Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • coscine/frontend/apps/ui
1 result
Select Git revision
Show changes
Commits on Source (20)
Showing
with 378 additions and 64 deletions
# Coscine UIv2 # Coscine UI
## Routes [[_TOC_]]
Currently available routes in Coscine (Vue Router):
* `./profile` for user profile ## 📝 Overview
* `./search` for global search
* `./create-project` for project create The User Interface (UI) project is a comprehensive frontend application that facilitates interaction with the Coscine environment and its API. Built using Vue and TypeScript, it leverages a range of powerful tools including Bootstrap Vue, Vue Router, Pinia, and Vue i18n. It is the central repository for the entire Coscine user interface.
* `./p/{slug}` for projects
* `./p/{slug}/settings` for project settings ## ⚙️ Configuration
* `./p/{slug}/members` for project members
* `./p/{slug}/quota` for project quota
* `./p/{slug}/create-resource` for resource create
* `./p/{slug}/r/{guid}` for resources within a project
* `./p/{slug}/r/{guid}/settings` for resource edit
* `./admin` for admin page
* `./login` for login page
## Development
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://git.rwth-aachen.de/coscine/frontend/apps/ui) [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://git.rwth-aachen.de/coscine/frontend/apps/ui)
(For a specific branch, build such a URL: `https://gitpod.io/#https://git.rwth-aachen.de/coscine/frontend/apps/ui/tree/{branch}`) (For a specific branch, build such a URL: `https://gitpod.io/#https://git.rwth-aachen.de/coscine/frontend/apps/ui/tree/{branch}`)
## Commands ## 📖 Usage
This project uses [Yarn](https://yarnpkg.com/) and [Node.js](https://nodejs.org/en/) to manage its dependencies. This project uses [Yarn](https://yarnpkg.com/) and [Node.js](https://nodejs.org/en/) to manage its dependencies.
### Project setup
``` ```
yarn install yarn install
``` ```
...@@ -56,3 +45,29 @@ yarn lint ...@@ -56,3 +45,29 @@ yarn lint
yarn lint:fix yarn lint:fix
``` ```
## 👥 Contributing
As an open source plattform and project, we welcome contributions from our community in any form. You can do so by submitting bug reports or feature requests, or by directly contributing to Coscine's source code. To submit your contribution please follow our [Contributing Guideline](https://git.rwth-aachen.de/coscine/docs/public/wiki/-/blob/master/Contributing%20To%20Coscine.md).
## 📄 License
The current open source repository is licensed under the **MIT License**, which is a permissive license that allows the software to be used, modified, and distributed for both commercial and non-commercial purposes, with limited restrictions (see `LICENSE` file)
> The MIT License allows for free use, modification, and distribution of the software and its associated documentation, subject to certain conditions. The license requires that the copyright notice and permission notice be included in all copies or substantial portions of the software. The software is provided "as is" without any warranties, and the authors or copyright holders cannot be held liable for any damages or other liability arising from its use.
## 🆘 Support
1. **Check the documentation**: Before reaching out for support, check the help pages provided by the team at https://docs.coscine.de/en/. This may have the information you need to solve the issue.
2. **Contact the team**: If the documentation does not help you or if you have a specific question, you can reach out to our support team at `servicedesk@itc.rwth-aachen.de` 📧. Provide a detailed description of the issue you're facing, including any error messages or screenshots if applicable.
3. **Be patient**: Our team will do their best to provide you with the support you need, but keep in mind that they may have a lot of requests to handle. Be patient and wait for their response.
4. **Provide feedback**: If the support provided by our support team helps you solve the issue, let us know! This will help us improve our documentation and support processes for future users.
By following these simple steps, you can get the support you need to use Coscine's services as an external user.
## 📦 Release & Changelog
External users can find the _Releases and Changelog_ inside each project's repository. The repository contains a section for Releases (`Deployments > Releases`), where users can find the latest release changelog and source. Withing the Changelog you can find a list of all the changes made in that particular release and version.
By regularly checking for new releases and changes in the Changelog, you can stay up-to-date with the latest improvements and bug fixes by our team and community!
{ {
"name": "ui", "name": "ui",
"version": "1.26.1", "version": "1.27.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
...@@ -101,7 +101,7 @@ ...@@ -101,7 +101,7 @@
"vitest": "^0.27.1", "vitest": "^0.27.1",
"vue-template-compiler": "^2.7.14" "vue-template-compiler": "^2.7.14"
}, },
"packageManager": "yarn@3.4.1", "packageManager": "yarn@3.5.0",
"resolutions": { "resolutions": {
"readable-stream": "3.6.0" "readable-stream": "3.6.0"
} }
......
...@@ -5,7 +5,7 @@ export default { ...@@ -5,7 +5,7 @@ export default {
admin: { admin: {
headline: "Adminseite", headline: "Adminseite",
projectInputPlaceholder: "Projekt-GUID oder -Slug eingeben", projectInputPlaceholder: "Projekt Id oder -Slug eingeben",
projectFound: "Projekt gefunden", projectFound: "Projekt gefunden",
projectNotSelected: "Kein Projekt ausgewählt", projectNotSelected: "Kein Projekt ausgewählt",
...@@ -21,7 +21,7 @@ export default { ...@@ -21,7 +21,7 @@ export default {
displayNameLabel: displayNameLabel:
"@:(page.admin.form.displayName)@:(page.admin.form.labelSymbol)", "@:(page.admin.form.displayName)@:(page.admin.form.labelSymbol)",
projectId: "GUID", projectId: "Projekt Id",
projectIdLabel: projectIdLabel:
"@:(page.admin.form.projectId)@:(page.admin.form.labelSymbol)", "@:(page.admin.form.projectId)@:(page.admin.form.labelSymbol)",
}, },
...@@ -31,7 +31,7 @@ export default { ...@@ -31,7 +31,7 @@ export default {
headers: { headers: {
resourceType: "Ressourcentyp", resourceType: "Ressourcentyp",
projectQuota: "Aktuelle Projektquota", projectQuota: "Aktuelle Projektquota",
resourceQuota: "Aktielle Ressourcenquota", resourceQuota: "Aktuelle Ressourcenquota",
maximumQuota: "Maximale Quota", maximumQuota: "Maximale Quota",
maximumQuotaHint: maximumQuotaHint:
......
...@@ -5,7 +5,7 @@ export default { ...@@ -5,7 +5,7 @@ export default {
admin: { admin: {
headline: "Quota Admin Panel", headline: "Quota Admin Panel",
projectInputPlaceholder: "Enter a project's Slug or GUID", projectInputPlaceholder: "Enter a project's Slug or Id",
projectFound: "Project found", projectFound: "Project found",
projectNotSelected: "No project selected", projectNotSelected: "No project selected",
...@@ -21,7 +21,7 @@ export default { ...@@ -21,7 +21,7 @@ export default {
displayNameLabel: displayNameLabel:
"@:(page.admin.form.displayName)@:(page.admin.form.labelSymbol)", "@:(page.admin.form.displayName)@:(page.admin.form.labelSymbol)",
projectId: "GUID", projectId: "Project Id",
projectIdLabel: projectIdLabel:
"@:(page.admin.form.projectId)@:(page.admin.form.labelSymbol)", "@:(page.admin.form.projectId)@:(page.admin.form.labelSymbol)",
}, },
......
...@@ -18,7 +18,7 @@ export default { ...@@ -18,7 +18,7 @@ export default {
contactPidOwnerDescription: contactPidOwnerDescription:
"In den meisten Fällen sind die referenzierten Daten nicht öffentlich zugänglich. Sie können sich daher an den Besitzer der Daten wenden und um Zugang bitten. Der Besitzer dieser Ressource wird dann von Coscine kontaktiert. Die Informationen, die Sie im Formular angeben, werden so an den Besitzer weitergeleitet.", "In den meisten Fällen sind die referenzierten Daten nicht öffentlich zugänglich. Sie können sich daher an den Besitzer der Daten wenden und um Zugang bitten. Der Besitzer dieser Ressource wird dann von Coscine kontaktiert. Die Informationen, die Sie im Formular angeben, werden so an den Besitzer weitergeleitet.",
toClipboard: "PID wurde in der Zwischenablage kopiert", toClipboard: "PID wurde in die Zwischenablage kopiert",
form: { form: {
labelSymbol: ":", labelSymbol: ":",
...@@ -28,8 +28,7 @@ export default { ...@@ -28,8 +28,7 @@ export default {
"@:(page.pid.form.persistentId)@:(page.pid.form.labelSymbol)", "@:(page.pid.form.persistentId)@:(page.pid.form.labelSymbol)",
persistentIdPopover: persistentIdPopover:
"Für weitere Informationen zum @:(page.pid.form.persistentId) siehe", "Für weitere Informationen zum @:(page.pid.form.persistentId) siehe",
persistentIdPopoverUrl: persistentIdPopoverUrl: "https://docs.coscine.de/de/rdm/publishing/",
"https://help.itc.rwth-aachen.de/service/b2b7729fd93f4c7080b475776f6b5d87/article/d5c6ef062cc24c9a84dcb774d0bbc021/",
yourName: "Ihr Name", yourName: "Ihr Name",
yourNameLabel: yourNameLabel:
......
...@@ -28,8 +28,7 @@ export default { ...@@ -28,8 +28,7 @@ export default {
"@:(page.pid.form.persistentId)@:(page.pid.form.labelSymbol)", "@:(page.pid.form.persistentId)@:(page.pid.form.labelSymbol)",
persistentIdPopover: persistentIdPopover:
"For more information on @:(page.pid.form.persistentId) see", "For more information on @:(page.pid.form.persistentId) see",
persistentIdPopoverUrl: persistentIdPopoverUrl: "https://docs.coscine.de/en/rdm/publishing/",
"https://help.itc.rwth-aachen.de/en/service/b2b7729fd93f4c7080b475776f6b5d87/article/d5c6ef062cc24c9a84dcb774d0bbc021/",
yourName: "Your Name", yourName: "Your Name",
yourNameLabel: yourNameLabel:
......
...@@ -206,6 +206,21 @@ export default { ...@@ -206,6 +206,21 @@ export default {
projectDescriptionLabel: projectDescriptionLabel:
"@:(form.project.projectDescription)@:(form.project.labelSymbol)", "@:(form.project.projectDescription)@:(form.project.labelSymbol)",
projectSlug: "Slug",
projectSlugLabel:
"@:(form.project.projectSlug)@:(form.project.labelSymbol)",
projectId: "Projekt Id",
projectIdLabel: "@:(form.project.projectId)@:(form.project.labelSymbol)",
projectPersistentId: "Persistent Identifier (PID)",
projectPersistentIdLabel:
"@:(form.project.projectPersistentId)@:(form.project.labelSymbol)",
projectPersistentIdPopover:
"Für weitere Informationen zum @:(form.project.projectPersistentId) siehe",
projectPersistentIdPopoverUrl:
"https://docs.coscine.de/de/rdm/publishing/",
activatedImportFromParent: "Projekt-Metadaten", activatedImportFromParent: "Projekt-Metadaten",
copyMetadataLabel: copyMetadataLabel:
...@@ -232,6 +247,12 @@ export default { ...@@ -232,6 +247,12 @@ export default {
projectOrganization: "Teilnehmende Organisationen", projectOrganization: "Teilnehmende Organisationen",
projectOrganizationLabel: projectOrganizationLabel:
"@:(form.project.projectOrganization)@:(form.project.labelSymbol)", "@:(form.project.projectOrganization)@:(form.project.labelSymbol)",
projectOrganizationHint:
"Wenn Ihre Organisation nicht in der Liste erscheint, geben Sie bitte ihren Namen in das Feld ein, um nach ihr zu suchen.",
projectOrganizationLabelPopover:
"Für weitere Informationen zu teilnehmenden Organisationen siehe",
projectOrganizationLabelPopoverUrl:
"https://docs.coscine.de/de/projects/create/",
projectOrganizationNoOptions: "Suche nach Organisationen", projectOrganizationNoOptions: "Suche nach Organisationen",
projectOrganizationNoResult: projectOrganizationNoResult:
"Keine Organisationen gefunden, die der Suche entsprechen", "Keine Organisationen gefunden, die der Suche entsprechen",
...@@ -259,6 +280,8 @@ export default { ...@@ -259,6 +280,8 @@ export default {
"Dieses Feld besitzt eine Maximallänge von {maxLength} Zeichen.", "Dieses Feld besitzt eine Maximallänge von {maxLength} Zeichen.",
projectGrantIdLabel: projectGrantIdLabel:
"@:(form.project.projectGrantId)@:(form.project.labelSymbol)", "@:(form.project.projectGrantId)@:(form.project.labelSymbol)",
toClipboard: "{projectOption} wurde in die Zwischenablage kopiert",
}, },
}, },
} as VueI18n.LocaleMessageObject; } as VueI18n.LocaleMessageObject;
...@@ -201,6 +201,21 @@ export default { ...@@ -201,6 +201,21 @@ export default {
projectDescriptionLabel: projectDescriptionLabel:
"@:(form.project.projectDescription)@:(form.project.labelSymbol)", "@:(form.project.projectDescription)@:(form.project.labelSymbol)",
projectSlug: "Slug",
projectSlugLabel:
"@:(form.project.projectSlug)@:(form.project.labelSymbol)",
projectId: "Project Id",
projectIdLabel: "@:(form.project.projectId)@:(form.project.labelSymbol)",
projectPersistentId: "Persistent Identifier (PID)",
projectPersistentIdLabel:
"@:(form.project.projectPersistentId)@:(form.project.labelSymbol)",
projectPersistentIdPopover:
"For more information on @:(form.project.projectPersistentId) see",
projectPersistentIdPopoverUrl:
"https://docs.coscine.de/en/rdm/publishing/",
activatedImportFromParent: "Project Metadata", activatedImportFromParent: "Project Metadata",
copyMetadataLabel: copyMetadataLabel:
...@@ -227,6 +242,12 @@ export default { ...@@ -227,6 +242,12 @@ export default {
projectOrganization: "Participating Organizations", projectOrganization: "Participating Organizations",
projectOrganizationLabel: projectOrganizationLabel:
"@:(form.project.projectOrganization)@:(form.project.labelSymbol)", "@:(form.project.projectOrganization)@:(form.project.labelSymbol)",
projectOrganizationHint:
"If your organization does not appear in the list, please enter its name in the field to search for it.",
projectOrganizationLabelPopover:
"For more information on participating Organizations see",
projectOrganizationLabelPopoverUrl:
"https://docs.coscine.de/en/projects/create/",
projectOrganizationNoOptions: "Search for organizations", projectOrganizationNoOptions: "Search for organizations",
projectOrganizationNoResult: "No organizations found matching the search", projectOrganizationNoResult: "No organizations found matching the search",
...@@ -253,6 +274,8 @@ export default { ...@@ -253,6 +274,8 @@ export default {
"This field can only contain up to {maxLength} characters.", "This field can only contain up to {maxLength} characters.",
projectGrantIdLabel: projectGrantIdLabel:
"@:(form.project.projectGrantId)@:(form.project.labelSymbol)", "@:(form.project.projectGrantId)@:(form.project.labelSymbol)",
toClipboard: "{projectOption} has been copied to clipboard",
}, },
}, },
} as VueI18n.LocaleMessageObject; } as VueI18n.LocaleMessageObject;
...@@ -12,6 +12,12 @@ ...@@ -12,6 +12,12 @@
@validation="formValidations.naming = $event" @validation="formValidations.naming = $event"
/><!-- TODO: Fix @validation assignment and typing --> /><!-- TODO: Fix @validation assignment and typing -->
<FormReadonlyData
v-model="projectForm"
:disabled="!isOwner"
:is-loading="isLoading"
/>
<div class="h-divider" /> <div class="h-divider" />
<FormMetadata <FormMetadata
...@@ -74,6 +80,7 @@ ...@@ -74,6 +80,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from "vue"; import { defineComponent } from "vue";
import FormNaming from "./components/FormNaming.vue"; import FormNaming from "./components/FormNaming.vue";
import FormReadonlyData from "./components/FormReadonlyData.vue";
import FormMetadata from "./components/FormMetadata.vue"; import FormMetadata from "./components/FormMetadata.vue";
import DeleteProjectModal from "./components/modals/DeleteProjectModal.vue"; import DeleteProjectModal from "./components/modals/DeleteProjectModal.vue";
...@@ -93,6 +100,7 @@ import type { Validation } from "@vuelidate/core"; ...@@ -93,6 +100,7 @@ import type { Validation } from "@vuelidate/core";
export default defineComponent({ export default defineComponent({
components: { components: {
FormNaming, FormNaming,
FormReadonlyData,
FormMetadata, FormMetadata,
DeleteProjectModal, DeleteProjectModal,
}, },
...@@ -108,6 +116,8 @@ export default defineComponent({ ...@@ -108,6 +116,8 @@ export default defineComponent({
projectForm: { projectForm: {
description: "", description: "",
displayName: "", displayName: "",
id: "",
pid: "",
startDate: "", startDate: "",
endDate: "", endDate: "",
keywords: "", keywords: "",
......
...@@ -148,7 +148,24 @@ ...@@ -148,7 +148,24 @@
:label="$t('form.project.projectOrganizationLabel')" :label="$t('form.project.projectOrganizationLabel')"
:is-loading="isLoading" :is-loading="isLoading"
type="input" type="input"
:info="true"
> >
<!-- Hint -->
<template #hint>
{{ $t("form.project.projectOrganizationHint") }}
</template>
<template #popover>
{{ $t("form.project.projectOrganizationLabelPopover") }}
<b-link
:href="
$t('form.project.projectOrganizationLabelPopoverUrl').toString()
"
target="_blank"
>{{ $t("default.help") }}
</b-link>
</template>
<multiselect <multiselect
id="Organization" id="Organization"
v-model="v$.projectForm.organizations.$model" v-model="v$.projectForm.organizations.$model"
......
<template>
<div>
<!-- Project Slug -->
<CoscineFormGroup
label-for="Slug"
:label="$t('form.project.projectSlugLabel')"
:is-loading="isLoading"
type="input"
>
<b-form-input
id="ProjectSlug"
v-model="projectForm.slug"
:readonly="readonly"
required
/>
</CoscineFormGroup>
<!-- Project Id -->
<CoscineFormGroup
label-for="Id"
:label="$t('form.project.projectIdLabel')"
:is-loading="isLoading"
type="input"
>
<b-form-input
id="ProjectId"
v-model="projectForm.id"
:readonly="readonly"
required
/>
</CoscineFormGroup>
<!-- Project Persistent Identifier -->
<CoscineFormGroup
label-for="ProjectPersistentId"
:label="$t('form.project.projectPersistentIdLabel')"
:is-loading="isLoading"
:info="true"
>
<template #popover>
{{ $t("form.project.projectPersistentIdPopover") }}
<b-link
:href="$t('form.project.projectPersistentIdPopoverUrl').toString()"
target="_blank"
>
{{ $t("default.help") }}
</b-link>
</template>
<b-button-group class="w-100">
<!-- Text Field -->
<b-form-input
id="ProjectPersistentId"
v-model="projectForm.pid"
required
:readonly="readonly"
/>
<!-- Copy Button -->
<b-button id="copyPidButton" @click="copyPid()">
<b-icon icon="clipboard" />
</b-button>
<!-- Copied Tooltip -->
<b-tooltip
id="copyPidTooltip"
target="copyPidButton"
placement="top"
triggers="blur"
>
{{
$t("form.project.toClipboard", {
projectOption: $t("form.project.projectPersistentId"),
})
}}
</b-tooltip>
</b-button-group>
</CoscineFormGroup>
</div>
</template>
<script lang="ts">
import { defineComponent, PropType } from "vue";
import type { ProjectObject } from "@coscine/api-client/dist/types/Coscine.Api.Project";
export default defineComponent({
props: {
value: {
type: Object as PropType<ProjectObject>,
required: true,
},
isLoading: {
default: false,
type: Boolean,
},
},
data() {
return {
readonly: true,
projectForm: this.value,
};
},
methods: {
copyPid() {
if (this.projectForm) {
navigator.clipboard.writeText(
"http://hdl.handle.net/" + this.projectForm.pid
);
this.$root.$emit("bv::show::tooltip", "copyPidTooltip");
}
},
},
});
</script>
...@@ -16,6 +16,20 @@ ...@@ -16,6 +16,20 @@
<b-col class="user-details"> <b-col class="user-details">
<!-- Member Display Name --> <!-- Member Display Name -->
{{ projectRole.user ? projectRole.user.displayName : "" }} {{ projectRole.user ? projectRole.user.displayName : "" }}
<!-- Member Role Badge-->
<span
v-if="
projectRole.user &&
currentUser &&
projectRole.user.id === currentUser.id
"
class="badge badge-pill badge-primary ml-2"
>
{{ projectRole.role?.displayName }}
</span>
<span v-else class="badge badge-pill badge-secondary ml-2">
{{ projectRole.role?.displayName }}
</span>
<br /> <br />
<!-- Member Email --> <!-- Member Email -->
<a <a
......
<template> <template>
<div class="metadata"> <div class="applicationProfile">
<div> <div>
<!-- Application Profile Dropdown --> <!-- Application Profile Dropdown -->
<CoscineFormGroup <CoscineFormGroup
label-for="ApplicationProfiles" label-for="ApplicationProfiles"
:mandatory="true" :mandatory="true"
:label="$t('page.createResource.metadata.applicationProfileLabel')" :label="
$t('page.createResource.applicationProfile.applicationProfileLabel')
"
:info="true" :info="true"
> >
<template #popover> <template #popover>
{{ $t("page.createResource.metadata.applicationProfilePopover") }} {{
$t(
"page.createResource.applicationProfile.applicationProfilePopover"
)
}}
<b-link <b-link
:href=" :href="
$t( $t(
'page.createResource.metadata.applicationProfilePopoverUrl' 'page.createResource.applicationProfile.applicationProfilePopoverUrl'
).toString() ).toString()
" "
target="_blank" target="_blank"
...@@ -27,14 +33,18 @@ ...@@ -27,14 +33,18 @@
v-model="selectedApplicationProfile" v-model="selectedApplicationProfile"
:options="applicationProfileList" :options="applicationProfileList"
:placeholder=" :placeholder="
$t('page.createResource.metadata.selectApplicationProfile') $t(
'page.createResource.applicationProfile.selectApplicationProfile'
)
" "
@change="notifyFormGenerator" @change="notifyFormGenerator"
> >
<template #first> <template #first>
<b-form-select-option :value="null" disabled> <b-form-select-option :value="null" disabled>
{{ {{
$t("page.createResource.metadata.selectApplicationProfile") $t(
"page.createResource.applicationProfile.selectApplicationProfile"
)
}} }}
</b-form-select-option> </b-form-select-option>
</template> </template>
...@@ -56,7 +66,9 @@ ...@@ -56,7 +66,9 @@
</div> </div>
<b-tooltip target="createButton" triggers="hover"> <b-tooltip target="createButton" triggers="hover">
<i18n path="page.createResource.metadata.createAp.tooltip" /> <i18n
path="page.createResource.applicationProfile.createAp.tooltip"
/>
</b-tooltip> </b-tooltip>
</CoscineFormGroup> </CoscineFormGroup>
</div> </div>
......
...@@ -33,18 +33,18 @@ ...@@ -33,18 +33,18 @@
</CoscineFormGroup> </CoscineFormGroup>
</b-card> </b-card>
<!-- General Information --> <!-- Resource Metadata Information -->
<b-card class="my-2"> <b-card class="my-2">
<b-link class="float-right text-primary" @click.prevent="toTab(tabs[1])"> <b-link class="float-right text-primary" @click.prevent="toTab(tabs[1])">
{{ $t("page.createResource.overview.edit") }} {{ $t("page.createResource.overview.edit") }}
</b-link> </b-link>
<CoscineHeadline :headline="$t('form.steps.second')" h="h5" /> <CoscineHeadline :headline="$t('form.steps.second')" h="h5" />
<!-- General --> <!-- Resource Metadata -->
<General v-model="resource" :readonly="true" /> <ResourceMetadata v-model="resource" :readonly="true" />
</b-card> </b-card>
<!-- Metadata --> <!-- Application Profile -->
<b-card class="my-2 p-0"> <b-card class="my-2 p-0">
<b-link class="float-right text-primary" @click.prevent="toTab(tabs[2])"> <b-link class="float-right text-primary" @click.prevent="toTab(tabs[2])">
{{ $t("page.createResource.overview.edit") }} {{ $t("page.createResource.overview.edit") }}
...@@ -96,7 +96,7 @@ import useResourceStore from "@/modules/resource/store"; ...@@ -96,7 +96,7 @@ import useResourceStore from "@/modules/resource/store";
import useProjectStore from "@/modules/project/store"; import useProjectStore from "@/modules/project/store";
import useUserStore from "@/modules/user/store"; import useUserStore from "@/modules/user/store";
import "@/plugins/form-generator"; import "@/plugins/form-generator";
import General from "./General.vue"; import ResourceMetadata from "./ResourceMetadata.vue";
import { navigateToProject } from "@/router"; import { navigateToProject } from "@/router";
import type { Dataset } from "@rdfjs/types"; import type { Dataset } from "@rdfjs/types";
import type { ResourceObject } from "@coscine/api-client/dist/types/Coscine.Api.Resources"; import type { ResourceObject } from "@coscine/api-client/dist/types/Coscine.Api.Resources";
...@@ -107,7 +107,7 @@ import type { UserObject } from "@coscine/api-client/dist/types/Coscine.Api.User ...@@ -107,7 +107,7 @@ import type { UserObject } from "@coscine/api-client/dist/types/Coscine.Api.User
import useNotificationStore from "@/store/notification"; import useNotificationStore from "@/store/notification";
export default defineComponent({ export default defineComponent({
components: { General }, components: { ResourceMetadata },
props: { props: {
value: { value: {
type: Object as PropType<ResourceObject>, type: Object as PropType<ResourceObject>,
......
<template> <template>
<div class="general"> <div class="resourceMetadata">
<!-- Form --> <!-- Form -->
<b-form id="edit_form" @submit.stop.prevent=""> <b-form id="edit_form" @submit.stop.prevent="">
<!-- Resource Name --> <!-- Resource Name -->
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
<div class="modal"> <div class="modal">
<b-modal <b-modal
id="createAPModal" id="createAPModal"
:title="$t('page.createResource.metadata.createAp.title')" :title="$t('page.createResource.applicationProfile.createAp.title')"
:hide-footer="true" :hide-footer="true"
> >
<!-- Body --> <!-- Body -->
<i18n path="page.createResource.metadata.createAp.body" tag="p"> <i18n path="page.createResource.applicationProfile.createAp.body" tag="p">
<template #br><br /></template> <template #br><br /></template>
</i18n> </i18n>
......
...@@ -142,6 +142,22 @@ ...@@ -142,6 +142,22 @@
{{ $t("page.createResource.multiselect.noOptions") }} {{ $t("page.createResource.multiselect.noOptions") }}
</span> </span>
</multiselect> </multiselect>
<template #hint>
<span
v-if="
gitlabInformation.reference &&
!gitlabInformation.reference?.can_push
"
class="text-danger"
>
{{
$t("resourceType.gitlab.cantPush", {
branch: gitlabInformation.reference?.name,
})
}}
</span>
</template>
</CoscineFormGroup> </CoscineFormGroup>
<CoscineFormGroup> <CoscineFormGroup>
......
...@@ -165,19 +165,19 @@ export default defineComponent({ ...@@ -165,19 +165,19 @@ export default defineComponent({
type: Boolean, type: Boolean,
}, },
fileListEdit: { fileListEdit: {
default() { default: () => {
return []; return [];
}, },
type: Array as PropType<FolderContent[]>, type: Array as PropType<FolderContent[]>,
}, },
fileListUpload: { fileListUpload: {
default() { default: () => {
return []; return [];
}, },
type: Array as PropType<FileInformation[]>, type: Array as PropType<FileInformation[]>,
}, },
folderContents: { folderContents: {
default() { default: () => {
return []; return [];
}, },
type: Array as PropType<FolderContent[]>, type: Array as PropType<FolderContent[]>,
......
...@@ -2,17 +2,28 @@ ...@@ -2,17 +2,28 @@
<b-row id="metadataManagerButtonRowTop" align-h="between"> <b-row id="metadataManagerButtonRowTop" align-h="between">
<b-col> <b-col>
<!-- Select Files Button --> <!-- Select Files Button -->
<span id="buttonSelectFilesWrapper">
<b-button <b-button
v-if="!isGuest" v-if="!isGuest"
id="buttonSelectFiles" id="buttonSelectFiles"
variant="secondary" variant="secondary"
:placeholder="$t('page.resource.metadataManagerBtnSelectFiles')" :placeholder="$t('page.resource.metadataManagerBtnSelectFiles')"
:disabled="isUploading || readOnly || (resource && resource.archived)" :disabled="uploadDisabled"
autofocus autofocus
@click="$emit('selectFiles')" @click="$emit('selectFiles')"
> >
{{ $t("page.resource.metadataManagerBtnSelectFiles") }} {{ $t("page.resource.metadataManagerBtnSelectFiles") }}
</b-button> </b-button>
</span>
<b-tooltip
v-if="uploadDisabled && uploadDisabledReason"
target="buttonSelectFilesWrapper"
triggers="hover"
placement="bottom"
boundary="viewport"
>
{{ uploadDisabledReason }}
</b-tooltip>
</b-col> </b-col>
<b-col> <b-col>
...@@ -59,10 +70,14 @@ import useProjectStore from "@/modules/project/store"; ...@@ -59,10 +70,14 @@ import useProjectStore from "@/modules/project/store";
// import the store for current module // import the store for current module
import useResourceStore from "../../../store"; import useResourceStore from "../../../store";
import type { ResourceObject } from "@coscine/api-client/dist/types/Coscine.Api.Resources"; import type {
Branch,
ResourceObject,
} from "@coscine/api-client/dist/types/Coscine.Api.Resources";
import type { FolderContent } from "../../../utils/EntryDefinition"; import type { FolderContent } from "../../../utils/EntryDefinition";
import type { ResourceTypeInformation } from "@coscine/api-client/dist/types/Coscine.Api.Resources"; import type { ResourceTypeInformation } from "@coscine/api-client/dist/types/Coscine.Api.Resources";
import type { TranslateResult } from "vue-i18n";
export default defineComponent({ export default defineComponent({
props: { props: {
editableDataUrl: { editableDataUrl: {
...@@ -96,10 +111,37 @@ export default defineComponent({ ...@@ -96,10 +111,37 @@ export default defineComponent({
return { projectStore, resourceStore }; return { projectStore, resourceStore };
}, },
data() {
return {
gitlabBranchProps: null as Branch | null,
};
},
computed: { computed: {
isGuest(): boolean | undefined { isGuest(): boolean | undefined {
return this.projectStore.currentUserRoleIsGuest; return this.projectStore.currentUserRoleIsGuest;
}, },
uploadDisabled(): boolean {
return (
this.isUploading ||
this.readOnly ||
this.resource.archived ||
!this.gitlabBranchProps?.can_push ||
false
);
},
uploadDisabledReason(): TranslateResult | null {
if (this.isUploading)
return this.$t("page.resource.metadataManagerBtnCantUploadArchived");
else if (this.readOnly)
return this.$t("page.resource.metadataManagerBtnCantUploadReadonly");
else if (this.resource.archived)
return this.$t("page.resource.metadataManagerBtnCantUploadUploading");
else if (!this.gitlabBranchProps?.can_push)
return this.$t("resourceType.gitlab.cantPush", {
branch: this.gitlabBranchProps?.name,
});
else return null;
},
resourceTypeInformation(): null | undefined | ResourceTypeInformation { resourceTypeInformation(): null | undefined | ResourceTypeInformation {
if (this.resourceStore.enabledResourceTypes && this.resource) { if (this.resourceStore.enabledResourceTypes && this.resource) {
return this.resourceStore.enabledResourceTypes.find( return this.resourceStore.enabledResourceTypes.find(
...@@ -109,6 +151,35 @@ export default defineComponent({ ...@@ -109,6 +151,35 @@ export default defineComponent({
return null; return null;
}, },
}, },
async mounted() {
if (
this.resource.resourceTypeOption &&
this.resource.type?.displayName === "gitlab"
) {
await this.fetchGitlabBranchInfo();
}
},
methods: {
async fetchGitlabBranchInfo() {
const projectId = this.resource.resourceTypeOption["ProjectId"];
const domain = this.resource.resourceTypeOption["RepoUrl"];
const accessToken = this.resource.resourceTypeOption["AccessToken"];
const currentBranch = this.resource.resourceTypeOption["Branch"];
if (projectId && domain && accessToken && currentBranch) {
const gitlabRefs = await this.resourceStore.getGitlabBranchesForProject(
projectId,
domain,
accessToken
);
if (gitlabRefs) {
this.gitlabBranchProps = gitlabRefs.find(
(b) => b.name === currentBranch
) as Branch;
}
}
},
},
}); });
</script> </script>
......