Skip to content

Commit cedcdba

Browse files
committed
Merge branch 'main' into e2e/feature/RI-3932_import-ssh-parameters
2 parents c5ca294 + f79602b commit cedcdba

File tree

72 files changed

+1269
-311
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+1269
-311
lines changed

redisinsight/api/config/default.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,14 @@ export default {
108108
},
109109
guides: {
110110
updateUrl: process.env.GUIDES_UPDATE_URL
111-
|| 'https://github.com/RedisInsight/Guides/releases/download/latest',
111+
|| 'https://github.com/RedisInsight/Guides/releases/download/release',
112112
zip: process.env.GUIDES_ZIP || dataZipFileName,
113113
buildInfo: process.env.GUIDES_CHECKSUM || buildInfoFileName,
114114
devMode: !!process.env.GUIDES_DEV_PATH,
115115
},
116116
tutorials: {
117117
updateUrl: process.env.TUTORIALS_UPDATE_URL
118-
|| 'https://github.com/RedisInsight/Tutorials/releases/download/latest',
118+
|| 'https://github.com/RedisInsight/Tutorials/releases/download/release',
119119
zip: process.env.TUTORIALS_ZIP || dataZipFileName,
120120
buildInfo: process.env.TUTORIALS_CHECKSUM || buildInfoFileName,
121121
devMode: !!process.env.TUTORIALS_DEV_PATH,

redisinsight/api/src/modules/workbench/dto/create-command-execution.dto.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export enum RunQueryMode {
1919
export enum ResultsMode {
2020
Default = 'DEFAULT',
2121
GroupMode = 'GROUP_MODE',
22+
Silent = 'SILENT',
2223
}
2324

2425
export class CreateCommandExecutionDto {

redisinsight/api/src/modules/workbench/workbench.service.spec.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,18 @@ const mockCreateCommandExecutionDtoWithGroupMode: CreateCommandExecutionsDto = {
5151
resultsMode: ResultsMode.GroupMode,
5252
};
5353

54+
const mockCreateCommandExecutionDtoWithSilentMode: CreateCommandExecutionsDto = {
55+
commands: mockCommands,
56+
nodeOptions: {
57+
host: '127.0.0.1',
58+
port: 7002,
59+
enableRedirection: true,
60+
},
61+
role: ClusterNodeRole.All,
62+
mode: RunQueryMode.ASCII,
63+
resultsMode: ResultsMode.Silent,
64+
};
65+
5466
const mockCreateCommandExecutionsDto: CreateCommandExecutionsDto = {
5567
commands: [
5668
mockCreateCommandExecutionDto.command,
@@ -101,6 +113,21 @@ const mockCommandExecutionWithGroupMode = {
101113
}],
102114
};
103115

116+
const mockCommandExecutionWithSilentMode = {
117+
mode: 'ASCII',
118+
commands: mockCommands,
119+
resultsMode: 'GROUP_MODE',
120+
databaseId: 'd05043d0 - 0d12- 4ce1-9ca3 - 30c6d7e391ea',
121+
summary: { total: 2, success: 1, fail: 1 },
122+
command: 'set 1 1\r\nget 1',
123+
result: [{
124+
status: 'success',
125+
response: [
126+
{ response: 'error', status: 'fail', command: 'get 1' },
127+
],
128+
}],
129+
};
130+
104131
const mockCommandExecutionProvider = () => ({
105132
createMany: jest.fn(),
106133
getList: jest.fn(),
@@ -215,6 +242,21 @@ describe('WorkbenchService', () => {
215242
expect(result).toEqual([mockCommandExecutionWithGroupMode]);
216243
});
217244

245+
it('should successfully execute commands and save in silent mode view', async () => {
246+
when(workbenchCommandsExecutor.sendCommand)
247+
.calledWith(mockWorkbenchClientMetadata, expect.anything())
248+
.mockResolvedValue([mockSendCommandResultSuccess]);
249+
250+
commandExecutionProvider.createMany.mockResolvedValueOnce([mockCommandExecutionWithSilentMode]);
251+
252+
const result = await service.createCommandExecutions(
253+
mockWorkbenchClientMetadata,
254+
mockCreateCommandExecutionDtoWithSilentMode,
255+
);
256+
257+
expect(result).toEqual([mockCommandExecutionWithSilentMode]);
258+
});
259+
218260
it('should successfully execute commands with error and save summary', async () => {
219261
when(workbenchCommandsExecutor.sendCommand)
220262
.calledWith(mockWorkbenchClientMetadata, {
@@ -240,6 +282,31 @@ describe('WorkbenchService', () => {
240282
expect(result).toEqual([mockCommandExecutionWithGroupMode]);
241283
});
242284

285+
it('should successfully execute commands with error and save summary in silent mode view', async () => {
286+
when(workbenchCommandsExecutor.sendCommand)
287+
.calledWith(mockWorkbenchClientMetadata, {
288+
...mockCreateCommandExecutionDtoWithSilentMode,
289+
command: mockCommands[0],
290+
})
291+
.mockResolvedValue([mockSendCommandResultSuccess]);
292+
293+
when(workbenchCommandsExecutor.sendCommand)
294+
.calledWith(mockWorkbenchClientMetadata, {
295+
...mockCreateCommandExecutionDtoWithSilentMode,
296+
command: mockCommands[1],
297+
})
298+
.mockResolvedValue([mockSendCommandResultFail]);
299+
300+
commandExecutionProvider.createMany.mockResolvedValueOnce([mockCommandExecutionWithSilentMode]);
301+
302+
const result = await service.createCommandExecutions(
303+
mockWorkbenchClientMetadata,
304+
mockCreateCommandExecutionDtoWithSilentMode,
305+
);
306+
307+
expect(result).toEqual([mockCommandExecutionWithSilentMode]);
308+
});
309+
243310
it('should throw an error when command execution failed', async () => {
244311
workbenchCommandsExecutor.sendCommand.mockRejectedValueOnce(new BadRequestException('error'));
245312

redisinsight/api/src/modules/workbench/workbench.service.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,13 @@ export class WorkbenchService {
6363
* @param clientMetadata
6464
* @param dto
6565
* @param commands
66+
* @param onlyErrorResponse
6667
*/
6768
async createCommandsExecution(
6869
clientMetadata: ClientMetadata,
6970
dto: Partial<CreateCommandExecutionDto>,
7071
commands: string[],
72+
onlyErrorResponse: boolean = false,
7173
): Promise<Partial<CommandExecution>> {
7274
const commandExecution: Partial<CommandExecution> = {
7375
...dto,
@@ -114,7 +116,7 @@ export class WorkbenchService {
114116
commandExecution.command = commands.join('\r\n');
115117
commandExecution.result = [{
116118
status: CommandExecutionStatus.Success,
117-
response: executionResults,
119+
response: onlyErrorResponse ? failedCommands : executionResults,
118120
}];
119121

120122
return commandExecution;
@@ -134,9 +136,9 @@ export class WorkbenchService {
134136
// temporary workaround. Just create client before any command execution precess
135137
await this.databaseConnectionService.getOrCreateClient(clientMetadata);
136138

137-
if (dto.resultsMode === ResultsMode.GroupMode) {
139+
if (dto.resultsMode === ResultsMode.GroupMode || dto.resultsMode === ResultsMode.Silent) {
138140
return this.commandExecutionProvider.createMany(
139-
[await this.createCommandsExecution(clientMetadata, dto, dto.commands)],
141+
[await this.createCommandsExecution(clientMetadata, dto, dto.commands, dto.resultsMode === ResultsMode.Silent)],
140142
);
141143
}
142144
// todo: rework to support pipeline

redisinsight/api/test/api/plugins/POST-databases-id-plugins-command_executions.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const dataSchema = Joi.object({
2121
command: Joi.string().required(),
2222
role: Joi.string().valid('ALL', 'MASTER', 'SLAVE').allow(null),
2323
mode: Joi.string().valid('RAW', 'ASCII').allow(null),
24-
resultsMode: Joi.string().valid('DEFAULT', 'GROUP_MODE').allow(null),
24+
resultsMode: Joi.string().valid('DEFAULT', 'GROUP_MODE', 'SILENT').allow(null),
2525
nodeOptions: Joi.object().keys({
2626
host: Joi.string().required(),
2727
// todo: fix BE transform to avoid handle boolean as number
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 10 additions & 0 deletions
Loading

redisinsight/ui/src/components/database-overview/styles.module.scss

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
}
2121

2222
.overview {
23-
&.noModules, &.RediStack {
23+
&.noModules,
24+
&.RediStack {
2425
.overviewItem {
2526
&:last-child {
2627
border-right: 1px solid var(--separatorColor);
@@ -74,9 +75,9 @@
7475
.commandsPerSecTip {
7576
margin-bottom: 8px;
7677

77-
&:last-child {
78-
margin-bottom: 0;
79-
}
78+
&:last-child {
79+
margin-bottom: 0;
80+
}
8081
.moreInfoOverviewIcon {
8182
margin-right: 8px;
8283
width: auto !important;
@@ -99,6 +100,13 @@
99100

100101
.RediStackLogoWrapper {
101102
padding: 0 6px;
103+
cursor: pointer;
104+
transition: transform 250ms ease-in-out;
105+
106+
&:hover {
107+
transform: translateY(-1px);
108+
}
109+
102110
.redistackLogoIcon {
103111
width: 24px;
104112
height: 24px;
@@ -124,4 +132,3 @@
124132
display: none !important;
125133
}
126134
}
127-

redisinsight/ui/src/components/query-card/QueryCard.tsx

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import {
1010
getWBQueryType,
1111
getVisualizationsByCommand,
1212
Maybe,
13-
isGroupMode
13+
isGroupResults,
14+
isSilentModeWithoutError,
1415
} from 'uiSrc/utils'
1516
import { appPluginsSelector } from 'uiSrc/slices/app/plugins'
1617
import { CommandExecutionResult, IPluginVisualization } from 'uiSrc/slices/interfaces'
@@ -47,10 +48,14 @@ export interface Props {
4748
const getDefaultPlugin = (views: IPluginVisualization[], query: string) =>
4849
getVisualizationsByCommand(query, views).find((view) => view.default)?.uniqId || ''
4950

50-
export const getSummaryText = (summary?: ResultsSummary) => {
51+
export const getSummaryText = (summary?: ResultsSummary, mode?: ResultsMode) => {
5152
if (summary) {
5253
const { total, success, fail } = summary
53-
return `${total} Command(s) - ${success} success, ${fail} error(s)`
54+
const summaryText = `${total} Command(s) - ${success} success`
55+
if (!isSilentModeWithoutError(mode, summary?.fail)) {
56+
return `${summaryText}, ${fail} error(s)`
57+
}
58+
return summaryText
5459
}
5560
return summary
5661
}
@@ -82,7 +87,7 @@ const QueryCard = (props: Props) => {
8287
const [isFullScreen, setIsFullScreen] = useState<boolean>(false)
8388
const [queryType, setQueryType] = useState<WBQueryType>(getWBQueryType(command, visualizations))
8489
const [viewTypeSelected, setViewTypeSelected] = useState<WBQueryType>(queryType)
85-
const [summaryText, setSummaryText] = useState<string>('')
90+
const [message, setMessage] = useState<string>('')
8691
const [selectedViewValue, setSelectedViewValue] = useState<string>(
8792
getDefaultPlugin(visualizations, command || '') || queryType
8893
)
@@ -130,7 +135,7 @@ const QueryCard = (props: Props) => {
130135
}, [visualizations])
131136

132137
const toggleOpen = () => {
133-
if (isFullScreen) return
138+
if (isFullScreen || isSilentModeWithoutError(resultsMode, summary?.fail)) return
134139

135140
dispatch(toggleOpenWBResult(id))
136141

@@ -162,14 +167,16 @@ const QueryCard = (props: Props) => {
162167
query={command}
163168
loading={loading}
164169
createdAt={createdAt}
165-
summaryText={summaryText}
170+
message={message}
166171
queryType={queryType}
167172
selectedValue={selectedViewValue}
168173
activeMode={activeMode}
169174
mode={mode}
175+
resultsMode={resultsMode}
170176
activeResultsMode={activeResultsMode}
171177
emptyCommand={emptyCommand}
172-
summary={getSummaryText(summary)}
178+
summary={summary}
179+
summaryText={getSummaryText(summary, resultsMode)}
173180
executionTime={executionTime}
174181
toggleOpen={toggleOpen}
175182
toggleFullScreen={toggleFullScreen}
@@ -179,11 +186,11 @@ const QueryCard = (props: Props) => {
179186
/>
180187
{isOpen && (
181188
<>
182-
{React.isValidElement(commonError) && !isGroupMode(resultsMode)
189+
{React.isValidElement(commonError) && !isGroupResults(resultsMode)
183190
? <QueryCardCommonResult loading={loading} result={commonError} />
184191
: (
185192
<>
186-
{isGroupMode(resultsMode) && (
193+
{isGroupResults(resultsMode) && (
187194
<QueryCardCliResultWrapper
188195
loading={loading}
189196
query={command}
@@ -203,7 +210,7 @@ const QueryCard = (props: Props) => {
203210
id={selectedViewValue}
204211
result={result}
205212
query={command}
206-
setSummaryText={setSummaryText}
213+
setMessage={setMessage}
207214
commandId={id}
208215
/>
209216
) : (

redisinsight/ui/src/components/query-card/QueryCardCliPlugin/QueryCardCliPlugin.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export interface Props {
2525
result: CommandExecutionResult[]
2626
query: any
2727
id: string
28-
setSummaryText: (text: string) => void
28+
setMessage: (text: string) => void
2929
commandId: string
3030
}
3131

@@ -43,7 +43,7 @@ enum ActionTypes {
4343
const baseUrl = getBaseApiUrl()
4444

4545
const QueryCardCliPlugin = (props: Props) => {
46-
const { query, id, result, setSummaryText, commandId } = props
46+
const { query, id, result, setMessage, commandId } = props
4747
const { visualizations = [], staticPath } = useSelector(appPluginsSelector)
4848
const { modules = [] } = useSelector(connectedInstanceSelector)
4949
const serverInfo = useSelector(appServerInfoSelector)
@@ -177,7 +177,7 @@ const QueryCardCliPlugin = (props: Props) => {
177177
})
178178

179179
pluginApi.onEvent(generatedIframeNameRef.current, PluginEvents.setHeaderText, (text: string) => {
180-
setSummaryText(text)
180+
setMessage(text)
181181
})
182182

183183
pluginApi.onEvent(generatedIframeNameRef.current, PluginEvents.executeRedisCommand, sendRedisCommand)

0 commit comments

Comments
 (0)