big refactoring, opening flagcollection (folder) on the left of main-content

This commit is contained in:
Bachir Soussi Chiadmi 2020-11-27 23:02:59 +01:00
parent 420a879a4e
commit 93c4707c45
19 changed files with 656 additions and 253 deletions

View File

@ -3,13 +3,13 @@ langcode: en
status: true status: true
dependencies: { } dependencies: { }
name: card_medium name: card_medium
label: 'card-medium (210x295)' label: 'card-medium (205x295)'
effects: effects:
34e936a0-1fee-4327-9553-b4f48bde14e6: 34e936a0-1fee-4327-9553-b4f48bde14e6:
uuid: 34e936a0-1fee-4327-9553-b4f48bde14e6 uuid: 34e936a0-1fee-4327-9553-b4f48bde14e6
id: image_scale_and_crop id: image_scale_and_crop
weight: 1 weight: 1
data: data:
width: 210 width: 205
height: 295 height: 295
anchor: center-center anchor: center-center

View File

@ -0,0 +1,15 @@
uuid: 56308ed7-1b40-435a-bfd0-fbf99f97e7ca
langcode: en
status: true
dependencies: { }
name: card_medium_half
label: 'card-medium-half (205x100)'
effects:
34e936a0-1fee-4327-9553-b4f48bde14e6:
uuid: 34e936a0-1fee-4327-9553-b4f48bde14e6
id: image_scale_and_crop
weight: 1
data:
width: 205
height: 100
anchor: center-center

View File

@ -210,9 +210,10 @@ resourceFields:
styles: styles:
refine: true refine: true
custom_selection: custom_selection:
- card_medium
- card_big - card_big
- card_full - card_full
- card_medium
- card_medium_half
disabled: false disabled: false
field_memo: field_memo:
disabled: true disabled: true

6
package-lock.json generated
View File

