@gxp-dev/tools 2.0.63 → 2.0.64

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 (182) hide show
  1. package/README.md +32 -31
  2. package/bin/gx-devtools.js +74 -54
  3. package/bin/lib/cli.js +23 -21
  4. package/bin/lib/commands/add-dependency.js +366 -325
  5. package/bin/lib/commands/assets.js +137 -139
  6. package/bin/lib/commands/build.js +169 -174
  7. package/bin/lib/commands/datastore.js +181 -183
  8. package/bin/lib/commands/dev.js +127 -131
  9. package/bin/lib/commands/extensions.js +147 -149
  10. package/bin/lib/commands/extract-config.js +73 -67
  11. package/bin/lib/commands/index.js +12 -12
  12. package/bin/lib/commands/init.js +342 -240
  13. package/bin/lib/commands/publish.js +69 -75
  14. package/bin/lib/commands/socket.js +69 -69
  15. package/bin/lib/commands/ssl.js +14 -14
  16. package/bin/lib/constants.js +10 -24
  17. package/bin/lib/tui/App.tsx +761 -705
  18. package/bin/lib/tui/components/AIPanel.tsx +191 -171
  19. package/bin/lib/tui/components/CommandInput.tsx +394 -343
  20. package/bin/lib/tui/components/GeminiPanel.tsx +175 -151
  21. package/bin/lib/tui/components/Header.tsx +23 -21
  22. package/bin/lib/tui/components/LogPanel.tsx +244 -220
  23. package/bin/lib/tui/components/TabBar.tsx +50 -48
  24. package/bin/lib/tui/components/WelcomeScreen.tsx +126 -71
  25. package/bin/lib/tui/index.tsx +37 -39
  26. package/bin/lib/tui/services/AIService.ts +518 -462
  27. package/bin/lib/tui/services/ExtensionService.ts +140 -129
  28. package/bin/lib/tui/services/GeminiService.ts +367 -337
  29. package/bin/lib/tui/services/ServiceManager.ts +344 -322
  30. package/bin/lib/tui/services/SocketService.ts +168 -168
  31. package/bin/lib/tui/services/ViteService.ts +88 -88
  32. package/bin/lib/tui/services/index.ts +47 -22
  33. package/bin/lib/utils/ai-scaffold.js +291 -280
  34. package/bin/lib/utils/extract-config.js +157 -140
  35. package/bin/lib/utils/files.js +82 -86
  36. package/bin/lib/utils/index.js +7 -7
  37. package/bin/lib/utils/paths.js +34 -34
  38. package/bin/lib/utils/prompts.js +194 -169
  39. package/bin/lib/utils/ssl.js +79 -81
  40. package/browser-extensions/README.md +0 -1
  41. package/browser-extensions/chrome/background.js +244 -237
  42. package/browser-extensions/chrome/content.js +32 -29
  43. package/browser-extensions/chrome/devtools.html +7 -7
  44. package/browser-extensions/chrome/devtools.js +19 -19
  45. package/browser-extensions/chrome/inspector.js +802 -767
  46. package/browser-extensions/chrome/manifest.json +71 -63
  47. package/browser-extensions/chrome/panel.html +674 -636
  48. package/browser-extensions/chrome/panel.js +722 -712
  49. package/browser-extensions/chrome/popup.html +586 -543
  50. package/browser-extensions/chrome/popup.js +282 -244
  51. package/browser-extensions/chrome/rules.json +1 -1
  52. package/browser-extensions/chrome/test-chrome.html +216 -136
  53. package/browser-extensions/chrome/test-mixed-content.html +284 -189
  54. package/browser-extensions/chrome/test-uri-pattern.html +221 -198
  55. package/browser-extensions/firefox/README.md +9 -6
  56. package/browser-extensions/firefox/background.js +221 -218
  57. package/browser-extensions/firefox/content.js +55 -52
  58. package/browser-extensions/firefox/debug-errors.html +386 -228
  59. package/browser-extensions/firefox/debug-https.html +153 -105
  60. package/browser-extensions/firefox/devtools.html +7 -7
  61. package/browser-extensions/firefox/devtools.js +23 -20
  62. package/browser-extensions/firefox/inspector.js +802 -767
  63. package/browser-extensions/firefox/manifest.json +68 -68
  64. package/browser-extensions/firefox/panel.html +674 -636
  65. package/browser-extensions/firefox/panel.js +722 -712
  66. package/browser-extensions/firefox/popup.html +572 -535
  67. package/browser-extensions/firefox/popup.js +281 -236
  68. package/browser-extensions/firefox/test-gramercy.html +170 -125
  69. package/browser-extensions/firefox/test-imports.html +59 -55
  70. package/browser-extensions/firefox/test-masking.html +231 -140
  71. package/browser-extensions/firefox/test-uri-pattern.html +221 -198
  72. package/dist/tui/App.d.ts +1 -1
  73. package/dist/tui/App.d.ts.map +1 -1
  74. package/dist/tui/App.js +154 -150
  75. package/dist/tui/App.js.map +1 -1
  76. package/dist/tui/components/AIPanel.d.ts.map +1 -1
  77. package/dist/tui/components/AIPanel.js +42 -35
  78. package/dist/tui/components/AIPanel.js.map +1 -1
  79. package/dist/tui/components/CommandInput.d.ts +1 -1
  80. package/dist/tui/components/CommandInput.d.ts.map +1 -1
  81. package/dist/tui/components/CommandInput.js +92 -62
  82. package/dist/tui/components/CommandInput.js.map +1 -1
  83. package/dist/tui/components/GeminiPanel.d.ts.map +1 -1
  84. package/dist/tui/components/GeminiPanel.js +37 -30
  85. package/dist/tui/components/GeminiPanel.js.map +1 -1
  86. package/dist/tui/components/Header.d.ts.map +1 -1
  87. package/dist/tui/components/Header.js +1 -1
  88. package/dist/tui/components/Header.js.map +1 -1
  89. package/dist/tui/components/LogPanel.d.ts +1 -1
  90. package/dist/tui/components/LogPanel.d.ts.map +1 -1
  91. package/dist/tui/components/LogPanel.js +26 -24
  92. package/dist/tui/components/LogPanel.js.map +1 -1
  93. package/dist/tui/components/TabBar.d.ts +2 -2
  94. package/dist/tui/components/TabBar.d.ts.map +1 -1
  95. package/dist/tui/components/TabBar.js +11 -11
  96. package/dist/tui/components/TabBar.js.map +1 -1
  97. package/dist/tui/components/WelcomeScreen.d.ts.map +1 -1
  98. package/dist/tui/components/WelcomeScreen.js +6 -6
  99. package/dist/tui/components/WelcomeScreen.js.map +1 -1
  100. package/dist/tui/index.d.ts.map +1 -1
  101. package/dist/tui/index.js +8 -8
  102. package/dist/tui/index.js.map +1 -1
  103. package/dist/tui/services/AIService.d.ts +2 -2
  104. package/dist/tui/services/AIService.d.ts.map +1 -1
  105. package/dist/tui/services/AIService.js +165 -125
  106. package/dist/tui/services/AIService.js.map +1 -1
  107. package/dist/tui/services/ExtensionService.d.ts +1 -1
  108. package/dist/tui/services/ExtensionService.d.ts.map +1 -1
  109. package/dist/tui/services/ExtensionService.js +33 -26
  110. package/dist/tui/services/ExtensionService.js.map +1 -1
  111. package/dist/tui/services/GeminiService.d.ts +1 -1
  112. package/dist/tui/services/GeminiService.d.ts.map +1 -1
  113. package/dist/tui/services/GeminiService.js +87 -76
  114. package/dist/tui/services/GeminiService.js.map +1 -1
  115. package/dist/tui/services/ServiceManager.d.ts +3 -3
  116. package/dist/tui/services/ServiceManager.d.ts.map +1 -1
  117. package/dist/tui/services/ServiceManager.js +72 -58
  118. package/dist/tui/services/ServiceManager.js.map +1 -1
  119. package/dist/tui/services/SocketService.d.ts.map +1 -1
  120. package/dist/tui/services/SocketService.js +32 -32
  121. package/dist/tui/services/SocketService.js.map +1 -1
  122. package/dist/tui/services/ViteService.d.ts.map +1 -1
  123. package/dist/tui/services/ViteService.js +26 -28
  124. package/dist/tui/services/ViteService.js.map +1 -1
  125. package/dist/tui/services/index.d.ts +6 -6
  126. package/dist/tui/services/index.d.ts.map +1 -1
  127. package/dist/tui/services/index.js +6 -6
  128. package/dist/tui/services/index.js.map +1 -1
  129. package/mcp/gxp-api-server.js +83 -81
  130. package/package.json +109 -93
  131. package/runtime/PortalContainer.vue +258 -234
  132. package/runtime/dev-tools/DevToolsModal.vue +153 -155
  133. package/runtime/dev-tools/LayoutSwitcher.vue +144 -140
  134. package/runtime/dev-tools/MockDataEditor.vue +456 -433
  135. package/runtime/dev-tools/SocketSimulator.vue +379 -371
  136. package/runtime/dev-tools/StoreInspector.vue +517 -455
  137. package/runtime/dev-tools/index.js +5 -5
  138. package/runtime/fallback-layouts/PrivateLayout.vue +2 -2
  139. package/runtime/fallback-layouts/PublicLayout.vue +2 -2
  140. package/runtime/fallback-layouts/SystemLayout.vue +2 -2
  141. package/runtime/gxpStringsPlugin.js +159 -134
  142. package/runtime/index.html +17 -19
  143. package/runtime/main.js +24 -22
  144. package/runtime/mock-api/auth-middleware.js +15 -15
  145. package/runtime/mock-api/image-generator.js +46 -46
  146. package/runtime/mock-api/index.js +55 -55
  147. package/runtime/mock-api/response-generator.js +116 -105
  148. package/runtime/mock-api/route-generator.js +107 -84
  149. package/runtime/mock-api/socket-triggers.js +94 -93
  150. package/runtime/mock-api/spec-loader.js +79 -80
  151. package/runtime/package.json +3 -0
  152. package/runtime/server.js +68 -68
  153. package/runtime/stores/gxpPortalConfigStore.js +204 -186
  154. package/runtime/stores/index.js +2 -2
  155. package/runtime/vite-inspector-plugin.js +858 -707
  156. package/runtime/vite-source-tracker-plugin.js +132 -113
  157. package/runtime/vite.config.js +191 -139
  158. package/scripts/launch-chrome.js +41 -41
  159. package/scripts/pack-chrome.js +38 -39
  160. package/socket-events/AiSessionMessageCreated.json +17 -17
  161. package/socket-events/SocialStreamPostCreated.json +23 -23
  162. package/socket-events/SocialStreamPostVariantCompleted.json +22 -22
  163. package/template/.claude/agents/gxp-developer.md +100 -99
  164. package/template/.claude/settings.json +7 -7
  165. package/template/AGENTS.md +30 -23
  166. package/template/GEMINI.md +20 -20
  167. package/template/README.md +70 -53
  168. package/template/app-manifest.json +2 -4
  169. package/template/configuration.json +10 -10
  170. package/template/default-styling.css +1 -1
  171. package/template/index.html +18 -20
  172. package/template/main.js +24 -22
  173. package/template/src/DemoPage.vue +415 -362
  174. package/template/src/Plugin.vue +76 -85
  175. package/template/src/stores/index.js +3 -3
  176. package/template/src/stores/test-data.json +164 -172
  177. package/template/theme-layouts/AdditionalStyling.css +50 -50
  178. package/template/theme-layouts/PrivateLayout.vue +8 -12
  179. package/template/theme-layouts/PublicLayout.vue +8 -12
  180. package/template/theme-layouts/SystemLayout.vue +8 -12
  181. package/template/vite.extend.js +45 -0
  182. package/template/vite.config.js +0 -409
