Skip to content

Commit

Permalink
Restructure catalog sidebar
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-va committed Dec 9, 2024
1 parent b13506b commit 3f6f76d
Show file tree
Hide file tree
Showing 25 changed files with 1,007 additions and 267 deletions.
1 change: 1 addition & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion ui/locales/app.de.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@
"dtd_cant_upload_kml_error": "Fehler beim Hochladen von KML",
"dtd_change_order_label": "Anordnen",
"dtd_clamp_to_ground": "Auf Terrain legen",
"dtd_configure_data_btn": "Angezeigte Daten konfigurieren",
"dtd_displayed_data_label": "Angezeigte Daten",
"dtd_download_hint": "Herunterladen / Legende",
"dtd_empty_map_label": "Kein Hintergrund",
Expand Down
1 change: 0 additions & 1 deletion ui/locales/app.en.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@
"dtd_cant_upload_kml_error": "Error while uploading KML",
"dtd_change_order_label": "Change order",
"dtd_clamp_to_ground": "Clamp to terrain",
"dtd_configure_data_btn": "Configure data displayed",
"dtd_displayed_data_label": "Data displayed",
"dtd_download_hint": "Download / Legend",
"dtd_empty_map_label": "No background",
Expand Down
1 change: 0 additions & 1 deletion ui/locales/app.fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@
"dtd_cant_upload_kml_error": "Erreur lors du téléchargement de KML",
"dtd_change_order_label": "Réarranger",
"dtd_clamp_to_ground": "Fixation au terrain",
"dtd_configure_data_btn": "Configurer les données affichées",
"dtd_displayed_data_label": "Données affichées",
"dtd_download_hint": "Télécharger / Légende",
"dtd_empty_map_label": "Sans arrière-plan",
Expand Down
1 change: 0 additions & 1 deletion ui/locales/app.it.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@
"dtd_cant_upload_kml_error": "Errore nel download di KML",
"dtd_change_order_label": "Riordinare",
"dtd_clamp_to_ground": "Morsetto al terreno",
"dtd_configure_data_btn": "Configurare i dati visualizzati ",
"dtd_displayed_data_label": "Dati mostrati",
"dtd_download_hint": "Scaricare / Scala",
"dtd_empty_map_label": "Senza sfondo",
Expand Down
44 changes: 44 additions & 0 deletions ui/src/components/core/core-button.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {css, html, LitElement} from 'lit';
import {customElement, property} from 'lit/decorators.js';

@customElement('ngm-core-button')
export class CoreButton extends LitElement {
@property({reflect: true})
accessor variant: Variant = 'default';

@property({type: Boolean, attribute: 'active', reflect: true})
accessor isActive: boolean = false;

readonly render = () => html`
<button>
<slot></slot>
</button>
`;

static readonly styles = css`
button {
font-family: var(--font);
font-size: 14px;
}
:host([variant='text']) button {
color: var(--color-highlight--darker);
border: none;
background-color: transparent;
cursor: pointer;
}
:host([variant='text'][active]) button {
color: var(--color-action);
}
:host([variant='text']) button:hover {
color: var(--color-action--light);
}
`;
}

export type Variant =
| 'default'
| 'text'
49 changes: 49 additions & 0 deletions ui/src/components/core/core-icon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import {css, html, LitElement} from 'lit';
import {customElement, property} from 'lit/decorators.js';

@customElement('ngm-core-icon')
export class CoreIcon extends LitElement {
@property()
accessor icon: IconName | null = null;

@property({type: Boolean, attribute: 'interactive'})
accessor isInteractive: boolean = false;

readonly render = () => html``;

static readonly styles = css`
:host {
display: inline-block;
--size: var(--icon-size--normal);
width: var(--size);
height: var(--size);
background-color: var(--color-bg-contrast);
mask: var(--mask, none) no-repeat center;
-webkit-mask: var(--mask, none) no-repeat center;
/* Hide element if no valid icon has been specified. */
visibility: hidden;
}
:host([interactive]:hover) {
cursor: pointer;
background-color: var(--color-action);
}
:host([icon='close']) {
visibility: initial;
--mask: url('images/i_close.svg');
}
:host([icon='dropdown']) {
visibility: initial;
--mask: url('images/i_menu-1.svg')
}
`;
}

export type IconName =
| 'close'
| 'dropdown'
2 changes: 2 additions & 0 deletions ui/src/components/core/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import './core-button';
import './core-icon';
217 changes: 217 additions & 0 deletions ui/src/components/layers/layers-catalog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
import {css, html, TemplateResult, unsafeCSS} from 'lit';
import {customElement, property, state} from 'lit/decorators.js';
import {LitElementI18n} from '../../i18n.js';
import i18next from 'i18next';
import auth from '../../store/auth';
import type {LayerTreeNode} from '../../layertree';
import $ from 'jquery';