@ -11891,6 +11891,12 @@
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.0.tgz", "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.0.tgz",
"integrity": "sha512-W74OO2vCJPs9/YjNjW8lLbj+jzT24waTo2KShI8jLvJW8OaIkgb3wuAMA7D+ZiUxDOx3ubwSZTaJBip9G8a3aQ==" "integrity": "sha512-W74OO2vCJPs9/YjNjW8lLbj+jzT24waTo2KShI8jLvJW8OaIkgb3wuAMA7D+ZiUxDOx3ubwSZTaJBip9G8a3aQ=="
}, },
"vuex-extensions": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/vuex-extensions/-/vuex-extensions-1.1.5.tgz",
"integrity": "sha512-1Jfi8o6coel3jj20k6SaEtinddzS0jEG41lyyWmodAorXoN85AzuYa4oou71e99B6V+Y+gSVUysa3yHVhWpTrQ==",
"dev": true
},
"walker": { "walker": {
"version": "1.0.7", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz",

View File

@ -66,6 +66,7 @@
"vue-server-renderer": "^2.6.12", "vue-server-renderer": "^2.6.12",
"vue-style-loader": "^4.1.2", "vue-style-loader": "^4.1.2",
"vue-template-compiler": "^2.6.12", "vue-template-compiler": "^2.6.12",
"vuex-extensions": "^1.1.5",
"webpack": "^5.6.0", "webpack": "^5.6.0",
"webpack-cli": "^4.2.0", "webpack-cli": "^4.2.0",
"webpack-merge": "^5.4.0" "webpack-merge": "^5.4.0"

View File

@ -1096,60 +1096,60 @@ body.toolbar-horizontal.toolbar-themes.toolbar-no-tabs {
header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper { header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper {
margin: 0 auto; } margin: 0 auto; }
@media only screen and (min-width: 226px) and (max-width: 450px) { @media only screen and (min-width: 219px) and (max-width: 436px) {
header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper { header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper {
width: 210px; } } width: 218px; } }
@media only screen and (min-width: 451px) and (max-width: 675px) { @media only screen and (min-width: 437px) and (max-width: 654px) {
header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper { header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper {
width: 435px; } } width: 436px; } }
@media only screen and (min-width: 676px) and (max-width: 900px) { @media only screen and (min-width: 655px) and (max-width: 872px) {
header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper { header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper {
width: 660px; } } width: 654px; } }
@media only screen and (min-width: 901px) and (max-width: 1125px) { @media only screen and (min-width: 873px) and (max-width: 1090px) {
header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper { header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper {
width: 885px; } } width: 872px; } }
@media only screen and (min-width: 1126px) and (max-width: 1350px) { @media only screen and (min-width: 1091px) and (max-width: 1308px) {
header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper { header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper {
width: 1110px; } } width: 1090px; } }
@media only screen and (min-width: 1351px) and (max-width: 1575px) { @media only screen and (min-width: 1309px) and (max-width: 1526px) {
header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper { header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper {
width: 1335px; } } width: 1308px; } }
@media only screen and (min-width: 1576px) and (max-width: 1800px) { @media only screen and (min-width: 1527px) and (max-width: 1744px) {
header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper { header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper {
width: 1560px; } } width: 1526px; } }
@media only screen and (min-width: 1801px) and (max-width: 2025px) { @media only screen and (min-width: 1745px) and (max-width: 1962px) {
header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper { header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper {
width: 1785px; } } width: 1744px; } }
@media only screen and (min-width: 2026px) and (max-width: 2250px) { @media only screen and (min-width: 1963px) and (max-width: 2180px) {
header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper { header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper {
width: 2010px; } } width: 1962px; } }
@media only screen and (min-width: 2251px) and (max-width: 2475px) { @media only screen and (min-width: 2181px) and (max-width: 2398px) {
header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper { header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper {
width: 2235px; } } width: 2180px; } }
@media only screen and (min-width: 2476px) and (max-width: 2700px) { @media only screen and (min-width: 2399px) and (max-width: 2616px) {
header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper { header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper {
width: 2460px; } } width: 2398px; } }
@media only screen and (min-width: 2701px) and (max-width: 2925px) { @media only screen and (min-width: 2617px) and (max-width: 2834px) {
header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper { header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper {
width: 2685px; } } width: 2616px; } }
@media only screen and (min-width: 2926px) and (max-width: 3150px) { @media only screen and (min-width: 2835px) and (max-width: 3052px) {
header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper { header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper {
width: 2910px; } } width: 2834px; } }
@media only screen and (min-width: 3151px) and (max-width: 3375px) { @media only screen and (min-width: 3053px) and (max-width: 3270px) {
header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper { header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper {
width: 3135px; } } width: 3052px; } }
@media only screen and (min-width: 3376px) and (max-width: 3600px) { @media only screen and (min-width: 3271px) and (max-width: 3488px) {
header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper { header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper {
width: 3360px; } } width: 3270px; } }
@media only screen and (min-width: 3601px) and (max-width: 3825px) { @media only screen and (min-width: 3489px) and (max-width: 3706px) {
header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper { header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper {
width: 3585px; } } width: 3488px; } }
@media only screen and (min-width: 3826px) and (max-width: 4050px) { @media only screen and (min-width: 3707px) and (max-width: 3924px) {
header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper { header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper {
width: 3810px; } } width: 3706px; } }
@media only screen and (min-width: 4051px) and (max-width: 4275px) { @media only screen and (min-width: 3925px) and (max-width: 4142px) {
header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper { header[role="banner"] .wrapper, main[role="main"] > .scroller > .wrapper {
width: 4035px; } } width: 3924px; } }
header[role="banner"] { header[role="banner"] {
flex: 0 0 auto; flex: 0 0 auto;
@ -1182,11 +1182,12 @@ main[role="main"] {
display: flex; display: flex;
flex-direction: row-reverse; } flex-direction: row-reverse; }
main[role="main"] > .scroller > .wrapper #content-left { main[role="main"] > .scroller > .wrapper #content-left {
flex-basis: 435px; } flex-basis: 218px;
flex-shrink: 0; }
main[role="main"] > .scroller > .wrapper #content-left > * { main[role="main"] > .scroller > .wrapper #content-left > * {
width: 435px; } width: 100%; }
main[role="main"] > .scroller > .wrapper #content-center { main[role="main"] > .scroller > .wrapper #content-center {
flex-basis: 2235px; } flex-basis: 110%; }
@keyframes rotating { @keyframes rotating {
from { from {
@ -1443,11 +1444,37 @@ aside.messages {
padding: 0; } padding: 0; }
#content-left { #content-left {
z-index: 5;
box-sizing: content-box;
max-width: 1px; max-width: 1px;
overflow-x: hidden; overflow-x: hidden;
transition: all 0.3s ease-in-out; } transition: all 0.3s ease-in-out; }
#content-left.opened { #content-left.opened {
max-width: 500px; } max-width: 500px;
padding: 0.3em; }
#content-left > * {
box-sizing: border-box;
background-color: #fff;
box-shadow: -2px 0px 4px rgba(0, 0, 0, 0.2);
padding: 0.5em; }
#content-left .flag-collection > header {
display: flex;
flex-direction: row;
justify-content: space-between; }
#content-left .flag-collection > header .mdi-close {
cursor: pointer;
align-self: flex-end; }
#content-left .flag-collection > ul > li {
margin: 0 0 13px 0;
padding: 0; }
#content-left .flag-collection > ul > li article.card.minicard {
width: 100%; }
#content-left .flag-collection > ul > li article.card.minicard > header {
padding: 0.3em 0.3em 0.1em; }
#content-left .flag-collection > ul > li article.card.minicard > header h1 {
margin: 0; }
#content-left .flag-collection > ul > li article.card.minicard > nav.tools {
padding: 0 0.2em; }
article.node--type-frontpage .node__content > section.home-intro > div:nth-child(1) .field__label, article.node--type-frontpage .node__content > section.home-pricing > div:nth-child(1) .field__label, article.node--type-frontpage .node__content > section.home-database > div:nth-child(1) .field__label, article.node--type-frontpage .node__content > section.home-showrooms > div:nth-child(1) .field__label, article.node--type-frontpage .node__content > section.home-blabla > div:nth-child(1) .field__label { article.node--type-frontpage .node__content > section.home-intro > div:nth-child(1) .field__label, article.node--type-frontpage .node__content > section.home-pricing > div:nth-child(1) .field__label, article.node--type-frontpage .node__content > section.home-database > div:nth-child(1) .field__label, article.node--type-frontpage .node__content > section.home-showrooms > div:nth-child(1) .field__label, article.node--type-frontpage .node__content > section.home-blabla > div:nth-child(1) .field__label {
font-size: 3.5em; font-size: 3.5em;
@ -1515,12 +1542,12 @@ article.node--type-frontpage .node__content > section.home-showrooms {
position: relative; position: relative;
display: grid; display: grid;
grid-template-rows: 1fr; } grid-template-rows: 1fr; }
@media only screen and (max-width: 1575px) { @media only screen and (max-width: 1526px) {
article.node--type-frontpage .node__content > section.home-showrooms .field--name-computed-showrooms-reference { article.node--type-frontpage .node__content > section.home-showrooms .field--name-computed-showrooms-reference {
grid-template-columns: 1fr; } grid-template-columns: 1fr; }
article.node--type-frontpage .node__content > section.home-showrooms .field--name-computed-showrooms-reference > .field__item { article.node--type-frontpage .node__content > section.home-showrooms .field--name-computed-showrooms-reference > .field__item {
grid-column: 1; } } grid-column: 1; } }
@media only screen and (min-width: 1576px) { @media only screen and (min-width: 1527px) {
article.node--type-frontpage .node__content > section.home-showrooms .field--name-computed-showrooms-reference { article.node--type-frontpage .node__content > section.home-showrooms .field--name-computed-showrooms-reference {
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
grid-gap: 1em; } grid-gap: 1em; }
@ -1559,10 +1586,10 @@ article.node--type-frontpage .node__content > section.home-blabla {
article.node--type-frontpage .node__content > section.home-blabla .cards-list-home { article.node--type-frontpage .node__content > section.home-blabla .cards-list-home {
position: relative; position: relative;
overflow-y: hidden; } overflow-y: hidden; }
@media only screen and (max-width: 2610px) { @media only screen and (max-width: 2538px) {
article.node--type-frontpage .node__content > section.home-blabla .cards-list-home { article.node--type-frontpage .node__content > section.home-blabla .cards-list-home {
max-height: 630px; } } max-height: 630px; } }
@media only screen and (min-width: 2611px) { @media only screen and (min-width: 2539px) {
article.node--type-frontpage .node__content > section.home-blabla .cards-list-home { article.node--type-frontpage .node__content > section.home-blabla .cards-list-home {
max-height: 310px; } } max-height: 310px; } }
article.node--type-frontpage .node__content > section.home-blabla .cards-list-home ul { article.node--type-frontpage .node__content > section.home-blabla .cards-list-home ul {
@ -1570,7 +1597,7 @@ article.node--type-frontpage .node__content > section.home-blabla {
margin: 0; margin: 0;
padding: 0; padding: 0;
display: grid; display: grid;
grid-template-columns: repeat(auto-fill, minmax(80px, 420px)); grid-template-columns: repeat(auto-fill, minmax(80px, 410px));
grid-gap: 1em; grid-gap: 1em;
justify-content: start; } justify-content: start; }
article.node--type-frontpage .node__content > section.home-blabla .cards-list-home ul li { article.node--type-frontpage .node__content > section.home-blabla .cards-list-home ul li {
@ -1606,10 +1633,10 @@ article.node--type-frontpage .node__content > section.home-blabla {
.cards-list > ul { .cards-list > ul {
margin: 0; margin: 0;
padding: 0; padding: 0;
width: calc(100% + 15px); } width: calc(100% + 13px); }
.cards-list > ul > li { .cards-list > ul > li {
list-style: none; list-style: none;
margin: 0 15px 15px 0; margin: 0 13px 13px 0;
padding: 0; padding: 0;
display: inline-block; display: inline-block;
vertical-align: top; } vertical-align: top; }
@ -1617,11 +1644,13 @@ article.node--type-frontpage .node__content > section.home-blabla {
article.card { article.card {
position: relative; position: relative;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.2); box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
width: 210px; width: 205px;
height: 295px; } height: 295px; }
article.card.article { article.card.article {
width: 435px; width: 423px;
height: 295px; } height: 295px; }
article.card.minicard {
height: 100px; }
article.card header { article.card header {
position: absolute; position: absolute;
bottom: 0; bottom: 0;
@ -1707,8 +1736,8 @@ article.card {
grid-column: 2/6; } grid-column: 2/6; }
#main-content > article.article section.accroche figure { #main-content > article.article section.accroche figure {
width: 435px; width: 423px;
margin: 0 15px 0 0; } margin: 0 13px 0 0; }
#main-content > article.article section.accroche figure img { #main-content > article.article section.accroche figure img {
width: 100%; } width: 100%; }
@ -1722,18 +1751,18 @@ article.card {
#main-content > article.article div.gallery-wrapper .image { #main-content > article.article div.gallery-wrapper .image {
display: inline-block; display: inline-block;
width: 210px; width: 205px;
margin: 0 15px 9px 0; margin: 0 13px 7.8px 0;
height: 147.5px; height: 147.5px;
background-size: cover; } background-size: cover; }
#main-content > article.article aside.linked-materials ul { #main-content > article.article aside.linked-materials ul {
width: calc(100% + 15px); } width: calc(100% + 13px); }
#main-content > article.article aside.linked-materials ul li { #main-content > article.article aside.linked-materials ul li {
display: inline-block; display: inline-block;
vertical-align: top; vertical-align: top;
width: 210px; width: 205px;
margin: 0 15px 0 0; } margin: 0 13px 0 0; }
#main-content > article.article aside.linked-materials h3.field__label { #main-content > article.article aside.linked-materials h3.field__label {
font-size: 1em; font-size: 1em;
@ -1779,12 +1808,12 @@ article.card {
content: ' >'; } content: ' >'; }
#showrooms { #showrooms {
width: calc(100% + 15px); } width: calc(100% + 13px); }
#showrooms article.showroom { #showrooms article.showroom {
width: 435px; width: 423px;
display: inline-block; display: inline-block;
vertical-align: top; vertical-align: top;
margin: 0 15px 15px 0; } margin: 0 13px 13px 0; }
#showrooms article.showroom h1 { #showrooms article.showroom h1 {
margin: 0; margin: 0;
font-weight: 4; } font-weight: 4; }

