@@ -371,7 +371,7 @@ function SnackLog({ log, onClose, onOpenPanel }) {
})}
{status === "BUILDING" && (
-
@@ -427,10 +427,9 @@ export default function TableLogs() {
<>
{latestStatus === "BUILDING" && (
-
)}
@@ -499,7 +498,7 @@ export default function TableLogs() {
style={{ textAlign: "left" }}
>
{logEntry.status === "BUILDING" && (
-
+
)}
{logEntry.status === "SUCCESS" &&
}
{logEntry.status === "FAIL" &&
}
diff --git a/src/components/Table/TableHeader/Webhooks/Step2Conditions.tsx b/src/components/Table/TableHeader/Webhooks/Step2Conditions.tsx
index 41efaa76..3bde07af 100644
--- a/src/components/Table/TableHeader/Webhooks/Step2Conditions.tsx
+++ b/src/components/Table/TableHeader/Webhooks/Step2Conditions.tsx
@@ -1,8 +1,8 @@
import { IWebhookModalStepProps } from "./WebhookModal";
import useStateRef from "react-usestateref";
-import CodeEditor from "components/Table/editors/CodeEditor";
-import CodeEditorHelper from "components/CodeEditorHelper";
+import CodeEditor from "components/CodeEditor";
+import CodeEditorHelper from "components/CodeEditor/CodeEditorHelper";
import { WIKI_LINKS } from "constants/externalLinks";
@@ -26,12 +26,12 @@ export default function Step3Conditions({
<>
{
+ value={webhookObject.conditions}
+ minHeight={200}
+ onChange={(newValue) => {
setWebhookObject({
...webhookObject,
- conditions: newValue,
+ conditions: newValue || "",
});
}}
onValidStatusUpdate={({ isValid }) => {
diff --git a/src/components/Table/TableHeader/Webhooks/Step3Parser.tsx b/src/components/Table/TableHeader/Webhooks/Step3Parser.tsx
index cbeb8dc4..7939dedb 100644
--- a/src/components/Table/TableHeader/Webhooks/Step3Parser.tsx
+++ b/src/components/Table/TableHeader/Webhooks/Step3Parser.tsx
@@ -2,8 +2,8 @@ import { IWebhookModalStepProps } from "./WebhookModal";
import _upperFirst from "lodash/upperFirst";
import useStateRef from "react-usestateref";
-import CodeEditor from "components/Table/editors/CodeEditor";
-import CodeEditorHelper from "components/CodeEditorHelper";
+import CodeEditor from "components/CodeEditor";
+import CodeEditorHelper from "components/CodeEditor/CodeEditorHelper";
import { WIKI_LINKS } from "constants/externalLinks";
@@ -26,12 +26,12 @@ export default function Step4Body({
<>
{
+ value={webhookObject.parser}
+ minHeight={400}
+ onChange={(newValue) => {
setWebhookObject({
...webhookObject,
- parser: newValue,
+ parser: newValue || "",
});
}}
onValidStatusUpdate={({ isValid }) => {
diff --git a/src/components/Table/TableHeader/Webhooks/WebhookList.tsx b/src/components/Table/TableHeader/Webhooks/WebhookList.tsx
index 106011dd..fd8af180 100644
--- a/src/components/Table/TableHeader/Webhooks/WebhookList.tsx
+++ b/src/components/Table/TableHeader/Webhooks/WebhookList.tsx
@@ -90,7 +90,7 @@ export default function WebhookList({
onClick={handleAddButton}
ref={addButtonRef}
>
- Add Webhook…
+ Add webhook…
>
);
-};
-export default Settings;
+}
diff --git a/src/components/fields/File/SideDrawerField.tsx b/src/components/fields/File/SideDrawerField.tsx
index 5cea9319..547fd9b3 100644
--- a/src/components/fields/File/SideDrawerField.tsx
+++ b/src/components/fields/File/SideDrawerField.tsx
@@ -15,12 +15,12 @@ import {
Grid,
Tooltip,
Chip,
- CircularProgress,
} from "@mui/material";
import UploadIcon from "assets/icons/Upload";
import { FileIcon } from ".";
import Confirmation from "components/Confirmation";
+import CircularProgressOptical from "components/CircularProgressOptical";
import { DATE_TIME_FORMAT } from "constants/dates";
import { useFieldStyles } from "components/SideDrawer/Form/utils";
@@ -148,9 +148,7 @@ function ControlledFileUploader({
}
label={localFile}
- deleteIcon={
-
- }
+ deleteIcon={}
/>
)}
diff --git a/src/components/fields/File/TableCell.tsx b/src/components/fields/File/TableCell.tsx
index 9d609556..dd37cc9f 100644
--- a/src/components/fields/File/TableCell.tsx
+++ b/src/components/fields/File/TableCell.tsx
@@ -6,17 +6,10 @@ import _findIndex from "lodash/findIndex";
import { format } from "date-fns";
import { makeStyles, createStyles } from "@mui/styles";
-import {
- alpha,
- Stack,
- Grid,
- Tooltip,
- Chip,
- IconButton,
- CircularProgress,
-} from "@mui/material";
+import { alpha, Stack, Grid, Tooltip, Chip, IconButton } from "@mui/material";
import UploadIcon from "assets/icons/Upload";
import ChipList from "components/Table/formatters/ChipList";
+import CircularProgressOptical from "components/CircularProgressOptical";
import { useConfirmation } from "components/ConfirmationDialog";
import useUploader, { FileValue } from "hooks/useTable/useUploader";
@@ -184,11 +177,10 @@ export default function File_({
)
) : (
-
diff --git a/src/components/fields/Image/SideDrawerField.tsx b/src/components/fields/Image/SideDrawerField.tsx
index d5275205..8968ffef 100644
--- a/src/components/fields/Image/SideDrawerField.tsx
+++ b/src/components/fields/Image/SideDrawerField.tsx
@@ -7,14 +7,7 @@ import { useDropzone } from "react-dropzone";
import useUploader from "hooks/useTable/useUploader";
import { makeStyles, createStyles } from "@mui/styles";
-import {
- alpha,
- ButtonBase,
- Typography,
- Grid,
- CircularProgress,
- Tooltip,
-} from "@mui/material";
+import { alpha, ButtonBase, Typography, Grid, Tooltip } from "@mui/material";
import AddIcon from "@mui/icons-material/AddAPhotoOutlined";
import DeleteIcon from "@mui/icons-material/DeleteOutlined";
@@ -22,6 +15,7 @@ import OpenIcon from "@mui/icons-material/OpenInNewOutlined";
import { IMAGE_MIME_TYPES } from ".";
import Thumbnail from "components/Thumbnail";
+import CircularProgressOptical from "components/CircularProgressOptical";
import { useConfirmation } from "components/ConfirmationDialog";
import { useProjectContext } from "contexts/ProjectContext";
@@ -247,7 +241,7 @@ function ControlledImageUploader({
alignItems="center"
className={classes.overlay}
>
-
-
diff --git a/src/components/fields/Json/Settings.tsx b/src/components/fields/Json/Settings.tsx
index 4955ff44..d424c707 100644
--- a/src/components/fields/Json/Settings.tsx
+++ b/src/components/fields/Json/Settings.tsx
@@ -1,21 +1,25 @@
-import { Switch, FormControlLabel } from "@mui/material";
+import { Checkbox, FormControlLabel, FormHelperText } from "@mui/material";
const Settings = ({ config, handleChange }) => {
return (
<>
handleChange("isArray")(!Boolean(config.isArray))}
name="isArray"
/>
}
- label="Set as array"
- sx={{
- alignItems: "center",
- "& .MuiFormControlLabel-label": { mt: 0 },
- }}
+ label={
+ <>
+ Default as array
+
+ You can still set individual field values as a JSON object or
+ array using the code editor
+
+ >
+ }
/>
>
);
diff --git a/src/components/fields/Json/SideDrawerField.tsx b/src/components/fields/Json/SideDrawerField.tsx
index 46c3f761..f3f6f084 100644
--- a/src/components/fields/Json/SideDrawerField.tsx
+++ b/src/components/fields/Json/SideDrawerField.tsx
@@ -1,12 +1,20 @@
+import { useState } from "react";
import { Controller } from "react-hook-form";
+import createPersistedState from "use-persisted-state";
import { ISideDrawerFieldProps } from "../types";
import ReactJson from "react-json-view";
import jsonFormat from "json-format";
+import CodeEditor from "components/CodeEditor";
-import { useTheme } from "@mui/material";
+import { useTheme, Tab, FormHelperText } from "@mui/material";
+import TabContext from "@mui/lab/TabContext";
+import TabList from "@mui/lab/TabList";
+import TabPanel from "@mui/lab/TabPanel";
import { useFieldStyles } from "components/SideDrawer/Form/utils";
+const useJsonEditor = createPersistedState("__ROWY__JSON_EDITOR");
+
const isValidJson = (val: any) => {
try {
if (typeof val === "string") JSON.parse(val);
@@ -25,11 +33,31 @@ export default function Json({
const fieldClasses = useFieldStyles();
const theme = useTheme();
+ const [editor, setEditor] = useJsonEditor<"tree" | "code">("tree");
+ const [codeValid, setCodeValid] = useState(true);
+
+ const changeEditor = (_, newValue) => {
+ setEditor(newValue);
+ setCodeValid(true);
+ };
+
return (
{
+ const sanitizedValue =
+ value !== undefined && isValidJson(value)
+ ? value
+ : column.config?.isArray
+ ? []
+ : {};
+ const formattedJson = jsonFormat(sanitizedValue, {
+ type: "space",
+ char: " ",
+ size: 2,
+ });
+
if (disabled)
return (
- {value &&
- jsonFormat(value, {
- type: "space",
- char: " ",
- size: 2,
- })}
+ {value && formattedJson}
);
@@ -55,46 +78,68 @@ export default function Json({
};
return (
-
-
+
-
+ >
+
+
+
+
+
+
+
+
+
+
+
+ {
+ try {
+ if (v) onChange(JSON.parse(v));
+ } catch (e) {
+ console.log(`Failed to parse JSON: ${e}`);
+ setCodeValid(false);
+ }
+ }}
+ onValidStatusUpdate={({ isValid }) => setCodeValid(isValid)}
+ error={!codeValid}
+ />
+ {!codeValid && (
+
+ Invalid JSON
+
+ )}
+
+
);
}}
/>
diff --git a/src/components/fields/types.ts b/src/components/fields/types.ts
index 9f9932d3..853ea496 100644
--- a/src/components/fields/types.ts
+++ b/src/components/fields/types.ts
@@ -61,9 +61,7 @@ export interface ISideDrawerFieldProps {
export interface ISettingsProps {
handleChange: (key: string) => (value: any) => void;
config: Record;
- // TODO: WRITE TYPES
- tables: any;
- [key: string]: any;
+ fieldName: string;
}
// TODO: WRITE TYPES
diff --git a/src/hooks/useTable/useTableData.tsx b/src/hooks/useTable/useTableData.tsx
index 0ea6e34c..2b1a18f1 100644
--- a/src/hooks/useTable/useTableData.tsx
+++ b/src/hooks/useTable/useTableData.tsx
@@ -270,7 +270,7 @@ const useTableData = () => {
: [];
const { path } = tableState;
- const newId = generateSmallerId(rows[0]?.id ?? "zzzzzzzzzzzzzzzzzzzzzzzz");
+ const newId = generateSmallerId(rows[0]?.id ?? "zzzzzzzzzzzzzzzzzzzz");
if (missingRequiredFields.length === 0) {
try {
diff --git a/src/pages/Settings/UserSettings.tsx b/src/pages/Settings/UserSettings.tsx
index 96866fa9..40d94b59 100644
--- a/src/pages/Settings/UserSettings.tsx
+++ b/src/pages/Settings/UserSettings.tsx
@@ -48,7 +48,7 @@ export default function UserSettingsPage() {
const sections = [
{ title: "Account", Component: Account, props: childProps },
- { title: "Theme", Component: Theme },
+ { title: "Theme", Component: Theme, props: childProps },
{ title: "Personalization", Component: Personalization, props: childProps },
];
diff --git a/src/pages/Test.tsx b/src/pages/Test.tsx
index 68adf056..5511cae0 100644
--- a/src/pages/Test.tsx
+++ b/src/pages/Test.tsx
@@ -43,6 +43,7 @@ import { useConfirmation } from "components/ConfirmationDialog";
import SnackbarProgress, {
ISnackbarProgressRef,
} from "components/SnackbarProgress";
+import CircularProgressOptical from "components/CircularProgressOptical";
const typographyVariants = [
"h1",
@@ -913,7 +914,26 @@ export default function TestView() {
-
+
+ {/* size 40 thickness 3.6 */}
+
+
+
+
+
+
+
+
+
+ {/* size 40 thickness 3.6 */}
+
+
+
+
+
+
+
+
diff --git a/src/theme/components.tsx b/src/theme/components.tsx
index 644907bc..1f914289 100644
--- a/src/theme/components.tsx
+++ b/src/theme/components.tsx
@@ -256,23 +256,23 @@ export const components = (theme: Theme): ThemeOptions => {
backgroundColor: theme.palette.action.input,
},
- boxShadow: `0 0 0 1px ${theme.palette.action.inputOutline} inset,
- 0 -1px 0 0 ${theme.palette.text.disabled} inset`,
+ boxShadow: `0 -1px 0 0 ${theme.palette.text.disabled} inset,
+ 0 0 0 1px ${theme.palette.action.inputOutline} inset`,
transition: theme.transitions.create("box-shadow", {
duration: theme.transitions.duration.short,
}),
"&:hover": {
- boxShadow: `0 0 0 1px ${theme.palette.action.inputOutline} inset,
- 0 -1px 0 0 ${theme.palette.text.primary} inset`,
+ boxShadow: `0 -1px 0 0 ${theme.palette.text.primary} inset,
+ 0 0 0 1px ${theme.palette.action.inputOutline} inset`,
},
"&.Mui-focused, &.Mui-focused:hover": {
- boxShadow: `0 0 0 1px ${theme.palette.action.inputOutline} inset,
- 0 -2px 0 0 ${theme.palette.primary.main} inset`,
+ boxShadow: `0 -2px 0 0 ${theme.palette.primary.main} inset,
+ 0 0 0 1px ${theme.palette.action.inputOutline} inset`,
},
"&.Mui-error, &.Mui-error:hover": {
- boxShadow: `0 0 0 1px ${theme.palette.action.inputOutline} inset,
- 0 -2px 0 0 ${theme.palette.error.main} inset`,
+ boxShadow: `0 -2px 0 0 ${theme.palette.error.main} inset,
+ 0 0 0 1px ${theme.palette.action.inputOutline} inset`,
},
borderRadius: theme.shape.borderRadius,
@@ -368,7 +368,7 @@ export const components = (theme: Theme): ThemeOptions => {
root: {
width: `calc(100% - ${theme.spacing(1)})`,
margin: theme.spacing(0, 0.5),
- padding: theme.spacing(0.5, 0.75, 0.5, 1.5),
+ padding: theme.spacing(0.5, 1.5),
minHeight: 32,
borderRadius: theme.shape.borderRadius,
diff --git a/src/utils/fns.ts b/src/utils/fns.ts
index 936b2189..93efd586 100644
--- a/src/utils/fns.ts
+++ b/src/utils/fns.ts
@@ -68,29 +68,56 @@ export const isCollectionGroup = () => {
const pathName = window.location.pathname.split("/")[1];
return pathName === "tableGroup";
};
-var characters =
+
+const characters =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-export function makeId(length) {
- var result = "";
- var charactersLength = characters.length;
- for (var i = 0; i < length; i++) {
+export const makeId = (length: number = 20) => {
+ let result = "";
+ const charactersLength = characters.length;
+ for (var i = 0; i < length; i++)
result += characters.charAt(Math.floor(Math.random() * charactersLength));
- }
+
return result;
-}
+};
export const generateSmallerId = (id: string) => {
- const indexOfFirstChar = characters.indexOf(id[0]);
- if (indexOfFirstChar !== 0)
- return characters[indexOfFirstChar - 1] + makeId(id.length - 1);
- else return id[0] + generateSmallerId(id.substr(1, id.length - 1));
+ const generated = id.split("");
+ for (let i = generated.length - 1; i >= 0; i--) {
+ const charIndex = characters.indexOf(id[i]);
+ if (charIndex > 0) {
+ generated[i] = characters[charIndex - 1];
+ break;
+ } else if (i > 0) {
+ continue;
+ } else {
+ generated.push(characters[characters.length - 1]);
+ }
+ }
+
+ // Ensure we don't get 00...0, then the next ID would be 00...0z,
+ // which would appear as the second row
+ if (generated.every((char) => char === characters[0]))
+ generated.push(characters[characters.length - 1]);
+
+ return generated.join("");
};
export const generateBiggerId = (id: string) => {
- const indexOfFirstChar = characters.indexOf(id[0]);
- if (indexOfFirstChar !== 61)
- return characters[indexOfFirstChar + 1] + makeId(id.length - 1);
- else return id[0] + generateBiggerId(id.substr(1, id.length - 1));
+ const generated = id.split("");
+ for (let i = generated.length - 1; i >= 0; i--) {
+ const charIndex = characters.indexOf(id[i]);
+ console.log(i, id[i], charIndex);
+ if (charIndex < characters.length - 1) {
+ generated[i] = characters[charIndex + 1];
+ break;
+ } else if (i > 0) {
+ continue;
+ } else {
+ generated.push(characters[0]);
+ }
+ }
+
+ return generated.join("");
};
// Gets sub-table ID in $1
diff --git a/types/custom.ts b/types/custom.ts
index ae704ef5..63f9f2d0 100644
--- a/types/custom.ts
+++ b/types/custom.ts
@@ -6,3 +6,7 @@ declare module "*.mp4" {
const content: any;
export default content;
}
+declare module "!!raw-loader!*" {
+ const content: string;
+ export default content;
+}
diff --git a/yarn.lock b/yarn.lock
index 5c7be15c..0a60e954 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2374,7 +2374,7 @@
dependencies:
state-local "^1.0.6"
-"@monaco-editor/react@^4.1.0":
+"@monaco-editor/react@^4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@monaco-editor/react/-/react-4.3.1.tgz#d65bcbf174c39b6d4e7fec43d0cddda82b70a12a"
integrity sha512-f+0BK1PP/W5I50hHHmwf11+Ea92E5H1VZXs+wvKplWUWOfyMa1VVwqkJrXjRvbcqHL+XdIGYWhWNdi4McEvnZg==