Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/members')
-rw-r--r--app/assets/javascripts/members/components/action_buttons/access_request_action_buttons.vue4
-rw-r--r--app/assets/javascripts/members/components/action_buttons/approve_access_request_button.vue2
-rw-r--r--app/assets/javascripts/members/components/action_buttons/invite_action_buttons.vue2
-rw-r--r--app/assets/javascripts/members/components/action_buttons/leave_button.vue2
-rw-r--r--app/assets/javascripts/members/components/action_buttons/remove_group_link_button.vue3
-rw-r--r--app/assets/javascripts/members/components/action_buttons/remove_member_button.vue2
-rw-r--r--app/assets/javascripts/members/components/action_buttons/resend_invite_button.vue2
-rw-r--r--app/assets/javascripts/members/components/action_buttons/user_action_buttons.vue4
-rw-r--r--app/assets/javascripts/members/components/app.vue40
-rw-r--r--app/assets/javascripts/members/components/avatars/user_avatar.vue7
-rw-r--r--app/assets/javascripts/members/components/filter_sort/filter_sort_container.vue2
-rw-r--r--app/assets/javascripts/members/components/filter_sort/members_filtered_search_bar.vue6
-rw-r--r--app/assets/javascripts/members/components/filter_sort/sort_dropdown.vue4
-rw-r--r--app/assets/javascripts/members/components/modals/leave_modal.vue2
-rw-r--r--app/assets/javascripts/members/components/modals/remove_group_link_modal.vue3
-rw-r--r--app/assets/javascripts/members/components/table/member_action_buttons.vue6
-rw-r--r--app/assets/javascripts/members/components/table/member_avatar.vue4
-rw-r--r--app/assets/javascripts/members/components/table/members_table.vue20
-rw-r--r--app/assets/javascripts/members/components/table/members_table_cell.vue8
-rw-r--r--app/assets/javascripts/members/constants.js5
-rw-r--r--app/assets/javascripts/members/index.js43
-rw-r--r--app/assets/javascripts/members/store/actions.js6
-rw-r--r--app/assets/javascripts/members/store/index.js4
-rw-r--r--app/assets/javascripts/members/store/mutations.js18
-rw-r--r--app/assets/javascripts/members/utils.js62
25 files changed, 198 insertions, 63 deletions
diff --git a/app/assets/javascripts/members/components/action_buttons/access_request_action_buttons.vue b/app/assets/javascripts/members/components/action_buttons/access_request_action_buttons.vue
index fcb70dd45a6..35966be7363 100644
--- a/app/assets/javascripts/members/components/action_buttons/access_request_action_buttons.vue
+++ b/app/assets/javascripts/members/components/action_buttons/access_request_action_buttons.vue
@@ -1,8 +1,8 @@
<script>
+import { s__, sprintf } from '~/locale';
import ActionButtonGroup from './action_button_group.vue';
-import RemoveMemberButton from './remove_member_button.vue';
import ApproveAccessRequestButton from './approve_access_request_button.vue';
-import { s__, sprintf } from '~/locale';
+import RemoveMemberButton from './remove_member_button.vue';
export default {
name: 'AccessRequestActionButtons',
diff --git a/app/assets/javascripts/members/components/action_buttons/approve_access_request_button.vue b/app/assets/javascripts/members/components/action_buttons/approve_access_request_button.vue
index e8a53ff173d..83f266779f2 100644
--- a/app/assets/javascripts/members/components/action_buttons/approve_access_request_button.vue
+++ b/app/assets/javascripts/members/components/action_buttons/approve_access_request_button.vue
@@ -1,6 +1,6 @@
<script>
-import { mapState } from 'vuex';
import { GlButton, GlForm, GlTooltipDirective } from '@gitlab/ui';
+import { mapState } from 'vuex';
import csrf from '~/lib/utils/csrf';
import { __ } from '~/locale';
diff --git a/app/assets/javascripts/members/components/action_buttons/invite_action_buttons.vue b/app/assets/javascripts/members/components/action_buttons/invite_action_buttons.vue
index 9a27348f146..0bcc85157f1 100644
--- a/app/assets/javascripts/members/components/action_buttons/invite_action_buttons.vue
+++ b/app/assets/javascripts/members/components/action_buttons/invite_action_buttons.vue
@@ -1,8 +1,8 @@
<script>
+import { s__, sprintf } from '~/locale';
import ActionButtonGroup from './action_button_group.vue';
import RemoveMemberButton from './remove_member_button.vue';
import ResendInviteButton from './resend_invite_button.vue';
-import { s__, sprintf } from '~/locale';
export default {
name: 'InviteActionButtons',
diff --git a/app/assets/javascripts/members/components/action_buttons/leave_button.vue b/app/assets/javascripts/members/components/action_buttons/leave_button.vue
index 443a962e0cf..f600a207b8d 100644
--- a/app/assets/javascripts/members/components/action_buttons/leave_button.vue
+++ b/app/assets/javascripts/members/components/action_buttons/leave_button.vue
@@ -1,8 +1,8 @@
<script>
import { GlButton, GlModalDirective, GlTooltipDirective } from '@gitlab/ui';
import { __ } from '~/locale';
-import LeaveModal from '../modals/leave_modal.vue';
import { LEAVE_MODAL_ID } from '../../constants';
+import LeaveModal from '../modals/leave_modal.vue';
export default {
name: 'LeaveButton',
diff --git a/app/assets/javascripts/members/components/action_buttons/remove_group_link_button.vue b/app/assets/javascripts/members/components/action_buttons/remove_group_link_button.vue
index 9d89cb40676..3b87c29c1bc 100644
--- a/app/assets/javascripts/members/components/action_buttons/remove_group_link_button.vue
+++ b/app/assets/javascripts/members/components/action_buttons/remove_group_link_button.vue
@@ -1,6 +1,6 @@
<script>
-import { mapActions } from 'vuex';
import { GlButton, GlTooltipDirective } from '@gitlab/ui';
+import { mapActions } from 'vuex';
import { s__ } from '~/locale';
export default {
@@ -31,6 +31,7 @@ export default {
:title="$options.i18n.buttonTitle"
:aria-label="$options.i18n.buttonTitle"
icon="remove"
+ data-qa-selector="delete_group_access_link"
@click="showRemoveGroupLinkModal(groupLink)"
/>
</template>
diff --git a/app/assets/javascripts/members/components/action_buttons/remove_member_button.vue b/app/assets/javascripts/members/components/action_buttons/remove_member_button.vue
index b0b7ff4ce9a..cb71be39ebc 100644
--- a/app/assets/javascripts/members/components/action_buttons/remove_member_button.vue
+++ b/app/assets/javascripts/members/components/action_buttons/remove_member_button.vue
@@ -1,6 +1,6 @@
<script>
-import { mapState } from 'vuex';
import { GlButton, GlTooltipDirective } from '@gitlab/ui';
+import { mapState } from 'vuex';
export default {
name: 'RemoveMemberButton',
diff --git a/app/assets/javascripts/members/components/action_buttons/resend_invite_button.vue b/app/assets/javascripts/members/components/action_buttons/resend_invite_button.vue
index 1cc3fd17e98..261a6279920 100644
--- a/app/assets/javascripts/members/components/action_buttons/resend_invite_button.vue
+++ b/app/assets/javascripts/members/components/action_buttons/resend_invite_button.vue
@@ -1,6 +1,6 @@
<script>
-import { mapState } from 'vuex';
import { GlButton, GlTooltipDirective } from '@gitlab/ui';
+import { mapState } from 'vuex';
import csrf from '~/lib/utils/csrf';
import { __ } from '~/locale';
diff --git a/app/assets/javascripts/members/components/action_buttons/user_action_buttons.vue b/app/assets/javascripts/members/components/action_buttons/user_action_buttons.vue
index 0e5df961782..f779d1755a5 100644
--- a/app/assets/javascripts/members/components/action_buttons/user_action_buttons.vue
+++ b/app/assets/javascripts/members/components/action_buttons/user_action_buttons.vue
@@ -1,8 +1,8 @@
<script>
+import { s__, sprintf } from '~/locale';
import ActionButtonGroup from './action_button_group.vue';
-import RemoveMemberButton from './remove_member_button.vue';
import LeaveButton from './leave_button.vue';
-import { s__, sprintf } from '~/locale';
+import RemoveMemberButton from './remove_member_button.vue';
export default {
name: 'UserActionButtons',
diff --git a/app/assets/javascripts/members/components/app.vue b/app/assets/javascripts/members/components/app.vue
new file mode 100644
index 00000000000..27fceb7374e
--- /dev/null
+++ b/app/assets/javascripts/members/components/app.vue
@@ -0,0 +1,40 @@
+<script>
+import { GlAlert } from '@gitlab/ui';
+import { mapState, mapMutations } from 'vuex';
+import { scrollToElement } from '~/lib/utils/common_utils';
+import { HIDE_ERROR } from '../store/mutation_types';
+import FilterSortContainer from './filter_sort/filter_sort_container.vue';
+import MembersTable from './table/members_table.vue';
+
+export default {
+ name: 'MembersApp',
+ components: { MembersTable, FilterSortContainer, GlAlert },
+ computed: {
+ ...mapState(['showError', 'errorMessage']),
+ },
+ watch: {
+ showError(value) {
+ if (value) {
+ this.$nextTick(() => {
+ scrollToElement(this.$refs.errorAlert.$el);
+ });
+ }
+ },
+ },
+ methods: {
+ ...mapMutations({
+ hideError: HIDE_ERROR,
+ }),
+ },
+};
+</script>
+
+<template>
+ <div>
+ <gl-alert v-if="showError" ref="errorAlert" variant="danger" @dismiss="hideError">{{
+ errorMessage
+ }}</gl-alert>
+ <filter-sort-container />
+ <members-table />
+ </div>
+</template>
diff --git a/app/assets/javascripts/members/components/avatars/user_avatar.vue b/app/assets/javascripts/members/components/avatars/user_avatar.vue
index e2264085e67..79dda3c1379 100644
--- a/app/assets/javascripts/members/components/avatars/user_avatar.vue
+++ b/app/assets/javascripts/members/components/avatars/user_avatar.vue
@@ -6,9 +6,9 @@ import {
GlSafeHtmlDirective as SafeHtml,
} from '@gitlab/ui';
import { generateBadges } from 'ee_else_ce/members/utils';
+import { glEmojiTag } from '~/emoji';
import { __ } from '~/locale';
import { AVATAR_SIZE } from '../../constants';
-import { glEmojiTag } from '~/emoji';
export default {
name: 'UserAvatar',
@@ -69,7 +69,10 @@ export default {
>
<template #meta>
<div v-if="statusEmoji" class="gl-p-1">
- <span v-safe-html:[$options.safeHtmlConfig]="glEmojiTag(statusEmoji)"></span>
+ <span
+ v-safe-html:[$options.safeHtmlConfig]="glEmojiTag(statusEmoji)"
+ class="user-status-emoji gl-mr-0"
+ ></span>
</div>
<div v-for="badge in badges" :key="badge.text" class="gl-p-1">
<gl-badge size="sm" :variant="badge.variant">
diff --git a/app/assets/javascripts/members/components/filter_sort/filter_sort_container.vue b/app/assets/javascripts/members/components/filter_sort/filter_sort_container.vue
index f869ecd392f..812a8626949 100644
--- a/app/assets/javascripts/members/components/filter_sort/filter_sort_container.vue
+++ b/app/assets/javascripts/members/components/filter_sort/filter_sort_container.vue
@@ -19,7 +19,7 @@ export default {
</script>
<template>
- <div v-if="showContainer" class="gl-bg-gray-10 gl-p-3 gl-display-md-flex">
+ <div v-if="showContainer" class="gl-bg-gray-10 gl-p-3 gl-md-display-flex">
<members-filtered-search-bar v-if="filteredSearchBar.show" class="gl-p-3 gl-flex-grow-1" />
<sort-dropdown v-if="showSortDropdown" class="gl-p-3 gl-flex-shrink-0" />
</div>
diff --git a/app/assets/javascripts/members/components/filter_sort/members_filtered_search_bar.vue b/app/assets/javascripts/members/components/filter_sort/members_filtered_search_bar.vue
index cf7501d84fa..039ee9a0207 100644
--- a/app/assets/javascripts/members/components/filter_sort/members_filtered_search_bar.vue
+++ b/app/assets/javascripts/members/components/filter_sort/members_filtered_search_bar.vue
@@ -1,11 +1,11 @@
<script>
-import { mapState } from 'vuex';
import { GlFilteredSearchToken } from '@gitlab/ui';
-import { setUrlParams, queryToObject } from '~/lib/utils/url_utility';
+import { mapState } from 'vuex';
import { getParameterByName } from '~/lib/utils/common_utils';
+import { setUrlParams, queryToObject } from '~/lib/utils/url_utility';
import { s__ } from '~/locale';
-import FilteredSearchBar from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
import { SEARCH_TOKEN_TYPE, SORT_PARAM } from '~/members/constants';
+import FilteredSearchBar from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
export default {
name: 'MembersFilteredSearchBar',
diff --git a/app/assets/javascripts/members/components/filter_sort/sort_dropdown.vue b/app/assets/javascripts/members/components/filter_sort/sort_dropdown.vue
index bcfe559768d..9fa8772faf4 100644
--- a/app/assets/javascripts/members/components/filter_sort/sort_dropdown.vue
+++ b/app/assets/javascripts/members/components/filter_sort/sort_dropdown.vue
@@ -1,9 +1,9 @@
<script>
-import { mapState } from 'vuex';
import { GlSorting, GlSortingItem } from '@gitlab/ui';
+import { mapState } from 'vuex';
import { visitUrl } from '~/lib/utils/url_utility';
-import { parseSortParam, buildSortHref } from '~/members/utils';
import { FIELDS } from '~/members/constants';
+import { parseSortParam, buildSortHref } from '~/members/utils';
export default {
name: 'SortDropdown',
diff --git a/app/assets/javascripts/members/components/modals/leave_modal.vue b/app/assets/javascripts/members/components/modals/leave_modal.vue
index d231c7eabfa..a0f978d85cc 100644
--- a/app/assets/javascripts/members/components/modals/leave_modal.vue
+++ b/app/assets/javascripts/members/components/modals/leave_modal.vue
@@ -1,6 +1,6 @@
<script>
-import { mapState } from 'vuex';
import { GlModal, GlForm, GlSprintf, GlTooltipDirective } from '@gitlab/ui';
+import { mapState } from 'vuex';
import csrf from '~/lib/utils/csrf';
import { __, s__, sprintf } from '~/locale';
import { LEAVE_MODAL_ID } from '../../constants';
diff --git a/app/assets/javascripts/members/components/modals/remove_group_link_modal.vue b/app/assets/javascripts/members/components/modals/remove_group_link_modal.vue
index 231d014a4ec..1ba6bf9aba6 100644
--- a/app/assets/javascripts/members/components/modals/remove_group_link_modal.vue
+++ b/app/assets/javascripts/members/components/modals/remove_group_link_modal.vue
@@ -1,6 +1,6 @@
<script>
-import { mapState, mapActions } from 'vuex';
import { GlModal, GlSprintf, GlForm } from '@gitlab/ui';
+import { mapState, mapActions } from 'vuex';
import csrf from '~/lib/utils/csrf';
import { __, s__, sprintf } from '~/locale';
import { REMOVE_GROUP_LINK_MODAL_ID } from '../../constants';
@@ -52,6 +52,7 @@ export default {
:action-primary="$options.actionPrimary"
:action-cancel="$options.actionCancel"
size="sm"
+ data-qa-selector="remove_group_link_modal_content"
@primary="handlePrimary"
@hide="hideRemoveGroupLinkModal"
>
diff --git a/app/assets/javascripts/members/components/table/member_action_buttons.vue b/app/assets/javascripts/members/components/table/member_action_buttons.vue
index c61ebec33bd..6f15f079d2d 100644
--- a/app/assets/javascripts/members/components/table/member_action_buttons.vue
+++ b/app/assets/javascripts/members/components/table/member_action_buttons.vue
@@ -1,9 +1,9 @@
<script>
-import UserActionButtons from '../action_buttons/user_action_buttons.vue';
+import { MEMBER_TYPES } from '../../constants';
+import AccessRequestActionButtons from '../action_buttons/access_request_action_buttons.vue';
import GroupActionButtons from '../action_buttons/group_action_buttons.vue';
import InviteActionButtons from '../action_buttons/invite_action_buttons.vue';
-import AccessRequestActionButtons from '../action_buttons/access_request_action_buttons.vue';
-import { MEMBER_TYPES } from '../../constants';
+import UserActionButtons from '../action_buttons/user_action_buttons.vue';
export default {
name: 'MemberActionButtons',
diff --git a/app/assets/javascripts/members/components/table/member_avatar.vue b/app/assets/javascripts/members/components/table/member_avatar.vue
index a1f98d4008a..92b757ffcba 100644
--- a/app/assets/javascripts/members/components/table/member_avatar.vue
+++ b/app/assets/javascripts/members/components/table/member_avatar.vue
@@ -1,8 +1,8 @@
<script>
import { kebabCase } from 'lodash';
-import UserAvatar from '../avatars/user_avatar.vue';
-import InviteAvatar from '../avatars/invite_avatar.vue';
import GroupAvatar from '../avatars/group_avatar.vue';
+import InviteAvatar from '../avatars/invite_avatar.vue';
+import UserAvatar from '../avatars/user_avatar.vue';
export default {
name: 'MemberAvatar',
diff --git a/app/assets/javascripts/members/components/table/members_table.vue b/app/assets/javascripts/members/components/table/members_table.vue
index 16e0cd5ad4e..9a3edff19ff 100644
--- a/app/assets/javascripts/members/components/table/members_table.vue
+++ b/app/assets/javascripts/members/components/table/members_table.vue
@@ -1,18 +1,18 @@
<script>
-import { mapState } from 'vuex';
import { GlTable, GlBadge } from '@gitlab/ui';
+import { mapState } from 'vuex';
import MembersTableCell from 'ee_else_ce/members/components/table/members_table_cell.vue';
import { canOverride, canRemove, canResend, canUpdate } from 'ee_else_ce/members/utils';
-import { FIELDS } from '../../constants';
import initUserPopovers from '~/user_popovers';
-import MemberAvatar from './member_avatar.vue';
-import MemberSource from './member_source.vue';
+import { FIELDS } from '../../constants';
+import RemoveGroupLinkModal from '../modals/remove_group_link_modal.vue';
import CreatedAt from './created_at.vue';
+import ExpirationDatepicker from './expiration_datepicker.vue';
import ExpiresAt from './expires_at.vue';
import MemberActionButtons from './member_action_buttons.vue';
+import MemberAvatar from './member_avatar.vue';
+import MemberSource from './member_source.vue';
import RoleDropdown from './role_dropdown.vue';
-import RemoveGroupLinkModal from '../modals/remove_group_link_modal.vue';
-import ExpirationDatepicker from './expiration_datepicker.vue';
export default {
name: 'MembersTable',
@@ -32,7 +32,7 @@ export default {
import('ee_component/members/components/ldap/ldap_override_confirmation_modal.vue'),
},
computed: {
- ...mapState(['members', 'tableFields', 'tableAttrs', 'currentUserId', 'sourceId']),
+ ...mapState(['members', 'tableFields', 'tableAttrs', 'currentUserId']),
filteredFields() {
return FIELDS.filter(
(field) => this.tableFields.includes(field.key) && this.showField(field),
@@ -55,9 +55,9 @@ export default {
methods: {
hasActionButtons(member) {
return (
- canRemove(member, this.sourceId) ||
+ canRemove(member) ||
canResend(member) ||
- canUpdate(member, this.currentUserId, this.sourceId) ||
+ canUpdate(member, this.currentUserId) ||
canOverride(member)
);
},
@@ -80,7 +80,7 @@ export default {
return 'col-actions';
}
- return ['col-actions', 'gl-display-none!', 'gl-display-lg-table-cell!'];
+ return ['col-actions', 'gl-display-none!', 'gl-lg-display-table-cell!'];
},
tbodyTrAttr(member) {
return {
diff --git a/app/assets/javascripts/members/components/table/members_table_cell.vue b/app/assets/javascripts/members/components/table/members_table_cell.vue
index 20aa01b96bc..1f537740f94 100644
--- a/app/assets/javascripts/members/components/table/members_table_cell.vue
+++ b/app/assets/javascripts/members/components/table/members_table_cell.vue
@@ -19,7 +19,7 @@ export default {
},
},
computed: {
- ...mapState(['sourceId', 'currentUserId']),
+ ...mapState(['currentUserId']),
isGroup() {
return isGroup(this.member);
},
@@ -41,19 +41,19 @@ export default {
return MEMBER_TYPES.user;
},
isDirectMember() {
- return isDirectMember(this.member, this.sourceId);
+ return isDirectMember(this.member);
},
isCurrentUser() {
return isCurrentUser(this.member, this.currentUserId);
},
canRemove() {
- return canRemove(this.member, this.sourceId);
+ return canRemove(this.member);
},
canResend() {
return canResend(this.member);
},
canUpdate() {
- return canUpdate(this.member, this.currentUserId, this.sourceId);
+ return canUpdate(this.member, this.currentUserId);
},
},
render() {
diff --git a/app/assets/javascripts/members/constants.js b/app/assets/javascripts/members/constants.js
index 77cb150bff6..f68a8814fee 100644
--- a/app/assets/javascripts/members/constants.js
+++ b/app/assets/javascripts/members/constants.js
@@ -98,3 +98,8 @@ export const REMOVE_GROUP_LINK_MODAL_ID = 'remove-group-link-modal-id';
export const SEARCH_TOKEN_TYPE = 'filtered-search-term';
export const SORT_PARAM = 'sort';
+
+export const MEMBER_ACCESS_LEVEL_PROPERTY_NAME = 'access_level';
+
+export const GROUP_LINK_BASE_PROPERTY_NAME = 'group_link';
+export const GROUP_LINK_ACCESS_LEVEL_PROPERTY_NAME = 'group_access';
diff --git a/app/assets/javascripts/members/index.js b/app/assets/javascripts/members/index.js
new file mode 100644
index 00000000000..fe174d9beb6
--- /dev/null
+++ b/app/assets/javascripts/members/index.js
@@ -0,0 +1,43 @@
+import { GlToast } from '@gitlab/ui';
+import Vue from 'vue';
+import Vuex from 'vuex';
+import { parseDataAttributes } from 'ee_else_ce/members/utils';
+import App from './components/app.vue';
+import membersStore from './store';
+
+export const initMembersApp = (
+ el,
+ {
+ tableFields = [],
+ tableAttrs = {},
+ tableSortableFields = [],
+ requestFormatter = () => {},
+ filteredSearchBar = { show: false },
+ },
+) => {
+ if (!el) {
+ return () => {};
+ }
+
+ Vue.use(Vuex);
+ Vue.use(GlToast);
+
+ const store = new Vuex.Store(
+ membersStore({
+ ...parseDataAttributes(el),
+ currentUserId: gon.current_user_id || null,
+ tableFields,
+ tableAttrs,
+ tableSortableFields,
+ requestFormatter,
+ filteredSearchBar,
+ }),
+ );
+
+ return new Vue({
+ el,
+ components: { App },
+ store,
+ render: (createElement) => createElement('app'),
+ });
+};
diff --git a/app/assets/javascripts/members/store/actions.js b/app/assets/javascripts/members/store/actions.js
index 4c31b3c9744..7b191dd85d0 100644
--- a/app/assets/javascripts/members/store/actions.js
+++ b/app/assets/javascripts/members/store/actions.js
@@ -1,6 +1,6 @@
-import * as types from './mutation_types';
import axios from '~/lib/utils/axios_utils';
import { formatDate } from '~/lib/utils/datetime_utility';
+import * as types from './mutation_types';
export const updateMemberRole = async ({ state, commit }, { memberId, accessLevel }) => {
try {
@@ -11,7 +11,7 @@ export const updateMemberRole = async ({ state, commit }, { memberId, accessLeve
commit(types.RECEIVE_MEMBER_ROLE_SUCCESS, { memberId, accessLevel });
} catch (error) {
- commit(types.RECEIVE_MEMBER_ROLE_ERROR);
+ commit(types.RECEIVE_MEMBER_ROLE_ERROR, { error });
throw error;
}
@@ -37,7 +37,7 @@ export const updateMemberExpiration = async ({ state, commit }, { memberId, expi
expiresAt: expiresAt ? formatDate(expiresAt, 'isoUtcDateTime') : null,
});
} catch (error) {
- commit(types.RECEIVE_MEMBER_EXPIRATION_ERROR);
+ commit(types.RECEIVE_MEMBER_EXPIRATION_ERROR, { error });
throw error;
}
diff --git a/app/assets/javascripts/members/store/index.js b/app/assets/javascripts/members/store/index.js
index 34c102999d2..45f4eefffc9 100644
--- a/app/assets/javascripts/members/store/index.js
+++ b/app/assets/javascripts/members/store/index.js
@@ -1,6 +1,6 @@
-import createState from 'ee_else_ce/members/store/state';
-import mutations from 'ee_else_ce/members/store/mutations';
import * as actions from 'ee_else_ce/members/store/actions';
+import mutations from 'ee_else_ce/members/store/mutations';
+import createState from 'ee_else_ce/members/store/state';
export default (initialState) => ({
state: createState(initialState),
diff --git a/app/assets/javascripts/members/store/mutations.js b/app/assets/javascripts/members/store/mutations.js
index 2415e744290..f4aac1571d6 100644
--- a/app/assets/javascripts/members/store/mutations.js
+++ b/app/assets/javascripts/members/store/mutations.js
@@ -13,10 +13,10 @@ export default {
Vue.set(member, 'accessLevel', accessLevel);
},
- [types.RECEIVE_MEMBER_ROLE_ERROR](state) {
- state.errorMessage = s__(
- "Members|An error occurred while updating the member's role, please try again.",
- );
+ [types.RECEIVE_MEMBER_ROLE_ERROR](state, { error }) {
+ state.errorMessage =
+ error.response?.data?.message ||
+ s__("Members|An error occurred while updating the member's role, please try again.");
state.showError = true;
},
[types.RECEIVE_MEMBER_EXPIRATION_SUCCESS](state, { memberId, expiresAt }) {
@@ -28,10 +28,12 @@ export default {
Vue.set(member, 'expiresAt', expiresAt);
},
- [types.RECEIVE_MEMBER_EXPIRATION_ERROR](state) {
- state.errorMessage = s__(
- "Members|An error occurred while updating the member's expiration date, please try again.",
- );
+ [types.RECEIVE_MEMBER_EXPIRATION_ERROR](state, { error }) {
+ state.errorMessage =
+ error.response?.data?.message ||
+ s__(
+ "Members|An error occurred while updating the member's expiration date, please try again.",
+ );
state.showError = true;
},
[types.HIDE_ERROR](state) {
diff --git a/app/assets/javascripts/members/utils.js b/app/assets/javascripts/members/utils.js
index 780b5a9df57..4de2dadb490 100644
--- a/app/assets/javascripts/members/utils.js
+++ b/app/assets/javascripts/members/utils.js
@@ -1,7 +1,17 @@
-import { __ } from '~/locale';
-import { getParameterByName } from '~/lib/utils/common_utils';
+import { isUndefined } from 'lodash';
+import {
+ getParameterByName,
+ convertObjectPropsToCamelCase,
+ parseBoolean,
+} from '~/lib/utils/common_utils';
import { setUrlParams } from '~/lib/utils/url_utility';
-import { FIELDS, DEFAULT_SORT } from './constants';
+import { __ } from '~/locale';
+import {
+ FIELDS,
+ DEFAULT_SORT,
+ GROUP_LINK_BASE_PROPERTY_NAME,
+ GROUP_LINK_ACCESS_LEVEL_PROPERTY_NAME,
+} from './constants';
export const generateBadges = (member, isCurrentUser) => [
{
@@ -25,26 +35,24 @@ export const isGroup = (member) => {
return Boolean(member.sharedWithGroup);
};
-export const isDirectMember = (member, sourceId) => {
- return isGroup(member) || member.source?.id === sourceId;
+export const isDirectMember = (member) => {
+ return isGroup(member) || member.isDirectMember;
};
export const isCurrentUser = (member, currentUserId) => {
return member.user?.id === currentUserId;
};
-export const canRemove = (member, sourceId) => {
- return isDirectMember(member, sourceId) && member.canRemove;
+export const canRemove = (member) => {
+ return isDirectMember(member) && member.canRemove;
};
export const canResend = (member) => {
return Boolean(member.invite?.canResend);
};
-export const canUpdate = (member, currentUserId, sourceId) => {
- return (
- !isCurrentUser(member, currentUserId) && isDirectMember(member, sourceId) && member.canUpdate
- );
+export const canUpdate = (member, currentUserId) => {
+ return !isCurrentUser(member, currentUserId) && isDirectMember(member) && member.canUpdate;
};
export const parseSortParam = (sortableFields) => {
@@ -95,3 +103,35 @@ export const buildSortHref = ({
// Defined in `ee/app/assets/javascripts/vue_shared/components/members/utils.js`
export const canOverride = () => false;
+
+export const parseDataAttributes = (el) => {
+ const { members, sourceId, memberPath, canManageMembers } = el.dataset;
+
+ return {
+ members: convertObjectPropsToCamelCase(JSON.parse(members), { deep: true }),
+ sourceId: parseInt(sourceId, 10),
+ memberPath,
+ canManageMembers: parseBoolean(canManageMembers),
+ };
+};
+
+export const baseRequestFormatter = (basePropertyName, accessLevelPropertyName) => ({
+ accessLevel,
+ ...otherProperties
+}) => {
+ const accessLevelProperty = !isUndefined(accessLevel)
+ ? { [accessLevelPropertyName]: accessLevel }
+ : {};
+
+ return {
+ [basePropertyName]: {
+ ...accessLevelProperty,
+ ...otherProperties,
+ },
+ };
+};
+
+export const groupLinkRequestFormatter = baseRequestFormatter(
+ GROUP_LINK_BASE_PROPERTY_NAME,
+ GROUP_LINK_ACCESS_LEVEL_PROPERTY_NAME,
+);