Merge branch '52712-further-ui-improvements-to-profile-overview-tab' into 'master'
Resolve "Further UI improvements to Profile "Overview" tab" Closes #52712 See merge request gitlab-org/gitlab-ce!22977
This commit is contained in:
commit
41a3fa57f0
8 changed files with 96 additions and 104 deletions
|
@ -10,6 +10,7 @@ export default class UserOverviewBlock {
|
|||
limit: DEFAULT_LIMIT,
|
||||
...options.requestParams,
|
||||
};
|
||||
this.postRenderCallback = options.postRenderCallback;
|
||||
this.loadData();
|
||||
}
|
||||
|
||||
|
@ -43,5 +44,9 @@ export default class UserOverviewBlock {
|
|||
}
|
||||
|
||||
loadingEl.classList.add('hide');
|
||||
|
||||
if (this.postRenderCallback) {
|
||||
this.postRenderCallback.call(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,8 @@ import $ from 'jquery';
|
|||
import axios from '~/lib/utils/axios_utils';
|
||||
import Activities from '~/activities';
|
||||
import { localTimeAgo } from '~/lib/utils/datetime_utility';
|
||||
import { __, sprintf } from '~/locale';
|
||||
import AjaxCache from '~/lib/utils/ajax_cache';
|
||||
import { __ } from '~/locale';
|
||||
import flash from '~/flash';
|
||||
import ActivityCalendar from './activity_calendar';
|
||||
import UserOverviewBlock from './user_overview_block';
|
||||
|
@ -62,23 +63,20 @@ import UserOverviewBlock from './user_overview_block';
|
|||
* </div>
|
||||
*/
|
||||
|
||||
const CALENDAR_TEMPLATES = {
|
||||
activity: `
|
||||
<div class="clearfix calendar">
|
||||
<div class="js-contrib-calendar"></div>
|
||||
<div class="calendar-hint bottom-right"></div>
|
||||
</div>
|
||||
`,
|
||||
overview: `
|
||||
<div class="clearfix calendar">
|
||||
<div class="calendar-hint"></div>
|
||||
<div class="js-contrib-calendar prepend-top-20"></div>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
const CALENDAR_TEMPLATE = `
|
||||
<div class="clearfix calendar">
|
||||
<div class="js-contrib-calendar"></div>
|
||||
<div class="calendar-hint bottom-right"></div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const CALENDAR_PERIOD_6_MONTHS = 6;
|
||||
const CALENDAR_PERIOD_12_MONTHS = 12;
|
||||
/* computation based on
|
||||
* width = (group + 1) * this.daySizeWithSpace + this.getExtraWidthPadding(group);
|
||||
* (see activity_calendar.js)
|
||||
*/
|
||||
const OVERVIEW_CALENDAR_BREAKPOINT = 918;
|
||||
|
||||
export default class UserTabs {
|
||||
constructor({ defaultAction, action, parentEl }) {
|
||||
|
@ -105,6 +103,12 @@ export default class UserTabs {
|
|||
.off('shown.bs.tab', '.nav-links a[data-toggle="tab"]')
|
||||
.on('shown.bs.tab', '.nav-links a[data-toggle="tab"]', event => this.tabShown(event))
|
||||
.on('click', '.gl-pagination a', event => this.changeProjectsPage(event));
|
||||
|
||||
window.addEventListener('resize', () => this.onResize());
|
||||
}
|
||||
|
||||
onResize() {
|
||||
this.loadActivityCalendar();
|
||||
}
|
||||
|
||||
changeProjectsPage(e) {
|
||||
|
@ -167,8 +171,6 @@ export default class UserTabs {
|
|||
return;
|
||||
}
|
||||
|
||||
this.loadActivityCalendar('activity');
|
||||
|
||||
// eslint-disable-next-line no-new
|
||||
new Activities('#activity');
|
||||
|
||||
|
@ -180,10 +182,10 @@ export default class UserTabs {
|
|||
return;
|
||||
}
|
||||
|
||||
this.loadActivityCalendar('overview');
|
||||
this.loadActivityCalendar();
|
||||
|
||||
UserTabs.renderMostRecentBlocks('#js-overview .activities-block', {
|
||||
requestParams: { limit: 5 },
|
||||
requestParams: { limit: 10 },
|
||||
});
|
||||
UserTabs.renderMostRecentBlocks('#js-overview .projects-block', {
|
||||
requestParams: { limit: 10, skip_pagination: true },
|
||||
|
@ -198,52 +200,39 @@ export default class UserTabs {
|
|||
container,
|
||||
url: $(`${container} .overview-content-list`).data('href'),
|
||||
...options,
|
||||
postRenderCallback: () => localTimeAgo($('.js-timeago', container)),
|
||||
});
|
||||
}
|
||||
|
||||
loadActivityCalendar(action) {
|
||||
const monthsAgo = action === 'overview' ? CALENDAR_PERIOD_6_MONTHS : CALENDAR_PERIOD_12_MONTHS;
|
||||
loadActivityCalendar() {
|
||||
const $calendarWrap = this.$parentEl.find('.tab-pane.active .user-calendar');
|
||||
const calendarPath = $calendarWrap.data('calendarPath');
|
||||
|
||||
AjaxCache.retrieve(calendarPath)
|
||||
.then(data => UserTabs.renderActivityCalendar(data, $calendarWrap))
|
||||
.catch(() => flash(__('There was an error loading users activity calendar.')));
|
||||
}
|
||||
|
||||
static renderActivityCalendar(data, $calendarWrap) {
|
||||
const monthsAgo = UserTabs.getVisibleCalendarPeriod($calendarWrap);
|
||||
const calendarActivitiesPath = $calendarWrap.data('calendarActivitiesPath');
|
||||
const utcOffset = $calendarWrap.data('utcOffset');
|
||||
let utcFormatted = 'UTC';
|
||||
if (utcOffset !== 0) {
|
||||
utcFormatted = `UTC${utcOffset > 0 ? '+' : ''}${utcOffset / 3600}`;
|
||||
}
|
||||
const calendarHint = __('Issues, merge requests, pushes and comments.');
|
||||
|
||||
axios
|
||||
.get(calendarPath)
|
||||
.then(({ data }) => {
|
||||
$calendarWrap.html(CALENDAR_TEMPLATES[action]);
|
||||
$calendarWrap.html(CALENDAR_TEMPLATE);
|
||||
|
||||
let calendarHint = '';
|
||||
$calendarWrap.find('.calendar-hint').text(calendarHint);
|
||||
|
||||
if (action === 'activity') {
|
||||
calendarHint = sprintf(
|
||||
__(
|
||||
'Summary of issues, merge requests, push events, and comments (Timezone: %{utcFormatted})',
|
||||
),
|
||||
{ utcFormatted },
|
||||
);
|
||||
} else if (action === 'overview') {
|
||||
calendarHint = __('Issues, merge requests, pushes and comments.');
|
||||
}
|
||||
|
||||
$calendarWrap.find('.calendar-hint').text(calendarHint);
|
||||
|
||||
// eslint-disable-next-line no-new
|
||||
new ActivityCalendar(
|
||||
'.tab-pane.active .js-contrib-calendar',
|
||||
'.tab-pane.active .user-calendar-activities',
|
||||
data,
|
||||
calendarActivitiesPath,
|
||||
utcOffset,
|
||||
0,
|
||||
monthsAgo,
|
||||
);
|
||||
})
|
||||
.catch(() => flash(__('There was an error loading users activity calendar.')));
|
||||
// eslint-disable-next-line no-new
|
||||
new ActivityCalendar(
|
||||
'.tab-pane.active .js-contrib-calendar',
|
||||
'.tab-pane.active .user-calendar-activities',
|
||||
data,
|
||||
calendarActivitiesPath,
|
||||
utcOffset,
|
||||
0,
|
||||
monthsAgo,
|
||||
);
|
||||
}
|
||||
|
||||
toggleLoading(status) {
|
||||
|
@ -267,4 +256,11 @@ export default class UserTabs {
|
|||
getCurrentAction() {
|
||||
return this.$parentEl.find('.nav-links a.active').data('action');
|
||||
}
|
||||
|
||||
static getVisibleCalendarPeriod($calendarWrap) {
|
||||
const width = $calendarWrap.width();
|
||||
return width < OVERVIEW_CALENDAR_BREAKPOINT
|
||||
? CALENDAR_PERIOD_6_MONTHS
|
||||
: CALENDAR_PERIOD_12_MONTHS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +1,30 @@
|
|||
.row
|
||||
.col-12
|
||||
.calendar-block.prepend-top-default.append-bottom-default
|
||||
.user-calendar.d-none.d-sm-block{ data: { calendar_path: user_calendar_path(@user, :json), calendar_activities_path: user_calendar_activities_path, utc_offset: Time.zone.utc_offset } }
|
||||
%h4.center.light
|
||||
= spinner nil, true
|
||||
.user-calendar-activities.d-none.d-sm-block
|
||||
.row
|
||||
.col-md-12.col-lg-6
|
||||
.calendar-block
|
||||
.content-block.hide-bottom-border
|
||||
%h4
|
||||
= s_('UserProfile|Activity')
|
||||
.user-calendar.d-none.d-sm-block.text-left{ data: { calendar_path: user_calendar_path(@user, :json), calendar_activities_path: user_calendar_activities_path, utc_offset: Time.zone.utc_offset } }
|
||||
%h4.center.light
|
||||
%i.fa.fa-spinner.fa-spin
|
||||
.user-calendar-activities.d-none.d-sm-block
|
||||
|
||||
- if can?(current_user, :read_cross_project)
|
||||
.activities-block
|
||||
.border-bottom.prepend-top-16
|
||||
%h5
|
||||
= s_('UserProfile|Recent contributions')
|
||||
.prepend-top-16
|
||||
.d-flex.align-items-center.border-bottom
|
||||
%h4.flex-grow
|
||||
= s_('UserProfile|Activity')
|
||||
= link_to s_('UserProfile|View all'), user_activity_path, class: "hide js-view-all"
|
||||
.overview-content-list{ data: { href: user_path } }
|
||||
.center.light.loading
|
||||
%i.fa.fa-spinner.fa-spin
|
||||
.prepend-top-10
|
||||
= link_to s_('UserProfile|View all'), user_activity_path, class: "hide js-view-all"
|
||||
= spinner nil, true
|
||||
|
||||
.col-md-12.col-lg-6
|
||||
.projects-block
|
||||
.border-bottom.prepend-top-16
|
||||
%h4
|
||||
= s_('UserProfile|Personal projects')
|
||||
.prepend-top-16
|
||||
.d-flex.align-items-center.border-bottom
|
||||
%h4.flex-grow
|
||||
= s_('UserProfile|Personal projects')
|
||||
= link_to s_('UserProfile|View all'), user_projects_path, class: "hide js-view-all"
|
||||
.overview-content-list{ data: { href: user_projects_path } }
|
||||
.center.light.loading
|
||||
%i.fa.fa-spinner.fa-spin
|
||||
.prepend-top-10
|
||||
= link_to s_('UserProfile|View all'), user_projects_path, class: "hide js-view-all"
|
||||
= spinner nil, true
|
||||
|
|
|
@ -124,12 +124,6 @@
|
|||
|
||||
- if profile_tab?(:activity)
|
||||
#activity.tab-pane
|
||||
.row-content-block.calendar-block.white.second-block.d-none.d-sm-block
|
||||
.user-calendar{ data: { calendar_path: user_calendar_path(@user, :json), calendar_activities_path: user_calendar_activities_path, utc_offset: Time.zone.utc_offset } }
|
||||
%h4.center.light
|
||||
%i.fa.fa-spinner.fa-spin
|
||||
.user-calendar-activities
|
||||
|
||||
- if can?(current_user, :read_cross_project)
|
||||
%h4.prepend-top-20
|
||||
= s_('UserProfile|Most Recent Activity')
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: UI improvements to user's profile
|
||||
merge_request: 22977
|
||||
author:
|
||||
type: other
|
|
@ -5961,9 +5961,6 @@ msgstr ""
|
|||
msgid "Subscribed"
|
||||
msgstr ""
|
||||
|
||||
msgid "Summary of issues, merge requests, push events, and comments (Timezone: %{utcFormatted})"
|
||||
msgstr ""
|
||||
|
||||
msgid "Switch branch/tag"
|
||||
msgstr ""
|
||||
|
||||
|
@ -6837,9 +6834,6 @@ msgstr ""
|
|||
msgid "UserProfile|Personal projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|Recent contributions"
|
||||
msgstr ""
|
||||
|
||||
msgid "UserProfile|Report abuse"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ describe 'Contributions Calendar', :js do
|
|||
end
|
||||
|
||||
def selected_day_activities(visible: true)
|
||||
find('.tab-pane#activity .user-calendar-activities', visible: visible).text
|
||||
find('#js-overview .user-calendar-activities', visible: visible).text
|
||||
end
|
||||
|
||||
before do
|
||||
|
@ -74,16 +74,16 @@ describe 'Contributions Calendar', :js do
|
|||
describe 'calendar day selection' do
|
||||
before do
|
||||
visit user.username
|
||||
page.find('.js-activity-tab a').click
|
||||
page.find('.js-overview-tab a').click
|
||||
wait_for_requests
|
||||
end
|
||||
|
||||
it 'displays calendar' do
|
||||
expect(find('.tab-pane#activity')).to have_css('.js-contrib-calendar')
|
||||
expect(find('#js-overview')).to have_css('.js-contrib-calendar')
|
||||
end
|
||||
|
||||
describe 'select calendar day' do
|
||||
let(:cells) { page.all('.tab-pane#activity .user-contrib-cell') }
|
||||
let(:cells) { page.all('#js-overview .user-contrib-cell') }
|
||||
|
||||
before do
|
||||
cells[0].click
|
||||
|
@ -109,7 +109,7 @@ describe 'Contributions Calendar', :js do
|
|||
describe 'deselect calendar day' do
|
||||
before do
|
||||
cells[0].click
|
||||
page.find('.js-activity-tab a').click
|
||||
page.find('.js-overview-tab a').click
|
||||
wait_for_requests
|
||||
end
|
||||
|
||||
|
@ -124,7 +124,7 @@ describe 'Contributions Calendar', :js do
|
|||
shared_context 'visit user page' do
|
||||
before do
|
||||
visit user.username
|
||||
page.find('.js-activity-tab a').click
|
||||
page.find('.js-overview-tab a').click
|
||||
wait_for_requests
|
||||
end
|
||||
end
|
||||
|
@ -133,12 +133,12 @@ describe 'Contributions Calendar', :js do
|
|||
include_context 'visit user page'
|
||||
|
||||
it 'displays calendar activity square color for 1 contribution' do
|
||||
expect(find('.tab-pane#activity')).to have_selector(get_cell_color_selector(contribution_count), count: 1)
|
||||
expect(find('#js-overview')).to have_selector(get_cell_color_selector(contribution_count), count: 1)
|
||||
end
|
||||
|
||||
it 'displays calendar activity square on the correct date' do
|
||||
today = Date.today.strftime(date_format)
|
||||
expect(find('.tab-pane#activity')).to have_selector(get_cell_date_selector(contribution_count, today), count: 1)
|
||||
expect(find('#js-overview')).to have_selector(get_cell_date_selector(contribution_count, today), count: 1)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -153,7 +153,7 @@ describe 'Contributions Calendar', :js do
|
|||
include_context 'visit user page'
|
||||
|
||||
it 'displays calendar activity log' do
|
||||
expect(find('.tab-pane#activity .content_list .event-target-title')).to have_content issue_title
|
||||
expect(find('#js-overview .overview-content-list .event-target-title')).to have_content issue_title
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -185,17 +185,17 @@ describe 'Contributions Calendar', :js do
|
|||
include_context 'visit user page'
|
||||
|
||||
it 'displays calendar activity squares for both days' do
|
||||
expect(find('.tab-pane#activity')).to have_selector(get_cell_color_selector(1), count: 2)
|
||||
expect(find('#js-overview')).to have_selector(get_cell_color_selector(1), count: 2)
|
||||
end
|
||||
|
||||
it 'displays calendar activity square for yesterday' do
|
||||
yesterday = Date.yesterday.strftime(date_format)
|
||||
expect(find('.tab-pane#activity')).to have_selector(get_cell_date_selector(1, yesterday), count: 1)
|
||||
expect(find('#js-overview')).to have_selector(get_cell_date_selector(1, yesterday), count: 1)
|
||||
end
|
||||
|
||||
it 'displays calendar activity square for today' do
|
||||
today = Date.today.strftime(date_format)
|
||||
expect(find('.tab-pane#activity')).to have_selector(get_cell_date_selector(1, today), count: 1)
|
||||
expect(find('#js-overview')).to have_selector(get_cell_date_selector(1, today), count: 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -54,15 +54,15 @@ describe 'Overview tab on a user profile', :js do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'user has 10 activities' do
|
||||
describe 'user has 11 activities' do
|
||||
before do
|
||||
10.times { push_code_contribution }
|
||||
11.times { push_code_contribution }
|
||||
end
|
||||
|
||||
include_context 'visit overview tab'
|
||||
|
||||
it 'displays 5 entries in the list of activities' do
|
||||
expect(find('#js-overview')).to have_selector('.event-item', count: 5)
|
||||
it 'displays 10 entries in the list of activities' do
|
||||
expect(find('#js-overview')).to have_selector('.event-item', count: 10)
|
||||
end
|
||||
|
||||
it 'shows a link to the activity list' do
|
||||
|
|
Loading…
Reference in a new issue