From 879a5ae1f08bc9b4109c50dabdfe189a22e9daab Mon Sep 17 00:00:00 2001 From: Carter Date: Wed, 24 Jun 2026 14:16:54 -0600 Subject: [PATCH] fixed pending state logic --- src/interactions/InteractionsOverview.tsx | 60 ++++++++++++++--------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/src/interactions/InteractionsOverview.tsx b/src/interactions/InteractionsOverview.tsx index db73675..2619e97 100644 --- a/src/interactions/InteractionsOverview.tsx +++ b/src/interactions/InteractionsOverview.tsx @@ -70,6 +70,11 @@ interface Props { refreshCallback: () => void; } +interface PendingInteraction { + since: string; + accepted: boolean; +} + export default function InteractionsOverview(props: Props) { const classes = useStyles(); const [{as, user}] = useGlobalState(); @@ -81,7 +86,7 @@ export default function InteractionsOverview(props: Props) { const [interactions, setInteractions] = useState(props.interactions); const [dirtyInteractions, setDirtyInteractions] = useState>(new Map()); const [mappedComponents, setMappedComponents] = useState>(new Map()); - const [acceptedInteractions, setAcceptedInteractions] = useState>(new Set()); + const [pendingInteractions, setPendingInteractions] = useState>(new Map()); const [renderToggle, setRenderToggle] = useState(false); const [selectedInteraction, setSelectedInteraction] = useState( undefined @@ -97,20 +102,23 @@ export default function InteractionsOverview(props: Props) { } if (props.interactions !== prevInteractions) { - if (prevInteractions) { - setAcceptedInteractions((prevAccepted) => { - const updatedAccepted = new Set(prevAccepted); - props.interactions.forEach((interaction: Interaction) => { - const previous = prevInteractions.find(prevInteraction => prevInteraction.key() === interaction.key()); - if (!interaction.status.synced) { - updatedAccepted.delete(interaction.key()); - } else if (previous && !previous.status.synced) { - updatedAccepted.add(interaction.key()); + setPendingInteractions((prevPending) => { + const updatedPending = new Map(prevPending); + props.interactions.forEach((interaction: Interaction) => { + const existing = updatedPending.get(interaction.key()); + if (!interaction.status.synced) { + if (!existing || existing.accepted) { + updatedPending.set(interaction.key(), { + since: interaction.status.lastUpdate || moment().toISOString(), + accepted: false + }); } - }); - return updatedAccepted; + } else if (existing && !existing.accepted) { + updatedPending.set(interaction.key(), { ...existing, accepted: true }); + } }); - } + return updatedPending; + }); setInteractions(cloneDeep(props.interactions)); } }, [components, prevComponents, props.interactions, prevInteractions]); @@ -217,6 +225,14 @@ export default function InteractionsOverview(props: Props) { index: number, settings: pond.IInteractionSettings ) => { + const interactionKey = settings.key ?? ""; + setPendingInteractions((prevPending) => { + const updatedPending = new Map(prevPending); + if (interactionKey) { + updatedPending.set(interactionKey, { since: moment().toISOString(), accepted: false }); + } + return updatedPending; + }); interactionsAPI .updateInteraction(Number(deviceID), settings, as) .then((_response: any) => { @@ -224,7 +240,6 @@ export default function InteractionsOverview(props: Props) { updatedDirtyInteractions.set(index, false); setDirtyInteractions(updatedDirtyInteractions); success("Successfully updated the interaction for " + component.name()); - refreshCallback(); }) .catch((_err: any) => { error("Error occurred while updating the interaction for " + component.name()); @@ -242,16 +257,13 @@ export default function InteractionsOverview(props: Props) { let key = interaction.key(); let source = mappedComponents.get(componentIDToString(interaction.settings.source)); let sink = mappedComponents.get(componentIDToString(interaction.settings.sink)); - const isPending = !interaction.status.synced && Boolean(interaction.status.lastUpdate); - const isAccepted = interaction.status.synced && acceptedInteractions.has(interaction.key()); - let statusText = - !interaction.status.synced - ? interaction.status.lastUpdate - ? "Pending " + - moment(interaction.status.lastUpdate && interaction.status.lastUpdate).fromNow() - : "" - : acceptedInteractions.has(interaction.key()) - ? "Pending change accepted" + const pending = pendingInteractions.get(interaction.key()); + const isAccepted = Boolean(pending?.accepted); + const isPending = Boolean(pending && !pending.accepted); + let statusText = isAccepted + ? "Pending change accepted" + : isPending + ? "Pending " + moment(pending.since).fromNow() : ""; let schedule = pond.InteractionSchedule.create( interaction.settings.schedule !== null ? interaction.settings.schedule : undefined