diff options
Diffstat (limited to 'fe/src/lib/Table.svelte')
-rw-r--r-- | fe/src/lib/Table.svelte | 172 |
1 files changed, 90 insertions, 82 deletions
diff --git a/fe/src/lib/Table.svelte b/fe/src/lib/Table.svelte index 3a66e0d..d1cd7da 100644 --- a/fe/src/lib/Table.svelte +++ b/fe/src/lib/Table.svelte | |||
@@ -1,105 +1,113 @@ | |||
1 | <script lang="ts"> | 1 | <script lang="ts"> |
2 | export let data: Array<any> | undefined = undefined; | 2 | export let data: Array<any> | undefined = undefined; |
3 | export let nofooter: boolean = false; | 3 | export let nofooter: boolean = false; |
4 | export let noheader: boolean = false; | 4 | export let noheader: boolean = false; |
5 | export let omit: string[] = ["id"]; | 5 | export let omit: string[] = ["id"]; |
6 | export let title: string | undefined = undefined; | 6 | export let title: string | undefined = undefined; |
7 | 7 | ||
8 | function getDataKeys(data: any[]): string[] { | 8 | function getDataKeys(data: any[]): string[] { |
9 | if (!data || data.length === 0) return []; | 9 | if (!data || data.length === 0) return []; |
10 | return Object.keys(data[0]) | 10 | return Object.keys(data[0]) |
11 | .map((k) => k.split("_").join(" ")) | 11 | .map((k) => k.split("_").join(" ")) |
12 | .filter((k) => !omit.includes(k)); | 12 | .filter((k) => !omit.includes(k)); |
13 | } | 13 | } |
14 | 14 | ||
15 | function getRow(row: Record<string, any>): Array<any> { | 15 | function getRow(row: Record<string, any>): Array<any> { |
16 | return Object.entries(row).filter((r) => !omit.includes(r[0])); | 16 | return Object.entries(row).filter((r) => !omit.includes(r[0])); |
17 | } | 17 | } |
18 | 18 | ||
19 | const formatter = new Intl.DateTimeFormat("en", { | ||
20 | year: "numeric", | ||
21 | month: "numeric", | ||
22 | day: "numeric", | ||
23 | hour: "numeric", | ||
24 | minute: "2-digit", | ||
25 | second: "2-digit", | ||
26 | timeZone: "America/New_York", | ||
27 | }); | ||
28 | 19 | ||
29 | function formatDatum([key, value]: any[]) { | 20 | let limitedData: Array<any> = []; |
30 | if (key === "date") { | ||
31 | const parsedDate = new Date(value); | ||
32 | return formatter.format(parsedDate); | ||
33 | } | ||
34 | 21 | ||
35 | if (key === "user") { | 22 | if (data && (data as any[]).length > 0) { |
36 | return value["name"]; | 23 | limitedData = (data as any[]).slice(0, 4); |
37 | } | 24 | } |
38 | 25 | ||
39 | return value; | 26 | const formatter = new Intl.DateTimeFormat("en", { |
40 | } | 27 | year: "numeric", |
28 | month: "numeric", | ||
29 | day: "numeric", | ||
30 | hour: "numeric", | ||
31 | minute: "2-digit", | ||
32 | second: "2-digit", | ||
33 | timeZone: "America/New_York" | ||
34 | }); | ||
35 | |||
36 | function formatDatum([key, value]: any[]) { | ||
37 | if (key === "date") { | ||
38 | const parsedDate = new Date(value); | ||
39 | return formatter.format(parsedDate); | ||
40 | } | ||
41 | |||
42 | if (key === "user") { | ||
43 | return value["name"]; | ||
44 | } | ||
45 | |||
46 | return value; | ||
47 | } | ||
41 | </script> | 48 | </script> |
42 | 49 | ||
43 | <table> | 50 | <table> |
44 | {#if title} | 51 | {#if title} |
45 | <h2>{title}</h2> | 52 | <h2>{title}</h2> |
46 | {/if} | 53 | {/if} |
47 | {#if !noheader && data} | 54 | {#if !noheader && data} |
48 | <thead> | 55 | <thead> |
49 | <tr> | ||
50 | {#each getDataKeys(data) as header} | ||
51 | <th>{header}</th> | ||
52 | {/each} | ||
53 | </tr> | ||
54 | </thead> | ||
55 | {/if} | ||
56 | <tbody> | ||
57 | {#if data} | ||
58 | {#each data as row} | ||
59 | <tr> | 56 | <tr> |
60 | {#each getRow(row) as datum} | 57 | {#each getDataKeys(data) as header} |
61 | <td>{formatDatum(datum)}</td> | 58 | <th>{header}</th> |
62 | {/each} | 59 | {/each} |
63 | </tr> | 60 | </tr> |
64 | {/each} | 61 | </thead> |
62 | {/if} | ||
63 | <tbody> | ||
64 | {#if data} | ||
65 | {#each limitedData as row} | ||
66 | <tr> | ||
67 | {#each getRow(row) as datum} | ||
68 | <td>{formatDatum(datum)}</td> | ||
69 | {/each} | ||
70 | </tr> | ||
71 | {/each} | ||
65 | {:else} | 72 | {:else} |
66 | <tr> There is not data. </tr> | 73 | <tr> There is not data.</tr> |
74 | {/if} | ||
75 | </tbody> | ||
76 | {#if !nofooter} | ||
77 | <slot name="footer"> | ||
78 | <tfoot> | ||
79 | <tr> | ||
80 | <td>Table Footer</td> | ||
81 | </tr> | ||
82 | </tfoot> | ||
83 | </slot> | ||
67 | {/if} | 84 | {/if} |
68 | </tbody> | ||
69 | {#if !nofooter} | ||
70 | <slot name="footer"> | ||
71 | <tfoot> | ||
72 | <tr> | ||
73 | <td>Table Footer</td> | ||
74 | </tr> | ||
75 | </tfoot> | ||
76 | </slot> | ||
77 | {/if} | ||
78 | </table> | 85 | </table> |
79 | 86 | ||
80 | <style> | 87 | <style> |
81 | table { | 88 | table { |
82 | padding: 16px; | 89 | padding: 16px; |
83 | margin: 8px; | 90 | margin: 8px; |
84 | border: solid 1px black; | 91 | border: solid 1px black; |
85 | border-collapse: collapse; | 92 | border-collapse: collapse; |
86 | } | 93 | overflow-y: hidden; |
94 | } | ||
87 | 95 | ||
88 | th { | 96 | th { |
89 | text-transform: capitalize; | 97 | text-transform: capitalize; |
90 | } | 98 | } |
91 | 99 | ||
92 | thead tr { | 100 | thead tr { |
93 | background: rgba(0, 0, 23, 0.34); | 101 | background: rgba(0, 0, 23, 0.34); |
94 | } | 102 | } |
95 | 103 | ||
96 | tbody tr:nth-child(odd) { | 104 | tbody tr:nth-child(odd) { |
97 | background: rgba(0, 0, 23, 0.14); | 105 | background: rgba(0, 0, 23, 0.14); |
98 | } | 106 | } |
99 | 107 | ||
100 | th, | 108 | th, |
101 | td { | 109 | td { |
102 | padding: 1em; | 110 | padding: 1em; |
103 | border: 1px solid rgba(0, 0, 0, 1); | 111 | border: 1px solid rgba(0, 0, 0, 1); |
104 | } | 112 | } |
105 | </style> | 113 | </style> |