@teselagen/ui 0.3.77 → 0.3.79

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/package.json CHANGED
@@ -1,13 +1,12 @@
1
1
  {
2
2
  "name": "@teselagen/ui",
3
- "version": "0.3.77",
3
+ "version": "0.3.79",
4
4
  "main": "./src/index.js",
5
5
  "exports": {
6
6
  ".": {
7
7
  "import": "./index.es.js",
8
8
  "require": "./index.cjs.js"
9
- },
10
- "./style.css": "./style.css"
9
+ }
11
10
  },
12
11
  "dependencies": {
13
12
  "@teselagen/file-utils": "0.3.16",
@@ -21,6 +20,7 @@
21
20
  "buffer": "5.7.1",
22
21
  "color": "^3.2.1",
23
22
  "copy-to-clipboard": "^3.3.1",
23
+ "dayjs": "^1.10.4",
24
24
  "dom-scroll-into-view": "^2.0.1",
25
25
  "downloadjs": "^1.4.7",
26
26
  "fuse.js": "^6.6.2",
@@ -29,15 +29,19 @@
29
29
  "is-mobile": "^3.0.0",
30
30
  "jszip": "^3.10.1",
31
31
  "math-expression-evaluator": "^1.3.7",
32
+ "mobx": "^6.10.2",
33
+ "mobx-react": "^9.0.1",
32
34
  "mock-fs": "5.2.0",
33
35
  "nanoid": "^4.0.0",
34
36
  "papaparse": "^5.3.2",
35
37
  "prop-types": "^15.6.2",
38
+ "qs": "^6.9.6",
36
39
  "react": "18.2.0",
37
40
  "react-color": "^2.19.3",
38
41
  "react-dom": "18.2.0",
39
42
  "react-dropzone": "^11.4.2",
40
43
  "react-markdown": "8.0.7",
44
+ "react-redux": "^8.0.5",
41
45
  "react-rnd": "^10.2.4",
42
46
  "react-router-dom": "^4.3.1",
43
47
  "react-sortable-hoc": "^0.6.8",
@@ -49,7 +53,8 @@
49
53
  "remark-gfm": "^3.0.1",
50
54
  "tippy.js": "^6.3.7",
51
55
  "url-join": "^4.0.1",
52
- "use-deep-compare-effect": "^1.6.1"
56
+ "use-deep-compare-effect": "^1.6.1",
57
+ "write-excel-file": "^1.4.25"
53
58
  },
54
59
  "license": "MIT"
55
60
  }
@@ -15,7 +15,6 @@ import { viewColumn, openColumn } from "../DataTable/viewColumn";
15
15
  import pureNoFunc from "../utils/pureNoFunc";
16
16
  import tgFormValues from "../utils/tgFormValues";
17
17
  import getTableConfigFromStorage from "./utils/getTableConfigFromStorage";
18
- import computePresets from "./utils/computePresets";
19
18
 
20
19
  export default compose(
21
20
  // maybe we need this in some cases?
@@ -41,7 +40,6 @@ export default compose(
41
40
  ...ownProps.tableParams
42
41
  };
43
42
  }
44
- propsToUse = computePresets(propsToUse);
45
43
 
46
44
  const {
47
45
  schema,
@@ -128,8 +126,8 @@ export default compose(
128
126
  return field.render
129
127
  ? !field.render(val, e)
130
128
  : cellRenderer[field.path]
131
- ? !cellRenderer[field.path](val, e)
132
- : !val;
129
+ ? !cellRenderer[field.path](val, e)
130
+ : !val;
133
131
  });
134
132
  }