@@ -1,621 +1,644 @@
1
1
  <template>
2
- <div class="mock-data-editor">
3
- <div class="editor-description">
4
- <p>
5
- Edit mock data that simulates platform responses during development.
6
- Changes are applied in memory and will reset on page reload.
7
- </p>
8
- </div>
9
-
10
- <div class="data-sections">
11
- <div class="data-section">
12
- <div class="section-header" @click="toggleSection('theme')">
13
- <span class="toggle-icon">{{ expandedSections.theme ? '▼' : '▶' }}</span>
14
- <h4>Theme Settings</h4>
15
- </div>
16
- <div v-if="expandedSections.theme" class="section-content">
17
- <div class="color-grid">
18
- <div v-for="(value, key) in themeColors" :key="key" class="color-field">
19
- <label>{{ formatLabel(key) }}</label>
20
- <div class="color-input-wrapper">
21
- <input
22
- type="color"
23
- :value="extractColor(value)"
24
- @input="updateThemeColor(key, $event.target.value)"
25
- class="color-picker"
26
- />
27
- <input
28
- type="text"
29
- :value="value"
30
- @input="updateThemeColor(key, $event.target.value)"
31
- class="color-text"
32
- />
33
- </div>
34
- </div>
35
- </div>
36
- </div>
37
- </div>
38
-
39
- <div class="data-section">
40
- <div class="section-header" @click="toggleSection('navigation')">
41
- <span class="toggle-icon">{{ expandedSections.navigation ? '▼' : '▶' }}</span>
42
- <h4>Navigation Items</h4>
43
- </div>
44
- <div v-if="expandedSections.navigation" class="section-content">
45
- <div class="nav-items">
46
- <div
47
- v-for="(item, index) in navigationItems"
48
- :key="index"
49
- class="nav-item"
50
- >
51
- <input
52
- v-model="item.title"
53
- class="nav-input"
54
- placeholder="Title"
55
- />
56
- <input
57
- v-model="item.route"
58
- class="nav-input"
59
- placeholder="Route"
60
- />
61
- <button class="btn-icon" @click="removeNavItem(index)" title="Remove">
62
- &times;
63
- </button>
64
- </div>
65
- <button class="btn-add" @click="addNavItem">
66
- + Add Navigation Item
67
- </button>
68
- </div>
69
- </div>
70
- </div>
71
-
72
- <div class="data-section">
73
- <div class="section-header" @click="toggleSection('user')">
74
- <span class="toggle-icon">{{ expandedSections.user ? '▼' : '▶' }}</span>
75
- <h4>User Session</h4>
76
- </div>
77
- <div v-if="expandedSections.user" class="section-content">
78
- <div class="user-fields">
79
- <div class="field-row">
80
- <label>Authenticated:</label>
81
- <label class="toggle-switch">
82
- <input type="checkbox" v-model="userSession.authenticated" />
83
- <span class="toggle-slider"></span>
84
- </label>
85
- </div>
86
- <div class="field-row">
87
- <label>User ID:</label>
88
- <input
89
- type="text"
90
- v-model="userSession.userId"
91
- class="field-input"
92
- />
93
- </div>
94
- <div class="field-row">
95
- <label>Username:</label>
96
- <input
97
- type="text"
98
- v-model="userSession.username"
99
- class="field-input"
100
- />
101
- </div>
102
- <div class="field-row">
103
- <label>Email:</label>
104
- <input
105
- type="email"
106
- v-model="userSession.email"
107
- class="field-input"
108
- />
109
- </div>
110
- </div>
111
- </div>
112
- </div>
113
-
114
- <div class="data-section">
115
- <div class="section-header" @click="toggleSection('permissions')">
116
- <span class="toggle-icon">{{ expandedSections.permissions ? '▼' : '▶' }}</span>
117
- <h4>Permission Flags</h4>
118
- </div>
119
- <div v-if="expandedSections.permissions" class="section-content">
120
- <div class="permissions-list">
121
- <label
122
- v-for="flag in availablePermissions"
123
- :key="flag"
124
- class="permission-item"
125
- >
126
- <input
127
- type="checkbox"
128
- :checked="activePermissions.includes(flag)"
129
- @change="togglePermission(flag)"
130
- />
131
- <span>{{ flag }}</span>
132
- </label>
133
- <div class="add-permission">
134
- <input
135
- v-model="newPermission"
136
- placeholder="Add custom permission..."
137
- class="field-input"
138
- @keydown.enter="addPermission"
139
- />
140
- <button class="btn-add-sm" @click="addPermission">Add</button>
141
- </div>
142
- </div>
143
- </div>
144
- </div>
145
- </div>
146
-
147
- <div class="editor-actions">
148
- <button class="btn btn-secondary" @click="resetAllData">
149
- Reset All to Defaults
150
- </button>
151
- <button class="btn btn-primary" @click="exportData">
152
- Export as JSON
153
- </button>
154
- </div>
155
- </div>
2
+ <div class="mock-data-editor">
3
+ <div class="editor-description">
4
+ <p>
5
+ Edit mock data that simulates platform responses during development.
6
+ Changes are applied in memory and will reset on page reload.
7
+ </p>
8
+ </div>
9
+
10
+ <div class="data-sections">
11
+ <div class="data-section">
12
+ <div class="section-header" @click="toggleSection('theme')">
13
+ <span class="toggle-icon">{{
14
+ expandedSections.theme ? "▼" : "▶"
15
+ }}</span>
16
+ <h4>Theme Settings</h4>
17
+ </div>
18
+ <div v-if="expandedSections.theme" class="section-content">
19
+ <div class="color-grid">
20
+ <div
21
+ v-for="(value, key) in themeColors"
22
+ :key="key"
23
+ class="color-field"
24
+ >
25
+ <label>{{ formatLabel(key) }}</label>
26
+ <div class="color-input-wrapper">
27
+ <input
28
+ type="color"
29
+ :value="extractColor(value)"
30
+ @input="updateThemeColor(key, $event.target.value)"
31
+ class="color-picker"
32
+ />
33
+ <input
34
+ type="text"
35
+ :value="value"
36
+ @input="updateThemeColor(key, $event.target.value)"
37
+ class="color-text"
38
+ />
39
+ </div>
40
+ </div>
41
+ </div>
42
+ </div>
43
+ </div>
44
+
45
+ <div class="data-section">
46
+ <div class="section-header" @click="toggleSection('navigation')">
47
+ <span class="toggle-icon">{{
48
+ expandedSections.navigation ? "▼" : ""
49
+ }}</span>
50
+ <h4>Navigation Items</h4>
51
+ </div>
52
+ <div v-if="expandedSections.navigation" class="section-content">
53
+ <div class="nav-items">
54
+ <div
55
+ v-for="(item, index) in navigationItems"
56
+ :key="index"
57
+ class="nav-item"
58
+ >
59
+ <input
60
+ v-model="item.title"
61
+ class="nav-input"
62
+ placeholder="Title"
63
+ />
64
+ <input
65
+ v-model="item.route"
66
+ class="nav-input"
67
+ placeholder="Route"
68
+ />
69
+ <button
70
+ class="btn-icon"
71
+ @click="removeNavItem(index)"
72
+ title="Remove"
73
+ >
74
+ &times;
75
+ </button>
76
+ </div>
77
+ <button class="btn-add" @click="addNavItem">
78
+ + Add Navigation Item
79
+ </button>
80
+ </div>
81
+ </div>
82
+ </div>
83
+
84
+ <div class="data-section">
85
+ <div class="section-header" @click="toggleSection('user')">
86
+ <span class="toggle-icon">{{
87
+ expandedSections.user ? "▼" : "▶"
88
+ }}</span>
89
+ <h4>User Session</h4>
90
+ </div>
91
+ <div v-if="expandedSections.user" class="section-content">
92
+ <div class="user-fields">
93
+ <div class="field-row">
94
+ <label>Authenticated:</label>
95
+ <label class="toggle-switch">
96
+ <input type="checkbox" v-model="userSession.authenticated" />
97
+ <span class="toggle-slider"></span>
98
+ </label>
99
+ </div>
100
+ <div class="field-row">
101
+ <label>User ID:</label>
102
+ <input
103
+ type="text"
104
+ v-model="userSession.userId"
105
+ class="field-input"
106
+ />
107
+ </div>
108
+ <div class="field-row">
109
+ <label>Username:</label>
110
+ <input
111
+ type="text"
112
+ v-model="userSession.username"
113
+ class="field-input"
114
+ />
115
+ </div>
116
+ <div class="field-row">
117
+ <label>Email:</label>
118
+ <input
119
+ type="email"
120
+ v-model="userSession.email"
121
+ class="field-input"
122
+ />
123
+ </div>
124
+ </div>
125
+ </div>
126
+ </div>
127
+
128
+ <div class="data-section">
129
+ <div class="section-header" @click="toggleSection('permissions')">
130
+ <span class="toggle-icon">{{
131
+ expandedSections.permissions ? "▼" : "▶"
132
+ }}</span>
133
+ <h4>Permission Flags</h4>
134
+ </div>
135
+ <div v-if="expandedSections.permissions" class="section-content">
136
+ <div class="permissions-list">
137
+ <label
138
+ v-for="flag in availablePermissions"
139
+ :key="flag"
140
+ class="permission-item"
141
+ >
142
+ <input
143
+ type="checkbox"
144
+ :checked="activePermissions.includes(flag)"
145
+ @change="togglePermission(flag)"
146
+ />
147
+ <span>{{ flag }}</span>
148
+ </label>
149
+ <div class="add-permission">
150
+ <input
151
+ v-model="newPermission"
152
+ placeholder="Add custom permission..."
153
+ class="field-input"
154
+ @keydown.enter="addPermission"
155
+ />
156
+ <button class="btn-add-sm" @click="addPermission">Add</button>
157
+ </div>
158
+ </div>
159
+ </div>
160
+ </div>
161
+ </div>
162
+
163
+ <div class="editor-actions">
164
+ <button class="btn btn-secondary" @click="resetAllData">
165
+ Reset All to Defaults
166
+ </button>
167
+ <button class="btn btn-primary" @click="exportData">
168
+ Export as JSON
169
+ </button>
170
+ </div>
171
+ </div>
156
172
  </template>
