moved export/import of methods to list

This commit is contained in:
dcore94 2023-02-09 16:29:12 +01:00
parent 688b240d72
commit 907096ac2d
2 changed files with 106 additions and 94 deletions

View File

@ -155,9 +155,6 @@ class CCPMethodEditorController extends HTMLElement{
<path d="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z" /> <path d="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z" />
</svg> </svg>
` `
#download_icon = `
<svg viewBox="0 0 24 24"><g><rect fill="none" height="24" width="24"/></g><g><path d="M18,15v3H6v-3H4v3c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-3H18z M17,11l-1.41-1.41L13,12.17V4h-2v8.17L8.41,9.59L7,11l5,5 L17,11z"/></g></svg>
`
constructor(){ constructor(){
super(); super();
@ -295,31 +292,6 @@ class CCPMethodEditorController extends HTMLElement{
}) })
} }
downloadMethod(){
if(this.#locked) return;
this.lockRender()
this.#boot.secureFetch(this.#serviceurl + "/methods/" + this.#current.id + "/shareable").then(
(resp)=>{
if(resp.status === 200){
return resp.json()
}else throw "Error retrieving sharable process: " + resp.status
}
).then(data=>{
const filename = data.title + "-" + data.version + ".json"
const datastr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(data));
var tmplnk = document.createElement("a")
tmplnk.download = filename
tmplnk.href = datastr
document.body.appendChild(tmplnk)
tmplnk.click()
document.body.removeChild(tmplnk)
this.unlockRender()
}).catch(err=>{
alert(err)
this.unlockRender()
})
}
editMethod(method){ editMethod(method){
if(this.#locked) return; if(this.#locked) return;
this.lockRender() this.lockRender()
@ -407,7 +379,6 @@ class CCPMethodEditorController extends HTMLElement{
<div class="ccp-toolbar-right"> <div class="ccp-toolbar-right">
${this.renderSaveButton()} ${this.renderSaveButton()}
${this.renderResetButton()} ${this.renderResetButton()}
${this.renderDownloadButton()}
${ this.#isupdate ? this.renderDeleteButton() : "" } ${ this.#isupdate ? this.renderDeleteButton() : "" }
</div> </div>
</div> </div>
@ -562,12 +533,6 @@ class CCPMethodEditorController extends HTMLElement{
this.saveMethod() this.saveMethod()
}) })
this.#rootdoc.querySelector("button[name=download]").addEventListener("click", ev=>{
ev.preventDefault()
ev.stopPropagation()
this.downloadMethod()
})
if(this.#isupdate){ if(this.#isupdate){
this.#rootdoc.querySelector("button[name=delete]").addEventListener("click", ev=>{ this.#rootdoc.querySelector("button[name=delete]").addEventListener("click", ev=>{
ev.preventDefault() ev.preventDefault()
@ -801,14 +766,6 @@ class CCPMethodEditorController extends HTMLElement{
` `
} }
renderDownloadButton(){
return `
<button title="Export" name="download" class="btn btn-primary ccp-toolbar-button">
${this.#download_icon}
</button>
`
}
renderDeleteButton(){ renderDeleteButton(){
return ` return `
<button title="Delete" name="delete" class="btn btn-danger ccp-toolbar-button"> <button title="Delete" name="delete" class="btn btn-danger ccp-toolbar-button">

View File

@ -39,11 +39,20 @@ class CCPMethodList2 extends HTMLElement{
line-height: .8rem; line-height: .8rem;
cursor: pointer; cursor: pointer;
} }
.ccp-toolbar-button > svg { .ccp-toolbar-button svg {
width: 24px; display: block;
height:24px; fill: white;
fill: white; width: 24px;
stroke: white; height: 24px;
pointer-events: none;
}
.ccp-toolbar-button-small {
padding: 0.1rem !important;
line-height: .6rem !important;
}
.ccp-toolbar-button-small svg {
width: 16px !important;
height: 16px !important;
} }
.ccp-process-category-list{ .ccp-process-category-list{
list-style:none; list-style:none;
@ -60,22 +69,34 @@ class CCPMethodList2 extends HTMLElement{
} }
</style> </style>
<template id="PROCESS_LIST_TEMPLATE"> <template id="PROCESS_LIST_TEMPLATE">
<ul name="process_category_list" class="list-group ccp-process-category-list"> <ul name="process_category_list" class="border border-2 list-group ccp-process-category-list">
<li class="list-group-item list-group-item-dark ccp-process-category"> <li class="list-group-item list-group-item-dark ccp-process-category">
<details> <details>
<summary> <summary>
<h5 class="d-inline mr-2 text-primary"></h5> <h5 class="d-inline mr-2 text-primary"></h5>
<div class="float-right d-flex" style="gap:2px">
<span name="count_notexecutables" title="Number of non executable versions" class="badge border border-danger text-danger"></span>
<span name="count_executables" title="Number of executable versions" class="badge border border-success text-success"></span>
<button name="export_category" title="Export all versions" class="btn btn-primary ccp-toolbar-button ccp-toolbar-button-small">
<svg viewBox="0 0 24 24"><g><rect fill="none" height="24" width="24"/></g><g><path d="M18,15v3H6v-3H4v3c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-3H18z M17,11l-1.41-1.41L13,12.17V4h-2v8.17L8.41,9.59L7,11l5,5 L17,11z"/></g></svg>
</button>
</div>
</summary> </summary>
<ul name="process_list" class="list-group ccp-process-list"> <ul name="process_list" class="list-group ccp-process-list">
<li class="list-group-item list-group-item-secondary ccp-process p-2 my-1" draggable="true"> <li class="list-group-item list-group-item-secondary ccp-process p-2 my-1" draggable="true">
<div> <div>
<div name="executable" alt="Executable" title="Executable">
<svg viewBox="0 0 48 48" style="height:24px;width:24px; background-color:green;fill:white;position:absolute;right:5px;border-radius:50%;box-shadow:2px 2px 2px rgba(0,0,0,.5)">
<path d="M18.9 35.7 7.7 24.5l2.15-2.15 9.05 9.05 19.2-19.2 2.15 2.15Z"/>
</svg>
</div>
<span name="version" class="badge badge-primary"></span> <span name="version" class="badge badge-primary"></span>
<span name="author" class="badge badge-warning"></span> <span name="author" class="badge badge-warning"></span>
<div class="float-right d-flex" style="gap:3px">
<div name="executable" title="Executable" class="border border-success">
<svg viewBox="0 0 48 48" style="fill:green;width:16px;height:16px">
<path d="M18.9 35.7 7.7 24.5l2.15-2.15 9.05 9.05 19.2-19.2 2.15 2.15Z"/>
</svg>
</div>
<button name="export_method" title="Export this version" class="btn btn-primary ccp-toolbar-button ccp-toolbar-button-small">
<svg viewBox="0 0 24 24"><g><rect fill="none" height="24" width="24"/></g><g><path d="M18,15v3H6v-3H4v3c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-3H18z M17,11l-1.41-1.41L13,12.17V4h-2v8.17L8.41,9.59L7,11l5,5 L17,11z"/></g></svg>
</button>
</div>
</div> </div>
<p style="margin-top:.5rem" class="small" name="description"></p> <p style="margin-top:.5rem" class="small" name="description"></p>
<div> <div>
@ -194,59 +215,88 @@ class CCPMethodList2 extends HTMLElement{
}, {}) }, {})
} }
importMethods(files){ exportCategory(category){
if(files && files.length) { Promise.all(
let formdata = new FormData(); this.#filtered[category].map(m=>this.exportMethod(m.id))
files.reduce((formdata, f)=>{ )
formdata.append("files[]", f) }
return formdata
}, formdata) exportMethod(method){
this.#boot.secureFetch(`${this.#serviceurl}/methods`, { body: formdata, method : "POST"}) this.#boot.secureFetch(this.#serviceurl + "/methods/" + method + "/shareable").then(
.then(reply=>{ (resp)=>{
if (reply.status !== 200) { if(resp.status === 200){
throw "Unable to import" return resp.json()
}else return reply.text() }else throw "Error exporting sharable process: " + resp.status
}).then(data=>{ }
this.refreshExecutions() ).then(data=>{
}).catch(err=>{ alert(err) }) const filename = data.title + "-" + data.version + ".json"
} const datastr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(data));
var tmplnk = document.createElement("a")
tmplnk.download = filename
tmplnk.href = datastr
document.body.appendChild(tmplnk)
tmplnk.click()
document.body.removeChild(tmplnk)
}).catch(err=>{
console.log(err)
})
}
importMethods(files){
if(files && files.length) {
let formdata = new FormData();
files.reduce((formdata, f)=>{
formdata.append("files[]", f)
return formdata
}, formdata)
this.#boot.secureFetch(`${this.#serviceurl}/methods`, { body: formdata, method : "POST"})
.then(reply=>{
if (reply.status !== 200) {
throw "Unable to import"
}else return reply.text()
}).then(data=>{
this.updateList()
}).catch(err=>{ alert(err) })
}
} }
#process_list_bss = { #process_list_bss = {
template : "#PROCESS_LIST_TEMPLATE", template : "#PROCESS_LIST_TEMPLATE",
target : "ul[name=process_category_list]", target : "ul[name=process_category_list]",
"in" : this, "in" : this,
on_dragover : (ev)=>{ on_dragover : (ev)=> ev.preventDefault(),
ev.preventDefault() on_dragenter : (ev)=> ev.target.classList.toggle("border-info"),
}, on_dragleave : (ev)=> ev.target.classList.toggle("border-info"),
on_dragenter : (ev)=>{ on_drop : (ev)=>{
ev.target.classList.toggle("border-info") if(ev.dataTransfer && ev.dataTransfer.files && ev.dataTransfer.files.length){
}, const files = Array.prototype.slice.call(ev.dataTransfer.files)
on_dragleave : (ev)=>{ const jsons = files.filter(f=>f.type === "application/json")
ev.target.classList.toggle("border-info") if(confirm("Confirm import of method files?")){
}, this.importMethods(files)
on_drop : (ev)=>{ }
if(ev.dataTransfer && ev.dataTransfer.files && ev.dataTransfer.files.length){ ev.preventDefault()
const files = Array.prototype.slice.call(ev.dataTransfer.files) ev.stopPropagation()
const zips = files.filter(f=>f.type === "application/json") }
if(confirm("Confirm import of method files?")){ ev.target.classList.toggle("border-info")
this.importMethods(files) },
}
}
ev.target.classList.toggle("border-info")
},
recurse : [ recurse : [
{ {
target : "li", target : "li.ccp-process-category",
"in" : (e,d)=>Object.keys(this.#filtered), "in" : (e,d)=>Object.keys(this.#filtered),
on_click : ev=>{
if(ev.target.getAttribute("name") === "export_category"){
this.exportCategory(ev.currentTarget.bss_input.data)
}
},
recurse : [ recurse : [
{ {
target : "summary > h5", target : "summary",
apply : (e,d)=>{ apply : (e,d)=>{
const executables = this.#filtered[d].filter(m=>m.executable).length const executables = this.#filtered[d].filter(m=>m.executable).length
e.innerHTML = ` e.querySelector("h5").textContent = d
${d} <span title="Number of non executable versions" class="badge badge-danger float-right">${this.#filtered[d].length - executables}</span> e.querySelector("span[name=count_notexecutables]").textContent = this.#filtered[d].length - executables
<span title="Number of executable versions" class="badge badge-success mr-1 float-right">${executables}</span>` } e.querySelector("span[name=count_executables]").textContent = executables
}
}, },
{ {
target : "details ul[name=process_list]", target : "details ul[name=process_list]",
@ -255,6 +305,11 @@ class CCPMethodList2 extends HTMLElement{
{ {
target : "li.ccp-process", target : "li.ccp-process",
"in" : (e,d)=>this.#filtered[d], "in" : (e,d)=>this.#filtered[d],
on_click : ev=>{
if(ev.target.getAttribute("name") === "export_method"){
this.exportMethod(ev.currentTarget.bss_input.data.id)
}
},
on_dragstart : ev=>{ on_dragstart : ev=>{
ev.dataTransfer.effectAllowed = 'move' ev.dataTransfer.effectAllowed = 'move'
ev.dataTransfer.setData('text/html', ev.currentTarget.innerHTML) ev.dataTransfer.setData('text/html', ev.currentTarget.innerHTML)