@sealcode/sealgen 0.8.11 → 0.8.13
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/forms/controls/controls.d.ts +1 -0
- package/@types/forms/controls/file.d.ts +8 -7
- package/@types/forms/controls/photo.d.ts +20 -0
- package/lib/forms/controls/controls.js +1 -0
- package/lib/forms/controls/controls.js.map +1 -1
- package/lib/forms/controls/file.js +7 -4
- package/lib/forms/controls/file.js.map +1 -1
- package/lib/forms/controls/photo.js +56 -0
- package/lib/forms/controls/photo.js.map +1 -0
- package/package.json +2 -1
- package/src/forms/controls/controls.ts +1 -0
- package/src/forms/controls/file.ts +12 -6
- package/src/forms/controls/photo.ts +76 -0
- package/src/forms/controls/#simple-input.ts# +0 -172
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import { Context } from "koa";
|
|
3
|
+
import { FlatTemplatable } from "tempstream";
|
|
2
4
|
import { FileContainer } from "../fields/file";
|
|
3
5
|
import { FormDataValue } from "../form";
|
|
4
6
|
import { SimpleInput } from "./simple-input";
|
|
5
7
|
export declare class File extends SimpleInput<FileContainer> {
|
|
6
8
|
getType(): string;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}>;
|
|
9
|
+
renderFilePreview(ctx: Context, file_data: {
|
|
10
|
+
id?: string;
|
|
11
|
+
filename?: string;
|
|
12
|
+
}): Promise<FlatTemplatable>;
|
|
13
|
+
preInput(ctx: Context, data: Record<string, FormDataValue>): Promise<import("stream").Readable>;
|
|
14
|
+
getInputAttributes(ctx: Context, data: Record<string, FormDataValue>, field_prefix: string, form_id: string): Promise<Record<string, string | boolean>>;
|
|
14
15
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Context } from "koa";
|
|
2
|
+
import { FlatTemplatable } from "tempstream";
|
|
3
|
+
import { File } from "./file";
|
|
4
|
+
import { FileContainer, FormField } from "../fields/field";
|
|
5
|
+
import { SimpleInputOptions } from "./simple-input";
|
|
6
|
+
import KoaResponsiveImageRouter from "koa-responsive-image-router";
|
|
7
|
+
import { FormDataValue } from "../form";
|
|
8
|
+
export declare class Photo extends File {
|
|
9
|
+
field: FormField<boolean, FileContainer>;
|
|
10
|
+
imageRouter: KoaResponsiveImageRouter;
|
|
11
|
+
constructor(field: FormField<boolean, FileContainer>, imageRouter: KoaResponsiveImageRouter, options?: SimpleInputOptions);
|
|
12
|
+
getImgStyle(): Promise<string>;
|
|
13
|
+
renderFilePreview(ctx: Context, file_data: {
|
|
14
|
+
id?: string;
|
|
15
|
+
filename?: string;
|
|
16
|
+
}): Promise<FlatTemplatable>;
|
|
17
|
+
getInputAttributes(ctx: Context, data: Record<string, FormDataValue>, field_prefix: string, form_id: string): Promise<{
|
|
18
|
+
onchange: string;
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
@@ -47,6 +47,7 @@ __exportStar(require("./collapsible-field-group"), exports);
|
|
|
47
47
|
__exportStar(require("./collapsible-checkbox-group"), exports);
|
|
48
48
|
__exportStar(require("./autocomplete"), exports);
|
|
49
49
|
__exportStar(require("./file"), exports);
|
|
50
|
+
__exportStar(require("./photo"), exports);
|
|
50
51
|
__exportStar(require("./multiple-files"), exports);
|
|
51
52
|
__exportStar(require("./number"), exports);
|
|
52
53
|
//# sourceMappingURL=controls.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controls.js","sourceRoot":"","sources":["../../../src/forms/controls/controls.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,2DAAwD;AAA/C,sHAAA,gBAAgB,OAAA;AACzB,2EAAwE;AAA/D,sIAAA,wBAAwB,OAAA;AACjC,iCAAgC;AAAvB,8FAAA,KAAK,OAAA;AACd,iEAA8D;AAArD,4HAAA,mBAAmB,OAAA;AAC5B,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA;AACjB,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,6CAA2C;AAAlC,yGAAA,UAAU,OAAA;AACnB,mDAAiD;AAAxC,+GAAA,aAAa,OAAA;AACtB,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AACb,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA;AACjB,6CAA2C;AAAlC,yGAAA,UAAU,OAAA;AACnB,4CAA0B;AAC1B,6CAA2B;AAC3B,6CAA2B;AAC3B,0CAAwB;AACxB,oDAAkC;AAClC,mDAAiC;AACjC,4DAA0C;AAC1C,+DAA6C;AAC7C,iDAA+B;AAC/B,yCAAuB;AACvB,mDAAiC;AACjC,2CAAyB"}
|
|
1
|
+
{"version":3,"file":"controls.js","sourceRoot":"","sources":["../../../src/forms/controls/controls.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,2DAAwD;AAA/C,sHAAA,gBAAgB,OAAA;AACzB,2EAAwE;AAA/D,sIAAA,wBAAwB,OAAA;AACjC,iCAAgC;AAAvB,8FAAA,KAAK,OAAA;AACd,iEAA8D;AAArD,4HAAA,mBAAmB,OAAA;AAC5B,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA;AACjB,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,6CAA2C;AAAlC,yGAAA,UAAU,OAAA;AACnB,mDAAiD;AAAxC,+GAAA,aAAa,OAAA;AACtB,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AACb,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA;AACjB,6CAA2C;AAAlC,yGAAA,UAAU,OAAA;AACnB,4CAA0B;AAC1B,6CAA2B;AAC3B,6CAA2B;AAC3B,0CAAwB;AACxB,oDAAkC;AAClC,mDAAiC;AACjC,4DAA0C;AAC1C,+DAA6C;AAC7C,iDAA+B;AAC/B,yCAAuB;AACvB,0CAAwB;AACxB,mDAAiC;AACjC,2CAAyB"}
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.File = void 0;
|
|
4
|
+
const tempstream_1 = require("tempstream");
|
|
4
5
|
const simple_input_1 = require("./simple-input");
|
|
5
6
|
class File extends simple_input_1.SimpleInput {
|
|
6
7
|
getType() {
|
|
7
8
|
return "file";
|
|
8
9
|
}
|
|
10
|
+
async renderFilePreview(ctx, file_data) {
|
|
11
|
+
return file_data.filename || "";
|
|
12
|
+
}
|
|
9
13
|
async preInput(ctx, data) {
|
|
10
14
|
const { parsed } = await this.field.getValue(ctx, data);
|
|
11
|
-
return /* HTML */
|
|
15
|
+
return tempstream_1.tempstream /* HTML */ `${parsed.old
|
|
16
|
+
? this.renderFilePreview(ctx, parsed.old)
|
|
17
|
+
: ""}
|
|
12
18
|
<input
|
|
13
19
|
type="hidden"
|
|
14
20
|
name="${this.field.name}[old][id]"
|
|
@@ -28,9 +34,6 @@ class File extends simple_input_1.SimpleInput {
|
|
|
28
34
|
name: this.field.name + "[new]",
|
|
29
35
|
required: original.required && !parsed.old,
|
|
30
36
|
value: false,
|
|
31
|
-
onchange: (original.onchange || "") +
|
|
32
|
-
";" +
|
|
33
|
-
"filename = this.value.split('\\\\').slice(-1)[0]; this.parentElement.style.setProperty('--filename', '\\'Wybrany plik: ' + filename + '\\'')",
|
|
34
37
|
};
|
|
35
38
|
}
|
|
36
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../../src/forms/controls/file.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../../src/forms/controls/file.ts"],"names":[],"mappings":";;;AACA,2CAAyD;AAGzD,iDAA6C;AAE7C,MAAa,IAAK,SAAQ,0BAA0B;IACnD,OAAO;QACN,OAAO,MAAM,CAAC;IACf,CAAC;IAED,KAAK,CAAC,iBAAiB,CACtB,GAAY,EACZ,SAA6C;QAE7C,OAAO,SAAS,CAAC,QAAQ,IAAI,EAAE,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,GAAY,EAAE,IAAmC;QAC/D,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACxD,OAAO,uBAAU,CAAA,UAAU,CAAC,GAAG,MAAM,CAAC,GAAG;YACvC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC;YACzC,CAAC,CAAC,EAAE;;;YAGI,IAAI,CAAC,KAAK,CAAC,IAAI;aACd,MAAM,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE;;;;YAIrB,IAAI,CAAC,KAAK,CAAC,IAAI;aACd,MAAM,CAAC,GAAG,EAAE,QAAQ,IAAI,EAAE;MACjC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,kBAAkB,CACvB,GAAY,EACZ,IAAmC,EACnC,YAAoB,EACpB,OAAe;QAEf,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,kBAAkB,CAC9C,GAAG,EACH,IAAI,EACJ,YAAY,EACZ,OAAO,CACP,CAAC;QACF,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACxD,OAAO;YACN,GAAG,QAAQ;YACX,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,OAAO;YAC/B,QAAQ,EAAE,QAAQ,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,GAAG;YAC1C,KAAK,EAAE,KAAK;SACZ,CAAC;IACH,CAAC;CACD;AAjDD,oBAiDC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Photo = void 0;
|
|
4
|
+
const tempstream_1 = require("tempstream");
|
|
5
|
+
const file_1 = require("./file");
|
|
6
|
+
const sealious_1 = require("sealious");
|
|
7
|
+
class Photo extends file_1.File {
|
|
8
|
+
constructor(field, imageRouter, options) {
|
|
9
|
+
super(field, options);
|
|
10
|
+
this.field = field;
|
|
11
|
+
this.imageRouter = imageRouter;
|
|
12
|
+
}
|
|
13
|
+
async getImgStyle() {
|
|
14
|
+
return "width: 100px; height: 100px; object-fit: contain";
|
|
15
|
+
}
|
|
16
|
+
async renderFilePreview(ctx, file_data) {
|
|
17
|
+
const { id, filename } = file_data;
|
|
18
|
+
const class_name = "file_preview";
|
|
19
|
+
if (!id) {
|
|
20
|
+
return `<div class="${class_name}"></div>`;
|
|
21
|
+
}
|
|
22
|
+
const file = await sealious_1.File.fromID(ctx.$app, id);
|
|
23
|
+
return tempstream_1.tempstream /* HTML */ `<div class="${class_name}">
|
|
24
|
+
${this.imageRouter.image({
|
|
25
|
+
resolutions: [100],
|
|
26
|
+
sizes_attr: "100px",
|
|
27
|
+
path: file.getDataPath(),
|
|
28
|
+
img_style: await this.getImgStyle(),
|
|
29
|
+
})}
|
|
30
|
+
</div>`;
|
|
31
|
+
}
|
|
32
|
+
async getInputAttributes(ctx, data, field_prefix, form_id) {
|
|
33
|
+
const original = (await super.getInputAttributes(ctx, data, field_prefix, form_id));
|
|
34
|
+
const { parsed } = await this.field.getValue(ctx, data);
|
|
35
|
+
return {
|
|
36
|
+
...original,
|
|
37
|
+
onchange: (original.onchange || "") +
|
|
38
|
+
";" +
|
|
39
|
+
`
|
|
40
|
+
const file = this.files[0];
|
|
41
|
+
const preview_container = this.parentElement.querySelector(".file_preview");
|
|
42
|
+
const target = this;
|
|
43
|
+
if (file) {
|
|
44
|
+
const fileReader = new FileReader();
|
|
45
|
+
fileReader.readAsDataURL(file);
|
|
46
|
+
fileReader.addEventListener("load", function () {
|
|
47
|
+
preview_container.innerHTML = \`<img src="\${this.result}" style="${await this.getImgStyle()}" />\`;
|
|
48
|
+
});
|
|
49
|
+
}`
|
|
50
|
+
.replaceAll("\n", " ")
|
|
51
|
+
.replaceAll(`"`, "'"),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.Photo = Photo;
|
|
56
|
+
//# sourceMappingURL=photo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"photo.js","sourceRoot":"","sources":["../../../src/forms/controls/photo.ts"],"names":[],"mappings":";;;AACA,2CAAyD;AACzD,iCAA8B;AAC9B,uCAAgD;AAMhD,MAAa,KAAM,SAAQ,WAAI;IAC9B,YACQ,KAAwC,EACxC,WAAqC,EAC5C,OAA4B;QAE5B,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAJf,UAAK,GAAL,KAAK,CAAmC;QACxC,gBAAW,GAAX,WAAW,CAA0B;IAI7C,CAAC;IAED,KAAK,CAAC,WAAW;QAChB,OAAO,kDAAkD,CAAC;IAC3D,CAAC;IAED,KAAK,CAAC,iBAAiB,CACtB,GAAY,EACZ,SAA6C;QAE7C,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC;QACnC,MAAM,UAAU,GAAG,cAAc,CAAC;QAClC,IAAI,CAAC,EAAE,EAAE;YACR,OAAO,eAAe,UAAU,UAAU,CAAC;SAC3C;QACD,MAAM,IAAI,GAAG,MAAM,eAAY,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACrD,OAAO,uBAAU,CAAA,UAAU,CAAC,eAAe,UAAU;KAClD,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;YACxB,WAAW,EAAE,CAAC,GAAG,CAAC;YAClB,UAAU,EAAE,OAAO;YACnB,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE;YACxB,SAAS,EAAE,MAAM,IAAI,CAAC,WAAW,EAAE;SACnC,CAAC;SACI,CAAC;IACT,CAAC;IAED,KAAK,CAAC,kBAAkB,CACvB,GAAY,EACZ,IAAmC,EACnC,YAAoB,EACpB,OAAe;QAEf,MAAM,QAAQ,GAAG,CAAC,MAAM,KAAK,CAAC,kBAAkB,CAC/C,GAAG,EACH,IAAI,EACJ,YAAY,EACZ,OAAO,CACP,CAAqC,CAAC;QACvC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACxD,OAAO;YACN,GAAG,QAAQ;YACX,QAAQ,EACP,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC;gBACzB,GAAG;gBACH;;;;;;;;4EAQwE,MAAM,IAAI,CAAC,WAAW,EAAE;;EAElG;qBACI,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC;qBACrB,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC;SACvB,CAAC;IACH,CAAC;CACD;AAlED,sBAkEC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sealcode/sealgen",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.13",
|
|
4
4
|
"description": "Module to automate adding routes and collections to a sealious application",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"peerDependencies": {
|
|
53
53
|
"@koa/router": "^10.1.1",
|
|
54
54
|
"koa": "^2.13.0",
|
|
55
|
+
"koa-responsive-image-router": "^0.2.2",
|
|
55
56
|
"sealious": "^0.17.9"
|
|
56
57
|
}
|
|
57
58
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Context } from "koa";
|
|
2
|
+
import { FlatTemplatable, tempstream } from "tempstream";
|
|
2
3
|
import { FileContainer } from "../fields/file";
|
|
3
4
|
import { FormDataValue } from "../form";
|
|
4
5
|
import { SimpleInput } from "./simple-input";
|
|
@@ -8,9 +9,18 @@ export class File extends SimpleInput<FileContainer> {
|
|
|
8
9
|
return "file";
|
|
9
10
|
}
|
|
10
11
|
|
|
12
|
+
async renderFilePreview(
|
|
13
|
+
ctx: Context,
|
|
14
|
+
file_data: { id?: string; filename?: string }
|
|
15
|
+
): Promise<FlatTemplatable> {
|
|
16
|
+
return file_data.filename || "";
|
|
17
|
+
}
|
|
18
|
+
|
|
11
19
|
async preInput(ctx: Context, data: Record<string, FormDataValue>) {
|
|
12
20
|
const { parsed } = await this.field.getValue(ctx, data);
|
|
13
|
-
return /* HTML */
|
|
21
|
+
return tempstream/* HTML */ `${parsed.old
|
|
22
|
+
? this.renderFilePreview(ctx, parsed.old)
|
|
23
|
+
: ""}
|
|
14
24
|
<input
|
|
15
25
|
type="hidden"
|
|
16
26
|
name="${this.field.name}[old][id]"
|
|
@@ -28,7 +38,7 @@ export class File extends SimpleInput<FileContainer> {
|
|
|
28
38
|
data: Record<string, FormDataValue>,
|
|
29
39
|
field_prefix: string,
|
|
30
40
|
form_id: string
|
|
31
|
-
) {
|
|
41
|
+
): Promise<Record<string, string | boolean>> {
|
|
32
42
|
const original = await super.getInputAttributes(
|
|
33
43
|
ctx,
|
|
34
44
|
data,
|
|
@@ -41,10 +51,6 @@ export class File extends SimpleInput<FileContainer> {
|
|
|
41
51
|
name: this.field.name + "[new]",
|
|
42
52
|
required: original.required && !parsed.old,
|
|
43
53
|
value: false,
|
|
44
|
-
onchange:
|
|
45
|
-
(original.onchange || "") +
|
|
46
|
-
";" +
|
|
47
|
-
"filename = this.value.split('\\\\').slice(-1)[0]; this.parentElement.style.setProperty('--filename', '\\'Wybrany plik: ' + filename + '\\'')",
|
|
48
54
|
};
|
|
49
55
|
}
|
|
50
56
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Context } from "koa";
|
|
2
|
+
import { FlatTemplatable, tempstream } from "tempstream";
|
|
3
|
+
import { File } from "./file";
|
|
4
|
+
import { File as SealiousFile } from "sealious";
|
|
5
|
+
import { FileContainer, FormField } from "../fields/field";
|
|
6
|
+
import { SimpleInputOptions } from "./simple-input";
|
|
7
|
+
import KoaResponsiveImageRouter from "koa-responsive-image-router";
|
|
8
|
+
import { FormDataValue } from "../form";
|
|
9
|
+
|
|
10
|
+
export class Photo extends File {
|
|
11
|
+
constructor(
|
|
12
|
+
public field: FormField<boolean, FileContainer>,
|
|
13
|
+
public imageRouter: KoaResponsiveImageRouter,
|
|
14
|
+
options?: SimpleInputOptions
|
|
15
|
+
) {
|
|
16
|
+
super(field, options);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async getImgStyle() {
|
|
20
|
+
return "width: 100px; height: 100px; object-fit: contain";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async renderFilePreview(
|
|
24
|
+
ctx: Context,
|
|
25
|
+
file_data: { id?: string; filename?: string }
|
|
26
|
+
): Promise<FlatTemplatable> {
|
|
27
|
+
const { id, filename } = file_data;
|
|
28
|
+
const class_name = "file_preview";
|
|
29
|
+
if (!id) {
|
|
30
|
+
return `<div class="${class_name}"></div>`;
|
|
31
|
+
}
|
|
32
|
+
const file = await SealiousFile.fromID(ctx.$app, id);
|
|
33
|
+
return tempstream/* HTML */ `<div class="${class_name}">
|
|
34
|
+
${this.imageRouter.image({
|
|
35
|
+
resolutions: [100],
|
|
36
|
+
sizes_attr: "100px",
|
|
37
|
+
path: file.getDataPath(),
|
|
38
|
+
img_style: await this.getImgStyle(),
|
|
39
|
+
})}
|
|
40
|
+
</div>`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async getInputAttributes(
|
|
44
|
+
ctx: Context,
|
|
45
|
+
data: Record<string, FormDataValue>,
|
|
46
|
+
field_prefix: string,
|
|
47
|
+
form_id: string
|
|
48
|
+
) {
|
|
49
|
+
const original = (await super.getInputAttributes(
|
|
50
|
+
ctx,
|
|
51
|
+
data,
|
|
52
|
+
field_prefix,
|
|
53
|
+
form_id
|
|
54
|
+
)) as Record<string, string | boolean>;
|
|
55
|
+
const { parsed } = await this.field.getValue(ctx, data);
|
|
56
|
+
return {
|
|
57
|
+
...original,
|
|
58
|
+
onchange:
|
|
59
|
+
(original.onchange || "") +
|
|
60
|
+
";" +
|
|
61
|
+
`
|
|
62
|
+
const file = this.files[0];
|
|
63
|
+
const preview_container = this.parentElement.querySelector(".file_preview");
|
|
64
|
+
const target = this;
|
|
65
|
+
if (file) {
|
|
66
|
+
const fileReader = new FileReader();
|
|
67
|
+
fileReader.readAsDataURL(file);
|
|
68
|
+
fileReader.addEventListener("load", function () {
|
|
69
|
+
preview_container.innerHTML = \`<img src="\${this.result}" style="${await this.getImgStyle()}" />\`;
|
|
70
|
+
});
|
|
71
|
+
}`
|
|
72
|
+
.replaceAll("\n", " ")
|
|
73
|
+
.replaceAll(`"`, "'"),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import { Context } from "koa";
|
|
2
|
-
import { FlatTemplatable, tempstream } from "tempstream";
|
|
3
|
-
import { attribute } from "../../sanitize";
|
|
4
|
-
import { getRequiredClass, inputWrapper } from "../../utils/input-wrapper";
|
|
5
|
-
import { FormField } from "../fields/field";
|
|
6
|
-
import { FormDataValue, FormMessage } from "../form";
|
|
7
|
-
import { FormFieldControl } from "./controls";
|
|
8
|
-
|
|
9
|
-
export type SimpleInputOptions = {
|
|
10
|
-
id?: string;
|
|
11
|
-
label?: string;
|
|
12
|
-
autocomplete?: boolean;
|
|
13
|
-
hide_errors?: boolean;
|
|
14
|
-
type?:
|
|
15
|
-
| "color"
|
|
16
|
-
| "date"
|
|
17
|
-
| "email"
|
|
18
|
-
| "file"
|
|
19
|
-
| "month"
|
|
20
|
-
| "number"
|
|
21
|
-
| "password"
|
|
22
|
-
| "search"
|
|
23
|
-
| "tel"
|
|
24
|
-
| "text"
|
|
25
|
-
| "time"
|
|
26
|
-
| "url"
|
|
27
|
-
| "week";
|
|
28
|
-
value?: string;
|
|
29
|
-
placeholder?: string;
|
|
30
|
-
readonly?: boolean;
|
|
31
|
-
step?: number;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export class SimpleInput<
|
|
35
|
-
ParsedValue,
|
|
36
|
-
Options extends SimpleInputOptions = SimpleInputOptions
|
|
37
|
-
> extends FormFieldControl {
|
|
38
|
-
options: SimpleInputOptions;
|
|
39
|
-
constructor(
|
|
40
|
-
public field: FormField<boolean, ParsedValue>,
|
|
41
|
-
options?: Options
|
|
42
|
-
) {
|
|
43
|
-
super([field]);
|
|
44
|
-
this.options = options || {};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async preInput(
|
|
48
|
-
_ctx: Context,
|
|
49
|
-
_data: Record<string, FormDataValue>
|
|
50
|
-
): Promise<FlatTemplatable> {
|
|
51
|
-
return "";
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
getType(): string {
|
|
55
|
-
return this.options.type || "text";
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
getLabel(): string {
|
|
59
|
-
return this.options.label != undefined
|
|
60
|
-
? this.options.label
|
|
61
|
-
: this.field.name;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
getID(): string {
|
|
65
|
-
return this.options.id || this.field.name;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
getPlaceholder(): string {
|
|
69
|
-
return (!this.options.placeholder )|| this.getType();
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async getInputAttributes(
|
|
73
|
-
ctx: Context,
|
|
74
|
-
data: Record<string, FormDataValue>,
|
|
75
|
-
field_prefix: string,
|
|
76
|
-
form_id: string
|
|
77
|
-
): Promise<Record<string, string | boolean>> {
|
|
78
|
-
const readonly = this.options.readonly || false;
|
|
79
|
-
const required = this.field.required;
|
|
80
|
-
const { parsed, raw, valid } = await this.field.getValue(ctx, data);
|
|
81
|
-
return Object.fromEntries([
|
|
82
|
-
<const>["id", this.getID()],
|
|
83
|
-
<const>["type", this.getType()],
|
|
84
|
-
<const>["name", `${field_prefix}${this.field.name}`],
|
|
85
|
-
<const>[
|
|
86
|
-
"value",
|
|
87
|
-
!valid && raw
|
|
88
|
-
? raw.toString()
|
|
89
|
-
: parsed !== undefined && parsed !== null
|
|
90
|
-
? ((parsed as any)?.toString() as string) || ""
|
|
91
|
-
: "",
|
|
92
|
-
],
|
|
93
|
-
...(form_id ? [["form", form_id]] : []),
|
|
94
|
-
<const>["placeholder", this.getPlaceholder()],
|
|
95
|
-
...(readonly ? [["readonly", true]] : []),
|
|
96
|
-
...(required ? [["required", true]] : []),
|
|
97
|
-
...(!this.options.autocomplete ? [["autocomplete", "off"]] : []),
|
|
98
|
-
...(this.options.step ? [["step", this.options.step]] : []),
|
|
99
|
-
]);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
renderAttributes(attrs: Record<string, string | boolean>) {
|
|
103
|
-
return Object.entries(attrs)
|
|
104
|
-
.map(([key, value]) => {
|
|
105
|
-
if (typeof value === "boolean") {
|
|
106
|
-
if (value) {
|
|
107
|
-
return key;
|
|
108
|
-
} else {
|
|
109
|
-
return "";
|
|
110
|
-
}
|
|
111
|
-
} else {
|
|
112
|
-
return `${key}="${attribute(value)}"`;
|
|
113
|
-
}
|
|
114
|
-
})
|
|
115
|
-
.join(" ");
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
async postInput(ctx: Context): Promise<FlatTemplatable> {
|
|
119
|
-
return "";
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
async renderInput(
|
|
123
|
-
ctx: Context,
|
|
124
|
-
attributes_str: string,
|
|
125
|
-
data: Record<string, FormDataValue>
|
|
126
|
-
): Promise<FlatTemplatable> {
|
|
127
|
-
return `<input ${attributes_str} />`;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
async render<Fields extends Record<string, FormField>>(
|
|
131
|
-
ctx: Context,
|
|
132
|
-
data: Record<string, FormDataValue>,
|
|
133
|
-
_messages: FormMessage[],
|
|
134
|
-
field_prefix: string,
|
|
135
|
-
form_id: string,
|
|
136
|
-
show_errors: boolean
|
|
137
|
-
): Promise<FlatTemplatable> {
|
|
138
|
-
const id = this.getID();
|
|
139
|
-
const label = this.getLabel();
|
|
140
|
-
const type = this.getType();
|
|
141
|
-
|
|
142
|
-
const { parsed, raw, valid, message } = await this.field.getValue(
|
|
143
|
-
ctx,
|
|
144
|
-
data
|
|
145
|
-
);
|
|
146
|
-
const placeholder = this.getPlaceholder();
|
|
147
|
-
|
|
148
|
-
return inputWrapper(
|
|
149
|
-
[id, type, getRequiredClass(this.field.required)],
|
|
150
|
-
tempstream/* HTML */ `
|
|
151
|
-
${label ? `<label for="${id}">${label}</label>` : ""}
|
|
152
|
-
${await this.preInput(ctx, data)}
|
|
153
|
-
${this.renderInput(
|
|
154
|
-
ctx,
|
|
155
|
-
this.renderAttributes(
|
|
156
|
-
await this.getInputAttributes(
|
|
157
|
-
ctx,
|
|
158
|
-
data,
|
|
159
|
-
field_prefix,
|
|
160
|
-
form_id
|
|
161
|
-
)
|
|
162
|
-
),
|
|
163
|
-
data
|
|
164
|
-
)}
|
|
165
|
-
${this.postInput(ctx)}
|
|
166
|
-
${~valid && !this.options.hide_errors && show_errors
|
|
167
|
-
? `<div class="input__error">${message}</div>`
|
|
168
|
-
: ""}
|
|
169
|
-
`
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
}
|