@memberjunction/codegen-lib 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/advanced_generation.d.ts +3 -0
- package/dist/advanced_generation.d.ts.map +1 -1
- package/dist/advanced_generation.js +39 -26
- package/dist/advanced_generation.js.map +1 -1
- package/dist/angular_client_codegen.d.ts +45 -2
- package/dist/angular_client_codegen.d.ts.map +1 -1
- package/dist/angular_client_codegen.js +423 -399
- package/dist/angular_client_codegen.js.map +1 -1
- package/dist/createNewUser.d.ts +6 -1
- package/dist/createNewUser.d.ts.map +1 -1
- package/dist/createNewUser.js +68 -53
- package/dist/createNewUser.js.map +1 -1
- package/dist/dbSchema.d.ts +10 -3
- package/dist/dbSchema.d.ts.map +1 -1
- package/dist/dbSchema.js +144 -130
- package/dist/dbSchema.js.map +1 -1
- package/dist/entity_subclasses_codegen.d.ts +11 -6
- package/dist/entity_subclasses_codegen.d.ts.map +1 -1
- package/dist/entity_subclasses_codegen.js +144 -131
- package/dist/entity_subclasses_codegen.js.map +1 -1
- package/dist/graphql_server_codegen.d.ts +28 -5
- package/dist/graphql_server_codegen.d.ts.map +1 -1
- package/dist/graphql_server_codegen.js +552 -531
- package/dist/graphql_server_codegen.js.map +1 -1
- package/dist/logging.d.ts +20 -0
- package/dist/logging.d.ts.map +1 -1
- package/dist/logging.js +61 -26
- package/dist/logging.js.map +1 -1
- package/dist/manageMetadata.d.ts +128 -7
- package/dist/manageMetadata.d.ts.map +1 -1
- package/dist/manageMetadata.js +992 -898
- package/dist/manageMetadata.js.map +1 -1
- package/dist/runCodeGen.d.ts +16 -0
- package/dist/runCodeGen.d.ts.map +1 -1
- package/dist/runCodeGen.js +185 -140
- package/dist/runCodeGen.js.map +1 -1
- package/dist/runCommand.d.ts +7 -2
- package/dist/runCommand.d.ts.map +1 -1
- package/dist/runCommand.js +104 -90
- package/dist/runCommand.js.map +1 -1
- package/dist/sql.d.ts +21 -16
- package/dist/sql.d.ts.map +1 -1
- package/dist/sql.js +98 -87
- package/dist/sql.js.map +1 -1
- package/dist/sql_codegen.d.ts +56 -13
- package/dist/sql_codegen.d.ts.map +1 -1
- package/dist/sql_codegen.js +836 -795
- package/dist/sql_codegen.js.map +1 -1
- package/dist/util.js +0 -2
- package/dist/util.js.map +1 -1
- package/package.json +32 -32
- package/readme.md +2 -2
- package/dist/graphql_client_codegen.d.ts +0 -4
- package/dist/graphql_client_codegen.js +0 -161
- package/dist/graphql_client_codegen.js.map +0 -1
- package/dist/react_client_codegen.d.ts +0 -4
- package/dist/react_client_codegen.js +0 -147
- package/dist/react_client_codegen.js.map +0 -1
|
@@ -1,442 +1,466 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
2
8
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
9
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
10
|
};
|
|
5
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
12
|
+
exports.AngularClientGeneratorBase = exports.AngularFormSectionInfo = void 0;
|
|
7
13
|
const core_1 = require("@memberjunction/core");
|
|
8
14
|
const logging_1 = require("./logging");
|
|
9
15
|
const fs_1 = __importDefault(require("fs"));
|
|
10
16
|
const path_1 = __importDefault(require("path"));
|
|
11
17
|
const config_1 = require("./config");
|
|
18
|
+
const global_1 = require("@memberjunction/global");
|
|
12
19
|
class AngularFormSectionInfo {
|
|
13
20
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (
|
|
34
|
-
const
|
|
35
|
-
if (!fs_1.default.existsSync(
|
|
36
|
-
fs_1.default.mkdirSync(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
21
|
+
exports.AngularFormSectionInfo = AngularFormSectionInfo;
|
|
22
|
+
/**
|
|
23
|
+
* Base class for generating Angular client code, you can sub-class this class to create your own Angular client code generator logic
|
|
24
|
+
*/
|
|
25
|
+
let AngularClientGeneratorBase = class AngularClientGeneratorBase {
|
|
26
|
+
constructor() {
|
|
27
|
+
this.subModule_BaseName = 'GeneratedForms_SubModule_';
|
|
28
|
+
}
|
|
29
|
+
generateAngularCode(entities, directory, modulePrefix) {
|
|
30
|
+
try {
|
|
31
|
+
const entityPath = path_1.default.join(directory, 'Entities');
|
|
32
|
+
//const classMapEntries: string[] = [];
|
|
33
|
+
const componentImports = [];
|
|
34
|
+
const componentNames = [];
|
|
35
|
+
const sections = [];
|
|
36
|
+
if (!fs_1.default.existsSync(entityPath))
|
|
37
|
+
fs_1.default.mkdirSync(entityPath, { recursive: true }); // create the directory if it doesn't exist
|
|
38
|
+
for (let i = 0; i < entities.length; ++i) {
|
|
39
|
+
const entity = entities[i];
|
|
40
|
+
if (entity.PrimaryKey && entity.IncludeInAPI) {
|
|
41
|
+
const thisEntityPath = path_1.default.join(entityPath, entity.ClassName);
|
|
42
|
+
if (!fs_1.default.existsSync(thisEntityPath))
|
|
43
|
+
fs_1.default.mkdirSync(thisEntityPath, { recursive: true }); // create the directory if it doesn't exist
|
|
44
|
+
const { htmlCode, sections: entitySections } = this.generateSingleEntityHTMLForAngular(entity);
|
|
45
|
+
const tsCode = this.generateSingleEntityTypeScriptForAngular(entity, entitySections);
|
|
46
|
+
fs_1.default.writeFileSync(path_1.default.join(thisEntityPath, `${entity.ClassName.toLowerCase()}.form.component.ts`), tsCode);
|
|
47
|
+
fs_1.default.writeFileSync(path_1.default.join(thisEntityPath, `${entity.ClassName.toLowerCase()}.form.component.html`), htmlCode);
|
|
48
|
+
if (entitySections.length > 0) {
|
|
49
|
+
const sectionPath = path_1.default.join(thisEntityPath, 'sections');
|
|
50
|
+
if (!fs_1.default.existsSync(sectionPath))
|
|
51
|
+
fs_1.default.mkdirSync(sectionPath, { recursive: true }); // create the directory if it doesn't exist
|
|
52
|
+
for (let j = 0; j < entitySections.length; ++j) {
|
|
53
|
+
fs_1.default.writeFileSync(path_1.default.join(sectionPath, `${entitySections[j].FileName}`), entitySections[j].ComponentCode);
|
|
54
|
+
sections.push(entitySections[j]); // add the entity's secitons one by one to the master/global list of sections
|
|
55
|
+
}
|
|
40
56
|
}
|
|
57
|
+
const componentName = `${entity.ClassName}FormComponent`;
|
|
58
|
+
componentImports.push(`import { ${componentName}, Load${componentName} } from "./Entities/${entity.ClassName}/${entity.ClassName.toLowerCase()}.form.component";`);
|
|
59
|
+
componentNames.push(componentName);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
(0, logging_1.logStatus)(` Entity ${entity.Name} does not have a primary key or is not included in the API, skipping code generation for this entity`);
|
|
41
63
|
}
|
|
42
|
-
const componentName = `${entity.ClassName}FormComponent`;
|
|
43
|
-
componentImports.push(`import { ${componentName}, Load${componentName} } from "./Entities/${entity.ClassName}/${entity.ClassName.toLowerCase()}.form.component";`);
|
|
44
|
-
componentNames.push(componentName);
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
(0, logging_1.logStatus)(` Entity ${entity.Name} does not have a primary key or is not included in the API, skipping code generation for this entity`);
|
|
48
64
|
}
|
|
65
|
+
const maxComponentsPerModule = (0, config_1.outputOptionValue)('Angular', 'maxComponentsPerModule', 25);
|
|
66
|
+
const moduleCode = this.generateAngularModule(componentImports, componentNames, sections, modulePrefix, maxComponentsPerModule);
|
|
67
|
+
fs_1.default.writeFileSync(path_1.default.join(directory, 'generated-forms.module.ts'), moduleCode);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
(0, logging_1.logError)(err);
|
|
72
|
+
return false;
|
|
49
73
|
}
|
|
50
|
-
const maxComponentsPerModule = (0, config_1.outputOptionValue)('Angular', 'maxComponentsPerModule', 25);
|
|
51
|
-
const moduleCode = generateAngularModule(componentImports, componentNames, sections, modulePrefix, maxComponentsPerModule);
|
|
52
|
-
fs_1.default.writeFileSync(path_1.default.join(directory, 'generated-forms.module.ts'), moduleCode);
|
|
53
|
-
return true;
|
|
54
|
-
}
|
|
55
|
-
catch (err) {
|
|
56
|
-
(0, logging_1.logError)(err);
|
|
57
|
-
return false;
|
|
58
74
|
}
|
|
75
|
+
generateAngularModule(componentImports, componentNames, sections, modulePrefix, maxComponentsPerModule = 25) {
|
|
76
|
+
// this function will generate the overall code for the module file.
|
|
77
|
+
// there is one master angular module called GeneratedFormsModule, and this module will include all of the sub-modules
|
|
78
|
+
// the reason we do this is because of limits in the size of the types you can create in TypeScript and if we have a very large
|
|
79
|
+
// number of generated components for large systems, we can exceed that limit. So, we break the generated components into
|
|
80
|
+
// smaller modules and then import those modules into the master module, which is what this function does
|
|
81
|
+
// first, generate the sub-modules
|
|
82
|
+
const moduleCode = this.generateAngularModuleCode(componentNames, sections, maxComponentsPerModule, modulePrefix);
|
|
83
|
+
return `/**********************************************************************************
|
|
84
|
+
* GENERATED FILE - This file is automatically managed by the MJ CodeGen tool,
|
|
85
|
+
*
|
|
86
|
+
* DO NOT MODIFY THIS FILE - any changes you make will be wiped out the next time the file is
|
|
87
|
+
* generated
|
|
88
|
+
*
|
|
89
|
+
**********************************************************************************/
|
|
90
|
+
import { NgModule } from '@angular/core';
|
|
91
|
+
import { CommonModule } from '@angular/common';
|
|
92
|
+
import { FormsModule } from '@angular/forms';
|
|
93
|
+
|
|
94
|
+
// MemberJunction Imports
|
|
95
|
+
import { BaseFormsModule } from '@memberjunction/ng-base-forms';
|
|
96
|
+
import { UserViewGridModule } from '@memberjunction/ng-user-view-grid';
|
|
97
|
+
import { LinkDirectivesModule } from '@memberjunction/ng-link-directives';
|
|
98
|
+
import { MJTabStripModule } from "@memberjunction/ng-tabstrip";
|
|
99
|
+
import { ContainerDirectivesModule } from "@memberjunction/ng-container-directives";
|
|
100
|
+
|
|
101
|
+
// Kendo Imports
|
|
102
|
+
import { InputsModule } from '@progress/kendo-angular-inputs';
|
|
103
|
+
import { DateInputsModule } from '@progress/kendo-angular-dateinputs';
|
|
104
|
+
import { ButtonsModule } from '@progress/kendo-angular-buttons';
|
|
105
|
+
import { LayoutModule } from '@progress/kendo-angular-layout';
|
|
106
|
+
import { ComboBoxModule } from '@progress/kendo-angular-dropdowns';
|
|
107
|
+
import { DropDownListModule } from '@progress/kendo-angular-dropdowns';
|
|
108
|
+
|
|
109
|
+
// Import Generated Components
|
|
110
|
+
${componentImports.join('\n')}
|
|
111
|
+
${sections.map(s => `import { ${s.ClassName}, Load${s.ClassName} } from "./Entities/${s.EntityClassName}/sections/${s.FileNameWithoutExtension}"`).join('\n')}
|
|
112
|
+
|
|
113
|
+
${moduleCode}
|
|
114
|
+
|
|
115
|
+
export function Load${modulePrefix}GeneratedForms() {
|
|
116
|
+
// This function doesn't do much, but it calls each generated form's loader function
|
|
117
|
+
// which in turn calls the sections for that generated form. Ultimately, those bits of
|
|
118
|
+
// code do NOTHING - the point is to prevent the code from being eliminated during tree shaking
|
|
119
|
+
// since it is dynamically instantiated on demand, and the Angular compiler has no way to know that,
|
|
120
|
+
// in production builds tree shaking will eliminate the code unless we do this
|
|
121
|
+
${componentNames.map(c => `Load${c}();`).join('\n ')}
|
|
122
|
+
${sections.map(s => `Load${s.ClassName}();`).join('\n ')}
|
|
59
123
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
* DO NOT MODIFY THIS FILE - any changes you make will be wiped out the next time the file is
|
|
73
|
-
* generated
|
|
74
|
-
*
|
|
75
|
-
**********************************************************************************/
|
|
76
|
-
import { NgModule } from '@angular/core';
|
|
77
|
-
import { CommonModule } from '@angular/common';
|
|
78
|
-
import { FormsModule } from '@angular/forms';
|
|
79
|
-
|
|
80
|
-
// MemberJunction Imports
|
|
81
|
-
import { BaseFormsModule } from '@memberjunction/ng-base-forms';
|
|
82
|
-
import { UserViewGridModule } from '@memberjunction/ng-user-view-grid';
|
|
83
|
-
import { LinkDirectivesModule } from '@memberjunction/ng-link-directives';
|
|
84
|
-
import { MJTabStripModule } from "@memberjunction/ng-tabstrip";
|
|
85
|
-
import { ContainerDirectivesModule } from "@memberjunction/ng-container-directives";
|
|
86
|
-
|
|
87
|
-
// Kendo Imports
|
|
88
|
-
import { InputsModule } from '@progress/kendo-angular-inputs';
|
|
89
|
-
import { DateInputsModule } from '@progress/kendo-angular-dateinputs';
|
|
90
|
-
import { ButtonsModule } from '@progress/kendo-angular-buttons';
|
|
91
|
-
import { LayoutModule } from '@progress/kendo-angular-layout';
|
|
92
|
-
import { ComboBoxModule } from '@progress/kendo-angular-dropdowns';
|
|
93
|
-
import { DropDownListModule } from '@progress/kendo-angular-dropdowns';
|
|
94
|
-
|
|
95
|
-
// Import Generated Components
|
|
96
|
-
${componentImports.join('\n')}
|
|
97
|
-
${sections.map(s => `import { ${s.ClassName}, Load${s.ClassName} } from "./Entities/${s.EntityClassName}/sections/${s.FileNameWithoutExtension}"`).join('\n')}
|
|
98
|
-
|
|
99
|
-
${moduleCode}
|
|
100
|
-
|
|
101
|
-
export function Load${modulePrefix}GeneratedForms() {
|
|
102
|
-
// This function doesn't do much, but it calls each generated form's loader function
|
|
103
|
-
// which in turn calls the sections for that generated form. Ultimately, those bits of
|
|
104
|
-
// code do NOTHING - the point is to prevent the code from being eliminated during tree shaking
|
|
105
|
-
// since it is dynamically instantiated on demand, and the Angular compiler has no way to know that,
|
|
106
|
-
// in production builds tree shaking will eliminate the code unless we do this
|
|
107
|
-
${componentNames.map(c => `Load${c}();`).join('\n ')}
|
|
108
|
-
${sections.map(s => `Load${s.ClassName}();`).join('\n ')}
|
|
109
|
-
}
|
|
110
|
-
`;
|
|
111
|
-
}
|
|
112
|
-
function generateAngularModuleCode(componentNames, sections, maxComponentsPerModule, modulePrefix) {
|
|
113
|
-
// this function breaks up the componentNames and sections up, we only want to have a max of maxComponentsPerModule components per module (of components and/or sections, doesn't matter)
|
|
114
|
-
// so, we break up the list of components into sub-modules, and then generate the code for each sub-module
|
|
115
|
-
// iterate through the componentNames first, then after we've exhausted those, then iterate through the sections
|
|
116
|
-
const combinedArray = componentNames.concat(sections.map(s => s.ClassName));
|
|
117
|
-
const subModules = [];
|
|
118
|
-
let currentComponentCount = 0;
|
|
119
|
-
const subModuleStarter = `
|
|
120
|
-
@NgModule({
|
|
121
|
-
declarations: [
|
|
124
|
+
`;
|
|
125
|
+
}
|
|
126
|
+
generateAngularModuleCode(componentNames, sections, maxComponentsPerModule, modulePrefix) {
|
|
127
|
+
// this function breaks up the componentNames and sections up, we only want to have a max of maxComponentsPerModule components per module (of components and/or sections, doesn't matter)
|
|
128
|
+
// so, we break up the list of components into sub-modules, and then generate the code for each sub-module
|
|
129
|
+
// iterate through the componentNames first, then after we've exhausted those, then iterate through the sections
|
|
130
|
+
const combinedArray = componentNames.concat(sections.map(s => s.ClassName));
|
|
131
|
+
const subModules = [];
|
|
132
|
+
let currentComponentCount = 0;
|
|
133
|
+
const subModuleStarter = `
|
|
134
|
+
@NgModule({
|
|
135
|
+
declarations: [
|
|
122
136
|
`;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
137
|
+
let currentSubModuleCode = subModuleStarter;
|
|
138
|
+
// loop through the combined array which is the combination of the componentNames and the sections
|
|
139
|
+
for (let i = 0; i < combinedArray.length; ++i) {
|
|
140
|
+
currentSubModuleCode += (currentComponentCount === 0 ? '' : ',\n') + ' ' + combinedArray[i]; // prepend a comma if this isn't the first component in the module
|
|
141
|
+
if ((currentComponentCount === maxComponentsPerModule - 1) ||
|
|
142
|
+
(i === combinedArray.length - 1)) {
|
|
143
|
+
// we have reached the max number of components for this module, so generate the module code and reset the counters
|
|
144
|
+
currentSubModuleCode += this.generateSubModuleEnding(subModules.length);
|
|
145
|
+
subModules.push(currentSubModuleCode);
|
|
146
|
+
currentSubModuleCode = subModuleStarter;
|
|
147
|
+
currentComponentCount = 0;
|
|
148
|
+
}
|
|
149
|
+
else
|
|
150
|
+
currentComponentCount++;
|
|
134
151
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
]
|
|
144
|
-
|
|
145
|
-
${subModuleNames.join(',\n ')}
|
|
146
|
-
]
|
|
147
|
-
})
|
|
152
|
+
// at this point, we have a list of sub-modules that are generated into the subModules array, now we need to generate the main module that imports each of the sub-modules.
|
|
153
|
+
const subModuleNames = subModules.map((s, i) => `${this.SubModuleBaseName}${i}`);
|
|
154
|
+
const masterModuleCode = `
|
|
155
|
+
@NgModule({
|
|
156
|
+
declarations: [
|
|
157
|
+
],
|
|
158
|
+
imports: [
|
|
159
|
+
${subModuleNames.join(',\n ')}
|
|
160
|
+
]
|
|
161
|
+
})
|
|
148
162
|
export class ${modulePrefix}GeneratedFormsModule { }`;
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
163
|
+
// now we have the sub-modules generated into the subModules array, and we have the master module code generated into the masterModuleCode variable
|
|
164
|
+
// so we need to combine the two into a single return value and send back to the caller
|
|
165
|
+
return subModules.join('\n\n') + '\n\n' + masterModuleCode;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Get the base name for the sub-modules, override this method to change the base name. Defaults to 'GeneratedForms_SubModule_'
|
|
169
|
+
*/
|
|
170
|
+
get SubModuleBaseName() {
|
|
171
|
+
return this.subModule_BaseName;
|
|
172
|
+
}
|
|
173
|
+
generateSubModuleEnding(moduleNumber) {
|
|
174
|
+
return `],
|
|
175
|
+
imports: [
|
|
176
|
+
CommonModule,
|
|
177
|
+
FormsModule,
|
|
178
|
+
LayoutModule,
|
|
179
|
+
InputsModule,
|
|
180
|
+
ButtonsModule,
|
|
181
|
+
DateInputsModule,
|
|
182
|
+
UserViewGridModule,
|
|
183
|
+
LinkDirectivesModule,
|
|
184
|
+
BaseFormsModule,
|
|
185
|
+
MJTabStripModule,
|
|
186
|
+
ContainerDirectivesModule,
|
|
187
|
+
DropDownListModule,
|
|
188
|
+
ComboBoxModule
|
|
189
|
+
],
|
|
190
|
+
exports: [
|
|
191
|
+
]
|
|
192
|
+
})
|
|
193
|
+
export class ${this.SubModuleBaseName}${moduleNumber} { }
|
|
194
|
+
`;
|
|
195
|
+
}
|
|
196
|
+
generateSingleEntityTypeScriptForAngular(entity, sections) {
|
|
197
|
+
const entityObjectClass = entity.ClassName;
|
|
198
|
+
const sectionImports = sections.length > 0 ? sections.map(s => `import { Load${s.ClassName} } from "./sections/${s.FileNameWithoutExtension}"`).join('\n') : '';
|
|
199
|
+
return `import { Component } from '@angular/core';
|
|
200
|
+
import { ${entityObjectClass}Entity } from '${entity.SchemaName === config_1.mjCoreSchema ? '@memberjunction/core-entities' : 'mj_generatedentities'}';
|
|
201
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
202
|
+
import { BaseFormComponent } from '@memberjunction/ng-base-forms';
|
|
203
|
+
${sectionImports}
|
|
204
|
+
@RegisterClass(BaseFormComponent, '${entity.Name}') // Tell MemberJunction about this class
|
|
205
|
+
@Component({
|
|
206
|
+
selector: 'gen-${entity.ClassName.toLowerCase()}-form',
|
|
207
|
+
templateUrl: './${entity.ClassName.toLowerCase()}.form.component.html',
|
|
208
|
+
styleUrls: ['../../../../shared/form-styles.css']
|
|
209
|
+
})
|
|
210
|
+
export class ${entity.ClassName}FormComponent extends BaseFormComponent {
|
|
211
|
+
public record!: ${entityObjectClass}Entity;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function Load${entity.ClassName}FormComponent() {
|
|
215
|
+
${sections.map(s => `Load${s.ClassName}();`).join('\n ')}
|
|
176
216
|
}
|
|
177
|
-
function generateSingleEntityTypeScriptForAngular(entity, sections) {
|
|
178
|
-
const entityObjectClass = entity.ClassName;
|
|
179
|
-
const sectionImports = sections.length > 0 ? sections.map(s => `import { Load${s.ClassName} } from "./sections/${s.FileNameWithoutExtension}"`).join('\n') : '';
|
|
180
|
-
return `import { Component } from '@angular/core';
|
|
181
|
-
import { ${entityObjectClass}Entity } from '${entity.SchemaName === config_1.mjCoreSchema ? '@memberjunction/core-entities' : 'mj_generatedentities'}';
|
|
182
|
-
import { RegisterClass } from '@memberjunction/global';
|
|
183
|
-
import { BaseFormComponent } from '@memberjunction/ng-base-forms';
|
|
184
|
-
${sectionImports}
|
|
185
|
-
@RegisterClass(BaseFormComponent, '${entity.Name}') // Tell MemberJunction about this class
|
|
186
|
-
@Component({
|
|
187
|
-
selector: 'gen-${entity.ClassName.toLowerCase()}-form',
|
|
188
|
-
templateUrl: './${entity.ClassName.toLowerCase()}.form.component.html',
|
|
189
|
-
styleUrls: ['../../../../shared/form-styles.css']
|
|
190
|
-
})
|
|
191
|
-
export class ${entity.ClassName}FormComponent extends BaseFormComponent {
|
|
192
|
-
public record!: ${entityObjectClass}Entity;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
export function Load${entity.ClassName}FormComponent() {
|
|
196
|
-
${sections.map(s => `Load${s.ClassName}();`).join('\n ')}
|
|
197
|
-
}
|
|
198
217
|
`;
|
|
199
|
-
}
|
|
200
|
-
function entityHasTopArea(entity) {
|
|
201
|
-
return entity.Fields.some(f => f.GeneratedFormSectionType === core_1.GeneratedFormSectionType.Top);
|
|
202
|
-
}
|
|
203
|
-
function generateTopAreaHTMLForAngular(entity) {
|
|
204
|
-
if (!entityHasTopArea(entity))
|
|
205
|
-
return '';
|
|
206
|
-
else
|
|
207
|
-
return `<mj-form-section Entity="${entity.Name}" Section="top-area" [record]="record" [EditMode]="this.EditMode"></mj-form-section>`;
|
|
208
|
-
}
|
|
209
|
-
function AddSectionIfNeeded(entity, sections, type, name) {
|
|
210
|
-
const section = sections.find(s => s.Name === name && s.Type === type);
|
|
211
|
-
const fName = `${stripWhiteSpace(name.toLowerCase())}.component`;
|
|
212
|
-
if (!section)
|
|
213
|
-
sections.push({
|
|
214
|
-
Type: type,
|
|
215
|
-
Name: name,
|
|
216
|
-
FileName: `${fName}.ts`,
|
|
217
|
-
ComponentCode: '',
|
|
218
|
-
ClassName: `${entity.ClassName}${stripWhiteSpace(name)}Component`,
|
|
219
|
-
TabCode: '',
|
|
220
|
-
Fields: [],
|
|
221
|
-
EntityClassName: entity.ClassName,
|
|
222
|
-
FileNameWithoutExtension: fName
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
function generateAngularAdditionalSections(entity, startIndex) {
|
|
226
|
-
const sections = [];
|
|
227
|
-
let index = startIndex;
|
|
228
|
-
for (const field of entity.Fields) {
|
|
229
|
-
if (field.IncludeInGeneratedForm) {
|
|
230
|
-
if (field.GeneratedFormSectionType === core_1.GeneratedFormSectionType.Category && field.Category && field.Category !== '' && field.IncludeInGeneratedForm)
|
|
231
|
-
AddSectionIfNeeded(entity, sections, core_1.GeneratedFormSectionType.Category, field.Category);
|
|
232
|
-
else if (field.GeneratedFormSectionType === core_1.GeneratedFormSectionType.Details)
|
|
233
|
-
AddSectionIfNeeded(entity, sections, core_1.GeneratedFormSectionType.Details, "Details");
|
|
234
|
-
else if (field.GeneratedFormSectionType === core_1.GeneratedFormSectionType.Top)
|
|
235
|
-
AddSectionIfNeeded(entity, sections, core_1.GeneratedFormSectionType.Top, "Top");
|
|
236
|
-
}
|
|
237
218
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
let sectionName = '';
|
|
241
|
-
if (section.Type === core_1.GeneratedFormSectionType.Top) {
|
|
242
|
-
section.TabCode = generateTopAreaHTMLForAngular(entity);
|
|
243
|
-
sectionName = 'top-area';
|
|
244
|
-
}
|
|
245
|
-
else {
|
|
246
|
-
if (section.Type === core_1.GeneratedFormSectionType.Category)
|
|
247
|
-
sectionName = stripWhiteSpace(section.Name.toLowerCase());
|
|
248
|
-
else if (section.Type === core_1.GeneratedFormSectionType.Details)
|
|
249
|
-
sectionName = 'details';
|
|
250
|
-
section.TabCode = `
|
|
251
|
-
<mj-tab [TabSelected]="this.RegisterAndCheckIfCurrentTab('${section.Name}')">
|
|
252
|
-
${section.Name}
|
|
253
|
-
</mj-tab>
|
|
254
|
-
<mj-tab-body>
|
|
255
|
-
<mj-form-section Entity="${entity.Name}" Section="${stripWhiteSpace(section.Name.toLowerCase())}" [record]="record" [EditMode]="this.EditMode"></mj-form-section>
|
|
256
|
-
</mj-tab-body>`;
|
|
257
|
-
}
|
|
258
|
-
const { readModeHTML, editModeHTML } = generateSectionHTMLForAngular(entity, section);
|
|
259
|
-
section.ComponentCode = `import { Component, Input } from '@angular/core';
|
|
260
|
-
import { RegisterClass } from '@memberjunction/global';
|
|
261
|
-
import { BaseFormSectionComponent } from '@memberjunction/ng-base-forms';
|
|
262
|
-
import { ${entity.ClassName}Entity } from '${entity.SchemaName === config_1.mjCoreSchema ? '@memberjunction/core-entities' : 'mj_generatedentities'}';
|
|
263
|
-
|
|
264
|
-
@RegisterClass(BaseFormSectionComponent, '${entity.Name}.${sectionName}') // Tell MemberJunction about this class
|
|
265
|
-
@Component({
|
|
266
|
-
selector: 'gen-${entity.ClassName.toLowerCase()}-form-${sectionName}',
|
|
267
|
-
styleUrls: ['../../../../../shared/form-styles.css'],
|
|
268
|
-
template: \`<div *ngIf="this.record">
|
|
269
|
-
<div *ngIf="this.EditMode" class="record-form">
|
|
270
|
-
${editModeHTML}
|
|
271
|
-
</div>
|
|
272
|
-
<div *ngIf="!this.EditMode" class="record-form">
|
|
273
|
-
${readModeHTML}
|
|
274
|
-
</div>
|
|
275
|
-
</div>
|
|
276
|
-
\`
|
|
277
|
-
})
|
|
278
|
-
export class ${entity.ClassName}${stripWhiteSpace(section.Name)}Component extends BaseFormSectionComponent {
|
|
279
|
-
@Input() override record!: ${entity.ClassName}Entity;
|
|
280
|
-
@Input() override EditMode: boolean = false;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
export function Load${entity.ClassName}${stripWhiteSpace(section.Name)}Component() {
|
|
284
|
-
// does nothing, but called in order to prevent tree-shaking from eliminating this component from the build
|
|
285
|
-
}
|
|
286
|
-
`;
|
|
287
|
-
if (section.Type !== core_1.GeneratedFormSectionType.Top)
|
|
288
|
-
index++; // don't increment the tab index for TOP AREA, becuse it won't be rendered as a tab
|
|
219
|
+
entityHasTopArea(entity) {
|
|
220
|
+
return entity.Fields.some(f => f.GeneratedFormSectionType === core_1.GeneratedFormSectionType.Top);
|
|
289
221
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
222
|
+
generateTopAreaHTMLForAngular(entity) {
|
|
223
|
+
if (!this.entityHasTopArea(entity))
|
|
224
|
+
return '';
|
|
225
|
+
else
|
|
226
|
+
return `<mj-form-section Entity="${entity.Name}" Section="top-area" [record]="record" [EditMode]="this.EditMode"></mj-form-section>`;
|
|
227
|
+
}
|
|
228
|
+
AddSectionIfNeeded(entity, sections, type, name) {
|
|
229
|
+
const section = sections.find(s => s.Name === name && s.Type === type);
|
|
230
|
+
const fName = `${this.stripWhiteSpace(name.toLowerCase())}.component`;
|
|
231
|
+
if (!section)
|
|
232
|
+
sections.push({
|
|
233
|
+
Type: type,
|
|
234
|
+
Name: name,
|
|
235
|
+
FileName: `${fName}.ts`,
|
|
236
|
+
ComponentCode: '',
|
|
237
|
+
ClassName: `${entity.ClassName}${this.stripWhiteSpace(name)}Component`,
|
|
238
|
+
TabCode: '',
|
|
239
|
+
Fields: [],
|
|
240
|
+
EntityClassName: entity.ClassName,
|
|
241
|
+
FileNameWithoutExtension: fName
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
generateAngularAdditionalSections(entity, startIndex) {
|
|
245
|
+
const sections = [];
|
|
246
|
+
let index = startIndex;
|
|
247
|
+
for (const field of entity.Fields) {
|
|
248
|
+
if (field.IncludeInGeneratedForm) {
|
|
249
|
+
if (field.GeneratedFormSectionType === core_1.GeneratedFormSectionType.Category && field.Category && field.Category !== '' && field.IncludeInGeneratedForm)
|
|
250
|
+
this.AddSectionIfNeeded(entity, sections, core_1.GeneratedFormSectionType.Category, field.Category);
|
|
251
|
+
else if (field.GeneratedFormSectionType === core_1.GeneratedFormSectionType.Details)
|
|
252
|
+
this.AddSectionIfNeeded(entity, sections, core_1.GeneratedFormSectionType.Details, "Details");
|
|
253
|
+
else if (field.GeneratedFormSectionType === core_1.GeneratedFormSectionType.Top)
|
|
254
|
+
this.AddSectionIfNeeded(entity, sections, core_1.GeneratedFormSectionType.Top, "Top");
|
|
301
255
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
256
|
+
}
|
|
257
|
+
// now we have a distinct list of section names set, generate HTML for each section
|
|
258
|
+
for (const section of sections) {
|
|
259
|
+
let sectionName = '';
|
|
260
|
+
if (section.Type === core_1.GeneratedFormSectionType.Top) {
|
|
261
|
+
section.TabCode = this.generateTopAreaHTMLForAngular(entity);
|
|
262
|
+
sectionName = 'top-area';
|
|
305
263
|
}
|
|
306
|
-
else
|
|
307
|
-
|
|
308
|
-
|
|
264
|
+
else {
|
|
265
|
+
if (section.Type === core_1.GeneratedFormSectionType.Category)
|
|
266
|
+
sectionName = this.stripWhiteSpace(section.Name.toLowerCase());
|
|
267
|
+
else if (section.Type === core_1.GeneratedFormSectionType.Details)
|
|
268
|
+
sectionName = 'details';
|
|
269
|
+
section.TabCode = `
|
|
270
|
+
<mj-tab [TabSelected]="this.RegisterAndCheckIfCurrentTab('${section.Name}')">
|
|
271
|
+
${section.Name}
|
|
272
|
+
</mj-tab>
|
|
273
|
+
<mj-tab-body>
|
|
274
|
+
<mj-form-section Entity="${entity.Name}" Section="${this.stripWhiteSpace(section.Name.toLowerCase())}" [record]="record" [EditMode]="this.EditMode"></mj-form-section>
|
|
275
|
+
</mj-tab-body>`;
|
|
309
276
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
277
|
+
const { readModeHTML, editModeHTML } = this.generateSectionHTMLForAngular(entity, section);
|
|
278
|
+
section.ComponentCode = `import { Component, Input } from '@angular/core';
|
|
279
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
280
|
+
import { BaseFormSectionComponent } from '@memberjunction/ng-base-forms';
|
|
281
|
+
import { ${entity.ClassName}Entity } from '${entity.SchemaName === config_1.mjCoreSchema ? '@memberjunction/core-entities' : 'mj_generatedentities'}';
|
|
282
|
+
|
|
283
|
+
@RegisterClass(BaseFormSectionComponent, '${entity.Name}.${sectionName}') // Tell MemberJunction about this class
|
|
284
|
+
@Component({
|
|
285
|
+
selector: 'gen-${entity.ClassName.toLowerCase()}-form-${sectionName}',
|
|
286
|
+
styleUrls: ['../../../../../shared/form-styles.css'],
|
|
287
|
+
template: \`<div *ngIf="this.record">
|
|
288
|
+
<div *ngIf="this.EditMode" class="record-form">
|
|
289
|
+
${editModeHTML}
|
|
290
|
+
</div>
|
|
291
|
+
<div *ngIf="!this.EditMode" class="record-form">
|
|
292
|
+
${readModeHTML}
|
|
293
|
+
</div>
|
|
294
|
+
</div>
|
|
295
|
+
\`
|
|
296
|
+
})
|
|
297
|
+
export class ${entity.ClassName}${this.stripWhiteSpace(section.Name)}Component extends BaseFormSectionComponent {
|
|
298
|
+
@Input() override record!: ${entity.ClassName}Entity;
|
|
299
|
+
@Input() override EditMode: boolean = false;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export function Load${entity.ClassName}${this.stripWhiteSpace(section.Name)}Component() {
|
|
303
|
+
// does nothing, but called in order to prevent tree-shaking from eliminating this component from the build
|
|
304
|
+
}
|
|
305
|
+
`;
|
|
306
|
+
if (section.Type !== core_1.GeneratedFormSectionType.Top)
|
|
307
|
+
index++; // don't increment the tab index for TOP AREA, becuse it won't be rendered as a tab
|
|
308
|
+
}
|
|
309
|
+
return sections;
|
|
310
|
+
}
|
|
311
|
+
generateSectionHTMLForAngular(entity, section) {
|
|
312
|
+
let readModeHTML = '';
|
|
313
|
+
let editModeHTML = '';
|
|
314
|
+
for (const field of entity.Fields) {
|
|
315
|
+
if (field.IncludeInGeneratedForm) {
|
|
316
|
+
let bMatch = false;
|
|
317
|
+
if (field.GeneratedFormSectionType === core_1.GeneratedFormSectionType.Top && section.Type === core_1.GeneratedFormSectionType.Top) {
|
|
318
|
+
// match, include the field in the output
|
|
319
|
+
bMatch = true;
|
|
320
|
+
}
|
|
321
|
+
else if (field.GeneratedFormSectionType === core_1.GeneratedFormSectionType.Category && field.Category && section.Name && field.Category.trim().toLowerCase() === section.Name.trim().toLowerCase()) {
|
|
322
|
+
// match, include the field in the output
|
|
323
|
+
bMatch = true;
|
|
324
|
+
}
|
|
325
|
+
else if (field.GeneratedFormSectionType === core_1.GeneratedFormSectionType.Details && section.Type === core_1.GeneratedFormSectionType.Details) {
|
|
326
|
+
// match, include the field in the output
|
|
327
|
+
bMatch = true;
|
|
328
|
+
}
|
|
329
|
+
if (bMatch && field.Name.toLowerCase() !== 'id') {
|
|
330
|
+
section.Fields.push(field); // add the field to the section fields array
|
|
331
|
+
// next, generate HTML for the field
|
|
332
|
+
const linkDirective = field.RelatedEntity && field.RelatedEntity.length > 0 ? `mjFieldLink [record]="record" fieldName="${field.CodeName}" ` : '';
|
|
333
|
+
const linkNoTextDirective = field.RelatedEntity && field.RelatedEntity.length > 0 ? `mjFieldLink [record]="record" fieldName="${field.CodeName}" [replaceText]="false" ` : '';
|
|
334
|
+
const webLinkDirective = field.ExtendedType && field.ExtendedType.length > 0 && field.ExtendedType.trim().toLowerCase() === 'url' ? `mjWebLink [field]="record.GetFieldByName('${field.CodeName}')" ` : '';
|
|
335
|
+
const emailLinkDirective = field.ExtendedType && field.ExtendedType.length > 0 && field.ExtendedType.trim().toLowerCase() === 'email' ? `mjEmailLink [field]="record.GetFieldByName('${field.CodeName}')" ` : '';
|
|
336
|
+
readModeHTML += `
|
|
337
|
+
<div class="record-form-row">
|
|
338
|
+
<label class="fieldLabel">${field.DisplayNameOrName}</label>
|
|
339
|
+
<span ${linkDirective}${webLinkDirective}${emailLinkDirective}>{{FormatValue('${field.CodeName}', 0)}}</span>
|
|
321
340
|
</div>`;
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
341
|
+
let editControl = '';
|
|
342
|
+
let bReadOnly = false;
|
|
343
|
+
if (!field.ReadOnly) {
|
|
344
|
+
// first, check to see if we have a ValueListType != None, if so, generate a dropdown.
|
|
345
|
+
// If value list type is ListOrUserEntry, then generate a combobox, if ValueListType = List, then generate a dropdown
|
|
346
|
+
if (field.ValueListTypeEnum !== core_1.EntityFieldValueListType.None) {
|
|
347
|
+
// build the possible values list
|
|
348
|
+
const quotes = field.NeedsQuotes ? "'" : '';
|
|
349
|
+
const itemsString = '[' + field.EntityFieldValues.map(v => `${quotes}${v.Value}${quotes}`).join(', ') + ']';
|
|
350
|
+
if (field.ValueListTypeEnum === core_1.EntityFieldValueListType.ListOrUserEntry) {
|
|
351
|
+
// combo box
|
|
352
|
+
editControl = `<kendo-combobox [data]="${itemsString}" [allowCustom]="true" [(ngModel)]="record.${field.CodeName}${field.AllowsNull ? "!" : ""}" ></kendo-combobox>`;
|
|
353
|
+
}
|
|
354
|
+
else if (field.ValueListTypeEnum === core_1.EntityFieldValueListType.List) {
|
|
355
|
+
// dropdown
|
|
356
|
+
editControl = `<kendo-dropdownlist [data]="${itemsString}" [(ngModel)]="record.${field.CodeName}${field.AllowsNull ? "!" : ""}" ></kendo-dropdownlist>`;
|
|
357
|
+
}
|
|
334
358
|
}
|
|
335
|
-
else
|
|
336
|
-
//
|
|
337
|
-
|
|
359
|
+
else {
|
|
360
|
+
// no value list, generate a text box, checkbox, or date picker
|
|
361
|
+
if (field.TSType === core_1.EntityFieldTSType.Boolean)
|
|
362
|
+
editControl = `<input type="checkbox" [(ngModel)]="record.${field.CodeName}" kendoCheckBox />`;
|
|
363
|
+
else if (field.TSType === core_1.EntityFieldTSType.Date)
|
|
364
|
+
editControl = `<kendo-datepicker [(value)]="record.${field.CodeName}${field.AllowsNull ? "!" : ""}" ></kendo-datepicker>`; // if the field allows null, then add the ! to the end of the field name because the datepicker expects a date object, not null
|
|
365
|
+
else if (field.TSType === core_1.EntityFieldTSType.Number)
|
|
366
|
+
editControl = `<kendo-numerictextbox [(value)]="record.${field.CodeName}${field.AllowsNull ? "!" : ""}" ></kendo-numerictextbox>`; // if the field allows null, then add the ! to the end of the field name because the numerictextbox expects a number, not null
|
|
367
|
+
else if (field.TSType === core_1.EntityFieldTSType.String) {
|
|
368
|
+
if (field.MaxLength > 100)
|
|
369
|
+
editControl = `<kendo-textarea [(ngModel)]="record.${field.CodeName}" ></kendo-textarea>`;
|
|
370
|
+
else
|
|
371
|
+
editControl = `<kendo-textbox [(ngModel)]="record.${field.CodeName}" />`;
|
|
372
|
+
}
|
|
338
373
|
}
|
|
339
374
|
}
|
|
340
375
|
else {
|
|
341
|
-
//
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
else if (field.TSType === core_1.EntityFieldTSType.Date)
|
|
345
|
-
editControl = `<kendo-datepicker [(value)]="record.${field.CodeName}${field.AllowsNull ? "!" : ""}" ></kendo-datepicker>`; // if the field allows null, then add the ! to the end of the field name because the datepicker expects a date object, not null
|
|
346
|
-
else if (field.TSType === core_1.EntityFieldTSType.Number)
|
|
347
|
-
editControl = `<kendo-numerictextbox [(value)]="record.${field.CodeName}${field.AllowsNull ? "!" : ""}" ></kendo-numerictextbox>`; // if the field allows null, then add the ! to the end of the field name because the numerictextbox expects a number, not null
|
|
348
|
-
else if (field.TSType === core_1.EntityFieldTSType.String) {
|
|
349
|
-
if (field.MaxLength > 100)
|
|
350
|
-
editControl = `<kendo-textarea [(ngModel)]="record.${field.CodeName}" ></kendo-textarea>`;
|
|
351
|
-
else
|
|
352
|
-
editControl = `<kendo-textbox [(ngModel)]="record.${field.CodeName}" />`;
|
|
353
|
-
}
|
|
376
|
+
// read only field
|
|
377
|
+
editControl = `<span ${linkDirective}${webLinkDirective}${emailLinkDirective}>{{FormatValue('${field.CodeName}', 0)}}</span>`;
|
|
378
|
+
bReadOnly = true;
|
|
354
379
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
bReadOnly = true;
|
|
360
|
-
}
|
|
361
|
-
editModeHTML += `
|
|
362
|
-
<div class="record-form-row">
|
|
363
|
-
<label class="fieldLabel">${field.DisplayNameOrName}</label>
|
|
364
|
-
${editControl}
|
|
380
|
+
editModeHTML += `
|
|
381
|
+
<div class="record-form-row">
|
|
382
|
+
<label class="fieldLabel">${field.DisplayNameOrName}</label>
|
|
383
|
+
${editControl}
|
|
365
384
|
</div> `;
|
|
385
|
+
}
|
|
366
386
|
}
|
|
367
387
|
}
|
|
388
|
+
return { readModeHTML, editModeHTML };
|
|
368
389
|
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
[
|
|
383
|
-
|
|
384
|
-
[BottomMargin]="GridBottomMargin">
|
|
385
|
-
</mj-user-view-grid>
|
|
390
|
+
generateRelatedEntityTabs(entity, startIndex) {
|
|
391
|
+
const tabs = [];
|
|
392
|
+
let index = startIndex;
|
|
393
|
+
for (const relatedEntity of entity.RelatedEntities) {
|
|
394
|
+
const tabName = relatedEntity.DisplayName ? relatedEntity.DisplayName : relatedEntity.RelatedEntity;
|
|
395
|
+
tabs.push(`
|
|
396
|
+
<mj-tab [TabSelected]="this.RegisterAndCheckIfCurrentTab('${tabName}')">
|
|
397
|
+
${tabName}
|
|
398
|
+
</mj-tab>
|
|
399
|
+
<mj-tab-body>
|
|
400
|
+
<mj-user-view-grid [Params]="this.BuildRelationshipViewParamsByEntityName('${relatedEntity.RelatedEntity}')"
|
|
401
|
+
[AllowLoad]="this.IsCurrentTab('${tabName}')"
|
|
402
|
+
[EditMode]="this.GridEditMode()"
|
|
403
|
+
[BottomMargin]="GridBottomMargin">
|
|
404
|
+
</mj-user-view-grid>
|
|
386
405
|
</mj-tab-body>`);
|
|
387
|
-
|
|
406
|
+
index++;
|
|
407
|
+
}
|
|
408
|
+
return tabs;
|
|
388
409
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
return ` <div #topArea class="record-form-group">
|
|
423
|
-
${topArea}
|
|
410
|
+
stripWhiteSpace(s) {
|
|
411
|
+
return s.replace(/\s/g, '');
|
|
412
|
+
}
|
|
413
|
+
generateSingleEntityHTMLForAngular(entity) {
|
|
414
|
+
const topArea = this.generateTopAreaHTMLForAngular(entity);
|
|
415
|
+
const additionalSections = this.generateAngularAdditionalSections(entity, 0);
|
|
416
|
+
// calc ending index for additional sections so we can pass taht into the related entity tabs because they need to start incrementally up from there...
|
|
417
|
+
const endingIndex = additionalSections && additionalSections.length ? (topArea && topArea.length > 0 ? additionalSections.length - 1 : additionalSections.length) : 0;
|
|
418
|
+
const relatedEntitySections = this.generateRelatedEntityTabs(entity, endingIndex);
|
|
419
|
+
const htmlCode = topArea.length > 0 ? this.generateSingleEntityHTMLWithSplitterForAngular(topArea, additionalSections, relatedEntitySections) :
|
|
420
|
+
this.generateSingleEntityHTMLWithOUTSplitterForAngular(topArea, additionalSections, relatedEntitySections);
|
|
421
|
+
return { htmlCode, sections: additionalSections };
|
|
422
|
+
}
|
|
423
|
+
generateSingleEntityHTMLWithSplitterForAngular(topArea, additionalSections, relatedEntitySections) {
|
|
424
|
+
const htmlCode = `<div class="record-form-container" mjFillContainer [bottomMargin]="20" [rightMargin]="5">
|
|
425
|
+
<form *ngIf="record" class="record-form" #form="ngForm" mjFillContainer>
|
|
426
|
+
<mj-form-toolbar [form]="this"></mj-form-toolbar>
|
|
427
|
+
<kendo-splitter orientation="vertical" (layoutChange)="splitterLayoutChange()" mjFillContainer>
|
|
428
|
+
<kendo-splitter-pane [collapsible]="true" [size]="TopAreaHeight">
|
|
429
|
+
${this.innerTopAreaHTML(topArea)}
|
|
430
|
+
</kendo-splitter-pane>
|
|
431
|
+
<kendo-splitter-pane>
|
|
432
|
+
${this.innerTabStripHTML(additionalSections, relatedEntitySections)}
|
|
433
|
+
</kendo-splitter-pane>
|
|
434
|
+
</kendo-splitter>
|
|
435
|
+
</form>
|
|
436
|
+
</div>
|
|
437
|
+
`;
|
|
438
|
+
return htmlCode;
|
|
439
|
+
}
|
|
440
|
+
innerTopAreaHTML(topArea) {
|
|
441
|
+
return ` <div #topArea class="record-form-group">
|
|
442
|
+
${topArea}
|
|
424
443
|
</div>`;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
${additionalSections ? additionalSections.filter(s => s.Type !== core_1.GeneratedFormSectionType.Top).map(s => s.TabCode).join('\n ') : ''}
|
|
429
|
-
${relatedEntitySections ? relatedEntitySections.join('\n') : ''}
|
|
444
|
+
}
|
|
445
|
+
innerTabStripHTML(additionalSections, relatedEntitySections) {
|
|
446
|
+
return ` <mj-tabstrip (TabSelected)="onTabSelect($event.index)" mjFillContainer>
|
|
447
|
+
${additionalSections ? additionalSections.filter(s => s.Type !== core_1.GeneratedFormSectionType.Top).map(s => s.TabCode).join('\n ') : ''}
|
|
448
|
+
${relatedEntitySections ? relatedEntitySections.join('\n') : ''}
|
|
430
449
|
</mj-tabstrip>`;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
<form *ngIf="record" class="record-form" #form="ngForm" mjFillContainer>
|
|
435
|
-
${innerTopAreaHTML(topArea)}
|
|
436
|
-
${innerTabStripHTML(additionalSections, relatedEntitySections)}
|
|
437
|
-
</form>
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
}
|
|
450
|
+
}
|
|
451
|
+
generateSingleEntityHTMLWithOUTSplitterForAngular(topArea, additionalSections, relatedEntitySections) {
|
|
452
|
+
const htmlCode = `<div class="record-form-container" mjFillContainer [bottomMargin]="20" [rightMargin]="5">
|
|
453
|
+
<form *ngIf="record" class="record-form" #form="ngForm" mjFillContainer>
|
|
454
|
+
${this.innerTopAreaHTML(topArea)}
|
|
455
|
+
${this.innerTabStripHTML(additionalSections, relatedEntitySections)}
|
|
456
|
+
</form>
|
|
457
|
+
</div>
|
|
458
|
+
`;
|
|
459
|
+
return htmlCode;
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
exports.AngularClientGeneratorBase = AngularClientGeneratorBase;
|
|
463
|
+
exports.AngularClientGeneratorBase = AngularClientGeneratorBase = __decorate([
|
|
464
|
+
(0, global_1.RegisterClass)(AngularClientGeneratorBase)
|
|
465
|
+
], AngularClientGeneratorBase);
|
|
442
466
|
//# sourceMappingURL=angular_client_codegen.js.map
|