Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Dashboard De-Angular] Add dashboard class for discard flow #4478

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
const isChromeVisible = useChromeVisibility(services.chrome);
const [eventEmitter] = useState(new EventEmitter());

const savedDashboardInstance = useSavedDashboardInstance(
const { savedDashboard: savedDashboardInstance, dashboard } = useSavedDashboardInstance(
services,
eventEmitter,
isChromeVisible,
Expand All @@ -34,13 +34,15 @@
services,
isChromeVisible,
eventEmitter,
dashboard,
savedDashboardInstance,
appState
);

const { isEmbeddableRendered, currentAppState } = useEditorUpdates(
services,
eventEmitter,
dashboard,
savedDashboardInstance,
dashboardContainer,
appState
Expand All @@ -53,26 +55,33 @@
};
}, [eventEmitter]);

console.log('savedDashboardInstance', savedDashboardInstance);

Check failure on line 58 in src/plugins/dashboard/public/application/components/dashboard_editor.tsx

View workflow job for this annotation

GitHub Actions / Build and Verify on Linux

Unexpected console statement

Check failure on line 58 in src/plugins/dashboard/public/application/components/dashboard_editor.tsx

View workflow job for this annotation

GitHub Actions / Build and Verify on Windows

Unexpected console statement
console.log('dashboard', dashboard);

Check failure on line 59 in src/plugins/dashboard/public/application/components/dashboard_editor.tsx

View workflow job for this annotation

GitHub Actions / Build and Verify on Linux

Unexpected console statement

Check failure on line 59 in src/plugins/dashboard/public/application/components/dashboard_editor.tsx

View workflow job for this annotation

GitHub Actions / Build and Verify on Windows

Unexpected console statement
console.log('appState', appState);

Check failure on line 60 in src/plugins/dashboard/public/application/components/dashboard_editor.tsx

View workflow job for this annotation

GitHub Actions / Build and Verify on Linux

Unexpected console statement

Check failure on line 60 in src/plugins/dashboard/public/application/components/dashboard_editor.tsx

View workflow job for this annotation

GitHub Actions / Build and Verify on Windows

Unexpected console statement
console.log('appStateData', appState?.getState());

Check failure on line 61 in src/plugins/dashboard/public/application/components/dashboard_editor.tsx

View workflow job for this annotation

GitHub Actions / Build and Verify on Linux

Unexpected console statement

Check failure on line 61 in src/plugins/dashboard/public/application/components/dashboard_editor.tsx

View workflow job for this annotation

GitHub Actions / Build and Verify on Windows

Unexpected console statement
console.log('currentAppState', currentAppState);

Check failure on line 62 in src/plugins/dashboard/public/application/components/dashboard_editor.tsx

View workflow job for this annotation

GitHub Actions / Build and Verify on Linux

Unexpected console statement

Check failure on line 62 in src/plugins/dashboard/public/application/components/dashboard_editor.tsx

View workflow job for this annotation

GitHub Actions / Build and Verify on Windows

Unexpected console statement
console.log('isEmbeddableRendered', isEmbeddableRendered);

Check failure on line 63 in src/plugins/dashboard/public/application/components/dashboard_editor.tsx

View workflow job for this annotation

GitHub Actions / Build and Verify on Linux

Unexpected console statement

Check failure on line 63 in src/plugins/dashboard/public/application/components/dashboard_editor.tsx

View workflow job for this annotation

GitHub Actions / Build and Verify on Windows

Unexpected console statement
console.log('app state isDirty', appState?.getState().isDirty);

Check failure on line 64 in src/plugins/dashboard/public/application/components/dashboard_editor.tsx

View workflow job for this annotation

GitHub Actions / Build and Verify on Linux

Unexpected console statement

Check failure on line 64 in src/plugins/dashboard/public/application/components/dashboard_editor.tsx

View workflow job for this annotation

GitHub Actions / Build and Verify on Windows

Unexpected console statement
console.log('dashboardContainer', dashboardContainer);

Check failure on line 65 in src/plugins/dashboard/public/application/components/dashboard_editor.tsx

View workflow job for this annotation

GitHub Actions / Build and Verify on Linux

Unexpected console statement

Check failure on line 65 in src/plugins/dashboard/public/application/components/dashboard_editor.tsx

View workflow job for this annotation

GitHub Actions / Build and Verify on Windows

Unexpected console statement

return (
<div>
<div>
{savedDashboardInstance && appState && dashboardContainer && currentAppState && (
<DashboardTopNav
isChromeVisible={isChromeVisible}
savedDashboardInstance={savedDashboardInstance}
stateContainer={appState}
currentAppState={currentAppState}
isEmbeddableRendered={isEmbeddableRendered}
dashboardContainer={dashboardContainer}
/>
)}
{savedDashboardInstance &&
appState &&
dashboardContainer &&
currentAppState &&
dashboard && (
<DashboardTopNav
isChromeVisible={isChromeVisible}
savedDashboardInstance={savedDashboardInstance}
stateContainer={appState}
dashboard={dashboard}
currentAppState={currentAppState}
isEmbeddableRendered={isEmbeddableRendered}
dashboardContainer={dashboardContainer}
/>
)}
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@
import { getNavActions } from '../utils/get_nav_actions';
import { DashboardContainer } from '../embeddable';
import { isErrorEmbeddable } from '../../embeddable_plugin';
import { Dashboard } from '../../dashboard';

interface DashboardTopNavProps {
isChromeVisible: boolean;
savedDashboardInstance: any;
stateContainer: DashboardAppStateContainer;
dashboard: Dashboard;
currentAppState: DashboardAppState;
isEmbeddableRendered: boolean;
dashboardContainer?: DashboardContainer;
Expand All @@ -36,6 +38,7 @@
isChromeVisible,
savedDashboardInstance,
stateContainer,
dashboard,
currentAppState,
isEmbeddableRendered,
dashboardContainer,
Expand Down Expand Up @@ -83,6 +86,7 @@
stateContainer,
savedDashboardInstance,
services,
dashboard,
dashboardContainer
);
setTopNavMenu(
Expand All @@ -101,6 +105,7 @@
savedDashboardInstance,
stateContainer,
isEmbeddableRendered,
dashboard

Check failure on line 108 in src/plugins/dashboard/public/application/components/dashboard_top_nav.tsx

View workflow job for this annotation

GitHub Actions / Build and Verify on Linux

Insert `,`

Check failure on line 108 in src/plugins/dashboard/public/application/components/dashboard_top_nav.tsx

View workflow job for this annotation

GitHub Actions / Build and Verify on Windows

Insert `,`
]);

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,6 @@ export function getAppStateDefaults(
query: savedDashboard.getQuery(),
filters: savedDashboard.getFilters(),
viewMode: savedDashboard.id || hideWriteControls ? ViewMode.VIEW : ViewMode.EDIT,
isDirty: false,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const createDashboardAppState = ({
[option]: value,
},
}),
// setDashboard: (state)
} as DashboardAppStateTransitions;
/*
make sure url ('_a') matches initial state
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Any modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

import { Dashboard, DashboardParams } from '../../dashboard';
import { SavedObjectDashboard } from '../../saved_dashboards';
import { convertToSerializedDashboard } from '../../saved_dashboards/_saved_dashboard';
import { DashboardServices } from '../../types';

export const getDashboardInstance = async (
dashboardServices: DashboardServices,
/**
* opts can be either a saved dashboard id passed as string,
* or an object of new dashboard params.
* Both come from url search query
*/
opts?: Record<string, unknown> | string
): Promise<{
savedDashboard: SavedObjectDashboard;
dashboard: Dashboard<DashboardParams>;
}> => {
const { savedDashboards } = dashboardServices;

// Get the existing dashboard/default new dashboard from saved object loader
const savedDashboard: SavedObjectDashboard = await savedDashboards.get(opts);
// Serialized the saved object dashboard
const serializedDashboard = convertToSerializedDashboard(savedDashboard);
// Create a Dashboard class using the serialized dashboard
// const dashboard = (await dashboards.createDashboard(serializedDashboard)) as Dashboard;
const dashboard = new Dashboard(serializedDashboard);
await dashboard.setState(serializedDashboard);

return {
savedDashboard,
dashboard,
};
};
56 changes: 34 additions & 22 deletions src/plugins/dashboard/public/application/utils/get_nav_actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { DashboardContainer } from '../embeddable/dashboard_container';
import { DashboardConstants, createDashboardEditUrl } from '../../dashboard_constants';
import { unhashUrl } from '../../../../opensearch_dashboards_utils/public';
import { UrlParams } from '../components/dashboard_top_nav';
import { Dashboard } from '../../dashboard';

