Commit 9eb0d01c authored by Phil Hughes's avatar Phil Hughes

Merge branch '329658-add-job-project-count' into 'master'

Add project and job count

See merge request gitlab-org/gitlab!64178
parents c677b7b6 d01f632f
...@@ -3,6 +3,7 @@ import { GlTable, GlTooltipDirective, GlSkeletonLoader } from '@gitlab/ui'; ...@@ -3,6 +3,7 @@ import { GlTable, GlTooltipDirective, GlSkeletonLoader } from '@gitlab/ui';
import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { formatNumber, sprintf, __, s__ } from '~/locale'; import { formatNumber, sprintf, __, s__ } from '~/locale';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import { RUNNER_JOB_COUNT_LIMIT } from '../constants';
import RunnerActionsCell from './cells/runner_actions_cell.vue'; import RunnerActionsCell from './cells/runner_actions_cell.vue';
import RunnerNameCell from './cells/runner_name_cell.vue'; import RunnerNameCell from './cells/runner_name_cell.vue';
import RunnerTypeCell from './cells/runner_type_cell.vue'; import RunnerTypeCell from './cells/runner_type_cell.vue';
...@@ -64,6 +65,18 @@ export default { ...@@ -64,6 +65,18 @@ export default {
}, },
}, },
methods: { methods: {
formatProjectCount(projectCount) {
if (projectCount === null) {
return __('n/a');
}
return formatNumber(projectCount);
},
formatJobCount(jobCount) {
if (jobCount > RUNNER_JOB_COUNT_LIMIT) {
return `${formatNumber(RUNNER_JOB_COUNT_LIMIT)}+`;
}
return formatNumber(jobCount);
},
runnerTrAttr(runner) { runnerTrAttr(runner) {
if (runner) { if (runner) {
return { return {
...@@ -117,12 +130,12 @@ export default { ...@@ -117,12 +130,12 @@ export default {
{{ ipAddress }} {{ ipAddress }}
</template> </template>
<template #cell(projectCount)> <template #cell(projectCount)="{ item: { projectCount } }">
<!-- TODO add projects count --> {{ formatProjectCount(projectCount) }}
</template> </template>
<template #cell(jobCount)> <template #cell(jobCount)="{ item: { jobCount } }">
<!-- TODO add jobs count --> {{ formatJobCount(jobCount) }}
</template> </template>
<template #cell(tagList)="{ item: { tagList } }"> <template #cell(tagList)="{ item: { tagList } }">
......
import { s__ } from '~/locale'; import { s__ } from '~/locale';
export const RUNNER_PAGE_SIZE = 20; export const RUNNER_PAGE_SIZE = 20;
export const RUNNER_JOB_COUNT_LIMIT = 1000;
export const I18N_DETAILS_TITLE = s__('Runners|Runner #%{runner_id}'); export const I18N_DETAILS_TITLE = s__('Runners|Runner #%{runner_id}');
......
...@@ -10,4 +10,6 @@ fragment RunnerNode on CiRunner { ...@@ -10,4 +10,6 @@ fragment RunnerNode on CiRunner {
locked locked
tagList tagList
contactedAt contactedAt
jobCount
projectCount
} }
import { GlLink, GlTable, GlSkeletonLoader } from '@gitlab/ui'; import { GlLink, GlTable, GlSkeletonLoader } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils'; import { mount, shallowMount } from '@vue/test-utils';
import { cloneDeep } from 'lodash';
import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import RunnerList from '~/runner/components/runner_list.vue'; import RunnerList from '~/runner/components/runner_list.vue';
...@@ -85,12 +86,11 @@ describe('RunnerList', () => { ...@@ -85,12 +86,11 @@ describe('RunnerList', () => {
); );
expect(findCell({ fieldKey: 'name' }).text()).toContain(description); expect(findCell({ fieldKey: 'name' }).text()).toContain(description);
// Other fields: some cells are empty in the first iteration // Other fields
// See https://gitlab.com/gitlab-org/gitlab/-/issues/329658#pending-features
expect(findCell({ fieldKey: 'version' }).text()).toBe(version); expect(findCell({ fieldKey: 'version' }).text()).toBe(version);
expect(findCell({ fieldKey: 'ipAddress' }).text()).toBe(ipAddress); expect(findCell({ fieldKey: 'ipAddress' }).text()).toBe(ipAddress);
expect(findCell({ fieldKey: 'projectCount' }).text()).toBe(''); expect(findCell({ fieldKey: 'projectCount' }).text()).toBe('1');
expect(findCell({ fieldKey: 'jobCount' }).text()).toBe(''); expect(findCell({ fieldKey: 'jobCount' }).text()).toBe('0');
expect(findCell({ fieldKey: 'tagList' }).text()).toBe(''); expect(findCell({ fieldKey: 'tagList' }).text()).toBe('');
expect(findCell({ fieldKey: 'contactedAt' }).text()).toEqual(expect.any(String)); expect(findCell({ fieldKey: 'contactedAt' }).text()).toEqual(expect.any(String));
...@@ -101,6 +101,54 @@ describe('RunnerList', () => { ...@@ -101,6 +101,54 @@ describe('RunnerList', () => {
expect(actions.findByTestId('toggle-active-runner').exists()).toBe(true); expect(actions.findByTestId('toggle-active-runner').exists()).toBe(true);
}); });
describe('Table data formatting', () => {
let mockRunnersCopy;
beforeEach(() => {
mockRunnersCopy = cloneDeep(mockRunners);
});
it('Formats null project counts', () => {
mockRunnersCopy[0].projectCount = null;
createComponent({ props: { runners: mockRunnersCopy } }, mount);
expect(findCell({ fieldKey: 'projectCount' }).text()).toBe('n/a');
});
it('Formats 0 project counts', () => {
mockRunnersCopy[0].projectCount = 0;
createComponent({ props: { runners: mockRunnersCopy } }, mount);
expect(findCell({ fieldKey: 'projectCount' }).text()).toBe('0');
});
it('Formats big project counts', () => {
mockRunnersCopy[0].projectCount = 1000;
createComponent({ props: { runners: mockRunnersCopy } }, mount);
expect(findCell({ fieldKey: 'projectCount' }).text()).toBe('1,000');
});
it('Formats job counts', () => {
mockRunnersCopy[0].jobCount = 1000;
createComponent({ props: { runners: mockRunnersCopy } }, mount);
expect(findCell({ fieldKey: 'jobCount' }).text()).toBe('1,000');
});
it('Formats big job counts with a plus symbol', () => {
mockRunnersCopy[0].jobCount = 1001;
createComponent({ props: { runners: mockRunnersCopy } }, mount);
expect(findCell({ fieldKey: 'jobCount' }).text()).toBe('1,000+');
});
});
it('Links to the runner page', () => { it('Links to the runner page', () => {
const { id } = mockRunners[0]; const { id } = mockRunners[0];
......
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