basic editor interface
This commit is contained in:
parent
57dc0e929b
commit
ed3f0abf23
3 changed files with 123 additions and 1 deletions
67
sites/shared/components/workbench/edit.js
Normal file
67
sites/shared/components/workbench/edit.js
Normal file
|
@ -0,0 +1,67 @@
|
|||
import yaml from 'js-yaml'
|
||||
import hljs from 'highlight.js/lib/common'
|
||||
import defaultSettings from './default-settings'
|
||||
import validateGist from './gist-validator'
|
||||
import { useEffect, useState, useRef } from 'react'
|
||||
|
||||
const countLines = (txt) => txt.split('\n').length
|
||||
const Edit = (props) => {
|
||||
let { gist, setGist, design } = props
|
||||
|
||||
const inputRef = useRef(null)
|
||||
const [gistAsYaml, setGistAsYaml] = useState(null)
|
||||
const [numLines, setNumLines] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
setGistAsYaml(yaml.dump(gist))
|
||||
}, [gist])
|
||||
useEffect(() => {
|
||||
if (gistAsYaml) setNumLines(countLines(gistAsYaml))
|
||||
}, [gistAsYaml])
|
||||
|
||||
const onChange = (e) => {
|
||||
const editedAsJson = yaml.load(inputRef.current.value)
|
||||
if (validateGist(editedAsJson, design).valid) {
|
||||
setGist({ ...defaultSettings, ...editedAsJson, design: gist.design })
|
||||
}
|
||||
}
|
||||
|
||||
const onKeyUp = (e) => {
|
||||
setNumLines(countLines(e.target.value))
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="max-w-screen-xl m-auto h-screen form-control">
|
||||
<h1>Edit Pattern Configuration</h1>
|
||||
<div
|
||||
id="editor"
|
||||
className="h-3/5 mb-8 overflow-auto p-1 outline-1 outline-primary outline focus-within:outline-primary-focus focus-within:outline-2 rounded"
|
||||
>
|
||||
<div className="font-mono flex gap-4 leading-7 text-lg items-stretch">
|
||||
<div id="line-numbers" className="text-right p-4 pr-0 text-primary" aria-hidden>
|
||||
{Array.from({ length: numLines }, (_, i) => (
|
||||
<span className="block" key={i}>
|
||||
{' '}
|
||||
{i + 1}{' '}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
<textarea
|
||||
className="textarea focus:outline-none w-full p-4 leading-7 overflow-y-hidden resize-none text-lg"
|
||||
name="gistAsYaml"
|
||||
aria-label="Configuration in YAML format"
|
||||
ref={inputRef}
|
||||
defaultValue={gistAsYaml}
|
||||
onKeyUp={onKeyUp}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<button className="btn btn-primary" onClick={onChange}>
|
||||
{' '}
|
||||
Save{' '}
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Edit
|
53
sites/shared/components/workbench/gist-validator.js
Normal file
53
sites/shared/components/workbench/gist-validator.js
Normal file
|
@ -0,0 +1,53 @@
|
|||
import defaultSettings from './default-settings'
|
||||
|
||||
class GistValidator {
|
||||
givenGist
|
||||
design
|
||||
errors
|
||||
valid = true
|
||||
|
||||
constructor(givenGist, design) {
|
||||
this.givenGist = givenGist
|
||||
this.design = design
|
||||
this.errors = {}
|
||||
}
|
||||
|
||||
validateSettings() {
|
||||
for (var key in defaultSettings) {
|
||||
if (typeof this.givenGist[key] !== typeof defaultSettings[key]) {
|
||||
this.errors[key] = 'TypeError'
|
||||
this.valid = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
validateMeasurements() {
|
||||
this.errors.measurements = {}
|
||||
for (const m of this.design.patternConfig.measurements || []) {
|
||||
if (this.givenGist.measurements[m] === undefined) {
|
||||
this.errors.measurements[m] = 'MissingMeasurement'
|
||||
this.valid = false
|
||||
} else if (isNaN(this.givenGist.measurements[m])) {
|
||||
this.errors.measurements[m] = 'TypeError'
|
||||
this.valid = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
validateOptions() {
|
||||
console.log(this.design.patternConfig)
|
||||
}
|
||||
|
||||
validate() {
|
||||
this.validateSettings()
|
||||
this.validateMeasurements()
|
||||
this.validateOptions()
|
||||
|
||||
return { valid: this.valid, errors: this.errors }
|
||||
}
|
||||
}
|
||||
|
||||
export default function validateGist(givenGist, design) {
|
||||
const validator = new GistValidator(givenGist, design)
|
||||
return validator.validate()
|
||||
}
|
|
@ -19,6 +19,7 @@ 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'
|
||||
|
||||
|
||||
const views = {
|
||||
measurements: WorkbenchMeasurements,
|
||||
draft: LabDraft,
|
||||
|
@ -29,6 +30,7 @@ const views = {
|
|||
logs: DraftLogs,
|
||||
yaml: GistAsYaml,
|
||||
json: GistAsJson,
|
||||
edit: Edit,
|
||||
welcome: () => <p>TODO</p>,
|
||||
}
|
||||
|
||||
|
@ -76,7 +78,7 @@ export const WorkbenchWrapper = ({
|
|||
// force view to measurements
|
||||
useEffect(() => {
|
||||
if (!gistReady) return
|
||||
if (gist._state?.view !== 'measurements' && !hasRequiredMeasurements)
|
||||
if (!['measurements', 'edit'].includes(gist._state?.view) && !hasRequiredMeasurements)
|
||||
updateGist(['_state', 'view'], 'measurements')
|
||||
}, [gistReady, gist._state?.view, hasRequiredMeasurements])
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue