Commit 1d566265 authored by Phil Hughes's avatar Phil Hughes

Merge branch 'peterhegman/hide-mobile-actions-field-with-no-buttons' into 'master'

Hide mobile "Actions" label if no action buttons exist [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!50304
parents 331dc803 f040ec6d
...@@ -36,7 +36,14 @@ export default { ...@@ -36,7 +36,14 @@ export default {
filteredFields() { filteredFields() {
return FIELDS.filter( return FIELDS.filter(
(field) => this.tableFields.includes(field.key) && this.showField(field), (field) => this.tableFields.includes(field.key) && this.showField(field),
); ).map((field) => {
const tdClassFunction = this[field.tdClassFunction];
return {
...field,
...(tdClassFunction && { tdClass: tdClassFunction }),
};
});
}, },
userIsLoggedIn() { userIsLoggedIn() {
return this.currentUserId !== null; return this.currentUserId !== null;
...@@ -46,6 +53,14 @@ export default { ...@@ -46,6 +53,14 @@ export default {
initUserPopovers(this.$el.querySelectorAll('.js-user-link')); initUserPopovers(this.$el.querySelectorAll('.js-user-link'));
}, },
methods: { methods: {
hasActionButtons(member) {
return (
canRemove(member, this.sourceId) ||
canResend(member) ||
canUpdate(member, this.currentUserId, this.sourceId) ||
canOverride(member)
);
},
showField(field) { showField(field) {
if (!Object.prototype.hasOwnProperty.call(field, 'showFunction')) { if (!Object.prototype.hasOwnProperty.call(field, 'showFunction')) {
return true; return true;
...@@ -58,14 +73,20 @@ export default { ...@@ -58,14 +73,20 @@ export default {
return false; return false;
} }
return this.members.some((member) => { return this.members.some((member) => this.hasActionButtons(member));
return ( },
canRemove(member, this.sourceId) || tdClassActions(value, key, member) {
canResend(member) || if (this.hasActionButtons(member)) {
canUpdate(member, this.currentUserId, this.sourceId) || return 'col-actions';
canOverride(member) }
);
}); return ['col-actions', 'gl-display-none!', 'gl-display-lg-table-cell!'];
},
tbodyTrAttr(member) {
return {
...this.tableAttrs.tr,
...(member?.id && { 'data-testid': `members-table-row-${member.id}` }),
};
}, },
}, },
}; };
...@@ -85,7 +106,7 @@ export default { ...@@ -85,7 +106,7 @@ export default {
thead-class="border-bottom" thead-class="border-bottom"
:empty-text="__('No members found')" :empty-text="__('No members found')"
show-empty show-empty
:tbody-tr-attr="tableAttrs.tr" :tbody-tr-attr="tbodyTrAttr"
> >
<template #cell(account)="{ item: member }"> <template #cell(account)="{ item: member }">
<members-table-cell #default="{ memberType, isCurrentUser }" :member="member"> <members-table-cell #default="{ memberType, isCurrentUser }" :member="member">
......
...@@ -70,8 +70,8 @@ export const FIELDS = [ ...@@ -70,8 +70,8 @@ export const FIELDS = [
{ {
key: 'actions', key: 'actions',
thClass: 'col-actions', thClass: 'col-actions',
tdClass: 'col-actions',
showFunction: 'showActionsField', showFunction: 'showActionsField',
tdClassFunction: 'tdClassActions',
}, },
]; ];
......
---
title: Hide "Actions" label on group members view if no action buttons exist
merge_request: 50304
author:
type: fixed
import { within } from '@testing-library/dom'; import { within } from '@testing-library/dom';
import { mount, createLocalVue } from '@vue/test-utils'; import { mount, createLocalVue, createWrapper } from '@vue/test-utils';
import Vuex from 'vuex'; import Vuex from 'vuex';
import { member as memberMock, members } from 'jest/members/mock_data'; import { member as memberMock, members } from 'jest/members/mock_data';
import MembersTable from '~/members/components/table/members_table.vue'; import MembersTable from '~/members/components/table/members_table.vue';
...@@ -43,6 +43,13 @@ describe('MemberList', () => { ...@@ -43,6 +43,13 @@ describe('MemberList', () => {
}); });
}; };
const getByTestId = (id, options) =>
createWrapper(within(wrapper.element).getByTestId(id, options));
const findTableCellByMemberId = (tableCellLabel, memberId) =>
getByTestId(`members-table-row-${memberId}`).find(
`[data-label="${tableCellLabel}"][role="cell"]`,
);
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
wrapper = null; wrapper = null;
...@@ -56,11 +63,26 @@ describe('MemberList', () => { ...@@ -56,11 +63,26 @@ describe('MemberList', () => {
canOverride: true, canOverride: true,
}; };
const memberNoPermissions = {
...memberMock,
id: 2,
};
describe('when one of the members has `canOverride` permissions', () => { describe('when one of the members has `canOverride` permissions', () => {
it('renders the "Actions" field', () => { it('renders the "Actions" field', () => {
createComponent({ members: [memberCanOverride], tableFields: ['actions'] }); createComponent({
members: [memberNoPermissions, memberCanOverride],
tableFields: ['actions'],
});
expect(within(wrapper.element).queryByTestId('col-actions')).not.toBe(null); expect(within(wrapper.element).queryByTestId('col-actions')).not.toBe(null);
expect(
findTableCellByMemberId('Actions', memberNoPermissions.id).classes(),
).toStrictEqual(['col-actions', 'gl-display-none!', 'gl-display-lg-table-cell!']);
expect(findTableCellByMemberId('Actions', memberCanOverride.id).classes()).toStrictEqual([
'col-actions',
]);
}); });
}); });
......
...@@ -63,6 +63,10 @@ describe('MembersTable', () => { ...@@ -63,6 +63,10 @@ describe('MembersTable', () => {
createWrapper(getByTestIdHelper(wrapper.element, id, options)); createWrapper(getByTestIdHelper(wrapper.element, id, options));
const findTable = () => wrapper.find(GlTable); const findTable = () => wrapper.find(GlTable);
const findTableCellByMemberId = (tableCellLabel, memberId) =>
getByTestId(`members-table-row-${memberId}`).find(
`[data-label="${tableCellLabel}"][role="cell"]`,
);
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
...@@ -131,16 +135,30 @@ describe('MembersTable', () => { ...@@ -131,16 +135,30 @@ describe('MembersTable', () => {
canRemove: true, canRemove: true,
}; };
const memberNoPermissions = {
...memberMock,
id: 2,
};
describe.each` describe.each`
permission | members permission | members
${'canUpdate'} | ${[memberCanUpdate]} ${'canUpdate'} | ${[memberNoPermissions, memberCanUpdate]}
${'canRemove'} | ${[memberCanRemove]} ${'canRemove'} | ${[memberNoPermissions, memberCanRemove]}
${'canResend'} | ${[invite]} ${'canResend'} | ${[memberNoPermissions, invite]}
`('when one of the members has $permission permissions', ({ members }) => { `('when one of the members has $permission permissions', ({ members }) => {
it('renders the "Actions" field', () => { it('renders the "Actions" field', () => {
createComponent({ members, tableFields: ['actions'] }); createComponent({ members, tableFields: ['actions'] });
expect(getByTestId('col-actions').exists()).toBe(true); expect(getByTestId('col-actions').exists()).toBe(true);
expect(findTableCellByMemberId('Actions', members[0].id).classes()).toStrictEqual([
'col-actions',
'gl-display-none!',
'gl-display-lg-table-cell!',
]);
expect(findTableCellByMemberId('Actions', members[1].id).classes()).toStrictEqual([
'col-actions',
]);
}); });
}); });
......
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