1
0
Fork 0

feat(lab): Draft view pretty ok now

This commit is contained in:
Joost De Cock 2022-01-28 16:57:07 +01:00
parent 73163f5676
commit 929822b249
15 changed files with 327 additions and 29 deletions

View file

@ -0,0 +1,15 @@
import Robot from 'shared/components/robot/index.js'
import Events from './events.js'
const Error = props => (
<div className="mt-12">
<div className="flex flex-row items-center justify-around">
<h1>{props.app.t('errors.something')}</h1>
<div className="max-w-96"><Robot pose='fail' embed/></div>
</div>
<Events events={props.patternInstance.events} />
</div>
)
export default Error

View file

@ -0,0 +1,36 @@
import Markdown from 'react-markdown'
import { linkClasses } from 'shared/components/navigation/primary.js'
const eventBlock = events => events.join(" \n")
const EventGroup = ({ type='info', events=[] }) => events.length > 0 ? (
<div className="">
<h3 className="capitalize" id={`events-${type}`}>{type}</h3>
<div className="mdx">
<Markdown>{eventBlock(events)}</Markdown>
</div>
</div>
) : null
const order = [
'error',
'warning',
'info',
'debug'
]
const Events = props => (
<div className="flex flex-col">
<ul className="flex flex-row row-wrap">
{order.map(type => (
<li key={type} className="">
<a href={`#events-${type}`} className={`text-secondary font-bold capitalize text-xl`}>{type}</a>
{type === 'debug' ? '' : <span className="px-2 font-bold">|</span>}
</li>
))}
</ul>
{order.map(type => <EventGroup type={type} events={props.events[type]} />)}
</div>
)
export default Events

View file

