Skip to content

Commit

Permalink
workspace dropdown list (#9)
Browse files Browse the repository at this point in the history
Add workspace dropdown list 

---------

Signed-off-by: zhichao-aws <zhichaog@amazon.com>
Signed-off-by: SuZhoue-Joe <suzhou@amazon.com>
Signed-off-by: suzhou <suzhou@amazon.com>
Co-authored-by: SuZhoue-Joe <suzhou@amazon.com>
  • Loading branch information
zhichao-aws and SuZhou-Joe committed Jul 19, 2023
1 parent 1fe0c59 commit 4be6681
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { WorkspaceDropdownList } from './workspace_dropdown_list';

export { WorkspaceDropdownList };
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React, { useState, useCallback, useMemo, useEffect } from 'react';

import { EuiButton, EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui';
import useObservable from 'react-use/lib/useObservable';
import { CoreStart, WorkspaceAttribute } from '../../../../../core/public';

type WorkspaceOption = EuiComboBoxOptionOption<WorkspaceAttribute>;

interface WorkspaceDropdownListProps {
coreStart: CoreStart;
onCreateWorkspace: () => void;
onSwitchWorkspace: (workspaceId: string) => Promise<void>;
}

function workspaceToOption(workspace: WorkspaceAttribute): WorkspaceOption {
return { label: workspace.name, key: workspace.id, value: workspace };
}

export function WorkspaceDropdownList(props: WorkspaceDropdownListProps) {
const { coreStart, onCreateWorkspace, onSwitchWorkspace } = props;
const workspaceList = useObservable(coreStart.workspaces.client.workspaceList$, []);
const currentWorkspaceId = useObservable(coreStart.workspaces.client.currentWorkspaceId$, '');

const [loading, setLoading] = useState(false);
const [workspaceOptions, setWorkspaceOptions] = useState([] as WorkspaceOption[]);

const currentWorkspaceOption = useMemo(() => {
const workspace = workspaceList.find((item) => item.id === currentWorkspaceId);
if (!workspace) {
coreStart.notifications.toasts.addDanger(
`can not get current workspace of id [${currentWorkspaceId}]`
);
return [workspaceToOption({ id: currentWorkspaceId, name: '' })];
}
return [workspaceToOption(workspace)];
}, [workspaceList, currentWorkspaceId, coreStart]);
const allWorkspaceOptions = useMemo(() => {
return workspaceList.map(workspaceToOption);
}, [workspaceList]);

const onSearchChange = useCallback(
(searchValue: string) => {
setWorkspaceOptions(allWorkspaceOptions.filter((item) => item.label.includes(searchValue)));
},
[allWorkspaceOptions]
);

const onChange = (workspaceOption: WorkspaceOption[]) => {
/** switch the workspace */
setLoading(true);
onSwitchWorkspace(workspaceOption[0].key!)
.catch((err) =>
coreStart.notifications.toasts.addDanger('some error happens in workspace service')
)
.finally(() => {
setLoading(false);
});
};

useEffect(() => {
onSearchChange('');
}, [onSearchChange]);

return (
<>
<EuiComboBox
async
options={workspaceOptions}
isLoading={loading}
onChange={onChange}
selectedOptions={currentWorkspaceOption}
singleSelection={{ asPlainText: true }}
onSearchChange={onSearchChange}
append={<EuiButton onClick={onCreateWorkspace}>Create workspace</EuiButton>}
/>
</>
);
}
32 changes: 32 additions & 0 deletions src/plugins/workspace/public/mount.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import ReactDOM from 'react-dom';
import { CoreStart } from '../../../core/public';
import { WorkspaceDropdownList } from './containers/workspace_dropdown_list';

export const mountDropdownList = (core: CoreStart) => {
core.chrome.navControls.registerLeft({
order: 0,
mount: (element) => {
ReactDOM.render(
<WorkspaceDropdownList
coreStart={core}
onCreateWorkspace={() => alert('create')}
onSwitchWorkspace={async (id: string) => {
await new Promise((resolve) => setTimeout(resolve, 1000));
alert(`switch to workspace ${id}`);
}}
// onSwitchWorkspace={(id: string) => alert(`switch to workspace ${id}`)}
/>,
element
);
return () => {
ReactDOM.unmountComponentAtNode(element);
};
},
});
};
2 changes: 2 additions & 0 deletions src/plugins/workspace/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from '../../../core/public';
import { WORKSPACE_APP_ID, WORKSPACE_ID_IN_SESSION_STORAGE } from '../common/constants';
import { WORKSPACE_ID_QUERYSTRING_NAME } from '../../../core/public';
import { mountDropdownList } from './mount';

export class WorkspacesPlugin implements Plugin<{}, {}> {
private core?: CoreSetup;
Expand Down Expand Up @@ -100,6 +101,7 @@ export class WorkspacesPlugin implements Plugin<{}, {}> {
}

public start(core: CoreStart) {
mountDropdownList(core);
return {};
}
}

0 comments on commit 4be6681

Please sign in to comment.