Browse Source

Merge pull request #15237 from abpframework/auto-merge/rel-7-0/1618

Merge branch dev with rel-7.0
pull/15258/head
liangshiwei 4 years ago
committed by GitHub
parent
commit
052e511bec
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 27
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs
  2. 44
      modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/Components/FeatureManagementModal.razor
  3. 3
      modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/SettingManagementFeatureDefinitionProvider.cs
  4. 2
      modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs
  5. 2
      npm/ng-packs/packages/identity/src/lib/defaults/default-users-form-props.ts
  6. 2
      npm/ng-packs/packages/schematics/src/commands/create-lib/files-package/__libraryName@kebab__/karma.conf.js.template
  7. 109
      npm/ng-packs/packages/schematics/src/commands/create-lib/index.ts
  8. 15
      npm/ng-packs/packages/schematics/src/commands/create-lib/schema.json
  9. 2
      npm/ng-packs/packages/tenant-management/src/lib/defaults/default-tenants-form-props.ts
  10. 15
      npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.html
  11. 7
      npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.ts
  12. 3
      npm/ng-packs/packages/theme-shared/extensions/src/lib/enums/components.ts
  13. 1
      npm/ng-packs/packages/theme-shared/extensions/src/lib/enums/props.enum.ts
  14. 1
      npm/ng-packs/packages/theme-shared/extensions/src/public-api.ts
  15. 1
      npm/ng-packs/packages/theme-shared/src/lib/components/index.ts
  16. 19
      npm/ng-packs/packages/theme-shared/src/lib/components/password/password.component.html
  17. 28
      npm/ng-packs/packages/theme-shared/src/lib/components/password/password.component.ts
  18. 6
      npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts

27
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/App/AppTemplateBase.cs

@ -132,11 +132,11 @@ public abstract class AppTemplateBase : TemplateInfo
case UiFramework.BlazorServer: case UiFramework.BlazorServer:
ConfigureWithBlazorServerUi(context, steps); ConfigureWithBlazorServerUi(context, steps);
break; break;
case UiFramework.MauiBlazor: case UiFramework.MauiBlazor:
ConfigureWithMauiBlazorUi(context, steps); ConfigureWithMauiBlazorUi(context, steps);
break; break;
case UiFramework.Mvc: case UiFramework.Mvc:
case UiFramework.NotSpecified: case UiFramework.NotSpecified:
ConfigureWithMvcUi(context, steps); ConfigureWithMvcUi(context, steps);
@ -213,14 +213,14 @@ public abstract class AppTemplateBase : TemplateInfo
{ {
steps.Add(new ChangeThemeStyleStep()); steps.Add(new ChangeThemeStyleStep());
} }
RemoveThemeLogoFolders(context, steps); RemoveThemeLogoFolders(context, steps);
if (IsDefaultThemeForTemplate(context.BuildArgs.Theme.Value)) if (IsDefaultThemeForTemplate(context.BuildArgs.Theme.Value))
{ {
return; return;
} }
steps.Add(new ChangeThemeStep()); steps.Add(new ChangeThemeStep());
RemoveLeptonXThemePackagesFromPackageJsonFiles(steps, isProTemplate: IsPro(), uiFramework: context.BuildArgs.UiFramework); RemoveLeptonXThemePackagesFromPackageJsonFiles(steps, isProTemplate: IsPro(), uiFramework: context.BuildArgs.UiFramework);
} }
@ -240,15 +240,15 @@ public abstract class AppTemplateBase : TemplateInfo
private static bool IsDefaultThemeForTemplate(Theme theme) private static bool IsDefaultThemeForTemplate(Theme theme)
{ {
var defaultThemesForTemplates = new[] var defaultThemesForTemplates = new[]
{ {
AppTemplate.DefaultTheme, AppProTemplate.DefaultTheme, AppTemplate.DefaultTheme, AppProTemplate.DefaultTheme,
AppNoLayersTemplate.DefaultTheme, AppNoLayersProTemplate.DefaultTheme AppNoLayersTemplate.DefaultTheme, AppNoLayersProTemplate.DefaultTheme
}; };
return defaultThemesForTemplates.Any(defaultTheme => defaultTheme == theme); return defaultThemesForTemplates.Any(defaultTheme => defaultTheme == theme);
} }
private static void RemoveLeptonXThemePackagesFromPackageJsonFiles(List<ProjectBuildPipelineStep> steps, bool isProTemplate, UiFramework uiFramework) private static void RemoveLeptonXThemePackagesFromPackageJsonFiles(List<ProjectBuildPipelineStep> steps, bool isProTemplate, UiFramework uiFramework)
{ {
var mvcUiPackageName = isProTemplate ? "@volo/abp.aspnetcore.mvc.ui.theme.leptonx" : "@abp/aspnetcore.mvc.ui.theme.leptonxlite"; var mvcUiPackageName = isProTemplate ? "@volo/abp.aspnetcore.mvc.ui.theme.leptonx" : "@abp/aspnetcore.mvc.ui.theme.leptonxlite";
@ -263,7 +263,7 @@ public abstract class AppTemplateBase : TemplateInfo
"/MyCompanyName.MyProjectName.Host/package.json", "/MyCompanyName.MyProjectName.Host/package.json",
"/MyCompanyName.MyProjectName.Host.Mongo/package.json" "/MyCompanyName.MyProjectName.Host.Mongo/package.json"
}; };
foreach (var packageJsonFilePath in packageJsonFilePaths) foreach (var packageJsonFilePath in packageJsonFilePaths)
{ {
steps.Add(new RemoveDependencyFromPackageJsonFileStep(packageJsonFilePath, mvcUiPackageName)); steps.Add(new RemoveDependencyFromPackageJsonFileStep(packageJsonFilePath, mvcUiPackageName));
@ -278,7 +278,7 @@ public abstract class AppTemplateBase : TemplateInfo
"/MyCompanyName.MyProjectName.Blazor.Server.Tiered/package.json", "/MyCompanyName.MyProjectName.Blazor.Server.Tiered/package.json",
"/MyCompanyName.MyProjectName.Blazor.Server.Mongo/package.json" "/MyCompanyName.MyProjectName.Blazor.Server.Mongo/package.json"
}; };
foreach (var blazorServerPackageJsonFilePath in blazorServerPackageJsonFilePaths) foreach (var blazorServerPackageJsonFilePath in blazorServerPackageJsonFilePaths)
{ {
steps.Add(new RemoveDependencyFromPackageJsonFileStep(blazorServerPackageJsonFilePath, mvcUiPackageName)); steps.Add(new RemoveDependencyFromPackageJsonFileStep(blazorServerPackageJsonFilePath, mvcUiPackageName));
@ -288,11 +288,11 @@ public abstract class AppTemplateBase : TemplateInfo
else if (uiFramework == UiFramework.Angular) else if (uiFramework == UiFramework.Angular)
{ {
var ngUiPackageName = isProTemplate ? "@volosoft/abp.ng.theme.lepton-x" : "@abp/ng.theme.lepton-x"; var ngUiPackageName = isProTemplate ? "@volosoft/abp.ng.theme.lepton-x" : "@abp/ng.theme.lepton-x";
var angularPackageJsonFilePaths = new List<string> var angularPackageJsonFilePaths = new List<string>
{ {
"/angular/package.json" "/angular/package.json"
}; };
foreach (var angularPackageJsonFilePath in angularPackageJsonFilePaths) foreach (var angularPackageJsonFilePath in angularPackageJsonFilePaths)
{ {
steps.Add(new RemoveDependencyFromPackageJsonFileStep(angularPackageJsonFilePath, ngUiPackageName)); steps.Add(new RemoveDependencyFromPackageJsonFileStep(angularPackageJsonFilePath, ngUiPackageName));
@ -527,6 +527,7 @@ public abstract class AppTemplateBase : TemplateInfo
steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web")); steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web"));
steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web.Host")); steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web.Host"));
steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web.Tests", projectFolderPath: "/aspnet-core/test/MyCompanyName.MyProjectName.Web.Tests")); steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web.Tests", projectFolderPath: "/aspnet-core/test/MyCompanyName.MyProjectName.Web.Tests"));
steps.Add(new RemoveFileStep("/aspnet-core/src/MyCompanyName.MyProjectName.MauiBlazor/Directory.Build.props"));
if (context.BuildArgs.ExtraProperties.ContainsKey("separate-identity-server") || if (context.BuildArgs.ExtraProperties.ContainsKey("separate-identity-server") ||
context.BuildArgs.ExtraProperties.ContainsKey("separate-auth-server")) context.BuildArgs.ExtraProperties.ContainsKey("separate-auth-server"))

