From 4a713bd9ed4f276f6b9634d2551c9ec2cb8e1e96 Mon Sep 17 00:00:00 2001 From: "David Kim (DK)" <54411318+idk-92@users.noreply.github.com> Date: Mon, 10 Mar 2025 03:50:42 -0700 Subject: [PATCH] Plugin: expose nested folder component from core grafana (#97765) * expose nested folder component from core grafana * prettier * import order * remove unused commented code * remove unneeded file * make a LazyFolderPicker * fix types, change permission to string * comment * reset some changes back to main * no need to log --------- Co-authored-by: Joe Blubaugh Co-authored-by: joshhunt Co-authored-by: joshhunt --- .../src/components/FolderPicker.tsx | 49 +++++++++++++++++++ packages/grafana-runtime/src/index.ts | 1 + public/app/app.ts | 3 ++ 3 files changed, 53 insertions(+) create mode 100644 packages/grafana-runtime/src/components/FolderPicker.tsx diff --git a/packages/grafana-runtime/src/components/FolderPicker.tsx b/packages/grafana-runtime/src/components/FolderPicker.tsx new file mode 100644 index 00000000000..3a22b761e96 --- /dev/null +++ b/packages/grafana-runtime/src/components/FolderPicker.tsx @@ -0,0 +1,49 @@ +import * as React from 'react'; + +interface FolderPickerProps { + /* Folder UID to show as selected */ + value?: string; + + /** Show an invalid state around the folder picker */ + invalid?: boolean; + + /* Whether to show the root 'Dashboards' (formally General) folder as selectable */ + showRootFolder?: boolean; + + /* Folder UIDs to exclude from the picker, to prevent invalid operations */ + excludeUIDs?: string[]; + + /* Show folders matching this permission, mainly used to also show folders user can view. Defaults to showing only folders user has Edit */ + permission?: 'view' | 'edit'; + + /* Callback for when the user selects a folder */ + onChange?: (folderUID: string | undefined, folderName: string | undefined) => void; + + /* Whether the picker should be clearable */ + clearable?: boolean; +} + +type FolderPickerComponentType = React.ComponentType; + +let FolderPickerComponent: FolderPickerComponentType | undefined; + +/** + * Used to bootstrap the FolderPicker during application start + * + * @internal + */ +export function setFolderPicker(component: FolderPickerComponentType) { + FolderPickerComponent = component; +} + +export function FolderPicker(props: FolderPickerProps) { + if (FolderPickerComponent) { + return ; + } + + if (process.env.NODE_ENV !== 'production') { + return
@grafana/runtime FolderPicker is not set
; + } + + return null; +} diff --git a/packages/grafana-runtime/src/index.ts b/packages/grafana-runtime/src/index.ts index a28fab8050a..2250f0db26f 100644 --- a/packages/grafana-runtime/src/index.ts +++ b/packages/grafana-runtime/src/index.ts @@ -57,6 +57,7 @@ export { hasPermission, hasPermissionInMetadata, hasAllPermissions, hasAnyPermis export { QueryEditorWithMigration } from './components/QueryEditorWithMigration'; export { type MigrationHandler, isMigrationHandler, migrateQuery, migrateRequest } from './utils/migrationHandler'; export { usePluginUserStorage } from './utils/userStorage'; +export { FolderPicker, setFolderPicker } from './components/FolderPicker'; export { type CorrelationsService, type CorrelationData, diff --git a/public/app/app.ts b/public/app/app.ts index 7a3ba0bf140..02c491c90c0 100644 --- a/public/app/app.ts +++ b/public/app/app.ts @@ -38,6 +38,7 @@ import { setCurrentUser, setChromeHeaderHeightHook, setPluginLinksHook, + setFolderPicker, setCorrelationsService, setPluginFunctionsHook, } from '@grafana/runtime'; @@ -52,6 +53,7 @@ import getDefaultMonacoLanguages from '../lib/monaco-languages'; import { AppWrapper } from './AppWrapper'; import appEvents from './core/app_events'; import { AppChromeService } from './core/components/AppChrome/AppChromeService'; +import { LazyFolderPicker } from './core/components/NestedFolderPicker/LazyFolderPicker'; import { getAllOptionEditors, getAllStandardFieldConfigs } from './core/components/OptionsUI/registry'; import { PluginPage } from './core/components/Page/PluginPage'; import { GrafanaContextType, useChromeHeaderHeight, useReturnToPreviousInternal } from './core/context/GrafanaContext'; @@ -134,6 +136,7 @@ export class GrafanaApp { setWeekStart(config.bootData.user.weekStart); setPanelRenderer(PanelRenderer); setPluginPage(PluginPage); + setFolderPicker(LazyFolderPicker); setPanelDataErrorView(PanelDataErrorView); setLocationSrv(locationService); setCorrelationsService(new CorrelationsService());