diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-01-06 12:10:04 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-01-06 12:10:04 +0000 |
commit | 53fb4ad16325d4963fdc5396b8510ab748a45e50 (patch) | |
tree | b1bd9ce5cbff5bf9c94f60fee3db86d3d53ffadc /app | |
parent | f57ca9a5fc582232e23b2495812d57bf6f64313b (diff) | |
download | gitlab-ce-53fb4ad16325d4963fdc5396b8510ab748a45e50.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
13 files changed, 109 insertions, 106 deletions
diff --git a/app/assets/javascripts/groups_select.js b/app/assets/javascripts/groups_select.js index fb0c47fe018..2a2599801ca 100644 --- a/app/assets/javascripts/groups_select.js +++ b/app/assets/javascripts/groups_select.js @@ -1,12 +1,5 @@ import Vue from 'vue'; -import $ from 'jquery'; -import { escape } from 'lodash'; import GroupSelect from '~/vue_shared/components/group_select/group_select.vue'; -import { groupsPath } from '~/vue_shared/components/group_select/utils'; -import { __ } from '~/locale'; -import Api from './api'; -import { loadCSSFile } from './lib/utils/css_utils'; -import { select2AxiosTransport } from './lib/utils/select2_utils'; const initVueSelect = () => { [...document.querySelectorAll('.ajax-groups-select')].forEach((el) => { @@ -33,90 +26,6 @@ const initVueSelect = () => { }); }; -const groupsSelect = () => { - loadCSSFile(gon.select2_css_path) - .then(() => { - // Needs to be accessible in rspec - window.GROUP_SELECT_PER_PAGE = 20; - - $('.ajax-groups-select').each(function setAjaxGroupsSelect2() { - const $select = $(this); - const allAvailable = $select.data('allAvailable'); - const skipGroups = $select.data('skipGroups') || []; - const parentGroupID = $select.data('parentId'); - const groupsFilter = $select.data('groupsFilter'); - const minAccessLevel = $select.data('minAccessLevel'); - - $select.select2({ - placeholder: __('Search for a group'), - allowClear: $select.hasClass('allowClear'), - multiple: $select.hasClass('multiselect'), - minimumInputLength: 0, - ajax: { - url: Api.buildUrl(groupsPath(groupsFilter, parentGroupID)), - dataType: 'json', - quietMillis: 250, - transport: select2AxiosTransport, - data(search, page) { - return { - search, - page, - per_page: window.GROUP_SELECT_PER_PAGE, - all_available: allAvailable, - min_access_level: minAccessLevel, - }; - }, - results(data, page) { - const groups = data.length ? data : data.results || []; - const more = data.pagination ? data.pagination.more : false; - const results = groups.filter((group) => skipGroups.indexOf(group.id) === -1); - - return { - results, - page, - more, - }; - }, - }, - // eslint-disable-next-line consistent-return - initSelection(element, callback) { - const id = $(element).val(); - if (id !== '') { - return Api.group(id, callback); - } - }, - formatResult(object) { - return `<div class='group-result'> <div class='group-name'>${escape( - object.full_name, - )}</div> <div class='group-path'>${object.full_path}</div> </div>`; - }, - formatSelection(object) { - return escape(object.full_name); - }, - dropdownCssClass: 'ajax-groups-dropdown select2-infinite', - // we do not want to escape markup since we are displaying html in results - escapeMarkup(m) { - return m; - }, - }); - - $select.on('select2-loaded', () => { - const dropdown = document.querySelector('.select2-infinite .select2-results'); - dropdown.style.height = `${Math.floor(dropdown.scrollHeight)}px`; - }); - }); - }) - .catch(() => {}); -}; - export default () => { - if ($('.ajax-groups-select').length) { - if (gon.features?.vueGroupSelect) { - initVueSelect(); - } else { - import(/* webpackChunkName: 'select2' */ 'select2/select2') - .then(groupsSelect) - .catch(() => {}); - } - } + initVueSelect(); }; diff --git a/app/assets/javascripts/issuable/components/related_issuable_item.vue b/app/assets/javascripts/issuable/components/related_issuable_item.vue index fd55f05e955..c815c7aaba9 100644 --- a/app/assets/javascripts/issuable/components/related_issuable_item.vue +++ b/app/assets/javascripts/issuable/components/related_issuable_item.vue @@ -135,7 +135,6 @@ export default { <gl-link :href="computedPath" class="sortable-link gl-font-weight-normal" - target="_blank" @click="handleTitleClick" > {{ title }} diff --git a/app/assets/javascripts/ml/experiment_tracking/components/ml_experiment.vue b/app/assets/javascripts/ml/experiment_tracking/components/ml_experiment.vue index f8e269d3b57..0e601a67d85 100644 --- a/app/assets/javascripts/ml/experiment_tracking/components/ml_experiment.vue +++ b/app/assets/javascripts/ml/experiment_tracking/components/ml_experiment.vue @@ -1,6 +1,7 @@ <script> -import { GlTable, GlLink } from '@gitlab/ui'; +import { GlTable, GlLink, GlPagination } from '@gitlab/ui'; import { __ } from '~/locale'; +import { getParameterValues, setUrlParams } from '~/lib/utils/url_utility'; import IncubationAlert from './incubation_alert.vue'; export default { @@ -9,8 +10,14 @@ export default { GlTable, GlLink, IncubationAlert, + GlPagination, + }, + inject: ['candidates', 'metricNames', 'paramNames', 'pagination'], + data() { + return { + page: parseInt(getParameterValues('page')[0], 10) || 1, + }; }, - inject: ['candidates', 'metricNames', 'paramNames'], computed: { fields() { return [ @@ -20,6 +27,20 @@ export default { { key: 'artifact', label: '' }, ]; }, + displayPagination() { + return this.candidates.length > 0; + }, + prevPage() { + return this.pagination.page > 1 ? this.pagination.page - 1 : null; + }, + nextPage() { + return !this.pagination.isLastPage ? this.pagination.page + 1 : null; + }, + }, + methods: { + generateLink(page) { + return setUrlParams({ page }); + }, }, i18n: { titleLabel: __('Experiment candidates'), @@ -44,6 +65,7 @@ export default { :empty-text="$options.i18n.emptyStateLabel" show-empty class="gl-mt-0!" + small > <template #cell(artifact)="data"> <gl-link v-if="data.value" :href="data.value" target="_blank">{{ @@ -55,5 +77,17 @@ export default { <gl-link :href="data.value">{{ $options.i18n.detailsLabel }}</gl-link> </template> </gl-table> + + <gl-pagination + v-if="displayPagination" + v-model="pagination.page" + :prev-page="prevPage" + :next-page="nextPage" + :total-items="pagination.totalItems" + :per-page="pagination.perPage" + :link-gen="generateLink" + align="center" + class="w-100" + /> </div> </template> diff --git a/app/assets/javascripts/pages/projects/ml/experiments/show/index.js b/app/assets/javascripts/pages/projects/ml/experiments/show/index.js index 97e436920c7..6947b15dcbe 100644 --- a/app/assets/javascripts/pages/projects/ml/experiments/show/index.js +++ b/app/assets/javascripts/pages/projects/ml/experiments/show/index.js @@ -1,5 +1,6 @@ import Vue from 'vue'; import MlExperiment from '~/ml/experiment_tracking/components/ml_experiment.vue'; +import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; const initShowExperiment = () => { const element = document.querySelector('#js-show-ml-experiment'); @@ -13,6 +14,7 @@ const initShowExperiment = () => { const candidates = JSON.parse(element.dataset.candidates); const metricNames = JSON.parse(element.dataset.metrics); const paramNames = JSON.parse(element.dataset.params); + const pagination = convertObjectPropsToCamelCase(JSON.parse(element.dataset.pagination)); // eslint-disable-next-line no-new new Vue({ @@ -21,6 +23,7 @@ const initShowExperiment = () => { candidates, metricNames, paramNames, + pagination, }, render(h) { return h(MlExperiment); diff --git a/app/assets/javascripts/projects/commits/index.js b/app/assets/javascripts/projects/commits/index.js index 53169f689c9..f56884f605f 100644 --- a/app/assets/javascripts/projects/commits/index.js +++ b/app/assets/javascripts/projects/commits/index.js @@ -33,20 +33,31 @@ export const initCommitsRefSwitcher = () => { if (!el) return false; - const { projectId, ref, commitsPath } = el.dataset; + const { projectId, ref, commitsPath, refType } = el.dataset; const commitsPathPrefix = commitsPath.match(COMMITS_PATH_REGEX)?.[0]; - + const useSymbolicRefNames = Boolean(refType); return new Vue({ el, render(createElement) { return createElement(RefSelector, { props: { projectId, - value: ref, + value: useSymbolicRefNames ? `refs/${refType}/${ref}` : ref, + useSymbolicRefNames, + refType, }, on: { input(selected) { - visitUrl(`${commitsPathPrefix}/${selected}`); + if (useSymbolicRefNames) { + const matches = selected.match(/refs\/(heads|tags)\/(.+)/); + if (matches) { + visitUrl(`${commitsPathPrefix}/${matches[2]}?ref_type=${matches[1]}`); + } else { + visitUrl(`${commitsPathPrefix}/${selected}`); + } + } else { + visitUrl(`${commitsPathPrefix}/${selected}`); + } }, }, }); diff --git a/app/assets/javascripts/ref/components/ref_results_section.vue b/app/assets/javascripts/ref/components/ref_results_section.vue index 4fa2a92ff03..52d1ed96b21 100644 --- a/app/assets/javascripts/ref/components/ref_results_section.vue +++ b/app/assets/javascripts/ref/components/ref_results_section.vue @@ -74,6 +74,11 @@ export default { required: false, default: '', }, + shouldShowCheck: { + type: Boolean, + required: false, + default: true, + }, }, computed: { totalCountText() { @@ -82,6 +87,9 @@ export default { }, methods: { showCheck(item) { + if (!this.shouldShowCheck) { + return false; + } return item.name === this.selectedRef || item.value === this.selectedRef; }, }, diff --git a/app/assets/javascripts/ref/components/ref_selector.vue b/app/assets/javascripts/ref/components/ref_selector.vue index b75958e2ced..10967fb84ed 100644 --- a/app/assets/javascripts/ref/components/ref_selector.vue +++ b/app/assets/javascripts/ref/components/ref_selector.vue @@ -15,6 +15,8 @@ import { REF_TYPE_BRANCHES, REF_TYPE_TAGS, REF_TYPE_COMMITS, + BRANCH_REF_TYPE, + TAG_REF_TYPE, } from '../constants'; import createStore from '../stores'; import RefResultsSection from './ref_results_section.vue'; @@ -50,6 +52,11 @@ export default { required: false, default: '', }, + refType: { + type: String, + required: false, + default: null, + }, projectId: { type: String, required: true, @@ -146,6 +153,12 @@ export default { buttonText() { return this.selectedRefForDisplay || this.i18n.noRefSelected; }, + isTagRefType() { + return this.refType === TAG_REF_TYPE; + }, + isBranchRefType() { + return this.refType === BRANCH_REF_TYPE; + }, }, watch: { // Keep the Vuex store synchronized if the parent @@ -273,6 +286,7 @@ export default { :show-header="showSectionHeaders" data-testid="branches-section" data-qa-selector="branches_section" + :should-show-check="!useSymbolicRefNames || isBranchRefType" @selected="selectRef($event)" /> @@ -289,6 +303,7 @@ export default { :error-message="i18n.tagsErrorMessage" :show-header="showSectionHeaders" data-testid="tags-section" + :should-show-check="!useSymbolicRefNames || isTagRefType" @selected="selectRef($event)" /> diff --git a/app/assets/javascripts/ref/constants.js b/app/assets/javascripts/ref/constants.js index 397e3ed2ac8..f4faa535166 100644 --- a/app/assets/javascripts/ref/constants.js +++ b/app/assets/javascripts/ref/constants.js @@ -5,6 +5,8 @@ export const REF_TYPE_BRANCHES = 'REF_TYPE_BRANCHES'; export const REF_TYPE_TAGS = 'REF_TYPE_TAGS'; export const REF_TYPE_COMMITS = 'REF_TYPE_COMMITS'; export const ALL_REF_TYPES = Object.freeze([REF_TYPE_BRANCHES, REF_TYPE_TAGS, REF_TYPE_COMMITS]); +export const BRANCH_REF_TYPE = 'heads'; +export const TAG_REF_TYPE = 'tags'; export const X_TOTAL_HEADER = 'x-total'; diff --git a/app/assets/javascripts/vue_shared/components/pagination/table_pagination.vue b/app/assets/javascripts/vue_shared/components/pagination/table_pagination.vue index 5f2a66ee0b7..e1f042f78ab 100644 --- a/app/assets/javascripts/vue_shared/components/pagination/table_pagination.vue +++ b/app/assets/javascripts/vue_shared/components/pagination/table_pagination.vue @@ -64,8 +64,9 @@ export default { <template> <gl-pagination v-if="showPagination" - class="justify-content-center gl-mt-3" + class="gl-mt-3" v-bind="$attrs" + align="center" :value="pageInfo.page" :per-page="pageInfo.perPage" :total-items="pageInfo.total" diff --git a/app/controllers/projects/ml/experiments_controller.rb b/app/controllers/projects/ml/experiments_controller.rb index c0e4783602d..575ca23f815 100644 --- a/app/controllers/projects/ml/experiments_controller.rb +++ b/app/controllers/projects/ml/experiments_controller.rb @@ -7,10 +7,11 @@ module Projects feature_category :mlops - MAX_PER_PAGE = 20 + MAX_EXPERIMENTS_PER_PAGE = 20 + MAX_CANDIDATES_PER_PAGE = 30 def index - @experiments = ::Ml::Experiment.by_project_id(@project.id).page(params[:page]).per(MAX_PER_PAGE) + @experiments = ::Ml::Experiment.by_project_id(@project.id).page(params[:page]).per(MAX_EXPERIMENTS_PER_PAGE) end def show @@ -18,7 +19,25 @@ module Projects return redirect_to project_ml_experiments_path(@project) unless @experiment.present? - @candidates = @experiment.candidates&.including_metrics_and_params + page = params[:page].to_i + page = 1 if page == 0 + + @candidates = @experiment.candidates + .including_metrics_and_params + .page(page) + .per(MAX_CANDIDATES_PER_PAGE) + + return unless @candidates + + return redirect_to(url_for(page: @candidates.total_pages)) if @candidates.out_of_range? + + @pagination = { + page: page, + is_last_page: @candidates.last_page?, + per_page: MAX_CANDIDATES_PER_PAGE, + total_items: @candidates.total_count + } + @candidates.each(&:artifact_lazy) end diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml index c129d978e7e..8f802792e6a 100644 --- a/app/views/projects/commits/show.html.haml +++ b/app/views/projects/commits/show.html.haml @@ -10,7 +10,7 @@ .nav-block .tree-ref-container .tree-ref-holder - #js-project-commits-ref-switcher{ data: { "project-id" => @project.id, "ref" => @ref, "commits_path": project_commits_path(@project) } } + #js-project-commits-ref-switcher{ data: { "project-id" => @project.id, "ref" => @ref, "commits_path": project_commits_path(@project), "ref_type": @ref_type.to_s } } %ul.breadcrumb.repo-breadcrumb = commits_breadcrumbs diff --git a/app/views/projects/ml/experiments/show.html.haml b/app/views/projects/ml/experiments/show.html.haml index 2c350439762..143981eebe6 100644 --- a/app/views/projects/ml/experiments/show.html.haml +++ b/app/views/projects/ml/experiments/show.html.haml @@ -11,4 +11,6 @@ #js-show-ml-experiment{ data: { candidates: items, metrics: metrics, - params: params } } + params: params, + pagination: @pagination.to_json +} } diff --git a/app/views/shared/runners/_runner_type_alert.html.haml b/app/views/shared/runners/_runner_type_alert.html.haml index 9736780c436..a1599b3ec49 100644 --- a/app/views/shared/runners/_runner_type_alert.html.haml +++ b/app/views/shared/runners/_runner_type_alert.html.haml @@ -12,5 +12,5 @@ title: s_('Runners|This runner is associated with specific projects.'), dismissible: false) do |c| = c.body do - = s_('Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared runner.') + = s_('Runners|You can set up a specific runner to be used by multiple projects but you cannot make this a shared or group runner.') = link_to _('Learn more.'), help_page_path('ci/runners/runners_scope', anchor: 'specific-runners'), target: '_blank', rel: 'noopener noreferrer' |