File diff suppressed because one or more lines are too long

View File

@ -23,6 +23,8 @@ body.toolbar-horizontal.toolbar-themes.toolbar-no-tabs{
padding-top: 24px!important; padding-top: 24px!important;
} }
// build break points for each multiple of cards row
// cards will always be centered, using all available space
%grided-width{ %grided-width{
margin:0 auto; margin:0 auto;
$m: $column_goutiere; $m: $column_goutiere;
@ -31,7 +33,7 @@ body.toolbar-horizontal.toolbar-themes.toolbar-no-tabs{
@while $bp < 4096px { @while $bp < 4096px {
$upbp: $bp + $colw + $m; $upbp: $bp + $colw + $m;
@media only screen and (min-width: $bp + 1px) and (max-width: $upbp) { @media only screen and (min-width: $bp + 1px) and (max-width: $upbp) {
width:$bp - $m; width:$bp;
} }
$bp: $upbp; $bp: $upbp;
} }
@ -100,14 +102,15 @@ main[role="main"]{
display: flex; display: flex;
flex-direction: row-reverse; flex-direction: row-reverse;
#content-left{ #content-left{
flex-basis: $column_width*2+$column_goutiere; flex-basis: $column_width+$column_goutiere;
flex-shrink: 0;
// width:$column_width*2+$column_goutiere; // width:$column_width*2+$column_goutiere;
>*{ >*{
width:$column_width*2+$column_goutiere; width:100%;
} }
} }
#content-center{ #content-center{
flex-basis: $column_width*10+$column_goutiere*9; flex-basis: 110%;
} }
} }
} }

View File

@ -5,7 +5,7 @@ $base_font_size:16px;
// card-medium (210x295) // card-medium (210x295)
// card-small (100x140) // card-small (100x140)
$column_width: 210px; $column_width: 205px;
$column_goutiere: 15px; $column_goutiere: 13px;
$card_height: 295px; $card_height: 295px;

View File

@ -395,11 +395,55 @@ aside.messages{
// | (__/ _ \ ' \ _/ -_) ' \ _|___| |__/ -_) _| _| // | (__/ _ \ ' \ _/ -_) ' \ _|___| |__/ -_) _| _|
// \___\___/_||_\__\___|_||_\__| |____\___|_| \__| // \___\___/_||_\__\___|_||_\__| |____\___|_| \__|
#content-left{ #content-left{
z-index: 5;
box-sizing: content-box;
max-width:1px; max-width:1px;
overflow-x: hidden; overflow-x: hidden;
transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out;
&.opened{ &.opened{
max-width: 500px; max-width: 500px;
padding: 0.3em;
}
>*{
box-sizing: border-box;
background-color: #fff;
box-shadow: -2px 0px 4px rgba(0, 0, 0, 0.2);
padding: 0.5em;
}
.flag-collection{
>header{
display: flex;
flex-direction: row;
justify-content: space-between;
h3{
// flex-basis: calc(100% - 1em);
}
.mdi-close{
// display: block;
// flex-basis: 1em;
cursor:pointer;
align-self: flex-end;
}
}
>ul{
>li{
margin:0 0 $column_goutiere 0;
padding:0;
article.card.minicard{
width:100%;
>header{
padding: 0.3em 0.3em 0.1em;
h1{
margin:0;
}
}
>nav.tools{
padding:0 0.2em;
}
}
}
}
} }
} }
@ -663,6 +707,9 @@ article.card{
&.article{ &.article{
width:$column_width*2 + $column_goutiere; height:$card_height; width:$column_width*2 + $column_goutiere; height:$card_height;
} }
&.minicard{
height:100px;
}
// &.card-small{ // &.card-small{
// width:100px; height:140px; // width:100px; height:140px;
// } // }

View File

@ -1,5 +1,5 @@
<template> <template>
<article class="card"> <article class="card search-card">
<header> <header>
<h1>{{ item.title }}</h1> <h1>{{ item.title }}</h1>
<h4>{{ item.field_short_description }}</h4> <h4>{{ item.field_short_description }}</h4>
@ -45,10 +45,12 @@
<script> <script>
import { mapState, mapActions } from 'vuex' import { mapState, mapActions } from 'vuex'
import cardMixins from 'vuejs/components/cardMixins'
export default { export default {
name: "Card", name: "Card",
props: ['item'], props: ['item'],
mixins: [cardMixins],
data() { data() {
return { return {
blanksrc:`${drupalSettings.path.themePath}/assets/img/blank.gif`, blanksrc:`${drupalSettings.path.themePath}/assets/img/blank.gif`,
@ -60,54 +62,6 @@ export default {
flagcolls: state => state.User.flagcolls flagcolls: state => state.User.flagcolls
}) })
}, },
directives: {
lazy: {
bind(img,binding){
// console.log('lazy bind', img, binding);
if(binding.value === 0){
img.setAttribute('src', img.getAttribute('data-src'))
img.removeAttribute('data-src')
img.classList.remove('lazy')
}
}
},
switcher: {
inserted(el,binding){
// switch images on mousemove
el.addEventListener('mousemove', function(event) {
let figs = this.querySelectorAll('figure')
// console.log('mousemove', this, event, figs.length);
// let len = figs.length
// let w = this.clientWidth;
// let g = w / len;
// let delta = Math.floor(event.layerX / g)
let delta = Math.floor(event.layerX / (this.clientWidth / figs.length))
// console.log('delta', delta);
figs.forEach((fig, index) => {
// console.log(index);
if(index == delta){
fig.style.display = "block"
}else{
fig.style.display = "none"
}
})
})
}
}
},
mounted() {
// lazy load images on mouseover
this.$el.addEventListener('mouseover', function(event) {
let imgs = this.querySelectorAll('.images figure img.lazy')
// console.log('mouseover', this, imgs);
imgs.forEach((img) => {
// console.log('forEach img',img);
img.setAttribute('src', img.getAttribute('data-src'))
img.removeAttribute('data-src')
img.classList.remove('lazy')
})
}, {once : true})
},
methods: { methods: {
...mapActions({ ...mapActions({
flag: 'User/flag', flag: 'User/flag',

View File

@ -0,0 +1,93 @@
<template>
<article class="card minicard">
<header>
<h1>{{ item.title }}</h1>
<span class="ref">{{ item.field_reference }}</span>
</header>
<nav class="tools">
<section class="tool flags">
<span class="mdi mdi-folder-remove-outline"/>
</section>
</nav>
<section class="images" v-switcher>
<figure
v-for="(img, index) in item.images"
:key="img.url"
>
<img
class="lazy"
v-lazy="index"
:data-src="img.url"
:title="img.title"
/>
<img class="blank" :src="blanksrc">
</figure>
</section>
</article>
</template>
<script>
import { mapState, mapActions } from 'vuex'
import cardMixins from 'vuejs/components/cardMixins'
export default {
name: "MiniCard",
props: ['item'],
mixins: [cardMixins],
data() {
return {
blanksrc:`${drupalSettings.path.themePath}/assets/img/blank.gif`,
// loadingFlag: false
}
},
computed: {
// ...mapState({
// flagcolls: state => state.User.flagcolls
// })
},
methods: {
// ...mapActions({
// flag: 'User/flag',
// unFlag: 'User/unFlag'
// }),
// flagIsActive(collid) {
// // console.log(this.item.uuid);
// // console.log(this.flagcolls[collid].items_uuids);
// return this.flagcolls[collid].items_uuids.indexOf(this.item.uuid) !== -1;
// },
// flagIsLoading(collid) {
// // console.log(this.item.uuid);
// // console.log(this.flagcolls[collid].items_uuids);
// return collid === this.loadingFlag;
// },
// onFlagActionCard (e) {
// console.log("Card onFlagActionCard", e);
// if (!this.loadingFlag) {
// let collid = e.target.getAttribute('collid');
// let isActive = this.flagIsActive(collid);
// // console.log('collid', collid);
// // console.log("this.item", this.item);
// this.loadingFlag = collid;
// if (isActive) {
// this.unFlag({uuid: this.item.uuid, collid: collid})
// .then(data => {
// console.log("onFlagActionCard then", data);
// this.loadingFlag = false;
// })
// }else{
// this.flag({uuid: this.item.uuid, collid: collid})
// .then(data => {
// console.log("onFlagActionCard then", data);
// this.loadingFlag = false;
// })
// }
// }
// }
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@ -1,13 +1,16 @@
<template> <template>
<div id="Base"> <div id="Base">
<div class="loading" v-if="!items.length"> <div class="loading" v-if="!searchinfos">
<span>Loading ...</span> <span>Loading ...</span>
</div> </div>
<div class="cards-list" v-else> <div class="cards-list" v-else>
<aside class="search-info"> <aside class="search-info">
{{ searchinfos }} {{ searchinfos }}
</aside> </aside>
<ul> <div class="loading" v-if="!items.length & !noresults">
<span>Loading ...</span>
</div>
<ul v-else>
<li v-for="item in items" v-bind:key="item.uuid"> <li v-for="item in items" v-bind:key="item.uuid">
<Card :item="item"/> <Card :item="item"/>
</li> </li>
@ -42,6 +45,7 @@ export default {
items: state => state.Search.items, items: state => state.Search.items,
searchinfos: state => state.Search.infos, searchinfos: state => state.Search.infos,
count: state => state.Search.count, count: state => state.Search.count,
noresults: state => state.Search.noresults,
limit: state => state.Search.limit limit: state => state.Search.limit
}) })
}, },

View File

@ -1,11 +1,20 @@
<template> <template>
<section class="flag-collection"> <section class="flag-collection">
<h3>{{collection.name}}</h3> <header>
<h3 class="mdi mdi-folder-outline">{{collection.name}}</h3>
<span
class="mdi mdi-close"
title="close"
@click.prevent="onCloseFlagColl"
/>
</header>
<ul v-if="loadedItems"> <ul v-if="loadedItems">
<li <li
v-for="item in loadedItems" v-for="item in loadedItems"
:key="item.id" :key="item.id"
>{{item.attributes.title}}</li> >
<MiniCard :item="item"/>
</li>
</ul> </ul>
<span v-else class="loading">Loading</span> <span v-else class="loading">Loading</span>
</section> </section>
@ -13,6 +22,7 @@
<script> <script>
import { mapState, mapActions } from 'vuex' import { mapState, mapActions } from 'vuex'
import MiniCard from 'vuejs/components/Content/MiniCard'
export default { export default {
name: "FlagCollection", name: "FlagCollection",
@ -22,8 +32,8 @@ export default {
}), }),
computed: { computed: {
...mapState({ ...mapState({
flagcolls: state => state.User.flagcolls flagcolls: state => state.User.flagcolls,
// openedCollid: state => state.User.openedCollid openedCollid: state => state.User.openedCollid
}) })
}, },
// watch: { // watch: {
@ -35,11 +45,22 @@ export default {
// } // }
// }, // },
created() { created() {
if (typeof this.collection.loadedItems !== 'undefined') {
// if loadedItems are alredy loaded,
// the mutation occurs before this subscription
// so we first check if they are already available
this.loadedItems = this.collection.loadedItems
}
this.unsubscribe = this.$store.subscribe((mutation, state) => { this.unsubscribe = this.$store.subscribe((mutation, state) => {
if (mutation.type === 'User/setLoadedCollItems') { if (mutation.type === 'User/setLoadedCollItems') {
this.loadedItems = state.User.flagcolls[this.collection.id].loadedItems console.log("mutation setLoadedCollItems collid", this.openedCollid)
// mutation is triggered before the component update
// so this.collection.id is not good
this.loadedItems = state.User.flagcolls[this.openedCollid].loadedItems
} }
}); })
}, },
beforeDestroy() { beforeDestroy() {
this.unsubscribe() this.unsubscribe()
@ -49,11 +70,17 @@ export default {
// this. // this.
// } // }
// }, // },
// methods: { methods: {
// ...mapActions({ ...mapActions({
// loadFlagCollItems: 'User/loadFlagCollItems' closeFlagColl: 'User/closeFlagColl'
// }) }),
// } onCloseFlagColl(e) {
this.closeFlagColl()
}
},
components: {
MiniCard
}
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -26,7 +26,7 @@
<span <span
class="add-btn mdi" class="add-btn mdi"
:class="addFlagBtnClassObj" :class="addFlagBtnClassObj"
@click.prevent="onCreateFlagColl" @click.prevent.stop="onCreateFlagColl"
/> />
</li> </li>
</ul> </ul>
@ -92,7 +92,7 @@ export default {
}, },
onOpenFlagColl (e) { onOpenFlagColl (e) {
const flagcollid = e.target.getAttribute('flagcollid'); const flagcollid = e.target.getAttribute('flagcollid');
console.log("UserFlags onDeleteFlagColl", flagcollid); console.log("UserFlags onOpenFlagColl", flagcollid);
this.openFlagColl(flagcollid) this.openFlagColl(flagcollid)
.then(() => { .then(() => {
// console.log("onDeleteFlagColl then", data); // console.log("onDeleteFlagColl then", data);

View File

@ -0,0 +1,56 @@
// https://forum.vuejs.org/t/how-to-use-helper-functions-for-imported-modules-in-vuejs-vue-template/6266/5
export default {
directives: {
lazy: {
bind(img,binding){
// console.log('lazy bind', img, binding);
if(binding.value === 0){
img.setAttribute('src', img.getAttribute('data-src'))
img.removeAttribute('data-src')
img.classList.remove('lazy')
}
}
},
switcher: {
inserted(el,binding){
// switch images on mousemove
el.addEventListener('mousemove', function(event) {
let figs = this.querySelectorAll('figure')
// console.log('mousemove', this, event, figs.length);
// let len = figs.length
// let w = this.clientWidth;
// let g = w / len;
// let delta = Math.floor(event.layerX / g)
let delta = Math.floor(event.layerX / (this.clientWidth / figs.length))
// console.log('delta', delta);
figs.forEach((fig, index) => {
// console.log(index);
if(index == delta){
fig.style.display = "block"
}else{
fig.style.display = "none"
}
})
})
}
}
},
mounted() {
// lazy load images on mouseover
this.$el.addEventListener('mouseover', function(event) {
let imgs = this.querySelectorAll('.images figure img.lazy')
// console.log('mouseover', this, imgs);
imgs.forEach((img) => {
// console.log('forEach img',img);
img.setAttribute('src', img.getAttribute('data-src'))
img.removeAttribute('data-src')
img.classList.remove('lazy')
})
}, {once : true})
},
methods: {
// deg2rad (deg) {
// return deg * (Math.PI / 180)
// },
}
}

View File

@ -1,5 +1,11 @@
import Vue from 'vue' import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
import { createStore } from 'vuex-extensions'
import { JSONAPI } from 'vuejs/api/json-axios'
import qs from 'querystring-es3'
import Common from './modules/common' import Common from './modules/common'
import User from './modules/user' import User from './modules/user'
import Search from './modules/search' import Search from './modules/search'
@ -10,7 +16,8 @@ import Pages from './modules/pages'
// https://github.com/vuejs/vuex/tree/dev/examples/shopping-cart // https://github.com/vuejs/vuex/tree/dev/examples/shopping-cart
Vue.use(Vuex) Vue.use(Vuex)
export default new Vuex.Store({ // export default new Vuex.Store({
export default createStore(Vuex.Store, {
modules: { modules: {
Common, Common,
User, User,
@ -18,5 +25,87 @@ export default new Vuex.Store({
Blabla, Blabla,
Showrooms, Showrooms,
Pages Pages
},
// https://github.com/huybuidac/vuex-extensions
mixins: {
actions: {
loadMaterials ({ dispatch }, { uuids, imgStyle, callBack, callBackArgs }) {
const params = {
// include: 'images', // no needs to include thanks to consumers_image_styles module
// include: 'drupal_internal__nid',
'filter[uuids-groupe][group][conjunction]': 'OR'
}
for (let i = 0; i < uuids.length; i++) {
const uuid = uuids[i]
params[`filter[${uuid}][condition][path]`] = 'id'
params[`filter[${uuid}][condition][value]`] = uuid
params[`filter[${uuid}][condition][operator]`] = '='
params[`filter[${uuid}][condition][memberOf]`] = 'uuids-groupe'
}
// console.log('search JSONAPI params', params);
const q = qs.stringify(params)
return JSONAPI.get('node/materiau?' + q)
.then(({ data }) => {
console.log('mixin getMaterials data', data)
dispatch('parseMaterials', { data: data.data, uuids: uuids, imgStyle: imgStyle, callBack: callBack, callBackArgs: callBackArgs })
// commit('setItems', data.items)
})
.catch((error) => {
console.warn('Issue with getItems', error)
Promise.reject(error)
})
},
parseMaterials ({ dispatch }, { data, uuids, imgStyle, callBack, callBackArgs }) {
// data comes from jsonapi query
// uuids comes from original query (solr, FlagCollection, etc)
// so we loop from uuids to conserve the original order
console.log('mixin parseMaterials', data, uuids, callBack, callBackArgs)
const items = []
// for (var i = 0; i < data.length; i++) {
for (let i = 0; i < uuids.length; i++) {
const uuid = uuids[i]
// https://stackoverflow.com/questions/11258077/how-to-find-index-of-an-object-by-key-and-value-in-an-javascript-array
const item_index = data.findIndex(p => p.id === uuid)
// console.log('item_index', item_index);
if (item_index === -1) continue
const item_src = data[item_index]
const attrs = item_src.attributes
const relations = item_src.relationships
// get field values
const item = {
uuid: uuid,
title: attrs.title,
field_short_description: attrs.field_short_description,
body: attrs.body,
field_reference: attrs.field_reference
}
// get images included values
const img_src = relations.images.data
// console.log('img_src', img_src);
// this is a temporary deactivation of images
// img_src = [];
item.images = []
for (let j = 0; j < img_src.length; j++) {
if (img_src[j].meta.imageDerivatives) {
item.images.push({
title: img_src[j].meta.title,
// meta.imageDerivatives.style.href link is provided by drupal consumers_image_styles module
// BUG: missing all image derivative but first
url: img_src[j].meta.imageDerivatives.links.[imgStyle].href
})
} else {
console.warn('missing image derivative ' + j + '/' + img_src.length + ' for ' + attrs.title)
}
}
items.push(item)
}
console.log('items', items)
dispatch(callBack, { items: items, callBackArgs: callBackArgs })
}
}
} }
}) })

View File

@ -16,6 +16,7 @@ export default {
limit: 15, limit: 15,
infos: null, infos: null,
count: 0, count: 0,
noresults: false,
// infinteState will come from vue-infinite-loading plugin // infinteState will come from vue-infinite-loading plugin
// implemented in vuejs/components/Content/Base.vue // implemented in vuejs/components/Content/Base.vue
infiniteLoadingState: null infiniteLoadingState: null
@ -32,7 +33,7 @@ export default {
resetUuids (state) { resetUuids (state) {
state.uuids = [] state.uuids = []
}, },
setItems (state, items) { setMaterials (state, items) {
state.items = state.items.concat(items) state.items = state.items.concat(items)
}, },
resetItems (state) { resetItems (state) {
@ -50,6 +51,15 @@ export default {
setCount (state, count) { setCount (state, count) {
state.count = count state.count = count
}, },
resetCount (state, count) {
state.count = false
},
setNoresults (state) {
state.noresults = true
},
resetNoresults (state) {
state.noresults = false
},
resetOffset (state) { resetOffset (state) {
state.offset = 0 state.offset = 0
}, },
@ -67,6 +77,8 @@ export default {
console.log('Search newSearch') console.log('Search newSearch')
commit('resetUuids') commit('resetUuids')
commit('resetItems') commit('resetItems')
commit('resetCount')
commit('resetNoresults')
commit('resetOffset') commit('resetOffset')
this.commit('Common/setPagetitle', state.keys) this.commit('Common/setPagetitle', state.keys)
dispatch('getResults') dispatch('getResults')
@ -92,89 +104,27 @@ export default {
// commit('setItems', data.items) // commit('setItems', data.items)
commit('setInfos', data.infos) commit('setInfos', data.infos)
commit('setCount', data.count) commit('setCount', data.count)
commit('setUuids', data.uuids) if (data.count) {
dispatch('getItems', data.uuids) commit('setUuids', data.uuids)
// loadMaterials is on mixins
// https://github.com/huybuidac/vuex-extensions
dispatch('loadMaterials', {
uuids: data.uuids,
imgStyle: 'card_medium',
callBack: 'loadMaterialsCallBack'
})
}else{
commit('setNoresults')
}
}) })
.catch((error) => { .catch((error) => {
console.warn('Issue with getResults', error) console.warn('Issue with getResults', error)
Promise.reject(error) Promise.reject(error)
}) })
}, },
getItems ({ dispatch, commit, state }, uuids) { loadMaterialsCallBack ({ commit, state }, { items, callBackArgs }) {
const params = { console.log('search loadMaterialsCallBack', items)
// include: 'images', // no needs to include thanks to consumers_image_styles module commit('setMaterials', items)
// include: 'drupal_internal__nid',
'filter[uuids-groupe][group][conjunction]': 'OR'
}
for (let i = 0; i < uuids.length; i++) {
const uuid = uuids[i]
params[`filter[${uuid}][condition][path]`] = 'id'
params[`filter[${uuid}][condition][value]`] = uuid
params[`filter[${uuid}][condition][operator]`] = '='
params[`filter[${uuid}][condition][memberOf]`] = 'uuids-groupe'
}
// console.log('search JSONAPI params', params);
const q = qs.stringify(params)
return JSONAPI.get('node/materiau?' + q)
.then(({ data }) => {
console.log('search getItems data', data)
dispatch('parseItems', { data: data.data, uuids: uuids })
// commit('setItems', data.items)
})
.catch((error) => {
console.warn('Issue with getItems', error)
Promise.reject(error)
})
},
parseItems ({ dispatch, commit, state }, { data, uuids }) {
// data comes from jsonapi query
// uuids comes from solr search query (we loop from uuids to conserve the search results order)
console.log('search parseItems data, uuids', data, uuids)
const items = []
// for (var i = 0; i < data.length; i++) {
for (let i = 0; i < uuids.length; i++) {
const uuid = uuids[i]
// https://stackoverflow.com/questions/11258077/how-to-find-index-of-an-object-by-key-and-value-in-an-javascript-array
const item_index = data.findIndex(p => p.id == uuid)
// console.log('item_index', item_index);
if (item_index == -1) continue
const item_src = data[item_index]
const attrs = item_src.attributes
const relations = item_src.relationships
// get field values
const item = {
uuid: uuid,
title: attrs.title,
field_short_description: attrs.field_short_description,
body: attrs.body,
field_reference: attrs.field_reference
}
// get images included values
const img_src = relations.images.data
// console.log('img_src', img_src);
// this is a temporary deactivation of images
// img_src = [];
item.images = []
for (let j = 0; j < img_src.length; j++) {
if (img_src[j].meta.imageDerivatives) {
item.images.push({
title: img_src[j].meta.title,
// meta.imageDerivatives.style.href link is provided by drupal consumers_image_styles module
// BUG: missing all image derivative but first
url: img_src[j].meta.imageDerivatives.links.card_medium.href
})
} else {
console.warn('missing image derivative ' + j + '/' + img_src.length + ' for ' + attrs.title)
}
}
items.push(item)
}
console.log('items', items)
commit('setItems', items)
if (state.infiniteLoadingState) { if (state.infiniteLoadingState) {
if (state.offset + state.limit > state.count) { if (state.offset + state.limit > state.count) {
console.log('Search infinite completed') console.log('Search infinite completed')

View File

@ -1,5 +1,5 @@
import { REST } from 'vuejs/api/rest-axios' import { REST } from 'vuejs/api/rest-axios'
import { JSONAPI } from 'vuejs/api/json-axios' // import { JSONAPI } from 'vuejs/api/json-axios'
import { MA } from 'vuejs/api/ma-axios' import { MA } from 'vuejs/api/ma-axios'
import qs from 'querystring-es3' import qs from 'querystring-es3'
@ -89,9 +89,15 @@ export default {
openFlagColl (state, collid) { openFlagColl (state, collid) {
state.openedCollid = collid state.openedCollid = collid
}, },
closeFlagColl (state) {
state.openedCollid = null
},
setLoadedCollItems (state, data) { setLoadedCollItems (state, data) {
console.log('setLoadedCollItems', data) console.log('setLoadedCollItems', data)
state.flagcolls[data.collid].loadedItems = data.items // if no data, we are just calling the mutation to trigger the component update
if (data) {
state.flagcolls[data.collid].loadedItems = data.items
}
} }
}, },
@ -270,38 +276,31 @@ export default {
}) })
}) })
}, },
openFlagColl ({ commit, dispatch }, collid) { openFlagColl ({ commit, dispatch, state }, collid) {
console.log('user openFlagColl', collid) console.log('user openFlagColl', collid)
commit('openFlagColl', collid) commit('openFlagColl', collid)
dispatch('loadFlagCollItems', collid) if (typeof state.flagcolls[collid].loadedItems === 'undefined') {
// if no loadedItems, load them
// loadMaterials is on mixins
// https://github.com/huybuidac/vuex-extensions
dispatch('loadMaterials', {
uuids: state.flagcolls[collid].items_uuids,
imgStyle: 'card_medium_half',
callBack: 'loadMaterialsCallBack',
callBackArgs: { collid: collid }
})
} else {
// call the mutation without data to only trigger the FlagCollection component update
commit('setLoadedCollItems')
}
}, },
loadFlagCollItems ({ commit, state }, collid) { loadMaterialsCallBack ({ commit }, { items, callBackArgs }) {
console.log('loadFlagCollItems', state.flagcolls[collid].items_uuids) console.log('user loadMaterialsCallBack', items)
const params = { commit('setLoadedCollItems', { collid: callBackArgs.collid, items: items })
'filter[uuids-groupe][group][conjunction]': 'OR' },
} closeFlagColl ({ commit, dispatch }) {
const uuids = state.flagcolls[collid].items_uuids console.log('user closeFlagColl')
// console.log('uuids', uuids) commit('closeFlagColl')
for (let i = 0; i < uuids.length; i++) {
let uuid = uuids[i]
// console.log('uuid', uuid)
params[`filter[${uuid}][condition][path]`] = 'id'
params[`filter[${uuid}][condition][value]`] = uuid
params[`filter[${uuid}][condition][operator]`] = '='
params[`filter[${uuid}][condition][memberOf]`] = 'uuids-groupe'
}
console.log('search JSONAPI params', params);
const q = qs.stringify(params)
return JSONAPI.get('node/materiau?' + q)
.then(({ data }) => {
console.log('user loadFlagCollItems data', data)
// dispatch('parseItems', { data: data.data, uuids: uuids })
commit('setLoadedCollItems', {collid: collid, items: data.data})
})
.catch((error) => {
console.warn('Issue with loadFlagCollItems', error)
Promise.reject(error)
})
}, },
userLogout ({ commit, state }) { userLogout ({ commit, state }) {
const credentials = qs.stringify({ const credentials = qs.stringify({