interface UrlParamsSelectedMap {
[UrlParams.SHOW_TOP_MENU]: boolean;
Expand All @@ -46,6 +47,7 @@ export const getNavActions = (
stateContainer: DashboardAppStateContainer,
savedDashboard: any,
services: DashboardServices,
dashboard: Dashboard,
dashboardContainer?: DashboardContainer
) => {
const {
Expand Down Expand Up @@ -292,40 +294,50 @@ export const getNavActions = (
function onChangeViewMode(newMode: ViewMode) {
const isPageRefresh = newMode === appState.viewMode;
const isLeavingEditMode = !isPageRefresh && newMode === ViewMode.VIEW;
// TODO: check if any query and filter changed
const willLoseChanges = isLeavingEditMode;
const willLoseChanges = isLeavingEditMode && stateContainer.getState().isDirty === true;

// If there are no changes, do not show the discard window
if (!willLoseChanges) {
stateContainer.transitions.set('viewMode', newMode);
return;
}

// If there are changes, show the discard window, and reset the states to original
function revertChangesAndExitEditMode() {
stateContainer.transitions.set('viewMode', ViewMode.VIEW);
const pathname = savedDashboard.id
? createDashboardEditUrl(savedDashboard.id)
: DashboardConstants.CREATE_NEW_DASHBOARD_URL;
history.push(pathname);

/* dashboardStateManager.resetState();
// This is only necessary for new dashboards, which will default to Edit mode.
updateViewMode(ViewMode.VIEW);

// We need to do a hard reset of the timepicker. appState will not reload like
// it does on 'open' because it's been saved to the url and the getAppState.previouslyStored() check on
// reload will cause it not to sync.
if (dashboardStateManager.getIsTimeSavedWithDashboard()) {
dashboardStateManager.syncTimefilterWithDashboardTime(timefilter);
dashboardStateManager.syncTimefilterWithDashboardRefreshInterval(timefilter);
}

// Angular's $location skips this update because of history updates from syncState which happen simultaneously
// when calling osdUrl.change() angular schedules url update and when angular finally starts to process it,
// the update is considered outdated and angular skips it
// so have to use implementation of dashboardStateManager.changeDashboardUrl, which workarounds those issues
dashboardStateManager.changeDashboardUrl(
dash.id ? createDashboardEditUrl(dash.id) : DashboardConstants.CREATE_NEW_DASHBOARD_URL
);*/
// This is only necessary for new dashboards, which will default to Edit mode.
stateContainer.transitions.set('viewMode', ViewMode.VIEW);

// We need to reset the app state to its original state
if (dashboard.panels) {
stateContainer.transitions.set('panels', dashboard.panels);
}

stateContainer.transitions.set('filters', dashboard.filters);
stateContainer.transitions.set('query', dashboard.query);
stateContainer.transitions.setOption('hidePanelTitles', dashboard.options.hidePanelTitles);
stateContainer.transitions.setOption('useMargins', dashboard.options.useMargins);

// Need to see if needed
stateContainer.transitions.set('timeRestore', dashboard.timeRestore);

// Since time filters are not tracked by app state, we need to manually reset it
if (stateContainer.getState().timeRestore) {
queryService.timefilter.timefilter.setTime({
from: dashboard.timeFrom,
to: dashboard.timeTo,
});
if (dashboard.refreshInterval) {
queryService.timefilter.timefilter.setRefreshInterval(dashboard.refreshInterval);
}
}

// Set the isDirty flag back to false since we discard all the changes
stateContainer.transitions.set('isDirty', false);
}

overlays
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { DashboardServices } from '../../../types';
import { DashboardAppStateContainer } from '../../../types';
import { migrateAppState, getAppStateDefaults } from '../../lib';
import { createDashboardAppState } from '../create_dashboard_app_state';
import { SavedObjectDashboard } from '../../../saved_dashboards';

/**
* This effect is responsible for instantiating the dashboard app state container,
Expand All @@ -22,7 +23,7 @@ import { createDashboardAppState } from '../create_dashboard_app_state';
export const useDashboardAppState = (
services: DashboardServices,
eventEmitter: EventEmitter,
instance: any
instance?: SavedObjectDashboard
) => {
const [appState, setAppState] = useState<DashboardAppStateContainer | undefined>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import deepEqual from 'fast-deep-equal';
import { EventEmitter } from 'stream';
import { useEffect } from 'react';
import { i18n } from '@osd/i18n';
import _ from 'lodash';
import { IndexPattern, opensearchFilters } from '../../../../../data/public';
import {
DASHBOARD_CONTAINER_TYPE,
Expand Down Expand Up @@ -49,24 +50,28 @@ import {
import { migrateLegacyQuery } from '../../lib/migrate_legacy_query';
import { getSavedObjectFinder } from '../../../../../saved_objects/public';
import { DashboardConstants } from '../../../dashboard_constants';
import { SavedObjectDashboard } from '../../../saved_dashboards';
import { Dashboard } from '../../../dashboard';

export const useDashboardContainer = (
services: DashboardServices,
isChromeVisible: boolean,
eventEmitter: EventEmitter,
savedDashboardInstance?: any,
dashboard?: Dashboard,
savedDashboardInstance?: SavedObjectDashboard,
appState?: DashboardAppStateContainer
) => {
const [dashboardContainer, setDashboardContainer] = useState<DashboardContainer>();

useEffect(() => {
const getDashboardContainer = async () => {
try {
if (savedDashboardInstance && appState) {
if (savedDashboardInstance && appState && dashboard) {
const dashboardContainerEmbeddable = await createDashboardEmbeddable(
savedDashboardInstance,
services,
appState
appState,
dashboard
);

setDashboardContainer(dashboardContainerEmbeddable);
Expand All @@ -82,7 +87,7 @@ export const useDashboardContainer = (
};

getDashboardContainer();
}, [savedDashboardInstance, appState, services]);
}, [savedDashboardInstance, appState, services, dashboard]);

useEffect(() => {
const incomingEmbeddable = services.embeddable
Expand All @@ -106,7 +111,8 @@ export const useDashboardContainer = (
const createDashboardEmbeddable = (
savedDash: any,
dashboardServices: DashboardServices,
appState: DashboardAppStateContainer
appState: DashboardAppStateContainer,
dashboard: Dashboard
) => {
let dashboardContainer: DashboardContainer;
let inputSubscription: Subscription | undefined;
Expand Down Expand Up @@ -342,7 +348,7 @@ const createDashboardEmbeddable = (
appState.transitions.set('query', queryStringManager.getQuery());
}
// triggered when dashboard embeddable container has changes, and update the appState
handleDashboardContainerChanges(container, appState, dashboardServices);
handleDashboardContainerChanges(container, appState, dashboardServices, dashboard);
});
return dashboardContainer;
}
Expand All @@ -354,7 +360,8 @@ const createDashboardEmbeddable = (
const handleDashboardContainerChanges = (
dashboardContainer: DashboardContainer,
appState: DashboardAppStateContainer,
dashboardServices: DashboardServices
dashboardServices: DashboardServices,
dashboard: Dashboard
) => {
let dirty = false;
let dirtyBecauseOfInitialStateMigration = false;
Expand All @@ -370,6 +377,7 @@ const handleDashboardContainerChanges = (
dirty = true;
}
});

const convertedPanelStateMap: { [key: string]: SavedDashboardPanel } = {};
Object.values(input.panels).forEach((panelState) => {
if (savedDashboardPanelMap[panelState.explicitInput.id] === undefined) {
Expand All @@ -396,8 +404,8 @@ const handleDashboardContainerChanges = (
});
if (dirty) {
appState.transitions.set('panels', Object.values(convertedPanelStateMap));
if (dirtyBecauseOfInitialStateMigration) {
// this.saveState({ replace: true });
if (!dirtyBecauseOfInitialStateMigration) {
appState.transitions.set('isDirty', true);
}
}
if (input.isFullScreenMode !== appStateData.fullScreenMode) {
Expand Down
Loading
Loading