diff --git a/changelogs/fragments/7859.yml b/changelogs/fragments/7859.yml new file mode 100644 index 000000000000..5cfbc30b4834 --- /dev/null +++ b/changelogs/fragments/7859.yml @@ -0,0 +1,2 @@ +refactor: +- Add workspace info in index pattern and asset header and update workspace header ([#7859](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7859)) \ No newline at end of file diff --git a/src/plugins/index_pattern_management/public/components/breadcrumbs.ts b/src/plugins/index_pattern_management/public/components/breadcrumbs.ts index 0f9739c47a03..4811f41a4c0a 100644 --- a/src/plugins/index_pattern_management/public/components/breadcrumbs.ts +++ b/src/plugins/index_pattern_management/public/components/breadcrumbs.ts @@ -31,11 +31,11 @@ import { i18n } from '@osd/i18n'; import { IndexPattern } from '../../../data/public'; -export function getListBreadcrumbs() { +export function getListBreadcrumbs(currentWorkspaceName?: string) { return [ { text: i18n.translate('indexPatternManagement.indexPatterns.listBreadcrumb', { - defaultMessage: 'Index patterns', + defaultMessage: currentWorkspaceName ? 'Workspace index patterns' : 'Index patterns', }), href: `/`, }, diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.tsx index f930bf526fa1..a4acf2995d6e 100644 --- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/create_index_pattern_wizard.tsx @@ -43,7 +43,7 @@ import { withRouter, RouteComponentProps } from 'react-router-dom'; import { DocLinksStart } from 'src/core/public'; import { StepIndexPattern } from './components/step_index_pattern'; import { StepTimeField } from './components/step_time_field'; -import { Header, Description } from './components/header'; +import { Header } from './components/header'; import { LoadingState } from './components/loading_state'; import { context as contextType } from '../../../../opensearch_dashboards_react/public'; diff --git a/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/empty_index_pattern_prompt.tsx b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/empty_index_pattern_prompt.tsx index 42b5e4645c84..e34a43115724 100644 --- a/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/empty_index_pattern_prompt.tsx +++ b/src/plugins/index_pattern_management/public/components/index_pattern_table/empty_index_pattern_prompt/empty_index_pattern_prompt.tsx @@ -37,30 +37,21 @@ import { EuiPageContent, EuiSpacer, EuiText, EuiFlexItem, EuiFlexGroup } from '@ import { EuiDescriptionListTitle } from '@elastic/eui'; import { EuiDescriptionListDescription, EuiDescriptionList } from '@elastic/eui'; import { EuiLink } from '@elastic/eui'; -import { useMount } from 'react-use'; -import { getListBreadcrumbs } from '../../breadcrumbs'; import { IndexPatternCreationOption } from '../../types'; import { CreateButton } from '../../create_button'; import { Illustration } from './assets/index_pattern_illustration'; -import { ManagementAppMountParams } from '../../../../../management/public'; interface Props { canSave: boolean; creationOptions: IndexPatternCreationOption[]; docLinksIndexPatternIntro: string; - setBreadcrumbs: ManagementAppMountParams['setBreadcrumbs']; } export const EmptyIndexPatternPrompt = ({ canSave, creationOptions, docLinksIndexPatternIntro, - setBreadcrumbs, }: Props) => { - useMount(() => { - setBreadcrumbs(getListBreadcrumbs()); - }); - return ( { getMlCardState, data, dataSourceEnabled, + workspaces, } = useOpenSearchDashboards().services; const [indexPatterns, setIndexPatterns] = useState([]); @@ -115,11 +117,13 @@ export const IndexPatternTable = ({ canSave, history }: Props) => { const [isLoadingIndexPatterns, setIsLoadingIndexPatterns] = useState(true); const [isColumnDataLoaded, setIsColumnDataLoaded] = useState(false); + const currentWorkspace = useObservable(workspaces ? workspaces.currentWorkspace$ : of(null)); const { columns: columnRegistry } = indexPatternManagementStart; - useMount(() => { - setBreadcrumbs(getListBreadcrumbs()); - }); + const useUpdatedUX = uiSettings.get('home:useNewHomePage'); + useEffect(() => { + setBreadcrumbs(getListBreadcrumbs(useUpdatedUX ? currentWorkspace?.name : undefined)); + }, [chrome, currentWorkspace, setBreadcrumbs, useUpdatedUX]); useEffect(() => { (async function () { @@ -219,8 +223,6 @@ export const IndexPatternTable = ({ canSave, history }: Props) => { }), ]; - const showActionsInHeader = uiSettings.get('home:useNewHomePage'); - const createButton = (() => { if (!canSave) return null; @@ -233,7 +235,7 @@ export const IndexPatternTable = ({ canSave, history }: Props) => { ); - return showActionsInHeader ? ( + return useUpdatedUX ? ( { ); })(); - const description = (( - - ) as unknown) as string; - const pageTitleAndDescription = showActionsInHeader ? ( + const description = i18n.translate( + 'indexPatternManagement.indexPatternTable.indexPatternExplanation', + currentWorkspace + ? { + defaultMessage: + 'Create and manage the index patterns that help you retrieve your data from OpenSearch for {name} workspace.', + values: { + name: currentWorkspace.name, + }, + } + : { + defaultMessage: + 'Create and manage the index patterns that help you retrieve your data from OpenSearch.', + } + ); + const pageTitleAndDescription = useUpdatedUX ? ( { canSave={canSave} creationOptions={creationOptions} docLinksIndexPatternIntro={docLinks.links.noDocumentation.indexPatterns.introduction} - setBreadcrumbs={setBreadcrumbs} /> ); } diff --git a/src/plugins/index_pattern_management/public/management_app/mount_management_section.tsx b/src/plugins/index_pattern_management/public/management_app/mount_management_section.tsx index 2fa80e098992..b3da336ce897 100644 --- a/src/plugins/index_pattern_management/public/management_app/mount_management_section.tsx +++ b/src/plugins/index_pattern_management/public/management_app/mount_management_section.tsx @@ -66,7 +66,17 @@ export async function mountManagementSection( dataSource?: DataSourcePluginSetup ) { const [ - { chrome, application, savedObjects, uiSettings, notifications, overlays, http, docLinks }, + { + chrome, + application, + savedObjects, + uiSettings, + notifications, + overlays, + http, + docLinks, + workspaces, + }, { data, navigation }, indexPatternManagementStart, ] = await getStartServices(); @@ -94,6 +104,7 @@ export async function mountManagementSection( getMlCardState, dataSourceEnabled, hideLocalCluster, + workspaces, }; const showActionsInHeader = uiSettings.get('home:useNewHomePage'); diff --git a/src/plugins/index_pattern_management/public/types.ts b/src/plugins/index_pattern_management/public/types.ts index 9a0d92de52cd..6bdb359491f7 100644 --- a/src/plugins/index_pattern_management/public/types.ts +++ b/src/plugins/index_pattern_management/public/types.ts @@ -38,6 +38,7 @@ import { DocLinksStart, HttpSetup, SavedObjectReference, + WorkspacesStart, } from 'src/core/public'; import { DataPublicPluginStart } from 'src/plugins/data/public'; import { NavigationPublicPluginStart } from 'src/plugins/navigation/public'; @@ -62,6 +63,7 @@ export interface IndexPatternManagmentContext { getMlCardState: () => MlCardState; dataSourceEnabled: boolean; hideLocalCluster: boolean; + workspaces: WorkspacesStart; } export type IndexPatternManagmentContextValue = OpenSearchDashboardsReactContextValue< diff --git a/src/plugins/management/public/components/feature_cards/__snapshots__/feature_cards.test.tsx.snap b/src/plugins/management/public/components/feature_cards/__snapshots__/feature_cards.test.tsx.snap index c0963f0462aa..e5f9a1975d83 100644 --- a/src/plugins/management/public/components/feature_cards/__snapshots__/feature_cards.test.tsx.snap +++ b/src/plugins/management/public/components/feature_cards/__snapshots__/feature_cards.test.tsx.snap @@ -3,12 +3,12 @@ exports[` render with complex navLinks 1`] = `
render with complex navLinks 1`] = ` Dashboard
- + {groupedCardForDisplay.map((group) => (
{group.category && ( @@ -71,7 +71,7 @@ export const FeatureCards = ({

{group.category.label}

)} - + {group.navLinks.map((row, rowIndex) => { return ( diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap b/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap index 769444715a90..799535aec1c7 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap @@ -352,15 +352,6 @@ exports[`SavedObjectsTable duplicate should allow the user to choose on header w "closed": false, "hasError": false, "isStopped": false, - "observers": Array [], - "thrownError": null, - }, - "currentWorkspaceId$": BehaviorSubject { - "_isScalar": false, - "_value": "workspace1", - "closed": false, - "hasError": false, - "isStopped": false, "observers": Array [ Subscriber { "_parentOrParents": null, @@ -402,6 +393,15 @@ exports[`SavedObjectsTable duplicate should allow the user to choose on header w ], "thrownError": null, }, + "currentWorkspaceId$": BehaviorSubject { + "_isScalar": false, + "_value": "workspace1", + "closed": false, + "hasError": false, + "isStopped": false, + "observers": Array [], + "thrownError": null, + }, "initialized$": BehaviorSubject { "_isScalar": false, "_value": false, @@ -539,15 +539,6 @@ exports[`SavedObjectsTable duplicate should allow the user to choose on table wh "closed": false, "hasError": false, "isStopped": false, - "observers": Array [], - "thrownError": null, - }, - "currentWorkspaceId$": BehaviorSubject { - "_isScalar": false, - "_value": "workspace1", - "closed": false, - "hasError": false, - "isStopped": false, "observers": Array [ Subscriber { "_parentOrParents": null, @@ -589,6 +580,15 @@ exports[`SavedObjectsTable duplicate should allow the user to choose on table wh ], "thrownError": null, }, + "currentWorkspaceId$": BehaviorSubject { + "_isScalar": false, + "_value": "workspace1", + "closed": false, + "hasError": false, + "isStopped": false, + "observers": Array [], + "thrownError": null, + }, "initialized$": BehaviorSubject { "_isScalar": false, "_value": false, @@ -738,15 +738,6 @@ exports[`SavedObjectsTable duplicate should allow the user to choose on table wh "closed": false, "hasError": false, "isStopped": false, - "observers": Array [], - "thrownError": null, - }, - "currentWorkspaceId$": BehaviorSubject { - "_isScalar": false, - "_value": "workspace1", - "closed": false, - "hasError": false, - "isStopped": false, "observers": Array [ Subscriber { "_parentOrParents": null, @@ -788,6 +779,15 @@ exports[`SavedObjectsTable duplicate should allow the user to choose on table wh ], "thrownError": null, }, + "currentWorkspaceId$": BehaviorSubject { + "_isScalar": false, + "_value": "workspace1", + "closed": false, + "hasError": false, + "isStopped": false, + "observers": Array [], + "thrownError": null, + }, "initialized$": BehaviorSubject { "_isScalar": false, "_value": false, @@ -1120,7 +1120,6 @@ exports[`SavedObjectsTable should render normally 1`] = ` "has": [MockFunction], } } - currentWorkspaceId="" filters={ Array [ Object { diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/header.test.tsx.snap b/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/header.test.tsx.snap index 2fbed1f36534..56dd6b4bbf4b 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/header.test.tsx.snap +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/__snapshots__/header.test.tsx.snap @@ -216,47 +216,26 @@ exports[`Header should render normally when useUpdatedUX is true 1`] = ` controls={ Array [ Object { - "renderComponent": - - , + "controlType": "button", + "disabled": false, + "iconType": "copy", + "label": "Copy all objects to...", + "run": [Function], + "testId": "duplicateObjects", }, Object { - "renderComponent": - - , + "controlType": "button", + "iconType": "exportAction", + "label": "Export all objects", + "run": [Function], + "testId": "exportAllObjects", }, Object { - "renderComponent": - - , + "controlType": "button", + "iconType": "importAction", + "label": "Import", + "run": [Function], + "testId": "importObjects", }, ] } @@ -264,7 +243,7 @@ exports[`Header should render normally when useUpdatedUX is true 1`] = ` /> - `; diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/components/header.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/components/header.tsx index 80f37d53ceec..911db61be704 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/components/header.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/components/header.tsx @@ -36,12 +36,14 @@ import { EuiText, EuiTextColor, EuiButtonEmpty, - EuiButton, } from '@elastic/eui'; import { FormattedMessage } from '@osd/i18n/react'; import { ApplicationStart } from 'src/core/public'; import { i18n } from '@osd/i18n'; -import { NavigationPublicPluginStart } from '../../../../../navigation/public'; +import { + NavigationPublicPluginStart, + TopNavControlButtonData, +} from '../../../../../navigation/public'; export const Header = ({ onExportAll, @@ -53,6 +55,7 @@ export const Header = ({ useUpdatedUX, navigationUI: { HeaderControl }, applications, + currentWorkspaceName, }: { onExportAll: () => void; onImport: () => void; @@ -63,6 +66,7 @@ export const Header = ({ useUpdatedUX: boolean; navigationUI: NavigationPublicPluginStart['ui']; applications: ApplicationStart; + currentWorkspaceName: string; }) => { const title = useUpdatedUX ? null : ( @@ -79,11 +83,23 @@ export const Header = ({ const description = useUpdatedUX ? ( @@ -106,53 +122,36 @@ export const Header = ({ ...(showDuplicateAll ? [ { - renderComponent: ( - - - + testId: 'duplicateObjects', + run: onDuplicate, + controlType: 'button', + disabled: objectCount === 0, + iconType: 'copy', + label: i18n.translate( + 'savedObjectsManagement.objectsTable.header.duplicateAllButtonLabel', + { defaultMessage: 'Copy all objects to...' } ), - }, + } as TopNavControlButtonData, ] : []), { - renderComponent: ( - - - - ), - }, + testId: 'exportAllObjects', + run: onExportAll, + controlType: 'button', + iconType: 'exportAction', + label: i18n.translate('savedObjectsManagement.objectsTable.header.exportButtonLabel', { + defaultMessage: 'Export all objects', + }), + } as TopNavControlButtonData, { - renderComponent: ( - - - - ), - }, + testId: 'importObjects', + run: onImport, + controlType: 'button', + iconType: 'importAction', + label: i18n.translate('savedObjectsManagement.objectsTable.header.importButtonLabel', { + defaultMessage: 'Import', + }), + } as TopNavControlButtonData, ]} setMountPoint={applications.setAppRightControls} /> @@ -219,9 +218,9 @@ export const Header = ({ {title} {rightControls} - + {!useUpdatedUX ? : } {description} - + {!useUpdatedUX && } ); }; diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx index 191720256024..b548d7da6b76 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx @@ -109,6 +109,7 @@ import { DataPublicPluginStart } from '../../../../../plugins/data/public'; import { DuplicateObject } from '../types'; import { formatWorkspaceIdParams } from '../../utils'; import { NavigationPublicPluginStart } from '../../../../navigation/public'; +import { WorkspaceObject } from '../../../../workspaces/public'; interface ExportAllOption { id: string; @@ -159,7 +160,7 @@ export interface SavedObjectsTableState { exportAllOptions: ExportAllOption[]; exportAllSelectedOptions: Record; isIncludeReferencesDeepChecked: boolean; - currentWorkspaceId?: string; + currentWorkspace?: WorkspaceObject; workspaceEnabled: boolean; availableWorkspaces?: WorkspaceAttribute[]; isShowingDuplicateResultFlyout: boolean; @@ -169,7 +170,7 @@ export interface SavedObjectsTableState { } export class SavedObjectsTable extends Component { private _isMounted = false; - private currentWorkspaceIdSubscription?: Subscription; + private currentWorkspaceSubscription?: Subscription; private workspacesSubscription?: Subscription; constructor(props: SavedObjectsTableProps) { @@ -201,7 +202,7 @@ export class SavedObjectsTable extends Component { const workspace = this.props.workspaces; - this.currentWorkspaceIdSubscription = workspace.currentWorkspaceId$.subscribe((workspaceId) => + this.currentWorkspaceSubscription = workspace.currentWorkspace$.subscribe((newValue) => this.setState({ - currentWorkspaceId: workspaceId, + currentWorkspace: newValue, }) ); @@ -381,7 +382,7 @@ export class SavedObjectsTable extends Component { - this.currentWorkspaceIdSubscription?.unsubscribe(); + this.currentWorkspaceSubscription?.unsubscribe(); this.workspacesSubscription?.unsubscribe(); }; @@ -1062,7 +1063,7 @@ export class SavedObjectsTable extends Component (currentWorkspaceId ? currentWorkspaceId === ws.id : true)) + .filter((ws) => (currentWorkspace ? currentWorkspace.id === ws.id : true)) .map((ws) => { return { name: ws.name, @@ -1164,8 +1165,9 @@ export class SavedObjectsTable extends Component - + {!useUpdatedUX && } ('savedObjects:perPage', 50); const dateFormat = coreStart.uiSettings.get('dateFormat'); + const currentWorkspace = useObservable(coreStart.workspaces.currentWorkspace$); useEffect(() => { setBreadcrumbs([ useUpdatedUX - ? { - text: i18n.translate('savedObjectsManagement.updatedUX.title', { - defaultMessage: 'Assets', - }), - } + ? currentWorkspace + ? { + text: i18n.translate('savedObjectsManagement.updatedUX.workspace.title', { + defaultMessage: 'Workspace assets', + }), + } + : { + text: i18n.translate('savedObjectsManagement.updatedUX.title', { + defaultMessage: 'Assets', + }), + } : { text: i18n.translate('savedObjectsManagement.breadcrumb.index', { defaultMessage: 'Saved objects', @@ -89,7 +97,7 @@ const SavedObjectsTablePage = ({ href: '/', }, ]); - }, [setBreadcrumbs, useUpdatedUX]); + }, [setBreadcrumbs, useUpdatedUX, currentWorkspace]); return ( -
{ ]} setMountPoint={application.setAppRightControls} /> - Organize collaborative projects with use-case-specific workspaces. -
{ }, [isDashboardAdmin, workspaceCreateUrl]); const renderCreateWorkspaceButton = () => { - const button = ( - - {i18n.translate('workspace.list.buttons.createWorkspace', { - defaultMessage: 'Create workspace', - })} - - ); return ( );