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 7531febae818f765a895b39b82b4f5cb91f6370b..6347d4071584c1b05e5d0510f158f2687e8fca6c 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 fad4a9e291992a6c8a022a4a1aa063be34d6b501..234752050143bc91d828c4892b324ff97aad4a17 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 b8311080898828f520770a5922c3591d4224e919..820cfc01915444d6c6c013e248c68d04eaa8da8c 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 1ca28949032ad288ef2d4e245089ea59d406c9ac..3ff43d4fd328e31531c5fcbd56d8e00ab4cdf06a 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 f4db2b9026819d56445e76e5928a1dd242acbcc0..fb6a675a14fcb76a3e446feb583bee7596d04372 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 281154c1665b6b2a456f022589dcea6d596a10a9..92778bc62db3f9db3f6ac13c8c12015036e3aefd 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 7fa654505411fe9d3c97d4ac1f02ca3a7a66821f..7adf383dc3e00a6c57271e3c70040ca437418792 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 80d07f983c1ad40976df87513cf31ec52747457f..3b26d5c728149ec74703952529d6957589b8c20b 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 7ad9ecd60925b6c0c7c5c809f032afbfe813ca81..2c97a12341e08c07d3cd06713dd2dfc90149e345 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 30b0e3739167ab64cc8a54418eb337d1cbf847df..df678faf8989d4c85522dac1eaa2421077576c66 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 1b5f48d17783184dda8739c4645836f79f69891d..ef5cde53624e3173d194a3e8f57faa5e5274e97d 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 07771880271dc1158b22f8098728dad1a36a5e00..33ac5e6ac68cd782991072bbd359a69e834fd407 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', () => {