@geogirafe/lib-geoportal 1.2.0-dev.2872463389 → 1.2.0-dev.2873796427
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/base/GirafeDraggableElement.js +2 -2
- package/base/GirafeResizableElement.js +4 -4
- package/components/basemap/component.js +1 -1
- package/components/cross-section/cross-section-settings/component.js +1 -1
- package/components/cross-section/scatterplot.js +1 -1
- package/components/drawing/component-mobile.js +1 -1
- package/components/drawing/component.js +4 -4
- package/components/drawing/fixed-dimension/component.js +1 -1
- package/components/edit/component.js +1 -1
- package/components/edit/editform/component.js +1 -1
- package/components/extlayers/component.js +1 -1
- package/components/map-2d/component.js +1 -1
- package/components/map-2d/tools/swipemanager.js +2 -2
- package/components/modals/component.js +1 -1
- package/components/print/component.js +7 -7
- package/components/print/tools/MFPLegendEncoder.js +1 -1
- package/components/querybuilder/component.js +2 -2
- package/components/scale/component.js +1 -1
- package/components/selectionwindow/component.js +1 -1
- package/components/share/component.js +1 -1
- package/components/themes-mobile/layer-selected/component.js +1 -1
- package/components/timerestriction/timepicker/component.js +1 -1
- package/components/timerestriction/timeslider/component.js +4 -4
- package/components/treeview/treeviewroot/component.js +1 -1
- package/models/xmlTypes.js +1 -1
- package/package.json +1 -1
- package/templates/public/about.json +1 -1
- package/tools/resizewindow.js +6 -6
- package/tools/time/layertimeformatter.js +1 -1
|
@@ -112,10 +112,10 @@ class GirafeDraggableElement extends GirafeHTMLElement {
|
|
|
112
112
|
const height = this.getContainerHeight();
|
|
113
113
|
const left = _this.host.style.left;
|
|
114
114
|
const top = _this.host.style.top;
|
|
115
|
-
if (parseInt(left) + _this.host.offsetWidth > width) {
|
|
115
|
+
if (Number.parseInt(left) + _this.host.offsetWidth > width) {
|
|
116
116
|
_this.host.style.left = width - _this.host.offsetWidth + 'px';
|
|
117
117
|
}
|
|
118
|
-
if (parseInt(top) + _this.host.offsetHeight > height) {
|
|
118
|
+
if (Number.parseInt(top) + _this.host.offsetHeight > height) {
|
|
119
119
|
_this.host.style.top = height - _this.host.offsetHeight + 'px';
|
|
120
120
|
}
|
|
121
121
|
}
|
|
@@ -66,13 +66,13 @@ class GirafeResizableElement extends GirafeHTMLElement {
|
|
|
66
66
|
// If there is a configured minWidth or maxWidth, we have to take care of it
|
|
67
67
|
const css = getComputedStyle(this);
|
|
68
68
|
const minWidth = Number.parseFloat(css.minWidth);
|
|
69
|
-
this.minWidth = isNaN(minWidth) ? undefined : minWidth;
|
|
69
|
+
this.minWidth = Number.isNaN(minWidth) ? undefined : minWidth;
|
|
70
70
|
const maxWidth = Number.parseFloat(css.maxWidth);
|
|
71
|
-
this.maxWidth = isNaN(maxWidth) ? undefined : maxWidth;
|
|
71
|
+
this.maxWidth = Number.isNaN(maxWidth) ? undefined : maxWidth;
|
|
72
72
|
const minHeight = Number.parseFloat(css.minHeight);
|
|
73
|
-
this.minHeight = isNaN(minHeight) ? undefined : minHeight;
|
|
73
|
+
this.minHeight = Number.isNaN(minHeight) ? undefined : minHeight;
|
|
74
74
|
const maxHeight = Number.parseFloat(css.maxHeight);
|
|
75
|
-
this.maxHeight = isNaN(maxHeight) ? undefined : maxHeight;
|
|
75
|
+
this.maxHeight = Number.isNaN(maxHeight) ? undefined : maxHeight;
|
|
76
76
|
}
|
|
77
77
|
mousedown(e) {
|
|
78
78
|
e.preventDefault();
|
|
@@ -13,7 +13,7 @@ class BasemapComponent extends GirafeHTMLElement {
|
|
|
13
13
|
.basemap-button{background-color:var(--bkg-color);color:var(--text-color);border:var(--app-standard-border);box-sizing:border-box;cursor:pointer;box-shadow:var(--bx-shdw);border-width:2px;border-radius:4px;outline:0;margin:0;padding:5px;display:inline-flex}#container{flex-direction:column;width:max-content;display:inline-flex}.basemap-icon{background:var(--svg-legend-bkg);filter:var(--svg-map-filter)}.active-basemap{background-color:var(--bkg-color-grad2)!important}.opacity-slider{flex-direction:row;height:20px;padding:0 5px;display:flex}.opacity-slider img{height:16px;position:relative;top:2px}.opacity-slider input[type=range]{flex-grow:1}.basemap-container{flex-direction:column;display:flex}.basemap-container button{color:var(--text-color);background-color:#0000;border:none;flex-direction:row;flex-grow:1;display:flex}.basemap-container button img{height:2rem;margin:.3rem}.basemap-container button span{height:2rem;margin:.3rem;line-height:2rem}.basemap-container:hover{background-color:var(--bkg-color-grad1)}.basemaps-with-opacity-separator{border-top:1px solid var(--bkg-color-grad2);height:1px;margin:6px 8px}
|
|
14
14
|
</style>
|
|
15
15
|
<style>${this.customStyle}</style>
|
|
16
|
-
<girafe-menu-button direction="up-right" id="basemap-menu-button"><button slot="menu-button" class="basemap-button" tip="Select basemap"><img class="basemap-icon" alt="menu-icon" src="images/button_basemaps.webp"></button><div slot="menu-content" id="container">${Object.values(this.state.basemaps).filter(basemap => basemap.opacity == -1).map(basemap => uHtmlFor(basemap, basemap.id) `<div class="${this.determineClassnames(basemap)}"><button onclick="${() => this.changeBasemap(basemap)}"><img class="basemap-icon" alt="basemap-icon" src="${basemap.thumbnail}"> <span i18n="${basemap.name}">${basemap.name}</span></button></div>`)}<div class="basemaps-with-opacity-separator"></div>${Object.values(this.state.basemaps).filter(basemap => basemap.opacity != -1).map(basemap => uHtmlFor(basemap, basemap.id) `<div class="${this.determineClassnames(basemap)}"><button onclick="${() => this.changeBasemap(basemap)}"><img class="basemap-icon" alt="basemap-icon" src="${basemap.thumbnail}"> <span i18n="${basemap.name}">${basemap.name}</span></button><div class="opacity-slider"><img alt="Control opacity" src="icons/opacity.svg"> <input type="range" min="0" max="1" step="0.01" class="gg-range" value="${basemap.opacity}" onkeydown="${(e) => { e.preventDefault(); e.stopPropagation(); }}" onclick="${(e) => { e.preventDefault(); e.stopPropagation(); }}" onchange="${(e) => this.changeBasemapOpacity(basemap, e)}"></div></div>`)}</div></girafe-menu-button>
|
|
16
|
+
<girafe-menu-button direction="up-right" id="basemap-menu-button"><button slot="menu-button" class="basemap-button" tip="Select basemap"><img class="basemap-icon" alt="menu-icon" src="images/button_basemaps.webp"></button><div slot="menu-content" id="container">${Object.values(this.state.basemaps).filter(basemap => basemap.opacity == -1).map(basemap => uHtmlFor(basemap, basemap.id) `<div class="${this.determineClassnames(basemap)}"><button onclick="${() => this.changeBasemap(basemap)}"><img class="basemap-icon" alt="basemap-icon" src="${basemap.thumbnail}"> <span i18n="${basemap.name}">${basemap.name}</span></button></div>`)}<div class="basemaps-with-opacity-separator"></div>${Object.values(this.state.basemaps).filter(basemap => basemap.opacity != -1).map(basemap => uHtmlFor(basemap, basemap.id) `<div class="${this.determineClassnames(basemap)}"><button onclick="${() => this.changeBasemap(basemap)}"><img class="basemap-icon" alt="basemap-icon" src="${basemap.thumbnail}"> <span i18n="${basemap.name}">${basemap.name}</span></button><div class="opacity-slider"><img alt="Control opacity" src="icons/opacity.svg"> <input type="range" aria-label="Opacity" min="0" max="1" step="0.01" class="gg-range" value="${basemap.opacity}" onkeydown="${(e) => { e.preventDefault(); e.stopPropagation(); }}" onclick="${(e) => { e.preventDefault(); e.stopPropagation(); }}" onchange="${(e) => this.changeBasemapOpacity(basemap, e)}"></div></div>`)}</div></girafe-menu-button>
|
|
17
17
|
${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
18
18
|
};
|
|
19
19
|
constructor() {
|
|
@@ -23,7 +23,7 @@ class CrossSectionSettingsComponent extends GirafeHTMLElement {
|
|
|
23
23
|
.hidden{display:none!important}.gg-rotate90{transform:rotate(90deg)}.gg-rotate180{transform:rotate(180deg)}.gg-rotate270{transform:rotate(270deg)}img{filter:var(--svg-filter)}img.legend-image{filter:var(--svg-map-filter);background:var(--svg-legend-bkg)}div{scrollbar-width:thin}a,a:visited{color:var(--link-color)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes spin-wait{0%{transform:rotate(0)}7%{transform:rotate(360deg)}to{transform:rotate(360deg)}}.gg-spin{animation-name:spin;animation-duration:2s;animation-timing-function:linear;animation-iteration-count:infinite}.gg-spin-wait{animation-name:spin-wait;animation-duration:10s;animation-timing-function:linear;animation-iteration-count:infinite}::-webkit-scrollbar{width:5px}::-webkit-scrollbar-thumb{background:#999}button,input,select,textarea{font:inherit}.gg-button,.gg-select,.gg-input,.gg-textarea{background-color:var(--bkg-color);color:var(--text-color);border:var(--app-standard-border);box-sizing:border-box;cursor:pointer;border-radius:3px;outline:0;margin:0;padding:0 0 0 .5rem;display:inline-block}.gg-label{background-color:var(--bkg-color);color:var(--text-color);border:none;align-items:center;margin:0;padding:0;display:flex}.gg-button,.gg-select,.gg-input,.gg-label{min-height:calc(var(--app-standard-height) / 1.5)}.gg-textarea{max-height:initial;resize:vertical;height:6rem;padding:.5rem;line-height:1.3rem}.gg-input{cursor:text}.gg-checkbox{accent-color:var(--text-color);cursor:pointer;width:1.2rem}.gg-range{accent-color:var(--text-color)}.gg-button{padding:0 .5rem}.gg-button.active{border:solid 1px var(--text-color-grad1);background-color:var(--bkg-color-grad2)}.gg-button:disabled{background-color:var(--bkg-color-grad1);color:var(--text-color-grad2);cursor:not-allowed;border:none}.gg-button:disabled img{filter:opacity(.6)}.gg-input:disabled,.gg-select:disabled,.gg-textarea:disabled{background-color:var(--bkg-color-grad1);color:var(--text-color-grad2);cursor:not-allowed}.gg-button>img{vertical-align:middle}.gg-icon-button{color:var(--text-color);cursor:pointer;background-color:#0000;border:none;flex-direction:column;justify-content:center;align-items:center;padding:0;display:flex}.gg-icon{justify-content:center;align-items:center;display:flex}.gg-big,.gg-big-withtext{min-width:var(--app-standard-height);min-height:var(--app-standard-height);max-height:var(--app-standard-height)}.gg-big img,.gg-big-withtext img{width:calc(var(--app-standard-height) - 1.5rem);margin:0}.gg-big-withtext span{font-variant:small-caps;padding:0 1rem;font-size:.9rem}.gg-medium,.gg-medium-withtext{min-width:calc(var(--app-standard-height) / 1.2);min-height:calc(var(--app-standard-height) / 1.2);max-height:calc(var(--app-standard-height) / 1.2);flex-direction:row}.gg-medium img{width:calc(var(--app-standard-height) / 2.4);margin:0}.gg-medium-withtext img{width:calc(var(--app-standard-height) / 2.4);margin-left:.5rem}.gg-medium-withtext span{padding:0 1rem 0 .5rem;font-size:.9rem}.gg-small,.gg-small-withtext{min-width:calc(var(--app-standard-height) / 2);min-height:calc(var(--app-standard-height) / 2);max-height:calc(var(--app-standard-height) / 2);flex-direction:row}.gg-small img{width:calc(var(--app-standard-height) / 3);margin:0}.gg-small-withtext img{width:calc(var(--app-standard-height) / 3);margin-left:.5rem}.gg-small-withtext span{padding:0 .5rem 0 .3rem;font-size:.9rem}.gg-button:hover:not(:disabled),.gg-select:hover:not(:disabled),.gg-input:hover:not(:disabled),.gg-textarea:hover:not(:disabled),.gg-icon-button:hover:not(:disabled){background-color:var(--bkg-color-grad1)}.gg-opacity{opacity:.5}.gg-opacity:hover{opacity:1;background-color:#0000}.gg-tabs{cursor:pointer;grid-auto-flow:column;padding-bottom:1rem;font-size:1rem;display:grid}.gg-tab{border:none;border-bottom:var(--app-standard-border);cursor:pointer;color:var(--text-color);background:0 0;padding:.5rem}.gg-tab.active{border-bottom:solid 1px var(--text-color)}.girafe-button-big,.girafe-button-large,.girafe-button-small,.girafe-button-tiny{color:var(--text-color);background-color:#0000;border:none;flex-direction:column;display:flex}.girafe-button-big:hover,.girafe-button-large:hover,.girafe-button-small:hover,.girafe-button-tiny:hover{background-color:var(--bkg-color-grad1);cursor:pointer}.girafe-button-big.dark,.girafe-button-large.dark,.girafe-button-small.dark,.girafe-button-tiny.dark{background-color:var(--bkg-color);filter:invert()}.girafe-button-big{width:var(--app-standard-height);height:var(--app-standard-height);align-items:center;padding:1rem}.girafe-button-big img{overflow:hidden}.girafe-button-large{flex-direction:row}.girafe-button-large img{height:2rem;margin:.3rem}.girafe-button-large span{height:2rem;margin:.3rem;line-height:2rem}.girafe-button-small{min-width:calc(var(--app-standard-height) / 2);height:calc(var(--app-standard-height) / 2);align-items:center;padding:.5rem}.girafe-button-small img{overflow:hidden}.girafe-button-small span{text-align:left;text-overflow:ellipsis;width:100%;overflow:hidden}.girafe-button-tiny{align-items:center;width:1rem;height:1rem;padding:0}.girafe-button-tiny img{overflow:hidden}.girafe-onboarding-theme{background-color:var(--bkg-color)!important;color:var(--text-color)!important}.girafe-onboarding-theme button{background-color:var(--bkg-color)!important;color:var(--text-color)!important;text-shadow:none!important}.girafe-onboarding-theme button.driver-popover-close-btn{z-index:10000}.tippy-box{background-color:var(--bkg-color)!important;border:var(--app-standard-border)!important}.tippy-content{color:var(--text-color)!important}.tippy-arrow{color:var(--bkg-color)!important}.tippy-box[data-theme~=error]{background-color:var(--error-color);white-space:pre-line}div.tippy-box[data-theme=image-popup]{border:var(--app-standard-border)!important;& div.tippy-content{background-color:var(--bkg-color)!important;& img{max-width:20rem;max-height:20rem}}& div.tippy-arrow{color:var(--bkg-color)!important}}
|
|
24
24
|
</style>
|
|
25
25
|
<style>${this.customStyle}</style>
|
|
26
|
-
<div id="panel"><div id="content"><div class="btn-group-flex"><button id="draw-profile-btn" class="${this.crossSectionState.drawProfile ? 'gg-button active' : 'gg-button'}" tip="draw_profile_help" onclick="${() => this.toggleLineDraw()}" i18n="draw_profile">Draw</button> <button id="delete-profile-btn" class="gg-button" tip="delete_help" onclick="${() => this.deleteProfile()}" i18n="delete">Delete</button></div><div class="btn-group-flex"><label for="section-width-btn" i18n="profile_width" class="gg-label">Width [m]</label> <input id="section-width-btn" class="gg-input" type="number" value="${this.crossSectionState.sectionWidthSettings.value}" min="${this.crossSectionState.sectionWidthSettings.min}" max="${this.crossSectionState.sectionWidthSettings.max}" step="${this.crossSectionState.sectionWidthSettings.step}" onchange="${(e) => this.setSectionWidth(e.target.value)}"></div><div class="btn-group-flex"><button id="reset-zoom-btn" class="gg-button" tip="profile_reset_view_help" onclick="${() => this.resetZoom()}" i18n="profile_reset_view">Reset view</button> <button id="sync-views-btn" class="${this.crossSectionState.syncViews ? 'gg-button active' : 'gg-button'}" tip="profile_sync_view_help" onclick="${() => this.setViewSync(!this.crossSectionState.syncViews)}" i18n="profile_sync_view">Sync. views</button></div><div class="btn-group-flex"><button class="gg-icon-button gg-big" tip="profile_shift_up_help" onclick="${() => this.shiftLinestring([0.0, this.crossSectionState.linestringShift])}"><img src="icons/arrow_up.svg" alt="${this.context.i18nManager.getTranslation('profile_shift_up_help')}"></button> <button class="gg-icon-button gg-big" tip="profile_shift_down_help" onclick="${() => this.shiftLinestring([0.0, -this.crossSectionState.linestringShift])}"><img src="icons/arrow_down.svg" alt="${this.context.i18nManager.getTranslation('profile_shift_down_help')}"></button> <button class="gg-icon-button gg-big" tip="profile_shift_left_help" onclick="${() => this.shiftLinestring([-this.crossSectionState.linestringShift, 0.0])}"><img src="icons/arrow_left.svg" alt="${this.context.i18nManager.getTranslation('profile_shift_left_help')}"></button> <button class="gg-icon-button gg-big" tip="profile_shift_right_help" onclick="${() => this.shiftLinestring([this.crossSectionState.linestringShift, 0.0])}"><img src="icons/arrow_right.svg" alt="${this.context.i18nManager.getTranslation('profile_shift_right_help')}"></button></div><div class="btn-group-flex"><div class="cell"><label for="z-ratio-btn" class="gg-label">${this.context.i18nManager.getTranslation('profile_exaggeration')} (${this.crossSectionState.verticalExaggerationSettings.value})</label><div style="display: flex; align-items: center"><input id="z-ratio-btn" type="range" class="gg-range" min="${this.crossSectionState.verticalExaggerationSettings.min}" max="${this.crossSectionState.verticalExaggerationSettings.max}" step="${this.crossSectionState.verticalExaggerationSettings.step}" value="${this.crossSectionState.verticalExaggerationSettings.value}" oninput="${(e) => this.setVerticalExaggeration(parseFloat(e.target.value))}" style="flex: 1; min-width: 0; box-sizing: border-box"> <button id="z-ratio-reset-btn" class="reset-btn" tip="profile_exaggeration_reset_help" onclick="${() => this.setVerticalExaggeration(this.crossSectionState.verticalExaggerationSettings.default)}"><img src="icons/restart_alt.svg" alt="${this.context.i18nManager.getTranslation('profile_exaggeration_reset_help')}"></button></div></div></div><div class="btn-group-flex"><div class="cell"><label for="point-size-label" class="gg-label">${this.context.i18nManager.getTranslation('profile_point_size')} (${this.crossSectionState.pointSizeSettings.value})</label><div style="display: flex; align-items: center"><input id="point-size-btn" type="range" class="gg-range" min="${this.crossSectionState.pointSizeSettings.min}" max="${this.crossSectionState.pointSizeSettings.max}" step="${this.crossSectionState.pointSizeSettings.step}" value="${this.crossSectionState.pointSizeSettings.value}" oninput="${(e) => this.setPointSize(parseFloat(e.target.value))}" style="flex: 1; min-width: 0; box-sizing: border-box"> <button id="point-size-reset-btn" class="reset-btn" tip="profile_point_size_reset_help" onclick="${() => this.setPointSize(this.crossSectionState.pointSizeSettings.default)}"><img src="icons/restart_alt.svg" alt="${this.context.i18nManager.getTranslation('profile_point_size_reset_help')}"></button></div></div></div><div class="btn-group-flex"><label for="background-color-btn" i18n="profile_background_color" class="gg-label">Background color</label> <input id="background-color-btn" class="gg-input" type="color" value="${this.crossSectionState.backgroundColor}" oninput="${(e) => this.setBackgroundColor(e.target.value)}"></div><div class="btn-group-flex"><label for="sequential-color-btn" i18n="profile_colormap" class="gg-label">Colorscale</label> <select id="sequential-color-btn" class="gg-select" oninput="${(e) => this.setColorPalette(e.target.value)}"><option value="spectral" ?selected="${this.crossSectionState.colorPalette === 'spectral'}" i18n="palette_option_spectral">Spectral<option value="greys" ?selected="${this.crossSectionState.colorPalette === 'greys'}" i18n="palette_option_greys">Greys<option value="blues" ?selected="${this.crossSectionState.colorPalette === 'blues'}" i18n="palette_option_blues">Blues<option value="viridis" ?selected="${this.crossSectionState.colorPalette === 'viridis'}" i18n="palette_option_viridis">Viridis<option value="magma" ?selected="${this.crossSectionState.colorPalette === 'magma'}" i18n="palette_option_magma">Magma</select></div><div class="option"><label for="grid-btn" i18n="profile_toggle_grid" class="gg-label">Show grid</label> <input id="grid-btn" class="gg-checkbox" ?checked="${this.crossSectionState.gridVisible}" type="checkbox" onchange="${(e) => this.setGridVisibility(e.target.checked)}"></div><h3 i18n="profile_pointcloud">Pointclouds</h3><div class="btn-group-flex loader-progress"><div class="progress-wrapper" tip="profile_load_indicator_help"><progress id="load-progress" class="gg-progress" value="${this.crossSectionState.numberOfPoints}" max="${this.crossSectionState.maxNumberOfPoints}"></progress> <span class="progress-label">${(this.crossSectionState.loading) ? uHtml `<img src="icons/progress.svg" alt="Loading" class="gg-spin gg-small progress-icon">` : uHtml ``} ${this.crossSectionState.numberOfPoints} / ${this.crossSectionState.maxNumberOfPoints}</span></div></div><div>${this.crossSectionState.datasets.map(f => uHtml `<div class="dataset-row"><input type="checkbox" id="${f.id}" class="gg-checkbox" ?checked="${f.active}" onchange="${() => this.toggleVisibility(f.id)}"> <span class="dataset-name" i18n="${f.id}">${f.id}</span> <select class="gg-select" oninput="${(e) => this.setColorVariable(f.id, e.target.value)}"><option value="uniform" ?selected="${f.colorby === 'uniform'}" i18n="color_option_uniform">Uniform<option value="natural" ?selected="${f.colorby === 'natural'}" i18n="color_option_natural">Natural<option value="intensity" ?selected="${f.colorby === 'intensity'}" i18n="color_option_intensity">Intensity<option value="classification" ?selected="${f.colorby === 'classification'}" i18n="color_option_classification">Classification</select> <input id="uniform-color-btn" type="color" value="${f.color}" oninput="${(e) => this.setColor(f.id, e.target.value)}"></div>`)}</div><h3 i18n="profile_measure_and_annotate">Measurements and annotations</h3><div class="btn-group-flex"><button id="draw-measurements-btn" class="${this.crossSectionState.drawMeasurement ? 'gg-button active' : 'gg-button'}" tip="profile_measurement_help" onclick="${() => this.toggleMeasureDraw()}" i18n="profile_measurement" ?disabled="${!this.crossSectionState.enableMeasurement}">Measure</button> <button id="delete-measurements-btn" class="gg-button" tip="profile_delete_measurements_help" onclick="${() => this.deleteAllMeasurements()}" i18n="profile_delete_measurements">Delete all</button></div><div class="scrollable-table-container"><table id="measurements-table" class="scrollable-table"><thead><tr><th class="table-cell sticky-header" style="text-align: center"><th class="table-cell sticky-header" style="text-align: right" i18n="profile_table_dist">DIST.<th class="table-cell sticky-header" style="text-align: right" i18n="profile_table_slope">SLOPE.<th class="table-cell sticky-header" style="text-align: center"><tbody></table></div><div class="btn-group-flex"><button id="draw-markers-btn" class="${this.crossSectionState.drawMarker ? 'gg-button active' : 'gg-button'}" tip="profile_draw_markers_help" onclick="${() => this.toggleMarkerDraw()}" i18n="profile_draw_markers" ?disabled="${!this.crossSectionState.enableAnnotation}">Annotate</button> <button id="delete-markers-btn" class="gg-button" tip="profile_delete_markers_help" onclick="${() => this.deleteAllMarkers()}" i18n="profile_delete_markers">Delete all</button></div><div class="scrollable-table-container"><table id="markers-table" class="scrollable-table"><thead><tr><th class="sticky-header" style="text-align: center" i18n="profile_table_id">ID<th class="sticky-header" style="text-align: right" i18n="profile_table_coord">COORD.<th class="sticky-header" style="text-align: center"><th class="sticky-header" style="text-align: center"><th class="sticky-header" style="text-align: center"><tbody></table></div><h3 i18n="profile_print_title">Print</h3><div class="btn-group-flex"><select id="print-profile-format-btn" class="gg-select" oninput="${(e) => this.setPrintFileFormat(e.target.value)}"><option value="svg" i18n="SVG">SVG</select> <button id="print-profile-btn" class="gg-button" tip="profile_print_help" onclick="${() => this.printPlot(this.crossSectionState.printFileFormat)}" i18n="profile_print">Print</button></div><h3 i18n="profile_download_title">Downloads</h3><div class="text-label" i18n="profile_markers_download">Markers</div><div class="btn-group-flex"><select id="download-markers-format-btn" class="gg-select" oninput="${(e) => this.setAnnotationsFileFormat(e.target.value)}"><option value="kml" i18n="KML">KML<option value="geojson" i18n="GeoJSON">GeoJSON<option value="gpx" i18n="GPX">GPX</select> <button id="download-markers-btn" class="gg-button" tip="download_help" onclick="${() => this.exportFeature(this.points, 'markers', this.crossSectionState.downloadAnnotationsFormat)}" i18n="download" ?disabled="${!this.crossSectionState.enableAnnotationsDownload}">Download</button></div><div class="text-label" i18n="profile_linestring_download">Profile line</div><div class="btn-group-flex"><select id="download-linestring-format-btn" class="gg-select" oninput="${(e) => this.setLineFileFormat(e.target.value)}"><option value="kml" i18n="KML">KML<option value="geojson" i18n="GeoJSON">GeoJSON<option value="gpx" i18n="GPX">GPX</select> <button id="download-linestring-btn" class="gg-button" tip="download_help" onclick="${() => this.exportFeature([this.linestring], 'linestring', this.crossSectionState.downloadLinestringFormat)}" i18n="download" ?disabled="${!this.crossSectionState.enableLinestringDownload}">Download</button></div></div></div>
|
|
26
|
+
<div id="panel"><div id="content"><div class="btn-group-flex"><button id="draw-profile-btn" class="${this.crossSectionState.drawProfile ? 'gg-button active' : 'gg-button'}" tip="draw_profile_help" onclick="${() => this.toggleLineDraw()}" i18n="draw_profile">Draw</button> <button id="delete-profile-btn" class="gg-button" tip="delete_help" onclick="${() => this.deleteProfile()}" i18n="delete">Delete</button></div><div class="btn-group-flex"><label for="section-width-btn" i18n="profile_width" class="gg-label">Width [m]</label> <input id="section-width-btn" class="gg-input" type="number" value="${this.crossSectionState.sectionWidthSettings.value}" min="${this.crossSectionState.sectionWidthSettings.min}" max="${this.crossSectionState.sectionWidthSettings.max}" step="${this.crossSectionState.sectionWidthSettings.step}" onchange="${(e) => this.setSectionWidth(e.target.value)}"></div><div class="btn-group-flex"><button id="reset-zoom-btn" class="gg-button" tip="profile_reset_view_help" onclick="${() => this.resetZoom()}" i18n="profile_reset_view">Reset view</button> <button id="sync-views-btn" class="${this.crossSectionState.syncViews ? 'gg-button active' : 'gg-button'}" tip="profile_sync_view_help" onclick="${() => this.setViewSync(!this.crossSectionState.syncViews)}" i18n="profile_sync_view">Sync. views</button></div><div class="btn-group-flex"><button class="gg-icon-button gg-big" tip="profile_shift_up_help" onclick="${() => this.shiftLinestring([0.0, this.crossSectionState.linestringShift])}"><img src="icons/arrow_up.svg" alt="${this.context.i18nManager.getTranslation('profile_shift_up_help')}"></button> <button class="gg-icon-button gg-big" tip="profile_shift_down_help" onclick="${() => this.shiftLinestring([0.0, -this.crossSectionState.linestringShift])}"><img src="icons/arrow_down.svg" alt="${this.context.i18nManager.getTranslation('profile_shift_down_help')}"></button> <button class="gg-icon-button gg-big" tip="profile_shift_left_help" onclick="${() => this.shiftLinestring([-this.crossSectionState.linestringShift, 0.0])}"><img src="icons/arrow_left.svg" alt="${this.context.i18nManager.getTranslation('profile_shift_left_help')}"></button> <button class="gg-icon-button gg-big" tip="profile_shift_right_help" onclick="${() => this.shiftLinestring([this.crossSectionState.linestringShift, 0.0])}"><img src="icons/arrow_right.svg" alt="${this.context.i18nManager.getTranslation('profile_shift_right_help')}"></button></div><div class="btn-group-flex"><div class="cell"><label for="z-ratio-btn" class="gg-label">${this.context.i18nManager.getTranslation('profile_exaggeration')} (${this.crossSectionState.verticalExaggerationSettings.value})</label><div style="display: flex; align-items: center"><input id="z-ratio-btn" type="range" class="gg-range" min="${this.crossSectionState.verticalExaggerationSettings.min}" max="${this.crossSectionState.verticalExaggerationSettings.max}" step="${this.crossSectionState.verticalExaggerationSettings.step}" value="${this.crossSectionState.verticalExaggerationSettings.value}" oninput="${(e) => this.setVerticalExaggeration(Number.parseFloat(e.target.value))}" style="flex: 1; min-width: 0; box-sizing: border-box"> <button id="z-ratio-reset-btn" class="reset-btn" tip="profile_exaggeration_reset_help" onclick="${() => this.setVerticalExaggeration(this.crossSectionState.verticalExaggerationSettings.default)}"><img src="icons/restart_alt.svg" alt="${this.context.i18nManager.getTranslation('profile_exaggeration_reset_help')}"></button></div></div></div><div class="btn-group-flex"><div class="cell"><label for="point-size-btn" class="gg-label">${this.context.i18nManager.getTranslation('profile_point_size')} (${this.crossSectionState.pointSizeSettings.value})</label><div style="display: flex; align-items: center"><input id="point-size-btn" type="range" class="gg-range" min="${this.crossSectionState.pointSizeSettings.min}" max="${this.crossSectionState.pointSizeSettings.max}" step="${this.crossSectionState.pointSizeSettings.step}" value="${this.crossSectionState.pointSizeSettings.value}" oninput="${(e) => this.setPointSize(Number.parseFloat(e.target.value))}" style="flex: 1; min-width: 0; box-sizing: border-box"> <button id="point-size-reset-btn" class="reset-btn" tip="profile_point_size_reset_help" onclick="${() => this.setPointSize(this.crossSectionState.pointSizeSettings.default)}"><img src="icons/restart_alt.svg" alt="${this.context.i18nManager.getTranslation('profile_point_size_reset_help')}"></button></div></div></div><div class="btn-group-flex"><label for="background-color-btn" i18n="profile_background_color" class="gg-label">Background color</label> <input id="background-color-btn" class="gg-input" type="color" value="${this.crossSectionState.backgroundColor}" oninput="${(e) => this.setBackgroundColor(e.target.value)}"></div><div class="btn-group-flex"><label for="sequential-color-btn" i18n="profile_colormap" class="gg-label">Colorscale</label> <select id="sequential-color-btn" class="gg-select" oninput="${(e) => this.setColorPalette(e.target.value)}"><option value="spectral" ?selected="${this.crossSectionState.colorPalette === 'spectral'}" i18n="palette_option_spectral">Spectral<option value="greys" ?selected="${this.crossSectionState.colorPalette === 'greys'}" i18n="palette_option_greys">Greys<option value="blues" ?selected="${this.crossSectionState.colorPalette === 'blues'}" i18n="palette_option_blues">Blues<option value="viridis" ?selected="${this.crossSectionState.colorPalette === 'viridis'}" i18n="palette_option_viridis">Viridis<option value="magma" ?selected="${this.crossSectionState.colorPalette === 'magma'}" i18n="palette_option_magma">Magma</select></div><div class="option"><label for="grid-btn" i18n="profile_toggle_grid" class="gg-label">Show grid</label> <input id="grid-btn" class="gg-checkbox" ?checked="${this.crossSectionState.gridVisible}" type="checkbox" onchange="${(e) => this.setGridVisibility(e.target.checked)}"></div><h3 i18n="profile_pointcloud">Pointclouds</h3><div class="btn-group-flex loader-progress"><div class="progress-wrapper" tip="profile_load_indicator_help"><progress id="load-progress" class="gg-progress" value="${this.crossSectionState.numberOfPoints}" max="${this.crossSectionState.maxNumberOfPoints}"></progress> <span class="progress-label">${(this.crossSectionState.loading) ? uHtml `<img src="icons/progress.svg" alt="Loading" class="gg-spin gg-small progress-icon">` : uHtml ``} ${this.crossSectionState.numberOfPoints} / ${this.crossSectionState.maxNumberOfPoints}</span></div></div><div>${this.crossSectionState.datasets.map(f => uHtml `<div class="dataset-row"><input type="checkbox" id="${f.id}" class="gg-checkbox" aria-label="Dataset ${f.id}" ?checked="${f.active}" onchange="${() => this.toggleVisibility(f.id)}"> <span class="dataset-name" i18n="${f.id}">${f.id}</span> <select class="gg-select" aria-label="Color variable" oninput="${(e) => this.setColorVariable(f.id, e.target.value)}"><option value="uniform" ?selected="${f.colorby === 'uniform'}" i18n="color_option_uniform">Uniform<option value="natural" ?selected="${f.colorby === 'natural'}" i18n="color_option_natural">Natural<option value="intensity" ?selected="${f.colorby === 'intensity'}" i18n="color_option_intensity">Intensity<option value="classification" ?selected="${f.colorby === 'classification'}" i18n="color_option_classification">Classification</select> <input id="uniform-color-btn" type="color" aria-label="Uniform color" value="${f.color}" oninput="${(e) => this.setColor(f.id, e.target.value)}"></div>`)}</div><h3 i18n="profile_measure_and_annotate">Measurements and annotations</h3><div class="btn-group-flex"><button id="draw-measurements-btn" class="${this.crossSectionState.drawMeasurement ? 'gg-button active' : 'gg-button'}" tip="profile_measurement_help" onclick="${() => this.toggleMeasureDraw()}" i18n="profile_measurement" ?disabled="${!this.crossSectionState.enableMeasurement}">Measure</button> <button id="delete-measurements-btn" class="gg-button" tip="profile_delete_measurements_help" onclick="${() => this.deleteAllMeasurements()}" i18n="profile_delete_measurements">Delete all</button></div><div class="scrollable-table-container"><table id="measurements-table" class="scrollable-table"><thead><tr><th class="table-cell sticky-header" style="text-align: center"><th class="table-cell sticky-header" style="text-align: right" i18n="profile_table_dist">DIST.<th class="table-cell sticky-header" style="text-align: right" i18n="profile_table_slope">SLOPE.<th class="table-cell sticky-header" style="text-align: center"><tbody></table></div><div class="btn-group-flex"><button id="draw-markers-btn" class="${this.crossSectionState.drawMarker ? 'gg-button active' : 'gg-button'}" tip="profile_draw_markers_help" onclick="${() => this.toggleMarkerDraw()}" i18n="profile_draw_markers" ?disabled="${!this.crossSectionState.enableAnnotation}">Annotate</button> <button id="delete-markers-btn" class="gg-button" tip="profile_delete_markers_help" onclick="${() => this.deleteAllMarkers()}" i18n="profile_delete_markers">Delete all</button></div><div class="scrollable-table-container"><table id="markers-table" class="scrollable-table"><thead><tr><th class="sticky-header" style="text-align: center" i18n="profile_table_id">ID<th class="sticky-header" style="text-align: right" i18n="profile_table_coord">COORD.<th class="sticky-header" style="text-align: center"><th class="sticky-header" style="text-align: center"><th class="sticky-header" style="text-align: center"><tbody></table></div><h3 i18n="profile_print_title">Print</h3><div class="btn-group-flex"><select id="print-profile-format-btn" class="gg-select" aria-label="Print format" oninput="${(e) => this.setPrintFileFormat(e.target.value)}"><option value="svg" i18n="SVG">SVG</select> <button id="print-profile-btn" class="gg-button" tip="profile_print_help" onclick="${() => this.printPlot(this.crossSectionState.printFileFormat)}" i18n="profile_print">Print</button></div><h3 i18n="profile_download_title">Downloads</h3><div class="text-label" i18n="profile_markers_download">Markers</div><div class="btn-group-flex"><select id="download-markers-format-btn" class="gg-select" aria-label="Markers format" oninput="${(e) => this.setAnnotationsFileFormat(e.target.value)}"><option value="kml" i18n="KML">KML<option value="geojson" i18n="GeoJSON">GeoJSON<option value="gpx" i18n="GPX">GPX</select> <button id="download-markers-btn" class="gg-button" tip="download_help" onclick="${() => this.exportFeature(this.points, 'markers', this.crossSectionState.downloadAnnotationsFormat)}" i18n="download" ?disabled="${!this.crossSectionState.enableAnnotationsDownload}">Download</button></div><div class="text-label" i18n="profile_linestring_download">Profile line</div><div class="btn-group-flex"><select id="download-linestring-format-btn" class="gg-select" aria-label="Profile line format" oninput="${(e) => this.setLineFileFormat(e.target.value)}"><option value="kml" i18n="KML">KML<option value="geojson" i18n="GeoJSON">GeoJSON<option value="gpx" i18n="GPX">GPX</select> <button id="download-linestring-btn" class="gg-button" tip="download_help" onclick="${() => this.exportFeature([this.linestring], 'linestring', this.crossSectionState.downloadLinestringFormat)}" i18n="download" ?disabled="${!this.crossSectionState.enableLinestringDownload}">Download</button></div></div></div>
|
|
27
27
|
${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
28
28
|
};
|
|
29
29
|
crossSectionState;
|
|
@@ -1028,7 +1028,7 @@ export class Scatterplot {
|
|
|
1028
1028
|
}
|
|
1029
1029
|
generateId(markers) {
|
|
1030
1030
|
let id = 1;
|
|
1031
|
-
const existingIds = new Set(markers.map((marker) => parseInt(marker.label)));
|
|
1031
|
+
const existingIds = new Set(markers.map((marker) => Number.parseInt(marker.label)));
|
|
1032
1032
|
while (existingIds.has(id)) {
|
|
1033
1033
|
id++;
|
|
1034
1034
|
}
|
|
@@ -18,7 +18,7 @@ input{border:1px solid var(--bkg-color-grad1);width:inherit;background-color:var
|
|
|
18
18
|
button.selected{background-color:#daebff!important;border:1px solid #54a4ff!important}#toolbar{box-sizing:border-box;grid-template-columns:repeat(5,1fr);gap:20px;width:100%;display:grid}#toolbar>button{box-sizing:border-box;filter:drop-shadow(0 4px 7px #0004382c);background-color:#fff;border-radius:8px;padding:10px}#toolbar>button>img{opacity:.7;width:100%}.icon{width:1.5rem;height:1.5rem}.gg-icon-button:hover{background-color:#0000}#panel{font-size:1.5em}#drawingList{gap:10px}#drawingList .girafe{filter:drop-shadow(0 4px 7px #0004381c);background:#fff;border:none;border-radius:8px;padding:10px}#optionsTitle{text-align:center;filter:drop-shadow(0 4px 7px #0004381c);color:#4553ff;border-radius:8px;width:100%;margin-bottom:20px;padding:10px;font-size:1.6rem}.gg-input:hover{filter:drop-shadow(0 4px 7px #4c58ff70);background-color:#fff}#optionsColorLine{flex-direction:column;display:flex}#optionsColorLine>div{text-align:end;width:100%}.selectable-label{font-size:1.3em}#optionsNameFontSize,#optionsMeasuresFontSize,#optionsStrokeWidth,#line-style,#arrow-style,#arrow-position{text-align:right;border:1px solid #e3e3e3;padding:1px;font-size:1em}.popup.popup_top{translate:15px -15px}#optionsExportLine{display:none}
|
|
19
19
|
</style>
|
|
20
20
|
<style>${this.customStyle}</style>
|
|
21
|
-
<div id="panel"><div><div id="toolbar"><button id="disable" tip="Disable drawing" class="gg-icon-button gg-medium"><img alt="select icon" src="icons/arrow.svg"></button> <button id="point" tip="Point" class="gg-icon-button gg-medium"><img alt="point icon" src="icons/point.svg"></button> <button id="line" tip="Line" class="gg-icon-button gg-medium"><img alt="polyline icon" src="icons/polyline.svg"></button> <button id="polygon" tip="Polygon" class="gg-icon-button gg-medium"><img alt="polygon icon" src="icons/polygon.svg"></button> <button id="square" tip="Square" class="gg-icon-button gg-medium"><img alt="square icon" src="icons/square.svg"></button> <button id="rectangle" tip="Rectangle" class="gg-icon-button gg-medium"><img alt="rectangle icon" src="icons/rectangle.svg"></button> <button id="circle" tip="Circle" class="gg-icon-button gg-medium"><img alt="circle icon" src="icons/circle.svg"></button> <button id="freeline" tip="Freehand line" class="gg-icon-button gg-medium"><img alt="polyline-free icon" src="icons/polyline-free.svg"></button> <button id="freepolygon" tip="Freehand polygon" class="gg-icon-button gg-medium"><img alt="polygon-free icon" src="icons/polygon-free.svg"></button> <button id="text" tip="Text" class="gg-icon-button gg-medium"><img alt="text icon" src="icons/text-font.svg"></button></div><div id="toolParametersContainer"><span i18n="Settings" class="title"></span><div class="toolParameters" data-tool="Polyline,Polygon"><girafe-fixed-dimension dimensionname="length" dimension="length" id="fixedLineLength" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension></div><div class="toolParameters" data-tool="Square"><girafe-fixed-dimension dimensionname="side length" dimension="side" id="fixedSquareSide" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension></div><div class="toolParameters" data-tool="Rectangle"><girafe-fixed-dimension dimensionname="width" dimension="width" id="fixedRectangleWidth" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension><girafe-fixed-dimension dimensionname="height" dimension="height" id="fixedRectangleHeight" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension></div><div class="toolParameters" data-tool="Text"><label class="gg-label" for="drawingText" i18n="Text to draw">Text to draw</label> <input id="drawingText" class="gg-input" value="${this.drawingText}" oninput="${(e) => this.drawingTextChangedHandler(e)}"></div></div></div><div id="drawingListContainer"><div class="titleContainer"><span i18n="Drawing List" class="title"></span> <button class="gg-icon-button icon" tip="Delete all shapes" onclick="${() => this.deleteAllFeatures()}" ?disabled="${this.drawingState.features.length === 0}">${this.htmlUnsafe(this.trashIcon)}</button></div><div id="drawingList">${this.drawingState.features.map(feature => uHtmlFor(feature, feature.id) `<div id="${'f-' + feature.id}" class="girafe"><button id="${'f-select-' + feature.id}" class="gg-icon-button gg-small" tip="Select to change appearance" onclick="${() => this.onToggleFeatureSelection(feature)}"><div class="icon">${this.htmlUnsafe(feature.selected ? this.checkedIcon : this.noCheckedIcon)}</div></button><div class="label-container"><button class="${feature.selected ? 'selectable-label gg-icon-button gg-small gg-selected' : 'selectable-label gg-icon-button gg-small gg-opacity'}" onclick="${() => this.onToggleFeatureSelection(feature)}"><span id="${'f-name-' + feature.id}">${feature.name}</span></button></div><button class="gg-icon-button icon" tip="Center on shape" onclick="${() => this.olDrawing.centerViewOnFeature(feature)}">${this.htmlUnsafe(this.locateIcon)}</button> <button class="gg-icon-button icon" tip="Delete shape" onclick="${() => this.deleteFeature(feature)}">${this.htmlUnsafe(this.trashIcon)}</button></div>`)}</div></div><div id="options" class="${this.selectedFeatures.length > 0 ? '' : 'disabled'}"><fieldset class="field-wrapper" disabled="${this.selectedFeatures.length <= 0}"><input id="optionsTitle" value="${this.getOptionsTitle()}" class="gg-input" disabled="${this.selectedFeatures.length > 1}"><div id="optionsText"><div id="optionsTextLines"><span class="label first" i18n="Name">Name</span> <button class="gg-icon-button icon" id="visibleIconName" tip="Show or hide shape name" onclick="${() => this.toggleNameVisibility()}">${this.htmlUnsafe(this.isDisplayNameEnabled() ? this.visibleIcon : this.notVisibleIcon)}</button> <span class="label" i18n="Font">Font</span> <input id="optionsNameFontSize" class="gg-input" type="number" min="1" value="${this.selectedFeatures[0]?.nameFontSize}" oninput="${() => this.onOptionsChange()}"> <span class="unit">pt</span> <button class="icon colorPicker" id="nameColorPicker"></button> <span class="${this.isMeasureInformationEnabled() ? 'label first' : 'label first disabled'}" i18n="Measures">Measures</span> <select id="measure-information" class="gg-select" tip="${this.measureInformationTooltip}" disabled="${!this.isMeasureInformationEnabled()}" onchange="${() => this.onOptionsChange()}">${Object.entries(this.measureInformations).map((entry) => uHtml `<option selected="${this.selectedFeatureMeasureInformation === entry[0]}" value="${entry[0]}"><span i18n="${entry[1]}">${entry[0]}</span></option>`)}</select> <span class="${this.isMeasureInformationEnabled() ? 'label' : 'label disabled'}" i18n="Font">Font</span> <input id="optionsMeasuresFontSize" class="gg-input" type="number" min="1" value="${this.selectedFeatures[0]?.measureFontSize}" disabled="${!this.isMeasureInformationEnabled()}" oninput="${() => this.onOptionsChange()}"> <span class="${this.isMeasureInformationEnabled() ? 'unit' : 'unit disabled'}">pt</span> <button class="icon colorPicker" id="measureColorPicker" disabled="${!this.isMeasureInformationEnabled()}"></button></div></div><hr><div id="optionsColor"><div id="optionsColorLine"><div><span class="${this.isStrokeColorEnabled() ? 'text-end' : 'text-end disabled'}" i18n="Stroke color">Stroke color</span> <button class="icon colorPicker" disabled="${!this.isStrokeColorEnabled()}" id="strokePicker"></button></div><div><span class="${this.isFillColorEnabled() ? 'text-end' : 'text-end disabled'}" id="fillPickerSpan" i18n="Fill color">Fill color</span> <button class="icon colorPicker" disabled="${!this.isFillColorEnabled()}" id="fillPicker"></button></div></div></div><hr><div id="optionsLine"><div class="${this.isLineStyleEnabled() ? '' : 'disabled'}" id="optionsLineLines"><span i18n="Line width">Line width</span> <input id="optionsStrokeWidth" type="number" class="gg-input" min="1" value="${this.selectedFeatures[0]?.strokeWidth}" oninput="${() => this.onOptionsChange()}"> <span class="unit">px</span> <select id="line-style" class="gg-select" onchange="${() => this.onOptionsChange()}">${Object.entries(this.lineStyles).map((entry) => uHtml `<option selected="${this.selectedFeatures[0]?.lineStroke === entry[0]}" value="${entry[0]}"><span>${entry[1]}</span></option>`)}</select></div></div><hr><div id="optionsArrow"><div class="${this.isLineArrowEnabled() ? '' : 'disabled'}" id="optionsArrowStyles"><span i18n="Arrows style">Arrows style</span> <select id="arrow-style" class="gg-select" onchange="${() => this.onArrowsChange()}">${Object.entries(this.arrowStyles).map((entry) => uHtml `<option selected="${this.selectedFeatures[0]?.arrowStyle === entry[0]}" value="${entry[0]}"><span>${entry[1]}</span></option>`)}</select> <select id="arrow-position" class="gg-select" onchange="${() => this.onArrowsChange()}">${Object.entries(this.arrowPositions).map((entry) => uHtml `<option selected="${this.selectedFeatures[0]?.arrowPosition === entry[0]}" value="${entry[0]}"><span>${entry[1]}</span></option>`)}</select></div></div><hr><div id="optionsExport"><div id="optionsExportLine"><label for="export" class="gg-label" i18n="Export">Export</label> <button class="gg-button" onclick="${() => this.exportSelectedFeatures('geojson')}">GeoJson</button> <button class="gg-button" onclick="${() => this.exportSelectedFeatures('kml')}">KML</button> <button class="gg-button" onclick="${() => this.exportSelectedFeatures('gpx')}">GPX</button></div></div></fieldset></div></div>
|
|
21
|
+
<div id="panel"><div><div id="toolbar"><button id="disable" tip="Disable drawing" class="gg-icon-button gg-medium"><img alt="select icon" src="icons/arrow.svg"></button> <button id="point" tip="Point" class="gg-icon-button gg-medium"><img alt="point icon" src="icons/point.svg"></button> <button id="line" tip="Line" class="gg-icon-button gg-medium"><img alt="polyline icon" src="icons/polyline.svg"></button> <button id="polygon" tip="Polygon" class="gg-icon-button gg-medium"><img alt="polygon icon" src="icons/polygon.svg"></button> <button id="square" tip="Square" class="gg-icon-button gg-medium"><img alt="square icon" src="icons/square.svg"></button> <button id="rectangle" tip="Rectangle" class="gg-icon-button gg-medium"><img alt="rectangle icon" src="icons/rectangle.svg"></button> <button id="circle" tip="Circle" class="gg-icon-button gg-medium"><img alt="circle icon" src="icons/circle.svg"></button> <button id="freeline" tip="Freehand line" class="gg-icon-button gg-medium"><img alt="polyline-free icon" src="icons/polyline-free.svg"></button> <button id="freepolygon" tip="Freehand polygon" class="gg-icon-button gg-medium"><img alt="polygon-free icon" src="icons/polygon-free.svg"></button> <button id="text" tip="Text" class="gg-icon-button gg-medium"><img alt="text icon" src="icons/text-font.svg"></button></div><div id="toolParametersContainer"><span i18n="Settings" class="title"></span><div class="toolParameters" data-tool="Polyline,Polygon"><girafe-fixed-dimension dimensionname="length" dimension="length" id="fixedLineLength" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension></div><div class="toolParameters" data-tool="Square"><girafe-fixed-dimension dimensionname="side length" dimension="side" id="fixedSquareSide" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension></div><div class="toolParameters" data-tool="Rectangle"><girafe-fixed-dimension dimensionname="width" dimension="width" id="fixedRectangleWidth" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension><girafe-fixed-dimension dimensionname="height" dimension="height" id="fixedRectangleHeight" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension></div><div class="toolParameters" data-tool="Text"><label class="gg-label" for="drawingText" i18n="Text to draw">Text to draw</label> <input id="drawingText" class="gg-input" value="${this.drawingText}" oninput="${(e) => this.drawingTextChangedHandler(e)}"></div></div></div><div id="drawingListContainer"><div class="titleContainer"><span i18n="Drawing List" class="title"></span> <button class="gg-icon-button icon" tip="Delete all shapes" onclick="${() => this.deleteAllFeatures()}" ?disabled="${this.drawingState.features.length === 0}">${this.htmlUnsafe(this.trashIcon)}</button></div><div id="drawingList">${this.drawingState.features.map(feature => uHtmlFor(feature, feature.id) `<div id="${'f-' + feature.id}" class="girafe"><button id="${'f-select-' + feature.id}" class="gg-icon-button gg-small" tip="Select to change appearance" onclick="${() => this.onToggleFeatureSelection(feature)}"><div class="icon">${this.htmlUnsafe(feature.selected ? this.checkedIcon : this.noCheckedIcon)}</div></button><div class="label-container"><button class="${feature.selected ? 'selectable-label gg-icon-button gg-small gg-selected' : 'selectable-label gg-icon-button gg-small gg-opacity'}" onclick="${() => this.onToggleFeatureSelection(feature)}"><span id="${'f-name-' + feature.id}">${feature.name}</span></button></div><button class="gg-icon-button icon" tip="Center on shape" onclick="${() => this.olDrawing.centerViewOnFeature(feature)}">${this.htmlUnsafe(this.locateIcon)}</button> <button class="gg-icon-button icon" tip="Delete shape" onclick="${() => this.deleteFeature(feature)}">${this.htmlUnsafe(this.trashIcon)}</button></div>`)}</div></div><div id="options" class="${this.selectedFeatures.length > 0 ? '' : 'disabled'}"><fieldset class="field-wrapper" disabled="${this.selectedFeatures.length <= 0}"><input id="optionsTitle" aria-label="Title" value="${this.getOptionsTitle()}" class="gg-input" disabled="${this.selectedFeatures.length > 1}"><div id="optionsText"><div id="optionsTextLines"><span class="label first" i18n="Name">Name</span> <button class="gg-icon-button icon" id="visibleIconName" tip="Show or hide shape name" onclick="${() => this.toggleNameVisibility()}">${this.htmlUnsafe(this.isDisplayNameEnabled() ? this.visibleIcon : this.notVisibleIcon)}</button> <span class="label" i18n="Font">Font</span> <input id="optionsNameFontSize" class="gg-input" type="number" aria-label="Name font size" min="1" value="${this.selectedFeatures[0]?.nameFontSize}" oninput="${() => this.onOptionsChange()}"> <span class="unit">pt</span> <button class="icon colorPicker" id="nameColorPicker"></button> <span class="${this.isMeasureInformationEnabled() ? 'label first' : 'label first disabled'}" i18n="Measures">Measures</span> <select id="measure-information" class="gg-select" aria-label="Measures information" tip="${this.measureInformationTooltip}" disabled="${!this.isMeasureInformationEnabled()}" onchange="${() => this.onOptionsChange()}">${Object.entries(this.measureInformations).map((entry) => uHtml `<option selected="${this.selectedFeatureMeasureInformation === entry[0]}" value="${entry[0]}"><span i18n="${entry[1]}">${entry[0]}</span></option>`)}</select> <span class="${this.isMeasureInformationEnabled() ? 'label' : 'label disabled'}" i18n="Font">Font</span> <input id="optionsMeasuresFontSize" class="gg-input" type="number" aria-label="Measures font size" min="1" value="${this.selectedFeatures[0]?.measureFontSize}" disabled="${!this.isMeasureInformationEnabled()}" oninput="${() => this.onOptionsChange()}"> <span class="${this.isMeasureInformationEnabled() ? 'unit' : 'unit disabled'}">pt</span> <button class="icon colorPicker" id="measureColorPicker" disabled="${!this.isMeasureInformationEnabled()}"></button></div></div><hr><div id="optionsColor"><div id="optionsColorLine"><div><span class="${this.isStrokeColorEnabled() ? 'text-end' : 'text-end disabled'}" i18n="Stroke color">Stroke color</span> <button class="icon colorPicker" disabled="${!this.isStrokeColorEnabled()}" id="strokePicker"></button></div><div><span class="${this.isFillColorEnabled() ? 'text-end' : 'text-end disabled'}" id="fillPickerSpan" i18n="Fill color">Fill color</span> <button class="icon colorPicker" disabled="${!this.isFillColorEnabled()}" id="fillPicker"></button></div></div></div><hr><div id="optionsLine"><div class="${this.isLineStyleEnabled() ? '' : 'disabled'}" id="optionsLineLines"><span i18n="Line width">Line width</span> <input id="optionsStrokeWidth" type="number" aria-label="Line width" class="gg-input" min="1" value="${this.selectedFeatures[0]?.strokeWidth}" oninput="${() => this.onOptionsChange()}"> <span class="unit">px</span> <select id="line-style" class="gg-select" aria-label="Line style" onchange="${() => this.onOptionsChange()}">${Object.entries(this.lineStyles).map((entry) => uHtml `<option selected="${this.selectedFeatures[0]?.lineStroke === entry[0]}" value="${entry[0]}"><span>${entry[1]}</span></option>`)}</select></div></div><hr><div id="optionsArrow"><div class="${this.isLineArrowEnabled() ? '' : 'disabled'}" id="optionsArrowStyles"><span i18n="Arrows style">Arrows style</span> <select id="arrow-style" class="gg-select" aria-label="Arrows style" onchange="${() => this.onArrowsChange()}">${Object.entries(this.arrowStyles).map((entry) => uHtml `<option selected="${this.selectedFeatures[0]?.arrowStyle === entry[0]}" value="${entry[0]}"><span>${entry[1]}</span></option>`)}</select> <select id="arrow-position" class="gg-select" aria-label="Arrow position" onchange="${() => this.onArrowsChange()}">${Object.entries(this.arrowPositions).map((entry) => uHtml `<option selected="${this.selectedFeatures[0]?.arrowPosition === entry[0]}" value="${entry[0]}"><span>${entry[1]}</span></option>`)}</select></div></div><hr><div id="optionsExport"><div id="optionsExportLine"><label for="export" class="gg-label" i18n="Export">Export</label> <button class="gg-button" onclick="${() => this.exportSelectedFeatures('geojson')}">GeoJson</button> <button class="gg-button" onclick="${() => this.exportSelectedFeatures('kml')}">KML</button> <button class="gg-button" onclick="${() => this.exportSelectedFeatures('gpx')}">GPX</button></div></div></fieldset></div></div>
|
|
22
22
|
${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
23
23
|
};
|
|
24
24
|
constructor() {
|
|
@@ -41,7 +41,7 @@ export default class DrawingComponent extends GirafeHTMLElement {
|
|
|
41
41
|
input{border:1px solid var(--bkg-color-grad1);width:inherit;background-color:var(--bkg-color-input);padding-right:0}input:focus{border:1px solid var(--lt-color-gray-900)}button{border:solid 1px var(--bkg-color);color:var(--text-color);background-color:var(--bkg-color);cursor:pointer;padding:0}button:hover{border:solid 1px var(--text-color-grad2)}button.selected{border:solid 1px var(--text-color-grad2);background-color:var(--bkg-color-grad1);color:var(--bkg-color)}#toolbar{flex-wrap:wrap;display:flex}.label-container{flex-grow:1}.text-end{text-align:end}.icon{width:1.2rem;height:1.2rem;fill:var(--text-color);flex-shrink:0;margin:3px}.icon:hover{fill:var(--text-color-grad2)}.gg-icon-button:hover{border:none}.colorPicker{border:1px solid var(--text-color);border-radius:5px}.picker_wrapper{transform:translate(-250px)}.picker_arrow{transform:translate(200px)rotate(90deg)scaleX(-1)!important}.picker_wrapper,.picker_arrow:after,.picker_arrow:before{background-color:var(--bkg-color)!important}.picker_wrapper,.picker_arrow:before{box-shadow:0 0 10px 1px var(--text-color-grad1)!important}button:disabled,input:disabled,.disabled{pointer-events:none;opacity:.5}fieldset.field-wrapper{border:0;margin:0;padding:0}#panel{height:100%;color:var(--text-color);flex-direction:column;display:flex}#panel>div{padding:1rem}#toolParametersContainer{& .title{margin-top:.5rem;margin-bottom:.75rem;display:inline-block}}.toolParameters{flex-direction:column;justify-content:left;row-gap:.25rem;display:flex}.toolParameters>label{padding:0 5px}#drawingListContainer{flex-grow:1;overflow:hidden auto;padding-top:0!important;& .titleContainer{margin-bottom:1rem;display:flex;& .title{flex-grow:1;align-items:center;display:flex}}}#drawingList{flex-flow:column;gap:.15rem;display:flex}#drawingList .girafe{border:solid 1px var(--text-color);flex-wrap:wrap;align-items:center;padding:.3rem;display:flex;position:relative}#drawingList .girafe span{flex-grow:1;padding-left:5px}#options{box-shadow:0px -2px 3px -1px var(--text-color-grad1);z-index:100;flex-direction:column;display:flex;position:relative}#optionsTitle{text-align:center;margin-bottom:20px;font-size:1.2rem}#options hr{width:100%;margin:8px 0}#optionsTextLines,#optionsColorLine,#optionsLineLines{align-items:center;display:grid}#optionsText{margin:auto}#optionsTextLines{grid-template-columns:.825fr 2.5fr 1fr 4em .5fr .5fr}#optionsTextLines button:hover{border:none}#optionsColor,#optionsLine,#optionsExport,#optionsArrow{margin:auto}#optionsColorLine{display:flex}#optionsColorLine>div{align-items:center;width:100%;display:flex}#optionsLineLines,#optionsArrowStyle{grid-template-columns:3fr 4em 1fr auto}#optionsExportLine{grid-template-columns:60px 60px 45px 45px;gap:.2rem;display:flex}span.label{padding-left:.5rem;padding-right:.5rem;&.first{padding-left:0}}span.unit{padding-left:.5rem}
|
|
42
42
|
</style>
|
|
43
43
|
<style>${this.customStyle}</style>
|
|
44
|
-
<div id="panel"><div><div id="toolbar"><button id="disable" tip="Disable drawing" class="gg-icon-button gg-medium"><img alt="select icon" src="icons/arrow.svg"></button> <button id="point" tip="Point" class="gg-icon-button gg-medium"><img alt="point icon" src="icons/point.svg"></button> <button id="line" tip="Line" class="gg-icon-button gg-medium"><img alt="polyline icon" src="icons/polyline.svg"></button> <button id="polygon" tip="Polygon" class="gg-icon-button gg-medium"><img alt="polygon icon" src="icons/polygon.svg"></button> <button id="square" tip="Square" class="gg-icon-button gg-medium"><img alt="square icon" src="icons/square.svg"></button> <button id="rectangle" tip="Rectangle" class="gg-icon-button gg-medium"><img alt="rectangle icon" src="icons/rectangle.svg"></button> <button id="circle" tip="Circle" class="gg-icon-button gg-medium"><img alt="circle icon" src="icons/circle.svg"></button> <button id="freeline" tip="Freehand line" class="gg-icon-button gg-medium"><img alt="polyline-free icon" src="icons/polyline-free.svg"></button> <button id="freepolygon" tip="Freehand polygon" class="gg-icon-button gg-medium"><img alt="polygon-free icon" src="icons/polygon-free.svg"></button> <button id="text" tip="Text" class="gg-icon-button gg-medium"><img alt="text icon" src="icons/text-font.svg"></button></div><div id="toolParametersContainer"><span i18n="Settings" class="title"></span><div class="toolParameters" data-tool="Polyline,Polygon"><girafe-fixed-dimension dimensionname="length" dimension="length" id="fixedLineLength" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension></div><div class="toolParameters" data-tool="Square"><girafe-fixed-dimension dimensionname="side length" dimension="side" id="fixedSquareSide" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension></div><div class="toolParameters" data-tool="Rectangle"><girafe-fixed-dimension dimensionname="width" dimension="width" id="fixedRectangleWidth" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension><girafe-fixed-dimension dimensionname="height" dimension="height" id="fixedRectangleHeight" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension></div><div class="toolParameters" data-tool="Text"><label class="gg-label" for="drawingText" i18n="Text to draw">Text to draw</label> <input id="drawingText" class="gg-input" value="${this.drawingText}" oninput="${(e) => this.drawingTextChangedHandler(e)}"></div></div></div><div id="drawingListContainer"><div class="titleContainer"><span i18n="Drawing List" class="title"></span> <button class="gg-icon-button icon" tip="Delete all shapes" onclick="${() => this.deleteAllFeatures()}" ?disabled="${this.drawingState.features.length === 0}">${this.htmlUnsafe(this.trashIcon)}</button></div><div id="drawingList">${this.drawingState.features.map(feature => uHtmlFor(feature, feature.id) `<div id="${'f-' + feature.id}" class="girafe"><button id="${'f-select-' + feature.id}" class="gg-icon-button gg-small" tip="Select to change appearance" onclick="${() => this.onToggleFeatureSelection(feature)}"><div class="icon">${this.htmlUnsafe(feature.selected ? this.checkedIcon : this.noCheckedIcon)}</div></button><div class="label-container"><button class="${feature.selected ? 'selectable-label gg-icon-button gg-small gg-selected' : 'selectable-label gg-icon-button gg-small gg-opacity'}" onclick="${() => this.onToggleFeatureSelection(feature)}"><span id="${'f-name-' + feature.id}">${feature.name}</span></button></div><button class="gg-icon-button icon" tip="Center on shape" onclick="${() => this.olDrawing.centerViewOnFeature(feature)}">${this.htmlUnsafe(this.locateIcon)}</button> <button class="gg-icon-button icon" tip="Delete shape" onclick="${() => this.deleteFeature(feature)}">${this.htmlUnsafe(this.trashIcon)}</button></div>`)}</div></div><div id="options" class="${this.selectedFeatures.length > 0 ? '' : 'disabled'}"><fieldset class="field-wrapper" disabled="${this.selectedFeatures.length <= 0}"><input id="optionsTitle" value="${this.getOptionsTitle()}" class="gg-input" disabled="${this.selectedFeatures.length > 1}"><div id="optionsText"><div id="optionsTextLines"><span class="label first" i18n="Name">Name</span> <button class="gg-icon-button icon" id="visibleIconName" tip="Show or hide shape name" onclick="${() => this.toggleNameVisibility()}">${this.htmlUnsafe(this.isDisplayNameEnabled() ? this.visibleIcon : this.notVisibleIcon)}</button> <span class="label" i18n="Font">Font</span> <input id="optionsNameFontSize" class="gg-input" type="number" min="1" value="${this.selectedFeatures[0]?.nameFontSize}" oninput="${() => this.onOptionsChange()}"> <span class="unit">pt</span> <button class="icon colorPicker" id="nameColorPicker"></button> <span class="${this.isMeasureInformationEnabled() ? 'label first' : 'label first disabled'}" i18n="Measures">Measures</span> <select id="measure-information" class="gg-select" tip="${this.measureInformationTooltip}" disabled="${!this.isMeasureInformationEnabled()}" onchange="${() => this.onOptionsChange()}">${Object.entries(this.measureInformations).map((entry) => uHtml `<option selected="${this.selectedFeatureMeasureInformation === entry[0]}" value="${entry[0]}"><span i18n="${entry[1]}">${entry[0]}</span></option>`)}</select> <span class="${this.isMeasureInformationEnabled() ? 'label' : 'label disabled'}" i18n="Font">Font</span> <input id="optionsMeasuresFontSize" class="gg-input" type="number" min="1" value="${this.selectedFeatures[0]?.measureFontSize}" disabled="${!this.isMeasureInformationEnabled()}" oninput="${() => this.onOptionsChange()}"> <span class="${this.isMeasureInformationEnabled() ? 'unit' : 'unit disabled'}">pt</span> <button class="icon colorPicker" id="measureColorPicker" disabled="${!this.isMeasureInformationEnabled()}"></button></div></div><hr><div id="optionsColor"><div id="optionsColorLine"><div><span class="${this.isStrokeColorEnabled() ? 'text-end' : 'text-end disabled'}" i18n="Stroke color">Stroke color</span> <button class="icon colorPicker" disabled="${!this.isStrokeColorEnabled()}" id="strokePicker"></button></div><div><span class="${this.isFillColorEnabled() ? 'text-end' : 'text-end disabled'}" id="fillPickerSpan" i18n="Fill color">Fill color</span> <button class="icon colorPicker" disabled="${!this.isFillColorEnabled()}" id="fillPicker"></button></div></div></div><hr><div id="optionsLine"><div class="${this.isLineStyleEnabled() ? '' : 'disabled'}" id="optionsLineLines"><span i18n="Line width">Line width</span> <input id="optionsStrokeWidth" type="number" class="gg-input" min="1" value="${this.selectedFeatures[0]?.strokeWidth}" oninput="${() => this.onOptionsChange()}"> <span class="unit">px</span> <select id="line-style" class="gg-select" onchange="${() => this.onOptionsChange()}">${Object.entries(this.lineStyles).map((entry) => uHtml `<option selected="${this.selectedFeatures[0]?.lineStroke === entry[0]}" value="${entry[0]}"><span>${entry[1]}</span></option>`)}</select></div></div><hr><div id="optionsArrow"><div class="${this.isLineArrowEnabled() ? '' : 'disabled'}" id="optionsArrowStyles"><span i18n="Arrows style">Arrows style</span> <select id="arrow-style" class="gg-select" onchange="${() => this.onArrowsChange()}">${Object.entries(this.arrowStyles).map((entry) => uHtml `<option selected="${this.selectedFeatures[0]?.arrowStyle === entry[0]}" value="${entry[0]}"><span>${entry[1]}</span></option>`)}</select> <select id="arrow-position" class="gg-select" onchange="${() => this.onArrowsChange()}">${Object.entries(this.arrowPositions).map((entry) => uHtml `<option selected="${this.selectedFeatures[0]?.arrowPosition === entry[0]}" value="${entry[0]}"><span>${entry[1]}</span></option>`)}</select></div></div><hr><div id="optionsExport"><div id="optionsExportLine"><label for="export" class="gg-label" i18n="Export">Export</label> <button class="gg-button" onclick="${() => this.exportSelectedFeatures('geojson')}">GeoJson</button> <button class="gg-button" onclick="${() => this.exportSelectedFeatures('kml')}">KML</button> <button class="gg-button" onclick="${() => this.exportSelectedFeatures('gpx')}">GPX</button></div></div></fieldset></div></div>
|
|
44
|
+
<div id="panel"><div><div id="toolbar"><button id="disable" tip="Disable drawing" class="gg-icon-button gg-medium"><img alt="select icon" src="icons/arrow.svg"></button> <button id="point" tip="Point" class="gg-icon-button gg-medium"><img alt="point icon" src="icons/point.svg"></button> <button id="line" tip="Line" class="gg-icon-button gg-medium"><img alt="polyline icon" src="icons/polyline.svg"></button> <button id="polygon" tip="Polygon" class="gg-icon-button gg-medium"><img alt="polygon icon" src="icons/polygon.svg"></button> <button id="square" tip="Square" class="gg-icon-button gg-medium"><img alt="square icon" src="icons/square.svg"></button> <button id="rectangle" tip="Rectangle" class="gg-icon-button gg-medium"><img alt="rectangle icon" src="icons/rectangle.svg"></button> <button id="circle" tip="Circle" class="gg-icon-button gg-medium"><img alt="circle icon" src="icons/circle.svg"></button> <button id="freeline" tip="Freehand line" class="gg-icon-button gg-medium"><img alt="polyline-free icon" src="icons/polyline-free.svg"></button> <button id="freepolygon" tip="Freehand polygon" class="gg-icon-button gg-medium"><img alt="polygon-free icon" src="icons/polygon-free.svg"></button> <button id="text" tip="Text" class="gg-icon-button gg-medium"><img alt="text icon" src="icons/text-font.svg"></button></div><div id="toolParametersContainer"><span i18n="Settings" class="title"></span><div class="toolParameters" data-tool="Polyline,Polygon"><girafe-fixed-dimension dimensionname="length" dimension="length" id="fixedLineLength" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension></div><div class="toolParameters" data-tool="Square"><girafe-fixed-dimension dimensionname="side length" dimension="side" id="fixedSquareSide" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension></div><div class="toolParameters" data-tool="Rectangle"><girafe-fixed-dimension dimensionname="width" dimension="width" id="fixedRectangleWidth" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension><girafe-fixed-dimension dimensionname="height" dimension="height" id="fixedRectangleHeight" @fixed-dimension:value-changed="${(e) => this.fixedDimensionValueChangedHandler(e)}"></girafe-fixed-dimension></div><div class="toolParameters" data-tool="Text"><label class="gg-label" for="drawingText" i18n="Text to draw">Text to draw</label> <input id="drawingText" class="gg-input" value="${this.drawingText}" oninput="${(e) => this.drawingTextChangedHandler(e)}"></div></div></div><div id="drawingListContainer"><div class="titleContainer"><span i18n="Drawing List" class="title"></span> <button class="gg-icon-button icon" tip="Delete all shapes" onclick="${() => this.deleteAllFeatures()}" ?disabled="${this.drawingState.features.length === 0}">${this.htmlUnsafe(this.trashIcon)}</button></div><div id="drawingList">${this.drawingState.features.map(feature => uHtmlFor(feature, feature.id) `<div id="${'f-' + feature.id}" class="girafe"><button id="${'f-select-' + feature.id}" class="gg-icon-button gg-small" tip="Select to change appearance" onclick="${() => this.onToggleFeatureSelection(feature)}"><div class="icon">${this.htmlUnsafe(feature.selected ? this.checkedIcon : this.noCheckedIcon)}</div></button><div class="label-container"><button class="${feature.selected ? 'selectable-label gg-icon-button gg-small gg-selected' : 'selectable-label gg-icon-button gg-small gg-opacity'}" onclick="${() => this.onToggleFeatureSelection(feature)}"><span id="${'f-name-' + feature.id}">${feature.name}</span></button></div><button class="gg-icon-button icon" tip="Center on shape" onclick="${() => this.olDrawing.centerViewOnFeature(feature)}">${this.htmlUnsafe(this.locateIcon)}</button> <button class="gg-icon-button icon" tip="Delete shape" onclick="${() => this.deleteFeature(feature)}">${this.htmlUnsafe(this.trashIcon)}</button></div>`)}</div></div><div id="options" class="${this.selectedFeatures.length > 0 ? '' : 'disabled'}"><fieldset class="field-wrapper" disabled="${this.selectedFeatures.length <= 0}"><input id="optionsTitle" aria-label="Title" value="${this.getOptionsTitle()}" class="gg-input" disabled="${this.selectedFeatures.length > 1}"><div id="optionsText"><div id="optionsTextLines"><span class="label first" i18n="Name">Name</span> <button class="gg-icon-button icon" id="visibleIconName" tip="Show or hide shape name" onclick="${() => this.toggleNameVisibility()}">${this.htmlUnsafe(this.isDisplayNameEnabled() ? this.visibleIcon : this.notVisibleIcon)}</button> <span class="label" i18n="Font">Font</span> <input id="optionsNameFontSize" class="gg-input" type="number" aria-label="Name font size" min="1" value="${this.selectedFeatures[0]?.nameFontSize}" oninput="${() => this.onOptionsChange()}"> <span class="unit">pt</span> <button class="icon colorPicker" id="nameColorPicker"></button> <span class="${this.isMeasureInformationEnabled() ? 'label first' : 'label first disabled'}" i18n="Measures">Measures</span> <select id="measure-information" class="gg-select" aria-label="Measures information" tip="${this.measureInformationTooltip}" disabled="${!this.isMeasureInformationEnabled()}" onchange="${() => this.onOptionsChange()}">${Object.entries(this.measureInformations).map((entry) => uHtml `<option selected="${this.selectedFeatureMeasureInformation === entry[0]}" value="${entry[0]}"><span i18n="${entry[1]}">${entry[0]}</span></option>`)}</select> <span class="${this.isMeasureInformationEnabled() ? 'label' : 'label disabled'}" i18n="Font">Font</span> <input id="optionsMeasuresFontSize" class="gg-input" type="number" aria-label="Measures font size" min="1" value="${this.selectedFeatures[0]?.measureFontSize}" disabled="${!this.isMeasureInformationEnabled()}" oninput="${() => this.onOptionsChange()}"> <span class="${this.isMeasureInformationEnabled() ? 'unit' : 'unit disabled'}">pt</span> <button class="icon colorPicker" id="measureColorPicker" disabled="${!this.isMeasureInformationEnabled()}"></button></div></div><hr><div id="optionsColor"><div id="optionsColorLine"><div><span class="${this.isStrokeColorEnabled() ? 'text-end' : 'text-end disabled'}" i18n="Stroke color">Stroke color</span> <button class="icon colorPicker" disabled="${!this.isStrokeColorEnabled()}" id="strokePicker"></button></div><div><span class="${this.isFillColorEnabled() ? 'text-end' : 'text-end disabled'}" id="fillPickerSpan" i18n="Fill color">Fill color</span> <button class="icon colorPicker" disabled="${!this.isFillColorEnabled()}" id="fillPicker"></button></div></div></div><hr><div id="optionsLine"><div class="${this.isLineStyleEnabled() ? '' : 'disabled'}" id="optionsLineLines"><span i18n="Line width">Line width</span> <input id="optionsStrokeWidth" type="number" aria-label="Line width" class="gg-input" min="1" value="${this.selectedFeatures[0]?.strokeWidth}" oninput="${() => this.onOptionsChange()}"> <span class="unit">px</span> <select id="line-style" class="gg-select" aria-label="Line style" onchange="${() => this.onOptionsChange()}">${Object.entries(this.lineStyles).map((entry) => uHtml `<option selected="${this.selectedFeatures[0]?.lineStroke === entry[0]}" value="${entry[0]}"><span>${entry[1]}</span></option>`)}</select></div></div><hr><div id="optionsArrow"><div class="${this.isLineArrowEnabled() ? '' : 'disabled'}" id="optionsArrowStyles"><span i18n="Arrows style">Arrows style</span> <select id="arrow-style" class="gg-select" aria-label="Arrows style" onchange="${() => this.onArrowsChange()}">${Object.entries(this.arrowStyles).map((entry) => uHtml `<option selected="${this.selectedFeatures[0]?.arrowStyle === entry[0]}" value="${entry[0]}"><span>${entry[1]}</span></option>`)}</select> <select id="arrow-position" class="gg-select" aria-label="Arrow position" onchange="${() => this.onArrowsChange()}">${Object.entries(this.arrowPositions).map((entry) => uHtml `<option selected="${this.selectedFeatures[0]?.arrowPosition === entry[0]}" value="${entry[0]}"><span>${entry[1]}</span></option>`)}</select></div></div><hr><div id="optionsExport"><div id="optionsExportLine"><label for="export" class="gg-label" i18n="Export">Export</label> <button class="gg-button" onclick="${() => this.exportSelectedFeatures('geojson')}">GeoJson</button> <button class="gg-button" onclick="${() => this.exportSelectedFeatures('kml')}">KML</button> <button class="gg-button" onclick="${() => this.exportSelectedFeatures('gpx')}">GPX</button></div></div></fieldset></div></div>
|
|
45
45
|
${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
46
46
|
};
|
|
47
47
|
isPanelVisible = false;
|
|
@@ -454,9 +454,9 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
|
454
454
|
}
|
|
455
455
|
}
|
|
456
456
|
onOptionsChange() {
|
|
457
|
-
const nameFontSize = parseInt(this.getById('optionsNameFontSize').value);
|
|
458
|
-
const measureFontSize = parseInt(this.getById('optionsMeasuresFontSize').value);
|
|
459
|
-
const strokeWidth = parseInt(this.getById('optionsStrokeWidth').value);
|
|
457
|
+
const nameFontSize = Number.parseInt(this.getById('optionsNameFontSize').value);
|
|
458
|
+
const measureFontSize = Number.parseInt(this.getById('optionsMeasuresFontSize').value);
|
|
459
|
+
const strokeWidth = Number.parseInt(this.getById('optionsStrokeWidth').value);
|
|
460
460
|
const lineStroke = this.getById('line-style').value;
|
|
461
461
|
const measureInformation = this.getById('measure-information').value;
|
|
462
462
|
this.selectedFeatures.forEach((f) => (f.nameFontSize = nameFontSize));
|
|
@@ -22,7 +22,7 @@ class FixedDimensionComponent extends GirafeHTMLElement {
|
|
|
22
22
|
:host{grid-template-columns:auto auto 60px auto;justify-content:left;align-items:center;display:grid}input{border:1px solid var(--bkg-color-grad1);width:inherit;background-color:var(--bkg-color-input);padding-right:0}input:focus{border:1px solid var(--lt-color-gray-900)}button{border:solid 1px var(--bkg-color);color:var(--text-color);background-color:var(--bkg-color);cursor:pointer;padding:0}button:hover{border:solid 1px var(--text-color-grad2)}button.selected{border:solid 1px var(--text-color-grad2);background-color:var(--bkg-color-grad1);color:var(--bkg-color)}.icon{width:1.2rem;height:1.2rem;fill:var(--text-color);flex-shrink:0;margin:3px}.icon:hover{fill:var(--text-color-grad2)}.gg-icon-button:hover{border:none}button:disabled,input:disabled,.disabled{pointer-events:none;opacity:.5}label.gg-label{padding:0 5px!important;&.disabled{pointer-events:revert}}
|
|
23
23
|
</style>
|
|
24
24
|
<style>${this.customStyle}</style>
|
|
25
|
-
<button class="gg-icon-button icon" onclick="${() => this.toggleFixedDimensionEnabled()}">${this.htmlUnsafe(this.fixedDimensionEnabled ? this.checkedIcon : this.notCheckedIcon)}</button> <label class="${this.fixedDimensionEnabled ? 'gg-label' : 'gg-label disabled'}" onclick="${() => this.toggleFixedDimensionEnabled()}" onkeyup="${() => this.toggleFixedDimensionEnabled()}" for="fixedValue" i18n="${'Fix ' + this.dimensionName + ' to'}"></label> <input class="gg-input" disabled="${!this.fixedDimensionEnabled}" oninput="${(e) => this.fixedValueChanged(e)}" type="number" id="fixedValue"> <select id="dimensionUnits" class="gg-select" disabled="${!this.fixedDimensionEnabled}" onchange="${(e) => this.dimensionUnitChanged(e)}">${this.units.map((unit) => uHtml `<option ?selected="${this.unit?.name === unit.name}" value="${unit.factor}">${unit.name}</option>`)}</select>
|
|
25
|
+
<button class="gg-icon-button icon" onclick="${() => this.toggleFixedDimensionEnabled()}">${this.htmlUnsafe(this.fixedDimensionEnabled ? this.checkedIcon : this.notCheckedIcon)}</button> <label class="${this.fixedDimensionEnabled ? 'gg-label' : 'gg-label disabled'}" onclick="${() => this.toggleFixedDimensionEnabled()}" onkeyup="${() => this.toggleFixedDimensionEnabled()}" for="fixedValue" i18n="${'Fix ' + this.dimensionName + ' to'}"></label> <input class="gg-input" disabled="${!this.fixedDimensionEnabled}" oninput="${(e) => this.fixedValueChanged(e)}" type="number" id="fixedValue"> <select id="dimensionUnits" class="gg-select" aria-label="Units" disabled="${!this.fixedDimensionEnabled}" onchange="${(e) => this.dimensionUnitChanged(e)}">${this.units.map((unit) => uHtml `<option ?selected="${this.unit?.name === unit.name}" value="${unit.factor}">${unit.name}</option>`)}</select>
|
|
26
26
|
${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
27
27
|
};
|
|
28
28
|
checkedIcon = checkedIcon;
|
|
@@ -33,7 +33,7 @@ export default class EditComponent extends GirafeHTMLElement {
|
|
|
33
33
|
#content{background:var(--bkg-color);color:var(--text-color);flex-direction:column;gap:1rem;margin:0;padding:1rem;display:flex}.girafe-prototype{color:#fff;text-align:center;background:#ec5555;font-size:1rem;font-weight:700;line-height:40px}.editing{flex-direction:column;gap:1rem;display:flex}#layer-selector{width:100%}.draw-btn{text-align:right}.current-feature{border-top:var(--app-standard-border);margin-top:2rem}.current-feature-row{align-items:center;gap:.5em;display:flex}.current-feature-row>button{margin-left:auto}.current-feature-row>div:first-child{font-weight:700}.attribute-form-btns{justify-content:flex-end;gap:.5rem;margin-top:1rem;display:flex}.btn-active{background-color:var(--bkg-color-grad2)}
|
|
34
34
|
</style>
|
|
35
35
|
<style>${this.customStyle}</style>
|
|
36
|
-
<div id="content"><div class="girafe-prototype" i18n="PROTOTYPE - Work in progress">PROTOTYPE - Work in progress</div><div class="editing"><select id="layer-selector" class="gg-select" disabled="${this.feature}" onchange="${(evt) => this.onSelectLayer(evt)}">${this.editableLayersList.length === 0 && this.state.oauth.status !== 'loggedIn' ? uHtml `<option i18n="Please log in to edit layers..." ?selected="true" value="">Please log in to edit layers...</option>` : uHtml `<option i18n="Choose a layer..." ?selected="true" value="">Choose a layer...</option>`} ${this.editableLayersList.map(layer => uHtmlFor(layer, layer.collectionId) `<option value="${layer.collectionId}">${layer.displayName}</option>`)}</select> ${this.layer ? uHtml `<div class="draw-btn">${this.displayDrawingCancelButton() ? uHtml ` <button class="gg-button gg-medium-withtext btn-active" onclick="${() => this.onCancelDrawing()}"><img alt="cancel-drawing-icon" src="icons/close.svg"> <span i18n="Cancel editing">Cancel editing</span></button> ` : uHtml ` <button class="gg-button gg-medium-withtext" onclick="${() => this.onStartDrawing()}"><img alt="start-drawing-icon" src="${this.getButtonIcon()}"> <span i18n="${this.getButtonText()}">${this.getButtonText()}</span></button> `}</div>` : uHtml ``} ${this.feature ? uHtml `<div class="current-feature"><h3 i18n="Current Feature">Current Feature</h3><div class="current-feature-row"><div i18n="Feature ID">Feature ID</div><div>${this.getFeatureId()}</div><button class="${this.canDelete() ? 'gg-button gg-medium-withtext delete-btn' : 'hidden'}" onclick="${() => this.onDelete()}"><img alt="delete-icon" src="icons/trash.svg"> <span i18n="delete">Delete</span></button></div></div>` : uHtml ``}<girafe-edit-form id="edit-form"></girafe-edit-form>${this.feature ? uHtml `<div class="attribute-form-btns"><button class="gg-button" disabled="${!this.isValidForm()}" onclick="${() => this.onSave()}"><span i18n="Save">Save</span></button> <button class="gg-button" onclick="${() => this.onDiscard()}"><span i18n="Discard">Discard</span></button></div>` : uHtml ``}</div></div>
|
|
36
|
+
<div id="content"><div class="girafe-prototype" i18n="PROTOTYPE - Work in progress">PROTOTYPE - Work in progress</div><div class="editing"><select id="layer-selector" class="gg-select" aria-label="Layer to edit" disabled="${this.feature}" onchange="${(evt) => this.onSelectLayer(evt)}">${this.editableLayersList.length === 0 && this.state.oauth.status !== 'loggedIn' ? uHtml `<option i18n="Please log in to edit layers..." ?selected="true" value="">Please log in to edit layers...</option>` : uHtml `<option i18n="Choose a layer..." ?selected="true" value="">Choose a layer...</option>`} ${this.editableLayersList.map(layer => uHtmlFor(layer, layer.collectionId) `<option value="${layer.collectionId}">${layer.displayName}</option>`)}</select> ${this.layer ? uHtml `<div class="draw-btn">${this.displayDrawingCancelButton() ? uHtml ` <button class="gg-button gg-medium-withtext btn-active" onclick="${() => this.onCancelDrawing()}"><img alt="cancel-drawing-icon" src="icons/close.svg"> <span i18n="Cancel editing">Cancel editing</span></button> ` : uHtml ` <button class="gg-button gg-medium-withtext" onclick="${() => this.onStartDrawing()}"><img alt="start-drawing-icon" src="${this.getButtonIcon()}"> <span i18n="${this.getButtonText()}">${this.getButtonText()}</span></button> `}</div>` : uHtml ``} ${this.feature ? uHtml `<div class="current-feature"><h3 i18n="Current Feature">Current Feature</h3><div class="current-feature-row"><div i18n="Feature ID">Feature ID</div><div>${this.getFeatureId()}</div><button class="${this.canDelete() ? 'gg-button gg-medium-withtext delete-btn' : 'hidden'}" onclick="${() => this.onDelete()}"><img alt="delete-icon" src="icons/trash.svg"> <span i18n="delete">Delete</span></button></div></div>` : uHtml ``}<girafe-edit-form id="edit-form"></girafe-edit-form>${this.feature ? uHtml `<div class="attribute-form-btns"><button class="gg-button" disabled="${!this.isValidForm()}" onclick="${() => this.onSave()}"><span i18n="Save">Save</span></button> <button class="gg-button" onclick="${() => this.onDiscard()}"><span i18n="Discard">Discard</span></button></div>` : uHtml ``}</div></div>
|
|
37
37
|
${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
38
38
|
};
|
|
39
39
|
isPanelVisible = false;
|
|
@@ -56,7 +56,7 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
|
56
56
|
const formField = this.getById(`form-${attrName}`);
|
|
57
57
|
let formValue = formField.value;
|
|
58
58
|
if (this.featureSchema.isNumericProperty(attrName)) {
|
|
59
|
-
if (formValue === '' || isNaN(Number(formValue))) {
|
|
59
|
+
if (formValue === '' || Number.isNaN(Number(formValue))) {
|
|
60
60
|
formValue = null;
|
|
61
61
|
}
|
|
62
62
|
else {
|
|
@@ -18,7 +18,7 @@ class ExternalLayersComponent extends GirafeHTMLElement {
|
|
|
18
18
|
#panel{background:var(--bkg-color);height:100%;color:var(--text-color);flex-direction:column;padding:0 1rem;display:flex}#content{flex-direction:column;flex-grow:1;margin:0;display:flex}header{background-color:var(--bkg-color);margin:0;position:sticky;top:-5px}h4{margin-bottom:.5rem}ul{margin-top:0;margin-left:0;padding-left:2rem;line-height:1.3rem;list-style-type:disc}.clearable-input{background-color:var(--bkg-color);border:1px solid #cfd6dd;border-radius:4px;flex-direction:row;margin-bottom:.1rem;display:flex}.scan-button{float:right}.layers{border-top:1px solid #ccc;flex-direction:column;flex-grow:1;margin-top:1rem;padding-top:.5rem;display:flex;overflow:hidden}ul.results{border:none;margin-bottom:.5rem;padding:0;list-style:none;overflow-y:auto}.result{height:1.6rem;display:flex}.result>button>span{text-align:left;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}#panel>div{padding:1rem}#layers li{margin-top:.3rem;margin-bottom:.3rem}#layers li button{text-align:left;overflow-wrap:anywhere;text-wrap-style:balance}#loading-icon{flex-grow:1;align-self:center;width:3rem}.title{margin-top:0}.filter-buttons{flex-direction:row;margin:2px;display:flex}.filter-buttons span{flex-grow:1;align-self:center}.clearable-input-field{width:90%;color:var(--text-color);background:0 0;border:0;outline:none;flex:auto;padding:0;font-size:1rem}.filter-icon,.delete-icon{width:16px;color:var(--text-color);padding:0 .5rem}.delete-button{cursor:pointer;background-color:#0000;border:none;padding:0}#file-selector{flex-direction:column;display:flex;position:relative}#file{color:var(--text-color);cursor:pointer}#file::file-selector-button{background-color:var(--bkg-color);color:var(--text-color);border:var(--app-standard-border);min-height:calc(var(--app-standard-height) / 1.5);font:inherit;cursor:pointer;border-radius:.25em;outline:0;margin:0 .5rem 0 0;padding:0 .5rem}#file::file-selector-button:hover{background-color:var(--bkg-color-grad1)}.file-loaded-message{box-sizing:border-box;background-color:var(--success-color);border-radius:.25em;width:100%;margin:.5rem 0 0;padding:.5em;position:absolute;top:100%;left:0}
|
|
19
19
|
</style>
|
|
20
20
|
<style>${this.customStyle}</style>
|
|
21
|
-
<div id="panel"><header class="gg-tabs"><button class="${this.selectedTab === 'wms_wmts' ? 'gg-tab active' : 'gg-tab'}" onclick="${() => this.setSelectedTab('wms_wmts')}" i18n="wms_wmts"></button> <button class="${this.selectedTab === 'file' ? 'gg-tab active' : 'gg-tab'}" onclick="${() => this.setSelectedTab('file')}" i18n="local file"></button></header><section class="${(this.selectedTab === 'wms_wmts') ? 'group' : 'hidden'}"><h4 class="title" i18n="Suggestions" ?hidden="${!this.hasPredefinedWmsWmtsSources}">Suggestions</h4><ul class="suggestions" ?hidden="${!this.hasPredefinedWmsWmtsSources}">${this.predefinedWmsWmtsSources.map(source => uHtmlFor(source, source.label) `<li><a href="javascript:void(0)" onclick="${() => this.scanSource(source.url, source.type)}">${source.label}</a></li>`)}</ul><h4 class="title" i18n="Custom service URL">Custom service URL</h4><div class="clearable-input"><input id="url" class="gg-input clearable-input-field" oninput="${() => this.typeUrl()}"><br><button id="clear-url" class="delete-button hidden" onclick="${() => this.clearUrl()}"><img class="delete-icon" alt="delete-button-icon" tip="Reset filter" i18n="Reset filter" src="icons/trash.svg"></button></div><button i18n="Scan Source" class="gg-button scan-button" onclick="${() => this.scanSource()}">Scan Source</button></section><section class="${(this.selectedTab === 'file') ? 'group' : 'hidden'}"><div id="file-selector"><label for="file" class="gg-label" i18n="Choose local file">Choose local file</label> <input type="file" accept=".gpx,.kml,.geojson,.json" id="file" onchange="${() => this.loadFile()}"><p class="${this.fileLoaded ? 'file-loaded-message' : 'hidden'}" i18n="File loaded in the layer tree">File loaded in the layer tree</div></section><section class="${(this.selectedTab === 'wms_wmts' && this.externalLayers.length > 0) || this.loading ? 'layers' : 'hidden'}"><h4 class="title" i18n="Layers (from Capabilities)">Layers (from Capabilities)</h4><div class="clearable-input"><img class="filter-icon" alt="filter-button-icon" src="icons/filter.svg"> <input id="layer-search-field" class="gg-input clearable-input-field" placeholder="${this.context.i18nManager.getTranslation('Filter external layers...')}" i18n="Filter external layers..." autocomplete="off" autocorrect="off" oninput="${(e) => this.filterLayers(e.target.value)}"> <button class="${this.isFiltered ? 'delete-button' : 'hidden'}" onclick="${() => this.clearFilter()}"><img class="delete-icon" alt="delete-button-icon" tip="Reset filter" i18n="Reset filter" src="icons/trash.svg"></button></div><div class="filter-buttons"><span>${Object.values(this.externalLayers).filter(layer => layer.isSelected).length.toString()} ${this.context.i18nManager.getTranslation('layers selected')} </span><button class="gg-button" tip="Select all filtered layers" onclick="${() => this.selectVisible()}">+</button> <button class="gg-button" tip="Unselect all filtered layers" onclick="${() => this.deselectVisible()}">-</button> <button class="gg-button" tip="Select none" onclick="${() => this.deselectAll()}">--</button></div><img id="loading-icon" alt="loading-icon" src="icons/loading.svg" class="${this.loading ? 'gg-spin' : 'hidden'}"><ul class="results">${this.filteredLayers.map(layer => uHtmlFor(layer, layer.treeItemId) `<li class="result"><button class="${layer.isSelected ? 'gg-icon-button gg-small gg-selected' : 'gg-icon-button gg-small gg-opacity'}" tip="Activate / Deactivate" onclick="${() => this.selectLayer(layer)}"><img class="${layer.isSelected ? 'gg-checkbox' : 'hidden'}" alt="Expand/Collapse button" src="icons/checked-full.svg"> <img class="${!layer.isSelected ? 'gg-checkbox' : 'hidden'}" alt="Expand/Collapse button" src="icons/checked-no.svg"></button> <button class="${layer.isSelected ? 'gg-icon-button gg-small gg-selected' : 'gg-icon-button gg-small gg-opacity'}" onclick="${() => this.selectLayer(layer)}"><span i18n="${layer.name}" class="gg-tree-label">${layer.name}</span></button></li>`)}</ul><button id="add" tip="Add selected" i18n="Add selected" class="gg-button" onclick="${() => this.addSelectedLayers()}">Add selected</button></section></div>
|
|
21
|
+
<div id="panel"><header class="gg-tabs"><button class="${this.selectedTab === 'wms_wmts' ? 'gg-tab active' : 'gg-tab'}" onclick="${() => this.setSelectedTab('wms_wmts')}" i18n="wms_wmts"></button> <button class="${this.selectedTab === 'file' ? 'gg-tab active' : 'gg-tab'}" onclick="${() => this.setSelectedTab('file')}" i18n="local file"></button></header><section class="${(this.selectedTab === 'wms_wmts') ? 'group' : 'hidden'}"><h4 class="title" i18n="Suggestions" ?hidden="${!this.hasPredefinedWmsWmtsSources}">Suggestions</h4><ul class="suggestions" ?hidden="${!this.hasPredefinedWmsWmtsSources}">${this.predefinedWmsWmtsSources.map(source => uHtmlFor(source, source.label) `<li><a href="javascript:void(0)" onclick="${() => this.scanSource(source.url, source.type)}">${source.label}</a></li>`)}</ul><h4 class="title" i18n="Custom service URL">Custom service URL</h4><div class="clearable-input"><input id="url" aria-label="Custom service URL" class="gg-input clearable-input-field" oninput="${() => this.typeUrl()}"><br><button id="clear-url" class="delete-button hidden" onclick="${() => this.clearUrl()}"><img class="delete-icon" alt="delete-button-icon" tip="Reset filter" i18n="Reset filter" src="icons/trash.svg"></button></div><button i18n="Scan Source" class="gg-button scan-button" onclick="${() => this.scanSource()}">Scan Source</button></section><section class="${(this.selectedTab === 'file') ? 'group' : 'hidden'}"><div id="file-selector"><label for="file" class="gg-label" i18n="Choose local file">Choose local file</label> <input type="file" accept=".gpx,.kml,.geojson,.json" id="file" onchange="${() => this.loadFile()}"><p class="${this.fileLoaded ? 'file-loaded-message' : 'hidden'}" i18n="File loaded in the layer tree">File loaded in the layer tree</div></section><section class="${(this.selectedTab === 'wms_wmts' && this.externalLayers.length > 0) || this.loading ? 'layers' : 'hidden'}"><h4 class="title" i18n="Layers (from Capabilities)">Layers (from Capabilities)</h4><div class="clearable-input"><img class="filter-icon" alt="filter-button-icon" src="icons/filter.svg"> <input id="layer-search-field" class="gg-input clearable-input-field" aria-label="Filter external layers" placeholder="${this.context.i18nManager.getTranslation('Filter external layers...')}" i18n="Filter external layers..." autocomplete="off" autocorrect="off" oninput="${(e) => this.filterLayers(e.target.value)}"> <button class="${this.isFiltered ? 'delete-button' : 'hidden'}" onclick="${() => this.clearFilter()}"><img class="delete-icon" alt="delete-button-icon" tip="Reset filter" i18n="Reset filter" src="icons/trash.svg"></button></div><div class="filter-buttons"><span>${Object.values(this.externalLayers).filter(layer => layer.isSelected).length.toString()} ${this.context.i18nManager.getTranslation('layers selected')} </span><button class="gg-button" tip="Select all filtered layers" onclick="${() => this.selectVisible()}">+</button> <button class="gg-button" tip="Unselect all filtered layers" onclick="${() => this.deselectVisible()}">-</button> <button class="gg-button" tip="Select none" onclick="${() => this.deselectAll()}">--</button></div><img id="loading-icon" alt="loading-icon" src="icons/loading.svg" class="${this.loading ? 'gg-spin' : 'hidden'}"><ul class="results">${this.filteredLayers.map(layer => uHtmlFor(layer, layer.treeItemId) `<li class="result"><button class="${layer.isSelected ? 'gg-icon-button gg-small gg-selected' : 'gg-icon-button gg-small gg-opacity'}" tip="Activate / Deactivate" onclick="${() => this.selectLayer(layer)}"><img class="${layer.isSelected ? 'gg-checkbox' : 'hidden'}" alt="Expand/Collapse button" src="icons/checked-full.svg"> <img class="${!layer.isSelected ? 'gg-checkbox' : 'hidden'}" alt="Expand/Collapse button" src="icons/checked-no.svg"></button> <button class="${layer.isSelected ? 'gg-icon-button gg-small gg-selected' : 'gg-icon-button gg-small gg-opacity'}" onclick="${() => this.selectLayer(layer)}"><span i18n="${layer.name}" class="gg-tree-label">${layer.name}</span></button></li>`)}</ul><button id="add" tip="Add selected" i18n="Add selected" class="gg-button" onclick="${() => this.addSelectedLayers()}">Add selected</button></section></div>
|
|
22
22
|
${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
23
23
|
};
|
|
24
24
|
isPanelVisible = false;
|
|
@@ -51,7 +51,7 @@ export default class Map2dComponent extends GirafeHTMLElement {
|
|
|
51
51
|
#container,#ol-map{background-color:var(--bkg-color);width:100%;height:100%;position:relative}#ol-map.darkmap canvas{filter:invert()hue-rotate(180deg)}.hidden{display:none}.ol-control{background-color:#0000;border:none;box-shadow:0 1px 4px #0000004d;right:2rem!important;left:unset!important}.ol-zoom{top:2rem!important}.mobile-map .ol-zoom{display:none!important}.ol-rotate{top:11.6rem!important}.ol-fullscreen{top:7rem!important}.ol-location{top:9.3rem!important}.img-location,.img-disable-location,.img-fullscreen{width:55%;height:auto}.ol-zoom-in,.ol-zoom-out,.btn-location,.btn-disable-location,.btn-fullscreen,.btn-exit-fullscreen,.ol-rotate-reset{cursor:pointer;background-color:var(--bkg-color)!important;width:2rem!important;height:2rem!important;color:var(--text-color)!important;font-size:1.2rem!important}.ol-scale-line{bottom:.5rem!important;right:1rem!important;left:unset!important}#swiper{width:100%;height:0;margin:0;display:none;position:absolute;top:50%}input[type=range]{-webkit-appearance:none;width:100%}input[type=range]::-webkit-slider-runnable-track{height:0}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;background:var(--bkg-color);cursor:ew-resize;border:2px solid #444;width:6px;height:0;margin-top:-1000px;padding-top:1000px;padding-bottom:1000px}input[type=range]::-moz-range-thumb{background:var(--bkg-color);cursor:ew-resize;border:2px solid #444;width:3px;height:0;padding-top:1000px;padding-bottom:1000px}.close-swiper{--button-size:2rem;transform:translateX(calc(-1 * var(--button-size) / 2));width:var(--button-size);height:var(--button-size);background-color:var(--bkg-color);color:var(--text-color);cursor:pointer;border-width:1px;border-radius:4px;display:none;position:absolute;top:0}.close-swiper:hover,.close-swiper:focus{outline:1px solid var(--text-color);color:var(--text-color-grad1)}.ol-viewport .tooltip{color:#fff;opacity:.7;white-space:nowrap;background:#00000080;border-radius:0;padding:.32rem .62rem;position:relative}@media screen and (hover:none){.ol-zoom,.ol-rotate,.ol-location,.ol-fullscreen{display:none!important}}.contextmenu{background-color:var(--bkg-color);color:var(--text-color);border:1px solid #ccc;box-shadow:1px 3px 4px #0006;& .hidden{display:none}& .menu-entry{cursor:pointer;padding:10px}& .menu-entry:hover{background-color:var(--bkg-color-grad1)}& .menu-entry[aria-disabled=true]{pointer-events:none;color:var(--text-color-grad1)}}
|
|
52
52
|
</style>
|
|
53
53
|
<style>${this.customStyle}</style>
|
|
54
|
-
<div id="container"><div id="ol-map" class="${this.onMobile ? 'mobile-map' : ''}"></div><div class="${this.onMobile ? 'hidden' : 'ol-fullscreen ol-unselectable ol-control'}"><button id="fullscreen-enter-button" onclick="${() => this.toggleFullscreen()}" tip="fullscreen-on" class="btn-fullscreen"><img class="img-fullscreen" alt="fullscreen-icon" src="icons/fullscreen.svg"></button> <button id="fullscreen-exit-button" onclick="${() => this.toggleFullscreen()}" tip="fullscreen-off" class="btn-exit-fullscreen hidden"><img class="img-fullscreen" alt="fullscreen-exit-icon" src="icons/fullscreen-exit.svg"></button></div><div class="${this.onMobile ? 'hidden' : 'ol-location ol-unselectable ol-control'}"><button onclick="${() => this.locateUser()}" class="btn-location" tip="Locate user"><img class="img-location" alt="location-icon" src="icons/adjust.svg"></button> <button id="disable-location" onclick="${() => this.disableLocateUser()}" tip="Disable locate user" class="btn-disable-location hidden"><img class="img-disable-location" alt="disable-location-icon" src="icons/adjust-disable.svg"></button></div><input id="swiper" type="range" min="0" max="1000" step="1"> <button tip="Hide Swiper" id="close-swiper" class="close-swiper">×</button></div>
|
|
54
|
+
<div id="container"><div id="ol-map" class="${this.onMobile ? 'mobile-map' : ''}"></div><div class="${this.onMobile ? 'hidden' : 'ol-fullscreen ol-unselectable ol-control'}"><button id="fullscreen-enter-button" onclick="${() => this.toggleFullscreen()}" tip="fullscreen-on" class="btn-fullscreen"><img class="img-fullscreen" alt="fullscreen-icon" src="icons/fullscreen.svg"></button> <button id="fullscreen-exit-button" onclick="${() => this.toggleFullscreen()}" tip="fullscreen-off" class="btn-exit-fullscreen hidden"><img class="img-fullscreen" alt="fullscreen-exit-icon" src="icons/fullscreen-exit.svg"></button></div><div class="${this.onMobile ? 'hidden' : 'ol-location ol-unselectable ol-control'}"><button onclick="${() => this.locateUser()}" class="btn-location" tip="Locate user"><img class="img-location" alt="location-icon" src="icons/adjust.svg"></button> <button id="disable-location" onclick="${() => this.disableLocateUser()}" tip="Disable locate user" class="btn-disable-location hidden"><img class="img-disable-location" alt="disable-location-icon" src="icons/adjust-disable.svg"></button></div><input id="swiper" type="range" aria-label="Map swiper" min="0" max="1000" step="1"> <button tip="Hide Swiper" id="close-swiper" class="close-swiper">×</button></div>
|
|
55
55
|
${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
56
56
|
};
|
|
57
57
|
olMap;
|
|
@@ -18,7 +18,7 @@ class SwipeManager {
|
|
|
18
18
|
if (!maxVal) {
|
|
19
19
|
throw new Error('The Attribute <max> on the swiper is not defined !');
|
|
20
20
|
}
|
|
21
|
-
this.swiperMaxVal = parseInt(maxVal);
|
|
21
|
+
this.swiperMaxVal = Number.parseInt(maxVal);
|
|
22
22
|
this.wmtsManager = wmtsManager;
|
|
23
23
|
this.wmsManager = wmsManager;
|
|
24
24
|
this.localFileManager = localFileManager;
|
|
@@ -139,7 +139,7 @@ class SwipeManager {
|
|
|
139
139
|
throw new Error('The size of the map is null !');
|
|
140
140
|
}
|
|
141
141
|
const mapSize = size;
|
|
142
|
-
const width = mapSize[0] * (parseInt(this.swiper.value) / this.swiperMaxVal);
|
|
142
|
+
const width = mapSize[0] * (Number.parseInt(this.swiper.value) / this.swiperMaxVal);
|
|
143
143
|
let tl;
|
|
144
144
|
let tr;
|
|
145
145
|
let bl;
|
|
@@ -11,7 +11,7 @@ class ModalsComponent extends GirafeHTMLElement {
|
|
|
11
11
|
#content{z-index:10000;background-color:#000000a6;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.modal{background:var(--bkg-color);border:var(--app-standard-border);border-radius:10px;width:300px;min-height:400px;box-shadow:5px 5px 10px #0003}.wide{width:auto;max-width:480px}header{background:var(--app-color-grey);border-top-left-radius:10px;border-top-right-radius:10px;justify-content:center;height:100px;padding:2rem;display:flex}section{text-align:center;flex-direction:column;padding:30px;display:flex}span{margin-bottom:1rem;font-size:1.2rem;display:inline-block}.confirm-buttons{flex-direction:row;justify-content:center;gap:1rem;margin-top:2rem;display:flex}.confirm-buttons button{width:7rem}h2,span{color:var(--text-color)}.choices{grid-template-columns:1fr 1fr;gap:1rem;margin-top:1rem;display:grid}.choice{height:4rem}
|
|
12
12
|
</style>
|
|
13
13
|
<style>${this.customStyle}</style>
|
|
14
|
-
<div id="content" class="${this.visible ? '' : 'hidden'}"><div class="${this.boxType == 'info' ? 'modal wide' : 'modal'}"><header><img alt="question-icon" src="icons/help.svg" class="${(this.boxType === 'alert' || this.boxType === 'info') ? 'hidden' : ''}"> <img alt="error-icon" src="icons/error.svg" class="${this.boxType === 'alert' ? '' : 'hidden'}"> <img alt="info-icon" src="icons/info.svg" class="${this.boxType === 'info' ? '' : 'hidden'}"></header><section><h2>${this.boxTitle}</h2><span>${this.htmlUnsafe(this.boxMessage)}</span> <input id="input-text" class="${this.boxType === 'prompt' ? 'gg-input' : 'hidden'}" placeholder="${this.boxPlaceholder}"><div class="${this.boxType === 'choice' ? 'choices' : 'hidden'}">${this.boxChoices.map(option => uHtml ` <button class="gg-button choice" onclick="${() => this.choiceOk(option)}">${option}</button> `)}</div><div class="${(this.boxType === 'alert' || this.boxType === 'info') ? 'confirm-buttons' : 'hidden'}"><button class="gg-button" onclick="${() => this.ok()}" i18n="Ok">Ok</button></div><div class="${this.boxType === 'confirm' ? 'confirm-buttons' : 'hidden'}"><button class="gg-button" onclick="${() => this.ok()}" i18n="Yes">Yes</button> <button class="gg-button" onclick="${() => this.nok()}" i18n="No">No</button></div><div class="${this.boxType === 'prompt' ? 'confirm-buttons' : 'hidden'}"><button class="gg-button" onclick="${() => this.promptOk()}" i18n="Ok">Ok</button> <button class="gg-button" onclick="${() => this.promptNok()}" i18n="Cancel">Cancel</button></div><div class="${this.boxType === 'choice' ? 'confirm-buttons' : 'hidden'}"><button class="gg-button" onclick="${() => this.promptNok()}" i18n="Cancel">Cancel</button></div></section></div></div>
|
|
14
|
+
<div id="content" class="${this.visible ? '' : 'hidden'}"><div class="${this.boxType == 'info' ? 'modal wide' : 'modal'}"><header><img alt="question-icon" src="icons/help.svg" class="${(this.boxType === 'alert' || this.boxType === 'info') ? 'hidden' : ''}"> <img alt="error-icon" src="icons/error.svg" class="${this.boxType === 'alert' ? '' : 'hidden'}"> <img alt="info-icon" src="icons/info.svg" class="${this.boxType === 'info' ? '' : 'hidden'}"></header><section><h2>${this.boxTitle}</h2><span>${this.htmlUnsafe(this.boxMessage)}</span> <input id="input-text" aria-label="Input" class="${this.boxType === 'prompt' ? 'gg-input' : 'hidden'}" placeholder="${this.boxPlaceholder}"><div class="${this.boxType === 'choice' ? 'choices' : 'hidden'}">${this.boxChoices.map(option => uHtml ` <button class="gg-button choice" onclick="${() => this.choiceOk(option)}">${option}</button> `)}</div><div class="${(this.boxType === 'alert' || this.boxType === 'info') ? 'confirm-buttons' : 'hidden'}"><button class="gg-button" onclick="${() => this.ok()}" i18n="Ok">Ok</button></div><div class="${this.boxType === 'confirm' ? 'confirm-buttons' : 'hidden'}"><button class="gg-button" onclick="${() => this.ok()}" i18n="Yes">Yes</button> <button class="gg-button" onclick="${() => this.nok()}" i18n="No">No</button></div><div class="${this.boxType === 'prompt' ? 'confirm-buttons' : 'hidden'}"><button class="gg-button" onclick="${() => this.promptOk()}" i18n="Ok">Ok</button> <button class="gg-button" onclick="${() => this.promptNok()}" i18n="Cancel">Cancel</button></div><div class="${this.boxType === 'choice' ? 'confirm-buttons' : 'hidden'}"><button class="gg-button" onclick="${() => this.promptNok()}" i18n="Cancel">Cancel</button></div></section></div></div>
|
|
15
15
|
${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
16
16
|
};
|
|
17
17
|
visible = false;
|
|
@@ -29,13 +29,13 @@ class PrintComponent extends GirafeHTMLElement {
|
|
|
29
29
|
#panel{min-width:20rem;height:100%;overflow:auto}#content{background:var(--bkg-color);color:var(--text-color);margin:0;padding:1.5rem}#content .message{text-align:center;width:100%}#content .message *{margin:.25rem}.option{margin-top:.5rem;display:flex}.option label{width:40%}.option label:after{content:" :"}.option input,.option select,.option textarea{flex-grow:1}.option input.gg-checkbox{flex-grow:0}.rotation{flex-grow:1;gap:.5rem;display:flex}#rotationSlider{width:0}#rotationNumber{flex-grow:0;width:4rem}#content #export-pdf{float:right;margin-top:1rem}#content button{background-color:var(--bkg-color);color:var(--text-color);border:solid 1px var(--text-color);cursor:pointer;border-radius:3px;outline:0}#content button:hover{background-color:var(--bkg-color-grad2)}#content #print-list{margin-top:5rem}#print-list .print-item{border:solid 1px var(--text-color);color:var(--text-color);margin-top:.5rem;padding:.5rem;position:relative}#print-list .print-item .container{text-align:unset;border:none;width:100%;display:inline}#print-list .print-item .cancel{cursor:pointer;color:var(--text-color-grad1);background-color:#0000;border:none;position:absolute;top:.5rem;right:.5rem}.print-item .cancel i:before{content:"uf00d"}.print-item .cancel:hover{border-color:var(--text-color);color:var(--text-color)}.print-item i.status{float:left;text-align:center;width:3rem;margin-right:1rem}.print-item:has(.success):hover{background-color:var(--bkg-color-grad2);cursor:pointer}.print-item i.status:before{line-height:3rem;display:block}.print-item p{line-height:1.3rem}.print-item p.time{margin-right:.5rem;position:absolute;bottom:0;right:0}#custom-scale{color:var(--text-color);flex-flow:wrap;justify-content:flex-start;align-items:center;display:flex}#custom-scale .svg-info{margin-left:.5rem}#custom-scale>div{align-items:center;width:100%;display:flex}.gg-custom-scale{justify-content:flex-end}.warning{border-top:1px solid #333;border-bottom:1px solid #333;margin-top:1rem;margin-bottom:1rem;padding:.5rem}.warning h3{margin:0 0 1rem;font-size:1rem}.warning span{display:block}
|
|
30
30
|
</style>
|
|
31
31
|
<style>${this.customStyle}</style>
|
|
32
|
-
<div id="panel"><div id="content"><div class="${this.getRenderState() === 'loading' ? '' : 'hidden'}"><div class="message"><div i18n="Connecting to the print server, please wait."></div><img alt="loading-icon" src="icons/loading.svg" class="gg-spin"></div></div><div class="${this.getRenderState() === 'error' ? '' : 'hidden'}"><div class="message" i18n="The print server is unavailable. Please, try later."></div></div><div class="${this.getRenderState() === 'setup' ? '' : 'hidden'}"><div class="option"><label for="layout" i18n="Layout" class="gg-label">Layout</label> <select id="layout" class="gg-select" onchange="${(evt) => this.onLayoutChanged(evt)}">${this.layouts.map((layout) => uHtml `<option i18n="${layout.name}" ?selected="${this.selectedLayout?.name === layout.name}" value="${layout.name}">${layout.name}</option>`)}</select></div><div class="option gg-custom-scale"><label for="scale" i18n="Scale" class="gg-label">Scale</label> <select id="scale" class="gg-select" onchange="${(evt) => this.onScaleChanged(evt)}">${this.scales.map((scale) => uHtml `<option ?selected="${this.getSelectedScale() === scale}" value="${scale}"><span>1 : </span><span i18n="${scale}" i18nfn="formatNumber">${scale}</span></option>`)}<option i18n="Manual entry" class="${this.context.configManager.Config.print?.customScale === true ? '' : 'hidden'}" value="custom">Manual entry</select></div><div class="${this.showCustomScale === true ? 'option' : 'hidden'}"><div id="custom-scale"><label for="scale" i18n="Custom scale" class="gg-label">Custom scale</label><div><span>1 : </span><input class="gg-input" type="number" min="10" oninput="${(evt) => this.onCustomScaleTyped(evt)}"></div></div></div><div class="option"><label for="format" i18n="Format" class="gg-label">Format</label> <select id="format" class="gg-select" onchange="${(evt) => this.onFormatChanged(evt)}">${this.printFormats.map((format) => uHtml `<option ?selected="${this.getSelectedFormat() === format}" value="${format}">${format.toUpperCase()}</option>`)}</select></div>${uHtml `<div class="option"><label for="dpi" class="gg-label">DPI</label> <select id="dpi" class="gg-select" onchange="${(evt) => this.onDpiChanged(evt)}">${this.dpis.map((dpi) => uHtml `<option ?selected="${this.getSelectedDpi() === dpi}" value="${dpi}">${dpi}</option>`)}</select></div>`}<div class="option"><label for="rotationSlider" i18n="Rotation" class="gg-label">Rotation</label><div class="rotation"><input id="rotationSlider" class="gg-range" type="range" min="-180" max="180" step="1" value="${this.getRotation()}" oninput="${(evt) => this.onInputRotationChanged(evt)}"> <input id="rotationNumber" class="gg-input" type="number" min="-180" max="180" step="1" value="${this.getRotation()}" oninput="${(evt) => this.onInputRotationChanged(evt)}"></div></div>${this.attributeNames.map((attrName) => { if (this.getAttributeInputType(attrName) === 'number') {
|
|
32
|
+
<div id="panel"><div id="content"><div class="${this.getRenderState() === 'loading' ? '' : 'hidden'}"><div class="message"><div i18n="Connecting to the print server, please wait."></div><img alt="loading-icon" src="icons/loading.svg" class="gg-spin"></div></div><div class="${this.getRenderState() === 'error' ? '' : 'hidden'}"><div class="message" i18n="The print server is unavailable. Please, try later."></div></div><div class="${this.getRenderState() === 'setup' ? '' : 'hidden'}"><div class="option"><label for="layout" i18n="Layout" class="gg-label">Layout</label> <select id="layout" class="gg-select" onchange="${(evt) => this.onLayoutChanged(evt)}">${this.layouts.map((layout) => uHtml `<option i18n="${layout.name}" ?selected="${this.selectedLayout?.name === layout.name}" value="${layout.name}">${layout.name}</option>`)}</select></div><div class="option gg-custom-scale"><label for="scale" i18n="Scale" class="gg-label">Scale</label> <select id="scale" class="gg-select" onchange="${(evt) => this.onScaleChanged(evt)}">${this.scales.map((scale) => uHtml `<option ?selected="${this.getSelectedScale() === scale}" value="${scale}"><span>1 : </span><span i18n="${scale}" i18nfn="formatNumber">${scale}</span></option>`)}<option i18n="Manual entry" class="${this.context.configManager.Config.print?.customScale === true ? '' : 'hidden'}" value="custom">Manual entry</select></div><div class="${this.showCustomScale === true ? 'option' : 'hidden'}"><div id="custom-scale"><label for="scale" i18n="Custom scale" class="gg-label">Custom scale</label><div><span>1 : </span><input class="gg-input" type="number" aria-label="Custom scale value" min="10" oninput="${(evt) => this.onCustomScaleTyped(evt)}"></div></div></div><div class="option"><label for="format" i18n="Format" class="gg-label">Format</label> <select id="format" class="gg-select" onchange="${(evt) => this.onFormatChanged(evt)}">${this.printFormats.map((format) => uHtml `<option ?selected="${this.getSelectedFormat() === format}" value="${format}">${format.toUpperCase()}</option>`)}</select></div>${uHtml `<div class="option"><label for="dpi" class="gg-label">DPI</label> <select id="dpi" class="gg-select" onchange="${(evt) => this.onDpiChanged(evt)}">${this.dpis.map((dpi) => uHtml `<option ?selected="${this.getSelectedDpi() === dpi}" value="${dpi}">${dpi}</option>`)}</select></div>`}<div class="option"><label for="rotationSlider" i18n="Rotation" class="gg-label">Rotation</label><div class="rotation"><input id="rotationSlider" class="gg-range" type="range" min="-180" max="180" step="1" value="${this.getRotation()}" oninput="${(evt) => this.onInputRotationChanged(evt)}"> <input id="rotationNumber" class="gg-input" type="number" aria-label="Rotation" min="-180" max="180" step="1" value="${this.getRotation()}" oninput="${(evt) => this.onInputRotationChanged(evt)}"></div></div>${this.attributeNames.map((attrName) => { if (this.getAttributeInputType(attrName) === 'number') {
|
|
33
33
|
return uHtml `<div class="option"><label for="${attrName}" i18n="${this.attrNameForI18n(attrName)}" class="gg-label">${attrName}</label> <input id="${attrName}" type="number" class="gg-input" value="${this.getCapabilitiesAttribute(attrName)?.default}"></div>`;
|
|
34
34
|
} if (this.getAttributeInputType(attrName) === 'checkbox') {
|
|
35
35
|
return uHtml `<div class="option"><label for="${attrName}" i18n="${this.attrNameForI18n(attrName)}" class="gg-label">${attrName}</label> <input id="${attrName}" type="checkbox" class="gg-checkbox" ?checked="${this.getCapabilitiesAttribute(attrName)?.default}"></div>`;
|
|
36
36
|
} if (this.getAttributeInputType(attrName) === 'textarea') {
|
|
37
|
-
return uHtml `<div class="option"><textarea id="${attrName}" class="gg-textarea" i18n="${this.attrNameForI18n(attrName)}" placeholder="${attrName}">${this.getCapabilitiesAttribute(attrName)?.default}</textarea></div>`;
|
|
38
|
-
} return uHtml `<div class="option"><input id="${this.attrNameForI18n(attrName)}" class="gg-input" i18n="${attrName}" placeholder="${attrName}" value="${this.getCapabilitiesAttribute(attrName)?.default}"></div>`; })}<div class="${this.hasRestrictedLayers ? 'warning' : 'hidden'}"><h3 i18n="Warning: Private Layers are active">Warning: Private Layers are active</h3><span i18n="Private layers are enabled and will be printed."></span> <span i18n="The generated document may contain sensitive data."></span> <span i18n="Please review or disable them before printing."></span></div><button id="export-pdf" class="gg-button" onclick="${() => this.print()}" i18n="Print">Print</button><div id="print-list">${this.printList.map((printItem) => uHtml `<div id="${printItem.id}" class="print-item" title="${printItem.elementTitle}"><button class="cancel" tabindex="0" onclick="${() => this.onCancelPrintElementClicked(printItem.id)}"><img alt="close-icon" src="icons/close.svg"></button> <button class="container" tabindex="0" onclick="${() => this.onPrintElementClicked(printItem.id)}"><img alt="loading-icon" src="icons/loading.svg" class="${printItem.status === PrintStatus.Started ? 'gg-spin' : 'hidden'}"> <img alt="loading-icon" src="icons/download.svg" class="${printItem.status === PrintStatus.Success ? '' : 'hidden'}"> <img alt="loading-icon" src="icons/error.svg" class="${printItem.status === PrintStatus.Errored ? '' : 'hidden'}"><p><span i18n="${printItem.selectedLayoutName}">${printItem.selectedLayoutName}</span> <span>(</span><span>${printItem.selectedFormat.toUpperCase()}</span><span>)</span><p class="time">${printItem.time}</button></div>`)}</div></div></div></div>
|
|
37
|
+
return uHtml `<div class="option"><textarea id="${attrName}" class="gg-textarea" i18n="${this.attrNameForI18n(attrName)}" aria-label="${attrName}" placeholder="${attrName}">${this.getCapabilitiesAttribute(attrName)?.default}</textarea></div>`;
|
|
38
|
+
} return uHtml `<div class="option"><input id="${this.attrNameForI18n(attrName)}" class="gg-input" i18n="${attrName}" aria-label="${attrName}" placeholder="${attrName}" value="${this.getCapabilitiesAttribute(attrName)?.default}"></div>`; })}<div class="${this.hasRestrictedLayers ? 'warning' : 'hidden'}"><h3 i18n="Warning: Private Layers are active">Warning: Private Layers are active</h3><span i18n="Private layers are enabled and will be printed."></span> <span i18n="The generated document may contain sensitive data."></span> <span i18n="Please review or disable them before printing."></span></div><button id="export-pdf" class="gg-button" onclick="${() => this.print()}" i18n="Print">Print</button><div id="print-list">${this.printList.map((printItem) => uHtml `<div id="${printItem.id}" class="print-item" title="${printItem.elementTitle}"><button class="cancel" tabindex="0" onclick="${() => this.onCancelPrintElementClicked(printItem.id)}"><img alt="close-icon" src="icons/close.svg"></button> <button class="container" tabindex="0" onclick="${() => this.onPrintElementClicked(printItem.id)}"><img alt="loading-icon" src="icons/loading.svg" class="${printItem.status === PrintStatus.Started ? 'gg-spin' : 'hidden'}"> <img alt="loading-icon" src="icons/download.svg" class="${printItem.status === PrintStatus.Success ? '' : 'hidden'}"> <img alt="loading-icon" src="icons/error.svg" class="${printItem.status === PrintStatus.Errored ? '' : 'hidden'}"><p><span i18n="${printItem.selectedLayoutName}">${printItem.selectedLayoutName}</span> <span>(</span><span>${printItem.selectedFormat.toUpperCase()}</span><span>)</span><p class="time">${printItem.time}</button></div>`)}</div></div></div></div>
|
|
39
39
|
${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
40
40
|
};
|
|
41
41
|
isPanelVisible = false;
|
|
@@ -125,7 +125,7 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
|
125
125
|
this.showCustomScale = false;
|
|
126
126
|
this.render();
|
|
127
127
|
}
|
|
128
|
-
this.state.print.scale = parseInt(event.target?.value);
|
|
128
|
+
this.state.print.scale = Number.parseInt(event.target?.value);
|
|
129
129
|
this.printMaskManager?.zoomToScale(this.state.print.scale);
|
|
130
130
|
}
|
|
131
131
|
/**
|
|
@@ -133,7 +133,7 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
|
133
133
|
* in the state and update the mask.
|
|
134
134
|
*/
|
|
135
135
|
onCustomScaleTyped(evt) {
|
|
136
|
-
const value = parseInt(evt.target?.value);
|
|
136
|
+
const value = Number.parseInt(evt.target?.value);
|
|
137
137
|
if (!value) {
|
|
138
138
|
return;
|
|
139
139
|
}
|
|
@@ -170,7 +170,7 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
|
170
170
|
*/
|
|
171
171
|
onDpiChanged(event) {
|
|
172
172
|
const value = event.target?.value;
|
|
173
|
-
this.state.print.dpi = value ? parseInt(value) : this.default_dpi;
|
|
173
|
+
this.state.print.dpi = value ? Number.parseInt(value) : this.default_dpi;
|
|
174
174
|
}
|
|
175
175
|
/**
|
|
176
176
|
* @returns {number} The rotation angle in degrees, from the map.
|
|
@@ -399,7 +399,7 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
|
399
399
|
setRotation(rotationInputElement, mapRotationValue = null) {
|
|
400
400
|
const slider = rotationInputElement.parentElement?.querySelector('#rotationSlider');
|
|
401
401
|
const number = rotationInputElement.parentElement?.querySelector('#rotationNumber');
|
|
402
|
-
const rotation = mapRotationValue ?? parseInt(rotationInputElement.value);
|
|
402
|
+
const rotation = mapRotationValue ?? Number.parseInt(rotationInputElement.value);
|
|
403
403
|
slider.value = `${rotation}`;
|
|
404
404
|
number.value = `${rotation}`;
|
|
405
405
|
if (!mapRotationValue) {
|
|
@@ -191,7 +191,7 @@ export class MFPLegendEncoder {
|
|
|
191
191
|
}
|
|
192
192
|
if (hiDPILegendImages) {
|
|
193
193
|
for (const str_dpi in hiDPILegendImages) {
|
|
194
|
-
const new_dpi = parseFloat(str_dpi);
|
|
194
|
+
const new_dpi = Number.parseFloat(str_dpi);
|
|
195
195
|
const new_dist = Math.abs(Math.log(new_dpi / dpi));
|
|
196
196
|
if (new_dist < dist) {
|
|
197
197
|
dist = new_dist;
|
|
@@ -17,7 +17,7 @@ class QueryBuilderComponent extends GirafeHTMLElement {
|
|
|
17
17
|
.container{background-color:var(--bkg-color)}.content{display:flex}.loading i,.deactivated i{margin:.8rem}
|
|
18
18
|
</style>
|
|
19
19
|
<style>${this.customStyle}</style>
|
|
20
|
-
<div class="container"><div class="${this.loading ? 'loading' : 'loading hidden'}"><img alt="loading-icon" src="icons/loading.svg" class="gg-spin"> <span i18n="Loading server configuration...">Loading server configuration...</span></div><div class="${this.deactivated ? 'deactivated' : 'deactivated hidden'}"><img alt="info-icon" src="icons/info.svg"> <span i18n="Filtering deactivated: layers in layergroup don't have identical attributes.">Filtering deactivated: layers in layergroup don't have identical attributes.</span></div><div class="${this.loading || this.deactivated ? 'content hidden' : 'content'}"><select id="attribute" name="attribute" class="gg-select gg-medium" onchange="${() => this.attributeChanged()}"><option value="" disabled="disabled" ?selected="${!this.currentLayerAttribute}" i18n="Select attribute...">Select attribute...</option>${this.layerAttributes.map(attr => uHtmlFor(attr, attr.name) `<option i18n="${this.layerAttributesTranslations[attr.name]}" value="${attr.name}" ?selected="${this.currentLayerAttribute?.name == attr.name}">${attr.name}</option>`)}</select> <select id="operator" name="operator" class="gg-select gg-medium" onchange="${() => this.operatorChanged()}"><option value="" disabled="disabled" selected="selected" i18n="Select operator...">Select operator...</option>${this.operatorOptions.map(option => uHtmlFor(option, option.operator) `<option i18n="${option.displayName}" value="${option.operator}">${option.displayName}</option>`)}</select> <input id="val" type="${this.inputTypeForFilterValue}" class="${this.showVal ? 'gg-input gg-medium' : 'hidden'}" placeholder="${this.showVal2 ? 'Enter lower boundary...' : 'Enter value...'}" onkeydown="${(e) => this.onValueKeyPress(e)}"> <input id="val2" type="${this.inputTypeForFilterValue}" class="${this.showVal2 ? 'gg-input gg-medium' : 'hidden'}" placeholder="Enter upper boundary..." onkeydown="${(e) => this.onValueKeyPress(e)}"> <button class="gg-icon-button gg-medium" tip="Apply filter" onclick="${() => this.filter()}"><img alt="filter-icon" src="icons/filter.svg"></button> <button class="gg-icon-button gg-medium" tip="Remove filter" onclick="${() => this.removeFilter()}"><img alt="delete-icon" src="icons/trash.svg"></button></div></div>
|
|
20
|
+
<div class="container"><div class="${this.loading ? 'loading' : 'loading hidden'}"><img alt="loading-icon" src="icons/loading.svg" class="gg-spin"> <span i18n="Loading server configuration...">Loading server configuration...</span></div><div class="${this.deactivated ? 'deactivated' : 'deactivated hidden'}"><img alt="info-icon" src="icons/info.svg"> <span i18n="Filtering deactivated: layers in layergroup don't have identical attributes.">Filtering deactivated: layers in layergroup don't have identical attributes.</span></div><div class="${this.loading || this.deactivated ? 'content hidden' : 'content'}"><select id="attribute" name="attribute" class="gg-select gg-medium" aria-label="Attribute" onchange="${() => this.attributeChanged()}"><option value="" disabled="disabled" ?selected="${!this.currentLayerAttribute}" i18n="Select attribute...">Select attribute...</option>${this.layerAttributes.map(attr => uHtmlFor(attr, attr.name) `<option i18n="${this.layerAttributesTranslations[attr.name]}" value="${attr.name}" ?selected="${this.currentLayerAttribute?.name == attr.name}">${attr.name}</option>`)}</select> <select id="operator" name="operator" class="gg-select gg-medium" aria-label="Operator" onchange="${() => this.operatorChanged()}"><option value="" disabled="disabled" selected="selected" i18n="Select operator...">Select operator...</option>${this.operatorOptions.map(option => uHtmlFor(option, option.operator) `<option i18n="${option.displayName}" value="${option.operator}">${option.displayName}</option>`)}</select> <input id="val" type="${this.inputTypeForFilterValue}" aria-label="Filter value" class="${this.showVal ? 'gg-input gg-medium' : 'hidden'}" placeholder="${this.showVal2 ? 'Enter lower boundary...' : 'Enter value...'}" onkeydown="${(e) => this.onValueKeyPress(e)}"> <input id="val2" type="${this.inputTypeForFilterValue}" aria-label="Upper boundary" class="${this.showVal2 ? 'gg-input gg-medium' : 'hidden'}" placeholder="Enter upper boundary..." onkeydown="${(e) => this.onValueKeyPress(e)}"> <button class="gg-icon-button gg-medium" tip="Apply filter" onclick="${() => this.filter()}"><img alt="filter-icon" src="icons/filter.svg"></button> <button class="gg-icon-button gg-medium" tip="Remove filter" onclick="${() => this.removeFilter()}"><img alt="delete-icon" src="icons/trash.svg"></button></div></div>
|
|
21
21
|
${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
22
22
|
};
|
|
23
23
|
loading = true;
|
|
@@ -120,7 +120,7 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
|
120
120
|
validateInput(val) {
|
|
121
121
|
if (val && isDate(this.currentLayerAttribute?.type || '')) {
|
|
122
122
|
const date = new Date(val);
|
|
123
|
-
if (isNaN(date.getTime())) {
|
|
123
|
+
if (Number.isNaN(date.getTime())) {
|
|
124
124
|
throw new Error('Invalid date value entered !');
|
|
125
125
|
}
|
|
126
126
|
}
|
|
@@ -9,7 +9,7 @@ class ScaleComponent extends GirafeHTMLElement {
|
|
|
9
9
|
.hidden{display:none!important}.gg-rotate90{transform:rotate(90deg)}.gg-rotate180{transform:rotate(180deg)}.gg-rotate270{transform:rotate(270deg)}img{filter:var(--svg-filter)}img.legend-image{filter:var(--svg-map-filter);background:var(--svg-legend-bkg)}div{scrollbar-width:thin}a,a:visited{color:var(--link-color)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes spin-wait{0%{transform:rotate(0)}7%{transform:rotate(360deg)}to{transform:rotate(360deg)}}.gg-spin{animation-name:spin;animation-duration:2s;animation-timing-function:linear;animation-iteration-count:infinite}.gg-spin-wait{animation-name:spin-wait;animation-duration:10s;animation-timing-function:linear;animation-iteration-count:infinite}::-webkit-scrollbar{width:5px}::-webkit-scrollbar-thumb{background:#999}button,input,select,textarea{font:inherit}.gg-button,.gg-select,.gg-input,.gg-textarea{background-color:var(--bkg-color);color:var(--text-color);border:var(--app-standard-border);box-sizing:border-box;cursor:pointer;border-radius:3px;outline:0;margin:0;padding:0 0 0 .5rem;display:inline-block}.gg-label{background-color:var(--bkg-color);color:var(--text-color);border:none;align-items:center;margin:0;padding:0;display:flex}.gg-button,.gg-select,.gg-input,.gg-label{min-height:calc(var(--app-standard-height) / 1.5)}.gg-textarea{max-height:initial;resize:vertical;height:6rem;padding:.5rem;line-height:1.3rem}.gg-input{cursor:text}.gg-checkbox{accent-color:var(--text-color);cursor:pointer;width:1.2rem}.gg-range{accent-color:var(--text-color)}.gg-button{padding:0 .5rem}.gg-button.active{border:solid 1px var(--text-color-grad1);background-color:var(--bkg-color-grad2)}.gg-button:disabled{background-color:var(--bkg-color-grad1);color:var(--text-color-grad2);cursor:not-allowed;border:none}.gg-button:disabled img{filter:opacity(.6)}.gg-input:disabled,.gg-select:disabled,.gg-textarea:disabled{background-color:var(--bkg-color-grad1);color:var(--text-color-grad2);cursor:not-allowed}.gg-button>img{vertical-align:middle}.gg-icon-button{color:var(--text-color);cursor:pointer;background-color:#0000;border:none;flex-direction:column;justify-content:center;align-items:center;padding:0;display:flex}.gg-icon{justify-content:center;align-items:center;display:flex}.gg-big,.gg-big-withtext{min-width:var(--app-standard-height);min-height:var(--app-standard-height);max-height:var(--app-standard-height)}.gg-big img,.gg-big-withtext img{width:calc(var(--app-standard-height) - 1.5rem);margin:0}.gg-big-withtext span{font-variant:small-caps;padding:0 1rem;font-size:.9rem}.gg-medium,.gg-medium-withtext{min-width:calc(var(--app-standard-height) / 1.2);min-height:calc(var(--app-standard-height) / 1.2);max-height:calc(var(--app-standard-height) / 1.2);flex-direction:row}.gg-medium img{width:calc(var(--app-standard-height) / 2.4);margin:0}.gg-medium-withtext img{width:calc(var(--app-standard-height) / 2.4);margin-left:.5rem}.gg-medium-withtext span{padding:0 1rem 0 .5rem;font-size:.9rem}.gg-small,.gg-small-withtext{min-width:calc(var(--app-standard-height) / 2);min-height:calc(var(--app-standard-height) / 2);max-height:calc(var(--app-standard-height) / 2);flex-direction:row}.gg-small img{width:calc(var(--app-standard-height) / 3);margin:0}.gg-small-withtext img{width:calc(var(--app-standard-height) / 3);margin-left:.5rem}.gg-small-withtext span{padding:0 .5rem 0 .3rem;font-size:.9rem}.gg-button:hover:not(:disabled),.gg-select:hover:not(:disabled),.gg-input:hover:not(:disabled),.gg-textarea:hover:not(:disabled),.gg-icon-button:hover:not(:disabled){background-color:var(--bkg-color-grad1)}.gg-opacity{opacity:.5}.gg-opacity:hover{opacity:1;background-color:#0000}.gg-tabs{cursor:pointer;grid-auto-flow:column;padding-bottom:1rem;font-size:1rem;display:grid}.gg-tab{border:none;border-bottom:var(--app-standard-border);cursor:pointer;color:var(--text-color);background:0 0;padding:.5rem}.gg-tab.active{border-bottom:solid 1px var(--text-color)}.girafe-button-big,.girafe-button-large,.girafe-button-small,.girafe-button-tiny{color:var(--text-color);background-color:#0000;border:none;flex-direction:column;display:flex}.girafe-button-big:hover,.girafe-button-large:hover,.girafe-button-small:hover,.girafe-button-tiny:hover{background-color:var(--bkg-color-grad1);cursor:pointer}.girafe-button-big.dark,.girafe-button-large.dark,.girafe-button-small.dark,.girafe-button-tiny.dark{background-color:var(--bkg-color);filter:invert()}.girafe-button-big{width:var(--app-standard-height);height:var(--app-standard-height);align-items:center;padding:1rem}.girafe-button-big img{overflow:hidden}.girafe-button-large{flex-direction:row}.girafe-button-large img{height:2rem;margin:.3rem}.girafe-button-large span{height:2rem;margin:.3rem;line-height:2rem}.girafe-button-small{min-width:calc(var(--app-standard-height) / 2);height:calc(var(--app-standard-height) / 2);align-items:center;padding:.5rem}.girafe-button-small img{overflow:hidden}.girafe-button-small span{text-align:left;text-overflow:ellipsis;width:100%;overflow:hidden}.girafe-button-tiny{align-items:center;width:1rem;height:1rem;padding:0}.girafe-button-tiny img{overflow:hidden}.girafe-onboarding-theme{background-color:var(--bkg-color)!important;color:var(--text-color)!important}.girafe-onboarding-theme button{background-color:var(--bkg-color)!important;color:var(--text-color)!important;text-shadow:none!important}.girafe-onboarding-theme button.driver-popover-close-btn{z-index:10000}.tippy-box{background-color:var(--bkg-color)!important;border:var(--app-standard-border)!important}.tippy-content{color:var(--text-color)!important}.tippy-arrow{color:var(--bkg-color)!important}.tippy-box[data-theme~=error]{background-color:var(--error-color);white-space:pre-line}div.tippy-box[data-theme=image-popup]{border:var(--app-standard-border)!important;& div.tippy-content{background-color:var(--bkg-color)!important;& img{max-width:20rem;max-height:20rem}}& div.tippy-arrow{color:var(--bkg-color)!important}}
|
|
10
10
|
</style>
|
|
11
11
|
<style>${this.customStyle}</style>
|
|
12
|
-
<select class="gg-select" onchange="${(e) => { this.state.position.scale = parseInt(e.target.value); }}">${this.context.configManager.Config.map.scales.map((scale) => uHtml `<option ?selected="${this.getFormatedScale() === this.getFormatedScale(scale)}" value="${scale}">${this.getFormatedScale(scale)}</option>`)}</select>
|
|
12
|
+
<select class="gg-select" aria-label="Map scale" onchange="${(e) => { this.state.position.scale = Number.parseInt(e.target.value); }}">${this.context.configManager.Config.map.scales.map((scale) => uHtml `<option ?selected="${this.getFormatedScale() === this.getFormatedScale(scale)}" value="${scale}">${this.getFormatedScale(scale)}</option>`)}</select>
|
|
13
13
|
${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
14
14
|
};
|
|
15
15
|
constructor() {
|
|
@@ -28,7 +28,7 @@ class SelectionWindowComponent extends GirafeDraggableElement {
|
|
|
28
28
|
table{border-collapse:collapse;table-layout:auto;width:100%}td.feature-id{text-align:left;color:var(--text-color);font-weight:600;line-height:2rem}td.label{text-align:left;color:var(--text-color);padding-left:.25rem;padding-right:.5rem;font-weight:600}tr.key-value{line-height:2rem}tr.key-value:nth-child(odd){background-color:var(--bkg-color-grad1)}tr.key-value:nth-child(2n){background-color:var(--bkg-color)}button{background-color:unset;color:var(--text-color-grad1);cursor:pointer;border:none;flex-grow:.25;padding:.5rem}button.showing-dropdown{background-color:var(--bkg-color-grad1)}button:disabled:hover{background-color:var(--bkg-color);cursor:default}button>img{max-height:calc(var(--selection-window-header-height) / 2)}#previous i{float:left}#next i{float:right}#tools{justify-content:space-around;display:flex}#counter{line-height:var(--selection-window-footer-height);height:var(--selection-window-footer-height);text-align:center;flex-grow:1;margin-top:0}#layers-dropdown{background-color:var(--bkg-color);border:solid 1px var(--bkg-color-grad2);top:var(--selection-window-header-height);flex-direction:column;padding:.5rem 0;display:flex;position:absolute}option.layers-dropdown-item{cursor:pointer;flex-grow:1;padding:.1rem .5rem;display:flex}option.layers-dropdown-item:hover{background-color:var(--bkg-color-grad1)}
|
|
29
29
|
</style>
|
|
30
30
|
<style>${this.customStyle}</style>
|
|
31
|
-
<div id="draggable" class="${this.visible ? 'girafe-draggable-window' : 'hidden'}"><button tabindex="-1" class="girafe-resizer tl corner"></button> <button tabindex="-1" class="girafe-resizer t top-bottom"></button> <button tabindex="-1" class="girafe-resizer tr corner"></button> <button tabindex="-1" class="girafe-resizer r left-right"></button> <button tabindex="-1" class="girafe-resizer br corner"></button> <button tabindex="-1" class="girafe-resizer b top-bottom"></button> <button tabindex="-1" class="girafe-resizer bl corner"></button> <button tabindex="-1" class="girafe-resizer l left-right"></button><div id="header"><span i18n="Results" class="title"></span><div id="layers-download-wrapper"><button class="${this.showDropdown ? 'gg-icon-button gg-medium showing-dropdown' : 'gg-icon-button gg-medium'}" onclick="${() => this.openDropdown()}" tip="Generate CSV"><img alt="download csv icon" src="icons/arrow-download.svg"></button><div ?hidden="${!this.showDropdown}"><div id="layers-dropdown">${this.getLayersList().map((layer) => uHtml `<option class="layers-dropdown-item" value="${layer.id}" onclick="${() => this.generateCSV(layer.id)}" onkeydown="${() => this.generateCSV(layer.id)}" tabindex="0" i18n="${layer.label}"></option>`)}</div></div></div><girafe-get-directions></girafe-get-directions><button class="gg-icon-button gg-medium" onclick="${() => this.recenter()}" tip="Zoom to"><img alt="zoom to selection icon" src="icons/zoom-to-selection.svg"></button> <button class="gg-icon-button gg-medium" onclick="${() => this.closeWindow()}" tip="Clear results and close Panel"><img alt="close-icon" src="icons/close.svg"></button></div><div class="hr"></div><div id="content"><div><table><tr class="hidden"><th i18n="Label">Label<th i18n="Value">Value<tr><td class="feature-id" colspan="2" i18n="${this.getWindowFeature()?.id}"></tr>${this.displayedProperties.map((keyValue) => uHtml `<tr class="key-value"><td class="label" i18n="${keyValue[0]}"><td class="value">${this.htmlUnsafe(keyValue[1])}</tr>`)}</table></div></div><div class="hr"></div><div id="footer"><button id="beginning" class="gg-icon-button gg-medium" ?disabled="${this.maxIndex == 0 || this.focusedIndex == 0}" onclick="${() => this.onFocusWindowFeature(0)}"><img alt="beginning-icon" src="icons/skip-to-beginning.svg"></button> <button id="previous" class="gg-icon-button gg-medium" ?disabled="${this.maxIndex == 0 || this.focusedIndex == 0}" onclick="${() => this.onFocusWindowFeature(this.focusedIndex - 1)}"><img alt="previous-icon" src="icons/to-previous.svg"></button><div id="counter" class="${this.maxIndex > 0 ? '' : 'hidden'}"><span class="${this.maxIndex > 0 ? '' : 'hidden'}"><input class="gg-input" type="number" min="1" max="${this.maxIndex + 1}" value="${this.focusedIndex + 1}" onchange="${(e) => this.onFocusWindowFeatureChecked(e)}"> <span>/</span> <span>${this.maxIndex + 1}</span></span></div><button id="next" class="gg-icon-button gg-medium" ?disabled="${this.maxIndex == 0 || this.focusedIndex == this.maxIndex}" onclick="${() => this.onFocusWindowFeature(this.focusedIndex + 1)}"><img alt="next-icon" src="icons/to-next.svg"></button> <button id="end" class="gg-icon-button gg-medium" ?disabled="${this.maxIndex == 0 || this.focusedIndex == this.maxIndex}" onclick="${() => this.onFocusWindowFeature(this.maxIndex)}"><img alt="end-icon" src="icons/skip-to-end.svg"></button></div></div>
|
|
31
|
+
<div id="draggable" class="${this.visible ? 'girafe-draggable-window' : 'hidden'}"><button tabindex="-1" class="girafe-resizer tl corner"></button> <button tabindex="-1" class="girafe-resizer t top-bottom"></button> <button tabindex="-1" class="girafe-resizer tr corner"></button> <button tabindex="-1" class="girafe-resizer r left-right"></button> <button tabindex="-1" class="girafe-resizer br corner"></button> <button tabindex="-1" class="girafe-resizer b top-bottom"></button> <button tabindex="-1" class="girafe-resizer bl corner"></button> <button tabindex="-1" class="girafe-resizer l left-right"></button><div id="header"><span i18n="Results" class="title"></span><div id="layers-download-wrapper"><button class="${this.showDropdown ? 'gg-icon-button gg-medium showing-dropdown' : 'gg-icon-button gg-medium'}" onclick="${() => this.openDropdown()}" tip="Generate CSV"><img alt="download csv icon" src="icons/arrow-download.svg"></button><div ?hidden="${!this.showDropdown}"><div id="layers-dropdown">${this.getLayersList().map((layer) => uHtml `<option class="layers-dropdown-item" value="${layer.id}" onclick="${() => this.generateCSV(layer.id)}" onkeydown="${() => this.generateCSV(layer.id)}" tabindex="0" i18n="${layer.label}"></option>`)}</div></div></div><girafe-get-directions></girafe-get-directions><button class="gg-icon-button gg-medium" onclick="${() => this.recenter()}" tip="Zoom to"><img alt="zoom to selection icon" src="icons/zoom-to-selection.svg"></button> <button class="gg-icon-button gg-medium" onclick="${() => this.closeWindow()}" tip="Clear results and close Panel"><img alt="close-icon" src="icons/close.svg"></button></div><div class="hr"></div><div id="content"><div><table><tr class="hidden"><th i18n="Label">Label<th i18n="Value">Value<tr><td class="feature-id" colspan="2" i18n="${this.getWindowFeature()?.id}"></tr>${this.displayedProperties.map((keyValue) => uHtml `<tr class="key-value"><td class="label" i18n="${keyValue[0]}"><td class="value">${this.htmlUnsafe(keyValue[1])}</tr>`)}</table></div></div><div class="hr"></div><div id="footer"><button id="beginning" class="gg-icon-button gg-medium" ?disabled="${this.maxIndex == 0 || this.focusedIndex == 0}" onclick="${() => this.onFocusWindowFeature(0)}"><img alt="beginning-icon" src="icons/skip-to-beginning.svg"></button> <button id="previous" class="gg-icon-button gg-medium" ?disabled="${this.maxIndex == 0 || this.focusedIndex == 0}" onclick="${() => this.onFocusWindowFeature(this.focusedIndex - 1)}"><img alt="previous-icon" src="icons/to-previous.svg"></button><div id="counter" class="${this.maxIndex > 0 ? '' : 'hidden'}"><span class="${this.maxIndex > 0 ? '' : 'hidden'}"><input class="gg-input" type="number" aria-label="Feature index" min="1" max="${this.maxIndex + 1}" value="${this.focusedIndex + 1}" onchange="${(e) => this.onFocusWindowFeatureChecked(e)}"> <span>/</span> <span>${this.maxIndex + 1}</span></span></div><button id="next" class="gg-icon-button gg-medium" ?disabled="${this.maxIndex == 0 || this.focusedIndex == this.maxIndex}" onclick="${() => this.onFocusWindowFeature(this.focusedIndex + 1)}"><img alt="next-icon" src="icons/to-next.svg"></button> <button id="end" class="gg-icon-button gg-medium" ?disabled="${this.maxIndex == 0 || this.focusedIndex == this.maxIndex}" onclick="${() => this.onFocusWindowFeature(this.maxIndex)}"><img alt="end-icon" src="icons/skip-to-end.svg"></button></div></div>
|
|
32
32
|
${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
33
33
|
};
|
|
34
34
|
eventsCallbacks = [];
|
|
@@ -16,7 +16,7 @@ class ShareComponent extends GirafeHTMLElement {
|
|
|
16
16
|
#content{background:var(--bkg-color);color:var(--text-color);margin:0;padding:1rem}.group{padding-bottom:4em}.title{margin-top:0}.link{flex-direction:column;gap:.2rem;margin-top:.5rem;display:flex;& button{padding-top:.25rem;padding-bottom:.25rem}}.qrcode{opacity:.7;width:10rem;margin:2rem auto auto;display:block}.qrcode-placeholder{content:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=);width:10rem;height:10rem;margin:2rem auto auto;display:block}.social{display:flex}.social button{cursor:pointer;background-color:#0000;border:none;margin:2rem auto auto}.social img{opacity:.7;width:3rem;filter:var(--svg-filter)}.social img:hover{opacity:1}input{flex-grow:1;font-size:.9rem}.error{color:var(--error-color);text-align:center;order:3;width:90%}.textarea-for-code{font-family:monospace,Arial,sans-serif;font-size:.75rem;line-height:1.1rem}.copy-success,.copy-success:hover{background-color:var(--success-color)}.checkbox-wrapper{flex-direction:row;justify-content:space-between;align-items:center;height:2rem;display:flex;& input[type=checkbox]{flex-grow:unset}}.disabled{opacity:.25;pointer-events:none}.enabled{opacity:1;pointer-events:unset}.icon-loading{content:url(icons/3-dots-fade.svg)}.icon-copy{content:url(icons/content_copy.svg);margin:1px}
|
|
17
17
|
</style>
|
|
18
18
|
<style>${this.customStyle}</style>
|
|
19
|
-
<div id="panel"><div id="content"><div class="${!this.urlShortener ? '' : 'hidden'}"><div class="message" i18n="Error, the shortener service is not defined.">Error, the shortener service is not defined.</div></div><div id="share-map" class="${this.urlShortener ? 'group' : 'hidden'}"><h3 class="title" i18n="Share this map">Share this map</h3><div class="${this.awaitingShareLink ? 'disabled' : 'enabled'}"><div class="link"><input value="${this.shareLink}" class="gg-input" disabled="disabled"> <button id="btn-copy-short" class="gg-button" onclick="${() => this.generateAndCopyLink()}"><img alt="loading/copy" src="" class="${this.awaitingShareLink ? 'icon-loading' : 'icon-copy'}" width="20" height="20"> <span i18n="${this.awaitingShareLink ? 'Generating link' : (!this.shareLink ? 'Generate and copy link' : 'Copy to Clipboard')}"></span></button></div><img alt="share-qrcode" class="${(this.qrCode ? 'qrcode' : 'qrcode-placeholder')}" src="${this.qrCode}"><div class="${(this.success ? 'hidden' : 'qrcode error')}"><img alt="error-icon" src="icons/error.svg"> <span i18n="Error, can not fetch the shortener service. Please try again later.">Error, can not fetch the shortener service. Please try again later.</span></div><div class="social"><button onclick="${() => this.shareFacebook()}"><img alt="share-facebook" src="${this.facebookLogo}"></button> <button onclick="${() => this.shareTwitter()}"><img alt="share-twitter" src="${this.twitterLogo}"></button> <button onclick="${() => this.shareLinkedIn()}"><img alt="share-linkedin" src="${this.linkedInLogo}"></button> <button onclick="${() => this.shareMail()}"><img alt="share-mail" src="${this.mailLogo}"></button></div></div></div><div id="embed-map" class="${this.urlShortener ? 'group' : 'hidden'}"><h3 class="title" i18n="Embed this map">Embed this map</h3><div class="link"><select class="gg-select" id="logLevel" onchange="${(evt) => this.onSizeChanged(evt)}"><option ?selected="${this.iframeSize === ''}" i18n="Select map size..." value="">Select map size...<option ?selected="${this.iframeSize === 'small'}" i18n="Small" value="small">Small<option ?selected="${this.iframeSize === 'medium'}" i18n="Medium" value="medium">Medium<option ?selected="${this.iframeSize === 'large'}" i18n="Large" value="large">Large</select><div class="checkbox-wrapper"><label for="iframe-search-visible" i18n="Search visible">Search visible</label> <input type="checkbox" class="gg-checkbox" id="iframe-search-visible" value="${this.shareState.searchComponentVisible}" onchange="${(e) => this.shareState.searchComponentVisible = e.target.checked}"></div><div class="checkbox-wrapper"><label for="iframe-basemap-visible" i18n="Basemap visible">Basemap visible</label> <input type="checkbox" class="gg-checkbox" id="iframe-basemap-visible" value="${this.shareState.basemapComponentVisible}" onchange="${(e) => this.shareState.basemapComponentVisible = e.target.checked}"></div><textarea value="${this.iframeCode}" class="gg-input gg-textarea textarea-for-code" disabled="disabled"></textarea> <button id="btn-copy-iframe" class="gg-button" ?disabled="${this.iframeSize === ''}" onclick="${() => this.generateAndCopyIframeCode()}"><img alt="loading/copy" src="" class="${this.awaitingIframeUrl ? 'icon-loading' : 'icon-copy'}" width="20" height="20"> <span i18n="${this.awaitingIframeUrl ? 'Generating code' : 'Generate and copy code'}"></span></button></div></div></div></div>
|
|
19
|
+
<div id="panel"><div id="content"><div class="${!this.urlShortener ? '' : 'hidden'}"><div class="message" i18n="Error, the shortener service is not defined.">Error, the shortener service is not defined.</div></div><div id="share-map" class="${this.urlShortener ? 'group' : 'hidden'}"><h3 class="title" i18n="Share this map">Share this map</h3><div class="${this.awaitingShareLink ? 'disabled' : 'enabled'}"><div class="link"><input aria-label="Share link" value="${this.shareLink}" class="gg-input" disabled="disabled"> <button id="btn-copy-short" class="gg-button" onclick="${() => this.generateAndCopyLink()}"><img alt="loading/copy" src="" class="${this.awaitingShareLink ? 'icon-loading' : 'icon-copy'}" width="20" height="20"> <span i18n="${this.awaitingShareLink ? 'Generating link' : (!this.shareLink ? 'Generate and copy link' : 'Copy to Clipboard')}"></span></button></div><img alt="share-qrcode" class="${(this.qrCode ? 'qrcode' : 'qrcode-placeholder')}" src="${this.qrCode}"><div class="${(this.success ? 'hidden' : 'qrcode error')}"><img alt="error-icon" src="icons/error.svg"> <span i18n="Error, can not fetch the shortener service. Please try again later.">Error, can not fetch the shortener service. Please try again later.</span></div><div class="social"><button onclick="${() => this.shareFacebook()}"><img alt="share-facebook" src="${this.facebookLogo}"></button> <button onclick="${() => this.shareTwitter()}"><img alt="share-twitter" src="${this.twitterLogo}"></button> <button onclick="${() => this.shareLinkedIn()}"><img alt="share-linkedin" src="${this.linkedInLogo}"></button> <button onclick="${() => this.shareMail()}"><img alt="share-mail" src="${this.mailLogo}"></button></div></div></div><div id="embed-map" class="${this.urlShortener ? 'group' : 'hidden'}"><h3 class="title" i18n="Embed this map">Embed this map</h3><div class="link"><select class="gg-select" id="logLevel" aria-label="Map size" onchange="${(evt) => this.onSizeChanged(evt)}"><option ?selected="${this.iframeSize === ''}" i18n="Select map size..." value="">Select map size...<option ?selected="${this.iframeSize === 'small'}" i18n="Small" value="small">Small<option ?selected="${this.iframeSize === 'medium'}" i18n="Medium" value="medium">Medium<option ?selected="${this.iframeSize === 'large'}" i18n="Large" value="large">Large</select><div class="checkbox-wrapper"><label for="iframe-search-visible" i18n="Search visible">Search visible</label> <input type="checkbox" class="gg-checkbox" id="iframe-search-visible" value="${this.shareState.searchComponentVisible}" onchange="${(e) => this.shareState.searchComponentVisible = e.target.checked}"></div><div class="checkbox-wrapper"><label for="iframe-basemap-visible" i18n="Basemap visible">Basemap visible</label> <input type="checkbox" class="gg-checkbox" id="iframe-basemap-visible" value="${this.shareState.basemapComponentVisible}" onchange="${(e) => this.shareState.basemapComponentVisible = e.target.checked}"></div><textarea value="${this.iframeCode}" class="gg-input gg-textarea textarea-for-code" aria-label="Embed code" disabled="disabled"></textarea> <button id="btn-copy-iframe" class="gg-button" ?disabled="${this.iframeSize === ''}" onclick="${() => this.generateAndCopyIframeCode()}"><img alt="loading/copy" src="" class="${this.awaitingIframeUrl ? 'icon-loading' : 'icon-copy'}" width="20" height="20"> <span i18n="${this.awaitingIframeUrl ? 'Generating code' : 'Generate and copy code'}"></span></button></div></div></div></div>
|
|
20
20
|
${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
21
21
|
};
|
|
22
22
|
isPanelVisible = false;
|
|
@@ -13,7 +13,7 @@ class MobileSelectedLayerElementComponent extends MobileLayerElementComponent {
|
|
|
13
13
|
.container{border-bottom:1px solid #ddd;flex-direction:column;padding-top:.5rem;padding-bottom:.5rem;display:flex}header{align-items:center;display:flex}section.options{align-items:center;gap:1rem;width:100%;margin-bottom:.5rem;display:flex}.slider{flex-grow:1}.legend-icon{background:var(--svg-legend-bkg);max-height:1.5rem;filter:var(--svg-map-filter);margin-left:.5rem}
|
|
14
14
|
</style>
|
|
15
15
|
<style>${this.customStyle}</style>
|
|
16
|
-
<div class="container"><header><button class="${this.layer?.active ? 'gg-icon-button gg-small gg-selected' : 'gg-icon-button gg-small'}" tip="Activate / Deactivate" onclick="${() => this.toggle()}"><img class="${this.layer?.active ? 'gg-checkbox' : 'hidden'}" alt="Expand/Collapse button" src="icons/checked-full.svg"> <img class="${!this.layer?.active ? 'gg-checkbox' : 'hidden'}" alt="Expand/Collapse button" src="icons/checked-no.svg"></button><div class="label-container"><button class="${this.layer?.active ? 'gg-button gg-small gg-selected' : 'gg-button gg-small'}" onclick="${() => this.toggle()}"><span i18n="${this.layer?.name}" class="gg-tree-label">${this.layer?.name}</span></button></div><img class="${this.layer?.active && this.iconUrl ? 'legend-icon' : 'hidden'}" alt="${'Icon for ' + this.layer?.name}" src="${this.iconUrl}" crossorigin="${this.getCrossOrigin(this.iconUrl)}"></header><section class="options"><input type="range" class="gg-range" min="0" max="20" value="${((this.layer?.opacity ?? 1) * 20).toString()}" oninput="${(event) => this.layer.opacity = parseInt(event.target.value) / 20}"> <a href="${this.layer?.metadataUrl}" target="_blank" class="${this.layer?.hasMetadata ? 'tool' : 'hidden'}"><img alt="Metadata" src="icons/info.svg"> </a><a href="javascript:void(0)" onclick="${() => this.layer.swiped = (this.layer?.swiped === 'left') ? 'no' : 'left'}"><img alt="Swipe layer to the left" src="icons/swipe-left.svg"> </a><a href="javascript:void(0)" onclick="${() => this.layer.swiped = (this.layer?.swiped === 'right') ? 'no' : 'right'}"><img alt="Swipe layer to the right" src="icons/swipe-right.svg"> </a><a href="${this.firstLegendUrl ?? '#'}" target="_blank" class="${this.firstLegendUrl ? 'tool' : 'hidden'}"><img alt="Metadata" src="icons/legend.svg"></a></section></div>
|
|
16
|
+
<div class="container"><header><button class="${this.layer?.active ? 'gg-icon-button gg-small gg-selected' : 'gg-icon-button gg-small'}" tip="Activate / Deactivate" onclick="${() => this.toggle()}"><img class="${this.layer?.active ? 'gg-checkbox' : 'hidden'}" alt="Expand/Collapse button" src="icons/checked-full.svg"> <img class="${!this.layer?.active ? 'gg-checkbox' : 'hidden'}" alt="Expand/Collapse button" src="icons/checked-no.svg"></button><div class="label-container"><button class="${this.layer?.active ? 'gg-button gg-small gg-selected' : 'gg-button gg-small'}" onclick="${() => this.toggle()}"><span i18n="${this.layer?.name}" class="gg-tree-label">${this.layer?.name}</span></button></div><img class="${this.layer?.active && this.iconUrl ? 'legend-icon' : 'hidden'}" alt="${'Icon for ' + this.layer?.name}" src="${this.iconUrl}" crossorigin="${this.getCrossOrigin(this.iconUrl)}"></header><section class="options"><input type="range" aria-label="Opacity" class="gg-range" min="0" max="20" value="${((this.layer?.opacity ?? 1) * 20).toString()}" oninput="${(event) => this.layer.opacity = Number.parseInt(event.target.value) / 20}"> <a href="${this.layer?.metadataUrl}" target="_blank" class="${this.layer?.hasMetadata ? 'tool' : 'hidden'}"><img alt="Metadata" src="icons/info.svg"> </a><a href="javascript:void(0)" onclick="${() => this.layer.swiped = (this.layer?.swiped === 'left') ? 'no' : 'left'}"><img alt="Swipe layer to the left" src="icons/swipe-left.svg"> </a><a href="javascript:void(0)" onclick="${() => this.layer.swiped = (this.layer?.swiped === 'right') ? 'no' : 'right'}"><img alt="Swipe layer to the right" src="icons/swipe-right.svg"> </a><a href="${this.firstLegendUrl ?? '#'}" target="_blank" class="${this.firstLegendUrl ? 'tool' : 'hidden'}"><img alt="Metadata" src="icons/legend.svg"></a></section></div>
|
|
17
17
|
${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
18
18
|
};
|
|
19
19
|
iconUrl = null;
|
|
@@ -17,7 +17,7 @@ class TimePickerComponent extends TimeWidget {
|
|
|
17
17
|
#container{margin-right:.5rem;display:flex}
|
|
18
18
|
</style>
|
|
19
19
|
<style>${this.customStyle}</style>
|
|
20
|
-
<div id="container"><input id="input-lower" class="gg-select gg-medium"> <input id="input-upper" class="gg-select gg-medium"></div>
|
|
20
|
+
<div id="container"><input id="input-lower" aria-label="Start time" class="gg-select gg-medium"> <input id="input-upper" aria-label="End time" class="gg-select gg-medium"></div>
|
|
21
21
|
${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
22
22
|
};
|
|
23
23
|
constructor() {
|
|
@@ -20,7 +20,7 @@ class TimeSliderComponent extends TimeWidget {
|
|
|
20
20
|
#container{--slider-color:var(--text-color);--slider-disabled-color:var(--text-color-grad2);--slider-highlight-color:var(--bkg-color-grad2);--slider-width:170px;--track-width:calc(var(--slider-width) - var(--thumb-width));--thumb-width:19px;--margin-left:calc(var(--thumb-width) / 2);--slider-track-height:9px;--thumb-margin-top:calc(-.5 * var(--thumb-width) + .5 * var(--slider-track-height));--slider-track-border-color:var(--text-color-grad2);--slider-track-outside-color:var(--bkg-color-grad2);--slider-track-inside-color:var(--text-color);color:var(--text-color);flex-direction:column;margin:.5rem 0 0 .5rem;display:flex}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;pointer-events:all;width:var(--thumb-width);height:var(--thumb-width);margin-top:var(--thumb-margin-top);background:var(--slider-color);border:1px solid var(--slider-highlight-color);cursor:pointer;border-radius:50%;box-shadow:1px 1px 2px #9c9c9c}input[type=range]::-webkit-slider-thumb:hover{box-shadow:inset 0 0 2px 0 var(--slider-highlight-color), 0 0 4px var(--slider-highlight-color);border-color:var(--bkg-color)}input[type=range]::-webkit-slider-thumb:active{box-shadow:inset 0 0 2px 0 var(--slider-highlight-color), 0 0 4px var(--slider-highlight-color);-webkit-box-shadow:inset 0 0 2px 0 var(--slider-highlight-color), 0 0 4px var(--slider-highlight-color);border-color:var(--bkg-color)}input[type=range]::-webkit-slider-runnable-track{height:var(--slider-track-height)}input[type=range]::-moz-range-thumb{-webkit-appearance:none;pointer-events:all;width:var(--thumb-width);height:var(--thumb-width);margin-top:var(--thumb-margin-top);background:var(--slider-color);border:1px solid var(--slider-highlight-color);cursor:pointer;border-radius:50%}input[type=range]::-moz-range-thumb:hover{box-shadow:inset 0 0 2px 0 var(--slider-highlight-color), 0 0 4px var(--slider-highlight-color);border-color:var(--bkg-color)}input[type=range]::-moz-range-thumb:active{box-shadow:inset 0 0 2px 0 var(--slider-highlight-color), 0 0 4px var(--slider-highlight-color);-webkit-box-shadow:inset 0 0 2px 0 var(--slider-highlight-color), 0 0 4px var(--slider-highlight-color);border-color:var(--bkg-color)}input[type=range]::-moz-range-track{height:var(--slider-track-height)}input[type=range]{-webkit-appearance:none;appearance:none;height:var(--slider-track-height);width:var(--slider-width);pointer-events:none;z-index:2;background-color:#0000;margin:0}#input-upper{position:absolute}#slider-track{width:var(--track-width);margin-left:var(--margin-left);height:var(--slider-track-height);cursor:pointer;pointer-events:all;z-index:0;border:1px solid var(--slider-track-border-color);border-radius:3px;position:absolute}.slider-label{width:var(--track-width);margin:calc(.25 * var(--thumb-width)) 0 0 var(--margin-left);border:1px solid #0000;justify-content:space-around;align-items:center;line-height:1em;display:flex}.slider-label.editable{margin-top:calc(.5 * var(--thumb-width));margin-bottom:.3rem}.slider-label>input{text-align:center;max-width:80px;padding:0;line-height:1em}.slider-label>input::-webkit-outer-spin-button,.slider-label>input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.slider-label>input[type=number]{-moz-appearance:textfield}.slider-label>input:disabled{border-color:#0000}.slider-label>input:disabled:hover{background-color:initial;cursor:default}.slider-label>div{margin:0 2px}
|
|
21
21
|
</style>
|
|
22
22
|
<style>${this.customStyle}</style>
|
|
23
|
-
<div id="container"><input id="input-lower" type="range" min="0" max="1" step="1"> <input id="input-upper" type="range" min="0" max="1" step="1"><div id="slider-track"></div><div class="${this.resolution === 'year' ? 'slider-label editable' : 'slider-label'}"><input id="output-label-lower" disabled="disabled" class="gg-input gg-small"><div class="${this.mode === 'range' ? '' : 'hidden'}">/</div><input id="output-label-upper" disabled="disabled" class="${this.mode === 'range' ? 'gg-input gg-small' : 'hidden'}"></div></div>
|
|
23
|
+
<div id="container"><input id="input-lower" type="range" aria-label="Start time" min="0" max="1" step="1"> <input id="input-upper" type="range" aria-label="End time" min="0" max="1" step="1"><div id="slider-track"></div><div class="${this.resolution === 'year' ? 'slider-label editable' : 'slider-label'}"><input id="output-label-lower" disabled="disabled" aria-label="Start time value" class="gg-input gg-small"><div class="${this.mode === 'range' ? '' : 'hidden'}">/</div><input id="output-label-upper" disabled="disabled" aria-label="End time value" class="${this.mode === 'range' ? 'gg-input gg-small' : 'hidden'}"></div></div>
|
|
24
24
|
${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
25
25
|
};
|
|
26
26
|
discreteTimeSteps;
|
|
@@ -208,8 +208,8 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
|
208
208
|
const maxPosition = this.countSliderStepsInRange();
|
|
209
209
|
if (this.mode !== 'range' || maxPosition === 0)
|
|
210
210
|
return;
|
|
211
|
-
const lowVal = (100 * parseInt(this.lowerInputElem.value)) / maxPosition;
|
|
212
|
-
const highVal = (100 * (this.mode === 'range' ? parseInt(this.upperInputElem.value) : maxPosition)) / maxPosition;
|
|
211
|
+
const lowVal = (100 * Number.parseInt(this.lowerInputElem.value)) / maxPosition;
|
|
212
|
+
const highVal = (100 * (this.mode === 'range' ? Number.parseInt(this.upperInputElem.value) : maxPosition)) / maxPosition;
|
|
213
213
|
const sliderTrackElem = this.getById('slider-track');
|
|
214
214
|
const outCol = 'var(--slider-track-outside-color)';
|
|
215
215
|
const inCol = 'var(--slider-track-inside-color)';
|
|
@@ -317,7 +317,7 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
|
317
317
|
* @throws {Error} If the resolution is invalid.
|
|
318
318
|
*/
|
|
319
319
|
sliderPositionToDateString(position) {
|
|
320
|
-
if (position === '' || isNaN(Number(position)))
|
|
320
|
+
if (position === '' || Number.isNaN(Number(position)))
|
|
321
321
|
return '';
|
|
322
322
|
const increment = Number(position);
|
|
323
323
|
const oneDayInMillis = 1000 * 60 * 60 * 24;
|
|
@@ -25,7 +25,7 @@ class TreeViewRootComponent extends GirafeHTMLElement {
|
|
|
25
25
|
.panel{background:var(--bkg-color);flex-direction:column-reverse;display:flex;position:absolute;inset:0}.menu{z-index:1;border-top:1px solid #bbb;display:flex}.treeview-list,.treeview-no-data{flex-grow:1;overflow:hidden auto}.treeview-search{background-color:var(--bkg-color);border:1px solid #cfd6dd;border-radius:4px;flex-direction:row;flex-grow:1;align-self:center;width:auto;margin-right:2px;display:flex}#treeview-search-field{width:90%;color:var(--text-color);background:0 0;border:0;outline:none;flex:auto;padding:0;font-size:1rem}.filter-icon,.delete-icon{width:16px;color:var(--text-color);padding:0 .5rem}.delete-button{cursor:pointer;background-color:#0000;border:none;padding:0}.treeview-no-data{justify-content:center;align-items:center;display:flex}.treeview-loading{flex-direction:column;justify-content:center;align-items:center;display:flex}img:-moz-loading{visibility:hidden}.no-data{color:#999;text-align:center;align-items:anchor-center;font-variant:small-caps;flex-direction:column;gap:.3rem;font-size:1rem;display:flex}.no-data span{flex-grow:1;display:block}
|
|
26
26
|
</style>
|
|
27
27
|
<style>${this.customStyle}</style>
|
|
28
|
-
<div id="panel" class="panel"><div class="menu"><button class="gg-icon-button gg-medium" tip="Expand / Collapse all" onclick="${() => this.expandAll()}"><img class="${this.isAllExpanded ? '' : 'hidden'}" alt="Collapse all icon" src="icons/collapse-all.svg"> <img class="${this.isAllExpanded ? 'hidden' : ''}" alt="Expand all icon" src="icons/expand-all.svg"></button> <button class="gg-icon-button gg-medium" tip="Toggle all legends" onclick="${() => this.toggleAllLegends()}"><img alt="Toggle all legends icon" src="icons/legend.svg"></button> <button class="gg-icon-button gg-medium" tip="Remove all layers" onclick="${() => this.removeAll()}"><img alt="Remove all layers icon" src="icons/trash.svg"></button><div class="treeview-search" data-tour="treeview-filter"><img class="filter-icon" alt="filter-button-icon" src="icons/filter.svg"> <input id="treeview-search-field" class="gg-input" placeholder="Filter layer tree..." i18n="Filter layer tree..." autocomplete="off" autocorrect="off" oninput="${(e) => this.onFilterTree(e.target.value)}"> <button class="${this.isTreeFiltered ? 'delete-button' : 'hidden'}" onclick="${() => this.clearFilter()}"><img class="delete-icon" alt="delete-button-icon" tip="Reset filter" i18n="Reset filter" src="icons/trash.svg"></button></div></div><div class="${this.state.layers.layersList.length > 0 ? 'treeview-list' : 'hidden'}">${this.sortedLayers().map(layer => (layer instanceof ThemeLayer) ? uHtmlFor(layer, layer.treeItemId) `<girafe-tree-view-theme themeid="${layer.treeItemId}"></girafe-tree-view-theme>` : (layer instanceof GroupLayer) ? uHtmlFor(layer, layer.treeItemId) `<girafe-tree-view-group groupid="${layer.treeItemId}"></girafe-tree-view-group>` : uHtmlFor(layer, layer.treeItemId) `<girafe-tree-view-item layerid="${layer.treeItemId}"></girafe-tree-view-item>`)}</div><div class="${this.state.layers.layersList.length > 0 ? 'hidden' : 'treeview-no-data'}"><div class="${this.state.themes.isLoaded ? 'hidden' : 'treeview-loading'}"><img loading="eager" src="icons/progress.svg" class="gg-spin gg-big" alt="${this.context.i18nManager.getTranslation('Loading')}"><div><span i18n="Loading">Loading...</span></div></div><div class="${this.state.themes.isLoaded ? 'no-data' : 'hidden'}"><span i18n="Nothing here yet!">Nothing here yet!</span> <span>-</span> <span i18n="Add your first items">Add your first items</span> <span i18n="by selecting a theme">by selecting a theme</span> <span i18n="or">or</span> <span i18n="using the search bar">using the search bar</span></div></div></div>
|
|
28
|
+
<div id="panel" class="panel"><div class="menu"><button class="gg-icon-button gg-medium" tip="Expand / Collapse all" onclick="${() => this.expandAll()}"><img class="${this.isAllExpanded ? '' : 'hidden'}" alt="Collapse all icon" src="icons/collapse-all.svg"> <img class="${this.isAllExpanded ? 'hidden' : ''}" alt="Expand all icon" src="icons/expand-all.svg"></button> <button class="gg-icon-button gg-medium" tip="Toggle all legends" onclick="${() => this.toggleAllLegends()}"><img alt="Toggle all legends icon" src="icons/legend.svg"></button> <button class="gg-icon-button gg-medium" tip="Remove all layers" onclick="${() => this.removeAll()}"><img alt="Remove all layers icon" src="icons/trash.svg"></button><div class="treeview-search" data-tour="treeview-filter"><img class="filter-icon" alt="filter-button-icon" src="icons/filter.svg"> <input id="treeview-search-field" class="gg-input" aria-label="Filter layer tree" placeholder="Filter layer tree..." i18n="Filter layer tree..." autocomplete="off" autocorrect="off" oninput="${(e) => this.onFilterTree(e.target.value)}"> <button class="${this.isTreeFiltered ? 'delete-button' : 'hidden'}" onclick="${() => this.clearFilter()}"><img class="delete-icon" alt="delete-button-icon" tip="Reset filter" i18n="Reset filter" src="icons/trash.svg"></button></div></div><div class="${this.state.layers.layersList.length > 0 ? 'treeview-list' : 'hidden'}">${this.sortedLayers().map(layer => (layer instanceof ThemeLayer) ? uHtmlFor(layer, layer.treeItemId) `<girafe-tree-view-theme themeid="${layer.treeItemId}"></girafe-tree-view-theme>` : (layer instanceof GroupLayer) ? uHtmlFor(layer, layer.treeItemId) `<girafe-tree-view-group groupid="${layer.treeItemId}"></girafe-tree-view-group>` : uHtmlFor(layer, layer.treeItemId) `<girafe-tree-view-item layerid="${layer.treeItemId}"></girafe-tree-view-item>`)}</div><div class="${this.state.layers.layersList.length > 0 ? 'hidden' : 'treeview-no-data'}"><div class="${this.state.themes.isLoaded ? 'hidden' : 'treeview-loading'}"><img loading="eager" src="icons/progress.svg" class="gg-spin gg-big" alt="${this.context.i18nManager.getTranslation('Loading')}"><div><span i18n="Loading">Loading...</span></div></div><div class="${this.state.themes.isLoaded ? 'no-data' : 'hidden'}"><span i18n="Nothing here yet!">Nothing here yet!</span> <span>-</span> <span i18n="Add your first items">Add your first items</span> <span i18n="by selecting a theme">by selecting a theme</span> <span i18n="or">or</span> <span i18n="using the search bar">using the search bar</span></div></div></div>
|
|
29
29
|
${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
30
30
|
};
|
|
31
31
|
filterHelper;
|
package/models/xmlTypes.js
CHANGED
|
@@ -40,7 +40,7 @@ export const xmlTypesStrList = [
|
|
|
40
40
|
...xmlGeometryTypesStrList
|
|
41
41
|
];
|
|
42
42
|
export function isStringNumeric(str) {
|
|
43
|
-
return str.trim().length > 0 && !isNaN(Number(str)); // ensure strings of whitespace fail or mixed chars and numbers like '2n'
|
|
43
|
+
return str.trim().length > 0 && !Number.isNaN(Number(str)); // ensure strings of whitespace fail or mixed chars and numbers like '2n'
|
|
44
44
|
}
|
|
45
45
|
export function isString(attributeType) {
|
|
46
46
|
return xmlStringTypesStrList.includes(attributeType);
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"1.2.0-dev.
|
|
1
|
+
{"version":"1.2.0-dev.2873796427", "build":"2873796427", "date":"23/09/2026"}
|
package/tools/resizewindow.js
CHANGED
|
@@ -108,12 +108,12 @@ export default class ResizeWindow {
|
|
|
108
108
|
this.width = dimension.width;
|
|
109
109
|
this.height = dimension.height;
|
|
110
110
|
const css = getComputedStyle(this.host);
|
|
111
|
-
this.minHeight = parseInt(css.minHeight) || 0;
|
|
112
|
-
this.maxHeight = parseInt(css.maxHeight) || Infinity;
|
|
113
|
-
this.minWidth = parseInt(css.minWidth) || 0;
|
|
114
|
-
this.maxWidth = parseInt(css.maxWidth) || Infinity;
|
|
115
|
-
this.top = parseInt(css.top) || 0;
|
|
116
|
-
this.left = parseInt(css.left) || 0;
|
|
111
|
+
this.minHeight = Number.parseInt(css.minHeight) || 0;
|
|
112
|
+
this.maxHeight = Number.parseInt(css.maxHeight) || Infinity;
|
|
113
|
+
this.minWidth = Number.parseInt(css.minWidth) || 0;
|
|
114
|
+
this.maxWidth = Number.parseInt(css.maxWidth) || Infinity;
|
|
115
|
+
this.top = Number.parseInt(css.top) || 0;
|
|
116
|
+
this.left = Number.parseInt(css.left) || 0;
|
|
117
117
|
// Call a function whenever the cursor moves.
|
|
118
118
|
document.onmousemove = (dragEvent) => this.resize(dragEvent, direction);
|
|
119
119
|
// Detach events.
|
|
@@ -152,7 +152,7 @@ class LayerTimeFormatter {
|
|
|
152
152
|
return temporalFilter;
|
|
153
153
|
}
|
|
154
154
|
isValidDateString(dateString) {
|
|
155
|
-
return !isNaN(Date.parse(dateString));
|
|
155
|
+
return !Number.isNaN(Date.parse(dateString));
|
|
156
156
|
}
|
|
157
157
|
isWithinRange(date) {
|
|
158
158
|
return date >= this.minValue && date <= this.maxValue;
|