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.

AppMenuSection.vue 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <template>
  2. <NcSettingsSection :name="t('theming', 'Navigation bar settings')">
  3. <h3>{{ t('theming', 'Default app') }}</h3>
  4. <p class="info-note">
  5. {{ t('theming', 'The default app is the app that is e.g. opened after login or when the logo in the menu is clicked.') }}
  6. </p>
  7. <NcCheckboxRadioSwitch :checked.sync="hasCustomDefaultApp" type="switch" data-cy-switch-default-app="">
  8. {{ t('theming', 'Use custom default app') }}
  9. </NcCheckboxRadioSwitch>
  10. <template v-if="hasCustomDefaultApp">
  11. <h4>{{ t('theming', 'Global default app') }}</h4>
  12. <NcSelect v-model="selectedApps"
  13. :close-on-select="false"
  14. :placeholder="t('theming', 'Global default apps')"
  15. :options="allApps"
  16. :multiple="true" />
  17. <h5>{{ t('theming', 'Default app priority') }}</h5>
  18. <p class="info-note">
  19. {{ t('theming', 'If an app is not enabled for a user, the next app with lower priority is used.') }}
  20. </p>
  21. <AppOrderSelector :value.sync="selectedApps" />
  22. </template>
  23. </NcSettingsSection>
  24. </template>
  25. <script lang="ts">
  26. import { showError } from '@nextcloud/dialogs'
  27. import { loadState } from '@nextcloud/initial-state'
  28. import { translate as t } from '@nextcloud/l10n'
  29. import { generateUrl } from '@nextcloud/router'
  30. import { computed, defineComponent } from 'vue'
  31. import axios from '@nextcloud/axios'
  32. import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
  33. import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'
  34. import NcSettingsSection from '@nextcloud/vue/dist/Components/NcSettingsSection.js'
  35. import AppOrderSelector from '../AppOrderSelector.vue'
  36. export default defineComponent({
  37. name: 'AppMenuSection',
  38. components: {
  39. AppOrderSelector,
  40. NcCheckboxRadioSwitch,
  41. NcSelect,
  42. NcSettingsSection,
  43. },
  44. props: {
  45. defaultApps: {
  46. type: Array,
  47. required: true,
  48. },
  49. },
  50. emits: {
  51. 'update:defaultApps': (value: string[]) => Array.isArray(value) && value.every((id) => typeof id === 'string'),
  52. },
  53. setup(props, { emit }) {
  54. const hasCustomDefaultApp = computed({
  55. get: () => props.defaultApps.length > 0,
  56. set: (checked: boolean) => {
  57. if (checked) {
  58. emit('update:defaultApps', ['dashboard', 'files'])
  59. } else {
  60. selectedApps.value = []
  61. }
  62. },
  63. })
  64. /**
  65. * All enabled apps which can be navigated
  66. */
  67. const allApps = Object.values(
  68. loadState<Record<string, { id: string, name?: string, icon: string }>>('core', 'apps'),
  69. ).map(({ id, name, icon }) => ({ label: name, id, icon }))
  70. /**
  71. * Currently selected app, wrapps the setter
  72. */
  73. const selectedApps = computed({
  74. get: () => props.defaultApps.map((id) => allApps.filter(app => app.id === id)[0]),
  75. set(value) {
  76. saveSetting('defaultApps', value.map(app => app.id))
  77. .then(() => emit('update:defaultApps', value.map(app => app.id)))
  78. .catch(() => showError(t('theming', 'Could not set global default apps')))
  79. },
  80. })
  81. const saveSetting = async (key: string, value: unknown) => {
  82. const url = generateUrl('/apps/theming/ajax/updateAppMenu')
  83. return await axios.put(url, {
  84. setting: key,
  85. value,
  86. })
  87. }
  88. return {
  89. allApps,
  90. selectedApps,
  91. hasCustomDefaultApp,
  92. t,
  93. }
  94. },
  95. })
  96. </script>
  97. <style scoped lang="scss">
  98. h3, h4 {
  99. font-weight: bold;
  100. }
  101. h4, h5 {
  102. margin-block-start: 12px;
  103. }
  104. .info-note {
  105. color: var(--color-text-maxcontrast);
  106. }
  107. </style>