@sealcode/sealgen 0.15.54 → 0.15.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/@types/src/forms/controls/table.d.ts +3 -9
- package/@types/src/forms/fields/table.d.ts +1 -2
- package/lib/builder.js +1 -1
- package/lib/forms/controls/table.js +39 -59
- package/package.json +1 -1
- package/src/builder.ts +1 -1
- package/src/forms/controls/table.ts +58 -79
- package/src/forms/fields/table.ts +14 -13
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/// <reference types="koa__router" />
|
|
2
2
|
import Router from "@koa/router";
|
|
3
|
-
import { Context } from "koa";
|
|
4
3
|
import { FlatTemplatable } from "tempstream";
|
|
5
4
|
import { FormField } from "../fields/field.js";
|
|
6
5
|
import { Table as TableField } from "../fields/table.js";
|
|
@@ -14,14 +13,9 @@ export type TableControlOptions<F extends Record<string, FormField>> = {
|
|
|
14
13
|
label_add?: string;
|
|
15
14
|
label: string;
|
|
16
15
|
label_remove?: string;
|
|
17
|
-
} &
|
|
18
|
-
allow_adding:
|
|
19
|
-
}
|
|
20
|
-
allow_adding: true;
|
|
21
|
-
make_new_row: (ctx: Context) => Promise<{
|
|
22
|
-
[field_name in keyof F]: unknown;
|
|
23
|
-
}>;
|
|
24
|
-
});
|
|
16
|
+
} & {
|
|
17
|
+
allow_adding: boolean;
|
|
18
|
+
};
|
|
25
19
|
export declare class Table<F extends Record<string, FormField>> extends FormControl {
|
|
26
20
|
table_field: TableField<F>;
|
|
27
21
|
options: TableControlOptions<F>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Context } from "koa";
|
|
2
2
|
import { FormDataValue } from "../form-types.js";
|
|
3
3
|
import { FieldParseResult, FormField } from "./field.js";
|
|
4
|
-
type ExtractFormFieldParsed<Field extends FormField> = Field extends FormField<true, infer T> ? NonNullable<T> : Field extends FormField<true, infer T> ? T : never;
|
|
4
|
+
export type ExtractFormFieldParsed<Field extends FormField> = Field extends FormField<true, infer T> ? NonNullable<T> : Field extends FormField<true, infer T> ? T : never;
|
|
5
5
|
export type TableFieldParsed<F extends Record<string, FormField>> = {
|
|
6
6
|
[field_name in keyof F]: ExtractFormFieldParsed<F[field_name]>;
|
|
7
7
|
}[];
|
|
@@ -11,4 +11,3 @@ export declare class Table<F extends Record<string, FormField>> extends FormFiel
|
|
|
11
11
|
getEmptyValue(): never[];
|
|
12
12
|
parse(ctx: Context, raw_value: FormDataValue): Promise<FieldParseResult<TableFieldParsed<F>>>;
|
|
13
13
|
}
|
|
14
|
-
export {};
|
package/lib/builder.js
CHANGED
|
@@ -17,44 +17,28 @@ class Table extends FormControl {
|
|
|
17
17
|
if (!rows) {
|
|
18
18
|
rows = [];
|
|
19
19
|
}
|
|
20
|
-
|
|
21
|
-
id="${this.getFrameID()}"
|
|
22
|
-
class="${[
|
|
23
|
-
"form-input__wrapper",
|
|
24
|
-
"form-input__wrapper--type--table",
|
|
25
|
-
"form-input__wrapper--options-count--" + rows.length.toString(),
|
|
26
|
-
...rows.length >= 5 ? ["form-input__wrapper--options-count--5-or-more"] : [],
|
|
27
|
-
...rows.length >= 10 ? ["form-input__wrapper--options-count--10-or-more"] : [],
|
|
28
|
-
...rows.length >= 15 ? ["form-input__wrapper--options-count--15-or-more"] : [],
|
|
29
|
-
...rows.length >= 20 ? ["form-input__wrapper--options-count--20-or-more"] : []
|
|
30
|
-
].join(" ")}"
|
|
31
|
-
>
|
|
32
|
-
<label>${this.options.label}</label>
|
|
33
|
-
<div class="table__wrapper">
|
|
34
|
-
<table>
|
|
35
|
-
<tbody>
|
|
36
|
-
${rows?.map((row, row_index) => {
|
|
20
|
+
const make_row = (row, row_index) => {
|
|
37
21
|
return (
|
|
38
22
|
/* HTML */
|
|
39
23
|
tempstream`<tr>
|
|
40
|
-
|
|
24
|
+
${Object.entries(this.table_field.columns).map(([key]) => {
|
|
41
25
|
return tempstream`<td>${this.options.render_fields[key](
|
|
42
26
|
fctx,
|
|
43
|
-
`${this.table_field.name}[
|
|
27
|
+
`${this.table_field.name}[][${key}]`,
|
|
44
28
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
45
|
-
row[key]
|
|
29
|
+
row?.[key] || ""
|
|
46
30
|
)}</td>`;
|
|
47
31
|
})}
|
|
48
|
-
|
|
32
|
+
${this.options.allow_removing ? (
|
|
49
33
|
/* HTML */
|
|
50
34
|
`<td>
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
35
|
+
<input
|
|
36
|
+
type="submit"
|
|
37
|
+
data-turbo-frame="${this.getFrameID()}"
|
|
38
|
+
value="${this.options.label_remove || "remove"}"
|
|
39
|
+
form="${fctx.form_id}"
|
|
40
|
+
formnovalidate
|
|
41
|
+
formaction="${this.getActionURL(
|
|
58
42
|
this.table_field.name,
|
|
59
43
|
{
|
|
60
44
|
remove: {
|
|
@@ -62,28 +46,39 @@ class Table extends FormControl {
|
|
|
62
46
|
}
|
|
63
47
|
}
|
|
64
48
|
)}"
|
|
65
|
-
|
|
66
|
-
|
|
49
|
+
/>
|
|
50
|
+
</td>`
|
|
67
51
|
) : ""}
|
|
68
|
-
|
|
52
|
+
</tr>`
|
|
69
53
|
);
|
|
70
|
-
}
|
|
54
|
+
};
|
|
55
|
+
return tempstream`<turbo-frame
|
|
56
|
+
id="${this.getFrameID()}"
|
|
57
|
+
class="${[
|
|
58
|
+
"form-input__wrapper",
|
|
59
|
+
"form-input__wrapper--type--table",
|
|
60
|
+
"form-input__wrapper--options-count--" + rows.length.toString(),
|
|
61
|
+
...rows.length >= 5 ? ["form-input__wrapper--options-count--5-or-more"] : [],
|
|
62
|
+
...rows.length >= 10 ? ["form-input__wrapper--options-count--10-or-more"] : [],
|
|
63
|
+
...rows.length >= 15 ? ["form-input__wrapper--options-count--15-or-more"] : [],
|
|
64
|
+
...rows.length >= 20 ? ["form-input__wrapper--options-count--20-or-more"] : []
|
|
65
|
+
].join(" ")}"
|
|
66
|
+
>
|
|
67
|
+
<label>${this.options.label}</label>
|
|
68
|
+
<div class="table__wrapper">
|
|
69
|
+
<table>
|
|
70
|
+
<tbody>
|
|
71
|
+
${rows?.map((row, index) => make_row(row, index))}
|
|
71
72
|
</tbody>
|
|
72
73
|
</table>
|
|
74
|
+
<template> ${make_row(null, rows.length)} </template>
|
|
73
75
|
${this.options.allow_adding ? (
|
|
74
76
|
/* HTML */
|
|
75
|
-
`<
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
formaction="${this.getActionURL(
|
|
81
|
-
this.table_field.name,
|
|
82
|
-
{
|
|
83
|
-
insert: { index: rows.length, value: {} }
|
|
84
|
-
}
|
|
85
|
-
)}"
|
|
86
|
-
/>`
|
|
77
|
+
`<button
|
|
78
|
+
onclick="this.closest('turbo-frame').querySelector('tbody').appendChild(this.closest('turbo-frame').querySelector('template').cloneNode(true).content)"
|
|
79
|
+
>
|
|
80
|
+
add
|
|
81
|
+
</button>`
|
|
87
82
|
) : ""}
|
|
88
83
|
</div>
|
|
89
84
|
</turbo-frame>`;
|
|
@@ -105,21 +100,6 @@ class Table extends FormControl {
|
|
|
105
100
|
await next();
|
|
106
101
|
return;
|
|
107
102
|
}
|
|
108
|
-
if (this.options.allow_adding && hasShape(
|
|
109
|
-
{
|
|
110
|
-
insert: predicates.shape({ index: predicates.string })
|
|
111
|
-
},
|
|
112
|
-
action
|
|
113
|
-
)) {
|
|
114
|
-
if (field_name !== this.table_field.name) {
|
|
115
|
-
await next();
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
if (!ctx.$body[this.table_field.name]) {
|
|
119
|
-
ctx.$body[this.table_field.name] = {};
|
|
120
|
-
}
|
|
121
|
-
ctx.$body[this.table_field.name][action.insert.index] = await this.options.make_new_row(ctx);
|
|
122
|
-
}
|
|
123
103
|
if (hasShape(
|
|
124
104
|
{
|
|
125
105
|
remove: predicates.shape({ index: predicates.string })
|
package/package.json
CHANGED
package/src/builder.ts
CHANGED
|
@@ -7,7 +7,11 @@ import { Context } from "koa";
|
|
|
7
7
|
import qs from "qs";
|
|
8
8
|
import { FlatTemplatable, tempstream } from "tempstream";
|
|
9
9
|
import { FormField } from "../fields/field.js";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
ExtractFormFieldParsed,
|
|
12
|
+
Table as TableField,
|
|
13
|
+
TableFieldParsed,
|
|
14
|
+
} from "../fields/table.js";
|
|
11
15
|
import { FormReaction } from "../form-types.js";
|
|
12
16
|
import { Form } from "../form.js";
|
|
13
17
|
import { FormControl, FormControlContext } from "./form-control.js";
|
|
@@ -24,15 +28,7 @@ export type TableControlOptions<F extends Record<string, FormField>> = {
|
|
|
24
28
|
label_add?: string;
|
|
25
29
|
label: string;
|
|
26
30
|
label_remove?: string;
|
|
27
|
-
} &
|
|
28
|
-
| { allow_adding: false }
|
|
29
|
-
| {
|
|
30
|
-
allow_adding: true;
|
|
31
|
-
make_new_row: (
|
|
32
|
-
ctx: Context
|
|
33
|
-
) => Promise<{ [field_name in keyof F]: unknown }>;
|
|
34
|
-
}
|
|
35
|
-
);
|
|
31
|
+
} & { allow_adding: boolean };
|
|
36
32
|
|
|
37
33
|
export class Table<F extends Record<string, FormField>> extends FormControl {
|
|
38
34
|
role = <const>"input";
|
|
@@ -51,6 +47,51 @@ export class Table<F extends Record<string, FormField>> extends FormControl {
|
|
|
51
47
|
if (!rows) {
|
|
52
48
|
rows = [];
|
|
53
49
|
}
|
|
50
|
+
|
|
51
|
+
const make_row = (
|
|
52
|
+
row:
|
|
53
|
+
| {
|
|
54
|
+
[field_name in keyof F]: ExtractFormFieldParsed<
|
|
55
|
+
F[field_name]
|
|
56
|
+
>;
|
|
57
|
+
}
|
|
58
|
+
| null,
|
|
59
|
+
row_index: number
|
|
60
|
+
) => {
|
|
61
|
+
return /* HTML */ tempstream`<tr>
|
|
62
|
+
${Object.entries(this.table_field.columns).map(([key]) => {
|
|
63
|
+
return tempstream`<td>${this.options.render_fields[key](
|
|
64
|
+
fctx,
|
|
65
|
+
`${this.table_field.name}[][${key}]`,
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
67
|
+
(row?.[key] as string) || ""
|
|
68
|
+
)}</td>`;
|
|
69
|
+
})}
|
|
70
|
+
${
|
|
71
|
+
this.options.allow_removing
|
|
72
|
+
? /* HTML */ `<td>
|
|
73
|
+
<input
|
|
74
|
+
type="submit"
|
|
75
|
+
data-turbo-frame="${this.getFrameID()}"
|
|
76
|
+
value="${this.options.label_remove ||
|
|
77
|
+
"remove"}"
|
|
78
|
+
form="${fctx.form_id}"
|
|
79
|
+
formnovalidate
|
|
80
|
+
formaction="${this.getActionURL(
|
|
81
|
+
this.table_field.name,
|
|
82
|
+
{
|
|
83
|
+
remove: {
|
|
84
|
+
index: row_index,
|
|
85
|
+
},
|
|
86
|
+
}
|
|
87
|
+
)}"
|
|
88
|
+
/>
|
|
89
|
+
</td>`
|
|
90
|
+
: ""
|
|
91
|
+
}
|
|
92
|
+
</tr>`;
|
|
93
|
+
};
|
|
94
|
+
|
|
54
95
|
return tempstream/* HTML */ `<turbo-frame
|
|
55
96
|
id="${this.getFrameID()}"
|
|
56
97
|
class="${[
|
|
@@ -75,59 +116,16 @@ export class Table<F extends Record<string, FormField>> extends FormControl {
|
|
|
75
116
|
<div class="table__wrapper">
|
|
76
117
|
<table>
|
|
77
118
|
<tbody>
|
|
78
|
-
${rows?.map((row,
|
|
79
|
-
return /* HTML */ tempstream`<tr>
|
|
80
|
-
${Object.entries(this.table_field.columns).map(([key]) => {
|
|
81
|
-
return tempstream`<td>${this.options.render_fields[
|
|
82
|
-
key
|
|
83
|
-
](
|
|
84
|
-
fctx,
|
|
85
|
-
`${this.table_field.name}[${row_index}][${key}]`,
|
|
86
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
87
|
-
row[key] as string
|
|
88
|
-
)}</td>`;
|
|
89
|
-
})}
|
|
90
|
-
${
|
|
91
|
-
this.options.allow_removing
|
|
92
|
-
? /* HTML */ `<td>
|
|
93
|
-
<input
|
|
94
|
-
type="submit"
|
|
95
|
-
data-turbo-frame="${this.getFrameID()}"
|
|
96
|
-
value="${this.options
|
|
97
|
-
.label_remove ||
|
|
98
|
-
"remove"}"
|
|
99
|
-
form="${fctx.form_id}"
|
|
100
|
-
formnovalidate
|
|
101
|
-
formaction="${this.getActionURL(
|
|
102
|
-
this.table_field
|
|
103
|
-
.name,
|
|
104
|
-
{
|
|
105
|
-
remove: {
|
|
106
|
-
index: row_index,
|
|
107
|
-
},
|
|
108
|
-
}
|
|
109
|
-
)}"
|
|
110
|
-
/>
|
|
111
|
-
</td>`
|
|
112
|
-
: ""
|
|
113
|
-
}
|
|
114
|
-
</tr>`;
|
|
115
|
-
})}
|
|
119
|
+
${rows?.map((row, index) => make_row(row, index))}
|
|
116
120
|
</tbody>
|
|
117
121
|
</table>
|
|
122
|
+
<template> ${make_row(null, rows.length)} </template>
|
|
118
123
|
${this.options.allow_adding
|
|
119
|
-
? /* HTML */ `<
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
formaction="${this.getActionURL(
|
|
125
|
-
this.table_field.name,
|
|
126
|
-
{
|
|
127
|
-
insert: { index: rows.length, value: {} },
|
|
128
|
-
}
|
|
129
|
-
)}"
|
|
130
|
-
/>`
|
|
124
|
+
? /* HTML */ `<button
|
|
125
|
+
onclick="this.closest('turbo-frame').querySelector('tbody').appendChild(this.closest('turbo-frame').querySelector('template').cloneNode(true).content)"
|
|
126
|
+
>
|
|
127
|
+
add
|
|
128
|
+
</button>`
|
|
131
129
|
: ""}
|
|
132
130
|
</div>
|
|
133
131
|
</turbo-frame>`;
|
|
@@ -155,25 +153,6 @@ export class Table<F extends Record<string, FormField>> extends FormControl {
|
|
|
155
153
|
await next();
|
|
156
154
|
return;
|
|
157
155
|
}
|
|
158
|
-
if (
|
|
159
|
-
this.options.allow_adding &&
|
|
160
|
-
hasShape(
|
|
161
|
-
{
|
|
162
|
-
insert: predicates.shape({ index: predicates.string }),
|
|
163
|
-
},
|
|
164
|
-
action
|
|
165
|
-
)
|
|
166
|
-
) {
|
|
167
|
-
if (field_name !== this.table_field.name) {
|
|
168
|
-
await next();
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
if (!ctx.$body[this.table_field.name]) {
|
|
172
|
-
ctx.$body[this.table_field.name] = {};
|
|
173
|
-
}
|
|
174
|
-
(ctx.$body[this.table_field.name] as any)[action.insert.index] =
|
|
175
|
-
await this.options.make_new_row(ctx);
|
|
176
|
-
}
|
|
177
156
|
if (
|
|
178
157
|
hasShape(
|
|
179
158
|
{
|
|
@@ -3,19 +3,20 @@ import { Context } from "koa";
|
|
|
3
3
|
import { FormDataValue } from "../form-types.js";
|
|
4
4
|
import { FieldParseResult, FormField } from "./field.js";
|
|
5
5
|
|
|
6
|
-
type ExtractFormFieldParsed<Field extends FormField> =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
6
|
+
export type ExtractFormFieldParsed<Field extends FormField> =
|
|
7
|
+
Field extends FormField<
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
true,
|
|
10
|
+
infer T
|
|
11
|
+
>
|
|
12
|
+
? NonNullable<T>
|
|
13
|
+
: Field extends FormField<
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15
|
+
true,
|
|
16
|
+
infer T
|
|
17
|
+
>
|
|
18
|
+
? T
|
|
19
|
+
: never;
|
|
19
20
|
|
|
20
21
|
export type TableFieldParsed<F extends Record<string, FormField>> = {
|
|
21
22
|
[field_name in keyof F]: ExtractFormFieldParsed<F[field_name]>;
|