import fomanticTransitionCss from 'fomantic-ui-css/components/transition.css';
import fomanticAccordionCss from 'fomantic-ui-css/components/accordion.css';
import 'fomantic-ui-css/components/transition.js';
import {LayerEvent} from './layers-display';


@customElement('ngm-layers-catalog')
export class NgmLayersCatalog extends LitElementI18n {
@property({type: Array})
accessor layers: LayerTreeNode[] = [];

@state()
accessor userGroups: string[] = [];

constructor() {
super();
auth.user.subscribe((user) => {
this.userGroups = user?.['cognito:groups'] ?? [];
});
}

firstUpdated(): void {
const {shadowRoot} = this;
if (shadowRoot == null) {
return;
}
$(shadowRoot.querySelectorAll(':host > .ui.accordion')).accordion({
duration: 150,
});
}

getCategoryOrLayerTemplate(node: LayerTreeNode, level: string): TemplateResult {
if (node.children) {
return this.getCategoryTemplate(node, level);
}
return this.getLayerTemplate(node);
}

getCategoryTemplate(category: LayerTreeNode, level: string): TemplateResult {
// if it is a restricted layer, the user must be logged in to see it
const content = category.children?.filter(
node => !(node.restricted && (!node.restricted.some(g => this.userGroups.includes(g))))
).map(node => this.getCategoryOrLayerTemplate(node, 'second-level'));

if (!content?.length) return html``;

return html`
<div class="category ui accordion">
<div class="title ${level}">
<ngm-core-icon icon="dropdown"></ngm-core-icon>
<label>${i18next.t(category.label)}</label>
</div>
<div class="content">
${content}
</div>
</div>
`;
}

getLayerTemplate(layer: LayerTreeNode): TemplateResult {
return html`
<div class="ngm-checkbox ${layer.displayed ? 'active' : ''}"
@click=${() => {
this.dispatchEvent(new CustomEvent('layer-click', {
composed: true,
bubbles: true,
detail: {
layer
}
}) satisfies LayerEvent);
}}>
<input type="checkbox" .checked=${!!layer.visible}>
<span class="ngm-checkbox-icon"></span>
<label class=${layer.displayed ? 'displayed' : ''}>
<i class=${layer.restricted ? 'lock icon' : ''}></i>${i18next.t(layer.label)}
</label>
</div>
`;
}

render() {
return html`${this.layers.map(node => this.getCategoryOrLayerTemplate(node, 'first-level'))}`;
}

static readonly styles = css`
${unsafeCSS(fomanticTransitionCss)}
${unsafeCSS(fomanticAccordionCss)}
:host, :host * {
box-sizing: border-box;
}
.category.ui.accordion {
margin-top: 0;
}
.category.ui.accordion > .title ~ .content,
.category.ui.accordion .category.ui.accordion > .title ~ .content
{
padding-top: 0;
}
.category > .title {
display: flex;
align-items: center;
cursor: pointer;
}
.category > .title.active > label {
color: var(--color-action);
}
.category > .title:hover > label {
color: var(--color-action--light);
}
.category > .title > ngm-core-icon {
background-color: var(--color-highlight--darker);
}
.category > .title:hover > ngm-core-icon {
background-color: var(--color-action--light);
}
.category > .title.first-level {
font-weight: 700;
}
.category > .title > label {
cursor: pointer;
font-size: 14px;
margin-left: 10px;
}
.category > .title.active > ngm-core-icon {
transform: rotate(90deg);
}
.ngm-checkbox {
display: flex;
align-items: center;
margin-bottom: 12px;
cursor: pointer;
}
.ngm-checkbox:hover {
color: var(--color-action--light);
}
.ngm-checkbox.active {
color: var(--color-action);
}
.ngm-checkbox > input {
display: none;
}
.ngm-checkbox:hover > .ngm-checkbox-icon {
border-color: var(--color-action--light);
}
.ngm-checkbox > .ngm-checkbox-icon {
display: inline-block;
position: relative;
width: 19px;
height: 18px;
border-radius: 2px;
border: 2px solid var(--ngm-interaction);
transition: all 0.5s ease;
}
.ngm-checkbox > label {
margin-left: 10px;
cursor: pointer;
}
.ngm-checkbox.active > .ngm-checkbox-icon {
border-color: var(--color-action);
}
.ngm-checkbox input:checked + .ngm-checkbox-icon {
background-color: var(--color-action);
}
.ngm-checkbox.active:hover > .ngm-checkbox-icon {
background-color: var(--color-action--light);
}
.ngm-checkbox > .ngm-checkbox-icon::before {
box-sizing: content-box;
content: "";
top: -2px;
left: 3px;
width: 6px;
height: 12px;
display: none;
position: absolute;
transform: rotate(45deg);
transition: all 0.5s ease;
border-right: 2px solid #fff;
border-bottom: 2px solid #fff;
}
.ngm-checkbox input:checked + .ngm-checkbox-icon::before {
display: block;
}
`;
}
Loading

0 comments on commit 3f6f76d

Please sign in to comment.