Browse Source

Merge pull request #17711 from abpframework/auto-merge/rel-7-4/2200

Merge branch dev with rel-7.4
pull/17712/head
Berkan Sasmaz 3 years ago
committed by GitHub
parent
commit
adf6900d95
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Generators/JQuery/JQueryProxyScriptGenerator.cs
  2. 2
      npm/ng-packs/package.json
  3. 5
      npm/ng-packs/packages/generators/generators.json
  4. 20
      npm/ng-packs/packages/generators/src/generators/change-theme/generator.spec.ts
  5. 26
      npm/ng-packs/packages/generators/src/generators/change-theme/generator.ts
  6. 3
      npm/ng-packs/packages/generators/src/generators/change-theme/index.ts
  7. 5
      npm/ng-packs/packages/generators/src/generators/change-theme/schema.d.ts
  8. 41
      npm/ng-packs/packages/generators/src/generators/change-theme/schema.json
  9. 8
      npm/ng-packs/packages/generators/src/generators/change-theme/theme-options.enum.ts
  10. 4
      npm/ng-packs/packages/generators/src/index.ts
  11. 156
      npm/ng-packs/packages/schematics/src/commands/change-theme/index.ts
  12. 51
      npm/ng-packs/packages/schematics/src/commands/change-theme/style-map.ts
  13. 1
      npm/ng-packs/packages/schematics/src/utils/angular/ast-utils.ts

16
framework/src/Volo.Abp.Http/Volo/Abp/Http/ProxyScripting/Generators/JQuery/JQueryProxyScriptGenerator.cs

@ -114,7 +114,21 @@ public class JQueryProxyScriptGenerator : IProxyScriptGenerator, ITransientDepen
if (versionParam != null) if (versionParam != null)
{ {
var version = FindBestApiVersion(action); var version = FindBestApiVersion(action);
script.AppendLine($" var {ProxyScriptingJsFuncHelper.NormalizeJsVariableName(versionParam.Name)} = api_version ? api_version : '{version}';"); if (parameterList.Contains("api_version"))
{
script.AppendLine($" var {ProxyScriptingJsFuncHelper.NormalizeJsVariableName(versionParam.Name)} = api_version ? api_version : '{version}';");
}
else
{
var apiVersion = action.Parameters.FirstOrDefault(p =>
p.BindingSourceId.IsIn(ParameterBindingSources.ModelBinding, ParameterBindingSources.Query) &&
p.Name == "api-version");
if (apiVersion != null && parameterList.Contains(apiVersion.NameOnMethod))
{
var apiVersionVariable = ProxyScriptingJsFuncHelper.GetParamNameInJsFunc(apiVersion);
script.AppendLine($" {apiVersionVariable} = {apiVersionVariable} ? {apiVersionVariable} : '{version}';");
}
}
} }
script.AppendLine(" return abp.ajax($.extend(true, {"); script.AppendLine(" return abp.ajax($.extend(true, {");

2
npm/ng-packs/package.json

@ -34,7 +34,7 @@
"build:schematics": "cd scripts && yarn && yarn build:schematics && cd ..", "build:schematics": "cd scripts && yarn && yarn build:schematics && cd ..",
"dev:schematics": "tsc -p packages/schematics/tsconfig.json -w", "dev:schematics": "tsc -p packages/schematics/tsconfig.json -w",
"mock:schematics": "cd scripts/mock-schematic && yarn && yarn start", "mock:schematics": "cd scripts/mock-schematic && yarn && yarn start",
"debug:schematics": "./node_modules/.bin/ng g ./packages/schematics/src/collection.json:proxy-add --module __default --apiName __default --source __default --target __default --url https://localhost:44305 --serviceType application --entryPoint __default ", "debug:schematics": "./node_modules/.bin/nx g ./packages/schematics/src/collection.json:proxy-add --module identity --apiName __default --source __default --target __default --url https://localhost:44305 --serviceType application --entryPoint __default ",
"debug:schematics-dist": "./node_modules/.bin/ng g ./dist/packages/schematics/collection.json:proxy-add --module __default --apiName __default --source __default --target __default --url http://localhost:4300 --service-type application --entryPoint __default", "debug:schematics-dist": "./node_modules/.bin/ng g ./dist/packages/schematics/collection.json:proxy-add --module __default --apiName __default --source __default --target __default --url http://localhost:4300 --service-type application --entryPoint __default",
"ci": "yarn affected:lint && yarn affected:build && yarn affected:test", "ci": "yarn affected:lint && yarn affected:build && yarn affected:test",
"lerna": "lerna", "lerna": "lerna",

5
npm/ng-packs/packages/generators/generators.json

@ -9,6 +9,11 @@
"factory": "./src/generators/update-version/generator", "factory": "./src/generators/update-version/generator",
"schema": "./src/generators/update-version/schema.json", "schema": "./src/generators/update-version/schema.json",
"description": "update-version generator" "description": "update-version generator"
},
"change-theme": {
"factory": "./src/generators/change-theme/generator",
"schema": "./src/generators/change-theme/schema.json",
"description": "change-theme generator"
} }
} }
} }

20
npm/ng-packs/packages/generators/src/generators/change-theme/generator.spec.ts

@ -0,0 +1,20 @@
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { Tree, readProjectConfiguration } from '@nx/devkit';
import { changeThemeGenerator } from './generator';
import { ChangeThemeGeneratorSchema } from './schema';
describe('change-theme generator', () => {
let tree: Tree;
const options: ChangeThemeGeneratorSchema = { name: 'test' };
beforeEach(() => {
tree = createTreeWithEmptyWorkspace();
});
it('should run successfully', async () => {
await changeThemeGenerator(tree, options);
const config = readProjectConfiguration(tree, 'test');
expect(config).toBeDefined();
});
});

26
npm/ng-packs/packages/generators/src/generators/change-theme/generator.ts

@ -0,0 +1,26 @@
import { Tree } from '@nx/devkit';
import { wrapAngularDevkitSchematic } from '@nx/devkit/ngcli-adapter';
import { ChangeThemeGeneratorSchema } from './schema';
import { ThemeOptionsEnum } from './theme-options.enum';
export async function changeThemeGenerator(host: Tree, schema: ChangeThemeGeneratorSchema) {
const schematicPath = schema.localPath || '@abp/ng.schematics';
const runAngularLibrarySchematic = wrapAngularDevkitSchematic(
schema.localPath ? `${host.root}${schematicPath}` : schematicPath,
'change-theme',
);
await runAngularLibrarySchematic(host, {
...schema,
});
return () => {
const destTheme = Object.values(ThemeOptionsEnum).find(
(theme, index) => index + 1 === schema.name,
);
console.log(`✅️ Switched to Theme ${destTheme}`);
};
}
export default changeThemeGenerator;

3
npm/ng-packs/packages/generators/src/generators/change-theme/index.ts

@ -0,0 +1,3 @@
export * from './theme-options.enum';
export * from './schema';
export * from './generator';

5
npm/ng-packs/packages/generators/src/generators/change-theme/schema.d.ts

@ -0,0 +1,5 @@
export interface ChangeThemeGeneratorSchema {
name: number;
targetOption: string;
localPath?: string;
}

41
npm/ng-packs/packages/generators/src/generators/change-theme/schema.json

@ -0,0 +1,41 @@
{
"$schema": "http://json-schema.org/schema",
"$id": "SchematicsABPThemeChanger",
"title": "ABP Theme Style Generator API Schema",
"type": "object",
"properties": {
"name": {
"description": "The name of theme will change.",
"type": "number",
"$default": {
"$source": "argv",
"index": 0
},
"enum": [1, 2, 3, 4],
"x-prompt": {
"message": "Which theme would you like to use?",
"type": "list",
"items": [
{ "value": 1, "label": "Basic" },
{ "value": 2, "label": "Lepton" },
{ "value": 3, "label": "LeptonXLite" },
{ "value": 4, "label": "LeptonX" }
]
}
},
"targetProject": {
"description": "The name of the project will change the style.The project type must be 'application'",
"type": "string",
"x-prompt": "Please enter the project name",
"$default": {
"$source": "argv",
"index": 1
}
},
"localPath": {
"description": "If set value schematics will work on given path",
"type": "string"
}
},
"required": ["name", "targetProject"]
}

8
npm/ng-packs/packages/generators/src/generators/change-theme/theme-options.enum.ts

@ -0,0 +1,8 @@
// this enum create by https://raw.githubusercontent.com/abpframework/abp/rel-7.4/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Theme.cs
export enum ThemeOptionsEnum {
Basic = 1,
Lepton = 2,
LeptonXLite = 3,
LeptonX = 4,
}

4
npm/ng-packs/packages/generators/src/index.ts

@ -1 +1,3 @@
export * from './generators/generate-proxy' export * from './generators/change-theme';
export * from './generators/generate-proxy';
export * from './generators/update-version';

156
npm/ng-packs/packages/schematics/src/commands/change-theme/index.ts