157
173
 
158
174
  <script setup>
159
- import { ref, reactive, computed } from 'vue';
175
+ import { ref, reactive, computed } from "vue"
160
176
 
161
177
  const props = defineProps({
162
- store: {
163
- type: Object,
164
- required: true
165
- }
166
- });
178
+ store: {
179
+ type: Object,
180
+ required: true,
181
+ },
182
+ })
167
183
 
168
184
  const expandedSections = reactive({
169
- theme: true,
170
- navigation: false,
171
- user: false,
172
- permissions: false
173
- });
185
+ theme: true,
186
+ navigation: false,
187
+ user: false,
188
+ permissions: false,
189
+ })
174
190
 
175
191
  const themeColors = reactive({
176
- background_color: '#ffffff',
177
- text_color: '#333333',
178
- primary_color: '#FFD600',
179
- start_background_color: '#667eea',
180
- start_text_color: '#ffffff',
181
- final_background_color: '#4CAF50',
182
- final_text_color: '#ffffff'
183
- });
192
+ background_color: "#ffffff",
193
+ text_color: "#333333",
194
+ primary_color: "#FFD600",
195
+ start_background_color: "#667eea",
196
+ start_text_color: "#ffffff",
197
+ final_background_color: "#4CAF50",
198
+ final_text_color: "#ffffff",
199
+ })
184
200
 
