Work on the trace viewer for form lines.
[ustaxviewer.git] / src / FormView.tsx
1 // Copyright 2020 Blue Static <https://www.bluestatic.org>
2 // This program is free software licensed under the GNU General Public License,
3 // version 3.0. The full text of the license can be found in LICENSE.txt.
4 // SPDX-License-Identifier: GPL-3.0-only
5
6 import { createDependentEffect, createMemo, createState } from 'solid-js';
7 import { For, Show } from 'solid-js/dom';
8 import { TaxReturn, Form, Line } from 'ustaxlib/core';
9 import { getLastTraceList } from 'ustaxlib/core/Trace';
10
11 const S = require('./FormView.css');
12
13 interface FormProps {
14 tr: TaxReturn;
15 form: Form<any>;
16 }
17
18 export default function FormView(props: FormProps) {
19 const lines = createMemo(() => {
20 const keys = Object.keys(props.form.lines);
21 keys.sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
22 return keys.map(k => props.form.lines[k]);
23 });
24
25 return (
26 <>
27 <h2 class={S.formName}>Form {props.form.name}</h2>
28
29 <table class={S.table}>
30 <For each={lines()}>
31 {line => <LineView tr={props.tr} line={line} />}
32 </For>
33 </table>
34 </>
35 );
36 }
37
38 interface LineProps {
39 tr: TaxReturn;
40 line: Line<any>;
41 }
42
43 function LineView(props: LineProps) {
44 const { tr, line } = props;
45 const value = createMemo(() => {
46 try {
47 return JSON.stringify(line.value(tr), null, 1);
48 } catch (e) {
49 return <span class={S.error} title={e.stack}>{e.message}</span>;
50 }
51 });
52
53 const [ state, setState ] = createState({
54 trace: "",
55 showTrace: false
56 });
57
58 createDependentEffect(() => setState('trace', JSON.stringify(getLastTraceList(), null, ' ')), [value]);
59
60 const toggleTrace = () => setState('showTrace', !state.showTrace);
61
62 return (
63 <tr class={S.line}>
64 <th class={S.id} onclick={toggleTrace}>{line.id}</th>
65 <td class={S.description}>
66 {line.description}
67
68 <Show when={state.showTrace}>
69 <TraceViewer line={line} trace={state.trace} />
70 </Show>
71 </td>
72 <td class={S.value}>{value()}</td>
73 </tr>
74 );
75 }
76
77 interface TraceProps {
78 line: Line<any>;
79 trace: string;
80 }
81
82 function TraceViewer(props: TraceProps) {
83 return (
84 <div class={S.traceViewer}>
85 <h2>Trace {props.line.id}</h2>
86 <div class={S.trace}>{props.trace}</div>
87 </div>
88 );
89 }