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.

UserAppMenuSection.vue 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <template>
  2. <NcSettingsSection :name="t('theming', 'Navigation bar settings')">
  3. <p>
  4. {{ t('theming', 'You can configure the app order used for the navigation bar. The first entry will be the default app, opened after login or when clicking on the logo.') }}
  5. </p>
  6. <NcNoteCard v-if="!!appOrder[0]?.default" type="info">
  7. {{ t('theming', 'The default app can not be changed because it was configured by the administrator.') }}
  8. </NcNoteCard>
  9. <NcNoteCard v-if="hasAppOrderChanged" type="info">
  10. {{ t('theming', 'The app order was changed, to see it in action you have to reload the page.') }}
  11. </NcNoteCard>
  12. <AppOrderSelector class="user-app-menu-order" :value.sync="appOrder" />
  13. </NcSettingsSection>
  14. </template>
  15. <script lang="ts">
  16. import { showError } from '@nextcloud/dialogs'
  17. import { loadState } from '@nextcloud/initial-state'
  18. import { translate as t } from '@nextcloud/l10n'
  19. import { generateOcsUrl } from '@nextcloud/router'
  20. import { computed, defineComponent, ref } from 'vue'
  21. import axios from '@nextcloud/axios'
  22. import AppOrderSelector from './AppOrderSelector.vue'
  23. import NcNoteCard from '@nextcloud/vue/dist/Components/NcNoteCard.js'
  24. import NcSettingsSection from '@nextcloud/vue/dist/Components/NcSettingsSection.js'
  25. /** See NavigationManager */
  26. interface INavigationEntry {
  27. /** Navigation id */
  28. id: string
  29. /** Order where this entry should be shown */
  30. order: number
  31. /** Target of the navigation entry */
  32. href: string
  33. /** The icon used for the naviation entry */
  34. icon: string
  35. /** Type of the navigation entry ('link' vs 'settings') */
  36. type: 'link' | 'settings'
  37. /** Localized name of the navigation entry */
  38. name: string
  39. /** Whether this is the default app */
  40. default?: boolean
  41. /** App that registered this navigation entry (not necessarly the same as the id) */
  42. app: string
  43. /** The key used to identify this entry in the navigations entries */
  44. key: number
  45. }
  46. export default defineComponent({
  47. name: 'UserAppMenuSection',
  48. components: {
  49. AppOrderSelector,
  50. NcNoteCard,
  51. NcSettingsSection,
  52. },
  53. setup() {
  54. /**
  55. * Track if the app order has changed, so the user can be informed to reload
  56. */
  57. const hasAppOrderChanged = ref(false)
  58. /** The enforced default app set by the administrator (if any) */
  59. const enforcedDefaultApp = loadState<string|null>('theming', 'enforcedDefaultApp', null)
  60. /**
  61. * Array of all available apps, it is set by a core controller for the app menu, so it is always available
  62. */
  63. const allApps = ref(
  64. Object.values(loadState<Record<string, INavigationEntry>>('core', 'apps'))
  65. .filter(({ type }) => type === 'link')
  66. .map((app) => ({ ...app, label: app.name, default: app.default && app.app === enforcedDefaultApp })),
  67. )
  68. /**
  69. * Wrapper around the sortedApps list with a setter for saving any changes
  70. */
  71. const appOrder = computed({
  72. get: () => allApps.value,
  73. set: (value) => {
  74. const order = {} as Record<string, Record<number, number>>
  75. value.forEach(({ app, key }, index) => {
  76. order[app] = { ...order[app], [key]: index }
  77. })
  78. saveSetting('apporder', order)
  79. .then(() => {
  80. allApps.value = value
  81. hasAppOrderChanged.value = true
  82. })
  83. .catch((error) => {
  84. console.warn('Could not set the app order', error)
  85. showError(t('theming', 'Could not set the app order'))
  86. })
  87. },
  88. })
  89. const saveSetting = async (key: string, value: unknown) => {
  90. const url = generateOcsUrl('apps/provisioning_api/api/v1/config/users/{appId}/{configKey}', {
  91. appId: 'core',
  92. configKey: key,
  93. })
  94. return await axios.post(url, {
  95. configValue: JSON.stringify(value),
  96. })
  97. }
  98. return {
  99. appOrder,
  100. hasAppOrderChanged,
  101. t,
  102. }
  103. },
  104. })
  105. </script>
  106. <style scoped lang="scss">
  107. .user-app-menu-order {
  108. margin-block: 12px;
  109. }
  110. </style>