diff options
Diffstat (limited to 'app')
29 files changed, 343 insertions, 147 deletions
diff --git a/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue b/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue index 10976202d06..7fefbab977d 100644 --- a/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue +++ b/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue @@ -7,6 +7,7 @@ import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vu import { updateGlobalTodoCount } from '~/vue_shared/components/sidebar/todo_toggle/utils'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import DesignNotePin from '~/vue_shared/components/design_management/design_note_pin.vue'; +import { isLoggedIn } from '~/lib/utils/common_utils'; import { ACTIVE_DISCUSSION_SOURCE_TYPES } from '../../constants'; import createNoteMutation from '../../graphql/mutations/create_note.mutation.graphql'; import toggleResolveDiscussionMutation from '../../graphql/mutations/toggle_resolve_discussion.mutation.graphql'; @@ -17,6 +18,7 @@ import { hasErrors } from '../../utils/cache_update'; import { extractDesign } from '../../utils/design_management_utils'; import { ADD_DISCUSSION_COMMENT_ERROR } from '../../utils/error_messages'; import DesignNote from './design_note.vue'; +import DesignNoteSignedOut from './design_note_signed_out.vue'; import DesignReplyForm from './design_reply_form.vue'; import ToggleRepliesWidget from './toggle_replies_widget.vue'; @@ -24,6 +26,7 @@ export default { components: { ApolloMutation, DesignNote, + DesignNoteSignedOut, ReplyPlaceholder, DesignReplyForm, GlIcon, @@ -55,6 +58,14 @@ export default { required: false, default: '', }, + registerPath: { + type: String, + required: true, + }, + signInPath: { + type: String, + required: true, + }, resolvedDiscussionsExpanded: { type: Boolean, required: true, @@ -93,6 +104,7 @@ export default { isResolving: false, shouldChangeResolvedStatus: false, areRepliesCollapsed: this.discussion.resolved, + isLoggedIn: isLoggedIn(), }; }, computed: { @@ -226,7 +238,7 @@ export default { :class="{ 'gl-bg-blue-50': isDiscussionActive }" @error="$emit('update-note-error', $event)" > - <template v-if="discussion.resolvable" #resolve-discussion> + <template v-if="isLoggedIn && discussion.resolvable" #resolve-discussion> <button v-gl-tooltip :class="{ 'is-active': discussion.resolved }" @@ -269,38 +281,47 @@ export default { :class="{ 'gl-bg-blue-50': isDiscussionActive }" @error="$emit('update-note-error', $event)" /> - <li v-show="isReplyPlaceholderVisible" class="reply-wrapper discussion-reply-holder"> - <reply-placeholder - v-if="!isFormVisible" - class="qa-discussion-reply" - :placeholder-text="__('Reply…')" - @focus="showForm" - /> - <apollo-mutation - v-else - #default="{ mutate, loading }" - :mutation="$options.createNoteMutation" - :variables="{ - input: mutationPayload, - }" - @done="onDone" - @error="onCreateNoteError" - > - <design-reply-form - v-model="discussionComment" - :is-saving="loading" - :markdown-preview-path="markdownPreviewPath" - @submit-form="mutate" - @cancel-form="hideForm" + <li + v-show="isReplyPlaceholderVisible" + class="reply-wrapper discussion-reply-holder" + :class="{ 'gl-bg-gray-10': !isLoggedIn }" + > + <template v-if="!isLoggedIn"> + <design-note-signed-out :register-path="registerPath" :sign-in-path="signInPath" /> + </template> + <template v-else> + <reply-placeholder + v-if="!isFormVisible" + class="qa-discussion-reply" + :placeholder-text="__('Reply…')" + @focus="showForm" + /> + <apollo-mutation + v-else + #default="{ mutate, loading }" + :mutation="$options.createNoteMutation" + :variables="{ + input: mutationPayload, + }" + @done="onDone" + @error="onCreateNoteError" > - <template v-if="discussion.resolvable" #resolve-checkbox> - <label data-testid="resolve-checkbox"> - <input v-model="shouldChangeResolvedStatus" type="checkbox" /> - {{ resolveCheckboxText }} - </label> - </template> - </design-reply-form> - </apollo-mutation> + <design-reply-form + v-model="discussionComment" + :is-saving="loading" + :markdown-preview-path="markdownPreviewPath" + @submit-form="mutate" + @cancel-form="hideForm" + > + <template v-if="discussion.resolvable" #resolve-checkbox> + <label data-testid="resolve-checkbox"> + <input v-model="shouldChangeResolvedStatus" type="checkbox" /> + {{ resolveCheckboxText }} + </label> + </template> + </design-reply-form> + </apollo-mutation> + </template> </li> </ul> </div> diff --git a/app/assets/javascripts/design_management/components/design_notes/design_note_signed_out.vue b/app/assets/javascripts/design_management/components/design_notes/design_note_signed_out.vue new file mode 100644 index 00000000000..f0812e62bba --- /dev/null +++ b/app/assets/javascripts/design_management/components/design_notes/design_note_signed_out.vue @@ -0,0 +1,50 @@ +<script> +import { GlSprintf, GlLink } from '@gitlab/ui'; +import { __ } from '~/locale'; + +export default { + components: { + GlSprintf, + GlLink, + }, + props: { + registerPath: { + type: String, + required: true, + }, + signInPath: { + type: String, + required: true, + }, + isAddDiscussion: { + type: Boolean, + required: false, + default: false, + }, + }, + computed: { + signedOutText() { + return this.isAddDiscussion + ? __( + 'Please %{registerLinkStart}register%{registerLinkEnd} or %{signInLinkStart}sign in%{signInLinkEnd} to start a new discussion.', + ) + : __( + 'Please %{registerLinkStart}register%{registerLinkEnd} or %{signInLinkStart}sign in%{signInLinkEnd} to reply.', + ); + }, + }, +}; +</script> + +<template> + <div class="disabled-comment text-center"> + <gl-sprintf :message="signedOutText"> + <template #registerLink="{ content }"> + <gl-link :href="registerPath">{{ content }}</gl-link> + </template> + <template #signInLink="{ content }"> + <gl-link :href="signInPath">{{ content }}</gl-link> + </template> + </gl-sprintf> + </div> +</template> diff --git a/app/assets/javascripts/design_management/components/design_presentation.vue b/app/assets/javascripts/design_management/components/design_presentation.vue index 11d2f3b2e37..5116bacefa5 100644 --- a/app/assets/javascripts/design_management/components/design_presentation.vue +++ b/app/assets/javascripts/design_management/components/design_presentation.vue @@ -1,5 +1,6 @@ <script> import { throttle } from 'lodash'; +import { isLoggedIn } from '~/lib/utils/common_utils'; import DesignOverlay from './design_overlay.vue'; import DesignImage from './image.vue'; @@ -54,6 +55,7 @@ export default { initialLoad: true, lastDragPosition: null, isDraggingDesign: false, + isLoggedIn: isLoggedIn(), }; }, computed: { @@ -311,7 +313,7 @@ export default { :position="overlayPosition" :notes="discussionStartingNotes" :current-comment-form="currentCommentForm" - :disable-commenting="isDraggingDesign" + :disable-commenting="!isLoggedIn || isDraggingDesign" :resolved-discussions-expanded="resolvedDiscussionsExpanded" @openCommentForm="openCommentForm" @closeCommentForm="closeCommentForm" diff --git a/app/assets/javascripts/design_management/components/design_sidebar.vue b/app/assets/javascripts/design_management/components/design_sidebar.vue index ced76eb4843..6d0ed3b08a3 100644 --- a/app/assets/javascripts/design_management/components/design_sidebar.vue +++ b/app/assets/javascripts/design_management/components/design_sidebar.vue @@ -1,7 +1,7 @@ <script> import { GlCollapse, GlButton, GlPopover } from '@gitlab/ui'; import Cookies from 'js-cookie'; -import { parseBoolean } from '~/lib/utils/common_utils'; +import { parseBoolean, isLoggedIn } from '~/lib/utils/common_utils'; import { s__ } from '~/locale'; import Participants from '~/sidebar/components/participants/participants.vue'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; @@ -9,11 +9,13 @@ import { ACTIVE_DISCUSSION_SOURCE_TYPES } from '../constants'; import updateActiveDiscussionMutation from '../graphql/mutations/update_active_discussion.mutation.graphql'; import { extractDiscussions, extractParticipants } from '../utils/design_management_utils'; import DesignDiscussion from './design_notes/design_discussion.vue'; +import DesignNoteSignedOut from './design_notes/design_note_signed_out.vue'; import DesignTodoButton from './design_todo_button.vue'; export default { components: { DesignDiscussion, + DesignNoteSignedOut, Participants, GlCollapse, GlButton, @@ -28,6 +30,12 @@ export default { issueIid: { default: '', }, + registerPath: { + default: '', + }, + signInPath: { + default: '', + }, }, props: { design: { @@ -47,6 +55,7 @@ export default { return { isResolvedCommentsPopoverHidden: parseBoolean(Cookies.get(this.$options.cookieKey)), discussionWithOpenForm: '', + isLoggedIn: isLoggedIn(), }; }, computed: { @@ -134,12 +143,19 @@ export default { class="gl-mb-4" /> <h2 - v-if="unresolvedDiscussions.length === 0" + v-if="isLoggedIn && unresolvedDiscussions.length === 0" class="new-discussion-disclaimer gl-font-base gl-m-0 gl-mb-4" data-testid="new-discussion-disclaimer" > {{ s__("DesignManagement|Click the image where you'd like to start a new discussion") }} </h2> + <design-note-signed-out + v-if="!isLoggedIn" + class="gl-mb-4" + :register-path="registerPath" + :sign-in-path="signInPath" + :is-add-discussion="true" + /> <design-discussion v-for="discussion in unresolvedDiscussions" :key="discussion.id" @@ -147,6 +163,8 @@ export default { :design-id="$route.params.id" :noteable-id="design.id" :markdown-preview-path="markdownPreviewPath" + :register-path="registerPath" + :sign-in-path="signInPath" :resolved-discussions-expanded="resolvedDiscussionsExpanded" :discussion-with-open-form="discussionWithOpenForm" data-testid="unresolved-discussion" @@ -197,6 +215,8 @@ export default { :design-id="$route.params.id" :noteable-id="design.id" :markdown-preview-path="markdownPreviewPath" + :register-path="registerPath" + :sign-in-path="signInPath" :resolved-discussions-expanded="resolvedDiscussionsExpanded" :discussion-with-open-form="discussionWithOpenForm" data-testid="resolved-discussion" diff --git a/app/assets/javascripts/design_management/index.js b/app/assets/javascripts/design_management/index.js index 11666587265..4ae76050aa5 100644 --- a/app/assets/javascripts/design_management/index.js +++ b/app/assets/javascripts/design_management/index.js @@ -8,7 +8,7 @@ import createRouter from './router'; export default () => { const el = document.querySelector('.js-design-management'); - const { issueIid, projectPath, issuePath } = el.dataset; + const { issueIid, projectPath, issuePath, registerPath, signInPath } = el.dataset; const router = createRouter(issuePath); apolloProvider.clients.defaultClient.cache.writeQuery({ @@ -29,6 +29,8 @@ export default () => { provide: { projectPath, issueIid, + registerPath, + signInPath, }, mounted() { performanceMarkAndMeasure({ diff --git a/app/assets/javascripts/gitlab_version_check.js b/app/assets/javascripts/gitlab_version_check.js new file mode 100644 index 00000000000..2892aded7c5 --- /dev/null +++ b/app/assets/javascripts/gitlab_version_check.js @@ -0,0 +1,20 @@ +import Vue from 'vue'; +import GitlabVersionCheck from '~/vue_shared/components/gitlab_version_check.vue'; + +const mountGitlabVersionCheck = (el) => { + const { size } = el.dataset; + + return new Vue({ + el, + render(createElement) { + return createElement(GitlabVersionCheck, { + props: { + size, + }, + }); + }, + }); +}; + +export default () => + [...document.querySelectorAll('.js-gitlab-version-check')].map(mountGitlabVersionCheck); diff --git a/app/assets/javascripts/issues/show/components/app.vue b/app/assets/javascripts/issues/show/components/app.vue index eeaf865a35f..0490728c6bc 100644 --- a/app/assets/javascripts/issues/show/components/app.vue +++ b/app/assets/javascripts/issues/show/components/app.vue @@ -6,7 +6,7 @@ import { IssuableStatus, IssuableStatusText, IssuableType } from '~/issues/const import Poll from '~/lib/utils/poll'; import { visitUrl } from '~/lib/utils/url_utility'; import { __, sprintf } from '~/locale'; -import { IssueTypePath, IncidentTypePath, IncidentType, POLLING_DELAY } from '../constants'; +import { ISSUE_TYPE_PATH, INCIDENT_TYPE_PATH, INCIDENT_TYPE, POLLING_DELAY } from '../constants'; import eventHub from '../event_hub'; import getIssueStateQuery from '../queries/get_issue_state.query.graphql'; import Service from '../services/index'; @@ -378,15 +378,15 @@ export default { .then((data) => { if ( !window.location.pathname.includes(data.web_url) && - issueState.issueType !== IncidentType + issueState.issueType !== INCIDENT_TYPE ) { visitUrl(data.web_url); } if (issueState.isDirty) { const URI = - issueState.issueType === IncidentType - ? data.web_url.replace(IssueTypePath, IncidentTypePath) + issueState.issueType === INCIDENT_TYPE + ? data.web_url.replace(ISSUE_TYPE_PATH, INCIDENT_TYPE_PATH) : data.web_url; visitUrl(URI); } diff --git a/app/assets/javascripts/issues/show/components/fields/type.vue b/app/assets/javascripts/issues/show/components/fields/type.vue index 9110a6924b4..75d0b9e5e76 100644 --- a/app/assets/javascripts/issues/show/components/fields/type.vue +++ b/app/assets/javascripts/issues/show/components/fields/type.vue @@ -2,7 +2,7 @@ import { GlFormGroup, GlDropdown, GlDropdownItem, GlIcon } from '@gitlab/ui'; import { capitalize } from 'lodash'; import { __ } from '~/locale'; -import { IssuableTypes, IncidentType } from '../../constants'; +import { issuableTypes, INCIDENT_TYPE } from '../../constants'; import getIssueStateQuery from '../../queries/get_issue_state.query.graphql'; import updateIssueStateMutation from '../../queries/update_issue_state.mutation.graphql'; @@ -12,7 +12,7 @@ export const i18n = { export default { i18n, - IssuableTypes, + issuableTypes, components: { GlFormGroup, GlIcon, @@ -45,7 +45,7 @@ export default { return capitalize(issueType); }, shouldShowIncident() { - return this.issueType === IncidentType || this.canCreateIncident; + return this.issueType === INCIDENT_TYPE || this.canCreateIncident; }, }, methods: { @@ -59,7 +59,7 @@ export default { }); }, isShown(type) { - return type.value !== IncidentType || this.shouldShowIncident; + return type.value !== INCIDENT_TYPE || this.shouldShowIncident; }, }, }; @@ -81,7 +81,7 @@ export default { toggle-class="dropdown-menu-toggle" > <gl-dropdown-item - v-for="type in $options.IssuableTypes" + v-for="type in $options.issuableTypes" v-show="isShown(type)" :key="type.value" :is-checked="issueState.issueType === type.value" diff --git a/app/assets/javascripts/issues/show/components/header_actions.vue b/app/assets/javascripts/issues/show/components/header_actions.vue index 700ef92a0f3..52c95d48a23 100644 --- a/app/assets/javascripts/issues/show/components/header_actions.vue +++ b/app/assets/javascripts/issues/show/components/header_actions.vue @@ -13,7 +13,7 @@ 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 } from '~/issues/constants'; -import { IssueStateEvent } from '~/issues/show/constants'; +import { ISSUE_STATE_EVENT_CLOSE, ISSUE_STATE_EVENT_REOPEN } from '~/issues/show/constants'; import { capitalizeFirstCharacter } from '~/lib/utils/text_utility'; import { visitUrl } from '~/lib/utils/url_utility'; import { s__, __, sprintf } from '~/locale'; @@ -163,7 +163,7 @@ export default { input: { iid: this.iid.toString(), projectPath: this.projectPath, - stateEvent: this.isClosed ? IssueStateEvent.Reopen : IssueStateEvent.Close, + stateEvent: this.isClosed ? ISSUE_STATE_EVENT_REOPEN : ISSUE_STATE_EVENT_CLOSE, }, }, }) diff --git a/app/assets/javascripts/issues/show/constants.js b/app/assets/javascripts/issues/show/constants.js index 35f3bcdad70..a100aaf88ad 100644 --- a/app/assets/javascripts/issues/show/constants.js +++ b/app/assets/javascripts/issues/show/constants.js @@ -1,22 +1,20 @@ import { __ } from '~/locale'; -export const IssueStateEvent = { - Close: 'CLOSE', - Reopen: 'REOPEN', -}; - -export const STATUS_PAGE_PUBLISHED = __('Published on status page'); +export const INCIDENT_TYPE = 'incident'; +export const INCIDENT_TYPE_PATH = 'issues/incident'; +export const ISSUE_STATE_EVENT_CLOSE = 'CLOSE'; +export const ISSUE_STATE_EVENT_REOPEN = 'REOPEN'; +export const ISSUE_TYPE_PATH = 'issues'; export const JOIN_ZOOM_MEETING = __('Join Zoom meeting'); +export const POLLING_DELAY = 2000; +export const STATUS_PAGE_PUBLISHED = __('Published on status page'); -export const IssuableTypes = [ +export const issuableTypes = [ { value: 'issue', text: __('Issue'), icon: 'issue-type-issue' }, { value: 'incident', text: __('Incident'), icon: 'issue-type-incident' }, ]; -export const IssueTypePath = 'issues'; -export const IncidentTypePath = 'issues/incident'; -export const IncidentType = 'incident'; - -export const issueState = { issueType: undefined, isDirty: false }; - -export const POLLING_DELAY = 2000; +export const issueState = { + issueType: undefined, + isDirty: false, +}; diff --git a/app/assets/javascripts/issues/show/index.js b/app/assets/javascripts/issues/show/index.js index 3ac781089ba..3e6736d14bf 100644 --- a/app/assets/javascripts/issues/show/index.js +++ b/app/assets/javascripts/issues/show/index.js @@ -6,7 +6,7 @@ import IssueApp from './components/app.vue'; import HeaderActions from './components/header_actions.vue'; import IncidentTabs from './components/incidents/incident_tabs.vue'; import SentryErrorStackTrace from './components/sentry_error_stack_trace.vue'; -import { IncidentType, issueState } from './constants'; +import { INCIDENT_TYPE, issueState } from './constants'; import apolloProvider from './graphql'; import getIssueStateQuery from './queries/get_issue_state.query.graphql'; @@ -45,7 +45,7 @@ export function initIncidentApp(issueData = {}) { el, apolloProvider, provide: { - issueType: IncidentType, + issueType: INCIDENT_TYPE, canCreateIncident, canUpdate, fullPath, @@ -111,7 +111,7 @@ export function initHeaderActions(store, type = '') { bootstrapApollo({ ...issueState, issueType: el.dataset.issueType }); const canCreate = - type === IncidentType ? el.dataset.canCreateIncident : el.dataset.canCreateIssue; + type === INCIDENT_TYPE ? el.dataset.canCreateIncident : el.dataset.canCreateIssue; return new Vue({ el, diff --git a/app/assets/javascripts/lib/utils/constants.js b/app/assets/javascripts/lib/utils/constants.js index a108b02bcbf..36c6545164e 100644 --- a/app/assets/javascripts/lib/utils/constants.js +++ b/app/assets/javascripts/lib/utils/constants.js @@ -17,7 +17,6 @@ export const BV_HIDE_MODAL = 'bv::hide::modal'; export const BV_HIDE_TOOLTIP = 'bv::hide::tooltip'; export const BV_DROPDOWN_SHOW = 'bv::dropdown::show'; export const BV_DROPDOWN_HIDE = 'bv::dropdown::hide'; -export const BV_COLLAPSE_STATE = 'bv::collapse::state'; export const DEFAULT_TH_CLASSES = 'gl-bg-transparent! gl-border-b-solid! gl-border-b-gray-100! gl-p-5! gl-border-b-1!'; diff --git a/app/assets/javascripts/pages/help/index/index.js b/app/assets/javascripts/pages/help/index/index.js index 736add8dca3..a8e67c57307 100644 --- a/app/assets/javascripts/pages/help/index/index.js +++ b/app/assets/javascripts/pages/help/index/index.js @@ -1,6 +1,5 @@ -import $ from 'jquery'; import docs from '~/docs/docs_bundle'; -import VersionCheckImage from '~/version_check_image'; +import initGitlabVersionCheck from '~/gitlab_version_check'; docs(); -VersionCheckImage.bindErrorEvent($('img.js-version-status-badge')); +initGitlabVersionCheck(); diff --git a/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue b/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue index b29e9455755..c28de88554a 100644 --- a/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue +++ b/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue @@ -596,7 +596,9 @@ export default { :disabled="disableSubmitButton" >{{ submitButtonText }}</gl-button > - <gl-button :href="cancelFormPath" class="float-right">{{ $options.i18n.cancel }}</gl-button> + <gl-button data-testid="wiki-cancel-button" :href="cancelFormPath" class="float-right">{{ + $options.i18n.cancel + }}</gl-button> </div> </gl-form> </template> diff --git a/app/assets/javascripts/version_check_image.js b/app/assets/javascripts/version_check_image.js deleted file mode 100644 index 4e00e0f11f7..00000000000 --- a/app/assets/javascripts/version_check_image.js +++ /dev/null @@ -1,6 +0,0 @@ -export default class VersionCheckImage { - static bindErrorEvent(imageElement) { - // eslint-disable-next-line @gitlab/no-global-event-off - imageElement.off('error').on('error', () => imageElement.hide()); - } -} diff --git a/app/assets/javascripts/vue_shared/components/gitlab_version_check.vue b/app/assets/javascripts/vue_shared/components/gitlab_version_check.vue new file mode 100644 index 00000000000..acddf16bd27 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/gitlab_version_check.vue @@ -0,0 +1,67 @@ +<script> +import { GlBadge } from '@gitlab/ui'; +import { s__ } from '~/locale'; +import axios from '~/lib/utils/axios_utils'; + +const STATUS_TYPES = { + SUCCESS: 'success', + WARNING: 'warning', + DANGER: 'danger', +}; + +export default { + name: 'GitlabVersionCheck', + components: { + GlBadge, + }, + props: { + size: { + type: String, + required: false, + default: 'md', + }, + }, + data() { + return { + status: null, + }; + }, + computed: { + title() { + if (this.status === STATUS_TYPES.SUCCESS) { + return s__('VersionCheck|Up to date'); + } else if (this.status === STATUS_TYPES.WARNING) { + return s__('VersionCheck|Update available'); + } else if (this.status === STATUS_TYPES.DANGER) { + return s__('VersionCheck|Update ASAP'); + } + + return null; + }, + }, + created() { + this.checkGitlabVersion(); + }, + methods: { + checkGitlabVersion() { + axios + .get('/admin/version_check.json') + .then((res) => { + if (res.data) { + this.status = res.data.severity; + } + }) + .catch(() => { + // Silently fail + this.status = null; + }); + }, + }, +}; +</script> + +<template> + <gl-badge v-if="status" class="version-check-badge" :variant="status" :size="size">{{ + title + }}</gl-badge> +</template> diff --git a/app/graphql/types/packages/package_details_type.rb b/app/graphql/types/packages/package_details_type.rb index 043cb7eff2b..07d8cf93b4e 100644 --- a/app/graphql/types/packages/package_details_type.rb +++ b/app/graphql/types/packages/package_details_type.rb @@ -3,6 +3,8 @@ module Types module Packages class PackageDetailsType < PackageType + include ::PackagesHelper + graphql_name 'PackageDetailsType' description 'Represents a package details in the Package Registry. Note that this type is in beta and susceptible to changes' authorize :read_package @@ -21,6 +23,15 @@ module Types description: 'Pipelines that built the package.', deprecated: { reason: 'Due to scalability concerns, this field is going to be removed', milestone: '14.6' } + field :composer_config_repository_url, GraphQL::Types::String, null: true, description: 'Url of the Composer setup endpoint.' + field :composer_url, GraphQL::Types::String, null: true, description: 'Url of the Composer endpoint.' + field :conan_url, GraphQL::Types::String, null: true, description: 'Url of the Conan project endpoint.' + field :maven_url, GraphQL::Types::String, null: true, description: 'Url of the Maven project endpoint.' + field :npm_url, GraphQL::Types::String, null: true, description: 'Url of the NPM project endpoint.' + field :nuget_url, GraphQL::Types::String, null: true, description: 'Url of the Nuget project endpoint.' + field :pypi_setup_url, GraphQL::Types::String, null: true, description: 'Url of the PyPi project setup endpoint.' + field :pypi_url, GraphQL::Types::String, null: true, description: 'Url of the PyPi project endpoint.' + def versions object.versions end @@ -32,6 +43,38 @@ module Types object.package_files end end + + def composer_config_repository_url + composer_config_repository_name(object.project.group&.id) + end + + def composer_url + composer_registry_url(object.project.group&.id) + end + + def conan_url + package_registry_project_url(object.project.id, :conan) + end + + def maven_url + package_registry_project_url(object.project.id, :maven) + end + + def npm_url + package_registry_project_url(object.project.id, :npm) + end + + def nuget_url + nuget_package_registry_url(object.project.id) + end + + def pypi_setup_url + package_registry_project_url(object.project.id, :pypi) + end + + def pypi_url + pypi_registry_url(object.project.id) + end end end end diff --git a/app/helpers/packages_helper.rb b/app/helpers/packages_helper.rb index 9e2b27de5b3..cf97fdf73e3 100644 --- a/app/helpers/packages_helper.rb +++ b/app/helpers/packages_helper.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true module PackagesHelper + include ::API::Helpers::RelatedResourcesHelpers + def package_sort_path(options = {}) "#{request.path}?#{options.to_param}" end diff --git a/app/helpers/version_check_helper.rb b/app/helpers/version_check_helper.rb index 7875b9e4a28..48548ae9e6a 100644 --- a/app/helpers/version_check_helper.rb +++ b/app/helpers/version_check_helper.rb @@ -1,12 +1,11 @@ # frozen_string_literal: true module VersionCheckHelper - def version_status_badge - return unless Rails.env.production? - return unless Gitlab::CurrentSettings.version_check_enabled - return if User.single_user&.requires_usage_stats_consent? + def show_version_check? + return false unless Gitlab::CurrentSettings.version_check_enabled + return false if User.single_user&.requires_usage_stats_consent? - image_tag VersionCheck.image_url, class: 'js-version-status-badge' + current_user&.can_read_all_resources? end def link_to_version diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml index 801b903395a..85b6ebfc63a 100644 --- a/app/views/admin/dashboard/index.html.haml +++ b/app/views/admin/dashboard/index.html.haml @@ -118,9 +118,9 @@ .gl-card-body %h4 = s_('AdminArea|Components') - - if Gitlab::CurrentSettings.version_check_enabled + - if show_version_check? .float-right - = version_status_badge + .js-gitlab-version-check{ data: { "size": "lg" } } = link_to(sprite_icon('question'), "https://gitlab.com/gitlab-org/gitlab/-/blob/master/CHANGELOG.md", class: 'gl-ml-2', target: '_blank', rel: 'noopener noreferrer') %p = link_to _('GitLab'), general_admin_application_settings_path diff --git a/app/views/admin/labels/_form.html.haml b/app/views/admin/labels/_form.html.haml deleted file mode 100644 index abf380474e4..00000000000 --- a/app/views/admin/labels/_form.html.haml +++ /dev/null @@ -1,31 +0,0 @@ -= form_for [:admin, @label], html: { class: 'label-form js-requires-input' } do |f| - = form_errors(@label) - - .form-group.row - .col-sm-2.col-form-label - = f.label :title - .col-sm-10 - = f.text_field :title, class: "form-control gl-form-input", required: true - .form-group.row - .col-sm-2.col-form-label - = f.label :description - .col-sm-10 - = f.text_field :description, class: "form-control gl-form-input js-quick-submit" - .form-group.row - .col-sm-2.col-form-label - = f.label :color, _("Background color") - .col-sm-10 - .input-group - .input-group-prepend - .input-group-text.label-color-preview - = f.text_field :color, class: "form-control gl-form-input" - .form-text.text-muted - = _('Choose any color.') - %br - = _("Or you can choose one of the suggested colors below") - - = render_suggested_colors - - .form-actions - = f.submit _('Save'), class: 'btn gl-button btn-confirm js-save-button' - = link_to _("Cancel"), admin_labels_path, class: 'btn gl-button btn-default btn-cancel' diff --git a/app/views/admin/labels/edit.html.haml b/app/views/admin/labels/edit.html.haml index 652ed095d00..44dd2b6a646 100644 --- a/app/views/admin/labels/edit.html.haml +++ b/app/views/admin/labels/edit.html.haml @@ -4,4 +4,4 @@ %h3.page-title = _('Edit Label') %hr -= render 'form' += render 'shared/labels/form', url: admin_label_path(@label), back_path: admin_labels_path diff --git a/app/views/admin/labels/new.html.haml b/app/views/admin/labels/new.html.haml index 20103fb8a29..5166bdb4d20 100644 --- a/app/views/admin/labels/new.html.haml +++ b/app/views/admin/labels/new.html.haml @@ -2,4 +2,4 @@ %h3.page-title = _('New Label') %hr -= render 'form' += render 'shared/labels/form', url: admin_labels_path, back_path: admin_labels_path diff --git a/app/views/help/index.html.haml b/app/views/help/index.html.haml index f81afd0a82e..3992cb527ed 100644 --- a/app/views/help/index.html.haml +++ b/app/views/help/index.html.haml @@ -4,12 +4,15 @@ = markdown_field(Gitlab::CurrentSettings.current_application_settings, :help_page_text) %hr -%h1 - = default_brand_title - - if user_signed_in? - %span= link_to_version - = version_status_badge - %hr +.gl-display-flex.gl-align-items-flex-end + %h1.gl-mt-5.gl-mb-3 + = default_brand_title + - if user_signed_in? + %span= link_to_version + - if show_version_check? + %span.gl-mt-5.gl-mb-3.gl-ml-3 + .js-gitlab-version-check{ data: { "size": "lg" } } +%hr - unless Gitlab::CurrentSettings.help_page_hide_commercial_content? %p.slead diff --git a/app/views/projects/issues/_design_management.html.haml b/app/views/projects/issues/_design_management.html.haml index a2ff9620c0c..c5ce0549816 100644 --- a/app/views/projects/issues/_design_management.html.haml +++ b/app/views/projects/issues/_design_management.html.haml @@ -8,7 +8,11 @@ - if @project.design_management_enabled? - add_page_startup_graphql_call('design_management/get_design_list', { fullPath: @project.full_path, iid: @issue.iid.to_s, atVersion: nil }) - add_page_startup_graphql_call('design_management/design_permissions', { fullPath: @project.full_path, iid: @issue.iid.to_s }) - .js-design-management{ data: { project_path: @project.full_path, issue_iid: @issue.iid, issue_path: project_issue_path(@project, @issue) } } + .js-design-management{ data: { project_path: @project.full_path, + issue_iid: @issue.iid, + issue_path: project_issue_path(@project, @issue), + register_path: new_user_registration_path(redirect_to_referer: 'yes'), + sign_in_path: new_session_path(:user, redirect_to_referer: 'yes') } } - else .gl-border-solid.gl-border-1.gl-border-gray-100.gl-rounded-base.gl-mt-5.gl-p-3.gl-text-center = enable_lfs_message diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml index 4024c5b77f6..16301789b65 100644 --- a/app/views/shared/issuable/_form.html.haml +++ b/app/views/shared/issuable/_form.html.haml @@ -64,9 +64,9 @@ for this project. - if issuable.new_record? - = form.submit "#{_('Create')} #{issuable.class.model_name.human.downcase}", class: 'gl-button btn btn-confirm gl-mr-2', data: { qa_selector: 'issuable_create_button' } + = form.submit "#{_('Create')} #{issuable.class.model_name.human.downcase}", class: 'gl-button btn btn-confirm gl-mr-2', data: { qa_selector: 'issuable_create_button', track_experiment: 'promote_mr_approvals_in_free', track_action: 'click_button', track_label: 'submit_mr', track_value: 0 } - else - = form.submit _('Save changes'), class: 'gl-button btn btn-confirm gl-mr-2' + = form.submit _('Save changes'), class: 'gl-button btn btn-confirm gl-mr-2', data: { track_experiment: 'promote_mr_approvals_in_free', track_action: 'click_button', track_label: 'submit_mr', track_value: 0 } - if issuable.new_record? = link_to _('Cancel'), polymorphic_path([@project, issuable.class]), class: 'btn gl-button btn-default' diff --git a/app/views/shared/labels/_form.html.haml b/app/views/shared/labels/_form.html.haml index 6f65dbe4811..9c17735cd14 100644 --- a/app/views/shared/labels/_form.html.haml +++ b/app/views/shared/labels/_form.html.haml @@ -5,30 +5,30 @@ .col-sm-2.col-form-label = f.label :title .col-sm-10 - = f.text_field :title, class: "form-control js-label-title qa-label-title", required: true, autofocus: true + = f.text_field :title, class: "gl-form-input form-control js-label-title qa-label-title", required: true, autofocus: true = render_if_exists 'shared/labels/create_label_help_text' .form-group.row .col-sm-2.col-form-label = f.label :description .col-sm-10 - = f.text_field :description, class: "form-control js-quick-submit qa-label-description" + = f.text_field :description, class: "gl-form-input form-control js-quick-submit qa-label-description" .form-group.row .col-sm-2.col-form-label - = f.label :color, "Background color" + = f.label :color, _("Background color") .col-sm-10 .input-group .input-group-prepend .input-group-text.label-color-preview - = f.text_field :color, class: "form-control qa-label-color" + = f.text_field :color, class: "gl-form-input form-control qa-label-color" .form-text.text-muted - Choose any color. + = _('Choose any color.') %br - Or you can choose one of the suggested colors below + = _("Or you can choose one of the suggested colors below") = render_suggested_colors .form-actions - if @label.persisted? = f.submit _('Save changes'), class: 'btn gl-button btn-confirm js-save-button' - else - = f.submit 'Create label', class: 'btn gl-button btn-confirm js-save-button qa-label-create-button' + = f.submit _('Create label'), class: 'btn gl-button btn-confirm js-save-button qa-label-create-button' = link_to _('Cancel'), back_path, class: 'btn gl-button btn-default btn-cancel' diff --git a/app/views/shared/web_hooks/_form.html.haml b/app/views/shared/web_hooks/_form.html.haml index 18912bf149f..5650f08b2a9 100644 --- a/app/views/shared/web_hooks/_form.html.haml +++ b/app/views/shared/web_hooks/_form.html.haml @@ -4,12 +4,14 @@ = form.label :url, s_('Webhooks|URL'), class: 'label-bold' = form.text_field :url, class: 'form-control gl-form-input', placeholder: 'http://example.com/trigger-ci.json' %p.form-text.text-muted - = s_('Webhooks|URL must be percent-encoded if neccessary.') + = s_('Webhooks|URL must be percent-encoded if it contains one or more special characters.') .form-group = form.label :token, s_('Webhooks|Secret token'), class: 'label-bold' = form.text_field :token, class: 'form-control gl-form-input', placeholder: '' %p.form-text.text-muted - = s_('Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header.') + - code_start = '<code>'.html_safe + - code_end = '</code>'.html_safe + = s_('Webhooks|Used to validate received payloads. Sent with the request in the %{code_start}X-Gitlab-Token HTTP%{code_end} header.').html_safe % { code_start: code_start, code_end: code_end } .form-group = form.label :url, s_('Webhooks|Trigger'), class: 'label-bold' %ul.list-unstyled.gl-ml-6 @@ -19,37 +21,37 @@ %strong= s_('Webhooks|Push events') = form.text_field :push_events_branch_filter, class: 'form-control gl-form-input', placeholder: 'Branch name or wildcard pattern to trigger on (leave blank for all)' %p.text-muted.gl-ml-1 - = s_('Webhooks|URL is triggered by a push to the repository') + = s_('Webhooks|Push to the repository.') %li = form.check_box :tag_push_events, class: 'form-check-input' = form.label :tag_push_events, class: 'list-label form-check-label gl-ml-1' do %strong= s_('Webhooks|Tag push events') %p.text-muted.gl-ml-1 - = s_('Webhooks|URL is triggered when a new tag is pushed to the repository') + = s_('Webhooks|A new tag is pushed to the repository.') %li = form.check_box :note_events, class: 'form-check-input' = form.label :note_events, class: 'list-label form-check-label gl-ml-1' do %strong= s_('Webhooks|Comments') %p.text-muted.gl-ml-1 - = s_('Webhooks|URL is triggered when someone adds a comment') + = s_('Webhooks|A comment is added to an issue.') %li = form.check_box :confidential_note_events, class: 'form-check-input' = form.label :confidential_note_events, class: 'list-label form-check-label gl-ml-1' do %strong= s_('Webhooks|Confidential comments') %p.text-muted.gl-ml-1 - = s_('Webhooks|URL is triggered when someone adds a comment on a confidential issue') + = s_('Webhooks|A comment is added to a confidential issue.') %li = form.check_box :issues_events, class: 'form-check-input' = form.label :issues_events, class: 'list-label form-check-label gl-ml-1' do %strong= s_('Webhooks|Issues events') %p.text-muted.gl-ml-1 - = s_('Webhooks|URL is triggered when an issue is created, updated, closed, or reopened') + = s_('Webhooks|An issue is created, updated, closed, or reopened.') %li = form.check_box :confidential_issues_events, class: 'form-check-input' = form.label :confidential_issues_events, class: 'list-label form-check-label gl-ml-1' do %strong= s_('Webhooks|Confidential issues events') %p.text-muted.gl-ml-1 - = s_('Webhooks|URL is triggered when a confidential issue is created, updated, closed, or reopened') + = s_('Webhooks|A confidential issue is created, updated, closed, or reopened.') - if @group = render_if_exists 'groups/hooks/member_events', form: form = render_if_exists 'groups/hooks/subgroup_events', form: form @@ -58,43 +60,43 @@ = form.label :merge_requests_events, class: 'list-label form-check-label gl-ml-1' do %strong= s_('Webhooks|Merge request events') %p.text-muted.gl-ml-1 - = s_('Webhooks|URL is triggered when a merge request is created, updated, or merged') + = s_('Webhooks|A merge request is created, updated, or merged.') %li = form.check_box :job_events, class: 'form-check-input' = form.label :job_events, class: 'list-label form-check-label gl-ml-1' do %strong= s_('Webhooks|Job events') %p.text-muted.gl-ml-1 - = s_('Webhooks|URL is triggered when the job status changes') + = s_("Webhooks|A job's status changes.") %li = form.check_box :pipeline_events, class: 'form-check-input' = form.label :pipeline_events, class: 'list-label form-check-label gl-ml-1' do %strong= s_('Webhooks|Pipeline events') %p.text-muted.gl-ml-1 - = s_('Webhooks|URL is triggered when the pipeline status changes') + = s_("Webhooks|A pipeline's status changes.") %li = form.check_box :wiki_page_events, class: 'form-check-input' = form.label :wiki_page_events, class: 'list-label form-check-label gl-ml-1' do %strong= s_('Webhooks|Wiki page events') %p.text-muted.gl-ml-1 - = s_('Webhooks|URL is triggered when a wiki page is created or updated') + = s_('Webhooks|A wiki page is created or updated.') %li = form.check_box :deployment_events, class: 'form-check-input' = form.label :deployment_events, class: 'list-label form-check-label gl-ml-1' do %strong= s_('Webhooks|Deployment events') %p.text-muted.gl-ml-1 - = s_('Webhooks|URL is triggered when a deployment starts, finishes, fails, or is canceled') + = s_('Webhooks|A deployment starts, finishes, fails, or is canceled.') %li = form.check_box :feature_flag_events, class: 'form-check-input' = form.label :feature_flag_events, class: 'list-label form-check-label gl-ml-1' do %strong= s_('Webhooks|Feature flag events') %p.text-muted.gl-ml-1 - = s_('Webhooks|URL is triggered when a feature flag is turned on or off') + = s_('Webhooks|A feature flag is turned on or off.') %li = form.check_box :releases_events, class: 'form-check-input' = form.label :releases_events, class: 'list-label form-check-label gl-ml-1' do %strong= s_('Webhooks|Releases events') %p.text-muted.gl-ml-1 - = s_('Webhooks|URL is triggered when a release is created or updated') + = s_('Webhooks|A release is created or updated.') .form-group = form.label :enable_ssl_verification, s_('Webhooks|SSL verification'), class: 'label-bold checkbox' .form-check diff --git a/app/views/shared/web_hooks/_index.html.haml b/app/views/shared/web_hooks/_index.html.haml index f1eef5d7f0f..5d07b0f95ab 100644 --- a/app/views/shared/web_hooks/_index.html.haml +++ b/app/views/shared/web_hooks/_index.html.haml @@ -11,4 +11,4 @@ = render 'shared/web_hooks/hook', hook: hook - else %p.text-center.gl-mt-3.gl-mb-3 - = _('No webhooks found, add one in the form above.') + = _('No webhooks enabled. Select trigger events above.') |