From 6f3c9a8c375f2189d87e683c83c3b0d7efe3a727 Mon Sep 17 00:00:00 2001 From: James Bradford Date: Tue, 19 Sep 2023 08:03:35 -0700 Subject: [PATCH 01/13] change presentation mode header language --- .../client/src/views/Campaign/Presentation/Presentation.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/client/src/views/Campaign/Presentation/Presentation.tsx b/applications/client/src/views/Campaign/Presentation/Presentation.tsx index 69800bcf..54037cde 100644 --- a/applications/client/src/views/Campaign/Presentation/Presentation.tsx +++ b/applications/client/src/views/Campaign/Presentation/Presentation.tsx @@ -78,7 +78,7 @@ const Presentation = observer(({ ...props }) => { margin: 0.75rem 1rem; `} > - Select a comment topic to present + Present a Comment Topic )} From 63f011549cbb02a1136f118eda3a4215bd149dcd Mon Sep 17 00:00:00 2001 From: James Bradford Date: Tue, 19 Sep 2023 09:51:12 -0700 Subject: [PATCH 02/13] export breadcrumbLinkStyle --- .../Explore/components/BreadcrumbsStyled.tsx | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/applications/client/src/views/Campaign/Explore/components/BreadcrumbsStyled.tsx b/applications/client/src/views/Campaign/Explore/components/BreadcrumbsStyled.tsx index 9c34134d..b1ed4f54 100644 --- a/applications/client/src/views/Campaign/Explore/components/BreadcrumbsStyled.tsx +++ b/applications/client/src/views/Campaign/Explore/components/BreadcrumbsStyled.tsx @@ -37,6 +37,30 @@ export type BreadcrumbsStyledProps = { muted?: boolean; }; +export const breadcrumbLinkStyle = ({ muted }: BreadcrumbsStyledProps) => css` + .${Classes.BREADCRUMB} { + display: inline; + font-size: inherit; + } + + a.${Classes.BREADCRUMB} { + color: ${CoreTokens.TextMuted}; + ${!muted && + css` + font-weight: ${CoreTokens.FontWeightBold}; + color: ${CoreTokens.TextLink}; + `}; + + &:hover { + text-decoration: underline; + } + } + + .${Classes.BREADCRUMB_CURRENT} { + color: ${CoreTokens.TextMuted}; + } +`; + export const BreadcrumbsStyled = styled(BreadcrumbsSimple)` /* ${UtilityStyles.textMeta} */ @@ -64,28 +88,7 @@ export const BreadcrumbsStyled = styled(BreadcrumbsSimple) - !muted && - css` - font-weight: ${CoreTokens.FontWeightBold}; - color: ${CoreTokens.TextLink}; - `}; - - &:hover { - text-decoration: underline; - } - } - - .${Classes.BREADCRUMB_CURRENT} { - color: ${CoreTokens.TextMuted}; - } + ${({ muted }) => breadcrumbLinkStyle({ muted })} .${Classes.OVERFLOW_LIST_SPACER} { // this is used by OverflowList to measure and adjust layout... From 9d5c09c8335ca680af7f1c55c5a0205c7673da30 Mon Sep 17 00:00:00 2001 From: James Bradford Date: Tue, 19 Sep 2023 09:51:28 -0700 Subject: [PATCH 03/13] shuffle Presentation mode components --- .../Campaign/Presentation/Presentation.tsx | 116 +++++++++-------- .../Presentation/PresentationItem.tsx | 26 ++-- .../Presentation/PresentationItemHeader.tsx | 37 ++++++ .../Presentation/PresentationNavBar.tsx | 56 +++------ .../Campaign/Presentation/SlideSelector.tsx | 117 +++++++----------- 5 files changed, 172 insertions(+), 180 deletions(-) create mode 100644 applications/client/src/views/Campaign/Presentation/PresentationItemHeader.tsx diff --git a/applications/client/src/views/Campaign/Presentation/Presentation.tsx b/applications/client/src/views/Campaign/Presentation/Presentation.tsx index 54037cde..4af330f9 100644 --- a/applications/client/src/views/Campaign/Presentation/Presentation.tsx +++ b/applications/client/src/views/Campaign/Presentation/Presentation.tsx @@ -6,7 +6,7 @@ import { RedEyeRoutes, useStore, } from '@redeye/client/store'; -import { PresentationItem, PresentationNavBar, PresentationTopicItem, SlideSelector } from '@redeye/client/views'; +import { PresentationItem, PresentationNavBar, PresentationTopicItem } from '@redeye/client/views'; import { Header, CoreTokens } from '@redeye/ui-styles'; import { useQuery } from '@tanstack/react-query'; import { observer } from 'mobx-react-lite'; @@ -54,72 +54,70 @@ const Presentation = observer(({ ...props }) => { cy-test="presentation-root" {...props} css={css` - /* width: 100%; */ display: flex; flex-direction: column; overflow: hidden; - /* background-color: var(--dark-gray2); */ `} > -
- {store.campaign.presentation.isPresenting ? ( - - ) : ( -
- Present a Comment Topic -
- )} -
- - - - - - - - } - /> - - {data?.presentationItems - ?.filter( - (presentationItem) => - presentationItem.id !== 'procedural' && presentationItem.id.slice(0, 5) !== 'user-' - ) - .map((presentationItem) => ( - - ))} - - } - /> - - - + + + + + + + + } + /> + +
+ Present a Comment Topic +
+ + {data?.presentationItems + ?.filter( + (presentationItem) => + presentationItem.id !== 'procedural' && presentationItem.id.slice(0, 5) !== 'user-' + ) + .map((presentationItem) => ( + + ))} + + + } + /> +
); }); // eslint-disable-next-line import/no-default-export export default Presentation; + +const StyledScrollBox = ({ children, ...props }: ComponentProps<'div'>) => ( + + {children} + +); diff --git a/applications/client/src/views/Campaign/Presentation/PresentationItem.tsx b/applications/client/src/views/Campaign/Presentation/PresentationItem.tsx index 1ffafa67..58ad806e 100644 --- a/applications/client/src/views/Campaign/Presentation/PresentationItem.tsx +++ b/applications/client/src/views/Campaign/Presentation/PresentationItem.tsx @@ -6,6 +6,7 @@ import { observable } from 'mobx'; import { observer } from 'mobx-react-lite'; import { useEffect } from 'react'; import type { ComponentProps } from 'react'; +import { PresentationItemHeader } from './PresentationItemHeader'; type PresentationItemProps = ComponentProps<'div'> & { commandGroupId?: string; @@ -59,16 +60,19 @@ export const PresentationItem = observer(({ commandGroupI if (!data?.commandGroup) return null; return ( - + <> + + + ); }); diff --git a/applications/client/src/views/Campaign/Presentation/PresentationItemHeader.tsx b/applications/client/src/views/Campaign/Presentation/PresentationItemHeader.tsx new file mode 100644 index 00000000..2754a828 --- /dev/null +++ b/applications/client/src/views/Campaign/Presentation/PresentationItemHeader.tsx @@ -0,0 +1,37 @@ +import { dateTimeFormat, timeFormat } from '@redeye/client/components'; +import { createState } from '@redeye/client/components/mobx-create-state'; +import { useStore } from '@redeye/client/store'; +import { Flex, Txt } from '@redeye/ui-styles'; +import { observer } from 'mobx-react-lite'; +import type { ComponentProps } from 'react'; + +type PresentationItemHeaderProps = ComponentProps<'div'> & {}; + +export const PresentationItemHeader = observer(({}) => { + const store = useStore(); + + const state = createState({ + get min() { + return store.settings.momentTz(store.campaign.presentation.currentSlide?.minDate); + }, + get max() { + return store.settings.momentTz(store.campaign.presentation.currentSlide?.maxDate); + }, + }); + + return ( + + + {store.campaign.presentation.currentSlide?.minDate ? state.min.format(`ddd ${dateTimeFormat}`) : 'Unknown'} + {store.campaign.presentation.currentSlide?.commandIds?.length! > 1 && ( + <> + + {store.campaign.presentation.currentSlide?.maxDate + ? state.max.format(state.max.dayOfYear() > state.min.dayOfYear() ? `ddd ${dateTimeFormat}` : timeFormat) + : 'Unknown'} + + )} + + + ); +}); diff --git a/applications/client/src/views/Campaign/Presentation/PresentationNavBar.tsx b/applications/client/src/views/Campaign/Presentation/PresentationNavBar.tsx index 934e84dc..51eacc42 100644 --- a/applications/client/src/views/Campaign/Presentation/PresentationNavBar.tsx +++ b/applications/client/src/views/Campaign/Presentation/PresentationNavBar.tsx @@ -1,10 +1,11 @@ -import { Button, ButtonGroup, Divider, Intent } from '@blueprintjs/core'; -import { ArrowLeft16, SkipBack16, SkipForward16 } from '@carbon/icons-react'; +import { Breadcrumb, Button, ButtonGroup, Intent } from '@blueprintjs/core'; +import { SkipBack16, SkipForward16 } from '@carbon/icons-react'; import { css } from '@emotion/react'; import { CarbonIcon } from '@redeye/client/components'; import { routes, useStore } from '@redeye/client/store'; import { CampaignViews } from '@redeye/client/types'; -import { Header } from '@redeye/ui-styles'; +import { SlideSelector, breadcrumbLinkStyle } from '@redeye/client/views'; +import { Flex, Header, Spacer, Txt, UtilityStyles, flexChild } from '@redeye/ui-styles'; import { observer } from 'mobx-react-lite'; import type { ComponentProps } from 'react'; @@ -25,42 +26,19 @@ export const PresentationNavBar = observer(({}) => { store.campaign.presentation.index >= (store.campaign.presentation.selectedItem?.commandGroups?.length || 1) - 1; return ( -
-
-
- + + + +
+ ); }); diff --git a/applications/client/src/views/Campaign/Presentation/SlideSelector.tsx b/applications/client/src/views/Campaign/Presentation/SlideSelector.tsx index e21e0fe8..561597b1 100644 --- a/applications/client/src/views/Campaign/Presentation/SlideSelector.tsx +++ b/applications/client/src/views/Campaign/Presentation/SlideSelector.tsx @@ -1,86 +1,61 @@ -import { Button, MenuItem } from '@blueprintjs/core'; +import { Button, Classes, MenuItem } from '@blueprintjs/core'; import { Select } from '@blueprintjs/select'; import { CaretDown16 } from '@carbon/icons-react'; import { css } from '@emotion/react'; -import { CarbonIcon, dateTimeFormat, timeFormat } from '@redeye/client/components'; -import { createState } from '@redeye/client/components/mobx-create-state'; +import { CarbonIcon } from '@redeye/client/components'; import { useStore } from '@redeye/client/store'; +import type { TxtProps } from '@redeye/ui-styles'; import { Txt } from '@redeye/ui-styles'; import { observer } from 'mobx-react-lite'; -import type { ComponentProps } from 'react'; -type SlideSelectorProps = ComponentProps<'div'> & {}; - -export const SlideSelector = observer(({}) => { +export const SlideSelector = observer(({ ...props }) => { const store = useStore(); - const state = createState({ - get min() { - return store.settings.momentTz(store.campaign.presentation.currentSlide?.minDate); - }, - get max() { - return store.settings.momentTz(store.campaign.presentation.currentSlide?.maxDate); - }, - }); - return ( -
- - {store.campaign.presentation.currentSlide?.minDate ? state.min.format(`ddd ${dateTimeFormat}`) : 'Unknown'} - {store.campaign.presentation.currentSlide?.commandIds?.length! > 1 && ( - <> - - {store.campaign.presentation.currentSlide?.maxDate - ? state.max.format(state.max.dayOfYear() > state.min.dayOfYear() ? dateTimeFormat : timeFormat) - : 'Unknown'} - + + {/* Slide: */} + x++)} - onItemSelect={(item) => store.campaign.presentation.changeIndex(item)} - itemRenderer={(item, { handleClick, modifiers }) => ( - - )} - filterable={false} - // matchTargetWidth - popoverProps={{ - minimal: true, - }} + filterable={false} + popoverProps={{ + minimal: true, + // matchTargetWidth: true, + }} + css={css` + display: inline-flex; + align-content: baseline; + `} + > +
+ /> + + of {store.campaign.presentation.selectedItem?.commandGroups?.length} + ); }); From 25ea86ba55f118c49e1a29e2d2d8323f54395ef0 Mon Sep 17 00:00:00 2001 From: James Bradford Date: Tue, 19 Sep 2023 10:00:18 -0700 Subject: [PATCH 04/13] simple presentation mode beacon name header --- .../Presentation/PresentationItemHeader.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/applications/client/src/views/Campaign/Presentation/PresentationItemHeader.tsx b/applications/client/src/views/Campaign/Presentation/PresentationItemHeader.tsx index 2754a828..3d11f032 100644 --- a/applications/client/src/views/Campaign/Presentation/PresentationItemHeader.tsx +++ b/applications/client/src/views/Campaign/Presentation/PresentationItemHeader.tsx @@ -1,7 +1,7 @@ import { dateTimeFormat, timeFormat } from '@redeye/client/components'; import { createState } from '@redeye/client/components/mobx-create-state'; import { useStore } from '@redeye/client/store'; -import { Flex, Txt } from '@redeye/ui-styles'; +import { Flex, Header, Txt } from '@redeye/ui-styles'; import { observer } from 'mobx-react-lite'; import type { ComponentProps } from 'react'; @@ -19,9 +19,14 @@ export const PresentationItemHeader = observer(({}) }, }); + const beacons = store.campaign.presentation.currentSlide?.beacons; + return ( - - +
+
+ {beacons && beacons.length === 1 ? beacons[0].computedNameWithHost : Multiple Beacons} +
+ {store.campaign.presentation.currentSlide?.minDate ? state.min.format(`ddd ${dateTimeFormat}`) : 'Unknown'} {store.campaign.presentation.currentSlide?.commandIds?.length! > 1 && ( <> @@ -32,6 +37,6 @@ export const PresentationItemHeader = observer(({}) )} - +
); }); From 01ae690af03e8bf36911d3cdb4591b1aea776cb2 Mon Sep 17 00:00:00 2001 From: James Bradford Date: Tue, 19 Sep 2023 12:30:19 -0700 Subject: [PATCH 05/13] adding more robust PresentationItemHeader --- .../Presentation/PresentationItemHeader.tsx | 54 +++++++++++++++++-- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/applications/client/src/views/Campaign/Presentation/PresentationItemHeader.tsx b/applications/client/src/views/Campaign/Presentation/PresentationItemHeader.tsx index 3d11f032..94d4e557 100644 --- a/applications/client/src/views/Campaign/Presentation/PresentationItemHeader.tsx +++ b/applications/client/src/views/Campaign/Presentation/PresentationItemHeader.tsx @@ -1,7 +1,9 @@ +import { Tooltip } from '@blueprintjs/core'; import { dateTimeFormat, timeFormat } from '@redeye/client/components'; import { createState } from '@redeye/client/components/mobx-create-state'; import { useStore } from '@redeye/client/store'; -import { Flex, Header, Txt } from '@redeye/ui-styles'; +import type { TxtProps } from '@redeye/ui-styles'; +import { Header, Spacer, Txt } from '@redeye/ui-styles'; import { observer } from 'mobx-react-lite'; import type { ComponentProps } from 'react'; @@ -19,14 +21,28 @@ export const PresentationItemHeader = observer(({}) }, }); - const beacons = store.campaign.presentation.currentSlide?.beacons; + const beaconNames = store.campaign.presentation.currentSlide?.beacons.map((beacon) => beacon.computedName); + + const hostNames = Array.from( + new Set( + store.campaign.presentation.currentSlide?.beacons + .map((beacon) => beacon.host?.current.computedName) + .filter((h) => h) as string[] + ) + ); return (
-
- {beacons && beacons.length === 1 ? beacons[0].computedNameWithHost : Multiple Beacons} +
+ + + + / + + +
- + {store.campaign.presentation.currentSlide?.minDate ? state.min.format(`ddd ${dateTimeFormat}`) : 'Unknown'} {store.campaign.presentation.currentSlide?.commandIds?.length! > 1 && ( <> @@ -40,3 +56,31 @@ export const PresentationItemHeader = observer(({})
); }); + +const PresentationHeaderPart = ({ names, type, ...props }: TxtProps & { names?: string[]; type: string }) => ( + <> + {names == null ? ( + + Unknown {type} + + ) : names.length === 1 ? ( + {names[0]} + ) : ( + + {names.map((name) => ( +
  • {name}
  • + ))} + + } + > + + Multiple {type}s + +
    + )} + +); From f23ef2cfe2b79104f01b903c48da7a14013b1790 Mon Sep 17 00:00:00 2001 From: James Bradford Date: Tue, 19 Sep 2023 12:31:21 -0700 Subject: [PATCH 06/13] removing the header-like nav breadcrumbs from the CommentGroup --- .../Explore/Panels/Comment/CommentGroup.tsx | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/applications/client/src/views/Campaign/Explore/Panels/Comment/CommentGroup.tsx b/applications/client/src/views/Campaign/Explore/Panels/Comment/CommentGroup.tsx index 19b13a3b..e5bf4df7 100644 --- a/applications/client/src/views/Campaign/Explore/Panels/Comment/CommentGroup.tsx +++ b/applications/client/src/views/Campaign/Explore/Panels/Comment/CommentGroup.tsx @@ -2,7 +2,7 @@ import { css } from '@emotion/react'; import type { AnnotationModel } from '@redeye/client/store'; import { useStore } from '@redeye/client/store'; import type { CommandSummaryProps } from '@redeye/client/views'; -import { CommandRow, CommentBox, NavBreadcrumbs } from '@redeye/client/views'; +import { CommandRow, CommentBox } from '@redeye/client/views'; import { CoreTokens, ThemeClasses, Flex } from '@redeye/ui-styles'; import type { Ref } from 'mobx-keystone'; import { observer } from 'mobx-react-lite'; @@ -33,12 +33,6 @@ export const CommentGroup = observer( }) => { const store = useStore(); const commandGroup = store.graphqlStore.commandGroups.get(commandGroupId); - const firstCommandId = commandGroup?.commandIds?.[0]; - const firstCommand = firstCommandId && store.graphqlStore.commands.get(firstCommandId); - - // `showPath === 'server'` in this case means show the header path for presentation mode - // TODO: what in case of Multi-Beacon Comment? - const showNavPath = !!(showPath === 'server' && firstCommand); return (
    ( )} - {showNavPath && ( - - )} {!hideCommands && commandGroup?.commandIds?.map((commandId) => ( ( css={{ borderBottom: 'none !important' }} key={`${commandGroup?.id}${commandId}`} hideCommentButton - showPath={!showNavPath && showPath} + showPath={showPath} expandedCommandIDs={expandedCommandIDs} removeExpandedCommandID={removeExpandedCommandID} /> From a9da61a4d1621129a80723063797206207b15e6b Mon Sep 17 00:00:00 2001 From: James Bradford Date: Tue, 19 Sep 2023 14:13:13 -0700 Subject: [PATCH 07/13] forgot .map() key --- .../src/views/Campaign/Presentation/PresentationItemHeader.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/client/src/views/Campaign/Presentation/PresentationItemHeader.tsx b/applications/client/src/views/Campaign/Presentation/PresentationItemHeader.tsx index 94d4e557..bcc872a9 100644 --- a/applications/client/src/views/Campaign/Presentation/PresentationItemHeader.tsx +++ b/applications/client/src/views/Campaign/Presentation/PresentationItemHeader.tsx @@ -72,7 +72,7 @@ const PresentationHeaderPart = ({ names, type, ...props }: TxtProps & { names?: content={
      {names.map((name) => ( -
    • {name}
    • +
    • {name}
    • ))}
    } From 761ff90c0d964cf2adeeb84474712490dd4d51c0 Mon Sep 17 00:00:00 2001 From: James Bradford Date: Tue, 19 Sep 2023 14:33:07 -0700 Subject: [PATCH 08/13] update HierarchicalGraphData.selectNodes() to accept an array --- .../client/src/store/campaign/interaction-state.ts | 4 ++-- applications/redeye-e2e/src/support/beacon.js | 2 +- .../graph/src/GraphData/HierarchicalGraphData.ts | 13 ++++++++----- packages/graph/src/GraphHandler.ts | 3 ++- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/applications/client/src/store/campaign/interaction-state.ts b/applications/client/src/store/campaign/interaction-state.ts index afe01dbd..a4ca1ce1 100644 --- a/applications/client/src/store/campaign/interaction-state.ts +++ b/applications/client/src/store/campaign/interaction-state.ts @@ -206,8 +206,8 @@ export class InteractionState extends ExtendedModel(() => ({ else this.selectedCommandType = undefined; if (beaconId || hostId || serverId) { - this.appStore?.campaign.graph?.graphData.selectNode( - (beaconId || hostId || this.selectedServer?.maybeCurrent?.serverHost?.id)!, + this.appStore?.campaign.graph?.graphData.selectNodes( + [(beaconId || hostId || this.selectedServer?.maybeCurrent?.serverHost?.id)!], false ); } else { diff --git a/applications/redeye-e2e/src/support/beacon.js b/applications/redeye-e2e/src/support/beacon.js index fb193759..15f82cf8 100644 --- a/applications/redeye-e2e/src/support/beacon.js +++ b/applications/redeye-e2e/src/support/beacon.js @@ -71,7 +71,7 @@ Cypress.Commands.add('addMultiCommandComment', () => { Cypress.Commands.add('beaconClick', (id) => { cy.wait(1000); return cy.window().then((win) => { - win.graph.graphData.selectNode(id); + win.graph.graphData.selectNode([id]); }); }); diff --git a/packages/graph/src/GraphData/HierarchicalGraphData.ts b/packages/graph/src/GraphData/HierarchicalGraphData.ts index 922f1a24..d1e4d37b 100644 --- a/packages/graph/src/GraphData/HierarchicalGraphData.ts +++ b/packages/graph/src/GraphData/HierarchicalGraphData.ts @@ -335,12 +335,15 @@ export class HierarchicalGraphData { } } - selectNode(node: HierarchicalGraphNode | string, fireEvent = true) { - const _node = typeof node === 'string' ? this.allNodes.get(node) : node; - if (!_node) return; + selectNodes(nodes: (HierarchicalGraphNode | string)[], fireEvent = true) { this.clearSelection(false); - this.addNodeToSelection(_node, false); - if (fireEvent) this.onSelectionChange(_node, Array.from(this.selectionSet)); + for (let i = 0; i < nodes.length; i++) { + const node = nodes[i]; + const _node = typeof node === 'string' ? this.allNodes.get(node) : node; + if (!_node) return; + this.addNodeToSelection(_node, false); + if (fireEvent) this.onSelectionChange(_node, Array.from(this.selectionSet)); + } } addNodeToSelection(node: HierarchicalGraphNode, fireEvent = true) { this.addToSet(node, 'selection'); diff --git a/packages/graph/src/GraphHandler.ts b/packages/graph/src/GraphHandler.ts index da1605e2..2d5e36da 100644 --- a/packages/graph/src/GraphHandler.ts +++ b/packages/graph/src/GraphHandler.ts @@ -293,7 +293,8 @@ export class GraphHandler { clickNode(_event: PointerEvent, node: HierarchicalGraphNode) { if (node.selectedFocus) this.graphData.clearSelection(); - else this.graphData.selectNode(node); + // else if (_event.metaKey) this.graphData.addNodeToSelection(node); + else this.graphData.selectNodes([node]); } mouseOverNode(_event: PointerEvent, node: HierarchicalGraphNode) { if (!this.dragState.isDragging) this.graphData.previewNode(node); From f39456a6b953e9dc0a1e5cf68b73f86e7494649a Mon Sep 17 00:00:00 2001 From: James Bradford Date: Tue, 19 Sep 2023 14:34:23 -0700 Subject: [PATCH 09/13] InteractionState.changeSelected selects multiple beacons if in presentation mode --- .../client/src/store/campaign/interaction-state.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/applications/client/src/store/campaign/interaction-state.ts b/applications/client/src/store/campaign/interaction-state.ts index a4ca1ce1..b6d6be96 100644 --- a/applications/client/src/store/campaign/interaction-state.ts +++ b/applications/client/src/store/campaign/interaction-state.ts @@ -44,7 +44,7 @@ export class InteractionState extends ExtendedModel(() => ({ })) { protected onAttachedToRootStore(rootStore: any): (() => void) | void { return reaction( - () => [rootStore.router.params.currentItemId, !!rootStore.campaign.graph], + () => [rootStore.router.params.currentItemId, rootStore.router.params.slide, !!rootStore.campaign.graph], () => { this.changeSelected(); }, @@ -159,7 +159,7 @@ export class InteractionState extends ExtendedModel(() => ({ this.appStore.campaign.timeline?.selectedBeacons.clear(); this.appStore.campaign.timeline?.selectedChainedBeacons.clear(); if (beacon) { - this.appStore.campaign.timeline?.setBeacon(this.currentBeacons.get(beacon)); + this.appStore.campaign.timeline?.setBeacon(this.currentBeacons.get(beacon)); // } else if (host) { const comp = this.currentHosts.get(host); if (comp) { @@ -175,7 +175,15 @@ export class InteractionState extends ExtendedModel(() => ({ } } } - this.setSelectedModels(beacon, host, server, operator, commandType); + const isPresentation = this.appStore?.router.params.view === CampaignViews.PRESENTATION; + if (isPresentation) { + // TODO: changeSelected => this.appStore.campaign.timeline?.setBeacon for multiple beacons too + const beaconIds = this.appStore?.campaign.presentation.currentSlide?.beacons.map((beacon) => beacon.id); + if (beaconIds) this.appStore?.campaign.graph?.graphData.selectNodes(beaconIds); + else this.appStore?.campaign.graph?.graphData.clearSelection(); + } else { + this.setSelectedModels(beacon, host, server, operator, commandType); + } } } From 8ceac9ba088423a9726b5dac6b00a16c25070aad Mon Sep 17 00:00:00 2001 From: James Bradford Date: Tue, 19 Sep 2023 14:37:03 -0700 Subject: [PATCH 10/13] simplify routing by removing /:currentItem from from RedEyeRoutes.CAMPAIGN_PRESENTATION_SELECTED --- .../client/src/store/campaign/presentation.ts | 31 +++++++------------ .../client/src/store/routing/router.ts | 2 +- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/applications/client/src/store/campaign/presentation.ts b/applications/client/src/store/campaign/presentation.ts index 3f9daddb..01ac351e 100644 --- a/applications/client/src/store/campaign/presentation.ts +++ b/applications/client/src/store/campaign/presentation.ts @@ -30,25 +30,16 @@ export class PresentationStore extends ExtendedModel(RedEyeModel, {}) { @modelAction async changeIndex(index: number, presentation?: string) { if (this.appStore?.router.params.presentation || presentation) { - const currentSlide = presentation - ? this.appStore?.graphqlStore.presentationItems.get(presentation)?.commandGroups?.[index]?.current - : this.selectedItem?.commandGroups?.[index]?.current; - const beaconId = currentSlide?.beaconIds?.[(currentSlide?.beaconIds?.length || 1) - 1]; - const beacon = beaconId && this.appStore?.graphqlStore.beacons.get(beaconId); - if (beacon) { - this.appStore?.router.updateRoute({ - path: routes[CampaignViews.PRESENTATION], - params: { - presentation: presentation || this.selectedItem?.id, - slide: `${index + 1}`, - currentItem: 'beacon', - currentItemId: beacon.id as UUID, - activeItem: undefined, - activeItemId: undefined, - }, - }); - this.updateTimeline(); - } + this.appStore?.router.updateRoute({ + path: routes[CampaignViews.PRESENTATION], + params: { + presentation: presentation || this.selectedItem?.id, + slide: `${index + 1}`, + activeItem: undefined, + activeItemId: undefined, + }, + }); + this.updateTimeline(); } } @@ -73,6 +64,6 @@ export class PresentationStore extends ExtendedModel(RedEyeModel, {}) { this.appStore?.campaign.timeline.setScrubberTimeAny(this.appStore?.campaign.timeline.endTime); } this.appStore?.campaign?.interactionState.onHoverOut({}); - this.appStore?.campaign.interactionState.changeSelected(); + this.appStore?.campaign.interactionState.changeSelected(); // } } diff --git a/applications/client/src/store/routing/router.ts b/applications/client/src/store/routing/router.ts index da5d5f80..583424ca 100644 --- a/applications/client/src/store/routing/router.ts +++ b/applications/client/src/store/routing/router.ts @@ -26,7 +26,7 @@ export const RedEyeRoutes = { CAMPAIGN: '/campaign/:id', CAMPAIGN_EXPLORE: `${CampaignViews.EXPLORE}/:currentItem/:tab`, CAMPAIGN_PRESENTATION: `${CampaignViews.PRESENTATION}`, - CAMPAIGN_PRESENTATION_SELECTED: ':presentation/:slide/:currentItem', + CAMPAIGN_PRESENTATION_SELECTED: ':presentation/:slide', CAMPAIGN_SEARCH: `${CampaignViews.SEARCH}`, }; From 4825b5adffd5112be9ea0c936d1a8ca5b76bc0cf Mon Sep 17 00:00:00 2001 From: James Bradford Date: Tue, 19 Sep 2023 14:48:12 -0700 Subject: [PATCH 11/13] repair presentation timeline beacon highlighting --- .../src/store/campaign/interaction-state.ts | 48 +++++++++++-------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/applications/client/src/store/campaign/interaction-state.ts b/applications/client/src/store/campaign/interaction-state.ts index b6d6be96..f34e3619 100644 --- a/applications/client/src/store/campaign/interaction-state.ts +++ b/applications/client/src/store/campaign/interaction-state.ts @@ -155,33 +155,39 @@ export class InteractionState extends ExtendedModel(() => ({ @modelAction changeSelected() { if (this.appStore) { - const { server, host, operator, beacon, commandType } = this.currentItem?.items || {}; this.appStore.campaign.timeline?.selectedBeacons.clear(); this.appStore.campaign.timeline?.selectedChainedBeacons.clear(); - if (beacon) { - this.appStore.campaign.timeline?.setBeacon(this.currentBeacons.get(beacon)); // - } else if (host) { - const comp = this.currentHosts.get(host); - if (comp) { - for (const hostBeaconId of comp.beaconIds) { - this.appStore.campaign.timeline?.setBeacon(this.currentBeacons.get(hostBeaconId)); + const isPresentation = this.appStore?.router.params.view === CampaignViews.PRESENTATION; + if (isPresentation) { + const beacons = this.appStore.campaign.presentation.currentSlide?.beacons; + const beaconIds = beacons?.map((beacon) => beacon.id); + if (beaconIds) { + for (const beaconId of beaconIds) { + this.appStore.campaign.timeline?.setBeacon(this.currentBeacons.get(beaconId)); } + this.appStore.campaign.graph?.graphData.selectNodes(beaconIds); + } else { + this.appStore.campaign.graph?.graphData.clearSelection(); } - } else if (server) { - const comp = this.appStore.graphqlStore.servers.get(server); - if (comp) { - for (const serverBeacon of comp.beacons) { - this.appStore.campaign.timeline?.setBeacon(this.currentBeacons.get(serverBeacon.id)); + } else { + const { server, host, operator, beacon, commandType } = this.currentItem?.items || {}; + if (beacon) { + this.appStore.campaign.timeline?.setBeacon(this.currentBeacons.get(beacon)); + } else if (host) { + const comp = this.currentHosts.get(host); + if (comp) { + for (const hostBeaconId of comp.beaconIds) { + this.appStore.campaign.timeline?.setBeacon(this.currentBeacons.get(hostBeaconId)); + } + } + } else if (server) { + const comp = this.appStore.graphqlStore.servers.get(server); + if (comp) { + for (const serverBeacon of comp.beacons) { + this.appStore.campaign.timeline?.setBeacon(this.currentBeacons.get(serverBeacon.id)); + } } } - } - const isPresentation = this.appStore?.router.params.view === CampaignViews.PRESENTATION; - if (isPresentation) { - // TODO: changeSelected => this.appStore.campaign.timeline?.setBeacon for multiple beacons too - const beaconIds = this.appStore?.campaign.presentation.currentSlide?.beacons.map((beacon) => beacon.id); - if (beaconIds) this.appStore?.campaign.graph?.graphData.selectNodes(beaconIds); - else this.appStore?.campaign.graph?.graphData.clearSelection(); - } else { this.setSelectedModels(beacon, host, server, operator, commandType); } } From ba28a73da9d847c8bc6d1c160707fdb109862ae7 Mon Sep 17 00:00:00 2001 From: James Bradford Date: Tue, 19 Sep 2023 15:10:46 -0700 Subject: [PATCH 12/13] fix another issue with removing currentItemParams from router --- applications/client/src/store/routing/router.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/client/src/store/routing/router.ts b/applications/client/src/store/routing/router.ts index 583424ca..83885758 100644 --- a/applications/client/src/store/routing/router.ts +++ b/applications/client/src/store/routing/router.ts @@ -37,7 +37,7 @@ export const routes = { [Views.CAMPAIGN]: RedEyeRoutes.CAMPAIGN, [Views.CAMPAIGNS_LIST]: RedEyeRoutes.CAMPAIGNS_LIST, [CampaignViews.EXPLORE]: `${RedEyeRoutes.CAMPAIGN}/:view(${CampaignViews.EXPLORE})/${currentItemParams}/:tab(${tabs})?/${activeItemParams}`, - [CampaignViews.PRESENTATION]: `${RedEyeRoutes.CAMPAIGN}/:view(${CampaignViews.PRESENTATION})/:presentation?/:slide?/${currentItemParams}/${activeItemParams}`, + [CampaignViews.PRESENTATION]: `${RedEyeRoutes.CAMPAIGN}/:view(${CampaignViews.PRESENTATION})/:presentation?/:slide?/${activeItemParams}`, [CampaignViews.SEARCH]: `${RedEyeRoutes.CAMPAIGN}/:view(${CampaignViews.SEARCH})`, }; From 4a75adfc18ef46c3a545b4c4594d6fab073a1d0e Mon Sep 17 00:00:00 2001 From: James Bradford Date: Tue, 19 Sep 2023 15:16:26 -0700 Subject: [PATCH 13/13] remove stray comment --- applications/client/src/store/campaign/presentation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/client/src/store/campaign/presentation.ts b/applications/client/src/store/campaign/presentation.ts index 01ac351e..b9ebbe13 100644 --- a/applications/client/src/store/campaign/presentation.ts +++ b/applications/client/src/store/campaign/presentation.ts @@ -64,6 +64,6 @@ export class PresentationStore extends ExtendedModel(RedEyeModel, {}) { this.appStore?.campaign.timeline.setScrubberTimeAny(this.appStore?.campaign.timeline.endTime); } this.appStore?.campaign?.interactionState.onHoverOut({}); - this.appStore?.campaign.interactionState.changeSelected(); // + this.appStore?.campaign.interactionState.changeSelected(); } }