@mwater/visualization 5.4.4 → 5.4.5

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.
@@ -3,6 +3,8 @@ import { Expr } from "@mwater/expressions";
3
3
  design is an array of quick filters (user-selectable filters).
4
4
  */
5
5
  export interface Quickfilter {
6
+ /** Optional id for the quickfilter. If not present, a random id will be generated the first time the quickfilter is edited. */
7
+ id?: string;
6
8
  /** filter expression (left hand side only. Usually enum, enumset, text, date, datetime, id[], text[]) */
7
9
  expr: Expr;
8
10
  /** optional label */
@@ -29,6 +29,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.default = QuickfiltersDesignComponent;
30
30
  const lodash_1 = __importDefault(require("lodash"));
31
31
  const react_1 = __importStar(require("react"));
32
+ const uuid_1 = __importDefault(require("uuid"));
32
33
  const immer_1 = require("immer");
33
34
  const expressions_ui_1 = require("@mwater/expressions-ui");
34
35
  const expressions_1 = require("@mwater/expressions");
@@ -36,10 +37,19 @@ const ui = __importStar(require("@mwater/react-library/lib/bootstrap"));
36
37
  const ListEditorComponent_1 = require("@mwater/react-library/lib/ListEditorComponent");
37
38
  // Displays quick filters and allows their value to be modified
38
39
  function QuickfiltersDesignComponent(props) {
39
- // This counter is used to force a complete remount of the ListEditorComponent when items are reordered
40
- // This is necessary because the ExprComponent inside the list has internal state that can get corrupted
41
- // during reordering operations. By remounting, we ensure a clean slate for all expression components.
42
- const [reorderCounter, setReorderCounter] = (0, react_1.useState)(0);
40
+ // Add ids if not present
41
+ (0, react_1.useEffect)(() => {
42
+ if (props.design.some(qf => !qf.id)) {
43
+ const design = (0, immer_1.produce)(props.design, draft => {
44
+ for (let i = 0; i < draft.length; i++) {
45
+ if (!draft[i].id) {
46
+ draft[i].id = uuid_1.default.v4();
47
+ }
48
+ }
49
+ });
50
+ props.onDesignChange(design);
51
+ }
52
+ }, [props.design]);
43
53
  const handleDesignChange = (design) => {
44
54
  const newDesign = (0, immer_1.produce)(design, draft => {
45
55
  // Update merged flag, clearing if not mergeable
@@ -51,10 +61,6 @@ function QuickfiltersDesignComponent(props) {
51
61
  });
52
62
  props.onDesignChange(newDesign);
53
63
  };
54
- const handleReorder = (design) => {
55
- setReorderCounter(c => c + 1);
56
- handleDesignChange(design);
57
- };
58
64
  // Determine if quickfilter at index is mergeable with previous (same type, id table and enum values)
59
65
  const isMergeable = (design, index) => {
60
66
  if (index === 0) {
@@ -92,7 +98,9 @@ function QuickfiltersDesignComponent(props) {
92
98
  };
93
99
  const handleAdd = () => {
94
100
  // Add blank to end
95
- const design = props.design.concat([{ expr: null }]);
101
+ const design = (0, immer_1.produce)(props.design, draft => {
102
+ draft.push({ expr: null, id: uuid_1.default.v4() });
103
+ });
96
104
  props.onDesignChange(design);
97
105
  };
98
106
  const handleRemove = (index) => {
@@ -101,7 +109,7 @@ function QuickfiltersDesignComponent(props) {
101
109
  props.onDesignChange(design);
102
110
  };
103
111
  return (react_1.default.createElement("div", null,
104
- react_1.default.createElement(ListEditorComponent_1.ListEditorComponent, { key: reorderCounter, items: props.design, onItemsChange: handleReorder, renderItem: renderQuickfilter, getReorderableKey: (item, index) => index }),
112
+ react_1.default.createElement(ListEditorComponent_1.ListEditorComponent, { items: props.design, onItemsChange: handleDesignChange, renderItem: renderQuickfilter, getReorderableKey: (item, index) => item.id ?? index }),
105
113
  props.tables.length > 0 ? (react_1.default.createElement("button", { type: "button", className: "btn btn-sm btn-link", onClick: handleAdd },
106
114
  react_1.default.createElement("span", { className: "fas fa-plus me-1" }),
107
115
  T `Add Quick Filter`)) : undefined));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mwater/visualization",
3
- "version": "5.4.4",
3
+ "version": "5.4.5",
4
4
  "description": "Visualization library",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -4,6 +4,9 @@ import { Expr } from "@mwater/expressions"
4
4
  design is an array of quick filters (user-selectable filters).
5
5
  */
6
6
  export interface Quickfilter {
7
+ /** Optional id for the quickfilter. If not present, a random id will be generated the first time the quickfilter is edited. */
8
+ id?: string
9
+
7
10
  // `table`: (deprecated) table of filter
8
11
 
9
12
  /** filter expression (left hand side only. Usually enum, enumset, text, date, datetime, id[], text[]) */
@@ -1,5 +1,5 @@
1
1
  import _ from "lodash"
2
- import React, { useState } from "react"
2
+ import React, { useEffect, useState } from "react"
3
3
  import uuid from "uuid"
4
4
  import { produce } from "immer"
5
5
  import { ExprComponent } from "@mwater/expressions-ui"
@@ -21,10 +21,19 @@ export interface QuickfiltersDesignComponentProps {
21
21
 
22
22
  // Displays quick filters and allows their value to be modified
23
23
  export default function QuickfiltersDesignComponent(props: QuickfiltersDesignComponentProps) {
24
- // This counter is used to force a complete remount of the ListEditorComponent when items are reordered
25
- // This is necessary because the ExprComponent inside the list has internal state that can get corrupted
26
- // during reordering operations. By remounting, we ensure a clean slate for all expression components.
27
- const [reorderCounter, setReorderCounter] = useState(0)
24
+ // Add ids if not present
25
+ useEffect(() => {
26
+ if (props.design.some(qf => !qf.id)) {
27
+ const design = produce(props.design, draft => {
28
+ for (let i = 0; i < draft.length; i++) {
29
+ if (!draft[i].id) {
30
+ draft[i].id = uuid.v4()
31
+ }
32
+ }
33
+ })
34
+ props.onDesignChange(design)
35
+ }
36
+ }, [props.design])
28
37
 
29
38
  const handleDesignChange = (design: Quickfilter[]) => {
30
39
  const newDesign = produce(design, draft => {
@@ -39,11 +48,6 @@ export default function QuickfiltersDesignComponent(props: QuickfiltersDesignCom
39
48
  props.onDesignChange(newDesign)
40
49
  }
41
50
 
42
- const handleReorder = (design: Quickfilter[]) => {
43
- setReorderCounter(c => c + 1)
44
- handleDesignChange(design)
45
- }
46
-
47
51
  // Determine if quickfilter at index is mergeable with previous (same type, id table and enum values)
48
52
  const isMergeable = (design: Quickfilter[], index: number) => {
49
53
  if (index === 0) {
@@ -102,7 +106,9 @@ export default function QuickfiltersDesignComponent(props: QuickfiltersDesignCom
102
106
 
103
107
  const handleAdd = () => {
104
108
  // Add blank to end
105
- const design = props.design.concat([{ expr: null }])
109
+ const design = produce(props.design, draft => {
110
+ draft.push({ expr: null, id: uuid.v4() })
111
+ })
106
112
  props.onDesignChange(design)
107
113
  }
108
114
 
@@ -115,11 +121,10 @@ export default function QuickfiltersDesignComponent(props: QuickfiltersDesignCom
115
121
  return (
116
122
  <div>
117
123
  <ListEditorComponent
118
- key={reorderCounter}
119
124
  items={props.design}
120
- onItemsChange={handleReorder}
125
+ onItemsChange={handleDesignChange}
121
126
  renderItem={renderQuickfilter}
122
- getReorderableKey={(item, index) => index}
127
+ getReorderableKey={(item, index) => item.id ?? index}
123
128
  />
124
129
  {props.tables.length > 0 ? (
125
130
  <button type="button" className="btn btn-sm btn-link" onClick={handleAdd}>