@ -3,35 +3,86 @@ import Svg from './svg'
import Defs from './defs'
import Part from './part'
import theme from 'pkgs/plugin-theme/src/index.js'
import Robot from 'shared/components/robot/index.js'
import Error from './error.js'
import Events from './events.js'
import Json from 'shared/components/json.js'
import Yaml from 'shared/components/yaml.js'
import { capitalize } from 'shared/utils.js'
const LabDraft = ({ app, pattern, gist, updateGist }) => {
const tabClasses = active => `
tab tab-bordered font-bold text-4xl pb-12 capitalize
${active && 'text-base-content tab-active'}
`
const Wrap = props => <div className="max-w-screen-xl m-auto">{props.children}</div>
const LabDraft = props => {
const { app, pattern, gist, updateGist } = props
const [tab, setTab] = useState(props.pattern.config.name)
const patternInstance = new pattern(gist)
if (gist?.renderer === 'svg') return <div
dangerouslySetInnerHTML={{ __html: patternInstance.use(theme).draft().render()}} />
const eprops = { ...props, patternInstance }
if (gist?.renderer === 'svg') patternInstance.use(theme)
// Catch errors
try { patternInstance.draft() }
catch(error) {
console.log('Failed to draft pattern', error)
return <Error error={error} {...eprops} at={'draft'} />
}
const patternProps = patternInstance.draft().getRenderProps()
console.log(patternProps)
// Render as SVG
let svg
try { svg = patternInstance.render() }
catch(error) {
console.log('Failed to render pattern', error)
return <Error error={error} {...eprops} />
}
if (gist?.renderer === 'svg')
return <div dangerouslySetInnerHTML={{ __html: svg }} />
// Render as React
let patternProps = {}
try { patternProps = patternInstance.draft().getRenderProps() }
catch(error) {
console.log('Failed to get render props for pattern', error)
return <Error error={error} {...eprops} />
}
return (
<Svg {...patternProps}>
<Defs {...patternProps} />
<style>{`:root { --pattern-scale: ${gist.scale || 1}}`}</style>
<g>
{Object.keys(patternProps.parts).map((name) => (
<Part
key={name}
part={patternProps.parts[name]}
locale={gist.locale}
paperless={gist.paperless}
units={gist.units}
name={name}
app={app}
/>
))}
</g>
</Svg>
<div>
<div className="tabs my-8 mx-auto justify-center">
{[props.pattern.config.name, 'events', 'yaml', 'json'].map(name => <button
key={name}
onClick={() => setTab(name)}
className={tabClasses(tab === name)}
>{name}</button>)}
</div>
{tab === 'events' && <Wrap><Events events={patternInstance.events} /></Wrap>}
{tab === 'json' && <Wrap><Json>{JSON.stringify(props.gist, null, 2)}</Json></Wrap>}
{tab === 'yaml' && <Wrap><Yaml json={JSON.stringify(props.gist, null, 2)} /></Wrap>}
{tab === props.pattern.config.name && (
<Svg {...patternProps}>
<Defs {...patternProps} />
<style>{`:root { --pattern-scale: ${gist.scale || 1}}`}</style>
<g>
{Object.keys(patternProps.parts).map((name) => (
<Part
key={name}
part={patternProps.parts[name]}
locale={gist.locale}
paperless={gist.paperless}
units={gist.units}
name={name}
app={app}
/>
))}
</g>
</Svg>
)}
</div>
)
}

View file

@ -0,0 +1,64 @@
import ClearIcon from 'shared/components/icons/clear.js'
import orderBy from 'lodash.orderby'
const CoreSettingOnly = props => {
const list = props.pattern.config.draftOrder
const partNames = list.map(part => ({ id: part, name: props.app.t(`parts.${part}`, props.app.locale) }))
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 (
<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.only.description`)}
</p>
<div className="flex flex-row">
<div className="grow">
{orderBy(partNames, ['name'], ['asc']).map(part => (
<button
key={part.id}
onClick={() => togglePart(part.id)}
className={`
mr-1 mb-1 text-left text-lg w-full hover:text-secondary-focus px-2
${props.gist?.only && props.gist.only.indexOf(part.id) !== -1 && 'font-bold text-secondary'}
`}
>
<span className={`
text-3xl mr-2 inline-block p-0 leading-3
translate-y-3
`}>
<>&deg;</>
</span>
{part.name}
</button>
))}
</div>
</div>
<div className="flex flex-row-reverse">
<button
title={props.app.t('app.reset')}
className="btn btn-ghost btn-xs text-accent"
disabled={!props.gist.only || props.gist.only.length < 1}
onClick={reset}
>
<ClearIcon />
</button>
</div>
</div>
)
}
export default CoreSettingOnly

View file

@ -17,6 +17,7 @@ const settings = {
complete: {
dflt: false,
},
only: { },
locale: {
list: ['de', 'en', 'es', 'fr', 'nl'],
},
@ -35,6 +36,9 @@ const settings = {
svg: '@freesewing/core (SVG)'
}
},
debug: {
dflt: false,
},
}
const CoreSettings = props => {

View file

@ -2,6 +2,7 @@ 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 OnlySetting from './core-setting-only'
import MmSetting from './core-setting-mm'
import BoolSetting from './core-setting-bool.js'
import SaBoolSetting from './core-setting-sa-bool.js'
@ -23,6 +24,13 @@ const settings = {
</span>
)
},
debug: props => {
return (
<span className="text-secondary">
{props.app.t(`app.${props.gist.debug ? 'yes' : 'no'}`)}
</span>
)
},
locale: props => {
return (
<span className="text-secondary">
@ -56,6 +64,9 @@ const settings = {
{props.config.titles[props.gist.renderer]}
</span>
),
only: props => (props.gist?.only && props.gist.only.lenght > 0)
? <span>{props.gist.only.length}</span>
: <span>fixme</span>
}
const inputs = {
@ -82,13 +93,14 @@ const inputs = {
title: props.config.titles[key]
}))}
/>,
only: props => <OnlySetting {...props} />
}
const Setting = props => {
if (props.setting === 'saBool')
return <SaBoolSetting {...props} {...props.config} />
if (['paperless', 'complete'].indexOf(props.setting) !== -1)
if (['paperless', 'complete', 'debug'].indexOf(props.setting) !== -1)
return <BoolSetting {...props} {...props.config} />
const Input = inputs[props.setting]