Skip to content
This repository was archived by the owner on Jul 12, 2023. It is now read-only.

Commit 4cc6fb2

Browse files
committed
Add JSON editing
1 parent 119d6ed commit 4cc6fb2

File tree

2 files changed

+58
-6
lines changed

2 files changed

+58
-6
lines changed

src/micro-panel-editor-entry.js

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
import 'codeflask-element'
22
import 'prismjs/components/prism-markdown.min.js'
3+
import 'prismjs/components/prism-json.min.js'
34
import { LitElement, html } from '@polymer/lit-element'
45
import { sharedStyles, icons, iconCode } from './util.js'
56
import produce from 'immer'
67

78
export default class MicroPanelEditorEntry extends LitElement {
8-
static get properties () { return { entry: Object, setEntry: Function } }
9+
static get properties () {
10+
return {
11+
entry: Object, setEntry: Function, openJsonEditors: Object, jsonParseError: Object
12+
}
13+
}
14+
15+
constructor () {
16+
super()
17+
this.openJsonEditors = {}
18+
this.jsonParseError = {}
19+
}
920

10-
_render ({ entry }) {
21+
_render ({ entry, openJsonEditors, jsonParseError }) {
1122
return html`
1223
${sharedStyles}
1324
<style>
@@ -33,7 +44,7 @@ export default class MicroPanelEditorEntry extends LitElement {
3344
.input-row + .input-row {
3445
padding-top: 0;
3546
}
36-
.input-row input, .input-row textarea, .input-row code-flask {
47+
.input-row input, .input-row textarea, .input-row code-flask, .input-row .error-value {
3748
flex: 1;
3849
}
3950
.input-row button {
@@ -46,6 +57,14 @@ export default class MicroPanelEditorEntry extends LitElement {
4657
resize: vertical;
4758
min-height: 200px;
4859
}
60+
.error-value {
61+
color: #bb1111;
62+
}
63+
.json-error {
64+
background: #bb1111;
65+
color: #fff;
66+
padding: 0.5rem;
67+
}
4968
5069
@media screen and (min-width: 700px) {
5170
fieldset { width: 70%; }
@@ -59,18 +78,23 @@ export default class MicroPanelEditorEntry extends LitElement {
5978
<button on-click=${_ =>
6079
this._modify(entry, draft => delete draft.properties[propname])
6180
} title="Delete this property" class="icon-button">${iconCode(icons.minus)}</button>
81+
<button on-click=${_ => {
82+
this.openJsonEditors = produce(openJsonEditors, x => { x[propname] = !(x[propname] || false) })
83+
this.jsonParseError = produce(jsonParseError, pes => { pes[propname] = null })
84+
}} title="Edit this property as JSON" class="icon-button">${iconCode(icons.json)}</button>
6285
<button on-click=${_ =>
6386
this._modify(entry, draft => draft.properties[propname].push(''))
6487
} title="Add new value to this property" class="icon-button">${iconCode(icons.plus)}</button>
6588
</header>
66-
${entry.properties[propname] && entry.properties[propname].map((propval, idx) => html`
89+
${openJsonEditors[propname] ? this._jsonEditor(entry, propname, jsonParseError)
90+
: (entry.properties[propname] && entry.properties[propname].map((propval, idx) => html`
6791
<div class="input-row">
6892
${this._rowEditor(entry, propname, propval, idx)}
6993
<button on-click=${_ =>
7094
this._modify(entry, draft => draft.properties[propname].splice(idx, 1))
7195
} title="Delete this value" class="icon-button">${iconCode(icons.minus)}</button>
7296
</div>
73-
`)}
97+
`))}
7498
</fieldset>
7599
`)}
76100
@@ -89,8 +113,11 @@ export default class MicroPanelEditorEntry extends LitElement {
89113
}/>
90114
`
91115
}
116+
if (propval === null) {
117+
return html`<div class="error-value">null</div>`
118+
}
92119
if (typeof propval !== 'object') {
93-
return `Unsupported object type ${typeof propval}`
120+
return html`<div class="error-value">Item of unsupported type ${typeof propval}</div>`
94121
}
95122
if ('html' in propval) {
96123
return html`
@@ -104,9 +131,30 @@ export default class MicroPanelEditorEntry extends LitElement {
104131
this._modify(entry, draft => draft.properties[propname][idx].markdown = e.target.value)
105132
}></code-flask>
106133
`
134+
} else {
135+
return html`<div class="error-value">Unsupported object with keys: ${Object.keys(propval)}</div>`
107136
}
108137
}
109138

139+
_jsonEditor (entry, propname, jsonParseError) {
140+
return html`
141+
<code-flask language="json" value=${JSON.stringify(entry.properties[propname], null, 2)} on-value-changed=${e =>
142+
this._modify(entry, draft => {
143+
try {
144+
draft.properties[propname] = JSON.parse(e.target.value)
145+
this.jsonParseError = produce(jsonParseError, pes => { pes[propname] = null })
146+
} catch (e) {
147+
this.jsonParseError = produce(jsonParseError, pes => { pes[propname] = e.toString() })
148+
}
149+
})
150+
}></code-flask>
151+
${jsonParseError[propname] ? html`<div class="json-error">
152+
<p><strong>JSON parsing error!</strong> The changes are not saved when this error is present. Please fix the syntax in the editor above. The error is:</p>
153+
<p><code>${jsonParseError[propname]}</code></p>
154+
</div>` : ''}
155+
`
156+
}
157+
110158
addNewProp (e, entry) {
111159
if ('key' in e && e.key !== 'Enter') {
112160
return

src/util.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ export const icons = {
118118
close: svg`
119119
<path fill="currentColor" d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />
120120
`,
121+
/* by Austin Andrews @Templarian | OFL licensed: */
122+
json: svg`
123+
<path fill="currentColor" d="M5,3H7V5H5V10A2,2 0 0,1 3,12A2,2 0 0,1 5,14V19H7V21H5C3.93,20.73 3,20.1 3,19V15A2,2 0 0,0 1,13H0V11H1A2,2 0 0,0 3,9V5A2,2 0 0,1 5,3M19,3A2,2 0 0,1 21,5V9A2,2 0 0,0 23,11H24V13H23A2,2 0 0,0 21,15V19A2,2 0 0,1 19,21H17V19H19V14A2,2 0 0,1 21,12A2,2 0 0,1 19,10V5H17V3H19M12,15A1,1 0 0,1 13,16A1,1 0 0,1 12,17A1,1 0 0,1 11,16A1,1 0 0,1 12,15M8,15A1,1 0 0,1 9,16A1,1 0 0,1 8,17A1,1 0 0,1 7,16A1,1 0 0,1 8,15M16,15A1,1 0 0,1 17,16A1,1 0 0,1 16,17A1,1 0 0,1 15,16A1,1 0 0,1 16,15Z" />
124+
`,
121125
}
122126

123127
export function iconCode (icon, title = null) {

0 commit comments

Comments
 (0)