Skip to content

Commit

Permalink
Merge branch 'jhipster:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
mshima authored Jan 23, 2024
2 parents a1f818c + 77657db commit da7089f
Show file tree
Hide file tree
Showing 15 changed files with 135 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { Component, inject, OnInit } from '@angular/core';
import { HttpHeaders } from '@angular/common/http';
<%_ } _%>
import { ActivatedRoute, Data, ParamMap, Router, RouterModule } from '@angular/router';
import { combineLatest<%_ if (!readOnly) { _%>, filter<%_ } _%>, Observable, switchMap, tap } from 'rxjs';
import { combineLatest<%_ if (!readOnly) { _%>, filter<%_ } _%>, Observable, switchMap, Subscription, tap } from 'rxjs';
<%_ if (!readOnly) { _%>
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
<%_ } _%>
Expand Down Expand Up @@ -121,6 +121,7 @@ export class <%= componentName %> implements OnInit {
private static readonly NOT_SORTABLE_FIELDS_AFTER_SEARCH = [<%- notSortableFieldsAfterSearch %>];

<%_ } _%>
subscription: Subscription | null = null;
<%= entityInstancePlural %>?: I<%= entityAngularName %>[];
isLoading = false;

Expand Down Expand Up @@ -227,7 +228,10 @@ export class <%= componentName %> implements OnInit {

<%_ } _%>
load(): void {
this.loadFromBackendWithRouteInformations().subscribe({
if (this.subscription !== null) {
this.subscription.unsubscribe();
}
this.subscription = this.loadFromBackendWithRouteInformations().subscribe({
next: (res: EntityArrayResponseType) => {
this.onResponseSuccess(res);
}
Expand Down
2 changes: 2 additions & 0 deletions generators/app/__snapshots__/generator.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ exports[`generator - app with default config should match snapshot 1`] = `
"authenticationTypeOauth2": false,
"authenticationTypeSession": false,
"authenticationUsesCsrf": false,
"authority": Any<Object>,
"backendType": "Java",
"backendTypeJavaAny": true,
"backendTypeSpringBoot": true,
Expand Down Expand Up @@ -791,6 +792,7 @@ exports[`generator - app with gateway should match snapshot 1`] = `
"authenticationTypeOauth2": false,
"authenticationTypeSession": false,
"authenticationUsesCsrf": false,
"authority": Any<Object>,
"backendType": "Java",
"backendTypeJavaAny": true,
"backendTypeSpringBoot": true,
Expand Down
2 changes: 2 additions & 0 deletions generators/app/generator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ describe(`generator - ${generator}`, () => {
it('should match snapshot', () => {
expect(runResult.generator.sharedData.getApplication()).toMatchSnapshot({
user: expect.any(Object),
authority: expect.any(Object),
jhipsterPackageJson: expect.any(Object),
});
});
Expand All @@ -73,6 +74,7 @@ describe(`generator - ${generator}`, () => {
it('should match snapshot', () => {
expect(runResult.generator.sharedData.getApplication()).toMatchSnapshot({
user: expect.any(Object),
authority: expect.any(Object),
jhipsterPackageJson: expect.any(Object),
jwtSecretKey: expect.any(String),
});
Expand Down
62 changes: 34 additions & 28 deletions generators/base-application/generator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ describe(`generator - ${generator}`, () => {
const entitiesArg = {
...controlArg,
...applicationArg,
entities: [expect.any(Object), expect.any(Object), expect.any(Object), expect.any(Object)],
entities: [expect.any(Object), expect.any(Object), expect.any(Object), expect.any(Object), expect.any(Object)],
};

expect(initializing).toBeCalledWith(controlArg);
Expand All @@ -248,32 +248,35 @@ describe(`generator - ${generator}`, () => {
expect(configuringEachEntity).toHaveBeenNthCalledWith(2, { ...entityConfiguringArg, entityName: 'Two' });
expect(configuringEachEntity).toHaveBeenNthCalledWith(3, { ...entityConfiguringArg, entityName: 'Three' });

expect(preparingEachEntity).toBeCalledTimes(4);
expect(preparingEachEntity).toBeCalledTimes(5);
expect(preparingEachEntity).toHaveBeenNthCalledWith(1, { ...entityArg, entityName: 'User' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(2, { ...entityArg, entityName: 'One' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(3, { ...entityArg, entityName: 'Two' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(4, { ...entityArg, entityName: 'Three' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(2, { ...entityArg, entityName: 'Authority' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(3, { ...entityArg, entityName: 'One' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(4, { ...entityArg, entityName: 'Two' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(5, { ...entityArg, entityName: 'Three' });

expect(preparingEachEntityField).toBeCalledTimes(8);
expect(preparingEachEntityField).toBeCalledTimes(9);
expect(preparingEachEntityField).toHaveBeenNthCalledWith(1, { ...fieldArg, description: 'User#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(2, { ...fieldArg, description: 'User#login' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(3, { ...fieldArg, description: 'User#firstName' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(4, { ...fieldArg, description: 'User#lastName' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(5, { ...fieldArg, description: 'One#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(6, { ...fieldArg, description: 'Two#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(7, { ...fieldArg, description: 'Two#name' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(8, { ...fieldArg, description: 'Three#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(5, { ...fieldArg, description: 'Authority#name' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(6, { ...fieldArg, description: 'One#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(7, { ...fieldArg, description: 'Two#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(8, { ...fieldArg, description: 'Two#name' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(9, { ...fieldArg, description: 'Three#id' });

expect(preparingEachEntityRelationship).toBeCalledTimes(3);
expect(preparingEachEntityRelationship).toHaveBeenNthCalledWith(1, { ...relationshipArg, description: 'One#two' });
expect(preparingEachEntityRelationship).toHaveBeenNthCalledWith(2, { ...relationshipArg, description: 'Two#one' });
expect(preparingEachEntityRelationship).toHaveBeenNthCalledWith(3, { ...relationshipArg, description: 'Two#three' });

expect(postPreparingEachEntity).toBeCalledTimes(4);
expect(postPreparingEachEntity).toBeCalledTimes(5);
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(1, { ...entityArg, entityName: 'User' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(2, { ...entityArg, entityName: 'One' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(3, { ...entityArg, entityName: 'Two' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(4, { ...entityArg, entityName: 'Three' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(2, { ...entityArg, entityName: 'Authority' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(3, { ...entityArg, entityName: 'One' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(4, { ...entityArg, entityName: 'Two' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(5, { ...entityArg, entityName: 'Three' });

expect(defaultTask).toBeCalledWith(entitiesArg);
expect(writingEntities).toBeCalledWith(entitiesArg);
Expand Down Expand Up @@ -468,7 +471,7 @@ describe(`generator - ${generator}`, () => {

const entitiesArg = {
...applicationArg,
entities: [expect.any(Object), expect.any(Object), expect.any(Object), expect.any(Object)],
entities: [expect.any(Object), expect.any(Object), expect.any(Object), expect.any(Object), expect.any(Object)],
};

const writingEntitiesArg = {
Expand All @@ -492,32 +495,35 @@ describe(`generator - ${generator}`, () => {
expect(configuringEachEntity).toHaveBeenNthCalledWith(2, { ...entityConfiguringArg, entityName: 'Two' });
expect(configuringEachEntity).toHaveBeenNthCalledWith(3, { ...entityConfiguringArg, entityName: 'Three' });

expect(preparingEachEntity).toBeCalledTimes(4);
expect(preparingEachEntity).toBeCalledTimes(5);
expect(preparingEachEntity).toHaveBeenNthCalledWith(1, { ...entityArg, entityName: 'User' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(2, { ...entityArg, entityName: 'One' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(3, { ...entityArg, entityName: 'Two' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(4, { ...entityArg, entityName: 'Three' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(2, { ...entityArg, entityName: 'Authority' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(3, { ...entityArg, entityName: 'One' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(4, { ...entityArg, entityName: 'Two' });
expect(preparingEachEntity).toHaveBeenNthCalledWith(5, { ...entityArg, entityName: 'Three' });

expect(preparingEachEntityField).toBeCalledTimes(8);
expect(preparingEachEntityField).toBeCalledTimes(9);
expect(preparingEachEntityField).toHaveBeenNthCalledWith(1, { ...fieldArg, description: 'User#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(2, { ...fieldArg, description: 'User#login' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(3, { ...fieldArg, description: 'User#firstName' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(4, { ...fieldArg, description: 'User#lastName' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(5, { ...fieldArg, description: 'One#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(6, { ...fieldArg, description: 'Two#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(7, { ...fieldArg, description: 'Two#name' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(8, { ...fieldArg, description: 'Three#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(5, { ...fieldArg, description: 'Authority#name' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(6, { ...fieldArg, description: 'One#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(7, { ...fieldArg, description: 'Two#id' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(8, { ...fieldArg, description: 'Two#name' });
expect(preparingEachEntityField).toHaveBeenNthCalledWith(9, { ...fieldArg, description: 'Three#id' });

expect(preparingEachEntityRelationship).toBeCalledTimes(3);
expect(preparingEachEntityRelationship).toHaveBeenNthCalledWith(1, { ...relationshipArg, description: 'One#two' });
expect(preparingEachEntityRelationship).toHaveBeenNthCalledWith(2, { ...relationshipArg, description: 'Two#one' });
expect(preparingEachEntityRelationship).toHaveBeenNthCalledWith(3, { ...relationshipArg, description: 'Two#three' });

expect(postPreparingEachEntity).toBeCalledTimes(4);
expect(postPreparingEachEntity).toBeCalledTimes(5);
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(1, { ...entityArg, entityName: 'User' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(2, { ...entityArg, entityName: 'One' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(3, { ...entityArg, entityName: 'Two' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(4, { ...entityArg, entityName: 'Three' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(2, { ...entityArg, entityName: 'Authority' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(3, { ...entityArg, entityName: 'One' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(4, { ...entityArg, entityName: 'Two' });
expect(postPreparingEachEntity).toHaveBeenNthCalledWith(5, { ...entityArg, entityName: 'Three' });

expect(defaultTask).toBeCalledWith(entitiesArg);

Expand Down
9 changes: 7 additions & 2 deletions generators/base-application/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,15 @@ type ApplicationType = DeterministicOptionWithDerivedProperties<
type UserManagement =
| {
skipUserManagement: true;
generateBuiltInUserEntity?: false;
generateBuiltInAuthorityEntity: false;
}
| {
skipUserManagement: false;
generateBuiltInUserEntity?: boolean;
user: any;
generateBuiltInAuthorityEntity: boolean;
authority: any;
};

type JwtApplication = UserManagement & {
Expand All @@ -68,7 +73,9 @@ type JwtApplication = UserManagement & {

type Oauth2Application = {
jwtSecretKey: string;
generateBuiltInUserEntity?: boolean;
user: any;
generateBuiltInAuthorityEntity: false;
};

type SessionApplication = UserManagement & {
Expand Down Expand Up @@ -112,8 +119,6 @@ export type CommonClientServerApplication = BaseApplication &

skipUserManagement?: boolean;
generateUserManagement?: boolean;
generateBuiltInUserEntity?: boolean;
generateBuiltInAuthorityEntity?: boolean;
};

type ServiceDiscoveryApplication = OptionWithDerivedProperties<'serviceDiscoveryType', ['no', 'eureka', 'consul']>;
Expand Down
1 change: 1 addition & 0 deletions generators/base-application/types/entity.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export type BaseEntity = {
type Entity = Required<BaseEntity> & {
builtIn?: boolean;
builtInUser?: boolean;
builtInAuthority?: boolean;
microserviceName?: string;

entityNameCapitalized: string;
Expand Down
6 changes: 5 additions & 1 deletion generators/base-entity-changes/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default abstract class GeneratorBaseEntityChanges extends GeneratorBaseAp
*/
protected generateIncrementalChanges(): BaseChangelog[] {
const recreateInitialChangelog = this.recreateInitialChangelog;
const { generateBuiltInUserEntity, incrementalChangelog } = this.sharedData.getApplication();
const { generateBuiltInUserEntity, generateBuiltInAuthorityEntity, incrementalChangelog } = this.sharedData.getApplication();
const entityNames = this.getExistingEntityNames();

const entitiesByName = Object.fromEntries(entityNames.map(entityName => [entityName, this.sharedData.getEntity(entityName)]));
Expand All @@ -88,6 +88,10 @@ export default abstract class GeneratorBaseEntityChanges extends GeneratorBaseAp
const user = this.sharedData.getEntity('User');
previousEntitiesByName.User = user;
}
if (generateBuiltInAuthorityEntity) {
const authority = this.sharedData.getEntity('Authority');
previousEntitiesByName.Authority = authority;
}

const entities: any[] = Object.values(previousEntitiesByName);
loadEntitiesAnnotations(entities);
Expand Down
22 changes: 18 additions & 4 deletions generators/bootstrap-application-base/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import {
prepareField as prepareFieldForTemplates,
prepareRelationship,
} from '../base-application/support/index.js';
import { createUserEntity } from './utils.js';
import { createAuthorityEntity, createUserEntity } from './utils.js';
import { JAVA_DOCKER_DIR } from '../generator-constants.js';
import { GENERATOR_BOOTSTRAP, GENERATOR_BOOTSTRAP_APPLICATION_BASE, GENERATOR_COMMON, GENERATOR_PROJECT_NAME } from '../generator-list.js';
import { packageJson } from '../../lib/index.js';
Expand Down Expand Up @@ -227,10 +227,24 @@ export default class BootstrapApplicationBase extends BaseApplicationGenerator {
}

const customUser = entitiesToLoad.find(entityToLoad => entityToLoad.entityName === 'User');
const customUserData = customUser ? customUser.entityStorage.getAll() : {};
const user = createUserEntity.call(this, customUserData, application);
const customUserData: any = customUser?.entityStorage.getAll() ?? {};
const user = createUserEntity.call(this, { ...customUserData, ...customUserData.annotations }, application);
this.sharedData.setEntity('User', user);
(application as any).user = user;
application.user = user;
}
},
loadAuthority({ application, entitiesToLoad }) {
if (application.generateBuiltInAuthorityEntity) {
const authority = 'Authority';
if (this.sharedData.hasEntity(authority)) {
throw new Error(`Fail to bootstrap '${authority}', already exists.`);
}

const customEntity = entitiesToLoad.find(entityToLoad => entityToLoad.entityName === authority);
const customEntityData: any = customEntity?.entityStorage.getAll() ?? {};
const authorityEntity = createAuthorityEntity.call(this, { ...customEntityData, ...customEntityData.annotations }, application);
this.sharedData.setEntity(authority, authorityEntity);
application.authority = authorityEntity;
}
},
loadingEntities({ application, entitiesToLoad }) {
Expand Down
46 changes: 46 additions & 0 deletions generators/bootstrap-application-base/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ const { CommonDBTypes } = fieldTypes;

const { STRING: TYPE_STRING } = CommonDBTypes;

const authorityEntityName = 'Authority';

// eslint-disable-next-line import/prefer-default-export
export function createUserEntity(customUserData = {}, application) {
const userEntityDefinition = this.getEntityConfig('User')?.getAll();
Expand Down Expand Up @@ -96,6 +98,50 @@ export function createUserEntity(customUserData = {}, application) {
return user;
}

export function createAuthorityEntity(customAuthorityData = {}, application) {
const entityDefinition = this.getEntityConfig(authorityEntityName)?.getAll();
if (entityDefinition) {
if (entityDefinition.relationships && entityDefinition.relationships.length > 0) {
this.log.warn(`Relationships on the ${authorityEntityName} entity side will be disregarded`);
}
if (entityDefinition.fields && entityDefinition.fields.some(field => field.fieldName !== 'name')) {
this.log.warn(`Fields on the ${authorityEntityName} entity side (other than name) will be disregarded`);
}
}

// Create entity definition for built-in entity to make easier to deal with relationships.
const authorityEntity = {
name: authorityEntityName,
entitySuffix: '',
builtIn: true,
fluentMethods: false,
entityTableName: `${application.jhiTablePrefix}_authority`,
relationships: [],
fields: entityDefinition ? entityDefinition.fields || [] : [],
builtInAuthority: true,
skipClient: application.clientFrameworkReact || application.clientFrameworkVue,
searchEngine: 'no',
...customAuthorityData,
};

loadRequiredConfigIntoEntity(authorityEntity, application);
// Fallback to defaults for test cases.
loadRequiredConfigIntoEntity(authorityEntity, this.jhipsterConfigWithDefaults);

addOrExtendFields(authorityEntity.fields, [
{
fieldName: 'name',
fieldType: TYPE_STRING,
id: true,
fieldValidateRules: [Validations.MAXLENGTH],
fieldValidateRulesMaxlength: 50,
builtIn: true,
},
]);

return authorityEntity;
}

function addOrExtendFields(fields, fieldsToAdd) {
fieldsToAdd = [].concat(fieldsToAdd);
for (const fieldToAdd of fieldsToAdd) {
Expand Down
2 changes: 1 addition & 1 deletion generators/bootstrap-application-server/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ export default class BoostrapApplicationServer extends BaseApplicationGenerator
for (const { entityName } of entitiesToLoad) {
const entity = this.sharedData.getEntity(entityName);
loadRequiredConfigIntoEntity.call(this, entity, application);
loadRequiredConfigDerivedProperties(entity);
}
},
requiredOtherSideRelationships() {
Expand All @@ -166,6 +165,7 @@ export default class BoostrapApplicationServer extends BaseApplicationGenerator
return this.asPreparingEachEntityTaskGroup({
prepareEntity({ entity }) {
prepareEntityServerForTemplates(entity);
loadRequiredConfigDerivedProperties(entity);
},
preparePrimaryKey({ entity, application }) {
// If primaryKey doesn't exist, create it.
Expand Down
1 change: 1 addition & 0 deletions generators/bootstrap-application/generator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ describe(`generator - ${generator}`, () => {
expect(Object.keys(runResult.generator.sharedData.getEntitiesMap())).toMatchInlineSnapshot(`
[
"User",
"Authority",
"EntityA",
]
`);
Expand Down
Loading

0 comments on commit da7089f

Please sign in to comment.