Commit 6e73b6fb authored by Vitaly Slobodin's avatar Vitaly Slobodin

Remove redundant request to fetch billable members

We don't need an extra HTTP request for getting
the list of billable members because we can pass this
data from the backend. Doing so means we no longer
need this logic in Vuex store and in components.
parent e2214baa
......@@ -108,11 +108,11 @@ export default {
return this.tables[tableKey].rows;
},
},
mounted() {
created() {
this.fetchSubscription();
},
methods: {
...mapActions(['fetchSubscription']),
...mapActions(['fetchSubscription', 'fetchHasBillableGroupMembers']),
isLast(index) {
return index === this.visibleRows.length - 1;
},
......@@ -151,6 +151,7 @@ export default {
:last="isLast(i)"
:header="row.header"
:columns="row.columns"
:is-free-plan="isFreePlan"
/>
</div>
</div>
......
<script>
import { GlIcon, GlButton } from '@gitlab/ui';
import { mapActions, mapGetters, mapState } from 'vuex';
import { dateInWords } from '~/lib/utils/datetime_utility';
import Popover from '~/vue_shared/components/help_popover.vue';
......@@ -11,7 +10,11 @@ export default {
GlIcon,
Popover,
},
inject: ['billableSeatsHref', 'isGroup'],
inject: {
billableSeatsHref: {
default: '',
},
},
props: {
header: {
type: Object,
......@@ -26,21 +29,18 @@ export default {
required: false,
default: false,
},
isFreePlan: {
type: Boolean,
required: false,
default: false,
},
},
computed: {
...mapState(['hasBillableGroupMembers']),
...mapGetters(['isFreePlan']),
rowClasses() {
return !this.last ? 'gl-border-b-gray-100 gl-border-b-1 gl-border-b-solid' : null;
},
},
created() {
if (this.isGroup) {
this.fetchHasBillableGroupMembers();
}
},
methods: {
...mapActions(['fetchHasBillableGroupMembers']),
getPopoverOptions(col) {
const defaults = {
placement: 'bottom',
......@@ -63,7 +63,7 @@ export default {
return typeof col.value !== 'undefined' && col.value !== null ? col.value : ' - ';
},
isSeatsUsageButtonShown(col) {
return this.hasBillableGroupMembers && this.billableSeatsHref && col.id === 'seatsInUse';
return this.billableSeatsHref && col.id === 'seatsInUse';
},
},
};
......
......@@ -29,27 +29,3 @@ export const receiveSubscriptionError = ({ commit }) => {
});
commit(types.RECEIVE_SUBSCRIPTION_ERROR);
};
/**
* Billable Members
*/
export const fetchHasBillableGroupMembers = ({ dispatch, state }) => {
dispatch('requestHasBillableGroupMembers');
return Api.fetchBillableGroupMembersList(state.namespaceId, { per_page: 1, page: 1 })
.then((data) => dispatch('receiveHasBillableGroupMembersSuccess', data))
.catch(() => dispatch('receiveHasBillableGroupMembersError'));
};
export const requestHasBillableGroupMembers = ({ commit }) =>
commit(types.REQUEST_HAS_BILLABLE_MEMBERS);
export const receiveHasBillableGroupMembersSuccess = ({ commit }, response) =>
commit(types.RECEIVE_HAS_BILLABLE_MEMBERS_SUCCESS, response);
export const receiveHasBillableGroupMembersError = ({ commit }) => {
createFlash({
message: s__('SubscriptionTable|An error occurred while loading billable members list'),
});
commit(types.RECEIVE_HAS_BILLABLE_MEMBERS_ERROR);
};
......@@ -3,7 +3,3 @@ export const SET_NAMESPACE_ID = 'SET_NAMESPACE_ID';
export const REQUEST_SUBSCRIPTION = 'REQUEST_SUBSCRIPTION';
export const RECEIVE_SUBSCRIPTION_SUCCESS = 'RECEIVE_SUBSCRIPTION_SUCCESS';
export const RECEIVE_SUBSCRIPTION_ERROR = 'RECEIVE_SUBSCRIPTION_ERROR';
export const REQUEST_HAS_BILLABLE_MEMBERS = 'REQUEST_HAS_BILLABLE_MEMBERS';
export const RECEIVE_HAS_BILLABLE_MEMBERS_SUCCESS = 'RECEIVE_HAS_BILLABLE_MEMBERS_SUCCESS';
export const RECEIVE_HAS_BILLABLE_MEMBERS_ERROR = 'RECEIVE_HAS_BILLABLE_MEMBERS_ERROR';
import { parseInt } from 'lodash';
import Vue from 'vue';
import {
TABLE_TYPE_DEFAULT,
TABLE_TYPE_FREE,
TABLE_TYPE_TRIAL,
HEADER_TOTAL_ENTRIES,
} from 'ee/billings/constants';
import { TABLE_TYPE_DEFAULT, TABLE_TYPE_FREE, TABLE_TYPE_TRIAL } from 'ee/billings/constants';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import * as types from './mutation_types';
......@@ -49,22 +43,4 @@ export default {
state.isLoadingSubscription = false;
state.hasErrorSubscription = true;
},
[types.REQUEST_HAS_BILLABLE_MEMBERS](state) {
state.isLoadingHasBillableMembers = true;
state.hasErrorHasBillableMembers = false;
},
[types.RECEIVE_HAS_BILLABLE_MEMBERS_SUCCESS](state, payload) {
const { headers } = payload;
const hasBillableGroupMembers = parseInt(headers[HEADER_TOTAL_ENTRIES], 10) > 0;
state.hasBillableGroupMembers = hasBillableGroupMembers;
state.isLoadingHasBillableMembers = false;
},
[types.RECEIVE_HAS_BILLABLE_MEMBERS_ERROR](state) {
state.isLoadinggHasBillableMembers = false;
state.hasErrorHasBillableMembers = true;
},
};
......@@ -3,8 +3,6 @@ import { s__ } from '~/locale';
export default () => ({
isLoadingSubscription: false,
hasErrorSubscription: false,
isLoadingBillableMembers: false,
hasErrorBillableMembers: false,
namespaceId: null,
plan: {
code: null,
......@@ -171,5 +169,4 @@ export default () => ({
],
},
},
hasBillableGroupMembers: false,
});
......@@ -39,15 +39,7 @@ describe('subscription table row', () => {
const defaultProps = { header: HEADER, columns: COLUMNS };
const createComponent = ({
props = {},
billableSeatsHref = BILLABLE_SEATS_URL,
isGroup = true,
} = {}) => {
if (wrapper) {
throw new Error('wrapper already exists!');
}
const createComponent = ({ props = {}, billableSeatsHref = BILLABLE_SEATS_URL } = {}) => {
wrapper = shallowMount(SubscriptionTableRow, {
propsData: {
...defaultProps,
......@@ -55,7 +47,6 @@ describe('subscription table row', () => {
},
provide: {
billableSeatsHref,
isGroup,
},
store,
localVue,
......@@ -69,7 +60,6 @@ describe('subscription table row', () => {
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
const findHeaderCell = () => wrapper.find('[data-testid="header-cell"]');
......@@ -88,18 +78,6 @@ describe('subscription table row', () => {
const findUsageButton = () => findContentCells().at(0).find('[data-testid="seats-usage-button"]');
describe('dispatched actions', () => {
it('dispatches action when created if namespace is group', () => {
createComponent();
expect(store.dispatch).toHaveBeenCalledWith('fetchHasBillableGroupMembers');
});
it('does not dispatch action when created if namespace is not group', () => {
createComponent({ isGroup: false });
expect(store.dispatch).not.toHaveBeenCalledWith('fetchHasBillableGroupMembers');
});
});
describe('default', () => {
beforeEach(() => {
createComponent();
......@@ -156,7 +134,7 @@ describe('subscription table row', () => {
};
it('renders a dash when the value is zero', () => {
createComponent({ props: { columns: [dateColumn] } });
createComponent({ props: { isFreePlan: true, columns: [dateColumn] } });
expect(wrapper.find('[data-testid="property-value"]').text()).toBe('-');
});
......@@ -185,22 +163,23 @@ describe('subscription table row', () => {
});
});
it.each`
state | columnId | provide | exists | attrs
${{ hasBillableGroupMembers: true }} | ${'seatsInUse'} | ${{}} | ${true} | ${{ href: BILLABLE_SEATS_URL }}
${{ hasBillableGroupMembers: true }} | ${'seatsInUse'} | ${{ billableSeatsHref: '' }} | ${false} | ${{}}
${{ hasBillableGroupMembers: true }} | ${'some_value'} | ${{}} | ${false} | ${{}}
${{ hasBillableGroupMembers: false }} | ${'seatsInUse'} | ${{}} | ${false} | ${{}}
`(
'should exists=$exists with (state=$state, columnId=$columnId, provide=$provide)',
({ state, columnId, provide, exists, attrs }) => {
Object.assign(store.state, state);
createComponent({ props: { columns: [{ id: columnId }] }, ...provide });
expect(findUsageButton().exists()).toBe(exists);
if (exists) {
expect(findUsageButton().attributes()).toMatchObject(attrs);
}
},
);
describe('seats in use button', () => {
it.each`
columnId | provide | exists | attrs
${'seatsInUse'} | ${{}} | ${true} | ${{ href: BILLABLE_SEATS_URL }}
${'seatsInUse'} | ${{ billableSeatsHref: '' }} | ${false} | ${{}}
${'some_value'} | ${{}} | ${false} | ${{}}
${'seatsInUse'} | ${{ billableSeatsHref: null }} | ${false} | ${{}}
`(
'should exists=$exists with (columnId=$columnId, provide=$provide)',
({ columnId, provide, exists, attrs }) => {
createComponent({ props: { columns: [{ id: columnId }] }, ...provide });
expect(findUsageButton().exists()).toBe(exists);
if (exists) {
expect(findUsageButton().attributes()).toMatchObject(attrs);
}
},
);
});
});
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