@c8y/tutorial 1019.6.10 → 1019.6.11

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.
Files changed (27) hide show
  1. package/cumulocity.config.ts +43 -1
  2. package/package.json +6 -6
  3. package/src/__mocks/scoped-mocks/device-data-grid.ts +47 -9
  4. package/src/__mocks/utils/common.ts +23 -2
  5. package/src/__mocks/utils/grid.ts +14 -0
  6. package/src/app/app.module.ts +3 -1
  7. package/src/app-icon/app-icon-example.component.html +109 -0
  8. package/src/app-icon/app-icon-example.component.ts +56 -0
  9. package/src/app-icon/app-icon-example.module.ts +22 -0
  10. package/src/breadcrumbs/basic-example/breadcrumbs-example.component.html +23 -0
  11. package/src/breadcrumbs/basic-example/breadcrumbs-example.component.ts +13 -0
  12. package/src/breadcrumbs/basic-example/breadcrumbs-example.module.ts +23 -0
  13. package/src/breadcrumbs/breadcrumbs.module.ts +14 -0
  14. package/src/breadcrumbs/content-projection/breadcrumbs-content-projection-example.component.html +28 -0
  15. package/src/breadcrumbs/content-projection/breadcrumbs-content-projection-example.component.ts +13 -0
  16. package/src/breadcrumbs/content-projection/breadcrumbs-content-projection-example.module.ts +25 -0
  17. package/src/breadcrumbs/expand-example/breadcrumbs-expand-example.component.html +30 -0
  18. package/src/breadcrumbs/expand-example/breadcrumbs-expand-example.component.ts +13 -0
  19. package/src/breadcrumbs/expand-example/breadcrumbs-expand-example.module.ts +25 -0
  20. package/src/breadcrumbs/index.ts +5 -0
  21. package/src/breadcrumbs/outlet/breadcrumbs-outlet-example.component.html +21 -0
  22. package/src/breadcrumbs/outlet/breadcrumbs-outlet-example.component.ts +13 -0
  23. package/src/breadcrumbs/outlet/breadcrumbs-outlet-example.module.ts +25 -0
  24. package/src/device-connection-status/device-connection-status-example.component.html +145 -0
  25. package/src/device-connection-status/device-connection-status-example.component.ts +61 -0
  26. package/src/device-connection-status/device-connection-status-example.module.ts +23 -0
  27. package/src/hooks/breadcrumbs/basic-view/basic-view.component.ts +3 -1
@@ -173,11 +173,35 @@ export default {
173
173
  description: 'A sample for action bar hook.'
174
174
  },
175
175
  {
176
- name: 'Breadcrumbs',
176
+ name: 'Breadcrumbs hook',
177
177
  module: 'BreadcrumbsModule',
178
178
  path: './src/hooks/breadcrumbs/breadcrumbs.module.ts',
179
179
  description: 'A sample for breadcrumbs hook.'
180
180
  },
