@scheels-softdev/kendoreact-generics 2.2.4 → 2.2.6

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.
Files changed (38) hide show
  1. package/FilterCellDropdown.d.ts +8 -0
  2. package/FilterCellDropdown.js +32 -0
  3. package/GenericDropdown.d.ts +30 -0
  4. package/GenericDropdown.js +92 -0
  5. package/MultiSelectDropdown.d.ts +9 -0
  6. package/MultiSelectDropdown.js +54 -0
  7. package/{src/PropTypes.ts → PropTypes.d.ts} +0 -1
  8. package/PropTypes.js +1 -0
  9. package/Toolbar.d.ts +10 -0
  10. package/Toolbar.js +4 -0
  11. package/Utility.d.ts +1 -0
  12. package/{src/Utility.ts → Utility.js} +1 -1
  13. package/commandCell/CommandCellCheckbox.d.ts +5 -0
  14. package/commandCell/CommandCellCheckbox.js +13 -0
  15. package/commandCell/CommandCellDDWithoutId.d.ts +11 -0
  16. package/commandCell/CommandCellDDWithoutId.js +7 -0
  17. package/commandCell/CommandCellDate.d.ts +6 -0
  18. package/commandCell/CommandCellDate.js +12 -0
  19. package/commandCell/CommandCellDropdown.d.ts +12 -0
  20. package/commandCell/CommandCellDropdown.js +11 -0
  21. package/commandCell/CommandCellPrice.d.ts +3 -0
  22. package/commandCell/CommandCellPrice.js +10 -0
  23. package/commandCell/CommandCellSwitch.d.ts +5 -0
  24. package/commandCell/CommandCellSwitch.js +5 -0
  25. package/index.js +10 -0
  26. package/package.json +1 -1
  27. package/src/FilterCellDropdown.tsx +0 -47
  28. package/src/GenericDropdown.tsx +0 -152
  29. package/src/MultiSelectDropdown.tsx +0 -105
  30. package/src/Toolbar.tsx +0 -16
  31. package/src/commandCell/CommandCellCheckbox.tsx +0 -17
  32. package/src/commandCell/CommandCellDDWithoutId.tsx +0 -24
  33. package/src/commandCell/CommandCellDate.tsx +0 -33
  34. package/src/commandCell/CommandCellDropdown.tsx +0 -30
  35. package/src/commandCell/CommandCellPrice.tsx +0 -9
  36. package/src/commandCell/CommandCellSwitch.tsx +0 -14
  37. package/tsconfig.json +0 -13
  38. /package/{src/index.ts → index.d.ts} +0 -0
