From 7d80795ae36ccaf10ddbf585803a7ff64c37827b Mon Sep 17 00:00:00 2001 From: Matteo Date: Thu, 19 Feb 2026 16:23:58 +0100 Subject: [PATCH 01/10] feat : plan du site (WIP) --- frontend/pages/index.vue | 4 +- frontend/pages/infrastructure/batiment.vue | 199 ++++++++++++++++++ frontend/pages/infrastructure/case.vue | 6 + frontend/services/dto/building-case-data.ts | 6 + .../dto/building-case-position-data.ts | 11 + frontend/services/dto/building-data.ts | 3 + frontend/services/dto/building-layout-data.ts | 9 + migrations/Version20260219100826.php | 47 +++++ src/Entity/Building.php | 56 ++++- src/Entity/BuildingCase.php | 139 ++++++++++++ src/Entity/BuildingCasePosition.php | 146 +++++++++++++ src/Entity/BuildingLayout.php | 141 +++++++++++++ 12 files changed, 764 insertions(+), 3 deletions(-) create mode 100644 frontend/pages/infrastructure/batiment.vue create mode 100644 frontend/pages/infrastructure/case.vue create mode 100644 frontend/services/dto/building-case-data.ts create mode 100644 frontend/services/dto/building-case-position-data.ts create mode 100644 frontend/services/dto/building-layout-data.ts create mode 100644 migrations/Version20260219100826.php create mode 100644 src/Entity/BuildingCase.php create mode 100644 src/Entity/BuildingCasePosition.php create mode 100644 src/Entity/BuildingLayout.php diff --git a/frontend/pages/index.vue b/frontend/pages/index.vue index 4311652..2131d24 100644 --- a/frontend/pages/index.vue +++ b/frontend/pages/index.vue @@ -4,7 +4,7 @@
- + - + diff --git a/frontend/pages/infrastructure/batiment.vue b/frontend/pages/infrastructure/batiment.vue new file mode 100644 index 0000000..8293cdb --- /dev/null +++ b/frontend/pages/infrastructure/batiment.vue @@ -0,0 +1,199 @@ + + + diff --git a/frontend/pages/infrastructure/case.vue b/frontend/pages/infrastructure/case.vue new file mode 100644 index 0000000..28c96c6 --- /dev/null +++ b/frontend/pages/infrastructure/case.vue @@ -0,0 +1,6 @@ + + diff --git a/frontend/services/dto/building-case-data.ts b/frontend/services/dto/building-case-data.ts new file mode 100644 index 0000000..6a59f1f --- /dev/null +++ b/frontend/services/dto/building-case-data.ts @@ -0,0 +1,6 @@ +export interface BuildingCaseData { + id: number + caseNumber: number | null + code: string | null + capacity: number | null +} diff --git a/frontend/services/dto/building-case-position-data.ts b/frontend/services/dto/building-case-position-data.ts new file mode 100644 index 0000000..b1f6e84 --- /dev/null +++ b/frontend/services/dto/building-case-position-data.ts @@ -0,0 +1,11 @@ +import type { BuildingCaseData } from '~/services/dto/building-case-data' + +export interface BuildingCasePositionData { + id: number + x: number | null + y: number | null + w: number | null + h: number | null + renderOrder: string | null + buildingCase: BuildingCaseData | null +} diff --git a/frontend/services/dto/building-data.ts b/frontend/services/dto/building-data.ts index 4993219..60729d4 100644 --- a/frontend/services/dto/building-data.ts +++ b/frontend/services/dto/building-data.ts @@ -1,5 +1,8 @@ +import type { BuildingLayoutData } from '~/services/dto/building-layout-data' + export interface BuildingData { id: number label: string code: string + layouts?: BuildingLayoutData[] | null } diff --git a/frontend/services/dto/building-layout-data.ts b/frontend/services/dto/building-layout-data.ts new file mode 100644 index 0000000..f9a2661 --- /dev/null +++ b/frontend/services/dto/building-layout-data.ts @@ -0,0 +1,9 @@ +import type { BuildingCasePositionData } from '~/services/dto/building-case-position-data' + +export interface BuildingLayoutData { + id: number + name: string | null + columns: number | null + rows: number | null + casePositions?: BuildingCasePositionData[] | null +} diff --git a/migrations/Version20260219100826.php b/migrations/Version20260219100826.php new file mode 100644 index 0000000..7d0be76 --- /dev/null +++ b/migrations/Version20260219100826.php @@ -0,0 +1,47 @@ +addSql('CREATE TABLE building_case (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, case_number INT NOT NULL, code VARCHAR(255) NOT NULL, capacity INT NOT NULL, id_building_id INT DEFAULT NULL, PRIMARY KEY (id))'); + $this->addSql('CREATE INDEX IDX_DE2CEE505538B3E5 ON building_case (id_building_id)'); + $this->addSql('CREATE TABLE building_case_position (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, x INT NOT NULL, y INT NOT NULL, w INT NOT NULL, h INT NOT NULL, render_order VARCHAR(255) NOT NULL, building_layout_id INT NOT NULL, building_case_id INT NOT NULL, PRIMARY KEY (id))'); + $this->addSql('CREATE INDEX IDX_ACCDF9077040AE67 ON building_case_position (building_layout_id)'); + $this->addSql('CREATE INDEX IDX_ACCDF907F8D859DF ON building_case_position (building_case_id)'); + $this->addSql('CREATE TABLE building_layout (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, name VARCHAR(255) NOT NULL, columns INT NOT NULL, rows INT NOT NULL, id_building_id INT NOT NULL, PRIMARY KEY (id))'); + $this->addSql('CREATE INDEX IDX_2A8CB1095538B3E5 ON building_layout (id_building_id)'); + $this->addSql('ALTER TABLE building_case ADD CONSTRAINT FK_DE2CEE505538B3E5 FOREIGN KEY (id_building_id) REFERENCES building (id)'); + $this->addSql('ALTER TABLE building_case_position ADD CONSTRAINT FK_ACCDF9077040AE67 FOREIGN KEY (building_layout_id) REFERENCES building_layout (id) NOT DEFERRABLE'); + $this->addSql('ALTER TABLE building_case_position ADD CONSTRAINT FK_ACCDF907F8D859DF FOREIGN KEY (building_case_id) REFERENCES building_case (id) NOT DEFERRABLE'); + $this->addSql('ALTER TABLE building_layout ADD CONSTRAINT FK_2A8CB1095538B3E5 FOREIGN KEY (id_building_id) REFERENCES building (id) NOT DEFERRABLE'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE building_case DROP CONSTRAINT FK_DE2CEE505538B3E5'); + $this->addSql('ALTER TABLE building_case_position DROP CONSTRAINT FK_ACCDF9077040AE67'); + $this->addSql('ALTER TABLE building_case_position DROP CONSTRAINT FK_ACCDF907F8D859DF'); + $this->addSql('ALTER TABLE building_layout DROP CONSTRAINT FK_2A8CB1095538B3E5'); + $this->addSql('DROP TABLE building_case'); + $this->addSql('DROP TABLE building_case_position'); + $this->addSql('DROP TABLE building_layout'); + } +} diff --git a/src/Entity/Building.php b/src/Entity/Building.php index 92caa14..af68257 100644 --- a/src/Entity/Building.php +++ b/src/Entity/Building.php @@ -11,6 +11,7 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Serializer\Attribute\Groups; +use Symfony\Component\Serializer\Attribute\SerializedName; #[ORM\Entity] #[ORM\Table(name: 'building')] @@ -48,9 +49,25 @@ class Building #[ORM\ManyToMany(targetEntity: Reception::class, mappedBy: 'buildings')] private Collection $receptions; + /** + * @var Collection + */ + #[ORM\OneToMany(targetEntity: BuildingCase::class, mappedBy: 'id_building')] + private Collection $buildingCases; + + /** + * @var Collection + */ + #[ORM\OneToMany(targetEntity: BuildingLayout::class, mappedBy: 'id_building')] + #[Groups(['building:read'])] + #[SerializedName('layouts')] + private Collection $buildingLayout; + public function __construct() { - $this->receptions = new ArrayCollection(); + $this->receptions = new ArrayCollection(); + $this->buildingCases = new ArrayCollection(); + $this->buildingLayout = new ArrayCollection(); } public function getId(): ?int @@ -89,4 +106,41 @@ class Building { return $this->receptions; } + + /** + * @return Collection + */ + public function getBuildingCases(): Collection + { + return $this->buildingCases; + } + + public function addBuildingCase(BuildingCase $buildingCase): static + { + if (!$this->buildingCases->contains($buildingCase)) { + $this->buildingCases->add($buildingCase); + $buildingCase->setIdBuilding($this); + } + + return $this; + } + + public function removeBuildingCase(BuildingCase $buildingCase): static + { + if ($this->buildingCases->removeElement($buildingCase)) { + if ($buildingCase->getIdBuilding() === $this) { + $buildingCase->setIdBuilding(null); + } + } + + return $this; + } + + /** + * @return Collection + */ + public function getBuildingLayout(): Collection + { + return $this->buildingLayout; + } } diff --git a/src/Entity/BuildingCase.php b/src/Entity/BuildingCase.php new file mode 100644 index 0000000..1730324 --- /dev/null +++ b/src/Entity/BuildingCase.php @@ -0,0 +1,139 @@ + + */ + #[ORM\OneToMany(targetEntity: BuildingCasePosition::class, mappedBy: 'buildingCase')] + private Collection $id_case_position; + + #[ORM\ManyToOne(inversedBy: 'buildingCases')] + private ?Building $id_building = null; + + public function __construct() + { + $this->id_case_position = new ArrayCollection(); + } + + public function getId(): ?int + { + return $this->id; + } + + public function setId(int $id): static + { + $this->id = $id; + + return $this; + } + + public function getCaseNumber(): ?int + { + return $this->case_number; + } + + public function setCaseNumber(int $case_number): static + { + $this->case_number = $case_number; + + return $this; + } + + public function getCode(): ?string + { + return $this->code; + } + + public function setCode(string $code): static + { + $this->code = $code; + + return $this; + } + + public function getCapacity(): ?int + { + return $this->capacity; + } + + public function setCapacity(int $capacity): static + { + $this->capacity = $capacity; + + return $this; + } + + /** + * @return Collection + */ + public function getIdCasePosition(): Collection + { + return $this->id_case_position; + } + + public function addIdCasePosition(BuildingCasePosition $idCasePosition): static + { + if (!$this->id_case_position->contains($idCasePosition)) { + $this->id_case_position->add($idCasePosition); + $idCasePosition->setBuildingCase($this); + } + + return $this; + } + + public function removeIdCasePosition(BuildingCasePosition $idCasePosition): static + { + if ($this->id_case_position->removeElement($idCasePosition)) { + // set the owning side to null (unless already changed) + if ($idCasePosition->getBuildingCase() === $this) { + $idCasePosition->setBuildingCase(null); + } + } + + return $this; + } + + public function getIdBuilding(): ?Building + { + return $this->id_building; + } + + public function setIdBuilding(?Building $id_building): static + { + $this->id_building = $id_building; + + return $this; + } +} diff --git a/src/Entity/BuildingCasePosition.php b/src/Entity/BuildingCasePosition.php new file mode 100644 index 0000000..de2196f --- /dev/null +++ b/src/Entity/BuildingCasePosition.php @@ -0,0 +1,146 @@ +id; + } + + public function setId(int $id): static + { + $this->id = $id; + + return $this; + } + + public function getX(): ?int + { + return $this->x; + } + + public function setX(int $x): static + { + $this->x = $x; + + return $this; + } + + public function getY(): ?int + { + return $this->y; + } + + public function setY(int $y): static + { + $this->y = $y; + + return $this; + } + + public function getW(): ?int + { + return $this->w; + } + + public function setW(int $w): static + { + $this->w = $w; + + return $this; + } + + public function getH(): ?int + { + return $this->h; + } + + public function setH(int $h): static + { + $this->h = $h; + + return $this; + } + + public function getRenderOrder(): ?string + { + return $this->render_order; + } + + public function setRenderOrder(string $render_order): static + { + $this->render_order = $render_order; + + return $this; + } + + public function getBuildingLayout(): ?BuildingLayout + { + return $this->buildingLayout; + } + + public function setBuildingLayout(?BuildingLayout $buildingLayout): static + { + $this->buildingLayout = $buildingLayout; + + return $this; + } + + public function getBuildingCase(): ?BuildingCase + { + return $this->buildingCase; + } + + public function setBuildingCase(?BuildingCase $buildingCase): static + { + $this->buildingCase = $buildingCase; + + return $this; + } +} diff --git a/src/Entity/BuildingLayout.php b/src/Entity/BuildingLayout.php new file mode 100644 index 0000000..a019e8a --- /dev/null +++ b/src/Entity/BuildingLayout.php @@ -0,0 +1,141 @@ + + */ + #[ORM\OneToMany(targetEntity: BuildingCasePosition::class, mappedBy: 'buildingLayout')] + #[Groups(['building:read'])] + #[SerializedName('casePositions')] + private Collection $id_case_position; + + public function __construct() + { + $this->id_case_position = new ArrayCollection(); + } + + public function getId(): ?int + { + return $this->id; + } + + public function setId(int $id): static + { + $this->id = $id; + + return $this; + } + + public function getName(): ?string + { + return $this->name; + } + + public function setName(string $name): static + { + $this->name = $name; + + return $this; + } + + public function getColumns(): ?int + { + return $this->columns; + } + + public function setColumns(int $columns): static + { + $this->columns = $columns; + + return $this; + } + + public function getRows(): ?int + { + return $this->rows; + } + + public function setRows(int $rows): static + { + $this->rows = $rows; + + return $this; + } + + public function getIdBuilding(): ?Building + { + return $this->id_building; + } + + public function setIdBuilding(?Building $id_building): static + { + $this->id_building = $id_building; + + return $this; + } + + /** + * @return Collection + */ + public function getIdCasePosition(): Collection + { + return $this->id_case_position; + } + + public function addIdCasePosition(BuildingCasePosition $idCasePosition): static + { + if (!$this->id_case_position->contains($idCasePosition)) { + $this->id_case_position->add($idCasePosition); + $idCasePosition->setBuildingLayout($this); + } + + return $this; + } + + public function removeIdCasePosition(BuildingCasePosition $idCasePosition): static + { + if ($this->id_case_position->removeElement($idCasePosition)) { + // set the owning side to null (unless already changed) + if ($idCasePosition->getBuildingLayout() === $this) { + $idCasePosition->setBuildingLayout(null); + } + } + + return $this; + } +} -- 2.39.5 From 30b065b69f5a670223be29fea8b81af489d4dc37 Mon Sep 17 00:00:00 2001 From: Matteo Date: Fri, 20 Feb 2026 11:32:51 +0100 Subject: [PATCH 02/10] feat : plan du site (WIP) --- frontend/pages/infrastructure/batiment.vue | 143 +++++++++++++----- frontend/services/dto/building-case-data.ts | 3 + .../services/dto/building-case-status-data.ts | 6 + migrations/Version20260220101607.php | 37 +++++ src/Entity/BuildingCase.php | 16 ++ src/Entity/Statut.php | 139 +++++++++++++++++ 6 files changed, 310 insertions(+), 34 deletions(-) create mode 100644 frontend/services/dto/building-case-status-data.ts create mode 100644 migrations/Version20260220101607.php create mode 100644 src/Entity/Statut.php diff --git a/frontend/pages/infrastructure/batiment.vue b/frontend/pages/infrastructure/batiment.vue index 8293cdb..2b1a424 100644 --- a/frontend/pages/infrastructure/batiment.vue +++ b/frontend/pages/infrastructure/batiment.vue @@ -30,21 +30,26 @@
-
+
@@ -63,21 +94,25 @@ import type { BuildingData } from "~/services/dto/building-data" import type { BuildingLayoutData } from "~/services/dto/building-layout-data" import type { BuildingCasePositionData } from "~/services/dto/building-case-position-data" +import type { BuildingCaseStatusData } from "~/services/dto/building-case-status-data" import { getBuildingList } from "~/services/building" +import { getStatutList } from "~/services/statut" definePageMeta({ layout: "default" }) const router = useRouter() const buildingList = ref([]) +const statutLegend = ref([]) const buildingLayouts = computed(() => { return buildingList.value.map((building) => { - const layout = getDisplayLayout(building) + const layout = building.layouts?.[0] ?? null const view = layout ? buildLayoutView(layout) : null return { building, layout, cells: view?.cells ?? [], - columnsTemplate: view?.columnsTemplate + columnsTemplate: view?.columnsTemplate, + gridStyle: view?.gridStyle ?? {} } }) }) @@ -93,35 +128,27 @@ type LayoutCell = { caseId: number | null display: string rawId?: number | string + hasGapLeft: boolean + hasGapRight: boolean + isOuterLeft: boolean + isOuterRight: boolean + caseStatusLabel: string | null + caseStyle?: Record + spanStyle: Record } -const getDisplayLayout = (building: BuildingData): BuildingLayoutData | null => { - const layouts = (building.layouts ?? []).filter(Boolean) as BuildingLayoutData[] - if (layouts.length === 0) return null - return layouts[0] ?? null +const normalizeCaseStatusColor = (value: string | null | undefined): string | null => { + const color = (value ?? "").trim() + return color.length > 0 ? color : null } -const getGridStyle = (layout: BuildingLayoutData, columnsTemplate?: string) => { - const cols = Math.max(0, layout.columns ?? 0) - return { - gridTemplateColumns: columnsTemplate ?? `repeat(${cols}, minmax(0, 1fr))`, - gridAutoRows: "1fr", - rowGap: "18.5px", - columnGap: "0px", - width: "100%" - } -} -const getCellSpanStyle = (cell: LayoutCell) => ({ - gridColumn: `${cell.x} / span ${cell.w}`, - gridRow: `${cell.y} / span ${cell.h}` -}) const buildLayoutView = ( layout: BuildingLayoutData -): { cells: LayoutCell[]; columnsTemplate: string } | null => { +): { cells: LayoutCell[]; columnsTemplate: string; gridStyle: Record } | null => { const totalRows = layout.rows ?? 0 const totalCols = layout.columns ?? 0 if (totalRows <= 0 || totalCols <= 0) return null const positions = (layout.casePositions ?? []).filter(Boolean) as BuildingCasePositionData[] - // marque les cases couvertes par un span pour ne pas générer du "vide" dessus + // éviter des doublons/chevauchements dans la grille pour les spans. const covered = Array.from({ length: totalRows }, () => Array.from({ length: totalCols }, () => false)) // map positions by (x,y) @@ -140,6 +167,7 @@ const buildLayoutView = ( for (let x = 1; x <= totalCols; x++) { if (!occupiedColumns.has(x)) gapColumns.push(x) } + const gapColumnsSet = new Set(gapColumns) for (let y = 1; y <= totalRows; y++) { for (let x = 1; x <= totalCols; x++) { @@ -157,6 +185,20 @@ const buildLayoutView = ( } const caseNumber = (p.buildingCase?.caseNumber ?? null) as number | null const caseId = (p.buildingCase?.id ?? null) as number | null + const statusLabel = p.buildingCase?.statut?.label ?? null + const statusColor = normalizeCaseStatusColor(p.buildingCase?.statut?.couleur) + const caseStatusLabel = statusLabel + const caseStyle = statusColor + ? { backgroundColor: statusColor } + : undefined + const spanStyle = { + gridColumn: `${x} / span ${w}`, + gridRow: `${y} / span ${h}` + } + const hasGapLeft = gapColumnsSet.has(x - 1) + const hasGapRight = gapColumnsSet.has(x + w) + const isOuterLeft = x === 1 + const isOuterRight = x + w - 1 === totalCols cells.push({ key: `case-${layout.id}-${p.id}`, x, @@ -167,11 +209,22 @@ const buildLayoutView = ( caseNumber, caseId, display: caseNumber !== null ? String(caseNumber) : "Case", - rawId: p.id + rawId: p.id, + hasGapLeft, + hasGapRight, + isOuterLeft, + isOuterRight, + caseStatusLabel, + caseStyle, + spanStyle }) } for (const gapX of gapColumns) { + const spanStyle = { + gridColumn: `${gapX} / span 1`, + gridRow: `${y} / span 1` + } cells.push({ key: `gap-${layout.id}-${y}-${gapX}`, x: gapX, @@ -182,18 +235,40 @@ const buildLayoutView = ( caseNumber: null, caseId: null, display: "", - rawId: undefined + rawId: undefined, + hasGapLeft: false, + hasGapRight: false, + isOuterLeft: gapX === 1, + isOuterRight: gapX === totalCols, + caseStatusLabel: null, + caseStyle: undefined, + spanStyle }) } } const columnsTemplate = Array.from({ length: totalCols }, (_, idx) => - gapColumns.includes(idx + 1) ? "24px" : "minmax(0, 1fr)" + gapColumnsSet.has(idx + 1) ? "24px" : "minmax(0, 1fr)" ).join(" ") + const cols = Math.max(0, layout.columns ?? 0) + const gridStyle = { + gridTemplateColumns: columnsTemplate ?? `repeat(${cols}, minmax(0, 1fr))`, + gridAutoRows: "1fr", + rowGap: "18px", + columnGap: "0px", + width: "100%" + } - return { cells, columnsTemplate } + return { cells, columnsTemplate, gridStyle } } onMounted(async () => { - buildingList.value = await getBuildingList() + const buildingsPromise = getBuildingList() + const statutsPromise = getStatutList() + const buildings = await buildingsPromise + const statuts = await statutsPromise + buildingList.value = buildings + statutLegend.value = [...statuts].sort((a, b) => + (a.label ?? "").localeCompare(b.label ?? "", "fr", { sensitivity: "base" }) + ) }) diff --git a/frontend/services/dto/building-case-data.ts b/frontend/services/dto/building-case-data.ts index 6a59f1f..4d718c3 100644 --- a/frontend/services/dto/building-case-data.ts +++ b/frontend/services/dto/building-case-data.ts @@ -1,6 +1,9 @@ +import type { BuildingCaseStatusData } from '~/services/dto/building-case-status-data' + export interface BuildingCaseData { id: number caseNumber: number | null code: string | null capacity: number | null + statut?: BuildingCaseStatusData | null } diff --git a/frontend/services/dto/building-case-status-data.ts b/frontend/services/dto/building-case-status-data.ts new file mode 100644 index 0000000..187a412 --- /dev/null +++ b/frontend/services/dto/building-case-status-data.ts @@ -0,0 +1,6 @@ +export interface BuildingCaseStatusData { + id: number + label: string | null + code: string | null + couleur: string | null +} diff --git a/migrations/Version20260220101607.php b/migrations/Version20260220101607.php new file mode 100644 index 0000000..301f0d8 --- /dev/null +++ b/migrations/Version20260220101607.php @@ -0,0 +1,37 @@ +addSql('CREATE TABLE statut (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, label VARCHAR(255) NOT NULL, code VARCHAR(255) NOT NULL, color VARCHAR(255) NOT NULL, PRIMARY KEY (id))'); + $this->addSql('ALTER TABLE building_case ADD statut_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE building_case ADD CONSTRAINT FK_DE2CEE50F6203804 FOREIGN KEY (statut_id) REFERENCES statut (id)'); + $this->addSql('CREATE INDEX IDX_DE2CEE50F6203804 ON building_case (statut_id)'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('DROP TABLE statut'); + $this->addSql('ALTER TABLE building_case DROP CONSTRAINT FK_DE2CEE50F6203804'); + $this->addSql('DROP INDEX IDX_DE2CEE50F6203804'); + $this->addSql('ALTER TABLE building_case DROP statut_id'); + } +} diff --git a/src/Entity/BuildingCase.php b/src/Entity/BuildingCase.php index 1730324..1864560 100644 --- a/src/Entity/BuildingCase.php +++ b/src/Entity/BuildingCase.php @@ -42,6 +42,10 @@ class BuildingCase #[ORM\ManyToOne(inversedBy: 'buildingCases')] private ?Building $id_building = null; + #[ORM\ManyToOne(inversedBy: 'id_case')] + #[Groups(['building:read'])] + private ?Statut $statut = null; + public function __construct() { $this->id_case_position = new ArrayCollection(); @@ -136,4 +140,16 @@ class BuildingCase return $this; } + + public function getStatut(): ?Statut + { + return $this->statut; + } + + public function setStatut(?Statut $statut): static + { + $this->statut = $statut; + + return $this; + } } diff --git a/src/Entity/Statut.php b/src/Entity/Statut.php new file mode 100644 index 0000000..431f889 --- /dev/null +++ b/src/Entity/Statut.php @@ -0,0 +1,139 @@ + '\d+'], + normalizationContext: ['groups' => ['building:read']], + ), + new GetCollection( + normalizationContext: ['groups' => ['building:read']], + ), + ], + security: "is_granted('ROLE_USER')", +)] +class Statut +{ + #[ORM\Id] + #[ORM\GeneratedValue] + #[ORM\Column] + #[Groups(['building:read'])] + private ?int $id = null; + + #[ORM\Column(length: 255)] + #[Groups(['building:read'])] + private ?string $label = null; + + #[ORM\Column(length: 255)] + #[Groups(['building:read'])] + private ?string $code = null; + + #[ORM\Column(length: 255)] + #[Groups(['building:read'])] + #[SerializedName('couleur')] + private ?string $color = null; + + /** + * @var Collection + */ + #[ORM\OneToMany(targetEntity: BuildingCase::class, mappedBy: 'statut')] + private Collection $id_case; + + public function __construct() + { + $this->id_case = new ArrayCollection(); + } + + public function getId(): ?int + { + return $this->id; + } + + public function setId(int $id): static + { + $this->id = $id; + + return $this; + } + + public function getLabel(): ?string + { + return $this->label; + } + + public function setLabel(string $label): static + { + $this->label = $label; + + return $this; + } + + public function getCode(): ?string + { + return $this->code; + } + + public function setCode(string $code): static + { + $this->code = $code; + + return $this; + } + + public function getColor(): ?string + { + return $this->color; + } + + public function setColor(string $color): static + { + $this->color = $color; + + return $this; + } + + /** + * @return Collection + */ + public function getIdCase(): Collection + { + return $this->id_case; + } + + public function addIdCase(BuildingCase $idCase): static + { + if (!$this->id_case->contains($idCase)) { + $this->id_case->add($idCase); + $idCase->setStatut($this); + } + + return $this; + } + + public function removeIdCase(BuildingCase $idCase): static + { + if ($this->id_case->removeElement($idCase)) { + // set the owning side to null (unless already changed) + if ($idCase->getStatut() === $this) { + $idCase->setStatut(null); + } + } + + return $this; + } +} -- 2.39.5 From 3e05c68c540053930f6a43497f6e307d31f33369 Mon Sep 17 00:00:00 2001 From: Matteo Date: Mon, 23 Feb 2026 09:26:19 +0100 Subject: [PATCH 03/10] feat : plan du site (WIP) --- frontend/pages/infrastructure/batiment.vue | 274 ------------------ frontend/pages/infrastructure/building.vue | 194 +++++++++++++ frontend/services/dto/building-layout-data.ts | 11 + 3 files changed, 205 insertions(+), 274 deletions(-) delete mode 100644 frontend/pages/infrastructure/batiment.vue create mode 100644 frontend/pages/infrastructure/building.vue diff --git a/frontend/pages/infrastructure/batiment.vue b/frontend/pages/infrastructure/batiment.vue deleted file mode 100644 index 2b1a424..0000000 --- a/frontend/pages/infrastructure/batiment.vue +++ /dev/null @@ -1,274 +0,0 @@ - - - diff --git a/frontend/pages/infrastructure/building.vue b/frontend/pages/infrastructure/building.vue new file mode 100644 index 0000000..503b50d --- /dev/null +++ b/frontend/pages/infrastructure/building.vue @@ -0,0 +1,194 @@ + + + diff --git a/frontend/services/dto/building-layout-data.ts b/frontend/services/dto/building-layout-data.ts index f9a2661..73e9de4 100644 --- a/frontend/services/dto/building-layout-data.ts +++ b/frontend/services/dto/building-layout-data.ts @@ -7,3 +7,14 @@ export interface BuildingLayoutData { rows: number | null casePositions?: BuildingCasePositionData[] | null } +export type LayoutCell = { + key: string + isEmpty: boolean + caseId: number | null + display: string + caseStatusId: number | null + caseStatusLabel: string | null + caseStyle?: Record + spanStyle: Record + baseClass: string +} -- 2.39.5 From 15903a0213283bfdbff7fc225d1a206877992a38 Mon Sep 17 00:00:00 2001 From: Matteo Date: Mon, 23 Feb 2026 12:06:11 +0100 Subject: [PATCH 04/10] feat : plan du site (WIP) --- frontend/pages/index.vue | 2 +- frontend/pages/infrastructure/building.vue | 152 ++++++++------------- frontend/services/statut.ts | 23 ++++ 3 files changed, 84 insertions(+), 93 deletions(-) create mode 100644 frontend/services/statut.ts diff --git a/frontend/pages/index.vue b/frontend/pages/index.vue index 2131d24..8eb2e9a 100644 --- a/frontend/pages/index.vue +++ b/frontend/pages/index.vue @@ -4,7 +4,7 @@
- +