feat(ws): improve message panel UX (#8465)

This commit is contained in:
Pooja
2026-07-06 14:46:27 +05:30
committed by GitHub
parent b1f08b5131
commit 0148ba6510
21 changed files with 164 additions and 4 deletions

View File

@@ -52,7 +52,7 @@ const WSRequestPane = ({ item, collection, handleRun }) => {
currentMessages.push({
uid: uuid(),
name: `message ${currentMessages.length + 1}`,
content: '{}',
content: '',
type: 'json',
selected: true
});

View File

@@ -17,7 +17,7 @@ const Wrapper = styled.div`
}
.selected-body-mode {
color: ${(props) => props.theme.primary.text};
color: ${(props) => props.theme.ws.activeMessage.label};
}
}

View File

@@ -3,6 +3,11 @@ import styled from 'styled-components';
const StyledWrapper = styled.div`
border-bottom: 1px solid ${(props) => props.theme.border.border0};
/* No divider below the last message */
&:last-child {
border-bottom: none;
}
/* Dim the row content when disabled, but not the tooltip */
.accordion-left > :not(.toolhint),
.accordion-actions,
@@ -18,6 +23,13 @@ const StyledWrapper = styled.div`
}
}
&:not(.disabled) .accordion-header {
position: sticky;
top: 0;
z-index: 1;
background: ${(props) => props.theme.bg};
}
.accordion-header {
display: flex;
align-items: center;
@@ -102,7 +114,7 @@ const StyledWrapper = styled.div`
}
&:not(.disabled) .accordion-header .message-label {
color: ${(props) => props.theme.primary.text};
color: ${(props) => props.theme.ws.activeMessage.label};
}
`;

View File

@@ -9,6 +9,7 @@ const Wrapper = styled.div`
.messages-container {
flex: 1;
overflow-y: auto;
isolation: isolate;
}
.empty-state {

View File

@@ -1711,7 +1711,7 @@ export const newWsRequest = (params) => (dispatch, getState) => {
uid: uuid(),
name: 'message 1',
type: 'json',
content: '{}'
content: ''
}
]
},

View File

@@ -75,6 +75,12 @@ const catppuccinFrappeTheme = {
subtle: colors.MAUVE
},
ws: {
activeMessage: {
label: colors.MAUVE
}
},
accents: {
primary: colors.MAUVE
},

View File

@@ -75,6 +75,12 @@ const catppuccinMacchiatoTheme = {
subtle: colors.MAUVE
},
ws: {
activeMessage: {
label: colors.MAUVE
}
},
accents: {
primary: colors.MAUVE
},

View File

@@ -75,6 +75,12 @@ const catppuccinMochaTheme = {
subtle: colors.MAUVE
},
ws: {
activeMessage: {
label: colors.MAUVE
}
},
accents: {
primary: colors.MAUVE
},

View File

@@ -212,6 +212,12 @@ const darkMonochromeTheme = {
}
},
ws: {
activeMessage: {
label: colors.TEXT
}
},
request: {
methods: {
get: '#a3a3a3',

View File

@@ -83,6 +83,12 @@ const darkPastelTheme = {
subtle: colors.BRAND
},
ws: {
activeMessage: {
label: colors.BRAND
}
},
accents: {
primary: colors.BRAND
},

View File

@@ -107,6 +107,12 @@ const darkTheme = {
subtle: palette.primary.SUBTLE
},
ws: {
activeMessage: {
label: palette.primary.TEXT
}
},
accents: {
primary: palette.primary.SOLID
},

View File

@@ -82,6 +82,12 @@ const nordTheme = {
subtle: colors.BRAND
},
ws: {
activeMessage: {
label: colors.BRAND
}
},
accents: {
primary: colors.BRAND
},

View File

@@ -85,6 +85,12 @@ const vscodeDarkTheme = {
subtle: '#005a9e'
},
ws: {
activeMessage: {
label: colors.BRAND_TEXT
}
},
accents: {
primary: colors.BRAND
},

View File

@@ -75,6 +75,12 @@ const catppuccinLatteTheme = {
subtle: colors.MAUVE
},
ws: {
activeMessage: {
label: colors.MAUVE
}
},
accents: {
primary: colors.MAUVE
},

View File

@@ -213,6 +213,12 @@ const lightMonochromeTheme = {
}
},
ws: {
activeMessage: {
label: colors.BRAND
}
},
request: {
methods: {
get: '#525252',

View File

@@ -228,6 +228,12 @@ const lightPastelTheme = {
}
},
ws: {
activeMessage: {
label: colors.BRAND
}
},
request: {
methods: {
get: '#3c9d7c', // Soft emerald - success

View File

@@ -249,6 +249,12 @@ const lightTheme = {
}
},
ws: {
activeMessage: {
label: palette.primary.TEXT
}
},
request: {
methods: {
get: palette.hues.GREEN,

View File

@@ -232,6 +232,12 @@ const vscodeLightTheme = {
}
},
ws: {
activeMessage: {
label: colors.TEXT_LINK
}
},
request: {
methods: {
get: colors.GREEN,

View File

@@ -334,6 +334,22 @@ export const ossSchema = {
additionalProperties: false
},
ws: {
type: 'object',
properties: {
activeMessage: {
type: 'object',
properties: {
label: { type: 'string' }
},
required: ['label'],
additionalProperties: false
}
},
required: ['activeMessage'],
additionalProperties: false
},
requestTabPanel: {
type: 'object',
properties: {

View File

@@ -0,0 +1,19 @@
meta {
name: ws-default-body-request
type: ws
seq: 4
}
ws {
url: ws://localhost:8081/ws
auth: inherit
}
body:ws {
name: message 1
content: '''
{
"foo":"bar"
}
'''
}

View File

@@ -0,0 +1,34 @@
import { expect, test } from '../../playwright';
import { closeAllCollections } from '../utils/page/actions';
const REQ_NAME = /^ws-default-body-request$/;
test.describe('websocket message default body', () => {
test.afterAll(async ({ pageWithUserData: page }) => {
await closeAllCollections(page);
});
test('a newly added message defaults to an empty body showing the placeholder', async ({
pageWithUserData: page
}) => {
// Open the preloaded websocket request
await page.getByTestId('sidebar-collection-row').click();
await page.getByTitle(REQ_NAME).click();
const headers = page.getByTestId(/^ws-message-header-/);
const beforeCount = await headers.count();
await page.getByTestId('ws-add-message').click();
await expect(headers).toHaveCount(beforeCount + 1);
// The newly added message is the last one and auto-expands.
const newBody = page.getByTestId(`ws-message-body-${beforeCount}`);
await expect(newBody).toBeVisible();
const editor = newBody.locator('.CodeMirror');
// Body should be empty (previously defaulted to '{}'); the editor should
// surface the '...' placeholder instead of any '{}' content.
await expect(editor.locator('.CodeMirror-placeholder')).toHaveText('...');
await expect(editor.locator('.CodeMirror-code')).not.toContainText('{}');
});
});