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';
import PolicyRuleBuilder from './policy_rule_builder.vue';
import PolicyPreview from './policy_preview.vue';
import PolicyActionPicker from './policy_action_picker.vue';
import DimDisableContainer from './dim_disable_container.vue';
import {
EditorModeRule,
EditorModeYAML,
......@@ -46,6 +47,7 @@ export default {
PolicyRuleBuilder,
PolicyPreview,
PolicyActionPicker,
DimDisableContainer,
},
directives: { GlModal: GlModalDirective },
props: {
......@@ -249,11 +251,25 @@ export default {
<hr />
<div v-if="shouldShowRuleEditor" class="row" data-testid="rule-editor">
<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">{{
$options.parsingErrorMessage
}}</gl-alert>
<gl-alert
v-if="hasParsingError"
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>
<policy-rule-builder
v-for="(rule, idx) in policy.rules"
:key="idx"
......@@ -268,24 +284,47 @@ export default {
@remove="removeRule(idx)"
/>
<div class="gl-p-3 gl-rounded-base gl-border-1 gl-border-solid gl-border-gray-100 gl-mb-5">
<gl-button
variant="link"
category="primary"
data-testid="add-rule"
:disabled="hasParsingError"
@click="addRule"
>{{ s__('Network Policy|New rule') }}</gl-button
<div
class="gl-p-3 gl-rounded-base gl-border-1 gl-border-solid gl-border-gray-100 gl-mb-5"
>
<gl-button variant="link" category="primary" data-testid="add-rule" @click="addRule">{{
s__('Network Policy|New rule')
}}</gl-button>
</div>
</dim-disable-container>
<dim-disable-container data-testid="policy-action-container" :disabled="hasParsingError">
<template #title>
<h4>{{ s__('NetworkPolicies|Actions') }}</h4>
<p>{{ s__('NetworkPolicies|Traffic that does not match any rule will be blocked.') }}</p>
<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 class="col-sm-12 col-md-6 col-lg-5 col-xl-4">
<dim-disable-container data-testid="policy-preview-container" :disabled="hasParsingError">
<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 v-if="shouldShowYamlEditor" class="row" data-testid="yaml-editor">
......
---
title: Improve policy editor layout
merge_request: 42424
author:
type: changed
......@@ -153,9 +153,9 @@ exports[`PolicyEditorApp component renders the policy editor layout 1`] = `
>
<!---->
<h4>
Rules
</h4>
<dim-disable-container-stub
data-testid="rule-builder-container"
>
<div
class="gl-p-3 gl-rounded-base gl-border-1 gl-border-solid gl-border-gray-100 gl-mb-5"
......@@ -171,24 +171,22 @@ exports[`PolicyEditorApp component renders the policy editor layout 1`] = `
New rule
</gl-button-stub>
</div>
</dim-disable-container-stub>
<h4>
Actions
</h4>
<p>
Traffic that does not match any rule will be blocked.
</p>
<dim-disable-container-stub
data-testid="policy-action-container"
>
<policy-action-picker-stub />
</dim-disable-container-stub>
</div>
<div
class="col-sm-12 col-md-6 col-lg-5 col-xl-4"
>
<h5>
Policy preview
</h5>
<dim-disable-container-stub
data-testid="policy-preview-container"
>
<policy-preview-stub
initialtab="0"
......@@ -203,6 +201,7 @@ spec:
network-policy.gitlab.com/disabled_by: gitlab
"
/>
</dim-disable-container-stub>
</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', () => {
const findPolicyName = () => wrapper.find("[id='policyName']");
const findSavePolicy = () => wrapper.find("[data-testid='save-policy']");
const findDeletePolicy = () => wrapper.find("[data-testid='delete-policy']");
const findEditorModeToggle = () => wrapper.find("[data-testid='editor-mode']");
beforeEach(() => {
factory();
......@@ -189,7 +190,7 @@ spec:
it('updates yaml editor value on switch to yaml editor', async () => {
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();
const editor = findNetworkPolicyEditor();
......@@ -212,13 +213,21 @@ spec:
expect(findYAMLParsingAlert().exists()).toBe(true);
});
it('disables add rule button', () => {
expect(findAddRuleButton().props('disabled')).toBe(true);
it('disables rule builder', () => {
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 () => {
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();
const editor = findNetworkPolicyEditor();
......
......@@ -16799,6 +16799,9 @@ msgstr ""
msgid "NetworkPolicies|Traffic that does not match any rule will be blocked."
msgstr ""
msgid "NetworkPolicies|Unable to parse policy"
msgstr ""
msgid "NetworkPolicies|YAML editor"
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