From 9cbd129d4e31551c6e64b47a7a6aaae25a4c98d3 Mon Sep 17 00:00:00 2001 From: Roman Hergenreder Date: Tue, 23 Jun 2020 20:57:54 +0200 Subject: [PATCH] User Edit --- core/Api/UserAPI.class.php | 35 ++++-- core/Driver/SQL/SQL.class.php | 5 +- js/admin.min.js | 26 ++++- src/src/api.js | 4 + src/src/include/select2.min.css | 1 + src/src/views/edituser.js | 189 ++++++++++++++++++++++++++++---- 6 files changed, 226 insertions(+), 34 deletions(-) create mode 100644 src/src/include/select2.min.css diff --git a/core/Api/UserAPI.class.php b/core/Api/UserAPI.class.php index 4da2dfe..01d99e2 100644 --- a/core/Api/UserAPI.class.php +++ b/core/Api/UserAPI.class.php @@ -286,8 +286,7 @@ namespace Api\User { ); foreach($user as $row) { - $this->result["user"]["groups"][] = array( - "uid" => $row["groupId"], + $this->result["user"]["groups"][$row["groupId"]] = array( "name" => $row["groupName"], "color" => $row["groupColor"], ); @@ -482,7 +481,7 @@ If the invitation was not intended, you can simply ignore this email.

modify("+48 hour"); $sql = $this->user->getSQL(); $res = $sql->insert("UserToken", array("user_id", "token", "token_type", "valid_until")) - ->addRow(array($this->userId, $this->token, "confirmation", $validUntil)) + ->addRow($this->userId, $this->token, "confirmation", $validUntil) ->execute(); $this->success = ($res !== FALSE); @@ -606,8 +605,20 @@ If the registration was not intended, you can simply ignore this email.

< $password = $this->getParam("password"); $groups = $this->getParam("groups"); + $groupIds = array(); if (!is_null($groups)) { - if ($id === $this->user->getId() && !in_array(USER_GROUP_ADMIN, $groups)) { + $param = new Parameter('groupId', Parameter::TYPE_INT); + + foreach($groups as $groupId) { + if (!$param->parseParam($groupId)) { + $value = print_r($groupId, true); + return $this->createError("Invalid Type for groupId in parameter groups: '$value' (Required: " . $param->getTypeName() . ")"); + } + + $groupIds[] = $param->value; + } + + if ($id === $this->user->getId() && !in_array(USER_GROUP_ADMIN, $groupIds)) { return $this->createError("Cannot remove Administrator group from own user."); } } @@ -628,18 +639,20 @@ If the registration was not intended, you can simply ignore this email.

< if ($emailChanged) $query->set("email", $email); if (!is_null($password)) $query->set("password", $this->hashPassword($password)); - $query->where(new Compare("User.uid", $id)); - $res = $query->execute(); - $this->lastError = $sql->getLastError(); - $this->success = ($res !== FALSE); + if (!empty($query->getValues())) { + $query->where(new Compare("User.uid", $id)); + $res = $query->execute(); + $this->lastError = $sql->getLastError(); + $this->success = ($res !== FALSE); + } - if ($this->success && !is_null($groups)) { + if ($this->success && !empty($groupIds)) { $deleteQuery = $sql->delete("UserGroup")->where(new Compare("user_id", $id)); $insertQuery = $sql->insert("UserGroup", array("user_id", "group_id")); - foreach($groups as $groupId) { - $insertQuery->addRow(array($id, $groupId)); + foreach($groupIds as $groupId) { + $insertQuery->addRow($id, $groupId); } $this->success = ($deleteQuery->execute() !== FALSE) && ($insertQuery->execute() !== FALSE); diff --git a/core/Driver/SQL/SQL.class.php b/core/Driver/SQL/SQL.class.php index 7b5c48d..a52bbb7 100644 --- a/core/Driver/SQL/SQL.class.php +++ b/core/Driver/SQL/SQL.class.php @@ -203,12 +203,13 @@ abstract class SQL { public function executeDelete(Delete $delete) { + $params = array(); $table = $this->tableName($delete->getTable()); $where = $this->getWhereClause($delete->getConditions(), $params); $query = "DELETE FROM $table$where"; if($delete->dump) { var_dump($query); } - return $this->execute($query); + return $this->execute($query, $params); } public function executeTruncate(Truncate $truncate) { @@ -222,7 +223,7 @@ abstract class SQL { $valueStr = array(); foreach($update->getValues() as $key => $val) { - $valueStr[] = "$key=" . $this->addValue($val, $params); + $valueStr[] = $this->columnName($key) . "=" . $this->addValue($val, $params); } $valueStr = implode(",", $valueStr); diff --git a/js/admin.min.js b/js/admin.min.js index 606bd5b..d25304f 100644 --- a/js/admin.min.js +++ b/js/admin.min.js @@ -4039,6 +4039,17 @@ eval("// Imports\nvar ___CSS_LOADER_API_IMPORT___ = __webpack_require__(/*! ../. /***/ }), +/***/ "./node_modules/css-loader/dist/cjs.js!./src/include/select2.min.css": +/*!***************************************************************************!*\ + !*** ./node_modules/css-loader/dist/cjs.js!./src/include/select2.min.css ***! + \***************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("// Imports\nvar ___CSS_LOADER_API_IMPORT___ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\nexports = ___CSS_LOADER_API_IMPORT___(false);\n// Module\nexports.push([module.i, \".select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir=\\\"rtl\\\"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;height:1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important;white-space:nowrap !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir=\\\"rtl\\\"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir=\\\"rtl\\\"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px;padding:1px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #fff;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#fff;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir=\\\"rtl\\\"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir=\\\"rtl\\\"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir=\\\"rtl\\\"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir=\\\"rtl\\\"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir=\\\"rtl\\\"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir=\\\"rtl\\\"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir=\\\"rtl\\\"] .select2-selection--multiple .select2-selection__choice{float:right;margin-left:5px;margin-right:auto}.select2-container--classic[dir=\\\"rtl\\\"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb}\\n\", \"\"]);\n// Exports\nmodule.exports = exports;\n\n\n//# sourceURL=webpack:///./src/include/select2.min.css?./node_modules/css-loader/dist/cjs.js"); + +/***/ }), + /***/ "./node_modules/css-loader/dist/runtime/api.js": /*!*****************************************************!*\ !*** ./node_modules/css-loader/dist/runtime/api.js ***! @@ -7559,7 +7570,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) * /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return API; });\n/* harmony import */ var babel_polyfill__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babel-polyfill */ \"./node_modules/babel-polyfill/lib/index.js\");\n/* harmony import */ var babel_polyfill__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babel_polyfill__WEBPACK_IMPORTED_MODULE_0__);\nfunction asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }\n\nfunction _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err); } _next(undefined); }); }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n\n\nvar API = /*#__PURE__*/function () {\n function API() {\n _classCallCheck(this, API);\n\n this.loggedIn = false;\n this.user = {};\n }\n\n _createClass(API, [{\n key: \"csrfToken\",\n value: function csrfToken() {\n return this.loggedIn ? this.user.session.csrf_token : null;\n }\n }, {\n key: \"apiCall\",\n value: function () {\n var _apiCall = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(method, params) {\n var response, res;\n return regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n params = params || {};\n params.csrf_token = this.csrfToken();\n _context.next = 4;\n return fetch(\"/api/\" + method, {\n method: 'post',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(params)\n });\n\n case 4:\n response = _context.sent;\n _context.next = 7;\n return response.json();\n\n case 7:\n res = _context.sent;\n\n if (!res.success && res.msg === \"You are not logged in.\") {\n document.location.reload();\n }\n\n return _context.abrupt(\"return\", res);\n\n case 10:\n case \"end\":\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function apiCall(_x, _x2) {\n return _apiCall.apply(this, arguments);\n }\n\n return apiCall;\n }()\n }, {\n key: \"fetchUser\",\n value: function () {\n var _fetchUser = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {\n var response, data;\n return regeneratorRuntime.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n _context2.next = 2;\n return fetch(\"/api/user/info\");\n\n case 2:\n response = _context2.sent;\n _context2.next = 5;\n return response.json();\n\n case 5:\n data = _context2.sent;\n this.user = data[\"user\"];\n this.loggedIn = data[\"loggedIn\"];\n return _context2.abrupt(\"return\", data && data.success && data.loggedIn);\n\n case 9:\n case \"end\":\n return _context2.stop();\n }\n }\n }, _callee2, this);\n }));\n\n function fetchUser() {\n return _fetchUser.apply(this, arguments);\n }\n\n return fetchUser;\n }()\n }, {\n key: \"logout\",\n value: function () {\n var _logout = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {\n return regeneratorRuntime.wrap(function _callee3$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n return _context3.abrupt(\"return\", this.apiCall(\"user/logout\"));\n\n case 1:\n case \"end\":\n return _context3.stop();\n }\n }\n }, _callee3, this);\n }));\n\n function logout() {\n return _logout.apply(this, arguments);\n }\n\n return logout;\n }()\n }, {\n key: \"getNotifications\",\n value: function () {\n var _getNotifications = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() {\n return regeneratorRuntime.wrap(function _callee4$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n return _context4.abrupt(\"return\", this.apiCall(\"notifications/fetch\"));\n\n case 1:\n case \"end\":\n return _context4.stop();\n }\n }\n }, _callee4, this);\n }));\n\n function getNotifications() {\n return _getNotifications.apply(this, arguments);\n }\n\n return getNotifications;\n }()\n }, {\n key: \"getUser\",\n value: function () {\n var _getUser = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5(id) {\n return regeneratorRuntime.wrap(function _callee5$(_context5) {\n while (1) {\n switch (_context5.prev = _context5.next) {\n case 0:\n return _context5.abrupt(\"return\", this.apiCall(\"user/get\", {\n id: id\n }));\n\n case 1:\n case \"end\":\n return _context5.stop();\n }\n }\n }, _callee5, this);\n }));\n\n function getUser(_x3) {\n return _getUser.apply(this, arguments);\n }\n\n return getUser;\n }()\n }, {\n key: \"fetchUsers\",\n value: function () {\n var _fetchUsers = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee6() {\n var pageNum,\n count,\n _args6 = arguments;\n return regeneratorRuntime.wrap(function _callee6$(_context6) {\n while (1) {\n switch (_context6.prev = _context6.next) {\n case 0:\n pageNum = _args6.length > 0 && _args6[0] !== undefined ? _args6[0] : 1;\n count = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : 20;\n return _context6.abrupt(\"return\", this.apiCall(\"user/fetch\", {\n page: pageNum,\n count: count\n }));\n\n case 3:\n case \"end\":\n return _context6.stop();\n }\n }\n }, _callee6, this);\n }));\n\n function fetchUsers() {\n return _fetchUsers.apply(this, arguments);\n }\n\n return fetchUsers;\n }()\n }, {\n key: \"fetchGroups\",\n value: function () {\n var _fetchGroups = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee7() {\n var pageNum,\n count,\n _args7 = arguments;\n return regeneratorRuntime.wrap(function _callee7$(_context7) {\n while (1) {\n switch (_context7.prev = _context7.next) {\n case 0:\n pageNum = _args7.length > 0 && _args7[0] !== undefined ? _args7[0] : 1;\n count = _args7.length > 1 && _args7[1] !== undefined ? _args7[1] : 20;\n return _context7.abrupt(\"return\", this.apiCall(\"groups/fetch\", {\n page: pageNum,\n count: count\n }));\n\n case 3:\n case \"end\":\n return _context7.stop();\n }\n }\n }, _callee7, this);\n }));\n\n function fetchGroups() {\n return _fetchGroups.apply(this, arguments);\n }\n\n return fetchGroups;\n }()\n }, {\n key: \"inviteUser\",\n value: function () {\n var _inviteUser = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee8(username, email) {\n return regeneratorRuntime.wrap(function _callee8$(_context8) {\n while (1) {\n switch (_context8.prev = _context8.next) {\n case 0:\n return _context8.abrupt(\"return\", this.apiCall(\"user/invite\", {\n username: username,\n email: email\n }));\n\n case 1:\n case \"end\":\n return _context8.stop();\n }\n }\n }, _callee8, this);\n }));\n\n function inviteUser(_x4, _x5) {\n return _inviteUser.apply(this, arguments);\n }\n\n return inviteUser;\n }()\n }, {\n key: \"createUser\",\n value: function () {\n var _createUser = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee9(username, email, password, confirmPassword) {\n return regeneratorRuntime.wrap(function _callee9$(_context9) {\n while (1) {\n switch (_context9.prev = _context9.next) {\n case 0:\n return _context9.abrupt(\"return\", this.apiCall(\"user/create\", {\n username: username,\n email: email,\n password: password,\n confirmPassword: confirmPassword\n }));\n\n case 1:\n case \"end\":\n return _context9.stop();\n }\n }\n }, _callee9, this);\n }));\n\n function createUser(_x6, _x7, _x8, _x9) {\n return _createUser.apply(this, arguments);\n }\n\n return createUser;\n }()\n }, {\n key: \"getStats\",\n value: function () {\n var _getStats = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee10() {\n return regeneratorRuntime.wrap(function _callee10$(_context10) {\n while (1) {\n switch (_context10.prev = _context10.next) {\n case 0:\n return _context10.abrupt(\"return\", this.apiCall(\"stats\"));\n\n case 1:\n case \"end\":\n return _context10.stop();\n }\n }\n }, _callee10, this);\n }));\n\n function getStats() {\n return _getStats.apply(this, arguments);\n }\n\n return getStats;\n }()\n }, {\n key: \"getRoutes\",\n value: function () {\n var _getRoutes = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee11() {\n return regeneratorRuntime.wrap(function _callee11$(_context11) {\n while (1) {\n switch (_context11.prev = _context11.next) {\n case 0:\n return _context11.abrupt(\"return\", this.apiCall(\"routes/fetch\"));\n\n case 1:\n case \"end\":\n return _context11.stop();\n }\n }\n }, _callee11, this);\n }));\n\n function getRoutes() {\n return _getRoutes.apply(this, arguments);\n }\n\n return getRoutes;\n }()\n }, {\n key: \"saveRoutes\",\n value: function () {\n var _saveRoutes = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee12(routes) {\n return regeneratorRuntime.wrap(function _callee12$(_context12) {\n while (1) {\n switch (_context12.prev = _context12.next) {\n case 0:\n return _context12.abrupt(\"return\", this.apiCall(\"routes/save\", {\n \"routes\": routes\n }));\n\n case 1:\n case \"end\":\n return _context12.stop();\n }\n }\n }, _callee12, this);\n }));\n\n function saveRoutes(_x10) {\n return _saveRoutes.apply(this, arguments);\n }\n\n return saveRoutes;\n }()\n }]);\n\n return API;\n}();\n\n\n;\n\n//# sourceURL=webpack:///./src/api.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return API; });\n/* harmony import */ var babel_polyfill__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babel-polyfill */ \"./node_modules/babel-polyfill/lib/index.js\");\n/* harmony import */ var babel_polyfill__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babel_polyfill__WEBPACK_IMPORTED_MODULE_0__);\nfunction asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }\n\nfunction _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err); } _next(undefined); }); }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n\n\nvar API = /*#__PURE__*/function () {\n function API() {\n _classCallCheck(this, API);\n\n this.loggedIn = false;\n this.user = {};\n }\n\n _createClass(API, [{\n key: \"csrfToken\",\n value: function csrfToken() {\n return this.loggedIn ? this.user.session.csrf_token : null;\n }\n }, {\n key: \"apiCall\",\n value: function () {\n var _apiCall = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(method, params) {\n var response, res;\n return regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n params = params || {};\n params.csrf_token = this.csrfToken();\n _context.next = 4;\n return fetch(\"/api/\" + method, {\n method: 'post',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(params)\n });\n\n case 4:\n response = _context.sent;\n _context.next = 7;\n return response.json();\n\n case 7:\n res = _context.sent;\n\n if (!res.success && res.msg === \"You are not logged in.\") {\n document.location.reload();\n }\n\n return _context.abrupt(\"return\", res);\n\n case 10:\n case \"end\":\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function apiCall(_x, _x2) {\n return _apiCall.apply(this, arguments);\n }\n\n return apiCall;\n }()\n }, {\n key: \"fetchUser\",\n value: function () {\n var _fetchUser = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {\n var response, data;\n return regeneratorRuntime.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n _context2.next = 2;\n return fetch(\"/api/user/info\");\n\n case 2:\n response = _context2.sent;\n _context2.next = 5;\n return response.json();\n\n case 5:\n data = _context2.sent;\n this.user = data[\"user\"];\n this.loggedIn = data[\"loggedIn\"];\n return _context2.abrupt(\"return\", data && data.success && data.loggedIn);\n\n case 9:\n case \"end\":\n return _context2.stop();\n }\n }\n }, _callee2, this);\n }));\n\n function fetchUser() {\n return _fetchUser.apply(this, arguments);\n }\n\n return fetchUser;\n }()\n }, {\n key: \"editUser\",\n value: function () {\n var _editUser = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(id, username, email, password, groups) {\n return regeneratorRuntime.wrap(function _callee3$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n return _context3.abrupt(\"return\", this.apiCall(\"user/edit\", {\n \"id\": id,\n \"username\": username,\n \"email\": email,\n \"password\": password,\n \"groups\": groups\n }));\n\n case 1:\n case \"end\":\n return _context3.stop();\n }\n }\n }, _callee3, this);\n }));\n\n function editUser(_x3, _x4, _x5, _x6, _x7) {\n return _editUser.apply(this, arguments);\n }\n\n return editUser;\n }()\n }, {\n key: \"logout\",\n value: function () {\n var _logout = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() {\n return regeneratorRuntime.wrap(function _callee4$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n return _context4.abrupt(\"return\", this.apiCall(\"user/logout\"));\n\n case 1:\n case \"end\":\n return _context4.stop();\n }\n }\n }, _callee4, this);\n }));\n\n function logout() {\n return _logout.apply(this, arguments);\n }\n\n return logout;\n }()\n }, {\n key: \"getNotifications\",\n value: function () {\n var _getNotifications = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5() {\n return regeneratorRuntime.wrap(function _callee5$(_context5) {\n while (1) {\n switch (_context5.prev = _context5.next) {\n case 0:\n return _context5.abrupt(\"return\", this.apiCall(\"notifications/fetch\"));\n\n case 1:\n case \"end\":\n return _context5.stop();\n }\n }\n }, _callee5, this);\n }));\n\n function getNotifications() {\n return _getNotifications.apply(this, arguments);\n }\n\n return getNotifications;\n }()\n }, {\n key: \"getUser\",\n value: function () {\n var _getUser = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee6(id) {\n return regeneratorRuntime.wrap(function _callee6$(_context6) {\n while (1) {\n switch (_context6.prev = _context6.next) {\n case 0:\n return _context6.abrupt(\"return\", this.apiCall(\"user/get\", {\n id: id\n }));\n\n case 1:\n case \"end\":\n return _context6.stop();\n }\n }\n }, _callee6, this);\n }));\n\n function getUser(_x8) {\n return _getUser.apply(this, arguments);\n }\n\n return getUser;\n }()\n }, {\n key: \"fetchUsers\",\n value: function () {\n var _fetchUsers = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee7() {\n var pageNum,\n count,\n _args7 = arguments;\n return regeneratorRuntime.wrap(function _callee7$(_context7) {\n while (1) {\n switch (_context7.prev = _context7.next) {\n case 0:\n pageNum = _args7.length > 0 && _args7[0] !== undefined ? _args7[0] : 1;\n count = _args7.length > 1 && _args7[1] !== undefined ? _args7[1] : 20;\n return _context7.abrupt(\"return\", this.apiCall(\"user/fetch\", {\n page: pageNum,\n count: count\n }));\n\n case 3:\n case \"end\":\n return _context7.stop();\n }\n }\n }, _callee7, this);\n }));\n\n function fetchUsers() {\n return _fetchUsers.apply(this, arguments);\n }\n\n return fetchUsers;\n }()\n }, {\n key: \"fetchGroups\",\n value: function () {\n var _fetchGroups = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee8() {\n var pageNum,\n count,\n _args8 = arguments;\n return regeneratorRuntime.wrap(function _callee8$(_context8) {\n while (1) {\n switch (_context8.prev = _context8.next) {\n case 0:\n pageNum = _args8.length > 0 && _args8[0] !== undefined ? _args8[0] : 1;\n count = _args8.length > 1 && _args8[1] !== undefined ? _args8[1] : 20;\n return _context8.abrupt(\"return\", this.apiCall(\"groups/fetch\", {\n page: pageNum,\n count: count\n }));\n\n case 3:\n case \"end\":\n return _context8.stop();\n }\n }\n }, _callee8, this);\n }));\n\n function fetchGroups() {\n return _fetchGroups.apply(this, arguments);\n }\n\n return fetchGroups;\n }()\n }, {\n key: \"inviteUser\",\n value: function () {\n var _inviteUser = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee9(username, email) {\n return regeneratorRuntime.wrap(function _callee9$(_context9) {\n while (1) {\n switch (_context9.prev = _context9.next) {\n case 0:\n return _context9.abrupt(\"return\", this.apiCall(\"user/invite\", {\n username: username,\n email: email\n }));\n\n case 1:\n case \"end\":\n return _context9.stop();\n }\n }\n }, _callee9, this);\n }));\n\n function inviteUser(_x9, _x10) {\n return _inviteUser.apply(this, arguments);\n }\n\n return inviteUser;\n }()\n }, {\n key: \"createUser\",\n value: function () {\n var _createUser = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee10(username, email, password, confirmPassword) {\n return regeneratorRuntime.wrap(function _callee10$(_context10) {\n while (1) {\n switch (_context10.prev = _context10.next) {\n case 0:\n return _context10.abrupt(\"return\", this.apiCall(\"user/create\", {\n username: username,\n email: email,\n password: password,\n confirmPassword: confirmPassword\n }));\n\n case 1:\n case \"end\":\n return _context10.stop();\n }\n }\n }, _callee10, this);\n }));\n\n function createUser(_x11, _x12, _x13, _x14) {\n return _createUser.apply(this, arguments);\n }\n\n return createUser;\n }()\n }, {\n key: \"getStats\",\n value: function () {\n var _getStats = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee11() {\n return regeneratorRuntime.wrap(function _callee11$(_context11) {\n while (1) {\n switch (_context11.prev = _context11.next) {\n case 0:\n return _context11.abrupt(\"return\", this.apiCall(\"stats\"));\n\n case 1:\n case \"end\":\n return _context11.stop();\n }\n }\n }, _callee11, this);\n }));\n\n function getStats() {\n return _getStats.apply(this, arguments);\n }\n\n return getStats;\n }()\n }, {\n key: \"getRoutes\",\n value: function () {\n var _getRoutes = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee12() {\n return regeneratorRuntime.wrap(function _callee12$(_context12) {\n while (1) {\n switch (_context12.prev = _context12.next) {\n case 0:\n return _context12.abrupt(\"return\", this.apiCall(\"routes/fetch\"));\n\n case 1:\n case \"end\":\n return _context12.stop();\n }\n }\n }, _callee12, this);\n }));\n\n function getRoutes() {\n return _getRoutes.apply(this, arguments);\n }\n\n return getRoutes;\n }()\n }, {\n key: \"saveRoutes\",\n value: function () {\n var _saveRoutes = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee13(routes) {\n return regeneratorRuntime.wrap(function _callee13$(_context13) {\n while (1) {\n switch (_context13.prev = _context13.next) {\n case 0:\n return _context13.abrupt(\"return\", this.apiCall(\"routes/save\", {\n \"routes\": routes\n }));\n\n case 1:\n case \"end\":\n return _context13.stop();\n }\n }\n }, _callee13, this);\n }));\n\n function saveRoutes(_x15) {\n return _saveRoutes.apply(this, arguments);\n }\n\n return saveRoutes;\n }()\n }]);\n\n return API;\n}();\n\n\n;\n\n//# sourceURL=webpack:///./src/api.js?"); /***/ }), @@ -7657,6 +7668,17 @@ eval("\nvar content = __webpack_require__(/*! !../../node_modules/css-loader/dis /***/ }), +/***/ "./src/include/select2.min.css": +/*!*************************************!*\ + !*** ./src/include/select2.min.css ***! + \*************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("\nvar content = __webpack_require__(/*! !../../node_modules/css-loader/dist/cjs.js!./select2.min.css */ \"./node_modules/css-loader/dist/cjs.js!./src/include/select2.min.css\");\n\nif(typeof content === 'string') content = [[module.i, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = __webpack_require__(/*! ../../node_modules/style-loader/lib/addStyles.js */ \"./node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(false) {}\n\n//# sourceURL=webpack:///./src/include/select2.min.css?"); + +/***/ }), + /***/ "./src/index.js": /*!**********************!*\ !*** ./src/index.js ***! @@ -7701,7 +7723,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) * /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return EditUser; });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _elements_icon__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../elements/icon */ \"./src/elements/icon.js\");\n/* harmony import */ var _elements_alert__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../elements/alert */ \"./src/elements/alert.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.js\");\n/* harmony import */ var react_collapse_lib_Collapse__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! react-collapse/lib/Collapse */ \"./node_modules/react-collapse/lib/Collapse.js\");\n/* harmony import */ var react_collapse_lib_Collapse__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(react_collapse_lib_Collapse__WEBPACK_IMPORTED_MODULE_4__);\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n\nvar EditUser = /*#__PURE__*/function (_React$Component) {\n _inherits(EditUser, _React$Component);\n\n var _super = _createSuper(EditUser);\n\n function EditUser(props) {\n var _this;\n\n _classCallCheck(this, EditUser);\n\n _this = _super.call(this, props);\n _this.parent = {\n api: props.api\n };\n _this.state = {\n user: {},\n errors: [],\n fetchError: null,\n loaded: false,\n isSaving: false\n };\n return _this;\n }\n\n _createClass(EditUser, [{\n key: \"removeError\",\n value: function removeError(i) {\n if (i >= 0 && i < this.state.errors.length) {\n var errors = this.state.errors.slice();\n errors.splice(i, 1);\n this.setState(_objectSpread(_objectSpread({}, this.state), {}, {\n errors: errors\n }));\n }\n }\n }, {\n key: \"componentDidMount\",\n value: function componentDidMount() {\n var _this2 = this;\n\n this.parent.api.getUser(this.props.match.params[\"userId\"]).then(function (res) {\n if (res.success) {\n _this2.setState(_objectSpread(_objectSpread({}, _this2.state), {}, {\n user: res.user,\n loaded: true\n }));\n } else {\n _this2.setState(_objectSpread(_objectSpread({}, _this2.state), {}, {\n fetchError: res.msg,\n loaded: true\n }));\n }\n });\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this3 = this;\n\n if (!this.state.loaded) {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"h2\", {\n className: \"text-center\"\n }, \"Loading\\u2026\", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"br\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](_elements_icon__WEBPACK_IMPORTED_MODULE_1__[\"default\"], {\n icon: \"spinner\",\n className: \"mt-3 text-muted fa-2x\"\n }));\n }\n\n var errors = [];\n var form = null;\n\n if (this.state.fetchError) {\n errors.push( /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](_elements_alert__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n key: \"error-fetch\",\n title: \"Error fetching user details\",\n type: \"danger\",\n message: /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", null, this.state.fetchError, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"br\", null), \"You can meanwhile return to the\\xA0\", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](react_router_dom__WEBPACK_IMPORTED_MODULE_3__[\"Link\"], {\n to: \"/admin/users\"\n }, \"user overview\"))\n }));\n } else {\n var _loop = function _loop(i) {\n errors.push( /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](_elements_alert__WEBPACK_IMPORTED_MODULE_2__[\"default\"], _extends({\n key: \"error-\" + i,\n onClose: function onClose() {\n return _this3.removeError(i);\n }\n }, _this3.state.errors[i])));\n };\n\n for (var i = 0; i < this.state.errors.length; i++) {\n _loop(i);\n }\n\n form = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"form\", {\n role: \"form\",\n onSubmit: function onSubmit(e) {\n return e.preventDefault();\n }\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"form-group\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"label\", {\n htmlFor: \"username\"\n }, \"Username\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"input\", {\n type: \"text\",\n className: \"form-control\",\n placeholder: \"Enter username\",\n name: \"username\",\n id: \"username\",\n maxLength: 32,\n value: this.state.user.name\n })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"form-group\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"label\", {\n htmlFor: \"email\"\n }, \"E-Mail\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"input\", {\n type: \"email\",\n className: \"form-control\",\n placeholder: \"E-Mail address\",\n id: \"email\",\n name: \"email\",\n maxLength: 64,\n value: this.state.user.email\n })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](react_router_dom__WEBPACK_IMPORTED_MODULE_3__[\"Link\"], {\n to: \"/admin/users\",\n className: \"btn btn-info mt-2 mr-2\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](_elements_icon__WEBPACK_IMPORTED_MODULE_1__[\"default\"], {\n icon: \"arrow-left\"\n }), \"\\xA0Back\"), this.state.isSaving ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"button\", {\n type: \"submit\",\n className: \"btn btn-primary mt-2\",\n disabled: true\n }, \"Saving\\u2026\\xA0\", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](_elements_icon__WEBPACK_IMPORTED_MODULE_1__[\"default\"], {\n icon: \"circle-notch\"\n })) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"button\", {\n type: \"submit\",\n className: \"btn btn-primary mt-2\"\n }, \"Save\"));\n }\n\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](react__WEBPACK_IMPORTED_MODULE_0__[\"Fragment\"], null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"content-header\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"container-fluid\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"row mb-2\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"col-sm-6\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"h1\", {\n className: \"m-0 text-dark\"\n }, \"Edit User\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"col-sm-6\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"ol\", {\n className: \"breadcrumb float-sm-right\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"li\", {\n className: \"breadcrumb-item\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](react_router_dom__WEBPACK_IMPORTED_MODULE_3__[\"Link\"], {\n to: \"/admin/dashboard\"\n }, \"Home\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"li\", {\n className: \"breadcrumb-item\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](react_router_dom__WEBPACK_IMPORTED_MODULE_3__[\"Link\"], {\n to: \"/admin/users\"\n }, \"Users\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"li\", {\n className: \"breadcrumb-item active\"\n }, \"Add User\")))))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"content\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"row\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"col-lg-6 pl-5 pr-5\"\n }, errors, form))));\n }\n }]);\n\n return EditUser;\n}(react__WEBPACK_IMPORTED_MODULE_0__[\"Component\"]);\n\n\n\n//# sourceURL=webpack:///./src/views/edituser.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return EditUser; });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _elements_icon__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../elements/icon */ \"./src/elements/icon.js\");\n/* harmony import */ var _elements_alert__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../elements/alert */ \"./src/elements/alert.js\");\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/react-router-dom/esm/react-router-dom.js\");\n/* harmony import */ var _include_select2_min_css__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../include/select2.min.css */ \"./src/include/select2.min.css\");\n/* harmony import */ var _include_select2_min_css__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_include_select2_min_css__WEBPACK_IMPORTED_MODULE_4__);\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n\nvar EditUser = /*#__PURE__*/function (_React$Component) {\n _inherits(EditUser, _React$Component);\n\n var _super = _createSuper(EditUser);\n\n function EditUser(props) {\n var _this;\n\n _classCallCheck(this, EditUser);\n\n _this = _super.call(this, props);\n _this.parent = {\n api: props.api\n };\n _this.state = {\n user: {},\n alerts: [],\n fetchError: null,\n loaded: false,\n isSaving: false,\n groups: {},\n searchString: \"\",\n searchActive: false\n };\n _this.searchBox = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createRef\"]();\n return _this;\n }\n\n _createClass(EditUser, [{\n key: \"removeAlert\",\n value: function removeAlert(i) {\n if (i >= 0 && i < this.state.alerts.length) {\n var alerts = this.state.alerts.slice();\n alerts.splice(i, 1);\n this.setState(_objectSpread(_objectSpread({}, this.state), {}, {\n alerts: alerts\n }));\n }\n }\n }, {\n key: \"componentDidMount\",\n value: function componentDidMount() {\n var _this2 = this;\n\n this.parent.api.getUser(this.props.match.params[\"userId\"]).then(function (res) {\n if (res.success) {\n _this2.setState(_objectSpread(_objectSpread({}, _this2.state), {}, {\n user: _objectSpread(_objectSpread({}, res.user), {}, {\n password: \"\"\n })\n }));\n\n _this2.parent.api.fetchGroups(1, 50).then(function (res) {\n if (res.success) {\n _this2.setState(_objectSpread(_objectSpread({}, _this2.state), {}, {\n groups: res.groups,\n loaded: true\n }));\n } else {\n _this2.setState(_objectSpread(_objectSpread({}, _this2.state), {}, {\n fetchError: res.msg,\n loaded: true\n }));\n }\n });\n } else {\n _this2.setState(_objectSpread(_objectSpread({}, _this2.state), {}, {\n fetchError: res.msg,\n loaded: true\n }));\n }\n });\n }\n }, {\n key: \"onChangeInput\",\n value: function onChangeInput(event) {\n var target = event.target;\n var value = target.value;\n var name = target.name;\n\n if (name === \"search\") {\n this.setState(_objectSpread(_objectSpread({}, this.state), {}, {\n searchString: value\n }));\n } else {\n this.setState(_objectSpread(_objectSpread({}, this.state), {}, {\n user: _objectSpread(_objectSpread({}, this.state.user), {}, _defineProperty({}, name, value))\n }));\n }\n }\n }, {\n key: \"onToggleSearch\",\n value: function onToggleSearch(e) {\n e.stopPropagation();\n this.setState(_objectSpread(_objectSpread({}, this.state), {}, {\n searchActive: !this.state.searchActive\n }));\n this.searchBox.current.focus();\n }\n }, {\n key: \"onSubmitForm\",\n value: function onSubmitForm(event) {\n var _this3 = this;\n\n event.preventDefault();\n event.stopPropagation();\n var id = this.props.match.params[\"userId\"];\n var username = this.state.user[\"name\"];\n var email = this.state.user[\"email\"];\n var password = this.state.user[\"password\"].length > 0 ? this.state.user[\"password\"] : null;\n var groups = Object.keys(this.state.user.groups);\n this.setState(_objectSpread(_objectSpread({}, this.state), {}, {\n isSaving: true\n }));\n this.parent.api.editUser(id, username, email, password, groups).then(function (res) {\n var alerts = _this3.state.alerts.slice();\n\n if (res.success) {\n alerts.push({\n title: \"Success\",\n message: \"User was successfully updated.\",\n type: \"success\"\n });\n\n _this3.setState(_objectSpread(_objectSpread({}, _this3.state), {}, {\n isSaving: false,\n alerts: alerts,\n user: _objectSpread(_objectSpread({}, _this3.state.user), {}, {\n password: \"\"\n })\n }));\n } else {\n alerts.push({\n title: \"Error updating user\",\n message: res.msg,\n type: \"danger\"\n });\n\n _this3.setState(_objectSpread(_objectSpread({}, _this3.state), {}, {\n isSaving: false,\n alerts: alerts,\n user: _objectSpread(_objectSpread({}, _this3.state.user), {}, {\n password: \"\"\n })\n }));\n }\n });\n }\n }, {\n key: \"onRemoveGroup\",\n value: function onRemoveGroup(event, groupId) {\n event.stopPropagation();\n\n if (this.state.user.groups.hasOwnProperty(groupId)) {\n var groups = _objectSpread({}, this.state.user.groups);\n\n delete groups[groupId];\n this.setState(_objectSpread(_objectSpread({}, this.state), {}, {\n user: _objectSpread(_objectSpread({}, this.state.user), {}, {\n groups: groups\n })\n }));\n }\n }\n }, {\n key: \"onAddGroup\",\n value: function onAddGroup(event, groupId) {\n event.stopPropagation();\n\n if (!this.state.user.groups.hasOwnProperty(groupId)) {\n var groups = _objectSpread(_objectSpread({}, this.state.user.groups), {}, _defineProperty({}, groupId, _objectSpread({}, this.state.groups[groupId])));\n\n this.setState(_objectSpread(_objectSpread({}, this.state), {}, {\n user: _objectSpread(_objectSpread({}, this.state.user), {}, {\n groups: groups\n }),\n searchActive: false,\n searchString: \"\"\n }));\n }\n }\n }, {\n key: \"render\",\n value: function render() {\n var _this4 = this;\n\n if (!this.state.loaded) {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"h2\", {\n className: \"text-center\"\n }, \"Loading\\u2026\", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"br\", null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](_elements_icon__WEBPACK_IMPORTED_MODULE_1__[\"default\"], {\n icon: \"spinner\",\n className: \"mt-3 text-muted fa-2x\"\n }));\n }\n\n var alerts = [];\n var form = null;\n\n if (this.state.fetchError) {\n alerts.push( /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](_elements_alert__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n key: \"error-fetch\",\n title: \"Error fetching data\",\n type: \"danger\",\n message: /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", null, this.state.fetchError, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"br\", null), \"You can meanwhile return to the\\xA0\", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](react_router_dom__WEBPACK_IMPORTED_MODULE_3__[\"Link\"], {\n to: \"/admin/users\"\n }, \"user overview\"))\n }));\n } else {\n var _loop = function _loop(i) {\n alerts.push( /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](_elements_alert__WEBPACK_IMPORTED_MODULE_2__[\"default\"], _extends({\n key: \"error-\" + i,\n onClose: function onClose() {\n return _this4.removeAlert(i);\n }\n }, _this4.state.alerts[i])));\n };\n\n for (var i = 0; i < this.state.alerts.length; i++) {\n _loop(i);\n }\n\n var possibleOptions = [];\n var renderedOptions = [];\n\n var _loop2 = function _loop2(groupId) {\n if (_this4.state.groups.hasOwnProperty(groupId)) {\n var groupName = _this4.state.groups[groupId].name;\n var groupColor = _this4.state.groups[groupId].color;\n\n if (_this4.state.user.groups.hasOwnProperty(groupId)) {\n renderedOptions.push( /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"li\", {\n className: \"select2-selection__choice\",\n key: \"group-\" + groupId,\n title: groupName,\n style: {\n backgroundColor: groupColor\n }\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"span\", {\n className: \"select2-selection__choice__remove\",\n role: \"presentation\",\n onClick: function onClick(e) {\n return _this4.onRemoveGroup(e, groupId);\n }\n }, \"\\xD7\"), groupName));\n } else {\n if (_this4.state.searchString.length === 0 || groupName.toLowerCase().includes(_this4.state.searchString.toLowerCase())) {\n possibleOptions.push( /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"li\", {\n className: \"select2-results__option\",\n role: \"option\",\n key: \"group-\" + groupId,\n \"aria-selected\": false,\n onClick: function onClick(e) {\n return _this4.onAddGroup(e, groupId);\n }\n }, groupName));\n }\n }\n }\n };\n\n for (var groupId in this.state.groups) {\n _loop2(groupId);\n }\n\n var searchWidth = \"100%\";\n var placeholder = \"Select Groups\";\n var searchVisible = this.state.searchString.length > 0 || this.state.searchActive ? \"block\" : \"none\";\n\n if (renderedOptions.length > 0) {\n searchWidth = 0.75 + this.state.searchString.length * 0.75 + \"em\";\n placeholder = \"\";\n }\n\n form = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"form\", {\n role: \"form\",\n onSubmit: this.onSubmitForm.bind(this)\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"form-group\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"label\", {\n htmlFor: \"username\"\n }, \"Username\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"input\", {\n type: \"text\",\n className: \"form-control\",\n placeholder: \"Enter username\",\n name: \"username\",\n id: \"username\",\n maxLength: 32,\n value: this.state.user.name,\n onChange: this.onChangeInput.bind(this)\n })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"form-group\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"label\", {\n htmlFor: \"email\"\n }, \"E-Mail\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"input\", {\n type: \"email\",\n className: \"form-control\",\n placeholder: \"E-Mail address\",\n id: \"email\",\n name: \"email\",\n maxLength: 64,\n value: this.state.user.email,\n onChange: this.onChangeInput.bind(this)\n })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"form-group\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"label\", {\n htmlFor: \"password\"\n }, \"Password\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"input\", {\n type: \"password\",\n className: \"form-control\",\n placeholder: \"(unchanged)\",\n id: \"password\",\n name: \"password\",\n value: this.state.user.password,\n onChange: this.onChangeInput.bind(this)\n })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"form-group position-relative\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"label\", null, \"Groups\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"span\", {\n className: \"select2 select2-container select2-container--default select2-container--below\",\n dir: \"ltr\",\n style: {\n width: \"100%\"\n }\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"span\", {\n className: \"selection\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"span\", {\n className: \"select2-selection select2-selection--multiple\",\n role: \"combobox\",\n \"aria-haspopup\": \"true\",\n \"aria-expanded\": false,\n \"aria-disabled\": false,\n onClick: this.onToggleSearch.bind(this)\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"ul\", {\n className: \"select2-selection__rendered\"\n }, renderedOptions, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"li\", {\n className: \"select2-search select2-search--inline\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"input\", {\n className: \"select2-search__field\",\n type: \"search\",\n tabIndex: 0,\n autoComplete: \"off\",\n autoCorrect: \"off\",\n autoCapitalize: \"none\",\n spellCheck: false,\n role: \"searchbox\",\n \"aria-autocomplete\": \"list\",\n placeholder: placeholder,\n name: \"search\",\n style: {\n width: searchWidth\n },\n value: this.state.searchString,\n onChange: this.onChangeInput.bind(this),\n ref: this.searchBox\n }))))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"span\", {\n className: \"dropdown-wrapper\",\n \"aria-hidden\": \"true\"\n })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"span\", {\n className: \"select2-container select2-container--default select2-container--open\",\n style: {\n position: \"absolute\",\n bottom: 0,\n left: 0,\n width: \"100%\",\n display: searchVisible\n }\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"span\", {\n className: \"select2-dropdown select2-dropdown--below\",\n dir: \"ltr\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"span\", {\n className: \"select2-results\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"ul\", {\n className: \"select2-results__options\",\n role: \"listbox\",\n \"aria-multiselectable\": true,\n \"aria-expanded\": true,\n \"aria-hidden\": false\n }, possibleOptions))))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](react_router_dom__WEBPACK_IMPORTED_MODULE_3__[\"Link\"], {\n to: \"/admin/users\",\n className: \"btn btn-info mt-2 mr-2\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](_elements_icon__WEBPACK_IMPORTED_MODULE_1__[\"default\"], {\n icon: \"arrow-left\"\n }), \"\\xA0Back\"), this.state.isSaving ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"button\", {\n type: \"submit\",\n className: \"btn btn-primary mt-2\",\n disabled: true\n }, \"Saving\\u2026\\xA0\", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](_elements_icon__WEBPACK_IMPORTED_MODULE_1__[\"default\"], {\n icon: \"circle-notch\"\n })) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"button\", {\n type: \"submit\",\n className: \"btn btn-primary mt-2\"\n }, \"Save\"));\n }\n\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](react__WEBPACK_IMPORTED_MODULE_0__[\"Fragment\"], null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"content-header\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"container-fluid\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"row mb-2\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"col-sm-6\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"h1\", {\n className: \"m-0 text-dark\"\n }, \"Edit User\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"col-sm-6\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"ol\", {\n className: \"breadcrumb float-sm-right\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"li\", {\n className: \"breadcrumb-item\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](react_router_dom__WEBPACK_IMPORTED_MODULE_3__[\"Link\"], {\n to: \"/admin/dashboard\"\n }, \"Home\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"li\", {\n className: \"breadcrumb-item\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](react_router_dom__WEBPACK_IMPORTED_MODULE_3__[\"Link\"], {\n to: \"/admin/users\"\n }, \"Users\")), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"li\", {\n className: \"breadcrumb-item active\"\n }, \"Add User\")))))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"content\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"row\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__[\"createElement\"](\"div\", {\n className: \"col-lg-6 pl-5 pr-5\"\n }, alerts, form))));\n }\n }]);\n\n return EditUser;\n}(react__WEBPACK_IMPORTED_MODULE_0__[\"Component\"]);\n\n\n\n//# sourceURL=webpack:///./src/views/edituser.js?"); /***/ }), diff --git a/src/src/api.js b/src/src/api.js index dc13c25..5e9e982 100644 --- a/src/src/api.js +++ b/src/src/api.js @@ -35,6 +35,10 @@ export default class API { return data && data.success && data.loggedIn; } + async editUser(id, username, email, password, groups) { + return this.apiCall("user/edit", { "id": id, "username": username, "email": email, "password": password, "groups": groups }); + } + async logout() { return this.apiCall("user/logout"); } diff --git a/src/src/include/select2.min.css b/src/src/include/select2.min.css new file mode 100644 index 0000000..4d566a7 --- /dev/null +++ b/src/src/include/select2.min.css @@ -0,0 +1 @@ +.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;height:1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important;white-space:nowrap !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px;padding:1px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #fff;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#fff;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right;margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb} diff --git a/src/src/views/edituser.js b/src/src/views/edituser.js index e22adfa..3aa418f 100644 --- a/src/src/views/edituser.js +++ b/src/src/views/edituser.js @@ -2,6 +2,7 @@ import * as React from "react"; import Icon from "../elements/icon"; import Alert from "../elements/alert"; import {Link} from "react-router-dom"; +import "../include/select2.min.css"; export default class EditUser extends React.Component { @@ -13,33 +14,102 @@ export default class EditUser extends React.Component { this.state = { user: {}, - errors: [], + alerts: [], fetchError: null, loaded: false, - isSaving: false - } + isSaving: false, + groups: { }, + searchString: "", + searchActive: false + }; + + this.searchBox = React.createRef(); } - removeError(i) { - if (i >= 0 && i < this.state.errors.length) { - let errors = this.state.errors.slice(); - errors.splice(i, 1); - this.setState({...this.state, errors: errors}); + removeAlert(i) { + if (i >= 0 && i < this.state.alerts.length) { + let alerts = this.state.alerts.slice(); + alerts.splice(i, 1); + this.setState({...this.state, alerts: alerts}); } } componentDidMount() { this.parent.api.getUser(this.props.match.params["userId"]).then((res) => { if (res.success) { - this.setState({ ...this.state, user: res.user, loaded: true }); + this.setState({ ...this.state, user: {... res.user, password: ""} }); + this.parent.api.fetchGroups(1, 50).then((res) => { + if (res.success) { + this.setState({ ...this.state, groups: res.groups, loaded: true }); + } else { + this.setState({ ...this.state, fetchError: res.msg, loaded: true }); + } + }); } else { this.setState({ ...this.state, fetchError: res.msg, loaded: true }); } }); } - render() { + onChangeInput(event) { + const target = event.target; + const value = target.value; + const name = target.name; + if (name === "search") { + this.setState({ ...this.state, searchString: value }); + } else { + this.setState({ ...this.state, user: { ...this.state.user, [name]: value } }); + } + } + + onToggleSearch(e) { + e.stopPropagation(); + this.setState({ ...this.state, searchActive: !this.state.searchActive }); + this.searchBox.current.focus(); + } + + onSubmitForm(event) { + event.preventDefault(); + event.stopPropagation(); + const id = this.props.match.params["userId"]; + const username = this.state.user["name"]; + const email = this.state.user["email"]; + let password = this.state.user["password"].length > 0 ? this.state.user["password"] : null; + let groups = Object.keys(this.state.user.groups); + + this.setState({ ...this.state, isSaving: true}); + this.parent.api.editUser(id, username, email, password, groups).then((res) => { + let alerts = this.state.alerts.slice(); + + if (res.success) { + alerts.push({ title: "Success", message: "User was successfully updated.", type: "success" }); + this.setState({ ...this.state, isSaving: false, alerts: alerts, user: { ...this.state.user, password: "" } }); + } else { + alerts.push({ title: "Error updating user", message: res.msg, type: "danger" }); + this.setState({ ...this.state, isSaving: false, alerts: alerts, user: { ...this.state.user, password: "" } }); + } + }); + } + + onRemoveGroup(event, groupId) { + event.stopPropagation(); + if (this.state.user.groups.hasOwnProperty(groupId)) { + let groups = { ...this.state.user.groups }; + delete groups[groupId]; + this.setState({ ...this.state, user: { ...this.state.user, groups: groups }}); + } + } + + onAddGroup(event, groupId) { + event.stopPropagation(); + if (!this.state.user.groups.hasOwnProperty(groupId)) { + let groups = { ...this.state.user.groups, [groupId]: { ...this.state.groups[groupId] } }; + this.setState({ ...this.state, user: { ...this.state.user, groups: groups }, searchActive: false, searchString: "" }); + } + } + + render() { if (!this.state.loaded) { return

Loading…
@@ -47,31 +117,112 @@ export default class EditUser extends React.Component {

} - let errors = []; + let alerts = []; let form = null; if(this.state.fetchError) { - errors.push( - {this.state.fetchError}
You can meanwhile return to the  user overview }/> ) } else { - for (let i = 0; i < this.state.errors.length; i++) { - errors.push( this.removeError(i)} {...this.state.errors[i]}/>) + + for (let i = 0; i < this.state.alerts.length; i++) { + alerts.push( this.removeAlert(i)} {...this.state.alerts[i]}/>) } - form =
e.preventDefault()}> + let possibleOptions = []; + let renderedOptions = []; + for (let groupId in this.state.groups) { + if (this.state.groups.hasOwnProperty(groupId)) { + let groupName = this.state.groups[groupId].name; + let groupColor = this.state.groups[groupId].color; + if (this.state.user.groups.hasOwnProperty(groupId)) { + renderedOptions.push( +
  • + this.onRemoveGroup(e, groupId)}> + Ă— + + {groupName} +
  • + ); + } else { + if (this.state.searchString.length === 0 || groupName.toLowerCase().includes(this.state.searchString.toLowerCase())) { + possibleOptions.push( +
  • this.onAddGroup(e, groupId)}> + {groupName} +
  • + ); + } + } + } + } + + let searchWidth = "100%"; + let placeholder = "Select Groups"; + let searchVisible = (this.state.searchString.length > 0 || this.state.searchActive) ? "block" : "none"; + if (renderedOptions.length > 0) { + searchWidth = (0.75 + this.state.searchString.length * 0.75) + "em"; + placeholder = ""; + } + + form =
    + name={"username"} id={"username"} maxLength={32} value={this.state.user.name} + onChange={this.onChangeInput.bind(this)}/>
    + id={"email"} name={"email"} maxLength={64} value={this.state.user.email} + onChange={this.onChangeInput.bind(this)}/> +
    + +
    + + +
    + +
    + + + + +
      + {renderedOptions} +
    • + +
    • +
    +
    +
    + + + + +
      + {possibleOptions} +
    +
    +
    +
    @@ -105,7 +256,7 @@ export default class EditUser extends React.Component {
    - {errors} + {alerts} {form}