mirror of
https://github.com/rowyio/rowy.git
synced 2025-12-29 00:16:39 +01:00
single select field
This commit is contained in:
@@ -25,8 +25,8 @@
|
||||
|
||||
### additional fields:
|
||||
|
||||
- single select(string)
|
||||
- [https://material-ui.com/components/chips/#chip-array] Multiple select(array of strings)
|
||||
- single select(string)✅
|
||||
- Multiple select(array of strings)
|
||||
- date(Firebase timestamp)✅
|
||||
- time(Firebase timestamp)✅
|
||||
- file(firebase storage url string)
|
||||
|
||||
@@ -28,6 +28,10 @@ export enum FieldType {
|
||||
rating = "RATING",
|
||||
image = "IMAGE",
|
||||
file = "FILE",
|
||||
singleSelect = "SINGLE_SELECT",
|
||||
multiSelect = "MULTI_SELECT",
|
||||
documentSelect = "DOCUMENT_SELECT",
|
||||
documentsSelect = "DOCUMENTS_SELECT",
|
||||
}
|
||||
|
||||
export const FIELDS = [
|
||||
@@ -43,6 +47,10 @@ export const FIELDS = [
|
||||
{ icon: <RatingIcon />, name: "Rating", type: FieldType.rating },
|
||||
{ icon: <ImageIcon />, name: "Image", type: FieldType.image },
|
||||
{ icon: <FileIcon />, name: "File", type: FieldType.file },
|
||||
{ icon: <FileIcon />, name: "Single Select", type: FieldType.singleSelect },
|
||||
{ icon: <FileIcon />, name: "Multi Select", type: FieldType.multiSelect },
|
||||
{ icon: <FileIcon />, name: "Doc Select", type: FieldType.documentSelect },
|
||||
{ icon: <FileIcon />, name: "Docs Select", type: FieldType.documentsSelect },
|
||||
];
|
||||
|
||||
export const getFieldIcon = (type: FieldType) => {
|
||||
|
||||
70
src/components/Table/ColumnEditor/SelectOptionsInput.tsx
Normal file
70
src/components/Table/ColumnEditor/SelectOptionsInput.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { createStyles, makeStyles, Theme } from "@material-ui/core/styles";
|
||||
import Chip from "@material-ui/core/Chip";
|
||||
import { TextField, Grid, Divider } from "@material-ui/core";
|
||||
import _includes from "lodash/includes";
|
||||
import _camelCase from "lodash/camelCase";
|
||||
|
||||
const useStyles = makeStyles(Theme =>
|
||||
createStyles({
|
||||
root: {
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
flexWrap: "wrap",
|
||||
maxWidth: 300,
|
||||
padding: Theme.spacing(1),
|
||||
},
|
||||
chip: {
|
||||
margin: Theme.spacing(0.5),
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
export default function SelectOptionsInput(props: any) {
|
||||
const { options, setValue } = props;
|
||||
const classes = useStyles();
|
||||
|
||||
const handleAdd = (newOption: string) => {
|
||||
// setOptions([...options, newOption]);
|
||||
setValue("options", [...options, newOption]);
|
||||
};
|
||||
const handleDelete = (optionToDelete: string) => () => {
|
||||
const newOptions = options.filter(
|
||||
(option: string) => option !== optionToDelete
|
||||
);
|
||||
setValue("options", newOptions);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setValue({ data: { options } });
|
||||
}, [options]);
|
||||
|
||||
return (
|
||||
<Grid container direction="column" className={classes.root}>
|
||||
<Grid item>
|
||||
<TextField
|
||||
label="New Option"
|
||||
onKeyPress={(e: any) => {
|
||||
const value = e.target.value;
|
||||
if (e.key === "Enter") {
|
||||
handleAdd(value);
|
||||
e.target.value = "";
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
{options.map((option: string) => {
|
||||
return (
|
||||
<Chip
|
||||
key={option}
|
||||
label={option}
|
||||
onDelete={handleDelete(option)}
|
||||
className={classes.chip}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import Paper from "@material-ui/core/Paper";
|
||||
import ClickAwayListener from "@material-ui/core/ClickAwayListener";
|
||||
import { createStyles, makeStyles } from "@material-ui/core/styles";
|
||||
import { TextField, Grid } from "@material-ui/core";
|
||||
import { FieldsDropDown, isFieldType } from "../../Fields";
|
||||
import { FieldsDropDown, isFieldType, FieldType } from "../../Fields";
|
||||
import ToggleButton from "@material-ui/lab/ToggleButton";
|
||||
import ToggleButtonGroup from "@material-ui/lab/ToggleButtonGroup";
|
||||
|
||||
@@ -20,10 +20,10 @@ import LockIcon from "@material-ui/icons/Lock";
|
||||
import LockOpenIcon from "@material-ui/icons/LockOpen";
|
||||
import VisibilityIcon from "@material-ui/icons/Visibility";
|
||||
import VisibilityOffIcon from "@material-ui/icons/VisibilityOff";
|
||||
import FormatItalicIcon from "@material-ui/icons/FormatItalic";
|
||||
import FormatUnderlinedIcon from "@material-ui/icons/FormatUnderlined";
|
||||
import FormatColorFillIcon from "@material-ui/icons/FormatColorFill";
|
||||
import DeleteIcon from "@material-ui/icons/Delete";
|
||||
import SelectOptionsInput from "./SelectOptionsInput";
|
||||
|
||||
const useStyles = makeStyles(Theme =>
|
||||
createStyles({
|
||||
@@ -72,6 +72,7 @@ const ColumnEditor = (props: any) => {
|
||||
const [values, setValues] = React.useState({
|
||||
type: null,
|
||||
name: "",
|
||||
options: [],
|
||||
});
|
||||
const [flags, setFlags] = React.useState(() => [""]);
|
||||
const classes = useStyles();
|
||||
@@ -100,6 +101,11 @@ const ColumnEditor = (props: any) => {
|
||||
key: column.key,
|
||||
isNew: column.isNew,
|
||||
}));
|
||||
if (column.options) {
|
||||
setValue("options", column.options);
|
||||
} else {
|
||||
setValue("options", []);
|
||||
}
|
||||
}
|
||||
}, [column]);
|
||||
const onClickAway = (event: any) => {
|
||||
@@ -126,11 +132,18 @@ const ColumnEditor = (props: any) => {
|
||||
};
|
||||
const updateColumn = () => {
|
||||
console.log(values, props);
|
||||
const updatables = [
|
||||
|
||||
let updatables: { field: string; value: any }[] = [
|
||||
{ field: "name", value: values.name },
|
||||
{ field: "type", value: values.type },
|
||||
{ field: "resizable", value: flags.includes("resizable") },
|
||||
];
|
||||
if (
|
||||
values.type === FieldType.multiSelect ||
|
||||
values.type === FieldType.singleSelect
|
||||
) {
|
||||
updatables.push({ field: "options", value: values.options });
|
||||
}
|
||||
actions.update(props.column.idx, updatables);
|
||||
handleClose();
|
||||
};
|
||||
@@ -190,18 +203,28 @@ const ColumnEditor = (props: any) => {
|
||||
<FormControl className={classes.formControl}>
|
||||
<InputLabel htmlFor="Field-select">Field Type</InputLabel>
|
||||
{FieldsDropDown(values.type, handleChange)}
|
||||
|
||||
{(values.type === FieldType.singleSelect ||
|
||||
values.type === FieldType.multiSelect) && (
|
||||
<SelectOptionsInput
|
||||
setValue={setValue}
|
||||
options={values.options}
|
||||
/>
|
||||
)}
|
||||
{column.isNew ? (
|
||||
<Button onClick={createNewColumn}>Add</Button>
|
||||
) : (
|
||||
<Button onClick={updateColumn}>update</Button>
|
||||
)}
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={deleteColumn}
|
||||
>
|
||||
<DeleteIcon /> Delete
|
||||
</Button>
|
||||
{!column.isNew && (
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={deleteColumn}
|
||||
>
|
||||
<DeleteIcon /> Delete
|
||||
</Button>
|
||||
)}
|
||||
<Button color="secondary" onClick={handleClose}>
|
||||
cancel
|
||||
</Button>
|
||||
|
||||
@@ -6,7 +6,7 @@ import Rating from "../Fields/Rating";
|
||||
import CheckBox from "../Fields/CheckBox";
|
||||
import UrlLink from "../Fields/UrlLink";
|
||||
import firebase from "firebase/app";
|
||||
|
||||
import { Editors } from "react-data-grid-addons";
|
||||
export const copyPaste = (props: any) => {
|
||||
console.log(props);
|
||||
};
|
||||
@@ -71,3 +71,15 @@ export const cellFormatter = (fieldType: FieldType, key: string) => {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const { DropDownEditor } = Editors;
|
||||
|
||||
export const singleSelectEditor = (options: string[]) => {
|
||||
const _options = options.map(option => ({
|
||||
id: option,
|
||||
value: option,
|
||||
title: option,
|
||||
text: option,
|
||||
}));
|
||||
return <DropDownEditor options={_options} />;
|
||||
};
|
||||
|
||||
@@ -11,11 +11,13 @@ import Rating from "../Fields/Rating";
|
||||
import CheckBox from "../Fields/CheckBox";
|
||||
import UrlLink from "../Fields/UrlLink";
|
||||
import ColumnEditor from "./ColumnEditor/index";
|
||||
|
||||
import {
|
||||
cellFormatter,
|
||||
onCellSelected,
|
||||
onGridRowsUpdated,
|
||||
copyPaste,
|
||||
singleSelectEditor,
|
||||
} from "./grid-fns";
|
||||
const useStyles = makeStyles(Theme =>
|
||||
createStyles({
|
||||
@@ -91,13 +93,16 @@ function Table(props: any) {
|
||||
if (tableState.columns) {
|
||||
let columns = tableState.columns.map((column: any) => ({
|
||||
width: 220,
|
||||
|
||||
key: column.fieldName,
|
||||
name: column.columnName,
|
||||
editable: true,
|
||||
resizable: true,
|
||||
headerRenderer: headerRenderer,
|
||||
formatter: cellFormatter(column.type, column.fieldName),
|
||||
editor:
|
||||
column.type === FieldType.singleSelect
|
||||
? singleSelectEditor(column.options)
|
||||
: false,
|
||||
...column,
|
||||
}));
|
||||
columns.push({
|
||||
|
||||
Reference in New Issue
Block a user