Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5d072ff
Remove node auth token from publish step
sakari-malkki Dec 9, 2025
e55559c
Update permissions
sakari-malkki Dec 9, 2025
5541a7d
Merge pull request #143 from StatisticsFinland/bugfix/cd-publish-update
sakari-malkki Dec 9, 2025
3ee3524
Raise CI and CD pipelien node versions to 25.x
sakari-malkki Dec 9, 2025
c17f7ce
Downgrade to node 24.x
sakari-malkki Dec 9, 2025
f1cdaa1
Merge pull request #144 from StatisticsFinland/bugfix/ci-cd-node-version
sakari-malkki Dec 9, 2025
b62a5fe
Bump storybook from 8.6.14 to 8.6.15
dependabot[bot] Dec 18, 2025
c1801f7
Merge b62a5feb33e23445172846012ed7ae1f425177b2 into f1cdaa16aadf06192…
dependabot[bot] Dec 18, 2025
233c1ec
Version bump from 1.4.2 to 1.4.3
github-actions[bot] Dec 18, 2025
cc36bc3
Bump qs from 6.14.0 to 6.14.1
dependabot[bot] Jan 1, 2026
29b90fb
Merge cc36bc328aae2785f189da28e22c59498d0e005d into f1cdaa16aadf06192…
dependabot[bot] Jan 1, 2026
cdcee6c
Version bump from 1.4.2 to 1.4.3
github-actions[bot] Jan 1, 2026
9f2beb6
Bump lodash from 4.17.21 to 4.17.23
dependabot[bot] Jan 23, 2026
50d8044
Merge 9f2beb6a4b547ceb91eb9738dc38ccb90148cbb9 into f1cdaa16aadf06192…
dependabot[bot] Jan 23, 2026
da25b87
Version bump from 1.4.2 to 1.4.3
github-actions[bot] Jan 23, 2026
7e00f5c
Bump webpack from 5.102.0 to 5.105.0
dependabot[bot] Feb 7, 2026
e901178
Merge 7e00f5cf0023a0039f1c96ffa6ae7ab25ed740aa into f1cdaa16aadf06192…
dependabot[bot] Feb 7, 2026
9cbf2cb
Version bump from 1.4.2 to 1.4.3
github-actions[bot] Feb 7, 2026
4e4167e
Merge pull request #146 from StatisticsFinland/dependabot/npm_and_yar…
sakari-malkki Feb 16, 2026
2b0aaea
Merge pull request #147 from StatisticsFinland/dependabot/npm_and_yar…
sakari-malkki Feb 16, 2026
5d7d8a8
Merge pull request #148 from StatisticsFinland/dependabot/npm_and_yar…
sakari-malkki Feb 16, 2026
9387500
Bump qs from 6.14.1 to 6.15.0
dependabot[bot] Feb 16, 2026
41e8321
Merge pull request #149 from StatisticsFinland/dependabot/npm_and_yar…
sakari-malkki Feb 16, 2026
26a7b0b
Merge pull request #150 from StatisticsFinland/dependabot/npm_and_yar…
sakari-malkki Feb 16, 2026
a0df397
Update dependencies, related fixes
sakari-malkki Mar 11, 2026
aadf1b4
Merge pull request #155 from StatisticsFinland/feature/dependency-upd…
sakari-malkki Mar 16, 2026
22615ba
Fix bunch of sonar warnings
sakari-malkki Mar 16, 2026
1b685aa
Fix snaphshot
sakari-malkki Mar 16, 2026
657259f
Fixes
sakari-malkki Mar 16, 2026
823a91b
Further fixes
sakari-malkki Mar 16, 2026
45e7c35
Test fixes
sakari-malkki Mar 16, 2026
568acf7
Simplify styled link
sakari-malkki Mar 16, 2026
8b8d748
Merge pull request #157 from StatisticsFinland/feature/sonar-cleanup
sakari-malkki Mar 16, 2026
69ee12c
Merge pull request #156 from StatisticsFinland/dev
jsaarimaa Mar 16, 2026
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
10 changes: 5 additions & 5 deletions .github/workflows/CD.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ env:

jobs:
build:
permissions: read-all
permissions:
id-token: write
contents: read
strategy:
matrix:
os: [ubuntu-latest]
node-version: [21.x]
node-version: [24.x]

runs-on: ${{ matrix.os }}

Expand All @@ -51,6 +53,4 @@ jobs:
if: env.ENV == 'd' || env.ENV == 't'

- name: Publish
run: npm publish --tag ${{ env.ENV }} --git-tag-version false
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npm publish --tag ${{ env.ENV }} --git-tag-version false
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
node-version: [21.x]
node-version: [24.x]

runs-on: ${{ matrix.os }}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/dependabot_version_increment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: '21.x'
node-version: '24.x'

