@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.
- package/README.md +32 -31
- package/bin/gx-devtools.js +74 -54
- package/bin/lib/cli.js +23 -21
- package/bin/lib/commands/add-dependency.js +366 -325
- package/bin/lib/commands/assets.js +137 -139
- package/bin/lib/commands/build.js +169 -174
- package/bin/lib/commands/datastore.js +181 -183
- package/bin/lib/commands/dev.js +127 -131
- package/bin/lib/commands/extensions.js +147 -149
- package/bin/lib/commands/extract-config.js +73 -67
- package/bin/lib/commands/index.js +12 -12
- package/bin/lib/commands/init.js +342 -240
- package/bin/lib/commands/publish.js +69 -75
- package/bin/lib/commands/socket.js +69 -69
- package/bin/lib/commands/ssl.js +14 -14
- package/bin/lib/constants.js +10 -24
- package/bin/lib/tui/App.tsx +761 -705
- package/bin/lib/tui/components/AIPanel.tsx +191 -171
- package/bin/lib/tui/components/CommandInput.tsx +394 -343
- package/bin/lib/tui/components/GeminiPanel.tsx +175 -151
- package/bin/lib/tui/components/Header.tsx +23 -21
- package/bin/lib/tui/components/LogPanel.tsx +244 -220
- package/bin/lib/tui/components/TabBar.tsx +50 -48
- package/bin/lib/tui/components/WelcomeScreen.tsx +126 -71
- package/bin/lib/tui/index.tsx +37 -39
- package/bin/lib/tui/services/AIService.ts +518 -462
- package/bin/lib/tui/services/ExtensionService.ts +140 -129
- package/bin/lib/tui/services/GeminiService.ts +367 -337
- package/bin/lib/tui/services/ServiceManager.ts +344 -322
- package/bin/lib/tui/services/SocketService.ts +168 -168
- package/bin/lib/tui/services/ViteService.ts +88 -88
- package/bin/lib/tui/services/index.ts +47 -22
- package/bin/lib/utils/ai-scaffold.js +291 -280
- package/bin/lib/utils/extract-config.js +157 -140
- package/bin/lib/utils/files.js +82 -86
- package/bin/lib/utils/index.js +7 -7
- package/bin/lib/utils/paths.js +34 -34
- package/bin/lib/utils/prompts.js +194 -169
- package/bin/lib/utils/ssl.js +79 -81
- package/browser-extensions/README.md +0 -1
- package/browser-extensions/chrome/background.js +244 -237
- package/browser-extensions/chrome/content.js +32 -29
- package/browser-extensions/chrome/devtools.html +7 -7
- package/browser-extensions/chrome/devtools.js +19 -19
- package/browser-extensions/chrome/inspector.js +802 -767
- package/browser-extensions/chrome/manifest.json +71 -63
- package/browser-extensions/chrome/panel.html +674 -636
- package/browser-extensions/chrome/panel.js +722 -712
- package/browser-extensions/chrome/popup.html +586 -543
- package/browser-extensions/chrome/popup.js +282 -244
- package/browser-extensions/chrome/rules.json +1 -1
- package/browser-extensions/chrome/test-chrome.html +216 -136
- package/browser-extensions/chrome/test-mixed-content.html +284 -189
- package/browser-extensions/chrome/test-uri-pattern.html +221 -198
- package/browser-extensions/firefox/README.md +9 -6
- package/browser-extensions/firefox/background.js +221 -218
- package/browser-extensions/firefox/content.js +55 -52
- package/browser-extensions/firefox/debug-errors.html +386 -228
- package/browser-extensions/firefox/debug-https.html +153 -105
- package/browser-extensions/firefox/devtools.html +7 -7
- package/browser-extensions/firefox/devtools.js +23 -20
- package/browser-extensions/firefox/inspector.js +802 -767
- package/browser-extensions/firefox/manifest.json +68 -68
- package/browser-extensions/firefox/panel.html +674 -636
- package/browser-extensions/firefox/panel.js +722 -712
- package/browser-extensions/firefox/popup.html +572 -535
- package/browser-extensions/firefox/popup.js +281 -236
- package/browser-extensions/firefox/test-gramercy.html +170 -125
- package/browser-extensions/firefox/test-imports.html +59 -55
- package/browser-extensions/firefox/test-masking.html +231 -140
- package/browser-extensions/firefox/test-uri-pattern.html +221 -198
- package/dist/tui/App.d.ts +1 -1
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +154 -150
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/components/AIPanel.d.ts.map +1 -1
- package/dist/tui/components/AIPanel.js +42 -35
- package/dist/tui/components/AIPanel.js.map +1 -1
- package/dist/tui/components/CommandInput.d.ts +1 -1
- package/dist/tui/components/CommandInput.d.ts.map +1 -1
- package/dist/tui/components/CommandInput.js +92 -62
- package/dist/tui/components/CommandInput.js.map +1 -1
- package/dist/tui/components/GeminiPanel.d.ts.map +1 -1
- package/dist/tui/components/GeminiPanel.js +37 -30
- package/dist/tui/components/GeminiPanel.js.map +1 -1
- package/dist/tui/components/Header.d.ts.map +1 -1
- package/dist/tui/components/Header.js +1 -1
- package/dist/tui/components/Header.js.map +1 -1
- package/dist/tui/components/LogPanel.d.ts +1 -1
- package/dist/tui/components/LogPanel.d.ts.map +1 -1
- package/dist/tui/components/LogPanel.js +26 -24
- package/dist/tui/components/LogPanel.js.map +1 -1
- package/dist/tui/components/TabBar.d.ts +2 -2
- package/dist/tui/components/TabBar.d.ts.map +1 -1
- package/dist/tui/components/TabBar.js +11 -11
- package/dist/tui/components/TabBar.js.map +1 -1
- package/dist/tui/components/WelcomeScreen.d.ts.map +1 -1
- package/dist/tui/components/WelcomeScreen.js +6 -6
- package/dist/tui/components/WelcomeScreen.js.map +1 -1
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/index.js +8 -8
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/services/AIService.d.ts +2 -2
- package/dist/tui/services/AIService.d.ts.map +1 -1
- package/dist/tui/services/AIService.js +165 -125
- package/dist/tui/services/AIService.js.map +1 -1
- package/dist/tui/services/ExtensionService.d.ts +1 -1
- package/dist/tui/services/ExtensionService.d.ts.map +1 -1
- package/dist/tui/services/ExtensionService.js +33 -26
- package/dist/tui/services/ExtensionService.js.map +1 -1
- package/dist/tui/services/GeminiService.d.ts +1 -1
- package/dist/tui/services/GeminiService.d.ts.map +1 -1
- package/dist/tui/services/GeminiService.js +87 -76
- package/dist/tui/services/GeminiService.js.map +1 -1
- package/dist/tui/services/ServiceManager.d.ts +3 -3
- package/dist/tui/services/ServiceManager.d.ts.map +1 -1
- package/dist/tui/services/ServiceManager.js +72 -58
- package/dist/tui/services/ServiceManager.js.map +1 -1
- package/dist/tui/services/SocketService.d.ts.map +1 -1
- package/dist/tui/services/SocketService.js +32 -32
- package/dist/tui/services/SocketService.js.map +1 -1
- package/dist/tui/services/ViteService.d.ts.map +1 -1
- package/dist/tui/services/ViteService.js +26 -28
- package/dist/tui/services/ViteService.js.map +1 -1
- package/dist/tui/services/index.d.ts +6 -6
- package/dist/tui/services/index.d.ts.map +1 -1
- package/dist/tui/services/index.js +6 -6
- package/dist/tui/services/index.js.map +1 -1
- package/mcp/gxp-api-server.js +83 -81
- package/package.json +109 -93
- package/runtime/PortalContainer.vue +258 -234
- package/runtime/dev-tools/DevToolsModal.vue +153 -155
- package/runtime/dev-tools/LayoutSwitcher.vue +144 -140
- package/runtime/dev-tools/MockDataEditor.vue +456 -433
- package/runtime/dev-tools/SocketSimulator.vue +379 -371
- package/runtime/dev-tools/StoreInspector.vue +517 -455
- package/runtime/dev-tools/index.js +5 -5
- package/runtime/fallback-layouts/PrivateLayout.vue +2 -2
- package/runtime/fallback-layouts/PublicLayout.vue +2 -2
- package/runtime/fallback-layouts/SystemLayout.vue +2 -2
- package/runtime/gxpStringsPlugin.js +159 -134
- package/runtime/index.html +17 -19
- package/runtime/main.js +24 -22
- package/runtime/mock-api/auth-middleware.js +15 -15
- package/runtime/mock-api/image-generator.js +46 -46
- package/runtime/mock-api/index.js +55 -55
- package/runtime/mock-api/response-generator.js +116 -105
- package/runtime/mock-api/route-generator.js +107 -84
- package/runtime/mock-api/socket-triggers.js +94 -93
- package/runtime/mock-api/spec-loader.js +79 -80
- package/runtime/package.json +3 -0
- package/runtime/server.js +68 -68
- package/runtime/stores/gxpPortalConfigStore.js +204 -186
- package/runtime/stores/index.js +2 -2
- package/runtime/vite-inspector-plugin.js +858 -707
- package/runtime/vite-source-tracker-plugin.js +132 -113
- package/runtime/vite.config.js +191 -139
- package/scripts/launch-chrome.js +41 -41
- package/scripts/pack-chrome.js +38 -39
- package/socket-events/AiSessionMessageCreated.json +17 -17
- package/socket-events/SocialStreamPostCreated.json +23 -23
- package/socket-events/SocialStreamPostVariantCompleted.json +22 -22
- package/template/.claude/agents/gxp-developer.md +100 -99
- package/template/.claude/settings.json +7 -7
- package/template/AGENTS.md +30 -23
- package/template/GEMINI.md +20 -20
- package/template/README.md +70 -53
- package/template/app-manifest.json +2 -4
- package/template/configuration.json +10 -10
- package/template/default-styling.css +1 -1
- package/template/index.html +18 -20
- package/template/main.js +24 -22
- package/template/src/DemoPage.vue +415 -362
- package/template/src/Plugin.vue +76 -85
- package/template/src/stores/index.js +3 -3
- package/template/src/stores/test-data.json +164 -172
- package/template/theme-layouts/AdditionalStyling.css +50 -50
- package/template/theme-layouts/PrivateLayout.vue +8 -12
- package/template/theme-layouts/PublicLayout.vue +8 -12
- package/template/theme-layouts/SystemLayout.vue +8 -12
- package/template/vite.extend.js +45 -0
- package/template/vite.config.js +0 -409
|
@@ -1,331 +1,381 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
2
|
+
<div class="store-inspector">
|
|
3
|
+
<div class="inspector-section">
|
|
4
|
+
<h3 class="section-title" @click="toggleSection('pluginVars')">
|
|
5
|
+
<span class="toggle-icon">{{
|
|
6
|
+
expandedSections.pluginVars ? "▼" : "▶"
|
|
7
|
+
}}</span>
|
|
8
|
+
Plugin Variables
|
|
9
|
+
<span class="item-count">{{
|
|
10
|
+
Object.keys(store.pluginVars || {}).length
|
|
11
|
+
}}</span>
|
|
12
|
+
</h3>
|
|
13
|
+
<div v-if="expandedSections.pluginVars" class="section-content">
|
|
14
|
+
<div
|
|
15
|
+
v-if="Object.keys(store.pluginVars || {}).length === 0"
|
|
16
|
+
class="empty-state"
|
|
17
|
+
>
|
|
18
|
+
No plugin variables defined
|
|
19
|
+
</div>
|
|
20
|
+
<div v-else class="property-list">
|
|
21
|
+
<div
|
|
22
|
+
v-for="(value, key) in store.pluginVars"
|
|
23
|
+
:key="key"
|
|
24
|
+
class="property-item"
|
|
25
|
+
@mouseenter="highlightElements('gxp-settings', key)"
|
|
26
|
+
@mouseleave="clearHighlight()"
|
|
27
|
+
>
|
|
28
|
+
<span class="property-key">{{ key }}</span>
|
|
29
|
+
<input
|
|
30
|
+
v-if="editingKey === `pluginVars.${key}`"
|
|
31
|
+
v-model="editValue"
|
|
32
|
+
class="property-input"
|
|
33
|
+
@blur="saveEdit('pluginVars', key)"
|
|
34
|
+
@keydown.enter="saveEdit('pluginVars', key)"
|
|
35
|
+
@keydown.escape="cancelEdit"
|
|
36
|
+
ref="editInput"
|
|
37
|
+
/>
|
|
38
|
+
<span
|
|
39
|
+
v-else
|
|
40
|
+
class="property-value"
|
|
41
|
+
:class="getValueType(value)"
|
|
42
|
+
@dblclick="startEdit('pluginVars', key, value)"
|
|
43
|
+
:title="'Double-click to edit'"
|
|
44
|
+
>
|
|
45
|
+
{{ formatValue(value) }}
|
|
46
|
+
</span>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<div class="inspector-section">
|
|
53
|
+
<h3 class="section-title" @click="toggleSection('stringsList')">
|
|
54
|
+
<span class="toggle-icon">{{
|
|
55
|
+
expandedSections.stringsList ? "▼" : "▶"
|
|
56
|
+
}}</span>
|
|
57
|
+
Strings List
|
|
58
|
+
<span class="item-count">{{
|
|
59
|
+
Object.keys(store.stringsList || {}).length
|
|
60
|
+
}}</span>
|
|
61
|
+
</h3>
|
|
62
|
+
<div v-if="expandedSections.stringsList" class="section-content">
|
|
63
|
+
<div
|
|
64
|
+
v-if="Object.keys(store.stringsList || {}).length === 0"
|
|
65
|
+
class="empty-state"
|
|
66
|
+
>
|
|
67
|
+
No strings defined
|
|
68
|
+
</div>
|
|
69
|
+
<div v-else class="property-list">
|
|
70
|
+
<div
|
|
71
|
+
v-for="(value, key) in store.stringsList"
|
|
72
|
+
:key="key"
|
|
73
|
+
class="property-item"
|
|
74
|
+
@mouseenter="highlightElements('gxp-string', key)"
|
|
75
|
+
@mouseleave="clearHighlight()"
|
|
76
|
+
>
|
|
77
|
+
<span class="property-key">{{ key }}</span>
|
|
78
|
+
<input
|
|
79
|
+
v-if="editingKey === `stringsList.${key}`"
|
|
80
|
+
v-model="editValue"
|
|
81
|
+
class="property-input"
|
|
82
|
+
@blur="saveEdit('stringsList', key)"
|
|
83
|
+
@keydown.enter="saveEdit('stringsList', key)"
|
|
84
|
+
@keydown.escape="cancelEdit"
|
|
85
|
+
/>
|
|
86
|
+
<span
|
|
87
|
+
v-else
|
|
88
|
+
class="property-value string"
|
|
89
|
+
@dblclick="startEdit('stringsList', key, value)"
|
|
90
|
+
:title="'Double-click to edit'"
|
|
91
|
+
>
|
|
92
|
+
"{{ value }}"
|
|
93
|
+
</span>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
|
|
99
|
+
<div class="inspector-section">
|
|
100
|
+
<h3 class="section-title" @click="toggleSection('assetList')">
|
|
101
|
+
<span class="toggle-icon">{{
|
|
102
|
+
expandedSections.assetList ? "▼" : "▶"
|
|
103
|
+
}}</span>
|
|
104
|
+
Asset List
|
|
105
|
+
<span class="item-count">{{
|
|
106
|
+
Object.keys(store.assetList || {}).length
|
|
107
|
+
}}</span>
|
|
108
|
+
</h3>
|
|
109
|
+
<div v-if="expandedSections.assetList" class="section-content">
|
|
110
|
+
<div
|
|
111
|
+
v-if="Object.keys(store.assetList || {}).length === 0"
|
|
112
|
+
class="empty-state"
|
|
113
|
+
>
|
|
114
|
+
No assets defined
|
|
115
|
+
</div>
|
|
116
|
+
<div v-else class="property-list">
|
|
117
|
+
<div
|
|
118
|
+
v-for="(value, key) in store.assetList"
|
|
119
|
+
:key="key"
|
|
120
|
+
class="property-item asset-item"
|
|
121
|
+
@mouseenter="highlightElements('gxp-src', key)"
|
|
122
|
+
@mouseleave="clearHighlight()"
|
|
123
|
+
>
|
|
124
|
+
<span class="property-key">{{ key }}</span>
|
|
125
|
+
<div class="asset-preview">
|
|
126
|
+
<img
|
|
127
|
+
v-if="isImageUrl(value)"
|
|
128
|
+
:src="value"
|
|
129
|
+
class="asset-thumbnail"
|
|
130
|
+
@error="(e) => (e.target.style.display = 'none')"
|
|
131
|
+
/>
|
|
132
|
+
<span class="property-value string" :title="value">
|
|
133
|
+
{{ truncateUrl(value) }}
|
|
134
|
+
</span>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
|
|
141
|
+
<div class="inspector-section">
|
|
142
|
+
<h3 class="section-title" @click="toggleSection('triggerState')">
|
|
143
|
+
<span class="toggle-icon">{{
|
|
144
|
+
expandedSections.triggerState ? "▼" : "▶"
|
|
145
|
+
}}</span>
|
|
146
|
+
Trigger State
|
|
147
|
+
<span class="item-count">{{
|
|
148
|
+
Object.keys(store.triggerState || {}).length
|
|
149
|
+
}}</span>
|
|
150
|
+
</h3>
|
|
151
|
+
<div v-if="expandedSections.triggerState" class="section-content">
|
|
152
|
+
<div
|
|
153
|
+
v-if="Object.keys(store.triggerState || {}).length === 0"
|
|
154
|
+
class="empty-state"
|
|
155
|
+
>
|
|
156
|
+
No trigger state defined
|
|
157
|
+
</div>
|
|
158
|
+
<div v-else class="property-list">
|
|
159
|
+
<div
|
|
160
|
+
v-for="(value, key) in store.triggerState"
|
|
161
|
+
:key="key"
|
|
162
|
+
class="property-item"
|
|
163
|
+
@mouseenter="highlightElements('gxp-state', key)"
|
|
164
|
+
@mouseleave="clearHighlight()"
|
|
165
|
+
>
|
|
166
|
+
<span class="property-key">{{ key }}</span>
|
|
167
|
+
<span class="property-value" :class="getValueType(value)">
|
|
168
|
+
{{ formatValue(value) }}
|
|
169
|
+
</span>
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
|
|
175
|
+
<div class="inspector-section">
|
|
176
|
+
<h3 class="section-title" @click="toggleSection('dependencyList')">
|
|
177
|
+
<span class="toggle-icon">{{
|
|
178
|
+
expandedSections.dependencyList ? "▼" : "▶"
|
|
179
|
+
}}</span>
|
|
180
|
+
Dependencies
|
|
181
|
+
<span class="item-count">{{ getDependencyCount() }}</span>
|
|
182
|
+
</h3>
|
|
183
|
+
<div v-if="expandedSections.dependencyList" class="section-content">
|
|
184
|
+
<div v-if="getDependencyCount() === 0" class="empty-state">
|
|
185
|
+
No dependencies defined
|
|
186
|
+
</div>
|
|
187
|
+
<div v-else class="property-list">
|
|
188
|
+
<div
|
|
189
|
+
v-for="(value, key) in store.dependencyList"
|
|
190
|
+
:key="key"
|
|
191
|
+
class="property-item"
|
|
192
|
+
>
|
|
193
|
+
<span class="property-key">{{ key }}</span>
|
|
194
|
+
<input
|
|
195
|
+
v-if="editingKey === `dependencyList.${key}`"
|
|
196
|
+
v-model="editValue"
|
|
197
|
+
class="property-input"
|
|
198
|
+
@blur="saveEdit('dependencyList', key)"
|
|
199
|
+
@keydown.enter="saveEdit('dependencyList', key)"
|
|
200
|
+
@keydown.escape="cancelEdit"
|
|
201
|
+
/>
|
|
202
|
+
<span
|
|
203
|
+
v-else
|
|
204
|
+
class="property-value string"
|
|
205
|
+
@dblclick="startEdit('dependencyList', key, value)"
|
|
206
|
+
:title="'Double-click to edit'"
|
|
207
|
+
>
|
|
208
|
+
"{{ value }}"
|
|
209
|
+
</span>
|
|
210
|
+
</div>
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
213
|
+
</div>
|
|
214
|
+
|
|
215
|
+
<div class="inspector-actions">
|
|
216
|
+
<button
|
|
217
|
+
class="action-btn"
|
|
218
|
+
@click="refreshStore"
|
|
219
|
+
title="Refresh store data"
|
|
220
|
+
>
|
|
221
|
+
Refresh
|
|
222
|
+
</button>
|
|
223
|
+
<button
|
|
224
|
+
class="action-btn"
|
|
225
|
+
@click="copyStoreToClipboard"
|
|
226
|
+
title="Copy store state to clipboard"
|
|
227
|
+
>
|
|
228
|
+
Copy JSON
|
|
229
|
+
</button>
|
|
230
|
+
</div>
|
|
231
|
+
</div>
|
|
194
232
|
</template>
|
|
195
233
|
|
|
196
234
|
<script setup>
|
|
197
|
-
import { ref, reactive, nextTick, onUnmounted } from
|
|
235
|
+
import { ref, reactive, nextTick, onUnmounted } from "vue"
|
|
198
236
|
|
|
199
237
|
const props = defineProps({
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
})
|
|
238
|
+
store: {
|
|
239
|
+
type: Object,
|
|
240
|
+
required: true,
|
|
241
|
+
},
|
|
242
|
+
})
|
|
205
243
|
|
|
206
244
|
// Element highlighting
|
|
207
|
-
const highlightedElements = ref([])
|
|
208
|
-
const highlightOverlays = ref([])
|
|
245
|
+
const highlightedElements = ref([])
|
|
246
|
+
const highlightOverlays = ref([])
|
|
209
247
|
|
|
210
248
|
const expandedSections = reactive({
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
})
|
|
249
|
+
pluginVars: true,
|
|
250
|
+
stringsList: false,
|
|
251
|
+
assetList: false,
|
|
252
|
+
triggerState: false,
|
|
253
|
+
dependencyList: false,
|
|
254
|
+
})
|
|
217
255
|
|
|
218
|
-
const editingKey = ref(null)
|
|
219
|
-
const editValue = ref(
|
|
256
|
+
const editingKey = ref(null)
|
|
257
|
+
const editValue = ref("")
|
|
220
258
|
|
|
221
259
|
function toggleSection(section) {
|
|
222
|
-
|
|
260
|
+
expandedSections[section] = !expandedSections[section]
|
|
223
261
|
}
|
|
224
262
|
|
|
225
263
|
function getValueType(value) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
264
|
+
if (value === null) return "null"
|
|
265
|
+
if (value === undefined) return "undefined"
|
|
266
|
+
if (typeof value === "boolean") return "boolean"
|
|
267
|
+
if (typeof value === "number") return "number"
|
|
268
|
+
if (typeof value === "string") return "string"
|
|
269
|
+
if (Array.isArray(value)) return "array"
|
|
270
|
+
if (typeof value === "object") return "object"
|
|
271
|
+
return "unknown"
|
|
234
272
|
}
|
|
235
273
|
|
|
236
274
|
function formatValue(value) {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
275
|
+
if (value === null) return "null"
|
|
276
|
+
if (value === undefined) return "undefined"
|
|
277
|
+
if (typeof value === "boolean") return value ? "true" : "false"
|
|
278
|
+
if (typeof value === "number") return value.toString()
|
|
279
|
+
if (typeof value === "string") return `"${value}"`
|
|
280
|
+
if (Array.isArray(value)) return `Array(${value.length})`
|
|
281
|
+
if (typeof value === "object") return `Object(${Object.keys(value).length})`
|
|
282
|
+
return String(value)
|
|
245
283
|
}
|
|
246
284
|
|
|
247
285
|
function isImageUrl(url) {
|
|
248
|
-
|
|
249
|
-
|
|
286
|
+
if (typeof url !== "string") return false
|
|
287
|
+
return /\.(jpg|jpeg|png|gif|webp|svg)(\?.*)?$/i.test(url)
|
|
250
288
|
}
|
|
251
289
|
|
|
252
290
|
function truncateUrl(url, maxLength = 50) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
291
|
+
if (typeof url !== "string") return url
|
|
292
|
+
if (url.length <= maxLength) return url
|
|
293
|
+
return url.substring(0, maxLength) + "..."
|
|
256
294
|
}
|
|
257
295
|
|
|
258
296
|
function getDependencyCount() {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
297
|
+
const deps = props.store.dependencyList
|
|
298
|
+
if (!deps) return 0
|
|
299
|
+
if (Array.isArray(deps)) return deps.length
|
|
300
|
+
return Object.keys(deps).length
|
|
263
301
|
}
|
|
264
302
|
|
|
265
303
|
function startEdit(section, key, value) {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
304
|
+
editingKey.value = `${section}.${key}`
|
|
305
|
+
editValue.value = typeof value === "string" ? value : JSON.stringify(value)
|
|
306
|
+
nextTick(() => {
|
|
307
|
+
const input = document.querySelector(".property-input")
|
|
308
|
+
if (input) input.focus()
|
|
309
|
+
})
|
|
272
310
|
}
|
|
273
311
|
|
|
274
312
|
function saveEdit(section, key) {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
313
|
+
if (editingKey.value && props.store[section]) {
|
|
314
|
+
let newValue = editValue.value
|
|
315
|
+
// Try to parse as JSON for non-string values
|
|
316
|
+
try {
|
|
317
|
+
const parsed = JSON.parse(newValue)
|
|
318
|
+
newValue = parsed
|
|
319
|
+
} catch {
|
|
320
|
+
// Keep as string if not valid JSON
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Use the store's update methods to ensure Vue reactivity triggers properly
|
|
324
|
+
// This will update any gxp-string/gxp-src directives that depend on these values
|
|
325
|
+
if (
|
|
326
|
+
section === "stringsList" &&
|
|
327
|
+
typeof props.store.updateString === "function"
|
|
328
|
+
) {
|
|
329
|
+
props.store.updateString(key, newValue)
|
|
330
|
+
} else if (
|
|
331
|
+
section === "pluginVars" &&
|
|
332
|
+
typeof props.store.updateSetting === "function"
|
|
333
|
+
) {
|
|
334
|
+
props.store.updateSetting(key, newValue)
|
|
335
|
+
} else if (
|
|
336
|
+
section === "assetList" &&
|
|
337
|
+
typeof props.store.updateAsset === "function"
|
|
338
|
+
) {
|
|
339
|
+
props.store.updateAsset(key, newValue)
|
|
340
|
+
} else if (
|
|
341
|
+
section === "triggerState" &&
|
|
342
|
+
typeof props.store.updateState === "function"
|
|
343
|
+
) {
|
|
344
|
+
props.store.updateState(key, newValue)
|
|
345
|
+
} else {
|
|
346
|
+
// Fallback for older stores without update methods
|
|
347
|
+
props.store[section][key] = newValue
|
|
348
|
+
}
|
|
349
|
+
console.log(`[DevTools] Updated ${section}.${key}:`, newValue)
|
|
350
|
+
}
|
|
351
|
+
cancelEdit()
|
|
302
352
|
}
|
|
303
353
|
|
|
304
354
|
function cancelEdit() {
|
|
305
|
-
|
|
306
|
-
|
|
355
|
+
editingKey.value = null
|
|
356
|
+
editValue.value = ""
|
|
307
357
|
}
|
|
308
358
|
|
|
309
359
|
function refreshStore() {
|
|
310
|
-
|
|
311
|
-
|
|
360
|
+
// Force reactivity update
|
|
361
|
+
console.log("[DevTools] Store refreshed")
|
|
312
362
|
}
|
|
313
363
|
|
|
314
364
|
async function copyStoreToClipboard() {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
365
|
+
const storeData = {
|
|
366
|
+
pluginVars: props.store.pluginVars,
|
|
367
|
+
stringsList: props.store.stringsList,
|
|
368
|
+
assetList: props.store.assetList,
|
|
369
|
+
triggerState: props.store.triggerState,
|
|
370
|
+
dependencyList: props.store.dependencyList,
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
try {
|
|
374
|
+
await navigator.clipboard.writeText(JSON.stringify(storeData, null, 2))
|
|
375
|
+
console.log("[DevTools] Store data copied to clipboard")
|
|
376
|
+
} catch (err) {
|
|
377
|
+
console.error("[DevTools] Failed to copy:", err)
|
|
378
|
+
}
|
|
329
379
|
}
|
|
330
380
|
|
|
331
381
|
/**
|
|
@@ -334,15 +384,15 @@ async function copyStoreToClipboard() {
|
|
|
334
384
|
*/
|
|
335
385
|
|
|
336
386
|
// CSS class name for our highlight overlay
|
|
337
|
-
const HIGHLIGHT_CLASS =
|
|
387
|
+
const HIGHLIGHT_CLASS = "gxp-devtools-highlight-overlay"
|
|
338
388
|
|
|
339
389
|
// Inject highlight styles into the document if not already present
|
|
340
390
|
function ensureHighlightStyles() {
|
|
341
|
-
|
|
391
|
+
if (document.getElementById("gxp-devtools-highlight-styles")) return
|
|
342
392
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
393
|
+
const style = document.createElement("style")
|
|
394
|
+
style.id = "gxp-devtools-highlight-styles"
|
|
395
|
+
style.textContent = `
|
|
346
396
|
.${HIGHLIGHT_CLASS} {
|
|
347
397
|
position: fixed;
|
|
348
398
|
pointer-events: none;
|
|
@@ -371,274 +421,286 @@ function ensureHighlightStyles() {
|
|
|
371
421
|
0%, 100% { box-shadow: 0 0 10px rgba(97, 218, 251, 0.5), inset 0 0 10px rgba(97, 218, 251, 0.1); }
|
|
372
422
|
50% { box-shadow: 0 0 20px rgba(97, 218, 251, 0.8), inset 0 0 15px rgba(97, 218, 251, 0.2); }
|
|
373
423
|
}
|
|
374
|
-
|
|
375
|
-
|
|
424
|
+
`
|
|
425
|
+
document.head.appendChild(style)
|
|
376
426
|
}
|
|
377
427
|
|
|
378
428
|
// Find elements that match a gxp attribute and key
|
|
379
429
|
function findMatchingElements(attribute, key) {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
430
|
+
const elements = []
|
|
431
|
+
|
|
432
|
+
// For stringsList, look for gxp-string attribute (without gxp-settings, gxp-assets, gxp-state)
|
|
433
|
+
// For pluginVars (gxp-settings), look for gxp-string with gxp-settings modifier
|
|
434
|
+
// For assetList (gxp-src), look for gxp-src attribute
|
|
435
|
+
// For triggerState (gxp-state), look for gxp-string or gxp-src with gxp-state modifier
|
|
436
|
+
|
|
437
|
+
if (attribute === "gxp-string") {
|
|
438
|
+
// Find elements with gxp-string="key" that don't have modifiers
|
|
439
|
+
document.querySelectorAll(`[gxp-string="${key}"]`).forEach((el) => {
|
|
440
|
+
if (
|
|
441
|
+
!el.hasAttribute("gxp-settings") &&
|
|
442
|
+
!el.hasAttribute("gxp-assets") &&
|
|
443
|
+
!el.hasAttribute("gxp-state")
|
|
444
|
+
) {
|
|
445
|
+
elements.push(el)
|
|
446
|
+
}
|
|
447
|
+
})
|
|
448
|
+
} else if (attribute === "gxp-settings") {
|
|
449
|
+
// Find elements with gxp-string="key" AND gxp-settings attribute
|
|
450
|
+
document
|
|
451
|
+
.querySelectorAll(`[gxp-string="${key}"][gxp-settings]`)
|
|
452
|
+
.forEach((el) => {
|
|
453
|
+
elements.push(el)
|
|
454
|
+
})
|
|
455
|
+
} else if (attribute === "gxp-src") {
|
|
456
|
+
// Find elements with gxp-src="key" that don't have gxp-state modifier
|
|
457
|
+
document.querySelectorAll(`[gxp-src="${key}"]`).forEach((el) => {
|
|
458
|
+
if (!el.hasAttribute("gxp-state")) {
|
|
459
|
+
elements.push(el)
|
|
460
|
+
}
|
|
461
|
+
})
|
|
462
|
+
// Also check for gxp-string with gxp-assets modifier
|
|
463
|
+
document
|
|
464
|
+
.querySelectorAll(`[gxp-string="${key}"][gxp-assets]`)
|
|
465
|
+
.forEach((el) => {
|
|
466
|
+
elements.push(el)
|
|
467
|
+
})
|
|
468
|
+
} else if (attribute === "gxp-state") {
|
|
469
|
+
// Find elements with gxp-state modifier on either gxp-string or gxp-src
|
|
470
|
+
document
|
|
471
|
+
.querySelectorAll(`[gxp-string="${key}"][gxp-state]`)
|
|
472
|
+
.forEach((el) => {
|
|
473
|
+
elements.push(el)
|
|
474
|
+
})
|
|
475
|
+
document.querySelectorAll(`[gxp-src="${key}"][gxp-state]`).forEach((el) => {
|
|
476
|
+
elements.push(el)
|
|
477
|
+
})
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
return elements
|
|
421
481
|
}
|
|
422
482
|
|
|
423
483
|
// Create overlay for an element
|
|
424
484
|
function createOverlay(element, key) {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
485
|
+
const rect = element.getBoundingClientRect()
|
|
486
|
+
const overlay = document.createElement("div")
|
|
487
|
+
overlay.className = HIGHLIGHT_CLASS
|
|
488
|
+
overlay.setAttribute("data-gxp-key", key)
|
|
489
|
+
overlay.style.top = `${rect.top}px`
|
|
490
|
+
overlay.style.left = `${rect.left}px`
|
|
491
|
+
overlay.style.width = `${rect.width}px`
|
|
492
|
+
overlay.style.height = `${rect.height}px`
|
|
493
|
+
document.body.appendChild(overlay)
|
|
494
|
+
return overlay
|
|
435
495
|
}
|
|
436
496
|
|
|
437
497
|
// Highlight elements matching a key
|
|
438
498
|
function highlightElements(attribute, key) {
|
|
439
|
-
|
|
440
|
-
|
|
499
|
+
ensureHighlightStyles()
|
|
500
|
+
clearHighlight()
|
|
441
501
|
|
|
442
|
-
|
|
443
|
-
|
|
502
|
+
const elements = findMatchingElements(attribute, key)
|
|
503
|
+
highlightedElements.value = elements
|
|
444
504
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
505
|
+
elements.forEach((el) => {
|
|
506
|
+
const overlay = createOverlay(el, key)
|
|
507
|
+
highlightOverlays.value.push(overlay)
|
|
508
|
+
})
|
|
449
509
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
510
|
+
if (elements.length > 0) {
|
|
511
|
+
console.log(
|
|
512
|
+
`[DevTools] Highlighting ${elements.length} element(s) with ${attribute}="${key}"`,
|
|
513
|
+
)
|
|
514
|
+
}
|
|
453
515
|
}
|
|
454
516
|
|
|
455
517
|
// Clear all highlight overlays
|
|
456
518
|
function clearHighlight() {
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
519
|
+
highlightOverlays.value.forEach((overlay) => {
|
|
520
|
+
if (overlay && overlay.parentNode) {
|
|
521
|
+
overlay.parentNode.removeChild(overlay)
|
|
522
|
+
}
|
|
523
|
+
})
|
|
524
|
+
highlightOverlays.value = []
|
|
525
|
+
highlightedElements.value = []
|
|
464
526
|
}
|
|
465
527
|
|
|
466
528
|
// Clean up on unmount
|
|
467
529
|
onUnmounted(() => {
|
|
468
|
-
|
|
469
|
-
})
|
|
530
|
+
clearHighlight()
|
|
531
|
+
})
|
|
470
532
|
</script>
|
|
471
533
|
|
|
472
534
|
<style scoped>
|
|
473
535
|
.store-inspector {
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
536
|
+
display: flex;
|
|
537
|
+
flex-direction: column;
|
|
538
|
+
gap: 8px;
|
|
477
539
|
}
|
|
478
540
|
|
|
479
541
|
.inspector-section {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
542
|
+
background: #2d2d2d;
|
|
543
|
+
border-radius: 6px;
|
|
544
|
+
overflow: hidden;
|
|
483
545
|
}
|
|
484
546
|
|
|
485
547
|
.section-title {
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
548
|
+
display: flex;
|
|
549
|
+
align-items: center;
|
|
550
|
+
gap: 8px;
|
|
551
|
+
margin: 0;
|
|
552
|
+
padding: 10px 12px;
|
|
553
|
+
font-size: 13px;
|
|
554
|
+
font-weight: 500;
|
|
555
|
+
cursor: pointer;
|
|
556
|
+
user-select: none;
|
|
557
|
+
transition: background 0.2s;
|
|
496
558
|
}
|
|
497
559
|
|
|
498
560
|
.section-title:hover {
|
|
499
|
-
|
|
561
|
+
background: #3d3d3d;
|
|
500
562
|
}
|
|
501
563
|
|
|
502
564
|
.toggle-icon {
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
565
|
+
font-size: 10px;
|
|
566
|
+
color: #888;
|
|
567
|
+
width: 12px;
|
|
506
568
|
}
|
|
507
569
|
|
|
508
570
|
.item-count {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
571
|
+
margin-left: auto;
|
|
572
|
+
background: #3d3d3d;
|
|
573
|
+
padding: 2px 8px;
|
|
574
|
+
border-radius: 10px;
|
|
575
|
+
font-size: 11px;
|
|
576
|
+
color: #888;
|
|
515
577
|
}
|
|
516
578
|
|
|
517
579
|
.section-content {
|
|
518
|
-
|
|
519
|
-
|
|
580
|
+
padding: 8px 12px 12px;
|
|
581
|
+
border-top: 1px solid #3d3d3d;
|
|
520
582
|
}
|
|
521
583
|
|
|
522
584
|
.empty-state {
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
585
|
+
color: #666;
|
|
586
|
+
font-size: 12px;
|
|
587
|
+
font-style: italic;
|
|
588
|
+
padding: 8px 0;
|
|
527
589
|
}
|
|
528
590
|
|
|
529
591
|
.property-list {
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
592
|
+
display: flex;
|
|
593
|
+
flex-direction: column;
|
|
594
|
+
gap: 6px;
|
|
533
595
|
}
|
|
534
596
|
|
|
535
597
|
.property-item {
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
598
|
+
display: flex;
|
|
599
|
+
align-items: flex-start;
|
|
600
|
+
gap: 8px;
|
|
601
|
+
font-size: 12px;
|
|
602
|
+
font-family: "SF Mono", Monaco, "Courier New", monospace;
|
|
541
603
|
}
|
|
542
604
|
|
|
543
605
|
.property-key {
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
606
|
+
color: #9cdcfe;
|
|
607
|
+
min-width: 140px;
|
|
608
|
+
flex-shrink: 0;
|
|
547
609
|
}
|
|
548
610
|
|
|
549
611
|
.property-key::after {
|
|
550
|
-
|
|
551
|
-
|
|
612
|
+
content: ":";
|
|
613
|
+
color: #888;
|
|
552
614
|
}
|
|
553
615
|
|
|
554
616
|
.property-value {
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
617
|
+
word-break: break-all;
|
|
618
|
+
cursor: pointer;
|
|
619
|
+
padding: 2px 4px;
|
|
620
|
+
border-radius: 3px;
|
|
621
|
+
transition: background 0.2s;
|
|
560
622
|
}
|
|
561
623
|
|
|
562
624
|
.property-value:hover {
|
|
563
|
-
|
|
625
|
+
background: #3d3d3d;
|
|
564
626
|
}
|
|
565
627
|
|
|
566
628
|
.property-value.string {
|
|
567
|
-
|
|
629
|
+
color: #ce9178;
|
|
568
630
|
}
|
|
569
631
|
|
|
570
632
|
.property-value.number {
|
|
571
|
-
|
|
633
|
+
color: #b5cea8;
|
|
572
634
|
}
|
|
573
635
|
|
|
574
636
|
.property-value.boolean {
|
|
575
|
-
|
|
637
|
+
color: #569cd6;
|
|
576
638
|
}
|
|
577
639
|
|
|
578
640
|
.property-value.null,
|
|
579
641
|
.property-value.undefined {
|
|
580
|
-
|
|
581
|
-
|
|
642
|
+
color: #808080;
|
|
643
|
+
font-style: italic;
|
|
582
644
|
}
|
|
583
645
|
|
|
584
646
|
.property-value.object,
|
|
585
647
|
.property-value.array {
|
|
586
|
-
|
|
648
|
+
color: #dcdcaa;
|
|
587
649
|
}
|
|
588
650
|
|
|
589
651
|
.property-input {
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
652
|
+
flex: 1;
|
|
653
|
+
background: #3d3d3d;
|
|
654
|
+
border: 1px solid #61dafb;
|
|
655
|
+
color: #e0e0e0;
|
|
656
|
+
padding: 4px 8px;
|
|
657
|
+
border-radius: 3px;
|
|
658
|
+
font-family: inherit;
|
|
659
|
+
font-size: 12px;
|
|
660
|
+
outline: none;
|
|
599
661
|
}
|
|
600
662
|
|
|
601
663
|
.asset-item {
|
|
602
|
-
|
|
603
|
-
|
|
664
|
+
flex-direction: column;
|
|
665
|
+
gap: 4px;
|
|
604
666
|
}
|
|
605
667
|
|
|
606
668
|
.asset-preview {
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
669
|
+
display: flex;
|
|
670
|
+
align-items: center;
|
|
671
|
+
gap: 8px;
|
|
672
|
+
padding-left: 148px;
|
|
611
673
|
}
|
|
612
674
|
|
|
613
675
|
.asset-thumbnail {
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
676
|
+
width: 32px;
|
|
677
|
+
height: 32px;
|
|
678
|
+
object-fit: cover;
|
|
679
|
+
border-radius: 4px;
|
|
680
|
+
background: #3d3d3d;
|
|
619
681
|
}
|
|
620
682
|
|
|
621
683
|
.inspector-actions {
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
684
|
+
display: flex;
|
|
685
|
+
gap: 8px;
|
|
686
|
+
margin-top: 12px;
|
|
687
|
+
padding-top: 12px;
|
|
688
|
+
border-top: 1px solid #3d3d3d;
|
|
627
689
|
}
|
|
628
690
|
|
|
629
691
|
.action-btn {
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
692
|
+
background: #3d3d3d;
|
|
693
|
+
border: none;
|
|
694
|
+
color: #e0e0e0;
|
|
695
|
+
padding: 8px 16px;
|
|
696
|
+
border-radius: 4px;
|
|
697
|
+
cursor: pointer;
|
|
698
|
+
font-size: 12px;
|
|
699
|
+
transition: all 0.2s;
|
|
638
700
|
}
|
|
639
701
|
|
|
640
702
|
.action-btn:hover {
|
|
641
|
-
|
|
642
|
-
|
|
703
|
+
background: #4d4d4d;
|
|
704
|
+
color: #61dafb;
|
|
643
705
|
}
|
|
644
706
|
</style>
|