Skip to content

Commit 0ed84c1

Browse files
zhichao-awsSuZhou-Joe
authored andcommittedSep 15, 2023
workspace dropdown list (opensearch-project#9)
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>

File tree

4 files changed

+125
-0
lines changed

4 files changed

+125
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import { WorkspaceDropdownList } from './workspace_dropdown_list';
7+
8+
export { WorkspaceDropdownList };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import React, { useState, useCallback, useMemo, useEffect } from 'react';
7+
8+
import { EuiButton, EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui';
9+
import useObservable from 'react-use/lib/useObservable';
10+
import { CoreStart, WorkspaceAttribute } from '../../../../../core/public';
11+
12+
type WorkspaceOption = EuiComboBoxOptionOption<WorkspaceAttribute>;
13+
14+
interface WorkspaceDropdownListProps {
15+
coreStart: CoreStart;
16+
onCreateWorkspace: () => void;
17+
onSwitchWorkspace: (workspaceId: string) => Promise<void>;
18+
}
19+
20+
function workspaceToOption(workspace: WorkspaceAttribute): WorkspaceOption {
21+
return { label: workspace.name, key: workspace.id, value: workspace };
22+
}
23+
24+
export function WorkspaceDropdownList(props: WorkspaceDropdownListProps) {
25+
const { coreStart, onCreateWorkspace, onSwitchWorkspace } = props;
26+
const workspaceList = useObservable(coreStart.workspaces.client.workspaceList$, []);
27+
const currentWorkspaceId = useObservable(coreStart.workspaces.client.currentWorkspaceId$, '');
28+
29+
const [loading, setLoading] = useState(false);
30+
const [workspaceOptions, setWorkspaceOptions] = useState([] as WorkspaceOption[]);
31+
32+
const currentWorkspaceOption = useMemo(() => {
33+
const workspace = workspaceList.find((item) => item.id === currentWorkspaceId);
34+
if (!workspace) {
35+
coreStart.notifications.toasts.addDanger(
36+
`can not get current workspace of id [${currentWorkspaceId}]`
37+
);
38+
return [workspaceToOption({ id: currentWorkspaceId, name: '' })];
39+
}
40+
return [workspaceToOption(workspace)];
41+
}, [workspaceList, currentWorkspaceId, coreStart]);
42+
const allWorkspaceOptions = useMemo(() => {
43+
return workspaceList.map(workspaceToOption);
44+
}, [workspaceList]);
45+
46+
const onSearchChange = useCallback(
47+
(searchValue: string) => {
48+
setWorkspaceOptions(allWorkspaceOptions.filter((item) => item.label.includes(searchValue)));
49+
},
50+
[allWorkspaceOptions]
51+
);
52+
53+
const onChange = (workspaceOption: WorkspaceOption[]) => {
54+
/** switch the workspace */
55+
setLoading(true);
56+
onSwitchWorkspace(workspaceOption[0].key!)
57+
.catch((err) =>
58+
coreStart.notifications.toasts.addDanger('some error happens in workspace service')
59+
)
60+
.finally(() => {
61+
setLoading(false);
62+
});
63+
};
64+
65+
useEffect(() => {
66+
onSearchChange('');
67+
}, [onSearchChange]);
68+
69+
return (
70+
<>
71+
<EuiComboBox
72+
async
73+
options={workspaceOptions}
74+
isLoading={loading}
75+
onChange={onChange}
76+
selectedOptions={currentWorkspaceOption}
77+
singleSelection={{ asPlainText: true }}
78+
onSearchChange={onSearchChange}
79+
append={<EuiButton onClick={onCreateWorkspace}>Create workspace</EuiButton>}
80+
/>
81+
</>
82+
);
83+
}
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import React from 'react';
7+
import ReactDOM from 'react-dom';
8+
import { CoreStart } from '../../../core/public';
9+
import { WorkspaceDropdownList } from './containers/workspace_dropdown_list';
10+
11+
export const mountDropdownList = (core: CoreStart) => {
12+
core.chrome.navControls.registerLeft({
13+
order: 0,
14+
mount: (element) => {
15+
ReactDOM.render(
16+
<WorkspaceDropdownList
17+
coreStart={core}
18+
onCreateWorkspace={() => alert('create')}
19+
onSwitchWorkspace={async (id: string) => {
20+
await new Promise((resolve) => setTimeout(resolve, 1000));
21+
alert(`switch to workspace ${id}`);
22+
}}
23+
// onSwitchWorkspace={(id: string) => alert(`switch to workspace ${id}`)}
24+
/>,
25+
element
26+
);
27+
return () => {
28+
ReactDOM.unmountComponentAtNode(element);
29+
};
30+
},
31+
});
32+
};

‎src/plugins/workspace/public/plugin.ts

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
} from '../../../core/public';
1414
import { WORKSPACE_APP_ID, WORKSPACE_ID_IN_SESSION_STORAGE } from '../common/constants';
1515
import { WORKSPACE_ID_QUERYSTRING_NAME } from '../../../core/public';
16+
import { mountDropdownList } from './mount';
1617

1718
export class WorkspacesPlugin implements Plugin<{}, {}> {
1819
private core?: CoreSetup;
@@ -100,6 +101,7 @@ export class WorkspacesPlugin implements Plugin<{}, {}> {
100101
}
101102

102103
public start(core: CoreStart) {
104+
mountDropdownList(core);
103105
return {};
104106
}
105107
}

0 commit comments

Comments
 (0)
Please sign in to comment.