- name: Get version number from PR branch
run: |
Expand Down
3 changes: 1 addition & 2 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ const config: StorybookConfig = {
},

addons: [
"@storybook/addon-docs",
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
"@storybook/addon-a11y",
"@storybook/addon-webpack5-compiler-swc"
],
Expand Down
4,526 changes: 1,813 additions & 2,713 deletions package-lock.json

Large diffs are not rendered by default.

27 changes: 13 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@statisticsfinland/pxvisualizer",
"version": "1.4.2",
"version": "1.4.5",
"description": "Component library for visualizing PxGraf data",
"main": "./dist/pxv.cjs",
"jestSonar": {
Expand Down Expand Up @@ -47,16 +47,12 @@
"license": "Apache-2.0",
"devDependencies": {
"@babel/core": "^7.28.4",
"@storybook/addon-a11y": "^8.6.14",
"@storybook/addon-actions": "^8.6.14",
"@storybook/addon-essentials": "^8.6.14",
"@storybook/addon-interactions": "^8.6.14",
"@storybook/addon-links": "^8.6.14",
"@storybook/addon-webpack5-compiler-swc": "^3.0.0",
"@storybook/blocks": "^8.6.14",
"@storybook/react": "^8.6.14",
"@storybook/react-webpack5": "^8.6.14",
"@storybook/test": "^8.6.14",
"@storybook/addon-a11y": "^10.2.17",
"@storybook/addon-docs": "^10.2.17",
"@storybook/addon-links": "^10.2.17",
"@storybook/addon-webpack5-compiler-swc": "^4.0.2",
"@storybook/react": "^10.2.17",
"@storybook/react-webpack5": "^10.2.17",
"@testing-library/dom": "^10.4.0",
"@testing-library/react": "^16.3.0",
"@types/file-saver": "^2.0.7",
Expand All @@ -66,7 +62,7 @@
"@types/styled-components": "^5.1.34",
"@types/uuid": "^10.0.0",
"babel-loader": "^10.0.0",
"clean-publish": "^5.1.0",
"clean-publish": "^6.0.3",
"decimal.js": "^10.5.0",
"jest": "^30.2.0",
"jest-environment-jsdom": "^30.2.0",
Expand All @@ -78,7 +74,7 @@
"react": "^19.1.0",
"react-dom": "^19.1.0",
"semver": "^7.7.0",
"storybook": "^8.6.14",
"storybook": "^10.2.17",
"styled-components": "^6.1.17",
"ts-jest": "^29.2.5",
"ts-node": "^10.9.2",
Expand All @@ -99,5 +95,8 @@
"px-file",
"px",
"visualization"
]
],
"overrides": {
"serialize-javascript": "^7.0.4"
}
}
2 changes: 1 addition & 1 deletion src/core/chartOptions/Utility/timeIntervals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export function getXAxisOptions(view: View, locale: string): XAxisOptions {
}
else {
const labels: string[] = view.columnNameGroups.map(cng => cng.map(n => n[locale]).join(', '));
const numeric: boolean = labels.every(l => !isNaN(parseFloat(l)));
const numeric: boolean = labels.every(l => !Number.isNaN(Number.parseFloat(l)));
if (view.seriesType === ESeriesType.Ordinal && numeric) {
return getOrdinalOptions(view, locale);
}
Expand Down
3 changes: 2 additions & 1 deletion src/core/conversion/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { convertPxGraphDataToChartOptions } from './pxGrafDataConverter';
export { extractSelectableVariableValues } from './helpers';
export { convertPxGrafResponseToView } from './viewUtils';
export { TTranslationPackage, AddTranslations } from './translations';
export type { TTranslationPackage } from './translations';
export { AddTranslations } from './translations';
2 changes: 1 addition & 1 deletion src/core/conversion/seriesBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class SeriesBuilder {
const targetVariableCode: string = this.selectedViewMeta[targetIndex].code;
const values: IVariableValueMeta[] = completeMap.find(v => v.code === targetVariableCode)?.values as IVariableValueMeta[];
const targetVariable: IVariableMeta = this.selectedViewMeta.find(v => v.code === targetVariableCode) as IVariableMeta;
this.coordinates[variableIndex] = targetVariable.values.map(tv => values.findIndex(v => v === tv));
this.coordinates[variableIndex] = targetVariable.values.map(tv => values.indexOf(tv));
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/conversion/translations/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { TranslationManager } from './translationManager';
import { TTranslations, TArrayTranslations, TTranslationPackage } from './translationTypes';

export { TTranslationPackage } from './translationTypes';
export type { TTranslationPackage } from './translationTypes';

const Manager = new TranslationManager();

Expand Down
8 changes: 4 additions & 4 deletions src/core/conversion/viewUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,11 @@ export function getLastUpdated(
dates = contentVar.values
.filter(v => selectedValueCodes[contentVar.code].includes(v.code))
.map(cvv => cvv.contentComponent?.lastUpdated)
.filter(onlyUnique);
.filter((value, index, array) => onlyUnique(value, index, array));
} else {
dates = contentVar.values
.map(cvv => cvv.contentComponent?.lastUpdated)
.filter(onlyUnique);
.filter((value, index, array) => onlyUnique(value, index, array));
}

// Filter out undefined values and get the most recent date
Expand Down Expand Up @@ -206,9 +206,9 @@ function getContentProperty(
return contentVar.values
.filter(v => selectedValueCodes[contentVar.code].includes(v.code))
.map(cvv => extractorFunc(cvv.contentComponent))
.filter(onlyUnique);
.filter((value, index, array) => onlyUnique(value, index, array));
} else {
return contentVar.values.map(cvv => extractorFunc(cvv.contentComponent)).filter(onlyUnique);
return contentVar.values.map(cvv => extractorFunc(cvv.contentComponent)).filter((value, index, array) => onlyUnique(value, index, array));
}
}

Expand Down
15 changes: 15 additions & 0 deletions src/core/highcharts/drawChart.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,19 @@ describe('drawChart tests', () => {
expect(Highcharts.chart).toHaveBeenCalledWith('chart-container', expect.any(Object));
expect(result).toEqual({ mockedChart: true });
});

it('calls Highcharts.chart with correct parameters when called without optional parameters', () => {
// Act
const result = drawChart(
'chart-container',
GROUP_VERTICAL_BAR_CHART_CHART_FIXTURE,
'fi'
);

// Assert
expect(Highcharts.setOptions).toHaveBeenCalledTimes(1);
expect(Highcharts.chart).toHaveBeenCalledTimes(1);
expect(Highcharts.chart).toHaveBeenCalledWith('chart-container', expect.any(Object));
expect(result).toEqual({ mockedChart: true });
});
});
4 changes: 2 additions & 2 deletions src/core/highcharts/drawChart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { IChartOptions } from "../types/chartOptions";

