diff --git a/app/components/templates/form/dialog/index.ts b/app/components/templates/form/dialog/index.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/app/components/templates/navbar/nav-actions.tsx b/app/components/templates/navbar/combobox.tsx similarity index 100% rename from app/components/templates/navbar/nav-actions.tsx rename to app/components/templates/navbar/combobox.tsx diff --git a/app/components/templates/navbar/index.ts b/app/components/templates/navbar/index.ts index 3ecaa839..71094d42 100644 --- a/app/components/templates/navbar/index.ts +++ b/app/components/templates/navbar/index.ts @@ -1 +1 @@ -export * from './nav-actions' +export * from './combobox' diff --git a/app/models/artboard-branch/artboard-branch.get.server.ts b/app/models/artboard-branch/artboard-branch.get.server.ts index 98efd803..6175d548 100644 --- a/app/models/artboard-branch/artboard-branch.get.server.ts +++ b/app/models/artboard-branch/artboard-branch.get.server.ts @@ -58,7 +58,7 @@ export const getArtboardBranchWithVersions = async ({ include: { versions: { orderBy: { - name: 'desc', + createdAt: 'desc', }, }, }, diff --git a/app/routes/sketch+/projects+/$projectSlug_+/artboards+/$artboardSlug+/__components/header.artboard.dialog.form.version.create.tsx b/app/routes/sketch+/projects+/$projectSlug_+/artboards+/$artboardSlug+/__components/header.artboard.dialog.form.version.create.tsx new file mode 100644 index 00000000..cba5e5f6 --- /dev/null +++ b/app/routes/sketch+/projects+/$projectSlug_+/artboards+/$artboardSlug+/__components/header.artboard.dialog.form.version.create.tsx @@ -0,0 +1,126 @@ +import { conform, useForm } from '@conform-to/react' +import { getFieldsetConstraint } from '@conform-to/zod' +import { useFetcher } from '@remix-run/react' +import { useEffect, useState } from 'react' +import { AuthenticityTokenInput } from 'remix-utils/csrf/react' +import { useHydrated } from 'remix-utils/use-hydrated' +import { type z } from 'zod' +import { TextareaField } from '#app/components/forms' +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from '#app/components/ui/dialog' +import { type IconName } from '#app/components/ui/icon' +import { PanelIconButton } from '#app/components/ui/panel-icon-button' +import { StatusButton } from '#app/components/ui/status-button' +import { + type IEntityId, + type IEntityParentId, + type entityParentIdTypeEnum, +} from '#app/schema/entity' +import { useIsPending } from '#app/utils/misc' +import { getActionType, type RoutePath } from '#app/utils/routes.utils' + +// 3 things: +// friendly reminder to change the form id when switching a fetcher.form icon to dialog +// explore not needing actionData on other forms and fetcher is action, not loader +// planning to revisit design system so not as much effort to make dialog dynamic like fetcher forms + +export const DialogFormVersionCreate = ({ + entityId, + parentTypeId, + parentId, + route, + formId, + schema, + icon, + iconText, + title, + description, +}: { + entityId?: IEntityId + parentTypeId?: entityParentIdTypeEnum + parentId?: IEntityParentId + route: RoutePath + formId: string + schema: z.ZodSchema + icon: IconName + iconText: string + title: string + description: string +}) => { + const [open, setOpen] = useState(false) + + const action = getActionType(route) + const fetcher = useFetcher() + const isPending = useIsPending() + let isHydrated = useHydrated() + const [form, fields] = useForm({ + id: `${formId}-${parentId || 'parent'}-${entityId || 'new'}`, + constraint: getFieldsetConstraint(schema), + lastSubmission: fetcher.data?.submission, + defaultValue: { + description: '', + }, + }) + + // close dialog on successful submission + // https://www.nico.fyi/blog/close-dialog-with-use-fetcher-remix + useEffect(() => { + if (fetcher.state === 'idle' && fetcher.data?.status === 'success') { + setOpen(false) + } + }, [fetcher]) + + return ( + + + + + + + {title} + {description} + +
+ + + + + + {parentId && ( + + )} + +
+ +
+
+
+ + + Submit + + +
+
+ ) +} diff --git a/app/routes/sketch+/projects+/$projectSlug_+/artboards+/$artboardSlug+/__components/header.artboard.tsx b/app/routes/sketch+/projects+/$projectSlug_+/artboards+/$artboardSlug+/__components/header.artboard.tsx index a9b774b2..c392df5f 100644 --- a/app/routes/sketch+/projects+/$projectSlug_+/artboards+/$artboardSlug+/__components/header.artboard.tsx +++ b/app/routes/sketch+/projects+/$projectSlug_+/artboards+/$artboardSlug+/__components/header.artboard.tsx @@ -5,7 +5,6 @@ import { NavbarButtonGroup, } from '#app/components/layout' import { ComboboxNav } from '#app/components/templates/combobox' -import { FormFetcherIcon } from '#app/components/templates/form/fetcher/icon' import { IconLink } from '#app/components/templates/link' import { NewArtboardVersionSchema } from '#app/schema/artboard-version' import { EntityParentIdType } from '#app/schema/entity' @@ -16,6 +15,7 @@ import { artboardBranchLoaderRoute } from '../$branchSlug' import { artboardVersionLoaderRoute } from '../$branchSlug.$versionSlug' import { projectLoaderRoute } from '../../route' import { artboardLoaderRoute } from '../route' +import { DialogFormVersionCreate } from './header.artboard.dialog.form.version.create' export const ArtboardHeader = () => { const user = useUser() @@ -58,16 +58,28 @@ export const ArtboardHeader = () => { slugParam="versionSlug" baseUrl={`${baseUrl}/${artboard.slug}/${branch.slug}`} /> - {!onLatestVersion && } + {!onLatestVersion && ( + // this should be displayed when: + // - creating a new artboard version + // - navigating to a previous artboard version + + )} + {/* TODO: make these have the same look as the form fetcher icon */} {/* refresh */} {/* star */} {/* info a, ab, abv */} {/* fork ab */} {/* merge ab */} - { schema={NewArtboardVersionSchema} icon="card-stack-plus" iconText="New Version" + title="Create new version" + description="Save a new version of this artboard. Add a description to help understand the changes. Click save when you're done." /> - {/* TODO: make this have the same look as the form fetcher icon */} { ) } - -// this should be displayed when: -// - creating a new artboard version -// - navigating to a previous artboard version -const LatestArtboardVersionLink = () => { - return ( - - ) -} diff --git a/app/services/artboard/branch/version/create.service.ts b/app/services/artboard/branch/version/create.service.ts index 90c74973..8e031298 100644 --- a/app/services/artboard/branch/version/create.service.ts +++ b/app/services/artboard/branch/version/create.service.ts @@ -52,7 +52,7 @@ export const artboardVersionCreateService = async ({ branchId: artboardBranchId, name: newName, slug: newName, - description: 'new version -- fix me to be the description passed in', + description: description || 'new version', width, height, background, @@ -63,6 +63,7 @@ export const artboardVersionCreateService = async ({ invariant(createdArtboardVersion, 'New artboard version not created') // Step 4: delete all artboard versions after the current artboard version + // getting multiple heads and tails on v1... const artboardVersions = await getArtboardVersions({ where: { branchId: artboardBranchId }, }) diff --git a/app/utils/linked-list.utils.ts b/app/utils/linked-list.utils.ts index 4390ab0f..79ee5362 100644 --- a/app/utils/linked-list.utils.ts +++ b/app/utils/linked-list.utils.ts @@ -11,11 +11,13 @@ export const orderLinkedItems = (items: T[]): T[] => { const heads = items.filter(item => !item.prevId) if (heads.length > 1) { console.warn('Multiple heads found in the linked list.') + console.log('heads', heads) } const tails = items.filter(item => !item.nextId) if (tails.length > 1) { console.warn('Multiple tails found in the linked list.') + console.log('tails', tails) } // Step 1: Find the head of the list