Commit f040ec6d authored by Peter Hegman's avatar Peter Hegman Committed by Phil Hughes

Hide mobile "Actions" label if no action buttons exist

On desktop the whole column is hidden, but on mobile we need to hide
the "Actions" label on individual cards.
parent 0a003ee7
...@@ -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