mirror of
https://github.com/rowyio/rowy.git
synced 2025-12-29 00:16:39 +01:00
creating docselect columns
This commit is contained in:
79
src/components/Fields/DocSelect.tsx
Normal file
79
src/components/Fields/DocSelect.tsx
Normal file
@@ -0,0 +1,79 @@
|
||||
import React, { useState } from "react";
|
||||
import SearchIcon from "@material-ui/icons/Search";
|
||||
import IconButton from "@material-ui/core/IconButton";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import Button from "@material-ui/core/Button";
|
||||
import { createStyles, makeStyles, Theme } from "@material-ui/core/styles";
|
||||
import Popper from "@material-ui/core/Popper";
|
||||
import Fade from "@material-ui/core/Fade";
|
||||
import Paper from "@material-ui/core/Paper";
|
||||
import TextareaAutosize from "@material-ui/core/TextareaAutosize";
|
||||
import ClickAwayListener from "@material-ui/core/ClickAwayListener";
|
||||
import { onSubmit } from "components/Table/grid-fns";
|
||||
import { TextField } from "@material-ui/core";
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) =>
|
||||
createStyles({
|
||||
root: {
|
||||
position: "relative",
|
||||
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
},
|
||||
typography: {
|
||||
padding: theme.spacing(2),
|
||||
},
|
||||
textArea: {
|
||||
fontSize: 14,
|
||||
minWidth: 230,
|
||||
},
|
||||
paper: { minWidth: 200 },
|
||||
})
|
||||
);
|
||||
interface Props {
|
||||
value: any;
|
||||
row: { ref: firebase.firestore.DocumentReference; id: string };
|
||||
onSubmit: Function;
|
||||
collectionPath: string;
|
||||
}
|
||||
|
||||
const DocSelect = (props: Props) => {
|
||||
const { value, row, onSubmit, collectionPath } = props;
|
||||
const [query, setQuery] = useState(value ? value : "");
|
||||
|
||||
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
|
||||
const classes = useStyles();
|
||||
|
||||
const handleClick = (
|
||||
event: React.MouseEvent<HTMLButtonElement, MouseEvent>
|
||||
) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
|
||||
const open = Boolean(anchorEl);
|
||||
const id = open ? "no-transition-popper" : undefined;
|
||||
const onClickAway = (event: any) => {
|
||||
if (event.target.id !== id) {
|
||||
// onSubmit(row.ref, text);
|
||||
setAnchorEl(null);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<ClickAwayListener onClickAway={onClickAway}>
|
||||
<div>
|
||||
<IconButton onClick={handleClick}>
|
||||
<SearchIcon />
|
||||
</IconButton>
|
||||
{value}
|
||||
<Popper id={id} open={open} anchorEl={anchorEl}>
|
||||
<Paper>
|
||||
<TextField id={id} placeholder={`searching ${collectionPath}`} />
|
||||
</Paper>
|
||||
</Popper>
|
||||
</div>
|
||||
</ClickAwayListener>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export default DocSelect;
|
||||
@@ -18,6 +18,7 @@ import CreateTableDialog from "./CreateTableDialog";
|
||||
|
||||
import useSettings from "../hooks/useSettings";
|
||||
import useRouter from "../hooks/useRouter";
|
||||
import TablesContext from "../contexts/tablesContext";
|
||||
|
||||
const useStyles = makeStyles(theme =>
|
||||
createStyles({
|
||||
@@ -63,69 +64,71 @@ const Navigation = (props: any) => {
|
||||
const classes = useStyles();
|
||||
const [settings, createTable] = useSettings();
|
||||
return (
|
||||
<React.Fragment>
|
||||
<CssBaseline />
|
||||
<Paper square className={classes.paper}>
|
||||
<Typography className={classes.text} variant="h5" gutterBottom>
|
||||
{props.header}
|
||||
</Typography>
|
||||
</Paper>
|
||||
{props.children}
|
||||
<AppBar position="fixed" color="primary" className={classes.appBar}>
|
||||
<Toolbar>
|
||||
<IconButton edge="start" color="inherit" aria-label="open drawer">
|
||||
<MenuIcon />
|
||||
</IconButton>
|
||||
{!settings.tables ? (
|
||||
<>
|
||||
<Skeleton
|
||||
variant="rect"
|
||||
width={120}
|
||||
height={40}
|
||||
className={classes.skeleton}
|
||||
/>
|
||||
<Skeleton
|
||||
variant="rect"
|
||||
width={120}
|
||||
height={40}
|
||||
className={classes.skeleton}
|
||||
/>
|
||||
<Skeleton
|
||||
variant="rect"
|
||||
width={120}
|
||||
height={40}
|
||||
className={classes.skeleton}
|
||||
/>
|
||||
<Skeleton
|
||||
variant="rect"
|
||||
width={120}
|
||||
height={40}
|
||||
className={classes.skeleton}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{settings.tables.map(
|
||||
(table: { name: string; collection: string }) => (
|
||||
<Button
|
||||
key={table.collection}
|
||||
onClick={() => {
|
||||
router.history.push(table.collection);
|
||||
}}
|
||||
className={classes.button}
|
||||
>
|
||||
{table.name}
|
||||
</Button>
|
||||
)
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<TablesContext.Provider value={{ value: settings.tables }}>
|
||||
<React.Fragment>
|
||||
<CssBaseline />
|
||||
<Paper square className={classes.paper}>
|
||||
<Typography className={classes.text} variant="h5" gutterBottom>
|
||||
{props.header}
|
||||
</Typography>
|
||||
</Paper>
|
||||
{props.children}
|
||||
<AppBar position="fixed" color="primary" className={classes.appBar}>
|
||||
<Toolbar>
|
||||
<IconButton edge="start" color="inherit" aria-label="open drawer">
|
||||
<MenuIcon />
|
||||
</IconButton>
|
||||
{!settings.tables ? (
|
||||
<>
|
||||
<Skeleton
|
||||
variant="rect"
|
||||
width={120}
|
||||
height={40}
|
||||
className={classes.skeleton}
|
||||
/>
|
||||
<Skeleton
|
||||
variant="rect"
|
||||
width={120}
|
||||
height={40}
|
||||
className={classes.skeleton}
|
||||
/>
|
||||
<Skeleton
|
||||
variant="rect"
|
||||
width={120}
|
||||
height={40}
|
||||
className={classes.skeleton}
|
||||
/>
|
||||
<Skeleton
|
||||
variant="rect"
|
||||
width={120}
|
||||
height={40}
|
||||
className={classes.skeleton}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{settings.tables.map(
|
||||
(table: { name: string; collection: string }) => (
|
||||
<Button
|
||||
key={table.collection}
|
||||
onClick={() => {
|
||||
router.history.push(table.collection);
|
||||
}}
|
||||
className={classes.button}
|
||||
>
|
||||
{table.name}
|
||||
</Button>
|
||||
)
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
<CreateTableDialog classes={classes} createTable={createTable} />
|
||||
<div className={classes.grow} />
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
</React.Fragment>
|
||||
<CreateTableDialog classes={classes} createTable={createTable} />
|
||||
<div className={classes.grow} />
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
</React.Fragment>
|
||||
</TablesContext.Provider>
|
||||
);
|
||||
};
|
||||
export default Navigation;
|
||||
|
||||
54
src/components/Table/ColumnEditor/DocInput.tsx
Normal file
54
src/components/Table/ColumnEditor/DocInput.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import React, { useContext } from "react";
|
||||
import { createStyles, makeStyles, Theme } from "@material-ui/core/styles";
|
||||
import Chip from "@material-ui/core/Chip";
|
||||
import { TextField, Grid, Divider, Select } from "@material-ui/core";
|
||||
import TablesContext from "../../../contexts/tablesContext";
|
||||
import MenuItem from "@material-ui/core/MenuItem";
|
||||
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 DocInput(props: any) {
|
||||
const { collectionPath, setValue } = props;
|
||||
|
||||
const classes = useStyles();
|
||||
const tables = useContext(TablesContext);
|
||||
const onChange = (e: any, v: any) => {
|
||||
setValue("collectionPath", v.props.value);
|
||||
};
|
||||
console.log(collectionPath);
|
||||
if (tables.value)
|
||||
return (
|
||||
<Select
|
||||
value={collectionPath ? collectionPath : null}
|
||||
onChange={onChange}
|
||||
inputProps={{
|
||||
name: "Table",
|
||||
id: "table",
|
||||
}}
|
||||
>
|
||||
{tables.value.map((table: { collection: string; table: string }) => {
|
||||
return (
|
||||
<MenuItem
|
||||
id={`select-collection-${table.collection}`}
|
||||
value={table.collection}
|
||||
>
|
||||
<>{table.collection}</>
|
||||
</MenuItem>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
);
|
||||
else return <div />;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from "react";
|
||||
import React, { useEffect, useContext, useState } from "react";
|
||||
import Button from "@material-ui/core/Button";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import InputLabel from "@material-ui/core/InputLabel";
|
||||
@@ -11,7 +11,7 @@ import Fade from "@material-ui/core/Fade";
|
||||
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 { TextField, Grid, Select } from "@material-ui/core";
|
||||
import { FieldsDropDown, isFieldType, FieldType } from "../../Fields";
|
||||
import ToggleButton from "@material-ui/lab/ToggleButton";
|
||||
import ToggleButtonGroup from "@material-ui/lab/ToggleButtonGroup";
|
||||
@@ -25,6 +25,8 @@ import FormatColorFillIcon from "@material-ui/icons/FormatColorFill";
|
||||
import DeleteIcon from "@material-ui/icons/Delete";
|
||||
import SelectOptionsInput from "./SelectOptionsInput";
|
||||
|
||||
import DocInput from "./DocInput";
|
||||
|
||||
const useStyles = makeStyles(Theme =>
|
||||
createStyles({
|
||||
container: {
|
||||
@@ -69,12 +71,14 @@ const useStyles = makeStyles(Theme =>
|
||||
|
||||
const ColumnEditor = (props: any) => {
|
||||
const { anchorEl, column, handleClose, actions } = props;
|
||||
const [values, setValues] = React.useState({
|
||||
|
||||
const [values, setValues] = useState({
|
||||
type: null,
|
||||
name: "",
|
||||
options: [],
|
||||
collectionPath: "",
|
||||
});
|
||||
const [flags, setFlags] = React.useState(() => [""]);
|
||||
const [flags, setFlags] = useState(() => [""]);
|
||||
const classes = useStyles();
|
||||
|
||||
function handleChange(
|
||||
@@ -106,14 +110,18 @@ const ColumnEditor = (props: any) => {
|
||||
} else {
|
||||
setValue("options", []);
|
||||
}
|
||||
if (column.collectionPath) {
|
||||
setValue("collectionPath", column.collectionPath);
|
||||
}
|
||||
}
|
||||
}, [column]);
|
||||
const clearValues = () => {
|
||||
setValues({ type: null, name: "", options: [] });
|
||||
setValues({ type: null, name: "", options: [], collectionPath: "" });
|
||||
};
|
||||
const onClickAway = (event: any) => {
|
||||
const dropDownClicked = isFieldType(event.target.dataset.value);
|
||||
if (!dropDownClicked) {
|
||||
const elementId = event.target.id;
|
||||
console.log(event, elementId);
|
||||
if (!elementId.includes("select")) {
|
||||
handleClose();
|
||||
clearValues();
|
||||
}
|
||||
@@ -126,12 +134,9 @@ const ColumnEditor = (props: any) => {
|
||||
};
|
||||
|
||||
const createNewColumn = () => {
|
||||
const { name, type, options } = values;
|
||||
if (type === FieldType.multiSelect || type === FieldType.singleSelect) {
|
||||
actions.add(name, type, { options: values.options });
|
||||
} else {
|
||||
actions.add(name, type);
|
||||
}
|
||||
const { name, type, options, collectionPath } = values;
|
||||
|
||||
actions.add(name, type, { options, collectionPath });
|
||||
|
||||
handleClose();
|
||||
clearValues();
|
||||
@@ -154,6 +159,15 @@ const ColumnEditor = (props: any) => {
|
||||
) {
|
||||
updatables.push({ field: "options", value: values.options });
|
||||
}
|
||||
if (
|
||||
values.type === FieldType.documentSelect ||
|
||||
values.type === FieldType.documentsSelect
|
||||
) {
|
||||
updatables.push({
|
||||
field: "collectionPath",
|
||||
value: values.collectionPath,
|
||||
});
|
||||
}
|
||||
actions.update(props.column.idx, updatables);
|
||||
handleClose();
|
||||
clearValues();
|
||||
@@ -223,6 +237,13 @@ const ColumnEditor = (props: any) => {
|
||||
options={values.options}
|
||||
/>
|
||||
)}
|
||||
{(values.type === FieldType.documentSelect ||
|
||||
values.type === FieldType.documentsSelect) && (
|
||||
<DocInput
|
||||
setValue={setValue}
|
||||
collectionPath={values.collectionPath}
|
||||
/>
|
||||
)}
|
||||
{column.isNew ? (
|
||||
<Button onClick={createNewColumn}>Add</Button>
|
||||
) : (
|
||||
|
||||
@@ -11,6 +11,7 @@ import MultiSelect from "../Fields/MultiSelect";
|
||||
import Image from "../Fields/Image";
|
||||
import File from "../Fields/File";
|
||||
import LongText from "../Fields/LongText";
|
||||
import DocSelect from "../Fields/DocSelect";
|
||||
|
||||
const { AutoComplete } = Editors;
|
||||
|
||||
@@ -24,6 +25,7 @@ export const editable = (fieldType: FieldType) => {
|
||||
case FieldType.image:
|
||||
case FieldType.file:
|
||||
case FieldType.longText:
|
||||
case FieldType.documentSelect:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
@@ -91,7 +93,17 @@ export const cellFormatter = (column: any) => {
|
||||
};
|
||||
case FieldType.longText:
|
||||
return (props: any) => {
|
||||
return <LongText {...props} onSubmit={onSubmit(key)} fieldName={key} />;
|
||||
return <LongText {...props} onSubmit={onSubmit(key)} />;
|
||||
};
|
||||
case FieldType.documentSelect:
|
||||
return (props: any) => {
|
||||
return (
|
||||
<DocSelect
|
||||
{...props}
|
||||
onSubmit={onSubmit(key)}
|
||||
collectionPath={column.collectionPath}
|
||||
/>
|
||||
);
|
||||
};
|
||||
default:
|
||||
return false;
|
||||
@@ -99,11 +111,15 @@ export const cellFormatter = (column: any) => {
|
||||
};
|
||||
|
||||
export const singleSelectEditor = (options: string[]) => {
|
||||
const _options = options.map(option => ({
|
||||
id: option,
|
||||
value: option,
|
||||
title: option,
|
||||
text: option,
|
||||
}));
|
||||
return <AutoComplete options={_options} />;
|
||||
if (options) {
|
||||
const _options = options.map(option => ({
|
||||
id: option,
|
||||
value: option,
|
||||
title: option,
|
||||
text: option,
|
||||
}));
|
||||
return <AutoComplete options={_options} />;
|
||||
}
|
||||
|
||||
return <AutoComplete options={[]} />;
|
||||
};
|
||||
|
||||
11
src/contexts/tablesContext.ts
Normal file
11
src/contexts/tablesContext.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import React from "react";
|
||||
|
||||
interface TablesContextInterface {
|
||||
value: any[] | undefined;
|
||||
}
|
||||
|
||||
const TablesContext = React.createContext<TablesContextInterface>({
|
||||
value: undefined,
|
||||
});
|
||||
|
||||
export default TablesContext;
|
||||
Reference in New Issue
Block a user