This commit is contained in:
isUnknown 2025-01-23 12:23:14 +01:00
parent 0923c9ec01
commit 28804ceba1
7 changed files with 267 additions and 181 deletions

View file

@ -28,6 +28,7 @@ tabs:
label: PDF
type: files
template: pdf
upload: pdf
multiple: false
description:
type: textarea

View file

@ -2,18 +2,34 @@ designToLight:
label: Design to light
icon: leaf
columns:
- width: 2/10
fields:
isDTLEnabled:
label: Actif
type: toggle
default: false
- width: 8/10
fields:
isDTLEnabled:
label: Actif
type: toggle
default: false
width: 2/10
dtlProposals:
label: Propositions
type: structure
when:
isDTLEnabled: true
help: |
**La première proposition correspond au projet initial. Les propositions suivantes constituent des alternatives.**
Pour déplacer une proposition, survolez son index puis cliquez-glissez la poignée ⁝⁝
width: 8/10
columns:
DTLProposalLocation:
label: Localisation
width: 1/2
DTLGrade:
label: Note globale
width: 1/2
after: / 10
fields:
DTLTargetHeadline:
type: headline
label: La proposition Design to light
label: La proposition
DTLProposalLocation:
label: Localisation
@ -24,8 +40,6 @@ columns:
industrialIdeation: Idéation industrielle
virtualSampleDynamicTrack: Échantillon virtuel - piste dynamique
virtualSampleStaticTrack: Échantillon virtuel - piste statique
when:
isDTLEnabled: true
width: 1/2
DTLproposal:
@ -76,10 +90,38 @@ columns:
type: range
min: 0
max: 10
default: 5
tooltip:
after: / 10
when:
isDTLEnabled: true
positionHeadline:
type: headline
label: Positionnement
DTLComplexityGrade:
label: Complexité
type: range
before: Complexe
min: -5
max: 5
after: Sobre
default: 0
help: Axe horizontal (X) du graph
width: 1/2
DTLWeightGrade:
label: Poids
type: range
before: Lourd
min: -5
max: 5
after: Léger
default: 0
help: Axe vertical (Y) du graph
width: 1/2
indicatorsHeadline:
type: headline
label: Indicateurs
DTLDesignGrade:
label: Design global

View file