44
modules/feature-management/src/Volo.Abp.FeatureManagement.Blazor/Components/FeatureManagementModal.razor

@ -6,15 +6,15 @@
<ModalContent Size="ModalSize.Large" Centered="true"> <ModalContent Size="ModalSize.Large" Centered="true">
<ModalHeader> <ModalHeader>
<ModalTitle>@L["Features"]</ModalTitle> <ModalTitle>@L["Features"]</ModalTitle>
<CloseButton Clicked="CloseModal"/> <CloseButton Clicked="CloseModal" />
</ModalHeader> </ModalHeader>
<ModalBody MaxHeight="50"> @if (Groups == null || !Groups.Any())
@if (Groups == null || !Groups.Any()) {
{ <span class="m-3">@L["NoFeatureFoundMessage"]</span>
<span>@L["NoFeatureFoundMessage"]</span> }
} else
else {
{ <ModalBody MaxHeight="50">
<Tabs TabPosition="TabPosition.Start" Pills="true" @bind-SelectedTab="@SelectedTabName"> <Tabs TabPosition="TabPosition.Start" Pills="true" @bind-SelectedTab="@SelectedTabName">
<Items> <Items>
@foreach (var group in Groups) @foreach (var group in Groups)
@ -30,7 +30,7 @@
var index = i; var index = i;
<TabPanel Name="@GetNormalizedGroupName(Groups[index].Name)"> <TabPanel Name="@GetNormalizedGroupName(Groups[index].Name)">
<h4>@Groups[index].DisplayName</h4> <h4>@Groups[index].DisplayName</h4>
<hr class="mt-2 mb-3"/> <hr class="mt-2 mb-3" />
@foreach (var feature in Groups[index].Features) @foreach (var feature in Groups[index].Features)
{ {
<div class="mt-2"> <div class="mt-2">
@ -42,8 +42,8 @@
<Field Style="@GetFeatureStyles(feature)"> <Field Style="@GetFeatureStyles(feature)">
<FieldLabel>@feature.DisplayName</FieldLabel> <FieldLabel>@feature.DisplayName</FieldLabel>
<TextEdit Disabled="@disabled" <TextEdit Disabled="@disabled"
Text="@feature.Value" Text="@feature.Value"
TextChanged="@(async (v) => await OnFeatureValueChangedAsync(v, feature))"/> TextChanged="@(async (v) => await OnFeatureValueChangedAsync(v, feature))" />
@if (feature.Description != null) @if (feature.Description != null)
{ {
<div class="form-text">@feature.Description</div> <div class="form-text">@feature.Description</div>
@ -53,12 +53,12 @@
if (feature.ValueType is SelectionStringValueType) if (feature.ValueType is SelectionStringValueType)
{ {
var items = ((SelectionStringValueType) feature.ValueType).ItemSource.Items; var items = ((SelectionStringValueType)feature.ValueType).ItemSource.Items;
<Field Style="@GetFeatureStyles(feature)"> <Field Style="@GetFeatureStyles(feature)">
<FieldLabel>@feature.DisplayName</FieldLabel> <FieldLabel>@feature.DisplayName</FieldLabel>
<Select TValue="string" <Select TValue="string"
@bind-SelectedValue="@SelectionStringValues[feature.Name]"> @bind-SelectedValue="@SelectionStringValues[feature.Name]">
@foreach (var item in items) @foreach (var item in items)
{ {
<SelectItem Value="@item.Value"> <SelectItem Value="@item.Value">
@ -76,8 +76,7 @@
if (feature.ValueType is ToggleStringValueType) if (feature.ValueType is ToggleStringValueType)
{ {
<Field Style="@GetFeatureStyles(feature)"> <Field Style="@GetFeatureStyles(feature)">
<Check <Check TValue="bool" Checked="@ToggleValues[feature.Name]" CheckedChanged="@(async (v) => await OnSelectedValueChangedAsync(v, feature))">
TValue="bool" Checked="@ToggleValues[feature.Name]" CheckedChanged="@(async (v) => await OnSelectedValueChangedAsync(v, feature))">
@feature.DisplayName @feature.DisplayName
</Check> </Check>
@if (feature.Description != null) @if (feature.Description != null)
@ -94,12 +93,13 @@
} }
</Content> </Content>
</Tabs> </Tabs>
} </ModalBody>
</ModalBody> <ModalFooter>
<ModalFooter> <Button Color="Color.Primary" Clicked="@(async () => await DeleteAsync(ProviderName,ProviderKey))">@L["ResetToDefault"]</Button>
<Button Color="Color.Primary" Clicked="@(async () => await DeleteAsync(ProviderName,ProviderKey))">@L["ResetToDefault"]</Button> <Button Color="Color.Secondary" Clicked="CloseModal">@L["Cancel"]</Button>
<Button Color="Color.Secondary" Clicked="CloseModal">@L["Cancel"]</Button> <Button Color="Color.Primary" Clicked="SaveAsync">@L["Save"]</Button>
<Button Color="Color.Primary" Clicked="SaveAsync">@L["Save"]</Button> </ModalFooter>
</ModalFooter> }
</ModalContent> </ModalContent>
</Modal> </Modal>

3
modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/SettingManagementFeatureDefinitionProvider.cs

@ -17,7 +17,8 @@ public class SettingManagementFeatureDefinitionProvider : FeatureDefinitionProvi
"true", "true",
L("Feature:SettingManagementEnable"), L("Feature:SettingManagementEnable"),
L("Feature:SettingManagementEnableDescription"), L("Feature:SettingManagementEnableDescription"),
new ToggleStringValueType()); new ToggleStringValueType(),
isAvailableToHost: false);
settingEnableFeature.CreateChild( settingEnableFeature.CreateChild(
SettingManagementFeatures.AllowChangingEmailSettings, SettingManagementFeatures.AllowChangingEmailSettings,

2
modules/setting-management/src/Volo.Abp.SettingManagement.Web/Settings/EmailingPageContributor.cs

@ -11,7 +11,7 @@ public class EmailingPageContributor : SettingPageContributorBase
{ {
public EmailingPageContributor() public EmailingPageContributor()
{ {
RequiredFeatures(SettingManagementFeatures.Enable); RequiredTenantSideFeatures(SettingManagementFeatures.Enable);
RequiredTenantSideFeatures(SettingManagementFeatures.AllowChangingEmailSettings); RequiredTenantSideFeatures(SettingManagementFeatures.AllowChangingEmailSettings);
RequiredPermissions(SettingManagementPermissions.Emailing); RequiredPermissions(SettingManagementPermissions.Emailing);
} }

2
npm/ng-packs/packages/identity/src/lib/defaults/default-users-form-props.ts

@ -12,7 +12,7 @@ export const DEFAULT_USERS_CREATE_FORM_PROPS = FormProp.createMany<IdentityUserD
validators: () => [Validators.required, Validators.maxLength(256)], validators: () => [Validators.required, Validators.maxLength(256)],
}, },
{ {
type: ePropType.Password, type: ePropType.PasswordInputGroup,
name: 'password', name: 'password',
displayName: 'AbpIdentity::Password', displayName: 'AbpIdentity::Password',
id: 'password', id: 'password',

2
npm/ng-packs/packages/schematics/src/commands/create-lib/files-package/__libraryName@kebab__/karma.conf.js.template

@ -25,7 +25,7 @@ module.exports = function (config) {
suppressAll: true // removes the duplicated traces suppressAll: true // removes the duplicated traces
}, },
coverageReporter: { coverageReporter: {
dir: require('path').join(__dirname, '../../coverage/my-project-name'), dir: require('path').join(__dirname, '../../coverage/<%= kebab(libraryName) %>'),
subdir: '.', subdir: '.',
reporters: [ reporters: [
{ type: 'html' }, { type: 'html' },

109
npm/ng-packs/packages/schematics/src/commands/create-lib/index.ts

@ -8,25 +8,31 @@ import {
Tree, Tree,
url, url,
} from '@angular-devkit/schematics'; } from '@angular-devkit/schematics';
import { GenerateLibSchema } from './models/generate-lib-schema'; import * as ts from 'typescript';
import { join, normalize } from '@angular-devkit/core';
import { import {
addImportToModule,
addRouteDeclarationToModule,
applyWithOverwrite, applyWithOverwrite,
camel,
getFirstApplication,
getWorkspace, getWorkspace,
InsertChange,
interpolate, interpolate,
isLibrary, isLibrary,
JSONFile, JSONFile,
kebab, kebab,
pascal,
readWorkspaceSchema,
resolveProject, resolveProject,
updateWorkspace, updateWorkspace,
} from '../../utils'; } from '../../utils';
import * as cases from '../../utils/text'; import { ProjectDefinition, WorkspaceDefinition } from '../../utils/angular/workspace';
import { Exception } from '../../enums';
import { join, normalize } from '@angular-devkit/core';
import {
ProjectDefinition,
WorkspaceDefinition,
} from '@angular-devkit/core/src/workspace/definitions';
import { addLibToWorkspaceFile } from '../../utils/angular-schematic/generate-lib'; import { addLibToWorkspaceFile } from '../../utils/angular-schematic/generate-lib';
import * as cases from '../../utils/text';
import { Exception } from '../../enums/exception';
import { GenerateLibSchema } from './models/generate-lib-schema';
export default function (schema: GenerateLibSchema) { export default function (schema: GenerateLibSchema) {
return async (tree: Tree) => { return async (tree: Tree) => {
@ -120,6 +126,8 @@ export function addLibToWorkspaceIfNotExist(name: string, packagesDir: string):
: noop(), : noop(),
addLibToWorkspaceFile(projectRoot, packageName), addLibToWorkspaceFile(projectRoot, packageName),
updateTsConfig(packageName, pathImportLib), updateTsConfig(packageName, pathImportLib),
importConfigModuleToDefaultProjectAppModule(workspace, packageName),
addRoutingToAppRoutingModule(workspace, packageName),
]); ]);
}; };
} }
@ -134,7 +142,9 @@ export function updateTsConfig(packageName: string, path: string) {
const file = new JSONFile(host, tsConfig); const file = new JSONFile(host, tsConfig);
const jsonPath = ['compilerOptions', 'paths', packageName]; const jsonPath = ['compilerOptions', 'paths', packageName];
const jsonPathConfig = ['compilerOptions', 'paths', `${packageName}/config`];
file.modify(jsonPath, [`${path}/src/public-api.ts`]); file.modify(jsonPath, [`${path}/src/public-api.ts`]);
file.modify(jsonPathConfig, [`${path}/config/src/public-api.ts`]);
}; };
} }
@ -154,3 +164,86 @@ export async function createLibSecondaryEntry(tree: Tree, options: GenerateLibSc
]), ]),
]); ]);
} }
export function importConfigModuleToDefaultProjectAppModule(
workspace: WorkspaceDefinition,
packageName: string,
) {
return (tree: Tree) => {
const projectName = readWorkspaceSchema(tree).defaultProject || getFirstApplication(tree).name!;
const project = workspace.projects.get(projectName);
const appModulePath = `${project?.sourceRoot}/app/app.module.ts`;
const appModule = tree.read(appModulePath);
if (!appModule) {
return;
}
const appModuleContent = appModule.toString();
if (appModuleContent.includes(`${camel(packageName)}ConfigModule`)) {
return;
}
const forRootStatement = `${pascal(packageName)}ConfigModule.forRoot()`;
const text = tree.read(appModulePath);
if (!text) {
return;
}
const sourceText = text.toString();
if (sourceText.includes(forRootStatement)) {
return;
}
const source = ts.createSourceFile(appModulePath, sourceText, ts.ScriptTarget.Latest, true);
const changes = addImportToModule(
source,
appModulePath,
forRootStatement,
`${kebab(packageName)}/config`,
);
const recorder = tree.beginUpdate(appModulePath);
for (const change of changes) {
if (change instanceof InsertChange) {
recorder.insertLeft(change.pos, change.toAdd);
}
}
tree.commitUpdate(recorder);
return;
};
}
export function addRoutingToAppRoutingModule(workspace: WorkspaceDefinition, packageName: string) {
return (tree: Tree) => {
const projectName = readWorkspaceSchema(tree).defaultProject || getFirstApplication(tree).name!;
const project = workspace.projects.get(projectName);
const appRoutingModulePath = `${project?.sourceRoot}/app/app-routing.module.ts`;
const appRoutingModule = tree.read(appRoutingModulePath);
if (!appRoutingModule) {
return;
}
const appRoutingModuleContent = appRoutingModule.toString();
const moduleName = `${pascal(packageName)}Module`;
if (appRoutingModuleContent.includes(moduleName)) {
return;
}
const source = ts.createSourceFile(
appRoutingModulePath,
appRoutingModuleContent,
ts.ScriptTarget.Latest,
true,
);
const importPath = `${kebab(packageName)}`;
const importStatement = `() => import('${importPath}').then(m => m.${moduleName}.forLazy())`;
const routeDefinition = `{ path: '${kebab(packageName)}', loadChildren: ${importStatement} }`;
const change = addRouteDeclarationToModule(source, `${kebab(packageName)}`, routeDefinition);
const recorder = tree.beginUpdate(appRoutingModulePath);
if (change instanceof InsertChange) {
recorder.insertLeft(change.pos, change.toAdd);
}
tree.commitUpdate(recorder);
return;
};
}

