Options.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. <template>
  2. <div>
  3. <setting-tabs :activeTab="'settings.options'"></setting-tabs>
  4. <div class="options-tabs">
  5. <form-wrapper>
  6. <!-- <form @submit.prevent="handleSubmit" @change="handleSubmit" @keydown="form.onKeydown($event)"> -->
  7. <form>
  8. <h4 class="title is-4 has-text-grey-light">{{ $t('settings.general') }}</h4>
  9. <!-- Check for update -->
  10. <form-checkbox v-on:checkForUpdate="saveSetting('checkForUpdate', $event)" :form="form" fieldName="checkForUpdate" :label="$t('commons.check_for_update')" :help="$t('commons.check_for_update_help')" />
  11. <version-checker></version-checker>
  12. <!-- Language -->
  13. <form-select v-on:lang="saveSetting('lang', $event)" :options="langs" :form="form" fieldName="lang" :label="$t('settings.forms.language.label')" :help="$t('settings.forms.language.help')" />
  14. <div class="field help">
  15. {{ $t('settings.forms.some_translation_are_missing') }}
  16. <a class="ml-2" href="https://crowdin.com/project/2fauth">
  17. {{ $t('settings.forms.help_translate_2fauth') }}
  18. <font-awesome-icon :icon="['fas', 'external-link-alt']" />
  19. </a>
  20. </div>
  21. <!-- display mode -->
  22. <form-toggle v-on:displayMode="saveSetting('displayMode', $event)" :choices="layouts" :form="form" fieldName="displayMode" :label="$t('settings.forms.display_mode.label')" :help="$t('settings.forms.display_mode.help')" />
  23. <!-- theme -->
  24. <form-toggle v-on:theme="saveSetting('theme', $event)" :choices="themes" :form="form" fieldName="theme" :label="$t('settings.forms.theme.label')" :help="$t('settings.forms.theme.help')" />
  25. <!-- show icon -->
  26. <form-checkbox v-on:showAccountsIcons="saveSetting('showAccountsIcons', $event)" :form="form" fieldName="showAccountsIcons" :label="$t('settings.forms.show_accounts_icons.label')" :help="$t('settings.forms.show_accounts_icons.help')" />
  27. <!-- Official icons -->
  28. <form-checkbox v-on:getOfficialIcons="saveSetting('getOfficialIcons', $event)" :form="form" fieldName="getOfficialIcons" :label="$t('settings.forms.get_official_icons.label')" :help="$t('settings.forms.get_official_icons.help')" />
  29. <h4 class="title is-4 pt-4 has-text-grey-light">{{ $t('groups.groups') }}</h4>
  30. <!-- default group -->
  31. <form-select v-on:defaultGroup="saveSetting('defaultGroup', $event)" :options="groups" :form="form" fieldName="defaultGroup" :label="$t('settings.forms.default_group.label')" :help="$t('settings.forms.default_group.help')" />
  32. <!-- retain active group -->
  33. <form-checkbox v-on:rememberActiveGroup="saveSetting('rememberActiveGroup', $event)" :form="form" fieldName="rememberActiveGroup" :label="$t('settings.forms.remember_active_group.label')" :help="$t('settings.forms.remember_active_group.help')" />
  34. <h4 class="title is-4 pt-4 has-text-grey-light">{{ $t('settings.security') }}</h4>
  35. <!-- auto lock -->
  36. <form-select v-on:kickUserAfter="saveSetting('kickUserAfter', $event)" :options="kickUserAfters" :form="form" fieldName="kickUserAfter" :label="$t('settings.forms.auto_lock.label')" :help="$t('settings.forms.auto_lock.help')" />
  37. <!-- protect db -->
  38. <form-checkbox v-on:useEncryption="saveSetting('useEncryption', $event)" :form="form" fieldName="useEncryption" :label="$t('settings.forms.use_encryption.label')" :help="$t('settings.forms.use_encryption.help')" />
  39. <!-- otp as dot -->
  40. <form-checkbox v-on:showOtpAsDot="saveSetting('showOtpAsDot', $event)" :form="form" fieldName="showOtpAsDot" :label="$t('settings.forms.show_otp_as_dot.label')" :help="$t('settings.forms.show_otp_as_dot.help')" />
  41. <!-- close otp on copy -->
  42. <form-checkbox v-on:closeOtpOnCopy="saveSetting('closeOtpOnCopy', $event)" :form="form" fieldName="closeOtpOnCopy" :label="$t('settings.forms.close_otp_on_copy.label')" :help="$t('settings.forms.close_otp_on_copy.help')" />
  43. <!-- copy otp on get -->
  44. <form-checkbox v-on:copyOtpOnDisplay="saveSetting('copyOtpOnDisplay', $event)" :form="form" fieldName="copyOtpOnDisplay" :label="$t('settings.forms.copy_otp_on_display.label')" :help="$t('settings.forms.copy_otp_on_display.help')" />
  45. <h4 class="title is-4 pt-4 has-text-grey-light">{{ $t('settings.data_input') }}</h4>
  46. <!-- basic qrcode -->
  47. <form-checkbox v-on:useBasicQrcodeReader="saveSetting('useBasicQrcodeReader', $event)" :form="form" fieldName="useBasicQrcodeReader" :label="$t('settings.forms.use_basic_qrcode_reader.label')" :help="$t('settings.forms.use_basic_qrcode_reader.help')" />
  48. <!-- direct capture -->
  49. <form-checkbox v-on:useDirectCapture="saveSetting('useDirectCapture', $event)" :form="form" fieldName="useDirectCapture" :label="$t('settings.forms.useDirectCapture.label')" :help="$t('settings.forms.useDirectCapture.help')" />
  50. <!-- default capture mode -->
  51. <form-select v-on:defaultCaptureMode="saveSetting('defaultCaptureMode', $event)" :options="captureModes" :form="form" fieldName="defaultCaptureMode" :label="$t('settings.forms.defaultCaptureMode.label')" :help="$t('settings.forms.defaultCaptureMode.help')" />
  52. </form>
  53. </form-wrapper>
  54. </div>
  55. <vue-footer :showButtons="true">
  56. <!-- Cancel button -->
  57. <p class="control">
  58. <button class="button is-rounded" :class="{'is-dark' : $root.showDarkMode}" @click.stop="exitSettings">
  59. {{ $t('commons.close') }}
  60. </button>
  61. </p>
  62. </vue-footer>
  63. </div>
  64. </template>
  65. <script>
  66. /**
  67. * Options view
  68. *
  69. * route: '/settings'
  70. *
  71. * Allow user to edit any option.
  72. *
  73. * This is the content of the Options tab set in views/settings/index.vue
  74. * The view is a form that automatically post to backend every time a field is changed.
  75. *
  76. * All changes are dynamically applied thanks to vue reacivity, except the lang one which force the
  77. * page to reload.
  78. *
  79. * inputs : Running options values are passed using the this.$root.appSettings var to feed the form
  80. */
  81. import Form from './../../components/Form'
  82. import VersionChecker from './../../components/VersionChecker'
  83. export default {
  84. data(){
  85. return {
  86. form: new Form({
  87. lang: 'browser',
  88. showOtpAsDot: null,
  89. closeOtpOnCopy: null,
  90. copyOtpOnDisplay: null,
  91. useBasicQrcodeReader: null,
  92. showAccountsIcons: null,
  93. displayMode: '',
  94. kickUserAfter: '',
  95. useEncryption: null,
  96. defaultGroup: '',
  97. useDirectCapture: null,
  98. defaultCaptureMode: '',
  99. rememberActiveGroup: true,
  100. getOfficialIcons: null,
  101. checkForUpdate: null,
  102. theme: 'dark',
  103. }),
  104. layouts: [
  105. { text: this.$t('settings.forms.grid'), value: 'grid', icon: 'th' },
  106. { text: this.$t('settings.forms.list'), value: 'list', icon: 'list' },
  107. ],
  108. themes: [
  109. { text: this.$t('settings.forms.light'), value: 'light', icon: 'sun' },
  110. { text: this.$t('settings.forms.dark'), value: 'dark', icon: 'moon' },
  111. { text: this.$t('settings.forms.automatic'), value: 'system', icon: 'desktop' },
  112. ],
  113. kickUserAfters: [
  114. { text: this.$t('settings.forms.never'), value: '0' },
  115. { text: this.$t('settings.forms.on_otp_copy'), value: '-1' },
  116. { text: this.$t('settings.forms.1_minutes'), value: '1' },
  117. { text: this.$t('settings.forms.5_minutes'), value: '5' },
  118. { text: this.$t('settings.forms.10_minutes'), value: '10' },
  119. { text: this.$t('settings.forms.15_minutes'), value: '15' },
  120. { text: this.$t('settings.forms.30_minutes'), value: '30' },
  121. { text: this.$t('settings.forms.1_hour'), value: '60' },
  122. { text: this.$t('settings.forms.1_day'), value: '1440' },
  123. ],
  124. groups: [
  125. { text: this.$t('groups.no_group'), value: 0 },
  126. { text: this.$t('groups.active_group'), value: -1 },
  127. ],
  128. captureModes: [
  129. { text: this.$t('settings.forms.livescan'), value: 'livescan' },
  130. { text: this.$t('settings.forms.upload'), value: 'upload' },
  131. { text: this.$t('settings.forms.advanced_form'), value: 'advancedForm' },
  132. ],
  133. }
  134. },
  135. components: {
  136. VersionChecker,
  137. },
  138. computed : {
  139. langs: function() {
  140. let locales = [{
  141. text: this.$t('languages.browser_preference') + ' (' + this.$root.$i18n.locale + ')',
  142. value: 'browser'
  143. }];
  144. for (const locale of window.appLocales) {
  145. locales.push({
  146. text: this.$t('languages.' + locale),
  147. value: locale
  148. })
  149. }
  150. return locales
  151. }
  152. },
  153. async mounted() {
  154. const { data } = await this.form.get('/api/v1/settings')
  155. this.form.fillWithKeyValueObject(data)
  156. let lang = data.filter(x => x.key === 'lang')
  157. if (lang.value == 'browser') {
  158. if(window.appLocales.includes(lang.value)) {
  159. this.form.lang = lang
  160. }
  161. }
  162. // this.$root.$i18n.locale
  163. this.form.setOriginal()
  164. this.fetchGroups()
  165. },
  166. methods : {
  167. handleSubmit(e) {
  168. e.preventDefault()
  169. console.log(e)
  170. // this.form.post('/api/v1/settings/options', {returnError: false})
  171. // .then(response => {
  172. // this.$notify({ type: 'is-success', text: response.data.message })
  173. // if(response.data.settings.lang !== this.$root.$i18n.locale) {
  174. // this.$router.go()
  175. // }
  176. // else {
  177. // this.$root.appSettings = response.data.settings
  178. // }
  179. // });
  180. },
  181. saveSetting(settingName, event) {
  182. this.axios.put('/api/v1/settings/' + settingName, { value: event }).then(response => {
  183. this.$notify({ type: 'is-success', text: this.$t('settings.forms.setting_saved') })
  184. if(settingName === 'lang' && response.data.value !== this.$root.$i18n.locale) {
  185. this.$router.go()
  186. }
  187. else {
  188. this.$root.appSettings[response.data.key] = response.data.value
  189. if(settingName === 'theme') {
  190. this.setTheme(response.data.value)
  191. }
  192. }
  193. })
  194. },
  195. fetchGroups() {
  196. this.axios.get('/api/v1/groups').then(response => {
  197. response.data.forEach((data) => {
  198. if( data.id >0 ) {
  199. this.groups.push({
  200. text: data.name,
  201. value: data.id
  202. })
  203. }
  204. })
  205. })
  206. },
  207. },
  208. }
  209. </script>