Skip to content

Commit

Permalink
migrate 'core' ui settings to core (#75544)
Browse files Browse the repository at this point in the history
* migrate ui settings to core

* add basic test on service

* add unit tests

* adapt buildNum schema

* use any for buildNum...

* move i18n keys to core prefix

* translate added validation messages

* using number for schema for buildNum

* move state:storeInSessionStorage setting to core

* remove overrides config validation

* remove defaultRoute from config schema
  • Loading branch information
pgayvallet authored Aug 24, 2020
1 parent d20c653 commit 4e3f47a
Show file tree
Hide file tree
Showing 23 changed files with 1,181 additions and 398 deletions.
44 changes: 44 additions & 0 deletions src/core/server/ui_settings/settings/accessibility.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { UiSettingsParams } from '../../../types';
import { getAccessibilitySettings } from './accessibility';

describe('accessibility settings', () => {
const accessibilitySettings = getAccessibilitySettings();

const getValidationFn = (setting: UiSettingsParams) => (value: any) =>
setting.schema.validate(value);

describe('accessibility:disableAnimations', () => {
const validate = getValidationFn(accessibilitySettings['accessibility:disableAnimations']);

it('should only accept boolean', () => {
expect(() => validate(true)).not.toThrow();
expect(() => validate(false)).not.toThrow();

expect(() => validate(42)).toThrowErrorMatchingInlineSnapshot(
`"expected value of type [boolean] but got [number]"`
);
expect(() => validate('foo')).toThrowErrorMatchingInlineSnapshot(
`"expected value of type [boolean] but got [string]"`
);
});
});
});
40 changes: 40 additions & 0 deletions src/core/server/ui_settings/settings/accessibility.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { schema } from '@kbn/config-schema';
import { i18n } from '@kbn/i18n';
import { UiSettingsParams } from '../../../types';

export const getAccessibilitySettings = (): Record<string, UiSettingsParams> => {
return {
'accessibility:disableAnimations': {
name: i18n.translate('core.ui_settings.params.disableAnimationsTitle', {
defaultMessage: 'Disable Animations',
}),
value: false,
description: i18n.translate('core.ui_settings.params.disableAnimationsText', {
defaultMessage:
'Turn off all unnecessary animations in the Kibana UI. Refresh the page to apply the changes.',
}),
category: ['accessibility'],
requiresPageReload: true,
schema: schema.boolean(),
},
};
};
104 changes: 104 additions & 0 deletions src/core/server/ui_settings/settings/date_formats.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import moment from 'moment-timezone';
import { UiSettingsParams } from '../../../types';
import { getDateFormatSettings } from './date_formats';

describe('accessibility settings', () => {
const dateFormatSettings = getDateFormatSettings();

const getValidationFn = (setting: UiSettingsParams) => (value: any) =>
setting.schema.validate(value);

describe('dateFormat', () => {
const validate = getValidationFn(dateFormatSettings.dateFormat);

it('should only accept string values', () => {
expect(() => validate('some format')).not.toThrow();

expect(() => validate(42)).toThrowErrorMatchingInlineSnapshot(
`"expected value of type [string] but got [number]"`
);
expect(() => validate(true)).toThrowErrorMatchingInlineSnapshot(
`"expected value of type [string] but got [boolean]"`
);
});
});

describe('dateFormat:tz', () => {
const validate = getValidationFn(dateFormatSettings['dateFormat:tz']);

it('should only accept valid timezones or `Browser`', () => {
expect(() => validate('Browser')).not.toThrow();
expect(() => validate('UTC')).not.toThrow();

expect(() => validate('EST')).toThrowErrorMatchingInlineSnapshot(`"Invalid timezone: EST"`);
expect(() => validate('random string')).toThrowErrorMatchingInlineSnapshot(
`"Invalid timezone: random string"`
);
});
});

describe('dateFormat:scaled', () => {
const validate = getValidationFn(dateFormatSettings['dateFormat:scaled']);

it('should only accept string values', () => {
expect(() => validate('some format')).not.toThrow();

expect(() => validate(42)).toThrowErrorMatchingInlineSnapshot(
`"expected value of type [string] but got [number]"`
);
expect(() => validate(true)).toThrowErrorMatchingInlineSnapshot(
`"expected value of type [string] but got [boolean]"`
);
});
});

describe('dateFormat:dow', () => {
const [validDay] = moment.weekdays();
const validate = getValidationFn(dateFormatSettings['dateFormat:dow']);

it('should only accept DOW values', () => {
expect(() => validate(validDay)).not.toThrow();

expect(() => validate('invalid value')).toThrowErrorMatchingInlineSnapshot(
`"Invalid day of week: invalid value"`
);
expect(() => validate(true)).toThrowErrorMatchingInlineSnapshot(
`"expected value of type [string] but got [boolean]"`
);
});
});

describe('dateNanosFormat', () => {
const validate = getValidationFn(dateFormatSettings.dateNanosFormat);

it('should only accept string values', () => {
expect(() => validate('some format')).not.toThrow();

expect(() => validate(42)).toThrowErrorMatchingInlineSnapshot(
`"expected value of type [string] but got [number]"`
);
expect(() => validate(true)).toThrowErrorMatchingInlineSnapshot(
`"expected value of type [string] but got [boolean]"`
);
});
});
});
168 changes: 168 additions & 0 deletions src/core/server/ui_settings/settings/date_formats.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import moment from 'moment-timezone';
import { schema } from '@kbn/config-schema';
import { i18n } from '@kbn/i18n';
import { UiSettingsParams } from '../../../types';

export const getDateFormatSettings = (): Record<string, UiSettingsParams> => {
const weekdays = moment.weekdays().slice();
const [defaultWeekday] = weekdays;

const timezones = [
'Browser',
...moment.tz
.names()
// We need to filter out some time zones, that moment.js knows about, but Elasticsearch
// does not understand and would fail thus with a 400 bad request when using them.
.filter((tz) => !['America/Nuuk', 'EST', 'HST', 'ROC', 'MST'].includes(tz)),
];

return {
dateFormat: {
name: i18n.translate('core.ui_settings.params.dateFormatTitle', {
defaultMessage: 'Date format',
}),
value: 'MMM D, YYYY @ HH:mm:ss.SSS',
description: i18n.translate('core.ui_settings.params.dateFormatText', {
defaultMessage: 'When displaying a pretty formatted date, use this {formatLink}',
description:
'Part of composite text: core.ui_settings.params.dateFormatText + ' +
'core.ui_settings.params.dateFormat.optionsLinkText',
values: {
formatLink:
'<a href="https://momentjs.com/docs/#/displaying/format/" target="_blank" rel="noopener noreferrer">' +
i18n.translate('core.ui_settings.params.dateFormat.optionsLinkText', {
defaultMessage: 'format',
}) +
'</a>',
},
}),
schema: schema.string(),
},
'dateFormat:tz': {
name: i18n.translate('core.ui_settings.params.dateFormat.timezoneTitle', {
defaultMessage: 'Timezone for date formatting',
}),
value: 'Browser',
description: i18n.translate('core.ui_settings.params.dateFormat.timezoneText', {
defaultMessage:
'Which timezone should be used. {defaultOption} will use the timezone detected by your browser.',
values: {
defaultOption: '"Browser"',
},
}),
type: 'select',
options: timezones,
requiresPageReload: true,
schema: schema.string({
validate: (value) => {
if (!timezones.includes(value)) {
return i18n.translate(
'core.ui_settings.params.dateFormat.timezone.invalidValidationMessage',
{
defaultMessage: 'Invalid timezone: {timezone}',
values: {
timezone: value,
},
}
);
}
},
}),
},
'dateFormat:scaled': {
name: i18n.translate('core.ui_settings.params.dateFormat.scaledTitle', {
defaultMessage: 'Scaled date format',
}),
type: 'json',
value: `[
["", "HH:mm:ss.SSS"],
["PT1S", "HH:mm:ss"],
["PT1M", "HH:mm"],
["PT1H", "YYYY-MM-DD HH:mm"],
["P1DT", "YYYY-MM-DD"],
["P1YT", "YYYY"]
]`,
description: i18n.translate('core.ui_settings.params.dateFormat.scaledText', {
defaultMessage:
'Values that define the format used in situations where time-based ' +
'data is rendered in order, and formatted timestamps should adapt to the ' +
'interval between measurements. Keys are {intervalsLink}.',
description:
'Part of composite text: core.ui_settings.params.dateFormat.scaledText + ' +
'core.ui_settings.params.dateFormat.scaled.intervalsLinkText',
values: {
intervalsLink:
'<a href="http://en.wikipedia.org/wiki/ISO_8601#Time_intervals" target="_blank" rel="noopener noreferrer">' +
i18n.translate('core.ui_settings.params.dateFormat.scaled.intervalsLinkText', {
defaultMessage: 'ISO8601 intervals',
}) +
'</a>',
},
}),
schema: schema.string(),
},
'dateFormat:dow': {
name: i18n.translate('core.ui_settings.params.dateFormat.dayOfWeekTitle', {
defaultMessage: 'Day of week',
}),
value: defaultWeekday,
description: i18n.translate('core.ui_settings.params.dateFormat.dayOfWeekText', {
defaultMessage: 'What day should weeks start on?',
}),
type: 'select',
options: weekdays,
schema: schema.string({
validate: (value) => {
if (!weekdays.includes(value)) {
return i18n.translate(
'core.ui_settings.params.dayOfWeekText.invalidValidationMessage',
{
defaultMessage: 'Invalid day of week: {dayOfWeek}',
values: {
dayOfWeek: value,
},
}
);
}
},
}),
},
dateNanosFormat: {
name: i18n.translate('core.ui_settings.params.dateNanosFormatTitle', {
defaultMessage: 'Date with nanoseconds format',
}),
value: 'MMM D, YYYY @ HH:mm:ss.SSSSSSSSS',
description: i18n.translate('core.ui_settings.params.dateNanosFormatText', {
defaultMessage: 'Used for the {dateNanosLink} datatype of Elasticsearch',
values: {
dateNanosLink:
'<a href="https://www.elastic.co/guide/en/elasticsearch/reference/master/date_nanos.html" target="_blank" rel="noopener noreferrer">' +
i18n.translate('core.ui_settings.params.dateNanosLinkTitle', {
defaultMessage: 'date_nanos',
}) +
'</a>',
},
}),
schema: schema.string(),
},
};
};
Loading

0 comments on commit 4e3f47a

Please sign in to comment.