// Only load Highcharts modules in a browser environment
const loadHighchartsModules = () => {
if (typeof window !== 'undefined') {
if (globalThis.window !== undefined) {
try {
require('highcharts/modules/pattern-fill.js');
require('highcharts/modules/accessibility.js');
Expand All @@ -27,7 +27,7 @@ export const drawChart = (
pxGraphData: IQueryVisualizationResponse,
locale: string,
selectedVariableCodes: TVariableSelections | null = null,
options: IChartOptions) =>
options: IChartOptions | undefined = undefined) =>
{
loadHighchartsModules();
const validLocale = formatLocale(locale);
Expand Down
46 changes: 26 additions & 20 deletions src/core/tables/xlsx/xlsxDataBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,21 @@ export const buildCellRows: (view: View, locale: string) => TCell[][] = (view, l
const rowHeaderCols = view.series[0]?.rowNameGroup.length ?? 0;
const gridWidth = (view.series[0]?.series.length ?? 0) + rowHeaderCols;

// Add header
const stringTable: TCell[][] = [buildCellRow([view.header[locale]], 0, gridWidth)];
// Build header
const headerRow = buildCellRow([view.header[locale]], 0, gridWidth);

// Add subheader
if (view.subheaderValues.length > 0) {
stringTable.push(buildCellRow([view.subheaderValues.map(value => value[locale]).join(' | ')], 0, gridWidth));
}
// Build subheader
const subheaderRows = view.subheaderValues.length > 0
? [buildCellRow([view.subheaderValues.map(value => value[locale]).join(' | ')], 0, gridWidth)]
: [];

// Add column variables
for (let index = 0; index < colHeaderRows; index++) {
stringTable.push(buildCellRow(view.columnNameGroups.map(group => group[index][locale]), rowHeaderCols, gridWidth));
}
// Build column header rows
const columnHeaderRows = Array.from({ length: colHeaderRows }, (_, index) =>
buildCellRow(view.columnNameGroups.map(group => group[index][locale]), rowHeaderCols, gridWidth)
);

// Add row variables + data
view.series.forEach((serie) => {
// Build data rows
const dataRows = view.series.map((serie) => {
let row: (string | number)[] = []
if (serie.rowNameGroup.length > 0) row = serie.rowNameGroup.map(name => name[locale]);

Expand All @@ -43,20 +43,26 @@ export const buildCellRows: (view: View, locale: string) => TCell[][] = (view, l
else return Number(n.value.toFixed(n.precision));
}));

stringTable.push(buildCellRow(row, 0, gridWidth));
return buildCellRow(row, 0, gridWidth);
});

// Add unit information
stringTable.push(buildCellRow([`${Translations.unit[locale]}: ${getFormattedUnits(view.units, locale)}`], 0, gridWidth));

// Add source
stringTable.push(buildCellRow([`${Translations.source[locale]}: ${view.sources.map(source => source[locale]).join(', ')}`], 0, gridWidth));
// Build footer rows
const unitRow = buildCellRow([`${Translations.unit[locale]}: ${getFormattedUnits(view.units, locale)}`], 0, gridWidth);
const sourceRow = buildCellRow([`${Translations.source[locale]}: ${view.sources.map(source => source[locale]).join(', ')}`], 0, gridWidth);

return stringTable;
// Combine all rows
return [
headerRow,
...subheaderRows,
...columnHeaderRows,
...dataRows,
unitRow,
sourceRow
];
}

function buildCellRow(data: (number | string)[], startIndex: number, rowLen: number): TCell[] {
const cellRow: TCell[] = Array(rowLen);
const cellRow: TCell[] = new Array(rowLen);
for (let i = 0; i < rowLen; i++) {
if (i >= startIndex && i < startIndex + data.length) cellRow[i] = data[i - startIndex];
else cellRow[i] = null;
Expand Down
2 changes: 1 addition & 1 deletion src/core/tables/xlsx/xlsxUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ export function escapeXmlFunctionChars(input: string): string {
'"': '&quot;',
"'": '&apos;'
};
return input.replace(/[&<>"']/g, char => xmlCharMap[char]);
return input.replaceAll(/[&<>"']/g, char => xmlCharMap[char]);
}
2 changes: 1 addition & 1 deletion src/core/tables/xlsx/xlsxWorksheetBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function getColumnLetter(colIndex: number) : string {

// If we run out of letters, we combine new letters after the prevous "prefix" ie. AA, AB, AC etc.
const prefix = Math.floor(colIndex / 26);
const letter = String.fromCharCode(97 + (colIndex % 26)).toUpperCase();
const letter = String.fromCodePoint(97 + (colIndex % 26)).toUpperCase();

if (prefix === 0) return letter;
else return getColumnLetter(prefix - 1) + letter;
Expand Down
12 changes: 7 additions & 5 deletions src/core/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
export {
export type {
IQueryVisualizationResponse,
EVisualizationType,
TVisualizationType,
ETimeVariableInterval,
TTimeVariableInterval,
EVariableType,
TVariableType
} from './queryVisualizationResponse';
export { IChartOptions } from './chartOptions';
export {
EVisualizationType,
ETimeVariableInterval,
EVariableType
} from './queryVisualizationResponse';
export type { IChartOptions } from './chartOptions';
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,13 @@ exports[`MenuItem, rendering tests should render with correct external icon 1`]
class="c0"
>
<a
aria-label="NAPPI"
class="c1"
href="foobar"
id="foo-menuitem--1"
role="menuitem"
tabindex="-1"
title="[object Object]"
title="NAPPI"
>
<div
class="c2"
Expand Down
4 changes: 2 additions & 2 deletions src/react/components/burgerMenu/menuItem/menuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const Button = styled(forwardRef<HTMLButtonElement, React.ComponentPropsWithoutR
}
`;

const StyledLink = styled(forwardRef<HTMLAnchorElement, React.ComponentPropsWithoutRef<'a'>>((props, ref) => (<a ref={ref} {...props} title={props.children ? props.children.toString() : ''} />)))`
const StyledLink = styled.a`
text-decoration: none;
display: flex;
align-items: center;
Expand Down Expand Up @@ -154,7 +154,7 @@ export const MenuItem = forwardRef<HTMLAnchorElement | HTMLButtonElement, IMenuI
if (url) {
return (
<ListItem $isFirst={isFirst} $isLast={isLast} $separator={bottomSeparator}>
<StyledLink role="menuitem" id={`${idPrefix}-menuitem-${index}`} ref={ref as React.Ref<HTMLAnchorElement>} href={url} target={openNewTab ? '_blank' : undefined} onKeyDown={handleKeyDown} onClick={handleClick} tabIndex={tabIndex}>
<StyledLink role="menuitem" id={`${idPrefix}-menuitem-${index}`} ref={ref as React.Ref<HTMLAnchorElement>} href={url} target={openNewTab ? '_blank' : undefined} rel={openNewTab ? 'noopener noreferrer' : undefined} title={text} aria-label={text} onKeyDown={handleKeyDown} onClick={handleClick} tabIndex={tabIndex}>
{content}
</StyledLink>
</ListItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
exports[`Rendering test renders correctly 1`] = `
<DocumentFragment>
<div
class="sc-bRKDuR hOGaEz"
class="sc-aXZVf fyUppu"
>
<h1>
Kuviota ei voitu muodostaa
Expand Down
Loading
Loading