diff --git a/viewer/components/IconDialog.jsx b/viewer/components/IconDialog.jsx index 7ecc18b7..4d68d0b6 100644 --- a/viewer/components/IconDialog.jsx +++ b/viewer/components/IconDialog.jsx @@ -32,6 +32,8 @@ import GuiHelpers from "../util/GuiHelpers"; import Helper from "../util/helper"; import UploadHandler from "./UploadHandler"; import Toast from "./Toast"; +import globalStore from "../util/globalstore"; +import keys from "../util/keys"; const IMAGES_FLAG=1; const SOURCES=[ @@ -138,7 +140,7 @@ export const IconDialog=(props)=>{ label:'New', onClick:()=>setUploadSequence(uploadSequence+1), close:false, - visible: (props.allowUpload === undefined|| props.allowUpload), + visible: (props.allowUpload === undefined|| props.allowUpload) && globalStore.getData(keys.gui.capabilities.uploadImages), disabled: ! (sources & IMAGES_FLAG) }, DBCancel() diff --git a/viewer/components/UploadHandler.jsx b/viewer/components/UploadHandler.jsx index 7542c43a..d5a5caa1 100644 --- a/viewer/components/UploadHandler.jsx +++ b/viewer/components/UploadHandler.jsx @@ -61,7 +61,15 @@ class UploadHandler extends React.Component{ resolve({name: name}); }); } - return this.props.checkNameCallback(name); + let rt=this.props.checkNameCallback(name); + if (rt instanceof Promise) return rt; + return new Promise((resolve,reject)=>{ + if (typeof(rt) === 'object') { + if (!rt.error) resolve(rt); + else reject(rt.error); + } + else reject(rt); + }) } upload(file){ let self=this; diff --git a/viewer/components/UserAppDialog.jsx b/viewer/components/UserAppDialog.jsx index e265993d..2fd594db 100644 --- a/viewer/components/UserAppDialog.jsx +++ b/viewer/components/UserAppDialog.jsx @@ -1,47 +1,119 @@ import React, {useEffect, useState} from 'react'; import PropTypes from 'prop-types'; -import OverlayDialog, {useDialogContext} from './OverlayDialog.jsx'; +import OverlayDialog, {SelectList, showPromiseDialog, useDialogContext} from './OverlayDialog.jsx'; import Toast from './Toast.jsx'; -import {Checkbox,Input,InputReadOnly,InputSelect} from './Inputs.jsx'; +import {Checkbox,Input,InputReadOnly} from './Inputs.jsx'; import Addons from './Addons.js'; import Helper from '../util/helper.js'; import Requests from '../util/requests.js'; -import GuiHelpers from '../util/GuiHelpers.js'; import UploadHandler from "./UploadHandler"; import {DBCancel, DBOk, DialogButtons, DialogFrame} from "./OverlayDialog"; import {IconDialog} from "./IconDialog"; +import globalStore from "../util/globalstore"; +import keys from "../util/keys"; -const contains = (list, url, opt_key) => { - if (opt_key === undefined) opt_key = "url"; - for (let k = 0; k < list.length; k++) { - if (list[k][opt_key] === url) return true; - } - return false; -} -const UserAppDialog = (props) => { - const [currentAddon, setCurrentAddon] = useState({...props.addon, ...props.fixed}); - const dialogContext = useDialogContext(); - const [userFiles, setUserFiles] = useState([]); - const initiallyLoaded = (props.fixed || {}).url === undefined || props.addon !== undefined; - const [loaded, setLoaded] = useState(initiallyLoaded); - const [internal, setInternal] = useState(!(initiallyLoaded && (props.addon || {}).keepUrl)); - - const fillLists = () => { +const SelectHtmlDialog=({allowUpload,resolveFunction,current})=>{ + const dialogContext=useDialogContext(); + const [uploadSequence,setUploadSequence]=useState(0); + const [userFiles,setUserFiles]=useState([]); + const listFiles=(name)=>{ Requests.getJson("?request=list&type=user") .then((data) => { let nuserFiles = []; if (data.items) { data.items.forEach((el) => { if (Helper.getExt(el.name) === 'html') { - el.label = el.url; + el.label = el.name; el.value = el.url; + if (el.url === current) el.selected=true; nuserFiles.push(el); + if (name && el.name === name) { + resolveFunction(el.url); + dialogContext.closeDialog(); + } } }); setUserFiles(nuserFiles) } }).catch((error) => { }); + } + useEffect(() => { + listFiles(); + }, []); + const checkName=(name)=>{ + for (let i=0;i + { + if (name && name.substring(name.length-4).toUpperCase() === 'HTML') { + let err=checkName(name); + if (err) return err; + return {name: name} + } + return "only files of type html allowed"; + }} + doneCallback={(v)=>listFiles(v.param.name)} + errorCallback={(err)=>Toast(err)} + /> + { + dialogContext.closeDialog(); + resolveFunction(el.url); + }} + /> + { setUploadSequence((old)=>old+1)}, + visible: (allowUpload === undefined|| allowUpload) && globalStore.getData(keys.gui.capabilities.uploadUser), + close: false + }, + { + name: 'new', + label: 'New', + onClick:()=>{ + showPromiseDialog(dialogContext,OverlayDialog.createValueDialog("enter html filename"),"") + .then((name)=>{ + if (! name) throw Error("empty name"); + if (!Helper.getExt(name) === 'html') name+=".html"; + const err=checkName(name); + if (err) throw Error(err); + const data="\n\n\n\n\n\n"; + Requests.postPlain({ + request:'upload', + type: 'user', + name: name + }, data) + .then(()=>{ + listFiles(); + }) + }) + .catch((err)=>Toast(err+"")); + }, + visible: (allowUpload === undefined|| allowUpload) && globalStore.getData(keys.gui.capabilities.uploadUser), + close: false + }, + DBCancel() + + ]}/> + +} + +const UserAppDialog = (props) => { + const [currentAddon, setCurrentAddon] = useState({...props.addon, ...props.fixed}); + const dialogContext = useDialogContext(); + const initiallyLoaded = (props.fixed || {}).url === undefined || props.addon !== undefined; + const [loaded, setLoaded] = useState(initiallyLoaded); + const [internal, setInternal] = useState(!(initiallyLoaded && (props.addon || {}).keepUrl)); + const fillLists = () => { if (!loaded) Addons.readAddOns() .then((addons) => { let current = Addons.findAddonByUrl(addons, props.fixed.url) @@ -90,14 +162,21 @@ const UserAppDialog = (props) => { mandatory={(v) => !v} onChange={(val) => setCurrentAddon({...currentAddon, url: val})}/> : - !v} - list={userFiles} - showDialogFunction={dialogContext.showDialog} - onChange={(selected) => setCurrentAddon({...currentAddon, url: selected.url})}/> + onClick={()=>{ + dialogContext.showDialog(()=>{ + return + setCurrentAddon({...currentAddon,url:url}) + } + current={currentAddon.url} + /> + }) + }}/> } }