@scheels-softdev/kendoreact-generics 4.0.8 → 4.0.10
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/GenericDropdown.d.ts +16 -0
- package/GenericDropdown.js +48 -0
- package/MultiSelectDropdown.d.ts +14 -0
- package/MultiSelectDropdown.js +44 -0
- package/{src/PropTypes.ts → PropTypes.d.ts} +0 -1
- package/PropTypes.js +1 -0
- package/Toolbar.d.ts +13 -0
- package/Toolbar.js +4 -0
- package/Utility.d.ts +4 -0
- package/Utility.js +11 -0
- package/_index.test.d.ts +1 -0
- package/{src/_index.test.tsx → _index.test.js} +10 -49
- package/commandCell/CommandCellCheckbox.d.ts +10 -0
- package/commandCell/CommandCellCheckbox.js +13 -0
- package/commandCell/CommandCellDate.d.ts +9 -0
- package/commandCell/CommandCellDate.js +12 -0
- package/commandCell/CommandCellPrice.d.ts +3 -0
- package/commandCell/CommandCellPrice.js +10 -0
- package/commandCell/CommandCellSwitch.d.ts +12 -0
- package/commandCell/CommandCellSwitch.js +5 -0
- package/index.js +7 -0
- package/package.json +1 -1
- package/jest.config.js +0 -4
- package/src/GenericDropdown.tsx +0 -65
- package/src/MultiSelectDropdown.tsx +0 -79
- package/src/Toolbar.tsx +0 -27
- package/src/Utility.ts +0 -19
- package/src/commandCell/CommandCellCheckbox.tsx +0 -31
- package/src/commandCell/CommandCellDate.tsx +0 -36
- package/src/commandCell/CommandCellPrice.tsx +0 -9
- package/src/commandCell/CommandCellSwitch.tsx +0 -20
- package/tsconfig.json +0 -13
- /package/{src/index.ts → index.d.ts} +0 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
import { ComboBoxProps } from "@progress/kendo-react-dropdowns";
|
2
|
+
interface BaseProps<T> extends ComboBoxProps {
|
3
|
+
data: T[];
|
4
|
+
pageSize?: number;
|
5
|
+
onClear?: () => void;
|
6
|
+
}
|
7
|
+
interface SelectedDataProps<T> {
|
8
|
+
selectedData?: T;
|
9
|
+
}
|
10
|
+
interface SelectedIdProps<T> {
|
11
|
+
selectedId?: number;
|
12
|
+
idField: keyof T;
|
13
|
+
}
|
14
|
+
type GenericDropdownProps<T> = BaseProps<T> & (SelectedDataProps<T> | SelectedIdProps<T>);
|
15
|
+
export declare function GenericDropdown<T>({ data, onClear, ...props }: GenericDropdownProps<T>): import("react/jsx-runtime").JSX.Element;
|
16
|
+
export default GenericDropdown;
|
@@ -0,0 +1,48 @@
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
2
|
+
var t = {};
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
4
|
+
t[p] = s[p];
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
8
|
+
t[p[i]] = s[p[i]];
|
9
|
+
}
|
10
|
+
return t;
|
11
|
+
};
|
12
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
13
|
+
import React, { useMemo } from "react";
|
14
|
+
import { ComboBox } from "@progress/kendo-react-dropdowns";
|
15
|
+
// GenericDropdown component definition
|
16
|
+
export function GenericDropdown(_a) {
|
17
|
+
var { data, onClear } = _a, props = __rest(_a, ["data", "onClear"]);
|
18
|
+
// Compute selected item based on the provided props using type guards
|
19
|
+
const selectedItem = useMemo(() => {
|
20
|
+
var _a;
|
21
|
+
if ("selectedData" in props) {
|
22
|
+
return props.selectedData;
|
23
|
+
}
|
24
|
+
else if ("selectedId" in props && "idField" in props) {
|
25
|
+
return (_a = data.find((item) => item[props.idField] === props.selectedId)) !== null && _a !== void 0 ? _a : null;
|
26
|
+
}
|
27
|
+
return null;
|
28
|
+
}, [props, data]);
|
29
|
+
const [state, setState] = React.useState({
|
30
|
+
subsetData: data.slice(0, 6),
|
31
|
+
skip: 0,
|
32
|
+
});
|
33
|
+
const pageChange = (event) => {
|
34
|
+
const skip = event.page.skip;
|
35
|
+
const take = event.page.take;
|
36
|
+
const newSubsetData = data.slice(skip, skip + take);
|
37
|
+
setState({
|
38
|
+
subsetData: newSubsetData,
|
39
|
+
skip: skip,
|
40
|
+
});
|
41
|
+
};
|
42
|
+
return (_jsx(ComboBox, Object.assign({ data: state.subsetData, value: selectedItem, virtual: {
|
43
|
+
pageSize: 6,
|
44
|
+
skip: state.skip,
|
45
|
+
total: data.length,
|
46
|
+
}, onPageChange: pageChange }, props)));
|
47
|
+
}
|
48
|
+
export default GenericDropdown;
|
@@ -0,0 +1,14 @@
|
|
1
|
+
export declare function MultiSelectDropdown<T>({ data, selectedData, textField, onSelect, title, limit, }: {
|
2
|
+
/** The data array for the dropdown options. */
|
3
|
+
data: T[];
|
4
|
+
/** The array of selected data items. */
|
5
|
+
selectedData: T[];
|
6
|
+
/** The field names to use for text values in the dropdown. */
|
7
|
+
textField: keyof T;
|
8
|
+
/** The function to call when an item is selected or deselected. */
|
9
|
+
onSelect: Function;
|
10
|
+
/** The optional title of the dropdown. */
|
11
|
+
title?: string;
|
12
|
+
/** The optional limit of the maximum number of selected items. */
|
13
|
+
limit?: number;
|
14
|
+
}): import("react/jsx-runtime").JSX.Element;
|
@@ -0,0 +1,44 @@
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
+
import { useRef, useState } from "react";
|
3
|
+
import { filterBy } from "@progress/kendo-data-query";
|
4
|
+
import { MultiSelect } from "@progress/kendo-react-dropdowns";
|
5
|
+
export function MultiSelectDropdown({ data, selectedData, textField, onSelect, title, limit, }) {
|
6
|
+
//local state
|
7
|
+
const pageSize = 8;
|
8
|
+
const [state, setState] = useState({
|
9
|
+
skip: 0,
|
10
|
+
total: data.length,
|
11
|
+
subsetData: data.slice(0, pageSize),
|
12
|
+
});
|
13
|
+
//external function variables
|
14
|
+
const filteredData = useRef(data.slice());
|
15
|
+
//function creation
|
16
|
+
// function to handle filter changes
|
17
|
+
const onFilterChange = (event) => {
|
18
|
+
var _a;
|
19
|
+
if ((_a = event.filter.value) === null || _a === void 0 ? void 0 : _a.length)
|
20
|
+
filteredData.current = filterBy(data.slice(), event.filter);
|
21
|
+
else
|
22
|
+
filteredData.current = data;
|
23
|
+
const newData = filteredData.current.slice(0, pageSize);
|
24
|
+
setState({
|
25
|
+
subsetData: newData,
|
26
|
+
skip: 0,
|
27
|
+
total: filteredData.current.length,
|
28
|
+
});
|
29
|
+
};
|
30
|
+
// function to handle page changes for virtualization
|
31
|
+
const pageChange = (event) => {
|
32
|
+
const skip = event.page.skip;
|
33
|
+
const take = event.page.take;
|
34
|
+
const newSubsetData = filteredData.current.slice(skip, skip + take);
|
35
|
+
setState(Object.assign(Object.assign({}, state), { subsetData: newSubsetData, skip: skip }));
|
36
|
+
};
|
37
|
+
return (_jsx("div", Object.assign({ "data-testid": "multiselect", style: { width: "100%" } }, { children: _jsx(MultiSelect, { label: title, data: state.subsetData, textField: textField.toString(), style: { width: "100%" }, virtual: {
|
38
|
+
total: state.total,
|
39
|
+
pageSize: pageSize,
|
40
|
+
skip: state.skip,
|
41
|
+
}, onPageChange: pageChange, filterable: true, onFilterChange: onFilterChange, popupSettings: {
|
42
|
+
height: "210px",
|
43
|
+
}, onChange: (e) => onSelect(limit && e.value.length ? e.value.slice(0, limit) : e.value), autoClose: false, value: selectedData }) })));
|
44
|
+
}
|
package/PropTypes.js
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
package/Toolbar.d.ts
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
type CommonProps = {
|
2
|
+
id: number;
|
3
|
+
isEditing?: boolean;
|
4
|
+
};
|
5
|
+
export declare function ToolbarButton<T extends CommonProps>({ item, data, setData, }: {
|
6
|
+
/** The item object to add. */
|
7
|
+
item: T;
|
8
|
+
/** The data array. */
|
9
|
+
data: T[];
|
10
|
+
/** The function to set the updated data. */
|
11
|
+
setData: Function;
|
12
|
+
}): import("react/jsx-runtime").JSX.Element;
|
13
|
+
export {};
|
package/Toolbar.js
ADDED
@@ -0,0 +1,4 @@
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
+
export function ToolbarButton({ item, data, setData, }) {
|
3
|
+
return (_jsx("button", Object.assign({ title: "Add new", className: "k-button k-button-md k-rounded-md k-button-solid k-button-solid-primary", onClick: () => setData([Object.assign(Object.assign({}, item), { isEditing: true, id: 0 }), ...data]), disabled: data.find((x) => x.isEditing) ? true : false }, { children: "Add Another" })));
|
4
|
+
}
|
package/Utility.d.ts
ADDED
package/Utility.js
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
// function to concatenate text values from dataItem using specified fields and separator
|
2
|
+
export const getTextValue = (dataItem, fields, separator) => {
|
3
|
+
let textValue = "";
|
4
|
+
fields.forEach((field, index) => (textValue += index > 0 ? (separator ? separator : " ") + dataItem[field] : dataItem[field]));
|
5
|
+
return textValue;
|
6
|
+
};
|
7
|
+
export const getDropdownArray = (data, textFields, separator) => {
|
8
|
+
return data.map((x) => {
|
9
|
+
return Object.assign(Object.assign({}, x), { textValue: getTextValue(x, textFields.map((x) => x.toString()), separator) });
|
10
|
+
});
|
11
|
+
};
|
package/_index.test.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -1,138 +1,99 @@
|
|
1
|
-
import {
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
2
2
|
import { GenericDropdown } from "./GenericDropdown";
|
3
|
-
import { GridChangeEvent } from "./PropTypes";
|
4
3
|
import { fireEvent, render } from "@testing-library/react";
|
5
|
-
type DataType = {
|
6
|
-
id: number;
|
7
|
-
name: string;
|
8
|
-
};
|
9
4
|
describe("GenericDropdown", () => {
|
10
|
-
const data
|
5
|
+
const data = [];
|
11
6
|
for (let i = 1; i < 20; i++) {
|
12
7
|
data.push({ id: i, name: `Option ${i}` });
|
13
8
|
}
|
14
9
|
test("renders virtualized ordering by index when passed selectedData", () => {
|
15
10
|
// Set initial selectedData to the second item in the data array
|
16
11
|
let selectedData = data[1];
|
17
|
-
|
18
12
|
// Render the GenericDropdown component with the data, onChange function, textField prop, and selectedData prop
|
19
|
-
let result = render(
|
20
|
-
|
13
|
+
let result = render(_jsx(GenericDropdown, { data: data, onChange: (e) => { }, textField: "name", selectedData: selectedData }));
|
21
14
|
// Get the input element by its role of "combobox"
|
22
15
|
const input = result.getByRole("combobox");
|
23
|
-
|
24
16
|
expect(input.getAttribute("value")).toBe("Option 2");
|
25
17
|
// Simulate a change event on the input element by setting its target value to "O"
|
26
18
|
fireEvent.change(input, { target: { value: "O" } });
|
27
|
-
|
28
19
|
// Simulate a key down event on the input element with the key value of "ArrowDown"
|
29
20
|
fireEvent.keyDown(input, { key: "ArrowDown" });
|
30
|
-
|
31
21
|
// Query the rendered result for elements with the text "Option 1", "Option 2", and "Option 3"
|
32
22
|
let item1 = result.queryByText("Option 1");
|
33
23
|
let item2 = result.queryByText("Option 2");
|
34
24
|
let item3 = result.queryByText("Option 3");
|
35
|
-
|
36
25
|
// Ensure that item1, item2, and item3 are not undefined (i.e., they are rendered)
|
37
26
|
expect(item1).not.toBeUndefined();
|
38
27
|
expect(item2).not.toBeUndefined();
|
39
28
|
expect(item3).not.toBeUndefined();
|
40
|
-
|
41
29
|
// Ensure that there are no elements with the text "Option 9" (i.e., it is not rendered)
|
42
30
|
expect(result.queryAllByText("Option 9")).toHaveLength(0);
|
43
31
|
});
|
44
32
|
test("renders virtualized ordering by index when passed selectedId", () => {
|
45
33
|
// Set initial selectedData to the second item in the data array
|
46
34
|
let selectedId = 2;
|
47
|
-
|
48
35
|
// Render the GenericDropdown component with the data, onChange function, textField prop, and selectedData prop
|
49
|
-
let result = render(
|
50
|
-
|
36
|
+
let result = render(_jsx(GenericDropdown, { data: data, onChange: () => { }, textField: "name", selectedId: selectedId, idField: "id" }));
|
51
37
|
// Get the input element by its role of "combobox"
|
52
38
|
const input = result.getByRole("combobox");
|
53
|
-
|
54
39
|
expect(input.getAttribute("value")).toBe("Option 2");
|
55
40
|
// Simulate a change event on the input element by setting its target value to "O"
|
56
41
|
fireEvent.change(input, { target: { value: "O" } });
|
57
|
-
|
58
42
|
// Simulate a key down event on the input element with the key value of "ArrowDown"
|
59
43
|
fireEvent.keyDown(input, { key: "ArrowDown" });
|
60
|
-
|
61
44
|
// Query the rendered result for elements with the text "Option 1", "Option 2", and "Option 3"
|
62
45
|
let item1 = result.queryByText("Option 1");
|
63
46
|
let item2 = result.queryByText("Option 2");
|
64
47
|
let item3 = result.queryByText("Option 3");
|
65
|
-
|
66
48
|
// Ensure that item1, item2, and item3 are not undefined (i.e., they are rendered)
|
67
49
|
expect(item1).not.toBeUndefined();
|
68
50
|
expect(item2).not.toBeUndefined();
|
69
51
|
expect(item3).not.toBeUndefined();
|
70
|
-
|
71
52
|
// Ensure that there are no elements with the text "Option 9" (i.e., it is not rendered)
|
72
53
|
expect(result.queryAllByText("Option 9")).toHaveLength(0);
|
73
54
|
});
|
74
|
-
|
75
55
|
test("handles change event when selecting by object", () => {
|
76
56
|
// Set initial selectedData to the second item in the data array
|
77
|
-
let selectedData
|
78
|
-
|
57
|
+
let selectedData = data[1];
|
79
58
|
// Render the GenericDropdown component with the data, onChange function, textField prop, and selectedData prop
|
80
|
-
let result = render(
|
81
|
-
|
59
|
+
let result = render(_jsx(GenericDropdown, { data: data, onChange: (e) => (selectedData = e.value), textField: "name", selectedData: selectedData }));
|
82
60
|
// Get the input element by its role of "combobox"
|
83
|
-
|
84
61
|
// Simulate a change event on the input element by setting its target value to "O"
|
85
62
|
let input = result.getByRole("combobox");
|
86
63
|
fireEvent.change(input, { target: { value: "O" } });
|
87
|
-
|
88
64
|
// Get the item element with the text "Option 2"
|
89
65
|
let item2 = result.getByText("Option 2");
|
90
|
-
|
91
66
|
// Simulate a click event on the item element
|
92
67
|
fireEvent.click(item2);
|
93
|
-
|
94
68
|
// Ensure that the input element's value attribute is set to "Option 2"
|
95
69
|
expect(selectedData.id).toBe(2);
|
96
70
|
});
|
97
71
|
test("handles change event when selecting by id", () => {
|
98
72
|
// Set initial selectedData to the second item in the data array
|
99
|
-
let selectedId
|
73
|
+
let selectedId = 1;
|
100
74
|
// Render the GenericDropdown component with the data, onChange function, textField prop, and selectedData prop
|
101
|
-
let result = render(
|
102
|
-
<GenericDropdown data={data} onChange={(e) => (selectedId = e?.value.id || null)} textField="name" selectedId={selectedId} idField="id" />
|
103
|
-
);
|
104
|
-
|
75
|
+
let result = render(_jsx(GenericDropdown, { data: data, onChange: (e) => (selectedId = (e === null || e === void 0 ? void 0 : e.value.id) || null), textField: "name", selectedId: selectedId, idField: "id" }));
|
105
76
|
// Get the input element by its role of "combobox"
|
106
|
-
|
107
77
|
// Simulate a change event on the input element by setting its target value to "O"
|
108
78
|
let input = result.getByRole("combobox");
|
109
79
|
fireEvent.change(input, { target: { value: "O" } });
|
110
|
-
|
111
80
|
// Get the item element with the text "Option 2"
|
112
81
|
let item2 = result.getByText("Option 2");
|
113
|
-
|
114
82
|
// Simulate a click event on the item element
|
115
|
-
|
116
83
|
fireEvent.click(item2);
|
117
|
-
|
118
84
|
// Ensure that the input element's value attribute is set to "Option 2"
|
119
85
|
expect(selectedId).toBe(2);
|
120
86
|
});
|
121
|
-
|
122
87
|
test("only displays items that match the search", () => {
|
123
88
|
// Set initial selectedData to the second item in the data array
|
124
|
-
let selectedData
|
125
|
-
|
89
|
+
let selectedData = data[1];
|
126
90
|
// Render the GenericDropdown component with the data, onChange function, textField prop, and selectedData prop
|
127
|
-
let result = render(
|
128
|
-
|
91
|
+
let result = render(_jsx(GenericDropdown, { data: data, onChange: (e) => (selectedData = e.value), textField: "name", selectedData: selectedData }));
|
129
92
|
let input = result.getByRole("combobox"); // Get the input element by its role of "combobox"
|
130
93
|
fireEvent.change(input, { target: { value: "9" } }); //simulate a change event on the input element
|
131
|
-
|
132
94
|
// Query the rendered result for elements with the text "Option 1" and "Option 9", and store the results in variables
|
133
95
|
let item1 = result.queryAllByText("Option 1");
|
134
96
|
let item9 = result.queryAllByText("Option 9");
|
135
|
-
|
136
97
|
// Ensure that there are no elements with the text "Option 1" and at least one element with the text "Option 9"
|
137
98
|
expect(item1).toHaveLength(0);
|
138
99
|
expect(item9.length).toBeGreaterThan(0);
|
@@ -0,0 +1,10 @@
|
|
1
|
+
export declare function CommandCellCheckBox({ checked, onCheck, onUncheck, disabled, }: {
|
2
|
+
/** Boolean value indicating whether the checkbox is checked (`true`) or unchecked (`false`). */
|
3
|
+
checked: boolean;
|
4
|
+
/** Callback function to be called when the checkbox is checked. */
|
5
|
+
onCheck: () => void;
|
6
|
+
/** Callback function to be called when the checkbox is unchecked. */
|
7
|
+
onUncheck: () => void;
|
8
|
+
/** Boolean value indicating whether the checkbox is disabled. */
|
9
|
+
disabled?: boolean;
|
10
|
+
}): import("react/jsx-runtime").JSX.Element;
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
+
import { Checkbox } from "@progress/kendo-react-inputs";
|
3
|
+
export function CommandCellCheckBox({ checked, onCheck, onUncheck, disabled, }) {
|
4
|
+
const functionToRun = () => {
|
5
|
+
if (checked) {
|
6
|
+
onUncheck();
|
7
|
+
}
|
8
|
+
else {
|
9
|
+
onCheck();
|
10
|
+
}
|
11
|
+
};
|
12
|
+
return (_jsx("td", Object.assign({ className: "justify-content-center", "data-testid": "checkbox" }, { children: _jsx(Checkbox, { checked: checked, onChange: functionToRun, disabled: disabled }) })));
|
13
|
+
}
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import { CommonProps, GridChangeEvent } from "../PropTypes";
|
2
|
+
export declare function CommandCellDate<T extends CommonProps>({ dataItem, onChange, field, }: {
|
3
|
+
/** The data item for the cell. */
|
4
|
+
dataItem: T;
|
5
|
+
/** Callback function to be called when the value changes. */
|
6
|
+
onChange: (e: GridChangeEvent) => void;
|
7
|
+
/** The field of the data item to display in the cell. this field must be formattable into a date. */
|
8
|
+
field: keyof T;
|
9
|
+
}): import("react/jsx-runtime").JSX.Element;
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
+
import { DatePicker } from "@progress/kendo-react-dateinputs";
|
3
|
+
import moment from "moment";
|
4
|
+
export function CommandCellDate({ dataItem, onChange, field, }) {
|
5
|
+
let valString = "" + dataItem[field];
|
6
|
+
let date = moment(valString).format("MM/DD/YY");
|
7
|
+
return (_jsx("td", Object.assign({ "data-testid": "date" }, { children: valString === undefined || dataItem.isEditing ? (_jsx(DatePicker, { value: new Date(moment(valString).format("MMMM, DD YYYY")), onChange: (e) => onChange({
|
8
|
+
field: field.toString(),
|
9
|
+
value: moment(e.value),
|
10
|
+
dataItem: dataItem,
|
11
|
+
}) })) : (date) })));
|
12
|
+
}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
+
export function CommandCellPrice({ cost }) {
|
3
|
+
let formattedCost = new Intl.NumberFormat("en", {
|
4
|
+
style: "currency",
|
5
|
+
currency: "USD",
|
6
|
+
minimumSignificantDigits: 2,
|
7
|
+
maximumFractionDigits: 3,
|
8
|
+
}).format(cost);
|
9
|
+
return _jsx("td", Object.assign({ "data-testid": "price" }, { children: formattedCost }));
|
10
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
export declare function CommandCellSwitch<T extends {
|
2
|
+
isEditing: boolean;
|
3
|
+
[key: string]: any;
|
4
|
+
}>({ props, changeFunction, }: {
|
5
|
+
/** The GridCellProps object containing cell-related properties. */
|
6
|
+
props: {
|
7
|
+
dataItem: T;
|
8
|
+
field?: keyof T;
|
9
|
+
};
|
10
|
+
/** The function to call when the switch value changes. */
|
11
|
+
changeFunction: Function;
|
12
|
+
}): import("react/jsx-runtime").JSX.Element;
|
@@ -0,0 +1,5 @@
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
+
import { Switch } from "@progress/kendo-react-inputs";
|
3
|
+
export function CommandCellSwitch({ props, changeFunction, }) {
|
4
|
+
return (_jsx("td", Object.assign({ "data-testid": "switch" }, { children: props.dataItem.isEditing ? (_jsx(Switch, { onChange: () => changeFunction(), checked: props.dataItem[props.field] })) : (props.dataItem[props.field].toString()) })));
|
5
|
+
}
|
package/index.js
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
export { CommandCellCheckBox } from "./commandCell/CommandCellCheckbox";
|
2
|
+
export { CommandCellDate } from "./commandCell/CommandCellDate";
|
3
|
+
export { CommandCellPrice } from "./commandCell/CommandCellPrice";
|
4
|
+
export { CommandCellSwitch } from "./commandCell/CommandCellSwitch";
|
5
|
+
export { ToolbarButton } from "./Toolbar";
|
6
|
+
export { GenericDropdown } from "./GenericDropdown";
|
7
|
+
export { MultiSelectDropdown } from "./MultiSelectDropdown";
|
package/package.json
CHANGED
package/jest.config.js
DELETED
package/src/GenericDropdown.tsx
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
import React, { useMemo } from "react";
|
2
|
-
import { ComboBox, ComboBoxPageChangeEvent, ComboBoxProps } from "@progress/kendo-react-dropdowns";
|
3
|
-
|
4
|
-
// Define the base properties that are always required
|
5
|
-
interface BaseProps<T> extends ComboBoxProps {
|
6
|
-
data: T[];
|
7
|
-
pageSize?: number;
|
8
|
-
onClear?: () => void;
|
9
|
-
}
|
10
|
-
|
11
|
-
// Option 1: Props when only selectedData is provided
|
12
|
-
interface SelectedDataProps<T> {
|
13
|
-
selectedData?: T;
|
14
|
-
}
|
15
|
-
|
16
|
-
// Option 2: Props when selectedId and idField are both provided
|
17
|
-
interface SelectedIdProps<T> {
|
18
|
-
selectedId?: number;
|
19
|
-
idField: keyof T;
|
20
|
-
}
|
21
|
-
|
22
|
-
// Combining the props into a union type
|
23
|
-
type GenericDropdownProps<T> = BaseProps<T> & (SelectedDataProps<T> | SelectedIdProps<T>);
|
24
|
-
|
25
|
-
// GenericDropdown component definition
|
26
|
-
export function GenericDropdown<T>({ data, pageSize = 6, onClear, ...props }: GenericDropdownProps<T>) {
|
27
|
-
// Compute selected item based on the provided props using type guards
|
28
|
-
const selectedItem = useMemo(() => {
|
29
|
-
if ("selectedData" in props) {
|
30
|
-
return props.selectedData;
|
31
|
-
} else if ("selectedId" in props && "idField" in props) {
|
32
|
-
return data.find((item) => item[props.idField] === props.selectedId) ?? null;
|
33
|
-
}
|
34
|
-
return null;
|
35
|
-
}, [props, data]);
|
36
|
-
const [skip, setSkip] = React.useState(0);
|
37
|
-
const [state, setState] = React.useState({
|
38
|
-
subsetData: data.slice(0, pageSize),
|
39
|
-
skip: 0,
|
40
|
-
});
|
41
|
-
const pageChange = (event: ComboBoxPageChangeEvent) => {
|
42
|
-
const skip = event.page.skip;
|
43
|
-
const take = event.page.take;
|
44
|
-
const newSubsetData = data.slice(skip, skip + take);
|
45
|
-
setState({
|
46
|
-
subsetData: newSubsetData,
|
47
|
-
skip: skip,
|
48
|
-
});
|
49
|
-
};
|
50
|
-
return (
|
51
|
-
<ComboBox
|
52
|
-
data={state.subsetData}
|
53
|
-
value={selectedItem}
|
54
|
-
virtual={{
|
55
|
-
pageSize,
|
56
|
-
skip,
|
57
|
-
total: data.length,
|
58
|
-
}}
|
59
|
-
onPageChange={pageChange}
|
60
|
-
{...props}
|
61
|
-
/>
|
62
|
-
);
|
63
|
-
}
|
64
|
-
|
65
|
-
export default GenericDropdown;
|
@@ -1,79 +0,0 @@
|
|
1
|
-
import { useRef, useState } from "react";
|
2
|
-
import { filterBy } from "@progress/kendo-data-query";
|
3
|
-
import { MultiSelect, MultiSelectPageChangeEvent, MultiSelectFilterChangeEvent } from "@progress/kendo-react-dropdowns";
|
4
|
-
export function MultiSelectDropdown<T>({
|
5
|
-
data,
|
6
|
-
selectedData,
|
7
|
-
textField,
|
8
|
-
onSelect,
|
9
|
-
title,
|
10
|
-
limit,
|
11
|
-
}: {
|
12
|
-
/** The data array for the dropdown options. */
|
13
|
-
data: T[];
|
14
|
-
/** The array of selected data items. */
|
15
|
-
selectedData: T[];
|
16
|
-
/** The field names to use for text values in the dropdown. */
|
17
|
-
textField: keyof T;
|
18
|
-
/** The function to call when an item is selected or deselected. */
|
19
|
-
onSelect: Function;
|
20
|
-
/** The optional title of the dropdown. */
|
21
|
-
title?: string;
|
22
|
-
/** The optional limit of the maximum number of selected items. */
|
23
|
-
limit?: number;
|
24
|
-
}) {
|
25
|
-
//local state
|
26
|
-
const pageSize = 8;
|
27
|
-
const [state, setState] = useState({
|
28
|
-
skip: 0,
|
29
|
-
total: data.length,
|
30
|
-
subsetData: data.slice(0, pageSize),
|
31
|
-
});
|
32
|
-
|
33
|
-
//external function variables
|
34
|
-
const filteredData = useRef(data.slice());
|
35
|
-
//function creation
|
36
|
-
// function to handle filter changes
|
37
|
-
const onFilterChange = (event: MultiSelectFilterChangeEvent) => {
|
38
|
-
if (event.filter.value?.length) filteredData.current = filterBy(data.slice(), event.filter);
|
39
|
-
else filteredData.current = data;
|
40
|
-
const newData = filteredData.current.slice(0, pageSize);
|
41
|
-
setState({
|
42
|
-
subsetData: newData,
|
43
|
-
skip: 0,
|
44
|
-
total: filteredData.current.length,
|
45
|
-
});
|
46
|
-
};
|
47
|
-
// function to handle page changes for virtualization
|
48
|
-
const pageChange = (event: MultiSelectPageChangeEvent) => {
|
49
|
-
const skip = event.page.skip;
|
50
|
-
const take = event.page.take;
|
51
|
-
const newSubsetData = filteredData.current.slice(skip, skip + take);
|
52
|
-
setState({ ...state, subsetData: newSubsetData, skip: skip });
|
53
|
-
};
|
54
|
-
|
55
|
-
return (
|
56
|
-
<div data-testid={"multiselect"} style={{ width: "100%" }}>
|
57
|
-
<MultiSelect
|
58
|
-
label={title}
|
59
|
-
data={state.subsetData}
|
60
|
-
textField={textField.toString()} // name of the field to use for display text
|
61
|
-
style={{ width: "100%" }}
|
62
|
-
virtual={{
|
63
|
-
total: state.total,
|
64
|
-
pageSize: pageSize,
|
65
|
-
skip: state.skip,
|
66
|
-
}}
|
67
|
-
onPageChange={pageChange}
|
68
|
-
filterable={true}
|
69
|
-
onFilterChange={onFilterChange}
|
70
|
-
popupSettings={{
|
71
|
-
height: "210px",
|
72
|
-
}}
|
73
|
-
onChange={(e) => onSelect(limit && e.value.length ? e.value.slice(0, limit) : e.value)}
|
74
|
-
autoClose={false}
|
75
|
-
value={selectedData} ///right now: clears selected values whenever selected Vendor Value changes. This will need to be changed to something better in the future
|
76
|
-
/>
|
77
|
-
</div>
|
78
|
-
);
|
79
|
-
}
|
package/src/Toolbar.tsx
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
type CommonProps = {
|
2
|
-
id: number;
|
3
|
-
isEditing?: boolean;
|
4
|
-
};
|
5
|
-
export function ToolbarButton<T extends CommonProps>({
|
6
|
-
item,
|
7
|
-
data,
|
8
|
-
setData,
|
9
|
-
}: {
|
10
|
-
/** The item object to add. */
|
11
|
-
item: T;
|
12
|
-
/** The data array. */
|
13
|
-
data: T[];
|
14
|
-
/** The function to set the updated data. */
|
15
|
-
setData: Function;
|
16
|
-
}) {
|
17
|
-
return (
|
18
|
-
<button
|
19
|
-
title="Add new"
|
20
|
-
className="k-button k-button-md k-rounded-md k-button-solid k-button-solid-primary"
|
21
|
-
onClick={() => setData([{ ...item, isEditing: true, id: 0 }, ...data])}
|
22
|
-
disabled={data.find((x) => x.isEditing) ? true : false}
|
23
|
-
>
|
24
|
-
Add Another
|
25
|
-
</button>
|
26
|
-
);
|
27
|
-
}
|
package/src/Utility.ts
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
// function to concatenate text values from dataItem using specified fields and separator
|
2
|
-
export const getTextValue = (dataItem: any, fields: string[], separator?: string) => {
|
3
|
-
let textValue = "";
|
4
|
-
fields.forEach((field, index) => (textValue += index > 0 ? (separator ? separator : " ") + dataItem[field] : dataItem[field]));
|
5
|
-
return textValue;
|
6
|
-
};
|
7
|
-
|
8
|
-
export const getDropdownArray = <T>(data: T[], textFields: (keyof T)[], separator: string) => {
|
9
|
-
return data.map((x) => {
|
10
|
-
return {
|
11
|
-
...x,
|
12
|
-
textValue: getTextValue(
|
13
|
-
x,
|
14
|
-
textFields.map((x) => x.toString()),
|
15
|
-
separator
|
16
|
-
),
|
17
|
-
};
|
18
|
-
});
|
19
|
-
};
|
@@ -1,31 +0,0 @@
|
|
1
|
-
import { Checkbox, CheckboxChangeEvent } from "@progress/kendo-react-inputs";
|
2
|
-
|
3
|
-
export function CommandCellCheckBox({
|
4
|
-
checked,
|
5
|
-
onCheck,
|
6
|
-
onUncheck,
|
7
|
-
disabled,
|
8
|
-
}: {
|
9
|
-
/** Boolean value indicating whether the checkbox is checked (`true`) or unchecked (`false`). */
|
10
|
-
checked: boolean;
|
11
|
-
/** Callback function to be called when the checkbox is checked. */
|
12
|
-
onCheck: () => void;
|
13
|
-
/** Callback function to be called when the checkbox is unchecked. */
|
14
|
-
onUncheck: () => void;
|
15
|
-
/** Boolean value indicating whether the checkbox is disabled. */
|
16
|
-
disabled?: boolean;
|
17
|
-
}) {
|
18
|
-
const functionToRun = () => {
|
19
|
-
if (checked) {
|
20
|
-
onUncheck();
|
21
|
-
} else {
|
22
|
-
onCheck();
|
23
|
-
}
|
24
|
-
};
|
25
|
-
|
26
|
-
return (
|
27
|
-
<td className="justify-content-center" data-testid="checkbox">
|
28
|
-
<Checkbox checked={checked} onChange={functionToRun} disabled={disabled} />
|
29
|
-
</td>
|
30
|
-
);
|
31
|
-
}
|
@@ -1,36 +0,0 @@
|
|
1
|
-
import { DatePicker } from "@progress/kendo-react-dateinputs";
|
2
|
-
import moment from "moment";
|
3
|
-
import { CommonProps, GridChangeEvent } from "../PropTypes";
|
4
|
-
export function CommandCellDate<T extends CommonProps>({
|
5
|
-
dataItem,
|
6
|
-
onChange,
|
7
|
-
field,
|
8
|
-
}: {
|
9
|
-
/** The data item for the cell. */
|
10
|
-
dataItem: T;
|
11
|
-
/** Callback function to be called when the value changes. */
|
12
|
-
onChange: (e: GridChangeEvent) => void;
|
13
|
-
/** The field of the data item to display in the cell. this field must be formattable into a date. */
|
14
|
-
field: keyof T;
|
15
|
-
}) {
|
16
|
-
let valString = "" + dataItem[field];
|
17
|
-
let date = moment(valString).format("MM/DD/YY");
|
18
|
-
return (
|
19
|
-
<td data-testid="date">
|
20
|
-
{valString === undefined || dataItem.isEditing ? (
|
21
|
-
<DatePicker
|
22
|
-
value={new Date(moment(valString).format("MMMM, DD YYYY"))}
|
23
|
-
onChange={(e) =>
|
24
|
-
onChange({
|
25
|
-
field: field.toString(),
|
26
|
-
value: moment(e.value),
|
27
|
-
dataItem: dataItem,
|
28
|
-
})
|
29
|
-
}
|
30
|
-
/>
|
31
|
-
) : (
|
32
|
-
date
|
33
|
-
)}
|
34
|
-
</td>
|
35
|
-
);
|
36
|
-
}
|
@@ -1,9 +0,0 @@
|
|
1
|
-
export function CommandCellPrice({ cost }: { /** The cost value for the cell. */ cost: number }) {
|
2
|
-
let formattedCost: any = new Intl.NumberFormat("en", {
|
3
|
-
style: "currency",
|
4
|
-
currency: "USD",
|
5
|
-
minimumSignificantDigits: 2,
|
6
|
-
maximumFractionDigits: 3,
|
7
|
-
}).format(cost);
|
8
|
-
return <td data-testid="price">{formattedCost}</td>;
|
9
|
-
}
|
@@ -1,20 +0,0 @@
|
|
1
|
-
import { Switch } from "@progress/kendo-react-inputs";
|
2
|
-
export function CommandCellSwitch<T extends { isEditing: boolean; [key: string]: any }>({
|
3
|
-
props,
|
4
|
-
changeFunction,
|
5
|
-
}: {
|
6
|
-
/** The GridCellProps object containing cell-related properties. */
|
7
|
-
props: { dataItem: T; field?: keyof T };
|
8
|
-
/** The function to call when the switch value changes. */
|
9
|
-
changeFunction: Function;
|
10
|
-
}) {
|
11
|
-
return (
|
12
|
-
<td data-testid="switch">
|
13
|
-
{props.dataItem.isEditing ? (
|
14
|
-
<Switch onChange={() => changeFunction()} checked={props.dataItem[props.field!]} />
|
15
|
-
) : (
|
16
|
-
props.dataItem[props.field!].toString()
|
17
|
-
)}
|
18
|
-
</td>
|
19
|
-
);
|
20
|
-
}
|
package/tsconfig.json
DELETED
File without changes
|