-
Notifications
You must be signed in to change notification settings - Fork 410
RI-7614 Introduce shared commands history (for Search and Workbench) #5057
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
5f6d57f
2ab6faf
29af575
dd09d60
0057330
3530f38
d781313
adaa5b4
c16afe3
93a1318
f3d6c9f
bec64b6
eddc5f3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| import { CommandExecutionType } from 'uiSrc/slices/interfaces' | ||
| import { CommandsHistoryDatabase, CommandHistoryResult } from './interface' | ||
|
|
||
| export class CommandsHistoryIndexedDB implements CommandsHistoryDatabase { | ||
| async getCommandsHistory( | ||
| instanceId: string, | ||
| commandExecutionType: CommandExecutionType, | ||
| ): Promise<CommandHistoryResult> { | ||
| // TODO: Implementation for fetching command history from IndexedDB | ||
valkirilov marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return Promise.resolve({ | ||
| success: true, | ||
| data: [], | ||
| }) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| import { AxiosError } from 'axios' | ||
|
|
||
| import apiService from 'uiSrc/services/apiService' | ||
| import { ApiEndpoints } from 'uiSrc/constants' | ||
| import { getUrl, isStatusSuccessful } from 'uiSrc/utils' | ||
| import { | ||
| CommandExecution, | ||
| CommandExecutionType, | ||
| CommandExecutionUI, | ||
| } from 'uiSrc/slices/interfaces' | ||
|
|
||
| import { mapCommandExecutionToUI } from '../utils/command-execution.mapper' | ||
| import { CommandsHistoryDatabase, CommandHistoryResult } from './interface' | ||
|
|
||
| export class CommandsHistorySQLite implements CommandsHistoryDatabase { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is an i(example) implementation of the service that should work with the Commands History stored in the SQLite database. It should follow the common interface and keep all of the business login encapsulated inside it. |
||
| async getCommandsHistory( | ||
| instanceId: string, | ||
| commandExecutionType: CommandExecutionType, | ||
| ): Promise<CommandHistoryResult> { | ||
| try { | ||
| const url = getUrl(instanceId, ApiEndpoints.WORKBENCH_COMMAND_EXECUTIONS) | ||
| const config = { params: { type: commandExecutionType } } | ||
|
|
||
| const { data, status } = await apiService.get<CommandExecution[]>( | ||
| url, | ||
| config, | ||
| ) | ||
|
|
||
| if (isStatusSuccessful(status)) { | ||
| const results: CommandExecutionUI[] = data.map(mapCommandExecutionToUI) | ||
|
|
||
| return { success: true, data: results } | ||
| } | ||
|
|
||
| return { | ||
| success: false, | ||
| error: new Error(`Request failed with status ${status}`), | ||
| } | ||
| } catch (exception) { | ||
| return { | ||
| success: false, | ||
| error: exception as AxiosError, | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import { AxiosError } from 'axios' | ||
| import { | ||
| CommandExecutionType, | ||
| CommandExecutionUI, | ||
| } from 'uiSrc/slices/interfaces' | ||
|
|
||
| export interface CommandsHistoryDatabase { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the interface that every service should comply with. It's basic CRUD, simple as that. And it's independent from the data source behind it. |
||
| getCommandsHistory( | ||
| instanceId: string, | ||
| commandExecutionType: CommandExecutionType, | ||
| ): Promise<CommandHistoryResult> | ||
| } | ||
|
|
||
| export interface CommandHistoryResult { | ||
| success: boolean | ||
| data?: CommandExecutionUI[] | ||
| error?: Error | AxiosError | any | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| import { | ||
| CommandExecutionType, | ||
| CommandExecutionUI, | ||
| } from 'uiSrc/slices/interfaces' | ||
| import { CommandsHistorySQLite } from '../database/CommandsHistorySQLite' | ||
| import { appFeatureFlagsFeaturesSelector } from 'uiSrc/slices/app/features' | ||
| import { useDispatch, useSelector } from 'react-redux' | ||
| import { useEffect } from 'react' | ||
| import { CommandsHistoryDatabase } from '../database/interface' | ||
| import { CommandsHistoryIndexedDB } from '../database/CommandsHistoryIndexedDB' | ||
| import { FeatureFlags } from 'uiSrc/constants/featureFlags' | ||
| import { addErrorNotification } from 'uiSrc/slices/app/notifications' | ||
|
|
||
| interface CommandHistoryProps { | ||
| commandExecutionType: CommandExecutionType | ||
| } | ||
|
|
||
| interface CommandsHistoryHook { | ||
| getCommandsHistory: (instanceId: string) => Promise<CommandExecutionUI[]> | ||
| } | ||
|
|
||
| export const useCommandsHistory = ({ | ||
valkirilov marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| commandExecutionType, | ||
| }: CommandHistoryProps): CommandsHistoryHook => { | ||
| let commandsHistoryDatabase: CommandsHistoryDatabase | ||
|
|
||
| const dispatch = useDispatch() | ||
| const { [FeatureFlags.envDependent]: envDependentFeature } = useSelector( | ||
| appFeatureFlagsFeaturesSelector, | ||
| ) | ||
|
|
||
| useEffect(() => { | ||
| if (envDependentFeature?.flag) { | ||
| commandsHistoryDatabase = new CommandsHistorySQLite() | ||
| } else { | ||
| commandsHistoryDatabase = new CommandsHistoryIndexedDB() | ||
| } | ||
| }, [envDependentFeature]) | ||
|
|
||
| const getCommandsHistory = async (instanceId: string) => { | ||
| const { data, error } = await commandsHistoryDatabase.getCommandsHistory( | ||
| instanceId, | ||
| commandExecutionType, | ||
| ) | ||
|
|
||
| if (error) { | ||
| dispatch(addErrorNotification(error)) | ||
| } | ||
|
|
||
| return data || [] | ||
| } | ||
valkirilov marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| return { | ||
| getCommandsHistory, | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| import { EMPTY_COMMAND } from 'uiSrc/constants' | ||
| import { CommandExecution, CommandExecutionUI } from 'uiSrc/slices/interfaces' | ||
|
|
||
| export const mapCommandExecutionToUI = ( | ||
| item: CommandExecution, | ||
| ): CommandExecutionUI => { | ||
| return { | ||
| ...item, | ||
| command: item.command || EMPTY_COMMAND, | ||
| emptyCommand: !item.command, | ||
valkirilov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My goal is to preserve the current way of managing command history through the Search page (with this hook) while modifying only the underlying logic responsible for interacting with the data store.
This approach ensures that the existing components remain unchanged, while simultaneously achieving the goal of having an independent data store that can be easily changed via a feature flag.
And of course, by design, this hook (and the components that depend on it) remain unaware of this information, and they will not be affected by any future changes of the data source behind it.