Skip to content

Commit

Permalink
can toggle selected artboard version layer from resource route
Browse files Browse the repository at this point in the history
  • Loading branch information
goodeats committed May 16, 2024
1 parent 4db4b64 commit a8a8a10
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { memo, useCallback } from 'react'
import { type IArtboardVersion } from '#app/models/artboard-version/artboard-version.server'
import { type ILayer } from '#app/models/layer/layer.server'
import { ArtboardVersionLayerToggleSelected } from '#app/routes/resources+/api.v1+/artboard-version.layer.update.selected'
import {
type entityParentTypeEnum,
type entityTypeEnum,
type IEntityParentType,
type IEntitySelectable,
EntityType,
EntityParentType,
} from '#app/schema/entity'
import { type IDashboardPanelSelectEntityStrategy } from '#app/strategies/component/dashboard-panel/select-entity.strategy'

interface ToggleSelectedChildEntityFormProps {
entityType: entityTypeEnum
parentType?: entityParentTypeEnum
entity: IEntitySelectable
parent: IEntityParentType
}

const ArtboardVersionToggleSelectedChildEntityForm = memo(
({ entityType, entity, parent }: ToggleSelectedChildEntityFormProps) => {
switch (entityType) {
case EntityType.LAYER:
return (
<ArtboardVersionLayerToggleSelected
layer={entity as ILayer}
version={parent as IArtboardVersion}
/>
)
default:
console.log('unknown artboard version entity type', entityType)
return null
}
},
)
ArtboardVersionToggleSelectedChildEntityForm.displayName =
'ArtboardVersionToggleSelectedChildEntityForm'

const ToggleSelectedEntityForm = memo(
({
parentType,
entityType,
entity,
parent,
}: ToggleSelectedChildEntityFormProps) => {
switch (parentType) {
case EntityParentType.ARTBOARD_VERSION:
return (
<ArtboardVersionToggleSelectedChildEntityForm
entityType={entityType}
entity={entity}
parent={parent}
/>
)
default:
console.log('unknown parent type', parentType)
return null
}
},
)
ToggleSelectedEntityForm.displayName = 'ToggleSelectedEntityForm'

