Select Git revision
Configuration.vue

Ashish Shetty authored and
Petar Hristov
committed
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
Configuration.vue 11.37 KiB
<template>
<div class="setup">
<!-- Resource Type Dropdown -->
<div v-if="resourceTypes && resourceTypes.length > 0">
<CoscineFormGroup
:mandatory="true"
label-for="ResourceTypes"
:label="$t('page.createResource.configuration.labels.resourceType')"
:is-loading="isLoading"
:info="true"
>
<template #popover>
{{
$t("page.createResource.configuration.labels.resourceTypePopover")
}}
<b-link
:href="
$t(
'page.createResource.configuration.labels.resourceTypePopoverUrl'
).toString()
"
target="_blank"
>{{ $t("default.help") }}
</b-link>
</template>
<multiselect
v-if="resourceTypes.length > 1"
id="ResourceTypes"
v-model="selectedResourceType"
:options="resourceTypes"
:multiple="false"
:hide-selected="false"
label="iDisplayName"
track-by="iDisplayName"
:show-labels="false"
:placeholder="
$t('page.createResource.multiselect.placeholderResourceText')
"
select-label=""
selected-label=""
deselect-label=""
@input="setSelectedResourceTypeInformation"
>
<span slot="noResult">{{
$t("page.createResource.multiselect.noResults")
}}</span>
<span slot="noOptions">{{
$t("page.createResource.multiselect.noOptions")
}}</span>
</multiselect>
<!-- Resource Text Field (see condition) -->
<b-form-input
v-else-if="resourceTypes.length === 1 && selectedResourceType"
id="ResourceType"
v-model="selectedResourceType.iDisplayName"
disabled
/>
<!-- Hint -->
<template #hint>
<!-- Logged in with ORCID -->
<i18n
v-if="externalUser"
path="page.createResource.configuration.labels.hintTextORCiD"
tag="span"
>
<template #userProfile>
<b-link :to="{ name: 'userprofile' }">
{{ $t("breadcrumbs.user.profile") }}
</b-link>
</template>
</i18n>
<!-- Logged in with SSO -->
<span v-else>
{{
$t("page.createResource.configuration.labels.hintTextSSO", {
organizationName: organizations[0],
})
}}
</span>
</template>
</CoscineFormGroup>
<!-- Resource Description -->
<CoscineFormGroup
v-if="selectedResourceType"
:label="`${selectedResourceType.iFullName}:`"
>
<p>{{ selectedResourceType.iDescription }}</p>
</CoscineFormGroup>
</div>
<!-- Setup Slider -->
<ConfigurationSizeSlider v-if="resourceTypeHasSize" v-model="resource" />
<GitLab
v-if="
selectedResourceType && selectedResourceType.displayName === 'gitlab'
"
v-model="resource"
/>
<!-- Button Next (wrapper needed for Popover) -->
<div id="divButtonNext" class="float-right">
<b-button
variant="outline-primary"
:disabled="!valid"
@click.prevent="next"
>
{{ $t("buttons.next") }}
</b-button>
</div>
<!-- Popover -->
<b-popover
v-if="
resource.resourceTypeOption &&
resource.resourceTypeOption.Size <= 0 &&
resourceTypeHasSize
"
target="divButtonNext"
:title="$t('page.createResource.configuration.popover.title')"
placement="top"
triggers="hover"
:delay="{ show: 0, hide: 500 }"
>
{{ $t("page.createResource.configuration.popover.body") }}
<!-- Router Link -->
<router-link v-if="isOwner" :to="{ name: 'project-quota' }">
{{ $t("page.createResource.configuration.needMore") }}
</router-link>
</b-popover>
</div>
</template>
<script lang="ts">
import { defineComponent, type PropType } from "vue";
// import the store for current module
import useResourceStore from "../../store";
import useProjectStore from "@/modules/project/store";
// import the main store
import useMainStore from "@/store/index";
import ConfigurationSizeSlider from "./ConfigurationSizeSlider.vue";
import "@/plugins/deprecated/vue-multiselect";
import type {
ResourceCreateObject,
ResourceObject,
ResourceTypeInformation,
ResourceTypeObject,
} from "@coscine/api-client/dist/types/Coscine.Api.Resources";
import type { LabeledResourceObject, ResourceTypeOption } from "../../types";
import useUserStore from "@/modules/user/store";
import type { OrganizationObject } from "@coscine/api-client/dist/types/Coscine.Api.Organization";
export default defineComponent({
components: {
ConfigurationSizeSlider,
GitLab: () => import("./resource-type/GitLab.vue"),
},
props: {
value: {
type: Object as PropType<ResourceObject>,
required: true,
},
isLoading: {
default: false,
type: Boolean,
},
},
emits: {
valid: (_: boolean) => true,
next: null,
input: (_: ResourceObject) => true,
},
setup() {
const mainStore = useMainStore();
const projectStore = useProjectStore();
const resourceStore = useResourceStore();
const userStore = useUserStore();
return { mainStore, projectStore, resourceStore, userStore };
},
data() {
return {
resource: this.value,
selectedResourceType: null as LabeledResourceObject | null,
};
},
computed: {
isOwner(): boolean | undefined {
return this.projectStore.currentUserRoleIsOwner;
},
organizations(): string[] {
if (this.userMemberships) {
return this.userMemberships
.filter((organization) => !(organization.url?.indexOf("#") !== -1)) // If does contain "#" it's a sub level organization, otherwise top level
.map((org) => (org.displayName ? org.displayName : "")) // Extract organization display name, could contain empty strings
.filter((n) => n); // Filter out empty strings, if any;
}
return [];
},
organizationsSet(): boolean {
return this.organizations && this.organizations.length > 0;
},
externalUser(): boolean {
return !this.organizationsSet;
},
userMemberships(): null | OrganizationObject[] {
return this.userStore.userProfile.userMemberships;
},
resourceTypes(): LabeledResourceObject[] | null {
const labeledResourceTypes: LabeledResourceObject[] = [];
const resourceTypes = this.resourceStore.enabledResourceTypes;
if (resourceTypes) {
resourceTypes.forEach((r) => {
const labeledResourceType: LabeledResourceObject = {
iDisplayName: this.$t(
"resourceTypes." + r.displayName + ".displayName"
).toString(),
iFullName: this.$t(
"resourceTypes." + r.displayName + ".fullName"
).toString(),
iDescription: this.$t(
"resourceTypes." + r.displayName + ".description"
).toString(),
};
Object.assign(labeledResourceType, r);
labeledResourceTypes.push(labeledResourceType);
});
return labeledResourceTypes.sort((a, b) => {
const valueA = a.iDisplayName.toUpperCase();
const valueB = b.iDisplayName.toUpperCase();
return valueA < valueB ? -1 : valueA > valueB ? 1 : 0;
});
} else {
return null;
}
},
resourceTypeHasSize(): boolean {
if (
this.selectedResourceType &&
this.selectedResourceType.resourceCreate &&
this.selectedResourceType.resourceCreate.components
) {
return (
this.selectedResourceType.resourceCreate.components.flatMap((e) =>
e.filter((z) => z === "Size")
).length > 0
);
} else {
return false;
}
},
valid(): boolean {
// Ensure a resource type is selected and its ID is consistent across the options and the target object
if (
this.selectedResourceType &&
this.resource.type &&
this.selectedResourceType.id === this.resource.type.id
) {
// Evaluate resource types that have quota, require Size has been set and is a positive number
if (
this.selectedResourceType.isQuotaAvailable &&
this.selectedResourceType.isQuotaAdjustable
) {
return (
(this.resource.resourceTypeOption as ResourceTypeOption).Size > 0
);
}
// Evaluate resource type specific - GitLab
else if (this.resource.type.displayName === "gitlab") {
return (
this.resource.resourceTypeOption &&
this.resource.resourceTypeOption["RepoUrl"] &&
this.resource.resourceTypeOption["AccessToken"] &&
this.resource.resourceTypeOption["ProjectId"] &&
this.resource.resourceTypeOption["Branch"] &&
this.resource.resourceTypeOption["TosAccepted"]
);
}
// Evaluate resource type specific - Linked Data
else if (this.resource.type.displayName === "linked") {
return true;
}
}
return false;
},
},
watch: {
resource: {
handler() {
this.$emit("input", this.resource);
},
deep: true,
},
resourceTypes() {
this.onResourceTypesLoaded();
this.initTabContent();
},
valid() {
this.$emit("valid", this.valid);
},
},
created() {
this.onResourceTypesLoaded();
this.initTabContent();
this.mainStore.$subscribe((mutation) => {
if (mutation.type == "patch function") {
this.initTabContent();
}
});
},
methods: {
next() {
this.$emit("next");
},
initTabContent() {
if (this.resourceTypes && this.resource.type && this.resource.type.id) {
// A resource type has been selected, but the dropdown is empty. Set selection in dropdown.
const selection = this.resourceTypes.find(
(r) => r.id === this.resource.type?.id
);
if (selection) {
this.selectedResourceType = selection;
}
}
},
onResourceTypesLoaded() {
if (this.resourceTypes && this.resourceTypes.length === 1) {
this.setSelectedResourceTypeInformation(this.resourceTypes[0]);
}
},
setSelectedResourceTypeInformation(
resourceTypeInformation: ResourceTypeInformation | null
) {
if (resourceTypeInformation) {
// Set Resource Type
const type: ResourceTypeObject = {
id: resourceTypeInformation.id,
displayName: resourceTypeInformation.displayName,
};
this.$set(this.resource, "type", type);
// Set Resource Type Options
const resourceTypeOptions: ResourceCreateObject = {};
if (
resourceTypeInformation.resourceCreate &&
resourceTypeInformation.resourceCreate.components
) {
for (const key of resourceTypeInformation.resourceCreate
.components[0]) {
Object.assign(resourceTypeOptions, { [key]: undefined });
}
this.$set(this.resource, "resourceTypeOption", resourceTypeOptions);
}
} else {
this.$set(this.resource, "type", undefined);
this.$set(this.resource, "resourceTypeOption", undefined);
}
},
},
});
</script>
<style></style>