Skip to content
Snippets Groups Projects
Commit eedf5c44 authored by Savas Vedova's avatar Savas Vedova Committed by Brandon Labuschagne
Browse files

Redesign new policy form

Implement the new design based on feedback received.

Changelog: changed
EE: true
parent 55e27263
No related branches found
No related tags found
1 merge request!77482Redesign new policy form
Showing
with 96 additions and 84 deletions
......@@ -4,7 +4,7 @@ import {
GlFormGroup,
GlFormInput,
GlFormTextarea,
GlToggle,
GlFormCheckbox,
GlButton,
GlAlert,
GlIcon,
......@@ -35,11 +35,9 @@ import PolicyRuleBuilder from './policy_rule_builder.vue';
export default {
EDITOR_MODES,
i18n: {
basicInformation: __('Basic information'),
actions: s__('SecurityOrchestration|Actions'),
addRule: s__('SecurityOrchestration|Add rule'),
defaultTrafficBehavior: s__(
'NetworkPolicies|Traffic that does not match any rule will be blocked.',
),
description: __('Description'),
toggleLabel: s__('SecurityOrchestration|Policy status'),
PARSING_ERROR_MESSAGE,
......@@ -49,7 +47,8 @@ export default {
),
noEnvironmentButton: __('Learn more'),
yamlPreview: s__('SecurityOrchestration|.yaml preview'),
policyPreview: s__('SecurityOrchestration|Policy preview'),
policySummary: s__('SecurityOrchestration|Policy summary'),
policyEnabled: __('Enabled'),
rules: s__('SecurityOrchestration|Rules'),
saveButtonTooltip: s__(
'NetworkPolicies|Network policy can be created after the environment is loaded successfully.',
......@@ -61,7 +60,7 @@ export default {
GlFormGroup,
GlFormInput,
GlFormTextarea,
GlToggle,
GlFormCheckbox,
GlButton,
GlAlert,
GlIcon,
......@@ -236,11 +235,15 @@ export default {
{{ $options.i18n.PARSING_ERROR_MESSAGE }}
</gl-alert>
<h5 class="gl-mt-0 gl-mb-5">
{{ $options.i18n.basicInformation }}
</h5>
<gl-form-group :label="$options.i18n.name" label-for="policyName">
<gl-form-input id="policyName" v-model="policy.name" :disabled="hasParsingError" />
</gl-form-group>
<gl-form-group :label="$options.i18n.description" label-for="policyDescription">
<gl-form-group :label="$options.i18n.description" label-for="policyDescription" optional>
<gl-form-textarea
id="policyDescription"
v-model="policy.description"
......@@ -248,13 +251,26 @@ export default {
/>
</gl-form-group>
<gl-form-group :disabled="hasParsingError" data-testid="policy-enable">
<gl-toggle v-model="policy.isEnabled" :label="$options.i18n.toggleLabel" />
<gl-form-group
:label="$options.i18n.toggleLabel"
:disabled="hasParsingError"
data-testid="policy-enable"
class="gl-mb-6"
>
<gl-form-checkbox id="policyStatus" v-model="policy.isEnabled">
{{ $options.i18n.policyEnabled }}
</gl-form-checkbox>
</gl-form-group>
<dim-disable-container data-testid="rule-builder-container" :disabled="hasParsingError">
<dim-disable-container
class="gl-mb-6"
data-testid="rule-builder-container"
:disabled="hasParsingError"
>
<template #title>
<h4>{{ $options.i18n.rules }}</h4>
<h5 class="gl-mt-0 gl-mb-5">
{{ $options.i18n.rules }}
</h5>
</template>
<template #disabled>
......@@ -277,58 +293,54 @@ export default {
@remove="removeRule(index)"
/>
<div
class="gl-p-5 gl-rounded-base gl-border-1 gl-border-solid gl-border-gray-100 gl-mb-5 gl-bg-gray-10"
>
<gl-button variant="link" data-testid="add-rule" icon="plus" @click="addRule">
{{ $options.i18n.addRule }}
</gl-button>
</div>
<gl-button variant="link" data-testid="add-rule" icon="plus" @click="addRule">
{{ $options.i18n.addRule }}
</gl-button>
</dim-disable-container>
<dim-disable-container data-testid="policy-action-container" :disabled="hasParsingError">
<dim-disable-container
class="gl-mb-6"
data-testid="policy-action-container"
:disabled="hasParsingError"
>
<template #title>
<h4>{{ $options.i18n.actions }}</h4>
<p>{{ $options.i18n.defaultTrafficBehavior }}</p>
<h5 class="gl-mt-0 gl-mb-5">{{ $options.i18n.actions }}</h5>
</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>
<div class="gl-bg-gray-10 gl-p-6"></div>
</template>
<policy-action-picker />
<policy-alert-picker :policy-alert="policyAlert" @update-alert="handleAlertUpdate" />
</dim-disable-container>
</template>
<template #rule-editor-preview>
<h5>{{ $options.i18n.yamlPreview }}</h5>
<pre
data-testid="yaml-preview"
class="gl-bg-white gl-border-none gl-p-0"
:class="{ 'gl-opacity-5': hasParsingError }"
>{{ policyYaml || yamlEditorValue }}</pre
>
</template>
<template v-if="!hasParsingError" #bottom>
<div class="gl-my-6">
<div v-if="!hasParsingError" class="gl-my-6">
<gl-button
v-collapse-toggle="$options.policyPreviewHumanCollapseId"
category="tertiary"
class="gl-font-weight-bold gl-bg-transparent! gl-px-0!"
>
{{ $options.i18n.policyPreview }}
{{ $options.i18n.policySummary }}
<gl-icon :name="isPolicyPreviewHumanVisible ? 'angle-up' : 'angle-down'" :size="12" />
</gl-button>
<gl-collapse
:id="$options.policyPreviewHumanCollapseId"
v-model="isPolicyPreviewHumanVisible"
>
<policy-preview-human class="gl-md-w-70p" :policy-description="humanizedPolicy" />
<policy-preview-human :policy-description="humanizedPolicy" />
</gl-collapse>
</div>
</template>
<template #rule-editor-preview>
<h5>{{ $options.i18n.yamlPreview }}</h5>
<pre
data-testid="yaml-preview"
class="gl-border-none gl-p-0"
:class="{ 'gl-opacity-5': hasParsingError }"
>{{ policyYaml || yamlEditorValue }}</pre
>
</template>
</policy-editor-layout>
<gl-empty-state
v-else
......
......@@ -132,13 +132,11 @@ export default {
</script>
<template>
<div
class="gl-bg-gray-10 gl-border-solid gl-border-1 gl-border-gray-100 gl-rounded-base px-3 pt-3 gl-relative"
>
<gl-form inline @submit.prevent>
<div class="gl-bg-gray-10 gl-px-3 gl-pt-3 gl-relative gl-display-flex">
<gl-form class="gl-flex-grow-1" inline @submit.prevent>
<gl-sprintf :message="sprintfTemplate">
<template #ifLabel="{ content }">
<label for="ruleType" class="text-uppercase gl-font-lg gl-mr-4 gl-mb-5!">{{
<label for="ruleType" class="text-uppercase gl-font-lg gl-mr-4 gl-mb-3!">{{
content
}}</label>
</template>
......@@ -146,14 +144,14 @@ export default {
<template #ruleType>
<gl-form-select
id="ruleType"
class="gl-mr-4 gl-mb-5"
class="gl-mr-4 gl-mb-3"
:value="ruleType"
:options="$options.ruleTypes"
/>
</template>
<template #isLabel="{ content }">
<label for="direction" class="gl-mr-4 gl-mb-5! gl-font-weight-normal">{{
<label for="direction" class="gl-mr-4 gl-mb-3! gl-font-weight-normal">{{
content
}}</label>
</template>
......@@ -163,7 +161,7 @@ export default {
<gl-form-select
id="direction"
v-model="rule.direction"
class="gl-mr-4 gl-mb-5"
class="gl-mr-4 gl-mb-3"
:options="$options.trafficDirections"
/>
<!-- eslint-enable vue/no-mutating-props -->
......@@ -172,7 +170,7 @@ export default {
<template #ruleSelector>
<gl-form-select
data-testid="endpoint-match-mode"
class="gl-mr-4 gl-mb-5"
class="gl-mr-4 gl-mb-3"
:value="endpointMatchMode"
:disabled="endpointSelectorDisabled"
:options="$options.endpointMatchModes"
......@@ -183,7 +181,7 @@ export default {
<gl-form-input
v-if="shouldShowEndpointLabels"
data-testid="endpoint-labels"
class="gl-mr-4 gl-mb-5 gl-bg-white!"
class="gl-mr-4 gl-mb-3 gl-bg-white!"
placeholder="key:value"
:value="endpointLabels"
:disabled="endpointSelectorDisabled"
......@@ -193,23 +191,23 @@ export default {
</template>
<template #directionLabel="{ content }">
<label for="ruleMode" class="gl-mr-4 gl-mb-5! gl-font-weight-normal">{{ content }}</label>
<label for="ruleMode" class="gl-mr-4 gl-mb-3! gl-font-weight-normal">{{ content }}</label>
</template>
<template #rule>
<gl-form-select
id="ruleMode"
class="gl-mr-4 gl-mb-5"
class="gl-mr-4 gl-mb-3"
:value="rule.ruleType"
:options="$options.ruleModes"
@change="$emit('rule-type-change', $event)"
/>
<component :is="ruleComponentName" v-model="ruleComponentModel" class="gl-mr-4 gl-mb-5" />
<component :is="ruleComponentName" v-model="ruleComponentModel" class="gl-mr-4 gl-mb-3" />
</template>
<template #portsLabel="{ content }">
<label for="portMatch" class="gl-mr-4 gl-mb-5! gl-font-weight-normal">{{
<label for="portMatch" class="gl-mr-4 gl-mb-3! gl-font-weight-normal">{{
content
}}</label>
</template>
......@@ -219,7 +217,7 @@ export default {
<gl-form-select
id="portMatch"
v-model="rule.portMatchMode"
class="gl-mr-4 gl-mb-5"
class="gl-mr-4 gl-mb-3"
:options="$options.portMatchModes"
/>
<!-- placeholder is the same in all languages-->
......@@ -228,7 +226,7 @@ export default {
v-if="shouldShowPorts"
v-model="rule.ports"
data-testid="ports"
class="gl-mr-4 gl-mb-5 gl-bg-white!"
class="gl-mr-4 gl-mb-3 gl-bg-white!"
placeholder="80/tcp"
/>
<!-- eslint-enable @gitlab/vue-require-i18n-attribute-strings -->
......@@ -236,11 +234,10 @@ export default {
</template>
</gl-sprintf>
</gl-form>
<gl-button
icon="remove"
category="tertiary"
class="gl-absolute gl-top-3 gl-right-3"
class="gl-align-self-start gl-ml-3"
:aria-label="__('Remove')"
data-testid="remove-rule"
@click="$emit('remove')"
......
......@@ -17,9 +17,7 @@ export default {
</script>
<template>
<div
class="gl-bg-gray-10 gl-border-solid gl-border-1 gl-border-gray-100 gl-rounded-base gl-px-5 gl-pt-5"
>
<div class="gl-bg-gray-10 gl-px-5 gl-pt-5">
<gl-form inline>
<gl-sprintf
:message="
......
<script>
import { GlAlert, GlFormGroup, GlFormSelect } from '@gitlab/ui';
import { s__ } from '~/locale';
import { POLICY_TYPE_COMPONENT_OPTIONS } from '../constants';
import EnvironmentPicker from '../environment_picker.vue';
import NetworkPolicyEditor from './network_policy/network_policy_editor.vue';
......@@ -66,6 +67,9 @@ export default {
this.newPolicyType = type;
},
},
i18n: {
title: s__('SecurityOrchestration|Policy description'),
},
};
</script>
......@@ -75,7 +79,7 @@ export default {
{{ error }}
</gl-alert>
<header class="gl-pb-5">
<h3>{{ s__('SecurityOrchestration|Policy description') }}</h3>
<h3>{{ $options.i18n.title }}</h3>
</header>
<div class="gl-display-flex">
<gl-form-group :label="s__('SecurityOrchestration|Policy type')" label-for="policyType">
......
<script>
import {
GlButton,
GlFormGroup,
GlModal,
GlModalDirective,
GlSegmentedControl,
......@@ -16,7 +15,6 @@ export default {
},
components: {
GlButton,
GlFormGroup,
GlModal,
GlSegmentedControl,
PolicyYamlEditor: () =>
......@@ -127,19 +125,17 @@ export default {
</script>
<template>
<section>
<div class="gl-mb-5 gl-border-1 gl-border-solid gl-border-gray-100 gl-rounded-base">
<gl-form-group
class="gl-px-5 gl-py-3 gl-mb-0 gl-bg-gray-10 gl-border-b-solid gl-border-b-gray-100 gl-border-b-1 gl-rounded-top-base"
>
<section class="gl-mt-6">
<div class="gl-mb-5">
<div class="gl-border-b-solid gl-border-b-1 gl-border-gray-100 gl-mb-6 gl-pb-6">
<gl-segmented-control
:options="editorModes"
:checked="selectedEditorMode"
@input="updateEditorMode"
/>
</gl-form-group>
</div>
<div class="gl-display-flex gl-sm-flex-direction-column">
<section class="gl-w-full" :class="{ 'gl-p-5': shouldShowRuleEditor }">
<section class="gl-w-full gl-mr-7">
<div v-if="shouldShowRuleEditor" data-testid="rule-editor">
<slot name="rule-editor"></slot>
</div>
......@@ -153,7 +149,7 @@ export default {
</section>
<section
v-if="shouldShowRuleEditor"
class="gl-md-w-50p gl-md-max-w-30p gl-p-5 gl-border-l-gray-100 gl-border-l-1 gl-md-border-l-solid"
class="gl-md-w-50p gl-md-max-w-30p gl-p-5 gl-bg-gray-10 gl-ml-11 gl-align-self-start"
data-testid="rule-editor-preview"
>
<slot name="rule-editor-preview"></slot>
......
......@@ -27,7 +27,7 @@ export default {
<div
v-if="policyDescription"
v-safe-html:[$options.safeHtmlConfig]="policyDescription"
class="gl-bg-white gl-rounded-base gl-py-3 gl-px-4 gl-border-1 gl-border-solid gl-border-gray-100"
class="gl-bg-gray-10 gl-py-3 gl-px-4"
></div>
<div v-else>
<gl-alert variant="info" :dismissible="false">
......
......@@ -2,7 +2,7 @@
exports[`PolicyActionPicker component renders policy action picker 1`] = `
<div
class="gl-bg-gray-10 gl-border-solid gl-border-1 gl-border-gray-100 gl-rounded-base gl-px-5 gl-pt-5"
class="gl-bg-gray-10 gl-px-5 gl-pt-5"
>
<gl-form-stub
inline=""
......
import { GlEmptyState, GlToggle } from '@gitlab/ui';
import { GlEmptyState, GlFormCheckbox, GlFormGroup } from '@gitlab/ui';
import { EDITOR_MODE_YAML } from 'ee/threat_monitoring/components/policy_editor/constants';
import DimDisableContainer from 'ee/threat_monitoring/components/policy_editor/dim_disable_container.vue';
import {
......@@ -65,7 +65,11 @@ describe('NetworkPolicyEditor component', () => {
...provide,
},
store,
stubs: { DimDisableContainer, PolicyYamlEditor: true, transition: stubTransition() },
stubs: {
DimDisableContainer,
PolicyYamlEditor: true,
transition: stubTransition(),
},
});
};
......@@ -82,7 +86,7 @@ describe('NetworkPolicyEditor component', () => {
const findPolicyEditorLayout = () => wrapper.findComponent(PolicyEditorLayout);
const findCollapseToggle = () =>
wrapper.findByRole('button', {
name: NetworkPolicyEditor.i18n.policyPreview,
name: NetworkPolicyEditor.i18n.policySummary,
});
const modifyPolicyAlert = async ({ isAlertEnabled }) => {
......@@ -96,11 +100,12 @@ describe('NetworkPolicyEditor component', () => {
wrapper.destroy();
});
it('renders toggle with label', () => {
it('renders checkbox with label', () => {
factory();
const policyEnableToggle = findPolicyEnableContainer().findComponent(GlToggle);
expect(policyEnableToggle.exists()).toBe(true);
expect(policyEnableToggle.props('label')).toBe(NetworkPolicyEditor.i18n.toggleLabel);
expect(findPolicyEnableContainer().findComponent(GlFormGroup).attributes('label')).toBe(
NetworkPolicyEditor.i18n.toggleLabel,
);
expect(findPolicyEnableContainer().findComponent(GlFormCheckbox).exists()).toBe(true);
});
it('disables the tooltip and enables the save button', () => {
......
......@@ -5370,6 +5370,9 @@ msgstr ""
msgid "Based on"
msgstr ""
 
msgid "Basic information"
msgstr ""
msgid "Be careful. Changing the project's namespace can have unintended side effects."
msgstr ""
 
......@@ -23550,9 +23553,6 @@ msgstr ""
msgid "NetworkPolicies|To enable alerts, %{installLinkStart}install an agent%{installLinkEnd} first."
msgstr ""
 
msgid "NetworkPolicies|Traffic that does not match any rule will be blocked."
msgstr ""
msgid "NetworkPolicies|all DNS names"
msgstr ""
 
......@@ -31681,10 +31681,10 @@ msgstr ""
msgid "SecurityOrchestration|Policy editor"
msgstr ""
 
msgid "SecurityOrchestration|Policy preview"
msgid "SecurityOrchestration|Policy status"
msgstr ""
 
msgid "SecurityOrchestration|Policy status"
msgid "SecurityOrchestration|Policy summary"
msgstr ""
 
msgid "SecurityOrchestration|Policy type"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment