Skip to content

Commit

Permalink
refactor: move selected building id into store
Browse files Browse the repository at this point in the history
which makes custom handling in threeSceneService deprecated. Having only one global state and flow is more maintanable in general and in concrete it facilitates migrating to Angular.

refs: #2318
  • Loading branch information
shaman-apprentice committed Sep 11, 2021
1 parent 96bb3c3 commit bc58e65
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 4 deletions.
2 changes: 2 additions & 0 deletions visualization/app/codeCharta/codeCharta.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { FileState } from "./model/files/files"
import { CustomConfig } from "./model/customConfig/customConfig.api.model"
import Rectangle from "./util/algorithm/streetLayout/rectangle"
import { SecondaryMetric } from "./ui/attributeSideBar/attributeSideBar.component"
import { SetSelectedBuildingIdPayload } from "./state/store/lookUp/selectedBuildingId/selectedBuildingId.actions"

export interface NameDataPair {
fileName: string
Expand Down Expand Up @@ -391,6 +392,7 @@ export interface CCAction extends Action {
export interface LookUp {
idToNode: Map<number, CodeMapNode>
idToBuilding: Map<number, CodeMapBuilding>
selectedBuildingId: SetSelectedBuildingIdPayload
}

export enum PanelSelection {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { CCAction, RecursivePartial, LookUp } from "../../../codeCharta.model"
// Plop: Append default property import here
import { defaultIdToNode } from "./idToNode/idToNode.actions"
import { defaultIdToBuilding } from "./idToBuilding/idToBuilding.actions"
import { defaultSelectedBuildingId } from "./selectedBuildingId/selectedBuildingId.actions"

export enum LookUpActions {
SET_LOOK_UP = "SET_LOOK_UP"
Expand All @@ -25,5 +26,6 @@ export function setLookUp(lookUp: RecursivePartial<LookUp> = defaultLookUp): Loo
export const defaultLookUp: LookUp = {
// Plop: Append default property here
idToNode: defaultIdToNode,
idToBuilding: defaultIdToBuilding
idToBuilding: defaultIdToBuilding,
selectedBuildingId: defaultSelectedBuildingId
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
// Plop: Append reducer import here
import { idToNode } from "./idToNode/idToNode.reducer"
import { idToBuilding } from "./idToBuilding/idToBuilding.reducer"
import { selectedBuildingId } from "./selectedBuildingId/selectedBuildingId.reducer"
import { combineReducers } from "redux"

const lookUp = combineReducers({
// Plop: Append sub-reducer here
idToNode,
idToBuilding
idToBuilding,
selectedBuildingId
})

export default lookUp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Action } from "redux"
import { SetIdToBuildingAction } from "../idToBuilding/idToBuilding.actions"

export enum SelectedBuildingIdActions {
SET_SELECTED_BUILDING_ID = "SET_SELECTED_BUILDING_ID"
}

type InferredKeyOfMap<M> = M extends Map<infer K, unknown> ? K : never
export type SetSelectedBuildingIdPayload = InferredKeyOfMap<SetIdToBuildingAction["payload"]> | null

export interface SetSelectedBuildingIdAction extends Action {
type: SelectedBuildingIdActions.SET_SELECTED_BUILDING_ID
payload: SetSelectedBuildingIdPayload
}

export const defaultSelectedBuildingId: SetSelectedBuildingIdPayload = null

export const setSelectedBuildingId = (
selectedBuilding: SetSelectedBuildingIdPayload = defaultSelectedBuildingId
): SetSelectedBuildingIdAction => ({
type: SelectedBuildingIdActions.SET_SELECTED_BUILDING_ID,
payload: selectedBuilding
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { setSelectedBuildingId } from "./selectedBuildingId.actions"
import { selectedBuildingId } from "./selectedBuildingId.reducer"

describe("selectedBuildingId", () => {
it("should set default state", () => {
const newState = selectedBuildingId(undefined, { type: "someType" })
expect(newState).toBe(null)
})

it("should update state", () => {
const newState = selectedBuildingId(undefined, setSelectedBuildingId(1))
expect(newState).toBe(1)
})

it("should ignore actions other than its own", () => {
const newState = selectedBuildingId(1, { type: "someType", payload: 2 })
expect(newState).toBe(1)
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {
SetSelectedBuildingIdPayload,
SelectedBuildingIdActions,
SetSelectedBuildingIdAction,
setSelectedBuildingId
} from "./selectedBuildingId.actions"

export const selectedBuildingId = (
state: SetSelectedBuildingIdPayload = setSelectedBuildingId().payload,
action: Record<string, unknown> | SetSelectedBuildingIdAction
) => {
switch (action.type) {
case SelectedBuildingIdActions.SET_SELECTED_BUILDING_ID:
return (<SetSelectedBuildingIdAction>action).payload
default:
return state
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { CodeMapNode, MapColors } from "../../../codeCharta.model"
import { hierarchy } from "d3-hierarchy"
import { ColorConverter } from "../../../util/color/colorConverter"
import { MapColorsSubscriber, MapColorsService } from "../../../state/store/appSettings/mapColors/mapColors.service"
import { setSelectedBuildingId } from "../../../state/store/lookUp/selectedBuildingId/selectedBuildingId.actions"

export interface BuildingSelectedEventSubscriber {
onBuildingSelected(selectedBuilding?: CodeMapBuilding)
Expand Down Expand Up @@ -163,6 +164,9 @@ export class ThreeSceneService implements CodeMapPreRenderServiceSubscriber, Map
this.selected = building
this.highlightBuildings()
this.$rootScope.$broadcast(ThreeSceneService.BUILDING_SELECTED_EVENT, this.selected)
// after clean up of custom broadcast hell through $rootScope we can probably remove this if condition
if (building.id !== this.selected?.id) this.storeService.dispatch(setSelectedBuildingId(building.id))

if (this.mapGeometry.children[0]) {
this.selectMaterial(this.mapGeometry.children[0]["material"])
}
Expand Down Expand Up @@ -342,6 +346,7 @@ export class ThreeSceneService implements CodeMapPreRenderServiceSubscriber, Map
if (this.selected) {
this.getMapMesh().clearSelection(this.selected)
this.$rootScope.$broadcast(ThreeSceneService.BUILDING_DESELECTED_EVENT)
this.storeService.dispatch(setSelectedBuildingId(null))
}
if (this.highlighted.length > 0) {
this.highlightBuildings()
Expand Down Expand Up @@ -384,6 +389,7 @@ export class ThreeSceneService implements CodeMapPreRenderServiceSubscriber, Map
return this.mapMesh
}

/** @deprecated - connect to store instead */
getSelectedBuilding() {
return this.selected
}
Expand Down Expand Up @@ -422,6 +428,7 @@ export class ThreeSceneService implements CodeMapPreRenderServiceSubscriber, Map
})
}

/** @deprecated - connect to store instead */
static subscribeToBuildingSelectedEvents($rootScope: IRootScopeService, subscriber: BuildingSelectedEventSubscriber) {
$rootScope.$on(this.BUILDING_SELECTED_EVENT, (_event, selectedBuilding: CodeMapBuilding) => {
subscriber.onBuildingSelected(selectedBuilding)
Expand Down
6 changes: 4 additions & 2 deletions visualization/app/codeCharta/util/dataMocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1790,7 +1790,8 @@ export const STATE: State = {
files: [],
lookUp: {
idToNode: new Map(),
idToBuilding: new Map()
idToBuilding: new Map(),
selectedBuildingId: null
},
metricData: {
nodeMetricData: METRIC_DATA,
Expand Down Expand Up @@ -1871,7 +1872,8 @@ export const DEFAULT_STATE: State = {
files: [],
lookUp: {
idToBuilding: new Map(),
idToNode: new Map()
idToNode: new Map(),
selectedBuildingId: null
},
metricData: {
nodeMetricData: [],
Expand Down

0 comments on commit bc58e65

Please sign in to comment.