diff --git a/sites/org/components/layouts/workbench.mjs b/sites/org/components/layouts/workbench.mjs index 19be0b12a78..ef1ac12b2f4 100644 --- a/sites/org/components/layouts/workbench.mjs +++ b/sites/org/components/layouts/workbench.mjs @@ -1,7 +1,7 @@ export const ns = [] export const WorkbenchLayout = (props) => ( -
+
{props.children}
) diff --git a/sites/shared/components/workbench/draft/index.mjs b/sites/shared/components/workbench/draft/index.mjs deleted file mode 100644 index 523473c474d..00000000000 --- a/sites/shared/components/workbench/draft/index.mjs +++ /dev/null @@ -1,62 +0,0 @@ -import { SvgWrapper } from './svg.mjs' -import { DraftError } from './error.mjs' - -export const DraftView = ({ pattern, setView, gist, updateGist }) => { - //const { app, draft, gist, updateGist, unsetGist, showInfo, feedback, hasRequiredMeasurements } = props - - if (!pattern) return null - - // Render as SVG - if (gist?.renderer === 'svg') { - let svg - try { - svg = pattern.render() - } catch (error) { - console.log('Failed to render design', error) - return - } - return
- } - - // Render as React - let patternProps = {} - try { - patternProps = pattern.getRenderProps() - } catch (error) { - console.log('Failed to get render props for design', error) - return ( - - ) - } - - const errors = [] - errors.push(...patternProps.logs.pattern.error) - for (const set of patternProps.logs.sets) { - errors.push(...set.error) - } - - console.log(patternProps) - - return ( - <> - {errors.length > 0 ? ( - - ) : null} - - - ) -} diff --git a/sites/shared/components/workbench/index.mjs b/sites/shared/components/workbench/index.mjs index 1e654c90c79..af891caf9cf 100644 --- a/sites/shared/components/workbench/index.mjs +++ b/sites/shared/components/workbench/index.mjs @@ -1,6 +1,5 @@ // Hooks -import { useEffect, useState, useMemo } from 'react' -import { useGist } from 'shared/hooks/useGist' +import { useEffect, useState } from 'react' import { useTranslation } from 'next-i18next' import { useView } from 'shared/hooks/use-view.mjs' import { useAccount } from 'shared/hooks/use-account.mjs' @@ -8,48 +7,45 @@ import { useBackend } from 'shared/hooks/use-backend.mjs' // Dependencies import { pluginTheme } from '@freesewing/plugin-theme' import { pluginI18n } from '@freesewing/plugin-i18n' -import { preloaders } from 'shared/components/workbench/preloaders.mjs' +//import { preloaders } from 'shared/components/workbench/preloaders.mjs' import _set from 'lodash.set' +import _unset from 'lodash.unset' // Components -import { WorkbenchMenu } from 'shared/components/workbench/menu/index.mjs' -import { DraftError } from 'shared/components/workbench/draft/error.mjs' +//import { DraftError } from 'shared/components/workbench/pattern/error.mjs' import { Modal } from 'shared/components/modal/modal.mjs' import { ErrorBoundary } from 'shared/components/error/error-boundary.mjs' // Views -import { WorkbenchMeasurements } from 'shared/components/workbench/measurements/index.mjs' -import { LabSample } from 'shared/components/workbench/sample.mjs' -import { ExportDraft } from 'shared/components/workbench/exporting/index.mjs' -import { GistAsJson, GistAsYaml } from 'shared/components/workbench/gist.mjs' -import { DraftLogs } from 'shared/components/workbench/logs.mjs' -import { CutLayout } from 'shared/components/workbench/layout/cut/index.mjs' -import { PrintLayout } from 'shared/components/workbench/layout/print/index.mjs' -import { EditYaml } from 'shared/components/workbench/edit/index.mjs' +//import { LabSample } from 'shared/components/workbench/sample.mjs' +//import { ExportDraft } from 'shared/components/workbench/exporting/index.mjs' +//import { GistAsJson, GistAsYaml } from 'shared/components/workbench/gist.mjs' +//import { DraftLogs } from 'shared/components/workbench/logs.mjs' +//import { CutLayout } from 'shared/components/workbench/layout/cut/index.mjs' +//import { PrintLayout } from 'shared/components/workbench/layout/print/index.mjs' +//import { EditYaml } from 'shared/components/workbench/edit/index.mjs' // Components import { WorkbenchHeader } from './header.mjs' import { ErrorView } from 'shared/components/error/view.mjs' // Views -import { DraftView } from 'shared/components/workbench/draft/index.mjs' +import { DraftView } from 'shared/components/workbench/views/draft/index.mjs' export const ns = ['workbench'] const loadDefaultSettings = ({ locale = 'en', units = 'metric' }) => ({ - settings: { - sa: 0, - scale: 1, - complete: true, - paperless: false, - margin: 2, - units, - locale, - embed: true, - }, - renderer: 'react', - //saBool: false, - //saMm: 10, - //debug: true, + sa: 0, + scale: 1, + complete: true, + paperless: false, + margin: 2, + units, + locale, + embed: true, }) +const defaultUi = { + renderer: 'react', +} + const draftViews = ['draft', 'test'] export const Workbench = ({ design, Design, set = false }) => { @@ -59,20 +55,21 @@ export const Workbench = ({ design, Design, set = false }) => { const { account, token } = useAccount() const { backend } = useBackend(token) - const defaults = loadDefaultSettings({ + const defaultSettings = loadDefaultSettings({ units: account.imperial ? 'imperial' : 'metric', locale: language, }) - if (set) defaults.settings.measurements = set.measies + if (set) defaultSettings.measurements = set.measies // State const [view, setView] = useView() - const [gist, setGist] = useState({ ...defaults, embed: true, renderer: 'react' }) + const [settings, setSettings] = useState({ ...defaultSettings, embed: true }) + const [ui, setUi] = useState({ ...defaultUi }) const [error, setError] = useState(false) // Effects useEffect(() => { - if (set.measies) updateGist('settings.measurements', set.measies) + if (set.measies) update.settings('measurements', set.measies) }, [set]) // Don't bother without a set or Design @@ -87,18 +84,34 @@ export const Workbench = ({ design, Design, set = false }) => { ) - // Helper method to update the gist - const updateGist = (path, val) => { - const newGist = { ...gist } - _set(newGist, path, val) - setGist(newGist) + // Helper methods for settings/ui updates + const update = { + settings: (path, val = 'unset') => { + const newSettings = { ...settings } + if (val === 'unset') { + if (Array.isArray(path) && Array.isArray(path[0])) { + for (const item of path) update.settings(...item) + } else _unset(newSettings, path) + } else _set(newSettings, path, val) + setSettings(newSettings) + }, + ui: (path, val = 'unset') => { + const newUi = { ...ui } + if (val === 'unset') { + if (Array.isArray(path) && Array.isArray(path[0])) { + for (const item of path) update.ui(...item) + } else _unset(newUi, path) + } else _set(newUi, path, val) + setUi(newUi) + }, } // Generate the pattern here so we can pass it down to both the view and the options menu - const pattern = draftViews.includes(view) ? new Design(gist.settings) : false + const pattern = draftViews.includes(view) ? new Design(settings) : false + const patternConfig = pattern.getConfig() if (pattern) { // add theme to svg renderer - if (gist.renderer === 'svg') { + if (ui.renderer === 'svg') { pattern.use(pluginI18n, { t }) pattern.use(pluginTheme, { skipGrid: ['pages'] }) } @@ -115,14 +128,15 @@ export const Workbench = ({ design, Design, set = false }) => { return ( <> - {view === 'draft' && } -

view is {view}

