Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ All notable changes to this project will be documented in this file. The format

### Fixed

- **About**: The About window shows the installed API SITNA version and the installed OpenLayers version. Both values are read from the installed packages when the viewer is built ([#218](https://github.com/sitmun/sitmun-viewer-app/issues/218)).
- **Map**: A WFS row in Loaded Layers uses the root folder as its heading, the same folder path as a WMS row, and the leaf name as its title. The toolbar overflow control shows › when the extra tools are hidden and ‹ when they are open, on every Loaded Layers row that has that control.
- **Map**: A WFS entry in the legend lists the root folder and each intermediate folder above the layer, the same way a WMS legend does. The point swatch stays on the layer.
- **Map**: An identify field with format Image keeps the original address and SITNA's `img.tc-img-attr`. `maxWidth` and `maxHeight` on the field set those limits. A field without them stays `width:auto;height:auto`.
Expand Down
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ This frontend integrates with the [SITMUN Backend Core](https://github.com/sitmu
- Internationalization (CA, ES, EN, FR)
- Configurable UI components
- Lazy loading and efficient rendering
- SITNA integration (api-sitna 4.8.0)
- SITNA integration (api-sitna 4.9.1, OpenLayers 10.5.0)
- Service Worker for API auth token forwarding

## Quick Start
Expand Down Expand Up @@ -453,7 +453,10 @@ The application uses the **SITNA (Sistema de Información Territorial de Navarra

**Version Information:**

- **SITNA API Version**: Aligned with api-sitna 4.8.0
- **SITNA API Version**: api-sitna 4.9.1
- **OpenLayers**: 10.5.0, the version api-sitna 4.9.1 depends on

The About window reads both versions from the installed packages when the viewer is built.

#### **Core Mapping Features**

Expand Down Expand Up @@ -581,7 +584,7 @@ src/
- **Modular Design**: Feature-based module organization
- **Reactive Programming**: RxJS for asynchronous operations
- **Material Design**: Angular Material for consistent UI
- **SITNA Integration**: Advanced mapping through SITNA library (api-sitna 4.8.0)
- **SITNA Integration**: Advanced mapping through SITNA library (api-sitna 4.9.1, OpenLayers 10.5.0)

## Contributing

Expand Down
28 changes: 18 additions & 10 deletions src/app/ui/components/about-dialog/about-dialog.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,25 @@ <h2 mat-dialog-title>{{ 'systemInfo.about' | translate }}</h2>
</div>
</div>

@if (data.sitnaVersion) {
<div class="about-item">
<mat-icon class="about-icon">map</mat-icon>
<div class="about-info">
<span class="about-label">
{{ 'systemInfo.sitnaVersion' | translate }}:
</span>
<span class="about-value">{{ data.sitnaVersion }}</span>
</div>
<div class="about-item">
<mat-icon class="about-icon">map</mat-icon>
<div class="about-info">
<span class="about-label">
{{ 'systemInfo.sitnaVersion' | translate }}:
</span>
<span class="about-value">{{ data.sitnaVersion }}</span>
</div>
}
</div>

<div class="about-item">
<mat-icon class="about-icon">layers</mat-icon>
<div class="about-info">
<span class="about-label">
{{ 'systemInfo.openLayersVersion' | translate }}:
</span>
<span class="about-value">{{ data.openLayersVersion }}</span>
</div>
</div>

@if (data.buildTimestamp) {
<div class="about-item">
Expand Down
7 changes: 2 additions & 5 deletions src/app/ui/components/about-dialog/about-dialog.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@ export interface AboutDialogData {
environmentName: string;
angularVersion: string;
buildTimestamp?: string;
sitnaVersion?: string;
sitnaVersion: string;
openLayersVersion: string;
}

/**
* Component for displaying application information dialog.
* TODO: Add unit tests (about-dialog.component.spec.ts)
*/
@Component({
standalone: false,
selector: 'app-about-dialog',
Expand Down
5 changes: 5 additions & 0 deletions src/app/ui/components/about-dialog/library-versions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import sitnaPackage from 'api-sitna/package.json';
import olPackage from 'ol/package.json';

export const sitnaVersion: string = sitnaPackage.version;
export const openLayersVersion: string = olPackage.version;
43 changes: 42 additions & 1 deletion src/app/ui/components/menu/menu.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { readFileSync } from 'fs';
import { join } from 'path';

import { NgOptimizedImage } from '@angular/common';
import { provideHttpClient } from '@angular/common/http';
import { provideHttpClientTesting } from '@angular/common/http/testing';
Expand All @@ -17,14 +20,25 @@ import { AuthenticationService } from '@auth/services/authentication.service';
import { TranslateModule, TranslateService } from '@ngx-translate/core';

import { MenuComponent } from './menu.component';
import { AboutDialogComponent } from '../about-dialog/about-dialog.component';

function installedPackageVersion(name: string): string {
const manifest = JSON.parse(
readFileSync(
join(process.cwd(), 'node_modules', name, 'package.json'),
'utf8'
)
) as { version: string };
return manifest.version;
}

describe('MenuComponent', () => {
let component: MenuComponent;
let fixture: ComponentFixture<MenuComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [MenuComponent],
declarations: [MenuComponent, AboutDialogComponent],
imports: [
BrowserAnimationsModule,
NgOptimizedImage,
Expand Down Expand Up @@ -92,4 +106,31 @@ describe('MenuComponent', () => {
it('should initialize with default language', () => {
expect(component.currentLang).toBe('en');
});

it('shows the installed SITNA and OpenLayers versions in About', () => {
const translate = TestBed.inject(TranslateService);
translate.setTranslation('en', {
'systemInfo.about': 'About',
'systemInfo.application': 'Application',
'systemInfo.applicationName': 'Visualizador SITMUN',
'systemInfo.version': 'Version',
'systemInfo.environment': 'Environment',
'systemInfo.angularVersion': 'Angular Version',
'systemInfo.sitnaVersion': 'API SITNA Version',
'systemInfo.openLayersVersion': 'OpenLayers Version',
'common.button.close': 'Close'
});
translate.use('en');

component.openAboutDialog();
fixture.detectChanges();

const text = (document.body.textContent ?? '').replace(/\s+/g, ' ');
expect(text).toContain(
`API SITNA Version: ${installedPackageVersion('api-sitna')}`
);
expect(text).toContain(
`OpenLayers Version: ${installedPackageVersion('ol')}`
);
});
});
7 changes: 6 additions & 1 deletion src/app/ui/components/menu/menu.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ import {
AboutDialogComponent,
AboutDialogData
} from '../about-dialog/about-dialog.component';
import {
openLayersVersion,
sitnaVersion
} from '../about-dialog/library-versions';

@Component({
standalone: false,
Expand Down Expand Up @@ -182,7 +186,8 @@ export class MenuComponent implements OnInit, OnDestroy {
environmentName: this.environment.environmentName || 'N/A',
angularVersion: this.angularVersion,
buildTimestamp: (this.environment as any).buildTimestamp,
sitnaVersion: this.environment.sitnaVersion
sitnaVersion,
openLayersVersion
};

this.dialog.open(AboutDialogComponent, {
Expand Down
1 change: 1 addition & 0 deletions src/assets/i18n/ca.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@
"systemInfo.errorType.logger": "Error d'aplicació",
"systemInfo.errorType.uncaught": "Excepció no capturada",
"systemInfo.noErrors": "No hi ha errors registrats",
"systemInfo.openLayersVersion": "Versió d'OpenLayers",
"systemInfo.recentErrors": "Errors recents",
"systemInfo.sitnaVersion": "Versió API SITNA",
"systemInfo.version": "Versió",
Expand Down
1 change: 1 addition & 0 deletions src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@
"systemInfo.errorType.logger": "Application Error",
"systemInfo.errorType.uncaught": "Uncaught Exception",
"systemInfo.noErrors": "No errors recorded",
"systemInfo.openLayersVersion": "OpenLayers Version",
"systemInfo.recentErrors": "Recent Errors",
"systemInfo.sitnaVersion": "API SITNA Version",
"systemInfo.version": "Version",
Expand Down
1 change: 1 addition & 0 deletions src/assets/i18n/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@
"systemInfo.errorType.logger": "Error de Aplicación",
"systemInfo.errorType.uncaught": "Excepción No Capturada",
"systemInfo.noErrors": "No hay errores registrados",
"systemInfo.openLayersVersion": "Versión de OpenLayers",
"systemInfo.recentErrors": "Errores Recientes",
"systemInfo.sitnaVersion": "Versión API SITNA",
"systemInfo.version": "Versión",
Expand Down
1 change: 1 addition & 0 deletions src/assets/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@
"systemInfo.errorType.logger": "Erreur d'application",
"systemInfo.errorType.uncaught": "Exception non interceptée",
"systemInfo.noErrors": "Aucune erreur enregistrée",
"systemInfo.openLayersVersion": "Version d'OpenLayers",
"systemInfo.recentErrors": "Erreurs récentes",
"systemInfo.sitnaVersion": "Version API SITNA",
"systemInfo.version": "Version",
Expand Down
1 change: 1 addition & 0 deletions src/assets/i18n/oc-aranes.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@
"systemInfo.errorType.logger": "Error d'aplicacion",
"systemInfo.errorType.uncaught": "Excepcion no capturada",
"systemInfo.noErrors": "Non i a errors registrats",
"systemInfo.openLayersVersion": "Versió OpenLayers",
"systemInfo.recentErrors": "Errors recents",
"systemInfo.sitnaVersion": "Versió API SITNA",
"systemInfo.version": "Versió",
Expand Down
1 change: 0 additions & 1 deletion src/environments/environment.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ export const environment = {
apiUrl: '/backend',
version: '1.2.9',
environmentName: 'E2E',
sitnaVersion: '4.8.0',
buildTimestamp: new Date().toISOString(),
loginBackgroundImageUrl: '',
proxyTokenRefreshIntervalMs: 10 * 60 * 1000,
Expand Down
1 change: 0 additions & 1 deletion src/environments/environment.prod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export const environment = {
apiUrl: '/backend', // Change this when there is a real production environment
version: '1.2.9',
environmentName: 'Production',
sitnaVersion: '4.8.0',
buildTimestamp: new Date().toISOString(),
loginBackgroundImageUrl: 'assets/logos/barcelona_background.jpg',
proxyTokenRefreshIntervalMs: 2 * 60 * 1000,
Expand Down
1 change: 0 additions & 1 deletion src/environments/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export const environment = {
apiUrl: 'http://localhost:9000/backend',
version: '1.2.9',
environmentName: 'Development',
sitnaVersion: '4.8.0',
buildTimestamp: new Date().toISOString(),
loginBackgroundImageUrl: 'assets/logos/barcelona_background.jpg',
proxyTokenRefreshIntervalMs: 2 * 60 * 1000,
Expand Down
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"moduleResolution": "bundler",
"importHelpers": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"target": "ES2022",
"module": "es2020",
"types": ["node"],
Expand Down
Loading