Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
9 changes: 1 addition & 8 deletions confiture-web-app/src/components/overview/AuditStep.vue
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,7 @@ const auditIsInProgress = computed(() => {
/>

<ul
:class="[
'fr-btns-group fr-btns-group--icon-left audit-step-card-actions',
{ 'audit-step-card-actions--half': auditIsReady }
]"
class="fr-btns-group fr-btns-group--icon-left audit-step-card-actions"
>
<li>
<RouterLink
Expand Down Expand Up @@ -215,10 +212,6 @@ const auditIsInProgress = computed(() => {
grid-column: 1 / -1;
}

.audit-step-card-actions--half {
grid-column: 1;
}

@media (width < 48rem) {
.audit-step-charts {
grid-template-columns: 1fr;
Expand Down
3 changes: 1 addition & 2 deletions confiture-web-app/src/components/overview/GridStep.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@ const csvExportSizeEstimation = computed(() => {
<ul class="fr-btns-group fr-btns-group--icon-left">
<li>
<a
class="fr-btn fr-mb-1w fr-btn--icon-left fr-icon-download-line"
:class="auditIsReady ? 'fr-btn--secondary' : 'fr-btn--tertiary'"
class="fr-btn fr-btn--secondary fr-btn--icon-left fr-icon-download-line fr-mb-1w"
aria-describedby="audit-grid-step-download-informations"
:href="csvExportUrl"
:download="csvExportFilename"
Expand Down
52 changes: 40 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,33 @@ 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
hidden-label-suffix="du rapport"
icon="fr-icon-link"
:content-to-copy="{
name: 'report',
params: { uniqueId: audit.consultUniqueId }
}"
is-within-btn-group
/>
</div>
</div>
</StepCard>
</template>

Expand All @@ -69,4 +85,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>
54 changes: 39 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,32 @@ 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
hidden-label-suffix="de la déclaration"
icon="fr-icon-link"
: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 +157,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.

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

/**
* FIXME: trigger warning ⚠️ the code of the following component is a bit dirty.
*
* The goal is to create a button that changes its content
* when clicked without changing its size, in 2 different contexts.
*/
const props = withDefaults(defineProps<{
icon: string;
label?: string;
successLabel?: string;
hiddenLabelSuffix?: string;
contentToCopy: string | RouteLocationRaw;
isWithinBtnGroup?: boolean;
}>(), {
label: "Copier le lien de partage",
successLabel: "Lien copié"
});

const showSuccess = ref(false);

function copyContentToClipboard() {
if (showSuccess.value) return;

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);
}
</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"
>
<template v-if="isWithinBtnGroup">
{{ showSuccess ? successLabel : label }}
</template>

<span v-else class="copy-button-outer-wrapper" :style="{ '--content': `'${label}'` }">
<span class="copy-button-inner-wrapper">
<template v-if="showSuccess">
<span class="fr-icon-check-line copy-button-success-icon" aria-hidden="true" />
{{ successLabel }}
</template>
<template v-else>
{{ label }}
</template>
</span>
</span>

<span v-if="hiddenLabelSuffix" class="fr-sr-only">{{ hiddenLabelSuffix }}</span>
</button>
</template>

<style scoped>
.copy-button {
&:not(.copy-button--within-btn-group) {
.copy-button-outer-wrapper {
position: relative;

&::after {
content: var(--content);
visibility: hidden;
}

.copy-button-inner-wrapper {
position: absolute;
inset: 0;
display: flex;
gap: 0.5rem;
}

.copy-button-success-icon::before {
--icon-size: 1rem;
}
}
}
}

.copy-button--success {
color: var(--text-default-success) !important;
box-shadow: inset 0 0 0 1px var(--text-default-success) !important;

&:not(.copy-button--within-btn-group) {
.copy-button-inner-wrapper {
translate: 1.5rem;
}

&::before {
opacity: 0 !important;
}
}
}
</style>
Loading
Loading