feat(lab): Added language setting
This commit is contained in:
parent
91ddfd4580
commit
19f9be6a3c
7 changed files with 284 additions and 11 deletions
|
@ -141,6 +141,7 @@ function useApp(full = true) {
|
|||
|
||||
// Translation
|
||||
t,
|
||||
languages: Object.keys(strings),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
const defaultSettings = {
|
||||
sa: 0,
|
||||
complete: true,
|
||||
paperless: false,
|
||||
units: 'metric',
|
||||
locale: 'en',
|
||||
margin: 2,
|
||||
debug: true,
|
||||
}
|
||||
|
||||
export default defaultSettings
|
|
@ -0,0 +1,48 @@
|
|||
import { useState } from 'react'
|
||||
|
||||
const CoreSettingList = props => {
|
||||
const { dflt, list } = props
|
||||
const val = props.gist?.settings?.[props.setting]
|
||||
|
||||
const [value, setValue] = useState(val)
|
||||
|
||||
const handleChange = (newVal) => {
|
||||
if (newVal === dflt) reset()
|
||||
else {
|
||||
setValue(newVal)
|
||||
props.updateGist(['settings', props.setting], newVal)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="py-4 mx-6 border-l-2 pl-2">
|
||||
<p className="m-0 p-0 px-2 mb-2 text-neutral-content opacity-60 italic">
|
||||
{props.app.t(`settings.${props.setting}.description`)}
|
||||
</p>
|
||||
<div className="flex flex-row">
|
||||
<div className="grow">
|
||||
{props.list.map(entry => (
|
||||
<button
|
||||
key={entry.key}
|
||||
onClick={() => handleChange(entry.key)}
|
||||
className={`
|
||||
mr-1 mb-1 text-left text-lg w-full hover:text-secondary-focus px-2
|
||||
${entry.key === value && 'font-bold text-secondary'}
|
||||
`}
|
||||
>
|
||||
<span className={`
|
||||
text-3xl mr-2 inline-block p-0 leading-3
|
||||
translate-y-3
|
||||
`}>
|
||||
<>°</>
|
||||
</span>
|
||||
{entry.title}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CoreSettingList
|
|
@ -0,0 +1,39 @@
|
|||
import SettingsIcon from 'shared/components/icons/settings.js'
|
||||
import { linkClasses, Chevron } from 'shared/components/navigation/primary.js'
|
||||
import Setting from './setting.js'
|
||||
|
||||
const settings = {
|
||||
locale: {
|
||||
dflt: 'en',
|
||||
list: ['de', 'en', 'es', 'fr', 'nl'],
|
||||
},
|
||||
}
|
||||
|
||||
const CoreSettings = props => {
|
||||
|
||||
return (
|
||||
<details className='py-1' open>
|
||||
<summary className={`
|
||||
flex flex-row uppercase gap-4 font-bold text-lg
|
||||
hover:cursor-row-resize
|
||||
p-2
|
||||
text-base-content
|
||||
sm:text-neutral-content
|
||||
items-center
|
||||
`}>
|
||||
<span className="text-secondary-focus mr-4"><SettingsIcon /></span>
|
||||
<span className={`grow ${linkClasses}`}>
|
||||
{props.app.t('app.settings')}
|
||||
</span>
|
||||
<Chevron />
|
||||
</summary>
|
||||
<ul className="pl-5 list-inside">
|
||||
{Object.keys(settings).map(setting => (
|
||||
<Setting key={setting} setting={setting} config={settings[setting]} {...props} />
|
||||
))}
|
||||
</ul>
|
||||
</details>
|
||||
)
|
||||
}
|
||||
|
||||
export default CoreSettings
|
|
@ -0,0 +1,169 @@
|
|||
import { linkClasses, Chevron } from 'shared/components/navigation/primary.js'
|
||||
import PctDegOption from 'shared/components/workbench/inputs/design-option-pct-deg'
|
||||
import CountOption from 'shared/components/workbench/inputs/design-option-count'
|
||||
import ListSetting from './core-setting-list'
|
||||
import { formatMm, formatPercentage, optionType } from 'shared/utils.js'
|
||||
|
||||
const settings = {
|
||||
locale: props => {
|
||||
return (
|
||||
<span className="text-secondary">
|
||||
{props.app.t(`i18n.${props.gist.settings.locale}`)}
|
||||
</span>
|
||||
)
|
||||
},
|
||||
pct: props => {
|
||||
const val = (typeof props.gist?.options?.[props.option] === 'undefined')
|
||||
? props.pattern.config.options[props.option].pct/100
|
||||
: props.gist.options[props.option]
|
||||
return (
|
||||
<span className={
|
||||
val=== props.pattern.config.options[props.option].pct/100
|
||||
? 'text-secondary'
|
||||
: 'text-accent'
|
||||
}>
|
||||
{formatPercentage(val)}
|
||||
{props.pattern.config.options[props.option]?.toAbs
|
||||
? ' | ' +formatMm(props.pattern.config.options[props.option]?.toAbs(val, props.gist))
|
||||
: null
|
||||
}
|
||||
</span>
|
||||
)
|
||||
},
|
||||
bool: props => {
|
||||
const dflt = props.pattern.config.options[props.option].bool
|
||||
const current = props.gist?.options?.[props.option]
|
||||
return (
|
||||
<span className={
|
||||
(dflt==current || typeof current === 'undefined')
|
||||
? 'text-secondary'
|
||||
: 'text-accent'
|
||||
}>
|
||||
{props.gist?.options?.[props.option]
|
||||
? props.app.t('app.yes')
|
||||
: props.app.t('app.no')
|
||||
}
|
||||
</span>
|
||||
)
|
||||
},
|
||||
count: props => {
|
||||
const dflt = props.pattern.config.options[props.option].count
|
||||
const current = props.gist?.options?.[props.option]
|
||||
return (dflt==current || typeof current === 'undefined')
|
||||
? <span className="text-secondary">{dflt}</span>
|
||||
: <span className="text-accent">{current}</span>
|
||||
},
|
||||
deg: props => {
|
||||
const dflt = props.pattern.config.options[props.option].deg
|
||||
const current = props.gist?.options?.[props.option]
|
||||
return (dflt==current || typeof current === 'undefined')
|
||||
? <span className="text-secondary">{dflt}°</span>
|
||||
: <span className="text-accent">{current}°</span>
|
||||
},
|
||||
mm: props => {
|
||||
return <p>No mm val yet</p>
|
||||
},
|
||||
constant: props => {
|
||||
return <p>No constant val yet</p>
|
||||
},
|
||||
}
|
||||
|
||||
const Tmp = props => <p>not yet</p>
|
||||
|
||||
const inputs = {
|
||||
locale: props => <ListSetting
|
||||
{...props}
|
||||
list={props.app.languages.map(key => ({
|
||||
key,
|
||||
title: props.app.t(`i18n.${key}`)
|
||||
}))}
|
||||
/>,
|
||||
}
|
||||
|
||||
|
||||
const Setting = props => {
|
||||
const Input = inputs[props.setting]
|
||||
const Value = settings[props.setting]
|
||||
|
||||
const toggleBoolean = () => {
|
||||
const dflt = props.pattern.config.options[props.option].bool
|
||||
const current = props.gist?.options?.[props.option]
|
||||
if (typeof current === 'undefined')
|
||||
props.updateGist(['options', props.option], !dflt)
|
||||
else props.unsetGist(['options', props.option])
|
||||
}
|
||||
|
||||
if (props.setting === 'bool') return (
|
||||
<li className="flex flex-row">
|
||||
<button className={`
|
||||
flex flex-row
|
||||
w-full
|
||||
justify-between
|
||||
px-2
|
||||
text-left
|
||||
text-base-content
|
||||
sm:text-neutral-content
|
||||
items-center
|
||||
pr-6
|
||||
`} onClick={toggleBoolean}>
|
||||
<div className={`
|
||||
grow pl-2 border-l-2
|
||||
${linkClasses}
|
||||
hover:border-secondary
|
||||
sm:hover:border-secondary-focus
|
||||
text-base-content sm:text-neutral-content
|
||||
`}>
|
||||
<span className={`
|
||||
text-3xl mr-2 inline-block p-0 leading-3
|
||||
translate-y-3
|
||||
`}>
|
||||
<>°</>
|
||||
</span>
|
||||
<span>
|
||||
{ props.app.t(`options.${props.pattern.config.name}.${props.option}.title`) }
|
||||
</span>
|
||||
</div>
|
||||
<Value setting={props.setting} {...props} />
|
||||
</button>
|
||||
</li>
|
||||
|
||||
)
|
||||
|
||||
return (
|
||||
<li className="flex flex-row">
|
||||
<details className="grow">
|
||||
<summary className={`
|
||||
flex flex-row
|
||||
px-2
|
||||
text-base-content
|
||||
sm:text-neutral-content
|
||||
hover:cursor-row-resize
|
||||
items-center
|
||||
`}>
|
||||
<div className={`
|
||||
grow pl-2 border-l-2
|
||||
${linkClasses}
|
||||
hover:border-secondary
|
||||
sm:hover:border-secondary-focus
|
||||
text-base-content sm:text-neutral-content
|
||||
`}>
|
||||
<span className={`
|
||||
text-3xl inline-block p-0 leading-3 px-2
|
||||
translate-y-3
|
||||
`}>
|
||||
<>°</>
|
||||
</span>
|
||||
<span>
|
||||
{ props.app.t(`settings.${props.setting}.title`) }
|
||||
</span>
|
||||
</div>
|
||||
<Value setting={props.setting} {...props} />
|
||||
<Chevron w={6} m={3}/>
|
||||
</summary>
|
||||
<Input {...props} />
|
||||
</details>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
|
||||
export default Setting
|
|
@ -1,11 +1,17 @@
|
|||
import ModesMenu from './modes.js'
|
||||
import DesignOptions from './design-options'
|
||||
import CoreSettings from './core-settings'
|
||||
|
||||
const WorkbenchMenu = props => {
|
||||
return (
|
||||
<nav className="smmax-w-96 grow mb-12">
|
||||
<ModesMenu {...props} />
|
||||
{props.mode === 'draft' && <DesignOptions {...props} />}
|
||||
{props.mode === 'draft' && (
|
||||
<>
|
||||
<DesignOptions {...props} />
|
||||
<CoreSettings {...props} />
|
||||
</>
|
||||
)}
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -6,21 +6,20 @@ import Measurements, { Input } from 'shared/components/workbench/measurements/in
|
|||
import LabDraft from 'shared/components/workbench/draft/index.js'
|
||||
import set from 'lodash.set'
|
||||
import unset from 'lodash.unset'
|
||||
import defaultSettings from 'shared/components/workbench/default-settings.js'
|
||||
|
||||
|
||||
// Generates a default pattern gist to start from
|
||||
const defaultGist = (pattern, language='en') => ({
|
||||
const defaultGist = (pattern, language='en') => {
|
||||
const gist = {
|
||||
design: pattern.config.name,
|
||||
version: pattern.config.version,
|
||||
settings: {
|
||||
sa: 0,
|
||||
complete: true,
|
||||
paperless: false,
|
||||
units: 'metric',
|
||||
locale: language,
|
||||
margin: 2,
|
||||
debug: true,
|
||||
settings: defaultSettings
|
||||
}
|
||||
})
|
||||
if (language) gist.settings.locale = language
|
||||
|
||||
return gist
|
||||
}
|
||||
|
||||
const hasRequiredMeasurements = (pattern, gist) => {
|
||||
for (const m of pattern.config.measurements) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue