mirror of https://github.com/abpframework/abp.git
committed by
GitHub
9 changed files with 485 additions and 67 deletions
|
After Width: | Height: | Size: 14 KiB |
@ -0,0 +1,85 @@ |
|||||
|
import { Rule, SchematicContext, SchematicsException, Tree } 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 { ChangeThemeOptions } from './model'; |
||||
|
import { ThemeOptionsEnum } from './theme-options.enum'; |
||||
|
|
||||
|
export default function (_options: ChangeThemeOptions): Rule { |
||||
|
return async (_: Tree, __: SchematicContext) => { |
||||
|
const targetThemeName = _options.name; |
||||
|
const selectedProject = _options.targetProject; |
||||
|
if (!targetThemeName) { |
||||
|
throw new SchematicsException('The theme name does not selected'); |
||||
|
} |
||||
|
|
||||
|
return updateWorkspace(storedWorkspace => { |
||||
|
updateProjectStyle(selectedProject, storedWorkspace, targetThemeName); |
||||
|
}); |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
function updateProjectStyle( |
||||
|
projectName: string, |
||||
|
workspace: WorkspaceDefinition, |
||||
|
targetThemeName: ThemeOptionsEnum, |
||||
|
) { |
||||
|
const project = workspace.projects.get(projectName); |
||||
|
|
||||
|
if (!project) { |
||||
|
throw new SchematicsException('The target project does not selected'); |
||||
|
} |
||||
|
|
||||
|
const isProjectLibrary = isLibrary(project); |
||||
|
if (isProjectLibrary) { |
||||
|
throw new SchematicsException('The library project does not supported'); |
||||
|
} |
||||
|
|
||||
|
const targetOption = getProjectTargetOptions(project, 'build'); |
||||
|
const styles = targetOption.styles as (string | { input: string })[]; |
||||
|
|
||||
|
const sanitizedStyles = removeThemeBasedStyles(styles); |
||||
|
|
||||
|
const newStyles = styleMap.get(targetThemeName); |
||||
|
if (!newStyles) { |
||||
|
throw new SchematicsException('The theme does not found'); |
||||
|
} |
||||
|
targetOption.styles = [...newStyles, ...sanitizedStyles] as JsonArray; |
||||
|
} |
||||
|
|
||||
|
export function getProjectTargetOptions( |
||||
|
project: ProjectDefinition, |
||||
|
buildTarget: string, |
||||
|
): Record<string, JsonValue | undefined> { |
||||
|
const options = project.targets?.get(buildTarget)?.options; |
||||
|
|
||||
|
if (!options) { |
||||
|
throw new SchematicsException( |
||||
|
`Cannot determine project target configuration for: ${buildTarget}.`, |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
return options; |
||||
|
} |
||||
|
|
||||
|
export function removeThemeBasedStyles(styles: (string | object)[]) { |
||||
|
return styles.filter(s => !allStyles.some(x => styleCompareFn(s, x))); |
||||
|
} |
||||
|
|
||||
|
export const styleCompareFn = (item1: string | object, item2: string | object) => { |
||||
|
const type1 = typeof item1; |
||||
|
const type2 = typeof item1; |
||||
|
|
||||
|
if (type1 !== type2) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (type1 === 'string') { |
||||
|
return item1 === item2; |
||||
|
} |
||||
|
const o1 = item1 as { bundleName?: string }; |
||||
|
const o2 = item2 as { bundleName?: string }; |
||||
|
|
||||
|
return o1.bundleName && o2.bundleName && o1.bundleName == o2.bundleName; |
||||
|
}; |
||||
@ -0,0 +1,6 @@ |
|||||
|
import { ThemeOptionsEnum } from './theme-options.enum'; |
||||
|
|
||||
|
export type ChangeThemeOptions = { |
||||
|
name: ThemeOptionsEnum; |
||||
|
targetProject: string; |
||||
|
}; |
||||
@ -0,0 +1,37 @@ |
|||||
|
{ |
||||
|
"$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 |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"required": ["name"] |
||||
|
} |
||||
@ -0,0 +1,223 @@ |
|||||
|
import { ThemeOptionsEnum } from './theme-options.enum'; |
||||
|
|
||||
|
export type StyleDefinition = |
||||
|
| { |
||||
|
input: string; |
||||
|
inject: boolean; |
||||
|
bundleName: string; |
||||
|
} |
||||
|
| string; |
||||
|
|
||||
|
export const styleMap = new Map<ThemeOptionsEnum, StyleDefinition[]>(); |
||||
|
|
||||
|
styleMap.set(ThemeOptionsEnum.Basic, [ |
||||
|
{ |
||||
|
input: 'node_modules/bootstrap/dist/css/bootstrap.rtl.min.css', |
||||
|
inject: false, |
||||
|
bundleName: 'bootstrap-rtl.min', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/bootstrap/dist/css/bootstrap.min.css', |
||||
|
inject: true, |
||||
|
bundleName: 'bootstrap-ltr.min', |
||||
|
}, |
||||
|
]); |
||||
|
|
||||
|
styleMap.set(ThemeOptionsEnum.Lepton, [ |
||||
|
{ |
||||
|
input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton1.min.css', |
||||
|
inject: false, |
||||
|
bundleName: 'lepton1', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton2.min.css', |
||||
|
inject: false, |
||||
|
bundleName: 'lepton2', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton3.min.css', |
||||
|
inject: false, |
||||
|
bundleName: 'lepton3', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton4.min.css', |
||||
|
inject: false, |
||||
|
bundleName: 'lepton4', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton5.min.css', |
||||
|
inject: false, |
||||
|
bundleName: 'lepton5', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton6.min.css', |
||||
|
inject: false, |
||||
|
bundleName: 'lepton6', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton1.rtl.min.css', |
||||
|
inject: false, |
||||
|
bundleName: 'lepton1.rtl', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton2.rtl.min.css', |
||||
|
inject: false, |
||||
|
bundleName: 'lepton2.rtl', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton3.rtl.min.css', |
||||
|
inject: false, |
||||
|
bundleName: 'lepton3.rtl', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton4.rtl.min.css', |
||||
|
inject: false, |
||||
|
bundleName: 'lepton4.rtl', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton5.rtl.min.css', |
||||
|
inject: false, |
||||
|
bundleName: 'lepton5.rtl', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton6.rtl.min.css', |
||||
|
inject: false, |
||||
|
bundleName: 'lepton6.rtl', |
||||
|
}, |
||||
|
]); |
||||
|
styleMap.set(ThemeOptionsEnum.LeptonX, [ |
||||
|
{ |
||||
|
input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/dark.css', |
||||
|
inject: false, |
||||
|
bundleName: 'dark', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/light.css', |
||||
|
inject: false, |
||||
|
bundleName: 'light', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/dim.css', |
||||
|
inject: false, |
||||
|
bundleName: 'dim', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/bootstrap-dim.css', |
||||
|
inject: false, |
||||
|
bundleName: 'bootstrap-dim', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/bootstrap-dark.css', |
||||
|
inject: false, |
||||
|
bundleName: 'bootstrap-dark', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/bootstrap-light.css', |
||||
|
inject: false, |
||||
|
bundleName: 'bootstrap-light', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/ng-bundle.css', |
||||
|
inject: false, |
||||
|
bundleName: 'ng-bundle', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/side-menu/layout-bundle.css', |
||||
|
inject: false, |
||||
|
bundleName: 'layout-bundle', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volosoft/abp.ng.theme.lepton-x/assets/css/abp-bundle.css', |
||||
|
inject: false, |
||||
|
bundleName: 'abp-bundle', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/dark.rtl.css', |
||||
|
inject: false, |
||||
|
bundleName: 'dark.rtl', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/light.rtl.css', |
||||
|
inject: false, |
||||
|
bundleName: 'light.rtl', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/dim.rtl.css', |
||||
|
inject: false, |
||||
|
bundleName: 'dim.rtl', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/bootstrap-dim.rtl.css', |
||||
|
inject: false, |
||||
|
bundleName: 'bootstrap-dim.rtl', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/bootstrap-dark.rtl.css', |
||||
|
inject: false, |
||||
|
bundleName: 'bootstrap-dark.rtl', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/bootstrap-light.rtl.css', |
||||
|
inject: false, |
||||
|
bundleName: 'bootstrap-light.rtl', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/ng-bundle.rtl.css', |
||||
|
inject: false, |
||||
|
bundleName: 'ng-bundle.rtl', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/side-menu/layout-bundle.rtl.css', |
||||
|
inject: false, |
||||
|
bundleName: 'layout-bundle.rtl', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volosoft/abp.ng.theme.lepton-x/assets/css/abp-bundle.rtl.css', |
||||
|
inject: false, |
||||
|
bundleName: 'abp-bundle.rtl', |
||||
|
}, |
||||
|
]); |
||||
|
styleMap.set(ThemeOptionsEnum.LeptonXLite, [ |
||||
|
{ |
||||
|
input: 'node_modules/@volo/ngx-lepton-x.lite/assets/css/bootstrap-dim.css', |
||||
|
inject: false, |
||||
|
bundleName: 'bootstrap-dim', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volo/ngx-lepton-x.lite/assets/css/ng-bundle.css', |
||||
|
inject: false, |
||||
|
bundleName: 'ng-bundle', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volo/ngx-lepton-x.lite/assets/css/side-menu/layout-bundle.css', |
||||
|
inject: false, |
||||
|
bundleName: 'layout-bundle', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@abp/ng.theme.lepton-x/assets/css/abp-bundle.css', |
||||
|
inject: false, |
||||
|
bundleName: 'abp-bundle', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volo/ngx-lepton-x.lite/assets/css/bootstrap-dim.rtl.css', |
||||
|
inject: false, |
||||
|
bundleName: 'bootstrap-dim.rtl', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volo/ngx-lepton-x.lite/assets/css/ng-bundle.rtl.css', |
||||
|
inject: false, |
||||
|
bundleName: 'ng-bundle.rtl', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@volo/ngx-lepton-x.lite/assets/css/side-menu/layout-bundle.rtl.css', |
||||
|
inject: false, |
||||
|
bundleName: 'layout-bundle.rtl', |
||||
|
}, |
||||
|
{ |
||||
|
input: 'node_modules/@abp/ng.theme.lepton-x/assets/css/abp-bundle.rtl.css', |
||||
|
inject: false, |
||||
|
bundleName: 'abp-bundle.rtl', |
||||
|
}, |
||||
|
]); |
||||
|
// 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], []); |
||||
@ -0,0 +1,8 @@ |
|||||
|
// this enum create by https://raw.githubusercontent.com/abpframework/abp/rel-6.0/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Theme.cs
|
||||
|
|
||||
|
export enum ThemeOptionsEnum { |
||||
|
Basic = 1, |
||||
|
Lepton = 2, |
||||
|
LeptonXLite = 3, |
||||
|
LeptonX = 4, |
||||
|
} |
||||
Loading…
Reference in new issue