[visualizations] read only config flag for vis_types (#158507)

Part of https://github.com/elastic/kibana/issues/154307

### Overview
PR adds `readOnly` configuration to all vis_type plugins.

### Test
* Start kibana with `yarn start --serverless=es`
* set the following yaml configuration values
    ```
    vis_type_gauge.readOnly: true
    vis_type_heatmap.readOnly: true
    vis_type_metric.readOnly: true
    vis_type_pie.readOnly: true
    vis_type_table.readOnly: true
    vis_type_tagcloud.readOnly: true
    vis_type_timelion.readOnly: true
    vis_type_timeseries.readOnly: true
    vis_type_vislib.readOnly: true
    vis_type_xy.readOnly: true
    ```

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Stratoula Kalafateli <efstratia.kalafateli@elastic.co>
This commit is contained in:
Nathan Reese 2023-05-30 12:45:31 -06:00 committed by GitHub
parent b52988757f
commit 21151dd39f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
48 changed files with 517 additions and 127 deletions

View file

@ -218,29 +218,33 @@ export const EditorMenu = ({ createNewVisType, createNewEmbeddable }: Props) =>
});
const getEditorMenuPanels = (closePopover: () => void) => {
const initialPanelItems = [
...visTypeAliases.map(getVisTypeAliasMenuItem),
...Object.values(factoryGroupMap).map(({ id, appName, icon, panelId }) => ({
name: appName,
icon,
panel: panelId,
'data-test-subj': `dashboardEditorMenu-${id}Group`,
})),
...ungroupedFactories.map((factory) => {
return getEmbeddableFactoryMenuItem(factory, closePopover);
}),
...promotedVisTypes.map(getVisTypeMenuItem),
];
if (aggsBasedVisTypes.length > 0) {
initialPanelItems.push({
name: aggsPanelTitle,
icon: 'visualizeApp',
panel: aggBasedPanelID,
'data-test-subj': `dashboardEditorAggBasedMenuItem`,
});
}
initialPanelItems.push(...toolVisTypes.map(getVisTypeMenuItem));
return [
{
id: 0,
items: [
...visTypeAliases.map(getVisTypeAliasMenuItem),
...Object.values(factoryGroupMap).map(({ id, appName, icon, panelId }) => ({
name: appName,
icon,
panel: panelId,
'data-test-subj': `dashboardEditorMenu-${id}Group`,
})),
...ungroupedFactories.map((factory) => {
return getEmbeddableFactoryMenuItem(factory, closePopover);
}),
...promotedVisTypes.map(getVisTypeMenuItem),
{
name: aggsPanelTitle,
icon: 'visualizeApp',
panel: aggBasedPanelID,
'data-test-subj': `dashboardEditorAggBasedMenuItem`,
},
...toolVisTypes.map(getVisTypeMenuItem),
],
items: initialPanelItems,
},
{
id: aggBasedPanelID,

View file

@ -10,6 +10,17 @@ import { schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
readOnly: schema.conditional(
schema.contextRef('serverless'),
true,
schema.maybe(schema.boolean({ defaultValue: false })),
schema.never()
),
});
export type ConfigSchema = TypeOf<typeof configSchema>;
export type GaugeConfig = TypeOf<typeof configSchema>;
export interface GaugePublicConfig {
readOnly?: boolean;
}

View file

@ -6,10 +6,12 @@
* Side Public License, v 1.
*/
import { PluginInitializerContext } from '@kbn/core/public';
import { GaugePublicConfig } from '../config';
import { VisTypeGaugePlugin } from './plugin';
export function plugin() {
return new VisTypeGaugePlugin();
export function plugin(initializerContext: PluginInitializerContext<GaugePublicConfig>) {
return new VisTypeGaugePlugin(initializerContext);
}
export type { VisTypeGaugePluginSetup, VisTypeGaugePluginStart } from './types';

View file

@ -6,10 +6,11 @@
* Side Public License, v 1.
*/
import { CoreSetup, CoreStart } from '@kbn/core/public';
import { CoreSetup, CoreStart, PluginInitializerContext } from '@kbn/core/public';
import { VisualizationsSetup } from '@kbn/visualizations-plugin/public';
import { DataPublicPluginStart } from '@kbn/data-plugin/public';
import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
import { GaugePublicConfig } from '../config';
import { LEGACY_GAUGE_CHARTS_LIBRARY } from '../common';
import { VisTypeGaugePluginSetup } from './types';
import { gaugeVisType, goalVisType } from './vis_type';
@ -27,14 +28,29 @@ export interface VisTypeGaugePluginStartDependencies {
}
export class VisTypeGaugePlugin {
private readonly initializerContext: PluginInitializerContext<GaugePublicConfig>;
constructor(initializerContext: PluginInitializerContext<GaugePublicConfig>) {
this.initializerContext = initializerContext;
}
public setup(
core: CoreSetup<VisTypeGaugeSetupDependencies>,
{ visualizations }: VisTypeGaugeSetupDependencies
): VisTypeGaugePluginSetup {
if (!core.uiSettings.get(LEGACY_GAUGE_CHARTS_LIBRARY)) {
const { readOnly } = this.initializerContext.config.get<GaugePublicConfig>();
const visTypeProps = { showElasticChartsOptions: true };
visualizations.createBaseVisualization(gaugeVisType(visTypeProps));
visualizations.createBaseVisualization(goalVisType(visTypeProps));
visualizations.createBaseVisualization({
...gaugeVisType(visTypeProps),
disableCreate: Boolean(readOnly),
disableEdit: Boolean(readOnly),
});
visualizations.createBaseVisualization({
...goalVisType(visTypeProps),
disableCreate: Boolean(readOnly),
disableEdit: Boolean(readOnly),
});
}
return {};

View file

@ -6,12 +6,16 @@
* Side Public License, v 1.
*/
import { PluginConfigDescriptor } from '@kbn/core/server';
import { configSchema, ConfigSchema } from '../config';
import { PluginInitializerContext, PluginConfigDescriptor } from '@kbn/core/server';
import { configSchema, GaugeConfig } from '../config';
import { VisTypeGaugeServerPlugin } from './plugin';
export const config: PluginConfigDescriptor<ConfigSchema> = {
export const config: PluginConfigDescriptor<GaugeConfig> = {
exposeToBrowser: {
readOnly: true,
},
schema: configSchema,
};
export const plugin = () => new VisTypeGaugeServerPlugin();
export const plugin = (initializerContext: PluginInitializerContext) =>
new VisTypeGaugeServerPlugin(initializerContext);

View file

@ -9,7 +9,9 @@
import { i18n } from '@kbn/i18n';
import { schema } from '@kbn/config-schema';
import { CoreSetup, Plugin, UiSettingsParams } from '@kbn/core/server';
import { CoreSetup, Plugin, PluginInitializerContext, UiSettingsParams } from '@kbn/core/server';
import type { VisualizationsServerSetup } from '@kbn/visualizations-plugin/server';
import { GaugeConfig } from '../config';
import { LEGACY_GAUGE_CHARTS_LIBRARY } from '../common';
@ -34,10 +36,24 @@ export const getUiSettingsConfig: () => Record<string, UiSettingsParams<boolean>
},
});
interface PluginSetupDependencies {
visualizations: VisualizationsServerSetup;
}
export class VisTypeGaugeServerPlugin implements Plugin<object, object> {
public setup(core: CoreSetup) {
constructor(private readonly initializerContext: PluginInitializerContext) {
this.initializerContext = initializerContext;
}
public setup(core: CoreSetup, plugins: PluginSetupDependencies) {
core.uiSettings.register(getUiSettingsConfig());
const { readOnly } = this.initializerContext.config.get<GaugeConfig>();
if (readOnly) {
plugins.visualizations.registerReadOnlyVisType('gauge');
plugins.visualizations.registerReadOnlyVisType('goal');
}
return {};
}

View file

@ -10,6 +10,17 @@ import { schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
readOnly: schema.conditional(
schema.contextRef('serverless'),
true,
schema.maybe(schema.boolean({ defaultValue: false })),
schema.never()
),
});
export type ConfigSchema = TypeOf<typeof configSchema>;
export type HeatmapConfig = TypeOf<typeof configSchema>;
export interface HeatmapPublicConfig {
readOnly?: boolean;
}

View file

@ -6,8 +6,11 @@
* Side Public License, v 1.
*/
import { PluginInitializerContext } from '@kbn/core/public';
import { HeatmapPublicConfig } from '../config';
import { VisTypeHeatmapPlugin } from './plugin';
export { heatmapVisType } from './vis_type';
export const plugin = () => new VisTypeHeatmapPlugin();
export const plugin = (initializerContext: PluginInitializerContext<HeatmapPublicConfig>) =>
new VisTypeHeatmapPlugin(initializerContext);

View file

@ -6,13 +6,14 @@
* Side Public License, v 1.
*/
import { CoreSetup, CoreStart } from '@kbn/core/public';
import { CoreSetup, CoreStart, PluginInitializerContext } from '@kbn/core/public';
import type { VisualizationsSetup } from '@kbn/visualizations-plugin/public';
import type { ChartsPluginSetup } from '@kbn/charts-plugin/public';
import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public';
import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public';
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
import { HeatmapPublicConfig } from '../config';
import { LEGACY_HEATMAP_CHARTS_LIBRARY } from '../common';
import { heatmapVisType } from './vis_type';
import { setDataViewsStart } from './services';
@ -36,17 +37,26 @@ export interface VisTypeHeatmapStartDependencies {
}
export class VisTypeHeatmapPlugin {
private readonly initializerContext: PluginInitializerContext<HeatmapPublicConfig>;
constructor(initializerContext: PluginInitializerContext<HeatmapPublicConfig>) {
this.initializerContext = initializerContext;
}
setup(
core: CoreSetup<VisTypeHeatmapPluginStartDependencies>,
{ visualizations, charts, usageCollection }: VisTypeHeatmapSetupDependencies
) {
if (!core.uiSettings.get(LEGACY_HEATMAP_CHARTS_LIBRARY)) {
visualizations.createBaseVisualization(
heatmapVisType({
const { readOnly } = this.initializerContext.config.get<HeatmapPublicConfig>();
visualizations.createBaseVisualization({
...heatmapVisType({
showElasticChartsOptions: true,
palettes: charts.palettes,
})
);
}),
disableCreate: Boolean(readOnly),
disableEdit: Boolean(readOnly),
});
}
return {};
}

View file

@ -6,12 +6,16 @@
* Side Public License, v 1.
*/
import { PluginConfigDescriptor } from '@kbn/core/server';
import { configSchema, ConfigSchema } from '../config';
import { PluginConfigDescriptor, PluginInitializerContext } from '@kbn/core/server';
import { configSchema, HeatmapConfig } from '../config';
import { VisTypeHeatmapServerPlugin } from './plugin';
export const config: PluginConfigDescriptor<ConfigSchema> = {
export const config: PluginConfigDescriptor<HeatmapConfig> = {
exposeToBrowser: {
readOnly: true,
},
schema: configSchema,
};
export const plugin = () => new VisTypeHeatmapServerPlugin();
export const plugin = (initializerContext: PluginInitializerContext) =>
new VisTypeHeatmapServerPlugin(initializerContext);

View file

@ -9,7 +9,9 @@
import { i18n } from '@kbn/i18n';
import { schema } from '@kbn/config-schema';
import { CoreSetup, Plugin, UiSettingsParams } from '@kbn/core/server';
import { CoreSetup, Plugin, PluginInitializerContext, UiSettingsParams } from '@kbn/core/server';
import type { VisualizationsServerSetup } from '@kbn/visualizations-plugin/server';
import { HeatmapConfig } from '../config';
import { LEGACY_HEATMAP_CHARTS_LIBRARY } from '../common';
@ -45,10 +47,23 @@ export const getUiSettingsConfig: () => Record<string, UiSettingsParams<boolean>
},
});
interface PluginSetupDependencies {
visualizations: VisualizationsServerSetup;
}
export class VisTypeHeatmapServerPlugin implements Plugin<object, object> {
public setup(core: CoreSetup) {
constructor(private readonly initializerContext: PluginInitializerContext) {
this.initializerContext = initializerContext;
}
public setup(core: CoreSetup, plugins: PluginSetupDependencies) {
core.uiSettings.register(getUiSettingsConfig());
const { readOnly } = this.initializerContext.config.get<HeatmapConfig>();
if (readOnly) {
plugins.visualizations.registerReadOnlyVisType('heatmap');
}
return {};
}

View file

@ -10,6 +10,17 @@ import { schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
readOnly: schema.conditional(
schema.contextRef('serverless'),
true,
schema.maybe(schema.boolean({ defaultValue: false })),
schema.never()
),
});
export type ConfigSchema = TypeOf<typeof configSchema>;
export type MetricConfig = TypeOf<typeof configSchema>;
export interface MetricPublicConfig {
readOnly?: boolean;
}

View file

@ -7,8 +7,9 @@
*/
import { PluginInitializerContext } from '@kbn/core/public';
import { MetricPublicConfig } from '../config';
import { MetricVisPlugin as Plugin } from './plugin';
export function plugin(initializerContext: PluginInitializerContext) {
export function plugin(initializerContext: PluginInitializerContext<MetricPublicConfig>) {
return new Plugin(initializerContext);
}

View file

@ -10,7 +10,7 @@ import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from '@kbn/cor
import { VisualizationsSetup } from '@kbn/visualizations-plugin/public';
import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
import { createMetricVisTypeDefinition } from './metric_vis_type';
import { ConfigSchema } from '../config';
import { MetricPublicConfig } from '../config';
import { setDataViewsStart } from './services';
/** @internal */
@ -27,14 +27,19 @@ export interface MetricVisPluginStartDependencies {
export class MetricVisPlugin
implements Plugin<void, void, MetricVisPluginSetupDependencies, MetricVisPluginStartDependencies>
{
initializerContext: PluginInitializerContext<ConfigSchema>;
initializerContext: PluginInitializerContext<MetricPublicConfig>;
constructor(initializerContext: PluginInitializerContext<ConfigSchema>) {
constructor(initializerContext: PluginInitializerContext<MetricPublicConfig>) {
this.initializerContext = initializerContext;
}
public setup(core: CoreSetup, { visualizations }: MetricVisPluginSetupDependencies) {
visualizations.createBaseVisualization(createMetricVisTypeDefinition());
const { readOnly } = this.initializerContext.config.get<MetricPublicConfig>();
visualizations.createBaseVisualization({
...createMetricVisTypeDefinition(),
disableCreate: Boolean(readOnly),
disableEdit: Boolean(readOnly),
});
}
public start(core: CoreStart, { dataViews }: MetricVisPluginStartDependencies) {

View file

@ -6,15 +6,30 @@
* Side Public License, v 1.
*/
import { PluginConfigDescriptor } from '@kbn/core/server';
import { CoreSetup, PluginConfigDescriptor, PluginInitializerContext } from '@kbn/core/server';
import type { VisualizationsServerSetup } from '@kbn/visualizations-plugin/server';
import { configSchema, ConfigSchema } from '../config';
import { configSchema, MetricConfig } from '../config';
export const config: PluginConfigDescriptor<ConfigSchema> = {
export const config: PluginConfigDescriptor<MetricConfig> = {
exposeToBrowser: {
readOnly: true,
},
schema: configSchema,
};
export const plugin = () => ({
setup() {},
interface PluginSetupDependencies {
visualizations: VisualizationsServerSetup;
}
export const plugin = (initializerContext: PluginInitializerContext) => ({
setup(core: CoreSetup, plugins: PluginSetupDependencies) {
const { readOnly } = initializerContext.config.get<MetricConfig>();
if (readOnly) {
plugins.visualizations.registerReadOnlyVisType('metric');
}
return {};
},
start() {},
});

View file

@ -10,6 +10,17 @@ import { schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
readOnly: schema.conditional(
schema.contextRef('serverless'),
true,
schema.maybe(schema.boolean({ defaultValue: false })),
schema.never()
),
});
export type ConfigSchema = TypeOf<typeof configSchema>;
export type PieConfig = TypeOf<typeof configSchema>;
export interface PiePublicConfig {
readOnly?: boolean;
}

View file

@ -6,9 +6,12 @@
* Side Public License, v 1.
*/
import type { PluginInitializerContext } from '@kbn/core/public';
import { VisTypePiePlugin } from './plugin';
import type { PiePublicConfig } from '../config';
export { pieVisType } from './vis_type';
export type { Dimensions, Dimension } from './types';
export const plugin = () => new VisTypePiePlugin();
export const plugin = (initializerContext: PluginInitializerContext<PiePublicConfig>) =>
new VisTypePiePlugin(initializerContext);

View file

@ -6,12 +6,19 @@
* Side Public License, v 1.
*/
import { CoreSetup, CoreStart, DocLinksStart, ThemeServiceStart } from '@kbn/core/public';
import {
CoreSetup,
CoreStart,
DocLinksStart,
PluginInitializerContext,
ThemeServiceStart,
} from '@kbn/core/public';
import { VisualizationsSetup } from '@kbn/visualizations-plugin/public';
import { ChartsPluginSetup } from '@kbn/charts-plugin/public';
import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public';
import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
import { DataPublicPluginStart } from '@kbn/data-plugin/public';
import type { PiePublicConfig } from '../config';
import { pieVisType } from './vis_type';
import { setDataViewsStart } from './services';
@ -44,16 +51,25 @@ export interface VisTypePieDependencies {
}
export class VisTypePiePlugin {
initializerContext: PluginInitializerContext<PiePublicConfig>;
constructor(initializerContext: PluginInitializerContext<PiePublicConfig>) {
this.initializerContext = initializerContext;
}
setup(
core: CoreSetup<VisTypePiePluginStartDependencies>,
{ visualizations, charts, usageCollection }: VisTypePieSetupDependencies
) {
visualizations.createBaseVisualization(
pieVisType({
const { readOnly } = this.initializerContext.config.get<PiePublicConfig>();
visualizations.createBaseVisualization({
...pieVisType({
showElasticChartsOptions: true,
palettes: charts.palettes,
})
);
}),
disableCreate: Boolean(readOnly),
disableEdit: Boolean(readOnly),
});
return {};
}

View file

@ -6,12 +6,16 @@
* Side Public License, v 1.
*/
import { PluginConfigDescriptor } from '@kbn/core/server';
import { configSchema, ConfigSchema } from '../config';
import { PluginConfigDescriptor, PluginInitializerContext } from '@kbn/core/server';
import { configSchema, PieConfig } from '../config';
import { VisTypePieServerPlugin } from './plugin';
export const config: PluginConfigDescriptor<ConfigSchema> = {
export const config: PluginConfigDescriptor<PieConfig> = {
exposeToBrowser: {
readOnly: true,
},
schema: configSchema,
};
export const plugin = () => new VisTypePieServerPlugin();
export const plugin = (initializerContext: PluginInitializerContext) =>
new VisTypePieServerPlugin(initializerContext);

View file

@ -6,10 +6,25 @@
* Side Public License, v 1.
*/
import { CoreSetup, Plugin } from '@kbn/core/server';
import { CoreSetup, Plugin, PluginInitializerContext } from '@kbn/core/server';
import type { VisualizationsServerSetup } from '@kbn/visualizations-plugin/server';
import type { PieConfig } from '../config';
interface PluginSetupDependencies {
visualizations: VisualizationsServerSetup;
}
export class VisTypePieServerPlugin implements Plugin<object, object> {
public setup(core: CoreSetup) {
constructor(private readonly initializerContext: PluginInitializerContext) {
this.initializerContext = initializerContext;
}
public setup(core: CoreSetup, plugins: PluginSetupDependencies) {
const { readOnly } = this.initializerContext.config.get<PieConfig>();
if (readOnly) {
plugins.visualizations.registerReadOnlyVisType('pie');
}
return {};
}

View file

@ -10,6 +10,17 @@ import { schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
readOnly: schema.conditional(
schema.contextRef('serverless'),
true,
schema.maybe(schema.boolean({ defaultValue: false })),
schema.never()
),
});
export type ConfigSchema = TypeOf<typeof configSchema>;
export type TableConfig = TypeOf<typeof configSchema>;
export interface TablePublicConfig {
readOnly?: boolean;
}

View file

@ -6,8 +6,10 @@
* Side Public License, v 1.
*/
import { PluginInitializerContext } from '@kbn/core/public';
import { TablePublicConfig } from '../config';
import { TableVisPlugin as Plugin } from './plugin';
export function plugin() {
return new Plugin();
export function plugin(initializerContext: PluginInitializerContext<TablePublicConfig>) {
return new Plugin(initializerContext);
}

View file

@ -6,13 +6,13 @@
* Side Public License, v 1.
*/
import type { CoreSetup, CoreStart, Plugin } from '@kbn/core/public';
import type { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public';
import type { Plugin as ExpressionsPublicPlugin } from '@kbn/expressions-plugin/public';
import type { VisualizationsSetup } from '@kbn/visualizations-plugin/public';
import type { UsageCollectionStart } from '@kbn/usage-collection-plugin/public';
import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public';
import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
import { TablePublicConfig } from '../config';
import { setDataViewsStart, setFormatService } from './services';
import { registerTableVis } from './register_vis';
@ -33,8 +33,15 @@ export interface TablePluginStartDependencies {
export class TableVisPlugin
implements Plugin<void, void, TablePluginSetupDependencies, TablePluginStartDependencies>
{
initializerContext: PluginInitializerContext<TablePublicConfig>;
constructor(initializerContext: PluginInitializerContext<TablePublicConfig>) {
this.initializerContext = initializerContext;
}
public setup(core: CoreSetup<TablePluginStartDependencies>, deps: TablePluginSetupDependencies) {
registerTableVis(core, deps);
const { readOnly } = this.initializerContext.config.get<TablePublicConfig>();
registerTableVis(core, deps, Boolean(readOnly));
}
public start(core: CoreStart, { fieldFormats, dataViews }: TablePluginStartDependencies) {

View file

@ -14,10 +14,15 @@ import { tableVisTypeDefinition } from './table_vis_type';
export const registerTableVis = async (
core: CoreSetup<TablePluginStartDependencies>,
{ expressions, visualizations }: TablePluginSetupDependencies
{ expressions, visualizations }: TablePluginSetupDependencies,
readOnly: boolean
) => {
const [coreStart, { usageCollection }] = await core.getStartServices();
expressions.registerFunction(createTableVisFn);
expressions.registerRenderer(getTableVisRenderer(coreStart, usageCollection));
visualizations.createBaseVisualization(tableVisTypeDefinition);
visualizations.createBaseVisualization({
...tableVisTypeDefinition,
disableCreate: readOnly,
disableEdit: readOnly,
});
};

View file

@ -6,14 +6,30 @@
* Side Public License, v 1.
*/
import { PluginConfigDescriptor } from '@kbn/core/server';
import { configSchema, ConfigSchema } from '../config';
import { CoreSetup, PluginConfigDescriptor, PluginInitializerContext } from '@kbn/core/server';
import type { VisualizationsServerSetup } from '@kbn/visualizations-plugin/server';
import { configSchema, TableConfig } from '../config';
import { VIS_TYPE_TABLE } from '../common';
export const config: PluginConfigDescriptor<ConfigSchema> = {
export const config: PluginConfigDescriptor<TableConfig> = {
exposeToBrowser: {
readOnly: true,
},
schema: configSchema,
};
export const plugin = () => ({
setup() {},
interface PluginSetupDependencies {
visualizations: VisualizationsServerSetup;
}
export const plugin = (initializerContext: PluginInitializerContext) => ({
setup(core: CoreSetup, plugins: PluginSetupDependencies) {
const { readOnly } = initializerContext.config.get<TableConfig>();
if (readOnly) {
plugins.visualizations.registerReadOnlyVisType(VIS_TYPE_TABLE);
}
return {};
},
start() {},
});

View file

@ -10,6 +10,17 @@ import { schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
readOnly: schema.conditional(
schema.contextRef('serverless'),
true,
schema.maybe(schema.boolean({ defaultValue: false })),
schema.never()
),
});
export type ConfigSchema = TypeOf<typeof configSchema>;
export type TagcloudConfig = TypeOf<typeof configSchema>;
export interface TagcloudPublicConfig {
readOnly?: boolean;
}

View file

@ -7,8 +7,9 @@
*/
import { PluginInitializerContext } from '@kbn/core/public';
import { TagcloudPublicConfig } from '../config';
import { TagCloudPlugin as Plugin } from './plugin';
export function plugin(initializerContext: PluginInitializerContext) {
export function plugin(initializerContext: PluginInitializerContext<TagcloudPublicConfig>) {
return new Plugin(initializerContext);
}

View file

@ -11,7 +11,7 @@ import { VisualizationsSetup } from '@kbn/visualizations-plugin/public';
import { ChartsPluginSetup } from '@kbn/charts-plugin/public';
import { getTagCloudVisTypeDefinition } from './tag_cloud_type';
import { ConfigSchema } from '../config';
import { TagcloudPublicConfig } from '../config';
/** @internal */
export interface TagCloudPluginSetupDependencies {
@ -26,9 +26,9 @@ export interface TagCloudVisDependencies {
/** @internal */
export class TagCloudPlugin implements Plugin<void, void> {
initializerContext: PluginInitializerContext<ConfigSchema>;
initializerContext: PluginInitializerContext<TagcloudPublicConfig>;
constructor(initializerContext: PluginInitializerContext<ConfigSchema>) {
constructor(initializerContext: PluginInitializerContext<TagcloudPublicConfig>) {
this.initializerContext = initializerContext;
}
@ -37,7 +37,12 @@ export class TagCloudPlugin implements Plugin<void, void> {
palettes: charts.palettes,
};
visualizations.createBaseVisualization(getTagCloudVisTypeDefinition(visualizationDependencies));
const { readOnly } = this.initializerContext.config.get<TagcloudPublicConfig>();
visualizations.createBaseVisualization({
...getTagCloudVisTypeDefinition(visualizationDependencies),
disableCreate: Boolean(readOnly),
disableEdit: Boolean(readOnly),
});
}
public start(core: CoreStart) {}

View file

@ -6,15 +6,29 @@
* Side Public License, v 1.
*/
import { PluginConfigDescriptor } from '@kbn/core/server';
import { CoreSetup, PluginConfigDescriptor, PluginInitializerContext } from '@kbn/core/server';
import type { VisualizationsServerSetup } from '@kbn/visualizations-plugin/server';
import { configSchema, TagcloudConfig } from '../config';
import { configSchema, ConfigSchema } from '../config';
export const config: PluginConfigDescriptor<ConfigSchema> = {
export const config: PluginConfigDescriptor<TagcloudConfig> = {
exposeToBrowser: {
readOnly: true,
},
schema: configSchema,
};
export const plugin = () => ({
setup() {},
interface PluginSetupDependencies {
visualizations: VisualizationsServerSetup;
}
export const plugin = (initializerContext: PluginInitializerContext) => ({
setup(core: CoreSetup, plugins: PluginSetupDependencies) {
const { readOnly } = initializerContext.config.get<TagcloudConfig>();
if (readOnly) {
plugins.visualizations.registerReadOnlyVisType('tagcloud');
}
return {};
},
start() {},
});

View file

@ -6,6 +6,8 @@
* Side Public License, v 1.
*/
export const TIMELION_VIS_NAME = 'timelion';
export const UI_SETTINGS = {
ES_TIMEFIELD: 'timelion:es.timefield',
DEFAULT_INDEX: 'timelion:es.default_index',

View file

@ -11,6 +11,17 @@ import { schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
graphiteUrls: schema.maybe(schema.arrayOf(schema.string())),
enabled: schema.boolean({ defaultValue: true }),
readOnly: schema.conditional(
schema.contextRef('serverless'),
true,
schema.maybe(schema.boolean({ defaultValue: false })),
schema.never()
),
});
export type ConfigSchema = TypeOf<typeof configSchema>;
export type TimelionConfig = TypeOf<typeof configSchema>;
export interface TimelionPublicConfig {
readOnly?: boolean;
}

View file

@ -7,9 +7,10 @@
*/
import { PluginInitializerContext } from '@kbn/core/public';
import type { TimelionPublicConfig } from '../config';
import { TimelionVisPlugin as Plugin } from './plugin';
export function plugin(initializerContext: PluginInitializerContext) {
export function plugin(initializerContext: PluginInitializerContext<TimelionPublicConfig>) {
return new Plugin(initializerContext);
}

View file

@ -40,7 +40,7 @@ import {
import { getArgValueSuggestions } from './helpers/arg_value_suggestions';
import { getTimelionVisRenderer } from './timelion_vis_renderer';
import type { ConfigSchema } from '../config';
import type { TimelionPublicConfig } from '../config';
/** @internal */
export interface TimelionVisDependencies extends Partial<CoreStart> {
@ -82,7 +82,7 @@ export class TimelionVisPlugin
TimelionVisStartDependencies
>
{
constructor(public initializerContext: PluginInitializerContext<ConfigSchema>) {}
constructor(public initializerContext: PluginInitializerContext<TimelionPublicConfig>) {}
public setup(
{ uiSettings, http, theme }: CoreSetup,
@ -97,7 +97,12 @@ export class TimelionVisPlugin
expressions.registerFunction(() => getTimelionVisualizationConfig(dependencies));
expressions.registerRenderer(getTimelionVisRenderer(dependencies));
visualizations.createBaseVisualization(getTimelionVisDefinition(dependencies));
const { readOnly } = this.initializerContext.config.get<TimelionPublicConfig>();
visualizations.createBaseVisualization({
...getTimelionVisDefinition(dependencies),
disableCreate: Boolean(readOnly),
disableEdit: Boolean(readOnly),
});
}
public start(

View file

@ -12,7 +12,7 @@ import { Filter, Query, TimeRange } from '@kbn/es-query';
import { ExpressionFunctionDefinition, Render } from '@kbn/expressions-plugin/public';
import { KibanaContext } from '@kbn/data-plugin/public';
import { TimelionSuccessResponse } from './helpers/timelion_request_handler';
import { TIMELION_VIS_NAME } from './timelion_vis_type';
import { TIMELION_VIS_NAME } from '../common/constants';
import { TimelionVisDependencies } from './plugin';
type Input = KibanaContext | null;

View file

@ -11,6 +11,7 @@ import { i18n } from '@kbn/i18n';
import { DefaultEditorSize } from '@kbn/vis-default-editor-plugin/public';
import { VIS_EVENT_TO_TRIGGER, VisParams } from '@kbn/visualizations-plugin/public';
import { TIMELION_VIS_NAME } from '../common/constants';
import { TimelionOptionsProps } from './timelion_options';
import { TimelionVisDependencies } from './plugin';
import { toExpressionAst } from './to_ast';
@ -20,8 +21,6 @@ import { parseTimelionExpressionAsync } from '../common/parser_async';
const TimelionOptions = lazy(() => import('./timelion_options'));
export const TIMELION_VIS_NAME = 'timelion';
export function getTimelionVisDefinition(dependencies: TimelionVisDependencies) {
// return the visType object, which kibana will use to display and configure new
// Vis object of this type.

View file

@ -7,10 +7,13 @@
*/
import { PluginConfigDescriptor, PluginInitializerContext } from '@kbn/core/server';
import { configSchema, ConfigSchema } from '../config';
import { configSchema, TimelionConfig } from '../config';
import { TimelionPlugin } from './plugin';
export const config: PluginConfigDescriptor<ConfigSchema> = {
export const config: PluginConfigDescriptor<TimelionConfig> = {
exposeToBrowser: {
readOnly: true,
},
schema: configSchema,
deprecations: ({ unused }) => [unused('graphiteUrls', { level: 'warning' })],
};

View file

@ -11,12 +11,19 @@ import { i18n } from '@kbn/i18n';
import type { PluginStart, DataRequestHandlerContext } from '@kbn/data-plugin/server';
import type { PluginStart as DataViewPluginStart } from '@kbn/data-views-plugin/server';
import { CoreSetup, PluginInitializerContext, Plugin } from '@kbn/core/server';
import type { VisualizationsServerSetup } from '@kbn/visualizations-plugin/server';
import type { TimelionConfig } from '../config';
import { TIMELION_VIS_NAME } from '../common/constants';
import loadFunctions from './lib/load_functions';
import { functionsRoute } from './routes/functions';
import { runRoute } from './routes/run';
import { ConfigManager } from './lib/config_manager';
import { getUiSettings } from './ui_settings';
interface PluginSetupDependencies {
visualizations: VisualizationsServerSetup;
}
export interface TimelionPluginStartDeps {
data: PluginStart;
dataViews: DataViewPluginStart;
@ -25,10 +32,12 @@ export interface TimelionPluginStartDeps {
/**
* Represents Timelion Plugin instance that will be managed by the Kibana plugin system.
*/
export class TimelionPlugin implements Plugin<void, void, TimelionPluginStartDeps> {
export class TimelionPlugin
implements Plugin<void, void, PluginSetupDependencies, TimelionPluginStartDeps>
{
constructor(private readonly initializerContext: PluginInitializerContext) {}
public setup(core: CoreSetup<TimelionPluginStartDeps>): void {
public setup(core: CoreSetup<TimelionPluginStartDeps>, plugins: PluginSetupDependencies): void {
const configManager = new ConfigManager(this.initializerContext.config);
const functions = loadFunctions('series_functions');
@ -62,6 +71,11 @@ export class TimelionPlugin implements Plugin<void, void, TimelionPluginStartDep
runRoute(router, deps);
core.uiSettings.register(getUiSettings());
const { readOnly } = this.initializerContext.config.get<TimelionConfig>();
if (readOnly) {
plugins.visualizations.registerReadOnlyVisType(TIMELION_VIS_NAME);
}
}
public start() {

View file

@ -0,0 +1,26 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
readOnly: schema.conditional(
schema.contextRef('serverless'),
true,
schema.maybe(schema.boolean({ defaultValue: false })),
schema.never()
),
});
export type VislibConfig = TypeOf<typeof configSchema>;
export interface VislibPublicConfig {
readOnly?: boolean;
}

View file

@ -16,6 +16,7 @@ import type { UsageCollectionStart } from '@kbn/usage-collection-plugin/public';
import { LEGACY_HEATMAP_CHARTS_LIBRARY } from '@kbn/vis-type-heatmap-plugin/common';
import { LEGACY_GAUGE_CHARTS_LIBRARY } from '@kbn/vis-type-gauge-plugin/common';
import { VislibPublicConfig } from '../config';
import { setUsageCollectionStart } from './services';
import { heatmapVisTypeDefinition } from './heatmap';
@ -52,20 +53,32 @@ export class VisTypeVislibPlugin
core: VisTypeVislibCoreSetup,
{ expressions, visualizations, charts }: VisTypeVislibPluginSetupDependencies
) {
// register vislib XY axis charts
expressions.registerRenderer(getVislibVisRenderer(core, charts));
expressions.registerFunction(createVisTypeVislibVisFn());
const { readOnly } = this.initializerContext.config.get<VislibPublicConfig>();
if (core.uiSettings.get(LEGACY_HEATMAP_CHARTS_LIBRARY)) {
// register vislib heatmap chart
visualizations.createBaseVisualization(heatmapVisTypeDefinition);
visualizations.createBaseVisualization({
...heatmapVisTypeDefinition,
disableCreate: Boolean(readOnly),
disableEdit: Boolean(readOnly),
});
}
if (core.uiSettings.get(LEGACY_GAUGE_CHARTS_LIBRARY)) {
// register vislib gauge and goal charts
visualizations.createBaseVisualization(gaugeVisTypeDefinition);
visualizations.createBaseVisualization(goalVisTypeDefinition);
visualizations.createBaseVisualization({
...gaugeVisTypeDefinition,
disableCreate: Boolean(readOnly),
disableEdit: Boolean(readOnly),
});
visualizations.createBaseVisualization({
...goalVisTypeDefinition,
disableCreate: Boolean(readOnly),
disableEdit: Boolean(readOnly),
});
}
}

View file

@ -6,10 +6,15 @@
* Side Public License, v 1.
*/
import { schema } from '@kbn/config-schema';
import { PluginConfigDescriptor } from '@kbn/core/server';
import { configSchema, VislibConfig } from '../config';
import { VisTypeVislibServerPlugin } from './plugin';
export const config = {
schema: schema.object({ enabled: schema.boolean({ defaultValue: true }) }),
export const config: PluginConfigDescriptor<VislibConfig> = {
exposeToBrowser: {
readOnly: true,
},
schema: configSchema,
};
export const plugin = () => new VisTypeVislibServerPlugin();

View file

@ -7,6 +7,7 @@
"common/**/*",
"public/**/*",
"server/**/*",
"*.ts",
"public/fixtures/dispatch_heatmap_d3.json",
"public/fixtures/dispatch_heatmap_config.json",
"public/fixtures/dispatch_heatmap_data_point.json",

View file

@ -10,6 +10,17 @@ import { schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
readOnly: schema.conditional(
schema.contextRef('serverless'),
true,
schema.maybe(schema.boolean({ defaultValue: false })),
schema.never()
),
});
export type ConfigSchema = TypeOf<typeof configSchema>;
export type XyConfig = TypeOf<typeof configSchema>;
export interface XyPublicConfig {
readOnly?: boolean;
}

View file

@ -6,7 +6,9 @@
* Side Public License, v 1.
*/
import type { PluginInitializerContext } from '@kbn/core/public';
import { VisTypeXyPlugin as Plugin } from './plugin';
import type { XyPublicConfig } from '../config';
export type { VisTypeXyPluginSetup } from './plugin';
@ -27,6 +29,6 @@ export { TruncateLabelsOption } from './editor/components/common/truncate_labels
export { getPositions } from './editor/positions';
export { getScaleTypes } from './editor/scale_types';
export function plugin() {
return new Plugin();
export function plugin(initializerContext: PluginInitializerContext<XyPublicConfig>) {
return new Plugin(initializerContext);
}

View file

@ -6,10 +6,11 @@
* Side Public License, v 1.
*/
import type { CoreSetup, CoreStart, Plugin } from '@kbn/core/public';
import type { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public';
import type { VisualizationsSetup } from '@kbn/visualizations-plugin/public';
import type { ChartsPluginSetup } from '@kbn/charts-plugin/public';
import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
import type { XyPublicConfig } from '../config';
import { setUISettings, setPalettesService, setDataViewsStart } from './services';
import { visTypesDefinitions } from './vis_types';
@ -37,6 +38,12 @@ export class VisTypeXyPlugin
implements
Plugin<VisTypeXyPluginSetup, VisTypeXyPluginStart, VisTypeXyPluginSetupDependencies, {}>
{
initializerContext: PluginInitializerContext<XyPublicConfig>;
constructor(initializerContext: PluginInitializerContext<XyPublicConfig>) {
this.initializerContext = initializerContext;
}
public setup(
core: VisTypeXyCoreSetup,
{ visualizations, charts }: VisTypeXyPluginSetupDependencies
@ -44,7 +51,14 @@ export class VisTypeXyPlugin
setUISettings(core.uiSettings);
setPalettesService(charts.palettes);
visTypesDefinitions.forEach(visualizations.createBaseVisualization);
const { readOnly } = this.initializerContext.config.get<XyPublicConfig>();
visTypesDefinitions.forEach((visTypeDefinition) =>
visualizations.createBaseVisualization({
...visTypeDefinition,
disableCreate: Boolean(readOnly),
disableEdit: Boolean(readOnly),
})
);
return {};
}

View file

@ -6,12 +6,16 @@
* Side Public License, v 1.
*/
import { PluginConfigDescriptor } from '@kbn/core/server';
import { configSchema, ConfigSchema } from '../config';
import { PluginConfigDescriptor, PluginInitializerContext } from '@kbn/core/server';
import { configSchema, XyConfig } from '../config';
import { VisTypeXYServerPlugin } from './plugin';
export const config: PluginConfigDescriptor<ConfigSchema> = {
export const config: PluginConfigDescriptor<XyConfig> = {
exposeToBrowser: {
readOnly: true,
},
schema: configSchema,
};
export const plugin = () => new VisTypeXYServerPlugin();
export const plugin = (initializerContext: PluginInitializerContext) =>
new VisTypeXYServerPlugin(initializerContext);

View file

@ -6,10 +6,28 @@
* Side Public License, v 1.
*/
import { Plugin } from '@kbn/core/server';
import { CoreSetup, Plugin, PluginInitializerContext } from '@kbn/core/server';
import type { VisualizationsServerSetup } from '@kbn/visualizations-plugin/server';
import type { XyConfig } from '../config';
interface PluginSetupDependencies {
visualizations: VisualizationsServerSetup;
}
export class VisTypeXYServerPlugin implements Plugin {
public setup() {
constructor(private readonly initializerContext: PluginInitializerContext) {
this.initializerContext = initializerContext;
}
public setup(core: CoreSetup, plugins: PluginSetupDependencies) {
const { readOnly } = this.initializerContext.config.get<XyConfig>();
if (readOnly) {
plugins.visualizations.registerReadOnlyVisType('area');
plugins.visualizations.registerReadOnlyVisType('histogram');
plugins.visualizations.registerReadOnlyVisType('horizontal_bar');
plugins.visualizations.registerReadOnlyVisType('line');
}
return {};
}

View file

@ -58,7 +58,7 @@ function GroupSelection(props: GroupSelectionProps) {
...props.visTypesRegistry.getAliases(),
...props.visTypesRegistry.getByGroup(VisGroups.PROMOTED),
].filter((visDefinition) => {
return !Boolean(visDefinition.disableCreate);
return !visDefinition.disableCreate;
}),
['promotion', 'title'],
['asc', 'asc']
@ -92,7 +92,9 @@ function GroupSelection(props: GroupSelectionProps) {
<div className="visNewVisDialogGroupSelection__footer">
<EuiSpacer size="l" />
<EuiFlexGrid columns={2}>
{props.visTypesRegistry.getByGroup(VisGroups.AGGBASED).length > 0 && (
{props.visTypesRegistry.getByGroup(VisGroups.AGGBASED).filter((visDefinition) => {
return !visDefinition.disableCreate;
}).length > 0 && (
<EuiFlexItem>
<EuiCard
titleSize="xs"

View file

@ -160,7 +160,17 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
'telemetry.sendUsageTo (any)',
'usageCollection.uiCounters.debug (boolean)',
'usageCollection.uiCounters.enabled (boolean)',
// readOnly is boolean flag
'vis_type_gauge.readOnly (any)',
'vis_type_heatmap.readOnly (any)',
'vis_type_metric.readOnly (any)',
'vis_type_pie.readOnly (any)',
'vis_type_table.readOnly (any)',
'vis_type_tagcloud.readOnly (any)',
'vis_type_timelion.readOnly (any)',
'vis_type_timeseries.readOnly (any)',
'vis_type_vislib.readOnly (any)',
'vis_type_xy.readOnly (any)',
'vis_type_vega.enableExternalUrls (boolean)',
'xpack.actions.email.domain_allowlist (array)',
'xpack.apm.serviceMapEnabled (boolean)',