Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions redisinsight/api/src/__mocks__/workbench.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const mockCommandExecutionSuccessResult = Object.assign(new CommandExecut
export const mockCommendExecutionHugeResultPlaceholder = Object.assign(new CommandExecutionResult(), {
status: CommandExecutionStatus.Success,
response: 'Results have been deleted since they exceed 1 MB. Re-run the command to see new results.',
sizeLimitExceeded: true,
});

export const mockCommendExecutionHugeResultPlaceholderEncrypted = 'huge_result_placeholder_encrypted';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,11 @@ export class CommandExecutionResult {
})
@Expose()
response: any;

@ApiProperty({
type: Boolean,
description: 'Flag showing if response was replaced with message notification about response size limit threshold',
})
@Expose()
sizeLimitExceeded?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export class LocalCommandExecutionRepository extends CommandExecutionRepository
{
status: CommandExecutionStatus.Success,
response: ERROR_MESSAGES.WORKBENCH_RESPONSE_TOO_BIG(),
sizeLimitExceeded: true,
},
]);
// Hack, do not store isNotStored. Send once to show warning
Expand All @@ -61,7 +62,10 @@ export class LocalCommandExecutionRepository extends CommandExecutionRepository
...(await this.commandExecutionRepository.save(await this.modelEncryptor.encryptEntity(entity))),
command: commandExecutions[idx].command, // avoid decryption
mode: commandExecutions[idx].mode,
result: commandExecutions[idx].result, // avoid decryption + show original response when it was huge
// avoid decryption + show original response when it was huge
// also will return original response even if it wasn't stored
// so flag sizeLimitExceeded will be undefined
result: commandExecutions[idx].result,
summary: commandExecutions[idx].summary,
executionTime: commandExecutions[idx].executionTime,
isNotStored,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ describe('POST /databases/:instanceId/workbench/command-executions', () => {
expect(localDb.encryptData(JSON.stringify([{
status: 'success',
response: 'Results have been deleted since they exceed 1 MB. Re-run the command to see new results.',
sizeLimitExceeded: true,
}]))).to.eql(entity.result);
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { instance, mock } from 'ts-mockito'
import { toggleOpenWBResult } from 'uiSrc/slices/workbench/wb-results'
import { ResultsMode } from 'uiSrc/slices/interfaces/workbench'
import { cleanup, clearStoreActions, fireEvent, mockedStore, render } from 'uiSrc/utils/test-utils'
import { CommandExecutionStatus } from 'uiSrc/slices/interfaces/cli'
import QueryCard, { Props, getSummaryText } from './QueryCard'

const mockedProps = mock<Props>()
Expand Down Expand Up @@ -137,4 +138,41 @@ describe('QueryCard', () => {
expect(queryCommonResultEl).toBeInTheDocument()
expect(queryCliResultEl).not.toBeInTheDocument()
})

it('should render QueryCardCliResult when result reached response size threshold', () => {
const { queryByTestId } = render(
<QueryCard
{...instance(mockedProps)}
resultsMode={ResultsMode.GroupMode}
result={[{
status: CommandExecutionStatus.Success,
response: 'Any message about size limit threshold exceeded',
sizeLimitExceeded: true
}]}
isOpen
command={null}
/>
)
const queryCliResultEl = queryByTestId('query-cli-result')

expect(queryCliResultEl).toBeInTheDocument()
})

it('should render QueryCardCliResult when result reached response size threshold even w/o flag', () => {
const { queryByTestId } = render(
<QueryCard
{...instance(mockedProps)}
resultsMode={ResultsMode.GroupMode}
result={[{
status: CommandExecutionStatus.Success,
response: 'Results have been deleted since they exceed 1 MB. Re-run the command to see new results.',
}]}
isOpen
command={null}
/>
)
const queryCliResultEl = queryByTestId('query-cli-result')

expect(queryCliResultEl).toBeInTheDocument()
})
})
109 changes: 65 additions & 44 deletions redisinsight/ui/src/components/query/query-card/QueryCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,12 @@ const QueryCard = (props: Props) => {

const commonError = CommonErrorResponse(id, command, result)

const isSizeLimitExceededResponse = (result: Maybe<CommandExecutionResult[]>) => {
const resultObj = result?.[0]
// response.includes - to be backward compatible with responses which don't include sizeLimitExceeded flag
return resultObj?.sizeLimitExceeded === true || resultObj?.response?.includes('Results have been deleted')
}

return (
<div
className={cx(styles.containerWrapper, {
Expand Down Expand Up @@ -196,50 +202,65 @@ const QueryCard = (props: Props) => {
? <QueryCardCommonResult loading={loading} result={commonError} />
: (
<>
{isGroupResults(resultsMode) && (
<QueryCardCliResultWrapper
loading={loading}
query={command}
db={db}
resultsMode={resultsMode}
result={result}
isNotStored={isNotStored}
isFullScreen={isFullScreen}
data-testid="group-mode-card"
/>
)}
{(resultsMode === ResultsMode.Default || !resultsMode) && (
<>
{viewTypeSelected === WBQueryType.Plugin && (
<>
{!loading && result !== undefined ? (
<QueryCardCliPlugin
id={selectedViewValue}
result={result}
query={command}
mode={mode}
setMessage={setMessage}
commandId={id}
/>
) : (
<div className={styles.loading}>
<EuiLoadingContent lines={5} data-testid="loading-content" />
</div>
)}
</>
)}
{(viewTypeSelected === WBQueryType.Text) && (
<QueryCardCliResultWrapper
loading={loading}
query={command}
resultsMode={resultsMode}
result={result}
isNotStored={isNotStored}
isFullScreen={isFullScreen}
/>
)}
</>
)}
{isSizeLimitExceededResponse(result)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of nesting 🥲

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. Otherwise we must split/refactor entire component which is time-consuming for such small task.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If any of notices such deep nesting and ternaries being used in the rendering, or anything else that might be a suboptimal practice, but it is done to get it done for now. Please, tag me, so we can discuss it and make a task for it to improve it whenever we have time. Otherwise we'll forget about it and things like these or similar will keep falling through the cracks.
It will also be more productive than emotes ;)
Tagging @pd-redis and @seth-riedel so they can see it as well

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use

(isGroupResults(resultsMode) || isSizeLimitExceededResponse(result)) ? ...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love the initiative, @KIvanow! While I’m slightly skeptical about the 'whenever we have time' part, it’s definitely a step forward. And hey, emojis might be simple, but they’ve got some serious discussion-starting power! 😸✨

? (
<QueryCardCliResultWrapper
loading={loading}
query={command}
resultsMode={resultsMode}
result={result}
isNotStored={isNotStored}
isFullScreen={isFullScreen}
/>
)
: (
<>
{isGroupResults(resultsMode) && (
<QueryCardCliResultWrapper
loading={loading}
query={command}
db={db}
resultsMode={resultsMode}
result={result}
isNotStored={isNotStored}
isFullScreen={isFullScreen}
data-testid="group-mode-card"
/>
)}
{(resultsMode === ResultsMode.Default || !resultsMode) && (
<>
{viewTypeSelected === WBQueryType.Plugin && (
<>
{!loading && result !== undefined ? (
<QueryCardCliPlugin
id={selectedViewValue}
result={result}
query={command}
mode={mode}
setMessage={setMessage}
commandId={id}
/>
) : (
<div className={styles.loading}>
<EuiLoadingContent lines={5} data-testid="loading-content" />
</div>
)}
</>
)}
{(viewTypeSelected === WBQueryType.Text) && (
<QueryCardCliResultWrapper
loading={loading}
query={command}
resultsMode={resultsMode}
result={result}
isNotStored={isNotStored}
isFullScreen={isFullScreen}
/>
)}
</>
)}
</>
)}
</>
)}
</>
Expand Down
Loading