diff --git a/package-lock.json b/package-lock.json index b130c4d3a05d020cce2240daf2c708f04fb3aa0f..b7ff436fa04e77d6abac0fbf5bfb797e426afd6f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,17 +16,19 @@ "@fontsource/lato": "^4.3.0", "@fontsource/lora": "^4.3.0", "@iconify/svelte": "^3.0.0", - "@leximpact/socio-fiscal-openfisca-json": "^0.0.82", - "@openfisca/json-model": "^1.3.2", + "@leximpact/socio-fiscal-openfisca-json": "^0.0.83", + "@openfisca/json-model": "^2.0.1", "@playwright/test": "^1.22.2", "@rgossiaux/svelte-headlessui": "^1.0.0-beta.12", + "@rollup/plugin-yaml": "^4.0.1", "@sveltejs/adapter-node": "^1.0.0-next.101", - "@sveltejs/kit": "^1.0.0-next.556", + "@sveltejs/kit": "^1.0.0-next.560", "@tailwindcss/typography": "^0.5.4", "@tricoteuses/explorer-tools": "^0.2.0", "@tricoteuses/legal-explorer": "^0.0.1", "@types/cookie": "^0.5.0", "@types/fs-extra": "^9.0.11", + "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^5.0.0", "@typescript-eslint/parser": "^5.0.0", "autoprefixer": "^10.2.5", @@ -1983,9 +1985,9 @@ "dev": true }, "node_modules/@iconify-icons/codicon": { - "version": "1.2.17", - "resolved": "https://registry.npmjs.org/@iconify-icons/codicon/-/codicon-1.2.17.tgz", - "integrity": "sha512-U/WpKTudEtvlND6WvU1sMac8Zd1Oe9j1oOTkiF8h36tQtfKnADqO7wO8xZl4AAs7P28pHikPDcA3N8tdYah35g==", + "version": "1.2.18", + "resolved": "https://registry.npmjs.org/@iconify-icons/codicon/-/codicon-1.2.18.tgz", + "integrity": "sha512-4PNn2qGXv/W8jzgy7Aj1hJd5C6edRnd0MbZ/7bcraJLFgWFUydg0D2WuMI6S3Ly1mT21ct5G/Oj6RN3hbzlQuQ==", "dev": true, "dependencies": { "@iconify/types": "*" @@ -2057,12 +2059,12 @@ } }, "node_modules/@leximpact/socio-fiscal-openfisca-json": { - "version": "0.0.82", - "resolved": "https://registry.npmjs.org/@leximpact/socio-fiscal-openfisca-json/-/socio-fiscal-openfisca-json-0.0.82.tgz", - "integrity": "sha512-RR68AU+51uET+9CPUJjT6sNyPly7bp8SONye1e0iO7QNLCvfnOFkoz1ImwHieoCPMuS4Vsbo3Flc8SSB6if61Q==", + "version": "0.0.83", + "resolved": "https://registry.npmjs.org/@leximpact/socio-fiscal-openfisca-json/-/socio-fiscal-openfisca-json-0.0.83.tgz", + "integrity": "sha512-pwa2kfnVqBCARC/F8EJzBeYSJJCTyX2TaQdplcbIIUC+srJnid+KA0YYpDFsYIih9m0a1nmM+Vzl58G2GkIkpA==", "dev": true, "peerDependencies": { - "@openfisca/json-model": "^1.3.2" + "@openfisca/json-model": "^2.0.1" }, "peerDependenciesMeta": { "@openfisca/json-model": { @@ -2106,9 +2108,9 @@ } }, "node_modules/@openfisca/json-model": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@openfisca/json-model/-/json-model-1.3.2.tgz", - "integrity": "sha512-F65sS565vX6Gk7xHQTItu861Xi6edF9Bv5v7jtmYbMiPY0c/47741AFBEPIXaMIa5mbs+1dKazSuKgOc7NYdKA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@openfisca/json-model/-/json-model-2.0.1.tgz", + "integrity": "sha512-tpPNFww71HW/xI31raU9+QeFU1UuWgDWLkizy0N4kgv3bp7lUVKGngtp+qT4BocOwobPdFZgQUo7jYKGuFOunA==", "dev": true, "dependencies": { "@auditors/core": "^0.3.0", @@ -2220,6 +2222,28 @@ } } }, + "node_modules/@rollup/plugin-yaml": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-yaml/-/plugin-yaml-4.0.1.tgz", + "integrity": "sha512-eyftkLWrwaGhgad+gXmisPYXeW3hP1s+lz63mgbur+F/8aKZhPG1Bf8RFNnz0Vhnf3uBimFebZBDwwz6X4KqUQ==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "js-yaml": "^4.1.0", + "tosource": "^2.0.0-alpha.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, "node_modules/@rollup/pluginutils": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", @@ -2255,9 +2279,9 @@ } }, "node_modules/@sveltejs/kit": { - "version": "1.0.0-next.556", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.0.0-next.556.tgz", - "integrity": "sha512-poCCk0Eqd5uFwEzeoi2KsP+RtjeEoYsg+UMDIEZiNIZtM6lw2CPDZS98TYOFAdLN+pQJJAji8ZNfvcE/rJN+jA==", + "version": "1.0.0-next.560", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.0.0-next.560.tgz", + "integrity": "sha512-ldZJyd+jfQWVkOkRHq25cXMffhL5MgB1Uzhhw1ngF8ezB38P/g4T+5ohP8wuk2lxPJIjbY3S6BeXN5mod9XOhA==", "hasInstallScript": true, "dependencies": { "@sveltejs/vite-plugin-svelte": "^1.1.0", @@ -2285,16 +2309,16 @@ } }, "node_modules/@sveltejs/vite-plugin-svelte": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.2.0.tgz", - "integrity": "sha512-DT2oUkWAloH1tO7X5cQ4uDxQofaIS76skyFMElKtoqT6HJao+D82LI5i+0jPaSSmO7ex3Pa6jGYMlWy9ZJ1cdQ==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.3.1.tgz", + "integrity": "sha512-2Uu2sDdIR+XQWF7QWOVSF2jR9EU6Ciw1yWfYnfLYj8HIgnNxkh/8g22Fw2pBUI8QNyW/KxtqJUWBI+8ypamSrQ==", "dependencies": { "debug": "^4.3.4", "deepmerge": "^4.2.2", "kleur": "^4.1.5", "magic-string": "^0.26.7", "svelte-hmr": "^0.15.1", - "vitefu": "^0.2.1" + "vitefu": "^0.2.2" }, "engines": { "node": "^14.18.0 || >= 16" @@ -2413,6 +2437,12 @@ "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, + "node_modules/@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", + "dev": true + }, "node_modules/@types/which": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.1.tgz", @@ -5667,9 +5697,9 @@ } }, "node_modules/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.0.tgz", + "integrity": "sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -6561,6 +6591,15 @@ "node": ">=8.0" } }, + "node_modules/tosource": { + "version": "2.0.0-alpha.3", + "resolved": "https://registry.npmjs.org/tosource/-/tosource-2.0.0-alpha.3.tgz", + "integrity": "sha512-KAB2lrSS48y91MzFPFuDg4hLbvDiyTjOVgaK7Erw+5AmZXNq4sFRVn8r6yxSLuNs15PaokrDRpS61ERY9uZOug==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/totalist": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.0.tgz", @@ -6806,9 +6845,9 @@ } }, "node_modules/vitefu": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.1.tgz", - "integrity": "sha512-clkvXTAeUf+XQKm3bhWUhT4pye+3acm6YCTGaWhxxIvZZ/QjnA3JA8Zud+z/mO5y5XYvJJhevs5Sjkv/FI8nRw==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.2.tgz", + "integrity": "sha512-8CKEIWPm4B4DUDN+h+hVJa9pyNi7rzc5MYmbxhs1wcMakueGFNWB5/DL30USm9qU3xUPnL4/rrLEAwwFiD1tag==", "peerDependencies": { "vite": "^3.0.0" }, @@ -8353,9 +8392,9 @@ "dev": true }, "@iconify-icons/codicon": { - "version": "1.2.17", - "resolved": "https://registry.npmjs.org/@iconify-icons/codicon/-/codicon-1.2.17.tgz", - "integrity": "sha512-U/WpKTudEtvlND6WvU1sMac8Zd1Oe9j1oOTkiF8h36tQtfKnADqO7wO8xZl4AAs7P28pHikPDcA3N8tdYah35g==", + "version": "1.2.18", + "resolved": "https://registry.npmjs.org/@iconify-icons/codicon/-/codicon-1.2.18.tgz", + "integrity": "sha512-4PNn2qGXv/W8jzgy7Aj1hJd5C6edRnd0MbZ/7bcraJLFgWFUydg0D2WuMI6S3Ly1mT21ct5G/Oj6RN3hbzlQuQ==", "dev": true, "requires": { "@iconify/types": "*" @@ -8412,9 +8451,9 @@ } }, "@leximpact/socio-fiscal-openfisca-json": { - "version": "0.0.82", - "resolved": "https://registry.npmjs.org/@leximpact/socio-fiscal-openfisca-json/-/socio-fiscal-openfisca-json-0.0.82.tgz", - "integrity": "sha512-RR68AU+51uET+9CPUJjT6sNyPly7bp8SONye1e0iO7QNLCvfnOFkoz1ImwHieoCPMuS4Vsbo3Flc8SSB6if61Q==", + "version": "0.0.83", + "resolved": "https://registry.npmjs.org/@leximpact/socio-fiscal-openfisca-json/-/socio-fiscal-openfisca-json-0.0.83.tgz", + "integrity": "sha512-pwa2kfnVqBCARC/F8EJzBeYSJJCTyX2TaQdplcbIIUC+srJnid+KA0YYpDFsYIih9m0a1nmM+Vzl58G2GkIkpA==", "dev": true, "requires": {} }, @@ -8445,9 +8484,9 @@ } }, "@openfisca/json-model": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@openfisca/json-model/-/json-model-1.3.2.tgz", - "integrity": "sha512-F65sS565vX6Gk7xHQTItu861Xi6edF9Bv5v7jtmYbMiPY0c/47741AFBEPIXaMIa5mbs+1dKazSuKgOc7NYdKA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@openfisca/json-model/-/json-model-2.0.1.tgz", + "integrity": "sha512-tpPNFww71HW/xI31raU9+QeFU1UuWgDWLkizy0N4kgv3bp7lUVKGngtp+qT4BocOwobPdFZgQUo7jYKGuFOunA==", "dev": true, "requires": { "@auditors/core": "^0.3.0", @@ -8515,6 +8554,17 @@ "resolve": "^1.22.1" } }, + "@rollup/plugin-yaml": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-yaml/-/plugin-yaml-4.0.1.tgz", + "integrity": "sha512-eyftkLWrwaGhgad+gXmisPYXeW3hP1s+lz63mgbur+F/8aKZhPG1Bf8RFNnz0Vhnf3uBimFebZBDwwz6X4KqUQ==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^5.0.1", + "js-yaml": "^4.1.0", + "tosource": "^2.0.0-alpha.3" + } + }, "@rollup/pluginutils": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", @@ -8539,9 +8589,9 @@ } }, "@sveltejs/kit": { - "version": "1.0.0-next.556", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.0.0-next.556.tgz", - "integrity": "sha512-poCCk0Eqd5uFwEzeoi2KsP+RtjeEoYsg+UMDIEZiNIZtM6lw2CPDZS98TYOFAdLN+pQJJAji8ZNfvcE/rJN+jA==", + "version": "1.0.0-next.560", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.0.0-next.560.tgz", + "integrity": "sha512-ldZJyd+jfQWVkOkRHq25cXMffhL5MgB1Uzhhw1ngF8ezB38P/g4T+5ohP8wuk2lxPJIjbY3S6BeXN5mod9XOhA==", "requires": { "@sveltejs/vite-plugin-svelte": "^1.1.0", "@types/cookie": "^0.5.1", @@ -8558,16 +8608,16 @@ } }, "@sveltejs/vite-plugin-svelte": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.2.0.tgz", - "integrity": "sha512-DT2oUkWAloH1tO7X5cQ4uDxQofaIS76skyFMElKtoqT6HJao+D82LI5i+0jPaSSmO7ex3Pa6jGYMlWy9ZJ1cdQ==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.3.1.tgz", + "integrity": "sha512-2Uu2sDdIR+XQWF7QWOVSF2jR9EU6Ciw1yWfYnfLYj8HIgnNxkh/8g22Fw2pBUI8QNyW/KxtqJUWBI+8ypamSrQ==", "requires": { "debug": "^4.3.4", "deepmerge": "^4.2.2", "kleur": "^4.1.5", "magic-string": "^0.26.7", "svelte-hmr": "^0.15.1", - "vitefu": "^0.2.1" + "vitefu": "^0.2.2" } }, "@tailwindcss/typography": { @@ -8670,6 +8720,12 @@ "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, + "@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", + "dev": true + }, "@types/which": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.1.tgz", @@ -10933,9 +10989,9 @@ "dev": true }, "prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.0.tgz", + "integrity": "sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA==", "dev": true }, "prettier-plugin-svelte": { @@ -11540,6 +11596,12 @@ "is-number": "^7.0.0" } }, + "tosource": { + "version": "2.0.0-alpha.3", + "resolved": "https://registry.npmjs.org/tosource/-/tosource-2.0.0-alpha.3.tgz", + "integrity": "sha512-KAB2lrSS48y91MzFPFuDg4hLbvDiyTjOVgaK7Erw+5AmZXNq4sFRVn8r6yxSLuNs15PaokrDRpS61ERY9uZOug==", + "dev": true + }, "totalist": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.0.tgz", @@ -11689,9 +11751,9 @@ } }, "vitefu": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.1.tgz", - "integrity": "sha512-clkvXTAeUf+XQKm3bhWUhT4pye+3acm6YCTGaWhxxIvZZ/QjnA3JA8Zud+z/mO5y5XYvJJhevs5Sjkv/FI8nRw==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.2.tgz", + "integrity": "sha512-8CKEIWPm4B4DUDN+h+hVJa9pyNi7rzc5MYmbxhs1wcMakueGFNWB5/DL30USm9qU3xUPnL4/rrLEAwwFiD1tag==", "requires": {} }, "web-streams-polyfill": { diff --git a/package.json b/package.json index 6c601b8df93770150f47e1a97da1f06670f0a49a..c55eca35ed533ed767f0d218f3448e77fd1e2ad3 100644 --- a/package.json +++ b/package.json @@ -20,17 +20,19 @@ "@fontsource/lato": "^4.3.0", "@fontsource/lora": "^4.3.0", "@iconify/svelte": "^3.0.0", - "@leximpact/socio-fiscal-openfisca-json": "^0.0.82", - "@openfisca/json-model": "^1.3.2", + "@leximpact/socio-fiscal-openfisca-json": "^0.0.83", + "@openfisca/json-model": "^2.0.1", "@playwright/test": "^1.22.2", "@rgossiaux/svelte-headlessui": "^1.0.0-beta.12", + "@rollup/plugin-yaml": "^4.0.1", "@sveltejs/adapter-node": "^1.0.0-next.101", - "@sveltejs/kit": "^1.0.0-next.556", + "@sveltejs/kit": "^1.0.0-next.560", "@tailwindcss/typography": "^0.5.4", "@tricoteuses/explorer-tools": "^0.2.0", "@tricoteuses/legal-explorer": "^0.0.1", "@types/cookie": "^0.5.0", "@types/fs-extra": "^9.0.11", + "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^5.0.0", "@typescript-eslint/parser": "^5.0.0", "autoprefixer": "^10.2.5", diff --git a/src/lib/components/ValueChange.svelte b/src/lib/components/ValueChange.svelte index cb4fd0299cc2d6ae932ca94d7486ef24d4567d52..6c4ca3b95f3c8fc6d710cce4f0e0c541813abf35 100644 --- a/src/lib/components/ValueChange.svelte +++ b/src/lib/components/ValueChange.svelte @@ -1,10 +1,8 @@ <script lang="ts"> - import type { Unit } from "@openfisca/json-model" - import { valueFormatter } from "$lib/values" import type { VariableValueByCalculationName } from "$lib/variables" - export let unit: Unit | undefined | null + export let unitName: string | undefined | null export let valueByCalculationName: VariableValueByCalculationName export let legend = false @@ -21,7 +19,7 @@ : billValue : lawValue - $: format = valueFormatter(baseValue, unit) + $: format = valueFormatter(baseValue, unitName) $: amendmentValueFormatted = amendmentValue === undefined ? undefined : format(amendmentValue) @@ -45,7 +43,7 @@ function mustShowAmendmentValue( amendmentValueFormatted: string | undefined, billValueFormatted: string | undefined, - lawValueFormatted: string, + lawValueFormatted: string | undefined, ): boolean { if (amendmentValueFormatted === undefined) { return false diff --git a/src/lib/components/ValueChangeCompare.svelte b/src/lib/components/ValueChangeCompare.svelte index 9bc6d36db50d43674f8ea7a3a06aab85d576b32d..e35f61ab3214f95b03e4d853d1cb6a3ceed0d68b 100644 --- a/src/lib/components/ValueChangeCompare.svelte +++ b/src/lib/components/ValueChangeCompare.svelte @@ -1,10 +1,8 @@ <script lang="ts"> - import type { Unit } from "@openfisca/json-model" - import { valueFormatter } from "$lib/values" import type { VariableValueByCalculationName } from "$lib/variables" - export let unit: Unit | undefined | null + export let unitName: string | undefined | null export let valueByCalculationName0: VariableValueByCalculationName export let valueByCalculationName1: VariableValueByCalculationName export let legend = false @@ -31,7 +29,7 @@ : billValue1 : lawValue1 - $: format = valueFormatter(baseValue0, unit) + $: format = valueFormatter(baseValue0, unitName) $: amendmentValue0Formatted = amendmentValue0 === undefined ? undefined : format(amendmentValue0) @@ -72,7 +70,7 @@ function mustShowAmendmentValue( amendmentValueFormatted: string | undefined, billValueFormatted: string | undefined, - lawValueFormatted: string, + lawValueFormatted: string | undefined, ): boolean { if (amendmentValueFormatted === undefined) { return false diff --git a/src/lib/components/parameters/NodeEdit.svelte b/src/lib/components/parameters/NodeEdit.svelte index 6f60f68c5a443cd175d698b3e7186f07b01ac3ff..e4232c378f5a8d52b5d419c71f77840d86a42e2f 100644 --- a/src/lib/components/parameters/NodeEdit.svelte +++ b/src/lib/components/parameters/NodeEdit.svelte @@ -1,11 +1,10 @@ <script lang="ts"> import { auditDateIso8601String, laxAudit } from "@auditors/core" import type { NodeParameter, Reference } from "@openfisca/json-model" - import { Unit } from "@openfisca/json-model" import ReferencesEdit from "$lib/components/parameters/ReferencesEdit.svelte" import { errorAsKeyValueDictionary, iterArrayWithErrors } from "$lib/errors" - import { labelFromUnit } from "$lib/parameters" + import { labelFromUnitName, units } from "$lib/units" let globalErrors: { [key: string]: unknown } export { globalErrors as errors } @@ -55,7 +54,7 @@ .map(([, instantReferences]) => instantReferences) } - function changeInstant(index, { target }: Event) { + function changeInstant(index: number, { target }: Event) { const { value: instant } = target as HTMLInputElement const [validInstant, error] = auditDateIso8601String(laxAudit, instant) @@ -86,7 +85,7 @@ updateParameter() } - function changeReferences(index, { detail }: CustomEvent) { + function changeReferences(index: number, { detail }: CustomEvent) { const references = detail as Reference[] instantReferencesArray = [...instantReferencesArray] instantReferencesArray[index] = { @@ -105,7 +104,7 @@ } function updateParameter(): void { - const referencesByInstant = {} + const referencesByInstant: { [instant: string]: Reference[] } = {} for (const { instant, references } of instantReferencesArray) { if (references.length > 0) { referencesByInstant[instant] = references @@ -228,8 +227,8 @@ {#if parameter.unit === undefined} <option selected value={undefined}>Non précisée</option> {/if} - {#each Object.values(Unit) as unit} - <option value={unit}>{labelFromUnit(unit)}</option> + {#each units as unit} + <option value={unit.name}>{labelFromUnitName(unit.name)}</option> {/each} </select> {#if showErrors && errors.unit !== undefined} diff --git a/src/lib/components/parameters/ParameterView.svelte b/src/lib/components/parameters/ParameterView.svelte index 84c7ae52dabb85bf58a3d4a1e8c90a1620dece5f..bd97462676c264e614a1ec428db62c7584e993f9 100644 --- a/src/lib/components/parameters/ParameterView.svelte +++ b/src/lib/components/parameters/ParameterView.svelte @@ -5,7 +5,6 @@ newParameterRepositoryUrl, ParameterClass, parameterLastReviewOrChange, - Unit, type Parameter, } from "@openfisca/json-model" import { getContext } from "svelte" @@ -17,9 +16,9 @@ asRateScaleParameter, buildInstantReferencesAndValueArray, labelFromScaleType, - labelFromUnit, labelFromValueType, } from "$lib/parameters" + import { shortLabelFromUnitName } from "$lib/units" import type { SelfTargetAProps } from "$lib/urls" export let parameter: Parameter @@ -186,13 +185,13 @@ {:else} <!-- TODO: Handle when valueAtInstant.value is a string array or a string by string dict. --> <td class="border p-1 text-center font-serif" - >{(valueAtInstant.unit ?? parameter.unit) == - Unit.Rate && typeof valueAtInstant.value === "number" + >{(valueAtInstant.unit ?? parameter.unit) == "/1" && + typeof valueAtInstant.value === "number" ? parseFloat((valueAtInstant.value * 100).toFixed(8)) // trick to round value * 100 : valueAtInstant.value ?? ""}</td > <td class="border p-1 text-center" - >{labelFromUnit( + >{shortLabelFromUnitName( valueAtInstant.unit ?? parameter.unit, ) ?? ""}</td > @@ -233,7 +232,7 @@ <div class="font-base my-1 flex border-b py-1 "> <p class="mr-1"> Unité du paramètre :: <span class="font-bold"> - {labelFromUnit(parameter.unit)}</span + {shortLabelFromUnitName(parameter.unit)}</span > </p> </div> @@ -248,7 +247,7 @@ {#if parameter.threshold_unit !== undefined} <p class="font-base my-1 mr-1 flex py-1"> Unité de seuil : <span class="font-bold"> - {labelFromUnit(parameter.threshold_unit)}</span + {shortLabelFromUnitName(parameter.threshold_unit)}</span > </p> {/if} @@ -256,7 +255,7 @@ {#if asAmountScaleParameter(parameter).amount_unit !== undefined} <p class="font-base my-1 mr-1 flex py-1"> Unité de montant : <span class="font-bold"> - {labelFromUnit( + {shortLabelFromUnitName( asAmountScaleParameter(parameter).amount_unit, )}</span > @@ -265,7 +264,7 @@ {:else if asRateScaleParameter(parameter).rate_unit !== undefined} <p class="font-base my-1 mr-1 flex py-1"> Unité de taux : <span class="font-bold"> - {labelFromUnit( + {shortLabelFromUnitName( asRateScaleParameter(parameter).rate_unit, )}</span > @@ -282,7 +281,7 @@ <div class="font-base my-1 flex py-1"> <p class="mr-1"> Unité de la valeur : <span class="font-bold" - >{labelFromUnit(parameter.unit)}</span + >{shortLabelFromUnitName(parameter.unit)}</span > </p> </div> diff --git a/src/lib/components/parameters/ScaleAtInstantEdit.svelte b/src/lib/components/parameters/ScaleAtInstantEdit.svelte index 84e0cd1d0bde56ee33781108814446795c970d1b..463c6a6b1cbfb14b0df711ee4a271366e10d9c0b 100644 --- a/src/lib/components/parameters/ScaleAtInstantEdit.svelte +++ b/src/lib/components/parameters/ScaleAtInstantEdit.svelte @@ -4,17 +4,13 @@ isAmountScaleParameter, scaleParameterUsesBase, ScaleType, - Unit, type AmountBracketAtInstant, - type AmountUnit, type BracketAtInstant, type MaybeNumberValue, type NumberValue, type RateBracketAtInstant, - type RateUnit, type ScaleAtInstant, type ScaleParameter, - type ThresholdUnit, } from "@openfisca/json-model" import { createEventDispatcher } from "svelte" @@ -24,8 +20,8 @@ asAmountScaleParameter, asRateBracketAtInstant, asRateScaleParameter, - labelFromUnit, } from "$lib/parameters" + import { shortLabelFromUnitName } from "$lib/units" let globalErrors: { [key: string]: unknown } export { globalErrors as errors } @@ -46,7 +42,7 @@ ScaleType.SingleAmount, ].includes(parameter.type) ? { - amount: { value: null } as NumberValue, + amount: { value: null } as unknown as NumberValue, threshold: { value: null } as MaybeNumberValue, } : { @@ -54,20 +50,20 @@ rate: { value: null } as MaybeNumberValue, threshold: { value: null } as MaybeNumberValue, } - scaleAtInstant = [...scaleAtInstant, bracket] + scaleAtInstant = [...(scaleAtInstant as ScaleAtInstant), bracket] } function changeValue( index: number, key: keyof AmountBracketAtInstant | keyof RateBracketAtInstant, - unit: AmountUnit | RateUnit | ThresholdUnit | Unit | undefined | null, + unitName: string | undefined | null, { target }: Event, ) { const { value } = target as HTMLInputElement let [validValue, error] = auditStringToNumber(laxAudit, value) let errorsAtIndex = errors[index] as { [key: string]: unknown } | undefined if (error === null) { - if (unit === Unit.Rate) { + if (unitName === "/1") { validValue = validValue / 100 } if (errorsAtIndex?.[key] !== undefined) { @@ -86,29 +82,29 @@ } } } - scaleAtInstant = [...scaleAtInstant] + scaleAtInstant = [...(scaleAtInstant as ScaleAtInstant)] const bracket = (scaleAtInstant[index] = { ...scaleAtInstant[index], - }) as BracketAtInstant + }) as AmountBracketAtInstant & RateBracketAtInstant bracket[key] = bracket[key] === "expected" ? { value: validValue } : { - ...(bracket[key] as { [key: string]: unknown }), + ...(bracket[key] as unknown as { [key: string]: unknown }), value: validValue, } dispatch("change", scaleAtInstant) } function deleteBracket(index: number) { - scaleAtInstant = [...scaleAtInstant] + scaleAtInstant = [...(scaleAtInstant as ScaleAtInstant)] scaleAtInstant.splice(index, 1) dispatch("change", scaleAtInstant) } function valueFromMaybeNumberValueOrExpected( - value: NumberValue | "expected" | undefined | null, - unit: AmountUnit | RateUnit | ThresholdUnit | Unit, + value: MaybeNumberValue | "expected" | undefined | null, + unitName: string | undefined | null, ): number | string | null { if (value == null) { return null @@ -120,7 +116,7 @@ if (number == null) { return null } - return unit === Unit.Rate + return unitName === "/1" ? parseFloat((number * 100).toFixed(8)) // trick to round value * 100 : number } @@ -185,7 +181,7 @@ )} /> <span class="font-serif text-sm text-black"> - {labelFromUnit(parameter.threshold_unit) ?? ""} + {shortLabelFromUnitName(parameter.threshold_unit) ?? ""} </span> {#if showErrors && errorAsKeyValueDictionary(errorAsKeyValueDictionary(errorsAtIndex).threshold).value !== undefined} <p> @@ -216,7 +212,7 @@ )} /> <span class="font-serif text-base"> - {labelFromUnit( + {shortLabelFromUnitName( asAmountScaleParameter(parameter).amount_unit, ) ?? ""} </span> @@ -253,7 +249,7 @@ /> <span class="font-serif text-base"> <!-- TODO: Should be parameter.base_unit. --> - {labelFromUnit(parameter.threshold_unit) ?? ""} + {shortLabelFromUnitName(parameter.threshold_unit) ?? ""} </span> {#if showErrors && errorAsKeyValueDictionary(errorAsKeyValueDictionary(errorsAtIndex).base).value !== undefined} <p> @@ -284,8 +280,9 @@ )} /> <span class="font-serif text-base"> - {labelFromUnit(asRateScaleParameter(parameter).rate_unit) ?? - ""} + {shortLabelFromUnitName( + asRateScaleParameter(parameter).rate_unit, + ) ?? ""} </span> {#if showErrors && errorAsKeyValueDictionary(errorAsKeyValueDictionary(errorsAtIndex).rate).value !== undefined} <p> diff --git a/src/lib/components/parameters/ScaleEdit.svelte b/src/lib/components/parameters/ScaleEdit.svelte index beb65c65435153754a028fc51c1187d3ecfeca8e..07896e6868c7c6b60698249ae3b58af9f9db960b 100644 --- a/src/lib/components/parameters/ScaleEdit.svelte +++ b/src/lib/components/parameters/ScaleEdit.svelte @@ -1,13 +1,10 @@ <script lang="ts"> import { auditDateIso8601String, laxAudit } from "@auditors/core" import { - AmountUnit, bracketsFromScaleByInstant, isAmountScaleParameter, isRateScaleParameter, - RateUnit, ScaleType, - Unit, type Reference, type ScaleAtInstant, type ScaleParameter, @@ -23,8 +20,8 @@ asRateScaleParameter, buildInstantReferencesAndScaleArray, labelFromScaleType, - labelFromUnit, } from "$lib/parameters" + import { labelFromUnitName, units } from "$lib/units" let globalErrors: { [key: string]: unknown } export { globalErrors as errors } @@ -65,7 +62,7 @@ updateParameter() } - function changeInstant(index, { target }: Event) { + function changeInstant(index: number, { target }: Event) { const { value: instant } = target as HTMLInputElement const [validInstant, error] = auditDateIso8601String(laxAudit, instant) @@ -96,7 +93,7 @@ updateParameter() } - function changeReferences(index, { detail }: CustomEvent) { + function changeReferences(index: number, { detail }: CustomEvent) { const references = detail as Reference[] instantReferencesAndScaleArray = [...instantReferencesAndScaleArray] instantReferencesAndScaleArray[index] = { @@ -107,7 +104,7 @@ updateParameter() } - function changeScaleAtInstant(index, { detail }: CustomEvent) { + function changeScaleAtInstant(index: number, { detail }: CustomEvent) { const scaleAtInstant = detail as ScaleAtInstant instantReferencesAndScaleArray = [...instantReferencesAndScaleArray] instantReferencesAndScaleArray[index] = { @@ -126,7 +123,7 @@ } function updateParameter(): void { - const referencesByInstant = {} + const referencesByInstant: { [instant: string]: Reference[] } = {} const scaleByInstant: { [instant: string]: ScaleAtInstant } = {} for (const { instant, @@ -303,8 +300,8 @@ {#if asAmountScaleParameter(parameter).amount_unit === undefined} <option selected value={undefined}>Non précisée</option> {/if} - {#each Object.values(AmountUnit) as unit} - <option value={unit}>{labelFromUnit(unit)}</option> + {#each units as unit} + <option value={unit.name}>{labelFromUnitName(unit.name)}</option> {/each} </select> {#if showErrors && errors.amount_unit !== undefined} @@ -323,8 +320,8 @@ {#if asRateScaleParameter(parameter).rate_unit === undefined} <option selected value={undefined}>Non précisée</option> {/if} - {#each Object.values(RateUnit) as unit} - <option value={unit}>{labelFromUnit(unit)}</option> + {#each units as unit} + <option value={unit.name}>{labelFromUnitName(unit.name)}</option> {/each} </select> {#if showErrors && errors.rate_unit !== undefined} @@ -380,8 +377,8 @@ {#if parameter.threshold_unit === undefined} <option selected value={undefined}>Non précisée</option> {/if} - {#each Object.values(Unit) as unit} - <option value={unit}>{labelFromUnit(unit)}</option> + {#each units as unit} + <option value={unit.name}>{labelFromUnitName(unit.name)}</option> {/each} </select> {#if showErrors && errors.threshold_unit !== undefined} diff --git a/src/lib/components/parameters/ScaleView.svelte b/src/lib/components/parameters/ScaleView.svelte index 255123d7e23690cba81321582f85a2e19324aef3..98f923aa3bce79955f0bfa5c8e3b302861bf4f1e 100644 --- a/src/lib/components/parameters/ScaleView.svelte +++ b/src/lib/components/parameters/ScaleView.svelte @@ -2,12 +2,8 @@ import { isAmountScaleParameter, scaleParameterUsesBase, - Unit, - type AmountUnit, - type NumberValue, - type RateUnit, + type MaybeNumberValue, type ScaleParameter, - type ThresholdUnit, } from "@openfisca/json-model" import { @@ -25,8 +21,8 @@ $: usesBase = scaleParameterUsesBase(parameter) function formatMaybeNumberValueOrExpected( - value: NumberValue | "expected" | undefined | null, - unit: AmountUnit | RateUnit | ThresholdUnit | Unit, + value: MaybeNumberValue | "expected" | undefined | null, + unit: string | undefined | null, ): number | string | null { if (value == null) { return null @@ -38,7 +34,7 @@ if (number == null) { return null } - return unit === Unit.Rate + return unit === "/1" ? parseFloat((number * 100).toFixed(8)) // trick to round value * 100 : number } diff --git a/src/lib/components/parameters/ValueAtInstantEdit.svelte b/src/lib/components/parameters/ValueAtInstantEdit.svelte index 17a16101ac76b506d97874513f58a9d6eb205696..da89dcfac4ef53af6ccf0b7fdad35dd1605a4a97 100644 --- a/src/lib/components/parameters/ValueAtInstantEdit.svelte +++ b/src/lib/components/parameters/ValueAtInstantEdit.svelte @@ -7,18 +7,19 @@ laxAudit, } from "@auditors/core" import type { + MaybeBooleanValue, MaybeNumberValue, MaybeStringArrayValue, MaybeStringByStringValue, + NumberValue, ValueAtInstant, ValueParameter, } from "@openfisca/json-model" - import { Unit, ValueType } from "@openfisca/json-model" + import { ValueType } from "@openfisca/json-model" import { createEventDispatcher } from "svelte" import { auditEditedAttribute } from "$lib/errors" - import { labelFromUnit } from "$lib/parameters" - import type { MaybeBooleanValue } from "@openfisca/json-model/build/parameters" + import { labelFromUnitName, shortLabelFromUnitName, units } from "$lib/units" let globalErrors: { [key: string]: unknown } export { globalErrors as errors } @@ -41,6 +42,17 @@ return value as MaybeNumberValue } + function asNumberValue( + value: + | MaybeBooleanValue + | MaybeNumberValue + | MaybeStringArrayValue + | MaybeStringByStringValue + | "expected", + ): NumberValue { + return value as NumberValue + } + function changeUnit({ target }: Event) { const { value } = target as HTMLSelectElement ;[valueAtInstant, errors] = auditEditedAttribute( @@ -52,7 +64,7 @@ errors, auditTrimString, auditFunction((value) => (value === "undefined" ? undefined : value)), - auditOptions(Object.values(Unit)), + auditOptions(units.map((unit) => unit.name)), ) dispatch("change", valueAtInstant) } @@ -70,8 +82,8 @@ ) if ( validErrors.unit === undefined && - validValueAtInstant.unit === Unit.Rate && - typeof validValueAtInstant.value === "number" + validValueAtInstant?.unit === "/1" && + typeof validValueAtInstant?.value === "number" ) { validValueAtInstant.value = validValueAtInstant.value / 100 } @@ -82,8 +94,8 @@ function valueHasChanged( parameter: ValueParameter, - oldValueAtInstant: ValueAtInstant, - valueAtInstant: ValueAtInstant, + oldValueAtInstant: ValueAtInstant | undefined | null, + valueAtInstant: ValueAtInstant | undefined | null, ): boolean { switch (parameter.type) { case ValueType.Number: @@ -96,7 +108,8 @@ : asMaybeNumberValue(oldValueAtInstant).value ?? null) ) default: - console.log(`TODO: Handle parameter of type ${parameter.type}.`) + console.error(`TODO: Handle parameter of type ${parameter.type}.`) + return true } } </script> @@ -127,11 +140,9 @@ value={valueAtInstant === "expected" ? null : (errors.unit === undefined && - valueAtInstant.unit === Unit.Rate && + valueAtInstant?.unit === "/1" && typeof valueAtInstant.value === "number" - ? parseFloat( - (asMaybeNumberValue(valueAtInstant).value * 100).toFixed(8), - ) // trick to round value * 100 + ? parseFloat((asNumberValue(valueAtInstant).value * 100).toFixed(8)) // trick to round value * 100 : asMaybeNumberValue(valueAtInstant).value) ?? null} /> {#if showErrors && errors.value !== undefined} @@ -145,14 +156,14 @@ value={asMaybeNumberValue(valueAtInstant).unit} > <option value={undefined}> - {#if parameter.unit == null}Non précisée{:else}{labelFromUnit( + {#if parameter.unit == null}Non précisée{:else}{shortLabelFromUnitName( parameter.unit, )} {/if}</option > - {#each Object.values(Unit) as unit} - {#if unit !== parameter.unit} - <option value={unit}>{labelFromUnit(unit)}</option> + {#each units as unit} + {#if unit.name !== parameter.unit} + <option value={unit.name}>{labelFromUnitName(unit.name)}</option> {/if} {/each} </select> diff --git a/src/lib/components/parameters/ValueEdit.svelte b/src/lib/components/parameters/ValueEdit.svelte index c6aa5cb760f30e7ea95c0ed64e5416656b7a5253..a5e1f3ae573405c8542a7815881496af2f401bf9 100644 --- a/src/lib/components/parameters/ValueEdit.svelte +++ b/src/lib/components/parameters/ValueEdit.svelte @@ -5,7 +5,7 @@ ValueAtInstant, ValueParameter, } from "@openfisca/json-model" - import { Unit, ValueType } from "@openfisca/json-model" + import { ValueType } from "@openfisca/json-model" import ReferencesEdit from "$lib/components/parameters/ReferencesEdit.svelte" import ValueAtInstantEdit from "$lib/components/parameters/ValueAtInstantEdit.svelte" @@ -14,8 +14,8 @@ import { buildInstantReferencesAndValueArray, labelFromValueType, - labelFromUnit, } from "$lib/parameters" + import { labelFromUnitName, units } from "$lib/units" let globalErrors: { [key: string]: unknown } export { globalErrors as errors } @@ -41,7 +41,7 @@ updateParameter() } - function changeInstant(index, { target }: Event) { + function changeInstant(index: number, { target }: Event) { const { value: instant } = target as HTMLInputElement const [validInstant, error] = auditDateIso8601String(laxAudit, instant) @@ -72,7 +72,7 @@ updateParameter() } - function changeReferences(index, { detail }: CustomEvent) { + function changeReferences(index: number, { detail }: CustomEvent) { const references = detail as Reference[] instantReferencesAndValueArray = [...instantReferencesAndValueArray] instantReferencesAndValueArray[index] = { @@ -83,7 +83,7 @@ updateParameter() } - function changeValueAtInstant(index, { detail }: CustomEvent) { + function changeValueAtInstant(index: number, { detail }: CustomEvent) { const valueAtInstant = detail as ValueAtInstant instantReferencesAndValueArray = [...instantReferencesAndValueArray] instantReferencesAndValueArray[index] = { @@ -102,8 +102,8 @@ } function updateParameter(): void { - const referencesByInstant = {} - const values = {} + const referencesByInstant: { [instant: string]: Reference[] } = {} + const values: { [instant: string]: ValueAtInstant } = {} for (const { instant, references, @@ -121,7 +121,7 @@ parameter.reference = referencesByInstant } if (Object.keys(values).length > 0) { - parameter.values = values + parameter.values = values as ValueParameter["values"] } } </script> @@ -297,8 +297,8 @@ {#if parameter.unit === undefined} <option selected value={undefined}>Non précisée</option> {/if} - {#each Object.values(Unit) as unit} - <option value={unit}>{labelFromUnit(unit)}</option> + {#each units as unit} + <option value={unit.name}>{labelFromUnitName(unit.name)}</option> {/each} </select> {#if showErrors && errors.unit !== undefined} diff --git a/src/lib/components/test_cases/OilSpendingBill.svelte b/src/lib/components/test_cases/OilSpendingBill.svelte index 6c178c2f76506beef9a4a1c78df76f2c1ac605d8..a5375e35616e37114693e25f7fcd167d9f375765 100644 --- a/src/lib/components/test_cases/OilSpendingBill.svelte +++ b/src/lib/components/test_cases/OilSpendingBill.svelte @@ -1,6 +1,6 @@ <script lang="ts"> import Icon from "@iconify/svelte" - import { Unit, type Variable } from "@openfisca/json-model" + import type { Variable } from "@openfisca/json-model" import { createEventDispatcher } from "svelte" import { page } from "$app/stores" @@ -173,7 +173,7 @@ <td class="text-right text-lg font-bold "> <div class="flex flex-col items-end"> <ValueChange - unit={Unit.CurrencyEUR} + unitName="currency-EUR" valueByCalculationName={getCalculatedVariableSummedValueByCalculationName( depenseTtcVariableName, valuesByCalculationNameByVariableName, @@ -187,7 +187,7 @@ <td class="text-right"> <div class="flex flex-col items-end"> <ValueChange - unit={Unit.CurrencyEUR} + unit="currency-EUR" valueByCalculationName={getCalculatedVariableSummedValueByCalculationName( tvaVariableName, valuesByCalculationNameByVariableName, @@ -201,7 +201,7 @@ <td class="text-right"> <div class="flex flex-col items-end"> <ValueChange - unit={Unit.CurrencyEUR} + unit="currency-EUR" valueByCalculationName={getCalculatedVariableSummedValueByCalculationName( ticpeVariableName, valuesByCalculationNameByVariableName, diff --git a/src/lib/components/test_cases/TestCaseCompareView.svelte b/src/lib/components/test_cases/TestCaseCompareView.svelte index f6faf778912327f461badce202f9116743778bce..cdac0c8bfca1f7686d31d65427a7c9e8ce118aa0 100644 --- a/src/lib/components/test_cases/TestCaseCompareView.svelte +++ b/src/lib/components/test_cases/TestCaseCompareView.svelte @@ -1,10 +1,6 @@ <script lang="ts"> import Icon from "@iconify/svelte" - import { - type DecompositionReference, - Unit, - type Waterfall, - } from "@openfisca/json-model" + import type { DecompositionReference, Waterfall } from "@openfisca/json-model" import { createEventDispatcher, getContext } from "svelte" import type { Writable } from "svelte/store" @@ -168,7 +164,7 @@ </p> <ValueChangeCompare legend={true} - unit={Unit.CurrencyEUR} + unit="currency-EUR" valueByCalculationName0={{ amendment: Object.keys($parametricReform).length === 0 @@ -245,7 +241,7 @@ </p> <div class="text-2xl font-semibold"> <ValueChangeCompare - unit={Unit.CurrencyEUR} + unit="currency-EUR" valueByCalculationName0={{ amendment: Object.keys($parametricReform).length === 0 diff --git a/src/lib/components/test_cases/TestCaseView.svelte b/src/lib/components/test_cases/TestCaseView.svelte index 257459fda702034036e0991c5a7c694d241a9d93..9c878f1f527545ed109b030a364a41afc69a6166 100644 --- a/src/lib/components/test_cases/TestCaseView.svelte +++ b/src/lib/components/test_cases/TestCaseView.svelte @@ -1,6 +1,5 @@ <script lang="ts"> import type { DecompositionReference, Waterfall } from "@openfisca/json-model" - import { Unit } from "@openfisca/json-model" import { getContext } from "svelte" import type { Writable } from "svelte/store" @@ -143,7 +142,7 @@ > <ValueChange legend={true} - unit={Unit.CurrencyEUR} + unit="currency-EUR" valueByCalculationName={{ amendment: Object.keys($parametricReform).length === 0 @@ -204,7 +203,7 @@ </span> <div class="flex flex-wrap items-start gap-2 text-4xl"> <ValueChange - unit={Unit.CurrencyEUR} + unit="currency-EUR" valueByCalculationName={{ amendment: Object.keys($parametricReform).length === 0 diff --git a/src/lib/components/variables/VariableReferredScaleAtInstant.svelte b/src/lib/components/variables/VariableReferredScaleAtInstant.svelte index 7c8317562989d62cc9d0c2537fc85cf3714d0d13..7249b159e75139d10226c3341e66e12892ea2cd3 100644 --- a/src/lib/components/variables/VariableReferredScaleAtInstant.svelte +++ b/src/lib/components/variables/VariableReferredScaleAtInstant.svelte @@ -17,11 +17,13 @@ import { errorAsKeyValueDictionary, iterArrayWithErrors } from "$lib/errors" import { asAmountBracketAtInstant, + asAmountBracketAtInstantOrNullable, asAmountScaleParameter, asRateBracketAtInstant, + asRateBracketAtInstantOrNullable, asRateScaleParameter, - labelFromUnit, } from "$lib/parameters" + import { shortLabelFromUnitName } from "$lib/units" import VariableReferredValueEdit from "./VariableReferredValueEdit.svelte" @@ -46,7 +48,7 @@ ScaleType.SingleAmount, ].includes(billParameter.type) ? { - amount: { value: null } as NumberValue, + amount: { value: null } as unknown as NumberValue, threshold: { value: null } as MaybeNumberValue, } : { @@ -54,7 +56,7 @@ rate: { value: null } as MaybeNumberValue, threshold: { value: null } as MaybeNumberValue, } - scaleAtInstant = [...scaleAtInstant, bracket] + scaleAtInstant = [...(scaleAtInstant as ScaleAtInstant), bracket] } function asMaybeNumberValue(value: MaybeNumberValue | "expected") { @@ -65,6 +67,12 @@ return value as NumberValue } + function asNumberValueOrNullable( + value: NumberValue | "expected" | undefined | null, + ): NumberValue | undefined | null { + return value as NumberValue | undefined | null + } + function changeValue( index: number, key: keyof AmountBracketAtInstant | keyof RateBracketAtInstant, @@ -89,22 +97,22 @@ } } } - scaleAtInstant = [...scaleAtInstant] + scaleAtInstant = [...(scaleAtInstant as ScaleAtInstant)] const bracket = (scaleAtInstant[index] = { ...scaleAtInstant[index], - }) as BracketAtInstant + }) as AmountBracketAtInstant & RateBracketAtInstant bracket[key] = bracket[key] === "expected" ? { value: validValue } : { - ...(bracket[key] as { [key: string]: unknown }), + ...(bracket[key] as unknown as { [key: string]: unknown }), value: validValue, } dispatch("change", scaleAtInstant) } function deleteBracket(index: number) { - scaleAtInstant = [...scaleAtInstant] + scaleAtInstant = [...(scaleAtInstant as ScaleAtInstant)] scaleAtInstant.splice(index, 1) dispatch("change", scaleAtInstant) } @@ -163,7 +171,7 @@ : bracketAtInstant.threshold?.value ?? null} /> <span class="ml-1 text-base"> - {labelFromUnit(billParameter.threshold_unit) ?? ""} + {shortLabelFromUnitName(billParameter.threshold_unit) ?? ""} </span> {#if showErrors && errorAsKeyValueDictionary(errorAsKeyValueDictionary(errorsAtIndex).threshold).value !== undefined} <p> @@ -178,10 +186,10 @@ <td class="border-l border-black p-1 pl-3"> <div class="flex items-center"> <VariableReferredValueEdit - billValue={asAmountBracketAtInstant( + billValue={asAmountBracketAtInstantOrNullable( billScaleAtInstant?.[index], )?.amount} - lawValue={asAmountBracketAtInstant( + lawValue={asAmountBracketAtInstantOrNullable( lawScaleAtInstant?.[index], )?.amount} on:changeValue={(event) => @@ -195,7 +203,7 @@ ).value ?? null} /> <span class="text-base"> - {labelFromUnit( + {shortLabelFromUnitName( asAmountScaleParameter(billParameter).amount_unit, ) ?? ""} </span> @@ -213,10 +221,10 @@ <td class="border-l border-black p-1 pl-3"> <div class="flex items-center"> <VariableReferredValueEdit - billValue={asRateBracketAtInstant( + billValue={asRateBracketAtInstantOrNullable( billScaleAtInstant?.[index], )?.base} - lawValue={asRateBracketAtInstant( + lawValue={asRateBracketAtInstantOrNullable( lawScaleAtInstant?.[index], )?.base} on:changeValue={(event) => @@ -225,13 +233,15 @@ value={asRateBracketAtInstant(bracketAtInstant).base === "expected" ? null - : asNumberValue( - asRateBracketAtInstant(bracketAtInstant).base, + : asNumberValueOrNullable( + asRateBracketAtInstantOrNullable(bracketAtInstant) + ?.base, )?.value ?? null} /> <span class="ml-1 text-base"> <!-- TODO: Should be parameter.base_unit. --> - {labelFromUnit(billParameter.threshold_unit) ?? ""} + {shortLabelFromUnitName(billParameter.threshold_unit) ?? + ""} </span> {#if showErrors && errorAsKeyValueDictionary(errorAsKeyValueDictionary(errorsAtIndex).base).value !== undefined} <p> @@ -246,11 +256,12 @@ <td class="border-l border-black p-1 pl-3"> <div class="flex items-center"> <VariableReferredValueEdit - billValue={asRateBracketAtInstant( + billValue={asRateBracketAtInstantOrNullable( billScaleAtInstant?.[index], )?.rate} - lawValue={asRateBracketAtInstant(lawScaleAtInstant?.[index]) - ?.rate} + lawValue={asRateBracketAtInstantOrNullable( + lawScaleAtInstant?.[index], + )?.rate} on:changeValue={(event) => changeValue(index, "rate", event)} unit={asRateScaleParameter(billParameter).rate_unit} @@ -263,7 +274,7 @@ /> <span class="ml-1 text-base"> <!-- TODO: Should be parameter.base_unit. --> - {labelFromUnit( + {shortLabelFromUnitName( asRateScaleParameter(billParameter).rate_unit, ) ?? ""} </span> diff --git a/src/lib/components/variables/VariableReferredValueEdit.svelte b/src/lib/components/variables/VariableReferredValueEdit.svelte index ea05a3340c679e5b79fee41ec836f5b308b980d9..96b8742e7dcafcf366e7ae88b55161eb495635ed 100644 --- a/src/lib/components/variables/VariableReferredValueEdit.svelte +++ b/src/lib/components/variables/VariableReferredValueEdit.svelte @@ -1,28 +1,16 @@ <script lang="ts"> - import { - type AmountUnit, - type RateUnit, - type ThresholdUnit, - Unit, - type ValueAtInstant, - } from "@openfisca/json-model" + import type { ValueAtInstant } from "@openfisca/json-model" import { createEventDispatcher } from "svelte" export let billValue: ValueAtInstant | undefined | null export let lawValue: ValueAtInstant | undefined | null - export let unit: - | AmountUnit - | RateUnit - | ThresholdUnit - | Unit - | undefined - | null + export let unit: string | undefined | null export let value: | boolean | number | string - | string[] - | { [key: string]: string } + | (string | null)[] + | { [key: string]: string | null } | "expected" | undefined | null @@ -33,23 +21,21 @@ }) $: billValueFormatted = - billValue === undefined || - billValue === "expected" || - billValue.value === null + billValue == null || billValue === "expected" || billValue.value === null ? "absent" : typeof billValue.value === "number" ? numberFormatter.format( - unit === Unit.Rate + unit === "/1" ? parseFloat((billValue.value * 100).toFixed(8)) // trick to round value * 100 : billValue.value, ) : "TODO" $: lawValueFormatted = - lawValue === undefined || lawValue === "expected" || lawValue.value === null + lawValue == null || lawValue === "expected" || lawValue.value === null ? "absent" : typeof lawValue.value === "number" ? numberFormatter.format( - unit === Unit.Rate + unit === "/1" ? parseFloat((lawValue.value * 100).toFixed(8)) // trick to round value * 100 : lawValue.value, ) @@ -59,7 +45,7 @@ ? "absent" : typeof value === "number" ? numberFormatter.format( - unit === Unit.Rate + unit === "/1" ? parseFloat((value * 100).toFixed(8)) // trick to round value * 100 : value, ) @@ -74,7 +60,7 @@ function changeValue({ target }: Event) { let { value } = target as HTMLInputElement - if (unit === Unit.Rate) { + if (unit === "/1") { const validValue = parseFloat(value) if (validValue != null && !Number.isNaN(validValue)) { value = (validValue / 100).toString() @@ -110,7 +96,7 @@ placeholder={value === "expected" ? "attendu" : null} step="any" value={typeof value === "number" - ? unit === Unit.Rate + ? unit === "/1" ? parseFloat((value * 100).toFixed(8)) // trick to round value * 100 : value : null} diff --git a/src/lib/components/variables/VariableReferredValueParameter.svelte b/src/lib/components/variables/VariableReferredValueParameter.svelte index 33302cac8338ba8db4f30e01981844262f362b7c..5e52ca09df589c5d7e803788f9d16e554d9d685d 100644 --- a/src/lib/components/variables/VariableReferredValueParameter.svelte +++ b/src/lib/components/variables/VariableReferredValueParameter.svelte @@ -1,4 +1,5 @@ <script lang="ts"> + import Icon from "@iconify/svelte" import { parameterLastReviewOrChange, type Reference, @@ -11,11 +12,10 @@ import type { RequestedCalculationByName } from "$lib/calculations" import { requestCalculation } from "$lib/calculations" - import { labelFromUnit } from "$lib/parameters" + import ArticleModal from "$lib/components/parameters/ArticleModal.svelte" import type { ParametricReform, ValueParameterReform } from "$lib/reforms" import { ParameterReformChangeType } from "$lib/reforms" - import Icon from "@iconify/svelte" - import ArticleModal from "$lib/components/parameters/ArticleModal.svelte" + import { shortLabelFromUnitName } from "$lib/units" import VariableReferredParameterHeader from "./VariableReferredParameterHeader.svelte" import VariableReferredValueEdit from "./VariableReferredValueEdit.svelte" @@ -29,7 +29,7 @@ let billLatestInstantValueCouplesArray: [string, ValueAtInstant][] const dateFormatter = new Intl.DateTimeFormat("fr-FR", { dateStyle: "full" }) let lawInstantValueCouplesArray: [string, ValueAtInstant][] - let openReferenceUrl = null + let openReferenceUrl: string | null = null const parametricReform = getContext( "parametricReform", ) as Writable<ParametricReform> @@ -37,11 +37,14 @@ "requestedCalculationByName", ) as Writable<RequestedCalculationByName> let validValue = undefined - let valueError = null + let valueError: string | null = null - $: change = $parametricReform[billParameter.name] as - | ValueParameterReform - | undefined + $: change = + billParameter.name === undefined + ? undefined + : ($parametricReform[billParameter.name] as + | ValueParameterReform + | undefined) $: billLatestInstantValueCouplesArray = Object.entries( billParameter.values, @@ -99,11 +102,11 @@ return undefined } - function updateReform(start: string, value) { + function updateReform(start: string, value: number | undefined) { if (start !== undefined && value !== undefined) { $parametricReform = { ...$parametricReform, - [billParameter.name]: { + [billParameter.name as string]: { start, type: ParameterReformChangeType.Parameter, value, @@ -137,7 +140,7 @@ /> </div> <span class="ml-1 text-base"> - {labelFromUnit(billParameter.unit) ?? ""} + {shortLabelFromUnitName(billParameter.unit) ?? ""} </span> {#if valueError !== null}<p class="text-red-500">{valueError}</p>{/if} @@ -151,7 +154,7 @@ rel="noreferrer" target="_blank" > - {#if lastReviewOrChange < "2020"} + {#if lastReviewOrChange === undefined || lastReviewOrChange < "2020"} <!-- Inspired from Material Icons name: Warning / with white symbol inside --> <svg aria-hidden="true" @@ -165,9 +168,11 @@ </svg> <span class="pl-2" - title="La dernière relecture date du {dateFormatter.format( - new Date(lastReviewOrChange), - )}">À vérifier</span + title={lastReviewOrChange === undefined + ? "Ce paramètre n'a jamais été relu" + : `La dernière relecture date du ${dateFormatter.format( + new Date(lastReviewOrChange), + )}`}>À vérifier</span > {:else} <!-- Inspired from Material Icons name: New Releases / with white symbol inside --> @@ -241,7 +246,7 @@ {:else} <button class="link text-left" - on:click={() => (openReferenceUrl = href)} + on:click={() => (openReferenceUrl = href ?? null)} title="Voir le paramètre dans l'article de loi" > <Icon diff --git a/src/lib/errors.ts b/src/lib/errors.ts index efa4dd406d58c3bfb9a3d6c746eb4fa7690f8a73..d67caf8aa67a04ac2221cdadc5c33a0e11685a9e 100644 --- a/src/lib/errors.ts +++ b/src/lib/errors.ts @@ -50,19 +50,21 @@ export function errorAsKeyValueDictionary(error: unknown): { } export function* iterArrayWithErrors<T>( - value: Iterable<T>, + value: Iterable<T> | undefined | null, error: { [index: string]: unknown } | undefined | null, ): Generator<[T, unknown], void, unknown> { - if ( - error === undefined || - error === null || - typeof error === "string" || - Array.isArray(error) || - typeof error !== "object" - ) { - error = {} - } - for (const [index, item] of [...value].entries()) { - yield [item, error[index]] + if (value != null) { + if ( + error === undefined || + error === null || + typeof error === "string" || + Array.isArray(error) || + typeof error !== "object" + ) { + error = {} + } + for (const [index, item] of [...value].entries()) { + yield [item, error[index]] + } } } diff --git a/src/lib/parameters.ts b/src/lib/parameters.ts index 714b19e6b5e4141ddf98eec9992808dcf3f1d6a5..744ebf304ae464061bbafcdcd03108a6acf0030d 100644 --- a/src/lib/parameters.ts +++ b/src/lib/parameters.ts @@ -5,11 +5,9 @@ import { patchParameter, scaleByInstantFromBrackets, ScaleType, - Unit, ValueType, walkParameters, type AmountBracketAtInstant, - type AmountUnit, type BracketAtInstant, type LinearAverageRateScaleParameter, type MarginalAmountScaleParameter, @@ -17,7 +15,6 @@ import { type NodeParameter, type Parameter, type RateBracketAtInstant, - type RateUnit, type Reference, type ScaleAtInstant, type ScaleParameter, @@ -26,7 +23,6 @@ import { type ValueParameter, } from "@openfisca/json-model" -import { metadata } from "$lib/metadata" import { reformChangesByName } from "$lib/reforms" export interface InstantReferencesAndScale { @@ -74,10 +70,22 @@ export function asNodeParameter(parameter: Parameter): NodeParameter { return parameter as NodeParameter } +export function asAmountBracketAtInstantOrNullable( + bracket: BracketAtInstant | undefined | null, +) { + return bracket as AmountBracketAtInstant | undefined | null +} + export function asRateBracketAtInstant(bracket: BracketAtInstant) { return bracket as RateBracketAtInstant } +export function asRateBracketAtInstantOrNullable( + bracket: BracketAtInstant | undefined | null, +) { + return bracket as RateBracketAtInstant | undefined | null +} + export function asRateScaleParameter(parameter: ScaleParameter) { return parameter as | LinearAverageRateScaleParameter @@ -195,29 +203,6 @@ export function labelFromScaleType(type: ScaleType | string): string { ) } -export function labelFromUnit( - unit: AmountUnit | RateUnit | Unit | string | null | undefined, -): string { - if (unit == null) { - return undefined - } - return ( - { - [Unit.CodesDepartements]: "code département", - [Unit.CountryCode]: "code pays", - [Unit.Currency]: metadata.currency, - [Unit.CurrencyEUR]: "€", - [Unit.CurrencyFRF]: "FRF", - [Unit.CurrencyGBP]: "£", - [Unit.CurrencyUSD]: "$", - [Unit.Day]: "jour", - [Unit.Month]: "mois", - [Unit.Rate]: "%", // Number between 0 and 1 - [Unit.Year]: "année", - }[unit] ?? unit - ) -} - export function labelFromValueType(type: ValueType | string): string { return ( { diff --git a/src/lib/reforms.ts b/src/lib/reforms.ts index 7ac33303e4fbfc8bce95cc4c4a2f5eef310a2105..fb8409f6a4149a47e82737aac32dc0803b1bc889 100644 --- a/src/lib/reforms.ts +++ b/src/lib/reforms.ts @@ -7,7 +7,7 @@ import type { import { metadata } from "$lib/metadata" -export type ParameterReform = ValueParameterReform | ScaleParameterReform +export type ParameterReform = ScaleParameterReform | ValueParameterReform export interface ParameterReformBase { start: string diff --git a/src/lib/units.ts b/src/lib/units.ts new file mode 100644 index 0000000000000000000000000000000000000000..1998dd7550f0dc51e3d0a934a6582e7baa3ff7f4 --- /dev/null +++ b/src/lib/units.ts @@ -0,0 +1,33 @@ +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore +import unitsUnknown from "@leximpact/socio-fiscal-openfisca-json/units.yaml" +import type { UnitsMetadata } from "@openfisca/json-model" + +export function labelFromUnitName(unitName: string | undefined | null): string { + if (unitName == null) { + return "" + } + const unit = unitByName[unitName] + if (unit === undefined) { + return unitName + } + return unit.label ?? unitName +} + +export function shortLabelFromUnitName( + unitName: string | undefined | null, +): string { + if (unitName == null) { + return "" + } + const unit = unitByName[unitName] + if (unit === undefined) { + return unitName + } + return unit.short_label ?? unit.label ?? unitName +} + +export const units = unitsUnknown as UnitsMetadata +export const unitByName = Object.fromEntries( + units.map((unit) => [unit.name, unit]), +) diff --git a/src/lib/values.ts b/src/lib/values.ts index f0b59d067f8af528434cbffd0c24bfeb33d3b4d1..aee84eaf6cf56a37de90781303903fdfff0fd258 100644 --- a/src/lib/values.ts +++ b/src/lib/values.ts @@ -1,29 +1,33 @@ -export function formatValue(value: unknown, unit?: string): string { +export function formatValue(value: number, unit?: string): string { return valueFormatter(value, unit)(value) } export function valueFormatter( baseValue: unknown, - unit?: string, + unit?: string | undefined | null, ): (value: unknown) => string { return baseValue === undefined - ? () => "" + ? ((() => "") as (value: unknown) => string) : typeof baseValue === "boolean" - ? (value: boolean) => (value ? "vrai" : "faux") + ? (((value: boolean) => (value ? "vrai" : "faux")) as ( + value: unknown, + ) => string) : typeof baseValue === "number" - ? unit === "/1" // Unit.Rate - ? new Intl.NumberFormat("fr-FR", { + ? unit === "/1" // rate + ? (new Intl.NumberFormat("fr-FR", { maximumFractionDigits: 2, minimumFractionDigits: 2, style: "percent", - }).format + }).format as (value: unknown) => string) : unit != null && unit.startsWith("currency-") - ? new Intl.NumberFormat("fr-FR", { + ? (new Intl.NumberFormat("fr-FR", { currency: unit.replace(/^currency-/, ""), maximumFractionDigits: 0, minimumFractionDigits: 0, style: "currency", - }).format - : new Intl.NumberFormat("fr-FR").format - : (value: unknown) => value.toString() + }).format as (value: unknown) => string) + : (new Intl.NumberFormat("fr-FR").format as (value: unknown) => string) + : (((value: unknown) => (value as string).toString()) as ( + value: unknown, + ) => string) } diff --git a/vite.config.ts b/vite.config.ts index 77b6a0c7184f74c7fa955858031f5a30ccd37648..ca0833bae56da5197c165ccab5ca90bae4265093 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,5 +1,6 @@ import { sveltekit } from "@sveltejs/kit/vite" import type { UserConfig } from "vite" +import yaml from "@rollup/plugin-yaml" const config: UserConfig = { build: { @@ -12,7 +13,10 @@ const config: UserConfig = { // and https://github.com/sveltejs/vite-plugin-svelte/issues/124. exclude: ["svelte-modals"], }, - plugins: [sveltekit()], + plugins: [ + yaml(), // To import YAML files + sveltekit(), + ], ssr: { noExternal: ["d3-scale"], },