summaryrefslogtreecommitdiff
path: root/web/src/types.ts
blob: 8b1b6505bdcb37597f271987c42ca07fe54b29c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import Ratio from "./math/Ratio";

export interface Cell {
  value?: string;
  widthRatio: Ratio;
}

export interface Row {
  cells: Cell[];
}

export interface Part {
  title?: string;
  rows: Row[];
}

export interface Grid {
  id: string;
  baseCellSize: number;
  baseCellWidthRatio: Ratio;
  parts: Part[];
}

export interface Doc {
  grids: Grid[];
}

export interface RowRef {
  partIndex: number;
  rowIndex: number;
}

// TODO Should probably have a gridId
export interface CellRef {
  partIndex: number;
  rowIndex: number;
  cellIndex: number;
}

export function cellRefEquals(a: CellRef, b: CellRef): boolean {
  return (
    a.partIndex === b.partIndex &&
    a.rowIndex === b.rowIndex &&
    a.cellIndex === b.cellIndex
  );
}

export function mapRowsInRange(
  doc: Doc,
  gridId: string,
  startRef: CellRef,
  endRef: CellRef,
  mapFn: (row: Row, ref: RowRef) => Row,
): Doc {
  const firstPartIndex = Math.min(startRef.partIndex, endRef.partIndex);
  const lastPartIndex = Math.max(startRef.partIndex, endRef.partIndex);
  const firstRowIndex = Math.min(startRef.rowIndex, endRef.rowIndex);
  const lastRowIndex = Math.max(startRef.rowIndex, endRef.rowIndex);

  return {
    ...doc,
    grids: doc.grids.map((grid) => {
      if (grid.id !== gridId) return grid;

      return {
        ...grid,
        parts: grid.parts.map((part, partIndex) => {
          if (partIndex < firstPartIndex || partIndex > lastPartIndex) {
            return part;
          }

          return {
            ...part,
            rows: part.rows.map((row, rowIndex) => {
              if (rowIndex < firstRowIndex || rowIndex > lastRowIndex) {
                return row;
              }

              return mapFn(row, { partIndex, rowIndex });
            }),
          };
        }),
      };
    }),
  };
}