@solar-angular/ui-zorro 1.0.0
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/README.md +7 -0
- package/crud/editor-drawer/editor-drawer.component.d.ts +9 -0
- package/crud/editor-drawer/index.d.ts +1 -0
- package/crud/editor.d.ts +35 -0
- package/crud/index.d.ts +4 -0
- package/crud/page.d.ts +52 -0
- package/crud/searcher.d.ts +8 -0
- package/esm2022/crud/editor-drawer/editor-drawer.component.mjs +34 -0
- package/esm2022/crud/editor-drawer/index.mjs +2 -0
- package/esm2022/crud/editor.mjs +65 -0
- package/esm2022/crud/index.mjs +5 -0
- package/esm2022/crud/page.mjs +69 -0
- package/esm2022/crud/searcher.mjs +9 -0
- package/esm2022/crud/solar-angular-ui-zorro-crud.mjs +5 -0
- package/esm2022/fluent-form/components.mjs +15 -0
- package/esm2022/fluent-form/controls.mjs +104 -0
- package/esm2022/fluent-form/form.mjs +15 -0
- package/esm2022/fluent-form/index.mjs +5 -0
- package/esm2022/fluent-form/patchers.mjs +57 -0
- package/esm2022/fluent-form/solar-angular-ui-zorro-fluent-form.mjs +5 -0
- package/esm2022/fluent-form/typing.mjs +2 -0
- package/esm2022/index.mjs +2 -0
- package/esm2022/media-uploader/index.mjs +2 -0
- package/esm2022/media-uploader/media-uploader.component.mjs +175 -0
- package/esm2022/media-uploader/solar-angular-ui-zorro-media-uploader.mjs +5 -0
- package/esm2022/message/index.mjs +2 -0
- package/esm2022/message/message.service.mjs +36 -0
- package/esm2022/message/solar-angular-ui-zorro-message.mjs +5 -0
- package/esm2022/page-forbidden/forbidden.page.mjs +25 -0
- package/esm2022/page-forbidden/index.mjs +4 -0
- package/esm2022/page-forbidden/solar-angular-ui-zorro-page-forbidden.mjs +5 -0
- package/esm2022/page-logout/index.mjs +4 -0
- package/esm2022/page-logout/logout.page.mjs +36 -0
- package/esm2022/page-logout/solar-angular-ui-zorro-page-logout.mjs +5 -0
- package/esm2022/page-not-found/index.mjs +4 -0
- package/esm2022/page-not-found/not-found.page.mjs +25 -0
- package/esm2022/page-not-found/solar-angular-ui-zorro-page-not-found.mjs +5 -0
- package/esm2022/solar-angular-ui-zorro.mjs +5 -0
- package/esm2022/updater/app-updater.mjs +27 -0
- package/esm2022/updater/index.mjs +3 -0
- package/esm2022/updater/solar-angular-ui-zorro-updater.mjs +5 -0
- package/esm2022/updater/updater.component.mjs +71 -0
- package/fesm2022/solar-angular-ui-zorro-crud.mjs +180 -0
- package/fesm2022/solar-angular-ui-zorro-crud.mjs.map +1 -0
- package/fesm2022/solar-angular-ui-zorro-fluent-form.mjs +196 -0
- package/fesm2022/solar-angular-ui-zorro-fluent-form.mjs.map +1 -0
- package/fesm2022/solar-angular-ui-zorro-media-uploader.mjs +182 -0
- package/fesm2022/solar-angular-ui-zorro-media-uploader.mjs.map +1 -0
- package/fesm2022/solar-angular-ui-zorro-message.mjs +43 -0
- package/fesm2022/solar-angular-ui-zorro-message.mjs.map +1 -0
- package/fesm2022/solar-angular-ui-zorro-page-forbidden.mjs +32 -0
- package/fesm2022/solar-angular-ui-zorro-page-forbidden.mjs.map +1 -0
- package/fesm2022/solar-angular-ui-zorro-page-logout.mjs +43 -0
- package/fesm2022/solar-angular-ui-zorro-page-logout.mjs.map +1 -0
- package/fesm2022/solar-angular-ui-zorro-page-not-found.mjs +32 -0
- package/fesm2022/solar-angular-ui-zorro-page-not-found.mjs.map +1 -0
- package/fesm2022/solar-angular-ui-zorro-updater.mjs +102 -0
- package/fesm2022/solar-angular-ui-zorro-updater.mjs.map +1 -0
- package/fesm2022/solar-angular-ui-zorro.mjs +6 -0
- package/fesm2022/solar-angular-ui-zorro.mjs.map +1 -0
- package/fluent-form/components.d.ts +6 -0
- package/fluent-form/controls.d.ts +45 -0
- package/fluent-form/form.d.ts +8 -0
- package/fluent-form/index.d.ts +4 -0
- package/fluent-form/patchers.d.ts +10 -0
- package/fluent-form/typing.d.ts +1 -0
- package/index.d.ts +2 -0
- package/media-uploader/index.d.ts +1 -0
- package/media-uploader/media-uploader.component.d.ts +53 -0
- package/message/index.d.ts +1 -0
- package/message/message.service.d.ts +13 -0
- package/package.json +85 -0
- package/page-forbidden/forbidden.page.d.ts +5 -0
- package/page-forbidden/index.d.ts +3 -0
- package/page-logout/index.d.ts +3 -0
- package/page-logout/logout.page.d.ts +10 -0
- package/page-not-found/index.d.ts +3 -0
- package/page-not-found/not-found.page.d.ts +5 -0
- package/updater/app-updater.d.ts +10 -0
- package/updater/index.d.ts +2 -0
- package/updater/updater.component.d.ts +14 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { form } from '@fluent-form/core';
|
|
2
|
+
import { finalize, tap, shareReplay } from 'rxjs';
|
|
3
|
+
import * as i0 from '@angular/core';
|
|
4
|
+
import { Component, Input, inject } from '@angular/core';
|
|
5
|
+
import * as i1 from 'ng-zorro-antd/drawer';
|
|
6
|
+
import { NzDrawerModule } from 'ng-zorro-antd/drawer';
|
|
7
|
+
import * as i3 from 'ng-zorro-antd/icon';
|
|
8
|
+
import { NzIconModule } from 'ng-zorro-antd/icon';
|
|
9
|
+
import * as i2 from 'ng-zorro-antd/spin';
|
|
10
|
+
import { NzSpinModule } from 'ng-zorro-antd/spin';
|
|
11
|
+
import * as i4 from 'ng-zorro-antd/typography';
|
|
12
|
+
import { NzTypographyModule } from 'ng-zorro-antd/typography';
|
|
13
|
+
import { MenuService } from '@solar-angular/planets/earth';
|
|
14
|
+
import { MessageService } from '@solar-angular/ui-zorro/message';
|
|
15
|
+
|
|
16
|
+
class Editor {
|
|
17
|
+
constructor() {
|
|
18
|
+
this._visible = false;
|
|
19
|
+
/** 模型初始值 */
|
|
20
|
+
this.originalModel = {};
|
|
21
|
+
this.model = {};
|
|
22
|
+
this.loading = false;
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
24
|
+
this.schema = form(() => { });
|
|
25
|
+
/** 是否在保存完之后固定抽屉 */
|
|
26
|
+
this.pin = false;
|
|
27
|
+
}
|
|
28
|
+
get visible() {
|
|
29
|
+
return this._visible;
|
|
30
|
+
}
|
|
31
|
+
set visible(value) {
|
|
32
|
+
// 手动判断一下,因为双向绑定的原因,这里会被设置两次
|
|
33
|
+
if (this._visible !== value) {
|
|
34
|
+
if (!value) {
|
|
35
|
+
this.reset(); // 关闭的时候自动重置
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
this._visible = value;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 自动控制 loading 状态
|
|
42
|
+
*/
|
|
43
|
+
withLoading() {
|
|
44
|
+
this.loading = true;
|
|
45
|
+
return (observable) => {
|
|
46
|
+
return observable.pipe(finalize(() => this.loading = false));
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* next 时自动重置表单 或 收起编辑器
|
|
51
|
+
*/
|
|
52
|
+
withAttach() {
|
|
53
|
+
return (observable) => observable.pipe(tap(() => this.pin ? this.reset() : this.dismiss()));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* 呈现编辑器
|
|
57
|
+
*/
|
|
58
|
+
present() {
|
|
59
|
+
this.visible = true;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 关闭编辑器
|
|
63
|
+
*/
|
|
64
|
+
dismiss() {
|
|
65
|
+
this.visible = false;
|
|
66
|
+
}
|
|
67
|
+
togglePin() {
|
|
68
|
+
this.pin = !this.pin;
|
|
69
|
+
}
|
|
70
|
+
reset() {
|
|
71
|
+
this.fill({});
|
|
72
|
+
}
|
|
73
|
+
fill(model) {
|
|
74
|
+
this.originalModel = model;
|
|
75
|
+
this.model = model;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
class SunEditorDrawer {
|
|
80
|
+
constructor() {
|
|
81
|
+
this.width = 600;
|
|
82
|
+
this.primaryKey = 'id';
|
|
83
|
+
}
|
|
84
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SunEditorDrawer, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
85
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: SunEditorDrawer, isStandalone: true, selector: "sun-editor-drawer", inputs: { editor: "editor", width: "width", primaryKey: "primaryKey" }, ngImport: i0, template: "<nz-drawer\n nzWrapClassName=\"sun-editor-drawer-wrapper\"\n [nzWidth]=\"width\"\n [nzClosable]=\"false\"\n [nzTitle]=\"editorTitle\"\n [nzFooter]=\"editorFooter\"\n [(nzVisible)]=\"editor.visible\"\n (nzOnClose)=\"editor.visible = false\">\n <nz-spin *nzDrawerContent [nzSpinning]=\"editor.loading\">\n <ng-content />\n </nz-spin>\n</nz-drawer>\n\n<ng-template #editorTitle>\n <div>{{ editor.model[primaryKey] ? '\u7F16\u8F91\u6761\u76EE' : '\u65B0\u589E\u6761\u76EE' }}</div>\n\n <span nz-icon nzType=\"pushpin\" [nzTheme]=\"editor.pin ? 'twotone' : 'outline'\" (click)=\"editor.togglePin()\"></span>\n</ng-template>\n\n<ng-template #editorFooter>\n <small nz-typography nzType=\"secondary\">\n \u6CE8\u610F\uFF1A\u6807\u7B7E\u4E0A\u5E26\u6709\n <span nz-typography nzType=\"danger\" style=\"font-family: SimSun, sans-serif\">*</span>\n \u7B26\u53F7\u7684\u9879\u76EE\u4E3A\u5FC5\u586B\u9879\n </small>\n</ng-template>\n", styles: ["::ng-deep .sun-editor-drawer-wrapper .ant-drawer-title{display:flex;justify-content:space-between;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: NzDrawerModule }, { kind: "component", type: i1.NzDrawerComponent, selector: "nz-drawer", inputs: ["nzContent", "nzCloseIcon", "nzClosable", "nzMaskClosable", "nzMask", "nzCloseOnNavigation", "nzNoAnimation", "nzKeyboard", "nzTitle", "nzExtra", "nzFooter", "nzPlacement", "nzSize", "nzMaskStyle", "nzBodyStyle", "nzWrapClassName", "nzWidth", "nzHeight", "nzZIndex", "nzOffsetX", "nzOffsetY", "nzVisible"], outputs: ["nzOnViewInit", "nzOnClose", "nzVisibleChange"], exportAs: ["nzDrawer"] }, { kind: "directive", type: i1.NzDrawerContentDirective, selector: "[nzDrawerContent]", exportAs: ["nzDrawerContent"] }, { kind: "ngmodule", type: NzSpinModule }, { kind: "component", type: i2.NzSpinComponent, selector: "nz-spin", inputs: ["nzIndicator", "nzSize", "nzTip", "nzDelay", "nzSimple", "nzSpinning"], exportAs: ["nzSpin"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i3.NzIconDirective, selector: "[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzTypographyModule }, { kind: "component", type: i4.NzTypographyComponent, selector: " nz-typography, [nz-typography], p[nz-paragraph], span[nz-text], h1[nz-title], h2[nz-title], h3[nz-title], h4[nz-title] ", inputs: ["nzCopyable", "nzEditable", "nzDisabled", "nzExpandable", "nzEllipsis", "nzCopyTooltips", "nzCopyIcons", "nzEditTooltip", "nzEditIcon", "nzContent", "nzEllipsisRows", "nzType", "nzCopyText", "nzSuffix"], outputs: ["nzContentChange", "nzCopy", "nzExpandChange", "nzOnEllipsis"], exportAs: ["nzTypography"] }] }); }
|
|
86
|
+
}
|
|
87
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SunEditorDrawer, decorators: [{
|
|
88
|
+
type: Component,
|
|
89
|
+
args: [{ selector: 'sun-editor-drawer', standalone: true, imports: [
|
|
90
|
+
NzDrawerModule,
|
|
91
|
+
NzSpinModule,
|
|
92
|
+
NzIconModule,
|
|
93
|
+
NzTypographyModule
|
|
94
|
+
], template: "<nz-drawer\n nzWrapClassName=\"sun-editor-drawer-wrapper\"\n [nzWidth]=\"width\"\n [nzClosable]=\"false\"\n [nzTitle]=\"editorTitle\"\n [nzFooter]=\"editorFooter\"\n [(nzVisible)]=\"editor.visible\"\n (nzOnClose)=\"editor.visible = false\">\n <nz-spin *nzDrawerContent [nzSpinning]=\"editor.loading\">\n <ng-content />\n </nz-spin>\n</nz-drawer>\n\n<ng-template #editorTitle>\n <div>{{ editor.model[primaryKey] ? '\u7F16\u8F91\u6761\u76EE' : '\u65B0\u589E\u6761\u76EE' }}</div>\n\n <span nz-icon nzType=\"pushpin\" [nzTheme]=\"editor.pin ? 'twotone' : 'outline'\" (click)=\"editor.togglePin()\"></span>\n</ng-template>\n\n<ng-template #editorFooter>\n <small nz-typography nzType=\"secondary\">\n \u6CE8\u610F\uFF1A\u6807\u7B7E\u4E0A\u5E26\u6709\n <span nz-typography nzType=\"danger\" style=\"font-family: SimSun, sans-serif\">*</span>\n \u7B26\u53F7\u7684\u9879\u76EE\u4E3A\u5FC5\u586B\u9879\n </small>\n</ng-template>\n", styles: ["::ng-deep .sun-editor-drawer-wrapper .ant-drawer-title{display:flex;justify-content:space-between;align-items:center}\n"] }]
|
|
95
|
+
}], propDecorators: { editor: [{
|
|
96
|
+
type: Input
|
|
97
|
+
}], width: [{
|
|
98
|
+
type: Input
|
|
99
|
+
}], primaryKey: [{
|
|
100
|
+
type: Input
|
|
101
|
+
}] } });
|
|
102
|
+
|
|
103
|
+
class Searcher {
|
|
104
|
+
constructor() {
|
|
105
|
+
this.model = {};
|
|
106
|
+
}
|
|
107
|
+
reset() {
|
|
108
|
+
this.form?.reset({});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* 增删改查页面
|
|
114
|
+
* @template T Searcher 的模型类型
|
|
115
|
+
* @template U Editor 的模型类型,默认为 T
|
|
116
|
+
* @template V Data 的模型类型,默认为 U
|
|
117
|
+
*/
|
|
118
|
+
class CrudPage {
|
|
119
|
+
constructor() {
|
|
120
|
+
this.data = [];
|
|
121
|
+
this.pageSize = 10;
|
|
122
|
+
this.pageNo = 1;
|
|
123
|
+
this.loading = false;
|
|
124
|
+
this.searcher = new Searcher();
|
|
125
|
+
this.editor = new Editor();
|
|
126
|
+
/** 当前页面的菜单列 */
|
|
127
|
+
this.menus$ = inject(MenuService).menus$.pipe(shareReplay(1));
|
|
128
|
+
this.message = inject(MessageService);
|
|
129
|
+
}
|
|
130
|
+
withTableLoading() {
|
|
131
|
+
return (observable) => {
|
|
132
|
+
this.loading = true;
|
|
133
|
+
return observable.pipe(finalize(() => this.loading = false));
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* {@link MessageService.withLoading()} 的快捷方式
|
|
138
|
+
* @param content
|
|
139
|
+
*/
|
|
140
|
+
withLoading(content) {
|
|
141
|
+
return this.message.withLoading(content);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* {@link MessageService.withDeleteLoading()} 的快捷方式
|
|
145
|
+
* @param content
|
|
146
|
+
*/
|
|
147
|
+
withDeleteLoading() {
|
|
148
|
+
return this.message.withDeleteLoading();
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* {@link MessageService.withSaveLoading()} 的快捷方式
|
|
152
|
+
* @param content
|
|
153
|
+
*/
|
|
154
|
+
withSaveLoading() {
|
|
155
|
+
return this.message.withSaveLoading();
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* 编辑
|
|
159
|
+
* @param entity
|
|
160
|
+
*/
|
|
161
|
+
edit(entity) {
|
|
162
|
+
this.editor.fill(entity);
|
|
163
|
+
this.editor.present();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* 带分页的增删改查页面
|
|
168
|
+
* @template T Searcher 的模型类型
|
|
169
|
+
* @template U Editor 的模型类型,默认为 T
|
|
170
|
+
* @template V Data 的模型类型,默认为 U
|
|
171
|
+
*/
|
|
172
|
+
class PagingCrudPage extends CrudPage {
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Generated bundle index. Do not edit.
|
|
177
|
+
*/
|
|
178
|
+
|
|
179
|
+
export { CrudPage, Editor, PagingCrudPage, Searcher, SunEditorDrawer };
|
|
180
|
+
//# sourceMappingURL=solar-angular-ui-zorro-crud.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solar-angular-ui-zorro-crud.mjs","sources":["../../../packages/ui-zorro/crud/editor.ts","../../../packages/ui-zorro/crud/editor-drawer/editor-drawer.component.ts","../../../packages/ui-zorro/crud/editor-drawer/editor-drawer.component.html","../../../packages/ui-zorro/crud/searcher.ts","../../../packages/ui-zorro/crud/page.ts","../../../packages/ui-zorro/crud/solar-angular-ui-zorro-crud.ts"],"sourcesContent":["import { FormGroup } from '@angular/forms';\nimport { AbstractFormGroupSchema, form } from '@fluent-form/core';\nimport { Observable, finalize, tap } from 'rxjs';\n\nexport class Editor<T> {\n private _visible = false;\n /** 模型初始值 */\n originalModel: T = {} as T;\n model: T = {} as T;\n loading = false;\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n schema: AbstractFormGroupSchema = form(() => { });\n /** 是否在保存完之后固定抽屉 */\n pin = false;\n form?: FormGroup;\n\n get visible(): boolean {\n return this._visible;\n }\n\n set visible(value: boolean) {\n // 手动判断一下,因为双向绑定的原因,这里会被设置两次\n if (this._visible !== value) {\n if (!value) {\n this.reset(); // 关闭的时候自动重置\n }\n }\n this._visible = value;\n }\n\n /**\n * 自动控制 loading 状态\n */\n withLoading<X>() {\n this.loading = true;\n return (observable: Observable<X>) => {\n return observable.pipe(\n finalize(() => this.loading = false)\n );\n };\n }\n\n /**\n * next 时自动重置表单 或 收起编辑器\n */\n withAttach<X>() {\n return (observable: Observable<X>) => observable.pipe(\n tap(() => this.pin ? this.reset() : this.dismiss())\n );\n }\n\n /**\n * 呈现编辑器\n */\n present() {\n this.visible = true;\n }\n\n /**\n * 关闭编辑器\n */\n dismiss() {\n this.visible = false;\n }\n\n togglePin() {\n this.pin = !this.pin;\n }\n\n reset() {\n this.fill({} as T);\n }\n\n fill(model: T) {\n this.originalModel = model;\n this.model = model;\n }\n}\n","import { Component, Input } from '@angular/core';\nimport { NzDrawerModule } from 'ng-zorro-antd/drawer';\nimport { NzIconModule } from 'ng-zorro-antd/icon';\nimport { NzSpinModule } from 'ng-zorro-antd/spin';\nimport { NzTypographyModule } from 'ng-zorro-antd/typography';\nimport { Editor } from '../editor';\n\n@Component({\n selector: 'sun-editor-drawer',\n standalone: true,\n imports: [\n NzDrawerModule,\n NzSpinModule,\n NzIconModule,\n NzTypographyModule\n ],\n templateUrl: './editor-drawer.component.html',\n styleUrl: './editor-drawer.component.scss'\n})\nexport class SunEditorDrawer<T extends Record<string, any>> {\n @Input() editor!: Editor<T>;\n @Input() width: string | number = 600;\n @Input() primaryKey = 'id';\n}\n","<nz-drawer\n nzWrapClassName=\"sun-editor-drawer-wrapper\"\n [nzWidth]=\"width\"\n [nzClosable]=\"false\"\n [nzTitle]=\"editorTitle\"\n [nzFooter]=\"editorFooter\"\n [(nzVisible)]=\"editor.visible\"\n (nzOnClose)=\"editor.visible = false\">\n <nz-spin *nzDrawerContent [nzSpinning]=\"editor.loading\">\n <ng-content />\n </nz-spin>\n</nz-drawer>\n\n<ng-template #editorTitle>\n <div>{{ editor.model[primaryKey] ? '编辑条目' : '新增条目' }}</div>\n\n <span nz-icon nzType=\"pushpin\" [nzTheme]=\"editor.pin ? 'twotone' : 'outline'\" (click)=\"editor.togglePin()\"></span>\n</ng-template>\n\n<ng-template #editorFooter>\n <small nz-typography nzType=\"secondary\">\n 注意:标签上带有\n <span nz-typography nzType=\"danger\" style=\"font-family: SimSun, sans-serif\">*</span>\n 符号的项目为必填项\n </small>\n</ng-template>\n","import { FormGroup } from '@angular/forms';\nimport { AbstractFormGroupSchema } from '@fluent-form/core';\n\nexport class Searcher<T> {\n form?: FormGroup;\n model: Partial<T> = {};\n\n schema!: AbstractFormGroupSchema;\n\n reset() {\n this.form?.reset({});\n }\n}\n","import { inject } from '@angular/core';\nimport { MenuService } from '@solar-angular/planets/earth';\nimport { MessageService } from '@solar-angular/ui-zorro/message';\nimport { Menu } from '@solar-kit/planets/earth';\nimport { finalize, Observable, shareReplay } from 'rxjs';\nimport { Editor } from './editor';\nimport { Searcher } from './searcher';\n\n/**\n * 增删改查页面\n * @template T Searcher 的模型类型\n * @template U Editor 的模型类型,默认为 T\n * @template V Data 的模型类型,默认为 U\n */\nexport abstract class CrudPage<T, U = T, V = U> {\n protected data: V[] = [];\n\n protected pageSize = 10;\n protected pageNo = 1;\n\n protected loading = false;\n\n protected searcher = new Searcher<T>();\n protected editor = new Editor<U>();\n\n /** 当前页面的菜单列 */\n readonly menus$: Observable<Menu[]> = inject(MenuService).menus$.pipe(shareReplay(1));\n readonly message = inject(MessageService);\n\n protected withTableLoading<X>() {\n return (observable: Observable<X>) => {\n this.loading = true;\n return observable.pipe(\n finalize(() => this.loading = false)\n );\n };\n }\n\n /**\n * {@link MessageService.withLoading()} 的快捷方式\n * @param content\n */\n protected withLoading<X>(content?: string) {\n return this.message.withLoading<X>(content);\n }\n\n /**\n * {@link MessageService.withDeleteLoading()} 的快捷方式\n * @param content\n */\n protected withDeleteLoading<X>() {\n return this.message.withDeleteLoading<X>();\n }\n\n /**\n * {@link MessageService.withSaveLoading()} 的快捷方式\n * @param content\n */\n protected withSaveLoading<X>() {\n return this.message.withSaveLoading<X>();\n }\n\n /**\n * 编辑\n * @param entity\n */\n protected edit(entity: U) {\n this.editor.fill(entity);\n this.editor.present();\n }\n}\n\n/**\n * 带分页的增删改查页面\n * @template T Searcher 的模型类型\n * @template U Editor 的模型类型,默认为 T\n * @template V Data 的模型类型,默认为 U\n */\nexport abstract class PagingCrudPage<T, U = T, V = U> extends CrudPage<T, U, V> {\n protected totalSize!: number;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { button, text, number, toggle, radioGroup, checkboxGroup, select, cascader, datePicker, dateRangePicker, headless } from '@fluent-form/ui-zorro';
|
|
2
|
+
import { levels2tree, tree2list } from '@solar-angular/core';
|
|
3
|
+
import { form } from '@fluent-form/core';
|
|
4
|
+
|
|
5
|
+
function searchButton() {
|
|
6
|
+
return button().icon('search').content('查询').type('primary');
|
|
7
|
+
}
|
|
8
|
+
function addButton() {
|
|
9
|
+
return button().icon('plus').content('新增').type('primary').mode('button');
|
|
10
|
+
}
|
|
11
|
+
function saveButton() {
|
|
12
|
+
return button()
|
|
13
|
+
.content('保存')
|
|
14
|
+
.type('primary')
|
|
15
|
+
.variants({ block: true })
|
|
16
|
+
.disabled(({ control }) => control.invalid);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function cellphoneText(key = 'cellphone', length = 11) {
|
|
20
|
+
return text(key).type('tel').length(length);
|
|
21
|
+
}
|
|
22
|
+
function integer(key) {
|
|
23
|
+
return number(key).precision(0);
|
|
24
|
+
}
|
|
25
|
+
function enabledToggle(key = 'enabled', defaultValue = true) {
|
|
26
|
+
return toggle(key).placeholder(['有效', '无效']).defaultValue(defaultValue);
|
|
27
|
+
}
|
|
28
|
+
function finishedToggle(key = 'finished', defaultValue = false) {
|
|
29
|
+
return toggle(key).placeholder(['已完成', '未完成']).defaultValue(defaultValue);
|
|
30
|
+
}
|
|
31
|
+
function genderRadioGroup(key = 'gender') {
|
|
32
|
+
return radioGroup(key).options([
|
|
33
|
+
{ label: '女', value: 0 /* Gender.Woman */ },
|
|
34
|
+
{ label: '男', value: 1 /* Gender.Man */ }
|
|
35
|
+
]);
|
|
36
|
+
}
|
|
37
|
+
function categoryCascader(key, channels, categories) {
|
|
38
|
+
return entityCascader(key).options(levels2tree([channels, categories], 'channel'));
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 通用的实体多选框
|
|
42
|
+
*
|
|
43
|
+
* 已经配置了 labelProperty: 'fullName', valueProperty: 'id'
|
|
44
|
+
* @param key
|
|
45
|
+
*/
|
|
46
|
+
function entityCheckboxGroup(key) {
|
|
47
|
+
return checkboxGroup(key).config({ labelProperty: 'fullName', valueProperty: 'id' });
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 通用的实体单选框
|
|
51
|
+
*
|
|
52
|
+
* 已经配置了 labelProperty: 'fullName', valueProperty: 'id'
|
|
53
|
+
* @param key
|
|
54
|
+
*/
|
|
55
|
+
function entityRadioGroup(key) {
|
|
56
|
+
return radioGroup(key).config({ labelProperty: 'fullName', valueProperty: 'id' });
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* 通用的实体选择器
|
|
60
|
+
*
|
|
61
|
+
* 已经配置了 labelProperty: 'fullName', valueProperty: 'id'
|
|
62
|
+
* @param key
|
|
63
|
+
*/
|
|
64
|
+
function entitySelect(key) {
|
|
65
|
+
return select(key).config({ labelProperty: 'fullName', valueProperty: 'id' });
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 通用的实体联级选择器
|
|
69
|
+
*
|
|
70
|
+
* - 多字段模式下不支持以下选项:
|
|
71
|
+
* - 不支持使用函数作为 options
|
|
72
|
+
* - 不支持 fetchOptions 选项
|
|
73
|
+
*
|
|
74
|
+
* options 选项可以使用 `list2tree()` 或 `levels2tree()` 来构造
|
|
75
|
+
*
|
|
76
|
+
* @param key
|
|
77
|
+
*/
|
|
78
|
+
function entityCascader(key) {
|
|
79
|
+
let list;
|
|
80
|
+
return cascader(key)
|
|
81
|
+
.trigger('hover')
|
|
82
|
+
.mapper({
|
|
83
|
+
parser: (value, schema) => {
|
|
84
|
+
if (!value)
|
|
85
|
+
return null;
|
|
86
|
+
// 如果输入的是数组,则说明当前是多字段模式,不需要做处理
|
|
87
|
+
if (Array.isArray(value))
|
|
88
|
+
return value;
|
|
89
|
+
// 如果输入的是叶子节点,我们需要转为 [父节点, ..., 叶子节点]
|
|
90
|
+
list ??= tree2list(schema.options);
|
|
91
|
+
// 找到选中的叶子节点
|
|
92
|
+
let node = list.find(node => node.id === value && node.isLeaf);
|
|
93
|
+
const levels = [];
|
|
94
|
+
while (node) {
|
|
95
|
+
levels.unshift(node.id);
|
|
96
|
+
node = node.parent;
|
|
97
|
+
}
|
|
98
|
+
return levels;
|
|
99
|
+
},
|
|
100
|
+
formatter: value => {
|
|
101
|
+
// 多字段模式,不需要处理
|
|
102
|
+
if (Array.isArray(key))
|
|
103
|
+
return value;
|
|
104
|
+
// 输出的是节点数组,我们只要叶子节点
|
|
105
|
+
return value?.[value.length - 1];
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
.config({ labelProperty: 'fullName', valueProperty: 'id' });
|
|
109
|
+
}
|
|
110
|
+
function datetimePicker(key, format = 'yyyy-MM-dd HH:mm') {
|
|
111
|
+
return datePicker(key)
|
|
112
|
+
.time({ nzFormat: 'HH:mm' })
|
|
113
|
+
.format(format);
|
|
114
|
+
}
|
|
115
|
+
function datetimeRangePicker(key, format = 'yyyy-MM-dd HH:mm') {
|
|
116
|
+
return dateRangePicker(key)
|
|
117
|
+
.time({ nzFormat: 'HH:mm' })
|
|
118
|
+
.format(format);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* 实体表单
|
|
123
|
+
*
|
|
124
|
+
* 内置了一个 Headless ID 控件图示:`headless('id')`
|
|
125
|
+
* @param schemas
|
|
126
|
+
*/
|
|
127
|
+
function entityForm(composeFn) {
|
|
128
|
+
return form(() => {
|
|
129
|
+
headless('id');
|
|
130
|
+
composeFn();
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function parseLabel(label) {
|
|
135
|
+
if (typeof label === 'string') {
|
|
136
|
+
return label;
|
|
137
|
+
}
|
|
138
|
+
return label.content ?? '';
|
|
139
|
+
}
|
|
140
|
+
function autoPlaceholder(schema, action) {
|
|
141
|
+
const label = schema['label'];
|
|
142
|
+
if (label && typeof label !== 'function') {
|
|
143
|
+
schema['placeholder'] ??= action + parseLabel(label);
|
|
144
|
+
}
|
|
145
|
+
return schema;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* 为文本框字段自动添加 placeholder
|
|
149
|
+
*/
|
|
150
|
+
function useAutoPlaceholderPatchers() {
|
|
151
|
+
return [
|
|
152
|
+
{
|
|
153
|
+
selector: ['text', 'number'],
|
|
154
|
+
patch: schema => autoPlaceholder(schema, '请输入')
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
selector: 'textarea',
|
|
158
|
+
patch: schema => autoPlaceholder(schema, '请填写')
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
selector: ['date-picker', 'time-picker', 'select', 'cascader', 'tree-select'],
|
|
162
|
+
patch: schema => autoPlaceholder(schema, '请选择')
|
|
163
|
+
}
|
|
164
|
+
];
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* 1. 自动为非必填字段添加清除按钮
|
|
168
|
+
* 2. 为选择器添加搜索功能
|
|
169
|
+
*/
|
|
170
|
+
function useImprovedPickerPatchers() {
|
|
171
|
+
return [
|
|
172
|
+
{
|
|
173
|
+
selector: ['date-picker', 'time-picker', 'select', 'cascader', 'tree-select'],
|
|
174
|
+
patch: schema => {
|
|
175
|
+
if (!schema['required']) {
|
|
176
|
+
schema['clearable'] ??= true;
|
|
177
|
+
}
|
|
178
|
+
return schema;
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
selector: ['select', 'cascader', 'tree-select'],
|
|
183
|
+
patch: schema => {
|
|
184
|
+
schema['searchable'] ??= true;
|
|
185
|
+
return schema;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
];
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Generated bundle index. Do not edit.
|
|
193
|
+
*/
|
|
194
|
+
|
|
195
|
+
export { addButton, categoryCascader, cellphoneText, datetimePicker, datetimeRangePicker, enabledToggle, entityCascader, entityCheckboxGroup, entityForm, entityRadioGroup, entitySelect, finishedToggle, genderRadioGroup, integer, saveButton, searchButton, useAutoPlaceholderPatchers, useImprovedPickerPatchers };
|
|
196
|
+
//# sourceMappingURL=solar-angular-ui-zorro-fluent-form.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solar-angular-ui-zorro-fluent-form.mjs","sources":["../../../packages/ui-zorro/fluent-form/components.ts","../../../packages/ui-zorro/fluent-form/controls.ts","../../../packages/ui-zorro/fluent-form/form.ts","../../../packages/ui-zorro/fluent-form/patchers.ts","../../../packages/ui-zorro/fluent-form/solar-angular-ui-zorro-fluent-form.ts"],"sourcesContent":["import { UnstableBuilder } from '@fluent-form/core';\nimport { button, ButtonComponentSchema } from '@fluent-form/ui-zorro';\nimport { KindOrKey } from './typing';\n\nexport function searchButton(): UnstableBuilder<ButtonComponentSchema, KindOrKey | 'icon' | 'content' | 'type'> {\n return button().icon('search').content('查询').type('primary');\n}\n\nexport function addButton(): UnstableBuilder<ButtonComponentSchema, KindOrKey | 'icon' | 'content' | 'type' | 'mode'> {\n return button().icon('plus').content('新增').type('primary').mode('button');\n}\n\nexport function saveButton(): UnstableBuilder<ButtonComponentSchema, KindOrKey | 'content' | 'type' | 'disabled'> {\n return button()\n .content('保存')\n .type('primary')\n .variants({ block: true })\n .disabled(({ control }) => control.invalid) as UnstableBuilder<ButtonComponentSchema, KindOrKey | 'content' | 'type' | 'disabled'>;\n}\n","import { SchemaKey, SingleSchemaKey, UnstableBuilder } from '@fluent-form/core';\nimport { CascaderControlSchema, CheckboxGroupControlSchema, DatePickerControlSchema, DateRangePickerControlSchema, NumberControlSchema, RadioGroupControlSchema, SelectControlSchema, TextControlSchema, ToggleControlSchema, cascader, checkboxGroup, datePicker, dateRangePicker, number, radioGroup, select, text, toggle } from '@fluent-form/ui-zorro';\nimport { TreeNode, levels2tree, tree2list } from '@solar-angular/core';\nimport { Category, Channel } from '@solar-kit/planets/earth';\nimport { Gender } from '@solar-kit/planets/sun';\nimport { KindOrKey } from './typing';\n\nexport function cellphoneText(key = 'cellphone', length = 11): UnstableBuilder<TextControlSchema, KindOrKey | 'type' | 'length'> {\n return text(key).type('tel').length(length);\n}\n\nexport function integer(key: SingleSchemaKey): UnstableBuilder<NumberControlSchema, KindOrKey | 'precision'> {\n return number(key).precision(0);\n}\n\nexport function enabledToggle(key: SingleSchemaKey = 'enabled', defaultValue = true): UnstableBuilder<ToggleControlSchema, KindOrKey | 'placeholder' | 'defaultValue'> {\n return toggle(key).placeholder(['有效', '无效']).defaultValue(defaultValue);\n}\n\nexport function finishedToggle(key: SingleSchemaKey = 'finished', defaultValue = false): UnstableBuilder<ToggleControlSchema, KindOrKey | 'placeholder' | 'defaultValue'> {\n return toggle(key).placeholder(['已完成', '未完成']).defaultValue(defaultValue);\n}\n\nexport function genderRadioGroup(key = 'gender'): UnstableBuilder<RadioGroupControlSchema, KindOrKey | 'options'> {\n return radioGroup(key).options([\n { label: '女', value: Gender.Woman },\n { label: '男', value: Gender.Man }\n ]);\n}\n\nexport function categoryCascader(key: SchemaKey, channels: Channel[], categories: Category[]): UnstableBuilder<CascaderControlSchema, KindOrKey | 'options' | 'trigger' | 'config' | 'mapper'> {\n return entityCascader(key).options(levels2tree([channels, categories], 'channel'));\n}\n\n/**\n * 通用的实体多选框\n *\n * 已经配置了 labelProperty: 'fullName', valueProperty: 'id'\n * @param key\n */\nexport function entityCheckboxGroup(key: string): UnstableBuilder<CheckboxGroupControlSchema, KindOrKey | 'config'> {\n return checkboxGroup(key).config({ labelProperty: 'fullName', valueProperty: 'id' });\n}\n\n/**\n * 通用的实体单选框\n *\n * 已经配置了 labelProperty: 'fullName', valueProperty: 'id'\n * @param key\n */\nexport function entityRadioGroup(key: string): UnstableBuilder<RadioGroupControlSchema, KindOrKey | 'config'> {\n return radioGroup(key).config({ labelProperty: 'fullName', valueProperty: 'id' });\n}\n\n/**\n * 通用的实体选择器\n *\n * 已经配置了 labelProperty: 'fullName', valueProperty: 'id'\n * @param key\n */\nexport function entitySelect(key: SingleSchemaKey): UnstableBuilder<SelectControlSchema, KindOrKey | 'config'> {\n return select(key).config({ labelProperty: 'fullName', valueProperty: 'id' });\n}\n\n/**\n * 通用的实体联级选择器\n *\n * - 多字段模式下不支持以下选项:\n * - 不支持使用函数作为 options\n * - 不支持 fetchOptions 选项\n *\n * options 选项可以使用 `list2tree()` 或 `levels2tree()` 来构造\n *\n * @param key\n */\nexport function entityCascader(key: SchemaKey): UnstableBuilder<CascaderControlSchema, KindOrKey | 'trigger' | 'config' | 'mapper'> {\n let list: TreeNode[];\n\n return cascader(key)\n .trigger('hover')\n .mapper({\n parser: (value: TreeNode['id'] | TreeNode['id'][] | null, schema) => {\n if (!value) return null;\n\n // 如果输入的是数组,则说明当前是多字段模式,不需要做处理\n if (Array.isArray(value)) return value;\n\n // 如果输入的是叶子节点,我们需要转为 [父节点, ..., 叶子节点]\n list ??= tree2list((schema as CascaderControlSchema).options as TreeNode[]);\n // 找到选中的叶子节点\n let node = list.find(node => node.id === value && node.isLeaf);\n\n const levels = [];\n\n while (node) {\n levels.unshift(node.id);\n node = node.parent;\n }\n\n return levels;\n },\n formatter: value => {\n // 多字段模式,不需要处理\n if (Array.isArray(key)) return value;\n\n // 输出的是节点数组,我们只要叶子节点\n return value?.[value.length - 1];\n }\n })\n .config({ labelProperty: 'fullName', valueProperty: 'id' });\n}\n\nexport function datetimePicker(key: string, format = 'yyyy-MM-dd HH:mm'): UnstableBuilder<DatePickerControlSchema, KindOrKey | 'time' | 'format'> {\n return datePicker(key)\n .time({ nzFormat: 'HH:mm' })\n .format(format);\n}\n\nexport function datetimeRangePicker(key: SchemaKey, format = 'yyyy-MM-dd HH:mm'): UnstableBuilder<DateRangePickerControlSchema, KindOrKey | 'time' | 'format'> {\n return dateRangePicker(key)\n .time({ nzFormat: 'HH:mm' })\n .format(format);\n}\n","import { form } from '@fluent-form/core';\nimport { headless } from '@fluent-form/ui-zorro';\nimport { NzSafeAny } from 'ng-zorro-antd/core/types';\n\n/**\n * 实体表单\n *\n * 内置了一个 Headless ID 控件图示:`headless('id')`\n * @param schemas\n */\nexport function entityForm(composeFn: () => NzSafeAny) {\n return form(() => {\n headless('id');\n composeFn();\n });\n}\n","import { SchemaPatcher } from '@fluent-form/core';\nimport { AbstractZorroControlSchema, Label } from '@fluent-form/ui-zorro';\n\nfunction parseLabel(label: string | Label): string {\n if (typeof label === 'string') {\n return label;\n }\n\n return label.content ?? '';\n}\n\nfunction autoPlaceholder(schema: AbstractZorroControlSchema, action: string) {\n const label = schema['label'];\n\n if (label && typeof label !== 'function') {\n (schema as any)['placeholder'] ??= action + parseLabel(label);\n }\n\n return schema;\n}\n\n/**\n * 为文本框字段自动添加 placeholder\n */\nexport function useAutoPlaceholderPatchers(): SchemaPatcher[] {\n return [\n {\n selector: ['text', 'number'],\n patch: schema => autoPlaceholder(schema, '请输入')\n },\n {\n selector: 'textarea',\n patch: schema => autoPlaceholder(schema, '请填写')\n },\n {\n selector: ['date-picker', 'time-picker', 'select', 'cascader', 'tree-select'],\n patch: schema => autoPlaceholder(schema, '请选择')\n }\n ];\n}\n\n/**\n * 1. 自动为非必填字段添加清除按钮\n * 2. 为选择器添加搜索功能\n */\nexport function useImprovedPickerPatchers(): SchemaPatcher[] {\n return [\n {\n selector: ['date-picker', 'time-picker', 'select', 'cascader', 'tree-select'],\n patch: schema => {\n if (!schema['required']) {\n schema['clearable'] ??= true;\n }\n\n return schema;\n }\n },\n {\n selector: ['select', 'cascader', 'tree-select'],\n patch: schema => {\n schema['searchable'] ??= true;\n\n return schema;\n }\n }\n ];\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { HttpEventType } from '@angular/common/http';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { inject, EventEmitter, numberAttribute, booleanAttribute, Component, ChangeDetectionStrategy, ViewEncapsulation, Input, Output } from '@angular/core';
|
|
4
|
+
import { EarthService, ObjectStorageService } from '@solar-angular/planets/earth';
|
|
5
|
+
import { ImageCompressor, FileManager } from '@solar-angular/platform-browser';
|
|
6
|
+
import { MessageService } from '@solar-angular/ui-zorro/message';
|
|
7
|
+
import { fileExtensionOf } from '@solar-kit/core';
|
|
8
|
+
import { filterResult, unpackResult } from '@solar-kit/planets/sun';
|
|
9
|
+
import * as i1 from 'ng-zorro-antd/icon';
|
|
10
|
+
import { NzIconModule } from 'ng-zorro-antd/icon';
|
|
11
|
+
import { NzImageService, NzImageModule } from 'ng-zorro-antd/image';
|
|
12
|
+
import * as i3 from 'ng-zorro-antd/popconfirm';
|
|
13
|
+
import { NzPopconfirmModule } from 'ng-zorro-antd/popconfirm';
|
|
14
|
+
import * as i2 from 'ng-zorro-antd/upload';
|
|
15
|
+
import { NzUploadModule } from 'ng-zorro-antd/upload';
|
|
16
|
+
import { switchMap, of, fromEvent, take, tap, from } from 'rxjs';
|
|
17
|
+
|
|
18
|
+
class SunMediaUploader {
|
|
19
|
+
constructor() {
|
|
20
|
+
this.imageService = inject(NzImageService);
|
|
21
|
+
this.earthService = inject(EarthService);
|
|
22
|
+
this.oss = inject(ObjectStorageService);
|
|
23
|
+
this.imageCompressor = inject(ImageCompressor);
|
|
24
|
+
this.message = inject(MessageService);
|
|
25
|
+
this.fileManager = inject(FileManager);
|
|
26
|
+
this.data = [
|
|
27
|
+
// {
|
|
28
|
+
// uid: '1',
|
|
29
|
+
// type: 'image',
|
|
30
|
+
// url: '',
|
|
31
|
+
// progress: 50
|
|
32
|
+
// },
|
|
33
|
+
// {
|
|
34
|
+
// uid: '2',
|
|
35
|
+
// type: 'image',
|
|
36
|
+
// url: '',
|
|
37
|
+
// }
|
|
38
|
+
];
|
|
39
|
+
this.limit = 9;
|
|
40
|
+
this.deletable = true;
|
|
41
|
+
this.uploadable = true;
|
|
42
|
+
this.previewable = true;
|
|
43
|
+
this.downloadable = false;
|
|
44
|
+
this.shape = 'square';
|
|
45
|
+
this.uploadKeys = this.earthService.mediaUploadKeys().pipe(filterResult(), unpackResult());
|
|
46
|
+
/** 启用图片压缩 */
|
|
47
|
+
this.compress = false;
|
|
48
|
+
this.uploaded = new EventEmitter();
|
|
49
|
+
this.delete = new EventEmitter();
|
|
50
|
+
this.error = new EventEmitter();
|
|
51
|
+
this.dataChange = new EventEmitter();
|
|
52
|
+
this.upload = (args) => {
|
|
53
|
+
const file = args.postFile;
|
|
54
|
+
const ext = fileExtensionOf(args.file.name);
|
|
55
|
+
return this.uploadKeys.pipe(switchMap(uploadKey => this.oss.uploadWithEvents(file, `${uploadKey.keys[0]}.${ext}`, uploadKey))).subscribe({
|
|
56
|
+
next: event => {
|
|
57
|
+
switch (event.type) {
|
|
58
|
+
case HttpEventType.UploadProgress:
|
|
59
|
+
args.onProgress({ percent: (event.loaded / event.total) * 100 }, args.file);
|
|
60
|
+
break;
|
|
61
|
+
case HttpEventType.Response:
|
|
62
|
+
this.uploaded.next({
|
|
63
|
+
url: URL.createObjectURL(file),
|
|
64
|
+
...event.body
|
|
65
|
+
});
|
|
66
|
+
args.onSuccess(event.body, args.file, event);
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
error: error => {
|
|
71
|
+
args.onError(error, args.file);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
get transform() {
|
|
77
|
+
return (file) => {
|
|
78
|
+
if (!file.type?.startsWith('image/')) {
|
|
79
|
+
return of(file);
|
|
80
|
+
}
|
|
81
|
+
const { messageId } = this.message.loading('正在压缩图像');
|
|
82
|
+
const reader = new FileReader();
|
|
83
|
+
const source = fromEvent(reader, 'load').pipe(take(1), switchMap(() => this.imageCompressor.compress(reader.result)), tap(() => this.message.remove(messageId)));
|
|
84
|
+
reader.readAsDataURL(file);
|
|
85
|
+
return source;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
onChange({ type, file, event }) {
|
|
89
|
+
const media = this.data.find(o => o.uid === file.uid);
|
|
90
|
+
switch (type) {
|
|
91
|
+
case 'start': {
|
|
92
|
+
const url = URL.createObjectURL(file.originFileObj);
|
|
93
|
+
this.data = this.data.concat({
|
|
94
|
+
uid: file.uid,
|
|
95
|
+
url: url,
|
|
96
|
+
thumbnailUrl: url,
|
|
97
|
+
progress: 0.01,
|
|
98
|
+
type: 'image',
|
|
99
|
+
file: file.originFileObj
|
|
100
|
+
});
|
|
101
|
+
this.dataChange.emit(this.data);
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
case 'progress':
|
|
105
|
+
media.progress = +event.percent.toFixed(2);
|
|
106
|
+
break;
|
|
107
|
+
case 'success':
|
|
108
|
+
delete media.progress;
|
|
109
|
+
break;
|
|
110
|
+
case 'error':
|
|
111
|
+
this.data = this.data.filter(o => o.uid !== file.uid);
|
|
112
|
+
this.dataChange.emit(this.data);
|
|
113
|
+
this.error.emit(media);
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
onPreview(media) {
|
|
118
|
+
const images = this.data.map(o => ({ src: o.url || o.thumbnailUrl }));
|
|
119
|
+
const ref = this.imageService.preview(images);
|
|
120
|
+
ref.switchTo(this.data.findIndex(o => o === media));
|
|
121
|
+
}
|
|
122
|
+
onDownload(media) {
|
|
123
|
+
from(this.fileManager.download(media.url)).pipe(this.message.withLoading('正在下载')).subscribe({
|
|
124
|
+
error: () => {
|
|
125
|
+
this.message.error('下载失败');
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SunMediaUploader, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
130
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: SunMediaUploader, isStandalone: true, selector: "sun-media-uploader", inputs: { data: "data", limit: ["limit", "limit", numberAttribute], deletable: ["deletable", "deletable", booleanAttribute], uploadable: ["uploadable", "uploadable", booleanAttribute], previewable: ["previewable", "previewable", booleanAttribute], downloadable: ["downloadable", "downloadable", booleanAttribute], shape: "shape", uploadKeys: "uploadKeys", compress: ["compress", "compress", booleanAttribute] }, outputs: { uploaded: "uploaded", delete: "delete", error: "error", dataChange: "dataChange" }, host: { properties: { "class.sun-media-uploader-circle": "shape === 'circle'" }, classAttribute: "sun-media-uploader" }, ngImport: i0, template: "@for (item of data; track item) {\n <div class=\"sun-media-uploader-item\">\n <img class=\"sun-media-uploader-img\" [src]=\"item.thumbnailUrl || item.url\" />\n\n @if (item.progress) {\n <div class=\"sun-media-uploader-progress-bar\">\n <div\n class=\"sun-media-uploader-progress-inner\"\n [style]=\"{ transform: 'translateY(-' + item.progress + 'px)' }\"></div>\n <div class=\"sun-media-uploader-progress-text\">\n <div>{{ item.progress }}%</div>\n <div>\u4E0A\u4F20\u4E2D...</div>\n </div>\n </div>\n } @else {\n <div class=\"sun-media-uploader-mask\">\n @if (previewable) {\n <div class=\"sun-media-uploader-action\" (click)=\"onPreview(item)\">\n <span nz-icon nzType=\"eye\" nzTheme=\"outline\"></span>\u9884\u89C8\n </div>\n }\n @if (downloadable) {\n <div class=\"sun-media-uploader-action\" (click)=\"onDownload(item)\">\n <span nz-icon nzType=\"download\" nzTheme=\"outline\"></span>\u4E0B\u8F7D\n </div>\n }\n @if (deletable) {\n <div\n class=\"sun-media-uploader-action\"\n nz-popconfirm\n nzType=\"danger\"\n nzPopconfirmTitle=\"\u60A8\u786E\u5B9A\u8981\u5220\u9664\u8BE5\u9879\u76EE\u5417\uFF1F\"\n nzOkDanger\n (nzOnConfirm)=\"delete.next(item)\">\n <span nz-icon nzType=\"delete\" nzTheme=\"outline\"></span>\u5220\u9664\n </div>\n }\n </div>\n }\n </div>\n}\n\n<nz-upload\n nzAccept=\"image/*\"\n nzListType=\"picture-card\"\n [hidden]=\"data?.length! >= limit || !uploadable\"\n [nzShowUploadList]=\"false\"\n [nzCustomRequest]=\"upload\"\n [nzTransformFile]=\"compress ? transform : undefined\"\n (nzChange)=\"onChange($event)\">\n <div class=\"sun-media-uploader-btn\">\n <span nz-icon nzType=\"plus\"></span>\n <div class=\"sun-media-uploader-btn-text\">\u70B9\u51FB\u4E0A\u4F20</div>\n </div>\n</nz-upload>\n", styles: [".sun-media-uploader{--item-size: 100px;--item-width: var(--item-size);--item-height: var(--item-size);display:flex;flex-wrap:wrap;gap:6px}.sun-media-uploader .ant-upload-picture-card-wrapper{width:auto}.sun-media-uploader .ant-upload.ant-upload-select-picture-card{height:var(--item-height);width:var(--item-width)}.sun-media-uploader-item{position:relative;height:var(--item-height);width:var(--item-width);border:.5px solid #d9d9d9;border-radius:var(--border-radius-base);overflow:hidden}.sun-media-uploader-item:hover{border-color:var(--color-primary)}.sun-media-uploader-progress-bar,.sun-media-uploader-mask{position:absolute;top:0;left:0;height:100%;width:100%;color:#fff;filter:drop-shadow(0 0 1px rgba(0,0,0,.5))}.sun-media-uploader-progress-inner,.sun-media-uploader-mask{background-color:#0000004d}.sun-media-uploader-progress-bar{display:flex;justify-content:center;align-items:center;text-align:center}.sun-media-uploader-progress-inner{position:absolute;top:0;left:0;width:100%;height:100%;transition:transform ease-out .3s}.sun-media-uploader-progress-text{position:relative;z-index:1}.sun-media-uploader-mask{display:flex;flex-direction:column;justify-content:center;gap:2px;opacity:0;transition:all ease-out .3s}.sun-media-uploader-mask:hover{opacity:1}.sun-media-uploader-action{display:flex;justify-content:center;gap:6px;padding-right:4px;cursor:pointer}.sun-media-uploader-btn-text{margin-top:6px}.sun-media-uploader-img,.sun-media-uploader-video{width:100%;height:100%;object-fit:cover}.sun-media-uploader-circle .sun-media-uploader-item,.sun-media-uploader-circle .ant-upload.ant-upload-select-picture-card{border-radius:50%}\n"], dependencies: [{ kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1.NzIconDirective, selector: "[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzUploadModule }, { kind: "component", type: i2.NzUploadComponent, selector: "nz-upload", inputs: ["nzType", "nzLimit", "nzSize", "nzFileType", "nzAccept", "nzAction", "nzDirectory", "nzOpenFileDialogOnClick", "nzBeforeUpload", "nzCustomRequest", "nzData", "nzFilter", "nzFileList", "nzDisabled", "nzHeaders", "nzListType", "nzMultiple", "nzName", "nzShowUploadList", "nzShowButton", "nzWithCredentials", "nzRemove", "nzPreview", "nzPreviewFile", "nzPreviewIsImage", "nzTransformFile", "nzDownload", "nzIconRender", "nzFileListRender"], outputs: ["nzChange", "nzFileListChange"], exportAs: ["nzUpload"] }, { kind: "ngmodule", type: NzImageModule }, { kind: "ngmodule", type: NzPopconfirmModule }, { kind: "directive", type: i3.NzPopconfirmDirective, selector: "[nz-popconfirm]", inputs: ["nzPopconfirmArrowPointAtCenter", "nzPopconfirmTitle", "nzPopconfirmTitleContext", "nz-popconfirm", "nzPopconfirmTrigger", "nzPopconfirmPlacement", "nzPopconfirmOrigin", "nzPopconfirmMouseEnterDelay", "nzPopconfirmMouseLeaveDelay", "nzPopconfirmOverlayClassName", "nzPopconfirmOverlayStyle", "nzPopconfirmVisible", "nzOkText", "nzOkType", "nzOkDisabled", "nzOkDanger", "nzCancelText", "nzBeforeConfirm", "nzIcon", "nzCondition", "nzPopconfirmShowArrow", "nzPopconfirmBackdrop", "nzAutofocus"], outputs: ["nzPopconfirmVisibleChange", "nzOnCancel", "nzOnConfirm"], exportAs: ["nzPopconfirm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
131
|
+
}
|
|
132
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SunMediaUploader, decorators: [{
|
|
133
|
+
type: Component,
|
|
134
|
+
args: [{ selector: 'sun-media-uploader', standalone: true, imports: [
|
|
135
|
+
NzIconModule,
|
|
136
|
+
NzUploadModule,
|
|
137
|
+
NzImageModule,
|
|
138
|
+
NzPopconfirmModule
|
|
139
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
140
|
+
class: 'sun-media-uploader',
|
|
141
|
+
'[class.sun-media-uploader-circle]': `shape === 'circle'`,
|
|
142
|
+
}, template: "@for (item of data; track item) {\n <div class=\"sun-media-uploader-item\">\n <img class=\"sun-media-uploader-img\" [src]=\"item.thumbnailUrl || item.url\" />\n\n @if (item.progress) {\n <div class=\"sun-media-uploader-progress-bar\">\n <div\n class=\"sun-media-uploader-progress-inner\"\n [style]=\"{ transform: 'translateY(-' + item.progress + 'px)' }\"></div>\n <div class=\"sun-media-uploader-progress-text\">\n <div>{{ item.progress }}%</div>\n <div>\u4E0A\u4F20\u4E2D...</div>\n </div>\n </div>\n } @else {\n <div class=\"sun-media-uploader-mask\">\n @if (previewable) {\n <div class=\"sun-media-uploader-action\" (click)=\"onPreview(item)\">\n <span nz-icon nzType=\"eye\" nzTheme=\"outline\"></span>\u9884\u89C8\n </div>\n }\n @if (downloadable) {\n <div class=\"sun-media-uploader-action\" (click)=\"onDownload(item)\">\n <span nz-icon nzType=\"download\" nzTheme=\"outline\"></span>\u4E0B\u8F7D\n </div>\n }\n @if (deletable) {\n <div\n class=\"sun-media-uploader-action\"\n nz-popconfirm\n nzType=\"danger\"\n nzPopconfirmTitle=\"\u60A8\u786E\u5B9A\u8981\u5220\u9664\u8BE5\u9879\u76EE\u5417\uFF1F\"\n nzOkDanger\n (nzOnConfirm)=\"delete.next(item)\">\n <span nz-icon nzType=\"delete\" nzTheme=\"outline\"></span>\u5220\u9664\n </div>\n }\n </div>\n }\n </div>\n}\n\n<nz-upload\n nzAccept=\"image/*\"\n nzListType=\"picture-card\"\n [hidden]=\"data?.length! >= limit || !uploadable\"\n [nzShowUploadList]=\"false\"\n [nzCustomRequest]=\"upload\"\n [nzTransformFile]=\"compress ? transform : undefined\"\n (nzChange)=\"onChange($event)\">\n <div class=\"sun-media-uploader-btn\">\n <span nz-icon nzType=\"plus\"></span>\n <div class=\"sun-media-uploader-btn-text\">\u70B9\u51FB\u4E0A\u4F20</div>\n </div>\n</nz-upload>\n", styles: [".sun-media-uploader{--item-size: 100px;--item-width: var(--item-size);--item-height: var(--item-size);display:flex;flex-wrap:wrap;gap:6px}.sun-media-uploader .ant-upload-picture-card-wrapper{width:auto}.sun-media-uploader .ant-upload.ant-upload-select-picture-card{height:var(--item-height);width:var(--item-width)}.sun-media-uploader-item{position:relative;height:var(--item-height);width:var(--item-width);border:.5px solid #d9d9d9;border-radius:var(--border-radius-base);overflow:hidden}.sun-media-uploader-item:hover{border-color:var(--color-primary)}.sun-media-uploader-progress-bar,.sun-media-uploader-mask{position:absolute;top:0;left:0;height:100%;width:100%;color:#fff;filter:drop-shadow(0 0 1px rgba(0,0,0,.5))}.sun-media-uploader-progress-inner,.sun-media-uploader-mask{background-color:#0000004d}.sun-media-uploader-progress-bar{display:flex;justify-content:center;align-items:center;text-align:center}.sun-media-uploader-progress-inner{position:absolute;top:0;left:0;width:100%;height:100%;transition:transform ease-out .3s}.sun-media-uploader-progress-text{position:relative;z-index:1}.sun-media-uploader-mask{display:flex;flex-direction:column;justify-content:center;gap:2px;opacity:0;transition:all ease-out .3s}.sun-media-uploader-mask:hover{opacity:1}.sun-media-uploader-action{display:flex;justify-content:center;gap:6px;padding-right:4px;cursor:pointer}.sun-media-uploader-btn-text{margin-top:6px}.sun-media-uploader-img,.sun-media-uploader-video{width:100%;height:100%;object-fit:cover}.sun-media-uploader-circle .sun-media-uploader-item,.sun-media-uploader-circle .ant-upload.ant-upload-select-picture-card{border-radius:50%}\n"] }]
|
|
143
|
+
}], propDecorators: { data: [{
|
|
144
|
+
type: Input
|
|
145
|
+
}], limit: [{
|
|
146
|
+
type: Input,
|
|
147
|
+
args: [{ transform: numberAttribute }]
|
|
148
|
+
}], deletable: [{
|
|
149
|
+
type: Input,
|
|
150
|
+
args: [{ transform: booleanAttribute }]
|
|
151
|
+
}], uploadable: [{
|
|
152
|
+
type: Input,
|
|
153
|
+
args: [{ transform: booleanAttribute }]
|
|
154
|
+
}], previewable: [{
|
|
155
|
+
type: Input,
|
|
156
|
+
args: [{ transform: booleanAttribute }]
|
|
157
|
+
}], downloadable: [{
|
|
158
|
+
type: Input,
|
|
159
|
+
args: [{ transform: booleanAttribute }]
|
|
160
|
+
}], shape: [{
|
|
161
|
+
type: Input
|
|
162
|
+
}], uploadKeys: [{
|
|
163
|
+
type: Input
|
|
164
|
+
}], compress: [{
|
|
165
|
+
type: Input,
|
|
166
|
+
args: [{ transform: booleanAttribute }]
|
|
167
|
+
}], uploaded: [{
|
|
168
|
+
type: Output
|
|
169
|
+
}], delete: [{
|
|
170
|
+
type: Output
|
|
171
|
+
}], error: [{
|
|
172
|
+
type: Output
|
|
173
|
+
}], dataChange: [{
|
|
174
|
+
type: Output
|
|
175
|
+
}] } });
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Generated bundle index. Do not edit.
|
|
179
|
+
*/
|
|
180
|
+
|
|
181
|
+
export { SunMediaUploader };
|
|
182
|
+
//# sourceMappingURL=solar-angular-ui-zorro-media-uploader.mjs.map
|