Skip to content

Commit 5eca281

Browse files
committed
feat(ui): reorder api profile
1 parent 966ed76 commit 5eca281

File tree

20 files changed

+572
-103
lines changed

20 files changed

+572
-103
lines changed

webview-ui/src/components/chat/ApiConfigSelector.tsx

Lines changed: 293 additions & 66 deletions
Large diffs are not rendered by default.

webview-ui/src/components/chat/__tests__/ApiConfigSelector.spec.tsx

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ describe("ApiConfigSelector", () => {
346346

347347
// Find the settings button by its icon class within the popover content
348348
const popoverContent = screen.getByTestId("popover-content")
349-
const settingsButton = popoverContent.querySelector('[aria-label="chat:edit"]') as HTMLElement
349+
const settingsButton = popoverContent.querySelector(".codicon-settings-gear") as HTMLElement
350350
expect(settingsButton).toBeInTheDocument()
351351
fireEvent.click(settingsButton)
352352

@@ -444,4 +444,66 @@ describe("ApiConfigSelector", () => {
444444
// Search value should be maintained
445445
expect(searchInput.value).toBe("Config")
446446
})
447+
448+
test("reorders configs in custom mode via drag-and-drop and disables drag after Done", async () => {
449+
const props = {
450+
...defaultProps,
451+
sortMode: "custom" as const,
452+
}
453+
454+
render(<ApiConfigSelector {...props} />)
455+
456+
// Open the dropdown (Popover content is always rendered by the mock, but keep action for parity)
457+
const trigger = screen.getByTestId("dropdown-trigger")
458+
fireEvent.click(trigger)
459+
460+
// Enter reorder mode by clicking the Reorder button
461+
const reorderButton = screen.getByText("apiConfigSelector.reorder")
462+
fireEvent.click(reorderButton)
463+
464+
const content = screen.getByTestId("popover-content")
465+
466+
// Collect list rows
467+
const queryRows = () => Array.from(content.querySelectorAll("[data-config-item]"))
468+
const getNames = (rows: Element[]) =>
469+
rows.map((row) => row.querySelector(".flex-1 span.flex-shrink-0")?.textContent?.trim() || "")
470+
471+
// Initial order should be: pinned "Config 1" first, then "Config 2", "Config 3"
472+
const rowsBefore = queryRows()
473+
const startNames = getNames(rowsBefore)
474+
expect(startNames).toEqual(["Config 1", "Config 2", "Config 3"])
475+
476+
// Move "Config 3" above "Config 2"
477+
const fromIndex = startNames.indexOf("Config 3")
478+
const toIndex = startNames.indexOf("Config 2")
479+
480+
// Create mock dataTransfer object for drag events
481+
const mockDataTransfer = {
482+
effectAllowed: "",
483+
dropEffect: "",
484+
setData: vi.fn(),
485+
}
486+
487+
// Simulate drag and drop with proper dataTransfer mock
488+
fireEvent.dragStart(rowsBefore[fromIndex] as HTMLElement, { dataTransfer: mockDataTransfer })
489+
fireEvent.dragOver(rowsBefore[toIndex] as HTMLElement, { dataTransfer: mockDataTransfer })
490+
fireEvent.dragEnd(rowsBefore[fromIndex] as HTMLElement, { dataTransfer: mockDataTransfer })
491+
492+
// Verify new order reflects the drag operation
493+
await waitFor(() => {
494+
const rowsAfter = queryRows()
495+
const namesAfter = getNames(rowsAfter)
496+
expect(namesAfter).toEqual(["Config 1", "Config 3", "Config 2"])
497+
})
498+
499+
// Click Done to exit reorder mode and ensure items are no longer draggable
500+
const doneButton = screen.getByText("apiConfigSelector.done")
501+
fireEvent.click(doneButton)
502+
503+
const rowsFinal = queryRows()
504+
rowsFinal.forEach((row) => {
505+
// draggable attribute should not be true after exiting reorder mode
506+
expect((row as HTMLElement).getAttribute("draggable")).not.toBe("true")
507+
})
508+
})
447509
})

webview-ui/src/i18n/locales/ca/chat.json

Lines changed: 12 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/de/chat.json

Lines changed: 12 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/en/chat.json

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@
2626
"shareSuccessOrganization": "Organization link copied to clipboard",
2727
"shareSuccessPublic": "Public link copied to clipboard"
2828
},
29-
"unpin": "Unpin",
30-
"pin": "Pin",
3129
"retry": {
3230
"title": "Retry",
3331
"tooltip": "Try the operation again"
@@ -388,5 +386,17 @@
388386
"queuedMessages": {
389387
"title": "Queued Messages:",
390388
"clickToEdit": "Click to edit message"
389+
},
390+
"apiConfigSelector": {
391+
"unpin": "Unpin",
392+
"pin": "Pin",
393+
"sort": "Sort",
394+
"alphabetical": "A–Z",
395+
"custom": "Custom",
396+
"reorder": "Reorder…",
397+
"dragToReorder": "Drag to reorder configurations",
398+
"cancel": "Cancel",
399+
"done": "Done",
400+
"editConfigurations": "Edit configurations"
391401
}
392402
}

webview-ui/src/i18n/locales/es/chat.json

Lines changed: 12 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/fr/chat.json

Lines changed: 12 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/hi/chat.json

Lines changed: 12 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/id/chat.json

Lines changed: 12 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/it/chat.json

Lines changed: 12 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)