diff --git a/sites/lab/components/header.js b/sites/lab/components/header.js index 704eb5fa79f..1b076045eaa 100644 --- a/sites/lab/components/header.js +++ b/sites/lab/components/header.js @@ -3,7 +3,6 @@ import Link from 'next/link' import ThemePicker from 'shared/components/theme-picker.js' import LocalePicker from 'shared/components/locale-picker.js' import PatternPicker from 'site/components/pattern-picker.js' -import VersionPicker from 'site/components/version-picker.js' import CloseIcon from 'shared/components/icons/close.js' import MenuIcon from 'shared/components/icons/menu.js' @@ -69,7 +68,6 @@ const Header = ({ app }) => {
-
diff --git a/sites/lab/components/layouts/lab.js b/sites/lab/components/layouts/lab.js index 1eba829e582..e269676042c 100644 --- a/sites/lab/components/layouts/lab.js +++ b/sites/lab/components/layouts/lab.js @@ -1,6 +1,5 @@ import ThemePicker from 'shared/components/theme-picker.js' import LocalePicker from 'shared/components/locale-picker.js' -import VersionPicker from 'site/components/version-picker.js' export const BeforeNav = ({ app }) => ( <> @@ -9,7 +8,6 @@ export const BeforeNav = ({ app }) => (
-
) diff --git a/sites/lab/components/version-picker.js b/sites/lab/components/version-picker.js deleted file mode 100644 index 2bc7bca2551..00000000000 --- a/sites/lab/components/version-picker.js +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react' -import VersionsIcon from 'shared/components/icons/versions.js' -import { useTranslation } from 'next-i18next' -import versions from 'site/versions.json' -import useVersion from 'site/hooks/useVersion.js' -import {Picker, PickerLink} from 'shared/components/picker' - -export const defaultVersion = 'next' - -export const formatVersionTitle = version => (!version || version === defaultVersion) - ? `${defaultVersion} version` - : `Version ${version}` - -export const formatVersionUri = (version=false, design=false) => { - if (!version && !design) return '/' - if (!version && design) return `/${design}` - if (version && !design) return `/v/${version}` - - return `/v/${version}/${design}` -} - -const PatternPicker = ({ app }) => { - const { t } = useTranslation(['common']) - const version = useVersion() - - const pickerProps = { - title: formatVersionTitle(version), - Icon: VersionsIcon, - ariaLabel: t('versionPicker') - } - - return ( - {[defaultVersion, ...versions].map(v => ( - {formatVersionTitle(v)} - ))} - ) -} - -export default PatternPicker diff --git a/sites/lab/hooks/useApp.js b/sites/lab/hooks/useApp.js index 0c0c2183c7d..083c615341b 100644 --- a/sites/lab/hooks/useApp.js +++ b/sites/lab/hooks/useApp.js @@ -2,17 +2,15 @@ import { useState } from 'react' // Stores state in local storage import useLocalStorage from 'shared/hooks/useLocalStorage.js' // Designs -import { designsByType } from 'config/software/index.mjs' +import { designsByType } from 'prebuild/designs-by-type.mjs' // Locale and translation import { useRouter } from 'next/router' import { useTranslation } from 'next-i18next' import { capitalize } from 'shared/utils.mjs' -import { formatVersionUri } from '../components/version-picker.js' -import useVersion from 'site/hooks/useVersion.js' import useTheme from 'shared/hooks/useTheme' // Initial navigation -const initialNavigation = (t, version) => { +const initialNavigation = t => { const base = { accessories: { __title: t('accessoryDesigns'), @@ -35,7 +33,7 @@ const initialNavigation = (t, version) => { for (const design in designsByType[type]) { base[type][design] = { __title: capitalize(design), - __slug: formatVersionUri(version,design) + __slug: design } } } @@ -57,9 +55,6 @@ for (const type in designsByType) { function useApp(full = true) { - // Version - const version = useVersion() - // Load translation method const locale = useRouter().locale const { t } = useTranslation(['app']) @@ -70,7 +65,7 @@ function useApp(full = true) { // React State const [primaryMenu, setPrimaryMenu] = useState(false) - const [navigation, setNavigation] = useState(initialNavigation(t, version)) + const [navigation, setNavigation] = useState(initialNavigation(t)) const [slug, setSlug] = useState('/') const [design, setDesign] = useState(false) const [loading, setLoading] = useState(false) diff --git a/sites/lab/hooks/useVersion.js b/sites/lab/hooks/useVersion.js deleted file mode 100644 index 5f8b8069c38..00000000000 --- a/sites/lab/hooks/useVersion.js +++ /dev/null @@ -1,16 +0,0 @@ -import { useRouter } from 'next/router' - -export const defaultVersion = 'next' - -const useVersion = () => { - const { pathname } = useRouter() - const chunks = pathname.split('/') - const version = (chunks[1] === 'v') - ? chunks[2] - : defaultVersion - - return version -} - -export default useVersion - diff --git a/sites/lab/lib/.gitkeep b/sites/lab/lib/.gitkeep deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/sites/lab/next.config.mjs b/sites/lab/next.config.mjs index 0c4b7670ba4..1b7e9521394 100644 --- a/sites/lab/next.config.mjs +++ b/sites/lab/next.config.mjs @@ -1,6 +1,7 @@ import path from 'path' import i18nConfig from './next-i18next.config.js' -import { designs, plugins } from '../../config/software/index.mjs' +import { designs } from './prebuild/designs.mjs' +import { plugins } from './prebuild/plugins.mjs' import { banner } from '../../scripts/banner.mjs' let greeting = false @@ -14,11 +15,11 @@ const config = { webpack: (config, options) => { // JSON support - config.module.rules.push({ - test: /\.json$/, - type: 'json', - use: 'json-loader' - }) + //config.module.rules.push({ + // test: /\.json$/, + // type: 'json', + // use: 'json-loader' + //}) // YAML support config.module.rules.push({ @@ -36,7 +37,7 @@ const config = { // Aliases config.resolve.alias.shared = path.resolve('../shared/') config.resolve.alias.site = path.resolve('.') - config.resolve.alias.lib = path.resolve('./lib') + config.resolve.alias.prebuild = path.resolve('./prebuild') config.resolve.alias.config = path.resolve('../../config/') config.resolve.alias.designs = path.resolve('../../designs/') config.resolve.alias.plugins = path.resolve('../../plugins/') diff --git a/sites/lab/page-templates/design-list.js b/sites/lab/page-templates/design-list.js index 9feecf2ede3..1fc3bbc8e48 100644 --- a/sites/lab/page-templates/design-list.js +++ b/sites/lab/page-templates/design-list.js @@ -2,12 +2,10 @@ import Page from 'site/components/wrappers/page.js' import useApp from 'site/hooks/useApp.js' import Link from 'next/link' import { useTranslation } from 'next-i18next' -import { formatVersionTitle } from 'site/components/version-picker.js' import Layout from 'site/components/layouts/bare' import { PageTitle } from 'shared/components/layouts/default' -import availableVersions from 'site/available-versions.json' -const DesignLinks = ({ list, prefix='', version=false }) => { +const DesignLinks = ({ list, prefix='' }) => { const { t } = useTranslation(['patterns']) return ( @@ -27,7 +25,7 @@ const DesignLinks = ({ list, prefix='', version=false }) => { ) } -const PatternListPageTemplate = ({ section=false, version=false }) => { +const PatternListPageTemplate = ({ section=false }) => { const app = useApp() const { t } = useTranslation(['app']) @@ -35,45 +33,22 @@ const PatternListPageTemplate = ({ section=false, version=false }) => { ? app.navigation[section].__title : t('designs') - const sectionDesigns = (section=false, version=false) => { + const sectionDesigns = (section=false) => { if (!section) { const all = [] - if (!version || version === 'next') { - for (const section in app.designs) all.push(...app.designs[section]) - return all - } - else if (availableVersions[version]) return availableVersions[version] - } else { - if (!version || version === 'next') return app.designs[section] - else if (availableVersions[version]) return availableVersions[version] - } + for (const section in app.designs) all.push(...app.designs[section]) + return all + } else return app.designs[section] return [] } return ( - +
- {version && version !== 'next' - ? ( - - ) - : - } +
diff --git a/sites/shared/components/icons/without-breasts.js b/sites/shared/components/icons/menswear.js similarity index 100% rename from sites/shared/components/icons/without-breasts.js rename to sites/shared/components/icons/menswear.js diff --git a/sites/shared/components/icons/with-breasts.js b/sites/shared/components/icons/womenswear.js similarity index 100% rename from sites/shared/components/icons/with-breasts.js rename to sites/shared/components/icons/womenswear.js diff --git a/sites/shared/components/json.js b/sites/shared/components/json-highlight.js similarity index 100% rename from sites/shared/components/json.js rename to sites/shared/components/json-highlight.js diff --git a/sites/shared/components/workbench/json.js b/sites/shared/components/workbench/gist-as-json.js similarity index 75% rename from sites/shared/components/workbench/json.js rename to sites/shared/components/workbench/gist-as-json.js index ec59bfdf359..c6c5c9ee194 100644 --- a/sites/shared/components/workbench/json.js +++ b/sites/shared/components/workbench/gist-as-json.js @@ -1,4 +1,4 @@ -import Json from 'shared/components/json.js' +import Json from 'shared/components/json-highlight.js' const GistAsJson = props => (
diff --git a/sites/shared/components/workbench/measurements/index.js b/sites/shared/components/workbench/measurements/index.js index 5dcf094aa89..cb92f2945b6 100644 --- a/sites/shared/components/workbench/measurements/index.js +++ b/sites/shared/components/workbench/measurements/index.js @@ -1,33 +1,33 @@ import React, {useMemo, useEffect, useState} from 'react' import MeasurementInput from '../inputs/measurement.js' -import { withBreasts, withoutBreasts } from '@freesewing/models' +import { menswear, womenswear } from '@freesewing/models' import nonHuman from './non-human.js' -import WithBreastsIcon from 'shared/components/icons/with-breasts.js' -import WithoutBreastsIcon from 'shared/components/icons/without-breasts.js' +import WomenswearIcon from 'shared/components/icons/womenswear.js' +import MenswearIcon from 'shared/components/icons/menswear.js' import { useTranslation } from 'next-i18next' import Setting from '../menu/core-settings/setting'; import {settings} from '../menu/core-settings/index'; import { Tab, Tabs } from 'shared/components/mdx/tabs.js' + const groups = { - people: { - with: withBreasts, - without: withoutBreasts, - }, + people: { menswear, womenswear }, dolls: { - with: nonHuman.withBreasts.dolls, - without: nonHuman.withoutBreasts.dolls, + menswear: nonHuman.menswear.dolls, + womenswear: nonHuman.womenswear.dolls, }, giants: { - with: nonHuman.withBreasts.giants, - without: nonHuman.withoutBreasts.giants, + menswear: nonHuman.menswear.giants, + womenswear: nonHuman.womenswear.giants, } } + const icons = { - with: , - without: , + menswear: , + womenswear: , } + const WorkbenchMeasurements = ({ app, design, gist, updateGist, gistReady }) => { const { t } = useTranslation(['app', 'cfp']) @@ -72,7 +72,7 @@ const WorkbenchMeasurements = ({ app, design, gist, updateGist, gistReady }) => {Object.keys(icons).map(type => ( -

{t(`${type}Breasts`)}

+

{t(type)}

    {Object.keys(groups[group][type]).map((m) => (
  • @@ -81,9 +81,8 @@ const WorkbenchMeasurements = ({ app, design, gist, updateGist, gistReady }) => onClick={() => updateMeasurements(groups[group][type][m], false)} > {icons[type]} - {t('size')}  { group === 'people' - ? m.replace('size', '') + ? m.slice(-2) : m } diff --git a/sites/shared/components/workbench/measurements/non-human.js b/sites/shared/components/workbench/measurements/non-human.js index 78fdf30dac9..2b613c68611 100644 --- a/sites/shared/components/workbench/measurements/non-human.js +++ b/sites/shared/components/workbench/measurements/non-human.js @@ -1,11 +1,11 @@ -import { withBreasts, withoutBreasts } from '@freesewing/models' +import { menswear42, womenswear34 } from '@freesewing/models' const nonHuman = { - withoutBreasts: { + menswear: { dolls: {}, giants: {} }, - withBreasts: { + womenswear: { dolls: {}, giants: {} } @@ -14,34 +14,34 @@ const round = val => Math.round(val*10)/10 for (let i=0.1;i<0.7;i+=0.1) { const name = `${Math.round(i*10)}/10` - nonHuman.withBreasts.dolls[name] = {} - // withBreasts: Based on Anneke (size 34) - for (const [m, val] of Object.entries(withBreasts.size34)) { - nonHuman.withBreasts.dolls[name][m] = (m === 'shoulderSlope') + nonHuman.womenswear.dolls[name] = {} + // womenswear: Based on womenswear34 + for (const [m, val] of Object.entries(womenswear34)) { + nonHuman.womenswear.dolls[name][m] = (m === 'shoulderSlope') ? val : round(val * i) } - // withoutBreasts: Based on Ronan (size 42) - nonHuman.withoutBreasts.dolls[name] = {} - for (const [m, val] of Object.entries(withoutBreasts.size42)) { - nonHuman.withoutBreasts.dolls[name][m] = (m === 'shoulderSlope') + nonHuman.menswear.dolls[name] = {} + // menswear: Based on menswear42 + for (const [m, val] of Object.entries(menswear42)) { + nonHuman.menswear.dolls[name][m] = (m === 'shoulderSlope') ? val : round(val * i) } } for (let i=1.5;i<=3;i+=0.5) { const name = `${i}/1` - nonHuman.withBreasts.giants[name] = {} - // withBreasts: Based on Anneke (size 34) - for (const [m, val] of Object.entries(withBreasts.size34)) { - nonHuman.withBreasts.giants[name][m] = (m === 'shoulderSlope') + nonHuman.womenswear.giants[name] = {} + // womenswear: Based on womenswear34 + for (const [m, val] of Object.entries(womenswear34)) { + nonHuman.womenswear.giants[name][m] = (m === 'shoulderSlope') ? val : round(val * i) } - nonHuman.withoutBreasts.giants[name] = {} - // withoutBreasts: Based on Ronan (size 42) - for (const [m, val] of Object.entries(withoutBreasts.size42)) { - nonHuman.withoutBreasts.giants[name][m] = (m === 'shoulderSlope') + nonHuman.menswear.giants[name] = {} + // menswear: Based on menswear42 + for (const [m, val] of Object.entries(menswear42)) { + nonHuman.menswear.giants[name][m] = (m === 'shoulderSlope') ? val : round(val * i) } diff --git a/sites/shared/components/workbench/menu/design-options/index.js b/sites/shared/components/workbench/menu/design-options/index.js index 2a78ebcdd80..a5327236bf3 100644 --- a/sites/shared/components/workbench/menu/design-options/index.js +++ b/sites/shared/components/workbench/menu/design-options/index.js @@ -3,9 +3,11 @@ import { Chevron } from 'shared/components/navigation/primary.js' import OptionGroup from './option-group' import { Ul, Details, TopSummary, TopSumTitle } from 'shared/components/workbench/menu' import { useTranslation } from 'next-i18next' +import { optionsMenuStructure } from 'shared/utils.mjs' const DesignOptions = props => { const { t } = useTranslation(['app']) + const optionsMenu = optionsMenuStructure(props.design.config.options) return (
    @@ -14,12 +16,14 @@ const DesignOptions = props => {
      - {Object.keys(props.design.config.optionGroups).map(group => ( - - ))} + {Object.entries(optionsMenu).map(([group, options]) => typeof options === "string" + ?

      top-level option

      + : + )}
    ) } export default DesignOptions + diff --git a/sites/shared/components/workbench/menu/design-options/option-group.js b/sites/shared/components/workbench/menu/design-options/option-group.js index 71628691f77..64250f266c3 100644 --- a/sites/shared/components/workbench/menu/design-options/option-group.js +++ b/sites/shared/components/workbench/menu/design-options/option-group.js @@ -5,7 +5,7 @@ import { useTranslation } from 'next-i18next' const OptionGroup = props => { const { t } = useTranslation(['optiongroups']) - const config = props.config || props.design.config.optionGroups[props.group] + return (
  • @@ -19,10 +19,10 @@ const OptionGroup = props => {
      - {config.map(option => - typeof option === 'string' ?
  • diff --git a/sites/shared/components/wrappers/workbench.js b/sites/shared/components/wrappers/workbench.js index 40c9f3876b9..87fd614c25f 100644 --- a/sites/shared/components/wrappers/workbench.js +++ b/sites/shared/components/wrappers/workbench.js @@ -12,7 +12,7 @@ import Measurements from 'shared/components/workbench/measurements/index.js' import LabDraft from 'shared/components/workbench/draft/index.js' import LabSample from 'shared/components/workbench/sample.js' import ExportDraft from 'shared/components/workbench/exporting/index.js' -import GistAsJson from 'shared/components/workbench/json.js' +import GistAsJson from 'shared/components/workbench/gist-as-json.js' import GistAsYaml from 'shared/components/workbench/yaml.js' import DraftEvents from 'shared/components/workbench/events.js' import CutLayout from 'shared/components/workbench/layout/cut' diff --git a/sites/shared/prebuild/lab.mjs b/sites/shared/prebuild/lab.mjs index c3b72ae44c2..6c453ec494b 100644 --- a/sites/shared/prebuild/lab.mjs +++ b/sites/shared/prebuild/lab.mjs @@ -1,7 +1,7 @@ import fs_ from 'fs' import path from 'path' import { capitalize } from '../utils.mjs' -import { designsByType } from '../../../config/software/index.mjs' +import { designsByType, plugins, designs } from '../../../config/software/index.mjs' const fs = fs_.promises @@ -43,7 +43,6 @@ export const prebuildLab = async (site) => { // Iterate over sections console.log(`Generating pages for ${section} designs`) for (const design in designsByType[section]) { - // Generate pattern pages for next console.log(` - ${design}`) const page = pageTemplate(design) @@ -62,6 +61,24 @@ export const prebuildLab = async (site) => { } } + // Write designs file + const header = "// This file is auto-generated by the prebuild script | Any changes will be overwritten\n" + const nl = "\n" + promises.push( + fs.writeFile( + path.resolve('..', 'lab', 'prebuild', 'designs.mjs'), + `${header}export const designs = ${JSON.stringify(Object.keys(designs))}${nl}` + ), + fs.writeFile( + path.resolve('..', 'lab', 'prebuild', 'plugins.mjs'), + `${header}export const plugins = ${JSON.stringify(Object.keys(plugins))}${nl}` + ), + fs.writeFile( + path.resolve('..', 'lab', 'prebuild', 'designs-by-type.mjs'), + `${header}export const designsByType = ${JSON.stringify(designsByType)}${nl}` + ), + ) + await Promise.all(promises) } diff --git a/sites/shared/utils.mjs b/sites/shared/utils.mjs index 22a4065eaa9..07c53d86590 100644 --- a/sites/shared/utils.mjs +++ b/sites/shared/utils.mjs @@ -1,4 +1,5 @@ import get from 'lodash.get' +import set from 'lodash.set' // Generic rounding method export const round = (val, decimals=1) => Math.round(val*Math.pow(10, decimals))/Math.pow(10, decimals) @@ -159,3 +160,16 @@ export const measurementAsMm = (value, units = "metric") => { } return false; } + +export const optionsMenuStructure = options => { + if (!options) return options + const menu = {} + for (const [name, option] of Object.entries(options)) { + if (typeof option === 'object') { + set(menu, (option.menu ? `${option.menu}.${name}` : name), optionType(option)) + } + } + + return menu +} +