You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

302 lines
12 KiB

  1. <template lang='pug'>
  2. v-container(fluid, grid-list-lg)
  3. v-layout(row, wrap)
  4. v-flex(xs12)
  5. .admin-header
  6. img.animated.fadeInUp(src='/_assets/svg/icon-globe-earth.svg', alt='Locale', style='width: 80px;')
  7. .admin-header-title
  8. .headline.primary--text.animated.fadeInLeft {{ $t('admin:locale.title') }}
  9. .subtitle-1.grey--text.animated.fadeInLeft.wait-p4s {{ $t('admin:locale.subtitle') }}
  10. v-spacer
  11. v-btn.animated.fadeInDown.wait-p3s(icon, outlined, color='grey', href='https://docs.requarks.io/locales', target='_blank')
  12. v-icon mdi-help-circle
  13. v-btn.animated.fadeInDown.ml-3(color='success', depressed, @click='save', large, :loading='loading')
  14. v-icon(left) mdi-check
  15. span {{$t('common:actions.apply')}}
  16. v-form.pt-3
  17. v-layout(row wrap)
  18. v-flex(xl6 lg5 xs12)
  19. v-card.wiki-form.animated.fadeInUp
  20. v-toolbar(color='primary', dark, dense, flat)
  21. v-toolbar-title.subtitle-1 {{ $t('admin:locale.settings') }}
  22. v-card-text
  23. v-select(
  24. outlined
  25. :items='installedLocales'
  26. prepend-icon='mdi-web'
  27. v-model='selectedLocale'
  28. item-value='code'
  29. item-text='nativeName'
  30. :label='namespacing ? $t("admin:locale.base.labelWithNS") : $t("admin:locale.base.label")'
  31. persistent-hint
  32. :hint='$t("admin:locale.base.hint")'
  33. )
  34. template(slot='item', slot-scope='data')
  35. template(v-if='typeof data.item !== "object"')
  36. v-list-item-content(v-text='data.item')
  37. template(v-else)
  38. v-list-item-avatar
  39. v-avatar.blue.white--text(tile, size='40', v-html='data.item.code.toUpperCase()')
  40. v-list-item-content
  41. v-list-item-title(v-html='data.item.name')
  42. v-list-item-subtitle(v-html='data.item.nativeName')
  43. v-divider.mt-3
  44. v-switch(
  45. inset
  46. v-model='autoUpdate'
  47. :label='$t("admin:locale.autoUpdate.label")'
  48. color='primary'
  49. persistent-hint
  50. :hint='namespacing ? $t("admin:locale.autoUpdate.hintWithNS") : $t("admin:locale.autoUpdate.hint")'
  51. )
  52. v-card.wiki-form.mt-3.animated.fadeInUp.wait-p2s
  53. v-toolbar(color='primary', dark, dense, flat)
  54. v-toolbar-title.subtitle-1 {{ $t('admin:locale.namespacing') }}
  55. v-card-text
  56. v-switch(
  57. inset
  58. v-model='namespacing'
  59. :label='$t("admin:locale.namespaces.label")'
  60. color='primary'
  61. persistent-hint
  62. :hint='$t("admin:locale.namespaces.hint")'
  63. )
  64. v-alert.mt-3(
  65. outlined
  66. color='orange'
  67. :value='true'
  68. icon='mdi-alert'
  69. )
  70. span {{ $t('admin:locale.namespacingPrefixWarning.title', { langCode: selectedLocale }) }}
  71. .caption.grey--text {{ $t('admin:locale.namespacingPrefixWarning.subtitle') }}
  72. v-divider.mt-3.mb-4
  73. v-select(
  74. outlined
  75. :disabled='!namespacing'
  76. :items='installedLocales'
  77. prepend-icon='mdi-web'
  78. multiple
  79. chips
  80. deletable-chips
  81. v-model='namespaces'
  82. item-value='code'
  83. item-text='name'
  84. :label='$t("admin:locale.activeNamespaces.label")'
  85. persistent-hint
  86. small-chips
  87. :hint='$t("admin:locale.activeNamespaces.hint")'
  88. )
  89. template(slot='item', slot-scope='data')
  90. template(v-if='typeof data.item !== "object"')
  91. v-list-item-content(v-text='data.item')
  92. template(v-else)
  93. v-list-item-avatar
  94. v-avatar.blue.white--text(tile, size='40', v-html='data.item.code.toUpperCase()')
  95. v-list-item-content
  96. v-list-item-title(v-html='data.item.name')
  97. v-list-item-subtitle(v-html='data.item.nativeName')
  98. v-list-item-action
  99. v-checkbox(:input-value='data.attrs.inputValue', color='primary', value)
  100. v-flex(xl6 lg7 xs12)
  101. v-card.animated.fadeInUp.wait-p4s
  102. v-toolbar(color='teal', dark, dense, flat)
  103. v-toolbar-title.subtitle-1 {{ $t('admin:locale.downloadTitle') }}
  104. v-data-table(
  105. :headers='headers',
  106. :items='locales',
  107. hide-default-footer,
  108. item-key='code',
  109. :items-per-page='1000'
  110. )
  111. template(v-slot:item.code='{ item }')
  112. v-chip.white--text(label, color='teal', small) {{item.code}}
  113. template(v-slot:item.name='{ item }')
  114. strong {{item.name}}
  115. template(v-slot:item.isRTL='{ item }')
  116. v-icon(v-if='item.isRTL') mdi-check
  117. template(v-slot:item.availability='{ item }')
  118. .d-flex.align-center.pl-4
  119. v-progress-circular(:value='item.availability', width='2', size='20', :color='item.availability <= 33 ? `red` : (item.availability <= 66) ? `orange` : `green`')
  120. .caption.mx-2(:class='item.availability <= 33 ? `red--text` : (item.availability <= 66) ? `orange--text` : `green--text`') {{item.availability}}%
  121. template(v-slot:item.isInstalled='{ item }')
  122. v-progress-circular(v-if='item.isDownloading', indeterminate, color='blue', size='20', :width='2')
  123. v-btn(v-else-if='item.isInstalled && item.installDate < item.updatedAt', icon, small, @click='download(item)')
  124. v-icon.blue--text mdi-cached
  125. v-btn(v-else-if='item.isInstalled', icon, small, @click='download(item)')
  126. v-icon.green--text mdi-check-bold
  127. v-btn(v-else, icon, small, @click='download(item)')
  128. v-icon.grey--text mdi-cloud-download
  129. v-card.wiki-form.mt-3.animated.fadeInUp.wait-p5s
  130. v-toolbar(color='teal', dark, dense, flat)
  131. v-toolbar-title.subtitle-1 {{ $t('admin:locale.sideload') }}
  132. v-spacer
  133. v-chip(label, color='white', small).teal--text coming soon
  134. v-card-text
  135. div {{ $t('admin:locale.sideloadHelp') }}
  136. v-btn.ml-0.mt-3(color='teal', disabled) {{ $t('common:actions.browse') }}
  137. </template>
  138. <script>
  139. import _ from 'lodash'
  140. /* global WIKI */
  141. import localesQuery from 'gql/admin/locale/locale-query-list.gql'
  142. import localesDownloadMutation from 'gql/admin/locale/locale-mutation-download.gql'
  143. import localesSaveMutation from 'gql/admin/locale/locale-mutation-save.gql'
  144. export default {
  145. data() {
  146. return {
  147. loading: false,
  148. locales: [],
  149. selectedLocale: 'en',
  150. autoUpdate: false,
  151. namespacing: false,
  152. namespaces: []
  153. }
  154. },
  155. computed: {
  156. installedLocales() {
  157. return _.filter(this.locales, ['isInstalled', true])
  158. },
  159. headers() {
  160. return [
  161. {
  162. text: this.$t('admin:locale.code'),
  163. align: 'left',
  164. value: 'code',
  165. width: 90
  166. },
  167. {
  168. text: this.$t('admin:locale.name'),
  169. align: 'left',
  170. value: 'name'
  171. },
  172. {
  173. text: this.$t('admin:locale.nativeName'),
  174. align: 'left',
  175. value: 'nativeName'
  176. },
  177. {
  178. text: this.$t('admin:locale.rtl'),
  179. align: 'center',
  180. value: 'isRTL',
  181. sortable: false,
  182. width: 10
  183. },
  184. {
  185. text: this.$t('admin:locale.availability'),
  186. align: 'center',
  187. value: 'availability',
  188. sortable: false,
  189. width: 120
  190. },
  191. {
  192. text: this.$t('admin:locale.download'),
  193. align: 'center',
  194. value: 'isInstalled',
  195. sortable: false,
  196. width: 100
  197. }
  198. ]
  199. }
  200. },
  201. methods: {
  202. async download(lc) {
  203. lc.isDownloading = true
  204. const respRaw = await this.$apollo.mutate({
  205. mutation: localesDownloadMutation,
  206. variables: {
  207. locale: lc.code
  208. }
  209. })
  210. const resp = _.get(respRaw, 'data.localization.downloadLocale.responseResult', {})
  211. if (resp.succeeded) {
  212. lc.isDownloading = false
  213. lc.isInstalled = true
  214. lc.updatedAt = new Date().toISOString()
  215. lc.installDate = lc.updatedAt
  216. this.$store.commit('showNotification', {
  217. message: `Locale ${lc.name} has been installed successfully.`,
  218. style: 'success',
  219. icon: 'get_app'
  220. })
  221. } else {
  222. this.$store.commit('showNotification', {
  223. message: `Error: ${resp.message}`,
  224. style: 'error',
  225. icon: 'warning'
  226. })
  227. }
  228. this.isDownloading = false
  229. },
  230. async save() {
  231. this.loading = true
  232. const respRaw = await this.$apollo.mutate({
  233. mutation: localesSaveMutation,
  234. variables: {
  235. locale: this.selectedLocale,
  236. autoUpdate: this.autoUpdate,
  237. namespacing: this.namespacing,
  238. namespaces: this.namespaces
  239. }
  240. })
  241. const resp = _.get(respRaw, 'data.localization.updateLocale.responseResult', {})
  242. if (resp.succeeded) {
  243. // Change UI language
  244. WIKI.$i18n.i18next.changeLanguage(this.selectedLocale)
  245. WIKI.$moment.locale(this.selectedLocale)
  246. // Check for RTL
  247. const curLocale = _.find(this.locales, ['code', this.selectedLocale])
  248. this.$vuetify.rtl = curLocale && curLocale.isRTL
  249. this.$store.commit('showNotification', {
  250. message: 'Locale settings updated successfully.',
  251. style: 'success',
  252. icon: 'check'
  253. })
  254. _.delay(() => {
  255. window.location.reload(true)
  256. }, 1000)
  257. } else {
  258. this.$store.commit('showNotification', {
  259. message: `Error: ${resp.message}`,
  260. style: 'error',
  261. icon: 'warning'
  262. })
  263. }
  264. this.loading = false
  265. }
  266. },
  267. apollo: {
  268. locales: {
  269. query: localesQuery,
  270. fetchPolicy: 'network-only',
  271. update: (data) => data.localization.locales.map(lc => ({ ...lc, isDownloading: false })),
  272. watchLoading (isLoading) {
  273. this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-locale-refresh')
  274. }
  275. },
  276. selectedLocale: {
  277. query: localesQuery,
  278. update: (data) => data.localization.config.locale
  279. },
  280. autoUpdate: {
  281. query: localesQuery,
  282. update: (data) => data.localization.config.autoUpdate
  283. },
  284. namespacing: {
  285. query: localesQuery,
  286. update: (data) => data.localization.config.namespacing
  287. },
  288. namespaces: {
  289. query: localesQuery,
  290. update: (data) => data.localization.config.namespaces
  291. }
  292. }
  293. }
  294. </script>