@perses-dev/plugin-system 0.54.0-beta.1 → 0.54.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/PluginRegistry/PluginRegistry.js +11 -15
- package/dist/cjs/components/PluginRegistry/getPluginSearchHelper.js +92 -0
- package/dist/cjs/components/PluginRegistry/plugin-indexes.js +16 -13
- package/dist/cjs/components/Variables/variable-model.js +115 -29
- package/dist/cjs/context/ValidationProvider.js +3 -3
- package/dist/cjs/model/alerts-queries.js +16 -0
- package/dist/cjs/model/index.js +2 -0
- package/dist/cjs/model/log-volume-utils.js +10 -10
- package/dist/cjs/model/plugin-loading.js +24 -8
- package/dist/cjs/model/plugins.js +10 -0
- package/dist/cjs/model/silences-queries.js +16 -0
- package/dist/cjs/remote/PluginRuntime.js +38 -9
- package/dist/cjs/remote/remotePluginLoader.js +28 -5
- package/dist/cjs/runtime/DataQueriesProvider/DataQueriesProvider.js +18 -2
- package/dist/cjs/runtime/DataQueriesProvider/model.js +30 -4
- package/dist/cjs/runtime/UsageMetricsProvider.js +2 -2
- package/dist/cjs/runtime/alerts-queries.js +101 -0
- package/dist/cjs/runtime/index.js +2 -0
- package/dist/cjs/runtime/item-actions.js +3 -3
- package/dist/cjs/runtime/log-queries.js +4 -1
- package/dist/cjs/runtime/plugin-registry.js +12 -3
- package/dist/cjs/runtime/profile-queries.js +4 -1
- package/dist/cjs/runtime/silences-queries.js +101 -0
- package/dist/cjs/runtime/time-series-queries.js +4 -1
- package/dist/cjs/runtime/trace-queries.js +4 -1
- package/dist/cjs/test/mock-data.js +51 -0
- package/dist/cjs/test/test-plugins/bert/index.js +9 -12
- package/dist/cjs/test/test-plugins/ernie/index.js +9 -12
- package/dist/cjs/test/test-plugins/index.js +2 -2
- package/dist/cjs/test-utils/mock-plugin-registry.js +8 -2
- package/dist/components/CalculationSelector/CalculationSelector.js +1 -1
- package/dist/components/CalculationSelector/CalculationSelector.js.map +1 -1
- package/dist/components/DatasourceEditorForm/DatasourceEditorForm.d.ts +1 -1
- package/dist/components/DatasourceEditorForm/DatasourceEditorForm.d.ts.map +1 -1
- package/dist/components/DatasourceEditorForm/DatasourceEditorForm.js +1 -1
- package/dist/components/DatasourceEditorForm/DatasourceEditorForm.js.map +1 -1
- package/dist/components/DatasourceSelect/DatasourceSelect.js +2 -2
- package/dist/components/DatasourceSelect/DatasourceSelect.js.map +1 -1
- package/dist/components/HTTPSettingsEditor/HTTPSettingsEditor.d.ts +1 -1
- package/dist/components/HTTPSettingsEditor/HTTPSettingsEditor.d.ts.map +1 -1
- package/dist/components/HTTPSettingsEditor/HTTPSettingsEditor.js +1 -1
- package/dist/components/HTTPSettingsEditor/HTTPSettingsEditor.js.map +1 -1
- package/dist/components/ItemSelectionActionsOptionsEditor/ItemSelectionActionsOptionsEditor.js +1 -1
- package/dist/components/ItemSelectionActionsOptionsEditor/ItemSelectionActionsOptionsEditor.js.map +1 -1
- package/dist/components/LegendOptionsEditor/LegendOptionsEditor.js +1 -1
- package/dist/components/LegendOptionsEditor/LegendOptionsEditor.js.map +1 -1
- package/dist/components/MetricLabelInput/MetricLabelInput.js +1 -1
- package/dist/components/MetricLabelInput/MetricLabelInput.js.map +1 -1
- package/dist/components/MultiQueryEditor/MultiQueryEditor.js +1 -1
- package/dist/components/MultiQueryEditor/MultiQueryEditor.js.map +1 -1
- package/dist/components/MultiQueryEditor/QueryEditorContainer.js +1 -1
- package/dist/components/MultiQueryEditor/QueryEditorContainer.js.map +1 -1
- package/dist/components/OptionsEditorRadios/OptionsEditorRadios.js +1 -1
- package/dist/components/OptionsEditorRadios/OptionsEditorRadios.js.map +1 -1
- package/dist/components/OptionsEditorTabPanel/OptionsEditorTabPanel.js +1 -1
- package/dist/components/OptionsEditorTabPanel/OptionsEditorTabPanel.js.map +1 -1
- package/dist/components/OptionsEditorTabs/OptionsEditorTabs.js +1 -1
- package/dist/components/OptionsEditorTabs/OptionsEditorTabs.js.map +1 -1
- package/dist/components/PanelSpecEditor/PanelSpecEditor.js +1 -1
- package/dist/components/PanelSpecEditor/PanelSpecEditor.js.map +1 -1
- package/dist/components/PluginEditor/PluginEditor.js +1 -1
- package/dist/components/PluginEditor/PluginEditor.js.map +1 -1
- package/dist/components/PluginKindSelect/PluginKindSelect.js +1 -1
- package/dist/components/PluginKindSelect/PluginKindSelect.js.map +1 -1
- package/dist/components/PluginRegistry/PluginRegistry.d.ts.map +1 -1
- package/dist/components/PluginRegistry/PluginRegistry.js +12 -16
- package/dist/components/PluginRegistry/PluginRegistry.js.map +1 -1
- package/dist/components/PluginRegistry/getPluginSearchHelper.d.ts +12 -0
- package/dist/components/PluginRegistry/getPluginSearchHelper.d.ts.map +1 -0
- package/dist/components/PluginRegistry/getPluginSearchHelper.js +88 -0
- package/dist/components/PluginRegistry/getPluginSearchHelper.js.map +1 -0
- package/dist/components/PluginRegistry/plugin-indexes.d.ts +4 -6
- package/dist/components/PluginRegistry/plugin-indexes.d.ts.map +1 -1
- package/dist/components/PluginRegistry/plugin-indexes.js +15 -13
- package/dist/components/PluginRegistry/plugin-indexes.js.map +1 -1
- package/dist/components/PluginSpecEditor/PluginSpecEditor.d.ts.map +1 -1
- package/dist/components/PluginSpecEditor/PluginSpecEditor.js +1 -1
- package/dist/components/PluginSpecEditor/PluginSpecEditor.js.map +1 -1
- package/dist/components/SelectionOptionsEditor/SelectionOptionsEditor.js +1 -1
- package/dist/components/SelectionOptionsEditor/SelectionOptionsEditor.js.map +1 -1
- package/dist/components/TimeRangeControls/TimeRangeControls.js +1 -1
- package/dist/components/TimeRangeControls/TimeRangeControls.js.map +1 -1
- package/dist/components/Variables/VariableEditorForm/VariableEditorForm.js +1 -1
- package/dist/components/Variables/VariableEditorForm/VariableEditorForm.js.map +1 -1
- package/dist/components/Variables/VariableEditorForm/VariablePreview.js +1 -1
- package/dist/components/Variables/VariableEditorForm/VariablePreview.js.map +1 -1
- package/dist/components/Variables/variable-model.d.ts +9 -1
- package/dist/components/Variables/variable-model.d.ts.map +1 -1
- package/dist/components/Variables/variable-model.js +117 -31
- package/dist/components/Variables/variable-model.js.map +1 -1
- package/dist/context/ValidationProvider.d.ts +1 -1
- package/dist/context/ValidationProvider.d.ts.map +1 -1
- package/dist/context/ValidationProvider.js +2 -2
- package/dist/context/ValidationProvider.js.map +1 -1
- package/dist/model/alerts-queries.d.ts +33 -0
- package/dist/model/alerts-queries.d.ts.map +1 -0
- package/dist/model/alerts-queries.js +15 -0
- package/dist/model/alerts-queries.js.map +1 -0
- package/dist/model/datasource.d.ts +1 -8
- package/dist/model/datasource.d.ts.map +1 -1
- package/dist/model/datasource.js +1 -1
- package/dist/model/datasource.js.map +1 -1
- package/dist/model/index.d.ts +2 -0
- package/dist/model/index.d.ts.map +1 -1
- package/dist/model/index.js +2 -0
- package/dist/model/index.js.map +1 -1
- package/dist/model/plugin-loading.d.ts.map +1 -1
- package/dist/model/plugin-loading.js +24 -8
- package/dist/model/plugin-loading.js.map +1 -1
- package/dist/model/plugins.d.ts +21 -0
- package/dist/model/plugins.d.ts.map +1 -1
- package/dist/model/plugins.js +4 -1
- package/dist/model/plugins.js.map +1 -1
- package/dist/model/silences-queries.d.ts +33 -0
- package/dist/model/silences-queries.d.ts.map +1 -0
- package/dist/model/silences-queries.js +15 -0
- package/dist/model/silences-queries.js.map +1 -0
- package/dist/remote/PersesPlugin.types.d.ts +2 -0
- package/dist/remote/PersesPlugin.types.d.ts.map +1 -1
- package/dist/remote/PersesPlugin.types.js.map +1 -1
- package/dist/remote/PluginLoaderComponent.js +1 -1
- package/dist/remote/PluginLoaderComponent.js.map +1 -1
- package/dist/remote/PluginRuntime.d.ts +7 -1
- package/dist/remote/PluginRuntime.d.ts.map +1 -1
- package/dist/remote/PluginRuntime.js +38 -9
- package/dist/remote/PluginRuntime.js.map +1 -1
- package/dist/remote/remotePluginLoader.d.ts.map +1 -1
- package/dist/remote/remotePluginLoader.js +28 -5
- package/dist/remote/remotePluginLoader.js.map +1 -1
- package/dist/runtime/DataQueriesProvider/DataQueriesProvider.d.ts.map +1 -1
- package/dist/runtime/DataQueriesProvider/DataQueriesProvider.js +19 -3
- package/dist/runtime/DataQueriesProvider/DataQueriesProvider.js.map +1 -1
- package/dist/runtime/DataQueriesProvider/model.d.ts.map +1 -1
- package/dist/runtime/DataQueriesProvider/model.js +30 -4
- package/dist/runtime/DataQueriesProvider/model.js.map +1 -1
- package/dist/runtime/QueryCountProvider.js +1 -1
- package/dist/runtime/QueryCountProvider.js.map +1 -1
- package/dist/runtime/RouterProvider.js +1 -1
- package/dist/runtime/RouterProvider.js.map +1 -1
- package/dist/runtime/TimeRangeProvider/TimeRangeProvider.js +1 -1
- package/dist/runtime/TimeRangeProvider/TimeRangeProvider.js.map +1 -1
- package/dist/runtime/TimeRangeProvider/TimeRangeSettingsProvider.js +1 -1
- package/dist/runtime/TimeRangeProvider/TimeRangeSettingsProvider.js.map +1 -1
- package/dist/runtime/UsageMetricsProvider.js +2 -2
- package/dist/runtime/UsageMetricsProvider.js.map +1 -1
- package/dist/runtime/alerts-queries.d.ts +11 -0
- package/dist/runtime/alerts-queries.d.ts.map +1 -0
- package/dist/runtime/alerts-queries.js +89 -0
- package/dist/runtime/alerts-queries.js.map +1 -0
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +2 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/item-actions.js +1 -1
- package/dist/runtime/item-actions.js.map +1 -1
- package/dist/runtime/log-queries.js +4 -1
- package/dist/runtime/log-queries.js.map +1 -1
- package/dist/runtime/plugin-registry.d.ts +2 -1
- package/dist/runtime/plugin-registry.d.ts.map +1 -1
- package/dist/runtime/plugin-registry.js +12 -3
- package/dist/runtime/plugin-registry.js.map +1 -1
- package/dist/runtime/profile-queries.js +4 -1
- package/dist/runtime/profile-queries.js.map +1 -1
- package/dist/runtime/silences-queries.d.ts +11 -0
- package/dist/runtime/silences-queries.d.ts.map +1 -0
- package/dist/runtime/silences-queries.js +89 -0
- package/dist/runtime/silences-queries.js.map +1 -0
- package/dist/runtime/time-series-queries.js +4 -1
- package/dist/runtime/time-series-queries.js.map +1 -1
- package/dist/runtime/trace-queries.js +4 -1
- package/dist/runtime/trace-queries.js.map +1 -1
- package/dist/test/mock-data.d.ts +3 -1
- package/dist/test/mock-data.d.ts.map +1 -1
- package/dist/test/mock-data.js +45 -0
- package/dist/test/mock-data.js.map +1 -1
- package/dist/test/render.js +1 -1
- package/dist/test/render.js.map +1 -1
- package/dist/test/test-plugins/bert/index.d.ts +12 -6
- package/dist/test/test-plugins/bert/index.d.ts.map +1 -1
- package/dist/test/test-plugins/bert/index.js +6 -2
- package/dist/test/test-plugins/bert/index.js.map +1 -1
- package/dist/test/test-plugins/ernie/index.d.ts +8 -6
- package/dist/test/test-plugins/ernie/index.d.ts.map +1 -1
- package/dist/test/test-plugins/ernie/index.js +6 -2
- package/dist/test/test-plugins/ernie/index.js.map +1 -1
- package/dist/test/test-plugins/index.js +2 -2
- package/dist/test/test-plugins/index.js.map +1 -1
- package/dist/test/utils.js +1 -1
- package/dist/test/utils.js.map +1 -1
- package/dist/test-utils/mock-plugin-registry.d.ts.map +1 -1
- package/dist/test-utils/mock-plugin-registry.js +8 -2
- package/dist/test-utils/mock-plugin-registry.js.map +1 -1
- package/package.json +6 -5
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
1
2
|
// Copyright The Perses Authors
|
|
2
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -10,7 +11,6 @@
|
|
|
10
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
12
|
// See the License for the specific language governing permissions and
|
|
12
13
|
// limitations under the License.
|
|
13
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
14
14
|
import { Tab, Tabs, Box } from '@mui/material';
|
|
15
15
|
import { useState } from 'react';
|
|
16
16
|
import { OptionsEditorTabPanel } from '../OptionsEditorTabPanel';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/OptionsEditorTabs/OptionsEditorTabs.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Tab, Tabs, TabsProps, Box } from '@mui/material';\nimport { ReactElement, ReactNode, useState } from 'react';\nimport { OptionsEditorTabPanel } from '../OptionsEditorTabPanel';\n\nexport type OptionsEditorTab = {\n label: string;\n /**\n * Content rendered when the tab is active.\n */\n content: ReactNode;\n};\n\nexport type OptionsEditorTabsProps = {\n tabs: OptionsEditorTab[];\n};\n\nexport const OptionsEditorTabs = ({ tabs }: OptionsEditorTabsProps): ReactElement => {\n const [activeTab, setActiveTab] = useState(0);\n\n const handleChange: TabsProps['onChange'] = (_, newValue) => {\n setActiveTab(newValue);\n };\n\n return (\n <>\n <Box sx={{ borderBottom: 1, borderColor: (theme) => theme.palette.divider }}>\n <Tabs value={activeTab} onChange={handleChange} aria-label=\"Panel configuration tabs\">\n {tabs.map(({ label }, i) => {\n return (\n <Tab\n key={label}\n label={label}\n id={`options-editor-tab-${i}`}\n aria-controls={`options-editor-tabpanel-${i}`}\n />\n );\n })}\n </Tabs>\n </Box>\n {tabs.map(({ label, content }, i) => {\n return (\n <OptionsEditorTabPanel key={label} value={activeTab} index={i}>\n {content}\n </OptionsEditorTabPanel>\n );\n })}\n </>\n );\n};\n"],"names":["Tab","Tabs","Box","useState","OptionsEditorTabPanel","OptionsEditorTabs","tabs","activeTab","setActiveTab","handleChange","_","newValue","sx","borderBottom","borderColor","theme","palette","divider","value","onChange","aria-label","map","label","i","id","aria-controls","content","index"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC
|
|
1
|
+
{"version":3,"sources":["../../../src/components/OptionsEditorTabs/OptionsEditorTabs.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Tab, Tabs, TabsProps, Box } from '@mui/material';\nimport { ReactElement, ReactNode, useState } from 'react';\nimport { OptionsEditorTabPanel } from '../OptionsEditorTabPanel';\n\nexport type OptionsEditorTab = {\n label: string;\n /**\n * Content rendered when the tab is active.\n */\n content: ReactNode;\n};\n\nexport type OptionsEditorTabsProps = {\n tabs: OptionsEditorTab[];\n};\n\nexport const OptionsEditorTabs = ({ tabs }: OptionsEditorTabsProps): ReactElement => {\n const [activeTab, setActiveTab] = useState(0);\n\n const handleChange: TabsProps['onChange'] = (_, newValue) => {\n setActiveTab(newValue);\n };\n\n return (\n <>\n <Box sx={{ borderBottom: 1, borderColor: (theme) => theme.palette.divider }}>\n <Tabs value={activeTab} onChange={handleChange} aria-label=\"Panel configuration tabs\">\n {tabs.map(({ label }, i) => {\n return (\n <Tab\n key={label}\n label={label}\n id={`options-editor-tab-${i}`}\n aria-controls={`options-editor-tabpanel-${i}`}\n />\n );\n })}\n </Tabs>\n </Box>\n {tabs.map(({ label, content }, i) => {\n return (\n <OptionsEditorTabPanel key={label} value={activeTab} index={i}>\n {content}\n </OptionsEditorTabPanel>\n );\n })}\n </>\n );\n};\n"],"names":["Tab","Tabs","Box","useState","OptionsEditorTabPanel","OptionsEditorTabs","tabs","activeTab","setActiveTab","handleChange","_","newValue","sx","borderBottom","borderColor","theme","palette","divider","value","onChange","aria-label","map","label","i","id","aria-controls","content","index"],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,GAAG,EAAEC,IAAI,EAAaC,GAAG,QAAQ,gBAAgB;AAC1D,SAAkCC,QAAQ,QAAQ,QAAQ;AAC1D,SAASC,qBAAqB,QAAQ,2BAA2B;AAcjE,OAAO,MAAMC,oBAAoB,CAAC,EAAEC,IAAI,EAA0B;IAChE,MAAM,CAACC,WAAWC,aAAa,GAAGL,SAAS;IAE3C,MAAMM,eAAsC,CAACC,GAAGC;QAC9CH,aAAaG;IACf;IAEA,qBACE;;0BACE,KAACT;gBAAIU,IAAI;oBAAEC,cAAc;oBAAGC,aAAa,CAACC,QAAUA,MAAMC,OAAO,CAACC,OAAO;gBAAC;0BACxE,cAAA,KAAChB;oBAAKiB,OAAOX;oBAAWY,UAAUV;oBAAcW,cAAW;8BACxDd,KAAKe,GAAG,CAAC,CAAC,EAAEC,KAAK,EAAE,EAAEC;wBACpB,qBACE,KAACvB;4BAECsB,OAAOA;4BACPE,IAAI,CAAC,mBAAmB,EAAED,GAAG;4BAC7BE,iBAAe,CAAC,wBAAwB,EAAEF,GAAG;2BAHxCD;oBAMX;;;YAGHhB,KAAKe,GAAG,CAAC,CAAC,EAAEC,KAAK,EAAEI,OAAO,EAAE,EAAEH;gBAC7B,qBACE,KAACnB;oBAAkCc,OAAOX;oBAAWoB,OAAOJ;8BACzDG;mBADyBJ;YAIhC;;;AAGN,EAAE"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
2
|
// Copyright The Perses Authors
|
|
2
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -10,7 +11,6 @@
|
|
|
10
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
12
|
// See the License for the specific language governing permissions and
|
|
12
13
|
// limitations under the License.
|
|
13
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
14
|
import { ErrorAlert, JSONEditor, LinksEditor } from '@perses-dev/components';
|
|
15
15
|
import { Controller } from 'react-hook-form';
|
|
16
16
|
import { forwardRef } from 'react';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/PanelSpecEditor/PanelSpecEditor.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ErrorAlert, JSONEditor, LinksEditor } from '@perses-dev/components';\nimport { PanelDefinition, PanelEditorValues, QueryDefinition, UnknownSpec } from '@perses-dev/spec';\nimport { Control, Controller } from 'react-hook-form';\nimport { forwardRef, ReactElement } from 'react';\nimport { QueryCountProvider, useDataQueriesContext, usePlugin } from '../../runtime';\nimport { PanelPlugin } from '../../model';\nimport { OptionsEditorTabsProps, OptionsEditorTabs } from '../OptionsEditorTabs';\nimport { MultiQueryEditor } from '../MultiQueryEditor';\nimport { PluginEditorRef } from '../PluginEditor';\n\nexport interface PanelSpecEditorProps {\n control: Control<PanelEditorValues>;\n panelDefinition: PanelDefinition;\n onQueriesChange: (queries: QueryDefinition[]) => void;\n onQueryRun: (index: number, query: QueryDefinition) => void;\n onPluginSpecChange: (spec: UnknownSpec) => void;\n onJSONChange: (panelDefinitionStr: string) => void;\n}\n\nexport const PanelSpecEditor = forwardRef<PluginEditorRef, PanelSpecEditorProps>((props, ref): ReactElement | null => {\n const { control, panelDefinition, onQueriesChange, onQueryRun, onPluginSpecChange, onJSONChange } = props;\n const { kind } = panelDefinition.spec.plugin;\n const { data: plugin, isLoading, error } = usePlugin('Panel', kind);\n\n const { queryResults } = useDataQueriesContext();\n\n if (error) {\n return <ErrorAlert error={error} />;\n }\n\n if (isLoading) {\n return null;\n }\n\n if (!plugin) {\n throw new Error(`Missing implementation for panel plugin with kind '${kind}'`);\n }\n\n const { panelOptionsEditorComponents, hideQueryEditor } = plugin as PanelPlugin;\n let tabs: OptionsEditorTabsProps['tabs'] = [];\n\n if (!hideQueryEditor) {\n tabs.push({\n label: 'Query',\n content: (\n <Controller\n control={control}\n name=\"panelDefinition.spec.queries\"\n render={({ field }) => (\n <MultiQueryEditor\n ref={ref}\n queryTypes={plugin.supportedQueryTypes ?? []}\n queries={panelDefinition.spec.queries ?? []}\n queryResults={queryResults}\n onChange={(queries) => {\n field.onChange(queries);\n onQueriesChange(queries);\n }}\n onQueryRun={(index, query) => {\n onQueryRun(index, query);\n // If spec has not changed, refetch to update the data\n if (JSON.stringify(panelDefinition.spec.queries?.[index]) === JSON.stringify(query)) {\n queryResults[index]?.refetch?.();\n }\n }}\n />\n )}\n />\n ),\n });\n }\n\n if (panelOptionsEditorComponents) {\n tabs = tabs.concat(\n panelOptionsEditorComponents.map(({ label, content: OptionsEditorComponent }) => ({\n label,\n content: (\n <Controller\n control={control}\n name=\"panelDefinition.spec.plugin.spec\"\n render={({ field }) => (\n <OptionsEditorComponent\n value={panelDefinition.spec.plugin.spec}\n onChange={(spec) => {\n field.onChange(spec);\n onPluginSpecChange(spec);\n }}\n />\n )}\n />\n ),\n }))\n );\n }\n\n // always show json editor and links editor by default\n tabs.push({\n label: 'Links',\n content: <LinksEditor control={control} />,\n });\n tabs.push({\n label: 'JSON',\n content: (\n <Controller\n control={control}\n name=\"panelDefinition\"\n render={({ field }) => (\n <JSONEditor\n maxHeight=\"80vh\"\n value={panelDefinition}\n onChange={(json) => {\n field.onChange(JSON.parse(json));\n onJSONChange(json);\n }}\n />\n )}\n />\n ),\n });\n\n return (\n <QueryCountProvider queryCount={(panelDefinition.spec.queries ?? []).length}>\n <OptionsEditorTabs key={tabs.length} tabs={tabs} />\n </QueryCountProvider>\n );\n});\n\nPanelSpecEditor.displayName = 'PanelSpecEditor';\n"],"names":["ErrorAlert","JSONEditor","LinksEditor","Controller","forwardRef","QueryCountProvider","useDataQueriesContext","usePlugin","OptionsEditorTabs","MultiQueryEditor","PanelSpecEditor","props","ref","control","panelDefinition","onQueriesChange","onQueryRun","onPluginSpecChange","onJSONChange","kind","spec","plugin","data","isLoading","error","queryResults","Error","panelOptionsEditorComponents","hideQueryEditor","tabs","push","label","content","name","render","field","queryTypes","supportedQueryTypes","queries","onChange","index","query","JSON","stringify","refetch","concat","map","OptionsEditorComponent","value","maxHeight","json","parse","queryCount","length","displayName"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC
|
|
1
|
+
{"version":3,"sources":["../../../src/components/PanelSpecEditor/PanelSpecEditor.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ErrorAlert, JSONEditor, LinksEditor } from '@perses-dev/components';\nimport { PanelDefinition, PanelEditorValues, QueryDefinition, UnknownSpec } from '@perses-dev/spec';\nimport { Control, Controller } from 'react-hook-form';\nimport { forwardRef, ReactElement } from 'react';\nimport { QueryCountProvider, useDataQueriesContext, usePlugin } from '../../runtime';\nimport { PanelPlugin } from '../../model';\nimport { OptionsEditorTabsProps, OptionsEditorTabs } from '../OptionsEditorTabs';\nimport { MultiQueryEditor } from '../MultiQueryEditor';\nimport { PluginEditorRef } from '../PluginEditor';\n\nexport interface PanelSpecEditorProps {\n control: Control<PanelEditorValues>;\n panelDefinition: PanelDefinition;\n onQueriesChange: (queries: QueryDefinition[]) => void;\n onQueryRun: (index: number, query: QueryDefinition) => void;\n onPluginSpecChange: (spec: UnknownSpec) => void;\n onJSONChange: (panelDefinitionStr: string) => void;\n}\n\nexport const PanelSpecEditor = forwardRef<PluginEditorRef, PanelSpecEditorProps>((props, ref): ReactElement | null => {\n const { control, panelDefinition, onQueriesChange, onQueryRun, onPluginSpecChange, onJSONChange } = props;\n const { kind } = panelDefinition.spec.plugin;\n const { data: plugin, isLoading, error } = usePlugin('Panel', kind);\n\n const { queryResults } = useDataQueriesContext();\n\n if (error) {\n return <ErrorAlert error={error} />;\n }\n\n if (isLoading) {\n return null;\n }\n\n if (!plugin) {\n throw new Error(`Missing implementation for panel plugin with kind '${kind}'`);\n }\n\n const { panelOptionsEditorComponents, hideQueryEditor } = plugin as PanelPlugin;\n let tabs: OptionsEditorTabsProps['tabs'] = [];\n\n if (!hideQueryEditor) {\n tabs.push({\n label: 'Query',\n content: (\n <Controller\n control={control}\n name=\"panelDefinition.spec.queries\"\n render={({ field }) => (\n <MultiQueryEditor\n ref={ref}\n queryTypes={plugin.supportedQueryTypes ?? []}\n queries={panelDefinition.spec.queries ?? []}\n queryResults={queryResults}\n onChange={(queries) => {\n field.onChange(queries);\n onQueriesChange(queries);\n }}\n onQueryRun={(index, query) => {\n onQueryRun(index, query);\n // If spec has not changed, refetch to update the data\n if (JSON.stringify(panelDefinition.spec.queries?.[index]) === JSON.stringify(query)) {\n queryResults[index]?.refetch?.();\n }\n }}\n />\n )}\n />\n ),\n });\n }\n\n if (panelOptionsEditorComponents) {\n tabs = tabs.concat(\n panelOptionsEditorComponents.map(({ label, content: OptionsEditorComponent }) => ({\n label,\n content: (\n <Controller\n control={control}\n name=\"panelDefinition.spec.plugin.spec\"\n render={({ field }) => (\n <OptionsEditorComponent\n value={panelDefinition.spec.plugin.spec}\n onChange={(spec) => {\n field.onChange(spec);\n onPluginSpecChange(spec);\n }}\n />\n )}\n />\n ),\n }))\n );\n }\n\n // always show json editor and links editor by default\n tabs.push({\n label: 'Links',\n content: <LinksEditor control={control} />,\n });\n tabs.push({\n label: 'JSON',\n content: (\n <Controller\n control={control}\n name=\"panelDefinition\"\n render={({ field }) => (\n <JSONEditor\n maxHeight=\"80vh\"\n value={panelDefinition}\n onChange={(json) => {\n field.onChange(JSON.parse(json));\n onJSONChange(json);\n }}\n />\n )}\n />\n ),\n });\n\n return (\n <QueryCountProvider queryCount={(panelDefinition.spec.queries ?? []).length}>\n <OptionsEditorTabs key={tabs.length} tabs={tabs} />\n </QueryCountProvider>\n );\n});\n\nPanelSpecEditor.displayName = 'PanelSpecEditor';\n"],"names":["ErrorAlert","JSONEditor","LinksEditor","Controller","forwardRef","QueryCountProvider","useDataQueriesContext","usePlugin","OptionsEditorTabs","MultiQueryEditor","PanelSpecEditor","props","ref","control","panelDefinition","onQueriesChange","onQueryRun","onPluginSpecChange","onJSONChange","kind","spec","plugin","data","isLoading","error","queryResults","Error","panelOptionsEditorComponents","hideQueryEditor","tabs","push","label","content","name","render","field","queryTypes","supportedQueryTypes","queries","onChange","index","query","JSON","stringify","refetch","concat","map","OptionsEditorComponent","value","maxHeight","json","parse","queryCount","length","displayName"],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
2
|
// Copyright The Perses Authors
|
|
2
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -10,7 +11,6 @@
|
|
|
10
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
12
|
// See the License for the specific language governing permissions and
|
|
12
13
|
// limitations under the License.
|
|
13
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
14
|
import { Box, Button } from '@mui/material';
|
|
15
15
|
import Reload from 'mdi-material-ui/Reload';
|
|
16
16
|
import { ErrorAlert, ErrorBoundary } from '@perses-dev/components';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/PluginEditor/PluginEditor.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Box, Button } from '@mui/material';\nimport Reload from 'mdi-material-ui/Reload';\nimport { ErrorAlert, ErrorBoundary } from '@perses-dev/components';\nimport { ReactElement, useCallback } from 'react';\nimport { UnknownSpec } from '@perses-dev/spec';\nimport { PluginKindSelect } from '../PluginKindSelect';\nimport { PluginSpecEditor } from '../PluginSpecEditor';\nimport { PluginEditorProps, usePluginEditor } from './plugin-editor-api';\n\n/**\n * A combination `PluginKindSelect` and `PluginSpecEditor` component. This is meant for editing the `plugin` property\n * that's common in our JSON specs where a user selects a plugin `kind` and then edits the `spec` via that plugin's\n * editor component. It takes care of transitioning from one plugin kind to another \"all at once\" so that when the\n * plugin's kind changes, the spec is also changed at the same time so those options editor components don't see a\n * previous plugin's spec state. If you just want this behavior, but in a different UI layout from this, try the\n * `usePluginEditor` hook that powers this component.\n */\n\nexport function PluginEditor(props: PluginEditorProps): ReactElement {\n const {\n value,\n withRunQueryButton = true,\n pluginTypes,\n pluginKindLabel,\n onChange: _,\n isReadonly,\n onRunQuery,\n filteredQueryPlugins,\n ...others\n } = props;\n\n const { pendingSelection, isLoading, error, onSelectionChange, onSpecChange } = usePluginEditor(props);\n\n const handleSpecChange = useCallback(\n (nextSpec: UnknownSpec) => {\n onSpecChange(nextSpec);\n },\n [onSpecChange]\n );\n\n return (\n <Box {...others}>\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 1,\n mb: 1,\n }}\n >\n <PluginKindSelect\n fullWidth={false}\n sx={{ minWidth: 120 }}\n margin=\"dense\"\n label={pluginKindLabel}\n pluginTypes={pluginTypes}\n disabled={isLoading}\n value={pendingSelection ? pendingSelection : value.selection}\n slotProps={{ input: { readOnly: isReadonly } }}\n error={!!error}\n helperText={error?.message}\n onChange={onSelectionChange}\n filteredQueryPlugins={filteredQueryPlugins}\n />\n\n {withRunQueryButton && (\n <Button\n data-testid=\"run_query_button\"\n variant=\"contained\"\n startIcon={<Reload />}\n onClick={onRunQuery}\n disabled={isLoading}\n >\n Run Query\n </Button>\n )}\n </Box>\n\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <PluginSpecEditor\n pluginSelection={value.selection}\n value={value.spec}\n onChange={handleSpecChange}\n isReadonly={isReadonly}\n />\n </ErrorBoundary>\n </Box>\n );\n}\n"],"names":["Box","Button","Reload","ErrorAlert","ErrorBoundary","useCallback","PluginKindSelect","PluginSpecEditor","usePluginEditor","PluginEditor","props","value","withRunQueryButton","pluginTypes","pluginKindLabel","onChange","_","isReadonly","onRunQuery","filteredQueryPlugins","others","pendingSelection","isLoading","error","onSelectionChange","onSpecChange","handleSpecChange","nextSpec","sx","display","flexDirection","alignItems","justifyContent","gap","mb","fullWidth","minWidth","margin","label","disabled","selection","slotProps","input","readOnly","helperText","message","data-testid","variant","startIcon","onClick","FallbackComponent","pluginSelection","spec"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC
|
|
1
|
+
{"version":3,"sources":["../../../src/components/PluginEditor/PluginEditor.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Box, Button } from '@mui/material';\nimport Reload from 'mdi-material-ui/Reload';\nimport { ErrorAlert, ErrorBoundary } from '@perses-dev/components';\nimport { ReactElement, useCallback } from 'react';\nimport { UnknownSpec } from '@perses-dev/spec';\nimport { PluginKindSelect } from '../PluginKindSelect';\nimport { PluginSpecEditor } from '../PluginSpecEditor';\nimport { PluginEditorProps, usePluginEditor } from './plugin-editor-api';\n\n/**\n * A combination `PluginKindSelect` and `PluginSpecEditor` component. This is meant for editing the `plugin` property\n * that's common in our JSON specs where a user selects a plugin `kind` and then edits the `spec` via that plugin's\n * editor component. It takes care of transitioning from one plugin kind to another \"all at once\" so that when the\n * plugin's kind changes, the spec is also changed at the same time so those options editor components don't see a\n * previous plugin's spec state. If you just want this behavior, but in a different UI layout from this, try the\n * `usePluginEditor` hook that powers this component.\n */\n\nexport function PluginEditor(props: PluginEditorProps): ReactElement {\n const {\n value,\n withRunQueryButton = true,\n pluginTypes,\n pluginKindLabel,\n onChange: _,\n isReadonly,\n onRunQuery,\n filteredQueryPlugins,\n ...others\n } = props;\n\n const { pendingSelection, isLoading, error, onSelectionChange, onSpecChange } = usePluginEditor(props);\n\n const handleSpecChange = useCallback(\n (nextSpec: UnknownSpec) => {\n onSpecChange(nextSpec);\n },\n [onSpecChange]\n );\n\n return (\n <Box {...others}>\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 1,\n mb: 1,\n }}\n >\n <PluginKindSelect\n fullWidth={false}\n sx={{ minWidth: 120 }}\n margin=\"dense\"\n label={pluginKindLabel}\n pluginTypes={pluginTypes}\n disabled={isLoading}\n value={pendingSelection ? pendingSelection : value.selection}\n slotProps={{ input: { readOnly: isReadonly } }}\n error={!!error}\n helperText={error?.message}\n onChange={onSelectionChange}\n filteredQueryPlugins={filteredQueryPlugins}\n />\n\n {withRunQueryButton && (\n <Button\n data-testid=\"run_query_button\"\n variant=\"contained\"\n startIcon={<Reload />}\n onClick={onRunQuery}\n disabled={isLoading}\n >\n Run Query\n </Button>\n )}\n </Box>\n\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <PluginSpecEditor\n pluginSelection={value.selection}\n value={value.spec}\n onChange={handleSpecChange}\n isReadonly={isReadonly}\n />\n </ErrorBoundary>\n </Box>\n );\n}\n"],"names":["Box","Button","Reload","ErrorAlert","ErrorBoundary","useCallback","PluginKindSelect","PluginSpecEditor","usePluginEditor","PluginEditor","props","value","withRunQueryButton","pluginTypes","pluginKindLabel","onChange","_","isReadonly","onRunQuery","filteredQueryPlugins","others","pendingSelection","isLoading","error","onSelectionChange","onSpecChange","handleSpecChange","nextSpec","sx","display","flexDirection","alignItems","justifyContent","gap","mb","fullWidth","minWidth","margin","label","disabled","selection","slotProps","input","readOnly","helperText","message","data-testid","variant","startIcon","onClick","FallbackComponent","pluginSelection","spec"],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,GAAG,EAAEC,MAAM,QAAQ,gBAAgB;AAC5C,OAAOC,YAAY,yBAAyB;AAC5C,SAASC,UAAU,EAAEC,aAAa,QAAQ,yBAAyB;AACnE,SAAuBC,WAAW,QAAQ,QAAQ;AAElD,SAASC,gBAAgB,QAAQ,sBAAsB;AACvD,SAASC,gBAAgB,QAAQ,sBAAsB;AACvD,SAA4BC,eAAe,QAAQ,sBAAsB;AAEzE;;;;;;;CAOC,GAED,OAAO,SAASC,aAAaC,KAAwB;IACnD,MAAM,EACJC,KAAK,EACLC,qBAAqB,IAAI,EACzBC,WAAW,EACXC,eAAe,EACfC,UAAUC,CAAC,EACXC,UAAU,EACVC,UAAU,EACVC,oBAAoB,EACpB,GAAGC,QACJ,GAAGV;IAEJ,MAAM,EAAEW,gBAAgB,EAAEC,SAAS,EAAEC,KAAK,EAAEC,iBAAiB,EAAEC,YAAY,EAAE,GAAGjB,gBAAgBE;IAEhG,MAAMgB,mBAAmBrB,YACvB,CAACsB;QACCF,aAAaE;IACf,GACA;QAACF;KAAa;IAGhB,qBACE,MAACzB;QAAK,GAAGoB,MAAM;;0BACb,MAACpB;gBACC4B,IAAI;oBACFC,SAAS;oBACTC,eAAe;oBACfC,YAAY;oBACZC,gBAAgB;oBAChBC,KAAK;oBACLC,IAAI;gBACN;;kCAEA,KAAC5B;wBACC6B,WAAW;wBACXP,IAAI;4BAAEQ,UAAU;wBAAI;wBACpBC,QAAO;wBACPC,OAAOxB;wBACPD,aAAaA;wBACb0B,UAAUjB;wBACVX,OAAOU,mBAAmBA,mBAAmBV,MAAM6B,SAAS;wBAC5DC,WAAW;4BAAEC,OAAO;gCAAEC,UAAU1B;4BAAW;wBAAE;wBAC7CM,OAAO,CAAC,CAACA;wBACTqB,YAAYrB,OAAOsB;wBACnB9B,UAAUS;wBACVL,sBAAsBA;;oBAGvBP,oCACC,KAACX;wBACC6C,eAAY;wBACZC,SAAQ;wBACRC,yBAAW,KAAC9C;wBACZ+C,SAAS/B;wBACTqB,UAAUjB;kCACX;;;;0BAML,KAAClB;gBAAc8C,mBAAmB/C;0BAChC,cAAA,KAACI;oBACC4C,iBAAiBxC,MAAM6B,SAAS;oBAChC7B,OAAOA,MAAMyC,IAAI;oBACjBrC,UAAUW;oBACVT,YAAYA;;;;;AAKtB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
2
|
// Copyright The Perses Authors
|
|
2
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -10,7 +11,6 @@
|
|
|
10
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
12
|
// See the License for the specific language governing permissions and
|
|
12
13
|
// limitations under the License.
|
|
13
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
14
|
import { MenuItem, TextField } from '@mui/material';
|
|
15
15
|
import { forwardRef, useCallback, useMemo } from 'react';
|
|
16
16
|
import { useListPluginMetadata } from '../../runtime';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/PluginKindSelect/PluginKindSelect.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { MenuItem, TextField, TextFieldProps } from '@mui/material';\nimport { forwardRef, ReactElement, useCallback, useMemo } from 'react';\nimport { PluginType } from '../../model';\nimport { useListPluginMetadata } from '../../runtime';\nimport { PluginEditorSelection } from '../PluginEditor';\n\nexport interface PluginKindSelectProps extends Omit<TextFieldProps, 'value' | 'onChange' | 'children'> {\n filteredQueryPlugins?: string[];\n pluginTypes: PluginType[];\n value?: PluginEditorSelection;\n onChange?: (s: PluginEditorSelection) => void;\n}\n\n/**\n * Displays a MUI Select input for selecting a plugin's kind from a list of all the available plugins of some specific\n * plugin types. (e.g. \"Show a list of all the Panel plugins\", or \"Show a list of all the Variable plugins\", or \"Show\n * a list of all the TimeSeriesQuery, TraceQuery, ProfileQuery, and LogQuery plugins\").\n * The value of the select is the kind of the plugin, but you can also listen to the `onPluginTypeChange` event to know\n * when the user changes the plugin type (it fires at start for the default value.)\n */\nexport const PluginKindSelect = forwardRef((props: PluginKindSelectProps, ref): ReactElement => {\n const { pluginTypes, value: propValue, onChange, filteredQueryPlugins, ...others } = props;\n const { data, isLoading } = useListPluginMetadata(pluginTypes);\n\n const sortedData = useMemo(() => {\n if (filteredQueryPlugins?.length) {\n return data\n ?.filter((i) => filteredQueryPlugins.includes(i.spec.name))\n ?.sort((a, b) => a.spec.display.name.localeCompare(b.spec.display.name));\n }\n\n return data?.sort((a, b) => a.spec.display.name.localeCompare(b.spec.display.name));\n }, [data, filteredQueryPlugins]);\n\n // Pass an empty value while options are still loading so MUI doesn't complain about us using an \"out of range\" value\n const value = !propValue || isLoading ? '' : selectionToOptionValue(propValue);\n\n const handleChange = (event: { target: { value: string } }): void => {\n onChange?.(optionValueToSelection(event.target.value));\n };\n\n const renderValue = useCallback(\n (selected: unknown) => {\n if (selected === '') {\n return '';\n }\n const selectedValue = optionValueToSelection(selected as string);\n return sortedData?.find((v) => v.kind === selectedValue.type && v.spec.name === selectedValue.kind)?.spec.display\n .name;\n },\n [sortedData]\n );\n\n // TODO: Does this need a loading indicator of some kind?\n return (\n <TextField\n select\n inputRef={ref}\n {...others}\n value={value}\n aria-label={value}\n onChange={handleChange}\n SelectProps={{ renderValue }}\n data-testid=\"plugin-kind-select\"\n >\n {isLoading && <MenuItem value=\"\">Loading...</MenuItem>}\n {sortedData?.map((metadata) => (\n <MenuItem\n data-testid=\"option\"\n key={metadata.kind + metadata.spec.name}\n value={selectionToOptionValue({ type: metadata.kind, kind: metadata.spec.name })}\n >\n {metadata.spec.display.name}\n </MenuItem>\n ))}\n </TextField>\n );\n});\nPluginKindSelect.displayName = 'PluginKindSelect';\n\n// Delimiter used to stringify/parse option values\nconst OPTION_VALUE_DELIMITER = '_____';\n\n/**\n * Given a PluginEditorSelection,\n * returns a string value like `{type}_____{kind}` that can be used as a Select input value.\n * @param selector\n */\nfunction selectionToOptionValue(selector: PluginEditorSelection): string {\n return [selector.type, selector.kind].join(OPTION_VALUE_DELIMITER);\n}\n\n/**\n * Given an option value name like `{type}_____{kind}`,\n * returns a PluginEditorSelection to be used by the query data model.\n * @param optionValue\n */\nfunction optionValueToSelection(optionValue: string): PluginEditorSelection {\n const words = optionValue.split(OPTION_VALUE_DELIMITER);\n const type = words[0] as PluginType | undefined;\n const kind = words[1];\n if (type === undefined || kind === undefined) {\n throw new Error('Invalid optionValue string');\n }\n return {\n type,\n kind,\n };\n}\n"],"names":["MenuItem","TextField","forwardRef","useCallback","useMemo","useListPluginMetadata","PluginKindSelect","props","ref","pluginTypes","value","propValue","onChange","filteredQueryPlugins","others","data","isLoading","sortedData","length","filter","i","includes","spec","name","sort","a","b","display","localeCompare","selectionToOptionValue","handleChange","event","optionValueToSelection","target","renderValue","selected","selectedValue","find","v","kind","type","select","inputRef","aria-label","SelectProps","data-testid","map","metadata","displayName","OPTION_VALUE_DELIMITER","selector","join","optionValue","words","split","undefined","Error"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC
|
|
1
|
+
{"version":3,"sources":["../../../src/components/PluginKindSelect/PluginKindSelect.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { MenuItem, TextField, TextFieldProps } from '@mui/material';\nimport { forwardRef, ReactElement, useCallback, useMemo } from 'react';\nimport { PluginType } from '../../model';\nimport { useListPluginMetadata } from '../../runtime';\nimport { PluginEditorSelection } from '../PluginEditor';\n\nexport interface PluginKindSelectProps extends Omit<TextFieldProps, 'value' | 'onChange' | 'children'> {\n filteredQueryPlugins?: string[];\n pluginTypes: PluginType[];\n value?: PluginEditorSelection;\n onChange?: (s: PluginEditorSelection) => void;\n}\n\n/**\n * Displays a MUI Select input for selecting a plugin's kind from a list of all the available plugins of some specific\n * plugin types. (e.g. \"Show a list of all the Panel plugins\", or \"Show a list of all the Variable plugins\", or \"Show\n * a list of all the TimeSeriesQuery, TraceQuery, ProfileQuery, and LogQuery plugins\").\n * The value of the select is the kind of the plugin, but you can also listen to the `onPluginTypeChange` event to know\n * when the user changes the plugin type (it fires at start for the default value.)\n */\nexport const PluginKindSelect = forwardRef((props: PluginKindSelectProps, ref): ReactElement => {\n const { pluginTypes, value: propValue, onChange, filteredQueryPlugins, ...others } = props;\n const { data, isLoading } = useListPluginMetadata(pluginTypes);\n\n const sortedData = useMemo(() => {\n if (filteredQueryPlugins?.length) {\n return data\n ?.filter((i) => filteredQueryPlugins.includes(i.spec.name))\n ?.sort((a, b) => a.spec.display.name.localeCompare(b.spec.display.name));\n }\n\n return data?.sort((a, b) => a.spec.display.name.localeCompare(b.spec.display.name));\n }, [data, filteredQueryPlugins]);\n\n // Pass an empty value while options are still loading so MUI doesn't complain about us using an \"out of range\" value\n const value = !propValue || isLoading ? '' : selectionToOptionValue(propValue);\n\n const handleChange = (event: { target: { value: string } }): void => {\n onChange?.(optionValueToSelection(event.target.value));\n };\n\n const renderValue = useCallback(\n (selected: unknown) => {\n if (selected === '') {\n return '';\n }\n const selectedValue = optionValueToSelection(selected as string);\n return sortedData?.find((v) => v.kind === selectedValue.type && v.spec.name === selectedValue.kind)?.spec.display\n .name;\n },\n [sortedData]\n );\n\n // TODO: Does this need a loading indicator of some kind?\n return (\n <TextField\n select\n inputRef={ref}\n {...others}\n value={value}\n aria-label={value}\n onChange={handleChange}\n SelectProps={{ renderValue }}\n data-testid=\"plugin-kind-select\"\n >\n {isLoading && <MenuItem value=\"\">Loading...</MenuItem>}\n {sortedData?.map((metadata) => (\n <MenuItem\n data-testid=\"option\"\n key={metadata.kind + metadata.spec.name}\n value={selectionToOptionValue({ type: metadata.kind, kind: metadata.spec.name })}\n >\n {metadata.spec.display.name}\n </MenuItem>\n ))}\n </TextField>\n );\n});\nPluginKindSelect.displayName = 'PluginKindSelect';\n\n// Delimiter used to stringify/parse option values\nconst OPTION_VALUE_DELIMITER = '_____';\n\n/**\n * Given a PluginEditorSelection,\n * returns a string value like `{type}_____{kind}` that can be used as a Select input value.\n * @param selector\n */\nfunction selectionToOptionValue(selector: PluginEditorSelection): string {\n return [selector.type, selector.kind].join(OPTION_VALUE_DELIMITER);\n}\n\n/**\n * Given an option value name like `{type}_____{kind}`,\n * returns a PluginEditorSelection to be used by the query data model.\n * @param optionValue\n */\nfunction optionValueToSelection(optionValue: string): PluginEditorSelection {\n const words = optionValue.split(OPTION_VALUE_DELIMITER);\n const type = words[0] as PluginType | undefined;\n const kind = words[1];\n if (type === undefined || kind === undefined) {\n throw new Error('Invalid optionValue string');\n }\n return {\n type,\n kind,\n };\n}\n"],"names":["MenuItem","TextField","forwardRef","useCallback","useMemo","useListPluginMetadata","PluginKindSelect","props","ref","pluginTypes","value","propValue","onChange","filteredQueryPlugins","others","data","isLoading","sortedData","length","filter","i","includes","spec","name","sort","a","b","display","localeCompare","selectionToOptionValue","handleChange","event","optionValueToSelection","target","renderValue","selected","selectedValue","find","v","kind","type","select","inputRef","aria-label","SelectProps","data-testid","map","metadata","displayName","OPTION_VALUE_DELIMITER","selector","join","optionValue","words","split","undefined","Error"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginRegistry.d.ts","sourceRoot":"","sources":["../../../src/components/PluginRegistry/PluginRegistry.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAgC,SAAS,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC9E,OAAO,EAKL,YAAY,EACZ,kBAAkB,EACnB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"PluginRegistry.d.ts","sourceRoot":"","sources":["../../../src/components/PluginRegistry/PluginRegistry.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAgC,SAAS,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC9E,OAAO,EAKL,YAAY,EACZ,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAMrB,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,YAAY,CAAC;IAC3B,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,YAAY,CAgEvE"}
|
|
@@ -14,7 +14,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
14
14
|
import { useRef, useCallback, useMemo } from 'react';
|
|
15
15
|
import { PluginRegistryContext } from '../../runtime';
|
|
16
16
|
import { useEvent } from '../../utils';
|
|
17
|
-
import { usePluginIndexes
|
|
17
|
+
import { usePluginIndexes } from './plugin-indexes';
|
|
18
|
+
import { resolvePluginKeys } from './getPluginSearchHelper';
|
|
18
19
|
/**
|
|
19
20
|
* PluginRegistryContext provider that keeps track of all available plugins and provides an API for getting them or
|
|
20
21
|
* querying the metadata about them.
|
|
@@ -35,23 +36,18 @@ import { usePluginIndexes, getTypeAndKindKey } from './plugin-indexes';
|
|
|
35
36
|
}
|
|
36
37
|
return request;
|
|
37
38
|
});
|
|
38
|
-
const getPlugin = useCallback(async (
|
|
39
|
-
// Get the indexes of the installed plugins
|
|
39
|
+
const getPlugin = useCallback(async (compoundKeyObj)=>{
|
|
40
40
|
const pluginIndexes = await getPluginIndexes();
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
const { kind, name } = compoundKeyObj;
|
|
42
|
+
const candidateKeys = resolvePluginKeys(pluginIndexes.pluginResourcesByNameKindRegistryVersion.keys(), compoundKeyObj);
|
|
43
|
+
for (const resourceKey of candidateKeys){
|
|
44
|
+
const resource = pluginIndexes.pluginResourcesByNameKindRegistryVersion.get(resourceKey);
|
|
45
|
+
if (!resource) continue;
|
|
46
|
+
const pluginModule = await loadPluginModule(resource);
|
|
47
|
+
const plugin = pluginModule?.[resourceKey];
|
|
48
|
+
if (plugin) return plugin;
|
|
46
49
|
}
|
|
47
|
-
|
|
48
|
-
const pluginModule = await loadPluginModule(resource);
|
|
49
|
-
// We currently assume that plugin modules will have named exports that match the kinds they handle
|
|
50
|
-
const plugin = pluginModule[name];
|
|
51
|
-
if (plugin === undefined) {
|
|
52
|
-
throw new Error(`The ${name} plugin for kind '${kind}' is missing from the ${resource.metadata.name} plugin module`);
|
|
53
|
-
}
|
|
54
|
-
return plugin;
|
|
50
|
+
throw new Error(`A ${name} plugin for kind '${kind}' is not installed`);
|
|
55
51
|
}, [
|
|
56
52
|
getPluginIndexes,
|
|
57
53
|
loadPluginModule
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/PluginRegistry/PluginRegistry.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { UnknownSpec } from '@perses-dev/spec';\nimport { useRef, useCallback, useMemo, ReactNode, ReactElement } from 'react';\nimport {\n PluginModuleResource,\n PluginType,\n PluginImplementation,\n Plugin,\n PluginLoader,\n DefaultPluginKinds,\n} from '../../model';\nimport { PluginRegistryContext } from '../../runtime';\nimport { useEvent } from '../../utils';\nimport { usePluginIndexes,
|
|
1
|
+
{"version":3,"sources":["../../../src/components/PluginRegistry/PluginRegistry.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { UnknownSpec } from '@perses-dev/spec';\nimport { useRef, useCallback, useMemo, ReactNode, ReactElement } from 'react';\nimport {\n PluginModuleResource,\n PluginType,\n PluginImplementation,\n Plugin,\n PluginLoader,\n DefaultPluginKinds,\n} from '../../model';\nimport { PluginRegistryContext } from '../../runtime';\nimport { useEvent } from '../../utils';\nimport { usePluginIndexes, PluginCompoundKey } from './plugin-indexes';\nimport { resolvePluginKeys } from './getPluginSearchHelper';\n\nexport interface PluginRegistryProps {\n pluginLoader: PluginLoader;\n defaultPluginKinds?: DefaultPluginKinds;\n children?: ReactNode;\n}\n\n/**\n * PluginRegistryContext provider that keeps track of all available plugins and provides an API for getting them or\n * querying the metadata about them.\n */\nexport function PluginRegistry(props: PluginRegistryProps): ReactElement {\n const {\n pluginLoader: { getInstalledPlugins, importPluginModule },\n children,\n defaultPluginKinds,\n } = props;\n\n const getPluginIndexes = usePluginIndexes(getInstalledPlugins);\n\n // De-dupe calls to import plugin modules\n const importCache = useRef(new Map<PluginModuleResource, Promise<unknown>>());\n\n // Do useEvent here since this accesses the importPluginModule prop and we want a stable reference to it for the\n // callback below\n const loadPluginModule = useEvent((resource: PluginModuleResource) => {\n let request = importCache.current.get(resource);\n if (request === undefined) {\n request = importPluginModule(resource);\n importCache.current.set(resource, request);\n\n // Remove failed requests from the cache so they can potentially be retried\n request.catch(() => importCache.current.delete(resource));\n }\n return request;\n });\n\n const getPlugin = useCallback(\n async <T extends PluginType>(compoundKeyObj: PluginCompoundKey<T>): Promise<PluginImplementation<T>> => {\n const pluginIndexes = await getPluginIndexes();\n const { kind, name } = compoundKeyObj;\n\n const candidateKeys = resolvePluginKeys(\n pluginIndexes.pluginResourcesByNameKindRegistryVersion.keys(),\n compoundKeyObj\n );\n\n for (const resourceKey of candidateKeys) {\n const resource = pluginIndexes.pluginResourcesByNameKindRegistryVersion.get(resourceKey);\n if (!resource) continue;\n\n const pluginModule = (await loadPluginModule(resource)) as Record<string, Plugin<UnknownSpec>>;\n const plugin = pluginModule?.[resourceKey];\n if (plugin) return plugin as PluginImplementation<T>;\n }\n\n throw new Error(`A ${name} plugin for kind '${kind}' is not installed`);\n },\n [getPluginIndexes, loadPluginModule]\n );\n\n const listPluginMetadata = useCallback(\n async (pluginTypes: PluginType[]) => {\n const pluginIndexes = await getPluginIndexes();\n return pluginTypes.flatMap((type) => pluginIndexes.pluginMetadataByKind.get(type) ?? []);\n },\n [getPluginIndexes]\n );\n\n // Create the registry's context value and render\n const context = useMemo(\n () => ({ getPlugin, listPluginMetadata, defaultPluginKinds }),\n [getPlugin, listPluginMetadata, defaultPluginKinds]\n );\n return <PluginRegistryContext.Provider value={context}>{children}</PluginRegistryContext.Provider>;\n}\n"],"names":["useRef","useCallback","useMemo","PluginRegistryContext","useEvent","usePluginIndexes","resolvePluginKeys","PluginRegistry","props","pluginLoader","getInstalledPlugins","importPluginModule","children","defaultPluginKinds","getPluginIndexes","importCache","Map","loadPluginModule","resource","request","current","get","undefined","set","catch","delete","getPlugin","compoundKeyObj","pluginIndexes","kind","name","candidateKeys","pluginResourcesByNameKindRegistryVersion","keys","resourceKey","pluginModule","plugin","Error","listPluginMetadata","pluginTypes","flatMap","type","pluginMetadataByKind","context","Provider","value"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAGjC,SAASA,MAAM,EAAEC,WAAW,EAAEC,OAAO,QAAiC,QAAQ;AAS9E,SAASC,qBAAqB,QAAQ,gBAAgB;AACtD,SAASC,QAAQ,QAAQ,cAAc;AACvC,SAASC,gBAAgB,QAA2B,mBAAmB;AACvE,SAASC,iBAAiB,QAAQ,0BAA0B;AAQ5D;;;CAGC,GACD,OAAO,SAASC,eAAeC,KAA0B;IACvD,MAAM,EACJC,cAAc,EAAEC,mBAAmB,EAAEC,kBAAkB,EAAE,EACzDC,QAAQ,EACRC,kBAAkB,EACnB,GAAGL;IAEJ,MAAMM,mBAAmBT,iBAAiBK;IAE1C,yCAAyC;IACzC,MAAMK,cAAcf,OAAO,IAAIgB;IAE/B,gHAAgH;IAChH,iBAAiB;IACjB,MAAMC,mBAAmBb,SAAS,CAACc;QACjC,IAAIC,UAAUJ,YAAYK,OAAO,CAACC,GAAG,CAACH;QACtC,IAAIC,YAAYG,WAAW;YACzBH,UAAUR,mBAAmBO;YAC7BH,YAAYK,OAAO,CAACG,GAAG,CAACL,UAAUC;YAElC,2EAA2E;YAC3EA,QAAQK,KAAK,CAAC,IAAMT,YAAYK,OAAO,CAACK,MAAM,CAACP;QACjD;QACA,OAAOC;IACT;IAEA,MAAMO,YAAYzB,YAChB,OAA6B0B;QAC3B,MAAMC,gBAAgB,MAAMd;QAC5B,MAAM,EAAEe,IAAI,EAAEC,IAAI,EAAE,GAAGH;QAEvB,MAAMI,gBAAgBzB,kBACpBsB,cAAcI,wCAAwC,CAACC,IAAI,IAC3DN;QAGF,KAAK,MAAMO,eAAeH,cAAe;YACvC,MAAMb,WAAWU,cAAcI,wCAAwC,CAACX,GAAG,CAACa;YAC5E,IAAI,CAAChB,UAAU;YAEf,MAAMiB,eAAgB,MAAMlB,iBAAiBC;YAC7C,MAAMkB,SAASD,cAAc,CAACD,YAAY;YAC1C,IAAIE,QAAQ,OAAOA;QACrB;QAEA,MAAM,IAAIC,MAAM,CAAC,EAAE,EAAEP,KAAK,kBAAkB,EAAED,KAAK,kBAAkB,CAAC;IACxE,GACA;QAACf;QAAkBG;KAAiB;IAGtC,MAAMqB,qBAAqBrC,YACzB,OAAOsC;QACL,MAAMX,gBAAgB,MAAMd;QAC5B,OAAOyB,YAAYC,OAAO,CAAC,CAACC,OAASb,cAAcc,oBAAoB,CAACrB,GAAG,CAACoB,SAAS,EAAE;IACzF,GACA;QAAC3B;KAAiB;IAGpB,iDAAiD;IACjD,MAAM6B,UAAUzC,QACd,IAAO,CAAA;YAAEwB;YAAWY;YAAoBzB;QAAmB,CAAA,GAC3D;QAACa;QAAWY;QAAoBzB;KAAmB;IAErD,qBAAO,KAACV,sBAAsByC,QAAQ;QAACC,OAAOF;kBAAU/B;;AAC1D"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { PluginType } from '../../model';
|
|
2
|
+
import { PluginCompoundKey } from './plugin-indexes';
|
|
3
|
+
export interface PluginLookupPrecedenceLogic {
|
|
4
|
+
registryOverVersion: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Returns an ordered list of candidate 4-part keys to try when resolving a plugin.
|
|
8
|
+
* If version/registry are specified, the exact-match key comes first.
|
|
9
|
+
* The best fallback key (highest version, tie-broken by precedence policy) follows.
|
|
10
|
+
*/
|
|
11
|
+
export declare const resolvePluginKeys: <T extends PluginType>(allKeys: Iterable<string>, query: PluginCompoundKey<T>, precedenceLogic?: PluginLookupPrecedenceLogic) => string[];
|
|
12
|
+
//# sourceMappingURL=getPluginSearchHelper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getPluginSearchHelper.d.ts","sourceRoot":"","sources":["../../../src/components/PluginRegistry/getPluginSearchHelper.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,UAAU,EAA8B,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAIrD,MAAM,WAAW,2BAA2B;IAC1C,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAID;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,kCACnB,SAAS,MAAM,CAAC,SAClB,kBAAkB,CAAC,CAAC,oBACV,2BAA2B,KAC3C,MAAM,EAkER,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Copyright The Perses Authors
|
|
2
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
// you may not use this file except in compliance with the License.
|
|
4
|
+
// You may obtain a copy of the License at
|
|
5
|
+
//
|
|
6
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
//
|
|
8
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
// See the License for the specific language governing permissions and
|
|
12
|
+
// limitations under the License.
|
|
13
|
+
import { gt } from 'semver';
|
|
14
|
+
import { getPluginModuleCompoundKey } from '../../model';
|
|
15
|
+
const PLUGIN_LOOKUP_PRECEDENCE_LOGIC = {
|
|
16
|
+
registryOverVersion: false
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Returns an ordered list of candidate 4-part keys to try when resolving a plugin.
|
|
20
|
+
* If version/registry are specified, the exact-match key comes first.
|
|
21
|
+
* The best fallback key (highest version, tie-broken by precedence policy) follows.
|
|
22
|
+
*/ export const resolvePluginKeys = (allKeys, query, precedenceLogic = PLUGIN_LOOKUP_PRECEDENCE_LOGIC)=>{
|
|
23
|
+
const { kind, name, version, registry } = query;
|
|
24
|
+
const candidates = [];
|
|
25
|
+
// Exact match first when version or registry is specified
|
|
26
|
+
if (version || registry) {
|
|
27
|
+
candidates.push(getPluginModuleCompoundKey({
|
|
28
|
+
kind,
|
|
29
|
+
name,
|
|
30
|
+
registry,
|
|
31
|
+
version
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
const latestWithRegistry = {
|
|
35
|
+
key: '',
|
|
36
|
+
version: ''
|
|
37
|
+
};
|
|
38
|
+
const latestWithoutRegistry = {
|
|
39
|
+
key: '',
|
|
40
|
+
version: ''
|
|
41
|
+
};
|
|
42
|
+
const prefix = `${kind}:${name}:`;
|
|
43
|
+
for (const key of allKeys){
|
|
44
|
+
if (!key.startsWith(prefix)) continue;
|
|
45
|
+
const split = key.split(':');
|
|
46
|
+
if (split.length !== 4) {
|
|
47
|
+
console.warn(`An invalid Plugin Resource key detected during default plugin lookup: ${key}`);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const [, , reg, ver] = split;
|
|
51
|
+
if (!ver) {
|
|
52
|
+
console.warn(`An invalid Plugin Resource key detected during default plugin lookup: ${key}`);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (reg) {
|
|
56
|
+
if (!latestWithRegistry.key || gt(ver, latestWithRegistry.version)) {
|
|
57
|
+
latestWithRegistry.key = key;
|
|
58
|
+
latestWithRegistry.version = ver;
|
|
59
|
+
}
|
|
60
|
+
} else {
|
|
61
|
+
if (!latestWithoutRegistry.key || gt(ver, latestWithoutRegistry.version)) {
|
|
62
|
+
latestWithoutRegistry.key = key;
|
|
63
|
+
latestWithoutRegistry.version = ver;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Determine the best fallback key from the two buckets
|
|
68
|
+
let fallbackKey;
|
|
69
|
+
if (latestWithRegistry.key && latestWithoutRegistry.key) {
|
|
70
|
+
const { registryOverVersion } = precedenceLogic;
|
|
71
|
+
if (gt(latestWithRegistry.version, latestWithoutRegistry.version)) {
|
|
72
|
+
fallbackKey = latestWithRegistry.key;
|
|
73
|
+
} else if (gt(latestWithoutRegistry.version, latestWithRegistry.version)) {
|
|
74
|
+
fallbackKey = latestWithoutRegistry.key;
|
|
75
|
+
} else {
|
|
76
|
+
// Versions are equal — use the tie-breaker
|
|
77
|
+
fallbackKey = registryOverVersion ? latestWithRegistry.key : latestWithoutRegistry.key;
|
|
78
|
+
}
|
|
79
|
+
} else {
|
|
80
|
+
fallbackKey = latestWithRegistry.key || latestWithoutRegistry.key || undefined;
|
|
81
|
+
}
|
|
82
|
+
if (fallbackKey && !candidates.includes(fallbackKey)) {
|
|
83
|
+
candidates.push(fallbackKey);
|
|
84
|
+
}
|
|
85
|
+
return candidates;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
//# sourceMappingURL=getPluginSearchHelper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/PluginRegistry/getPluginSearchHelper.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { gt } from 'semver';\nimport { PluginType, getPluginModuleCompoundKey } from '../../model';\nimport { PluginCompoundKey } from './plugin-indexes';\n\n// When both a registry and non-registry variant exist at the same version,\n// `registryOverVersion: true` prefers the registry variant.\nexport interface PluginLookupPrecedenceLogic {\n registryOverVersion: boolean;\n}\n\nconst PLUGIN_LOOKUP_PRECEDENCE_LOGIC: PluginLookupPrecedenceLogic = { registryOverVersion: false };\n\n/**\n * Returns an ordered list of candidate 4-part keys to try when resolving a plugin.\n * If version/registry are specified, the exact-match key comes first.\n * The best fallback key (highest version, tie-broken by precedence policy) follows.\n */\nexport const resolvePluginKeys = <T extends PluginType>(\n allKeys: Iterable<string>,\n query: PluginCompoundKey<T>,\n precedenceLogic: PluginLookupPrecedenceLogic = PLUGIN_LOOKUP_PRECEDENCE_LOGIC\n): string[] => {\n const { kind, name, version, registry } = query;\n const candidates: string[] = [];\n\n // Exact match first when version or registry is specified\n if (version || registry) {\n candidates.push(getPluginModuleCompoundKey({ kind, name, registry, version }));\n }\n\n // Find the best fallback by scanning all matching keys\n type PluginBucket = { key: string; version: string };\n const latestWithRegistry: PluginBucket = { key: '', version: '' };\n const latestWithoutRegistry: PluginBucket = { key: '', version: '' };\n\n const prefix = `${kind}:${name}:`;\n for (const key of allKeys) {\n if (!key.startsWith(prefix)) continue;\n const split = key.split(':');\n\n if (split.length !== 4) {\n console.warn(`An invalid Plugin Resource key detected during default plugin lookup: ${key}`);\n continue;\n }\n\n const [, , reg, ver] = split;\n if (!ver) {\n console.warn(`An invalid Plugin Resource key detected during default plugin lookup: ${key}`);\n continue;\n }\n\n if (reg) {\n if (!latestWithRegistry.key || gt(ver, latestWithRegistry.version)) {\n latestWithRegistry.key = key;\n latestWithRegistry.version = ver;\n }\n } else {\n if (!latestWithoutRegistry.key || gt(ver, latestWithoutRegistry.version)) {\n latestWithoutRegistry.key = key;\n latestWithoutRegistry.version = ver;\n }\n }\n }\n\n // Determine the best fallback key from the two buckets\n let fallbackKey: string | undefined;\n\n if (latestWithRegistry.key && latestWithoutRegistry.key) {\n const { registryOverVersion } = precedenceLogic;\n\n if (gt(latestWithRegistry.version, latestWithoutRegistry.version)) {\n fallbackKey = latestWithRegistry.key;\n } else if (gt(latestWithoutRegistry.version, latestWithRegistry.version)) {\n fallbackKey = latestWithoutRegistry.key;\n } else {\n // Versions are equal — use the tie-breaker\n fallbackKey = registryOverVersion ? latestWithRegistry.key : latestWithoutRegistry.key;\n }\n } else {\n fallbackKey = latestWithRegistry.key || latestWithoutRegistry.key || undefined;\n }\n\n if (fallbackKey && !candidates.includes(fallbackKey)) {\n candidates.push(fallbackKey);\n }\n\n return candidates;\n};\n"],"names":["gt","getPluginModuleCompoundKey","PLUGIN_LOOKUP_PRECEDENCE_LOGIC","registryOverVersion","resolvePluginKeys","allKeys","query","precedenceLogic","kind","name","version","registry","candidates","push","latestWithRegistry","key","latestWithoutRegistry","prefix","startsWith","split","length","console","warn","reg","ver","fallbackKey","undefined","includes"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,EAAE,QAAQ,SAAS;AAC5B,SAAqBC,0BAA0B,QAAQ,cAAc;AASrE,MAAMC,iCAA8D;IAAEC,qBAAqB;AAAM;AAEjG;;;;CAIC,GACD,OAAO,MAAMC,oBAAoB,CAC/BC,SACAC,OACAC,kBAA+CL,8BAA8B;IAE7E,MAAM,EAAEM,IAAI,EAAEC,IAAI,EAAEC,OAAO,EAAEC,QAAQ,EAAE,GAAGL;IAC1C,MAAMM,aAAuB,EAAE;IAE/B,0DAA0D;IAC1D,IAAIF,WAAWC,UAAU;QACvBC,WAAWC,IAAI,CAACZ,2BAA2B;YAAEO;YAAMC;YAAME;YAAUD;QAAQ;IAC7E;IAIA,MAAMI,qBAAmC;QAAEC,KAAK;QAAIL,SAAS;IAAG;IAChE,MAAMM,wBAAsC;QAAED,KAAK;QAAIL,SAAS;IAAG;IAEnE,MAAMO,SAAS,GAAGT,KAAK,CAAC,EAAEC,KAAK,CAAC,CAAC;IACjC,KAAK,MAAMM,OAAOV,QAAS;QACzB,IAAI,CAACU,IAAIG,UAAU,CAACD,SAAS;QAC7B,MAAME,QAAQJ,IAAII,KAAK,CAAC;QAExB,IAAIA,MAAMC,MAAM,KAAK,GAAG;YACtBC,QAAQC,IAAI,CAAC,CAAC,sEAAsE,EAAEP,KAAK;YAC3F;QACF;QAEA,MAAM,KAAKQ,KAAKC,IAAI,GAAGL;QACvB,IAAI,CAACK,KAAK;YACRH,QAAQC,IAAI,CAAC,CAAC,sEAAsE,EAAEP,KAAK;YAC3F;QACF;QAEA,IAAIQ,KAAK;YACP,IAAI,CAACT,mBAAmBC,GAAG,IAAIf,GAAGwB,KAAKV,mBAAmBJ,OAAO,GAAG;gBAClEI,mBAAmBC,GAAG,GAAGA;gBACzBD,mBAAmBJ,OAAO,GAAGc;YAC/B;QACF,OAAO;YACL,IAAI,CAACR,sBAAsBD,GAAG,IAAIf,GAAGwB,KAAKR,sBAAsBN,OAAO,GAAG;gBACxEM,sBAAsBD,GAAG,GAAGA;gBAC5BC,sBAAsBN,OAAO,GAAGc;YAClC;QACF;IACF;IAEA,uDAAuD;IACvD,IAAIC;IAEJ,IAAIX,mBAAmBC,GAAG,IAAIC,sBAAsBD,GAAG,EAAE;QACvD,MAAM,EAAEZ,mBAAmB,EAAE,GAAGI;QAEhC,IAAIP,GAAGc,mBAAmBJ,OAAO,EAAEM,sBAAsBN,OAAO,GAAG;YACjEe,cAAcX,mBAAmBC,GAAG;QACtC,OAAO,IAAIf,GAAGgB,sBAAsBN,OAAO,EAAEI,mBAAmBJ,OAAO,GAAG;YACxEe,cAAcT,sBAAsBD,GAAG;QACzC,OAAO;YACL,2CAA2C;YAC3CU,cAActB,sBAAsBW,mBAAmBC,GAAG,GAAGC,sBAAsBD,GAAG;QACxF;IACF,OAAO;QACLU,cAAcX,mBAAmBC,GAAG,IAAIC,sBAAsBD,GAAG,IAAIW;IACvE;IAEA,IAAID,eAAe,CAACb,WAAWe,QAAQ,CAACF,cAAc;QACpDb,WAAWC,IAAI,CAACY;IAClB;IAEA,OAAOb;AACT,EAAE"}
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import { PluginLoader, PluginMetadataWithModule, PluginModuleResource, PluginType } from '../../model';
|
|
1
|
+
import { PluginLoader, PluginMetadataWithModule, PluginModuleResource, PluginType, PluginCompoundKey, getPluginModuleCompoundKey } from '../../model';
|
|
2
|
+
export type { PluginCompoundKey };
|
|
3
|
+
export { getPluginModuleCompoundKey };
|
|
2
4
|
export interface PluginIndexes {
|
|
3
|
-
|
|
5
|
+
pluginResourcesByNameKindRegistryVersion: Map<string, PluginModuleResource>;
|
|
4
6
|
pluginMetadataByKind: Map<PluginType, PluginMetadataWithModule[]>;
|
|
5
7
|
}
|
|
6
8
|
/**
|
|
7
9
|
* Returns an async callback for getting indexes of the installed plugin data.
|
|
8
10
|
*/
|
|
9
11
|
export declare function usePluginIndexes(getInstalledPlugins: PluginLoader['getInstalledPlugins']): () => Promise<PluginIndexes>;
|
|
10
|
-
/**
|
|
11
|
-
* Gets a unique key for a plugin type/kind that can be used as a cache key.
|
|
12
|
-
*/
|
|
13
|
-
export declare function getTypeAndKindKey(kind: PluginType, name: string): string;
|
|
14
12
|
//# sourceMappingURL=plugin-indexes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-indexes.d.ts","sourceRoot":"","sources":["../../../src/components/PluginRegistry/plugin-indexes.ts"],"names":[],"mappings":"AAcA,OAAO,
|
|
1
|
+
{"version":3,"file":"plugin-indexes.d.ts","sourceRoot":"","sources":["../../../src/components/PluginRegistry/plugin-indexes.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,YAAY,EACZ,wBAAwB,EACxB,oBAAoB,EACpB,UAAU,EACV,iBAAiB,EACjB,0BAA0B,EAC3B,MAAM,aAAa,CAAC;AAGrB,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAClC,OAAO,EAAE,0BAA0B,EAAE,CAAC;AAEtC,MAAM,WAAW,aAAa;IAE5B,wCAAwC,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAE5E,oBAAoB,EAAE,GAAG,CAAC,UAAU,EAAE,wBAAwB,EAAE,CAAC,CAAC;CACnE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,mBAAmB,EAAE,YAAY,CAAC,qBAAqB,CAAC,GACvD,MAAM,OAAO,CAAC,aAAa,CAAC,CA2D9B"}
|
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
import { useCallback, useRef } from 'react';
|
|
14
|
+
import { getPluginModuleCompoundKey } from '../../model';
|
|
14
15
|
import { useEvent } from '../../utils';
|
|
16
|
+
export { getPluginModuleCompoundKey };
|
|
15
17
|
/**
|
|
16
18
|
* Returns an async callback for getting indexes of the installed plugin data.
|
|
17
19
|
*/ export function usePluginIndexes(getInstalledPlugins) {
|
|
@@ -20,17 +22,22 @@ import { useEvent } from '../../utils';
|
|
|
20
22
|
const createPluginIndexes = useEvent(async ()=>{
|
|
21
23
|
const installedPlugins = await getInstalledPlugins();
|
|
22
24
|
// Create the two indexes from the installed plugins
|
|
23
|
-
const
|
|
25
|
+
const pluginResourcesByNameKindRegistryVersion = new Map();
|
|
24
26
|
const pluginMetadataByKind = new Map();
|
|
25
27
|
for (const resource of installedPlugins){
|
|
28
|
+
const { metadata: { version, registry } } = resource;
|
|
26
29
|
for (const pluginMetadata of resource.spec.plugins){
|
|
27
30
|
const { kind, spec: { name } } = pluginMetadata;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
const key = getPluginModuleCompoundKey({
|
|
32
|
+
kind,
|
|
33
|
+
name,
|
|
34
|
+
registry,
|
|
35
|
+
version
|
|
36
|
+
});
|
|
37
|
+
if (pluginResourcesByNameKindRegistryVersion.has(key)) {
|
|
38
|
+
console.warn(`Got more than one ${kind} plugin for kind ${name}, registry '${registry || 'undefined'}', and version '${version || 'undefined'}'`);
|
|
32
39
|
}
|
|
33
|
-
|
|
40
|
+
pluginResourcesByNameKindRegistryVersion.set(key, resource);
|
|
34
41
|
// Index the metadata by plugin type
|
|
35
42
|
let list = pluginMetadataByKind.get(kind);
|
|
36
43
|
if (list === undefined) {
|
|
@@ -44,7 +51,7 @@ import { useEvent } from '../../utils';
|
|
|
44
51
|
}
|
|
45
52
|
}
|
|
46
53
|
return {
|
|
47
|
-
|
|
54
|
+
pluginResourcesByNameKindRegistryVersion,
|
|
48
55
|
pluginMetadataByKind
|
|
49
56
|
};
|
|
50
57
|
});
|
|
@@ -56,7 +63,7 @@ import { useEvent } from '../../utils';
|
|
|
56
63
|
request = createPluginIndexes();
|
|
57
64
|
pluginIndexesCache.current = request;
|
|
58
65
|
// Remove failed requests from the cache so they can potentially be retried
|
|
59
|
-
request.catch(()=>pluginIndexesCache.current
|
|
66
|
+
request.catch(()=>pluginIndexesCache.current = undefined);
|
|
60
67
|
}
|
|
61
68
|
return request;
|
|
62
69
|
}, [
|
|
@@ -64,10 +71,5 @@ import { useEvent } from '../../utils';
|
|
|
64
71
|
]);
|
|
65
72
|
return getPluginIndexes;
|
|
66
73
|
}
|
|
67
|
-
/**
|
|
68
|
-
* Gets a unique key for a plugin type/kind that can be used as a cache key.
|
|
69
|
-
*/ export function getTypeAndKindKey(kind, name) {
|
|
70
|
-
return `${kind}:${name}`;
|
|
71
|
-
}
|
|
72
74
|
|
|
73
75
|
//# sourceMappingURL=plugin-indexes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/PluginRegistry/plugin-indexes.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { useCallback, useRef } from 'react';\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/components/PluginRegistry/plugin-indexes.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { useCallback, useRef } from 'react';\nimport {\n PluginLoader,\n PluginMetadataWithModule,\n PluginModuleResource,\n PluginType,\n PluginCompoundKey,\n getPluginModuleCompoundKey,\n} from '../../model';\nimport { useEvent } from '../../utils';\n\nexport type { PluginCompoundKey };\nexport { getPluginModuleCompoundKey };\n\nexport interface PluginIndexes {\n // Plugin resources by plugin type, kind, registry, and version\n pluginResourcesByNameKindRegistryVersion: Map<string, PluginModuleResource>;\n // Plugin metadata by plugin type\n pluginMetadataByKind: Map<PluginType, PluginMetadataWithModule[]>;\n}\n\n/**\n * Returns an async callback for getting indexes of the installed plugin data.\n */\nexport function usePluginIndexes(\n getInstalledPlugins: PluginLoader['getInstalledPlugins']\n): () => Promise<PluginIndexes> {\n // Creates indexes from the installed plugins data (does useEvent because this accesses the getInstalledPlugins prop\n // and we want a stable reference for the callback below)\n const createPluginIndexes = useEvent(async (): Promise<PluginIndexes> => {\n const installedPlugins = await getInstalledPlugins();\n\n // Create the two indexes from the installed plugins\n const pluginResourcesByNameKindRegistryVersion = new Map<string, PluginModuleResource>();\n const pluginMetadataByKind = new Map<PluginType, PluginMetadataWithModule[]>();\n\n for (const resource of installedPlugins) {\n const {\n metadata: { version, registry },\n } = resource;\n for (const pluginMetadata of resource.spec.plugins) {\n const {\n kind,\n spec: { name },\n } = pluginMetadata;\n\n const key = getPluginModuleCompoundKey({ kind, name, registry, version });\n if (pluginResourcesByNameKindRegistryVersion.has(key)) {\n console.warn(\n `Got more than one ${kind} plugin for kind ${name}, registry '${registry || 'undefined'}', and version '${version || 'undefined'}'`\n );\n }\n pluginResourcesByNameKindRegistryVersion.set(key, resource);\n\n // Index the metadata by plugin type\n let list = pluginMetadataByKind.get(kind);\n if (list === undefined) {\n list = [];\n pluginMetadataByKind.set(kind, list);\n }\n list.push({ ...pluginMetadata, module: resource.metadata });\n }\n }\n\n return {\n pluginResourcesByNameKindRegistryVersion,\n pluginMetadataByKind,\n };\n });\n\n // De-dupe creating plugin indexes (i.e. requests to get installed plugins)\n const pluginIndexesCache = useRef<Promise<PluginIndexes> | undefined>(undefined);\n const getPluginIndexes = useCallback(() => {\n let request = pluginIndexesCache.current;\n if (request === undefined) {\n request = createPluginIndexes();\n pluginIndexesCache.current = request;\n\n // Remove failed requests from the cache so they can potentially be retried\n request.catch(() => (pluginIndexesCache.current = undefined));\n }\n return request;\n }, [createPluginIndexes]);\n\n return getPluginIndexes;\n}\n"],"names":["useCallback","useRef","getPluginModuleCompoundKey","useEvent","usePluginIndexes","getInstalledPlugins","createPluginIndexes","installedPlugins","pluginResourcesByNameKindRegistryVersion","Map","pluginMetadataByKind","resource","metadata","version","registry","pluginMetadata","spec","plugins","kind","name","key","has","console","warn","set","list","get","undefined","push","module","pluginIndexesCache","getPluginIndexes","request","current","catch"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,WAAW,EAAEC,MAAM,QAAQ,QAAQ;AAC5C,SAMEC,0BAA0B,QACrB,cAAc;AACrB,SAASC,QAAQ,QAAQ,cAAc;AAGvC,SAASD,0BAA0B,GAAG;AAStC;;CAEC,GACD,OAAO,SAASE,iBACdC,mBAAwD;IAExD,oHAAoH;IACpH,yDAAyD;IACzD,MAAMC,sBAAsBH,SAAS;QACnC,MAAMI,mBAAmB,MAAMF;QAE/B,oDAAoD;QACpD,MAAMG,2CAA2C,IAAIC;QACrD,MAAMC,uBAAuB,IAAID;QAEjC,KAAK,MAAME,YAAYJ,iBAAkB;YACvC,MAAM,EACJK,UAAU,EAAEC,OAAO,EAAEC,QAAQ,EAAE,EAChC,GAAGH;YACJ,KAAK,MAAMI,kBAAkBJ,SAASK,IAAI,CAACC,OAAO,CAAE;gBAClD,MAAM,EACJC,IAAI,EACJF,MAAM,EAAEG,IAAI,EAAE,EACf,GAAGJ;gBAEJ,MAAMK,MAAMlB,2BAA2B;oBAAEgB;oBAAMC;oBAAML;oBAAUD;gBAAQ;gBACvE,IAAIL,yCAAyCa,GAAG,CAACD,MAAM;oBACrDE,QAAQC,IAAI,CACV,CAAC,kBAAkB,EAAEL,KAAK,iBAAiB,EAAEC,KAAK,YAAY,EAAEL,YAAY,YAAY,gBAAgB,EAAED,WAAW,YAAY,CAAC,CAAC;gBAEvI;gBACAL,yCAAyCgB,GAAG,CAACJ,KAAKT;gBAElD,oCAAoC;gBACpC,IAAIc,OAAOf,qBAAqBgB,GAAG,CAACR;gBACpC,IAAIO,SAASE,WAAW;oBACtBF,OAAO,EAAE;oBACTf,qBAAqBc,GAAG,CAACN,MAAMO;gBACjC;gBACAA,KAAKG,IAAI,CAAC;oBAAE,GAAGb,cAAc;oBAAEc,QAAQlB,SAASC,QAAQ;gBAAC;YAC3D;QACF;QAEA,OAAO;YACLJ;YACAE;QACF;IACF;IAEA,2EAA2E;IAC3E,MAAMoB,qBAAqB7B,OAA2C0B;IACtE,MAAMI,mBAAmB/B,YAAY;QACnC,IAAIgC,UAAUF,mBAAmBG,OAAO;QACxC,IAAID,YAAYL,WAAW;YACzBK,UAAU1B;YACVwB,mBAAmBG,OAAO,GAAGD;YAE7B,2EAA2E;YAC3EA,QAAQE,KAAK,CAAC,IAAOJ,mBAAmBG,OAAO,GAAGN;QACpD;QACA,OAAOK;IACT,GAAG;QAAC1B;KAAoB;IAExB,OAAOyB;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginSpecEditor.d.ts","sourceRoot":"","sources":["../../../src/components/PluginSpecEditor/PluginSpecEditor.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAErC,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,WAAW,qBAAsB,SAAQ,kBAAkB,CAAC,WAAW,CAAC;IAC5E,eAAe,EAAE,qBAAqB,CAAC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,YAAY,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"PluginSpecEditor.d.ts","sourceRoot":"","sources":["../../../src/components/PluginSpecEditor/PluginSpecEditor.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAErC,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,WAAW,qBAAsB,SAAQ,kBAAkB,CAAC,WAAW,CAAC;IAC5E,eAAe,EAAE,qBAAqB,CAAC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,YAAY,GAAG,IAAI,CA4BlF"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
2
|
// Copyright The Perses Authors
|
|
2
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -10,7 +11,6 @@
|
|
|
10
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
12
|
// See the License for the specific language governing permissions and
|
|
12
13
|
// limitations under the License.
|
|
13
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
14
|
import { ErrorAlert } from '@perses-dev/components';
|
|
15
15
|
import { CircularProgress, Stack } from '@mui/material';
|
|
16
16
|
import { usePlugin } from '../../runtime';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/PluginSpecEditor/PluginSpecEditor.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ErrorAlert } from '@perses-dev/components';\nimport { UnknownSpec } from '@perses-dev/spec';\nimport { ReactElement } from 'react';\nimport { CircularProgress, Stack } from '@mui/material';\nimport { OptionsEditorProps } from '../../model';\nimport { usePlugin } from '../../runtime';\nimport { PluginEditorSelection } from '../PluginEditor';\n\nexport interface PluginSpecEditorProps extends OptionsEditorProps<UnknownSpec> {\n pluginSelection: PluginEditorSelection;\n isEditor?: boolean;\n}\n\nexport function PluginSpecEditor(props: PluginSpecEditorProps): ReactElement | null {\n const {\n pluginSelection: { type: pluginType, kind: pluginKind },\n ...others\n } = props;\n const { data: plugin, isLoading, error } = usePlugin(pluginType, pluginKind);\n
|
|
1
|
+
{"version":3,"sources":["../../../src/components/PluginSpecEditor/PluginSpecEditor.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ErrorAlert } from '@perses-dev/components';\nimport { UnknownSpec } from '@perses-dev/spec';\nimport { ReactElement } from 'react';\nimport { CircularProgress, Stack } from '@mui/material';\nimport { OptionsEditorProps } from '../../model';\nimport { usePlugin } from '../../runtime';\nimport { PluginEditorSelection } from '../PluginEditor';\n\nexport interface PluginSpecEditorProps extends OptionsEditorProps<UnknownSpec> {\n pluginSelection: PluginEditorSelection;\n isEditor?: boolean;\n}\n\nexport function PluginSpecEditor(props: PluginSpecEditorProps): ReactElement | null {\n const {\n pluginSelection: { type: pluginType, kind: pluginKind },\n ...others\n } = props;\n const { data: plugin, isLoading, error } = usePlugin(pluginType, pluginKind);\n if (error) {\n return <ErrorAlert error={error} />;\n }\n\n if (isLoading) {\n return (\n <Stack width=\"100%\" sx={{ alignItems: 'center', justifyContent: 'center' }}>\n <CircularProgress />\n </Stack>\n );\n }\n\n if (!plugin) {\n throw new Error(`Missing implementation for ${pluginType} plugin with kind '${pluginKind}'`);\n }\n\n if (pluginType === 'Panel') {\n throw new Error('This editor should not be used for panel type. Please use Panel Spec Editor instead.');\n }\n const { OptionsEditorComponent } = plugin;\n\n return OptionsEditorComponent ? <OptionsEditorComponent {...others} /> : null;\n}\n"],"names":["ErrorAlert","CircularProgress","Stack","usePlugin","PluginSpecEditor","props","pluginSelection","type","pluginType","kind","pluginKind","others","data","plugin","isLoading","error","width","sx","alignItems","justifyContent","Error","OptionsEditorComponent"],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,UAAU,QAAQ,yBAAyB;AAGpD,SAASC,gBAAgB,EAAEC,KAAK,QAAQ,gBAAgB;AAExD,SAASC,SAAS,QAAQ,gBAAgB;AAQ1C,OAAO,SAASC,iBAAiBC,KAA4B;IAC3D,MAAM,EACJC,iBAAiB,EAAEC,MAAMC,UAAU,EAAEC,MAAMC,UAAU,EAAE,EACvD,GAAGC,QACJ,GAAGN;IACJ,MAAM,EAAEO,MAAMC,MAAM,EAAEC,SAAS,EAAEC,KAAK,EAAE,GAAGZ,UAAUK,YAAYE;IACjE,IAAIK,OAAO;QACT,qBAAO,KAACf;YAAWe,OAAOA;;IAC5B;IAEA,IAAID,WAAW;QACb,qBACE,KAACZ;YAAMc,OAAM;YAAOC,IAAI;gBAAEC,YAAY;gBAAUC,gBAAgB;YAAS;sBACvE,cAAA,KAAClB;;IAGP;IAEA,IAAI,CAACY,QAAQ;QACX,MAAM,IAAIO,MAAM,CAAC,2BAA2B,EAAEZ,WAAW,mBAAmB,EAAEE,WAAW,CAAC,CAAC;IAC7F;IAEA,IAAIF,eAAe,SAAS;QAC1B,MAAM,IAAIY,MAAM;IAClB;IACA,MAAM,EAAEC,sBAAsB,EAAE,GAAGR;IAEnC,OAAOQ,uCAAyB,KAACA;QAAwB,GAAGV,MAAM;SAAO;AAC3E"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
2
|
// Copyright The Perses Authors
|
|
2
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -10,7 +11,6 @@
|
|
|
10
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
12
|
// See the License for the specific language governing permissions and
|
|
12
13
|
// limitations under the License.
|
|
13
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
14
|
import { Switch } from '@mui/material';
|
|
15
15
|
import { OptionsEditorControl, OptionsEditorGroup } from '@perses-dev/components';
|
|
16
16
|
export function SelectionOptionsEditor({ value, onChange }) {
|