diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 6af953c..8613670 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -10,19 +10,19 @@ jobs: timeout-minutes: 45 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: submodules: recursive - name: Set up Java 17 - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: temurin java-version: '17' cache: gradle - name: Set up Node 20 - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: '20' cache: npm @@ -47,7 +47,7 @@ jobs: - name: Upload Playwright artifacts if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: playwright-admin-artifacts path: | @@ -60,19 +60,19 @@ jobs: timeout-minutes: 45 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: submodules: recursive - name: Set up Java 17 - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: temurin java-version: '17' cache: gradle - name: Set up Node 20 - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: '20' cache: npm @@ -97,7 +97,7 @@ jobs: - name: Upload Playwright artifacts if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: playwright-viewer-artifacts path: | @@ -110,19 +110,19 @@ jobs: timeout-minutes: 45 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: submodules: recursive - name: Set up Java 17 - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: temurin java-version: '17' cache: gradle - name: Set up Node 20 - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: '20' cache: npm @@ -152,7 +152,7 @@ jobs: - name: Upload Playwright artifacts if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: playwright-application-contact-artifacts path: | @@ -165,19 +165,19 @@ jobs: timeout-minutes: 60 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: submodules: recursive - name: Set up Java 17 - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: temurin java-version: '17' cache: gradle - name: Set up Node 20 - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: '20' cache: npm @@ -207,7 +207,7 @@ jobs: - name: Upload Playwright artifacts if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: playwright-mia-cross-artifacts path: | @@ -220,19 +220,19 @@ jobs: timeout-minutes: 60 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: submodules: recursive - name: Set up Java 17 - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: temurin java-version: '17' cache: gradle - name: Set up Node 20 - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: '20' cache: npm @@ -251,7 +251,7 @@ jobs: - name: Upload Playwright artifacts if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: playwright-mobile-web-artifacts path: | @@ -264,19 +264,19 @@ jobs: timeout-minutes: 120 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: submodules: recursive - name: Set up Java 17 - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: temurin java-version: '17' cache: gradle - name: Set up Node 20 - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: '20' cache: npm @@ -322,7 +322,7 @@ jobs: - name: Upload Android E2E artifacts if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: mobile-android-artifacts path: test-results/mobile-android/ diff --git a/.github/workflows/liquibase-immutability.yml b/.github/workflows/liquibase-immutability.yml index cd7af65..31446c1 100644 --- a/.github/workflows/liquibase-immutability.yml +++ b/.github/workflows/liquibase-immutability.yml @@ -10,13 +10,13 @@ jobs: timeout-minutes: 5 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 submodules: recursive - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.12' diff --git a/.github/workflows/liquibase-seed-identity.yml b/.github/workflows/liquibase-seed-identity.yml index 0ff60dd..5fd22d4 100644 --- a/.github/workflows/liquibase-seed-identity.yml +++ b/.github/workflows/liquibase-seed-identity.yml @@ -16,12 +16,12 @@ jobs: timeout-minutes: 5 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.12' diff --git a/.github/workflows/liquibase-upgrade.yml b/.github/workflows/liquibase-upgrade.yml index 49233bc..e62619f 100644 --- a/.github/workflows/liquibase-upgrade.yml +++ b/.github/workflows/liquibase-upgrade.yml @@ -24,7 +24,7 @@ jobs: timeout-minutes: 5 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Extracted-tree helper unit tests run: python3 tools/tests/test_prepare_extracted_liquibase.py @@ -34,7 +34,7 @@ jobs: timeout-minutes: 20 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 fetch-tags: true @@ -56,7 +56,7 @@ jobs: source: ['1.2.8'] steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 fetch-tags: true @@ -72,7 +72,7 @@ jobs: timeout-minutes: 20 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 @@ -88,7 +88,7 @@ jobs: source: ['1.2.6', '1.2.7', '1.2.8'] steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 fetch-tags: true @@ -107,7 +107,7 @@ jobs: timeout-minutes: 60 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 fetch-tags: true @@ -125,7 +125,7 @@ jobs: timeout-minutes: 40 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 fetch-tags: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a3af59..a5fd7d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,25 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ## [Unreleased] +### Added + +#### Backend Core + +- **Profile**: Client profile layers publish ordered `featureInfoFields` for `INFO` cartography parameters. The list is omitted when empty. Labels come from `STM_TRANSLATION` on `CartographyParameter.value` ([sitmun-backend-core#268](https://github.com/sitmun/sitmun-backend-core/pull/268), [#77](https://github.com/sitmun/sitmun-application-stack/issues/77)). + +#### Admin Application + +- **Layers**: The feature-information field grid is on the cartography form without the experimental query-layer flag. Labels translate per parameter. `N` and `P` edit fraction digits and padding. `F` chooses date or date and time. A WFS DescribeFeatureType request seeds top-level element names ([sitmun-admin-app#469](https://github.com/sitmun/sitmun-admin-app/pull/469), [#77](https://github.com/sitmun/sitmun-application-stack/issues/77)). + +#### Viewer Application + +- **Map**: A non-empty field list replaces the full GetFeatureInfo property table, in order, with the translated label. `T`, `N`, `F`, `U`, `P`, and `I` follow the map locale. `AUTO` keeps API-SITNA detection. `feature.data` is not rewritten ([sitmun-viewer-app#179](https://github.com/sitmun/sitmun-viewer-app/pull/179), [#77](https://github.com/sitmun/sitmun-application-stack/issues/77)). + +#### Profile-level + +- **Liquibase**: PostgreSQL and Oracle changelog 27, and development changelog 74, add `PGI_OPTIONS` and format code `AUTO` ([#77](https://github.com/sitmun/sitmun-application-stack/issues/77)). +- **Liquibase**: Development changelog 75 seeds GetFeatureInfo fields on IDE genèric Menorca cartography 1304, Trams del camí de cavalls (`tu007rts_ccavalls`): route, kind, max easting, and website. Spanish and Catalan labels are translations; English is the stored default ([#77](https://github.com/sitmun/sitmun-application-stack/issues/77)). + ### Fixed #### Stack-level diff --git a/back/backend/sitmun-backend-core b/back/backend/sitmun-backend-core index 6e1498f..922fb10 160000 --- a/back/backend/sitmun-backend-core +++ b/back/backend/sitmun-backend-core @@ -1 +1 @@ -Subproject commit 6e1498f3de7117cd3c75a79b99c39368149f9adf +Subproject commit 922fb1045060e4805da55c808dd2bd04ff7b3665 diff --git a/e2e/README.md b/e2e/README.md index 3ffd06b..5a9e664 100644 --- a/e2e/README.md +++ b/e2e/README.md @@ -43,6 +43,7 @@ Browser E2E against backend-core on in-memory H2. No Docker Compose. - Map legend (`viewer-legend`): after loading a stubbed catalog leaf, Capas shows capabilities `LegendURL` imagery and the Legend task shows symbology when the stub denies `DescribeLayer` and fails `/wms` GetLegendGraphic (DiBa/ArcGIS-style #164); setup enables `sitna.legend` task-availability - No base map (`viewer-basemap`): basemap selector option `sitmun-no-base-map` clears raster basemap to a white viewport while a catalog leaf stays visible (#167); setup enables `sitna.basemapSelector` task-availability - Print preview (`viewer-print`): 1600×700 window; A4 landscape map becomes 1040×704 and A4 portrait 712×1034 while `tc-ctl-prnmap-printing` is set, then returns to window size ([sitmun-viewer-app#160](https://github.com/sitmun/sitmun-viewer-app/issues/160)); setup enables `sitna.printMap` and drops seed `div: "print"` / external logo +- GetFeatureInfo include list plus more-info (`viewer-gfi-fields`): profile for Toponímia (`34_TOPO_TX`, cartography 6) gets a `sitmun.moreInfo` URL task whose placeholder reads `id`, then three field-list cases. One listed field (`name` → Place) keeps Place and the task row, uses omitted `id` in the link, and hides the `id` header. An empty list keeps the original properties plus the more-info row. Two listed fields where one name misses the feature keep both rows (blank cell for the miss), hide unlisted headers, and still show the more-info link (`e2e/viewer/gfi-field-list.spec.ts`). - HTML GetFeatureInfo embed (`viewer-gfi`): `e2e/viewer/gfi-html-embed.spec.ts` loads the viewer origin, then nested `iframe`s against the WMS stub. Playwright `frame.url()` is the oracle. `/embed/allow` (no `X-Frame-Options`) commits `http://127.0.0.1:18093/embed/allow`. `/embed/deny` (`X-Frame-Options: DENY`) does not. Same-origin `location.href` is not used. Chromium opaque error documents can throw `SecurityError` for both outcomes. Jest covers hide/load/probe ([sitmun-viewer-app#169](https://github.com/sitmun/sitmun-viewer-app/issues/169)). - More Info Advanced (`viewer-mia`): profile includes `sitna.moreInfoAdvanced` + type-16 parent on Toponímia (seed parent 42 includes query child 38); synthetic FeatureInfo `responseCallback` opens `.sitmun-mia-popup-overlay` and `POST /api/tasks/template/more-info-advanced/render` carries `appId`/`terId` body plus `lang` query ([sitmun-viewer-app#162](https://github.com/sitmun/sitmun-viewer-app/pull/162)); also asserts live backend render, overlay error on 500, close, multi-feature GFI re-render (`selectMiaGfiFeature`), and deferred-route races (late first identify must not overwrite a newer one; close-during-load ignores late fulfill); setup enables MIA + featureInfo task-availability. Shared helpers live in `e2e/viewer/helpers/mia.ts`. - Local Basic-auth upstream stub (plus unauthenticated `/legend` PNG for #164); capabilities advertise `GetFeatureInfo` `application/json` so SITNA sets `INFO_FORMAT`; GetFeatureInfo for layer `34_TOPO_TX` returns JSON FeatureCollection (XML fixture fallback). Production Liquibase is not modified. diff --git a/e2e/viewer/gfi-field-list.spec.ts b/e2e/viewer/gfi-field-list.spec.ts new file mode 100644 index 0000000..5d85e3d --- /dev/null +++ b/e2e/viewer/gfi-field-list.spec.ts @@ -0,0 +1,150 @@ +import { expect, test, type Page } from '@playwright/test'; +import { QUERYABLE_LEAF_CARTOGRAPHY_ID } from './fixtures'; +import { + enableCapasGfi, + identifyAtMapCenter, + loadQueryableLeafIntoCapas, + loginAndOpenMap, +} from './helpers/mia'; + +const LAYER_NAME = '34_TOPO_TX'; +const TASK_NAME = 'E2E extra field'; + +type FieldSeed = { name: string; label: string; format: 'T'; order: number }; + +type ProfileBody = { + layers?: Array<{ + layers?: string[]; + featureInfoFields?: Array<{ name?: string; label?: string }>; + }>; + tasks?: Array<{ name?: string }>; +}; + +async function identifyWithFieldList(page: Page, featureInfoFields: FieldSeed[]) { + // The viewer service worker fetches the profile. page.route does not see that. + await page.context().route(/\/config\/client\/profile\//, async (route) => { + const response = await route.fetch(); + const body = (await response.json()) as { + layers?: Array<{ id?: string; layers?: string[]; featureInfoFields?: unknown }>; + tasks?: Array>; + }; + const layer = body.layers?.find( + (item) => Array.isArray(item.layers) && item.layers.includes(LAYER_NAME), + ); + if (!layer) { + throw new Error(`profile has no layer whose names include ${LAYER_NAME}`); + } + layer.featureInfoFields = featureInfoFields; + body.tasks = body.tasks ?? []; + body.tasks.push({ + id: 'e2e-more-info', + name: TASK_NAME, + 'ui-control': 'sitmun.moreInfo', + cartographyId: String(QUERYABLE_LEAF_CARTOGRAPHY_ID), + command: 'https://example.org/item/$ID$', + parameters: { + ID: { label: '$ID$', value: 'id' }, + }, + }); + await route.fulfill({ + status: response.status(), + contentType: 'application/json', + body: JSON.stringify(body), + }); + }); + + const profileSeen = page.waitForResponse( + (response) => + response.url().includes('/config/client/profile/') && response.ok(), + ); + await loginAndOpenMap(page); + const profileBody = (await (await profileSeen).json()) as ProfileBody; + await loadQueryableLeafIntoCapas(page); + await enableCapasGfi(page); + + const gfi = page.waitForResponse( + (response) => + /REQUEST=GetFeatureInfo/i.test(response.url()) && + /34_TOPO_TX/i.test(response.url()) && + response.ok(), + { timeout: 60_000 }, + ); + await identifyAtMapCenter(page); + await gfi; + + const table = page.locator('.tc-ctl-popup .tc-ctl-finfo-layers table').first(); + await expect(table).toBeVisible({ timeout: 30_000 }); + return { profileBody, table }; +} + +/** + * Include-list identify still grows when a sitmun.moreInfo task is present: + * listed properties stay, omitted service properties stay hidden, and the + * task appends its own row using the full payload. + */ +test.describe('GetFeatureInfo include list and more-info', () => { + test('more-info adds a row while omitted properties stay hidden', async ({ page }) => { + const { profileBody, table } = await identifyWithFieldList(page, [ + { name: 'name', label: 'Place', format: 'T', order: 0 }, + ]); + const seeded = profileBody.layers?.find((item) => item.layers?.includes(LAYER_NAME)); + expect(seeded?.featureInfoFields?.some((field) => field.label === 'Place')).toBeTruthy(); + expect(profileBody.tasks?.some((task) => task.name === TASK_NAME)).toBeTruthy(); + + await expect(table.locator('th', { hasText: /^Place$/ })).toBeVisible(); + await expect(table.locator('td', { hasText: 'e2e-gfi-click' })).toBeVisible(); + await expect(table.locator('th', { hasText: TASK_NAME })).toBeVisible(); + await expect(table.locator('a.sitmun-more-info-link')).toHaveAttribute( + 'href', + 'https://example.org/item/1', + ); + await expect(table.locator('th', { hasText: /^id$/ })).toHaveCount(0); + }); + + test('empty field list keeps the original properties and the more-info row', async ({ + page, + }) => { + const { profileBody, table } = await identifyWithFieldList(page, []); + const seeded = profileBody.layers?.find((item) => item.layers?.includes(LAYER_NAME)); + expect(seeded?.featureInfoFields).toHaveLength(0); + expect(profileBody.tasks?.some((task) => task.name === TASK_NAME)).toBe(true); + + await expect(table.locator('th', { hasText: /^id$/ })).toBeVisible(); + await expect( + table.locator('tr', { has: page.locator('th', { hasText: /^id$/ }) }).locator('td'), + ).toHaveText('1'); + await expect(table.locator('th', { hasText: /^name$/ })).toBeVisible(); + await expect( + table.locator('tr', { has: page.locator('th', { hasText: /^name$/ }) }).locator('td'), + ).toHaveText('e2e-gfi-click'); + await expect(table.locator('th', { hasText: TASK_NAME })).toBeVisible(); + await expect(table.locator('a.sitmun-more-info-link')).toHaveAttribute( + 'href', + 'https://example.org/item/1', + ); + }); + + test('listed fields stay when one name misses the feature', async ({ page }) => { + const { profileBody, table } = await identifyWithFieldList(page, [ + { name: 'name', label: 'Place', format: 'T', order: 0 }, + { name: 'missing-attr', label: 'Missing', format: 'T', order: 1 }, + ]); + const seeded = profileBody.layers?.find((item) => item.layers?.includes(LAYER_NAME)); + const labels = seeded?.featureInfoFields?.map((field) => field.label) ?? []; + expect(labels).toEqual(expect.arrayContaining(['Place', 'Missing'])); + + await expect( + table.locator('tr', { has: page.locator('th', { hasText: /^Place$/ }) }).locator('td'), + ).toHaveText('e2e-gfi-click'); + await expect( + table.locator('tr', { has: page.locator('th', { hasText: /^Missing$/ }) }).locator('td'), + ).toHaveText(''); + await expect(table.locator('th', { hasText: /^id$/ })).toHaveCount(0); + await expect(table.locator('th', { hasText: /^name$/ })).toHaveCount(0); + await expect(table.locator('a.sitmun-more-info-link')).toHaveAttribute( + 'href', + 'https://example.org/item/1', + ); + await expect(table.locator('tr')).toHaveCount(3); + }); +}); diff --git a/e2e/viewer/helpers/mia.ts b/e2e/viewer/helpers/mia.ts index 11df087..21ef909 100644 --- a/e2e/viewer/helpers/mia.ts +++ b/e2e/viewer/helpers/mia.ts @@ -317,6 +317,41 @@ export async function openPublicDashboard(page: Page): Promise { } /** Enable Capas GFI toggle so map clicks issue GetFeatureInfo for the loaded leaf. */ +/** Drive FeatureInfo.callback at the map center (stub GetFeatureInfo, not responseCallback). */ +export async function identifyAtMapCenter(page: Page): Promise { + await page.evaluate(async () => { + const w = window as unknown as { + TC?: { + Map?: { + get: (el: Element) => { + controls?: Array<{ callback?: (coords: number[]) => Promise }>; + getCenter?: () => number[]; + wrap?: { map?: { getView: () => { getCenter: () => number[] } } }; + }; + }; + control?: { FeatureInfo?: new () => unknown }; + }; + }; + const mapEl = document.querySelector('.tc-map'); + if (!w.TC?.Map?.get || !mapEl) { + throw new Error('TC.Map not available'); + } + const map = w.TC.Map.get(mapEl); + const FeatureInfo = w.TC.control?.FeatureInfo; + const fi = (map.controls || []).find( + (ctl) => FeatureInfo && ctl instanceof (FeatureInfo as unknown as Function), + ); + if (!fi?.callback) { + throw new Error('FeatureInfo.callback not found'); + } + const center = map.getCenter?.() || map.wrap?.map?.getView()?.getCenter() || null; + if (!center) { + throw new Error('map center unavailable'); + } + await fi.callback(center); + }); +} + export async function enableCapasGfi(page: Page): Promise { const gfi = page.locator('#tc-slot-wlm sitna-toggle.sitmun-wlm-gfi, #tc-slot-wlm .sitmun-wlm-gfi').first(); await expect(gfi).toBeVisible({ timeout: 30_000 }); diff --git a/front/admin/sitmun-admin-app b/front/admin/sitmun-admin-app index 5d7dca2..6d92482 160000 --- a/front/admin/sitmun-admin-app +++ b/front/admin/sitmun-admin-app @@ -1 +1 @@ -Subproject commit 5d7dca22360d77245a0df7858e570a96347ab1c9 +Subproject commit 6d924820f6e307ae64704c1b82cc606518c52fa1 diff --git a/front/viewer/sitmun-viewer-app b/front/viewer/sitmun-viewer-app index 32c7b08..3f79db3 160000 --- a/front/viewer/sitmun-viewer-app +++ b/front/viewer/sitmun-viewer-app @@ -1 +1 @@ -Subproject commit 32c7b08591bf7613c87e64143896c5db07b2a435 +Subproject commit 3f79db37da2a7b2509840f3fe410463676366a88 diff --git a/playwright.viewer.config.ts b/playwright.viewer.config.ts index 86d78ac..6c481fd 100644 --- a/playwright.viewer.config.ts +++ b/playwright.viewer.config.ts @@ -104,5 +104,11 @@ export default defineConfig({ testMatch: /gfi-html-embed\.spec\.ts/, use: { ...devices['Desktop Chrome'] }, }, + { + name: 'viewer-gfi-fields', + testMatch: /gfi-field-list\.spec\.ts/, + dependencies: ['viewer-setup'], + use: { ...devices['Desktop Chrome'] }, + }, ], }); diff --git a/profiles/development/backend/liquibase/changelog/74_feature_info_field_format.yaml b/profiles/development/backend/liquibase/changelog/74_feature_info_field_format.yaml new file mode 100644 index 0000000..4ad5667 --- /dev/null +++ b/profiles/development/backend/liquibase/changelog/74_feature_info_field_format.yaml @@ -0,0 +1,92 @@ +databaseChangeLog: + - changeSet: + id: 23-feature-info-options-h2 + author: sitmun + dbms: h2 + changes: + - addColumn: + tableName: STM_PAR_GI + columns: + - column: + name: PGI_OPTIONS + type: CLOB + - changeSet: + id: 23-feature-info-options-postgresql + author: sitmun + dbms: postgresql + changes: + - addColumn: + tableName: STM_PAR_GI + columns: + - column: + name: PGI_OPTIONS + type: TEXT + - changeSet: + id: 23-feature-info-options-oracle + author: sitmun + dbms: oracle + changes: + - addColumn: + tableName: STM_PAR_GI + columns: + - column: + name: PGI_OPTIONS + type: CLOB + - changeSet: + id: 23-feature-info-auto-h2 + author: sitmun + dbms: h2 + changes: + - sql: + sql: > + INSERT INTO STM_CODELIST (COD_ID, COD_LIST, COD_VALUE, COD_SYSTEM, COD_DEFAULT, COD_DESCRIPTION) + SELECT (SELECT COALESCE(MAX(COD_ID), 0) + 1 FROM STM_CODELIST), + 'cartographyParameter.format', 'AUTO', FALSE, FALSE, 'Automatic' + WHERE NOT EXISTS ( + SELECT 1 FROM STM_CODELIST + WHERE COD_LIST = 'cartographyParameter.format' AND COD_VALUE = 'AUTO' + ); + - sql: + sql: > + UPDATE STM_SEQUENCE + SET SEQ_COUNT = (SELECT COALESCE(MAX(COD_ID), 0) + 1 FROM STM_CODELIST) + WHERE SEQ_NAME = 'COD_ID'; + - changeSet: + id: 23-feature-info-auto-postgresql + author: sitmun + dbms: postgresql + changes: + - sql: + sql: > + INSERT INTO STM_CODELIST (COD_ID, COD_LIST, COD_VALUE, COD_SYSTEM, COD_DEFAULT, COD_DESCRIPTION) + SELECT (SELECT COALESCE(MAX(COD_ID), 0) + 1 FROM STM_CODELIST), + 'cartographyParameter.format', 'AUTO', FALSE, FALSE, 'Automatic' + WHERE NOT EXISTS ( + SELECT 1 FROM STM_CODELIST + WHERE COD_LIST = 'cartographyParameter.format' AND COD_VALUE = 'AUTO' + ); + - sql: + sql: > + UPDATE STM_SEQUENCE + SET SEQ_COUNT = (SELECT COALESCE(MAX(COD_ID), 0) + 1 FROM STM_CODELIST) + WHERE SEQ_NAME = 'COD_ID'; + - changeSet: + id: 23-feature-info-auto-oracle + author: sitmun + dbms: oracle + changes: + - sql: + sql: > + INSERT INTO STM_CODELIST (COD_ID, COD_LIST, COD_VALUE, COD_SYSTEM, COD_DEFAULT, COD_DESCRIPTION) + SELECT (SELECT COALESCE(MAX(COD_ID), 0) + 1 FROM STM_CODELIST), + 'cartographyParameter.format', 'AUTO', 0, 0, 'Automatic' + FROM DUAL + WHERE NOT EXISTS ( + SELECT 1 FROM STM_CODELIST + WHERE COD_LIST = 'cartographyParameter.format' AND COD_VALUE = 'AUTO' + ); + - sql: + sql: > + UPDATE STM_SEQUENCE + SET SEQ_COUNT = (SELECT COALESCE(MAX(COD_ID), 0) + 1 FROM STM_CODELIST) + WHERE SEQ_NAME = 'COD_ID'; diff --git a/profiles/development/backend/liquibase/changelog/75_dev_feature_info_fields.yaml b/profiles/development/backend/liquibase/changelog/75_dev_feature_info_fields.yaml new file mode 100644 index 0000000..9f4040c --- /dev/null +++ b/profiles/development/backend/liquibase/changelog/75_dev_feature_info_fields.yaml @@ -0,0 +1,88 @@ +databaseChangeLog: + - changeSet: + id: 75-dev-feature-info-fields-postgresql + author: sitmun + context: dev + dbms: postgresql + comment: > + IDE genèric Menorca (application 12). Identify Trams del camí de cavalls + (cartography 1304, layer tu007rts_ccavalls). English labels are PGI_VALUE; + Spanish and Catalan come from STM_TRANSLATION. + preConditions: + - onFail: MARK_RAN + sqlCheck: + expectedResult: 1 + sql: > + SELECT CASE + WHEN (SELECT COUNT(*) FROM STM_PAR_GI WHERE PGI_ID = 9101) = 0 + AND (SELECT COUNT(*) FROM STM_GEOINFO WHERE GEO_ID = 1304) = 1 + THEN 1 ELSE 0 END + changes: + - sql: + sql: | + INSERT INTO STM_PAR_GI ( + PGI_ID, PGI_NAME, PGI_VALUE, PGI_FORMAT, PGI_TYPE, PGI_GIID, PGI_ORDER, + PGI_OPTIONS + ) VALUES + (9101, 'nomruta', 'Route', 'T', 'INFO', 1304, 0, NULL), + (9102, 'dstipus', 'Kind', 'AUTO', 'INFO', 1304, 1, NULL), + (9103, 'etrsxmax', 'Max easting', 'N', 'INFO', 1304, 2, '{"fractionDigits":0}'), + (9104, 'link', 'Website', 'U', 'INFO', 1304, 3, NULL); + INSERT INTO STM_TRANSLATION (TRA_ID, TRA_ELEID, TRA_COLUMN, TRA_LANID, TRA_NAME) VALUES + (9101001, 9101, 'CartographyParameter.value', 2, 'Ruta'), + (9101002, 9101, 'CartographyParameter.value', 3, 'Ruta'), + (9101003, 9102, 'CartographyParameter.value', 2, 'Tipo'), + (9101004, 9102, 'CartographyParameter.value', 3, 'Tipus'), + (9101005, 9103, 'CartographyParameter.value', 2, 'Este máximo'), + (9101006, 9103, 'CartographyParameter.value', 3, 'Est màxim'), + (9101007, 9104, 'CartographyParameter.value', 2, 'Enlace'), + (9101008, 9104, 'CartographyParameter.value', 3, 'Enllaç'); + UPDATE STM_SEQUENCE + SET SEQ_COUNT = GREATEST(SEQ_COUNT, (SELECT COALESCE(MAX(PGI_ID), 0) + 1 FROM STM_PAR_GI)) + WHERE SEQ_NAME = 'PGI_ID'; + UPDATE STM_SEQUENCE + SET SEQ_COUNT = GREATEST(SEQ_COUNT, (SELECT COALESCE(MAX(TRA_ID), 0) + 1 FROM STM_TRANSLATION)) + WHERE SEQ_NAME = 'TRA_ID'; + - changeSet: + id: 75-dev-feature-info-fields-oracle + author: sitmun + context: dev + dbms: oracle + comment: > + IDE genèric Menorca (application 12). Identify Trams del camí de cavalls + (cartography 1304, layer tu007rts_ccavalls). + preConditions: + - onFail: MARK_RAN + sqlCheck: + expectedResult: 1 + sql: > + SELECT CASE + WHEN (SELECT COUNT(*) FROM STM_PAR_GI WHERE PGI_ID = 9101) = 0 + AND (SELECT COUNT(*) FROM STM_GEOINFO WHERE GEO_ID = 1304) = 1 + THEN 1 ELSE 0 END + changes: + - sql: + sql: | + INSERT INTO STM_PAR_GI ( + PGI_ID, PGI_NAME, PGI_VALUE, PGI_FORMAT, PGI_TYPE, PGI_GIID, PGI_ORDER, + PGI_OPTIONS + ) + SELECT 9101, 'nomruta', 'Route', 'T', 'INFO', 1304, 0, NULL FROM DUAL UNION ALL + SELECT 9102, 'dstipus', 'Kind', 'AUTO', 'INFO', 1304, 1, NULL FROM DUAL UNION ALL + SELECT 9103, 'etrsxmax', 'Max easting', 'N', 'INFO', 1304, 2, '{"fractionDigits":0}' FROM DUAL UNION ALL + SELECT 9104, 'link', 'Website', 'U', 'INFO', 1304, 3, NULL FROM DUAL; + INSERT INTO STM_TRANSLATION (TRA_ID, TRA_ELEID, TRA_COLUMN, TRA_LANID, TRA_NAME) + SELECT 9101001, 9101, 'CartographyParameter.value', 2, 'Ruta' FROM DUAL UNION ALL + SELECT 9101002, 9101, 'CartographyParameter.value', 3, 'Ruta' FROM DUAL UNION ALL + SELECT 9101003, 9102, 'CartographyParameter.value', 2, 'Tipo' FROM DUAL UNION ALL + SELECT 9101004, 9102, 'CartographyParameter.value', 3, 'Tipus' FROM DUAL UNION ALL + SELECT 9101005, 9103, 'CartographyParameter.value', 2, 'Este máximo' FROM DUAL UNION ALL + SELECT 9101006, 9103, 'CartographyParameter.value', 3, 'Est màxim' FROM DUAL UNION ALL + SELECT 9101007, 9104, 'CartographyParameter.value', 2, 'Enlace' FROM DUAL UNION ALL + SELECT 9101008, 9104, 'CartographyParameter.value', 3, 'Enllaç' FROM DUAL; + UPDATE STM_SEQUENCE + SET SEQ_COUNT = GREATEST(SEQ_COUNT, (SELECT COALESCE(MAX(PGI_ID), 0) + 1 FROM STM_PAR_GI)) + WHERE SEQ_NAME = 'PGI_ID'; + UPDATE STM_SEQUENCE + SET SEQ_COUNT = GREATEST(SEQ_COUNT, (SELECT COALESCE(MAX(TRA_ID), 0) + 1 FROM STM_TRANSLATION)) + WHERE SEQ_NAME = 'TRA_ID'; diff --git a/profiles/development/backend/liquibase/master.xml b/profiles/development/backend/liquibase/master.xml index 02af712..3af0448 100644 --- a/profiles/development/backend/liquibase/master.xml +++ b/profiles/development/backend/liquibase/master.xml @@ -80,4 +80,6 @@ + + diff --git a/profiles/oracle/liquibase/changelog/27_feature_info_field_format.yaml b/profiles/oracle/liquibase/changelog/27_feature_info_field_format.yaml new file mode 100644 index 0000000..4ad5667 --- /dev/null +++ b/profiles/oracle/liquibase/changelog/27_feature_info_field_format.yaml @@ -0,0 +1,92 @@ +databaseChangeLog: + - changeSet: + id: 23-feature-info-options-h2 + author: sitmun + dbms: h2 + changes: + - addColumn: + tableName: STM_PAR_GI + columns: + - column: + name: PGI_OPTIONS + type: CLOB + - changeSet: + id: 23-feature-info-options-postgresql + author: sitmun + dbms: postgresql + changes: + - addColumn: + tableName: STM_PAR_GI + columns: + - column: + name: PGI_OPTIONS + type: TEXT + - changeSet: + id: 23-feature-info-options-oracle + author: sitmun + dbms: oracle + changes: + - addColumn: + tableName: STM_PAR_GI + columns: + - column: + name: PGI_OPTIONS + type: CLOB + - changeSet: + id: 23-feature-info-auto-h2 + author: sitmun + dbms: h2 + changes: + - sql: + sql: > + INSERT INTO STM_CODELIST (COD_ID, COD_LIST, COD_VALUE, COD_SYSTEM, COD_DEFAULT, COD_DESCRIPTION) + SELECT (SELECT COALESCE(MAX(COD_ID), 0) + 1 FROM STM_CODELIST), + 'cartographyParameter.format', 'AUTO', FALSE, FALSE, 'Automatic' + WHERE NOT EXISTS ( + SELECT 1 FROM STM_CODELIST + WHERE COD_LIST = 'cartographyParameter.format' AND COD_VALUE = 'AUTO' + ); + - sql: + sql: > + UPDATE STM_SEQUENCE + SET SEQ_COUNT = (SELECT COALESCE(MAX(COD_ID), 0) + 1 FROM STM_CODELIST) + WHERE SEQ_NAME = 'COD_ID'; + - changeSet: + id: 23-feature-info-auto-postgresql + author: sitmun + dbms: postgresql + changes: + - sql: + sql: > + INSERT INTO STM_CODELIST (COD_ID, COD_LIST, COD_VALUE, COD_SYSTEM, COD_DEFAULT, COD_DESCRIPTION) + SELECT (SELECT COALESCE(MAX(COD_ID), 0) + 1 FROM STM_CODELIST), + 'cartographyParameter.format', 'AUTO', FALSE, FALSE, 'Automatic' + WHERE NOT EXISTS ( + SELECT 1 FROM STM_CODELIST + WHERE COD_LIST = 'cartographyParameter.format' AND COD_VALUE = 'AUTO' + ); + - sql: + sql: > + UPDATE STM_SEQUENCE + SET SEQ_COUNT = (SELECT COALESCE(MAX(COD_ID), 0) + 1 FROM STM_CODELIST) + WHERE SEQ_NAME = 'COD_ID'; + - changeSet: + id: 23-feature-info-auto-oracle + author: sitmun + dbms: oracle + changes: + - sql: + sql: > + INSERT INTO STM_CODELIST (COD_ID, COD_LIST, COD_VALUE, COD_SYSTEM, COD_DEFAULT, COD_DESCRIPTION) + SELECT (SELECT COALESCE(MAX(COD_ID), 0) + 1 FROM STM_CODELIST), + 'cartographyParameter.format', 'AUTO', 0, 0, 'Automatic' + FROM DUAL + WHERE NOT EXISTS ( + SELECT 1 FROM STM_CODELIST + WHERE COD_LIST = 'cartographyParameter.format' AND COD_VALUE = 'AUTO' + ); + - sql: + sql: > + UPDATE STM_SEQUENCE + SET SEQ_COUNT = (SELECT COALESCE(MAX(COD_ID), 0) + 1 FROM STM_CODELIST) + WHERE SEQ_NAME = 'COD_ID'; diff --git a/profiles/oracle/liquibase/master.xml b/profiles/oracle/liquibase/master.xml index d901d0b..8a8b5f2 100644 --- a/profiles/oracle/liquibase/master.xml +++ b/profiles/oracle/liquibase/master.xml @@ -31,4 +31,5 @@ + diff --git a/profiles/postgres/liquibase/changelog/27_feature_info_field_format.yaml b/profiles/postgres/liquibase/changelog/27_feature_info_field_format.yaml new file mode 100644 index 0000000..4ad5667 --- /dev/null +++ b/profiles/postgres/liquibase/changelog/27_feature_info_field_format.yaml @@ -0,0 +1,92 @@ +databaseChangeLog: + - changeSet: + id: 23-feature-info-options-h2 + author: sitmun + dbms: h2 + changes: + - addColumn: + tableName: STM_PAR_GI + columns: + - column: + name: PGI_OPTIONS + type: CLOB + - changeSet: + id: 23-feature-info-options-postgresql + author: sitmun + dbms: postgresql + changes: + - addColumn: + tableName: STM_PAR_GI + columns: + - column: + name: PGI_OPTIONS + type: TEXT + - changeSet: + id: 23-feature-info-options-oracle + author: sitmun + dbms: oracle + changes: + - addColumn: + tableName: STM_PAR_GI + columns: + - column: + name: PGI_OPTIONS + type: CLOB + - changeSet: + id: 23-feature-info-auto-h2 + author: sitmun + dbms: h2 + changes: + - sql: + sql: > + INSERT INTO STM_CODELIST (COD_ID, COD_LIST, COD_VALUE, COD_SYSTEM, COD_DEFAULT, COD_DESCRIPTION) + SELECT (SELECT COALESCE(MAX(COD_ID), 0) + 1 FROM STM_CODELIST), + 'cartographyParameter.format', 'AUTO', FALSE, FALSE, 'Automatic' + WHERE NOT EXISTS ( + SELECT 1 FROM STM_CODELIST + WHERE COD_LIST = 'cartographyParameter.format' AND COD_VALUE = 'AUTO' + ); + - sql: + sql: > + UPDATE STM_SEQUENCE + SET SEQ_COUNT = (SELECT COALESCE(MAX(COD_ID), 0) + 1 FROM STM_CODELIST) + WHERE SEQ_NAME = 'COD_ID'; + - changeSet: + id: 23-feature-info-auto-postgresql + author: sitmun + dbms: postgresql + changes: + - sql: + sql: > + INSERT INTO STM_CODELIST (COD_ID, COD_LIST, COD_VALUE, COD_SYSTEM, COD_DEFAULT, COD_DESCRIPTION) + SELECT (SELECT COALESCE(MAX(COD_ID), 0) + 1 FROM STM_CODELIST), + 'cartographyParameter.format', 'AUTO', FALSE, FALSE, 'Automatic' + WHERE NOT EXISTS ( + SELECT 1 FROM STM_CODELIST + WHERE COD_LIST = 'cartographyParameter.format' AND COD_VALUE = 'AUTO' + ); + - sql: + sql: > + UPDATE STM_SEQUENCE + SET SEQ_COUNT = (SELECT COALESCE(MAX(COD_ID), 0) + 1 FROM STM_CODELIST) + WHERE SEQ_NAME = 'COD_ID'; + - changeSet: + id: 23-feature-info-auto-oracle + author: sitmun + dbms: oracle + changes: + - sql: + sql: > + INSERT INTO STM_CODELIST (COD_ID, COD_LIST, COD_VALUE, COD_SYSTEM, COD_DEFAULT, COD_DESCRIPTION) + SELECT (SELECT COALESCE(MAX(COD_ID), 0) + 1 FROM STM_CODELIST), + 'cartographyParameter.format', 'AUTO', 0, 0, 'Automatic' + FROM DUAL + WHERE NOT EXISTS ( + SELECT 1 FROM STM_CODELIST + WHERE COD_LIST = 'cartographyParameter.format' AND COD_VALUE = 'AUTO' + ); + - sql: + sql: > + UPDATE STM_SEQUENCE + SET SEQ_COUNT = (SELECT COALESCE(MAX(COD_ID), 0) + 1 FROM STM_CODELIST) + WHERE SEQ_NAME = 'COD_ID'; diff --git a/profiles/postgres/liquibase/master.xml b/profiles/postgres/liquibase/master.xml index 82804b7..eeecabe 100644 --- a/profiles/postgres/liquibase/master.xml +++ b/profiles/postgres/liquibase/master.xml @@ -29,4 +29,5 @@ +