summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/members
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/members')
-rw-r--r--app/assets/javascripts/members/components/action_buttons/user_action_buttons.vue1
-rw-r--r--app/assets/javascripts/members/components/app.vue7
-rw-r--r--app/assets/javascripts/members/components/filter_sort/members_filtered_search_bar.vue20
-rw-r--r--app/assets/javascripts/members/components/members_tabs.vue45
-rw-r--r--app/assets/javascripts/members/components/table/members_table.vue19
-rw-r--r--app/assets/javascripts/members/constants.js9
-rw-r--r--app/assets/javascripts/members/utils.js4
7 files changed, 72 insertions, 33 deletions
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 1e9f79927ea..0c20f935d50 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
@@ -38,6 +38,7 @@ export default {
usersName: user.name,
source: source.fullName,
},
+ false,
);
}
diff --git a/app/assets/javascripts/members/components/app.vue b/app/assets/javascripts/members/components/app.vue
index a08518584f3..0ec39f58930 100644
--- a/app/assets/javascripts/members/components/app.vue
+++ b/app/assets/javascripts/members/components/app.vue
@@ -19,6 +19,11 @@ export default {
type: String,
required: true,
},
+ tabQueryParamValue: {
+ type: String,
+ required: false,
+ default: '',
+ },
},
computed: {
...mapState({
@@ -55,6 +60,6 @@ export default {
errorMessage
}}</gl-alert>
<filter-sort-container />
- <members-table />
+ <members-table :tab-query-param-value="tabQueryParamValue" />
</div>
</template>
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 cc0533391df..33d86dec767 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,10 +1,13 @@
<script>
import { GlFilteredSearchToken } from '@gitlab/ui';
import { mapState } from 'vuex';
-import { getParameterByName, urlParamsToObject } from '~/lib/utils/common_utils';
-import { setUrlParams } from '~/lib/utils/url_utility';
+import { getParameterByName, setUrlParams, queryToObject } from '~/lib/utils/url_utility';
import { s__ } from '~/locale';
-import { SEARCH_TOKEN_TYPE, SORT_PARAM } from '~/members/constants';
+import {
+ SEARCH_TOKEN_TYPE,
+ SORT_QUERY_PARAM_NAME,
+ ACTIVE_TAB_QUERY_PARAM_NAME,
+} from '~/members/constants';
import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants';
import FilteredSearchBar from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
@@ -64,7 +67,7 @@ export default {
},
},
created() {
- const query = urlParamsToObject(window.location.search);
+ const query = queryToObject(window.location.search);
const tokens = this.tokens
.filter((token) => query[token.type])
@@ -116,10 +119,15 @@ export default {
return accumulator;
}, {});
- const sortParam = getParameterByName(SORT_PARAM);
+ const sortParamValue = getParameterByName(SORT_QUERY_PARAM_NAME);
+ const activeTabParamValue = getParameterByName(ACTIVE_TAB_QUERY_PARAM_NAME);
window.location.href = setUrlParams(
- { ...params, ...(sortParam && { sort: sortParam }) },
+ {
+ ...params,
+ ...(sortParamValue && { [SORT_QUERY_PARAM_NAME]: sortParamValue }),
+ ...(activeTabParamValue && { [ACTIVE_TAB_QUERY_PARAM_NAME]: activeTabParamValue }),
+ },
window.location.href,
true,
);
diff --git a/app/assets/javascripts/members/components/members_tabs.vue b/app/assets/javascripts/members/components/members_tabs.vue
index 37b9135126d..7c21e33d892 100644
--- a/app/assets/javascripts/members/components/members_tabs.vue
+++ b/app/assets/javascripts/members/components/members_tabs.vue
@@ -1,16 +1,18 @@
<script>
import { GlTabs, GlTab, GlBadge } from '@gitlab/ui';
import { mapState } from 'vuex';
-import { urlParamsToObject } from '~/lib/utils/common_utils';
+// eslint-disable-next-line import/no-deprecated
+import { urlParamsToObject } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
-import { MEMBER_TYPES } from '../constants';
+import { MEMBER_TYPES, TAB_QUERY_PARAM_VALUES, ACTIVE_TAB_QUERY_PARAM_NAME } from '../constants';
import MembersApp from './app.vue';
const countComputed = (state, namespace) => state[namespace]?.pagination?.totalItems || 0;
export default {
name: 'MembersTabs',
- tabs: [
+ ACTIVE_TAB_QUERY_PARAM_NAME,
+ TABS: [
{
namespace: MEMBER_TYPES.user,
title: __('Members'),
@@ -19,19 +21,21 @@ export default {
namespace: MEMBER_TYPES.group,
title: __('Groups'),
attrs: { 'data-qa-selector': 'groups_list_tab' },
+ queryParamValue: TAB_QUERY_PARAM_VALUES.group,
},
{
namespace: MEMBER_TYPES.invite,
title: __('Invited'),
canManageMembersPermissionsRequired: true,
+ queryParamValue: TAB_QUERY_PARAM_VALUES.invite,
},
{
namespace: MEMBER_TYPES.accessRequest,
title: __('Access requests'),
canManageMembersPermissionsRequired: true,
+ queryParamValue: TAB_QUERY_PARAM_VALUES.accessRequest,
},
],
- urlParams: [],
components: { MembersApp, GlTabs, GlTab, GlBadge },
inject: ['canManageMembers'],
data() {
@@ -55,32 +59,22 @@ export default {
},
}),
urlParams() {
+ // eslint-disable-next-line import/no-deprecated
return Object.keys(urlParamsToObject(window.location.search));
},
activeTabIndexCalculatedFromUrlParams() {
- return this.$options.tabs.findIndex(({ namespace }) => {
+ return this.$options.TABS.findIndex(({ namespace }) => {
return this.getTabUrlParams(namespace).some((urlParam) =>
this.urlParams.includes(urlParam),
);
});
},
},
- created() {
- if (this.activeTabIndexCalculatedFromUrlParams === -1) {
- return;
- }
-
- this.selectedTabIndex = this.activeTabIndexCalculatedFromUrlParams;
- },
methods: {
getTabUrlParams(namespace) {
const state = this.$store.state[namespace];
const urlParams = [];
- if (state?.pagination?.paramName) {
- urlParams.push(state.pagination.paramName);
- }
-
if (state?.filteredSearchBar?.searchParam) {
urlParams.push(state.filteredSearchBar.searchParam);
}
@@ -110,14 +104,23 @@ export default {
</script>
<template>
- <gl-tabs v-model="selectedTabIndex">
- <template v-for="(tab, index) in $options.tabs">
- <gl-tab v-if="showTab(tab, index)" :key="tab.namespace" :title-link-attributes="tab.attrs">
- <template slot="title">
+ <gl-tabs
+ v-model="selectedTabIndex"
+ sync-active-tab-with-query-params
+ :query-param-name="$options.ACTIVE_TAB_QUERY_PARAM_NAME"
+ >
+ <template v-for="(tab, index) in $options.TABS">
+ <gl-tab
+ v-if="showTab(tab, index)"
+ :key="tab.namespace"
+ :title-link-attributes="tab.attrs"
+ :query-param-value="tab.queryParamValue"
+ >
+ <template #title>
<span>{{ tab.title }}</span>
<gl-badge size="sm" class="gl-tab-counter-badge">{{ getTabCount(tab) }}</gl-badge>
</template>
- <members-app :namespace="tab.namespace" />
+ <members-app :namespace="tab.namespace" :tab-query-param-value="tab.queryParamValue" />
</gl-tab>
</template>
</gl-tabs>
diff --git a/app/assets/javascripts/members/components/table/members_table.vue b/app/assets/javascripts/members/components/table/members_table.vue
index 09ef98ec411..b9c80edbc49 100644
--- a/app/assets/javascripts/members/components/table/members_table.vue
+++ b/app/assets/javascripts/members/components/table/members_table.vue
@@ -5,7 +5,7 @@ import MembersTableCell from 'ee_else_ce/members/components/table/members_table_
import { canOverride, canRemove, canResend, canUpdate } from 'ee_else_ce/members/utils';
import { mergeUrlParams } from '~/lib/utils/url_utility';
import initUserPopovers from '~/user_popovers';
-import { FIELDS } from '../../constants';
+import { FIELDS, ACTIVE_TAB_QUERY_PARAM_NAME } from '../../constants';
import RemoveGroupLinkModal from '../modals/remove_group_link_modal.vue';
import CreatedAt from './created_at.vue';
import ExpirationDatepicker from './expiration_datepicker.vue';
@@ -34,6 +34,13 @@ export default {
import('ee_component/members/components/ldap/ldap_override_confirmation_modal.vue'),
},
inject: ['namespace', 'currentUserId'],
+ props: {
+ tabQueryParamValue: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ },
computed: {
...mapState({
members(state) {
@@ -112,7 +119,15 @@ export default {
paginationLinkGenerator(page) {
const { params = {}, paramName } = this.pagination;
- return mergeUrlParams({ ...params, [paramName]: page }, window.location.href);
+ return mergeUrlParams(
+ {
+ ...params,
+ [ACTIVE_TAB_QUERY_PARAM_NAME]:
+ this.tabQueryParamValue !== '' ? this.tabQueryParamValue : null,
+ [paramName]: page,
+ },
+ window.location.href,
+ );
},
},
};
diff --git a/app/assets/javascripts/members/constants.js b/app/assets/javascripts/members/constants.js
index f68a8814fee..6f465245d20 100644
--- a/app/assets/javascripts/members/constants.js
+++ b/app/assets/javascripts/members/constants.js
@@ -89,6 +89,12 @@ export const MEMBER_TYPES = {
accessRequest: 'accessRequest',
};
+export const TAB_QUERY_PARAM_VALUES = {
+ group: 'groups',
+ invite: 'invited',
+ accessRequest: 'access_requests',
+};
+
export const DAYS_TO_EXPIRE_SOON = 7;
export const LEAVE_MODAL_ID = 'member-leave-modal';
@@ -97,7 +103,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 SORT_QUERY_PARAM_NAME = 'sort';
+export const ACTIVE_TAB_QUERY_PARAM_NAME = 'tab';
export const MEMBER_ACCESS_LEVEL_PROPERTY_NAME = 'access_level';
diff --git a/app/assets/javascripts/members/utils.js b/app/assets/javascripts/members/utils.js
index be549b40885..05f086c8f4f 100644
--- a/app/assets/javascripts/members/utils.js
+++ b/app/assets/javascripts/members/utils.js
@@ -1,6 +1,6 @@
import { isUndefined } from 'lodash';
-import { getParameterByName, convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
-import { setUrlParams } from '~/lib/utils/url_utility';
+import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
+import { getParameterByName, setUrlParams } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
import {
FIELDS,