Commit d215c54b authored by Mark Florian's avatar Mark Florian

Merge branch 'network-policy-editor-fixes' into 'master'

Network policy editor fixes

See merge request gitlab-org/gitlab!42424
parents 8e4e69cd 96334aba
<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: {
......@@ -146,7 +148,7 @@ export default {
}
},
changeEditorMode(mode) {
if (mode === EditorModeYAML) {
if (mode === EditorModeYAML && !this.hasParsingError) {
this.yamlEditorValue = toYaml(this.policy);
}
......@@ -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">
......
......@@ -152,7 +152,9 @@ export default {
</template>
<template #isLabel="{ content }">
<label for="direction" class="gl-mr-4 gl-mb-5!">{{ content }}</label>
<label for="direction" class="gl-mr-4 gl-mb-5! gl-font-weight-normal">{{
content
}}</label>
</template>
<template #ruleDirection>
......@@ -178,7 +180,7 @@ export default {
<gl-form-input
v-if="shouldShowEndpointLabels"
data-testid="endpoint-labels"
class="gl-mr-4 gl-mb-5"
class="gl-mr-4 gl-mb-5 gl-bg-white!"
placeholder="key:value"
:value="endpointLabels"
:disabled="endpointSelectorDisabled"
......@@ -188,7 +190,7 @@ export default {
</template>
<template #directionLabel="{ content }">
<label for="ruleMode" class="gl-mr-4 gl-mb-5!">{{ content }}</label>
<label for="ruleMode" class="gl-mr-4 gl-mb-5! gl-font-weight-normal">{{ content }}</label>
</template>
<template #rule>
......@@ -204,7 +206,9 @@ export default {
</template>
<template #portsLabel="{ content }">
<label for="portMatch" class="gl-mr-4 gl-mb-5!">{{ content }}</label>
<label for="portMatch" class="gl-mr-4 gl-mb-5! gl-font-weight-normal">{{
content
}}</label>
</template>
<template #ports>
......@@ -220,7 +224,7 @@ export default {
v-if="shouldShowPorts"
v-model="rule.ports"
data-testid="ports"
class="gl-mr-4 gl-mb-5"
class="gl-mr-4 gl-mb-5 gl-bg-white!"
placeholder="80/tcp"
/>
<!-- eslint-enable @gitlab/vue-require-i18n-attribute-strings -->
......
......@@ -17,6 +17,11 @@ export default {
<template>
<!-- placeholder is the same in all languages-->
<!-- eslint-disable @gitlab/vue-require-i18n-attribute-strings -->
<gl-form-input placeholder="0.0.0.0/24" :value="value" @input="$emit('input', $event)" />
<gl-form-input
class="gl-bg-white!"
placeholder="0.0.0.0/24"
:value="value"
@input="$emit('input', $event)"
/>
<!-- eslint-enable @gitlab/vue-require-i18n-attribute-strings -->
</template>
......@@ -17,6 +17,11 @@ export default {
<template>
<!-- placeholder is the same in all languages-->
<!-- eslint-disable @gitlab/vue-require-i18n-attribute-strings -->
<gl-form-input placeholder="key:value" :value="value" @input="$emit('input', $event)" />
<gl-form-input
class="gl-bg-white!"
placeholder="key:value"
:value="value"
@input="$emit('input', $event)"
/>
<!-- eslint-enable @gitlab/vue-require-i18n-attribute-strings -->
</template>
......@@ -17,6 +17,11 @@ export default {
<template>
<!-- placeholder is the same in all languages-->
<!-- eslint-disable @gitlab/vue-require-i18n-attribute-strings -->
<gl-form-input placeholder="remote-service.com" :value="value" @input="$emit('input', $event)" />
<gl-form-input
class="gl-bg-white!"
placeholder="remote-service.com"
:value="value"
@input="$emit('input', $event)"
/>
<!-- eslint-enable @gitlab/vue-require-i18n-attribute-strings -->
</template>
---
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,8 +213,26 @@ 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');
findEditorModeToggle().vm.$emit('input', EditorModeYAML);
await wrapper.vm.$nextTick();
const editor = findNetworkPolicyEditor();
expect(editor.exists()).toBe(true);
expect(editor.props('value')).toEqual('');
});
});
......
......@@ -16814,6 +16814,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