From c219cf88d33dca508b5bf422a6bea722838f2a41 Mon Sep 17 00:00:00 2001 From: Kapian1234 Date: Wed, 28 Aug 2024 15:51:24 +0800 Subject: [PATCH] Refactor association table in create page Signed-off-by: Kapian1234 --- .../association_data_source_modal.tsx | 2 +- .../opensearch_connections_table.tsx | 54 +++-- .../select_data_source_panel.tsx | 2 +- .../select_data_source_panel.tsx | 214 ++++++++---------- .../public/components/workspace_form/types.ts | 4 +- .../workspace_form/use_workspace_form.ts | 4 +- .../workspace_form/workspace_form.tsx | 5 +- 7 files changed, 145 insertions(+), 140 deletions(-) diff --git a/src/plugins/workspace/public/components/workspace_detail/association_data_source_modal.tsx b/src/plugins/workspace/public/components/workspace_detail/association_data_source_modal.tsx index 74e9d47628e8..fe798b81f240 100644 --- a/src/plugins/workspace/public/components/workspace_detail/association_data_source_modal.tsx +++ b/src/plugins/workspace/public/components/workspace_detail/association_data_source_modal.tsx @@ -81,7 +81,7 @@ export interface AssociationDataSourceModalProps { savedObjects: SavedObjectsStart; assignedConnections: DataSourceConnection[]; closeModal: () => void; - handleAssignDataSourceConnections: (connections: DataSourceConnection[]) => Promise; + handleAssignDataSourceConnections: (connections: DataSourceConnection[]) => Promise | void; } export const AssociationDataSourceModal = ({ diff --git a/src/plugins/workspace/public/components/workspace_detail/opensearch_connections_table.tsx b/src/plugins/workspace/public/components/workspace_detail/opensearch_connections_table.tsx index c1d0989991ac..ae4416ac632a 100644 --- a/src/plugins/workspace/public/components/workspace_detail/opensearch_connections_table.tsx +++ b/src/plugins/workspace/public/components/workspace_detail/opensearch_connections_table.tsx @@ -29,9 +29,11 @@ import S3Logo from '../../assets/s3_logo.svg'; interface OpenSearchConnectionTableProps { isDashboardAdmin: boolean; - connectionType: string; + connectionType?: string; dataSourceConnections: DataSourceConnection[]; - handleUnassignDataSources: (dataSources: DataSourceConnection[]) => Promise; + inCreatePage?: boolean; + handleUnassignDataSources: (dataSources: DataSourceConnection[]) => Promise | void; + getSelectedItems?: (dataSources: DataSourceConnection[]) => void; } export const OpenSearchConnectionTable = ({ @@ -39,11 +41,19 @@ export const OpenSearchConnectionTable = ({ connectionType, dataSourceConnections, handleUnassignDataSources, + getSelectedItems, + inCreatePage = false, }: OpenSearchConnectionTableProps) => { const [selectedItems, setSelectedItems] = useState([]); const [modalVisible, setModalVisible] = useState(false); const [popoversState, setPopoversState] = useState>({}); + useEffect(() => { + if (inCreatePage && getSelectedItems) { + getSelectedItems(selectedItems); + } + }, [selectedItems, getSelectedItems, inCreatePage]); + useEffect(() => { // Reset selected items when connectionType changes setSelectedItems([]); @@ -127,7 +137,7 @@ export const OpenSearchConnectionTable = ({ { field: 'name', name: i18n.translate('workspace.detail.dataSources.table.title', { - defaultMessage: 'Title', + defaultMessage: 'Data source', }), truncateText: true, render: (name: string, record) => { @@ -250,19 +260,31 @@ export const OpenSearchConnectionTable = ({ return ( <> - + {inCreatePage ? ( + + ) : ( + + )} + {modalVisible && ( void; + assignedDataSources: DataSourceConnection[]; + onChange: (value: DataSourceConnection[]) => void; + isDashboardAdmin: boolean; } export const SelectDataSourcePanel = ({ errors, onChange, - selectedDataSources, + assignedDataSources, savedObjects, + isDashboardAdmin, }: SelectDataSourcePanelProps) => { - const [dataSourcesOptions, setDataSourcesOptions] = useState([]); - useEffect(() => { - if (!savedObjects) return; - getDataSourcesList(savedObjects.client, ['*']).then((result) => { - const options = result.map(({ title, id }) => ({ - label: title, - value: id, - })); - setDataSourcesOptions(options); - }); - }, [savedObjects, setDataSourcesOptions]); - const handleAddNewOne = useCallback(() => { - onChange?.([ - ...selectedDataSources, - { - title: '', - id: '', - }, - ]); - }, [onChange, selectedDataSources]); + const [modalVisible, setModalVisible] = useState(false); + const [selectedItems, setSelectedItems] = useState([]); + const { + services: { notifications, http }, + } = useOpenSearchDashboards<{ CoreStart: CoreStart; workspaceClient: WorkspaceClient }>(); - const handleSelect = useCallback( - (selectedOptions, index) => { - const newOption = selectedOptions[0] - ? // Select new data source - { - title: selectedOptions[0].label, - id: selectedOptions[0].value, - } - : // Click reset button - { - title: '', - id: '', - }; - const newSelectedOptions = [...selectedDataSources]; - newSelectedOptions.splice(index, 1, newOption); + const handleAssignDataSources = (dataSources: DataSourceConnection[]) => { + setModalVisible(false); + const savedDataSources: DataSourceConnection[] = [...assignedDataSources, ...dataSources]; + onChange(savedDataSources); + }; - onChange(newSelectedOptions); - }, - [onChange, selectedDataSources] - ); + const handleUnassignDataSources = (dataSources: DataSourceConnection[]) => { + const savedDataSources = (assignedDataSources ?? [])?.filter( + ({ id }: DataSourceConnection) => !dataSources.some((item) => item.id === id) + ); + onChange(savedDataSources); + }; + + const renderTableContent = () => { + return ( + + ); + }; - const handleDelete = useCallback( - (index) => { - const newSelectedOptions = [...selectedDataSources]; - newSelectedOptions.splice(index, 1); + const associationButton = ( + setModalVisible(true)} + data-test-subj="workspace-creator-dataSources-assign-button" + > + {i18n.translate('workspace.form.selectDataSourcePanel.addNew', { + defaultMessage: 'Add data sources', + })} + + ); - onChange(newSelectedOptions); - }, - [onChange, selectedDataSources] + const removeButton = ( + { + handleUnassignDataSources(selectedItems); + }} + data-test-subj="workspace-creator-dataSources-assign-button" + > + {i18n.translate('workspace.form.selectDataSourcePanel.remove', { + defaultMessage: 'Remove selected', + })} + ); + const getSelectedItems = (currentSelectedItems: DataSourceConnection[]) => + setSelectedItems(currentSelectedItems); + return (
- {i18n.translate('workspace.form.selectDataSource.subTitle', { - defaultMessage: 'Data source', - })} + + {i18n.translate('workspace.form.selectDataSource.subTitle', { + defaultMessage: 'Add data sources that will be available in the workspace', + })} + - - {selectedDataSources.map(({ id, title }, index) => ( - - - - handleSelect(selectedOptions, index)} - placeholder="Select" - /> - - - handleDelete(index)} - isDisabled={false} - /> - - - - ))} - - - {i18n.translate('workspace.form.selectDataSourcePanel.addNew', { - defaultMessage: 'Add New', - })} - + + + {isDashboardAdmin && selectedItems.length > 0 && assignedDataSources.length > 0 && ( + {removeButton} + )} + {isDashboardAdmin && {associationButton}} + + + + {assignedDataSources.length > 0 && renderTableContent()} + + {modalVisible && ( + setModalVisible(false)} + handleAssignDataSourceConnections={handleAssignDataSources} + http={http} + notifications={notifications} + /> + )}
); }; diff --git a/src/plugins/workspace/public/components/workspace_form/types.ts b/src/plugins/workspace/public/components/workspace_form/types.ts index 5ec929e17b0c..a9a7df9005d4 100644 --- a/src/plugins/workspace/public/components/workspace_form/types.ts +++ b/src/plugins/workspace/public/components/workspace_form/types.ts @@ -6,7 +6,7 @@ import type { ApplicationStart, SavedObjectsStart } from '../../../../../core/public'; import type { WorkspacePermissionMode } from '../../../common/constants'; import type { DetailTab, WorkspaceOperationType, WorkspacePermissionItemType } from './constants'; -import { DataSource } from '../../../common/types'; +import { DataSourceConnection } from '../../../common/types'; import { DataSourceManagementPluginSetup } from '../../../../../plugins/data_source_management/public'; import { WorkspaceUseCase } from '../../types'; @@ -34,7 +34,7 @@ export interface WorkspaceFormSubmitData { features?: string[]; color?: string; permissionSettings?: WorkspacePermissionSetting[]; - selectedDataSources?: DataSource[]; + selectedDataSources?: DataSourceConnection[]; } export interface WorkspaceFormData extends WorkspaceFormSubmitData { diff --git a/src/plugins/workspace/public/components/workspace_form/use_workspace_form.ts b/src/plugins/workspace/public/components/workspace_form/use_workspace_form.ts index fb8bf40e497c..12dee9792652 100644 --- a/src/plugins/workspace/public/components/workspace_form/use_workspace_form.ts +++ b/src/plugins/workspace/public/components/workspace_form/use_workspace_form.ts @@ -12,7 +12,7 @@ import { getUseCaseFeatureConfig, isUseCaseFeatureConfig, } from '../../utils'; -import { DataSource } from '../../../common/types'; +import { DataSourceConnection } from '../../../common/types'; import { WorkspaceFormProps, WorkspaceFormErrors, WorkspacePermissionSetting } from './types'; import { appendDefaultFeatureIds, @@ -52,7 +52,7 @@ export const useWorkspaceForm = ({ Array & Partial> >(initialPermissionSettingsRef.current); - const [selectedDataSources, setSelectedDataSources] = useState( + const [selectedDataSources, setSelectedDataSources] = useState( defaultValues?.selectedDataSources && defaultValues.selectedDataSources.length > 0 ? defaultValues.selectedDataSources : [] diff --git a/src/plugins/workspace/public/components/workspace_form/workspace_form.tsx b/src/plugins/workspace/public/components/workspace_form/workspace_form.tsx index e33005ec81eb..d16ca7e8c9fd 100644 --- a/src/plugins/workspace/public/components/workspace_form/workspace_form.tsx +++ b/src/plugins/workspace/public/components/workspace_form/workspace_form.tsx @@ -48,7 +48,7 @@ export const WorkspaceForm = (props: WorkspaceFormProps) => { const disabledUserOrGroupInputIdsRef = useRef( defaultValues?.permissionSettings?.map((item) => item.id) ?? [] ); - const isDashboardAdmin = application?.capabilities?.dashboards?.isDashboardAdmin ?? false; + const isDashboardAdmin = !!application?.capabilities?.dashboards?.isDashboardAdmin; const handleNameInputChange = useCallback( (newName) => { setName(newName); @@ -140,8 +140,9 @@ export const WorkspaceForm = (props: WorkspaceFormProps) => { errors={formErrors.selectedDataSources} onChange={setSelectedDataSources} savedObjects={savedObjects} - selectedDataSources={formData.selectedDataSources} + assignedDataSources={formData.selectedDataSources} data-test-subj={`workspaceForm-dataSourcePanel`} + isDashboardAdmin={isDashboardAdmin} /> )}