Skip to content

Commit d57e22e

Browse files
checkpoint
1 parent 38e481c commit d57e22e

File tree

11 files changed

+103
-72
lines changed

11 files changed

+103
-72
lines changed

packages/grafana-ui/src/components/Portal/Portal.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export function PortalContainer() {
6060
return (
6161
<div
6262
id="grafana-portal-container"
63+
data-qiankun="grafana-full-app"
6364
className={cx({
6465
[styles.grafanaPortalContainer]: isBodyScrolling,
6566
})}

public/app/AppWrapper.tsx

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import { LiveConnectionWarning } from './features/live/LiveConnectionWarning';
3030

3131
interface AppWrapperProps {
3232
app: GrafanaApp;
33+
isMFE?: boolean;
34+
children?: React.ReactNode | null;
3335
}
3436

3537
interface AppWrapperState {
@@ -88,7 +90,7 @@ export class AppWrapper extends Component<AppWrapperProps, AppWrapperState> {
8890
}
8991

9092
render() {
91-
const { app } = this.props;
93+
const { app, isMFE, children } = this.props;
9294
const { ready } = this.state;
9395

9496
navigationLogger('AppWrapper', false, 'rendering');
@@ -116,22 +118,29 @@ export class AppWrapper extends Component<AppWrapperProps, AppWrapperState> {
116118
<GlobalStyles />
117119
<div className="grafana-app">
118120
<AppChrome>
119-
<AngularRoot />
120-
<AppNotificationList />
121-
<Stack gap={0} grow={1} direction="column">
122-
{pageBanners.map((Banner, index) => (
123-
<Banner key={index.toString()} />
121+
<>
122+
<AngularRoot />
123+
<AppNotificationList />
124+
<Stack gap={0} grow={1} direction="column">
125+
{pageBanners.map((Banner, index) => (
126+
<Banner key={index.toString()} />
127+
))}
128+
{ready && !isMFE && this.renderRoutes()}
129+
</Stack>
130+
{bodyRenderHooks.map((Hook, index) => (
131+
<Hook key={index.toString()} />
124132
))}
125-
{ready && this.renderRoutes()}
126-
</Stack>
127-
{bodyRenderHooks.map((Hook, index) => (
128-
<Hook key={index.toString()} />
129-
))}
133+
</>
134+
{children}
130135
</AppChrome>
131136
</div>
132137
<LiveConnectionWarning />
133-
<ModalRoot />
134-
<PortalContainer />
138+
{!isMFE && (
139+
<>
140+
<ModalRoot />
141+
<PortalContainer />
142+
</>
143+
)}
135144
</ModalsContextProvider>
136145
</CompatRouter>
137146
</LocationServiceProvider>

public/app/app.ts

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ import {
4444
import { setPanelDataErrorView } from '@grafana/runtime/src/components/PanelDataErrorView';
4545
import { setPanelRenderer } from '@grafana/runtime/src/components/PanelRenderer';
4646
import { setPluginPage } from '@grafana/runtime/src/components/PluginPage';
47-
import config, { updateConfig } from 'app/core/config';
47+
import config, { Settings, updateConfig } from 'app/core/config';
4848
import { arrayMove } from 'app/core/utils/arrayMove';
4949
import { getStandardTransformers } from 'app/features/transformers/standardTransformers';
5050

@@ -125,15 +125,27 @@ if (process.env.NODE_ENV === 'development') {
125125
export class GrafanaApp {
126126
context!: GrafanaContextType;
127127

128-
async init() {
128+
async init(isMFE = false) {
129129
try {
130130
// Let iframe container know grafana has started loading
131131
parent.postMessage('GrafanaAppInit', '*');
132132

133133
const initI18nPromise = initializeI18n(config.bootData.user.language);
134134
initI18nPromise.then(({ language }) => updateConfig({ language }));
135135

136-
setBackendSrv(backendSrv);
136+
if(isMFE){
137+
backendSrv.setGrafanaPrefix(true);
138+
setBackendSrv(backendSrv);
139+
const settings: Settings = await backendSrv.get('/api/frontend/settings');
140+
141+
config.panels = settings.panels;
142+
config.datasources = settings.datasources;
143+
config.defaultDatasource = settings.defaultDatasource;
144+
} else {
145+
setBackendSrv(backendSrv);
146+
}
147+
148+
137149
initEchoSrv();
138150
initIconCache();
139151
// This needs to be done after the `initEchoSrv` since it is being used under the hood.
@@ -270,12 +282,14 @@ export class GrafanaApp {
270282

271283
initializeScopes();
272284

273-
const root = createRoot(document.getElementById('reactRoot')!);
274-
root.render(
275-
createElement(AppWrapper, {
276-
app: this,
277-
})
278-
);
285+
if(!isMFE){
286+
const root = createRoot(document.getElementById('reactRoot')!);
287+
root.render(
288+
createElement(AppWrapper, {
289+
app: this,
290+
})
291+
);
292+
}
279293
} catch (error) {
280294
console.error('Failed to start Grafana', error);
281295
window.__grafana_load_failed();

public/app/core/context/ModalsProvider.ts

Whitespace-only changes.

public/app/features/dashboard/components/PanelEditor/PanelEditor.tsx

Lines changed: 21 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
277277
dashboard={dashboard}
278278
tabs={tabs}
279279
onChangeTab={this.onChangeTab}
280+
isMfeEditPanel={this.props.isMFEDashboard}
280281
/>
281282
</div>
282283
</SplitPaneWrapper>
@@ -433,33 +434,32 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
433434
};
434435

435436
render() {
436-
const { initDone, uiState, theme, sectionNav, pageNav, className, updatePanelEditorUIState, isMFECustomDashboard } = this.props;
437+
const { initDone, uiState, theme, sectionNav, pageNav, className, updatePanelEditorUIState, isMFECustomDashboard } =
438+
this.props;
437439
const styles = getStyles(theme, this.props);
438440

439441
if (!initDone) {
440442
return null;
441443
}
442444

443-
console.log('PanelEditor.tsx this.props', {
444-
isPanelOptionVisible: uiState.isPanelOptionsVisible,
445-
isMFECustomDashboard,
446-
modelState: this.state.showSaveLibraryPanelModal,
447-
});
448-
449-
const editPanelContent = (
450-
<>
451-
{
452-
!isMFECustomDashboard ? (
445+
return (
446+
<Page
447+
navModel={sectionNav}
448+
pageNav={pageNav}
449+
data-testid={selectors.components.PanelEditor.General.content}
450+
layout={PageLayoutType.Custom}
451+
className={!isMFECustomDashboard ? className : styles.mfeWrapper}
452+
>
453+
{!isMFECustomDashboard ? (
453454
<AppChromeUpdate
454-
actions={<ToolbarButtonRow alignment="right">{this.renderEditorActions()}</ToolbarButtonRow>}
455+
actions={<ToolbarButtonRow alignment="right">{this.renderEditorActions()}</ToolbarButtonRow>}
455456
/>
456-
): (
457+
) : (
457458
<ToolbarButtonRow alignment="right">{this.renderEditorActions()}</ToolbarButtonRow>
458-
)
459-
}
459+
)}
460460
<div className={styles.wrapper}>
461461
<div className={styles.verticalSplitPanesWrapper}>
462-
{!uiState.isPanelOptionsVisible || isMFECustomDashboard ? (
462+
{!uiState.isPanelOptionsVisible ? (
463463
this.renderPanelAndEditor(uiState, styles)
464464
) : (
465465
<SplitPaneWrapper
@@ -488,25 +488,7 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
488488
/>
489489
)}
490490
</div>
491-
</>
492-
)
493-
494-
return (
495-
<>
496-
{
497-
!isMFECustomDashboard ? (
498-
<Page
499-
navModel={sectionNav}
500-
pageNav={pageNav}
501-
data-testid={selectors.components.PanelEditor.General.content}
502-
layout={PageLayoutType.Custom}
503-
className={className}
504-
>
505-
{editPanelContent}
506-
</Page>
507-
): <div>{editPanelContent}</div>
508-
}
509-
</>
491+
</Page>
510492
);
511493
}
512494
}
@@ -521,12 +503,16 @@ export const getStyles = stylesFactory((theme: GrafanaTheme2, props: Props) => {
521503
const paneSpacing = theme.spacing(2);
522504

523505
return {
506+
mfeWrapper: css({
507+
height: '100vh',
508+
}),
524509
wrapper: css({
525510
width: '100%',
526511
flexGrow: 1,
527512
minHeight: 0,
528513
display: 'flex',
529514
paddingTop: theme.spacing(2),
515+
height: '100%',
530516
}),
531517
verticalSplitPanesWrapper: css({
532518
display: 'flex',

public/app/features/dashboard/components/PanelEditor/PanelEditorTabs.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@ interface PanelEditorTabsProps {
2020
dashboard: DashboardModel;
2121
tabs: PanelEditorTab[];
2222
onChangeTab: (tab: PanelEditorTab) => void;
23+
isMfeEditPanel?: boolean;
2324
}
2425

25-
export const PanelEditorTabs = memo(({ panel, dashboard, tabs, onChangeTab }: PanelEditorTabsProps) => {
26+
export const PanelEditorTabs = memo(({ panel, dashboard, tabs, onChangeTab, isMfeEditPanel }: PanelEditorTabsProps) => {
2627
const forceUpdate = useForceUpdate();
2728
const styles = useStyles2(getStyles);
2829

@@ -49,7 +50,7 @@ export const PanelEditorTabs = memo(({ panel, dashboard, tabs, onChangeTab }: Pa
4950
return () => eventSubs.unsubscribe();
5051
}, [panel, dashboard, forceUpdate]);
5152

52-
const activeTab = tabs.find((item) => item.active)!;
53+
const activeTab = !isMfeEditPanel? tabs.find((item) => item.active)!: tabs.find((item) => item.id === PanelEditorTabId.Query)!;
5354

5455
if (tabs.length === 0) {
5556
return null;
@@ -60,7 +61,7 @@ export const PanelEditorTabs = memo(({ panel, dashboard, tabs, onChangeTab }: Pa
6061
return (
6162
<div className={styles.wrapper}>
6263
<TabsBar className={styles.tabBar} hideBorder>
63-
{tabs.map((tab) => {
64+
{!isMfeEditPanel ? tabs.map((tab) => {
6465
if (tab.id === PanelEditorTabId.Alert && alertingEnabled) {
6566
return (
6667
<PanelAlertTab
@@ -84,7 +85,7 @@ export const PanelEditorTabs = memo(({ panel, dashboard, tabs, onChangeTab }: Pa
8485
counter={getCounter(panel, tab)}
8586
/>
8687
);
87-
})}
88+
}): null}
8889
</TabsBar>
8990
<TabContent className={styles.tabContent}>
9091
{activeTab.id === PanelEditorTabId.Query && <PanelEditorQueries panel={panel} queries={panel.targets} />}

public/app/features/dashboard/containers/DashboardPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ export class UnthemedDashboardPage extends PureComponent<Props, State> {
483483
)}
484484
</header>
485485
)}
486-
{!isFNDashboardEditable && <DashboardPrompt dashboard={dashboard} />}
486+
<DashboardPrompt dashboard={dashboard} />
487487
{initError && <DashboardFailed />}
488488
{showSubMenu && (
489489
<section aria-label={selectors.pages.Dashboard.SubMenu.submenu}>

public/app/features/query/components/QueryGroup.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { dataSource as expressionDatasource } from 'app/features/expressions/Exp
2727
import { AngularDeprecationPluginNotice } from 'app/features/plugins/angularDeprecation/AngularDeprecationPluginNotice';
2828
import { isSharedDashboardQuery } from 'app/plugins/datasource/dashboard';
2929
import { GrafanaQuery } from 'app/plugins/datasource/grafana/types';
30-
import { QueryGroupOptions } from 'app/types';
30+
import { QueryGroupOptions, StoreState, useSelector } from 'app/types';
3131

3232
import { isAngularDatasourcePluginAndNotHidden } from '../../plugins/angularDeprecation/utils';
3333
import { PanelQueryRunner } from '../state/PanelQueryRunner';
@@ -37,6 +37,7 @@ import { GroupActionComponents } from './QueryActionComponent';
3737
import { QueryEditorRows } from './QueryEditorRows';
3838
import { QueryGroupOptionsEditor } from './QueryGroupOptions';
3939

40+
4041
export interface Props {
4142
queryRunner: PanelQueryRunner;
4243
options: QueryGroupOptions;
@@ -404,6 +405,13 @@ export function QueryGroupTopSection({
404405
}: QueryGroupTopSectionProps) {
405406
const styles = getStyles();
406407
const [isHelpOpen, setIsHelpOpen] = useState(false);
408+
const { FNDashboard, isCustomDashboard } = useSelector((state: StoreState) => state.fnGlobalState);
409+
410+
// do not render data source selection options in micro frontend dashboard
411+
if(isCustomDashboard && FNDashboard){
412+
return null;
413+
}
414+
407415
return (
408416
<>
409417
<div data-testid={selectors.components.QueryTab.queryGroupTopSection}>

public/app/fn-app/create-mfe.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { GrafanaTheme2 } from '@grafana/data/src/themes/types';
1414
import { ThemeChangedEvent } from '@grafana/runtime';
1515
import { GrafanaBootConfig } from '@grafana/runtime/src/config';
1616
import { getTheme } from '@grafana/ui';
17+
import app from 'app/app';
1718
import appEvents from 'app/core/app_events';
1819
import config from 'app/core/config';
1920
import {
@@ -25,7 +26,6 @@ import {
2526
fnStateProps,
2627
} from 'app/core/reducers/fn-slice';
2728
import { backendSrv } from 'app/core/services/backend_srv';
28-
import fn_app from 'app/fn_app';
2929
import { FnLoggerService } from 'app/fn_logger';
3030
import { dispatch } from 'app/store/store';
3131

@@ -89,7 +89,7 @@ class createMfe {
8989
}
9090

9191
static boot() {
92-
return () => fn_app.init();
92+
return () => app.init(true);
9393
}
9494

9595
private static toggleTheme = (mode: FNDashboardProps['mode']): GrafanaThemeType.Light | GrafanaThemeType.Dark =>

public/app/fn-app/fn-dashboard-page/fn-dashboard.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { FC, useMemo } from 'react';
22

3+
import { ModalRoot, PortalContainer } from '@grafana/ui';
4+
import { AppWrapper } from 'app/AppWrapper';
5+
import app from 'app/app';
36
import { FnGlobalState, FnPropMappedFromState } from 'app/core/reducers/fn-slice';
47
import { useSelector } from 'app/types';
58

6-
import { FnAppProvider } from '../fn-app-provider';
79
import { FNDashboardProps } from '../types';
810
import { RenderPortal } from '../utils';
911

@@ -13,9 +15,9 @@ type FNDashboardComponentProps = Omit<FNDashboardProps, FnPropMappedFromState>;
1315

1416
export const FNDashboard: FC<FNDashboardComponentProps> = (props) => {
1517
return (
16-
<FnAppProvider fnError={props.fnError}>
18+
<AppWrapper app={app} isMFE>
1719
<DashboardPortal {...props} />
18-
</FnAppProvider>
20+
</AppWrapper>
1921
);
2022
};
2123

@@ -54,6 +56,8 @@ export const DashboardPortal: FC<FNDashboardComponentProps> = (p) => {
5456

5557
return (
5658
<RenderPortal ID="grafana-portal">
59+
<ModalRoot />
60+
<PortalContainer />
5761
{content}
5862
</RenderPortal>
5963
);

0 commit comments

Comments
 (0)