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