diff --git a/ui/app/dto/MirrorsDTO.ts b/ui/app/dto/MirrorsDTO.ts index e0f6486b10..b2561a4dda 100644 --- a/ui/app/dto/MirrorsDTO.ts +++ b/ui/app/dto/MirrorsDTO.ts @@ -17,4 +17,5 @@ export type TableMapRow = { source: string; destination: string; partitionKey: string; + selected: boolean; }; diff --git a/ui/app/mirrors/create/handlers.ts b/ui/app/mirrors/create/handlers.ts index cd08210f26..ffafaa2602 100644 --- a/ui/app/mirrors/create/handlers.ts +++ b/ui/app/mirrors/create/handlers.ts @@ -52,14 +52,23 @@ const validateQRepFields = ( return true; }; +interface TableMapping { + sourceTableIdentifier: string; + destinationTableIdentifier: string; + partitionKey: string; +} const reformattedTableMapping = (tableMapping: TableMapRow[]) => { - const mapping = tableMapping.map((row) => { - return { - sourceTableIdentifier: row.source, - destinationTableIdentifier: row.destination, - partitionKey: row.partitionKey, - }; - }); + const mapping = tableMapping + .map((row) => { + if (row.selected === true) { + return { + sourceTableIdentifier: row.source, + destinationTableIdentifier: row.destination, + partitionKey: row.partitionKey, + }; + } + }) + .filter(Boolean); return mapping; }; @@ -83,7 +92,7 @@ export const handleCreateCDC = async ( const isValid = validateCDCFields(rows, setMsg, config); if (!isValid) return; const tableNameMapping = reformattedTableMapping(rows); - config['tableMappings'] = tableNameMapping; + config['tableMappings'] = tableNameMapping as TableMapping[]; config['flowJobName'] = flowJobName; setLoading(true); const statusMessage: UCreateMirrorResponse = await fetch('/api/mirrors/cdc', { diff --git a/ui/app/mirrors/create/page.tsx b/ui/app/mirrors/create/page.tsx index 94c9a74787..b689bffbb9 100644 --- a/ui/app/mirrors/create/page.tsx +++ b/ui/app/mirrors/create/page.tsx @@ -74,7 +74,6 @@ export default function CreateMirrors() { const handlePeer = (val: string, peerEnd: 'src' | 'dst') => { const stateVal = peers.find((peer) => peer.name === val)!; - console.log('/handelPeer: val:', stateVal); if (peerEnd === 'dst') { if (stateVal.type === DBType.POSTGRES) { setConfig((curr) => { @@ -107,7 +106,6 @@ export default function CreateMirrors() { sourcePeer: stateVal, })); } - console.log('/handelPeer: val:', config); }; return ( diff --git a/ui/app/mirrors/create/tablemapping.tsx b/ui/app/mirrors/create/tablemapping.tsx index 30e524626a..65a77a8d8b 100644 --- a/ui/app/mirrors/create/tablemapping.tsx +++ b/ui/app/mirrors/create/tablemapping.tsx @@ -34,51 +34,40 @@ const TableMapping = ({ setSchema, }: TableMappingProps) => { const [allSchemas, setAllSchemas] = useState(); - const [allTables, setAllTables] = useState(); const [tableColumns, setTableColumns] = useState< { tableName: string; columns: string[] }[] >([]); const [loading, setLoading] = useState(false); const handleAddRow = (source: string) => { - setRows([...rows, { source, destination: source, partitionKey: '' }]); - }; - - const handleRemoveRow = (source: string) => { const newRows = [...rows]; const index = newRows.findIndex((row) => row.source === source); - if (index >= 0) newRows.splice(index, 1); + if (index >= 0) newRows[index] = { ...newRows[index], selected: true }; setRows(newRows); }; - const getRow = (source: string) => { + const handleRemoveRow = (source: string) => { const newRows = [...rows]; - const row = newRows.find((row) => row.source === `${schema}.${source}`); - return row; + const index = newRows.findIndex((row) => row.source === source); + if (index >= 0) newRows[index] = { ...newRows[index], selected: false }; + setRows(newRows); }; const handleSelectAll = ( e: React.MouseEvent ) => { - if (e.currentTarget.checked) { - const tableNames: TableMapRow[] | undefined = allTables?.map( - (tableName) => { - return { - source: `${schema}.${tableName}`, - destination: `${schema}.${tableName}`, - partitionKey: '', - }; - } - ); - setRows(tableNames ?? []); - } else setRows([]); + const newRows = [...rows]; + for (const row of newRows) { + row.selected = e.currentTarget.checked; + } + setRows(newRows); }; const handleSwitch = (on: boolean, source: string) => { if (on) { - handleAddRow(`${schema}.${source}`); + handleAddRow(source); } else { - handleRemoveRow(`${schema}.${source}`); + handleRemoveRow(source); } }; @@ -86,41 +75,47 @@ const TableMapping = ({ // find the row with source and update the destination const newRows = [...rows]; const index = newRows.findIndex((row) => row.source === source); - newRows[index].destination = dest; - return newRows; + newRows[index] = { ...newRows[index], destination: dest }; + setRows(newRows); }; const updatePartitionKey = (source: string, pkey: string) => { const newRows = [...rows]; const index = newRows.findIndex((row) => row.source === source); - newRows[index].partitionKey = pkey; - return newRows; + newRows[index] = { ...newRows[index], partitionKey: pkey }; + setRows(newRows); }; const getTablesOfSchema = useCallback( (schemaName: string) => { - fetchTables(sourcePeerName, schemaName, setLoading).then((res) => - setAllTables(res) + fetchTables(sourcePeerName, schemaName, setLoading).then((tableNames) => + setRows((curr) => { + const newRows = [...curr]; + tableNames.forEach((tableName) => { + const row = newRows.find( + (row) => row.source === `${schemaName}.${tableName}` + ); + if (!row) { + newRows.push({ + source: `${schemaName}.${tableName}`, + destination: `${schemaName}.${tableName}`, + partitionKey: '', + selected: false, + }); + } + }); + return newRows; + }) ); }, - [sourcePeerName] + [sourcePeerName, setRows] ); const [searchQuery, setSearchQuery] = useState(''); - useEffect(() => { - if (searchQuery.length > 0) { - setAllTables( - (curr) => - curr?.filter((table) => { - return table.toLowerCase().includes(searchQuery.toLowerCase()); - }) - ); - } - if (searchQuery.length == 0) { - getTablesOfSchema(schema); - } - }, [searchQuery, getTablesOfSchema]); + const filteredRows = rows?.filter((row) => { + return row.source.toLowerCase().includes(searchQuery.toLowerCase()); + }); useEffect(() => { fetchSchemas(sourcePeerName, setLoading).then((res) => setAllSchemas(res)); @@ -179,8 +174,8 @@ const TableMapping = ({
- {allTables ? ( - allTables.map((sourceTableName, index) => ( + {filteredRows ? ( + filteredRows.map((row, index) => (
- handleSwitch(state, sourceTableName) + handleSwitch(state, row.source) } />
- {sourceTableName} + {row.source}
- {rows.find( - (row) => row.source === `${schema}.${sourceTableName}` - )?.destination && ( + {row.selected && (
- row.source === - `${schema}.${sourceTableName}` - )?.destination - } + defaultValue={row.destination} onChange={( e: React.ChangeEvent ) => - updateDestination( - `${schema}.${sourceTableName}`, - e.target.value - ) + updateDestination(row.source, e.target.value) } />
@@ -294,10 +279,7 @@ const TableMapping = ({ onChange={( e: React.ChangeEvent ) => - updatePartitionKey( - `${schema}.${sourceTableName}`, - e.target.value - ) + updatePartitionKey(row.source, e.target.value) } />
@@ -313,7 +295,7 @@ const TableMapping = ({ diff --git a/ui/components/Search.tsx b/ui/components/Search.tsx index cd7b917fc4..e7be28db60 100644 --- a/ui/components/Search.tsx +++ b/ui/components/Search.tsx @@ -1,29 +1,26 @@ import { SearchField } from '@/lib/SearchField'; -import { Dispatch, SetStateAction, useEffect, useState } from 'react'; +import { Dispatch, SetStateAction } from 'react'; interface SearchProps { allItems: any[]; setItems: Dispatch>; filterFunction: (query: string) => {}; } -const SearchBar = (props: SearchProps) => { - const [searchQuery, setSearchQuery] = useState(''); - - useEffect(() => { +const SearchBar = ({ allItems, setItems, filterFunction }: SearchProps) => { + const handleSearch = (searchQuery: string) => { if (searchQuery.length > 0) { - props.setItems(props.filterFunction(searchQuery)); + setItems(filterFunction(searchQuery)); } if (searchQuery.length == 0) { - props.setItems(props.allItems); + setItems(allItems); } - }, [searchQuery]); + }; return ( ) => - setSearchQuery(e.target.value) + handleSearch(e.target.value) } /> );