@c8y/tutorial 1019.19.4 → 1019.20.7

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.
@@ -1,4 +1,3 @@
1
- import { ConfigurationOptions } from '@c8y/devkit/dist/options';
2
1
  import { DefinePlugin } from 'webpack';
3
2
  import { author, description, version } from './package.json';
4
3
 
@@ -136,6 +135,12 @@ export default {
136
135
  path: './src/dynamic-forms/custom-element-example/custom-element-example.module.ts',
137
136
  description: 'A sample for a custom element in dynamic forms.'
138
137
  },
138
+ {
139
+ name: 'Validation Example Module',
140
+ module: 'ValidationExampleModule',
141
+ path: './src/dynamic-forms/validation-example/validation-example.module.ts',
142
+ description: 'A sample for validation options in dynamic forms.'
143
+ },
139
144
  {
140
145
  name: 'Forms validation example module',
141
146
  module: 'FormsTutorialModule',
@@ -622,6 +627,7 @@ export default {
622
627
  'JsonSchemaExampleModule',
623
628
  'IntroductionExampleModule',
624
629
  'CustomElementExampleModule',
630
+ 'ValidationExampleModule',
625
631
  'CascadingStyleSheetsExampleModule',
626
632
  'LeanerStyleSheetsExampleModule',
627
633
  'SyntacticallyAwesomeStyleSheetsExampleModule',
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@c8y/tutorial",
3
- "version": "1019.19.4",
3
+ "version": "1019.20.7",
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.19.4",
7
- "@c8y/style": "1019.19.4",
8
- "@c8y/ngx-components": "1019.19.4",
9
- "@c8y/client": "1019.19.4",
10
- "@c8y/bootstrap": "1019.19.4",
6
+ "@c8y/devkit": "1019.20.7",
7
+ "@c8y/style": "1019.20.7",
8
+ "@c8y/ngx-components": "1019.20.7",
9
+ "@c8y/client": "1019.20.7",
10
+ "@c8y/bootstrap": "1019.20.7",
11
11
  "@angular/cdk": "^16.2.11",
12
12
  "ngx-bootstrap": "11.0.2",
13
13
  "leaflet": "1.7.1",
@@ -1,5 +1,5 @@
1
1
  import { NgModule } from '@angular/core';
2
- import { NavigatorNode, hookNavigator, hookRoute } from '@c8y/ngx-components';
2
+ import { hookNavigator, hookRoute, NavigatorNode } from '@c8y/ngx-components';
3
3
  import { FORMLY_CONFIG } from '@ngx-formly/core';
4
4
  import { CustomFieldCheckbox } from './types/checkbox/checkbox.type.component';
5
5
 
@@ -21,6 +21,7 @@ import { CustomFieldCheckbox } from './types/checkbox/checkbox.type.component';
21
21
  parent: 'Dynamic forms'
22
22
  })
23
23
  ),
