From 67ad042736109c8bde2eb0ac670de59d2202ce55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn?= Date: Thu, 22 Jul 2021 23:15:31 +0200 Subject: [PATCH] adding --- mix-manifest.json | 2 +- public/css/index.css | 10 +- public/js/create-bucket.js | 4556 +++++++++++++++++++++ public/js/critical.js | 149 +- public/js/dashboard.js | 2595 +++++++++++- public/js/index.js | 4650 +--------------------- resources/js/components/field-error.riot | 108 + resources/js/create-bucket.js | 27 + resources/js/critical.js | 2 +- resources/js/dashboard.js | 10 +- resources/js/index.js | 2 - resources/scss/components/_field.scss | 8 + resources/scss/index.scss | 6 +- resources/views/bucket/form.html | 10 +- resources/views/index.html | 4 +- resources/views/layout.html | 5 +- src/http/api/bucket.ts | 14 +- src/http/bucket.ts | 1 + webpack.mix.js | 2 +- 19 files changed, 7470 insertions(+), 4691 deletions(-) create mode 100644 public/js/create-bucket.js create mode 100644 resources/js/components/field-error.riot create mode 100644 resources/js/create-bucket.js delete mode 100644 resources/js/index.js create mode 100644 resources/scss/components/_field.scss diff --git a/mix-manifest.json b/mix-manifest.json index ccf5629..83a95b5 100644 --- a/mix-manifest.json +++ b/mix-manifest.json @@ -1,7 +1,7 @@ { "/public/js/spritemap.js": "/public/js/spritemap.js", - "/public/js/index.js": "/public/js/index.js", "/public/js/critical.js": "/public/js/critical.js", + "/public/js/create-bucket.js": "/public/js/create-bucket.js", "/public/js/dashboard.js": "/public/js/dashboard.js", "/public/css/index.css": "/public/css/index.css", "/public/css/demo.html": "/public/css/demo.html", diff --git a/public/css/index.css b/public/css/index.css index 50b06af..03ad9c6 100644 --- a/public/css/index.css +++ b/public/css/index.css @@ -14919,15 +14919,19 @@ input[type=checkbox].field-choice:checked ~ .field-switch:after { color: var(--text); } +.field-error ul { + list-style: none; + padding: 0; +} + .container--app { max-width: 100%; padding: 15px 30px; } .turbolinks-progress-bar { - width: 5px; - height: 100%; - background-color: blue; + height: 5px; + background-color: var(--danger); } .app-header .logo { diff --git a/public/js/create-bucket.js b/public/js/create-bucket.js new file mode 100644 index 0000000..b33303f --- /dev/null +++ b/public/js/create-bucket.js @@ -0,0 +1,4556 @@ +/******/ (() => { // webpackBootstrap +/******/ var __webpack_modules__ = ({ + +/***/ "./resources/js/components/field-error.riot": +/*!**************************************************!*\ + !*** ./resources/js/components/field-error.riot ***! + \**************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ + 'css': null, + + 'exports': { + state: { + errors: [ + + ], + }, + + /** + * + * + * @param {Object} props [description] + * @param {Object} state [description] + * + */ + onMounted(props, state) + { + // getting parent element for entire field + const parent = this.root.closest('.field-group') + + // getting current element by name + const element = document.querySelector('[name="' + props.name + '"]') + + // getting form + const form = element.closest('form') + + // element, form are exists and nofieldupdate is not set + // each change of the element dispatch a event to form validation + if (element && form && !props.nofieldupdate) { + element.addEventListener('input', (event) => { + this.dispatchCustomEvent(event, form, props.name) + }) + } + + // add custom event to listen to form-validation + this.root.addEventListener('form-validation', (event) => { + this.onFormValidation(event, parent) + }) + }, + + /** + * process form validation triggered by form + * + * @param {Event} event + * @param {Element} parent + * + */ + onFormValidation(event, parent) + { + // if detail is a value, set to errors + if (event.detail) { + this.state.errors = event.detail + + parent.classList.add('field--error') + parent.classList.remove('field--valid') + } else { + this.state.errors = [] + + parent.classList.remove('field--error') + parent.classList.add('field--valid') + } + + this.update() + }, + + /** + * create event to send to form validation + * + * @param {Event} event + * @param {Element} form + * @param {string} name + * + */ + dispatchCustomEvent(event, form, name) + { + const fieldUpdateEvent = new CustomEvent('field-update', { + 'detail': { + 'name': name, + 'value': event.target.value + } + }) + + form.dispatchEvent(fieldUpdateEvent) + } + }, + + 'template': function( + template, + expressionTypes, + bindingTypes, + getComponent + ) { + return template( + '
', + [ + { + 'type': bindingTypes.IF, + + 'evaluate': function( + _scope + ) { + return _scope.state.errors.length > 0; + }, + + 'redundantAttribute': 'expr6', + 'selector': '[expr6]', + + 'template': template( + '', + [ + { + 'type': bindingTypes.EACH, + 'getKey': null, + 'condition': null, + + 'template': template( + ' ', + [ + { + 'expressions': [ + { + 'type': expressionTypes.TEXT, + 'childNodeIndex': 0, + + 'evaluate': function( + _scope + ) { + return [ + _scope.error + ].join( + '' + ); + } + } + ] + } + ] + ), + + 'redundantAttribute': 'expr7', + 'selector': '[expr7]', + 'itemName': 'error', + 'indexName': null, + + 'evaluate': function( + _scope + ) { + return _scope.state.errors; + } + } + ] + ) + } + ] + ); + }, + + 'name': 'field-error' +}); + +/***/ }), + +/***/ "./node_modules/@tentakelfabrik/tiny-validator/src/FormValidator.js": +/*!**************************************************************************!*\ + !*** ./node_modules/@tentakelfabrik/tiny-validator/src/FormValidator.js ***! + \**************************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var validate_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! validate.js */ "./node_modules/validate.js/validate.js"); +/* harmony import */ var validate_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(validate_js__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var form_serialize__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! form-serialize */ "./node_modules/form-serialize/index.js"); +/* harmony import */ var form_serialize__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(form_serialize__WEBPACK_IMPORTED_MODULE_1__); + + + +/** + * Form Validator with RiotJS Components + * + * + * + * + */ +class FormValidator +{ + /** + * + * @param {[type]} formSelector [description] + * @param {[type]} constraits [description] + */ + constructor(formSelector, constraits) + { + // getting selector to find form-element + this.formSelector = formSelector + + // constraits for validate.js + this.constraits = constraits + + // get form and elements + this.form = document.querySelector(this.formSelector) + this.elements = this.form.querySelectorAll('field-error') + + // adding submit event + this.form.addEventListener('submit', (event) => { + this.onSubmit(event) + }) + + // adding event if a element is updated + this.form.addEventListener('field-update', (event) => { + this.onFieldUpdate(event) + }) + } + + /** + * + * @param {[type]} event [description] + * @return {[type]} [description] + */ + onSubmit(event) + { + let errors = validate_js__WEBPACK_IMPORTED_MODULE_0___default()(form_serialize__WEBPACK_IMPORTED_MODULE_1___default()(event.target, { + hash: true + }), this.constraits, { + fullMessages: false + }) + + if (errors) { + event.preventDefault() + + // send each element a event + this.elements.forEach((element) => { + let elementErrors = false + + // check for errors by name + if (errors[element.attributes.name.nodeValue]) { + elementErrors = errors[element.attributes.name.nodeValue] + } + + this.dispatchCustomEvent(elementErrors, element) + }) + } + } + + /** + * + * + * @param {Event} event + * + */ + onFieldUpdate(event) + { + // workaround, make sure that value for single is undefined if it is empty + if (event.detail.value == '') { + event.detail.value = undefined + } + + let errors = validate_js__WEBPACK_IMPORTED_MODULE_0___default().single(event.detail.value, this.constraits[event.detail.name]) + + // search for element by name and dispatch event + this.elements.forEach((element) => { + if (element.attributes.name.nodeValue == event.detail.name) { + this.dispatchCustomEvent(errors, element) + } + }) + } + + /** + * dispatch event to single element + * + * @param {Array} errors + * @param {Element} element + * + */ + dispatchCustomEvent(errors, element) + { + let detail = false + + if (errors) { + detail = errors + } + + const formValidationEvent = new CustomEvent('form-validation', { + 'detail': detail + }) + + element.dispatchEvent(formValidationEvent) + } +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (FormValidator); + +/***/ }), + +/***/ "./node_modules/form-serialize/index.js": +/*!**********************************************!*\ + !*** ./node_modules/form-serialize/index.js ***! + \**********************************************/ +/***/ ((module) => { + +// get successful control from form and assemble into object +// http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2 + +// types which indicate a submit action and are not successful controls +// these will be ignored +var k_r_submitter = /^(?:submit|button|image|reset|file)$/i; + +// node names which could be successful controls +var k_r_success_contrls = /^(?:input|select|textarea|keygen)/i; + +// Matches bracket notation. +var brackets = /(\[[^\[\]]*\])/g; + +// serializes form fields +// @param form MUST be an HTMLForm element +// @param options is an optional argument to configure the serialization. Default output +// with no options specified is a url encoded string +// - hash: [true | false] Configure the output type. If true, the output will +// be a js object. +// - serializer: [function] Optional serializer function to override the default one. +// The function takes 3 arguments (result, key, value) and should return new result +// hash and url encoded str serializers are provided with this module +// - disabled: [true | false]. If true serialize disabled fields. +// - empty: [true | false]. If true serialize empty fields +function serialize(form, options) { + if (typeof options != 'object') { + options = { hash: !!options }; + } + else if (options.hash === undefined) { + options.hash = true; + } + + var result = (options.hash) ? {} : ''; + var serializer = options.serializer || ((options.hash) ? hash_serializer : str_serialize); + + var elements = form && form.elements ? form.elements : []; + + //Object store each radio and set if it's empty or not + var radio_store = Object.create(null); + + for (var i=0 ; i myString + */ + +function dashToCamelCase(string) { + return string.replace(/-(\w)/g, (_, c) => c.toUpperCase()); +} + +/** + * Get all the element attributes as object + * @param {HTMLElement} element - DOM node we want to parse + * @returns {Object} all the attributes found as a key value pairs + */ + +function DOMattributesToObject(element) { + return Array.from(element.attributes).reduce((acc, attribute) => { + acc[dashToCamelCase(attribute.name)] = attribute.value; + return acc; + }, {}); +} +/** + * Move all the child nodes from a source tag to another + * @param {HTMLElement} source - source node + * @param {HTMLElement} target - target node + * @returns {undefined} it's a void method ¯\_(ツ)_/¯ + */ +// Ignore this helper because it's needed only for svg tags + +function moveChildren(source, target) { + if (source.firstChild) { + target.appendChild(source.firstChild); + moveChildren(source, target); + } +} +/** + * Remove the child nodes from any DOM node + * @param {HTMLElement} node - target node + * @returns {undefined} + */ + +function cleanNode(node) { + clearChildren(node.childNodes); +} +/** + * Clear multiple children in a node + * @param {HTMLElement[]} children - direct children nodes + * @returns {undefined} + */ + +function clearChildren(children) { + Array.from(children).forEach(removeChild); +} +/** + * Remove a node + * @param {HTMLElement}node - node to remove + * @returns {undefined} + */ + +const removeChild = node => node && node.parentNode && node.parentNode.removeChild(node); +/** + * Insert before a node + * @param {HTMLElement} newNode - node to insert + * @param {HTMLElement} refNode - ref child + * @returns {undefined} + */ + +const insertBefore = (newNode, refNode) => refNode && refNode.parentNode && refNode.parentNode.insertBefore(newNode, refNode); +/** + * Replace a node + * @param {HTMLElement} newNode - new node to add to the DOM + * @param {HTMLElement} replaced - node to replace + * @returns {undefined} + */ + +const replaceChild = (newNode, replaced) => replaced && replaced.parentNode && replaced.parentNode.replaceChild(newNode, replaced); + +// Riot.js constants that can be used accross more modules +const COMPONENTS_IMPLEMENTATION_MAP$1 = new Map(), + DOM_COMPONENT_INSTANCE_PROPERTY$1 = Symbol('riot-component'), + PLUGINS_SET$1 = new Set(), + IS_DIRECTIVE = 'is', + VALUE_ATTRIBUTE = 'value', + MOUNT_METHOD_KEY = 'mount', + UPDATE_METHOD_KEY = 'update', + UNMOUNT_METHOD_KEY = 'unmount', + SHOULD_UPDATE_KEY = 'shouldUpdate', + ON_BEFORE_MOUNT_KEY = 'onBeforeMount', + ON_MOUNTED_KEY = 'onMounted', + ON_BEFORE_UPDATE_KEY = 'onBeforeUpdate', + ON_UPDATED_KEY = 'onUpdated', + ON_BEFORE_UNMOUNT_KEY = 'onBeforeUnmount', + ON_UNMOUNTED_KEY = 'onUnmounted', + PROPS_KEY = 'props', + STATE_KEY = 'state', + SLOTS_KEY = 'slots', + ROOT_KEY = 'root', + IS_PURE_SYMBOL = Symbol('pure'), + IS_COMPONENT_UPDATING = Symbol('is_updating'), + PARENT_KEY_SYMBOL = Symbol('parent'), + ATTRIBUTES_KEY_SYMBOL = Symbol('attributes'), + TEMPLATE_KEY_SYMBOL = Symbol('template'); + +var globals = /*#__PURE__*/Object.freeze({ + __proto__: null, + COMPONENTS_IMPLEMENTATION_MAP: COMPONENTS_IMPLEMENTATION_MAP$1, + DOM_COMPONENT_INSTANCE_PROPERTY: DOM_COMPONENT_INSTANCE_PROPERTY$1, + PLUGINS_SET: PLUGINS_SET$1, + IS_DIRECTIVE: IS_DIRECTIVE, + VALUE_ATTRIBUTE: VALUE_ATTRIBUTE, + MOUNT_METHOD_KEY: MOUNT_METHOD_KEY, + UPDATE_METHOD_KEY: UPDATE_METHOD_KEY, + UNMOUNT_METHOD_KEY: UNMOUNT_METHOD_KEY, + SHOULD_UPDATE_KEY: SHOULD_UPDATE_KEY, + ON_BEFORE_MOUNT_KEY: ON_BEFORE_MOUNT_KEY, + ON_MOUNTED_KEY: ON_MOUNTED_KEY, + ON_BEFORE_UPDATE_KEY: ON_BEFORE_UPDATE_KEY, + ON_UPDATED_KEY: ON_UPDATED_KEY, + ON_BEFORE_UNMOUNT_KEY: ON_BEFORE_UNMOUNT_KEY, + ON_UNMOUNTED_KEY: ON_UNMOUNTED_KEY, + PROPS_KEY: PROPS_KEY, + STATE_KEY: STATE_KEY, + SLOTS_KEY: SLOTS_KEY, + ROOT_KEY: ROOT_KEY, + IS_PURE_SYMBOL: IS_PURE_SYMBOL, + IS_COMPONENT_UPDATING: IS_COMPONENT_UPDATING, + PARENT_KEY_SYMBOL: PARENT_KEY_SYMBOL, + ATTRIBUTES_KEY_SYMBOL: ATTRIBUTES_KEY_SYMBOL, + TEMPLATE_KEY_SYMBOL: TEMPLATE_KEY_SYMBOL +}); + +const EACH = 0; +const IF = 1; +const SIMPLE = 2; +const TAG = 3; +const SLOT = 4; +var bindingTypes = { + EACH, + IF, + SIMPLE, + TAG, + SLOT +}; + +const ATTRIBUTE = 0; +const EVENT = 1; +const TEXT = 2; +const VALUE = 3; +var expressionTypes = { + ATTRIBUTE, + EVENT, + TEXT, + VALUE +}; + +const HEAD_SYMBOL = Symbol('head'); +const TAIL_SYMBOL = Symbol('tail'); + +/** + * Create the