185
201
  const navigationItems = reactive([
186
- { title: 'Start', route: '/start' },
187
- { title: 'Plugin', route: '/plugin' },
188
- { title: 'Final', route: '/final' },
189
- { title: 'Logout', route: '/logout', system_type: 'logout' }
190
- ]);
202
+ { title: "Start", route: "/start" },
203
+ { title: "Plugin", route: "/plugin" },
204
+ { title: "Final", route: "/final" },
205
+ { title: "Logout", route: "/logout", system_type: "logout" },
206
+ ])
191
207
 
192
208
  const userSession = reactive({
193
- authenticated: false,
194
- userId: '',
195
- username: '',
196
- email: ''
197
- });
209
+ authenticated: false,
210
+ userId: "",
211
+ username: "",
212
+ email: "",
213
+ })
198
214
 
199
215
  const availablePermissions = ref([
200
- 'admin',
201
- 'editor',
202
- 'viewer',
203
- 'can_upload',
204
- 'can_delete',
205
- 'can_share'
206
- ]);
216
+ "admin",
217
+ "editor",
218
+ "viewer",
219
+ "can_upload",
220
+ "can_delete",
221
+ "can_share",
222
+ ])
207
223
 
208
- const activePermissions = ref([]);
209
- const newPermission = ref('');
224
+ const activePermissions = ref([])
225
+ const newPermission = ref("")
210
226
 