@@ -0,0 +1,8 @@
1
+ import { GridFilterCellProps } from "@progress/kendo-react-grid";
2
+ interface DropdownFilterCellProps<T> extends GridFilterCellProps {
3
+ data: T[];
4
+ textFields: (keyof T)[];
5
+ separator?: string;
6
+ }
7
+ export declare function FilterCellDropdown<T>(props: DropdownFilterCellProps<T>): import("react/jsx-runtime").JSX.Element;
8
+ export {};
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button } from "@progress/kendo-react-buttons";
3
+ import { GenericDropdown } from "./GenericDropdown";
4
+ // Define the DropdownFilterCell component with props of type DropdownFilterCellProps
5
+ export function FilterCellDropdown(props) {
6
+ // Define a function that returns true if a value is not undefined or null, and is different from the default item
7
+ let hasValue = (value) => Boolean(value);
8
+ // Define an onChange function that will be called when the ComboBox value changes
9
+ const onChange = (event) => {
10
+ var _a, _b;
11
+ // Update the hasValue variable based on the new value of the ComboBox
12
+ hasValue = hasValue((_b = (_a = event === null || event === void 0 ? void 0 : event.target) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.id);
13
+ // Call the onChange function passed down as a prop, passing a filter object with the new value and operator
14
+ props.onChange({
15
+ value: hasValue ? event.target.value.id : "",
16
+ operator: hasValue ? "eq" : "",
17
+ syntheticEvent: event.syntheticEvent,
18
+ });
19
+ };
20
+ // Define an onClearButtonClick function that will be called when the Clear button is clicked
21
+ const onClearButtonClick = (event) => {
22
+ event.preventDefault();
23
+ // Call the onChange function passed down as a prop, passing a filter object with empty values
24
+ props.onChange({
25
+ value: "",
26
+ operator: "",
27
+ syntheticEvent: event,
28
+ });
29
+ };
30
+ // Render a div containing a GenericDropdownWithSearch component and a Clear button
31
+ return (_jsxs("div", Object.assign({ className: "k-filtercell", "data-testid": "dropdownFilter" }, { children: [_jsx(GenericDropdown, { data: props.data, onChange: onChange, selectedId: props.value, textFields: [...props.textFields], separator: props.separator }), _jsx(Button, { title: "Clear", disabled: !hasValue(props.value), onClick: onClearButtonClick, icon: "filter-clear" })] })));
32
+ }
@@ -0,0 +1,30 @@
1
+ import { CSSProperties } from "react";
2
+ /**
3
+ * JSX Component for displaying selected images in a fullscreen Modal
4
+ * @param {object} props
5
+ * @param {T[]} props.data array of data objects
6
+ * @param {number} [props.selectedId] id of the selected data object
7
+ * @param {T} [props.selectedData] if there is no identity key in the object and you need to compare the entire object, use this instead of selectedId
8
+ * @param {Function} props.onChange function to call when the selected value changes
9
+ * @param {(keyof T)[] } props.textFields array of field names to use for text values
10
+ * @param {string} [props.separator] optional separator to use for concatenating text values
11
+ * @param {object} [props.disabled] boolean to disable the dropdown
12
+ * @param {keyof T} [props.idField] if the id field to look at isn't 'id', what is it?
13
+ * @param {string} [props.title] the label of the dropdown
14
+ * @param {boolean} [props.showClearButton] set to false if you want to hide clear button
15
+ * @param {CSSProperties} [props.style] the CSS Properties you want to use. It is generally recommended to do styling in your App.css file but if necessary this prop is available to you
16
+ * @returns
17
+ */
18
+ export declare function GenericDropdown<T>({ data, selectedId, selectedData, onChange, textFields, separator, disabled, idField, title, hideClearButton, style, }: {
19
+ data: T[];
20
+ selectedId?: number;
21
+ selectedData?: T;
22
+ onChange: Function;
23
+ textFields: (keyof T)[];
24
+ separator?: string;
25
+ idField?: keyof T;
26
+ disabled?: boolean;
27
+ title?: string;
28
+ hideClearButton?: boolean;
29
+ style?: CSSProperties;
30
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,92 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { ComboBox } from "@progress/kendo-react-dropdowns";
3
+ import { filterBy } from "@progress/kendo-data-query";
4
+ import { useEffect, useRef, useState } from "react";
5
+ import { getTextValue } from "./Utility";
6
+ //TODO add a style property
7
+ //TODO add metadata documentation
8
+ // component that renders a dropdown with a search filter
9
+ /**
10
+ * JSX Component for displaying selected images in a fullscreen Modal
11
+ * @param {object} props
12
+ * @param {T[]} props.data array of data objects
13
+ * @param {number} [props.selectedId] id of the selected data object
14
+ * @param {T} [props.selectedData] if there is no identity key in the object and you need to compare the entire object, use this instead of selectedId
15
+ * @param {Function} props.onChange function to call when the selected value changes
16
+ * @param {(keyof T)[] } props.textFields array of field names to use for text values
17
+ * @param {string} [props.separator] optional separator to use for concatenating text values
18
+ * @param {object} [props.disabled] boolean to disable the dropdown
19
+ * @param {keyof T} [props.idField] if the id field to look at isn't 'id', what is it?
20
+ * @param {string} [props.title] the label of the dropdown
21
+ * @param {boolean} [props.showClearButton] set to false if you want to hide clear button
22
+ * @param {CSSProperties} [props.style] the CSS Properties you want to use. It is generally recommended to do styling in your App.css file but if necessary this prop is available to you
23
+ * @returns
24
+ */
25
+ export function GenericDropdown({ data, selectedId, selectedData, onChange, textFields, separator, disabled, idField, title, hideClearButton, style, }) {
26
+ if (selectedId !== undefined && selectedData !== undefined) {
27
+ throw new Error("You cannot provide both selectedData and selectedId to GenericDropdown.");
28
+ }
29
+ useEffect(() => {
30
+ console.log(selectedId);
31
+ }, [selectedId]);
32
+ //local state
33
+ const pageSize = 8;
34
+ const [dataList, setDataList] = useState(data.map((x) => {
35
+ return Object.assign(Object.assign({}, x), { textValue: getTextValue(x, textFields.map((x) => x.toString()), separator) });
36
+ }));
37
+ const [state, setState] = useState({
38
+ skip: 0,
39
+ total: dataList.length,
40
+ subsetData: dataList.slice(0, pageSize),
41
+ });
42
+ //external function variables
43
+ const filteredData = useRef(dataList.slice());
44
+ //function creation
45
+ // function to handle filter changes
46
+ const onFilterChange = (event) => {
47
+ var _a;
48
+ if ((_a = event.filter.value) === null || _a === void 0 ? void 0 : _a.length)
49
+ filteredData.current = filterBy(dataList.slice(), event.filter);
50
+ else
51
+ filteredData.current = dataList;
52
+ const newData = filteredData.current.slice(0, pageSize);
53
+ setState({
54
+ subsetData: newData,
55
+ skip: 0,
56
+ total: filteredData.current.length,
57
+ });
58
+ };
59
+ // function to handle page changes for virtualization
60
+ const pageChange = (event) => {
61
+ const skip = event.page.skip;
62
+ const take = event.page.take;
63
+ const newSubsetData = filteredData.current.slice(skip, skip + take);
64
+ setState(Object.assign(Object.assign({}, state), { subsetData: newSubsetData, skip: skip }));
65
+ };
66
+ //change event listeners
67
+ useEffect(() => {
68
+ setDataList(data.map((x) => {
69
+ return Object.assign(Object.assign({}, x), { textValue: getTextValue(x, textFields.map((x) => x.toString()), separator) });
70
+ }));
71
+ }, [data, textFields, separator]);
72
+ const findByIndex = (id, idKey, data) => {
73
+ console.log(id, data, idField);
74
+ const item = data.find((item) => id === item[idKey || "id"]);
75
+ console.log(item);
76
+ return item;
77
+ };
78
+ const findByValue = (item, data) => {
79
+ console.log(item, data);
80
+ const returnVal = data.find((x) => JSON.stringify(Object.assign(Object.assign({}, x), selectedData)) === JSON.stringify(Object.assign({}, x)));
81
+ console.log(returnVal);
82
+ return returnVal;
83
+ };
84
+ return (_jsx("div", Object.assign({ "data-testid": "dropdown" }, { children: _jsx(ComboBox, { style: style, label: title, disabled: disabled, data: state.subsetData, textField: "textValue", virtual: {
85
+ // enable virtualization for large datasets
86
+ total: state.total,
87
+ pageSize: pageSize,
88
+ skip: state.skip,
89
+ }, suggest: true, onPageChange: pageChange, filterable: true, onFilterChange: onFilterChange, popupSettings: {
90
+ height: "210px",
91
+ }, onChange: (e) => onChange(e), onBlur: (e) => e.nativeEvent.preventDefault(), clearButton: !hideClearButton, value: !selectedId && !selectedData ? null : findByIndex(selectedId, idField, dataList) || findByValue(selectedData, dataList) || null }) })));
92
+ }
@@ -0,0 +1,9 @@
1
+ export declare function MultiSelectDropdown<T>({ data, selectedData, textFields, selectEvent, title, separator, limit, }: {
2
+ data: T[];
3
+ selectedData: T[];
4
+ textFields: (keyof T)[];
5
+ selectEvent: Function;
6
+ title?: string;
7
+ separator?: string;
8
+ limit?: number;
9
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,54 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { filterBy } from "@progress/kendo-data-query";
4
+ import { MultiSelect } from "@progress/kendo-react-dropdowns";
5
+ import { getTextValue } from "./Utility";
6
+ export function MultiSelectDropdown({ data, selectedData, textFields, selectEvent, title, separator, limit, }) {
7
+ //local state
8
+ const pageSize = 8;
9
+ const [dataList, setDataList] = useState(data.map((x) => {
10
+ return Object.assign(Object.assign({}, x), { textValue: getTextValue(x, textFields.map((x) => x.toString()), separator) });
11
+ }));
12
+ const [state, setState] = useState({
13
+ skip: 0,
14
+ total: dataList.length,
15
+ subsetData: dataList.slice(0, pageSize),
16
+ });
17
+ //external function variables
18
+ const filteredData = useRef(dataList.slice());
19
+ //function creation
20
+ // function to handle filter changes
21
+ const onFilterChange = (event) => {
22
+ var _a;
23
+ if ((_a = event.filter.value) === null || _a === void 0 ? void 0 : _a.length)
24
+ filteredData.current = filterBy(dataList.slice(), event.filter);
25
+ else
26
+ filteredData.current = dataList;
27
+ const newData = filteredData.current.slice(0, pageSize);
28
+ setState({
29
+ subsetData: newData,
30
+ skip: 0,
31
+ total: filteredData.current.length,
32
+ });
33
+ };
34
+ // function to handle page changes for virtualization
35
+ const pageChange = (event) => {
36
+ const skip = event.page.skip;
37
+ const take = event.page.take;
38
+ const newSubsetData = filteredData.current.slice(skip, skip + take);
39
+ setState(Object.assign(Object.assign({}, state), { subsetData: newSubsetData, skip: skip }));
40
+ };
41
+ //change event listeners
42
+ useEffect(() => {
43
+ setDataList(data.map((x) => {
44
+ return Object.assign(Object.assign({}, x), { textValue: getTextValue(x, textFields.map((x) => x.toString()), separator) });
45
+ }));
46
+ }, [data, textFields, separator]);
47
+ return (_jsx("div", Object.assign({ "data-testid": "multiselect", style: { width: "100%" } }, { children: _jsx(MultiSelect, { label: title, data: state.subsetData, textField: "textValue", style: { width: "100%" }, virtual: {
48
+ total: state.total,
49
+ pageSize: pageSize,
50
+ skip: state.skip,
51
+ }, onPageChange: pageChange, filterable: true, onFilterChange: onFilterChange, popupSettings: {
52
+ height: "210px",
53
+ }, onChange: (e) => selectEvent(limit && e.value.length ? e.value.slice(0, limit) : e.value), autoClose: false, value: selectedData }) })));
54
+ }
@@ -2,7 +2,6 @@ export type CommonProps = {
2
2
  isEditing?: boolean;
3
3
  id?: number;
4
4
  };
5
-
6
5
  export type GridChangeEvent = {
7
6
  value: any;
8
7
  field?: string;
package/PropTypes.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/Toolbar.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ type CommonProps = {
2
+ id: number;
3
+ isEditing?: boolean;
4
+ };
5
+ export declare function ToolbarButton<T extends CommonProps>({ item, data, setData }: {
6
+ item: T;
7
+ data: T[];
8
+ setData: Function;
9
+ }): import("react/jsx-runtime").JSX.Element;
10
+ 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
@@ -0,0 +1 @@
1
+ export declare const getTextValue: (dataItem: any, fields: string[], separator?: string) => string;
@@ -1,5 +1,5 @@
1
1
  // function to concatenate text values from dataItem using specified fields and separator
2
- export const getTextValue = (dataItem: any, fields: string[], separator?: string) => {
2
+ export const getTextValue = (dataItem, fields, separator) => {
3
3
  let textValue = "";
4
4
  fields.forEach((field, index) => (textValue += index > 0 ? (separator ? separator : " ") + dataItem[field] : dataItem[field]));
5
5
  return textValue;
@@ -0,0 +1,5 @@
1
+ export declare function CommandCellCheckBox({ checked, onCheck, onUncheck }: {
2
+ checked: boolean;
3
+ onCheck: Function;
4
+ onUncheck: Function;
5
+ }): 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 }) {
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 }) })));
13
+ }
@@ -0,0 +1,11 @@
1
+ import { ComboBoxChangeEvent } from "@progress/kendo-react-dropdowns";
2
+ export declare function CommandCellDDWithoutId<T>(props: {
3
+ data: T[];
4
+ selectedData: T;
5
+ textFields: (keyof T)[];
6
+ onChange: (e: ComboBoxChangeEvent) => void;
7
+ separator?: string;
8
+ checkEditField?: boolean;
9
+ isEditing?: boolean;
10
+ showClearButton?: boolean;
11
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { GenericDropdown } from "../GenericDropdown";
3
+ export function CommandCellDDWithoutId(props) {
4
+ return (_jsx("td", { children: props.checkEditField && !props.isEditing ? (props.textFields.map((x) => props.data.find((y) => y === props.selectedData)[x]).join(props.separator || " ")) : (
5
+ // If "props.checkEditField" is false or "props.isEditing" is true, render the GenericDropdownWithSearch component with the "props" passed to it
6
+ _jsx(GenericDropdown, Object.assign({}, props))) }));
7
+ }
@@ -0,0 +1,6 @@
1
+ import { CommonProps, GridChangeEvent } from "../PropTypes";
2
+ export declare function CommandCellDate<T extends CommonProps>({ dataItem, chgFn: changeFunction, field, }: {
3
+ dataItem: T;
4
+ chgFn: (e: GridChangeEvent) => void;
5
+ field: keyof T;
6
+ }): 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, chgFn: changeFunction, 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) => changeFunction({
8
+ field: field.toString(),
9
+ value: moment(e.value),
10
+ dataItem: dataItem,
11
+ }) })) : (date) })));
12
+ }
@@ -0,0 +1,12 @@
1
+ import { ComboBoxChangeEvent } from "@progress/kendo-react-dropdowns";
2
+ export declare function CommandCellDropdown<T>(props: {
3
+ data: T[];
4
+ selectedId: number;
5
+ textFields: (keyof T)[];
6
+ onChange: (e: ComboBoxChangeEvent) => void;
7
+ separator?: string;
8
+ checkEditField?: boolean;
9
+ isEditing?: boolean;
10
+ idField?: keyof T;
11
+ showClearButton?: boolean;
12
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { GenericDropdown } from "../GenericDropdown";
3
+ // This exports a function component called "CommandCellDropdown"
4
+ // It takes in various props that are used to render a dropdown in a table cell
5
+ export function CommandCellDropdown(props) {
6
+ return (_jsx("td", { children: props.checkEditField && !props.isEditing ? (props.textFields
7
+ .map((x) => props.data.find((y) => y[props.idField ? props.idField : "id"] === props.selectedId)[x])
8
+ .join(props.separator || " ")) : (
9
+ // If "props.checkEditField" is false or "props.isEditing" is true, render the GenericDropdownWithSearch component with the "props" passed to it
10
+ _jsx(GenericDropdown, Object.assign({}, props))) }));
11
+ }
@@ -0,0 +1,3 @@
1
+ export declare function CommandCellPrice({ cost }: {
2
+ cost: number;
3
+ }): import("react/jsx-runtime").JSX.Element;
@@ -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,5 @@
1
+ import { GridCellProps } from "@progress/kendo-react-grid";
2
+ export declare function CommandCellSwitch({ props, changeFunction }: {
3
+ props: GridCellProps;
4
+ changeFunction: Function;
5
+ }): 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,10 @@
1
+ export { CommandCellCheckBox } from "./commandCell/CommandCellCheckbox";
2
+ export { CommandCellDate } from "./commandCell/CommandCellDate";
3
+ export { CommandCellDropdown } from "./commandCell/CommandCellDropdown";
4
+ export { CommandCellDDWithoutId } from "./commandCell/CommandCellDDWithoutId";
5
+ export { CommandCellPrice } from "./commandCell/CommandCellPrice";
6
+ export { CommandCellSwitch } from "./commandCell/CommandCellSwitch";
7
+ export { FilterCellDropdown } from "./FilterCellDropdown";
8
+ export { ToolbarButton } from "./Toolbar";
9
+ export { GenericDropdown } from "./GenericDropdown";
10
+ export { MultiSelectDropdown } from "./MultiSelectDropdown";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scheels-softdev/kendoreact-generics",
3
- "version": "2.2.4",
3
+ "version": "2.2.6",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",
@@ -1,47 +0,0 @@
1
- import { ComboBoxChangeEvent } from "@progress/kendo-react-dropdowns";
2
- import { GridFilterCellProps } from "@progress/kendo-react-grid";
3
- import { Button } from "@progress/kendo-react-buttons";
4
- import { GenericDropdown } from "./GenericDropdown";
5
-
6
- interface DropdownFilterCellProps<T> extends GridFilterCellProps {
7
- data: T[];
8
- textFields: (keyof T)[];
9
- separator?: string;
10
- }
11
-
12
- // Define the DropdownFilterCell component with props of type DropdownFilterCellProps
13
- export function FilterCellDropdown<T>(props: DropdownFilterCellProps<T>) {
14
- // Define a function that returns true if a value is not undefined or null, and is different from the default item
15
- let hasValue: any = (value: string) => Boolean(value);
16
-
17
- // Define an onChange function that will be called when the ComboBox value changes
18
- const onChange = (event: ComboBoxChangeEvent) => {
19
- // Update the hasValue variable based on the new value of the ComboBox
20
- hasValue = hasValue(event?.target?.value?.id);
21
- // Call the onChange function passed down as a prop, passing a filter object with the new value and operator
22
- props.onChange({
23
- value: hasValue ? event.target.value.id : "", // Use the ID of the selected value as the filter value
24
- operator: hasValue ? "eq" : "", // Use the "eq" operator if the value is non-empty, otherwise use an empty string
25
- syntheticEvent: event.syntheticEvent,
26
- });
27
- };
28
-
29
- // Define an onClearButtonClick function that will be called when the Clear button is clicked
30
- const onClearButtonClick = (event: any) => {
31
- event.preventDefault();
32
- // Call the onChange function passed down as a prop, passing a filter object with empty values
33
- props.onChange({
34
- value: "", // Set the filter value to an empty string
35
- operator: "", // Set the operator to an empty string
36
- syntheticEvent: event,
37
- });
38
- };
39
-
40
- // Render a div containing a GenericDropdownWithSearch component and a Clear button
41
- return (
42
- <div className="k-filtercell" data-testid="dropdownFilter">
43
- <GenericDropdown data={props.data} onChange={onChange} selectedId={props.value} textFields={[...props.textFields]} separator={props.separator} />
44
- <Button title="Clear" disabled={!hasValue(props.value)} onClick={onClearButtonClick} icon="filter-clear" />
45
- </div>
46
- );
47
- }
@@ -1,152 +0,0 @@
1
- import { ComboBox, ComboBoxFilterChangeEvent, ComboBoxPageChangeEvent } from "@progress/kendo-react-dropdowns";
2
- import { filterBy } from "@progress/kendo-data-query";
3
- import { CSSProperties, useEffect, useRef, useState } from "react";
4
- import { getTextValue } from "./Utility";
5
- //TODO add a style property
6
- //TODO add metadata documentation
7
- // component that renders a dropdown with a search filter
8
- /**
9
- * JSX Component for displaying selected images in a fullscreen Modal
10
- * @param {object} props
11
- @param {T[]} [props.data] array of data objects
12
- @param {number | undefined} [props.selectedId] id of the selected data object
13
- @param {T | undefined} [props.selectedData] if there is no identity key in the object and you need to compare the entire object, use this instead of selectedId
14
- @param {Function} [props.onChange] function to call when the selected value changes
15
- @param {(keyof T)[] } [props.textFields] array of field names to use for text values
16
- @param {string | undefined} [props.separator] optional separator to use for concatenating text values
17
- @param {object | undefined} [props.disabled] boolean to disable the dropdown
18
- @param {keyof T | undefined} [props.idField] if the id field to look at isn't 'id', what is it?
19
- @param {string | undefined} [props.title] the label of the dropdown
20
- @param {boolean | undefined} [props.showClearButton] set to false if you want to hide clear button
21
- @param {CSSProperties | undefined} [props.style] the CSS Properties you want to use. It is generally recommended to do styling in your App.css file but if necessary this prop is available to you
22
- * @returns
23
- */
24
- export function GenericDropdown<T>({
25
- data,
26
- selectedId,
27
- selectedData,
28
- onChange,
29
- textFields,
30
- separator,
31
- disabled,
32
- idField,
33
- title,
34
- hideClearButton,
35
- style,
36
- }: {
37
- data: T[];
38
- selectedId?: number;
39
- selectedData?: T;
40
- onChange: Function;
41
- textFields: (keyof T)[];
42
- separator?: string;
43
- idField?: keyof T;
44
- disabled?: boolean;
45
- title?: string;
46
- hideClearButton?: boolean;
47
- style?: CSSProperties;
48
- }) {
49
- if (selectedId !== undefined && selectedData !== undefined) {
50
- throw new Error("You cannot provide both selectedData and selectedId to GenericDropdown.");
51
- }
52
- useEffect(() => {
53
- console.log(selectedId);
54
- }, [selectedId]);
55
- //local state
56
- const pageSize = 8;
57
- const [dataList, setDataList] = useState(
58
- data.map((x) => {
59
- return {
60
- ...x,
61
- textValue: getTextValue(
62
- x,
63
- textFields.map((x) => x.toString()),
64
- separator
65
- ),
66
- };
67
- })
68
- );
69
- const [state, setState] = useState({
70
- skip: 0,
71
- total: dataList.length,
72
- subsetData: dataList.slice(0, pageSize),
73
- });
74
-
75
- //external function variables
76
- const filteredData = useRef(dataList.slice());
77
- //function creation
78
- // function to handle filter changes
79
- const onFilterChange = (event: ComboBoxFilterChangeEvent) => {
80
- if (event.filter.value?.length) filteredData.current = filterBy(dataList.slice(), event.filter);
81
- else filteredData.current = dataList;
82
- const newData = filteredData.current.slice(0, pageSize);
83
- setState({
84
- subsetData: newData,
85
- skip: 0,
86
- total: filteredData.current.length,
87
- });
88
- };
89
- // function to handle page changes for virtualization
90
- const pageChange = (event: ComboBoxPageChangeEvent) => {
91
- const skip = event.page.skip;
92
- const take = event.page.take;
93
- const newSubsetData = filteredData.current.slice(skip, skip + take);
94
- setState({ ...state, subsetData: newSubsetData, skip: skip });
95
- };
96
-
97
- //change event listeners
98
- useEffect(() => {
99
- setDataList(
100
- data.map((x) => {
101
- return {
102
- ...x,
103
- textValue: getTextValue(
104
- x,
105
- textFields.map((x) => x.toString()),
106
- separator
107
- ),
108
- };
109
- })
110
- );
111
- }, [data, textFields, separator]);
112
- const findByIndex = (id: number | undefined, idKey: keyof T | undefined, data: T[]) => {
113
- console.log(id, data, idField);
114
- const item = data.find((item: any) => id === item[idKey || "id"]);
115
- console.log(item);
116
- return item;
117
- };
118
- const findByValue = (item: T | undefined, data: T[]) => {
119
- console.log(item, data);
120
- const returnVal = data.find((x) => JSON.stringify({ ...x, ...selectedData }) === JSON.stringify({ ...x }));
121
- console.log(returnVal);
122
- return returnVal;
123
- };
124
- return (
125
- <div data-testid={"dropdown"}>
126
- <ComboBox
127
- style={style}
128
- label={title}
129
- disabled={disabled}
130
- data={state.subsetData} // data to display in the dropdown
131
- textField={"textValue"} // name of the field to use for display text
132
- virtual={{
133
- // enable virtualization for large datasets
134
- total: state.total,
135
- pageSize: pageSize,
136
- skip: state.skip,
137
- }}
138
- suggest
139
- onPageChange={pageChange} // handle page changes for virtualization
140
- filterable={true} // enable filter
141
- onFilterChange={onFilterChange} // handle filter changes
142
- popupSettings={{
143
- height: "210px",
144
- }}
145
- onChange={(e) => onChange(e)}
146
- onBlur={(e) => e.nativeEvent.preventDefault()}
147
- clearButton={!hideClearButton}
148
- value={!selectedId && !selectedData ? null : findByIndex(selectedId, idField, dataList) || findByValue(selectedData, dataList) || null}
149
- />
150
- </div>
151
- );
152
- }
@@ -1,105 +0,0 @@
1
- import { useEffect, useRef, useState } from "react";
2
- import { filterBy } from "@progress/kendo-data-query";
3
- import { MultiSelect, MultiSelectPageChangeEvent, MultiSelectFilterChangeEvent } from "@progress/kendo-react-dropdowns";
4
- import { getTextValue } from "./Utility";
5
-
6
- export function MultiSelectDropdown<T>({
7
- data,
8
- selectedData,
9
- textFields,
10
- selectEvent,
11
- title,
12
- separator,
13
- limit,
14
- }: {
15
- data: T[];
16
- selectedData: T[];
17
- textFields: (keyof T)[];
18
- selectEvent: Function;
19
- title?: string;
20
- separator?: string;
21
- limit?: number;
22
- }) {
23
- //local state
24
- const pageSize = 8;
25
- const [dataList, setDataList] = useState(
26
- data.map((x) => {
27
- return {
28
- ...x,
29
- textValue: getTextValue(
30
- x,
31
- textFields.map((x) => x.toString()),
32
- separator
33
- ),
34
- };
35
- })
36
- );
37
- const [state, setState] = useState({
38
- skip: 0,
39
- total: dataList.length,
40
- subsetData: dataList.slice(0, pageSize),
41
- });
42
-
43
- //external function variables
44
- const filteredData = useRef(dataList.slice());
45
- //function creation
46
- // function to handle filter changes
47
- const onFilterChange = (event: MultiSelectFilterChangeEvent) => {
48
- if (event.filter.value?.length) filteredData.current = filterBy(dataList.slice(), event.filter);
49
- else filteredData.current = dataList;
50
- const newData = filteredData.current.slice(0, pageSize);
51
- setState({
52
- subsetData: newData,
53
- skip: 0,
54
- total: filteredData.current.length,
55
- });
56
- };
57
- // function to handle page changes for virtualization
58
- const pageChange = (event: MultiSelectPageChangeEvent) => {
59
- const skip = event.page.skip;
60
- const take = event.page.take;
61
- const newSubsetData = filteredData.current.slice(skip, skip + take);
62
- setState({ ...state, subsetData: newSubsetData, skip: skip });
63
- };
64
-
65
- //change event listeners
66
- useEffect(() => {
67
- setDataList(
68
- data.map((x) => {
69
- return {
70
- ...x,
71
- textValue: getTextValue(
72
- x,
73
- textFields.map((x) => x.toString()),
74
- separator
75
- ),
76
- };
77
- })
78
- );
79
- }, [data, textFields, separator]);
80
-
81
- return (
82
- <div data-testid={"multiselect"} style={{ width: "100%" }}>
83
- <MultiSelect
84
- label={title}
85
- data={state.subsetData}
86
- textField={"textValue"} // name of the field to use for display text
87
- style={{ width: "100%" }}
88
- virtual={{
89
- total: state.total,
90
- pageSize: pageSize,
91
- skip: state.skip,
92
- }}
93
- onPageChange={pageChange}
94
- filterable={true}
95
- onFilterChange={onFilterChange}
96
- popupSettings={{
97
- height: "210px",
98
- }}
99
- onChange={(e) => selectEvent(limit && e.value.length ? e.value.slice(0, limit) : e.value)}
100
- autoClose={false}
101
- value={selectedData} ///right now: clears selected values whenever selected Vendor Value changes. This will need to be changed to something better in the future
102
- />
103
- </div>
104
- );
105
- }
package/src/Toolbar.tsx DELETED
@@ -1,16 +0,0 @@
1
- type CommonProps = {
2
- id: number;
3
- isEditing?: boolean;
4
- };
5
- export function ToolbarButton<T extends CommonProps>({ item, data, setData }: { item: T; data: T[]; setData: Function }) {
6
- return (
7
- <button
8
- title="Add new"
9
- className="k-button k-button-md k-rounded-md k-button-solid k-button-solid-primary"
10
- onClick={() => setData([{ ...item, isEditing: true, id: 0 }, ...data])}
11
- disabled={data.find((x) => x.isEditing) ? true : false}
12
- >
13
- Add Another
14
- </button>
15
- );
16
- }
@@ -1,17 +0,0 @@
1
- import { Checkbox } from "@progress/kendo-react-inputs";
2
-
3
- export function CommandCellCheckBox({ checked, onCheck, onUncheck }: { checked: boolean; onCheck: Function; onUncheck: Function }) {
4
- const functionToRun = () => {
5
- if (checked) {
6
- onUncheck();
7
- } else {
8
- onCheck();
9
- }
10
- };
11
-
12
- return (
13
- <td className="justify-content-center" data-testid="checkbox">
14
- <Checkbox checked={checked} onChange={functionToRun} />
15
- </td>
16
- );
17
- }
@@ -1,24 +0,0 @@
1
- import { ComboBoxChangeEvent } from "@progress/kendo-react-dropdowns";
2
- import { GenericDropdown } from "../GenericDropdown";
3
-
4
- export function CommandCellDDWithoutId<T>(props: {
5
- data: T[];
6
- selectedData: T;
7
- textFields: (keyof T)[];
8
- onChange: (e: ComboBoxChangeEvent) => void;
9
- separator?: string;
10
- checkEditField?: boolean;
11
- isEditing?: boolean;
12
- showClearButton?: boolean;
13
- }) {
14
- return (
15
- <td>
16
- {props.checkEditField && !props.isEditing ? (
17
- props.textFields.map((x) => props.data.find((y) => y === props.selectedData)![x]).join(props.separator || " ")
18
- ) : (
19
- // If "props.checkEditField" is false or "props.isEditing" is true, render the GenericDropdownWithSearch component with the "props" passed to it
20
- <GenericDropdown {...props} />
21
- )}
22
- </td>
23
- );
24
- }
@@ -1,33 +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
- chgFn: changeFunction,
7
- field,
8
- }: {
9
- dataItem: T;
10
- chgFn: (e: GridChangeEvent) => void;
11
- field: keyof T;
12
- }) {
13
- let valString = "" + dataItem[field];
14
- let date = moment(valString).format("MM/DD/YY");
15
- return (
16
- <td data-testid="date">
17
- {valString === undefined || dataItem.isEditing ? (
18
- <DatePicker
19
- value={new Date(moment(valString).format("MMMM, DD YYYY"))}
20
- onChange={(e) =>
21
- changeFunction({
22
- field: field.toString(),
23
- value: moment(e.value),
24
- dataItem: dataItem,
25
- })
26
- }
27
- />
28
- ) : (
29
- date
30
- )}
31
- </td>
32
- );
33
- }
@@ -1,30 +0,0 @@
1
- import { ComboBoxChangeEvent } from "@progress/kendo-react-dropdowns";
2
- import { GenericDropdown } from "../GenericDropdown";
3
- import { CommonProps } from "../PropTypes";
4
-
5
- // This exports a function component called "CommandCellDropdown"
6
- // It takes in various props that are used to render a dropdown in a table cell
7
- export function CommandCellDropdown<T>(props: {
8
- data: T[];
9
- selectedId: number;
10
- textFields: (keyof T)[];
11
- onChange: (e: ComboBoxChangeEvent) => void;
12
- separator?: string;
13
- checkEditField?: boolean;
14
- isEditing?: boolean;
15
- idField?: keyof T;
16
- showClearButton?: boolean;
17
- }) {
18
- return (
19
- <td>
20
- {props.checkEditField && !props.isEditing ? (
21
- props.textFields
22
- .map((x) => props.data.find((y: any) => y[props.idField ? props.idField : "id"] === props.selectedId)![x])
23
- .join(props.separator || " ")
24
- ) : (
25
- // If "props.checkEditField" is false or "props.isEditing" is true, render the GenericDropdownWithSearch component with the "props" passed to it
26
- <GenericDropdown {...props} />
27
- )}
28
- </td>
29
- );
30
- }
@@ -1,9 +0,0 @@
1
- export function CommandCellPrice({ cost }: { 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,14 +0,0 @@
1
- import { GridCellProps } from "@progress/kendo-react-grid";
2
- import { Switch } from "@progress/kendo-react-inputs";
3
-
4
- export function CommandCellSwitch({ props, changeFunction }: { props: GridCellProps; changeFunction: Function }) {
5
- return (
6
- <td data-testid="switch">
7
- {props.dataItem.isEditing ? (
8
- <Switch onChange={() => changeFunction()} checked={props.dataItem[props.field!]} />
9
- ) : (
10
- props.dataItem[props.field!].toString()
11
- )}
12
- </td>
13
- );
14
- }
package/tsconfig.json DELETED
@@ -1,13 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "strict": true,
4
- "jsx": "react-jsx",
5
- "declaration": true,
6
- "esModuleInterop": true,
7
- "outDir": "dist",
8
- "target": "es6",
9
- "module": "es6",
10
- "moduleResolution": "node"
11
- },
12
- "include": ["src"]
13
- }
File without changes