@acorex/layout 6.5.29 → 6.5.31

Sign up to get free protection for your applications and to get access to all the features.
Files changed (26) hide show
  1. package/README.md +1 -1
  2. package/acorex-layout.d.ts +5 -5
  3. package/esm2020/acorex-layout.mjs +4 -4
  4. package/esm2020/lib/widget-board/editors/widget-size-editor/widget-size.editor.mjs +46 -46
  5. package/esm2020/lib/widget-board/editors/widget-size-editor/widget-size.module.mjs +21 -21
  6. package/esm2020/lib/widget-board/widget-board.component.mjs +450 -450
  7. package/esm2020/lib/widget-board/widget-board.module.mjs +111 -111
  8. package/esm2020/lib/widget-board/widget-config.component.mjs +82 -82
  9. package/esm2020/lib/widget-board/widget-host.component.mjs +295 -295
  10. package/esm2020/lib/widget-board/widget-save.component.mjs +79 -79
  11. package/esm2020/lib/widget-board/widget.class.mjs +127 -127
  12. package/esm2020/public-api.mjs +7 -7
  13. package/fesm2015/acorex-layout.mjs +1147 -1147
  14. package/fesm2015/acorex-layout.mjs.map +1 -1
  15. package/fesm2020/acorex-layout.mjs +1140 -1140
  16. package/fesm2020/acorex-layout.mjs.map +1 -1
  17. package/lib/widget-board/editors/widget-size-editor/widget-size.editor.d.ts +19 -19
  18. package/lib/widget-board/editors/widget-size-editor/widget-size.module.d.ts +10 -10
  19. package/lib/widget-board/widget-board.component.d.ts +61 -61
  20. package/lib/widget-board/widget-board.module.d.ts +18 -18
  21. package/lib/widget-board/widget-config.component.d.ts +23 -23
  22. package/lib/widget-board/widget-host.component.d.ts +52 -52
  23. package/lib/widget-board/widget-save.component.d.ts +19 -19
  24. package/lib/widget-board/widget.class.d.ts +58 -58
  25. package/package.json +1 -1
  26. package/public-api.d.ts +6 -6
@@ -11,1162 +11,1162 @@ import * as i1$2 from '@angular/router';
11
11
  import { RouterModule } from '@angular/router';
12
12
  import { FormsModule } from '@angular/forms';
13
13
 
14
- // @dynamic
15
- // TODO: Add Angular decorator.
16
- class AXWidgetComponent {
17
- constructor() {
18
- this.uid = AXHtmlUtil.getUID();
19
- this.onBusyChanged = new EventEmitter();
20
- this._isBusy = true;
21
- this.refreshRate = [{
22
- id: 60000 * 5,
23
- text: AXTranslator.get('dateTime.duration.format_minute').replace('{0}', '5')
24
- }];
25
- this.onConfiguredChanged = new EventEmitter();
26
- this.onConfiguredChanged.subscribe(() => {
27
- if (this.isConfigured === true && this.getRefreshRate()) {
28
- this.restartRefreshTimer();
29
- }
30
- else {
31
- this.stopRefreshTimer();
32
- }
33
- });
34
- }
35
- get isBusy() {
36
- return this._isBusy;
37
- }
38
- set isBusy(v) {
39
- if (v !== this._isBusy) {
40
- const eventData = {
41
- component: this,
42
- oldValue: this._isBusy,
43
- value: v
44
- };
45
- this._isBusy = v;
46
- this.onBusyChanged.emit(eventData);
47
- }
48
- }
49
- // ???
50
- getRefreshRate() {
51
- return Array.isArray(this.refreshRate) && this.refreshRate.length ? this.refreshRate[0].id : this.refreshRate;
52
- }
53
- startRefreshTimer() {
54
- this.intervalId = window.setInterval(this.refresh.bind(this), this.getRefreshRate());
55
- }
56
- stopRefreshTimer() {
57
- window.clearInterval(this.intervalId);
58
- }
59
- restartRefreshTimer() {
60
- this.stopRefreshTimer();
61
- this.startRefreshTimer();
62
- }
63
- ngOnDestroy() {
64
- this.stopRefreshTimer();
65
- }
66
- redraw() {
67
- }
68
- refresh() {
69
- this.restartRefreshTimer();
70
- }
71
- get isConfigured() {
72
- return true;
73
- }
74
- setValue(name, value) {
75
- this[name] = value;
76
- this.onConfiguredChanged.emit();
77
- }
78
- getValue(name) {
79
- const val = this[name];
80
- const config = this['__meta__'].config;
81
- const runtime = config.props[name]?.runtime;
82
- if (runtime && this.provideValue) {
83
- const res = this.provideValue({
84
- name,
85
- value: val,
86
- uniqueName: config.uniqueName,
87
- options: config.options,
88
- });
89
- if (this.provideValue instanceof Promise) {
90
- return res;
91
- }
92
- else {
93
- return Promise.resolve(res);
94
- }
95
- }
96
- return Promise.resolve(val);
97
- }
98
- }
99
- AXWidgetComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
100
- AXWidgetComponent.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetComponent });
101
- __decorate([
102
- propertyEditor({
103
- editorClass: 'ax/editors/widget-size',
104
- title: 'common.size',
105
- visible: false,
106
- order: -99,
107
- }),
108
- __metadata("design:type", Array)
109
- ], AXWidgetComponent.prototype, "widgetSize", void 0);
110
- __decorate([
111
- propertyEditor({
112
- editorClass: 'ax/editors/select',
113
- title: 'common.refresh-rate',
114
- visible: true,
115
- order: -98,
116
- editorOptions: {
117
- items: () => {
118
- return [1, 2, 3, 5, 10, 20, 30, 60].map(c => ({
119
- id: 60000 * c,
120
- text: AXTranslator.get('dateTime.duration.format_minute').replace('{0}', c.toString())
121
- }));
122
- },
123
- allowNull: false,
124
- allowSearch: false,
125
- selectionDataMode: 'value',
126
- selectionMode: 'single',
127
- valueField: 'id',
128
- }
129
- }),
130
- __metadata("design:type", Object)
131
- ], AXWidgetComponent.prototype, "refreshRate", void 0);
132
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetComponent, decorators: [{
133
- type: Injectable
14
+ // @dynamic
15
+ // TODO: Add Angular decorator.
16
+ class AXWidgetComponent {
17
+ constructor() {
18
+ this.uid = AXHtmlUtil.getUID();
19
+ this.onBusyChanged = new EventEmitter();
20
+ this._isBusy = true;
21
+ this.refreshRate = [{
22
+ id: 60000 * 5,
23
+ text: AXTranslator.get('dateTime.duration.format_minute').replace('{0}', '5')
24
+ }];
25
+ this.onConfiguredChanged = new EventEmitter();
26
+ this.onConfiguredChanged.subscribe(() => {
27
+ if (this.isConfigured === true && this.getRefreshRate()) {
28
+ this.restartRefreshTimer();
29
+ }
30
+ else {
31
+ this.stopRefreshTimer();
32
+ }
33
+ });
34
+ }
35
+ get isBusy() {
36
+ return this._isBusy;
37
+ }
38
+ set isBusy(v) {
39
+ if (v !== this._isBusy) {
40
+ const eventData = {
41
+ component: this,
42
+ oldValue: this._isBusy,
43
+ value: v
44
+ };
45
+ this._isBusy = v;
46
+ this.onBusyChanged.emit(eventData);
47
+ }
48
+ }
49
+ // ???
50
+ getRefreshRate() {
51
+ return Array.isArray(this.refreshRate) && this.refreshRate.length ? this.refreshRate[0].id : this.refreshRate;
52
+ }
53
+ startRefreshTimer() {
54
+ this.intervalId = window.setInterval(this.refresh.bind(this), this.getRefreshRate());
55
+ }
56
+ stopRefreshTimer() {
57
+ window.clearInterval(this.intervalId);
58
+ }
59
+ restartRefreshTimer() {
60
+ this.stopRefreshTimer();
61
+ this.startRefreshTimer();
62
+ }
63
+ ngOnDestroy() {
64
+ this.stopRefreshTimer();
65
+ }
66
+ redraw() {
67
+ }
68
+ refresh() {
69
+ this.restartRefreshTimer();
70
+ }
71
+ get isConfigured() {
72
+ return true;
73
+ }
74
+ setValue(name, value) {
75
+ this[name] = value;
76
+ this.onConfiguredChanged.emit();
77
+ }
78
+ getValue(name) {
79
+ const val = this[name];
80
+ const config = this['__meta__'].config;
81
+ const runtime = config.props[name]?.runtime;
82
+ if (runtime && this.provideValue) {
83
+ const res = this.provideValue({
84
+ name,
85
+ value: val,
86
+ uniqueName: config.uniqueName,
87
+ options: config.options,
88
+ });
89
+ if (this.provideValue instanceof Promise) {
90
+ return res;
91
+ }
92
+ else {
93
+ return Promise.resolve(res);
94
+ }
95
+ }
96
+ return Promise.resolve(val);
97
+ }
98
+ }
99
+ AXWidgetComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
100
+ AXWidgetComponent.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetComponent });
101
+ __decorate([
102
+ propertyEditor({
103
+ editorClass: 'ax/editors/widget-size',
104
+ title: 'common.size',
105
+ visible: false,
106
+ order: -99,
107
+ }),
108
+ __metadata("design:type", Array)
109
+ ], AXWidgetComponent.prototype, "widgetSize", void 0);
110
+ __decorate([
111
+ propertyEditor({
112
+ editorClass: 'ax/editors/select',
113
+ title: 'common.refresh-rate',
114
+ visible: true,
115
+ order: -98,
116
+ editorOptions: {
117
+ items: () => {
118
+ return [1, 2, 3, 5, 10, 20, 30, 60].map(c => ({
119
+ id: 60000 * c,
120
+ text: AXTranslator.get('dateTime.duration.format_minute').replace('{0}', c.toString())
121
+ }));
122
+ },
123
+ allowNull: false,
124
+ allowSearch: false,
125
+ selectionDataMode: 'value',
126
+ selectionMode: 'single',
127
+ valueField: 'id',
128
+ }
129
+ }),
130
+ __metadata("design:type", Object)
131
+ ], AXWidgetComponent.prototype, "refreshRate", void 0);
132
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetComponent, decorators: [{
133
+ type: Injectable
134
134
  }], ctorParameters: function () { return []; }, propDecorators: { widgetSize: [], refreshRate: [] } });
135
135
 
