From 80082174443d197b74ba01b1b880c1808d6cd48e Mon Sep 17 00:00:00 2001 From: bach Date: Mon, 5 Apr 2021 12:45:58 +0200 Subject: [PATCH] search filters ok, to be improved on results pertinance --- .../materio_sapi/src/Controller/Base.php | 19 ++++++++++ .../custom/materiotheme/assets/dist/main.css | 19 ++++++++-- .../custom/materiotheme/assets/dist/main.js | 8 ++-- .../materiotheme/assets/styles/main.scss | 14 ++++++- .../vuejs/components/Form/SearchForm.vue | 37 +++++++++++++++---- .../vuejs/components/Pages/Base.vue | 22 ++++++++--- .../vuejs/components/cardMixins.js | 4 +- .../vuejs/store/modules/search.js | 9 +++++ 8 files changed, 107 insertions(+), 25 deletions(-) diff --git a/web/modules/custom/materio_sapi/src/Controller/Base.php b/web/modules/custom/materio_sapi/src/Controller/Base.php index e56f305..1168498 100644 --- a/web/modules/custom/materio_sapi/src/Controller/Base.php +++ b/web/modules/custom/materio_sapi/src/Controller/Base.php @@ -86,6 +86,18 @@ class Base extends ControllerBase { $this->query->setOption('termid', $this->term); } + // filter the search + if ($this->filters) { + $filters_conditions = $this->query->createConditionGroup('OR'); + foreach ($this->filters as $filter) { + $filter = (int) $filter; + foreach (['tag_tid', 'thesaurus_tid'] as $field) { + $filters_conditions->addCondition($field, $filter); + } + } + $this->query->addConditionGroup($filters_conditions); + } + // Restrict the search to specific languages. $lang = \Drupal::languageManager()->getCurrentLanguage()->getId(); $this->query->setLanguages([$lang]); @@ -137,7 +149,14 @@ class Base extends ControllerBase { // $this->keys = Tags::explode($this->keys); \Drupal::logger('materio_sapi')->notice($this->keys); } + // get the exacte term id in case of autocomplete $this->term = $request->query->get('term'); + // get the filters of advanced search + $f = $request->query->get('filters'); + $this->filters = strlen($f) ? explode(',', $f) : null; + // $this->allparams = $request->query->all(); + // $request->attributes->get('_raw_variables')->get('filters') + // $this->offset = $request->query->get('offset') ?? $this->offset; $this->limit = $request->query->get('limit') ?? $this->limit; } diff --git a/web/themes/custom/materiotheme/assets/dist/main.css b/web/themes/custom/materiotheme/assets/dist/main.css index 4743582..32d3c19 100644 --- a/web/themes/custom/materiotheme/assets/dist/main.css +++ b/web/themes/custom/materiotheme/assets/dist/main.css @@ -19759,10 +19759,21 @@ header[role="banner"] { border-radius: 14px; padding: 0.3em; color: #666; } - header[role="banner"] #block-materiosapisearchblock #materio-sapi-search-form #edit-filters .ss-main .ss-single-selected { - border-radius: 15px; } - header[role="banner"] #block-materiosapisearchblock #materio-sapi-search-form #edit-filters .ss-main .ss-content { - width: auto; } + header[role="banner"] #block-materiosapisearchblock #materio-sapi-search-form #edit-filters .ss-main { + font-size: 0.756em; } + header[role="banner"] #block-materiosapisearchblock #materio-sapi-search-form #edit-filters .ss-main .ss-single-selected { + border-radius: 0.7em; + height: 1.5em; + border: none; + padding: 0 0.5em; + background-color: #e2e2e2; } + header[role="banner"] #block-materiosapisearchblock #materio-sapi-search-form #edit-filters .ss-main .ss-single-selected span.placeholder { + color: #1A1A1A; + line-height: 1; } + header[role="banner"] #block-materiosapisearchblock #materio-sapi-search-form #edit-filters .ss-main .ss-single-selected span.placeholder span.ss-disabled { + color: #616161; } + header[role="banner"] #block-materiosapisearchblock #materio-sapi-search-form #edit-filters .ss-main .ss-content { + width: auto; } header[role="banner"] #block-materiosapisearchblock #materio-sapi-search-form .button.form-submit { border: 0; text-indent: 50px; diff --git a/web/themes/custom/materiotheme/assets/dist/main.js b/web/themes/custom/materiotheme/assets/dist/main.js index 9df20a3..a7aa7de 100644 --- a/web/themes/custom/materiotheme/assets/dist/main.js +++ b/web/themes/custom/materiotheme/assets/dist/main.js @@ -1008,7 +1008,7 @@ eval("\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n})); /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.default = void 0;\n\nvar _vue = _interopRequireDefault(__webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.js\"));\n\nvar _route = _interopRequireDefault(__webpack_require__(/*! vuejs/route */ \"./web/themes/custom/materiotheme/vuejs/route/index.js\"));\n\nvar _vuex = __webpack_require__(/*! vuex */ \"./node_modules/vuex/dist/vuex.esm.js\");\n\nvar _slimSelect = _interopRequireDefault(__webpack_require__(/*! slim-select */ \"./node_modules/slim-select/dist/slimselect.min.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\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\nvar _default = {\n router: _route.default,\n props: ['form'],\n data: function data() {\n return {\n template: null,\n typed: null,\n autocomplete: null,\n $input: null // basePath: drupalSettings.path.baseUrl + drupalSettings.path.pathPrefix\n\n };\n },\n computed: _objectSpread({}, (0, _vuex.mapState)({\n keys: function keys(state) {\n return state.Search.keys;\n },\n term: function term(state) {\n return state.Search.term;\n }\n })),\n methods: {\n submit: function submit() {\n console.log(\"search submited\", this.typed, this.autocomplete); // unfocus the text input to hide the keyboard on mobile device\n\n this.$input.blur(); // New search is triggered by Base.vue with router (which will also fill the store)\n\n this.$router.push({\n name: 'base',\n query: {\n keys: this.typed,\n term: this.autocomplete\n }\n }); // this.$router.push({\n // path:`${this.basePath}/base`,\n // query:{keys:this.typed,term:this.autocomplete}\n // })\n },\n onAutoCompleteSelect: function onAutoCompleteSelect(event, ui) {\n event.preventDefault();\n console.log('autoCompleteSelect', event, ui);\n this.typed = ui.item.label; // we have to wait for typed watch to reset autocomplete before setting it\n\n setTimeout(function () {\n console.log('update autocomplete value after settimeout');\n this.autocomplete = ui.item.value;\n\n if (this.typed !== this.keys || this.autocomplete !== this.term) {\n this.submit();\n }\n }.bind(this), 1);\n }\n },\n directives: {\n focus: {\n // directive definition\n inserted: function inserted(el) {// do not focus the input as it popup the keyboard on mobile device\n // el.focus()\n }\n }\n },\n beforeMount: function beforeMount() {\n var _this = this;\n\n // console.log('SearchForm beforeMount')\n if (this._props.form) {\n // console.log('SearchForm beforeMount if this._props.form ok')\n this.template = _vue.default.compile(this._props.form); // https://github.com/vuejs/vue/issues/9911\n\n this.$options.staticRenderFns = [];\n this._staticTrees = [];\n this.template.staticRenderFns.map(function (fn) {\n return _this.$options.staticRenderFns.push(fn);\n });\n }\n },\n watch: {\n typed: function typed(n, o) {\n console.log('typed changed', o, n); // is changed also when autocomplete change it ...\n\n this.autocomplete = null;\n },\n keys: function keys(n, o) {\n console.log('keys changed', o, n);\n this.typed = n;\n },\n term: function term(n, o) {\n console.log('autocomplete changed', o, n);\n this.autocomplete = n;\n }\n },\n created: function created() {\n this.typed = this.keys;\n this.autocomplete = this.term;\n },\n mounted: function mounted() {\n // console.log('SearchForm mounted')\n Drupal.attachBehaviors(this.$el); // get the search input\n\n this.$input = this.$el.querySelector('#edit-search'); // // focus on input\n // $input.focus()\n // Catch the jquery ui events for autocmplete widget\n\n jQuery(this.$input).on('autocompleteselect', this.onAutoCompleteSelect); // customize the select filters\n // http://slimselectjs.com/options\n\n var selects = this.$el.querySelectorAll('select');\n selects.forEach(function (selectElement) {\n var placeholder_option = selectElement.querySelector('option:first-child');\n console.log('placeholder_option', placeholder_option);\n var placeholder = placeholder_option.innerText;\n placeholder_option.removeAttribute(\"value\"); // let attr = document.createAttribute('data-placeholder')\n // attr.value = true\n\n placeholder_option.setAttribute(\"data-placeholder\", true);\n placeholder_option.innerHTML = '';\n new _slimSelect.default({\n select: selectElement,\n placeholder: placeholder,\n // allowDeselect: true\n allowDeselectOption: true,\n showSearch: false,\n closeOnSelect: false,\n onChange: function onChange(info) {\n console.log(info);\n }\n });\n });\n },\n render: function render(h) {\n // console.log('searchForm render')\n if (!this.template) {\n return h('span', 'Loading ...');\n } else {\n return this.template.render.call(this);\n }\n }\n};\nexports.default = _default;\n\n//# sourceURL=webpack://materio.com/./web/themes/custom/materiotheme/vuejs/components/Form/SearchForm.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/index.js??vue-loader-options"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.default = void 0;\n\nvar _vue = _interopRequireDefault(__webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.js\"));\n\nvar _route = _interopRequireDefault(__webpack_require__(/*! vuejs/route */ \"./web/themes/custom/materiotheme/vuejs/route/index.js\"));\n\nvar _vuex = __webpack_require__(/*! vuex */ \"./node_modules/vuex/dist/vuex.esm.js\");\n\nvar _slimSelect = _interopRequireDefault(__webpack_require__(/*! slim-select */ \"./node_modules/slim-select/dist/slimselect.min.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\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\nvar _default = {\n router: _route.default,\n props: ['form'],\n data: function data() {\n return {\n template: null,\n typed: null,\n autocomplete: null,\n slimFilters: [],\n $input: null // basePath: drupalSettings.path.baseUrl + drupalSettings.path.pathPrefix\n\n };\n },\n computed: _objectSpread({}, (0, _vuex.mapState)({\n keys: function keys(state) {\n return state.Search.keys;\n },\n term: function term(state) {\n return state.Search.term;\n },\n filters: function filters(state) {\n return state.Search.filters;\n }\n })),\n methods: {\n submit: function submit() {\n console.log(\"search submited\", this.typed, this.autocomplete); // unfocus the text input to hide the keyboard on mobile device\n\n this.$input.blur(); // New search is triggered by Base.vue with router (which will also fill the store)\n // cleaning slimfilters\n\n var filters = [];\n this.slimFilters.forEach(function (filter, index) {\n console.log('foreach filters', filter);\n\n if (filter) {\n filters.push(filter);\n }\n });\n console.log('Cleaning filters', this.slimFilters, filters); // push router\n\n this.$router.push({\n name: 'base',\n query: {\n keys: this.typed,\n term: this.autocomplete,\n filters: filters.join(',')\n }\n }); // this.$router.push({\n // path:`${this.basePath}/base`,\n // query:{keys:this.typed,term:this.autocomplete}\n // })\n },\n onAutoCompleteSelect: function onAutoCompleteSelect(event, ui) {\n event.preventDefault();\n console.log('autoCompleteSelect', event, ui);\n this.typed = ui.item.label; // we have to wait for typed watch to reset autocomplete before setting it\n\n setTimeout(function () {\n console.log('update autocomplete value after settimeout');\n this.autocomplete = ui.item.value;\n\n if (this.typed !== this.keys || this.autocomplete !== this.term) {\n this.submit();\n }\n }.bind(this), 1);\n },\n onSelectFiltersChange: function onSelectFiltersChange(index, info) {\n console.log('onSelectFiltersChange', index, info, this.filters);\n this.slimFilters[index] = info.value;\n }\n },\n directives: {\n focus: {\n // directive definition\n inserted: function inserted(el) {// do not focus the input as it popup the keyboard on mobile device\n // el.focus()\n }\n }\n },\n beforeMount: function beforeMount() {\n var _this = this;\n\n // console.log('SearchForm beforeMount')\n if (this._props.form) {\n // console.log('SearchForm beforeMount if this._props.form ok')\n this.template = _vue.default.compile(this._props.form); // https://github.com/vuejs/vue/issues/9911\n\n this.$options.staticRenderFns = [];\n this._staticTrees = [];\n this.template.staticRenderFns.map(function (fn) {\n return _this.$options.staticRenderFns.push(fn);\n });\n }\n },\n watch: {\n typed: function typed(n, o) {\n console.log('typed changed', o, n); // is changed also when autocomplete change it ...\n\n this.autocomplete = null;\n },\n keys: function keys(n, o) {\n console.log('keys changed', o, n);\n this.typed = n;\n },\n term: function term(n, o) {\n console.log('autocomplete changed', o, n);\n this.autocomplete = n;\n }\n },\n created: function created() {\n this.typed = this.keys;\n this.autocomplete = this.term;\n },\n mounted: function mounted() {\n var _this2 = this;\n\n // console.log('SearchForm mounted')\n Drupal.attachBehaviors(this.$el); // get the search input\n\n this.$input = this.$el.querySelector('#edit-search'); // // focus on input\n // $input.focus()\n // Catch the jquery ui events for autocmplete widget\n\n jQuery(this.$input).on('autocompleteselect', this.onAutoCompleteSelect); // customize the select filters\n // http://slimselectjs.com/options\n\n var selects = this.$el.querySelectorAll('select');\n selects.forEach(function (selectElement, index) {\n // get the first option to make the placeholder then empty it\n var placeholder_option = selectElement.querySelector('option:first-child'); // console.log('placeholder_option', placeholder_option);\n\n var placeholder = placeholder_option.innerText;\n placeholder_option.removeAttribute(\"value\");\n placeholder_option.setAttribute(\"data-placeholder\", true);\n placeholder_option.innerHTML = '';\n new _slimSelect.default({\n select: selectElement,\n placeholder: placeholder,\n // allowDeselect: true\n allowDeselectOption: true,\n showSearch: false,\n closeOnSelect: true,\n onChange: function onChange(info) {\n _this2.onSelectFiltersChange(index, info);\n }\n });\n });\n },\n render: function render(h) {\n // console.log('searchForm render')\n if (!this.template) {\n return h('span', 'Loading ...');\n } else {\n return this.template.render.call(this);\n }\n }\n};\nexports.default = _default;\n\n//# sourceURL=webpack://materio.com/./web/themes/custom/materiotheme/vuejs/components/Form/SearchForm.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/index.js??vue-loader-options"); /***/ }), @@ -1052,7 +1052,7 @@ eval("\n\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.default = void 0;\n\nvar _Card = _interopRequireDefault(__webpack_require__(/*! vuejs/components/Content/Card */ \"./web/themes/custom/materiotheme/vuejs/components/Content/Card.vue\"));\n\nvar _CardThematique = _interopRequireDefault(__webpack_require__(/*! vuejs/components/Content/CardThematique */ \"./web/themes/custom/materiotheme/vuejs/components/Content/CardThematique.vue\"));\n\nvar _vuex = __webpack_require__(/*! vuex */ \"./node_modules/vuex/dist/vuex.esm.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\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\nvar _default = {\n name: \"Base\",\n data: function data() {\n return {\n pagetitle: \"Base\" // searchinfos: null\n\n };\n },\n computed: _objectSpread({}, (0, _vuex.mapState)({\n items: function items(state) {\n return state.Search.items;\n },\n searchinfos: function searchinfos(state) {\n return state.Search.infos;\n },\n count: function count(state) {\n return state.Search.count;\n },\n noresults: function noresults(state) {\n return state.Search.noresults;\n },\n limit: function limit(state) {\n return state.Search.limit;\n }\n })),\n methods: _objectSpread({}, (0, _vuex.mapActions)({\n newSearch: 'Search/newSearch',\n nextPage: 'Search/nextPage'\n })),\n created: function created() {\n // at first page load or first route entering launch a search if params exists in url query\n console.log('Base created() location', window.location);\n var params = new URLSearchParams(window.location.search);\n\n if (params.has('keys') || params.has('term')) {\n this.$store.commit('Search/setKeys', params.get('keys'));\n this.$store.commit('Search/setTerm', params.get('term'));\n this.pagetitle = params.get('keys');\n this.newSearch();\n } else {\n // load default base page\n this.$store.commit('Search/setKeys', '');\n this.$store.commit('Search/setTerm', '');\n this.pagetitle = 'Base';\n this.newSearch();\n }\n },\n beforeRouteUpdate: function beforeRouteUpdate(to, from, next) {\n // when query change launch a new search\n console.log('Base beforeRouteUpdate', to, from, next);\n this.$store.commit('Search/setKeys', to.query.keys);\n this.$store.commit('Search/setTerm', to.query.term);\n this.pagetitle = to.query.keys;\n this.newSearch();\n next();\n },\n components: {\n Card: _Card.default,\n CardThematique: _CardThematique.default\n }\n};\nexports.default = _default;\n\n//# sourceURL=webpack://materio.com/./web/themes/custom/materiotheme/vuejs/components/Pages/Base.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/index.js??vue-loader-options"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.default = void 0;\n\nvar _Card = _interopRequireDefault(__webpack_require__(/*! vuejs/components/Content/Card */ \"./web/themes/custom/materiotheme/vuejs/components/Content/Card.vue\"));\n\nvar _CardThematique = _interopRequireDefault(__webpack_require__(/*! vuejs/components/Content/CardThematique */ \"./web/themes/custom/materiotheme/vuejs/components/Content/CardThematique.vue\"));\n\nvar _vuex = __webpack_require__(/*! vuex */ \"./node_modules/vuex/dist/vuex.esm.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\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\nvar _default = {\n name: \"Base\",\n data: function data() {\n return {\n pagetitle: \"Base\" // searchinfos: null\n\n };\n },\n computed: _objectSpread({}, (0, _vuex.mapState)({\n items: function items(state) {\n return state.Search.items;\n },\n searchinfos: function searchinfos(state) {\n return state.Search.infos;\n },\n count: function count(state) {\n return state.Search.count;\n },\n noresults: function noresults(state) {\n return state.Search.noresults;\n },\n limit: function limit(state) {\n return state.Search.limit;\n }\n })),\n methods: _objectSpread({}, (0, _vuex.mapActions)({\n newSearch: 'Search/newSearch',\n nextPage: 'Search/nextPage'\n })),\n created: function created() {\n // at first page load or first route entering launch a search if params exists in url query\n console.log('Base created() location', window.location);\n var params = new URLSearchParams(window.location.search);\n\n if (params.has('keys')) {\n this.$store.commit('Search/setKeys', params.get('keys'));\n this.pagetitle = params.get('keys');\n } else {\n this.$store.commit('Search/setKeys', '');\n this.pagetitle = 'Base';\n }\n\n if (params.has('term')) {\n this.$store.commit('Search/setTerm', params.get('term'));\n } else {\n this.$store.commit('Search/setTerm', '');\n }\n\n if (params.has('filters')) {\n this.$store.commit('Search/setFilters', params.get('filters').split(','));\n } else {\n this.$store.commit('Search/setFilters', []);\n }\n\n this.newSearch();\n },\n beforeRouteUpdate: function beforeRouteUpdate(to, from, next) {\n // when query change launch a new search\n console.log('Base beforeRouteUpdate', to, from, next);\n this.$store.commit('Search/setKeys', to.query.keys);\n this.$store.commit('Search/setTerm', to.query.term);\n this.$store.commit('Search/setFilters', to.query.filters);\n this.pagetitle = to.query.keys;\n this.newSearch();\n next();\n },\n components: {\n Card: _Card.default,\n CardThematique: _CardThematique.default\n }\n};\nexports.default = _default;\n\n//# sourceURL=webpack://materio.com/./web/themes/custom/materiotheme/vuejs/components/Pages/Base.vue?./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/index.js??vue-loader-options"); /***/ }), @@ -1280,7 +1280,7 @@ eval("\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n})); /***/ ((__unused_webpack_module, exports) => { "use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.default = void 0;\n// https://forum.vuejs.org/t/how-to-use-helper-functions-for-imported-modules-in-vuejs-vue-template/6266/5\nvar _default = {\n directives: {\n lazy: {\n bind: function bind(img, binding) {\n // console.log('lazy bind', img, binding)\n // show only the first image\n if (binding.value === 0) {\n img.setAttribute('src', img.getAttribute('data-src'));\n img.removeAttribute('data-src');\n img.classList.remove('lazy');\n }\n }\n },\n switcher: {\n inserted: function inserted(el, binding) {\n // switch images on mousemove\n el.addEventListener('mousemove', function (event) {\n var figs = this.querySelectorAll('figure'); // console.log('mousemove', this, event, figs.length)\n // let len = figs.length\n // let w = this.clientWidth;\n // let g = w / len;\n // let delta = Math.floor(event.layerX / g)\n\n var delta = Math.floor(event.layerX / (this.clientWidth / figs.length)); // console.log('delta', delta)\n\n figs.forEach(function (fig, index) {\n // console.log(index)\n if (index === delta) {\n // fig.style.display = \"block\"\n fig.classList.remove('hide');\n fig.classList.add('show');\n } else {\n // fig.style.display = \"none\"\n fig.classList.remove('show');\n fig.classList.add('hide');\n }\n });\n });\n }\n }\n },\n mounted: function mounted() {\n // lazy load images on mouseover\n console.log('card mounted', this.$options.name); // if (this.$options.name ==! 'ModalCard') {\n\n this.$el.addEventListener('mouseover', function (event) {\n var imgs = this.querySelectorAll('.images figure img.lazy');\n console.log('mousemove', this, imgs);\n imgs.forEach(function (img) {\n // console.log('forEach img',img)\n img.setAttribute('src', img.getAttribute('data-src'));\n img.removeAttribute('data-src');\n img.classList.remove('lazy');\n });\n }, {\n once: true\n }); // }\n },\n methods: {\n activateLazyLoad: function activateLazyLoad() {\n console.log('card activateLazyLoad', this.$options.name);\n this.$el.addEventListener('mousemove', function (event) {\n var imgs = this.querySelectorAll('.images figure img.lazy');\n console.log('mousemove', this, imgs);\n imgs.forEach(function (img) {\n // console.log('forEach img',img)\n img.setAttribute('src', img.getAttribute('data-src'));\n img.removeAttribute('data-src');\n img.classList.remove('lazy');\n });\n }, {\n once: true\n });\n } // deg2rad (deg) {\n // return deg * (Math.PI / 180)\n // },\n\n }\n};\nexports.default = _default;\n\n//# sourceURL=webpack://materio.com/./web/themes/custom/materiotheme/vuejs/components/cardMixins.js?"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.default = void 0;\n// https://forum.vuejs.org/t/how-to-use-helper-functions-for-imported-modules-in-vuejs-vue-template/6266/5\nvar _default = {\n directives: {\n lazy: {\n bind: function bind(img, binding) {\n // console.log('lazy bind', img, binding)\n // show only the first image\n if (binding.value === 0) {\n img.setAttribute('src', img.getAttribute('data-src'));\n img.removeAttribute('data-src');\n img.classList.remove('lazy');\n }\n }\n },\n switcher: {\n inserted: function inserted(el, binding) {\n // switch images on mousemove\n el.addEventListener('mousemove', function (event) {\n var figs = this.querySelectorAll('figure'); // console.log('mousemove', this, event, figs.length)\n // let len = figs.length\n // let w = this.clientWidth;\n // let g = w / len;\n // let delta = Math.floor(event.layerX / g)\n\n var delta = Math.floor(event.layerX / (this.clientWidth / figs.length)); // console.log('delta', delta)\n\n figs.forEach(function (fig, index) {\n // console.log(index)\n if (index === delta) {\n // fig.style.display = \"block\"\n fig.classList.remove('hide');\n fig.classList.add('show');\n } else {\n // fig.style.display = \"none\"\n fig.classList.remove('show');\n fig.classList.add('hide');\n }\n });\n });\n }\n }\n },\n mounted: function mounted() {\n // lazy load images on mouseover\n console.log('card mounted', this.$options.name); // if (this.$options.name ==! 'ModalCard') {\n\n this.$el.addEventListener('mouseover', function (event) {\n var imgs = this.querySelectorAll('.images figure img.lazy'); // console.log('mousemove', this, imgs)\n\n imgs.forEach(function (img) {\n // console.log('forEach img',img)\n img.setAttribute('src', img.getAttribute('data-src'));\n img.removeAttribute('data-src');\n img.classList.remove('lazy');\n });\n }, {\n once: true\n }); // }\n },\n methods: {\n activateLazyLoad: function activateLazyLoad() {\n console.log('card activateLazyLoad', this.$options.name);\n this.$el.addEventListener('mousemove', function (event) {\n var imgs = this.querySelectorAll('.images figure img.lazy'); // console.log('mousemove', this, imgs)\n\n imgs.forEach(function (img) {\n // console.log('forEach img',img)\n img.setAttribute('src', img.getAttribute('data-src'));\n img.removeAttribute('data-src');\n img.classList.remove('lazy');\n });\n }, {\n once: true\n });\n } // deg2rad (deg) {\n // return deg * (Math.PI / 180)\n // },\n\n }\n};\nexports.default = _default;\n\n//# sourceURL=webpack://materio.com/./web/themes/custom/materiotheme/vuejs/components/cardMixins.js?"); /***/ }), @@ -1357,7 +1357,7 @@ eval("\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n})); /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.default = void 0;\n\nvar _maAxios = __webpack_require__(/*! vuejs/api/ma-axios */ \"./web/themes/custom/materiotheme/vuejs/api/ma-axios.js\");\n\nvar _querystringEs = _interopRequireDefault(__webpack_require__(/*! querystring-es3 */ \"./node_modules/querystring-es3/index.js\"));\n\nvar _vue = _interopRequireDefault(__webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.js\"));\n\nvar _graphqlAxios = __webpack_require__(/*! vuejs/api/graphql-axios */ \"./web/themes/custom/materiotheme/vuejs/api/graphql-axios.js\");\n\nvar _printer = __webpack_require__(/*! graphql/language/printer */ \"./node_modules/graphql/language/printer.js\");\n\nvar _graphqlTag = _interopRequireDefault(__webpack_require__(/*! graphql-tag */ \"./node_modules/graphql-tag/src/index.js\"));\n\nvar _searchresultsFragment = _interopRequireDefault(__webpack_require__(/*! vuejs/api/gql/searchresults.fragment.gql */ \"./web/themes/custom/materiotheme/vuejs/api/gql/searchresults.fragment.gql\"));\n\nvar _templateObject, _templateObject2;\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }\n\nvar _default = {\n namespaced: true,\n // initial state\n state: {\n keys: '',\n term: '',\n uuids: [],\n items: [],\n offset: 0,\n limit: 15,\n infos: null,\n count: 0,\n noresults: false,\n // infinteState will come from vue-infinite-loading plugin\n // implemented in vuejs/components/Content/Base.vue\n infiniteLoadingState: null\n },\n // getters\n getters: {},\n // mutations\n mutations: {\n setUuids: function setUuids(state, uuids) {\n state.uuids = state.uuids.concat(uuids);\n },\n resetUuids: function resetUuids(state) {\n state.uuids = [];\n },\n setResults: function setResults(state, items) {\n // console.log('setResults, items', items)\n if (items) {\n // avoid bug like items = [null]\n state.items = state.items.concat(items);\n } // console.log('setResults, state.items', state.items)\n\n },\n updateItem: function updateItem(state, item) {\n // state.items[data.index] = data.item // this is not triggering vuejs refresh\n // find the right index\n var index = state.items.findIndex(function (i) {\n return i.id === item.id;\n }); // update the array\n\n if (index !== -1) {\n _vue.default.set(state.items, index, item);\n } // console.log(\"mutation updateItem state.items\", state.items)\n\n },\n resetItems: function resetItems(state) {\n state.items = [];\n },\n setKeys: function setKeys(state, keys) {\n state.keys = keys;\n },\n setTerm: function setTerm(state, term) {\n state.term = term;\n },\n setInfos: function setInfos(state, infos) {\n state.infos = infos;\n },\n setCount: function setCount(state, count) {\n state.count = count;\n },\n resetCount: function resetCount(state, count) {\n state.count = false;\n },\n setNoresults: function setNoresults(state) {\n state.noresults = true;\n },\n resetNoresults: function resetNoresults(state) {\n state.noresults = false;\n },\n resetOffset: function resetOffset(state) {\n state.offset = 0;\n },\n incrementOffset: function incrementOffset(state) {\n state.offset += state.limit;\n },\n setInfiniteState: function setInfiniteState(state, infiniteLoadingstate) {\n state.infiniteLoadingState = infiniteLoadingstate;\n }\n },\n // actions\n actions: {\n newSearch: function newSearch(_ref) {\n var dispatch = _ref.dispatch,\n commit = _ref.commit,\n state = _ref.state;\n console.log('Search newSearch');\n commit('resetUuids');\n commit('resetItems');\n commit('resetCount');\n commit('resetNoresults');\n commit('resetOffset');\n\n if (state.keys || state.term) {\n this.commit('Common/setPagetitle', state.keys);\n } else {\n this.commit('Common/setPagetitle', 'Base');\n }\n\n dispatch('getResults');\n },\n nextPage: function nextPage(_ref2, $infiniteLoadingstate) {\n var dispatch = _ref2.dispatch,\n commit = _ref2.commit,\n state = _ref2.state;\n console.log('Search nextPage', $infiniteLoadingstate);\n commit('incrementOffset');\n commit('setInfiniteState', $infiniteLoadingstate);\n dispatch('getResults');\n },\n getResults: function getResults(_ref3) {\n var dispatch = _ref3.dispatch,\n commit = _ref3.commit,\n state = _ref3.state;\n var params = {\n keys: state.keys,\n term: state.term,\n offset: state.offset,\n limit: state.limit\n }; // console.log('Search getResults params', params)\n\n var q = _querystringEs.default.stringify(params);\n\n return _maAxios.MA.get('/materio_sapi/getresults?' + q).then(function (_ref4) {\n var data = _ref4.data;\n console.log('search MA getresults data', data); // commit('setItems', data.items)\n\n commit('setInfos', data.infos);\n commit('setCount', data.count);\n\n if (data.count) {\n commit('setUuids', data.uuids); // loadMaterials is on mixins\n // https://github.com/huybuidac/vuex-extensions\n // dispatch('loadMaterialsGQL', {\n // ids: data.nids,\n // gqlfragment: materiauGQL,\n // callBack: 'loadSearchResultsCallBack'\n // })\n\n var ast = (0, _graphqlTag.default)(_templateObject || (_templateObject = _taggedTemplateLiteral([\"{\\n searchresults(ids: [\", \"], lang: \\\"\", \"\\\") {\\n ...SearchResultFields\\n }\\n }\\n \", \"\\n \"])), data.nids, drupalDecoupled.lang_code, _searchresultsFragment.default);\n\n _graphqlAxios.MGQ.post('', {\n query: (0, _printer.print)(ast)\n }).then(function (resp) {\n console.log('loadSearchResultsGQL resp', resp);\n dispatch('loadSearchResultsCallBack', {\n items: resp.data.data.searchresults\n });\n }).catch(function (error) {\n console.warn('Issue with loadSearchResults', error);\n Promise.reject(error);\n });\n } else {\n commit('setNoresults');\n }\n }).catch(function (error) {\n console.warn('Issue with getResults', error);\n Promise.reject(error);\n });\n },\n loadSearchResultsCallBack: function loadSearchResultsCallBack(_ref5, _ref6) {\n var commit = _ref5.commit,\n state = _ref5.state;\n var items = _ref6.items,\n callBackArgs = _ref6.callBackArgs;\n console.log('search loadSearchResultsCallBack', items);\n commit('setResults', items);\n\n if (state.infiniteLoadingState) {\n if (state.offset + state.limit > state.count) {\n console.log('Search infinite completed'); // tell to vue-infinite-loading plugin that there si no new page\n\n state.infiniteLoadingState.complete();\n } else {\n console.log('Search infinite loaded'); // tell to vue-infinite-loading plugin that newpage is loaded\n\n state.infiniteLoadingState.loaded();\n }\n }\n },\n refreshItem: function refreshItem(_ref7, _ref8) {\n var commit = _ref7.commit,\n state = _ref7.state;\n var id = _ref8.id;\n console.log('Search refreshItem: id', id);\n var ast = (0, _graphqlTag.default)(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral([\"{\\n searchresult(id: \", \", lang: \\\"\", \"\\\") {\\n ...SearchResultFields\\n }\\n }\\n \", \"\\n \"])), id, drupalDecoupled.lang_code, _searchresultsFragment.default);\n\n _graphqlAxios.MGQ.post('', {\n query: (0, _printer.print)(ast)\n }).then(function (resp) {\n console.log('refreshItem searchresult resp', resp); // dispatch(\"loadSearchResultsCallBack\", { items: resp.data.data.searchresults})\n\n commit('updateItem', resp.data.data.searchresult);\n }).catch(function (error) {\n console.warn('Issue with refreshItem', error);\n Promise.reject(error);\n });\n }\n }\n};\nexports.default = _default;\n\n//# sourceURL=webpack://materio.com/./web/themes/custom/materiotheme/vuejs/store/modules/search.js?"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.default = void 0;\n\nvar _maAxios = __webpack_require__(/*! vuejs/api/ma-axios */ \"./web/themes/custom/materiotheme/vuejs/api/ma-axios.js\");\n\nvar _querystringEs = _interopRequireDefault(__webpack_require__(/*! querystring-es3 */ \"./node_modules/querystring-es3/index.js\"));\n\nvar _vue = _interopRequireDefault(__webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.js\"));\n\nvar _graphqlAxios = __webpack_require__(/*! vuejs/api/graphql-axios */ \"./web/themes/custom/materiotheme/vuejs/api/graphql-axios.js\");\n\nvar _printer = __webpack_require__(/*! graphql/language/printer */ \"./node_modules/graphql/language/printer.js\");\n\nvar _graphqlTag = _interopRequireDefault(__webpack_require__(/*! graphql-tag */ \"./node_modules/graphql-tag/src/index.js\"));\n\nvar _searchresultsFragment = _interopRequireDefault(__webpack_require__(/*! vuejs/api/gql/searchresults.fragment.gql */ \"./web/themes/custom/materiotheme/vuejs/api/gql/searchresults.fragment.gql\"));\n\nvar _templateObject, _templateObject2;\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }\n\nvar _default = {\n namespaced: true,\n // initial state\n state: {\n keys: '',\n term: '',\n filters: [],\n uuids: [],\n items: [],\n offset: 0,\n limit: 15,\n infos: null,\n count: 0,\n noresults: false,\n // infinteState will come from vue-infinite-loading plugin\n // implemented in vuejs/components/Content/Base.vue\n infiniteLoadingState: null\n },\n // getters\n getters: {},\n // mutations\n mutations: {\n setUuids: function setUuids(state, uuids) {\n state.uuids = state.uuids.concat(uuids);\n },\n resetUuids: function resetUuids(state) {\n state.uuids = [];\n },\n setResults: function setResults(state, items) {\n // console.log('setResults, items', items)\n if (items) {\n // avoid bug like items = [null]\n state.items = state.items.concat(items);\n } // console.log('setResults, state.items', state.items)\n\n },\n updateItem: function updateItem(state, item) {\n // state.items[data.index] = data.item // this is not triggering vuejs refresh\n // find the right index\n var index = state.items.findIndex(function (i) {\n return i.id === item.id;\n }); // update the array\n\n if (index !== -1) {\n _vue.default.set(state.items, index, item);\n } // console.log(\"mutation updateItem state.items\", state.items)\n\n },\n resetItems: function resetItems(state) {\n state.items = [];\n },\n setKeys: function setKeys(state, keys) {\n state.keys = keys;\n },\n setTerm: function setTerm(state, term) {\n state.term = term;\n },\n setFilters: function setFilters(state, filters) {\n console.log('store search setFilters', filters);\n state.filters = filters;\n },\n setInfos: function setInfos(state, infos) {\n state.infos = infos;\n },\n setCount: function setCount(state, count) {\n state.count = count;\n },\n resetCount: function resetCount(state, count) {\n state.count = false;\n },\n setNoresults: function setNoresults(state) {\n state.noresults = true;\n },\n resetNoresults: function resetNoresults(state) {\n state.noresults = false;\n },\n resetOffset: function resetOffset(state) {\n state.offset = 0;\n },\n incrementOffset: function incrementOffset(state) {\n state.offset += state.limit;\n },\n setInfiniteState: function setInfiniteState(state, infiniteLoadingstate) {\n state.infiniteLoadingState = infiniteLoadingstate;\n }\n },\n // actions\n actions: {\n newSearch: function newSearch(_ref) {\n var dispatch = _ref.dispatch,\n commit = _ref.commit,\n state = _ref.state;\n console.log('Search newSearch');\n commit('resetUuids');\n commit('resetItems');\n commit('resetCount');\n commit('resetNoresults');\n commit('resetOffset');\n\n if (state.keys || state.term) {\n this.commit('Common/setPagetitle', state.keys);\n } else {\n this.commit('Common/setPagetitle', 'Base');\n }\n\n dispatch('getResults');\n },\n nextPage: function nextPage(_ref2, $infiniteLoadingstate) {\n var dispatch = _ref2.dispatch,\n commit = _ref2.commit,\n state = _ref2.state;\n console.log('Search nextPage', $infiniteLoadingstate);\n commit('incrementOffset');\n commit('setInfiniteState', $infiniteLoadingstate);\n dispatch('getResults');\n },\n getResults: function getResults(_ref3) {\n var dispatch = _ref3.dispatch,\n commit = _ref3.commit,\n state = _ref3.state;\n var params = {\n keys: state.keys,\n term: state.term,\n offset: state.offset,\n limit: state.limit\n };\n\n if (state.filters) {\n console.log('getResults filters', state.filters);\n params.filters = state.filters;\n } // console.log('Search getResults params', params)\n\n\n var q = _querystringEs.default.stringify(params);\n\n return _maAxios.MA.get('/materio_sapi/getresults?' + q).then(function (_ref4) {\n var data = _ref4.data;\n console.log('search MA getresults data', data); // commit('setItems', data.items)\n\n commit('setInfos', data.infos);\n commit('setCount', data.count);\n\n if (data.count) {\n commit('setUuids', data.uuids); // loadMaterials is on mixins\n // https://github.com/huybuidac/vuex-extensions\n // dispatch('loadMaterialsGQL', {\n // ids: data.nids,\n // gqlfragment: materiauGQL,\n // callBack: 'loadSearchResultsCallBack'\n // })\n\n var ast = (0, _graphqlTag.default)(_templateObject || (_templateObject = _taggedTemplateLiteral([\"{\\n searchresults(ids: [\", \"], lang: \\\"\", \"\\\") {\\n ...SearchResultFields\\n }\\n }\\n \", \"\\n \"])), data.nids, drupalDecoupled.lang_code, _searchresultsFragment.default);\n\n _graphqlAxios.MGQ.post('', {\n query: (0, _printer.print)(ast)\n }).then(function (resp) {\n console.log('loadSearchResultsGQL resp', resp);\n dispatch('loadSearchResultsCallBack', {\n items: resp.data.data.searchresults\n });\n }).catch(function (error) {\n console.warn('Issue with loadSearchResults', error);\n Promise.reject(error);\n });\n } else {\n commit('setNoresults');\n }\n }).catch(function (error) {\n console.warn('Issue with getResults', error);\n Promise.reject(error);\n });\n },\n loadSearchResultsCallBack: function loadSearchResultsCallBack(_ref5, _ref6) {\n var commit = _ref5.commit,\n state = _ref5.state;\n var items = _ref6.items,\n callBackArgs = _ref6.callBackArgs;\n console.log('search loadSearchResultsCallBack', items);\n commit('setResults', items);\n\n if (state.infiniteLoadingState) {\n if (state.offset + state.limit > state.count) {\n console.log('Search infinite completed'); // tell to vue-infinite-loading plugin that there si no new page\n\n state.infiniteLoadingState.complete();\n } else {\n console.log('Search infinite loaded'); // tell to vue-infinite-loading plugin that newpage is loaded\n\n state.infiniteLoadingState.loaded();\n }\n }\n },\n refreshItem: function refreshItem(_ref7, _ref8) {\n var commit = _ref7.commit,\n state = _ref7.state;\n var id = _ref8.id;\n console.log('Search refreshItem: id', id);\n var ast = (0, _graphqlTag.default)(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral([\"{\\n searchresult(id: \", \", lang: \\\"\", \"\\\") {\\n ...SearchResultFields\\n }\\n }\\n \", \"\\n \"])), id, drupalDecoupled.lang_code, _searchresultsFragment.default);\n\n _graphqlAxios.MGQ.post('', {\n query: (0, _printer.print)(ast)\n }).then(function (resp) {\n console.log('refreshItem searchresult resp', resp); // dispatch(\"loadSearchResultsCallBack\", { items: resp.data.data.searchresults})\n\n commit('updateItem', resp.data.data.searchresult);\n }).catch(function (error) {\n console.warn('Issue with refreshItem', error);\n Promise.reject(error);\n });\n }\n }\n};\nexports.default = _default;\n\n//# sourceURL=webpack://materio.com/./web/themes/custom/materiotheme/vuejs/store/modules/search.js?"); /***/ }), diff --git a/web/themes/custom/materiotheme/assets/styles/main.scss b/web/themes/custom/materiotheme/assets/styles/main.scss index 709825b..e776621 100644 --- a/web/themes/custom/materiotheme/assets/styles/main.scss +++ b/web/themes/custom/materiotheme/assets/styles/main.scss @@ -589,8 +589,20 @@ header[role="banner"]{ #edit-filters{ .ss-main{ + font-size: 0.756em; .ss-single-selected{ - border-radius: 15px; + border-radius: 0.7em; + height:1.5em; + border: none; + padding: 0 0.5em; + background-color: #e2e2e2; + span.placeholder{ + color: $color-main-text; + line-height: 1; + span.ss-disabled{ + color: #616161; + } + } } .ss-content{ width:auto; diff --git a/web/themes/custom/materiotheme/vuejs/components/Form/SearchForm.vue b/web/themes/custom/materiotheme/vuejs/components/Form/SearchForm.vue index 7ba5b22..575b5e8 100644 --- a/web/themes/custom/materiotheme/vuejs/components/Form/SearchForm.vue +++ b/web/themes/custom/materiotheme/vuejs/components/Form/SearchForm.vue @@ -16,6 +16,7 @@ export default { template: null, typed: null, autocomplete: null, + slimFilters: [], $input: null // basePath: drupalSettings.path.baseUrl + drupalSettings.path.pathPrefix } @@ -23,7 +24,8 @@ export default { computed: { ...mapState({ keys: state => state.Search.keys, - term: state => state.Search.term + term: state => state.Search.term, + filters: state => state.Search.filters }) }, methods: { @@ -32,7 +34,21 @@ export default { // unfocus the text input to hide the keyboard on mobile device this.$input.blur() // New search is triggered by Base.vue with router (which will also fill the store) - this.$router.push({name:'base', query:{keys:this.typed,term:this.autocomplete}}) + // cleaning slimfilters + let filters = [] + this.slimFilters.forEach((filter, index) => { + console.log('foreach filters', filter) + if(filter){ + filters.push(filter) + } + }) + console.log('Cleaning filters',this.slimFilters, filters) + // push router + this.$router.push({name:'base', query:{ + keys:this.typed, + term:this.autocomplete, + filters:filters.join(',') + }}) // this.$router.push({ // path:`${this.basePath}/base`, // query:{keys:this.typed,term:this.autocomplete} @@ -51,6 +67,10 @@ export default { } }.bind(this), 1) + }, + onSelectFiltersChange(index, info){ + console.log('onSelectFiltersChange', index, info, this.filters) + this.slimFilters[index] = info.value } }, directives: { @@ -99,18 +119,19 @@ export default { this.$input = this.$el.querySelector('#edit-search') // // focus on input // $input.focus() + // Catch the jquery ui events for autocmplete widget jQuery(this.$input).on('autocompleteselect', this.onAutoCompleteSelect); + // customize the select filters // http://slimselectjs.com/options const selects = this.$el.querySelectorAll('select') - selects.forEach((selectElement) => { + selects.forEach((selectElement, index) => { + // get the first option to make the placeholder then empty it const placeholder_option = selectElement.querySelector('option:first-child') - console.log('placeholder_option', placeholder_option); + // console.log('placeholder_option', placeholder_option); const placeholder = placeholder_option.innerText placeholder_option.removeAttribute("value") - // let attr = document.createAttribute('data-placeholder') - // attr.value = true placeholder_option.setAttribute("data-placeholder", true) placeholder_option.innerHTML = '' new SlimSelect({ @@ -119,9 +140,9 @@ export default { // allowDeselect: true allowDeselectOption: true, showSearch: false, - closeOnSelect: false, + closeOnSelect: true, onChange: (info) => { - console.log(info) + this.onSelectFiltersChange(index, info) } }) }) diff --git a/web/themes/custom/materiotheme/vuejs/components/Pages/Base.vue b/web/themes/custom/materiotheme/vuejs/components/Pages/Base.vue index fba082f..7fce5c0 100644 --- a/web/themes/custom/materiotheme/vuejs/components/Pages/Base.vue +++ b/web/themes/custom/materiotheme/vuejs/components/Pages/Base.vue @@ -65,24 +65,34 @@ export default { // at first page load or first route entering launch a search if params exists in url query console.log('Base created() location',window.location) let params = new URLSearchParams(window.location.search) - if (params.has('keys') || params.has('term')) { + if (params.has('keys')) { this.$store.commit('Search/setKeys', params.get('keys')) - this.$store.commit('Search/setTerm', params.get('term')) this.pagetitle = params.get('keys') - this.newSearch() } else { - // load default base page this.$store.commit('Search/setKeys', '') - this.$store.commit('Search/setTerm', '') this.pagetitle = 'Base' - this.newSearch() } + + if (params.has('term')) { + this.$store.commit('Search/setTerm', params.get('term')) + } else { + this.$store.commit('Search/setTerm', '') + } + + if (params.has('filters')) { + this.$store.commit('Search/setFilters', params.get('filters').split(',')) + } else { + this.$store.commit('Search/setFilters', []) + } + + this.newSearch() }, beforeRouteUpdate (to, from, next) { // when query change launch a new search console.log('Base beforeRouteUpdate', to, from, next) this.$store.commit('Search/setKeys', to.query.keys) this.$store.commit('Search/setTerm', to.query.term) + this.$store.commit('Search/setFilters', to.query.filters) this.pagetitle = to.query.keys this.newSearch() next() diff --git a/web/themes/custom/materiotheme/vuejs/components/cardMixins.js b/web/themes/custom/materiotheme/vuejs/components/cardMixins.js index a996684..6774534 100644 --- a/web/themes/custom/materiotheme/vuejs/components/cardMixins.js +++ b/web/themes/custom/materiotheme/vuejs/components/cardMixins.js @@ -46,7 +46,7 @@ export default { // if (this.$options.name ==! 'ModalCard') { this.$el.addEventListener('mouseover', function (event) { const imgs = this.querySelectorAll('.images figure img.lazy') - console.log('mousemove', this, imgs) + // console.log('mousemove', this, imgs) imgs.forEach((img) => { // console.log('forEach img',img) img.setAttribute('src', img.getAttribute('data-src')) @@ -62,7 +62,7 @@ export default { this.$el.addEventListener('mousemove', function (event) { const imgs = this.querySelectorAll('.images figure img.lazy') - console.log('mousemove', this, imgs) + // console.log('mousemove', this, imgs) imgs.forEach((img) => { // console.log('forEach img',img) img.setAttribute('src', img.getAttribute('data-src')) diff --git a/web/themes/custom/materiotheme/vuejs/store/modules/search.js b/web/themes/custom/materiotheme/vuejs/store/modules/search.js index 67143cd..afccb80 100644 --- a/web/themes/custom/materiotheme/vuejs/store/modules/search.js +++ b/web/themes/custom/materiotheme/vuejs/store/modules/search.js @@ -17,6 +17,7 @@ export default { state: { keys: '', term: '', + filters: [], uuids: [], items: [], offset: 0, @@ -66,6 +67,10 @@ export default { setTerm (state, term) { state.term = term }, + setFilters (state, filters) { + console.log('store search setFilters', filters) + state.filters = filters + }, setInfos (state, infos) { state.infos = infos }, @@ -121,6 +126,10 @@ export default { offset: state.offset, limit: state.limit } + if (state.filters) { + console.log('getResults filters', state.filters) + params.filters = state.filters + } // console.log('Search getResults params', params) const q = qs.stringify(params) return MA.get('/materio_sapi/getresults?' + q)