@ -1,10 +1,17 @@
import { Rule, SchematicsException } from '@angular-devkit/schematics';
import { isLibrary, updateWorkspace, WorkspaceDefinition } from '../../utils';
import { allStyles, styleMap } from './style-map';
import { ProjectDefinition } from '@angular-devkit/core/src/workspace';
import { JsonArray, JsonValue } from '@angular-devkit/core'; import { JsonArray, JsonValue } from '@angular-devkit/core';
import { Rule, SchematicsException, Tree, chain } from '@angular-devkit/schematics';
import { ProjectDefinition } from '@angular-devkit/core/src/workspace';
import * as ts from 'typescript';
import { allStyles, importMap, styleMap } from './style-map';
import { ChangeThemeOptions } from './model'; import { ChangeThemeOptions } from './model';
import { Change, InsertChange, isLibrary, updateWorkspace, WorkspaceDefinition } from '../../utils';
import { ThemeOptionsEnum } from './theme-options.enum'; import { ThemeOptionsEnum } from './theme-options.enum';
import {
addImportToModule,
findNodes,
getDecoratorMetadata,
getMetadataField,
} from '../../utils/angular/ast-utils';
export default function (_options: ChangeThemeOptions): Rule { export default function (_options: ChangeThemeOptions): Rule {
return async () => { return async () => {
@ -14,9 +21,12 @@ export default function (_options: ChangeThemeOptions): Rule {
throw new SchematicsException('The theme name does not selected'); throw new SchematicsException('The theme name does not selected');
} }
return updateWorkspace(storedWorkspace => { return chain([
updateProjectStyle(selectedProject, storedWorkspace, targetThemeName); updateWorkspace(storedWorkspace => {
}); updateProjectStyle(selectedProject, storedWorkspace, targetThemeName);
}),
updateAppModule(selectedProject, targetThemeName),
]);
}; };
} }
@ -48,6 +58,138 @@ function updateProjectStyle(
targetOption.styles = [...newStyles, ...sanitizedStyles] as JsonArray; targetOption.styles = [...newStyles, ...sanitizedStyles] as JsonArray;
} }
function updateAppModule(selectedProject: string, targetThemeName: ThemeOptionsEnum): Rule {
return (host: Tree) => {
const angularJSON = host.read('angular.json');
if (!angularJSON) {
throw new SchematicsException('The angular.json does not found');
}
const workspace = JSON.parse(angularJSON.toString());
const project = workspace.projects[selectedProject];
if (!project || !project.sourceRoot) {
throw new SchematicsException('The target project does not found');
}
const appModulePath = project.sourceRoot + '/app/app.module.ts';
return chain([
removeImportPath(appModulePath, targetThemeName),
removeImportFromNgModuleMetadata(appModulePath, targetThemeName),
insertImports(appModulePath, targetThemeName),
]);
};
}
function removeImportPath(appModulePath: string, selectedTheme: ThemeOptionsEnum): Rule {
return (host: Tree) => {
const recorder = host.beginUpdate(appModulePath);
const sourceText = host.read(appModulePath)?.toString('utf-8');
const source = ts.createSourceFile(
appModulePath,
sourceText!,
ts.ScriptTarget.Latest,
true,
ts.ScriptKind.TS,
);
const impMap = Array.from(importMap.values())
.filter(f => f !== importMap.get(selectedTheme))
.reduce((acc, val) => [...acc, ...val], []);
const nodes = findNodes(source, ts.isImportDeclaration);
const filteredNodes = nodes.filter(n => impMap.some(f => n.getFullText().match(f.path)));
if (!filteredNodes || filteredNodes.length < 1) {
return;
}
filteredNodes.map(importPath =>
recorder.remove(importPath.getStart(), importPath.getWidth() + 1),
);
host.commitUpdate(recorder);
return host;
};
}
function removeImportFromNgModuleMetadata(
appModulePath: string,
selectedTheme: ThemeOptionsEnum,
): Rule {
return (host: Tree) => {
const recorder = host.beginUpdate(appModulePath);
const sourceText = host.read(appModulePath)?.toString('utf-8');
const source = ts.createSourceFile(
appModulePath,
sourceText!,
ts.ScriptTarget.Latest,
true,
ts.ScriptKind.TS,
);
const impMap = Array.from(importMap.values())
.filter(f => f !== importMap.get(selectedTheme))
.reduce((acc, val) => [...acc, ...val], []);
const node = getDecoratorMetadata(source, 'NgModule', '@angular/core')[0] || {};
if (!node) {
throw new SchematicsException('The app module does not found');
}
const matchingProperties = getMetadataField(node as ts.ObjectLiteralExpression, 'imports');
const assignment = matchingProperties[0] as ts.PropertyAssignment;
const assignmentInit = assignment.initializer as ts.ArrayLiteralExpression;
const elements = assignmentInit.elements;
if (!elements || elements.length < 1) {
return;
}
const filteredElements = elements.filter(f =>
impMap.some(s => f.getText().match(s.importName)),
);
if (!filteredElements || filteredElements.length < 1) {
return;
}
filteredElements.map(willRemoveModule =>
recorder.remove(willRemoveModule.getStart(), willRemoveModule.getWidth() + 1),
);
host.commitUpdate(recorder);
return host;
};
}
function insertImports(appModulePath: string, selectedTheme: ThemeOptionsEnum): Rule {
return (host: Tree) => {
const recorder = host.beginUpdate(appModulePath);
const sourceText = host.read(appModulePath)?.toString('utf-8');
const source = ts.createSourceFile(
appModulePath,
sourceText!,
ts.ScriptTarget.Latest,
true,
ts.ScriptKind.TS,
);
const selected = importMap.get(selectedTheme);
const changes: Change[] = [];
selected!.map(({ importName, path }) =>
changes.push(...addImportToModule(source, appModulePath, importName, path)),
);
if (changes.length > 0) {
for (const change of changes) {
if (change instanceof InsertChange) {
recorder.insertLeft(change.pos, change.toAdd);
}
}
}
host.commitUpdate(recorder);
return host;
};
}
export function getProjectTargetOptions( export function getProjectTargetOptions(
project: ProjectDefinition, project: ProjectDefinition,
buildTarget: string, buildTarget: string,

51
npm/ng-packs/packages/schematics/src/commands/change-theme/style-map.ts

@ -8,6 +8,11 @@ export type StyleDefinition =
} }
| string; | string;
export type ImportDefinition = {
path: string;
importName: string;
};
export const styleMap = new Map<ThemeOptionsEnum, StyleDefinition[]>(); export const styleMap = new Map<ThemeOptionsEnum, StyleDefinition[]>();
styleMap.set(ThemeOptionsEnum.Basic, [ styleMap.set(ThemeOptionsEnum.Basic, [
@ -241,3 +246,49 @@ styleMap.set(ThemeOptionsEnum.LeptonXLite, [
]); ]);
// the code written by Github co-pilot. thank go-pilot. You are the best sidekick. // the code written by Github co-pilot. thank go-pilot. You are the best sidekick.
export const allStyles = Array.from(styleMap.values()).reduce((acc, val) => [...acc, ...val], []); export const allStyles = Array.from(styleMap.values()).reduce((acc, val) => [...acc, ...val], []);
export const importMap = new Map<ThemeOptionsEnum, ImportDefinition[]>();
importMap.set(ThemeOptionsEnum.Basic, [
{
path: '@abp/ng.theme.basic',
importName: 'ThemeBasicModule.forRoot()',
},
]);
importMap.set(ThemeOptionsEnum.Lepton, [
{
path: '@volo/abp.ng.theme.lepton',
importName: 'ThemeLeptonModule.forRoot()',
},
]);
importMap.set(ThemeOptionsEnum.LeptonXLite, [
{
path: '@abp/ng.theme.lepton-x',
importName: 'ThemeLeptonXModule.forRoot()',
},
{
path: '@abp/ng.theme.lepton-x/layouts',
importName: 'SideMenuLayoutModule.forRoot()',
},
{
path: '@abp/ng.theme.lepton-x/account',
importName: 'AccountLayoutModule.forRoot()',
},
]);
importMap.set(ThemeOptionsEnum.LeptonX, [
{
path: '@volosoft/abp.ng.theme.lepton-x',
importName: 'ThemeLeptonXModule.forRoot()',
},
{
path: '@volosoft/abp.ng.theme.lepton-x/layouts',
importName: 'SideMenuLayoutModule.forRoot()',
},
{
path: '@volosoft/abp.ng.theme.lepton-x/account',
importName: 'AccountLayoutModule.forRoot()',
},
]);

1
npm/ng-packs/packages/schematics/src/utils/angular/ast-utils.ts

@ -446,7 +446,6 @@ export function addSymbolToNgModuleMetadata(
toInsert = `, ${symbolName}`; toInsert = `, ${symbolName}`;
} }
} }
if (importPath !== null) { if (importPath !== null) {
return [ return [
new InsertChange(ngModulePath, position, toInsert), new InsertChange(ngModulePath, position, toInsert),

Loading…
Cancel
Save