Merge pull request #1794 from umap-project/integrate-facets
feat: integrate facets into browser filters
This commit is contained in:
commit
0ce1971b4e
24 changed files with 457 additions and 227 deletions
|
@ -159,6 +159,51 @@ input[type="range"] {
|
|||
input[type="checkbox"] {
|
||||
margin: 0 5px;
|
||||
vertical-align: middle;
|
||||
appearance: none;
|
||||
}
|
||||
input[type="checkbox"]:after {
|
||||
display: inline-block;
|
||||
content: ' ';
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border: 1px solid var(--color-lightGray);
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
font-size: 1.3rem;
|
||||
line-height: 1rem;
|
||||
}
|
||||
input[type=checkbox]:checked:after {
|
||||
background-color: var(--color-lightCyan);
|
||||
content: '✓';
|
||||
}
|
||||
label input[type="radio"] {
|
||||
appearance: none;
|
||||
margin-right: 10px;
|
||||
}
|
||||
input[type="radio"]:after {
|
||||
display: inline-block;
|
||||
content: ' ';
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid var(--color-lightGray);
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
font-size: 1.3rem;
|
||||
line-height: 1rem;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
label input[type="radio"]:checked:after {
|
||||
background-color: var(--color-lightCyan);
|
||||
content: '•';
|
||||
font-size: 3rem;
|
||||
line-height: 1.1rem;
|
||||
color: var(--color-darkGray);
|
||||
}
|
||||
|
||||
input[data-modified=true] {
|
||||
background-color: var(--color-lightCyan);
|
||||
border: 1px solid var(--color-darkGray);
|
||||
}
|
||||
textarea {
|
||||
height: inherit;
|
||||
|
@ -263,9 +308,6 @@ input[type="checkbox"] + label {
|
|||
display: inline;
|
||||
padding: 0 14px;
|
||||
}
|
||||
label input[type="radio"] {
|
||||
margin-right: 10px;
|
||||
}
|
||||
select + .error,
|
||||
input + .error {
|
||||
display: block;
|
||||
|
@ -290,67 +332,59 @@ input:invalid {
|
|||
border-color: #1b1f20;
|
||||
color: #efefef;
|
||||
}
|
||||
.fieldset {
|
||||
details {
|
||||
margin-bottom: 5px;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.dark .fieldset {
|
||||
.dark details {
|
||||
border: 1px solid #222;
|
||||
}
|
||||
.fieldset .fields {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: visibility 0s, opacity 0.5s linear;
|
||||
height: 0;
|
||||
details fieldset {
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--color-lightGray);
|
||||
margin: 0;
|
||||
padding-top: 10px;
|
||||
}
|
||||
.fieldset.toggle.on .fields {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
height: initial;
|
||||
padding: 10px;
|
||||
}
|
||||
.fieldset.toggle .legend {
|
||||
text-align: left;
|
||||
display: block;
|
||||
details summary {
|
||||
cursor: pointer;
|
||||
background-color: var(--color-lightGray);
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
margin: 0;
|
||||
font-family: fira_sans;
|
||||
font-weight: normal;
|
||||
font-size: 1.2em;
|
||||
padding: 0 5px;
|
||||
}
|
||||
.dark .fieldset.toggle .legend {
|
||||
.dark details summary {
|
||||
background-color: #232729;
|
||||
color: #fff;
|
||||
}
|
||||
.fieldset.toggle .legend:before {
|
||||
background-repeat: no-repeat;
|
||||
text-indent: 24px;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
line-height: 24px;
|
||||
display: inline-block;
|
||||
background-image: url('./img/16.svg');
|
||||
vertical-align: bottom;
|
||||
content: " ";
|
||||
background-position: -144px -76px;
|
||||
}
|
||||
.dark .fieldset.toggle .legend:before {
|
||||
background-image: url('./img/16-white.svg');
|
||||
}
|
||||
.fieldset.toggle.on .legend:before {
|
||||
background-position: -144px -51px;
|
||||
.dark details fieldset {
|
||||
border: 1px solid var(--color-darkGray);
|
||||
}
|
||||
fieldset legend {
|
||||
font-size: 1.1rem;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
[data-badge] {
|
||||
position: relative;
|
||||
}
|
||||
[data-badge]:after {
|
||||
position: absolute;
|
||||
right: -6px;
|
||||
top: -6px;
|
||||
min-width: 8px;
|
||||
min-height: 8px;
|
||||
line-height: 8px;
|
||||
padding: 2px;
|
||||
font-weight: bold;
|
||||
background-color: var(--color-accent);
|
||||
color: var(--color-darkBlue);
|
||||
text-align: center;
|
||||
font-size: .75rem;
|
||||
border-radius: 50%;
|
||||
content: attr(data-badge);
|
||||
}
|
||||
|
||||
/* Switch */
|
||||
input.switch:empty {
|
||||
display: none;
|
||||
|
@ -408,11 +442,16 @@ input.switch:checked:empty ~ label:after {
|
|||
}
|
||||
.dark input.switch:checked ~ label:before,
|
||||
input.switch:checked ~ label:before {
|
||||
background-color: #215d9c;
|
||||
background-color: var(--color-lightCyan);
|
||||
border: 1px solid var(--color-lightGray);
|
||||
color: var(--color-darkGray);
|
||||
content: "ON";
|
||||
text-indent: 0.7em;
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
.dark input.switch:checked ~ label:before {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
input.switch:checked ~ label:after {
|
||||
margin-left: 3em;
|
||||
|
@ -458,9 +497,9 @@ input.switch:checked ~ label:after {
|
|||
background-color: #2c3233;
|
||||
}
|
||||
.umap-multiplechoice input[type='radio']:checked + label {
|
||||
background-color: #215d9c;
|
||||
background-color: var(--color-lightCyan);
|
||||
box-shadow: inset 0 0 6px 0px #2c3233;
|
||||
color: #ededed;
|
||||
color: var(--color-darkGray);
|
||||
}
|
||||
.inheritable .header,
|
||||
.inheritable {
|
||||
|
|
|
@ -55,6 +55,9 @@
|
|||
.off .icon-edit {
|
||||
background-position: -51px -73px;
|
||||
}
|
||||
.icon-filters {
|
||||
background-position: -4px -24px;
|
||||
}
|
||||
.icon-key {
|
||||
background-position: -144px -121px;
|
||||
}
|
||||
|
@ -76,6 +79,9 @@
|
|||
.icon-resize {
|
||||
background-position: -74px -144px;
|
||||
}
|
||||
.icon-restore {
|
||||
background-position: -121px -74px;
|
||||
}
|
||||
.expanded .icon-resize {
|
||||
background-position: -50px -144px;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
bottom: var(--panel-bottom);
|
||||
overflow-x: auto;
|
||||
z-index: 1010;
|
||||
background-color: #fff;
|
||||
background-color: var(--background-color);
|
||||
opacity: 0.98;
|
||||
cursor: initial;
|
||||
border-radius: 5px;
|
||||
|
@ -14,7 +14,6 @@
|
|||
}
|
||||
.panel.dark {
|
||||
border: 1px solid #222;
|
||||
background-color: var(--color-darkGray);
|
||||
color: #efefef;
|
||||
}
|
||||
.panel.full {
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
<path id="rect3787" d="m2 1047.9 13-10 1 1-13 10z"/>
|
||||
</g>
|
||||
<path id="table-disabled" d="m78 819.36v2h12v-2zm0 3v1h4v-1zm5 0v1h7v-1zm-5 2v1h4v-1zm5 0v1h7v-1zm-5 2v1h4v-1zm5 0v1h7v-1zm-5 2v1h4v-1zm5 0v1h7v-1z" fill="#b3b3b3"/>
|
||||
<path id="add-disabled" d="m35 843.36v4h-4v2h4v4h2v-4h4v-2h-4v-4z" fill="#f2f2f2"/>
|
||||
<path id="zoom" d="m13.518 866.36c-2.4668 0-4.4825 2.0158-4.4825 4.4826 0 0.8297 0.23375 1.5964 0.63035 2.2646l-3.6654 3.6653 1.5875 1.5876 3.6654-3.6654c0.66814 0.3966 1.4348 0.6303 2.2646 0.6303 2.4668 0 4.4825-2.0157 4.4825-4.4824 0-2.4668-2.0157-4.4826-4.4825-4.4826zm0 1.4943c1.6593 0 2.9883 1.329 2.9883 2.9883 0 1.6592-1.3291 2.9883-2.9883 2.9883s-2.9883-1.3291-2.9883-2.9883c0-1.6593 1.3291-2.9883 2.9883-2.9883zm0 1.4941c-0.81635 0-1.4942 0.6779-1.4942 1.4942s0.67781 1.4942 1.4942 1.4942 1.4942-0.6779 1.4942-1.4942-0.67781-1.4942-1.4942-1.4942z" color="#000000" fill="#4d4d4d" style="text-decoration-line:none;text-indent:0;text-transform:none"/>
|
||||
<path id="zoom-disabled" d="m37.518 866.36c-2.4668 0-4.4825 2.0157-4.4825 4.4825 0 0.8298 0.23375 1.5964 0.63035 2.2645l-3.6654 3.6655 1.5875 1.5875 3.6654-3.6654c0.66814 0.39662 1.4348 0.63042 2.2646 0.63042 2.4668 0 4.4825-2.0157 4.4825-4.4825s-2.0157-4.4825-4.4825-4.4825zm0 1.4942c1.6593 0 2.9883 1.329 2.9883 2.9883s-1.3291 2.9883-2.9883 2.9883-2.9883-1.329-2.9883-2.9883 1.3291-2.9883 2.9883-2.9883zm0 1.4941c-0.81636 0-1.4942 0.6779-1.4942 1.4942s0.67781 1.4942 1.4942 1.4942 1.4942-0.6779 1.4942-1.4942-0.67781-1.4942-1.4942-1.4942z" color="#000000" fill="#b3b3b3" style="text-decoration-line:none;text-indent:0;text-transform:none"/>
|
||||
<path id="path5321" d="m36 889.36c-3.866 0-7 3.134-7 7 0 3.866 3.134 7 7 7s7-3.134 7-7c0-3.866-3.134-7-7-7zm-0.15625 2.9687a1.0001 1.0001 0 0 1 0.09375 0 1.0001 1.0001 0 0 1 0.65625 1.8125l-1.625 1.2188h5.0312a1.0001 1.0001 0 1 1 0 2h-5l1.5938 1.1875a1.0001 1.0001 0 1 1-1.1875 1.5937l-3.7188-2.7812a1.0044 1.0044 0 0 1-0.15625-1.9063l3.875-2.9062a1.0001 1.0001 0 0 1 0.4375-0.2188z" fill="#f2f2f2"/>
|
||||
|
@ -36,7 +35,8 @@
|
|||
<path id="path5340" d="m12 913.36c-3.866 0-7 3.134-7 7 0 3.8661 3.134 7.0001 7 7.0001s7-3.134 7-7.0001c0-3.866-3.134-7-7-7zm-0.15625 1.7187a1.2501 1.2501 0 0 1 0.125 0 1.2501 1.2501 0 0 1 1.2812 1.2813v2.75h2.75a1.2501 1.2501 0 1 1 0 2.5h-2.75v2.7501a1.2501 1.2501 0 1 1-2.5 0v-2.7501h-2.75a1.2516 1.2516 0 0 1-0.125-2.5 1.2501 1.2501 0 0 1 0.125 0h2.75v-2.75a1.2501 1.2501 0 0 1 1.0938-1.2813z" fill="#f2f2f2"/>
|
||||
<path id="table" d="m54 819.36v2h12v-2zm0 3v1h4v-1zm5 0v1h7v-1zm-5 2v1h4v-1zm5 0v1h7v-1zm-5 2v1h4v-1zm5 0v1h7v-1zm-5 2v1h4v-1zm5 0v1h7v-1z" fill="#464646"/>
|
||||
<path id="close-9" d="m32.353 820.01-0.70703 0.70704 3.6465 3.6465-3.6465 3.6465 0.70703 0.70704 3.6465-3.6465 3.6465 3.6465 0.70703-0.70704-3.6465-3.6465 3.6465-3.6465-0.70703-0.70704-3.6465 3.6465z" color="#000000" fill="#4d4d4d" fill-rule="evenodd"/>
|
||||
<path id="add" d="m11.192 853.36 2e-6 -4.1999-4.1923 1e-5 -3e-6 -1.6267h4.1923v-4.1733l1.6088 7e-3 0.0067 4.1666h4.1923l-3.9e-5 1.6266-4.1922 4e-5 -1.5e-5 4.1999h-1.6155" fill="#4d4d4d"/>
|
||||
<path id="add" d="m35.192 853.36 2e-6 -4.1999-4.1923 1e-5 -3e-6 -1.6267h4.1923v-4.1733l1.6088 7e-3 0.0067 4.1666h4.1923l-3.9e-5 1.6266-4.1922 4e-5 -1.5e-5 4.1999h-1.6155" fill="#4d4d4d"/>
|
||||
<path id="path1-3" d="m16.557 844.08c0.12973-0.17297 0.25946-0.38919 0.3027-0.64865h2.6811c0.25946 0 0.43243-0.17297 0.43243-0.43243s-0.17297-0.43243-0.43243-0.43243h-2.6811c-0.08649-0.38919-0.34595-0.77838-0.69189-1.0378-0.82162-0.60541-1.9459-0.38919-2.5081 0.38919-0.12973 0.17297-0.21622 0.38919-0.3027 0.64865h-8.9514c-0.25946 0-0.43243 0.17297-0.43243 0.43243s0.17297 0.43243 0.43243 0.43243h8.9514c0.08649 0.38919 0.34595 0.77838 0.69189 1.0378 0.77838 0.6054 1.9459 0.43243 2.5081-0.38919zm-1.9892-0.3027c-0.21622-0.12973-0.34595-0.34595-0.38919-0.60541-0.04324-0.25946 0-0.47567 0.17297-0.69189 0.3027-0.43243 0.90811-0.51892 1.2973-0.21622 0.21622 0.12973 0.34595 0.34595 0.38919 0.60541v0.12973c0 0.21621-0.04324 0.38919-0.17297 0.56216-0.3027 0.43243-0.90811 0.51892-1.2973 0.21622zm-4.4108 5.2324c0.12973-0.17297 0.25946-0.38919 0.3027-0.64865h9.0811c0.25946 0 0.43243-0.17297 0.43243-0.43243s-0.17297-0.43243-0.43243-0.43243h-9.0811c-0.08649-0.38919-0.34594-0.77838-0.69189-1.0378-0.82162-0.60541-1.9459-0.38919-2.5081 0.38919-0.12973 0.17297-0.21622 0.38919-0.3027 0.64865h-2.5514c-0.25946 0-0.43243 0.17297-0.43243 0.43243s0.17297 0.43243 0.43243 0.43243h2.5514c0.086486 0.38919 0.34595 0.77838 0.69189 1.0378 0.77838 0.56216 1.9027 0.38919 2.5081-0.38919zm-1.9892-0.34595c-0.21622-0.12973-0.34595-0.34594-0.38919-0.6054-0.043243-0.25946 0-0.47568 0.17297-0.69189 0.3027-0.43244 0.90811-0.51892 1.2973-0.21622 0.21622 0.12973 0.34595 0.34595 0.38919 0.60541v0.12973c0 0.21621-0.043243 0.38918-0.17297 0.56216-0.3027 0.43243-0.90811 0.51892-1.2973 0.21621zm6.7027 5.2324c0.12973-0.17298 0.25946-0.38919 0.3027-0.64865h4.3676c0.25946 0 0.43243-0.17298 0.43243-0.43244 0-0.25945-0.17297-0.43243-0.43243-0.43243h-4.3676c-0.08649-0.38919-0.34595-0.77838-0.69189-1.0378-0.38919-0.3027-0.86486-0.38918-1.3405-0.34594-0.47568 0.0865-0.90811 0.34594-1.1676 0.73513-0.12973 0.21622-0.21622 0.38919-0.3027 0.64865h-7.2649c-0.25946 0-0.43243 0.17298-0.43243 0.43243 0 0.25946 0.17297 0.43244 0.43243 0.43244h7.3081c0.08649 0.38919 0.34594 0.77838 0.69189 1.0378 0.77838 0.56216 1.9027 0.38918 2.4649-0.38919zm-1.9892-0.30271c-0.21622-0.17297-0.34595-0.38919-0.38919-0.64865v-0.0865-0.0865c0-0.17297 0.08649-0.3027 0.17297-0.43243 0.12973-0.21622 0.34595-0.34595 0.6054-0.38919 0.25946-0.0432 0.47568 0.0432 0.69189 0.17297 0.21622 0.12973 0.34595 0.34595 0.38919 0.60541v0.12973c0 0.21621-0.04324 0.38919-0.17297 0.56216-0.3027 0.38919-0.86486 0.47568-1.2973 0.17297z" fill="#4d4d4d"/>
|
||||
<path id="edit" d="m63.714 866.36-1.1428 1.1429 2.2857 2.2857 1.1428-1.1429zm-1.7143 1.7143-6.2857 6.2857 2.2857 2.2857 6.2857-6.2857zm-6.2857 6.2857-1.7143 4 4-1.7143z" fill="#4d4d4d"/>
|
||||
<text id="text4457-6" x="39.647079" y="918.79706" fill="#000000" font-family="sans-serif" letter-spacing="0px" word-spacing="0px" style="line-height:0%" xml:space="preserve"><tspan id="tspan4459-6" x="39.647079" y="918.79706" font-family="sans-serif" font-size="30.476px" style="line-height:1.25"> </tspan></text>
|
||||
<g id="text4356-2" transform="translate(44,-124)" fill="#fff" stroke="#000" stroke-width=".1">
|
||||
|
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 25 KiB |
|
@ -10,7 +10,7 @@
|
|||
<path d="M 16.0401,2.3158 H 2.005 v 14.0351 h 14.0351 z" fill="#ffffff" id="path2351" />
|
||||
</mask>
|
||||
</defs>
|
||||
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="21.380532" inkscape:cx="34.119824" inkscape:cy="18.264279" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" inkscape:window-width="1920" inkscape:window-height="1011" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" showguides="true" inkscape:guide-bbox="true" inkscape:snap-grids="true" inkscape:snap-to-guides="true" inkscape:showpageshadow="2" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1">
|
||||
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="8.783299" inkscape:cx="35.578887" inkscape:cy="40.702246" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" inkscape:window-width="1920" inkscape:window-height="1011" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" showguides="true" inkscape:guide-bbox="true" inkscape:snap-grids="true" inkscape:snap-to-guides="true" inkscape:showpageshadow="2" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1">
|
||||
<inkscape:grid type="xygrid" id="grid3004" empspacing="4" visible="true" enabled="true" snapvisiblegridlinesonly="true" originx="0" originy="0" spacingy="1" spacingx="1" units="px" />
|
||||
<sodipodi:guide orientation="-1,0" position="24,168" id="guide3084" inkscape:locked="false" inkscape:label="" inkscape:color="rgb(0,134,229)" />
|
||||
<sodipodi:guide orientation="0,1" position="0,120" id="guide3086" inkscape:locked="false" inkscape:label="" inkscape:color="rgb(0,134,229)" />
|
||||
|
@ -46,7 +46,6 @@
|
|||
<path sodipodi:nodetypes="ccccc" inkscape:connector-curvature="0" id="rect3787" d="m 2,1047.8622 13,-10 1,1 -13,10 z" style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none" />
|
||||
</g>
|
||||
<path style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 78,819.36214 v 2 h 12 v -2 z m 0,3 v 1 h 4 v -1 z m 5,0 v 1 h 7 v -1 z m -5,2 v 1 h 4 v -1 z m 5,0 v 1 h 7 v -1 z m -5,2 v 1 h 4 v -1 z m 5,0 v 1 h 7 v -1 z m -5,2 v 1 h 4 v -1 z m 5,0 v 1 h 7 v -1 z" id="table-disabled" inkscape:connector-curvature="0" inkscape:label="" inkscape:export-filename="/home/ybon/Code/js/leaflet-storage/src/img/browse-data.png" inkscape:export-xdpi="89.996864" inkscape:export-ydpi="89.996864" />
|
||||
<path style="fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 35,843.36218 v 4 h -4 v 2 h 4 v 4 h 2 v -4 h 4 v -2 h -4 v -4 z" id="add-disabled" inkscape:export-filename="/home/ybon/Code/js/leaflet-storage/src/img/add-layer-grey-18.png" inkscape:export-xdpi="89.996864" inkscape:export-ydpi="89.996864" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccccccccccc" />
|
||||
<path style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#4d4d4d;fill-opacity:1;stroke:none;stroke-width:3;marker:none;enable-background:accumulate" d="m 13.51751,866.36211 c -2.466762,0 -4.48249,2.0158 -4.48249,4.4826 0,0.8297 0.233748,1.5964 0.63035,2.26462 L 6,876.77465 l 1.587549,1.5876 3.66537,-3.66542 c 0.668139,0.3966 1.434831,0.6303 2.264591,0.6303 2.466762,0 4.48249,-2.0157 4.48249,-4.48242 0,-2.4668 -2.015728,-4.4826 -4.48249,-4.4826 z m 0,1.4943 c 1.659256,0 2.988326,1.329 2.988326,2.9883 0,1.6592 -1.32907,2.98832 -2.988326,2.98832 -1.659256,0 -2.988326,-1.32912 -2.988326,-2.98832 0,-1.6593 1.32907,-2.9883 2.988326,-2.9883 z m 0,1.4941 c -0.816354,0 -1.494163,0.6779 -1.494163,1.4942 0,0.8163 0.677809,1.4942 1.494163,1.4942 0.816354,0 1.494163,-0.6779 1.494163,-1.4942 0,-0.8163 -0.677809,-1.4942 -1.494163,-1.4942 z" id="zoom" inkscape:export-filename="/home/ybon/Code/js/leaflet-storage/src/img/zoom_to.png" inkscape:export-xdpi="89.996864" inkscape:export-ydpi="89.996864" inkscape:connector-curvature="0" />
|
||||
<path id="zoom-disabled" d="m 37.51751,866.36216 c -2.466762,0 -4.482491,2.0157 -4.482491,4.4825 0,0.8298 0.233749,1.5964 0.630351,2.2645 L 30,876.7747 l 1.587549,1.5875 3.665369,-3.66544 c 0.668139,0.39662 1.434831,0.63042 2.264592,0.63042 2.466762,0 4.48249,-2.01572 4.48249,-4.48252 0,-2.4668 -2.015728,-4.4825 -4.48249,-4.4825 z m 0,1.4942 c 1.659256,0 2.988327,1.329 2.988327,2.9883 0,1.6593 -1.329071,2.9883 -2.988327,2.9883 -1.659256,0 -2.988327,-1.329 -2.988327,-2.9883 0,-1.6593 1.329071,-2.9883 2.988327,-2.9883 z m 0,1.4941 c -0.816355,0 -1.494164,0.6779 -1.494164,1.4942 0,0.8163 0.677809,1.4942 1.494164,1.4942 0.816355,0 1.494163,-0.6779 1.494163,-1.4942 0,-0.8163 -0.677808,-1.4942 -1.494163,-1.4942 z" style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#b3b3b3;fill-opacity:1;stroke:none;stroke-width:3;marker:none;enable-background:accumulate" inkscape:connector-curvature="0" inkscape:export-filename="/home/ybon/Code/js/leaflet-storage/src/img/zoom_to-off.png" inkscape:export-xdpi="89.996864" inkscape:export-ydpi="89.996864" />
|
||||
<path inkscape:connector-curvature="0" style="fill:#f2f2f2;fill-opacity:1;stroke:none" d="m 36,889.36215 c -3.865993,0 -7,3.134 -7,7 0,3.86602 3.134007,7.00005 7,7.00005 3.865993,0 7,-3.13404 7,-7.00005 0,-3.866 -3.134007,-7 -7,-7 z m -0.15625,2.9687 a 1.0001,1.0001 0 0 1 0.09375,0 1.0001,1.0001 0 0 1 0.65625,1.8125 l -1.625,1.2188 H 40 a 1.0001,1.0001 0 1 1 0,2 h -5 l 1.59375,1.1875 a 1.0001,1.0001 0 1 1 -1.1875,1.59372 l -3.71875,-2.78122 a 1.0043849,1.0043849 0 0 1 -0.15625,-1.9063 l 3.875,-2.9062 a 1.0001,1.0001 0 0 1 0.4375,-0.2188 z" id="path5321" inkscape:export-filename="/home/ybon/Code/js/leaflet-storage/src/img/arrow-left-16.png" inkscape:export-xdpi="89.996864" inkscape:export-ydpi="89.996864" />
|
||||
|
@ -55,7 +54,8 @@
|
|||
<path style="fill:#464646;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 54,819.36218 v 2 h 12 v -2 z m 0,3 v 1 h 4 v -1 z m 5,0 v 1 h 7 v -1 z m -5,2 v 1 h 4 v -1 z m 5,0 v 1 h 7 v -1 z m -5,2 v 1 h 4 v -1 z m 5,0 v 1 h 7 v -1 z m -5,2 v 1 h 4 v -1 z m 5,0 v 1 h 7 v -1 z" id="table" inkscape:connector-curvature="0" inkscape:label="" inkscape:export-filename="/home/ybon/Code/js/leaflet-storage/src/img/browse-data.png" inkscape:export-xdpi="89.996864" inkscape:export-ydpi="89.996864" />
|
||||
<g transform="translate(32,-54.000118)" style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#4d4d4d;fill-opacity:1;stroke:none" id="text3784-6" />
|
||||
<path id="close-9" style="color:#000000;fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.188976;stroke-dasharray:none;stroke-opacity:1" d="m 32.353032,820.00818 -0.707032,0.70704 3.646485,3.64648 -3.646485,3.64648 0.707032,0.70704 3.646484,-3.64649 3.646484,3.64649 0.707032,-0.70704 -3.646485,-3.64648 3.646485,-3.64648 -0.707032,-0.70704 -3.646484,3.64649 z" />
|
||||
<path inkscape:connector-curvature="0" d="m 11.192241,853.36196 2e-6,-4.19993 -4.192255,1e-5 -3e-6,-1.62667 h 4.192263 v -4.17331 l 1.608812,0.007 0.0067,4.16664 h 4.192255 l -3.9e-5,1.62662 -4.19222,4e-5 -1.5e-5,4.19994 h -1.615475" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:20px;line-height:125%;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;fill:#4d4d4d;fill-opacity:1;stroke:none" id="add" />
|
||||
<path inkscape:connector-curvature="0" d="m 35.192241,853.36196 2e-6,-4.19993 -4.192255,1e-5 -3e-6,-1.62667 h 4.192263 v -4.17331 l 1.608812,0.007 0.0067,4.16664 h 4.192255 l -3.9e-5,1.62662 -4.19222,4e-5 -1.5e-5,4.19994 h -1.615475" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:20px;line-height:125%;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;fill:#4d4d4d;fill-opacity:1;stroke:none" id="add" />
|
||||
<path d="m 16.556757,844.0811 c 0.129729,-0.17297 0.259459,-0.38919 0.302702,-0.64865 h 2.681081 c 0.25946,0 0.432433,-0.17297 0.432433,-0.43243 0,-0.25946 -0.172973,-0.43243 -0.432433,-0.43243 h -2.681081 c -0.08649,-0.38919 -0.345946,-0.77838 -0.691891,-1.03784 -0.821622,-0.60541 -1.945946,-0.38919 -2.508109,0.38919 -0.129729,0.17297 -0.216216,0.38919 -0.302702,0.64865 h -8.9513515 c -0.2594595,0 -0.4324325,0.17297 -0.4324325,0.43243 0,0.25946 0.172973,0.43243 0.4324325,0.43243 h 8.9513515 c 0.08649,0.38919 0.345946,0.77838 0.691892,1.03784 0.778378,0.6054 1.945946,0.43243 2.508108,-0.38919 z m -1.989189,-0.3027 c -0.216217,-0.12973 -0.345946,-0.34595 -0.38919,-0.60541 -0.04324,-0.25946 0,-0.47567 0.172973,-0.69189 0.302703,-0.43243 0.908109,-0.51892 1.297298,-0.21622 0.216216,0.12973 0.345946,0.34595 0.389189,0.60541 0,0.0432 0,0.0865 0,0.12973 0,0.21621 -0.04324,0.38919 -0.172973,0.56216 -0.302703,0.43243 -0.908108,0.51892 -1.297297,0.21622 z m -4.410811,5.23243 c 0.129729,-0.17297 0.259459,-0.38919 0.302702,-0.64865 h 9.081081 c 0.25946,0 0.432433,-0.17297 0.432433,-0.43243 0,-0.25946 -0.172973,-0.43243 -0.432433,-0.43243 h -9.081081 c -0.08649,-0.38919 -0.345945,-0.77838 -0.6918914,-1.03784 -0.8216216,-0.60541 -1.9459459,-0.38919 -2.5081081,0.38919 -0.1297297,0.17297 -0.2162162,0.38919 -0.3027027,0.64865 h -2.5513513 c -0.2594595,0 -0.4324325,0.17297 -0.4324325,0.43243 0,0.25946 0.172973,0.43243 0.4324325,0.43243 h 2.5513513 c 0.086486,0.38919 0.3459459,0.77838 0.6918919,1.03784 0.7783784,0.56216 1.9027027,0.38919 2.5081083,-0.38919 z m -1.9891894,-0.34595 c -0.2162162,-0.12973 -0.3459459,-0.34594 -0.3891892,-0.6054 -0.043243,-0.25946 0,-0.47568 0.172973,-0.69189 0.3027027,-0.43244 0.9081081,-0.51892 1.2972973,-0.21622 0.2162162,0.12973 0.3459459,0.34595 0.3891892,0.60541 0,0.0432 0,0.0865 0,0.12973 0,0 0,0 0,0 0,0 0,0 0,0 0,0.21621 -0.043243,0.38918 -0.172973,0.56216 -0.3027027,0.43243 -0.9081081,0.51892 -1.2972973,0.21621 z m 6.7027024,5.23244 c 0.12973,-0.17298 0.25946,-0.38919 0.302703,-0.64865 h 4.367567 c 0.25946,0 0.432433,-0.17298 0.432433,-0.43244 0,-0.25945 -0.172973,-0.43243 -0.432433,-0.43243 h -4.367567 c -0.08649,-0.38919 -0.345946,-0.77838 -0.691892,-1.03784 -0.389189,-0.3027 -0.864865,-0.38918 -1.34054,-0.34594 -0.475676,0.0865 -0.908109,0.34594 -1.167568,0.73513 -0.12973,0.21622 -0.216216,0.38919 -0.302703,0.64865 h -7.2648645 c -0.2594595,0 -0.4324325,0.17298 -0.4324325,0.43243 0,0.25946 0.172973,0.43244 0.4324325,0.43244 h 7.3081085 c 0.08649,0.38919 0.345945,0.77838 0.691891,1.03784 0.778379,0.56216 1.902703,0.38918 2.464865,-0.38919 z m -1.989189,-0.30271 c -0.216216,-0.17297 -0.345946,-0.38919 -0.389189,-0.64865 0,-0.0432 0,-0.0865 0,-0.0865 0,-0.0433 0,-0.0865 0,-0.0865 0,-0.17297 0.08649,-0.3027 0.172973,-0.43243 0.12973,-0.21622 0.345946,-0.34595 0.605405,-0.38919 0.25946,-0.0432 0.475676,0.0432 0.691892,0.17297 0.216216,0.12973 0.345946,0.34595 0.389189,0.60541 0,0.0432 0,0.0865 0,0.12973 0,0 0,0 0,0 0,0 0,0 0,0 0,0.21621 -0.04324,0.38919 -0.172973,0.56216 -0.302702,0.38919 -0.864864,0.47568 -1.297297,0.17297 z" id="path1-3" style="stroke-width:1;fill:#4d4d4d;fill-opacity:1" />
|
||||
<path style="fill:#4d4d4d;fill-opacity:1;stroke:none" d="m 63.71429,866.36218 -1.14285,1.14286 2.28571,2.28572 L 66,868.6479 Z M 62,868.07646 l -6.285714,6.28574 2.285715,2.2857 6.285719,-6.28572 z M 55.714286,874.3622 54,878.36219 58.000001,876.6479 Z" id="edit" inkscape:connector-curvature="0" sodipodi:nodetypes="cccccccccccccc" />
|
||||
<text xml:space="preserve" style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" x="39.647079" y="918.79706" id="text4457-6"><tspan y="918.79706" x="39.647079" sodipodi:role="line" id="tspan4459-6" style="font-size:30.4762px;line-height:1.25;font-family:sans-serif"> </tspan></text>
|
||||
<g id="text4356-2" style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.1;stroke-dasharray:none;stroke-opacity:1" transform="translate(44,-124)">
|
||||
|
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 47 KiB |
|
@ -9,11 +9,22 @@ export default class Browser {
|
|||
filter: '',
|
||||
inBbox: false,
|
||||
}
|
||||
this._mode = 'layers'
|
||||
}
|
||||
|
||||
set mode(value) {
|
||||
// Store the mode so we can respect it when we redraw
|
||||
if (['data', 'filters'].includes(value)) this.map.panel.mode = 'expanded'
|
||||
else if (value === 'layers') this.map.panel.mode = 'condensed'
|
||||
this._mode = value
|
||||
}
|
||||
|
||||
get mode() {
|
||||
return this._mode
|
||||
}
|
||||
|
||||
addFeature(feature, parent) {
|
||||
const filter = this.options.filter
|
||||
if (filter && !feature.matchFilter(filter, this.filterKeys)) return
|
||||
if (feature.isFiltered()) return
|
||||
if (this.options.inBbox && !feature.isOnScreen(this.bounds)) return
|
||||
const row = DomUtil.create('li', `${feature.getClassName()} feature`)
|
||||
const zoom_to = DomUtil.createButtonIcon(
|
||||
|
@ -98,15 +109,29 @@ export default class Browser {
|
|||
counter.title = translate(`Features in this layer: ${count}`)
|
||||
}
|
||||
|
||||
toggleBadge() {
|
||||
U.Utils.toggleBadge(this.filtersTitle, this.hasFilters())
|
||||
U.Utils.toggleBadge('.umap-control-browse', this.hasFilters())
|
||||
}
|
||||
|
||||
onFormChange() {
|
||||
this.map.eachBrowsableDataLayer((datalayer) => {
|
||||
datalayer.resetLayer(true)
|
||||
this.updateDatalayer(datalayer)
|
||||
})
|
||||
this.toggleBadge()
|
||||
}
|
||||
|
||||
redraw() {
|
||||
if (this.isOpen()) this.open()
|
||||
}
|
||||
|
||||
isOpen() {
|
||||
return !!document.querySelector('.umap-browser')
|
||||
return !!document.querySelector('.on .umap-browser')
|
||||
}
|
||||
|
||||
hasFilters() {
|
||||
return !!this.options.filter || this.map.facets.isActive()
|
||||
}
|
||||
|
||||
onMoveEnd() {
|
||||
|
@ -126,7 +151,9 @@ export default class Browser {
|
|||
})
|
||||
}
|
||||
|
||||
open() {
|
||||
open(mode) {
|
||||
// Force only if mode is known, otherwise keep current mode.
|
||||
if (mode) this.mode = mode
|
||||
// Get once but use it for each feature later
|
||||
this.filterKeys = this.map.getFilterKeys()
|
||||
const container = DomUtil.create('div')
|
||||
|
@ -135,18 +162,46 @@ export default class Browser {
|
|||
DomEvent.disableClickPropagation(container)
|
||||
|
||||
DomUtil.createTitle(container, translate('Browse data'), 'icon-layers')
|
||||
this.tabsMenu(container, 'browse')
|
||||
const formContainer = DomUtil.create('div', '', container)
|
||||
const formContainer = DomUtil.createFieldset(container, L._('Filters'), {
|
||||
on: this.mode === 'filters',
|
||||
className: 'filters',
|
||||
icon: 'icon-filters',
|
||||
})
|
||||
this.filtersTitle = container.querySelector('summary')
|
||||
this.toggleBadge()
|
||||
this.dataContainer = DomUtil.create('div', '', container)
|
||||
|
||||
const fields = [
|
||||
['options.filter', { handler: 'Input', placeholder: translate('Filter') }],
|
||||
let fields = [
|
||||
[
|
||||
'options.filter',
|
||||
{ handler: 'Input', placeholder: translate('Search map features…') },
|
||||
],
|
||||
['options.inBbox', { handler: 'Switch', label: translate('Current map view') }],
|
||||
]
|
||||
const builder = new L.FormBuilder(this, fields, {
|
||||
callback: () => this.onFormChange(),
|
||||
})
|
||||
let filtersBuilder
|
||||
formContainer.appendChild(builder.build())
|
||||
DomEvent.on(builder.form, 'reset', () => {
|
||||
window.setTimeout(builder.syncAll.bind(builder))
|
||||
})
|
||||
if (this.map.options.facetKey) {
|
||||
fields = this.map.facets.build()
|
||||
filtersBuilder = new L.FormBuilder(this.map.facets, fields, {
|
||||
callback: () => this.onFormChange(),
|
||||
})
|
||||
DomEvent.on(filtersBuilder.form, 'reset', () => {
|
||||
window.setTimeout(filtersBuilder.syncAll.bind(filtersBuilder))
|
||||
})
|
||||
formContainer.appendChild(filtersBuilder.build())
|
||||
}
|
||||
const reset = DomUtil.createButton('flat', formContainer, '', () => {
|
||||
builder.form.reset()
|
||||
if (filtersBuilder) filtersBuilder.form.reset()
|
||||
})
|
||||
DomUtil.createIcon(reset, 'icon-restore')
|
||||
DomUtil.element({ tagName: 'span', parent: reset, textContent: translate('Reset all') })
|
||||
|
||||
this.map.panel.open({
|
||||
content: container,
|
||||
|
@ -166,18 +221,4 @@ export default class Browser {
|
|||
DomEvent.on(button, 'click', map.openBrowser, map)
|
||||
return button
|
||||
}
|
||||
|
||||
tabsMenu(container, active) {
|
||||
const tabs = L.DomUtil.create('div', 'flat-tabs', container)
|
||||
const browse = L.DomUtil.add('button', 'flat tab-browse', tabs, L._('Data'))
|
||||
DomEvent.on(browse, 'click', this.open, this)
|
||||
if (this.map.options.facetKey) {
|
||||
const facets = L.DomUtil.add('button', 'flat tab-facets', tabs, L._('Filters'))
|
||||
DomEvent.on(facets, 'click', this.map.facets.open, this.map.facets)
|
||||
}
|
||||
const info = L.DomUtil.add('button', 'flat tab-info', tabs, L._('About'))
|
||||
DomEvent.on(info, 'click', this.map.displayCaption, this.map)
|
||||
let el = tabs.querySelector(`.tab-${active}`)
|
||||
L.DomUtil.addClass(el, 'on')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,15 +10,18 @@ export default class Facets {
|
|||
|
||||
compute(names, defined) {
|
||||
const properties = {}
|
||||
let selected
|
||||
|
||||
names.forEach((name) => {
|
||||
const type = defined[name]['type']
|
||||
properties[name] = { type: type }
|
||||
this.selected[name] = { type: type }
|
||||
selected = this.selected[name] || {}
|
||||
selected.type = type
|
||||
if (!['date', 'datetime', 'number'].includes(type)) {
|
||||
properties[name].choices = []
|
||||
this.selected[name].choices = []
|
||||
selected.choices = selected.choices || []
|
||||
}
|
||||
this.selected[name] = selected
|
||||
})
|
||||
|
||||
this.map.eachBrowsableDataLayer((datalayer) => {
|
||||
|
@ -53,42 +56,20 @@ export default class Facets {
|
|||
return properties
|
||||
}
|
||||
|
||||
redraw() {
|
||||
if (this.isOpen()) this.open()
|
||||
isActive() {
|
||||
for (let { type, min, max, choices } of Object.values(this.selected)) {
|
||||
if (min !== undefined || max != undefined || choices?.length) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
isOpen() {
|
||||
return !!document.querySelector('.umap-facet-search')
|
||||
}
|
||||
|
||||
open() {
|
||||
const container = L.DomUtil.create('div', 'umap-facet-search')
|
||||
const title = L.DomUtil.add(
|
||||
'h3',
|
||||
'umap-filter-title',
|
||||
container,
|
||||
translate('Facet search')
|
||||
)
|
||||
this.map.browser.tabsMenu(container, 'facets')
|
||||
build() {
|
||||
const defined = this.getDefined()
|
||||
const names = Object.keys(defined)
|
||||
const facetProperties = this.compute(names, defined)
|
||||
|
||||
const filterFeatures = function () {
|
||||
let found = false
|
||||
this.map.eachBrowsableDataLayer((datalayer) => {
|
||||
datalayer.resetLayer(true)
|
||||
if (datalayer.hasDataVisible()) found = true
|
||||
})
|
||||
// TODO: display a results counter in the panel instead.
|
||||
if (!found) {
|
||||
this.map.ui.alert({
|
||||
content: translate('No results for these facets'),
|
||||
level: 'info',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const fields = names.map((name) => {
|
||||
let criteria = facetProperties[name]
|
||||
let handler = 'FacetSearchChoices'
|
||||
|
@ -114,13 +95,7 @@ export default class Facets {
|
|||
]
|
||||
})
|
||||
|
||||
const builder = new L.FormBuilder(this, fields, {
|
||||
callback: filterFeatures,
|
||||
callbackContext: this,
|
||||
})
|
||||
container.appendChild(builder.build())
|
||||
|
||||
this.map.panel.open({ content: container })
|
||||
return fields
|
||||
}
|
||||
|
||||
getDefined() {
|
||||
|
|
|
@ -272,9 +272,9 @@ export const SCHEMA = {
|
|||
choices: [
|
||||
['none', translate('None')],
|
||||
['caption', translate('Caption')],
|
||||
['databrowser', translate('Data browser')],
|
||||
['datalayers', translate('Layers')],
|
||||
['facet', translate('Facet search')],
|
||||
['databrowser', translate('Browser in data mode')],
|
||||
['datalayers', translate('Browser in layers mode')],
|
||||
['datafilters', translate('Browser in filters mode')],
|
||||
],
|
||||
default: 'none',
|
||||
},
|
||||
|
|
|
@ -362,3 +362,11 @@ export function parseNaiveDate(value) {
|
|||
// Let's pretend naive date are UTC, and remove time…
|
||||
return new Date(Date.UTC(naive.getFullYear(), naive.getMonth(), naive.getDate()))
|
||||
}
|
||||
|
||||
export function toggleBadge(element, value) {
|
||||
if (!element.nodeType) element = document.querySelector(element)
|
||||
if (!element) return
|
||||
// True means simple badge, without content
|
||||
if (value) element.dataset.badge = value === true ? ' ' : value
|
||||
else delete element.dataset.badge
|
||||
}
|
||||
|
|
|
@ -499,8 +499,11 @@ L.Control.Button = L.Control.extend({
|
|||
this
|
||||
)
|
||||
L.DomEvent.on(button, 'dblclick', L.DomEvent.stopPropagation)
|
||||
this.afterAdd(container)
|
||||
return container
|
||||
},
|
||||
|
||||
afterAdd: function (container) {},
|
||||
})
|
||||
|
||||
U.DataLayersControl = L.Control.Button.extend({
|
||||
|
@ -510,6 +513,10 @@ U.DataLayersControl = L.Control.Button.extend({
|
|||
title: L._('See layers'),
|
||||
},
|
||||
|
||||
afterAdd: function (container) {
|
||||
U.Utils.toggleBadge(container, this.map.browser.hasFilters())
|
||||
},
|
||||
|
||||
onClick: function () {
|
||||
this.map.openBrowser()
|
||||
},
|
||||
|
@ -663,15 +670,11 @@ const ControlsMixin = {
|
|||
'star',
|
||||
'tilelayers',
|
||||
],
|
||||
_openFacet: function () {
|
||||
this.facets.open()
|
||||
},
|
||||
|
||||
displayCaption: function () {
|
||||
const container = L.DomUtil.create('div', 'umap-caption')
|
||||
L.DomUtil.createTitle(container, this.options.name, 'icon-caption')
|
||||
this.permissions.addOwnerLink('h5', container)
|
||||
this.browser.tabsMenu(container, 'info')
|
||||
if (this.options.description) {
|
||||
const description = L.DomUtil.element({
|
||||
tagName: 'div',
|
||||
|
|
|
@ -81,18 +81,18 @@ L.DomUtil.add = (tagName, className, container, content) => {
|
|||
|
||||
L.DomUtil.createFieldset = (container, legend, options) => {
|
||||
options = options || {}
|
||||
const fieldset = L.DomUtil.create('div', 'fieldset toggle', container)
|
||||
const legendEl = L.DomUtil.add('h5', 'legend style_options_toggle', fieldset, legend)
|
||||
const fieldsEl = L.DomUtil.add('div', 'fields with-transition', fieldset)
|
||||
L.DomEvent.on(legendEl, 'click', function () {
|
||||
if (L.DomUtil.hasClass(fieldset, 'on')) {
|
||||
L.DomUtil.removeClass(fieldset, 'on')
|
||||
} else {
|
||||
L.DomUtil.addClass(fieldset, 'on')
|
||||
if (options.callback) options.callback.call(options.context || this)
|
||||
}
|
||||
const details = L.DomUtil.create('details', options.className || '', container)
|
||||
const summary = L.DomUtil.add('summary', '', details)
|
||||
if (options.icon) L.DomUtil.createIcon(summary, options.icon)
|
||||
L.DomUtil.add('span', '', summary, legend)
|
||||
const fieldset = L.DomUtil.add('fieldset', '', details)
|
||||
details.open = options.on === true
|
||||
if (options.callback) {
|
||||
L.DomEvent.on(details, 'toggle', () => {
|
||||
if (details.open) options.callback.call(options.context || this)
|
||||
})
|
||||
return fieldsEl
|
||||
}
|
||||
return fieldset
|
||||
}
|
||||
|
||||
L.DomUtil.createButton = (className, container, content, callback, context) => {
|
||||
|
@ -556,9 +556,9 @@ U.Help = L.Class.extend({
|
|||
'Comma separated list of properties to use for sorting features. To reverse the sort, put a minus sign (-) before. Eg. mykey,-otherkey.'
|
||||
),
|
||||
slugKey: L._('The name of the property to use as feature unique identifier.'),
|
||||
filterKey: L._('Comma separated list of properties to use when filtering features'),
|
||||
filterKey: L._('Comma separated list of properties to use when filtering features by text input'),
|
||||
facetKey: L._(
|
||||
'Comma separated list of properties to use for facet search (eg.: mykey,otherkey). To control label, add it after a | (eg.: mykey|My Key,otherkey|Other Key). To control input field type, add it after another | (eg.: mykey|My Key|checkbox,otherkey|Other Key|datetime). Allowed values for the input field type are checkbox (default), radio, number, date and datetime.'
|
||||
'Comma separated list of properties to use for filters (eg.: mykey,otherkey). To control label, add it after a | (eg.: mykey|My Key,otherkey|Other Key). To control input field type, add it after another | (eg.: mykey|My Key|checkbox,otherkey|Other Key|datetime). Allowed values for the input field type are checkbox (default), radio, number, date and datetime.'
|
||||
),
|
||||
interactive: L._(
|
||||
'If false, the polygon or line will act as a part of the underlying map.'
|
||||
|
|
|
@ -494,6 +494,14 @@ U.FeatureMixin = {
|
|||
this.bindTooltip(U.Utils.escapeHTML(displayName), options)
|
||||
},
|
||||
|
||||
isFiltered: function () {
|
||||
const filterKeys = this.map.getFilterKeys()
|
||||
const filter = this.map.browser.options.filter
|
||||
if (filter && !this.matchFilter(filter, filterKeys)) return true
|
||||
if (!this.matchFacets()) return true
|
||||
return false
|
||||
},
|
||||
|
||||
matchFilter: function (filter, keys) {
|
||||
filter = filter.toLowerCase()
|
||||
for (let i = 0, value; i < keys.length; i++) {
|
||||
|
@ -513,8 +521,6 @@ U.FeatureMixin = {
|
|||
case 'date':
|
||||
case 'datetime':
|
||||
case 'number':
|
||||
min = parser(min)
|
||||
max = parser(max)
|
||||
if (!isNaN(min) && !isNaN(value) && min > value) return false
|
||||
if (!isNaN(max) && !isNaN(value) && max < value) return false
|
||||
break
|
||||
|
|
|
@ -744,7 +744,17 @@ L.FormBuilder.Switch = L.FormBuilder.CheckBox.extend({
|
|||
},
|
||||
})
|
||||
|
||||
L.FormBuilder.FacetSearchChoices = L.FormBuilder.Element.extend({
|
||||
L.FormBuilder.FacetSearchBase = L.FormBuilder.Element.extend({
|
||||
|
||||
buildLabel: function () {
|
||||
this.label = L.DomUtil.element({
|
||||
tagName: 'legend',
|
||||
textContent: this.options.label,
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
L.FormBuilder.FacetSearchChoices = L.FormBuilder.FacetSearchBase.extend({
|
||||
build: function () {
|
||||
this.container = L.DomUtil.create('fieldset', 'umap-facet', this.parentNode)
|
||||
this.container.appendChild(this.label)
|
||||
|
@ -756,13 +766,6 @@ L.FormBuilder.FacetSearchChoices = L.FormBuilder.Element.extend({
|
|||
choices.forEach((value) => this.buildLi(value))
|
||||
},
|
||||
|
||||
buildLabel: function () {
|
||||
this.label = L.DomUtil.element({
|
||||
tagName: 'legend',
|
||||
textContent: this.options.label,
|
||||
})
|
||||
},
|
||||
|
||||
buildLi: function (value) {
|
||||
const property_li = L.DomUtil.create('li', '', this.ul)
|
||||
const label = L.DomUtil.create('label', '', property_li)
|
||||
|
@ -787,7 +790,7 @@ L.FormBuilder.FacetSearchChoices = L.FormBuilder.Element.extend({
|
|||
},
|
||||
})
|
||||
|
||||
L.FormBuilder.MinMaxBase = L.FormBuilder.Element.extend({
|
||||
L.FormBuilder.MinMaxBase = L.FormBuilder.FacetSearchBase.extend({
|
||||
getInputType: function (type) {
|
||||
return type
|
||||
},
|
||||
|
@ -796,7 +799,7 @@ L.FormBuilder.MinMaxBase = L.FormBuilder.Element.extend({
|
|||
return [L._('Min'), L._('Max')]
|
||||
},
|
||||
|
||||
castValue: function (value) {
|
||||
prepareForHTML: function (value) {
|
||||
return value.valueOf()
|
||||
},
|
||||
|
||||
|
@ -804,6 +807,10 @@ L.FormBuilder.MinMaxBase = L.FormBuilder.Element.extend({
|
|||
this.container = L.DomUtil.create('fieldset', 'umap-facet', this.parentNode)
|
||||
this.container.appendChild(this.label)
|
||||
const { min, max, type } = this.options.criteria
|
||||
const { min: modifiedMin, max: modifiedMax } = this.get()
|
||||
|
||||
const currentMin = modifiedMin !== undefined ? modifiedMin : min
|
||||
const currentMax = modifiedMax !== undefined ? modifiedMax : max
|
||||
this.type = type
|
||||
this.inputType = this.getInputType(this.type)
|
||||
|
||||
|
@ -815,9 +822,17 @@ L.FormBuilder.MinMaxBase = L.FormBuilder.Element.extend({
|
|||
this.minInput = L.DomUtil.create('input', '', this.minLabel)
|
||||
this.minInput.type = this.inputType
|
||||
this.minInput.step = 'any'
|
||||
this.minInput.min = this.prepareForHTML(min)
|
||||
this.minInput.max = this.prepareForHTML(max)
|
||||
if (min != null) {
|
||||
this.minInput.valueAsNumber = this.castValue(min)
|
||||
this.minInput.dataset.value = min
|
||||
// The value stored using setAttribute is not modified by
|
||||
// user input, and will be used as initial value when calling
|
||||
// form.reset(), and can also be retrieve later on by using
|
||||
// getAttributing, to compare with current value and know
|
||||
// if this value has been modified by the user
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/reset
|
||||
this.minInput.setAttribute('value', this.prepareForHTML(min))
|
||||
this.minInput.value = this.prepareForHTML(currentMin)
|
||||
}
|
||||
|
||||
this.maxLabel = L.DomUtil.create('label', '', this.container)
|
||||
|
@ -826,37 +841,76 @@ L.FormBuilder.MinMaxBase = L.FormBuilder.Element.extend({
|
|||
this.maxInput = L.DomUtil.create('input', '', this.maxLabel)
|
||||
this.maxInput.type = this.inputType
|
||||
this.maxInput.step = 'any'
|
||||
this.maxInput.min = this.prepareForHTML(min)
|
||||
this.maxInput.max = this.prepareForHTML(max)
|
||||
if (max != null) {
|
||||
this.maxInput.valueAsNumber = this.castValue(max)
|
||||
this.maxInput.dataset.value = max
|
||||
// Cf comment above about setAttribute vs value
|
||||
this.maxInput.setAttribute('value', this.prepareForHTML(max))
|
||||
this.maxInput.value = this.prepareForHTML(currentMax)
|
||||
}
|
||||
this.toggleStatus()
|
||||
|
||||
L.DomEvent.on(this.minInput, 'change', (e) => this.sync())
|
||||
L.DomEvent.on(this.maxInput, 'change', (e) => this.sync())
|
||||
L.DomEvent.on(this.minInput, 'change', () => this.sync())
|
||||
L.DomEvent.on(this.maxInput, 'change', () => this.sync())
|
||||
},
|
||||
|
||||
buildLabel: function () {
|
||||
this.label = L.DomUtil.element({
|
||||
tagName: 'legend',
|
||||
textContent: this.options.label,
|
||||
})
|
||||
toggleStatus: function () {
|
||||
this.minInput.dataset.modified = this.isMinModified()
|
||||
this.maxInput.dataset.modified = this.isMaxModified()
|
||||
},
|
||||
|
||||
sync: function () {
|
||||
L.FormBuilder.Element.prototype.sync.call(this)
|
||||
this.toggleStatus()
|
||||
},
|
||||
|
||||
isMinModified: function () {
|
||||
const default_ = this.minInput.getAttribute("value")
|
||||
const current = this.minInput.value
|
||||
return current != default_
|
||||
},
|
||||
|
||||
isMaxModified: function () {
|
||||
const default_ = this.maxInput.getAttribute("value")
|
||||
const current = this.maxInput.value
|
||||
return current != default_
|
||||
},
|
||||
|
||||
toJS: function () {
|
||||
return {
|
||||
const opts = {
|
||||
type: this.type,
|
||||
min: this.minInput.value,
|
||||
max: this.maxInput.value,
|
||||
}
|
||||
if (this.minInput.value !== '' && this.isMinModified()) {
|
||||
opts.min = this.prepareForJS(this.minInput.value)
|
||||
}
|
||||
if (this.maxInput.value !== '' && this.isMaxModified()) {
|
||||
opts.max = this.prepareForJS(this.maxInput.value)
|
||||
}
|
||||
return opts
|
||||
},
|
||||
})
|
||||
|
||||
L.FormBuilder.FacetSearchNumber = L.FormBuilder.MinMaxBase.extend({})
|
||||
L.FormBuilder.FacetSearchNumber = L.FormBuilder.MinMaxBase.extend({
|
||||
prepareForJS: function (value) {
|
||||
return new Number(value)
|
||||
},
|
||||
})
|
||||
|
||||
L.FormBuilder.FacetSearchDate = L.FormBuilder.MinMaxBase.extend({
|
||||
castValue: function (value) {
|
||||
return value.valueOf() - value.getTimezoneOffset() * 60000
|
||||
prepareForJS: function (value) {
|
||||
return new Date(value)
|
||||
},
|
||||
|
||||
toLocaleDateTime: function (dt) {
|
||||
return new Date(dt.valueOf() - dt.getTimezoneOffset() * 60000)
|
||||
},
|
||||
|
||||
prepareForHTML: function (value) {
|
||||
// Value must be in local time
|
||||
if (isNaN(value)) return
|
||||
return this.toLocaleDateTime(value).toISOString().substr(0, 10)
|
||||
},
|
||||
|
||||
getLabels: function () {
|
||||
return [L._('From'), L._('Until')]
|
||||
},
|
||||
|
@ -866,6 +920,12 @@ L.FormBuilder.FacetSearchDateTime = L.FormBuilder.FacetSearchDate.extend({
|
|||
getInputType: function (type) {
|
||||
return 'datetime-local'
|
||||
},
|
||||
|
||||
prepareForHTML: function (value) {
|
||||
// Value must be in local time
|
||||
if (isNaN(value)) return
|
||||
return this.toLocaleDateTime(value).toISOString().slice(0, -1)
|
||||
},
|
||||
})
|
||||
|
||||
L.FormBuilder.MultiChoice = L.FormBuilder.Element.extend({
|
||||
|
|
|
@ -149,6 +149,9 @@ U.Map = L.Map.extend({
|
|||
if (this.options.datalayersControl === 'expanded') {
|
||||
this.options.onLoadPanel = 'datalayers'
|
||||
}
|
||||
if (this.options.onLoadPanel === 'facet') {
|
||||
this.options.onLoadPanel = 'datafilters'
|
||||
}
|
||||
|
||||
let isDirty = false // self status
|
||||
try {
|
||||
|
@ -211,15 +214,15 @@ U.Map = L.Map.extend({
|
|||
if (L.Util.queryString('share')) {
|
||||
this.share.open()
|
||||
} else if (this.options.onLoadPanel === 'databrowser') {
|
||||
this.openBrowser('expanded')
|
||||
this.openBrowser('data')
|
||||
} else if (this.options.onLoadPanel === 'datalayers') {
|
||||
this.openBrowser('condensed')
|
||||
this.openBrowser('layers')
|
||||
} else if (this.options.onLoadPanel === 'datafilters') {
|
||||
this.panel.mode = 'expanded'
|
||||
this.openBrowser('filters')
|
||||
} else if (this.options.onLoadPanel === 'caption') {
|
||||
this.panel.mode = 'condensed'
|
||||
this.displayCaption()
|
||||
} else if (['facet', 'datafilters'].includes(this.options.onLoadPanel)) {
|
||||
this.panel.mode = 'expanded'
|
||||
this.openFacet()
|
||||
}
|
||||
if (L.Util.queryString('edit')) {
|
||||
if (this.hasEditMode()) this.enableEdit()
|
||||
|
@ -252,7 +255,7 @@ U.Map = L.Map.extend({
|
|||
this.initCaptionBar()
|
||||
this.renderEditToolbar()
|
||||
this.renderControls()
|
||||
this.facets.redraw()
|
||||
this.browser.redraw()
|
||||
break
|
||||
case 'data':
|
||||
this.redrawVisibleDataLayers()
|
||||
|
@ -908,15 +911,8 @@ U.Map = L.Map.extend({
|
|||
},
|
||||
|
||||
openBrowser: function (mode) {
|
||||
if (mode) this.panel.mode = mode
|
||||
this.onceDatalayersLoaded(function () {
|
||||
this.browser.open()
|
||||
})
|
||||
},
|
||||
|
||||
openFacet: function () {
|
||||
this.onceDataLoaded(function () {
|
||||
this._openFacet()
|
||||
this.browser.open(mode)
|
||||
})
|
||||
},
|
||||
|
||||
|
@ -1229,7 +1225,7 @@ U.Map = L.Map.extend({
|
|||
handler: 'Input',
|
||||
helpEntries: 'filterKey',
|
||||
placeholder: L._('Default: name'),
|
||||
label: L._('Filter keys'),
|
||||
label: L._('Search keys'),
|
||||
inheritable: true,
|
||||
},
|
||||
],
|
||||
|
@ -1239,7 +1235,7 @@ U.Map = L.Map.extend({
|
|||
handler: 'BlurInput',
|
||||
helpEntries: 'facetKey',
|
||||
placeholder: L._('Example: key1,key2|Label 2,key3|Label 3|checkbox'),
|
||||
label: L._('Facet keys'),
|
||||
label: L._('Filters keys'),
|
||||
},
|
||||
],
|
||||
[
|
||||
|
@ -1602,15 +1598,14 @@ U.Map = L.Map.extend({
|
|||
'umap-open-browser-link flat',
|
||||
container,
|
||||
L._('Browse data'),
|
||||
() => this.openBrowser('expanded')
|
||||
() => this.openBrowser('data')
|
||||
)
|
||||
if (this.options.facetKey) {
|
||||
L.DomUtil.createButton(
|
||||
'umap-open-filter-link flat',
|
||||
container,
|
||||
L._('Select data'),
|
||||
this.openFacet,
|
||||
this
|
||||
L._('Filter data'),
|
||||
() => this.openBrowser('filters')
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1747,17 +1742,17 @@ U.Map = L.Map.extend({
|
|||
'-',
|
||||
{
|
||||
text: L._('See layers'),
|
||||
callback: () => this.openBrowser('condensed'),
|
||||
callback: () => this.openBrowser('layers'),
|
||||
},
|
||||
{
|
||||
text: L._('Browse data'),
|
||||
callback: () => this.openBrowser('expanded'),
|
||||
callback: () => this.openBrowser('data'),
|
||||
}
|
||||
)
|
||||
if (this.options.facetKey) {
|
||||
items.push({
|
||||
text: L._('Facet search'),
|
||||
callback: this.openFacet,
|
||||
text: L._('Filter data'),
|
||||
callback: () => this.openBrowser('filters'),
|
||||
})
|
||||
}
|
||||
items.push(
|
||||
|
|
|
@ -875,10 +875,7 @@ U.DataLayer = L.Evented.extend({
|
|||
},
|
||||
|
||||
showFeature: function (feature) {
|
||||
const filterKeys = this.map.getFilterKeys(),
|
||||
filter = this.map.browser.options.filter
|
||||
if (filter && !feature.matchFilter(filter, filterKeys)) return
|
||||
if (!feature.matchFacets()) return
|
||||
if (feature.isFiltered()) return
|
||||
this.layer.addLayer(feature)
|
||||
},
|
||||
|
||||
|
|
|
@ -888,10 +888,10 @@ a.umap-control-caption,
|
|||
.umap-browser .datalayer i {
|
||||
cursor: pointer;
|
||||
}
|
||||
.umap-browser ul {
|
||||
.umap-browser .datalayer ul {
|
||||
display: none;
|
||||
}
|
||||
.show-list ul {
|
||||
.umap-browser .show-list ul {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
@ -982,6 +982,21 @@ a.umap-control-caption,
|
|||
.umap-browser .show-list .datalayer-toggle-list {
|
||||
background-position: -145px -45px;
|
||||
}
|
||||
.umap-browser .filters summary {
|
||||
background: none;
|
||||
border: 1px solid var(--color-lightGray);
|
||||
width: fit-content;
|
||||
padding: 0 10px;
|
||||
margin-bottom: var(--block-margin);
|
||||
}
|
||||
.umap-browser .filters summary {
|
||||
list-style: none;
|
||||
display: inline-block;
|
||||
}
|
||||
.umap-browser details[open].filters summary {
|
||||
margin-bottom: -1px;
|
||||
border-bottom: 1px solid var(--background-color);
|
||||
}
|
||||
.datalayer-name {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,13 @@
|
|||
--color-darkBlue: #263B58;
|
||||
--color-lightGray: #ddd;
|
||||
--color-darkGray: #323737;
|
||||
--color-light: white;
|
||||
--color-limeGreen: #b9f5d2;
|
||||
--color-brightCyan: #46ece6;
|
||||
--color-lightCyan: #d4fbf9;
|
||||
|
||||
--background-color: var(--color-light);
|
||||
--color-accent: var(--color-brightCyan);
|
||||
|
||||
/* Buttons. */
|
||||
--button-primary-background: var(--color-waterMint);
|
||||
|
@ -20,3 +27,6 @@
|
|||
--footer-height: 46px;
|
||||
--control-size: 36px;
|
||||
}
|
||||
.dark {
|
||||
--background-color: var(--color-darkGray);
|
||||
}
|
||||
|
|
|
@ -77,6 +77,7 @@ def test_data_browser_should_be_filterable(live_server, page, bootstrap, map):
|
|||
paths = page.locator(".leaflet-overlay-pane path")
|
||||
expect(markers).to_have_count(1)
|
||||
expect(paths).to_have_count(2)
|
||||
page.locator(".filters summary").click()
|
||||
filter_ = page.locator("input[name='filter']")
|
||||
expect(filter_).to_be_visible()
|
||||
filter_.type("poly")
|
||||
|
@ -103,6 +104,7 @@ def test_data_browser_should_be_filterable(live_server, page, bootstrap, map):
|
|||
def test_data_browser_can_show_only_visible_features(live_server, page, bootstrap, map):
|
||||
# Zoom on France
|
||||
page.goto(f"{live_server.url}{map.get_absolute_url()}#6/51.000/2.000")
|
||||
page.locator(".filters summary").click()
|
||||
el = page.get_by_text("Current map view")
|
||||
expect(el).to_be_visible()
|
||||
el.click()
|
||||
|
@ -114,6 +116,7 @@ def test_data_browser_can_show_only_visible_features(live_server, page, bootstra
|
|||
def test_data_browser_can_mix_filter_and_bbox(live_server, page, bootstrap, map):
|
||||
# Zoom on north west
|
||||
page.goto(f"{live_server.url}{map.get_absolute_url()}#4/61.98/-2.68")
|
||||
page.locator(".filters summary").click()
|
||||
el = page.get_by_text("Current map view")
|
||||
expect(el).to_be_visible()
|
||||
el.click()
|
||||
|
@ -131,6 +134,7 @@ def test_data_browser_can_mix_filter_and_bbox(live_server, page, bootstrap, map)
|
|||
def test_data_browser_bbox_limit_should_be_dynamic(live_server, page, bootstrap, map):
|
||||
# Zoom on Europe
|
||||
page.goto(f"{live_server.url}{map.get_absolute_url()}#6/51.000/2.000")
|
||||
page.locator(".filters summary").click()
|
||||
el = page.get_by_text("Current map view")
|
||||
expect(el).to_be_visible()
|
||||
el.click()
|
||||
|
@ -156,6 +160,7 @@ def test_data_browser_bbox_filter_should_be_persistent(
|
|||
):
|
||||
# Zoom on Europe
|
||||
page.goto(f"{live_server.url}{map.get_absolute_url()}#6/51.000/2.000")
|
||||
page.locator(".filters summary").click()
|
||||
el = page.get_by_text("Current map view")
|
||||
expect(el).to_be_visible()
|
||||
el.click()
|
||||
|
@ -181,6 +186,7 @@ def test_data_browser_bbox_filtered_is_clickable(live_server, page, bootstrap, m
|
|||
popup = page.locator(".leaflet-popup")
|
||||
# Zoom on Europe
|
||||
page.goto(f"{live_server.url}{map.get_absolute_url()}#6/51.000/2.000")
|
||||
page.locator(".filters summary").click()
|
||||
el = page.get_by_text("Current map view")
|
||||
expect(el).to_be_visible()
|
||||
el.click()
|
||||
|
@ -202,6 +208,7 @@ def test_data_browser_with_variable_in_name(live_server, page, bootstrap, map):
|
|||
expect(page.get_by_text("one point in france (point)")).to_be_visible()
|
||||
expect(page.get_by_text("one line in new zeland (line)")).to_be_visible()
|
||||
expect(page.get_by_text("one polygon in greenland (polygon)")).to_be_visible()
|
||||
page.locator(".filters summary").click()
|
||||
filter_ = page.locator("input[name='filter']")
|
||||
expect(filter_).to_be_visible()
|
||||
filter_.type("foobar") # Hide all
|
||||
|
|
|
@ -50,7 +50,7 @@ def test_basic_choropleth_map_with_custom_brewer(openmap, live_server, page):
|
|||
page.get_by_role("button", name="Edit").click()
|
||||
page.get_by_role("link", name="Manage layers").click()
|
||||
page.locator(".panel").get_by_title("Edit", exact=True).click()
|
||||
page.get_by_role("heading", name="Choropleth: settings").click()
|
||||
page.get_by_text("Choropleth: settings").click()
|
||||
page.locator('select[name="brewer"]').select_option("Greens")
|
||||
|
||||
# Hauts-de-France
|
||||
|
|
|
@ -80,7 +80,7 @@ def test_can_clone_datalayer(live_server, openmap, login, datalayer, page):
|
|||
expect(markers).to_have_count(1)
|
||||
page.get_by_role("link", name="Manage layers").click()
|
||||
page.locator(".panel.right").get_by_title("Edit", exact=True).click()
|
||||
page.get_by_role("heading", name="Advanced actions").click()
|
||||
page.get_by_text("Advanced actions").click()
|
||||
page.get_by_role("button", name="Clone").click()
|
||||
expect(layers).to_have_count(2)
|
||||
expect(markers).to_have_count(2)
|
||||
|
@ -104,7 +104,7 @@ def test_can_change_icon_class(live_server, openmap, page):
|
|||
page.get_by_role("link", name="Manage layers").click()
|
||||
expect(page.locator(".umap-circle-icon")).to_be_hidden()
|
||||
page.locator(".panel.right").get_by_title("Edit", exact=True).click()
|
||||
page.get_by_role("heading", name="Shape properties").click()
|
||||
page.get_by_text("Shape properties").click()
|
||||
page.locator(".umap-field-iconClass a.define").click()
|
||||
page.get_by_text("Circle").click()
|
||||
expect(page.locator(".umap-circle-icon")).to_be_visible()
|
||||
|
@ -165,14 +165,14 @@ def test_can_restore_version(live_server, openmap, page, datalayer):
|
|||
marker = page.locator(".leaflet-marker-icon")
|
||||
expect(marker).to_have_class(re.compile(".*umap-ball-icon.*"))
|
||||
marker.click(modifiers=["Shift"])
|
||||
page.get_by_role("heading", name="Shape properties").click()
|
||||
page.get_by_text("Shape properties").click()
|
||||
page.locator("#umap-feature-shape-properties").get_by_text("Default").click()
|
||||
with page.expect_response(re.compile(".*/datalayer/update/.*")):
|
||||
page.get_by_role("button", name="Save").click()
|
||||
expect(marker).to_have_class(re.compile(".*umap-div-icon.*"))
|
||||
page.get_by_role("link", name="Manage layers").click()
|
||||
page.locator(".panel.right").get_by_title("Edit", exact=True).click()
|
||||
page.get_by_role("heading", name="Versions").click()
|
||||
page.get_by_text("Versions").click()
|
||||
page.once("dialog", lambda dialog: dialog.accept())
|
||||
page.get_by_role("button", name="Restore this version").last.click()
|
||||
expect(marker).to_have_class(re.compile(".*umap-ball-icon.*"))
|
||||
|
@ -182,4 +182,4 @@ def test_can_edit_layer_on_ctrl_shift_click(live_server, openmap, page, datalaye
|
|||
modifier = "Meta" if platform.system() == "Darwin" else "Control"
|
||||
page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
|
||||
page.locator(".leaflet-marker-icon").click(modifiers=[modifier, "Shift"])
|
||||
expect(page.get_by_role("heading", name="Layer properties")).to_be_visible()
|
||||
expect(page.get_by_text("Layer properties")).to_be_visible()
|
||||
|
|
|
@ -58,7 +58,7 @@ def test_zoomcontrol_impacts_ui(live_server, page, tilelayer):
|
|||
expect(zoom_out).to_be_visible()
|
||||
|
||||
# Hide them
|
||||
page.get_by_role("heading", name="User interface options").click()
|
||||
page.get_by_text("User interface options").click()
|
||||
hide_zoom_controls = (
|
||||
page.locator("div")
|
||||
.filter(has_text=re.compile(r"^Display the zoom control"))
|
||||
|
@ -90,7 +90,7 @@ def test_map_color_impacts_data(live_server, page, tilelayer):
|
|||
expect(marker_pane_p1).to_have_count(1)
|
||||
|
||||
# Change the default color
|
||||
page.get_by_role("heading", name="Shape properties").click()
|
||||
page.get_by_text("Shape properties").click()
|
||||
page.locator("#umap-feature-shape-properties").get_by_text("define").first.click()
|
||||
page.get_by_title("Lime", exact=True).click()
|
||||
|
||||
|
@ -108,7 +108,7 @@ def test_limitbounds_impacts_ui(live_server, page, tilelayer):
|
|||
expect(gear_icon).to_be_visible()
|
||||
gear_icon.click()
|
||||
|
||||
page.get_by_role("heading", name="Limit bounds").click()
|
||||
page.get_by_text("Limit bounds").click()
|
||||
default_zoom_url = f"{live_server.url}/en/map/new/#5/51.110/7.053"
|
||||
page.goto(default_zoom_url)
|
||||
page.get_by_role("button", name="Use current bounds").click()
|
||||
|
@ -183,7 +183,7 @@ def test_sortkey_impacts_datalayerindex(map, live_server, page):
|
|||
# Change the default sortkey to be "key"
|
||||
page.get_by_role("button", name="Edit").click()
|
||||
page.get_by_role("link", name="Map advanced properties").click()
|
||||
page.get_by_role("heading", name="Default properties").click()
|
||||
page.get_by_text("Default properties").click()
|
||||
|
||||
# Click "define"
|
||||
page.locator(".panel .umap-field-sortKey .define").click()
|
||||
|
|
|
@ -36,7 +36,7 @@ def test_can_edit_on_shift_click(live_server, openmap, page, datalayer):
|
|||
modifier = "Meta" if platform.system() == "Darwin" else "Control"
|
||||
page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
|
||||
page.locator(".leaflet-marker-icon").click(modifiers=[modifier, "Shift"])
|
||||
expect(page.get_by_role("heading", name="Layer properties")).to_be_visible()
|
||||
expect(page.get_by_text("Layer properties")).to_be_visible()
|
||||
|
||||
|
||||
def test_marker_style_should_have_precedence(live_server, openmap, page, bootstrap):
|
||||
|
@ -45,7 +45,7 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr
|
|||
# Change colour at layer level
|
||||
page.get_by_role("link", name="Manage layers").click()
|
||||
page.locator(".panel").get_by_title("Edit", exact=True).click()
|
||||
page.get_by_role("heading", name="Shape properties").click()
|
||||
page.get_by_text("Shape properties").click()
|
||||
page.locator(".umap-field-color .define").click()
|
||||
expect(page.locator(".leaflet-marker-icon .icon_container")).to_have_css(
|
||||
"background-color", "rgb(0, 0, 139)"
|
||||
|
@ -57,7 +57,7 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr
|
|||
|
||||
# Now change at marker level, it should take precedence
|
||||
page.locator(".leaflet-marker-icon").click(modifiers=["Shift"])
|
||||
page.get_by_role("heading", name="Shape properties").click()
|
||||
page.get_by_text("Shape properties").click()
|
||||
page.locator("#umap-feature-shape-properties").get_by_text("define").first.click()
|
||||
page.get_by_title("GoldenRod", exact=True).click()
|
||||
expect(page.locator(".leaflet-marker-icon .icon_container")).to_have_css(
|
||||
|
@ -67,7 +67,7 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr
|
|||
# Now change again at layer level again, it should not change the marker color
|
||||
page.get_by_role("link", name="Manage layers").click()
|
||||
page.locator(".panel").get_by_title("Edit", exact=True).click()
|
||||
page.get_by_role("heading", name="Shape properties").click()
|
||||
page.get_by_text("Shape properties").click()
|
||||
page.locator(".umap-field-color input").click()
|
||||
page.get_by_title("DarkViolet").first.click()
|
||||
expect(page.locator(".leaflet-marker-icon .icon_container")).to_have_css(
|
||||
|
@ -87,12 +87,12 @@ def test_should_update_open_popup_on_edit(live_server, openmap, page, bootstrap)
|
|||
expect(page.locator(".umap-icon-active")).to_be_hidden()
|
||||
page.locator(".leaflet-marker-icon").click()
|
||||
expect(page.locator(".leaflet-popup-content-wrapper")).to_be_visible()
|
||||
expect(page.get_by_role("heading", name="test marker")).to_be_visible()
|
||||
expect(page.get_by_text("test marker")).to_be_visible()
|
||||
expect(page.get_by_text("Some description")).to_be_visible()
|
||||
page.get_by_role("button", name="Edit").click()
|
||||
page.locator(".leaflet-marker-icon").click(modifiers=["Shift"])
|
||||
page.locator('input[name="name"]').fill("test marker edited")
|
||||
expect(page.get_by_role("heading", name="test marker edited")).to_be_visible()
|
||||
expect(page.get_by_text("test marker edited")).to_be_visible()
|
||||
|
||||
|
||||
def test_should_follow_datalayer_style_when_changing_datalayer(
|
||||
|
|
|
@ -50,7 +50,7 @@ def test_can_edit_on_shift_click(live_server, openmap, page, datalayer):
|
|||
modifier = "Meta" if platform.system() == "Darwin" else "Control"
|
||||
page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
|
||||
page.locator(".leaflet-marker-icon").click(modifiers=[modifier, "Shift"])
|
||||
expect(page.get_by_role("heading", name="Layer properties")).to_be_visible()
|
||||
expect(page.get_by_text("Layer properties")).to_be_visible()
|
||||
|
||||
|
||||
def test_marker_style_should_have_precedence(live_server, openmap, page, bootstrap):
|
||||
|
@ -59,7 +59,7 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr
|
|||
# Change colour at layer level
|
||||
page.get_by_role("link", name="Manage layers").click()
|
||||
page.locator(".panel").get_by_title("Edit", exact=True).click()
|
||||
page.get_by_role("heading", name="Shape properties").click()
|
||||
page.get_by_text("Shape properties").click()
|
||||
page.locator(".umap-field-color .define").click()
|
||||
expect(page.locator(".leaflet-overlay-pane path[fill='DarkBlue']")).to_have_count(1)
|
||||
page.get_by_title("DarkRed").first.click()
|
||||
|
@ -67,7 +67,7 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr
|
|||
|
||||
# Now change at polygon level, it should take precedence
|
||||
page.locator("path").click(modifiers=["Shift"])
|
||||
page.get_by_role("heading", name="Shape properties").click()
|
||||
page.get_by_text("Shape properties").click()
|
||||
page.locator("#umap-feature-shape-properties").get_by_text("define").first.click()
|
||||
page.get_by_title("GoldenRod", exact=True).first.click()
|
||||
expect(page.locator(".leaflet-overlay-pane path[fill='GoldenRod']")).to_have_count(
|
||||
|
@ -77,7 +77,7 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr
|
|||
# Now change again at layer level again, it should not change the marker color
|
||||
page.get_by_role("link", name="Manage layers").click()
|
||||
page.locator(".panel").get_by_title("Edit", exact=True).click()
|
||||
page.get_by_role("heading", name="Shape properties").click()
|
||||
page.get_by_text("Shape properties").click()
|
||||
page.locator(".umap-field-color input").click()
|
||||
page.get_by_title("DarkViolet").first.click()
|
||||
expect(page.locator(".leaflet-overlay-pane path[fill='GoldenRod']")).to_have_count(
|
||||
|
@ -99,7 +99,7 @@ def test_can_remove_stroke(live_server, openmap, page, bootstrap):
|
|||
)
|
||||
page.locator("path").click()
|
||||
page.get_by_role("link", name="Toggle edit mode").click()
|
||||
page.get_by_role("heading", name="Shape properties").click()
|
||||
page.get_by_text("Shape properties").click()
|
||||
page.locator(".umap-field-stroke .define").first.click()
|
||||
page.locator(".umap-field-stroke label").first.click()
|
||||
expect(page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']")).to_have_count(
|
||||
|
@ -111,7 +111,7 @@ def test_can_remove_stroke(live_server, openmap, page, bootstrap):
|
|||
def test_should_reset_style_on_cancel(live_server, openmap, page, bootstrap):
|
||||
page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
|
||||
page.locator("path").click(modifiers=["Shift"])
|
||||
page.get_by_role("heading", name="Shape properties").click()
|
||||
page.get_by_text("Shape properties").click()
|
||||
page.locator("#umap-feature-shape-properties").get_by_text("define").first.click()
|
||||
page.get_by_title("GoldenRod", exact=True).first.click()
|
||||
expect(page.locator(".leaflet-overlay-pane path[fill='GoldenRod']")).to_have_count(
|
||||
|
|
|
@ -93,7 +93,7 @@ DATALAYER_DATA3 = {
|
|||
|
||||
|
||||
def test_simple_facet_search(live_server, page, map):
|
||||
map.settings["properties"]["onLoadPanel"] = "facet"
|
||||
map.settings["properties"]["onLoadPanel"] = "datafilters"
|
||||
map.settings["properties"]["facetKey"] = "mytype|My type,mynumber|My Number|number"
|
||||
map.settings["properties"]["showLabel"] = True
|
||||
map.save()
|
||||
|
@ -101,7 +101,7 @@ def test_simple_facet_search(live_server, page, map):
|
|||
DataLayerFactory(map=map, data=DATALAYER_DATA2)
|
||||
DataLayerFactory(map=map, data=DATALAYER_DATA3)
|
||||
page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
|
||||
panel = page.locator(".umap-facet-search")
|
||||
panel = page.locator(".umap-browser")
|
||||
# From a non browsable datalayer, should not be impacted
|
||||
paths = page.locator(".leaflet-overlay-pane path")
|
||||
expect(paths).to_be_visible()
|
||||
|
@ -117,17 +117,28 @@ def test_simple_facet_search(live_server, page, map):
|
|||
markers = page.locator(".leaflet-marker-icon")
|
||||
expect(markers).to_have_count(4)
|
||||
# Tooltips
|
||||
expect(page.get_by_text("Point 1")).to_be_visible()
|
||||
expect(page.get_by_text("Point 2")).to_be_visible()
|
||||
expect(page.get_by_text("Point 3")).to_be_visible()
|
||||
expect(page.get_by_text("Point 4")).to_be_visible()
|
||||
expect(page.get_by_role("tooltip", name="Point 1")).to_be_visible()
|
||||
expect(page.get_by_role("tooltip", name="Point 2")).to_be_visible()
|
||||
expect(page.get_by_role("tooltip", name="Point 3")).to_be_visible()
|
||||
expect(page.get_by_role("tooltip", name="Point 4")).to_be_visible()
|
||||
|
||||
# Datalist
|
||||
expect(panel.get_by_text("Point 1")).to_be_visible()
|
||||
expect(panel.get_by_text("Point 2")).to_be_visible()
|
||||
expect(panel.get_by_text("Point 3")).to_be_visible()
|
||||
expect(panel.get_by_text("Point 4")).to_be_visible()
|
||||
|
||||
# Now let's filter
|
||||
odd.click()
|
||||
expect(markers).to_have_count(2)
|
||||
expect(page.get_by_text("Point 2")).to_be_hidden()
|
||||
expect(page.get_by_text("Point 4")).to_be_hidden()
|
||||
expect(page.get_by_text("Point 1")).to_be_visible()
|
||||
expect(page.get_by_text("Point 3")).to_be_visible()
|
||||
expect(page.get_by_role("tooltip", name="Point 2")).to_be_hidden()
|
||||
expect(page.get_by_role("tooltip", name="Point 4")).to_be_hidden()
|
||||
expect(page.get_by_role("tooltip", name="Point 1")).to_be_visible()
|
||||
expect(page.get_by_role("tooltip", name="Point 3")).to_be_visible()
|
||||
expect(panel.get_by_text("Point 2")).to_be_hidden()
|
||||
expect(panel.get_by_text("Point 4")).to_be_hidden()
|
||||
expect(panel.get_by_text("Point 1")).to_be_visible()
|
||||
expect(panel.get_by_text("Point 3")).to_be_visible()
|
||||
expect(paths).to_be_visible
|
||||
# Now let's filter
|
||||
odd.click()
|
||||
|
@ -156,7 +167,7 @@ def test_simple_facet_search(live_server, page, map):
|
|||
|
||||
|
||||
def test_date_facet_search(live_server, page, map):
|
||||
map.settings["properties"]["onLoadPanel"] = "facet"
|
||||
map.settings["properties"]["onLoadPanel"] = "datafilters"
|
||||
map.settings["properties"]["facetKey"] = "mydate|Date filter|date"
|
||||
map.save()
|
||||
DataLayerFactory(map=map, data=DATALAYER_DATA1)
|
||||
|
@ -174,7 +185,7 @@ def test_date_facet_search(live_server, page, map):
|
|||
|
||||
|
||||
def test_choice_with_empty_value(live_server, page, map):
|
||||
map.settings["properties"]["onLoadPanel"] = "facet"
|
||||
map.settings["properties"]["onLoadPanel"] = "datafilters"
|
||||
map.settings["properties"]["facetKey"] = "mytype|My type"
|
||||
map.save()
|
||||
data = copy.deepcopy(DATALAYER_DATA1)
|
||||
|
@ -191,7 +202,7 @@ def test_choice_with_empty_value(live_server, page, map):
|
|||
|
||||
|
||||
def test_number_with_zero_value(live_server, page, map):
|
||||
map.settings["properties"]["onLoadPanel"] = "facet"
|
||||
map.settings["properties"]["onLoadPanel"] = "datafilters"
|
||||
map.settings["properties"]["facetKey"] = "mynumber|Filter|number"
|
||||
map.save()
|
||||
data = copy.deepcopy(DATALAYER_DATA1)
|
||||
|
@ -205,3 +216,61 @@ def test_number_with_zero_value(live_server, page, map):
|
|||
page.keyboard.press("Tab") # Move out of the input, so the "change" event is sent
|
||||
markers = page.locator(".leaflet-marker-icon")
|
||||
expect(markers).to_have_count(3)
|
||||
|
||||
|
||||
def test_facets_search_are_persistent_when_closing_panel(live_server, page, map):
|
||||
map.settings["properties"]["onLoadPanel"] = "datafilters"
|
||||
map.settings["properties"]["facetKey"] = "mytype|My type,mynumber|My Number|number"
|
||||
map.save()
|
||||
DataLayerFactory(map=map, data=DATALAYER_DATA1)
|
||||
DataLayerFactory(map=map, data=DATALAYER_DATA2)
|
||||
page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
|
||||
panel = page.locator(".umap-browser")
|
||||
|
||||
# Facet values
|
||||
odd = page.get_by_label("odd")
|
||||
markers = page.locator(".leaflet-marker-icon")
|
||||
expect(markers).to_have_count(4)
|
||||
|
||||
# Datalist in the browser
|
||||
expect(panel.get_by_text("Point 1")).to_be_visible()
|
||||
expect(panel.get_by_text("Point 2")).to_be_visible()
|
||||
expect(panel.get_by_text("Point 3")).to_be_visible()
|
||||
expect(panel.get_by_text("Point 4")).to_be_visible()
|
||||
|
||||
# Now let's filter
|
||||
odd.click()
|
||||
expect(page.locator("summary")).to_have_attribute("data-badge", " ")
|
||||
expect(page.locator(".umap-control-browse")).to_have_attribute("data-badge", " ")
|
||||
expect(markers).to_have_count(2)
|
||||
expect(panel.get_by_text("Point 2")).to_be_hidden()
|
||||
expect(panel.get_by_text("Point 4")).to_be_hidden()
|
||||
expect(panel.get_by_text("Point 1")).to_be_visible()
|
||||
expect(panel.get_by_text("Point 3")).to_be_visible()
|
||||
|
||||
# Let's filter using the number facet
|
||||
expect(panel.get_by_label("Min")).to_have_value("10")
|
||||
expect(panel.get_by_label("Max")).to_have_value("14")
|
||||
page.get_by_label("Min").fill("13")
|
||||
page.keyboard.press("Tab") # Move out of the input, so the "change" event is sent
|
||||
expect(panel.get_by_label("Min")).to_have_attribute("data-modified", "true")
|
||||
expect(markers).to_have_count(1)
|
||||
expect(panel.get_by_text("Point 2")).to_be_hidden()
|
||||
expect(panel.get_by_text("Point 4")).to_be_hidden()
|
||||
expect(panel.get_by_text("Point 1")).to_be_hidden()
|
||||
expect(panel.get_by_text("Point 3")).to_be_visible()
|
||||
|
||||
# Close panel
|
||||
expect(panel.locator("summary")).to_have_attribute("data-badge", " ")
|
||||
expect(page.locator(".umap-control-browse")).to_have_attribute("data-badge", " ")
|
||||
page.get_by_role("listitem", name="Close").click()
|
||||
page.get_by_role("button", name="See layers").click()
|
||||
expect(panel.get_by_label("Min")).to_have_value("13")
|
||||
expect(panel.get_by_label("Min")).to_have_attribute("data-modified", "true")
|
||||
expect(panel.get_by_label("odd")).to_be_checked()
|
||||
|
||||
# Datalist in the browser should be inchanged
|
||||
expect(panel.get_by_text("Point 2")).to_be_hidden()
|
||||
expect(panel.get_by_text("Point 4")).to_be_hidden()
|
||||
expect(panel.get_by_text("Point 1")).to_be_hidden()
|
||||
expect(panel.get_by_text("Point 3")).to_be_visible()
|
||||
|
|
Loading…
Reference in a new issue