Skip to content
代码片段 群组 项目
提交 85672022 编辑于 作者: Himanshu Kapoor's avatar Himanshu Kapoor
浏览文件

Merge branch '422328-add-compliance-framework-sidebar' into 'master'

Add projects to compliance framework sidebar

See merge request https://gitlab.com/gitlab-org/gitlab/-/merge_requests/135634



Merged-by: default avatarHimanshu Kapoor <info@fleon.org>
Approved-by: default avatarJay Montal <jmontal@gitlab.com>
Approved-by: default avatarCamellia X Yang <xyang@gitlab.com>
Approved-by: default avatarHimanshu Kapoor <info@fleon.org>
Reviewed-by: default avatarJay Montal <jmontal@gitlab.com>
Co-authored-by: default avatarnrosandich <nrosandich@gitlab.com>
No related branches found
No related tags found
无相关合并请求
<script> <script>
import { GlDrawer, GlButton, GlLabel } from '@gitlab/ui'; import {
GlDrawer,
GlButton,
GlLabel,
GlLink,
GlAccordion,
GlAccordionItem,
GlTruncate,
} from '@gitlab/ui';
import { s__ } from '~/locale';
import { DRAWER_Z_INDEX } from '~/lib/utils/constants'; import { DRAWER_Z_INDEX } from '~/lib/utils/constants';
import { getContentWrapperHeight } from '~/lib/utils/dom_utils'; import { getContentWrapperHeight } from '~/lib/utils/dom_utils';
...@@ -9,6 +18,10 @@ export default { ...@@ -9,6 +18,10 @@ export default {
GlDrawer, GlDrawer,
GlButton, GlButton,
GlLabel, GlLabel,
GlLink,
GlAccordion,
GlAccordionItem,
GlTruncate,
}, },
props: { props: {
framework: { framework: {
...@@ -31,8 +44,17 @@ export default { ...@@ -31,8 +44,17 @@ export default {
defaultFramework() { defaultFramework() {
return Boolean(this.framework.default); return Boolean(this.framework.default);
}, },
associatedProjectsTitle() {
return `${this.$options.i18n.associatedProjects} (${this.framework.associatedProjects.length})`;
},
}, },
DRAWER_Z_INDEX, DRAWER_Z_INDEX,
i18n: {
defaultFramework: s__('ComplianceFrameworksReport|Default'),
editFramework: s__('ComplianceFrameworksReport|Edit framework'),
frameworkDescription: s__('ComplianceFrameworksReport|Description'),
associatedProjects: s__('ComplianceFrameworksReport|Associated Projects'),
},
}; };
</script> </script>
...@@ -44,13 +66,13 @@ export default { ...@@ -44,13 +66,13 @@ export default {
@close="$emit('close')" @close="$emit('close')"
> >
<template v-if="framework" #title> <template v-if="framework" #title>
<div> <div style="max-width: 350px">
<h2 class="gl-mt-0"> <h2 class="gl-mt-0">
{{ framework.name }} <gl-truncate :text="framework.name" with-tooltip />
<gl-label <gl-label
v-if="defaultFramework" v-if="defaultFramework"
:background-color="framework.color" :background-color="framework.color"
:title="s__('ComplianceFrameworksReport|Default')" :title="$options.i18n.defaultFramework"
size="sm" size="sm"
/> />
</h2> </h2>
...@@ -60,16 +82,27 @@ export default { ...@@ -60,16 +82,27 @@ export default {
variant="confirm" variant="confirm"
@click="$emit('edit', framework)" @click="$emit('edit', framework)"
> >
{{ s__('ComplianceFrameworksReport|Edit framework') }} {{ $options.i18n.editFramework }}
</gl-button> </gl-button>
</div> </div>
</template> </template>
<template v-if="framework" #default> <template v-if="framework" #default>
<div> <div>
<h4 class="gl-mt-0"> <gl-accordion :auto-collapse="false" :header-level="3">
{{ s__('ComplianceFrameworksReport|Associated Projects') }} <gl-accordion-item :title="$options.i18n.frameworkDescription" visible :header-level="2">
</h4> {{ framework.description }}
</gl-accordion-item>
<gl-accordion-item :title="associatedProjectsTitle">
<div
v-for="associatedProject in framework.associatedProjects"
:key="associatedProject.id"
class="gl-m-2"
>
<gl-link :href="associatedProject.webUrl">{{ associatedProject.name }}</gl-link>
</div>
</gl-accordion-item>
</gl-accordion>
</div> </div>
</template> </template>
</gl-drawer> </gl-drawer>
......
...@@ -86,8 +86,8 @@ export default { ...@@ -86,8 +86,8 @@ export default {
{ {
key: 'associatedProjects', key: 'associatedProjects',
label: __('Associated projects'), label: __('Associated projects'),
thClass: 'gl-white-space-nowrap gl-vertical-align-middle!', thClass: 'gl-md-max-w-26 gl-white-space-nowrap gl-vertical-align-middle!',
tdClass: 'gl-white-space-nowrap gl-vertical-align-middle! gl-cursor-pointer', tdClass: 'gl-md-max-w-26 gl-vertical-align-middle! gl-cursor-pointer',
sortable: false, sortable: false,
}, },
], ],
...@@ -127,9 +127,13 @@ export default { ...@@ -127,9 +127,13 @@ export default {
<framework-badge :framework="item" @edit="editComplianceFramework(item)" /> <framework-badge :framework="item" @edit="editComplianceFramework(item)" />
</template> </template>
<template #cell(associatedProjects)="{ item: { associatedProjects } }"> <template #cell(associatedProjects)="{ item: { associatedProjects } }">
<div v-for="(associatedProject, index) in associatedProjects" :key="associatedProject.id"> <div
v-for="(associatedProject, index) in associatedProjects"
:key="associatedProject.id"
class="gl-display-inline-block"
>
<gl-link :href="associatedProject.webUrl">{{ associatedProject.name }}</gl-link <gl-link :href="associatedProject.webUrl">{{ associatedProject.name }}</gl-link
><span v-if="index < associatedProjects.length - 1">,</span> ><span v-if="index < associatedProjects.length - 1">, </span>
</div> </div>
</template> </template>
<template #table-busy> <template #table-busy>
......
import { GlLabel } from '@gitlab/ui'; import { GlLabel, GlLink, GlAccordionItem, GlTruncate } from '@gitlab/ui';
import FrameworkInfoDrawer from 'ee/compliance_dashboard/components/frameworks_report/framework_info_drawer.vue'; import FrameworkInfoDrawer from 'ee/compliance_dashboard/components/frameworks_report/framework_info_drawer.vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { createFramework } from 'ee_jest/compliance_dashboard/mock_data'; import { createFrameworkReportFramework } from 'ee_jest/compliance_dashboard/mock_data';
describe('FrameworkInfoDrawer component', () => { describe('FrameworkInfoDrawer component', () => {
let wrapper; let wrapper;
const defaultFramework = createFramework({ id: 1, isDefault: true }); const defaultFramework = createFrameworkReportFramework({ id: 1, isDefault: true });
const nonDefaultFramework = createFramework(2); const nonDefaultFramework = createFrameworkReportFramework(2);
const associatedProjectsCount = defaultFramework.associatedProjects.length;
const findDefaultBadge = () => wrapper.findComponent(GlLabel); const findDefaultBadge = () => wrapper.findComponent(GlLabel);
const findProjectLinks = () => wrapper.findAllComponents(GlLink);
const findAccordionItems = () => wrapper.findAllComponents(GlAccordionItem);
const findTitle = () => wrapper.findComponent(GlTruncate);
const findEditFrameworkBtn = () => wrapper.findByText('Edit framework'); const findEditFrameworkBtn = () => wrapper.findByText('Edit framework');
const findAssociatedProjectsTitle = () => wrapper.findByText('Associated Projects');
const createComponent = ({ props = {} } = {}) => { const createComponent = ({ props = {} } = {}) => {
wrapper = shallowMountExtended(FrameworkInfoDrawer, { wrapper = shallowMountExtended(FrameworkInfoDrawer, {
...@@ -32,8 +35,8 @@ describe('FrameworkInfoDrawer component', () => { ...@@ -32,8 +35,8 @@ describe('FrameworkInfoDrawer component', () => {
}); });
describe('for drawer body content', () => { describe('for drawer body content', () => {
it('renders the `requirement` title', () => { it('renders the title', () => {
expect(wrapper.findByText(defaultFramework.name).exists()).toBe(true); expect(findTitle().props()).toMatchObject({ text: defaultFramework.name, position: 'end' });
}); });
it('renders the default badge', () => { it('renders the default badge', () => {
...@@ -44,8 +47,26 @@ describe('FrameworkInfoDrawer component', () => { ...@@ -44,8 +47,26 @@ describe('FrameworkInfoDrawer component', () => {
expect(findEditFrameworkBtn().exists()).toBe(true); expect(findEditFrameworkBtn().exists()).toBe(true);
}); });
it('renders the Associated Projects Title', () => { it('renders the Description accordion', () => {
expect(findAssociatedProjectsTitle().exists()).toBe(true); expect(findAccordionItems().at(0).props('title')).toBe(`Description`);
expect(findAccordionItems().at(0).text()).toBe(defaultFramework.description);
});
it('renders the Associated Projects accordion', () => {
expect(findAccordionItems().at(1).props('title')).toBe(
`Associated Projects (${associatedProjectsCount})`,
);
});
it('renders the Associated Projects list', () => {
expect(findProjectLinks().exists()).toBe(true);
expect(findProjectLinks().wrappers).toHaveLength(3);
expect(findProjectLinks().at(0).text()).toContain(
defaultFramework.associatedProjects[0].name,
);
expect(findProjectLinks().at(0).attributes('href')).toBe(
defaultFramework.associatedProjects[0].webUrl,
);
}); });
}); });
}); });
......
...@@ -273,6 +273,19 @@ export const createFramework = ({ id, isDefault = false } = {}) => ({ ...@@ -273,6 +273,19 @@ export const createFramework = ({ id, isDefault = false } = {}) => ({
__typename: 'ComplianceFramework', __typename: 'ComplianceFramework',
}); });
export const createFrameworkReportFramework = ({ id, isDefault = false, projects = 3 } = {}) => ({
id: `gid://gitlab/ComplianceManagement::Framework/${id}`,
name: `Some framework ${id}`,
default: isDefault,
description: `This is a framework ${id}`,
color: `#3cb37${id}`,
pipelineConfigurationFullPath: null,
associatedProjects: Array(projects)
.fill(null)
.map((_, pid) => createProject({ id: pid })),
__typename: 'ComplianceFramework',
});
export const createComplianceFrameworksReportResponse = ({ count = 1 } = {}) => { export const createComplianceFrameworksReportResponse = ({ count = 1 } = {}) => {
return { return {
data: { data: {
......
...@@ -12370,6 +12370,9 @@ msgstr "" ...@@ -12370,6 +12370,9 @@ msgstr ""
msgid "ComplianceFrameworksReport|Default" msgid "ComplianceFrameworksReport|Default"
msgstr "" msgstr ""
   
msgid "ComplianceFrameworksReport|Description"
msgstr ""
msgid "ComplianceFrameworksReport|Edit framework" msgid "ComplianceFrameworksReport|Edit framework"
msgstr "" msgstr ""
   
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册