2025-01-22 13:25:34 +01:00
|
|
|
|
<template>
|
2025-01-27 11:06:06 +01:00
|
|
|
|
<aside
|
|
|
|
|
|
id="dtl-panel"
|
|
|
|
|
|
class="text-sm bg-black rounded-2xl"
|
2025-01-27 15:51:26 +01:00
|
|
|
|
:class="{ 'with-dialog': isDialogOpen }"
|
2025-01-27 11:06:06 +01:00
|
|
|
|
aria-labelledby="dtl-label"
|
|
|
|
|
|
@click="preventClose($event)"
|
|
|
|
|
|
>
|
|
|
|
|
|
<header
|
|
|
|
|
|
class="flex items-center | border-b pl-32 pr-16 py-8"
|
|
|
|
|
|
data-icon="leaf"
|
|
|
|
|
|
style="--column-gap: 0.5rem"
|
2025-01-27 15:51:26 +01:00
|
|
|
|
>
|
|
|
|
|
|
<h2 id="dtl-label" class="font-serif text-md">
|
|
|
|
|
|
{{
|
2025-01-27 18:33:56 +01:00
|
|
|
|
proposals.length === 1 && isDialogOpen
|
2025-01-27 15:51:26 +01:00
|
|
|
|
? activeProposal.title
|
|
|
|
|
|
? activeProposal.title
|
2025-02-05 11:22:09 +01:00
|
|
|
|
: 'Design to light'
|
|
|
|
|
|
: 'Design to light'
|
2025-01-27 15:51:26 +01:00
|
|
|
|
}}
|
|
|
|
|
|
</h2>
|
2025-01-27 11:06:06 +01:00
|
|
|
|
<button
|
2025-01-27 11:22:57 +01:00
|
|
|
|
v-if="!isDialogOpen"
|
2025-01-27 11:06:06 +01:00
|
|
|
|
@click="emits('close')"
|
|
|
|
|
|
class="btn btn--icon btn--transparent | ml-auto"
|
|
|
|
|
|
data-icon="close"
|
|
|
|
|
|
>
|
2025-01-23 18:46:38 +01:00
|
|
|
|
<span class="sr-only">Fermer</span>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</header>
|
2025-01-27 15:51:26 +01:00
|
|
|
|
<nav v-if="!isDialogOpen" class="tabs" role="tablist" tabindex="-1">
|
2025-01-27 11:06:06 +01:00
|
|
|
|
<button
|
2025-01-23 18:46:38 +01:00
|
|
|
|
v-for="(proposal, index) in proposals"
|
|
|
|
|
|
@click="activeProposal = proposal"
|
|
|
|
|
|
role="tab"
|
2025-01-27 18:50:13 +01:00
|
|
|
|
:aria-selected="activeProposal === proposal"
|
2025-01-23 18:46:38 +01:00
|
|
|
|
aria-controls=""
|
|
|
|
|
|
>
|
2025-01-27 15:51:26 +01:00
|
|
|
|
{{
|
2025-01-27 18:46:18 +01:00
|
|
|
|
proposal.title
|
|
|
|
|
|
? proposal.title
|
2025-01-27 15:51:26 +01:00
|
|
|
|
: index === 0
|
2025-02-05 11:22:09 +01:00
|
|
|
|
? 'Proposition initiale'
|
|
|
|
|
|
: 'Alternative ' + index
|
2025-01-27 15:51:26 +01:00
|
|
|
|
}}
|
2025-01-23 18:46:38 +01:00
|
|
|
|
</button>
|
|
|
|
|
|
</nav>
|
|
|
|
|
|
<section class="overflow-y" tabindex="-1">
|
2025-01-27 11:06:06 +01:00
|
|
|
|
<div
|
2025-01-27 18:33:56 +01:00
|
|
|
|
v-if="!isDialogOpen"
|
2025-01-27 11:06:06 +01:00
|
|
|
|
id="proposition"
|
2025-01-27 18:37:04 +01:00
|
|
|
|
class="flex relative | bg-white-05 text-grey-200 px-32 py-16"
|
2025-01-27 11:06:06 +01:00
|
|
|
|
style="--column-gap: 1rem"
|
|
|
|
|
|
>
|
2025-01-23 18:46:38 +01:00
|
|
|
|
<h3 class="sr-only">Proposition</h3>
|
2025-01-27 18:37:04 +01:00
|
|
|
|
<router-link class="link-full" :to="activeProposal.path">
|
|
|
|
|
|
<img
|
|
|
|
|
|
v-if="activeProposal.thumb"
|
|
|
|
|
|
:src="activeProposal.thumb"
|
|
|
|
|
|
alt=""
|
|
|
|
|
|
width="72"
|
|
|
|
|
|
height="72"
|
|
|
|
|
|
loading="lazy"
|
|
|
|
|
|
class="bg-white rounded-sm"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</router-link>
|
2025-01-27 11:06:06 +01:00
|
|
|
|
<p>
|
|
|
|
|
|
Données basées sur la proposition <br />du {{ activeProposal.date }}
|
|
|
|
|
|
<br />{{ activeProposal.stepLabel }}
|
|
|
|
|
|
</p>
|
2025-01-23 18:46:38 +01:00
|
|
|
|
</div>
|
|
|
|
|
|
<div id="note-globale" class="px-32 py-16 border-b flow">
|
|
|
|
|
|
<h3>Note globale</h3>
|
2025-01-27 11:06:06 +01:00
|
|
|
|
<div class="flex" style="--column-gap: 1rem">
|
|
|
|
|
|
<p :data-grade="activeProposal.grades.global.letter">
|
|
|
|
|
|
<strong class="sr-only">{{
|
|
|
|
|
|
activeProposal.grades.global.letter
|
|
|
|
|
|
}}</strong>
|
|
|
|
|
|
</p>
|
2025-01-23 18:46:38 +01:00
|
|
|
|
<div class="flex-1">
|
2025-01-27 11:06:06 +01:00
|
|
|
|
<p>
|
|
|
|
|
|
<strong class="text-md font-medium">{{
|
|
|
|
|
|
activeProposal.grades.global.mention
|
|
|
|
|
|
}}</strong>
|
|
|
|
|
|
<span class="text-white-50 ml-8"
|
|
|
|
|
|
>{{ activeProposal.grades.global.number }}/10</span
|
|
|
|
|
|
>
|
|
|
|
|
|
</p>
|
|
|
|
|
|
<input
|
|
|
|
|
|
type="range"
|
|
|
|
|
|
min="0"
|
|
|
|
|
|
max="10"
|
|
|
|
|
|
:value="activeProposal.grades.global.number"
|
|
|
|
|
|
disabled
|
|
|
|
|
|
/>
|
2025-01-23 18:46:38 +01:00
|
|
|
|
<p>{{ activeProposal.grades.global.comment }}</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div id="positionnement" class="px-32 py-16 border-b flow">
|
|
|
|
|
|
<h3>Positionnement</h3>
|
|
|
|
|
|
<dl>
|
|
|
|
|
|
<dt id="design">Design</dt>
|
2025-01-27 11:06:06 +01:00
|
|
|
|
<dd>
|
|
|
|
|
|
<span class="sr-only">{{
|
|
|
|
|
|
activeProposal.grades.position.complexity
|
|
|
|
|
|
}}</span>
|
|
|
|
|
|
</dd>
|
2025-01-23 18:46:38 +01:00
|
|
|
|
<dt id="poids">Poids</dt>
|
2025-01-27 11:06:06 +01:00
|
|
|
|
<dd>
|
|
|
|
|
|
<span class="sr-only">{{
|
|
|
|
|
|
activeProposal.grades.position.weight
|
|
|
|
|
|
}}</span>
|
|
|
|
|
|
</dd>
|
2025-01-23 18:46:38 +01:00
|
|
|
|
</dl>
|
2025-01-27 11:06:06 +01:00
|
|
|
|
<button
|
2025-01-23 18:46:38 +01:00
|
|
|
|
class="dot"
|
|
|
|
|
|
v-for="(proposal, index) in proposals"
|
|
|
|
|
|
@click="activeProposal = proposal"
|
2025-01-27 19:49:07 +01:00
|
|
|
|
:aria-selected="activeProposal === proposal"
|
2025-01-27 11:06:06 +01:00
|
|
|
|
:style="
|
|
|
|
|
|
'--x:' +
|
2025-01-27 19:49:07 +01:00
|
|
|
|
proposal.grades.position.complexity +
|
2025-01-27 11:06:06 +01:00
|
|
|
|
';--y:' +
|
2025-01-27 19:49:07 +01:00
|
|
|
|
proposal.grades.position.weight
|
2025-01-27 11:06:06 +01:00
|
|
|
|
"
|
2025-01-27 19:49:07 +01:00
|
|
|
|
:title="proposal.title"
|
2025-01-23 18:46:38 +01:00
|
|
|
|
>
|
2025-01-27 19:49:07 +01:00
|
|
|
|
<span class="sr-only">{{ proposal.title }}</span>
|
2025-01-23 12:23:14 +01:00
|
|
|
|
</button>
|
2025-01-23 18:46:38 +01:00
|
|
|
|
</div>
|
|
|
|
|
|
<div id="indicateur" class="px-32 py-16 border-b flow">
|
|
|
|
|
|
<h3>Indicateur des composants impliqués</h3>
|
|
|
|
|
|
<div class="grid">
|
|
|
|
|
|
<template
|
|
|
|
|
|
v-for="indicator in activeProposal.grades.indicators"
|
2025-01-27 18:50:13 +01:00
|
|
|
|
:key="indicator.id"
|
2025-01-23 18:46:38 +01:00
|
|
|
|
>
|
2025-01-27 11:06:06 +01:00
|
|
|
|
<div
|
|
|
|
|
|
class="gauge"
|
|
|
|
|
|
:data-value="
|
|
|
|
|
|
indicator.value < 0 ? indicator.value : '+' + indicator.value
|
|
|
|
|
|
"
|
|
|
|
|
|
>
|
|
|
|
|
|
<label
|
|
|
|
|
|
:for="indicator.id"
|
|
|
|
|
|
:style="'--value:' + indicator.value"
|
|
|
|
|
|
>{{ indicator.label }}</label
|
|
|
|
|
|
>
|
|
|
|
|
|
<input
|
|
|
|
|
|
:id="indicator.id"
|
|
|
|
|
|
type="range"
|
|
|
|
|
|
min="-5"
|
|
|
|
|
|
max="5"
|
|
|
|
|
|
orient="vertical"
|
|
|
|
|
|
:value="indicator.value"
|
|
|
|
|
|
disabled
|
|
|
|
|
|
/>
|
2025-01-23 18:46:38 +01:00
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2025-01-27 22:30:24 +01:00
|
|
|
|
<footer v-if="proposals.length === 1 && !isDialogOpen" class="p-16">
|
2025-01-27 14:39:52 +01:00
|
|
|
|
<button
|
2025-02-05 11:22:09 +01:00
|
|
|
|
:disabled="page.hasOptimizationRequest ? '' : undefined"
|
2025-01-27 14:39:52 +01:00
|
|
|
|
class="btn btn--white w-full"
|
2025-01-27 20:44:11 +01:00
|
|
|
|
@click="handleOptimizationButtonClick"
|
2025-01-27 14:39:52 +01:00
|
|
|
|
>
|
2025-02-05 11:22:09 +01:00
|
|
|
|
{{
|
|
|
|
|
|
page.hasOptimizationRequest
|
|
|
|
|
|
? "Demande d'expertise en cours de traitement…"
|
|
|
|
|
|
: 'Demander une expertise d’optimisation'
|
|
|
|
|
|
}}
|
2025-01-27 11:06:06 +01:00
|
|
|
|
</button>
|
2025-01-23 18:46:38 +01:00
|
|
|
|
</footer>
|
|
|
|
|
|
</section>
|
2025-01-22 13:25:34 +01:00
|
|
|
|
</aside>
|
2025-01-27 20:44:11 +01:00
|
|
|
|
<OptimizationRequestDialog
|
|
|
|
|
|
v-if="isOptimizationDialogOpen"
|
|
|
|
|
|
@close="isOptimizationDialogOpen = false"
|
|
|
|
|
|
/>
|
2025-01-22 13:25:34 +01:00
|
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
2025-02-05 11:22:09 +01:00
|
|
|
|
import OptimizationRequestDialog from './OptimizationRequestDialog.vue';
|
|
|
|
|
|
import dayjs from 'dayjs';
|
|
|
|
|
|
import 'dayjs/locale/fr';
|
|
|
|
|
|
import { storeToRefs } from 'pinia';
|
|
|
|
|
|
import { ref, onBeforeUnmount, computed } from 'vue';
|
|
|
|
|
|
import { useDialogStore } from '../../stores/dialog';
|
|
|
|
|
|
import { usePageStore } from '../../stores/page';
|
2025-01-22 13:25:34 +01:00
|
|
|
|
|
2025-01-27 11:06:06 +01:00
|
|
|
|
const { proposals } = defineProps({
|
|
|
|
|
|
proposals: Array,
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2025-02-05 11:22:09 +01:00
|
|
|
|
const { page } = storeToRefs(usePageStore());
|
2025-01-27 11:22:57 +01:00
|
|
|
|
const { openedFile } = storeToRefs(useDialogStore());
|
2025-01-22 13:25:34 +01:00
|
|
|
|
|
2025-01-27 11:22:57 +01:00
|
|
|
|
const isDialogOpen = computed(() => {
|
2025-01-27 15:29:03 +01:00
|
|
|
|
if (openedFile.value) {
|
|
|
|
|
|
return true;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2025-01-27 11:22:57 +01:00
|
|
|
|
});
|
|
|
|
|
|
|
2025-01-27 14:39:52 +01:00
|
|
|
|
const isOptimizationDialogOpen = ref(false);
|
|
|
|
|
|
|
2025-02-05 11:22:09 +01:00
|
|
|
|
dayjs.locale('fr');
|
2025-01-22 13:25:34 +01:00
|
|
|
|
|
2025-02-05 11:22:09 +01:00
|
|
|
|
const emits = defineEmits(['close']);
|
2025-01-23 12:23:14 +01:00
|
|
|
|
|
|
|
|
|
|
proposals[0].isActive = true;
|
|
|
|
|
|
|
|
|
|
|
|
const activeProposal = ref(proposals[0]);
|
|
|
|
|
|
|
2025-02-05 11:22:09 +01:00
|
|
|
|
window.addEventListener('keyup', closeOnEscape);
|
|
|
|
|
|
window.addEventListener('click', close);
|
2025-01-23 12:23:14 +01:00
|
|
|
|
|
2025-01-27 15:29:30 +01:00
|
|
|
|
onBeforeUnmount(() => {
|
2025-02-05 11:22:09 +01:00
|
|
|
|
window.removeEventListener('keyup', closeOnEscape);
|
|
|
|
|
|
window.removeEventListener('click', close);
|
2025-01-27 15:29:30 +01:00
|
|
|
|
});
|
2025-01-23 12:23:14 +01:00
|
|
|
|
|
|
|
|
|
|
// Functions
|
|
|
|
|
|
function closeOnEscape(event) {
|
2025-02-05 11:22:09 +01:00
|
|
|
|
if (event.key === 'Escape') emits('close');
|
2025-01-23 12:23:14 +01:00
|
|
|
|
}
|
2025-01-23 13:50:24 +01:00
|
|
|
|
|
|
|
|
|
|
function close() {
|
2025-02-05 11:22:09 +01:00
|
|
|
|
emits('close');
|
2025-01-23 13:50:24 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function preventClose(event) {
|
|
|
|
|
|
event.stopImmediatePropagation();
|
|
|
|
|
|
}
|
2025-01-27 20:44:11 +01:00
|
|
|
|
|
|
|
|
|
|
function handleOptimizationButtonClick() {
|
|
|
|
|
|
isOptimizationDialogOpen.value = true;
|
|
|
|
|
|
}
|
2025-01-22 13:25:34 +01:00
|
|
|
|
</script>
|