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" />
</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(){
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){
if(this.#locked) return;
this.lockRender()
@ -407,7 +379,6 @@ class CCPMethodEditorController extends HTMLElement{
<div class="ccp-toolbar-right">
${this.renderSaveButton()}
${this.renderResetButton()}
${this.renderDownloadButton()}
${ this.#isupdate ? this.renderDeleteButton() : "" }
</div>
</div>
@ -562,12 +533,6 @@ class CCPMethodEditorController extends HTMLElement{
this.saveMethod()
})
this.#rootdoc.querySelector("button[name=download]").addEventListener("click", ev=>{
ev.preventDefault()
ev.stopPropagation()
this.downloadMethod()
})
if(this.#isupdate){
this.#rootdoc.querySelector("button[name=delete]").addEventListener("click", ev=>{
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(){
return `
<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;
cursor: pointer;
}
.ccp-toolbar-button > svg {
width: 24px;
height:24px;
fill: white;
stroke: white;
.ccp-toolbar-button svg {
display: block;
fill: white;
width: 24px;
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{
list-style:none;
@ -60,22 +69,34 @@ class CCPMethodList2 extends HTMLElement{
}
</style>
<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">
<details>
<summary>
<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>
<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">
<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="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>
<p style="margin-top:.5rem" class="small" name="description"></p>
<div>
@ -194,59 +215,88 @@ class CCPMethodList2 extends HTMLElement{
}, {})
}
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.refreshExecutions()
}).catch(err=>{ alert(err) })
}
exportCategory(category){
Promise.all(
this.#filtered[category].map(m=>this.exportMethod(m.id))
)
}
exportMethod(method){
this.#boot.secureFetch(this.#serviceurl + "/methods/" + method + "/shareable").then(
(resp)=>{
if(resp.status === 200){
return resp.json()
}else throw "Error exporting 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)
}).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 = {
template : "#PROCESS_LIST_TEMPLATE",
target : "ul[name=process_category_list]",
"in" : this,
on_dragover : (ev)=>{
ev.preventDefault()
},
on_dragenter : (ev)=>{
ev.target.classList.toggle("border-info")
},
on_dragleave : (ev)=>{
ev.target.classList.toggle("border-info")
},
on_drop : (ev)=>{
if(ev.dataTransfer && ev.dataTransfer.files && ev.dataTransfer.files.length){
const files = Array.prototype.slice.call(ev.dataTransfer.files)
const zips = files.filter(f=>f.type === "application/json")
if(confirm("Confirm import of method files?")){
this.importMethods(files)
}
}
ev.target.classList.toggle("border-info")
},
on_dragover : (ev)=> ev.preventDefault(),
on_dragenter : (ev)=> ev.target.classList.toggle("border-info"),
on_dragleave : (ev)=> ev.target.classList.toggle("border-info"),
on_drop : (ev)=>{
if(ev.dataTransfer && ev.dataTransfer.files && ev.dataTransfer.files.length){
const files = Array.prototype.slice.call(ev.dataTransfer.files)
const jsons = files.filter(f=>f.type === "application/json")
if(confirm("Confirm import of method files?")){
this.importMethods(files)
}
ev.preventDefault()
ev.stopPropagation()
}
ev.target.classList.toggle("border-info")
},
recurse : [
{
target : "li",
target : "li.ccp-process-category",
"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 : [
{
target : "summary > h5",
target : "summary",
apply : (e,d)=>{
const executables = this.#filtered[d].filter(m=>m.executable).length
e.innerHTML = `
${d} <span title="Number of non executable versions" class="badge badge-danger float-right">${this.#filtered[d].length - executables}</span>
<span title="Number of executable versions" class="badge badge-success mr-1 float-right">${executables}</span>` }
e.querySelector("h5").textContent = d
e.querySelector("span[name=count_notexecutables]").textContent = this.#filtered[d].length - executables
e.querySelector("span[name=count_executables]").textContent = executables
}
},
{
target : "details ul[name=process_list]",
@ -255,6 +305,11 @@ class CCPMethodList2 extends HTMLElement{
{
target : "li.ccp-process",
"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=>{
ev.dataTransfer.effectAllowed = 'move'
ev.dataTransfer.setData('text/html', ev.currentTarget.innerHTML)