diff --git a/src/components/Model/Model.vue b/src/components/Model/Model.vue index 835648dea5b59957e70ad2a3794c994ad74a72a6..f99d09425312663f84d4b45fb69da9b8ea8d792e 100644 --- a/src/components/Model/Model.vue +++ b/src/components/Model/Model.vue @@ -30,13 +30,15 @@ <hr /> <ModelWorkers :model-id="modelId" /> - <hr /> - <h2 class="title is-4">Members</h2> - <ListMembers - content-type="model" - :content-id="modelId" - v-model:page-number="membersPageNumber" - /> + <template v-if="hasFeature('enterprise')"> + <hr /> + <h2 class="title is-4">Members</h2> + <ListMembers + content-type="model" + :content-id="modelId" + v-model:page-number="membersPageNumber" + /> + </template> </template> <ArchivalModal v-if="canAdmin" @@ -49,14 +51,17 @@ </template> <script lang="ts"> +import { mapActions, mapState } from 'pinia' import { defineComponent } from 'vue' +import { mapGetters as mapVuexGetters } from 'vuex' + +import { useModelStore } from '@/stores' import { UUID_REGEX } from '@/config' + import ListMembers from '@/components/Memberships/ListMembers.vue' -import VersionList from './Versions/List.vue' import ModelWorkers from '@/components/Model/Workers/List.vue' import ArchivalModal from '@/components/ArchivalModal.vue' -import { mapActions, mapState } from 'pinia' -import { useModelStore } from '@/stores' +import VersionList from './Versions/List.vue' export default defineComponent({ components: { @@ -91,6 +96,7 @@ export default defineComponent({ }), computed: { ...mapState(useModelStore, ['models']), + ...mapVuexGetters('auth', ['hasFeature']), canAdmin () { return this.models[this.modelId].rights.includes('admin') }, diff --git a/src/components/Repos/Row.vue b/src/components/Repos/Row.vue index fda455620f893a3933266e51eab21b2e294341c0..c917408d795811f6a8bb5a3941ece2354ef8f62b 100644 --- a/src/components/Repos/Row.vue +++ b/src/components/Repos/Row.vue @@ -13,7 +13,7 @@ </router-link> </div> </td> - <td> + <td v-if="hasFeature('enterprise')"> <router-link :to="{ name: 'repo-rights', params: { repoId: repo.id } }"> {{ repo.authorized_users }} user<template v-if="repo.authorized_users > 1">s</template> </router-link> @@ -45,7 +45,7 @@ export default { } }, computed: { - ...mapGetters('auth', ['isVerified']) + ...mapGetters('auth', ['isVerified', 'hasFeature']) } } </script> diff --git a/src/router/index.js b/src/router/index.js index cc29db9af3f5ceb25fc0bd0ed4c5ed3a4bd784f5..dd88aba776dfdf60d81fef5355e5c40f7b689392 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -162,7 +162,11 @@ const routes = [ path: `/process/repos/:repoId(${UUID})/rights`, name: 'repo-rights', component: ReposRights, - meta: { requiresLogin: true, requiresVerified: true }, + meta: { + requiresLogin: true, + requiresVerified: true, + requiresFeatures: ['enterprise'] + }, props: true }, { @@ -294,13 +298,21 @@ const routes = [ path: '/group/create', name: 'group-create', component: GroupCreate, - meta: { requiresLogin: true, requiresVerified: true } + meta: { + requiresLogin: true, + requiresVerified: true, + requiresFeatures: ['enterprise'] + } }, { path: `/group/:groupId(${UUID})`, name: 'group-manage', component: GroupManage, - meta: { requiresLogin: true, requiresVerified: true }, + meta: { + requiresLogin: true, + requiresVerified: true, + requiresFeatures: ['enterprise'] + }, props: true }, { diff --git a/src/types/user.ts b/src/types/user.ts index dc9fcf0fe940fd5bc681008a844eac47904428e2..cfed54e66d8dce47eeefd7494c4d57236cd41ee0 100644 --- a/src/types/user.ts +++ b/src/types/user.ts @@ -6,7 +6,7 @@ export interface UserLight { display_name: string } -export type Feature = 'signup' | 'selection' | 'search' | 'doorbell' +export type Feature = 'signup' | 'selection' | 'search' | 'doorbell' | 'enterprise' export interface User extends UserLight { verified_email: boolean diff --git a/src/views/App.vue b/src/views/App.vue index 312f3ef5902788ff91b3c43ed6884f00a7e7825d..e1d4552d503226cc6ed89d23a88c9d38de6cc389 100644 --- a/src/views/App.vue +++ b/src/views/App.vue @@ -24,7 +24,14 @@ </div> <router-view /> <footer class="footer is-paddingless is-flex is-justify-content-space-between"> - <span class="footer-item">Version <a :href="releaseNotes" target="_blank">{{ VERSION }}</a></span> + <span class="footer-item"> + Version + <a :href="releaseNotes" target="_blank"> + {{ VERSION }} + </a> <span class="tag" :class="hasFeature('enterprise') ? 'is-success' : 'is-info'"> + {{ hasFeature('enterprise') ? 'Enterprise' : 'Community' }} Edition + </span> + </span> <span class="footer-item">Built by <a href="https://teklia.com" target="_blank">Teklia</a></span> <span class="is-inline-flex"> <DoorBell class="footer-item mb-0" v-if="hasFeature('doorbell')" /> diff --git a/src/views/Auth/Profile.vue b/src/views/Auth/Profile.vue index b887f4e064ed733c8aa7f256a903c3fe8ad40801..3866b65a610beb316dc3ce5b49ec4849065b88c5 100644 --- a/src/views/Auth/Profile.vue +++ b/src/views/Auth/Profile.vue @@ -1,7 +1,7 @@ <template> <main class="container is-fluid"> <h1 class="title">Your profile and settings</h1> - <Tabs :tabs="{ details: 'Details', groups: 'Groups' }" v-model="tab"> + <Tabs :tabs="tabs" v-model="tab"> <template v-slot:details> <UserInfo /> </template> @@ -13,6 +13,7 @@ </template> <script> +import { mapGetters } from 'vuex' import Tabs from '@/components/Tabs.vue' import Groups from '@/components/Auth/Profile/Groups' import UserInfo from '@/components/Auth/Profile/Info' @@ -25,6 +26,14 @@ export default { }, data: () => ({ tab: 'details' - }) + }), + computed: { + ...mapGetters('auth', ['hasFeature']), + tabs () { + const tabs = { details: 'Details' } + if (this.hasFeature('enterprise')) tabs.groups = 'Groups' + return tabs + } + } } </script> diff --git a/src/views/Corpus/Main.vue b/src/views/Corpus/Main.vue index 6e828c6c160bb3f7c8e5379c090f34c7f791aa0e..514749297dcd909c4f88ebd61499725406bcbc2d 100644 --- a/src/views/Corpus/Main.vue +++ b/src/views/Corpus/Main.vue @@ -65,7 +65,7 @@ </template> <script> -import { mapState } from 'vuex' +import { mapState, mapGetters } from 'vuex' import { corporaMixin } from '@/mixins' import ItemId from '@/components/ItemId' import Tabs from '@/components/Tabs.vue' @@ -105,6 +105,7 @@ export default { }), computed: { ...mapState('corpora', ['corporaLoaded']), + ...mapGetters('auth', ['hasFeature']), tabs () { // Only show the details tab when creating a project let tabs = { details: 'Details' } @@ -116,9 +117,11 @@ export default { entitytypes: 'Entity types', mlclasses: 'Classes', datasets: 'Datasets', - members: 'Members', search: 'Search' } + if (this.hasFeature('enterprise')) { + tabs.members = 'Members' + } } return tabs } diff --git a/src/views/Process/Workers/List.vue b/src/views/Process/Workers/List.vue index 4774e83871172bfe08a4ec879c87885e3ea91d31..72d0d5e961ddd4f860cea1a8292ad6671e8c769d 100644 --- a/src/views/Process/Workers/List.vue +++ b/src/views/Process/Workers/List.vue @@ -131,7 +131,7 @@ :local="local" v-on:selected-version="$emit('selected-version', $event)" /> - <template v-if="!processId && !selectable"> + <template v-if="!processId && !selectable && hasFeature('enterprise')"> <hr /> <h2 class="title is-4">Members</h2> <ListMembers @@ -156,8 +156,11 @@ <script> import { isEmpty } from 'lodash' import { mapState, mapActions } from 'pinia' -import { mapState as mapVuexState } from 'vuex' import MarkdownIt from 'markdown-it' +import { + mapState as mapVuexState, + mapGetters as mapVuexGetters +} from 'vuex' import { errorParser } from '@/helpers' import { truncateMixin } from '@/mixins' @@ -239,6 +242,7 @@ export default { computed: { ...mapVuexState('repos', ['reposPage']), ...mapState(useWorkerStore, ['workerTypes']), + ...mapVuexGetters('auth', ['hasFeature']), readMoreText () { if (this.expandDescription) return 'collapse description' return 'expand description' diff --git a/src/views/Process/Workers/Manage.vue b/src/views/Process/Workers/Manage.vue index 075d1f97a669bd3d01adba1a76e11a067eb2a07f..ec9e04f1cddb05422979fc4ee4d239508754b3b9 100644 --- a/src/views/Process/Workers/Manage.vue +++ b/src/views/Process/Workers/Manage.vue @@ -32,12 +32,14 @@ <hr /> <VersionList :worker="worker" /> - <hr /> - <h2 class="title is-4">Members</h2> - <ListMembers - content-type="worker" - :content-id="workerId" - /> + <template v-if="hasFeature('enterprise')"> + <hr /> + <h2 class="title is-4">Members</h2> + <ListMembers + content-type="worker" + :content-id="workerId" + /> + </template> </template> <div v-else-if="error" class="notification is-warning">{{ error }}</div> <div v-else class="notification is-info">Loading…</div> @@ -55,6 +57,7 @@ import MarkdownIt from 'markdown-it' import { mapState, mapActions } from 'pinia' import { defineComponent } from 'vue' +import { mapGetters as mapVuexGetters } from 'vuex' import { errorParser } from '@/helpers' import VersionList from '@/components/Process/Workers/Versions/List.vue' import ListMembers from '@/components/Memberships/ListMembers.vue' @@ -87,6 +90,7 @@ export default defineComponent({ }, computed: { ...mapState(useWorkerStore, ['workers']), + ...mapVuexGetters('auth', ['hasFeature']), worker () { const worker = this.workers[this.workerId] if (!worker || !isWorker(worker)) return diff --git a/src/views/Repos/List.vue b/src/views/Repos/List.vue index 6fc9d2d0847cb739b51057accc7bde98f6707581..092dce9ff6bfbbde1831f891ec1f36f074bac927 100644 --- a/src/views/Repos/List.vue +++ b/src/views/Repos/List.vue @@ -12,7 +12,7 @@ <tr> <th>URL</th> <th>Workers</th> - <th>Users</th> + <th v-if="hasFeature('enterprise')">Users</th> <th v-if="isVerified">Actions</th> </tr> </thead> @@ -61,7 +61,7 @@ export default { this.updatePage(query.page ?? 1) }, computed: { - ...mapGetters('auth', ['isVerified']), + ...mapGetters('auth', ['isVerified', 'hasFeature']), ...mapState('repos', ['repositories']) }, methods: {