create-bluecopa-react-app 1.0.40 → 1.0.42
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/README.md +16 -14
- package/package.json +1 -1
- package/templates/latest/.claude/settings.local.json +56 -0
- package/templates/latest/.env.example +8 -0
- package/templates/latest/Agent.md +598 -775
- package/templates/latest/CLAUDE.md +759 -0
- package/templates/latest/README.md +17 -8
- package/templates/latest/app/app.css +292 -85
- package/templates/latest/app/app.tsx +48 -39
- package/templates/latest/app/components/bluecopa-logo.tsx +20 -0
- package/templates/latest/app/components/charts/bar-chart.tsx +132 -0
- package/templates/latest/app/components/charts/base-chart.tsx +149 -0
- package/templates/latest/app/components/charts/chart-provider.tsx +71 -0
- package/templates/latest/app/components/charts/chart-theme.ts +262 -0
- package/templates/latest/app/components/charts/chart-utils.ts +142 -0
- package/templates/latest/app/components/charts/donut-chart.tsx +110 -0
- package/templates/latest/app/components/charts/index.ts +5 -0
- package/templates/latest/app/components/layouts/app-layout.tsx +22 -0
- package/templates/latest/app/components/layouts/app-sidebar.tsx +88 -0
- package/templates/latest/app/components/layouts/nav-main.tsx +50 -0
- package/templates/latest/app/components/layouts/nav-user.tsx +38 -0
- package/templates/latest/app/components/layouts/site-header.tsx +93 -0
- package/templates/latest/app/components/loading-screen.tsx +41 -0
- package/templates/latest/app/components/ui/ag-grid-table.tsx +79 -0
- package/templates/latest/app/components/ui/button.tsx +23 -23
- package/templates/latest/app/components/ui/card.tsx +20 -20
- package/templates/latest/app/components/ui/dropdown-menu.tsx +54 -49
- package/templates/latest/app/components/ui/input.tsx +8 -8
- package/templates/latest/app/components/ui/label.tsx +8 -8
- package/templates/latest/app/components/ui/separator.tsx +7 -7
- package/templates/latest/app/components/ui/sheet.tsx +43 -32
- package/templates/latest/app/components/ui/sidebar.tsx +240 -235
- package/templates/latest/app/components/ui/skeleton.tsx +4 -4
- package/templates/latest/app/components/ui/sonner.tsx +6 -9
- package/templates/latest/app/components/ui/tabs.tsx +15 -15
- package/templates/latest/app/components/ui/tooltip.tsx +18 -12
- package/templates/latest/app/constants/index.ts +31 -0
- package/templates/latest/app/contexts/app-context.tsx +201 -0
- package/templates/latest/app/hooks/use-mobile.ts +13 -12
- package/templates/latest/app/main.tsx +1 -1
- package/templates/latest/app/pages/dashboard.tsx +246 -0
- package/templates/latest/app/pages/payments.tsx +182 -0
- package/templates/latest/app/pages/settings.tsx +128 -0
- package/templates/latest/app/routes/index.tsx +19 -0
- package/templates/latest/app/single-spa.tsx +68 -86
- package/templates/latest/app/types/index.ts +37 -0
- package/templates/latest/app/utils/ag-grid-datasource.ts +63 -0
- package/templates/latest/app/utils/ag-grid-license.ts +12 -0
- package/templates/latest/app/utils/ag-grid-theme.ts +9 -0
- package/templates/latest/app/utils/component-style.ts +7 -0
- package/templates/latest/app/utils/style-drivers.ts +24 -0
- package/templates/latest/app/utils/utils.ts +10 -0
- package/templates/latest/components.json +3 -3
- package/templates/latest/index.html +30 -2
- package/templates/latest/package-lock.json +30 -416
- package/templates/latest/package.json +8 -18
- package/templates/latest/preview/index.html +125 -285
- package/templates/latest/public/favicon.svg +1 -0
- package/templates/latest/vite.config.ts +2 -8
- package/templates/latest/app/components/app-sidebar.tsx +0 -182
- package/templates/latest/app/components/chart-area-interactive.tsx +0 -290
- package/templates/latest/app/components/data-table.tsx +0 -807
- package/templates/latest/app/components/nav-documents.tsx +0 -92
- package/templates/latest/app/components/nav-main.tsx +0 -40
- package/templates/latest/app/components/nav-secondary.tsx +0 -42
- package/templates/latest/app/components/nav-user.tsx +0 -111
- package/templates/latest/app/components/section-cards.tsx +0 -102
- package/templates/latest/app/components/site-header.tsx +0 -28
- package/templates/latest/app/components/ui/avatar.tsx +0 -53
- package/templates/latest/app/components/ui/badge.tsx +0 -46
- package/templates/latest/app/components/ui/breadcrumb.tsx +0 -109
- package/templates/latest/app/components/ui/chart.tsx +0 -352
- package/templates/latest/app/components/ui/checkbox.tsx +0 -30
- package/templates/latest/app/components/ui/drawer.tsx +0 -139
- package/templates/latest/app/components/ui/select.tsx +0 -183
- package/templates/latest/app/components/ui/table.tsx +0 -117
- package/templates/latest/app/components/ui/toggle-group.tsx +0 -73
- package/templates/latest/app/components/ui/toggle.tsx +0 -47
- package/templates/latest/app/data/data.json +0 -614
- package/templates/latest/app/data/mock-payments.json +0 -122
- package/templates/latest/app/data/mock-transactions.json +0 -128
- package/templates/latest/app/hooks/use-bluecopa-user.ts +0 -37
- package/templates/latest/app/lib/utils.ts +0 -6
- package/templates/latest/app/routes/apitest.tsx +0 -2118
- package/templates/latest/app/routes/comments.tsx +0 -588
- package/templates/latest/app/routes/dashboard.tsx +0 -36
- package/templates/latest/app/routes/payments.tsx +0 -342
- package/templates/latest/app/routes/statements.tsx +0 -493
- package/templates/latest/app/routes/websocket.tsx +0 -450
- package/templates/latest/app/routes.tsx +0 -22
- package/templates/latest/dist/assets/__federation_expose_App-OFfdinOR.js +0 -97
- package/templates/latest/dist/assets/__federation_fn_import-CzfA7kmP.js +0 -438
- package/templates/latest/dist/assets/__federation_shared_react-Bp6HVBS4.js +0 -16
- package/templates/latest/dist/assets/__federation_shared_react-dom-BCcRGiYp.js +0 -17
- package/templates/latest/dist/assets/client-CkHcT_xc.js +0 -76035
- package/templates/latest/dist/assets/index-B3cD3sP_.js +0 -60
- package/templates/latest/dist/assets/index-BzNimew1.js +0 -69
- package/templates/latest/dist/assets/index-DMFtQdNS.js +0 -412
- package/templates/latest/dist/assets/remoteEntry.css +0 -3996
- package/templates/latest/dist/assets/remoteEntry.js +0 -88
- package/templates/latest/dist/favicon.ico +0 -0
- package/templates/latest/dist/index.html +0 -19
|
@@ -2,11 +2,25 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
|
-
<link rel="icon" type="image/svg+xml" href="/favicon.
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
-
<title>
|
|
8
|
-
<meta name="description" content="Preview wrapper for federation module" />
|
|
7
|
+
<title>MFE Preview</title>
|
|
9
8
|
<style>
|
|
9
|
+
/* Preflight — matches what the host app normally provides */
|
|
10
|
+
*, *::before, *::after { box-sizing: border-box; border-width: 0; border-style: solid; margin: 0; padding: 0; }
|
|
11
|
+
html { height: 100%; line-height: 1.5; -webkit-text-size-adjust: 100%; tab-size: 4; }
|
|
12
|
+
body { height: 100%; line-height: inherit; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
|
|
13
|
+
h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; }
|
|
14
|
+
a { color: inherit; text-decoration: inherit; }
|
|
15
|
+
ol, ul, menu { list-style: none; }
|
|
16
|
+
img, svg, video, canvas, audio, iframe, embed, object { display: block; max-width: 100%; }
|
|
17
|
+
button, input, optgroup, select, textarea { font: inherit; color: inherit; }
|
|
18
|
+
button { cursor: pointer; background: transparent; }
|
|
19
|
+
table { border-collapse: collapse; border-spacing: 0; text-indent: 0; border-color: inherit; }
|
|
20
|
+
hr { height: 0; color: inherit; border-top-width: 1px; }
|
|
21
|
+
p, blockquote, dl, dd, figure, fieldset, legend, pre { margin: 0; }
|
|
22
|
+
|
|
23
|
+
/* Preview-specific */
|
|
10
24
|
.loading {
|
|
11
25
|
display: flex;
|
|
12
26
|
align-items: center;
|
|
@@ -17,344 +31,170 @@
|
|
|
17
31
|
}
|
|
18
32
|
.error {
|
|
19
33
|
padding: 20px;
|
|
20
|
-
background: #
|
|
21
|
-
border: 1px solid #
|
|
34
|
+
background: #fef2f2;
|
|
35
|
+
border: 1px solid #fecaca;
|
|
22
36
|
border-radius: 8px;
|
|
23
37
|
margin: 20px;
|
|
24
38
|
}
|
|
25
|
-
.error h2 {
|
|
26
|
-
color: #c33;
|
|
27
|
-
margin-top: 0;
|
|
28
|
-
}
|
|
39
|
+
.error h2 { color: #dc2626; margin-top: 0; }
|
|
29
40
|
.error code {
|
|
30
41
|
background: #f5f5f5;
|
|
31
42
|
padding: 2px 4px;
|
|
32
43
|
border-radius: 3px;
|
|
33
44
|
font-family: monospace;
|
|
34
45
|
}
|
|
35
|
-
#
|
|
36
|
-
width: 100%;
|
|
37
|
-
min-height: 500px;
|
|
38
|
-
}
|
|
46
|
+
#mfe-container { width: 100%; min-height: 100vh; }
|
|
39
47
|
</style>
|
|
40
48
|
</head>
|
|
41
49
|
<body>
|
|
42
|
-
<div id="loading-indicator" class="loading">
|
|
43
|
-
Loading Bluecopa module...
|
|
44
|
-
</div>
|
|
50
|
+
<div id="loading-indicator" class="loading">Loading MFE module...</div>
|
|
45
51
|
<div id="error-container" style="display: none;"></div>
|
|
46
|
-
<div id="
|
|
52
|
+
<div id="mfe-container"></div>
|
|
47
53
|
|
|
48
|
-
<!-- SystemJS import map for shared dependencies
|
|
54
|
+
<!-- SystemJS import map for shared dependencies -->
|
|
49
55
|
<script type="systemjs-importmap">
|
|
50
56
|
{
|
|
51
57
|
"imports": {
|
|
52
58
|
"react": "https://unpkg.com/react@18/umd/react.development.js",
|
|
53
|
-
"react-dom": "https://unpkg.com/react-dom@18/umd/react-dom.development.js"
|
|
54
|
-
"react-router-dom": "https://unpkg.com/react-router-dom@6/dist/umd/react-router-dom.development.js",
|
|
55
|
-
"single-spa": "https://unpkg.com/single-spa@5/dist/system/single-spa.min.js",
|
|
56
|
-
"single-spa-react": "https://unpkg.com/single-spa-react@4/dist/umd/single-spa-react.min.js"
|
|
59
|
+
"react-dom": "https://unpkg.com/react-dom@18/umd/react-dom.development.js"
|
|
57
60
|
}
|
|
58
61
|
}
|
|
59
62
|
</script>
|
|
60
|
-
|
|
61
|
-
<!-- SystemJS for loading System format
|
|
63
|
+
|
|
64
|
+
<!-- SystemJS for loading System format modules -->
|
|
62
65
|
<script src="https://unpkg.com/systemjs@6/dist/system.min.js"></script>
|
|
63
|
-
|
|
64
|
-
<script
|
|
65
|
-
//
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (importMap) {
|
|
70
|
-
window.System.addImportMap(JSON.parse(importMap.textContent));
|
|
71
|
-
}
|
|
72
|
-
// Auto-load on page open
|
|
73
|
-
await loadFederationModule();
|
|
74
|
-
}
|
|
75
|
-
});
|
|
66
|
+
|
|
67
|
+
<script>
|
|
68
|
+
// Using regular script (not module) so it runs synchronously after SystemJS loads
|
|
69
|
+
const MODULE_URL = "http://localhost:3001/assets/remoteEntry.js";
|
|
70
|
+
const BASE_PATH = "/";
|
|
71
|
+
|
|
76
72
|
let currentModule = null;
|
|
77
|
-
let currentMountProps = null;
|
|
78
73
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const existingScript = document.querySelector(`script[src='${moduleUrl}']`);
|
|
84
|
-
if (existingScript) existingScript.remove();
|
|
85
|
-
// Create new script
|
|
74
|
+
function loadRemoteEntry(url) {
|
|
75
|
+
return new Promise(function(resolve, reject) {
|
|
76
|
+
const existing = document.querySelector("script[src='" + url + "']");
|
|
77
|
+
if (existing) existing.remove();
|
|
86
78
|
const script = document.createElement('script');
|
|
87
|
-
script.
|
|
88
|
-
script.src = moduleUrl;
|
|
79
|
+
script.src = url;
|
|
89
80
|
script.async = true;
|
|
90
|
-
script.onload =
|
|
91
|
-
script.onerror = ()
|
|
81
|
+
script.onload = resolve;
|
|
82
|
+
script.onerror = function() { reject(new Error('Failed to load remoteEntry.js')); };
|
|
92
83
|
document.head.appendChild(script);
|
|
93
84
|
});
|
|
94
85
|
}
|
|
95
86
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const
|
|
100
|
-
const moduleName = "__copa_ext_app__react_route";
|
|
101
|
-
const exposeName = "./App";
|
|
102
|
-
const basePath = "/preview";
|
|
103
|
-
|
|
104
|
-
const loadingIndicator = document.getElementById('loading-indicator');
|
|
105
|
-
const errorContainer = document.getElementById('error-container');
|
|
106
|
-
const previewContainer = document.getElementById('bluecopa-preview');
|
|
87
|
+
async function loadModule() {
|
|
88
|
+
const loading = document.getElementById('loading-indicator');
|
|
89
|
+
const errorEl = document.getElementById('error-container');
|
|
90
|
+
const container = document.getElementById('mfe-container');
|
|
107
91
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
errorContainer.style.display = 'none';
|
|
112
|
-
previewContainer.innerHTML = '';
|
|
92
|
+
loading.style.display = 'flex';
|
|
93
|
+
errorEl.style.display = 'none';
|
|
94
|
+
container.innerHTML = '';
|
|
113
95
|
|
|
114
96
|
try {
|
|
115
|
-
//
|
|
116
|
-
await
|
|
117
|
-
|
|
118
|
-
console.log('Loading federation module from:', moduleUrl);
|
|
119
|
-
|
|
120
|
-
// Load remoteEntry script
|
|
121
|
-
await loadRemoteEntryScript(moduleUrl);
|
|
97
|
+
// Load remoteEntry.js as a script tag first
|
|
98
|
+
await loadRemoteEntry(MODULE_URL);
|
|
122
99
|
|
|
123
100
|
// Clear System cache for fresh load
|
|
124
101
|
if (window.System && typeof window.System.delete === 'function') {
|
|
125
|
-
window.System.delete(
|
|
102
|
+
window.System.delete(MODULE_URL);
|
|
126
103
|
}
|
|
127
104
|
|
|
128
|
-
//
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
try {
|
|
143
|
-
const factory = await container.get(entry);
|
|
144
|
-
appModule = factory ? factory() : factory;
|
|
145
|
-
console.log(`Found module at ${entry}:`, appModule);
|
|
146
|
-
break;
|
|
147
|
-
} catch (e) {
|
|
148
|
-
console.log(`No module at ${entry}`);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (!appModule) {
|
|
154
|
-
appModule = container;
|
|
105
|
+
// Import the federation container via SystemJS
|
|
106
|
+
const fedContainer = await Promise.race([
|
|
107
|
+
System.import(MODULE_URL),
|
|
108
|
+
new Promise(function(_, reject) {
|
|
109
|
+
setTimeout(function() { reject(new Error('Module load timeout (15s)')); }, 15000);
|
|
110
|
+
})
|
|
111
|
+
]);
|
|
112
|
+
|
|
113
|
+
// Get the exposed ./App module
|
|
114
|
+
let appModule;
|
|
115
|
+
if (typeof fedContainer.get === 'function') {
|
|
116
|
+
// Initialize the federation container shared scope
|
|
117
|
+
if (typeof fedContainer.init === 'function') {
|
|
118
|
+
try { await fedContainer.init({}); } catch (e) { /* already initialized */ }
|
|
155
119
|
}
|
|
156
|
-
|
|
157
|
-
|
|
120
|
+
const factory = await fedContainer.get('./App');
|
|
121
|
+
appModule = factory();
|
|
158
122
|
} else {
|
|
159
|
-
|
|
123
|
+
appModule = fedContainer;
|
|
160
124
|
}
|
|
161
125
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
errorContainer.style.display = 'block';
|
|
166
|
-
errorContainer.innerHTML = `
|
|
167
|
-
<div class="error">
|
|
168
|
-
<h2>Failed to Load Application</h2>
|
|
169
|
-
<p>${error.message}</p>
|
|
170
|
-
<ul>
|
|
171
|
-
<li>Make sure the federation build is running: <code>npm run preview</code></li>
|
|
172
|
-
<li>Verify the module URL points to the correct remoteEntry.js</li>
|
|
173
|
-
<li>Check that module name matches your vite.config.ts federation name</li>
|
|
174
|
-
<li>Open browser DevTools Console for detailed error information</li>
|
|
175
|
-
<li>Ensure CORS is enabled on your federation server</li>
|
|
176
|
-
</ul>
|
|
177
|
-
<p>Refresh the page to retry.</p>
|
|
178
|
-
</div>
|
|
179
|
-
`;
|
|
180
|
-
// Also log to console
|
|
181
|
-
console.error('bluecopa preview error:', error);
|
|
182
|
-
}
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
// Helper function to mount the module
|
|
186
|
-
async function mountModule(appModule, basePath, loadingIndicator, previewContainer, container) {
|
|
187
|
-
// Create a container for the module
|
|
188
|
-
const moduleContainer = document.createElement('div');
|
|
189
|
-
moduleContainer.id = 'single-spa-application:bluecopa-preview';
|
|
190
|
-
moduleContainer.style.width = '100%';
|
|
191
|
-
moduleContainer.style.minHeight = '500px';
|
|
192
|
-
previewContainer.appendChild(moduleContainer);
|
|
193
|
-
|
|
194
|
-
console.log('App module:', appModule);
|
|
195
|
-
console.log('App module type:', typeof appModule);
|
|
126
|
+
// Find mount function — single-spa.tsx exports { mount, unmount, bootstrap }
|
|
127
|
+
const mountFn = (appModule && appModule.default && appModule.default.mount) || (appModule && appModule.mount);
|
|
128
|
+
const unmountFn = (appModule && appModule.default && appModule.default.unmount) || (appModule && appModule.unmount);
|
|
196
129
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
// Initialize container if needed
|
|
200
|
-
if (typeof container.init === 'function') {
|
|
201
|
-
try {
|
|
202
|
-
await container.init({});
|
|
203
|
-
} catch (e) {
|
|
204
|
-
console.warn('Container init failed:', e);
|
|
130
|
+
if (typeof mountFn !== 'function') {
|
|
131
|
+
throw new Error('No mount function found in module exports');
|
|
205
132
|
}
|
|
206
|
-
}
|
|
207
133
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
appModule?.init ||
|
|
214
|
-
appModule?.default?.init ||
|
|
215
|
-
appModule?.bootstrap ||
|
|
216
|
-
appModule?.default?.bootstrap ||
|
|
217
|
-
appModule?.start ||
|
|
218
|
-
appModule?.default?.start ||
|
|
219
|
-
(typeof appModule === 'function' ? appModule : null);
|
|
134
|
+
// Create mount point
|
|
135
|
+
const mountPoint = document.createElement('div');
|
|
136
|
+
mountPoint.id = 'single-spa-application:mfe-preview';
|
|
137
|
+
mountPoint.style.cssText = 'width: 100%; min-height: 100vh;';
|
|
138
|
+
container.appendChild(mountPoint);
|
|
220
139
|
|
|
221
|
-
|
|
222
|
-
|
|
140
|
+
// Mount with standard MFE props
|
|
141
|
+
await mountFn({
|
|
142
|
+
domElement: mountPoint,
|
|
143
|
+
basename: BASE_PATH,
|
|
144
|
+
});
|
|
223
145
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
try {
|
|
228
|
-
// Pattern 1: Single-spa config
|
|
229
|
-
const props = {
|
|
230
|
-
domElement: moduleContainer,
|
|
231
|
-
basename: basePath,
|
|
232
|
-
singleSpa: {
|
|
233
|
-
name: 'bluecopa-preview',
|
|
234
|
-
mountParcel: () => {},
|
|
235
|
-
getProps: () => ({})
|
|
236
|
-
}
|
|
237
|
-
};
|
|
238
|
-
await mountFunc(props);
|
|
239
|
-
mounted = true;
|
|
240
|
-
} catch (e1) {
|
|
241
|
-
console.log('Single-spa pattern failed:', e1);
|
|
242
|
-
try {
|
|
243
|
-
// Pattern 2: Direct element
|
|
244
|
-
await mountFunc(moduleContainer);
|
|
245
|
-
mounted = true;
|
|
246
|
-
} catch (e2) {
|
|
247
|
-
console.log('Direct element pattern failed:', e2);
|
|
248
|
-
try {
|
|
249
|
-
// Pattern 3: No args
|
|
250
|
-
await mountFunc();
|
|
251
|
-
mounted = true;
|
|
252
|
-
} catch (e3) {
|
|
253
|
-
console.error('All mount patterns failed:', { e1, e2, e3 });
|
|
254
|
-
throw new Error('Failed to mount application with any pattern');
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
146
|
+
currentModule = { unmountFn: unmountFn, mountPoint: mountPoint };
|
|
147
|
+
loading.style.display = 'none';
|
|
148
|
+
console.log('MFE mounted successfully');
|
|
258
149
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
root.render(React.createElement(appModule, { basename: basePath }));
|
|
275
|
-
currentModule = { unmount: () => root.unmount(), container };
|
|
276
|
-
loadingIndicator.style.display = 'none';
|
|
277
|
-
console.log('React component mounted successfully');
|
|
278
|
-
return;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
throw new Error('No valid mount function or React component found');
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// Helper to unmount
|
|
285
|
-
async function unmountModule(appModule, moduleContainer) {
|
|
286
|
-
// Try multiple unmount patterns
|
|
287
|
-
const unmountFunc = appModule?.unmount ||
|
|
288
|
-
appModule?.default?.unmount ||
|
|
289
|
-
appModule?.destroy ||
|
|
290
|
-
appModule?.default?.destroy ||
|
|
291
|
-
appModule?.cleanup ||
|
|
292
|
-
appModule?.default?.cleanup ||
|
|
293
|
-
appModule?.dispose ||
|
|
294
|
-
appModule?.default?.dispose;
|
|
295
|
-
|
|
296
|
-
if (typeof unmountFunc === 'function') {
|
|
297
|
-
try {
|
|
298
|
-
// Try with props if available
|
|
299
|
-
if (currentMountProps) {
|
|
300
|
-
await unmountFunc(currentMountProps);
|
|
301
|
-
} else {
|
|
302
|
-
await unmountFunc();
|
|
303
|
-
}
|
|
304
|
-
console.log('Module unmounted via function');
|
|
305
|
-
return;
|
|
306
|
-
} catch (e) {
|
|
307
|
-
console.warn('Unmount function failed:', e);
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
// Fallback manual cleanup
|
|
312
|
-
if (moduleContainer) {
|
|
313
|
-
moduleContainer.innerHTML = '';
|
|
150
|
+
} catch (error) {
|
|
151
|
+
loading.style.display = 'none';
|
|
152
|
+
errorEl.style.display = 'block';
|
|
153
|
+
errorEl.innerHTML =
|
|
154
|
+
'<div class="error">' +
|
|
155
|
+
'<h2>Failed to Load MFE</h2>' +
|
|
156
|
+
'<p>' + error.message + '</p>' +
|
|
157
|
+
'<ul>' +
|
|
158
|
+
'<li>Build the MFE first: <code>pnpm build</code></li>' +
|
|
159
|
+
'<li>Start the preview server: <code>pnpm start</code></li>' +
|
|
160
|
+
'<li>Verify <code>' + MODULE_URL + '</code> is accessible</li>' +
|
|
161
|
+
'<li>Check browser DevTools for details</li>' +
|
|
162
|
+
'</ul>' +
|
|
163
|
+
'</div>';
|
|
164
|
+
console.error('MFE preview error:', error);
|
|
314
165
|
}
|
|
315
|
-
console.log('Module cleaned up manually');
|
|
316
166
|
}
|
|
317
167
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
try {
|
|
322
|
-
if (currentModule.container && typeof currentModule.container.delete === 'function') {
|
|
323
|
-
currentModule.container.delete(currentModule.container.url || ''); // Clear cache
|
|
324
|
-
}
|
|
325
|
-
await unmountModule(currentModule.appModule || currentModule, document.getElementById('bluecopa-preview'));
|
|
326
|
-
} catch (error) {
|
|
327
|
-
console.error('Error unmounting module:', error);
|
|
328
|
-
}
|
|
168
|
+
window.reloadModule = async function() {
|
|
169
|
+
if (currentModule && currentModule.unmountFn) {
|
|
170
|
+
try { await currentModule.unmountFn(); } catch (e) { console.warn('Unmount failed:', e); }
|
|
329
171
|
}
|
|
330
|
-
|
|
331
172
|
currentModule = null;
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
const previewContainer = document.getElementById('bluecopa-preview');
|
|
335
|
-
previewContainer.innerHTML = '';
|
|
336
|
-
|
|
337
|
-
const loadingIndicator = document.getElementById('loading-indicator');
|
|
338
|
-
loadingIndicator.style.display = 'flex';
|
|
339
|
-
loadingIndicator.textContent = 'Ready to load bluecopa module...';
|
|
340
|
-
|
|
341
|
-
const errorContainer = document.getElementById('error-container');
|
|
342
|
-
errorContainer.style.display = 'none';
|
|
173
|
+
if (window.System && window.System.clear) window.System.clear();
|
|
174
|
+
setTimeout(loadModule, 100);
|
|
343
175
|
};
|
|
344
176
|
|
|
345
|
-
//
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
177
|
+
// Wait for DOM + SystemJS to be ready, then load
|
|
178
|
+
if (document.readyState === 'loading') {
|
|
179
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
180
|
+
if (window.System) {
|
|
181
|
+
var importMap = document.querySelector('script[type="systemjs-importmap"]');
|
|
182
|
+
if (importMap) {
|
|
183
|
+
window.System.addImportMap(JSON.parse(importMap.textContent));
|
|
184
|
+
}
|
|
185
|
+
loadModule();
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
} else {
|
|
189
|
+
// DOM already ready
|
|
190
|
+
if (window.System) {
|
|
191
|
+
var importMap = document.querySelector('script[type="systemjs-importmap"]');
|
|
192
|
+
if (importMap) {
|
|
193
|
+
window.System.addImportMap(JSON.parse(importMap.textContent));
|
|
194
|
+
}
|
|
195
|
+
loadModule();
|
|
351
196
|
}
|
|
352
|
-
|
|
353
|
-
setTimeout(() => {
|
|
354
|
-
loadFederationModule();
|
|
355
|
-
}, 100);
|
|
356
|
-
};
|
|
357
|
-
|
|
197
|
+
}
|
|
358
198
|
</script>
|
|
359
199
|
</body>
|
|
360
200
|
</html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1820 1774.9"><circle fill="#fff" cx="1054.53" cy="779.52" r="386.21"/><path fill="#8ac2ff" d="M5.91,1004.47L0,1768.96l764.5,5.91c422.08,3.27,767.15-336.52,770.42-758.58,3.26-422.06-336.51-767.14-758.59-770.41C350.68,242.59,9.18,582.4,5.91,1004.47Z"/><path fill="#3548ff" d="M1820,764.52V0h-764.52C633.38,0,290.95,342.44,290.95,764.52s342.43,764.52,764.52,764.52,764.52-342.44,764.52-764.52Z"/><circle fill="#fff" cx="1055.48" cy="780.55" r="382.26"/></svg>
|
|
@@ -3,7 +3,6 @@ import { defineConfig } from "vite";
|
|
|
3
3
|
import tsconfigPaths from "vite-tsconfig-paths";
|
|
4
4
|
import federation from "@originjs/vite-plugin-federation";
|
|
5
5
|
import react from "@vitejs/plugin-react-swc";
|
|
6
|
-
import path from "path";
|
|
7
6
|
|
|
8
7
|
export default defineConfig({
|
|
9
8
|
server: {
|
|
@@ -30,14 +29,9 @@ export default defineConfig({
|
|
|
30
29
|
shared: ["react", "react-dom"],
|
|
31
30
|
}),
|
|
32
31
|
],
|
|
33
|
-
resolve: {
|
|
34
|
-
alias: {
|
|
35
|
-
"@": path.resolve(__dirname, "./src"),
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
32
|
build: {
|
|
39
33
|
target: "esnext",
|
|
40
|
-
minify:
|
|
34
|
+
minify: "esbuild",
|
|
41
35
|
cssCodeSplit: false,
|
|
42
36
|
ssr: false,
|
|
43
37
|
rollupOptions: {
|
|
@@ -46,7 +40,7 @@ export default defineConfig({
|
|
|
46
40
|
format: "system",
|
|
47
41
|
assetFileNames: (assetInfo) => {
|
|
48
42
|
const fileName = assetInfo.names?.[0] || assetInfo.name;
|
|
49
|
-
if (fileName && fileName.endsWith(
|
|
43
|
+
if (fileName && fileName.endsWith(".css")) {
|
|
50
44
|
return "assets/remoteEntry.css";
|
|
51
45
|
}
|
|
52
46
|
return fileName || "assets/remoteEntry.css";
|