@odoo/o-spreadsheet 14.0.1 → 14.0.3

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.
Files changed (204) hide show
  1. package/dist/o-spreadsheet.cjs.js +17880 -0
  2. package/dist/o-spreadsheet.d.ts +4119 -0
  3. package/dist/o-spreadsheet.esm.js +17845 -0
  4. package/dist/o-spreadsheet.iife.js +17882 -0
  5. package/dist/o-spreadsheet.iife.min.js +1446 -0
  6. package/package.json +32 -9
  7. package/readme.md +10 -0
  8. package/.eslintrc.json +0 -20
  9. package/.husky/post-checkout +0 -9
  10. package/.husky/pre-commit +0 -39
  11. package/.prettierignore +0 -1
  12. package/astToFormula.patch +0 -0
  13. package/demo/data.js +0 -255
  14. package/demo/index.html +0 -9
  15. package/demo/libs/Chart.bundle.js +0 -20755
  16. package/demo/main.js +0 -101
  17. package/doc/readme.md +0 -46
  18. package/rollup.config.js +0 -23
  19. package/src/base_plugin.ts +0 -102
  20. package/src/components/autofill.ts +0 -146
  21. package/src/components/bottom_bar.ts +0 -199
  22. package/src/components/color_picker.ts +0 -150
  23. package/src/components/composer/autocomplete_dropdown.ts +0 -135
  24. package/src/components/composer/composer.ts +0 -487
  25. package/src/components/composer/content_editable_helper.ts +0 -146
  26. package/src/components/figures/chart.ts +0 -70
  27. package/src/components/figures/container.ts +0 -268
  28. package/src/components/figures/text_figure.ts +0 -36
  29. package/src/components/grid.ts +0 -635
  30. package/src/components/helpers/dom_helpers.ts +0 -7
  31. package/src/components/helpers/drag_and_drop.ts +0 -17
  32. package/src/components/icons.ts +0 -36
  33. package/src/components/index.ts +0 -1
  34. package/src/components/menu.ts +0 -288
  35. package/src/components/overlay.ts +0 -457
  36. package/src/components/scrollbar.ts +0 -22
  37. package/src/components/selection_input.ts +0 -168
  38. package/src/components/side_panel/cell_is_rule_editor.ts +0 -169
  39. package/src/components/side_panel/chart_panel.ts +0 -104
  40. package/src/components/side_panel/color_scale_rule_editor.ts +0 -145
  41. package/src/components/side_panel/conditional_formatting.ts +0 -396
  42. package/src/components/side_panel/side_panel.ts +0 -127
  43. package/src/components/side_panel/translations_terms.ts +0 -45
  44. package/src/components/spreadsheet.ts +0 -198
  45. package/src/components/top_bar.ts +0 -535
  46. package/src/constants.ts +0 -26
  47. package/src/data.ts +0 -149
  48. package/src/fonts.ts +0 -41
  49. package/src/formulas/compiler.ts +0 -258
  50. package/src/formulas/composer_tokenizer.ts +0 -70
  51. package/src/formulas/index.ts +0 -15
  52. package/src/formulas/normalize.ts +0 -52
  53. package/src/formulas/parser.ts +0 -280
  54. package/src/formulas/range_tokenizer.ts +0 -97
  55. package/src/formulas/tokenizer.ts +0 -242
  56. package/src/functions/arguments.ts +0 -114
  57. package/src/functions/dates.ts +0 -302
  58. package/src/functions/helpers.ts +0 -592
  59. package/src/functions/index.ts +0 -52
  60. package/src/functions/module_database.ts +0 -282
  61. package/src/functions/module_date.ts +0 -743
  62. package/src/functions/module_info.ts +0 -69
  63. package/src/functions/module_logical.ts +0 -208
  64. package/src/functions/module_lookup.ts +0 -185
  65. package/src/functions/module_math.ts +0 -1252
  66. package/src/functions/module_operators.ts +0 -291
  67. package/src/functions/module_statistical.ts +0 -882
  68. package/src/functions/module_text.ts +0 -370
  69. package/src/helpers/color.ts +0 -30
  70. package/src/helpers/coordinates.ts +0 -71
  71. package/src/helpers/grid_manipulation.ts +0 -68
  72. package/src/helpers/index.ts +0 -7
  73. package/src/helpers/misc.ts +0 -76
  74. package/src/helpers/numbers.ts +0 -117
  75. package/src/helpers/uuid.ts +0 -19
  76. package/src/helpers/zones.ts +0 -263
  77. package/src/history.ts +0 -186
  78. package/src/index.ts +0 -84
  79. package/src/model.ts +0 -261
  80. package/src/plugins/autofill.ts +0 -412
  81. package/src/plugins/chart.ts +0 -404
  82. package/src/plugins/clipboard.ts +0 -461
  83. package/src/plugins/conditional_format.ts +0 -445
  84. package/src/plugins/core.ts +0 -1502
  85. package/src/plugins/edition.ts +0 -157
  86. package/src/plugins/evaluation.ts +0 -428
  87. package/src/plugins/figures.ts +0 -123
  88. package/src/plugins/formatting.ts +0 -630
  89. package/src/plugins/highlight.ts +0 -187
  90. package/src/plugins/index.ts +0 -32
  91. package/src/plugins/merge.ts +0 -524
  92. package/src/plugins/renderer.ts +0 -571
  93. package/src/plugins/selection.ts +0 -562
  94. package/src/plugins/selection_inputs.ts +0 -326
  95. package/src/registries/autofill_modifiers.ts +0 -76
  96. package/src/registries/autofill_rules.ts +0 -98
  97. package/src/registries/figure_registry.ts +0 -30
  98. package/src/registries/index.ts +0 -7
  99. package/src/registries/menu_items_registry.ts +0 -110
  100. package/src/registries/menus/cell_menu_registry.ts +0 -79
  101. package/src/registries/menus/col_menu_registry.ts +0 -63
  102. package/src/registries/menus/index.ts +0 -6
  103. package/src/registries/menus/menu_items_actions.ts +0 -425
  104. package/src/registries/menus/row_menu_registry.ts +0 -63
  105. package/src/registries/menus/sheet_menu_registry.ts +0 -75
  106. package/src/registries/menus/topbar_menu_registry.ts +0 -204
  107. package/src/registries/side_panel_registry.ts +0 -26
  108. package/src/registries/topbar_component_registry.ts +0 -12
  109. package/src/registry.ts +0 -51
  110. package/src/translation.ts +0 -44
  111. package/src/types/autofill.ts +0 -48
  112. package/src/types/chart.ts +0 -26
  113. package/src/types/commands.ts +0 -716
  114. package/src/types/conditional_formatting.ts +0 -124
  115. package/src/types/env.ts +0 -13
  116. package/src/types/functions.ts +0 -35
  117. package/src/types/getters.ts +0 -103
  118. package/src/types/index.ts +0 -20
  119. package/src/types/misc.ts +0 -143
  120. package/src/types/rendering.ts +0 -41
  121. package/src/types/workbook_data.ts +0 -62
  122. package/tests/__mocks__/uuid.ts +0 -7
  123. package/tests/canvas.mock.ts +0 -34
  124. package/tests/components/__mocks__/content_editable_helper.ts +0 -79
  125. package/tests/components/__mocks__/scrollbar.ts +0 -18
  126. package/tests/components/__snapshots__/autocomplete_dropdown_test.ts.snap +0 -29
  127. package/tests/components/__snapshots__/bottom_bar_test.ts.snap +0 -75
  128. package/tests/components/__snapshots__/context_menu_test.ts.snap +0 -88
  129. package/tests/components/__snapshots__/grid_test.ts.snap +0 -60
  130. package/tests/components/__snapshots__/spreadsheet_test.ts.snap +0 -455
  131. package/tests/components/__snapshots__/top_bar_test.ts.snap +0 -705
  132. package/tests/components/autocomplete_dropdown_test.ts +0 -315
  133. package/tests/components/autofill_test.ts +0 -167
  134. package/tests/components/bottom_bar_test.ts +0 -262
  135. package/tests/components/chart_side_panel_test.ts +0 -123
  136. package/tests/components/composer_test.ts +0 -400
  137. package/tests/components/context_menu_test.ts +0 -825
  138. package/tests/components/grid_manipulation_test.ts +0 -163
  139. package/tests/components/grid_test.ts +0 -581
  140. package/tests/components/overlay_test.ts +0 -541
  141. package/tests/components/selection_input_test.ts +0 -259
  142. package/tests/components/side_panel_test.ts +0 -148
  143. package/tests/components/spreadsheet_test.ts +0 -194
  144. package/tests/components/top_bar_test.ts +0 -427
  145. package/tests/data_test.ts +0 -175
  146. package/tests/dom_helper.ts +0 -42
  147. package/tests/formulas/__snapshots__/compiler_test.ts.snap +0 -302
  148. package/tests/formulas/compiler_test.ts +0 -266
  149. package/tests/formulas/composer_tokenizer_test.ts +0 -137
  150. package/tests/formulas/expressions_test.ts +0 -57
  151. package/tests/formulas/formulas_test.ts +0 -80
  152. package/tests/formulas/normalize_test.ts +0 -82
  153. package/tests/formulas/parser_test.ts +0 -224
  154. package/tests/formulas/range_tokenizer_test.ts +0 -187
  155. package/tests/formulas/tokenizer_test.ts +0 -164
  156. package/tests/functions/arguments_test.ts +0 -141
  157. package/tests/functions/dates_test.ts +0 -1081
  158. package/tests/functions/functions_test.ts +0 -53
  159. package/tests/functions/helper_test.ts +0 -98
  160. package/tests/functions/module_database_test.ts +0 -311
  161. package/tests/functions/module_date_test.ts +0 -941
  162. package/tests/functions/module_info_test.ts +0 -139
  163. package/tests/functions/module_logical_test.ts +0 -369
  164. package/tests/functions/module_lookup_test.ts +0 -541
  165. package/tests/functions/module_math_test.ts +0 -2482
  166. package/tests/functions/module_operators_test.ts +0 -955
  167. package/tests/functions/module_statistical_test.ts +0 -2014
  168. package/tests/functions/module_text_test.ts +0 -667
  169. package/tests/helpers/coordinates_test.ts +0 -25
  170. package/tests/helpers/misc_test.ts +0 -95
  171. package/tests/helpers/numbers_test.ts +0 -196
  172. package/tests/helpers/zones_test.ts +0 -97
  173. package/tests/helpers.ts +0 -384
  174. package/tests/menu_items_registry_test.ts +0 -540
  175. package/tests/model/plugins/__snapshots__/chart_test.ts.snap +0 -90
  176. package/tests/model/plugins/chart_test.ts +0 -562
  177. package/tests/model_test.ts +0 -82
  178. package/tests/plugins/__snapshots__/conditional_formatting_test.ts.snap +0 -131
  179. package/tests/plugins/__snapshots__/renderer_test.ts.snap +0 -371
  180. package/tests/plugins/autofill_test.ts +0 -457
  181. package/tests/plugins/borders_test.ts +0 -295
  182. package/tests/plugins/clipboard_test.ts +0 -1180
  183. package/tests/plugins/conditional_formatting_test.ts +0 -1253
  184. package/tests/plugins/core_test.ts +0 -614
  185. package/tests/plugins/edition_test.ts +0 -100
  186. package/tests/plugins/evaluation_async_test.ts +0 -332
  187. package/tests/plugins/evaluation_dates_test.ts +0 -79
  188. package/tests/plugins/evaluation_test.ts +0 -901
  189. package/tests/plugins/figures_test.ts +0 -327
  190. package/tests/plugins/formatting_test.ts +0 -391
  191. package/tests/plugins/grid_manipulation_test.ts +0 -1366
  192. package/tests/plugins/highlight_test.ts +0 -413
  193. package/tests/plugins/history_test.ts +0 -142
  194. package/tests/plugins/import_export_test.ts +0 -276
  195. package/tests/plugins/merges_test.ts +0 -490
  196. package/tests/plugins/navigation_test.ts +0 -181
  197. package/tests/plugins/plugins/evaluation_test.ts +0 -111
  198. package/tests/plugins/renderer_test.ts +0 -598
  199. package/tests/plugins/resizing_test.ts +0 -152
  200. package/tests/plugins/selection_input_test.ts +0 -409
  201. package/tests/plugins/selection_test.ts +0 -442
  202. package/tests/plugins/sheets_test.ts +0 -643
  203. package/tests/plugins/style_test.ts +0 -90
  204. package/tsconfig.json +0 -22
