Commit 96334aba authored by ap4y's avatar ap4y

Improve rule mode error state in policy editor

This commit updates yaml parsing error state in policy editor to be
closer to mocks.
parent af1fadd1
<script>
export default {
props: {
disabled: {
type: Boolean,
required: false,
default: false,
},
},
};
</script>
<template>
<div>
<slot name="title"></slot>
<slot v-if="disabled" name="disabled"></slot>
<slot v-else></slot>
<div
v-if="disabled"
class="gl-absolute gl-top-0 gl-bottom-0 gl-left-0 gl-right-0 gl-bg-white gl-opacity-5"
data-testid="overlay"
></div>
</div>
</template>
...@@ -19,6 +19,7 @@ import NetworkPolicyEditor from '../network_policy_editor.vue'; ...@@ -19,6 +19,7 @@ import NetworkPolicyEditor from '../network_policy_editor.vue';
import PolicyRuleBuilder from './policy_rule_builder.vue'; import PolicyRuleBuilder from './policy_rule_builder.vue';
import PolicyPreview from './policy_preview.vue'; import PolicyPreview from './policy_preview.vue';
import PolicyActionPicker from './policy_action_picker.vue'; import PolicyActionPicker from './policy_action_picker.vue';
import DimDisableContainer from './dim_disable_container.vue';
import { import {
EditorModeRule, EditorModeRule,
EditorModeYAML, EditorModeYAML,
...@@ -46,6 +47,7 @@ export default { ...@@ -46,6 +47,7 @@ export default {
PolicyRuleBuilder, PolicyRuleBuilder,
PolicyPreview, PolicyPreview,
PolicyActionPicker, PolicyActionPicker,
DimDisableContainer,
}, },
directives: { GlModal: GlModalDirective }, directives: { GlModal: GlModalDirective },
props: { props: {
...@@ -249,43 +251,80 @@ export default { ...@@ -249,43 +251,80 @@ export default {
<hr /> <hr />
<div v-if="shouldShowRuleEditor" class="row" data-testid="rule-editor"> <div v-if="shouldShowRuleEditor" class="row" data-testid="rule-editor">
<div class="col-sm-12 col-md-6 col-lg-7 col-xl-8"> <div class="col-sm-12 col-md-6 col-lg-7 col-xl-8">
<gl-alert v-if="hasParsingError" data-testid="parsing-alert" :dismissible="false">{{ <gl-alert
$options.parsingErrorMessage v-if="hasParsingError"
}}</gl-alert> class="gl-z-index-1"
data-testid="parsing-alert"
:dismissible="false"
>{{ $options.parsingErrorMessage }}</gl-alert
>
<dim-disable-container data-testid="rule-builder-container" :disabled="hasParsingError">
<template #title>
<h4>{{ s__('NetworkPolicies|Rules') }}</h4>
</template>
<template #disabled>
<div
class="gl-bg-gray-10 gl-border-solid gl-border-1 gl-border-gray-100 gl-rounded-base gl-p-6"
></div>
</template>
<h4>{{ s__('NetworkPolicies|Rules') }}</h4> <policy-rule-builder
<policy-rule-builder v-for="(rule, idx) in policy.rules"
v-for="(rule, idx) in policy.rules" :key="idx"
:key="idx" class="gl-mb-4"
class="gl-mb-4" :rule="rule"
:rule="rule" :endpoint-match-mode="policy.endpointMatchMode"
:endpoint-match-mode="policy.endpointMatchMode" :endpoint-labels="policy.endpointLabels"
:endpoint-labels="policy.endpointLabels" :endpoint-selector-disabled="idx > 0"
:endpoint-selector-disabled="idx > 0" @rule-type-change="updateRuleType(idx, $event)"
@rule-type-change="updateRuleType(idx, $event)" @endpoint-match-mode-change="updateEndpointMatchMode"
@endpoint-match-mode-change="updateEndpointMatchMode" @endpoint-labels-change="updateEndpointLabels"
@endpoint-labels-change="updateEndpointLabels" @remove="removeRule(idx)"
@remove="removeRule(idx)" />
/>
<div class="gl-p-3 gl-rounded-base gl-border-1 gl-border-solid gl-border-gray-100 gl-mb-5"> <div
<gl-button class="gl-p-3 gl-rounded-base gl-border-1 gl-border-solid gl-border-gray-100 gl-mb-5"
variant="link"
category="primary"
data-testid="add-rule"
:disabled="hasParsingError"
@click="addRule"
>{{ s__('Network Policy|New rule') }}</gl-button
> >
</div> <gl-button variant="link" category="primary" data-testid="add-rule" @click="addRule">{{
s__('Network Policy|New rule')
}}</gl-button>
</div>
</dim-disable-container>
<h4>{{ s__('NetworkPolicies|Actions') }}</h4> <dim-disable-container data-testid="policy-action-container" :disabled="hasParsingError">
<p>{{ s__('NetworkPolicies|Traffic that does not match any rule will be blocked.') }}</p> <template #title>
<policy-action-picker /> <h4>{{ s__('NetworkPolicies|Actions') }}</h4>
<p>
{{ s__('NetworkPolicies|Traffic that does not match any rule will be blocked.') }}
</p>
</template>
<template #disabled>
<div
class="gl-bg-gray-10 gl-border-solid gl-border-1 gl-border-gray-100 gl-rounded-base gl-p-6"
></div>
</template>
<policy-action-picker />
</dim-disable-container>
</div> </div>
<div class="col-sm-12 col-md-6 col-lg-5 col-xl-4"> <div class="col-sm-12 col-md-6 col-lg-5 col-xl-4">
<h5>{{ s__('NetworkPolicies|Policy preview') }}</h5> <dim-disable-container data-testid="policy-preview-container" :disabled="hasParsingError">
<policy-preview :policy-yaml="policyYaml" :policy-description="humanizedPolicy" /> <template #title>
<h5>{{ s__('NetworkPolicies|Policy preview') }}</h5>
</template>
<template #disabled>
<policy-preview
:policy-yaml="s__('NetworkPolicies|Unable to parse policy')"
policy-description=""
/>
</template>
<policy-preview :policy-yaml="policyYaml" :policy-description="humanizedPolicy" />
</dim-disable-container>
</div> </div>
</div> </div>
<div v-if="shouldShowYamlEditor" class="row" data-testid="yaml-editor"> <div v-if="shouldShowYamlEditor" class="row" data-testid="yaml-editor">
......
---
title: Improve policy editor layout
merge_request: 42424
author:
type: changed
...@@ -153,47 +153,45 @@ exports[`PolicyEditorApp component renders the policy editor layout 1`] = ` ...@@ -153,47 +153,45 @@ exports[`PolicyEditorApp component renders the policy editor layout 1`] = `
> >
<!----> <!---->
<h4> <dim-disable-container-stub
Rules data-testid="rule-builder-container"
</h4>
<div
class="gl-p-3 gl-rounded-base gl-border-1 gl-border-solid gl-border-gray-100 gl-mb-5"
> >
<gl-button-stub
buttontextclasses="" <div
category="primary" class="gl-p-3 gl-rounded-base gl-border-1 gl-border-solid gl-border-gray-100 gl-mb-5"
data-testid="add-rule"
icon=""
size="medium"
variant="link"
> >
New rule <gl-button-stub
</gl-button-stub> buttontextclasses=""
</div> category="primary"
data-testid="add-rule"
<h4> icon=""
Actions size="medium"
</h4> variant="link"
>
<p> New rule
Traffic that does not match any rule will be blocked. </gl-button-stub>
</p> </div>
</dim-disable-container-stub>
<policy-action-picker-stub /> <dim-disable-container-stub
data-testid="policy-action-container"
>
<policy-action-picker-stub />
</dim-disable-container-stub>
</div> </div>
<div <div
class="col-sm-12 col-md-6 col-lg-5 col-xl-4" class="col-sm-12 col-md-6 col-lg-5 col-xl-4"
> >
<h5> <dim-disable-container-stub
Policy preview data-testid="policy-preview-container"
</h5> >
<policy-preview-stub <policy-preview-stub
initialtab="0" initialtab="0"
policydescription="Deny all traffic" policydescription="Deny all traffic"
policyyaml="apiVersion: cilium.io/v2 policyyaml="apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy kind: CiliumNetworkPolicy
metadata: metadata:
name: '' name: ''
...@@ -202,7 +200,8 @@ spec: ...@@ -202,7 +200,8 @@ spec:
matchLabels: matchLabels:
network-policy.gitlab.com/disabled_by: gitlab network-policy.gitlab.com/disabled_by: gitlab
" "
/> />
</dim-disable-container-stub>
</div> </div>
</div> </div>
......
import { shallowMount } from '@vue/test-utils';
import DimDisableContainer from 'ee/threat_monitoring/components/policy_editor/dim_disable_container.vue';
describe('DimDisableContainer component', () => {
let wrapper;
const factory = ({ propsData } = {}) => {
wrapper = shallowMount(DimDisableContainer, {
propsData: {
...propsData,
},
slots: {
default: '<main>Item</main>',
title: '<h1>Title</h1>',
disabled: '<span>Disabled</span>',
},
});
};
beforeEach(() => {
factory();
});
afterEach(() => {
wrapper.destroy();
});
it('renders title slot component', () => {
expect(wrapper.contains('h1')).toBe(true);
});
it('renders default slot component', () => {
expect(wrapper.contains('main')).toBe(true);
});
it('does not render disabled slot component', () => {
expect(wrapper.contains('span')).toBe(false);
});
it('does not render dim overlay', () => {
expect(wrapper.contains("[data-testid='overlay']")).toBe(false);
});
describe('give disabled is true', () => {
beforeEach(() => {
factory({
propsData: {
disabled: true,
},
});
});
it('renders title slot component', () => {
expect(wrapper.contains('h1')).toBe(true);
});
it('does not render default slot component', () => {
expect(wrapper.contains('main')).toBe(false);
});
it('renders disabled slot component', () => {
expect(wrapper.contains('span')).toBe(true);
});
it('renders dim overlay', () => {
expect(wrapper.contains("[data-testid='overlay']")).toBe(true);
});
});
});
...@@ -53,6 +53,7 @@ describe('PolicyEditorApp component', () => { ...@@ -53,6 +53,7 @@ describe('PolicyEditorApp component', () => {
const findPolicyName = () => wrapper.find("[id='policyName']"); const findPolicyName = () => wrapper.find("[id='policyName']");
const findSavePolicy = () => wrapper.find("[data-testid='save-policy']"); const findSavePolicy = () => wrapper.find("[data-testid='save-policy']");
const findDeletePolicy = () => wrapper.find("[data-testid='delete-policy']"); const findDeletePolicy = () => wrapper.find("[data-testid='delete-policy']");
const findEditorModeToggle = () => wrapper.find("[data-testid='editor-mode']");
beforeEach(() => { beforeEach(() => {
factory(); factory();
...@@ -189,7 +190,7 @@ spec: ...@@ -189,7 +190,7 @@ spec:
it('updates yaml editor value on switch to yaml editor', async () => { it('updates yaml editor value on switch to yaml editor', async () => {
findPolicyName().vm.$emit('input', 'test-policy'); findPolicyName().vm.$emit('input', 'test-policy');
wrapper.find("[data-testid='editor-mode']").vm.$emit('input', EditorModeYAML); findEditorModeToggle().vm.$emit('input', EditorModeYAML);
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
const editor = findNetworkPolicyEditor(); const editor = findNetworkPolicyEditor();
...@@ -212,13 +213,21 @@ spec: ...@@ -212,13 +213,21 @@ spec:
expect(findYAMLParsingAlert().exists()).toBe(true); expect(findYAMLParsingAlert().exists()).toBe(true);
}); });
it('disables add rule button', () => { it('disables rule builder', () => {
expect(findAddRuleButton().props('disabled')).toBe(true); expect(wrapper.find("[data-testid='rule-builder-container']").props().disabled).toBe(true);
});
it('disables action picker', () => {
expect(wrapper.find("[data-testid='policy-action-container']").props().disabled).toBe(true);
});
it('disables policy preview', () => {
expect(wrapper.find("[data-testid='policy-preview-container']").props().disabled).toBe(true);
}); });
it('does not update yaml editor value on switch to yaml editor', async () => { it('does not update yaml editor value on switch to yaml editor', async () => {
findPolicyName().vm.$emit('input', 'test-policy'); findPolicyName().vm.$emit('input', 'test-policy');
wrapper.find("[data-testid='editor-mode']").vm.$emit('input', EditorModeYAML); findEditorModeToggle().vm.$emit('input', EditorModeYAML);
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
const editor = findNetworkPolicyEditor(); const editor = findNetworkPolicyEditor();
......
...@@ -16799,6 +16799,9 @@ msgstr "" ...@@ -16799,6 +16799,9 @@ msgstr ""
msgid "NetworkPolicies|Traffic that does not match any rule will be blocked." msgid "NetworkPolicies|Traffic that does not match any rule will be blocked."
msgstr "" msgstr ""
msgid "NetworkPolicies|Unable to parse policy"
msgstr ""
msgid "NetworkPolicies|YAML editor" msgid "NetworkPolicies|YAML editor"
msgstr "" msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment