Swap button for dropdowns in group members page
What does this MR do and why?
In the group members page, we replaced the buttons in the right side of the table for dropdowns. This is in preparation for adding one more action, Disable two-factor authentication
, to this dropdown. See &9484 (closed)
The size of this MR is big, so to facilitate the review I have broken into a series of commits. Sequence of commits:
- Replace buttons by dropdowns
- Rename files
- Improve test coverage
- Fix failing rspecs
It maybe simpler to look at the changes on each of the individual commits.
Closes: #385614 (closed)
Screenshots or screen recordings
Before
After
The content of the dropdowns are shown only when clicked. The screenshot has been prepared to show the differences.
Notice the buttons in the other tabs (Groups
, Invited
and Access requests
) still shows actions in the form of buttons.
How to set up and validate locally
Go to the Flightjs
group members page: https://gdk.test:3443/groups/flightjs/-/group_members
To display the three possible buttons, you can apply this patch (expand the the collapsible section).
Click to expand
diff --git a/app/assets/javascripts/members/index.js b/app/assets/javascripts/members/index.js
index 359239c5c0c..95dd56496db 100644
--- a/app/assets/javascripts/members/index.js
+++ b/app/assets/javascripts/members/index.js
@@ -22,7 +22,386 @@ export const initMembersApp = (el, options) => {
canFilterByEnterprise,
exportCsvPath,
...vuexStoreAttributes
- } = parseDataAttributes(el);
+ } = {
+ user: {
+ members: [
+ {
+ id: 427,
+ createdAt: '2022-12-21T09:41:46.229Z',
+ expiresAt: null,
+ requestedAt: null,
+ createdBy: {
+ name: 'Super Administrator',
+ webUrl: 'https://gdk.test:3443/root',
+ },
+ canUpdate: true,
+ canRemove: true,
+ isLastOwner: false,
+ isDirectMember: true,
+ accessLevel: {
+ stringValue: 'Owner',
+ integerValue: 50,
+ },
+ source: {
+ id: 31,
+ fullName: 'Flightjs',
+ webUrl: 'https://gdk.test:3443/groups/flightjs',
+ },
+ type: 'GroupMember',
+ validRoles: {
+ Guest: 10,
+ Reporter: 20,
+ Developer: 30,
+ Maintainer: 40,
+ Owner: 50,
+ 'Minimal Access': 5,
+ },
+ user: {
+ id: 29,
+ username: 'reported_user_7',
+ name: 'Brianna Lehner',
+ avatarUrl:
+ 'https://secure.gravatar.com/avatar/70bdca730b2045df686f396eb4231d06?s=80&d=identicon',
+ webUrl: 'https://gdk.test:3443/reported_user_7',
+ showStatus: false,
+ availability: null,
+ createdAt: '2022-05-12T15:51:03.084Z',
+ lastActivityOn: '2022-12-21',
+ blocked: false,
+ isBot: false,
+ twoFactorEnabled: false,
+ oncallSchedules: [],
+ escalationPolicies: [],
+ },
+ state: 0,
+ usingLicense: false,
+ groupSso: false,
+ groupManagedAccount: false,
+ canOverride: false,
+ isOverridden: false,
+ provisionedByThisGroup: false,
+ canUnban: true,
+ banned: false,
+ },
+ {
+ id: 5,
+ createdAt: '2022-05-12T15:49:37.605Z',
+ expiresAt: null,
+ requestedAt: null,
+ canUpdate: true,
+ canRemove: true,
+ isLastOwner: false,
+ isDirectMember: true,
+ accessLevel: {
+ stringValue: 'Owner',
+ integerValue: 50,
+ },
+ source: {
+ id: 31,
+ fullName: 'Flightjs',
+ webUrl: 'https://gdk.test:3443/groups/flightjs',
+ },
+ type: 'GroupMember',
+ validRoles: {
+ Guest: 10,
+ Reporter: 20,
+ Developer: 30,
+ Maintainer: 40,
+ Owner: 50,
+ 'Minimal Access': 5,
+ },
+ user: {
+ id: 1,
+ username: 'root',
+ name: 'Super Administrator',
+ avatarUrl:
+ 'https://secure.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ webUrl: 'https://gdk.test:3443/root',
+ showStatus: false,
+ availability: null,
+ createdAt: '2022-05-12T15:49:00.637Z',
+ lastActivityOn: '2022-12-23',
+ blocked: false,
+ isBot: false,
+ twoFactorEnabled: true,
+ oncallSchedules: [],
+ escalationPolicies: [],
+ },
+ state: 0,
+ usingLicense: false,
+ groupSso: false,
+ groupManagedAccount: false,
+ canOverride: false,
+ isOverridden: false,
+ provisionedByThisGroup: false,
+ canUnban: true,
+ banned: false,
+ },
+ {
+ id: 464,
+ createdAt: '2022-12-23T08:10:29.965Z',
+ expiresAt: null,
+ requestedAt: null,
+ createdBy: {
+ name: 'Super Administrator',
+ webUrl: 'https://gdk.test:3443/root',
+ },
+ canUpdate: true,
+ canRemove: false,
+ isLastOwner: false,
+ isDirectMember: true,
+ accessLevel: {
+ stringValue: 'Owner',
+ integerValue: 50,
+ },
+ source: {
+ id: 31,
+ fullName: 'Flightjs',
+ webUrl: 'https://gdk.test:3443/groups/flightjs',
+ },
+ type: 'GroupMember',
+ validRoles: {
+ Guest: 10,
+ Reporter: 20,
+ Developer: 30,
+ Maintainer: 40,
+ Owner: 50,
+ 'Minimal Access': 5,
+ },
+ user: {
+ id: 376,
+ username: 'bob',
+ name: 'bob Doe',
+ avatarUrl:
+ 'https://secure.gravatar.com/avatar/c44142baacdd839e36e569ff5c7cbe10?s=80&d=identicon',
+ webUrl: 'https://gdk.test:3443/bob',
+ showStatus: false,
+ availability: null,
+ createdAt: '2022-11-22T13:22:09.290Z',
+ lastActivityOn: '2022-11-22',
+ blocked: false,
+ isBot: false,
+ twoFactorEnabled: false,
+ oncallSchedules: [],
+ escalationPolicies: [],
+ },
+ state: 0,
+ usingLicense: false,
+ groupSso: false,
+ groupManagedAccount: false,
+ canOverride: true,
+ isOverridden: false,
+ provisionedByThisGroup: false,
+ canUnban: true,
+ banned: false,
+ },
+ ],
+ pagination: {
+ currentPage: 1,
+ perPage: 50,
+ totalItems: 7,
+ paramName: 'page',
+ params: {
+ invited_members_page: null,
+ search_invited: null,
+ },
+ },
+ memberPath: '/groups/flightjs/-/group_members/:id',
+ ldapOverridePath: '/groups/flightjs/-/group_members/:id/override',
+ },
+ group: {
+ members: [
+ {
+ id: 1,
+ createdAt: '2022-12-09T16:43:36.404Z',
+ expiresAt: null,
+ accessLevel: {
+ stringValue: 'Guest',
+ integerValue: 10,
+ },
+ validRoles: {
+ Guest: 10,
+ Reporter: 20,
+ Developer: 30,
+ Maintainer: 40,
+ Owner: 50,
+ },
+ sharedWithGroup: {
+ avatarUrl: null,
+ webUrl: 'https://gdk.test:3443/groups/2fa_enforced',
+ id: 184,
+ name: '2fa_enforced',
+ fullPath: '2fa_enforced',
+ fullName: '2fa_enforced',
+ },
+ canUpdate: true,
+ canRemove: true,
+ isDirectMember: true,
+ source: {
+ id: 31,
+ fullName: 'Flightjs',
+ webUrl: 'https://gdk.test:3443/groups/flightjs',
+ },
+ },
+ ],
+ pagination: {
+ currentPage: null,
+ perPage: null,
+ totalItems: 1,
+ paramName: null,
+ params: {},
+ },
+ memberPath: '/groups/flightjs/-/group_links/:id',
+ },
+ invite: {
+ members: [
+ {
+ id: 428,
+ createdAt: '2022-12-21T09:45:30.481Z',
+ expiresAt: null,
+ requestedAt: null,
+ createdBy: {
+ name: 'Super Administrator',
+ webUrl: 'https://gdk.test:3443/root',
+ },
+ canUpdate: true,
+ canRemove: true,
+ isLastOwner: false,
+ isDirectMember: true,
+ accessLevel: {
+ stringValue: 'Guest',
+ integerValue: 10,
+ },
+ source: {
+ id: 31,
+ fullName: 'Flightjs',
+ webUrl: 'https://gdk.test:3443/groups/flightjs',
+ },
+ type: 'GroupMember',
+ validRoles: {
+ Guest: 10,
+ Reporter: 20,
+ Developer: 30,
+ Maintainer: 40,
+ Owner: 50,
+ 'Minimal Access': 5,
+ },
+ state: 0,
+ invite: {
+ email: 'rubocom@a.com',
+ avatarUrl:
+ 'https://secure.gravatar.com/avatar/848c9b3f4de106b3ce6be82279ef9d50?s=80&d=identicon',
+ canResend: true,
+ userState: null,
+ },
+ usingLicense: null,
+ groupSso: false,
+ groupManagedAccount: false,
+ canOverride: false,
+ isOverridden: false,
+ provisionedByThisGroup: false,
+ canUnban: true,
+ banned: false,
+ },
+ ],
+ pagination: {
+ currentPage: 1,
+ perPage: 50,
+ totalItems: 1,
+ paramName: 'invited_members_page',
+ params: {
+ page: null,
+ },
+ },
+ memberPath: '/groups/flightjs/-/group_members/:id',
+ ldapOverridePath: '/groups/flightjs/-/group_members/:id/override',
+ },
+ accessRequest: {
+ members: [
+ {
+ id: 426,
+ createdAt: '2022-12-21T09:39:47.359Z',
+ expiresAt: null,
+ requestedAt: '2022-12-21T09:39:47.344Z',
+ canUpdate: true,
+ canRemove: true,
+ isLastOwner: false,
+ isDirectMember: true,
+ accessLevel: {
+ stringValue: 'Developer',
+ integerValue: 30,
+ },
+ source: {
+ id: 31,
+ fullName: 'Flightjs',
+ webUrl: 'https://gdk.test:3443/groups/flightjs',
+ },
+ type: 'GroupMember',
+ validRoles: {
+ Guest: 10,
+ Reporter: 20,
+ Developer: 30,
+ Maintainer: 40,
+ Owner: 50,
+ 'Minimal Access': 5,
+ },
+ user: {
+ id: 21,
+ username: 'charles',
+ name: 'Young Murphy',
+ avatarUrl:
+ 'https://secure.gravatar.com/avatar/14e9bcc5b5bb1065bbc505338d4ce54d?s=80&d=identicon',
+ webUrl: 'https://gdk.test:3443/charles',
+ showStatus: false,
+ availability: null,
+ createdAt: '2022-05-12T15:49:02.547Z',
+ lastActivityOn: '2022-12-21',
+ blocked: false,
+ isBot: false,
+ twoFactorEnabled: true,
+ oncallSchedules: [],
+ escalationPolicies: [],
+ },
+ state: 0,
+ usingLicense: false,
+ groupSso: false,
+ groupManagedAccount: false,
+ canOverride: false,
+ isOverridden: false,
+ provisionedByThisGroup: false,
+ canUnban: true,
+ banned: false,
+ },
+ ],
+ pagination: {
+ currentPage: null,
+ perPage: null,
+ totalItems: 1,
+ paramName: null,
+ params: {},
+ },
+ memberPath: '/groups/flightjs/-/group_members/:id',
+ ldapOverridePath: '/groups/flightjs/-/group_members/:id/override',
+ },
+ sourceId: 31,
+ canManageMembers: true,
+ canManageAccessRequests: true,
+ canExportMembers: true,
+ exportCsvPath: '/groups/flightjs/-/group_members/export_csv',
+ canFilterByEnterprise: true,
+ banned: {
+ members: [],
+ pagination: {
+ currentPage: null,
+ perPage: null,
+ totalItems: 0,
+ paramName: null,
+ params: {},
+ },
+ memberPath: '/groups/flightjs/-/group_members/:id',
+ ldapOverridePath: '/groups/flightjs/-/group_members/:id/override',
+ },
+ };
const modules = Object.keys(MEMBER_TYPES).reduce((accumulator, namespace) => {
const namespacedOptions = options[namespace];
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.