181
+ {
182
+ name: 'Breadcrumbs expand',
183
+ module: 'BreadcrumbsExpandExampleModule',
184
+ path: './src/breadcrumbs/expand-example/breadcrumbs-expand-example.module.ts',
185
+ description: 'A sample for breadcrumbs.'
186
+ },
187
+ {
188
+ name: 'Breadcrumbs outlet',
189
+ module: 'BreadcrumbsOutletExampleModule',
190
+ path: './src/breadcrumbs/outlet/breadcrumbs-outlet-example.module.ts',
191
+ description: 'A sample for breadcrumb outlet.'
192
+ },
193
+ {
194
+ name: 'Breadcrumbs basic',
195
+ module: 'BreadcrumbsExampleModule',
196
+ path: './src/breadcrumbs/basic-example/breadcrumbs-example.module.ts',
197
+ description: 'A sample for breadcrumbs.'
198
+ },
199
+ {
200
+ name: 'Breadcrumbs content projection',
201
+ module: 'BreadcrumbsContentProjectionExampleModule',
202
+ path: './src/breadcrumbs/content-projection/breadcrumbs-content-projection-example.module.ts',
203
+ description: 'A sample for breadcrumbs content projection.'
204
+ },
181
205
  {
182
206
  name: 'Component',
183
207
  module: 'ComponentModule',
@@ -298,6 +322,12 @@ export default {
298
322
  path: './src/alert/alert-example.module.ts',
299
323
  description: 'A sample for alerts.'
300
324
  },
325
+ {
326
+ name: 'App icon example',
327
+ module: 'AppIconExampleModule',
328
+ path: './src/app-icon/app-icon-example.module.ts',
329
+ description: 'An example for App Icon component.'
330
+ },
301
331
  {
302
332
  name: 'Client grid example',
303
333
  module: 'ClientGridExampleModule',
@@ -538,6 +568,12 @@ export default {
538
568
  path: './src/hooks/state/hook-state.module.ts',
539
569
  description: 'This is an example for an Action added via service or factory.'
540
570
  },
571
+ {
572
+ name: 'Device connection status',
573
+ module: 'DeviceConnectionStatusExampleModule',
574
+ path: './src/device-connection-status/device-connection-status-example.module.ts',
575
+ description: 'This is an example of Device connection status icons.'
576
+ },
541
577
  {
542
578
  name: 'Pagination',
543
579
  module: 'PaginationExampleModule',
@@ -562,6 +598,10 @@ export default {
562
598
  'ActionModule',
563
599
  'ActionBarModule',
564
600
  'BreadcrumbsModule',
601
+ 'BreadcrumbsExampleModule',
602
+ 'BreadcrumbsExpandExampleModule',
603
+ 'BreadcrumbsOutletExampleModule',
604
+ 'BreadcrumbsContentProjectionExampleModule',
565
605
  'ComponentModule',
566
606
  'WizardModule',
567
607
  'StepperHookModule',
@@ -590,6 +630,7 @@ export default {
590
630
  'ServiceDashboardModule',
591
631
  'NamedContextDashboardModule',
592
632
  'AlertExampleModule',
633
+ 'AppIconExampleModule',
593
634
  'RightDrawerModule',
594
635
  'LeftDrawerModule',
595
636
  'AssetSelectorExampleModule',
@@ -629,6 +670,7 @@ export default {
629
670
  'StepperModule',
630
671
  'ApplicationCardExampleModule',
631
672
  'HookStateModule',
673
+ 'DeviceConnectionStatusExampleModule',
632
674
  'PaginationExampleModule'
633
675
  ]
634
676
  }
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@c8y/tutorial",
3
- "version": "1019.6.10",
3
+ "version": "1019.6.11",
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/devkit": "1019.6.10",
7
- "@c8y/style": "1019.6.10",
8
- "@c8y/ngx-components": "1019.6.10",
9
- "@c8y/client": "1019.6.10",
10
- "@c8y/bootstrap": "1019.6.10",
6
+ "@c8y/devkit": "1019.6.11",
7
+ "@c8y/style": "1019.6.11",
8
+ "@c8y/ngx-components": "1019.6.11",
9
+ "@c8y/client": "1019.6.11",
10
+ "@c8y/bootstrap": "1019.6.11",
11
11
  "@angular/cdk": "^16.2.11",
12
12
  "ngx-bootstrap": "11.0.2",
13
13
  "leaflet": "1.7.1",
@@ -1,10 +1,13 @@
1
1
  import { IFetchResponse } from '@c8y/client';
2
2
  import { ApiCall, HttpHandler, HttpInterceptor } from '@c8y/ngx-components/api';
3
+ import { filterObjectBySearchText, filterObjects } from '../utils/grid';
3
4
  import { generateResponse, handleRequest } from '../utils/common';
4
5
  import { Observable } from 'rxjs';
5
6
  import { generateDevice } from '../../__mocks/utils/generators/managedObjects';
6
7
 
7
8
  export class DeviceDataGridInterceptor implements HttpInterceptor {
9
+ // Check handleTotalPagesRequest
10
+ private totalPages = 100;
8
11
  intercept(req: ApiCall, next: HttpHandler): Observable<IFetchResponse> {
9
12
  return handleRequest(req, next, 'inventory/managedObjects', {
10
13
  POST: this.mockPOST.bind(this),
@@ -20,25 +23,60 @@ export class DeviceDataGridInterceptor implements HttpInterceptor {
20
23
  mockPUT(_requestDescriptor: string) {
21
24
  return null;
22
25
  }
23
- private mockGET(_requestDescriptor: string) {
24
- const responseGenerators = this.getResponseGenerators();
26
+ private mockGET(_requestDescriptor: string, statistics) {
27
+ const mockedQueryStringParameters = this.getMockedQueryStringParameters();
25
28
 
26
- for (const urlPart in responseGenerators) {
29
+ for (const urlPart in mockedQueryStringParameters) {
27
30
  if (_requestDescriptor.includes(urlPart)) {
28
- const generatorResult = responseGenerators[urlPart]();
31
+ const generatorResult = mockedQueryStringParameters[urlPart];
29
32
  if (generatorResult) {
30
- return generateResponse(() => generatorResult);
33
+ if (statistics?.pageSize === 1) {
34
+ return this.handleTotalPagesRequest(statistics);
35
+ }
36
+ return this.handleDataRequest(_requestDescriptor, statistics);
31
37
  }
32
38
  }
33
39
  }
34
40
  return null;
35
41
  }
36
42
 
37
- private getResponseGenerators() {
43
+ // Sets the totalPages number to 100. Enables pagination in the device grid.
44
+ // The device grid needs to know the total number of items.
45
+ private handleTotalPagesRequest(statistics) {
46
+ statistics.totalPages = this.totalPages;
47
+ return generateResponse(
48
+ () => ({
49
+ managedObjects: [],
50
+ ...(statistics?.next && { next: statistics.next.toString() })
51
+ }),
52
+ statistics
53
+ );
54
+ }
55
+
56
+ // Handles the data request. Returns data that populates the device grid.
57
+ private handleDataRequest(_requestDescriptor, statistics) {
58
+ // statistics?.pageSize depends on the "Items per page" dropdown, where pageSize can be set to 25, 50, or 100.
59
+ const devices = [...Array(statistics?.pageSize || 25)].map(() => generateDevice());
60
+
61
+ const filteredDevices = filterObjects(devices, _requestDescriptor);
62
+
63
+ const filteredDevicesByTextSearch = filterObjectBySearchText(
64
+ filteredDevices,
65
+ _requestDescriptor
66
+ );
67
+ return generateResponse(
68
+ () => ({
69
+ managedObjects: [...filteredDevicesByTextSearch],
70
+ ...(statistics?.next && { next: statistics.next.toString() })
71
+ }),
72
+ statistics
73
+ );
74
+ }
75
+
76
+ private getMockedQueryStringParameters() {
38
77
  return {
39
- pageSize: () => ({
40
- managedObjects: [...[...Array(25)].map(() => generateDevice())]
41
- })
78
+ // Mock only requests that include a `pageSize` parameter.
79
+ pageSize: true
42
80
  };
43
81
  }
44
82
  }
@@ -72,8 +72,10 @@ export function handleRequest(
72
72
  const { method = 'GET' } = req?.options || {};
73
73
 
74
74
  if (requestDescriptor.includes(urlPath) && handlers[method]) {
75
- const response = handlers[method](requestDescriptor);
76
- return response ? from(Promise.resolve(response)) : next.handle(req);
75
+ const statistics = generateStatistics(req?.options?.params);
76
+ const mockedResponse = handlers[method](requestDescriptor, statistics);
77
+
78
+ return mockedResponse ? from(Promise.resolve(mockedResponse)) : next.handle(req);
77
79
  }
78
80
  return next.handle(req);
79
81
  }
@@ -112,3 +114,22 @@ export function generateResponse<T>(bodyGenerator: () => T, statistics = DEFAULT
112
114
  });
113
115
  return newResponse as ResponseWithType<T & { statistics: typeof DEFAULT_STATISTICS }>;
114
116
  }
117
+
118
+ /**
119
+ * Generates statistics by merging default statistics with external statistics.
120
+ *
121
+ * @param params A `Record<string, any>` object containing optional statistics parameters such as `totalPages`, `pageSize`, and `currentPage`.
122
+ * - `totalPages` specifies the total number of pages.
123
+ * - `pageSize` specifies the number of items per page.
124
+ * - `currentPage` specifies the current page number.
125
+ * @returns A statistics object that enables and handles pagination in the mocked response.
126
+ */
127
+ function generateStatistics(params: Record<string, any>): typeof DEFAULT_STATISTICS {
128
+ return {
129
+ ...DEFAULT_STATISTICS,
130
+ ...(params?.totalPages && { totalPages: params.totalPages }),
131
+ ...(params?.pageSize && { pageSize: params.pageSize }),
132
+ ...(params?.currentPage && { currentPage: params.currentPage }),
133
+ ...(params?.currentPage && { next: params.currentPage + 1 })
134
+ } as typeof DEFAULT_STATISTICS;
135
+ }
@@ -58,6 +58,20 @@ export function filterObjects(objects: IManagedObject[], query: string): IManage
58
58
  );
59
59
  }
60
60
 
61
+ /**
62
+ * Filters objects based on the provided search text
63
+ */
64
+ export function filterObjectBySearchText(objects: IManagedObject[], query: string) {
65
+ const regex = /"text":"(.*?)"/;
66
+ const match = query.match(regex);
67
+
68
+ if (match) {
69
+ const textValue = match[1];
70
+ return objects.filter(object => filterByName(object, textValue));
71
+ }
72
+ return objects;
73
+ }
74
+
61
75
  /**
62
76
  * Filters object by name
63
77
  */
@@ -24,6 +24,7 @@ import { WidgetResolversModule } from '../widget-resolvers';
24
24
  import { MockModule } from '../__mocks';
25
25
  import { IntroductionModule } from '../provider-configuration';
26
26
  import { TranslationsModule } from '../translations';
27
+ import { BreadcrumbsNodeModule } from '../breadcrumbs/breadcrumbs.module';
27
28
 
28
29
  @NgModule({
29
30
  declarations: [],
@@ -57,7 +58,8 @@ import { TranslationsModule } from '../translations';
57
58
  widgets: [...cockpitDefaultWidgets, ...deviceManagementDefaultWidgets]
58
59
  }),
59
60
  RedirectToLastRouteModule,
60
- MockModule
61
+ MockModule,
62
+ BreadcrumbsNodeModule
61
63
  ],
62
64
 
63
65
  providers: [BsModalRef],
@@ -0,0 +1,109 @@
1
+ <div class="container-fluid">
2
+ <div class="content-flex-50 separator-bottom p-t-16 p-b-16">
3
+ <p class="col-2 a-s-center text-medium">Default icon</p>
4
+ <div class="col-2 d-col a-i-center">
5
+ <!-- important -->
6
+ <c8y-app-icon
7
+ class="icon-36"
8
+ [app]="defaultApp1"
9
+ [contextPath]="defaultApp1.contextPath"
10
+ [name]="defaultApp1.name"
11
+ ></c8y-app-icon>
12
+ <!-- /important -->
13
+ <p class="text-center">{{defaultApp1.name}}</p>
14
+ </div>
15
+ <div class="col-2 d-col a-i-center">
16
+ <c8y-app-icon
17
+ class="icon-36"
18
+ [app]="defaultApp2"
19
+ [contextPath]="defaultApp2.contextPath"
20
+ [name]="defaultApp2.name"
21
+ ></c8y-app-icon>
22
+ <p class="text-center">{{defaultApp2.name}}</p>
23
+ </div>
24
+ <div class="col-2 d-col a-i-center">
25
+ <c8y-app-icon
26
+ class="icon-36"
27
+ [app]="defaultApp3"
28
+ [contextPath]="defaultApp3.contextPath"
29
+ [name]="defaultApp3.name"
30
+ ></c8y-app-icon>
31
+ <p class="text-center">{{defaultApp3.name}}</p>
32
+ </div>
33
+ <div class="col-2 d-col a-i-center">
34
+ <c8y-app-icon
35
+ class="icon-36"
36
+ [app]="defaultApp4"
37
+ [contextPath]="defaultApp4.contextPath"
38
+ [name]="defaultApp4.name"
39
+ ></c8y-app-icon>
40
+ <p class="text-center">{{defaultApp4.name}}</p>
41
+ </div>
42
+ <div class="col-2 d-col a-i-center">
43
+ <c8y-app-icon
44
+ class="icon-36"
45
+ [app]="defaultApp5"
46
+ [contextPath]="defaultApp5.contextPath"
47
+ [name]="defaultApp5.name"
48
+ ></c8y-app-icon>
49
+ <p class="text-center">{{defaultApp5.name}}</p>
50
+ </div>
51
+ </div>
52
+
53
+ <div class="content-flex-50 separator-bottom p-t-16 p-b-16" >
54
+ <p class="col-2 a-s-center text-medium">Custom icon</p>
55
+ <div class="col-2 d-col a-i-center">
56
+ <!-- important -->
57
+ <c8y-app-icon
58
+ class="icon-36"
59
+ [app]="customApp1"
60
+ [contextPath]="customApp1.contextPath"
61
+ [name]="customApp1.name"
62
+ ></c8y-app-icon>
63
+ <!-- /important -->
64
+ <p class="text-center">{{customApp1.name}}</p>
65
+ </div>
66
+ <div class="col-2 d-col a-i-center">
67
+ <c8y-app-icon
68
+ class="icon-36"
69
+ [app]="customApp2"
70
+ [contextPath]="customApp2.contextPath"
71
+ [name]="customApp2.name"
72
+ ></c8y-app-icon>
73
+ <p class="text-center">{{customApp2.name}}</p>
74
+ </div>
75
+ <div class="col-2 d-col a-i-center">
76
+ <c8y-app-icon
77
+ class="icon-36"
78
+ [app]="customApp3"
79
+ [contextPath]="customApp3.contextPath"
80
+ [name]="customApp3.name"
81
+ ></c8y-app-icon>
82
+ <p class="text-center">{{customApp3.name}}</p>
83
+ </div>
84
+ </div>
85
+
86
+ <div class="content-flex-50 p-t-16 p-b-16" >
87
+ <p class="col-2 text-medium a-s-center">Fallback icon</p>
88
+ <div class="col-2 d-col a-i-center">
89
+ <!-- important -->
90
+ <c8y-app-icon
91
+ [app]="appExample1"
92
+ class="icon-36"
93
+ [contextPath]="appExample1.contextPath"
94
+ [name]="appExample1.name"
95
+ ></c8y-app-icon>
96
+ <!-- /important -->
97
+ <p class="text-center">{{appExample1.name}}</p>
98
+ </div>
99
+ <div class="col-2 d-col a-i-center">
100
+ <c8y-app-icon
101
+ [app]="appExample2"
102
+ class="icon-36"
103
+ [contextPath]="appExample2.contextPath"
104
+ [name]="appExample2.name"
105
+ ></c8y-app-icon>
106
+ <p class="text-center">{{appExample2.name}}</p>
107
+ </div>
108
+ </div>
109
+ </div>
@@ -0,0 +1,56 @@
1
+ import { Component } from '@angular/core';
2
+ import { IApplication } from '@c8y/client';
3
+ import { CoreModule } from '@c8y/ngx-components';
4
+ @Component({
5
+ selector: 'tut-app-icon-example',
6
+ templateUrl: './app-icon-example.component.html',
7
+ standalone: true,
8
+ imports: [CoreModule]
9
+ })
10
+ export class AppIconExampleComponents {
11
+ appExample1: IApplication = {
12
+ name: 'Chat',
13
+ contextPath: 'chat'
14
+ };
15
+ appExample2: IApplication = {
16
+ name: 'Fleet Manager',
17
+ contextPath: 'fleetmanager'
18
+ };
19
+
20
+ customApp1: IApplication = {
21
+ name: 'Digital Twin Manager',
22
+ contextPath: 'dtm',
23
+ icon: { class: 'c8y-icon-enterprise' }
24
+ };
25
+ customApp2: IApplication = {
26
+ name: 'DataHub',
27
+ contextPath: 'datahub',
28
+ icon: { class: 'c8y-icon-data-hub ' }
29
+ };
30
+ customApp3: IApplication = {
31
+ name: 'OEE',
32
+ contextPath: 'oee',
33
+ icon: { class: 'c8y-icon-oee' }
34
+ };
35
+
36
+ defaultApp1: IApplication = {
37
+ name: 'Cockpit',
38
+ contextPath: 'cockpit'
39
+ };
40
+ defaultApp2: IApplication = {
41
+ name: 'Device Management',
42
+ contextPath: 'devicemanagement'
43
+ };
44
+ defaultApp3: IApplication = {
45
+ name: 'Administration',
46
+ contextPath: 'administration'
47
+ };
48
+ defaultApp4: IApplication = {
49
+ name: 'Analytics Builder',
50
+ contextPath: 'analyticsbuilder'
51
+ };
52
+ defaultApp5: IApplication = {
53
+ name: 'Apama EPL',
54
+ contextPath: 'apamaepl'
55
+ };
56
+ }
@@ -0,0 +1,22 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { NavigatorNode, hookNavigator, hookRoute } from '@c8y/ngx-components';
4
+
5
+ @NgModule({
6
+ imports: [CommonModule],
7
+ providers: [
8
+ hookRoute({
9
+ path: 'app-icon',
10
+ loadComponent: () =>
11
+ import('./app-icon-example.component').then(m => m.AppIconExampleComponents)
12
+ }),
13
+ hookNavigator(
14
+ new NavigatorNode({
15
+ path: 'app-icon',
16
+ icon: 'notification',
17
+ label: 'App icon'
18
+ })
19
+ )
20
+ ]
21
+ })
22
+ export class AppIconExampleModule {}
@@ -0,0 +1,23 @@
1
+ <c8y-title>Breadcrumb</c8y-title>
2
+
3
+ <div class="card">
4
+ <!-- important -->
5
+ <c8y-breadcrumb>
6
+ <c8y-breadcrumb-item
7
+ [icon]="'cog'"
8
+ [label]="'Breadcrumb'"
9
+ ></c8y-breadcrumb-item>
10
+ <c8y-breadcrumb-item
11
+ [label]="'Breadcrumb expand'"
12
+ [path]="'/breadcrumbs-expand'"
13
+ ></c8y-breadcrumb-item>
14
+ </c8y-breadcrumb>
15
+ <!-- /important -->
16
+
17
+ <div class="card-block">
18
+ <c8y-breadcrumb-outlet
19
+ class="app-breadcrumbs"
20
+ [breadcrumbs]="breadcrumbService.items$ | async"
21
+ ></c8y-breadcrumb-outlet>
22
+ </div>
23
+ </div>
@@ -0,0 +1,13 @@
1
+ import { Component } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { BreadcrumbService, CoreModule } from '@c8y/ngx-components';
4
+
5
+ @Component({
6
+ selector: 'tut-breadcrumbs-example',
7
+ templateUrl: './breadcrumbs-example.component.html',
8
+ standalone: true,
9
+ imports: [CommonModule, CoreModule]
10
+ })
11
+ export class BreadcrumbsExampleComponents {
12
+ constructor(public breadcrumbService: BreadcrumbService) {}
13
+ }
@@ -0,0 +1,23 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { NavigatorNode, hookNavigator, hookRoute } from '@c8y/ngx-components';
4
+
5
+ @NgModule({
6
+ imports: [CommonModule],
7
+ providers: [
8
+ hookRoute({
9
+ path: 'breadcrumbs-basic',
10
+ loadComponent: () =>
11
+ import('./breadcrumbs-example.component').then(m => m.BreadcrumbsExampleComponents)
12
+ }),
13
+ hookNavigator(
14
+ new NavigatorNode({
15
+ path: 'breadcrumbs-basic',
16
+ icon: 'notification',
17
+ label: 'Breadcrumbs basic',
18
+ parent: 'Breadcrumbs'
19
+ })
20
+ )
21
+ ]
22
+ })
23
+ export class BreadcrumbsExampleModule {}
@@ -0,0 +1,14 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { NavigatorNode, hookNavigator } from '@c8y/ngx-components';
3
+
4
+ @NgModule({
5
+ providers: [
6
+ hookNavigator(
7
+ new NavigatorNode({
8
+ icon: 'notification',
9
+ label: 'Breadcrumbs'
10
+ })
11
+ )
12
+ ]
13
+ })
14
+ export class BreadcrumbsNodeModule {}
@@ -0,0 +1,28 @@
1
+ <!-- The c8y-title component will display the given string (here: "Breadcrumb hook example") in the header as title -->
2
+ <c8y-title>Breadcrumb</c8y-title>
3
+
4
+ <div class="card">
5
+ <!-- important -->
6
+
7
+ <c8y-breadcrumb>
8
+ <c8y-breadcrumb-item
9
+ [icon]="'cog'"
10
+ [label]="'Settings'"
11
+ ></c8y-breadcrumb-item>
12
+ <c8y-breadcrumb-item
13
+ [icon]="'cog'"
14
+ [label]="'Authentication'"
15
+ >
16
+ <span>Projected content</span>
17
+ <span></span>
18
+ </c8y-breadcrumb-item>
19
+ </c8y-breadcrumb>
20
+ <!-- /important -->
21
+
22
+ <div class="card-block">
23
+ <c8y-breadcrumb-outlet
24
+ class="app-breadcrumbs"
25
+ [breadcrumbs]="breadcrumbService.items$ | async"
26
+ ></c8y-breadcrumb-outlet>
27
+ </div>
28
+ </div>
@@ -0,0 +1,13 @@
1
+ import { Component } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { BreadcrumbService, CoreModule } from '@c8y/ngx-components';
4
+
5
+ @Component({
6
+ selector: 'tut-breadcrumbs-example',
7
+ templateUrl: './breadcrumbs-content-projection-example.component.html',
8
+ standalone: true,
9
+ imports: [CommonModule, CoreModule]
10
+ })
11
+ export class BreadcrumbsContentProjectionExampleComponents {
12
+ constructor(public breadcrumbService: BreadcrumbService) {}
13
+ }
@@ -0,0 +1,25 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { NavigatorNode, hookNavigator, hookRoute } from '@c8y/ngx-components';
4
+
5
+ @NgModule({
6
+ imports: [CommonModule],
7
+ providers: [
8
+ hookRoute({
9
+ path: 'breadcrumbs-content-projection',
10
+ loadComponent: () =>
11
+ import('./breadcrumbs-content-projection-example.component').then(
12
+ m => m.BreadcrumbsContentProjectionExampleComponents
13
+ )
14
+ }),
15
+ hookNavigator(
16
+ new NavigatorNode({
17
+ path: 'breadcrumbs-content-projection',
18
+ icon: 'notification',
19
+ label: 'Breadcrumbs content projection',
20
+ parent: 'Breadcrumbs'
21
+ })
22
+ )
23
+ ]
24
+ })
25
+ export class BreadcrumbsContentProjectionExampleModule {}
@@ -0,0 +1,30 @@
1
+ <c8y-title>Breadcrumb</c8y-title>
2
+
3
+ <div class="card">
4
+ <!-- important -->
5
+
6
+ <c8y-breadcrumb>
7
+ <c8y-breadcrumb-item
8
+ [icon]="'cog'"
9
+ [label]="'Group A'"
10
+ ></c8y-breadcrumb-item>
11
+ </c8y-breadcrumb>
12
+
13
+ <c8y-breadcrumb>
14
+ <c8y-breadcrumb-item
15
+ [icon]="'cog'"
16
+ [label]="'Group B'"
17
+ ></c8y-breadcrumb-item>
18
+ </c8y-breadcrumb>
19
+ <!-- /important -->
20
+
21
+ <div
22
+ class="card-block"
23
+ style="height: 70px"
24
+ >
25
+ <c8y-breadcrumb-outlet
26
+ class="app-breadcrumbs"
27
+ [breadcrumbs]="breadcrumbService.items$ | async"
28
+ ></c8y-breadcrumb-outlet>
29
+ </div>
30
+ </div>
@@ -0,0 +1,13 @@
1
+ import { Component } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { BreadcrumbService, CoreModule } from '@c8y/ngx-components';
4
+
5
+ @Component({
6
+ selector: 'tut-breadcrumbs-expand-example',
7
+ templateUrl: './breadcrumbs-expand-example.component.html',
8
+ standalone: true,
9
+ imports: [CommonModule, CoreModule]
10
+ })
11
+ export class BreadcrumbsExpandExampleComponents {
12
+ constructor(public breadcrumbService: BreadcrumbService) {}
13
+ }
@@ -0,0 +1,25 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { NavigatorNode, hookNavigator, hookRoute } from '@c8y/ngx-components';
4
+
5
+ @NgModule({
6
+ imports: [CommonModule],
7
+ providers: [
8
+ hookRoute({
9
+ path: 'breadcrumbs-expand',
10
+ loadComponent: () =>
11
+ import('./breadcrumbs-expand-example.component').then(
12
+ m => m.BreadcrumbsExpandExampleComponents
13
+ )
14
+ }),
15
+ hookNavigator(
16
+ new NavigatorNode({
17
+ path: 'breadcrumbs-expand',
18
+ icon: 'notification',
19
+ label: 'Breadcrumbs expand',
20
+ parent: 'Breadcrumbs'
21
+ })
22
+ )
23
+ ]
24
+ })
25
+ export class BreadcrumbsExpandExampleModule {}
@@ -0,0 +1,5 @@
1
+ export * from './basic-example/breadcrumbs-example.module';
2
+ export * from './expand-example/breadcrumbs-expand-example.module';
3
+ export * from './outlet/breadcrumbs-outlet-example.module';
4
+ export * from './content-projection/breadcrumbs-content-projection-example.module';
5
+ export * from './breadcrumbs.module';
@@ -0,0 +1,21 @@
1
+ <c8y-title>Breadcrumb outlet</c8y-title>
2
+
3
+ <div class="card">
4
+ <c8y-breadcrumb>
5
+ <c8y-breadcrumb-item
6
+ [icon]="'cog'"
7
+ [label]="'Group A'"
8
+ ></c8y-breadcrumb-item>
9
+ </c8y-breadcrumb>
10
+
11
+
12
+ <div class="card-block">
13
+ <!-- important -->
14
+
15
+ <c8y-breadcrumb-outlet
16
+ class="app-breadcrumbs"
17
+ [breadcrumbs]="breadcrumbService.items$ | async"
18
+ ></c8y-breadcrumb-outlet>
19
+ <!-- /important -->
20
+ </div>
21
+ </div>
@@ -0,0 +1,13 @@
1
+ import { Component } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { BreadcrumbService, CoreModule } from '@c8y/ngx-components';
4
+
5
+ @Component({
6
+ selector: 'tut-breadcrumbs-outlet-example',
7
+ templateUrl: './breadcrumbs-outlet-example.component.html',
8
+ standalone: true,
9
+ imports: [CommonModule, CoreModule]
10
+ })
11
+ export class BreadcrumbsOutletExampleComponent {
12
+ constructor(public breadcrumbService: BreadcrumbService) {}
13
+ }
@@ -0,0 +1,25 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { NavigatorNode, hookNavigator, hookRoute } from '@c8y/ngx-components';
4
+
5
+ @NgModule({
6
+ imports: [CommonModule],
7
+ providers: [
8
+ hookRoute({
9
+ path: 'breadcrumbs-outlet',
10
+ loadComponent: () =>
11
+ import('./breadcrumbs-outlet-example.component').then(
12
+ m => m.BreadcrumbsOutletExampleComponent
13
+ )
14
+ }),
15
+ hookNavigator(
16
+ new NavigatorNode({
17
+ path: 'breadcrumbs-outlet',
18
+ icon: 'notification',
19
+ label: 'Breadcrumbs outlet',
20
+ parent: 'Breadcrumbs'
21
+ })
22
+ )
23
+ ]
24
+ })
25
+ export class BreadcrumbsOutletExampleModule {}
@@ -0,0 +1,145 @@
1
+ <c8y-title>Device connection status</c8y-title>
2
+ <div class="container-fluid p-t-16">
3
+ <c8y-list-group class="no-border-last">
4
+ <c8y-li>
5
+ <div class="content-flex-50">
6
+ <div class="col-4 text-medium">Connection status</div>
7
+ <div class="col-3 text-medium">
8
+ Size
9
+ <code>20</code>
10
+ <small class="text-muted"><em>(default)</em></small>
11
+ </div>
12
+ <div class="col-3 text-medium">
13
+ Size
14
+ <code>32</code>
15
+ </div>
16
+ <div class="col-2 text-medium">
17
+ Size
18
+ <code>64</code>
19
+ </div>
20
+ </div>
21
+ </c8y-li>
22
+ <c8y-li>
23
+ <div class="content-flex-50">
24
+ <div class="col-4">
25
+ <span>Send connection: available</span>
26
+ <br />
27
+ <span>Push connection: active</span>
28
+ </div>
29
+ <div class="col-3 a-s-center">
30
+ <!-- important -->
31
+ <c8y-device-status [mo]="connectedAndAvailableDeviceExample"></c8y-device-status>
32
+ <!-- /important -->
33
+ </div>
34
+ <div class="col-3">
35
+ <!-- important -->
36
+ <c8y-device-status
37
+ [size]="32"
38
+ [mo]="connectedAndAvailableDeviceExample"
39
+ ></c8y-device-status>
40
+ <!-- /important -->
41
+ </div>
42
+ <div class="col-2">
43
+ <!-- important -->
44
+ <c8y-device-status
45
+ [size]="64"
46
+ [mo]="connectedAndAvailableDeviceExample"
47
+ ></c8y-device-status>
48
+ <!-- /important -->
49
+ </div>
50
+ </div>
51
+ </c8y-li>
52
+ <c8y-li>
53
+ <div class="content-flex-50">
54
+ <div class="col-4">
55
+ <span>Send connection: available</span>
56
+ <br />
57
+ <span>Push connection: inactive</span>
58
+ </div>
59
+ <div class="col-3 a-s-center">
60
+ <c8y-device-status [mo]="disconnectedAndAvailableExample"></c8y-device-status>
61
+ </div>
62
+ <div class="col-3">
63
+ <c8y-device-status
64
+ [size]="32"
65
+ [mo]="disconnectedAndAvailableExample"
66
+ ></c8y-device-status>
67
+ </div>
68
+ <div class="col-2">
69
+ <c8y-device-status
70
+ [size]="64"
71
+ [mo]="disconnectedAndAvailableExample"
72
+ ></c8y-device-status>
73
+ </div>
74
+ </div>
75
+ </c8y-li>
76
+ <c8y-li>
77
+ <div class="content-flex-50">
78
+ <div class="col-4">
79
+ <span>Send connection: unavailable</span>
80
+ <br />
81
+ <span>Push connection: inactive</span>
82
+ </div>
83
+ <div class="col-3 a-s-center">
84
+ <c8y-device-status [mo]="disconnectedAndUnavailableDeviceExample"></c8y-device-status>
85
+ </div>
86
+ <div class="col-3">
87
+ <c8y-device-status
88
+ [size]="32"
89
+ [mo]="disconnectedAndUnavailableDeviceExample"
90
+ ></c8y-device-status>
91
+ </div>
92
+ <div class="col-2">
93
+ <c8y-device-status
94
+ [size]="64"
95
+ [mo]="disconnectedAndUnavailableDeviceExample"
96
+ ></c8y-device-status>
97
+ </div>
98
+ </div>
99
+ </c8y-li>
100
+ <c8y-li>
101
+ <div class="content-flex-50">
102
+ <div class="col-4">
103
+ <span>Send connection: not monitored</span>
104
+ <br />
105
+ <span>Push connection: inactive</span>
106
+ </div>
107
+ <div class="col-3 a-s-center">
108
+ <c8y-device-status [mo]="notMonitoredDeviceExample"></c8y-device-status>
109
+ </div>
110
+ <div class="col-3">
111
+ <c8y-device-status
112
+ [size]="32"
113
+ [mo]="notMonitoredDeviceExample"
114
+ ></c8y-device-status>
115
+ </div>
116
+ <div class="col-2">
117
+ <c8y-device-status
118
+ [size]="64"
119
+ [mo]="notMonitoredDeviceExample"
120
+ ></c8y-device-status>
121
+ </div>
122
+ </div>
123
+ </c8y-li>
124
+ <c8y-li>
125
+ <div class="content-flex-50">
126
+ <div class="col-4">Maintenance</div>
127
+ <div class="col-3 a-s-center">
128
+ <c8y-device-status [mo]="inMaintenanceDeviceExample"></c8y-device-status>
129
+ </div>
130
+ <div class="col-3">
131
+ <c8y-device-status
132
+ [size]="32"
133
+ [mo]="inMaintenanceDeviceExample"
134
+ ></c8y-device-status>
135
+ </div>
136
+ <div class="col-2">
137
+ <c8y-device-status
138
+ [size]="64"
139
+ [mo]="inMaintenanceDeviceExample"
140
+ ></c8y-device-status>
141
+ </div>
142
+ </div>
143
+ </c8y-li>
144
+ </c8y-list-group>
145
+ </div>
@@ -0,0 +1,61 @@
1
+ import { Component } from '@angular/core';
2
+ import { CoreModule, DeviceStatusModule } from '@c8y/ngx-components';
3
+
4
+ @Component({
5
+ selector: 'tut-device-connection-status-example',
6
+ templateUrl: `./device-connection-status-example.component.html`,
7
+ standalone: true,
8
+ imports: [CoreModule, DeviceStatusModule]
9
+ })
10
+ export class DeviceConnectionStatusExampleComponent {
11
+ private readonly CONNECTED_AND_AVAILABLE_DEVICE_EXAMPLE = {
12
+ c8y_RequiredAvailability: {},
13
+ c8y_Availability: {
14
+ lastMessage: '2024-01-01T00:00:00.000Z',
15
+ status: 'AVAILABLE'
16
+ },
17
+ c8y_Connection: {
18
+ status: 'CONNECTED'
19
+ }
20
+ };
21
+
22
+ private readonly DISCONNECTED_AND_AVAILABLE_DEVICE_EXAMPLE = {
23
+ c8y_RequiredAvailability: {},
24
+ c8y_Availability: {
25
+ lastMessage: '2024-01-01T00:00:00.000Z',
26
+ status: 'AVAILABLE'
27
+ },
28
+ c8y_Connection: {
29
+ status: 'DISCONNECTED'
30
+ }
31
+ };
32
+
33
+ private readonly DISCONNECTED_AND_UNAVAILABLE_DEVICE_EXAMPLE = {
34
+ c8y_RequiredAvailability: {},
35
+ c8y_Availability: {
36
+ lastMessage: '2024-01-01T00:00:00.000Z',
37
+ status: 'UNAVAILABLE'
38
+ },
39
+ c8y_Connection: {
40
+ status: 'DISCONNECTED'
41
+ }
42
+ };
43
+
44
+ private readonly NOT_MONITORED_DEVICE_EXAMPLE = {
45
+ c8y_RequiredAvailability: {}
46
+ };
47
+
48
+ private readonly IN_MAINTENANCE_DEVICE_EXAMPLE = {
49
+ c8y_RequiredAvailability: {},
50
+ c8y_Availability: {
51
+ status: 'MAINTENANCE'
52
+ },
53
+ c8y_Connection: {}
54
+ };
55
+
56
+ connectedAndAvailableDeviceExample = this.CONNECTED_AND_AVAILABLE_DEVICE_EXAMPLE;
57
+ disconnectedAndAvailableExample = this.DISCONNECTED_AND_AVAILABLE_DEVICE_EXAMPLE;
58
+ disconnectedAndUnavailableDeviceExample = this.DISCONNECTED_AND_UNAVAILABLE_DEVICE_EXAMPLE;
59
+ notMonitoredDeviceExample = this.NOT_MONITORED_DEVICE_EXAMPLE;
60
+ inMaintenanceDeviceExample = this.IN_MAINTENANCE_DEVICE_EXAMPLE;
61
+ }
@@ -0,0 +1,23 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { NavigatorNode, hookNavigator, hookRoute } from '@c8y/ngx-components';
3
+
4
+ @NgModule({
5
+ providers: [
6
+ hookRoute({
7
+ path: 'device-connection-status',
8
+ loadComponent: () =>
9
+ import('./device-connection-status-example.component').then(
10
+ m => m.DeviceConnectionStatusExampleComponent
11
+ )
12
+ }),
13
+ hookNavigator(
14
+ new NavigatorNode({
15
+ path: '/device-connection-status',
16
+ label: 'Device connection status',
17
+ icon: 'realtime',
18
+ priority: 15
19
+ })
20
+ )
21
+ ]
22
+ })
23
+ export class DeviceConnectionStatusExampleModule {}
@@ -1,5 +1,5 @@
1
1
  import { Component } from '@angular/core';
2
- import { CoreModule } from '@c8y/ngx-components';
2
+ import { BreadcrumbService, CoreModule } from '@c8y/ngx-components';
3
3
 
4
4
  /**
5
5
  * This is a standard angular component.
@@ -15,4 +15,6 @@ export class BasicViewComponent {
15
15
  /**
16
16
  * Your content of the Basic View goes in here!
17
17
  */
18
+
19
+ constructor(public breadcrumbService: BreadcrumbService) {}
18
20
  }