@ -1,6 +1,7 @@
<?php
function getFileData($file) {
if (!$file) return null;
$data = [
'modified' => $file->modified('YYYY-MM-dd'),
'url' => $file->thumb([

View file

@ -1,160 +1,154 @@
<?php
function getGlobalEvaluation($numberedGrade) {
if ($numberedGrade >= 0 && $numberedGrade < 3) {
return [
"letter" => "D",
$gradeMapping = [
[0, 3, "D", "Assez lourd", "Allègement du flacon recommandé"],
[3, 6, "C", "Assez lourd", "Allègement du flacon recommandé"],
[6, 8, "B", "Assez lourd", "Allègement du flacon recommandé"],
[8, 10, "A", "Léger", "Conception optimisée"],
];
foreach ($gradeMapping as [$min, $max, $letter, $mention, $comment]) {
if ($numberedGrade >= $min && $numberedGrade < $max) {
return [
"letter" => $letter,
"number" => $numberedGrade,
"mention" => $mention,
"comment" => $comment,
];
}
}
return [
"letter" => "",
"number" => $numberedGrade,
"mention" => "Assez lourd",
"comment" => "Allègement du flacon recommandé"
];
}
if ($numberedGrade >= 3 && $numberedGrade < 6) {
return [
"letter" => "C",
"number" => $numberedGrade,
"mention" => "Assez lourd",
"comment" => "Allègement du flacon recommandé"
];
}
if ($numberedGrade >= 6 && $numberedGrade < 8) {
return [
"letter" => "B",
"number" => $numberedGrade,
"mention" => "Assez lourd",
"comment" => "Allègement du flacon recommandé"
];
}
if ($numberedGrade >= 8 && $numberedGrade <= 10) {
return [
"letter" => "A",
"number" => $numberedGrade,
"mention" => "Assez lourd",
"comment" => "Allègement du flacon recommandé"
];
}
return [
"letter" => "",
"number" => $numberedGrade,
"mention" => "Assez lourd",
"comment" => "Allègement du flacon recommandé"
];
"mention" => "Non défini",
"comment" => "Pas d'évaluation disponible",
];
}
function processDTLProposals($page) {
$proposals = [];
foreach ($page->dtlProposals()->toStructure() as $proposal) {
$location = $proposal->DTLProposalLocation()->value();
$DTLProposal = null;
switch ($location) {
case 'proposal':
$proposalPage = $page->find('proposal');
$proposalFile = $proposal->DTLproposal()->toFile();
if ($proposalPage && $proposalFile) {
$index = $proposalPage->pdf()->toFiles()->indexOf($proposalFile);
$DTLProposal = [
"location" => "proposal",
"path" => "/projects/" . $page->slug() . "?dialog=proposal&fileIndex=" . $index,
"date" => $proposalFile->modified("d/MM/Y"),
"stepLabel" => "Proposition commerciale",
];
}
break;
case 'industrialIdeation':
$proposalPage = $page->find('industrial-ideation');
$proposalFile = $proposal->DTLindustrialIdeation()->toFile();
if ($proposalPage && $proposalFile) {
$DTLProposal = [
"location" => "industrialIdeation",
"path" => "/projects/" . $page->slug() . "?dialog=industrial-ideation",
"date" => $proposalFile->modified("d/MM/Y"),
"stepLabel" => "Idéation industrielle",
];
}
break;
case 'virtualSampleDynamicTrack':
$proposalPage = $proposal->DTLVirtualSampleDynamicTrack()->toPage();
if ($proposalPage) {
$DTLProposal = [
"location" => "virtualSampleDynamicTrack",
"path" => "/projects/" . $page->slug() . "?dialog=virtual-sample",
"date" => $proposalPage->modified("d/MM/Y"),
"stepLabel" => "Échantillon virtuel - piste dynamique",
];
}
break;
case 'virtualSampleStaticTrack':
$proposalPage = $page->find('virtual-sample');
$proposalFile = $proposal->DTLVirtualSampleStaticTrack()->toFile();
if ($proposalPage && $proposalFile) {
$DTLProposal = [
"location" => "virtualSampleStaticTrack",
"path" => "/projects/" . $page->slug() . "?dialog=virtual-sample",
"date" => $proposalFile->modified("d/MM/Y"),
"stepLabel" => "Échantillon virtuel - piste statique",
];
}
break;
}
if ($DTLProposal) {
$numberedGlobalGrade = (int) $proposal->DTLGrade()->value() ?? 0;
$DTLProposal["grades"] = [
"global" => getGlobalEvaluation($numberedGlobalGrade),
"position" => [
"complexity" => (int) $proposal->DTLComplexityGrade()->value() ?? 0,
"weight" => (int) $proposal->DTLWeightGrade()->value() ?? 0,
],
"indicators" => [
[
"label" => "design",
"value" => (int) $proposal->DTLDesignGrade()->value() ?? 0,
],
[
"label" => "ring",
"value" => (int) $proposal->DTLRingGrade()->value() ?? 0,
],
[
"label" => "shoulder",
"value" => (int) $proposal->DTLShoulderGrade()->value() ?? 0,
],
[
"label" => "skeleton",
"value" => (int) $proposal->DTLSkeletonGrade()->value() ?? 0,
],
[
"label" => "foot",
"value" => (int) $proposal->DTLFootGrade()->value() ?? 0,
],
[
"label" => "bottom",
"value" => (int) $proposal->DTLBottomGrade()->value() ?? 0,
],
],
];
$proposals[] = $DTLProposal;
}
}
return $proposals;
}
$project = [
"title" => $page->title()->value(),
"url" => $page->url(),
"modified" => $page->modified("Y-MM-d"),
"status" => $page->status(),
"logo" => $page->client()->isNotEmpty() && $page->client()->toPage() ? $page->client()->toPage()->logo()->toFile()->url() : null,
"steps" => $page->getSteps(),
"designToLight" => null
"title" => $page->title()->value(),
"url" => $page->url(),
"modified" => $page->modified("Y-MM-d"),
"status" => $page->status(),
"logo" => $page->client()->isNotEmpty() && $page->client()->toPage()
? $page->client()->toPage()->logo()->toFile()->url()
: null,
"steps" => $page->getSteps(),
"designToLight" => $page->isDTLEnabled() ? processDTLProposals($page) : null,
];
if ($page->isDTLEnabled()) {
$DTLProposal = null;
$proposalLocation = $page->DTLProposalLocation()->value();
switch ($proposalLocation) {
case 'proposal':
$proposalPage = $page->find('proposal');
$proposalFile = $page->DTLProposal()->toFile();
if ($proposalPage && $proposalFile) {
$index = $proposalPage->pdf()->toFiles()->indexOf($proposalFile);
$DTLProposal = [
"location" => "proposal",
"path" => "/projects/" . $page->slug() . "?dialog=proposal&fileIndex=" . $index,
"date" => $proposalFile->modified("Y-MM-d"),
"stepLabel" => "Proposition commerciale",
];
}
break;
case 'industrialIdeation':
$proposalPage = $page->find('industrial-ideation');
$proposalFile = $page->DTLindustrialIdeation()->toFile();
if ($proposalPage && $proposalFile) {
$index = $proposalPage->pdf()->toFiles()->indexOf($proposalFile);
$DTLProposal = [
"location" => "proposal",
"path" => "/projects/" . $page->slug() . "?dialog=industrial-ideation&fileIndex=" . $index,
"date" => $proposalFile->modified("Y-MM-d"),
"stepLabel" => "Idéation industrielle"
];
}
break;
case 'virtualSampleDynamicTrack':
$proposalPage = $page->DTLVirtualSampleDynamicTrack()->toPage();
if ($proposalPage) {
$DTLProposal = [
"location" => "proposal",
"path" => "/projects/" . $page->slug() . "?dialog=virtual-sample",
"date" => $proposalPage->modified("Y-MM-d"),
"stepLabel" => "Échantillon virtuel"
];
}
break;
case 'virtualSampleStaticTrack':
$proposalPage = $page->find('virtual-sample');
$proposalFile = $page->DTLVirtualSampleStaticTrack()->toFile();
if ($proposalPage && $proposalFile) {
$DTLProposal = [
"location" => "proposal",
"path" => "/projects/" . $page->slug() . "?dialog=virtual-sample",
"date" => $proposalFile->modified("Y-MM-d"),
"stepLabel" => "Échantillon virtuel"
];
}
break;
}
if ($page->DTLGrade()->isNotEmpty()) {
$numberedGlobalGrade = (int) $page->DTLGrade()->value() ?? 0;
$DTLProposal["grades"] = [
"global" => getGlobalEvaluation($numberedGlobalGrade),
"indicators" => [
[
"label" => "design",
"value" => (int) $page->DTLDesignGrade()->value() ?? 0,
],
[
"label" => "ring",
"value" => (int) $page->DTLRingGrade()->value() ?? 0,
],
[
"label" => "shoulder",
"value" => (int) $page->DTLShoulderGrade()->value() ?? 0,
],
[
"label" => "skeleton",
"value" => (int) $page->DTLSkeletonGrade()->value() ?? 0,
],
[
"label" => "foot",
"value" => (int) $page->DTLFootGrade()->value() ?? 0,
],
[
"label" => "bottom",
"value" => (int) $page->DTLBottomGrade()->value() ?? 0,
]
],
];
}
$project["designToLight"] = $DTLProposal;
}
$pageData = array_merge($genericData, $project);
echo json_encode([
"page" => $pageData,
"user" => $userData
]);
"page" => $pageData,
"user" => $userData,
]);

View file

@ -4,8 +4,11 @@
<Menu />
<RouterView />
</div>
<DTLPanel v-if="isDTLPanelOpen" />
<DTLButton @click="isDTLPanelOpen = !isDTLPanelOpen" />
<DTLPanel v-if="isDTLPanelOpen" @close="isDTLPanelOpen = false" />
<DTLButton
v-if="page?.designToLight?.length > 0"
@click="isDTLPanelOpen = !isDTLPanelOpen"
/>
</template>
<script setup>

View file

@ -1,11 +1,31 @@
<template>
<button v-if="page?.designToLight?.grades?.global">
{{ page.designToLight.grades.global.letter }}
</button>
<button :data-new="hasAlternatives ? true : undefined">{{ content }}</button>
</template>
<script setup>
import { storeToRefs } from "pinia";
import { usePageStore } from "../../stores/page";
import { computed } from "vue";
const { page } = storeToRefs(usePageStore());
const hasAlternatives = computed(() => {
return page.value.designToLight.length > 1;
});
const content = computed(() => {
if (hasAlternatives.value) return "new";
return page.value.designToLight[0].grades.global.letter;
});
</script>
<style scoped>
button {
position: fixed;
min-width: 4rem;
min-height: 2rem;
right: 2rem;
bottom: 2rem;
background-color: #000;
color: #fff;
}
</style>

View file

@ -1,23 +1,29 @@
<template>
<aside>
<p>Données basées sur la proposition du {{ frenchFormattedModified }}</p>
<p>{{ page.designToLight.stepLabel }}</p>
<button @click="emits('close')">X</button>
<ul class="tabs">
<li v-for="(proposal, index) in proposals">
<button @click="activeProposal = proposal">
{{ index === 0 ? "Proposition initiale" : "Alternative " + index }}
</button>
</li>
</ul>
<p>Données basées sur la proposition du {{ activeProposal.date }}</p>
<p>{{ activeProposal.stepLabel }}</p>
<h4>Note globale</h4>
<p>{{ page.designToLight.grades.global.letter }}</p>
<p>{{ page.designToLight.grades.global.mention }}</p>
<input
type="range"
:value="page.designToLight.grades.global.number"
disabled
/>
<p>{{ page.designToLight.grades.global.comment }}</p>
<p>{{ activeProposal.grades.global.letter }}</p>
<p>{{ activeProposal.grades.global.mention }}</p>
<input type="range" :value="activeProposal.grades.global.number" disabled />
<p>{{ activeProposal.grades.global.comment }}</p>
<h4>Positionnement</h4>
{{ activeProposal.grades.position.complexity }}
{{ activeProposal.grades.position.weight }}
<h4>Indicateur des composants impliqués</h4>
<template
v-for="indicator in page.designToLight.grades.indicators"
v-for="indicator in activeProposal.grades.indicators"
:key="indicator.value"
>
<label for="">{{ indicator.label }}</label>
@ -33,15 +39,30 @@ import { storeToRefs } from "pinia";
import { usePageStore } from "../../stores/page";
import dayjs from "dayjs";
import "dayjs/locale/fr";
import { computed } from "vue";
import { ref, onBeforeUnmount } from "vue";
dayjs.locale("fr");
const { page } = storeToRefs(usePageStore());
const frenchFormattedModified = dayjs(page.value.designToLight.date).format(
"D/MM/YYYY"
);
const emits = defineEmits(["close"]);
const proposals = page.value.designToLight;
proposals[0].isActive = true;
const activeProposal = ref(proposals[0]);
window.addEventListener("keyup", closeOnEscape);
onBeforeUnmount(() => {
window.removeEventListener("keyup", closeOnEscape);
});
// Functions
function closeOnEscape(event) {
if (event.key === "Escape") emits("close");
}
</script>
<style scoped>
@ -56,4 +77,8 @@ aside {
background-color: #191919;
color: #fff;
}
button {
color: #fff;
}
</style>