Skip to content

Commit

Permalink
generator-specific entity
Browse files Browse the repository at this point in the history
  • Loading branch information
Tcharl committed Nov 2, 2024
1 parent e6ee5a7 commit 4948d95
Show file tree
Hide file tree
Showing 20 changed files with 126 additions and 121 deletions.
102 changes: 31 additions & 71 deletions generators/angular/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
*/
import chalk from 'chalk';
import { isFileStateModified } from 'mem-fs-editor/state';
import type { Entity } from '../../lib/types/application/entity.js';
import BaseApplicationGenerator from '../base-application/index.js';
import { GENERATOR_ANGULAR, GENERATOR_CLIENT, GENERATOR_LANGUAGES } from '../generator-list.js';
import { defaultLanguage } from '../languages/support/index.js';
Expand Down Expand Up @@ -47,17 +46,15 @@ import {
isTranslatedAngularFile,
translateAngularFilesTransform,
} from './support/index.js';
import type { AngularApplication } from './types.js';
import type { AngularApplication, AngularEntity } from './types.js';

const { ANGULAR } = clientFrameworkTypes;

export default class AngularGenerator extends BaseApplicationGenerator<
Entity,
AngularEntity,
AngularApplication,
DefaultTaskTypes<Entity, AngularApplication>
DefaultTaskTypes<AngularEntity, AngularApplication>
> {
localEntities?: any[];

async beforeQueue() {
if (!this.fromBlueprint) {
await this.composeWithBlueprints();
Expand Down Expand Up @@ -92,14 +89,19 @@ export default class AngularGenerator extends BaseApplicationGenerator<

get preparing() {
return this.asPreparingTaskGroup({
prepareApplication({ application }) {
// @ts-ignore
application.getTypescriptKeyType = primaryKey => {
return getTSKeyType(primaryKey);
};
},
applicationDefauts({ application, applicationDefaults }) {
applicationDefaults({
__override__: true,
eslintConfigFile: app => `eslint.config.${app.packageJsonType === 'module' ? 'js' : 'mjs'}`,
webappEnumerationsDir: app => `${app.clientSrcDir}app/entities/enumerations/`,
angularLocaleId: app => app.nativeLanguageDefinition.angularLocale ?? defaultLanguage.angularLocale,
});

application.addPrettierExtensions?.(['html', 'css', 'scss']);
},
addNeedles({ source, application }) {
Expand All @@ -114,7 +116,6 @@ export default class AngularGenerator extends BaseApplicationGenerator<
const editCallback = addToEntitiesMenu(param);
this.editFile(filePath, { ignoreNonExisting }, editCallback);
};

source.addAdminRoute = (args: Omit<Parameters<typeof addRoute>[0], 'needle'>) =>
this.editFile(
`${application.srcMainWebapp}app/admin/admin.routes.ts`,
Expand Down Expand Up @@ -175,6 +176,26 @@ export default class AngularGenerator extends BaseApplicationGenerator<
...(entity.entityReadAuthority?.split(',') ?? []),
]),
});

entity.generateEntityClientEnumImports = fields => {
return getClientEnumImportsFormat(fields, ANGULAR);
};

entity.generateTestEntityPrimaryKey = (primaryKey, index) => {
return getTestEntityPrimaryKey(primaryKey, index);
};

entity.generateTypescriptTestEntity = (references, additionalFields) => {
return generateTestEntity(references, additionalFields);
};

entity.buildAngularFormPath = (reference, prefix = []) => {
return angularFormPath(reference, prefix);
};

entity.generateTestEntityId = (primaryKey, index = 0, wrapped = true) => {
return getTestEntityId(primaryKey, index, wrapped);
};
},
});
}
Expand Down Expand Up @@ -220,9 +241,9 @@ export default class AngularGenerator extends BaseApplicationGenerator<

