Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
9bc96aa4f9
commit
b0891151f1
184 changed files with 1032 additions and 1050 deletions
|
@ -3,9 +3,6 @@ GraphQL/OrderedArguments:
|
|||
Exclude:
|
||||
- app/graphql/mutations/jira_import/start.rb
|
||||
- app/graphql/mutations/merge_requests/accept.rb
|
||||
- app/graphql/resolvers/base_issues_resolver.rb
|
||||
- app/graphql/resolvers/design_management/designs_resolver.rb
|
||||
- app/graphql/resolvers/design_management/version/design_at_version_resolver.rb
|
||||
- app/graphql/resolvers/design_management/version/designs_at_version_resolver.rb
|
||||
- app/graphql/resolvers/design_management/version_in_collection_resolver.rb
|
||||
- app/graphql/resolvers/group_milestones_resolver.rb
|
||||
|
|
|
@ -10,7 +10,6 @@ Performance/ActiveRecordSubtransactionMethods:
|
|||
- app/models/design_management/design_collection.rb
|
||||
- app/models/error_tracking/error.rb
|
||||
- app/models/external_pull_request.rb
|
||||
- app/models/gpg_signature.rb
|
||||
- app/models/merge_request.rb
|
||||
- app/models/plan.rb
|
||||
- app/models/project.rb
|
||||
|
@ -18,6 +17,7 @@ Performance/ActiveRecordSubtransactionMethods:
|
|||
- app/models/x509_certificate.rb
|
||||
- app/models/x509_commit_signature.rb
|
||||
- app/models/x509_issuer.rb
|
||||
- app/models/concerns/commit_signature.rb
|
||||
- app/services/bulk_imports/relation_export_service.rb
|
||||
- app/services/ci/update_build_state_service.rb
|
||||
- app/services/event_create_service.rb
|
||||
|
|
|
@ -3,9 +3,6 @@ Rails/SaveBang:
|
|||
Exclude:
|
||||
- ee/spec/initializers/fog_google_https_private_urls_spec.rb
|
||||
- ee/spec/lib/analytics/merge_request_metrics_calculator_spec.rb
|
||||
- ee/spec/lib/ee/gitlab/auth/ldap/sync/group_spec.rb
|
||||
- ee/spec/lib/ee/gitlab/checks/push_rules/commit_check_spec.rb
|
||||
- ee/spec/lib/ee/gitlab/ci/pipeline/quota/activity_spec.rb
|
||||
- ee/spec/lib/gitlab/auth/ldap/access_spec.rb
|
||||
- ee/spec/lib/gitlab/auth/o_auth/user_spec.rb
|
||||
- ee/spec/lib/gitlab/auth/saml/user_spec.rb
|
||||
|
|
|
@ -1 +1 @@
|
|||
27dddad834d99e9901b4a9b137748b850e71849a
|
||||
9aa8e36d420402b19210dcf861f7bf619ff39089
|
||||
|
|
|
@ -1 +1 @@
|
|||
2.16.0
|
||||
2.17.0
|
||||
|
|
2
Gemfile
2
Gemfile
|
@ -194,7 +194,7 @@ end
|
|||
gem 'state_machines-activerecord', '~> 0.8.0'
|
||||
|
||||
# Issue tags
|
||||
gem 'acts-as-taggable-on', '~> 7.0'
|
||||
gem 'acts-as-taggable-on', '~> 8.1'
|
||||
|
||||
# Background jobs
|
||||
gem 'sidekiq', '~> 6.3'
|
||||
|
|
|
@ -73,7 +73,7 @@ GEM
|
|||
minitest (>= 5.1)
|
||||
tzinfo (~> 2.0)
|
||||
zeitwerk (~> 2.3)
|
||||
acts-as-taggable-on (7.0.0)
|
||||
acts-as-taggable-on (8.1.0)
|
||||
activerecord (>= 5.0, < 6.2)
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
|
@ -1390,7 +1390,7 @@ DEPENDENCIES
|
|||
RedCloth (~> 4.3.2)
|
||||
acme-client (~> 2.0, >= 2.0.6)
|
||||
activerecord-explain-analyze (~> 0.1)
|
||||
acts-as-taggable-on (~> 7.0)
|
||||
acts-as-taggable-on (~> 8.1)
|
||||
addressable (~> 2.8)
|
||||
akismet (~> 3.0)
|
||||
apollo_upload_server (~> 2.1.0)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { omitBy, isNil } from 'lodash';
|
||||
import { objectToQuery } from '~/lib/utils/url_utility';
|
||||
|
||||
import {
|
||||
|
@ -12,23 +13,29 @@ import {
|
|||
} from '../constants';
|
||||
|
||||
export const searchQuery = (state) => {
|
||||
const query = {
|
||||
search: state.search,
|
||||
nav_source: 'navbar',
|
||||
project_id: state.searchContext.project?.id,
|
||||
group_id: state.searchContext.group?.id,
|
||||
scope: state.searchContext.scope,
|
||||
};
|
||||
const query = omitBy(
|
||||
{
|
||||
search: state.search,
|
||||
nav_source: 'navbar',
|
||||
project_id: state.searchContext.project?.id,
|
||||
group_id: state.searchContext.group?.id,
|
||||
scope: state.searchContext?.scope,
|
||||
},
|
||||
isNil,
|
||||
);
|
||||
|
||||
return `${state.searchPath}?${objectToQuery(query)}`;
|
||||
};
|
||||
|
||||
export const autocompleteQuery = (state) => {
|
||||
const query = {
|
||||
term: state.search,
|
||||
project_id: state.searchContext.project?.id,
|
||||
project_ref: state.searchContext.ref,
|
||||
};
|
||||
const query = omitBy(
|
||||
{
|
||||
term: state.search,
|
||||
project_id: state.searchContext.project?.id,
|
||||
project_ref: state.searchContext?.ref,
|
||||
},
|
||||
isNil,
|
||||
);
|
||||
|
||||
return `${state.autocompletePath}?${objectToQuery(query)}`;
|
||||
};
|
||||
|
@ -82,42 +89,43 @@ export const defaultSearchOptions = (state, getters) => {
|
|||
};
|
||||
|
||||
export const projectUrl = (state) => {
|
||||
if (!state.searchContext.project || !state.searchContext.group) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const query = {
|
||||
search: state.search,
|
||||
nav_source: 'navbar',
|
||||
project_id: state.searchContext.project.id,
|
||||
group_id: state.searchContext.group.id,
|
||||
scope: state.searchContext.scope,
|
||||
};
|
||||
const query = omitBy(
|
||||
{
|
||||
search: state.search,
|
||||
nav_source: 'navbar',
|
||||
project_id: state.searchContext?.project?.id,
|
||||
group_id: state.searchContext?.group?.id,
|
||||
scope: state.searchContext?.scope,
|
||||
},
|
||||
isNil,
|
||||
);
|
||||
|
||||
return `${state.searchPath}?${objectToQuery(query)}`;
|
||||
};
|
||||
|
||||
export const groupUrl = (state) => {
|
||||
if (!state.searchContext.group) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const query = {
|
||||
search: state.search,
|
||||
nav_source: 'navbar',
|
||||
group_id: state.searchContext.group.id,
|
||||
scope: state.searchContext.scope,
|
||||
};
|
||||
const query = omitBy(
|
||||
{
|
||||
search: state.search,
|
||||
nav_source: 'navbar',
|
||||
group_id: state.searchContext?.group?.id,
|
||||
scope: state.searchContext?.scope,
|
||||
},
|
||||
isNil,
|
||||
);
|
||||
|
||||
return `${state.searchPath}?${objectToQuery(query)}`;
|
||||
};
|
||||
|
||||
export const allUrl = (state) => {
|
||||
const query = {
|
||||
search: state.search,
|
||||
nav_source: 'navbar',
|
||||
scope: state.searchContext.scope,
|
||||
};
|
||||
const query = omitBy(
|
||||
{
|
||||
search: state.search,
|
||||
nav_source: 'navbar',
|
||||
scope: state.searchContext?.scope,
|
||||
},
|
||||
isNil,
|
||||
);
|
||||
|
||||
return `${state.searchPath}?${objectToQuery(query)}`;
|
||||
};
|
||||
|
|
|
@ -117,7 +117,11 @@ export default {
|
|||
</p>
|
||||
<template v-if="showJiraIssuesIntegration">
|
||||
<input name="service[issues_enabled]" type="hidden" :value="enableJiraIssues || false" />
|
||||
<gl-form-checkbox v-model="enableJiraIssues" :disabled="isInheriting">
|
||||
<gl-form-checkbox
|
||||
v-model="enableJiraIssues"
|
||||
:disabled="isInheriting"
|
||||
data-qa-selector="service_jira_issues_enabled_checkbox"
|
||||
>
|
||||
{{ $options.i18n.enableCheckboxLabel }}
|
||||
<template #help>
|
||||
{{ $options.i18n.enableCheckboxHelp }}
|
||||
|
@ -162,6 +166,7 @@ export default {
|
|||
id="service_project_key"
|
||||
v-model="projectKey"
|
||||
name="service[project_key]"
|
||||
data-qa-selector="service_jira_project_key_field"
|
||||
:placeholder="$options.i18n.projectKeyPlaceholder"
|
||||
:required="enableJiraIssues"
|
||||
:state="validProjectKey"
|
||||
|
|
25
app/assets/javascripts/issues/constants.js
Normal file
25
app/assets/javascripts/issues/constants.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { __ } from '~/locale';
|
||||
|
||||
export const IssuableStatus = {
|
||||
Closed: 'closed',
|
||||
Open: 'opened',
|
||||
Reopened: 'reopened',
|
||||
};
|
||||
|
||||
export const IssuableStatusText = {
|
||||
[IssuableStatus.Closed]: __('Closed'),
|
||||
[IssuableStatus.Open]: __('Open'),
|
||||
[IssuableStatus.Reopened]: __('Open'),
|
||||
};
|
||||
|
||||
export const IssuableType = {
|
||||
Issue: 'issue',
|
||||
Epic: 'epic',
|
||||
MergeRequest: 'merge_request',
|
||||
Alert: 'alert',
|
||||
};
|
||||
|
||||
export const WorkspaceType = {
|
||||
project: 'project',
|
||||
group: 'group',
|
||||
};
|
|
@ -2,18 +2,11 @@
|
|||
import { GlIcon, GlIntersectionObserver, GlTooltipDirective } from '@gitlab/ui';
|
||||
import Visibility from 'visibilityjs';
|
||||
import createFlash from '~/flash';
|
||||
import { IssuableStatus, IssuableStatusText, IssuableType } from '~/issues/constants';
|
||||
import Poll from '~/lib/utils/poll';
|
||||
import { visitUrl } from '~/lib/utils/url_utility';
|
||||
import { __, sprintf } from '~/locale';
|
||||
import {
|
||||
IssuableStatus,
|
||||
IssuableStatusText,
|
||||
IssuableType,
|
||||
IssueTypePath,
|
||||
IncidentTypePath,
|
||||
IncidentType,
|
||||
POLLING_DELAY,
|
||||
} from '../constants';
|
||||
import { IssueTypePath, IncidentTypePath, IncidentType, POLLING_DELAY } from '../constants';
|
||||
import eventHub from '../event_hub';
|
||||
import getIssueStateQuery from '../queries/get_issue_state.query.graphql';
|
||||
import Service from '../services/index';
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { GlAlert } from '@gitlab/ui';
|
||||
import $ from 'jquery';
|
||||
import Autosave from '~/autosave';
|
||||
import { IssuableType } from '~/issues/show/constants';
|
||||
import { IssuableType } from '~/issues/constants';
|
||||
import eventHub from '../event_hub';
|
||||
import EditActions from './edit_actions.vue';
|
||||
import DescriptionField from './fields/description.vue';
|
||||
|
|
|
@ -4,7 +4,8 @@ import { mapActions, mapGetters, mapState } from 'vuex';
|
|||
import createFlash, { FLASH_TYPES } from '~/flash';
|
||||
import { EVENT_ISSUABLE_VUE_APP_CHANGE } from '~/issuable/constants';
|
||||
import { IssuableType } from '~/vue_shared/issuable/show/constants';
|
||||
import { IssuableStatus, IssueStateEvent } from '~/issues/show/constants';
|
||||
import { IssuableStatus } from '~/issues/constants';
|
||||
import { IssueStateEvent } from '~/issues/show/constants';
|
||||
import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
|
||||
import { visitUrl } from '~/lib/utils/url_utility';
|
||||
import { s__, __, sprintf } from '~/locale';
|
||||
|
|
|
@ -1,24 +1,5 @@
|
|||
import { __ } from '~/locale';
|
||||
|
||||
export const IssuableStatus = {
|
||||
Closed: 'closed',
|
||||
Open: 'opened',
|
||||
Reopened: 'reopened',
|
||||
};
|
||||
|
||||
export const IssuableStatusText = {
|
||||
[IssuableStatus.Closed]: __('Closed'),
|
||||
[IssuableStatus.Open]: __('Open'),
|
||||
[IssuableStatus.Reopened]: __('Open'),
|
||||
};
|
||||
|
||||
export const IssuableType = {
|
||||
Issue: 'issue',
|
||||
Epic: 'epic',
|
||||
MergeRequest: 'merge_request',
|
||||
Alert: 'alert',
|
||||
};
|
||||
|
||||
export const IssueStateEvent = {
|
||||
Close: 'CLOSE',
|
||||
Reopen: 'REOPEN',
|
||||
|
@ -39,8 +20,3 @@ export const IncidentType = 'incident';
|
|||
export const issueState = { issueType: undefined, isDirty: false };
|
||||
|
||||
export const POLLING_DELAY = 2000;
|
||||
|
||||
export const WorkspaceType = {
|
||||
project: 'project',
|
||||
group: 'group',
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import { mapActions } from 'vuex';
|
||||
import { IssuableType } from '~/issues/show/constants';
|
||||
import { IssuableType } from '~/issues/constants';
|
||||
import { fetchPolicies } from '~/lib/graphql';
|
||||
import { confidentialityQueries } from '~/sidebar/constants';
|
||||
import { defaultClient as gqlClient } from '~/sidebar/graphql';
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
import { s__ } from '~/locale';
|
||||
|
||||
export const PackageType = {
|
||||
CONAN: 'conan',
|
||||
MAVEN: 'maven',
|
||||
NPM: 'npm',
|
||||
NUGET: 'nuget',
|
||||
PYPI: 'pypi',
|
||||
COMPOSER: 'composer',
|
||||
RUBYGEMS: 'rubygems',
|
||||
GENERIC: 'generic',
|
||||
DEBIAN: 'debian',
|
||||
HELM: 'helm',
|
||||
};
|
||||
|
||||
// we want this separated from the main dictionary to avoid it being pulled in the search of package
|
||||
export const TERRAFORM_PACKAGE_TYPE = 'terraform_module';
|
||||
|
||||
export const TrackingActions = {
|
||||
DELETE_PACKAGE: 'delete_package',
|
||||
REQUEST_DELETE_PACKAGE: 'request_delete_package',
|
||||
CANCEL_DELETE_PACKAGE: 'cancel_delete_package',
|
||||
PULL_PACKAGE: 'pull_package',
|
||||
DELETE_PACKAGE_FILE: 'delete_package_file',
|
||||
REQUEST_DELETE_PACKAGE_FILE: 'request_delete_package_file',
|
||||
CANCEL_DELETE_PACKAGE_FILE: 'cancel_delete_package_file',
|
||||
};
|
||||
|
||||
export const TrackingCategories = {
|
||||
[PackageType.MAVEN]: 'MavenPackages',
|
||||
[PackageType.NPM]: 'NpmPackages',
|
||||
[PackageType.CONAN]: 'ConanPackages',
|
||||
};
|
||||
|
||||
export const SHOW_DELETE_SUCCESS_ALERT = 'showSuccessDeleteAlert';
|
||||
export const DELETE_PACKAGE_ERROR_MESSAGE = s__(
|
||||
'PackageRegistry|Something went wrong while deleting the package.',
|
||||
);
|
||||
export const DELETE_PACKAGE_FILE_ERROR_MESSAGE = s__(
|
||||
'PackageRegistry|Something went wrong while deleting the package file.',
|
||||
);
|
||||
export const DELETE_PACKAGE_FILE_SUCCESS_MESSAGE = s__(
|
||||
'PackageRegistry|Package file deleted successfully',
|
||||
);
|
||||
|
||||
export const PACKAGE_ERROR_STATUS = 'error';
|
||||
export const PACKAGE_DEFAULT_STATUS = 'default';
|
||||
export const PACKAGE_HIDDEN_STATUS = 'hidden';
|
||||
export const PACKAGE_PROCESSING_STATUS = 'processing';
|
|
@ -1,43 +0,0 @@
|
|||
import { s__ } from '~/locale';
|
||||
import { PackageType, TrackingCategories } from './constants';
|
||||
|
||||
export const packageTypeToTrackCategory = (type) =>
|
||||
// eslint-disable-next-line @gitlab/require-i18n-strings
|
||||
`UI::${TrackingCategories[type]}`;
|
||||
|
||||
export const beautifyPath = (path) => (path ? path.split('/').join(' / ') : '');
|
||||
|
||||
export const getPackageTypeLabel = (packageType) => {
|
||||
switch (packageType) {
|
||||
case PackageType.CONAN:
|
||||
return s__('PackageRegistry|Conan');
|
||||
case PackageType.MAVEN:
|
||||
return s__('PackageRegistry|Maven');
|
||||
case PackageType.NPM:
|
||||
return s__('PackageRegistry|npm');
|
||||
case PackageType.NUGET:
|
||||
return s__('PackageRegistry|NuGet');
|
||||
case PackageType.PYPI:
|
||||
return s__('PackageRegistry|PyPI');
|
||||
case PackageType.RUBYGEMS:
|
||||
return s__('PackageRegistry|RubyGems');
|
||||
case PackageType.COMPOSER:
|
||||
return s__('PackageRegistry|Composer');
|
||||
case PackageType.GENERIC:
|
||||
return s__('PackageRegistry|Generic');
|
||||
case PackageType.DEBIAN:
|
||||
return s__('PackageRegistry|Debian');
|
||||
case PackageType.HELM:
|
||||
return s__('PackageRegistry|Helm');
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const getCommitLink = ({ project_path: projectPath, pipeline = {} }, isGroup = false) => {
|
||||
if (isGroup) {
|
||||
return `/${projectPath}/commit/${pipeline.sha}`;
|
||||
}
|
||||
|
||||
return `../commit/${pipeline.sha}`;
|
||||
};
|
|
@ -17,9 +17,12 @@ import TerraformTitle from '~/packages_and_registries/infrastructure_registry/de
|
|||
import TerraformInstallation from '~/packages_and_registries/infrastructure_registry/details/components/terraform_installation.vue';
|
||||
import Tracking from '~/tracking';
|
||||
import PackageListRow from '~/packages_and_registries/infrastructure_registry/shared/package_list_row.vue';
|
||||
import PackagesListLoader from '~/packages/shared/components/packages_list_loader.vue';
|
||||
import { TrackingActions, SHOW_DELETE_SUCCESS_ALERT } from '~/packages/shared/constants';
|
||||
import { packageTypeToTrackCategory } from '~/packages/shared/utils';
|
||||
import PackagesListLoader from '~/packages_and_registries/shared/components/packages_list_loader.vue';
|
||||
import {
|
||||
TRACKING_ACTIONS,
|
||||
SHOW_DELETE_SUCCESS_ALERT,
|
||||
} from '~/packages_and_registries/shared/constants';
|
||||
import { TRACK_CATEGORY } from '~/packages_and_registries/infrastructure_registry/shared/constants';
|
||||
import PackageFiles from './package_files.vue';
|
||||
import PackageHistory from './package_history.vue';
|
||||
|
||||
|
@ -44,7 +47,7 @@ export default {
|
|||
GlModal: GlModalDirective,
|
||||
},
|
||||
mixins: [Tracking.mixin()],
|
||||
trackingActions: { ...TrackingActions },
|
||||
trackingActions: { ...TRACKING_ACTIONS },
|
||||
data() {
|
||||
return {
|
||||
fileToDelete: null,
|
||||
|
@ -68,7 +71,7 @@ export default {
|
|||
},
|
||||
tracking() {
|
||||
return {
|
||||
category: packageTypeToTrackCategory(this.packageEntity.package_type),
|
||||
category: TRACK_CATEGORY,
|
||||
};
|
||||
},
|
||||
hasVersions() {
|
||||
|
@ -86,7 +89,7 @@ export default {
|
|||
}
|
||||
},
|
||||
async confirmPackageDeletion() {
|
||||
this.track(TrackingActions.DELETE_PACKAGE);
|
||||
this.track(TRACKING_ACTIONS.DELETE_PACKAGE);
|
||||
await this.deletePackage();
|
||||
const returnTo =
|
||||
!this.groupListUrl || document.referrer.includes(this.projectName)
|
||||
|
@ -96,12 +99,12 @@ export default {
|
|||
window.location.replace(`${returnTo}?${modalQuery}`);
|
||||
},
|
||||
handleFileDelete(file) {
|
||||
this.track(TrackingActions.REQUEST_DELETE_PACKAGE_FILE);
|
||||
this.track(TRACKING_ACTIONS.REQUEST_DELETE_PACKAGE_FILE);
|
||||
this.fileToDelete = { ...file };
|
||||
this.$refs.deleteFileModal.show();
|
||||
},
|
||||
confirmFileDelete() {
|
||||
this.track(TrackingActions.DELETE_PACKAGE_FILE);
|
||||
this.track(TRACKING_ACTIONS.DELETE_PACKAGE_FILE);
|
||||
this.deletePackageFile(this.fileToDelete.id);
|
||||
this.fileToDelete = null;
|
||||
},
|
||||
|
|
|
@ -4,7 +4,7 @@ import {
|
|||
DELETE_PACKAGE_ERROR_MESSAGE,
|
||||
DELETE_PACKAGE_FILE_ERROR_MESSAGE,
|
||||
DELETE_PACKAGE_FILE_SUCCESS_MESSAGE,
|
||||
} from '~/packages/shared/constants';
|
||||
} from '~/packages_and_registries/shared/constants';
|
||||
import { FETCH_PACKAGE_VERSIONS_ERROR } from '../constants';
|
||||
import * as types from './mutation_types';
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@ import { mapState, mapGetters } from 'vuex';
|
|||
import { s__ } from '~/locale';
|
||||
import Tracking from '~/tracking';
|
||||
import PackagesListRow from '~/packages_and_registries/infrastructure_registry/shared/package_list_row.vue';
|
||||
import PackagesListLoader from '~/packages/shared/components/packages_list_loader.vue';
|
||||
import { TrackingActions } from '~/packages/shared/constants';
|
||||
import { packageTypeToTrackCategory } from '~/packages/shared/utils';
|
||||
import PackagesListLoader from '~/packages_and_registries/shared/components/packages_list_loader.vue';
|
||||
import { TRACKING_ACTIONS } from '~/packages_and_registries/shared/constants';
|
||||
import { TRACK_CATEGORY } from '~/packages_and_registries/infrastructure_registry/shared/constants';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -49,27 +49,24 @@ export default {
|
|||
return this.itemToBeDeleted?.name ?? '';
|
||||
},
|
||||
tracking() {
|
||||
const category = this.itemToBeDeleted
|
||||
? packageTypeToTrackCategory(this.itemToBeDeleted.package_type)
|
||||
: undefined;
|
||||
return {
|
||||
category,
|
||||
category: TRACK_CATEGORY,
|
||||
};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
setItemToBeDeleted(item) {
|
||||
this.itemToBeDeleted = { ...item };
|
||||
this.track(TrackingActions.REQUEST_DELETE_PACKAGE);
|
||||
this.track(TRACKING_ACTIONS.REQUEST_DELETE_PACKAGE);
|
||||
this.$refs.packageListDeleteModal.show();
|
||||
},
|
||||
deleteItemConfirmation() {
|
||||
this.$emit('package:delete', this.itemToBeDeleted);
|
||||
this.track(TrackingActions.DELETE_PACKAGE);
|
||||
this.track(TRACKING_ACTIONS.DELETE_PACKAGE);
|
||||
this.itemToBeDeleted = null;
|
||||
},
|
||||
deleteItemCanceled() {
|
||||
this.track(TrackingActions.CANCEL_DELETE_PACKAGE);
|
||||
this.track(TRACKING_ACTIONS.CANCEL_DELETE_PACKAGE);
|
||||
this.itemToBeDeleted = null;
|
||||
},
|
||||
},
|
||||
|
|
|
@ -4,8 +4,11 @@ import { mapActions, mapState } from 'vuex';
|
|||
import createFlash from '~/flash';
|
||||
import { historyReplaceState } from '~/lib/utils/common_utils';
|
||||
import { s__ } from '~/locale';
|
||||
import { SHOW_DELETE_SUCCESS_ALERT } from '~/packages/shared/constants';
|
||||
import { FILTERED_SEARCH_TERM } from '~/packages_and_registries/shared/constants';
|
||||
import {
|
||||
SHOW_DELETE_SUCCESS_ALERT,
|
||||
FILTERED_SEARCH_TERM,
|
||||
} from '~/packages_and_registries/shared/constants';
|
||||
|
||||
import { getQueryParams, extractFilterAndSorting } from '~/packages_and_registries/shared/utils';
|
||||
import InfrastructureTitle from '~/packages_and_registries/infrastructure_registry/list/components/infrastructure_title.vue';
|
||||
import InfrastructureSearch from '~/packages_and_registries/infrastructure_registry/list/components/infrastructure_search.vue';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Api from '~/api';
|
||||
import createFlash from '~/flash';
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
import { DELETE_PACKAGE_ERROR_MESSAGE } from '~/packages/shared/constants';
|
||||
import { DELETE_PACKAGE_ERROR_MESSAGE } from '~/packages_and_registries/shared/constants';
|
||||
import {
|
||||
FETCH_PACKAGES_LIST_ERROR_MESSAGE,
|
||||
DELETE_PACKAGE_SUCCESS_MESSAGE,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { beautifyPath } from '~/packages/shared/utils';
|
||||
import { beautifyPath } from '~/packages_and_registries/shared/utils';
|
||||
import { LIST_KEY_PROJECT } from '../constants';
|
||||
|
||||
export default (state) =>
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export const TRACK_CATEGORY = 'UI::TerraformPackages';
|
|
@ -3,11 +3,13 @@ import { GlButton, GlLink, GlSprintf, GlTooltipDirective, GlTruncate } from '@gi
|
|||
import { s__ } from '~/locale';
|
||||
import ListItem from '~/vue_shared/components/registry/list_item.vue';
|
||||
import timeagoMixin from '~/vue_shared/mixins/timeago';
|
||||
import { PACKAGE_ERROR_STATUS, PACKAGE_DEFAULT_STATUS } from '~/packages/shared/constants';
|
||||
import { getPackageTypeLabel } from '~/packages/shared/utils';
|
||||
import PackagePath from '~/packages/shared/components/package_path.vue';
|
||||
import PackageTags from '~/packages/shared/components/package_tags.vue';
|
||||
import PublishMethod from '~/packages/shared/components/publish_method.vue';
|
||||
import {
|
||||
PACKAGE_ERROR_STATUS,
|
||||
PACKAGE_DEFAULT_STATUS,
|
||||
} from '~/packages_and_registries/shared/constants';
|
||||
import PackagePath from '~/packages_and_registries/shared/components/package_path.vue';
|
||||
import PackageTags from '~/packages_and_registries/shared/components/package_tags.vue';
|
||||
import PublishMethod from '~/packages_and_registries/shared/components/publish_method.vue';
|
||||
import InfrastructureIconAndName from '~/packages_and_registries/infrastructure_registry/shared/infrastructure_icon_and_name.vue';
|
||||
|
||||
export default {
|
||||
|
@ -53,9 +55,6 @@ export default {
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
packageType() {
|
||||
return getPackageTypeLabel(this.packageEntity.package_type);
|
||||
},
|
||||
hasPipeline() {
|
||||
return Boolean(this.packageEntity.pipeline);
|
||||
},
|
||||
|
@ -120,9 +119,7 @@ export default {
|
|||
</gl-sprintf>
|
||||
</div>
|
||||
|
||||
<infrastructure-icon-and-name v-if="showPackageType">
|
||||
{{ packageType }}
|
||||
</infrastructure-icon-and-name>
|
||||
<infrastructure-icon-and-name v-if="showPackageType" />
|
||||
|
||||
<package-path
|
||||
v-if="hasProjectLink"
|
||||
|
|
|
@ -15,7 +15,7 @@ import { convertToGraphQLId } from '~/graphql_shared/utils';
|
|||
import { numberToHumanSize } from '~/lib/utils/number_utils';
|
||||
import { objectToQuery } from '~/lib/utils/url_utility';
|
||||
import { s__, __ } from '~/locale';
|
||||
import { packageTypeToTrackCategory } from '~/packages/shared/utils';
|
||||
import { packageTypeToTrackCategory } from '~/packages_and_registries/package_registry/utils';
|
||||
import AdditionalMetadata from '~/packages_and_registries/package_registry/components/details/additional_metadata.vue';
|
||||
import DependencyRow from '~/packages_and_registries/package_registry/components/details/dependency_row.vue';
|
||||
import InstallationCommands from '~/packages_and_registries/package_registry/components/details/installation_commands.vue';
|
||||
|
|
|
@ -3,7 +3,7 @@ import { GlIcon, GlSprintf, GlBadge, GlResizeObserverDirective } from '@gitlab/u
|
|||
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
|
||||
import { numberToHumanSize } from '~/lib/utils/number_utils';
|
||||
import { __ } from '~/locale';
|
||||
import PackageTags from '~/packages/shared/components/package_tags.vue';
|
||||
import PackageTags from '~/packages_and_registries/shared/components/package_tags.vue';
|
||||
import { PACKAGE_TYPE_NUGET } from '~/packages_and_registries/package_registry/constants';
|
||||
import { getPackageTypeLabel } from '~/packages_and_registries/package_registry/utils';
|
||||
import MetadataItem from '~/vue_shared/components/registry/metadata_item.vue';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<script>
|
||||
import { GlLink, GlSprintf, GlTruncate } from '@gitlab/ui';
|
||||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import PackageTags from '~/packages/shared/components/package_tags.vue';
|
||||
import PublishMethod from '~/packages/shared/components/publish_method.vue';
|
||||
import PackageTags from '~/packages_and_registries/shared/components/package_tags.vue';
|
||||
import PublishMethod from '~/packages_and_registries/shared/components/publish_method.vue';
|
||||
import ListItem from '~/vue_shared/components/registry/list_item.vue';
|
||||
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
import { PACKAGE_DEFAULT_STATUS } from '../../constants';
|
||||
|
|
|
@ -3,7 +3,7 @@ import { GlEmptyState, GlLink, GlSprintf } from '@gitlab/ui';
|
|||
import createFlash from '~/flash';
|
||||
import { historyReplaceState } from '~/lib/utils/common_utils';
|
||||
import { s__ } from '~/locale';
|
||||
import { SHOW_DELETE_SUCCESS_ALERT } from '~/packages/shared/constants';
|
||||
import { SHOW_DELETE_SUCCESS_ALERT } from '~/packages_and_registries/shared/constants';
|
||||
import {
|
||||
PROJECT_RESOURCE_TYPE,
|
||||
GROUP_RESOURCE_TYPE,
|
||||
|
|
|
@ -6,11 +6,11 @@ import {
|
|||
PACKAGE_ERROR_STATUS,
|
||||
PACKAGE_DEFAULT_STATUS,
|
||||
} from '~/packages_and_registries/package_registry/constants';
|
||||
import { getPackageTypeLabel } from '~/packages/shared/utils';
|
||||
import PackagePath from '~/packages/shared/components/package_path.vue';
|
||||
import PackageTags from '~/packages/shared/components/package_tags.vue';
|
||||
import { getPackageTypeLabel } from '~/packages_and_registries/package_registry/utils';
|
||||
import PackagePath from '~/packages_and_registries/shared/components/package_path.vue';
|
||||
import PackageTags from '~/packages_and_registries/shared/components/package_tags.vue';
|
||||
import PublishMethod from '~/packages_and_registries/package_registry/components/list/publish_method.vue';
|
||||
import PackageIconAndName from '~/packages/shared/components/package_icon_and_name.vue';
|
||||
import PackageIconAndName from '~/packages_and_registries/shared/components/package_icon_and_name.vue';
|
||||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
|
||||
|
@ -40,7 +40,7 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
packageType() {
|
||||
return getPackageTypeLabel(this.packageEntity.packageType.toLowerCase());
|
||||
return getPackageTypeLabel(this.packageEntity.packageType);
|
||||
},
|
||||
packageLink() {
|
||||
const { project, id } = this.packageEntity;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { GlModal, GlSprintf, GlKeysetPagination } from '@gitlab/ui';
|
||||
import { s__ } from '~/locale';
|
||||
import PackagesListRow from '~/packages_and_registries/package_registry/components/list/package_list_row.vue';
|
||||
import PackagesListLoader from '~/packages/shared/components/packages_list_loader.vue';
|
||||
import PackagesListLoader from '~/packages_and_registries/shared/components/packages_list_loader.vue';
|
||||
import {
|
||||
DELETE_PACKAGE_TRACKING_ACTION,
|
||||
REQUEST_DELETE_PACKAGE_TRACKING_ACTION,
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
import { s__, __ } from '~/locale';
|
||||
|
||||
export {
|
||||
DELETE_PACKAGE_TRACKING_ACTION,
|
||||
REQUEST_DELETE_PACKAGE_TRACKING_ACTION,
|
||||
CANCEL_DELETE_PACKAGE_TRACKING_ACTION,
|
||||
PULL_PACKAGE_TRACKING_ACTION,
|
||||
DELETE_PACKAGE_FILE_TRACKING_ACTION,
|
||||
REQUEST_DELETE_PACKAGE_FILE_TRACKING_ACTION,
|
||||
CANCEL_DELETE_PACKAGE_FILE_TRACKING_ACTION,
|
||||
} from '~/packages_and_registries/shared/constants';
|
||||
|
||||
export const PACKAGE_TYPE_CONAN = 'CONAN';
|
||||
export const PACKAGE_TYPE_MAVEN = 'MAVEN';
|
||||
export const PACKAGE_TYPE_NPM = 'NPM';
|
||||
|
@ -11,14 +21,6 @@ export const PACKAGE_TYPE_GENERIC = 'GENERIC';
|
|||
export const PACKAGE_TYPE_DEBIAN = 'DEBIAN';
|
||||
export const PACKAGE_TYPE_HELM = 'HELM';
|
||||
|
||||
export const DELETE_PACKAGE_TRACKING_ACTION = 'delete_package';
|
||||
export const REQUEST_DELETE_PACKAGE_TRACKING_ACTION = 'request_delete_package';
|
||||
export const CANCEL_DELETE_PACKAGE_TRACKING_ACTION = 'cancel_delete_package';
|
||||
export const PULL_PACKAGE_TRACKING_ACTION = 'pull_package';
|
||||
export const DELETE_PACKAGE_FILE_TRACKING_ACTION = 'delete_package_file';
|
||||
export const REQUEST_DELETE_PACKAGE_FILE_TRACKING_ACTION = 'request_delete_package_file';
|
||||
export const CANCEL_DELETE_PACKAGE_FILE_TRACKING_ACTION = 'cancel_delete_package_file';
|
||||
|
||||
export const TRACKING_LABEL_CODE_INSTRUCTION = 'code_instruction';
|
||||
export const TRACKING_LABEL_CONAN_INSTALLATION = 'conan_installation';
|
||||
export const TRACKING_LABEL_MAVEN_INSTALLATION = 'maven_installation';
|
||||
|
|
|
@ -1,3 +1,39 @@
|
|||
import { s__ } from '~/locale';
|
||||
|
||||
export const FILTERED_SEARCH_TERM = 'filtered-search-term';
|
||||
export const FILTERED_SEARCH_TYPE = 'type';
|
||||
export const HISTORY_PIPELINES_LIMIT = 5;
|
||||
|
||||
export const DELETE_PACKAGE_TRACKING_ACTION = 'delete_package';
|
||||
export const REQUEST_DELETE_PACKAGE_TRACKING_ACTION = 'request_delete_package';
|
||||
export const CANCEL_DELETE_PACKAGE_TRACKING_ACTION = 'cancel_delete_package';
|
||||
export const PULL_PACKAGE_TRACKING_ACTION = 'pull_package';
|
||||
export const DELETE_PACKAGE_FILE_TRACKING_ACTION = 'delete_package_file';
|
||||
export const REQUEST_DELETE_PACKAGE_FILE_TRACKING_ACTION = 'request_delete_package_file';
|
||||
export const CANCEL_DELETE_PACKAGE_FILE_TRACKING_ACTION = 'cancel_delete_package_file';
|
||||
|
||||
export const TRACKING_ACTIONS = {
|
||||
DELETE_PACKAGE: DELETE_PACKAGE_TRACKING_ACTION,
|
||||
REQUEST_DELETE_PACKAGE: REQUEST_DELETE_PACKAGE_TRACKING_ACTION,
|
||||
CANCEL_DELETE_PACKAGE: CANCEL_DELETE_PACKAGE_TRACKING_ACTION,
|
||||
PULL_PACKAGE: PULL_PACKAGE_TRACKING_ACTION,
|
||||
DELETE_PACKAGE_FILE: DELETE_PACKAGE_FILE_TRACKING_ACTION,
|
||||
REQUEST_DELETE_PACKAGE_FILE: REQUEST_DELETE_PACKAGE_FILE_TRACKING_ACTION,
|
||||
CANCEL_DELETE_PACKAGE_FILE: CANCEL_DELETE_PACKAGE_FILE_TRACKING_ACTION,
|
||||
};
|
||||
|
||||
export const SHOW_DELETE_SUCCESS_ALERT = 'showSuccessDeleteAlert';
|
||||
export const DELETE_PACKAGE_ERROR_MESSAGE = s__(
|
||||
'PackageRegistry|Something went wrong while deleting the package.',
|
||||
);
|
||||
export const DELETE_PACKAGE_FILE_ERROR_MESSAGE = s__(
|
||||
'PackageRegistry|Something went wrong while deleting the package file.',
|
||||
);
|
||||
export const DELETE_PACKAGE_FILE_SUCCESS_MESSAGE = s__(
|
||||
'PackageRegistry|Package file deleted successfully',
|
||||
);
|
||||
|
||||
export const PACKAGE_ERROR_STATUS = 'error';
|
||||
export const PACKAGE_DEFAULT_STATUS = 'default';
|
||||
export const PACKAGE_HIDDEN_STATUS = 'hidden';
|
||||
export const PACKAGE_PROCESSING_STATUS = 'processing';
|
||||
|
|
|
@ -28,3 +28,13 @@ export const extractFilterAndSorting = (queryObject) => {
|
|||
}
|
||||
return { filters, sorting };
|
||||
};
|
||||
|
||||
export const beautifyPath = (path) => (path ? path.split('/').join(' / ') : '');
|
||||
|
||||
export const getCommitLink = ({ project_path: projectPath, pipeline = {} }, isGroup = false) => {
|
||||
if (isGroup) {
|
||||
return `/${projectPath}/commit/${pipeline.sha}`;
|
||||
}
|
||||
|
||||
return `../commit/${pipeline.sha}`;
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script>
|
||||
import produce from 'immer';
|
||||
import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import { IssuableType } from '~/issues/show/constants';
|
||||
import { IssuableType } from '~/issues/constants';
|
||||
import { assigneesQueries } from '~/sidebar/constants';
|
||||
|
||||
export default {
|
||||
|
|
|
@ -3,7 +3,7 @@ import { GlDropdownItem } from '@gitlab/ui';
|
|||
import { cloneDeep } from 'lodash';
|
||||
import Vue from 'vue';
|
||||
import createFlash from '~/flash';
|
||||
import { IssuableType } from '~/issues/show/constants';
|
||||
import { IssuableType } from '~/issues/constants';
|
||||
import { __, n__ } from '~/locale';
|
||||
import SidebarAssigneesRealtime from '~/sidebar/components/assignees/assignees_realtime.vue';
|
||||
import IssuableAssignees from '~/sidebar/components/assignees/issuable_assignees.vue';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import { IssuableType } from '~/issues/show/constants';
|
||||
import { IssuableType } from '~/issues/constants';
|
||||
import { __, sprintf } from '~/locale';
|
||||
import AttentionRequestedToggle from '../attention_requested_toggle.vue';
|
||||
import AssigneeAvatarLink from './assignee_avatar_link.vue';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script>
|
||||
import { GlSprintf, GlButton } from '@gitlab/ui';
|
||||
import createFlash from '~/flash';
|
||||
import { IssuableType } from '~/issues/show/constants';
|
||||
import { IssuableType } from '~/issues/constants';
|
||||
import { __, sprintf } from '~/locale';
|
||||
import { confidentialityQueries } from '~/sidebar/constants';
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script>
|
||||
import { GlIcon, GlDatepicker, GlTooltipDirective, GlLink, GlPopover } from '@gitlab/ui';
|
||||
import createFlash from '~/flash';
|
||||
import { IssuableType } from '~/issues/show/constants';
|
||||
import { IssuableType } from '~/issues/constants';
|
||||
import { dateInWords, formatDate, parsePikadayDate } from '~/lib/utils/datetime_utility';
|
||||
import { __, sprintf } from '~/locale';
|
||||
import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue';
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
} from '@gitlab/ui';
|
||||
import createFlash from '~/flash';
|
||||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import { IssuableType } from '~/issues/show/constants';
|
||||
import { IssuableType } from '~/issues/constants';
|
||||
import { timeFor } from '~/lib/utils/datetime_utility';
|
||||
import { __ } from '~/locale';
|
||||
import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script>
|
||||
import { GlIcon, GlLoadingIcon, GlToggle, GlTooltipDirective } from '@gitlab/ui';
|
||||
import createFlash from '~/flash';
|
||||
import { IssuableType } from '~/issues/show/constants';
|
||||
import { IssuableType } from '~/issues/constants';
|
||||
import { isLoggedIn } from '~/lib/utils/common_utils';
|
||||
import { __, sprintf } from '~/locale';
|
||||
import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import { GlIcon, GlLink, GlModal, GlModalDirective, GlLoadingIcon } from '@gitlab/ui';
|
||||
import { IssuableType } from '~/issues/show/constants';
|
||||
import { IssuableType } from '~/issues/constants';
|
||||
import { s__, __ } from '~/locale';
|
||||
import { timeTrackingQueries } from '~/sidebar/constants';
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { s__, sprintf } from '~/locale';
|
||||
import updateIssueLabelsMutation from '~/boards/graphql/issue_set_labels.mutation.graphql';
|
||||
import { IssuableType, WorkspaceType } from '~/issues/show/constants';
|
||||
import { IssuableType, WorkspaceType } from '~/issues/constants';
|
||||
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
|
||||
import epicConfidentialQuery from '~/sidebar/queries/epic_confidential.query.graphql';
|
||||
import epicDueDateQuery from '~/sidebar/queries/epic_due_date.query.graphql';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import Vue from 'vue';
|
||||
import { IssuableType } from '~/issues/show/constants';
|
||||
import { IssuableType } from '~/issues/constants';
|
||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
||||
import timeTracker from './components/time_tracking/time_tracker.vue';
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import { TYPE_ISSUE, TYPE_MERGE_REQUEST } from '~/graphql_shared/constants';
|
|||
import { convertToGraphQLId } from '~/graphql_shared/utils';
|
||||
import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
|
||||
import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
|
||||
import { IssuableType } from '~/issues/show/constants';
|
||||
import { IssuableType } from '~/issues/constants';
|
||||
import {
|
||||
isInIssuePage,
|
||||
isInDesignPage,
|
||||
|
|
|
@ -39,6 +39,11 @@ export default {
|
|||
required: false,
|
||||
default: null,
|
||||
},
|
||||
isOverviewTab: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['getUserData']),
|
||||
|
@ -46,9 +51,10 @@ export default {
|
|||
return renderMarkdown(this.note.body);
|
||||
},
|
||||
avatarSize() {
|
||||
if (this.line) {
|
||||
return 16;
|
||||
if (this.line && !this.isOverviewTab) {
|
||||
return 24;
|
||||
}
|
||||
|
||||
return 40;
|
||||
},
|
||||
},
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { debounce } from 'lodash';
|
||||
import { MutationOperationMode, getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import createFlash from '~/flash';
|
||||
import { IssuableType } from '~/issues/show/constants';
|
||||
import { IssuableType } from '~/issues/constants';
|
||||
import { __ } from '~/locale';
|
||||
import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue';
|
||||
import { issuableLabelsQueries } from '~/sidebar/constants';
|
||||
|
|
|
@ -166,6 +166,8 @@ export default {
|
|||
class="issue gl-display-flex! gl-px-5!"
|
||||
:class="{ closed: issuable.closedAt, today: createdInPastDay }"
|
||||
:data-labels="labelIdsString"
|
||||
data-qa-selector="issuable_item_container"
|
||||
:data-qa-issue-id="issuableId"
|
||||
>
|
||||
<gl-form-checkbox
|
||||
v-if="showCheckbox"
|
||||
|
|
|
@ -100,7 +100,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="issuable-show-container">
|
||||
<div class="issuable-show-container" data-qa-selector="issuable_show_container">
|
||||
<issuable-header
|
||||
:status-badge-class="statusBadgeClass"
|
||||
:status-icon="statusIcon"
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#import './widget.fragment.graphql'
|
||||
|
||||
mutation createWorkItem($input: CreateWorkItemInput) {
|
||||
createWorkItem(input: $input) @client {
|
||||
mutation createWorkItem($input: LocalCreateWorkItemInput) {
|
||||
localCreateWorkItem(input: $input) @client {
|
||||
workItem {
|
||||
id
|
||||
type
|
||||
widgets {
|
||||
nodes {
|
||||
...WidgetBase
|
||||
... on TitleWidget {
|
||||
... on LocalTitleWidget {
|
||||
contentText
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"__schema":{"types":[{"kind":"INTERFACE","name":"WorkItemWidget","possibleTypes":[{"name":"TitleWidget"}]}]}}
|
||||
{"__schema":{"types":[{"kind":"INTERFACE","name":"LocalWorkItemWidget","possibleTypes":[{"name":"LocalTitleWidget"}]}]}}
|
||||
|
|
|
@ -28,14 +28,14 @@ export function createApolloProvider() {
|
|||
},
|
||||
data: {
|
||||
workItem: {
|
||||
__typename: 'WorkItem',
|
||||
__typename: 'LocalWorkItem',
|
||||
id: '1',
|
||||
type: 'FEATURE',
|
||||
widgets: {
|
||||
__typename: 'WorkItemWidgetConnection',
|
||||
__typename: 'LocalWorkItemWidgetConnection',
|
||||
nodes: [
|
||||
{
|
||||
__typename: 'TitleWidget',
|
||||
__typename: 'LocalTitleWidget',
|
||||
type: 'TITLE',
|
||||
enabled: true,
|
||||
// eslint-disable-next-line @gitlab/require-i18n-strings
|
||||
|
|
|
@ -3,17 +3,17 @@ import workItemQuery from './work_item.query.graphql';
|
|||
|
||||
export const resolvers = {
|
||||
Mutation: {
|
||||
createWorkItem(_, { input }, { cache }) {
|
||||
localCreateWorkItem(_, { input }, { cache }) {
|
||||
const id = uuids()[0];
|
||||
const workItem = {
|
||||
__typename: 'WorkItem',
|
||||
__typename: 'LocalWorkItem',
|
||||
type: 'FEATURE',
|
||||
id,
|
||||
widgets: {
|
||||
__typename: 'WorkItemWidgetConnection',
|
||||
__typename: 'LocalWorkItemWidgetConnection',
|
||||
nodes: [
|
||||
{
|
||||
__typename: 'TitleWidget',
|
||||
__typename: 'LocalTitleWidget',
|
||||
type: 'TITLE',
|
||||
enabled: true,
|
||||
contentText: input.title,
|
||||
|
@ -25,24 +25,24 @@ export const resolvers = {
|
|||
cache.writeQuery({ query: workItemQuery, variables: { id }, data: { workItem } });
|
||||
|
||||
return {
|
||||
__typename: 'CreateWorkItemPayload',
|
||||
__typename: 'LocalCreateWorkItemPayload',
|
||||
workItem,
|
||||
};
|
||||
},
|
||||
|
||||
updateWorkItem(_, { input }, { cache }) {
|
||||
localUpdateWorkItem(_, { input }, { cache }) {
|
||||
const workItemTitle = {
|
||||
__typename: 'TitleWidget',
|
||||
__typename: 'LocalTitleWidget',
|
||||
type: 'TITLE',
|
||||
enabled: true,
|
||||
contentText: input.title,
|
||||
};
|
||||
const workItem = {
|
||||
__typename: 'WorkItem',
|
||||
__typename: 'LocalWorkItem',
|
||||
type: 'FEATURE',
|
||||
id: input.id,
|
||||
widgets: {
|
||||
__typename: 'WorkItemWidgetConnection',
|
||||
__typename: 'LocalWorkItemWidgetConnection',
|
||||
nodes: [workItemTitle],
|
||||
},
|
||||
};
|
||||
|
@ -50,7 +50,7 @@ export const resolvers = {
|
|||
cache.writeQuery({ query: workItemQuery, variables: { id: input.id }, data: { workItem } });
|
||||
|
||||
return {
|
||||
__typename: 'UpdateWorkItemPayload',
|
||||
__typename: 'LocalUpdateWorkItemPayload',
|
||||
workItem,
|
||||
};
|
||||
},
|
||||
|
|
|
@ -1,60 +1,60 @@
|
|||
enum WorkItemType {
|
||||
enum LocalWorkItemType {
|
||||
FEATURE
|
||||
}
|
||||
|
||||
enum WidgetType {
|
||||
enum LocalWidgetType {
|
||||
TITLE
|
||||
}
|
||||
|
||||
interface WorkItemWidget {
|
||||
type: WidgetType!
|
||||
interface LocalWorkItemWidget {
|
||||
type: LocalWidgetType!
|
||||
}
|
||||
|
||||
# Replicating Relay connection type for client schema
|
||||
type WorkItemWidgetEdge {
|
||||
type LocalWorkItemWidgetEdge {
|
||||
cursor: String!
|
||||
node: WorkItemWidget
|
||||
node: LocalWorkItemWidget
|
||||
}
|
||||
|
||||
type WorkItemWidgetConnection {
|
||||
edges: [WorkItemWidgetEdge]
|
||||
nodes: [WorkItemWidget]
|
||||
type LocalWorkItemWidgetConnection {
|
||||
edges: [LocalWorkItemWidgetEdge]
|
||||
nodes: [LocalWorkItemWidget]
|
||||
pageInfo: PageInfo!
|
||||
}
|
||||
|
||||
type TitleWidget implements WorkItemWidget {
|
||||
type: WidgetType!
|
||||
type LocalTitleWidget implements LocalWorkItemWidget {
|
||||
type: LocalWidgetType!
|
||||
contentText: String!
|
||||
}
|
||||
|
||||
type WorkItem {
|
||||
type LocalWorkItem {
|
||||
id: ID!
|
||||
type: WorkItemType!
|
||||
widgets: [WorkItemWidgetConnection]
|
||||
type: LocalWorkItemType!
|
||||
widgets: [LocalWorkItemWidgetConnection]
|
||||
}
|
||||
|
||||
type CreateWorkItemInput {
|
||||
type LocalCreateWorkItemInput {
|
||||
title: String!
|
||||
}
|
||||
|
||||
type UpdateWorkItemInput {
|
||||
type LocalUpdateWorkItemInput {
|
||||
id: ID!
|
||||
title: String
|
||||
}
|
||||
|
||||
type CreateWorkItemPayload {
|
||||
workItem: WorkItem!
|
||||
type LocalCreateWorkItemPayload {
|
||||
workItem: LocalWorkItem!
|
||||
}
|
||||
|
||||
type UpdateWorkItemPayload {
|
||||
workItem: WorkItem!
|
||||
type LocalUpdateWorkItemPayload {
|
||||
workItem: LocalWorkItem!
|
||||
}
|
||||
|
||||
extend type Query {
|
||||
workItem(id: ID!): WorkItem!
|
||||
workItem(id: ID!): LocalWorkItem!
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
createWorkItem(input: CreateWorkItemInput!): CreateWorkItemPayload!
|
||||
updateWorkItem(input: UpdateWorkItemInput!): UpdateWorkItemPayload!
|
||||
localCreateWorkItem(input: LocalCreateWorkItemInput!): LocalCreateWorkItemPayload!
|
||||
localUpdateWorkItem(input: LocalUpdateWorkItemInput!): LocalUpdateWorkItemPayload!
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#import './widget.fragment.graphql'
|
||||
|
||||
mutation updateWorkItem($input: UpdateWorkItemInput) {
|
||||
updateWorkItem(input: $input) @client {
|
||||
mutation updateWorkItem($input: LocalUpdateWorkItemInput) {
|
||||
localUpdateWorkItem(input: $input) @client {
|
||||
workItem {
|
||||
id
|
||||
type
|
||||
widgets {
|
||||
nodes {
|
||||
...WidgetBase
|
||||
... on TitleWidget {
|
||||
... on LocalTitleWidget {
|
||||
contentText
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
fragment WidgetBase on WorkItemWidget {
|
||||
fragment WidgetBase on LocalWorkItemWidget {
|
||||
type
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ query WorkItem($id: ID!) {
|
|||
widgets {
|
||||
nodes {
|
||||
...WidgetBase
|
||||
... on TitleWidget {
|
||||
... on LocalTitleWidget {
|
||||
contentText
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ export default {
|
|||
|
||||
const {
|
||||
data: {
|
||||
createWorkItem: {
|
||||
localCreateWorkItem: {
|
||||
workItem: { id },
|
||||
},
|
||||
},
|
||||
|
@ -60,11 +60,10 @@ export default {
|
|||
class="gl-mr-3"
|
||||
data-testid="create-button"
|
||||
type="submit"
|
||||
@click="createWorkItem"
|
||||
>
|
||||
{{ __('Create') }}
|
||||
</gl-button>
|
||||
<gl-button data-testid="cancel-button" @click="$router.go(-1)">
|
||||
<gl-button type="button" data-testid="cancel-button" @click="$router.go(-1)">
|
||||
{{ __('Cancel') }}
|
||||
</gl-button>
|
||||
</div>
|
||||
|
|
|
@ -94,7 +94,8 @@ $dark-il: #de935f;
|
|||
}
|
||||
|
||||
.line-numbers,
|
||||
.diff-line-num {
|
||||
.diff-line-num,
|
||||
.code-search-line {
|
||||
background-color: $dark-main-bg;
|
||||
}
|
||||
|
||||
|
@ -168,7 +169,8 @@ $dark-il: #de935f;
|
|||
}
|
||||
|
||||
.diff-grid-left:hover,
|
||||
.diff-grid-right:hover {
|
||||
.diff-grid-right:hover,
|
||||
&.code-search-line:hover {
|
||||
.diff-line-num:not(.empty-cell) {
|
||||
@include line-number-hover;
|
||||
}
|
||||
|
|
|
@ -95,7 +95,8 @@ $monokai-gh: #75715e;
|
|||
}
|
||||
|
||||
.line-numbers,
|
||||
.diff-line-num {
|
||||
.diff-line-num,
|
||||
.code-search-line {
|
||||
background-color: $monokai-bg;
|
||||
}
|
||||
|
||||
|
@ -169,7 +170,8 @@ $monokai-gh: #75715e;
|
|||
}
|
||||
|
||||
.diff-grid-left:hover,
|
||||
.diff-grid-right:hover {
|
||||
.diff-grid-right:hover,
|
||||
&.code-search-line:hover {
|
||||
.diff-line-num:not(.empty-cell) {
|
||||
@include line-number-hover;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
}
|
||||
|
||||
.line-numbers,
|
||||
.diff-line-num {
|
||||
.diff-line-num,
|
||||
.code-search-line {
|
||||
background-color: $gray-light;
|
||||
}
|
||||
|
||||
|
@ -66,7 +67,8 @@
|
|||
}
|
||||
|
||||
.diff-grid-left:hover,
|
||||
.diff-grid-right:hover {
|
||||
.diff-grid-right:hover,
|
||||
&.code-search-line:hover {
|
||||
.diff-line-num:not(.empty-cell) {
|
||||
@include line-number-hover;
|
||||
}
|
||||
|
|
|
@ -98,7 +98,8 @@ $solarized-dark-il: #2aa198;
|
|||
}
|
||||
|
||||
.line-numbers,
|
||||
.diff-line-num {
|
||||
.diff-line-num,
|
||||
.code-search-line {
|
||||
background-color: $solarized-dark-line-bg;
|
||||
}
|
||||
|
||||
|
@ -148,7 +149,8 @@ $solarized-dark-il: #2aa198;
|
|||
}
|
||||
|
||||
.diff-grid-left:hover,
|
||||
.diff-grid-right:hover {
|
||||
.diff-grid-right:hover,
|
||||
&.code-search-line:hover {
|
||||
.diff-line-num:not(.empty-cell) {
|
||||
@include line-number-hover;
|
||||
}
|
||||
|
|
|
@ -105,7 +105,8 @@ $solarized-light-il: #2aa198;
|
|||
}
|
||||
|
||||
.line-numbers,
|
||||
.diff-line-num {
|
||||
.diff-line-num,
|
||||
.code-search-line {
|
||||
background-color: $solarized-light-line-bg;
|
||||
}
|
||||
|
||||
|
@ -168,7 +169,8 @@ $solarized-light-il: #2aa198;
|
|||
}
|
||||
|
||||
.diff-grid-left:hover,
|
||||
.diff-grid-right:hover {
|
||||
.diff-grid-right:hover,
|
||||
&.code-search-line:hover {
|
||||
.diff-line-num:not(.empty-cell) {
|
||||
@include line-number-hover;
|
||||
}
|
||||
|
|
|
@ -82,7 +82,8 @@ $white-gc-bg: #eaf2f5;
|
|||
}
|
||||
|
||||
.line-numbers,
|
||||
.diff-line-num {
|
||||
.diff-line-num,
|
||||
.code-search-line {
|
||||
background-color: $gray-light;
|
||||
|
||||
&.conflict_marker,
|
||||
|
@ -128,7 +129,8 @@ pre.code,
|
|||
}
|
||||
|
||||
.diff-grid-left:hover,
|
||||
.diff-grid-right:hover {
|
||||
.diff-grid-right:hover,
|
||||
&.code-search-line:hover {
|
||||
.diff-line-num:not(.empty-cell):not(.conflict_marker_their):not(.conflict_marker_our) {
|
||||
@include line-number-hover;
|
||||
}
|
||||
|
|
|
@ -321,6 +321,51 @@ input[type='checkbox']:hover {
|
|||
}
|
||||
}
|
||||
|
||||
// This overrides parts of the Project File View CSS
|
||||
// We leverage most of the styling but broke off
|
||||
// from how we were doing it in `shared/file_highlight`
|
||||
#search-blob-content {
|
||||
.line_holder {
|
||||
pre {
|
||||
padding: 0; // This overrides the existing style that will add space between each line.
|
||||
}
|
||||
|
||||
svg {
|
||||
float: none; // We have more than one icon on this implementation and don't want to float them.
|
||||
margin: 0; // We will manage the margin with GitLab UI utility classes
|
||||
}
|
||||
|
||||
.line-numbers {
|
||||
padding: 0; // This overrides the existing style that will add space between each line.
|
||||
min-width: 6.5rem; // Ensure our numbers fit
|
||||
|
||||
.diff-line-num {
|
||||
a {
|
||||
transition: none; // There will be a hover transition from theme, blue, darkened
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
svg {
|
||||
visibility: visible; // We want to show the icons when the any part of the line is hovered
|
||||
}
|
||||
}
|
||||
|
||||
// The icons only appear on hover
|
||||
// So on mobile we can hide them and retake the space for the code blob
|
||||
@include media-breakpoint-down(sm) {
|
||||
svg {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.line-numbers {
|
||||
min-width: 4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable webkit input icons, link to solution: https://stackoverflow.com/questions/9421551/how-do-i-remove-all-default-webkit-search-field-styling
|
||||
/* stylelint-disable property-no-vendor-prefix */
|
||||
input[type='search']::-webkit-search-decoration,
|
||||
|
|
|
@ -50,6 +50,8 @@ class GraphqlController < ApplicationController
|
|||
end
|
||||
|
||||
rescue_from StandardError do |exception|
|
||||
@exception_object = exception
|
||||
|
||||
log_exception(exception)
|
||||
|
||||
if Rails.env.test? || Rails.env.development?
|
||||
|
@ -197,7 +199,9 @@ class GraphqlController < ApplicationController
|
|||
|
||||
# Merging to :metadata will ensure these are logged as top level keys
|
||||
payload[:metadata] ||= {}
|
||||
payload[:metadata].merge!(graphql: logs)
|
||||
payload[:metadata][:graphql] = logs
|
||||
|
||||
payload[:exception_object] = @exception_object if @exception_object
|
||||
end
|
||||
|
||||
def logs
|
||||
|
|
|
@ -4,13 +4,13 @@ module Resolvers
|
|||
class BaseIssuesResolver < BaseResolver
|
||||
prepend IssueResolverArguments
|
||||
|
||||
argument :state, Types::IssuableStateEnum,
|
||||
required: false,
|
||||
description: 'Current state of this issue.'
|
||||
argument :sort, Types::IssueSortEnum,
|
||||
description: 'Sort issues by this criteria.',
|
||||
required: false,
|
||||
default_value: :created_desc
|
||||
argument :state, Types::IssuableStateEnum,
|
||||
required: false,
|
||||
description: 'Current state of this issue.'
|
||||
|
||||
type Types::IssueType.connection_type, null: true
|
||||
|
||||
|
|
|
@ -8,16 +8,16 @@ module Resolvers
|
|||
|
||||
type ::Types::DesignManagement::DesignType.connection_type, null: true
|
||||
|
||||
argument :ids, [DesignID],
|
||||
required: false,
|
||||
description: 'Filters designs by their ID.'
|
||||
argument :filenames, [GraphQL::Types::String],
|
||||
required: false,
|
||||
description: 'Filters designs by their filename.'
|
||||
argument :at_version, VersionID,
|
||||
required: false,
|
||||
description: 'Filters designs to only those that existed at the version. ' \
|
||||
'If argument is omitted or nil then all designs will reflect the latest version'
|
||||
argument :filenames, [GraphQL::Types::String],
|
||||
required: false,
|
||||
description: 'Filters designs by their filename.'
|
||||
argument :ids, [DesignID],
|
||||
required: false,
|
||||
description: 'Filters designs by their ID.'
|
||||
|
||||
def self.single
|
||||
::Resolvers::DesignManagement::DesignResolver
|
||||
|
|
|
@ -16,16 +16,16 @@ module Resolvers
|
|||
|
||||
authorize :read_design
|
||||
|
||||
argument :id, DesignAtVersionID,
|
||||
required: false,
|
||||
as: :design_at_version_id,
|
||||
description: 'ID of the DesignAtVersion.'
|
||||
argument :design_id, DesignID,
|
||||
required: false,
|
||||
description: 'ID of a specific design.'
|
||||
argument :filename, GraphQL::Types::String,
|
||||
required: false,
|
||||
description: 'Filename of a specific design.'
|
||||
argument :id, DesignAtVersionID,
|
||||
required: false,
|
||||
as: :design_at_version_id,
|
||||
description: 'ID of the DesignAtVersion.'
|
||||
|
||||
def self.single
|
||||
self
|
||||
|
|
|
@ -18,6 +18,6 @@ module X509Helper
|
|||
end
|
||||
|
||||
def x509_signature?(sig)
|
||||
sig.is_a?(X509CommitSignature) || sig.is_a?(Gitlab::X509::Signature)
|
||||
sig.is_a?(CommitSignatures::X509CommitSignature) || sig.is_a?(Gitlab::X509::Signature)
|
||||
end
|
||||
end
|
||||
|
|
53
app/models/commit_signatures/gpg_signature.rb
Normal file
53
app/models/commit_signatures/gpg_signature.rb
Normal file
|
@ -0,0 +1,53 @@
|
|||
# frozen_string_literal: true
|
||||
module CommitSignatures
|
||||
class GpgSignature < ApplicationRecord
|
||||
include CommitSignature
|
||||
|
||||
sha_attribute :gpg_key_primary_keyid
|
||||
|
||||
belongs_to :gpg_key
|
||||
belongs_to :gpg_key_subkey
|
||||
|
||||
validates :gpg_key_primary_keyid, presence: true
|
||||
|
||||
def self.with_key_and_subkeys(gpg_key)
|
||||
subkey_ids = gpg_key.subkeys.pluck(:id)
|
||||
|
||||
where(
|
||||
arel_table[:gpg_key_id].eq(gpg_key.id).or(
|
||||
arel_table[:gpg_key_subkey_id].in(subkey_ids)
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def gpg_key=(model)
|
||||
case model
|
||||
when GpgKey
|
||||
super
|
||||
when GpgKeySubkey
|
||||
self.gpg_key_subkey = model
|
||||
when NilClass
|
||||
super
|
||||
self.gpg_key_subkey = nil
|
||||
end
|
||||
end
|
||||
|
||||
def gpg_key
|
||||
if gpg_key_id
|
||||
super
|
||||
elsif gpg_key_subkey_id
|
||||
gpg_key_subkey
|
||||
end
|
||||
end
|
||||
|
||||
def gpg_key_primary_keyid
|
||||
super&.upcase
|
||||
end
|
||||
|
||||
def gpg_commit
|
||||
return unless commit
|
||||
|
||||
Gitlab::Gpg::Commit.new(commit)
|
||||
end
|
||||
end
|
||||
end
|
16
app/models/commit_signatures/x509_commit_signature.rb
Normal file
16
app/models/commit_signatures/x509_commit_signature.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
module CommitSignatures
|
||||
class X509CommitSignature < ApplicationRecord
|
||||
include CommitSignature
|
||||
|
||||
belongs_to :x509_certificate, class_name: 'X509Certificate', foreign_key: 'x509_certificate_id', optional: false
|
||||
|
||||
validates :x509_certificate_id, presence: true
|
||||
|
||||
def x509_commit
|
||||
return unless commit
|
||||
|
||||
Gitlab::X509::Commit.new(commit)
|
||||
end
|
||||
end
|
||||
end
|
50
app/models/concerns/commit_signature.rb
Normal file
50
app/models/concerns/commit_signature.rb
Normal file
|
@ -0,0 +1,50 @@
|
|||
# frozen_string_literal: true
|
||||
module CommitSignature
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
include ShaAttribute
|
||||
|
||||
sha_attribute :commit_sha
|
||||
|
||||
enum verification_status: {
|
||||
unverified: 0,
|
||||
verified: 1,
|
||||
same_user_different_email: 2,
|
||||
other_user: 3,
|
||||
unverified_key: 4,
|
||||
unknown_key: 5,
|
||||
multiple_signatures: 6
|
||||
}
|
||||
|
||||
belongs_to :project, class_name: 'Project', foreign_key: 'project_id', optional: false
|
||||
|
||||
validates :commit_sha, presence: true
|
||||
validates :project_id, presence: true
|
||||
|
||||
scope :by_commit_sha, ->(shas) { where(commit_sha: shas) }
|
||||
end
|
||||
|
||||
class_methods do
|
||||
def safe_create!(attributes)
|
||||
create_with(attributes)
|
||||
.safe_find_or_create_by!(commit_sha: attributes[:commit_sha])
|
||||
end
|
||||
|
||||
# Find commits that are lacking a signature in the database at present
|
||||
def unsigned_commit_shas(commit_shas)
|
||||
return [] if commit_shas.empty?
|
||||
|
||||
signed = by_commit_sha(commit_shas).pluck(:commit_sha)
|
||||
commit_shas - signed
|
||||
end
|
||||
end
|
||||
|
||||
def commit
|
||||
project.commit(commit_sha)
|
||||
end
|
||||
|
||||
def user
|
||||
commit.committer
|
||||
end
|
||||
end
|
|
@ -92,13 +92,13 @@ class GpgKey < ApplicationRecord
|
|||
end
|
||||
|
||||
def revoke
|
||||
GpgSignature
|
||||
CommitSignatures::GpgSignature
|
||||
.with_key_and_subkeys(self)
|
||||
.where.not(verification_status: GpgSignature.verification_statuses[:unknown_key])
|
||||
.where.not(verification_status: CommitSignatures::GpgSignature.verification_statuses[:unknown_key])
|
||||
.update_all(
|
||||
gpg_key_id: nil,
|
||||
gpg_key_subkey_id: nil,
|
||||
verification_status: GpgSignature.verification_statuses[:unknown_key],
|
||||
verification_status: CommitSignatures::GpgSignature.verification_statuses[:unknown_key],
|
||||
updated_at: Time.zone.now
|
||||
)
|
||||
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class GpgSignature < ApplicationRecord
|
||||
include ShaAttribute
|
||||
|
||||
sha_attribute :commit_sha
|
||||
sha_attribute :gpg_key_primary_keyid
|
||||
|
||||
enum verification_status: {
|
||||
unverified: 0,
|
||||
verified: 1,
|
||||
same_user_different_email: 2,
|
||||
other_user: 3,
|
||||
unverified_key: 4,
|
||||
unknown_key: 5,
|
||||
multiple_signatures: 6
|
||||
}
|
||||
|
||||
belongs_to :project
|
||||
belongs_to :gpg_key
|
||||
belongs_to :gpg_key_subkey
|
||||
|
||||
validates :commit_sha, presence: true
|
||||
validates :project_id, presence: true
|
||||
validates :gpg_key_primary_keyid, presence: true
|
||||
|
||||
scope :by_commit_sha, ->(shas) { where(commit_sha: shas) }
|
||||
|
||||
def self.with_key_and_subkeys(gpg_key)
|
||||
subkey_ids = gpg_key.subkeys.pluck(:id)
|
||||
|
||||
where(
|
||||
arel_table[:gpg_key_id].eq(gpg_key.id).or(
|
||||
arel_table[:gpg_key_subkey_id].in(subkey_ids)
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def self.safe_create!(attributes)
|
||||
create_with(attributes)
|
||||
.safe_find_or_create_by!(commit_sha: attributes[:commit_sha])
|
||||
end
|
||||
|
||||
# Find commits that are lacking a signature in the database at present
|
||||
def self.unsigned_commit_shas(commit_shas)
|
||||
return [] if commit_shas.empty?
|
||||
|
||||
signed = GpgSignature.where(commit_sha: commit_shas).pluck(:commit_sha)
|
||||
|
||||
commit_shas - signed
|
||||
end
|
||||
|
||||
def gpg_key=(model)
|
||||
case model
|
||||
when GpgKey
|
||||
super
|
||||
when GpgKeySubkey
|
||||
self.gpg_key_subkey = model
|
||||
when NilClass
|
||||
super
|
||||
self.gpg_key_subkey = nil
|
||||
end
|
||||
end
|
||||
|
||||
def gpg_key
|
||||
if gpg_key_id
|
||||
super
|
||||
elsif gpg_key_subkey_id
|
||||
gpg_key_subkey
|
||||
end
|
||||
end
|
||||
|
||||
def gpg_key_primary_keyid
|
||||
super&.upcase
|
||||
end
|
||||
|
||||
def commit
|
||||
project.commit(commit_sha)
|
||||
end
|
||||
|
||||
def gpg_commit
|
||||
return unless commit
|
||||
|
||||
Gitlab::Gpg::Commit.new(commit)
|
||||
end
|
||||
end
|
|
@ -10,17 +10,10 @@ class Packages::Conan::Metadatum < ApplicationRecord
|
|||
validates :package_username,
|
||||
:package_channel,
|
||||
presence: true,
|
||||
format: { with: Gitlab::Regex.conan_recipe_component_regex },
|
||||
if: -> { Feature.disabled?(:packages_conan_allow_empty_username_channel) }
|
||||
|
||||
validates :package_username,
|
||||
:package_channel,
|
||||
presence: true,
|
||||
format: { with: Gitlab::Regex.conan_recipe_user_channel_regex },
|
||||
if: -> { Feature.enabled?(:packages_conan_allow_empty_username_channel) }
|
||||
format: { with: Gitlab::Regex.conan_recipe_user_channel_regex }
|
||||
|
||||
validate :conan_package_type
|
||||
validate :username_channel_none_values, if: -> { Feature.enabled?(:packages_conan_allow_empty_username_channel) }
|
||||
validate :username_channel_none_values
|
||||
|
||||
def recipe
|
||||
"#{package.name}/#{package.version}@#{package_username}/#{package_channel}"
|
||||
|
|
|
@ -13,7 +13,7 @@ class X509Certificate < ApplicationRecord
|
|||
|
||||
belongs_to :x509_issuer, class_name: 'X509Issuer', foreign_key: 'x509_issuer_id', optional: false
|
||||
|
||||
has_many :x509_commit_signatures, inverse_of: 'x509_certificate'
|
||||
has_many :x509_commit_signatures, class_name: 'CommitSignatures::X509CommitSignature', inverse_of: 'x509_certificate'
|
||||
|
||||
# rfc 5280 - 4.2.1.2 Subject Key Identifier
|
||||
validates :subject_key_identifier, presence: true, format: { with: /\A(\h{2}:){19}\h{2}\z/ }
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class X509CommitSignature < ApplicationRecord
|
||||
include ShaAttribute
|
||||
|
||||
sha_attribute :commit_sha
|
||||
|
||||
enum verification_status: {
|
||||
unverified: 0,
|
||||
verified: 1
|
||||
}
|
||||
|
||||
belongs_to :project, class_name: 'Project', foreign_key: 'project_id', optional: false
|
||||
belongs_to :x509_certificate, class_name: 'X509Certificate', foreign_key: 'x509_certificate_id', optional: false
|
||||
|
||||
validates :commit_sha, presence: true
|
||||
validates :project_id, presence: true
|
||||
validates :x509_certificate_id, presence: true
|
||||
|
||||
scope :by_commit_sha, ->(shas) { where(commit_sha: shas) }
|
||||
|
||||
def self.safe_create!(attributes)
|
||||
create_with(attributes)
|
||||
.safe_find_or_create_by!(commit_sha: attributes[:commit_sha])
|
||||
end
|
||||
|
||||
# Find commits that are lacking a signature in the database at present
|
||||
def self.unsigned_commit_shas(commit_shas)
|
||||
return [] if commit_shas.empty?
|
||||
|
||||
signed = by_commit_sha(commit_shas).pluck(:commit_sha)
|
||||
commit_shas - signed
|
||||
end
|
||||
|
||||
def commit
|
||||
project.commit(commit_sha)
|
||||
end
|
||||
|
||||
def x509_commit
|
||||
return unless commit
|
||||
|
||||
Gitlab::X509::Commit.new(commit)
|
||||
end
|
||||
|
||||
def user
|
||||
commit.committer
|
||||
end
|
||||
end
|
|
@ -157,11 +157,11 @@ module Git
|
|||
end
|
||||
|
||||
def unsigned_x509_shas(commits)
|
||||
X509CommitSignature.unsigned_commit_shas(commits.map(&:sha))
|
||||
CommitSignatures::X509CommitSignature.unsigned_commit_shas(commits.map(&:sha))
|
||||
end
|
||||
|
||||
def unsigned_gpg_shas(commits)
|
||||
GpgSignature.unsigned_commit_shas(commits.map(&:sha))
|
||||
CommitSignatures::GpgSignature.unsigned_commit_shas(commits.map(&:sha))
|
||||
end
|
||||
|
||||
def enqueue_update_signatures
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
- if project.archived
|
||||
%span.badge.badge-warning
|
||||
= _('archived')
|
||||
= gl_badge_tag _('archived'), variant: :warning
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
= render 'delete_project_button', project: project
|
||||
|
||||
.stats
|
||||
%span.badge.badge-pill
|
||||
= storage_counter(project.statistics&.storage_size)
|
||||
= gl_badge_tag storage_counter(project.statistics&.storage_size)
|
||||
= render 'project_badges', project: project
|
||||
|
||||
.title
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
= link_to matching_branch.name, project_ref_path(@project, matching_branch.name), class: 'ref-name'
|
||||
|
||||
- if @project.root_ref?(matching_branch.name)
|
||||
%span.badge.badge-info.gl-ml-2 default
|
||||
= gl_badge_tag s_('ProtectedBranch|default'), { variant: :info }, { class: 'gl-ml-2' }
|
||||
%td
|
||||
- commit = @project.commit(matching_branch.name)
|
||||
= link_to(commit.short_id, project_commit_path(@project, commit.id), class: 'commit-sha')
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
- project = blob.project
|
||||
- return unless project
|
||||
- blob_link = project_blob_path(project, tree_join(repository_ref(project), blob.path))
|
||||
- blame_link = project_blame_path(project, tree_join(repository_ref(project), blob.path))
|
||||
|
||||
= render partial: 'search/results/blob_data', locals: { blob: blob, project: project, path: blob.path, blob_link: blob_link }
|
||||
= render partial: 'search/results/blob_data', locals: { blob: blob, project: project, path: blob.path, blob_link: blob_link, blame_link: blame_link }
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
- if blob.data
|
||||
- if blob.data.size > 0
|
||||
.file-content.code.term{ data: { qa_selector: 'file_text_content' } }
|
||||
= render 'shared/file_highlight', blob: blob, first_line_number: blob.startline, blob_link: blob_link, highlight_line: blob.highlight_line
|
||||
= render 'search/results/blob_highlight', blob: blob, first_line_number: blob.startline, blob_link: blob_link, blame_link: blame_link, highlight_line: blob.highlight_line
|
||||
- else
|
||||
.file-content.code
|
||||
.nothing-here-block
|
||||
|
|
22
app/views/search/results/_blob_highlight.html.haml
Normal file
22
app/views/search/results/_blob_highlight.html.haml
Normal file
|
@ -0,0 +1,22 @@
|
|||
- offset = defined?(first_line_number) ? first_line_number : 1
|
||||
- highlight = defined?(highlight_line) && highlight_line ? highlight_line - offset : nil
|
||||
|
||||
#search-blob-content.file-content.code.js-syntax-highlight{ class: 'gl-py-3!' }
|
||||
- if blob.present?
|
||||
.blob-content{ data: { blob_id: blob.id, path: blob.path, highlight_line: highlight, qa_selector: 'file_content' } }
|
||||
- blob.present.highlight.lines.each_with_index do |line, index|
|
||||
- i = index + offset
|
||||
.line_holder.code-search-line
|
||||
.line-numbers
|
||||
.gl-display-flex
|
||||
%span.diff-line-num.gl-pl-3
|
||||
%a.has-tooltip{ href: "#{blame_link}#L#{i}", id: "blame-L#{i}", 'data-line-number' => i, title: _('View blame') }
|
||||
= sprite_icon('git')
|
||||
%span.diff-line-num.flex-grow-1.gl-pr-3
|
||||
%a{ href: "#{blob_link}#L#{i}", id: "blob-L#{i}", 'data-line-number' => i, class: 'gl-display-flex! gl-align-items-center gl-justify-content-end' }
|
||||
= sprite_icon('link', css_class: 'gl-ml-3! gl-mr-1!')
|
||||
= i
|
||||
%pre.code.highlight
|
||||
%code
|
||||
= line.html_safe
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
.card-header
|
||||
= _("Users requesting access to")
|
||||
%strong= membership_source.name
|
||||
%span.badge.badge-pill= requesters.size
|
||||
= gl_badge_tag requesters.size
|
||||
= render 'shared/members/manage_access_button', path: membership_source.is_a?(Project) ? project_project_members_path(@project, tab: 'access_requests') : group_group_members_path(@group, tab: 'access_requests')
|
||||
%ul.content-list.members-list
|
||||
= render partial: 'shared/members/member',
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
- if project.archived
|
||||
%span.d-flex.badge-pill.gl-badge.badge-warning.gl-ml-3
|
||||
= _('archived')
|
||||
= gl_badge_tag _('archived'), { variant: :warning }, { class: 'gl-display-flex gl-ml-3' }
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: packages_conan_allow_empty_username_channel
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75106
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346006
|
||||
milestone: '14.5'
|
||||
type: development
|
||||
group: group::package
|
||||
default_enabled: false
|
|
@ -11,6 +11,3 @@ Grape::Validations.register_validator(:untrusted_regexp, ::API::Validations::Val
|
|||
Grape::Validations.register_validator(:email_or_email_list, ::API::Validations::Validators::EmailOrEmailList)
|
||||
Grape::Validations.register_validator(:iteration_id, ::API::Validations::Validators::IntegerOrCustomValue)
|
||||
Grape::Validations.register_validator(:project_portable, ::API::Validations::Validators::ProjectPortable)
|
||||
# TODO Delete this validator along with the packages_conan_allow_empty_username_channel feature flag
|
||||
# # https://gitlab.com/gitlab-org/gitlab/-/issues/346006
|
||||
Grape::Validations.register_validator('packages_conan_user_channel', ::API::Validations::Validators::PackagesConanUserChannel)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
data_category: optional
|
||||
data_category: operational
|
||||
key_path: usage_activity_by_stage_monthly.create.merge_requests_users
|
||||
description: Distinct count of users performing merge request actions like closed, merged, created, commented
|
||||
product_section: dev
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
data_category: optional
|
||||
data_category: operational
|
||||
key_path: usage_activity_by_stage_monthly.verify.ci_builds
|
||||
description: Unique monthly builds in project
|
||||
product_section: ops
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
data_category: optional
|
||||
data_category: operational
|
||||
key_path: usage_activity_by_stage_monthly.verify.ci_internal_pipelines
|
||||
description: Total pipelines in GitLab repositories in a month
|
||||
product_section: ops
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
data_category: optional
|
||||
data_category: operational
|
||||
key_path: usage_activity_by_stage_monthly.verify.ci_pipeline_config_repository
|
||||
description: Total Monthly Pipelines from templates in repository
|
||||
product_section: ops
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
data_category: optional
|
||||
data_category: operational
|
||||
key_path: usage_activity_by_stage_monthly.verify.ci_pipelines
|
||||
description: Distinct users triggering pipelines in a month
|
||||
product_section: ops
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
data_category: optional
|
||||
data_category: operational
|
||||
key_path: usage_activity_by_stage_monthly.create.action_monthly_active_users_design_management
|
||||
description: Monthly active users for design management
|
||||
product_section: dev
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue