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.

AppStoreNavigation.vue 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <template>
  2. <!-- Categories & filters -->
  3. <NcAppNavigation :aria-label="t('settings', 'Apps')">
  4. <template #list>
  5. <NcAppNavigationItem id="app-category-discover"
  6. :to="{ name: 'apps-category', params: { category: 'discover'} }"
  7. :name="APPS_SECTION_ENUM.discover">
  8. <template #icon>
  9. <NcIconSvgWrapper :path="APPSTORE_CATEGORY_ICONS.discover" />
  10. </template>
  11. </NcAppNavigationItem>
  12. <NcAppNavigationItem id="app-category-installed"
  13. :to="{ name: 'apps-category', params: { category: 'installed'} }"
  14. :name="APPS_SECTION_ENUM.installed">
  15. <template #icon>
  16. <NcIconSvgWrapper :path="APPSTORE_CATEGORY_ICONS.installed" />
  17. </template>
  18. </NcAppNavigationItem>
  19. <NcAppNavigationItem id="app-category-enabled"
  20. :to="{ name: 'apps-category', params: { category: 'enabled' } }"
  21. :name="APPS_SECTION_ENUM.enabled">
  22. <template #icon>
  23. <NcIconSvgWrapper :path="APPSTORE_CATEGORY_ICONS.enabled" />
  24. </template>
  25. </NcAppNavigationItem>
  26. <NcAppNavigationItem id="app-category-disabled"
  27. :to="{ name: 'apps-category', params: { category: 'disabled' } }"
  28. :name="APPS_SECTION_ENUM.disabled">
  29. <template #icon>
  30. <NcIconSvgWrapper :path="APPSTORE_CATEGORY_ICONS.disabled" />
  31. </template>
  32. </NcAppNavigationItem>
  33. <NcAppNavigationItem v-if="updateCount > 0"
  34. id="app-category-updates"
  35. :to="{ name: 'apps-category', params: { category: 'updates' } }"
  36. :name="APPS_SECTION_ENUM.updates">
  37. <template #counter>
  38. <NcCounterBubble>{{ updateCount }}</NcCounterBubble>
  39. </template>
  40. <template #icon>
  41. <NcIconSvgWrapper :path="APPSTORE_CATEGORY_ICONS.updates" />
  42. </template>
  43. </NcAppNavigationItem>
  44. <NcAppNavigationItem id="app-category-your-bundles"
  45. :to="{ name: 'apps-category', params: { category: 'app-bundles' } }"
  46. :name="APPS_SECTION_ENUM['app-bundles']">
  47. <template #icon>
  48. <NcIconSvgWrapper :path="APPSTORE_CATEGORY_ICONS.bundles" />
  49. </template>
  50. </NcAppNavigationItem>
  51. <NcAppNavigationSpacer />
  52. <!-- App store categories -->
  53. <li v-if="appstoreEnabled && categoriesLoading" class="categories--loading">
  54. <NcLoadingIcon :size="20" :aria-label="t('settings', 'Loading categories')" />
  55. </li>
  56. <template v-else-if="appstoreEnabled && !categoriesLoading">
  57. <NcAppNavigationItem v-if="isSubscribed"
  58. id="app-category-supported"
  59. :to="{ name: 'apps-category', params: { category: 'supported' } }"
  60. :name="APPS_SECTION_ENUM.supported">
  61. <template #icon>
  62. <NcIconSvgWrapper :path="APPSTORE_CATEGORY_ICONS.supported" />
  63. </template>
  64. </NcAppNavigationItem>
  65. <NcAppNavigationItem id="app-category-featured"
  66. :to="{ name: 'apps-category', params: { category: 'featured' } }"
  67. :name="APPS_SECTION_ENUM.featured">
  68. <template #icon>
  69. <NcIconSvgWrapper :path="APPSTORE_CATEGORY_ICONS.featured" />
  70. </template>
  71. </NcAppNavigationItem>
  72. <NcAppNavigationItem v-for="category in categories"
  73. :id="`app-category-${category.id}`"
  74. :key="category.id"
  75. :name="category.displayName"
  76. :to="{
  77. name: 'apps-category',
  78. params: { category: category.id },
  79. }">
  80. <template #icon>
  81. <NcIconSvgWrapper :path="category.icon" />
  82. </template>
  83. </NcAppNavigationItem>
  84. </template>
  85. <NcAppNavigationItem id="app-developer-docs"
  86. :name="t('settings', 'Developer documentation ↗')"
  87. :href="developerDocsUrl" />
  88. </template>
  89. </NcAppNavigation>
  90. </template>
  91. <script setup lang="ts">
  92. import { loadState } from '@nextcloud/initial-state'
  93. import { translate as t } from '@nextcloud/l10n'
  94. import { computed, onBeforeMount } from 'vue'
  95. import { APPS_SECTION_ENUM } from '../constants/AppsConstants'
  96. import { useAppsStore } from '../store/apps-store'
  97. import NcAppNavigation from '@nextcloud/vue/dist/Components/NcAppNavigation.js'
  98. import NcAppNavigationItem from '@nextcloud/vue/dist/Components/NcAppNavigationItem.js'
  99. import NcAppNavigationSpacer from '@nextcloud/vue/dist/Components/NcAppNavigationSpacer.js'
  100. import NcCounterBubble from '@nextcloud/vue/dist/Components/NcCounterBubble.js'
  101. import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js'
  102. import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
  103. import APPSTORE_CATEGORY_ICONS from '../constants/AppstoreCategoryIcons.ts'
  104. const updateCount = loadState<number>('settings', 'appstoreUpdateCount', 0)
  105. const appstoreEnabled = loadState<boolean>('settings', 'appstoreEnabled', true)
  106. const developerDocsUrl = loadState<string>('settings', 'appstoreDeveloperDocs', '')
  107. const store = useAppsStore()
  108. const categories = computed(() => store.categories)
  109. const categoriesLoading = computed(() => store.loading.categories)
  110. /**
  111. * Check if the current instance has a support subscription from the Nextcloud GmbH
  112. *
  113. * For customers of the Nextcloud GmbH the app level will be set to `300` for apps that are supported in their subscription
  114. */
  115. const isSubscribed = computed(() => store.apps.find(({ level }) => level === 300) !== undefined)
  116. // load categories when component is mounted
  117. onBeforeMount(() => {
  118. store.loadCategories()
  119. store.loadApps()
  120. })
  121. </script>
  122. <style scoped>
  123. /* The categories-loading indicator */
  124. .categories--loading {
  125. flex: 1;
  126. display: flex;
  127. align-items: center;
  128. justify-content: center;
  129. }
  130. </style>