diff --git a/.gitignore b/.gitignore index e0b553ec61bfbc6d7909b30ffae7809ff2e62b72..f5d774609839a1db681aa0ec621c53301e9fe66b 100644 --- a/.gitignore +++ b/.gitignore @@ -305,6 +305,7 @@ $RECYCLE.BIN/ # End of https://www.toptal.com/developers/gitignore/api/vue,node,macos,windows,linux,vscode,intellij+all +# Other .husky .yarn/* !.yarn/patches diff --git a/src/modules/project/ProjectModule.vue b/src/modules/project/ProjectModule.vue index b0604e0730bdb949be6ed17515398e5c66460579..a816df71231ab5919dd9634729ca5064f87cb0a0 100644 --- a/src/modules/project/ProjectModule.vue +++ b/src/modules/project/ProjectModule.vue @@ -83,14 +83,6 @@ export default defineComponent({ if (this.projectStore.currentProjectRoles === null) { this.projectStore.retrieveProjectRoles(this.project); } - // Load Quotas for the project if not present - if (this.projectStore.currentQuotas === null) { - this.projectStore.retrieveQuotas(this.project); - } - // Load list of Enabled Resource Types if not present - if (this.resourceStore.resourceTypes === null) { - this.resourceStore.retrieveResourceTypes(); - } // Load list of all Project Role Types if not present if (this.projectStore.roles === null) { this.projectStore.retrieveRoles(); diff --git a/src/modules/project/pages/CreateProject.vue b/src/modules/project/pages/CreateProject.vue index 5f42042686c8f8c5e0c629b5b2b9bc68e2a824b4..49a78d8e1d64020490eb9d73a1956d906ad86925 100644 --- a/src/modules/project/pages/CreateProject.vue +++ b/src/modules/project/pages/CreateProject.vue @@ -130,9 +130,9 @@ export default defineComponent({ }, }, - created() { + async created() { this.isLoading = true; - this.fetchData(); + await this.fetchData(); this.isLoading = false; }, diff --git a/src/modules/project/pages/ProjectPage.vue b/src/modules/project/pages/ProjectPage.vue index 7f8a09036b8e4c3a706acfa94d3086e7b4ec5713..e9e54d8c6a72366d563b5b2601e1b2ddb1ecdc9c 100644 --- a/src/modules/project/pages/ProjectPage.vue +++ b/src/modules/project/pages/ProjectPage.vue @@ -69,6 +69,7 @@ <CoscineCard :title="$t('page.listProjects.addProject')" type="create" + :style="cardStyle" :to="toCreateSubProject()" @open-card="openCreateProject($event)" /> @@ -85,6 +86,7 @@ :key="index" :title="subProject.displayName" type="project" + :style="cardStyle" :to="toSubProject(subProject)" @open-card="openProject($event, subProject)" /> diff --git a/src/modules/project/pages/Quota.vue b/src/modules/project/pages/Quota.vue index c9df2993d9a8dfb68f495873c3e73f3315cdb1e1..9366928814a4b0b2a3867b18eed6e47c4d466162 100644 --- a/src/modules/project/pages/Quota.vue +++ b/src/modules/project/pages/Quota.vue @@ -391,11 +391,22 @@ export default defineComponent({ }, }, - created() { + async created() { + await this.fetchData(); this.selectFirstResourceType(); }, methods: { + async fetchData() { + // Load Quotas for the project if not present + if (this.projectStore.currentQuotas === null) { + await this.projectStore.retrieveQuotas(this.project); + } + // Load list of Enabled Resource Types if not present + if (this.resourceStore.resourceTypes === null) { + await this.resourceStore.retrieveResourceTypes(); + } + }, async changeProjectQuota() { if ( this.project && diff --git a/src/modules/resource/components/settings/Actions.vue b/src/modules/resource/components/settings/Actions.vue index fd925e8ef54bfd6623ea628035f6789a705f08a4..e3cf51ecf49a66e3a1bf4d4d29dade56f4fd4f32 100644 --- a/src/modules/resource/components/settings/Actions.vue +++ b/src/modules/resource/components/settings/Actions.vue @@ -11,10 +11,10 @@ <b-form-checkbox id="Archive" :checked="resourceForm.archived" - :disabled="!(isOwner || isResourceCreator) || !resourceForm" + :disabled="!isUserAllowedToEdit" switch size="lg" - @click.native.prevent="isArchiveModalVisible = true" + @click.prevent="isArchiveModalVisible = true" /> </CoscineFormGroup> @@ -31,7 +31,7 @@ type="delete" variant="danger" :disabled=" - !resourceForm || + !isUserAllowedToEdit || (resourceTypeInformation && !resourceTypeInformation.canDelete) " @click.prevent="isDeleteModalVisible = true" @@ -61,12 +61,10 @@ <script lang="ts"> import { defineComponent, type PropType } from "vue"; import useProjectStore from "@/modules/project/store"; -import useUserStore from "@/modules/user/store"; import useResourceStore from "../../store"; import ArchiveResourceModal from "./modals/ArchiveResourceModal.vue"; import DeleteResourceModal from "./modals/DeleteResourceModal.vue"; import type { ResourceObject } from "@coscine/api-client/dist/types/Coscine.Api.Resources"; -import type { UserObject } from "@coscine/api-client/dist/types/Coscine.Api.User"; import type { ResourceTypeInformation } from "@coscine/api-client/dist/types/Coscine.Api.Resources"; export default defineComponent({ components: { @@ -82,6 +80,10 @@ export default defineComponent({ default: false, type: Boolean, }, + isUserAllowedToEdit: { + default: false, + type: Boolean, + }, }, emits: { @@ -91,10 +93,9 @@ export default defineComponent({ setup() { const projectStore = useProjectStore(); - const userStore = useUserStore(); const resourceStore = useResourceStore(); - return { projectStore, userStore, resourceStore }; + return { projectStore, resourceStore }; }, data() { @@ -116,19 +117,6 @@ export default defineComponent({ } return null; }, - isOwner(): boolean | undefined { - return this.projectStore.currentUserRoleIsOwner; - }, - user(): UserObject | null { - return this.userStore.user; - }, - isResourceCreator(): boolean | undefined { - if (this.resourceForm.creator && this.user && this.user.id) { - return this.resourceForm.creator === this.user.id; - } else { - return undefined; - } - }, }, methods: { diff --git a/src/modules/resource/components/settings/MetadataView.vue b/src/modules/resource/components/settings/MetadataView.vue index a1df50d8032874b6ce3f8119aa7f49cedb4a3a58..f56dfb0f4a4e9372827c504c499698d39db13b5f 100644 --- a/src/modules/resource/components/settings/MetadataView.vue +++ b/src/modules/resource/components/settings/MetadataView.vue @@ -7,7 +7,7 @@ <FormGenerator v-else-if="resource" :key="resourceForm.applicationProfile" - :disabled-mode="!isOwner || resource.archived" + :disabled-mode="!isUserAllowedToEdit || resource.archived" :fixed-value-mode="true" :fixed-values="resourceForm.fixedValues" :locale="$root.$i18n.locale" @@ -25,7 +25,6 @@ import { defineComponent, type PropType } from "vue"; // import the store for current module import useResourceStore from "../../store"; -import useProjectStore from "@/modules/project/store"; import useUserStore from "@/modules/user/store"; import "@/plugins/form-generator"; import type { Dataset } from "@rdfjs/types"; @@ -47,6 +46,10 @@ export default defineComponent({ type: Boolean, required: true, }, + isUserAllowedToEdit: { + default: false, + type: Boolean, + }, }, emits: { @@ -55,10 +58,9 @@ export default defineComponent({ setup() { const resourceStore = useResourceStore(); - const projectStore = useProjectStore(); const userStore = useUserStore(); - return { resourceStore, projectStore, userStore }; + return { resourceStore, userStore }; }, data() { @@ -71,9 +73,6 @@ export default defineComponent({ resource(): ResourceObject | null { return this.resourceStore.currentResource; }, - isOwner(): boolean | undefined { - return this.projectStore.currentUserRoleIsOwner; - }, user(): UserObject | null { return this.userStore.user; }, @@ -99,5 +98,3 @@ export default defineComponent({ }, }); </script> - -<style></style> diff --git a/src/modules/resource/components/settings/Overview.vue b/src/modules/resource/components/settings/Overview.vue index 099b09edc8dcc174e2cc435cc362fadbbe589e08..5d1a51d449c8abfcd68c55cf66273f8ab54be6e9 100644 --- a/src/modules/resource/components/settings/Overview.vue +++ b/src/modules/resource/components/settings/Overview.vue @@ -129,7 +129,7 @@ type="input" > <b-form-input - v-if="resource" + v-if="resource && resource.type" id="ResourceType" :value=" $t('resourceTypes.' + resource.type.displayName + '.displayName') @@ -143,7 +143,12 @@ <!-- Resource Quota --> <b-col> <CoscineFormGroup - v-if="resource && resource.resourceTypeOption.Size" + v-if=" + resource && + resource.resourceTypeOption.Size && + quotaCurrentBytes !== null && + quotaMaximumBytes !== null + " label-for="Quota" :label="$t('page.settings.overview.quotaLabel')" :is-loading=" diff --git a/src/modules/resource/pages/CreateResource.vue b/src/modules/resource/pages/CreateResource.vue index 03286919780f560cdedf97ec8575ebb32dfdd93e..1db1ecc7dc27ea9766974cb9adfb27f03113a26c 100644 --- a/src/modules/resource/pages/CreateResource.vue +++ b/src/modules/resource/pages/CreateResource.vue @@ -62,7 +62,8 @@ variant="outline-primary" :disabled="!tabs[currentTab + 1].active" @click.prevent="next" - >{{ $t("buttons.next") }} + > + {{ $t("buttons.next") }} </b-button> </b-form-group> </div> @@ -171,15 +172,23 @@ export default defineComponent({ }, }, - created() { + async created() { this.isLoading = true; this.getGroupedApplicationProfilesList(); - this.fetchData(); + await this.fetchData(); this.isLoading = false; }, methods: { async fetchData() { + // Load Quotas for the project if not present + if (this.projectStore.currentQuotas === null) { + await this.projectStore.retrieveQuotas(this.project); + } + // Load list of Enabled Resource Types if not present + if (this.resourceStore.resourceTypes === null) { + await this.resourceStore.retrieveResourceTypes(); + } // Load Project Visibilities if not present if (this.projectStore.visibilities === null) { await this.projectStore.retrieveVisibilities(); diff --git a/src/modules/resource/pages/Settings.vue b/src/modules/resource/pages/Settings.vue index 55be8a1d10e97d57cfb9d685860893746abaafd0..986ea157cf2d08541b14c31c24299ee4ca5cecd2 100644 --- a/src/modules/resource/pages/Settings.vue +++ b/src/modules/resource/pages/Settings.vue @@ -40,6 +40,7 @@ v-model="resourceForm" :application-profile="applicationProfile" :is-loading-form-generator="isLoading" + :is-user-allowed-to-edit="isUserAllowedToEdit" @clickSave="clickSave" /> @@ -48,6 +49,7 @@ v-if="resource" v-show="tabs[currentTab].step === 'action'" :resource-form="resource" + :is-user-allowed-to-edit="isUserAllowedToEdit" @toggleArchive="toggleArchive" @clickDelete="clickDelete" /> @@ -75,6 +77,7 @@ import { defineComponent } from "vue"; // import the store for current module import useResourceStore from "../store"; import useProjectStore from "@/modules/project/store"; +import useUserStore from "@/modules/user/store"; import { navigateToProject } from "@/router"; import General from "../components/create-resource/General.vue"; import MetadataView from "../components/settings/MetadataView.vue"; @@ -91,6 +94,7 @@ import type { ResourceCreationTab, ResourceTypeOption } from "../types"; import type { ProjectObject } from "@coscine/api-client/dist/types/Coscine.Api.Project"; import useNotificationStore from "@/store/notification"; import type { Validation } from "@vuelidate/core"; +import type { UserObject } from "@coscine/api-client/dist/types/Coscine.Api.User"; export default defineComponent({ components: { @@ -103,9 +107,10 @@ export default defineComponent({ setup() { const resourceStore = useResourceStore(); const projectStore = useProjectStore(); + const userStore = useUserStore(); const notificationStore = useNotificationStore(); - return { resourceStore, projectStore, notificationStore }; + return { resourceStore, projectStore, userStore, notificationStore }; }, data() { @@ -198,6 +203,25 @@ export default defineComponent({ } return tabs; }, + isOwner(): boolean | undefined { + return this.projectStore.currentUserRoleIsOwner; + }, + user(): UserObject | null { + return this.userStore.user; + }, + isResourceCreator(): boolean | undefined { + if (this.resourceForm.creator && this.user && this.user.id) { + return this.resourceForm.creator === this.user.id; + } else { + return undefined; + } + }, + isUserAllowedToEdit(): boolean { + if ((this.isOwner || this.isResourceCreator) && this.resourceForm) { + return true; + } + return false; + }, }, watch: {