Refactors rendering pipeline with flexible data handling
Removes hardcoded data from render context, allowing more dynamic renderer implementation Changes include: - Decoupling data retrieval from render context - Simplifying renderer interface - Supporting more flexible data traversal strategies Prepares for more modular and adaptable rendering approach
This commit is contained in:
parent
a3a1b9a421
commit
c16e432b29
5 changed files with 517 additions and 22 deletions
246
.workbench/plan-comparison.md
Normal file
246
.workbench/plan-comparison.md
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
# Plan Sammenligning: Spec vs Min Plan
|
||||
|
||||
## 1. Grid Container
|
||||
|
||||
| Spec | Min Plan | Kommentar |
|
||||
|------|----------|-----------|
|
||||
| Ét grid (`ctx.grid`) | To containers (`headerContainer` + `columnContainer`) | **Afvigelse:** Vi har 2 containers for at understøtte header drawer og sticky headers. Spec'en bruger ét grid hvor append-rækkefølge = rækker. |
|
||||
|
||||
**Spørgsmål:** Er 2 containers ok, eller skal vi følge spec'en med ét grid?
|
||||
|
||||
---
|
||||
|
||||
## 2. RenderContext
|
||||
|
||||
| Spec | Min Plan |
|
||||
|------|----------|
|
||||
| `{ grid: HTMLElement, teams: Team[] }` | `{ headerContainer: HTMLElement, columnContainer: HTMLElement }` |
|
||||
|
||||
**Spec:**
|
||||
```typescript
|
||||
interface RenderContext {
|
||||
grid: HTMLElement;
|
||||
teams: Team[];
|
||||
}
|
||||
```
|
||||
|
||||
**Min plan:**
|
||||
```typescript
|
||||
interface RenderContext {
|
||||
headerContainer: HTMLElement;
|
||||
columnContainer: HTMLElement;
|
||||
}
|
||||
```
|
||||
|
||||
**Kommentar:** Spec'en har `teams` data i context. Min plan har ingen data i context - renderers henter selv. Er det korrekt at fjerne data fra context?
|
||||
|
||||
---
|
||||
|
||||
## 3. Data Model
|
||||
|
||||
| Spec | Min Plan |
|
||||
|------|----------|
|
||||
| Nested: `team.resources[]`, `resource.dates[]` | Flad med id-relationer, renderers henter selv |
|
||||
|
||||
**Spec:**
|
||||
```typescript
|
||||
interface Team {
|
||||
id: string;
|
||||
name: string;
|
||||
resources: Resource[]; // nested
|
||||
}
|
||||
```
|
||||
|
||||
**Min plan:**
|
||||
```typescript
|
||||
// Hardcoded i renderer
|
||||
private resourcesByTeam = {
|
||||
'team1': ['res1', 'res2'], // kun ids
|
||||
'team2': ['res3']
|
||||
};
|
||||
```
|
||||
|
||||
**Kommentar:** Spec'en har nested data. Min plan bruger id-relationer og renderers slår selv op. Begge dele virker - min plan er mere fleksibel for store datasets.
|
||||
|
||||
---
|
||||
|
||||
## 4. Renderer Interface
|
||||
|
||||
| Spec | Min Plan |
|
||||
|------|----------|
|
||||
| `render(ctx): void` | `render(ids, next, context): void` |
|
||||
|
||||
**Spec:**
|
||||
```typescript
|
||||
interface Renderer {
|
||||
id: string;
|
||||
next: Renderer | null;
|
||||
render(ctx: RenderContext): void;
|
||||
}
|
||||
```
|
||||
|
||||
**Min plan:**
|
||||
```typescript
|
||||
interface IGroupingRenderer {
|
||||
readonly type: string;
|
||||
count?(ids: string[], next: NextFunction): number;
|
||||
render(ids: string[], next: NextFunction, context: RenderContext): void;
|
||||
}
|
||||
```
|
||||
|
||||
**Kommentar:**
|
||||
- Spec'en: Renderer har `next` som property, kalder selv `this.next.render(ctx)`
|
||||
- Min plan: `next` kommer som parameter, kalder `next.render(ids)`
|
||||
|
||||
Min plan sender ids eksplicit. Spec'en bruger nested data så ids er unødvendige.
|
||||
|
||||
---
|
||||
|
||||
## 5. Pipeline / Builder
|
||||
|
||||
| Spec | Min Plan |
|
||||
|------|----------|
|
||||
| `buildPipeline()` linker `renderer.next` | `RenderBuilder` med `buildChain()` |
|
||||
|
||||
**Spec:**
|
||||
```typescript
|
||||
function buildPipeline(renderers: Renderer[]) {
|
||||
for (let i = 0; i < renderers.length - 1; i++) {
|
||||
renderers[i].next = renderers[i + 1];
|
||||
}
|
||||
return { run(ctx) { first.render(ctx); } };
|
||||
}
|
||||
```
|
||||
|
||||
**Min plan:**
|
||||
```typescript
|
||||
class RenderBuilder {
|
||||
add(renderer): this { ... }
|
||||
build(startIds): void { ... }
|
||||
private buildChain(index): NextFunction { ... }
|
||||
}
|
||||
```
|
||||
|
||||
**Kommentar:** Samme koncept, forskellig implementering. Spec'en muterer renderers (`next` property). Min plan bruger closures (functional chain).
|
||||
|
||||
---
|
||||
|
||||
## 6. Colspan Beregning
|
||||
|
||||
| Spec | Min Plan |
|
||||
|------|----------|
|
||||
| Beregnes før render: `team.resources.length` | Beregnes via `next.count()` |
|
||||
|
||||
**Spec:**
|
||||
```typescript
|
||||
// I renderer
|
||||
cell.style.setProperty('--team-cols', team.resources.length.toString());
|
||||
```
|
||||
|
||||
**Min plan:**
|
||||
```typescript
|
||||
// I renderer
|
||||
const colspan = next.count(resourceIds);
|
||||
cell.style.setProperty('--team-cols', String(colspan));
|
||||
```
|
||||
|
||||
**Kommentar:** Spec'en ved colspan direkte fra nested data. Min plan kalder `next.count()` rekursivt for at beregne. Resultat er det samme.
|
||||
|
||||
---
|
||||
|
||||
## 7. CSS Custom Properties
|
||||
|
||||
| Spec | Min Plan |
|
||||
|------|----------|
|
||||
| `--total-cols`, `--team-cols` | `--grid-columns`, `--team-cols` |
|
||||
|
||||
**Kommentar:** Næsten identisk. Begge bruger CSS vars til dynamisk colspan.
|
||||
|
||||
---
|
||||
|
||||
## 8. Append Rækkefølge
|
||||
|
||||
| Spec | Min Plan |
|
||||
|------|----------|
|
||||
| Alle teams → alle resources → alle dates | Per team: resources → dates |
|
||||
|
||||
**Spec flow:**
|
||||
```
|
||||
TeamRenderer: append team1, team2, team3 headers
|
||||
ResourceRenderer: append res1, res2, res3, res4 headers
|
||||
DateRenderer: append alle dates
|
||||
```
|
||||
|
||||
**Min plan flow:**
|
||||
```
|
||||
TeamRenderer:
|
||||
append team1 header → next.render(['res1','res2'])
|
||||
ResourceRenderer: append res1 → next.render(dates)
|
||||
append res2 → next.render(dates)
|
||||
append team2 header → next.render(['res3'])
|
||||
ResourceRenderer: append res3 → next.render(dates)
|
||||
```
|
||||
|
||||
**Kommentar:** Dette er en **væsentlig forskel**.
|
||||
|
||||
Spec'en renderer alle teams først, så alle resources, så alle dates - CSS grid auto-row placerer dem.
|
||||
|
||||
Min plan renderer nested: team1 → team1's resources → team1's dates → team2 → osv.
|
||||
|
||||
**Spørgsmål:** Hvilken approach foretrækker du? Spec'ens "lag for lag" eller min "nested traversal"?
|
||||
|
||||
---
|
||||
|
||||
## 9. Hvem kalder next?
|
||||
|
||||
| Spec | Min Plan |
|
||||
|------|----------|
|
||||
| Renderer kalder `this.next.render(ctx)` efter egen render | Renderer kalder `next.render(ids)` per item |
|
||||
|
||||
**Spec:**
|
||||
```typescript
|
||||
render(ctx) {
|
||||
// render alle teams
|
||||
for (const team of ctx.teams) { ... }
|
||||
// derefter kald next
|
||||
if (this.next) this.next.render(ctx);
|
||||
}
|
||||
```
|
||||
|
||||
**Min plan:**
|
||||
```typescript
|
||||
render(ids, next, context) {
|
||||
for (const id of ids) {
|
||||
// render ét team
|
||||
next.render(childIds); // kald next PER team
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Kommentar:** Spec'en kalder next ÉN gang efter alle items. Min plan kalder next PER item. Dette hænger sammen med punkt 8.
|
||||
|
||||
---
|
||||
|
||||
## Opsummering af Afvigelser
|
||||
|
||||
| # | Emne | Status |
|
||||
|---|------|--------|
|
||||
| 1 | 2 containers vs 1 grid | **Accepteret** (header drawer) |
|
||||
| 2 | Data i context | **Afvigelse** - fjernet |
|
||||
| 3 | Nested vs flad data | **Accepteret** (id-relationer) |
|
||||
| 4 | next som parameter vs property | **Afvigelse** - funktionel |
|
||||
| 5 | Pipeline implementation | Lignende |
|
||||
| 6 | Colspan beregning | Lignende |
|
||||
| 7 | CSS vars | Identisk |
|
||||
| 8 | Render rækkefølge | **Væsentlig afvigelse** |
|
||||
| 9 | Hvornår next kaldes | **Væsentlig afvigelse** |
|
||||
|
||||
---
|
||||
|
||||
## Åbne Spørgsmål
|
||||
|
||||
1. **Render rækkefølge:** Skal vi følge spec'ens "lag for lag" approach, eller er "nested traversal" ok?
|
||||
|
||||
2. **Context data:** Spec'en har `teams` i context. Skal vi have noget data i context, eller er det ok at renderers henter selv?
|
||||
|
||||
3. **2 containers:** Er det ok at beholde 2 containers for header drawer support?
|
||||
Loading…
Add table
Add a link
Reference in a new issue