Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 41 additions & 12 deletions confiture-web-app/src/components/overview/ReportStep.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { computed } from "vue";

import { useResultsStore } from "../../store";
import { Audit } from "../../types";
import CopyBlock from "../ui/CopyBlock.vue";
import CopyButton from "../ui/CopyButton.vue";
import StepCard from "./StepCard.vue";

defineProps<{
Expand Down Expand Up @@ -46,17 +46,34 @@ const auditIsReady = computed(() => {
: "Terminez l’audit avant de livrer le rapport d’audit."
}}
</p>
<CopyBlock
class="report-step-copy"
:to="{
name: 'report',
params: { uniqueId: audit.consultUniqueId }
}"
:show-copy-button="auditIsReady"
success-message="Le lien vers le rapport d’audit a bien été copié dans le presse-papier."
link-hidden-label="le rapport"
copy-button-hidden-label="du rapport"
/>
<div class="report-step-actions">
<div class="fr-btns-group fr-btns-group--icon-left">
<RouterLink
:to="{
name: 'report',
params: { uniqueId: audit.consultUniqueId }
}"
target="_blank"
class="fr-btn fr-btn--tertiary fr-mb-0"
>
Consulter
<span class="fr-sr-only">le rapport (nouvelle fenêtre)</span>
</RouterLink>
</div>

<div class="fr-btns-group fr-btns-group--icon-left">
<CopyButton
label="Copier le lien de partage"
icon="fr-icon-link"
success-label="Lien de partage copié"
:content-to-copy="{
name: 'report',
params: { uniqueId: audit.consultUniqueId }
}"
is-within-btn-group
/>
</div>
</div>
</StepCard>
</template>

