flowpilot 0.0.2 → 0.0.3

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.
@@ -0,0 +1,1965 @@
1
+ import { a as useRef, c as Fragment, i as useReducer, n as instance, r as useEffect, s as render, t as jsxDEV } from "./jsx-dev-runtime-DOO7Tqjo.js";
2
+ import { t as filterByRelevance } from "./search-cPm8k8mK.js";
3
+ //#region src/commands/release/client.tsx
4
+ const initPromise = typeof window !== "undefined" && window.__I18N_LOCALE__ && window.__I18N_RESOURCES__ ? instance.init({
5
+ lng: window.__I18N_LOCALE__,
6
+ fallbackLng: "zh-CN",
7
+ resources: window.__I18N_RESOURCES__,
8
+ interpolation: { escapeValue: false }
9
+ }) : Promise.resolve();
10
+ const t = instance.t;
11
+ const releaseStyle = `
12
+ .page-header {
13
+ margin-bottom: 28px;
14
+ animation: slide-up 0.3s cubic-bezier(0.16, 1, 0.3, 1) 0.05s both;
15
+ }
16
+ .page-header h2 {
17
+ font-size: 22px;
18
+ font-weight: 600;
19
+ letter-spacing: -0.02em;
20
+ margin-bottom: 6px;
21
+ }
22
+ .page-header p {
23
+ font-size: 13px;
24
+ color: var(--text-2);
25
+ font-weight: 300;
26
+ line-height: 1.5;
27
+ }
28
+
29
+ /* ── Pipeline ── */
30
+ .pipeline {
31
+ display: flex;
32
+ align-items: center;
33
+ gap: 0;
34
+ margin-bottom: 28px;
35
+ animation: slide-up 0.3s cubic-bezier(0.16, 1, 0.3, 1) 0.08s both;
36
+ }
37
+ .pipeline-step {
38
+ display: flex;
39
+ align-items: center;
40
+ gap: 6px;
41
+ font-size: 11px;
42
+ font-family: var(--mono);
43
+ color: var(--text-3);
44
+ font-weight: 400;
45
+ white-space: nowrap;
46
+ }
47
+ .pipeline-step.active {
48
+ color: var(--neon);
49
+ font-weight: 500;
50
+ }
51
+ .pipeline-step.done {
52
+ color: var(--cyan);
53
+ }
54
+ .pipeline-node {
55
+ width: 8px; height: 8px;
56
+ border-radius: 50%;
57
+ background: var(--text-3);
58
+ transition: background 0.3s, box-shadow 0.3s;
59
+ }
60
+ .pipeline-step.active .pipeline-node {
61
+ background: var(--neon);
62
+ box-shadow: 0 0 8px var(--neon-glow);
63
+ animation: neon-pulse 2s ease infinite;
64
+ }
65
+ .pipeline-step.done .pipeline-node {
66
+ background: var(--cyan);
67
+ box-shadow: 0 0 4px var(--cyan-glow);
68
+ }
69
+ .pipeline-line {
70
+ width: 32px;
71
+ height: 1px;
72
+ background: var(--border);
73
+ margin: 0 4px;
74
+ transition: background 0.3s;
75
+ }
76
+ .pipeline-line.done { background: var(--cyan); }
77
+
78
+ /* ── Generic select ── */
79
+ .sel {
80
+ position: relative;
81
+ margin-bottom: 16px;
82
+ animation: slide-up 0.3s cubic-bezier(0.16, 1, 0.3, 1) 0.12s both;
83
+ z-index: 1;
84
+ }
85
+ .sel-trigger {
86
+ width: 100%;
87
+ display: flex;
88
+ align-items: center;
89
+ gap: 8px;
90
+ padding: 12px 14px;
91
+ font-size: 13px;
92
+ font-family: var(--sans);
93
+ color: var(--text-1, #E2E8F0);
94
+ background: var(--bg-input, #0A0E14);
95
+ border: 1px solid var(--border);
96
+ border-radius: 8px;
97
+ cursor: pointer;
98
+ outline: none;
99
+ transition: border-color 0.2s, box-shadow 0.2s;
100
+ text-align: left;
101
+ }
102
+ .sel-trigger:hover { border-color: var(--border-active); }
103
+ .sel-trigger:focus,
104
+ .sel-trigger.open {
105
+ border-color: var(--neon);
106
+ box-shadow: 0 0 0 2px var(--neon-soft), 0 0 8px var(--neon-glow);
107
+ }
108
+ .sel-trigger-label {
109
+ font-size: 11px;
110
+ color: var(--text-3, #64748B);
111
+ flex-shrink: 0;
112
+ }
113
+ .sel-trigger-value {
114
+ flex: 1;
115
+ font-family: var(--mono);
116
+ font-size: 13px;
117
+ font-weight: 500;
118
+ color: var(--text-1, #E2E8F0);
119
+ }
120
+ .sel-trigger-value.empty {
121
+ color: var(--text-3);
122
+ font-weight: 300;
123
+ }
124
+ .sel-trigger-arrow {
125
+ color: var(--text-3, #64748B);
126
+ font-size: 10px;
127
+ transition: transform 0.2s;
128
+ }
129
+ .sel-trigger.open .sel-trigger-arrow {
130
+ transform: rotate(180deg);
131
+ }
132
+ .sel-dropdown {
133
+ position: absolute;
134
+ top: calc(100% + 6px);
135
+ left: 0; right: 0;
136
+ max-height: 280px;
137
+ overflow-y: auto;
138
+ background: var(--bg-card, #111820);
139
+ border: 1px solid rgba(0,255,136,0.08);
140
+ border-radius: 8px;
141
+ box-shadow: 0 8px 32px rgba(0,0,0,0.6), 0 0 12px rgba(0,255,136,0.03);
142
+ z-index: 1000;
143
+ animation: dropdown-in 0.12s ease both;
144
+ }
145
+ .sel-dropdown::-webkit-scrollbar { width: 6px; }
146
+ .sel-dropdown::-webkit-scrollbar-track { background: transparent; }
147
+ .sel-dropdown::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
148
+ .sel-search {
149
+ padding: 8px;
150
+ border-bottom: 1px solid var(--border);
151
+ position: sticky;
152
+ top: 0;
153
+ background: var(--bg-card, #111820);
154
+ z-index: 1;
155
+ }
156
+ .sel-search-input {
157
+ width: 100%;
158
+ padding: 6px 10px;
159
+ font-size: 12px;
160
+ font-family: var(--mono);
161
+ color: var(--text-1, #E2E8F0);
162
+ background: var(--bg-void, #0A0A0F);
163
+ border: 1px solid var(--border);
164
+ border-radius: 4px;
165
+ outline: none;
166
+ transition: border-color 0.15s;
167
+ }
168
+ .sel-search-input::placeholder { color: var(--text-3); }
169
+ .sel-search-input:focus { border-color: var(--neon); }
170
+ .sel-item {
171
+ padding: 10px 14px;
172
+ font-size: 13px;
173
+ cursor: pointer;
174
+ transition: background 0.1s;
175
+ border-left: 3px solid transparent;
176
+ color: var(--text-1, #E2E8F0);
177
+ }
178
+ .sel-item:first-child { border-radius: 7px 7px 0 0; }
179
+ .sel-item:last-child { border-radius: 0 0 7px 7px; }
180
+ .sel-item:hover,
181
+ .sel-item.highlighted { background: var(--bg-hover, rgba(0,255,136,0.04)); }
182
+ .sel-item.active {
183
+ background: var(--neon-soft, rgba(0,255,136,0.08));
184
+ border-left-color: var(--neon);
185
+ font-weight: 500;
186
+ }
187
+ .sel-item-name { font-weight: 500; color: var(--text-1, #E2E8F0); }
188
+ .sel-item-sub { font-size: 11px; color: var(--text-3, #64748B); font-family: var(--mono); margin-top: 2px; }
189
+ .sel-empty { padding: 12px; text-align: center; color: var(--text-3, #64748B); font-size: 12px; }
190
+
191
+ /* ── Spinner ── */
192
+ .spinner {
193
+ display: inline-block;
194
+ width: 14px; height: 14px;
195
+ border: 2px solid var(--border);
196
+ border-top-color: var(--neon);
197
+ border-radius: 50%;
198
+ animation: spin 0.6s linear infinite;
199
+ }
200
+ @keyframes spin { to { transform: rotate(360deg); } }
201
+ .loading-row {
202
+ display: flex;
203
+ align-items: center;
204
+ gap: 8px;
205
+ padding: 10px 14px;
206
+ color: var(--text-3);
207
+ font-size: 13px;
208
+ margin-bottom: 16px;
209
+ animation: slide-up 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
210
+ }
211
+
212
+ /* ── Version display ── */
213
+ .version-display {
214
+ display: flex;
215
+ align-items: center;
216
+ gap: 12px;
217
+ padding: 14px 20px;
218
+ background: var(--bg-card);
219
+ border: 1px solid rgba(0,212,255,0.08);
220
+ border-radius: 8px;
221
+ animation: slide-up 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
222
+ }
223
+ .version-tag { font-size: 11px; color: var(--text-3); text-transform: uppercase; letter-spacing: 0.05em; font-family: var(--mono); }
224
+ .version-number { font-size: 20px; font-weight: 600; font-family: var(--mono); color: var(--cyan); letter-spacing: -0.01em; }
225
+ .version-error { color: var(--error); font-size: 13px; animation: slide-up 0.3s cubic-bezier(0.16, 1, 0.3, 1) both; }
226
+
227
+ .empty-hint { text-align: center; padding: 32px 0; color: var(--text-3); font-size: 13px; animation: slide-up 0.3s cubic-bezier(0.16, 1, 0.3, 1) 0.15s both; }
228
+ .state-error { color: var(--error); font-size: 13px; animation: slide-up 0.3s cubic-bezier(0.16, 1, 0.3, 1) both; }
229
+
230
+ /* ── Jira ── */
231
+ .jira-section { margin-top: 20px; animation: slide-up 0.3s cubic-bezier(0.16, 1, 0.3, 1) both; }
232
+ .jira-btn {
233
+ width: 100%;
234
+ min-height: 44px;
235
+ padding: 10px 20px;
236
+ font-size: 13px;
237
+ font-family: var(--sans);
238
+ font-weight: 500;
239
+ color: var(--bg-void);
240
+ background: var(--neon);
241
+ border: none;
242
+ border-radius: 8px;
243
+ cursor: pointer;
244
+ transition: background 0.15s, box-shadow 0.2s;
245
+ margin-top: 16px;
246
+ position: relative;
247
+ z-index: 1;
248
+ }
249
+ .jira-btn:hover { background: var(--neon-hover); box-shadow: 0 0 12px var(--neon-glow), 0 2px 12px rgba(0,255,136,0.2); }
250
+ .jira-btn:disabled { opacity: 0.5; cursor: not-allowed; }
251
+
252
+ /* ── Custom Checkbox ── */
253
+ input[type="checkbox"] {
254
+ appearance: none;
255
+ width: 16px;
256
+ height: 16px;
257
+ border: 1px solid var(--border, rgba(0,255,136,0.2));
258
+ border-radius: 3px;
259
+ background: var(--bg-input, #0A0E14);
260
+ cursor: pointer;
261
+ position: relative;
262
+ transition: border-color 0.15s, background 0.15s;
263
+ }
264
+ input[type="checkbox"]:checked {
265
+ background: var(--neon, #00ff88);
266
+ border-color: var(--neon, #00ff88);
267
+ }
268
+ input[type="checkbox"]:checked::after {
269
+ content: "✓";
270
+ position: absolute;
271
+ top: -1px;
272
+ left: 2px;
273
+ font-size: 12px;
274
+ font-weight: 700;
275
+ color: var(--bg-void, #0A0A0F);
276
+ }
277
+ input[type="checkbox"]:focus-visible {
278
+ outline: 2px solid var(--neon-soft, rgba(0,255,136,0.2));
279
+ outline-offset: 2px;
280
+ }
281
+ .jira-result {
282
+ margin-top: 12px;
283
+ padding: 12px 16px;
284
+ background: var(--bg-card);
285
+ border: 1px solid var(--border);
286
+ border-radius: 8px;
287
+ animation: slide-up 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
288
+ position: relative;
289
+ z-index: 1;
290
+ }
291
+ .jira-result-key {
292
+ font-family: var(--mono);
293
+ font-size: 14px;
294
+ font-weight: 600;
295
+ color: var(--neon);
296
+ text-decoration: none;
297
+ border-bottom: 1px dashed rgba(0,255,136,0.3);
298
+ transition: border-color 0.2s;
299
+ }
300
+ .jira-result-key:hover { border-bottom-color: var(--neon); }
301
+ .jira-result-label { font-size: 11px; color: var(--text-3); margin-bottom: 4px; }
302
+ .jira-result-badge { display: inline-block; font-size: 10px; padding: 2px 8px; border-radius: 4px; margin-left: 8px; font-weight: 500; }
303
+ .jira-result-badge.created { background: var(--neon-soft); color: var(--neon); }
304
+ .jira-result-badge.exists { background: var(--cyan-soft); color: var(--cyan); }
305
+ .jira-error { margin-top: 12px; color: var(--error); font-size: 13px; animation: slide-up 0.3s cubic-bezier(0.16, 1, 0.3, 1) both; }
306
+
307
+ /* ── History ── */
308
+ .history-section {
309
+ margin-bottom: 24px;
310
+ animation: slide-up 0.3s cubic-bezier(0.16, 1, 0.3, 1) 0.06s both;
311
+ }
312
+ .history-title {
313
+ font-size: 16px;
314
+ font-weight: 600;
315
+ margin-bottom: 12px;
316
+ color: var(--text-1);
317
+ }
318
+ .history-list {
319
+ display: flex;
320
+ flex-direction: column;
321
+ gap: 8px;
322
+ }
323
+ .history-item {
324
+ display: flex;
325
+ flex-direction: column;
326
+ padding: 12px 16px;
327
+ background: var(--bg-card);
328
+ border: 1px solid var(--border);
329
+ border-radius: 8px;
330
+ transition: border-color 0.15s, box-shadow 0.15s;
331
+ animation: slide-up 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
332
+ }
333
+ .history-item-row {
334
+ display: flex;
335
+ align-items: center;
336
+ justify-content: space-between;
337
+ }
338
+ .history-item:hover {
339
+ border-color: var(--border-active);
340
+ box-shadow: 0 2px 8px rgba(0,0,0,0.3);
341
+ }
342
+ .history-info {
343
+ display: flex;
344
+ align-items: center;
345
+ gap: 12px;
346
+ flex: 1;
347
+ }
348
+ .history-project { font-weight: 500; color: var(--text-1); font-size: 14px; }
349
+ .history-detail { font-size: 12px; color: var(--text-3); font-family: var(--mono); }
350
+ .history-actions { display: flex; align-items: center; gap: 8px; }
351
+ .history-quick-btn {
352
+ padding: 6px 14px;
353
+ font-size: 12px;
354
+ font-family: var(--sans);
355
+ font-weight: 500;
356
+ color: var(--bg-void);
357
+ background: var(--neon);
358
+ border: none;
359
+ border-radius: 6px;
360
+ cursor: pointer;
361
+ transition: background 0.15s;
362
+ }
363
+ .history-quick-btn:hover { background: var(--neon-hover); }
364
+ .history-quick-btn:disabled { opacity: 0.5; cursor: not-allowed; }
365
+ .history-quick-btn.executing {
366
+ background: var(--border);
367
+ color: var(--text-3);
368
+ }
369
+ .history-footer {
370
+ display: flex;
371
+ align-items: center;
372
+ justify-content: space-between;
373
+ margin-top: 16px;
374
+ padding-top: 16px;
375
+ border-top: 1px solid var(--border);
376
+ }
377
+ .history-new-btn {
378
+ padding: 8px 16px;
379
+ font-size: 13px;
380
+ font-family: var(--sans);
381
+ font-weight: 500;
382
+ color: var(--bg-void);
383
+ background: var(--neon);
384
+ border: none;
385
+ border-radius: 8px;
386
+ cursor: pointer;
387
+ transition: background 0.15s, box-shadow 0.2s;
388
+ }
389
+ .history-new-btn:hover { background: var(--neon-hover); box-shadow: 0 0 12px var(--neon-glow); }
390
+ .history-clear-btn {
391
+ padding: 8px 16px;
392
+ font-size: 13px;
393
+ font-family: var(--sans);
394
+ font-weight: 400;
395
+ color: var(--text-3);
396
+ background: transparent;
397
+ border: 1px solid var(--border);
398
+ border-radius: 8px;
399
+ cursor: pointer;
400
+ transition: border-color 0.15s, color 0.15s;
401
+ }
402
+ .history-clear-btn:hover { border-color: var(--error); color: var(--error); }
403
+ .history-result {
404
+ margin-top: 12px;
405
+ padding: 10px 14px;
406
+ background: var(--bg-void);
407
+ border: 1px solid rgba(0,255,136,0.08);
408
+ border-radius: 8px;
409
+ animation: slide-up 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
410
+ }
411
+ .history-result-key {
412
+ font-family: var(--mono);
413
+ font-size: 14px;
414
+ font-weight: 600;
415
+ color: var(--neon);
416
+ text-decoration: none;
417
+ }
418
+ .history-result-error {
419
+ color: var(--error);
420
+ font-size: 13px;
421
+ }
422
+
423
+ /* ── Modal ── */
424
+ .modal-overlay {
425
+ position: fixed;
426
+ top: 0; left: 0; right: 0; bottom: 0;
427
+ background: rgba(0,0,0,0.7);
428
+ display: flex;
429
+ align-items: center;
430
+ justify-content: center;
431
+ z-index: 2000;
432
+ animation: fade-in 0.2s ease both;
433
+ }
434
+ .modal-content {
435
+ width: 90%;
436
+ max-width: 560px;
437
+ background: var(--bg-void);
438
+ border: 1px solid var(--border);
439
+ border-radius: 12px;
440
+ padding: 24px;
441
+ animation: slide-up 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
442
+ }
443
+ .modal-header {
444
+ display: flex;
445
+ align-items: center;
446
+ justify-content: space-between;
447
+ margin-bottom: 20px;
448
+ }
449
+ .modal-title { font-size: 18px; font-weight: 600; color: var(--text-1); }
450
+ .modal-close {
451
+ width: 32px; height: 32px;
452
+ display: flex;
453
+ align-items: center;
454
+ justify-content: center;
455
+ font-size: 16px;
456
+ color: var(--text-3);
457
+ background: transparent;
458
+ border: 1px solid var(--border);
459
+ border-radius: 6px;
460
+ cursor: pointer;
461
+ transition: border-color 0.15s, color 0.15s;
462
+ }
463
+ .modal-close:hover { border-color: var(--text-2); color: var(--text-2); }
464
+ `;
465
+ const initial = {
466
+ jiraHost: "",
467
+ projects: [],
468
+ projectsLoading: true,
469
+ projectsError: "",
470
+ projectOpen: false,
471
+ projectSearch: "",
472
+ projectIndex: -1,
473
+ selected: null,
474
+ branches: [],
475
+ branchesLoading: false,
476
+ branchOpen: false,
477
+ branchSearch: "",
478
+ branchIndex: -1,
479
+ selectedBranch: "",
480
+ pomInfo: null,
481
+ pomLoading: false,
482
+ pomError: "",
483
+ jiraProjects: [],
484
+ jiraProjectsLoading: false,
485
+ jiraProjectOpen: false,
486
+ jiraProjectSearch: "",
487
+ jiraProjectIndex: -1,
488
+ selectedJiraProject: null,
489
+ jiraStatus: "idle",
490
+ jiraResult: null,
491
+ jiraError: "",
492
+ mrStatus: "idle",
493
+ mrUrl: "",
494
+ mrError: "",
495
+ mrBranches: [],
496
+ mrSourceBranch: "",
497
+ mrTargetBranch: "",
498
+ mrBranchOpen: false,
499
+ mrBranchSearch: "",
500
+ mrBranchIndex: -1,
501
+ history: [],
502
+ historyLoading: true,
503
+ quickExecuting: null,
504
+ quickResults: {},
505
+ quickErrors: {},
506
+ showNewModal: false,
507
+ clearConfirm: false,
508
+ createMrChecked: {}
509
+ };
510
+ const reducer = (state, action) => {
511
+ switch (action.type) {
512
+ case "SET_JIRA_HOST": return {
513
+ ...state,
514
+ jiraHost: action.host
515
+ };
516
+ case "PROJECTS_LOADED": return {
517
+ ...state,
518
+ projects: action.projects,
519
+ projectsLoading: false
520
+ };
521
+ case "PROJECTS_ERROR": return {
522
+ ...state,
523
+ projectsError: action.error,
524
+ projectsLoading: false
525
+ };
526
+ case "SET_PROJECT_OPEN": return {
527
+ ...state,
528
+ projectOpen: action.open,
529
+ ...action.open ? {} : {
530
+ projectSearch: "",
531
+ projectIndex: -1
532
+ }
533
+ };
534
+ case "SET_PROJECT_SEARCH": return {
535
+ ...state,
536
+ projectSearch: action.search,
537
+ projectIndex: -1
538
+ };
539
+ case "SET_PROJECT_INDEX": return {
540
+ ...state,
541
+ projectIndex: action.index
542
+ };
543
+ case "SELECT_PROJECT": return {
544
+ ...state,
545
+ selected: action.project,
546
+ projectOpen: false,
547
+ projectSearch: "",
548
+ projectIndex: -1,
549
+ branches: [],
550
+ branchesLoading: false,
551
+ selectedBranch: "",
552
+ branchOpen: false,
553
+ branchSearch: "",
554
+ branchIndex: -1,
555
+ pomInfo: null,
556
+ pomError: "",
557
+ selectedJiraProject: null,
558
+ jiraStatus: "idle",
559
+ jiraResult: null,
560
+ jiraError: "",
561
+ mrStatus: "idle",
562
+ mrUrl: "",
563
+ mrError: "",
564
+ mrBranches: [],
565
+ mrSourceBranch: "",
566
+ mrTargetBranch: "",
567
+ mrBranchOpen: false,
568
+ mrBranchSearch: "",
569
+ mrBranchIndex: -1
570
+ };
571
+ case "CLEAR_PROJECT": return {
572
+ ...state,
573
+ selected: null,
574
+ branches: [],
575
+ selectedBranch: "",
576
+ branchOpen: false,
577
+ branchSearch: "",
578
+ branchIndex: -1,
579
+ pomInfo: null,
580
+ pomError: "",
581
+ pomLoading: false,
582
+ selectedJiraProject: null,
583
+ jiraStatus: "idle",
584
+ jiraResult: null,
585
+ jiraError: "",
586
+ mrStatus: "idle",
587
+ mrUrl: "",
588
+ mrError: "",
589
+ mrBranches: [],
590
+ mrSourceBranch: "",
591
+ mrTargetBranch: "",
592
+ mrBranchOpen: false,
593
+ mrBranchSearch: "",
594
+ mrBranchIndex: -1
595
+ };
596
+ case "BRANCHES_LOADING": return {
597
+ ...state,
598
+ branchesLoading: true,
599
+ branches: [],
600
+ selectedBranch: ""
601
+ };
602
+ case "BRANCHES_LOADED": return {
603
+ ...state,
604
+ branches: action.branches,
605
+ branchesLoading: false
606
+ };
607
+ case "SET_BRANCH_OPEN": return {
608
+ ...state,
609
+ branchOpen: action.open,
610
+ ...action.open ? {} : {
611
+ branchSearch: "",
612
+ branchIndex: -1
613
+ }
614
+ };
615
+ case "SET_BRANCH_SEARCH": return {
616
+ ...state,
617
+ branchSearch: action.search,
618
+ branchIndex: -1
619
+ };
620
+ case "SET_BRANCH_INDEX": return {
621
+ ...state,
622
+ branchIndex: action.index
623
+ };
624
+ case "SELECT_BRANCH": return {
625
+ ...state,
626
+ selectedBranch: action.branch,
627
+ branchOpen: false,
628
+ branchSearch: "",
629
+ branchIndex: -1
630
+ };
631
+ case "POM_LOADING": return {
632
+ ...state,
633
+ pomLoading: true,
634
+ pomError: "",
635
+ pomInfo: null
636
+ };
637
+ case "POM_LOADED": return {
638
+ ...state,
639
+ pomLoading: false,
640
+ pomInfo: action.info
641
+ };
642
+ case "POM_ERROR": return {
643
+ ...state,
644
+ pomLoading: false,
645
+ pomError: action.error
646
+ };
647
+ case "JIRA_PROJECTS_LOADING": return {
648
+ ...state,
649
+ jiraProjectsLoading: true
650
+ };
651
+ case "JIRA_PROJECTS_LOADED": return {
652
+ ...state,
653
+ jiraProjects: action.projects,
654
+ jiraProjectsLoading: false
655
+ };
656
+ case "JIRA_PROJECTS_ERROR": return {
657
+ ...state,
658
+ jiraProjectsLoading: false
659
+ };
660
+ case "SET_JIRA_PROJECT_OPEN": return {
661
+ ...state,
662
+ jiraProjectOpen: action.open,
663
+ ...action.open ? {} : {
664
+ jiraProjectSearch: "",
665
+ jiraProjectIndex: -1
666
+ }
667
+ };
668
+ case "SET_JIRA_PROJECT_SEARCH": return {
669
+ ...state,
670
+ jiraProjectSearch: action.search,
671
+ jiraProjectIndex: -1
672
+ };
673
+ case "SET_JIRA_PROJECT_INDEX": return {
674
+ ...state,
675
+ jiraProjectIndex: action.index
676
+ };
677
+ case "SELECT_JIRA_PROJECT": return {
678
+ ...state,
679
+ selectedJiraProject: action.project,
680
+ jiraProjectOpen: false,
681
+ jiraProjectSearch: "",
682
+ jiraProjectIndex: -1,
683
+ jiraStatus: "idle",
684
+ jiraResult: null,
685
+ jiraError: ""
686
+ };
687
+ case "CLEAR_JIRA_PROJECT": return {
688
+ ...state,
689
+ selectedJiraProject: null,
690
+ jiraProjectOpen: false,
691
+ jiraProjectSearch: "",
692
+ jiraProjectIndex: -1,
693
+ jiraStatus: "idle",
694
+ jiraResult: null,
695
+ jiraError: ""
696
+ };
697
+ case "JIRA_CHECKING": return {
698
+ ...state,
699
+ jiraStatus: "checking",
700
+ jiraResult: null,
701
+ jiraError: ""
702
+ };
703
+ case "JIRA_CREATING": return {
704
+ ...state,
705
+ jiraStatus: "creating"
706
+ };
707
+ case "JIRA_DONE": return {
708
+ ...state,
709
+ jiraStatus: "done",
710
+ jiraResult: action.result
711
+ };
712
+ case "JIRA_ERROR": return {
713
+ ...state,
714
+ jiraStatus: "error",
715
+ jiraError: action.error
716
+ };
717
+ case "JIRA_RESET": return {
718
+ ...state,
719
+ jiraStatus: "idle",
720
+ jiraResult: null,
721
+ jiraError: ""
722
+ };
723
+ case "SET_HISTORY": return {
724
+ ...state,
725
+ history: action.history,
726
+ historyLoading: false
727
+ };
728
+ case "QUICK_EXEC_START": return {
729
+ ...state,
730
+ quickExecuting: action.id
731
+ };
732
+ case "QUICK_EXEC_SUCCESS": return {
733
+ ...state,
734
+ quickExecuting: null,
735
+ quickResults: {
736
+ ...state.quickResults,
737
+ [action.id]: action.result
738
+ }
739
+ };
740
+ case "QUICK_EXEC_FAIL": return {
741
+ ...state,
742
+ quickExecuting: null,
743
+ quickErrors: {
744
+ ...state.quickErrors,
745
+ [action.id]: action.error
746
+ }
747
+ };
748
+ case "SHOW_NEW_MODAL": return {
749
+ ...state,
750
+ showNewModal: true
751
+ };
752
+ case "HIDE_NEW_MODAL": return {
753
+ ...state,
754
+ showNewModal: false
755
+ };
756
+ case "CLEAR_CONFIRM_TOGGLE": return {
757
+ ...state,
758
+ clearConfirm: !state.clearConfirm
759
+ };
760
+ case "CLEAR_HISTORY_DONE": return {
761
+ ...state,
762
+ history: [],
763
+ clearConfirm: false,
764
+ quickResults: {},
765
+ quickErrors: {}
766
+ };
767
+ case "TOGGLE_CREATE_MR": return {
768
+ ...state,
769
+ createMrChecked: {
770
+ ...state.createMrChecked,
771
+ [action.id]: !state.createMrChecked[action.id]
772
+ }
773
+ };
774
+ case "MR_SELECTING": return {
775
+ ...state,
776
+ mrStatus: "selecting",
777
+ mrBranches: action.branches,
778
+ mrSourceBranch: "",
779
+ mrTargetBranch: "",
780
+ mrError: ""
781
+ };
782
+ case "MR_SOURCE_SELECTED": return {
783
+ ...state,
784
+ mrSourceBranch: action.branch,
785
+ mrBranchOpen: false,
786
+ mrBranchSearch: "",
787
+ mrBranchIndex: -1
788
+ };
789
+ case "SET_MR_BRANCH_OPEN": return {
790
+ ...state,
791
+ mrBranchOpen: action.open,
792
+ ...action.open ? {} : {
793
+ mrBranchSearch: "",
794
+ mrBranchIndex: -1
795
+ }
796
+ };
797
+ case "SET_MR_BRANCH_SEARCH": return {
798
+ ...state,
799
+ mrBranchSearch: action.search,
800
+ mrBranchIndex: -1
801
+ };
802
+ case "SET_MR_BRANCH_INDEX": return {
803
+ ...state,
804
+ mrBranchIndex: action.index
805
+ };
806
+ case "MR_LOADING": return {
807
+ ...state,
808
+ mrStatus: "loading",
809
+ mrBranches: [],
810
+ mrSourceBranch: "",
811
+ mrTargetBranch: "",
812
+ mrError: ""
813
+ };
814
+ case "MR_CREATING": return {
815
+ ...state,
816
+ mrStatus: "creating",
817
+ mrUrl: "",
818
+ mrTargetBranch: "",
819
+ mrError: ""
820
+ };
821
+ case "MR_DONE": return {
822
+ ...state,
823
+ mrStatus: "done",
824
+ mrUrl: action.mrUrl,
825
+ mrSourceBranch: action.mrSourceBranch,
826
+ mrTargetBranch: action.mrTargetBranch,
827
+ history: state.history.map((e) => e.projectId === state.selected?.id && e.branch === state.selectedBranch ? {
828
+ ...e,
829
+ mrUrl: action.mrUrl,
830
+ mrSourceBranch: action.mrSourceBranch,
831
+ mrTargetBranch: action.mrTargetBranch
832
+ } : e)
833
+ };
834
+ case "MR_ERROR": return {
835
+ ...state,
836
+ mrStatus: "error",
837
+ mrError: action.error
838
+ };
839
+ }
840
+ };
841
+ const cleanVersion = (v) => (v ?? "").split("-")[0];
842
+ const selKeyDown = (e, open, len, idx, onSelect, onClose) => {
843
+ if (!open || len === 0) return void 0;
844
+ switch (e.key) {
845
+ case "ArrowDown":
846
+ e.preventDefault();
847
+ return Math.min(idx + 1, len - 1);
848
+ case "ArrowUp":
849
+ e.preventDefault();
850
+ return Math.max(idx - 1, -1);
851
+ case "Enter":
852
+ e.preventDefault();
853
+ if (idx >= 0) onSelect(idx);
854
+ return;
855
+ case "Escape":
856
+ onClose();
857
+ return;
858
+ }
859
+ };
860
+ const pipelineStepClass = (done, active) => done ? "pipeline-step done" : active ? "pipeline-step active" : "pipeline-step";
861
+ const pipelineLineClass = (done) => done ? "pipeline-line done" : "pipeline-line";
862
+ const HistoryList = ({ s, d }) => {
863
+ const handleQuickExecute = async (id) => {
864
+ d({
865
+ type: "QUICK_EXEC_START",
866
+ id
867
+ });
868
+ try {
869
+ const data = await (await fetch(`/release/api/history/${id}/execute`, {
870
+ method: "POST",
871
+ headers: { "Content-Type": "application/json" },
872
+ body: JSON.stringify({ createMr: s.createMrChecked[id] ?? false })
873
+ })).json();
874
+ if (data.error) d({
875
+ type: "QUICK_EXEC_FAIL",
876
+ id,
877
+ error: data.error
878
+ });
879
+ else {
880
+ d({
881
+ type: "QUICK_EXEC_SUCCESS",
882
+ id,
883
+ result: data
884
+ });
885
+ d({
886
+ type: "SET_HISTORY",
887
+ history: await (await fetch("/release/api/history")).json()
888
+ });
889
+ }
890
+ } catch (e) {
891
+ d({
892
+ type: "QUICK_EXEC_FAIL",
893
+ id,
894
+ error: e instanceof Error ? e.message : String(e)
895
+ });
896
+ }
897
+ };
898
+ const handleClearHistory = async () => {
899
+ await fetch("/release/api/history", { method: "DELETE" });
900
+ d({ type: "CLEAR_HISTORY_DONE" });
901
+ };
902
+ return /* @__PURE__ */ jsxDEV("div", {
903
+ class: "history-section",
904
+ children: [
905
+ /* @__PURE__ */ jsxDEV("div", {
906
+ class: "history-title",
907
+ children: t("web.historyTitle")
908
+ }),
909
+ s.history.length > 0 ? /* @__PURE__ */ jsxDEV("div", {
910
+ class: "history-list",
911
+ children: s.history.map((entry) => /* @__PURE__ */ jsxDEV("div", {
912
+ class: "history-item",
913
+ children: [
914
+ /* @__PURE__ */ jsxDEV("div", {
915
+ class: "history-item-row",
916
+ children: [/* @__PURE__ */ jsxDEV("div", {
917
+ class: "history-info",
918
+ children: [
919
+ /* @__PURE__ */ jsxDEV("span", {
920
+ class: "history-project",
921
+ children: entry.projectName
922
+ }),
923
+ /* @__PURE__ */ jsxDEV("span", {
924
+ class: "history-detail",
925
+ children: [
926
+ entry.branch,
927
+ " / ",
928
+ entry.jiraProjectKey
929
+ ]
930
+ }),
931
+ entry.mrUrl && /* @__PURE__ */ jsxDEV("a", {
932
+ href: entry.mrUrl,
933
+ target: "_blank",
934
+ rel: "noreferrer",
935
+ style: "font-size:12px;color:var(--cyan);text-decoration:none;margin-left:6px",
936
+ children: t("release.mrFromTo", {
937
+ source: entry.mrSourceBranch ?? "",
938
+ target: entry.mrTargetBranch ?? entry.branch
939
+ })
940
+ })
941
+ ]
942
+ }), /* @__PURE__ */ jsxDEV("div", {
943
+ class: "history-actions",
944
+ children: [entry.mrUrl && /* @__PURE__ */ jsxDEV("label", {
945
+ style: "display:flex;align-items:center;gap:4px;font-size:12px;color:var(--text-3);cursor:pointer",
946
+ children: [/* @__PURE__ */ jsxDEV("input", {
947
+ type: "checkbox",
948
+ checked: s.createMrChecked[entry.id] ?? false,
949
+ onChange: () => d({
950
+ type: "TOGGLE_CREATE_MR",
951
+ id: entry.id
952
+ })
953
+ }), t("web.createMrCheckbox")]
954
+ }), /* @__PURE__ */ jsxDEV("button", {
955
+ class: `history-quick-btn${s.quickExecuting === entry.id ? " executing" : ""}`,
956
+ type: "button",
957
+ disabled: s.quickExecuting !== null,
958
+ onClick: () => handleQuickExecute(entry.id),
959
+ children: s.quickExecuting === entry.id ? t("web.executing") : t("web.quickExecute")
960
+ })]
961
+ })]
962
+ }),
963
+ s.quickResults[entry.id] && /* @__PURE__ */ jsxDEV("div", {
964
+ class: "history-result",
965
+ children: [
966
+ /* @__PURE__ */ jsxDEV("a", {
967
+ class: "history-result-key",
968
+ href: s.quickResults[entry.id].issueUrl,
969
+ target: "_blank",
970
+ rel: "noreferrer",
971
+ children: s.quickResults[entry.id].issueKey
972
+ }),
973
+ /* @__PURE__ */ jsxDEV("span", {
974
+ class: `jira-result-badge ${s.quickResults[entry.id].issueCreated ? "created" : "exists"}`,
975
+ children: s.quickResults[entry.id].issueCreated ? t("web.createdBadge") : t("web.existsBadge")
976
+ }),
977
+ /* @__PURE__ */ jsxDEV("span", {
978
+ style: "font-size:12px;color:var(--text-3);margin-left:8px",
979
+ children: ["v", s.quickResults[entry.id].version]
980
+ }),
981
+ s.quickResults[entry.id].versionCreated && /* @__PURE__ */ jsxDEV("span", {
982
+ style: "font-size:10px;color:var(--neon);margin-left:4px",
983
+ children: t("web.createdBadge")
984
+ }),
985
+ s.quickResults[entry.id].mrUrl && /* @__PURE__ */ jsxDEV("span", {
986
+ style: "font-size:12px;margin-left:12px",
987
+ children: /* @__PURE__ */ jsxDEV("a", {
988
+ href: s.quickResults[entry.id].mrUrl,
989
+ target: "_blank",
990
+ rel: "noreferrer",
991
+ style: "color:var(--cyan);text-decoration:none;border-bottom:1px dashed var(--cyan)",
992
+ children: t("release.mrFromTo", {
993
+ source: s.quickResults[entry.id].mrSourceBranch ?? "",
994
+ target: s.quickResults[entry.id].mrTargetBranch ?? entry.branch
995
+ })
996
+ })
997
+ })
998
+ ]
999
+ }),
1000
+ s.quickErrors[entry.id] && /* @__PURE__ */ jsxDEV("div", {
1001
+ class: "history-result-error",
1002
+ children: s.quickErrors[entry.id]
1003
+ })
1004
+ ]
1005
+ }))
1006
+ }) : /* @__PURE__ */ jsxDEV("div", {
1007
+ class: "empty-hint",
1008
+ children: t("web.noHistory")
1009
+ }),
1010
+ /* @__PURE__ */ jsxDEV("div", {
1011
+ class: "history-footer",
1012
+ children: [/* @__PURE__ */ jsxDEV("button", {
1013
+ class: "history-new-btn",
1014
+ type: "button",
1015
+ onClick: () => d({ type: "SHOW_NEW_MODAL" }),
1016
+ children: t("web.createNew")
1017
+ }), s.history.length > 0 && (s.clearConfirm ? /* @__PURE__ */ jsxDEV("div", {
1018
+ style: "display:flex;align-items:center;gap:8px",
1019
+ children: [
1020
+ /* @__PURE__ */ jsxDEV("span", {
1021
+ style: "font-size:12px;color:var(--text-3)",
1022
+ children: t("web.clearConfirm")
1023
+ }),
1024
+ /* @__PURE__ */ jsxDEV("button", {
1025
+ class: "history-clear-btn",
1026
+ type: "button",
1027
+ style: "border-color:var(--error);color:var(--error)",
1028
+ onClick: handleClearHistory,
1029
+ children: t("web.clearHistory")
1030
+ }),
1031
+ /* @__PURE__ */ jsxDEV("button", {
1032
+ class: "history-clear-btn",
1033
+ type: "button",
1034
+ onClick: () => d({ type: "CLEAR_CONFIRM_TOGGLE" }),
1035
+ children: t("web.cancel")
1036
+ })
1037
+ ]
1038
+ }) : /* @__PURE__ */ jsxDEV("button", {
1039
+ class: "history-clear-btn",
1040
+ type: "button",
1041
+ onClick: () => d({ type: "CLEAR_CONFIRM_TOGGLE" }),
1042
+ children: t("web.clearHistory")
1043
+ }))]
1044
+ })
1045
+ ]
1046
+ });
1047
+ };
1048
+ const ReleaseFlow = ({ s, d }) => {
1049
+ const projectSearchRef = useRef(null);
1050
+ const branchSearchRef = useRef(null);
1051
+ const jiraSearchRef = useRef(null);
1052
+ const mrBranchSearchRef = useRef(null);
1053
+ useEffect(() => {
1054
+ fetch("/release/api/config").then((r) => r.json()).then((data) => {
1055
+ if (data.jiraHost) d({
1056
+ type: "SET_JIRA_HOST",
1057
+ host: data.jiraHost
1058
+ });
1059
+ }).catch(() => {});
1060
+ }, []);
1061
+ useEffect(() => {
1062
+ fetch("/release/api/projects").then((r) => r.json()).then((data) => {
1063
+ if (data.error) d({
1064
+ type: "PROJECTS_ERROR",
1065
+ error: data.error
1066
+ });
1067
+ else d({
1068
+ type: "PROJECTS_LOADED",
1069
+ projects: data
1070
+ });
1071
+ }).catch((e) => d({
1072
+ type: "PROJECTS_ERROR",
1073
+ error: e.message
1074
+ }));
1075
+ }, []);
1076
+ useEffect(() => {
1077
+ if (!s.projectOpen && !s.branchOpen && !s.jiraProjectOpen && !s.mrBranchOpen) return;
1078
+ const handler = (e) => {
1079
+ const target = e.target;
1080
+ if (!target.closest(".sel") && !target.closest(".mr-branch-sel")) {
1081
+ d({
1082
+ type: "SET_PROJECT_OPEN",
1083
+ open: false
1084
+ });
1085
+ d({
1086
+ type: "SET_BRANCH_OPEN",
1087
+ open: false
1088
+ });
1089
+ d({
1090
+ type: "SET_MR_BRANCH_OPEN",
1091
+ open: false
1092
+ });
1093
+ d({
1094
+ type: "SET_JIRA_PROJECT_OPEN",
1095
+ open: false
1096
+ });
1097
+ }
1098
+ };
1099
+ document.addEventListener("click", handler);
1100
+ return () => document.removeEventListener("click", handler);
1101
+ }, [
1102
+ s.projectOpen,
1103
+ s.branchOpen,
1104
+ s.jiraProjectOpen
1105
+ ]);
1106
+ useEffect(() => {
1107
+ if (s.projectOpen) setTimeout(() => projectSearchRef.current?.focus(), 50);
1108
+ if (s.branchOpen) setTimeout(() => branchSearchRef.current?.focus(), 50);
1109
+ if (s.jiraProjectOpen) setTimeout(() => jiraSearchRef.current?.focus(), 50);
1110
+ if (s.mrBranchOpen) setTimeout(() => mrBranchSearchRef.current?.focus(), 50);
1111
+ }, [
1112
+ s.projectOpen,
1113
+ s.branchOpen,
1114
+ s.jiraProjectOpen,
1115
+ s.mrBranchOpen
1116
+ ]);
1117
+ useEffect(() => {
1118
+ if (s.mrStatus !== "creating" || !s.mrSourceBranch || !s.selected) return;
1119
+ const jiraUrl2 = s.jiraResult && s.jiraHost ? `${s.jiraHost}/browse/${s.jiraResult.key}` : "";
1120
+ fetch("/release/api/create-mr", {
1121
+ method: "POST",
1122
+ headers: { "Content-Type": "application/json" },
1123
+ body: JSON.stringify({
1124
+ projectId: s.selected.id,
1125
+ targetBranch: s.selectedBranch,
1126
+ sourceBranch: s.mrSourceBranch,
1127
+ jiraUrl: jiraUrl2
1128
+ })
1129
+ }).then((r) => r.json()).then((data) => {
1130
+ if (data.mrUrl) {
1131
+ d({
1132
+ type: "MR_DONE",
1133
+ mrUrl: data.mrUrl,
1134
+ mrSourceBranch: data.sourceBranch,
1135
+ mrTargetBranch: data.targetBranch
1136
+ });
1137
+ fetch("/release/api/history").then((r) => r.json()).then((h) => d({
1138
+ type: "HISTORY_LOADED",
1139
+ history: h
1140
+ }));
1141
+ } else d({
1142
+ type: "MR_ERROR",
1143
+ error: data.error ?? "Failed"
1144
+ });
1145
+ }).catch((e) => d({
1146
+ type: "MR_ERROR",
1147
+ error: e instanceof Error ? e.message : "Failed"
1148
+ }));
1149
+ }, [s.mrStatus, s.mrSourceBranch]);
1150
+ useEffect(() => {
1151
+ if (!s.pomInfo?.version || s.jiraProjects.length > 0 || s.jiraProjectsLoading) return;
1152
+ d({ type: "JIRA_PROJECTS_LOADING" });
1153
+ fetch("/release/api/jira/projects").then((r) => r.json()).then((data) => {
1154
+ if (Array.isArray(data)) d({
1155
+ type: "JIRA_PROJECTS_LOADED",
1156
+ projects: data
1157
+ });
1158
+ else d({
1159
+ type: "JIRA_PROJECTS_ERROR",
1160
+ error: data.error ?? "Failed"
1161
+ });
1162
+ }).catch(() => d({
1163
+ type: "JIRA_PROJECTS_ERROR",
1164
+ error: "Failed"
1165
+ }));
1166
+ }, [s.pomInfo?.version]);
1167
+ const fetchPom = (projectId, ref) => {
1168
+ d({ type: "POM_LOADING" });
1169
+ fetch(`/release/api/projects/${projectId}/pom-version?ref=${encodeURIComponent(ref)}`).then((r) => r.json()).then((data) => {
1170
+ if (data.error) d({
1171
+ type: "POM_ERROR",
1172
+ error: data.error
1173
+ });
1174
+ else d({
1175
+ type: "POM_LOADED",
1176
+ info: data
1177
+ });
1178
+ }).catch(() => d({
1179
+ type: "POM_ERROR",
1180
+ error: "Failed to fetch version"
1181
+ }));
1182
+ };
1183
+ const handleSelectProject = (project) => {
1184
+ d({
1185
+ type: "SELECT_PROJECT",
1186
+ project
1187
+ });
1188
+ d({ type: "BRANCHES_LOADING" });
1189
+ fetch(`/release/api/projects/${project.id}/branches`).then((r) => r.json()).then((data) => {
1190
+ d({
1191
+ type: "BRANCHES_LOADED",
1192
+ branches: "error" in data ? [] : data
1193
+ });
1194
+ }).catch(() => d({
1195
+ type: "BRANCHES_LOADED",
1196
+ branches: []
1197
+ }));
1198
+ };
1199
+ const handleSelectBranch = (name) => {
1200
+ d({
1201
+ type: "SELECT_BRANCH",
1202
+ branch: name
1203
+ });
1204
+ if (s.selected) fetchPom(s.selected.id, name);
1205
+ };
1206
+ const handleCreateIssue = async () => {
1207
+ if (!s.selected || !s.pomInfo?.version || !s.selectedJiraProject) return;
1208
+ const artifactId = s.pomInfo.artifactId ?? s.selected.name;
1209
+ const projectVersion = cleanVersion(s.pomInfo.version);
1210
+ const versionName = `${artifactId}-${projectVersion}`;
1211
+ const summary = `${artifactId}-${projectVersion} ${t("web.releaseSuffix") ?? t("release.releaseSuffix")}`;
1212
+ d({ type: "JIRA_CHECKING" });
1213
+ try {
1214
+ const searchData = await (await fetch("/release/api/jira/search", {
1215
+ method: "POST",
1216
+ headers: { "Content-Type": "application/json" },
1217
+ body: JSON.stringify({
1218
+ jql: `summary ~ "${summary}" AND project = ${s.selectedJiraProject.key}`,
1219
+ maxResults: 1
1220
+ })
1221
+ })).json();
1222
+ if (searchData.error) {
1223
+ d({
1224
+ type: "JIRA_ERROR",
1225
+ error: searchData.error
1226
+ });
1227
+ return;
1228
+ }
1229
+ if (searchData.total > 0 && searchData.issues?.[0]) {
1230
+ d({
1231
+ type: "JIRA_DONE",
1232
+ result: {
1233
+ key: searchData.issues[0].key,
1234
+ exists: true,
1235
+ versionName
1236
+ }
1237
+ });
1238
+ await fetch("/release/api/history", {
1239
+ method: "POST",
1240
+ headers: { "Content-Type": "application/json" },
1241
+ body: JSON.stringify({
1242
+ id: Date.now().toString(36),
1243
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1244
+ projectId: s.selected.id,
1245
+ projectName: s.selected.name,
1246
+ projectPath: s.selected.pathWithNamespace ?? "",
1247
+ branch: s.selectedBranch,
1248
+ jiraProjectKey: s.selectedJiraProject.key
1249
+ })
1250
+ });
1251
+ return;
1252
+ }
1253
+ d({ type: "JIRA_CREATING" });
1254
+ const verData = await (await fetch("/release/api/jira/ensure-version", {
1255
+ method: "POST",
1256
+ headers: { "Content-Type": "application/json" },
1257
+ body: JSON.stringify({
1258
+ projectKey: s.selectedJiraProject.key,
1259
+ versionName
1260
+ })
1261
+ })).json();
1262
+ if (verData.error) {
1263
+ d({
1264
+ type: "JIRA_ERROR",
1265
+ error: verData.error
1266
+ });
1267
+ return;
1268
+ }
1269
+ const issueData = await (await fetch("/release/api/jira/create-issue", {
1270
+ method: "POST",
1271
+ headers: { "Content-Type": "application/json" },
1272
+ body: JSON.stringify({
1273
+ projectKey: s.selectedJiraProject.key,
1274
+ summary,
1275
+ issuetypeId: "10000",
1276
+ customfield_15800: "无",
1277
+ customfield_13410: [{ id: verData.id }],
1278
+ customfield_13341: [{ name: "licheng.li" }]
1279
+ })
1280
+ })).json();
1281
+ if (issueData.error) {
1282
+ d({
1283
+ type: "JIRA_ERROR",
1284
+ error: issueData.error
1285
+ });
1286
+ return;
1287
+ }
1288
+ d({
1289
+ type: "JIRA_DONE",
1290
+ result: {
1291
+ key: issueData.key,
1292
+ exists: false,
1293
+ versionName: verData.name
1294
+ }
1295
+ });
1296
+ await fetch("/release/api/history", {
1297
+ method: "POST",
1298
+ headers: { "Content-Type": "application/json" },
1299
+ body: JSON.stringify({
1300
+ id: Date.now().toString(36),
1301
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1302
+ projectId: s.selected.id,
1303
+ projectName: s.selected.name,
1304
+ projectPath: s.selected.pathWithNamespace ?? "",
1305
+ branch: s.selectedBranch,
1306
+ jiraProjectKey: s.selectedJiraProject.key
1307
+ })
1308
+ });
1309
+ } catch (e) {
1310
+ d({
1311
+ type: "JIRA_ERROR",
1312
+ error: e instanceof Error ? e.message : String(e)
1313
+ });
1314
+ }
1315
+ };
1316
+ const fp = filterByRelevance(s.projects.map((p) => ({
1317
+ ...p,
1318
+ name: p.name,
1319
+ path: p.pathWithNamespace ?? ""
1320
+ })), s.projectSearch);
1321
+ const fb = filterByRelevance(s.branches.map((b) => ({
1322
+ ...b,
1323
+ name: b.name
1324
+ })), s.branchSearch);
1325
+ const fj = filterByRelevance(s.jiraProjects.map((p) => ({
1326
+ ...p,
1327
+ name: `${p.key} ${p.name ?? ""}`
1328
+ })), s.jiraProjectSearch);
1329
+ const jiraUrl = s.jiraResult && s.jiraHost ? `${s.jiraHost}/browse/${s.jiraResult.key}` : "";
1330
+ const step1Done = !!s.selected;
1331
+ const step1Active = !s.projectsLoading && !step1Done;
1332
+ const step2Done = !!s.selectedBranch;
1333
+ const step2Active = !!s.selected && !step2Done;
1334
+ const step3Done = !!s.pomInfo?.version;
1335
+ const step3Active = !!s.selectedBranch && !step3Done;
1336
+ const step4Done = !!s.selectedJiraProject;
1337
+ const step4Active = !!s.pomInfo?.version && !step4Done;
1338
+ const step5Done = !!s.jiraResult;
1339
+ const step5Active = !!s.selectedJiraProject && !step5Done;
1340
+ if (s.projectsLoading) return /* @__PURE__ */ jsxDEV("div", {
1341
+ class: "loading-row",
1342
+ children: [/* @__PURE__ */ jsxDEV("span", { class: "spinner" }), t("web.loadingProjects")]
1343
+ });
1344
+ if (s.projectsError) return /* @__PURE__ */ jsxDEV("div", {
1345
+ class: "state-error",
1346
+ children: s.projectsError
1347
+ });
1348
+ return /* @__PURE__ */ jsxDEV("div", { children: [
1349
+ /* @__PURE__ */ jsxDEV("div", {
1350
+ class: "pipeline",
1351
+ children: [
1352
+ /* @__PURE__ */ jsxDEV("div", {
1353
+ class: pipelineStepClass(step1Done, step1Active),
1354
+ children: [/* @__PURE__ */ jsxDEV("span", { class: "pipeline-node" }), t("web.projectLabel")]
1355
+ }),
1356
+ /* @__PURE__ */ jsxDEV("div", { class: pipelineLineClass(step1Done) }),
1357
+ /* @__PURE__ */ jsxDEV("div", {
1358
+ class: pipelineStepClass(step2Done, step2Active),
1359
+ children: [/* @__PURE__ */ jsxDEV("span", { class: "pipeline-node" }), t("web.branchLabel")]
1360
+ }),
1361
+ /* @__PURE__ */ jsxDEV("div", { class: pipelineLineClass(step2Done) }),
1362
+ /* @__PURE__ */ jsxDEV("div", {
1363
+ class: pipelineStepClass(step3Done, step3Active),
1364
+ children: [/* @__PURE__ */ jsxDEV("span", { class: "pipeline-node" }), t("web.versionTag")]
1365
+ }),
1366
+ /* @__PURE__ */ jsxDEV("div", { class: pipelineLineClass(step3Done) }),
1367
+ /* @__PURE__ */ jsxDEV("div", {
1368
+ class: pipelineStepClass(step4Done, step4Active),
1369
+ children: [/* @__PURE__ */ jsxDEV("span", { class: "pipeline-node" }), t("web.jiraProjectLabel")]
1370
+ }),
1371
+ /* @__PURE__ */ jsxDEV("div", { class: pipelineLineClass(step4Done) }),
1372
+ /* @__PURE__ */ jsxDEV("div", {
1373
+ class: pipelineStepClass(step5Done, step5Active),
1374
+ children: [/* @__PURE__ */ jsxDEV("span", { class: "pipeline-node" }), t("web.createBtn")]
1375
+ })
1376
+ ]
1377
+ }),
1378
+ /* @__PURE__ */ jsxDEV("div", {
1379
+ class: "sel",
1380
+ "data-sel": "project",
1381
+ style: `z-index:${s.projectOpen ? 100 : 1}`,
1382
+ children: [/* @__PURE__ */ jsxDEV("button", {
1383
+ class: `sel-trigger${s.projectOpen ? " open" : ""}`,
1384
+ type: "button",
1385
+ role: "combobox",
1386
+ "aria-expanded": s.projectOpen,
1387
+ "aria-haspopup": "listbox",
1388
+ onClick: () => {
1389
+ d({
1390
+ type: "SET_BRANCH_OPEN",
1391
+ open: false
1392
+ });
1393
+ d({
1394
+ type: "SET_JIRA_PROJECT_OPEN",
1395
+ open: false
1396
+ });
1397
+ d({
1398
+ type: "SET_MR_BRANCH_OPEN",
1399
+ open: false
1400
+ });
1401
+ d({
1402
+ type: "SET_PROJECT_OPEN",
1403
+ open: !s.projectOpen
1404
+ });
1405
+ },
1406
+ children: [
1407
+ /* @__PURE__ */ jsxDEV("span", {
1408
+ class: "sel-trigger-label",
1409
+ children: t("web.projectLabel")
1410
+ }),
1411
+ /* @__PURE__ */ jsxDEV("span", {
1412
+ class: `sel-trigger-value${s.selected ? "" : " empty"}`,
1413
+ children: s.selected ? s.selected.name : t("web.selectProject")
1414
+ }),
1415
+ /* @__PURE__ */ jsxDEV("span", {
1416
+ class: "sel-trigger-arrow",
1417
+ children: "▼"
1418
+ })
1419
+ ]
1420
+ }), s.projectOpen && /* @__PURE__ */ jsxDEV("div", {
1421
+ class: "sel-dropdown",
1422
+ role: "listbox",
1423
+ "aria-label": t("web.selectProject"),
1424
+ children: [/* @__PURE__ */ jsxDEV("div", {
1425
+ class: "sel-search",
1426
+ children: /* @__PURE__ */ jsxDEV("input", {
1427
+ ref: projectSearchRef,
1428
+ class: "sel-search-input",
1429
+ type: "text",
1430
+ placeholder: t("web.searchProjects"),
1431
+ value: s.projectSearch,
1432
+ onChange: (e) => d({
1433
+ type: "SET_PROJECT_SEARCH",
1434
+ search: e.target.value
1435
+ }),
1436
+ onKeyDown: (e) => {
1437
+ const n = selKeyDown(e, s.projectOpen, fp.length, s.projectIndex, (i) => {
1438
+ const p = fp[i];
1439
+ if (p) handleSelectProject(p);
1440
+ }, () => d({
1441
+ type: "SET_PROJECT_OPEN",
1442
+ open: false
1443
+ }));
1444
+ if (n !== void 0) d({
1445
+ type: "SET_PROJECT_INDEX",
1446
+ index: n
1447
+ });
1448
+ }
1449
+ })
1450
+ }), fp.length > 0 ? fp.map((p, i) => /* @__PURE__ */ jsxDEV("div", {
1451
+ class: `sel-item${s.selected?.id === p.id ? " active" : ""}${i === s.projectIndex ? " highlighted" : ""}`,
1452
+ onMouseEnter: () => d({
1453
+ type: "SET_PROJECT_INDEX",
1454
+ index: i
1455
+ }),
1456
+ onClick: () => handleSelectProject(p),
1457
+ children: [/* @__PURE__ */ jsxDEV("div", {
1458
+ class: "sel-item-name",
1459
+ children: p.name
1460
+ }), /* @__PURE__ */ jsxDEV("div", {
1461
+ class: "sel-item-sub",
1462
+ children: p.pathWithNamespace
1463
+ })]
1464
+ })) : /* @__PURE__ */ jsxDEV("div", {
1465
+ class: "sel-empty",
1466
+ children: t("web.noProjects")
1467
+ })]
1468
+ })]
1469
+ }),
1470
+ s.selected && (s.branchesLoading ? /* @__PURE__ */ jsxDEV("div", {
1471
+ class: "loading-row",
1472
+ children: [/* @__PURE__ */ jsxDEV("span", { class: "spinner" }), t("web.loadingBranches")]
1473
+ }) : s.branches.length > 0 && /* @__PURE__ */ jsxDEV("div", {
1474
+ class: "sel",
1475
+ "data-sel": "branch",
1476
+ style: `z-index:${s.branchOpen ? 100 : 1}`,
1477
+ children: [/* @__PURE__ */ jsxDEV("button", {
1478
+ class: `sel-trigger${s.branchOpen ? " open" : ""}`,
1479
+ type: "button",
1480
+ role: "combobox",
1481
+ "aria-expanded": s.branchOpen,
1482
+ "aria-haspopup": "listbox",
1483
+ onClick: () => {
1484
+ d({
1485
+ type: "SET_PROJECT_OPEN",
1486
+ open: false
1487
+ });
1488
+ d({
1489
+ type: "SET_JIRA_PROJECT_OPEN",
1490
+ open: false
1491
+ });
1492
+ d({
1493
+ type: "SET_MR_BRANCH_OPEN",
1494
+ open: false
1495
+ });
1496
+ d({
1497
+ type: "SET_BRANCH_OPEN",
1498
+ open: !s.branchOpen
1499
+ });
1500
+ },
1501
+ children: [
1502
+ /* @__PURE__ */ jsxDEV("span", {
1503
+ class: "sel-trigger-label",
1504
+ children: t("web.branchLabel")
1505
+ }),
1506
+ /* @__PURE__ */ jsxDEV("span", {
1507
+ class: `sel-trigger-value${s.selectedBranch ? "" : " empty"}`,
1508
+ children: s.selectedBranch || t("web.selectBranch")
1509
+ }),
1510
+ /* @__PURE__ */ jsxDEV("span", {
1511
+ class: "sel-trigger-arrow",
1512
+ children: "▼"
1513
+ })
1514
+ ]
1515
+ }), s.branchOpen && /* @__PURE__ */ jsxDEV("div", {
1516
+ class: "sel-dropdown",
1517
+ role: "listbox",
1518
+ "aria-label": t("web.selectBranch"),
1519
+ children: [/* @__PURE__ */ jsxDEV("div", {
1520
+ class: "sel-search",
1521
+ children: /* @__PURE__ */ jsxDEV("input", {
1522
+ ref: branchSearchRef,
1523
+ class: "sel-search-input",
1524
+ type: "text",
1525
+ placeholder: t("web.filterBranches"),
1526
+ value: s.branchSearch,
1527
+ onChange: (e) => d({
1528
+ type: "SET_BRANCH_SEARCH",
1529
+ search: e.target.value
1530
+ }),
1531
+ onKeyDown: (e) => {
1532
+ const n = selKeyDown(e, s.branchOpen, fb.length, s.branchIndex, (i) => {
1533
+ const b = fb[i];
1534
+ if (b) handleSelectBranch(b.name);
1535
+ }, () => d({
1536
+ type: "SET_BRANCH_OPEN",
1537
+ open: false
1538
+ }));
1539
+ if (n !== void 0) d({
1540
+ type: "SET_BRANCH_INDEX",
1541
+ index: n
1542
+ });
1543
+ }
1544
+ })
1545
+ }), fb.length > 0 ? fb.map((b, i) => /* @__PURE__ */ jsxDEV("div", {
1546
+ class: `sel-item${b.name === s.selectedBranch ? " active" : ""}${i === s.branchIndex ? " highlighted" : ""}`,
1547
+ onMouseEnter: () => d({
1548
+ type: "SET_BRANCH_INDEX",
1549
+ index: i
1550
+ }),
1551
+ onClick: () => handleSelectBranch(b.name),
1552
+ children: [/* @__PURE__ */ jsxDEV("span", {
1553
+ class: "sel-item-name",
1554
+ children: b.name
1555
+ }), b.default && /* @__PURE__ */ jsxDEV("span", {
1556
+ style: "font-size:10px;color:var(--neon);margin-left:6px",
1557
+ children: t("web.defaultBranch")
1558
+ })]
1559
+ })) : /* @__PURE__ */ jsxDEV("div", {
1560
+ class: "sel-empty",
1561
+ children: t("web.noBranches")
1562
+ })]
1563
+ })]
1564
+ })),
1565
+ s.selected && s.selectedBranch && !s.branchesLoading && (s.pomLoading ? /* @__PURE__ */ jsxDEV("div", {
1566
+ class: "loading-row",
1567
+ children: [/* @__PURE__ */ jsxDEV("span", { class: "spinner" }), t("web.loadingVersion")]
1568
+ }) : s.pomError ? /* @__PURE__ */ jsxDEV("div", {
1569
+ class: "version-error",
1570
+ role: "alert",
1571
+ children: s.pomError.includes("404") ? t("web.noPom") : s.pomError
1572
+ }) : s.pomInfo && /* @__PURE__ */ jsxDEV("div", {
1573
+ class: "version-display",
1574
+ children: [/* @__PURE__ */ jsxDEV("span", {
1575
+ class: "version-tag",
1576
+ children: t("web.versionTag")
1577
+ }), /* @__PURE__ */ jsxDEV("span", {
1578
+ class: "version-number",
1579
+ children: cleanVersion(s.pomInfo.version)
1580
+ })]
1581
+ })),
1582
+ s.selected && s.pomInfo?.version && !s.pomLoading && /* @__PURE__ */ jsxDEV("div", {
1583
+ class: "jira-section",
1584
+ children: [
1585
+ s.jiraProjectsLoading ? /* @__PURE__ */ jsxDEV("div", {
1586
+ class: "loading-row",
1587
+ children: [/* @__PURE__ */ jsxDEV("span", { class: "spinner" }), t("web.loadingJiraProjects")]
1588
+ }) : /* @__PURE__ */ jsxDEV("div", {
1589
+ class: "sel",
1590
+ "data-sel": "jira",
1591
+ style: `z-index:${s.jiraProjectOpen ? 100 : 1}`,
1592
+ children: [/* @__PURE__ */ jsxDEV("button", {
1593
+ class: `sel-trigger${s.jiraProjectOpen ? " open" : ""}`,
1594
+ type: "button",
1595
+ role: "combobox",
1596
+ "aria-expanded": s.jiraProjectOpen,
1597
+ "aria-haspopup": "listbox",
1598
+ onClick: () => {
1599
+ d({
1600
+ type: "SET_PROJECT_OPEN",
1601
+ open: false
1602
+ });
1603
+ d({
1604
+ type: "SET_BRANCH_OPEN",
1605
+ open: false
1606
+ });
1607
+ d({
1608
+ type: "SET_JIRA_PROJECT_OPEN",
1609
+ open: !s.jiraProjectOpen
1610
+ });
1611
+ },
1612
+ children: [
1613
+ /* @__PURE__ */ jsxDEV("span", {
1614
+ class: "sel-trigger-label",
1615
+ children: t("web.jiraProjectLabel")
1616
+ }),
1617
+ /* @__PURE__ */ jsxDEV("span", {
1618
+ class: `sel-trigger-value${s.selectedJiraProject ? "" : " empty"}`,
1619
+ children: s.selectedJiraProject ? `${s.selectedJiraProject.key} - ${s.selectedJiraProject.name ?? ""}` : t("web.selectJiraProject")
1620
+ }),
1621
+ /* @__PURE__ */ jsxDEV("span", {
1622
+ class: "sel-trigger-arrow",
1623
+ children: "▼"
1624
+ })
1625
+ ]
1626
+ }), s.jiraProjectOpen && /* @__PURE__ */ jsxDEV("div", {
1627
+ class: "sel-dropdown",
1628
+ role: "listbox",
1629
+ "aria-label": t("web.selectJiraProject"),
1630
+ children: [/* @__PURE__ */ jsxDEV("div", {
1631
+ class: "sel-search",
1632
+ children: /* @__PURE__ */ jsxDEV("input", {
1633
+ ref: jiraSearchRef,
1634
+ class: "sel-search-input",
1635
+ type: "text",
1636
+ placeholder: t("web.searchJiraProject"),
1637
+ value: s.jiraProjectSearch,
1638
+ onChange: (e) => d({
1639
+ type: "SET_JIRA_PROJECT_SEARCH",
1640
+ search: e.target.value
1641
+ }),
1642
+ onKeyDown: (e) => {
1643
+ const n = selKeyDown(e, s.jiraProjectOpen, fj.length, s.jiraProjectIndex, (i) => {
1644
+ const p = fj[i];
1645
+ if (p) d({
1646
+ type: "SELECT_JIRA_PROJECT",
1647
+ project: p
1648
+ });
1649
+ }, () => d({
1650
+ type: "SET_JIRA_PROJECT_OPEN",
1651
+ open: false
1652
+ }));
1653
+ if (n !== void 0) d({
1654
+ type: "SET_JIRA_PROJECT_INDEX",
1655
+ index: n
1656
+ });
1657
+ }
1658
+ })
1659
+ }), fj.length > 0 ? fj.map((p, i) => /* @__PURE__ */ jsxDEV("div", {
1660
+ class: `sel-item${s.selectedJiraProject?.key === p.key ? " active" : ""}${i === s.jiraProjectIndex ? " highlighted" : ""}`,
1661
+ onMouseEnter: () => d({
1662
+ type: "SET_JIRA_PROJECT_INDEX",
1663
+ index: i
1664
+ }),
1665
+ onClick: () => d({
1666
+ type: "SELECT_JIRA_PROJECT",
1667
+ project: p
1668
+ }),
1669
+ children: [/* @__PURE__ */ jsxDEV("span", {
1670
+ class: "sel-item-name",
1671
+ children: p.key
1672
+ }), p.name && /* @__PURE__ */ jsxDEV("div", {
1673
+ class: "sel-item-sub",
1674
+ children: p.name
1675
+ })]
1676
+ })) : /* @__PURE__ */ jsxDEV("div", {
1677
+ class: "sel-empty",
1678
+ children: t("web.noJiraProjects")
1679
+ })]
1680
+ })]
1681
+ }),
1682
+ /* @__PURE__ */ jsxDEV("button", {
1683
+ class: "jira-btn",
1684
+ type: "button",
1685
+ disabled: !s.selectedJiraProject || s.jiraStatus === "checking" || s.jiraStatus === "creating",
1686
+ onClick: handleCreateIssue,
1687
+ children: s.jiraStatus === "checking" ? t("web.checkingBtn") : s.jiraStatus === "creating" ? t("web.creatingBtn") : t("web.createBtn")
1688
+ }),
1689
+ (s.jiraStatus === "checking" || s.jiraStatus === "creating") && /* @__PURE__ */ jsxDEV("div", {
1690
+ class: "loading-row",
1691
+ style: "margin-top:12px",
1692
+ children: [/* @__PURE__ */ jsxDEV("span", { class: "spinner" }), s.jiraStatus === "checking" ? t("web.checkingIssues") : t("web.creatingIssue")]
1693
+ }),
1694
+ s.jiraResult && /* @__PURE__ */ jsxDEV("div", {
1695
+ class: "jira-result",
1696
+ children: [
1697
+ /* @__PURE__ */ jsxDEV("div", {
1698
+ class: "jira-result-label",
1699
+ children: s.jiraResult.exists ? t("web.versionExistsResult", { version: s.jiraResult.versionName }) : t("web.versionCreatedResult", { version: s.jiraResult.versionName })
1700
+ }),
1701
+ /* @__PURE__ */ jsxDEV("a", {
1702
+ class: "jira-result-key",
1703
+ href: jiraUrl,
1704
+ target: "_blank",
1705
+ rel: "noreferrer",
1706
+ children: s.jiraResult.key
1707
+ }),
1708
+ /* @__PURE__ */ jsxDEV("span", {
1709
+ class: `jira-result-badge ${s.jiraResult.exists ? "exists" : "created"}`,
1710
+ children: s.jiraResult.exists ? t("web.existsBadge") : t("web.createdBadge")
1711
+ })
1712
+ ]
1713
+ }),
1714
+ s.jiraError && /* @__PURE__ */ jsxDEV("div", {
1715
+ class: "jira-error",
1716
+ role: "alert",
1717
+ children: s.jiraError
1718
+ }),
1719
+ s.jiraResult && (s.mrStatus === "idle" || s.mrStatus === "loading") && /* @__PURE__ */ jsxDEV("button", {
1720
+ class: "jira-btn",
1721
+ type: "button",
1722
+ disabled: s.mrStatus === "loading",
1723
+ style: "background:var(--cyan);margin-top:12px",
1724
+ onClick: async () => {
1725
+ if (s.mrStatus === "loading") return;
1726
+ d({ type: "MR_LOADING" });
1727
+ try {
1728
+ const data = await (await fetch(`/release/api/projects/${s.selected.id}/branches`)).json();
1729
+ const branches = (Array.isArray(data) ? data : []).filter((b) => b.name !== s.selectedBranch);
1730
+ if (branches.length === 0) {
1731
+ d({
1732
+ type: "MR_ERROR",
1733
+ error: t("release.noSourceBranches")
1734
+ });
1735
+ return;
1736
+ }
1737
+ d({
1738
+ type: "MR_SELECTING",
1739
+ branches
1740
+ });
1741
+ } catch (e) {
1742
+ d({
1743
+ type: "MR_ERROR",
1744
+ error: e instanceof Error ? e.message : "Failed"
1745
+ });
1746
+ }
1747
+ },
1748
+ children: s.mrStatus === "loading" ? /* @__PURE__ */ jsxDEV(Fragment, { children: [/* @__PURE__ */ jsxDEV("span", {
1749
+ class: "spinner",
1750
+ style: "width:12px;height:12px;border-width:1px;margin-right:6px;vertical-align:middle"
1751
+ }), t("web.loadingMr")] }) : t("web.createMrBtn")
1752
+ }),
1753
+ s.mrStatus === "selecting" && (() => {
1754
+ const mrb = s.mrBranches.filter((b) => b.name.toLowerCase().includes(s.mrBranchSearch.toLowerCase()));
1755
+ return /* @__PURE__ */ jsxDEV("div", {
1756
+ class: "mr-branch-sel",
1757
+ style: "margin-top:12px",
1758
+ children: [/* @__PURE__ */ jsxDEV("div", {
1759
+ style: "font-size:13px;color:var(--text-2);margin-bottom:4px",
1760
+ children: t("release.selectMrBranch")
1761
+ }), /* @__PURE__ */ jsxDEV("div", {
1762
+ class: "sel",
1763
+ style: "position:relative;z-index:100",
1764
+ children: [/* @__PURE__ */ jsxDEV("button", {
1765
+ type: "button",
1766
+ class: "sel-trigger",
1767
+ onClick: () => d({
1768
+ type: "SET_MR_BRANCH_OPEN",
1769
+ open: !s.mrBranchOpen
1770
+ }),
1771
+ children: [
1772
+ /* @__PURE__ */ jsxDEV("span", {
1773
+ class: "sel-trigger-label",
1774
+ children: t("web.branchLabel")
1775
+ }),
1776
+ /* @__PURE__ */ jsxDEV("span", {
1777
+ class: `sel-trigger-value${s.mrSourceBranch ? "" : " empty"}`,
1778
+ children: s.mrSourceBranch || t("web.selectBranch")
1779
+ }),
1780
+ /* @__PURE__ */ jsxDEV("span", {
1781
+ class: "sel-trigger-arrow",
1782
+ children: "▼"
1783
+ })
1784
+ ]
1785
+ }), s.mrBranchOpen && /* @__PURE__ */ jsxDEV("div", {
1786
+ class: "sel-dropdown",
1787
+ role: "listbox",
1788
+ "aria-label": t("release.selectMrBranch"),
1789
+ children: [/* @__PURE__ */ jsxDEV("div", {
1790
+ class: "sel-search",
1791
+ children: /* @__PURE__ */ jsxDEV("input", {
1792
+ ref: mrBranchSearchRef,
1793
+ class: "sel-search-input",
1794
+ type: "text",
1795
+ placeholder: t("web.filterBranches"),
1796
+ value: s.mrBranchSearch,
1797
+ onChange: (e) => d({
1798
+ type: "SET_MR_BRANCH_SEARCH",
1799
+ search: e.target.value
1800
+ }),
1801
+ onKeyDown: (e) => {
1802
+ const n = selKeyDown(e, s.mrBranchOpen, mrb.length, s.mrBranchIndex, (i) => {
1803
+ if (mrb[i]) d({
1804
+ type: "MR_SOURCE_SELECTED",
1805
+ branch: mrb[i].name
1806
+ });
1807
+ }, () => d({
1808
+ type: "SET_MR_BRANCH_OPEN",
1809
+ open: false
1810
+ }));
1811
+ if (n !== void 0) d({
1812
+ type: "SET_MR_BRANCH_INDEX",
1813
+ index: n
1814
+ });
1815
+ }
1816
+ })
1817
+ }), mrb.length > 0 ? mrb.map((b, i) => /* @__PURE__ */ jsxDEV("div", {
1818
+ class: `sel-item${b.name === s.mrSourceBranch ? " active" : ""}${i === s.mrBranchIndex ? " highlighted" : ""}`,
1819
+ onMouseEnter: () => d({
1820
+ type: "SET_MR_BRANCH_INDEX",
1821
+ index: i
1822
+ }),
1823
+ onClick: () => d({
1824
+ type: "MR_SOURCE_SELECTED",
1825
+ branch: b.name
1826
+ }),
1827
+ children: [/* @__PURE__ */ jsxDEV("span", {
1828
+ class: "sel-item-name",
1829
+ children: b.name
1830
+ }), b.default && /* @__PURE__ */ jsxDEV("span", {
1831
+ style: "font-size:10px;color:var(--neon);margin-left:6px",
1832
+ children: t("web.defaultBranch")
1833
+ })]
1834
+ })) : /* @__PURE__ */ jsxDEV("div", {
1835
+ class: "sel-empty",
1836
+ children: t("web.noBranches")
1837
+ })]
1838
+ })]
1839
+ })]
1840
+ });
1841
+ })(),
1842
+ s.mrStatus === "selecting" && s.mrSourceBranch && /* @__PURE__ */ jsxDEV("div", {
1843
+ style: "margin-top:8px",
1844
+ children: [/* @__PURE__ */ jsxDEV("div", {
1845
+ style: "font-size:13px;color:var(--text-2);margin-bottom:6px",
1846
+ children: t("release.mrFromTo", {
1847
+ source: s.mrSourceBranch,
1848
+ target: s.selectedBranch
1849
+ })
1850
+ }), /* @__PURE__ */ jsxDEV("button", {
1851
+ class: "jira-btn",
1852
+ type: "button",
1853
+ style: "background:var(--cyan);font-size:13px;padding:4px 12px",
1854
+ onClick: () => d({ type: "MR_CREATING" }),
1855
+ children: t("release.confirmCreateMr")
1856
+ })]
1857
+ }),
1858
+ s.mrStatus === "creating" && /* @__PURE__ */ jsxDEV("div", {
1859
+ class: "loading-row",
1860
+ style: "margin-top:12px",
1861
+ children: [/* @__PURE__ */ jsxDEV("span", { class: "spinner" }), t("release.creatingMrBtn")]
1862
+ }),
1863
+ s.mrStatus === "done" && s.mrUrl && /* @__PURE__ */ jsxDEV("div", {
1864
+ class: "jira-result",
1865
+ style: "margin-top:12px",
1866
+ children: [/* @__PURE__ */ jsxDEV("div", {
1867
+ class: "jira-result-label",
1868
+ children: "MR"
1869
+ }), /* @__PURE__ */ jsxDEV("a", {
1870
+ class: "jira-result-key",
1871
+ href: s.mrUrl,
1872
+ target: "_blank",
1873
+ rel: "noreferrer",
1874
+ children: t("release.mrFromTo", {
1875
+ source: s.mrSourceBranch,
1876
+ target: s.selectedBranch
1877
+ })
1878
+ })]
1879
+ }),
1880
+ s.mrStatus === "error" && s.mrError && /* @__PURE__ */ jsxDEV("div", {
1881
+ class: "jira-error",
1882
+ role: "alert",
1883
+ style: "margin-top:12px",
1884
+ children: s.mrError
1885
+ })
1886
+ ]
1887
+ }),
1888
+ !s.selected && /* @__PURE__ */ jsxDEV("div", {
1889
+ class: "empty-hint",
1890
+ children: t("web.emptyHint")
1891
+ })
1892
+ ] });
1893
+ };
1894
+ const ReleaseClient = () => {
1895
+ const [s, d] = useReducer(reducer, initial);
1896
+ useEffect(() => {
1897
+ fetch("/release/api/history").then((r) => r.json()).then((data) => d({
1898
+ type: "SET_HISTORY",
1899
+ history: Array.isArray(data) ? data : []
1900
+ })).catch(() => d({
1901
+ type: "SET_HISTORY",
1902
+ history: []
1903
+ }));
1904
+ }, []);
1905
+ return /* @__PURE__ */ jsxDEV("div", { children: [
1906
+ /* @__PURE__ */ jsxDEV("style", { children: releaseStyle }),
1907
+ /* @__PURE__ */ jsxDEV("div", {
1908
+ class: "page-header",
1909
+ children: [/* @__PURE__ */ jsxDEV("h2", { children: t("web.releaseTitle") }), /* @__PURE__ */ jsxDEV("p", { children: t("web.releaseDesc") })]
1910
+ }),
1911
+ s.historyLoading ? /* @__PURE__ */ jsxDEV("div", {
1912
+ class: "loading-row",
1913
+ children: [/* @__PURE__ */ jsxDEV("span", { class: "spinner" }), t("web.loading")]
1914
+ }) : s.showNewModal ? /* @__PURE__ */ jsxDEV("div", {
1915
+ class: "modal-overlay",
1916
+ onClick: (e) => {
1917
+ if (e.target.classList.contains("modal-overlay")) fetch("/release/api/history").then((r) => r.json()).then((data) => {
1918
+ d({
1919
+ type: "SET_HISTORY",
1920
+ history: Array.isArray(data) ? data : []
1921
+ });
1922
+ d({ type: "HIDE_NEW_MODAL" });
1923
+ }).catch(() => d({ type: "HIDE_NEW_MODAL" }));
1924
+ },
1925
+ children: /* @__PURE__ */ jsxDEV("div", {
1926
+ class: "modal-content",
1927
+ children: [/* @__PURE__ */ jsxDEV("div", {
1928
+ class: "modal-header",
1929
+ children: [/* @__PURE__ */ jsxDEV("span", {
1930
+ class: "modal-title",
1931
+ children: t("web.newModalTitle")
1932
+ }), /* @__PURE__ */ jsxDEV("button", {
1933
+ class: "modal-close",
1934
+ type: "button",
1935
+ onClick: () => {
1936
+ fetch("/release/api/history").then((r) => r.json()).then((data) => {
1937
+ d({
1938
+ type: "SET_HISTORY",
1939
+ history: Array.isArray(data) ? data : []
1940
+ });
1941
+ d({ type: "HIDE_NEW_MODAL" });
1942
+ }).catch(() => d({ type: "HIDE_NEW_MODAL" }));
1943
+ },
1944
+ children: "✕"
1945
+ })]
1946
+ }), /* @__PURE__ */ jsxDEV(ReleaseFlow, {
1947
+ s,
1948
+ d
1949
+ })]
1950
+ })
1951
+ }) : s.history.length > 0 ? /* @__PURE__ */ jsxDEV(HistoryList, {
1952
+ s,
1953
+ d
1954
+ }) : /* @__PURE__ */ jsxDEV(ReleaseFlow, {
1955
+ s,
1956
+ d
1957
+ })
1958
+ ] });
1959
+ };
1960
+ const mount = async (el) => {
1961
+ await initPromise;
1962
+ render(/* @__PURE__ */ jsxDEV(ReleaseClient, {}), el);
1963
+ };
1964
+ //#endregion
1965
+ export { mount };