in src/hub.tsx [32:219]
export function Hub() {
const [items, setItems] = useState<GanttHubDocument[]>([]);
const [context, setContext] = useState<HubContext>({
workItemTypes: new Map<string, string>(),
progressMap: new Map<string, ProgressInterface>()
} as HubContext);
const [hubState, setHubState] = useState<IHubState>({ backButtonEnabled: false, panelExpanded: false, itemToEdit: undefined, fullScreenMode: false });
const { ganttId, panelExpanded, itemToEdit, backButtonEnabled, headerDescription, useLargeTitle } = hubState;
const { workItemTypes, progressMap, project } = context;
useEffect(() => {
const accessTokenReady: DaemonEventCallback<void> = () => {
SDK.getAccessToken().then(accessToken => {
daemonController.fireCommand(daemonCommandBuilder()
.type(DaemonCommandType.REFRESH_ACCESS_TOKEN)
.payload(accessToken)
.build())
});
};
daemonController.registerHandler(DaemonEventHandler.builder<void>()
.eventType(DaemonEventType.ACCESS_TOKEN_REQUESTED)
.callback(accessTokenReady)
.build());
const load = async () => {
await SDK.init();
const locationService = await SDK.getService<ILocationService>(CommonServiceIds.LocationService);
const projectService = await SDK.getService<IProjectPageService>(CommonServiceIds.ProjectPageService);
const project = await projectService.getProject();
const { id, name, serviceVersion } = SDK.getHost();
const serviceHost = await locationService.getServiceLocation(id);
daemonController.init({ id, name, serviceVersion, serviceHost } as DaemonConfiguration);
daemonController.fireCommand(daemonCommandBuilder()
.type(DaemonCommandType.AGGREGATE_EXECUTE)
.source(Hub.name)
.cancelable(true)
.next(daemonCommandBuilder()
.type(DaemonCommandType.NO_OP)
.payload({ project })
.next(daemonCommandBuilder()
.type(DaemonCommandType.LOAD_ASSETS)
.next(daemonCommandBuilder()
.type(DaemonCommandType.BUILD_PROGRESS_MAP)
.build())
.build())
.build())
.build());
initializeFullScreenState();
};
load().catch(console.error);
return () => {
daemonController.close();
};
}, []);
useEffect(() => {
const contextLoaded: DaemonEventCallback<HubContext> = (event) => {
const context = event.payload!;
setContext(context);
};
const progressMapReady: DaemonEventCallback<ProgressMapReadyPayload> = (event) => {
const { progressMap } = event.payload!
setContext({ ...context, progressMap });
};
daemonController.registerHandler(DaemonEventHandler.builder<HubContext>()
.eventType(DaemonEventType.AGGREGATE_READY)
.componentName(Hub.name)
.callback(contextLoaded)
.build());
daemonController.registerHandler(DaemonEventHandler.builder<ProgressMapReadyPayload>()
.eventType(DaemonEventType.PROGRESS_MAP_READY)
.callback(progressMapReady)
.build());
return () => {
daemonController.unregisterHandler(DaemonEventType.PROGRESS_MAP_READY);
daemonController.unregisterHandler(DaemonEventType.AGGREGATE_READY + Hub.name);
}
}, [context]);
useEffect(() => {
(async () => {
if (!backButtonEnabled && !panelExpanded) {
const items = await ExtensionManagementUtil.getItems().handle([], "Failed to fetch gannt items");
setItems(items);
}
})();
}, [panelExpanded, backButtonEnabled])
const onPanelClick = async () => {
setHubState(current => ({ ...current, panelExpanded: true }));
}
const getCommandBarItems = (ids: Set<string> = new Set()): IHeaderCommandBarItem[] => {
const { fullScreenMode } = hubState;
const buttons = [
{
id: "gantt",
text: "Gantt",
onActivate: () => { onPanelClick() },
iconProps: {
iconName: 'Add'
},
isPrimary: true,
tooltipProps: {
text: "Open a panel with custom extension content"
}
},
{
id: "fullScreen",
ariaLabel: fullScreenMode ? "Exit full screen mode" : "Enter full screen mode",
iconProps: {
iconName: fullScreenMode ? "BackToWindow" : "FullScreen"
},
onActivate: () => { onToggleFullScreenMode() }
}
];
return buttons.filter(it => !ids.has(it.id));
};
const initializeFullScreenState = async () => {
const layoutService = await SDK.getService<IHostPageLayoutService>(CommonServiceIds.HostPageLayoutService);
const fullScreenMode = await layoutService.getFullScreenMode().handle(false, 'Full screen cant be loaded');
if (fullScreenMode !== hubState.fullScreenMode) {
setHubState(current => ({ ...current, fullScreenMode }));
}
}
const onToggleFullScreenMode = async () => {
const fullScreenMode = !hubState.fullScreenMode!;
setHubState(current => ({ ...current, fullScreenMode }));
const layoutService = await SDK.getService<IHostPageLayoutService>(CommonServiceIds.HostPageLayoutService);
layoutService.setFullScreenMode(fullScreenMode);
}
const onRowSelect = React.useCallback((data: ITableItem, isChecked: boolean) => {
setItems([]);
setHubState(current => ({ ...current, ganttId: data.id, backButtonEnabled: !isChecked }))
}, [backButtonEnabled]);
const onPanelDismiss = React.useCallback((isChecked: boolean) => {
setHubState(current => ({ ...current, panelExpanded: !isChecked, itemToEdit: undefined }))
}, [panelExpanded]);
const showEditPanel = React.useCallback((itemToEdit: GanttHubDocument) => {
setHubState(current => ({ ...current, panelExpanded: true, itemToEdit }))
}, [itemToEdit]);
const backButtonHandler = () => {
daemonController.fireCommand(daemonCommandBuilder().type(DaemonCommandType.CANCEL).build());
setHubState(current => ({ ...current, backButtonEnabled: false }));
}
return (
<RootHubContext.Provider value={{ workItemTypes, progressMap, project, daemonController }}>
<Page className="sample-hub flex-grow">
<Header title="Delivery Gantt"
commandBarItems={!backButtonEnabled ? getCommandBarItems() : getCommandBarItems(new Set(["gantt"]))}
description={headerDescription}
backButtonProps={backButtonEnabled ? { onClick: backButtonHandler } : undefined}
titleSize={useLargeTitle ? TitleSize.Large : TitleSize.Medium} />
{panelExpanded &&
<GanttDetailsPanel itemToEdit={itemToEdit} isChecked={panelExpanded} onDismiss={onPanelDismiss} />
}
{!backButtonEnabled ?
<BoardPage onRowEdit={showEditPanel} isChecked={backButtonEnabled} onRowSelect={onRowSelect} items={items} />
: <GanttPage ganttId={ganttId!} />
}
</Page>
</RootHubContext.Provider>
);
}