export const PanelEntityToggleSelectedAction = ({
entity,
parent,
strategyEntitySelect,
}: {
entity: IEntitySelectable
parent: IEntityParentType
strategyEntitySelect: IDashboardPanelSelectEntityStrategy
}) => {
const { entityType, parentType } = strategyEntitySelect

const toggleSelectedEntityForm = useCallback(
() => (
<ToggleSelectedEntityForm
parentType={parentType}
entityType={entityType}
entity={entity}
parent={parent}
/>
),
[parentType, entityType, entity, parent],
)

return toggleSelectedEntityForm()
}
29 changes: 2 additions & 27 deletions app/components/templates/panel/dashboard-entity-panel.actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import {
import { type IDashboardPanelSelectEntityStrategy } from '#app/strategies/component/dashboard-panel/select-entity.strategy'
import { type IDashboardPanelUpdateEntityVisibleStrategy } from '#app/strategies/component/dashboard-panel/update-entity-visible.strategy'
import { SidebarPanelRowActionsContainer } from '..'
import { FormFetcherIcon } from '../form/fetcher/icon'
import { PanelEntityDeleteAction } from './dashboard-entity-panel.actions.delete'
import { PanelEntityToggleSelectedAction } from './dashboard-entity-panel.actions.toggle-selected'
import { PanelEntityToggleVisobleAction } from './dashboard-entity-panel.actions.toggle-visible'

export const PanelEntityRowActions = ({
Expand Down Expand Up @@ -75,7 +75,7 @@ const PanelEntityAction = ({
)
case EntityActionType.SELECT:
return (
<PanelEntitySelectAction
<PanelEntityToggleSelectedAction
entity={entity as IEntitySelectable}
parent={parent}
strategyEntitySelect={
Expand All @@ -87,28 +87,3 @@ const PanelEntityAction = ({
return null
}
}

export const PanelEntitySelectAction = ({
entity,
parent,
strategyEntitySelect,
}: {
entity: IEntitySelectable
parent: IEntityParentType
strategyEntitySelect: IDashboardPanelSelectEntityStrategy
}) => {
const { selected } = entity
return (
<FormFetcherIcon
entityId={entity.id}
parentId={parent.id}
parentTypeId={strategyEntitySelect.parentTypeId}
route={strategyEntitySelect.route}
formId={strategyEntitySelect.formId}
schema={strategyEntitySelect.schema}
icon={selected ? 'crosshair-2' : 'crosshair-1'}
iconText={strategyEntitySelect.iconText}
className={selected ? 'bg-secondary text-secondary-foreground' : ''}
/>
)
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import {
type LoaderFunctionArgs,
json,
type DataFunctionArgs,
} from '@remix-run/node'
import { useForm } from '@conform-to/react'
import { getFieldsetConstraint } from '@conform-to/zod'
import { json, type ActionFunctionArgs } from '@remix-run/node'
import { useFetcher } from '@remix-run/react'
import { AuthenticityTokenInput } from 'remix-utils/csrf/react'
import { redirectBack } from 'remix-utils/redirect-back'
import { useHydrated } from 'remix-utils/use-hydrated'
import { PanelIconButton } from '#app/components/ui/panel-icon-button'
import { type IArtboardVersion } from '#app/models/artboard-version/artboard-version.server'
import { type ILayer } from '#app/models/layer/layer.server'
import { validateArtboardVersionSelectLayerSubmission } from '#app/models/layer-artboard-version/layer-artboard-version.update.server'
import { EntityParentIdType } from '#app/schema/entity'
import { validateNoJS } from '#app/schema/form-data'
import { SelectArtboardVersionLayerSchema } from '#app/schema/layer-artboard-version'
import { artboardVersionLayerSelectService } from '#app/services/artboard/version/layer/select.service'
import { requireUserId } from '#app/utils/auth.server'
import { useIsPending } from '#app/utils/misc'
import { Routes } from '#app/utils/routes.const'

// https://www.epicweb.dev/full-stack-components

export async function loader({ request }: LoaderFunctionArgs) {
await requireUserId(request)
return json({})
}
const route = Routes.RESOURCES.API.V1.ARTBOARD_VERSION.LAYER.UPDATE.SELECTED
const schema = SelectArtboardVersionLayerSchema

export async function action({ request }: DataFunctionArgs) {
export async function action({ request }: ActionFunctionArgs) {
const userId = await requireUserId(request)
const formData = await request.formData()
const noJS = validateNoJS({ formData })
Expand Down Expand Up @@ -49,3 +55,50 @@ export async function action({ request }: DataFunctionArgs) {
},
)
}

export const ArtboardVersionLayerToggleSelected = ({
layer,
version,
}: {
layer: ILayer
version: IArtboardVersion
}) => {
const versionId = version.id
const layerId = layer.id
const isSelected = layer.selected
const icon = isSelected ? 'crosshair-2' : 'crosshair-1'
const iconText = isSelected ? 'Deselect layer' : 'Select layer'
const className = isSelected ? 'bg-primary text-primary-foreground' : ''

const fetcher = useFetcher<typeof action>()
const lastSubmission = fetcher.data?.submission
const isPending = useIsPending()
let isHydrated = useHydrated()
const [form] = useForm({
id: `artboard-version-layer-toggle-selected-${versionId}-new`,
constraint: getFieldsetConstraint(schema),
lastSubmission,
})

return (
<fetcher.Form method="POST" action={route} {...form.props}>
<AuthenticityTokenInput />

<input type="hidden" name="no-js" value={String(!isHydrated)} />
<input type="hidden" name="id" value={layerId} />
<input
type="hidden"
name={EntityParentIdType.ARTBOARD_VERSION_ID}
value={versionId}
/>

<PanelIconButton
type="submit"
iconName={icon}
iconText={iconText}
disabled={isPending}
className={className}
/>
</fetcher.Form>
)
}

0 comments on commit a8a8a10

Please sign in to comment.