- - + {view === 'draft' && ( + + )} +
{JSON.stringify(settings, null, 2)}
+
{JSON.stringify(ui, null, 2)}
) } - +/* const views = { measurements: WorkbenchMeasurements, //draft: LabDraft, @@ -157,7 +171,6 @@ const doPreload = async (preload, from, design, gist, setGist, setPreloaded) => * This component wraps the workbench and is in charge of * keeping the gist state, which will trickle down * to all workbench subcomponents - */ export const WorkbenchWrapper = ({ app, design, @@ -290,3 +303,4 @@ export const WorkbenchWrapper = ({ ) } + */ diff --git a/sites/shared/components/workbench/inputs/design-option-count.mjs b/sites/shared/components/workbench/inputs/design-option-count.mjs deleted file mode 100644 index 9e39d2840e3..00000000000 --- a/sites/shared/components/workbench/inputs/design-option-count.mjs +++ /dev/null @@ -1,106 +0,0 @@ -import { useState } from 'react' -import { ClearIcon, EditIcon } from 'shared/components/icons.mjs' -import { useTranslation } from 'next-i18next' - -const EditCount = (props) => ( -
- - -
-) - -export const DesignOptionCount = (props) => { - const { t } = useTranslation(['app']) - const { count, max, min } = props.design.patternConfig.options[props.option] - const val = - typeof props.gist?.options?.[props.option] === 'undefined' - ? count - : props.gist.options[props.option] - - const [value, setValue] = useState(val) - const [editCount, setEditCount] = useState(false) - - const handleChange = (evt) => { - const newVal = evt.target.value - setValue(newVal) - props.updateGist(['options', props.option], newVal) - } - const reset = () => { - setValue(count) - props.unsetGist(['options', props.option]) - } - - return ( -
-
- {editCount ? ( - - ) : ( - <> - {min} - - {val} - - {max} - - )} -
- -
- -
- - -
-
-
- ) -} diff --git a/sites/shared/components/workbench/inputs/design-option-list.mjs b/sites/shared/components/workbench/inputs/design-option-list.mjs deleted file mode 100644 index 479c2d1770b..00000000000 --- a/sites/shared/components/workbench/inputs/design-option-list.mjs +++ /dev/null @@ -1,70 +0,0 @@ -import { useState } from 'react' -import { ClearIcon } from 'shared/components/icons.mjs' -import { useTranslation } from 'next-i18next' - -export const DesignOptionList = (props) => { - const { t } = useTranslation([`o_${props.design.designConfig.data.name}`]) - const { dflt, list, doNotTranslate = false } = props.design.patternConfig.options[props.option] - const val = - typeof props.gist?.options?.[props.option] === 'undefined' - ? dflt - : props.gist.options[props.option] - - const [value, setValue] = useState(val) - - const handleChange = (newVal) => { - if (newVal === dflt) reset() - else { - setValue(newVal) - props.updateGist(['options', props.option], newVal) - } - } - const reset = () => { - setValue(dflt) - props.unsetGist(['options', props.option]) - } - - return ( -
-
-
- {list.map((choice) => ( - - ))} -
- -
-
- ) -} - -export default DesignOptionList diff --git a/sites/shared/components/workbench/inputs/design-option-pct-deg.mjs b/sites/shared/components/workbench/inputs/design-option-pct-deg.mjs deleted file mode 100644 index 3f28165c995..00000000000 --- a/sites/shared/components/workbench/inputs/design-option-pct-deg.mjs +++ /dev/null @@ -1,136 +0,0 @@ -import { useState } from 'react' -import { ClearIcon, EditIcon } from 'shared/components/icons.mjs' -import { formatMm, round } from 'shared/utils.mjs' -import { useTranslation } from 'next-i18next' - -const EditOption = (props) => ( -
- - -
-) - -export const DesignOptionPctDeg = (props) => { - const { t } = useTranslation(['app']) - const suffix = props.type === 'deg' ? '°' : '%' - const factor = props.type === 'deg' ? 1 : 100 - const { max, min } = props.design.patternConfig.options[props.option] - const dflt = props.design.patternConfig.options[props.option][props.type || 'pct'] - const val = - typeof props.gist?.options?.[props.option] === 'undefined' - ? dflt - : props.gist.options[props.option] * factor - - const [value, setValue] = useState(val) - const [editOption, setEditOption] = useState(false) - - const handleChange = (evt) => { - const newVal = evt.target.value - setValue(newVal) - props.updateGist(['options', props.option], newVal / factor) - } - const reset = () => { - setValue(dflt) - props.unsetGist(['options', props.option]) - } - - return ( -
-

- {props.ot(`${props.option}.d`)} -

-
- {editOption ? ( - - ) : ( - <> - - {round(min)} - {suffix} - - - {round(val)} - {suffix} - - - {round(max)} - {suffix} - - - )} -
- -
- - {props.design.patternConfig.options[props.option]?.toAbs && props.gist.measurements - ? formatMm( - props.design.patternConfig.options[props.option].toAbs(value / 100, props.gist) - ) - : ' '} - -
- - -
-
-
- ) -} diff --git a/sites/shared/components/workbench/inputs/measurement.mjs b/sites/shared/components/workbench/inputs/measurement.mjs deleted file mode 100644 index 88534a8de30..00000000000 --- a/sites/shared/components/workbench/inputs/measurement.mjs +++ /dev/null @@ -1,139 +0,0 @@ -import React, { useState, useEffect, useMemo, useCallback, useRef } from 'react' -import { useTranslation } from 'next-i18next' -import { isDegreeMeasurement } from '../../../config/measurements' -import { measurementAsMm } from 'shared/utils.mjs' - -/* - * This is a single input for a measurements - * Note that it keeps local state with whatever the user types - * but will only trigger a gist update if the input is valid. - * - * m holds the measurement name. It's just so long to type - * measurement and I always have some typo in it because dyslexia. - */ -export const MeasurementInput = ({ m, gist, app, updateMeasurements, focus }) => { - const { t } = useTranslation(['app', 'measurements']) - const prefix = app.site === 'org' ? '' : 'https://freesewing.org' - const title = t(`measurements:${m}`) - - const isDegree = isDegreeMeasurement(m) - const factor = useMemo(() => (isDegree ? 1 : gist.units == 'imperial' ? 25.4 : 10), [gist.units]) - - const isValValid = (val) => - typeof val === 'undefined' || val === '' ? null : val != false && !isNaN(val) - const isValid = (newVal) => (typeof newVal === 'undefined' ? isValValid(val) : isValValid(newVal)) - - const [val, setVal] = useState(gist.measurements?.[m] / factor || '') - - // keep a single reference to a debounce timer - const debounceTimeout = useRef(null) - const input = useRef(null) - - // onChange - const update = useCallback( - (evt) => { - evt.stopPropagation() - let evtVal = evt.target.value - // set Val immediately so that the input reflects it - setVal(evtVal) - - let useVal = isDegree ? evtVal : measurementAsMm(evtVal, gist.units) - const ok = isValid(useVal) - // only set to the gist if it's valid - if (ok) { - // debounce in case it's still changing - if (debounceTimeout.current !== null) { - clearTimeout(debounceTimeout.current) - } - debounceTimeout.current = setTimeout(() => { - // clear the timeout reference - debounceTimeout.current = null - updateMeasurements(useVal, m) - }, 500) - } - }, - [gist.units] - ) - - // use this for better update efficiency - const memoVal = useMemo(() => gist.measurements?.[m], [gist]) - // track validity against the value and the units - const valid = useMemo( - () => isValid(isDegree ? val : measurementAsMm(val, gist.units)), - [val, gist.units] - ) - - // hook to update the value or format when the gist changes - useEffect(() => { - // set the value to the proper value and format - if (memoVal) { - let gistVal = +(memoVal / factor).toFixed(2) - setVal(gistVal) - } - }, [memoVal, factor]) - - // focus when prompted by parent - useEffect(() => { - if (focus) { - input.current.focus() - } - }, [focus]) - - // cleanup - useEffect(() => { - clearTimeout(debounceTimeout.current) - }, []) - - if (!m) return null - - return ( -
- - -
- ) -} diff --git a/sites/shared/components/workbench/layout/draft/index.mjs b/sites/shared/components/workbench/layout/draft/index.mjs index abbdef9af38..bf0a16356d0 100644 --- a/sites/shared/components/workbench/layout/draft/index.mjs +++ b/sites/shared/components/workbench/layout/draft/index.mjs @@ -1,7 +1,7 @@ import { useRef } from 'react' import { Stack } from './stack.mjs' -import { SvgWrapper } from '../../draft/svg.mjs' -import { PartInner } from '../../draft/part.mjs' +import { SvgWrapper } from '../../pattern/svg.mjs' +import { PartInner } from '../../pattern/part.mjs' import get from 'lodash.get' export const Draft = (props) => { diff --git a/sites/shared/components/workbench/layout/draft/stack.mjs b/sites/shared/components/workbench/layout/draft/stack.mjs index d5b3469d98b..eab940310f9 100644 --- a/sites/shared/components/workbench/layout/draft/stack.mjs +++ b/sites/shared/components/workbench/layout/draft/stack.mjs @@ -45,8 +45,8 @@ */ import { useRef, useState, useEffect } from 'react' import { generateStackTransform } from '@freesewing/core' -import { Part } from '../../draft/part.mjs' -import { getProps, angle } from '../../draft/utils.mjs' +import { Part } from '../../pattern/part.mjs' +import { getProps, angle } from '../../pattern/utils.mjs' import { drag } from 'd3-drag' import { select } from 'd3-selection' import { Buttons } from './buttons.mjs' diff --git a/sites/shared/components/workbench/measurements/index.mjs b/sites/shared/components/workbench/measurements/index.mjs deleted file mode 100644 index 2ff7260c079..00000000000 --- a/sites/shared/components/workbench/measurements/index.mjs +++ /dev/null @@ -1,113 +0,0 @@ -import React, { useMemo, useEffect, useState } from 'react' -import { MeasurementInput } from '../inputs/measurement.mjs' -import { adult, doll, giant } from '@freesewing/models' -import { - CisFemaleIcon as WomenswearIcon, - CisMaleIcon as MenswearIcon, -} from 'shared/components/icons.mjs' -import { useTranslation } from 'next-i18next' -import { Setting } from '../menu/core-settings/setting.mjs' -import { settings } from '../menu/core-settings/index.mjs' -import { Tab, Tabs } from 'shared/components/mdx/tabs.mjs' - -const groups = { adult, doll, giant } - -const icons = { - cisFemale: , - cisMale: , -} - -export const WorkbenchMeasurements = ({ app, design, gist, updateGist, gistReady }) => { - const { t } = useTranslation(['app', 'cfp']) - - // Method to handle measurement updates - const updateMeasurements = (value, m = false) => { - if (m === false) { - // Set all measurements - updateGist('measurements', value) - } else { - // Set one measurement - updateGist(['measurements', m], value) - } - } - - const [firstInvalid, setFirstInvalid] = useState(undefined) - - useEffect(() => { - if (!gistReady) { - return - } - for (const m of design.patternConfig?.measurements || []) { - if (!gist?.measurements?.[m]) { - setFirstInvalid(m) - return - } - - setFirstInvalid(undefined) - } - }, [gistReady]) - - // Save us some typing - const inputProps = useMemo(() => ({ app, updateMeasurements, gist }), [app, gist]) - const shortname = design.designConfig.data.name.replace('@freesewing/', '') - - return ( -
-

- {shortname}: {t('measurements')} -

-

{t('cfp:preloadMeasurements')}

- - {Object.keys(groups).map((group) => ( - - {Object.keys(icons).map((type) => ( - -

{t(type)}

-
    - {Object.keys(groups[group][type]).map((m) => ( -
  • - -
  • - ))} -
-
- ))} -
- ))} -
- -

{t('cfp:enterMeasurements')}

-
- -
- {design.patternConfig.measurements.length > 0 && ( - <> -

{t('requiredMeasurements')}

- {design.patternConfig.measurements.map((m) => ( - - ))} - - )} - {design.patternConfig.optionalMeasurements.length > 0 && ( - <> -

{t('optionalMeasurements')}

- {design.patternConfig.optionalMeasurements.map((m) => ( - - ))} - - )} -
- ) -} diff --git a/sites/shared/components/workbench/menu/core-settings/core-setting-bool.mjs b/sites/shared/components/workbench/menu/core-settings/core-setting-bool.mjs deleted file mode 100644 index 9f1ba50361c..00000000000 --- a/sites/shared/components/workbench/menu/core-settings/core-setting-bool.mjs +++ /dev/null @@ -1,25 +0,0 @@ -import { useState } from 'react' -import { useTranslation } from 'next-i18next' -import { SecText, SumButton, Li, SumDiv, Deg } from 'shared/components/workbench/menu/index.mjs' - -export const CoreSettingBool = (props) => { - const { t } = useTranslation(['app']) - const [value, setValue] = useState(props.gist[props.setting]) - - const toggle = () => { - props.updateGist([props.setting], !value) - setValue(!value) - } - - return ( -
  • - - - - {t(`settings:${props.setting}.t`)} - - {t(value ? 'yes' : 'no')} - -
  • - ) -} diff --git a/sites/shared/components/workbench/menu/core-settings/core-setting-list.mjs b/sites/shared/components/workbench/menu/core-settings/core-setting-list.mjs deleted file mode 100644 index b2a894929dd..00000000000 --- a/sites/shared/components/workbench/menu/core-settings/core-setting-list.mjs +++ /dev/null @@ -1,49 +0,0 @@ -import { useState } from 'react' -import { useTranslation } from 'next-i18next' -import { Deg } from 'shared/components/workbench/menu/index.mjs' - -export const CoreSettingList = (props) => { - const { t } = useTranslation(['settings']) - const { dflt } = props - const val = props.gist?.[props.setting] - - const [value, setValue] = useState(val) - - const handleChange = (newVal) => { - if (newVal === dflt) reset() - else { - setValue(newVal) - props.updateGist([props.setting], newVal) - } - } - - const reset = () => { - setValue(props.dflt) - props.updateGist([props.setting], props.dflt) - } - - return ( -
    -

    - {t(`settings:${props.setting}.d`)} -

    -
    -
    - {props.list.map((entry) => ( - - ))} -
    -
    -
    - ) -} diff --git a/sites/shared/components/workbench/menu/core-settings/core-setting-mm.mjs b/sites/shared/components/workbench/menu/core-settings/core-setting-mm.mjs deleted file mode 100644 index e181aeb1397..00000000000 --- a/sites/shared/components/workbench/menu/core-settings/core-setting-mm.mjs +++ /dev/null @@ -1,71 +0,0 @@ -import { useState } from 'react' -import { useTranslation } from 'next-i18next' -import { formatMm } from 'shared/utils.mjs' -import { ClearIcon } from 'shared/components/icons.mjs' - -export const CoreSettingMm = (props) => { - const { t } = useTranslation(['app', 'settings']) - const { dflt, min, max } = props - const val = props.gist?.[props.setting] - - const [value, setValue] = useState(val) - - const handleChange = (evt) => { - const newVal = parseFloat(evt.target.value) - - if (newVal === dflt) reset() - else { - setValue(newVal) - props.updateGist([props.setting], newVal) - } - } - const reset = () => { - setValue(props.dflt) - props.updateGist([props.setting], props.dflt) - } - - return ( -
    -

    - {t(`settings:${props.setting}.d`)} -

    -
    - - - -
    - -
    - - -
    -
    - ) -} diff --git a/sites/shared/components/workbench/menu/core-settings/core-setting-nr.mjs b/sites/shared/components/workbench/menu/core-settings/core-setting-nr.mjs deleted file mode 100644 index 310735858d9..00000000000 --- a/sites/shared/components/workbench/menu/core-settings/core-setting-nr.mjs +++ /dev/null @@ -1,63 +0,0 @@ -import { useState } from 'react' -import { ClearIcon } from 'shared/components/icons.mjs' -import { useTranslation } from 'next-i18next' - -export const CoreSettingNr = (props) => { - const { t } = useTranslation(['app', 'settings']) - const { dflt, min, max } = props - const val = props.gist?.[props.setting] - - const [value, setValue] = useState(val) - - const handleChange = (evt) => { - const newVal = parseFloat(evt.target.value) - - if (newVal === dflt) reset() - else { - setValue(newVal) - props.updateGist([props.setting], newVal) - } - } - const reset = () => { - setValue(props.dflt) - props.updateGist([props.setting], props.dflt) - } - - return ( -
    -

    - {t(`settings:${props.setting}.d`)} -

    -
    - {min} - - {val} - - {max} -
    - -
    - - -
    -
    - ) -} diff --git a/sites/shared/components/workbench/menu/core-settings/core-setting-only.mjs b/sites/shared/components/workbench/menu/core-settings/core-setting-only.mjs deleted file mode 100644 index b73877950ed..00000000000 --- a/sites/shared/components/workbench/menu/core-settings/core-setting-only.mjs +++ /dev/null @@ -1,68 +0,0 @@ -import { ClearIcon } from 'shared/components/icons.mjs' -import orderBy from 'lodash.orderby' -import { useTranslation } from 'next-i18next' - -export const CoreSettingOnly = (props) => { - const { t } = useTranslation(['app', 'parts', 'settings']) - const list = props.design.patternConfig.draftOrder - const partNames = list.map((part) => ({ id: part, name: t(`parts:${part}`) })) - - const togglePart = (part) => { - const parts = props.gist.only || [] - const newParts = new Set(parts) - if (newParts.has(part)) newParts.delete(part) - else newParts.add(part) - if (newParts.size < 1) reset() - else props.updateGist(['only'], [...newParts]) - } - - const reset = () => { - props.unsetGist(['only']) - } - - return ( -
    -

    - {t(`settings:only.d`)} -

    -
    -
    - {orderBy(partNames, ['name'], ['asc']).map((part) => ( - - ))} -
    -
    -
    - -
    -
    - ) -} diff --git a/sites/shared/components/workbench/menu/core-settings/core-setting-sa-bool.mjs b/sites/shared/components/workbench/menu/core-settings/core-setting-sa-bool.mjs deleted file mode 100644 index 460aae7eef6..00000000000 --- a/sites/shared/components/workbench/menu/core-settings/core-setting-sa-bool.mjs +++ /dev/null @@ -1,29 +0,0 @@ -import { useState } from 'react' -import { useTranslation } from 'next-i18next' -import { SecText, SumButton, Li, SumDiv, Deg } from 'shared/components/workbench/menu/index.mjs' - -export const CoreSettingSaBool = (props) => { - const { t } = useTranslation(['app', 'settings']) - const [value, setValue] = useState(props.gist.saBool || false) - - const toggle = () => { - props.setGist({ - ...props.gist, - saBool: !value, - sa: value ? 0 : props.gist.saMm, - }) - setValue(!value) - } - - return ( -
  • - - - - {t('settings:sabool.t')} - - {t(value ? 'yes' : 'no')} - -
  • - ) -} diff --git a/sites/shared/components/workbench/menu/design-options/index.mjs b/sites/shared/components/workbench/menu/design-options/index.mjs deleted file mode 100644 index 7a2422d0235..00000000000 --- a/sites/shared/components/workbench/menu/design-options/index.mjs +++ /dev/null @@ -1,31 +0,0 @@ -import { OptionsIcon } from 'shared/components/icons.mjs' -import { Chevron } from 'shared/components/navigation/primary.mjs' -import { OptionGroup } from './option-group.mjs' -import { OptionComponent } from './option.mjs' -import { Ul, Details, TopSummary, TopSumTitle } from 'shared/components/workbench/menu/index.mjs' -import { useTranslation } from 'next-i18next' -import { optionsMenuStructure } from 'shared/utils.mjs' - -export const DesignOptions = (props) => { - const { t } = useTranslation(['app']) - const Option = props.Option ? props.Option : OptionComponent - const optionsMenu = optionsMenuStructure(props.design.patternConfig.options) - - return ( -
    - }> - {t('designOptions')} - - -
      - {Object.entries(optionsMenu).map(([group, options]) => - typeof options === 'string' ? ( -
    -
    - ) -} diff --git a/sites/shared/components/workbench/menu/design-options/option-group.mjs b/sites/shared/components/workbench/menu/design-options/option-group.mjs deleted file mode 100644 index 2d9e265361c..00000000000 --- a/sites/shared/components/workbench/menu/design-options/option-group.mjs +++ /dev/null @@ -1,31 +0,0 @@ -import { Chevron } from 'shared/components/navigation/primary.mjs' -import { Li, Ul, Details, Summary, SumDiv, Deg } from 'shared/components/workbench/menu/index.mjs' -import { useTranslation } from 'next-i18next' - -export const OptionGroup = (props) => { - const { t } = useTranslation(['optiongroups']) - const Option = props.Option - - return ( -
  • -
    - - - - {t(props.group)} - - - -
      - {Object.entries(props.options).map(([option, type]) => - typeof type === 'string' ? ( -
    -
    -
  • - ) -} diff --git a/sites/shared/components/workbench/menu/design-options/option-input.mjs b/sites/shared/components/workbench/menu/design-options/option-input.mjs deleted file mode 100644 index 3568eb1f1a2..00000000000 --- a/sites/shared/components/workbench/menu/design-options/option-input.mjs +++ /dev/null @@ -1,19 +0,0 @@ -import { DesignOptionPctDeg } from 'shared/components/workbench/inputs/design-option-pct-deg.mjs' -import { DesignOptionCount } from 'shared/components/workbench/inputs/design-option-count.mjs' -import { DesignOptionList } from 'shared/components/workbench/inputs/design-option-list.mjs' -import { Popout } from 'shared/components/popout.mjs' - -export const Tmp = () =>

    not yet

    - -export const inputs = { - Pct: DesignOptionPctDeg, - Count: DesignOptionCount, - Deg: (props) => , - List: DesignOptionList, - Mm: () => ( - - Mm options are deprecated. Please report this - - ), - Constant: Tmp, -} diff --git a/sites/shared/components/workbench/menu/design-options/option-value.mjs b/sites/shared/components/workbench/menu/design-options/option-value.mjs deleted file mode 100644 index 9db435f559f..00000000000 --- a/sites/shared/components/workbench/menu/design-options/option-value.mjs +++ /dev/null @@ -1,78 +0,0 @@ -import { useTranslation } from 'next-i18next' -import { formatMm, formatPercentage } from 'shared/utils.mjs' - -export const values = { - Pct: (props) => { - const val = - typeof props.gist?.options?.[props.option] === 'undefined' - ? props.design.patternConfig.options[props.option].pct / 100 - : props.gist.options[props.option] - return ( - - {formatPercentage(val)} - {props.design.patternConfig.options[props.option]?.toAbs && props.gist.measurements - ? ' | ' + - formatMm(props.design.patternConfig.options[props.option]?.toAbs(val, props.gist)) - : null} - - ) - }, - Bool: (props) => { - const { t } = useTranslation(['app']) - const dflt = props.design.patternConfig.options[props.option].bool - let current = props.gist?.options?.[props.option] - current = current === undefined ? dflt : current - return ( - - {current ? t('yes') : t('no')} - - ) - }, - Count: (props) => { - const dflt = props.design.patternConfig.options[props.option].count - const current = props.gist?.options?.[props.option] - return dflt == current || typeof current === 'undefined' ? ( - {dflt} - ) : ( - {current} - ) - }, - List: (props) => { - const dflt = props.design.patternConfig.options[props.option].dflt - const current = props.gist?.options?.[props.option] - const prefix = `${props.option}.o.` - const translate = props.design.patternConfig.options[props.option]?.doNotTranslate - ? (input) => input - : (input) => props.t(prefix + input) - return dflt == current || typeof current === 'undefined' ? ( - {translate(dflt)} - ) : ( - {translate(current)} - ) - }, - Deg: (props) => { - const dflt = props.design.patternConfig.options[props.option].deg - const current = props.gist?.options?.[props.option] - return dflt == current || typeof current === 'undefined' ? ( - {dflt}° - ) : ( - {current}° - ) - }, - Mm: () => { - return

    No mm val yet

    - }, - Constant: () => { - return

    No constant val yet

    - }, -} diff --git a/sites/shared/components/workbench/menu/design-options/option.mjs b/sites/shared/components/workbench/menu/design-options/option.mjs deleted file mode 100644 index 85a07553c90..00000000000 --- a/sites/shared/components/workbench/menu/design-options/option.mjs +++ /dev/null @@ -1,67 +0,0 @@ -import { Chevron } from 'shared/components/navigation/primary.mjs' -import { optionType } from 'shared/utils.mjs' -import { - Li, - Details, - Summary, - SumButton, - SumDiv, - Deg, -} from 'shared/components/workbench/menu/index.mjs' -import { useTranslation } from 'next-i18next' -import { values } from 'shared/components/workbench/menu/design-options/option-value.mjs' -import { inputs } from 'shared/components/workbench/menu/design-options/option-input.mjs' -import { capitalize } from 'shared/utils.mjs' - -export const OptionComponent = (props) => { - const { t } = useTranslation([`o_${props.design.designConfig.data.name}`]) - const opt = props.design.patternConfig.options[props.option] - const type = optionType(opt) - const Input = inputs[capitalize(type)] - const Value = values[capitalize(type)] - - try { - const hide = opt.hide && opt.hide(props.gist) - - if (hide) return null - } catch (e) { - console.warn(`error occurred in hide method for ${props.option}, so we'll just show it`, e) - } - - if (type === 'bool') { - const toggleBoolean = () => { - const dflt = opt.bool - const current = props.gist?.options?.[props.option] - const newVal = typeof current === 'undefined' ? !dflt : !current - props.updateGist(['options', props.option], newVal) - } - - return ( -
  • - - - - {t(`${props.option}.t`)} - - - -
  • - ) - } - - return ( -
  • -
    - - - - {t(`${props.option}.t`)} - - - - - -
    -
  • - ) -} diff --git a/sites/shared/components/workbench/menu/view.mjs b/sites/shared/components/workbench/menu/view.mjs deleted file mode 100644 index a6e49b666e1..00000000000 --- a/sites/shared/components/workbench/menu/view.mjs +++ /dev/null @@ -1,128 +0,0 @@ -import { MenuIcon } from 'shared/components/icons.mjs' -import { linkClasses, Chevron } from 'shared/components/navigation/primary.mjs' -import { useTranslation } from 'next-i18next' -import { defaultGist } from 'shared/hooks/useGist.mjs' - -export const ViewMenu = (props) => { - const { t } = useTranslation(['app']) - const entries = [ - { - name: 'measurements', - title: t('measurements'), - onClick: () => props.updateGist(['_state', 'view'], 'measurements', true), - }, - { - name: 'draft', - title: t('draftDesign', { design: props.design.designConfig.data.name }), - onClick: () => props.updateGist(['_state', 'view'], 'draft', true), - }, - { - name: 'test', - title: t('testDesign', { design: props.design.designConfig.data.name }), - onClick: () => props.updateGist(['_state', 'view'], 'test', true), - }, - { - name: 'printingLayout', - title: - t('layoutThing', { thing: props.design.designConfig.data.name }) + ': ' + t('forPrinting'), - onClick: () => props.updateGist(['_state', 'view'], 'printingLayout', true), - }, - { - name: 'cuttingLayout', - title: - t('layoutThing', { thing: props.design.designConfig.data.name }) + ': ' + t('forCutting'), - onClick: () => props.updateGist(['_state', 'view'], 'cuttingLayout', true), - }, - { - name: 'export', - title: t('exportThing', { thing: props.design.designConfig.data.name }), - onClick: () => props.updateGist(['_state', 'view'], 'export', true), - }, - { - name: 'logs', - title: t('logs'), - onClick: () => props.updateGist(['_state', 'view'], 'logs', true), - }, - { - name: 'yaml', - title: t('YAML'), - onClick: () => props.updateGist(['_state', 'view'], 'yaml', true), - }, - { - name: 'json', - title: t('JSON'), - onClick: () => props.updateGist(['_state', 'view'], 'json', true), - }, - { - name: 'edit', - title: t('editThing', { thing: 'YAML' }), - onClick: () => props.updateGist(['_state', 'view'], 'edit', true), - }, - { - name: 'clear', - title: t('clearThing', { thing: 'YAML' }), - onClick: () => props.setGist(defaultGist(props.design, props.gist.locale)), - }, - ] - - return ( -
    - - - - - {t('view')} - - -
      - {entries.map((entry) => ( -
    • - -
    • - ))} -
    -
    - ) -} diff --git a/sites/shared/components/workbench/menu/core-settings/core-setting-sa-mm.mjs b/sites/shared/components/workbench/menus/core-settings/core-setting-sa-mm.mjs similarity index 100% rename from sites/shared/components/workbench/menu/core-settings/core-setting-sa-mm.mjs rename to sites/shared/components/workbench/menus/core-settings/core-setting-sa-mm.mjs diff --git a/sites/shared/components/workbench/menu/core-settings/index.mjs b/sites/shared/components/workbench/menus/core-settings/index.mjs similarity index 83% rename from sites/shared/components/workbench/menu/core-settings/index.mjs rename to sites/shared/components/workbench/menus/core-settings/index.mjs index aaf2be91183..5f23024fba0 100644 --- a/sites/shared/components/workbench/menu/core-settings/index.mjs +++ b/sites/shared/components/workbench/menus/core-settings/index.mjs @@ -48,7 +48,8 @@ export const settings = { }, } -export const CoreSettings = (props) => { +export const CoreSettings = ({ design, update, settings }) => { + // FIXME: Update this namespace const { t } = useTranslation(['app']) return ( @@ -58,8 +59,8 @@ export const CoreSettings = (props) => {
      - {Object.keys(settings).map((setting) => ( - + {Object.keys(settings).map((name) => ( + ))}
    diff --git a/sites/shared/components/workbench/menu/core-settings/setting.mjs b/sites/shared/components/workbench/menus/core-settings/setting.mjs similarity index 83% rename from sites/shared/components/workbench/menu/core-settings/setting.mjs rename to sites/shared/components/workbench/menus/core-settings/setting.mjs index 491642573fa..67fa5d04a85 100644 --- a/sites/shared/components/workbench/menu/core-settings/setting.mjs +++ b/sites/shared/components/workbench/menus/core-settings/setting.mjs @@ -1,12 +1,13 @@ import { Chevron } from 'shared/components/navigation/primary.mjs' -import { CoreSettingList as ListSetting } from './core-setting-list.mjs' -import { CoreSettingOnly as OnlySetting } from './core-setting-only.mjs' -import { CoreSettingMm as MmSetting } from './core-setting-mm.mjs' -import { CoreSettingNr as NrSetting } from './core-setting-nr.mjs' -import { CoreSettingBool as BoolSetting } from './core-setting-bool.mjs' -import { CoreSettingSaBool as SaBoolSetting } from './core-setting-sa-bool.mjs' -import { CoreSettingSaMm as SaMmSetting } from './core-setting-sa-mm.mjs' -import { formatMm } from 'shared/utils.mjs' +import { + ListSetting, + OnlySetting, + MmSetting, + NrSetting, + BoolSetting, + SaBoolSetting, + SaMmSetting, +} from './settings.mjs' import { SecText, Li, @@ -14,7 +15,7 @@ import { Summary, SumDiv, Deg, -} from 'shared/components/workbench/menu/index.mjs' +} from 'shared/components/workbench/menus/index.mjs' import { useTranslation } from 'next-i18next' const settings = { diff --git a/sites/shared/components/workbench/menus/core-settings/settings.mjs b/sites/shared/components/workbench/menus/core-settings/settings.mjs new file mode 100644 index 00000000000..9cc92368e53 --- /dev/null +++ b/sites/shared/components/workbench/menus/core-settings/settings.mjs @@ -0,0 +1,354 @@ +import { useState } from 'react' +import { useTranslation } from 'next-i18next' +import { SecText, SumButton, Li, SumDiv, Deg } from 'shared/components/workbench/menus/index.mjs' +import { formatMm } from 'shared/utils.mjs' +import { ClearIcon } from 'shared/components/icons.mjs' +import orderBy from 'lodash.orderby' + +export const BoolSetting = ({ gist, updateGist, setting }) => { + const { t } = useTranslation(['app']) + const [value, setValue] = useState(gist[setting]) + + const toggle = () => { + updateGist(['settings', setting], !value) + setValue(!value) + } + + return ( +
  • + + + + {t(`settings:${setting}.t`)} + + {t(value ? 'yes' : 'no')} + +
  • + ) +} + +export const ListSetting = ({ gist, updateGist, dflt, setting, list }) => { + const { t } = useTranslation(['settings']) + const val = gist.settings?.[setting] + + const [value, setValue] = useState(val) + + const handleChange = (newVal) => { + if (newVal === dflt) reset() + else { + setValue(newVal) + updateGist(['settings', setting], newVal) + } + } + + const reset = () => { + setValue(dflt) + updateGist(['settings', setting], dflt) + } + + return ( +
    +

    + {t(`settings:${setting}.d`)} +

    +
    +
    + {list.map((entry) => ( + + ))} +
    +
    +
    + ) +} + +export const MmSetting = (props) => { + const { t } = useTranslation(['app', 'settings']) + const { dflt, min, max } = props + const val = props.gist?.[props.setting] + + const [value, setValue] = useState(val) + + const handleChange = (evt) => { + const newVal = parseFloat(evt.target.value) + + if (newVal === dflt) reset() + else { + setValue(newVal) + props.updateGist([props.setting], newVal) + } + } + const reset = () => { + setValue(props.dflt) + props.updateGist([props.setting], props.dflt) + } + + return ( +
    +

    + {t(`settings:${props.setting}.d`)} +

    +
    + + + +
    + +
    + + +
    +
    + ) +} + +export const NrSetting = ({ gist, updateGist, dflt, setting, min = 0, max = 1 }) => { + const { t } = useTranslation(['app', 'settings']) + const val = gist.settings?.[setting] + + const [value, setValue] = useState(val) + + const handleChange = (evt) => { + const newVal = parseFloat(evt.target.value) + + if (newVal === dflt) reset() + else { + setValue(newVal) + updateGist(['settings', setting], newVal) + } + } + const reset = () => { + setValue(dflt) + updateGist(['settings', setting], dflt) + } + + return ( +
    +

    + {t(`settings:${setting}.d`)} +

    +
    + {min} + + {val} + + {max} +
    + +
    + + +
    +
    + ) +} + +export const OnlySetting = (props) => { + const { t } = useTranslation(['app', 'parts', 'settings']) + const list = props.patternConfig.draftOrder + const partNames = list.map((part) => ({ id: part, name: t(`parts:${part}`) })) + + const togglePart = (part) => { + const parts = props.gist.only || [] + const newParts = new Set(parts) + if (newParts.has(part)) newParts.delete(part) + else newParts.add(part) + if (newParts.size < 1) reset() + else props.updateGist(['only'], [...newParts]) + } + + const reset = () => { + props.unsetGist(['only']) + } + + return ( +
    +

    + {t(`settings:only.d`)} +

    +
    +
    + {orderBy(partNames, ['name'], ['asc']).map((part) => ( + + ))} +
    +
    +
    + +
    +
    + ) +} + +export const SaBoolSetting = ({ gist, updateGist }) => { + const { t } = useTranslation(['app', 'settings']) + const [value, setValue] = useState(gist.saBool || false) + + const toggle = () => { + setValue(!value) + updateGist([['saBool', !value][(['settings', 'sa'], value ? 0 : gist.saMm)]]) + } + + return ( +
  • + + + + {t('settings:sabool.t')} + + {t(value ? 'yes' : 'no')} + +
  • + ) +} + +export const SaMmSetting = (props) => { + const { t } = useTranslation(['app', 'settings']) + const { dflt, min, max } = props + const val = props.gist?.[props.setting] + + const [value, setValue] = useState(val) + + const handleChange = (evt) => { + const newVal = parseFloat(evt.target.value) + + setValue(newVal) + if (props.gist.saBool) + props.setGist({ + ...props.gist, + saMm: newVal, + sa: newVal, + }) + else props.updateGist(['saMm'], newVal) + } + const reset = () => { + setValue(dflt) + props.updateGist(['saMm'], dflt) + } + + return ( +
    +

    {t(`settings:sa.d`)}

    +
    + + + +
    + +
    + + +
    +
    + ) +} diff --git a/sites/shared/components/workbench/menus/design-options/index.mjs b/sites/shared/components/workbench/menus/design-options/index.mjs new file mode 100644 index 00000000000..53c187ed95c --- /dev/null +++ b/sites/shared/components/workbench/menus/design-options/index.mjs @@ -0,0 +1,180 @@ +import { OptionsIcon } from 'shared/components/icons.mjs' +import { Chevron } from 'shared/components/navigation/primary.mjs' +import { + Li, + Ul, + Details, + Summary, + SumDiv, + SumButton, + Deg, + TopSummary, + TopSumTitle, +} from 'shared/components/workbench/menus/index.mjs' +import { useTranslation } from 'next-i18next' +import { optionsMenuStructure } from 'shared/utils.mjs' +import { optionType } from 'shared/utils.mjs' +import { + ConstantOptionInput, + CountOptionInput, + DegOptionInput, + ListOptionInput, + MmOptionInput, + PctOptionInput, +} from './inputs.mjs' +import { + BoolOptionValue, + ConstantOptionValue, + CountOptionValue, + DegOptionValue, + ListOptionValue, + MmOptionValue, + PctOptionValue, +} from './values.mjs' + +// Facilitate lookup of the input component +const inputs = { + constant: ConstantOptionInput, + count: CountOptionInput, + deg: DegOptionInput, + list: ListOptionInput, + mm: MmOptionInput, + pct: PctOptionInput, +} + +// Facilitate lookup of the value component +const values = { + bool: BoolOptionValue, + constant: ConstantOptionValue, + count: CountOptionValue, + deg: DegOptionValue, + list: ListOptionValue, + mm: MmOptionValue, + pct: PctOptionValue, +} + +export const DesignOption = ({ design, name, current, config, settings, update, t }) => { + const type = optionType(config) + const Input = inputs[type] + const Value = values[type] + + // Hide option? + if (config?.hide || (typeof config?.hide === 'function' && config.hide(settings))) return null + + if (type === 'bool') { + const toggleBoolean = () => { + const dflt = config.bool + const current = settings.options?.[name] + const newVal = typeof current === 'undefined' ? !dflt : !current + update.settings(['options', name], newVal) + } + + return ( +
  • + + + + {t(`${name}.t`)} + + + +
  • + ) + } + + return ( +
  • +
    + + + + {t(`${name}.t`)} + + + + + +
    +
  • + ) +} + +export const DesignOptionGroup = ({ + design, + patternConfig, + settings, + update, + group, + options, + Option, + t, +}) => ( +
  • +
    + + + + {t(group)} + + + +
      + {Object.entries(options).map(([option, type]) => + typeof type === 'string' ? ( +
    +
    +
  • +) + +export const DesignOptions = ({ design, patternConfig, settings, update, Option = false }) => { + const { t } = useTranslation(['optiongroups', design]) + + // FIXME: Do we still care about passing in an Option component? + if (!Option) Option = DesignOption + const optionsMenu = optionsMenuStructure(patternConfig.options) + + return ( +
    + }> + {t('designOptions')} + + +
      + {Object.entries(optionsMenu).map(([group, option]) => + typeof option === 'string' ? ( +
    +
    + ) +} diff --git a/sites/shared/components/workbench/menus/design-options/inputs.mjs b/sites/shared/components/workbench/menus/design-options/inputs.mjs new file mode 100644 index 00000000000..226b5fdd8c2 --- /dev/null +++ b/sites/shared/components/workbench/menus/design-options/inputs.mjs @@ -0,0 +1,269 @@ +import { useState } from 'react' +import { ClearIcon, EditIcon } from 'shared/components/icons.mjs' +import { useTranslation } from 'next-i18next' +import { formatMm, round } from 'shared/utils.mjs' + +const EditCount = (props) => ( +
    + + +
    +) + +export const CountOptionInput = ({ name, config, current, update, t }) => { + const { count, max, min } = config + if (typeof current === 'undefined') current = count + + const [value, setValue] = useState(current) + const [editCount, setEditCount] = useState(false) + + const handleChange = (evt) => { + const newCurrent = evt.target.value + setValue(newCurrent) + update.settings(['options', name], newCurrent) + } + const reset = () => { + setValue(count) + update.settings(['options', name]) + } + + return ( +
    +
    + {editCount ? ( + + ) : ( + <> + {min} + + {current} + + {max} + + )} +
    + +
    + +
    + + +
    +
    +
    + ) +} + +export const ListOptionInput = ({ design, name, config, current, update, t }) => { + const { dflt, list, doNotTranslate = false } = config + if (typeof current === 'undefined') current = dflt + + const [value, setValue] = useState(current) + + const handleChange = (newCurrent) => { + if (newCurrent === dflt) reset() + else { + setValue(newCurrent) + update.settings(['options', name], newCurrent) + } + } + const reset = () => { + setValue(dflt) + update.settings(['options', name]) + } + + return ( +
    +
    +
    + {list.map((choice) => ( + + ))} +
    + +
    +
    + ) +} + +const EditOption = (props) => ( +
    + + +
    +) + +export const PctOptionInput = ({ name, config, settings, current, update, t, type = 'pct' }) => { + const suffix = type === 'deg' ? '°' : '%' + const factor = type === 'deg' ? 1 : 100 + const { max, min } = config + const dflt = config[type] + if (typeof current === 'undefined') current = dflt + else current = current * factor + + const [value, setValue] = useState(current) + const [editOption, setEditOption] = useState(false) + + const handleChange = (evt) => { + const newCurrent = evt.target.value + setValue(newCurrent) + update.settings(['options', name], newCurrent / factor) + } + const reset = () => { + setValue(dflt) + update.settings(['options', name]) + } + + return ( +
    +

    {t(`${name}.d`)}

    +
    + {editOption ? ( + + ) : ( + <> + + {round(min)} + {suffix} + + + {round(current)} + {suffix} + + + {round(max)} + {suffix} + + + )} +
    + +
    + + {config.toAbs && settings.measurements + ? formatMm(config.toAbs(value / 100, settings)) + : ' '} + +
    + + +
    +
    +
    + ) +} + +export const DegOptionInput = (props) => +export const MmOptionInput = () => ( + FIXME: Mm options are deprecated. Please report this +) +export const ConstantOptionInput = () =>

    FIXME: Constant options are not implemented (yet)

    diff --git a/sites/shared/components/workbench/menus/design-options/values.mjs b/sites/shared/components/workbench/menus/design-options/values.mjs new file mode 100644 index 00000000000..9821e0cb0c5 --- /dev/null +++ b/sites/shared/components/workbench/menus/design-options/values.mjs @@ -0,0 +1,59 @@ +import { formatMm, formatPercentage } from 'shared/utils.mjs' + +export const PctOptionValue = ({ name, config, current, settings }) => { + const val = typeof current === 'undefined' ? config.pct / 100 : current + + return ( + + {formatPercentage(val)} + {config?.toAbs && settings.measurements + ? ` | ${formatMm(config.toAbs(val, settings))}` + : null} + + ) +} + +export const BoolOptionValue = ({ name, config, current, t }) => { + const dflt = config.bool + current = current === undefined ? dflt : current + return ( + + {current ? t('yes') : t('no')} + + ) +} + +export const CountOptionValue = ({ name, config, current }) => + config.count == current || typeof current === 'undefined' ? ( + {config.count} + ) : ( + {current} + ) + +export const ListOptionValue = ({ name, config, current, t }) => { + const translate = config.doNotTranslate ? (input) => input : (input) => t(`${option}.o.${input}`) + + return config.dflt == current || typeof current === 'undefined' ? ( + {translate(config.dflt)} + ) : ( + {translate(current)} + ) +} + +export const DegOptionValue = ({ name, config, current }) => + config.deg == current || typeof current === 'undefined' ? ( + {config.deg}° + ) : ( + {current}° + ) + +export const MmOptionValue = () => ( + FIXME: No MmOptionvalue implemented +) +export const ConstantOptionValue = () => ( + FIXME: No ConstantOptionvalue implemented +) diff --git a/sites/shared/components/workbench/menu/index.mjs b/sites/shared/components/workbench/menus/index.mjs similarity index 75% rename from sites/shared/components/workbench/menu/index.mjs rename to sites/shared/components/workbench/menus/index.mjs index 21b0f83b49e..28965bb8e91 100644 --- a/sites/shared/components/workbench/menu/index.mjs +++ b/sites/shared/components/workbench/menus/index.mjs @@ -1,5 +1,4 @@ import { linkClasses } from 'shared/components/navigation/primary.mjs' -import { ViewMenu } from './view.mjs' import { DesignOptions } from './design-options/index.mjs' import { CoreSettings } from './core-settings/index.mjs' import { XrayMenu } from './xray/index.mjs' @@ -7,7 +6,9 @@ import { TestDesignOptions } from './test-design-options/index.mjs' export const Ul = (props) =>
      {props.children}
    export const Li = (props) => ( -
  • {props.children}
  • +
  • + {props.children} +
  • ) export const Details = (props) => (
    @@ -22,7 +23,7 @@ export const NoSumDiv = (props) => ( className={` grow px-2 ml-2 border-l-2 ${linkClasses} - hover:cursor-resize + hover:cursor-pointer hover:border-secondary sm:hover:border-secondary-focus text-base-content sm:text-base-content @@ -36,7 +37,7 @@ export const SumDiv = (props) => ( className={` grow pl-2 border-l-2 ${linkClasses} - hover:cursor-resize + hover:cursor-pointer hover:border-secondary sm:hover:border-secondary-focus text-base-content sm:text-base-content @@ -52,7 +53,7 @@ export const Summary = (props) => ( px-2 text-base-content sm:text-base-content - hover:cursor-row-resize + hover:cursor-pointer items-center `} > @@ -63,7 +64,7 @@ export const TopSummary = (props) => ( ( ) export const TopSumTitle = (props) => ( - + {props.children} ) @@ -104,18 +105,22 @@ export const SecText = (props) => {props.children} ) -export const WorkbenchMenu = (props) => { +export const DraftMenu = (props) => { + const { design, patternConfig, settings, ui, update, Option = false } = props + return ( + ) +} + +export const TestMenu = (props) => { + return ( + ) } diff --git a/sites/shared/components/workbench/menu/test-design-options/index.mjs b/sites/shared/components/workbench/menus/test-design-options/index.mjs similarity index 96% rename from sites/shared/components/workbench/menu/test-design-options/index.mjs rename to sites/shared/components/workbench/menus/test-design-options/index.mjs index 769d2eaea73..8e7ad55104c 100644 --- a/sites/shared/components/workbench/menu/test-design-options/index.mjs +++ b/sites/shared/components/workbench/menus/test-design-options/index.mjs @@ -1,8 +1,8 @@ import { OptionsIcon } from 'shared/components/icons.mjs' import { Chevron } from 'shared/components/navigation/primary.mjs' -import { OptionGroup } from '../design-options/option-group.mjs' +import { DesignOptionGroup } from '../design-options/index.mjs' import { Option } from './option.mjs' -import { Ul, Details, TopSummary, TopSumTitle } from 'shared/components/workbench/menu/index.mjs' +import { Ul, Details, TopSummary, TopSumTitle } from 'shared/components/workbench/menus/index.mjs' import { useTranslation } from 'next-i18next' import { optionsMenuStructure } from 'shared/utils.mjs' import { adult, doll, giant } from '@freesewing/models' @@ -48,7 +48,7 @@ export const TestDesignOptions = (props) => { sampleSettings={{ type: 'option', options }} /> ) : ( - { const active = props.sampleSettings?.type === 'option' && props.active === props.option diff --git a/sites/shared/components/workbench/menu/xray/attributes.mjs b/sites/shared/components/workbench/menus/xray/attributes.mjs similarity index 90% rename from sites/shared/components/workbench/menu/xray/attributes.mjs rename to sites/shared/components/workbench/menus/xray/attributes.mjs index 0126811cfb3..c7494ba6f40 100644 --- a/sites/shared/components/workbench/menu/xray/attributes.mjs +++ b/sites/shared/components/workbench/menus/xray/attributes.mjs @@ -1,5 +1,13 @@ import { Chevron } from 'shared/components/navigation/primary' -import { Ul, Li, Details, Summary, SumDiv, NoSumDiv, Deg } from 'shared/components/workbench/menu' +import { + Ul, + Li, + Details, + Summary, + SumDiv, + NoSumDiv, + Deg, +} from 'shared/components/workbench/menus/index.mjs' export const XrayAttributes = ({ attr = false, t }) => { if (!attr || !attr.list || Object.keys(attr.list).length < 1) return null diff --git a/sites/shared/components/workbench/menu/xray/disable.mjs b/sites/shared/components/workbench/menus/xray/disable.mjs similarity index 95% rename from sites/shared/components/workbench/menu/xray/disable.mjs rename to sites/shared/components/workbench/menus/xray/disable.mjs index 6cd41fed00d..0c29a9a4678 100644 --- a/sites/shared/components/workbench/menu/xray/disable.mjs +++ b/sites/shared/components/workbench/menus/xray/disable.mjs @@ -1,4 +1,4 @@ -import { Li, SumButton, SumDiv, Deg } from 'shared/components/workbench/menu' +import { Li, SumButton, SumDiv, Deg } from 'shared/components/workbench/menus/index.mjs' import { useTranslation } from 'next-i18next' export const XrayDisable = (props) => { diff --git a/sites/shared/components/workbench/menu/xray/index.mjs b/sites/shared/components/workbench/menus/xray/index.mjs similarity index 98% rename from sites/shared/components/workbench/menu/xray/index.mjs rename to sites/shared/components/workbench/menus/xray/index.mjs index 2e7c49e0ec1..627e3fe3a3f 100644 --- a/sites/shared/components/workbench/menu/xray/index.mjs +++ b/sites/shared/components/workbench/menus/xray/index.mjs @@ -4,7 +4,7 @@ import { ConsoleLog } from './log.mjs' import { XrayReset } from './reset.mjs' import { XrayDisable } from './disable.mjs' import { XrayList } from './list.mjs' -import { Ul, Details, TopSummary } from 'shared/components/workbench/menu' +import { Ul, Details, TopSummary } from 'shared/components/workbench/menus/index.mjs' import { useTranslation } from 'next-i18next' export const XrayMenu = (props) => { diff --git a/sites/shared/components/workbench/menu/xray/list.mjs b/sites/shared/components/workbench/menus/xray/list.mjs similarity index 99% rename from sites/shared/components/workbench/menu/xray/list.mjs rename to sites/shared/components/workbench/menus/xray/list.mjs index 1b7a87781fb..8a87a93f980 100644 --- a/sites/shared/components/workbench/menu/xray/list.mjs +++ b/sites/shared/components/workbench/menus/xray/list.mjs @@ -1,6 +1,6 @@ import { Chevron } from 'shared/components/navigation/primary.mjs' import { ClearIcon, FilterIcon, SearchIcon } from 'shared/components/icons.mjs' -import { Ul, Li, Details, Summary, SumDiv, Deg } from 'shared/components/workbench/menu/index.mjs' +import { Ul, Li, Details, Summary, SumDiv, Deg } from 'shared/components/workbench/menus/index.mjs' import { XrayPath } from './path.mjs' import { XrayPoint } from './point.mjs' import { useTranslation } from 'next-i18next' diff --git a/sites/shared/components/workbench/menu/xray/log.mjs b/sites/shared/components/workbench/menus/xray/log.mjs similarity index 95% rename from sites/shared/components/workbench/menu/xray/log.mjs rename to sites/shared/components/workbench/menus/xray/log.mjs index 6574181b186..123eda8a98a 100644 --- a/sites/shared/components/workbench/menu/xray/log.mjs +++ b/sites/shared/components/workbench/menus/xray/log.mjs @@ -7,7 +7,7 @@ import { SumButton, SumDiv, Deg, -} from 'shared/components/workbench/menu/index.mjs' +} from 'shared/components/workbench/menus/index.mjs' export const ConsoleLog = (props) => (
  • diff --git a/sites/shared/components/workbench/menu/xray/path-ops.mjs b/sites/shared/components/workbench/menus/xray/path-ops.mjs similarity index 92% rename from sites/shared/components/workbench/menu/xray/path-ops.mjs rename to sites/shared/components/workbench/menus/xray/path-ops.mjs index 622e606ba06..1939fe68a11 100644 --- a/sites/shared/components/workbench/menu/xray/path-ops.mjs +++ b/sites/shared/components/workbench/menus/xray/path-ops.mjs @@ -1,5 +1,13 @@ import { Chevron } from 'shared/components/navigation/primary' -import { Ul, Li, Details, Summary, SumDiv, NoSumDiv, Deg } from 'shared/components/workbench/menu' +import { + Ul, + Li, + Details, + Summary, + SumDiv, + NoSumDiv, + Deg, +} from 'shared/components/workbench/menus/index.mjs' import { XrayPoint } from './point' const MoveLine = ({ op }) => diff --git a/sites/shared/components/workbench/menu/xray/path.mjs b/sites/shared/components/workbench/menus/xray/path.mjs similarity index 97% rename from sites/shared/components/workbench/menu/xray/path.mjs rename to sites/shared/components/workbench/menus/xray/path.mjs index 036e5c6c112..f0b837ef052 100644 --- a/sites/shared/components/workbench/menu/xray/path.mjs +++ b/sites/shared/components/workbench/menus/xray/path.mjs @@ -1,4 +1,4 @@ -import { Ul, Li, NoSumDiv, Deg } from 'shared/components/workbench/menu/index.mjs' +import { Ul, Li, NoSumDiv, Deg } from 'shared/components/workbench/menus/index.mjs' import { formatMm } from 'shared/utils.mjs' import { XrayAttributes } from './attributes.mjs' import { XrayPathOps } from './path-ops.mjs' diff --git a/sites/shared/components/workbench/menu/xray/point.mjs b/sites/shared/components/workbench/menus/xray/point.mjs similarity index 96% rename from sites/shared/components/workbench/menu/xray/point.mjs rename to sites/shared/components/workbench/menus/xray/point.mjs index 826edab39b6..50b76cd6722 100644 --- a/sites/shared/components/workbench/menu/xray/point.mjs +++ b/sites/shared/components/workbench/menus/xray/point.mjs @@ -1,4 +1,4 @@ -import { Ul, Li, NoSumDiv, Deg } from 'shared/components/workbench/menu' +import { Ul, Li, NoSumDiv, Deg } from 'shared/components/workbench/menus/index.mjs' import { round } from 'shared/utils' import { XrayAttributes } from './attributes' diff --git a/sites/shared/components/workbench/menu/xray/reset.mjs b/sites/shared/components/workbench/menus/xray/reset.mjs similarity index 94% rename from sites/shared/components/workbench/menu/xray/reset.mjs rename to sites/shared/components/workbench/menus/xray/reset.mjs index 8167f0faea4..c0971e13b81 100644 --- a/sites/shared/components/workbench/menu/xray/reset.mjs +++ b/sites/shared/components/workbench/menus/xray/reset.mjs @@ -1,4 +1,4 @@ -import { Li, SumButton, SumDiv, Deg } from 'shared/components/workbench/menu' +import { Li, SumButton, SumDiv, Deg } from 'shared/components/workbench/menus/index.mjs' import { useTranslation } from 'next-i18next' export const XrayReset = (props) => { diff --git a/sites/shared/components/workbench/draft/circle.mjs b/sites/shared/components/workbench/pattern/circle.mjs similarity index 100% rename from sites/shared/components/workbench/draft/circle.mjs rename to sites/shared/components/workbench/pattern/circle.mjs diff --git a/sites/shared/components/workbench/draft/defs.mjs b/sites/shared/components/workbench/pattern/defs.mjs similarity index 100% rename from sites/shared/components/workbench/draft/defs.mjs rename to sites/shared/components/workbench/pattern/defs.mjs diff --git a/sites/shared/components/workbench/draft/error.mjs b/sites/shared/components/workbench/pattern/error.mjs similarity index 100% rename from sites/shared/components/workbench/draft/error.mjs rename to sites/shared/components/workbench/pattern/error.mjs diff --git a/sites/shared/components/workbench/pattern/index.mjs b/sites/shared/components/workbench/pattern/index.mjs new file mode 100644 index 00000000000..8b4e480c425 --- /dev/null +++ b/sites/shared/components/workbench/pattern/index.mjs @@ -0,0 +1,12 @@ +import { SvgWrapper } from './svg.mjs' + +export const Pattern = ({ pattern, setView, settings, ui, update }) => { + if (!pattern) return null + + // Render as SVG + return ui.renderer === 'svg' ? ( +
    + ) : ( + + ) +} diff --git a/sites/shared/components/workbench/draft/part.mjs b/sites/shared/components/workbench/pattern/part.mjs similarity index 100% rename from sites/shared/components/workbench/draft/part.mjs rename to sites/shared/components/workbench/pattern/part.mjs diff --git a/sites/shared/components/workbench/draft/path.mjs b/sites/shared/components/workbench/pattern/path.mjs similarity index 100% rename from sites/shared/components/workbench/draft/path.mjs rename to sites/shared/components/workbench/pattern/path.mjs diff --git a/sites/shared/components/workbench/draft/point.mjs b/sites/shared/components/workbench/pattern/point.mjs similarity index 100% rename from sites/shared/components/workbench/draft/point.mjs rename to sites/shared/components/workbench/pattern/point.mjs diff --git a/sites/shared/components/workbench/draft/snippet.mjs b/sites/shared/components/workbench/pattern/snippet.mjs similarity index 100% rename from sites/shared/components/workbench/draft/snippet.mjs rename to sites/shared/components/workbench/pattern/snippet.mjs diff --git a/sites/shared/components/workbench/draft/stack.mjs b/sites/shared/components/workbench/pattern/stack.mjs similarity index 100% rename from sites/shared/components/workbench/draft/stack.mjs rename to sites/shared/components/workbench/pattern/stack.mjs diff --git a/sites/shared/components/workbench/draft/svg.mjs b/sites/shared/components/workbench/pattern/svg.mjs similarity index 96% rename from sites/shared/components/workbench/draft/svg.mjs rename to sites/shared/components/workbench/pattern/svg.mjs index c8ed027e66c..10e8795acf2 100644 --- a/sites/shared/components/workbench/draft/svg.mjs +++ b/sites/shared/components/workbench/pattern/svg.mjs @@ -74,7 +74,7 @@ export const SvgWrapper = forwardRef((props, ref) => { if (!patternProps) return null return ( - + {({ size }) => ( { wheel={{ activationKeys: ['Control'] }} > -
    +
    +
    + +
    +
    + +
    +
    +) diff --git a/sites/shared/components/workbench/views/draft/menu.mjs b/sites/shared/components/workbench/views/draft/menu.mjs new file mode 100644 index 00000000000..217acca96a0 --- /dev/null +++ b/sites/shared/components/workbench/views/draft/menu.mjs @@ -0,0 +1,11 @@ +import { DesignOptions } from 'shared/components/workbench/menus/design-options/index.mjs' +import { CoreSettings } from 'shared/components/workbench/menus/core-settings/index.mjs' +import { XrayMenu } from 'shared/components/workbench/menus/xray/index.mjs' + +export const DraftMenu = ({ design, pattern, patternConfig, settings, ui, update }) => ( + +) diff --git a/sites/shared/components/wrappers/swipes.mjs b/sites/shared/components/wrappers/swipes.mjs index 30cb39c805c..f2168b75487 100644 --- a/sites/shared/components/wrappers/swipes.mjs +++ b/sites/shared/components/wrappers/swipes.mjs @@ -20,7 +20,8 @@ export const SwipeWrapper = ({ children, app }) => { onSwipedRight: (evt) => { // Only process the first swipe event evt.event.stopPropagation() - setModal() + // FIXME: Make this not be such a PITA + //setModal() }, trackMouse: true, })