From fabc61db97f1f44cb729d0c3fa46480d83dc245e Mon Sep 17 00:00:00 2001 From: andreas Date: Sun, 1 Dec 2024 20:18:36 +0100 Subject: [PATCH] #372: allow icon upload directly in user app dialog --- viewer/components/OverlayDialogDisplay.jsx | 2 +- viewer/components/UserAppDialog.jsx | 123 +++++++++++++++------ 2 files changed, 92 insertions(+), 33 deletions(-) diff --git a/viewer/components/OverlayDialogDisplay.jsx b/viewer/components/OverlayDialogDisplay.jsx index d7a78f15d..965e58854 100644 --- a/viewer/components/OverlayDialogDisplay.jsx +++ b/viewer/components/OverlayDialogDisplay.jsx @@ -35,7 +35,7 @@ class OverlayDialog extends React.Component { this.container=el} onClick={this.props.closeCallback}>
this.box=el} className={className} onClick={ (ev)=>{ - ev.preventDefault(); + //ev.preventDefault(); ev.stopPropagation(); } }> diff --git a/viewer/components/UserAppDialog.jsx b/viewer/components/UserAppDialog.jsx index 74efa139c..84acbdd40 100644 --- a/viewer/components/UserAppDialog.jsx +++ b/viewer/components/UserAppDialog.jsx @@ -9,7 +9,15 @@ import Addons from './Addons.js'; import Helper from '../util/helper.js'; import Requests from '../util/requests.js'; import GuiHelpers, {stateHelper} from '../util/GuiHelpers.js'; +import UploadHandler from "./UploadHandler"; +const contains=(list,url,opt_key)=>{ + if (opt_key === undefined) opt_key="url"; + for (let k=0;k{ + let itemList=[]; + let activeUrl; + if (data.items) { + data.items.forEach((el)=> { + if (GuiHelpers.IMAGES.indexOf(Helper.getExt(el.name)) >= 0) { + if (! contains(this.state.iconList,el.url)) { + el.label = el.url; + el.value = el.url; + itemList.push(el); + } + if (opt_active !== undefined && el.name === opt_active){ + activeUrl=el.url; + } + } + }); + this.setState( (prevState)=>{ + return {iconList: prevState.iconList.concat(itemList)} + }); + } + if (activeUrl !== undefined){ + this.stateHelper.setState({ + icon:activeUrl + }); + } + }) + .catch((error)=>{}) + } fillLists(){ - let self=this; Requests.getJson("?request=list&type=user") .then((data)=>{ let iconList=[]; @@ -33,9 +71,11 @@ export default class UserAppDialog extends React.Component{ if (data.items){ data.items.forEach((el)=>{ if (GuiHelpers.IMAGES.indexOf(Helper.getExt(el.name)) >= 0){ - el.label=el.url; - el.value=el.url; - iconList.push(el); + if (! contains(this.state.iconList,el.url)) { + el.label = el.url; + el.value = el.url; + iconList.push(el); + } } if (Helper.getExt(el.name) === 'html'){ el.label=el.url; @@ -43,30 +83,18 @@ export default class UserAppDialog extends React.Component{ userFiles.push(el); } }); - self.setState({ - iconList:self.state.iconList.concat(iconList), - userFiles:userFiles - }); - } - }).catch((error)=>{}); - Requests.getJson("?request=list&type=images") - .then((data)=>{ - let itemList=[]; - if (data.items) { - data.items.forEach((el)=> { - if (GuiHelpers.IMAGES.indexOf(Helper.getExt(el.name)) >= 0) { - el.label=el.url; - el.value=el.url; - itemList.push(el); + this.setState( (prevState)=> { + return { + iconList: prevState.iconList.concat(iconList), + userFiles: userFiles } }); - self.setState({iconList: self.state.iconList.concat(itemList)}); } - }) - .catch((error)=>{}) + }).catch((error)=>{}); + this.readImages(); if (!this.state.loaded) Addons.readAddOns() .then((addons)=>{ - let current=Addons.findAddonByUrl(addons,self.props.fixed.url) + let current=Addons.findAddonByUrl(addons,this.props.fixed.url) if (current) this.stateHelper.setState(assign({},current,this.props.fixed)); this.setState({loaded:true}) }) @@ -93,13 +121,12 @@ export default class UserAppDialog extends React.Component{ } render(){ - let self=this; let fixed=this.props.fixed||{}; let canEdit=this.stateHelper.getValue('canDelete',true); if (!this.state.loaded) canEdit=false; let fixedUrl=fixed.url !== undefined; let title=""; - if (canEdit)title=fixed?"Modify ":"Create "; + if (canEdit)title=fixed.name?"Modify ":"Create "; return(
@@ -128,16 +155,41 @@ export default class UserAppDialog extends React.Component{ value={this.stateHelper.getValue('url','')} minSize={50} maxSize={100} - onChange={(val)=>self.stateHelper.setState({url:val})}/> + className={this.stateHelper.getValue('url')?"":"missing"} + onChange={(val)=>this.stateHelper.setState({url:val})}/> : self.stateHelper.setState({url:selected.url})}/> + onChange={(selected)=>this.stateHelper.setState({url:selected.url})}/> } + { + this.readImages(param.param.name); + }} + errorCallback={(err)=>{if (err) Toast(err);}} + uploadSequence={this.state.uploadSequence} + checkNameCallback={(name)=>{ + return new Promise((resolve,reject)=>{ + if (contains(this.state.iconList,name,"name")){ + reject(name+" already exists"); + return; + } + let ext=Helper.getExt(name); + let rt={name:name}; + if (GuiHelpers.IMAGES.indexOf(ext) < 0){ + reject("only images of types "+GuiHelpers.IMAGES.join(",")); + return; + } + resolve(rt); + });}} + /> } {canEdit ? @@ -147,7 +199,7 @@ export default class UserAppDialog extends React.Component{ value={this.stateHelper.getValue('title','')} minSize={50} maxSize={100} - onChange={(value)=>{self.stateHelper.setState({title:value})}} + onChange={(value)=>{this.stateHelper.setState({title:value})}} /> : this.stateHelper.setState({ + className={this.stateHelper.getValue('icon')?"":"missing"} + onChange={(selected)=>{ + if (selected.upload) { + this.setState({uploadSequence: this.state.uploadSequence + 1}); + return; + } + this.stateHelper.setState({ icon:selected.url - })} + }); + }} > {this.stateHelper.getValue('icon') && } @@ -190,7 +249,7 @@ export default class UserAppDialog extends React.Component{
{(this.stateHelper.getValue('name') && this.stateHelper.getValue('canDelete') && canEdit) && { - self.dialogHelper.showDialog(OverlayDialog.createConfirmDialog("really delete User App?", + this.dialogHelper.showDialog(OverlayDialog.createConfirmDialog("really delete User App?", ()=>{ this.props.closeCallback(); this.props.removeFunction(this.stateHelper.getValue('name'));