@@ -1,1253 +0,0 @@
1
- import { toZone } from "../../src/helpers";
2
- import { Model } from "../../src/model";
3
- import { CommandResult } from "../../src/types";
4
- import "../canvas.mock";
5
- import { setInputValueAndTrigger, triggerMouseEvent } from "../dom_helper";
6
- import {
7
- createColorScale,
8
- createEqualCF,
9
- GridParent,
10
- makeTestFixture,
11
- mockUuidV4To,
12
- nextTick,
13
- target,
14
- } from "../helpers";
15
- jest.mock("../../src/helpers/uuid", () => require("../__mocks__/uuid"));
16
-
17
- let model: Model;
18
-
19
- beforeEach(() => {
20
- model = new Model();
21
- });
22
-
23
- describe("conditional format", () => {
24
- test("works", () => {
25
- model.dispatch("SET_VALUE", { xc: "A1", text: "1" });
26
- model.dispatch("SET_VALUE", { xc: "A2", text: "2" });
27
- model.dispatch("SET_VALUE", { xc: "A3", text: "3" });
28
- model.dispatch("SET_VALUE", { xc: "A4", text: "4" });
29
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
30
- cf: createEqualCF(["A1:A4"], "2", { fillColor: "#FF0000" }, "1"),
31
- sheet: model.getters.getActiveSheet(),
32
- });
33
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
34
- cf: createEqualCF(["A1:A4"], "4", { fillColor: "#0000FF" }, "2"),
35
- sheet: model.getters.getActiveSheet(),
36
- });
37
- expect(model.getters.getConditionalFormats()).toEqual([
38
- {
39
- rule: {
40
- values: ["2"],
41
- operator: "Equal",
42
- type: "CellIsRule",
43
- style: {
44
- fillColor: "#FF0000",
45
- },
46
- },
47
- id: "1",
48
- ranges: ["A1:A4"],
49
- },
50
- {
51
- rule: {
52
- values: ["4"],
53
- operator: "Equal",
54
- type: "CellIsRule",
55
- style: {
56
- fillColor: "#0000FF",
57
- },
58
- },
59
- id: "2",
60
- ranges: ["A1:A4"],
61
- },
62
- ]);
63
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
64
- expect(model.getters.getConditionalStyle("A2")).toEqual({ fillColor: "#FF0000" });
65
- expect(model.getters.getConditionalStyle("A3")).toBeUndefined();
66
- expect(model.getters.getConditionalStyle("A4")).toEqual({ fillColor: "#0000FF" });
67
- });
68
-
69
- test("Add conditional formating on inactive sheet", () => {
70
- model = new Model();
71
- model.dispatch("CREATE_SHEET", { id: "42" });
72
- const [activeSheet, sheet] = model.getters.getSheets();
73
- expect(sheet.id).not.toBe(model.getters.getActiveSheet());
74
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
75
- cf: createEqualCF(["A1:A4"], "4", { fillColor: "#0000FF" }, "2"),
76
- sheet: sheet.id,
77
- });
78
- model.dispatch("ACTIVATE_SHEET", {
79
- from: activeSheet.id,
80
- to: "42",
81
- });
82
- expect(model.getters.getConditionalFormats()).toEqual([
83
- {
84
- rule: {
85
- values: ["4"],
86
- operator: "Equal",
87
- type: "CellIsRule",
88
- style: {
89
- fillColor: "#0000FF",
90
- },
91
- },
92
- id: "2",
93
- ranges: ["A1:A4"],
94
- },
95
- ]);
96
- });
97
-
98
- test("remove a conditional format rule", () => {
99
- model.dispatch("SET_VALUE", { xc: "A1", text: "1" });
100
- model.dispatch("SET_VALUE", { xc: "A2", text: "2" });
101
- model.dispatch("SET_VALUE", { xc: "A3", text: "3" });
102
- model.dispatch("SET_VALUE", { xc: "A4", text: "4" });
103
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
104
- cf: createEqualCF(["A1:A4"], "2", { fillColor: "#FF0000" }, "1"),
105
- sheet: model.getters.getActiveSheet(),
106
- });
107
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
108
- cf: createEqualCF(["A1:A4"], "4", { fillColor: "#0000FF" }, "2"),
109
- sheet: model.getters.getActiveSheet(),
110
- });
111
- expect(model.getters.getConditionalFormats()).toEqual([
112
- {
113
- rule: {
114
- values: ["2"],
115
- operator: "Equal",
116
- type: "CellIsRule",
117
- style: {
118
- fillColor: "#FF0000",
119
- },
120
- },
121
- id: "1",
122
- ranges: ["A1:A4"],
123
- },
124
- {
125
- rule: {
126
- values: ["4"],
127
- operator: "Equal",
128
- type: "CellIsRule",
129
- style: {
130
- fillColor: "#0000FF",
131
- },
132
- },
133
- id: "2",
134
- ranges: ["A1:A4"],
135
- },
136
- ]);
137
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
138
- expect(model.getters.getConditionalStyle("A2")).toEqual({ fillColor: "#FF0000" });
139
- expect(model.getters.getConditionalStyle("A3")).toBeUndefined();
140
- expect(model.getters.getConditionalStyle("A4")).toEqual({ fillColor: "#0000FF" });
141
- model.dispatch("REMOVE_CONDITIONAL_FORMAT", {
142
- id: "2",
143
- sheet: model.getters.getActiveSheet(),
144
- });
145
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
146
- expect(model.getters.getConditionalStyle("A2")).toEqual({ fillColor: "#FF0000" });
147
- expect(model.getters.getConditionalStyle("A3")).toBeUndefined();
148
- expect(model.getters.getConditionalStyle("A4")).toBeUndefined();
149
- });
150
-
151
- test("works on multiple ranges", () => {
152
- model.dispatch("SET_VALUE", { xc: "A1", text: "1" });
153
- model.dispatch("SET_VALUE", { xc: "A2", text: "1" });
154
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
155
- cf: createEqualCF(["A1", "A2"], "1", { fillColor: "#FF0000" }, "1"),
156
- sheet: model.getters.getActiveSheet(),
157
- });
158
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#FF0000" });
159
- expect(model.getters.getConditionalStyle("A2")).toEqual({ fillColor: "#FF0000" });
160
- });
161
-
162
- test("can be undo/redo", () => {
163
- model.dispatch("SET_VALUE", { xc: "A1", text: "1" });
164
- model.dispatch("SET_VALUE", { xc: "A2", text: "1" });
165
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
166
- cf: createEqualCF(["A1", "A2"], "1", { fillColor: "#FF0000" }, "1"),
167
- sheet: model.getters.getActiveSheet(),
168
- });
169
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#FF0000" });
170
- expect(model.getters.getConditionalStyle("A2")).toEqual({ fillColor: "#FF0000" });
171
-
172
- model.dispatch("UNDO");
173
-
174
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
175
- expect(model.getters.getConditionalStyle("A2")).toBeUndefined();
176
-
177
- model.dispatch("REDO");
178
-
179
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#FF0000" });
180
- expect(model.getters.getConditionalStyle("A2")).toEqual({ fillColor: "#FF0000" });
181
- });
182
-
183
- test("Still correct after ADD_COLUMNS and UNDO/REDO", () => {
184
- const sheet = model.getters.getActiveSheet();
185
- model.dispatch("SET_VALUE", { xc: "B1", text: "1" });
186
- model.dispatch("SET_VALUE", { xc: "B2", text: "1" });
187
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
188
- cf: createEqualCF(["B1", "B2"], "1", { fillColor: "#FF0000" }, "1"),
189
- sheet,
190
- });
191
- expect(model.getters.getConditionalStyle("B1")).toEqual({ fillColor: "#FF0000" });
192
- expect(model.getters.getConditionalStyle("B2")).toEqual({ fillColor: "#FF0000" });
193
- model.dispatch("ADD_COLUMNS", { sheet, column: 0, position: "after", quantity: 1 });
194
- expect(model.getters.getConditionalStyle("B1")).toBeUndefined();
195
- expect(model.getters.getConditionalStyle("B2")).toBeUndefined();
196
- expect(model.getters.getConditionalStyle("C1")).toEqual({ fillColor: "#FF0000" });
197
- expect(model.getters.getConditionalStyle("C2")).toEqual({ fillColor: "#FF0000" });
198
-
199
- model.dispatch("UNDO");
200
- expect(model.getters.getConditionalStyle("B1")).toEqual({ fillColor: "#FF0000" });
201
- expect(model.getters.getConditionalStyle("B2")).toEqual({ fillColor: "#FF0000" });
202
- expect(model.getters.getConditionalStyle("C1")).toBeUndefined();
203
- expect(model.getters.getConditionalStyle("C2")).toBeUndefined();
204
-
205
- model.dispatch("REDO");
206
- expect(model.getters.getConditionalStyle("B1")).toBeUndefined();
207
- expect(model.getters.getConditionalStyle("B2")).toBeUndefined();
208
- expect(model.getters.getConditionalStyle("C1")).toEqual({ fillColor: "#FF0000" });
209
- expect(model.getters.getConditionalStyle("C2")).toEqual({ fillColor: "#FF0000" });
210
- });
211
-
212
- test("is saved/restored", () => {
213
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
214
- cf: createEqualCF(["A1:A4"], "2", { fillColor: "#FF0000" }, "1"),
215
- sheet: model.getters.getActiveSheet(),
216
- });
217
- const workbookData = model.exportData();
218
- const newModel = new Model(workbookData);
219
- expect(newModel.getters.getConditionalFormats()).toBe(model.getters.getConditionalFormats());
220
- });
221
-
222
- test("works after value update", () => {
223
- model.dispatch("SET_VALUE", { xc: "A1", text: "1" });
224
- model.dispatch("SET_VALUE", { xc: "A2", text: "2" });
225
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
226
- cf: createEqualCF(["A1"], "2", { fillColor: "#FF0000" }, "1"),
227
- sheet: model.getters.getActiveSheet(),
228
- });
229
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
230
- model.dispatch("SET_VALUE", { xc: "A1", text: "2" });
231
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#FF0000" });
232
- model.dispatch("SET_VALUE", { xc: "A1", text: "1" });
233
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
234
- model.dispatch("SET_VALUE", { xc: "A1", text: "=A2" });
235
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#FF0000" });
236
- });
237
-
238
- test("works when cells are in error", () => {
239
- model.dispatch("SET_VALUE", { xc: "A1", text: "2" });
240
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
241
- cf: createEqualCF(["A1"], "2", { fillColor: "#FF0000" }, "1"),
242
- sheet: model.getters.getActiveSheet(),
243
- });
244
- model.dispatch("SET_VALUE", { xc: "A1", text: "=BLA" });
245
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
246
- });
247
-
248
- test("multiple conditional formats for one cell", () => {
249
- model.dispatch("SET_VALUE", { xc: "A1", text: "2" });
250
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
251
- cf: createEqualCF(["A1"], "2", { fillColor: "#FF0000" }, "1"),
252
- sheet: model.getters.getActiveSheet(),
253
- });
254
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
255
- cf: createEqualCF(["A1"], "2", { textColor: "#445566" }, "2"),
256
- sheet: model.getters.getActiveSheet(),
257
- });
258
- expect(model.getters.getConditionalStyle("A1")).toEqual({
259
- fillColor: "#FF0000",
260
- textColor: "#445566",
261
- });
262
- });
263
-
264
- test("multiple conditional formats with same style", () => {
265
- model.dispatch("SET_VALUE", { xc: "A1", text: "2" });
266
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
267
- cf: createEqualCF(["A1"], "2", { fillColor: "#FF0000" }, "1"),
268
- sheet: model.getters.getActiveSheet(),
269
- });
270
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
271
- cf: createEqualCF(["A1"], "2", { fillColor: "#FF0000" }, "2"),
272
- sheet: model.getters.getActiveSheet(),
273
- });
274
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#FF0000" });
275
- });
276
-
277
- test.skip("multiple conditional formats using stopIfTrue flag", () => {
278
- model.dispatch("SET_VALUE", { xc: "A1", text: "2" });
279
-
280
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
281
- cf: {
282
- ranges: ["A1"],
283
- rule: {
284
- values: ["2"],
285
- operator: "Equal",
286
- type: "CellIsRule",
287
- style: { fillColor: "#FF0000" },
288
- },
289
- id: "1",
290
- stopIfTrue: true,
291
- },
292
- sheet: model.getters.getActiveSheet(),
293
- });
294
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
295
- cf: createEqualCF(["A1"], "2", { fillColor: "#445566" }, "2"),
296
- sheet: model.getters.getActiveSheet(),
297
- });
298
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#FF0000" });
299
- });
300
-
301
- test("Set conditionalFormat on empty cell", () => {
302
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
303
- cf: createEqualCF(["A1"], "", { fillColor: "#FF0000" }, "1"),
304
- sheet: model.getters.getActiveSheet(),
305
- });
306
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#FF0000" });
307
- });
308
-
309
- describe("Grid Manipulation", () => {
310
- const rule = {
311
- values: ["42"],
312
- operator: "Equal",
313
- type: "CellIsRule",
314
- style: { fillColor: "orange" },
315
- };
316
- test("On row deletion", () => {
317
- model = new Model({
318
- sheets: [
319
- {
320
- colNumber: 7,
321
- rowNumber: 4,
322
- cells: {
323
- C3: { content: "42" },
324
- },
325
- conditionalFormats: [
326
- { id: "1", ranges: ["A1:A1"], rule },
327
- { id: "2", ranges: ["B2:B2"], rule },
328
- { id: "3", ranges: ["C3:C3"], rule },
329
- { id: "4", ranges: ["D1:D2"], rule },
330
- { id: "5", ranges: ["E2:E3"], rule },
331
- { id: "6", ranges: ["F1:F3"], rule },
332
- { id: "7", ranges: ["G1:G4"], rule },
333
- ],
334
- },
335
- ],
336
- });
337
- model.dispatch("REMOVE_ROWS", {
338
- sheet: model.getters.getActiveSheet(),
339
- rows: [1, 3],
340
- });
341
- expect(model.getters.getConditionalFormats()).toEqual([
342
- { id: "1", ranges: ["A1:A1"], rule },
343
- { id: "3", ranges: ["C2:C2"], rule },
344
- { id: "4", ranges: ["D1:D1"], rule },
345
- { id: "5", ranges: ["E2:E2"], rule },
346
- { id: "6", ranges: ["F1:F2"], rule },
347
- { id: "7", ranges: ["G1:G2"], rule },
348
- ]);
349
- expect(model.getters.getConditionalStyle("B2")).toBeUndefined();
350
- expect(model.getters.getConditionalStyle("C2")!.fillColor).toBe("orange");
351
- expect(model.getters.getConditionalStyle("C3")).toBeUndefined();
352
- });
353
- test("On column deletion", () => {
354
- model = new Model({
355
- sheets: [
356
- {
357
- colNumber: 4,
358
- rowNumber: 7,
359
- cells: {
360
- C3: { content: "42" },
361
- },
362
- conditionalFormats: [
363
- { id: "1", ranges: ["A1:A1"], rule },
364
- { id: "2", ranges: ["B2:B2"], rule },
365
- { id: "3", ranges: ["C3:C3"], rule },
366
- { id: "4", ranges: ["A4:B4"], rule },
367
- { id: "5", ranges: ["B5:C5"], rule },
368
- { id: "6", ranges: ["A6:C6"], rule },
369
- { id: "7", ranges: ["A7:D7"], rule },
370
- ],
371
- },
372
- ],
373
- });
374
- model.dispatch("REMOVE_COLUMNS", {
375
- sheet: model.getters.getActiveSheet(),
376
- columns: [1, 3],
377
- });
378
- expect(model.getters.getConditionalFormats()).toEqual([
379
- { id: "1", ranges: ["A1:A1"], rule },
380
- { id: "3", ranges: ["B3:B3"], rule },
381
- { id: "4", ranges: ["A4:A4"], rule },
382
- { id: "5", ranges: ["B5:B5"], rule },
383
- { id: "6", ranges: ["A6:B6"], rule },
384
- { id: "7", ranges: ["A7:B7"], rule },
385
- ]);
386
- expect(model.getters.getConditionalStyle("B2")).toBeUndefined();
387
- expect(model.getters.getConditionalStyle("B3")!.fillColor).toBe("orange");
388
- expect(model.getters.getConditionalStyle("C3")).toBeUndefined();
389
- });
390
- test("On column addition", () => {
391
- model = new Model({
392
- sheets: [
393
- {
394
- colNumber: 3,
395
- rowNumber: 4,
396
- cells: {
397
- B4: { content: "42" },
398
- },
399
- conditionalFormats: [
400
- { id: "1", ranges: ["A1:C1"], rule },
401
- { id: "2", ranges: ["A2:B2"], rule },
402
- { id: "3", ranges: ["B3:C3"], rule },
403
- { id: "4", ranges: ["B4:B4"], rule },
404
- ],
405
- },
406
- ],
407
- });
408
- model.dispatch("ADD_COLUMNS", {
409
- sheet: model.getters.getActiveSheet(),
410
- column: 1,
411
- position: "before",
412
- quantity: 1,
413
- });
414
- model.dispatch("ADD_COLUMNS", {
415
- sheet: model.getters.getActiveSheet(),
416
- column: 2,
417
- position: "after",
418
- quantity: 2,
419
- });
420
- expect(model.getters.getConditionalFormats()).toEqual([
421
- { id: "1", ranges: ["A1:F1"], rule },
422
- { id: "2", ranges: ["A2:C2"], rule },
423
- { id: "3", ranges: ["C3:F3"], rule },
424
- { id: "4", ranges: ["C4:C4"], rule },
425
- ]);
426
- expect(model.getters.getConditionalStyle("B4")).toBeUndefined();
427
- expect(model.getters.getConditionalStyle("C4")!.fillColor).toBe("orange");
428
- });
429
- test("On row addition", () => {
430
- model = new Model({
431
- sheets: [
432
- {
433
- colNumber: 4,
434
- rowNumber: 3,
435
- cells: {
436
- D2: { content: "42" },
437
- },
438
- conditionalFormats: [
439
- { id: "1", ranges: ["A1:A3"], rule },
440
- { id: "2", ranges: ["B1:B2"], rule },
441
- { id: "3", ranges: ["C2:C3"], rule },
442
- { id: "4", ranges: ["D2:D2"], rule },
443
- ],
444
- },
445
- ],
446
- });
447
- model.dispatch("ADD_ROWS", {
448
- sheet: model.getters.getActiveSheet(),
449
- row: 1,
450
- position: "before",
451
- quantity: 1,
452
- });
453
- model.dispatch("ADD_ROWS", {
454
- sheet: model.getters.getActiveSheet(),
455
- row: 2,
456
- position: "after",
457
- quantity: 2,
458
- });
459
- expect(model.getters.getConditionalFormats()).toEqual([
460
- { id: "1", ranges: ["A1:A6"], rule },
461
- { id: "2", ranges: ["B1:B3"], rule },
462
- { id: "3", ranges: ["C3:C6"], rule },
463
- { id: "4", ranges: ["D3:D3"], rule },
464
- ]);
465
- expect(model.getters.getConditionalStyle("D2")).toBeUndefined();
466
- expect(model.getters.getConditionalStyle("D3")!.fillColor).toBe("orange");
467
- });
468
- });
469
- });
470
-
471
- describe("conditional formats types", () => {
472
- describe("CellIs condition", () => {
473
- test("Operator BeginsWith", () => {
474
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
475
- cf: {
476
- rule: {
477
- type: "CellIsRule",
478
- operator: "BeginsWith",
479
- values: ["qsdf"],
480
- style: { fillColor: "#ff0f0f" },
481
- },
482
- ranges: ["A1"],
483
- id: "11",
484
- },
485
- sheet: model.getters.getActiveSheet(),
486
- });
487
-
488
- model.dispatch("SET_VALUE", { xc: "A1", text: "aaa" });
489
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
490
-
491
- model.dispatch("SET_VALUE", { xc: "A1", text: "qsdfmlkqjsdf" });
492
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff0f0f" });
493
- });
494
-
495
- test("Operator Between", () => {
496
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
497
- cf: {
498
- rule: {
499
- type: "CellIsRule",
500
- operator: "Between",
501
- values: ["1", "3"],
502
- style: { fillColor: "#ff0f0f" },
503
- },
504
- ranges: ["A1"],
505
- id: "11",
506
- },
507
- sheet: model.getters.getActiveSheet(),
508
- });
509
-
510
- model.dispatch("SET_VALUE", { xc: "A1", text: "0" });
511
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
512
-
513
- model.dispatch("SET_VALUE", { xc: "A1", text: "1" });
514
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff0f0f" });
515
-
516
- model.dispatch("SET_VALUE", { xc: "A1", text: "1.5" });
517
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff0f0f" });
518
-
519
- model.dispatch("SET_VALUE", { xc: "A1", text: "3" });
520
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff0f0f" });
521
-
522
- model.dispatch("SET_VALUE", { xc: "A1", text: "3.5" });
523
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
524
- });
525
-
526
- test("Operator ContainsText", () => {
527
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
528
- cf: {
529
- rule: {
530
- type: "CellIsRule",
531
- operator: "ContainsText",
532
- values: ["abc"],
533
- style: { fillColor: "#ff0f0f" },
534
- },
535
- ranges: ["A1"],
536
- id: "11",
537
- },
538
- sheet: model.getters.getActiveSheet(),
539
- });
540
- model.dispatch("SET_VALUE", { xc: "A1", text: "hello" });
541
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
542
-
543
- model.dispatch("SET_VALUE", { xc: "A1", text: "helabclo" });
544
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff0f0f" });
545
- });
546
-
547
- test("Operator EndsWith", () => {
548
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
549
- cf: {
550
- rule: {
551
- type: "CellIsRule",
552
- operator: "EndsWith",
553
- values: ["qsdf"],
554
- style: { fillColor: "#ff0f0f" },
555
- },
556
- ranges: ["A1"],
557
- id: "11",
558
- },
559
- sheet: model.getters.getActiveSheet(),
560
- });
561
-
562
- model.dispatch("SET_VALUE", { xc: "A1", text: "hello" });
563
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
564
-
565
- model.dispatch("SET_VALUE", { xc: "A1", text: "helloqsdf" });
566
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff0f0f" });
567
- });
568
-
569
- test("Operator GreaterThan", () => {
570
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
571
- cf: {
572
- rule: {
573
- type: "CellIsRule",
574
- operator: "GreaterThan",
575
- values: ["12"],
576
- style: { fillColor: "#ff0f0f" },
577
- },
578
- ranges: ["A1"],
579
- id: "11",
580
- },
581
- sheet: model.getters.getActiveSheet(),
582
- });
583
- model.dispatch("SET_VALUE", { xc: "A1", text: "5" });
584
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
585
-
586
- model.dispatch("SET_VALUE", { xc: "A1", text: "12" });
587
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
588
-
589
- model.dispatch("SET_VALUE", { xc: "A1", text: "13" });
590
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff0f0f" });
591
- });
592
-
593
- test("Operator GreaterThanOrEqual", () => {
594
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
595
- cf: {
596
- rule: {
597
- type: "CellIsRule",
598
- operator: "GreaterThanOrEqual",
599
- values: ["12"],
600
- style: { fillColor: "#ff0f0f" },
601
- },
602
- ranges: ["A1"],
603
- id: "11",
604
- },
605
- sheet: model.getters.getActiveSheet(),
606
- });
607
-
608
- model.dispatch("SET_VALUE", { xc: "A1", text: "5" });
609
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
610
-
611
- model.dispatch("SET_VALUE", { xc: "A1", text: "12" });
612
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff0f0f" });
613
-
614
- model.dispatch("SET_VALUE", { xc: "A1", text: "13" });
615
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff0f0f" });
616
- });
617
-
618
- test("Operator LessThan", () => {
619
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
620
- cf: {
621
- rule: {
622
- type: "CellIsRule",
623
- operator: "LessThan",
624
- values: ["10"],
625
- style: { fillColor: "#ff0f0f" },
626
- },
627
- ranges: ["A1"],
628
- id: "11",
629
- },
630
- sheet: model.getters.getActiveSheet(),
631
- });
632
-
633
- model.dispatch("SET_VALUE", { xc: "A1", text: "11" });
634
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
635
-
636
- model.dispatch("SET_VALUE", { xc: "A1", text: "10" });
637
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
638
-
639
- model.dispatch("SET_VALUE", { xc: "A1", text: "9" });
640
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff0f0f" });
641
- });
642
-
643
- test("Operator LessThanOrEqual", () => {
644
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
645
- cf: {
646
- rule: {
647
- type: "CellIsRule",
648
- operator: "LessThanOrEqual",
649
- values: ["10"],
650
- style: { fillColor: "#ff0f0f" },
651
- },
652
- ranges: ["A1"],
653
- id: "11",
654
- },
655
- sheet: model.getters.getActiveSheet(),
656
- });
657
-
658
- model.dispatch("SET_VALUE", { xc: "A1", text: "11" });
659
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
660
-
661
- model.dispatch("SET_VALUE", { xc: "A1", text: "10" });
662
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff0f0f" });
663
-
664
- model.dispatch("SET_VALUE", { xc: "A1", text: "9" });
665
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff0f0f" });
666
- });
667
-
668
- test("Operator NotBetween", () => {
669
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
670
- cf: {
671
- rule: {
672
- type: "CellIsRule",
673
- operator: "NotBetween",
674
- values: ["5", "10"],
675
- style: { fillColor: "#ff0f0f" },
676
- },
677
- ranges: ["A1"],
678
- id: "11",
679
- },
680
- sheet: model.getters.getActiveSheet(),
681
- });
682
-
683
- model.dispatch("SET_VALUE", { xc: "A1", text: "4" });
684
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff0f0f" });
685
-
686
- model.dispatch("SET_VALUE", { xc: "A1", text: "0" });
687
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff0f0f" });
688
-
689
- model.dispatch("SET_VALUE", { xc: "A1", text: "5" });
690
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
691
-
692
- model.dispatch("SET_VALUE", { xc: "A1", text: "10" });
693
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
694
-
695
- model.dispatch("SET_VALUE", { xc: "A1", text: "10.1" });
696
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff0f0f" });
697
- });
698
-
699
- test("Operator NotContains", () => {
700
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
701
- cf: {
702
- rule: {
703
- type: "CellIsRule",
704
- operator: "NotContains",
705
- values: ["qsdf"],
706
- style: { fillColor: "#ff0f0f" },
707
- },
708
- ranges: ["A1"],
709
- id: "11",
710
- },
711
- sheet: model.getters.getActiveSheet(),
712
- });
713
-
714
- model.dispatch("SET_VALUE", { xc: "A1", text: "hellqsdfo" });
715
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
716
-
717
- model.dispatch("SET_VALUE", { xc: "A1", text: "hello" });
718
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff0f0f" });
719
- });
720
-
721
- test("Operator NotEqual", () => {
722
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
723
- cf: {
724
- rule: {
725
- type: "CellIsRule",
726
- operator: "NotEqual",
727
- values: ["qsdf"],
728
- style: { fillColor: "#ff0f0f" },
729
- },
730
- ranges: ["A1"],
731
- id: "11",
732
- },
733
- sheet: model.getters.getActiveSheet(),
734
- });
735
-
736
- model.dispatch("SET_VALUE", { xc: "A1", text: "hellqsdfo" });
737
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff0f0f" });
738
-
739
- model.dispatch("SET_VALUE", { xc: "A1", text: "hello" });
740
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff0f0f" });
741
-
742
- model.dispatch("SET_VALUE", { xc: "A1", text: "qsdf" });
743
- expect(model.getters.getConditionalStyle("A1")).toBeUndefined();
744
- });
745
- });
746
-
747
- describe("color scale", () => {
748
- test("1 point, value scale", () => {
749
- model.dispatch("SET_VALUE", { xc: "A1", text: "10" });
750
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
751
- cf: createColorScale(
752
- "1",
753
- ["A1"],
754
- { type: "value", color: 0xff00ff },
755
- { type: "value", color: 0x123456 }
756
- ),
757
- sheet: model.getters.getActiveSheet(),
758
- });
759
- expect(model.getters.getConditionalStyle("A1")).toEqual(undefined);
760
- });
761
-
762
- test("2 points, value scale", () => {
763
- model.dispatch("SET_VALUE", { xc: "A1", text: "10" });
764
- model.dispatch("SET_VALUE", { xc: "A2", text: "11" });
765
- model.dispatch("SET_VALUE", { xc: "A3", text: "17" });
766
- model.dispatch("SET_VALUE", { xc: "A4", text: "19" });
767
- model.dispatch("SET_VALUE", { xc: "A5", text: "20" });
768
-
769
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
770
- cf: createColorScale(
771
- "1",
772
- ["A1:A5"],
773
- { type: "value", color: 0xff00ff },
774
- { type: "value", color: 0x123456 }
775
- ),
776
- sheet: model.getters.getActiveSheet(),
777
- });
778
-
779
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff00ff" });
780
- expect(model.getters.getConditionalStyle("A2")).toEqual({ fillColor: "#e705ee" });
781
- expect(model.getters.getConditionalStyle("A3")).toEqual({ fillColor: "#592489" });
782
- expect(model.getters.getConditionalStyle("A4")).toEqual({ fillColor: "#2a2f67" });
783
- expect(model.getters.getConditionalStyle("A5")).toEqual({ fillColor: "#123456" });
784
- });
785
-
786
- test("2 points, value scale with other min and max", () => {
787
- model.dispatch("SET_VALUE", { xc: "A1", text: "100" });
788
- model.dispatch("SET_VALUE", { xc: "A2", text: "110" });
789
- model.dispatch("SET_VALUE", { xc: "A3", text: "170" });
790
- model.dispatch("SET_VALUE", { xc: "A4", text: "190" });
791
- model.dispatch("SET_VALUE", { xc: "A5", text: "200" });
792
-
793
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
794
- cf: createColorScale(
795
- "1",
796
- ["A1:A5"],
797
- { type: "value", color: 0xff00ff },
798
- { type: "value", color: 0x123456 }
799
- ),
800
- sheet: model.getters.getActiveSheet(),
801
- });
802
-
803
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff00ff" });
804
- expect(model.getters.getConditionalStyle("A2")).toEqual({ fillColor: "#e705ee" });
805
- expect(model.getters.getConditionalStyle("A3")).toEqual({ fillColor: "#592489" });
806
- expect(model.getters.getConditionalStyle("A4")).toEqual({ fillColor: "#2a2f67" });
807
- expect(model.getters.getConditionalStyle("A5")).toEqual({ fillColor: "#123456" });
808
- });
809
-
810
- test("2 points, value scale with minimum = 0", () => {
811
- model.dispatch("SET_VALUE", { xc: "A1", text: "0" });
812
- model.dispatch("SET_VALUE", { xc: "A2", text: "1" });
813
- model.dispatch("SET_VALUE", { xc: "A3", text: "7" });
814
- model.dispatch("SET_VALUE", { xc: "A4", text: "9" });
815
- model.dispatch("SET_VALUE", { xc: "A5", text: "10" });
816
-
817
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
818
- cf: createColorScale(
819
- "1",
820
- ["A1:A5"],
821
- { type: "value", color: 0xff00ff },
822
- { type: "value", color: 0x123456 }
823
- ),
824
- sheet: model.getters.getActiveSheet(),
825
- });
826
-
827
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#ff00ff" });
828
- expect(model.getters.getConditionalStyle("A2")).toEqual({ fillColor: "#e705ee" });
829
- expect(model.getters.getConditionalStyle("A3")).toEqual({ fillColor: "#592489" });
830
- expect(model.getters.getConditionalStyle("A4")).toEqual({ fillColor: "#2a2f67" });
831
- expect(model.getters.getConditionalStyle("A5")).toEqual({ fillColor: "#123456" });
832
- });
833
-
834
- test("2 points, value scale with any value 0", () => {
835
- model.dispatch("SET_VALUE", { xc: "A1", text: "0" });
836
- model.dispatch("SET_VALUE", { xc: "A2", text: "-5" });
837
- model.dispatch("SET_VALUE", { xc: "A3", text: "5" });
838
-
839
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
840
- cf: createColorScale(
841
- "1",
842
- ["A1:A5"],
843
- { type: "value", color: 0xff0000 },
844
- { type: "value", color: 0x00ff00 }
845
- ),
846
- sheet: model.getters.getActiveSheet(),
847
- });
848
-
849
- expect(model.getters.getConditionalStyle("A1")).toEqual({ fillColor: "#808000" });
850
- expect(model.getters.getConditionalStyle("A2")).toEqual({ fillColor: "#ff0000" });
851
- expect(model.getters.getConditionalStyle("A3")).toEqual({ fillColor: "#00ff00" });
852
- });
853
-
854
- test("2 points, value scale with same min/max", () => {
855
- model.dispatch("SET_VALUE", { xc: "A1", text: "10" });
856
- model.dispatch("SET_VALUE", { xc: "A2", text: "10" });
857
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
858
- cf: createColorScale(
859
- "1",
860
- ["A1:A2"],
861
- { type: "value", color: 0xff00ff },
862
- { type: "value", color: 0x123456 }
863
- ),
864
- sheet: model.getters.getActiveSheet(),
865
- });
866
-
867
- expect(model.getters.getConditionalStyle("A1")).toEqual(undefined);
868
- expect(model.getters.getConditionalStyle("A2")).toEqual(undefined);
869
- });
870
-
871
- test("async values do not crash the evaluation", () => {
872
- model.dispatch("SET_VALUE", { xc: "A1", text: "=wait(100)" });
873
- model.dispatch("SET_VALUE", { xc: "A2", text: "110" });
874
-
875
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
876
- cf: createColorScale(
877
- "1",
878
- ["A1:A2"],
879
- { type: "value", color: 0xff00ff },
880
- { type: "value", color: 0x123456 }
881
- ),
882
- sheet: model.getters.getActiveSheet(),
883
- });
884
- expect(true).toBeTruthy(); // no error
885
- });
886
- });
887
- describe("icon scale", () => {});
888
- });
889
-
890
- describe("UI of conditional formats", () => {
891
- let fixture: HTMLElement;
892
- let parent: GridParent;
893
-
894
- beforeEach(async () => {
895
- fixture = makeTestFixture();
896
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
897
- cf: createEqualCF(["A1:A2"], "2", { fillColor: "#FF0000" }, "1"),
898
- sheet: model.getters.getActiveSheet(),
899
- });
900
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
901
- cf: createColorScale(
902
- "2",
903
- ["B1:B5"],
904
- { type: "value", color: 0xff00ff },
905
- { type: "value", color: 0x123456 }
906
- ),
907
- sheet: model.getters.getActiveSheet(),
908
- });
909
- parent = new GridParent(model);
910
- await parent.mount(fixture);
911
-
912
- parent.env.openSidePanel("ConditionalFormatting");
913
- await nextTick();
914
- });
915
-
916
- afterEach(() => {
917
- fixture.remove();
918
- parent.destroy();
919
- });
920
-
921
- const selectors = {
922
- listPreview: ".o-cf .o-cf-preview",
923
- ruleEditor: {
924
- range: ".o-cf .o-cf-ruleEditor .o-cf-range input",
925
- editor: {
926
- operatorInput: ".o-cf .o-cf-ruleEditor .o-cf-editor .o-cell-is-operator",
927
- valueInput: ".o-cf .o-cf-ruleEditor .o-cf-editor .o-cell-is-value",
928
- bold: ".o-cf .o-cf-ruleEditor .o-cf-editor .o-tools div.o-tool[title='Bold']",
929
- italic: ".o-cf .o-cf-ruleEditor .o-cf-editor .o-tools div.o-tool[title='Italic']",
930
- strikethrough:
931
- ".o-cf .o-cf-ruleEditor .o-cf-editor .o-tools div.o-tool[title='Strikethrough']",
932
- colorDropdown:
933
- ".o-cf .o-cf-ruleEditor .o-cf-editor .o-tools .o-tool.o-dropdown.o-with-color span",
934
- },
935
- },
936
- previewImage: ".o-cf-preview-image",
937
- description: {
938
- ruletype: {
939
- rule: ".o-cf-preview-description-rule",
940
- values: ".o-cf-preview-description-values",
941
- },
942
- range: ".o-cf-preview-range",
943
- },
944
- colorScaleEditor: {
945
- minColor: ".o-threshold-minimum .o-tool.o-dropdown.o-with-color span",
946
- minType: ".o-threshold-minimum > select",
947
- minValue: ".o-threshold-minimum .o-threshold-value",
948
- maxColor: ".o-threshold-maximum .o-tool.o-dropdown.o-with-color span",
949
- maxType: ".o-threshold-maximum > select",
950
- maxValue: ".o-threshold-maximum .o-threshold-value",
951
- colorPickerBlue: ".o-color-picker div[data-color='#0000ff']",
952
- colorPickerYellow: ".o-color-picker div[data-color='#ffff00']",
953
- },
954
- cfTabSelector: ".o-cf-type-selector .o-cf-type-tab",
955
- buttonSave: ".o-sidePanelButtons .o-cf-save",
956
- buttonDelete: ".o-cf-delete-button",
957
- buttonAdd: ".o-cf-add",
958
- closePanel: ".o-sidePanelClose",
959
- };
960
-
961
- test("simple snapshot", () => {
962
- expect(fixture.querySelector(".o-sidePanel")!).toMatchSnapshot();
963
- });
964
-
965
- test("the list of CF has a correct preview", () => {
966
- // check the html of the list (especially the colors)
967
- let previews = document.querySelectorAll(selectors.listPreview);
968
- expect(previews).toHaveLength(2);
969
-
970
- // --> should be the style for CellIsRule
971
- expect(previews[0].querySelector(selectors.description.ruletype.rule)!.textContent).toBe(
972
- "Is equal to"
973
- );
974
- expect(previews[0].querySelector(selectors.description.ruletype.values)!.textContent).toBe("2");
975
- expect(previews[0].querySelector(selectors.description.range)!.textContent).toBe("A1:A2");
976
- expect(
977
- window.getComputedStyle(previews[0].querySelector(selectors.previewImage)!).backgroundColor
978
- ).toBe("rgb(255, 0, 0)");
979
-
980
- // --> should be a nothing of color gradient for ColorScaleRule
981
- expect(previews[1].querySelector(selectors.description.range)!.textContent).toBe("B1:B5");
982
- expect(
983
- window.getComputedStyle(previews[1].querySelector(selectors.previewImage)!).backgroundColor
984
- ).toBe("");
985
- // TODO VSC: see how we can test the gradient background image
986
- });
987
-
988
- test("can edit an existing CellIsRule", async () => {
989
- triggerMouseEvent(document.querySelectorAll(selectors.listPreview)[0], "click");
990
- await nextTick();
991
-
992
- // change every value
993
- setInputValueAndTrigger(selectors.ruleEditor.range, "A1:A3", "change");
994
- setInputValueAndTrigger(selectors.ruleEditor.range, "A1:A3", "input");
995
- setInputValueAndTrigger(selectors.ruleEditor.editor.operatorInput, "BeginsWith", "change");
996
- setInputValueAndTrigger(selectors.ruleEditor.editor.valueInput, "3", "input");
997
-
998
- triggerMouseEvent(selectors.ruleEditor.editor.bold, "click");
999
- triggerMouseEvent(selectors.ruleEditor.editor.italic, "click");
1000
- triggerMouseEvent(selectors.ruleEditor.editor.strikethrough, "click");
1001
-
1002
- parent.env.dispatch = jest.fn((command) => ({ status: "SUCCESS" } as CommandResult));
1003
- // click save
1004
- triggerMouseEvent(selectors.buttonSave, "click");
1005
- await nextTick();
1006
-
1007
- expect(parent.env.dispatch).toHaveBeenCalledWith("ADD_CONDITIONAL_FORMAT", {
1008
- cf: {
1009
- id: "1",
1010
- ranges: ["A1:A3"],
1011
- rule: {
1012
- operator: "BeginsWith",
1013
- stopIfTrue: false,
1014
- style: { bold: true, fillColor: "#FF0000", italic: true, strikethrough: true },
1015
- type: "CellIsRule",
1016
- values: ["3", ""],
1017
- },
1018
- },
1019
- sheet: model.getters.getActiveSheet(),
1020
- });
1021
- });
1022
-
1023
- test("the preview should be bold when the rule is bold", async () => {
1024
- parent.env.dispatch = jest.fn((command) => ({ status: "SUCCESS" } as CommandResult));
1025
-
1026
- model.dispatch("ADD_CONDITIONAL_FORMAT", {
1027
- cf: createEqualCF(["C1:C5"], "2", { bold: true, fillColor: "#ff0000" }, "99"),
1028
- sheet: model.getters.getActiveSheet(),
1029
- });
1030
-
1031
- await nextTick();
1032
-
1033
- let previews = document.querySelectorAll(selectors.listPreview);
1034
- let line = previews[2].querySelector(selectors.previewImage);
1035
- expect(line!.getAttribute("style")).toMatch("font-weight:bold;");
1036
- });
1037
-
1038
- test("can edit an existing ColorScaleRule", async () => {
1039
- triggerMouseEvent(document.querySelectorAll(selectors.listPreview)[1], "click");
1040
- await nextTick();
1041
- // change every value
1042
- setInputValueAndTrigger(selectors.ruleEditor.range, "B2:B5", "change");
1043
-
1044
- triggerMouseEvent(selectors.colorScaleEditor.minColor, "click");
1045
- await nextTick();
1046
- triggerMouseEvent(selectors.colorScaleEditor.colorPickerBlue, "click");
1047
- triggerMouseEvent(selectors.colorScaleEditor.maxColor, "click");
1048
- await nextTick();
1049
- triggerMouseEvent(selectors.colorScaleEditor.colorPickerYellow, "click");
1050
-
1051
- setInputValueAndTrigger(selectors.colorScaleEditor.minValue, "33", "input");
1052
-
1053
- parent.env.dispatch = jest.fn((command) => ({ status: "SUCCESS" } as CommandResult));
1054
- // click save
1055
- triggerMouseEvent(selectors.buttonSave, "click");
1056
- await nextTick();
1057
-
1058
- expect(parent.env.dispatch).toHaveBeenCalledWith("ADD_CONDITIONAL_FORMAT", {
1059
- cf: {
1060
- id: "2",
1061
- ranges: ["B2:B5"],
1062
- rule: {
1063
- maximum: {
1064
- color: 0xffff00,
1065
- type: "value",
1066
- },
1067
- midpoint: undefined,
1068
- minimum: {
1069
- color: 0x0000ff,
1070
- type: "value",
1071
- value: "33",
1072
- },
1073
- type: "ColorScaleRule",
1074
- },
1075
- },
1076
- sheet: model.getters.getActiveSheet(),
1077
- });
1078
- });
1079
-
1080
- test("toggle color-picker", async () => {
1081
- triggerMouseEvent(document.querySelectorAll(selectors.listPreview)[0], "click");
1082
- await nextTick();
1083
- triggerMouseEvent(selectors.ruleEditor.editor.colorDropdown, "click");
1084
- await nextTick();
1085
- expect(fixture.querySelector(".o-color-picker")).toBeTruthy();
1086
- triggerMouseEvent(selectors.ruleEditor.editor.colorDropdown, "click");
1087
- await nextTick();
1088
- expect(fixture.querySelector(".o-color-picker")).toBeFalsy();
1089
- });
1090
-
1091
- test("color-picker closes when click elsewhere", async () => {
1092
- triggerMouseEvent(document.querySelectorAll(selectors.listPreview)[0], "click");
1093
- await nextTick();
1094
- triggerMouseEvent(selectors.ruleEditor.editor.colorDropdown, "click");
1095
- await nextTick();
1096
- expect(fixture.querySelector(".o-color-picker")).toBeTruthy();
1097
- triggerMouseEvent(".o-cf-preview-line", "click");
1098
- await nextTick();
1099
- expect(fixture.querySelector(".o-color-picker")).toBeFalsy();
1100
- });
1101
-
1102
- test("can create a new CellIsRule", async () => {
1103
- mockUuidV4To("42");
1104
-
1105
- triggerMouseEvent(selectors.buttonAdd, "click");
1106
- await nextTick();
1107
-
1108
- // change every value
1109
- setInputValueAndTrigger(selectors.ruleEditor.range, "A1:A3", "change");
1110
- setInputValueAndTrigger(selectors.ruleEditor.editor.operatorInput, "BeginsWith", "change");
1111
- setInputValueAndTrigger(selectors.ruleEditor.editor.valueInput, "3", "input");
1112
-
1113
- triggerMouseEvent(selectors.ruleEditor.editor.bold, "click");
1114
- triggerMouseEvent(selectors.ruleEditor.editor.italic, "click");
1115
- triggerMouseEvent(selectors.ruleEditor.editor.strikethrough, "click");
1116
-
1117
- parent.env.dispatch = jest.fn((command) => ({ status: "SUCCESS" } as CommandResult));
1118
- // click save
1119
- triggerMouseEvent(selectors.buttonSave, "click");
1120
- await nextTick();
1121
- expect(parent.env.dispatch).toHaveBeenCalledWith("ADD_CONDITIONAL_FORMAT", {
1122
- cf: {
1123
- id: "47",
1124
- ranges: ["A1:A3"],
1125
- rule: {
1126
- operator: "BeginsWith",
1127
- stopIfTrue: false,
1128
- style: { bold: true, fillColor: "#FF0000", italic: true, strikethrough: true },
1129
- type: "CellIsRule",
1130
- values: ["3", ""],
1131
- },
1132
- },
1133
- sheet: model.getters.getActiveSheet(),
1134
- });
1135
- });
1136
-
1137
- test("displayed range is updated if range changes", async () => {
1138
- const previews = document.querySelectorAll(selectors.listPreview);
1139
- expect(previews[0].querySelector(selectors.description.range)!.textContent).toBe("A1:A2");
1140
- model.dispatch("COPY", { target: target("A1:A2") });
1141
- model.dispatch("PASTE", { target: target("C1") });
1142
- await nextTick();
1143
- expect(previews[0].querySelector(selectors.description.range)!.textContent).toBe("A1:A2,C1:C2");
1144
- });
1145
-
1146
- test("can delete Rule", async () => {
1147
- parent.env.dispatch = jest.fn((command) => ({ status: "SUCCESS" } as CommandResult));
1148
- const previews = document.querySelectorAll(selectors.listPreview);
1149
- triggerMouseEvent(previews[0].querySelector(selectors.buttonDelete), "click");
1150
- await nextTick();
1151
- expect(parent.env.dispatch).toHaveBeenCalledWith("REMOVE_CONDITIONAL_FORMAT", {
1152
- id: "1",
1153
- sheet: model.getters.getActiveSheet(),
1154
- });
1155
- });
1156
-
1157
- test("can create a new ColorScaleRule", async () => {
1158
- mockUuidV4To("43");
1159
-
1160
- triggerMouseEvent(selectors.buttonAdd, "click");
1161
- await nextTick();
1162
-
1163
- triggerMouseEvent(document.querySelectorAll(selectors.cfTabSelector)[1], "click");
1164
- await nextTick();
1165
-
1166
- // change every value
1167
- setInputValueAndTrigger(selectors.ruleEditor.range, "B2:B5", "change");
1168
-
1169
- triggerMouseEvent(selectors.colorScaleEditor.minColor, "click");
1170
- await nextTick();
1171
- triggerMouseEvent(selectors.colorScaleEditor.colorPickerBlue, "click");
1172
- triggerMouseEvent(selectors.colorScaleEditor.maxColor, "click");
1173
- await nextTick();
1174
- triggerMouseEvent(selectors.colorScaleEditor.colorPickerYellow, "click");
1175
-
1176
- setInputValueAndTrigger(selectors.colorScaleEditor.minValue, "33", "input");
1177
-
1178
- parent.env.dispatch = jest.fn((command) => ({ status: "SUCCESS" } as CommandResult));
1179
- // click save
1180
- triggerMouseEvent(selectors.buttonSave, "click");
1181
- await nextTick();
1182
-
1183
- expect(parent.env.dispatch).toHaveBeenCalledWith("ADD_CONDITIONAL_FORMAT", {
1184
- cf: {
1185
- id: "51",
1186
- ranges: ["B2:B5"],
1187
- rule: {
1188
- maximum: {
1189
- color: 0xffff00,
1190
- type: "value",
1191
- },
1192
- midpoint: undefined,
1193
- minimum: {
1194
- color: 0x0000ff,
1195
- type: "value",
1196
- value: "33",
1197
- },
1198
- type: "ColorScaleRule",
1199
- },
1200
- },
1201
- sheet: model.getters.getActiveSheet(),
1202
- });
1203
- });
1204
-
1205
- test("Make a multiple selection, open CF panel, create a rule => Should create one line per selection", async () => {
1206
- triggerMouseEvent(selectors.closePanel, "click");
1207
- await nextTick();
1208
- const zone1 = { bottom: 1, left: 1, right: 1, top: 1 };
1209
- const zone2 = { bottom: 2, left: 2, right: 2, top: 2 };
1210
- model.dispatch("SET_SELECTION", {
1211
- anchor: [1, 1],
1212
- zones: [zone1, zone2],
1213
- });
1214
- parent.env.openSidePanel("ConditionalFormatting");
1215
- await nextTick();
1216
- triggerMouseEvent(selectors.buttonAdd, "click");
1217
- await nextTick();
1218
- const ranges = document.querySelectorAll(selectors.ruleEditor.range);
1219
- expect(ranges).toHaveLength(2);
1220
- expect(ranges[0]["value"]).toBe("B2");
1221
- expect(ranges[1]["value"]).toBe("C3");
1222
- });
1223
-
1224
- test("Open CF panel, make a multiple selection, open CF panel, create a rule => Should create one line per selection", async () => {
1225
- const zone1 = { bottom: 1, left: 1, right: 1, top: 1 };
1226
- const zone2 = { bottom: 2, left: 2, right: 2, top: 2 };
1227
- model.dispatch("SET_SELECTION", {
1228
- anchor: [1, 1],
1229
- zones: [zone1, zone2],
1230
- });
1231
- triggerMouseEvent(selectors.buttonAdd, "click");
1232
- await nextTick();
1233
- const ranges = document.querySelectorAll(selectors.ruleEditor.range);
1234
- expect(ranges).toHaveLength(2);
1235
- expect(ranges[0]["value"]).toBe("B2");
1236
- expect(ranges[1]["value"]).toBe("C3");
1237
- });
1238
-
1239
- test("switching sheet resets CF Editor to list", async () => {
1240
- triggerMouseEvent(selectors.closePanel, "click");
1241
- model.dispatch("CREATE_SHEET", { id: "42" });
1242
- await nextTick();
1243
- const zone = toZone("A1:A2");
1244
- parent.env.openSidePanel("ConditionalFormatting", { selection: [zone] });
1245
- await nextTick();
1246
- expect(fixture.querySelector(selectors.listPreview)).toBeNull();
1247
- expect(fixture.querySelector(selectors.ruleEditor.range! as "input")!.value).toBe("A1:A2");
1248
- model.dispatch("ACTIVATE_SHEET", { from: model.getters.getActiveSheet(), to: "42" });
1249
- await nextTick();
1250
- expect(fixture.querySelector(selectors.ruleEditor.range)).toBeNull();
1251
- expect(fixture.querySelector(selectors.listPreview)).toBeDefined();
1252
- });
1253
- });