diff --git a/src/components/descriptors/OcDescriptorResource/OcDescriptorResource.vue b/src/components/descriptors/OcDescriptorResource/OcDescriptorResource.vue index d566e7e1e867025402dcec4a17b64a71574256cc..868dc577990a2d74811b2062208520fb7686e35c 100644 --- a/src/components/descriptors/OcDescriptorResource/OcDescriptorResource.vue +++ b/src/components/descriptors/OcDescriptorResource/OcDescriptorResource.vue @@ -6,6 +6,8 @@ size="small" :label="t('descriptors.toolbar.share')" icon="fa-solid fa-share-nodes" + as="a" + :href="shareLink" /> <Button @@ -14,27 +16,17 @@ severity="secondary" icon="fa-solid fa-edit" /> - <!-- <Button - size="small" - :label="t('descriptors.toolbar.remove')" - severity="danger" - icon="fa-solid fa-trash" - /> --> - <Button - size="small" - :label="t('descriptors.toolbar.report')" - severity="warn" - icon="fa-solid fa-bullhorn" - /> </div> <Button + v-if="contactPointLink" size="small" :label="t('descriptors.toolbar.contact')" severity="info" icon="fa-solid fa-envelope" + as="a" + :href="contactPointLink" /> </header> - <OcDescriptorResourceSkeleton v-if="props.loading" /> <div class="shadow-md bg-slate-100 rounded border my-8 p-8 relative" v-else> <header class="flex-1"> @@ -213,10 +205,11 @@ import Button from 'primevue/button' import Menu from 'primevue/menu' import type { MenuItem } from 'primevue/menuitem' import OcDescriptorResourceSkeleton from '@/components/descriptors/OcDescriptorResourceSkeleton/OcDescriptorResourceSkeleton.vue' -import type { OcConcept, OcDataset } from '@/declarations' +import type { OcConcept, OcDataset, OcPerson } from '@/declarations' import OcDescriptorStatus from '@/components/descriptors/OcDescriptorStatus/OcDescriptorStatus.vue' import OcDescriptorSpatialCoverage from '@/components/descriptors/OcDescriptorSpatialCoverage/OcDescriptorSpatialCoverage.vue' import { datasetMetadata } from '@/modelMetadata/dataset' +import { useRoute } from 'vue-router' const { locale } = useI18n({ useScope: 'local' @@ -226,9 +219,11 @@ const { translateValue: globalTranslateValue } = useTranslateValue() const { t } = useI18n() +const route = useRoute() + const props = defineProps<{ loading: boolean - resource?: OcDataset + resource?: OcResource }>() const menu = ref() @@ -239,7 +234,6 @@ const menu = ref() */ const availableLangs: ComputedRef<MenuItem[]> = computed(() => { const localeItems: MenuItem[] = [] - const langs = new Set<string>() if (!props.resource) return localeItems if (typeof props.resource.title === 'object') { @@ -260,4 +254,43 @@ const availableLangs: ComputedRef<MenuItem[]> = computed(() => { return localeItems }) + +/** + * Share link + */ +const shareLink = computed(() => { + const resourceType = 'dataset' + const resourceTitle = globalTranslateValue(props.resource?.title) + const resourceLink = `${import.meta.env.BASE_URL}/${route.path}` + + const subject = t('emails.share.subject', { resourceType, resourceTitle }) + const body = t('emails.share.body', { resourceType, resourceTitle, resourceLink }) + return `mailto:?subject=${subject}&body=${body}` +}) + +/** + * Contact point link + * * compute if any contact points the mailing list to address the ask + * * if no contact point found, return null + */ +const contactPointLink = computed(() => { + let mailto: string = '' + if (Array.isArray(props.resource?.contactPoint)) { + if (props.resource?.contactPoint.length < 1) return null + props.resource.contactPoint.forEach((cp: OcPerson) => { + if (cp.mbox) mailto += `${cp.mbox};` + }) + } else { + if (props.resource?.contactPoint?.mbox) mailto += `${props.resource?.contactPoint?.mbox};` + } + if (mailto === '') return null + + const resourceType = 'dataset' + const resourceTitle = globalTranslateValue(props.resource?.title) + const resourceLink = `${import.meta.env.BASE_URL}/${route.path}` + + const subject = t('emails.ask.subject', { resourceType, resourceTitle }) + const body = t('emails.ask.body', { resourceType, resourceTitle, resourceLink }) + return `mailto:${mailto}?subject=${subject}&body=${body}` +}) </script> diff --git a/src/components/descriptors/OcDescriptorResourceSkeleton/OcDescriptorResourceSkeleton.vue b/src/components/descriptors/OcDescriptorResourceSkeleton/OcDescriptorResourceSkeleton.vue index 8de769aa6c42fdc0a808b9f964faef724d6f5e65..4b49a8c190a4a128bf3823de36d24e5424f7c661 100644 --- a/src/components/descriptors/OcDescriptorResourceSkeleton/OcDescriptorResourceSkeleton.vue +++ b/src/components/descriptors/OcDescriptorResourceSkeleton/OcDescriptorResourceSkeleton.vue @@ -11,9 +11,16 @@ <div class="flex gap-4 w-full max-w-full"> <main style="width: calc(100% - 20rem)"> <div class="animate-pulse flex flex-col"> + <section class="my-4"> + <h2 class="text-xl font-medium mb-2"> + {{ globalTranslateValue(datasetMetadata.type.label) }} + </h2> + <div class="rounded bg-slate-200 w-28 h-8 text-white font-medium px-2 py-1"></div> + </section> + <section class="my-4"> <h2 class="text-xl text-slate-400 font-medium mb-2"> - {{ t('descriptors.dataset.theme') }} + {{ globalTranslateValue(datasetMetadata.theme.label) }} </h2> <div class="flex gap-2"> <div class="rounded bg-slate-200 w-28 h-8 text-white font-medium px-2 py-1" /> @@ -24,7 +31,7 @@ <section class="my-4"> <h2 class="text-xl text-slate-400 font-medium mb-2"> - {{ t('descriptors.dataset.keyword') }} + {{ globalTranslateValue(datasetMetadata.keyword.label) }} </h2> <div class="flex gap-2 flex-wrap"> <div class="rounded bg-slate-200 w-28 h-8 text-white font-medium px-2 py-1" /> @@ -35,7 +42,7 @@ <section class="my-4 pb-4"> <h2 class="text-xl text-slate-400 font-medium mb-2"> - {{ t('descriptors.dataset.description') }} + {{ globalTranslateValue(datasetMetadata.description.label) }} </h2> <div class="space-y-3"> <div class="grid grid-cols-3 gap-4"> @@ -64,5 +71,9 @@ <script setup lang="ts"> import { useI18n } from 'vue-i18n' +import { datasetMetadata } from '@/modelMetadata/dataset' +import { useTranslateValue } from '@/composables/useTranslateValue' + const { t } = useI18n() -</script> \ No newline at end of file +const { translateValue: globalTranslateValue } = useTranslateValue() +</script> diff --git a/src/components/descriptors/OcDescriptorStatus/OcDescriptorStatus.vue b/src/components/descriptors/OcDescriptorStatus/OcDescriptorStatus.vue index 77ad8b16c3807c45b9f37632a2354853786c7be4..09c4ab226bb7788ced078755d0cfa24ec5d7bcfb 100644 --- a/src/components/descriptors/OcDescriptorStatus/OcDescriptorStatus.vue +++ b/src/components/descriptors/OcDescriptorStatus/OcDescriptorStatus.vue @@ -7,11 +7,11 @@ <script setup lang="ts"> // see http://publications.europa.eu/resource/authority/dataset-status to all values import { useTranslateValue } from '@/composables/useTranslateValue' -import type { OcVocabulary } from '@/declarations' +import type { OcConcept } from '@/declarations' import { computed } from 'vue' const props = defineProps<{ - status: OcVocabulary + status: OcConcept }>() const { translateValue } = useTranslateValue('local') diff --git a/src/layout/OcLayoutCommunityWithTree/OcLayoutCommunityWithTree.vue b/src/layout/OcLayoutCommunityWithTree/OcLayoutCommunityWithTree.vue index e92233797d2d8a805aacb14492e6e8f80b07b19f..b0dbb4bf7375a97478a39c79908ac2a498933572 100644 --- a/src/layout/OcLayoutCommunityWithTree/OcLayoutCommunityWithTree.vue +++ b/src/layout/OcLayoutCommunityWithTree/OcLayoutCommunityWithTree.vue @@ -53,7 +53,7 @@ const props = defineProps({ default: false }, userPrivateGraph: { - type: String, + type: String }, community: { type: Object as PropType<OcCommunity>, @@ -62,7 +62,7 @@ const props = defineProps({ breadcrumbItems: { type: Object as PropType<OcBreadcrumbItem[]>, required: true - }, + } }) const { locale, t } = useI18n() diff --git a/src/locales/en.ts b/src/locales/en.ts index d0f600ddb8e245c17f182abc381de10d2b6bb236..da350383723a0d976ce071ac8d79bedac1ea7dc6 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -1,3 +1,6 @@ +// carriage return character +const crEncoded = '%0D%0A' + export default { topMenu: { contact: { @@ -262,5 +265,33 @@ export default { community: 'Community resource', private: 'Private resource', protected: 'Protected resource' + }, + emails: { + share: { + subject: `[SO DRIIHM] Share of the {resourceType} : {resourceTitle}`, + body: ` +Hello, ${crEncoded} +${crEncoded} +I would like to share with you the {resourceType} whose title is : ${crEncoded} +{resourceTitle}${crEncoded} +${crEncoded} +You can access through the following link : {resourceLink}${crEncoded} +${crEncoded} +Greetings, + ` + }, + ask: { + subject: `[SO DRIIHM] Ask for contact for the {resourceType} : {resourceTitle}`, + body: ` +Hello, ${crEncoded} +${crEncoded} +I would like to ask contact with you for the {resourceType} whose title is : ${crEncoded} +{resourceTitle}${crEncoded} +${crEncoded} +and can be found by following the link : {resourceLink}${crEncoded} +${crEncoded} +Greetings, + ` + } } } diff --git a/src/locales/fr.ts b/src/locales/fr.ts index cc52bdc7dbfda31359f2592597ed61adfe380abb..de5d28132d583d10317c3d27da5675761ae44ec4 100644 --- a/src/locales/fr.ts +++ b/src/locales/fr.ts @@ -1,3 +1,6 @@ +// carriage return character +const crEncoded = '%0D%0A' + export default { topMenu: { contact: { @@ -263,5 +266,47 @@ export default { community: 'Ressource communautaire', private: 'Ressource privée', protected: 'Ressource protégée' + }, + emails: { + share: { + subject: ({ linked, named }) => + `[SO DRIIHM] Partage ${linked('emails.resourceTypeSubject.' + named('resourceType'))} : ${named('resourceTitle')}`, + body: ({ linked, named }) => ` +Bonjour, ${crEncoded} +${crEncoded} +Je souhaite vous partager ${linked('emails.resourceTypeBody.' + named('resourceType'))} dont le titre est : ${crEncoded} +${named('resourceTitle')}${crEncoded} +${crEncoded} +Vous pouvez y accéder en suivant le lien suivant : ${named('resourceLink')}${crEncoded} +${crEncoded} +Cordialement, + ` + }, + ask: { + subject: ({ linked, named }) => + `[SO DRIIHM] Prise de contact pour ${linked('emails.resourceTypeBody.' + named('resourceType'))} : ${named('resourceTitle')}`, + body: ({ linked, named }) => ` +Bonjour, ${crEncoded} +${crEncoded} +Je souhaite prendre contact avec vous concernant ${linked('emails.resourceTypeBody.' + named('resourceType'))} dont le titre est : ${crEncoded} +${named('resourceTitle')}${crEncoded} +${crEncoded} +et est accessible en suivant le lien suivant : ${named('resourceLink')}${crEncoded} +${crEncoded} +Cordialement, + ` + }, + resourceTypeSubject: { + dataset: 'du dataset', + catalog: 'du catalogue', + service: 'du service', + distribution: 'de la distribution' + }, + resourceTypeBody: { + dataset: 'le dataset', + catalog: 'le catalogue', + service: 'le service', + distribution: 'la distribution' + } } }