Select Git revision
Settings.vue
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
MetadataResult.vue 10.43 KiB
<template>
<div class="p-2">
<a :href="url">
<div id="resultHeader" class="mb-2 text-left text-primary">
<b>
{{
`${
result.type
? $t("results.labels." + result.type.toLowerCase())
: $t("results.labels.result")
}: `
}}
</b>
<!-- eslint-disable vue/no-v-html -->
<span
v-html="
$options.filters
? $options.filters.highlight(displayName, query)
: null
"
/>
<b-badge v-if="archived" pill variant="warning" class="ml-1">
{{ $t("default.archived") }}
</b-badge>
</div>
</a>
<div id="resultBody" class="text-left">
<span
v-for="(element, index) in fields"
:key="index"
class="mr-3 d-inline-block"
>
<span v-if="index === 'isPublic'">
<b>{{ `${$t("results.labels.visibility")}: ` }}</b>
<span v-if="element">
{{ $t("results.labels.isPublic") }}
<b-icon icon="people-fill" />
</span>
<span v-else>
{{ $t("results.labels.isPrivate") }}
<b-icon icon="shield-lock-fill" />
</span>
</span>
<span v-else-if="index === 'belongsToProject'">
<b>{{ `${$t(`results.labels.${index}`)}: ` }}</b>
<!-- eslint-disable vue/no-v-html -->
<span
v-html="
$options.filters
? $options.filters.highlight(belongsToProject(element), query)
: null
"
/>
</span>
<span v-else-if="index === 'homepage' && result.type !== 'Metadata'">
<b>{{ `${$t(`results.labels.pid`)}: ` }}</b>
<a :href="element">
<!-- eslint-disable vue/no-v-html -->
<span
v-html="
$options.filters
? $options.filters.highlight(substringPID(element), query)
: null
"
/>
</a>
</span>
<span v-else-if="index === 'service' && resourceType">
<b>{{ `${$t(`results.labels.resourceType`)}: ` }}</b>
<!-- eslint-disable vue/no-v-html -->
<span
v-html="
$options.filters
? $options.filters.highlight(
resourceType.displayName
? resourceTypeName(resourceType.displayName)
: null,
query
)
: null
"
/>
</span>
<span v-else-if="index !== 'structureType' && index !== 'deleted'">
<b v-if="$te(`results.labels.${index}`)">
{{ `${$t(`results.labels.${index}`)}: ` }}
</b>
<b v-else>{{ `${formatKey(index)}: ` }}</b>
<!-- eslint-disable vue/no-v-html -->
<span
v-html="
$options.filters
? $options.filters.highlight(element, query)
: null
"
/>
</span>
<!--
Keep the <br/> element at the end to have
double mouse click text selection work properly and
not have a table horizontal scrollbar appear
-->
<br />
</span>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, type PropType } from "vue";
import useResourceStore from "@/modules/resource/store";
import type { ItemSearchResult } from "@coscine/api-client/dist/types/Coscine.Api.Search";
import type { ProjectObject } from "@coscine/api-client/dist/types/Coscine.Api.Project";
import type { ResourceTypeObject } from "@coscine/api-client/dist/types/Coscine.Api.Resources";
export default defineComponent({
name: "MetadataResult",
filters: {
highlight(words: string, query: string) {
if (query.trim() !== "" && query.trim() !== "*") {
const iQuery = new RegExp(query, "ig");
return words.toString().replace(iQuery, function (matchedTxt) {
return "<mark>" + matchedTxt + "</mark>";
});
}
return words;
},
},
props: {
result: {
required: true,
type: Object as PropType<ItemSearchResult>,
},
allProjects: {
required: true,
type: Array as PropType<ProjectObject[] | null>,
},
query: {
required: true,
type: String,
},
},
setup() {
const resourceStore = useResourceStore();
return { resourceStore };
},
computed: {
archived(): boolean | undefined {
if (this.result.type === "Resource") {
if (this.result.source["archived"]) {
return this.result.source["archived"] === "true";
}
}
// No other way to get that information
return false;
},
displayName(): string | null | undefined {
if (
(this.result.type === "Resource" || this.result.type === "Project") &&
this.result.source["title"]
) {
return this.result.source["title"];
} else if (
this.result.type === "Metadata" &&
this.result.source["fileName"]
) {
return this.result.source["fileName"];
} else {
return this.result.graphName
? decodeURIComponent(this.result.graphName.split("/").at(-2) ?? "")
: "";
}
},
project(): ProjectObject | undefined {
return this.allProjects
? this.allProjects.find((p) => p.id === this.projectId)
: undefined;
},
projectId(): string | null {
if (this.result.source) {
if (this.result.source["belongsToProject"]) {
return this.result.source["belongsToProject"].replace(
"https://purl.org/coscine/projects/",
""
);
}
}
return null;
},
resourceId(): string | null {
if (
(this.result.source["homepage"] || this.result.graphName) &&
(this.result.type === "Resource" || this.result.type === "Metadata")
) {
let graphName = this.result.graphName ?? "";
if (this.result.source["homepage"]) {
graphName = this.result.source["homepage"];
}
let resourceId = graphName.substring(graphName.lastIndexOf("/") + 1);
if (this.result.type === "Metadata") {
resourceId = resourceId.substring(0, resourceId.indexOf("@"));
}
return resourceId;
}
return null;
},
resourceType(): ResourceTypeObject | undefined | null {
if (
this.resourceTypes &&
this.result.type === "Resource" &&
this.result.source["service"]
) {
const resourceTypeId = this.result.source["service"].substring(
this.result.source["service"].lastIndexOf("/") + 1
);
return this.resourceTypes.find(
(resourceType) => resourceType.id === resourceTypeId
);
}
return null;
},
resourceTypes(): ResourceTypeObject[] | null {
return this.resourceStore.resourceTypes;
},
fields(): Record<string, string> {
let entries: [string, string][] = Object.entries(this.result.source);
entries = entries.filter(
(entry) =>
entry[0] !== "structureType" &&
entry[1] !== "" &&
entry[1] !== null &&
entry[1] !== undefined &&
!(
this.result.type === "Project" &&
(entry[0] === "deleted" ||
entry[0] === "deleted_written" ||
entry[0] === "hasmember" ||
entry[0] === "member" ||
entry[0] === "catalog" ||
entry[0] === "organization" ||
entry[0] === "belongsToProject" ||
entry[0] === "role")
) &&
!(
this.result.type === "Resource" &&
(entry[0] === "archived_written" ||
entry[0] === "fixedvalues" ||
entry[0] === "creator" ||
entry[0] === "catalog" ||
entry[0] === "mode" ||
entry[0] === "accessto" ||
entry[0] === "default" ||
entry[0] === "deleted" ||
entry[0] === "deleted_written" ||
entry[0] === "agentgroup")
) &&
!(
(this.result.type === "Project" ||
this.result.type === "Resource") &&
(entry[0] === "graphName" || entry[0] === "visibility")
)
);
const fields: Record<string, string> = {};
entries.forEach((entry) => (fields[entry[0]] = entry[1]));
return fields;
},
url(): string {
if (this.result.type === "Project" && this.project && this.project.slug) {
return this.$router.resolve({
name: "project-page",
params: { slug: this.project.slug },
}).href;
} else if (
this.result.type === "Resource" &&
this.resourceId &&
this.project &&
this.project.slug
) {
return this.$router.resolve({
name: "resource-page",
params: {
guid: this.resourceId,
slug: this.project.slug,
},
}).href;
} else if (
this.result.type === "Metadata" &&
this.resourceId &&
this.project &&
this.project.slug
) {
return this.$router.resolve({
name: "resource-page",
params: {
guid: this.resourceId,
slug: this.project.slug,
},
}).href;
} else {
return this.result.source["homepage"] ?? this.result.graphName ?? "#";
}
},
},
methods: {
belongsToProject(value: string): string {
const project = this.allProjects
? this.allProjects.find((p) => p.id === this.projectId)
: null;
if (project && project.displayName) {
return project.displayName;
} else return value;
},
substringPID(value: string): string {
return value.substring(value.indexOf(".net/") + 5);
},
resourceTypeName(value: string | null): string {
return this.$t("resourceTypes." + value + ".displayName").toString();
},
formatKey(key: string) {
const words = key.replace("_", " ").replace("_", " ").split(" ");
for (let i = 0; i < words.length; i++) {
words[i] = words[i][0].toUpperCase() + words[i].substring(1);
}
return words.join(" ");
},
isPublic(value: string): string {
return value
? this.$t("results.labels.isPublic").toString()
: this.$t("results.labels.isPrivate").toString();
},
},
});
</script>