Skip to content

Commit 285aff2

Browse files
author
GitLab Bot
committed
Add latest changes from gitlab-org/gitlab@master
1 parent b5cafdc commit 285aff2

File tree

103 files changed

+1560
-808
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+1560
-808
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ Instructions on how to start GitLab and how to run the tests can be found in the
8282
GitLab is a Ruby on Rails application that runs on the following software:
8383

8484
- Ubuntu/Debian/CentOS/RHEL/OpenSUSE
85-
- Ruby (MRI) 3.1.4
85+
- Ruby (MRI) 3.2.5
8686
- Git 2.33+
8787
- Redis 6.0+
8888
- PostgreSQL 14.9+

app/assets/javascripts/behaviors/date_picker.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import $ from 'jquery';
22
import Pikaday from 'pikaday';
3-
import { parsePikadayDate, pikadayToString } from '~/lib/utils/datetime_utility';
3+
import { parsePikadayDate, toISODateFormat } from '~/lib/utils/datetime_utility';
44

55
export default function initDatePickers() {
66
$('.datepicker').each(function initPikaday() {
@@ -13,7 +13,7 @@ export default function initDatePickers() {
1313
format: 'yyyy-mm-dd',
1414
container: $datePicker.parent().get(0),
1515
parse: (dateString) => parsePikadayDate(dateString),
16-
toString: (date) => pikadayToString(date),
16+
toString: (date) => toISODateFormat(date),
1717
onSelect(dateText) {
1818
$datePicker.val(calendar.toString(dateText));
1919
},

app/assets/javascripts/graphql_shared/constants.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,6 @@ export const TYPE_ORGANIZATION = 'Organizations::Organization';
3535
export const TYPE_USERS_SAVED_REPLY = 'Users::SavedReply';
3636
export const TYPE_WORKSPACE = 'RemoteDevelopment::Workspace';
3737
export const TYPE_COMPLIANCE_FRAMEWORK = 'ComplianceManagement::Framework';
38+
39+
export const QUERY_PARAM_START_CURSOR = 'start_cursor';
40+
export const QUERY_PARAM_END_CURSOR = 'end_cursor';

app/assets/javascripts/graphql_shared/utils.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { isArray } from 'lodash';
22
import Visibility from 'visibilityjs';
3+
import { QUERY_PARAM_START_CURSOR, QUERY_PARAM_END_CURSOR } from './constants';
34

45
/**
56
* Ids generated by GraphQL endpoints are usually in the format
@@ -162,3 +163,25 @@ export const etagQueryHeaders = (featureCorrelation, etagResource = '') => {
162163
},
163164
};
164165
};
166+
167+
export const calculateGraphQLPaginationQueryParams = ({
168+
startCursor,
169+
endCursor,
170+
routeQuery: { start_cursor, end_cursor, ...routeQuery },
171+
}) => {
172+
if (startCursor) {
173+
return {
174+
...routeQuery,
175+
[QUERY_PARAM_START_CURSOR]: startCursor,
176+
};
177+
}
178+
179+
if (endCursor) {
180+
return {
181+
...routeQuery,
182+
[QUERY_PARAM_END_CURSOR]: endCursor,
183+
};
184+
}
185+
186+
return routeQuery;
187+
};

app/assets/javascripts/issuable/issuable_form.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import $ from 'jquery';
22
import Pikaday from 'pikaday';
33
import GfmAutoComplete from 'ee_else_ce/gfm_auto_complete';
44
import Autosave from '~/autosave';
5-
import { parsePikadayDate, pikadayToString } from '~/lib/utils/datetime_utility';
5+
import { parsePikadayDate, toISODateFormat } from '~/lib/utils/datetime_utility';
66
import { queryToObject, objectToQuery } from '~/lib/utils/url_utility';
77
import UsersSelect from '~/users_select';
88
import ZenMode from '~/zen_mode';
@@ -114,7 +114,7 @@ export default class IssuableForm {
114114
format: 'yyyy-mm-dd',
115115
container: $issuableDueDate.parent().get(0),
116116
parse: (dateString) => parsePikadayDate(dateString),
117-
toString: (date) => pikadayToString(date),
117+
toString: (date) => toISODateFormat(date),
118118
onSelect: (dateText) => {
119119
$issuableDueDate.val(calendar.toString(dateText));
120120
if (this.autosaves.has('due_date')) this.autosaves.get('due_date').save();

app/assets/javascripts/lib/utils/datetime/date_calculation_utility.js

Lines changed: 2 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export const MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000;
3333
* for UTC-8 timezone.
3434
*
3535
* @param {string|number|Date} date
36-
* @returns {Date|null|undefined}
36+
* @returns {Date|null|undefined} A Date object in local time
3737
*/
3838
export const newDate = (date) => {
3939
if (date === null) {
@@ -42,6 +42,7 @@ export const newDate = (date) => {
4242
if (date === undefined) {
4343
return undefined;
4444
}
45+
// Fix historical bug so we return a local time for `yyyy-mm-dd` date-only strings
4546
if (typeof date === 'string' && DATE_ONLY_REGEX.test(date)) {
4647
const parts = date.split('-');
4748
const year = parseInt(parts[0], 10);
@@ -545,48 +546,6 @@ export const dateAtFirstDayOfMonth = (date) => new Date(cloneDate(date).setDate(
545546
*/
546547
export const datesMatch = (date1, date2) => differenceInMilliseconds(date1, date2) === 0;
547548

548-
/**
549-
* A utility function which checks if two date ranges overlap.
550-
*
551-
* @param {Object} givenPeriodLeft - the first period to compare.
552-
* @param {Object} givenPeriodRight - the second period to compare.
553-
* @returns {Object} { overlap: number of days the overlap is present, overlapStartDate: the start date of the overlap in time format, overlapEndDate: the end date of the overlap in time format }
554-
* @throws {Error} Uncaught Error: Invalid period
555-
*
556-
* @example
557-
* getOverlappingDaysInPeriods(
558-
* { start: new Date(2021, 0, 11), end: new Date(2021, 0, 13) },
559-
* { start: new Date(2021, 0, 11), end: new Date(2021, 0, 14) }
560-
* ) => { daysOverlap: 2, overlapStartDate: 1610323200000, overlapEndDate: 1610496000000 }
561-
*
562-
*/
563-
export const getOverlappingDaysInPeriods = (givenPeriodLeft = {}, givenPeriodRight = {}) => {
564-
const leftStartTime = new Date(givenPeriodLeft.start).getTime();
565-
const leftEndTime = new Date(givenPeriodLeft.end).getTime();
566-
const rightStartTime = new Date(givenPeriodRight.start).getTime();
567-
const rightEndTime = new Date(givenPeriodRight.end).getTime();
568-
569-
if (!(leftStartTime <= leftEndTime && rightStartTime <= rightEndTime)) {
570-
throw new Error(__('Invalid period'));
571-
}
572-
573-
const isOverlapping = leftStartTime < rightEndTime && rightStartTime < leftEndTime;
574-
575-
if (!isOverlapping) {
576-
return { daysOverlap: 0 };
577-
}
578-
579-
const overlapStartDate = Math.max(leftStartTime, rightStartTime);
580-
const overlapEndDate = rightEndTime > leftEndTime ? leftEndTime : rightEndTime;
581-
const differenceInMs = overlapEndDate - overlapStartDate;
582-
583-
return {
584-
daysOverlap: Math.ceil(differenceInMs / MILLISECONDS_IN_DAY),
585-
overlapStartDate,
586-
overlapEndDate,
587-
};
588-
};
589-
590549
/**
591550
* Mimics the behaviour of the rails distance_of_time_in_words function
592551
* https://api.rubyonrails.org/classes/ActionView/Helpers/DateHelper.html#method-i-distance_of_time_in_words
@@ -634,21 +593,6 @@ export const approximateDuration = (seconds = 0) => {
634593
return n__('1 day', '%d days', seconds < ONE_DAY_LIMIT ? 1 : days);
635594
};
636595

637-
/**
638-
* A utility function which helps creating a date object
639-
* for a specific date. Accepts the year, month and day
640-
* returning a date object for the given params.
641-
*
642-
* @param {Int} year the full year as a number i.e. 2020
643-
* @param {Int} month the month index i.e. January => 0
644-
* @param {Int} day the day as a number i.e. 23
645-
*
646-
* @return {Date} the date object from the params
647-
*/
648-
export const dateFromParams = (year, month, day) => {
649-
return new Date(year, month, day);
650-
};
651-
652596
/**
653597
* A utility function which computes a formatted 24 hour
654598
* time string from a positive int in the range 0 - 24.

app/assets/javascripts/lib/utils/datetime/date_format_utility.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,19 @@ export const timeToHoursMinutes = (time = '') => {
357357
return { hours, minutes };
358358
};
359359

360+
/**
361+
* Converts a Date object to a date-only string in the ISO format `yyyy-mm-dd`
362+
*
363+
* @param {Date} date A Date object
364+
* @returns {string} A string in the format `yyyy-mm-dd`
365+
*/
366+
export const toISODateFormat = (date) => {
367+
const day = padWithZeros(date.getDate());
368+
const month = padWithZeros(date.getMonth() + 1);
369+
const year = date.getFullYear();
370+
return `${year}-${month}-${day}`;
371+
};
372+
360373
/**
361374
* This combines a date and a time and returns the computed Date's ISO string representation.
362375
*
@@ -516,3 +529,15 @@ export const humanTimeframe = (startDate, dueDate) => {
516529
}
517530
return '';
518531
};
532+
533+
/**
534+
* Formats seconds into a human readable value of elapsed time,
535+
* optionally limiting it to hours.
536+
* @param {Number} seconds Seconds to format
537+
* @param {Boolean} limitToHours Whether or not to limit the elapsed time to be expressed in hours
538+
* @return {String} Provided seconds in human readable elapsed time format
539+
*/
540+
export const formatTimeSpent = (seconds, limitToHours) => {
541+
const negative = seconds < 0;
542+
return (negative ? '- ' : '') + stringifyTime(parseSeconds(seconds, { limitToHours }));
543+
};
Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
export const pad = (val, len = 2) => `0${val}`.slice(-len);
2-
31
/**
42
* Formats dates in Pickaday
53
* @param {String} dateString Date in yyyy-mm-dd format
@@ -13,16 +11,3 @@ export const parsePikadayDate = (dateString) => {
1311

1412
return new Date(year, month, day);
1513
};
16-
17-
/**
18-
* Used `onSelect` method in pickaday
19-
* @param {Date} date UTC format
20-
* @return {String} Date formatted in yyyy-mm-dd
21-
*/
22-
export const pikadayToString = (date) => {
23-
const day = pad(date.getDate());
24-
const month = pad(date.getMonth() + 1);
25-
const year = date.getFullYear();
26-
27-
return `${year}-${month}-${day}`;
28-
};

app/assets/javascripts/lib/utils/datetime/time_spent_utility.js

Lines changed: 0 additions & 13 deletions
This file was deleted.

app/assets/javascripts/lib/utils/datetime_utility.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@ export * from './datetime/timeago_utility';
22
export * from './datetime/date_format_utility';
33
export * from './datetime/date_calculation_utility';
44
export * from './datetime/pikaday_utility';
5-
export * from './datetime/time_spent_utility';
65
export * from './datetime/locale_dateformat';

app/assets/javascripts/organizations/groups_and_projects/components/app.vue

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,15 @@ import GroupsView from '~/organizations/shared/components/groups_view.vue';
66
import ProjectsView from '~/organizations/shared/components/projects_view.vue';
77
import NewGroupButton from '~/organizations/shared/components/new_group_button.vue';
88
import NewProjectButton from '~/organizations/shared/components/new_project_button.vue';
9-
import { onPageChange } from '~/organizations/shared/utils';
9+
import { calculateGraphQLPaginationQueryParams } from '~/graphql_shared/utils';
1010
import {
1111
RESOURCE_TYPE_GROUPS,
1212
RESOURCE_TYPE_PROJECTS,
13-
QUERY_PARAM_END_CURSOR,
14-
QUERY_PARAM_START_CURSOR,
1513
SORT_DIRECTION_ASC,
1614
SORT_DIRECTION_DESC,
1715
SORT_ITEM_NAME,
1816
} from '~/organizations/shared/constants';
17+
import { QUERY_PARAM_END_CURSOR, QUERY_PARAM_START_CURSOR } from '~/graphql_shared/constants';
1918
import FilteredSearchAndSort from '~/groups_projects/components/filtered_search_and_sort.vue';
2019
import {
2120
RECENT_SEARCHES_STORAGE_KEY_GROUPS,
@@ -172,7 +171,9 @@ export default {
172171
});
173172
},
174173
onPageChange(pagination) {
175-
this.pushQuery(onPageChange({ ...pagination, routeQuery: this.$route.query }));
174+
this.pushQuery(
175+
calculateGraphQLPaginationQueryParams({ ...pagination, routeQuery: this.$route.query }),
176+
);
176177
},
177178
async userPreferencesUpdateMutate(input) {
178179
try {

app/assets/javascripts/organizations/shared/constants.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@ export const FORM_FIELD_DESCRIPTION_VALIDATORS = [
3030
),
3131
];
3232

33-
export const QUERY_PARAM_START_CURSOR = 'start_cursor';
34-
export const QUERY_PARAM_END_CURSOR = 'end_cursor';
35-
3633
export const SORT_DIRECTION_ASC = 'asc';
3734
export const SORT_DIRECTION_DESC = 'desc';
3835

app/assets/javascripts/organizations/shared/utils.js

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,7 @@ import {
44
TIMESTAMP_TYPE_CREATED_AT,
55
TIMESTAMP_TYPE_UPDATED_AT,
66
} from '~/vue_shared/components/resource_lists/constants';
7-
import {
8-
SORT_CREATED_AT,
9-
SORT_UPDATED_AT,
10-
QUERY_PARAM_END_CURSOR,
11-
QUERY_PARAM_START_CURSOR,
12-
} from './constants';
7+
import { SORT_CREATED_AT, SORT_UPDATED_AT } from './constants';
138

149
const availableGroupActions = (userPermissions) => {
1510
const baseActions = [];
@@ -52,28 +47,6 @@ export const formatGroups = (groups) =>
5247
}),
5348
);
5449

55-
export const onPageChange = ({
56-
startCursor,
57-
endCursor,
58-
routeQuery: { start_cursor, end_cursor, ...routeQuery },
59-
}) => {
60-
if (startCursor) {
61-
return {
62-
...routeQuery,
63-
[QUERY_PARAM_START_CURSOR]: startCursor,
64-
};
65-
}
66-
67-
if (endCursor) {
68-
return {
69-
...routeQuery,
70-
[QUERY_PARAM_END_CURSOR]: endCursor,
71-
};
72-
}
73-
74-
return routeQuery;
75-
};
76-
7750
export const timestampType = (sortName) => {
7851
const SORT_MAP = {
7952
[SORT_CREATED_AT]: TIMESTAMP_TYPE_CREATED_AT,

app/assets/javascripts/organizations/show/components/groups_and_projects.vue

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,15 @@ import { isEqual } from 'lodash';
44
import { s__, __ } from '~/locale';
55
import GroupsView from '~/organizations/shared/components/groups_view.vue';
66
import ProjectsView from '~/organizations/shared/components/projects_view.vue';
7-
import { onPageChange } from '~/organizations/shared/utils';
7+
import { calculateGraphQLPaginationQueryParams } from '~/graphql_shared/utils';
88
import {
99
RESOURCE_TYPE_GROUPS,
1010
RESOURCE_TYPE_PROJECTS,
11-
QUERY_PARAM_END_CURSOR,
12-
QUERY_PARAM_START_CURSOR,
1311
SORT_CREATED_AT,
1412
SORT_UPDATED_AT,
1513
SORT_DIRECTION_DESC,
1614
} from '~/organizations/shared/constants';
15+
import { QUERY_PARAM_END_CURSOR, QUERY_PARAM_START_CURSOR } from '~/graphql_shared/constants';
1716
import { GROUPS_AND_PROJECTS_PER_PAGE } from '../constants';
1817
import { buildDisplayListboxItem } from '../utils';
1918
@@ -108,7 +107,9 @@ export default {
108107
this.pushQuery({ display });
109108
},
110109
onPageChange(pagination) {
111-
this.pushQuery(onPageChange({ ...pagination, routeQuery: this.$route.query }));
110+
this.pushQuery(
111+
calculateGraphQLPaginationQueryParams({ ...pagination, routeQuery: this.$route.query }),
112+
);
112113
},
113114
},
114115
};

app/assets/javascripts/pages/users/activity_calendar.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
getDayName,
88
getDayDifference,
99
localeDateFormat,
10-
pikadayToString,
10+
toISODateFormat,
1111
newDate,
1212
} from '~/lib/utils/datetime_utility';
1313
import { n__, s__, __ } from '~/locale';
@@ -117,7 +117,7 @@ export default class ActivityCalendar {
117117
date.setDate(date.getDate() + i);
118118

119119
const day = date.getDay();
120-
const count = timestamps[pikadayToString(date)] || 0;
120+
const count = timestamps[toISODateFormat(date)] || 0;
121121

122122
// Create a new group array if this is the first day of the week
123123
// or if is first object

0 commit comments

Comments
 (0)