Skip to content

Commit 313348e

Browse files
committed
fix(material/schematics): support standalone projects in dashboard schematic
Updates the `ng generate dashboard` schematic to support standalone projects. (cherry picked from commit 5bfbfad)
1 parent f8fad4f commit 313348e

File tree

5 files changed

+76
-18
lines changed

5 files changed

+76
-18
lines changed

src/material/schematics/ng-generate/dashboard/files/__path__/__name@dasherize@if-flat__/__name@dasherize__.component.spec.ts.template

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import { LayoutModule } from '@angular/cdk/layout';
2-
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
31
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
2+
import { NoopAnimationsModule } from '@angular/platform-browser/animations';<% if(!standalone) { %>
43
import { MatButtonModule } from '@angular/material/button';
54
import { MatCardModule } from '@angular/material/card';
65
import { MatGridListModule } from '@angular/material/grid-list';
76
import { MatIconModule } from '@angular/material/icon';
8-
import { MatMenuModule } from '@angular/material/menu';
7+
import { MatMenuModule } from '@angular/material/menu';<% } %>
98

109
import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';
1110

@@ -14,17 +13,17 @@ describe('<%= classify(name) %>Component', () => {
1413
let fixture: ComponentFixture<<%= classify(name) %>Component>;
1514

1615
beforeEach(waitForAsync(() => {
17-
TestBed.configureTestingModule({
16+
TestBed.configureTestingModule({<% if(standalone) { %>
17+
imports: [NoopAnimationsModule]<% } else { %>
1818
declarations: [<%= classify(name) %>Component],
1919
imports: [
2020
NoopAnimationsModule,
21-
LayoutModule,
2221
MatButtonModule,
2322
MatCardModule,
2423
MatGridListModule,
2524
MatIconModule,
2625
MatMenuModule,
27-
]
26+
]<% } %>
2827
}).compileComponents();
2928
}));
3029

src/material/schematics/ng-generate/dashboard/files/__path__/__name@dasherize@if-flat__/__name@dasherize__.component.ts.template

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
import { Component<% if(!!viewEncapsulation) { %>, ViewEncapsulation<% }%><% if(changeDetection !== 'Default') { %>, ChangeDetectionStrategy<% }%> } from '@angular/core';
2-
import { map } from 'rxjs/operators';
1+
import { Component, inject<% if(!!viewEncapsulation) { %>, ViewEncapsulation<% }%><% if(changeDetection !== 'Default') { %>, ChangeDetectionStrategy<% }%> } from '@angular/core';
32
import { Breakpoints, BreakpointObserver } from '@angular/cdk/layout';
3+
import { map } from 'rxjs/operators';<% if(standalone) { %>
4+
import { MatGridListModule } from '@angular/material/grid-list';
5+
import { MatMenuModule } from '@angular/material/menu';
6+
import { MatIconModule } from '@angular/material/icon';
7+
import { MatButtonModule } from '@angular/material/button';
8+
import { MatCardModule } from '@angular/material/card';<% } %>
49

510
@Component({
611
selector: '<%= selector %>',<% if(inlineTemplate) { %>
@@ -13,9 +18,19 @@ import { Breakpoints, BreakpointObserver } from '@angular/cdk/layout';
1318
`]<% } else { %>
1419
styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>']<% } %><% if(!!viewEncapsulation) { %>,
1520
encapsulation: ViewEncapsulation.<%= viewEncapsulation %><% } if (changeDetection !== 'Default') { %>,
16-
changeDetection: ChangeDetectionStrategy.<%= changeDetection %><% } %>
21+
changeDetection: ChangeDetectionStrategy.<%= changeDetection %><% } %><% if(standalone) { %>,
22+
standalone: true,
23+
imports: [
24+
MatGridListModule,
25+
MatMenuModule,
26+
MatIconModule,
27+
MatButtonModule,
28+
MatCardModule
29+
]<% } %>
1730
})
1831
export class <%= classify(name) %>Component {
32+
private breakpointObserver = inject(BreakpointObserver);
33+
1934
/** Based on the screen size, switch from standard to one column per row */
2035
cards = this.breakpointObserver.observe(Breakpoints.Handset).pipe(
2136
map(({ matches }) => {
@@ -36,6 +51,4 @@ export class <%= classify(name) %>Component {
3651
];
3752
})
3853
);
39-
40-
constructor(private breakpointObserver: BreakpointObserver) {}
4154
}

src/material/schematics/ng-generate/dashboard/index.spec.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,44 @@ describe('material-dashboard-schematic', () => {
5858
).toBeRejectedWithError(/required property 'name'/);
5959
});
6060

61+
describe('standalone option', () => {
62+
it('should generate a standalone component', async () => {
63+
const app = await createTestApp(runner);
64+
const tree = await runner.runSchematic('dashboard', {...baseOptions, standalone: true}, app);
65+
const module = getFileContent(tree, '/projects/material/src/app/app.module.ts');
66+
const component = getFileContent(tree, '/projects/material/src/app/foo/foo.component.ts');
67+
const requiredModules = [
68+
'MatButtonModule',
69+
'MatCardModule',
70+
'MatGridListModule',
71+
'MatIconModule',
72+
'MatMenuModule',
73+
];
74+
75+
requiredModules.forEach(name => {
76+
expect(module).withContext('Module should not import dependencies').not.toContain(name);
77+
expect(component).withContext('Component should import dependencies').toContain(name);
78+
});
79+
80+
expect(module).not.toContain('FooComponent');
81+
expect(component).toContain('standalone: true');
82+
expect(component).toContain('imports: [');
83+
});
84+
85+
it('should infer the standalone option from the project structure', async () => {
86+
const app = await createTestApp(runner, {standalone: true});
87+
const tree = await runner.runSchematic('dashboard', baseOptions, app);
88+
const componentContent = getFileContent(
89+
tree,
90+
'/projects/material/src/app/foo/foo.component.ts',
91+
);
92+
93+
expect(tree.exists('/projects/material/src/app/app.module.ts')).toBe(false);
94+
expect(componentContent).toContain('standalone: true');
95+
expect(componentContent).toContain('imports: [');
96+
});
97+
});
98+
6199
describe('style option', () => {
62100
it('should respect the option value', async () => {
63101
const tree = await runner.runSchematic(

src/material/schematics/ng-generate/dashboard/index.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
addModuleImportToModule,
1212
buildComponent,
1313
findModuleFromOptions,
14+
isStandaloneSchematic,
1415
} from '@angular/cdk/schematics';
1516
import {Schema} from './schema';
1617

@@ -38,12 +39,15 @@ export default function (options: Schema): Rule {
3839
*/
3940
function addNavModulesToModule(options: Schema) {
4041
return async (host: Tree) => {
41-
const modulePath = (await findModuleFromOptions(host, options))!;
42-
addModuleImportToModule(host, modulePath, 'MatGridListModule', '@angular/material/grid-list');
43-
addModuleImportToModule(host, modulePath, 'MatCardModule', '@angular/material/card');
44-
addModuleImportToModule(host, modulePath, 'MatMenuModule', '@angular/material/menu');
45-
addModuleImportToModule(host, modulePath, 'MatIconModule', '@angular/material/icon');
46-
addModuleImportToModule(host, modulePath, 'MatButtonModule', '@angular/material/button');
47-
addModuleImportToModule(host, modulePath, 'LayoutModule', '@angular/cdk/layout');
42+
const isStandalone = await isStandaloneSchematic(host, options);
43+
44+
if (!isStandalone) {
45+
const modulePath = (await findModuleFromOptions(host, options))!;
46+
addModuleImportToModule(host, modulePath, 'MatGridListModule', '@angular/material/grid-list');
47+
addModuleImportToModule(host, modulePath, 'MatCardModule', '@angular/material/card');
48+
addModuleImportToModule(host, modulePath, 'MatMenuModule', '@angular/material/menu');
49+
addModuleImportToModule(host, modulePath, 'MatIconModule', '@angular/material/icon');
50+
addModuleImportToModule(host, modulePath, 'MatButtonModule', '@angular/material/button');
51+
}
4852
};
4953
}

src/material/schematics/ng-generate/dashboard/schema.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@
3939
"type": "boolean",
4040
"alias": "t"
4141
},
42+
"standalone": {
43+
"description": "Whether the generated component is standalone.",
44+
"type": "boolean"
45+
},
4246
"viewEncapsulation": {
4347
"description": "Specifies the view encapsulation strategy.",
4448
"enum": ["Emulated", "None"],

0 commit comments

Comments
 (0)