24
+ /* Register your custom field as Formly input type */
24
25
  {
25
26
  provide: FORMLY_CONFIG,
26
27
  multi: true,
@@ -0,0 +1,125 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { Component } from '@angular/core';
3
+ import { AbstractControl, FormGroup, ReactiveFormsModule, ValidationErrors } from '@angular/forms';
4
+ import { HeaderModule } from '@c8y/ngx-components';
5
+ import { FormlyFieldConfig, FormlyModule } from '@ngx-formly/core';
6
+ import { delay, of } from 'rxjs';
7
+
8
+ export function ipValidator(control: AbstractControl): ValidationErrors {
9
+ return !control.value || /(\d{1,3}\.){3}\d{1,3}/.test(control.value) ? null : { ip: true };
10
+ }
11
+
12
+ @Component({
13
+ selector: 'c8y-validation-example',
14
+ template: `<c8y-title>Dynamic forms: Validation</c8y-title>
15
+ <div class="row">
16
+ <div class="col-xs-12 col-sm-10 col-md-8 col-lg-6">
17
+ <form class="card" [formGroup]="form" (ngSubmit)="onSubmit()">
18
+ <div class="card-block">
19
+ <formly-form [form]="form" [fields]="fields" [model]="model"></formly-form>
20
+ </div>
21
+ <div class="card-footer">
22
+ <button class="btn btn-default" title="Reset" type="reset">Reset</button>
23
+ <button class="btn btn-primary" title="Submit" type="submit">Submit</button>
24
+ </div>
25
+ </form>
26
+ </div>
27
+ <div class="col-xs-12 col-sm-10 col-md-8 col-lg-6">
28
+ <div class="card">
29
+ <div class="card-block">
30
+ <div class="legend form-block">Model</div>
31
+ <pre style="min-height: 98px;"><code>{{ model | json }}</code></pre>
32
+ </div>
33
+ </div>
34
+ </div>
35
+ </div> `,
36
+ standalone: true,
37
+ imports: [CommonModule, ReactiveFormsModule, FormlyModule, HeaderModule]
38
+ })
39
+ export class ValidationExampleComponent {
40
+ form = new FormGroup({});
41
+ model = {};
42
+ fields: FormlyFieldConfig[] = [
43
+ {
44
+ key: 'built-in',
45
+ type: 'input',
46
+ props: {
47
+ label: 'Built-in validators',
48
+ placeholder: 'Between 0 and 10',
49
+ description: 'This field uses Formly built-in validators',
50
+ required: true,
51
+ min: 0,
52
+ max: 10
53
+ }
54
+ },
55
+ {
56
+ key: 'ip',
57
+ type: 'input',
58
+ props: {
59
+ label: 'IP address',
60
+ placeholder: '192.168.0.1',
61
+ description: 'Uses custom validator declared in NgModule'
62
+ },
63
+ validators: {
64
+ validation: ['ip']
65
+ }
66
+ },
67
+ {
68
+ key: 'subnet-mask',
69
+ type: 'input',
70
+ props: {
71
+ label: 'Subnet mask',
72
+ placeholder: '255.255.254.0',
73
+ description: 'Uses custom validation through <code>validators.expression</code> property'
74
+ },
75
+ validators: {
76
+ snmask: {
77
+ expression: (c: AbstractControl) =>
78
+ !c.value ||
79
+ /(((255\.){3}(255|254|252|248|240|224|192|128|0+))|((255\.){2}(255|254|252|248|240|224|192|128|0+)\.0)|((255\.)(255|254|252|248|240|224|192|128|0+)(\.0+){2})|((255|254|252|248|240|224|192|128|0+)(\.0+){3}))/.test(
80
+ c.value
81
+ ),
82
+ message: (error: object, field: FormlyFieldConfig) =>
83
+ `"${field.formControl.value}" is not a valid subnet mask`
84
+ }
85
+ }
86
+ },
87
+ {
88
+ key: 'dns',
89
+ type: 'input',
90
+ templateOptions: {
91
+ label: 'DNS',
92
+ placeholder: '1.1.1.1',
93
+ description: 'Uses custom validation through <code>validators.validation</code> property'
94
+ },
95
+ validators: {
96
+ validation: [ipValidator]
97
+ }
98
+ },
99
+ {
100
+ key: 'username',
101
+ type: 'input',
102
+ props: {
103
+ label: 'Username',
104
+ placeholder: 'Spider-Man',
105
+ description: 'Username is checked for uniqueness asynchronously'
106
+ },
107
+ asyncValidators: {
108
+ uniqueUsername: {
109
+ expression: (control: AbstractControl) =>
110
+ of(
111
+ ['Spider-Man', 'Wonder Woman', 'Batman', 'Iron Man'].indexOf(control.value) === -1
112
+ ).pipe(delay(1000)),
113
+ message: (error: any, field: FormlyFieldConfig) =>
114
+ `${field.formControl.value} is already taken.`
115
+ }
116
+ }
117
+ }
118
+ ];
119
+
120
+ onSubmit() {
121
+ if (this.form.valid) {
122
+ alert(JSON.stringify(this.model));
123
+ }
124
+ }
125
+ }
@@ -0,0 +1,42 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { NgModule } from '@angular/core';
3
+ import { AbstractControl, ValidationErrors } from '@angular/forms';
4
+ import { hookNavigator, hookRoute, NavigatorNode } from '@c8y/ngx-components';
5
+ import { FormlyFieldConfig, FORMLY_CONFIG } from '@ngx-formly/core';
6
+
7
+ export function IpValidator(control: AbstractControl): ValidationErrors {
8
+ return !control.value || /(\d{1,3}\.){3}\d{1,3}/.test(control.value) ? null : { ip: true };
9
+ }
10
+
11
+ export function IpValidatorMessage(error: any, field: FormlyFieldConfig) {
12
+ return `"${field.formControl.value}" is not a valid IP Address`;
13
+ }
14
+
15
+ @NgModule({
16
+ imports: [CommonModule],
17
+ providers: [
18
+ hookRoute({
19
+ path: 'dynamic-forms/validation',
20
+ loadComponent: () =>
21
+ import('./validation-example.component').then(m => m.ValidationExampleComponent)
22
+ }),
23
+ hookNavigator(
24
+ new NavigatorNode({
25
+ path: '/dynamic-forms/validation',
26
+ label: 'Formly Validation',
27
+ icon: 'hand-o-right',
28
+ priority: 60,
29
+ parent: 'Dynamic forms'
30
+ })
31
+ ),
32
+ {
33
+ provide: FORMLY_CONFIG,
34
+ multi: true,
35
+ useValue: {
36
+ validators: [{ name: 'ip', validation: IpValidator }],
37
+ validationMessages: [{ name: 'ip', message: IpValidatorMessage }]
38
+ }
39
+ }
40
+ ]
41
+ })
42
+ export class ValidationExampleModule {}
@@ -53,7 +53,7 @@ export class PropertiesListExampleComponent {
53
53
 
54
54
  readonly archiveManifest: Partial<IManifest> = {
55
55
  author: 'Cumulocity IoT',
56
- homepage: 'https://cumulocity.com/guides/web/overview/',
56
+ homepage: 'https://cumulocity.com/docs/web/introduction/',
57
57
  keywords: ['Cumulocity', 'Plugin', 'Widget'],
58
58
  license: 'Apache 2.0',
59
59
  repository: {