Expand All @@ -69,4 +86,16 @@ const auditIsReady = computed(() => {
.report-step-copy {
grid-column: 1 / -1;
}

.report-step-actions {
grid-column: 1/-1;
display: grid;
grid-template-columns: subgrid;

@media (width < 48rem) {
grid-template-columns: 1fr;
grid-template-rows: 1fr 1fr;
gap: 1rem;
}
}
</style>
55 changes: 40 additions & 15 deletions confiture-web-app/src/components/overview/StatementStep.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { computed } from "vue";
import { useResultsStore } from "../../store";
import { Audit } from "../../types";
import { formatDate, isSameDay } from "../../utils";
import CopyBlock from "../ui/CopyBlock.vue";
import CopyButton from "../ui/CopyButton.vue";
import StepCard from "./StepCard.vue";

const props = defineProps<{
Expand Down Expand Up @@ -68,20 +68,33 @@ const auditIsPublishable = computed(() => {
</template>
</p>

<CopyBlock
v-if="auditIsPublishable"
class="statement-step-copy"
:to="{
name: 'a11y-statement',
params: {
uniqueId: audit.consultUniqueId
}
}"
:show-copy-button="auditIsPublishable"
success-message="Le lien vers la déclaration d’accessibilité a bien été copié dans le presse-papier."
link-hidden-label="la déclaration d’accessibilité"
copy-button-hidden-label="de la déclaration d’accessibilité"
/>
<div v-if="auditIsPublishable" class="statement-step-actions">
<div class="fr-btns-group fr-btns-group--icon-left">
<RouterLink
:to="{
name: 'a11y-statement',
params: { uniqueId: audit.consultUniqueId }
}"
target="_blank"
class="fr-btn fr-btn--tertiary fr-mb-0"
>
Consulter
<span class="fr-sr-only">la déclaration d’accessibilité (nouvelle fenêtre)</span>
</RouterLink>
</div>
<div class="fr-btns-group fr-btns-group--icon-left">
<CopyButton
label="Copier le lien de partage"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Et si on mettait ces 2 props label et success-label en valeurs par défaut dans le composant CopyButton à "Copier le lien de partage" et "Lien de partage copié" ? Comme ça pas besoin de répéter à chaque fois ces même textes. (En gardant la possibilité de spécifier d’autres labels au cas où…)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oui effectivement, surtout que ça sera souvent ces labels là.

icon="fr-icon-link"
success-label="Lien de partage copié"
:content-to-copy="{
name: 'a11y-statement',
params: { uniqueId: audit.consultUniqueId }
}"
is-within-btn-group
/>
</div>
</div>

<ul
v-else
Expand Down Expand Up @@ -145,4 +158,16 @@ const auditIsPublishable = computed(() => {
.statement-step-copy {
grid-column: 1 / -1;
}

.statement-step-actions {
grid-column: 1/-1;
display: grid;
grid-template-columns: subgrid;

@media (width < 48rem) {
grid-template-columns: 1fr;
grid-template-rows: 1fr 1fr;
gap: 1rem;
}
}
</style>
106 changes: 0 additions & 106 deletions confiture-web-app/src/components/ui/CopyBlock.vue

This file was deleted.

63 changes: 63 additions & 0 deletions confiture-web-app/src/components/ui/CopyButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<script lang="ts" setup>
import { templateRef } from "@vueuse/core";
import { onMounted, ref } from "vue";
import { RouteLocationRaw } from "vue-router";
import router from "../../router";

const props = defineProps<{
icon: string;
label: string;
successLabel: string;
contentToCopy: string | RouteLocationRaw;
isWithinBtnGroup?: boolean;
}>();

const showSuccess = ref(false);

function copyContentToClipboard() {
const content = typeof props.contentToCopy === "string"
? props.contentToCopy
: window.location.origin + router.resolve(props.contentToCopy).fullPath;

navigator.clipboard.writeText(content).then(() => {
showSuccess.value = true;
});

setTimeout(() => {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Attention le comportement est étrange si on clic alors que le message de succès est déjà affiché et que le délai (setTimeout) est en cours.

Après la sélection du bouton "Copier le lien de partage", changer le <button> par une <div> ? Ainsi il ne sera plus possible de cliquer dessus ! Attention à la restitution aux aides techniques.
Aussi, pour aller jusqu’au bout, on peut vérifier l’id retourné par le setTimeout : ne pas relancer de setTimeout tant qu’un délai est en cours.

Copy link
Copy Markdown
Collaborator Author

@bellangerq bellangerq Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dans la méthode, j'ai rajouté ça pour ne rien faire si on montre déjà le succès. Et du coup ça relance pas un nouveau setTimeout().

if (showSuccess.value) return;

showSuccess.value = false;
}, 3500);
}

const initialButtonWidth = ref<string>();
const copyButtonRef = templateRef("copyButtonRef");
onMounted(() => {
initialButtonWidth.value = `${copyButtonRef.value?.offsetWidth}px`;
});
</script>

<template>
<button
ref="copyButtonRef"
type="button"
:class="[`fr-btn fr-btn--secondary fr-btn--icon-left ${showSuccess ? 'fr-icon-check-line copy-button--success' : icon} copy-button`, {
'copy-button--within-btn-group fr-mb-0': isWithinBtnGroup
}]"
@click="copyContentToClipboard"
>
{{ showSuccess ? successLabel : label }}
</button>
</template>

<style scoped>
.copy-button {
&:not(.copy-button--within-btn-group) {
width: v-bind(initialButtonWidth) !important;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super le width qui se met à jour !

Attention ça casse le côté responsive sur petits écrans, côté rapport ("within btn group").

Rajouter ici :

max-width: 100%;

Et sur .heading-action :

flex-wrap: wrap;
max-width: 100%;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bien vu !

D'ailleurs, j'ai l'impression que seul le flex-wrap suffit sur .heanding-action.

justify-content: center !important;
}
}

.copy-button--success {
color: var(--text-default-success) !important;
box-shadow: inset 0 0 0 1px var(--text-default-success) !important;
}
</style>
44 changes: 9 additions & 35 deletions confiture-web-app/src/pages/report/ReportPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import ReportErrors from "../../components/report/ReportErrors.vue";
import ReportImprovements from "../../components/report/ReportImprovements.vue";
import ReportNotes from "../../components/report/ReportNotes.vue";
import ReportResults from "../../components/report/ReportResults.vue";
import CopyButton from "../../components/ui/CopyButton.vue";
import Dropdown from "../../components/ui/Dropdown.vue";
import TopLink from "../../components/ui/TopLink.vue";
import { useWrappedFetch } from "../../composables/useWrappedFetch";
Expand All @@ -35,7 +36,6 @@ const report = useReportStore();

const router = useRouter();

const showCopyAlert = ref(false);
const onboardingModalRef = ref<InstanceType<typeof OnboardingModal>>();
const tabsRef = ref<InstanceType<typeof AraTabs>>();

Expand Down Expand Up @@ -120,23 +120,10 @@ const siteUrl = computed(() => {
return null;
});

const copyReportButtonRef = ref<HTMLButtonElement>();

async function copyReportUrl() {
const url =
window.location.origin +
const reportUrlToCopy =
window.location.origin +
router.resolve({ name: "report", params: { uniqueId } }).fullPath;

navigator.clipboard.writeText(url).then(() => {
showCopyAlert.value = true;
});
}

function hideReportAlert() {
showCopyAlert.value = false;
copyReportButtonRef.value?.focus();
}

function onOnboardingClose() {
localStorage.setItem("confiture:seen-onboarding", "true");
}
Expand Down Expand Up @@ -175,13 +162,12 @@ watch(
<div class="fr-mb-3v heading">
<h1 class="fr-mb-0">Rapport d’audit accessibilité</h1>
<div class="heading-actions">
<button
ref="copyReportButtonRef"
class="fr-btn fr-btn--secondary fr-btn--icon-left fr-icon-links-fill"
@click="copyReportUrl"
>
Copier le lien du rapport
</button>
<CopyButton
icon="fr-icon-link"
:content-to-copy="reportUrlToCopy"
label="Copier le lien du rapport"
success-label="Lien copié"
/>
<Dropdown
title="Télécharger"
:button-props="{ class: 'fr-btn--secondary' }"
Expand All @@ -204,18 +190,6 @@ watch(
</div>
</div>

<div role="alert" aria-live="polite">
<div
v-if="showCopyAlert"
class="fr-alert fr-alert--success fr-alert--sm fr-mb-2w"
>
<p>Le lien vers le rapport a bien été copié dans le presse-papier.</p>
<button class="fr-link fr-link--close" @click="hideReportAlert">
Masquer le message
</button>
</div>
</div>

<template v-if="report.data">
<PageMeta
:title="pageTitle"
Expand Down
Loading
Loading