summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-01-06 12:10:04 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2023-01-06 12:10:04 +0000
commit53fb4ad16325d4963fdc5396b8510ab748a45e50 (patch)
treeb1bd9ce5cbff5bf9c94f60fee3db86d3d53ffadc /app
parentf57ca9a5fc582232e23b2495812d57bf6f64313b (diff)
downloadgitlab-ce-53fb4ad16325d4963fdc5396b8510ab748a45e50.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/groups_select.js93
-rw-r--r--app/assets/javascripts/issuable/components/related_issuable_item.vue1
-rw-r--r--app/assets/javascripts/ml/experiment_tracking/components/ml_experiment.vue38
-rw-r--r--app/assets/javascripts/pages/projects/ml/experiments/show/index.js3
-rw-r--r--app/assets/javascripts/projects/commits/index.js19
-rw-r--r--app/assets/javascripts/ref/components/ref_results_section.vue8
-rw-r--r--app/assets/javascripts/ref/components/ref_selector.vue15
-rw-r--r--app/assets/javascripts/ref/constants.js2
-rw-r--r--app/assets/javascripts/vue_shared/components/pagination/table_pagination.vue3
-rw-r--r--app/controllers/projects/ml/experiments_controller.rb25
-rw-r--r--app/views/projects/commits/show.html.haml2
-rw-r--r--app/views/projects/ml/experiments/show.html.haml4
-rw-r--r--app/views/shared/runners/_runner_type_alert.html.haml2
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'