diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ae0c72e67049a82812803d3c6b11d89b8eaf5850..b8d20acb6c365ad8036a7b36d47dabd876d08efa 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,3 +1,3 @@ include: - - project: 'quiqqer/semantic-release' + - project: 'quiqqer/stabilization/semantic-release' file: '/ci-templates/.gitlab-ci.yml' diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000000000000000000000000000000000000..1d5a563bae502c447548c4ab4891777c2637a2b7 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,55 @@ +{ + "bitwise": true, + "curly": true, + "esversion": 11, + "forin": true, + "freeze": true, + "futurehostile": true, + "latedef": "nofunc", + "maxdepth": 3, + "nonbsp": true, + "nonew": true, + "noreturnawait": true, + "shadow": "outer", + "strict": true, + "undef": true, + "unused": true, + + "browser": true, + "devel": true, + "mootools": true, + + "globals": { + "QUI": false, + "QUILocale": false, + + "QUIQQER": false, + "QUIQQER_PROJECT": false, + "QUIQQER_SITE": false, + "QUIQQER_ONLOAD_MODULES": false, + "QUIQQER_FRONTEND": false, + "QUIQQER_LOCALE": false, + "QUIQQER_USER": false, + "QUIQQER_PRIVACY_POLICY_URL": false, + + "URL_DIR": false, + "URL_OPT_DIR": false, + "URL_BIN_DIR": false, + "URL_LIB_DIR": false, + "URL_VAR_DIR": false, + "URL_PROJECT_DIR": false, + "URL_TEMPLATE_DIR": false, + + "Fx": false, + "Locale": false, + "moofx": false, + "require": false, + "requirejs": false, + "define": false, + "quiIsLoaded": false, + "whenQuiLoaded": false, + "GDPR": false, + "JSON": false, + "Element": false + } +} diff --git a/bin/.jshintrc b/bin/.jshintrc new file mode 100644 index 0000000000000000000000000000000000000000..1d5a563bae502c447548c4ab4891777c2637a2b7 --- /dev/null +++ b/bin/.jshintrc @@ -0,0 +1,55 @@ +{ + "bitwise": true, + "curly": true, + "esversion": 11, + "forin": true, + "freeze": true, + "futurehostile": true, + "latedef": "nofunc", + "maxdepth": 3, + "nonbsp": true, + "nonew": true, + "noreturnawait": true, + "shadow": "outer", + "strict": true, + "undef": true, + "unused": true, + + "browser": true, + "devel": true, + "mootools": true, + + "globals": { + "QUI": false, + "QUILocale": false, + + "QUIQQER": false, + "QUIQQER_PROJECT": false, + "QUIQQER_SITE": false, + "QUIQQER_ONLOAD_MODULES": false, + "QUIQQER_FRONTEND": false, + "QUIQQER_LOCALE": false, + "QUIQQER_USER": false, + "QUIQQER_PRIVACY_POLICY_URL": false, + + "URL_DIR": false, + "URL_OPT_DIR": false, + "URL_BIN_DIR": false, + "URL_LIB_DIR": false, + "URL_VAR_DIR": false, + "URL_PROJECT_DIR": false, + "URL_TEMPLATE_DIR": false, + + "Fx": false, + "Locale": false, + "moofx": false, + "require": false, + "requirejs": false, + "define": false, + "quiIsLoaded": false, + "whenQuiLoaded": false, + "GDPR": false, + "JSON": false, + "Element": false + } +} diff --git a/bin/Panel.js b/bin/Panel.js new file mode 100644 index 0000000000000000000000000000000000000000..73527c023b78cb154e9584139d4a2feeedf67871 --- /dev/null +++ b/bin/Panel.js @@ -0,0 +1,351 @@ +/** + * Redirect panel + * + * @module package/quiqqer/redirect/bin/controls/Panel + * @author www.pcsg.de (Jan Wennrich) + * + */ +define('package/quiqqer/redirect/bin/controls/Panel', [ + + 'qui/QUI', + 'qui/controls/desktop/Panel', + 'qui/controls/buttons/Select', + 'qui/controls/buttons/Separator', + 'qui/controls/windows/Confirm', + + 'package/quiqqer/redirect/bin/Handler', + + 'controls/grid/Grid', + 'Locale' + +], function (QUI, QUIPanel, QUISelect, QUIButtonSeparator, QUIConfirm, RedirectHandler, Grid, QUILocale) { + "use strict"; + + var lg = 'quiqqer/redirect'; + + return new Class({ + + Extends: QUIPanel, + Type : 'package/quiqqer/redirect/bin/controls/Panel', + + Binds: [ + 'loadData', + 'openSearch', + 'openClear', + '$onCreate', + '$onInject', + '$onResize', + 'deleteRedirect', + 'openAddRedirectDialog', + 'editRedirect', + 'getSelectedProjectData', + 'startSearch' + ], + + $ProjectSelect: null, + + initialize: function (options) { + this.setAttributes({ + icon : 'fa fa-share', + title: QUILocale.get('quiqqer/redirect', 'panel.title') + }); + + this.parent(options); + + this.$Grid = null; + this.$SearchInput = null; + + this.addEvents({ + onCreate: this.$onCreate, + onResize: this.$onResize, + onInject: this.$onInject + }); + }, + + /** + * event : on create + */ + $onCreate: function () { + var self = this; + + // Buttons + this.addButton({ + name : 'redirect-add', + text : QUILocale.get(lg, 'panel.button.redirect.add'), + textimage: 'fa fa-plus', + events : { + onClick: this.openAddRedirectDialog + } + }); + + this.addButton(new QUIButtonSeparator()); + + this.addButton({ + name : 'redirect-edit', + text : QUILocale.get(lg, 'panel.button.redirect.edit'), + textimage: 'fa fa-pencil', + disabled : true, + events : { + onClick: this.editRedirect + } + }); + + this.addButton({ + name : 'redirect-delete', + text : QUILocale.get(lg, 'panel.button.redirect.delete'), + textimage: 'fa fa-trash', + disabled : true, + events : { + onClick: this.deleteRedirect + }, + styles : { + float: 'right' + } + }); + + this.$SearchInput = new Element('input', { + placeholder: QUILocale.get(lg, 'panel.input.search.placeholder'), + styles : { + 'float': 'right', + margin : 10, + width : 200 + }, + events : { + keyup: (e) => { + e.stop(); + + if (e.key === 'enter') { + this.startSearch(); + } + } + } + }); + + this.getButtonBar().appendChild(this.$SearchInput); + + // Grid + var Container = new Element('div').inject( + this.getContent() + ); + + this.$Grid = new Grid(Container, { + columnModel: [{ + header : QUILocale.get(lg, 'window.redirect.url.source'), + dataIndex: 'source_url', + dataType : 'string', + width : 500 + }, { + header : QUILocale.get(lg, 'window.redirect.url.target'), + dataIndex: 'target_url', + dataType : 'string', + width : 500 + }], + + onrefresh : self.loadData, + pagination: true, + filterInput: false, + + perPage: 25, + + multipleSelection: true + }); + + this.$Grid.addEvents({ + onClick : function () { + self.getButtons('redirect-edit').disable(); + + if (self.$Grid.getSelectedIndices().length === 1) { + self.getButtons('redirect-edit').enable(); + } + + self.getButtons('redirect-delete').enable(); + }, + onDblClick: self.editRedirect + }); + }, + + + /** + * event : on inject + */ + $onInject: function () { + var self = this; + require(['controls/projects/Select'], function (ProjectSelect) { + self.$ProjectSelect = new ProjectSelect({ + emptyselect: false, + events : { + onChange: self.loadData + }, + project: QUIQQER_PROJECT.name, + lang: QUIQQER_PROJECT.lang, + }); + + self.addButton(self.$ProjectSelect); + }); + }, + + + /** + * event : on resize + */ + $onResize: function () { + if (!this.$Grid) { + return; + } + + var Content = this.getContent(); + + if (!Content) { + return; + } + + var size = Content.getSize(); + + this.$Grid.setHeight(size.y - 40); + + this.$Grid.setWidth(size.x - 40); + }, + + /** + * Load the grid data for the currently selected project-name and -language + */ + loadData: function () { + if (!this.$Grid) { + return; + } + + this.Loader.show(); + + var self = this; + + var selectedProjectData = self.getSelectedProjectData(), + projectName = selectedProjectData[0], + projectLanguage = selectedProjectData[1]; + + RedirectHandler.getRedirectsForGrid( + projectName, + projectLanguage, + self.$Grid.getAttribute('page'), + self.$Grid.getAttribute('perPage'), + self.$SearchInput.value + ).then(function (result) { + self.$Grid.setData({ + data : result.data, + page : result.page, + total: result.total + }); + self.Loader.hide(); + }); + }, + + /** + * Opens the add-redirect-dialog-popup + */ + openAddRedirectDialog: function () { + var self = this; + require(['package/quiqqer/redirect/bin/controls/window/AddRedirect'], function (AddRedirectPopup) { + var selectedProjectData = self.getSelectedProjectData(); + + if (!selectedProjectData) { + QUI.getMessageHandler().then(function (MessageHandler) { + MessageHandler.addAttention( + QUILocale.get(lg, 'panel.error.projectData.missing.message'), + self.$ProjectSelect.getElm() + ); + }); + return; + } + + new AddRedirectPopup({ + projectName : selectedProjectData[0], + projectLanguage: selectedProjectData[1], + events : { + onClose: self.loadData + } + }).open(); + }); + }, + + + /** + * Delete the (in the grid) selected redirects + */ + deleteRedirect: function () { + var self = this; + + var sourceUrls = this.$Grid.getSelectedData().map(function (data) { + return data.source_url; + }); + + + new QUIConfirm({ + icon : 'fa fa-trash', + title : QUILocale.get(lg, 'window.redirect.delete.title'), + maxHeight: 300, + maxWidth : 450, + ok_button: { + text : QUILocale.get(lg, 'window.redirect.delete.button.ok.text'), + textimage: 'fa fa-trash' + }, + events : { + onOpen: function (Win) { + Win.getContent().set('html', QUILocale.get( + lg, + 'window.redirect.delete.text', {urls: sourceUrls.toString()}) + ); + }, + + onSubmit: function () { + var selectedProjectData = self.getSelectedProjectData(); + RedirectHandler.deleteRedirects( + sourceUrls, + selectedProjectData[0], + selectedProjectData[1] + ).then(self.loadData); + } + } + }).open(); + }, + + + editRedirect: function () { + var self = this; + require(['package/quiqqer/redirect/bin/controls/window/AddRedirect'], function (AddRedirectPopup) { + var selectedProjectData = self.getSelectedProjectData(); + + new AddRedirectPopup({ + sourceUrlReadOnly: true, + sourceUrl : self.$Grid.getSelectedData()[0].source_url, + targetUrl : self.$Grid.getSelectedData()[0].target_url, + projectName : selectedProjectData[0], + projectLanguage : selectedProjectData[1], + events : { + onClose: self.loadData + } + }).open(); + }); + }, + + + /** + * Returns an array ofdata about the selected project. + * First entry in the array is the project's name, the second entry is the project's language + * + * @return {string[]} + */ + getSelectedProjectData: function () { + var value = this.$ProjectSelect.getValue(); + + if (!value) { + return null; + } + + return value.split(','); + }, + + startSearch: function () { + // loadData uses value from search input to query redirects containing the search term + this.loadData(); + } + }); +}); diff --git a/bin/TestPanel.js b/bin/TestPanel.js new file mode 100644 index 0000000000000000000000000000000000000000..73527c023b78cb154e9584139d4a2feeedf67871 --- /dev/null +++ b/bin/TestPanel.js @@ -0,0 +1,351 @@ +/** + * Redirect panel + * + * @module package/quiqqer/redirect/bin/controls/Panel + * @author www.pcsg.de (Jan Wennrich) + * + */ +define('package/quiqqer/redirect/bin/controls/Panel', [ + + 'qui/QUI', + 'qui/controls/desktop/Panel', + 'qui/controls/buttons/Select', + 'qui/controls/buttons/Separator', + 'qui/controls/windows/Confirm', + + 'package/quiqqer/redirect/bin/Handler', + + 'controls/grid/Grid', + 'Locale' + +], function (QUI, QUIPanel, QUISelect, QUIButtonSeparator, QUIConfirm, RedirectHandler, Grid, QUILocale) { + "use strict"; + + var lg = 'quiqqer/redirect'; + + return new Class({ + + Extends: QUIPanel, + Type : 'package/quiqqer/redirect/bin/controls/Panel', + + Binds: [ + 'loadData', + 'openSearch', + 'openClear', + '$onCreate', + '$onInject', + '$onResize', + 'deleteRedirect', + 'openAddRedirectDialog', + 'editRedirect', + 'getSelectedProjectData', + 'startSearch' + ], + + $ProjectSelect: null, + + initialize: function (options) { + this.setAttributes({ + icon : 'fa fa-share', + title: QUILocale.get('quiqqer/redirect', 'panel.title') + }); + + this.parent(options); + + this.$Grid = null; + this.$SearchInput = null; + + this.addEvents({ + onCreate: this.$onCreate, + onResize: this.$onResize, + onInject: this.$onInject + }); + }, + + /** + * event : on create + */ + $onCreate: function () { + var self = this; + + // Buttons + this.addButton({ + name : 'redirect-add', + text : QUILocale.get(lg, 'panel.button.redirect.add'), + textimage: 'fa fa-plus', + events : { + onClick: this.openAddRedirectDialog + } + }); + + this.addButton(new QUIButtonSeparator()); + + this.addButton({ + name : 'redirect-edit', + text : QUILocale.get(lg, 'panel.button.redirect.edit'), + textimage: 'fa fa-pencil', + disabled : true, + events : { + onClick: this.editRedirect + } + }); + + this.addButton({ + name : 'redirect-delete', + text : QUILocale.get(lg, 'panel.button.redirect.delete'), + textimage: 'fa fa-trash', + disabled : true, + events : { + onClick: this.deleteRedirect + }, + styles : { + float: 'right' + } + }); + + this.$SearchInput = new Element('input', { + placeholder: QUILocale.get(lg, 'panel.input.search.placeholder'), + styles : { + 'float': 'right', + margin : 10, + width : 200 + }, + events : { + keyup: (e) => { + e.stop(); + + if (e.key === 'enter') { + this.startSearch(); + } + } + } + }); + + this.getButtonBar().appendChild(this.$SearchInput); + + // Grid + var Container = new Element('div').inject( + this.getContent() + ); + + this.$Grid = new Grid(Container, { + columnModel: [{ + header : QUILocale.get(lg, 'window.redirect.url.source'), + dataIndex: 'source_url', + dataType : 'string', + width : 500 + }, { + header : QUILocale.get(lg, 'window.redirect.url.target'), + dataIndex: 'target_url', + dataType : 'string', + width : 500 + }], + + onrefresh : self.loadData, + pagination: true, + filterInput: false, + + perPage: 25, + + multipleSelection: true + }); + + this.$Grid.addEvents({ + onClick : function () { + self.getButtons('redirect-edit').disable(); + + if (self.$Grid.getSelectedIndices().length === 1) { + self.getButtons('redirect-edit').enable(); + } + + self.getButtons('redirect-delete').enable(); + }, + onDblClick: self.editRedirect + }); + }, + + + /** + * event : on inject + */ + $onInject: function () { + var self = this; + require(['controls/projects/Select'], function (ProjectSelect) { + self.$ProjectSelect = new ProjectSelect({ + emptyselect: false, + events : { + onChange: self.loadData + }, + project: QUIQQER_PROJECT.name, + lang: QUIQQER_PROJECT.lang, + }); + + self.addButton(self.$ProjectSelect); + }); + }, + + + /** + * event : on resize + */ + $onResize: function () { + if (!this.$Grid) { + return; + } + + var Content = this.getContent(); + + if (!Content) { + return; + } + + var size = Content.getSize(); + + this.$Grid.setHeight(size.y - 40); + + this.$Grid.setWidth(size.x - 40); + }, + + /** + * Load the grid data for the currently selected project-name and -language + */ + loadData: function () { + if (!this.$Grid) { + return; + } + + this.Loader.show(); + + var self = this; + + var selectedProjectData = self.getSelectedProjectData(), + projectName = selectedProjectData[0], + projectLanguage = selectedProjectData[1]; + + RedirectHandler.getRedirectsForGrid( + projectName, + projectLanguage, + self.$Grid.getAttribute('page'), + self.$Grid.getAttribute('perPage'), + self.$SearchInput.value + ).then(function (result) { + self.$Grid.setData({ + data : result.data, + page : result.page, + total: result.total + }); + self.Loader.hide(); + }); + }, + + /** + * Opens the add-redirect-dialog-popup + */ + openAddRedirectDialog: function () { + var self = this; + require(['package/quiqqer/redirect/bin/controls/window/AddRedirect'], function (AddRedirectPopup) { + var selectedProjectData = self.getSelectedProjectData(); + + if (!selectedProjectData) { + QUI.getMessageHandler().then(function (MessageHandler) { + MessageHandler.addAttention( + QUILocale.get(lg, 'panel.error.projectData.missing.message'), + self.$ProjectSelect.getElm() + ); + }); + return; + } + + new AddRedirectPopup({ + projectName : selectedProjectData[0], + projectLanguage: selectedProjectData[1], + events : { + onClose: self.loadData + } + }).open(); + }); + }, + + + /** + * Delete the (in the grid) selected redirects + */ + deleteRedirect: function () { + var self = this; + + var sourceUrls = this.$Grid.getSelectedData().map(function (data) { + return data.source_url; + }); + + + new QUIConfirm({ + icon : 'fa fa-trash', + title : QUILocale.get(lg, 'window.redirect.delete.title'), + maxHeight: 300, + maxWidth : 450, + ok_button: { + text : QUILocale.get(lg, 'window.redirect.delete.button.ok.text'), + textimage: 'fa fa-trash' + }, + events : { + onOpen: function (Win) { + Win.getContent().set('html', QUILocale.get( + lg, + 'window.redirect.delete.text', {urls: sourceUrls.toString()}) + ); + }, + + onSubmit: function () { + var selectedProjectData = self.getSelectedProjectData(); + RedirectHandler.deleteRedirects( + sourceUrls, + selectedProjectData[0], + selectedProjectData[1] + ).then(self.loadData); + } + } + }).open(); + }, + + + editRedirect: function () { + var self = this; + require(['package/quiqqer/redirect/bin/controls/window/AddRedirect'], function (AddRedirectPopup) { + var selectedProjectData = self.getSelectedProjectData(); + + new AddRedirectPopup({ + sourceUrlReadOnly: true, + sourceUrl : self.$Grid.getSelectedData()[0].source_url, + targetUrl : self.$Grid.getSelectedData()[0].target_url, + projectName : selectedProjectData[0], + projectLanguage : selectedProjectData[1], + events : { + onClose: self.loadData + } + }).open(); + }); + }, + + + /** + * Returns an array ofdata about the selected project. + * First entry in the array is the project's name, the second entry is the project's language + * + * @return {string[]} + */ + getSelectedProjectData: function () { + var value = this.$ProjectSelect.getValue(); + + if (!value) { + return null; + } + + return value.split(','); + }, + + startSearch: function () { + // loadData uses value from search input to query redirects containing the search term + this.loadData(); + } + }); +}); diff --git a/change_me.txt b/change_me.txt index 0f86fc28b53a60c0f14675339398f9c82d30a281..f57b8e00a2b688b28846c66cf01cba46d7674a31 100644 --- a/change_me.txt +++ b/change_me.txt @@ -38,3 +38,7 @@ salz brezel wurst kartoffel +update +seife +hand +bagel