2023-05-08 19:28:03 +02:00
|
|
|
// Hooks
|
2023-05-11 19:14:48 +02:00
|
|
|
import { useEffect, useState } from 'react'
|
2023-05-08 19:28:03 +02:00
|
|
|
import { useTranslation } from 'next-i18next'
|
|
|
|
import { useView } from 'shared/hooks/use-view.mjs'
|
|
|
|
import { useAccount } from 'shared/hooks/use-account.mjs'
|
|
|
|
// Dependencies
|
|
|
|
import { pluginTheme } from '@freesewing/plugin-theme'
|
|
|
|
import { pluginI18n } from '@freesewing/plugin-i18n'
|
2023-05-13 14:17:47 +02:00
|
|
|
import { objUpdate } from 'shared/utils.mjs'
|
2023-05-08 19:28:03 +02:00
|
|
|
// Components
|
|
|
|
import { WorkbenchHeader } from './header.mjs'
|
|
|
|
import { ErrorView } from 'shared/components/error/view.mjs'
|
2023-05-31 15:32:54 +02:00
|
|
|
import { ModalSpinner } from 'shared/components/modal/spinner.mjs'
|
2023-05-08 19:28:03 +02:00
|
|
|
// Views
|
2023-05-13 14:17:47 +02:00
|
|
|
import { DraftView, ns as draftNs } from 'shared/components/workbench/views/draft/index.mjs'
|
2023-05-26 15:54:43 +02:00
|
|
|
import { SaveView, ns as saveNs } from 'shared/components/workbench/views/save/index.mjs'
|
2023-06-04 09:59:47 -05:00
|
|
|
import { PrintView, ns as printNs } from 'shared/components/workbench/views/print/index.mjs'
|
2023-06-06 11:17:14 -05:00
|
|
|
import { CutView, ns as cutNs } from 'shared/components/workbench/views/cut/index.mjs'
|
2023-05-08 19:28:03 +02:00
|
|
|
|
2023-06-06 11:17:14 -05:00
|
|
|
export const ns = ['account', 'workbench', ...draftNs, ...saveNs, ...printNs, ...cutNs]
|
2023-05-08 19:28:03 +02:00
|
|
|
|
2023-05-11 19:14:48 +02:00
|
|
|
const defaultUi = {
|
|
|
|
renderer: 'react',
|
|
|
|
}
|
|
|
|
|
2023-06-04 09:59:47 -05:00
|
|
|
const views = {
|
|
|
|
draft: DraftView,
|
|
|
|
print: PrintView,
|
2023-06-06 11:17:14 -05:00
|
|
|
cut: CutView,
|
2023-06-04 09:59:47 -05:00
|
|
|
}
|
|
|
|
|
2023-05-08 19:28:03 +02:00
|
|
|
const draftViews = ['draft', 'test']
|
|
|
|
|
2023-06-04 09:59:47 -05:00
|
|
|
export const Workbench = ({ design, Design, baseSettings, DynamicDocs, from }) => {
|
2023-05-08 19:28:03 +02:00
|
|
|
// Hooks
|
|
|
|
const { t, i18n } = useTranslation(ns)
|
|
|
|
const { language } = i18n
|
2023-05-19 18:27:36 +02:00
|
|
|
const { account } = useAccount()
|
2023-05-08 19:28:03 +02:00
|
|
|
|
|
|
|
// State
|
|
|
|
const [view, setView] = useView()
|
2023-05-31 15:32:54 +02:00
|
|
|
const [settings, setSettings] = useState({ ...baseSettings, embed: true })
|
|
|
|
const [ui, setUi] = useState(defaultUi)
|
2023-05-08 19:28:03 +02:00
|
|
|
const [error, setError] = useState(false)
|
|
|
|
|
2023-05-31 15:32:54 +02:00
|
|
|
// Effect
|
2023-05-08 19:28:03 +02:00
|
|
|
useEffect(() => {
|
2023-05-31 15:32:54 +02:00
|
|
|
// Force re-render when baseSettings changes. Required when they are loaded async.
|
2023-06-03 11:31:40 -05:00
|
|
|
setSettings({ ...baseSettings, embed: true })
|
|
|
|
}, [baseSettings])
|
2023-05-31 15:32:54 +02:00
|
|
|
|
|
|
|
// Helper methods for settings/ui updates
|
|
|
|
const update = {
|
|
|
|
settings: (path, val) => setSettings(objUpdate({ ...settings }, path, val)),
|
|
|
|
ui: (path, val) => setUi(objUpdate({ ...ui }, path, val)),
|
|
|
|
}
|
2023-05-08 19:28:03 +02:00
|
|
|
|
2023-05-31 15:32:54 +02:00
|
|
|
// Don't bother without a Design
|
2023-06-03 21:36:35 +02:00
|
|
|
if (!Design || !baseSettings) return <ModalSpinner />
|
2023-05-08 19:28:03 +02:00
|
|
|
|
|
|
|
// Short-circuit errors early
|
|
|
|
if (error)
|
|
|
|
return (
|
|
|
|
<>
|
2023-05-31 17:56:58 +02:00
|
|
|
<WorkbenchHeader {...{ view, setView, update }} />
|
2023-05-08 19:28:03 +02:00
|
|
|
{error}
|
|
|
|
</>
|
|
|
|
)
|
2023-05-31 17:56:58 +02:00
|
|
|
|
2023-05-26 15:54:43 +02:00
|
|
|
// Deal with each view
|
|
|
|
const viewProps = {
|
|
|
|
account,
|
|
|
|
design,
|
|
|
|
setView,
|
|
|
|
update,
|
|
|
|
settings,
|
|
|
|
ui,
|
|
|
|
language,
|
|
|
|
DynamicDocs,
|
2023-06-05 16:07:16 -05:00
|
|
|
Design,
|
2023-05-13 17:52:34 +02:00
|
|
|
}
|
2023-05-26 15:54:43 +02:00
|
|
|
let viewContent = null
|
|
|
|
|
2023-06-04 09:59:47 -05:00
|
|
|
switch (view) {
|
|
|
|
// Save view
|
|
|
|
case 'save':
|
|
|
|
viewContent = <SaveView {...viewProps} from={from} />
|
|
|
|
break
|
|
|
|
default: {
|
2023-06-04 23:28:43 -05:00
|
|
|
const layout = ui.layouts?.[view] || settings.layout || true
|
2023-06-04 09:59:47 -05:00
|
|
|
// Generate the pattern here so we can pass it down to both the view and the options menu
|
2023-06-04 23:28:43 -05:00
|
|
|
const pattern = settings.measurements !== undefined && new Design({ layout, ...settings })
|
2023-05-26 15:54:43 +02:00
|
|
|
|
2023-06-04 09:59:47 -05:00
|
|
|
// Return early if the pattern is not initialized yet
|
|
|
|
if (typeof pattern.getConfig !== 'function') return null
|
2023-05-26 15:54:43 +02:00
|
|
|
|
2023-06-04 09:59:47 -05:00
|
|
|
const patternConfig = pattern.getConfig()
|
|
|
|
if (ui.renderer === 'svg') {
|
|
|
|
// Add theme to svg renderer
|
|
|
|
pattern.use(pluginI18n, { t })
|
|
|
|
pattern.use(pluginTheme, { skipGrid: ['pages'] })
|
|
|
|
}
|
|
|
|
|
|
|
|
if (draftViews.includes(view)) {
|
|
|
|
// Draft the pattern or die trying
|
|
|
|
try {
|
|
|
|
pattern.draft()
|
|
|
|
} catch (error) {
|
|
|
|
console.log(error)
|
|
|
|
setError(<ErrorView>{JSON.stringify(error)}</ErrorView>)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const View = views[view]
|
2023-06-04 23:28:43 -05:00
|
|
|
viewContent = <View {...{ ...viewProps, pattern, patternConfig }} />
|
2023-05-26 15:54:43 +02:00
|
|
|
}
|
2023-05-08 19:28:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
2023-05-31 17:56:58 +02:00
|
|
|
<WorkbenchHeader {...{ view, setView, update }} />
|
2023-05-26 15:54:43 +02:00
|
|
|
{viewContent}
|
2023-05-08 19:28:03 +02:00
|
|
|
</>
|
|
|
|
)
|
|
|
|
}
|