@khester/create-dynamics-app 1.1.0 → 2.1.0

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.
Files changed (210) hide show
  1. package/README.md +74 -0
  2. package/dist/artifacts/registry.d.ts +18 -0
  3. package/dist/artifacts/registry.d.ts.map +1 -0
  4. package/dist/artifacts/registry.js +340 -0
  5. package/dist/artifacts/registry.js.map +1 -0
  6. package/dist/artifacts/types.d.ts +122 -0
  7. package/dist/artifacts/types.d.ts.map +1 -0
  8. package/dist/artifacts/types.js +7 -0
  9. package/dist/artifacts/types.js.map +1 -0
  10. package/dist/artifacts/validators.d.ts +16 -0
  11. package/dist/artifacts/validators.d.ts.map +1 -0
  12. package/dist/artifacts/validators.js +45 -0
  13. package/dist/artifacts/validators.js.map +1 -0
  14. package/dist/fromDesign.d.ts +5 -0
  15. package/dist/fromDesign.d.ts.map +1 -0
  16. package/dist/fromDesign.js +98 -0
  17. package/dist/fromDesign.js.map +1 -0
  18. package/dist/index.js +129 -177
  19. package/dist/index.js.map +1 -1
  20. package/dist/injectDevTools.d.ts +28 -0
  21. package/dist/injectDevTools.d.ts.map +1 -0
  22. package/dist/injectDevTools.js +148 -0
  23. package/dist/injectDevTools.js.map +1 -0
  24. package/dist/scaffold.d.ts +48 -0
  25. package/dist/scaffold.d.ts.map +1 -0
  26. package/dist/scaffold.js +180 -0
  27. package/dist/scaffold.js.map +1 -0
  28. package/dist/templatePlan.d.ts +3 -0
  29. package/dist/templatePlan.d.ts.map +1 -0
  30. package/dist/templatePlan.js +43 -0
  31. package/dist/templatePlan.js.map +1 -0
  32. package/dist/utils/copyTemplate.d.ts +13 -1
  33. package/dist/utils/copyTemplate.d.ts.map +1 -1
  34. package/dist/utils/copyTemplate.js +98 -4
  35. package/dist/utils/copyTemplate.js.map +1 -1
  36. package/dist/utils/updatePackageJson.d.ts +11 -1
  37. package/dist/utils/updatePackageJson.d.ts.map +1 -1
  38. package/dist/utils/updatePackageJson.js +12 -10
  39. package/dist/utils/updatePackageJson.js.map +1 -1
  40. package/package.json +10 -7
  41. package/templates/_shared/dev-tools/auth/get-token.js +72 -0
  42. package/templates/_shared/dev-tools/dev/mock-xrm.js +42 -0
  43. package/templates/_shared/dev-tools/metadata-sync/index.js +152 -0
  44. package/templates/_shared/dev-tools/smoke/test-retrieve.js +44 -0
  45. package/templates/dialog-form/README.md +27 -0
  46. package/templates/dialog-form/_variants/App.v8.tsx +39 -0
  47. package/templates/dialog-form/_variants/App.v9.tsx +41 -0
  48. package/templates/dialog-form/gitignore +5 -0
  49. package/templates/dialog-form/package.json +27 -0
  50. package/templates/dialog-form/public/index.html +11 -0
  51. package/templates/dialog-form/src/index.tsx +10 -0
  52. package/templates/dialog-form/src/services/dataverse.ts +30 -0
  53. package/templates/dialog-form/tsconfig.json +15 -0
  54. package/templates/dialog-form/webpack.config.js +17 -0
  55. package/templates/grid-customizer/README.md +28 -0
  56. package/templates/grid-customizer/gitignore +4 -0
  57. package/templates/grid-customizer/package.json +25 -0
  58. package/templates/grid-customizer/src/GridCustomizer.ts +28 -0
  59. package/templates/grid-customizer/src/cell-renderers.tsx +35 -0
  60. package/templates/grid-customizer/src/index.ts +4 -0
  61. package/templates/grid-customizer/src/types/grid-types.ts +30 -0
  62. package/templates/grid-customizer/src/utils/color-utils.ts +24 -0
  63. package/templates/grid-customizer/tsconfig.json +15 -0
  64. package/templates/grid-customizer/webpack.config.js +17 -0
  65. package/templates/pcf-dataset/ControlManifest.Input.xml +16 -0
  66. package/templates/pcf-dataset/README.md +21 -0
  67. package/templates/pcf-dataset/gitignore +5 -0
  68. package/templates/pcf-dataset/index.ts +39 -0
  69. package/templates/pcf-dataset/package.json +30 -0
  70. package/templates/pcf-dataset/strings/{{componentName}}.1033.resx +47 -0
  71. package/templates/pcf-dataset/tsconfig.json +8 -0
  72. package/templates/pcf-dataset/{{componentName}}Component.tsx +39 -0
  73. package/templates/pcf-field/ControlManifest.Input.xml +17 -0
  74. package/templates/pcf-field/README.md +95 -0
  75. package/templates/pcf-field/_variants/ValueInput.boolean.tsx +24 -0
  76. package/templates/pcf-field/_variants/ValueInput.date.tsx +27 -0
  77. package/templates/pcf-field/_variants/ValueInput.number.tsx +35 -0
  78. package/templates/pcf-field/_variants/ValueInput.text.tsx +27 -0
  79. package/templates/pcf-field/gitignore +5 -0
  80. package/templates/pcf-field/index.ts +61 -0
  81. package/templates/pcf-field/package.json +30 -0
  82. package/templates/pcf-field/strings/{{componentName}}.1033.resx +47 -0
  83. package/templates/pcf-field/tsconfig.json +8 -0
  84. package/templates/pcf-field/{{componentName}}Component.tsx +35 -0
  85. package/templates/power-pages-starter/gitignore +5 -0
  86. package/templates/react-custom-page/gitignore +5 -0
  87. package/templates/{dynamics-365-starter → react-custom-page}/package.json +3 -3
  88. package/templates/react-custom-page/tools/metadata-sync/index.js +152 -0
  89. package/templates/static-web-app/README.md +36 -0
  90. package/templates/static-web-app/_variants/App.v8.tsx +32 -0
  91. package/templates/static-web-app/_variants/App.v9.tsx +31 -0
  92. package/templates/static-web-app/api/host.json +12 -0
  93. package/templates/static-web-app/api/package.json +19 -0
  94. package/templates/static-web-app/api/src/functions/hello.ts +16 -0
  95. package/templates/static-web-app/api/tsconfig.json +14 -0
  96. package/templates/static-web-app/frontend/index.html +12 -0
  97. package/templates/static-web-app/frontend/package.json +23 -0
  98. package/templates/static-web-app/frontend/src/index.tsx +8 -0
  99. package/templates/static-web-app/frontend/tsconfig.json +16 -0
  100. package/templates/static-web-app/frontend/vite.config.ts +13 -0
  101. package/templates/static-web-app/gitignore +8 -0
  102. package/templates/static-web-app/package.json +15 -0
  103. package/templates/static-web-app/staticwebapp.config.json +7 -0
  104. package/templates/teams-app/README.md +27 -0
  105. package/templates/teams-app/_variants/graph.off.ts +7 -0
  106. package/templates/teams-app/_variants/graph.on.ts +22 -0
  107. package/templates/teams-app/appPackage/manifest.json +26 -0
  108. package/templates/teams-app/gitignore +5 -0
  109. package/templates/teams-app/index.html +12 -0
  110. package/templates/teams-app/package.json +26 -0
  111. package/templates/teams-app/src/App.tsx +25 -0
  112. package/templates/teams-app/src/index.tsx +8 -0
  113. package/templates/teams-app/tsconfig.json +16 -0
  114. package/templates/teams-app/vite.config.ts +9 -0
  115. package/templates/web-resource/README.md +39 -0
  116. package/templates/web-resource/_variants/App.v8.tsx +29 -0
  117. package/templates/web-resource/_variants/App.v9.tsx +28 -0
  118. package/templates/web-resource/gitignore +5 -0
  119. package/templates/web-resource/package.json +27 -0
  120. package/templates/web-resource/public/index.html +11 -0
  121. package/templates/web-resource/src/index.tsx +10 -0
  122. package/templates/web-resource/src/services/dataverse.ts +30 -0
  123. package/templates/web-resource/tsconfig.json +15 -0
  124. package/templates/web-resource/webpack.config.js +17 -0
  125. package/dist/utils/consultingHelpers.d.ts +0 -13
  126. package/dist/utils/consultingHelpers.d.ts.map +0 -1
  127. package/dist/utils/consultingHelpers.js +0 -569
  128. package/dist/utils/consultingHelpers.js.map +0 -1
  129. package/templates/dynamics-365-starter/INTEGRATION_TEST_RESULTS.md +0 -302
  130. package/templates/dynamics-365-starter/PHASE_4_COMPLETION_SUMMARY.md +0 -305
  131. package/templates/dynamics-365-starter/deployment/QUICKSTART-MAC.md +0 -507
  132. package/templates/dynamics-365-starter/deployment/QUICKSTART-WINDOWS.md +0 -372
  133. package/templates/dynamics-365-starter/deployment/pipelines/README.md +0 -375
  134. package/templates/dynamics-365-starter/deployment/pipelines/azure-pipelines.yml +0 -330
  135. package/templates/dynamics-365-starter/deployment/pipelines/github-actions.yml +0 -422
  136. package/templates/dynamics-365-starter/deployment/pipelines/jenkins.groovy +0 -636
  137. package/templates/dynamics-365-starter/deployment/scripts/deploy.ps1 +0 -417
  138. package/templates/dynamics-365-starter/deployment/scripts/deploy.sh +0 -582
  139. package/templates/dynamics-365-starter/deployment/scripts/team-onboarding.ps1 +0 -486
  140. package/templates/dynamics-365-starter/deployment/scripts/team-onboarding.sh +0 -567
  141. package/templates/dynamics-365-starter/deployment/scripts/validate-setup.ps1 +0 -703
  142. package/templates/dynamics-365-starter/deployment/scripts/validate-setup.sh +0 -671
  143. package/templates/dynamics-365-starter/docs/team-standards/README.md +0 -273
  144. package/templates/dynamics-365-starter/docs/team-standards/client-onboarding.md +0 -577
  145. package/templates/dynamics-365-starter/docs/team-standards/code-review-checklist.md +0 -359
  146. package/templates/dynamics-365-starter/docs/team-standards/coding-standards.md +0 -700
  147. package/templates/dynamics-365-starter/docs/team-standards/cross-platform-team-guide.md +0 -736
  148. package/templates/dynamics-365-starter/docs/team-standards/development-workflows.md +0 -727
  149. package/templates/dynamics-365-starter/docs/troubleshooting/common-errors.md +0 -758
  150. package/templates/dynamics-365-starter/docs/troubleshooting/platform-specific-issues.md +0 -878
  151. package/templates/dynamics-365-starter/src/client-project-template/README.md +0 -234
  152. package/templates/dynamics-365-starter/src/client-project-template/config/client.template.json +0 -114
  153. package/templates/dynamics-365-starter/src/client-project-template/config/environments/template.json +0 -186
  154. package/templates/dynamics-365-starter/src/client-project-template/scripts/client-setup.js +0 -667
  155. package/templates/dynamics-365-starter/src/examples/README.md +0 -52
  156. package/templates/dynamics-365-starter/src/examples/component-examples/opportunity-management.tsx +0 -625
  157. package/templates/dynamics-365-starter/src/examples/entity-examples/opportunity-model.ts +0 -545
  158. package/templates/dynamics-365-starter/src/examples/integration-examples/custom-pcf-wrapper.tsx +0 -722
  159. package/templates/dynamics-365-starter/src/examples/workflow-examples/sales-workflow.ts +0 -662
  160. package/templates/dynamics-365-starter/src/page-templates/EntityDashboard.tsx +0 -519
  161. package/templates/dynamics-365-starter/src/page-templates/EntityDetailPage.tsx +0 -456
  162. package/templates/dynamics-365-starter/src/page-templates/EntityListPage.tsx +0 -406
  163. package/templates/dynamics-365-starter/src/page-templates/RelatedEntitiesPage.tsx +0 -578
  164. package/templates/dynamics-365-starter/src/page-templates/SearchPage.tsx +0 -629
  165. package/templates/dynamics-365-starter/tools/entity-generator/index.js +0 -168
  166. package/templates/dynamics-365-starter/tools/entity-generator/templates/constants.template.ts +0 -124
  167. package/templates/dynamics-365-starter/tools/entity-generator/templates/form.template.css +0 -283
  168. package/templates/dynamics-365-starter/tools/entity-generator/templates/form.template.tsx +0 -275
  169. package/templates/dynamics-365-starter/tools/entity-generator/templates/management.template.css +0 -204
  170. package/templates/dynamics-365-starter/tools/entity-generator/templates/management.template.tsx +0 -413
  171. package/templates/dynamics-365-starter/tools/entity-generator/templates/model.template.ts +0 -250
  172. package/templates/dynamics-365-starter/tools/metadata-sync/d365-client.js +0 -410
  173. package/templates/dynamics-365-starter/tools/metadata-sync/index.js +0 -512
  174. package/templates/dynamics-365-starter/tools/metadata-sync/type-generator.js +0 -675
  175. /package/templates/{dynamics-365-starter → react-custom-page}/README.md +0 -0
  176. /package/templates/{dynamics-365-starter → react-custom-page}/deployment/README.md +0 -0
  177. /package/templates/{dynamics-365-starter → react-custom-page}/docs/ARCHITECTURE_OVERVIEW.md +0 -0
  178. /package/templates/{dynamics-365-starter → react-custom-page}/docs/BEST_PRACTICES.md +0 -0
  179. /package/templates/{dynamics-365-starter → react-custom-page}/docs/MIGRATION_GUIDE.md +0 -0
  180. /package/templates/{dynamics-365-starter → react-custom-page}/public/index.html +0 -0
  181. /package/templates/{dynamics-365-starter → react-custom-page}/scripts/custom-build.js +0 -0
  182. /package/templates/{dynamics-365-starter → react-custom-page}/src/components/AccountForm.css +0 -0
  183. /package/templates/{dynamics-365-starter → react-custom-page}/src/components/AccountForm.tsx +0 -0
  184. /package/templates/{dynamics-365-starter → react-custom-page}/src/components/AccountManagement.css +0 -0
  185. /package/templates/{dynamics-365-starter → react-custom-page}/src/components/AccountManagement.tsx +0 -0
  186. /package/templates/{dynamics-365-starter → react-custom-page}/src/components/ContactForm.css +0 -0
  187. /package/templates/{dynamics-365-starter → react-custom-page}/src/components/ContactForm.tsx +0 -0
  188. /package/templates/{dynamics-365-starter → react-custom-page}/src/components/ContactManagement.css +0 -0
  189. /package/templates/{dynamics-365-starter → react-custom-page}/src/components/ContactManagement.tsx +0 -0
  190. /package/templates/{dynamics-365-starter → react-custom-page}/src/components/Logging/LogDialog.tsx +0 -0
  191. /package/templates/{dynamics-365-starter → react-custom-page}/src/components/Logging/LoggingContext.tsx +0 -0
  192. /package/templates/{dynamics-365-starter → react-custom-page}/src/components/Logging/LoggingDebugPanel.css +0 -0
  193. /package/templates/{dynamics-365-starter → react-custom-page}/src/components/Logging/LoggingDebugPanel.tsx +0 -0
  194. /package/templates/{dynamics-365-starter → react-custom-page}/src/components/Logging/LoggingProvider.tsx +0 -0
  195. /package/templates/{dynamics-365-starter → react-custom-page}/src/components/Logging/logger.ts +0 -0
  196. /package/templates/{dynamics-365-starter → react-custom-page}/src/constants/account.ts +0 -0
  197. /package/templates/{dynamics-365-starter → react-custom-page}/src/constants/contact.ts +0 -0
  198. /package/templates/{dynamics-365-starter → react-custom-page}/src/index.tsx +0 -0
  199. /package/templates/{dynamics-365-starter → react-custom-page}/src/models/Account.ts +0 -0
  200. /package/templates/{dynamics-365-starter → react-custom-page}/src/models/BaseEntity.ts +0 -0
  201. /package/templates/{dynamics-365-starter → react-custom-page}/src/models/Contact.ts +0 -0
  202. /package/templates/{dynamics-365-starter → react-custom-page}/src/pcf/ContactControlWrapper.tsx +0 -0
  203. /package/templates/{dynamics-365-starter → react-custom-page}/src/pcf/MultiEntityControlWrapper.tsx +0 -0
  204. /package/templates/{dynamics-365-starter → react-custom-page}/src/providers/DynamicsProvider.tsx +0 -0
  205. /package/templates/{dynamics-365-starter → react-custom-page}/src/services/MockApiService.ts +0 -0
  206. /package/templates/{dynamics-365-starter → react-custom-page}/src/services/ServiceFactory.ts +0 -0
  207. /package/templates/{dynamics-365-starter → react-custom-page}/src/services/XrmApiService.ts +0 -0
  208. /package/templates/{dynamics-365-starter → react-custom-page}/src/styles/index.css +0 -0
  209. /package/templates/{dynamics-365-starter → react-custom-page}/tsconfig.json +0 -0
  210. /package/templates/{dynamics-365-starter → react-custom-page}/webpack.config.js +0 -0
@@ -1,569 +0,0 @@
1
- import fs from 'fs-extra';
2
- import path from 'path';
3
- import chalk from 'chalk';
4
- import { exec } from 'child_process';
5
- import { promisify } from 'util';
6
- const execAsync = promisify(exec);
7
- /**
8
- * Generate entities using the entity generator
9
- */
10
- export async function generateEntities(projectPath, entities, generateSample) {
11
- console.log(chalk.cyan('🔧 Generating entities...'));
12
- const entityList = entities ? entities.split(',').map((e) => e.trim()) : [];
13
- if (generateSample) {
14
- // Generate sample entities
15
- const sampleEntities = [
16
- { name: 'opportunity', displayName: 'Opportunity' },
17
- { name: 'quote', displayName: 'Quote' },
18
- { name: 'invoice', displayName: 'Invoice' },
19
- ];
20
- for (const entity of sampleEntities) {
21
- try {
22
- await execAsync(`cd "${projectPath}" && npm run generate:entity -- --entity ${entity.name} --display-name "${entity.displayName}"`, { timeout: 30000 });
23
- console.log(chalk.green(` ✓ Generated ${entity.displayName} entity`));
24
- }
25
- catch (error) {
26
- console.log(chalk.yellow(` ⚠ Could not generate ${entity.displayName} entity (run manually later)`));
27
- }
28
- }
29
- }
30
- else if (entityList.length > 0) {
31
- // Generate specified entities
32
- for (const entityName of entityList) {
33
- try {
34
- const displayName = entityName.charAt(0).toUpperCase() + entityName.slice(1);
35
- await execAsync(`cd "${projectPath}" && npm run generate:entity -- --entity ${entityName} --display-name "${displayName}"`, { timeout: 30000 });
36
- console.log(chalk.green(` ✓ Generated ${displayName} entity`));
37
- }
38
- catch (error) {
39
- console.log(chalk.yellow(` ⚠ Could not generate ${entityName} entity (run manually later)`));
40
- }
41
- }
42
- }
43
- }
44
- /**
45
- * Generate page templates based on selection
46
- */
47
- export async function generatePageTemplates(projectPath, pageType, entities, generateSample) {
48
- console.log(chalk.cyan('📄 Setting up page templates...'));
49
- const templatesPath = path.join(projectPath, 'src', 'pages');
50
- await fs.ensureDir(templatesPath);
51
- // Create main pages based on selection
52
- if (pageType === 'all' || pageType === 'entity-list') {
53
- await createEntityListExample(templatesPath, entities, generateSample);
54
- }
55
- if (pageType === 'all' || pageType === 'entity-detail') {
56
- await createEntityDetailExample(templatesPath, entities, generateSample);
57
- }
58
- if (pageType === 'all' || pageType === 'entity-dashboard') {
59
- await createEntityDashboardExample(templatesPath, entities, generateSample);
60
- }
61
- if (pageType === 'all' || pageType === 'search') {
62
- await createSearchPageExample(templatesPath, entities, generateSample);
63
- }
64
- if (pageType === 'all' || pageType === 'related-entities') {
65
- await createRelatedEntitiesExample(templatesPath, entities, generateSample);
66
- }
67
- }
68
- /**
69
- * Customize project for deployment target
70
- */
71
- export async function customizeForDeployment(projectPath, deploymentTarget) {
72
- console.log(chalk.cyan(`🎯 Customizing for ${deploymentTarget} deployment...`));
73
- // Create environment-specific configuration
74
- const configPath = path.join(projectPath, 'src', 'config');
75
- await fs.ensureDir(configPath);
76
- const environmentConfig = {
77
- dev: {
78
- apiUrl: 'http://localhost:3000/api',
79
- logLevel: 'debug',
80
- enableMockServices: true,
81
- enableLogging: true,
82
- },
83
- test: {
84
- apiUrl: 'https://test.dynamics.com/api',
85
- logLevel: 'info',
86
- enableMockServices: false,
87
- enableLogging: true,
88
- },
89
- prod: {
90
- apiUrl: 'https://prod.dynamics.com/api',
91
- logLevel: 'error',
92
- enableMockServices: false,
93
- enableLogging: false,
94
- },
95
- };
96
- const config = environmentConfig[deploymentTarget] ||
97
- environmentConfig.dev;
98
- await fs.writeJSON(path.join(configPath, `${deploymentTarget}.json`), config, { spaces: 2 });
99
- // Create deployment scripts
100
- await createDeploymentScripts(projectPath, deploymentTarget);
101
- console.log(chalk.green(` ✓ Created ${deploymentTarget} configuration`));
102
- }
103
- // Helper functions for creating page examples
104
- async function createEntityListExample(templatesPath, entities, generateSample) {
105
- const entityName = getFirstEntity(entities, generateSample) || 'account';
106
- const entityPascal = entityName.charAt(0).toUpperCase() + entityName.slice(1);
107
- const content = `import React from 'react';
108
- import { EntityListPage, createStandardFetchXml } from '../page-templates/EntityListPage';
109
- import { ${entityPascal} } from '../models/${entityPascal}';
110
- import { ${entityPascal}Constants } from '../constants/${entityName}';
111
- import { IColumn } from '@fluentui/react';
112
-
113
- export const ${entityPascal}ListPage: React.FC = () => {
114
- const columns: IColumn[] = [
115
- {
116
- key: 'name',
117
- name: ${entityPascal}Constants.FieldDisplayNames[${entityPascal}Constants.PrimaryNameAttribute],
118
- fieldName: ${entityPascal}Constants.PrimaryNameAttribute,
119
- minWidth: 150,
120
- maxWidth: 250,
121
- isResizable: true
122
- },
123
- {
124
- key: 'description',
125
- name: ${entityPascal}Constants.FieldDisplayNames[${entityPascal}Constants.Description],
126
- fieldName: ${entityPascal}Constants.Description,
127
- minWidth: 200,
128
- maxWidth: 300,
129
- isResizable: true
130
- },
131
- {
132
- key: 'createdOn',
133
- name: 'Created On',
134
- fieldName: 'createdon',
135
- minWidth: 120,
136
- maxWidth: 180,
137
- isResizable: true,
138
- onRender: (item: ${entityPascal}) => (
139
- <span>{item.createdOn?.toLocaleDateString()}</span>
140
- )
141
- }
142
- ];
143
-
144
- const fetchXmlTemplate = createStandardFetchXml(
145
- ${entityPascal}Constants.EntityLogicalName,
146
- [
147
- ${entityPascal}Constants.PrimaryIdAttribute,
148
- ${entityPascal}Constants.PrimaryNameAttribute,
149
- ${entityPascal}Constants.Description,
150
- 'createdon'
151
- ],
152
- ${entityPascal}Constants.PrimaryNameAttribute
153
- );
154
-
155
- return (
156
- <EntityListPage<${entityPascal}>
157
- title="${entityPascal}s"
158
- entityLogicalName={${entityPascal}Constants.EntityLogicalName}
159
- entityClass={${entityPascal}}
160
- columns={columns}
161
- fetchXmlTemplate={fetchXmlTemplate}
162
- enableSearch={true}
163
- searchFields={[
164
- ${entityPascal}Constants.PrimaryNameAttribute,
165
- ${entityPascal}Constants.Description
166
- ]}
167
- />
168
- );
169
- };`;
170
- await fs.writeFile(path.join(templatesPath, `${entityPascal}ListPage.tsx`), content);
171
- console.log(chalk.green(` ✓ Created ${entityPascal}ListPage.tsx`));
172
- }
173
- async function createEntityDetailExample(templatesPath, entities, generateSample) {
174
- const entityName = getFirstEntity(entities, generateSample) || 'account';
175
- const entityPascal = entityName.charAt(0).toUpperCase() + entityName.slice(1);
176
- const content = `import React from 'react';
177
- import { EntityDetailPage, createDetailFetchXml } from '../page-templates/EntityDetailPage';
178
- import { ${entityPascal} } from '../models/${entityPascal}';
179
- import { ${entityPascal}Form } from '../components/${entityPascal}Form';
180
- import { ${entityPascal}Constants } from '../constants/${entityName}';
181
-
182
- interface ${entityPascal}DetailPageProps {
183
- ${entityName}Id: string;
184
- onBack?: () => void;
185
- }
186
-
187
- export const ${entityPascal}DetailPage: React.FC<${entityPascal}DetailPageProps> = ({
188
- ${entityName}Id,
189
- onBack
190
- }) => {
191
- const fetchXmlTemplate = createDetailFetchXml(
192
- ${entityPascal}Constants.EntityLogicalName,
193
- [
194
- ${entityPascal}Constants.PrimaryIdAttribute,
195
- ${entityPascal}Constants.PrimaryNameAttribute,
196
- ${entityPascal}Constants.Description,
197
- ${entityPascal}Constants.Priority,
198
- ${entityPascal}Constants.DueDate,
199
- ${entityPascal}Constants.Amount,
200
- ${entityPascal}Constants.IsActive,
201
- 'createdon',
202
- 'modifiedon'
203
- ]
204
- );
205
-
206
- const renderForm = (${entityName}: ${entityPascal} | null, onSave: (entity: ${entityPascal}) => void, readOnly?: boolean) => (
207
- <${entityPascal}Form
208
- ${entityName}={${entityName}}
209
- onSave={onSave}
210
- onCancel={() => {}}
211
- readOnly={readOnly}
212
- />
213
- );
214
-
215
- return (
216
- <EntityDetailPage<${entityPascal}>
217
- entityId={${entityName}Id}
218
- title="${entityPascal}"
219
- entityLogicalName={${entityPascal}Constants.EntityLogicalName}
220
- entityClass={${entityPascal}}
221
- fetchXmlTemplate={fetchXmlTemplate}
222
- renderForm={renderForm}
223
- onBack={onBack}
224
- enableTabs={true}
225
- />
226
- );
227
- };`;
228
- await fs.writeFile(path.join(templatesPath, `${entityPascal}DetailPage.tsx`), content);
229
- console.log(chalk.green(` ✓ Created ${entityPascal}DetailPage.tsx`));
230
- }
231
- async function createEntityDashboardExample(templatesPath, entities, generateSample) {
232
- const entityName = getFirstEntity(entities, generateSample) || 'account';
233
- const entityPascal = entityName.charAt(0).toUpperCase() + entityName.slice(1);
234
- const content = `import React from 'react';
235
- import { EntityDashboard, KPIHelpers } from '../page-templates/EntityDashboard';
236
- import { ${entityPascal} } from '../models/${entityPascal}';
237
- import { ${entityPascal}Constants } from '../constants/${entityName}';
238
- import { IColumn } from '@fluentui/react';
239
-
240
- export const ${entityPascal}Dashboard: React.FC = () => {
241
- const kpiQueries = {
242
- total: \`
243
- <fetch aggregate="true">
244
- <entity name="\${${entityPascal}Constants.EntityLogicalName}">
245
- <attribute name="\${${entityPascal}Constants.PrimaryIdAttribute}" alias="total_count" aggregate="count" />
246
- </entity>
247
- </fetch>\`,
248
- active: \`
249
- <fetch aggregate="true">
250
- <entity name="\${${entityPascal}Constants.EntityLogicalName}">
251
- <attribute name="\${${entityPascal}Constants.PrimaryIdAttribute}" alias="active_count" aggregate="count" />
252
- <filter>
253
- <condition attribute="\${${entityPascal}Constants.IsActive}" operator="eq" value="true" />
254
- </filter>
255
- </entity>
256
- </fetch>\`,
257
- thisMonth: \`
258
- <fetch aggregate="true">
259
- <entity name="\${${entityPascal}Constants.EntityLogicalName}">
260
- <attribute name="\${${entityPascal}Constants.PrimaryIdAttribute}" alias="month_count" aggregate="count" />
261
- <filter>
262
- <condition attribute="createdon" operator="this-month" />
263
- </filter>
264
- </entity>
265
- </fetch>\`
266
- };
267
-
268
- const recentItemsQuery = \`
269
- <fetch top="10">
270
- <entity name="\${${entityPascal}Constants.EntityLogicalName}">
271
- <attribute name="\${${entityPascal}Constants.PrimaryIdAttribute}" />
272
- <attribute name="\${${entityPascal}Constants.PrimaryNameAttribute}" />
273
- <attribute name="\${${entityPascal}Constants.Description}" />
274
- <attribute name="createdon" />
275
- <order attribute="createdon" descending="true" />
276
- </entity>
277
- </fetch>\`;
278
-
279
- const recentItemsColumns: IColumn[] = [
280
- {
281
- key: 'name',
282
- name: 'Name',
283
- fieldName: ${entityPascal}Constants.PrimaryNameAttribute,
284
- minWidth: 150,
285
- maxWidth: 250,
286
- isResizable: true
287
- },
288
- {
289
- key: 'description',
290
- name: 'Description',
291
- fieldName: ${entityPascal}Constants.Description,
292
- minWidth: 200,
293
- maxWidth: 300,
294
- isResizable: true
295
- },
296
- {
297
- key: 'createdOn',
298
- name: 'Created',
299
- fieldName: 'createdon',
300
- minWidth: 120,
301
- maxWidth: 180,
302
- isResizable: true,
303
- onRender: (item: ${entityPascal}) => (
304
- <span>{item.createdOn?.toLocaleDateString()}</span>
305
- )
306
- }
307
- ];
308
-
309
- const renderKPICards = (data: { [key: string]: any[] }) => {
310
- const totalCount = data.total?.[0]?.total_count || 0;
311
- const activeCount = data.active?.[0]?.active_count || 0;
312
- const monthCount = data.thisMonth?.[0]?.month_count || 0;
313
-
314
- return [
315
- {
316
- title: 'Total ${entityPascal}s',
317
- value: KPIHelpers.formatNumber(totalCount),
318
- icon: '📊',
319
- color: '#0078d4'
320
- },
321
- {
322
- title: 'Active ${entityPascal}s',
323
- value: KPIHelpers.formatNumber(activeCount),
324
- trend: 'up',
325
- trendValue: KPIHelpers.percentage(activeCount, totalCount),
326
- icon: '✅',
327
- color: '#107c10'
328
- },
329
- {
330
- title: 'This Month',
331
- value: KPIHelpers.formatNumber(monthCount),
332
- icon: '📅',
333
- color: '#ff8c00'
334
- }
335
- ];
336
- };
337
-
338
- return (
339
- <EntityDashboard<${entityPascal}>
340
- title="${entityPascal}"
341
- entityLogicalName={${entityPascal}Constants.EntityLogicalName}
342
- entityClass={${entityPascal}}
343
- kpiQueries={kpiQueries}
344
- recentItemsQuery={recentItemsQuery}
345
- recentItemsColumns={recentItemsColumns}
346
- renderKPICards={renderKPICards}
347
- refreshInterval={300}
348
- />
349
- );
350
- };`;
351
- await fs.writeFile(path.join(templatesPath, `${entityPascal}Dashboard.tsx`), content);
352
- console.log(chalk.green(` ✓ Created ${entityPascal}Dashboard.tsx`));
353
- }
354
- async function createSearchPageExample(templatesPath, entities, generateSample) {
355
- const entityList = entities
356
- ? entities.split(',').map((e) => e.trim())
357
- : generateSample
358
- ? ['opportunity', 'quote', 'invoice']
359
- : ['account', 'contact'];
360
- const content = `import React from 'react';
361
- import { SearchPage, createSearchFetchXml } from '../page-templates/SearchPage';
362
- ${entityList
363
- .map((entity) => {
364
- const entityPascal = entity.charAt(0).toUpperCase() + entity.slice(1);
365
- return `import { ${entityPascal} } from '../models/${entityPascal}';
366
- import { ${entityPascal}Constants } from '../constants/${entity}';`;
367
- })
368
- .join('\n')}
369
- import { IColumn } from '@fluentui/react';
370
-
371
- export const GlobalSearchPage: React.FC = () => {
372
- const entityConfigs = [
373
- ${entityList
374
- .map((entity) => {
375
- const entityPascal = entity.charAt(0).toUpperCase() + entity.slice(1);
376
- return ` {
377
- key: '${entity}',
378
- title: '${entityPascal}s',
379
- entityLogicalName: ${entityPascal}Constants.EntityLogicalName,
380
- entityClass: ${entityPascal},
381
- searchFields: [
382
- ${entityPascal}Constants.PrimaryNameAttribute,
383
- ${entityPascal}Constants.Description
384
- ],
385
- fetchXmlTemplate: createSearchFetchXml(
386
- ${entityPascal}Constants.EntityLogicalName,
387
- [
388
- ${entityPascal}Constants.PrimaryIdAttribute,
389
- ${entityPascal}Constants.PrimaryNameAttribute,
390
- ${entityPascal}Constants.Description,
391
- 'createdon'
392
- ],
393
- [
394
- ${entityPascal}Constants.PrimaryNameAttribute,
395
- ${entityPascal}Constants.Description
396
- ]
397
- ),
398
- columns: [
399
- {
400
- key: 'name',
401
- name: 'Name',
402
- fieldName: ${entityPascal}Constants.PrimaryNameAttribute,
403
- minWidth: 150,
404
- maxWidth: 250,
405
- isResizable: true
406
- },
407
- {
408
- key: 'description',
409
- name: 'Description',
410
- fieldName: ${entityPascal}Constants.Description,
411
- minWidth: 200,
412
- maxWidth: 300,
413
- isResizable: true
414
- }
415
- ],
416
- icon: '📊',
417
- color: '#0078d4'
418
- }`;
419
- })
420
- .join(',\n')}
421
- ];
422
-
423
- return (
424
- <SearchPage
425
- title="Global Search"
426
- entityConfigs={entityConfigs}
427
- enableAdvancedSearch={true}
428
- enableSavedSearches={false}
429
- placeholder="Search across all entities..."
430
- minSearchLength={3}
431
- />
432
- );
433
- };`;
434
- await fs.writeFile(path.join(templatesPath, 'GlobalSearchPage.tsx'), content);
435
- console.log(chalk.green(' ✓ Created GlobalSearchPage.tsx'));
436
- }
437
- async function createRelatedEntitiesExample(templatesPath, entities, generateSample) {
438
- const parentEntity = getFirstEntity(entities, generateSample) || 'account';
439
- const parentPascal = parentEntity.charAt(0).toUpperCase() + parentEntity.slice(1);
440
- const content = `import React from 'react';
441
- import { RelatedEntitiesPage, createRelatedEntityFetchXml } from '../page-templates/RelatedEntitiesPage';
442
- import { ${parentPascal} } from '../models/${parentPascal}';
443
- import { Contact } from '../models/Contact';
444
- import { ContactConstants } from '../constants/contact';
445
- import { ContactForm } from '../components/ContactForm';
446
-
447
- interface ${parentPascal}RelatedPageProps {
448
- ${parentEntity}: ${parentPascal};
449
- onBack?: () => void;
450
- }
451
-
452
- export const ${parentPascal}RelatedPage: React.FC<${parentPascal}RelatedPageProps> = ({
453
- ${parentEntity},
454
- onBack
455
- }) => {
456
- const relatedEntityConfigs = [
457
- {
458
- key: 'contacts',
459
- title: 'Contacts',
460
- entityLogicalName: ContactConstants.EntityLogicalName,
461
- entityClass: Contact,
462
- relationshipField: ContactConstants.AccountId,
463
- fetchXmlTemplate: createRelatedEntityFetchXml(
464
- ContactConstants.EntityLogicalName,
465
- [
466
- ContactConstants.PrimaryIdAttribute,
467
- ContactConstants.PrimaryNameAttribute,
468
- ContactConstants.Email,
469
- ContactConstants.Phone,
470
- 'createdon'
471
- ],
472
- ContactConstants.AccountId
473
- ),
474
- columns: [
475
- {
476
- key: 'name',
477
- name: 'Full Name',
478
- fieldName: ContactConstants.PrimaryNameAttribute,
479
- minWidth: 150,
480
- maxWidth: 250,
481
- isResizable: true
482
- },
483
- {
484
- key: 'email',
485
- name: 'Email',
486
- fieldName: ContactConstants.Email,
487
- minWidth: 200,
488
- maxWidth: 300,
489
- isResizable: true
490
- },
491
- {
492
- key: 'phone',
493
- name: 'Phone',
494
- fieldName: ContactConstants.Phone,
495
- minWidth: 120,
496
- maxWidth: 180,
497
- isResizable: true
498
- }
499
- ],
500
- allowCreate: true,
501
- allowEdit: true,
502
- allowDelete: true,
503
- renderForm: (contact: Contact | null, onSave: (entity: Contact) => void, onCancel: () => void) => (
504
- <ContactForm
505
- contact={contact}
506
- onSave={async (contactData) => {
507
- const contactEntity = contact ? Object.assign(contact, contactData) : new Contact(contactData);
508
- await onSave(contactEntity);
509
- }}
510
- onCancel={onCancel}
511
- />
512
- )
513
- }
514
- ];
515
-
516
- return (
517
- <RelatedEntitiesPage
518
- parentEntity={${parentEntity}}
519
- parentTitle="${parentPascal}"
520
- relatedEntityConfigs={relatedEntityConfigs}
521
- onBack={onBack}
522
- enableSearch={true}
523
- />
524
- );
525
- };`;
526
- await fs.writeFile(path.join(templatesPath, `${parentPascal}RelatedPage.tsx`), content);
527
- console.log(chalk.green(` ✓ Created ${parentPascal}RelatedPage.tsx`));
528
- }
529
- async function createDeploymentScripts(projectPath, deploymentTarget) {
530
- const scriptsPath = path.join(projectPath, 'scripts');
531
- await fs.ensureDir(scriptsPath);
532
- const deployScript = `#!/bin/bash
533
- # Deployment script for ${deploymentTarget} environment
534
- # Auto-generated by create-dynamics-app
535
-
536
- echo "🚀 Deploying to ${deploymentTarget} environment..."
537
-
538
- # Build for production
539
- npm run build:prod
540
-
541
- # Run quality checks
542
- npm run quality
543
-
544
- # Deploy based on target
545
- if [ "$1" = "${deploymentTarget}" ]; then
546
- echo "✅ Ready for ${deploymentTarget} deployment"
547
- echo "📋 Next steps:"
548
- echo " 1. Upload dist/ contents to Dynamics 365 web resources"
549
- echo " 2. Update custom page configurations"
550
- echo " 3. Test in ${deploymentTarget} environment"
551
- else
552
- echo "❌ Invalid deployment target. Use: ${deploymentTarget}"
553
- exit 1
554
- fi
555
- `;
556
- await fs.writeFile(path.join(scriptsPath, `deploy-${deploymentTarget}.sh`), deployScript);
557
- await fs.chmod(path.join(scriptsPath, `deploy-${deploymentTarget}.sh`), '755');
558
- }
559
- function getFirstEntity(entities, generateSample) {
560
- if (entities) {
561
- const entityList = entities.split(',').map((e) => e.trim());
562
- return entityList[0] || null;
563
- }
564
- if (generateSample) {
565
- return 'opportunity';
566
- }
567
- return null;
568
- }
569
- //# sourceMappingURL=consultingHelpers.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"consultingHelpers.js","sourceRoot":"","sources":["../../src/utils/consultingHelpers.ts"],"names":[],"mappings":"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"}