136
- class AXWidgetConfigComponent extends AXBasePopupPageComponent {
137
- constructor(cdr) {
138
- super();
139
- this.cdr = cdr;
140
- this.props = [];
141
- this.displayProps = [];
142
- this.changes = [];
143
- this.context = {};
144
- }
145
- getFooterButtons() {
146
- return [
147
- {
148
- name: 'okay',
149
- submitBehavior: true,
150
- text: AXTranslator.get('common.confirm'),
151
- style: 'success'
152
- },
153
- {
154
- name: 'cancel',
155
- cancelBehavior: true,
156
- text: AXTranslator.get('common.cancel'),
157
- style: 'danger blank'
158
- }
159
- ];
160
- }
161
- onFooterButtonClick(e) {
162
- if (e.name === 'cancel') {
163
- this.close();
164
- }
165
- if (e.name === 'okay') {
166
- this.form.validate().then(c => {
167
- if (c.result) {
168
- this.close(this.changes);
169
- }
170
- });
171
- }
172
- }
173
- handleValueChange(e) {
174
- const prop = this.changes.find(c => c.property.name === e.property.name);
175
- if (prop) {
176
- prop.value = e.value;
177
- }
178
- else {
179
- this.changes.push({ property: e.property, value: e.value });
180
- }
181
- this.updateContext();
182
- }
183
- ngOnInit() {
184
- this.displayProps = this.props.filter(c => c.property.visible !== false).sort((a, b) => a.property.order - b.property.order);
185
- this.updateContext();
186
- }
187
- updateContext() {
188
- const ctx = {};
189
- this.props.forEach(p => {
190
- ctx[p.property.name] = p.value;
191
- });
192
- this.changes.forEach(p => {
193
- ctx[p.property.name] = p.value;
194
- });
195
- this.context = ctx;
196
- }
197
- identify(index, item) {
198
- return item.property.name;
199
- }
200
- }
201
- AXWidgetConfigComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetConfigComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
202
- AXWidgetConfigComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: AXWidgetConfigComponent, selector: "ng-component", viewQueries: [{ propertyName: "form", first: true, predicate: AXValidationFormComponent, descendants: true }], usesInheritance: true, ngImport: i0, template: "<ax-page>\r\n <ax-page-content>\r\n <div class=\"container\">\r\n <ax-validation-form #form>\r\n <div class=\"row\" *ngFor=\"let p of displayProps; trackBy: identify\">\r\n <div class=\"col-12\">\r\n <ax-label>{{p.property.title | trans}}</ax-label>\r\n <ng-container ax-property-editor-renderer [property]=\"p\" [context]=\"context\" [host]=\"widget\" [validationForm]=\"form\"\r\n (onValueChange)=\"handleValueChange($event)\">\r\n </ng-container>\r\n </div>\r\n </div>\r\n </ax-validation-form>\r\n </div>\r\n </ax-page-content>\r\n</ax-page>", components: [{ type: i1.AXPageComponent, selector: "ax-page" }, { type: i1.AXPageContentComponent, selector: "ax-page-content" }, { type: i1.AXValidationFormComponent, selector: "ax-validation-form", inputs: ["validateOn"], outputs: ["onInit"] }, { type: i1.AXLabelComponent, selector: "ax-label", inputs: ["size"] }], directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.AXPropertyEditorRendererDirective, selector: "[ax-property-editor-renderer]", inputs: ["property", "validationForm", "context", "host", "groupId"], outputs: ["onValueChange"] }], pipes: { "trans": i1$1.AXTranslatorPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
203
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetConfigComponent, decorators: [{
204
- type: Component,
205
- args: [{ encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ax-page>\r\n <ax-page-content>\r\n <div class=\"container\">\r\n <ax-validation-form #form>\r\n <div class=\"row\" *ngFor=\"let p of displayProps; trackBy: identify\">\r\n <div class=\"col-12\">\r\n <ax-label>{{p.property.title | trans}}</ax-label>\r\n <ng-container ax-property-editor-renderer [property]=\"p\" [context]=\"context\" [host]=\"widget\" [validationForm]=\"form\"\r\n (onValueChange)=\"handleValueChange($event)\">\r\n </ng-container>\r\n </div>\r\n </div>\r\n </ax-validation-form>\r\n </div>\r\n </ax-page-content>\r\n</ax-page>" }]
206
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { form: [{
207
- type: ViewChild,
208
- args: [AXValidationFormComponent]
136
+ class AXWidgetConfigComponent extends AXBasePopupPageComponent {
137
+ constructor(cdr) {
138
+ super();
139
+ this.cdr = cdr;
140
+ this.props = [];
141
+ this.displayProps = [];
142
+ this.changes = [];
143
+ this.context = {};
144
+ }
145
+ getFooterButtons() {
146
+ return [
147
+ {
148
+ name: 'okay',
149
+ submitBehavior: true,
150
+ text: AXTranslator.get('common.confirm'),
151
+ style: 'success'
152
+ },
153
+ {
154
+ name: 'cancel',
155
+ cancelBehavior: true,
156
+ text: AXTranslator.get('common.cancel'),
157
+ style: 'danger blank'
158
+ }
159
+ ];
160
+ }
161
+ onFooterButtonClick(e) {
162
+ if (e.name === 'cancel') {
163
+ this.close();
164
+ }
165
+ if (e.name === 'okay') {
166
+ this.form.validate().then(c => {
167
+ if (c.result) {
168
+ this.close(this.changes);
169
+ }
170
+ });
171
+ }
172
+ }
173
+ handleValueChange(e) {
174
+ const prop = this.changes.find(c => c.property.name === e.property.name);
175
+ if (prop) {
176
+ prop.value = e.value;
177
+ }
178
+ else {
179
+ this.changes.push({ property: e.property, value: e.value });
180
+ }
181
+ this.updateContext();
182
+ }
183
+ ngOnInit() {
184
+ this.displayProps = this.props.filter(c => c.property.visible !== false).sort((a, b) => a.property.order - b.property.order);
185
+ this.updateContext();
186
+ }
187
+ updateContext() {
188
+ const ctx = {};
189
+ this.props.forEach(p => {
190
+ ctx[p.property.name] = p.value;
191
+ });
192
+ this.changes.forEach(p => {
193
+ ctx[p.property.name] = p.value;
194
+ });
195
+ this.context = ctx;
196
+ }
197
+ identify(index, item) {
198
+ return item.property.name;
199
+ }
200
+ }
201
+ AXWidgetConfigComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetConfigComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
202
+ AXWidgetConfigComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: AXWidgetConfigComponent, selector: "ng-component", viewQueries: [{ propertyName: "form", first: true, predicate: AXValidationFormComponent, descendants: true }], usesInheritance: true, ngImport: i0, template: "<ax-page>\n <ax-page-content>\n <div class=\"container\">\n <ax-validation-form #form>\n <div class=\"row\" *ngFor=\"let p of displayProps; trackBy: identify\">\n <div class=\"col-12\">\n <ax-label>{{p.property.title | trans}}</ax-label>\n <ng-container ax-property-editor-renderer [property]=\"p\" [context]=\"context\" [host]=\"widget\" [validationForm]=\"form\"\n (onValueChange)=\"handleValueChange($event)\">\n </ng-container>\n </div>\n </div>\n </ax-validation-form>\n </div>\n </ax-page-content>\n</ax-page>", components: [{ type: i1.AXPageComponent, selector: "ax-page" }, { type: i1.AXPageContentComponent, selector: "ax-page-content" }, { type: i1.AXValidationFormComponent, selector: "ax-validation-form", inputs: ["validateOn"], outputs: ["onInit"] }, { type: i1.AXLabelComponent, selector: "ax-label", inputs: ["size"] }], directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.AXPropertyEditorRendererDirective, selector: "[ax-property-editor-renderer]", inputs: ["property", "validationForm", "context", "host", "groupId"], outputs: ["onValueChange"] }], pipes: { "trans": i1$1.AXTranslatorPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
203
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetConfigComponent, decorators: [{
204
+ type: Component,
205
+ args: [{ encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ax-page>\n <ax-page-content>\n <div class=\"container\">\n <ax-validation-form #form>\n <div class=\"row\" *ngFor=\"let p of displayProps; trackBy: identify\">\n <div class=\"col-12\">\n <ax-label>{{p.property.title | trans}}</ax-label>\n <ng-container ax-property-editor-renderer [property]=\"p\" [context]=\"context\" [host]=\"widget\" [validationForm]=\"form\"\n (onValueChange)=\"handleValueChange($event)\">\n </ng-container>\n </div>\n </div>\n </ax-validation-form>\n </div>\n </ax-page-content>\n</ax-page>" }]
206
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { form: [{
207
+ type: ViewChild,
208
+ args: [AXValidationFormComponent]
209
209
  }] } });
210
210
 
211
- class AXWidgetSaveComponent extends AXBasePopupPageComponent {
212
- constructor() {
213
- super(...arguments);
214
- this.props = [];
215
- }
216
- getFooterButtons() {
217
- return [
218
- {
219
- name: 'okay',
220
- submitBehavior: true,
221
- text: AXTranslator.get('common.confirm'),
222
- style: 'ax success'
223
- },
224
- {
225
- name: 'cancel',
226
- cancelBehavior: true,
227
- text: AXTranslator.get('common.cancel'),
228
- style: 'ax light'
229
- }
230
- ];
231
- }
232
- ngOnInit() {
233
- const titleProp = this.props.find(c => c.property.name === 'title' || c.property.name === 'name');
234
- const title = titleProp?.value || this.config.title;
235
- const pp = {};
236
- this.props?.forEach(c => {
237
- pp[c.property.name] = c.property;
238
- });
239
- this.data = {
240
- component: this.config.component,
241
- title,
242
- uniqueName: `${this.config.uniqueName}-${AXHtmlUtil.getUID()}`,
243
- options: AXObjectUtil.deepJSONClone(this.config.options),
244
- props: AXObjectUtil.deepJSONClone(pp)
245
- };
246
- this.displayProps = this.props
247
- .filter(c => c.property.visible !== false)
248
- .sort((a, b) => a.property.order - b.property.order)
249
- .map(c => ({
250
- name: c.property.name,
251
- title: c.property.title,
252
- allow: true
253
- }));
254
- }
255
- onFooterButtonClick(e) {
256
- if (e.name === 'cancel') {
257
- this.close();
258
- }
259
- if (e.name === 'okay') {
260
- this.props.forEach(p => {
261
- const pp = this.displayProps.find(c => c.name === p.property.name);
262
- if (pp == null || !pp.allow) {
263
- let ppp = this.data.props[p.property.name];
264
- if (ppp) {
265
- ppp.visible = false;
266
- }
267
- else {
268
- ppp = { visible: false };
269
- }
270
- }
271
- });
272
- this.close(this.data);
273
- }
274
- }
275
- }
276
- AXWidgetSaveComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetSaveComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
277
- AXWidgetSaveComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: AXWidgetSaveComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<ax-page>\r\n <ax-page-content>\r\n <div class=\"container\">\r\n <div class=\"row\">\r\n <div class=\"col-12\">\r\n <ax-form-group>\r\n <ax-label>{{'common.title' | trans}}</ax-label>\r\n <ax-text-box [(value)]=\"data.title\"></ax-text-box>\r\n </ax-form-group>\r\n </div>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col-12\">\r\n <ax-form-group>\r\n <ax-label>{{'common.description' | trans}}</ax-label>\r\n <ax-text-area [(value)]=\"data.description\"></ax-text-area>\r\n </ax-form-group>\r\n </div>\r\n </div>\r\n <!-- <div class=\"row\">\r\n <div class=\"col-12\">\r\n <ax-form-group>\r\n <ax-label>{{'common.uniquename' | trans}}</ax-label>\r\n <ax-text-box></ax-text-box>\r\n </ax-form-group>\r\n </div>\r\n </div> -->\r\n <div class=\"row\" style=\"margin-block-end: var(--ax-size-md);margin-block-start: var(--ax-size-md);\">\r\n <div class=\"col-12\">\r\n <ax-fieldset caption=\"{{'widget-board.configurable-props' | trans}}\">\r\n <div class=\"row\" *ngFor=\"let prop of displayProps\">\r\n <div class=\"col-12\" style=\"margin-block-end: var(--ax-size-sm)\">\r\n <ax-check-box [(value)]=\"prop.allow\" label=\"{{ prop.title | trans }}\">\r\n\r\n </ax-check-box>\r\n </div>\r\n </div>\r\n </ax-fieldset>\r\n </div>\r\n </div>\r\n </div>\r\n </ax-page-content>\r\n</ax-page>", components: [{ type: i1.AXPageComponent, selector: "ax-page" }, { type: i1.AXPageContentComponent, selector: "ax-page-content" }, { type: i1.AXFormGroupComponent, selector: "ax-form-group", inputs: ["size"] }, { type: i1.AXLabelComponent, selector: "ax-label", inputs: ["size"] }, { type: i1.AXTextBoxComponent, selector: "ax-text-box", inputs: ["mask", "type", "showMask", "maxLength", "maskGuid", "maskPlaceholder", "maskKeepCharPositions"] }, { type: i1.AXTextAreaComponent, selector: "ax-text-area", inputs: ["rows", "cols", "maxLength"] }, { type: i1.AXFieldsetComponent, selector: "ax-fieldset", inputs: ["size", "caption", "allowCollapse"] }, { type: i1.AXCheckBoxComponent, selector: "ax-check-box", inputs: ["readonly", "disabled", "size", "label", "tabIndex", "indeterminate", "value"], outputs: ["onValueChanged", "valueChange", "onClick"] }], directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "trans": i1$1.AXTranslatorPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
278
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetSaveComponent, decorators: [{
279
- type: Component,
280
- args: [{ encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ax-page>\r\n <ax-page-content>\r\n <div class=\"container\">\r\n <div class=\"row\">\r\n <div class=\"col-12\">\r\n <ax-form-group>\r\n <ax-label>{{'common.title' | trans}}</ax-label>\r\n <ax-text-box [(value)]=\"data.title\"></ax-text-box>\r\n </ax-form-group>\r\n </div>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col-12\">\r\n <ax-form-group>\r\n <ax-label>{{'common.description' | trans}}</ax-label>\r\n <ax-text-area [(value)]=\"data.description\"></ax-text-area>\r\n </ax-form-group>\r\n </div>\r\n </div>\r\n <!-- <div class=\"row\">\r\n <div class=\"col-12\">\r\n <ax-form-group>\r\n <ax-label>{{'common.uniquename' | trans}}</ax-label>\r\n <ax-text-box></ax-text-box>\r\n </ax-form-group>\r\n </div>\r\n </div> -->\r\n <div class=\"row\" style=\"margin-block-end: var(--ax-size-md);margin-block-start: var(--ax-size-md);\">\r\n <div class=\"col-12\">\r\n <ax-fieldset caption=\"{{'widget-board.configurable-props' | trans}}\">\r\n <div class=\"row\" *ngFor=\"let prop of displayProps\">\r\n <div class=\"col-12\" style=\"margin-block-end: var(--ax-size-sm)\">\r\n <ax-check-box [(value)]=\"prop.allow\" label=\"{{ prop.title | trans }}\">\r\n\r\n </ax-check-box>\r\n </div>\r\n </div>\r\n </ax-fieldset>\r\n </div>\r\n </div>\r\n </div>\r\n </ax-page-content>\r\n</ax-page>" }]
211
+ class AXWidgetSaveComponent extends AXBasePopupPageComponent {
212
+ constructor() {
213
+ super(...arguments);
214
+ this.props = [];
215
+ }
216
+ getFooterButtons() {
217
+ return [
218
+ {
219
+ name: 'okay',
220
+ submitBehavior: true,
221
+ text: AXTranslator.get('common.confirm'),
222
+ style: 'ax success'
223
+ },
224
+ {
225
+ name: 'cancel',
226
+ cancelBehavior: true,
227
+ text: AXTranslator.get('common.cancel'),
228
+ style: 'ax light'
229
+ }
230
+ ];
231
+ }
232
+ ngOnInit() {
233
+ const titleProp = this.props.find(c => c.property.name === 'title' || c.property.name === 'name');
234
+ const title = titleProp?.value || this.config.title;
235
+ const pp = {};
236
+ this.props?.forEach(c => {
237
+ pp[c.property.name] = c.property;
238
+ });
239
+ this.data = {
240
+ component: this.config.component,
241
+ title,
242
+ uniqueName: `${this.config.uniqueName}-${AXHtmlUtil.getUID()}`,
243
+ options: AXObjectUtil.deepJSONClone(this.config.options),
244
+ props: AXObjectUtil.deepJSONClone(pp)
245
+ };
246
+ this.displayProps = this.props
247
+ .filter(c => c.property.visible !== false)
248
+ .sort((a, b) => a.property.order - b.property.order)
249
+ .map(c => ({
250
+ name: c.property.name,
251
+ title: c.property.title,
252
+ allow: true
253
+ }));
254
+ }
255
+ onFooterButtonClick(e) {
256
+ if (e.name === 'cancel') {
257
+ this.close();
258
+ }
259
+ if (e.name === 'okay') {
260
+ this.props.forEach(p => {
261
+ const pp = this.displayProps.find(c => c.name === p.property.name);
262
+ if (pp == null || !pp.allow) {
263
+ let ppp = this.data.props[p.property.name];
264
+ if (ppp) {
265
+ ppp.visible = false;
266
+ }
267
+ else {
268
+ ppp = { visible: false };
269
+ }
270
+ }
271
+ });
272
+ this.close(this.data);
273
+ }
274
+ }
275
+ }
276
+ AXWidgetSaveComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetSaveComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
277
+ AXWidgetSaveComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: AXWidgetSaveComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<ax-page>\n <ax-page-content>\n <div class=\"container\">\n <div class=\"row\">\n <div class=\"col-12\">\n <ax-form-group>\n <ax-label>{{'common.title' | trans}}</ax-label>\n <ax-text-box [(value)]=\"data.title\"></ax-text-box>\n </ax-form-group>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-12\">\n <ax-form-group>\n <ax-label>{{'common.description' | trans}}</ax-label>\n <ax-text-area [(value)]=\"data.description\"></ax-text-area>\n </ax-form-group>\n </div>\n </div>\n <!-- <div class=\"row\">\n <div class=\"col-12\">\n <ax-form-group>\n <ax-label>{{'common.uniquename' | trans}}</ax-label>\n <ax-text-box></ax-text-box>\n </ax-form-group>\n </div>\n </div> -->\n <div class=\"row\" style=\"margin-block-end: var(--ax-size-md);margin-block-start: var(--ax-size-md);\">\n <div class=\"col-12\">\n <ax-fieldset caption=\"{{'widget-board.configurable-props' | trans}}\">\n <div class=\"row\" *ngFor=\"let prop of displayProps\">\n <div class=\"col-12\" style=\"margin-block-end: var(--ax-size-sm)\">\n <ax-check-box [(value)]=\"prop.allow\" label=\"{{ prop.title | trans }}\">\n\n </ax-check-box>\n </div>\n </div>\n </ax-fieldset>\n </div>\n </div>\n </div>\n </ax-page-content>\n</ax-page>", components: [{ type: i1.AXPageComponent, selector: "ax-page" }, { type: i1.AXPageContentComponent, selector: "ax-page-content" }, { type: i1.AXFormGroupComponent, selector: "ax-form-group", inputs: ["size"] }, { type: i1.AXLabelComponent, selector: "ax-label", inputs: ["size"] }, { type: i1.AXTextBoxComponent, selector: "ax-text-box", inputs: ["mask", "type", "showMask", "maxLength", "maskGuid", "maskPlaceholder", "maskKeepCharPositions"] }, { type: i1.AXTextAreaComponent, selector: "ax-text-area", inputs: ["rows", "cols", "maxLength"] }, { type: i1.AXFieldsetComponent, selector: "ax-fieldset", inputs: ["size", "caption", "allowCollapse"] }, { type: i1.AXCheckBoxComponent, selector: "ax-check-box", inputs: ["readonly", "disabled", "size", "label", "tabIndex", "indeterminate", "value"], outputs: ["onValueChanged", "valueChange", "onClick"] }], directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "trans": i1$1.AXTranslatorPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
278
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetSaveComponent, decorators: [{
279
+ type: Component,
280
+ args: [{ encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ax-page>\n <ax-page-content>\n <div class=\"container\">\n <div class=\"row\">\n <div class=\"col-12\">\n <ax-form-group>\n <ax-label>{{'common.title' | trans}}</ax-label>\n <ax-text-box [(value)]=\"data.title\"></ax-text-box>\n </ax-form-group>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-12\">\n <ax-form-group>\n <ax-label>{{'common.description' | trans}}</ax-label>\n <ax-text-area [(value)]=\"data.description\"></ax-text-area>\n </ax-form-group>\n </div>\n </div>\n <!-- <div class=\"row\">\n <div class=\"col-12\">\n <ax-form-group>\n <ax-label>{{'common.uniquename' | trans}}</ax-label>\n <ax-text-box></ax-text-box>\n </ax-form-group>\n </div>\n </div> -->\n <div class=\"row\" style=\"margin-block-end: var(--ax-size-md);margin-block-start: var(--ax-size-md);\">\n <div class=\"col-12\">\n <ax-fieldset caption=\"{{'widget-board.configurable-props' | trans}}\">\n <div class=\"row\" *ngFor=\"let prop of displayProps\">\n <div class=\"col-12\" style=\"margin-block-end: var(--ax-size-sm)\">\n <ax-check-box [(value)]=\"prop.allow\" label=\"{{ prop.title | trans }}\">\n\n </ax-check-box>\n </div>\n </div>\n </ax-fieldset>\n </div>\n </div>\n </div>\n </ax-page-content>\n</ax-page>" }]
281
281
  }] });
282
282
 
283
- class AXWidgetHostComponent {
284
- constructor(ref, componentFactoryResolver, rendererService, cdr, popup, loadingService) {
285
- this.ref = ref;
286
- this.componentFactoryResolver = componentFactoryResolver;
287
- this.rendererService = rendererService;
288
- this.cdr = cdr;
289
- this.popup = popup;
290
- this.loadingService = loadingService;
291
- this._hasProps = false;
292
- this._hasMenu = false;
293
- this.configMenuItem = [
294
- {
295
- icon: 'far fa-ellipsis-h',
296
- items: []
297
- }
298
- ];
299
- this.onRemove = new EventEmitter();
300
- this.onConfigChanged = new EventEmitter();
301
- this.onResized = new EventEmitter();
302
- this.onSave = new EventEmitter();
303
- this.readonly = false;
304
- this._isLoading = false;
305
- this.sizeX = 1;
306
- this.sizeY = 1;
307
- this.col = 1;
308
- this.row = 1;
309
- }
310
- get widget() {
311
- return this._widget;
312
- }
313
- get element() {
314
- return this.ref.nativeElement;
315
- }
316
- get isLoading() {
317
- return this._isLoading;
318
- }
319
- set isLoading(v) {
320
- this._isLoading = v;
321
- if (this._loadingId && !v) {
322
- this.loadingService.hide(this._loadingId);
323
- this._loadingId = null;
324
- }
325
- if (v) {
326
- this._loadingId = this.loadingService.show(this.ref.nativeElement);
327
- }
328
- }
329
- get isConfigured() {
330
- return this._widget?.isConfigured || false;
331
- }
332
- ngOnInit() {
333
- this.isLoading = true;
334
- }
335
- async ngAfterViewInit() {
336
- let component;
337
- if (typeof this.config.component === 'string') {
338
- const route = await this.rendererService.findLoadedComponentByRoute(this.config.component, 20);
339
- component = route?.component;
340
- }
341
- else if (typeof this.config.component === 'function') {
342
- component = this.config.component;
343
- }
344
- if (component == null) {
345
- console.error(`Invalid Widget Component!`, this.config);
346
- this.onRemove.emit(this);
347
- return;
348
- }
349
- const widgetFactory = this.componentFactoryResolver.resolveComponentFactory(component);
350
- this.componentRef = this.vc.createComponent(widgetFactory);
351
- this._widget = this.componentRef.instance;
352
- this._widget.provideValue = this.provideValue;
353
- if (this._widget.onBusyChanged) {
354
- this._widget.onBusyChanged.subscribe((d) => {
355
- if (!this._widget.widgetSize) {
356
- this._widget.setValue('widgetSize', [this.sizeX, this.sizeY]);
357
- }
358
- else {
359
- this.setSizeFromOptions();
360
- }
361
- this.isLoading = d.value;
362
- this.cdr.detectChanges();
363
- });
364
- }
365
- if (this._widget.onConfiguredChanged) {
366
- this._widget.onConfiguredChanged.subscribe(() => {
367
- this.setSizeFromOptions();
368
- });
369
- }
370
- //
371
- if (this.config.options) {
372
- Object.assign(this._widget, this.config.options);
373
- }
374
- this._hasProps = AXPropertyDecorators.getProperties(this._widget).length > 0;
375
- this.isLoading = false;
376
- this.config['__meta__'].instance = this;
377
- this._widget['__meta__'] = {};
378
- this._widget['__meta__'].config = this.config;
379
- //
380
- this.configMenuItem[0].items.push({
381
- name: 'refresh',
382
- icon: 'far fa-undo',
383
- text: AXTranslator.get('common.refresh'),
384
- onClick: () => {
385
- this?.widget?.refresh();
386
- }
387
- });
388
- //
389
- if (this._hasProps) {
390
- this.configMenuItem[0].items.push({
391
- name: 'configs',
392
- icon: 'far fa-cogs',
393
- text: AXTranslator.get('common.configs'),
394
- onClick: () => {
395
- this.openConfigDialog();
396
- }
397
- });
398
- }
399
- this.configMenuItem[0].items.push({
400
- name: 'save',
401
- icon: 'far fa-save',
402
- text: AXTranslator.get('common.save-as'),
403
- onClick: () => {
404
- this.openSaveDialog();
405
- }
406
- });
407
- if (true) {
408
- this.configMenuItem[0].items.push({
409
- name: 'remove',
410
- icon: 'far fa-times',
411
- style: 'ax danger blank',
412
- text: AXTranslator.get('common.remove'),
413
- onClick: () => {
414
- this.onRemove.emit(this);
415
- }
416
- });
417
- }
418
- this._hasMenu = this.configMenuItem[0].items.length > 0;
419
- this.cdr.detectChanges();
420
- }
421
- setSizeFromOptions() {
422
- this._widget.getValue('widgetSize').then(c => {
423
- const oldSizeX = this.sizeX;
424
- const oldSizeY = this.sizeY;
425
- if (c && Array.isArray(c) && (oldSizeX !== c[0] || oldSizeY !== c[1])) {
426
- this.config.sizeX = this.sizeX = c[0];
427
- this.config.sizeY = this.sizeY = c[1];
428
- this.onResized.emit({
429
- component: this._widget,
430
- config: this.config
431
- });
432
- }
433
- this.cdr.detectChanges();
434
- });
435
- }
436
- remove(e) {
437
- e.preventDefault();
438
- e.stopPropagation();
439
- if (!this.readonly)
440
- this.onRemove.emit(this);
441
- return false;
442
- }
443
- handleConfig(e) {
444
- e.preventDefault();
445
- e.stopPropagation();
446
- if (!this.readonly)
447
- this.openConfigDialog();
448
- return false;
449
- }
450
- openConfigDialog() {
451
- const ppp = this.getMergedProps();
452
- this.popup.open(AXWidgetConfigComponent, {
453
- title: AXTranslator.get('common.configs'),
454
- size: 'sm',
455
- data: {
456
- props: ppp.map(c => ({ property: c.options, value: this._widget[c.options.name] })),
457
- widget: this.widget
458
- }
459
- }).then(c => {
460
- if (c.data) {
461
- if (!this.config.options) {
462
- this.config.options = {};
463
- }
464
- c.data.forEach(p => {
465
- this._widget.setValue(p.property.name, p.value);
466
- this.config.options[p.property.name] = p.value;
467
- });
468
- this.emitConfigChanged();
469
- this._widget.redraw();
470
- this.cdr.detectChanges();
471
- }
472
- });
473
- }
474
- openSaveDialog() {
475
- const ppp = this.getMergedProps();
476
- this.popup.open(AXWidgetSaveComponent, {
477
- title: AXTranslator.get('common.save-as'),
478
- size: 'sm',
479
- data: {
480
- config: this.config,
481
- props: ppp.map(c => ({ property: c.options, value: this._widget[c.options.name] }))
482
- }
483
- }).then(c => {
484
- if (c.data) {
485
- this.onSave.emit({
486
- component: this._widget,
487
- data: c.data
488
- });
489
- }
490
- });
491
- }
492
- handleOptionClick(e) {
493
- e.preventDefault();
494
- e.stopPropagation();
495
- this.openConfigDialog();
496
- return false;
497
- }
498
- ngOnDestroy() {
499
- this.vc.clear();
500
- if (this.componentRef) {
501
- this.componentRef.destroy();
502
- }
503
- }
504
- getMergedProps() {
505
- const ppp = AXObjectUtil.deepCopy(AXPropertyDecorators.getProperties(this._widget));
506
- for (const key in this.config.props) {
507
- if (Object.prototype.hasOwnProperty.call(this.config.props, key)) {
508
- const newP = this.config.props[key];
509
- const existPropDec = ppp.find(p => p.property === key);
510
- if (existPropDec) {
511
- Object.assign(existPropDec.options, newP);
512
- }
513
- }
514
- }
515
- return ppp;
516
- }
517
- emitConfigChanged() {
518
- this.onConfigChanged.emit({
519
- component: this._widget,
520
- config: this.config
521
- });
522
- }
523
- }
524
- AXWidgetHostComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetHostComponent, deps: [{ token: i0.ElementRef }, { token: i0.ComponentFactoryResolver }, { token: i1$1.AXRenderService }, { token: i0.ChangeDetectorRef }, { token: i1.AXPopupService }, { token: i1.AXLoadingService }], target: i0.ɵɵFactoryTarget.Component });
525
- AXWidgetHostComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: AXWidgetHostComponent, selector: "ax-widget-host", inputs: { provideValue: "provideValue", config: "config", readonly: "readonly", sizeX: "sizeX", sizeY: "sizeY", col: "col", row: "row" }, outputs: { onRemove: "onRemove", onConfigChanged: "onConfigChanged", onResized: "onResized", onSave: "onSave" }, host: { attributes: { "tabindex": "0" }, properties: { "attr.data-size-x": "this.sizeX", "attr.data-size-y": "this.sizeY", "attr.data-col": "this.col", "attr.data-row": "this.row" }, classAttribute: "ax widget-host" }, viewQueries: [{ propertyName: "vc", first: true, predicate: ["vc"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<div class='widget-container'>\r\n <div class=\"widget-config-overlay\" *ngIf=\"!isConfigured\" (click)=\"handleConfig($event)\">\r\n <div class=\"widget-title\">{{config.title}}</div>\r\n <div class=\"widget-config-box\">\r\n <div class=\"config-title\">{{ 'widget-board.configure' | trans}}</div>\r\n <div class=\"config-icon\" *ngIf=\"!readonly\"><i class=\"fas fa-cogs fa-5x\" aria-hidden=\"true\"></i></div>\r\n </div>\r\n </div>\r\n <div class='widget-edit-overlay' >\r\n <div class='widget-edit-menu'>\r\n <button class=\"widget-edit-menu-button\" (click)=\"handleConfig($event)\"\r\n (mousedown)=\"$event.stopPropagation()\" *ngIf=\"_hasProps\" (mouseup)=\"$event.stopPropagation()\">\r\n <i class=\"far fa-cogs\" aria-hidden=\"true\"></i>\r\n </button>\r\n <button class=\"widget-edit-menu-button\" (click)=\"remove($event)\" (mousedown)=\"$event.stopPropagation()\"\r\n (mouseup)=\"$event.stopPropagation()\">\r\n <i class=\"far fa-times\" aria-hidden=\"true\"></i>\r\n </button>\r\n </div>\r\n\r\n </div>\r\n <div class=\"widget-options-menu\" *ngIf=\"_hasMenu && !readonly\">\r\n <ax-menu [items]='configMenuItem' direction=\"horizontal\"></ax-menu>\r\n </div>\r\n <!-- <ax-loading-panel [visible]=\"isBusy\">\r\n </ax-loading-panel> -->\r\n <div class=\"widget-content\">\r\n <ng-container #vc></ng-container>\r\n </div>\r\n</div>", components: [{ type: i1.AXMenuComponent, selector: "ax-menu", inputs: ["menuTemplate", "rtl", "size", "selection", "mode", "target", "floatAlignment", "floatPlacemnet", "direction", "items"], outputs: ["onItemClick"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "trans": i1$1.AXTranslatorPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
526
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetHostComponent, decorators: [{
527
- type: Component,
528
- args: [{ selector: 'ax-widget-host', host: { class: 'ax widget-host', tabindex: '0' }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class='widget-container'>\r\n <div class=\"widget-config-overlay\" *ngIf=\"!isConfigured\" (click)=\"handleConfig($event)\">\r\n <div class=\"widget-title\">{{config.title}}</div>\r\n <div class=\"widget-config-box\">\r\n <div class=\"config-title\">{{ 'widget-board.configure' | trans}}</div>\r\n <div class=\"config-icon\" *ngIf=\"!readonly\"><i class=\"fas fa-cogs fa-5x\" aria-hidden=\"true\"></i></div>\r\n </div>\r\n </div>\r\n <div class='widget-edit-overlay' >\r\n <div class='widget-edit-menu'>\r\n <button class=\"widget-edit-menu-button\" (click)=\"handleConfig($event)\"\r\n (mousedown)=\"$event.stopPropagation()\" *ngIf=\"_hasProps\" (mouseup)=\"$event.stopPropagation()\">\r\n <i class=\"far fa-cogs\" aria-hidden=\"true\"></i>\r\n </button>\r\n <button class=\"widget-edit-menu-button\" (click)=\"remove($event)\" (mousedown)=\"$event.stopPropagation()\"\r\n (mouseup)=\"$event.stopPropagation()\">\r\n <i class=\"far fa-times\" aria-hidden=\"true\"></i>\r\n </button>\r\n </div>\r\n\r\n </div>\r\n <div class=\"widget-options-menu\" *ngIf=\"_hasMenu && !readonly\">\r\n <ax-menu [items]='configMenuItem' direction=\"horizontal\"></ax-menu>\r\n </div>\r\n <!-- <ax-loading-panel [visible]=\"isBusy\">\r\n </ax-loading-panel> -->\r\n <div class=\"widget-content\">\r\n <ng-container #vc></ng-container>\r\n </div>\r\n</div>" }]
529
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ComponentFactoryResolver }, { type: i1$1.AXRenderService }, { type: i0.ChangeDetectorRef }, { type: i1.AXPopupService }, { type: i1.AXLoadingService }]; }, propDecorators: { provideValue: [{
530
- type: Input
531
- }], onRemove: [{
532
- type: Output
533
- }], onConfigChanged: [{
534
- type: Output
535
- }], onResized: [{
536
- type: Output
537
- }], onSave: [{
538
- type: Output
539
- }], config: [{
540
- type: Input
541
- }], vc: [{
542
- type: ViewChild,
543
- args: ['vc', { read: ViewContainerRef }]
544
- }], readonly: [{
545
- type: Input
546
- }], sizeX: [{
547
- type: HostBinding,
548
- args: ['attr.data-size-x']
549
- }, {
550
- type: Input
551
- }], sizeY: [{
552
- type: HostBinding,
553
- args: ['attr.data-size-y']
554
- }, {
555
- type: Input
556
- }], col: [{
557
- type: HostBinding,
558
- args: ['attr.data-col']
559
- }, {
560
- type: Input
561
- }], row: [{
562
- type: HostBinding,
563
- args: ['attr.data-row']
564
- }, {
565
- type: Input
283
+ class AXWidgetHostComponent {
284
+ constructor(ref, componentFactoryResolver, rendererService, cdr, popup, loadingService) {
285
+ this.ref = ref;
286
+ this.componentFactoryResolver = componentFactoryResolver;
287
+ this.rendererService = rendererService;
288
+ this.cdr = cdr;
289
+ this.popup = popup;
290
+ this.loadingService = loadingService;
291
+ this._hasProps = false;
292
+ this._hasMenu = false;
293
+ this.configMenuItem = [
294
+ {
295
+ icon: 'far fa-ellipsis-h',
296
+ items: []
297
+ }
298
+ ];
299
+ this.onRemove = new EventEmitter();
300
+ this.onConfigChanged = new EventEmitter();
301
+ this.onResized = new EventEmitter();
302
+ this.onSave = new EventEmitter();
303
+ this.readonly = false;
304
+ this._isLoading = false;
305
+ this.sizeX = 1;
306
+ this.sizeY = 1;
307
+ this.col = 1;
308
+ this.row = 1;
309
+ }
310
+ get widget() {
311
+ return this._widget;
312
+ }
313
+ get element() {
314
+ return this.ref.nativeElement;
315
+ }
316
+ get isLoading() {
317
+ return this._isLoading;
318
+ }
319
+ set isLoading(v) {
320
+ this._isLoading = v;
321
+ if (this._loadingId && !v) {
322
+ this.loadingService.hide(this._loadingId);
323
+ this._loadingId = null;
324
+ }
325
+ if (v) {
326
+ this._loadingId = this.loadingService.show(this.ref.nativeElement);
327
+ }
328
+ }
329
+ get isConfigured() {
330
+ return this._widget?.isConfigured || false;
331
+ }
332
+ ngOnInit() {
333
+ this.isLoading = true;
334
+ }
335
+ async ngAfterViewInit() {
336
+ let component;
337
+ if (typeof this.config.component === 'string') {
338
+ const route = await this.rendererService.findLoadedComponentByRoute(this.config.component, 20);
339
+ component = route?.component;
340
+ }
341
+ else if (typeof this.config.component === 'function') {
342
+ component = this.config.component;
343
+ }
344
+ if (component == null) {
345
+ console.error(`Invalid Widget Component!`, this.config);
346
+ this.onRemove.emit(this);
347
+ return;
348
+ }
349
+ const widgetFactory = this.componentFactoryResolver.resolveComponentFactory(component);
350
+ this.componentRef = this.vc.createComponent(widgetFactory);
351
+ this._widget = this.componentRef.instance;
352
+ this._widget.provideValue = this.provideValue;
353
+ if (this._widget.onBusyChanged) {
354
+ this._widget.onBusyChanged.subscribe((d) => {
355
+ if (!this._widget.widgetSize) {
356
+ this._widget.setValue('widgetSize', [this.sizeX, this.sizeY]);
357
+ }
358
+ else {
359
+ this.setSizeFromOptions();
360
+ }
361
+ this.isLoading = d.value;
362
+ this.cdr.detectChanges();
363
+ });
364
+ }
365
+ if (this._widget.onConfiguredChanged) {
366
+ this._widget.onConfiguredChanged.subscribe(() => {
367
+ this.setSizeFromOptions();
368
+ });
369
+ }
370
+ //
371
+ if (this.config.options) {
372
+ Object.assign(this._widget, this.config.options);
373
+ }
374
+ this._hasProps = AXPropertyDecorators.getProperties(this._widget).length > 0;
375
+ this.isLoading = false;
376
+ this.config['__meta__'].instance = this;
377
+ this._widget['__meta__'] = {};
378
+ this._widget['__meta__'].config = this.config;
379
+ //
380
+ this.configMenuItem[0].items.push({
381
+ name: 'refresh',
382
+ icon: 'far fa-undo',
383
+ text: AXTranslator.get('common.refresh'),
384
+ onClick: () => {
385
+ this?.widget?.refresh();
386
+ }
387
+ });
388
+ //
389
+ if (this._hasProps) {
390
+ this.configMenuItem[0].items.push({
391
+ name: 'configs',
392
+ icon: 'far fa-cogs',
393
+ text: AXTranslator.get('common.configs'),
394
+ onClick: () => {
395
+ this.openConfigDialog();
396
+ }
397
+ });
398
+ }
399
+ this.configMenuItem[0].items.push({
400
+ name: 'save',
401
+ icon: 'far fa-save',
402
+ text: AXTranslator.get('common.save-as'),
403
+ onClick: () => {
404
+ this.openSaveDialog();
405
+ }
406
+ });
407
+ if (true) {
408
+ this.configMenuItem[0].items.push({
409
+ name: 'remove',
410
+ icon: 'far fa-times',
411
+ style: 'ax danger blank',
412
+ text: AXTranslator.get('common.remove'),
413
+ onClick: () => {
414
+ this.onRemove.emit(this);
415
+ }
416
+ });
417
+ }
418
+ this._hasMenu = this.configMenuItem[0].items.length > 0;
419
+ this.cdr.detectChanges();
420
+ }
421
+ setSizeFromOptions() {
422
+ this._widget.getValue('widgetSize').then(c => {
423
+ const oldSizeX = this.sizeX;
424
+ const oldSizeY = this.sizeY;
425
+ if (c && Array.isArray(c) && (oldSizeX !== c[0] || oldSizeY !== c[1])) {
426
+ this.config.sizeX = this.sizeX = c[0];
427
+ this.config.sizeY = this.sizeY = c[1];
428
+ this.onResized.emit({
429
+ component: this._widget,
430
+ config: this.config
431
+ });
432
+ }
433
+ this.cdr.detectChanges();
434
+ });
435
+ }
436
+ remove(e) {
437
+ e.preventDefault();
438
+ e.stopPropagation();
439
+ if (!this.readonly)
440
+ this.onRemove.emit(this);
441
+ return false;
442
+ }
443
+ handleConfig(e) {
444
+ e.preventDefault();
445
+ e.stopPropagation();
446
+ if (!this.readonly)
447
+ this.openConfigDialog();
448
+ return false;
449
+ }
450
+ openConfigDialog() {
451
+ const ppp = this.getMergedProps();
452
+ this.popup.open(AXWidgetConfigComponent, {
453
+ title: AXTranslator.get('common.configs'),
454
+ size: 'sm',
455
+ data: {
456
+ props: ppp.map(c => ({ property: c.options, value: this._widget[c.options.name] })),
457
+ widget: this.widget
458
+ }
459
+ }).then(c => {
460
+ if (c.data) {
461
+ if (!this.config.options) {
462
+ this.config.options = {};
463
+ }
464
+ c.data.forEach(p => {
465
+ this._widget.setValue(p.property.name, p.value);
466
+ this.config.options[p.property.name] = p.value;
467
+ });
468
+ this.emitConfigChanged();
469
+ this._widget.redraw();
470
+ this.cdr.detectChanges();
471
+ }
472
+ });
473
+ }
474
+ openSaveDialog() {
475
+ const ppp = this.getMergedProps();
476
+ this.popup.open(AXWidgetSaveComponent, {
477
+ title: AXTranslator.get('common.save-as'),
478
+ size: 'sm',
479
+ data: {
480
+ config: this.config,
481
+ props: ppp.map(c => ({ property: c.options, value: this._widget[c.options.name] }))
482
+ }
483
+ }).then(c => {
484
+ if (c.data) {
485
+ this.onSave.emit({
486
+ component: this._widget,
487
+ data: c.data
488
+ });
489
+ }
490
+ });
491
+ }
492
+ handleOptionClick(e) {
493
+ e.preventDefault();
494
+ e.stopPropagation();
495
+ this.openConfigDialog();
496
+ return false;
497
+ }
498
+ ngOnDestroy() {
499
+ this.vc.clear();
500
+ if (this.componentRef) {
501
+ this.componentRef.destroy();
502
+ }
503
+ }
504
+ getMergedProps() {
505
+ const ppp = AXObjectUtil.deepCopy(AXPropertyDecorators.getProperties(this._widget));
506
+ for (const key in this.config.props) {
507
+ if (Object.prototype.hasOwnProperty.call(this.config.props, key)) {
508
+ const newP = this.config.props[key];
509
+ const existPropDec = ppp.find(p => p.property === key);
510
+ if (existPropDec) {
511
+ Object.assign(existPropDec.options, newP);
512
+ }
513
+ }
514
+ }
515
+ return ppp;
516
+ }
517
+ emitConfigChanged() {
518
+ this.onConfigChanged.emit({
519
+ component: this._widget,
520
+ config: this.config
521
+ });
522
+ }
523
+ }
524
+ AXWidgetHostComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetHostComponent, deps: [{ token: i0.ElementRef }, { token: i0.ComponentFactoryResolver }, { token: i1$1.AXRenderService }, { token: i0.ChangeDetectorRef }, { token: i1.AXPopupService }, { token: i1.AXLoadingService }], target: i0.ɵɵFactoryTarget.Component });
525
+ AXWidgetHostComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: AXWidgetHostComponent, selector: "ax-widget-host", inputs: { provideValue: "provideValue", config: "config", readonly: "readonly", sizeX: "sizeX", sizeY: "sizeY", col: "col", row: "row" }, outputs: { onRemove: "onRemove", onConfigChanged: "onConfigChanged", onResized: "onResized", onSave: "onSave" }, host: { attributes: { "tabindex": "0" }, properties: { "attr.data-size-x": "this.sizeX", "attr.data-size-y": "this.sizeY", "attr.data-col": "this.col", "attr.data-row": "this.row" }, classAttribute: "ax widget-host" }, viewQueries: [{ propertyName: "vc", first: true, predicate: ["vc"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<div class='widget-container'>\n <div class=\"widget-config-overlay\" *ngIf=\"!isConfigured\" (click)=\"handleConfig($event)\">\n <div class=\"widget-title\">{{config.title}}</div>\n <div class=\"widget-config-box\">\n <div class=\"config-title\">{{ 'widget-board.configure' | trans}}</div>\n <div class=\"config-icon\" *ngIf=\"!readonly\"><i class=\"fas fa-cogs fa-5x\" aria-hidden=\"true\"></i></div>\n </div>\n </div>\n <div class='widget-edit-overlay' >\n <div class='widget-edit-menu'>\n <button class=\"widget-edit-menu-button\" (click)=\"handleConfig($event)\"\n (mousedown)=\"$event.stopPropagation()\" *ngIf=\"_hasProps\" (mouseup)=\"$event.stopPropagation()\">\n <i class=\"far fa-cogs\" aria-hidden=\"true\"></i>\n </button>\n <button class=\"widget-edit-menu-button\" (click)=\"remove($event)\" (mousedown)=\"$event.stopPropagation()\"\n (mouseup)=\"$event.stopPropagation()\">\n <i class=\"far fa-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n </div>\n <div class=\"widget-options-menu\" *ngIf=\"_hasMenu && !readonly\">\n <ax-menu [items]='configMenuItem' direction=\"horizontal\"></ax-menu>\n </div>\n <!-- <ax-loading-panel [visible]=\"isBusy\">\n </ax-loading-panel> -->\n <div class=\"widget-content\">\n <ng-container #vc></ng-container>\n </div>\n</div>", components: [{ type: i1.AXMenuComponent, selector: "ax-menu", inputs: ["menuTemplate", "rtl", "size", "selection", "mode", "target", "floatAlignment", "floatPlacemnet", "direction", "items"], outputs: ["onItemClick"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "trans": i1$1.AXTranslatorPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
526
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetHostComponent, decorators: [{
527
+ type: Component,
528
+ args: [{ selector: 'ax-widget-host', host: { class: 'ax widget-host', tabindex: '0' }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class='widget-container'>\n <div class=\"widget-config-overlay\" *ngIf=\"!isConfigured\" (click)=\"handleConfig($event)\">\n <div class=\"widget-title\">{{config.title}}</div>\n <div class=\"widget-config-box\">\n <div class=\"config-title\">{{ 'widget-board.configure' | trans}}</div>\n <div class=\"config-icon\" *ngIf=\"!readonly\"><i class=\"fas fa-cogs fa-5x\" aria-hidden=\"true\"></i></div>\n </div>\n </div>\n <div class='widget-edit-overlay' >\n <div class='widget-edit-menu'>\n <button class=\"widget-edit-menu-button\" (click)=\"handleConfig($event)\"\n (mousedown)=\"$event.stopPropagation()\" *ngIf=\"_hasProps\" (mouseup)=\"$event.stopPropagation()\">\n <i class=\"far fa-cogs\" aria-hidden=\"true\"></i>\n </button>\n <button class=\"widget-edit-menu-button\" (click)=\"remove($event)\" (mousedown)=\"$event.stopPropagation()\"\n (mouseup)=\"$event.stopPropagation()\">\n <i class=\"far fa-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n </div>\n <div class=\"widget-options-menu\" *ngIf=\"_hasMenu && !readonly\">\n <ax-menu [items]='configMenuItem' direction=\"horizontal\"></ax-menu>\n </div>\n <!-- <ax-loading-panel [visible]=\"isBusy\">\n </ax-loading-panel> -->\n <div class=\"widget-content\">\n <ng-container #vc></ng-container>\n </div>\n</div>" }]
529
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ComponentFactoryResolver }, { type: i1$1.AXRenderService }, { type: i0.ChangeDetectorRef }, { type: i1.AXPopupService }, { type: i1.AXLoadingService }]; }, propDecorators: { provideValue: [{
530
+ type: Input
531
+ }], onRemove: [{
532
+ type: Output
533
+ }], onConfigChanged: [{
534
+ type: Output
535
+ }], onResized: [{
536
+ type: Output
537
+ }], onSave: [{
538
+ type: Output
539
+ }], config: [{
540
+ type: Input
541
+ }], vc: [{
542
+ type: ViewChild,
543
+ args: ['vc', { read: ViewContainerRef }]
544
+ }], readonly: [{
545
+ type: Input
546
+ }], sizeX: [{
547
+ type: HostBinding,
548
+ args: ['attr.data-size-x']
549
+ }, {
550
+ type: Input
551
+ }], sizeY: [{
552
+ type: HostBinding,
553
+ args: ['attr.data-size-y']
554
+ }, {
555
+ type: Input
556
+ }], col: [{
557
+ type: HostBinding,
558
+ args: ['attr.data-col']
559
+ }, {
560
+ type: Input
561
+ }], row: [{
562
+ type: HostBinding,
563
+ args: ['attr.data-row']
564
+ }, {
565
+ type: Input
566
566
  }] } });
567
567
 
568
- class AXWidgetBoardComponent {
569
- constructor(ref, zone, cdr) {
570
- this.ref = ref;
571
- this.zone = zone;
572
- this.cdr = cdr;
573
- this.widgets = [];
574
- this.galleryItems = [];
575
- this.tileSize = 80;
576
- this.gapSize = 5;
577
- this.readonly = false;
578
- this.newWidget = null;
579
- this._isInEditing = false;
580
- this.isDragging = false;
581
- this.DATA_COL = 'data-col';
582
- this.DATA_ROW = 'data-row';
583
- this.DATA_SIZE_X = 'data-size-x';
584
- this.DATA_SIZE_Y = 'data-size-y';
585
- this.DATA_OLD_COL = 'data-old-col';
586
- this.DATA_OLD_ROW = 'data-old-row';
587
- this.onConfigChanged = new EventEmitter();
588
- this.onWidgetSave = new EventEmitter();
589
- }
590
- isInEditing() {
591
- return this._isInEditing;
592
- }
593
- ngOnInit() {
594
- if (this.rtl == null) {
595
- this.rtl = window.getComputedStyle(this.ref.nativeElement, null).getPropertyValue('direction') === 'rtl';
596
- }
597
- }
598
- ngAfterViewInit() {
599
- this.zone.runOutsideAngular((c) => {
600
- const style = document.createElement('style');
601
- style.type = 'text/css';
602
- this.ref.nativeElement.appendChild(style);
603
- // add css data classes
604
- for (let i = 1; i <= 50; i++) {
605
- style.innerHTML += `[${this.DATA_COL}="${i}"] { ${this.rtl ? 'right' : 'left'}: ${(i - 1) * (this.tileSize + this.gapSize)}px; }`;
606
- style.innerHTML += `[${this.DATA_ROW}="${i}"] { top: ${(i - 1) * (this.tileSize + this.gapSize)}px; }`;
607
- style.innerHTML += `[${this.DATA_SIZE_X}="${i}"] { width: ${(i * this.tileSize) + ((i - 1) * this.gapSize)}px; }`;
608
- style.innerHTML += `[${this.DATA_SIZE_Y}="${i}"] { height: ${(i * this.tileSize) + ((i - 1) * this.gapSize)}px; }`;
609
- }
610
- });
611
- }
612
- calcGridSize() {
613
- this.zone.runOutsideAngular(() => {
614
- const width = (Math.max(...this.widgets.map((c) => c.col + c.sizeX - 1))) * (this.tileSize + this.gapSize);
615
- const height = (Math.max(...this.widgets.map((c) => c.row + c.sizeY - 1))) * (this.tileSize + this.gapSize);
616
- this.container.nativeElement.style.width = width + 'px';
617
- this.container.nativeElement.style.height = height + 'px';
618
- });
619
- }
620
- toggleEdit() {
621
- this._isInEditing ? this.finishEdit() : this.startEdit();
622
- }
623
- dragStart(e) {
624
- e.preventDefault();
625
- e.stopPropagation();
626
- this.zone.runOutsideAngular(() => {
627
- if (this._isInEditing && e.which === 1) {
628
- this.dragItem = e.currentTarget;
629
- this.dragItem.setAttribute('data-x-offset', (this.dragItem.offsetLeft - e.clientX).toString());
630
- //
631
- this.dragItem.setAttribute('data-y-offset', (this.dragItem.offsetTop - e.clientY).toString());
632
- this.dragItem.classList.add('widget-dragging');
633
- this.dragItem.classList.remove('animate__animated', 'animate__pulse');
634
- }
635
- });
636
- return false;
637
- }
638
- removePositionData() {
639
- this.zone.runOutsideAngular(() => {
640
- if (this.dragItem && this._isInEditing && this.dragItem.getAttribute(this.DATA_OLD_COL) == null) {
641
- this.dragItem.setAttribute(this.DATA_OLD_COL, this.dragItem.getAttribute(this.DATA_COL));
642
- this.dragItem.setAttribute(this.DATA_OLD_ROW, this.dragItem.getAttribute(this.DATA_ROW));
643
- this.dragItem.removeAttribute(this.DATA_COL);
644
- this.dragItem.removeAttribute(this.DATA_ROW);
645
- }
646
- });
647
- }
648
- resetPositionData() {
649
- this.zone.runOutsideAngular(() => {
650
- if (this.dragItem && this._isInEditing) {
651
- this.setPosition(this.dragItem, this.dragItem.getAttribute(this.DATA_OLD_COL), this.dragItem.getAttribute(this.DATA_OLD_ROW));
652
- }
653
- });
654
- }
655
- setPosition(element, col, row) {
656
- this.zone.runOutsideAngular(() => {
657
- element.setAttribute(this.DATA_COL, col);
658
- element.setAttribute(this.DATA_ROW, row);
659
- element.removeAttribute(this.DATA_OLD_COL);
660
- element.removeAttribute(this.DATA_OLD_ROW);
661
- element.style.removeProperty('top');
662
- element.style.removeProperty('left');
663
- const widget = this.widgets.find(c => c['__meta__'].instance.element === element);
664
- widget.col = Number(col);
665
- widget.row = Number(row);
666
- });
667
- }
668
- drag(e) {
669
- e.preventDefault();
670
- e.stopPropagation();
671
- this.zone.runOutsideAngular(() => {
672
- if (this.dragItem && this._isInEditing) {
673
- this.isDragging = true;
674
- this.addPlaceholder();
675
- const xOffset = Number(this.dragItem.getAttribute('data-x-offset'));
676
- const yOffset = Number(this.dragItem.getAttribute('data-y-offset'));
677
- this.dragItem.style.left = e.clientX + xOffset + 'px';
678
- this.dragItem.style.top = e.clientY + yOffset + 'px';
679
- //
680
- this.detectBestPlacement();
681
- this.removePositionData();
682
- }
683
- });
684
- return false;
685
- }
686
- dragEnd(e) {
687
- this.zone.runOutsideAngular(() => {
688
- if (this.dragItem && this._isInEditing && this.isDragging) {
689
- this.dragItem.classList.remove('widget-dragging');
690
- this.dragItem.classList.add('animate__animated', 'animate__pulse');
691
- //
692
- const p = this.container.nativeElement.querySelector('.widget-blank-placeholder');
693
- if (this.newWidget) {
694
- const w = {
695
- uniqueName: this.newWidget.uniqueName,
696
- component: this.newWidget.component,
697
- title: this.newWidget.title,
698
- options: this.newWidget.options,
699
- sizeX: this.newWidget.sizeX,
700
- sizeY: this.newWidget.sizeY,
701
- col: Number(p.getAttribute(this.DATA_COL)),
702
- row: Number(p.getAttribute(this.DATA_ROW))
703
- };
704
- this.widgets.push(w);
705
- this.newWidget = null;
706
- this.container.nativeElement.removeChild(this.dragItem);
707
- this.zone.run(() => {
708
- this.cdr.detectChanges();
709
- this.calcGridSize();
710
- setTimeout(() => {
711
- w['__meta__'].instance.element.addEventListener('mousedown', this.dragStart.bind(this), false);
712
- }, 1000);
713
- });
714
- }
715
- else {
716
- if (p) {
717
- this.setPosition(this.dragItem, p.getAttribute(this.DATA_COL), p.getAttribute(this.DATA_ROW));
718
- }
719
- else {
720
- this.setPosition(this.dragItem, this.dragItem.getAttribute(this.DATA_OLD_COL), this.dragItem.getAttribute(this.DATA_OLD_ROW));
721
- }
722
- }
723
- //
724
- this.removePlaceholder();
725
- this.dragItem = null;
726
- this.calcGridSize();
727
- this.emitConfigChanged('config');
728
- }
729
- this.isDragging = false;
730
- });
731
- }
732
- detectFirstEmptySlot(w) {
733
- const xTile = Math.floor(this.ref.nativeElement.parentElement.offsetWidth / this.tileSize);
734
- for (let j = 1; j <= 100; j++) {
735
- for (let i = 1; i <= xTile - w.sizeX; i++) {
736
- const rec = new AXClientRec({
737
- left: i,
738
- top: j,
739
- width: w.sizeX,
740
- height: w.sizeY
741
- });
742
- const el = this.widgets.filter(c => c !== w).find((c) => rec.intersect({
743
- left: c.col,
744
- top: c.row,
745
- width: c.sizeX,
746
- height: c.sizeY
747
- }));
748
- if (el == null) {
749
- w.col = i;
750
- w.row = j;
751
- return;
752
- }
753
- }
754
- }
755
- }
756
- detectBestPlacement() {
757
- this.zone.runOutsideAngular(() => {
758
- const p = this.container.nativeElement.querySelector('.widget-blank-placeholder');
759
- let col = Math.ceil(this.dragItem.offsetLeft / this.tileSize);
760
- if (this.rtl) {
761
- col = Math.ceil((this.container.nativeElement.clientWidth - (this.dragItem.offsetLeft + this.dragItem.clientWidth)) / this.tileSize);
762
- }
763
- let row = Math.ceil(this.dragItem.offsetTop / this.tileSize);
764
- if (col < 1) {
765
- col = 1;
766
- }
767
- if (row < 1) {
768
- row = 1;
769
- }
770
- const widgets = Array.from(this.ref.nativeElement.querySelectorAll('.widget-host')).map((c) => c);
771
- p.setAttribute(this.DATA_COL, col.toString());
772
- p.setAttribute(this.DATA_ROW, row.toString());
773
- const collision = widgets.filter(c => c !== this.dragItem).some(c => AXHtmlUtil.collision(c, this.dragItem));
774
- if (collision) {
775
- this.removePlaceholder();
776
- }
777
- });
778
- }
779
- addPlaceholder() {
780
- this.zone.runOutsideAngular(() => {
781
- this.removePlaceholder();
782
- if (this.dragItem) {
783
- const p = document.createElement('div');
784
- p.classList.add('widget-blank-placeholder');
785
- p.setAttribute(this.DATA_COL, this.dragItem.getAttribute(this.DATA_COL));
786
- p.setAttribute(this.DATA_ROW, this.dragItem.getAttribute(this.DATA_ROW));
787
- p.setAttribute(this.DATA_SIZE_X, this.dragItem.getAttribute(this.DATA_SIZE_X));
788
- p.setAttribute(this.DATA_SIZE_Y, this.dragItem.getAttribute(this.DATA_SIZE_Y));
789
- this.container.nativeElement.appendChild(p);
790
- }
791
- });
792
- }
793
- removePlaceholder() {
794
- const p = this.container.nativeElement.querySelector('.widget-blank-placeholder');
795
- p?.remove();
796
- }
797
- startEdit() {
798
- this._isInEditing = true;
799
- this.calcGridSize();
800
- this.ref.nativeElement.classList.add('grid-background');
801
- const bg = this.ref.nativeElement;
802
- bg.style.setProperty('background-position', `${this.rtl ? 'right' : 'left'} top`);
803
- // tslint:disable-next-line: max-line-length
804
- const pattern = `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${this.tileSize + this.gapSize}" height="${this.tileSize + this.gapSize}"> <rect style="fill: %23dadada" x="${this.rtl ? this.gapSize : 0}" width="${this.tileSize}" height="${this.tileSize}" y="0"></rect></svg>')`;
805
- bg.style.setProperty('background-image', pattern);
806
- //
807
- const widgets = Array.from(this.ref.nativeElement.querySelectorAll('.widget-host'));
808
- widgets.forEach((w) => {
809
- w.addEventListener('mousedown', this.dragStart.bind(this), false);
810
- });
811
- this.ref.nativeElement.addEventListener('mousemove', this.drag.bind(this), false);
812
- this.ref.nativeElement.addEventListener('mouseup', this.dragEnd.bind(this), false);
813
- }
814
- finishEdit() {
815
- this.ref.nativeElement.classList.remove('grid-background');
816
- const bg = this.ref.nativeElement;
817
- bg.style.removeProperty('background-image');
818
- //
819
- this._isInEditing = false;
820
- const widgets = Array.from(this.ref.nativeElement.querySelectorAll('.widget-host'));
821
- widgets.forEach((w) => {
822
- w.removeEventListener('mousedown', this.dragStart.bind(this), false);
823
- });
824
- this.ref.nativeElement.removeEventListener('mousemove', this.drag.bind(this), false);
825
- this.ref.nativeElement.removeEventListener('mouseup', this.dragEnd.bind(this), false);
826
- this.emitConfigChanged('config');
827
- }
828
- addWidget(widget) {
829
- this.zone.runOutsideAngular(() => {
830
- this.newWidget = {
831
- uniqueName: widget.uniqueName,
832
- component: widget.component,
833
- title: widget.title,
834
- col: 1,
835
- row: 1,
836
- sizeX: widget.sizeX,
837
- sizeY: widget.sizeY,
838
- options: widget.options,
839
- props: widget.props
840
- };
841
- this.detectFirstEmptySlot(this.newWidget);
842
- const w = {
843
- uniqueName: this.newWidget.uniqueName,
844
- component: this.newWidget.component,
845
- title: this.newWidget.title,
846
- options: this.newWidget.options,
847
- props: this.newWidget.props,
848
- sizeX: this.newWidget.sizeX,
849
- sizeY: this.newWidget.sizeY,
850
- col: this.newWidget.col,
851
- row: this.newWidget.row
852
- };
853
- this.widgets.push(w);
854
- this.newWidget = null;
855
- this.zone.run(() => {
856
- this.cdr.detectChanges();
857
- this.calcGridSize();
858
- this.emitConfigChanged('add');
859
- setTimeout(() => {
860
- w['__meta__'].instance.element.addEventListener('mousedown', this.dragStart.bind(this), false);
861
- }, 1000);
862
- });
863
- });
864
- }
865
- handleOnRemove(w) {
866
- w.element.classList.add('animate__animated', 'animate__zoomOut');
867
- w.element.addEventListener('animationend', () => {
868
- this.widgets = this.widgets.filter((c) => c.__meta__.id !== w.config.__meta__.id);
869
- this.cdr.detectChanges();
870
- this.calcGridSize();
871
- this.emitConfigChanged('remove');
872
- });
873
- }
874
- handleOnSave(e) {
875
- this.onWidgetSave.emit(e);
876
- }
877
- trackByFn(index, item) {
878
- if (!item['__meta__']?.id) {
879
- item['__meta__'] = {};
880
- item['__meta__'].id = AXHtmlUtil.getUID();
881
- }
882
- return item['__meta__']?.id;
883
- }
884
- load(widgets) {
885
- this.clear();
886
- return new Promise((resolve, reject) => {
887
- if (widgets) {
888
- const loadedWidgets = [];
889
- if (typeof widgets === 'string') {
890
- try {
891
- loadedWidgets.push(...JSON.parse(widgets));
892
- this.emitConfigChanged('load');
893
- }
894
- catch (error) {
895
- reject('Invalid widget json data!');
896
- }
897
- }
898
- else {
899
- loadedWidgets.push(...widgets);
900
- this.emitConfigChanged('load');
901
- }
902
- let intervalId = -1;
903
- const loadFunc = () => {
904
- if (this.galleryItems && this.galleryItems.length > 0) {
905
- loadedWidgets.forEach(w => {
906
- const gitem = this.galleryItems.find(c => c.uniqueName === w.uniqueName);
907
- if (gitem) {
908
- w.component = gitem.component;
909
- if (gitem.props) {
910
- w.props = JSON.parse(JSON.stringify(gitem.props));
911
- }
912
- }
913
- });
914
- this.widgets.push(...loadedWidgets);
915
- this.emitConfigChanged('load');
916
- window.clearInterval(intervalId);
917
- this.cdr.detectChanges();
918
- resolve();
919
- }
920
- };
921
- intervalId = window.setInterval(loadFunc, 200);
922
- }
923
- else {
924
- resolve();
925
- }
926
- });
927
- }
928
- clear() {
929
- if (this.widgets.length) {
930
- this.widgets = [];
931
- this.cdr.detectChanges();
932
- this.emitConfigChanged('clear');
933
- }
934
- }
935
- save() {
936
- const obj = this.widgets.map(c => ({
937
- uniqueName: c.uniqueName,
938
- component: c.component,
939
- title: c.title,
940
- sizeX: c.sizeX,
941
- sizeY: c.sizeY,
942
- col: c.col,
943
- row: c.row,
944
- options: c.options,
945
- props: c.props
946
- }));
947
- return Promise.resolve(JSON.stringify(obj));
948
- }
949
- refresh() {
950
- this.widgetHosts.forEach(host => {
951
- host.widget.refresh();
952
- });
953
- }
954
- handleOnConfigChanged(e) {
955
- this.cdr.detectChanges();
956
- this.emitConfigChanged('config');
957
- }
958
- handleOnResizedChanged(e) {
959
- this.detectFirstEmptySlot(e.config);
960
- this.cdr.detectChanges();
961
- this.emitConfigChanged('config');
962
- }
963
- //private resizeChangeObserver: any;
964
- emitConfigChanged(mode) {
965
- // if (!this.resizeChangeObserver) {
966
- // this.resizeChangeObserver = new Observable();
967
- // Observable.create(observer => {
968
- // this.resizeChangeObserver = observer;
969
- // })
970
- // .pipe(debounceTime(750))
971
- // .pipe(distinctUntilChanged())
972
- // .subscribe(c => {
973
- // this.onConfigChanged.emit({
974
- // component: this
975
- // });
976
- // });
977
- // }
978
- // this.resizeChangeObserver.next(new Date());
979
- this.onConfigChanged.emit({
980
- component: this,
981
- mode
982
- });
983
- }
984
- }
985
- AXWidgetBoardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetBoardComponent, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
986
- AXWidgetBoardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: AXWidgetBoardComponent, selector: "ax-widget-board", inputs: { galleryItems: "galleryItems", tileSize: "tileSize", gapSize: "gapSize", readonly: "readonly", provideValue: "provideValue" }, outputs: { onConfigChanged: "onConfigChanged", onWidgetSave: "onWidgetSave" }, host: { classAttribute: "ax widget-board" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }, { propertyName: "widgetHosts", predicate: AXWidgetHostComponent, descendants: true }], ngImport: i0, template: "<div class=\"widgets-container\" [class.rtl]=\"rtl\" #container>\r\n <ax-widget-host *ngFor=\"let w of widgets;trackBy: trackByFn\" [config]='w' [sizeX]=\"w.sizeX\" [readonly]=\"readonly || w.readonly\"\r\n [sizeY]=\"w.sizeY\" [col]=\"w.col\" [row]=\"w.row\" (onRemove)=\"handleOnRemove($event)\" (onSave)=\"handleOnSave($event)\"\r\n (onConfigChanged)=\"handleOnConfigChanged($event)\" (onResized)=\"handleOnResizedChanged($event)\"\r\n [provideValue]=\"provideValue\">\r\n </ax-widget-host>\r\n</div>\r\n", styles: [".widget-board{display:inline-block;margin:15px 20px;min-width:calc(100% - 40px);min-height:calc(100% - 34px);--animate-duration: .5s;background-repeat:no-repeat}.widget-board.grid-background{background-repeat:repeat!important}.widget-board.grid-background .widgets-container .widget-host{touch-action:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.widget-board.grid-background .widgets-container .widget-host .widget-edit-overlay{display:block;cursor:move}.widget-board.grid-background .widgets-container .widget-host.widget-dragging{z-index:1000}.widget-board.grid-background .widgets-container .widget-host:focus{outline-width:1px;outline-style:solid;outline-color:var(--ax-primary-color)}.widget-board.grid-background .widget-blank-placeholder{background:var(--ax-primary-trans-light-color);position:absolute}.widget-board .widgets-container{position:relative;touch-action:none}.widget-board .widgets-container.rtl .widget-host .widget-options-menu{right:unset!important;left:0!important}.widget-board .widgets-container .widget-host{position:absolute;background:#fff;box-shadow:2px 2px 3px #dadada;z-index:0}.widget-board .widgets-container .widget-host .widget-content{width:100%;height:100%;display:flex;flex-direction:column}.widget-board .widgets-container .widget-host .widget-content .widget-title{padding:var(--ax-size-md);text-align:start;font-size:1.5em;position:absolute}.widget-board .widgets-container .widget-host .widget-edit-loading{display:none;background:rgba(255,255,255,.85);position:absolute;width:100%;height:100%;top:0;left:0;z-index:2;display:flex}.widget-board .widgets-container .widget-host .widget-config-overlay{position:absolute;background:white;width:100%;height:100%;top:0;left:0;z-index:1;padding:var(--ax-size-md);cursor:pointer}.widget-board .widgets-container .widget-host .widget-config-overlay:hover .widget-title{text-decoration:underline}.widget-board .widgets-container .widget-host .widget-config-overlay .widget-title{text-align:start;font-size:1.5em}.widget-board .widgets-container .widget-host .widget-config-overlay .widget-config-box{align-self:center;text-align:center;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:var(--ax-gray-dark-color)}.widget-board .widgets-container .widget-host .widget-config-overlay .widget-config-box .config-title{font-size:1.2em;margin-bottom:var(--ax-size-md)}.widget-board .widgets-container .widget-host .widget-edit-overlay{display:none;background:rgba(255,255,255,.5);position:absolute;width:100%;height:100%;top:0;left:0;z-index:10}.widget-board .widgets-container .widget-host .widget-edit-overlay .widget-edit-menu{margin:6px;text-align:end;float:inline-end;opacity:1;transition:opacity 1s ease}.widget-board .widgets-container .widget-host .widget-edit-overlay .widget-edit-menu .widget-edit-menu-button{display:inline-block;background-color:#f0f0f0;border-radius:1px;border:2px solid #fff;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;padding:0;height:32px;width:32px;cursor:pointer;color:#666}.widget-board .widgets-container .widget-host .widget-edit-overlay .widget-edit-menu .widget-edit-menu-button:hover{border-color:#a6a6a6;background-color:#c8c8c8}.widget-board .widgets-container .widget-host .widget-options-menu{display:none;position:absolute;top:0;right:0;z-index:2;cursor:pointer;padding:2px 5px}.widget-board .widgets-container .widget-host .widget-options-menu:hover{background-color:#f0f0f0}.widget-board .widgets-container .widget-host .widget-container{padding:1px;height:100%}.widget-board .widgets-container .widget-host .widget-container:hover .widget-options-menu{display:block}\n"], components: [{ type: AXWidgetHostComponent, selector: "ax-widget-host", inputs: ["provideValue", "config", "readonly", "sizeX", "sizeY", "col", "row"], outputs: ["onRemove", "onConfigChanged", "onResized", "onSave"] }], directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
987
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetBoardComponent, decorators: [{
988
- type: Component,
989
- args: [{ selector: 'ax-widget-board', host: { class: 'ax widget-board' }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"widgets-container\" [class.rtl]=\"rtl\" #container>\r\n <ax-widget-host *ngFor=\"let w of widgets;trackBy: trackByFn\" [config]='w' [sizeX]=\"w.sizeX\" [readonly]=\"readonly || w.readonly\"\r\n [sizeY]=\"w.sizeY\" [col]=\"w.col\" [row]=\"w.row\" (onRemove)=\"handleOnRemove($event)\" (onSave)=\"handleOnSave($event)\"\r\n (onConfigChanged)=\"handleOnConfigChanged($event)\" (onResized)=\"handleOnResizedChanged($event)\"\r\n [provideValue]=\"provideValue\">\r\n </ax-widget-host>\r\n</div>\r\n", styles: [".widget-board{display:inline-block;margin:15px 20px;min-width:calc(100% - 40px);min-height:calc(100% - 34px);--animate-duration: .5s;background-repeat:no-repeat}.widget-board.grid-background{background-repeat:repeat!important}.widget-board.grid-background .widgets-container .widget-host{touch-action:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.widget-board.grid-background .widgets-container .widget-host .widget-edit-overlay{display:block;cursor:move}.widget-board.grid-background .widgets-container .widget-host.widget-dragging{z-index:1000}.widget-board.grid-background .widgets-container .widget-host:focus{outline-width:1px;outline-style:solid;outline-color:var(--ax-primary-color)}.widget-board.grid-background .widget-blank-placeholder{background:var(--ax-primary-trans-light-color);position:absolute}.widget-board .widgets-container{position:relative;touch-action:none}.widget-board .widgets-container.rtl .widget-host .widget-options-menu{right:unset!important;left:0!important}.widget-board .widgets-container .widget-host{position:absolute;background:#fff;box-shadow:2px 2px 3px #dadada;z-index:0}.widget-board .widgets-container .widget-host .widget-content{width:100%;height:100%;display:flex;flex-direction:column}.widget-board .widgets-container .widget-host .widget-content .widget-title{padding:var(--ax-size-md);text-align:start;font-size:1.5em;position:absolute}.widget-board .widgets-container .widget-host .widget-edit-loading{display:none;background:rgba(255,255,255,.85);position:absolute;width:100%;height:100%;top:0;left:0;z-index:2;display:flex}.widget-board .widgets-container .widget-host .widget-config-overlay{position:absolute;background:white;width:100%;height:100%;top:0;left:0;z-index:1;padding:var(--ax-size-md);cursor:pointer}.widget-board .widgets-container .widget-host .widget-config-overlay:hover .widget-title{text-decoration:underline}.widget-board .widgets-container .widget-host .widget-config-overlay .widget-title{text-align:start;font-size:1.5em}.widget-board .widgets-container .widget-host .widget-config-overlay .widget-config-box{align-self:center;text-align:center;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:var(--ax-gray-dark-color)}.widget-board .widgets-container .widget-host .widget-config-overlay .widget-config-box .config-title{font-size:1.2em;margin-bottom:var(--ax-size-md)}.widget-board .widgets-container .widget-host .widget-edit-overlay{display:none;background:rgba(255,255,255,.5);position:absolute;width:100%;height:100%;top:0;left:0;z-index:10}.widget-board .widgets-container .widget-host .widget-edit-overlay .widget-edit-menu{margin:6px;text-align:end;float:inline-end;opacity:1;transition:opacity 1s ease}.widget-board .widgets-container .widget-host .widget-edit-overlay .widget-edit-menu .widget-edit-menu-button{display:inline-block;background-color:#f0f0f0;border-radius:1px;border:2px solid #fff;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;padding:0;height:32px;width:32px;cursor:pointer;color:#666}.widget-board .widgets-container .widget-host .widget-edit-overlay .widget-edit-menu .widget-edit-menu-button:hover{border-color:#a6a6a6;background-color:#c8c8c8}.widget-board .widgets-container .widget-host .widget-options-menu{display:none;position:absolute;top:0;right:0;z-index:2;cursor:pointer;padding:2px 5px}.widget-board .widgets-container .widget-host .widget-options-menu:hover{background-color:#f0f0f0}.widget-board .widgets-container .widget-host .widget-container{padding:1px;height:100%}.widget-board .widgets-container .widget-host .widget-container:hover .widget-options-menu{display:block}\n"] }]
990
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { container: [{
991
- type: ViewChild,
992
- args: ['container']
993
- }], widgetHosts: [{
994
- type: ViewChildren,
995
- args: [AXWidgetHostComponent]
996
- }], galleryItems: [{
997
- type: Input
998
- }], tileSize: [{
999
- type: Input
1000
- }], gapSize: [{
1001
- type: Input
1002
- }], readonly: [{
1003
- type: Input
1004
- }], provideValue: [{
1005
- type: Input
1006
- }], onConfigChanged: [{
1007
- type: Output
1008
- }], onWidgetSave: [{
1009
- type: Output
568
+ class AXWidgetBoardComponent {
569
+ constructor(ref, zone, cdr) {
570
+ this.ref = ref;
571
+ this.zone = zone;
572
+ this.cdr = cdr;
573
+ this.widgets = [];
574
+ this.galleryItems = [];
575
+ this.tileSize = 80;
576
+ this.gapSize = 5;
577
+ this.readonly = false;
578
+ this.newWidget = null;
579
+ this._isInEditing = false;
580
+ this.isDragging = false;
581
+ this.DATA_COL = 'data-col';
582
+ this.DATA_ROW = 'data-row';
583
+ this.DATA_SIZE_X = 'data-size-x';
584
+ this.DATA_SIZE_Y = 'data-size-y';
585
+ this.DATA_OLD_COL = 'data-old-col';
586
+ this.DATA_OLD_ROW = 'data-old-row';
587
+ this.onConfigChanged = new EventEmitter();
588
+ this.onWidgetSave = new EventEmitter();
589
+ }
590
+ isInEditing() {
591
+ return this._isInEditing;
592
+ }
593
+ ngOnInit() {
594
+ if (this.rtl == null) {
595
+ this.rtl = window.getComputedStyle(this.ref.nativeElement, null).getPropertyValue('direction') === 'rtl';
596
+ }
597
+ }
598
+ ngAfterViewInit() {
599
+ this.zone.runOutsideAngular((c) => {
600
+ const style = document.createElement('style');
601
+ style.type = 'text/css';
602
+ this.ref.nativeElement.appendChild(style);
603
+ // add css data classes
604
+ for (let i = 1; i <= 50; i++) {
605
+ style.innerHTML += `[${this.DATA_COL}="${i}"] { ${this.rtl ? 'right' : 'left'}: ${(i - 1) * (this.tileSize + this.gapSize)}px; }`;
606
+ style.innerHTML += `[${this.DATA_ROW}="${i}"] { top: ${(i - 1) * (this.tileSize + this.gapSize)}px; }`;
607
+ style.innerHTML += `[${this.DATA_SIZE_X}="${i}"] { width: ${(i * this.tileSize) + ((i - 1) * this.gapSize)}px; }`;
608
+ style.innerHTML += `[${this.DATA_SIZE_Y}="${i}"] { height: ${(i * this.tileSize) + ((i - 1) * this.gapSize)}px; }`;
609
+ }
610
+ });
611
+ }
612
+ calcGridSize() {
613
+ this.zone.runOutsideAngular(() => {
614
+ const width = (Math.max(...this.widgets.map((c) => c.col + c.sizeX - 1))) * (this.tileSize + this.gapSize);
615
+ const height = (Math.max(...this.widgets.map((c) => c.row + c.sizeY - 1))) * (this.tileSize + this.gapSize);
616
+ this.container.nativeElement.style.width = width + 'px';
617
+ this.container.nativeElement.style.height = height + 'px';
618
+ });
619
+ }
620
+ toggleEdit() {
621
+ this._isInEditing ? this.finishEdit() : this.startEdit();
622
+ }
623
+ dragStart(e) {
624
+ e.preventDefault();
625
+ e.stopPropagation();
626
+ this.zone.runOutsideAngular(() => {
627
+ if (this._isInEditing && e.which === 1) {
628
+ this.dragItem = e.currentTarget;
629
+ this.dragItem.setAttribute('data-x-offset', (this.dragItem.offsetLeft - e.clientX).toString());
630
+ //
631
+ this.dragItem.setAttribute('data-y-offset', (this.dragItem.offsetTop - e.clientY).toString());
632
+ this.dragItem.classList.add('widget-dragging');
633
+ this.dragItem.classList.remove('animate__animated', 'animate__pulse');
634
+ }
635
+ });
636
+ return false;
637
+ }
638
+ removePositionData() {
639
+ this.zone.runOutsideAngular(() => {
640
+ if (this.dragItem && this._isInEditing && this.dragItem.getAttribute(this.DATA_OLD_COL) == null) {
641
+ this.dragItem.setAttribute(this.DATA_OLD_COL, this.dragItem.getAttribute(this.DATA_COL));
642
+ this.dragItem.setAttribute(this.DATA_OLD_ROW, this.dragItem.getAttribute(this.DATA_ROW));
643
+ this.dragItem.removeAttribute(this.DATA_COL);
644
+ this.dragItem.removeAttribute(this.DATA_ROW);
645
+ }
646
+ });
647
+ }
648
+ resetPositionData() {
649
+ this.zone.runOutsideAngular(() => {
650
+ if (this.dragItem && this._isInEditing) {
651
+ this.setPosition(this.dragItem, this.dragItem.getAttribute(this.DATA_OLD_COL), this.dragItem.getAttribute(this.DATA_OLD_ROW));
652
+ }
653
+ });
654
+ }
655
+ setPosition(element, col, row) {
656
+ this.zone.runOutsideAngular(() => {
657
+ element.setAttribute(this.DATA_COL, col);
658
+ element.setAttribute(this.DATA_ROW, row);
659
+ element.removeAttribute(this.DATA_OLD_COL);
660
+ element.removeAttribute(this.DATA_OLD_ROW);
661
+ element.style.removeProperty('top');
662
+ element.style.removeProperty('left');
663
+ const widget = this.widgets.find(c => c['__meta__'].instance.element === element);
664
+ widget.col = Number(col);
665
+ widget.row = Number(row);
666
+ });
667
+ }
668
+ drag(e) {
669
+ e.preventDefault();
670
+ e.stopPropagation();
671
+ this.zone.runOutsideAngular(() => {
672
+ if (this.dragItem && this._isInEditing) {
673
+ this.isDragging = true;
674
+ this.addPlaceholder();
675
+ const xOffset = Number(this.dragItem.getAttribute('data-x-offset'));
676
+ const yOffset = Number(this.dragItem.getAttribute('data-y-offset'));
677
+ this.dragItem.style.left = e.clientX + xOffset + 'px';
678
+ this.dragItem.style.top = e.clientY + yOffset + 'px';
679
+ //
680
+ this.detectBestPlacement();
681
+ this.removePositionData();
682
+ }
683
+ });
684
+ return false;
685
+ }
686
+ dragEnd(e) {
687
+ this.zone.runOutsideAngular(() => {
688
+ if (this.dragItem && this._isInEditing && this.isDragging) {
689
+ this.dragItem.classList.remove('widget-dragging');
690
+ this.dragItem.classList.add('animate__animated', 'animate__pulse');
691
+ //
692
+ const p = this.container.nativeElement.querySelector('.widget-blank-placeholder');
693
+ if (this.newWidget) {
694
+ const w = {
695
+ uniqueName: this.newWidget.uniqueName,
696
+ component: this.newWidget.component,
697
+ title: this.newWidget.title,
698
+ options: this.newWidget.options,
699
+ sizeX: this.newWidget.sizeX,
700
+ sizeY: this.newWidget.sizeY,
701
+ col: Number(p.getAttribute(this.DATA_COL)),
702
+ row: Number(p.getAttribute(this.DATA_ROW))
703
+ };
704
+ this.widgets.push(w);
705
+ this.newWidget = null;
706
+ this.container.nativeElement.removeChild(this.dragItem);
707
+ this.zone.run(() => {
708
+ this.cdr.detectChanges();
709
+ this.calcGridSize();
710
+ setTimeout(() => {
711
+ w['__meta__'].instance.element.addEventListener('mousedown', this.dragStart.bind(this), false);
712
+ }, 1000);
713
+ });
714
+ }
715
+ else {
716
+ if (p) {
717
+ this.setPosition(this.dragItem, p.getAttribute(this.DATA_COL), p.getAttribute(this.DATA_ROW));
718
+ }
719
+ else {
720
+ this.setPosition(this.dragItem, this.dragItem.getAttribute(this.DATA_OLD_COL), this.dragItem.getAttribute(this.DATA_OLD_ROW));
721
+ }
722
+ }
723
+ //
724
+ this.removePlaceholder();
725
+ this.dragItem = null;
726
+ this.calcGridSize();
727
+ this.emitConfigChanged('config');
728
+ }
729
+ this.isDragging = false;
730
+ });
731
+ }
732
+ detectFirstEmptySlot(w) {
733
+ const xTile = Math.floor(this.ref.nativeElement.parentElement.offsetWidth / this.tileSize);
734
+ for (let j = 1; j <= 100; j++) {
735
+ for (let i = 1; i <= xTile - w.sizeX; i++) {
736
+ const rec = new AXClientRec({
737
+ left: i,
738
+ top: j,
739
+ width: w.sizeX,
740
+ height: w.sizeY
741
+ });
742
+ const el = this.widgets.filter(c => c !== w).find((c) => rec.intersect({
743
+ left: c.col,
744
+ top: c.row,
745
+ width: c.sizeX,
746
+ height: c.sizeY
747
+ }));
748
+ if (el == null) {
749
+ w.col = i;
750
+ w.row = j;
751
+ return;
752
+ }
753
+ }
754
+ }
755
+ }
756
+ detectBestPlacement() {
757
+ this.zone.runOutsideAngular(() => {
758
+ const p = this.container.nativeElement.querySelector('.widget-blank-placeholder');
759
+ let col = Math.ceil(this.dragItem.offsetLeft / this.tileSize);
760
+ if (this.rtl) {
761
+ col = Math.ceil((this.container.nativeElement.clientWidth - (this.dragItem.offsetLeft + this.dragItem.clientWidth)) / this.tileSize);
762
+ }
763
+ let row = Math.ceil(this.dragItem.offsetTop / this.tileSize);
764
+ if (col < 1) {
765
+ col = 1;
766
+ }
767
+ if (row < 1) {
768
+ row = 1;
769
+ }
770
+ const widgets = Array.from(this.ref.nativeElement.querySelectorAll('.widget-host')).map((c) => c);
771
+ p.setAttribute(this.DATA_COL, col.toString());
772
+ p.setAttribute(this.DATA_ROW, row.toString());
773
+ const collision = widgets.filter(c => c !== this.dragItem).some(c => AXHtmlUtil.collision(c, this.dragItem));
774
+ if (collision) {
775
+ this.removePlaceholder();
776
+ }
777
+ });
778
+ }
779
+ addPlaceholder() {
780
+ this.zone.runOutsideAngular(() => {
781
+ this.removePlaceholder();
782
+ if (this.dragItem) {
783
+ const p = document.createElement('div');
784
+ p.classList.add('widget-blank-placeholder');
785
+ p.setAttribute(this.DATA_COL, this.dragItem.getAttribute(this.DATA_COL));
786
+ p.setAttribute(this.DATA_ROW, this.dragItem.getAttribute(this.DATA_ROW));
787
+ p.setAttribute(this.DATA_SIZE_X, this.dragItem.getAttribute(this.DATA_SIZE_X));
788
+ p.setAttribute(this.DATA_SIZE_Y, this.dragItem.getAttribute(this.DATA_SIZE_Y));
789
+ this.container.nativeElement.appendChild(p);
790
+ }
791
+ });
792
+ }
793
+ removePlaceholder() {
794
+ const p = this.container.nativeElement.querySelector('.widget-blank-placeholder');
795
+ p?.remove();
796
+ }
797
+ startEdit() {
798
+ this._isInEditing = true;
799
+ this.calcGridSize();
800
+ this.ref.nativeElement.classList.add('grid-background');
801
+ const bg = this.ref.nativeElement;
802
+ bg.style.setProperty('background-position', `${this.rtl ? 'right' : 'left'} top`);
803
+ // tslint:disable-next-line: max-line-length
804
+ const pattern = `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${this.tileSize + this.gapSize}" height="${this.tileSize + this.gapSize}"> <rect style="fill: %23dadada" x="${this.rtl ? this.gapSize : 0}" width="${this.tileSize}" height="${this.tileSize}" y="0"></rect></svg>')`;
805
+ bg.style.setProperty('background-image', pattern);
806
+ //
807
+ const widgets = Array.from(this.ref.nativeElement.querySelectorAll('.widget-host'));
808
+ widgets.forEach((w) => {
809
+ w.addEventListener('mousedown', this.dragStart.bind(this), false);
810
+ });
811
+ this.ref.nativeElement.addEventListener('mousemove', this.drag.bind(this), false);
812
+ this.ref.nativeElement.addEventListener('mouseup', this.dragEnd.bind(this), false);
813
+ }
814
+ finishEdit() {
815
+ this.ref.nativeElement.classList.remove('grid-background');
816
+ const bg = this.ref.nativeElement;
817
+ bg.style.removeProperty('background-image');
818
+ //
819
+ this._isInEditing = false;
820
+ const widgets = Array.from(this.ref.nativeElement.querySelectorAll('.widget-host'));
821
+ widgets.forEach((w) => {
822
+ w.removeEventListener('mousedown', this.dragStart.bind(this), false);
823
+ });
824
+ this.ref.nativeElement.removeEventListener('mousemove', this.drag.bind(this), false);
825
+ this.ref.nativeElement.removeEventListener('mouseup', this.dragEnd.bind(this), false);
826
+ this.emitConfigChanged('config');
827
+ }
828
+ addWidget(widget) {
829
+ this.zone.runOutsideAngular(() => {
830
+ this.newWidget = {
831
+ uniqueName: widget.uniqueName,
832
+ component: widget.component,
833
+ title: widget.title,
834
+ col: 1,
835
+ row: 1,
836
+ sizeX: widget.sizeX,
837
+ sizeY: widget.sizeY,
838
+ options: widget.options,
839
+ props: widget.props
840
+ };
841
+ this.detectFirstEmptySlot(this.newWidget);
842
+ const w = {
843
+ uniqueName: this.newWidget.uniqueName,
844
+ component: this.newWidget.component,
845
+ title: this.newWidget.title,
846
+ options: this.newWidget.options,
847
+ props: this.newWidget.props,
848
+ sizeX: this.newWidget.sizeX,
849
+ sizeY: this.newWidget.sizeY,
850
+ col: this.newWidget.col,
851
+ row: this.newWidget.row
852
+ };
853
+ this.widgets.push(w);
854
+ this.newWidget = null;
855
+ this.zone.run(() => {
856
+ this.cdr.detectChanges();
857
+ this.calcGridSize();
858
+ this.emitConfigChanged('add');
859
+ setTimeout(() => {
860
+ w['__meta__'].instance.element.addEventListener('mousedown', this.dragStart.bind(this), false);
861
+ }, 1000);
862
+ });
863
+ });
864
+ }
865
+ handleOnRemove(w) {
866
+ w.element.classList.add('animate__animated', 'animate__zoomOut');
867
+ w.element.addEventListener('animationend', () => {
868
+ this.widgets = this.widgets.filter((c) => c.__meta__.id !== w.config.__meta__.id);
869
+ this.cdr.detectChanges();
870
+ this.calcGridSize();
871
+ this.emitConfigChanged('remove');
872
+ });
873
+ }
874
+ handleOnSave(e) {
875
+ this.onWidgetSave.emit(e);
876
+ }
877
+ trackByFn(index, item) {
878
+ if (!item['__meta__']?.id) {
879
+ item['__meta__'] = {};
880
+ item['__meta__'].id = AXHtmlUtil.getUID();
881
+ }
882
+ return item['__meta__']?.id;
883
+ }
884
+ load(widgets) {
885
+ this.clear();
886
+ return new Promise((resolve, reject) => {
887
+ if (widgets) {
888
+ const loadedWidgets = [];
889
+ if (typeof widgets === 'string') {
890
+ try {
891
+ loadedWidgets.push(...JSON.parse(widgets));
892
+ this.emitConfigChanged('load');
893
+ }
894
+ catch (error) {
895
+ reject('Invalid widget json data!');
896
+ }
897
+ }
898
+ else {
899
+ loadedWidgets.push(...widgets);
900
+ this.emitConfigChanged('load');
901
+ }
902
+ let intervalId = -1;
903
+ const loadFunc = () => {
904
+ if (this.galleryItems && this.galleryItems.length > 0) {
905
+ loadedWidgets.forEach(w => {
906
+ const gitem = this.galleryItems.find(c => c.uniqueName === w.uniqueName);
907
+ if (gitem) {
908
+ w.component = gitem.component;
909
+ if (gitem.props) {
910
+ w.props = JSON.parse(JSON.stringify(gitem.props));
911
+ }
912
+ }
913
+ });
914
+ this.widgets.push(...loadedWidgets);
915
+ this.emitConfigChanged('load');
916
+ window.clearInterval(intervalId);
917
+ this.cdr.detectChanges();
918
+ resolve();
919
+ }
920
+ };
921
+ intervalId = window.setInterval(loadFunc, 200);
922
+ }
923
+ else {
924
+ resolve();
925
+ }
926
+ });
927
+ }
928
+ clear() {
929
+ if (this.widgets.length) {
930
+ this.widgets = [];
931
+ this.cdr.detectChanges();
932
+ this.emitConfigChanged('clear');
933
+ }
934
+ }
935
+ save() {
936
+ const obj = this.widgets.map(c => ({
937
+ uniqueName: c.uniqueName,
938
+ component: c.component,
939
+ title: c.title,
940
+ sizeX: c.sizeX,
941
+ sizeY: c.sizeY,
942
+ col: c.col,
943
+ row: c.row,
944
+ options: c.options,
945
+ props: c.props
946
+ }));
947
+ return Promise.resolve(JSON.stringify(obj));
948
+ }
949
+ refresh() {
950
+ this.widgetHosts.forEach(host => {
951
+ host.widget.refresh();
952
+ });
953
+ }
954
+ handleOnConfigChanged(e) {
955
+ this.cdr.detectChanges();
956
+ this.emitConfigChanged('config');
957
+ }
958
+ handleOnResizedChanged(e) {
959
+ this.detectFirstEmptySlot(e.config);
960
+ this.cdr.detectChanges();
961
+ this.emitConfigChanged('config');
962
+ }
963
+ //private resizeChangeObserver: any;
964
+ emitConfigChanged(mode) {
965
+ // if (!this.resizeChangeObserver) {
966
+ // this.resizeChangeObserver = new Observable();
967
+ // Observable.create(observer => {
968
+ // this.resizeChangeObserver = observer;
969
+ // })
970
+ // .pipe(debounceTime(750))
971
+ // .pipe(distinctUntilChanged())
972
+ // .subscribe(c => {
973
+ // this.onConfigChanged.emit({
974
+ // component: this
975
+ // });
976
+ // });
977
+ // }
978
+ // this.resizeChangeObserver.next(new Date());
979
+ this.onConfigChanged.emit({
980
+ component: this,
981
+ mode
982
+ });
983
+ }
984
+ }
985
+ AXWidgetBoardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetBoardComponent, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
986
+ AXWidgetBoardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: AXWidgetBoardComponent, selector: "ax-widget-board", inputs: { galleryItems: "galleryItems", tileSize: "tileSize", gapSize: "gapSize", readonly: "readonly", provideValue: "provideValue" }, outputs: { onConfigChanged: "onConfigChanged", onWidgetSave: "onWidgetSave" }, host: { classAttribute: "ax widget-board" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }, { propertyName: "widgetHosts", predicate: AXWidgetHostComponent, descendants: true }], ngImport: i0, template: "<div class=\"widgets-container\" [class.rtl]=\"rtl\" #container>\n <ax-widget-host *ngFor=\"let w of widgets;trackBy: trackByFn\" [config]='w' [sizeX]=\"w.sizeX\" [readonly]=\"readonly || w.readonly\"\n [sizeY]=\"w.sizeY\" [col]=\"w.col\" [row]=\"w.row\" (onRemove)=\"handleOnRemove($event)\" (onSave)=\"handleOnSave($event)\"\n (onConfigChanged)=\"handleOnConfigChanged($event)\" (onResized)=\"handleOnResizedChanged($event)\"\n [provideValue]=\"provideValue\">\n </ax-widget-host>\n</div>\n", styles: [".widget-board{display:inline-block;margin:15px 20px;min-width:calc(100% - 40px);min-height:calc(100% - 34px);--animate-duration: .5s;background-repeat:no-repeat}.widget-board.grid-background{background-repeat:repeat!important}.widget-board.grid-background .widgets-container .widget-host{touch-action:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.widget-board.grid-background .widgets-container .widget-host .widget-edit-overlay{display:block;cursor:move}.widget-board.grid-background .widgets-container .widget-host.widget-dragging{z-index:1000}.widget-board.grid-background .widgets-container .widget-host:focus{outline-width:1px;outline-style:solid;outline-color:var(--ax-primary-color)}.widget-board.grid-background .widget-blank-placeholder{background:var(--ax-primary-trans-light-color);position:absolute}.widget-board .widgets-container{position:relative;touch-action:none}.widget-board .widgets-container.rtl .widget-host .widget-options-menu{right:unset!important;left:0!important}.widget-board .widgets-container .widget-host{position:absolute;background:#fff;box-shadow:2px 2px 3px #dadada;z-index:0}.widget-board .widgets-container .widget-host .widget-content{width:100%;height:100%;display:flex;flex-direction:column}.widget-board .widgets-container .widget-host .widget-content .widget-title{padding:var(--ax-size-md);text-align:start;font-size:1.5em;position:absolute}.widget-board .widgets-container .widget-host .widget-edit-loading{display:none;background:rgba(255,255,255,.85);position:absolute;width:100%;height:100%;top:0;left:0;z-index:2;display:flex}.widget-board .widgets-container .widget-host .widget-config-overlay{position:absolute;background:white;width:100%;height:100%;top:0;left:0;z-index:1;padding:var(--ax-size-md);cursor:pointer}.widget-board .widgets-container .widget-host .widget-config-overlay:hover .widget-title{text-decoration:underline}.widget-board .widgets-container .widget-host .widget-config-overlay .widget-title{text-align:start;font-size:1.5em}.widget-board .widgets-container .widget-host .widget-config-overlay .widget-config-box{align-self:center;text-align:center;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:var(--ax-gray-dark-color)}.widget-board .widgets-container .widget-host .widget-config-overlay .widget-config-box .config-title{font-size:1.2em;margin-bottom:var(--ax-size-md)}.widget-board .widgets-container .widget-host .widget-edit-overlay{display:none;background:rgba(255,255,255,.5);position:absolute;width:100%;height:100%;top:0;left:0;z-index:10}.widget-board .widgets-container .widget-host .widget-edit-overlay .widget-edit-menu{margin:6px;text-align:end;float:inline-end;opacity:1;transition:opacity 1s ease}.widget-board .widgets-container .widget-host .widget-edit-overlay .widget-edit-menu .widget-edit-menu-button{display:inline-block;background-color:#f0f0f0;border-radius:1px;border:2px solid #fff;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;padding:0;height:32px;width:32px;cursor:pointer;color:#666}.widget-board .widgets-container .widget-host .widget-edit-overlay .widget-edit-menu .widget-edit-menu-button:hover{border-color:#a6a6a6;background-color:#c8c8c8}.widget-board .widgets-container .widget-host .widget-options-menu{display:none;position:absolute;top:0;right:0;z-index:2;cursor:pointer;padding:2px 5px}.widget-board .widgets-container .widget-host .widget-options-menu:hover{background-color:#f0f0f0}.widget-board .widgets-container .widget-host .widget-container{padding:1px;height:100%}.widget-board .widgets-container .widget-host .widget-container:hover .widget-options-menu{display:block}\n"], components: [{ type: AXWidgetHostComponent, selector: "ax-widget-host", inputs: ["provideValue", "config", "readonly", "sizeX", "sizeY", "col", "row"], outputs: ["onRemove", "onConfigChanged", "onResized", "onSave"] }], directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
987
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetBoardComponent, decorators: [{
988
+ type: Component,
989
+ args: [{ selector: 'ax-widget-board', host: { class: 'ax widget-board' }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"widgets-container\" [class.rtl]=\"rtl\" #container>\n <ax-widget-host *ngFor=\"let w of widgets;trackBy: trackByFn\" [config]='w' [sizeX]=\"w.sizeX\" [readonly]=\"readonly || w.readonly\"\n [sizeY]=\"w.sizeY\" [col]=\"w.col\" [row]=\"w.row\" (onRemove)=\"handleOnRemove($event)\" (onSave)=\"handleOnSave($event)\"\n (onConfigChanged)=\"handleOnConfigChanged($event)\" (onResized)=\"handleOnResizedChanged($event)\"\n [provideValue]=\"provideValue\">\n </ax-widget-host>\n</div>\n", styles: [".widget-board{display:inline-block;margin:15px 20px;min-width:calc(100% - 40px);min-height:calc(100% - 34px);--animate-duration: .5s;background-repeat:no-repeat}.widget-board.grid-background{background-repeat:repeat!important}.widget-board.grid-background .widgets-container .widget-host{touch-action:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.widget-board.grid-background .widgets-container .widget-host .widget-edit-overlay{display:block;cursor:move}.widget-board.grid-background .widgets-container .widget-host.widget-dragging{z-index:1000}.widget-board.grid-background .widgets-container .widget-host:focus{outline-width:1px;outline-style:solid;outline-color:var(--ax-primary-color)}.widget-board.grid-background .widget-blank-placeholder{background:var(--ax-primary-trans-light-color);position:absolute}.widget-board .widgets-container{position:relative;touch-action:none}.widget-board .widgets-container.rtl .widget-host .widget-options-menu{right:unset!important;left:0!important}.widget-board .widgets-container .widget-host{position:absolute;background:#fff;box-shadow:2px 2px 3px #dadada;z-index:0}.widget-board .widgets-container .widget-host .widget-content{width:100%;height:100%;display:flex;flex-direction:column}.widget-board .widgets-container .widget-host .widget-content .widget-title{padding:var(--ax-size-md);text-align:start;font-size:1.5em;position:absolute}.widget-board .widgets-container .widget-host .widget-edit-loading{display:none;background:rgba(255,255,255,.85);position:absolute;width:100%;height:100%;top:0;left:0;z-index:2;display:flex}.widget-board .widgets-container .widget-host .widget-config-overlay{position:absolute;background:white;width:100%;height:100%;top:0;left:0;z-index:1;padding:var(--ax-size-md);cursor:pointer}.widget-board .widgets-container .widget-host .widget-config-overlay:hover .widget-title{text-decoration:underline}.widget-board .widgets-container .widget-host .widget-config-overlay .widget-title{text-align:start;font-size:1.5em}.widget-board .widgets-container .widget-host .widget-config-overlay .widget-config-box{align-self:center;text-align:center;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:var(--ax-gray-dark-color)}.widget-board .widgets-container .widget-host .widget-config-overlay .widget-config-box .config-title{font-size:1.2em;margin-bottom:var(--ax-size-md)}.widget-board .widgets-container .widget-host .widget-edit-overlay{display:none;background:rgba(255,255,255,.5);position:absolute;width:100%;height:100%;top:0;left:0;z-index:10}.widget-board .widgets-container .widget-host .widget-edit-overlay .widget-edit-menu{margin:6px;text-align:end;float:inline-end;opacity:1;transition:opacity 1s ease}.widget-board .widgets-container .widget-host .widget-edit-overlay .widget-edit-menu .widget-edit-menu-button{display:inline-block;background-color:#f0f0f0;border-radius:1px;border:2px solid #fff;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;padding:0;height:32px;width:32px;cursor:pointer;color:#666}.widget-board .widgets-container .widget-host .widget-edit-overlay .widget-edit-menu .widget-edit-menu-button:hover{border-color:#a6a6a6;background-color:#c8c8c8}.widget-board .widgets-container .widget-host .widget-options-menu{display:none;position:absolute;top:0;right:0;z-index:2;cursor:pointer;padding:2px 5px}.widget-board .widgets-container .widget-host .widget-options-menu:hover{background-color:#f0f0f0}.widget-board .widgets-container .widget-host .widget-container{padding:1px;height:100%}.widget-board .widgets-container .widget-host .widget-container:hover .widget-options-menu{display:block}\n"] }]
990
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { container: [{
991
+ type: ViewChild,
992
+ args: ['container']
993
+ }], widgetHosts: [{
994
+ type: ViewChildren,
995
+ args: [AXWidgetHostComponent]
996
+ }], galleryItems: [{
997
+ type: Input
998
+ }], tileSize: [{
999
+ type: Input
1000
+ }], gapSize: [{
1001
+ type: Input
1002
+ }], readonly: [{
1003
+ type: Input
1004
+ }], provideValue: [{
1005
+ type: Input
1006
+ }], onConfigChanged: [{
1007
+ type: Output
1008
+ }], onWidgetSave: [{
1009
+ type: Output
1010
1010
  }] } });
1011
1011
 
1012
- class AXWidgetSizePropertyEditorComponent extends AXProperyEditorComponent {
1013
- constructor(cdr) {
1014
- super(cdr);
1015
- this.cdr = cdr;
1016
- this.minX = 1;
1017
- this.maxX = 10;
1018
- this.minY = 1;
1019
- this.maxY = 10;
1020
- }
1021
- ngOnInit() {
1022
- if (Array.isArray(this.value)) {
1023
- this.sizeX = this.value[0];
1024
- this.sizeY = this.value[1];
1025
- }
1026
- else {
1027
- this.sizeX = 2;
1028
- this.sizeY = 2;
1029
- }
1030
- }
1031
- handleMinValueChange(e) {
1032
- this.sizeX = e.value;
1033
- if (this.sizeY > 0) {
1034
- super.handleValueChange([this.sizeX, this.sizeY]);
1035
- }
1036
- }
1037
- handleMaxValueChange(e) {
1038
- this.sizeY = e.value;
1039
- if (this.sizeX > 0) {
1040
- super.handleValueChange([this.sizeX, this.sizeY]);
1041
- }
1042
- }
1043
- ngAfterViewInit() {
1044
- this.onRenderCompleted.emit();
1045
- }
1046
- }
1047
- AXWidgetSizePropertyEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetSizePropertyEditorComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1048
- AXWidgetSizePropertyEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: AXWidgetSizePropertyEditorComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<div style=\"display: grid;grid-gap: 2%; grid-template-columns: 49% 49%;\">\r\n <ax-number-box (onValueChanged)=\"handleMinValueChange($event)\" [value]=\"sizeX\" [min]=\"minX\" [max]=\"maxX\">\r\n </ax-number-box>\r\n <ax-number-box (onValueChanged)=\"handleMaxValueChange($event)\" [value]=\"sizeY\" [min]=\"minY\" [max]=\"maxY\">\r\n </ax-number-box>\r\n</div>", components: [{ type: i1.AXNumberBoxComponent, selector: "ax-number-box", inputs: ["min", "max", "showSeparator", "showCurrency", "showCounter", "scrollWeel", "showDoubleCounter", "maxLength", "intStep", "decimalNumber", "customStep"] }] });
1049
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetSizePropertyEditorComponent, decorators: [{
1050
- type: Component,
1051
- args: [{ template: "<div style=\"display: grid;grid-gap: 2%; grid-template-columns: 49% 49%;\">\r\n <ax-number-box (onValueChanged)=\"handleMinValueChange($event)\" [value]=\"sizeX\" [min]=\"minX\" [max]=\"maxX\">\r\n </ax-number-box>\r\n <ax-number-box (onValueChanged)=\"handleMaxValueChange($event)\" [value]=\"sizeY\" [min]=\"minY\" [max]=\"maxY\">\r\n </ax-number-box>\r\n</div>" }]
1012
+ class AXWidgetSizePropertyEditorComponent extends AXProperyEditorComponent {
1013
+ constructor(cdr) {
1014
+ super(cdr);
1015
+ this.cdr = cdr;
1016
+ this.minX = 1;
1017
+ this.maxX = 10;
1018
+ this.minY = 1;
1019
+ this.maxY = 10;
1020
+ }
1021
+ ngOnInit() {
1022
+ if (Array.isArray(this.value)) {
1023
+ this.sizeX = this.value[0];
1024
+ this.sizeY = this.value[1];
1025
+ }
1026
+ else {
1027
+ this.sizeX = 2;
1028
+ this.sizeY = 2;
1029
+ }
1030
+ }
1031
+ handleMinValueChange(e) {
1032
+ this.sizeX = e.value;
1033
+ if (this.sizeY > 0) {
1034
+ super.handleValueChange([this.sizeX, this.sizeY]);
1035
+ }
1036
+ }
1037
+ handleMaxValueChange(e) {
1038
+ this.sizeY = e.value;
1039
+ if (this.sizeX > 0) {
1040
+ super.handleValueChange([this.sizeX, this.sizeY]);
1041
+ }
1042
+ }
1043
+ ngAfterViewInit() {
1044
+ this.onRenderCompleted.emit();
1045
+ }
1046
+ }
1047
+ AXWidgetSizePropertyEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetSizePropertyEditorComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1048
+ AXWidgetSizePropertyEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: AXWidgetSizePropertyEditorComponent, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<div style=\"display: grid;grid-gap: 2%; grid-template-columns: 49% 49%;\">\n <ax-number-box (onValueChanged)=\"handleMinValueChange($event)\" [value]=\"sizeX\" [min]=\"minX\" [max]=\"maxX\">\n </ax-number-box>\n <ax-number-box (onValueChanged)=\"handleMaxValueChange($event)\" [value]=\"sizeY\" [min]=\"minY\" [max]=\"maxY\">\n </ax-number-box>\n</div>", components: [{ type: i1.AXNumberBoxComponent, selector: "ax-number-box", inputs: ["min", "max", "showSeparator", "showCurrency", "showCounter", "scrollWeel", "showDoubleCounter", "maxLength", "intStep", "decimalNumber", "customStep"] }] });
1049
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetSizePropertyEditorComponent, decorators: [{
1050
+ type: Component,
1051
+ args: [{ template: "<div style=\"display: grid;grid-gap: 2%; grid-template-columns: 49% 49%;\">\n <ax-number-box (onValueChanged)=\"handleMinValueChange($event)\" [value]=\"sizeX\" [min]=\"minX\" [max]=\"maxX\">\n </ax-number-box>\n <ax-number-box (onValueChanged)=\"handleMaxValueChange($event)\" [value]=\"sizeY\" [min]=\"minY\" [max]=\"maxY\">\n </ax-number-box>\n</div>" }]
1052
1052
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; } });
1053
1053
 
1054
- class AXWidgetBoardModule {
1055
- /**
1056
- *
1057
- */
1058
- constructor() {
1059
- AXTranslator.load('en', {
1060
- 'widget-board': {
1061
- 'configurable-props': 'Configurable Properties',
1062
- configure: 'Configure Widget'
1063
- }
1064
- });
1065
- AXTranslator.load('fa', {
1066
- 'widget-board': {
1067
- 'configurable-props': 'ویژگی های قابل تنظیم',
1068
- configure: 'پیکر بندی ابزارک'
1069
- }
1070
- });
1071
- }
1072
- }
1073
- AXWidgetBoardModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetBoardModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1074
- AXWidgetBoardModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetBoardModule, declarations: [AXWidgetBoardComponent, AXWidgetHostComponent, AXWidgetConfigComponent, AXWidgetSaveComponent], imports: [CommonModule,
1075
- AXSearchBoxModule,
1076
- AXLoadingModule,
1077
- RouterModule,
1078
- AXProppertyEditorModule,
1079
- AXPageModule,
1080
- AXToolbarModule,
1081
- AXTranslatorModule,
1082
- AXLabelModule,
1083
- AXTextAreaModule,
1084
- AXFieldsetModule,
1085
- AXTextBoxModule,
1086
- AXFormGroupModule,
1087
- AXTabStripModule,
1088
- AXCheckBoxModule,
1089
- AXMenuModule,
1090
- AXTranslatorModule,
1091
- AXValidationModule, i1$2.RouterModule], exports: [AXWidgetBoardComponent, AXProppertyEditorModule] });
1092
- AXWidgetBoardModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetBoardModule, providers: [], imports: [[
1093
- CommonModule,
1094
- AXSearchBoxModule,
1095
- AXLoadingModule,
1096
- RouterModule,
1097
- AXProppertyEditorModule,
1098
- AXPageModule,
1099
- AXToolbarModule,
1100
- AXTranslatorModule,
1101
- AXLabelModule,
1102
- AXTextAreaModule,
1103
- AXFieldsetModule,
1104
- AXTextBoxModule,
1105
- AXFormGroupModule,
1106
- AXTabStripModule,
1107
- AXCheckBoxModule,
1108
- AXMenuModule,
1109
- AXTranslatorModule,
1110
- AXValidationModule,
1111
- RouterModule.forChild([
1112
- {
1113
- component: AXWidgetSizePropertyEditorComponent,
1114
- path: 'ax/editors/widget-size'
1115
- },
1116
- ])
1117
- ], AXProppertyEditorModule] });
1118
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetBoardModule, decorators: [{
1119
- type: NgModule,
1120
- args: [{
1121
- imports: [
1122
- CommonModule,
1123
- AXSearchBoxModule,
1124
- AXLoadingModule,
1125
- RouterModule,
1126
- AXProppertyEditorModule,
1127
- AXPageModule,
1128
- AXToolbarModule,
1129
- AXTranslatorModule,
1130
- AXLabelModule,
1131
- AXTextAreaModule,
1132
- AXFieldsetModule,
1133
- AXTextBoxModule,
1134
- AXFormGroupModule,
1135
- AXTabStripModule,
1136
- AXCheckBoxModule,
1137
- AXMenuModule,
1138
- AXTranslatorModule,
1139
- AXValidationModule,
1140
- RouterModule.forChild([
1141
- {
1142
- component: AXWidgetSizePropertyEditorComponent,
1143
- path: 'ax/editors/widget-size'
1144
- },
1145
- ])
1146
- ],
1147
- exports: [AXWidgetBoardComponent, AXProppertyEditorModule],
1148
- declarations: [AXWidgetBoardComponent, AXWidgetHostComponent, AXWidgetConfigComponent, AXWidgetSaveComponent],
1149
- providers: []
1150
- }]
1054
+ class AXWidgetBoardModule {
1055
+ /**
1056
+ *
1057
+ */
1058
+ constructor() {
1059
+ AXTranslator.load('en', {
1060
+ 'widget-board': {
1061
+ 'configurable-props': 'Configurable Properties',
1062
+ configure: 'Configure Widget'
1063
+ }
1064
+ });
1065
+ AXTranslator.load('fa', {
1066
+ 'widget-board': {
1067
+ 'configurable-props': 'ویژگی های قابل تنظیم',
1068
+ configure: 'پیکر بندی ابزارک'
1069
+ }
1070
+ });
1071
+ }
1072
+ }
1073
+ AXWidgetBoardModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetBoardModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1074
+ AXWidgetBoardModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetBoardModule, declarations: [AXWidgetBoardComponent, AXWidgetHostComponent, AXWidgetConfigComponent, AXWidgetSaveComponent], imports: [CommonModule,
1075
+ AXSearchBoxModule,
1076
+ AXLoadingModule,
1077
+ RouterModule,
1078
+ AXProppertyEditorModule,
1079
+ AXPageModule,
1080
+ AXToolbarModule,
1081
+ AXTranslatorModule,
1082
+ AXLabelModule,
1083
+ AXTextAreaModule,
1084
+ AXFieldsetModule,
1085
+ AXTextBoxModule,
1086
+ AXFormGroupModule,
1087
+ AXTabStripModule,
1088
+ AXCheckBoxModule,
1089
+ AXMenuModule,
1090
+ AXTranslatorModule,
1091
+ AXValidationModule, i1$2.RouterModule], exports: [AXWidgetBoardComponent, AXProppertyEditorModule] });
1092
+ AXWidgetBoardModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetBoardModule, providers: [], imports: [[
1093
+ CommonModule,
1094
+ AXSearchBoxModule,
1095
+ AXLoadingModule,
1096
+ RouterModule,
1097
+ AXProppertyEditorModule,
1098
+ AXPageModule,
1099
+ AXToolbarModule,
1100
+ AXTranslatorModule,
1101
+ AXLabelModule,
1102
+ AXTextAreaModule,
1103
+ AXFieldsetModule,
1104
+ AXTextBoxModule,
1105
+ AXFormGroupModule,
1106
+ AXTabStripModule,
1107
+ AXCheckBoxModule,
1108
+ AXMenuModule,
1109
+ AXTranslatorModule,
1110
+ AXValidationModule,
1111
+ RouterModule.forChild([
1112
+ {
1113
+ component: AXWidgetSizePropertyEditorComponent,
1114
+ path: 'ax/editors/widget-size'
1115
+ },
1116
+ ])
1117
+ ], AXProppertyEditorModule] });
1118
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetBoardModule, decorators: [{
1119
+ type: NgModule,
1120
+ args: [{
1121
+ imports: [
1122
+ CommonModule,
1123
+ AXSearchBoxModule,
1124
+ AXLoadingModule,
1125
+ RouterModule,
1126
+ AXProppertyEditorModule,
1127
+ AXPageModule,
1128
+ AXToolbarModule,
1129
+ AXTranslatorModule,
1130
+ AXLabelModule,
1131
+ AXTextAreaModule,
1132
+ AXFieldsetModule,
1133
+ AXTextBoxModule,
1134
+ AXFormGroupModule,
1135
+ AXTabStripModule,
1136
+ AXCheckBoxModule,
1137
+ AXMenuModule,
1138
+ AXTranslatorModule,
1139
+ AXValidationModule,
1140
+ RouterModule.forChild([
1141
+ {
1142
+ component: AXWidgetSizePropertyEditorComponent,
1143
+ path: 'ax/editors/widget-size'
1144
+ },
1145
+ ])
1146
+ ],
1147
+ exports: [AXWidgetBoardComponent, AXProppertyEditorModule],
1148
+ declarations: [AXWidgetBoardComponent, AXWidgetHostComponent, AXWidgetConfigComponent, AXWidgetSaveComponent],
1149
+ providers: []
1150
+ }]
1151
1151
  }], ctorParameters: function () { return []; } });
1152
1152
 
1153
- class AXWidgetSizePropertyEditorModule {
1154
- }
1155
- AXWidgetSizePropertyEditorModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetSizePropertyEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1156
- AXWidgetSizePropertyEditorModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetSizePropertyEditorModule, declarations: [AXWidgetSizePropertyEditorComponent], imports: [CommonModule, FormsModule, AXNumberBoxModule], exports: [AXWidgetSizePropertyEditorComponent] });
1157
- AXWidgetSizePropertyEditorModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetSizePropertyEditorModule, providers: [], imports: [[CommonModule, FormsModule, AXNumberBoxModule]] });
1158
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetSizePropertyEditorModule, decorators: [{
1159
- type: NgModule,
1160
- args: [{
1161
- declarations: [AXWidgetSizePropertyEditorComponent],
1162
- imports: [CommonModule, FormsModule, AXNumberBoxModule],
1163
- exports: [AXWidgetSizePropertyEditorComponent],
1164
- providers: []
1165
- }]
1153
+ class AXWidgetSizePropertyEditorModule {
1154
+ }
1155
+ AXWidgetSizePropertyEditorModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetSizePropertyEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1156
+ AXWidgetSizePropertyEditorModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetSizePropertyEditorModule, declarations: [AXWidgetSizePropertyEditorComponent], imports: [CommonModule, FormsModule, AXNumberBoxModule], exports: [AXWidgetSizePropertyEditorComponent] });
1157
+ AXWidgetSizePropertyEditorModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetSizePropertyEditorModule, providers: [], imports: [[CommonModule, FormsModule, AXNumberBoxModule]] });
1158
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: AXWidgetSizePropertyEditorModule, decorators: [{
1159
+ type: NgModule,
1160
+ args: [{
1161
+ declarations: [AXWidgetSizePropertyEditorComponent],
1162
+ imports: [CommonModule, FormsModule, AXNumberBoxModule],
1163
+ exports: [AXWidgetSizePropertyEditorComponent],
1164
+ providers: []
1165
+ }]
1166
1166
  }] });
1167
1167
 
1168
- /**
1169
- * Generated bundle index. Do not edit.
1168
+ /**
1169
+ * Generated bundle index. Do not edit.
1170
1170
  */
1171
1171
 
1172
1172
  export { AXWidgetBoardComponent, AXWidgetBoardModule, AXWidgetComponent, AXWidgetHostComponent, AXWidgetSizePropertyEditorComponent, AXWidgetSizePropertyEditorModule };