diff --git a/www/src/components/Table/withPopoverCell.tsx b/www/src/components/Table/withPopoverCell.tsx
index 0a3417cf..e53493d6 100644
--- a/www/src/components/Table/withPopoverCell.tsx
+++ b/www/src/components/Table/withPopoverCell.tsx
@@ -64,6 +64,13 @@ export default function withPopoverCell(
setLocalValue(value);
}, [value]);
+ const handleSubmit = (value: any) => {
+ if (updateCell && !options?.readOnly) {
+ updateCell(props.row.ref, props.column.key as string, value);
+ setLocalValue(value);
+ }
+ };
+
const basicCell = (
);
@@ -79,13 +87,6 @@ export default function withPopoverCell(
const parentRef = basicCellRef.current?.parentElement;
- const handleSubmit = (value: any) => {
- if (updateCell && !options?.readOnly) {
- updateCell(props.row.ref, props.column.key as string, value);
- setLocalValue(value);
- }
- };
-
// Switch to heavy cell Component once basic cell is clicked
return (
<>
@@ -104,6 +105,8 @@ export default function withPopoverCell(
},
...popoverProps?.PaperProps,
}}
+ onClick={(e) => e.stopPropagation()}
+ onKeyDown={(e) => e.stopPropagation()}
>
|
diff --git a/www/src/components/fields/MultiSelect/ConvertStringToArray.tsx b/www/src/components/fields/MultiSelect/ConvertStringToArray.tsx
new file mode 100644
index 00000000..1177087e
--- /dev/null
+++ b/www/src/components/fields/MultiSelect/ConvertStringToArray.tsx
@@ -0,0 +1,26 @@
+import React from "react";
+import { Grid, Tooltip, Button } from "@material-ui/core";
+
+export const ConvertStringToArray = ({ value, onSubmit }) => (
+
+
+ {value}
+
+
+
+
+
+
+
+);
diff --git a/www/src/components/fields/MultiSelect/PopoverBasicCell.tsx b/www/src/components/fields/MultiSelect/PopoverBasicCell.tsx
new file mode 100644
index 00000000..ff8a9686
--- /dev/null
+++ b/www/src/components/fields/MultiSelect/PopoverBasicCell.tsx
@@ -0,0 +1,89 @@
+import React from "react";
+import clsx from "clsx";
+import { IPopoverBasicCellProps } from "../types";
+
+import { makeStyles, createStyles, ButtonBase, Grid } from "@material-ui/core";
+import ArrowDropDownIcon from "@material-ui/icons/ArrowDropDown";
+
+import { sanitiseValue } from "./utils";
+import FormattedChip from "components/FormattedChip";
+import { ConvertStringToArray } from "./ConvertStringToArray";
+
+const useStyles = makeStyles((theme) =>
+ createStyles({
+ root: {
+ height: "100%",
+ padding: theme.spacing(0, 1, 0, 1.5),
+
+ font: "inherit",
+ color: "inherit !important",
+ letterSpacing: "inherit",
+ textAlign: "inherit",
+ justifyContent: "flex-start",
+ },
+
+ value: {
+ flex: 1,
+ maxWidth: `calc(100% - 24px + 4px)`,
+ overflow: "hidden",
+ marginRight: 0,
+ },
+ chip: {
+ display: "flex",
+ cursor: "inherit",
+ },
+ chipLabel: { whiteSpace: "nowrap" },
+
+ icon: {
+ display: "block",
+ color: theme.palette.action.active,
+ },
+ disabled: {
+ color: theme.palette.action.disabled,
+ },
+ })
+);
+
+export const SingleSelect = React.forwardRef(function SingleSelect(
+ { value, setShowComplexCell, disabled, onSubmit }: IPopoverBasicCellProps,
+ ref: React.Ref
+) {
+ const classes = useStyles();
+
+ if (typeof value === "string" && value !== "")
+ return ;
+
+ return (
+ setShowComplexCell(true)}
+ ref={ref}
+ disabled={disabled}
+ >
+
+ {sanitiseValue(value).map(
+ (item) =>
+ typeof item === "string" && (
+
+
+
+ )
+ )}
+
+
+
+
+ );
+});
+export default SingleSelect;
diff --git a/www/src/components/fields/MultiSelect/PopoverCell.tsx b/www/src/components/fields/MultiSelect/PopoverCell.tsx
new file mode 100644
index 00000000..6f7efec2
--- /dev/null
+++ b/www/src/components/fields/MultiSelect/PopoverCell.tsx
@@ -0,0 +1,43 @@
+import React from "react";
+import { IPopoverCellProps } from "../types";
+import _get from "lodash/get";
+
+import MultiSelect_ from "@antlerengineering/multiselect";
+
+import { sanitiseValue } from "./utils";
+
+export default function SingleSelect({
+ value,
+ onSubmit,
+ column,
+ parentRef,
+ setShowComplexCell,
+ disabled,
+}: IPopoverCellProps) {
+ const config = column.config ?? {};
+
+ return (
+ setShowComplexCell(false)}
+ />
+ );
+}
diff --git a/www/src/components/fields/MultiSelect/SideDrawerField.tsx b/www/src/components/fields/MultiSelect/SideDrawerField.tsx
new file mode 100644
index 00000000..beecd21c
--- /dev/null
+++ b/www/src/components/fields/MultiSelect/SideDrawerField.tsx
@@ -0,0 +1,76 @@
+import React from "react";
+import { Controller } from "react-hook-form";
+import { ISideDrawerFieldProps } from "../types";
+
+import { useTheme, Grid } from "@material-ui/core";
+import MultiSelect_ from "@antlerengineering/multiselect";
+import FormattedChip from "components/FormattedChip";
+
+import { sanitiseValue } from "./utils";
+import { ConvertStringToArray } from "./ConvertStringToArray";
+
+export default function SingleSelect({
+ column,
+ control,
+ disabled,
+}: ISideDrawerFieldProps) {
+ const theme = useTheme();
+
+ const config = column.config ?? {};
+
+ return (
+ {
+ const handleDelete = (index: number) => () => {
+ const newValues = [...value];
+ newValues.splice(index, 1);
+ onChange(newValues);
+ };
+
+ if (typeof value === "string" && value !== "")
+ return ;
+
+ return (
+ <>
+
+
+ {value && Array.isArray(value) && (
+
+ {value.map(
+ (item, i) =>
+ item?.length > 0 && (
+
+
+
+ )
+ )}
+
+ )}
+ >
+ );
+ }}
+ />
+ );
+}
diff --git a/www/src/components/fields/MultiSelect/index.tsx b/www/src/components/fields/MultiSelect/index.tsx
new file mode 100644
index 00000000..0db14658
--- /dev/null
+++ b/www/src/components/fields/MultiSelect/index.tsx
@@ -0,0 +1,35 @@
+import React, { lazy } from "react";
+import { IFieldConfig, FieldType } from "components/fields/types";
+import withPopoverCell from "components/Table/withPopoverCell";
+
+import MultiSelectIcon from "assets/icons/MultiSelect";
+import PopoverBasicCell from "./PopoverBasicCell";
+import NullEditor from "components/Table/editors/NullEditor";
+
+const PopoverCell = lazy(
+ () =>
+ import("./PopoverCell" /* webpackChunkName: "PopoverCell-MultiSelect" */)
+);
+const SideDrawerField = lazy(
+ () =>
+ import(
+ "./SideDrawerField" /* webpackChunkName: "SideDrawerField-MultiSelect" */
+ )
+);
+
+export const config: IFieldConfig = {
+ type: FieldType.multiSelect,
+ name: "MultiSelect",
+ dataType: "string[]",
+ initialValue: [],
+ icon: ,
+ description:
+ "Dropdown selector with searchable options and check box behavior. Optionally allows users to input custom values. Max selection: all options.",
+ TableCell: withPopoverCell(PopoverCell, PopoverBasicCell, {
+ anchorOrigin: { horizontal: "left", vertical: "bottom" },
+ transparent: true,
+ }),
+ TableEditor: NullEditor,
+ SideDrawerField,
+};
+export default config;
diff --git a/www/src/components/fields/MultiSelect/utils.ts b/www/src/components/fields/MultiSelect/utils.ts
new file mode 100644
index 00000000..d2feec47
--- /dev/null
+++ b/www/src/components/fields/MultiSelect/utils.ts
@@ -0,0 +1,4 @@
+export const sanitiseValue = (value: any) => {
+ if (value === undefined || value === null || value === "") return [];
+ else return value as string[];
+};
diff --git a/www/src/components/fields/SingleSelect/PopoverBasicCell.tsx b/www/src/components/fields/SingleSelect/PopoverBasicCell.tsx
new file mode 100644
index 00000000..0f42c7c7
--- /dev/null
+++ b/www/src/components/fields/SingleSelect/PopoverBasicCell.tsx
@@ -0,0 +1,61 @@
+import React from "react";
+import clsx from "clsx";
+import { IPopoverBasicCellProps } from "../types";
+
+import { makeStyles, createStyles, ButtonBase } from "@material-ui/core";
+import ArrowDropDownIcon from "@material-ui/icons/ArrowDropDown";
+
+import { sanitiseValue } from "./utils";
+
+const useStyles = makeStyles((theme) =>
+ createStyles({
+ root: {
+ height: "100%",
+ padding: theme.spacing(0, 1, 0, 1.5),
+
+ font: "inherit",
+ color: "inherit !important",
+ letterSpacing: "inherit",
+ textAlign: "inherit",
+ justifyContent: "flex-start",
+ },
+
+ value: {
+ flex: 1,
+ maxWidth: `calc(100% - 24px)`,
+ overflow: "hidden",
+ textOverflow: "ellipsis",
+ },
+
+ icon: {
+ display: "block",
+ color: theme.palette.action.active,
+ },
+ disabled: {
+ color: theme.palette.action.disabled,
+ },
+ })
+);
+
+export const SingleSelect = React.forwardRef(function SingleSelect(
+ { value, setShowComplexCell, disabled }: IPopoverBasicCellProps,
+ ref: React.Ref
+) {
+ const classes = useStyles();
+
+ return (
+ setShowComplexCell(true)}
+ ref={ref}
+ disabled={disabled}
+ >
+ {sanitiseValue(value)}
+
+
+
+ );
+});
+export default SingleSelect;
diff --git a/www/src/components/fields/SingleSelect/PopoverCell.tsx b/www/src/components/fields/SingleSelect/PopoverCell.tsx
new file mode 100644
index 00000000..33a1b082
--- /dev/null
+++ b/www/src/components/fields/SingleSelect/PopoverCell.tsx
@@ -0,0 +1,43 @@
+import React from "react";
+import { IPopoverCellProps } from "../types";
+import _get from "lodash/get";
+
+import MultiSelect_ from "@antlerengineering/multiselect";
+
+import { sanitiseValue } from "./utils";
+
+export default function SingleSelect({
+ value,
+ onSubmit,
+ column,
+ parentRef,
+ setShowComplexCell,
+ disabled,
+}: IPopoverCellProps) {
+ const config = column.config ?? {};
+
+ return (
+ setShowComplexCell(false)}
+ />
+ );
+}
diff --git a/www/src/components/fields/SingleSelect/SideDrawerField.tsx b/www/src/components/fields/SingleSelect/SideDrawerField.tsx
new file mode 100644
index 00000000..93069283
--- /dev/null
+++ b/www/src/components/fields/SingleSelect/SideDrawerField.tsx
@@ -0,0 +1,49 @@
+import React from "react";
+import { Controller } from "react-hook-form";
+import { ISideDrawerFieldProps } from "../types";
+
+import { useTheme } from "@material-ui/core";
+import MultiSelect_ from "@antlerengineering/multiselect";
+import FormattedChip from "components/FormattedChip";
+
+import { sanitiseValue } from "./utils";
+
+export default function SingleSelect({
+ column,
+ control,
+ disabled,
+}: ISideDrawerFieldProps) {
+ const theme = useTheme();
+
+ const config = column.config ?? {};
+
+ return (
+ (
+ <>
+
+
+ {value?.length > 0 && (
+
+
+
+ )}
+ >
+ )}
+ />
+ );
+}
diff --git a/www/src/components/fields/SingleSelect/index.tsx b/www/src/components/fields/SingleSelect/index.tsx
new file mode 100644
index 00000000..eee9eaa5
--- /dev/null
+++ b/www/src/components/fields/SingleSelect/index.tsx
@@ -0,0 +1,35 @@
+import React, { lazy } from "react";
+import { IFieldConfig, FieldType } from "components/fields/types";
+import withPopoverCell from "components/Table/withPopoverCell";
+
+import SingleSelectIcon from "@material-ui/icons/FormatListBulleted";
+import PopoverBasicCell from "./PopoverBasicCell";
+import NullEditor from "components/Table/editors/NullEditor";
+
+const PopoverCell = lazy(
+ () =>
+ import("./PopoverCell" /* webpackChunkName: "PopoverCell-SingleSelect" */)
+);
+const SideDrawerField = lazy(
+ () =>
+ import(
+ "./SideDrawerField" /* webpackChunkName: "SideDrawerField-SingleSelect" */
+ )
+);
+
+export const config: IFieldConfig = {
+ type: FieldType.singleSelect,
+ name: "SingleSelect",
+ dataType: "string | null",
+ initialValue: null,
+ icon: ,
+ description:
+ "Dropdown selector with searchable options and radio button behavior. Optionally allows users to input custom values. Max selection: 1 option.",
+ TableCell: withPopoverCell(PopoverCell, PopoverBasicCell, {
+ anchorOrigin: { horizontal: "left", vertical: "bottom" },
+ transparent: true,
+ }),
+ TableEditor: NullEditor,
+ SideDrawerField,
+};
+export default config;
diff --git a/www/src/components/fields/SingleSelect/utils.ts b/www/src/components/fields/SingleSelect/utils.ts
new file mode 100644
index 00000000..3070d669
--- /dev/null
+++ b/www/src/components/fields/SingleSelect/utils.ts
@@ -0,0 +1,5 @@
+export const sanitiseValue = (value: any) => {
+ if (value === undefined || value === null || value === "") return null;
+ else if (Array.isArray(value)) return value[0] as string;
+ else return value as string;
+};
diff --git a/www/src/components/fields/index.tsx b/www/src/components/fields/index.tsx
index 59610a11..cc34bd41 100644
--- a/www/src/components/fields/index.tsx
+++ b/www/src/components/fields/index.tsx
@@ -21,6 +21,8 @@ import DateTime from "./DateTime";
import Duration from "./Duration";
import Image_ from "./Image";
import File_ from "./File";
+import SingleSelect from "./SingleSelect";
+import MultiSelect from "./MultiSelect";
import SubTable from "./SubTable";
import Json from "./Json";
import Code from "./Code";
@@ -54,8 +56,8 @@ export const FIELDS: IFieldConfig[] = [
Image_,
File_,
// SELECT
- // TODO: singleSelect,
- // TODO: multiSelect,
+ SingleSelect,
+ MultiSelect,
// CONNECTION
SubTable,
// TODO: connectTable,
diff --git a/www/src/components/fields/types.ts b/www/src/components/fields/types.ts
index 3a341194..54c3a1e6 100644
--- a/www/src/components/fields/types.ts
+++ b/www/src/components/fields/types.ts
@@ -2,6 +2,7 @@ import { FieldType } from "constants/fields";
import { FormatterProps, EditorProps } from "react-data-grid";
import { Control } from "react-hook-form";
+import { PopoverProps } from "@material-ui/core";
export { FieldType };
@@ -36,10 +37,12 @@ export interface IBasicCellProps {
export interface IPopoverCellProps extends ICustomCellProps {
setShowComplexCell: React.Dispatch>;
+ parentRef: PopoverProps["anchorEl"];
}
export interface IPopoverBasicCellProps extends IBasicCellProps {
setShowComplexCell: React.Dispatch>;
disabled: boolean;
+ onSubmit: (value: any) => void;
}
export interface ISideDrawerFieldProps {