From 122b017ec3213fa1835d66d16ab7f45285b9fbfb Mon Sep 17 00:00:00 2001 From: Kamy Date: Wed, 11 Sep 2024 13:33:28 -0400 Subject: [PATCH] Fix(ExportTemplate): fix export template legend issue (#2459) * fix(ExportTemplate): fix export template closes2458 * fix(ExportTemplate): fix export template closes2458 * fix(ExportTemplate): fix export template closes2458 --- .../feature-info-event-processor.ts | 2 +- .../ui-event-processor.ts | 4 +-- .../core/components/app-bar/app-bar-api.ts | 4 +-- .../src/core/components/app-bar/app-bar.tsx | 5 +-- .../core/components/export/export-modal.tsx | 7 ++-- .../core/components/geolocator/geolocator.tsx | 34 +++++++++++++++++-- .../ui-state.ts | 15 ++++---- .../geoview-core/src/ui/panel/panel-types.ts | 2 ++ packages/geoview-core/src/ui/panel/panel.tsx | 4 +-- 9 files changed, 57 insertions(+), 20 deletions(-) diff --git a/packages/geoview-core/src/api/event-processors/event-processor-children/feature-info-event-processor.ts b/packages/geoview-core/src/api/event-processors/event-processor-children/feature-info-event-processor.ts index 699a079c5bd..63be5f9b2ee 100644 --- a/packages/geoview-core/src/api/event-processors/event-processor-children/feature-info-event-processor.ts +++ b/packages/geoview-core/src/api/event-processors/event-processor-children/feature-info-event-processor.ts @@ -145,7 +145,7 @@ export class FeatureInfoEventProcessor extends AbstractEventProcessor { // Open details appbar tab when user clicked on map layer. if (UIEventProcessor.getAppBarComponents(mapId).includes('details')) { - UIEventProcessor.setActiveAppBarTab(mapId, 'AppbarPanelButtonDetails', 'details', true); + UIEventProcessor.setActiveAppBarTab(mapId, `${mapId}AppbarPanelButtonDetails`, 'details', true, true); } } } else if (eventType === 'name') { diff --git a/packages/geoview-core/src/api/event-processors/event-processor-children/ui-event-processor.ts b/packages/geoview-core/src/api/event-processors/event-processor-children/ui-event-processor.ts index 798bf94cc63..96de17ab362 100644 --- a/packages/geoview-core/src/api/event-processors/event-processor-children/ui-event-processor.ts +++ b/packages/geoview-core/src/api/event-processors/event-processor-children/ui-event-processor.ts @@ -63,8 +63,8 @@ export class UIEventProcessor extends AbstractEventProcessor { this.getUIStateProtected(mapId).setterActions.setActiveFooterBarTab(id); } - static setActiveAppBarTab(mapId: string, tabId: string, tabGroup: string, isOpen: boolean): void { - this.getUIStateProtected(mapId).setterActions.setActiveAppBarTab(tabId, tabGroup, isOpen); + static setActiveAppBarTab(mapId: string, tabId: string, tabGroup: string, isOpen: boolean, isFocusTrapped: boolean): void { + this.getUIStateProtected(mapId).setterActions.setActiveAppBarTab(tabId, tabGroup, isOpen, isFocusTrapped); } static getActiveAppBarTab(mapId: string): ActiveAppBarTabType { diff --git a/packages/geoview-core/src/core/components/app-bar/app-bar-api.ts b/packages/geoview-core/src/core/components/app-bar/app-bar-api.ts index 138ca824280..db0a78fce36 100644 --- a/packages/geoview-core/src/core/components/app-bar/app-bar-api.ts +++ b/packages/geoview-core/src/core/components/app-bar/app-bar-api.ts @@ -232,8 +232,8 @@ export class AppBarApi { * @param {string} tabGroup - The id of the panel * @param {boolean} open - Open (true) or closed (false) panel: default = true */ - selectAppBarTab(tabId: string, tabGroup: string, open: boolean = true): void { - UIEventProcessor.setActiveAppBarTab(this.mapId, tabId, tabGroup, open); + selectAppBarTab(tabId: string, tabGroup: string, open: boolean = true, isFocusTrapped: boolean = true): void { + UIEventProcessor.setActiveAppBarTab(this.mapId, tabId, tabGroup, open, isFocusTrapped); } } diff --git a/packages/geoview-core/src/core/components/app-bar/app-bar.tsx b/packages/geoview-core/src/core/components/app-bar/app-bar.tsx index dfe0ff0bc12..f742578d81f 100644 --- a/packages/geoview-core/src/core/components/app-bar/app-bar.tsx +++ b/packages/geoview-core/src/core/components/app-bar/app-bar.tsx @@ -163,7 +163,7 @@ export function AppBar(props: AppBarProps): JSX.Element { // Get the button panel const buttonPanel = buttonPanelGroups[groupName][buttonId]; - setActiveAppBarTab(buttonId, groupName, !buttonPanel.panel?.status); + setActiveAppBarTab(buttonId, groupName, !buttonPanel.panel?.status, !buttonPanel.panel?.status); }, [buttonPanelGroups, setActiveAppBarTab] ); @@ -173,7 +173,7 @@ export function AppBar(props: AppBarProps): JSX.Element { // Log logger.logTraceUseCallback('APP-BAR - handleGeneralCloseClicked'); - setActiveAppBarTab(buttonId, groupName, false); + setActiveAppBarTab(buttonId, groupName, false, false); }, [setActiveAppBarTab] ); @@ -255,6 +255,7 @@ export function AppBar(props: AppBarProps): JSX.Element { // Log logger.logTraceUseEffect('APP-BAR - PANEL - OPEN/CLOSE ', isOpen); + // Open and close of the panel. if (isOpen) { openPanelById(tabId, tabGroup); } else { diff --git a/packages/geoview-core/src/core/components/export/export-modal.tsx b/packages/geoview-core/src/core/components/export/export-modal.tsx index 89336fb49c7..257fa57433a 100644 --- a/packages/geoview-core/src/core/components/export/export-modal.tsx +++ b/packages/geoview-core/src/core/components/export/export-modal.tsx @@ -26,6 +26,7 @@ export default function ExportModal(): JSX.Element { const mapViewport = mapElement.getElementsByClassName('ol-viewport')[0]; const footerbarLegendContainer = mapElement.querySelector(`[id^="${mapId}-footerBar-legendContainer"]`); const appBarLegendContainer = mapElement.querySelector(`[id^="${mapId}-appBar-legendContainer"]`); + const legendId = `${mapId}AppbarPanelButtonLegend`; const theme = useTheme(); @@ -65,7 +66,7 @@ export default function ExportModal(): JSX.Element { .then((dataUrl) => { setIsMapExporting(false); exportPNG(dataUrl, mapId); - setActiveAppBarTab('AppbarPanelButtonLegend', 'legend', false); + setActiveAppBarTab(legendId, 'legend', false, false); disableFocusTrap(); }) .catch((error: Error) => { @@ -75,7 +76,7 @@ export default function ExportModal(): JSX.Element { }) as MouseEventHandler; const handleCloseModal = (): void => { - setActiveAppBarTab('AppbarPanelButtonLegend', 'legend', false); + setActiveAppBarTab(legendId, 'legend', false, false); disableFocusTrap(); }; /** @@ -102,7 +103,7 @@ export default function ExportModal(): JSX.Element { const dialogBox = dialogRef.current; // open legend in appbar when only appbar exists if (appBarLegendContainer && !footerbarLegendContainer) { - setActiveAppBarTab('AppbarPanelButtonLegend', 'legend', true); + setActiveAppBarTab(legendId, 'legend', true, false); } // Reason for timer, so that content of the export modal will be loaded // after modal is fully opened. diff --git a/packages/geoview-core/src/core/components/geolocator/geolocator.tsx b/packages/geoview-core/src/core/components/geolocator/geolocator.tsx index 72dfba3cf91..c40a0dd91a4 100644 --- a/packages/geoview-core/src/core/components/geolocator/geolocator.tsx +++ b/packages/geoview-core/src/core/components/geolocator/geolocator.tsx @@ -47,6 +47,7 @@ export function Geolocator(): JSX.Element { const urlRef = useRef(`${geolocatorServiceURL}&lang=${displayLanguage}`); const abortControllerRef = useRef(null); + const fetchTimerRef = useRef(); const MIN_SEARCH_LENGTH = 3; /** @@ -94,6 +95,7 @@ export function Geolocator(): JSX.Element { // Abort any pending requests if (abortControllerRef.current) { abortControllerRef.current.abort(); + clearTimeout(fetchTimerRef.current); } // Create new abort controller @@ -117,11 +119,21 @@ export function Geolocator(): JSX.Element { setData(result); setError(null); setIsLoading(false); + clearTimeout(fetchTimerRef?.current); } catch (err) { setError(err as Error); } }; + /** + * Reset loading and data state and clear fetch timer. + */ + const resetGeoLocatorState = (): void => { + setIsLoading(false); + setData([]); + clearTimeout(fetchTimerRef.current); + }; + /** * Reset search component values when close icon is clicked. * @returns void @@ -129,7 +141,7 @@ export function Geolocator(): JSX.Element { const resetSearch = useCallback(() => { setSearchValue(''); setData(undefined); - setActiveAppBarTab(`${mapId}AppbarPanelButtonGeolocator`, CV_DEFAULT_APPBAR_CORE.GEOLOCATOR, false); + setActiveAppBarTab(`${mapId}AppbarPanelButtonGeolocator`, CV_DEFAULT_APPBAR_CORE.GEOLOCATOR, false, false); // eslint-disable-next-line react-hooks/exhaustive-deps }, [setActiveAppBarTab]); @@ -171,6 +183,7 @@ export function Geolocator(): JSX.Element { if (abortControllerRef.current) { abortControllerRef.current.abort(); } + resetGeoLocatorState(); doRequest.cancel(); setData(undefined); } @@ -195,10 +208,27 @@ export function Geolocator(): JSX.Element { // Cleanup function to abort any pending requests if (abortControllerRef.current) { abortControllerRef.current.abort(); + clearTimeout(fetchTimerRef.current); } }; }, []); + /** + * Effect that will track fetch call, so that after 15 seconds if no response comes back, + * Error will be displayed. + */ + useEffect(() => { + if (isLoading) { + fetchTimerRef.current = setTimeout(() => { + resetGeoLocatorState(); + setError(new Error('No result found.')); + }, 15000); + } + return () => { + clearTimeout(fetchTimerRef.current); + }; + }, [isLoading]); + return ( )} - {!!data && searchValue?.length >= MIN_SEARCH_LENGTH && !error && ( + {!!data && searchValue?.length >= MIN_SEARCH_LENGTH && ( diff --git a/packages/geoview-core/src/core/stores/store-interface-and-intial-values/ui-state.ts b/packages/geoview-core/src/core/stores/store-interface-and-intial-values/ui-state.ts index bad0a3c4156..5760d1571d8 100644 --- a/packages/geoview-core/src/core/stores/store-interface-and-intial-values/ui-state.ts +++ b/packages/geoview-core/src/core/stores/store-interface-and-intial-values/ui-state.ts @@ -16,6 +16,7 @@ export type ActiveAppBarTabType = { tabId: string; tabGroup: string; isOpen: boolean; + isFocusTrapped?: boolean; }; export interface IUIState { @@ -40,7 +41,7 @@ export interface IUIState { disableFocusTrap: () => void; showTab: (tab: string) => void; setActiveFooterBarTab: (id: string) => void; - setActiveAppBarTab: (tabId: string, tabGroup: string, isOpen: boolean) => void; + setActiveAppBarTab: (tabId: string, tabGroup: string, isOpen: boolean, isFocusTrapped: boolean) => void; setActiveTrapGeoView: (active: boolean) => void; setFooterPanelResizeValue: (value: number) => void; setMapInfoExpanded: (expanded: boolean) => void; @@ -52,7 +53,7 @@ export interface IUIState { enableFocusTrap: (uiFocus: FocusItemProps) => void; disableFocusTrap: () => void; setActiveFooterBarTab: (id: string) => void; - setActiveAppBarTab: (tabId: string, tabGroup: string, isOpen: boolean) => void; + setActiveAppBarTab: (tabId: string, tabGroup: string, isOpen: boolean, isFocusTrapped: boolean) => void; setActiveTrapGeoView: (active: boolean) => void; setFooterPanelResizeValue: (value: number) => void; setHiddenTabs: (hiddenTabs: string[]) => void; @@ -74,7 +75,7 @@ export function initializeUIState(set: TypeSetStore, get: TypeGetStore): IUIStat const init = { appBarComponents: ['geolocator'], activeFooterBarTabId: '', - activeAppBarTab: { tabId: '', tabGroup: '', isOpen: false }, + activeAppBarTab: { tabId: '', tabGroup: '', isOpen: false, isFocusTrapped: false }, activeTrapGeoView: false, corePackagesComponents: [], focusItem: { activeElementId: false, callbackElementId: false }, @@ -98,6 +99,7 @@ export function initializeUIState(set: TypeSetStore, get: TypeGetStore): IUIStat : '', tabGroup: geoviewConfig.appBar?.selectedTab || '', isOpen: geoviewConfig.appBar?.collapsed !== undefined ? !geoviewConfig.appBar.collapsed : true, + isFocusTrapped: false, }, activeFooterBarTabId: geoviewConfig.footerBar?.selectedTab || '', corePackagesComponents: geoviewConfig.corePackages || [], @@ -146,9 +148,9 @@ export function initializeUIState(set: TypeSetStore, get: TypeGetStore): IUIStat // Redirect to setter get().uiState.setterActions.setFooterBarIsCollapsed(collapsed); }, - setActiveAppBarTab: (tabId: string, tabGroup: string, isOpen: boolean) => { + setActiveAppBarTab: (tabId: string, tabGroup: string, isOpen: boolean, isFocusTrapped: boolean) => { // Redirect to setter - get().uiState.setterActions.setActiveAppBarTab(tabId, tabGroup, isOpen); + get().uiState.setterActions.setActiveAppBarTab(tabId, tabGroup, isOpen, isFocusTrapped); }, setSelectedFooterLayerListItem: (layerListItem: string) => { // Redirect to setter @@ -222,7 +224,7 @@ export function initializeUIState(set: TypeSetStore, get: TypeGetStore): IUIStat }, }); }, - setActiveAppBarTab: (tabId: string, tabGroup: string, isOpen: boolean) => { + setActiveAppBarTab: (tabId: string, tabGroup: string, isOpen: boolean, isFocusTrapped: boolean = false) => { set({ uiState: { ...get().uiState, @@ -230,6 +232,7 @@ export function initializeUIState(set: TypeSetStore, get: TypeGetStore): IUIStat tabId, tabGroup, isOpen, + isFocusTrapped, }, }, }); diff --git a/packages/geoview-core/src/ui/panel/panel-types.ts b/packages/geoview-core/src/ui/panel/panel-types.ts index b2ef481adf3..f53b8cccc34 100644 --- a/packages/geoview-core/src/ui/panel/panel-types.ts +++ b/packages/geoview-core/src/ui/panel/panel-types.ts @@ -38,6 +38,8 @@ export type TypePanelProps = { convertHtmlContent?: boolean; /** Custom panel styles */ panelStyles?: PanelStyles; + /** is focus trapped for panel */ + isFocusTrapped?: boolean; }; export interface PanelStyles { diff --git a/packages/geoview-core/src/ui/panel/panel.tsx b/packages/geoview-core/src/ui/panel/panel.tsx index 442d60e2209..9f910cb45e6 100644 --- a/packages/geoview-core/src/ui/panel/panel.tsx +++ b/packages/geoview-core/src/ui/panel/panel.tsx @@ -40,7 +40,7 @@ export type TypePanelAppProps = { */ export function Panel(props: TypePanelAppProps): JSX.Element { const { panel, button, onPanelOpened, onPanelClosed, onGeneralCloseClicked, ...rest } = props; - const { status: open = false, panelStyles, panelGroupName } = panel; + const { status: open = false, isFocusTrapped = false, panelStyles, panelGroupName } = panel; const { t } = useTranslation(); @@ -122,7 +122,7 @@ export function Panel(props: TypePanelAppProps): JSX.Element { return ( - +