Compare commits
9 Commits
sriram/SQL
...
moustafab/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4cd3e32a96 | ||
|
|
1cbe2bad7c | ||
|
|
c790bdff06 | ||
|
|
aeba2401a9 | ||
|
|
7af42967ee | ||
|
|
45d7169f8b | ||
|
|
138000a80d | ||
|
|
35b43aae84 | ||
|
|
9e40214c84 |
@@ -4677,4 +4677,4 @@
|
|||||||
"count": 1
|
"count": 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,4 +177,32 @@ describe('Rules group tests', () => {
|
|||||||
expect(ui.editGroupButton.query()).not.toBeInTheDocument();
|
expect(ui.editGroupButton.query()).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Ungrouped rules', () => {
|
||||||
|
const ungroupedGroup: CombinedRuleGroup = {
|
||||||
|
name: 'no_group_for_rule_TestRule',
|
||||||
|
rules: [
|
||||||
|
mockCombinedRule({
|
||||||
|
name: 'TestRule',
|
||||||
|
rulerRule: mockGrafanaRulerRule({ namespace_uid: 'folder-123' }),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
totals: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
const namespace: CombinedRuleNamespace = {
|
||||||
|
name: 'TestNamespace',
|
||||||
|
rulesSource: 'grafana',
|
||||||
|
groups: [ungroupedGroup],
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
mockUseHasRuler(true, GRAFANA_RULER_CONFIG);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should display rule name with (Ungrouped) suffix in grouped view', async () => {
|
||||||
|
renderRulesGroup(namespace, ungroupedGroup);
|
||||||
|
expect(await screen.findByText(/TestRule \(Ungrouped\)/)).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { useRulesAccess } from '../../utils/accessControlHooks';
|
|||||||
import { GRAFANA_RULES_SOURCE_NAME, getRulesSourceName, isCloudRulesSource } from '../../utils/datasource';
|
import { GRAFANA_RULES_SOURCE_NAME, getRulesSourceName, isCloudRulesSource } from '../../utils/datasource';
|
||||||
import { makeFolderLink } from '../../utils/misc';
|
import { makeFolderLink } from '../../utils/misc';
|
||||||
import { groups } from '../../utils/navigation';
|
import { groups } from '../../utils/navigation';
|
||||||
import { isFederatedRuleGroup, isPluginProvidedRule, rulerRuleType } from '../../utils/rules';
|
import { isFederatedRuleGroup, isPluginProvidedRule, isUngroupedRuleGroup, rulerRuleType } from '../../utils/rules';
|
||||||
import { CollapseToggle } from '../CollapseToggle';
|
import { CollapseToggle } from '../CollapseToggle';
|
||||||
import { RuleLocation } from '../RuleLocation';
|
import { RuleLocation } from '../RuleLocation';
|
||||||
import { GrafanaRuleFolderExporter } from '../export/GrafanaRuleFolderExporter';
|
import { GrafanaRuleFolderExporter } from '../export/GrafanaRuleFolderExporter';
|
||||||
@@ -164,11 +164,16 @@ export const RulesGroup = React.memo(({ group, namespace, expandAll, viewMode }:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ungrouped rules are rules that are in the "default" group name
|
// ungrouped rules are rules that are in the "default" group name
|
||||||
const groupName = isListView ? (
|
let groupName = <RuleLocation namespace={decodeGrafanaNamespace(namespace).name} group={group.name} />;
|
||||||
<RuleLocation namespace={decodeGrafanaNamespace(namespace).name} />
|
if (isListView) {
|
||||||
) : (
|
groupName = <RuleLocation namespace={decodeGrafanaNamespace(namespace).name} />;
|
||||||
<RuleLocation namespace={decodeGrafanaNamespace(namespace).name} group={group.name} />
|
} else if (isUngroupedRuleGroup(group.name)) {
|
||||||
);
|
const firstRuleName = group.rules[0]?.name ?? t('alerting.rules-group.unknown-rule', 'Unknown Rule');
|
||||||
|
const groupDisplayName = t('alerting.rules-group.ungrouped-suffix', '{{ruleName}} (Ungrouped)', {
|
||||||
|
ruleName: firstRuleName,
|
||||||
|
});
|
||||||
|
groupName = <RuleLocation namespace={decodeGrafanaNamespace(namespace).name} group={groupDisplayName} />;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.wrapper} data-testid="rule-group">
|
<div className={styles.wrapper} data-testid="rule-group">
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
import { render, screen } from 'test/test-utils';
|
||||||
|
import { byRole, byText } from 'testing-library-selector';
|
||||||
|
|
||||||
|
import { AccessControlAction } from 'app/types/accessControl';
|
||||||
|
import { GrafanaPromRuleGroupDTO } from 'app/types/unified-alerting-dto';
|
||||||
|
|
||||||
|
import { mockFolderApi, setupMswServer } from '../mockApi';
|
||||||
|
import { grantUserPermissions, mockFolder, mockGrafanaPromAlertingRule } from '../mocks';
|
||||||
|
import { NO_GROUP_PREFIX } from '../utils/rules';
|
||||||
|
|
||||||
|
import { GrafanaRuleGroupListItem } from './PaginatedGrafanaLoader';
|
||||||
|
|
||||||
|
const server = setupMswServer();
|
||||||
|
|
||||||
|
const ui = {
|
||||||
|
treeItem: byRole('treeitem'),
|
||||||
|
groupLink: (name: string | RegExp) => byRole('link', { name }),
|
||||||
|
ungroupedText: byText(/\(Ungrouped\)/),
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('GrafanaRuleGroupListItem', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
grantUserPermissions([AccessControlAction.AlertingRuleRead]);
|
||||||
|
mockFolderApi(server).folder('folder-123', mockFolder({ uid: 'folder-123', title: 'TestFolder' }));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
server.resetHandlers();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display rule name with (Ungrouped) suffix for ungrouped rules', async () => {
|
||||||
|
const grafanaRule = mockGrafanaPromAlertingRule({ name: 'My Alert Rule' });
|
||||||
|
const ungroupedGroup: GrafanaPromRuleGroupDTO = {
|
||||||
|
name: `${NO_GROUP_PREFIX}test-rule-uid`,
|
||||||
|
file: 'TestFolder',
|
||||||
|
folderUid: 'folder-123',
|
||||||
|
interval: 60,
|
||||||
|
rules: [grafanaRule],
|
||||||
|
};
|
||||||
|
|
||||||
|
render(<GrafanaRuleGroupListItem group={ungroupedGroup} namespaceName="TestFolder" />);
|
||||||
|
|
||||||
|
expect(await ui.treeItem.find()).toBeInTheDocument();
|
||||||
|
expect(await ui.groupLink(/My Alert Rule \(Ungrouped\)/).find()).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display normal group name for grouped rules', async () => {
|
||||||
|
const grafanaRule = mockGrafanaPromAlertingRule({ name: 'My Alert Rule' });
|
||||||
|
const groupedGroup: GrafanaPromRuleGroupDTO = {
|
||||||
|
name: 'MyGroup',
|
||||||
|
file: 'TestFolder',
|
||||||
|
folderUid: 'folder-123',
|
||||||
|
interval: 60,
|
||||||
|
rules: [grafanaRule],
|
||||||
|
};
|
||||||
|
|
||||||
|
render(<GrafanaRuleGroupListItem group={groupedGroup} namespaceName="TestFolder" />);
|
||||||
|
|
||||||
|
expect(await ui.groupLink('MyGroup').find()).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText(/Ungrouped/)).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render link to group details page with correct URL', async () => {
|
||||||
|
const grafanaRule = mockGrafanaPromAlertingRule({ name: 'My Alert Rule' });
|
||||||
|
const groupedGroup: GrafanaPromRuleGroupDTO = {
|
||||||
|
name: 'MyGroup',
|
||||||
|
file: 'TestFolder',
|
||||||
|
folderUid: 'folder-123',
|
||||||
|
interval: 60,
|
||||||
|
rules: [grafanaRule],
|
||||||
|
};
|
||||||
|
|
||||||
|
render(<GrafanaRuleGroupListItem group={groupedGroup} namespaceName="TestFolder" />);
|
||||||
|
|
||||||
|
const link = await ui.groupLink('MyGroup').find();
|
||||||
|
expect(link).toHaveAttribute(
|
||||||
|
'href',
|
||||||
|
expect.stringContaining('/alerting/grafana/namespaces/folder-123/groups/MyGroup/view')
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render as treeitem with correct aria attributes', async () => {
|
||||||
|
const grafanaRule = mockGrafanaPromAlertingRule({ name: 'My Alert Rule' });
|
||||||
|
const group: GrafanaPromRuleGroupDTO = {
|
||||||
|
name: 'TestGroup',
|
||||||
|
file: 'TestFolder',
|
||||||
|
folderUid: 'folder-123',
|
||||||
|
interval: 60,
|
||||||
|
rules: [grafanaRule],
|
||||||
|
};
|
||||||
|
|
||||||
|
render(<GrafanaRuleGroupListItem group={group} namespaceName="TestFolder" />);
|
||||||
|
|
||||||
|
const treeItem = await ui.treeItem.find();
|
||||||
|
expect(treeItem).toHaveAttribute('aria-expanded', 'false');
|
||||||
|
expect(treeItem).toHaveAttribute('aria-selected', 'false');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { groupBy, isEmpty } from 'lodash';
|
import { groupBy, isEmpty } from 'lodash';
|
||||||
import { useEffect, useMemo, useRef } from 'react';
|
import { useEffect, useMemo, useRef } from 'react';
|
||||||
|
|
||||||
|
import { t } from '@grafana/i18n';
|
||||||
import { Icon, Stack, Text } from '@grafana/ui';
|
import { Icon, Stack, Text } from '@grafana/ui';
|
||||||
import { GrafanaRuleGroupIdentifier, GrafanaRulesSourceSymbol } from 'app/types/unified-alerting';
|
import { GrafanaRuleGroupIdentifier, GrafanaRulesSourceSymbol } from 'app/types/unified-alerting';
|
||||||
import { GrafanaPromRuleGroupDTO, PromRuleGroupDTO } from 'app/types/unified-alerting-dto';
|
import { GrafanaPromRuleGroupDTO, PromRuleGroupDTO } from 'app/types/unified-alerting-dto';
|
||||||
@@ -9,6 +10,7 @@ import { FolderActionsButton } from '../components/folder-actions/FolderActionsB
|
|||||||
import { GrafanaNoRulesCTA } from '../components/rules/NoRulesCTA';
|
import { GrafanaNoRulesCTA } from '../components/rules/NoRulesCTA';
|
||||||
import { GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource';
|
import { GRAFANA_RULES_SOURCE_NAME } from '../utils/datasource';
|
||||||
import { groups } from '../utils/navigation';
|
import { groups } from '../utils/navigation';
|
||||||
|
import { isUngroupedRuleGroup } from '../utils/rules';
|
||||||
|
|
||||||
import { GrafanaGroupLoader } from './GrafanaGroupLoader';
|
import { GrafanaGroupLoader } from './GrafanaGroupLoader';
|
||||||
import { DataSourceSection } from './components/DataSourceSection';
|
import { DataSourceSection } from './components/DataSourceSection';
|
||||||
@@ -161,10 +163,15 @@ export function GrafanaRuleGroupListItem({ group, namespaceName }: GrafanaRuleGr
|
|||||||
|
|
||||||
const detailsLink = groups.detailsPageLink(GRAFANA_RULES_SOURCE_NAME, group.folderUid, group.name);
|
const detailsLink = groups.detailsPageLink(GRAFANA_RULES_SOURCE_NAME, group.folderUid, group.name);
|
||||||
|
|
||||||
|
const firstRuleName = group.rules[0]?.name ?? t('alerting.rules-group.unknown-rule', 'Unknown Rule');
|
||||||
|
const groupDisplayName = isUngroupedRuleGroup(group.name)
|
||||||
|
? t('alerting.rules-group.ungrouped-suffix', '{{ruleName}} (Ungrouped)', { ruleName: firstRuleName })
|
||||||
|
: group.name;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ListGroup
|
<ListGroup
|
||||||
key={group.name}
|
key={group.name}
|
||||||
name={group.name}
|
name={groupDisplayName}
|
||||||
metaRight={<GroupIntervalIndicator seconds={group.interval} />}
|
metaRight={<GroupIntervalIndicator seconds={group.interval} />}
|
||||||
href={detailsLink}
|
href={detailsLink}
|
||||||
isOpen={false}
|
isOpen={false}
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
import { render, screen } from 'test/test-utils';
|
||||||
|
import { byRole } from 'testing-library-selector';
|
||||||
|
|
||||||
|
import { PromApplication } from 'app/types/unified-alerting-dto';
|
||||||
|
|
||||||
|
import { NO_GROUP_PREFIX } from '../../utils/rules';
|
||||||
|
|
||||||
|
import { RuleLocation } from './RuleLocation';
|
||||||
|
|
||||||
|
const ui = {
|
||||||
|
groupLink: (name: string) => byRole('link', { name }),
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('RuleLocation', () => {
|
||||||
|
describe('ungrouped rules', () => {
|
||||||
|
it('should display "Ungrouped" text for groups with no_group_for_rule_ prefix', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<RuleLocation namespace="TestNamespace" group={`${NO_GROUP_PREFIX}test-rule-uid`} application="grafana" />
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(container).toHaveTextContent('Ungrouped');
|
||||||
|
expect(container).not.toHaveTextContent(`${NO_GROUP_PREFIX}test-rule-uid`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render "Ungrouped" as link when groupUrl is provided', () => {
|
||||||
|
render(
|
||||||
|
<RuleLocation
|
||||||
|
namespace="TestNamespace"
|
||||||
|
group={`${NO_GROUP_PREFIX}test-rule-uid`}
|
||||||
|
groupUrl="/alerting/grafana/namespaces/folder-123/groups/test-group/view"
|
||||||
|
application="grafana"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const link = ui.groupLink('Ungrouped').get();
|
||||||
|
expect(link).toHaveAttribute('href', '/alerting/grafana/namespaces/folder-123/groups/test-group/view');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render "Ungrouped" as text when groupUrl is not provided', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<RuleLocation namespace="TestNamespace" group={`${NO_GROUP_PREFIX}test-rule-uid`} application="grafana" />
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(screen.queryByRole('link')).not.toBeInTheDocument();
|
||||||
|
expect(container).toHaveTextContent('Ungrouped');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('grouped rules', () => {
|
||||||
|
it('should display normal group name for regular groups', () => {
|
||||||
|
const { container } = render(<RuleLocation namespace="TestNamespace" group="MyGroup" application="grafana" />);
|
||||||
|
|
||||||
|
expect(container).toHaveTextContent('MyGroup');
|
||||||
|
expect(container).not.toHaveTextContent('Ungrouped');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render group name as link when groupUrl is provided', () => {
|
||||||
|
render(
|
||||||
|
<RuleLocation
|
||||||
|
namespace="TestNamespace"
|
||||||
|
group="MyGroup"
|
||||||
|
groupUrl="/alerting/grafana/namespaces/folder-123/groups/MyGroup/view"
|
||||||
|
application="grafana"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const link = ui.groupLink('MyGroup').get();
|
||||||
|
expect(link).toHaveAttribute('href', '/alerting/grafana/namespaces/folder-123/groups/MyGroup/view');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render group name as text when groupUrl is not provided', () => {
|
||||||
|
const { container } = render(<RuleLocation namespace="TestNamespace" group="MyGroup" application="grafana" />);
|
||||||
|
|
||||||
|
expect(screen.queryByRole('link')).not.toBeInTheDocument();
|
||||||
|
expect(container).toHaveTextContent('MyGroup');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('namespace and group display', () => {
|
||||||
|
it('should display namespace and group correctly', () => {
|
||||||
|
const { container } = render(<RuleLocation namespace="TestNamespace" group="MyGroup" application="grafana" />);
|
||||||
|
|
||||||
|
expect(container).toHaveTextContent('TestNamespace');
|
||||||
|
expect(container).toHaveTextContent('MyGroup');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('grafana application', () => {
|
||||||
|
it('should not render data source tooltip for grafana application', () => {
|
||||||
|
render(<RuleLocation namespace="TestNamespace" group="MyGroup" application="grafana" />);
|
||||||
|
|
||||||
|
expect(screen.queryByRole('tooltip')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('datasource application', () => {
|
||||||
|
const mockRulesSource = {
|
||||||
|
uid: 'prometheus-1',
|
||||||
|
name: 'Prometheus',
|
||||||
|
ruleSourceType: 'datasource' as const,
|
||||||
|
};
|
||||||
|
|
||||||
|
it('should render content for datasource application', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<RuleLocation
|
||||||
|
namespace="TestNamespace"
|
||||||
|
group="MyGroup"
|
||||||
|
rulesSource={mockRulesSource}
|
||||||
|
application={PromApplication.Prometheus}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(container).toHaveTextContent('TestNamespace');
|
||||||
|
expect(container).toHaveTextContent('MyGroup');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
|
import { t } from '@grafana/i18n';
|
||||||
import { Icon, Stack, TextLink, Tooltip } from '@grafana/ui';
|
import { Icon, Stack, TextLink, Tooltip } from '@grafana/ui';
|
||||||
import { RulesSourceIdentifier } from 'app/types/unified-alerting';
|
import { RulesSourceIdentifier } from 'app/types/unified-alerting';
|
||||||
import { RulesSourceApplication } from 'app/types/unified-alerting-dto';
|
import { RulesSourceApplication } from 'app/types/unified-alerting-dto';
|
||||||
|
|
||||||
|
import { isUngroupedRuleGroup } from '../../utils/rules';
|
||||||
|
|
||||||
import { DataSourceIcon } from './DataSourceIcon';
|
import { DataSourceIcon } from './DataSourceIcon';
|
||||||
|
|
||||||
interface RuleLocationProps {
|
interface RuleLocationProps {
|
||||||
@@ -15,6 +18,7 @@ interface RuleLocationProps {
|
|||||||
export function RuleLocation({ namespace, group, groupUrl, rulesSource, application }: RuleLocationProps) {
|
export function RuleLocation({ namespace, group, groupUrl, rulesSource, application }: RuleLocationProps) {
|
||||||
const isGrafanaApp = application === 'grafana';
|
const isGrafanaApp = application === 'grafana';
|
||||||
const isDataSourceApp = !!rulesSource && !!application && !isGrafanaApp;
|
const isDataSourceApp = !!rulesSource && !!application && !isGrafanaApp;
|
||||||
|
const groupText = isUngroupedRuleGroup(group) ? t('alerting.rules-group.ungrouped', 'Ungrouped') : group;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack direction="row" alignItems="center" gap={0.5}>
|
<Stack direction="row" alignItems="center" gap={0.5}>
|
||||||
@@ -32,10 +36,10 @@ export function RuleLocation({ namespace, group, groupUrl, rulesSource, applicat
|
|||||||
<Icon size="sm" name="angle-right" />
|
<Icon size="sm" name="angle-right" />
|
||||||
{groupUrl ? (
|
{groupUrl ? (
|
||||||
<TextLink href={groupUrl} color="secondary" variant="bodySmall" inline={false}>
|
<TextLink href={groupUrl} color="secondary" variant="bodySmall" inline={false}>
|
||||||
{group}
|
{groupText}
|
||||||
</TextLink>
|
</TextLink>
|
||||||
) : (
|
) : (
|
||||||
group
|
groupText
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
getRuleGroupLocationFromCombinedRule,
|
getRuleGroupLocationFromCombinedRule,
|
||||||
getRuleGroupLocationFromRuleWithLocation,
|
getRuleGroupLocationFromRuleWithLocation,
|
||||||
getRulePluginOrigin,
|
getRulePluginOrigin,
|
||||||
|
isUngroupedRuleGroup,
|
||||||
} from './rules';
|
} from './rules';
|
||||||
|
|
||||||
describe('getRuleOrigin', () => {
|
describe('getRuleOrigin', () => {
|
||||||
@@ -123,3 +124,22 @@ describe('ruleGroupLocation', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('isUngroupedRuleGroup', () => {
|
||||||
|
it('should return true for group names starting with NO_GROUP_PREFIX', () => {
|
||||||
|
expect(isUngroupedRuleGroup('no_group_for_rule_abc123')).toBe(true);
|
||||||
|
expect(isUngroupedRuleGroup('no_group_for_rule_')).toBe(true);
|
||||||
|
expect(isUngroupedRuleGroup('no_group_for_rule_test-rule-uid')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for group names not starting with NO_GROUP_PREFIX', () => {
|
||||||
|
expect(isUngroupedRuleGroup('MyGroup')).toBe(false);
|
||||||
|
expect(isUngroupedRuleGroup('group-1')).toBe(false);
|
||||||
|
expect(isUngroupedRuleGroup('')).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false for group names that contain but do not start with NO_GROUP_PREFIX', () => {
|
||||||
|
expect(isUngroupedRuleGroup('prefix_no_group_for_rule_abc123')).toBe(false);
|
||||||
|
expect(isUngroupedRuleGroup('MyGroup_no_group_for_rule_')).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -563,3 +563,6 @@ export function getRuleUID(rule?: RulerRuleDTO | Rule) {
|
|||||||
|
|
||||||
return ruleUid;
|
return ruleUid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const NO_GROUP_PREFIX = 'no_group_for_rule_';
|
||||||
|
export const isUngroupedRuleGroup = (group: string): boolean => group.startsWith(NO_GROUP_PREFIX);
|
||||||
|
|||||||
@@ -2656,7 +2656,10 @@
|
|||||||
"rules-group": {
|
"rules-group": {
|
||||||
"deleting": "Deleting",
|
"deleting": "Deleting",
|
||||||
"text-federated": "Federated",
|
"text-federated": "Federated",
|
||||||
"text-provisioned": "Provisioned"
|
"text-provisioned": "Provisioned",
|
||||||
|
"ungrouped": "Ungrouped",
|
||||||
|
"ungrouped-suffix": "{{ruleName}} (Ungrouped)",
|
||||||
|
"unknown-rule": "Unknown Rule"
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"property": {
|
"property": {
|
||||||
|
|||||||
Reference in New Issue
Block a user