kanban > steps : add dtl indicator

This commit is contained in:
isUnknown 2025-01-23 17:39:40 +01:00
parent 7038185e7f
commit 30fbc0e4e8
9 changed files with 222 additions and 156 deletions

View file

@ -0,0 +1,11 @@
title: Client
description: Ne peut pas accéder au Panel, peut accéder aux Projets auxquels il est assigné côté front.
permissions:
access:
panel: false
fields:
projects:
label: Projets
type: pages
query: page('projects').children

View file

@ -0,0 +1,21 @@
title: Interne Pochet
description: Peux accéder au Panel mais pas aux Utilisateurs, peut accéder aux Projets auxquels il est assigné par un Admin.
home: /panel/pages/projects
permissions:
access:
users: false
fields:
job:
label: Métier
type: select
options:
- Project Manager
- Sales Manager
default: Project Panager
width: 1/4
projects:
label: Projets
type: pages
query: page('projects').children
width: 3/4

View file

@ -36,4 +36,151 @@ function getFileData($file) {
}
return $data;
}
function getGlobalEvaluation($numberedGrade) {
$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" => "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) {
if (isset($proposalFile) && $proposalFile->cover()->isNotEmpty()) {
$DTLProposal["thumb"] = $proposalFile->cover()->toFile()->thumb([
"width" => 200,
"format" => "webp"
])->url();
}
if ($proposalPage->views()->isNotEmpty()) {
$DTLProposal["thumb"] = $proposalPage->views()->toFile()->thumb([
"width" => 200,
"format" => "webp"
])->url();
}
$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;
}

View file

@ -1,152 +1,5 @@
<?php
function getGlobalEvaluation($numberedGrade) {
$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" => "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) {
if (isset($proposalFile) && $proposalFile->cover()->isNotEmpty()) {
$DTLProposal["thumb"] = $proposalFile->cover()->toFile()->thumb([
"width" => 200,
"format" => "webp"
])->url();
}
if ($proposalPage->views()->isNotEmpty()) {
$DTLProposal["thumb"] = $proposalPage->views()->toFile()->thumb([
"width" => 200,
"format" => "webp"
])->url();
}
$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(),

View file

@ -1,6 +1,6 @@
<?php
function getProjectData($project) {
return [
$data = [
"title" => $project->title()->value(),
"url" => $project->url(),
"uri" => "/" . $project->uri(),
@ -12,7 +12,14 @@ function getProjectData($project) {
"notifications" => Yaml::decode($project->notifications()->value),
"uuid" => (string) $project->uuid(),
"slug" => (string) $project->slug(),
"isDTLEnabled" => (bool) $project->isDTLEnabled()->value() == "true"
];
if ($project->isDTLEnabled()) {
$data["designToLight"] = processDTLProposals($project);
}
return $data;
}
try {

View file

@ -1,19 +1,22 @@
<template>
<article class="project-item | flex | rounded-2xl | px-32 py-32">
<article
class="project-item | flex | rounded-2xl | px-32 py-32"
:data-dtl="project.isDTLEnabled ? 'true' : undefined"
>
<hgroup>
<h3>
<router-link
:to="isEmptyBrief(project) ? project.uri + '/client-brief' : project.uri"
:to="
isEmptyBrief(project) ? project.uri + '/client-brief' : project.uri
"
class="link-full"
>
{{ project.title }}
{{ project.title }}
</router-link>
</h3>
<p>
Dernière mise à jour le
<time :datetime="project.modified">{{
frenchFormattedModified
}}</time>
<time :datetime="project.modified">{{ frenchFormattedModified }}</time>
</p>
</hgroup>
<img :src="project.logo" alt="Logo" class="project-logo | rounded-sm" />

View file

@ -31,12 +31,14 @@
}}
</router-link>
</footer>
<div v-if="isDesignToLightStep(step)">Design to light</div>
</article>
</template>
<script setup>
import { useRoute } from "vue-router";
import DateTime from "./DateTime.vue";
import { computed } from "vue";
import { useDesignToLightStore } from "../../../stores/designToLight";
const { step, pdf, index } = defineProps({
step: Object,
@ -48,6 +50,8 @@ const { step, pdf, index } = defineProps({
},
});
const { isDesignToLightStep } = useDesignToLightStore();
const route = useRoute();
const uri = computed(() => {

View file

@ -24,16 +24,18 @@
images[0].comments.length > 1 ? "s" : ""
}}
</footer> -->
<div v-if="isDesignToLightStep(step)">Design to light</div>
</article>
</template>
<script setup>
import DateTime from "./DateTime.vue";
import { usePageStore } from "../../../stores/page";
import { useDesignToLightStore } from "../../../stores/designToLight";
const { images, step, uri } = defineProps({
images: Array,
step: Object,
uri: String,
});
const { page } = usePageStore();
const { isDesignToLightStep } = useDesignToLightStore();
</script>

View file

@ -0,0 +1,18 @@
import { defineStore, storeToRefs } from "pinia";
import { usePageStore } from "./page";
export const useDesignToLightStore = defineStore("design-to-light", () => {
const { page } = storeToRefs(usePageStore());
function isDesignToLightStep(step) {
const isDTLEnabled = page.value.designToLight;
return (
isDTLEnabled &&
page.value.designToLight.some((proposal) =>
proposal.path.includes(step.uri)
)
);
}
return { isDesignToLightStep };
});