@teselagen/ui 0.7.7-beta.2 → 0.7.7

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@teselagen/ui",
3
- "version": "0.7.7-beta.2",
3
+ "version": "0.7.7",
4
4
  "main": "./src/index.js",
5
5
  "exports": {
6
6
  ".": {
@@ -12,8 +12,8 @@
12
12
  "dependencies": {
13
13
  "@teselagen/file-utils": "0.3.16",
14
14
  "@teselagen/bounce-loader": "0.3.11",
15
- "@blueprintjs/core": "3.52.0",
16
- "@blueprintjs/datetime": "3.23.19",
15
+ "@blueprintjs/core": "3.54.0",
16
+ "@blueprintjs/datetime": "^3.24.1",
17
17
  "@blueprintjs/icons": "3.33.0",
18
18
  "@blueprintjs/select": "3.18.11",
19
19
  "@dnd-kit/core": "^6.1.0",
@@ -45,7 +45,7 @@
45
45
  "react-color": "^2.19.3",
46
46
  "react-dom": "^18.3.1",
47
47
  "react-dropzone": "^11.4.2",
48
- "react-markdown": "8.0.7",
48
+ "react-markdown": "9.0.1",
49
49
  "react-redux": "^8.0.5",
50
50
  "react-rnd": "^10.2.4",
51
51
  "react-router-dom": "4",
@@ -54,7 +54,7 @@
54
54
  "redux": "^4.1.2",
55
55
  "redux-form": "^8.3.10",
56
56
  "redux-thunk": "2.4.1",
57
- "remark-gfm": "^3.0.1",
57
+ "remark-gfm": "^4.0.0",
58
58
  "tippy.js": "^6.3.7",
59
59
  "url-join": "^4.0.1",
60
60
  "use-deep-compare-effect": "^1.6.1",
@@ -102,6 +102,7 @@ import { useColumns } from "./Columns";
102
102
  import { formValueSelector, change as _change } from "redux-form";
103
103
  import { throwFormError } from "../throwFormError";
104
104
  import { isObservableArray, toJS } from "mobx";
105
+ import { isBeingCalledExcessively } from "../utils/isBeingCalledExcessively";
105
106
 
106
107
  enablePatches();
107
108
  const IS_LINUX = window.navigator.platform.toLowerCase().search("linux") > -1;
@@ -425,7 +426,7 @@ const DataTable = ({
425
426
  hideSelectedCount = isSimple,
426
427
  hideSetPageSize,
427
428
  hideTotalPages,
428
- initialSelectedIds,
429
+ selectedIds,
429
430
  isCellEditable,
430
431
  isCopyable = true,
431
432
  isEntityDisabled = noop,
@@ -501,16 +502,14 @@ const DataTable = ({
501
502
  // This is because we need to maintain the reduxFormSelectedEntityIdMap and
502
503
  // allOrderedEntities updated
503
504
  useEffect(() => {
504
- if (change) {
505
- change("allOrderedEntities", entitiesAcrossPages);
506
- if (entities.length === 0 || isEmpty(reduxFormSelectedEntityIdMap))
507
- return;
508
- changeSelectedEntities({
509
- idMap: reduxFormSelectedEntityIdMap,
510
- entities,
511
- change
512
- });
513
- }
505
+ isBeingCalledExcessively({ uniqName: `dt_entities_${formName}` });
506
+ change("allOrderedEntities", entitiesAcrossPages);
507
+ if (entities.length === 0 || isEmpty(reduxFormSelectedEntityIdMap)) return;
508
+ changeSelectedEntities({
509
+ idMap: reduxFormSelectedEntityIdMap,
510
+ entities,
511
+ change
512
+ });
514
513
  // eslint-disable-next-line react-hooks/exhaustive-deps
515
514
  }, [entitiesAcrossPages, reduxFormSelectedEntityIdMap, change]);
516
515
 
@@ -524,6 +523,7 @@ const DataTable = ({
524
523
  } else {
525
524
  newTableConfig = getTableConfigFromStorage(formName);
526
525
  }
526
+ isBeingCalledExcessively({ uniqName: `dt_setTableConfig_${formName}` });
527
527
  // if the tableConfig is the same as the newTableConfig, don't update
528
528
  setTableConfig(prev => {
529
529
  if (!newTableConfig) {
@@ -1752,17 +1752,15 @@ const DataTable = ({
1752
1752
 
1753
1753
  // We need to make sure this only runs at the beggining
1754
1754
  useEffect(() => {
1755
- if (initialSelectedIds) {
1756
- if (alreadySelected.current) return;
1757
- setSelectedIds(initialSelectedIds);
1758
- alreadySelected.current = true;
1755
+ if (selectedIds) {
1756
+ setSelectedIds(selectedIds);
1759
1757
  }
1760
1758
  if (selectAllByDefault && entities && entities.length) {
1761
1759
  if (alreadySelected.current) return;
1762
1760
  setSelectedIds(entities.map(getIdOrCodeOrIndex));
1763
1761
  alreadySelected.current = true;
1764
1762
  }
1765
- }, [entities, initialSelectedIds, selectAllByDefault, setSelectedIds]);
1763
+ }, [entities, selectedIds, selectAllByDefault, setSelectedIds]);
1766
1764
 
1767
1765
  const TheadComponent = useCallback(
1768
1766
  ({ className, style, children }) => {
package/src/FillWindow.js CHANGED
@@ -1,4 +1,5 @@
1
- import React, { createPortal } from "react";
1
+ import React from "react";
2
+ import createPortal from "react-dom";
2
3
  import { isFunction } from "lodash-es";
3
4
  import rerenderOnWindowResize from "./rerenderOnWindowResize";
4
5
  import "./FillWindow.css";
@@ -49,8 +49,6 @@ import { LoadingDots } from "./LoadingDots";
49
49
  import { useDispatch } from "react-redux";
50
50
  import { flushSync } from "react-dom";
51
51
  import { useStableReference } from "../utils/hooks/useStableReference";
52
- import useDeepCompareEffect from "use-deep-compare-effect";
53
- import { useTraceUpdate } from "../utils/useTraceUpdate";
54
52
 
55
53
  const manualEnterMessage = "Build CSV File";
56
54
  const manualEnterSubMessage = "Paste or type data to build a CSV file";
@@ -254,7 +252,7 @@ const Uploader = ({
254
252
  validateAgainstSchema: _validateAgainstSchema
255
253
  }) => {
256
254
  const dispatch = useDispatch();
257
- const [acceptLoading, setAcceptLoading] = useState(true); // set to true by default to prevent the dropzone from being actionable until the accept is resolved
255
+ const [acceptLoading, setAcceptLoading] = useState();
258
256
  const [resolvedAccept, setResolvedAccept] = useState();
259
257
  const [loading, setLoading] = useState(false);
260
258
  const filesToClean = useRef([]);
@@ -364,26 +362,17 @@ const Uploader = ({
364
362
  }
365
363
  return __accept;
366
364
  }, [__accept, isAcceptPromise, resolvedAccept]);
367
- useTraceUpdate({
368
- __accept,
369
- isAcceptPromise
370
- });
365
+
371
366
  useEffect(() => {
372
367
  if (isAcceptPromise) {
373
368
  setAcceptLoading(true);
374
369
  Promise.allSettled(Array.isArray(__accept) ? __accept : [__accept]).then(
375
370
  results => {
376
371
  const resolved = flatMap(results, r => r.value);
372
+ setAcceptLoading(false);
377
373
  setResolvedAccept(resolved);
378
- setTimeout(() => {
379
- // give the resolved accept a full JS cycle to update before allowing actionability on the dropzone
380
- setAcceptLoading(false);
381
- }, 0);
382
374
  }
383
375
  );
384
- } else {
385
- // set this to false since it is defaulted to true
386
- setAcceptLoading(false);
387
376
  }
388
377
  }, [__accept, isAcceptPromise]);
389
378
 
@@ -0,0 +1,24 @@
1
+ const keyCount = {};
2
+ export const isBeingCalledExcessively = ({ uniqName }) => {
3
+ if (process.env.NODE_ENV !== "development") {
4
+ return;
5
+ }
6
+ if (!uniqName) {
7
+ throw new Error("uniqName is required");
8
+ }
9
+ // if this function is hit more than 10 times in a row in 2 seconds with the same uniqName then throw an error
10
+ if (keyCount[uniqName + "_timeout"]) {
11
+ clearTimeout(keyCount[uniqName + "_timeout"]);
12
+ }
13
+ keyCount[uniqName] = keyCount[uniqName] || 0;
14
+ keyCount[uniqName]++;
15
+
16
+ keyCount[uniqName + "_timeout"] = setTimeout(() => {
17
+ keyCount[uniqName] = 0;
18
+ }, 2000);
19
+
20
+ if (keyCount[uniqName] > 20) {
21
+ keyCount[uniqName] = 0;
22
+ throw new Error(`isBeingCalledExcessively: ${uniqName}`);
23
+ }
24
+ };
@@ -0,0 +1,3 @@
1
+ export function isBeingCalledExcessively({ uniqName }: {
2
+ uniqName: any;
3
+ }): void;
@@ -1,10 +0,0 @@
1
- export function EditableCell({ cancelEdit, dataTest, finishEdit, initialValue, isEditableCellInitialValue, isNumeric, shouldSelectAll, stopSelectAll }: {
2
- cancelEdit: any;
3
- dataTest: any;
4
- finishEdit: any;
5
- initialValue: any;
6
- isEditableCellInitialValue: any;
7
- isNumeric: any;
8
- shouldSelectAll: any;
9
- stopSelectAll: any;
10
- }): import("react/jsx-runtime").JSX.Element;
@@ -1,43 +0,0 @@
1
- import { noop } from 'lodash-es';
2
- declare namespace _default {
3
- export { noop as addFilters };
4
- export let className: string;
5
- export { noop as clearFilters };
6
- export { noop as contextMenu };
7
- export let disabled: boolean;
8
- export let entities: never[];
9
- export let extraClasses: string;
10
- export let filters: never[];
11
- export let isCopyable: boolean;
12
- export { noop as isEntityDisabled };
13
- export let isLoading: boolean;
14
- export let isSimple: boolean;
15
- export let isSingleSelect: boolean;
16
- export let maxHeight: number;
17
- export let noHeader: boolean;
18
- export let noSelect: boolean;
19
- export let noUserSelect: boolean;
20
- export { noop as onDeselect };
21
- export { noop as onMultiRowSelect };
22
- export { noop as onRowClick };
23
- export { noop as onRowSelect };
24
- export { noop as onSingleRowSelect };
25
- export let page: number;
26
- export let pageSize: number;
27
- export let reduxFormExpandedEntityIdMap: {};
28
- export let reduxFormSearchInput: string;
29
- export let reduxFormSelectedEntityIdMap: {};
30
- export { noop as removeSingleFilter };
31
- export let resized: never[];
32
- export { noop as resizePersist };
33
- export { noop as setFilter };
34
- export { noop as setOrder };
35
- export { noop as setPage };
36
- export { noop as setPageSize };
37
- export { noop as setSearchTerm };
38
- export let showCount: boolean;
39
- export let style: {};
40
- export let withCheckboxes: boolean;
41
- export let withSort: boolean;
42
- }
43
- export default _default;
@@ -1 +0,0 @@
1
- export default function computePresets(props?: {}): import('lodash').Dictionary<any>;
@@ -1,55 +0,0 @@
1
- import React, { useEffect, useRef, useState } from "react";
2
-
3
- export const EditableCell = ({
4
- cancelEdit,
5
- dataTest,
6
- finishEdit,
7
- initialValue,
8
- isEditableCellInitialValue,
9
- isNumeric,
10
- shouldSelectAll,
11
- stopSelectAll
12
- }) => {
13
- const [value, setValue] = useState(initialValue);
14
- const inputRef = useRef(null);
15
-
16
- useEffect(() => {
17
- if (inputRef.current) {
18
- inputRef.current.focus();
19
- if (isEditableCellInitialValue && !isNumeric) {
20
- inputRef.current.selectionStart = inputRef.current.value.length;
21
- inputRef.current.selectionEnd = inputRef.current.value.length;
22
- } else if (shouldSelectAll) {
23
- inputRef.current.select();
24
- stopSelectAll();
25
- }
26
- }
27
- }, [isEditableCellInitialValue, isNumeric, shouldSelectAll, stopSelectAll]);
28
-
29
- return (
30
- <input
31
- style={{
32
- border: 0,
33
- width: "95%",
34
- fontSize: 12,
35
- background: "none"
36
- }}
37
- ref={inputRef}
38
- {...dataTest}
39
- autoFocus
40
- onKeyDown={e => {
41
- if (e.key === "Enter") {
42
- finishEdit(value);
43
- e.stopPropagation();
44
- } else if (e.key === "Escape") {
45
- e.stopPropagation();
46
- cancelEdit();
47
- }
48
- }}
49
- onBlur={() => finishEdit(value)}
50
- onChange={e => setValue(e.target.value)}
51
- type={isNumeric ? "number" : undefined}
52
- value={value}
53
- />
54
- );
55
- };
@@ -1,45 +0,0 @@
1
- import { noop } from "lodash-es";
2
-
3
- // eslint-disable-next-line import/no-anonymous-default-export
4
- export default {
5
- //NOTE: DO NOT SET DEFAULTS HERE FOR PROPS THAT GET COMPUTED AS PART OF PRESET GROUPS IN computePresets
6
- addFilters: noop,
7
- className: "",
8
- clearFilters: noop,
9
- contextMenu: noop,
10
- disabled: false,
11
- entities: [],
12
- extraClasses: "",
13
- filters: [],
14
- isCopyable: true,
15
- isEntityDisabled: noop,
16
- isLoading: false,
17
- isSimple: false,
18
- isSingleSelect: false,
19
- maxHeight: 600,
20
- noHeader: false,
21
- noSelect: false,
22
- noUserSelect: false,
23
- onDeselect: noop,
24
- onMultiRowSelect: noop,
25
- onRowClick: noop,
26
- onRowSelect: noop,
27
- onSingleRowSelect: noop,
28
- page: 1,
29
- pageSize: 10,
30
- reduxFormExpandedEntityIdMap: {},
31
- reduxFormSearchInput: "",
32
- reduxFormSelectedEntityIdMap: {},
33
- removeSingleFilter: noop,
34
- resized: [],
35
- resizePersist: noop,
36
- setFilter: noop,
37
- setOrder: noop,
38
- setPage: noop,
39
- setPageSize: noop,
40
- setSearchTerm: noop,
41
- showCount: false,
42
- style: {},
43
- withCheckboxes: false,
44
- withSort: true
45
- };
@@ -1,42 +0,0 @@
1
- import { omitBy, isNil } from "lodash-es";
2
- //we use this to make adding preset prop groups simpler
3
- export default function computePresets(props = {}) {
4
- const { isSimple } = props;
5
- let toReturn = omitBy(props, isNil);
6
- toReturn.pageSize = toReturn.controlled_pageSize || toReturn.pageSize;
7
- if (isSimple) {
8
- //isSimplePreset
9
- toReturn = {
10
- noHeader: true,
11
- noFooter: !props.withPaging,
12
- noPadding: true,
13
- noFullscreenButton: true,
14
- hidePageSizeWhenPossible: !props.withPaging,
15
- isInfinite: !props.withPaging,
16
- hideSelectedCount: true,
17
- withTitle: false,
18
- withSearch: false,
19
- compact: true,
20
- withPaging: false,
21
- withFilter: false,
22
- ...toReturn
23
- };
24
- } else {
25
- toReturn = {
26
- // the usual defaults:
27
- noFooter: false,
28
- noPadding: false,
29
- compact: true,
30
- noFullscreenButton: false,
31
- hidePageSizeWhenPossible: false,
32
- isInfinite: false,
33
- hideSelectedCount: false,
34
- withTitle: true,
35
- withSearch: true,
36
- withPaging: true,
37
- withFilter: true,
38
- ...toReturn
39
- };
40
- }
41
- return toReturn || {};
42
- }