mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-19 07:33:18 +02:00
Nest projects under a master project and roll their figures up (#1264)
Projects were flat. The parent_id column and the sub-project list existed but nothing could set a parent outside the API, and a master project's stats only ever covered its own prints. The project dialog gets a parent picker, and a project with sub-projects gets a second card covering the whole tree -- jobs, parts, time, filament, cost, and progress against every target in the tree added together. That card is separate from the project's own stats, which keep their existing meaning; widening them would have restated the figures of anyone who had already nested projects over the API. Each listed sub-project carries its own branch's roll-up, so the rows add up to the card above them. On the Projects page a sub-project is drawn inside its parent's group rather than as another card in the grid -- two cards columns apart cannot show that they belong together, whatever the caption says. A sub-project whose parent the status filter has hidden stays put and names its parent instead. compute_project_stats now goes through the same grouped aggregation as the roll-up rather than its own copy of the SQL, since the two must agree. Three things the interface made reachable: - PATCH refused only a project as its own direct parent, so A -> B -> A was two calls away. A cycle has no root to roll up to, and the walk keeps its seen-set for databases that already contain one. - A sub-project's percentage was completed quantities against the plate target, disagreeing with the page it linked to. - Deleting a mid-tree project orphaned its children at top level; they now move up to its own parent.
This commit is contained in:
@@ -908,12 +908,21 @@ export interface ProjectStats {
|
||||
bom_cost: number;
|
||||
}
|
||||
|
||||
// A sub-project as listed on its parent's page. The figures cover the child's
|
||||
// own subtree, so the listed rows add up to the parent's roll-up minus the
|
||||
// parent's own prints (#1264).
|
||||
export interface ProjectChildPreview {
|
||||
id: number;
|
||||
name: string;
|
||||
color: string | null;
|
||||
status: string;
|
||||
progress_percent: number | null;
|
||||
descendant_count: number;
|
||||
total_archives: number;
|
||||
completed_prints: number;
|
||||
total_print_time_hours: number;
|
||||
total_filament_grams: number;
|
||||
total_cost: number; // Filament + energy + BOM, matching the parent's cost card
|
||||
}
|
||||
|
||||
export interface Project {
|
||||
@@ -936,9 +945,13 @@ export interface Project {
|
||||
parent_id: number | null;
|
||||
parent_name: string | null;
|
||||
children: ProjectChildPreview[];
|
||||
descendant_count: number; // Sub-projects at any depth beneath this one (#1264)
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
stats?: ProjectStats;
|
||||
// This project's numbers combined with every sub-project's. Null when there
|
||||
// are none, since it would only repeat `stats` (#1264).
|
||||
rollup_stats?: ProjectStats | null;
|
||||
url: string | null; // External link rendered next to project name on the card (#1155)
|
||||
cover_image_filename: string | null; // Filename within project attachments dir (#1155)
|
||||
}
|
||||
@@ -985,6 +998,8 @@ export interface ProjectListItem {
|
||||
failed_count: number; // Sum of quantities for failed prints
|
||||
queue_count: number;
|
||||
progress_percent: number | null; // Plates progress
|
||||
parent_id: number | null; // #1264 — set when this is a sub-project
|
||||
child_count: number; // #1264 — direct sub-projects only
|
||||
archives: ArchivePreview[];
|
||||
url: string | null; // #1155
|
||||
cover_image_filename: string | null; // #1155
|
||||
|
||||
Reference in New Issue
Block a user