@c8y/tutorial 1019.5.11 → 1019.6.10
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 +16 -1
- package/package.json +6 -6
- package/src/application-card/application-card-example.component.html +41 -0
- package/src/application-card/application-card-example.component.ts +57 -0
- package/src/application-card/application-card-example.module.ts +22 -0
- package/src/help/help-example.component.html +12 -0
- package/src/help/help-example.component.ts +2 -13
- package/src/pagination/pagination-example.component.ts +61 -0
- package/src/pagination/pagination-example.module.ts +21 -0
- package/src/properties-list/properties-list-example.component.html +22 -0
- package/src/properties-list/properties-list-example.component.ts +75 -27
- package/src/realtime/realtime-tutorial.component.ts +1 -1
package/cumulocity.config.ts
CHANGED
|
@@ -13,6 +13,7 @@ export default {
|
|
|
13
13
|
globalTitle: 'Tutorial application IoT',
|
|
14
14
|
tabsHorizontal: true,
|
|
15
15
|
rightDrawer: true,
|
|
16
|
+
contextHelp: true,
|
|
16
17
|
icon: {
|
|
17
18
|
class: 'c8y-icon-tools'
|
|
18
19
|
},
|
|
@@ -525,11 +526,23 @@ export default {
|
|
|
525
526
|
path: './src/stepper/stepper.module.ts',
|
|
526
527
|
description: 'A simple stepper example.'
|
|
527
528
|
},
|
|
529
|
+
{
|
|
530
|
+
name: 'ApplicationCard',
|
|
531
|
+
module: 'ApplicationCardExampleModule',
|
|
532
|
+
path: './src/application-card/application-card-example.module.ts',
|
|
533
|
+
description: 'Application card example.'
|
|
534
|
+
},
|
|
528
535
|
{
|
|
529
536
|
name: 'Hooking via service',
|
|
530
537
|
module: 'HookStateModule',
|
|
531
538
|
path: './src/hooks/state/hook-state.module.ts',
|
|
532
539
|
description: 'This is an example for an Action added via service or factory.'
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
name: 'Pagination',
|
|
543
|
+
module: 'PaginationExampleModule',
|
|
544
|
+
path: './src/pagination/pagination-example.module.ts',
|
|
545
|
+
description: 'This is an example for pagination.'
|
|
533
546
|
}
|
|
534
547
|
],
|
|
535
548
|
remotes: {
|
|
@@ -614,7 +627,9 @@ export default {
|
|
|
614
627
|
'AssetSelectorTreeDevicesModule',
|
|
615
628
|
'AssetSelectorTreeSearchModule',
|
|
616
629
|
'StepperModule',
|
|
617
|
-
'
|
|
630
|
+
'ApplicationCardExampleModule',
|
|
631
|
+
'HookStateModule',
|
|
632
|
+
'PaginationExampleModule'
|
|
618
633
|
]
|
|
619
634
|
}
|
|
620
635
|
},
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@c8y/tutorial",
|
|
3
|
-
"version": "1019.
|
|
3
|
+
"version": "1019.6.10",
|
|
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.
|
|
7
|
-
"@c8y/style": "1019.
|
|
8
|
-
"@c8y/ngx-components": "1019.
|
|
9
|
-
"@c8y/client": "1019.
|
|
10
|
-
"@c8y/bootstrap": "1019.
|
|
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",
|
|
11
11
|
"@angular/cdk": "^16.2.11",
|
|
12
12
|
"ngx-bootstrap": "11.0.2",
|
|
13
13
|
"leaflet": "1.7.1",
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<c8y-title>Application card</c8y-title>
|
|
2
|
+
|
|
3
|
+
<c8y-action-bar-item
|
|
4
|
+
[placement]="'left'"
|
|
5
|
+
itemClass="navbar-form hidden-xs"
|
|
6
|
+
>
|
|
7
|
+
<c8y-list-display-switch
|
|
8
|
+
(onListClassChange)="listClass = $event"
|
|
9
|
+
[listLength]="(apps$ | async)?.length"
|
|
10
|
+
></c8y-list-display-switch>
|
|
11
|
+
</c8y-action-bar-item>
|
|
12
|
+
<div
|
|
13
|
+
class="card-group"
|
|
14
|
+
[ngClass]="listClass"
|
|
15
|
+
>
|
|
16
|
+
<div
|
|
17
|
+
class="page-sticky-header hidden-xs d-flex"
|
|
18
|
+
*ngIf="(apps$ | async)?.length > 0"
|
|
19
|
+
>
|
|
20
|
+
<div class="card-block card-column-40">
|
|
21
|
+
<div class="card-appicon p-l-32 p-r-16 m-r-0 m-l-4"></div>
|
|
22
|
+
{{ 'Application' }}
|
|
23
|
+
</div>
|
|
24
|
+
<div class="card-block p-0 card-column-80 m-r-40">
|
|
25
|
+
<div class="card-block card-column-80">{{ 'Description' }}</div>
|
|
26
|
+
<div class="card-block card-column-20">{{ 'Type' }}</div>
|
|
27
|
+
<div class="card-block card-column-20"></div>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
<div
|
|
31
|
+
class="col-xs-12 col-sm-4 col-md-3"
|
|
32
|
+
*ngFor="let app of apps$ | async"
|
|
33
|
+
>
|
|
34
|
+
<c8y-application-card
|
|
35
|
+
class="d-contents"
|
|
36
|
+
(onAppDeleted)="appDeleted(app)"
|
|
37
|
+
(onAppCloned)="appCloned(app)"
|
|
38
|
+
[app]="app"
|
|
39
|
+
></c8y-application-card>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { Component } from '@angular/core';
|
|
3
|
+
import { FormsModule } from '@angular/forms';
|
|
4
|
+
import { AppStateService, CoreModule, PackageType } from '@c8y/ngx-components';
|
|
5
|
+
import { SharedEcosystemModule } from '@c8y/ngx-components/ecosystem/shared';
|
|
6
|
+
import { IApplication } from '@c8y/client';
|
|
7
|
+
import { Observable, of } from 'rxjs';
|
|
8
|
+
|
|
9
|
+
@Component({
|
|
10
|
+
selector: 'tut-application-card',
|
|
11
|
+
templateUrl: './application-card-example.component.html',
|
|
12
|
+
standalone: true,
|
|
13
|
+
imports: [CommonModule, FormsModule, CoreModule, SharedEcosystemModule],
|
|
14
|
+
providers: [
|
|
15
|
+
{
|
|
16
|
+
provide: AppStateService,
|
|
17
|
+
useValue: { currentTenant: { value: { name: '' } } }
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
})
|
|
21
|
+
export class ApplicationCardExampleComponent {
|
|
22
|
+
listClass: string;
|
|
23
|
+
apps$: Observable<IApplication[]> = of([
|
|
24
|
+
{
|
|
25
|
+
name: 'cockpit',
|
|
26
|
+
contextPath: 'cockpit',
|
|
27
|
+
key: 'cockpit-application-key',
|
|
28
|
+
label: PackageType.OFFICIAL,
|
|
29
|
+
description: 'This package is used to scaffold a cockpit application for Cumulocity IoT.',
|
|
30
|
+
manifest: { version: '1.0.0', author: 'c8y_dev' }
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'administration',
|
|
34
|
+
contextPath: 'administration',
|
|
35
|
+
key: 'administration-application-key',
|
|
36
|
+
label: PackageType.OFFICIAL,
|
|
37
|
+
description: '',
|
|
38
|
+
manifest: { version: '1.0.0', author: 'c8y_dev' }
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'devicemanagement',
|
|
42
|
+
contextPath: 'devicemanagement',
|
|
43
|
+
key: 'devicemanagement-application-key',
|
|
44
|
+
label: PackageType.OFFICIAL,
|
|
45
|
+
description:
|
|
46
|
+
'This package is used to scaffold a Device management application for Cumulocity IoT.',
|
|
47
|
+
manifest: { version: '1.0.0', author: 'c8y_dev' }
|
|
48
|
+
}
|
|
49
|
+
]);
|
|
50
|
+
|
|
51
|
+
appDeleted(app: IApplication[]) {
|
|
52
|
+
console.log('App deleted:', app);
|
|
53
|
+
}
|
|
54
|
+
appCloned(app: IApplication[]) {
|
|
55
|
+
console.log('App cloned:', app);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -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: 'application-card',
|
|
10
|
+
loadComponent: () =>
|
|
11
|
+
import('./application-card-example.component').then(m => m.ApplicationCardExampleComponent)
|
|
12
|
+
}),
|
|
13
|
+
hookNavigator(
|
|
14
|
+
new NavigatorNode({
|
|
15
|
+
path: 'application-card',
|
|
16
|
+
icon: 'inactive-state',
|
|
17
|
+
label: 'Application card'
|
|
18
|
+
})
|
|
19
|
+
)
|
|
20
|
+
]
|
|
21
|
+
})
|
|
22
|
+
export class ApplicationCardExampleModule {}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<c8y-title>Context help</c8y-title>
|
|
2
|
+
<c8y-action-bar-item [placement]="'right'">
|
|
3
|
+
<a class="btn btn-link" title="{{ 'Only pretends to do something...' }}" disabled="disabled">
|
|
4
|
+
<i c8yIcon="refresh"></i>
|
|
5
|
+
{{ 'Refresh' }}
|
|
6
|
+
</a>
|
|
7
|
+
</c8y-action-bar-item>
|
|
8
|
+
<!-- important -->
|
|
9
|
+
<c8y-help
|
|
10
|
+
src="/docs/device-management-application/viewing-all-devices/#viewing-all-devices"
|
|
11
|
+
></c8y-help>
|
|
12
|
+
<!-- /important -->
|
|
@@ -2,21 +2,10 @@ import { Component } from '@angular/core';
|
|
|
2
2
|
import { CommonModule, CoreModule } from '@c8y/ngx-components';
|
|
3
3
|
import { DeviceGridModule } from '@c8y/ngx-components/device-grid';
|
|
4
4
|
import { DeviceListModule } from '@c8y/ngx-components/device-list';
|
|
5
|
+
|
|
5
6
|
@Component({
|
|
6
7
|
selector: 'help-example',
|
|
7
|
-
|
|
8
|
-
<div class="card">
|
|
9
|
-
<div class="card-block">
|
|
10
|
-
<div>
|
|
11
|
-
The "Help" component adds contextual help to the action bar(question mark icon). The
|
|
12
|
-
content of contextual help comes from the user guide.
|
|
13
|
-
</div>
|
|
14
|
-
</div>
|
|
15
|
-
</div>
|
|
16
|
-
|
|
17
|
-
<c8y-help
|
|
18
|
-
src="/docs/device-management-application/viewing-all-devices/#viewing-all-devices"
|
|
19
|
-
></c8y-help> `,
|
|
8
|
+
templateUrl: './help-example.component.html',
|
|
20
9
|
standalone: true,
|
|
21
10
|
imports: [CoreModule, CommonModule, DeviceGridModule, DeviceListModule]
|
|
22
11
|
})
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
import { CoreModule } from '@c8y/ngx-components';
|
|
3
|
+
import { PageChangedEvent, PaginationModule } from 'ngx-bootstrap/pagination';
|
|
4
|
+
|
|
5
|
+
interface Item {
|
|
6
|
+
id: number;
|
|
7
|
+
name: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
@Component({
|
|
11
|
+
selector: 'tut-pagination-example',
|
|
12
|
+
template: `
|
|
13
|
+
<div class="container-fluid">
|
|
14
|
+
<c8y-title>Pagination</c8y-title>
|
|
15
|
+
<c8y-list-group>
|
|
16
|
+
<c8y-li *ngFor="let item of itemsToShow">
|
|
17
|
+
{{ item.name }}
|
|
18
|
+
</c8y-li>
|
|
19
|
+
<c8y-li class="sticky-bottom">
|
|
20
|
+
<pagination
|
|
21
|
+
[totalItems]="totalItems"
|
|
22
|
+
[(ngModel)]="currentPage"
|
|
23
|
+
[itemsPerPage]="itemsPerPage"
|
|
24
|
+
(pageChanged)="pageChanged($event)"
|
|
25
|
+
previousText="previous"
|
|
26
|
+
nextText="next"
|
|
27
|
+
></pagination>
|
|
28
|
+
</c8y-li>
|
|
29
|
+
</c8y-list-group>
|
|
30
|
+
</div>
|
|
31
|
+
`,
|
|
32
|
+
standalone: true,
|
|
33
|
+
imports: [CoreModule, PaginationModule]
|
|
34
|
+
})
|
|
35
|
+
export class PaginationExampleComponent {
|
|
36
|
+
currentPage = 1;
|
|
37
|
+
itemsPerPage = 10;
|
|
38
|
+
// Items to display on the current page
|
|
39
|
+
itemsToShow: Item[] = [];
|
|
40
|
+
totalItems = 50;
|
|
41
|
+
|
|
42
|
+
// Mock dataset
|
|
43
|
+
private allItems: Item[] = Array.from({ length: this.totalItems }, (_, i) => ({
|
|
44
|
+
id: i + 1,
|
|
45
|
+
name: `Item ${i + 1}`
|
|
46
|
+
}));
|
|
47
|
+
|
|
48
|
+
constructor() {
|
|
49
|
+
this.updateItemsToShow();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
pageChanged(event: PageChangedEvent): void {
|
|
53
|
+
this.currentPage = event.page;
|
|
54
|
+
this.updateItemsToShow();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private updateItemsToShow(): void {
|
|
58
|
+
const startIndex = (this.currentPage - 1) * this.itemsPerPage;
|
|
59
|
+
this.itemsToShow = this.allItems.slice(startIndex, startIndex + this.itemsPerPage);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { NavigatorNode, hookNavigator, hookRoute } from '@c8y/ngx-components';
|
|
3
|
+
|
|
4
|
+
@NgModule({
|
|
5
|
+
providers: [
|
|
6
|
+
hookRoute({
|
|
7
|
+
path: 'pagination',
|
|
8
|
+
loadComponent: () =>
|
|
9
|
+
import('./pagination-example.component').then(m => m.PaginationExampleComponent)
|
|
10
|
+
}),
|
|
11
|
+
hookNavigator(
|
|
12
|
+
new NavigatorNode({
|
|
13
|
+
path: '/pagination',
|
|
14
|
+
label: 'Pagination',
|
|
15
|
+
icon: 'realtime',
|
|
16
|
+
priority: 20
|
|
17
|
+
})
|
|
18
|
+
)
|
|
19
|
+
]
|
|
20
|
+
})
|
|
21
|
+
export class PaginationExampleModule {}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<div class="p-t-16">
|
|
2
|
+
<c8y-title>Properties list</c8y-title>
|
|
3
|
+
<!-- important -->
|
|
4
|
+
<c8y-properties-list
|
|
5
|
+
[title]="'Custom object properties'"
|
|
6
|
+
[data]="customData"
|
|
7
|
+
[emptyLabel]="'--'"
|
|
8
|
+
[properties]="customProperties"
|
|
9
|
+
></c8y-properties-list>
|
|
10
|
+
<!-- /important -->
|
|
11
|
+
|
|
12
|
+
<br />
|
|
13
|
+
|
|
14
|
+
<!-- important -->
|
|
15
|
+
<c8y-properties-list
|
|
16
|
+
[title]="'Typed object properties'"
|
|
17
|
+
[data]="archiveManifest"
|
|
18
|
+
[emptyLabel]="'--'"
|
|
19
|
+
[properties]="specifiedPackageVersionProperties"
|
|
20
|
+
></c8y-properties-list>
|
|
21
|
+
<!-- /important -->
|
|
22
|
+
</div>
|
|
@@ -1,49 +1,97 @@
|
|
|
1
1
|
import { Component } from '@angular/core';
|
|
2
|
-
import { CoreModule, gettext, PropertiesListItem } from '@c8y/ngx-components';
|
|
3
2
|
import { IManifest } from '@c8y/client';
|
|
4
|
-
|
|
3
|
+
import { CoreModule, PropertiesListItem } from '@c8y/ngx-components';
|
|
5
4
|
|
|
6
5
|
@Component({
|
|
7
|
-
selector: 'properties-list-example',
|
|
8
|
-
|
|
9
|
-
<c8y-properties-list
|
|
10
|
-
[title]="'Application properties'"
|
|
11
|
-
[data]="archiveManifest"
|
|
12
|
-
[emptyLabel]="'--'"
|
|
13
|
-
[properties]="packageVersionProperties"
|
|
14
|
-
>
|
|
15
|
-
</c8y-properties-list>
|
|
16
|
-
`,
|
|
6
|
+
selector: 'tut-properties-list-example',
|
|
7
|
+
templateUrl: './properties-list-example.component.html',
|
|
17
8
|
standalone: true,
|
|
18
9
|
imports: [CoreModule]
|
|
19
10
|
})
|
|
20
11
|
export class PropertiesListExampleComponent {
|
|
21
|
-
|
|
12
|
+
readonly customData: any = {
|
|
13
|
+
string: 'Hello, world!',
|
|
14
|
+
number: 42,
|
|
15
|
+
boolean: true,
|
|
16
|
+
array: [1, 'two', false],
|
|
17
|
+
object: { key: 'value' },
|
|
18
|
+
null: null,
|
|
19
|
+
undefined: undefined
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
readonly customProperties: PropertiesListItem[] = [
|
|
23
|
+
{
|
|
24
|
+
label: 'String property',
|
|
25
|
+
key: 'string'
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
label: 'Number property',
|
|
29
|
+
key: 'number'
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
label: 'Boolean property',
|
|
33
|
+
key: 'boolean'
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
label: 'Array property',
|
|
37
|
+
key: 'array'
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
label: 'Object property',
|
|
41
|
+
key: 'object',
|
|
42
|
+
transform: (object: any) => object.key
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
label: 'Null property',
|
|
46
|
+
key: 'null'
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
label: 'Undefined property',
|
|
50
|
+
key: 'undefined'
|
|
51
|
+
}
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
readonly archiveManifest: Partial<IManifest> = {
|
|
22
55
|
author: 'Cumulocity IoT',
|
|
56
|
+
homepage: 'https://cumulocity.com/guides/web/overview/',
|
|
57
|
+
keywords: ['Cumulocity', 'Plugin', 'Widget'],
|
|
58
|
+
license: 'Apache 2.0',
|
|
59
|
+
repository: {
|
|
60
|
+
type: 'git',
|
|
61
|
+
url: 'git+https://github.com/SoftwareAG/some-not-exisiting-repository.git'
|
|
62
|
+
},
|
|
63
|
+
requiredPlatformVersion: '>=10.18.0.0',
|
|
23
64
|
version: '10.20.0.0',
|
|
24
|
-
|
|
25
|
-
|
|
65
|
+
name: 'Application name',
|
|
66
|
+
custom: 'Custom property value'
|
|
26
67
|
};
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
readonly packageVersionProperties: PropertiesListItem[] = [
|
|
68
|
+
|
|
69
|
+
readonly specifiedPackageVersionProperties: PropertiesListItem[] = [
|
|
30
70
|
{
|
|
31
|
-
label:
|
|
32
|
-
key: '
|
|
71
|
+
label: 'Author',
|
|
72
|
+
key: 'author'
|
|
33
73
|
},
|
|
34
74
|
{
|
|
35
|
-
label:
|
|
36
|
-
key: '
|
|
75
|
+
label: 'Homepage',
|
|
76
|
+
key: 'homepage',
|
|
77
|
+
type: 'link',
|
|
78
|
+
action: (event, link: string) => window.open(link, '_blank', 'noopener,noreferrer')
|
|
37
79
|
},
|
|
38
80
|
{
|
|
39
|
-
label:
|
|
81
|
+
label: 'Required platform version',
|
|
40
82
|
key: 'requiredPlatformVersion'
|
|
41
83
|
},
|
|
42
84
|
{
|
|
43
|
-
label:
|
|
44
|
-
key: '
|
|
45
|
-
|
|
46
|
-
|
|
85
|
+
label: 'Version',
|
|
86
|
+
key: 'version'
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
label: 'Name',
|
|
90
|
+
key: 'name'
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
label: 'Custom property',
|
|
94
|
+
key: 'custom'
|
|
47
95
|
}
|
|
48
96
|
];
|
|
49
97
|
}
|
|
@@ -14,7 +14,7 @@ import { Observable, merge } from 'rxjs';
|
|
|
14
14
|
import { map, scan } from 'rxjs/operators';
|
|
15
15
|
|
|
16
16
|
@Component({
|
|
17
|
-
selector: '
|
|
17
|
+
selector: 'tut-realtime-button',
|
|
18
18
|
templateUrl: './realtime-tutorial.component.html',
|
|
19
19
|
providers: [
|
|
20
20
|
ManagedObjectRealtimeService,
|