import yaml from 'js-yaml' import { defaultGist } from 'shared/components/workbench/gist.mjs' import { validateGist } from './gist-validator.mjs' import { useEffect, useState, useRef } from 'react' import Popout from 'shared/components/popout.mjs' import { useTranslation } from 'next-i18next' import { capitalize } from '@freesewing/core' /** a view for editing the gist as yaml */ export const EditYaml = (props) => { let { gist, setGist, gistReady } = props const inputRef = useRef(null) // the gist parsed to yaml const [gistAsYaml, setGistAsYaml] = useState(null) // any errors as a json string const [error, setError] = useState(null) // success notifier const [success, setSuccess] = useState(null) const { t } = useTranslation(['workbench']) // parse the current gist to yaml. this will also run when the gist gets set by input useEffect(() => { if (gistReady) { // get everything but the design because it's a function and can't be serialized // eslint-disable-next-line no-unused-vars const { design, ...gistRest } = gist setGistAsYaml(yaml.dump(gistRest)) } }, [gist, gistReady]) // set the line numbers when the yaml changes useEffect(() => { if (gistAsYaml) { inputRef.current.value = gistAsYaml } }, [gistAsYaml]) /** user-initiated save */ const onSave = () => { // clear the errors setError(null) try { // parse back to json const editedAsJson = yaml.load(inputRef.current.value) // make it backwards compatible so that people can paste in the yaml export from org // the yaml export from org is missing some of the settings that are needed in the gist, // and what it does have is under 'settings', so we merge that stuff with the existing gist view state // and the default settings to make sure all necessary keys are accounted for, // but we're not keeping stuff that was supposed to be cleared const gistFromDefaults = { _state: gist._state } for (const d in defaultGist) { gistFromDefaults[d] = gist[d] === undefined ? defaultGist[d] : gist[d] } // merge it all up const gistToCheck = { ...gistFromDefaults, ...(editedAsJson.settings ? editedAsJson.settings : editedAsJson), } // validate it const validation = validateGist(gistToCheck, props.design) // if it's not valid, show a warning about errors if (!validation.valid) { const newError = JSON.stringify(validation.errors, null, 2) setError(newError) } // save regardless setGist(gistToCheck) setSuccess(true) } catch (e) { setError(e) } } const designName = capitalize(props.design.designConfig.data.name.replace('@freesewing/', '')) return (

{t('yamlEditViewTitleThing', { thing: designName })}

{error ? (

{t('yamlEditViewError')}

{success ?

{t('yamlEditViewErrorDesc')}:

: null}

        
) : null} {success ? (
{t('success')}
) : null}