diff --git a/packages/plutono-data/src/types/config.ts b/packages/plutono-data/src/types/config.ts index f41713ac16..a9f47f3d24 100644 --- a/packages/plutono-data/src/types/config.ts +++ b/packages/plutono-data/src/types/config.ts @@ -126,4 +126,5 @@ export interface PlutonoConfig { dateFormats?: SystemDateFormatSettings; sentry: SentryConfig; customTheme?: any; + optionsLimit: number; } diff --git a/packages/plutono-runtime/src/config.ts b/packages/plutono-runtime/src/config.ts index b5180b5be0..31736ad288 100644 --- a/packages/plutono-runtime/src/config.ts +++ b/packages/plutono-runtime/src/config.ts @@ -73,6 +73,7 @@ export class PlutonoBootConfig implements PlutonoConfig { customTheme?: any; awsAllowedAuthProviders: string[] = []; awsAssumeRoleEnabled = false; + optionsLimit = 1000; constructor(options: PlutonoBootConfig) { this.theme = options.bootData.user.lightTheme ? getTheme(PlutonoThemeType.Light) : getTheme(PlutonoThemeType.Dark); diff --git a/pkg/api/frontendsettings.go b/pkg/api/frontendsettings.go index 6ac455c3e9..0f3db79271 100644 --- a/pkg/api/frontendsettings.go +++ b/pkg/api/frontendsettings.go @@ -219,6 +219,7 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *models.ReqContext) (map[string]i "editorsCanAdmin": hs.Cfg.EditorsCanAdmin, "disableSanitizeHtml": hs.Cfg.DisableSanitizeHtml, "pluginsToPreload": pluginsToPreload, + "optionsLimit": hs.Cfg.OptionsLimit, "buildInfo": map[string]interface{}{ "hideVersion": hideVersion, "version": version, diff --git a/pkg/api/metrics.go b/pkg/api/metrics.go index b129c75388..f0604f335c 100644 --- a/pkg/api/metrics.go +++ b/pkg/api/metrics.go @@ -59,7 +59,7 @@ func (hs *HTTPServer) QueryMetricsV2(c *models.ReqContext, reqDTO dtos.MetricReq request.Queries = append(request.Queries, &tsdb.Query{ RefId: query.Get("refId").MustString("A"), - MaxDataPoints: query.Get("maxDataPoints").MustInt64(100), + MaxDataPoints: query.Get("maxDataPoints").MustInt64(hs.Cfg.MaxDataPoints), IntervalMs: query.Get("intervalMs").MustInt64(1000), QueryType: query.Get("queryType").MustString(""), Model: query, diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index 1f07b5cfaa..f7241abe34 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -337,6 +337,8 @@ type Cfg struct { // Data sources DataSourceLimit int + OptionsLimit int64 + MaxDataPoints int64 // Snapshots SnapshotPublicMode bool @@ -1418,6 +1420,9 @@ func (cfg *Cfg) GetContentDeliveryURL(prefix string) string { } func (cfg *Cfg) readDataSourcesSettings() { + const MaxDataPointsLimitScale = 10 //for some reason we need to divide by 10 for the max data points limit. IE 100 means 1000. Not clear why that is the case datasources := cfg.Raw.Section("datasources") cfg.DataSourceLimit = datasources.Key("datasource_limit").MustInt(5000) + cfg.OptionsLimit = datasources.Key("options_limit").MustInt64(1000) + cfg.MaxDataPoints = cfg.OptionsLimit / MaxDataPointsLimitScale } diff --git a/public/app/features/variables/pickers/OptionsPicker/reducer.test.ts b/public/app/features/variables/pickers/OptionsPicker/reducer.test.ts index d11e1baa1b..5e2cf3b3bc 100644 --- a/public/app/features/variables/pickers/OptionsPicker/reducer.test.ts +++ b/public/app/features/variables/pickers/OptionsPicker/reducer.test.ts @@ -4,7 +4,6 @@ import { hideOptions, initialState as optionsPickerInitialState, moveOptionsHighlight, - OPTIONS_LIMIT, optionsPickerReducer, OptionsPickerState, showOptions, @@ -18,6 +17,7 @@ import { import { reducerTester } from '../../../../../test/core/redux/reducerTester'; import { QueryVariableModel, VariableOption, VariableTag } from '../../types'; import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../../state/types'; +import config from 'app/core/config'; const getVariableTestContext = (extend: Partial) => { return { @@ -730,7 +730,7 @@ describe('optionsPickerReducer', () => { const queryValue = 'option:1337'; const options = []; - for (let index = 0; index <= OPTIONS_LIMIT + 337; index++) { + for (let index = 0; index <= config.optionsLimit + 337; index++) { options.push({ text: `option:${index}`, value: `option:${index}`, selected: false }); } @@ -911,7 +911,7 @@ describe('optionsPickerReducer', () => { const searchQuery = 'option:11256'; const options: VariableOption[] = []; - for (let index = 0; index <= OPTIONS_LIMIT + 11256; index++) { + for (let index = 0; index <= config.optionsLimit + 11256; index++) { options.push({ text: `option:${index}`, value: `option:${index}`, selected: false }); } @@ -937,7 +937,7 @@ describe('optionsPickerReducer', () => { const searchQuery = '__searchFilter'; const options = [{ text: 'All', value: '$__all', selected: true }]; - for (let i = 0; i <= OPTIONS_LIMIT + 137; i++) { + for (let i = 0; i <= config.optionsLimit + 137; i++) { options.push({ text: `option${i}`, value: `option${i}`, selected: false }); } const { initialState } = getVariableTestContext({ @@ -949,7 +949,7 @@ describe('optionsPickerReducer', () => { .whenActionIsDispatched(updateOptionsFromSearch(options)) .thenStateShouldEqual({ ...initialState, - options: options.slice(0, OPTIONS_LIMIT), + options: options.slice(0, config.optionsLimit), selectedValues: [{ text: 'All', value: '$__all', selected: true }], highlightIndex: 0, }); @@ -967,10 +967,10 @@ describe('optionsPickerReducer', () => { id: '0', } as QueryVariableModel; const checkOptions = []; - for (let index = 0; index < OPTIONS_LIMIT; index++) { + for (let index = 0; index < config.optionsLimit; index++) { checkOptions.push({ text: `option${index}`, value: `option${index}`, selected: false }); } - for (let i = 1; i <= OPTIONS_LIMIT + 137; i++) { + for (let i = 1; i <= config.optionsLimit + 137; i++) { payload.options.push({ text: `option${i}`, value: `option${i}`, selected: false }); } diff --git a/public/app/features/variables/pickers/OptionsPicker/reducer.ts b/public/app/features/variables/pickers/OptionsPicker/reducer.ts index 464fa70b6c..ec8392d068 100644 --- a/public/app/features/variables/pickers/OptionsPicker/reducer.ts +++ b/public/app/features/variables/pickers/OptionsPicker/reducer.ts @@ -5,6 +5,7 @@ import { ALL_VARIABLE_VALUE } from '../../state/types'; import { isMulti, isQuery } from '../../guard'; import { applyStateChanges } from '../../../../core/utils/applyStateChanges'; import { containsSearchFilter } from '../../utils'; +import config from 'app/core/config'; export interface ToggleOption { option?: VariableOption; @@ -34,8 +35,6 @@ export const initialState: OptionsPickerState = { multi: false, }; -export const OPTIONS_LIMIT = 1000; - const getTags = (model: VariableWithMultiSupport) => { if (isQuery(model) && Array.isArray(model.tags)) { return cloneDeep(model.tags); @@ -86,10 +85,11 @@ const applyLimit = (options: VariableOption[]): VariableOption[] => { if (!Array.isArray(options)) { return []; } - if (options.length <= OPTIONS_LIMIT) { + if (options.length <= config.optionsLimit) { return options; } - return options.slice(0, OPTIONS_LIMIT); + console.log('Need to slice!'); + return options.slice(0, config.optionsLimit); }; const updateDefaultSelection = (state: OptionsPickerState): OptionsPickerState => {