@gxp-dev/tools 2.0.6 → 2.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.
Files changed (99) hide show
  1. package/browser-extensions/README.md +1 -0
  2. package/browser-extensions/chrome/background.js +857 -0
  3. package/browser-extensions/chrome/content.js +51 -0
  4. package/browser-extensions/chrome/devtools.html +9 -0
  5. package/browser-extensions/chrome/devtools.js +23 -0
  6. package/browser-extensions/chrome/icons/gx_off_128.png +0 -0
  7. package/browser-extensions/chrome/icons/gx_off_16.png +0 -0
  8. package/browser-extensions/chrome/icons/gx_off_32.png +0 -0
  9. package/browser-extensions/chrome/icons/gx_off_64.png +0 -0
  10. package/browser-extensions/chrome/icons/gx_on_128.png +0 -0
  11. package/browser-extensions/chrome/icons/gx_on_16.png +0 -0
  12. package/browser-extensions/chrome/icons/gx_on_32.png +0 -0
  13. package/browser-extensions/chrome/icons/gx_on_64.png +0 -0
  14. package/browser-extensions/chrome/inspector.js +1087 -0
  15. package/browser-extensions/chrome/manifest.json +70 -0
  16. package/browser-extensions/chrome/panel.html +638 -0
  17. package/browser-extensions/chrome/panel.js +862 -0
  18. package/browser-extensions/chrome/popup.html +399 -0
  19. package/browser-extensions/chrome/popup.js +515 -0
  20. package/browser-extensions/chrome/rules.json +1 -0
  21. package/browser-extensions/chrome/test-chrome.html +145 -0
  22. package/browser-extensions/chrome/test-mixed-content.html +190 -0
  23. package/browser-extensions/chrome/test-uri-pattern.html +199 -0
  24. package/browser-extensions/firefox/README.md +134 -0
  25. package/browser-extensions/firefox/background.js +804 -0
  26. package/browser-extensions/firefox/content.js +120 -0
  27. package/browser-extensions/firefox/debug-errors.html +229 -0
  28. package/browser-extensions/firefox/debug-https.html +113 -0
  29. package/browser-extensions/firefox/devtools.html +9 -0
  30. package/browser-extensions/firefox/devtools.js +24 -0
  31. package/browser-extensions/firefox/icons/gx_off_128.png +0 -0
  32. package/browser-extensions/firefox/icons/gx_off_16.png +0 -0
  33. package/browser-extensions/firefox/icons/gx_off_32.png +0 -0
  34. package/browser-extensions/firefox/icons/gx_off_64.png +0 -0
  35. package/browser-extensions/firefox/icons/gx_on_128.png +0 -0
  36. package/browser-extensions/firefox/icons/gx_on_16.png +0 -0
  37. package/browser-extensions/firefox/icons/gx_on_32.png +0 -0
  38. package/browser-extensions/firefox/icons/gx_on_64.png +0 -0
  39. package/browser-extensions/firefox/inspector.js +1087 -0
  40. package/browser-extensions/firefox/manifest.json +67 -0
  41. package/browser-extensions/firefox/panel.html +638 -0
  42. package/browser-extensions/firefox/panel.js +862 -0
  43. package/browser-extensions/firefox/popup.html +525 -0
  44. package/browser-extensions/firefox/popup.js +536 -0
  45. package/browser-extensions/firefox/test-gramercy.html +126 -0
  46. package/browser-extensions/firefox/test-imports.html +58 -0
  47. package/browser-extensions/firefox/test-masking.html +147 -0
  48. package/browser-extensions/firefox/test-uri-pattern.html +199 -0
  49. package/package.json +7 -2
  50. package/runtime/PortalContainer.vue +326 -0
  51. package/runtime/dev-tools/DevToolsModal.vue +217 -0
  52. package/runtime/dev-tools/LayoutSwitcher.vue +221 -0
  53. package/runtime/dev-tools/MockDataEditor.vue +621 -0
  54. package/runtime/dev-tools/SocketSimulator.vue +562 -0
  55. package/runtime/dev-tools/StoreInspector.vue +644 -0
  56. package/runtime/dev-tools/index.js +6 -0
  57. package/runtime/gxpStringsPlugin.js +428 -0
  58. package/runtime/index.html +22 -0
  59. package/runtime/main.js +32 -0
  60. package/runtime/mock-api/auth-middleware.js +97 -0
  61. package/runtime/mock-api/image-generator.js +221 -0
  62. package/runtime/mock-api/index.js +197 -0
  63. package/runtime/mock-api/response-generator.js +394 -0
  64. package/runtime/mock-api/route-generator.js +323 -0
  65. package/runtime/mock-api/socket-triggers.js +371 -0
  66. package/runtime/mock-api/spec-loader.js +300 -0
  67. package/runtime/server.js +180 -0
  68. package/runtime/stores/gxpPortalConfigStore.js +554 -0
  69. package/runtime/stores/index.js +6 -0
  70. package/runtime/vite-inspector-plugin.js +749 -0
  71. package/runtime/vite-source-tracker-plugin.js +232 -0
  72. package/runtime/vite.config.js +402 -0
  73. package/scripts/launch-chrome.js +90 -0
  74. package/scripts/pack-chrome.js +91 -0
  75. package/socket-events/AiSessionMessageCreated.json +18 -0
  76. package/socket-events/SocialStreamPostCreated.json +24 -0
  77. package/socket-events/SocialStreamPostVariantCompleted.json +23 -0
  78. package/template/README.md +332 -0
  79. package/template/app-manifest.json +32 -0
  80. package/template/dev-assets/images/avatar-placeholder.png +0 -0
  81. package/template/dev-assets/images/background-placeholder.jpg +0 -0
  82. package/template/dev-assets/images/banner-placeholder.jpg +0 -0
  83. package/template/dev-assets/images/icon-placeholder.png +0 -0
  84. package/template/dev-assets/images/logo-placeholder.png +0 -0
  85. package/template/dev-assets/images/product-placeholder.jpg +0 -0
  86. package/template/dev-assets/images/thumbnail-placeholder.jpg +0 -0
  87. package/template/env.example +51 -0
  88. package/template/gitignore +53 -0
  89. package/template/index.html +22 -0
  90. package/template/main.js +28 -0
  91. package/template/src/DemoPage.vue +459 -0
  92. package/template/src/Plugin.vue +38 -0
  93. package/template/src/stores/index.js +9 -0
  94. package/template/src/stores/test-data.json +173 -0
  95. package/template/theme-layouts/AdditionalStyling.css +0 -0
  96. package/template/theme-layouts/PrivateLayout.vue +39 -0
  97. package/template/theme-layouts/PublicLayout.vue +39 -0
  98. package/template/theme-layouts/SystemLayout.vue +39 -0
  99. package/template/vite.config.js +333 -0
@@ -0,0 +1,53 @@
1
+ # Dependencies
2
+ node_modules/
3
+ .pnp
4
+ .pnp.js
5
+
6
+ # Build output
7
+ dist/
8
+ dist-ssr/
9
+ *.local
10
+
11
+ # Environment files
12
+ .env
13
+ .env.local
14
+ .env.*.local
15
+
16
+ # SSL certificates
17
+ .certs/
18
+
19
+ # Development assets (optional - uncomment to ignore)
20
+ # dev-assets/
21
+
22
+ # Editor directories and files
23
+ .vscode/*
24
+ !.vscode/extensions.json
25
+ .idea/
26
+ *.suo
27
+ *.ntvs*
28
+ *.njsproj
29
+ *.sln
30
+ *.sw?
31
+ *.swp
32
+ *~
33
+
34
+ # OS files
35
+ .DS_Store
36
+ Thumbs.db
37
+
38
+ # Logs
39
+ logs/
40
+ *.log
41
+ npm-debug.log*
42
+ yarn-debug.log*
43
+ yarn-error.log*
44
+ pnpm-debug.log*
45
+
46
+ # Testing
47
+ coverage/
48
+ .nyc_output/
49
+
50
+ # Temporary files
51
+ tmp/
52
+ temp/
53
+ *.tmp
@@ -0,0 +1,22 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
+ <title>GxP Plugin Builder</title>
9
+ <script type="module">
10
+ import * as Vue from '/node_modules/vue/dist/vue.esm-bundler.js';
11
+ window.Vue = Vue;
12
+ import * as Pinia from '/node_modules/pinia/dist/pinia.esm-browser.js';
13
+ window.Pinia = Pinia;
14
+ </script>
15
+ </head>
16
+
17
+ <body>
18
+ <div id="app"></div>
19
+ <script type="module" src="/main.js"></script>
20
+ </body>
21
+
22
+ </html>
@@ -0,0 +1,28 @@
1
+ import { createApp } from "vue";
2
+
3
+ import * as Vue from "vue";
4
+ import * as Pinia from "pinia";
5
+ // Expose Vue, Pinia, and store to window for browser console access and platform compatibility
6
+ // This allows dynamically loaded plugins to use the same Vue/Pinia instances
7
+ window.Vue = Vue;
8
+ window.Pinia = Pinia;
9
+
10
+
11
+ // Import PortalContainer from the toolkit's runtime
12
+ import App from "@gx-runtime/PortalContainer.vue";
13
+
14
+ const app = createApp(App);
15
+ app.use(pinia);
16
+
17
+ import { useGxpStore, pinia } from "@/stores/index.js";
18
+ import { createGxpStringsPlugin } from "@gx-runtime/gxpStringsPlugin.js";
19
+
20
+ // window.pinia = pinia; // The active pinia instance
21
+ window.useGxpStore = { useGxpStore };
22
+
23
+
24
+ // Initialize the GxP store and register the strings plugin
25
+ const gxpStore = useGxpStore();
26
+ app.use(createGxpStringsPlugin(gxpStore));
27
+
28
+ app.mount("#app");
@@ -0,0 +1,459 @@
1
+ <template>
2
+ <div class="plugin-container">
3
+ <!-- Example usage of the GxP Datastore -->
4
+ <div class="content-wrapper">
5
+ <h1 gxp-string="welcome_text">Welcome!</h1>
6
+
7
+ <div class="info-section">
8
+ <h2>Plugin Information</h2>
9
+ <p><strong>Primary Color:</strong> <span gxp-string="primary_color"></span></p>
10
+ <p><strong>Project ID:</strong> <span gxp-settings gxp-string="projectId"></span></p>
11
+ <p><strong>Environment:</strong> <span gxp-settings gxp-string="environment"></span></p>
12
+ </div>
13
+
14
+ <div class="assets-section">
15
+ <h2>Assets</h2>
16
+ <img
17
+ v-if="gxpStore.getAsset('main_logo')"
18
+ :src="gxpStore.getAsset('main_logo')"
19
+ alt="Main Logo"
20
+ class="logo"
21
+ />
22
+ <div class="asset-controls">
23
+ <button @click="addDevAssets" class="action-btn secondary small">
24
+ Add Dev Assets
25
+ </button>
26
+ <button @click="listAllAssets" class="action-btn secondary small">
27
+ List Assets
28
+ </button>
29
+ <button @click="updateLogo" class="action-btn secondary small">
30
+ Update Logo
31
+ </button>
32
+ </div>
33
+ <div v-if="currentAssets" class="asset-preview">
34
+ <h3>Current Assets:</h3>
35
+ <div v-for="(url, key) in currentAssets" :key="key" class="asset-item">
36
+ <strong>{{ key }}:</strong>
37
+ <a :href="url" target="_blank" class="asset-link">{{ url }}</a>
38
+ </div>
39
+ </div>
40
+ </div>
41
+
42
+ <div class="actions-section">
43
+ <button
44
+ @click="handleApiCall"
45
+ class="action-btn"
46
+ :style="{ backgroundColor: gxpStore.getSetting('primary_color') }"
47
+ >
48
+ {{ gxpStore.getString('continue_button', 'Continue') }}
49
+ </button>
50
+
51
+ <button
52
+ @click="handleSocketTest"
53
+ class="action-btn secondary"
54
+ >
55
+ Test Socket
56
+ </button>
57
+
58
+ <button
59
+ @click="props.router?.visit('/start')"
60
+ class="action-btn secondary"
61
+ >
62
+ {{ gxpStore.getString('back_button', 'Back') }}
63
+ </button>
64
+ </div>
65
+
66
+ <div class="permissions-section">
67
+ <h2>Permissions</h2>
68
+ <ul>
69
+ <li v-for="permission in ['can_access_camera', 'can_save_data', 'can_share_content']" :key="permission">
70
+ {{ permission }}:
71
+ <span :class="gxpStore.hasPermission(permission) ? 'granted' : 'denied'">
72
+ {{ gxpStore.hasPermission(permission) ? 'Granted' : 'Denied' }}
73
+ </span>
74
+ </li>
75
+ </ul>
76
+ </div>
77
+
78
+ <div class="dependencies-section">
79
+ <h2>Available Dependencies</h2>
80
+ <div v-if="Array.isArray(gxpStore.dependencyList)">
81
+ <div v-for="dependency in gxpStore.dependencyList" :key="dependency.identifier" class="dependency-item">
82
+ <h3>{{ dependency.identifier }}</h3>
83
+ <p><strong>Model:</strong> {{ dependency.model }}</p>
84
+ <p><strong>Events:</strong> {{ Object.keys(dependency.events || {}).join(', ') || 'None' }}</p>
85
+ <button
86
+ @click="testDependencyAPI(dependency.identifier)"
87
+ class="action-btn secondary small"
88
+ >
89
+ Test API
90
+ </button>
91
+ <button
92
+ v-if="dependency.events && Object.keys(dependency.events).length > 0"
93
+ @click="setupDependencyListeners(dependency)"
94
+ class="action-btn secondary small"
95
+ >
96
+ Listen for Events
97
+ </button>
98
+ </div>
99
+ </div>
100
+ <div v-else>
101
+ <ul>
102
+ <li v-for="(id, key) in gxpStore.dependencyList" :key="key">
103
+ {{ key }}: {{ id }}
104
+ </li>
105
+ </ul>
106
+ </div>
107
+ </div>
108
+
109
+ <!-- Example of how to use socket listeners -->
110
+ <div class="socket-section">
111
+ <h2>Socket Events</h2>
112
+ <button @click="emitTestEvent" class="action-btn secondary">
113
+ Emit Test Event
114
+ </button>
115
+ <div v-if="socketMessages.length > 0" class="socket-messages">
116
+ <h3>Received Messages:</h3>
117
+ <ul>
118
+ <li v-for="(message, index) in socketMessages" :key="index">
119
+ {{ message }}
120
+ </li>
121
+ </ul>
122
+ </div>
123
+ </div>
124
+
125
+ <!-- Complete button -->
126
+ <div class="complete-section">
127
+ <button
128
+ @click="props.router?.visit('/final')"
129
+ class="action-btn complete"
130
+ :style="{ backgroundColor: gxpStore.getSetting('final_background_color') }"
131
+ >
132
+ Complete Experience
133
+ </button>
134
+ </div>
135
+ </div>
136
+ </div>
137
+ </template>
138
+
139
+ <style scoped>
140
+ .plugin-container {
141
+ padding: 20px;
142
+ max-width: 800px;
143
+ margin: 0 auto;
144
+ font-family: Arial, sans-serif;
145
+ }
146
+
147
+ .content-wrapper {
148
+ background: white;
149
+ border-radius: 8px;
150
+ padding: 30px;
151
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
152
+ }
153
+
154
+ h1 {
155
+ color: v-bind('gxpStore.getSetting("primary_color")');
156
+ text-align: center;
157
+ margin-bottom: 30px;
158
+ }
159
+
160
+ h2 {
161
+ color: #333;
162
+ border-bottom: 2px solid #eee;
163
+ padding-bottom: 10px;
164
+ margin: 20px 0 15px 0;
165
+ }
166
+
167
+ .info-section,
168
+ .assets-section,
169
+ .actions-section,
170
+ .permissions-section,
171
+ .dependencies-section,
172
+ .socket-section,
173
+ .complete-section {
174
+ margin: 20px 0;
175
+ }
176
+
177
+ .logo {
178
+ max-width: 200px;
179
+ height: auto;
180
+ display: block;
181
+ margin: 10px 0;
182
+ }
183
+
184
+ .action-btn {
185
+ background-color: #007bff;
186
+ color: white;
187
+ border: none;
188
+ padding: 12px 24px;
189
+ margin: 5px;
190
+ border-radius: 4px;
191
+ cursor: pointer;
192
+ font-size: 16px;
193
+ transition: background-color 0.3s;
194
+ }
195
+
196
+ .action-btn:hover {
197
+ opacity: 0.9;
198
+ }
199
+
200
+ .action-btn.secondary {
201
+ background-color: #6c757d;
202
+ }
203
+
204
+ .action-btn.complete {
205
+ background-color: #28a745;
206
+ font-size: 18px;
207
+ padding: 15px 30px;
208
+ display: block;
209
+ margin: 20px auto 0;
210
+ }
211
+
212
+ .granted {
213
+ color: #28a745;
214
+ font-weight: bold;
215
+ }
216
+
217
+ .denied {
218
+ color: #dc3545;
219
+ font-weight: bold;
220
+ }
221
+
222
+ .socket-messages {
223
+ background: #f8f9fa;
224
+ padding: 15px;
225
+ border-radius: 4px;
226
+ margin-top: 10px;
227
+ }
228
+
229
+ .dependency-item {
230
+ background: #f8f9fa;
231
+ padding: 15px;
232
+ margin: 10px 0;
233
+ border-radius: 4px;
234
+ border-left: 4px solid #007bff;
235
+ }
236
+
237
+ .dependency-item h3 {
238
+ margin: 0 0 10px 0;
239
+ color: #007bff;
240
+ }
241
+
242
+ .action-btn.small {
243
+ padding: 8px 16px;
244
+ font-size: 14px;
245
+ margin: 2px;
246
+ }
247
+
248
+ ul {
249
+ list-style-type: none;
250
+ padding: 0;
251
+ }
252
+
253
+ li {
254
+ padding: 5px 0;
255
+ border-bottom: 1px solid #eee;
256
+ }
257
+
258
+ li:last-child {
259
+ border-bottom: none;
260
+ }
261
+
262
+ .asset-controls {
263
+ margin: 15px 0;
264
+ }
265
+
266
+ .asset-preview {
267
+ background: #f8f9fa;
268
+ padding: 15px;
269
+ border-radius: 4px;
270
+ margin-top: 15px;
271
+ }
272
+
273
+ .asset-preview h3 {
274
+ margin: 0 0 10px 0;
275
+ color: #333;
276
+ }
277
+
278
+ .asset-item {
279
+ margin: 8px 0;
280
+ padding: 8px;
281
+ background: white;
282
+ border-radius: 4px;
283
+ border-left: 3px solid #007bff;
284
+ }
285
+
286
+ .asset-link {
287
+ color: #007bff;
288
+ text-decoration: none;
289
+ word-break: break-all;
290
+ }
291
+
292
+ .asset-link:hover {
293
+ text-decoration: underline;
294
+ }
295
+ </style>
296
+
297
+ <script setup>
298
+ defineOptions({
299
+ inheritAttrs: false,
300
+ });
301
+
302
+ import { ref, onMounted, onUnmounted } from 'vue';
303
+
304
+ // Initialize the GxP store
305
+ import { useGxpStore } from "@/stores/gxpPortalConfigStore";
306
+
307
+ const gxpStore = useGxpStore();
308
+
309
+ // Define props (router will be passed from platform)
310
+ const props = defineProps({
311
+ router: {
312
+ type: Object,
313
+ required: false,
314
+ default: () => ({
315
+ visit: (url, options) => console.log('Router not available:', url, options)
316
+ }),
317
+ },
318
+ });
319
+
320
+ // Router is now available as props.router for navigation
321
+
322
+ // Local state
323
+ const socketMessages = ref([]);
324
+ const socketUnsubscribers = ref([]);
325
+ const currentAssets = ref(null);
326
+
327
+ // Example API call using the store
328
+ async function handleApiCall() {
329
+ try {
330
+ console.log('Making API call...');
331
+ // Example API call - this would work with your actual API
332
+ // const result = await gxpStore.apiGet('/some-endpoint');
333
+ // console.log('API Result:', result);
334
+
335
+ // For demo purposes, simulate API call
336
+ setTimeout(() => {
337
+ console.log('Simulated API call completed');
338
+ }, 1000);
339
+
340
+ } catch (error) {
341
+ console.error('API call failed:', error);
342
+ }
343
+ }
344
+
345
+ // Example dependency API call using new methods
346
+ async function testDependencyAPI(identifier) {
347
+ try {
348
+ console.log(`Testing API for dependency: ${identifier}`);
349
+
350
+ // Example of the new getList method
351
+ // const result = await gxpStore.getList(identifier, { page: 1, limit: 10 });
352
+ // console.log(`API Result for ${identifier}:`, result);
353
+
354
+ // For demo purposes, simulate API call
355
+ socketMessages.value.unshift(`API call simulated for ${identifier}`);
356
+
357
+ } catch (error) {
358
+ console.error(`API call failed for ${identifier}:`, error);
359
+ socketMessages.value.unshift(`API call failed for ${identifier}: ${error.message}`);
360
+ }
361
+ }
362
+
363
+ // Set up socket listeners for a specific dependency
364
+ function setupDependencyListeners(dependency) {
365
+ console.log(`Setting up listeners for ${dependency.identifier}`);
366
+
367
+ // Set up listeners for each event type
368
+ Object.keys(dependency.events || {}).forEach(eventType => {
369
+ const eventName = dependency.events[eventType];
370
+
371
+ if (gxpStore.sockets[dependency.identifier] && gxpStore.sockets[dependency.identifier][eventType]) {
372
+ const unsubscribe = gxpStore.sockets[dependency.identifier][eventType].listen((data) => {
373
+ console.log(`Received ${eventType} event for ${dependency.identifier}:`, data);
374
+ socketMessages.value.unshift(
375
+ `${dependency.identifier}.${eventType}: ${data.message || JSON.stringify(data).substring(0, 50)}...`
376
+ );
377
+ });
378
+
379
+ socketUnsubscribers.value.push(unsubscribe);
380
+ }
381
+ });
382
+
383
+ socketMessages.value.unshift(`Listening for events on ${dependency.identifier}`);
384
+ }
385
+
386
+ // Example socket functionality
387
+ function handleSocketTest() {
388
+ // Emit a test event
389
+ gxpStore.emitSocket('primary', 'test-event', { message: 'Hello from plugin!' });
390
+ console.log('Emitted test event via socket');
391
+ }
392
+
393
+ function emitTestEvent() {
394
+ const timestamp = new Date().toLocaleTimeString();
395
+ gxpStore.emitSocket('primary', 'plugin-message', {
396
+ message: `Test message at ${timestamp}`,
397
+ timestamp: Date.now()
398
+ });
399
+
400
+ socketMessages.value.unshift(`Sent: Test message at ${timestamp}`);
401
+ }
402
+
403
+ // Asset management methods
404
+ function addDevAssets() {
405
+ // Add some development assets using the convenience method
406
+ gxpStore.addDevAsset('main_logo', 'logo-placeholder.png');
407
+ gxpStore.addDevAsset('background_image', 'background-placeholder.jpg');
408
+ gxpStore.addDevAsset('product_image', 'product-placeholder.jpg');
409
+ gxpStore.addDevAsset('avatar_placeholder', 'avatar-placeholder.png');
410
+
411
+ console.log('Added development assets');
412
+ listAllAssets();
413
+ }
414
+
415
+ function listAllAssets() {
416
+ currentAssets.value = gxpStore.listAssets();
417
+ console.log('Listed all assets');
418
+ }
419
+
420
+ function updateLogo() {
421
+ // Example of updating a specific asset
422
+ const appPort = window.location.port || 3000;
423
+ const appProtocol = window.location.protocol || 'http';
424
+ const newLogoUrl = `${appProtocol}://localhost:${appPort}/dev-assets/images/logo-placeholder.png`;
425
+ gxpStore.updateAsset('main_logo', newLogoUrl);
426
+ console.log('Updated logo asset');
427
+ listAllAssets();
428
+ }
429
+
430
+ // Set up socket listeners when component mounts
431
+ onMounted(() => {
432
+ // Listen for test events
433
+ const unsubscribe1 = gxpStore.useSocketListener('primary', 'test-response', (data) => {
434
+ console.log('Received test response:', data);
435
+ socketMessages.value.unshift(`Received: ${JSON.stringify(data)}`);
436
+ });
437
+
438
+ // Listen for any incoming messages
439
+ const unsubscribe2 = gxpStore.useSocketListener('primary', 'incoming-message', (data) => {
440
+ console.log('Received incoming message:', data);
441
+ socketMessages.value.unshift(`Incoming: ${data.message || JSON.stringify(data)}`);
442
+ });
443
+
444
+ // Store unsubscribers for cleanup
445
+ socketUnsubscribers.value = [unsubscribe1, unsubscribe2];
446
+
447
+ console.log('Plugin component mounted with GxP Datastore');
448
+ console.log('Available store methods:', Object.keys(gxpStore));
449
+ });
450
+
451
+ // Clean up socket listeners when component unmounts
452
+ onUnmounted(() => {
453
+ socketUnsubscribers.value.forEach(unsubscribe => {
454
+ if (typeof unsubscribe === 'function') {
455
+ unsubscribe();
456
+ }
457
+ });
458
+ });
459
+ </script>
@@ -0,0 +1,38 @@
1
+ <template>
2
+ <!-- Your Custom Plugin Content -->
3
+ <DemoPage
4
+ :router="mockRouter"
5
+ />
6
+ </template>
7
+
8
+ <style scoped>
9
+ #app {
10
+ font-family: Avenir, Helvetica, Arial, sans-serif;
11
+ -webkit-font-smoothing: antialiased;
12
+ -moz-osx-font-smoothing: grayscale;
13
+ }
14
+ </style>
15
+
16
+ <script setup>
17
+ import { ref, shallowRef } from "vue";
18
+ import DemoPage from "@/DemoPage.vue";
19
+ import {
20
+ GxPageStart,
21
+ GxPageFinal,
22
+ GxPageLoading
23
+ } from "@gramercytech/gx-componentkit";
24
+
25
+ // Initialize the GxP store
26
+ // This import is externalized to window.useGxpStore during build for platform compatibility
27
+ import { useGxpStore } from "@/stores/gxpPortalConfigStore";
28
+
29
+
30
+
31
+ const gxpStore = useGxpStore();
32
+ gxpStore.sockets?.primary.listenForStateChange((event) => {
33
+ console.log('🔗 GXP Store: State change event received', event);
34
+ })
35
+
36
+
37
+
38
+ </script>
@@ -0,0 +1,9 @@
1
+ // Import from package runtime directory by default
2
+ // To customize, run: gxdev publish gxpPortalConfigStore.js
3
+ // Then update this import to: import { useGxpStore } from './gxpPortalConfigStore.js';
4
+ import { useGxpStore } from "@gramercytech/gx-devtools/runtime/stores/gxpPortalConfigStore";
5
+
6
+ // Expose to window for platform compatibility and externalized imports
7
+ window.useGxpStore = useGxpStore;
8
+
9
+ export { useGxpStore };