@c8y/tutorial 1022.10.1 → 1022.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cumulocity.config.ts +39 -4
- package/package.json +7 -7
- package/src/__mocks/global-mocks/inventory.interceptor.ts +6 -1
- package/src/__mocks/global-mocks/provider-configuration.ts +62 -0
- package/src/__mocks/global-mocks/provider-definitions.ts +24 -0
- package/src/__mocks/index.ts +18 -0
- package/src/countdown/countdown-example.component.html +4 -1
- package/src/countdown/countdown-example.component.ts +1 -0
- package/src/dynamic-forms/custom-element-example/custom-element-example.component.ts +2 -2
- package/src/dynamic-forms/introduction-example/introduction-example.component.ts +2 -2
- package/src/dynamic-forms/json-schema-example/json-schema-example.component.html +2 -2
- package/src/dynamic-forms/validation-example/validation-example.component.ts +2 -2
- package/src/for-of-directive/for-of-example.component.ts +3 -3
- package/src/generate-json-schema/generate-json-schema.component.ts +1 -0
- package/src/hooks/docs/docs-example.service.ts +17 -0
- package/src/hooks/docs/hook-docs-example.component.ts +17 -0
- package/src/hooks/docs/hook-docs.module.ts +30 -0
- package/src/hooks/preview-feature/index.ts +0 -1
- package/src/hooks/tabs/named-outlet/basic-view/basic-view.component.html +15 -0
- package/src/hooks/tabs/named-outlet/basic-view/basic-view.component.ts +25 -0
- package/src/hooks/tabs/named-outlet/content-a.component.ts +8 -0
- package/src/hooks/tabs/named-outlet/content-b.component.ts +8 -0
- package/src/hooks/tabs/named-outlet/named-outlet.module.ts +80 -0
- package/src/hooks/tabs/tabs.module.ts +0 -2
- package/src/hooks/widget/context-dashboard.component.ts +13 -0
- package/src/hooks/widget/widget.providers.ts +18 -0
- package/src/hooks/widget-config/basic-view/basic-edit.component.ts +18 -1
- package/src/hooks/widget-config/widget-config.providers.ts +0 -3
- package/src/input-group/extendable-input-list-example.component.ts +19 -3
- package/src/lazy-widget/lazy-widget-config/lazy-widget-config.component.ts +19 -3
- package/src/list/list/list-check/list-check.component.html +1 -1
- package/src/maps/cluster-map/cluster-map-example.component.html +31 -10
- package/src/maps/cluster-map/cluster-map-example.component.ts +7 -2
- package/src/maps/cluster-map-root-node/cluster-map-root-node-example.component.html +13 -17
- package/src/maps/map-popup/map-popup-example.component.html +4 -4
- package/src/maps/simple-map/simple-map-example.component.html +8 -5
- package/src/maps/simple-map/simple-map-example.module.ts +1 -1
- package/src/maps/simple-map-custom-config/map-layer.service.ts +50 -0
- package/src/maps/simple-map-custom-config/simple-map-custom-config.component.html +27 -0
- package/src/maps/simple-map-custom-config/simple-map-custom-config.component.ts +16 -0
- package/src/maps/simple-map-custom-config/simple-map-custom-config.module.ts +35 -0
- package/src/pattern-messages/pattern-messages-array.ts +20 -0
- package/src/pattern-messages/pattern-messages-factory.ts +18 -0
- package/src/pattern-messages/pattern-messages-single.ts +10 -0
- package/src/popconfirm/pop-confirm-example.component.ts +5 -2
- package/src/quick-link/quick-link-example.component.ts +0 -3
- package/src/realtime/realtime-tutorial.component.html +39 -30
- package/src/selector/alarm-event-selector-example/alarm-event-selector.component.ts +19 -15
- package/src/selector/data-points-export-selector-example/datapoints-export-selector.component.ts +11 -15
- package/src/translations/text-translation/gettext-translation/text-translation-gettext.component.ts +8 -6
- package/src/hooks/preview-feature/preview-feature.module.ts +0 -11
- package/src/hooks/widget-config/basic-view/basic-edit.component.html +0 -18
package/cumulocity.config.ts
CHANGED
|
@@ -192,6 +192,13 @@ export default {
|
|
|
192
192
|
description: 'A sample for simple map.',
|
|
193
193
|
scope: 'self'
|
|
194
194
|
},
|
|
195
|
+
{
|
|
196
|
+
name: 'Simple map with custom config',
|
|
197
|
+
module: 'SimpleMapCustomConfigModule',
|
|
198
|
+
path: './src/maps/simple-map-custom-config/simple-map-custom-config.module.ts',
|
|
199
|
+
description: 'A sample for simple map with custom config.',
|
|
200
|
+
scope: 'self'
|
|
201
|
+
},
|
|
195
202
|
{
|
|
196
203
|
name: 'Cluster map',
|
|
197
204
|
module: 'ClusterMapExampleModule',
|
|
@@ -214,10 +221,17 @@ export default {
|
|
|
214
221
|
scope: 'self'
|
|
215
222
|
},
|
|
216
223
|
{
|
|
217
|
-
name: 'Preview feature',
|
|
218
|
-
module: '
|
|
219
|
-
path: './src/hooks/preview-feature/preview-feature.module.ts',
|
|
220
|
-
description: 'A sample for feature preview hook.',
|
|
224
|
+
name: 'Default Preview feature',
|
|
225
|
+
module: 'PreviewFeatureDefaultModule',
|
|
226
|
+
path: './src/hooks/preview-feature/basic-view-default/preview-feature-default.module.ts',
|
|
227
|
+
description: 'A sample for default feature preview hook.',
|
|
228
|
+
scope: 'self'
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
name: 'Custom Preview feature',
|
|
232
|
+
module: 'PreviewFeatureCustomModule',
|
|
233
|
+
path: './src/hooks/preview-feature/basic-view-custom/preview-feature-custom.module.ts',
|
|
234
|
+
description: 'A sample for custom feature preview hook.',
|
|
221
235
|
scope: 'self'
|
|
222
236
|
},
|
|
223
237
|
{
|
|
@@ -290,6 +304,13 @@ export default {
|
|
|
290
304
|
description: 'A sample for tabs hook.',
|
|
291
305
|
scope: 'self'
|
|
292
306
|
},
|
|
307
|
+
{
|
|
308
|
+
name: 'Named router outlet',
|
|
309
|
+
module: 'NamedOutletModule',
|
|
310
|
+
path: './src/hooks/tabs/named-outlet/named-outlet.module.ts',
|
|
311
|
+
description: 'A sample for named router outlet and related hooks.',
|
|
312
|
+
scope: 'self'
|
|
313
|
+
},
|
|
293
314
|
{
|
|
294
315
|
name: 'Navigator-route',
|
|
295
316
|
module: 'NavigatorRouteModule',
|
|
@@ -780,6 +801,13 @@ export default {
|
|
|
780
801
|
description: 'This is an example for an Action added via service or factory.',
|
|
781
802
|
scope: 'self'
|
|
782
803
|
},
|
|
804
|
+
{
|
|
805
|
+
name: 'Hooking via service',
|
|
806
|
+
module: 'HookDocsModule',
|
|
807
|
+
path: './src/hooks/docs/hook-docs.module.ts',
|
|
808
|
+
description: 'This is an example for an hook docs added via module or service.',
|
|
809
|
+
scope: 'self'
|
|
810
|
+
},
|
|
783
811
|
{
|
|
784
812
|
name: 'Device connection status',
|
|
785
813
|
module: 'DeviceConnectionStatusExampleModule',
|
|
@@ -821,6 +849,13 @@ export default {
|
|
|
821
849
|
path: './src/hooks/widget-config/widget-config.providers.ts',
|
|
822
850
|
description: 'This is an example for the bottom drawer service.',
|
|
823
851
|
scope: 'self'
|
|
852
|
+
},
|
|
853
|
+
{
|
|
854
|
+
name: 'Widget Hook',
|
|
855
|
+
module: 'widgetHookProviders',
|
|
856
|
+
path: './src/hooks/widget/widget.providers.ts',
|
|
857
|
+
description: 'This is an example for the bottom drawer service.',
|
|
858
|
+
scope: 'self'
|
|
824
859
|
}
|
|
825
860
|
]
|
|
826
861
|
},
|
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@c8y/tutorial",
|
|
3
|
-
"version": "1022.
|
|
3
|
+
"version": "1022.13.0",
|
|
4
4
|
"description": "This package is used to scaffold a tutorial for Cumulocity IoT Web SDK which explains a lot of concepts.",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@c8y/style": "1022.
|
|
7
|
-
"@c8y/ngx-components": "1022.
|
|
8
|
-
"@c8y/client": "1022.
|
|
9
|
-
"@c8y/bootstrap": "1022.
|
|
6
|
+
"@c8y/style": "1022.13.0",
|
|
7
|
+
"@c8y/ngx-components": "1022.13.0",
|
|
8
|
+
"@c8y/client": "1022.13.0",
|
|
9
|
+
"@c8y/bootstrap": "1022.13.0",
|
|
10
10
|
"@angular/cdk": "^19.2.18",
|
|
11
11
|
"ngx-bootstrap": "19.0.2",
|
|
12
12
|
"leaflet": "1.9.4",
|
|
13
13
|
"rxjs": "7.8.1"
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
|
-
"@c8y/options": "1022.
|
|
17
|
-
"@c8y/devkit": "1022.
|
|
16
|
+
"@c8y/options": "1022.13.0",
|
|
17
|
+
"@c8y/devkit": "1022.13.0"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
20
|
"@angular/common": ">=19 <20"
|
|
@@ -69,8 +69,13 @@ export class InventoryInterceptor implements HttpInterceptor {
|
|
|
69
69
|
'has(c8y_IsDeviceGroup)': () => ({
|
|
70
70
|
managedObjects: [...[...Array(5)].map(() => generateGroup())]
|
|
71
71
|
}),
|
|
72
|
+
// generate 3 realtime devices for the map example
|
|
72
73
|
'has(c8y_Position)': () => ({
|
|
73
|
-
managedObjects: [
|
|
74
|
+
managedObjects: [
|
|
75
|
+
generateRealtimeDeviceMO(),
|
|
76
|
+
generateRealtimeDeviceMO(),
|
|
77
|
+
generateRealtimeDeviceMO()
|
|
78
|
+
]
|
|
74
79
|
}),
|
|
75
80
|
'has(c8y_IsDevice)': () => ({
|
|
76
81
|
managedObjects: [...[...Array(5)].map(() => generateDevice())]
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { IFetchResponse } from '@c8y/client';
|
|
2
|
+
import { ApiCall, HttpHandler, HttpInterceptor } from '@c8y/ngx-components/api';
|
|
3
|
+
import { handleRequest } from '../utils/common';
|
|
4
|
+
import { Observable } from 'rxjs';
|
|
5
|
+
|
|
6
|
+
export class ProviderConfigurationsApiInterceptor implements HttpInterceptor {
|
|
7
|
+
configurations = [
|
|
8
|
+
{ id: 'provider1', config: { username: 'user1', password: 'pass1' } },
|
|
9
|
+
{ id: 'provider2', config: { username: 'user2', password: 'pass2' } }
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
intercept(req: ApiCall, next: HttpHandler): Observable<IFetchResponse> {
|
|
13
|
+
return handleRequest(req, next, '/service/demo/providers/configuration', {
|
|
14
|
+
GET: this.mockGET.bind(this),
|
|
15
|
+
POST: this.mockPOST.bind(this),
|
|
16
|
+
PUT: this.mockPUT.bind(this),
|
|
17
|
+
DELETE: this.mockDELETE.bind(this)
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
private async mockGET(_requestDescriptor: string) {
|
|
22
|
+
return {
|
|
23
|
+
status: 200,
|
|
24
|
+
json: async () => this.configurations
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private async mockPOST(requestDescriptor: string) {
|
|
29
|
+
const bodyStartIndex = requestDescriptor.indexOf('{');
|
|
30
|
+
const body = bodyStartIndex !== -1 ? JSON.parse(requestDescriptor.slice(bodyStartIndex)) : {};
|
|
31
|
+
this.configurations.push(body);
|
|
32
|
+
return {
|
|
33
|
+
status: 201,
|
|
34
|
+
json: async () => body
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private async mockPUT(requestDescriptor: string) {
|
|
39
|
+
const bodyStartIndex = requestDescriptor.indexOf('{');
|
|
40
|
+
const body = bodyStartIndex !== -1 ? JSON.parse(requestDescriptor.slice(bodyStartIndex)) : {};
|
|
41
|
+
const idx = this.configurations.findIndex(c => c.id === body.id);
|
|
42
|
+
if (idx > -1) {
|
|
43
|
+
this.configurations[idx] = body;
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
status: 200,
|
|
47
|
+
json: async () => body
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private async mockDELETE(requestDescriptor: string) {
|
|
52
|
+
const match = requestDescriptor.match(/\/configuration\/([^/]+)/);
|
|
53
|
+
if (match) {
|
|
54
|
+
const id = match[1];
|
|
55
|
+
this.configurations = this.configurations.filter(c => c.id !== id);
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
status: 204,
|
|
59
|
+
json: async () => ({})
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { IFetchResponse } from '@c8y/client';
|
|
2
|
+
import { ApiCall, HttpHandler, HttpInterceptor } from '@c8y/ngx-components/api';
|
|
3
|
+
import { handleRequest } from '../utils/common';
|
|
4
|
+
import { Observable } from 'rxjs';
|
|
5
|
+
|
|
6
|
+
export class ProviderDefinitionsApiInterceptor implements HttpInterceptor {
|
|
7
|
+
providers = [
|
|
8
|
+
{ id: 'provider1', name: 'Provider One' },
|
|
9
|
+
{ id: 'provider2', name: 'Provider Two' }
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
intercept(req: ApiCall, next: HttpHandler): Observable<IFetchResponse> {
|
|
13
|
+
return handleRequest(req, next, '/service/demo/providers/definitions', {
|
|
14
|
+
GET: this.mockGET.bind(this)
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
private async mockGET(_requestDescriptor: string) {
|
|
19
|
+
return {
|
|
20
|
+
status: 200,
|
|
21
|
+
json: async () => this.providers
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
}
|
package/src/__mocks/index.ts
CHANGED
|
@@ -24,6 +24,8 @@ import { EnvironmentProviders, Provider, inject, provideAppInitializer } from '@
|
|
|
24
24
|
import { MockService } from './mock.service';
|
|
25
25
|
import { IUser } from '@c8y/client';
|
|
26
26
|
import { FeatureApiInterceptor } from './global-mocks/feature-api';
|
|
27
|
+
import { ProviderDefinitionsApiInterceptor } from './global-mocks/provider-definitions';
|
|
28
|
+
import { ProviderConfigurationsApiInterceptor } from './global-mocks/provider-configuration';
|
|
27
29
|
|
|
28
30
|
export function provideAPIMock() {
|
|
29
31
|
return [
|
|
@@ -161,6 +163,22 @@ export function provideAPIMock() {
|
|
|
161
163
|
} as ApiMockConfig,
|
|
162
164
|
multi: true
|
|
163
165
|
},
|
|
166
|
+
{
|
|
167
|
+
provide: API_MOCK_CONFIG,
|
|
168
|
+
useValue: {
|
|
169
|
+
id: 'z-global-provider-definitions-interceptor-interceptor',
|
|
170
|
+
mockService: ProviderDefinitionsApiInterceptor
|
|
171
|
+
} as ApiMockConfig,
|
|
172
|
+
multi: true
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
provide: API_MOCK_CONFIG,
|
|
176
|
+
useValue: {
|
|
177
|
+
id: 'z-global-provider-configurations-interceptor-interceptor',
|
|
178
|
+
mockService: ProviderConfigurationsApiInterceptor
|
|
179
|
+
} as ApiMockConfig,
|
|
180
|
+
multi: true
|
|
181
|
+
},
|
|
164
182
|
{
|
|
165
183
|
provide: RealtimeSubjectService,
|
|
166
184
|
useExisting: RealtimeSubjectServiceWithMocking
|
|
@@ -9,7 +9,7 @@ import { FormlyModule } from '@ngx-formly/core';
|
|
|
9
9
|
selector: 'c8y-custom-element-example',
|
|
10
10
|
template: `<c8y-title>Dynamic forms: Custom element</c8y-title>
|
|
11
11
|
<div class="row">
|
|
12
|
-
<div class="col-xs-12 col-
|
|
12
|
+
<div class="col-xs-12 col-md-7 col-lg-6">
|
|
13
13
|
<form class="card" [formGroup]="form" (ngSubmit)="onSubmit()">
|
|
14
14
|
<div class="card-block">
|
|
15
15
|
<formly-form [form]="form" [fields]="fields" [model]="model"></formly-form>
|
|
@@ -20,7 +20,7 @@ import { FormlyModule } from '@ngx-formly/core';
|
|
|
20
20
|
</div>
|
|
21
21
|
</form>
|
|
22
22
|
</div>
|
|
23
|
-
<div class="col-xs-12 col-
|
|
23
|
+
<div class="col-xs-12 col-md-5 col-lg-6">
|
|
24
24
|
<div class="card">
|
|
25
25
|
<div class="card-block">
|
|
26
26
|
<div class="legend form-block">Model</div>
|
|
@@ -8,7 +8,7 @@ import { FormlyFieldConfig } from '@ngx-formly/core';
|
|
|
8
8
|
selector: 'c8y-introduction-example',
|
|
9
9
|
template: `<c8y-title>Dynamic forms: Introduction</c8y-title>
|
|
10
10
|
<div class="row">
|
|
11
|
-
<div class="col-xs-12 col-
|
|
11
|
+
<div class="col-xs-12 col-md-7 col-lg-6">
|
|
12
12
|
<form class="card" [formGroup]="form" (ngSubmit)="onSubmit()">
|
|
13
13
|
<div class="card-block">
|
|
14
14
|
<formly-form [form]="form" [fields]="fields" [model]="model"></formly-form>
|
|
@@ -19,7 +19,7 @@ import { FormlyFieldConfig } from '@ngx-formly/core';
|
|
|
19
19
|
</div>
|
|
20
20
|
</form>
|
|
21
21
|
</div>
|
|
22
|
-
<div class="col-xs-12 col-
|
|
22
|
+
<div class="col-xs-12 col-md-5 col-lg-6">
|
|
23
23
|
<div class="card">
|
|
24
24
|
<div class="card-block">
|
|
25
25
|
<div class="legend form-block">Model</div>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<c8y-title>Dynamic forms: JSON schema</c8y-title>
|
|
2
2
|
<div class="row">
|
|
3
|
-
<div class="col-xs-12 col-
|
|
3
|
+
<div class="col-xs-12 col-md-7 col-lg-6">
|
|
4
4
|
<form class="card" [formGroup]="form" (ngSubmit)="onSubmit()">
|
|
5
5
|
<div class="card-block">
|
|
6
6
|
<!-- important -->
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
</div>
|
|
23
23
|
</form>
|
|
24
24
|
</div>
|
|
25
|
-
<div class="col-xs-12 col-
|
|
25
|
+
<div class="col-xs-12 col-md-5 col-lg-6">
|
|
26
26
|
<div class="card">
|
|
27
27
|
<div class="card-block">
|
|
28
28
|
<div class="legend form-block">Model</div>
|
|
@@ -13,7 +13,7 @@ export function ipValidator(control: AbstractControl): ValidationErrors {
|
|
|
13
13
|
selector: 'c8y-validation-example',
|
|
14
14
|
template: `<c8y-title>Dynamic forms: Validation</c8y-title>
|
|
15
15
|
<div class="row">
|
|
16
|
-
<div class="col-xs-12 col-
|
|
16
|
+
<div class="col-xs-12 col-md-7 col-lg-6">
|
|
17
17
|
<form class="card" [formGroup]="form" (ngSubmit)="onSubmit()">
|
|
18
18
|
<div class="card-block">
|
|
19
19
|
<formly-form [form]="form" [fields]="fields" [model]="model"></formly-form>
|
|
@@ -24,7 +24,7 @@ export function ipValidator(control: AbstractControl): ValidationErrors {
|
|
|
24
24
|
</div>
|
|
25
25
|
</form>
|
|
26
26
|
</div>
|
|
27
|
-
<div class="col-xs-12 col-
|
|
27
|
+
<div class="col-xs-12 col-md-5 col-lg-6">
|
|
28
28
|
<div class="card">
|
|
29
29
|
<div class="card-block">
|
|
30
30
|
<div class="legend form-block">Model</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Component } from '@angular/core';
|
|
2
|
-
import { CoreModule, ForOfFilterPipe } from '@c8y/ngx-components';
|
|
2
|
+
import { CoreModule, ForOfDirective, ForOfFilterPipe, LoadMoreMode } from '@c8y/ngx-components';
|
|
3
3
|
import { IManagedObject, InventoryService, IResultList } from '@c8y/client';
|
|
4
4
|
import { pipe } from 'rxjs';
|
|
5
5
|
import { map, tap } from 'rxjs/operators';
|
|
@@ -8,13 +8,13 @@ import { map, tap } from 'rxjs/operators';
|
|
|
8
8
|
selector: 'c8y-for-of-example',
|
|
9
9
|
templateUrl: './for-of-example.component.html',
|
|
10
10
|
standalone: true,
|
|
11
|
-
imports: [CoreModule]
|
|
11
|
+
imports: [CoreModule, ForOfDirective]
|
|
12
12
|
})
|
|
13
13
|
export class ForOfExampleComponent {
|
|
14
14
|
devices: IResultList<IManagedObject>;
|
|
15
15
|
filterPipe: ForOfFilterPipe = pipe(tap());
|
|
16
16
|
config = {
|
|
17
|
-
loadMore: 'auto',
|
|
17
|
+
loadMore: 'auto' as LoadMoreMode,
|
|
18
18
|
filter: '',
|
|
19
19
|
pageSize: 10,
|
|
20
20
|
maxIterations: 12
|
|
@@ -6,6 +6,7 @@ import { CoreModule } from '@c8y/ngx-components';
|
|
|
6
6
|
template: `
|
|
7
7
|
<h3>Base interface</h3>
|
|
8
8
|
<pre>{{ baseInterface }}</pre>
|
|
9
|
+
<h3>Referenced types in base interface</h3>
|
|
9
10
|
<pre>{{ referencedInterfaces }}</pre>
|
|
10
11
|
<h3>JSON Schema generated from ExampleInterface</h3>
|
|
11
12
|
<pre>{{ schemaString }}</pre>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { DocLink, ExtensionFactory } from '@c8y/ngx-components';
|
|
3
|
+
import { Observable, of } from 'rxjs';
|
|
4
|
+
|
|
5
|
+
@Injectable()
|
|
6
|
+
export class DocsExampleService implements ExtensionFactory<DocLink> {
|
|
7
|
+
get(): Observable<DocLink[]> {
|
|
8
|
+
return of([
|
|
9
|
+
{
|
|
10
|
+
icon: 'c8y-icon c8y-icon-mobile-add',
|
|
11
|
+
type: 'doc',
|
|
12
|
+
url: 'https://cumulocity.com',
|
|
13
|
+
label: 'Doc link from service'
|
|
14
|
+
}
|
|
15
|
+
]);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
import { TitleComponent } from '@c8y/ngx-components';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'c8y-hook-docs-example',
|
|
6
|
+
imports: [TitleComponent],
|
|
7
|
+
template: `
|
|
8
|
+
<c8y-title>Docs</c8y-title>
|
|
9
|
+
<div class="card">
|
|
10
|
+
<div class="card-block">
|
|
11
|
+
<p>This is the example of <code>hookDocs</code>.</p>
|
|
12
|
+
<p>See the <code>Right drawer</code> in the <code>Documentation</code> section.</p>
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
`
|
|
16
|
+
})
|
|
17
|
+
export class HookDocsExampleComponent {}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { DocLink, hookDocs, hookNavigator, hookRoute, NavigatorNode } from '@c8y/ngx-components';
|
|
3
|
+
import { DocsExampleService } from './docs-example.service';
|
|
4
|
+
|
|
5
|
+
@NgModule({
|
|
6
|
+
providers: [
|
|
7
|
+
hookDocs({
|
|
8
|
+
icon: 'c8y-icon c8y-icon-mobile-add',
|
|
9
|
+
type: 'doc',
|
|
10
|
+
url: 'https://cumulocity.com/docs/',
|
|
11
|
+
label: 'Doc link from hookDocs'
|
|
12
|
+
} as DocLink),
|
|
13
|
+
hookDocs(DocsExampleService),
|
|
14
|
+
hookRoute({
|
|
15
|
+
path: 'hooks/docs',
|
|
16
|
+
loadComponent: () =>
|
|
17
|
+
import('./hook-docs-example.component').then(m => m.HookDocsExampleComponent)
|
|
18
|
+
}),
|
|
19
|
+
hookNavigator(
|
|
20
|
+
new NavigatorNode({
|
|
21
|
+
priority: 100,
|
|
22
|
+
path: 'hooks/docs',
|
|
23
|
+
icon: 'document',
|
|
24
|
+
label: 'Docs',
|
|
25
|
+
parent: 'Hooks'
|
|
26
|
+
})
|
|
27
|
+
)
|
|
28
|
+
]
|
|
29
|
+
})
|
|
30
|
+
export class HookDocsModule {}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<c8y-title>Named router outlet example</c8y-title>
|
|
2
|
+
<div
|
|
3
|
+
clas="d-flex"
|
|
4
|
+
*ngIf="tabs.length"
|
|
5
|
+
>
|
|
6
|
+
<c8y-tabs-outlet
|
|
7
|
+
[outletName]="'namedOutletTabs'"
|
|
8
|
+
[orientation]="'horizontal'"
|
|
9
|
+
[openFirstTab]="true"
|
|
10
|
+
[tabs]="tabs"
|
|
11
|
+
></c8y-tabs-outlet>
|
|
12
|
+
<div>
|
|
13
|
+
<router-outlet name="namedOutlet"></router-outlet>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
3
|
+
import { Tab, TabsService } from '@c8y/ngx-components';
|
|
4
|
+
import { map } from 'rxjs';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* This is a standard angular component.
|
|
8
|
+
*/
|
|
9
|
+
@Component({
|
|
10
|
+
selector: 'tut-basic-view',
|
|
11
|
+
templateUrl: './basic-view.component.html',
|
|
12
|
+
standalone: false
|
|
13
|
+
})
|
|
14
|
+
export class BasicViewComponent {
|
|
15
|
+
tabs: Tab[] = [];
|
|
16
|
+
|
|
17
|
+
constructor(private tabsService: TabsService) {
|
|
18
|
+
this.tabsService.items$
|
|
19
|
+
.pipe(
|
|
20
|
+
map(tabs => tabs.filter(tab => tab.tabsOutlet === 'namedOutletTabs')),
|
|
21
|
+
takeUntilDestroyed()
|
|
22
|
+
)
|
|
23
|
+
.subscribe(tabs => (this.tabs = tabs));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import {
|
|
3
|
+
CoreModule,
|
|
4
|
+
hookNavigator,
|
|
5
|
+
hookRoute,
|
|
6
|
+
hookTab,
|
|
7
|
+
NavigatorNode,
|
|
8
|
+
NavigatorNodeData
|
|
9
|
+
} from '@c8y/ngx-components';
|
|
10
|
+
import { RouterModule } from '@angular/router';
|
|
11
|
+
import { ContentAComponent } from './content-a.component';
|
|
12
|
+
import { ContentBComponent } from './content-b.component';
|
|
13
|
+
import { BasicViewComponent } from './basic-view/basic-view.component';
|
|
14
|
+
|
|
15
|
+
const hooks = [
|
|
16
|
+
hookRoute([
|
|
17
|
+
{
|
|
18
|
+
path: 'hooks/named-outlet',
|
|
19
|
+
component: BasicViewComponent,
|
|
20
|
+
children: [
|
|
21
|
+
{
|
|
22
|
+
path: 'content-a',
|
|
23
|
+
component: ContentAComponent,
|
|
24
|
+
outlet: 'namedOutlet'
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
path: 'content-b',
|
|
28
|
+
component: ContentBComponent,
|
|
29
|
+
outlet: 'namedOutlet'
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
]),
|
|
34
|
+
hookTab([
|
|
35
|
+
{
|
|
36
|
+
label: 'Tab A',
|
|
37
|
+
icon: 'web-design',
|
|
38
|
+
priority: 20,
|
|
39
|
+
featureId: 'A',
|
|
40
|
+
path: [
|
|
41
|
+
{
|
|
42
|
+
outlets: {
|
|
43
|
+
['namedOutlet']: 'content-a'
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
],
|
|
47
|
+
tabsOutlet: 'namedOutletTabs'
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
label: 'Tab B',
|
|
51
|
+
icon: 'web-design',
|
|
52
|
+
priority: 10,
|
|
53
|
+
featureId: 'B',
|
|
54
|
+
path: [
|
|
55
|
+
{
|
|
56
|
+
outlets: {
|
|
57
|
+
['namedOutlet']: 'content-b'
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
tabsOutlet: 'namedOutletTabs'
|
|
62
|
+
}
|
|
63
|
+
]),
|
|
64
|
+
hookNavigator(
|
|
65
|
+
new NavigatorNode({
|
|
66
|
+
priority: 55,
|
|
67
|
+
path: 'hooks/named-outlet',
|
|
68
|
+
icon: 'name-tag',
|
|
69
|
+
label: 'Named router outlet',
|
|
70
|
+
parent: 'Hooks'
|
|
71
|
+
} as NavigatorNodeData)
|
|
72
|
+
)
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
@NgModule({
|
|
76
|
+
declarations: [BasicViewComponent],
|
|
77
|
+
imports: [RouterModule, ContentAComponent, ContentBComponent, CoreModule],
|
|
78
|
+
providers: [...hooks]
|
|
79
|
+
})
|
|
80
|
+
export class NamedOutletModule {}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
import { CoreModule } from '@c8y/ngx-components';
|
|
3
|
+
import { ContextDashboardModule } from '@c8y/ngx-components/context-dashboard';
|
|
4
|
+
import { CommonModule } from '@angular/common';
|
|
5
|
+
|
|
6
|
+
@Component({
|
|
7
|
+
selector: 'tut-context-dashboard',
|
|
8
|
+
template: `<c8y-title>Context dashboard</c8y-title>
|
|
9
|
+
<c8y-context-dashboard name="example-widget" [canDelete]="false"></c8y-context-dashboard> `,
|
|
10
|
+
standalone: true,
|
|
11
|
+
imports: [ContextDashboardModule, CoreModule, CommonModule]
|
|
12
|
+
})
|
|
13
|
+
export class ContextDashboardComponent {}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { hookNavigator, hookRoute, NavigatorNode } from '@c8y/ngx-components';
|
|
2
|
+
|
|
3
|
+
export const widgetHookProviders = [
|
|
4
|
+
hookRoute({
|
|
5
|
+
path: 'hooks/widget',
|
|
6
|
+
loadComponent: () =>
|
|
7
|
+
import('./context-dashboard.component').then(m => m.ContextDashboardComponent)
|
|
8
|
+
}),
|
|
9
|
+
hookNavigator(
|
|
10
|
+
new NavigatorNode({
|
|
11
|
+
priority: 75,
|
|
12
|
+
path: 'hooks/widget',
|
|
13
|
+
icon: 'edit',
|
|
14
|
+
label: 'Widget',
|
|
15
|
+
parent: 'Hooks'
|
|
16
|
+
})
|
|
17
|
+
)
|
|
18
|
+
];
|
|
@@ -13,7 +13,24 @@ import { referenceWidgetDefinition } from '../widget-config.providers';
|
|
|
13
13
|
*/
|
|
14
14
|
@Component({
|
|
15
15
|
selector: 'tut-basic-widget-config-hook-view',
|
|
16
|
-
|
|
16
|
+
template: `<div class="card">
|
|
17
|
+
<div class="card-block">
|
|
18
|
+
<c8y-widget-config-section
|
|
19
|
+
*ngFor="let section of widgetConfigService.currentSections$ | async; let i = index"
|
|
20
|
+
[section]="section"
|
|
21
|
+
></c8y-widget-config-section>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<div class="card-block">
|
|
25
|
+
<label>The configuration is:</label>
|
|
26
|
+
<code>
|
|
27
|
+
<pre>
|
|
28
|
+
{{ widgetConfigService.currentConfig$ | async | json }}
|
|
29
|
+
</pre
|
|
30
|
+
>
|
|
31
|
+
</code>
|
|
32
|
+
</div>
|
|
33
|
+
</div>`,
|
|
17
34
|
standalone: true,
|
|
18
35
|
imports: [CoreModule, CommonModule, WidgetConfigSectionComponent, AsyncPipe, JsonPipe]
|
|
19
36
|
})
|