@trebco/treb 27.7.6 → 27.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/treb-spreadsheet.mjs +14 -14
- package/dist/treb.d.ts +21 -21
- package/notes/conditional-fomratring.md +29 -0
- package/package.json +1 -1
- package/treb-base-types/src/area.ts +181 -0
- package/treb-base-types/src/evaluate-options.ts +21 -0
- package/treb-base-types/src/gradient.ts +97 -0
- package/treb-base-types/src/import.ts +2 -1
- package/treb-base-types/src/index.ts +2 -0
- package/treb-calculator/src/calculator.ts +190 -28
- package/treb-calculator/src/dag/calculation_leaf_vertex.ts +97 -0
- package/treb-calculator/src/dag/graph.ts +10 -22
- package/treb-calculator/src/dag/{leaf_vertex.ts → state_leaf_vertex.ts} +3 -3
- package/treb-calculator/src/descriptors.ts +10 -3
- package/treb-calculator/src/expression-calculator.ts +1 -1
- package/treb-calculator/src/function-library.ts +25 -22
- package/treb-calculator/src/functions/base-functions.ts +166 -5
- package/treb-calculator/src/index.ts +6 -6
- package/treb-calculator/src/notifier-types.ts +1 -1
- package/treb-calculator/src/utilities.ts +2 -2
- package/treb-charts/src/util.ts +2 -2
- package/treb-embed/src/embedded-spreadsheet.ts +352 -41
- package/treb-export/src/export-worker/export-worker.ts +0 -13
- package/treb-export/src/export2.ts +187 -2
- package/treb-export/src/import2.ts +169 -4
- package/treb-export/src/workbook-style2.ts +56 -8
- package/treb-export/src/workbook2.ts +10 -1
- package/treb-grid/src/index.ts +2 -1
- package/treb-grid/src/layout/base_layout.ts +23 -15
- package/treb-grid/src/render/tile_renderer.ts +2 -1
- package/treb-grid/src/types/conditional_format.ts +168 -0
- package/treb-grid/src/types/grid.ts +5 -6
- package/treb-grid/src/types/grid_base.ts +186 -33
- package/treb-grid/src/types/sheet.ts +330 -26
- package/treb-grid/src/types/sheet_types.ts +4 -0
- /package/{README-shadow-DOM.md → notes/shadow-DOM.md} +0 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
|
|
2
|
+
import type { CellStyle, EvaluateOptions, IArea, Color, Gradient, GradientStop, UnionValue } from 'treb-base-types';
|
|
3
|
+
|
|
4
|
+
interface VertexPlaceholder {
|
|
5
|
+
result: UnionValue;
|
|
6
|
+
updated: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface CondifionalFormatExpressionOptions {
|
|
10
|
+
style: CellStyle;
|
|
11
|
+
expression: string;
|
|
12
|
+
options?: EvaluateOptions;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* conditional format predicated on an expression. if the expression
|
|
17
|
+
* evaluates to true, we apply the style. otherwise no.
|
|
18
|
+
*/
|
|
19
|
+
export interface ConditionalFormatExpression extends CondifionalFormatExpressionOptions {
|
|
20
|
+
|
|
21
|
+
type: 'expression';
|
|
22
|
+
area: IArea;
|
|
23
|
+
|
|
24
|
+
/** @internal */
|
|
25
|
+
internal?: {
|
|
26
|
+
vertex?: VertexPlaceholder;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface ConditionalFormatGradientOptions {
|
|
32
|
+
|
|
33
|
+
/** property defaults to fill */
|
|
34
|
+
property?: 'fill'|'text';
|
|
35
|
+
|
|
36
|
+
/** defaults to HSL */
|
|
37
|
+
color_space?: 'HSL'|'RGB';
|
|
38
|
+
|
|
39
|
+
/** gradient stops, required */
|
|
40
|
+
stops: Array<{ value: number, color: Color }>;
|
|
41
|
+
|
|
42
|
+
/** min and max are optional. if not provided, we use the min/max of the range of data. */
|
|
43
|
+
min?: number;
|
|
44
|
+
|
|
45
|
+
/** min and max are optional. if not provided, we use the min/max of the range of data. */
|
|
46
|
+
max?: number;
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
export const StandardGradientsList = {
|
|
52
|
+
'red-green': {
|
|
53
|
+
color_space: 'RGB',
|
|
54
|
+
stops: [
|
|
55
|
+
{ value: 0, color: { theme: 5, tint: .5 }},
|
|
56
|
+
{ value: 1, color: { theme: 9, tint: .5 }},
|
|
57
|
+
] as GradientStop[],
|
|
58
|
+
},
|
|
59
|
+
'red-yellow-green': {
|
|
60
|
+
color_space: 'RGB',
|
|
61
|
+
stops: [
|
|
62
|
+
{ value: 0, color: { theme: 5, tint: .5 }},
|
|
63
|
+
{ value: 0.5, color: { theme: 7, tint: .5 }},
|
|
64
|
+
{ value: 1, color: { theme: 9, tint: .5 }},
|
|
65
|
+
] as GradientStop[],
|
|
66
|
+
},
|
|
67
|
+
'green-red': {
|
|
68
|
+
color_space: 'RGB',
|
|
69
|
+
stops: [
|
|
70
|
+
{ value: 0, color: { theme: 9, tint: .5 }},
|
|
71
|
+
{ value: 1, color: { theme: 5, tint: .5 }},
|
|
72
|
+
] as GradientStop[],
|
|
73
|
+
},
|
|
74
|
+
'green-yellow-red': {
|
|
75
|
+
color_space: 'RGB',
|
|
76
|
+
stops: [
|
|
77
|
+
{ value: 0, color: { theme: 9, tint: .5 }},
|
|
78
|
+
{ value: 0.5, color: { theme: 7, tint: .5 }},
|
|
79
|
+
{ value: 1, color: { theme: 5, tint: .5 }},
|
|
80
|
+
] as GradientStop[],
|
|
81
|
+
},
|
|
82
|
+
} as const;
|
|
83
|
+
export type StandardGradient = keyof typeof StandardGradientsList;
|
|
84
|
+
|
|
85
|
+
export interface ConditionalFormatGradient extends ConditionalFormatGradientOptions {
|
|
86
|
+
type: 'gradient';
|
|
87
|
+
area: IArea;
|
|
88
|
+
|
|
89
|
+
/** @internal */
|
|
90
|
+
internal?: {
|
|
91
|
+
gradient?: Gradient;
|
|
92
|
+
vertex?: VertexPlaceholder;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface ConditionalFormatCellMatchOptions {
|
|
97
|
+
style: CellStyle;
|
|
98
|
+
expression: string;
|
|
99
|
+
options?: EvaluateOptions;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface ConditionalFormatCellMatch extends ConditionalFormatCellMatchOptions {
|
|
103
|
+
type: 'cell-match';
|
|
104
|
+
area: IArea;
|
|
105
|
+
|
|
106
|
+
/** @internal */
|
|
107
|
+
internal?: {
|
|
108
|
+
vertex?: VertexPlaceholder;
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface ConditionalFormatCellMatchOptions {
|
|
113
|
+
style: CellStyle;
|
|
114
|
+
expression: string;
|
|
115
|
+
options?: EvaluateOptions;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface ConditionalFormatCellMatch extends ConditionalFormatCellMatchOptions {
|
|
119
|
+
type: 'cell-match';
|
|
120
|
+
area: IArea;
|
|
121
|
+
|
|
122
|
+
/** @internal */
|
|
123
|
+
internal?: {
|
|
124
|
+
vertex?: VertexPlaceholder;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface ConditionalFormatDuplicateValuesOptions {
|
|
129
|
+
style: CellStyle;
|
|
130
|
+
|
|
131
|
+
/** true to highlight unique cells, false to highlight duplicates. defaults to false. */
|
|
132
|
+
unique?: boolean;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export interface ConditionalFormatDuplicateValues extends ConditionalFormatDuplicateValuesOptions {
|
|
136
|
+
|
|
137
|
+
type: 'duplicate-values';
|
|
138
|
+
area: IArea;
|
|
139
|
+
|
|
140
|
+
/** @internal */
|
|
141
|
+
internal?: {
|
|
142
|
+
vertex?: VertexPlaceholder;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* union, plus we're adding a state used to track application.
|
|
149
|
+
* that state is serialized if it's true.
|
|
150
|
+
* we also add an internal field that will be type-specific, and not serialized.
|
|
151
|
+
*
|
|
152
|
+
* ...everybody has a vertex now, we could standardize it
|
|
153
|
+
*
|
|
154
|
+
*/
|
|
155
|
+
export type ConditionalFormat = { internal?: unknown } & (
|
|
156
|
+
ConditionalFormatDuplicateValues |
|
|
157
|
+
ConditionalFormatExpression |
|
|
158
|
+
ConditionalFormatCellMatch |
|
|
159
|
+
ConditionalFormatGradient
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* the list of formats, in reverse order of precedence. as a starting
|
|
164
|
+
* point we're using the naive approach, just applying everything in
|
|
165
|
+
* order. that may change.
|
|
166
|
+
*/
|
|
167
|
+
export type ConditionalFormatList = ConditionalFormat[];
|
|
168
|
+
|
|
@@ -1720,15 +1720,16 @@ export class Grid extends GridBase {
|
|
|
1720
1720
|
this.RenderSelections();
|
|
1721
1721
|
}
|
|
1722
1722
|
|
|
1723
|
-
|
|
1723
|
+
/* *
|
|
1724
1724
|
* FIXME: who uses this? anyone?
|
|
1725
|
-
|
|
1725
|
+
* /
|
|
1726
1726
|
public GetNumberFormat(address: ICellAddress): string|undefined {
|
|
1727
1727
|
const style = this.active_sheet.CellStyleData(address);
|
|
1728
1728
|
if (style && style.number_format) {
|
|
1729
1729
|
return NumberFormatCache.Get(style.number_format).toString();
|
|
1730
1730
|
}
|
|
1731
1731
|
}
|
|
1732
|
+
*/
|
|
1732
1733
|
|
|
1733
1734
|
/**
|
|
1734
1735
|
* I can't figure out a way in typescript to overload the GetRange function
|
|
@@ -1986,7 +1987,7 @@ export class Grid extends GridBase {
|
|
|
1986
1987
|
}
|
|
1987
1988
|
|
|
1988
1989
|
/** repaint after an external event (calculation) */
|
|
1989
|
-
public Update(force = false, area?:
|
|
1990
|
+
public Update(force = false, area?: IArea|IArea[]): void {
|
|
1990
1991
|
this.DelayedRender(force, area);
|
|
1991
1992
|
}
|
|
1992
1993
|
|
|
@@ -2792,9 +2793,7 @@ export class Grid extends GridBase {
|
|
|
2792
2793
|
|
|
2793
2794
|
}
|
|
2794
2795
|
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
private DelayedRender(force = false, area?: Area, full_tile = false) {
|
|
2796
|
+
private DelayedRender(force = false, area?: IArea|IArea[], full_tile = false) {
|
|
2798
2797
|
|
|
2799
2798
|
// if area is passed, set dirty before calling repaint
|
|
2800
2799
|
|
|
@@ -40,7 +40,7 @@ import type { DataModel, MacroFunction, SerializedModel, SerializedNamedExpressi
|
|
|
40
40
|
import type { Parser, UnitAddress} from 'treb-parser';
|
|
41
41
|
import { type ExpressionUnit, IllegalSheetNameRegex, ParseCSV, ArgumentSeparatorType, DecimalMarkType } from 'treb-parser';
|
|
42
42
|
import { Area, IsCellAddress, ValidationType, ValueType, DefaultTableSortOptions } from 'treb-base-types';
|
|
43
|
-
import type { ICellAddress, IArea, Cell, CellValue , Style, CellStyle, Table, TableSortOptions, TableTheme, Complex } from 'treb-base-types';
|
|
43
|
+
import type { ICellAddress, IArea, Cell, CellValue , Style, CellStyle, Table, TableSortOptions, TableTheme, Complex, PatchOptions as PatchAreaOptions } from 'treb-base-types';
|
|
44
44
|
import { Sheet } from './sheet';
|
|
45
45
|
import type { FunctionDescriptor} from '../editors/autocomplete_matcher';
|
|
46
46
|
import { AutocompleteMatcher, DescriptorType } from '../editors/autocomplete_matcher';
|
|
@@ -61,6 +61,11 @@ import type { UpdateFlags } from './update_flags';
|
|
|
61
61
|
import type { FreezePane, LegacySerializedSheet } from './sheet_types';
|
|
62
62
|
import type { Annotation } from './annotation';
|
|
63
63
|
import type { ClipboardCellData } from './clipboard_data';
|
|
64
|
+
import type { ConditionalFormat } from './conditional_format';
|
|
65
|
+
|
|
66
|
+
interface PatchOptions extends PatchAreaOptions {
|
|
67
|
+
sheet: Sheet;
|
|
68
|
+
}
|
|
64
69
|
|
|
65
70
|
export class GridBase {
|
|
66
71
|
|
|
@@ -2146,6 +2151,29 @@ export class GridBase {
|
|
|
2146
2151
|
|
|
2147
2152
|
}
|
|
2148
2153
|
|
|
2154
|
+
protected PatchExpressionSheetName(expression: string, old_name: string, name: string): string|undefined {
|
|
2155
|
+
|
|
2156
|
+
let modified = false;
|
|
2157
|
+
const parsed = this.parser.Parse(expression || '');
|
|
2158
|
+
if (parsed.expression) {
|
|
2159
|
+
this.parser.Walk(parsed.expression, (element: ExpressionUnit) => {
|
|
2160
|
+
if (element.type === 'address') {
|
|
2161
|
+
if (element.sheet && element.sheet.toLowerCase() === old_name) {
|
|
2162
|
+
element.sheet = name;
|
|
2163
|
+
modified = true;
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
return true; // continue walk
|
|
2167
|
+
});
|
|
2168
|
+
if (modified) {
|
|
2169
|
+
return '=' + this.parser.Render(parsed.expression, { missing: '' });
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
|
|
2173
|
+
return undefined;
|
|
2174
|
+
|
|
2175
|
+
}
|
|
2176
|
+
|
|
2149
2177
|
/**
|
|
2150
2178
|
* splitting this logic into a new function so we can reuse it
|
|
2151
2179
|
* for invalidating broken references. generally we'll call this
|
|
@@ -2165,45 +2193,39 @@ export class GridBase {
|
|
|
2165
2193
|
// cells
|
|
2166
2194
|
sheet.cells.IterateAll((cell: Cell) => {
|
|
2167
2195
|
if (cell.ValueIsFormula()) {
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2196
|
+
const updated = this.PatchExpressionSheetName(cell.value||'', old_name, name);
|
|
2197
|
+
if (updated) {
|
|
2198
|
+
cell.value = updated;
|
|
2199
|
+
changes++;
|
|
2200
|
+
}
|
|
2201
|
+
}
|
|
2202
|
+
});
|
|
2203
|
+
|
|
2204
|
+
// conditionals
|
|
2205
|
+
if (sheet.conditional_formats?.length) {
|
|
2206
|
+
for (const format of sheet.conditional_formats) {
|
|
2207
|
+
switch (format.type) {
|
|
2208
|
+
case 'cell-match':
|
|
2209
|
+
case 'expression':
|
|
2210
|
+
{
|
|
2211
|
+
const updated = this.PatchExpressionSheetName(format.expression, old_name, name);
|
|
2212
|
+
if (updated) {
|
|
2213
|
+
format.expression = updated;
|
|
2214
|
+
changes++;
|
|
2176
2215
|
}
|
|
2177
2216
|
}
|
|
2178
|
-
|
|
2179
|
-
});
|
|
2180
|
-
if (modified) {
|
|
2181
|
-
cell.value = '=' + this.parser.Render(parsed.expression, { missing: '' });
|
|
2182
|
-
changes++;
|
|
2183
|
-
}
|
|
2217
|
+
break;
|
|
2184
2218
|
}
|
|
2185
2219
|
}
|
|
2186
|
-
}
|
|
2220
|
+
}
|
|
2187
2221
|
|
|
2188
2222
|
// annotations
|
|
2189
2223
|
for (const annotation of sheet.annotations) {
|
|
2190
2224
|
if (annotation.data.formula) {
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
if (element.type === 'address') {
|
|
2196
|
-
if (element.sheet && element.sheet.toLowerCase() === old_name) {
|
|
2197
|
-
element.sheet = name;
|
|
2198
|
-
modified = true;
|
|
2199
|
-
}
|
|
2200
|
-
}
|
|
2201
|
-
return true; // continue walk
|
|
2202
|
-
});
|
|
2203
|
-
if (modified) {
|
|
2204
|
-
annotation.data.formula = '=' + this.parser.Render(parsed.expression, { missing: '' });
|
|
2205
|
-
changes++;
|
|
2206
|
-
}
|
|
2225
|
+
const updated = this.PatchExpressionSheetName(annotation.data.formula, old_name, name);
|
|
2226
|
+
if (updated) {
|
|
2227
|
+
annotation.data.formula = updated;
|
|
2228
|
+
changes++;
|
|
2207
2229
|
}
|
|
2208
2230
|
}
|
|
2209
2231
|
}
|
|
@@ -2634,7 +2656,121 @@ export class GridBase {
|
|
|
2634
2656
|
|
|
2635
2657
|
}
|
|
2636
2658
|
|
|
2637
|
-
|
|
2659
|
+
/**
|
|
2660
|
+
* patch an expression for insert/delete row/column operations.
|
|
2661
|
+
* FIXME: should move, maybe to parser? (...)
|
|
2662
|
+
*
|
|
2663
|
+
* NOTE: did I write this twice? we only need one. check which one is better.
|
|
2664
|
+
* @see PatchFormulasInternal
|
|
2665
|
+
*
|
|
2666
|
+
* @returns the updated expression, or `undefined` if no changes were made.
|
|
2667
|
+
*/
|
|
2668
|
+
protected PatchExpression(expression: string, options: PatchOptions) {
|
|
2669
|
+
|
|
2670
|
+
let count = 0;
|
|
2671
|
+
const parse_result = this.parser.Parse(expression);
|
|
2672
|
+
if (parse_result.expression) {
|
|
2673
|
+
|
|
2674
|
+
this.parser.Walk(parse_result.expression, unit => {
|
|
2675
|
+
if (unit.type === 'range') {
|
|
2676
|
+
if (!unit.start.sheet || (unit.start.sheet.toLowerCase() === options.sheet.name.toLowerCase())) {
|
|
2677
|
+
const updated = Area.PatchArea(unit, options);
|
|
2678
|
+
if (updated) {
|
|
2679
|
+
unit.start.row = updated.start.row;
|
|
2680
|
+
unit.start.column = updated.start.column;
|
|
2681
|
+
unit.end.row = updated.end.row;
|
|
2682
|
+
unit.end.column = updated.end.column;
|
|
2683
|
+
}
|
|
2684
|
+
else {
|
|
2685
|
+
|
|
2686
|
+
// FIXME: maybe have options for this? we don't really have a
|
|
2687
|
+
// good way to replace nodes atm
|
|
2688
|
+
unit.start.row = unit.end.row = unit.start.column = unit.end.column = -1;
|
|
2689
|
+
|
|
2690
|
+
}
|
|
2691
|
+
}
|
|
2692
|
+
count++;
|
|
2693
|
+
return false;
|
|
2694
|
+
}
|
|
2695
|
+
else if (unit.type === 'address') {
|
|
2696
|
+
const updated = Area.PatchArea({start: unit, end: unit}, options);
|
|
2697
|
+
if (updated) {
|
|
2698
|
+
unit.row = updated.start.row;
|
|
2699
|
+
unit.column = updated.start.column;
|
|
2700
|
+
}
|
|
2701
|
+
else {
|
|
2702
|
+
|
|
2703
|
+
// see above
|
|
2704
|
+
unit.row = unit.column = -1;
|
|
2705
|
+
}
|
|
2706
|
+
count++;
|
|
2707
|
+
return false;
|
|
2708
|
+
}
|
|
2709
|
+
return true;
|
|
2710
|
+
});
|
|
2711
|
+
|
|
2712
|
+
if (count) {
|
|
2713
|
+
const rendered = this.parser.Render(parse_result.expression, {
|
|
2714
|
+
missing: '',
|
|
2715
|
+
});
|
|
2716
|
+
// console.info("FROM", expression, "TO", rendered);
|
|
2717
|
+
return rendered;
|
|
2718
|
+
}
|
|
2719
|
+
|
|
2720
|
+
}
|
|
2721
|
+
|
|
2722
|
+
return undefined;
|
|
2723
|
+
|
|
2724
|
+
}
|
|
2725
|
+
|
|
2726
|
+
/**
|
|
2727
|
+
* patch sheet conditionals for insert/delete row/column operations.
|
|
2728
|
+
* some of them may be deleted.
|
|
2729
|
+
*/
|
|
2730
|
+
protected PatchConditionals(options: PatchOptions) {
|
|
2731
|
+
|
|
2732
|
+
if (options.sheet.conditional_formats?.length) {
|
|
2733
|
+
|
|
2734
|
+
const delete_list: Set<ConditionalFormat> = new Set();
|
|
2735
|
+
for (const format of options.sheet.conditional_formats) {
|
|
2736
|
+
|
|
2737
|
+
// first adjust the format area
|
|
2738
|
+
|
|
2739
|
+
const updated = Area.PatchArea(format.area, options);
|
|
2740
|
+
if (updated) {
|
|
2741
|
+
format.area = JSON.parse(JSON.stringify(updated));
|
|
2742
|
+
}
|
|
2743
|
+
else {
|
|
2744
|
+
delete_list.add(format);
|
|
2745
|
+
continue; // don't bother with formula
|
|
2746
|
+
}
|
|
2747
|
+
|
|
2748
|
+
// next update the formula, if necessary. what do we do if the
|
|
2749
|
+
// area has disappeared? should be a #REF error, not sure we
|
|
2750
|
+
// can encode that properly
|
|
2751
|
+
|
|
2752
|
+
switch (format.type) {
|
|
2753
|
+
case 'expression':
|
|
2754
|
+
case 'cell-match':
|
|
2755
|
+
{
|
|
2756
|
+
const updated = this.PatchExpression(format.expression, options);
|
|
2757
|
+
|
|
2758
|
+
if (updated) {
|
|
2759
|
+
format.expression = updated;
|
|
2760
|
+
}
|
|
2761
|
+
}
|
|
2762
|
+
break;
|
|
2763
|
+
}
|
|
2764
|
+
|
|
2765
|
+
}
|
|
2766
|
+
|
|
2767
|
+
if (delete_list.size) {
|
|
2768
|
+
options.sheet.conditional_formats = options.sheet.conditional_formats.filter(test => !delete_list.has(test));
|
|
2769
|
+
}
|
|
2770
|
+
|
|
2771
|
+
}
|
|
2772
|
+
|
|
2773
|
+
}
|
|
2638
2774
|
|
|
2639
2775
|
/**
|
|
2640
2776
|
* FIXME: should be API method
|
|
@@ -2664,6 +2800,15 @@ export class GridBase {
|
|
|
2664
2800
|
return { error: true };
|
|
2665
2801
|
}
|
|
2666
2802
|
|
|
2803
|
+
// conditionals
|
|
2804
|
+
this.PatchConditionals({
|
|
2805
|
+
sheet: target_sheet,
|
|
2806
|
+
before_column: 0,
|
|
2807
|
+
column_count: 0,
|
|
2808
|
+
before_row: command.before_row,
|
|
2809
|
+
row_count: command.count
|
|
2810
|
+
});
|
|
2811
|
+
|
|
2667
2812
|
// see InsertColumnsInternal re: tables. rows are less complicated,
|
|
2668
2813
|
// except that if you delete the header row we want to remove the
|
|
2669
2814
|
// table entirely.
|
|
@@ -2978,6 +3123,14 @@ export class GridBase {
|
|
|
2978
3123
|
return { error: true };
|
|
2979
3124
|
}
|
|
2980
3125
|
|
|
3126
|
+
// conditionals
|
|
3127
|
+
this.PatchConditionals({
|
|
3128
|
+
sheet: target_sheet,
|
|
3129
|
+
before_column: command.before_column,
|
|
3130
|
+
column_count: command.count,
|
|
3131
|
+
before_row: 0,
|
|
3132
|
+
row_count: 0 });
|
|
3133
|
+
|
|
2981
3134
|
// patch tables. we removed this from the sheet routine entirely,
|
|
2982
3135
|
// we need to rebuild any affected tables now.
|
|
2983
3136
|
|