openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit e2b2410fe3ed53fd381928100576e27f22a0285b
parent 911e918782ea1b1954d8fce1011fa423261dbf28
Author: Jan Dankert <develop@jandankert.de>
Date:   Sat, 27 Nov 2021 04:39:51 +0100

Refactoring: Extract the api request form.js into a new api class which returns a promise.

Diffstat:
Amodules/cms/ui/themes/default/script/openrat/api.js | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmodules/cms/ui/themes/default/script/openrat/callback.js | 1-
Mmodules/cms/ui/themes/default/script/openrat/form.js | 206+++++++++++++++++++++++++++----------------------------------------------------
Mmodules/cms/ui/themes/default/script/plugin/jquery-plugin-orLinkify.js | 20++++++++++----------
Mmodules/template_engine/components/html/component_upload/upload.js | 34++++------------------------------
5 files changed, 183 insertions(+), 176 deletions(-)

diff --git a/modules/cms/ui/themes/default/script/openrat/api.js b/modules/cms/ui/themes/default/script/openrat/api.js @@ -0,0 +1,98 @@ +import $ from '../jquery-global.js'; +import Workbench from "./workbench.js"; +import Notice from "./notice.js"; +import Callback from "./callback.js"; + +/** + * Form. + * + * @constructor + */ +export default class Api { + + static modes = { + get : 1, + write : 2, + }; + + constructor() { + + this.notifyBrowser = false; + this.mode = Api.modes.get; + } + + + sendData = function( formData ) { + + console.debug( "API form data", formData ); + + let api = this; + return new Promise( (resolve, reject) => { + + let load = fetch( './api/', { 'method':'POST', body:formData } ); + + load.then( response => { + if ( ! response.ok ) + reject( "Failed to post" ); + + return response.json(); + }).then( data => { + + for( let value of data['notices'] ) { + + let notice = new Notice(); + notice.setContext( value.type, value.id, value.name ); + notice.log = value.log; + notice.setStatus( value.status ); + notice.msg = value.text; + notice.show(); + + if ( api.notifyBrowser ) + notice.notifyBrowser() + }; + + if ( data.success ) { // Kein Fehler? + resolve(); + } + else { + // Validation errors + for( name of data['errors'] ) + this.validationErrorForField( name ); + + reject('API request failed'); + } + + } ).catch( cause => { + + console.warn( { + message: 'API request failed', + cause : cause, + data : formData, + } ); + + let msg = ''; + try { + msg = JSON.parse( cause ).message; + } + catch( e ) { + msg = cause; + } + + let notice = new Notice(); + notice.setStatus('error'); + notice.msg = msg; + notice.log = cause; //JSON.stringify( $.parseJSON(jqXHR.responseText),null,2); + notice.show(); + + reject( msg ); + } ); + } ); + + } + + + validationErrorForField = function( nameOfField ) { + } + +} + diff --git a/modules/cms/ui/themes/default/script/openrat/callback.js b/modules/cms/ui/themes/default/script/openrat/callback.js @@ -28,7 +28,6 @@ export default class Callback { } -console.debug("registering callbacks"); Callback.afterViewLoadedHandler = new Callback(); Callback.dataChangedHandler = new Callback(); Callback.afterNewActionHandler = new Callback(); diff --git a/modules/cms/ui/themes/default/script/openrat/form.js b/modules/cms/ui/themes/default/script/openrat/form.js @@ -1,7 +1,8 @@ -import $ from '../jquery-global.js'; +import $ from '../jquery-global.js'; import Workbench from "./workbench.js"; -import Notice from "./notice.js"; -import Callback from "./callback.js"; +import Notice from "./notice.js"; +import Callback from "./callback.js"; +import Api from "./api.js"; /** * Form. @@ -26,6 +27,14 @@ export default class Form { this.onChangeHandler = new Callback(); this.onSaveHandler = new Callback(); this.onCloseHandler = new Callback(); + + this.async = false; + this.afterSuccess = ''; + this.element = null; + this.autosave = false; + this.mode = Form.modes.keepOpen; + this.formMethod = 'GET'; + this.forwardToMethod = null; } setLoadStatus( isLoading ) { @@ -35,12 +44,19 @@ export default class Form { initOnElement( element ) { this.element = element; - let form = this; + this.formMethod = $(this.element).attr('method').toUpperCase(); + this.afterSuccess = $(this.element).data('afterSuccess'); + this.forwardToMethod = $(this.element).data('forwardTo'); + this.async = $(this.element).data('async'); + + let form = this; // Autosave in Formularen. // Bei Veränderungen von Checkboxen wird das Formular sofort abgeschickt. if ( $(this.element).data('autosave') ) { + this.autosave = true; + $(this.element).find('input[type="checkbox"]').click( function() { form.submit(Form.modes.keepOpen); }); @@ -49,13 +65,6 @@ export default class Form { }); } - // After click to "OK" the form is submitted. - // Why this?? input type=submit will submit! - /* - $(event.target).find('input.submit.ok').click( function() { - $(this).closest('form').submit(); - }); - */ $(element).find('.or-act-form-cancel').click( function() { form.cancel(); @@ -109,7 +118,7 @@ export default class Form { submit( mode ) { if ( mode === undefined ) - if ( $(this.element).data('async') ) + if ( this.async ) mode = Form.modes.closeAfterSubmit; else mode = Form.modes.closeAfterSuccess; @@ -135,9 +144,8 @@ export default class Form { if (!formData.has('action') ) formData.append('action',Workbench.state.action); - let formMethod = $(this.element).attr('method').toUpperCase(); - if ( formMethod == 'GET' ) + if ( this.formMethod == 'GET' ) { // Mehrseitiges Formular // Die eingegebenen Formulardaten werden zur nächsten Action geschickt. @@ -146,143 +154,71 @@ export default class Form { } else { - let url = './api/'; // Alle Parameter befinden sich im Formular + if ( mode == Form.modes.closeAfterSubmit ) + this.onCloseHandler.fire(); + // Async: Window is closed, but the action will be startet now. - // POST-Request - this.setLoadStatus(true); - //url += '?output=json'; - url += ''; - //params['output'] = 'json';// Irgendwie geht das nicht. formData.append('output','json'); + this.sendFormData( formData ); + status.close(); + } - if ( mode == Form.modes.closeAfterSubmit ) - this.onCloseHandler.fire(); - // Async: Window is closed, but the action will be startet now. - - let form = this; - console.debug( form ); + } - let load = fetch( url, { 'method':'POST', body:formData } ); - load.then( response => { - if ( ! response.ok ) - throw "Failed to post"; + sendFormData = function( formData ) { - return response.json(); - }).then( data => { - form.setLoadStatus(false); - status.close(); + this.setLoadStatus(true); - form.doResponse(data, "", form.element, () => { + let form = this; - form.onSaveHandler.fire(); + let api = new Api(); + api.notifyBrowser = form.async; + api.validationErrorForField = (name) => { + $('.or-input[name='+name+']').addClass('input--error').parent().addClass('input--error').parents('.or-group').removeClass('closed').addClass('show').addClass('open'); + } - let afterSuccess = $(form.element).data('afterSuccess'); - let forwardTo = $(form.element).data('forwardTo'); - let async = $(form.element).data('async'); + let result = api.sendData( formData ); + let mode = 0; - if (afterSuccess == 'forward') - mode = Form.modes.keepOpen; + result.then( + () => { + form.onSaveHandler.fire(); + if (this.afterSuccess == 'forward') + mode = Form.modes.keepOpen; - // The data was successful saved. - // Now we can close the form. - if (mode == Form.modes.closeAfterSuccess) { - form.onCloseHandler.fire(); + // The data was successful saved. + // Now we can close the form. + if (mode == Form.modes.closeAfterSuccess) { + form.onCloseHandler.fire(); - // clear the dirty flag. - $(form.element).closest('div.panel').find('div.header ul.views li.action.active').removeClass('dirty'); - } + // clear the dirty flag. + $(form.element).closest('div.panel').find('div.header ul.views li.action.active').removeClass('dirty'); + } - if (afterSuccess) { - if (afterSuccess == 'reloadAll') { - Workbench.getInstance().reloadAll(); - } else if (afterSuccess == 'forward') { - // Forwarding to next subaction. - if (forwardTo) - form.forwardTo(formData.get('action'), forwardTo, formData.get('id'), []); - } - } else { - if (async) - ; // do not reload - else - Workbench.getInstance().reloadViews(); + if (form.afterSuccess) { + if (form.afterSuccess == 'reloadAll') { + Workbench.getInstance().reloadAll(); + } else if (form.afterSuccess == 'forward') { + // Forwarding to next subaction. + if (form.forwardToMethod) + form.forwardTo(formData.get('action'), form.forwardToMethod, formData.get('id'), []); } - - }) - } ).catch( cause => { - - console.warn( { - message:'could not post form', - cause: cause, - form:form, - } ); - - form.setLoadStatus(false); - status.close(); - - let msg = ''; - try { - msg = JSON.parse( cause ).message; - } - catch( e ) { - msg = cause; + } else { + if (async) + ; // do not reload + else + Workbench.getInstance().reloadViews(); } + //form.onSuccess(); + Callback.dataChangedHandler.fire(); + } + ).catch( (reason) => { - let notice = new Notice(); - notice.setStatus('error'); - notice.msg = msg; - notice.log = cause; //JSON.stringify( $.parseJSON(jqXHR.responseText),null,2); - notice.show(); - } ); - - //$(form.element).fadeIn(); TODO no effects available - } - - } - + }).finally( () => { + form.setLoadStatus(false); + }) - - /** - * HTTP-Antwort auf einen POST-Request auswerten. - * - * @param data Formulardaten - * @param status Status - * @param element - */ - doResponse = function(data,status,element, onSuccess = $.noop ) - { - let form = this; - // Hinweismeldungen in Statuszeile anzeigen - for( let value of data['notices'] ) { - - // Bei asynchronen Requests wird zusätzlich eine Browser-Notice erzeugt, da der - // Benutzer bei länger laufenden Aktionen vielleicht das Tab oder Fenster - // gewechselt hat. - let notifyBrowser = $(element).data('async'); - - let notice = new Notice(); - notice.setContext( value.type, value.id, value.name ); - notice.log = value.log; - notice.setStatus( value.status ); - notice.msg = value.text; - notice.show(); - - if ( notifyBrowser ) - notice.notifyBrowser() - }; - - if ( data.success ) { // Kein Fehler? - onSuccess(); - Callback.dataChangedHandler.fire(); - } - else - ; // Server liefert Fehler zurück. - - // Validation error should mark the input field. - for( name of data['errors'] ) - $('.or-input[name='+name+']').addClass('input--error').parent().addClass('input--error').parents('.or-group').removeClass('closed').addClass('show').addClass('open'); - - // Jetzt das erhaltene Dokument auswerten. - } + } } diff --git a/modules/cms/ui/themes/default/script/plugin/jquery-plugin-orLinkify.js b/modules/cms/ui/themes/default/script/plugin/jquery-plugin-orLinkify.js @@ -1,6 +1,8 @@ import $ from "../jquery-global.js"; import Workbench from "../openrat/workbench.js"; import Dialog from "../openrat/dialog.js"; +import Form from "../openrat/form.js"; +import Api from "../openrat/api.js"; /** * JQuery-Plugin, enable clicking on an area. @@ -53,22 +55,20 @@ export default function( options ) */ case 'post': - // Create a temporary form element. - let $form = $('<form />').attr('method','POST').addClass('invisible'); - $form.data('afterSuccess', $link.data('afterSuccess')); + let api = new Api(); + api.mode = Api.modes.write; + let formData = new FormData(); + let params = JSON.parse( $link.attr('data-data') ); params.output = 'json'; - // Add input elements... - $.each( params, function(key,value) { - let $input = $('<input />').attr('type','hidden').attr('name',key).attr('value',value); - $form.append( $input ); + // Add formular data... + Object.keys( params ).forEach( (key) => { + formData.append( key, params[key] ); } ); // Submit the form. - let form = new Form(); - form.initOnElement( $form ); - form.submit(); + api.sendData( formData ); break; diff --git a/modules/template_engine/components/html/component_upload/upload.js b/modules/template_engine/components/html/component_upload/upload.js @@ -1,5 +1,6 @@ import Workbench from "../../../../cms/ui/themes/default/script/openrat/workbench.js"; -import $ from '../../../../cms/ui/themes/default/script/jquery-global.js'; +import Api from "../../../../cms/ui/themes/default/script/openrat/api.js"; +import $ from "../../../../cms/ui/themes/default/script/jquery-global.js"; export default function (element ) { @@ -54,37 +55,10 @@ Workbench.handleFileUpload = function(form,files) form_data.append('file' , f); form_data.append('action' ,'folder'); form_data.append('subaction',$(form).data('method')); - form_data.append('output' ,'json'); form_data.append('token' ,$(form).find('input[name=token]').val() ); form_data.append('id' ,$(form).find('input[name=id]' ).val() ); - - let notice = new Notice(); - notice.inProgress(); - notice.show(); - let url ='./api/'; - let load = fetch( url, { - method: 'POST' - } ); - - load.then( response => { - return response.json(); - }).then( data => { - - notice.close(); - let oform = new Form(); - oform.doResponse(data,"",form); - } ).catch( error => { - - notice.close(); - - console.error(error); - let notice = new Notice(); - notice.setStatus('error'); - notice.msg = 'Upload error'; - notice.log = error; - notice.show(); - } - ); + let form = new Api(); + form.sendData( form_data ); } }