diff --git a/www/src/components/ColumnDrawer.tsx b/www/src/components/ColumnDrawer.tsx
deleted file mode 100644
index d0c84d79..00000000
--- a/www/src/components/ColumnDrawer.tsx
+++ /dev/null
@@ -1,118 +0,0 @@
-import React, { useState, useEffect } from "react";
-import _camelCase from "lodash/camelCase";
-
-import makeStyles from "@material-ui/core/styles/makeStyles";
-import createStyles from "@material-ui/core/styles/createStyles";
-import Drawer from "@material-ui/core/Drawer";
-import List from "@material-ui/core/List";
-import Divider from "@material-ui/core/Divider";
-import ListItem from "@material-ui/core/ListItem";
-import ListItemIcon from "@material-ui/core/ListItemIcon";
-import ListItemText from "@material-ui/core/ListItemText";
-import IconButton from "@material-ui/core/IconButton";
-import TextField from "@material-ui/core/TextField";
-
-import AddIcon from "@material-ui/icons/Add";
-
-import { FIELDS } from "constants/fields";
-
-const useStyles = makeStyles(() =>
- createStyles({
- list: {
- width: 250,
- },
- fields: {
- paddingLeft: 15,
-
- paddingRight: 15,
- },
-
- fullList: {
- width: "auto",
- },
- })
-);
-
-// TODO: Create an interface for props
-export default function ColumnDrawer(props: any) {
- const { addColumn, columns } = props;
- const classes = useStyles();
- const [drawerState, toggleDrawer] = useState(false);
- const [columnName, setColumnName] = useState("");
- const [fieldName, setFieldName] = useState("");
- useEffect(() => {
- setFieldName(_camelCase(columnName));
- }, [columnName]);
- const drawer = () => (
-
{
- // toggleDrawer(false);
- }}
- >
-
- {
- setColumnName(e.target.value);
- }}
- margin="dense"
- id="name"
- label="Column Name"
- type="text"
- fullWidth
- />
- {
- setFieldName(e.target.value);
- }}
- margin="dense"
- id="field"
- label="Field Name"
- type="text"
- fullWidth
- />
-
-
-
- {FIELDS.map((field: any) => (
- {
- addColumn(columnName, fieldName, field.type);
- }}
- key={field.type}
- >
- {field.icon}
-
-
- ))}
-
-
- );
-
- return (
-
-
{
- toggleDrawer(true);
- }}
- >
-
-
-
-
{
- toggleDrawer(false);
- }}
- >
- {drawer()}
-
-
- );
-}
diff --git a/www/src/components/DatePicker/Context.ts b/www/src/components/DatePicker/Context.ts
deleted file mode 100644
index 5ca7e683..00000000
--- a/www/src/components/DatePicker/Context.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import React, { useContext } from "react";
-import { IDatePicker, DATE_PICKER_EMPTY_STATE } from "./props";
-const DatePickerContext = React.createContext(
- DATE_PICKER_EMPTY_STATE
-);
-export default DatePickerContext;
-
-export const useDatePicker = () => useContext(DatePickerContext);
diff --git a/www/src/components/DatePicker/Dialog.tsx b/www/src/components/DatePicker/Dialog.tsx
deleted file mode 100644
index 346c39a7..00000000
--- a/www/src/components/DatePicker/Dialog.tsx
+++ /dev/null
@@ -1,105 +0,0 @@
-import React from "react";
-import clsx from "clsx";
-
-import { useDebouncedCallback } from "use-debounce";
-
-import { makeStyles, createStyles } from "@material-ui/core";
-import DateRangeIcon from "@material-ui/icons/DateRange";
-import TimeIcon from "@material-ui/icons/Schedule";
-
-import { FieldType, DateIcon, DateTimeIcon } from "constants/fields";
-import { DATE_FORMAT, DATE_TIME_FORMAT } from "constants/dates";
-
-import DateFnsUtils from "@date-io/date-fns";
-import {
- MuiPickersUtilsProvider,
- KeyboardDatePicker,
- KeyboardDateTimePicker,
- DatePickerProps,
-} from "@material-ui/pickers";
-
-import { useFiretableContext } from "contexts/FiretableContext";
-
-const useStyles = makeStyles((theme) =>
- createStyles({
- root: {
- height: "100%",
- },
- inputBase: { height: "100%" },
-
- inputAdornment: {
- height: "100%",
- marginLeft: theme.spacing(1) + 1,
- marginRight: theme.spacing(0.25),
- },
-
- input: {
- ...theme.typography.body2,
- fontSize: "0.75rem",
- color: theme.palette.text.secondary,
- height: "100%",
- padding: theme.spacing(1.5, 0),
- },
-
- dateTabIcon: {
- color: theme.palette.primary.contrastText,
- },
- })
-);
-
-export default function Date({ rowIdx, column, value, onSubmit }: any) {
- const classes = useStyles();
- const { dataGridRef } = useFiretableContext();
-
- const transformedValue =
- value && typeof value !== "number" && "toDate" in value
- ? value.toDate()
- : null;
-
- const fieldType = (column as any).type;
- const Picker =
- fieldType === FieldType.date ? KeyboardDatePicker : KeyboardDateTimePicker;
- const Icon = fieldType === FieldType.date ? DateIcon : DateTimeIcon;
-
- const [handleDateChange] = useDebouncedCallback(
- (date) => {
- if (isNaN(date?.valueOf() ?? 0)) return;
-
- onSubmit(date);
- if (dataGridRef?.current?.selectCell)
- dataGridRef.current.selectCell({ rowIdx, idx: column.idx });
- },
- 500
- );
-
- return (
-
- e.stopPropagation()}
- format={fieldType === FieldType.date ? DATE_FORMAT : DATE_TIME_FORMAT}
- fullWidth
- clearable
- keyboardIcon={}
- className={clsx("cell-collapse-padding", classes.root)}
- inputVariant="standard"
- InputProps={{
- disableUnderline: true,
- classes: { root: classes.inputBase, input: classes.input },
- }}
- InputAdornmentProps={{
- position: "start",
- classes: { root: classes.inputAdornment },
- }}
- KeyboardButtonProps={{
- size: "small",
- classes: { root: "row-hover-iconButton" },
- }}
- DialogProps={{ onClick: (e) => e.stopPropagation() }}
- dateRangeIcon={}
- timeIcon={}
- />
-
- );
-}
diff --git a/www/src/components/DatePicker/Provider.tsx b/www/src/components/DatePicker/Provider.tsx
deleted file mode 100644
index 61a7be52..00000000
--- a/www/src/components/DatePicker/Provider.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import React, { useState, lazy, Suspense } from "react";
-
-import { datePickerProps } from "./props";
-const Dialog = lazy(
- () => import("./Dialog" /* webpackChunkName: "DatePickerDialog" */)
-);
-import ConfirmationContext from "./Context";
-interface IConfirmationProviderProps {
- children: React.ReactNode;
-}
-
-const ConfirmationProvider: React.FC = ({
- children,
-}) => {
- const [state, setState] = useState();
- const [open, setOpen] = useState(false);
- const handleClose = () => {
- setState(undefined);
- setOpen(false);
- };
- const setDate = (props: datePickerProps) => {
- setState(props);
- setOpen(true);
- };
- return (
-
- {children}
-
-
-
-
-
- );
-};
-
-export default ConfirmationProvider;
diff --git a/www/src/components/DatePicker/index.ts b/www/src/components/DatePicker/index.ts
deleted file mode 100644
index b520ae6f..00000000
--- a/www/src/components/DatePicker/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { useDatePicker } from "./Context";
diff --git a/www/src/components/DatePicker/props.ts b/www/src/components/DatePicker/props.ts
deleted file mode 100644
index 7255f5f7..00000000
--- a/www/src/components/DatePicker/props.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-export type datePickerProps =
- | {
- title?: string;
- customBody?: string;
- body?: string;
- cancel?: string;
- confirm?: string | JSX.Element;
- confirmationCommand?: string;
- handleConfirm: () => void;
- open?: Boolean;
- }
- | undefined;
-export interface IDatePicker {
- props?: datePickerProps;
- handleClose: () => void;
- open: boolean;
- setDate: (props: datePickerProps) => void;
-}
-export const DATE_PICKER_EMPTY_STATE = {
- props: undefined,
- open: false,
- handleClose: () => {},
- setDate: () => {},
-};
diff --git a/www/src/components/SideDrawer/Form/FieldWrapper.tsx b/www/src/components/SideDrawer/Form/FieldWrapper.tsx
index 562763d0..43c7b318 100644
--- a/www/src/components/SideDrawer/Form/FieldWrapper.tsx
+++ b/www/src/components/SideDrawer/Form/FieldWrapper.tsx
@@ -14,7 +14,8 @@ import LockIcon from "@material-ui/icons/Lock";
import ErrorBoundary from "components/ErrorBoundary";
import FieldSkeleton from "./FieldSkeleton";
-import { FieldType, getFieldIcon } from "constants/fields";
+import { FieldType } from "constants/fields";
+import { getFieldProp } from "components/fields";
const useStyles = makeStyles((theme) =>
createStyles({
@@ -68,7 +69,7 @@ export default function FieldWrapper({
htmlFor={`sidedrawer-field-${name}`}
>
- {type === "debug" ? : getFieldIcon(type)}
+ {type === "debug" ? : getFieldProp("icon", type)}
{label}
diff --git a/www/src/components/Table/ColumnMenu/index.tsx b/www/src/components/Table/ColumnMenu/index.tsx
index 66f6b9e5..fbf0198e 100644
--- a/www/src/components/Table/ColumnMenu/index.tsx
+++ b/www/src/components/Table/ColumnMenu/index.tsx
@@ -24,11 +24,11 @@ import TypeChange from "./TypeChange";
import Settings from "./Settings";
import { useFiretableContext } from "contexts/FiretableContext";
-import { FIELDS, FieldType } from "constants/fields";
+import { FieldType } from "constants/fields";
+import { getFieldProp } from "components/fields";
import _find from "lodash/find";
import { Column } from "react-data-grid";
import { PopoverProps } from "@material-ui/core";
-import { getFieldProp } from "components/fields";
const INITIAL_MODAL = { type: "", data: {} };
@@ -218,7 +218,7 @@ export default function ColumnMenu() {
{
label: `Edit Type: ${getFieldProp("name", column.type)}`,
// This is based off the cell type
- icon: _find(FIELDS, { type: column.type })?.icon,
+ icon: getFieldProp("icon", column.type),
onClick: () => {
setModal({ type: ModalStates.typeChange, data: { column } });
},
diff --git a/www/src/components/Wizards/Column.tsx b/www/src/components/Wizards/Column.tsx
index 762234c8..704f970e 100644
--- a/www/src/components/Wizards/Column.tsx
+++ b/www/src/components/Wizards/Column.tsx
@@ -10,7 +10,8 @@ import {
} from "@material-ui/core";
import { fade } from "@material-ui/core/styles";
-import { FieldType, getFieldIcon } from "constants/fields";
+import { FieldType } from "constants/fields";
+import { getFieldProp } from "components/fields";
const useStyles = makeStyles((theme) =>
createStyles({
@@ -88,7 +89,7 @@ export default function Column({
{...props}
className={clsx(classes.root, active && classes.active, props.className)}
>
- {type && {getFieldIcon(type)}}
+ {type && {getFieldProp("icon", type)}}
createStyles({
diff --git a/www/src/components/fields/File/index.tsx b/www/src/components/fields/File/index.tsx
index ae0bacd7..16aaf1b0 100644
--- a/www/src/components/fields/File/index.tsx
+++ b/www/src/components/fields/File/index.tsx
@@ -27,3 +27,5 @@ export const config: IFieldConfig = {
SideDrawerField,
};
export default config;
+
+export { FileIcon };
diff --git a/www/src/components/fields/Id/index.tsx b/www/src/components/fields/Id/index.tsx
index b5cad6c6..64c2ccc2 100644
--- a/www/src/components/fields/Id/index.tsx
+++ b/www/src/components/fields/Id/index.tsx
@@ -15,7 +15,7 @@ const SideDrawerField = lazy(
export const config: IFieldConfig = {
type: FieldType.id,
- name: "Id",
+ name: "ID",
dataType: "undefined",
initialValue: undefined,
icon: ,
diff --git a/www/src/components/fields/Image/SideDrawerField.tsx b/www/src/components/fields/Image/SideDrawerField.tsx
index 543666b7..979925aa 100644
--- a/www/src/components/fields/Image/SideDrawerField.tsx
+++ b/www/src/components/fields/Image/SideDrawerField.tsx
@@ -21,7 +21,7 @@ import AddIcon from "@material-ui/icons/AddAPhoto";
import DeleteIcon from "@material-ui/icons/Delete";
import OpenIcon from "@material-ui/icons/OpenInNewOutlined";
-import { IMAGE_MIME_TYPES } from "constants/fields";
+import { IMAGE_MIME_TYPES } from ".";
import Thumbnail from "components/Thumbnail";
import { useConfirmation } from "components/ConfirmationDialog";
diff --git a/www/src/constants/fields.ts b/www/src/constants/fields.ts
new file mode 100644
index 00000000..ace2ca77
--- /dev/null
+++ b/www/src/constants/fields.ts
@@ -0,0 +1,42 @@
+// Define field type strings used in Firetable column config
+export enum FieldType {
+ // TEXT
+ shortText = "SIMPLE_TEXT",
+ longText = "LONG_TEXT",
+ email = "EMAIL",
+ phone = "PHONE_NUMBER",
+ url = "URL",
+ // NUMERIC
+ checkbox = "CHECK_BOX",
+ number = "NUMBER",
+ percentage = "PERCENTAGE",
+ rating = "RATING",
+ slider = "SLIDER",
+ color = "COLOR",
+ // DATE & TIME
+ date = "DATE",
+ dateTime = "DATE_TIME",
+ duration = "DURATION",
+ // FILE
+ image = "IMAGE",
+ file = "FILE",
+ // SELECT
+ singleSelect = "SINGLE_SELECT",
+ multiSelect = "MULTI_SELECT",
+ // CONNECTION
+ subTable = "SUB_TABLE",
+ connectTable = "DOCUMENT_SELECT",
+ connectService = "SERVICE_SELECT",
+ // CODE
+ json = "JSON",
+ code = "CODE",
+ richText = "RICH_TEXT",
+ // CLOUD FUNCTION
+ action = "ACTION",
+ derivative = "DERIVATIVE",
+ aggregate = "AGGREGATE",
+ // FIRETABLE
+ user = "USER",
+ id = "ID",
+ last = "LAST",
+}
diff --git a/www/src/constants/fields.tsx b/www/src/constants/fields.tsx
deleted file mode 100644
index de4b90c0..00000000
--- a/www/src/constants/fields.tsx
+++ /dev/null
@@ -1,264 +0,0 @@
-import React from "react";
-import propEq from "ramda/es/propEq";
-import find from "ramda/es/find";
-
-import ShortTextIcon from "@material-ui/icons/ShortText";
-import LongTextIcon from "@material-ui/icons/Notes";
-import EmailIcon from "@material-ui/icons/Mail";
-import PhoneIcon from "@material-ui/icons/Phone";
-
-import CheckboxIcon from "@material-ui/icons/CheckBox";
-import NumberIcon from "assets/icons/Number";
-import PercentageIcon from "assets/icons/Percentage";
-
-import DateIcon from "@material-ui/icons/Today";
-import DateTimeIcon from "@material-ui/icons/AccessTime";
-import DurationIcon from "@material-ui/icons/Timer";
-
-import UrlIcon from "@material-ui/icons/Link";
-import RatingIcon from "@material-ui/icons/StarBorder";
-
-import ImageIcon from "@material-ui/icons/PhotoSizeSelectActual";
-import FileIcon from "@material-ui/icons/AttachFile";
-
-import SingleSelectIcon from "@material-ui/icons/FormatListBulleted";
-import MultiSelectIcon from "assets/icons/MultiSelect";
-
-import SubTableIcon from "assets/icons/SubTable";
-import ConnectTableIcon from "assets/icons/ConnectTable";
-import ConnectServiceIcon from "@material-ui/icons/Http";
-
-import JsonIcon from "assets/icons/Json";
-import CodeIcon from "@material-ui/icons/Code";
-import RichTextIcon from "@material-ui/icons/TextFormat";
-
-import ActionIcon from "assets/icons/Action";
-import DerivativeIcon from "assets/icons/Derivative";
-import AggregateIcon from "@material-ui/icons/Layers";
-
-import ColorIcon from "@material-ui/icons/Colorize";
-import SliderIcon from "assets/icons/Slider";
-
-import UserIcon from "@material-ui/icons/Person";
-import IdIcon from "assets/icons/Id";
-
-export {
- ShortTextIcon,
- LongTextIcon,
- EmailIcon,
- PhoneIcon,
- CheckboxIcon,
- NumberIcon,
- PercentageIcon,
- DateIcon,
- DateTimeIcon,
- DurationIcon,
- UrlIcon,
- RatingIcon,
- ImageIcon,
- FileIcon,
- SingleSelectIcon,
- MultiSelectIcon,
- SubTableIcon,
- ConnectTableIcon,
- ConnectServiceIcon,
- JsonIcon,
- CodeIcon,
- RichTextIcon,
- ActionIcon,
- DerivativeIcon,
- AggregateIcon,
- ColorIcon,
- SliderIcon,
- UserIcon,
- IdIcon,
-};
-
-// Define field type strings used in Firetable column config
-export enum FieldType {
- // TEXT
- shortText = "SIMPLE_TEXT",
- longText = "LONG_TEXT",
- email = "EMAIL",
- phone = "PHONE_NUMBER",
- url = "URL",
- // NUMERIC
- checkbox = "CHECK_BOX",
- number = "NUMBER",
- percentage = "PERCENTAGE",
- rating = "RATING",
- slider = "SLIDER",
- color = "COLOR",
- // DATE & TIME
- date = "DATE",
- dateTime = "DATE_TIME",
- duration = "DURATION",
- // FILE
- image = "IMAGE",
- file = "FILE",
- // SELECT
- singleSelect = "SINGLE_SELECT",
- multiSelect = "MULTI_SELECT",
- // CONNECTION
- subTable = "SUB_TABLE",
- connectTable = "DOCUMENT_SELECT",
- connectService = "SERVICE_SELECT",
- // CODE
- json = "JSON",
- code = "CODE",
- richText = "RICH_TEXT",
- // CLOUD FUNCTION
- action = "ACTION",
- derivative = "DERIVATIVE",
- aggregate = "AGGREGATE",
- // FIRETABLE
- user = "USER",
- id = "ID",
- last = "LAST",
-}
-
-export const FIELDS = [
- { icon: , name: "Short Text", type: FieldType.shortText },
- { icon: , name: "Long Text", type: FieldType.longText },
- { icon: , name: "Email", type: FieldType.email },
- { icon: , name: "Phone", type: FieldType.phone },
-
- { icon: , name: "Checkbox", type: FieldType.checkbox },
- { icon: , name: "Number", type: FieldType.number },
- { icon: , name: "Percentage", type: FieldType.percentage },
-
- { icon: , name: "Date", type: FieldType.date },
- { icon: , name: "Time & Date", type: FieldType.dateTime },
- { icon: , name: "Duration", type: FieldType.duration },
-
- { icon: , name: "URL", type: FieldType.url },
- { icon: , name: "Rating", type: FieldType.rating },
-
- { icon: , name: "Image", type: FieldType.image },
- { icon: , name: "File", type: FieldType.file },
-
- {
- icon: ,
- name: "Single Select",
- type: FieldType.singleSelect,
- },
- {
- icon: ,
- name: "Multi Select",
- type: FieldType.multiSelect,
- },
-
- {
- icon: ,
- name: "Sub-Table",
- type: FieldType.subTable,
- },
- {
- icon: ,
- name: "Connect Table",
- type: FieldType.connectTable,
- },
- {
- icon: ,
- name: "Connect Service",
- type: FieldType.connectService,
- },
-
- { icon: , name: "JSON", type: FieldType.json },
- { icon: , name: "Code", type: FieldType.code },
- { icon: , name: "Rich Text", type: FieldType.richText },
-
- { icon: , name: "Action", type: FieldType.action },
- { icon: , name: "Derivative", type: FieldType.derivative },
- { icon: , name: "Aggregate", type: FieldType.aggregate },
-
- { icon: , name: "Color", type: FieldType.color },
- { icon: , name: "Slider", type: FieldType.slider },
-
- { icon: , name: "User", type: FieldType.user },
- { icon: , name: "ID", type: FieldType.id },
-];
-
-export const FIELD_TYPE_DESCRIPTIONS = {
- [FieldType.shortText]: "Small amount of text, such as names and taglines.",
- [FieldType.longText]:
- "Large amount of text, such as sentences and paragraphs.",
- [FieldType.email]: "Email address. Firetable does not validate emails.",
- [FieldType.phone]:
- "Phone numbers stored as text. Firetable does not validate phone numbers.",
-
- [FieldType.checkbox]: "Either checked or unchecked. Unchecked by default.",
- [FieldType.number]: "Numeric data.",
- [FieldType.percentage]: "Percentage stored as a number between 0 and 1.",
-
- [FieldType.date]:
- "Date displayed and input as YYYY/MM/DD or input using a picker module.",
- [FieldType.dateTime]:
- "Time and Date can be written as YYYY/MM/DD hh:mm (am/pm) or input using a picker module.",
- [FieldType.duration]: "Duration calculated from two timestamps.",
-
- [FieldType.url]: "Web address. Firetable does not validate URLs.",
- [FieldType.rating]:
- "Rating displayed as stars from 0 to configurable number of stars. Default: 5 stars.",
-
- [FieldType.image]:
- "Image file uploaded to Firebase Storage. Supports JPEG, PNG, SVG, GIF, WebP.",
- [FieldType.file]:
- "File uploaded to Firebase Storage. Supports any file type.",
-
- [FieldType.singleSelect]:
- "Dropdown selector with searchable options and radio button behavior. Optionally allows users to input custom values. Max selection: 1 option.",
- [FieldType.multiSelect]:
- "Dropdown selector with searchable options and check box behavior. Optionally allows users to input custom values. Max selection: all options.",
-
- [FieldType.subTable]:
- "Creates a sub-table. Also displays number of rows inside the sub-table. Max sub-table levels: 100.",
- [FieldType.connectTable]:
- "Connects to an existing table to fetch a snapshot of values from a row. Requires Algolia integration.",
- [FieldType.connectService]:
- "Select a value from a list of external web service results.",
-
- [FieldType.json]: "JSON object editable with a visual JSON editor.",
- [FieldType.code]: "Raw code editable with Monaco Editor.",
- [FieldType.richText]: "Rich text editor with predefined HTML text styles.",
-
- [FieldType.action]:
- "A button with a pre-defined action. Triggers a Cloud Function. 3 different states: Disabled, Enabled, Active (Clicked). Supports Undo and Redo.",
- [FieldType.derivative]:
- "Value derived from the rest of the row’s values. Displayed using any other field type. Requires Cloud Function setup.",
- [FieldType.aggregate]:
- "Value aggregated from a specified sub-table of the row. Displayed using any other field type. Requires Cloud Function setup.",
-
- [FieldType.color]: "Visual color picker. Supports Hex, RGBA, HSLA.",
- [FieldType.slider]: "Slider with adjustable range. Returns a numeric value.",
-
- [FieldType.user]: "Displays the _ft_updatedBy field for editing history.",
- [FieldType.id]: "Displays the row’s document ID. Cannot be sorted.",
- [FieldType.last]: "Internally used to display last column with row actions.",
-};
-
-/**
- * Returns icon associated with field type
- * @param fieldType
- */
-export const getFieldIcon = (fieldType: FieldType) => {
- const field: any = find(propEq("type", fieldType))(FIELDS);
- return field.icon;
-};
-
-/**
- * Returns `true` if it receives an existing fieldType
- * @param fieldType
- */
-export const isFieldType = (fieldType: any) => {
- const fieldTypes = FIELDS.map((field) => field.type);
- return fieldTypes.includes(fieldType);
-};
-
-export const IMAGE_MIME_TYPES = [
- "image/jpeg",
- "image/png",
- "image/svg+xml",
- "image/gif",
- "image/webp",
-];