@mwater/visualization 5.4.3 → 5.4.4
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/lib/quickfilter/Quickfilter.d.ts +0 -2
- package/lib/quickfilter/QuickfiltersDesignComponent.d.ts +1 -8
- package/lib/quickfilter/QuickfiltersDesignComponent.js +36 -39
- package/package.json +1 -1
- package/src/quickfilter/Quickfilter.ts +0 -3
- package/src/quickfilter/QuickfiltersDesignComponent.tsx +51 -51
|
@@ -3,8 +3,6 @@ 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 modified. */
|
|
7
|
-
id?: string;
|
|
8
6
|
/** filter expression (left hand side only. Usually enum, enumset, text, date, datetime, id[], text[]) */
|
|
9
7
|
expr: Expr;
|
|
10
8
|
/** optional label */
|
|
@@ -11,11 +11,4 @@ export interface QuickfiltersDesignComponentProps {
|
|
|
11
11
|
/** List of possible table ids to use */
|
|
12
12
|
tables: string[];
|
|
13
13
|
}
|
|
14
|
-
export default
|
|
15
|
-
handleDesignChange: (design: Quickfilter[]) => void;
|
|
16
|
-
isMergeable(design: Quickfilter[], index: number): boolean;
|
|
17
|
-
renderQuickfilter: (item: Quickfilter, index: number) => React.JSX.Element;
|
|
18
|
-
handleAdd: () => void;
|
|
19
|
-
handleRemove: (index: number) => void;
|
|
20
|
-
render(): React.JSX.Element;
|
|
21
|
-
}
|
|
14
|
+
export default function QuickfiltersDesignComponent(props: QuickfiltersDesignComponentProps): React.JSX.Element;
|
|
@@ -26,40 +26,41 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.default = QuickfiltersDesignComponent;
|
|
29
30
|
const lodash_1 = __importDefault(require("lodash"));
|
|
30
|
-
const react_1 =
|
|
31
|
-
const uuid_1 = __importDefault(require("uuid"));
|
|
31
|
+
const react_1 = __importStar(require("react"));
|
|
32
32
|
const immer_1 = require("immer");
|
|
33
33
|
const expressions_ui_1 = require("@mwater/expressions-ui");
|
|
34
34
|
const expressions_1 = require("@mwater/expressions");
|
|
35
35
|
const ui = __importStar(require("@mwater/react-library/lib/bootstrap"));
|
|
36
36
|
const ListEditorComponent_1 = require("@mwater/react-library/lib/ListEditorComponent");
|
|
37
37
|
// Displays quick filters and allows their value to be modified
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
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);
|
|
43
|
+
const handleDesignChange = (design) => {
|
|
41
44
|
const newDesign = (0, immer_1.produce)(design, draft => {
|
|
42
|
-
// Add UUID if missing
|
|
43
|
-
for (let i = 0; i < draft.length; i++) {
|
|
44
|
-
if (!draft[i].id) {
|
|
45
|
-
draft[i].id = uuid_1.default.v4();
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
45
|
// Update merged flag, clearing if not mergeable
|
|
49
46
|
for (let i = 0; i < draft.length; i++) {
|
|
50
|
-
if (draft[i].merged && !
|
|
47
|
+
if (draft[i].merged && !isMergeable(draft, i)) {
|
|
51
48
|
draft[i].merged = false;
|
|
52
49
|
}
|
|
53
50
|
}
|
|
54
51
|
});
|
|
55
|
-
|
|
52
|
+
props.onDesignChange(newDesign);
|
|
53
|
+
};
|
|
54
|
+
const handleReorder = (design) => {
|
|
55
|
+
setReorderCounter(c => c + 1);
|
|
56
|
+
handleDesignChange(design);
|
|
56
57
|
};
|
|
57
58
|
// Determine if quickfilter at index is mergeable with previous (same type, id table and enum values)
|
|
58
|
-
isMergeable(design, index) {
|
|
59
|
+
const isMergeable = (design, index) => {
|
|
59
60
|
if (index === 0) {
|
|
60
61
|
return false;
|
|
61
62
|
}
|
|
62
|
-
const exprUtils = new expressions_1.ExprUtils(
|
|
63
|
+
const exprUtils = new expressions_1.ExprUtils(props.schema);
|
|
63
64
|
const type = exprUtils.getExprType(design[index].expr);
|
|
64
65
|
const prevType = exprUtils.getExprType(design[index - 1].expr);
|
|
65
66
|
const idTable = exprUtils.getExprIdTable(design[index].expr);
|
|
@@ -81,33 +82,30 @@ class QuickfiltersDesignComponent extends react_1.default.Component {
|
|
|
81
82
|
return false;
|
|
82
83
|
}
|
|
83
84
|
return true;
|
|
84
|
-
}
|
|
85
|
-
renderQuickfilter = (item, index) => {
|
|
86
|
-
return react_1.default.createElement(QuickfilterDesignComponent, { key: index, design: item, schema:
|
|
87
|
-
const design =
|
|
85
|
+
};
|
|
86
|
+
const renderQuickfilter = (item, index) => {
|
|
87
|
+
return react_1.default.createElement(QuickfilterDesignComponent, { key: index, design: item, schema: props.schema, dataSource: props.dataSource, tables: props.tables, mergeable: isMergeable(props.design, index), onChange: (newItem) => {
|
|
88
|
+
const design = props.design.slice();
|
|
88
89
|
design[index] = newItem;
|
|
89
|
-
|
|
90
|
-
}, onRemove:
|
|
90
|
+
handleDesignChange(design);
|
|
91
|
+
}, onRemove: () => handleRemove(index) });
|
|
91
92
|
};
|
|
92
|
-
handleAdd = () => {
|
|
93
|
+
const handleAdd = () => {
|
|
93
94
|
// Add blank to end
|
|
94
|
-
const design =
|
|
95
|
-
|
|
95
|
+
const design = props.design.concat([{ expr: null }]);
|
|
96
|
+
props.onDesignChange(design);
|
|
96
97
|
};
|
|
97
|
-
handleRemove = (index) => {
|
|
98
|
-
const design =
|
|
98
|
+
const handleRemove = (index) => {
|
|
99
|
+
const design = props.design.slice();
|
|
99
100
|
design.splice(index, 1);
|
|
100
|
-
|
|
101
|
+
props.onDesignChange(design);
|
|
101
102
|
};
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
T `Add Quick Filter`)) : undefined));
|
|
108
|
-
}
|
|
103
|
+
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 }),
|
|
105
|
+
props.tables.length > 0 ? (react_1.default.createElement("button", { type: "button", className: "btn btn-sm btn-link", onClick: handleAdd },
|
|
106
|
+
react_1.default.createElement("span", { className: "fas fa-plus me-1" }),
|
|
107
|
+
T `Add Quick Filter`)) : undefined));
|
|
109
108
|
}
|
|
110
|
-
exports.default = QuickfiltersDesignComponent;
|
|
111
109
|
/** Single quickfilter design component */
|
|
112
110
|
class QuickfilterDesignComponent extends react_1.default.Component {
|
|
113
111
|
constructor(props) {
|
|
@@ -119,10 +117,9 @@ class QuickfilterDesignComponent extends react_1.default.Component {
|
|
|
119
117
|
}
|
|
120
118
|
handleTableChange = (table) => {
|
|
121
119
|
this.setState({ table });
|
|
122
|
-
|
|
123
|
-
expr
|
|
124
|
-
};
|
|
125
|
-
return this.props.onChange(design);
|
|
120
|
+
this.props.onChange((0, immer_1.produce)(this.props.design, draft => {
|
|
121
|
+
draft.expr = null;
|
|
122
|
+
}));
|
|
126
123
|
};
|
|
127
124
|
handleExprChange = (expr) => {
|
|
128
125
|
this.props.onChange((0, immer_1.produce)(this.props.design, draft => {
|
package/package.json
CHANGED
|
@@ -4,9 +4,6 @@ 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 modified. */
|
|
8
|
-
id?: string
|
|
9
|
-
|
|
10
7
|
// `table`: (deprecated) table of filter
|
|
11
8
|
|
|
12
9
|
/** 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 from "react"
|
|
2
|
+
import React, { useState } from "react"
|
|
3
3
|
import uuid from "uuid"
|
|
4
4
|
import { produce } from "immer"
|
|
5
5
|
import { ExprComponent } from "@mwater/expressions-ui"
|
|
@@ -20,35 +20,37 @@ export interface QuickfiltersDesignComponentProps {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
// Displays quick filters and allows their value to be modified
|
|
23
|
-
export default
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
for (let i = 0; i < draft.length; i++) {
|
|
29
|
-
if (!draft[i].id) {
|
|
30
|
-
draft[i].id = uuid.v4()
|
|
31
|
-
}
|
|
32
|
-
}
|
|
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)
|
|
33
28
|
|
|
29
|
+
const handleDesignChange = (design: Quickfilter[]) => {
|
|
30
|
+
const newDesign = produce(design, draft => {
|
|
34
31
|
// Update merged flag, clearing if not mergeable
|
|
35
32
|
for (let i = 0; i < draft.length; i++) {
|
|
36
|
-
if (draft[i].merged && !
|
|
33
|
+
if (draft[i].merged && !isMergeable(draft, i)) {
|
|
37
34
|
draft[i].merged = false
|
|
38
35
|
}
|
|
39
36
|
}
|
|
40
37
|
})
|
|
41
38
|
|
|
42
|
-
|
|
39
|
+
props.onDesignChange(newDesign)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const handleReorder = (design: Quickfilter[]) => {
|
|
43
|
+
setReorderCounter(c => c + 1)
|
|
44
|
+
handleDesignChange(design)
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
// Determine if quickfilter at index is mergeable with previous (same type, id table and enum values)
|
|
46
|
-
isMergeable(design: Quickfilter[], index: number) {
|
|
48
|
+
const isMergeable = (design: Quickfilter[], index: number) => {
|
|
47
49
|
if (index === 0) {
|
|
48
50
|
return false
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
const exprUtils = new ExprUtils(
|
|
53
|
+
const exprUtils = new ExprUtils(props.schema)
|
|
52
54
|
|
|
53
55
|
const type = exprUtils.getExprType(design[index].expr)
|
|
54
56
|
const prevType = exprUtils.getExprType(design[index - 1].expr)
|
|
@@ -81,53 +83,52 @@ export default class QuickfiltersDesignComponent extends React.Component<Quickfi
|
|
|
81
83
|
return true
|
|
82
84
|
}
|
|
83
85
|
|
|
84
|
-
renderQuickfilter = (item: Quickfilter, index: number) => {
|
|
86
|
+
const renderQuickfilter = (item: Quickfilter, index: number) => {
|
|
85
87
|
return <QuickfilterDesignComponent
|
|
86
88
|
key={index}
|
|
87
89
|
design={item}
|
|
88
|
-
schema={
|
|
89
|
-
dataSource={
|
|
90
|
-
tables={
|
|
91
|
-
mergeable={
|
|
90
|
+
schema={props.schema}
|
|
91
|
+
dataSource={props.dataSource}
|
|
92
|
+
tables={props.tables}
|
|
93
|
+
mergeable={isMergeable(props.design, index)}
|
|
92
94
|
onChange={(newItem: Quickfilter) => {
|
|
93
|
-
const design =
|
|
95
|
+
const design = props.design.slice()
|
|
94
96
|
design[index] = newItem
|
|
95
|
-
|
|
97
|
+
handleDesignChange(design)
|
|
96
98
|
}}
|
|
97
|
-
onRemove={
|
|
99
|
+
onRemove={() => handleRemove(index)}
|
|
98
100
|
/>
|
|
99
101
|
}
|
|
100
102
|
|
|
101
|
-
handleAdd = () => {
|
|
103
|
+
const handleAdd = () => {
|
|
102
104
|
// Add blank to end
|
|
103
|
-
const design =
|
|
104
|
-
|
|
105
|
+
const design = props.design.concat([{ expr: null }])
|
|
106
|
+
props.onDesignChange(design)
|
|
105
107
|
}
|
|
106
108
|
|
|
107
|
-
handleRemove = (index: number) => {
|
|
108
|
-
const design =
|
|
109
|
+
const handleRemove = (index: number) => {
|
|
110
|
+
const design = props.design.slice()
|
|
109
111
|
design.splice(index, 1)
|
|
110
|
-
|
|
112
|
+
props.onDesignChange(design)
|
|
111
113
|
}
|
|
112
114
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
<
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
115
|
+
return (
|
|
116
|
+
<div>
|
|
117
|
+
<ListEditorComponent
|
|
118
|
+
key={reorderCounter}
|
|
119
|
+
items={props.design}
|
|
120
|
+
onItemsChange={handleReorder}
|
|
121
|
+
renderItem={renderQuickfilter}
|
|
122
|
+
getReorderableKey={(item, index) => index}
|
|
123
|
+
/>
|
|
124
|
+
{props.tables.length > 0 ? (
|
|
125
|
+
<button type="button" className="btn btn-sm btn-link" onClick={handleAdd}>
|
|
126
|
+
<span className="fas fa-plus me-1" />
|
|
127
|
+
{T`Add Quick Filter`}
|
|
128
|
+
</button>
|
|
129
|
+
) : undefined}
|
|
130
|
+
</div>
|
|
131
|
+
)
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
interface QuickfilterDesignComponentProps {
|
|
@@ -162,10 +163,9 @@ class QuickfilterDesignComponent extends React.Component<
|
|
|
162
163
|
|
|
163
164
|
handleTableChange = (table: string) => {
|
|
164
165
|
this.setState({ table })
|
|
165
|
-
|
|
166
|
-
expr
|
|
167
|
-
}
|
|
168
|
-
return this.props.onChange(design)
|
|
166
|
+
this.props.onChange(produce(this.props.design, draft => {
|
|
167
|
+
draft.expr = null
|
|
168
|
+
}))
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
handleExprChange = (expr: Expr) => {
|