From 285aff2385cdd9f33ae3504d3185e5d6f4981706 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 2 Oct 2024 15:13:28 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- README.md | 2 +- .../javascripts/behaviors/date_picker.js | 4 +- .../javascripts/graphql_shared/constants.js | 3 + .../javascripts/graphql_shared/utils.js | 23 ++ .../javascripts/issuable/issuable_form.js | 4 +- .../datetime/date_calculation_utility.js | 60 +---- .../lib/utils/datetime/date_format_utility.js | 25 ++ .../lib/utils/datetime/pikaday_utility.js | 15 -- .../lib/utils/datetime/time_spent_utility.js | 13 - .../javascripts/lib/utils/datetime_utility.js | 1 - .../groups_and_projects/components/app.vue | 9 +- .../organizations/shared/constants.js | 3 - .../javascripts/organizations/shared/utils.js | 29 +- .../show/components/groups_and_projects.vue | 9 +- .../pages/users/activity_calendar.js | 4 +- .../projects/your_work/components/app.vue | 21 +- .../your_work/components/tab_view.vue | 69 ++++- .../contributed_projects.query.graphql | 8 +- .../queries/inactive_projects.query.graphql | 15 +- .../queries/membership_projects.query.graphql | 8 +- .../queries/personal_projects.query.graphql | 8 +- .../queries/starred_projects.query.graphql | 8 +- .../filtered_search_tokens/group_token.vue | 105 ++++++++ .../filtered_search_tokens/project_token.vue | 105 ++++++++ .../queries/search_groups.query.graphql | 8 + .../queries/search_projects.query.graphql | 8 + .../todos/components/todos_app.vue | 4 +- .../todos/components/todos_filter_bar.vue | 251 ++++++++++-------- app/assets/javascripts/users_select/index.js | 4 +- .../components/checks/constants.js | 1 + .../filtered_search_bar/constants.js | 10 + .../components/create_work_item.vue | 14 +- .../components/work_item_due_date.vue | 10 +- .../work_items/graphql/resolvers.js | 6 +- .../stylesheets/framework/dropdowns.scss | 2 +- .../stylesheets/page_bundles/pipelines.scss | 41 --- .../stylesheets/page_bundles/todos.scss | 5 - .../pajamas/spinner_component.html.haml | 3 +- .../detailed_merge_status_enum.rb | 3 + app/helpers/todos_helper.rb | 2 +- app/views/dashboard/todos/_todo.html.haml | 12 +- .../pipeline_run_keyword.yml | 9 - .../backfill_ci_resources_project_id.yml | 9 + db/docs/ci_resources.yml | 1 + ...30154300_add_project_id_to_ci_resources.rb | 9 + ...154301_index_ci_resources_on_project_id.rb | 16 ++ ...302_add_ci_resources_project_id_trigger.rb | 25 ++ ..._queue_backfill_ci_resources_project_id.rb | 40 +++ db/schema_migrations/20240930154300 | 1 + db/schema_migrations/20240930154301 | 1 + db/schema_migrations/20240930154302 | 1 + db/schema_migrations/20240930154303 | 1 + db/structure.sql | 23 +- doc/api/graphql/reference/index.md | 2 + doc/api/merge_requests.md | 2 + doc/ci/yaml/index.md | 1 + doc/user/permissions.md | 8 +- doc/user/project/deploy_tokens/index.md | 6 +- doc/user/project/import/index.md | 6 +- .../virtual_registries/packages/endpoint.rb | 15 +- lib/api/entities/ci/job_request/response.rb | 8 +- lib/api/sidekiq_metrics.rb | 74 +++--- lib/api/virtual_registries/packages/maven.rb | 116 +++----- .../backfill_ci_resources_project_id.rb | 10 + lib/gitlab/ci/config/entry/job.rb | 8 +- lib/gitlab/ci/pipeline/seed/build.rb | 2 +- .../concurrency_limit/workers_concurrency.rb | 11 +- lib/gitlab/sidekiq_sharding/router.rb | 8 + lib/gitlab/workhorse.rb | 3 +- locale/gitlab.pot | 24 +- .../pajamas/button_component_spec.rb | 6 +- .../pajamas/spinner_component_spec.rb | 8 +- spec/db/schema_spec.rb | 1 + .../dashboard/todos/accessibility_spec.rb | 97 +++++++ .../dashboard/todos/target_state_spec.rb | 2 + .../dashboard/todos/todos_filtering_spec.rb | 2 + .../dashboard/todos/todos_sorting_spec.rb | 2 + spec/features/dashboard/todos/todos_spec.rb | 2 + spec/frontend/graphql_shared/utils_spec.js | 27 ++ .../datetime/date_format_utility_spec.js | 116 ++++---- .../utils/datetime/time_spent_utility_spec.js | 25 -- .../lib/utils/datetime_utility_spec.js | 20 +- .../organizations/shared/utils_spec.js | 28 +- .../projects/your_work/components/app_spec.js | 57 +++- .../your_work/components/mock_data.js | 7 + .../your_work/components/tab_view_spec.js | 131 ++++++++- .../components/checks/message_spec.js | 25 +- spec/helpers/icons_helper_spec.rb | 3 +- .../backfill_ci_resources_project_id_spec.rb | 16 ++ spec/lib/gitlab/ci/config/entry/job_spec.rb | 23 -- .../lib/gitlab/ci/pipeline/seed/build_spec.rb | 10 - spec/lib/gitlab/import_export/all_models.yml | 1 + spec/lib/gitlab/workhorse_spec.rb | 12 +- ...e_backfill_ci_resources_project_id_spec.rb | 33 +++ .../api/ci/runner/jobs_request_post_spec.rb | 27 -- spec/requests/api/sidekiq_metrics_spec.rb | 15 +- .../virtual_registries/packages/maven_spec.rb | 54 +--- .../ci/create_pipeline_service/run_spec.rb | 10 - .../_support/lint_last_known_acceptable.txt | 3 +- .../dependencyproxy/dependencyproxy.go | 47 +++- .../dependencyproxy/dependencyproxy_test.go | 52 +++- workhorse/internal/upload/body_uploader.go | 106 +++++--- .../internal/upload/body_uploader_test.go | 27 ++ 103 files changed, 1561 insertions(+), 809 deletions(-) delete mode 100644 app/assets/javascripts/lib/utils/datetime/time_spent_utility.js create mode 100644 app/assets/javascripts/todos/components/filtered_search_tokens/group_token.vue create mode 100644 app/assets/javascripts/todos/components/filtered_search_tokens/project_token.vue create mode 100644 app/assets/javascripts/todos/components/queries/search_groups.query.graphql create mode 100644 app/assets/javascripts/todos/components/queries/search_projects.query.graphql delete mode 100644 config/feature_flags/gitlab_com_derisk/pipeline_run_keyword.yml create mode 100644 db/docs/batched_background_migrations/backfill_ci_resources_project_id.yml create mode 100644 db/migrate/20240930154300_add_project_id_to_ci_resources.rb create mode 100644 db/post_migrate/20240930154301_index_ci_resources_on_project_id.rb create mode 100644 db/post_migrate/20240930154302_add_ci_resources_project_id_trigger.rb create mode 100644 db/post_migrate/20240930154303_queue_backfill_ci_resources_project_id.rb create mode 100644 db/schema_migrations/20240930154300 create mode 100644 db/schema_migrations/20240930154301 create mode 100644 db/schema_migrations/20240930154302 create mode 100644 db/schema_migrations/20240930154303 create mode 100644 lib/gitlab/background_migration/backfill_ci_resources_project_id.rb create mode 100644 spec/features/dashboard/todos/accessibility_spec.rb delete mode 100644 spec/frontend/lib/utils/datetime/time_spent_utility_spec.js create mode 100644 spec/frontend/projects/your_work/components/mock_data.js create mode 100644 spec/lib/gitlab/background_migration/backfill_ci_resources_project_id_spec.rb create mode 100644 spec/migrations/20240930154304_queue_backfill_ci_resources_project_id_spec.rb diff --git a/README.md b/README.md index b0400317536..b92c6dc5b7c 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ Instructions on how to start GitLab and how to run the tests can be found in the GitLab is a Ruby on Rails application that runs on the following software: - Ubuntu/Debian/CentOS/RHEL/OpenSUSE -- Ruby (MRI) 3.1.4 +- Ruby (MRI) 3.2.5 - Git 2.33+ - Redis 6.0+ - PostgreSQL 14.9+ diff --git a/app/assets/javascripts/behaviors/date_picker.js b/app/assets/javascripts/behaviors/date_picker.js index 89f1ad9c89e..f49a27ba16a 100644 --- a/app/assets/javascripts/behaviors/date_picker.js +++ b/app/assets/javascripts/behaviors/date_picker.js @@ -1,6 +1,6 @@ import $ from 'jquery'; import Pikaday from 'pikaday'; -import { parsePikadayDate, pikadayToString } from '~/lib/utils/datetime_utility'; +import { parsePikadayDate, toISODateFormat } from '~/lib/utils/datetime_utility'; export default function initDatePickers() { $('.datepicker').each(function initPikaday() { @@ -13,7 +13,7 @@ export default function initDatePickers() { format: 'yyyy-mm-dd', container: $datePicker.parent().get(0), parse: (dateString) => parsePikadayDate(dateString), - toString: (date) => pikadayToString(date), + toString: (date) => toISODateFormat(date), onSelect(dateText) { $datePicker.val(calendar.toString(dateText)); }, diff --git a/app/assets/javascripts/graphql_shared/constants.js b/app/assets/javascripts/graphql_shared/constants.js index a081e29d3ea..fe3f94f6fde 100644 --- a/app/assets/javascripts/graphql_shared/constants.js +++ b/app/assets/javascripts/graphql_shared/constants.js @@ -35,3 +35,6 @@ export const TYPE_ORGANIZATION = 'Organizations::Organization'; export const TYPE_USERS_SAVED_REPLY = 'Users::SavedReply'; export const TYPE_WORKSPACE = 'RemoteDevelopment::Workspace'; export const TYPE_COMPLIANCE_FRAMEWORK = 'ComplianceManagement::Framework'; + +export const QUERY_PARAM_START_CURSOR = 'start_cursor'; +export const QUERY_PARAM_END_CURSOR = 'end_cursor'; diff --git a/app/assets/javascripts/graphql_shared/utils.js b/app/assets/javascripts/graphql_shared/utils.js index 828a18a240e..fb7f5124e6d 100644 --- a/app/assets/javascripts/graphql_shared/utils.js +++ b/app/assets/javascripts/graphql_shared/utils.js @@ -1,5 +1,6 @@ import { isArray } from 'lodash'; import Visibility from 'visibilityjs'; +import { QUERY_PARAM_START_CURSOR, QUERY_PARAM_END_CURSOR } from './constants'; /** * Ids generated by GraphQL endpoints are usually in the format @@ -162,3 +163,25 @@ export const etagQueryHeaders = (featureCorrelation, etagResource = '') => { }, }; }; + +export const calculateGraphQLPaginationQueryParams = ({ + startCursor, + endCursor, + routeQuery: { start_cursor, end_cursor, ...routeQuery }, +}) => { + if (startCursor) { + return { + ...routeQuery, + [QUERY_PARAM_START_CURSOR]: startCursor, + }; + } + + if (endCursor) { + return { + ...routeQuery, + [QUERY_PARAM_END_CURSOR]: endCursor, + }; + } + + return routeQuery; +}; diff --git a/app/assets/javascripts/issuable/issuable_form.js b/app/assets/javascripts/issuable/issuable_form.js index 329b4c2781b..30edfa966f8 100644 --- a/app/assets/javascripts/issuable/issuable_form.js +++ b/app/assets/javascripts/issuable/issuable_form.js @@ -2,7 +2,7 @@ import $ from 'jquery'; import Pikaday from 'pikaday'; import GfmAutoComplete from 'ee_else_ce/gfm_auto_complete'; import Autosave from '~/autosave'; -import { parsePikadayDate, pikadayToString } from '~/lib/utils/datetime_utility'; +import { parsePikadayDate, toISODateFormat } from '~/lib/utils/datetime_utility'; import { queryToObject, objectToQuery } from '~/lib/utils/url_utility'; import UsersSelect from '~/users_select'; import ZenMode from '~/zen_mode'; @@ -114,7 +114,7 @@ export default class IssuableForm { format: 'yyyy-mm-dd', container: $issuableDueDate.parent().get(0), parse: (dateString) => parsePikadayDate(dateString), - toString: (date) => pikadayToString(date), + toString: (date) => toISODateFormat(date), onSelect: (dateText) => { $issuableDueDate.val(calendar.toString(dateText)); if (this.autosaves.has('due_date')) this.autosaves.get('due_date').save(); diff --git a/app/assets/javascripts/lib/utils/datetime/date_calculation_utility.js b/app/assets/javascripts/lib/utils/datetime/date_calculation_utility.js index 6e714025d80..2b3cdcb661e 100644 --- a/app/assets/javascripts/lib/utils/datetime/date_calculation_utility.js +++ b/app/assets/javascripts/lib/utils/datetime/date_calculation_utility.js @@ -33,7 +33,7 @@ export const MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000; * for UTC-8 timezone. * * @param {string|number|Date} date - * @returns {Date|null|undefined} + * @returns {Date|null|undefined} A Date object in local time */ export const newDate = (date) => { if (date === null) { @@ -42,6 +42,7 @@ export const newDate = (date) => { if (date === undefined) { return undefined; } + // Fix historical bug so we return a local time for `yyyy-mm-dd` date-only strings if (typeof date === 'string' && DATE_ONLY_REGEX.test(date)) { const parts = date.split('-'); const year = parseInt(parts[0], 10); @@ -545,48 +546,6 @@ export const dateAtFirstDayOfMonth = (date) => new Date(cloneDate(date).setDate( */ export const datesMatch = (date1, date2) => differenceInMilliseconds(date1, date2) === 0; -/** - * A utility function which checks if two date ranges overlap. - * - * @param {Object} givenPeriodLeft - the first period to compare. - * @param {Object} givenPeriodRight - the second period to compare. - * @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 } - * @throws {Error} Uncaught Error: Invalid period - * - * @example - * getOverlappingDaysInPeriods( - * { start: new Date(2021, 0, 11), end: new Date(2021, 0, 13) }, - * { start: new Date(2021, 0, 11), end: new Date(2021, 0, 14) } - * ) => { daysOverlap: 2, overlapStartDate: 1610323200000, overlapEndDate: 1610496000000 } - * - */ -export const getOverlappingDaysInPeriods = (givenPeriodLeft = {}, givenPeriodRight = {}) => { - const leftStartTime = new Date(givenPeriodLeft.start).getTime(); - const leftEndTime = new Date(givenPeriodLeft.end).getTime(); - const rightStartTime = new Date(givenPeriodRight.start).getTime(); - const rightEndTime = new Date(givenPeriodRight.end).getTime(); - - if (!(leftStartTime <= leftEndTime && rightStartTime <= rightEndTime)) { - throw new Error(__('Invalid period')); - } - - const isOverlapping = leftStartTime < rightEndTime && rightStartTime < leftEndTime; - - if (!isOverlapping) { - return { daysOverlap: 0 }; - } - - const overlapStartDate = Math.max(leftStartTime, rightStartTime); - const overlapEndDate = rightEndTime > leftEndTime ? leftEndTime : rightEndTime; - const differenceInMs = overlapEndDate - overlapStartDate; - - return { - daysOverlap: Math.ceil(differenceInMs / MILLISECONDS_IN_DAY), - overlapStartDate, - overlapEndDate, - }; -}; - /** * Mimics the behaviour of the rails distance_of_time_in_words function * 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) => { return n__('1 day', '%d days', seconds < ONE_DAY_LIMIT ? 1 : days); }; -/** - * A utility function which helps creating a date object - * for a specific date. Accepts the year, month and day - * returning a date object for the given params. - * - * @param {Int} year the full year as a number i.e. 2020 - * @param {Int} month the month index i.e. January => 0 - * @param {Int} day the day as a number i.e. 23 - * - * @return {Date} the date object from the params - */ -export const dateFromParams = (year, month, day) => { - return new Date(year, month, day); -}; - /** * A utility function which computes a formatted 24 hour * time string from a positive int in the range 0 - 24. diff --git a/app/assets/javascripts/lib/utils/datetime/date_format_utility.js b/app/assets/javascripts/lib/utils/datetime/date_format_utility.js index 3236a2c46d7..0e1ba0ef135 100644 --- a/app/assets/javascripts/lib/utils/datetime/date_format_utility.js +++ b/app/assets/javascripts/lib/utils/datetime/date_format_utility.js @@ -357,6 +357,19 @@ export const timeToHoursMinutes = (time = '') => { return { hours, minutes }; }; +/** + * Converts a Date object to a date-only string in the ISO format `yyyy-mm-dd` + * + * @param {Date} date A Date object + * @returns {string} A string in the format `yyyy-mm-dd` + */ +export const toISODateFormat = (date) => { + const day = padWithZeros(date.getDate()); + const month = padWithZeros(date.getMonth() + 1); + const year = date.getFullYear(); + return `${year}-${month}-${day}`; +}; + /** * This combines a date and a time and returns the computed Date's ISO string representation. * @@ -516,3 +529,15 @@ export const humanTimeframe = (startDate, dueDate) => { } return ''; }; + +/** + * Formats seconds into a human readable value of elapsed time, + * optionally limiting it to hours. + * @param {Number} seconds Seconds to format + * @param {Boolean} limitToHours Whether or not to limit the elapsed time to be expressed in hours + * @return {String} Provided seconds in human readable elapsed time format + */ +export const formatTimeSpent = (seconds, limitToHours) => { + const negative = seconds < 0; + return (negative ? '- ' : '') + stringifyTime(parseSeconds(seconds, { limitToHours })); +}; diff --git a/app/assets/javascripts/lib/utils/datetime/pikaday_utility.js b/app/assets/javascripts/lib/utils/datetime/pikaday_utility.js index 63542ddbb6a..4bd7b4199a1 100644 --- a/app/assets/javascripts/lib/utils/datetime/pikaday_utility.js +++ b/app/assets/javascripts/lib/utils/datetime/pikaday_utility.js @@ -1,5 +1,3 @@ -export const pad = (val, len = 2) => `0${val}`.slice(-len); - /** * Formats dates in Pickaday * @param {String} dateString Date in yyyy-mm-dd format @@ -13,16 +11,3 @@ export const parsePikadayDate = (dateString) => { return new Date(year, month, day); }; - -/** - * Used `onSelect` method in pickaday - * @param {Date} date UTC format - * @return {String} Date formatted in yyyy-mm-dd - */ -export const pikadayToString = (date) => { - const day = pad(date.getDate()); - const month = pad(date.getMonth() + 1); - const year = date.getFullYear(); - - return `${year}-${month}-${day}`; -}; diff --git a/app/assets/javascripts/lib/utils/datetime/time_spent_utility.js b/app/assets/javascripts/lib/utils/datetime/time_spent_utility.js deleted file mode 100644 index 64c77bf1080..00000000000 --- a/app/assets/javascripts/lib/utils/datetime/time_spent_utility.js +++ /dev/null @@ -1,13 +0,0 @@ -import { stringifyTime, parseSeconds } from './date_format_utility'; - -/** - * Formats seconds into a human readable value of elapsed time, - * optionally limiting it to hours. - * @param {Number} seconds Seconds to format - * @param {Boolean} limitToHours Whether or not to limit the elapsed time to be expressed in hours - * @return {String} Provided seconds in human readable elapsed time format - */ -export const formatTimeSpent = (seconds, limitToHours) => { - const negative = seconds < 0; - return (negative ? '- ' : '') + stringifyTime(parseSeconds(seconds, { limitToHours })); -}; diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js index 061ce96407e..cebac94b98f 100644 --- a/app/assets/javascripts/lib/utils/datetime_utility.js +++ b/app/assets/javascripts/lib/utils/datetime_utility.js @@ -2,5 +2,4 @@ export * from './datetime/timeago_utility'; export * from './datetime/date_format_utility'; export * from './datetime/date_calculation_utility'; export * from './datetime/pikaday_utility'; -export * from './datetime/time_spent_utility'; export * from './datetime/locale_dateformat'; diff --git a/app/assets/javascripts/organizations/groups_and_projects/components/app.vue b/app/assets/javascripts/organizations/groups_and_projects/components/app.vue index e2f3f7a26ad..8beb6db1b5c 100644 --- a/app/assets/javascripts/organizations/groups_and_projects/components/app.vue +++ b/app/assets/javascripts/organizations/groups_and_projects/components/app.vue @@ -6,16 +6,15 @@ import GroupsView from '~/organizations/shared/components/groups_view.vue'; import ProjectsView from '~/organizations/shared/components/projects_view.vue'; import NewGroupButton from '~/organizations/shared/components/new_group_button.vue'; import NewProjectButton from '~/organizations/shared/components/new_project_button.vue'; -import { onPageChange } from '~/organizations/shared/utils'; +import { calculateGraphQLPaginationQueryParams } from '~/graphql_shared/utils'; import { RESOURCE_TYPE_GROUPS, RESOURCE_TYPE_PROJECTS, - QUERY_PARAM_END_CURSOR, - QUERY_PARAM_START_CURSOR, SORT_DIRECTION_ASC, SORT_DIRECTION_DESC, SORT_ITEM_NAME, } from '~/organizations/shared/constants'; +import { QUERY_PARAM_END_CURSOR, QUERY_PARAM_START_CURSOR } from '~/graphql_shared/constants'; import FilteredSearchAndSort from '~/groups_projects/components/filtered_search_and_sort.vue'; import { RECENT_SEARCHES_STORAGE_KEY_GROUPS, @@ -172,7 +171,9 @@ export default { }); }, onPageChange(pagination) { - this.pushQuery(onPageChange({ ...pagination, routeQuery: this.$route.query })); + this.pushQuery( + calculateGraphQLPaginationQueryParams({ ...pagination, routeQuery: this.$route.query }), + ); }, async userPreferencesUpdateMutate(input) { try { diff --git a/app/assets/javascripts/organizations/shared/constants.js b/app/assets/javascripts/organizations/shared/constants.js index 7444ca70d90..8e871a8325d 100644 --- a/app/assets/javascripts/organizations/shared/constants.js +++ b/app/assets/javascripts/organizations/shared/constants.js @@ -30,9 +30,6 @@ export const FORM_FIELD_DESCRIPTION_VALIDATORS = [ ), ]; -export const QUERY_PARAM_START_CURSOR = 'start_cursor'; -export const QUERY_PARAM_END_CURSOR = 'end_cursor'; - export const SORT_DIRECTION_ASC = 'asc'; export const SORT_DIRECTION_DESC = 'desc'; diff --git a/app/assets/javascripts/organizations/shared/utils.js b/app/assets/javascripts/organizations/shared/utils.js index f128c6bc336..220739492f8 100644 --- a/app/assets/javascripts/organizations/shared/utils.js +++ b/app/assets/javascripts/organizations/shared/utils.js @@ -4,12 +4,7 @@ import { TIMESTAMP_TYPE_CREATED_AT, TIMESTAMP_TYPE_UPDATED_AT, } from '~/vue_shared/components/resource_lists/constants'; -import { - SORT_CREATED_AT, - SORT_UPDATED_AT, - QUERY_PARAM_END_CURSOR, - QUERY_PARAM_START_CURSOR, -} from './constants'; +import { SORT_CREATED_AT, SORT_UPDATED_AT } from './constants'; const availableGroupActions = (userPermissions) => { const baseActions = []; @@ -52,28 +47,6 @@ export const formatGroups = (groups) => }), ); -export const onPageChange = ({ - startCursor, - endCursor, - routeQuery: { start_cursor, end_cursor, ...routeQuery }, -}) => { - if (startCursor) { - return { - ...routeQuery, - [QUERY_PARAM_START_CURSOR]: startCursor, - }; - } - - if (endCursor) { - return { - ...routeQuery, - [QUERY_PARAM_END_CURSOR]: endCursor, - }; - } - - return routeQuery; -}; - export const timestampType = (sortName) => { const SORT_MAP = { [SORT_CREATED_AT]: TIMESTAMP_TYPE_CREATED_AT, diff --git a/app/assets/javascripts/organizations/show/components/groups_and_projects.vue b/app/assets/javascripts/organizations/show/components/groups_and_projects.vue index 4b734d090a0..59a85808a84 100644 --- a/app/assets/javascripts/organizations/show/components/groups_and_projects.vue +++ b/app/assets/javascripts/organizations/show/components/groups_and_projects.vue @@ -4,16 +4,15 @@ import { isEqual } from 'lodash'; import { s__, __ } from '~/locale'; import GroupsView from '~/organizations/shared/components/groups_view.vue'; import ProjectsView from '~/organizations/shared/components/projects_view.vue'; -import { onPageChange } from '~/organizations/shared/utils'; +import { calculateGraphQLPaginationQueryParams } from '~/graphql_shared/utils'; import { RESOURCE_TYPE_GROUPS, RESOURCE_TYPE_PROJECTS, - QUERY_PARAM_END_CURSOR, - QUERY_PARAM_START_CURSOR, SORT_CREATED_AT, SORT_UPDATED_AT, SORT_DIRECTION_DESC, } from '~/organizations/shared/constants'; +import { QUERY_PARAM_END_CURSOR, QUERY_PARAM_START_CURSOR } from '~/graphql_shared/constants'; import { GROUPS_AND_PROJECTS_PER_PAGE } from '../constants'; import { buildDisplayListboxItem } from '../utils'; @@ -108,7 +107,9 @@ export default { this.pushQuery({ display }); }, onPageChange(pagination) { - this.pushQuery(onPageChange({ ...pagination, routeQuery: this.$route.query })); + this.pushQuery( + calculateGraphQLPaginationQueryParams({ ...pagination, routeQuery: this.$route.query }), + ); }, }, }; diff --git a/app/assets/javascripts/pages/users/activity_calendar.js b/app/assets/javascripts/pages/users/activity_calendar.js index aab603c6769..8b23c36638b 100644 --- a/app/assets/javascripts/pages/users/activity_calendar.js +++ b/app/assets/javascripts/pages/users/activity_calendar.js @@ -7,7 +7,7 @@ import { getDayName, getDayDifference, localeDateFormat, - pikadayToString, + toISODateFormat, newDate, } from '~/lib/utils/datetime_utility'; import { n__, s__, __ } from '~/locale'; @@ -117,7 +117,7 @@ export default class ActivityCalendar { date.setDate(date.getDate() + i); const day = date.getDay(); - const count = timestamps[pikadayToString(date)] || 0; + const count = timestamps[toISODateFormat(date)] || 0; // Create a new group array if this is the first day of the week // or if is first object diff --git a/app/assets/javascripts/projects/your_work/components/app.vue b/app/assets/javascripts/projects/your_work/components/app.vue index 58961ec5e7e..343ce808824 100644 --- a/app/assets/javascripts/projects/your_work/components/app.vue +++ b/app/assets/javascripts/projects/your_work/components/app.vue @@ -3,9 +3,11 @@ import { GlTabs, GlTab, GlBadge, GlFilteredSearchToken } from '@gitlab/ui'; import { isEqual } from 'lodash'; import { __ } from '~/locale'; import { TIMESTAMP_TYPE_UPDATED_AT } from '~/vue_shared/components/resource_lists/constants'; +import { QUERY_PARAM_END_CURSOR, QUERY_PARAM_START_CURSOR } from '~/graphql_shared/constants'; import { numberToMetricPrefix } from '~/lib/utils/number_utils'; import { createAlert } from '~/alert'; import FilteredSearchAndSort from '~/groups_projects/components/filtered_search_and_sort.vue'; +import { calculateGraphQLPaginationQueryParams } from '~/graphql_shared/utils'; import { RECENT_SEARCHES_STORAGE_KEY_PROJECTS } from '~/filtered_search/recent_searches_storage_keys'; import { OPERATORS_IS } from '~/vue_shared/components/filtered_search_bar/constants'; import { ACCESS_LEVEL_OWNER_INTEGER } from '~/access_level/constants'; @@ -133,6 +135,12 @@ export default { isAscending() { return this.sort.endsWith(SORT_DIRECTION_ASC); }, + startCursor() { + return this.$route.query[QUERY_PARAM_START_CURSOR]; + }, + endCursor() { + return this.$route.query[QUERY_PARAM_END_CURSOR]; + }, }, methods: { numberToMetricPrefix, @@ -182,6 +190,11 @@ export default { this.pushQuery({ sort, ...filters }); }, + onPageChange(pagination) { + this.pushQuery( + calculateGraphQLPaginationQueryParams({ ...pagination, routeQuery: this.$route.query }), + ); + }, }, }; @@ -201,7 +214,13 @@ export default { - + diff --git a/app/assets/javascripts/projects/your_work/components/tab_view.vue b/app/assets/javascripts/projects/your_work/components/tab_view.vue index ab44133e532..18bbfeda653 100644 --- a/app/assets/javascripts/projects/your_work/components/tab_view.vue +++ b/app/assets/javascripts/projects/your_work/components/tab_view.vue @@ -1,7 +1,8 @@ diff --git a/app/assets/javascripts/projects/your_work/graphql/queries/contributed_projects.query.graphql b/app/assets/javascripts/projects/your_work/graphql/queries/contributed_projects.query.graphql index 29588e0948a..161c6da3457 100644 --- a/app/assets/javascripts/projects/your_work/graphql/queries/contributed_projects.query.graphql +++ b/app/assets/javascripts/projects/your_work/graphql/queries/contributed_projects.query.graphql @@ -1,12 +1,16 @@ +#import "~/graphql_shared/fragments/page_info.fragment.graphql" #import "ee_else_ce/graphql_shared/fragments/project.fragment.graphql" -query getContributedProjects { +query getContributedProjects($first: Int, $last: Int, $before: String, $after: String) { currentUser { id - contributedProjects { + contributedProjects(first: $first, last: $last, before: $before, after: $after) { nodes { ...Project } + pageInfo { + ...PageInfo + } } } } diff --git a/app/assets/javascripts/projects/your_work/graphql/queries/inactive_projects.query.graphql b/app/assets/javascripts/projects/your_work/graphql/queries/inactive_projects.query.graphql index 742ab50e4d3..99d4cb30186 100644 --- a/app/assets/javascripts/projects/your_work/graphql/queries/inactive_projects.query.graphql +++ b/app/assets/javascripts/projects/your_work/graphql/queries/inactive_projects.query.graphql @@ -1,9 +1,20 @@ +#import "~/graphql_shared/fragments/page_info.fragment.graphql" #import "ee_else_ce/graphql_shared/fragments/project.fragment.graphql" -query getInactiveProjects { - projects(archived: ONLY, membership: true) { +query getInactiveProjects($first: Int, $last: Int, $before: String, $after: String) { + projects( + archived: ONLY + membership: true + first: $first + last: $last + before: $before + after: $after + ) { nodes { ...Project } + pageInfo { + ...PageInfo + } } } diff --git a/app/assets/javascripts/projects/your_work/graphql/queries/membership_projects.query.graphql b/app/assets/javascripts/projects/your_work/graphql/queries/membership_projects.query.graphql index e0b127d312e..f18ab0212b6 100644 --- a/app/assets/javascripts/projects/your_work/graphql/queries/membership_projects.query.graphql +++ b/app/assets/javascripts/projects/your_work/graphql/queries/membership_projects.query.graphql @@ -1,9 +1,13 @@ +#import "~/graphql_shared/fragments/page_info.fragment.graphql" #import "ee_else_ce/graphql_shared/fragments/project.fragment.graphql" -query getMembershipProjects { - projects(membership: true) { +query getMembershipProjects($first: Int, $last: Int, $before: String, $after: String) { + projects(membership: true, first: $first, last: $last, before: $before, after: $after) { nodes { ...Project } + pageInfo { + ...PageInfo + } } } diff --git a/app/assets/javascripts/projects/your_work/graphql/queries/personal_projects.query.graphql b/app/assets/javascripts/projects/your_work/graphql/queries/personal_projects.query.graphql index fdfca493170..f4cc871f1f4 100644 --- a/app/assets/javascripts/projects/your_work/graphql/queries/personal_projects.query.graphql +++ b/app/assets/javascripts/projects/your_work/graphql/queries/personal_projects.query.graphql @@ -1,9 +1,13 @@ +#import "~/graphql_shared/fragments/page_info.fragment.graphql" #import "ee_else_ce/graphql_shared/fragments/project.fragment.graphql" -query getPersonalProjects { - projects(personal: true) { +query getPersonalProjects($first: Int, $last: Int, $before: String, $after: String) { + projects(personal: true, first: $first, last: $last, before: $before, after: $after) { nodes { ...Project } + pageInfo { + ...PageInfo + } } } diff --git a/app/assets/javascripts/projects/your_work/graphql/queries/starred_projects.query.graphql b/app/assets/javascripts/projects/your_work/graphql/queries/starred_projects.query.graphql index f35bd137198..d2df5f2804a 100644 --- a/app/assets/javascripts/projects/your_work/graphql/queries/starred_projects.query.graphql +++ b/app/assets/javascripts/projects/your_work/graphql/queries/starred_projects.query.graphql @@ -1,12 +1,16 @@ +#import "~/graphql_shared/fragments/page_info.fragment.graphql" #import "ee_else_ce/graphql_shared/fragments/project.fragment.graphql" -query getStarredProjects { +query getStarredProjects($first: Int, $last: Int, $before: String, $after: String) { currentUser { id - starredProjects { + starredProjects(first: $first, last: $last, before: $before, after: $after) { nodes { ...Project } + pageInfo { + ...PageInfo + } } } } diff --git a/app/assets/javascripts/todos/components/filtered_search_tokens/group_token.vue b/app/assets/javascripts/todos/components/filtered_search_tokens/group_token.vue new file mode 100644 index 00000000000..779e04bd0c9 --- /dev/null +++ b/app/assets/javascripts/todos/components/filtered_search_tokens/group_token.vue @@ -0,0 +1,105 @@ + + + diff --git a/app/assets/javascripts/todos/components/filtered_search_tokens/project_token.vue b/app/assets/javascripts/todos/components/filtered_search_tokens/project_token.vue new file mode 100644 index 00000000000..0db558b8f49 --- /dev/null +++ b/app/assets/javascripts/todos/components/filtered_search_tokens/project_token.vue @@ -0,0 +1,105 @@ + + + diff --git a/app/assets/javascripts/todos/components/queries/search_groups.query.graphql b/app/assets/javascripts/todos/components/queries/search_groups.query.graphql new file mode 100644 index 00000000000..dd6e97aa0f7 --- /dev/null +++ b/app/assets/javascripts/todos/components/queries/search_groups.query.graphql @@ -0,0 +1,8 @@ +query searchGroups($search: String) { + groups(search: $search, first: 20) { + nodes { + id + fullName + } + } +} diff --git a/app/assets/javascripts/todos/components/queries/search_projects.query.graphql b/app/assets/javascripts/todos/components/queries/search_projects.query.graphql new file mode 100644 index 00000000000..a03719e3ead --- /dev/null +++ b/app/assets/javascripts/todos/components/queries/search_projects.query.graphql @@ -0,0 +1,8 @@ +query searchTodosProjects($search: String) { + projects(search: $search, membership: true, first: 20) { + nodes { + id + name + } + } +} diff --git a/app/assets/javascripts/todos/components/todos_app.vue b/app/assets/javascripts/todos/components/todos_app.vue index 07506b51612..00f2564f034 100644 --- a/app/assets/javascripts/todos/components/todos_app.vue +++ b/app/assets/javascripts/todos/components/todos_app.vue @@ -49,6 +49,7 @@ export default { action: [], sort: `${SORT_OPTIONS[0].value}_DESC`, }, + alert: null, }; }, apollo: { @@ -67,7 +68,7 @@ export default { return nodes; }, error(error) { - createAlert({ message: s__('Todos|Something went wrong. Please try again.') }); + this.alert = createAlert({ message: s__('Todos|Something went wrong. Please try again.') }); Sentry.captureException(error); }, }, @@ -140,6 +141,7 @@ export default { }; }, handleFiltersChanged(data) { + this.alert?.dismiss(); this.queryFilterValues = { ...data }; }, }, diff --git a/app/assets/javascripts/todos/components/todos_filter_bar.vue b/app/assets/javascripts/todos/components/todos_filter_bar.vue index 17f8968d1ee..a9001550c72 100644 --- a/app/assets/javascripts/todos/components/todos_filter_bar.vue +++ b/app/assets/javascripts/todos/components/todos_filter_bar.vue @@ -1,8 +1,15 @@