@@ -28,7 +28,6 @@ import {
2828 type PaymentBuilderTableModel ,
2929 type PaymentBuilderTableProps ,
3030} from './types.ts' ;
31- import { getChangedSlots } from './utils.ts' ;
3231
3332const displayName = 'v5.common.ActionsContent.partials.PaymentBuilderTable' ;
3433
@@ -225,10 +224,14 @@ const useGetPaymentBuilderColumns = ({
225224 ) ;
226225} ;
227226
228- const useRenderSubComponent = ( ) => {
229- return ( { row } : { row : Row < PaymentBuilderTableModel > } ) => (
230- < EditContent actionRow = { row } />
231- ) ;
227+ const useRenderSubComponent = (
228+ setIsExpanded : ( id : number , isExpanded : boolean ) => void ,
229+ ) => {
230+ return ( { row } : { row : Row < PaymentBuilderTableModel > } ) => {
231+ setIsExpanded ( row . original . id , row . getIsExpanded ( ) ) ;
232+
233+ return < EditContent actionRow = { row } /> ;
234+ } ;
232235} ;
233236
234237const PaymentBuilderTable : FC < PaymentBuilderTableProps > = ( {
@@ -243,6 +246,7 @@ const PaymentBuilderTable: FC<PaymentBuilderTableProps> = ({
243246 colony : { expendituresGlobalClaimDelay } ,
244247 } = useColonyContext ( ) ;
245248 const { selectedEditingAction, currentStep } = usePaymentBuilderContext ( ) ;
249+ const [ allRowsChanged , setAllRowsChanged ] = useState ( false ) ;
246250 const { expenditureSlotChanges } = selectedEditingAction || { } ;
247251 const isEditStepActive =
248252 ! ! selectedEditingAction && currentStep ?. startsWith ( ExpenditureStep . Edit ) ;
@@ -300,62 +304,93 @@ const PaymentBuilderTable: FC<PaymentBuilderTableProps> = ({
300304 return [ ...populatedItems , ...placeholderItems ] ;
301305 } , [ expendituresGlobalClaimDelay , items , expectedNumberOfPayouts ] ) ;
302306
303- const dataWithChanges = useMemo ( ( ) => {
307+ const newDataWithChanges = useMemo ( ( ) => {
304308 if ( ! expenditureSlotChanges ) {
305309 return data . sort ( ( a , b ) => a . id - b . id ) ;
306310 }
307-
308311 const { newSlots, oldSlots } = expenditureSlotChanges ;
309312
310- const changedSlots = getChangedSlots ( newSlots , oldSlots ) ;
311- const changedData = data
312- . filter ( ( item ) => changedSlots . map ( ( slot ) => slot . id ) . includes ( item . id ) )
313- . map ( ( item ) => {
314- const newSlot = newSlots . find ( ( slot ) => slot . id === item . id ) ;
315- const oldSlot = oldSlots . find ( ( slot ) => slot . id === item . id ) ;
313+ const unchangedSlots : PaymentBuilderTableModel [ ] = [ ] ;
314+ const changedSlots : PaymentBuilderTableModel [ ] = [ ] ;
316315
317- return {
318- ...item ,
319- newValues : newSlot ,
320- oldValues : oldSlot ,
321- } ;
322- } )
323- . sort ( ( a , b ) => a . id - b . id ) ;
316+ newSlots . forEach ( ( newSlot ) => {
317+ const found = oldSlots . some (
318+ ( oldSlot ) => JSON . stringify ( oldSlot ) === JSON . stringify ( newSlot ) ,
319+ ) ;
324320
325- const unchangedData = data
326- . filter ( ( item ) => ! changedSlots . map ( ( slot ) => slot . id ) . includes ( item . id ) )
327- . sort ( ( a , b ) => a . id - b . id ) ;
321+ const newItemSlot = newSlots . find ( ( slot ) => slot . id === newSlot . id ) ;
322+ const oldItemSlot = oldSlots . find ( ( slot ) => slot . id === newSlot . id ) ;
323+
324+ if ( found ) {
325+ unchangedSlots . push ( {
326+ amount : newSlot . payouts ?. [ 0 ] . amount ?? '0' ,
327+ claimDelay : newSlot ?. claimDelay ?? '0' ,
328+ id : newSlot . id ,
329+ isClaimed : newSlot . payouts ?. [ 0 ] . isClaimed ?? false ,
330+ isLoading : false ,
331+ recipient : newSlot ?. recipientAddress ?? '' ,
332+ tokenAddress : newSlot . payouts ?. [ 0 ] . tokenAddress ?? '' ,
333+ } ) ;
334+ } else {
335+ changedSlots . push ( {
336+ amount : newSlot . payouts ?. [ 0 ] . amount ?? '0' ,
337+ claimDelay : newSlot . claimDelay ?? '' ,
338+ id : newSlot . id ,
339+ isClaimed : newSlot . payouts ?. [ 0 ] . isClaimed ?? false ,
340+ isLoading : false ,
341+ newValues : newItemSlot ,
342+ oldValues : oldItemSlot ,
343+ recipient : newSlot . recipientAddress ?? '' ,
344+ tokenAddress : newSlot . payouts ?. [ 0 ] . tokenAddress ?? '' ,
345+ } ) ;
346+ }
347+ } ) ;
328348
329- return [ ...changedData , ...unchangedData ] ;
330- } , [ data , expenditureSlotChanges ] ) ;
349+ return [
350+ ...changedSlots ,
351+ ...unchangedSlots . filter ( ( item ) => item . amount !== '0' ) ,
352+ ] ;
353+ } , [ expenditureSlotChanges , data ] ) ;
331354
332- const filteredData = dataWithChanges . filter ( ( item ) =>
355+ const filteredData = newDataWithChanges . filter ( ( item ) =>
333356 BigNumber . from ( item . amount ) . gt ( 0 ) ,
334357 ) ;
335358
336- const dataToShow = isEditStepActive ? dataWithChanges : filteredData ;
359+ const dataToShow = isEditStepActive ? newDataWithChanges : filteredData ;
337360
338361 const columns = useGetPaymentBuilderColumns ( {
339- data : dataWithChanges ,
362+ data : newDataWithChanges ,
340363 status,
341364 slots : items ,
342365 finalizedTimestamp,
343366 expectedNumberOfPayouts,
344367 } ) ;
345368
346- const renderSubComponent = useRenderSubComponent ( ) ;
369+ const [ expandedRowsIds , setExpandedRowsIds ] = useState < Array < number > > ( [ ] ) ;
370+
371+ const renderSubComponent = useRenderSubComponent ( ( id , isExpanded ) => {
372+ if ( isExpanded && ! expandedRowsIds . includes ( id ) ) {
373+ setExpandedRowsIds ( [ ...expandedRowsIds , id ] ) ;
374+ }
375+ if ( ! isExpanded && expandedRowsIds . includes ( id ) ) {
376+ setExpandedRowsIds ( expandedRowsIds . filter ( ( item ) => item !== id ) ) ;
377+ }
378+ } ) ;
347379 const tableRef = React . useRef < HTMLDivElement | null > ( null ) ;
348380
349381 useEffect ( ( ) => {
350382 const tableRefCurrent = tableRef . current ;
351383
352384 if ( isEditStepActive && tableRefCurrent ) {
353385 const tableRows = tableRefCurrent . querySelectorAll ( 'tbody > tr' ) ;
354- const changedItemsCount = dataWithChanges . filter (
386+ const tableBodys = tableRefCurrent . querySelectorAll ( 'tbody' ) ;
387+
388+ const changedItemsCount = newDataWithChanges . filter (
355389 ( item ) => item . newValues ,
356390 ) . length ;
357- const lastChangedTableRow = tableRows [ changedItemsCount - 1 ] ;
358- const hasAllRowsChanged = changedItemsCount === dataWithChanges . length ;
391+ const lastChangedTableRow =
392+ tableRows [ changedItemsCount + expandedRowsIds . length - 1 ] ;
393+ const hasAllRowsChanged = changedItemsCount === newDataWithChanges . length ;
359394 const rowsBeforeLastChanged = Array . from ( tableRows ) . slice (
360395 0 ,
361396 changedItemsCount - 1 ,
@@ -367,6 +402,27 @@ const PaymentBuilderTable: FC<PaymentBuilderTableProps> = ({
367402 } ) ;
368403 }
369404
405+ const editedRowsLength = changedItemsCount + expandedRowsIds . length ;
406+ setAllRowsChanged ( hasAllRowsChanged ) ;
407+
408+ if ( isTablet ) {
409+ tableBodys . forEach ( ( tbody , index ) => {
410+ if ( index < changedItemsCount ) {
411+ tbody . classList . add ( 'tablet-edited' ) ;
412+ } else {
413+ tbody . classList . remove ( 'tablet-edited' ) ;
414+ }
415+ } ) ;
416+ } else {
417+ tableRows . forEach ( ( row , index ) => {
418+ if ( index < editedRowsLength ) {
419+ row . classList . add ( 'edited' ) ;
420+ } else {
421+ row . classList . remove ( 'edited' ) ;
422+ }
423+ } ) ;
424+ }
425+
370426 if ( lastChangedTableRow ) {
371427 lastChangedTableRow . classList . add ( 'last-edited-row' ) ;
372428 if ( hasAllRowsChanged ) {
@@ -413,13 +469,19 @@ const PaymentBuilderTable: FC<PaymentBuilderTableProps> = ({
413469 observers . forEach ( ( observer ) => observer . disconnect ( ) ) ;
414470
415471 tableRows . forEach ( ( row ) => {
416- row . classList . remove ( 'previous-row' , 'last-edited-row' , 'last-row' ) ;
472+ row . classList . remove (
473+ 'previous-row' ,
474+ 'last-edited-row' ,
475+ 'last-row' ,
476+ 'edited' ,
477+ 'tablet-edited' ,
478+ ) ;
417479 } ) ;
418480 } ;
419481 }
420482
421483 return ( ) => { } ;
422- } , [ isEditStepActive , dataWithChanges ] ) ;
484+ } , [ isEditStepActive , newDataWithChanges , expandedRowsIds , isTablet ] ) ;
423485
424486 return (
425487 < div className = "mt-7" ref = { tableRef } >
@@ -440,13 +502,21 @@ const PaymentBuilderTable: FC<PaymentBuilderTableProps> = ({
440502 ) }
441503 < Table < PaymentBuilderTableModel >
442504 className = { clsx (
443- '[&_tbody]:relative [&_tfoot>tr>td]:border-gray-200 [&_tfoot>tr>td]:py-2 md:[&_tfoot>tr>td]:border-t' ,
444505 {
445- '[&_tfoot>tr>td:empty]:hidden [&_th]:w-[6.25rem]' : isTablet ,
446- '[&_table]:table-auto lg:[&_table]:table-fixed [&_tbody_td]:h-[54px] [&_td:first-child]:pl-4 [&_td]:pr-4 [&_tfoot_td:first-child]:pl-4 [&_tfoot_td:not(:first-child)]:pl-0 [&_th:first-child]:pl-4 [&_th:not(:first-child)]:pl-0 [&_th]:pr-4' :
506+ '[&_tbody>tr>td]:px-[18px] [&_tbody>tr>td]:py-[10px] [&_tr.edited:last-child>td:last-child]:before:h-[calc(100%-5px)] [&_tr.edited:not(:last-child)>td:first-child]:relative [&_tr.edited:not(:last-child)>td:first-child]:after:absolute [&_tr.edited:not(:last-child)>td:first-child]:after:left-0 [&_tr.edited:not(:last-child)>td:first-child]:after:top-0 [&_tr.edited:not(:last-child)>td:first-child]:after:h-[calc(100%+1px)] [&_tr.edited:not(:last-child)>td:first-child]:after:w-[1px] [&_tr.edited:not(:last-child)>td:first-child]:after:translate-x-[-1px] [&_tr.edited:not(:last-child)>td:first-child]:after:rounded-none [&_tr.edited:not(:last-child)>td:first-child]:after:bg-blue-400 [&_tr.edited>td:last-child]:relative [&_tr.edited>td:last-child]:before:absolute [&_tr.edited>td:last-child]:before:right-0 [&_tr.edited>td:last-child]:before:top-0 [&_tr.edited>td:last-child]:before:h-[calc(100%+1px)] [&_tr.edited>td:last-child]:before:w-[1px] [&_tr.edited>td:last-child]:before:translate-x-[1px] [&_tr.edited>td:last-child]:before:bg-blue-400' :
447507 ! isTablet ,
448- '[&_thead]:relative [&_thead]:after:absolute [&_thead]:after:-left-px [&_thead]:after:-right-px [&_thead]:after:-top-px [&_thead]:after:bottom-0 [&_thead]:after:rounded-t-lg [&_thead]:after:border [&_thead]:after:border-blue-400 [&_tr.last-edited-row.expanded-below+tr_td:first-child]:after:border-l [&_tr.last-edited-row.expanded-below+tr_td:last-child]:after:border-r [&_tr.last-edited-row.expanded-below+tr_td]:after:border-b [&_tr.last-edited-row.expanded-below_td:first-child]:after:rounded-bl-none [&_tr.last-edited-row.expanded-below_td:last-child]:after:rounded-br-none [&_tr.last-edited-row.expanded-below_td]:after:border-b-0 [&_tr.last-edited-row_td:first-child]:after:border-l [&_tr.last-edited-row_td:last-child]:after:border-r [&_tr.last-edited-row_td]:after:border-b [&_tr.last-edited-row_td]:after:border-blue-400 [&_tr.last-row.expanded-below+tr_td:first-child]:after:rounded-bl-lg [&_tr.last-row.expanded-below+tr_td:last-child]:after:rounded-br-lg [&_tr.last-row_td:first-child]:after:rounded-bl-lg [&_tr.last-row_td:last-child]:after:rounded-br-lg [&_tr.previous-row.expanded-below+tr_td:first-child]:after:border-l [&_tr.previous-row.expanded-below+tr_td:last-child]:after:border-r [&_tr.previous-row_td:first-child]:after:border-l [&_tr.previous-row_td:last-child]:after:border-r [&_tr_td>div]:relative [&_tr_td]:after:absolute [&_tr_td]:after:-inset-px [&_tr_td]:after:border-blue-400 [&_tr_td]:sm:relative [&_tr_td_*]:z-[1]' :
449- isEditStepActive ,
508+ } ,
509+ {
510+ '[&_thead]:relative [&_thead]:after:absolute [&_thead]:after:-left-px [&_thead]:after:-right-px [&_thead]:after:-top-px [&_thead]:after:bottom-0 [&_thead]:after:rounded-t-lg [&_thead]:after:border-b [&_thead]:after:border-blue-400' :
511+ ! isTablet && isEditStepActive ,
512+ } ,
513+ {
514+ '[&_tr.edited:last-child>td]:after:border-b-1 [&_tr.edited:last-child>td:first-child]:after:border-l-1 [&_tr.edited:last-child>td:first-child]:after:h-full [&_tr.edited:last-child>td:not(:first-child)]:after:border-l-0 [&_tr.edited:last-child>td]:relative [&_tr.edited:last-child>td]:after:absolute [&_tr.edited:last-child>td]:after:bottom-0 [&_tr.edited:last-child>td]:after:right-0 [&_tr.edited:last-child>td]:after:h-[17px] [&_tr.edited:last-child>td]:after:w-[calc(100%+2px)] [&_tr.edited:last-child>td]:after:translate-x-[1px] [&_tr.edited:last-child>td]:after:border [&_tr.edited:last-child>td]:after:border-r-0 [&_tr.edited:last-child>td]:after:border-t-0 [&_tr.edited:last-child>td]:after:border-blue-400 [&_tr.edited>td:first-child]:after:rounded-bl-lg [&_tr.edited>td:last-child]:after:rounded-r-lg' :
515+ ! isTablet && allRowsChanged ,
516+ } ,
517+ {
518+ '[&_tr.last-edited-row>td]:border-b-1 [&_tr.last-edited-row>td]:border [&_tr.last-edited-row>td]:border-l-0 [&_tr.last-edited-row>td]:border-r-0 [&_tr.last-edited-row>td]:border-t-0 [&_tr.last-edited-row>td]:border-blue-400' :
519+ ! isTablet && ! allRowsChanged ,
450520 } ,
451521 ) }
452522 rows = { {
0 commit comments