mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
# Backport This will backport the following commits from `main` to `8.6`: - [[DOCS] Automate connector-listing.png (#143605)](https://github.com/elastic/kibana/pull/143605) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Lisa Cawley","email":"lcawley@elastic.co"},"sourceCommit":{"committedDate":"2022-11-18T01:08:41Z","message":"[DOCS] Automate connector-listing.png (#143605)\n\nCo-authored-by: Robert Oskamp <traeluki@gmail.com>","sha":"31ca6447332e52e502f0ed3645ebb02f054807c7","branchLabelMapping":{"^v8.7.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:ResponseOps","docs","v8.6.0","v8.5.1","v8.7.0"],"number":143605,"url":"https://github.com/elastic/kibana/pull/143605","mergeCommit":{"message":"[DOCS] Automate connector-listing.png (#143605)\n\nCo-authored-by: Robert Oskamp <traeluki@gmail.com>","sha":"31ca6447332e52e502f0ed3645ebb02f054807c7"}},"sourceBranch":"main","suggestedTargetBranches":["8.6","8.5"],"targetPullRequestStates":[{"branch":"8.6","label":"v8.6.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.5","label":"v8.5.1","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.7.0","labelRegex":"^v8.7.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/143605","number":143605,"mergeCommit":{"message":"[DOCS] Automate connector-listing.png (#143605)\n\nCo-authored-by: Robert Oskamp <traeluki@gmail.com>","sha":"31ca6447332e52e502f0ed3645ebb02f054807c7"}}]}] BACKPORT--> Co-authored-by: Lisa Cawley <lcawley@elastic.co>
This commit is contained in:
parent
38c967b85e
commit
a8164ed83c
19 changed files with 207 additions and 83 deletions
|
@ -91,6 +91,7 @@ Rules use connectors to route actions to different destinations like log files,
|
|||
|
||||
[role="screenshot"]
|
||||
image::images/connector-listing.png[Example connector listing in the {rules-ui} UI]
|
||||
// NOTE: This is an autogenerated screenshot. Do not edit it directly.
|
||||
|
||||
[float]
|
||||
=== Required permissions
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 93 KiB |
|
@ -169,6 +169,9 @@ export default async function ({ readConfigFile }) {
|
|||
observability: {
|
||||
pathname: '/app/observability',
|
||||
},
|
||||
connectors: {
|
||||
pathname: '/app/management/insightsAndAlerting/triggersActionsConnectors/',
|
||||
},
|
||||
},
|
||||
|
||||
// choose where screenshots should be saved
|
||||
|
|
46
x-pack/test/functional/services/actions/api.ts
Normal file
46
x-pack/test/functional/services/actions/api.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export function ActionsAPIServiceProvider({ getService }: FtrProviderContext) {
|
||||
const kbnSupertest = getService('supertest');
|
||||
|
||||
return {
|
||||
async createConnector({
|
||||
name,
|
||||
config,
|
||||
secrets,
|
||||
connectorTypeId,
|
||||
}: {
|
||||
name: string;
|
||||
config: Record<string, unknown>;
|
||||
secrets: Record<string, unknown>;
|
||||
connectorTypeId: string;
|
||||
}) {
|
||||
const { body: createdAction } = await kbnSupertest
|
||||
.post(`/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name,
|
||||
config,
|
||||
secrets,
|
||||
connector_type_id: connectorTypeId,
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
return createdAction;
|
||||
},
|
||||
|
||||
async deleteConnector(id: string) {
|
||||
return kbnSupertest
|
||||
.delete(`/api/actions/connector/${id}`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.expect(204, '');
|
||||
},
|
||||
};
|
||||
}
|
|
@ -9,11 +9,13 @@ import { FtrProviderContext } from '../../ftr_provider_context';
|
|||
import { ActionsCommonServiceProvider } from './common';
|
||||
import { ActionsOpsgenieServiceProvider } from './opsgenie';
|
||||
import { ActionsTinesServiceProvider } from './tines';
|
||||
import { ActionsAPIServiceProvider } from './api';
|
||||
|
||||
export function ActionsServiceProvider(context: FtrProviderContext) {
|
||||
const common = ActionsCommonServiceProvider(context);
|
||||
|
||||
return {
|
||||
api: ActionsAPIServiceProvider(context),
|
||||
common: ActionsCommonServiceProvider(context),
|
||||
opsgenie: ActionsOpsgenieServiceProvider(context, common),
|
||||
tines: ActionsTinesServiceProvider(context, common),
|
||||
|
|
|
@ -73,6 +73,7 @@ import { CasesServiceProvider } from './cases';
|
|||
import { ActionsServiceProvider } from './actions';
|
||||
import { RulesServiceProvider } from './rules';
|
||||
import { AiopsProvider } from './aiops';
|
||||
import { SampleDataServiceProvider } from './sample_data';
|
||||
|
||||
// define the name and providers for services that should be
|
||||
// available to your tests. If you don't specify anything here
|
||||
|
@ -136,4 +137,5 @@ export const services = {
|
|||
rules: RulesServiceProvider,
|
||||
cases: CasesServiceProvider,
|
||||
aiops: AiopsProvider,
|
||||
sampleData: SampleDataServiceProvider,
|
||||
};
|
||||
|
|
|
@ -630,39 +630,5 @@ export function MachineLearningTestResourcesProvider(
|
|||
async clearAdvancedSettingProperty(propertyName: string) {
|
||||
await kibanaServer.uiSettings.unset(propertyName);
|
||||
},
|
||||
|
||||
async installKibanaSampleData(sampleDataId: 'ecommerce' | 'flights' | 'logs') {
|
||||
log.debug(`Installing Kibana sample data '${sampleDataId}'`);
|
||||
|
||||
const { body, status } = await supertest
|
||||
.post(`/api/sample_data/${sampleDataId}`)
|
||||
.set(COMMON_REQUEST_HEADERS);
|
||||
mlApi.assertResponseStatusCode(200, status, body);
|
||||
|
||||
log.debug(` > Installed`);
|
||||
},
|
||||
|
||||
async removeKibanaSampleData(sampleDataId: 'ecommerce' | 'flights' | 'logs') {
|
||||
log.debug(`Removing Kibana sample data '${sampleDataId}'`);
|
||||
|
||||
const { body, status } = await supertest
|
||||
.delete(`/api/sample_data/${sampleDataId}`)
|
||||
.set(COMMON_REQUEST_HEADERS);
|
||||
mlApi.assertResponseStatusCode(204, status, body);
|
||||
|
||||
log.debug(` > Removed`);
|
||||
},
|
||||
|
||||
async installAllKibanaSampleData() {
|
||||
await this.installKibanaSampleData('ecommerce');
|
||||
await this.installKibanaSampleData('flights');
|
||||
await this.installKibanaSampleData('logs');
|
||||
},
|
||||
|
||||
async removeAllKibanaSampleData() {
|
||||
await this.removeKibanaSampleData('ecommerce');
|
||||
await this.removeKibanaSampleData('flights');
|
||||
await this.removeKibanaSampleData('logs');
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
15
x-pack/test/functional/services/sample_data/index.ts
Normal file
15
x-pack/test/functional/services/sample_data/index.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
import { SampleDataTestResourcesServiceProvider } from './test_resources';
|
||||
|
||||
export function SampleDataServiceProvider(context: FtrProviderContext) {
|
||||
return {
|
||||
testResources: SampleDataTestResourcesServiceProvider(context),
|
||||
};
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export function SampleDataTestResourcesServiceProvider({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
|
||||
return {
|
||||
async installKibanaSampleData(sampleDataId: 'ecommerce' | 'flights' | 'logs') {
|
||||
await supertest.post(`/api/sample_data/${sampleDataId}`).set('kbn-xsrf', 'true').expect(200);
|
||||
},
|
||||
|
||||
async removeKibanaSampleData(sampleDataId: 'ecommerce' | 'flights' | 'logs') {
|
||||
await supertest
|
||||
.delete(`/api/sample_data/${sampleDataId}`)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.expect(204);
|
||||
},
|
||||
|
||||
async installAllKibanaSampleData() {
|
||||
await this.installKibanaSampleData('ecommerce');
|
||||
await this.installKibanaSampleData('flights');
|
||||
await this.installKibanaSampleData('logs');
|
||||
},
|
||||
|
||||
async removeAllKibanaSampleData() {
|
||||
await this.removeKibanaSampleData('ecommerce');
|
||||
await this.removeKibanaSampleData('flights');
|
||||
await this.removeKibanaSampleData('logs');
|
||||
},
|
||||
};
|
||||
}
|
|
@ -77,7 +77,7 @@ export default ({ getPageObjects, getPageObject, getService }: FtrProviderContex
|
|||
const updatedConnectorName = `${connectorName}updated`;
|
||||
const createdAction = await createSlackConnector({
|
||||
name: connectorName,
|
||||
supertest,
|
||||
getService,
|
||||
});
|
||||
objectRemover.add(createdAction.id, 'action', 'actions');
|
||||
await browser.refresh();
|
||||
|
@ -176,7 +176,7 @@ export default ({ getPageObjects, getPageObject, getService }: FtrProviderContex
|
|||
const connectorName = generateUniqueKey();
|
||||
const createdAction = await createSlackConnector({
|
||||
name: connectorName,
|
||||
supertest,
|
||||
getService,
|
||||
});
|
||||
objectRemover.add(createdAction.id, 'action', 'actions');
|
||||
await browser.refresh();
|
||||
|
@ -205,10 +205,10 @@ export default ({ getPageObjects, getPageObject, getService }: FtrProviderContex
|
|||
|
||||
it('should delete a connector', async () => {
|
||||
const connectorName = generateUniqueKey();
|
||||
await createSlackConnector({ name: connectorName, supertest });
|
||||
await createSlackConnector({ name: connectorName, getService });
|
||||
const createdAction = await createSlackConnector({
|
||||
name: generateUniqueKey(),
|
||||
supertest,
|
||||
getService,
|
||||
});
|
||||
objectRemover.add(createdAction.id, 'action', 'actions');
|
||||
await browser.refresh();
|
||||
|
@ -234,10 +234,10 @@ export default ({ getPageObjects, getPageObject, getService }: FtrProviderContex
|
|||
|
||||
it('should bulk delete connectors', async () => {
|
||||
const connectorName = generateUniqueKey();
|
||||
await createSlackConnector({ name: connectorName, supertest });
|
||||
await createSlackConnector({ name: connectorName, getService });
|
||||
const createdAction = await createSlackConnector({
|
||||
name: generateUniqueKey(),
|
||||
supertest,
|
||||
getService,
|
||||
});
|
||||
objectRemover.add(createdAction.id, 'action', 'actions');
|
||||
await browser.refresh();
|
||||
|
|
|
@ -9,7 +9,7 @@ import expect from '@kbn/expect';
|
|||
import { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
import { ObjectRemover } from '../../../lib/object_remover';
|
||||
import { generateUniqueKey } from '../../../lib/get_test_data';
|
||||
import { createConnector, createSlackConnectorAndObjectRemover, getConnectorByName } from './utils';
|
||||
import { createSlackConnectorAndObjectRemover, getConnectorByName } from './utils';
|
||||
|
||||
export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
@ -366,12 +366,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
|||
};
|
||||
|
||||
const createOpsgenieConnector = async (name: string) => {
|
||||
return createConnector({
|
||||
return actions.api.createConnector({
|
||||
name,
|
||||
config: { apiUrl: 'https//test.com' },
|
||||
secrets: { apiKey: '1234' },
|
||||
connectorTypeId: '.opsgenie',
|
||||
supertest,
|
||||
});
|
||||
};
|
||||
});
|
||||
|
|
|
@ -9,7 +9,7 @@ import expect from '@kbn/expect';
|
|||
import { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
import { ObjectRemover } from '../../../lib/object_remover';
|
||||
import { generateUniqueKey } from '../../../lib/get_test_data';
|
||||
import { createConnector, getConnectorByName } from './utils';
|
||||
import { getConnectorByName } from './utils';
|
||||
import {
|
||||
tinesAgentWebhook,
|
||||
tinesStory1,
|
||||
|
@ -267,12 +267,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
const createTinesConnector = async (name: string) => {
|
||||
return createConnector({
|
||||
return actions.api.createConnector({
|
||||
name,
|
||||
config: { url: simulatorUrl },
|
||||
secrets: { email: 'test@foo.com', token: 'apiToken' },
|
||||
connectorTypeId: '.tines',
|
||||
supertest,
|
||||
});
|
||||
};
|
||||
});
|
||||
|
|
|
@ -23,7 +23,7 @@ export const createSlackConnectorAndObjectRemover = async ({
|
|||
const testData = getTestActionData();
|
||||
const createdAction = await createSlackConnector({
|
||||
name: testData.name,
|
||||
supertest,
|
||||
getService,
|
||||
});
|
||||
objectRemover.add(createdAction.id, 'action', 'actions');
|
||||
|
||||
|
@ -32,17 +32,17 @@ export const createSlackConnectorAndObjectRemover = async ({
|
|||
|
||||
export const createSlackConnector = async ({
|
||||
name,
|
||||
supertest,
|
||||
getService,
|
||||
}: {
|
||||
name: string;
|
||||
supertest: SuperTest.SuperTest<SuperTest.Test>;
|
||||
getService: FtrProviderContext['getService'];
|
||||
}) => {
|
||||
const connector = await createConnector({
|
||||
const actions = getService('actions');
|
||||
const connector = await actions.api.createConnector({
|
||||
name,
|
||||
config: {},
|
||||
secrets: { webhookUrl: 'https://test.com' },
|
||||
connectorTypeId: '.slack',
|
||||
supertest,
|
||||
});
|
||||
|
||||
return connector;
|
||||
|
@ -59,30 +59,3 @@ export const getConnectorByName = async (
|
|||
const i = findIndex(body, (c: any) => c.name === name);
|
||||
return body[i];
|
||||
};
|
||||
|
||||
export const createConnector = async ({
|
||||
name,
|
||||
config,
|
||||
secrets,
|
||||
connectorTypeId,
|
||||
supertest,
|
||||
}: {
|
||||
name: string;
|
||||
config: Record<string, unknown>;
|
||||
secrets: Record<string, unknown>;
|
||||
connectorTypeId: string;
|
||||
supertest: SuperTest.SuperTest<SuperTest.Test>;
|
||||
}) => {
|
||||
const { body: createdAction } = await supertest
|
||||
.post(`/api/actions/connector`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
name,
|
||||
config,
|
||||
secrets,
|
||||
connector_type_id: connectorTypeId,
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
return createdAction;
|
||||
};
|
||||
|
|
|
@ -14,13 +14,14 @@ export const LOGS_INDEX_PATTERN = 'kibana_sample_data_logs';
|
|||
export default function ({ getPageObject, getService, loadTestFile }: FtrProviderContext) {
|
||||
const browser = getService('browser');
|
||||
const ml = getService('ml');
|
||||
const sampleData = getService('sampleData');
|
||||
const securityPage = getPageObject('security');
|
||||
|
||||
describe('machine learning docs', function () {
|
||||
this.tags(['ml']);
|
||||
|
||||
before(async () => {
|
||||
await ml.testResources.installAllKibanaSampleData();
|
||||
await sampleData.testResources.installAllKibanaSampleData();
|
||||
await ml.testResources.setKibanaTimeZoneToUTC();
|
||||
await ml.testResources.disableKibanaAnnouncements();
|
||||
await browser.setWindowSize(1920, 1080);
|
||||
|
@ -28,7 +29,7 @@ export default function ({ getPageObject, getService, loadTestFile }: FtrProvide
|
|||
|
||||
after(async () => {
|
||||
await securityPage.forceLogout();
|
||||
await ml.testResources.removeAllKibanaSampleData();
|
||||
await sampleData.testResources.removeAllKibanaSampleData();
|
||||
await ml.testResources.resetKibanaTimeZone();
|
||||
await ml.testResources.resetKibanaAnnouncements();
|
||||
});
|
||||
|
|
|
@ -15,13 +15,14 @@ export const LOGS_INDEX_PATTERN = 'kibana_sample_data_logs';
|
|||
export default function ({ getPageObject, getService, loadTestFile }: FtrProviderContext) {
|
||||
const browser = getService('browser');
|
||||
const ml = getService('ml');
|
||||
const sampleData = getService('sampleData');
|
||||
const securityPage = getPageObject('security');
|
||||
|
||||
describe('response ops docs', function () {
|
||||
this.tags(['responseOps']);
|
||||
|
||||
before(async () => {
|
||||
await ml.testResources.installAllKibanaSampleData();
|
||||
await sampleData.testResources.installAllKibanaSampleData();
|
||||
await ml.testResources.setKibanaTimeZoneToUTC();
|
||||
await ml.testResources.disableKibanaAnnouncements();
|
||||
await browser.setWindowSize(1920, 1080);
|
||||
|
@ -33,11 +34,12 @@ export default function ({ getPageObject, getService, loadTestFile }: FtrProvide
|
|||
|
||||
after(async () => {
|
||||
await securityPage.forceLogout();
|
||||
await ml.testResources.removeAllKibanaSampleData();
|
||||
await sampleData.testResources.removeAllKibanaSampleData();
|
||||
await ml.testResources.resetKibanaTimeZone();
|
||||
await ml.testResources.resetKibanaAnnouncements();
|
||||
});
|
||||
|
||||
loadTestFile(require.resolve('./stack_alerting'));
|
||||
loadTestFile(require.resolve('./stack_cases'));
|
||||
loadTestFile(require.resolve('./observability_cases'));
|
||||
});
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
|
||||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('stack alerting', function () {
|
||||
loadTestFile(require.resolve('./list_view'));
|
||||
});
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const commonScreenshots = getService('commonScreenshots');
|
||||
const screenshotDirectories = ['response_ops_docs', 'stack_alerting'];
|
||||
const pageObjects = getPageObjects(['common', 'header']);
|
||||
const actions = getService('actions');
|
||||
|
||||
describe('list view', function () {
|
||||
let serverLogConnectorId: string;
|
||||
|
||||
before(async () => {
|
||||
const connectorName = `server-log-connector`;
|
||||
({ id: serverLogConnectorId } = await createServerLogConnector(connectorName));
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await actions.api.deleteConnector(serverLogConnectorId);
|
||||
});
|
||||
|
||||
it('connectors list screenshot', async () => {
|
||||
await pageObjects.common.navigateToApp('connectors');
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
await commonScreenshots.takeScreenshot(
|
||||
'connector-listing',
|
||||
screenshotDirectories,
|
||||
1400,
|
||||
1024
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
const createServerLogConnector = async (name: string) => {
|
||||
return actions.api.createConnector({
|
||||
name,
|
||||
config: {},
|
||||
secrets: {},
|
||||
connectorTypeId: '.server-log',
|
||||
});
|
||||
};
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import { GenericFtrProviderContext } from '@kbn/test';
|
||||
|
||||
import { pageObjects } from '../functional/page_objects';
|
||||
import { pageObjects } from './page_objects';
|
||||
import { services } from './services';
|
||||
|
||||
export type FtrProviderContext = GenericFtrProviderContext<typeof services, typeof pageObjects>;
|
||||
|
|
16
x-pack/test/screenshot_creation/page_objects/index.ts
Normal file
16
x-pack/test/screenshot_creation/page_objects/index.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { pageObjects as xpackFunctionalPageObjects } from '../../functional/page_objects';
|
||||
import { TriggersActionsPageProvider } from '../../functional_with_es_ssl/page_objects/triggers_actions_ui_page';
|
||||
import { RuleDetailsPageProvider } from '../../functional_with_es_ssl/page_objects/rule_details';
|
||||
|
||||
export const pageObjects = {
|
||||
...xpackFunctionalPageObjects,
|
||||
triggersActionsUI: TriggersActionsPageProvider,
|
||||
ruleDetailsUI: RuleDetailsPageProvider,
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue