@planeasyinc/le-angular 0.0.22 → 0.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fesm2022/planeasyinc-le-angular.mjs +109 -26
- package/dist/fesm2022/planeasyinc-le-angular.mjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/lib/icons/le-icon.component.d.ts +1 -1
- package/dist/lib/services/le-actions.service.d.ts +15 -0
- package/dist/lib/services/le-data.service.d.ts +2 -2
- package/dist/lib/services/le-toast.service.d.ts +1 -0
- package/dist/lib/tokens/config.token.d.ts +2 -1
- package/dist/lib/tokens/http-context.token.d.ts +1 -1
- package/dist/lib/types/le-action.d.ts +5 -0
- package/dist/lib/views/form-view/form-view.component.d.ts +4 -1
- package/dist/styles/styles.scss +3 -4
- package/package.json +6 -6
|
@@ -16,14 +16,14 @@ import { NestedTreeControl, CdkTree, CdkNestedTreeNode, CdkTreeNodeDef, CdkTreeN
|
|
|
16
16
|
import { ArrayDataSource, SelectionModel } from '@angular/cdk/collections';
|
|
17
17
|
import { CdkMenuTrigger, CdkMenu, CdkMenuItem } from '@angular/cdk/menu';
|
|
18
18
|
import { A11yModule } from '@angular/cdk/a11y';
|
|
19
|
+
import { createEngine } from '@planeasyinc/fe-core';
|
|
19
20
|
import { adaptOld } from '@planeasyinc/fe-adapters-old';
|
|
20
21
|
import { adaptSections } from '@planeasyinc/fe-adapters-sections';
|
|
21
|
-
import { createEngine } from '@planeasyinc/fe-core';
|
|
22
22
|
import { FeFieldHost } from '@planeasyinc/fe-angular';
|
|
23
23
|
import * as i1 from '@angular/forms';
|
|
24
24
|
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
|
|
25
25
|
|
|
26
|
-
const
|
|
26
|
+
const LE_REQUEST_CONTEXT_TOKEN = new HttpContextToken(() => false);
|
|
27
27
|
|
|
28
28
|
const defaultConfig = {
|
|
29
29
|
apiUrl: '',
|
|
@@ -87,7 +87,7 @@ class LEApiService {
|
|
|
87
87
|
const url = new UrlFragmentBuilder(this.apiUrl())
|
|
88
88
|
.setFragment('api/contrib/frontend-config/dashboard/config')
|
|
89
89
|
.build();
|
|
90
|
-
return this.http.get(url, { context: new HttpContext().set(
|
|
90
|
+
return this.http.get(url, { context: new HttpContext().set(LE_REQUEST_CONTEXT_TOKEN, true) });
|
|
91
91
|
}
|
|
92
92
|
getObject(className, query = '') {
|
|
93
93
|
const url = new UrlFragmentBuilder(this.apiUrl())
|
|
@@ -97,7 +97,7 @@ class LEApiService {
|
|
|
97
97
|
.setQuery(query)
|
|
98
98
|
.build();
|
|
99
99
|
return this.http.get(url, {
|
|
100
|
-
context: new HttpContext().set(
|
|
100
|
+
context: new HttpContext().set(LE_REQUEST_CONTEXT_TOKEN, true),
|
|
101
101
|
});
|
|
102
102
|
}
|
|
103
103
|
getObjectByAddress(address, params) {
|
|
@@ -106,7 +106,7 @@ class LEApiService {
|
|
|
106
106
|
.setQuery(`all_versions=${params.includeVersions ?? false}&include_metadata=${params.includeMeta ?? false}&load_references=${params.loadReferences ?? false}&file_optimized=${params.fileOptimized ?? true}`)
|
|
107
107
|
.build();
|
|
108
108
|
return this.http.get(url, {
|
|
109
|
-
context: new HttpContext().set(
|
|
109
|
+
context: new HttpContext().set(LE_REQUEST_CONTEXT_TOKEN, true),
|
|
110
110
|
});
|
|
111
111
|
}
|
|
112
112
|
executeTransaction(name, body, query = '') {
|
|
@@ -115,20 +115,20 @@ class LEApiService {
|
|
|
115
115
|
.setQuery(query)
|
|
116
116
|
.build();
|
|
117
117
|
return this.http.post(url, body ?? {}, {
|
|
118
|
-
context: new HttpContext().set(
|
|
118
|
+
context: new HttpContext().set(LE_REQUEST_CONTEXT_TOKEN, true),
|
|
119
119
|
});
|
|
120
120
|
}
|
|
121
121
|
request(method, path, body) {
|
|
122
122
|
const url = new UrlFragmentBuilder(this.apiUrl()).setFragment(path).build();
|
|
123
123
|
const request = new HttpRequest(method, url, body, {
|
|
124
124
|
responseType: 'json',
|
|
125
|
-
context: new HttpContext().set(
|
|
125
|
+
context: new HttpContext().set(LE_REQUEST_CONTEXT_TOKEN, true),
|
|
126
126
|
});
|
|
127
127
|
return this.http.request(request);
|
|
128
128
|
}
|
|
129
129
|
getBlob(path) {
|
|
130
130
|
return this.http
|
|
131
|
-
.get(path, { responseType: 'blob', context: new HttpContext().set(
|
|
131
|
+
.get(path, { responseType: 'blob', context: new HttpContext().set(LE_REQUEST_CONTEXT_TOKEN, true) })
|
|
132
132
|
.pipe(map((blob) => URL.createObjectURL(blob)));
|
|
133
133
|
}
|
|
134
134
|
normalizeApiUrl(url) {
|
|
@@ -165,7 +165,8 @@ class LeNavigationService {
|
|
|
165
165
|
if (!this.config.withRouting)
|
|
166
166
|
return;
|
|
167
167
|
const path = this.mapNodeToLocationPath(node);
|
|
168
|
-
this.
|
|
168
|
+
const fullPath = [this.config.rootPath, path].filter(Boolean).join('/');
|
|
169
|
+
this.location.go(`/${fullPath}`, undefined, { node });
|
|
169
170
|
}
|
|
170
171
|
mapNodeToLocationPath(node) {
|
|
171
172
|
let pathChunks = [];
|
|
@@ -173,13 +174,20 @@ class LeNavigationService {
|
|
|
173
174
|
if (node.type === 'table') {
|
|
174
175
|
pathChunks.push(node?.title || node?.dataSource?.entity);
|
|
175
176
|
if (node?.dataSource?.params) {
|
|
176
|
-
query = Object.entries(node.dataSource.params)
|
|
177
|
+
query = Object.entries(node.dataSource.params)
|
|
178
|
+
.map((entry) => entry.join('='))
|
|
179
|
+
.join('&');
|
|
177
180
|
}
|
|
178
181
|
}
|
|
179
|
-
if (node.type === 'form') {
|
|
182
|
+
else if (node.type === 'form') {
|
|
180
183
|
pathChunks.push('details', node.controlSource?.kind, node.controlSource?.entity, node.controlSource?.params?.className, node.controlSource?.params?.address, node.controlSource?.params?.mode);
|
|
181
184
|
}
|
|
182
|
-
|
|
185
|
+
else {
|
|
186
|
+
const title = (node.title ?? '').replace(' ', '-');
|
|
187
|
+
if (title)
|
|
188
|
+
pathChunks.push(title);
|
|
189
|
+
}
|
|
190
|
+
const path = pathChunks.filter((v) => !!v).join('/');
|
|
183
191
|
return query ? `${path}?${query}` : path;
|
|
184
192
|
}
|
|
185
193
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LeNavigationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
@@ -249,7 +257,7 @@ class LEDataService {
|
|
|
249
257
|
navigateByNodeId(id) {
|
|
250
258
|
const node = this.getNodeById(id);
|
|
251
259
|
if (node) {
|
|
252
|
-
this.
|
|
260
|
+
this.setView(node);
|
|
253
261
|
}
|
|
254
262
|
}
|
|
255
263
|
getNodeById(id, node = this._config()) {
|
|
@@ -1242,8 +1250,9 @@ class TableViewComponent {
|
|
|
1242
1250
|
const result = [];
|
|
1243
1251
|
const firstRow = this.data().getValueByIndex(0);
|
|
1244
1252
|
const columnKeys = this.columns().map((column) => column.key);
|
|
1253
|
+
const hasMetadata = !!(firstRow && firstRow._metadata);
|
|
1245
1254
|
const hasVersion = !!(firstRow && firstRow._metadata && firstRow._metadata.object_version);
|
|
1246
|
-
if (
|
|
1255
|
+
if (hasMetadata && !this.config()?.hideInfo) {
|
|
1247
1256
|
result.push('info');
|
|
1248
1257
|
}
|
|
1249
1258
|
result.push(...columnKeys);
|
|
@@ -1342,11 +1351,11 @@ class TableViewComponent {
|
|
|
1342
1351
|
injector: this.injector,
|
|
1343
1352
|
})
|
|
1344
1353
|
.subscribe({
|
|
1345
|
-
next: event => {
|
|
1354
|
+
next: (event) => {
|
|
1346
1355
|
if (event.type === 'cell_clicked') {
|
|
1347
1356
|
this.onCellClicked(event.data);
|
|
1348
1357
|
}
|
|
1349
|
-
}
|
|
1358
|
+
},
|
|
1350
1359
|
});
|
|
1351
1360
|
}
|
|
1352
1361
|
onCellClicked(data) {
|
|
@@ -1382,6 +1391,20 @@ class TableViewComponent {
|
|
|
1382
1391
|
}
|
|
1383
1392
|
});
|
|
1384
1393
|
}
|
|
1394
|
+
else if (type === 'update_form') {
|
|
1395
|
+
if (clone.controlSource?.params) {
|
|
1396
|
+
clone.controlSource.params = this.interpolateRowValues(clone.controlSource.params, row);
|
|
1397
|
+
}
|
|
1398
|
+
this.setView({
|
|
1399
|
+
id: action.type,
|
|
1400
|
+
type: 'form',
|
|
1401
|
+
controlSource: {
|
|
1402
|
+
kind: clone.controlSource.kind,
|
|
1403
|
+
entity: clone.controlSource.entity,
|
|
1404
|
+
params: clone.controlSource.params,
|
|
1405
|
+
},
|
|
1406
|
+
});
|
|
1407
|
+
}
|
|
1385
1408
|
}
|
|
1386
1409
|
processTableAction(action) {
|
|
1387
1410
|
if (action.type === 'update_form') {
|
|
@@ -1425,7 +1448,7 @@ class TableViewComponent {
|
|
|
1425
1448
|
}
|
|
1426
1449
|
if (node.dataSource?.kind === 'transaction') {
|
|
1427
1450
|
const body = Object.assign({}, node.dataSource.params, buildRequestBody(ctx));
|
|
1428
|
-
this.apiService.executeTransaction(node.dataSource.entity, body);
|
|
1451
|
+
return this.apiService.executeTransaction(node.dataSource.entity, body);
|
|
1429
1452
|
}
|
|
1430
1453
|
if (node.dataSource?.kind === 'object') {
|
|
1431
1454
|
return this.apiService.getObjectByAddress(node.dataSource.entity, node.dataSource.params ?? {});
|
|
@@ -1849,17 +1872,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
|
|
|
1849
1872
|
args: [{ imports: [ToastListItemComponent], template: "@if (toasts().length) {\n <div class=\"le-toast-list\">\n @for (toast of toasts(); track toast.id) {\n <div\n class=\"le-toast\"\n [class.le-toast--success]=\"toast.type === 'success'\"\n [class.le-toast--info]=\"toast.type === 'info'\"\n [class.le-toast--warning]=\"toast.type === 'warning'\"\n [class.le-toast--error]=\"toast.type === 'error'\"\n >\n <le-toast-list-item\n [controls]=\"toast.controls\"\n (actions)=\"onActions($event)\"\n ></le-toast-list-item>\n </div>\n }\n </div>\n}\n" }]
|
|
1850
1873
|
}] });
|
|
1851
1874
|
|
|
1852
|
-
let ID = 100_000_000;
|
|
1875
|
+
let ID$1 = 100_000_000;
|
|
1853
1876
|
class LeToastService {
|
|
1854
1877
|
overlayRef;
|
|
1855
1878
|
overlay = inject(Overlay);
|
|
1856
1879
|
_toasts = signal([]);
|
|
1857
1880
|
toasts = this._toasts.asReadonly();
|
|
1881
|
+
hasToasts = computed(() => this._toasts().length > 0);
|
|
1858
1882
|
action$ = new Subject();
|
|
1859
1883
|
constructor() {
|
|
1860
1884
|
effect(() => {
|
|
1861
|
-
|
|
1862
|
-
if (toasts.length > 0) {
|
|
1885
|
+
if (this.hasToasts()) {
|
|
1863
1886
|
this.show();
|
|
1864
1887
|
}
|
|
1865
1888
|
else {
|
|
@@ -1899,7 +1922,7 @@ class LeToastService {
|
|
|
1899
1922
|
this.overlayRef = undefined;
|
|
1900
1923
|
}
|
|
1901
1924
|
buildToast(type, messages) {
|
|
1902
|
-
const id = `${type}_${ID++}`;
|
|
1925
|
+
const id = `${type}_${ID$1++}`;
|
|
1903
1926
|
return {
|
|
1904
1927
|
id,
|
|
1905
1928
|
type,
|
|
@@ -2092,12 +2115,44 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
|
|
|
2092
2115
|
type: Injectable
|
|
2093
2116
|
}] });
|
|
2094
2117
|
|
|
2118
|
+
class LeActionsService {
|
|
2119
|
+
_queue = [];
|
|
2120
|
+
_data = null;
|
|
2121
|
+
get hasActions() {
|
|
2122
|
+
return this._queue.length > 0;
|
|
2123
|
+
}
|
|
2124
|
+
setActions(actions, data) {
|
|
2125
|
+
this._queue = actions;
|
|
2126
|
+
this._data = data;
|
|
2127
|
+
}
|
|
2128
|
+
getActions() {
|
|
2129
|
+
const actions = this._queue.slice();
|
|
2130
|
+
const data = Object.assign({}, this._data);
|
|
2131
|
+
this._queue = [];
|
|
2132
|
+
this._data = null;
|
|
2133
|
+
return {
|
|
2134
|
+
actions,
|
|
2135
|
+
data,
|
|
2136
|
+
};
|
|
2137
|
+
}
|
|
2138
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LeActionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2139
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LeActionsService, providedIn: 'root' });
|
|
2140
|
+
}
|
|
2141
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: LeActionsService, decorators: [{
|
|
2142
|
+
type: Injectable,
|
|
2143
|
+
args: [{
|
|
2144
|
+
providedIn: 'root',
|
|
2145
|
+
}]
|
|
2146
|
+
}] });
|
|
2147
|
+
|
|
2148
|
+
let ID = 100_000_000;
|
|
2095
2149
|
class FormViewComponent {
|
|
2096
2150
|
apiService = inject(LEApiService);
|
|
2097
2151
|
dataService = inject(LEDataService);
|
|
2098
2152
|
attachmentService = inject(FormViewAttachmentService);
|
|
2099
2153
|
viewportScroller = inject(ViewportScroller);
|
|
2100
2154
|
toastService = inject(LeToastService);
|
|
2155
|
+
actionsService = inject(LeActionsService);
|
|
2101
2156
|
_isLoading = signal(false);
|
|
2102
2157
|
_form = signal(null);
|
|
2103
2158
|
_sections = signal([]);
|
|
@@ -2172,15 +2227,20 @@ class FormViewComponent {
|
|
|
2172
2227
|
return of(null);
|
|
2173
2228
|
},
|
|
2174
2229
|
show_popup: (action, response) => {
|
|
2230
|
+
const rawControls = this.normalizeControls(action.controls);
|
|
2231
|
+
const controls = this.populatePopupControlsWithResponseData(rawControls, response);
|
|
2175
2232
|
this.toastService.notify({
|
|
2176
|
-
controls
|
|
2233
|
+
controls,
|
|
2177
2234
|
id: action.id,
|
|
2178
2235
|
type: 'success',
|
|
2179
2236
|
});
|
|
2180
2237
|
return of(null);
|
|
2181
2238
|
},
|
|
2182
2239
|
close_popup: (action) => {
|
|
2183
|
-
|
|
2240
|
+
// TODO: models alignment required (to target_id)
|
|
2241
|
+
// @ts-ignore
|
|
2242
|
+
const id = action.target_id || action.target;
|
|
2243
|
+
this.toastService.remove(id);
|
|
2184
2244
|
return of(null);
|
|
2185
2245
|
},
|
|
2186
2246
|
open_url: (action) => {
|
|
@@ -2269,6 +2329,7 @@ class FormViewComponent {
|
|
|
2269
2329
|
objectLatest: (className) => firstValueFrom(this.dataService.getObjectByClassName(className)),
|
|
2270
2330
|
};
|
|
2271
2331
|
this._engine.set(createEngine(form, {}, resolvers));
|
|
2332
|
+
this.checkDelayedActions();
|
|
2272
2333
|
// this._engine()?.on('valueChanges', (value) => {
|
|
2273
2334
|
// console.log('Value Changes', value);
|
|
2274
2335
|
// // this.cdr.markForCheck();
|
|
@@ -2349,13 +2410,35 @@ class FormViewComponent {
|
|
|
2349
2410
|
};
|
|
2350
2411
|
}
|
|
2351
2412
|
processActionList(items, response) {
|
|
2413
|
+
const updateViewActionIndex = items.findIndex((item) => item.type === 'update_form' || item.type === 'update_table');
|
|
2414
|
+
if (updateViewActionIndex !== -1) {
|
|
2415
|
+
const delayedActions = items.splice(updateViewActionIndex + 1);
|
|
2416
|
+
this.actionsService.setActions(delayedActions, response ?? null);
|
|
2417
|
+
}
|
|
2352
2418
|
from(items)
|
|
2353
2419
|
.pipe(concatMap((a) => this.processAction(a, response)), finalize(() => {
|
|
2354
2420
|
this._isLoading.set(false);
|
|
2355
2421
|
}))
|
|
2356
2422
|
.subscribe();
|
|
2357
2423
|
}
|
|
2358
|
-
|
|
2424
|
+
checkDelayedActions() {
|
|
2425
|
+
if (this.actionsService.hasActions) {
|
|
2426
|
+
const { actions, data } = this.actionsService.getActions();
|
|
2427
|
+
this.processActionList(actions, data);
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
normalizeControls(controls) {
|
|
2431
|
+
return controls.map((control) => {
|
|
2432
|
+
if (!control.id) {
|
|
2433
|
+
return {
|
|
2434
|
+
...control,
|
|
2435
|
+
id: `${control.type}_${ID++}`,
|
|
2436
|
+
};
|
|
2437
|
+
}
|
|
2438
|
+
return control;
|
|
2439
|
+
});
|
|
2440
|
+
}
|
|
2441
|
+
populatePopupControlsWithResponseData(controls, response) {
|
|
2359
2442
|
return controls.map((control) => {
|
|
2360
2443
|
if (isPlaceholder(control.value)) {
|
|
2361
2444
|
const path = getPlaceholderValue(control.value);
|
|
@@ -2691,7 +2774,7 @@ const LEAuthInterceptor = (req, next) => {
|
|
|
2691
2774
|
if (authService.isGuest()) {
|
|
2692
2775
|
return next(req);
|
|
2693
2776
|
}
|
|
2694
|
-
if (req.context.get(
|
|
2777
|
+
if (req.context.get(LE_REQUEST_CONTEXT_TOKEN)) {
|
|
2695
2778
|
try {
|
|
2696
2779
|
authService.validateToken();
|
|
2697
2780
|
return next(req.clone({ setHeaders: { Authorization: authService.token() } }));
|
|
@@ -2708,5 +2791,5 @@ const LEAuthInterceptor = (req, next) => {
|
|
|
2708
2791
|
* Generated bundle index. Do not edit.
|
|
2709
2792
|
*/
|
|
2710
2793
|
|
|
2711
|
-
export { CONFIG_TOKEN, LEAuthInterceptor, LEAuthService, LeContainerComponent, LeToastService, provideConfig };
|
|
2794
|
+
export { CONFIG_TOKEN, LEAuthInterceptor, LEAuthService, CONFIG_TOKEN as LE_CONFIG_TOKEN, LE_REQUEST_CONTEXT_TOKEN, LeContainerComponent, LeToastService, provideConfig };
|
|
2712
2795
|
//# sourceMappingURL=planeasyinc-le-angular.mjs.map
|