135
133
  if (noValsForField) {
@@ -1,166 +1,25 @@
1
- import { isString, set, toNumber } from "lodash";
1
+ import { set } from "lodash";
2
2
  import { defaultValidators } from "./defaultValidators";
3
3
  import { defaultFormatters } from "./defaultFormatters";
4
- import { evaluate } from "mathjs";
5
- import getIdOrCodeOrIndex from "./utils/getIdOrCodeOrIndex";
6
4
 
7
5
  //(mutative) responsible for formatting and then validating the
8
- // const depGraph = {
9
- // a1: ["a3"],
10
- // a2: ["a1"],
11
- // a3: [],
12
- // b1: ["a1", "a2"],
13
- // b2: ["a2"],
14
- // b3: ["a3"]
15
- // };
16
6
 
17
7
  export const editCellHelper = ({
18
- _cellAlphaNum,
19
- updateGroup,
20
- depGraph,
21
8
  entity,
22
9
  path,
23
10
  schema,
24
11
  columnSchema,
25
- newVal,
26
- entities,
27
- nestLevel = 0,
28
- depLevel = 0,
29
- allowFormulas
12
+ newVal
30
13
  }) => {
31
14
  let nv = newVal;
32
- if (nv?.formula) {
33
- nv = nv.formula;
34
- }
35
15
 
36
16
  const colSchema =
37
17
  columnSchema || schema?.fields?.find(({ path: p }) => p === path) || {};
38
18
  path = path || colSchema.path;
39
- const cellAlphaNum =
40
- _cellAlphaNum ||
41
- getCellAlphaNum({
42
- entities,
43
- entity,
44
- colSchema,
45
- schema
46
- });
47
- if (
48
- updateGroup[cellAlphaNum] !== undefined &&
49
- updateGroup[cellAlphaNum] !== "__Currently&&Updating__"
50
- ) {
51
- // if the cell is already being updated, return the value
52
- return { value: updateGroup[cellAlphaNum], errors: {} };
53
- } else {
54
- updateGroup[cellAlphaNum] = "__Currently&&Updating__";
55
- }
56
- const cellId = `${getIdOrCodeOrIndex(entity)}:${colSchema.path}`;
57
- const oldVal = entity[path];
58
19
  const { format, validate, type } = colSchema;
59
- let errors = {
60
- __hasErrors: false
61
- };
62
- if (nv === undefined && colSchema.defaultValue !== undefined) {
20
+ let error;
21
+ if (nv === undefined && colSchema.defaultValue !== undefined)
63
22
  nv = colSchema.defaultValue;
64
- }
65
-
66
- let hasFormula = false;
67
- if (colSchema.allowFormulas && typeof nv === "string" && nv[0] === "=") {
68
- const ogFormula = nv;
69
- // if the nv is missing a closing paren, add it
70
- // count the number of open parens
71
- // count the number of close parens
72
- // if the number of open parens is greater than the number of close parens, add a close paren
73
- const openParens = (nv.match(/\(/g) || []).length;
74
- const closeParens = (nv.match(/\)/g) || []).length;
75
- if (openParens > closeParens) {
76
- nv = nv + ")";
77
- }
78
- // if the nv is a valid formula, evaluate it and evaluate any nested formulas
79
- // if the nv is not a valid formula, return the error
80
- // fill in any variables with their values
81
- let error;
82
- // if nv contains : then it is a range
83
- // if (nv.includes(":")) {
84
- // replace the range with the the values of the range
85
- // get the start and end of the range
86
- const { rangeErr, replacedFormula } = replaceFormulaRanges({
87
- formula: nv,
88
- schema,
89
- entities
90
- });
91
- error = rangeErr;
92
- nv = replacedFormula;
93
- nv = nv.replace(/([A-Z]+[0-9]+)/gi, _match => {
94
- const match = _match.toUpperCase();
95
- if (updateGroup[match] === "__Currently&&Updating__") {
96
- error = `Circular Loop Detected between ${cellAlphaNum} and ${match}`;
97
- return "circular_loop_detected";
98
- }
99
- // match will equal E12 or B4 for example
100
- const [letter, rowIndex] = match.split(/(\d+)/);
101
- const entity = entities.find((e, i) => {
102
- return i === rowIndex - 1;
103
- });
104
- const columns = schema.fields;
105
- const letterIndex = lettersToNumber(letter);
106
- const col = columns[letterIndex];
107
- if (!col) {
108
- return match;
109
- }
110
- const { path } = col;
111
- if (!entity) return match;
112
- let val = entity[path];
113
- if (val === undefined || val === "") return 0;
114
- if (val?.formula) {
115
- val = val.formula;
116
- }
117
- if (isString(val) && val[0] === "=") {
118
- // if the value is a formula, evaluate it
119
- const { value, errors: _errors } = editCellHelper({
120
- _cellAlphaNum: match,
121
- updateGroup,
122
- depGraph,
123
- entity,
124
- path,
125
- schema,
126
- columnSchema: col,
127
- newVal: val,
128
- entities,
129
- nestLevel: nestLevel + 1
130
- });
131
- errors = mergeErrors(errors, _errors);
132
- val = value?.formula ? value.value : value;
133
- } else if (!isNaN(toNumber(val))) {
134
- return val;
135
- } else if (isString(val)) {
136
- return 0;
137
- }
138
- return val;
139
- });
140
-
141
- const toEval = nv.slice(1);
142
- try {
143
- if (!error) {
144
- nv = evaluate(toEval);
145
- nv = {
146
- formula: ogFormula,
147
- value: `${nv}`
148
- };
149
- } else {
150
- throw new Error(error);
151
- }
152
- } catch (e) {
153
- nv = {
154
- formula: ogFormula,
155
- value: `#ERROR`,
156
- error: e.message
157
- };
158
- errors[cellId] = e.message;
159
- errors.__hasErrors = true;
160
- }
161
- hasFormula = nv;
162
- nv = nv.value;
163
- }
164
23
 
165
24
  if (format) {
166
25
  nv = format(nv, colSchema);
@@ -168,173 +27,18 @@ export const editCellHelper = ({
168
27
  if (defaultFormatters[type]) {
169
28
  nv = defaultFormatters[type](nv, colSchema);
170
29
  }
171
- if (validate && !hasErrors(errors)) {
172
- const error = validate(nv, colSchema, entity);
173
- if (error) {
174
- errors.__hasErrors = true;
175
- }
176
- errors[cellId] = error;
30
+ if (validate) {
31
+ error = validate(nv, colSchema, entity);
177
32
  }
178
- if (!hasErrors(errors)) {
33
+ if (!error) {
179
34
  const validator =
180
35
  defaultValidators[type] ||
181
36
  type === "string" ||
182
37
  (type === undefined && defaultValidators.string);
183
38
  if (validator) {
184
- const error = validator(nv, colSchema);
185
- if (error) {
186
- errors.__hasErrors = true;
187
- }
188
- errors[cellId] = error;
39
+ error = validator(nv, colSchema);
189
40
  }
190
41
  }
191
- const value = hasFormula || nv;
192
- if (
193
- // if the formula and its value is the same as it was, don't set it again otherwise it will be added to the undo/redo stack
194
- !(
195
- hasFormula &&
196
- value.value === oldVal?.value &&
197
- value.formula === oldVal?.formula
198
- )
199
- ) {
200
- set(entity, path, value);
201
- }
202
- updateGroup[cellAlphaNum] = value;
203
- if (allowFormulas && entities && entities.length) {
204
- // go through the depGraph and update any cells that depend on this cell
205
- const cellDepGraph = depGraph[cellAlphaNum];
206
- if (cellDepGraph && cellDepGraph.length) {
207
- cellDepGraph.forEach(depCellAlphaNum => {
208
- if (depCellAlphaNum === cellAlphaNum) return;
209
- if (updateGroup[depCellAlphaNum] === "__Currently&&Updating__") {
210
- // if the cell is already being updated, return the value
211
- return updateGroup[depCellAlphaNum];
212
- }
213
- const [depColLetter, depRowIndex] = depCellAlphaNum.split(/(\d+)/);
214
- const depEntity = entities[depRowIndex - 1];
215
- // if (!depEntity) debugger
216
- // if (!depEntity) return
217
- const depColIndex = depColLetter.charCodeAt(0) - 65;
218
- const depColSchema = schema.fields[depColIndex];
219
- const depPath = depColSchema.path;
220
- const depNewVal = depEntity[depPath];
221
-
222
- const { errors: _errors } = editCellHelper({
223
- _cellAlphaNum: depCellAlphaNum,
224
- allowFormulas,
225
- updateGroup,
226
- depGraph,
227
- entity: depEntity,
228
- path: depPath,
229
- schema,
230
- columnSchema: depColSchema,
231
- newVal: depNewVal,
232
- entities,
233
- depLevel: depLevel + 1,
234
- nestLevel: nestLevel
235
- });
236
- errors = mergeErrors(errors, _errors);
237
- });
238
- }
239
- }
240
- updateGroup[cellAlphaNum] = value?.formula ? value.value : value;
241
- if (!hasErrors(errors)) {
242
- errors[cellId] = undefined;
243
- }
244
- return { entity, errors, value };
42
+ set(entity, path, nv);
43
+ return { entity, error };
245
44
  };
246
-
247
- function getCellAlphaNum({ entities, entity, colSchema, schema }) {
248
- const rowIndex = entities.indexOf(entity);
249
- const colIndex = schema.fields.indexOf(colSchema);
250
- return getCellAlphaNumHelper(colIndex, rowIndex);
251
- }
252
- export function getCellAlphaNumHelper(colIndex, rowIndex) {
253
- const colLetter = getColLetFromIndex(colIndex);
254
- const cellAlphaNum = `${colLetter}${rowIndex + 1}`;
255
- return cellAlphaNum;
256
- }
257
-
258
- const hasErrors = errors => {
259
- return errors.__hasErrors;
260
- };
261
-
262
- export const getColLetFromIndex = index => {
263
- if (index > 25)
264
- return (
265
- getColLetFromIndexHelper(index / 26 - 1) +
266
- getColLetFromIndexHelper(index % 26)
267
- );
268
- return getColLetFromIndexHelper(index);
269
- };
270
- const getColLetFromIndexHelper = index => {
271
- return String.fromCharCode(65 + index);
272
- };
273
-
274
- const lettersToNumber = letters => {
275
- let n = 0;
276
- for (let p = 0; p < letters.length; p++) {
277
- n = letters[p].charCodeAt() - 64 + n * 26;
278
- }
279
- return n - 1;
280
- };
281
-
282
- export const replaceFormulaRanges = ({ formula, schema, entities }) => {
283
- let error;
284
- const replaced = formula
285
- .toLowerCase()
286
- .replaceAll("$", "")
287
- .replace(/([A-Z]*[0-9]*:[A-Z]*[0-9]*)/gi, _match => {
288
- // if (_match.includes(":")) {
289
- // }
290
- const match = _match.toUpperCase();
291
- const [start, end] = match.split(":");
292
- const [startLetter, _startRowIndex] = start.split(/(\d+)/);
293
- const [endLetter, _endRowIndex] = end.split(/(\d+)/);
294
- let startRowIndex = parseInt(_startRowIndex);
295
- let endRowIndex = parseInt(_endRowIndex);
296
- let toRet = "";
297
-
298
- if (startLetter !== endLetter) {
299
- error = `Ranges must be in the same column`;
300
- return "range_in_different_columns";
301
- }
302
- if (!startLetter && !endLetter && _startRowIndex === _endRowIndex) {
303
- // we have a range like 1:1
304
- const rowIndex = startRowIndex;
305
- const startColIndex = 1;
306
- const endColIndex = schema.fields.length;
307
- for (let i = startColIndex; i <= endColIndex; i++) {
308
- const colLet = getColLetFromIndex(i - 1);
309
- toRet += `${colLet}${rowIndex}${i === endColIndex ? "" : ","}`;
310
- }
311
- return toRet;
312
- }
313
- if (_startRowIndex === undefined && _endRowIndex === undefined) {
314
- // we have a range like A:A
315
- startRowIndex = 1;
316
- endRowIndex = entities.length;
317
- }
318
- for (let j = startRowIndex; j <= endRowIndex; j++) {
319
- toRet += `${startLetter}${j}${j === endRowIndex ? "" : ","}`;
320
- }
321
- return toRet;
322
- });
323
- return {
324
- replacedFormula: replaced,
325
- error
326
- };
327
- };
328
-
329
- function mergeErrors(errors, _errors) {
330
- let hasErrors = false;
331
- if (_errors.__hasErrors || errors.__hasErrors) {
332
- hasErrors = true;
333
- }
334
- errors = {
335
- ...errors,
336
- ..._errors,
337
- __hasErrors: hasErrors
338
- };
339
- return errors;
340
- }
@@ -1,4 +1,4 @@
1
- import { get, has } from "lodash";
1
+ import { get } from "lodash";
2
2
  import { isString } from "lodash";
3
3
  import { isTruthy } from "./isTruthy";
4
4
 
@@ -16,8 +16,5 @@ export const getCellVal = (ent, path, col) => {
16
16
  selectedCellVal === "yes";
17
17
  selectedCellVal = isTruthy(selectedCellVal);
18
18
  }
19
- if (has(selectedCellVal, "value")) {
20
- return selectedCellVal.value;
21
- }
22
19
  return selectedCellVal;
23
20
  };