15
npm/ng-packs/packages/schematics/src/commands/create-lib/schema.json

@ -16,19 +16,28 @@
"isSecondaryEntrypoint": { "isSecondaryEntrypoint": {
"description": "Is secondary entrypoint", "description": "Is secondary entrypoint",
"type": "boolean", "type": "boolean",
"$default": false, "$default": {
"$source": "argv",
"index": 1
},
"x-prompt": "Is secondary entrypoint?" "x-prompt": "Is secondary entrypoint?"
}, },
"isModuleTemplate": { "isModuleTemplate": {
"description": "Is module template", "description": "Is module template",
"type": "boolean", "type": "boolean",
"$default": true, "$default": {
"$source": "argv",
"index": 2
},
"x-prompt": "Is module template?" "x-prompt": "Is module template?"
}, },
"override": { "override": {
"description": "Override existing files", "description": "Override existing files",
"type": "boolean", "type": "boolean",
"$default": false, "$default": {
"$source": "argv",
"index": 3
},
"x-prompt": "Override existing files?" "x-prompt": "Override existing files?"
} }
}, },

2
npm/ng-packs/packages/tenant-management/src/lib/defaults/default-tenants-form-props.ts

@ -21,7 +21,7 @@ export const DEFAULT_TENANTS_CREATE_FORM_PROPS = FormProp.createMany<
validators: () => [Validators.required, Validators.maxLength(256), Validators.email], validators: () => [Validators.required, Validators.maxLength(256), Validators.email],
}, },
{ {
type: ePropType.Password, type: ePropType.PasswordInputGroup,
name: 'adminPassword', name: 'adminPassword',
displayName: 'AbpTenantManagement::DisplayName:AdminPassword', displayName: 'AbpTenantManagement::DisplayName:AdminPassword',
id: 'admin-password', id: 'admin-password',

15
npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.html

@ -138,6 +138,21 @@
class="form-control" class="form-control"
></textarea> ></textarea>
</ng-template> </ng-template>
<ng-template ngSwitchCase="passwordinputgroup">
<ng-template [ngTemplateOutlet]="label"></ng-template>
<abp-password
*abpReplaceableTemplate="{
componentKey: passwordKey,
inputs: {
inputId: { value: prop.id },
formControlName: { value: prop.name }
}
}"
[inputId]="prop.id"
[formControlName]="prop.name"
></abp-password>
</ng-template>
</div> </div>
</ng-container> </ng-container>

7
npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.ts

@ -32,6 +32,7 @@ import { FormProp } from '../../models/form-props';
import { PropData } from '../../models/props'; import { PropData } from '../../models/props';
import { selfFactory } from '../../utils/factory.util'; import { selfFactory } from '../../utils/factory.util';
import { addTypeaheadTextSuffix } from '../../utils/typeahead.util'; import { addTypeaheadTextSuffix } from '../../utils/typeahead.util';
import { eThemeSharedComponents } from '../../enums/components';
@Component({ @Component({
selector: 'abp-extensible-form-prop', selector: 'abp-extensible-form-prop',
@ -70,6 +71,8 @@ export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit {
typeaheadModel: any; typeaheadModel: any;
passwordKey = eThemeSharedComponents.PasswordComponent;
private readonly form: UntypedFormGroup; private readonly form: UntypedFormGroup;
disabledFn = (data: PropData) => false; disabledFn = (data: PropData) => false;
@ -161,6 +164,8 @@ export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit {
return 'time'; return 'time';
case ePropType.Typeahead: case ePropType.Typeahead:
return 'typeahead'; return 'typeahead';
case ePropType.PasswordInputGroup:
return 'passwordinputgroup';
default: default:
return prop.options ? 'select' : 'input'; return prop.options ? 'select' : 'input';
} }
@ -179,6 +184,8 @@ export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit {
return 'email'; return 'email';
case ePropType.Password: case ePropType.Password:
return 'password'; return 'password';
case ePropType.PasswordInputGroup:
return 'passwordinputgroup';
default: default:
return 'hidden'; return 'hidden';
} }

3
npm/ng-packs/packages/theme-shared/extensions/src/lib/enums/components.ts

@ -0,0 +1,3 @@
export const enum eThemeSharedComponents {
PasswordComponent = 'ThemeShared.Extensions.PasswordComponent',
}

1
npm/ng-packs/packages/theme-shared/extensions/src/lib/enums/props.enum.ts

@ -8,6 +8,7 @@ export const enum ePropType {
MultiSelect = 'multiselect', MultiSelect = 'multiselect',
Number = 'number', Number = 'number',
Password = 'password', Password = 'password',
PasswordInputGroup = 'passwordinputgroup',
String = 'string', String = 'string',
Text = 'text', Text = 'text',
Time = 'time', Time = 'time',

1
npm/ng-packs/packages/theme-shared/extensions/src/public-api.ts

@ -11,6 +11,7 @@ export * from './lib/constants/extra-properties';
export * from './lib/directives/disabled.directive'; export * from './lib/directives/disabled.directive';
export * from './lib/directives/prop-data.directive'; export * from './lib/directives/prop-data.directive';
export * from './lib/enums/props.enum'; export * from './lib/enums/props.enum';
export * from './lib/enums/components';
export { export {
ActionCallback, ActionCallback,
ActionList, ActionList,

1
npm/ng-packs/packages/theme-shared/src/lib/components/index.ts

@ -10,3 +10,4 @@ export * from './modal/modal-ref.service';
export * from './modal/modal.component'; export * from './modal/modal.component';
export * from './toast-container/toast-container.component'; export * from './toast-container/toast-container.component';
export * from './toast/toast.component'; export * from './toast/toast.component';
export * from './password/password.component';

19
npm/ng-packs/packages/theme-shared/src/lib/components/password/password.component.html

@ -0,0 +1,19 @@
<div class="input-group" validationTarget>
<input
[type]="fieldTextType ? 'text' : 'password'"
class="form-control"
[id]="inputId"
[(ngModel)]="value"
/>
<button class="btn btn-secondary" type="button">
<i
class="fa"
[ngClass]="{
'fa-eye-slash': !fieldTextType,
'fa-eye': fieldTextType
}"
(click)="toggleFieldTextType()"
></i>
</button>
</div>

28
npm/ng-packs/packages/theme-shared/src/lib/components/password/password.component.ts

@ -0,0 +1,28 @@
import { Component, forwardRef, Injector, Input } from '@angular/core';
import { AbstractNgModelComponent } from '@abp/ng.core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'abp-password',
templateUrl: `password.component.html`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => PasswordComponent),
multi: true,
},
],
})
export class PasswordComponent extends AbstractNgModelComponent {
@Input() inputId!: string;
@Input() formControlName!: string;
fieldTextType: boolean;
constructor(injector: Injector) {
super(injector);
}
toggleFieldTextType() {
this.fieldTextType = !this.fieldTextType;
}
}

6
npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts

@ -32,9 +32,10 @@ import { RootParams } from './models/common';
import { NG_BOOTSTRAP_CONFIG_PROVIDERS } from './providers'; import { NG_BOOTSTRAP_CONFIG_PROVIDERS } from './providers';
import { THEME_SHARED_ROUTE_PROVIDERS } from './providers/route.provider'; import { THEME_SHARED_ROUTE_PROVIDERS } from './providers/route.provider';
import { THEME_SHARED_APPEND_CONTENT } from './tokens/append-content.token'; import { THEME_SHARED_APPEND_CONTENT } from './tokens/append-content.token';
import { httpErrorConfigFactory, HTTP_ERROR_CONFIG } from './tokens/http-error.token'; import { HTTP_ERROR_CONFIG, httpErrorConfigFactory } from './tokens/http-error.token';
import { DateParserFormatter } from './utils/date-parser-formatter'; import { DateParserFormatter } from './utils/date-parser-formatter';
import { CONFIRMATION_ICONS, DEFAULT_CONFIRMATION_ICONS } from './tokens/confirmation-icons.token'; import { CONFIRMATION_ICONS, DEFAULT_CONFIRMATION_ICONS } from './tokens/confirmation-icons.token';
import { PasswordComponent } from './components/password/password.component';
const declarationsWithExports = [ const declarationsWithExports = [
BreadcrumbComponent, BreadcrumbComponent,
@ -46,6 +47,7 @@ const declarationsWithExports = [
ModalComponent, ModalComponent,
ToastComponent, ToastComponent,
ToastContainerComponent, ToastContainerComponent,
PasswordComponent,
NgxDatatableDefaultDirective, NgxDatatableDefaultDirective,
NgxDatatableListDirective, NgxDatatableListDirective,
LoadingDirective, LoadingDirective,
@ -61,7 +63,7 @@ const declarationsWithExports = [
EllipsisModule, EllipsisModule,
], ],
declarations: [...declarationsWithExports, HttpErrorWrapperComponent], declarations: [...declarationsWithExports, HttpErrorWrapperComponent],
exports: [NgxDatatableModule, EllipsisModule, ...declarationsWithExports], exports: [NgxDatatableModule, EllipsisModule, NgxValidateCoreModule, ...declarationsWithExports],
providers: [DatePipe], providers: [DatePipe],
}) })
export class BaseThemeSharedModule {} export class BaseThemeSharedModule {}

Loading…
Cancel
Save