From 8909b8bed22f097ff8c90955bb9baf284a1d1b0e Mon Sep 17 00:00:00 2001 From: Artur Fedorov <afedorov@gitlab.com> Date: Thu, 3 Oct 2024 00:30:04 +0000 Subject: [PATCH] This MR changes layout of filters New combined layout for status filters for approval policies Changelog: changed EE: true --- .../scan_filters/runner_tags_filter.vue | 2 +- .../action/scan_filters/template_selector.vue | 6 +- .../rule/license_scan_rule_builder.vue | 6 +- .../rule/scan_filters/age_filter.vue | 4 +- .../rule/scan_filters/attribute_filters.vue | 14 ++-- .../rule/scan_filters/license_filter.vue | 4 +- .../rule/scan_filters/severity_filter.vue | 4 +- .../rule/scan_filters/status_filter.vue | 16 +++- .../rule/scan_filters/status_filters.vue | 73 +++++++++++++------ .../policy_editor/section_layout.vue | 12 ++- .../rule/scan_filters/status_filters_spec.js | 13 ++++ .../policy_editor/section_layout_spec.js | 7 +- 12 files changed, 121 insertions(+), 40 deletions(-) diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/runner_tags_filter.vue b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/runner_tags_filter.vue index 7531febae818f..6347d4071584c 100644 --- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/runner_tags_filter.vue +++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/runner_tags_filter.vue @@ -42,7 +42,7 @@ export default { <template> <section-layout class="gl-w-full gl-bg-white" :show-remove-button="false"> <template #selector> - <label class="gl-mb-0 gl-mr-4" for="policy-tags" :title="$options.i18n.label"> + <label class="gl-mb-0 gl-mr-4 gl-font-normal" for="policy-tags" :title="$options.i18n.label"> {{ $options.i18n.label }} </label> </template> diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/template_selector.vue b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/template_selector.vue index fad4a9e291992..234752050143b 100644 --- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/template_selector.vue +++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_execution/action/scan_filters/template_selector.vue @@ -61,7 +61,11 @@ export default { :show-remove-button="false" > <template #selector> - <label class="gl-mb-0 gl-mr-4" for="policy-template" :title="$options.i18n.label"> + <label + class="gl-mb-0 gl-mr-4 gl-font-normal" + for="policy-template" + :title="$options.i18n.label" + > {{ $options.i18n.label }} </label> </template> diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/license_scan_rule_builder.vue b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/license_scan_rule_builder.vue index b831108089882..820cfc0191544 100644 --- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/license_scan_rule_builder.vue +++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/license_scan_rule_builder.vue @@ -118,7 +118,11 @@ export default { <section-layout class="gl-pr-0 gl-pt-3" :show-remove-button="false"> <template #content> - <status-filter :show-remove-button="false" class="!gl-bg-white"> + <status-filter + :show-remove-button="false" + class="!gl-bg-white md:gl-items-center" + label-classes="!gl-text-base !gl-w-12 !gl-pl-0" + > <rule-multi-select v-model="licenseStatuses" class="!gl-inline gl-align-middle" diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/age_filter.vue b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/age_filter.vue index 1ca28949032ad..3ff43d4fd328e 100644 --- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/age_filter.vue +++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/age_filter.vue @@ -67,7 +67,9 @@ export default { @remove="remove" > <template #selector> - <label class="gl-mb-0" :title="$options.i18n.label">{{ $options.i18n.label }}</label> + <label class="gl-mb-0 gl-font-normal" :title="$options.i18n.label">{{ + $options.i18n.label + }}</label> <number-range-select id="vulnerability-age-select" :value="value" diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/attribute_filters.vue b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/attribute_filters.vue index f4db2b9026819..fb6a675a14fcb 100644 --- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/attribute_filters.vue +++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/attribute_filters.vue @@ -61,12 +61,14 @@ export default { @remove="removeFilter" > <template #label> - <label v-if="idx === 0" v-gl-tooltip class="gl-mb-0" :title="$options.i18n.labelTooltip">{{ - $options.i18n.label - }}</label> - <label v-else class="gl-mb-0 gl-w-11 gl-font-normal gl-uppercase">{{ - $options.i18n.andOperator - }}</label> + <label + v-if="idx === 0" + v-gl-tooltip + class="gl-mb-0 gl-font-normal" + :title="$options.i18n.labelTooltip" + >{{ $options.i18n.label }}</label + > + <label v-else class="gl-mb-0 gl-w-11 gl-font-normal">{{ $options.i18n.andOperator }}</label> </template> </attribute-filter> </div> diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/license_filter.vue b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/license_filter.vue index 281154c1665b6..92778bc62db3f 100644 --- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/license_filter.vue +++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/license_filter.vue @@ -117,7 +117,9 @@ export default { <template> <section-layout class="gl-w-full gl-pt-3" :show-remove-button="false"> <template #selector> - <label class="gl-mb-0 gl-mr-4" :title="$options.i18n.label">{{ $options.i18n.label }}</label> + <label class="gl-mb-0 gl-mr-4 gl-font-normal" :title="$options.i18n.label">{{ + $options.i18n.label + }}</label> <slot> <gl-collapsible-listbox v-model="matchType" diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/severity_filter.vue b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/severity_filter.vue index 7fa654505411f..7adf383dc3e00 100644 --- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/severity_filter.vue +++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/severity_filter.vue @@ -33,7 +33,9 @@ export default { <template> <section-layout class="gl-w-full" :show-remove-button="false"> <template #selector> - <label class="gl-mb-0 gl-mr-2" :title="$options.i18n.label">{{ $options.i18n.label }}</label> + <label class="gl-mb-0 gl-mr-2 gl-font-normal" :title="$options.i18n.label">{{ + $options.i18n.label + }}</label> <rule-multi-select :value="selected" :item-type-name="$options.i18n.severityLevels" diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/status_filter.vue b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/status_filter.vue index 80d07f983c1ad..3b26d5c728149 100644 --- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/status_filter.vue +++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/status_filter.vue @@ -15,7 +15,6 @@ export default { APPROVAL_VULNERABILITY_STATE_GROUPS, APPROVAL_VULNERABILITY_STATES, i18n: { - label: s__('ScanResultPolicy|Status is:'), headerText: __('Choose an option'), vulnerabilityStates: s__('ScanResultPolicy|vulnerability states'), }, @@ -46,6 +45,16 @@ export default { required: false, default: true, }, + label: { + type: String, + required: false, + default: s__('ScanResultPolicy|Status is:'), + }, + labelClasses: { + type: String, + required: false, + default: '', + }, }, data() { return { @@ -82,11 +91,12 @@ export default { <section-layout :key="filter" class="gl-w-full gl-bg-white gl-pr-2" + :rule-label="label" + :label-classes="labelClasses" :show-remove-button="showRemoveButton" @remove="remove" > - <template #selector> - <label class="gl-mb-0 gl-mr-5" :title="$options.i18n.label">{{ $options.i18n.label }}</label> + <template #content> <slot> <gl-collapsible-listbox :header-text="$options.i18n.headerText" diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/status_filters.vue b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/status_filters.vue index 7ad9ecd60925b..2c97a12341e08 100644 --- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/status_filters.vue +++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/status_filters.vue @@ -1,13 +1,20 @@ <script> +import { __, s__ } from '~/locale'; +import SectionLayout from 'ee/security_orchestration/components/policy_editor/section_layout.vue'; import StatusFilter from './status_filter.vue'; import { DEFAULT_VULNERABILITY_STATES, NEWLY_DETECTED, PREVIOUSLY_EXISTING } from './constants'; export default { NEWLY_DETECTED, PREVIOUSLY_EXISTING, + i18n: { + secondFilterLabel: __('or'), + firstFilterLabel: s__('ScanResultPolicy|Status is:'), + }, name: 'StatusFilters', components: { StatusFilter, + SectionLayout, }, props: { filters: { @@ -22,9 +29,17 @@ export default { }, }, computed: { + allFiltersSelected() { + return this.filters[PREVIOUSLY_EXISTING] && this.filters[NEWLY_DETECTED]; + }, selectionDisabled() { return Boolean(this.filters[NEWLY_DETECTED] && this.filters[PREVIOUSLY_EXISTING]); }, + secondFilterLabel() { + return this.allFiltersSelected + ? this.$options.i18n.secondFilterLabel + : this.$options.i18n.firstFilterLabel; + }, }, methods: { isFilterSelected(filter) { @@ -58,26 +73,40 @@ export default { </script> <template> - <div class="gl-flex gl-w-full gl-flex-col gl-gap-3"> - <status-filter - v-if="isFilterSelected($options.NEWLY_DETECTED)" - :disabled="selectionDisabled" - :show-remove-button="selectionDisabled" - :filter="$options.NEWLY_DETECTED" - :selected="selected[$options.NEWLY_DETECTED]" - @input="setStatuses($event, $options.NEWLY_DETECTED)" - @change-group="setStatusFilter" - @remove="removeFilter" - /> - <status-filter - v-if="isFilterSelected($options.PREVIOUSLY_EXISTING)" - :disabled="selectionDisabled" - :show-remove-button="selectionDisabled" - :filter="$options.PREVIOUSLY_EXISTING" - :selected="selected[$options.PREVIOUSLY_EXISTING]" - @input="setStatuses($event, $options.PREVIOUSLY_EXISTING)" - @change-group="setStatusFilter" - @remove="removeFilter" - /> - </div> + <section-layout + :show-remove-button="false" + class="gl-w-full gl-bg-white !gl-p-0" + content-classes="!gl-gap-0" + > + <template #content> + <status-filter + v-if="isFilterSelected($options.NEWLY_DETECTED)" + :disabled="selectionDisabled" + :show-remove-button="selectionDisabled" + :filter="$options.NEWLY_DETECTED" + :selected="selected[$options.NEWLY_DETECTED]" + :label="$options.i18n.firstFilterLabel" + :class="{ 'gl-pb-3': allFiltersSelected }" + label-classes="!gl-text-base !gl-w-10 md:!gl-w-12 !gl-pl-0" + class="gl-w-full gl-bg-white md:gl-items-center" + @input="setStatuses($event, $options.NEWLY_DETECTED)" + @change-group="setStatusFilter" + @remove="removeFilter" + /> + <status-filter + v-if="isFilterSelected($options.PREVIOUSLY_EXISTING)" + :disabled="selectionDisabled" + :show-remove-button="selectionDisabled" + :filter="$options.PREVIOUSLY_EXISTING" + :label="secondFilterLabel" + :selected="selected[$options.PREVIOUSLY_EXISTING]" + label-classes="!gl-text-base !gl-w-12 !gl-pl-0" + class="gl-w-full md:gl-items-center" + :class="{ 'gl-pt-2': allFiltersSelected }" + @input="setStatuses($event, $options.PREVIOUSLY_EXISTING)" + @change-group="setStatusFilter" + @remove="removeFilter" + /> + </template> + </section-layout> </template> diff --git a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/section_layout.vue b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/section_layout.vue index 30b0e3739167a..df678faf8989d 100644 --- a/ee/app/assets/javascripts/security_orchestration/components/policy_editor/section_layout.vue +++ b/ee/app/assets/javascripts/security_orchestration/components/policy_editor/section_layout.vue @@ -22,11 +22,19 @@ export default { required: false, default: true, }, + labelClasses: { + type: String, + required: false, + default: '', + }, }, computed: { contentClass() { return `gl-grow gl-w-full gl-flex gl-gap-3 gl-items-center gl-flex-wrap ${this.contentClasses}`; }, + labelClass() { + return `gl-w-6 !gl-font-normal gl-mb-0 gl-text-lg ${this.labelClasses}`; + }, showLabel() { return Boolean(this.ruleLabel); }, @@ -36,8 +44,8 @@ export default { <template> <div class="security-policies-bg-gray-10 gl-flex gl-gap-3 gl-rounded-base gl-p-5"> - <div v-if="showLabel" class="gl-min-w-7"> - <label data-testid="base-label" for="content" class="gl-w-6 gl-pl-2 gl-text-lg gl-uppercase"> + <div v-if="showLabel" class="gl-min-w-10 md:gl-min-w-7"> + <label data-testid="base-label" for="content" :class="labelClass"> {{ ruleLabel }} </label> </div> diff --git a/ee/spec/frontend/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/status_filters_spec.js b/ee/spec/frontend/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/status_filters_spec.js index 1b5f48d177831..ef5cde53624e3 100644 --- a/ee/spec/frontend/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/status_filters_spec.js +++ b/ee/spec/frontend/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/status_filters_spec.js @@ -124,4 +124,17 @@ describe('StatusFilters', () => { expect(wrapper.emitted('remove')).toContainEqual([PREVIOUSLY_EXISTING]); }); }); + + describe('custom label and css class', () => { + it('add custom padding when all filters selected', () => { + createComponent({ + filters: filtersBoth, + }); + + expect(findStatusFilters().at(0).classes()).toContain('gl-pb-3'); + expect(findStatusFilters().at(1).classes()).toContain('gl-pt-2'); + + expect(findStatusFilters().at(1).props('label')).toBe('or'); + }); + }); }); diff --git a/ee/spec/frontend/security_orchestration/components/policy_editor/section_layout_spec.js b/ee/spec/frontend/security_orchestration/components/policy_editor/section_layout_spec.js index 07771880271dc..33ac5e6ac68cd 100644 --- a/ee/spec/frontend/security_orchestration/components/policy_editor/section_layout_spec.js +++ b/ee/spec/frontend/security_orchestration/components/policy_editor/section_layout_spec.js @@ -43,8 +43,13 @@ describe('SectionLayout', () => { describe('with custom props', () => { it('renders with custom CSS class', () => { const CUSTOM_CLASS = 'custom-class'; - createComponent({ contentClasses: CUSTOM_CLASS }); + createComponent({ + contentClasses: CUSTOM_CLASS, + labelClasses: CUSTOM_CLASS, + ruleLabel: 'label', + }); expect(findContent().attributes('class')).toContain(CUSTOM_CLASS); + expect(findBaseLayoutLabel().attributes('class')).toContain(CUSTOM_CLASS); }); it('displays the label', () => { -- GitLab