@khester/create-dynamics-app 2.10.0 → 3.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 (82) hide show
  1. package/README.md +28 -3
  2. package/dist/artifacts/registry.d.ts +7 -5
  3. package/dist/artifacts/registry.d.ts.map +1 -1
  4. package/dist/artifacts/registry.js +82 -27
  5. package/dist/artifacts/registry.js.map +1 -1
  6. package/dist/artifacts/types.d.ts +15 -8
  7. package/dist/artifacts/types.d.ts.map +1 -1
  8. package/dist/index.js +7 -5
  9. package/dist/index.js.map +1 -1
  10. package/dist/scaffold.d.ts.map +1 -1
  11. package/dist/scaffold.js +9 -4
  12. package/dist/scaffold.js.map +1 -1
  13. package/dist/templatePlan.d.ts.map +1 -1
  14. package/dist/templatePlan.js +20 -3
  15. package/dist/templatePlan.js.map +1 -1
  16. package/dist/utils/copyTemplate.d.ts +1 -1
  17. package/dist/utils/copyTemplate.d.ts.map +1 -1
  18. package/dist/utils/copyTemplate.js +5 -1
  19. package/dist/utils/copyTemplate.js.map +1 -1
  20. package/package.json +1 -1
  21. package/templates/_shared/dataverse-seam/XrmApiService.ts +26 -5
  22. package/templates/host-swap/README.md +57 -2
  23. package/templates/host-swap/_variants/host.custom-page/src/App.tsx +9 -5
  24. package/templates/host-swap/_variants/host.pcf/ControlManifest.Input.xml +26 -2
  25. package/templates/host-swap/_variants/host.pcf/gitignore +7 -0
  26. package/templates/host-swap/_variants/host.pcf/index.ts +21 -3
  27. package/templates/host-swap/_variants/host.pcf/package.json +20 -4
  28. package/templates/host-swap/_variants/host.pcf/{{componentName}}.pcfproj +67 -0
  29. package/templates/host-swap/_variants/host.web-resource/src/App.tsx +5 -1
  30. package/templates/host-swap/src/Component.tsx +54 -7
  31. package/templates/host-swap/src/useHostWidth.ts +53 -0
  32. package/templates/pcf-dataset/dev/harness/dataverse.ts +82 -0
  33. package/templates/pcf-dataset/dev/index.html +20 -0
  34. package/templates/pcf-dataset/dev/main.tsx +190 -0
  35. package/templates/pcf-dataset/dev/vite-env.d.ts +1 -0
  36. package/templates/pcf-dataset/env.local.example +24 -0
  37. package/templates/pcf-dataset/eslintrc.json +11 -0
  38. package/templates/pcf-dataset/gitignore +4 -0
  39. package/templates/pcf-dataset/package.json +18 -8
  40. package/templates/pcf-dataset/pcfconfig.json +3 -0
  41. package/templates/pcf-dataset/tsconfig.dev.json +15 -0
  42. package/templates/pcf-dataset/tsconfig.json +11 -2
  43. package/templates/pcf-dataset/vite.config.ts +63 -0
  44. package/templates/pcf-dataset/{{componentName}}/ControlManifest.Input.xml +45 -0
  45. package/templates/pcf-dataset/{{componentName}}/{{componentName}}App.tsx +64 -0
  46. package/templates/pcf-dataset/{{{componentName}}Component.tsx → {{componentName}}/{{componentName}}Component.tsx} +9 -46
  47. package/templates/pcf-field/eslintrc.json +11 -0
  48. package/templates/pcf-field/package.json +1 -0
  49. package/templates/pcf-field/pcfconfig.json +3 -0
  50. package/templates/pcf-field/{{componentName}}/ControlManifest.Input.xml +42 -0
  51. package/templates/power-pages-island/README.md +93 -0
  52. package/templates/power-pages-island/package.json +27 -0
  53. package/templates/power-pages-island/public/index.html +13 -0
  54. package/templates/power-pages-island/src/App.tsx +37 -0
  55. package/templates/power-pages-island/src/Component.tsx +136 -0
  56. package/templates/power-pages-island/src/core/services/MockApiService.ts +58 -0
  57. package/templates/power-pages-island/src/core/services/portalSeam.assert.ts +14 -0
  58. package/templates/power-pages-island/src/island-env.d.ts +12 -0
  59. package/templates/power-pages-island/src/islands.tsx +38 -0
  60. package/templates/power-pages-island/src/useHostWidth.ts +53 -0
  61. package/templates/power-pages-island/tsconfig.json +15 -0
  62. package/templates/power-pages-island/webpack.config.js +22 -0
  63. package/templates/react-custom-page/tools/deploy/deploy-webresource.cjs +8 -2
  64. package/templates/pcf-dataset/ControlManifest.Input.xml +0 -16
  65. package/templates/pcf-field/ControlManifest.Input.xml +0 -17
  66. package/templates/power-pages-starter/.env.example +0 -6
  67. package/templates/power-pages-starter/README.md +0 -95
  68. package/templates/power-pages-starter/package.json +0 -43
  69. package/templates/power-pages-starter/public/index.html +0 -15
  70. package/templates/power-pages-starter/src/components/ContactForm.css +0 -84
  71. package/templates/power-pages-starter/src/components/ContactForm.tsx +0 -258
  72. package/templates/power-pages-starter/src/index.tsx +0 -32
  73. package/templates/power-pages-starter/src/providers/PowerPagesProvider.tsx +0 -162
  74. package/templates/power-pages-starter/src/styles/index.css +0 -76
  75. package/templates/power-pages-starter/tsconfig.json +0 -20
  76. package/templates/power-pages-starter/webpack.config.js +0 -57
  77. package/templates/pcf-dataset/{index.ts → {{componentName}}/index.ts} +0 -0
  78. package/templates/pcf-dataset/{strings → {{componentName}}/strings}/{{componentName}}.1033.resx +0 -0
  79. package/templates/pcf-field/{index.ts → {{componentName}}/index.ts} +0 -0
  80. package/templates/pcf-field/{strings → {{componentName}}/strings}/{{componentName}}.1033.resx +0 -0
  81. package/templates/pcf-field/{{{componentName}}Component.tsx → {{componentName}}/{{componentName}}Component.tsx} +0 -0
  82. package/templates/{power-pages-starter → power-pages-island}/gitignore +1 -1
@@ -1,162 +0,0 @@
1
- import React, { createContext, useContext, useState, useEffect } from 'react';
2
- import { PowerPagesApiService } from '@khester/dynamics-ui-api-client';
3
-
4
- interface PowerPagesContextType {
5
- apiService: PowerPagesApiService | null;
6
- isAuthenticated: boolean;
7
- createRecord: (entityName: string, data: any) => Promise<any>;
8
- retrieveRecord: (
9
- entityName: string,
10
- id: string,
11
- select?: string
12
- ) => Promise<any>;
13
- updateRecord: (entityName: string, id: string, data: any) => Promise<any>;
14
- deleteRecord: (entityName: string, id: string) => Promise<void>;
15
- retrieveMultiple: (entityName: string, query?: string) => Promise<any>;
16
- }
17
-
18
- const PowerPagesContext = createContext<PowerPagesContextType | undefined>(
19
- undefined
20
- );
21
-
22
- interface PowerPagesProviderProps {
23
- children: React.ReactNode;
24
- }
25
-
26
- export const PowerPagesProvider: React.FC<PowerPagesProviderProps> = ({
27
- children,
28
- }) => {
29
- const [apiService, setApiService] = useState<PowerPagesApiService | null>(
30
- null
31
- );
32
- const [isAuthenticated, setIsAuthenticated] = useState(false);
33
-
34
- useEffect(() => {
35
- // Initialize the API service
36
- const portalUrl = window.location.origin;
37
-
38
- // CSRF token function for Power Pages authentication
39
- const getCsrfToken = async (): Promise<string> => {
40
- // In a real Power Pages implementation, you would fetch the CSRF token
41
- // For demo purposes, return empty string
42
- return '';
43
- };
44
-
45
- const service = new PowerPagesApiService(portalUrl, getCsrfToken);
46
-
47
- setApiService(service);
48
-
49
- // Check authentication status
50
- // In a real implementation, you would check if the user is logged in to the portal
51
- // For demo purposes, we'll assume they are authenticated
52
- setIsAuthenticated(true);
53
- }, []);
54
-
55
- const createRecord = async (entityName: string, data: any) => {
56
- if (!apiService) throw new Error('API service not initialized');
57
- return await apiService.createRecord(entityName, data);
58
- };
59
-
60
- const retrieveRecord = async (
61
- entityName: string,
62
- id: string,
63
- select?: string
64
- ) => {
65
- if (!apiService) throw new Error('API service not initialized');
66
- // Use retrieveMultipleRecords with FetchXML to get a single record
67
- const selectAttributes = select
68
- ? select.split(',').map((attr) => attr.trim())
69
- : ['*'];
70
- const attributes = selectAttributes
71
- .map((attr) => (attr === '*' ? '' : `<attribute name="${attr}" />`))
72
- .join('');
73
- const fetchXml = `
74
- <fetch top="1">
75
- <entity name="${entityName}">
76
- ${attributes}
77
- <filter>
78
- <condition attribute="${entityName}id" operator="eq" value="${id}" />
79
- </filter>
80
- </entity>
81
- </fetch>
82
- `;
83
- const result = await apiService.retrieveMultipleRecords(
84
- entityName,
85
- fetchXml
86
- );
87
- return result.entities.length > 0 ? result.entities[0] : null;
88
- };
89
-
90
- const updateRecord = async (entityName: string, id: string, data: any) => {
91
- if (!apiService) throw new Error('API service not initialized');
92
- return await apiService.updateRecord(entityName, id, data);
93
- };
94
-
95
- const deleteRecord = async (entityName: string, id: string) => {
96
- if (!apiService) throw new Error('API service not initialized');
97
- return await apiService.deleteRecord(entityName, id);
98
- };
99
-
100
- const retrieveMultiple = async (entityName: string, query?: string) => {
101
- if (!apiService) throw new Error('API service not initialized');
102
- // Convert OData-style query to FetchXML
103
- let fetchXml = `<fetch>`;
104
-
105
- if (query) {
106
- // Parse basic OData query parameters
107
- const selectMatch = query.match(/\$select=([^&]*)/i);
108
- const orderByMatch = query.match(/\$orderby=([^&]*)/i);
109
- const topMatch = query.match(/\$top=(\d+)/i);
110
-
111
- if (topMatch) {
112
- fetchXml = `<fetch top="${topMatch[1]}">`;
113
- }
114
-
115
- fetchXml += `<entity name="${entityName}">`;
116
-
117
- if (selectMatch) {
118
- const attributes = selectMatch[1].split(',').map((attr) => attr.trim());
119
- attributes.forEach((attr) => {
120
- fetchXml += `<attribute name="${attr}" />`;
121
- });
122
- }
123
-
124
- if (orderByMatch) {
125
- const [field, direction] = orderByMatch[1].split(' ');
126
- fetchXml += `<order attribute="${field.trim()}" descending="${direction?.toLowerCase() === 'desc'}" />`;
127
- }
128
-
129
- fetchXml += `</entity></fetch>`;
130
- } else {
131
- fetchXml = `<fetch><entity name="${entityName}"></entity></fetch>`;
132
- }
133
-
134
- return await apiService.retrieveMultipleRecords(entityName, fetchXml);
135
- };
136
-
137
- const value: PowerPagesContextType = {
138
- apiService,
139
- isAuthenticated,
140
- createRecord,
141
- retrieveRecord,
142
- updateRecord,
143
- deleteRecord,
144
- retrieveMultiple,
145
- };
146
-
147
- return (
148
- <PowerPagesContext.Provider value={value}>
149
- {children}
150
- </PowerPagesContext.Provider>
151
- );
152
- };
153
-
154
- export const usePowerPagesApi = (): PowerPagesContextType => {
155
- const context = useContext(PowerPagesContext);
156
- if (context === undefined) {
157
- throw new Error(
158
- 'usePowerPagesApi must be used within a PowerPagesProvider'
159
- );
160
- }
161
- return context;
162
- };
@@ -1,76 +0,0 @@
1
- /* Global Styles */
2
- * {
3
- box-sizing: border-box;
4
- }
5
-
6
- body {
7
- margin: 0;
8
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
9
- 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
10
- sans-serif;
11
- -webkit-font-smoothing: antialiased;
12
- -moz-osx-font-smoothing: grayscale;
13
- background-color: #f5f5f5;
14
- color: #323130;
15
- }
16
-
17
- .app {
18
- min-height: 100vh;
19
- display: flex;
20
- flex-direction: column;
21
- }
22
-
23
- .app-header {
24
- background: linear-gradient(135deg, #0078d4 0%, #106ebe 100%);
25
- color: white;
26
- padding: 24px;
27
- text-align: center;
28
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
29
- }
30
-
31
- .app-header h1 {
32
- margin: 0 0 8px 0;
33
- font-size: 28px;
34
- font-weight: 600;
35
- }
36
-
37
- .app-header p {
38
- margin: 0;
39
- font-size: 16px;
40
- opacity: 0.9;
41
- }
42
-
43
- .app-main {
44
- flex: 1;
45
- padding: 32px 16px;
46
- max-width: 1200px;
47
- margin: 0 auto;
48
- width: 100%;
49
- }
50
-
51
- .app-footer {
52
- background-color: #f3f2f1;
53
- border-top: 1px solid #edebe9;
54
- padding: 16px;
55
- text-align: center;
56
- color: #605e5c;
57
- font-size: 14px;
58
- }
59
-
60
- .app-footer p {
61
- margin: 0;
62
- }
63
-
64
- @media (max-width: 768px) {
65
- .app-header {
66
- padding: 16px;
67
- }
68
-
69
- .app-header h1 {
70
- font-size: 24px;
71
- }
72
-
73
- .app-main {
74
- padding: 16px 8px;
75
- }
76
- }
@@ -1,20 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "es5",
4
- "lib": ["dom", "dom.iterable", "es6"],
5
- "allowJs": true,
6
- "skipLibCheck": true,
7
- "esModuleInterop": true,
8
- "allowSyntheticDefaultImports": true,
9
- "strict": true,
10
- "forceConsistentCasingInFileNames": true,
11
- "noFallthroughCasesInSwitch": true,
12
- "module": "esnext",
13
- "moduleResolution": "node",
14
- "resolveJsonModule": true,
15
- "isolatedModules": true,
16
- "noEmit": true,
17
- "jsx": "react-jsx"
18
- },
19
- "include": ["src"]
20
- }
@@ -1,57 +0,0 @@
1
- const path = require('path');
2
- const HtmlWebpackPlugin = require('html-webpack-plugin');
3
-
4
- module.exports = (env, argv) => {
5
- const isProduction = argv.mode === 'production';
6
-
7
- return {
8
- entry: './src/index.tsx',
9
- output: {
10
- path: path.resolve(__dirname, 'dist'),
11
- filename: isProduction ? '[name].[contenthash].js' : '[name].js',
12
- clean: true,
13
- publicPath: '/',
14
- },
15
- resolve: {
16
- extensions: ['.tsx', '.ts', '.js', '.jsx'],
17
- },
18
- module: {
19
- rules: [
20
- {
21
- test: /\.tsx?$/,
22
- use: {
23
- loader: 'ts-loader',
24
- options: {
25
- transpileOnly: true,
26
- },
27
- },
28
- exclude: /node_modules/,
29
- },
30
- {
31
- test: /\.css$/i,
32
- use: ['style-loader', 'css-loader'],
33
- },
34
- ],
35
- },
36
- plugins: [
37
- new HtmlWebpackPlugin({
38
- template: './public/index.html',
39
- filename: 'index.html',
40
- }),
41
- ],
42
- devServer: {
43
- static: {
44
- directory: path.join(__dirname, 'public'),
45
- },
46
- port: 3000,
47
- open: true,
48
- hot: true,
49
- historyApiFallback: true,
50
- },
51
- optimization: {
52
- splitChunks: {
53
- chunks: 'all',
54
- },
55
- },
56
- };
57
- };
@@ -1,5 +1,5 @@
1
1
  node_modules/
2
2
  dist/
3
- *.log
4
3
  .env
5
4
  .env.local
5
+ *.log