devextreme-schematics 1.3.0-beta.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +10 -8
- package/src/add-app-template/index.js +2 -1
- package/src/add-app-template/index.js.map +1 -1
- package/src/add-app-template/index.ts +30 -0
- package/src/add-app-template/index_spec.js +6 -5
- package/src/add-app-template/index_spec.js.map +1 -1
- package/src/add-app-template/index_spec.ts +73 -0
- package/src/add-app-template/schema.json +7 -3
- package/src/add-layout/files/devextreme.json +1 -1
- package/src/add-layout/files/src/app/__name__.component.html +3 -3
- package/src/add-layout/files/src/app/__name__.component.ts +1 -1
- package/src/add-layout/files/src/app/app-routing.module.ts +1 -1
- package/src/add-layout/files/src/app/layouts/side-nav-inner-toolbar/side-nav-inner-toolbar.component.ts +13 -11
- package/src/add-layout/files/src/app/layouts/side-nav-outer-toolbar/side-nav-outer-toolbar.component.ts +10 -9
- package/src/add-layout/files/src/app/layouts/single-card/single-card.component.ts +4 -4
- package/src/add-layout/files/src/app/not-authorized-container.ts +2 -0
- package/src/add-layout/files/src/app/shared/components/change-password-form/change-password-form.component.html +8 -6
- package/src/add-layout/files/src/app/shared/components/change-password-form/change-password-form.component.ts +6 -15
- package/src/add-layout/files/src/app/shared/components/create-account-form/create-account-form.component.html +9 -7
- package/src/add-layout/files/src/app/shared/components/create-account-form/create-account-form.component.ts +4 -13
- package/src/add-layout/files/src/app/shared/components/header/header.component.ts +11 -6
- package/src/add-layout/files/src/app/shared/components/login-form/login-form.component.html +8 -6
- package/src/add-layout/files/src/app/shared/components/login-form/login-form.component.ts +2 -12
- package/src/add-layout/files/src/app/shared/components/reset-password-form/reset-password-form.component.html +8 -6
- package/src/add-layout/files/src/app/shared/components/reset-password-form/reset-password-form.component.ts +2 -12
- package/src/add-layout/files/src/app/shared/components/side-navigation-menu/side-navigation-menu.component.ts +8 -7
- package/src/add-layout/files/src/app/shared/components/user-panel/user-panel.component.html +5 -2
- package/src/add-layout/files/src/app/shared/components/user-panel/user-panel.component.ts +3 -2
- package/src/add-layout/files/src/app/shared/services/auth.service.ts +11 -5
- package/src/add-layout/files/src/app/shared/services/screen.service.ts +2 -2
- package/src/add-layout/files/src/app/unauthenticated-content.ts +53 -0
- package/src/add-layout/files/src/dx-styles.scss +4 -0
- package/src/add-layout/index.js +45 -31
- package/src/add-layout/index.js.map +1 -1
- package/src/add-layout/index.ts +384 -0
- package/src/add-layout/index_spec.js +42 -28
- package/src/add-layout/index_spec.js.map +1 -1
- package/src/add-layout/index_spec.ts +340 -0
- package/src/add-layout/schema.json +6 -2
- package/src/add-sample-views/files/pages/home/home.component.html +5 -5
- package/src/add-sample-views/files/pages/profile/profile.component.ts +1 -1
- package/src/add-sample-views/files/pages/tasks/tasks.component.html +1 -0
- package/src/add-sample-views/index.js +13 -4
- package/src/add-sample-views/index.js.map +1 -1
- package/src/add-sample-views/index.ts +141 -0
- package/src/add-sample-views/index_spec.js +5 -4
- package/src/add-sample-views/index_spec.js.map +1 -1
- package/src/add-sample-views/index_spec.ts +74 -0
- package/src/add-sample-views/schema.json +1 -1
- package/src/add-view/index.d.ts +2 -2
- package/src/add-view/index.js +33 -22
- package/src/add-view/index.js.map +1 -1
- package/src/add-view/index.ts +166 -0
- package/src/add-view/index_spec.js +12 -12
- package/src/add-view/index_spec.js.map +1 -1
- package/src/add-view/index_spec.ts +155 -0
- package/src/add-view/schema.json +4 -4
- package/src/collection.json +2 -1
- package/src/install/index.js +16 -3
- package/src/install/index.js.map +1 -1
- package/src/install/index.ts +88 -0
- package/src/install/index_spec.js +10 -9
- package/src/install/index_spec.js.map +1 -1
- package/src/install/index_spec.ts +106 -0
- package/src/install/schema.json +2 -2
- package/src/utility/array.js +1 -0
- package/src/utility/array.js.map +1 -1
- package/src/utility/array.ts +3 -0
- package/src/utility/change.js +1 -0
- package/src/utility/change.js.map +1 -1
- package/src/utility/change.ts +66 -0
- package/src/utility/latest-versions.d.ts +1 -1
- package/src/utility/latest-versions.js +3 -2
- package/src/utility/latest-versions.js.map +1 -1
- package/src/utility/latest-versions.ts +6 -0
- package/src/utility/modify-json-file.d.ts +1 -0
- package/src/utility/modify-json-file.js +7 -3
- package/src/utility/modify-json-file.js.map +1 -1
- package/src/utility/modify-json-file.ts +16 -0
- package/src/utility/project.d.ts +4 -4
- package/src/utility/project.js +35 -12
- package/src/utility/project.js.map +1 -1
- package/src/utility/project.ts +30 -0
- package/src/utility/routing.js +1 -0
- package/src/utility/routing.js.map +1 -1
- package/src/utility/routing.ts +44 -0
- package/src/utility/source.js +1 -0
- package/src/utility/source.js.map +1 -1
- package/src/utility/source.ts +16 -0
- package/src/utility/string.js +1 -0
- package/src/utility/string.js.map +1 -1
- package/src/utility/string.ts +5 -0
- package/src/utility/styles.d.ts +1 -2
- package/src/utility/styles.js +3 -4
- package/src/utility/styles.js.map +1 -1
- package/src/utility/styles.ts +30 -0
@@ -0,0 +1,340 @@
|
|
1
|
+
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
|
2
|
+
import { Schema as WorkspaceOptions } from '@schematics/angular/workspace/schema';
|
3
|
+
import {
|
4
|
+
NodeDependencyType,
|
5
|
+
addPackageJsonDependency,
|
6
|
+
removePackageJsonDependency
|
7
|
+
} from '@schematics/angular/utility/dependencies';
|
8
|
+
import * as path from 'path';
|
9
|
+
|
10
|
+
import { modifyJSONFile } from '../utility/modify-json-file';
|
11
|
+
|
12
|
+
const collectionPath = path.join(__dirname, '../collection.json');
|
13
|
+
|
14
|
+
describe('layout', () => {
|
15
|
+
const appOptions: any = {
|
16
|
+
name: 'testApp',
|
17
|
+
projectRoot: '',
|
18
|
+
inlineStyle: false,
|
19
|
+
inlineTemplate: false,
|
20
|
+
routing: false,
|
21
|
+
style: 'scss',
|
22
|
+
skipTests: false,
|
23
|
+
skipPackageJson: false
|
24
|
+
};
|
25
|
+
|
26
|
+
const workspaceOptions: WorkspaceOptions = {
|
27
|
+
name: 'workspace',
|
28
|
+
version: '6.0.0'
|
29
|
+
};
|
30
|
+
|
31
|
+
const options: any = {
|
32
|
+
layout: 'side-nav-outer-toolbar',
|
33
|
+
resolveConflicts: 'override',
|
34
|
+
globalNgCliVersion: '^8.0.0'
|
35
|
+
};
|
36
|
+
|
37
|
+
const angularSchematicsCollection = require.resolve('../../node_modules/@schematics/angular/collection.json');
|
38
|
+
const schematicRunner = new SchematicTestRunner('@schematics/angular', angularSchematicsCollection);
|
39
|
+
let appTree: UnitTestTree;
|
40
|
+
|
41
|
+
beforeEach(async () => {
|
42
|
+
appTree = await schematicRunner.runSchematicAsync('workspace', workspaceOptions).toPromise();
|
43
|
+
appTree = await schematicRunner.runSchematicAsync('application', appOptions, appTree).toPromise();
|
44
|
+
});
|
45
|
+
|
46
|
+
it('should add layout with override', async () => {
|
47
|
+
const runner = new SchematicTestRunner('schematics', collectionPath);
|
48
|
+
const tree = await runner.runSchematicAsync('add-layout', options, appTree).toPromise();
|
49
|
+
|
50
|
+
expect(tree.files)
|
51
|
+
.toContain('/devextreme.json');
|
52
|
+
expect(tree.files)
|
53
|
+
.toContain('/src/app/app-navigation.ts');
|
54
|
+
expect(tree.files)
|
55
|
+
.toContain('/src/app/shared/components/header/header.component.ts');
|
56
|
+
expect(tree.files)
|
57
|
+
.toContain('/src/app/shared/components/login-form/login-form.component.ts');
|
58
|
+
expect(tree.files)
|
59
|
+
.toContain('/src/app/shared/components/side-navigation-menu/side-navigation-menu.component.ts');
|
60
|
+
expect(tree.files)
|
61
|
+
.toContain('/src/app/shared/services/app-info.service.ts');
|
62
|
+
expect(tree.files)
|
63
|
+
.toContain('/src/app/shared/services/auth.service.ts');
|
64
|
+
expect(tree.files)
|
65
|
+
.toContain('/src/app/shared/services/screen.service.ts');
|
66
|
+
expect(tree.files)
|
67
|
+
.toContain('/src/app/layouts/side-nav-outer-toolbar/side-nav-outer-toolbar.component.ts');
|
68
|
+
expect(tree.files)
|
69
|
+
.toContain('/src/app/layouts/side-nav-inner-toolbar/side-nav-inner-toolbar.component.ts');
|
70
|
+
expect(tree.files)
|
71
|
+
.toContain('/src/app/layouts/single-card/single-card.component.ts');
|
72
|
+
expect(tree.files)
|
73
|
+
.toContain('/src/themes/metadata.base.json');
|
74
|
+
expect(tree.files)
|
75
|
+
.toContain('/src/themes/metadata.additional.json');
|
76
|
+
|
77
|
+
const devextremeConfigContent = tree.readContent('/devextreme.json');
|
78
|
+
expect(devextremeConfigContent).toContain('"applicationEngine": "angular"');
|
79
|
+
expect(devextremeConfigContent).toContain('"inputFile": "src/themes/metadata.additional.json"');
|
80
|
+
expect(devextremeConfigContent).toMatch(/\n\s{2}\S/g);
|
81
|
+
|
82
|
+
const componentContent = tree.readContent('/src/app/app.component.html');
|
83
|
+
expect(componentContent).toContain('app-side-nav-outer-toolbar title="{{appInfo.title}}"');
|
84
|
+
|
85
|
+
const stylesContent = tree.readContent('/src/dx-styles.scss');
|
86
|
+
expect(stylesContent).toMatch(/html, body {/);
|
87
|
+
|
88
|
+
const indexContent = tree.readContent('/src/index.html');
|
89
|
+
expect(indexContent).toMatch(/<body class="dx-viewport">/);
|
90
|
+
|
91
|
+
const angularContent = JSON.parse(tree.readContent('/angular.json'));
|
92
|
+
const styles = angularContent.projects.testApp.architect.build.options.styles;
|
93
|
+
|
94
|
+
expect(styles[0]).toBe('node_modules/devextreme/dist/css/dx.common.css');
|
95
|
+
expect(styles[1]).toBe('src/themes/generated/theme.base.css');
|
96
|
+
expect(styles[2]).toBe('src/themes/generated/theme.additional.css');
|
97
|
+
|
98
|
+
const moduleContent = tree.readContent('/src/app/app.module.ts');
|
99
|
+
expect(moduleContent)
|
100
|
+
.toContain('import { SideNavOuterToolbarModule, SideNavInnerToolbarModule, SingleCardModule }');
|
101
|
+
expect(moduleContent)
|
102
|
+
.toContain(`import { AuthService, ScreenService, AppInfoService } from './shared/services';`);
|
103
|
+
expect(moduleContent).toContain('import { AppRoutingModule }');
|
104
|
+
expect(moduleContent)
|
105
|
+
.toContain('import { FooterModule, ' +
|
106
|
+
'ResetPasswordFormModule, ' +
|
107
|
+
'CreateAccountFormModule, ' +
|
108
|
+
'ChangePasswordFormModule, ' +
|
109
|
+
'LoginFormModule }');
|
110
|
+
|
111
|
+
const testContent = tree.readContent('/e2e/src/app.e2e-spec.ts');
|
112
|
+
expect(testContent).toMatch(/'Welcome to TestApp!'/);
|
113
|
+
|
114
|
+
const testUtilsContent = tree.readContent('/e2e/src/app.po.ts');
|
115
|
+
expect(testUtilsContent).toMatch(/'app-root .dx-drawer-content .dx-card p:nth-child\(2\)'/);
|
116
|
+
|
117
|
+
const appContent = tree.readContent('/src/app/app.component.ts');
|
118
|
+
expect(appContent).toContain('templateUrl: \'./app.component.html\',');
|
119
|
+
expect(appContent).toContain('styleUrls: [\'./app.component.scss\']');
|
120
|
+
expect(appContent).toContain('selector: \'app-root\',');
|
121
|
+
expect(appContent).toContain(`import { AuthService, ScreenService, AppInfoService } from './shared/services';`);
|
122
|
+
|
123
|
+
const navigationMenu = tree.readContent(
|
124
|
+
'/src/app/shared/components/side-navigation-menu/side-navigation-menu.component.ts');
|
125
|
+
expect(navigationMenu).toContain('@ViewChild(DxTreeViewComponent, { static: true })');
|
126
|
+
});
|
127
|
+
|
128
|
+
it('should add npm scripts', async () => {
|
129
|
+
const runner = new SchematicTestRunner('schematics', collectionPath);
|
130
|
+
const tree = await runner.runSchematicAsync('add-layout', options, appTree).toPromise();
|
131
|
+
const packageConfig = JSON.parse(tree.readContent('package.json'));
|
132
|
+
expect(packageConfig.scripts['build-themes']).toBe('devextreme build');
|
133
|
+
expect(packageConfig.scripts['postinstall']).toBe('npm run build-themes');
|
134
|
+
});
|
135
|
+
|
136
|
+
it('should set static flag', async () => {
|
137
|
+
removePackageJsonDependency(appTree, '@angular/core');
|
138
|
+
addPackageJsonDependency(appTree, {
|
139
|
+
type: NodeDependencyType.Default,
|
140
|
+
name: '@angular/core',
|
141
|
+
version: '7.0.0'
|
142
|
+
});
|
143
|
+
|
144
|
+
const runner = new SchematicTestRunner('schematics', collectionPath);
|
145
|
+
const tree = await runner.runSchematicAsync('add-layout', options, appTree).toPromise();
|
146
|
+
const navigationMenu = tree.readContent(
|
147
|
+
'/src/app/shared/components/side-navigation-menu/side-navigation-menu.component.ts');
|
148
|
+
|
149
|
+
expect(navigationMenu).toContain('@ViewChild(DxTreeViewComponent, { static: true })');
|
150
|
+
});
|
151
|
+
|
152
|
+
it('should add npm scripts safely', async () => {
|
153
|
+
modifyJSONFile(appTree, './package.json', config => {
|
154
|
+
const scripts = config['scripts'];
|
155
|
+
|
156
|
+
scripts['build-themes'] = 'prev value 1';
|
157
|
+
scripts['postinstall'] = 'prev value 2';
|
158
|
+
|
159
|
+
return config;
|
160
|
+
});
|
161
|
+
|
162
|
+
const runner = new SchematicTestRunner('schematics', collectionPath);
|
163
|
+
const tree = await runner.runSchematicAsync('add-layout', options, appTree).toPromise();
|
164
|
+
const packageConfig = JSON.parse(tree.readContent('package.json'));
|
165
|
+
expect(packageConfig.scripts['origin-build-themes']).toBe('prev value 1');
|
166
|
+
expect(packageConfig.scripts['origin-postinstall']).toBe('prev value 2');
|
167
|
+
expect(packageConfig.scripts['build-themes']).toBe('npm run origin-build-themes && devextreme build');
|
168
|
+
expect(packageConfig.scripts['postinstall']).toBe('npm run origin-postinstall && npm run build-themes');
|
169
|
+
});
|
170
|
+
|
171
|
+
it('should add angular/cdk dependency', async () => {
|
172
|
+
const runner = new SchematicTestRunner('schematics', collectionPath);
|
173
|
+
const tree = await runner.runSchematicAsync('add-layout', options, appTree).toPromise();
|
174
|
+
const packageConfig = JSON.parse(tree.readContent('package.json'));
|
175
|
+
|
176
|
+
expect(packageConfig.dependencies['@angular/cdk']).toBeDefined();
|
177
|
+
});
|
178
|
+
|
179
|
+
it('should choose angular/cdk version such as angular/cli', async () => {
|
180
|
+
const runner = new SchematicTestRunner('schematics', collectionPath);
|
181
|
+
const tree = await runner.runSchematicAsync('add-layout', options, appTree).toPromise();
|
182
|
+
const packageConfig = JSON.parse(tree.readContent('package.json'));
|
183
|
+
|
184
|
+
expect(packageConfig.dependencies['@angular/cdk']).toBe('^8.0.0');
|
185
|
+
});
|
186
|
+
|
187
|
+
it('should update budgets if updateBudgets option is true', async () => {
|
188
|
+
const runner = new SchematicTestRunner('schematics', collectionPath);
|
189
|
+
const tree = await runner.runSchematicAsync('add-layout', {
|
190
|
+
...options,
|
191
|
+
updateBudgets: true
|
192
|
+
}, appTree).toPromise();
|
193
|
+
|
194
|
+
const angularContent = JSON.parse(tree.readContent('/angular.json'));
|
195
|
+
const budgets = angularContent.projects.testApp.architect.build.configurations.production.budgets;
|
196
|
+
|
197
|
+
expect(budgets.length).toBe(2);
|
198
|
+
expect(budgets[0]).toEqual({
|
199
|
+
type: 'initial',
|
200
|
+
maximumWarning: '4mb',
|
201
|
+
maximumError: '7mb'
|
202
|
+
});
|
203
|
+
});
|
204
|
+
|
205
|
+
it('should not update budgets if updateBudgets option is not defined or false', async () => {
|
206
|
+
const runner = new SchematicTestRunner('schematics', collectionPath);
|
207
|
+
const tree = await runner.runSchematicAsync('add-layout', options, appTree).toPromise();
|
208
|
+
|
209
|
+
const angularContent = JSON.parse(tree.readContent('/angular.json'));
|
210
|
+
const budgets = angularContent.projects.testApp.architect.build.configurations.production.budgets;
|
211
|
+
const defaultBudget = {
|
212
|
+
type: 'initial',
|
213
|
+
maximumWarning: '500kb',
|
214
|
+
maximumError: '1mb'
|
215
|
+
};
|
216
|
+
|
217
|
+
expect(budgets.length).toBe(2);
|
218
|
+
expect(budgets[0]).toEqual(defaultBudget);
|
219
|
+
});
|
220
|
+
|
221
|
+
it('should add layout without override', async () => {
|
222
|
+
const runner = new SchematicTestRunner('schematics', collectionPath);
|
223
|
+
|
224
|
+
options.resolveConflicts = 'createNew';
|
225
|
+
const tree = await runner.runSchematicAsync('add-layout', options, appTree).toPromise();
|
226
|
+
|
227
|
+
expect(tree.files).toContain('/src/app/app1.component.ts');
|
228
|
+
|
229
|
+
const componentContent = tree.readContent('/src/app/app1.component.html');
|
230
|
+
expect(componentContent).toContain('app-side-nav-outer-toolbar title="{{appInfo.title}}"');
|
231
|
+
|
232
|
+
const appContent = tree.readContent('/src/app/app.component.ts');
|
233
|
+
expect(appContent).toMatch(/templateUrl: '.\/app.component.html',/);
|
234
|
+
expect(appContent).toMatch(/styleUrls: \['.\/app.component.scss'\]/);
|
235
|
+
|
236
|
+
const newAppContent = tree.readContent('/src/app/app1.component.ts');
|
237
|
+
expect(newAppContent).toMatch(/templateUrl: '.\/app1.component.html',/);
|
238
|
+
expect(newAppContent).toMatch(/styleUrls: \['.\/app1.component.scss'\]/);
|
239
|
+
expect(newAppContent).toContain(`import { AuthService, ScreenService, AppInfoService } from './shared/services';`);
|
240
|
+
|
241
|
+
const appInfo = tree.readContent('/src/app/shared/services/app-info.service.ts');
|
242
|
+
expect(appInfo).toContain(`return 'TestApp';`);
|
243
|
+
});
|
244
|
+
|
245
|
+
it('should add routing to layout', async () => {
|
246
|
+
let newAppTree = await schematicRunner.runSchematicAsync('workspace', workspaceOptions).toPromise();
|
247
|
+
|
248
|
+
appOptions.routing = false;
|
249
|
+
newAppTree = await schematicRunner.runSchematicAsync(
|
250
|
+
'application', appOptions, newAppTree).toPromise();
|
251
|
+
|
252
|
+
const runner = new SchematicTestRunner('schematics', collectionPath);
|
253
|
+
const tree = await runner.runSchematicAsync('add-layout', options, appTree).toPromise();
|
254
|
+
|
255
|
+
expect(tree.files).toContain('/src/app/app-routing.module.ts');
|
256
|
+
const moduleContent = tree.readContent('/src/app/app-routing.module.ts');
|
257
|
+
expect(moduleContent)
|
258
|
+
.toMatch(/imports:\s\[RouterModule\.forRoot\(routes, { useHash: true }\)\],/);
|
259
|
+
|
260
|
+
expect(moduleContent)
|
261
|
+
.toContain(`{
|
262
|
+
path: 'login-form',
|
263
|
+
component: LoginFormComponent,
|
264
|
+
canActivate: [ AuthGuardService ]
|
265
|
+
}`);
|
266
|
+
});
|
267
|
+
|
268
|
+
it('should use selected layout', async () => {
|
269
|
+
const runner = new SchematicTestRunner('schematics', collectionPath);
|
270
|
+
options.layout = 'side-nav-inner-toolbar';
|
271
|
+
options.resolveConflicts = 'override';
|
272
|
+
const tree = await runner.runSchematicAsync('add-layout', options, appTree).toPromise();
|
273
|
+
const content = tree.readContent('/src/app/app.component.html');
|
274
|
+
|
275
|
+
expect(content).toContain('app-side-nav-inner-toolbar title="{{appInfo.title}}"');
|
276
|
+
});
|
277
|
+
|
278
|
+
it('should consider the `project` option', async () => {
|
279
|
+
appTree = await schematicRunner.runSchematicAsync('application', {
|
280
|
+
...appOptions,
|
281
|
+
name: 'testApp2',
|
282
|
+
projectRoot: 'projects/testApp2'
|
283
|
+
}, appTree).toPromise();
|
284
|
+
|
285
|
+
const runner = new SchematicTestRunner('schematics', collectionPath);
|
286
|
+
const tree = await runner.runSchematicAsync('add-layout', {
|
287
|
+
...options,
|
288
|
+
project: 'testApp2'
|
289
|
+
}, appTree).toPromise();
|
290
|
+
|
291
|
+
expect(tree.files)
|
292
|
+
.toContain('/devextreme.json');
|
293
|
+
expect(tree.files)
|
294
|
+
.toContain('/projects/testApp2/src/themes/metadata.base.json');
|
295
|
+
});
|
296
|
+
|
297
|
+
it('should merge build commands in devextreme.json file', async () => {
|
298
|
+
appTree = await schematicRunner.runSchematicAsync('application', {
|
299
|
+
...appOptions,
|
300
|
+
name: 'testApp2',
|
301
|
+
prefix: 'app2',
|
302
|
+
projectRoot: 'projects/testApp2'
|
303
|
+
}, appTree).toPromise();
|
304
|
+
|
305
|
+
const runner = new SchematicTestRunner('schematics', collectionPath);
|
306
|
+
let tree = await runner.runSchematicAsync('add-layout', options, appTree).toPromise();
|
307
|
+
tree = await runner.runSchematicAsync('add-layout', {
|
308
|
+
...options,
|
309
|
+
project: 'testApp2'
|
310
|
+
}, appTree).toPromise();
|
311
|
+
|
312
|
+
const appContent = tree.readContent('projects/testApp2/src/app/app.component.ts');
|
313
|
+
expect(appContent).toContain('selector: \'app2-root\',');
|
314
|
+
|
315
|
+
const content = tree.readContent('/devextreme.json');
|
316
|
+
expect(content).toContain('"inputFile": "src/themes/metadata.base.json",');
|
317
|
+
expect(content).toContain('"inputFile": "projects/testApp2/src/themes/metadata.base.json",');
|
318
|
+
});
|
319
|
+
|
320
|
+
it('should add e2e tests only for default project', async () => {
|
321
|
+
appTree = await schematicRunner.runSchematicAsync('application', {
|
322
|
+
...appOptions,
|
323
|
+
name: 'testApp2',
|
324
|
+
projectRoot: 'projects/testApp2'
|
325
|
+
}, appTree).toPromise();
|
326
|
+
|
327
|
+
const runner = new SchematicTestRunner('schematics', collectionPath);
|
328
|
+
let tree = await runner.runSchematicAsync('add-layout', options, appTree).toPromise();
|
329
|
+
tree = await runner.runSchematicAsync('add-layout', {
|
330
|
+
...options,
|
331
|
+
project: 'testApp2'
|
332
|
+
}, appTree).toPromise();
|
333
|
+
|
334
|
+
const testContent = tree.readContent('/e2e/src/app.e2e-spec.ts');
|
335
|
+
expect(testContent).toContain('Welcome to TestApp!');
|
336
|
+
|
337
|
+
const testUtilsContent = tree.readContent('/e2e/src/app.po.ts');
|
338
|
+
expect(testUtilsContent).toMatch(/'app-root .dx-drawer-content .dx-card p:nth-child\(2\)'/);
|
339
|
+
});
|
340
|
+
});
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"$schema": "http://json-schema.org/schema",
|
3
|
-
"id": "SchematicsDevextremeAddLayout",
|
3
|
+
"$id": "SchematicsDevextremeAddLayout",
|
4
4
|
"title": "Add a DevExtreme layout to a DevExtreme Angular application",
|
5
5
|
"type": "object",
|
6
6
|
"properties": {
|
@@ -10,7 +10,7 @@
|
|
10
10
|
"description": "The type of a DevExtreme layout to add",
|
11
11
|
"default": "side-nav-outer-toolbar",
|
12
12
|
"x-prompt": {
|
13
|
-
"message": "
|
13
|
+
"message": "Specify desired application layout:",
|
14
14
|
"type": "list",
|
15
15
|
"items": [
|
16
16
|
{ "value": "side-nav-outer-toolbar", "label": "Side navigation (outer toolbar)" },
|
@@ -46,6 +46,10 @@
|
|
46
46
|
},
|
47
47
|
"updateBudgets": {
|
48
48
|
"type": "boolean"
|
49
|
+
},
|
50
|
+
"globalNgCliVersion": {
|
51
|
+
"type":"string",
|
52
|
+
"default": "^12.0.0"
|
49
53
|
}
|
50
54
|
}
|
51
55
|
}
|
@@ -18,7 +18,7 @@
|
|
18
18
|
and <a href="https://js.devexpress.com/Documentation/Guide/Common/DevExtreme_CLI/" target="_blank" rel="noopener noreferrer">DevExtreme CLI</a>
|
19
19
|
and includes the following DevExtreme components:</p>
|
20
20
|
<ul>
|
21
|
-
<li><a href="https://js.devexpress.com/Documentation/Guide/
|
21
|
+
<li><a href="https://js.devexpress.com/Documentation/Guide/UI_Components/DataGrid/Getting_Started_with_DataGrid/" target="_blank" rel="noopener noreferrer">DataGrid</a></li>
|
22
22
|
<li><a href="https://js.devexpress.com/Documentation/Guide/Widgets/Form/Overview/" target="_blank" rel="noopener noreferrer">Form</a></li>
|
23
23
|
<li><a href="https://js.devexpress.com/Documentation/Guide/Widgets/Drawer/Getting_Started_with_Navigation_Drawer/" target="_blank" rel="noopener noreferrer">Drawer</a></li>
|
24
24
|
</ul>
|
@@ -26,10 +26,10 @@
|
|
26
26
|
<p>To customize your DevExtreme Angular application further, please refer to the following help topics:</p>
|
27
27
|
|
28
28
|
<ul>
|
29
|
-
<li><a href="https://js.devexpress.com/Documentation/Guide/Angular_Components/
|
30
|
-
<li><a href="https://js.devexpress.com/Documentation/Guide/Angular_Components/
|
31
|
-
<li><a href="https://js.devexpress.com/Documentation/Guide/Angular_Components/
|
32
|
-
<li><a href="https://js.devexpress.com/Documentation/Guide/Angular_Components/
|
29
|
+
<li><a href="https://js.devexpress.com/Documentation/Guide/Angular_Components/Application_Template/#Layouts" target="_blank" rel="noopener noreferrer">Layouts</a></li>
|
30
|
+
<li><a href="https://js.devexpress.com/Documentation/Guide/Angular_Components/Application_Template/#Add_a_New_View" target="_blank" rel="noopener noreferrer">Add a New View</a></li>
|
31
|
+
<li><a href="https://js.devexpress.com/Documentation/Guide/Angular_Components/Application_Template/#Configure_the_Navigation_Menu" target="_blank" rel="noopener noreferrer">Configure the Navigation Menu</a></li>
|
32
|
+
<li><a href="https://js.devexpress.com/Documentation/Guide/Angular_Components/Application_Template/#Configure_Themes" target="_blank" rel="noopener noreferrer">Configure Themes</a></li>
|
33
33
|
</ul>
|
34
34
|
|
35
35
|
<p>For technical content related to DevExtreme Angular components, feel free to explore
|
@@ -17,7 +17,7 @@ export class ProfileComponent {
|
|
17
17
|
Prefix: 'Mrs.',
|
18
18
|
Position: 'Controller',
|
19
19
|
Picture: 'images/employees/06.png',
|
20
|
-
BirthDate: new Date('1974/11/
|
20
|
+
BirthDate: new Date('1974/11/5'),
|
21
21
|
HireDate: new Date('2005/05/11'),
|
22
22
|
/* tslint:disable-next-line:max-line-length */
|
23
23
|
Notes: 'Sandra is a CPA and has been our controller since 2008. She loves to interact with staff so if you`ve not met her, be certain to say hi.\r\n\r\nSandra has 2 daughters both of whom are accomplished gymnasts.',
|
@@ -1,4 +1,13 @@
|
|
1
1
|
"use strict";
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9
|
+
});
|
10
|
+
};
|
2
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
12
|
const schematics_1 = require("@angular-devkit/schematics");
|
4
13
|
const ast_utils_1 = require("@schematics/angular/utility/ast-utils");
|
@@ -79,9 +88,9 @@ function addDefaultNavigation(rootPath) {
|
|
79
88
|
};
|
80
89
|
}
|
81
90
|
function default_1(options) {
|
82
|
-
return (host) => {
|
83
|
-
const project = project_1.getProjectName(host, options.project);
|
84
|
-
const rootPath = project_1.getApplicationPath(host, project);
|
91
|
+
return (host) => __awaiter(this, void 0, void 0, function* () {
|
92
|
+
const project = yield project_1.getProjectName(host, options.project);
|
93
|
+
const rootPath = yield project_1.getApplicationPath(host, project);
|
85
94
|
const routingPath = rootPath + 'app-routing.module.ts';
|
86
95
|
const rules = [];
|
87
96
|
const templateSource = schematics_1.apply(schematics_1.url('./files'), [
|
@@ -100,7 +109,7 @@ function default_1(options) {
|
|
100
109
|
});
|
101
110
|
rules.push(addDefaultNavigation(rootPath));
|
102
111
|
return schematics_1.chain(rules);
|
103
|
-
};
|
112
|
+
});
|
104
113
|
}
|
105
114
|
exports.default = default_1;
|
106
115
|
//# sourceMappingURL=index.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,141 @@
|
|
1
|
+
import {
|
2
|
+
Rule,
|
3
|
+
Tree,
|
4
|
+
chain,
|
5
|
+
apply,
|
6
|
+
template,
|
7
|
+
move,
|
8
|
+
url,
|
9
|
+
mergeWith
|
10
|
+
} from '@angular-devkit/schematics';
|
11
|
+
|
12
|
+
import {
|
13
|
+
addDeclarationToModule,
|
14
|
+
addImportToModule
|
15
|
+
} from '@schematics/angular/utility/ast-utils';
|
16
|
+
|
17
|
+
import { addViewToRouting } from '../add-view';
|
18
|
+
|
19
|
+
import {
|
20
|
+
getApplicationPath,
|
21
|
+
getProjectName
|
22
|
+
} from '../utility/project';
|
23
|
+
|
24
|
+
import { humanize } from '../utility/string';
|
25
|
+
|
26
|
+
import {
|
27
|
+
applyChanges,
|
28
|
+
insertItemToArray
|
29
|
+
} from '../utility/change';
|
30
|
+
|
31
|
+
import { getSourceFile } from '../utility/source';
|
32
|
+
|
33
|
+
const sampleViewOptions = [
|
34
|
+
{
|
35
|
+
name: 'home',
|
36
|
+
componentName: 'HomeComponent',
|
37
|
+
relativePath: './pages/home/home.component'
|
38
|
+
}, {
|
39
|
+
name: 'profile',
|
40
|
+
componentName: 'ProfileComponent',
|
41
|
+
relativePath: './pages/profile/profile.component'
|
42
|
+
}, {
|
43
|
+
name: 'tasks',
|
44
|
+
componentName: 'TasksComponent',
|
45
|
+
relativePath: './pages/tasks/tasks.component'
|
46
|
+
}];
|
47
|
+
|
48
|
+
const devextremeOptions = [
|
49
|
+
{
|
50
|
+
componentName: 'DxDataGridModule',
|
51
|
+
relativePath: 'devextreme-angular'
|
52
|
+
}, {
|
53
|
+
componentName: 'DxFormModule',
|
54
|
+
relativePath: 'devextreme-angular'
|
55
|
+
}];
|
56
|
+
|
57
|
+
const navigations = [
|
58
|
+
` {
|
59
|
+
text: 'Home',
|
60
|
+
path: '/home',
|
61
|
+
icon: 'home'
|
62
|
+
}`,
|
63
|
+
` {
|
64
|
+
text: 'Examples',
|
65
|
+
icon: 'folder',
|
66
|
+
items: [
|
67
|
+
{
|
68
|
+
text: 'Profile',
|
69
|
+
path: '/profile'
|
70
|
+
},
|
71
|
+
{
|
72
|
+
text: 'Tasks',
|
73
|
+
path: '/tasks'
|
74
|
+
}
|
75
|
+
]
|
76
|
+
}`
|
77
|
+
];
|
78
|
+
|
79
|
+
function addImportsToRoutingModule(isView: boolean, routingPath: string, options: any) {
|
80
|
+
return (host: Tree) => {
|
81
|
+
const source = getSourceFile(host, routingPath);
|
82
|
+
|
83
|
+
if (!source) {
|
84
|
+
return host;
|
85
|
+
}
|
86
|
+
|
87
|
+
let changes;
|
88
|
+
|
89
|
+
if (isView) {
|
90
|
+
changes = addDeclarationToModule(source, routingPath, options.componentName, options.relativePath);
|
91
|
+
} else {
|
92
|
+
changes = addImportToModule(source, routingPath, options.componentName, options.relativePath);
|
93
|
+
}
|
94
|
+
|
95
|
+
return applyChanges(host, changes, routingPath);
|
96
|
+
};
|
97
|
+
}
|
98
|
+
|
99
|
+
function addDefaultNavigation(rootPath: string) {
|
100
|
+
return (host: Tree) => {
|
101
|
+
const navigationPath = rootPath + 'app-navigation.ts';
|
102
|
+
|
103
|
+
navigations.forEach((navigation) => {
|
104
|
+
const navigationSource = getSourceFile(host, navigationPath)!;
|
105
|
+
insertItemToArray(host, navigationPath, navigationSource, navigation, { location: 'end' });
|
106
|
+
});
|
107
|
+
|
108
|
+
return host;
|
109
|
+
};
|
110
|
+
}
|
111
|
+
|
112
|
+
export default function(options: any): Rule {
|
113
|
+
return async (host: Tree) => {
|
114
|
+
const project = await getProjectName(host, options.project);
|
115
|
+
const rootPath = await getApplicationPath(host, project);
|
116
|
+
const routingPath = rootPath + 'app-routing.module.ts';
|
117
|
+
const rules: any[] = [];
|
118
|
+
|
119
|
+
const templateSource = apply(url('./files'), [
|
120
|
+
template({
|
121
|
+
project: humanize(project)
|
122
|
+
}),
|
123
|
+
move(rootPath)
|
124
|
+
]);
|
125
|
+
|
126
|
+
rules.push(mergeWith(templateSource));
|
127
|
+
|
128
|
+
sampleViewOptions.forEach((viewOptions) => {
|
129
|
+
rules.push(addViewToRouting({ name: viewOptions.name, project, module: 'app-routing' }));
|
130
|
+
rules.push(addImportsToRoutingModule(true, routingPath, viewOptions));
|
131
|
+
});
|
132
|
+
|
133
|
+
devextremeOptions.forEach((moduleOptions) => {
|
134
|
+
rules.push(addImportsToRoutingModule(false, routingPath, moduleOptions));
|
135
|
+
});
|
136
|
+
|
137
|
+
rules.push(addDefaultNavigation(rootPath));
|
138
|
+
|
139
|
+
return chain(rules);
|
140
|
+
};
|
141
|
+
}
|
@@ -1,9 +1,10 @@
|
|
1
1
|
"use strict";
|
2
2
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
3
4
|
return new (P || (P = Promise))(function (resolve, reject) {
|
4
5
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
5
6
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
6
|
-
function step(result) { result.done ? resolve(result.value) :
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
7
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
8
9
|
});
|
9
10
|
};
|
@@ -32,11 +33,11 @@ describe('sample views', () => {
|
|
32
33
|
const angularSchematicsCollection = require.resolve('../../node_modules/@schematics/angular/collection.json');
|
33
34
|
const schematicRunner = new testing_1.SchematicTestRunner('@schematics/angular', angularSchematicsCollection);
|
34
35
|
let appTree;
|
35
|
-
beforeEach(() => __awaiter(
|
36
|
+
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
36
37
|
appTree = yield schematicRunner.runSchematicAsync('workspace', workspaceOptions).toPromise();
|
37
38
|
appTree = yield schematicRunner.runSchematicAsync('application', appOptions, appTree).toPromise();
|
38
39
|
}));
|
39
|
-
it('should add sample views', () => __awaiter(
|
40
|
+
it('should add sample views', () => __awaiter(void 0, void 0, void 0, function* () {
|
40
41
|
const runner = new testing_1.SchematicTestRunner('schematics', collectionPath);
|
41
42
|
let tree = yield runner.runSchematicAsync('add-layout', { layout: 'side-nav-outer-toolbar' }, appTree).toPromise();
|
42
43
|
tree = yield runner.runSchematicAsync('add-sample-views', sampleViewsOptions, tree).toPromise();
|
@@ -44,7 +45,7 @@ describe('sample views', () => {
|
|
44
45
|
expect(moduleContent).toMatch(/component: HomeComponent/);
|
45
46
|
expect(moduleContent).toMatch(/path: 'home'/);
|
46
47
|
expect(moduleContent).toMatch(/import { HomeComponent } from /);
|
47
|
-
expect(moduleContent).toMatch(/declarations
|
48
|
+
expect(moduleContent).toMatch(/declarations:\s\[\n*\s*HomeComponent/);
|
48
49
|
const navigationContent = tree.readContent('/src/app/app-navigation.ts');
|
49
50
|
expect(navigationContent).toMatch(/text: 'Home'/);
|
50
51
|
expect(navigationContent).toContain(`export const navigation = [
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index_spec.js","sourceRoot":"","sources":["index_spec.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"index_spec.js","sourceRoot":"","sources":["index_spec.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,gEAAuF;AAEvF,6BAA6B;AAE7B,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC;AAElE,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,MAAM,UAAU,GAAQ;QACtB,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,EAAE;QACf,WAAW,EAAE,KAAK;QAClB,cAAc,EAAE,KAAK;QACrB,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,KAAK;QACZ,SAAS,EAAE,KAAK;QAChB,eAAe,EAAE,KAAK;KACvB,CAAC;IAEF,MAAM,gBAAgB,GAAqB;QACzC,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,OAAO;KACjB,CAAC;IAEF,MAAM,kBAAkB,GAAQ;QAC9B,OAAO,EAAE,SAAS;KACnB,CAAC;IAEF,MAAM,2BAA2B,GAAG,OAAO,CAAC,OAAO,CAAC,wDAAwD,CAAC,CAAC;IAC9G,MAAM,eAAe,GAAG,IAAI,6BAAmB,CAAC,qBAAqB,EAAE,2BAA2B,CAAC,CAAC;IACpG,IAAI,OAAqB,CAAC;IAE1B,UAAU,CAAC,GAAS,EAAE;QACpB,OAAO,GAAI,MAAM,eAAe,CAAC,iBAAiB,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC,SAAS,EAAE,CAAC;QAC9F,OAAO,GAAG,MAAM,eAAe,CAAC,iBAAiB,CAAC,aAAa,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC;IACpG,CAAC,CAAA,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,GAAS,EAAE;QACvC,MAAM,MAAM,GAAG,IAAI,6BAAmB,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;QACrE,IAAI,IAAI,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,wBAAwB,EAAE,EAAE,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC;QACnH,IAAI,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,kBAAkB,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;QAEhG,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC,gCAAgC,CAAC,CAAC;QAEzE,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;QAC1D,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAE9C,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC;QAChE,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC;QAEtE,MAAM,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,4BAA4B,CAAC,CAAC;QACzE,MAAM,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAClD,MAAM,CAAC,iBAAiB,CAAC,CAAC,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;GAoBrC,CAAC,CAAC;IACH,CAAC,CAAA,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|