get default() {
return this.asDefaultTaskGroup({
loadEntities() {
loadEntities({ application }) {
const entities = this.sharedData.getEntities().map(({ entity }) => entity);
this.localEntities = entities.filter(entity => !entity.builtIn && !entity.skipClient);
application.frontendEntities = entities.filter(entity => !entity.builtIn && !entity.skipClient);
},
queueTranslateTransform({ control, application }) {
const { enableTranslation, jhiPrefix } = application;
Expand Down Expand Up @@ -324,65 +345,4 @@ export default class AngularGenerator extends BaseApplicationGenerator<
get [BaseApplicationGenerator.END]() {
return this.delegateTasksToBlueprint(() => this.end);
}
/**
* Returns the typescript import section of enums referenced by all fields of the entity.
* @param fields returns the import of enums that are referenced by the fields
* @returns {typeImports:Map} the fields that potentially contains some enum types
*/
generateEntityClientEnumImports(fields) {
return getClientEnumImportsFormat(fields, ANGULAR);
}

/**
* Get the typescript type of a non-composite primary key
* @param primaryKey the primary key of the entity
* @returns {string} the typescript type.
*/
getTypescriptKeyType(primaryKey) {
return getTSKeyType(primaryKey);
}

/**
* generates a value for a primary key type
* @param primaryKey the primary key attribute (or its type) of the entity
* @param index an index to add salt to the value
* @param wrapped if the value should be within quotes
* @returns {string|number|string}
*/
generateTestEntityId(primaryKey, index = 0, wrapped = true) {
return getTestEntityId(primaryKey, index, wrapped);
}
/**
* @private
* Generate a test entity, for the PK references (when the PK is a composite, derived key)
*
* @param {any} primaryKey - primary key definition.
* @param {number} [index] - index of the primary key sample, pass undefined for a random key.
*/
generateTestEntityPrimaryKey(primaryKey, index) {
return getTestEntityPrimaryKey(primaryKey, index);
}

/**
* @private
* Generate a test entity instance with faked values.
*
* @param {any} references - references to other entities.
* @param {any} additionalFields - additional fields to add to the entity or with default values that overrides generated values.
*/
generateTypescriptTestEntity(references, additionalFields) {
return generateTestEntity(references, additionalFields);
}

/**
* @private
* Create a angular form path getter method of reference.
*
* @param {object} reference
* @param {string[]} prefix
* @return {string}
*/
buildAngularFormPath(reference, prefix = []) {
return angularFormPath(reference, prefix);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
limitations under the License.
-%>
<%_
const tsKeyId = this.generateTestEntityId(user.primaryKey.type);
const tsKeyId = generateTestEntityId(user.primaryKey.type);
_%>
import { TestBed } from '@angular/core/testing';
import { provideRouter, withComponentInputBinding } from '@angular/router';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
limitations under the License.
-%>
<%_
const tsKeyId = this.generateTestEntityId(user.primaryKey.type);
const tsKeyId = generateTestEntityId(user.primaryKey.type);
_%>
jest.mock('app/core/auth/account.service');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export default class UserManagementComponent implements OnInit {
this.userService.update({ ...user, activated: isActivated }).subscribe(() => this.loadAll());
}

trackIdentity(item: User): <%= this.getTypescriptKeyType(user.primaryKey.type) %> {
trackIdentity(item: User): <%= getTypescriptKeyType(user.primaryKey.type) %> {
return item.id!;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
limitations under the License.
-%>
<%_
const tsKeyId = this.generateTestEntityId(user.primaryKey.type);
const tsKeyId = generateTestEntityId(user.primaryKey.type);
_%>
import { TestBed } from '@angular/core/testing';
import { provideHttpClient, HttpErrorResponse } from '@angular/common/http';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
limitations under the License.
-%>
<%_
const tsKeyId = this.generateTestEntityId(user.primaryKey.type);
const tsKeyId = generateTestEntityId(user.primaryKey.type);
_%>
import { ComponentFixture, TestBed, waitForAsync, inject, fakeAsync, tick } from '@angular/core/testing';
import { provideHttpClient } from '@angular/common/http';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
limitations under the License.
-%>
<%_
const idType = this.getTypescriptKeyType(user.primaryKey.type);
const idType = getTypescriptKeyType(user.primaryKey.type);
_%>
export interface IUser {
id: <%= idType %> | null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
limitations under the License.
-%>
<%
const enumImports = this.generateEntityClientEnumImports(fields);
const enumImports = generateEntityClientEnumImports(fields);
%>
<%_ if (anyFieldIsDateDerived) { _%>
import dayjs from 'dayjs/esm';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
limitations under the License.
-%>
<%_
const enumImports = this.generateEntityClientEnumImports(fields);
const enumImports = generateEntityClientEnumImports(fields);
_%>
<%_ if (anyFieldIsDateDerived) { _%>
import dayjs from 'dayjs/esm';
Expand All @@ -29,14 +29,14 @@ import { <%- importedType %> } from '<%- importedPath %>';

import { I<%= entityAngularName %><% if (!readOnly && primaryKey) { %>, New<%= entityAngularName %><% } %> } from './<%= entityFileName %>.model';

export const sampleWithRequiredData: I<%= entityAngularName %> = <%- this.generateTypescriptTestEntity(fields.filter(field => field.id || field.fieldValidationRequired).map(field => field.reference)) %>;
export const sampleWithRequiredData: I<%= entityAngularName %> = <%- generateTypescriptTestEntity(fields.filter(field => field.id || field.fieldValidationRequired).map(field => field.reference)) %>;

export const sampleWithPartialData: I<%= entityAngularName %> = <%- this.generateTypescriptTestEntity(fields.filter(field => field.id || field.fieldValidationRequired || (!field.transient && faker.datatype.boolean())).map(field => field.reference)) %>;
export const sampleWithPartialData: I<%= entityAngularName %> = <%- generateTypescriptTestEntity(fields.filter(field => field.id || field.fieldValidationRequired || (!field.transient && faker.datatype.boolean())).map(field => field.reference)) %>;

export const sampleWithFullData: I<%= entityAngularName %> = <%- this.generateTypescriptTestEntity(fields.filter(field => !field.transient).map(field => field.reference)) %>;
export const sampleWithFullData: I<%= entityAngularName %> = <%- generateTypescriptTestEntity(fields.filter(field => !field.transient).map(field => field.reference)) %>;
<%_ if (!readOnly && primaryKey) { _%>

export const sampleWithNewData: New<%= entityAngularName %> = <%- this.generateTypescriptTestEntity(fields.filter(field => !field.id && field.fieldValidationRequired).map(field => field.reference), { [primaryKey.name]: null }) %>;
export const sampleWithNewData: New<%= entityAngularName %> = <%- generateTypescriptTestEntity(fields.filter(field => !field.id && field.fieldValidationRequired).map(field => field.reference), { [primaryKey.name]: null }) %>;

Object.freeze(sampleWithNewData);
<%_ } _%>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
limitations under the License.
-%>
<%_
const tsKeyId = this.generateTestEntityId(primaryKey.type);
const tsKeyId = generateTestEntityId(primaryKey.type);
_%>
jest.mock('@ng-bootstrap/ng-bootstrap');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
limitations under the License.
-%>
<%_
const tsKeyId = this.generateTestEntityId(primaryKey.type);
const testEntity = this.generateTestEntityPrimaryKey(primaryKey, 0);
const tsKeyId = generateTestEntityId(primaryKey.type);
const testEntity = generateTestEntityPrimaryKey(primaryKey, 0);
_%>
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { provideRouter, withComponentInputBinding } from '@angular/router';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
<%_
const entityArrayOptionalChainSymbol = '?.';
const order = 'desc';
const testEntityPrimaryKey = this.generateTestEntityPrimaryKey(primaryKey, 0);
const testEntityPrimaryKey2 = this.generateTestEntityPrimaryKey(primaryKey, 1);
const testEntityPrimaryKey = generateTestEntityPrimaryKey(primaryKey, 0);
const testEntityPrimaryKey2 = generateTestEntityPrimaryKey(primaryKey, 1);
_%>

import {
Expand Down Expand Up @@ -136,7 +136,7 @@ describe('<%= entityAngularName %> Management Component', () => {

describe('track<%= primaryKey.nameCapitalized %>', () => {
it('Should forward to <%= entityInstance %>Service', () => {
const entity = <%- this.generateTestEntityPrimaryKey(primaryKey, 0) %>;
const entity = <%- generateTestEntityPrimaryKey(primaryKey, 0) %>;
jest.spyOn(service, 'get<%= entityAngularName %>Identifier');
const <%= primaryKey.name %> = comp.track<%= primaryKey.nameCapitalized %>(entity);
expect(service.get<%= entityAngularName %>Identifier).toHaveBeenCalledWith(entity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
limitations under the License.
-%>
<%_
const tsKeyId = this.generateTestEntityId(primaryKey.type);
const tsKeyId = generateTestEntityId(primaryKey.type);
_%>
import { TestBed } from '@angular/core/testing';
import { provideHttpClient, HttpResponse } from '@angular/common/http';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
limitations under the License.
-%>
<%_
const tsKeyId = this.generateTestEntityId(primaryKey.type);
const enumImports = this.generateEntityClientEnumImports(fields);
const tsKeyId = generateTestEntityId(primaryKey.type);
const enumImports = generateEntityClientEnumImports(fields);
_%>
import { TestBed } from '@angular/core/testing';
import { provideHttpClientTesting, HttpTestingController } from '@angular/common/http/testing';
Expand Down Expand Up @@ -219,7 +219,7 @@ describe('<%= entityAngularName %> Service', () => {
});

it('Should return false if one entity is null', () => {
const entity1 = <%- this.generateTestEntityPrimaryKey(primaryKey, 0) %>;
const entity1 = <%- generateTestEntityPrimaryKey(primaryKey, 0) %>;
const entity2 = null;

const compareResult1 = service.compare<%= entityAngularName %>(entity1, entity2);
Expand All @@ -230,8 +230,8 @@ describe('<%= entityAngularName %> Service', () => {
});

it('Should return false if primaryKey differs', () => {
const entity1 = <%- this.generateTestEntityPrimaryKey(primaryKey, 0) %>;
const entity2 = <%- this.generateTestEntityPrimaryKey(primaryKey, 1) %>;
const entity1 = <%- generateTestEntityPrimaryKey(primaryKey, 0) %>;
const entity2 = <%- generateTestEntityPrimaryKey(primaryKey, 1) %>;

const compareResult1 = service.compare<%= entityAngularName %>(entity1, entity2);
const compareResult2 = service.compare<%= entityAngularName %>(entity2, entity1);
Expand All @@ -241,8 +241,8 @@ describe('<%= entityAngularName %> Service', () => {
});

it('Should return false if primaryKey matches', () => {
const entity1 = <%- this.generateTestEntityPrimaryKey(primaryKey, 0) %>;
const entity2 = <%- this.generateTestEntityPrimaryKey(primaryKey, 0) %>;
const entity1 = <%- generateTestEntityPrimaryKey(primaryKey, 0) %>;
const entity2 = <%- generateTestEntityPrimaryKey(primaryKey, 0) %>;

const compareResult1 = service.compare<%= entityAngularName %>(entity1, entity2);
const compareResult2 = service.compare<%= entityAngularName %>(entity2, entity1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ _%>
<option [ngValue]="null" selected></option>
}
<%_ } else { _%>
@if (editForm.get([<%- this.buildAngularFormPath(relationship.reference) %>])!.value == null) {
@if (editForm.get([<%- buildAngularFormPath(relationship.reference) %>])!.value == null) {
<option [ngValue]="null" selected></option>
}
<%_ } _%>
Expand All @@ -196,10 +196,10 @@ _%>
</div>
<%_ } _%>
<%_ if (relationship.relationshipValidate && relationship.persistableRelationship) { _%>
@if (editForm.get([<%- this.buildAngularFormPath(relationship.reference) %>])!.invalid && (editForm.get([<%- this.buildAngularFormPath(relationship.reference) %>])!.dirty || editForm.get([<%- this.buildAngularFormPath(relationship.reference) %>])!.touched)) {
@if (editForm.get([<%- buildAngularFormPath(relationship.reference) %>])!.invalid && (editForm.get([<%- buildAngularFormPath(relationship.reference) %>])!.dirty || editForm.get([<%- buildAngularFormPath(relationship.reference) %>])!.touched)) {
<div>
<%_ if (relationshipRequired) { _%>
@if (editForm.get([<%- this.buildAngularFormPath(relationship.reference) %>])?.errors?.required) {
@if (editForm.get([<%- buildAngularFormPath(relationship.reference) %>])?.errors?.required) {
<small class="form-text text-danger">__jhiTranslateTag__('entity.validation.required')</small>
}
<%_ } _%>
Expand Down
Loading

0 comments on commit 4948d95

Please sign in to comment.