@sealcode/sealgen 0.15.45 → 0.15.47
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/page/stateful-page.d.ts +2 -0
- package/lib/builder.js +1 -0
- package/lib/page/stateful-page.js +6 -2
- package/lib/templates/form.js +0 -2
- package/lib/templates/jdd-component.js +2 -2
- package/lib/templates/redirect.js +2 -2
- package/lib/templates/shared/collection-create-form.js +1 -1
- package/lib/templates/shared/collection-edit-form.js +12 -7
- package/lib/templates/shared/item-delete.js +1 -1
- package/package.json +1 -1
- package/src/builder.ts +1 -0
- package/src/page/stateful-page.ts +8 -3
- package/src/templates/form.ts +0 -2
- package/src/templates/jdd-component.ts +2 -2
- package/src/templates/redirect.ts +2 -2
- package/src/templates/shared/collection-create-form.ts +1 -1
- package/src/templates/shared/collection-edit-form.ts +12 -7
- package/src/templates/shared/item-delete.ts +1 -1
- package/@types/src/forms/fields/collection-field.test.d.ts +0 -1
- package/@types/src/vitest.config.d.ts +0 -2
|
@@ -8,6 +8,7 @@ export type StatefulPageActionDescription<ActionName> = {
|
|
|
8
8
|
action: ActionName;
|
|
9
9
|
label?: string;
|
|
10
10
|
content?: string;
|
|
11
|
+
disabled?: boolean;
|
|
11
12
|
} | ActionName;
|
|
12
13
|
export type StateAndMetadata<State, Actions> = {
|
|
13
14
|
state: State;
|
|
@@ -36,6 +37,7 @@ export declare abstract class StatefulPage<State extends Record<string, unknown>
|
|
|
36
37
|
action: string;
|
|
37
38
|
label: string;
|
|
38
39
|
content: string;
|
|
40
|
+
disabled: boolean;
|
|
39
41
|
};
|
|
40
42
|
makeActionURL<ActionName extends keyof Actions>(action_description: StatefulPageActionDescription<ActionName>, ...args: ExtractTail<ExtractTail<ExtractTail<Parameters<Actions[ActionName]>>>>): string;
|
|
41
43
|
makeActionButton<ActionName extends keyof Actions>(_state: State, action_description: StatefulPageActionDescription<ActionName>, ...args: ExtractTail<ExtractTail<ExtractTail<Parameters<Actions[ActionName]>>>>): string;
|
package/lib/builder.js
CHANGED
|
@@ -39,16 +39,19 @@ class StatefulPage extends Mountable {
|
|
|
39
39
|
}
|
|
40
40
|
extractActionAndLabel(action_description) {
|
|
41
41
|
let label, action, content;
|
|
42
|
+
let disabled;
|
|
42
43
|
if (is(action_description, predicates.object)) {
|
|
43
44
|
action = action_description.action.toString();
|
|
44
45
|
label = action_description.label || action;
|
|
45
46
|
content = action_description.content || label;
|
|
47
|
+
disabled = action_description.disabled || false;
|
|
46
48
|
} else {
|
|
47
49
|
action = action_description.toString();
|
|
48
50
|
label = action;
|
|
49
51
|
content = label;
|
|
52
|
+
disabled = false;
|
|
50
53
|
}
|
|
51
|
-
return { action, label, content };
|
|
54
|
+
return { action, label, content, disabled };
|
|
52
55
|
}
|
|
53
56
|
makeActionURL(action_description, ...args) {
|
|
54
57
|
const { action } = this.extractActionAndLabel(action_description);
|
|
@@ -58,7 +61,7 @@ class StatefulPage extends Mountable {
|
|
|
58
61
|
)}`;
|
|
59
62
|
}
|
|
60
63
|
makeActionButton(_state, action_description, ...args) {
|
|
61
|
-
const { label, content } = this.extractActionAndLabel(action_description);
|
|
64
|
+
const { label, content, disabled } = this.extractActionAndLabel(action_description);
|
|
62
65
|
return (
|
|
63
66
|
/* HTML */
|
|
64
67
|
`
|
|
@@ -66,6 +69,7 @@ class StatefulPage extends Mountable {
|
|
|
66
69
|
type="submit"
|
|
67
70
|
formaction="${this.makeActionURL(action_description, ...args)}"
|
|
68
71
|
title="${label}"
|
|
72
|
+
${disabled ? "disabled" : ""}
|
|
69
73
|
>
|
|
70
74
|
${content}
|
|
71
75
|
</button>
|
package/lib/templates/form.js
CHANGED
|
@@ -6,10 +6,8 @@ const defaults = {
|
|
|
6
6
|
import { Fields } from "@sealcode/sealgen";
|
|
7
7
|
import type {FormDataValue} from "@sealcode/sealgen";`,
|
|
8
8
|
fields: `
|
|
9
|
-
email: new Fields.CollectionField(true, Users.fields.email),
|
|
10
9
|
password: new Fields.SimpleFormField(true),`,
|
|
11
10
|
controls: `
|
|
12
|
-
new Controls.SimpleInput(fields.email, { label: "Email:", type: "email" }),
|
|
13
11
|
new Controls.SimpleInput(fields.password, {
|
|
14
12
|
label: "Password:",
|
|
15
13
|
type: "password",
|
|
@@ -26,12 +26,12 @@ export class ${toPascalCase(
|
|
|
26
26
|
content,
|
|
27
27
|
}: ExtractStructuredComponentArgumentsParsed<typeof component_arguments>,
|
|
28
28
|
classes: string[],
|
|
29
|
-
{ render_markdown }: JDDContext
|
|
29
|
+
{ language, render_markdown }: JDDContext
|
|
30
30
|
): FlatTemplatable {
|
|
31
31
|
return (
|
|
32
32
|
<div class={["${toKebabCase(component_name)}", ...classes]}>
|
|
33
33
|
<h2>{title} \u2022 ${toPascalCase(component_name)} </h2>
|
|
34
|
-
<div>{render_markdown(content)}</div>
|
|
34
|
+
<div>{render_markdown(language, content)}</div>
|
|
35
35
|
</div>
|
|
36
36
|
);
|
|
37
37
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
async function redirectTemplate(action_name) {
|
|
2
|
-
return `import { Context } from "koa";
|
|
2
|
+
return `import type { Context } from "koa";
|
|
3
3
|
import { Mountable } from "@sealcode/sealgen";
|
|
4
|
-
import Router from "@koa/router";
|
|
4
|
+
import type Router from "@koa/router";
|
|
5
5
|
|
|
6
6
|
export const actionName = "${action_name}";
|
|
7
7
|
|
|
@@ -70,7 +70,7 @@ async function createItemFormTemplate(create_action_name, newfilefullpath, colle
|
|
|
70
70
|
return html(
|
|
71
71
|
ctx,
|
|
72
72
|
"Create ${toKebabCase(collection_name)}",
|
|
73
|
-
tempstream/* HTML */ \` <div class="
|
|
73
|
+
tempstream/* HTML */ \` <div class="sealgen-crud-form">
|
|
74
74
|
<a class="" href="\${${list_action}URL}"
|
|
75
75
|
>\u2190 Back to ${collection_name} list</a
|
|
76
76
|
>
|
|
@@ -45,15 +45,20 @@ async function editItemFormTemplate(edit_action_name, newfilefullpath, collectio
|
|
|
45
45
|
return { canAccess: response?.allowed || false, message: response?.reason || "" };
|
|
46
46
|
};`,
|
|
47
47
|
onsubmit: `
|
|
48
|
-
|
|
48
|
+
async onSubmit(ctx: Context) {
|
|
49
49
|
const data = await this.getParsedValues(ctx);
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
const id = await this.getID(ctx);
|
|
51
|
+
const {items: [item]} = await ctx.$app.collections["${toKebabCase(
|
|
52
52
|
collection_name
|
|
53
53
|
)}"]
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
.list(ctx.$context)
|
|
55
|
+
.ids([id])
|
|
56
|
+
.fetch();
|
|
57
|
+
|
|
58
|
+
if (!item) {
|
|
59
|
+
throw new Error("Unknown id: " + id);
|
|
60
|
+
}
|
|
61
|
+
|
|
57
62
|
if (!data) {
|
|
58
63
|
throw new Error("Error when parsing the form values");
|
|
59
64
|
}
|
|
@@ -141,7 +146,7 @@ async function editItemFormTemplate(edit_action_name, newfilefullpath, collectio
|
|
|
141
146
|
return html(
|
|
142
147
|
ctx,
|
|
143
148
|
"Edit ${toPascalCase(collection_name)}",
|
|
144
|
-
tempstream/* HTML */ \` <div class="
|
|
149
|
+
tempstream/* HTML */ \` <div class="sealgen-crud-form">
|
|
145
150
|
<a class="" href="\${${list_action}URL}"
|
|
146
151
|
>\u2190 Back to ${collection_name} list</a
|
|
147
152
|
>
|
|
@@ -28,7 +28,7 @@ export default new (class ${delete_action_name}Redirect extends Mountable {
|
|
|
28
28
|
router.get(path, async (ctx) => {
|
|
29
29
|
await ctx.$app.collections["${toKebabCase(
|
|
30
30
|
collection_name
|
|
31
|
-
)}"].removeByID(ctx.$context, ctx.params.id);
|
|
31
|
+
)}"].removeByID(ctx.$context, ctx.params.id!);
|
|
32
32
|
ctx.status = 302;
|
|
33
33
|
ctx.redirect(${list_action_name}URL);
|
|
34
34
|
});
|
package/package.json
CHANGED
package/src/builder.ts
CHANGED
|
@@ -14,6 +14,7 @@ export type StatefulPageActionDescription<ActionName> =
|
|
|
14
14
|
action: ActionName;
|
|
15
15
|
label?: string;
|
|
16
16
|
content?: string;
|
|
17
|
+
disabled?: boolean;
|
|
17
18
|
}
|
|
18
19
|
| ActionName;
|
|
19
20
|
|
|
@@ -103,18 +104,21 @@ export abstract class StatefulPage<
|
|
|
103
104
|
|
|
104
105
|
extractActionAndLabel<ActionName extends keyof Actions>(
|
|
105
106
|
action_description: StatefulPageActionDescription<ActionName>
|
|
106
|
-
): { action: string; label: string; content: string } {
|
|
107
|
+
): { action: string; label: string; content: string; disabled: boolean } {
|
|
107
108
|
let label, action, content: string;
|
|
109
|
+
let disabled: boolean;
|
|
108
110
|
if (is(action_description, predicates.object)) {
|
|
109
111
|
action = action_description.action.toString();
|
|
110
112
|
label = action_description.label || action;
|
|
111
113
|
content = action_description.content || label;
|
|
114
|
+
disabled = action_description.disabled || false;
|
|
112
115
|
} else {
|
|
113
116
|
action = action_description.toString();
|
|
114
117
|
label = action;
|
|
115
118
|
content = label;
|
|
119
|
+
disabled = false;
|
|
116
120
|
}
|
|
117
|
-
return { action, label, content };
|
|
121
|
+
return { action, label, content, disabled };
|
|
118
122
|
}
|
|
119
123
|
|
|
120
124
|
makeActionURL<ActionName extends keyof Actions>(
|
|
@@ -137,13 +141,14 @@ export abstract class StatefulPage<
|
|
|
137
141
|
ExtractTail<ExtractTail<Parameters<Actions[ActionName]>>>
|
|
138
142
|
>
|
|
139
143
|
) {
|
|
140
|
-
const { label, content } =
|
|
144
|
+
const { label, content, disabled } =
|
|
141
145
|
this.extractActionAndLabel(action_description);
|
|
142
146
|
return /* HTML */ `
|
|
143
147
|
<button
|
|
144
148
|
type="submit"
|
|
145
149
|
formaction="${this.makeActionURL(action_description, ...args)}"
|
|
146
150
|
title="${label}"
|
|
151
|
+
${disabled ? "disabled" : ""}
|
|
147
152
|
>
|
|
148
153
|
${content}
|
|
149
154
|
</button>
|
package/src/templates/form.ts
CHANGED
|
@@ -7,10 +7,8 @@ const defaults = {
|
|
|
7
7
|
import { Fields } from "@sealcode/sealgen";
|
|
8
8
|
import type {FormDataValue} from "@sealcode/sealgen";`,
|
|
9
9
|
fields: `
|
|
10
|
-
email: new Fields.CollectionField(true, Users.fields.email),
|
|
11
10
|
password: new Fields.SimpleFormField(true),`,
|
|
12
11
|
controls: `
|
|
13
|
-
new Controls.SimpleInput(fields.email, { label: "Email:", type: "email" }),
|
|
14
12
|
new Controls.SimpleInput(fields.password, {
|
|
15
13
|
label: "Password:",
|
|
16
14
|
type: "password",
|
|
@@ -27,12 +27,12 @@ export class ${toPascalCase(
|
|
|
27
27
|
content,
|
|
28
28
|
}: ExtractStructuredComponentArgumentsParsed<typeof component_arguments>,
|
|
29
29
|
classes: string[],
|
|
30
|
-
{ render_markdown }: JDDContext
|
|
30
|
+
{ language, render_markdown }: JDDContext
|
|
31
31
|
): FlatTemplatable {
|
|
32
32
|
return (
|
|
33
33
|
<div class={["${toKebabCase(component_name)}", ...classes]}>
|
|
34
34
|
<h2>{title} • ${toPascalCase(component_name)} </h2>
|
|
35
|
-
<div>{render_markdown(content)}</div>
|
|
35
|
+
<div>{render_markdown(language, content)}</div>
|
|
36
36
|
</div>
|
|
37
37
|
);
|
|
38
38
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export async function redirectTemplate(action_name: string): Promise<string> {
|
|
2
|
-
return `import { Context } from "koa";
|
|
2
|
+
return `import type { Context } from "koa";
|
|
3
3
|
import { Mountable } from "@sealcode/sealgen";
|
|
4
|
-
import Router from "@koa/router";
|
|
4
|
+
import type Router from "@koa/router";
|
|
5
5
|
|
|
6
6
|
export const actionName = "${action_name}";
|
|
7
7
|
|
|
@@ -109,7 +109,7 @@ export async function createItemFormTemplate(
|
|
|
109
109
|
return html(
|
|
110
110
|
ctx,
|
|
111
111
|
"Create ${toKebabCase(collection_name)}",
|
|
112
|
-
tempstream/* HTML */ \` <div class="
|
|
112
|
+
tempstream/* HTML */ \` <div class="sealgen-crud-form">
|
|
113
113
|
<a class="" href="\${${list_action}URL}"
|
|
114
114
|
>← Back to ${collection_name} list</a
|
|
115
115
|
>
|
|
@@ -63,15 +63,20 @@ export async function editItemFormTemplate(
|
|
|
63
63
|
};`,
|
|
64
64
|
|
|
65
65
|
onsubmit: `
|
|
66
|
-
|
|
66
|
+
async onSubmit(ctx: Context) {
|
|
67
67
|
const data = await this.getParsedValues(ctx);
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
const id = await this.getID(ctx);
|
|
69
|
+
const {items: [item]} = await ctx.$app.collections["${toKebabCase(
|
|
70
70
|
collection_name
|
|
71
71
|
)}"]
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
.list(ctx.$context)
|
|
73
|
+
.ids([id])
|
|
74
|
+
.fetch();
|
|
75
|
+
|
|
76
|
+
if (!item) {
|
|
77
|
+
throw new Error("Unknown id: " + id);
|
|
78
|
+
}
|
|
79
|
+
|
|
75
80
|
if (!data) {
|
|
76
81
|
throw new Error("Error when parsing the form values");
|
|
77
82
|
}
|
|
@@ -184,7 +189,7 @@ export async function editItemFormTemplate(
|
|
|
184
189
|
return html(
|
|
185
190
|
ctx,
|
|
186
191
|
"Edit ${toPascalCase(collection_name)}",
|
|
187
|
-
tempstream/* HTML */ \` <div class="
|
|
192
|
+
tempstream/* HTML */ \` <div class="sealgen-crud-form">
|
|
188
193
|
<a class="" href="\${${list_action}URL}"
|
|
189
194
|
>← Back to ${collection_name} list</a
|
|
190
195
|
>
|
|
@@ -34,7 +34,7 @@ export default new (class ${delete_action_name}Redirect extends Mountable {
|
|
|
34
34
|
router.get(path, async (ctx) => {
|
|
35
35
|
await ctx.$app.collections["${toKebabCase(
|
|
36
36
|
collection_name
|
|
37
|
-
)}"].removeByID(ctx.$context, ctx.params.id);
|
|
37
|
+
)}"].removeByID(ctx.$context, ctx.params.id!);
|
|
38
38
|
ctx.status = 302;
|
|
39
39
|
ctx.redirect(${list_action_name}URL);
|
|
40
40
|
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|