@gxp-dev/tools 2.0.5 → 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.
- package/dist/tui/App.d.ts +13 -0
- package/dist/tui/App.d.ts.map +1 -0
- package/dist/tui/App.js +480 -0
- package/dist/tui/App.js.map +1 -0
- package/dist/tui/components/CommandInput.d.ts +13 -0
- package/dist/tui/components/CommandInput.d.ts.map +1 -0
- package/dist/tui/components/CommandInput.js +180 -0
- package/dist/tui/components/CommandInput.js.map +1 -0
- package/dist/tui/components/GeminiPanel.d.ts +7 -0
- package/dist/tui/components/GeminiPanel.d.ts.map +1 -0
- package/dist/tui/components/GeminiPanel.js +99 -0
- package/dist/tui/components/GeminiPanel.js.map +1 -0
- package/dist/tui/components/Header.d.ts +6 -0
- package/dist/tui/components/Header.d.ts.map +1 -0
- package/dist/tui/components/Header.js +6 -0
- package/dist/tui/components/Header.js.map +1 -0
- package/dist/tui/components/LogPanel.d.ts +8 -0
- package/dist/tui/components/LogPanel.d.ts.map +1 -0
- package/dist/tui/components/LogPanel.js +89 -0
- package/dist/tui/components/LogPanel.js.map +1 -0
- package/dist/tui/components/TabBar.d.ts +9 -0
- package/dist/tui/components/TabBar.d.ts.map +1 -0
- package/dist/tui/components/TabBar.js +23 -0
- package/dist/tui/components/TabBar.js.map +1 -0
- package/dist/tui/components/WelcomeScreen.d.ts +2 -0
- package/dist/tui/components/WelcomeScreen.d.ts.map +1 -0
- package/dist/tui/components/WelcomeScreen.js +14 -0
- package/dist/tui/components/WelcomeScreen.js.map +1 -0
- package/dist/tui/index.d.ts +8 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +47 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/package.json +1 -0
- package/dist/tui/services/ExtensionService.d.ts +11 -0
- package/dist/tui/services/ExtensionService.d.ts.map +1 -0
- package/dist/tui/services/ExtensionService.js +101 -0
- package/dist/tui/services/ExtensionService.js.map +1 -0
- package/dist/tui/services/GeminiService.d.ts +40 -0
- package/dist/tui/services/GeminiService.d.ts.map +1 -0
- package/dist/tui/services/GeminiService.js +327 -0
- package/dist/tui/services/GeminiService.js.map +1 -0
- package/dist/tui/services/ServiceManager.d.ts +40 -0
- package/dist/tui/services/ServiceManager.d.ts.map +1 -0
- package/dist/tui/services/ServiceManager.js +283 -0
- package/dist/tui/services/ServiceManager.js.map +1 -0
- package/dist/tui/services/SocketService.d.ts +19 -0
- package/dist/tui/services/SocketService.d.ts.map +1 -0
- package/dist/tui/services/SocketService.js +163 -0
- package/dist/tui/services/SocketService.js.map +1 -0
- package/dist/tui/services/ViteService.d.ts +8 -0
- package/dist/tui/services/ViteService.d.ts.map +1 -0
- package/dist/tui/services/ViteService.js +89 -0
- package/dist/tui/services/ViteService.js.map +1 -0
- package/dist/tui/services/index.d.ts +6 -0
- package/dist/tui/services/index.d.ts.map +1 -0
- package/dist/tui/services/index.js +6 -0
- package/dist/tui/services/index.js.map +1 -0
- package/package.json +11 -1
- package/.github/workflows/npm-publish.yml +0 -48
- package/CLAUDE.md +0 -400
- package/REFACTOR_PLAN.md +0 -194
- package/docs/DOCUSAURUS_IMPORT.md +0 -378
- package/docs/_category_.json +0 -8
- package/docs/app-manifest.md +0 -272
- package/docs/building-for-platform.md +0 -315
- package/docs/dev-tools.md +0 -291
- package/docs/getting-started.md +0 -180
- package/docs/gxp-store.md +0 -305
- package/docs/index.md +0 -44
- package/tsconfig.tui.json +0 -21
- package/vite.config.js +0 -164
package/docs/getting-started.md
DELETED
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
sidebar_position: 2
|
|
3
|
-
title: Getting Started
|
|
4
|
-
description: Install the GxP Toolkit and create your first plugin project
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Getting Started
|
|
8
|
-
|
|
9
|
-
This guide walks you through installing the GxP Toolkit and creating your first plugin project.
|
|
10
|
-
|
|
11
|
-
## Prerequisites
|
|
12
|
-
|
|
13
|
-
Before you begin, ensure you have:
|
|
14
|
-
|
|
15
|
-
- **Node.js 18+** - [Download Node.js](https://nodejs.org/)
|
|
16
|
-
- **npm 8+** - Comes with Node.js
|
|
17
|
-
- **Code editor** - VS Code recommended
|
|
18
|
-
|
|
19
|
-
## Installation
|
|
20
|
-
|
|
21
|
-
### Option 1: Global Installation (Recommended)
|
|
22
|
-
|
|
23
|
-
Install the toolkit globally to use the `gxdev` command anywhere:
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
npm install -g @gramercytech/gx-devtools
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
### Option 2: Project-Level Installation
|
|
30
|
-
|
|
31
|
-
Or install as a dev dependency in an existing project:
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
npm install --save-dev @gramercytech/gx-devtools
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Create a New Plugin
|
|
38
|
-
|
|
39
|
-
### 1. Initialize Your Project
|
|
40
|
-
|
|
41
|
-
Create a new plugin project using the CLI:
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
# Create a new directory and initialize
|
|
45
|
-
mkdir my-plugin
|
|
46
|
-
cd my-plugin
|
|
47
|
-
gxdev init my-plugin
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
This creates a complete project structure with:
|
|
51
|
-
|
|
52
|
-
- `src/Plugin.vue` - Your main plugin component
|
|
53
|
-
- `app-manifest.json` - Plugin configuration
|
|
54
|
-
- `theme-layouts/` - Layout components for different contexts
|
|
55
|
-
- `dev-assets/` - Development placeholder assets
|
|
56
|
-
|
|
57
|
-
### 2. Install Dependencies
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
npm install
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
### 3. Start Development Server
|
|
64
|
-
|
|
65
|
-
Start the development server with hot reload:
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
# With HTTPS (recommended)
|
|
69
|
-
npm run dev
|
|
70
|
-
|
|
71
|
-
# Without HTTPS (simpler setup)
|
|
72
|
-
npm run dev-http
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Your plugin is now running at `https://localhost:3060` (or `http://localhost:3060`).
|
|
76
|
-
|
|
77
|
-
## Project Structure
|
|
78
|
-
|
|
79
|
-
After initialization, your project looks like this:
|
|
80
|
-
|
|
81
|
-
```
|
|
82
|
-
my-plugin/
|
|
83
|
-
├── src/
|
|
84
|
-
│ ├── Plugin.vue # Main plugin entry point
|
|
85
|
-
│ ├── DemoPage.vue # Example component
|
|
86
|
-
│ └── stores/
|
|
87
|
-
│ └── index.js # Store setup
|
|
88
|
-
├── theme-layouts/
|
|
89
|
-
│ ├── PublicLayout.vue # Public-facing layout
|
|
90
|
-
│ ├── PrivateLayout.vue # Authenticated layout
|
|
91
|
-
│ └── SystemLayout.vue # System/admin layout
|
|
92
|
-
├── dev-assets/
|
|
93
|
-
│ └── images/ # Development placeholder images
|
|
94
|
-
├── app-manifest.json # Plugin configuration
|
|
95
|
-
├── vite.config.js # Vite configuration
|
|
96
|
-
├── main.js # Development entry point
|
|
97
|
-
├── index.html # Development HTML template
|
|
98
|
-
└── .env # Environment variables
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
## Your First Edit
|
|
102
|
-
|
|
103
|
-
Open `src/Plugin.vue` and make a change:
|
|
104
|
-
|
|
105
|
-
```vue
|
|
106
|
-
<template>
|
|
107
|
-
<div class="my-plugin">
|
|
108
|
-
<h1 gxp-string="welcome_title">Welcome to My Plugin!</h1>
|
|
109
|
-
<p>Edit this file to get started.</p>
|
|
110
|
-
</div>
|
|
111
|
-
</template>
|
|
112
|
-
|
|
113
|
-
<script setup>
|
|
114
|
-
import { useGxpStore } from '@gx-runtime/stores/gxpPortalConfigStore';
|
|
115
|
-
|
|
116
|
-
const store = useGxpStore();
|
|
117
|
-
</script>
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
The page automatically refreshes with your changes.
|
|
121
|
-
|
|
122
|
-
## SSL Setup (Optional)
|
|
123
|
-
|
|
124
|
-
For HTTPS development (required for some platform features):
|
|
125
|
-
|
|
126
|
-
```bash
|
|
127
|
-
npm run setup-ssl
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
This uses [mkcert](https://github.com/FiloSottile/mkcert) to generate trusted local certificates.
|
|
131
|
-
|
|
132
|
-
## Using the Interactive TUI
|
|
133
|
-
|
|
134
|
-
Run `gxdev` without arguments to launch the interactive Terminal UI:
|
|
135
|
-
|
|
136
|
-
```bash
|
|
137
|
-
gxdev
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
The TUI provides:
|
|
141
|
-
|
|
142
|
-
- **Service management** - Start/stop Vite, Socket.IO, extensions
|
|
143
|
-
- **Log viewing** - Real-time logs from all services
|
|
144
|
-
- **Slash commands** - Quick actions like `/dev`, `/socket`, `/ext chrome`
|
|
145
|
-
|
|
146
|
-
### TUI Keyboard Shortcuts
|
|
147
|
-
|
|
148
|
-
| Shortcut | Action |
|
|
149
|
-
|----------|--------|
|
|
150
|
-
| `Ctrl+1/2/3...` | Switch service tabs |
|
|
151
|
-
| `Ctrl+L` | Clear current log |
|
|
152
|
-
| `Ctrl+C` | Exit application |
|
|
153
|
-
| `Up/Down` | Scroll log panel |
|
|
154
|
-
|
|
155
|
-
## Next Steps
|
|
156
|
-
|
|
157
|
-
- [Configure your app manifest](./app-manifest) - Set up strings, settings, and assets
|
|
158
|
-
- [Learn the GxP Store](./gxp-store) - State management and platform integration
|
|
159
|
-
- [Use Dev Tools](./dev-tools) - Debug and inspect your plugin
|
|
160
|
-
- [Build for platform](./building-for-platform) - Prepare for production deployment
|
|
161
|
-
|
|
162
|
-
## Common Commands Reference
|
|
163
|
-
|
|
164
|
-
```bash
|
|
165
|
-
# Development
|
|
166
|
-
gxdev dev # Start with TUI + Vite
|
|
167
|
-
gxdev dev --no-https # Start without SSL
|
|
168
|
-
gxdev dev --with-socket # Include Socket.IO server
|
|
169
|
-
gxdev dev --chrome # Launch with Chrome extension
|
|
170
|
-
gxdev dev --firefox # Launch with Firefox extension
|
|
171
|
-
|
|
172
|
-
# Building
|
|
173
|
-
gxdev build # Build for production
|
|
174
|
-
|
|
175
|
-
# Utilities
|
|
176
|
-
gxdev datastore list # List store variables
|
|
177
|
-
gxdev datastore scan-strings # Find hardcoded strings
|
|
178
|
-
gxdev socket list # List socket events
|
|
179
|
-
gxdev assets generate # Generate placeholder images
|
|
180
|
-
```
|
package/docs/gxp-store.md
DELETED
|
@@ -1,305 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
sidebar_position: 4
|
|
3
|
-
title: GxP Store
|
|
4
|
-
description: State management with Pinia and platform integration
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# GxP Store
|
|
8
|
-
|
|
9
|
-
The GxP Store (`gxpPortalConfigStore`) is a Pinia store that provides reactive state management and platform integration for your plugin.
|
|
10
|
-
|
|
11
|
-
## Importing the Store
|
|
12
|
-
|
|
13
|
-
```javascript
|
|
14
|
-
import { useGxpStore } from '@gx-runtime/stores/gxpPortalConfigStore';
|
|
15
|
-
|
|
16
|
-
// In your component setup
|
|
17
|
-
const store = useGxpStore();
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## Store Sections
|
|
21
|
-
|
|
22
|
-
The store contains several reactive sections populated from your `app-manifest.json` and the platform:
|
|
23
|
-
|
|
24
|
-
| Section | Description | Source |
|
|
25
|
-
|---------|-------------|--------|
|
|
26
|
-
| `pluginVars` | Plugin settings/configuration | `settings` in manifest |
|
|
27
|
-
| `stringsList` | Translatable strings | `strings.default` in manifest |
|
|
28
|
-
| `assetList` | Asset URLs | `assets` in manifest |
|
|
29
|
-
| `triggerState` | Dynamic runtime state | `triggerState` in manifest |
|
|
30
|
-
| `dependencyList` | External dependencies | Platform-injected |
|
|
31
|
-
| `permissionFlags` | Granted permissions | Platform-injected |
|
|
32
|
-
| `theme` | Platform theme colors | Platform-injected |
|
|
33
|
-
| `router` | Navigation methods | Platform-injected |
|
|
34
|
-
|
|
35
|
-
## Getter Methods
|
|
36
|
-
|
|
37
|
-
Use these methods to safely access store values with fallbacks:
|
|
38
|
-
|
|
39
|
-
### `getString(key, defaultValue)`
|
|
40
|
-
|
|
41
|
-
Get a string from `stringsList`:
|
|
42
|
-
|
|
43
|
-
```javascript
|
|
44
|
-
const title = store.getString('welcome_title', 'Welcome');
|
|
45
|
-
const button = store.getString('btn_submit', 'Submit');
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### `getSetting(key, defaultValue)`
|
|
49
|
-
|
|
50
|
-
Get a setting from `pluginVars`:
|
|
51
|
-
|
|
52
|
-
```javascript
|
|
53
|
-
const color = store.getSetting('primary_color', '#000000');
|
|
54
|
-
const timeout = store.getSetting('idle_timeout', 30);
|
|
55
|
-
const enabled = store.getSetting('feature_enabled', false);
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### `getAsset(key, defaultValue)`
|
|
59
|
-
|
|
60
|
-
Get an asset URL from `assetList`:
|
|
61
|
-
|
|
62
|
-
```javascript
|
|
63
|
-
const logo = store.getAsset('logo', '/fallback-logo.png');
|
|
64
|
-
const hero = store.getAsset('hero_image', '/placeholder.jpg');
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### `getState(key, defaultValue)`
|
|
68
|
-
|
|
69
|
-
Get a value from `triggerState`:
|
|
70
|
-
|
|
71
|
-
```javascript
|
|
72
|
-
const step = store.getState('current_step', 1);
|
|
73
|
-
const isActive = store.getState('is_active', false);
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### `hasPermission(permission)`
|
|
77
|
-
|
|
78
|
-
Check if a permission is granted:
|
|
79
|
-
|
|
80
|
-
```javascript
|
|
81
|
-
if (store.hasPermission('camera')) {
|
|
82
|
-
// Camera access is available
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (store.hasPermission('bluetooth')) {
|
|
86
|
-
// Bluetooth access is available
|
|
87
|
-
}
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
## Update Methods
|
|
91
|
-
|
|
92
|
-
### `updateString(key, value)`
|
|
93
|
-
|
|
94
|
-
Update a string value:
|
|
95
|
-
|
|
96
|
-
```javascript
|
|
97
|
-
store.updateString('dynamic_message', 'Processing your request...');
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### `updateSetting(key, value)`
|
|
101
|
-
|
|
102
|
-
Update a setting value:
|
|
103
|
-
|
|
104
|
-
```javascript
|
|
105
|
-
store.updateSetting('current_mode', 'advanced');
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
### `updateAsset(key, url)`
|
|
109
|
-
|
|
110
|
-
Update an asset URL:
|
|
111
|
-
|
|
112
|
-
```javascript
|
|
113
|
-
store.updateAsset('user_avatar', 'https://example.com/avatar.jpg');
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### `updateState(key, value)`
|
|
117
|
-
|
|
118
|
-
Update trigger state:
|
|
119
|
-
|
|
120
|
-
```javascript
|
|
121
|
-
store.updateState('current_step', 2);
|
|
122
|
-
store.updateState('is_loading', true);
|
|
123
|
-
store.updateState('selected_item', { id: 123, name: 'Item' });
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
### `addDevAsset(key, filename)`
|
|
127
|
-
|
|
128
|
-
Add a development asset with the dev server URL prefix:
|
|
129
|
-
|
|
130
|
-
```javascript
|
|
131
|
-
// Automatically prefixes with dev server URL
|
|
132
|
-
store.addDevAsset('temp_image', 'screenshot.png');
|
|
133
|
-
// Result: https://localhost:3060/dev-assets/images/screenshot.png
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
## API Client
|
|
137
|
-
|
|
138
|
-
The store includes an Axios-based API client for making HTTP requests:
|
|
139
|
-
|
|
140
|
-
### `apiGet(endpoint, params)`
|
|
141
|
-
|
|
142
|
-
```javascript
|
|
143
|
-
const response = await store.apiGet('/events/123');
|
|
144
|
-
const events = await store.apiGet('/events', { status: 'active' });
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### `apiPost(endpoint, data)`
|
|
148
|
-
|
|
149
|
-
```javascript
|
|
150
|
-
const result = await store.apiPost('/checkin', {
|
|
151
|
-
attendee_id: 456,
|
|
152
|
-
timestamp: new Date().toISOString()
|
|
153
|
-
});
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
### `apiPut(endpoint, data)`
|
|
157
|
-
|
|
158
|
-
```javascript
|
|
159
|
-
await store.apiPut('/attendees/456', {
|
|
160
|
-
checked_in: true
|
|
161
|
-
});
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
### `apiDelete(endpoint)`
|
|
165
|
-
|
|
166
|
-
```javascript
|
|
167
|
-
await store.apiDelete('/sessions/789');
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
## Socket.IO Integration
|
|
171
|
-
|
|
172
|
-
The store provides methods for real-time communication via Socket.IO:
|
|
173
|
-
|
|
174
|
-
### `emitSocket(channel, event, data)`
|
|
175
|
-
|
|
176
|
-
Send a socket event:
|
|
177
|
-
|
|
178
|
-
```javascript
|
|
179
|
-
store.emitSocket('primary', 'checkin-complete', {
|
|
180
|
-
attendee_id: 123,
|
|
181
|
-
badge_printed: true
|
|
182
|
-
});
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
### `listenSocket(channel, event, callback)`
|
|
186
|
-
|
|
187
|
-
Listen for socket events:
|
|
188
|
-
|
|
189
|
-
```javascript
|
|
190
|
-
store.listenSocket('primary', 'session-updated', (data) => {
|
|
191
|
-
console.log('Session updated:', data);
|
|
192
|
-
store.updateState('current_session', data);
|
|
193
|
-
});
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
### `useSocketListener(dependencyId, event, callback)`
|
|
197
|
-
|
|
198
|
-
Set up a socket listener for a specific dependency:
|
|
199
|
-
|
|
200
|
-
```javascript
|
|
201
|
-
store.useSocketListener('badge-printer', 'print-complete', (result) => {
|
|
202
|
-
if (result.success) {
|
|
203
|
-
store.updateState('badge_printing', false);
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
## Reactive Usage in Templates
|
|
209
|
-
|
|
210
|
-
The store is fully reactive. Use it directly in your templates:
|
|
211
|
-
|
|
212
|
-
```vue
|
|
213
|
-
<template>
|
|
214
|
-
<div :style="{ backgroundColor: store.getSetting('bg_color', '#fff') }">
|
|
215
|
-
<h1>{{ store.getString('title', 'Default Title') }}</h1>
|
|
216
|
-
|
|
217
|
-
<p v-if="store.triggerState.is_loading">Loading...</p>
|
|
218
|
-
|
|
219
|
-
<div v-for="item in store.triggerState.items" :key="item.id">
|
|
220
|
-
{{ item.name }}
|
|
221
|
-
</div>
|
|
222
|
-
</div>
|
|
223
|
-
</template>
|
|
224
|
-
|
|
225
|
-
<script setup>
|
|
226
|
-
import { useGxpStore } from '@gx-runtime/stores/gxpPortalConfigStore';
|
|
227
|
-
|
|
228
|
-
const store = useGxpStore();
|
|
229
|
-
</script>
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
## Watching Store Changes
|
|
233
|
-
|
|
234
|
-
Use Vue's `watch` to react to store changes:
|
|
235
|
-
|
|
236
|
-
```javascript
|
|
237
|
-
import { watch } from 'vue';
|
|
238
|
-
import { useGxpStore } from '@gx-runtime/stores/gxpPortalConfigStore';
|
|
239
|
-
|
|
240
|
-
const store = useGxpStore();
|
|
241
|
-
|
|
242
|
-
// Watch a specific state value
|
|
243
|
-
watch(
|
|
244
|
-
() => store.triggerState.current_step,
|
|
245
|
-
(newStep, oldStep) => {
|
|
246
|
-
console.log(`Step changed from ${oldStep} to ${newStep}`);
|
|
247
|
-
}
|
|
248
|
-
);
|
|
249
|
-
|
|
250
|
-
// Watch multiple values
|
|
251
|
-
watch(
|
|
252
|
-
() => [store.triggerState.is_active, store.pluginVars.mode],
|
|
253
|
-
([isActive, mode]) => {
|
|
254
|
-
if (isActive && mode === 'kiosk') {
|
|
255
|
-
startKioskMode();
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
);
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
## Computed Properties
|
|
262
|
-
|
|
263
|
-
Create computed properties based on store values:
|
|
264
|
-
|
|
265
|
-
```javascript
|
|
266
|
-
import { computed } from 'vue';
|
|
267
|
-
import { useGxpStore } from '@gx-runtime/stores/gxpPortalConfigStore';
|
|
268
|
-
|
|
269
|
-
const store = useGxpStore();
|
|
270
|
-
|
|
271
|
-
const isReady = computed(() =>
|
|
272
|
-
!store.triggerState.is_loading &&
|
|
273
|
-
store.triggerState.data !== null
|
|
274
|
-
);
|
|
275
|
-
|
|
276
|
-
const formattedCount = computed(() =>
|
|
277
|
-
`${store.triggerState.checked_in_count} of ${store.pluginVars.total_expected}`
|
|
278
|
-
);
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
## Theme Integration
|
|
282
|
-
|
|
283
|
-
Access platform theme values:
|
|
284
|
-
|
|
285
|
-
```javascript
|
|
286
|
-
const store = useGxpStore();
|
|
287
|
-
|
|
288
|
-
// Theme colors
|
|
289
|
-
const primaryColor = store.theme?.primary || '#1976D2';
|
|
290
|
-
const backgroundColor = store.theme?.background || '#ffffff';
|
|
291
|
-
|
|
292
|
-
// Use in styles
|
|
293
|
-
const buttonStyle = computed(() => ({
|
|
294
|
-
backgroundColor: store.theme?.primary,
|
|
295
|
-
color: store.theme?.onPrimary
|
|
296
|
-
}));
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
## Best Practices
|
|
300
|
-
|
|
301
|
-
1. **Use getters with defaults** - Always provide fallback values
|
|
302
|
-
2. **Keep state updates atomic** - Update one value at a time when possible
|
|
303
|
-
3. **Use computed for derived state** - Don't duplicate logic
|
|
304
|
-
4. **Clean up listeners** - Remove socket listeners when components unmount
|
|
305
|
-
5. **Avoid deep nesting** - Keep `triggerState` relatively flat for reactivity
|
package/docs/index.md
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
sidebar_position: 1
|
|
3
|
-
title: GxP Toolkit Overview
|
|
4
|
-
description: Introduction to the GxP Dev Toolkit for building platform plugins
|
|
5
|
-
slug: /gx-devtools
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# GxP Dev Toolkit
|
|
9
|
-
|
|
10
|
-
The GxP Dev Toolkit (`@gramercytech/gx-devtools`) is an npm package for creating platform plugins for the GxP kiosk platform.
|
|
11
|
-
|
|
12
|
-
## What You Can Build
|
|
13
|
-
|
|
14
|
-
With the GxP Toolkit, you can create custom plugins that run on GxP kiosks, including:
|
|
15
|
-
|
|
16
|
-
- **Interactive displays** - Check-in kiosks, registration flows, badge printing
|
|
17
|
-
- **Information screens** - Schedules, maps, directories
|
|
18
|
-
- **Engagement features** - Surveys, gamification, social walls
|
|
19
|
-
- **Custom integrations** - Connect to external APIs and services
|
|
20
|
-
|
|
21
|
-
## Key Features
|
|
22
|
-
|
|
23
|
-
| Feature | Description |
|
|
24
|
-
|---------|-------------|
|
|
25
|
-
| **CLI Tool** | `gxdev` command for scaffolding and development |
|
|
26
|
-
| **Interactive TUI** | Terminal UI for managing dev services |
|
|
27
|
-
| **Hot Reload** | Vite-based dev server with instant updates |
|
|
28
|
-
| **Socket.IO** | Real-time event simulation |
|
|
29
|
-
| **Browser Extensions** | Test plugins in production environments |
|
|
30
|
-
| **Vue 3 + Pinia** | Modern reactive framework with state management |
|
|
31
|
-
|
|
32
|
-
## Quick Links
|
|
33
|
-
|
|
34
|
-
- [Getting Started](./getting-started) - Install and create your first plugin
|
|
35
|
-
- [App Manifest](./app-manifest) - Configure your plugin settings, strings, and assets
|
|
36
|
-
- [GxP Store](./gxp-store) - State management and platform integration
|
|
37
|
-
- [Dev Tools](./dev-tools) - In-browser debugging and inspection
|
|
38
|
-
- [Building for Platform](./building-for-platform) - Prepare your plugin for production
|
|
39
|
-
|
|
40
|
-
## Requirements
|
|
41
|
-
|
|
42
|
-
- Node.js 18 or higher
|
|
43
|
-
- npm 8 or higher
|
|
44
|
-
- Modern browser (Chrome, Firefox, Safari, Edge)
|
package/tsconfig.tui.json
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"module": "ES2020",
|
|
5
|
-
"moduleResolution": "bundler",
|
|
6
|
-
"lib": ["ES2020"],
|
|
7
|
-
"jsx": "react-jsx",
|
|
8
|
-
"strict": true,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"skipLibCheck": true,
|
|
11
|
-
"forceConsistentCasingInFileNames": true,
|
|
12
|
-
"outDir": "./dist/tui",
|
|
13
|
-
"rootDir": "./bin/lib/tui",
|
|
14
|
-
"declaration": true,
|
|
15
|
-
"declarationMap": true,
|
|
16
|
-
"sourceMap": true,
|
|
17
|
-
"resolveJsonModule": true
|
|
18
|
-
},
|
|
19
|
-
"include": ["bin/lib/tui/**/*.ts", "bin/lib/tui/**/*.tsx"],
|
|
20
|
-
"exclude": ["node_modules", "dist"]
|
|
21
|
-
}
|
package/vite.config.js
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import { defineConfig, loadEnv } from "vite";
|
|
2
|
-
import vue from "@vitejs/plugin-vue";
|
|
3
|
-
import path from "path";
|
|
4
|
-
import fs from "fs";
|
|
5
|
-
import externalGlobals from "rollup-plugin-external-globals";
|
|
6
|
-
import { gxpInspectorPlugin } from "./runtime/vite-inspector-plugin.js";
|
|
7
|
-
|
|
8
|
-
// https://www.npmjs.com/package/rollup-plugin-external-globals
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Get the library name from package.json
|
|
12
|
-
*/
|
|
13
|
-
function getLibName() {
|
|
14
|
-
try {
|
|
15
|
-
const packageJsonPath = path.resolve(process.cwd(), "package.json");
|
|
16
|
-
if (fs.existsSync(packageJsonPath)) {
|
|
17
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
18
|
-
// Convert package name to a valid JS identifier
|
|
19
|
-
// e.g., "@company/my-plugin" -> "MyPlugin"
|
|
20
|
-
const name = packageJson.name || "Plugin";
|
|
21
|
-
return name
|
|
22
|
-
.replace(/[@\/\-]/g, " ")
|
|
23
|
-
.replace(/\b\w/g, (l) => l.toUpperCase())
|
|
24
|
-
.replace(/\s/g, "");
|
|
25
|
-
}
|
|
26
|
-
} catch (error) {
|
|
27
|
-
console.warn("Could not read package.json, using default lib name");
|
|
28
|
-
}
|
|
29
|
-
return "Plugin";
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Setup HTTPS configuration if certificates are available
|
|
34
|
-
*/
|
|
35
|
-
function getHttpsConfig(env) {
|
|
36
|
-
const useHttps = env.USE_HTTPS === "true";
|
|
37
|
-
const certPath = env.CERT_PATH;
|
|
38
|
-
const keyPath = env.KEY_PATH;
|
|
39
|
-
|
|
40
|
-
if (!useHttps || !certPath || !keyPath) {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Resolve paths relative to project root
|
|
45
|
-
const resolvedCertPath = path.resolve(process.cwd(), certPath);
|
|
46
|
-
const resolvedKeyPath = path.resolve(process.cwd(), keyPath);
|
|
47
|
-
|
|
48
|
-
// Check if certificate files exist
|
|
49
|
-
if (!fs.existsSync(resolvedCertPath) || !fs.existsSync(resolvedKeyPath)) {
|
|
50
|
-
console.warn("⚠ SSL certificate files not found, falling back to HTTP");
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
try {
|
|
55
|
-
return {
|
|
56
|
-
key: fs.readFileSync(resolvedKeyPath),
|
|
57
|
-
cert: fs.readFileSync(resolvedCertPath),
|
|
58
|
-
};
|
|
59
|
-
} catch (error) {
|
|
60
|
-
console.warn("⚠ Failed to read SSL certificates, falling back to HTTP");
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export default defineConfig(({ mode }) => {
|
|
66
|
-
// Load environment variables
|
|
67
|
-
const env = loadEnv(mode, process.cwd(), "");
|
|
68
|
-
|
|
69
|
-
// Get lib name from package.json
|
|
70
|
-
const libName = getLibName();
|
|
71
|
-
|
|
72
|
-
return {
|
|
73
|
-
plugins: [
|
|
74
|
-
vue(),
|
|
75
|
-
gxpInspectorPlugin(),
|
|
76
|
-
externalGlobals(
|
|
77
|
-
{
|
|
78
|
-
"@gramercytech/gx-devtools/config/stores/gxpPortalConfigStore":
|
|
79
|
-
"(window.useGxpStoreBuilder || (() => { console.warn('useGxpStoreBuilder not found on window, using fallback'); return {}; }))",
|
|
80
|
-
vue: "Vue",
|
|
81
|
-
"@/stores/gxpPortalConfigStore":
|
|
82
|
-
"(window.useGxpStoreBuilder || (() => { console.warn('useGxpStoreBuilder not found on window, using fallback'); return {}; }))",
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
include: ["template/**"],
|
|
86
|
-
}
|
|
87
|
-
),
|
|
88
|
-
// Custom request logging and CORS plugin
|
|
89
|
-
{
|
|
90
|
-
name: "request-logger-cors",
|
|
91
|
-
configureServer(server) {
|
|
92
|
-
server.middlewares.use((req, res, next) => {
|
|
93
|
-
const start = Date.now();
|
|
94
|
-
const originalEnd = res.end;
|
|
95
|
-
|
|
96
|
-
// Add CORS headers to all responses
|
|
97
|
-
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
98
|
-
res.setHeader(
|
|
99
|
-
"Access-Control-Allow-Methods",
|
|
100
|
-
"GET, POST, PUT, DELETE, OPTIONS"
|
|
101
|
-
);
|
|
102
|
-
res.setHeader("Access-Control-Allow-Headers", "*");
|
|
103
|
-
res.setHeader("Access-Control-Allow-Credentials", "false");
|
|
104
|
-
|
|
105
|
-
// Handle preflight requests
|
|
106
|
-
if (req.method === "OPTIONS") {
|
|
107
|
-
res.statusCode = 200;
|
|
108
|
-
res.end();
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
res.end = function (...args) {
|
|
113
|
-
const duration = Date.now() - start;
|
|
114
|
-
const status = res.statusCode;
|
|
115
|
-
const method = req.method;
|
|
116
|
-
const url = req.url;
|
|
117
|
-
const referer = req.headers.referer || "direct";
|
|
118
|
-
const origin = req.headers.origin || "unknown";
|
|
119
|
-
|
|
120
|
-
console.log(
|
|
121
|
-
`[${new Date().toISOString()}] ${method} ${url} ${status} (${duration}ms) - Origin: ${origin} - Referer: ${referer}`
|
|
122
|
-
);
|
|
123
|
-
originalEnd.apply(this, args);
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
next();
|
|
127
|
-
});
|
|
128
|
-
},
|
|
129
|
-
},
|
|
130
|
-
],
|
|
131
|
-
logLevel: env.NODE_LOG_LEVEL || "error",
|
|
132
|
-
clearScreen: false,
|
|
133
|
-
dev: {},
|
|
134
|
-
server: {
|
|
135
|
-
port: parseInt(env.NODE_PORT) || 3060,
|
|
136
|
-
strictPort: true,
|
|
137
|
-
https: getHttpsConfig(env),
|
|
138
|
-
cors: {
|
|
139
|
-
origin: "*",
|
|
140
|
-
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
141
|
-
allowedHeaders: ["*"],
|
|
142
|
-
credentials: false,
|
|
143
|
-
},
|
|
144
|
-
hmr: {
|
|
145
|
-
clientPort:
|
|
146
|
-
parseInt(env.CLIENT_PORT) || parseInt(env.NODE_PORT) || 3060,
|
|
147
|
-
},
|
|
148
|
-
host: true, // Allow access from network
|
|
149
|
-
},
|
|
150
|
-
build: {
|
|
151
|
-
lib: {
|
|
152
|
-
entry: [env.COMPONENT_PATH || "./src/Plugin.vue"],
|
|
153
|
-
name: libName,
|
|
154
|
-
fileName: (format) => `plugin.${format}.js`,
|
|
155
|
-
formats: ["es"],
|
|
156
|
-
},
|
|
157
|
-
},
|
|
158
|
-
resolve: {
|
|
159
|
-
alias: {
|
|
160
|
-
"@": path.resolve(process.cwd(), "template/src"),
|
|
161
|
-
},
|
|
162
|
-
},
|
|
163
|
-
};
|
|
164
|
-
});
|