From e8ac1f8c22f949bcc9dce8c06c40e154e65d517a Mon Sep 17 00:00:00 2001 From: Nar Cuenca Date: Tue, 14 Feb 2023 14:56:48 +0800 Subject: [PATCH 1/6] task: add system fields switch --- .../src/appRevamp/components/FieldList.tsx | 54 +++++++++++++------ 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/src/apps/schema/src/appRevamp/components/FieldList.tsx b/src/apps/schema/src/appRevamp/components/FieldList.tsx index 97785fd0c0..b3a11c3f91 100644 --- a/src/apps/schema/src/appRevamp/components/FieldList.tsx +++ b/src/apps/schema/src/appRevamp/components/FieldList.tsx @@ -6,6 +6,8 @@ import { InputAdornment, CircularProgress, Typography, + Switch, + FormControlLabel, } from "@mui/material"; import { useParams } from "react-router"; import { isEqual } from "lodash"; @@ -55,6 +57,7 @@ export const FieldList = ({ onNewFieldModalClick }: Props) => { const [deactivatedFields, setDeactivatedFields] = useState< ContentModelField[] | null >(null); + const [isSystemFieldsVisible, setIsSystemFieldsVisible] = useState(false); useEffect(() => { if (fields?.length && !isEqual(localFields, fields)) { @@ -151,21 +154,42 @@ export const FieldList = ({ onNewFieldModalClick }: Props) => { flex={1} sx={{ pr: 3, pt: 2, overflowY: "scroll" }} > - setSearch(event.target.value)} - sx={{ width: "360px", px: 3 }} - InputProps={{ - startAdornment: ( - - - - ), - }} - inputRef={searchRef} - /> + + setSearch(event.target.value)} + sx={{ width: "360px", px: 3 }} + InputProps={{ + startAdornment: ( + + + + ), + }} + inputRef={searchRef} + /> + + Show system fields + + } + control={ + ) => + setIsSystemFieldsVisible(e.target.checked) + } + /> + } + sx={{ + mr: 0, + }} + /> + {/* No search results */} {!Boolean(filteredFields?.length) && search && ( From e984e6fc57e9e5c9630e6b81e5fd4c7b844fc352 Mon Sep 17 00:00:00 2001 From: Nar Cuenca Date: Tue, 14 Feb 2023 15:30:19 +0800 Subject: [PATCH 2/6] task: added basic structure when system fields are enabled --- .../src/appRevamp/components/FieldList.tsx | 94 ++++++++++++++----- 1 file changed, 72 insertions(+), 22 deletions(-) diff --git a/src/apps/schema/src/appRevamp/components/FieldList.tsx b/src/apps/schema/src/appRevamp/components/FieldList.tsx index b3a11c3f91..99c0a74eb1 100644 --- a/src/apps/schema/src/appRevamp/components/FieldList.tsx +++ b/src/apps/schema/src/appRevamp/components/FieldList.tsx @@ -8,6 +8,8 @@ import { Typography, Switch, FormControlLabel, + Link, + Divider, } from "@mui/material"; import { useParams } from "react-router"; import { isEqual } from "lodash"; @@ -150,11 +152,15 @@ export const FieldList = ({ onNewFieldModalClick }: Props) => { display="flex" flexDirection="column" height="100%" - gap={2} flex={1} sx={{ pr: 3, pt: 2, overflowY: "scroll" }} > - + { /> - {/* No search results */} - {!Boolean(filteredFields?.length) && search && ( - - )} + + {/* SYSTEM FIELDS */} + {isSystemFieldsVisible && !search && ( + + + System Fields + + + Each content item (child) of a model in Zesty comes included + with non-editable system fields that represent the state of the + content such as when it was created, updated, and the version. + The value of these fields can be under the{" "} + meta key in the{" "} + + Instances API end point + + . + + + )} - {/* No active or inactive fields in model */} - {!Boolean(filteredFields?.length) && - !Boolean(deactivatedFields?.length) && - !search && ( - onNewFieldModalClick(null)} /> + {/* NO SEARCH RESULTS */} + {!Boolean(filteredFields?.length) && search && ( + )} - - {/* Active fields are present */} + {/* NO ACTIVE OR INACTIVE FIELDS */} + {!Boolean(filteredFields?.length) && + !Boolean(deactivatedFields?.length) && + !search && ( + onNewFieldModalClick(null)} /> + )} + + {/* ACTIVE FIELDS ARE PRESENT */} {Boolean(filteredFields?.length) && ( <> + {isSystemFieldsVisible && ( + + + User Fields + + + These are editable fields that have been added in by a user + of this instance. The value of these fields can be under the + data key in the Instances API end point. + + + )} {filteredFields?.map((field, index) => { return ( @@ -257,7 +305,7 @@ export const FieldList = ({ onNewFieldModalClick }: Props) => { )} - {/* No active fields BUT there are Deactivated fields and not searching */} + {/* NO ACTIVE FIELDS BUT HAS INACTIVE FIELDS */} {!Boolean(filteredFields?.length) && Boolean(deactivatedFields?.length) && !search && ( @@ -268,11 +316,13 @@ export const FieldList = ({ onNewFieldModalClick }: Props) => { )} - {/* Inactive fields are present and not searching */} + {/* INACTIVE FIELDS ARE PRESENT */} {Boolean(deactivatedFields?.length) && !search && ( - Deactivated Fields + + Deactivated Fields + These fields can be re-activated at any time if you'd like to bring them back to the content model. From c6f137625d132a3b4215a3eded1de054adf07021 Mon Sep 17 00:00:00 2001 From: Nar Cuenca Date: Wed, 15 Feb 2023 12:20:41 +0800 Subject: [PATCH 3/6] task: added system fields and made field component support user and system fields --- .../src/appRevamp/components/Field/index.tsx | 194 ++++++++++-------- .../src/appRevamp/components/FieldList.tsx | 15 ++ .../src/appRevamp/components/configs.ts | 44 +++- 3 files changed, 165 insertions(+), 88 deletions(-) diff --git a/src/apps/schema/src/appRevamp/components/Field/index.tsx b/src/apps/schema/src/appRevamp/components/Field/index.tsx index 70d5f99f32..c8a9088f7b 100644 --- a/src/apps/schema/src/appRevamp/components/Field/index.tsx +++ b/src/apps/schema/src/appRevamp/components/Field/index.tsx @@ -27,20 +27,22 @@ import { useDeleteContentModelFieldMutation, useUndeleteContentModelFieldMutation, } from "../../../../../../shell/services/instance"; -import { TYPE_TEXT } from "../configs"; +import { TYPE_TEXT, SystemField } from "../configs"; import { notify } from "../../../../../../shell/store/notifications"; type Params = { id: string; }; interface Props { - field: ContentModelField; + field: ContentModelField | SystemField; index: number; - onReorder: () => void; - setDraggedIndex: (index: number) => void; - setHoveredIndex: (index: number) => void; + onReorder?: () => void; + setDraggedIndex?: (index: number) => void; + setHoveredIndex?: (index: number) => void; disableDrag: boolean; isDeactivated?: boolean; + withDragIcon: boolean; + withMenu: boolean; } export const Field = ({ @@ -51,6 +53,8 @@ export const Field = ({ setHoveredIndex, disableDrag, isDeactivated, + withDragIcon, + withMenu, }: Props) => { const ref = useRef(null); const [isDragging, setIsDragging] = useState(false); @@ -145,7 +149,9 @@ export const Field = ({ e.stopPropagation(); try { - await navigator.clipboard.writeText(field?.ZUID); + const { ZUID } = field as ContentModelField; + + await navigator.clipboard.writeText(ZUID); setIsZuidCopied(true); } catch (error) { @@ -213,17 +219,19 @@ export const Field = ({ gridTemplateColumns="28px 24px minmax(auto, min-content) 90px" alignItems="center" > - setIsDraggable(true)} - onMouseLeave={() => setIsDraggable(false)} - sx={{ cursor: "grab" }} - > - - + {withDragIcon && ( + setIsDraggable(true)} + onMouseLeave={() => setIsDraggable(false)} + sx={{ cursor: "grab" }} + > + + + )} @@ -255,78 +263,90 @@ export const Field = ({ {isFieldNameCopied ? "Copied" : field.name} - - - - setAnchorEl(null)} - anchorEl={anchorEl} - anchorOrigin={{ - vertical: "bottom", - horizontal: "right", - }} - transformOrigin={{ - vertical: "top", - horizontal: "right", - }} - > - history.push(`${location.pathname}/${field.ZUID}`)} - > - - - - Edit Field - - - - {isZuidCopied ? : } - - {isZuidCopied ? "Copied" : "Copy ZUID"} - - {isDeletingField || isUndeletingField ? ( - - - - - {isDeletingField && ( - De-activating Field - )} - {isUndeletingField && ( - Re-activating Field - )} - - ) : ( - { - if (isDeactivated) { - undeleteContentModelField({ - modelZUID, - fieldZUID: field?.ZUID, - }); - } else { - deleteContentModelField({ - modelZUID, - fieldZUID: field?.ZUID, - }); - } + {withMenu && ( + <> + + + + setAnchorEl(null)} + anchorEl={anchorEl} + anchorOrigin={{ + vertical: "bottom", + horizontal: "right", + }} + transformOrigin={{ + vertical: "top", + horizontal: "right", }} > - - {isDeactivated ? ( - - ) : ( - - )} - - - {isDeactivated ? "Re-activate Field" : "De-activate Field"} - - - )} - + { + const { ZUID } = field as ContentModelField; + + history.push(`${location.pathname}/${ZUID}`); + }} + > + + + + Edit Field + + + + {isZuidCopied ? : } + + + {isZuidCopied ? "Copied" : "Copy ZUID"} + + + {isDeletingField || isUndeletingField ? ( + + + + + {isDeletingField && ( + De-activating Field + )} + {isUndeletingField && ( + Re-activating Field + )} + + ) : ( + { + const { ZUID } = field as ContentModelField; + + if (isDeactivated) { + undeleteContentModelField({ + modelZUID, + fieldZUID: ZUID, + }); + } else { + deleteContentModelField({ + modelZUID, + fieldZUID: ZUID, + }); + } + }} + > + + {isDeactivated ? ( + + ) : ( + + )} + + + {isDeactivated ? "Re-activate Field" : "De-activate Field"} + + + )} + + + )} ); diff --git a/src/apps/schema/src/appRevamp/components/FieldList.tsx b/src/apps/schema/src/appRevamp/components/FieldList.tsx index 99c0a74eb1..bed7339b99 100644 --- a/src/apps/schema/src/appRevamp/components/FieldList.tsx +++ b/src/apps/schema/src/appRevamp/components/FieldList.tsx @@ -27,6 +27,7 @@ import { FieldsListRight } from "./FieldsListRight"; import { NoSearchResults } from "./NoSearchResults"; import { ContentModelField } from "../../../../../shell/services/types"; import { FieldEmptyState } from "./FieldEmptyState"; +import { SYSTEM_FIELDS, SystemField } from "./configs"; type Params = { id: string; @@ -225,6 +226,16 @@ export const FieldList = ({ onNewFieldModalClick }: Props) => { . + {SYSTEM_FIELDS.map((field, index) => ( + + ))} )} @@ -279,6 +290,8 @@ export const FieldList = ({ onNewFieldModalClick }: Props) => { setHoveredIndex={setHoveredIndex} onReorder={handleReorder} disableDrag={!!search} + withDragIcon + withMenu /> @@ -339,6 +352,8 @@ export const FieldList = ({ onNewFieldModalClick }: Props) => { onReorder={handleReorder} disableDrag isDeactivated + withDragIcon + withMenu /> ); diff --git a/src/apps/schema/src/appRevamp/components/configs.ts b/src/apps/schema/src/appRevamp/components/configs.ts index 2df0c40cb8..1e2befa5ae 100644 --- a/src/apps/schema/src/appRevamp/components/configs.ts +++ b/src/apps/schema/src/appRevamp/components/configs.ts @@ -1,4 +1,5 @@ import { InputField } from "./AddFieldModal/FieldFormInput"; +import { ContentModelField } from "../../../../../shell/services/types"; interface FieldListData { type: string; @@ -13,6 +14,7 @@ interface FormConfig { details: InputField[]; rules: InputField[]; } +type SystemField = Pick; const FIELD_COPY_CONFIG: { [key: string]: FieldListData[] } = { text: [ { @@ -548,4 +550,44 @@ const FORM_CONFIG: { [key: string]: FormConfig } = { }, }; -export { FieldListData, FIELD_COPY_CONFIG, TYPE_TEXT, FORM_CONFIG }; +const SYSTEM_FIELDS: SystemField[] = [ + { + label: "Item ZUID", + datatype: "uuid", + name: "ZUID", + }, + { + label: "Created At", + datatype: "datetime", + name: "createdAt", + }, + { + label: "Updated At", + datatype: "datetime", + name: "updatedAt", + }, + { + label: "Version", + datatype: "number", + name: "version", + }, + { + label: "Master ZUID", + datatype: "uuid", + name: "masterZUID", + }, + { + label: "Model ZUID", + datatype: "uuid", + name: "contentModelZUID", + }, +]; + +export { + FieldListData, + FIELD_COPY_CONFIG, + TYPE_TEXT, + FORM_CONFIG, + SYSTEM_FIELDS, + SystemField, +}; From eb55ed54fc9e1af82be7bd5455c544295323242e Mon Sep 17 00:00:00 2001 From: Nar Cuenca Date: Wed, 15 Feb 2023 12:30:50 +0800 Subject: [PATCH 4/6] task: layout fix --- .../src/appRevamp/components/Field/index.tsx | 12 ++++++++-- .../src/appRevamp/components/FieldList.tsx | 22 ++++++++++--------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/apps/schema/src/appRevamp/components/Field/index.tsx b/src/apps/schema/src/appRevamp/components/Field/index.tsx index c8a9088f7b..9a1ab1da29 100644 --- a/src/apps/schema/src/appRevamp/components/Field/index.tsx +++ b/src/apps/schema/src/appRevamp/components/Field/index.tsx @@ -187,6 +187,14 @@ export const Field = ({ return { opacity: 1 }; }; + const getGridTemplate = () => { + if (withDragIcon) { + return "28px 24px minmax(auto, min-content) 90px"; + } else { + return "24px minmax(auto, min-content) 90px"; + } + }; + return ( {withDragIcon && ( diff --git a/src/apps/schema/src/appRevamp/components/FieldList.tsx b/src/apps/schema/src/appRevamp/components/FieldList.tsx index bed7339b99..a40fe67448 100644 --- a/src/apps/schema/src/appRevamp/components/FieldList.tsx +++ b/src/apps/schema/src/appRevamp/components/FieldList.tsx @@ -226,16 +226,18 @@ export const FieldList = ({ onNewFieldModalClick }: Props) => { . - {SYSTEM_FIELDS.map((field, index) => ( - - ))} + + {SYSTEM_FIELDS.map((field, index) => ( + + ))} + )} From 393bc0ddc6dde9b73de2efbf9374c4d3f73d8d64 Mon Sep 17 00:00:00 2001 From: Nar Cuenca Date: Wed, 15 Feb 2023 12:50:05 +0800 Subject: [PATCH 5/6] task: updated error --- src/apps/schema/src/appRevamp/components/Field/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/schema/src/appRevamp/components/Field/index.tsx b/src/apps/schema/src/appRevamp/components/Field/index.tsx index 9a1ab1da29..818699a8b6 100644 --- a/src/apps/schema/src/appRevamp/components/Field/index.tsx +++ b/src/apps/schema/src/appRevamp/components/Field/index.tsx @@ -155,7 +155,7 @@ export const Field = ({ setIsZuidCopied(true); } catch (error) { - console.error("Failed to copy ZUID", error); + console.error("Failed to copy field ZUID", error); } }; @@ -167,7 +167,7 @@ export const Field = ({ setIsFieldNameCopied(true); } catch (error) { - console.error("Failed to copy ZUID", error); + console.error("Failed to copy field name", error); } }; From b6cbc84ee50f537a942af036668b3032b33f95d6 Mon Sep 17 00:00:00 2001 From: Nar Cuenca Date: Thu, 16 Feb 2023 08:55:49 +0800 Subject: [PATCH 6/6] task: used withCursorPosition HOC to mutated input fields --- .../components/AddFieldModal/FieldFormInput.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/apps/schema/src/appRevamp/components/AddFieldModal/FieldFormInput.tsx b/src/apps/schema/src/appRevamp/components/AddFieldModal/FieldFormInput.tsx index 04ec84854d..98a80b934a 100644 --- a/src/apps/schema/src/appRevamp/components/AddFieldModal/FieldFormInput.tsx +++ b/src/apps/schema/src/appRevamp/components/AddFieldModal/FieldFormInput.tsx @@ -23,6 +23,9 @@ import { cloneDeep } from "lodash"; import { FormValue } from "./views/FieldForm"; import { FieldSettingsOptions } from "../../../../../../shell/services/types"; import { convertLabelValue } from "../../utils"; +import { withCursorPosition } from "../../../../../../shell/components/withCursorPosition"; + +const TextFieldWithCursorPosition = withCursorPosition(TextField); export type Validation = "length" | "required" | "unique"; export type FieldNames = @@ -129,6 +132,9 @@ export const FieldFormInput = ({ }); }; + const InputTextField = + fieldConfig.name === "name" ? TextFieldWithCursorPosition : TextField; + return ( {fieldConfig.type === "input" && ( @@ -166,7 +172,7 @@ export const FieldFormInput = ({ )} - -