Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
39cb59f
feat(web-shell): add cell value dialog on double-click in markdown ta…
jifeng Jul 8, 2026
fd174f2
Merge remote-tracking branch 'origin/main' into feat/web-shell-cell-d…
jifeng Jul 8, 2026
792a7db
Merge remote-tracking branch 'origin/main' into feat/web-shell-cell-d…
jifeng Jul 8, 2026
6322905
fix(web-shell): improve table cell dialog interactions
jifeng Jul 8, 2026
4bc7e12
Merge remote-tracking branch 'origin/main' into feat/web-shell-cell-d…
jifeng Jul 8, 2026
1b8b837
fix(web-shell): portal table cell dialog
jifeng Jul 8, 2026
b667c24
Merge remote-tracking branch 'origin/main' into feat/web-shell-cell-d…
jifeng Jul 8, 2026
1a99094
Merge remote-tracking branch 'origin/main' into feat/web-shell-cell-d…
jifeng Jul 8, 2026
0f2a025
fix(web-shell): block shortcuts behind cell dialog
jifeng Jul 9, 2026
5d209e1
fix(web-shell): resolve merge conflict with origin/main in App.tsx
qwen-code-dev-bot Jul 9, 2026
bb67831
Merge branch 'main' into feat/web-shell-cell-dialog
wenshao Jul 10, 2026
ab9a82a
Merge branch 'main' into feat/web-shell-cell-dialog
wenshao Jul 10, 2026
1804342
merge: resolve conflicts with origin/main for cell dialog feature
qwen-code-dev-bot Jul 10, 2026
3c21322
merge: resolve conflicts with origin/main for cell dialog feature
qwen-code-dev-bot Jul 11, 2026
8c246f5
Merge remote-tracking branch 'origin/main' into feat/web-shell-cell-d…
jifeng Jul 11, 2026
71c8904
merge: resolve conflicts with origin/main for cell dialog feature
qwen-code-dev-bot Jul 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -453,9 +453,7 @@ tr:hover .selectedCell {

.evenRow .stickyActionCell,
.evenRow .frozenCell {
background:
linear-gradient(var(--subtle-bg), var(--subtle-bg)),
var(--card);
background: linear-gradient(var(--subtle-bg), var(--subtle-bg)), var(--card);
}

tr:hover .stickyActionCell,
Expand Down Expand Up @@ -535,9 +533,157 @@ tr:hover .frozenCell.selectedCell {
white-space: pre-wrap;
}

.cellDialogBackdrop {
position: fixed;
inset: 0;
z-index: 80;
Comment thread
jifeng marked this conversation as resolved.
Resolved
display: flex;
align-items: center;
justify-content: center;
padding: 16px;
background: color-mix(in srgb, var(--background) 62%, transparent);
}

.cellDialog {
position: relative;
box-sizing: border-box;
display: flex;
flex-direction: column;
width: min(520px, calc(100vw - 32px));
min-height: 190px;
padding: 20px 24px 16px;
border: 1px solid color-mix(in srgb, var(--border) 75%, transparent);
border-radius: 10px;
background: linear-gradient(
135deg,
color-mix(in srgb, var(--card) 96%, white 4%),
color-mix(in srgb, var(--card) 92%, black 8%)
);
box-shadow: 0 18px 56px rgb(0 0 0 / 38%);
color: var(--foreground);
font-size: 13px;
}

.cellDialogCloseIcon {
position: absolute;
top: 12px;
right: 14px;
display: grid;
width: 24px;
height: 24px;
place-items: center;
border: 0;
background: transparent;
color: var(--muted-foreground);
font: inherit;
font-size: 24px;
line-height: 1;
cursor: pointer;
}

.cellDialogCloseIcon:hover {
color: var(--foreground);
}

.cellDialogTitle {
margin-bottom: 16px;
font-size: inherit;
font-weight: 800;
line-height: 1.2;
}

.cellDialogValue {
min-height: 100px;
max-height: min(32vh, 200px);
overflow: auto;
padding: 10px 12px;
border: 1px solid color-mix(in srgb, var(--border) 82%, transparent);
border-radius: 8px;
background: color-mix(in srgb, var(--background) 72%, transparent);
color: var(--foreground);
font: inherit;
font-weight: 600;
line-height: 1.45;
cursor: text;
user-select: text;
white-space: pre-wrap;
overflow-wrap: anywhere;
}

.cellDialogFooter {
display: flex;
justify-content: flex-end;
gap: 10px;
align-items: center;
margin-top: auto;
padding-top: 20px;
}

.cellDialogActions {
display: flex;
gap: 12px;
align-items: center;
}

.cellDialogButton {
min-width: 64px;
padding: 6px 14px;
border: 0;
border-radius: 6px;
background: color-mix(in srgb, var(--foreground) 12%, transparent);
color: var(--foreground);
font: inherit;
font-weight: 700;
cursor: pointer;
}

.cellDialogButton:hover {
background: color-mix(in srgb, var(--foreground) 18%, transparent);
}

.cellDialogPrimaryButton {
background: var(--agent-blue-500);
color: white;
}

.cellDialogPrimaryButton:hover {
background: color-mix(in srgb, var(--agent-blue-500) 86%, white 14%);
}

.emptyState {
padding: 16px;
color: var(--muted-foreground);
font-size: 13px;
text-align: center;
}

@media (max-width: 640px) {
.cellDialogBackdrop {
padding: 10px;
}

.cellDialog {
width: 100%;
min-height: 0;
padding: 20px 14px 14px;
}

.cellDialogTitle {
margin-bottom: 14px;
}

.cellDialogFooter {
flex-direction: column;
align-items: stretch;
padding-top: 18px;
}

.cellDialogActions {
justify-content: flex-end;
}

.cellDialogButton {
min-width: 0;
padding: 6px 12px;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ function click(el: Element): void {
});
}

function doubleClick(el: Element): void {
act(() => {
el.dispatchEvent(new MouseEvent('dblclick', { bubbles: true }));
});
}

function inputValue(input: HTMLInputElement, value: string): void {
const setter = Object.getOwnPropertyDescriptor(
HTMLInputElement.prototype,
Expand Down Expand Up @@ -681,6 +687,58 @@ describe('EnhancedMarkdownTable', () => {
).toBeDefined();
});

it('opens a selectable cell value dialog on double click', () => {
const container = renderTable();

doubleClick(dataCell(container, 0, 0));

const dialog = container.querySelector<HTMLElement>('[role="dialog"]');
expect(dialog).not.toBeNull();
expect(dialog?.textContent).toContain('Current field value');
expect(dialog?.textContent).toContain('Alpha');
});

it('copies the current cell value from the dialog', () => {
const writeText = mockClipboard();
const container = renderTable();

doubleClick(dataCell(container, 1, 0));
click(textButton(container, 'Copy'));

expect(writeText).toHaveBeenCalledWith('Beta');
});

it('closes the cell value dialog with Escape', () => {
const container = renderTable();

doubleClick(dataCell(container, 0, 0));
expect(container.querySelector('[role="dialog"]')).not.toBeNull();

act(() => {
document.dispatchEvent(
new KeyboardEvent('keydown', { bubbles: true, key: 'Escape' }),
);
});

expect(container.querySelector('[role="dialog"]')).toBeNull();
});

it('clears table selection and row details when opening a cell dialog', () => {
const container = renderTable();

dragCells(dataCell(container, 0, 0), dataCell(container, 0, 0));
expect(container.textContent).toContain('1 cell selected');

click(button(container, 'View details for row 1'));
expect(container.textContent).toContain('Row details');

doubleClick(dataCell(container, 0, 0));

expect(container.textContent).not.toContain('1 cell selected');
expect(container.textContent).not.toContain('Row details');
expect(container.querySelector('[role="dialog"]')).not.toBeNull();
});

it('quick copies the visible sorted table', () => {
const writeText = mockClipboard();
const container = renderTable();
Expand Down Expand Up @@ -978,7 +1036,10 @@ describe('EnhancedMarkdownTable', () => {
const source = renderWideTable();
const target = renderWideTable();

dragColumnElements(button(source, 'Move Score'), button(target, 'Move Team'));
dragColumnElements(
button(source, 'Move Score'),
button(target, 'Move Team'),
);

expect(rowTexts(source)).toEqual(['Alpha|US|10', 'Beta|EMEA|2']);
expect(rowTexts(target)).toEqual(['Alpha|US|10', 'Beta|EMEA|2']);
Expand Down
Loading
Loading