From ffc4a8809446cd54a3e8cbe92b4fde683249f6b2 Mon Sep 17 00:00:00 2001 From: Bachir Soussi Chiadmi Date: Fri, 20 Nov 2020 10:39:19 +0100 Subject: [PATCH] improved my folders display on header --- .../custom/materiotheme/assets/dist/main.css | 70 ++++++++++++------ .../custom/materiotheme/assets/dist/main.js | 6 +- .../assets/styles/base/_animations.scss | 11 +++ .../materiotheme/assets/styles/main.scss | 71 ++++++++++++------- .../vuejs/components/User/UserFlags.vue | 39 +++++++--- .../materiotheme/vuejs/store/modules/user.js | 60 +++++++++------- 6 files changed, 172 insertions(+), 85 deletions(-) create mode 100644 web/themes/custom/materiotheme/assets/styles/base/_animations.scss diff --git a/web/themes/custom/materiotheme/assets/dist/main.css b/web/themes/custom/materiotheme/assets/dist/main.css index b94a906..2e17584 100644 --- a/web/themes/custom/materiotheme/assets/dist/main.css +++ b/web/themes/custom/materiotheme/assets/dist/main.css @@ -1179,6 +1179,14 @@ main[role="main"] { main[role="main"] > .wrapper { width: 100vw; } +@keyframes rotating { + from { + transform: rotate(0deg); + transform-origin: center; } + to { + transform: rotate(360deg); + transform-origin: center; } } + body { font-size: 16px; font-family: "Ubuntu",Arial,"MS Trebuchet",sans-serif; @@ -1271,23 +1279,26 @@ header[role="banner"] { position: relative; } header[role="banner"] #user-flags h2 { cursor: pointer; } + header[role="banner"] #user-flags h2:before { + padding-right: 0.2em; } header[role="banner"] #user-flags ul { - position: absolute; - width: 8em; - left: 0; background-color: #fff; - border-radius: 3px; - background-clip: padding-box; - box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2); - padding: 0.3em 0.3em 0.5em; - opacity: 0; + overflow: hidden; + width: 11em; max-height: 1px; - transition: opacity,max-height 0.3s ease-in-out; - overflow: hidden; } + padding: 0.01em 1em; + box-sizing: content-box; + transition: all 0.4s ease-in-out; + transition-delay: 2s; + position: absolute; + right: 0; + top: 1.7em; + box-sizing: content-box; } header[role="banner"] #user-flags:hover ul { - opacity: 1; - max-height: 100px; - transition: opacity,max-height 0.2s ease-in-out; } + transition-delay: 0s; + max-height: 12em; + padding: 1em 1em; + box-shadow: 0 0 10px #ccc; } header[role="banner"] #user-flags li { width: 100%; display: flex; @@ -1302,17 +1313,32 @@ header[role="banner"] { opacity: 0; transition: opacity 0.3s ease-in-out; padding-left: 0.5em; } + header[role="banner"] #user-flags li div.actions span.mdi { + cursor: pointer; + color: #4e4d4d; } + header[role="banner"] #user-flags li div.actions span.delete-btn.loading:before { + animation: rotating 2s linear infinite; } header[role="banner"] #user-flags li:hover div.actions { opacity: 1; } - header[role="banner"] #user-flags li input { - border: 1px solid #bbb; - border-radius: 5px; - width: calc(100% - 2em); - font-size: 0.8em; } - header[role="banner"] #user-flags li span.mdi-plus-box, - header[role="banner"] #user-flags li span.mdi-trash-can-outline { - cursor: pointer; - color: #4e4d4d; } + header[role="banner"] #user-flags li.create-flag { + margin-top: 0.2em; } + header[role="banner"] #user-flags li.create-flag input { + align-self: flex-end; + border: 1px solid #bbb; + border-radius: 5px; + width: calc(100% - 2em); + font-size: 0.8em; } + header[role="banner"] #user-flags li.create-flag span.add-btn { + align-self: flex-end; + color: #bbb; + font-size: 1em; + padding: 0 0 0 .5em; + transition: all 0.2s ease-in-out; } + header[role="banner"] #user-flags li.create-flag span.add-btn.active { + cursor: pointer; + color: #1a1a1a; } + header[role="banner"] #user-flags li.create-flag span.add-btn.loading:before { + animation: rotating 2s linear infinite; } header[role="banner"] #block-header { margin-right: 1em; padding-left: 1em; diff --git a/web/themes/custom/materiotheme/assets/dist/main.js b/web/themes/custom/materiotheme/assets/dist/main.js index 94558a7..8888e15 100644 --- a/web/themes/custom/materiotheme/assets/dist/main.js +++ b/web/themes/custom/materiotheme/assets/dist/main.js @@ -609,7 +609,7 @@ eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _vuex = __webpack_require__(/*! vuex */ \"./node_modules/vuex/dist/vuex.esm.js\");\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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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\nvar _default = {\n name: \"userFlags\",\n data: function data() {\n return {\n new_folder_name: \"\",\n is_creating_folder: false\n };\n },\n computed: _objectSpread({}, (0, _vuex.mapState)({\n flags: function flags(state) {\n return state.User.flags;\n }\n })),\n methods: _objectSpread({}, (0, _vuex.mapActions)({\n createFlag: 'User/createFlag',\n deleteFlag: 'User/deleteFlag'\n }), {\n onCreateFlag: function onCreateFlag() {\n var _this = this;\n\n console.log(\"UserFlags onCreateFlag\", this.new_folder_name);\n this.createFlag(this.new_folder_name).then(function (data) {\n console.log(\"onCreateFlag then\", data);\n _this.new_folder_name = \"\";\n });\n },\n onDeleteFlag: function onDeleteFlag(e) {\n var _this2 = this;\n\n var flagid = e.target.getAttribute('flagid');\n console.log(\"UserFlags onDeleteFlag\", flagid);\n this.deleteFlag(flagid).then(function (data) {\n console.log(\"onDeleteFlag then\", data);\n _this2.new_folder_name = \"\";\n });\n }\n })\n};\nexports.default = _default;\n\n//# sourceURL=webpack:///./web/themes/custom/materiotheme/vuejs/components/User/UserFlags.vue?./node_modules/babel-loader/lib!./node_modules/vue-loader/lib??vue-loader-options"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _vuex = __webpack_require__(/*! vuex */ \"./node_modules/vuex/dist/vuex.esm.js\");\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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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\nvar _default = {\n name: \"userFlags\",\n data: function data() {\n return {\n new_folder_name: \"\",\n is_creating_folder: false,\n is_deleting_folder: false\n };\n },\n computed: _objectSpread({}, (0, _vuex.mapState)({\n flags: function flags(state) {\n return state.User.flags;\n }\n }), {\n addFlagBtnClassObj: function addFlagBtnClassObj() {\n return {\n 'mdi-plus-circle-outline': !this.is_creating_folder,\n 'mdi-loading': this.is_creating_folder,\n active: this.new_folder_name.length > 4 && !this.is_creating_folder,\n loading: this.is_creating_folder\n };\n },\n flagDeletingClassObj: function flagDeletingClassObj() {\n return {\n 'mdi-trash-can-outline': !this.is_deleting_folder,\n 'mdi-loading': this.is_deleting_folder,\n 'loading': this.is_deleting_folder\n };\n }\n }),\n methods: _objectSpread({}, (0, _vuex.mapActions)({\n createFlag: 'User/createFlag',\n deleteFlag: 'User/deleteFlag'\n }), {\n onCreateFlag: function onCreateFlag() {\n var _this = this;\n\n console.log(\"UserFlags onCreateFlag\", this.new_folder_name);\n this.is_creating_folder = true;\n this.createFlag(this.new_folder_name).then(function (data) {\n console.log(\"onCreateFlag then\", data);\n _this.new_folder_name = \"\";\n _this.is_creating_folder = false;\n });\n },\n onDeleteFlag: function onDeleteFlag(e) {\n var _this2 = this;\n\n var flagid = e.target.getAttribute('flagid');\n console.log(\"UserFlags onDeleteFlag\", flagid);\n this.is_deleting_folder = flagid;\n this.deleteFlag(flagid).then(function () {\n // console.log(\"onDeleteFlag then\", data);\n _this2.is_deleting_folder = false;\n });\n }\n })\n};\nexports.default = _default;\n\n//# sourceURL=webpack:///./web/themes/custom/materiotheme/vuejs/components/User/UserFlags.vue?./node_modules/babel-loader/lib!./node_modules/vue-loader/lib??vue-loader-options"); /***/ }), @@ -970,7 +970,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__, \"render\", function() { return render; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"staticRenderFns\", function() { return staticRenderFns; });\nvar render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"user-flags\" } }, [\n _c(\"h2\", { staticClass: \"mdi mdi-folder-outline\" }, [_vm._v(\"My folders\")]),\n _vm._v(\" \"),\n _c(\n \"ul\",\n [\n _vm._l(_vm.flags, function(flag) {\n return _vm.flags\n ? _c(\"li\", { key: flag.id }, [\n _c(\"h5\", [_vm._v(_vm._s(flag.name))]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"actions\" }, [\n _c(\"span\", {\n staticClass: \"mdi mdi-trash-can-outline\",\n attrs: { flagid: flag.id },\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.onDeleteFlag($event)\n }\n }\n })\n ])\n ])\n : _vm._e()\n }),\n _vm._v(\" \"),\n _c(\"li\", { ref: \"create-flag\" }, [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.new_folder_name,\n expression: \"new_folder_name\"\n }\n ],\n attrs: { placeholder: \"new folder\" },\n domProps: { value: _vm.new_folder_name },\n on: {\n input: function($event) {\n if ($event.target.composing) {\n return\n }\n _vm.new_folder_name = $event.target.value\n }\n }\n }),\n _vm._v(\" \"),\n _vm.new_folder_name && !_vm.is_creating_folder\n ? _c(\"span\", {\n staticClass: \"mdi mdi-plus-box\",\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.onCreateFlag($event)\n }\n }\n })\n : _vm._e()\n ])\n ],\n 2\n )\n ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\n\n\n//# sourceURL=webpack:///./web/themes/custom/materiotheme/vuejs/components/User/UserFlags.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"render\", function() { return render; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"staticRenderFns\", function() { return staticRenderFns; });\nvar render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\"div\", { attrs: { id: \"user-flags\" } }, [\n _c(\"h2\", { staticClass: \"mdi mdi-folder-outline\" }, [_vm._v(\"My folders\")]),\n _vm._v(\" \"),\n _c(\n \"ul\",\n [\n _vm._l(_vm.flags, function(flag) {\n return _vm.flags\n ? _c(\"li\", { key: flag.id }, [\n _c(\"h5\", [_vm._v(_vm._s(flag.name))]),\n _vm._v(\" \"),\n _c(\"div\", { staticClass: \"actions\" }, [\n _c(\"span\", {\n staticClass: \"delete-btn mdi\",\n class: _vm.flagDeletingClassObj,\n attrs: { flagid: flag.id },\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.onDeleteFlag($event)\n }\n }\n })\n ])\n ])\n : _vm._e()\n }),\n _vm._v(\" \"),\n _c(\"li\", { staticClass: \"create-flag\" }, [\n _c(\"input\", {\n directives: [\n {\n name: \"model\",\n rawName: \"v-model\",\n value: _vm.new_folder_name,\n expression: \"new_folder_name\"\n }\n ],\n attrs: { placeholder: \"new folder\" },\n domProps: { value: _vm.new_folder_name },\n on: {\n input: function($event) {\n if ($event.target.composing) {\n return\n }\n _vm.new_folder_name = $event.target.value\n }\n }\n }),\n _vm._v(\" \"),\n _c(\"span\", {\n staticClass: \"add-btn mdi\",\n class: _vm.addFlagBtnClassObj,\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.onCreateFlag($event)\n }\n }\n })\n ])\n ],\n 2\n )\n ])\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\n\n\n//# sourceURL=webpack:///./web/themes/custom/materiotheme/vuejs/components/User/UserFlags.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options"); /***/ }), @@ -1963,7 +1963,7 @@ eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _restAxios = __webpack_require__(/*! vuejs/api/rest-axios */ \"./web/themes/custom/materiotheme/vuejs/api/rest-axios.js\");\n\nvar _maAxios = __webpack_require__(/*! vuejs/api/ma-axios */ \"./web/themes/custom/materiotheme/vuejs/api/ma-axios.js\");\n\nvar _querystring = _interopRequireDefault(__webpack_require__(/*! querystring */ \"./node_modules/querystring-es3/index.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n// import { JSONAPI } from 'vuejs/api/json-axios';\nvar _default = {\n namespaced: true,\n // initial state\n state: {\n uid: null,\n // username: '',\n mail: \"\",\n token: null,\n csrftoken: null,\n logout_token: null,\n isloggedin: false,\n isAdmin: false,\n isAdherent: false,\n canSearch: false,\n roles: [],\n flags: false\n },\n // getters\n getters: {},\n // mutations\n mutations: {\n SetCsrftoken: function SetCsrftoken(state, token) {\n state.csrftoken = token;\n },\n setToken: function setToken(state, data) {\n state.uid = data.current_user.uid; // state.username = data.username;\n\n state.mail = data.current_user.mail;\n state.token = data.csrf_token;\n state.isloggedin = true;\n state.logout_token = data.logout_token;\n },\n setUid: function setUid(state, uid) {\n state.uid = uid;\n state.isloggedin = true;\n },\n setUser: function setUser(state, data) {\n state.mail = data.mail[0].value;\n state.uuid = data.uuid[0].value;\n },\n setRoles: function setRoles(state, roles) {\n console.log(\"User setRoles\", roles);\n state.roles = [];\n\n for (var i = 0; i < roles.length; i++) {\n state.roles.push(roles[i].target_id);\n } // check if admin\n\n\n if (state.roles.indexOf(\"admin\") !== -1 || state.roles.indexOf(\"root\") !== -1) {\n // console.log('is admin');\n state.isAdmin = true;\n } // check if has access to search\n\n\n if (state.roles.indexOf(\"adherent\") !== -1) {\n // console.log('is admin');\n state.canSearch = true;\n state.isAdherent = true;\n }\n },\n setLoggedOut: function setLoggedOut(state) {\n console.log(\"setLoggedOut state\", state);\n state.uid = null;\n state.mail = \"\";\n state.token = null;\n state.isloggedin = false;\n state.logout_token = null;\n\n if (state.isAdmin) {\n // TODO: what if on a page where login is needed (as commerce checkout and cart)\n window.location.reload(true);\n }\n\n state.asAdmin = false;\n state.canSearch = false;\n },\n setFlags: function setFlags(state, flags) {\n console.log(\"User setFlags\", flags);\n state.flags = flags;\n }\n },\n // actions\n actions: {\n userRegister: function userRegister(_ref, credentials) {\n var dispatch = _ref.dispatch,\n commit = _ref.commit,\n state = _ref.state;\n return new Promise(function (resolve, reject) {\n _restAxios.REST.get(\"/session/token\").then(function (_ref2) {\n var token = _ref2.token;\n commit(\"SetCsrftoken\", token);\n\n _restAxios.REST.post(\"/user/register?_format=json\", credentials, {\n \"X-CSRF-Token\": state.csrftoken\n }).then(function (_ref3) {\n var data = _ref3.data;\n console.log(\"user REST registered\", data);\n dispatch(\"userLogin\", credentials).then(function () {\n resolve();\n });\n }).catch(function (error) {\n console.warn(\"Issue with register\", error);\n Promise.reject(error);\n });\n });\n });\n },\n userLogin: function userLogin(_ref4, credentials) {\n var dispatch = _ref4.dispatch,\n commit = _ref4.commit,\n state = _ref4.state;\n return new Promise(function (resolve, reject) {\n dispatch(\"getToken\", credentials).then(function () {\n dispatch(\"getUser\").then(function (userdata) {\n console.log(\"User Loggedin\");\n\n if (state.isAdmin) {\n window.location.reload(true);\n }\n\n resolve();\n });\n });\n });\n },\n getToken: function getToken(_ref5, credentials) {\n var dispatch = _ref5.dispatch,\n commit = _ref5.commit,\n state = _ref5.state;\n return _restAxios.REST.post(\"/user/login?_format=json\", credentials).then(function (_ref6) {\n var data = _ref6.data;\n console.log(\"user REST getToken data\", data);\n commit(\"setToken\", data);\n }).catch(function (error) {\n console.warn(\"Issue with getToken\", error);\n Promise.reject(error);\n });\n },\n getUser: function getUser(_ref7) {\n var dispatch = _ref7.dispatch,\n commit = _ref7.commit,\n state = _ref7.state;\n var params = {\n token: state.token\n };\n return _restAxios.REST.get(\"/user/\".concat(state.uid, \"?_format=json\"), params).then(function (_ref8) {\n var data = _ref8.data;\n console.log(\"user REST getUser data\", data);\n console.log(\"roles\", data.roles);\n commit(\"setUser\", data);\n\n if (data.roles) {\n commit(\"setRoles\", data.roles);\n }\n\n dispatch(\"getUserFlags\");\n }).catch(function (error) {\n console.warn(\"Issue with getUser\", error);\n Promise.reject(error);\n });\n },\n getUserFlags: function getUserFlags(_ref9) {\n var dispatch = _ref9.dispatch,\n commit = _ref9.commit,\n state = _ref9.state;\n // flags\n // REST.get('/flagging_collection/1?_format=json')\n // .then(( data ) => {\n // console.log('TEST FLAG REST data', data)\n // })\n // .catch(error => {\n // console.warn('Issue USER TEST FLAG REST', error)\n // Promise.reject(error)\n // })\n return _maAxios.MA.get(\"materio_flag/user_flagging_collections\").then(function (_ref10) {\n var data = _ref10.data;\n console.log(\"user MA getFlags data\", data);\n commit(\"setFlags\", data);\n }).catch(function (error) {\n console.warn(\"Issue USER MA getFlags\", error);\n Promise.reject(error);\n });\n },\n // https://drupal.stackexchange.com/questions/248539/cant-get-flagging-api-to-accept-post-request\n createFlag: function createFlag(_ref11, new_flag_name) {\n var dispatch = _ref11.dispatch,\n commit = _ref11.commit,\n state = _ref11.state;\n console.log(\"user createFlag\", new_flag_name);\n var params = {\n name: new_flag_name\n };\n return _maAxios.MA.post(\"materio_flag/create_user_flagging_collection\", params).then(function (_ref12) {\n var data = _ref12.data;\n console.log(\"user MA createFlag data\", data);\n\n if (data.status) {\n dispatch('getUserFlags');\n }\n }).catch(function (error) {\n console.warn(\"Issue USER MA createFlag\", error);\n Promise.reject(error);\n });\n },\n deleteFlag: function deleteFlag(_ref13, flagid) {\n var dispatch = _ref13.dispatch,\n commit = _ref13.commit,\n state = _ref13.state;\n console.log(\"user deleteFlag\", flagid);\n var params = {\n flagid: flagid\n };\n return _maAxios.MA.post(\"materio_flag/delete_user_flagging_collection\", params).then(function (_ref14) {\n var data = _ref14.data;\n console.log(\"user MA deleteFlag data\", data);\n dispatch('getUserFlags');\n }).catch(function (error) {\n console.warn(\"Issue USER MA createFlag\", error);\n Promise.reject(error);\n });\n },\n userLogout: function userLogout(_ref15) {\n var commit = _ref15.commit,\n state = _ref15.state;\n\n var credentials = _querystring.default.stringify({\n token: state.token\n });\n\n _restAxios.REST.post(\"/user/logout\", credentials).then(function (resp) {\n console.log(\"userLogout resp\", resp);\n commit(\"setLoggedOut\");\n }).catch(function (error) {\n console.warn(\"Issue with logout\", error);\n Promise.reject(error);\n });\n }\n }\n};\nexports.default = _default;\n\n//# sourceURL=webpack:///./web/themes/custom/materiotheme/vuejs/store/modules/user.js?"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _restAxios = __webpack_require__(/*! vuejs/api/rest-axios */ \"./web/themes/custom/materiotheme/vuejs/api/rest-axios.js\");\n\nvar _maAxios = __webpack_require__(/*! vuejs/api/ma-axios */ \"./web/themes/custom/materiotheme/vuejs/api/ma-axios.js\");\n\nvar _querystring = _interopRequireDefault(__webpack_require__(/*! querystring */ \"./node_modules/querystring-es3/index.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n// import { JSONAPI } from 'vuejs/api/json-axios';\nvar _default = {\n namespaced: true,\n // initial state\n state: {\n uid: null,\n // username: '',\n mail: \"\",\n token: null,\n csrftoken: null,\n logout_token: null,\n isloggedin: false,\n isAdmin: false,\n isAdherent: false,\n canSearch: false,\n roles: [],\n flags: false\n },\n // getters\n getters: {},\n // mutations\n mutations: {\n SetCsrftoken: function SetCsrftoken(state, token) {\n state.csrftoken = token;\n },\n setToken: function setToken(state, data) {\n state.uid = data.current_user.uid; // state.username = data.username;\n\n state.mail = data.current_user.mail;\n state.token = data.csrf_token;\n state.isloggedin = true;\n state.logout_token = data.logout_token;\n },\n setUid: function setUid(state, uid) {\n state.uid = uid;\n state.isloggedin = true;\n },\n setUser: function setUser(state, data) {\n state.mail = data.mail[0].value;\n state.uuid = data.uuid[0].value;\n },\n setRoles: function setRoles(state, roles) {\n console.log(\"User setRoles\", roles);\n state.roles = [];\n\n for (var i = 0; i < roles.length; i++) {\n state.roles.push(roles[i].target_id);\n } // check if admin\n\n\n if (state.roles.indexOf(\"admin\") !== -1 || state.roles.indexOf(\"root\") !== -1) {\n // console.log('is admin');\n state.isAdmin = true;\n } // check if has access to search\n\n\n if (state.roles.indexOf(\"adherent\") !== -1) {\n // console.log('is admin');\n state.canSearch = true;\n state.isAdherent = true;\n }\n },\n setLoggedOut: function setLoggedOut(state) {\n console.log(\"setLoggedOut state\", state);\n state.uid = null;\n state.mail = \"\";\n state.token = null;\n state.isloggedin = false;\n state.logout_token = null;\n\n if (state.isAdmin) {\n // TODO: what if on a page where login is needed (as commerce checkout and cart)\n window.location.reload(true);\n }\n\n state.asAdmin = false;\n state.canSearch = false;\n },\n setFlags: function setFlags(state, flags) {\n console.log(\"User setFlags\", flags);\n state.flags = flags;\n }\n },\n // actions\n actions: {\n userRegister: function userRegister(_ref, credentials) {\n var dispatch = _ref.dispatch,\n commit = _ref.commit,\n state = _ref.state;\n return new Promise(function (resolve, reject) {\n _restAxios.REST.get(\"/session/token\").then(function (_ref2) {\n var token = _ref2.token;\n commit(\"SetCsrftoken\", token);\n\n _restAxios.REST.post(\"/user/register?_format=json\", credentials, {\n \"X-CSRF-Token\": state.csrftoken\n }).then(function (_ref3) {\n var data = _ref3.data;\n console.log(\"user REST registered\", data);\n dispatch(\"userLogin\", credentials).then(function () {\n resolve();\n });\n }).catch(function (error) {\n console.warn(\"Issue with register\", error);\n Promise.reject(error);\n });\n });\n });\n },\n userLogin: function userLogin(_ref4, credentials) {\n var dispatch = _ref4.dispatch,\n commit = _ref4.commit,\n state = _ref4.state;\n return new Promise(function (resolve, reject) {\n dispatch(\"getToken\", credentials).then(function () {\n dispatch(\"getUser\").then(function (userdata) {\n console.log(\"User Loggedin\");\n\n if (state.isAdmin) {\n window.location.reload(true);\n }\n\n resolve();\n });\n });\n });\n },\n getToken: function getToken(_ref5, credentials) {\n var dispatch = _ref5.dispatch,\n commit = _ref5.commit,\n state = _ref5.state;\n return _restAxios.REST.post(\"/user/login?_format=json\", credentials).then(function (_ref6) {\n var data = _ref6.data;\n console.log(\"user REST getToken data\", data);\n commit(\"setToken\", data);\n }).catch(function (error) {\n console.warn(\"Issue with getToken\", error);\n Promise.reject(error);\n });\n },\n getUser: function getUser(_ref7) {\n var dispatch = _ref7.dispatch,\n commit = _ref7.commit,\n state = _ref7.state;\n var params = {\n token: state.token\n };\n return _restAxios.REST.get(\"/user/\".concat(state.uid, \"?_format=json\"), params).then(function (_ref8) {\n var data = _ref8.data;\n console.log(\"user REST getUser data\", data);\n console.log(\"roles\", data.roles);\n commit(\"setUser\", data);\n\n if (data.roles) {\n commit(\"setRoles\", data.roles);\n }\n\n dispatch(\"getUserFlags\");\n }).catch(function (error) {\n console.warn(\"Issue with getUser\", error);\n Promise.reject(error);\n });\n },\n getUserFlags: function getUserFlags(_ref9) {\n var dispatch = _ref9.dispatch,\n commit = _ref9.commit,\n state = _ref9.state;\n // flags\n // REST.get('/flagging_collection/1?_format=json')\n // .then(( data ) => {\n // console.log('TEST FLAG REST data', data)\n // })\n // .catch(error => {\n // console.warn('Issue USER TEST FLAG REST', error)\n // Promise.reject(error)\n // })\n return _maAxios.MA.get(\"materio_flag/user_flagging_collections\").then(function (_ref10) {\n var data = _ref10.data;\n console.log(\"user MA getFlags data\", data);\n commit(\"setFlags\", data);\n }).catch(function (error) {\n console.warn(\"Issue USER MA getFlags\", error);\n Promise.reject(error);\n });\n },\n // https://drupal.stackexchange.com/questions/248539/cant-get-flagging-api-to-accept-post-request\n createFlag: function createFlag(_ref11, new_flag_name) {\n var dispatch = _ref11.dispatch,\n commit = _ref11.commit,\n state = _ref11.state;\n console.log(\"user createFlag\", new_flag_name);\n return new Promise(function (resolve, reject) {\n var params = {\n name: new_flag_name\n };\n\n _maAxios.MA.post(\"materio_flag/create_user_flagging_collection\", params).then(function (_ref12) {\n var data = _ref12.data;\n console.log(\"user MA createFlag data\", data);\n\n if (data.status) {\n dispatch('getUserFlags').then(function () {\n resolve();\n });\n }\n }).catch(function (error) {\n console.warn(\"Issue USER MA createFlag\", error);\n reject(error);\n });\n });\n },\n deleteFlag: function deleteFlag(_ref13, flagid) {\n var dispatch = _ref13.dispatch,\n commit = _ref13.commit,\n state = _ref13.state;\n console.log(\"user deleteFlag\", flagid);\n return new Promise(function (resolve, reject) {\n var params = {\n flagid: flagid\n };\n\n _maAxios.MA.post(\"materio_flag/delete_user_flagging_collection\", params).then(function (_ref14) {\n var data = _ref14.data;\n console.log(\"user MA deleteFlag data\", data);\n dispatch('getUserFlags').then(function () {\n resolve();\n });\n }).catch(function (error) {\n console.warn(\"Issue USER MA createFlag\", error);\n reject(error);\n });\n });\n },\n userLogout: function userLogout(_ref15) {\n var commit = _ref15.commit,\n state = _ref15.state;\n\n var credentials = _querystring.default.stringify({\n token: state.token\n });\n\n _restAxios.REST.post(\"/user/logout\", credentials).then(function (resp) {\n console.log(\"userLogout resp\", resp);\n commit(\"setLoggedOut\");\n }).catch(function (error) {\n console.warn(\"Issue with logout\", error);\n Promise.reject(error);\n });\n }\n }\n};\nexports.default = _default;\n\n//# sourceURL=webpack:///./web/themes/custom/materiotheme/vuejs/store/modules/user.js?"); /***/ }) diff --git a/web/themes/custom/materiotheme/assets/styles/base/_animations.scss b/web/themes/custom/materiotheme/assets/styles/base/_animations.scss new file mode 100644 index 0000000..1f46cc4 --- /dev/null +++ b/web/themes/custom/materiotheme/assets/styles/base/_animations.scss @@ -0,0 +1,11 @@ + +@keyframes rotating { + from { + transform: rotate(0deg); + transform-origin: center; + } + to { + transform: rotate(360deg); + transform-origin: center; + } +} diff --git a/web/themes/custom/materiotheme/assets/styles/main.scss b/web/themes/custom/materiotheme/assets/styles/main.scss index e796b43..bf57377 100644 --- a/web/themes/custom/materiotheme/assets/styles/main.scss +++ b/web/themes/custom/materiotheme/assets/styles/main.scss @@ -11,8 +11,7 @@ @import './base/colors'; @import './base/grid'; @import './base/layout'; -// $mdi-font-path: "./mdi/fonts"; -// @import './mdi/scss/materialdesignicons.scss'; +@import './base/animations'; @import './base/fonts'; @@ -156,26 +155,30 @@ header[role="banner"]{ h2{ @extend %header-fs; cursor: pointer; + &:before{padding-right: 0.2em;} } ul{ - position: absolute; - width:8em; - left:0; background-color: #fff; - border-radius: 3px; - background-clip: padding-box; - box-shadow: 0px 0px 5px rgba(0,0,0,0.2); - padding:0.3em 0.3em 0.5em; - opacity:0; - max-height:1px; - transition: opacity,max-height 0.3s ease-in-out; overflow: hidden; + width:11em; + max-height:1px; + padding:0.01em 1em; + // margin:0 0 0 -1em; + box-sizing:content-box; + transition: all 0.4s ease-in-out; + // outline: 1px solid blue; + transition-delay: 2s; + position: absolute; + right:0; + top:1.7em; + box-sizing: content-box; } &:hover{ ul{ - opacity:1; - max-height:100px; - transition: opacity,max-height 0.2s ease-in-out; + transition-delay: 0s; + max-height:12em; + padding:1em 1em; + box-shadow: 0 0 10px #ccc; } } li{ @@ -196,6 +199,16 @@ header[role="banner"]{ opacity:0; transition: opacity 0.3s ease-in-out; padding-left:0.5em; + + span.mdi{ + cursor: pointer; + color: #4e4d4d; + } + span.delete-btn{ + &.loading:before{ + animation: rotating 2s linear infinite; + } + } } &:hover{ div.actions{ @@ -203,19 +216,29 @@ header[role="banner"]{ } } - input{ + &.create-flag{ + margin-top: 0.2em; + input{ + align-self: flex-end; border: 1px solid #bbb; border-radius:5px; width: calc(100% - 2em); font-size:0.8em; - // border: none; - // background-color:rgb(201, 201, 201); - // width:100%; - } - span.mdi-plus-box, - span.mdi-trash-can-outline{ - cursor: pointer; - color: #4e4d4d; + } + span.add-btn{ + align-self: flex-end; + color: #bbb; + font-size: 1em; + padding: 0 0 0 .5em; + transition: all 0.2s ease-in-out; + &.active{ + cursor: pointer; + color:#1a1a1a; + } + &.loading:before{ + animation: rotating 2s linear infinite; + } + } } } } diff --git a/web/themes/custom/materiotheme/vuejs/components/User/UserFlags.vue b/web/themes/custom/materiotheme/vuejs/components/User/UserFlags.vue index 638010d..01e2345 100644 --- a/web/themes/custom/materiotheme/vuejs/components/User/UserFlags.vue +++ b/web/themes/custom/materiotheme/vuejs/components/User/UserFlags.vue @@ -8,21 +8,21 @@
{{ flag.name }}
-
  • +
  • @@ -38,12 +38,28 @@ export default { name: "userFlags", data: () => ({ new_folder_name: "", - is_creating_folder: false + is_creating_folder: false, + is_deleting_folder: false }), computed: { ...mapState({ flags: state => state.User.flags - }) + }), + addFlagBtnClassObj() { + return { + 'mdi-plus-circle-outline': !this.is_creating_folder, + 'mdi-loading': this.is_creating_folder, + active: this.new_folder_name.length > 4 && !this.is_creating_folder, + loading: this.is_creating_folder + } + }, + flagDeletingClassObj() { + return { + 'mdi-trash-can-outline': !this.is_deleting_folder, + 'mdi-loading': this.is_deleting_folder, + 'loading': this.is_deleting_folder + } + } }, methods: { ...mapActions({ @@ -52,19 +68,22 @@ export default { }), onCreateFlag () { console.log("UserFlags onCreateFlag", this.new_folder_name) + this.is_creating_folder = true; this.createFlag(this.new_folder_name) .then(data => { console.log("onCreateFlag then", data); this.new_folder_name = ""; + this.is_creating_folder = false; }) }, onDeleteFlag (e) { let flagid = e.target.getAttribute('flagid'); console.log("UserFlags onDeleteFlag", flagid); + this.is_deleting_folder = flagid; this.deleteFlag(flagid) - .then(data => { - console.log("onDeleteFlag then", data); - this.new_folder_name = ""; + .then(() => { + // console.log("onDeleteFlag then", data); + this.is_deleting_folder = false; }) } } diff --git a/web/themes/custom/materiotheme/vuejs/store/modules/user.js b/web/themes/custom/materiotheme/vuejs/store/modules/user.js index dce7808..609a803 100644 --- a/web/themes/custom/materiotheme/vuejs/store/modules/user.js +++ b/web/themes/custom/materiotheme/vuejs/store/modules/user.js @@ -175,35 +175,43 @@ export default { // https://drupal.stackexchange.com/questions/248539/cant-get-flagging-api-to-accept-post-request createFlag({ dispatch, commit, state }, new_flag_name) { console.log("user createFlag", new_flag_name); - const params = { - name: new_flag_name - }; - return MA.post("materio_flag/create_user_flagging_collection", params) - .then(({ data }) => { - console.log("user MA createFlag data", data); - if (data.status) { - dispatch('getUserFlags'); - } - }) - .catch(error => { - console.warn("Issue USER MA createFlag", error); - Promise.reject(error); - }); + return new Promise((resolve, reject) => { + const params = { + name: new_flag_name + }; + MA.post("materio_flag/create_user_flagging_collection", params) + .then(({ data }) => { + console.log("user MA createFlag data", data); + if (data.status) { + dispatch('getUserFlags').then(() => { + resolve(); + }) + } + }) + .catch(error => { + console.warn("Issue USER MA createFlag", error); + reject(error); + }); + }); }, deleteFlag({ dispatch, commit, state }, flagid) { console.log("user deleteFlag", flagid); - const params = { - flagid: flagid - }; - return MA.post("materio_flag/delete_user_flagging_collection", params) - .then(({ data }) => { - console.log("user MA deleteFlag data", data); - dispatch('getUserFlags'); - }) - .catch(error => { - console.warn("Issue USER MA createFlag", error); - Promise.reject(error); - }); + return new Promise((resolve, reject) => { + const params = { + flagid: flagid + }; + MA.post("materio_flag/delete_user_flagging_collection", params) + .then(({ data }) => { + console.log("user MA deleteFlag data", data); + dispatch('getUserFlags').then(() =>{ + resolve(); + }); + }) + .catch(error => { + console.warn("Issue USER MA createFlag", error); + reject(error); + }); + }); }, userLogout({ commit, state }) { const credentials = qs.stringify({