211
227
  function toggleSection(section) {
212
- expandedSections[section] = !expandedSections[section];
228
+ expandedSections[section] = !expandedSections[section]
213
229
  }
214
230
 
215
231
  function formatLabel(key) {
216
- return key
217
- .replace(/_/g, ' ')
218
- .replace(/\b\w/g, l => l.toUpperCase());
232
+ return key.replace(/_/g, " ").replace(/\b\w/g, (l) => l.toUpperCase())
219
233
  }
220
234
 
221
235
  function extractColor(value) {
222
- // Extract hex color from value (handle gradients, etc.)
223
- if (typeof value !== 'string') return '#ffffff';
224
- const match = value.match(/#[0-9A-Fa-f]{6}/);
225
- return match ? match[0] : '#ffffff';
236
+ // Extract hex color from value (handle gradients, etc.)
237
+ if (typeof value !== "string") return "#ffffff"
238
+ const match = value.match(/#[0-9A-Fa-f]{6}/)
239
+ return match ? match[0] : "#ffffff"
226
240
  }
227
241
 
228
242
  function updateThemeColor(key, value) {
229
- themeColors[key] = value;
230
- // Update store if available
231
- if (props.store?.theme) {
232
- props.store.theme[key] = value;
233
- }
234
- console.log(`[DevTools] Theme ${key} updated:`, value);
243
+ themeColors[key] = value
244
+ // Update store if available
245
+ if (props.store?.theme) {
246
+ props.store.theme[key] = value
247
+ }
248
+ console.log(`[DevTools] Theme ${key} updated:`, value)
235
249
  }
236
250
 
237
251
  function addNavItem() {
238
- navigationItems.push({ title: '', route: '' });
252
+ navigationItems.push({ title: "", route: "" })
239
253
  }
240
254
 
241
255
  function removeNavItem(index) {
242
- navigationItems.splice(index, 1);
256
+ navigationItems.splice(index, 1)
243
257
  }
244
258
 
245
259
  function togglePermission(flag) {
246
- const index = activePermissions.value.indexOf(flag);
247
- if (index > -1) {
248
- activePermissions.value.splice(index, 1);
249
- } else {
250
- activePermissions.value.push(flag);
251
- }
252
- // Update store
253
- if (props.store?.permissionFlags) {
254
- props.store.permissionFlags.splice(0, props.store.permissionFlags.length, ...activePermissions.value);
255
- }
256
- console.log('[DevTools] Permissions updated:', activePermissions.value);
260
+ const index = activePermissions.value.indexOf(flag)
261
+ if (index > -1) {
262
+ activePermissions.value.splice(index, 1)
263
+ } else {
264
+ activePermissions.value.push(flag)
265
+ }
266
+ // Update store
267
+ if (props.store?.permissionFlags) {
268
+ props.store.permissionFlags.splice(
269
+ 0,
270
+ props.store.permissionFlags.length,
271
+ ...activePermissions.value,
272
+ )
273
+ }
274
+ console.log("[DevTools] Permissions updated:", activePermissions.value)
257
275
  }
258
276
 
259
277
  function addPermission() {
260
- if (newPermission.value && !availablePermissions.value.includes(newPermission.value)) {
261
- availablePermissions.value.push(newPermission.value);
262
- activePermissions.value.push(newPermission.value);
263
- newPermission.value = '';
264
- }
278
+ if (
279
+ newPermission.value &&
280
+ !availablePermissions.value.includes(newPermission.value)
281
+ ) {
282
+ availablePermissions.value.push(newPermission.value)
283
+ activePermissions.value.push(newPermission.value)
284
+ newPermission.value = ""
285
+ }
265
286
  }
266
287
 
267
288
  function resetAllData() {
268
- // Reset theme
269
- Object.assign(themeColors, {
270
- background_color: '#ffffff',
271
- text_color: '#333333',
272
- primary_color: '#FFD600',
273
- start_background_color: '#667eea',
274
- start_text_color: '#ffffff',
275
- final_background_color: '#4CAF50',
276
- final_text_color: '#ffffff'
277
- });
278
-
279
- // Reset navigation
280
- navigationItems.splice(0, navigationItems.length,
281
- { title: 'Start', route: '/start' },
282
- { title: 'Plugin', route: '/plugin' },
283
- { title: 'Final', route: '/final' },
284
- { title: 'Logout', route: '/logout', system_type: 'logout' }
285
- );
286
-
287
- // Reset user
288
- Object.assign(userSession, {
289
- authenticated: false,
290
- userId: '',
291
- username: '',
292
- email: ''
293
- });
294
-
295
- // Reset permissions
296
- activePermissions.value = [];
297
-
298
- console.log('[DevTools] All mock data reset to defaults');
289
+ // Reset theme
290
+ Object.assign(themeColors, {
291
+ background_color: "#ffffff",
292
+ text_color: "#333333",
293
+ primary_color: "#FFD600",
294
+ start_background_color: "#667eea",
295
+ start_text_color: "#ffffff",
296
+ final_background_color: "#4CAF50",
297
+ final_text_color: "#ffffff",
298
+ })
299
+
300
+ // Reset navigation
301
+ navigationItems.splice(
302
+ 0,
303
+ navigationItems.length,
304
+ { title: "Start", route: "/start" },
305
+ { title: "Plugin", route: "/plugin" },
306
+ { title: "Final", route: "/final" },
307
+ { title: "Logout", route: "/logout", system_type: "logout" },
308
+ )
309
+
310
+ // Reset user
311
+ Object.assign(userSession, {
312
+ authenticated: false,
313
+ userId: "",
314
+ username: "",
315
+ email: "",
316
+ })
317
+
318
+ // Reset permissions
319
+ activePermissions.value = []
320
+
321
+ console.log("[DevTools] All mock data reset to defaults")
299
322
  }
300
323
 
301
324
  async function exportData() {
302
- const data = {
303
- theme: { ...themeColors },
304
- navigation: [...navigationItems],
305
- userSession: { ...userSession },
306
- permissions: [...activePermissions.value]
307
- };
308
-
309
- try {
310
- await navigator.clipboard.writeText(JSON.stringify(data, null, 2));
311
- console.log('[DevTools] Mock data exported to clipboard');
312
- } catch (err) {
313
- console.error('[DevTools] Failed to export:', err);
314
- }
325
+ const data = {
326
+ theme: { ...themeColors },
327
+ navigation: [...navigationItems],
328
+ userSession: { ...userSession },
329
+ permissions: [...activePermissions.value],
330
+ }
331
+
332
+ try {
333
+ await navigator.clipboard.writeText(JSON.stringify(data, null, 2))
334
+ console.log("[DevTools] Mock data exported to clipboard")
335
+ } catch (err) {
336
+ console.error("[DevTools] Failed to export:", err)
337
+ }
315
338
  }
316
339
  </script>
317
340
 
318
341
  <style scoped>
319
342
  .mock-data-editor {
320
- display: flex;
321
- flex-direction: column;
322
- gap: 16px;
343
+ display: flex;
344
+ flex-direction: column;
345
+ gap: 16px;
323
346
  }
324
347
 
325
348
  .editor-description {
326
- background: #2d2d2d;
327
- padding: 12px 16px;
328
- border-radius: 8px;
349
+ background: #2d2d2d;
350
+ padding: 12px 16px;
351
+ border-radius: 8px;
329
352
  }
330
353
 
331
354
  .editor-description p {
332
- margin: 0;
333
- font-size: 13px;
334
- color: #888;
355
+ margin: 0;
356
+ font-size: 13px;
357
+ color: #888;
335
358
  }
336
359
 
337
360
  .data-sections {
338
- display: flex;
339
- flex-direction: column;
340
- gap: 8px;
361
+ display: flex;
362
+ flex-direction: column;
363
+ gap: 8px;
341
364
  }
342
365
 
343
366
  .data-section {
344
- background: #2d2d2d;
345
- border-radius: 8px;
346
- overflow: hidden;
367
+ background: #2d2d2d;
368
+ border-radius: 8px;
369
+ overflow: hidden;
347
370
  }
348
371
 
349
372
  .section-header {
350
- display: flex;
351
- align-items: center;
352
- gap: 8px;
353
- padding: 12px 16px;
354
- cursor: pointer;
355
- transition: background 0.2s;
373
+ display: flex;
374
+ align-items: center;
375
+ gap: 8px;
376
+ padding: 12px 16px;
377
+ cursor: pointer;
378
+ transition: background 0.2s;
356
379
  }
357
380
 
358
381
  .section-header:hover {
359
- background: #3d3d3d;
382
+ background: #3d3d3d;
360
383
  }
361
384
 
362
385
  .section-header h4 {
363
- margin: 0;
364
- font-size: 13px;
365
- font-weight: 500;
386
+ margin: 0;
387
+ font-size: 13px;
388
+ font-weight: 500;
366
389
  }
367
390
 
368
391
  .toggle-icon {
369
- font-size: 10px;
370
- color: #888;
371
- width: 12px;
392
+ font-size: 10px;
393
+ color: #888;
394
+ width: 12px;
372
395
  }
373
396
 
374
397
  .section-content {
375
- padding: 12px 16px;
376
- border-top: 1px solid #3d3d3d;
398
+ padding: 12px 16px;
399
+ border-top: 1px solid #3d3d3d;
377
400
  }
378
401
 
379
402
  /* Theme Colors */
380
403
  .color-grid {
381
- display: grid;
382
- grid-template-columns: repeat(2, 1fr);
383
- gap: 12px;
404
+ display: grid;
405
+ grid-template-columns: repeat(2, 1fr);
406
+ gap: 12px;
384
407
  }
385
408
 
386
409
  .color-field label {
387
- display: block;
388
- font-size: 11px;
389
- color: #888;
390
- margin-bottom: 4px;
410
+ display: block;
411
+ font-size: 11px;
412
+ color: #888;
413
+ margin-bottom: 4px;
391
414
  }
392
415
 
393
416
  .color-input-wrapper {
394
- display: flex;
395
- gap: 8px;
417
+ display: flex;
418
+ gap: 8px;
396
419
  }
397
420
 
398
421
  .color-picker {
399
- width: 40px;
400
- height: 32px;
401
- border: none;
402
- border-radius: 4px;
403
- cursor: pointer;
404
- background: transparent;
422
+ width: 40px;
423
+ height: 32px;
424
+ border: none;
425
+ border-radius: 4px;
426
+ cursor: pointer;
427
+ background: transparent;
405
428
  }
406
429
 
407
430
  .color-text {
408
- flex: 1;
409
- background: #1e1e1e;
410
- border: 1px solid #3d3d3d;
411
- color: #e0e0e0;
412
- padding: 6px 8px;
413
- border-radius: 4px;
414
- font-size: 12px;
415
- font-family: 'SF Mono', Monaco, monospace;
431
+ flex: 1;
432
+ background: #1e1e1e;
433
+ border: 1px solid #3d3d3d;
434
+ color: #e0e0e0;
435
+ padding: 6px 8px;
436
+ border-radius: 4px;
437
+ font-size: 12px;
438
+ font-family: "SF Mono", Monaco, monospace;
416
439
  }
417
440
 
418
441
  /* Navigation */
419
442
  .nav-items {
420
- display: flex;
421
- flex-direction: column;
422
- gap: 8px;
443
+ display: flex;
444
+ flex-direction: column;
445
+ gap: 8px;
423
446
  }
424
447
 
425
448
  .nav-item {
426
- display: flex;
427
- gap: 8px;
428
- align-items: center;
449
+ display: flex;
450
+ gap: 8px;
451
+ align-items: center;
429
452
  }
430
453
 
431
454
  .nav-input {
432
- flex: 1;
433
- background: #1e1e1e;
434
- border: 1px solid #3d3d3d;
435
- color: #e0e0e0;
436
- padding: 8px 12px;
437
- border-radius: 4px;
438
- font-size: 12px;
455
+ flex: 1;
456
+ background: #1e1e1e;
457
+ border: 1px solid #3d3d3d;
458
+ color: #e0e0e0;
459
+ padding: 8px 12px;
460
+ border-radius: 4px;
461
+ font-size: 12px;
439
462
  }
440
463
 
441
464
  .btn-icon {
442
- background: transparent;
443
- border: none;
444
- color: #888;
445
- font-size: 18px;
446
- cursor: pointer;
447
- padding: 4px 8px;
465
+ background: transparent;
466
+ border: none;
467
+ color: #888;
468
+ font-size: 18px;
469
+ cursor: pointer;
470
+ padding: 4px 8px;
448
471
  }
449
472
 
450
473
  .btn-icon:hover {
451
- color: #ff6b6b;
474
+ color: #ff6b6b;
452
475
  }
453
476
 
454
477
  .btn-add {
455
- background: #3d3d3d;
456
- border: 1px dashed #555;
457
- color: #888;
458
- padding: 8px;
459
- border-radius: 4px;
460
- cursor: pointer;
461
- font-size: 12px;
462
- text-align: center;
463
- transition: all 0.2s;
478
+ background: #3d3d3d;
479
+ border: 1px dashed #555;
480
+ color: #888;
481
+ padding: 8px;
482
+ border-radius: 4px;
483
+ cursor: pointer;
484
+ font-size: 12px;
485
+ text-align: center;
486
+ transition: all 0.2s;
464
487
  }
465
488
 
466
489
  .btn-add:hover {
467
- background: #4d4d4d;
468
- color: #e0e0e0;
490
+ background: #4d4d4d;
491
+ color: #e0e0e0;
469
492
  }
470
493
 
471
494
  /* User Session */
472
495
  .user-fields {
473
- display: flex;
474
- flex-direction: column;
475
- gap: 12px;
496
+ display: flex;
497
+ flex-direction: column;
498
+ gap: 12px;
476
499
  }
477
500
 
478
501
  .field-row {
479
- display: flex;
480
- align-items: center;
481
- gap: 12px;
502
+ display: flex;
503
+ align-items: center;
504
+ gap: 12px;
482
505
  }
483
506
 
484
507
  .field-row > label:first-child {
485
- min-width: 100px;
486
- font-size: 12px;
487
- color: #888;
508
+ min-width: 100px;
509
+ font-size: 12px;
510
+ color: #888;
488
511
  }
489
512
 
490
513
  .field-input {
491
- flex: 1;
492
- background: #1e1e1e;
493
- border: 1px solid #3d3d3d;
494
- color: #e0e0e0;
495
- padding: 8px 12px;
496
- border-radius: 4px;
497
- font-size: 12px;
514
+ flex: 1;
515
+ background: #1e1e1e;
516
+ border: 1px solid #3d3d3d;
517
+ color: #e0e0e0;
518
+ padding: 8px 12px;
519
+ border-radius: 4px;
520
+ font-size: 12px;
498
521
  }
499
522
 
500
523
  /* Toggle Switch */
501
524
  .toggle-switch {
502
- position: relative;
503
- display: inline-block;
504
- width: 44px;
505
- height: 24px;
525
+ position: relative;
526
+ display: inline-block;
527
+ width: 44px;
528
+ height: 24px;
506
529
  }
507
530
 
508
531
  .toggle-switch input {
509
- opacity: 0;
510
- width: 0;
511
- height: 0;
532
+ opacity: 0;
533
+ width: 0;
534
+ height: 0;
512
535
  }
513
536
 
514
537
  .toggle-slider {
515
- position: absolute;
516
- cursor: pointer;
517
- top: 0;
518
- left: 0;
519
- right: 0;
520
- bottom: 0;
521
- background-color: #3d3d3d;
522
- transition: 0.3s;
523
- border-radius: 24px;
538
+ position: absolute;
539
+ cursor: pointer;
540
+ top: 0;
541
+ left: 0;
542
+ right: 0;
543
+ bottom: 0;
544
+ background-color: #3d3d3d;
545
+ transition: 0.3s;
546
+ border-radius: 24px;
524
547
  }
525
548
 
526
549
  .toggle-slider:before {
527
- position: absolute;
528
- content: "";
529
- height: 18px;
530
- width: 18px;
531
- left: 3px;
532
- bottom: 3px;
533
- background-color: #888;
534
- transition: 0.3s;
535
- border-radius: 50%;
550
+ position: absolute;
551
+ content: "";
552
+ height: 18px;
553
+ width: 18px;
554
+ left: 3px;
555
+ bottom: 3px;
556
+ background-color: #888;
557
+ transition: 0.3s;
558
+ border-radius: 50%;
536
559
  }
537
560
 
538
561
  input:checked + .toggle-slider {
539
- background-color: #61dafb;
562
+ background-color: #61dafb;
540
563
  }
541
564
 
542
565
  input:checked + .toggle-slider:before {
543
- transform: translateX(20px);
544
- background-color: #1e1e1e;
566
+ transform: translateX(20px);
567
+ background-color: #1e1e1e;
545
568
  }
546
569
 
547
570
  /* Permissions */
548
571
  .permissions-list {
549
- display: flex;
550
- flex-direction: column;
551
- gap: 8px;
572
+ display: flex;
573
+ flex-direction: column;
574
+ gap: 8px;
552
575
  }
553
576
 
554
577
  .permission-item {
555
- display: flex;
556
- align-items: center;
557
- gap: 8px;
558
- font-size: 12px;
559
- cursor: pointer;
578
+ display: flex;
579
+ align-items: center;
580
+ gap: 8px;
581
+ font-size: 12px;
582
+ cursor: pointer;
560
583
  }
561
584
 
562
585
  .permission-item input[type="checkbox"] {
563
- accent-color: #61dafb;
586
+ accent-color: #61dafb;
564
587
  }
565
588
 
566
589
  .add-permission {
567
- display: flex;
568
- gap: 8px;
569
- margin-top: 8px;
590
+ display: flex;
591
+ gap: 8px;
592
+ margin-top: 8px;
570
593
  }
571
594
 
572
595
  .btn-add-sm {
573
- background: #3d3d3d;
574
- border: none;
575
- color: #e0e0e0;
576
- padding: 8px 12px;
577
- border-radius: 4px;
578
- cursor: pointer;
579
- font-size: 12px;
596
+ background: #3d3d3d;
597
+ border: none;
598
+ color: #e0e0e0;
599
+ padding: 8px 12px;
600
+ border-radius: 4px;
601
+ cursor: pointer;
602
+ font-size: 12px;
580
603
  }
581
604
 
582
605
  .btn-add-sm:hover {
583
- background: #4d4d4d;
606
+ background: #4d4d4d;
584
607
  }
585
608
 
586
609
  /* Actions */
587
610
  .editor-actions {
588
- display: flex;
589
- gap: 8px;
590
- justify-content: flex-end;
591
- padding-top: 16px;
592
- border-top: 1px solid #3d3d3d;
611
+ display: flex;
612
+ gap: 8px;
613
+ justify-content: flex-end;
614
+ padding-top: 16px;
615
+ border-top: 1px solid #3d3d3d;
593
616
  }
594
617
 
595
618
  .btn {
596
- padding: 8px 16px;
597
- border: none;
598
- border-radius: 4px;
599
- cursor: pointer;
600
- font-size: 12px;
601
- transition: all 0.2s;
619
+ padding: 8px 16px;
620
+ border: none;
621
+ border-radius: 4px;
622
+ cursor: pointer;
623
+ font-size: 12px;
624
+ transition: all 0.2s;
602
625
  }
603
626
 
604
627
  .btn-primary {
605
- background: #61dafb;
606
- color: #1e1e1e;
628
+ background: #61dafb;
629
+ color: #1e1e1e;
607
630
  }
608
631
 
609
632
  .btn-primary:hover {
610
- background: #4fc3f7;
633
+ background: #4fc3f7;
611
634
  }
612
635
 
613
636
  .btn-secondary {
614
- background: #3d3d3d;
615
- color: #e0e0e0;
637
+ background: #3d3d3d;
638
+ color: #e0e0e0;
616
639
  }
617
640
 
618
641
  .btn-secondary:hover {
619
- background: #4d4d4d;
642
+ background: #4d4d4d;
620
643
  }
621
644
  </style>