198 lines
8.5 KiB
JavaScript
198 lines
8.5 KiB
JavaScript
class CCPInputWidgetEditorController extends HTMLElement{
|
|
|
|
#input = null
|
|
#index = null
|
|
#type = null
|
|
|
|
#delete_icon = `
|
|
<svg style="width:24px;height:24px;pointer-events: none;" viewBox="0 0 24 24">
|
|
<path d="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z" />
|
|
</svg>
|
|
`
|
|
|
|
constructor(){
|
|
super();
|
|
|
|
}
|
|
|
|
connectedCallback(){
|
|
|
|
}
|
|
|
|
get index(){
|
|
return this.#index
|
|
}
|
|
|
|
computeDefaultInputType(){
|
|
if(this.#input.schema.format === "secret"){
|
|
return "password"
|
|
}else if(this.#input.schema.format === "date"){
|
|
return "date"
|
|
}else if(this.#input.schema.format === "time"){
|
|
return "type"
|
|
}else if(this.#input.schema.format === "dateTime"){
|
|
return "dateTime"
|
|
}
|
|
return "text"
|
|
}
|
|
|
|
isSelectedFormat(fmt){
|
|
return this.#input.schema.format === fmt ? 'selected="selected"' : ""
|
|
}
|
|
|
|
render(input, i){
|
|
this.#index = i
|
|
this.#input = input
|
|
this.#type = input.schema.enum ? "enum" : "string"
|
|
this.innerHTML = `
|
|
<details>
|
|
<summary class="mb-3">
|
|
<input class="form-control" style="width:auto;display:inline" required="required" name="id" value="${this.#input.id}" title="Id of input"/>
|
|
<button data-index="${this.#index}" name="delete-input" title="Delete" class="btn btn-danger ccp-toolbar-button">
|
|
${this.#delete_icon}
|
|
</button>
|
|
</summary>
|
|
<div style="padding-left: 1rem;border-left: 1px solid gray;">
|
|
<div class="row mb-3">
|
|
<div class="col">
|
|
<div class="form-field" title="Title">
|
|
<input name="title" class="form-control" placeholder="title" value="${this.#input.title}" required="required"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="mb-3">
|
|
<div class="form-field" title="description">
|
|
<input name="description" class="form-control" placeholder="description" value="${this.#input.description}" required="required"/>
|
|
</div>
|
|
</div>
|
|
<div class="row mb-3">
|
|
<div class="col-3">
|
|
<div class="form-field" title="Type">
|
|
<label>Type</label>
|
|
<select name="type" class="form-control" placeholder="type" value="${this.#input.schema.type}">
|
|
<option value="string">String</option>
|
|
<option value="enum">Enum</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col">
|
|
<div class="form-field" title="Minimum">
|
|
<label>Min</label>
|
|
<input value="${this.#input.minOccurs}" type="number" min="0" step="1" name="minOccurs" value="${this.#input.minOccurs}" required="required" class="form-control" placeholder="minOccurs"/>
|
|
</div>
|
|
</div>
|
|
<div class="col">
|
|
<div class="form-field" title="Maximum">
|
|
<label>Max</label>
|
|
<input value="${this.#input.maxOccurs}" type="number" min="0" step="1" name="maxOccurs" value="${this.#input.maxOccurs}" required="required" class="form-control" placeholder="maxOccurs"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div name="string-input" class="${this.#type === 'enum' ? 'd-none' : ''} row mb-3">
|
|
<div class="col-3">
|
|
<div class="form-field" title="Format">
|
|
<label>Format</label>
|
|
<select value="${this.#input.schema.format}" name="format" class="form-control">
|
|
<option value="none" selected="${this.isSelectedFormat('none')}">None</option>
|
|
<option value="date" selected="${this.isSelectedFormat('date')}">Date</option>
|
|
<option value="time" selected="${this.isSelectedFormat('time')}">Time</option>
|
|
<option value="dateTime" selected="${this.isSelectedFormat('dateTime')}">Date time</option>
|
|
<option value="code" selected="${this.isSelectedFormat('code')}">Code</option>
|
|
<option value="file" selected="${this.isSelectedFormat('file')}"}>File</option>
|
|
<option value="secret" selected="${this.isSelectedFormat('secret')}">Secret</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col" title="Mime type">
|
|
<label>Mime</label>
|
|
<div class="form-field">
|
|
<input value="${this.#input.schema.contentMediaType}" name="contentMediaType" class="form-control" placeholder="mime"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div name="enum-input" class="${this.#type !== 'enum' ? 'd-none' : ''} mb-3">
|
|
<div class="form-field" title="options">
|
|
<input name="options" class="form-control" type="text" placeholder="option"/>
|
|
<small class="form-text text-muted">Comma separated list of options</small>
|
|
</div>
|
|
</div>
|
|
<div name="input-default" class="mb-3">
|
|
<div class="form-field" title="Default value">
|
|
<input type="${this.computeDefaultInputType()}" value="${this.#input.schema.default}" name="default" class="form-control" placeholder="default"/>
|
|
<span style="user-select:none;position:relative;top:-1.6rem;float:right;cursor:pointer" name="password_toggle" class="${this.isSelectedFormat('secret') === '' ? 'd-none' : 'inline'}">👁</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</details>
|
|
`
|
|
this.addEventListener("click", ev=>{
|
|
const ename = ev.target.getAttribute("name")
|
|
if(ename === "password_toggle"){
|
|
const w = this.querySelector("div[name=input-default] input[name=default]")
|
|
w.type = (w.type === "password" ? "" : "password")
|
|
ev.preventDefault()
|
|
}
|
|
})
|
|
|
|
this.addEventListener("input", ev=>{
|
|
const val = ev.target.value
|
|
const ename = ev.target.getAttribute("name")
|
|
if(ename === "id"){
|
|
this.#input.id = val
|
|
}
|
|
else if(ename === "title"){
|
|
this.#input.title = val
|
|
}
|
|
else if(ename === "description"){
|
|
this.#input.description = val
|
|
}
|
|
else if(ename === "minOccurs"){
|
|
this.#input.minOccurs = val
|
|
}
|
|
else if(ename === "maxOccurs"){
|
|
this.#input.maxOccurs = val
|
|
}
|
|
else if(ename === "format"){
|
|
this.#input.schema.format = val
|
|
this.querySelector("div[name=input-default] span[name=password_toggle]").classList.add("d-none")
|
|
this.querySelector("div[name=input-default] input[name=default]").type = ""
|
|
if(this.#input.schema.format === "secret"){
|
|
this.querySelector("div[name=input-default] input[name=default]").type = "password"
|
|
this.querySelector("div[name=input-default] span[name=password_toggle]").classList.remove("d-none")
|
|
}else if(this.#input.schema.format === "date"){
|
|
this.querySelector("div[name=input-default] input[name=default]").type = "date"
|
|
}else if(this.#input.schema.format === "time"){
|
|
this.querySelector("div[name=input-default] input[name=default]").type = "time"
|
|
}else if(this.#input.schema.format === "dateTime"){
|
|
this.querySelector("div[name=input-default] input[name=default]").type = "dateTime"
|
|
}else if(this.#input.schema.format === "file"){
|
|
this.querySelector("div[name=input-default] input[name=default]").type = "file"
|
|
}
|
|
}
|
|
else if(ename === "contentMediaType"){
|
|
this.#input.schema.contentMediaType = val
|
|
}
|
|
else if(ename === "options"){
|
|
this.#input.schema.enum = val.split(",")
|
|
}
|
|
else if(ename === "default"){
|
|
this.#input.schema.default = val
|
|
}
|
|
else if(ename === "type"){
|
|
this.#type = ev.target.value
|
|
if(this.#type === "enum"){
|
|
this.querySelector("div[name=string-input]").classList.add("d-none")
|
|
this.querySelector("div[name=enum-input]").classList.remove("d-none")
|
|
this.#input.schema.enum = this.querySelector("input[name=options]").value.split(",")
|
|
}else if(this.#type === "string"){
|
|
this.querySelector("div[name=enum-input]").classList.add("d-none")
|
|
this.querySelector("div[name=string-input]").classList.remove("d-none")
|
|
delete this.#input.schema['enum']
|
|
}
|
|
}
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
window.customElements.define('d4s-ccp-input-editor', CCPInputWidgetEditorController); |