Skip to content
Snippets Groups Projects
Commit 64d6eba4 authored by Petar Hristov's avatar Petar Hristov :speech_balloon:
Browse files

New: Migrated Blob & Tree APIs

parent c9fb21a7
Branches Product/1573-ReadOnlyResources
Tags
1 merge request!256New: Migrated Blob & Tree APIs
Showing
with 1479 additions and 819 deletions
...@@ -25,6 +25,7 @@ module.exports = { ...@@ -25,6 +25,7 @@ module.exports = {
{ "allowWholeFile": true } { "allowWholeFile": true }
], ],
"@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }], // will only ignore variables that start with an underscore _ "@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }], // will only ignore variables that start with an underscore _
"@typescript-eslint/no-inferrable-types": "off", // this enforces the removal of the type declarations for variables that are initialized with a value (e.g. let foo: string = "foo")
"vue/multi-word-component-names": "off" "vue/multi-word-component-names": "off"
}, },
} }
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
"coverage": "vitest run --coverage" "coverage": "vitest run --coverage"
}, },
"dependencies": { "dependencies": {
"@coscine/api-client": "^3.0.0", "@coscine/api-client": "^3.1.0",
"@coscine/form-generator": "^3.2.2", "@coscine/form-generator": "^3.2.2",
"@dynamic-mapper/mapper": "^1.10.2", "@dynamic-mapper/mapper": "^1.10.2",
"@pinia/testing": "^0.1.2", "@pinia/testing": "^0.1.2",
...@@ -92,6 +92,7 @@ ...@@ -92,6 +92,7 @@
"vite": "^4.3.9", "vite": "^4.3.9",
"vite-aliases": "^0.11.2", "vite-aliases": "^0.11.2",
"vite-plugin-node-polyfills": "^0.9.0", "vite-plugin-node-polyfills": "^0.9.0",
"vite-plugin-rewrite-all": "^1.0.1",
"vite-plugin-windicss": "^1.9.0", "vite-plugin-windicss": "^1.9.0",
"vitest": "^0.32.2", "vitest": "^0.32.2",
"vue-template-compiler": "^2.7.14" "vue-template-compiler": "^2.7.14"
......
<template> <template>
<b-container class="mb-3 p-0 w-100">
<b-row no-gutters>
<b-form-group <b-form-group
class="w-100 m-0"
:class="mandatory === true ? 'mandatory' : ''" :class="mandatory === true ? 'mandatory' : ''"
:label-for="labelFor" :label-for="labelFor"
:label-cols-sm="labelColsSm" :label-cols-sm="labelColsSm"
...@@ -10,7 +13,10 @@ ...@@ -10,7 +13,10 @@
<template #loading> <template #loading>
<b-skeleton :type="type" animation="fade"></b-skeleton> <b-skeleton :type="type" animation="fade"></b-skeleton>
</template> </template>
<div class="flex-center">
<slot /> <slot />
</div>
</b-skeleton-wrapper> </b-skeleton-wrapper>
<!-- Label Template --> <!-- Label Template -->
...@@ -34,12 +40,16 @@ ...@@ -34,12 +40,16 @@
</b-popover> </b-popover>
</div> </div>
</template> </template>
</b-form-group>
</b-row>
<b-row no-gutters>
<b-col :sm="labelColsSm" />
<!-- Hint Text --> <!-- Hint Text -->
<div id="hint" class="small text-muted"> <b-col id="hint" class="small text-muted pl-1" align-self="end">
<slot name="hint" /> <slot name="hint" />
</div> </b-col>
</b-form-group> </b-row>
</b-container>
</template> </template>
<script lang="ts"> <script lang="ts">
...@@ -90,4 +100,18 @@ export default defineComponent({ ...@@ -90,4 +100,18 @@ export default defineComponent({
content: " *"; content: " *";
color: #a70619; color: #a70619;
} }
.flex-center {
/* Needed to center the content vertically */
display: flex;
align-items: center;
height: 100%;
width: 100%;
}
#hint {
position: relative;
}
.form-row :deep(.col) {
/* Removes the right padding from the inner col, making it go until the end */
padding: 0 0 0 5px;
}
</style> </style>
<template> <template>
<b-breadcrumb class="breadcrumbs"> <b-breadcrumb class="breadcrumbs">
<!-- Home -->
<b-breadcrumb-item :to="{ name: 'home' }" :active="crumbs.length === 0"> <b-breadcrumb-item :to="{ name: 'home' }" :active="crumbs.length === 0">
<b-icon v-if="crumbs.length === 0" icon="house-fill" aria-hidden="true" /> <b-icon v-if="crumbs.length === 0" icon="house-fill" aria-hidden="true" />
<b-icon v-else icon="house" aria-hidden="true" /> <b-icon v-else icon="house" aria-hidden="true" />
{{ $t(`breadcrumbs.home`) }} {{ $t(`breadcrumbs.home`) }}
</b-breadcrumb-item> </b-breadcrumb-item>
<!-- Rest -->
<b-breadcrumb-item <b-breadcrumb-item
v-for="(crumb, id) in crumbs" v-for="(crumb, id) in crumbs"
:key="id" :key="id"
...@@ -29,6 +32,7 @@ import type { ...@@ -29,6 +32,7 @@ import type {
ProjectDto, ProjectDto,
ResourceDto, ResourceDto,
} from "@coscine/api-client/dist/types/Coscine.Api/api"; } from "@coscine/api-client/dist/types/Coscine.Api/api";
import type { RouteRecord } from "vue-router";
interface RouteLink { interface RouteLink {
to: RawLocation; to: RawLocation;
...@@ -46,72 +50,14 @@ export default defineComponent({ ...@@ -46,72 +50,14 @@ export default defineComponent({
computed: { computed: {
crumbs(): RouteLink[] { crumbs(): RouteLink[] {
let pathArray = this.$route.path.split("/"); // Get the relevant path from the route (ignores everything after "/-")
pathArray = pathArray.filter( const relevantPath = this.$route.path.split("/-")[0];
(path) => // Filter out empty paths and the project and resource path
path.trim() !== "" && path.trim() !== "p" && path.trim() !== "r" let pathArray = this.filterPaths(relevantPath.split("/"));
); pathArray = this.includeRootPath(pathArray);
// Deal with Root Path inclusion let breadcrumbs = this.generateRouteLinks(pathArray);
if (pathArray.length === 1) { breadcrumbs = this.addParentProjects(breadcrumbs);
pathArray.unshift(""); return this.markLastActive(breadcrumbs);
}
const breadcrumbs = pathArray.reduce(
(breadcrumbArray: RouteLink[], path, idx) => {
// Deal with Root Path inclusion
if (path === "") {
return breadcrumbArray;
}
breadcrumbArray.push({
to: {
name: this.$route.matched[idx].name
? this.$route.matched[idx].name
: this.$route.matched[idx].meta.default,
},
text:
this.$route.matched[idx] &&
this.$route.matched[idx].meta &&
this.$route.matched[idx].meta.breadCrumb
? this.$t(
`breadcrumbs.${this.$route.matched[idx].meta.breadCrumb}`,
{
path: path,
projectName: this.project
? this.project.displayName
: path,
resourceName:
this.resource && this.resource.type
? `${this.$t(
"resourceTypes." +
this.resource.type.specificType +
".displayName"
)}: ${this.resource.displayName}`
: path,
}
).toString()
: path,
});
return breadcrumbArray;
},
[]
);
if (this.project && this.parentProjects) {
const parentBreadCrumbs = this.parentProjects.map((parentProject) => {
return {
to: {
name: "project-page",
params: { slug: parentProject.slug },
},
text: this.$t(`breadcrumbs.project.page`, {
projectName: parentProject.displayName,
}).toString(),
} as RouteLink;
});
breadcrumbs.unshift(...parentBreadCrumbs);
}
if (breadcrumbs.length > 0) {
breadcrumbs[breadcrumbs.length - 1].active = true;
}
return breadcrumbs;
}, },
parentProjects(): ProjectDto[] | null { parentProjects(): ProjectDto[] | null {
...@@ -155,7 +101,11 @@ export default defineComponent({ ...@@ -155,7 +101,11 @@ export default defineComponent({
}, },
methods: { methods: {
setDocumentTitle(title = "") { /**
* Set the document title.
* @param {string} [title=""] - The title to set. If empty, the default title will be used.
*/
setDocumentTitle(title: string = "") {
if (title.trim() !== "") { if (title.trim() !== "") {
document.title = this.$t("title.modified", { document.title = this.$t("title.modified", {
title: title, title: title,
...@@ -164,6 +114,126 @@ export default defineComponent({ ...@@ -164,6 +114,126 @@ export default defineComponent({
document.title = this.$t("title.default").toString(); document.title = this.$t("title.default").toString();
} }
}, },
/**
* Filters out unwanted paths from the given array.
* @param {string[]} paths - The array of paths.
* @returns {string[]} - The filtered array of paths.
*/
filterPaths(paths: string[]): string[] {
return paths.filter(
(path) =>
path.trim() !== "" &&
path.trim() !== "p" &&
path.trim() !== "r" &&
path.trim() !== "-"
);
},
/**
* Adds a root path if the path array contains only one element.
* @param {string[]} pathArray - The array of paths.
* @returns {string[]} - The array of paths possibly including the root.
*/
includeRootPath(pathArray: string[]): string[] {
if (pathArray.length === 1) {
pathArray.unshift("");
}
return pathArray;
},
/**
* Generates RouteLink objects based on the path array.
* @param {string[]} pathArray - The array of paths.
* @returns {RouteLink[]} - The array of RouteLink objects.
*/
generateRouteLinks(pathArray: string[]): RouteLink[] {
return pathArray.reduce((breadcrumbArray: RouteLink[], path, idx) => {
if (path === "") return breadcrumbArray;
const routeMatched = this.$route.matched[idx];
if (routeMatched) {
breadcrumbArray.push(this.generateRouteLink(routeMatched, path));
}
return breadcrumbArray;
}, []);
},
/**
* Generates a single RouteLink object.
* @param {RouteRecord} routeMatched - The matched route record.
* @param {string} path - The path segment for this breadcrumb.
* @returns {RouteLink} - The RouteLink object.
*/
generateRouteLink(routeMatched: RouteRecord, path: string): RouteLink {
return {
to: {
name: routeMatched.name
? routeMatched.name
: routeMatched.meta.default,
},
text: routeMatched?.meta?.breadCrumb
? this.$t(`breadcrumbs.${routeMatched.meta.breadCrumb}`, {
path: path,
projectName: this.project ? this.project.displayName : path,
resourceName: this.resource ? this.resourceDisplayName() : path,
}).toString()
: path,
} as RouteLink;
},
/**
* Retrieves the display name of the resource if available.
* @returns {string} - The display name of the resource or an empty string.
*/
resourceDisplayName(): string {
if (this.resource?.displayName) {
if (this.resource.type?.specificType) {
// e.g. "RWTH-RDS-S3: My Resource Name"
return `${this.$t(
"resourceTypes." + this.resource.type.specificType + ".displayName"
)}: ${this.resource.displayName}`;
}
return this.resource.displayName;
}
return "";
},
/**
* Adds parent projects to the breadcrumb array.
* @param {RouteLink[]} breadcrumbs - The existing array of RouteLink objects.
* @returns {RouteLink[]} - The updated array of RouteLink objects.
*/
addParentProjects(breadcrumbs: RouteLink[]): RouteLink[] {
if (this.project && this.parentProjects) {
const parentBreadCrumbs: RouteLink[] = this.parentProjects.map(
(parentProject) => {
return {
to: {
name: "project-page",
params: { slug: parentProject.slug },
},
text: this.$t(`breadcrumbs.project.page`, {
projectName: parentProject.displayName,
}).toString(),
} as RouteLink;
}
);
breadcrumbs.unshift(...parentBreadCrumbs);
}
return breadcrumbs;
},
/**
* Marks the last breadcrumb as active.
* @param {RouteLink[]} breadcrumbs - The existing array of RouteLink objects.
* @returns {RouteLink[]} - The updated array of RouteLink objects.
*/
markLastActive(breadcrumbs: RouteLink[]): RouteLink[] {
if (breadcrumbs.length > 0) {
breadcrumbs[breadcrumbs.length - 1].active = true;
}
return breadcrumbs;
},
}, },
}); });
</script> </script>
......
...@@ -166,6 +166,7 @@ export default defineComponent({ ...@@ -166,6 +166,7 @@ export default defineComponent({
params: { params: {
slug: this.project ? this.project.slug : undefined, slug: this.project ? this.project.slug : undefined,
guid: resource.id, guid: resource.id,
dirTrail: "",
}, },
}, },
icon: "bi bi-archive", icon: "bi bi-archive",
......
export const radarApplicationProfile = `[{"@id":"https://purl.org/coscine/ap/radar/","@graph":[{"@id":"https://purl.org/coscine/ap/radar#subject","http://www.w3.org/ns/shacl#path":[{"@id":"http://purl.org/dc/terms/subject"}],"http://www.w3.org/ns/shacl#order":[{"@value":"3","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#maxCount":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#class":[{"@id":"http://www.dfg.de/dfg_profil/gremien/fachkollegien/faecher/"}],"http://www.w3.org/ns/shacl#name":[{"@language":"de","@value":"Fachrichtung"},{"@language":"en","@value":"Subject Area"}]},{"@id":"https://purl.org/coscine/ap/radar#created","http://www.w3.org/ns/shacl#path":[{"@id":"http://purl.org/dc/terms/created"}],"http://www.w3.org/ns/shacl#order":[{"@value":"2","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#minCount":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#maxCount":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#name":[{"@language":"en","@value":"Production Date"},{"@language":"de","@value":"Erstelldatum"}],"http://www.w3.org/ns/shacl#datatype":[{"@id":"http://www.w3.org/2001/XMLSchema#date"}],"http://www.w3.org/ns/shacl#defaultValue":[{"@value":"{TODAY}"}]},{"@id":"https://purl.org/coscine/ap/radar#creator","http://www.w3.org/ns/shacl#path":[{"@id":"http://purl.org/dc/terms/creator"}],"http://www.w3.org/ns/shacl#order":[{"@value":"0","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#minCount":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#maxCount":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#name":[{"@language":"de","@value":"Ersteller"},{"@language":"en","@value":"Creator"}],"http://www.w3.org/ns/shacl#minLength":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#datatype":[{"@id":"http://www.w3.org/2001/XMLSchema#string"}],"http://www.w3.org/ns/shacl#defaultValue":[{"@value":"{ME}"}]},{"@id":"https://purl.org/coscine/ap/radar#rights","http://www.w3.org/ns/shacl#path":[{"@id":"http://purl.org/dc/terms/rights"}],"http://www.w3.org/ns/shacl#order":[{"@value":"5","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#maxCount":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#name":[{"@language":"en","@value":"Rights"},{"@language":"de","@value":"Berechtigung"}],"http://www.w3.org/ns/shacl#datatype":[{"@id":"http://www.w3.org/2001/XMLSchema#string"}]},{"@id":"https://purl.org/coscine/ap/radar#rightsHolder","http://www.w3.org/ns/shacl#path":[{"@id":"http://purl.org/dc/terms/rightsHolder"}],"http://www.w3.org/ns/shacl#order":[{"@value":"6","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#maxCount":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#name":[{"@language":"en","@value":"Rightsholder"},{"@language":"de","@value":"Rechteinhaber"}],"http://www.w3.org/ns/shacl#datatype":[{"@id":"http://www.w3.org/2001/XMLSchema#string"}]},{"@id":"https://purl.org/coscine/ap/radar#title","http://www.w3.org/ns/shacl#path":[{"@id":"http://purl.org/dc/terms/title"}],"http://www.w3.org/ns/shacl#order":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#minCount":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#maxCount":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#name":[{"@language":"de","@value":"Titel"},{"@language":"en","@value":"Title"}],"http://www.w3.org/ns/shacl#minLength":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#datatype":[{"@id":"http://www.w3.org/2001/XMLSchema#string"}]},{"@id":"https://purl.org/coscine/ap/radar#type","http://www.w3.org/ns/shacl#path":[{"@id":"http://purl.org/dc/terms/type"}],"http://www.w3.org/ns/shacl#order":[{"@value":"4","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#maxCount":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#class":[{"@id":"http://purl.org/dc/dcmitype/"}],"http://www.w3.org/ns/shacl#name":[{"@language":"en","@value":"Resource"},{"@language":"de","@value":"Ressource"}]},{"@id":"https://purl.org/coscine/ap/radar/","@type":["http://www.w3.org/ns/shacl#NodeShape"],"http://purl.org/dc/terms/license":[{"@id":"http://spdx.org/licenses/MIT"}],"http://purl.org/dc/terms/rights":[{"@value":"Copyright © 2020 IT Center, RWTH Aachen University"}],"http://www.w3.org/ns/shacl#targetClass":[{"@id":"https://purl.org/coscine/ap/radar/"}],"http://www.w3.org/ns/shacl#closed":[{"@value":"true","@type":"http://www.w3.org/2001/XMLSchema#boolean"}],"http://www.w3.org/ns/shacl#property":[{"@id":"https://purl.org/coscine/ap/radar#creator"},{"@id":"https://purl.org/coscine/ap/radar#rights"},{"@id":"https://purl.org/coscine/ap/radar#subject"},{"@id":"https://purl.org/coscine/ap/radar#created"},{"@id":"https://purl.org/coscine/ap/radar#type"},{"@id":"_:b8922734"},{"@id":"https://purl.org/coscine/ap/radar#rightsHolder"},{"@id":"https://purl.org/coscine/ap/radar#title"}],"http://purl.org/dc/terms/title":[{"@language":"en","@value":"radar application profile"}],"http://purl.org/dc/terms/publisher":[{"@id":"https://itc.rwth-aachen.de/"}],"http://purl.org/dc/terms/description":[{"@value":"The RADAR metadata schema v09 was created by the 2018 FIZ Karlsruhe - Leibniz-Institut fuer Informationsinfrastruktur GmbH and has been published under CC BY 4.0."}]},{"@id":"_:b8922734","http://www.w3.org/ns/shacl#path":[{"@id":"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"}]}]}]`; export const baseApplicationProfile = `[{"@id":"_:b6482494","http://www.w3.org/ns/shacl#datatype":[{"@id":"http://www.w3.org/2001/XMLSchema#string"}],"http://www.w3.org/ns/shacl#minCount":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#order":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#name":[{"@language":"en","@value":"Creator"},{"@language":"de","@value":"Ersteller"}],"http://www.w3.org/ns/shacl#description":[{"@language":"de","@value":"Wer ist der Ersteller der Daten?"},{"@language":"en","@value":"Who is the creator of the data?"}],"http://www.w3.org/ns/shacl#defaultValue":[{"@value":"{ME}"}],"http://www.w3.org/ns/shacl#minLength":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#path":[{"@id":"http://purl.org/dc/terms/creator"}]},{"@id":"_:b6482495","http://www.w3.org/ns/shacl#description":[{"@language":"de","@value":"Von welchem Datentyp sind Ihre Daten?"},{"@language":"en","@value":"What type of data is your data?"}],"http://www.w3.org/ns/shacl#order":[{"@value":"4","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#class":[{"@id":"http://purl.org/dc/dcmitype/"}],"http://www.w3.org/ns/shacl#path":[{"@id":"http://purl.org/dc/terms/type"}],"http://www.w3.org/ns/shacl#name":[{"@language":"de","@value":"Typ"},{"@language":"en","@value":"Type"}]},{"@id":"https://purl.org/coscine/ap/base/","http://purl.org/dc/terms/title":[{"@language":"en","@value":"Base Profile"},{"@language":"de","@value":"Basisprofil"}],"http://purl.org/dc/terms/creator":[{"@value":"Hanna Führ"}],"http://www.w3.org/ns/shacl#closed":[{"@value":"false","@type":"http://www.w3.org/2001/XMLSchema#boolean"}],"@type":["http://www.w3.org/ns/shacl#NodeShape"],"http://www.w3.org/ns/shacl#targetClass":[{"@id":"https://purl.org/coscine/ap/base/"}],"http://www.w3.org/ns/shacl#property":[{"@id":"_:b6482493"},{"@id":"_:b6482496"},{"@id":"_:b6482494"},{"@id":"_:b6482497"},{"@id":"_:b6482495"}],"http://purl.org/dc/terms/description":[{"@language":"de","@value":"Basisprofil, das Grundbausteine enthält"},{"@language":"en","@value":"Base application profile, which contains the basic building blocks"}],"http://purl.org/dc/terms/created":[{"@value":"2023-02-06","@type":"http://www.w3.org/2001/XMLSchema#date"}],"http://purl.org/dc/terms/license":[{"@value":"https://spdx.org/licenses/CC-BY-4.0.html"}]},{"@id":"_:b6482497","http://www.w3.org/ns/shacl#name":[{"@language":"en","@value":"Creation Date"},{"@language":"de","@value":"Erstellungsdatum"}],"http://www.w3.org/ns/shacl#path":[{"@id":"http://purl.org/dc/terms/created"}],"http://www.w3.org/ns/shacl#defaultValue":[{"@value":"{TODAY}"}],"http://www.w3.org/ns/shacl#minCount":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#datatype":[{"@id":"http://www.w3.org/2001/XMLSchema#date"}],"http://www.w3.org/ns/shacl#description":[{"@language":"en","@value":"When was the data created?"},{"@language":"de","@value":"Wann wurden die Daten erstellt?"}],"http://www.w3.org/ns/shacl#order":[{"@value":"2","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#maxCount":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}]},{"@id":"_:b6482493","http://www.w3.org/ns/shacl#description":[{"@language":"en","@value":"Which subject does your data belong to?"},{"@language":"de","@value":"Welcher Fachrichtung gehören Ihre Daten an?"}],"http://www.w3.org/ns/shacl#class":[{"@id":"http://www.dfg.de/dfg_profil/gremien/fachkollegien/faecher/"}],"http://www.w3.org/ns/shacl#order":[{"@value":"3","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#name":[{"@language":"de","@value":"Fachrichtung"},{"@language":"en","@value":"Subject Area"}],"http://www.w3.org/ns/shacl#path":[{"@id":"http://purl.org/dc/terms/subject"}]},{"@id":"_:b6482496","http://www.w3.org/ns/shacl#name":[{"@language":"de","@value":"Titel"},{"@language":"en","@value":"Title"}],"http://www.w3.org/ns/shacl#datatype":[{"@id":"http://www.w3.org/2001/XMLSchema#string"}],"http://www.w3.org/ns/shacl#minLength":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#order":[{"@value":"0","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#minCount":[{"@value":"1","@type":"http://www.w3.org/2001/XMLSchema#integer"}],"http://www.w3.org/ns/shacl#description":[{"@language":"en","@value":"Enter a title to describe your data."},{"@language":"de","@value":"Geben Sie einen Titel an, um Ihre Daten zu beschreiben."}],"http://www.w3.org/ns/shacl#path":[{"@id":"http://purl.org/dc/terms/title"}]}]`;
export const baseApplicationProfileFormat = "application/ld+json";
export const getMetadataResponse = { import type {
data: { FileDto,
metadataStorage: [ MetadataDto,
TreeDataType,
} from "@coscine/api-client/dist/types/Coscine.Api";
export const getMetadataTreeResponse: MetadataDto[] = [
{ {
"https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2FTesta": version: "1693212042",
'<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2FTesta> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://purl.org/coscine/ap/radar/> .\r\n<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2FTesta> <http://purl.org/dc/terms/created> "2022-02-25"^^<http://www.w3.org/2001/XMLSchema#date> .\r\n<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2FTesta> <http://purl.org/dc/terms/creator> "Benedikt Heinrichs"^^<http://www.w3.org/2001/XMLSchema#string> .\r\n<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2FTesta> <http://purl.org/dc/terms/title> "Test"^^<http://www.w3.org/2001/XMLSchema#string> .\r\n', availableVersions: ["1693212042"],
definition:
'@base <https://purl.org/coscine/resources/4103cbea-ffa3-40a5-9e5c-b99cc16f0007/folder_1/folder_2/A.txt/@type=metadata&version=1693212042>.\r\n\r\n@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.\r\n@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.\r\n@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.\r\n@prefix ns2: <http://purl.org/dc/terms/>.\r\n\r\n_:b8477997 ns2:created "2023-08-15"^^xsd:date;\r\n ns2:creator "Petar Hristov";\r\n ns2:title "Title inside Form Generator";\r\n a <https://purl.org/coscine/ap/base/>.\r\n',
format: "text/turtle",
path: "folder_1/folder_2/A.txt",
type: "Leaf" as TreeDataType.Leaf,
}, },
{ {
"https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2FTest": version: "1692777419",
'<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2FTest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://purl.org/coscine/ap/radar/> .\r\n<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2FTest> <http://purl.org/dc/terms/created> "2021-12-09"^^<http://www.w3.org/2001/XMLSchema#date> .\r\n<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2FTest> <http://purl.org/dc/terms/creator> "Benedikt Heinrichs"^^<http://www.w3.org/2001/XMLSchema#string> .\r\n<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2FTest> <http://purl.org/dc/terms/title> "Test"^^<http://www.w3.org/2001/XMLSchema#string> .\r\n', availableVersions: ["1692777419"],
definition:
'@base <https://purl.org/coscine/resources/4103cbea-ffa3-40a5-9e5c-b99cc16f0007/file_1.txt/@type=metadata&version=1692777419>.\r\n\r\n@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.\r\n@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.\r\n@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.\r\n@prefix ns2: <http://purl.org/dc/terms/>.\r\n\r\n_:b8425359 ns2:created "2023-08-18"^^xsd:date;\r\n ns2:creator "Petar Hristov";\r\n ns2:title "file_1";\r\n a <https://purl.org/coscine/ap/base/>.\r\n',
format: "text/turtle",
path: "file_1.txt",
type: "Leaf" as TreeDataType.Leaf,
}, },
{ {
"https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2FcoolerEintrag": version: "1692779210",
'<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2FcoolerEintrag> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://purl.org/coscine/ap/radar/> .\r\n<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2FcoolerEintrag> <http://purl.org/dc/terms/created> "2022-03-07"^^<http://www.w3.org/2001/XMLSchema#date> .\r\n<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2FcoolerEintrag> <http://purl.org/dc/terms/creator> "Benedikt Heinrichs"^^<http://www.w3.org/2001/XMLSchema#string> .\r\n<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2FcoolerEintrag> <http://purl.org/dc/terms/title> "test"^^<http://www.w3.org/2001/XMLSchema#string> .\r\n', availableVersions: [
}, "1692340745",
{ "1692340906",
"https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2Freview": "1692340959",
'<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2Freview> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://purl.org/coscine/ap/radar/> .\r\n<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2Freview> <http://purl.org/dc/terms/created> "2022-03-10"^^<http://www.w3.org/2001/XMLSchema#date> .\r\n<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2Freview> <http://purl.org/dc/terms/creator> "Benedikt Heinrichs"^^<http://www.w3.org/2001/XMLSchema#string> .\r\n<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2Freview> <http://purl.org/dc/terms/title> "MyTest2"^^<http://www.w3.org/2001/XMLSchema#string> .\r\n', "1692341031",
}, "1692779210",
{
"https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2Feawfaewf":
'<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2Feawfaewf> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://purl.org/coscine/ap/radar/> .\r\n<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2Feawfaewf> <http://purl.org/dc/terms/created> "2022-03-10"^^<http://www.w3.org/2001/XMLSchema#date> .\r\n<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2Feawfaewf> <http://purl.org/dc/terms/creator> "Benedikt Heinrichs"^^<http://www.w3.org/2001/XMLSchema#string> .\r\n<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2Feawfaewf> <http://purl.org/dc/terms/rights> "awer"^^<http://www.w3.org/2001/XMLSchema#string> .\r\n<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2Feawfaewf> <http://purl.org/dc/terms/title> "awerawe"^^<http://www.w3.org/2001/XMLSchema#string> .\r\n',
},
{
"https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2Fw":
'<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2Fw> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://purl.org/coscine/ap/radar/> .\r\n<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2Fw> <http://purl.org/dc/terms/created> "2022-04-04"^^<http://www.w3.org/2001/XMLSchema#date> .\r\n<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2Fw> <http://purl.org/dc/terms/creator> "Benedikt Heinrichs"^^<http://www.w3.org/2001/XMLSchema#string> .\r\n<https://hdl.handle.net/21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65@path=%2Fw> <http://purl.org/dc/terms/title> "a"^^<http://www.w3.org/2001/XMLSchema#string> .\r\n',
},
], ],
fileStorage: [ definition:
{ '@base <https://purl.org/coscine/resources/4103cbea-ffa3-40a5-9e5c-b99cc16f0007/file_0.txt/@type=metadata&version=1692779210>.\r\n\r\n@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.\r\n@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.\r\n@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.\r\n@prefix ns2: <http://purl.org/dc/terms/>.\r\n\r\n_:b8425361 ns2:created "2023-08-18"^^xsd:date;\r\n ns2:creator "Petar Hristov";\r\n ns2:title "Revised";\r\n a <https://purl.org/coscine/ap/base/>.\r\n',
Name: "Testa", format: "text/turtle",
Path: "/Testa", path: "file_0.txt",
Size: 7, type: "Leaf" as TreeDataType.Leaf,
Kind: "file",
Modified: null,
Created: null,
Provider: "linked",
IsFolder: false,
IsFile: true,
Action: {},
},
{
Name: "Test",
Path: "/Test",
Size: 18,
Kind: "file",
Modified: null,
Created: null,
Provider: "linked",
IsFolder: false,
IsFile: true,
Action: {},
}, },
{ {
Name: "coolerEintrag", version: "1693209938",
Path: "/coolerEintrag", availableVersions: ["1693209938"],
Size: 14, definition:
Kind: "file", '@base <https://purl.org/coscine/resources/4103cbea-ffa3-40a5-9e5c-b99cc16f0007/my_folder/file_of_folder.txt/@type=metadata&version=1693209938>.\r\n\r\n@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.\r\n@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.\r\n@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.\r\n@prefix ns2: <http://purl.org/dc/terms/>.\r\n\r\n_:b8477996 ns2:created "2023-08-15"^^xsd:date;\r\n ns2:creator "Petar Hristov";\r\n ns2:title "From Insomnia";\r\n a <https://purl.org/coscine/ap/base/>.\r\n',
Modified: null, format: "text/turtle",
Created: null, path: "my_folder/file_of_folder.txt",
Provider: "linked", type: "Leaf" as TreeDataType.Leaf,
IsFolder: false,
IsFile: true,
Action: {},
}, },
];
export const getFileTreeResponse: FileDto[] = [
{ {
Name: "review", parentDirectory: "",
Path: "/review", name: "folder_1",
Size: 14, size: 0,
Kind: "file", creationDate: "2023-09-01T16:57:48.2525218+02:00",
Modified: null, changeDate: "2023-09-01T16:57:48.2525225+02:00",
Created: null, path: "folder_1/",
Provider: "linked", type: "Tree" as TreeDataType.Tree,
IsFolder: false,
IsFile: true,
Action: {},
}, },
{ {
Name: "eawfaewf", parentDirectory: "",
Path: "/eawfaewf", name: "my_folder",
Size: 14, size: 0,
Kind: "file", creationDate: "2023-09-01T16:57:48.2525245+02:00",
Modified: null, changeDate: "2023-09-01T16:57:48.2525249+02:00",
Created: null, path: "my_folder/",
Provider: "linked", type: "Tree" as TreeDataType.Tree,
IsFolder: false,
IsFile: true,
Action: {},
}, },
{ {
Name: "w", parentDirectory: "",
Path: "/w", name: "file_0.txt",
Size: 9, extension: "txt",
Kind: "file", size: 2513352,
Modified: null, creationDate: "2023-08-23T10:27:20.062+02:00",
Created: null, changeDate: "2023-08-23T10:27:20.062+02:00",
Provider: "linked", path: "file_0.txt",
IsFolder: false, type: "Leaf" as TreeDataType.Leaf,
IsFile: true,
Action: {},
},
],
}, },
}; ];
...@@ -3,7 +3,10 @@ import type { ...@@ -3,7 +3,10 @@ import type {
ResourceState, ResourceState,
} from "@/modules/resource/types"; } from "@/modules/resource/types";
import { parseRDFDefinition } from "@/modules/resource/utils/linkedData"; import { parseRDFDefinition } from "@/modules/resource/utils/linkedData";
import { radarApplicationProfile } from "./metadata/applicationProfile"; import {
baseApplicationProfile,
baseApplicationProfileFormat,
} from "./metadata/applicationProfile";
import { radarFixedValues } from "./metadata/fixedValues"; import { radarFixedValues } from "./metadata/fixedValues";
import { testDiscipline, getTestUser } from "./testUser"; import { testDiscipline, getTestUser } from "./testUser";
import type { import type {
...@@ -40,10 +43,10 @@ export const testResourceType: ResourceTypeInformationDto = { ...@@ -40,10 +43,10 @@ export const testResourceType: ResourceTypeInformationDto = {
export const getTestResource: () => Promise<VisitedResourceObject> = export const getTestResource: () => Promise<VisitedResourceObject> =
async () => { async () => {
const apUrl = "https://purl.org/coscine/ap/radar/"; const apUrl = "https://purl.org/coscine/ap/base/";
const ap = await parseRDFDefinition( const ap = await parseRDFDefinition(
radarApplicationProfile, baseApplicationProfile,
"application/ld+json", baseApplicationProfileFormat,
apUrl apUrl
); );
const resourceObject: VisitedResourceObject = { const resourceObject: VisitedResourceObject = {
......
import { MapperConfiguration, MappingPair } from "@dynamic-mapper/mapper";
import { v4 as uuidv4 } from "uuid";
import type {
TreeDataType,
FileDto,
} from "@coscine/api-client/dist/types/Coscine.Api";
import type {
FileInformation,
FolderInformation,
} from "@/modules/resource/types";
export const TreeDto2FileInformation = new MappingPair<
FileDto,
FileInformation
>();
export const TreeDto2FolderInformation = new MappingPair<
FileDto,
FolderInformation
>();
const configuration = new MapperConfiguration((cfg) => {
cfg.createMap(TreeDto2FileInformation, {
id: (opt) => opt.mapFrom((_) => uuidv4()),
name: (opt) => opt.mapFrom((dto) => dto.name ?? ""),
parentDirectory: (opt) => opt.mapFrom((dto) => dto.parentDirectory ?? ""),
path: (opt) => opt.mapFrom((dto) => dto.path ?? ""),
type: (opt) => opt.mapFrom((_) => "Leaf" as TreeDataType.Leaf),
isFolder: (opt) => opt.mapFrom((_) => false),
createdAt: (opt) => opt.mapFrom((dto) => dto.creationDate ?? undefined),
lastModified: (opt) => opt.mapFrom((dto) => dto.changeDate),
size: (opt) => opt.mapFrom((dto) => dto.size ?? 0),
version: (opt) => opt.mapFrom((_) => `${+new Date()}`),
metadata: (opt) => opt.mapFrom((_) => null), // Set outside of the mapper
});
cfg.createMap(TreeDto2FolderInformation, {
id: (opt) => opt.mapFrom((_) => uuidv4()),
name: (opt) => opt.mapFrom((dto) => dto.name ?? ""),
parentDirectory: (opt) => opt.mapFrom((dto) => dto.parentDirectory ?? ""),
path: (opt) => opt.mapFrom((dto) => dto.path ?? ""),
type: (opt) => opt.mapFrom((_) => "Tree" as TreeDataType.Tree),
isFolder: (opt) => opt.mapFrom((_) => true),
createdAt: (opt) => opt.mapFrom((dto) => dto.creationDate ?? undefined),
lastModified: (opt) => opt.mapFrom((dto) => dto.changeDate),
metadata: (opt) => opt.mapFrom((_) => null), // Set outside of the mapper
});
});
export const treeMapper = configuration.createMapper();
...@@ -173,7 +173,7 @@ export default defineComponent({ ...@@ -173,7 +173,7 @@ export default defineComponent({
toResource(resource: ResourceDto): RawLocation { toResource(resource: ResourceDto): RawLocation {
const route = { const route = {
name: "resource-page", name: "resource-page",
params: { guid: resource.id }, params: { guid: resource.id, dirTrail: "" },
} as RawLocation; } as RawLocation;
return route; return route;
}, },
......
...@@ -70,6 +70,11 @@ export default defineComponent({ ...@@ -70,6 +70,11 @@ export default defineComponent({
this.initialize(); this.initialize();
}, },
beforeDestroy() {
// Set current resource ID to null
this.resourceStore.currentId = null;
},
methods: { methods: {
async initialize() { async initialize() {
await this.apiFetch(this.$router.currentRoute); await this.apiFetch(this.$router.currentRoute);
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
</template> </template>
<!-- Dropdown --> <!-- Dropdown -->
<div class="d-flex align-items-center gap-2"> <div class="d-inline-flex align-items-center gap-2 w-100">
<multiselect <multiselect
id="applicationProfiles" id="applicationProfiles"
v-model="selectedApplicationProfile" v-model="selectedApplicationProfile"
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
<b-button <b-button
variant="outline-primary" variant="outline-primary"
name="createAP" name="createAP"
class="d-flex justify-content-between align-items-center" class="d-flex gap-2 justify-content-between align-items-center w-fit"
@click="$bvModal.show('createAPModal')" @click="$bvModal.show('createAPModal')"
> >
<b-icon icon="file-earmark-plus" aria-hidden="true" /> <b-icon icon="file-earmark-plus" aria-hidden="true" />
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
:mandatory="true" :mandatory="true"
:label="$t('page.createResource.configuration.labels.size')" :label="$t('page.createResource.configuration.labels.size')"
> >
<div class="w-100">
<!-- Slider --> <!-- Slider -->
<b-form-input <b-form-input
id="slider" id="slider"
...@@ -22,6 +23,7 @@ ...@@ -22,6 +23,7 @@
{{ $t("page.createResource.configuration.needMore") }} {{ $t("page.createResource.configuration.needMore") }}
</router-link> </router-link>
</div> </div>
</div>
</CoscineFormGroup> </CoscineFormGroup>
</div> </div>
</template> </template>
......
/* Testing imports */ /* Testing imports */
import { createLocalVue, mount } from "@vue/test-utils"; import { type Wrapper, createLocalVue, mount } from "@vue/test-utils";
import { createTestingPinia } from "@pinia/testing"; import { createTestingPinia } from "@pinia/testing";
/* Vue i18n */ /* Vue i18n */
...@@ -15,6 +15,8 @@ import { PiniaVuePlugin } from "pinia"; ...@@ -15,6 +15,8 @@ import { PiniaVuePlugin } from "pinia";
/* Tested Component */ /* Tested Component */
import FilesView from "./FilesView.vue"; import FilesView from "./FilesView.vue";
import VueRouter from "vue-router";
import { routes } from "@/router";
import type Vue from "vue"; import type Vue from "vue";
...@@ -22,7 +24,10 @@ import { getTestUserState } from "@/data/mockup/testUser"; ...@@ -22,7 +24,10 @@ import { getTestUserState } from "@/data/mockup/testUser";
import { getTestResourceState } from "@/data/mockup/testResource"; import { getTestResourceState } from "@/data/mockup/testResource";
import { testProjectState } from "@/data/mockup/testProject"; import { testProjectState } from "@/data/mockup/testProject";
import useResourceStore from "../../store"; import useResourceStore from "../../store";
import { getMetadataResponse } from "@/data/mockup/responses/getMetadata"; import {
getFileTreeResponse,
getMetadataTreeResponse,
} from "@/data/mockup/responses/getMetadata";
function sleep(ms: number) { function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms)); return new Promise((resolve) => setTimeout(resolve, ms));
...@@ -31,10 +36,18 @@ function sleep(ms: number) { ...@@ -31,10 +36,18 @@ function sleep(ms: number) {
/* Create a local Vue instance */ /* Create a local Vue instance */
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(PiniaVuePlugin); localVue.use(PiniaVuePlugin);
localVue.use(VueRouter);
const router = new VueRouter({ routes: routes });
describe("FilesView.vue", () => { // Define the Vue instance type (computed properties)
/* Checks for local storage setting of columns */ interface ResourcePageComponent extends Vue {
test("testLocalStorageSetting", async () => { dirTrail: string;
}
describe("FilesView.vue", async () => {
let wrapper: Wrapper<ResourcePageComponent>;
// Create a mocked pinia instance with initial state
const testingPinia = createTestingPinia({ const testingPinia = createTestingPinia({
createSpy: vitest.fn, createSpy: vitest.fn,
initialState: { initialState: {
...@@ -44,24 +57,35 @@ describe("FilesView.vue", () => { ...@@ -44,24 +57,35 @@ describe("FilesView.vue", () => {
}, },
}); });
// Mock the API calls
const resourceStore = useResourceStore(testingPinia); const resourceStore = useResourceStore(testingPinia);
vi.mocked(resourceStore.getMetadata).mockReturnValue( vi.mocked(resourceStore.getMetadataTree).mockReturnValue(
Promise.resolve(getMetadataResponse) Promise.resolve(getMetadataTreeResponse)
);
vi.mocked(resourceStore.getFileTree).mockReturnValue(
Promise.resolve(getFileTreeResponse)
); );
vi.mocked(resourceStore.getVocabularyInstances).mockReturnValue( vi.mocked(resourceStore.getVocabularyInstances).mockReturnValue(
Promise.resolve({ en: [], de: [] }) Promise.resolve({ en: [], de: [] })
); );
const wrapper = mount(FilesView as unknown as typeof Vue, { beforeEach(() => {
// shallowMount does not work here!
wrapper = mount(FilesView as unknown as typeof Vue, {
pinia: testingPinia, pinia: testingPinia,
router,
i18n, i18n,
localVue, localVue,
}) as Wrapper<ResourcePageComponent>;
}); });
test(
"Should toggle column visibility and persist to local storage",
async () => {
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
// Wait for 1 second until everything is set up // Wait for 1 second until everything is set up
await sleep(1000); await sleep(1000); // Don't remove!
expect(resourceStore.setStoredColumns).toBeCalledTimes(1); expect(resourceStore.setStoredColumns).toBeCalledTimes(1);
...@@ -78,11 +102,16 @@ describe("FilesView.vue", () => { ...@@ -78,11 +102,16 @@ describe("FilesView.vue", () => {
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
// Wait for 1 second until everything is set up // Wait for 1 second until everything is set up
await sleep(1000); await sleep(1000); // Don't remove!
const additionalColumnHeader = wrapper.find(".additionalColumnHeader"); const additionalColumnHeader = wrapper.find(".additionalColumnHeader");
expect(additionalColumnHeader.exists()).toBeTruthy(); expect(additionalColumnHeader.exists()).toBeTruthy();
expect(resourceStore.setStoredColumns).toBeCalledTimes(2); expect(resourceStore.setStoredColumns).toBeCalledTimes(2);
}); },
{
// Override the maximum run time for this test (10 sec), due to the sleep() calls
timeout: 10000,
}
);
}); });
This diff is collapsed.
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
:disabled="isUploading || readOnly || (resource && resource.archived)" :disabled="isUploading || readOnly || (resource && resource.archived)"
@click="upload" @click="upload"
> >
<!-- TODO: Add GitLab branch disabled logic as in MetadataManagerHeader -->
<b-icon icon="plus" :title="$t('page.resource.upload')" /> <b-icon icon="plus" :title="$t('page.resource.upload')" />
</b-button> </b-button>
......
<template> <template>
<span> <span>
<!-- File Name -->
<CoscineFormGroup :label="$t('page.resource.infoFileName')"> <CoscineFormGroup :label="$t('page.resource.infoFileName')">
<div <div
id="fileInfoFieldID" id="fileInfofileName"
class="fileInfoField"
data-toggle="tooltip" data-toggle="tooltip"
:title="currentFile.name" :title="currentFile.name"
> >
...@@ -14,42 +14,39 @@ ...@@ -14,42 +14,39 @@
}} }}
</div> </div>
</CoscineFormGroup> </CoscineFormGroup>
<!-- Last Modified -->
<CoscineFormGroup :label="$t('page.resource.infoFileLastModified')"> <CoscineFormGroup :label="$t('page.resource.infoFileLastModified')">
<div class="fileInfoField">
{{ {{
!currentFile.lastModified !currentFile.lastModified
? $t("page.resource.infoFileNoInformation") ? $t("page.resource.infoFileNoInformation")
: new Date(currentFile.lastModified).toLocaleDateString( : new Date(currentFile.lastModified).toLocaleDateString($i18n.locale)
$i18n.locale
)
}} }}
</div>
</CoscineFormGroup> </CoscineFormGroup>
<!-- Uploaded -->
<CoscineFormGroup :label="$t('page.resource.infoFileCreated')"> <CoscineFormGroup :label="$t('page.resource.infoFileCreated')">
<div class="fileInfoField">
{{ {{
!currentFile.created !currentFile.createdAt
? $t("page.resource.infoFileNoInformation") ? $t("page.resource.infoFileNoInformation")
: new Date(currentFile.created).toLocaleDateString($i18n.locale) : new Date(currentFile.createdAt).toLocaleDateString($i18n.locale)
}} }}
</div>
</CoscineFormGroup> </CoscineFormGroup>
<!-- File Size -->
<CoscineFormGroup :label="$t('page.resource.infoFileSize')"> <CoscineFormGroup :label="$t('page.resource.infoFileSize')">
<div class="fileInfoField">
{{ {{
currentFile.isFolder === false currentFile.isFolder === false
? currentFile.size + " Bytes" ? currentFile.size + " Bytes"
: $t("page.resource.infoFileNoInformation") : $t("page.resource.infoFileNoInformation")
}} }}
</div>
</CoscineFormGroup> </CoscineFormGroup>
</span> </span>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, type PropType } from "vue"; import { defineComponent, type PropType } from "vue";
import type { FolderContent } from "@/modules/resource/types";
import type { FolderContent } from "../../../utils/EntryDefinition";
export default defineComponent({ export default defineComponent({
props: { props: {
...@@ -71,12 +68,7 @@ export default defineComponent({ ...@@ -71,12 +68,7 @@ export default defineComponent({
</script> </script>
<style scoped> <style scoped>
.fileInfoField { #fileInfofileName {
padding-top: calc(0.375rem + 1px);
padding-bottom: calc(0.375rem + 1px);
}
#fileInfoFieldID {
margin-left: auto;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
......
...@@ -65,20 +65,20 @@ ...@@ -65,20 +65,20 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, type PropType } from "vue"; import { defineComponent, type PropType } from "vue";
import useProjectStore from "@/modules/project/store"; 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 { FolderContent } from "../../../utils/EntryDefinition";
import type { TranslateResult } from "vue-i18n"; import type { TranslateResult } from "vue-i18n";
import type { import type {
GitlabBranchDto, GitlabBranchDto,
ResourceDto, ResourceDto,
ResourceTypeInformationDto, ResourceTypeInformationDto,
} from "@coscine/api-client/dist/types/Coscine.Api"; } from "@coscine/api-client/dist/types/Coscine.Api";
import { CoscineResourceTypes } from "@/modules/resource/types"; import {
CoscineResourceTypes,
type FolderContent,
} from "@/modules/resource/types";
export default defineComponent({ export default defineComponent({
props: { props: {
editableDataUrl: { editableDataUrl: {
...@@ -168,7 +168,6 @@ export default defineComponent({ ...@@ -168,7 +168,6 @@ export default defineComponent({
const accessToken = const accessToken =
this.resource.type?.options?.gitLabOptions?.accessToken; this.resource.type?.options?.gitLabOptions?.accessToken;
const currentBranch = this.resource.type?.options?.gitLabOptions?.branch; const currentBranch = this.resource.type?.options?.gitLabOptions?.branch;
if (projectId && domain && accessToken && currentBranch) { if (projectId && domain && accessToken && currentBranch) {
const gitlabBranches = const gitlabBranches =
await this.resourceStore.getGitlabBranchesForProject( await this.resourceStore.getGitlabBranchesForProject(
......
<template> <template>
<div> <div>
<!-- Data URL -->
<span v-if="editableDataUrl && !currentFolderContent.isFolder"> <span v-if="editableDataUrl && !currentFolderContent.isFolder">
<CoscineFormGroup <CoscineFormGroup
:mandatory="true" :mandatory="true"
...@@ -21,6 +22,8 @@ ...@@ -21,6 +22,8 @@
</b-input-group> </b-input-group>
</CoscineFormGroup> </CoscineFormGroup>
</span> </span>
<!-- Entry Name - Editable Key -->
<span v-if="editableKey"> <span v-if="editableKey">
<CoscineFormGroup <CoscineFormGroup
:mandatory="true" :mandatory="true"
...@@ -43,7 +46,7 @@ ...@@ -43,7 +46,7 @@
import { defineComponent, type PropType } from "vue"; import { defineComponent, type PropType } from "vue";
import useProjectStore from "@/modules/project/store"; import useProjectStore from "@/modules/project/store";
import type { FolderContent } from "../../../utils/EntryDefinition"; import type { FolderContent } from "@/modules/resource/types";
import type { ResourceDto } from "@coscine/api-client/dist/types/Coscine.Api"; import type { ResourceDto } from "@coscine/api-client/dist/types/Coscine.Api";
export default defineComponent({ export default defineComponent({
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment