@linzjs/step-ag-grid 1.1.1
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/README.md +4 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +89342 -0
- package/dist/index.js.map +1 -0
- package/dist/src/components/ComponentLoadingWrapper.d.ts +9 -0
- package/dist/src/components/GenericCellClass.d.ts +2 -0
- package/dist/src/components/Grid.d.ts +24 -0
- package/dist/src/components/GridCell.d.ts +31 -0
- package/dist/src/components/GridIcon.d.ts +6 -0
- package/dist/src/components/GridLoadableCell.d.ts +6 -0
- package/dist/src/components/GridPopoutHook.d.ts +7 -0
- package/dist/src/components/GridSubComponentTextArea.d.ts +5 -0
- package/dist/src/components/PostSortRowsHook.d.ts +11 -0
- package/dist/src/components/gridForm/GridFormDropDown.d.ts +26 -0
- package/dist/src/components/gridForm/GridFormEditBearing.d.ts +9 -0
- package/dist/src/components/gridForm/GridFormMessage.d.ts +8 -0
- package/dist/src/components/gridForm/GridFormMultiSelect.d.ts +26 -0
- package/dist/src/components/gridForm/GridFormPopoutMenu.d.ts +24 -0
- package/dist/src/components/gridForm/GridFormTextArea.d.ts +11 -0
- package/dist/src/components/gridForm/GridFormTextInput.d.ts +11 -0
- package/dist/src/components/gridHeader/GridHeaderSelect.d.ts +8 -0
- package/dist/src/components/gridPopoverEdit/GridPopoutEditMultiSelect.d.ts +4 -0
- package/dist/src/components/gridPopoverEdit/GridPopoutMenu.d.ts +10 -0
- package/dist/src/components/gridPopoverEdit/GridPopoverEditBearing.d.ts +4 -0
- package/dist/src/components/gridPopoverEdit/GridPopoverEditDropDown.d.ts +4 -0
- package/dist/src/components/gridPopoverEdit/GridPopoverMessage.d.ts +4 -0
- package/dist/src/components/gridRender/GridRenderGenericCell.d.ts +15 -0
- package/dist/src/components/gridRender/GridRenderPopoutMenuCell.d.ts +3 -0
- package/dist/src/contexts/GridContext.d.ts +25 -0
- package/dist/src/contexts/GridContextProvider.d.ts +11 -0
- package/dist/src/contexts/UpdatingContext.d.ts +6 -0
- package/dist/src/contexts/UpdatingContextProvider.d.ts +7 -0
- package/dist/src/lui/TextAreaInput.d.ts +11 -0
- package/dist/src/lui/TextInputFormatted.d.ts +14 -0
- package/dist/src/setupTests.d.ts +1 -0
- package/dist/src/stories/components/FormTest.d.ts +12 -0
- package/dist/src/stories/components/GridPopoutBearing.stories.d.ts +9 -0
- package/dist/src/stories/components/GridPopoutEditDropDown.stories.d.ts +9 -0
- package/dist/src/stories/components/GridPopoutEditGeneric.stories.d.ts +9 -0
- package/dist/src/stories/components/GridPopoutEditGenericTextArea.stories.d.ts +9 -0
- package/dist/src/stories/components/GridPopoutEditMultiSelect.stories.d.ts +9 -0
- package/dist/src/stories/components/GridReadOnly.stories.d.ts +9 -0
- package/dist/src/utils/bearing.d.ts +5 -0
- package/dist/src/utils/util.d.ts +4 -0
- package/dist/step-ag-grid.esm.js +89297 -0
- package/dist/step-ag-grid.esm.js.map +1 -0
- package/package.json +126 -0
- package/src/components/ComponentLoadingWrapper.tsx +31 -0
- package/src/components/GenericCellClass.tsx +15 -0
- package/src/components/Grid.scss +38 -0
- package/src/components/Grid.tsx +262 -0
- package/src/components/GridCell.tsx +101 -0
- package/src/components/GridIcon.tsx +12 -0
- package/src/components/GridLoadableCell.tsx +22 -0
- package/src/components/GridPopoutHook.tsx +118 -0
- package/src/components/GridSubComponentTextArea.tsx +26 -0
- package/src/components/GridTheme.scss +94 -0
- package/src/components/PostSortRowsHook.ts +131 -0
- package/src/components/gridForm/GridFormDropDown.tsx +192 -0
- package/src/components/gridForm/GridFormEditBearing.scss +3 -0
- package/src/components/gridForm/GridFormEditBearing.tsx +62 -0
- package/src/components/gridForm/GridFormMessage.tsx +34 -0
- package/src/components/gridForm/GridFormMultiSelect.tsx +180 -0
- package/src/components/gridForm/GridFormPopoutMenu.tsx +90 -0
- package/src/components/gridForm/GridFormTextArea.tsx +61 -0
- package/src/components/gridForm/GridFormTextInput.tsx +66 -0
- package/src/components/gridHeader/GridHeaderSelect.tsx +54 -0
- package/src/components/gridPopoverEdit/GridPopoutEditMultiSelect.ts +22 -0
- package/src/components/gridPopoverEdit/GridPopoutMenu.scss +9 -0
- package/src/components/gridPopoverEdit/GridPopoutMenu.tsx +35 -0
- package/src/components/gridPopoverEdit/GridPopoverEditBearing.ts +24 -0
- package/src/components/gridPopoverEdit/GridPopoverEditDropDown.ts +22 -0
- package/src/components/gridPopoverEdit/GridPopoverMessage.ts +22 -0
- package/src/components/gridRender/GridRenderGenericCell.scss +15 -0
- package/src/components/gridRender/GridRenderGenericCell.tsx +49 -0
- package/src/components/gridRender/GridRenderPopoutMenuCell.tsx +22 -0
- package/src/contexts/GridContext.tsx +82 -0
- package/src/contexts/GridContextProvider.tsx +292 -0
- package/src/contexts/UpdatingContext.tsx +16 -0
- package/src/contexts/UpdatingContextProvider.tsx +43 -0
- package/src/lui/TextAreaInput.tsx +50 -0
- package/src/lui/TextInputFormatted.scss +11 -0
- package/src/lui/TextInputFormatted.tsx +60 -0
- package/src/lui-overrides.scss +163 -0
- package/src/react-app-env.d.ts +1 -0
- package/src/setupTests.ts +5 -0
- package/src/stories/components/FormTest.scss +10 -0
- package/src/stories/components/FormTest.tsx +51 -0
- package/src/stories/components/GridPopoutBearing.stories.tsx +100 -0
- package/src/stories/components/GridPopoutEditDropDown.stories.tsx +174 -0
- package/src/stories/components/GridPopoutEditGeneric.stories.tsx +76 -0
- package/src/stories/components/GridPopoutEditGenericTextArea.stories.tsx +106 -0
- package/src/stories/components/GridPopoutEditMultiSelect.stories.tsx +111 -0
- package/src/stories/components/GridReadOnly.stories.tsx +151 -0
- package/src/utils/bearing.ts +72 -0
- package/src/utils/util.ts +26 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import "@linzjs/lui/dist/scss/base.scss";
|
|
2
|
+
import "@linzjs/lui/dist/fonts";
|
|
3
|
+
import "../../lui-overrides.scss";
|
|
4
|
+
|
|
5
|
+
import { ComponentMeta, ComponentStory } from "@storybook/react/dist/ts3.9/client/preview/types-6-3";
|
|
6
|
+
import { GridContextProvider } from "../../contexts/GridContextProvider";
|
|
7
|
+
import { Grid, GridProps } from "../../components/Grid";
|
|
8
|
+
import { useMemo, useState } from "react";
|
|
9
|
+
import { MenuSeparator } from "../../components/gridForm/GridFormDropDown";
|
|
10
|
+
import { UpdatingContextProvider } from "../../contexts/UpdatingContextProvider";
|
|
11
|
+
import { ColDef } from "ag-grid-community";
|
|
12
|
+
import { wait } from "../../utils/util";
|
|
13
|
+
import { MultiSelectResult } from "../../components/gridForm/GridFormMultiSelect";
|
|
14
|
+
import { GridSubComponentTextArea } from "../../components/GridSubComponentTextArea";
|
|
15
|
+
import { GridCell } from "../../components/GridCell";
|
|
16
|
+
import { GridPopoutEditMultiSelect } from "../../components/gridPopoverEdit/GridPopoutEditMultiSelect";
|
|
17
|
+
|
|
18
|
+
export default {
|
|
19
|
+
title: "Components / Grids",
|
|
20
|
+
component: Grid,
|
|
21
|
+
args: {
|
|
22
|
+
externalSelectedItems: [],
|
|
23
|
+
setExternalSelectedItems: () => {},
|
|
24
|
+
},
|
|
25
|
+
decorators: [
|
|
26
|
+
(Story) => (
|
|
27
|
+
<div style={{ width: 1200, height: 400, display: "flex" }}>
|
|
28
|
+
<UpdatingContextProvider>
|
|
29
|
+
<GridContextProvider>
|
|
30
|
+
<Story />
|
|
31
|
+
</GridContextProvider>
|
|
32
|
+
</UpdatingContextProvider>
|
|
33
|
+
</div>
|
|
34
|
+
),
|
|
35
|
+
],
|
|
36
|
+
} as ComponentMeta<typeof Grid>;
|
|
37
|
+
|
|
38
|
+
interface ITestRow {
|
|
39
|
+
id: number;
|
|
40
|
+
position: string | null;
|
|
41
|
+
position2: string | null;
|
|
42
|
+
position3: string | null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const GridEditMultiSelectTemplate: ComponentStory<typeof Grid> = (props: GridProps) => {
|
|
46
|
+
const [externalSelectedItems, setExternalSelectedItems] = useState<any[]>([]);
|
|
47
|
+
|
|
48
|
+
const columnDefs = useMemo(
|
|
49
|
+
() =>
|
|
50
|
+
[
|
|
51
|
+
GridCell({
|
|
52
|
+
field: "id",
|
|
53
|
+
headerName: "Id",
|
|
54
|
+
initialWidth: 65,
|
|
55
|
+
maxWidth: 85,
|
|
56
|
+
}),
|
|
57
|
+
GridPopoutEditMultiSelect<ITestRow, ITestRow["position"]>({
|
|
58
|
+
field: "position",
|
|
59
|
+
initialWidth: 65,
|
|
60
|
+
maxWidth: 150,
|
|
61
|
+
headerName: "Position",
|
|
62
|
+
cellEditorParams: {
|
|
63
|
+
multiEdit: false,
|
|
64
|
+
filtered: true,
|
|
65
|
+
filterPlaceholder: "Filter position",
|
|
66
|
+
options: [
|
|
67
|
+
{ value: "a", label: "Architect" },
|
|
68
|
+
{ value: "b", label: "Developer" },
|
|
69
|
+
{ value: "c", label: "Product Owner" },
|
|
70
|
+
{ value: "d", label: "Scrum Master" },
|
|
71
|
+
{ value: "e", label: "Tester" },
|
|
72
|
+
MenuSeparator,
|
|
73
|
+
{
|
|
74
|
+
value: "f",
|
|
75
|
+
label: "Other",
|
|
76
|
+
subComponent: (props) => <GridSubComponentTextArea {...props} />,
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
onSave: async (result: MultiSelectResult<ITestRow>) => {
|
|
80
|
+
// eslint-disable-next-line no-console
|
|
81
|
+
console.log(result);
|
|
82
|
+
await wait(1000);
|
|
83
|
+
return true;
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
}),
|
|
87
|
+
] as ColDef[],
|
|
88
|
+
[],
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const rowData = useMemo(
|
|
92
|
+
() =>
|
|
93
|
+
[
|
|
94
|
+
{ id: 1000, position: "Tester", position2: "1", position3: "Tester" },
|
|
95
|
+
{ id: 1001, position: "Developer", position2: "2", position3: "Developer" },
|
|
96
|
+
] as ITestRow[],
|
|
97
|
+
[],
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<Grid
|
|
102
|
+
{...props}
|
|
103
|
+
externalSelectedItems={externalSelectedItems}
|
|
104
|
+
setExternalSelectedItems={setExternalSelectedItems}
|
|
105
|
+
columnDefs={columnDefs}
|
|
106
|
+
rowData={rowData}
|
|
107
|
+
/>
|
|
108
|
+
);
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export const EditMultiSelect = GridEditMultiSelectTemplate.bind({});
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import "@linzjs/lui/dist/scss/base.scss";
|
|
2
|
+
import "@linzjs/lui/dist/fonts";
|
|
3
|
+
import "../../lui-overrides.scss";
|
|
4
|
+
|
|
5
|
+
import { ComponentMeta, ComponentStory } from "@storybook/react/dist/ts3.9/client/preview/types-6-3";
|
|
6
|
+
import { GridContextProvider } from "../../contexts/GridContextProvider";
|
|
7
|
+
import { Grid, GridProps } from "../../components/Grid";
|
|
8
|
+
import { useMemo, useState } from "react";
|
|
9
|
+
import { UpdatingContextProvider } from "../../contexts/UpdatingContextProvider";
|
|
10
|
+
import { wait } from "../../utils/util";
|
|
11
|
+
import { ICellRendererParams } from "ag-grid-community";
|
|
12
|
+
import { GridPopoutMenu } from "../../components/gridPopoverEdit/GridPopoutMenu";
|
|
13
|
+
import { GridPopoverMessage } from "../../components/gridPopoverEdit/GridPopoverMessage";
|
|
14
|
+
import { GridCell } from "../../components/GridCell";
|
|
15
|
+
|
|
16
|
+
export default {
|
|
17
|
+
title: "Components / Grids",
|
|
18
|
+
component: Grid,
|
|
19
|
+
args: {
|
|
20
|
+
externalSelectedItems: [],
|
|
21
|
+
setExternalSelectedItems: () => {},
|
|
22
|
+
},
|
|
23
|
+
decorators: [
|
|
24
|
+
(Story) => (
|
|
25
|
+
<div style={{ width: 1200, height: 400, display: "flex" }}>
|
|
26
|
+
<UpdatingContextProvider>
|
|
27
|
+
<GridContextProvider>
|
|
28
|
+
<Story />
|
|
29
|
+
</GridContextProvider>
|
|
30
|
+
</UpdatingContextProvider>
|
|
31
|
+
</div>
|
|
32
|
+
),
|
|
33
|
+
],
|
|
34
|
+
} as ComponentMeta<typeof Grid>;
|
|
35
|
+
|
|
36
|
+
interface ITestRow {
|
|
37
|
+
id: number;
|
|
38
|
+
position: string;
|
|
39
|
+
age: number;
|
|
40
|
+
desc: string;
|
|
41
|
+
dd: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const GridReadOnlyTemplate: ComponentStory<typeof Grid> = (props: GridProps) => {
|
|
45
|
+
const [externalSelectedItems, setExternalSelectedItems] = useState<any[]>([]);
|
|
46
|
+
const columnDefs = useMemo(
|
|
47
|
+
() => [
|
|
48
|
+
GridCell({
|
|
49
|
+
field: "id",
|
|
50
|
+
headerName: "Id",
|
|
51
|
+
initialWidth: 65,
|
|
52
|
+
maxWidth: 85,
|
|
53
|
+
}),
|
|
54
|
+
GridCell({
|
|
55
|
+
field: "position",
|
|
56
|
+
headerName: "Position",
|
|
57
|
+
initialWidth: 65,
|
|
58
|
+
maxWidth: 150,
|
|
59
|
+
cellRendererParams: {
|
|
60
|
+
warning: (props: ICellRendererParams) => props.value === "Tester" && "Testers are testing",
|
|
61
|
+
info: (props: ICellRendererParams) => props.value === "Developer" && "Developers are awesome",
|
|
62
|
+
},
|
|
63
|
+
}),
|
|
64
|
+
GridCell({
|
|
65
|
+
field: "age",
|
|
66
|
+
headerName: "Age",
|
|
67
|
+
initialWidth: 65,
|
|
68
|
+
maxWidth: 85,
|
|
69
|
+
}),
|
|
70
|
+
GridCell({
|
|
71
|
+
field: "desc",
|
|
72
|
+
headerName: "Description",
|
|
73
|
+
initialWidth: 150,
|
|
74
|
+
maxWidth: 200,
|
|
75
|
+
}),
|
|
76
|
+
GridPopoverMessage<ITestRow>({
|
|
77
|
+
headerName: "Popout message",
|
|
78
|
+
cellRenderer: () => <>Click me!</>,
|
|
79
|
+
cellEditorParams: {
|
|
80
|
+
message: async (selectedRows: ITestRow[]) => {
|
|
81
|
+
await wait(1000);
|
|
82
|
+
return `There are ${selectedRows.length} row(s) selected`;
|
|
83
|
+
},
|
|
84
|
+
multiEdit: true,
|
|
85
|
+
},
|
|
86
|
+
}),
|
|
87
|
+
GridPopoutMenu<ITestRow>({
|
|
88
|
+
headerName: "Menu",
|
|
89
|
+
cellEditorParams: {
|
|
90
|
+
options: async () => {
|
|
91
|
+
// Just doing a timeout here to demonstrate deferred loading
|
|
92
|
+
await wait(500);
|
|
93
|
+
return [
|
|
94
|
+
{
|
|
95
|
+
label: "Single edit only",
|
|
96
|
+
action: async (selectedRows) => {
|
|
97
|
+
alert(`Single-edit: ${selectedRows.length} rows`);
|
|
98
|
+
await wait(1500);
|
|
99
|
+
return true;
|
|
100
|
+
},
|
|
101
|
+
multiEdit: false,
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
label: "Multi-edit",
|
|
105
|
+
action: async (selectedRows) => {
|
|
106
|
+
alert(`Multi-edit: ${selectedRows.length} rows`);
|
|
107
|
+
await wait(1500);
|
|
108
|
+
return true;
|
|
109
|
+
},
|
|
110
|
+
multiEdit: true,
|
|
111
|
+
},
|
|
112
|
+
];
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
}),
|
|
116
|
+
GridPopoutMenu<ITestRow>({
|
|
117
|
+
headerName: "Menu disabled",
|
|
118
|
+
editable: false,
|
|
119
|
+
cellEditorParams: {
|
|
120
|
+
options: async () => {
|
|
121
|
+
return [];
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
}),
|
|
125
|
+
],
|
|
126
|
+
[],
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
const rowData = useMemo(
|
|
130
|
+
() =>
|
|
131
|
+
[
|
|
132
|
+
{ id: 1000, position: "Tester", age: 30, desc: "Tests application", dd: "1" },
|
|
133
|
+
{ id: 1001, position: "Developer", age: 12, desc: "Develops application", dd: "2" },
|
|
134
|
+
] as ITestRow[],
|
|
135
|
+
[],
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<Grid
|
|
140
|
+
{...props}
|
|
141
|
+
externalSelectedItems={externalSelectedItems}
|
|
142
|
+
setExternalSelectedItems={setExternalSelectedItems}
|
|
143
|
+
columnDefs={columnDefs}
|
|
144
|
+
rowData={rowData}
|
|
145
|
+
quickFilter={true}
|
|
146
|
+
quickFilterPlaceholder={"Quick filter..."}
|
|
147
|
+
/>
|
|
148
|
+
);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export const ReadOnly = GridReadOnlyTemplate.bind({});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { ValueFormatterParams } from "ag-grid-community/dist/lib/entities/colDef";
|
|
2
|
+
|
|
3
|
+
export const bearingValueFormatter = (params: ValueFormatterParams): string => {
|
|
4
|
+
const value = params.value;
|
|
5
|
+
if (value == null) {
|
|
6
|
+
return "-";
|
|
7
|
+
}
|
|
8
|
+
return convertDDToDMS(value);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const bearingNumberParser = (value: string): number | null => {
|
|
12
|
+
if (value === "") return null;
|
|
13
|
+
return parseFloat(value);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const validMaskForDmsBearing = /^(\d+)?(\.([0-5](\d([0-5](\d(\d+)?)?)?)?)?)?$/;
|
|
17
|
+
export const bearingStringValidator = (value: string): string | null => {
|
|
18
|
+
value = value.trim();
|
|
19
|
+
if (value === "") return null;
|
|
20
|
+
const match = value.match(validMaskForDmsBearing);
|
|
21
|
+
if (!match) return "Bearing must be a positive number in D.MMSSS format";
|
|
22
|
+
const decimalPart = match[3];
|
|
23
|
+
if (decimalPart != null && decimalPart.length > 5) {
|
|
24
|
+
return "Bearing has a maximum of 5 decimal places";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const bearing = parseFloat(value);
|
|
28
|
+
if (bearing >= 360) return "Bearing must be between 0 and 360 inclusive";
|
|
29
|
+
return null;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// Decimal-ish degrees to Degrees Minutes Seconds converter
|
|
33
|
+
export const convertDDToDMS = (dd: number | null, showPositiveSymbol = true, addTrailingZeros = true): string => {
|
|
34
|
+
if (dd == null) return "–";
|
|
35
|
+
|
|
36
|
+
if (dd === 0) addTrailingZeros = true;
|
|
37
|
+
|
|
38
|
+
// toFixed rounds parts up greater than 60, which has to be corrected below
|
|
39
|
+
const [bearingWholeString, beringDecimalString] = dd.toFixed(5).split(".");
|
|
40
|
+
|
|
41
|
+
let bearingWhole = Math.abs(parseInt(bearingWholeString));
|
|
42
|
+
let minNumeric = parseInt(beringDecimalString?.substring(0, 2));
|
|
43
|
+
let secNumeric = parseInt(beringDecimalString?.substring(2, 4));
|
|
44
|
+
|
|
45
|
+
// If the toFixed caused rounding beyond 60 minutes/seconds then apply the carry
|
|
46
|
+
if (secNumeric >= 60) {
|
|
47
|
+
minNumeric++;
|
|
48
|
+
secNumeric -= 60;
|
|
49
|
+
}
|
|
50
|
+
if (minNumeric >= 60) {
|
|
51
|
+
bearingWhole++;
|
|
52
|
+
minNumeric -= 60;
|
|
53
|
+
}
|
|
54
|
+
if (bearingWhole >= 360) {
|
|
55
|
+
bearingWhole -= 360;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const minString = minNumeric.toString().padStart(2, "0");
|
|
59
|
+
const secString = secNumeric.toString().padStart(2, "0");
|
|
60
|
+
const deciSecString = beringDecimalString?.substring(4, 5);
|
|
61
|
+
|
|
62
|
+
let dmsString = `${showPositiveSymbol && dd > 0 ? "+" : ""}${dd < 0 ? "-" : ""}${bearingWhole}°`;
|
|
63
|
+
if (addTrailingZeros || deciSecString != "0") {
|
|
64
|
+
dmsString += `\xa0${minString}'\xa0${secString}.${deciSecString}"`; // "\xa0" is here for non-breaking space
|
|
65
|
+
} else if (secNumeric != 0) {
|
|
66
|
+
dmsString += `\xa0${minString}'\xa0${secString}"`;
|
|
67
|
+
} else if (minNumeric != 0) {
|
|
68
|
+
dmsString += `\xa0${minString}'`;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return dmsString;
|
|
72
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { isEmpty as _isEmpty } from "lodash-es";
|
|
2
|
+
|
|
3
|
+
// Typed version of lodash !isEmpty
|
|
4
|
+
export const isNotEmpty = (obj: Set<any> | Map<any, any> | Record<any, any> | any[] | undefined): boolean =>
|
|
5
|
+
!_isEmpty(obj);
|
|
6
|
+
|
|
7
|
+
export const wait = (timeoutMs: number) =>
|
|
8
|
+
new Promise<(string | null)[]>((resolve) => {
|
|
9
|
+
setTimeout(resolve, timeoutMs);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export const isFloat = (value: string) => {
|
|
13
|
+
const regexp = /^-?\d+(\.\d+)?$/;
|
|
14
|
+
return regexp.test(value);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const hasParentClass = function (className: string, child: Node) {
|
|
18
|
+
let node: Node | null = child;
|
|
19
|
+
while (node) {
|
|
20
|
+
if (node instanceof Node && node instanceof HTMLElement && node.classList.contains(className)) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
node = node.parentNode;
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
};
|