@c8y/tutorial 1019.8.1 → 1019.12.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 +14 -0
- package/package.json +6 -6
- package/src/dashboard/context-dashboard/context-dashboard.component.ts +1 -1
- package/src/dashboard/custom-dashboard/custom-dashboard.component.html +38 -18
- package/src/dashboard/custom-dashboard/custom-dashboard.component.ts +22 -13
- package/src/dashboard/named-context-dashboard/named-context-dashboard.component.ts +1 -2
- package/src/dashboard/service-dashboard/service-dashboard.component.ts +1 -1
- package/src/dashboard/widget-dashboard/widget-dashboard.component.ts +1 -6
- package/src/dashboard/widget-guide-context-dashboard/widget-guide-context-dashboard.component.ts +42 -0
- package/src/dashboard/widget-guide-context-dashboard/widget-guide-context-dashboard.module.ts +24 -0
- package/src/dashboard/widget-guide-dashboard/widget-guide-dashboard.component.ts +70 -0
- package/src/dashboard/widget-guide-dashboard/widget-guide-dashboard.module.ts +22 -0
- package/src/widget/demo-widget.component.ts +36 -11
- package/src/widget/demo-widget.module.ts +9 -2
- package/src/widget-resolvers/widget-resolvers.module.ts +2 -1
- package/tsconfig.app.json +4 -1
package/cumulocity.config.ts
CHANGED
|
@@ -100,6 +100,18 @@ export default {
|
|
|
100
100
|
path: './src/dashboard/custom-dashboard/custom-dashboard.module.ts',
|
|
101
101
|
description: 'An introduction to custom dashboards.'
|
|
102
102
|
},
|
|
103
|
+
{
|
|
104
|
+
name: 'Dashboard module with example of dynamic component usage',
|
|
105
|
+
module: 'WidgetGuideDashboardModule',
|
|
106
|
+
path: './src/dashboard/widget-guide-dashboard/widget-guide-dashboard.module.ts',
|
|
107
|
+
description: 'An example showing usage of custom widget in dashboard.'
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: 'Context dashboard module with example of dynamic component usage',
|
|
111
|
+
module: 'WidgetGuideContextDashboardModule',
|
|
112
|
+
path: './src/dashboard/widget-guide-context-dashboard/widget-guide-context-dashboard.module.ts',
|
|
113
|
+
description: 'An example showing usage of custom widget in context dashboard.'
|
|
114
|
+
},
|
|
103
115
|
{
|
|
104
116
|
name: 'Introduction datapoint selection module',
|
|
105
117
|
module: 'DatapointSelectionExampleModule',
|
|
@@ -640,6 +652,8 @@ export default {
|
|
|
640
652
|
'NewTranslationModule',
|
|
641
653
|
'NewLanguageModule',
|
|
642
654
|
'CustomDashboardModule',
|
|
655
|
+
'WidgetGuideDashboardModule',
|
|
656
|
+
'WidgetGuideContextDashboardModule',
|
|
643
657
|
'WidgetDashboardModule',
|
|
644
658
|
'ContextDashboardModule',
|
|
645
659
|
'ServiceDashboardModule',
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@c8y/tutorial",
|
|
3
|
-
"version": "1019.
|
|
3
|
+
"version": "1019.12.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/devkit": "1019.
|
|
7
|
-
"@c8y/style": "1019.
|
|
8
|
-
"@c8y/ngx-components": "1019.
|
|
9
|
-
"@c8y/client": "1019.
|
|
10
|
-
"@c8y/bootstrap": "1019.
|
|
6
|
+
"@c8y/devkit": "1019.12.0",
|
|
7
|
+
"@c8y/style": "1019.12.0",
|
|
8
|
+
"@c8y/ngx-components": "1019.12.0",
|
|
9
|
+
"@c8y/client": "1019.12.0",
|
|
10
|
+
"@c8y/bootstrap": "1019.12.0",
|
|
11
11
|
"@angular/cdk": "^16.2.11",
|
|
12
12
|
"ngx-bootstrap": "11.0.2",
|
|
13
13
|
"leaflet": "1.7.1",
|
|
@@ -4,7 +4,7 @@ import { ContextDashboardModule } from '@c8y/ngx-components/context-dashboard';
|
|
|
4
4
|
import { CommonModule } from '@angular/common';
|
|
5
5
|
|
|
6
6
|
@Component({
|
|
7
|
-
selector: '
|
|
7
|
+
selector: 'tut-context-dashboard',
|
|
8
8
|
template: `<c8y-title>Context dashboard</c8y-title>
|
|
9
9
|
<c8y-context-dashboard
|
|
10
10
|
name="example-widget"
|
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
<c8y-title>Custom dashboard</c8y-title>
|
|
2
2
|
|
|
3
|
-
<!--TODO: align action bar-->
|
|
4
3
|
<c8y-action-bar-item [placement]="'right'">
|
|
5
4
|
<button
|
|
6
5
|
class="btn btn-link"
|
|
7
|
-
title="{{ 'Add random'
|
|
6
|
+
title="{{ 'Add random' }}"
|
|
8
7
|
type="button"
|
|
9
8
|
(click)="addRandom()"
|
|
10
9
|
>
|
|
11
10
|
<i c8yIcon="plus-circle"></i>
|
|
12
|
-
{{ 'Add random'
|
|
11
|
+
{{ 'Add random' }}
|
|
13
12
|
</button>
|
|
14
13
|
</c8y-action-bar-item>
|
|
15
14
|
<c8y-action-bar-item [placement]="'right'">
|
|
16
15
|
<button
|
|
17
16
|
class="btn btn-link"
|
|
18
|
-
title="{{ 'Toggle freeze'
|
|
17
|
+
title="{{ 'Toggle freeze' }}"
|
|
19
18
|
(click)="isFrozen = !isFrozen"
|
|
20
19
|
>
|
|
21
20
|
<i [c8yIcon]="isFrozen ? 'lock' : 'unlock'"></i>
|
|
22
|
-
{{ 'Toggle freeze'
|
|
21
|
+
{{ 'Toggle freeze' }}
|
|
23
22
|
</button>
|
|
24
23
|
</c8y-action-bar-item>
|
|
25
24
|
|
|
26
25
|
<c8y-help src="/docs/cockpit/working-with-dashboards/#working-with-dashboards"></c8y-help>
|
|
27
26
|
|
|
28
27
|
<c8y-dashboard (dashboardChange)="dashboardChange($event)">
|
|
28
|
+
<!-- Simple widgets represented by widgets array property from CustomDashboardComponent class-->
|
|
29
29
|
<c8y-dashboard-child
|
|
30
30
|
[class]="{
|
|
31
31
|
'panel-title-hidden': true
|
|
@@ -39,6 +39,8 @@
|
|
|
39
39
|
#current
|
|
40
40
|
>
|
|
41
41
|
<div class="card-block">
|
|
42
|
+
Simple widget with content only
|
|
43
|
+
<br />
|
|
42
44
|
x: {{ current.x }}
|
|
43
45
|
<br />
|
|
44
46
|
y: {{ current.y }}
|
|
@@ -49,10 +51,12 @@
|
|
|
49
51
|
<br />
|
|
50
52
|
</div>
|
|
51
53
|
</c8y-dashboard-child>
|
|
54
|
+
|
|
55
|
+
<!-- Dashboard child with title and widget classes applied-->
|
|
52
56
|
<c8y-dashboard-child
|
|
53
57
|
[class]="{
|
|
54
58
|
'panel-content-branded': true,
|
|
55
|
-
'panel-title-
|
|
59
|
+
'panel-title-border': true
|
|
56
60
|
}"
|
|
57
61
|
#cpWidget
|
|
58
62
|
[isFrozen]="isFrozen"
|
|
@@ -62,9 +66,11 @@
|
|
|
62
66
|
[height]="2"
|
|
63
67
|
>
|
|
64
68
|
<c8y-dashboard-child-title>
|
|
65
|
-
<span>
|
|
69
|
+
<span>Widget title</span>
|
|
66
70
|
</c8y-dashboard-child-title>
|
|
67
71
|
<div class="card-block">
|
|
72
|
+
This widget has CSS classes 'panel-content-branded' and 'panel-title-border' applied.
|
|
73
|
+
<br />
|
|
68
74
|
x: {{ cpWidget.x }}
|
|
69
75
|
<br />
|
|
70
76
|
y: {{ cpWidget.y }}
|
|
@@ -75,6 +81,8 @@
|
|
|
75
81
|
<br />
|
|
76
82
|
</div>
|
|
77
83
|
</c8y-dashboard-child>
|
|
84
|
+
|
|
85
|
+
<!-- Dashboard child with title, widget class applied and children actions-->
|
|
78
86
|
<c8y-dashboard-child
|
|
79
87
|
[class]="{ 'panel-content-dark': true }"
|
|
80
88
|
#cpWidget2
|
|
@@ -85,7 +93,7 @@
|
|
|
85
93
|
[height]="4"
|
|
86
94
|
>
|
|
87
95
|
<c8y-dashboard-child-title>
|
|
88
|
-
<span>
|
|
96
|
+
<span>Widget title</span>
|
|
89
97
|
</c8y-dashboard-child-title>
|
|
90
98
|
<c8y-dashboard-child-action>
|
|
91
99
|
<a
|
|
@@ -97,6 +105,9 @@
|
|
|
97
105
|
</a>
|
|
98
106
|
</c8y-dashboard-child-action>
|
|
99
107
|
<div class="card-block">
|
|
108
|
+
This widget has CSS classes 'panel-content-dark' applied. It also has toggle freeze action
|
|
109
|
+
button.
|
|
110
|
+
<br />
|
|
100
111
|
x: {{ cpWidget2.x }}
|
|
101
112
|
<br />
|
|
102
113
|
y: {{ cpWidget2.y }}
|
|
@@ -108,6 +119,7 @@
|
|
|
108
119
|
</div>
|
|
109
120
|
</c8y-dashboard-child>
|
|
110
121
|
|
|
122
|
+
<!-- Dashboard child with title, widget class applied and children actions-->
|
|
111
123
|
<c8y-dashboard-child
|
|
112
124
|
[class]="{ 'panel-content-transparent': true }"
|
|
113
125
|
#cpWidget3
|
|
@@ -118,7 +130,7 @@
|
|
|
118
130
|
[height]="2"
|
|
119
131
|
>
|
|
120
132
|
<c8y-dashboard-child-title *ngIf="showTitle">
|
|
121
|
-
<span>
|
|
133
|
+
<span>Widget title</span>
|
|
122
134
|
</c8y-dashboard-child-title>
|
|
123
135
|
<c8y-dashboard-child-action>
|
|
124
136
|
<a
|
|
@@ -139,6 +151,9 @@
|
|
|
139
151
|
</a>
|
|
140
152
|
</c8y-dashboard-child-action>
|
|
141
153
|
<div class="card-block">
|
|
154
|
+
This widget has CSS classes 'panel-content-transparent' applied. It also has toggle freeze and
|
|
155
|
+
toggle title action buttons.
|
|
156
|
+
<br />
|
|
142
157
|
x: {{ cpWidget3.x }}
|
|
143
158
|
<br />
|
|
144
159
|
y: {{ cpWidget3.y }}
|
|
@@ -150,31 +165,36 @@
|
|
|
150
165
|
</div>
|
|
151
166
|
</c8y-dashboard-child>
|
|
152
167
|
|
|
153
|
-
<!--
|
|
168
|
+
<!-- Dashboard child with a dynamic component -->
|
|
154
169
|
<c8y-dashboard-child
|
|
155
170
|
[isFrozen]="isFrozen"
|
|
156
171
|
[width]="10"
|
|
157
172
|
[height]="4"
|
|
158
173
|
>
|
|
159
174
|
<c8y-dashboard-child-title>
|
|
160
|
-
<span>Dynamic component
|
|
175
|
+
<span>Dynamic component child title</span>
|
|
161
176
|
</c8y-dashboard-child-title>
|
|
162
177
|
<c8y-dashboard-child-action>
|
|
163
178
|
<button
|
|
164
|
-
title="{{ 'Configure this widget'
|
|
179
|
+
title="{{ 'Configure this widget' }}"
|
|
165
180
|
type="button"
|
|
166
181
|
(click)="editComponent = !editComponent; (false)"
|
|
167
182
|
>
|
|
168
183
|
<i [c8yIcon]="'cog'"></i>
|
|
169
|
-
{{ 'Configure this widget'
|
|
184
|
+
{{ !editComponent ? 'Configure this widget' : 'Close configuration' }}
|
|
170
185
|
</button>
|
|
171
186
|
</c8y-dashboard-child-action>
|
|
172
187
|
<div class="card-block">
|
|
173
|
-
<
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
188
|
+
<form
|
|
189
|
+
name="form"
|
|
190
|
+
#configForm="ngForm"
|
|
191
|
+
>
|
|
192
|
+
<c8y-dynamic-component
|
|
193
|
+
componentId="angular.widget.demo"
|
|
194
|
+
[config]="{ text: 'Hello world' }"
|
|
195
|
+
[mode]="editComponent ? 'config' : 'component'"
|
|
196
|
+
></c8y-dynamic-component>
|
|
197
|
+
</form>
|
|
178
198
|
</div>
|
|
179
199
|
</c8y-dashboard-child>
|
|
180
200
|
</c8y-dashboard>
|
|
@@ -1,24 +1,18 @@
|
|
|
1
|
-
import { Component } from '@angular/core';
|
|
2
|
-
import {
|
|
1
|
+
import { AfterViewInit, Component, OnDestroy, ViewChild } from '@angular/core';
|
|
2
|
+
import { CoreModule, DashboardChildDimension } from '@c8y/ngx-components';
|
|
3
3
|
import { CommonModule } from '@angular/common';
|
|
4
4
|
import { AssetSelectorModule } from '@c8y/ngx-components/assets-navigator';
|
|
5
5
|
import { DatapointSelectorModule } from '@c8y/ngx-components/datapoint-selector';
|
|
6
|
-
import {
|
|
6
|
+
import { NgForm } from '@angular/forms';
|
|
7
|
+
import { Subscription } from 'rxjs';
|
|
7
8
|
|
|
8
9
|
@Component({
|
|
9
|
-
selector: 'custom-dashboard',
|
|
10
|
+
selector: 'tut-custom-dashboard',
|
|
10
11
|
templateUrl: './custom-dashboard.component.html',
|
|
11
12
|
standalone: true,
|
|
12
|
-
imports: [
|
|
13
|
-
CommonModule,
|
|
14
|
-
CoreModule,
|
|
15
|
-
AssetSelectorModule,
|
|
16
|
-
DatapointSelectorModule,
|
|
17
|
-
// TODO: REMOVE ME
|
|
18
|
-
DashboardWidgetDemoModule
|
|
19
|
-
]
|
|
13
|
+
imports: [CommonModule, CoreModule, AssetSelectorModule, DatapointSelectorModule]
|
|
20
14
|
})
|
|
21
|
-
export class CustomDashboardComponent {
|
|
15
|
+
export class CustomDashboardComponent implements AfterViewInit, OnDestroy {
|
|
22
16
|
widgets = [
|
|
23
17
|
{ x: 0, y: 0, width: 12, height: 1 },
|
|
24
18
|
{ x: 3, y: 1, width: 5, height: 2 }
|
|
@@ -27,6 +21,21 @@ export class CustomDashboardComponent {
|
|
|
27
21
|
showTitle = true;
|
|
28
22
|
editComponent = false;
|
|
29
23
|
|
|
24
|
+
@ViewChild('configForm', { static: false })
|
|
25
|
+
configForm: NgForm;
|
|
26
|
+
|
|
27
|
+
subscription: Subscription;
|
|
28
|
+
|
|
29
|
+
ngAfterViewInit() {
|
|
30
|
+
this.subscription = this.configForm.valueChanges.subscribe(value =>
|
|
31
|
+
console.log('Widget config:', value)
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
ngOnDestroy() {
|
|
36
|
+
this.subscription.unsubscribe();
|
|
37
|
+
}
|
|
38
|
+
|
|
30
39
|
/**
|
|
31
40
|
* Add a random child to the dashboard.
|
|
32
41
|
*/
|
|
@@ -6,9 +6,8 @@ import { CommonModule } from '@angular/common';
|
|
|
6
6
|
import { ContextDashboardModule } from '@c8y/ngx-components/context-dashboard';
|
|
7
7
|
|
|
8
8
|
@Component({
|
|
9
|
-
selector: '
|
|
9
|
+
selector: 'tut-named-context-dashboard',
|
|
10
10
|
template: `<c8y-title>Named context dashboard</c8y-title>
|
|
11
|
-
<!-- TODO: verify if device is found and everything is displaying properly -->
|
|
12
11
|
<c8y-context-dashboard
|
|
13
12
|
[name]="name"
|
|
14
13
|
[defaultWidgets]="defaultWidgets"
|
|
@@ -6,7 +6,7 @@ import { CommonModule } from '@angular/common';
|
|
|
6
6
|
import { ContextDashboardModule } from '@c8y/ngx-components/context-dashboard';
|
|
7
7
|
|
|
8
8
|
@Component({
|
|
9
|
-
selector: '
|
|
9
|
+
selector: 'tut-service-dashboard',
|
|
10
10
|
template: `<c8y-title>Service dashboard</c8y-title>
|
|
11
11
|
<!-- TODO: check what to do with this example -->
|
|
12
12
|
<c8y-context-dashboard
|
|
@@ -15,7 +15,7 @@ import { CommonModule } from '@angular/common';
|
|
|
15
15
|
canDelete: false,
|
|
16
16
|
translateWidgetTitle: false,
|
|
17
17
|
allowFullscreen: true,
|
|
18
|
-
title:
|
|
18
|
+
title: ''
|
|
19
19
|
}"
|
|
20
20
|
(onFreeze)="toggleFreeze($event)"
|
|
21
21
|
(onChangeDashboard)="change($event)"
|
|
@@ -23,11 +23,6 @@ import { CommonModule } from '@angular/common';
|
|
|
23
23
|
(onEditWidget)="editWidget($event)"
|
|
24
24
|
(onEditDashboard)="editDashboard()"
|
|
25
25
|
>
|
|
26
|
-
<!-- TODO: check me
|
|
27
|
-
Not added to demo that the functionality is gone then:
|
|
28
|
-
(onDeleteWidget)="deleteWidget($event)"
|
|
29
|
-
(onDeleteDashboard)="deleteDashboard($event)"
|
|
30
|
-
-->
|
|
31
26
|
</c8y-widgets-dashboard> `,
|
|
32
27
|
standalone: true,
|
|
33
28
|
imports: [CommonModule, CoreModule]
|
package/src/dashboard/widget-guide-context-dashboard/widget-guide-context-dashboard.component.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
import { CoreModule, Widget } from '@c8y/ngx-components';
|
|
3
|
+
import { CommonModule } from '@angular/common';
|
|
4
|
+
import { AssetSelectorModule } from '@c8y/ngx-components/assets-navigator';
|
|
5
|
+
import { DatapointSelectorModule } from '@c8y/ngx-components/datapoint-selector';
|
|
6
|
+
import { ContextDashboardModule } from '@c8y/ngx-components/context-dashboard';
|
|
7
|
+
|
|
8
|
+
@Component({
|
|
9
|
+
selector: 'tut-widget-guide-dashboard',
|
|
10
|
+
template: `
|
|
11
|
+
<c8y-title>Context dashboard</c8y-title>
|
|
12
|
+
<c8y-context-dashboard
|
|
13
|
+
name="example-widget"
|
|
14
|
+
[defaultWidgets]="defaultWidgets"
|
|
15
|
+
[canDelete]="false"
|
|
16
|
+
></c8y-context-dashboard>
|
|
17
|
+
`,
|
|
18
|
+
standalone: true,
|
|
19
|
+
imports: [
|
|
20
|
+
CommonModule,
|
|
21
|
+
CoreModule,
|
|
22
|
+
AssetSelectorModule,
|
|
23
|
+
DatapointSelectorModule,
|
|
24
|
+
ContextDashboardModule
|
|
25
|
+
]
|
|
26
|
+
})
|
|
27
|
+
export class WidgetGuideContextDashboardComponent {
|
|
28
|
+
defaultWidgets: Widget[] = [
|
|
29
|
+
{
|
|
30
|
+
_x: 3,
|
|
31
|
+
_y: 0,
|
|
32
|
+
_width: 6,
|
|
33
|
+
_height: 6,
|
|
34
|
+
componentId: 'angular.widget.demo',
|
|
35
|
+
config: {
|
|
36
|
+
text: 'Welcome to a context dashboard'
|
|
37
|
+
},
|
|
38
|
+
title: 'Hello',
|
|
39
|
+
id: 'some_unique_id'
|
|
40
|
+
}
|
|
41
|
+
];
|
|
42
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { NavigatorNode, hookNavigator, hookRoute } from '@c8y/ngx-components';
|
|
3
|
+
|
|
4
|
+
@NgModule({
|
|
5
|
+
providers: [
|
|
6
|
+
hookRoute({
|
|
7
|
+
path: 'dashboards/widget-guide-context-dashboard',
|
|
8
|
+
loadComponent: () =>
|
|
9
|
+
import('./widget-guide-context-dashboard.component').then(
|
|
10
|
+
m => m.WidgetGuideContextDashboardComponent
|
|
11
|
+
)
|
|
12
|
+
}),
|
|
13
|
+
hookNavigator(
|
|
14
|
+
new NavigatorNode({
|
|
15
|
+
label: 'Widget guide context dashboard example',
|
|
16
|
+
path: '/dashboards/widget-guide-context-dashboard',
|
|
17
|
+
icon: 'th-large',
|
|
18
|
+
priority: -6,
|
|
19
|
+
parent: 'Dashboards'
|
|
20
|
+
})
|
|
21
|
+
)
|
|
22
|
+
]
|
|
23
|
+
})
|
|
24
|
+
export class WidgetGuideContextDashboardModule {}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Component, OnDestroy, ViewChild } from '@angular/core';
|
|
2
|
+
import { CoreModule } from '@c8y/ngx-components';
|
|
3
|
+
import { CommonModule } from '@angular/common';
|
|
4
|
+
import { AssetSelectorModule } from '@c8y/ngx-components/assets-navigator';
|
|
5
|
+
import { DatapointSelectorModule } from '@c8y/ngx-components/datapoint-selector';
|
|
6
|
+
import { NgForm } from '@angular/forms';
|
|
7
|
+
import { Subscription } from 'rxjs';
|
|
8
|
+
|
|
9
|
+
@Component({
|
|
10
|
+
selector: 'tut-widget-guide-dashboard',
|
|
11
|
+
template: `
|
|
12
|
+
<c8y-title>Custom dashboard</c8y-title>
|
|
13
|
+
<c8y-action-bar-item [placement]="'right'">
|
|
14
|
+
<button class="btn btn-link" title="{{ 'Toggle freeze' }}" (click)="isFrozen = !isFrozen">
|
|
15
|
+
<i [c8yIcon]="isFrozen ? 'lock' : 'unlock'"></i>
|
|
16
|
+
{{ 'Toggle freeze' }}
|
|
17
|
+
</button>
|
|
18
|
+
</c8y-action-bar-item>
|
|
19
|
+
<c8y-dashboard>
|
|
20
|
+
<!-- Dashboard child with a dynamic component -->
|
|
21
|
+
<c8y-dashboard-child [width]="10" [height]="4">
|
|
22
|
+
<c8y-dashboard-child-title>
|
|
23
|
+
<span>Dynamic component child title</span>
|
|
24
|
+
</c8y-dashboard-child-title>
|
|
25
|
+
<c8y-dashboard-child-action>
|
|
26
|
+
<button
|
|
27
|
+
title="{{ 'Configure this widget' }}"
|
|
28
|
+
type="button"
|
|
29
|
+
(click)="editComponent = !editComponent; (false)"
|
|
30
|
+
>
|
|
31
|
+
<i [c8yIcon]="'cog'"></i>
|
|
32
|
+
{{ !editComponent ? 'Configure this widget' : 'Close configuration' }}
|
|
33
|
+
</button>
|
|
34
|
+
</c8y-dashboard-child-action>
|
|
35
|
+
<div class="card-block">
|
|
36
|
+
<form name="form" #configForm="ngForm">
|
|
37
|
+
<!-- important -->
|
|
38
|
+
<c8y-dynamic-component
|
|
39
|
+
componentId="angular.widget.demo"
|
|
40
|
+
[config]="{ text: 'Hello world' }"
|
|
41
|
+
[mode]="editComponent ? 'config' : 'component'"
|
|
42
|
+
></c8y-dynamic-component>
|
|
43
|
+
<!-- /important-->
|
|
44
|
+
</form>
|
|
45
|
+
</div>
|
|
46
|
+
</c8y-dashboard-child>
|
|
47
|
+
</c8y-dashboard>
|
|
48
|
+
`,
|
|
49
|
+
standalone: true,
|
|
50
|
+
imports: [CommonModule, CoreModule, AssetSelectorModule, DatapointSelectorModule]
|
|
51
|
+
})
|
|
52
|
+
export class WidgetGuideDashboardComponent implements OnDestroy {
|
|
53
|
+
isFrozen = false;
|
|
54
|
+
editComponent = false;
|
|
55
|
+
|
|
56
|
+
@ViewChild('configForm', { static: false })
|
|
57
|
+
configForm: NgForm;
|
|
58
|
+
|
|
59
|
+
subscription: Subscription;
|
|
60
|
+
|
|
61
|
+
ngAfterViewInit() {
|
|
62
|
+
this.subscription = this.configForm.valueChanges.subscribe(value =>
|
|
63
|
+
console.log('Widget config:', value)
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
ngOnDestroy() {
|
|
68
|
+
this.subscription.unsubscribe();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { NavigatorNode, hookNavigator, hookRoute } from '@c8y/ngx-components';
|
|
3
|
+
|
|
4
|
+
@NgModule({
|
|
5
|
+
providers: [
|
|
6
|
+
hookRoute({
|
|
7
|
+
path: 'dashboards/widget-guide-dashboard',
|
|
8
|
+
loadComponent: () =>
|
|
9
|
+
import('./widget-guide-dashboard.component').then(m => m.WidgetGuideDashboardComponent)
|
|
10
|
+
}),
|
|
11
|
+
hookNavigator(
|
|
12
|
+
new NavigatorNode({
|
|
13
|
+
label: 'Widget guide dashboard example',
|
|
14
|
+
path: '/dashboards/widget-guide-dashboard',
|
|
15
|
+
icon: 'th-large',
|
|
16
|
+
priority: -6,
|
|
17
|
+
parent: 'Dashboards'
|
|
18
|
+
})
|
|
19
|
+
)
|
|
20
|
+
]
|
|
21
|
+
})
|
|
22
|
+
export class WidgetGuideDashboardModule {}
|
|
@@ -1,35 +1,60 @@
|
|
|
1
|
-
import { Component, Input, SimpleChanges } from '@angular/core';
|
|
1
|
+
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
|
|
2
|
+
import {
|
|
3
|
+
DismissAlertStrategy,
|
|
4
|
+
DynamicComponentAlert,
|
|
5
|
+
DynamicComponentAlertAggregator,
|
|
6
|
+
gettext
|
|
7
|
+
} from '@c8y/ngx-components';
|
|
2
8
|
|
|
3
9
|
@Component({
|
|
4
10
|
selector: 'c8y-widget-demo',
|
|
5
11
|
template: `
|
|
6
12
|
<div class="p-16">
|
|
7
13
|
<h1>Hi I'm a widget from angular</h1>
|
|
8
|
-
<p class="text">{{ config?.text || 'No text' }}</p>
|
|
14
|
+
<p class="text">Text from config object: {{ config?.text || 'No text' }}</p>
|
|
9
15
|
<small>My context is: {{ config?.device?.name || 'No context' }}</small
|
|
10
16
|
><br />
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
<ng-container *ngIf="config?.date?.length === 2">
|
|
18
|
+
My time context is:
|
|
19
|
+
<ul>
|
|
20
|
+
<li>from: {{ (config?.date[0] | c8yDate) || 'No time context' }}</li>
|
|
21
|
+
<li>To: {{ (config?.date[1] | c8yDate) || 'No time context' }}</li>
|
|
22
|
+
</ul>
|
|
23
|
+
</ng-container>
|
|
24
|
+
<button class="btn btn-default" (click)="addAlert()">Add warning alert</button>
|
|
16
25
|
</div>
|
|
17
26
|
`,
|
|
18
27
|
styles: [
|
|
19
28
|
`
|
|
20
29
|
.text {
|
|
21
|
-
|
|
22
|
-
font-size: 3em;
|
|
30
|
+
font-size: 2em;
|
|
23
31
|
}
|
|
24
32
|
`
|
|
25
33
|
]
|
|
26
34
|
})
|
|
27
|
-
export class WidgetDemo {
|
|
35
|
+
export class WidgetDemo implements OnChanges {
|
|
28
36
|
@Input() config;
|
|
37
|
+
alerts: DynamicComponentAlertAggregator;
|
|
38
|
+
|
|
39
|
+
ngOnInit() {
|
|
40
|
+
this.alerts.setAlertGroupDismissStrategy(
|
|
41
|
+
'warning',
|
|
42
|
+
DismissAlertStrategy.TEMPORARY_OR_PERMANENT
|
|
43
|
+
);
|
|
44
|
+
}
|
|
29
45
|
|
|
30
46
|
ngOnChanges(changes: SimpleChanges): void {
|
|
31
|
-
if (!changes
|
|
47
|
+
if (!changes['config']?.firstChange && changes['config']?.currentValue.date) {
|
|
32
48
|
console.log('Global time context changed:', this.config.date);
|
|
33
49
|
}
|
|
34
50
|
}
|
|
51
|
+
|
|
52
|
+
addAlert() {
|
|
53
|
+
this.alerts.addAlerts(
|
|
54
|
+
new DynamicComponentAlert({
|
|
55
|
+
type: 'warning',
|
|
56
|
+
text: gettext('Operation not supported by this device.')
|
|
57
|
+
})
|
|
58
|
+
);
|
|
59
|
+
}
|
|
35
60
|
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { NgModule } from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
CommonModule as C8yCommonModule,
|
|
4
|
+
DynamicComponentDefinition,
|
|
5
|
+
DynamicComponentErrorStrategy,
|
|
6
|
+
FormsModule,
|
|
7
|
+
hookComponent
|
|
8
|
+
} from '@c8y/ngx-components';
|
|
3
9
|
import { AssetSelectorModule } from '@c8y/ngx-components/assets-navigator';
|
|
4
10
|
import { ContextWidgetConfig } from '@c8y/ngx-components/context-dashboard';
|
|
5
11
|
import { WidgetConfigDemo } from './demo-widget-config.component';
|
|
@@ -23,6 +29,7 @@ import { WidgetDemo } from './demo-widget.component';
|
|
|
23
29
|
description: 'This is a description from angular',
|
|
24
30
|
component: WidgetDemo,
|
|
25
31
|
configComponent: WidgetConfigDemo,
|
|
32
|
+
errorStrategy: DynamicComponentErrorStrategy.OVERLAY_ERROR,
|
|
26
33
|
|
|
27
34
|
/** new Angular-Dashboard definition */
|
|
28
35
|
data: {
|
|
@@ -41,7 +48,7 @@ import { WidgetDemo } from './demo-widget.component';
|
|
|
41
48
|
globalTimeContext: true // Set this to true, to add a global time context binding
|
|
42
49
|
}
|
|
43
50
|
} as ContextWidgetConfig
|
|
44
|
-
})
|
|
51
|
+
} as DynamicComponentDefinition)
|
|
45
52
|
]
|
|
46
53
|
})
|
|
47
54
|
export class DashboardWidgetDemoModule {}
|
|
@@ -2,6 +2,7 @@ import { NgModule } from '@angular/core';
|
|
|
2
2
|
import { WidgetResolversComponent } from './widget-resolvers.component';
|
|
3
3
|
import {
|
|
4
4
|
CommonModule,
|
|
5
|
+
DynamicComponentDefinition,
|
|
5
6
|
DynamicComponentErrorStrategy,
|
|
6
7
|
DynamicManagedObjectResolver,
|
|
7
8
|
FormsModule,
|
|
@@ -44,7 +45,7 @@ import { ContextWidgetConfig } from '@c8y/ngx-components/context-dashboard';
|
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
} as ContextWidgetConfig
|
|
47
|
-
})
|
|
48
|
+
} satisfies DynamicComponentDefinition)
|
|
48
49
|
]
|
|
49
50
|
})
|
|
50
51
|
export class WidgetResolversModule {}
|