From 915728999d7d04fc4a7ab10b47c45661425b905c Mon Sep 17 00:00:00 2001 From: AsaArrhen <72498716+AsaArrhen@users.noreply.github.com> Date: Tue, 5 Nov 2024 10:02:41 +0100 Subject: [PATCH 1/9] Create Asa --- docs/project/Asa | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/project/Asa diff --git a/docs/project/Asa b/docs/project/Asa new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/docs/project/Asa @@ -0,0 +1 @@ + From ce24905d4dae83e5b339abc8bcb07aa16b308fc6 Mon Sep 17 00:00:00 2001 From: AsaArrhen <72498716+AsaArrhen@users.noreply.github.com> Date: Tue, 5 Nov 2024 10:08:01 +0100 Subject: [PATCH 2/9] Update plans.md --- docs/project/plans.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/project/plans.md b/docs/project/plans.md index a8ff23f0..e4a2e948 100644 --- a/docs/project/plans.md +++ b/docs/project/plans.md @@ -1,20 +1,19 @@ # Plans -The project has different goals, and one of them is to launch a test-version of PxWeb in mid 2024. -Another goal is to deliver a beta-version of PxWeb based on PxWebAPI 2.0 during 2024. +The project has different goals, one of which is to launch a test-version of PxWeb 2.0 in mid 2024. Another goal is to deliver a version of PxWeb 2.0 based on PxWebAPI 2.0 during spring 2025. ## PxWeb 2.0 delivery testversion June 2024 - New PxWeb page with variablebox and table, getting data from API 2.0 - Language management - Algorithm for choosing the best result for displaying a table -- Chose different values in variable and see changes in the table +- Choose different values in variable and see changes in the table ![Picture of detail-page of variabel and the table in PxWeb 2.0](https://github.com/PxTools/PxWeb2/assets/81364833/39acd512-a589-4734-af96-4e76983f644d) -## Maintasks autumn 2024 +## Maintasks spring 2025 - Main-page for PxWeb 2.0 - Graph From ca8f91794a1176087ee4f054b5846b558445126e Mon Sep 17 00:00:00 2001 From: AsaArrhen <72498716+AsaArrhen@users.noreply.github.com> Date: Tue, 5 Nov 2024 10:10:27 +0100 Subject: [PATCH 3/9] Delete docs/project/Asa --- docs/project/Asa | 1 - 1 file changed, 1 deletion(-) delete mode 100644 docs/project/Asa diff --git a/docs/project/Asa b/docs/project/Asa deleted file mode 100644 index 8b137891..00000000 --- a/docs/project/Asa +++ /dev/null @@ -1 +0,0 @@ - From 16b81b8c93a35bf6245cb8ceae458d69c74d5cc4 Mon Sep 17 00:00:00 2001 From: Michael Pande Date: Tue, 12 Nov 2024 13:27:20 +0100 Subject: [PATCH 4/9] Pxweb2 384 fix unit tests for variable box (#334) * Preload fonts * PXWEB2-384 fix unit tests for variablebox --- .../VariableBox/VariableBox.spec.tsx | 4 +- .../VariableList/VariableList.spec.tsx | 61 +++++++++++++------ 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBox.spec.tsx b/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBox.spec.tsx index 2a75e2a5..ea114cea 100644 --- a/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBox.spec.tsx +++ b/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBox.spec.tsx @@ -1,6 +1,7 @@ import { render } from '@testing-library/react'; import VariableBox from './VariableBox'; +import { VartypeEnum } from '../../../lib/shared-types/vartypeEnum'; describe('VariableBox', () => { it('should render successfully', () => { @@ -22,9 +23,10 @@ describe('VariableBox', () => { return; }} selectedValues={[]} + type={VartypeEnum.CONTENTS_VARIABLE} /> ); - + expect(baseElement).toBeTruthy(); }); }); diff --git a/libs/pxweb2-ui/src/lib/components/VariableList/VariableList.spec.tsx b/libs/pxweb2-ui/src/lib/components/VariableList/VariableList.spec.tsx index 13633236..38ad5754 100644 --- a/libs/pxweb2-ui/src/lib/components/VariableList/VariableList.spec.tsx +++ b/libs/pxweb2-ui/src/lib/components/VariableList/VariableList.spec.tsx @@ -1,6 +1,6 @@ import { render } from '@testing-library/react'; - -import VariableBoxList from './VariableList'; +import { VirtuosoMockContext } from 'react-virtuoso'; +import { VariableList } from './VariableList'; import { PxTableMetadata } from '../../shared-types/pxTableMetadata'; import { VartypeEnum } from '../../shared-types/vartypeEnum'; @@ -27,7 +27,9 @@ const mockPxTableMetadataSingle: PxTableMetadata = { type: VartypeEnum.CONTENTS_VARIABLE, }, ], + language: 'sv', }; + const mockPxTableMetadataMultiple: PxTableMetadata = { id: '1', label: 'Mock Table', @@ -64,12 +66,13 @@ const mockPxTableMetadataMultiple: PxTableMetadata = { type: VartypeEnum.CONTENTS_VARIABLE, }, ], + language: 'sv', }; -describe('VariableBoxList', () => { +describe('VariableList', () => { it('should render successfully', () => { const { baseElement } = render( - { it('should render a VariableBox for each variable in the metadata', () => { const { getByText } = render( - { handleMixedCheckboxChange={() => { return; }} - /> + />, + { + wrapper: ({ children }) => ( + + {children} + + ), + } ); expect(getByText('Test Variable')).toBeTruthy(); expect(getByText('Test Variable 2')).toBeTruthy(); }); - /* TODO: Fix this test - it('should render a VariableBox with the correct values', () => { + it('should render a VariableBox with the correct values', () => { const { getByText } = render( - { handleMixedCheckboxChange={() => { return; }} - /> + />, + { + wrapper: ({ children }) => ( + + {children} + + ), + } ); expect(getByText('Test Variable 1 Value 1')).toBeTruthy(); expect(getByText('Test Variable 1 Value 2')).toBeTruthy(); - }); */ + }); - /* -TODO: Fix this test -it('should only render the values for the first VariableBox', () => { + it('should only render the values for the first VariableBox', () => { const { getByText, queryByText } = render( - { handleMixedCheckboxChange={() => { return; }} - /> + />, + { + wrapper: ({ children }) => ( + + {children} + + ), + } ); expect(getByText('Test Value')).toBeTruthy(); expect(queryByText('Test Variable 2 Value 1')).toBeNull(); expect(queryByText('Test Variable 2 Value 2')).toBeNull(); - }); */ + }); }); From 7da69702039fb3570ba38150cf63ae926dd15672 Mon Sep 17 00:00:00 2001 From: Sjur Sutterud Sagen Date: Tue, 12 Nov 2024 15:07:43 +0100 Subject: [PATCH 5/9] Update the API-query for the metadata (#335) This updates the API-query for the metadata to ask for the values used in the defaultSelection, and not the standard values. Also added a try/catch to the mapper to output something when the mapper fails. --- .../app/components/Selection/Selection.tsx | 8 +- .../mappers/TableMetadataResponseMapper.ts | 115 +++-- libs/pxweb2-api-client/src/index.ts | 1 + .../src/models/ConfigResponse.ts | 6 +- .../src/models/VariablePlacementType.ts | 15 + .../src/models/VariablesSelection.ts | 2 + .../src/services/TableService.ts | 471 +++++++++--------- 7 files changed, 337 insertions(+), 281 deletions(-) create mode 100644 libs/pxweb2-api-client/src/models/VariablePlacementType.ts diff --git a/apps/pxweb2/src/app/components/Selection/Selection.tsx b/apps/pxweb2/src/app/components/Selection/Selection.tsx index b5dc3804..ce7853c5 100644 --- a/apps/pxweb2/src/app/components/Selection/Selection.tsx +++ b/apps/pxweb2/src/app/components/Selection/Selection.tsx @@ -1,7 +1,7 @@ import { useTranslation } from 'react-i18next'; import { useState, useEffect } from 'react'; -import { TableService } from '@pxweb2/pxweb2-api-client'; +import { metadataOutputFormat, MetadataOutputFormatType, TableService } from '@pxweb2/pxweb2-api-client'; import { mapTableMetadataResponse } from '../../../mappers/TableMetadataResponseMapper'; import { mapTableSelectionResponse } from '../../../mappers/TableSelectionResponseMapper'; import { @@ -211,11 +211,15 @@ export function Selection({ variables.setIsLoadingMetadata(true); } - TableService.getMetadataById(selectedTabId, i18n.resolvedLanguage) + const outputFormat: metadataOutputFormat = MetadataOutputFormatType.JSON_PX; + const metaDataDefaultSelection = true; + + TableService.getMetadataById(selectedTabId, i18n.resolvedLanguage, outputFormat, metaDataDefaultSelection) .then((tableMetadataResponse) => { const pxTabMetadata: PxTableMetadata = mapTableMetadataResponse( tableMetadataResponse ); + setPxTableMetadata(pxTabMetadata); if (pxTableMetaToRender !== null) { setPxTableMetaToRender(null); diff --git a/apps/pxweb2/src/mappers/TableMetadataResponseMapper.ts b/apps/pxweb2/src/mappers/TableMetadataResponseMapper.ts index 5c910f73..028a59d2 100644 --- a/apps/pxweb2/src/mappers/TableMetadataResponseMapper.ts +++ b/apps/pxweb2/src/mappers/TableMetadataResponseMapper.ts @@ -1,59 +1,78 @@ -import { AbstractCodeListVariable, TableMetadataResponse, VariableTypeEnum } from "@pxweb2/pxweb2-api-client"; -import { PxTableMetadata, VartypeEnum } from "@pxweb2/pxweb2-ui"; - -export function mapTableMetadataResponse(response: TableMetadataResponse): PxTableMetadata { +import { + AbstractCodeListVariable, + TableMetadataResponse, + VariableTypeEnum, +} from '@pxweb2/pxweb2-api-client'; +import { PxTableMetadata, VartypeEnum } from '@pxweb2/pxweb2-ui'; +export function mapTableMetadataResponse( + response: TableMetadataResponse +): PxTableMetadata { + try { const pxTableMetadata: PxTableMetadata = { - id: response.id, - label: response.label, - updated: response.updated ? new Date(response.updated) : new Date(), - variables: response.variables.map((variable) => { + id: response.id, + label: response.label, + updated: response.updated ? new Date(response.updated) : new Date(), + variables: response.variables.map((variable) => { + return { + id: variable.id, + label: variable.label, + type: mapVariableTypeEnum(variable.type), + mandatory: + (variable as AbstractCodeListVariable).elimination != null + ? !(variable as AbstractCodeListVariable).elimination + : true, + values: (variable as AbstractCodeListVariable).values.map((value) => { + return { + label: value.label, + code: value.code, + notes: value.notes?.map((note) => { + return { + text: note.text, + mandatory: note.mandatory != null ? note.mandatory : false, + }; + }), + }; + }), + codeLists: (variable as AbstractCodeListVariable).codeLists?.map( + (codeList) => { + return { + id: codeList.id, + label: codeList.label, + }; + } + ), + notes: variable.notes?.map((note) => { return { - id: variable.id, - label: variable.label, - type: mapVariableTypeEnum(variable.type), - mandatory: (variable as AbstractCodeListVariable).elimination != null ? !(variable as AbstractCodeListVariable).elimination : true, - values: (variable as AbstractCodeListVariable).values.map((value) => { - return { - label: value.label, - code: value.code, - notes: value.notes?.map((note) => { - return { - text: note.text, - mandatory: note.mandatory != null ? note.mandatory : false - }; - }) - }; - }), - codeLists: (variable as AbstractCodeListVariable).codeLists?.map((codeList) => { - return { - id: codeList.id, - label: codeList.label, - }; - }), - notes: variable.notes?.map((note) => { - return { - text: note.text, - mandatory: note.mandatory != null ? note.mandatory : false - }; - }) + text: note.text, + mandatory: note.mandatory != null ? note.mandatory : false, }; - }), - language: "" + }), + }; + }), + language: '', }; return pxTableMetadata; + } catch (error) { + console.error('Error mapping table metadata response', error); + throw new Error('Error mapping table metadata response'); + } } function mapVariableTypeEnum(type: VariableTypeEnum): VartypeEnum { - switch (type) { - case VariableTypeEnum.CONTENTS_VARIABLE: - return VartypeEnum.CONTENTS_VARIABLE; - case VariableTypeEnum.TIME_VARIABLE: - return VartypeEnum.TIME_VARIABLE; - case VariableTypeEnum.GEOGRAPHICAL_VARIABLE: - return VartypeEnum.GEOGRAPHICAL_VARIABLE; - case VariableTypeEnum.REGULAR_VARIABLE: - return VartypeEnum.REGULAR_VARIABLE; - } + switch (type) { + case VariableTypeEnum.CONTENTS_VARIABLE: + return VartypeEnum.CONTENTS_VARIABLE; + case VariableTypeEnum.TIME_VARIABLE: + return VartypeEnum.TIME_VARIABLE; + case VariableTypeEnum.GEOGRAPHICAL_VARIABLE: + return VartypeEnum.GEOGRAPHICAL_VARIABLE; + case VariableTypeEnum.REGULAR_VARIABLE: + return VartypeEnum.REGULAR_VARIABLE; + default: + throw new Error( + `Unknown variable type in mapTableMetadataResponse: ${type}` + ); + } } diff --git a/libs/pxweb2-api-client/src/index.ts b/libs/pxweb2-api-client/src/index.ts index 9b33d3ff..14870b0f 100644 --- a/libs/pxweb2-api-client/src/index.ts +++ b/libs/pxweb2-api-client/src/index.ts @@ -71,6 +71,7 @@ export { TimeVariable } from './models/TimeVariable'; export type { updated } from './models/updated'; export type { Value } from './models/Value'; export type { ValueMap } from './models/ValueMap'; +export type { VariablePlacementType } from './models/VariablePlacementType'; export type { VariableSelection } from './models/VariableSelection'; export type { VariablesSelection } from './models/VariablesSelection'; export { VariableTypeEnum } from './models/VariableTypeEnum'; diff --git a/libs/pxweb2-api-client/src/models/ConfigResponse.ts b/libs/pxweb2-api-client/src/models/ConfigResponse.ts index c861ff8d..c0966db7 100644 --- a/libs/pxweb2-api-client/src/models/ConfigResponse.ts +++ b/libs/pxweb2-api-client/src/models/ConfigResponse.ts @@ -11,9 +11,13 @@ import type { SourceReference } from './SourceReference'; */ export type ConfigResponse = { /** - * The version of then API + * The version of the API spesification */ apiVersion: string; + /** + * The version of the API implementation + */ + appVersion: string; /** * A list of language that exists for the data. */ diff --git a/libs/pxweb2-api-client/src/models/VariablePlacementType.ts b/libs/pxweb2-api-client/src/models/VariablePlacementType.ts new file mode 100644 index 00000000..26a0c6ac --- /dev/null +++ b/libs/pxweb2-api-client/src/models/VariablePlacementType.ts @@ -0,0 +1,15 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type VariablePlacementType = { + /** + * List of variables that should be placed in the heading in the resulting data + */ + heading?: Array; + /** + * List of variables that should be placed in the stub in the resulting data + */ + stub?: Array; +}; + diff --git a/libs/pxweb2-api-client/src/models/VariablesSelection.ts b/libs/pxweb2-api-client/src/models/VariablesSelection.ts index 89f33139..aed4f09b 100644 --- a/libs/pxweb2-api-client/src/models/VariablesSelection.ts +++ b/libs/pxweb2-api-client/src/models/VariablesSelection.ts @@ -2,8 +2,10 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ +import type { VariablePlacementType } from './VariablePlacementType'; import type { VariableSelection } from './VariableSelection'; export type VariablesSelection = { selection: Array; + palcement?: VariablePlacementType; }; diff --git a/libs/pxweb2-api-client/src/services/TableService.ts b/libs/pxweb2-api-client/src/services/TableService.ts index e0240192..44fce829 100644 --- a/libs/pxweb2-api-client/src/services/TableService.ts +++ b/libs/pxweb2-api-client/src/services/TableService.ts @@ -14,234 +14,245 @@ import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; import { request as __request } from '../core/request'; export class TableService { - /** - * Get all Tables. - * @param lang The language if the default is not what you want. - * @param query Selects only tables that that matches a criteria which is specified by the search parameter. - * @param pastDays Selects only tables that was updated from the time of execution going back number of days stated by the parameter pastDays. Valid values for past days are integers between 1 and ? - * @param includeDiscontinued Decides if discontinued tables are included in response. - * @param pageNumber Pagination: Decides which page number to return - * @param pageSize Pagination: Decides how many tables per page - * @returns TablesResponse Success - * @throws ApiError - */ - public static listAllTables( - lang?: string | null, - query?: string, - pastDays?: number, - includeDiscontinued: boolean = false, - pageNumber: number = 1, - pageSize?: number - ): CancelablePromise { - return __request(OpenAPI, { - method: 'GET', - url: '/tables', - query: { - lang: lang, - query: query, - pastDays: pastDays, - includeDiscontinued: includeDiscontinued, - pageNumber: pageNumber, - pageSize: pageSize, - }, - }); - } - /** - * Get Table by {id}. - * @param id Id - * @param lang The language if the default is not what you want. - * @returns TableResponse Success - * @throws ApiError - */ - public static getTableById( - id: string, - lang?: string | null - ): CancelablePromise { - return __request(OpenAPI, { - method: 'GET', - url: '/tables/{id}', - path: { - id: id, - }, - query: { - lang: lang, - }, - errors: { - 400: `Error respsone for 400`, - 404: `Error respsone for 404`, - 429: `Error respsone for 429`, - }, - }); - } - /** - * Get Metadata about Table by {id}. - * **Used for listing detailed information about a specific table** - * * List all variables and values and all other metadata needed to be able to fetch data - * - * * Also links to where to: - * + Fetch - * - Where to get information about codelists - * - * * 2 output formats - * + Custom json - * - JSON-stat2 - * - * @param id Id - * @param lang The language if the default is not what you want. - * @param outputFormat The format of the resulting metadata - * @returns TableMetadataResponse Success - * @throws ApiError - */ - public static getMetadataById( - id: string, - lang?: string | null, - outputFormat?: MetadataOutputFormatType - ): CancelablePromise { - return __request(OpenAPI, { - method: 'GET', - url: '/tables/{id}/metadata', - path: { - id: id, - }, - query: { - lang: lang, - outputFormat: outputFormat, - }, - errors: { - 400: `Error respsone for 400`, - 404: `Error respsone for 404`, - 429: `Error respsone for 429`, - }, - }); - } - /** - * Get the default selection for Table by {id}. - * Get information about what is selected for the table by default when no selection is made i the /data endpoint. - * @param id Id - * @param lang The language if the default is not what you want. - * @returns SelectionResponse Success - * @throws ApiError - */ - public static getDefaultSelection( - id: string, - lang?: string | null - ): CancelablePromise { - return __request(OpenAPI, { - method: 'GET', - url: '/tables/{id}/defaultselection', - path: { - id: id, - }, - query: { - lang: lang, - }, - errors: { - 400: `Error respsone for 400`, - 404: `Error respsone for 404`, - 429: `Error respsone for 429`, - }, - }); - } - /** - * Get Codelist by {id}. - * @param id Id - * @param lang The language if the default is not what you want. - * @returns CodeListResponse Success - * @throws ApiError - */ - public static getTableCodeListById( - id: string, - lang?: string | null - ): CancelablePromise { - return __request(OpenAPI, { - method: 'GET', - url: '/codelists/{id}', - path: { - id: id, - }, - query: { - lang: lang, - }, - errors: { - 400: `Error respsone for 400`, - 404: `Error respsone for 404`, - 429: `Error respsone for 429`, - }, - }); - } - /** - * Get data from table by {id}. - * @param id Id - * @param lang The language if the default is not what you want. - * @param valuecodes - * @param codelist - * @param outputvalues - * @param outputFormat - * @returns string Success - * @throws ApiError - */ - public static getTableData( - id: string, - lang?: string | null, - valuecodes?: Record>, - codelist?: Record, - outputvalues?: Record, - outputFormat?: string - ): CancelablePromise { - return __request(OpenAPI, { - method: 'GET', - url: '/tables/{id}/data', - path: { - id: id, - }, - query: { - lang: lang, - valuecodes: valuecodes, - codelist: codelist, - outputvalues: outputvalues, - outputFormat: outputFormat, - }, - errors: { - 400: `Error respsone for 400`, - 403: `Error respsone for 403`, - 404: `Error respsone for 404`, - 429: `Error respsone for 429`, - }, - }); - } - /** - * Get data from table by {id}. - * @param id Id - * @param lang The language if the default is not what you want. - * @param outputFormat - * @param requestBody A selection - * @returns string Success - * @throws ApiError - */ - public static getTableDataByPost( - id: string, - lang?: string | null, - outputFormat?: string, - requestBody?: VariablesSelection - ): CancelablePromise { - return __request(OpenAPI, { - method: 'POST', - url: '/tables/{id}/data', - path: { - id: id, - }, - query: { - lang: lang, - outputFormat: outputFormat, - }, - body: requestBody, - mediaType: 'application/json', - errors: { - 400: `Error respsone for 400`, - 403: `Error respsone for 403`, - 404: `Error respsone for 404`, - 429: `Error respsone for 429`, - }, - }); - } + /** + * Get all Tables. + * @param lang The language if the default is not what you want. + * @param query Selects only tables that that matches a criteria which is specified by the search parameter. + * @param pastDays Selects only tables that was updated from the time of execution going back number of days stated by the parameter pastDays. Valid values for past days are integers between 1 and ? + * @param includeDiscontinued Decides if discontinued tables are included in response. + * @param pageNumber Pagination: Decides which page number to return + * @param pageSize Pagination: Decides how many tables per page + * @returns TablesResponse Success + * @throws ApiError + */ + public static listAllTables( + lang?: string | null, + query?: string, + pastDays?: number, + includeDiscontinued: boolean = false, + pageNumber: number = 1, + pageSize?: number, + ): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/tables', + query: { + 'lang': lang, + 'query': query, + 'pastDays': pastDays, + 'includeDiscontinued': includeDiscontinued, + 'pageNumber': pageNumber, + 'pageSize': pageSize, + }, + }); + } + /** + * Get Table by {id}. + * @param id Id + * @param lang The language if the default is not what you want. + * @returns TableResponse Success + * @throws ApiError + */ + public static getTableById( + id: string, + lang?: string | null, + ): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/tables/{id}', + path: { + 'id': id, + }, + query: { + 'lang': lang, + }, + errors: { + 400: `Error respsone for 400`, + 404: `Error respsone for 404`, + 429: `Error respsone for 429`, + }, + }); + } + /** + * Get Metadata about Table by {id}. + * **Used for listing detailed information about a specific table** + * * List all variables and values and all other metadata needed to be able to fetch data + * + * * Also links to where to: + * + Fetch + * - Where to get information about codelists + * + * * 2 output formats + * + Custom json + * - JSON-stat2 + * + * @param id Id + * @param lang The language if the default is not what you want. + * @param outputFormat The format of the resulting metadata + * @param defaultSelection If metadata should be included as if default selection would have been applied. + * This is a technical parameter that is used by PxWeb for initial loading of tables. + * + * @returns TableMetadataResponse Success + * @throws ApiError + */ + public static getMetadataById( + id: string, + lang?: string | null, + outputFormat?: MetadataOutputFormatType, + defaultSelection: boolean = false, + ): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/tables/{id}/metadata', + path: { + 'id': id, + }, + query: { + 'lang': lang, + 'outputFormat': outputFormat, + 'defaultSelection': defaultSelection, + }, + errors: { + 400: `Error respsone for 400`, + 404: `Error respsone for 404`, + 429: `Error respsone for 429`, + }, + }); + } + /** + * Get the default selection for Table by {id}. + * Get information about what is selected for the table by default when no selection is made i the /data endpoint. + * @param id Id + * @param lang The language if the default is not what you want. + * @returns SelectionResponse Success + * @throws ApiError + */ + public static getDefaultSelection( + id: string, + lang?: string | null, + ): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/tables/{id}/defaultselection', + path: { + 'id': id, + }, + query: { + 'lang': lang, + }, + errors: { + 400: `Error respsone for 400`, + 404: `Error respsone for 404`, + 429: `Error respsone for 429`, + }, + }); + } + /** + * Get Codelist by {id}. + * @param id Id + * @param lang The language if the default is not what you want. + * @returns CodeListResponse Success + * @throws ApiError + */ + public static getTableCodeListById( + id: string, + lang?: string | null, + ): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/codelists/{id}', + path: { + 'id': id, + }, + query: { + 'lang': lang, + }, + errors: { + 400: `Error respsone for 400`, + 404: `Error respsone for 404`, + 429: `Error respsone for 429`, + }, + }); + } + /** + * Get data from table by {id}. + * @param id Id + * @param lang The language if the default is not what you want. + * @param valuecodes + * @param codelist + * @param outputvalues + * @param outputFormat + * @param heading Commaseparated list of variable codes that should be placed in the heading in the resulting data + * @param stub Commaseparated list of variable codes that should be placed in the stub in the resulting data + * @returns string Success + * @throws ApiError + */ + public static getTableData( + id: string, + lang?: string | null, + valuecodes?: Record>, + codelist?: Record, + outputvalues?: Record, + outputFormat?: string, + heading?: Array, + stub?: Array, + ): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/tables/{id}/data', + path: { + 'id': id, + }, + query: { + 'lang': lang, + 'valuecodes': valuecodes, + 'codelist': codelist, + 'outputvalues': outputvalues, + 'outputFormat': outputFormat, + 'heading': heading, + 'stub': stub, + }, + errors: { + 400: `Error respsone for 400`, + 403: `Error respsone for 403`, + 404: `Error respsone for 404`, + 429: `Error respsone for 429`, + }, + }); + } + /** + * Get data from table by {id}. + * @param id Id + * @param lang The language if the default is not what you want. + * @param outputFormat + * @param requestBody A selection + * @returns string Success + * @throws ApiError + */ + public static getTableDataByPost( + id: string, + lang?: string | null, + outputFormat?: string, + requestBody?: VariablesSelection, + ): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/tables/{id}/data', + path: { + 'id': id, + }, + query: { + 'lang': lang, + 'outputFormat': outputFormat, + }, + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Error respsone for 400`, + 403: `Error respsone for 403`, + 404: `Error respsone for 404`, + 429: `Error respsone for 429`, + }, + }); + } } From 115a8cbb2326bf33ff81f3b6ee45e85f2380864f Mon Sep 17 00:00:00 2001 From: oyessb <47382101+oyessb@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:12:30 +0100 Subject: [PATCH 6/9] =?UTF-8?q?Sticky=20items=20for=20search/select=20are?= =?UTF-8?q?=20added=20by=20topItemCount=20prop.=20When=20s=E2=80=A6=20(#33?= =?UTF-8?q?3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Sticky items for search/select are added by topItemCount prop. When scrolling down a custom TopItemList i used to override sticky div with empty fragment. * Replaced isScrolling (start/stop scrolling) with onScroll event which will triggered for every scroll change. * Set scrollingdown to false when search phrase is cleared. Decrease margin sensitivity for scroll. Remove sticky only if search is empty. --- .../VariableBoxContent/VariableBoxContent.tsx | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx b/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx index 155acea8..2830d227 100644 --- a/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx +++ b/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx @@ -2,7 +2,7 @@ import { useEffect, useRef, useState } from 'react'; import cl from 'clsx'; import { useTranslation } from 'react-i18next'; import { useDebounce } from '@uidotdev/usehooks'; -import { Virtuoso } from 'react-virtuoso'; +import { Virtuoso, VirtuosoHandle } from 'react-virtuoso'; import classes from './VariableBoxContent.module.scss'; import { Checkbox, MixedCheckbox } from '../../Checkbox/Checkbox'; @@ -209,6 +209,9 @@ export function VariableBoxContent({ { setSearch(value); + if(value === '') { + setScrollingDown(false); + } }} variant="inVariableBox" showLabel={false} @@ -264,6 +267,38 @@ export function VariableBoxContent({ } }; + //How many items should be sticky + const stickyTopValueCount = hasSevenOrMoreValues + ? 2 + : hasTwoOrMoreValues + ? 1 + : 0; + + const virtuosoRef = useRef(null); + const [lastScrollPosition, setLastScrollPosition] = useState(0); + const [scrollingDown, setScrollingDown] = useState(false); + + const handleVirtuosoScroll = () => { + if (virtuosoRef.current) { + virtuosoRef.current.getState((state) => { + const scrollTop = state.scrollTop; + const isIntentionalScrollUp = scrollTop < lastScrollPosition - 2; + const isIntentionalScrollDown = scrollTop > lastScrollPosition + 2; + + if (isIntentionalScrollDown && !scrollingDown) { + setScrollingDown(true); + } else if (isIntentionalScrollUp && scrollingDown) { + setScrollingDown(false); + } + setLastScrollPosition(scrollTop); + }); + } + }; + + // To override element styling added by Virtuoso when scrolling down + /* eslint-disable-next-line */ + const TopItemListEmptyFragment = () => <>; + return (
@@ -328,6 +363,9 @@ export function VariableBoxContent({ enter: (velocity) => Math.abs(velocity) > 1000, exit: (velocity) => Math.abs(velocity) < 30, }} + topItemCount={stickyTopValueCount} + ref={virtuosoRef} + onScroll={handleVirtuosoScroll} components={{ ScrollSeekPlaceholder: ({ height }) => ( ), + TopItemList: (scrollingDown && search === '') + ? TopItemListEmptyFragment + : undefined, }} /> )} From c9ea5d22fd6281e3d279dc42ccb425a93a84f434 Mon Sep 17 00:00:00 2001 From: PerIngeVaaje <60141320+PerIngeVaaje@users.noreply.github.com> Date: Wed, 13 Nov 2024 14:52:11 +0100 Subject: [PATCH 7/9] PXWEB2 Fixed error (#340) After applying codelist, check for selected values for mandatory failed --- apps/pxweb2/src/app/components/Presentation/Presentation.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/pxweb2/src/app/components/Presentation/Presentation.tsx b/apps/pxweb2/src/app/components/Presentation/Presentation.tsx index 1ad4222f..7f229d7c 100644 --- a/apps/pxweb2/src/app/components/Presentation/Presentation.tsx +++ b/apps/pxweb2/src/app/components/Presentation/Presentation.tsx @@ -92,7 +92,9 @@ export function Presentation({ selectedTabId }: propsType) { .filter((variable) => variable.mandatory) .every((variable) => selectedVBValues.some( - (selectedVariable) => selectedVariable.id === variable.id + (selectedVariable) => + selectedVariable.id === variable.id && + selectedVariable.values.length > 0 ) ); From 23b80639d3e19316d53061d124fe7bf4a9907f22 Mon Sep 17 00:00:00 2001 From: oyessb <47382101+oyessb@users.noreply.github.com> Date: Wed, 13 Nov 2024 14:53:10 +0100 Subject: [PATCH 8/9] PXWEB2-389 Dynamic heights for variable boxes (#338) * Set height for Virtuoso list to calculated total height if total is less than 380px high. * Added check so calculated height is not updated if search field is present. --- .../VariableBoxContent/VariableBoxContent.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx b/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx index 2830d227..0a055966 100644 --- a/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx +++ b/libs/pxweb2-ui/src/lib/components/VariableBox/VariableBoxContent/VariableBoxContent.tsx @@ -299,6 +299,13 @@ export function VariableBoxContent({ /* eslint-disable-next-line */ const TopItemListEmptyFragment = () => <>; + //Set inital height to 44 + const [calcedHeight, setCalcedHeight] = useState(44); + + const handleTotalListHeightChanged = (height: number) => { + setCalcedHeight(height); + }; + return (
@@ -355,7 +362,7 @@ export function VariableBoxContent({ {items.length > 0 && ( `item-${key}`} - style={{ height: '380px', maxHeight: '380px', width: '100%' }} + style={{ height: hasSevenOrMoreValues ? 380 : Math.min(380, calcedHeight), width: '100%' }} className="" totalCount={items.length} itemContent={(index) => itemRenderer(items, index)} @@ -366,6 +373,7 @@ export function VariableBoxContent({ topItemCount={stickyTopValueCount} ref={virtuosoRef} onScroll={handleVirtuosoScroll} + totalListHeightChanged={handleTotalListHeightChanged} components={{ ScrollSeekPlaceholder: ({ height }) => ( Date: Thu, 14 Nov 2024 10:20:49 +0100 Subject: [PATCH 9/9] PXWEB2-391 Remove left border only in first repetition in header (#341) --- libs/pxweb2-ui/src/lib/components/Table/Table.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/pxweb2-ui/src/lib/components/Table/Table.tsx b/libs/pxweb2-ui/src/lib/components/Table/Table.tsx index 615ec640..7c55a6f7 100644 --- a/libs/pxweb2-ui/src/lib/components/Table/Table.tsx +++ b/libs/pxweb2-ui/src/lib/components/Table/Table.tsx @@ -117,7 +117,7 @@ export function createHeading( colSpan={columnSpan} key={getNewKey()} className={cl({ - [classes.firstColNoStub]: i === 0 && table.stub.length === 0, + [classes.firstColNoStub]: i === 0 && idxRepetitionCurrentHeadingLevel===1 && table.stub.length === 0, })} > {variable.values[i].label}