imcp 0.0.12 → 0.0.14
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/core/ConfigurationProvider.d.ts +2 -1
- package/dist/core/ConfigurationProvider.js +20 -24
- package/dist/core/InstallationService.d.ts +17 -0
- package/dist/core/InstallationService.js +127 -61
- package/dist/core/MCPManager.d.ts +1 -0
- package/dist/core/MCPManager.js +3 -0
- package/dist/core/RequirementService.d.ts +4 -4
- package/dist/core/RequirementService.js +11 -7
- package/dist/core/ServerSchemaProvider.d.ts +1 -1
- package/dist/core/ServerSchemaProvider.js +15 -10
- package/dist/core/constants.d.ts +3 -0
- package/dist/core/constants.js +4 -1
- package/dist/core/installers/clients/ClientInstaller.js +58 -40
- package/dist/core/installers/requirements/PipInstaller.js +10 -5
- package/dist/core/onboard/FeedOnboardService.d.ts +35 -0
- package/dist/core/onboard/FeedOnboardService.js +137 -0
- package/dist/core/types.d.ts +6 -1
- package/dist/core/validators/FeedValidator.d.ts +13 -0
- package/dist/core/validators/FeedValidator.js +27 -0
- package/dist/services/ServerService.d.ts +5 -0
- package/dist/services/ServerService.js +15 -0
- package/dist/utils/githubAuth.js +0 -10
- package/dist/utils/githubUtils.d.ts +16 -0
- package/dist/utils/githubUtils.js +55 -39
- package/dist/web/contract/serverContract.d.ts +64 -0
- package/dist/web/contract/serverContract.js +2 -0
- package/dist/web/public/css/detailsWidget.css +157 -32
- package/dist/web/public/css/onboard.css +44 -0
- package/dist/web/public/css/serverDetails.css +35 -19
- package/dist/web/public/index.html +16 -10
- package/dist/web/public/js/detailsWidget.js +43 -40
- package/dist/web/public/js/modal/index.js +58 -0
- package/dist/web/public/js/modal/installHandler.js +227 -0
- package/dist/web/public/js/modal/installModal.js +163 -0
- package/dist/web/public/js/modal/installation.js +281 -0
- package/dist/web/public/js/modal/loadingModal.js +52 -0
- package/dist/web/public/js/modal/loadingUI.js +74 -0
- package/dist/web/public/js/modal/messageQueue.js +112 -0
- package/dist/web/public/js/modal/modalSetup.js +512 -0
- package/dist/web/public/js/modal/modalUI.js +214 -0
- package/dist/web/public/js/modal/modalUtils.js +49 -0
- package/dist/web/public/js/modal/version.js +20 -0
- package/dist/web/public/js/modal/versionUtils.js +20 -0
- package/dist/web/public/js/modal.js +25 -1041
- package/dist/web/public/js/onboard/formProcessor.js +309 -0
- package/dist/web/public/js/onboard/index.js +131 -0
- package/dist/web/public/js/onboard/state.js +32 -0
- package/dist/web/public/js/onboard/templates.js +375 -0
- package/dist/web/public/js/onboard/uiHandlers.js +196 -0
- package/dist/web/public/js/serverCategoryDetails.js +211 -123
- package/dist/web/public/onboard.html +150 -0
- package/dist/web/server.js +25 -0
- package/package.json +3 -4
- package/src/core/ConfigurationProvider.ts +37 -29
- package/src/core/InstallationService.ts +176 -62
- package/src/core/MCPManager.ts +4 -0
- package/src/core/RequirementService.ts +12 -8
- package/src/core/ServerSchemaLoader.ts +48 -0
- package/src/core/ServerSchemaProvider.ts +137 -0
- package/src/core/constants.ts +4 -1
- package/src/core/installers/clients/ClientInstaller.ts +66 -49
- package/src/core/installers/requirements/PipInstaller.ts +10 -5
- package/src/core/types.ts +6 -1
- package/src/services/ServerService.ts +15 -0
- package/src/utils/githubAuth.ts +14 -27
- package/src/utils/githubUtils.ts +84 -47
- package/src/web/public/css/detailsWidget.css +235 -0
- package/src/web/public/css/serverDetails.css +126 -0
- package/src/web/public/index.html +16 -10
- package/src/web/public/js/detailsWidget.js +264 -0
- package/src/web/public/js/modal/index.js +58 -0
- package/src/web/public/js/modal/installModal.js +163 -0
- package/src/web/public/js/modal/installation.js +281 -0
- package/src/web/public/js/modal/loadingModal.js +52 -0
- package/src/web/public/js/modal/messageQueue.js +112 -0
- package/src/web/public/js/modal/modalSetup.js +512 -0
- package/src/web/public/js/modal/modalUtils.js +49 -0
- package/src/web/public/js/modal/versionUtils.js +20 -0
- package/src/web/public/js/modal.js +25 -1041
- package/src/web/public/js/serverCategoryDetails.js +211 -123
- package/src/web/server.ts +31 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
// Form data processing and API calls
|
|
2
|
+
export async function submitForm(event) {
|
|
3
|
+
event.preventDefault();
|
|
4
|
+
const formData = new FormData(event.target);
|
|
5
|
+
const jsonData = formDataToJson(formData);
|
|
6
|
+
|
|
7
|
+
try {
|
|
8
|
+
const response = await fetch('/api/categories/onboard', {
|
|
9
|
+
method: 'POST',
|
|
10
|
+
headers: {
|
|
11
|
+
'Content-Type': 'application/json'
|
|
12
|
+
},
|
|
13
|
+
body: JSON.stringify({
|
|
14
|
+
categoryData: {
|
|
15
|
+
name: jsonData.name || '',
|
|
16
|
+
displayName: jsonData.displayName || '',
|
|
17
|
+
description: jsonData.description,
|
|
18
|
+
repository: jsonData.repository,
|
|
19
|
+
requirements: jsonData.requirements,
|
|
20
|
+
mcpServers: jsonData.servers?.map(server => ({
|
|
21
|
+
name: server.name,
|
|
22
|
+
description: server.description,
|
|
23
|
+
mode: server.mode,
|
|
24
|
+
schemas: server.schemas,
|
|
25
|
+
dependencies: server.dependencies,
|
|
26
|
+
installation: {
|
|
27
|
+
command: server.installation?.command,
|
|
28
|
+
args: server.installation?.args,
|
|
29
|
+
env: server.installation?.env?.reduce((acc, env) => {
|
|
30
|
+
acc[env.name] = {
|
|
31
|
+
name: env.name,
|
|
32
|
+
default: env.default,
|
|
33
|
+
required: env.required || false,
|
|
34
|
+
description: env.description
|
|
35
|
+
};
|
|
36
|
+
return acc;
|
|
37
|
+
}, {})
|
|
38
|
+
}
|
|
39
|
+
}))
|
|
40
|
+
},
|
|
41
|
+
isUpdate: new URLSearchParams(window.location.search).has('category')
|
|
42
|
+
})
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
if (!response.ok) {
|
|
46
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const result = await response.json();
|
|
50
|
+
console.log('Form submitted successfully:', result);
|
|
51
|
+
alert('Form submitted successfully!');
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error('Error submitting form:', error);
|
|
54
|
+
alert('Error submitting form. Please try again.');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function formDataToJson(formData) {
|
|
59
|
+
// Basic category information
|
|
60
|
+
const categoryData = {
|
|
61
|
+
name: formData.get('name'),
|
|
62
|
+
displayName: formData.get('displayName'),
|
|
63
|
+
description: formData.get('description'),
|
|
64
|
+
repository: formData.get('repository')
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const servers = [];
|
|
68
|
+
|
|
69
|
+
// Process servers
|
|
70
|
+
for (let [key, value] of formData.entries()) {
|
|
71
|
+
if (key.startsWith('servers[')) {
|
|
72
|
+
const matches = key.match(/servers\[(\d+)\]\.(.+)/);
|
|
73
|
+
if (matches) {
|
|
74
|
+
const [, index, field] = matches;
|
|
75
|
+
|
|
76
|
+
if (!servers[index]) {
|
|
77
|
+
servers[index] = {
|
|
78
|
+
requirements: [],
|
|
79
|
+
installation: {
|
|
80
|
+
env: []
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Handle nested fields
|
|
86
|
+
if (field.includes('.')) {
|
|
87
|
+
const fieldParts = field.split('.');
|
|
88
|
+
let current = servers[index];
|
|
89
|
+
|
|
90
|
+
for (let i = 0; i < fieldParts.length - 1; i++) {
|
|
91
|
+
if (/\[\d+\]/.test(fieldParts[i])) {
|
|
92
|
+
const arrayMatches = fieldParts[i].match(/(.+)\[(\d+)\]/);
|
|
93
|
+
if (arrayMatches) {
|
|
94
|
+
const [, arrayName, arrayIndex] = arrayMatches;
|
|
95
|
+
if (!current[arrayName]) {
|
|
96
|
+
current[arrayName] = [];
|
|
97
|
+
}
|
|
98
|
+
if (!current[arrayName][arrayIndex]) {
|
|
99
|
+
current[arrayName][arrayIndex] = {};
|
|
100
|
+
}
|
|
101
|
+
current = current[arrayName][arrayIndex];
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
if (!current[fieldParts[i]]) {
|
|
105
|
+
current[fieldParts[i]] = {};
|
|
106
|
+
}
|
|
107
|
+
current = current[fieldParts[i]];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const lastField = fieldParts[fieldParts.length - 1];
|
|
112
|
+
if (lastField === 'required') {
|
|
113
|
+
current[lastField] = formData.get(key) === 'on';
|
|
114
|
+
} else {
|
|
115
|
+
current[lastField] = value;
|
|
116
|
+
}
|
|
117
|
+
} else {
|
|
118
|
+
servers[index][field] = value;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Process and clean up requirements
|
|
125
|
+
|
|
126
|
+
// Clean up servers data
|
|
127
|
+
const cleanServers = servers.filter(Boolean).map(server => {
|
|
128
|
+
const serverRequirements = (server.requirements || []).filter(Boolean).map(req => ({
|
|
129
|
+
name: req.name,
|
|
130
|
+
version: req.version,
|
|
131
|
+
order: req.order || undefined
|
|
132
|
+
}));
|
|
133
|
+
|
|
134
|
+
const cleanServer = {
|
|
135
|
+
name: server.name,
|
|
136
|
+
mode: server.mode,
|
|
137
|
+
description: server.description,
|
|
138
|
+
schemas: server.schemas || undefined,
|
|
139
|
+
dependencies: {
|
|
140
|
+
requirements: serverRequirements
|
|
141
|
+
},
|
|
142
|
+
requirements: (server.requirements || []).filter(Boolean).map(req => ({
|
|
143
|
+
name: req.name,
|
|
144
|
+
type: req.type,
|
|
145
|
+
version: req.version,
|
|
146
|
+
order: req.order || undefined,
|
|
147
|
+
alias: req.type === 'command' ? req.alias : undefined,
|
|
148
|
+
...(req.registryType && req.registryType !== 'public' && {
|
|
149
|
+
registry: {
|
|
150
|
+
...(req.registryType === 'github' && {
|
|
151
|
+
githubRelease: {
|
|
152
|
+
repository: req.registry?.githubRelease?.repository,
|
|
153
|
+
assetsName: req.registry?.githubRelease?.assetsName,
|
|
154
|
+
assetName: req.registry?.githubRelease?.assetName
|
|
155
|
+
}
|
|
156
|
+
}),
|
|
157
|
+
...(req.registryType === 'artifacts' && {
|
|
158
|
+
artifacts: {
|
|
159
|
+
registryUrl: req.registry?.artifacts?.registryUrl,
|
|
160
|
+
assetName: req.registry?.artifacts?.assetName
|
|
161
|
+
}
|
|
162
|
+
}),
|
|
163
|
+
...(req.registryType === 'local' && {
|
|
164
|
+
local: {
|
|
165
|
+
localPath: req.registry?.local?.localPath,
|
|
166
|
+
assetName: req.registry?.local?.assetName
|
|
167
|
+
}
|
|
168
|
+
})
|
|
169
|
+
}
|
|
170
|
+
})
|
|
171
|
+
}))
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
if (server.installation) {
|
|
175
|
+
cleanServer.installation = {
|
|
176
|
+
command: server.installation.command,
|
|
177
|
+
args: server.installation.args || undefined,
|
|
178
|
+
env: (server.installation.env || [])
|
|
179
|
+
.filter(Boolean)
|
|
180
|
+
.map(env => ({
|
|
181
|
+
name: env.name,
|
|
182
|
+
default: env.default || undefined,
|
|
183
|
+
required: env.required || false,
|
|
184
|
+
description: env.description || undefined
|
|
185
|
+
}))
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return cleanServer;
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// Collect all requirements from servers
|
|
193
|
+
const allRequirements = new Map();
|
|
194
|
+
|
|
195
|
+
cleanServers.forEach(server => {
|
|
196
|
+
server.requirements?.forEach(req => {
|
|
197
|
+
const key = `${req.type}:${req.name}`;
|
|
198
|
+
if (!allRequirements.has(key)) {
|
|
199
|
+
allRequirements.set(key, req);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
return {
|
|
205
|
+
name: categoryData.name,
|
|
206
|
+
displayName: categoryData.displayName,
|
|
207
|
+
description: categoryData.description,
|
|
208
|
+
repository: categoryData.repository,
|
|
209
|
+
requirements: Array.from(allRequirements.values()),
|
|
210
|
+
servers: cleanServers
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function populateForm(data) {
|
|
215
|
+
const { requirements = [], servers = [] } = data;
|
|
216
|
+
|
|
217
|
+
// Populate requirements
|
|
218
|
+
requirements.forEach((requirement, index) => {
|
|
219
|
+
window.addRequirement();
|
|
220
|
+
|
|
221
|
+
// Set basic fields
|
|
222
|
+
document.querySelector(`[name="requirements[${index}].name"]`).value = requirement.name;
|
|
223
|
+
document.querySelector(`[name="requirements[${index}].type"]`).value = requirement.type;
|
|
224
|
+
document.querySelector(`[name="requirements[${index}].version"]`).value = requirement.version;
|
|
225
|
+
|
|
226
|
+
if (requirement.order) {
|
|
227
|
+
document.querySelector(`[name="requirements[${index}].order"]`).value = requirement.order;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (requirement.type === 'command' && requirement.alias) {
|
|
231
|
+
document.querySelector(`[name="requirements[${index}].alias"]`).value = requirement.alias;
|
|
232
|
+
document.getElementById(`alias-field-${index}`).classList.remove('hidden');
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Handle registry configuration
|
|
236
|
+
if (requirement.registry) {
|
|
237
|
+
let registryType;
|
|
238
|
+
if (requirement.registry.githubRelease) registryType = 'github';
|
|
239
|
+
else if (requirement.registry.artifacts) registryType = 'artifacts';
|
|
240
|
+
else if (requirement.registry.local) registryType = 'local';
|
|
241
|
+
|
|
242
|
+
if (registryType) {
|
|
243
|
+
const registrySelect = document.querySelector(`[name="requirements[${index}].registryType"]`);
|
|
244
|
+
registrySelect.value = registryType;
|
|
245
|
+
window.toggleRegistryConfig(index);
|
|
246
|
+
|
|
247
|
+
// Populate registry-specific fields
|
|
248
|
+
if (registryType === 'github') {
|
|
249
|
+
const { repository, assetsName, assetName } = requirement.registry.githubRelease;
|
|
250
|
+
if (repository) document.querySelector(`[name="requirements[${index}].registry.githubRelease.repository"]`).value = repository;
|
|
251
|
+
if (assetsName) document.querySelector(`[name="requirements[${index}].registry.githubRelease.assetsName"]`).value = assetsName;
|
|
252
|
+
if (assetName) document.querySelector(`[name="requirements[${index}].registry.githubRelease.assetName"]`).value = assetName;
|
|
253
|
+
} else if (registryType === 'artifacts') {
|
|
254
|
+
const { registryUrl, assetName } = requirement.registry.artifacts;
|
|
255
|
+
if (registryUrl) document.querySelector(`[name="requirements[${index}].registry.artifacts.registryUrl"]`).value = registryUrl;
|
|
256
|
+
if (assetName) document.querySelector(`[name="requirements[${index}].registry.artifacts.assetName"]`).value = assetName;
|
|
257
|
+
} else if (registryType === 'local') {
|
|
258
|
+
const { localPath, assetName } = requirement.registry.local;
|
|
259
|
+
if (localPath) document.querySelector(`[name="requirements[${index}].registry.local.localPath"]`).value = localPath;
|
|
260
|
+
if (assetName) document.querySelector(`[name="requirements[${index}].registry.local.assetName"]`).value = assetName;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
// Populate servers
|
|
267
|
+
servers.forEach((server, serverIndex) => {
|
|
268
|
+
window.addServer();
|
|
269
|
+
|
|
270
|
+
// Set basic fields
|
|
271
|
+
document.querySelector(`[name="servers[${serverIndex}].name"]`).value = server.name;
|
|
272
|
+
document.querySelector(`[name="servers[${serverIndex}].mode"]`).value = server.mode;
|
|
273
|
+
document.querySelector(`[name="servers[${serverIndex}].description"]`).value = server.description;
|
|
274
|
+
|
|
275
|
+
if (server.schemas) {
|
|
276
|
+
document.getElementById(`schema-path-${serverIndex}`).value = server.schemas;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Set installation configuration
|
|
280
|
+
if (server.installation) {
|
|
281
|
+
document.querySelector(`[name="servers[${serverIndex}].installation.command"]`).value = server.installation.command;
|
|
282
|
+
if (server.installation.args) {
|
|
283
|
+
document.querySelector(`[name="servers[${serverIndex}].installation.args"]`).value = server.installation.args;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Add environment variables
|
|
287
|
+
server.installation.env?.forEach((env, envIndex) => {
|
|
288
|
+
window.addEnvVariable(serverIndex);
|
|
289
|
+
document.querySelector(`[name="servers[${serverIndex}].installation.env[${envIndex}].name"]`).value = env.name;
|
|
290
|
+
if (env.default) document.querySelector(`[name="servers[${serverIndex}].installation.env[${envIndex}].default"]`).value = env.default;
|
|
291
|
+
if (env.required) document.querySelector(`[name="servers[${serverIndex}].installation.env[${envIndex}].required"]`).checked = true;
|
|
292
|
+
if (env.description) document.querySelector(`[name="servers[${serverIndex}].installation.env[${envIndex}].description"]`).value = env.description;
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Add requirements from dependencies
|
|
297
|
+
server.dependencies?.requirements?.forEach((req, reqIndex) => {
|
|
298
|
+
window.addServerRequirement(serverIndex);
|
|
299
|
+
|
|
300
|
+
// Set basic fields
|
|
301
|
+
document.querySelector(`[name="servers[${serverIndex}].requirements[${reqIndex}].name"]`).value = req.name;
|
|
302
|
+
document.querySelector(`[name="servers[${serverIndex}].requirements[${reqIndex}].version"]`).value = req.version;
|
|
303
|
+
|
|
304
|
+
if (req.order) {
|
|
305
|
+
document.querySelector(`[name="servers[${serverIndex}].requirements[${reqIndex}].order"]`).value = req.order;
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addRequirement,
|
|
3
|
+
removeRequirement,
|
|
4
|
+
addServer,
|
|
5
|
+
removeServer,
|
|
6
|
+
addEnvVariable,
|
|
7
|
+
removeEnvVariable,
|
|
8
|
+
addServerRequirement,
|
|
9
|
+
removeServerRequirement,
|
|
10
|
+
toggleAliasField,
|
|
11
|
+
toggleServerAliasField,
|
|
12
|
+
toggleRegistryConfig,
|
|
13
|
+
toggleServerRegistryConfig,
|
|
14
|
+
browseLocalSchema
|
|
15
|
+
} from './uiHandlers.js';
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
submitForm,
|
|
19
|
+
formDataToJson,
|
|
20
|
+
populateForm
|
|
21
|
+
} from './formProcessor.js';
|
|
22
|
+
|
|
23
|
+
// Load existing category data if editing
|
|
24
|
+
async function loadExistingCategory() {
|
|
25
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
26
|
+
const categoryName = urlParams.get('category');
|
|
27
|
+
|
|
28
|
+
if (categoryName) {
|
|
29
|
+
try {
|
|
30
|
+
const response = await fetch(`/api/categories/${categoryName}`);
|
|
31
|
+
if (!response.ok) {
|
|
32
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const result = await response.json();
|
|
36
|
+
if (result.success && result.data) {
|
|
37
|
+
const { feedConfiguration } = result.data;
|
|
38
|
+
populateForm({
|
|
39
|
+
name: feedConfiguration.name,
|
|
40
|
+
displayName: feedConfiguration.displayName,
|
|
41
|
+
description: feedConfiguration.description,
|
|
42
|
+
repository: feedConfiguration.repository,
|
|
43
|
+
requirements: feedConfiguration.requirements || [],
|
|
44
|
+
servers: feedConfiguration.mcpServers || []
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.error('Error loading category:', error);
|
|
49
|
+
alert('Error loading category data. Please try again.');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Initialize event listeners
|
|
55
|
+
document.addEventListener('DOMContentLoaded', async () => {
|
|
56
|
+
// Load existing category data if in edit mode
|
|
57
|
+
await loadExistingCategory();
|
|
58
|
+
|
|
59
|
+
// Add form submit handlers
|
|
60
|
+
const categoryForm = document.getElementById('onboardForm');
|
|
61
|
+
if (categoryForm) {
|
|
62
|
+
categoryForm.addEventListener('submit', submitForm);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const serverForm = document.getElementById('onboardServerForm');
|
|
66
|
+
if (serverForm) {
|
|
67
|
+
serverForm.addEventListener('submit', submitForm);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Setup tab switching functionality
|
|
71
|
+
const tabCreateCategory = document.getElementById('tab-create-category');
|
|
72
|
+
const tabCreateServer = document.getElementById('tab-create-server');
|
|
73
|
+
const panelCreateCategory = document.getElementById('panel-create-category');
|
|
74
|
+
const panelCreateServer = document.getElementById('panel-create-server');
|
|
75
|
+
|
|
76
|
+
if (tabCreateCategory && tabCreateServer) {
|
|
77
|
+
tabCreateCategory.addEventListener('click', () => {
|
|
78
|
+
// Update tab styles
|
|
79
|
+
tabCreateCategory.classList.add('text-blue-600', 'border-blue-600');
|
|
80
|
+
tabCreateCategory.classList.remove('text-gray-600', 'border-transparent');
|
|
81
|
+
tabCreateServer.classList.remove('text-blue-600', 'border-blue-600');
|
|
82
|
+
tabCreateServer.classList.add('text-gray-600', 'border-transparent');
|
|
83
|
+
|
|
84
|
+
// Show/hide panels
|
|
85
|
+
panelCreateCategory.classList.remove('hidden');
|
|
86
|
+
panelCreateServer.classList.add('hidden');
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
tabCreateServer.addEventListener('click', () => {
|
|
90
|
+
// Update tab styles
|
|
91
|
+
tabCreateServer.classList.add('text-blue-600', 'border-blue-600');
|
|
92
|
+
tabCreateServer.classList.remove('text-gray-600', 'border-transparent');
|
|
93
|
+
tabCreateCategory.classList.remove('text-blue-600', 'border-blue-600');
|
|
94
|
+
tabCreateCategory.classList.add('text-gray-600', 'border-transparent');
|
|
95
|
+
|
|
96
|
+
// Show/hide panels
|
|
97
|
+
panelCreateServer.classList.remove('hidden');
|
|
98
|
+
panelCreateCategory.classList.add('hidden');
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Initialize button handlers
|
|
103
|
+
const addRequirementBtn = document.getElementById('addRequirementBtn');
|
|
104
|
+
if (addRequirementBtn) {
|
|
105
|
+
addRequirementBtn.addEventListener('click', addRequirement);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const addServerBtn = document.getElementById('addServerBtn');
|
|
109
|
+
if (addServerBtn) {
|
|
110
|
+
addServerBtn.addEventListener('click', addServer);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Expose necessary functions to window for HTML event handlers
|
|
114
|
+
Object.assign(window, {
|
|
115
|
+
addRequirement,
|
|
116
|
+
removeRequirement,
|
|
117
|
+
addServer,
|
|
118
|
+
removeServer,
|
|
119
|
+
addEnvVariable,
|
|
120
|
+
removeEnvVariable,
|
|
121
|
+
addServerRequirement,
|
|
122
|
+
removeServerRequirement,
|
|
123
|
+
toggleAliasField,
|
|
124
|
+
toggleServerAliasField,
|
|
125
|
+
toggleRegistryConfig,
|
|
126
|
+
toggleServerRegistryConfig,
|
|
127
|
+
browseLocalSchema,
|
|
128
|
+
formDataToJson,
|
|
129
|
+
populateForm
|
|
130
|
+
});
|
|
131
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Global state management
|
|
2
|
+
export const state = {
|
|
3
|
+
requirementCounter: 0,
|
|
4
|
+
serverCounter: 0,
|
|
5
|
+
envCounters: new Map(),
|
|
6
|
+
serverRequirementCounters: new Map()
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const incrementRequirementCounter = () => state.requirementCounter++;
|
|
10
|
+
export const incrementServerCounter = () => state.serverCounter++;
|
|
11
|
+
|
|
12
|
+
export const setEnvCounter = (serverIndex, value) => {
|
|
13
|
+
state.envCounters.set(serverIndex, value);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const getEnvCounter = (serverIndex) => state.envCounters.get(serverIndex) || 0;
|
|
17
|
+
|
|
18
|
+
export const deleteEnvCounter = (serverIndex) => {
|
|
19
|
+
state.envCounters.delete(serverIndex);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const setServerRequirementCounter = (serverIndex, value) => {
|
|
23
|
+
state.serverRequirementCounters.set(serverIndex, value);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const getServerRequirementCounter = (serverIndex) => {
|
|
27
|
+
return state.serverRequirementCounters.get(serverIndex) || 0;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const deleteServerRequirementCounter = (serverIndex) => {
|
|
31
|
+
state.serverRequirementCounters.delete(serverIndex);
|
|
32
|
+
};
|