Skip to main content
Sign in
Snippets Groups Projects
Commit 6f0b6f49 authored by Emmanuel Raviart's avatar Emmanuel Raviart
Browse files

Use new API to retrieve & display parameters.

parent bd36b707
No related branches found
No related tags found
No related merge requests found
......@@ -3,6 +3,7 @@ import type { Session } from "$lib/session"
export function getSession(): Session {
return {
apiBaseUrl: config.apiBaseUrl,
apiWebSocketBaseUrl: config.apiWebSocketBaseUrl,
title: config.title,
}
......
......
<script lang="ts">
// import fetch from "cross-fetch"
import type { AnyParameter } from "$lib/parameters"
import { ParameterClass } from "$lib/parameters"
export let id: string
export let parameter: AnyParameter
let open = false
// $: retrieveParameter(node)
// async function retrieveParameter(node: ParametersNode): Promise<void> {
// const res = await fetch(node.href)
// if (!res.ok) {
// console.error(
// `Error ${res.status} while retrieving parameter at ${
// node.href
// }\n\n${await res.text()}`,
// )
// }
// parameter = await res.json()
// }
</script>
<button class="align-top flex text-left" on:click={() => (open = !open)}>
{#if parameter.class !== ParameterClass.Node}
<span class="h5 w-5" />
{:else if open}
<!-- Heroicon name: solid/chevron-down -->
<svg
class="h-5 inline w-5"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
clip-rule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
fill-rule="evenodd"
/>
</svg>
{:else}
<!-- Heroicon name: solid/chevron-right -->
<svg
class="h-5 inline w-5"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
clip-rule="evenodd"
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
fill-rule="evenodd"
/>
</svg>
{/if}
<div>
<abbr title={parameter.name}>{id}</abbr>
{#if parameter.description !== undefined}
: {parameter.description}
{/if}
{#if parameter.documentation !== undefined}
<div>{parameter.documentation}</div>
{/if}
{#if parameter.unit !== undefined}
<div>Unité : {parameter.unit}</div>
{/if}
{#if parameter.reference !== undefined}
<div>
Références :
{#if typeof parameter.reference === "string"}
{parameter.reference}
{:else if Array.isArray(parameter.reference)}
<ul class="list-disc list-inside">
{#each parameter.reference as reference}
<li>{reference}</li>
{/each}
</ul>
{:else}
<dl>
{#each Object.entries(parameter.reference) as [instant, reference]}
<dt>{instant}</dt>
<dd>{reference}</dd>
{/each}
</dl>
{/if}
</div>
{/if}
{#if parameter.source !== undefined}
<div>Source : <a href={parameter.source}>{parameter.source}</a></div>
{/if}
{#if parameter.class === ParameterClass.Parameter}
{#if parameter.values !== undefined}
<div>
<div>Valeurs :</div>
<table>
<thead>
<tr>
<th>Date</th>
<!-- <th>Nom</th> -->
<th>Valeur</th>
<th>Unité</th>
<th>Source</th>
</tr>
</thead>
<tbody>
{#each parameter.values as { instant, /* name, */ source, unit, value }}
<tr>
<td>{instant}</td>
<!-- <td>{name}</td> -->
<td>{value ?? ""}</td>
<td>{unit ?? ""}</td>
<td
>{#if source !== undefined}<a href={source}>source</a
>{/if}</td
>
</tr>
{/each}
</tbody>
</table>
</div>
{/if}
{:else if parameter.class === ParameterClass.Scale}
<div>
<div>Barème de type {parameter.type}:</div>
<table>
<thead>
<tr>
<th>Date</th>
<th>Seuil</th>
<th>Unité de seuil</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{#each Object.entries(parameter.brackets) as [instant, bracket]}
{#if bracket === null}
<tr>
<td>{instant}</td>
<td colspan="3" />
</tr>
{:else}
{#each Object.entries(bracket) as [threshold, value], index}
<tr>
{#if index === 0}
<td rowspan={Object.keys(bracket).length}>{instant}</td>
{/if}
<td>{threshold}</td>
<td
>{parameter.rate_unit ??
parameter.threshold_unit ??
""}</td
>
<td>{value ?? ""}</td>
</tr>
{/each}
{/if}
{/each}
</tbody>
</table>
</div>
{/if}
</div>
</button>
{#if parameter.class === ParameterClass.Node && open}
<ul class="ml-4">
{#each Object.entries(parameter.children) as [childId, child]}
<li>
<svelte:self id={childId} parameter={child} />
</li>
{/each}
</ul>
{/if}
<script lang="ts">
import fetch from "cross-fetch"
import ParametersTree from "$lib/ParametersTree.svelte"
import type { Parameter, ParametersNode } from "$lib/parameters"
export let id: string
export let node: ParametersNode
let open = false
let parameter: Parameter | undefined = undefined
$: retrieveParameter(node)
async function retrieveParameter(node: ParametersNode): Promise<void> {
const res = await fetch(node.href)
if (!res.ok) {
console.error(
`Error ${res.status} while retrieving parameter at ${
node.href
}\n\n${await res.text()}`,
)
}
parameter = await res.json()
}
</script>
<button
class="align-top text-left"
on:click|stopPropagation={() => (open = !open)}
>
<div>{id}</div>
{#if node.description !== null}
<p>{node.description}</p>
{/if}
{#if open}
{#if parameter?.source !== undefined}
<div><a href={parameter.source}>Source</a></div>
{/if}
{#if parameter?.values !== undefined}
<div>
<div>Valeurs :</div>
<table>
<thead>
<tr>
<th>Date</th>
<th>Values</th>
</tr>
</thead>
<tbody>
{#each Object.entries(parameter.values) as [date, value]}
<tr>
<td>{date}</td>
<td>{value}</td>
</tr>
{/each}
</tbody>
</table>
</div>
{/if}
{#if node.children !== undefined}
<ParametersTree tree={node.children} />
{/if}
{/if}
</button>
<script lang="ts">
import ParametersNode from "$lib/ParametersNode.svelte"
import type { ParametersTree } from "$lib/parameters"
export let tree: ParametersTree
</script>
<ul class="list-disc list-inside">
{#each Object.entries(tree) as [id, node]}
<li>
<ParametersNode {id} {node} />
</li>
{/each}
</ul>
export interface Parameter {
description: string | null
id: string
metadata: ParameterMetadata
source: string
subparams: { [id: string]: { description: string | null } }
values?: { [date: string]: number }
export type AnyParameter = Parameter | ParameterNode | Scale
export interface Parameter extends ParameterBase {
class: ParameterClass.Parameter
values: ParameterAtInstant[]
}
export interface ParameterAtInstant {
instant: string
name: string
source?: string
unit?: Unit
value: number | string | string[]
}
export interface ParameterBase {
class: ParameterClass
description?: string
documentation?: string
name: string
reference?: string | string[] | { [instant: string]: string }
source?: string
unit?: Unit
}
export enum ParameterClass {
Node = "Node",
Parameter = "Parameter",
Scale = "Scale",
}
export interface ParameterMetadata {
unit?: "/1"
export interface ParameterNode extends ParameterBase {
children: { [name: string]: AnyParameter }
class: ParameterClass.Node
}
export interface ParametersNode extends ParameterSummary {
children?: { [id: string]: ParametersNode }
export interface Scale extends ParameterBase {
brackets: { [instant: string]: { [threshold: string]: number | null } | null }
class: ParameterClass.Scale
rate_unit?: Unit.Rate
threshold_unit?: Unit.Currency
type: ScaleType
}
export interface ParameterSummary {
description: string | null
href: string
export enum ScaleType {
MarginalRate = "marginal_rate",
SingleAmount = "single_amount",
}
export interface ParametersTree {
[id: string]: ParametersNode
export enum Unit {
CountryCode = "ISO 3166-1 alpha-2", // Two-letters code of a country
Currency = "currency",
Rate = "/1", // Number between 0 and 1
Year = "year",
}
export interface Session {
apiBaseUrl: string
apiWebSocketBaseUrl: string
title: string
}
......@@ -49,6 +49,7 @@
submit()
}
}
function changeSituation({ detail }) {
situation = detail
if (webSocketOpen) {
......@@ -58,7 +59,7 @@
function openWebSocket() {
webSocket = new Sockette(
new URL("ws", $session.apiWebSocketBaseUrl).toString(),
new URL("calculate", $session.apiWebSocketBaseUrl).toString(),
{
// maxAttempts: 10,
onmessage: (event) => {
......
......
<script context="module" lang="ts">
import type { LoadInput, LoadOutput } from "@sveltejs/kit/types.internal"
import type { ParametersNode } from "$lib/parameters"
import type { ParameterNode } from "$lib/parameters"
export async function load({ fetch }: LoadInput): Promise<LoadOutput> {
const url = "https://fr.openfisca.org/api/latest/parameters"
export async function load({
fetch,
session,
}: LoadInput): Promise<LoadOutput> {
const url = new URL("parameters", session.apiBaseUrl).toString()
const res = await fetch(url)
if (!res.ok) {
return {
......@@ -12,37 +15,39 @@
error: new Error(`Could not load ${url}`),
}
}
const parameterById = await res.json()
const parametersTree: { [id: string]: ParametersNode } = {}
const parametersRootNode: ParametersNode = {
// Dummy root node of parameters tree.
children: parametersTree,
description: null,
href: "",
}
for (const parameterId of Object.keys(parameterById)) {
const idSegments: string[] = []
let node = parametersRootNode
for (const idSegment of parameterId.split(".")) {
idSegments.push(idSegment)
let tree = node.children
if (tree === undefined) {
tree = node.children = {}
}
node = tree[idSegment]
if (node === undefined) {
node = tree[idSegment] = {
description: null,
href: `https://fr.openfisca.org/api/latest/parameter/${idSegments.join(
"/",
)}`,
}
}
}
}
const parameter = await res.json()
// const parameterById = await res.json()
// const parametersTree: { [id: string]: ParametersNode } = {}
// const parametersRootNode: ParametersNode = {
// // Dummy root node of parameters tree.
// children: parametersTree,
// description: null,
// href: "",
// }
// for (const parameterId of Object.keys(parameterById)) {
// const idSegments: string[] = []
// let node = parametersRootNode
// for (const idSegment of parameterId.split(".")) {
// idSegments.push(idSegment)
// let tree = node.children
// if (tree === undefined) {
// tree = node.children = {}
// }
// node = tree[idSegment]
// if (node === undefined) {
// node = tree[idSegment] = {
// description: null,
// href: `https://fr.openfisca.org/api/latest/parameter/${idSegments.join(
// "/",
// )}`,
// }
// }
// }
// }
return {
props: {
parametersTree,
parameter,
// parametersTree,
},
}
}
......@@ -50,9 +55,9 @@
<script lang="ts">
import { session } from "$app/stores"
import ParametersTree from "$lib/ParametersTree.svelte"
import ParameterTree from "$lib/ParameterTree.svelte"
export let parametersTree: { [id: string]: ParametersNode }
export let parameter: ParameterNode
</script>
<svelte:head>
......@@ -62,5 +67,11 @@
<main>
<h1>Paramètres</h1>
<ParametersTree tree={parametersTree} />
<ul>
{#each Object.entries(parameter.children) as [childId, child]}
<li>
<ParameterTree id={childId} parameter={child} />
</li>
{/each}
</ul>
</main>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment