@gxp-dev/tools 2.0.5
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/.github/workflows/npm-publish.yml +48 -0
- package/CLAUDE.md +400 -0
- package/README.md +247 -0
- package/REFACTOR_PLAN.md +194 -0
- package/bin/gx-devtools.js +87 -0
- package/bin/lib/cli.js +251 -0
- package/bin/lib/commands/assets.js +337 -0
- package/bin/lib/commands/build.js +259 -0
- package/bin/lib/commands/datastore.js +433 -0
- package/bin/lib/commands/dev.js +328 -0
- package/bin/lib/commands/extensions.js +298 -0
- package/bin/lib/commands/index.js +35 -0
- package/bin/lib/commands/init.js +307 -0
- package/bin/lib/commands/publish.js +189 -0
- package/bin/lib/commands/socket.js +158 -0
- package/bin/lib/commands/ssl.js +47 -0
- package/bin/lib/constants.js +120 -0
- package/bin/lib/tui/App.tsx +600 -0
- package/bin/lib/tui/components/CommandInput.tsx +278 -0
- package/bin/lib/tui/components/GeminiPanel.tsx +161 -0
- package/bin/lib/tui/components/Header.tsx +27 -0
- package/bin/lib/tui/components/LogPanel.tsx +122 -0
- package/bin/lib/tui/components/TabBar.tsx +56 -0
- package/bin/lib/tui/components/WelcomeScreen.tsx +80 -0
- package/bin/lib/tui/index.tsx +63 -0
- package/bin/lib/tui/services/ExtensionService.ts +122 -0
- package/bin/lib/tui/services/GeminiService.ts +395 -0
- package/bin/lib/tui/services/ServiceManager.ts +336 -0
- package/bin/lib/tui/services/SocketService.ts +204 -0
- package/bin/lib/tui/services/ViteService.ts +107 -0
- package/bin/lib/tui/services/index.ts +13 -0
- package/bin/lib/utils/files.js +180 -0
- package/bin/lib/utils/index.js +17 -0
- package/bin/lib/utils/paths.js +138 -0
- package/bin/lib/utils/prompts.js +71 -0
- package/bin/lib/utils/ssl.js +233 -0
- package/browser-extensions/README.md +1 -0
- package/browser-extensions/chrome/background.js +857 -0
- package/browser-extensions/chrome/content.js +51 -0
- package/browser-extensions/chrome/devtools.html +9 -0
- package/browser-extensions/chrome/devtools.js +23 -0
- package/browser-extensions/chrome/icons/gx_off_128.png +0 -0
- package/browser-extensions/chrome/icons/gx_off_16.png +0 -0
- package/browser-extensions/chrome/icons/gx_off_32.png +0 -0
- package/browser-extensions/chrome/icons/gx_off_64.png +0 -0
- package/browser-extensions/chrome/icons/gx_on_128.png +0 -0
- package/browser-extensions/chrome/icons/gx_on_16.png +0 -0
- package/browser-extensions/chrome/icons/gx_on_32.png +0 -0
- package/browser-extensions/chrome/icons/gx_on_64.png +0 -0
- package/browser-extensions/chrome/inspector.js +1087 -0
- package/browser-extensions/chrome/manifest.json +70 -0
- package/browser-extensions/chrome/panel.html +638 -0
- package/browser-extensions/chrome/panel.js +862 -0
- package/browser-extensions/chrome/popup.html +399 -0
- package/browser-extensions/chrome/popup.js +515 -0
- package/browser-extensions/chrome/rules.json +1 -0
- package/browser-extensions/chrome/test-chrome.html +145 -0
- package/browser-extensions/chrome/test-mixed-content.html +190 -0
- package/browser-extensions/chrome/test-uri-pattern.html +199 -0
- package/browser-extensions/firefox/README.md +134 -0
- package/browser-extensions/firefox/background.js +804 -0
- package/browser-extensions/firefox/content.js +120 -0
- package/browser-extensions/firefox/debug-errors.html +229 -0
- package/browser-extensions/firefox/debug-https.html +113 -0
- package/browser-extensions/firefox/devtools.html +9 -0
- package/browser-extensions/firefox/devtools.js +24 -0
- package/browser-extensions/firefox/icons/gx_off_128.png +0 -0
- package/browser-extensions/firefox/icons/gx_off_16.png +0 -0
- package/browser-extensions/firefox/icons/gx_off_32.png +0 -0
- package/browser-extensions/firefox/icons/gx_off_64.png +0 -0
- package/browser-extensions/firefox/icons/gx_on_128.png +0 -0
- package/browser-extensions/firefox/icons/gx_on_16.png +0 -0
- package/browser-extensions/firefox/icons/gx_on_32.png +0 -0
- package/browser-extensions/firefox/icons/gx_on_64.png +0 -0
- package/browser-extensions/firefox/inspector.js +1087 -0
- package/browser-extensions/firefox/manifest.json +67 -0
- package/browser-extensions/firefox/panel.html +638 -0
- package/browser-extensions/firefox/panel.js +862 -0
- package/browser-extensions/firefox/popup.html +525 -0
- package/browser-extensions/firefox/popup.js +536 -0
- package/browser-extensions/firefox/test-gramercy.html +126 -0
- package/browser-extensions/firefox/test-imports.html +58 -0
- package/browser-extensions/firefox/test-masking.html +147 -0
- package/browser-extensions/firefox/test-uri-pattern.html +199 -0
- package/docs/DOCUSAURUS_IMPORT.md +378 -0
- package/docs/_category_.json +8 -0
- package/docs/app-manifest.md +272 -0
- package/docs/building-for-platform.md +315 -0
- package/docs/dev-tools.md +291 -0
- package/docs/getting-started.md +180 -0
- package/docs/gxp-store.md +305 -0
- package/docs/index.md +44 -0
- package/package.json +77 -0
- package/runtime/PortalContainer.vue +326 -0
- package/runtime/dev-tools/DevToolsModal.vue +217 -0
- package/runtime/dev-tools/LayoutSwitcher.vue +221 -0
- package/runtime/dev-tools/MockDataEditor.vue +621 -0
- package/runtime/dev-tools/SocketSimulator.vue +562 -0
- package/runtime/dev-tools/StoreInspector.vue +644 -0
- package/runtime/dev-tools/index.js +6 -0
- package/runtime/gxpStringsPlugin.js +428 -0
- package/runtime/index.html +22 -0
- package/runtime/main.js +32 -0
- package/runtime/mock-api/auth-middleware.js +97 -0
- package/runtime/mock-api/image-generator.js +221 -0
- package/runtime/mock-api/index.js +197 -0
- package/runtime/mock-api/response-generator.js +394 -0
- package/runtime/mock-api/route-generator.js +323 -0
- package/runtime/mock-api/socket-triggers.js +371 -0
- package/runtime/mock-api/spec-loader.js +300 -0
- package/runtime/server.js +180 -0
- package/runtime/stores/gxpPortalConfigStore.js +554 -0
- package/runtime/stores/index.js +6 -0
- package/runtime/vite-inspector-plugin.js +749 -0
- package/runtime/vite-source-tracker-plugin.js +232 -0
- package/runtime/vite.config.js +402 -0
- package/scripts/launch-chrome.js +90 -0
- package/scripts/pack-chrome.js +91 -0
- package/socket-events/AiSessionMessageCreated.json +18 -0
- package/socket-events/SocialStreamPostCreated.json +24 -0
- package/socket-events/SocialStreamPostVariantCompleted.json +23 -0
- package/template/README.md +332 -0
- package/template/app-manifest.json +32 -0
- package/template/dev-assets/images/avatar-placeholder.png +0 -0
- package/template/dev-assets/images/background-placeholder.jpg +0 -0
- package/template/dev-assets/images/banner-placeholder.jpg +0 -0
- package/template/dev-assets/images/icon-placeholder.png +0 -0
- package/template/dev-assets/images/logo-placeholder.png +0 -0
- package/template/dev-assets/images/product-placeholder.jpg +0 -0
- package/template/dev-assets/images/thumbnail-placeholder.jpg +0 -0
- package/template/env.example +51 -0
- package/template/gitignore +53 -0
- package/template/index.html +22 -0
- package/template/main.js +28 -0
- package/template/src/DemoPage.vue +459 -0
- package/template/src/Plugin.vue +38 -0
- package/template/src/stores/index.js +9 -0
- package/template/src/stores/test-data.json +173 -0
- package/template/theme-layouts/AdditionalStyling.css +0 -0
- package/template/theme-layouts/PrivateLayout.vue +39 -0
- package/template/theme-layouts/PublicLayout.vue +39 -0
- package/template/theme-layouts/SystemLayout.vue +39 -0
- package/template/vite.config.js +333 -0
- package/tsconfig.tui.json +21 -0
- package/vite.config.js +164 -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>
|
package/template/main.js
ADDED
|
@@ -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 };
|