Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
c311ce331f
commit
e94d662e5a
30 changed files with 447 additions and 85 deletions
|
@ -25,7 +25,8 @@ export default class FilteredSearchBoards extends FilteredSearchManager {
|
|||
}
|
||||
|
||||
updateObject(path) {
|
||||
this.store.path = path.substr(1);
|
||||
const groupByParam = new URLSearchParams(window.location.search).get('group_by');
|
||||
this.store.path = `${path.substr(1)}${groupByParam ? `&group_by=${groupByParam}` : ''}`;
|
||||
|
||||
if (gon.features.boardsWithSwimlanes || gon.features.graphqlBoardLists) {
|
||||
boardsStore.updateFiltersUrl();
|
||||
|
|
|
@ -18,6 +18,13 @@ function onLoaded() {
|
|||
alert(res.responseJSON.error);
|
||||
};
|
||||
|
||||
AP.getLocation(function(location) {
|
||||
$('.js-jira-connect-sign-in').each(function() {
|
||||
var updatedLink = `${$(this).attr('href')}?return_to=${location}`;
|
||||
$(this).attr('href', updatedLink);
|
||||
});
|
||||
});
|
||||
|
||||
$('#add-subscription-form').on('submit', function(e) {
|
||||
var actionUrl = $(this).attr('action');
|
||||
e.preventDefault();
|
||||
|
|
|
@ -21,6 +21,7 @@ const createApolloProvider = appData => {
|
|||
},
|
||||
{
|
||||
typeDefs,
|
||||
assumeImmutableResults: true,
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
@ -1,16 +1,24 @@
|
|||
import { produce } from 'immer';
|
||||
import query from '../queries/app_data.query.graphql';
|
||||
|
||||
const hasSubmittedChangesResolver = (_, { input: { hasSubmittedChanges } }, { cache }) => {
|
||||
const { appData } = cache.readQuery({ query });
|
||||
cache.writeQuery({
|
||||
query,
|
||||
data: {
|
||||
const oldData = cache.readQuery({ query });
|
||||
|
||||
const data = produce(oldData, draftState => {
|
||||
// punctually modifying draftState as per immer docs upsets our linters
|
||||
return {
|
||||
...draftState,
|
||||
appData: {
|
||||
__typename: 'AppData',
|
||||
...appData,
|
||||
...draftState.appData,
|
||||
hasSubmittedChanges,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
cache.writeQuery({
|
||||
query,
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { produce } from 'immer';
|
||||
import submitContentChanges from '../../services/submit_content_changes';
|
||||
import savedContentMetaQuery from '../queries/saved_content_meta.query.graphql';
|
||||
|
||||
|
@ -14,14 +15,18 @@ const submitContentChangesResolver = (
|
|||
images,
|
||||
mergeRequestMeta,
|
||||
}).then(savedContentMeta => {
|
||||
cache.writeQuery({
|
||||
query: savedContentMetaQuery,
|
||||
data: {
|
||||
const data = produce(savedContentMeta, draftState => {
|
||||
return {
|
||||
savedContentMeta: {
|
||||
__typename: 'SavedContentMeta',
|
||||
...savedContentMeta,
|
||||
...draftState,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
cache.writeQuery({
|
||||
query: savedContentMetaQuery,
|
||||
data,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
@ -186,6 +186,7 @@ table {
|
|||
.checkbox {
|
||||
padding-left: $gl-spacing-scale-4;
|
||||
padding-right: 0;
|
||||
width: 1px;
|
||||
|
||||
+ td,
|
||||
+ th {
|
||||
|
@ -205,12 +206,20 @@ table {
|
|||
width: 10%;
|
||||
}
|
||||
|
||||
.description {
|
||||
max-width: 0;
|
||||
}
|
||||
|
||||
.identifier {
|
||||
width: 16%;
|
||||
}
|
||||
|
||||
.scanner {
|
||||
width: 15%;
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
.activity {
|
||||
width: 5%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -226,20 +226,20 @@
|
|||
@return calc(#{$original-padding + $original-border} - var(--ide-btn-hover-border-width, #{$original-border}));
|
||||
}
|
||||
|
||||
.btn:not(.btn-link):not([disabled]):hover {
|
||||
.btn:not(.gl-button):not(.btn-link):not([disabled]):hover {
|
||||
border-width: var(--ide-btn-hover-border-width, 1px);
|
||||
padding: calc-btn-hover-padding(6px) calc-btn-hover-padding(10px);
|
||||
}
|
||||
|
||||
.btn:not([disabled]).btn-sm:hover {
|
||||
.btn:not(.gl-button):not([disabled]).btn-sm:hover {
|
||||
padding: calc-btn-hover-padding(4px) calc-btn-hover-padding(10px);
|
||||
}
|
||||
|
||||
.btn:not([disabled]).btn-block:hover {
|
||||
.btn:not(.gl-button):not([disabled]).btn-block:hover {
|
||||
padding: calc-btn-hover-padding(6px) 0;
|
||||
}
|
||||
|
||||
.btn-default,
|
||||
.btn-default:not(.gl-button),
|
||||
.dropdown,
|
||||
.dropdown-menu-toggle {
|
||||
background-color: var(--ide-input-background, $white) !important;
|
||||
|
@ -258,7 +258,7 @@
|
|||
}
|
||||
|
||||
// In IDE, the only inverted buttons are `.btn-remove`
|
||||
.btn-inverted.btn-remove {
|
||||
.btn-inverted.btn-remove:not(.gl-button) {
|
||||
color: var(--ide-input-color, $red-500) !important;
|
||||
background-color: var(--ide-input-background, $white) !important;
|
||||
border-color: var(--ide-btn-default-border, $red-500);
|
||||
|
@ -277,17 +277,21 @@
|
|||
}
|
||||
}
|
||||
|
||||
.btn-default {
|
||||
// todo: remove this block after all default buttons have been migrated to gl-button
|
||||
.btn-default:not(.gl-button) {
|
||||
background-color: var(--ide-btn-default-background, $white) !important;
|
||||
border-color: var(--ide-btn-default-border, $border-color);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
border-color: var(--ide-btn-default-hover-border, $border-white-normal) !important;
|
||||
background-color: var(--ide-input-background, $white-normal) !important;
|
||||
background-color: var(--ide-btn-default-background, $white-normal) !important;
|
||||
}
|
||||
|
||||
&:active,
|
||||
.active {
|
||||
border-color: var(--ide-btn-default-hover-border, $border-white-normal) !important;
|
||||
background-color: var(--ide-input-background, $white-dark) !important;
|
||||
background-color: var(--ide-btn-default-background, $white-dark) !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -321,8 +325,9 @@
|
|||
border-color: var(--ide-dropdown-hover-background, $gray-100) !important;
|
||||
}
|
||||
|
||||
.btn-primary,
|
||||
.btn-info {
|
||||
// todo: remove this block after all primary/info buttons have been migrated to gl-button
|
||||
.btn-primary:not(.gl-button),
|
||||
.btn-info:not(.gl-button) {
|
||||
background-color: var(--ide-btn-primary-background, $blue-500);
|
||||
border-color: var(--ide-btn-primary-border, $blue-600) !important;
|
||||
|
||||
|
@ -339,7 +344,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
// todo: remove this block after all success buttons have been migrated to gl-button
|
||||
.btn-success:not(.gl-button) {
|
||||
background-color: var(--ide-btn-success-background, $green-500);
|
||||
border-color: var(--ide-btn-success-border, $green-600) !important;
|
||||
|
||||
|
@ -356,12 +362,70 @@
|
|||
}
|
||||
}
|
||||
|
||||
.btn[disabled] {
|
||||
// todo: remove this block after all disabled buttons have been migrated to gl-button
|
||||
.btn[disabled]:not(.gl-button) {
|
||||
background-color: var(--ide-btn-default-background, $gray-light) !important;
|
||||
border: 1px solid var(--ide-btn-disabled-border, $gray-100) !important;
|
||||
color: var(--ide-btn-disabled-color, $gl-text-color-disabled) !important;
|
||||
}
|
||||
|
||||
@function ide-btn-var($btn-type, $var-type, $value) {
|
||||
@return var(--ide-btn-#{$btn-type}-#{$var-type}, $value);
|
||||
}
|
||||
|
||||
@mixin ide-gl-button($btn-type, $bg-normal, $bg-hover, $bg-active, $border-normal, $border-hover, $border-focus, $border-active, $border-width-hover: 2px, $box-shadow-hover: $t-gray-a-08, $box-shadow-focus: 0 0 0 4px rgba($blue-500, 0.25)) {
|
||||
background-color: ide-btn-var($btn-type, background, $bg-normal);
|
||||
box-shadow: inset 0 0 0 1px ide-btn-var($btn-type, border, $border-normal);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: ide-btn-var($btn-type, background, $bg-hover);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
box-shadow: inset 0 0 0 ide-btn-var($btn-type, hover-border-width, $border-width-hover) ide-btn-var($btn-type, hover-border, $border-hover),
|
||||
0 2px 2px 0 $box-shadow-hover;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
box-shadow: inset 0 0 0 ide-btn-var($btn-type, hover-border-width, $border-width-hover) ide-btn-var($btn-type, hover-border, $border-focus),
|
||||
ide-btn-var($btn-type, focus-box-shadow, $box-shadow-focus);
|
||||
}
|
||||
|
||||
&:active:focus {
|
||||
background-color: ide-btn-var($btn-type, background, $bg-active);
|
||||
box-shadow: inset 0 0 0 ide-btn-var($btn-type, hover-border-width, $border-width-hover) ide-btn-var($btn-type, hover-border, $border-active),
|
||||
ide-btn-var($btn-type, focus-box-shadow, $box-shadow-focus);
|
||||
}
|
||||
}
|
||||
|
||||
.btn-default.gl-button.gl-button {
|
||||
color: var(--ide-input-color, $gl-text-color);
|
||||
|
||||
@include ide-gl-button(default, $white, $gray-50, $gray-100, $gray-200, $gray-300, $gray-300, $gray-400);
|
||||
}
|
||||
|
||||
.btn-success.gl-button.gl-button {
|
||||
@include ide-gl-button(success, $green-500, $green-600, $green-800, $green-600, $green-800, $green-800, $green-900);
|
||||
}
|
||||
|
||||
.btn-info.gl-button.gl-button,
|
||||
.btn-primary.gl-button.gl-button {
|
||||
@include ide-gl-button(primary, $blue-500, $blue-600, $blue-800, $blue-600, $blue-800, $blue-800, $blue-900);
|
||||
}
|
||||
|
||||
.btn-danger.btn-danger-secondary.gl-button.gl-button {
|
||||
color: var(--ide-input-color, $red-500);
|
||||
|
||||
@include ide-gl-button(danger-secondary, $white, $red-50, $red-100, $red-500, $red-600, $red-600, $red-700);
|
||||
}
|
||||
|
||||
.btn[disabled].gl-button.gl-button {
|
||||
color: var(--ide-btn-disabled-color, $gl-text-color-disabled);
|
||||
|
||||
@include ide-gl-button(disabled, $gray-10, $gray-10, $gray-10, $gray-100, $gray-100, $gray-100, $gray-100, 1px, transparent, transparent);
|
||||
}
|
||||
|
||||
.md table:not(.code) tbody {
|
||||
background-color: var(--ide-border-color, $white);
|
||||
}
|
||||
|
|
|
@ -20,20 +20,28 @@
|
|||
--ide-btn-default-background: transparent;
|
||||
--ide-btn-default-border: #bfbfbf;
|
||||
--ide-btn-default-hover-border: #d8d8d8;
|
||||
--ide-btn-default-hover-border-width: 2px;
|
||||
--ide-btn-default-focus-box-shadow: 0 0 0 1px #bfbfbf;
|
||||
|
||||
--ide-btn-primary-background: #1068bf;
|
||||
--ide-btn-primary-border: #428fdc;
|
||||
--ide-btn-primary-hover-border: #63a6e9;
|
||||
--ide-btn-primary-hover-border-width: 2px;
|
||||
--ide-btn-primary-focus-box-shadow: 0 0 0 1px #63a6e9;
|
||||
|
||||
--ide-btn-success-background: #217645;
|
||||
--ide-btn-success-border: #108548;
|
||||
--ide-btn-success-hover-border: #2da160;
|
||||
--ide-btn-success-hover-border-width: 2px;
|
||||
--ide-btn-success-focus-box-shadow: 0 0 0 1px #2da160;
|
||||
|
||||
--ide-btn-disabled-background: transparent;
|
||||
--ide-btn-disabled-border: rgba(223, 223, 223, 0.24);
|
||||
--ide-btn-disabled-hover-border: rgba(223, 223, 223, 0.24);
|
||||
--ide-btn-disabled-hover-border-width: 1px;
|
||||
--ide-btn-disabled-focus-box-shadow: 0 0 0 0 transparent;
|
||||
--ide-btn-disabled-color: rgba(145, 145, 145, 0.48);
|
||||
|
||||
--ide-btn-hover-border-width: 2px;
|
||||
|
||||
--ide-dropdown-background: #404040;
|
||||
--ide-dropdown-hover-background: #525252;
|
||||
|
||||
|
|
|
@ -18,22 +18,30 @@
|
|||
--ide-input-color: #fff;
|
||||
|
||||
--ide-btn-default-background: transparent;
|
||||
--ide-btn-default-border: var(--ide-input-border);
|
||||
--ide-btn-default-border: #d8d8d8;
|
||||
--ide-btn-default-hover-border: #d8d8d8;
|
||||
--ide-btn-default-hover-border-width: 2px;
|
||||
--ide-btn-default-focus-box-shadow: 0 0 0 1px #d8d8d8;
|
||||
|
||||
--ide-btn-primary-background: #1068bf;
|
||||
--ide-btn-primary-border: #428fdc;
|
||||
--ide-btn-primary-hover-border: #63a6e9;
|
||||
--ide-btn-primary-hover-border-width: 2px;
|
||||
--ide-btn-primary-focus-box-shadow: 0 0 0 1px #63a6e9;
|
||||
|
||||
--ide-btn-success-background: #217645;
|
||||
--ide-btn-success-border: #108548;
|
||||
--ide-btn-success-hover-border: #2da160;
|
||||
--ide-btn-success-hover-border-width: 2px;
|
||||
--ide-btn-success-focus-box-shadow: 0 0 0 1px #2da160;
|
||||
|
||||
--ide-btn-disabled-background: transparent;
|
||||
--ide-btn-disabled-border: rgba(223, 223, 223, 0.24);
|
||||
--ide-btn-disabled-hover-border: rgba(223, 223, 223, 0.24);
|
||||
--ide-btn-disabled-hover-border-width: 1px;
|
||||
--ide-btn-disabled-focus-box-shadow: transparent;
|
||||
--ide-btn-disabled-color: rgba(145, 145, 145, 0.48);
|
||||
|
||||
--ide-btn-hover-border-width: 2px;
|
||||
|
||||
--ide-dropdown-background: #004c61;
|
||||
--ide-dropdown-hover-background: #00617a;
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ $atlaskit-border-color: #dfe1e6;
|
|||
padding-top: $gl-padding-4;
|
||||
|
||||
.ak-button {
|
||||
align-items: center;
|
||||
height: auto;
|
||||
margin-left: $btn-margin-5;
|
||||
}
|
||||
|
@ -20,6 +21,74 @@ $atlaskit-border-color: #dfe1e6;
|
|||
}
|
||||
}
|
||||
|
||||
$header-height: 40px;
|
||||
|
||||
.jira-connect-header {
|
||||
border-bottom: 1px solid $gray-100;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: $header-height;
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.jira-connect-user {
|
||||
float: right;
|
||||
position: relative;
|
||||
top: -30px;
|
||||
}
|
||||
|
||||
.jira-connect-app {
|
||||
margin-top: $header-height;
|
||||
max-width: 600px;
|
||||
padding-top: 48px;
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.gl-mt-5 {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.heading-with-border {
|
||||
border-bottom: 1px solid $gray-100;
|
||||
display: inline-block;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: currentColor;
|
||||
|
||||
&.s16 {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.ak-field-group label {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.ak-button__appearance-primary {
|
||||
&:hover {
|
||||
color: $white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
svg {
|
||||
align-self: center;
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.subscriptions {
|
||||
tbody {
|
||||
tr {
|
||||
|
@ -31,3 +100,11 @@ $atlaskit-border-color: #dfe1e6;
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty-subscriptions {
|
||||
color: $gray-900;
|
||||
}
|
||||
|
||||
.browser-limitations-notice {
|
||||
margin-top: 32px;
|
||||
}
|
||||
|
|
13
app/assets/stylesheets/page_bundles/jira_connect_users.scss
Normal file
13
app/assets/stylesheets/page_bundles/jira_connect_users.scss
Normal file
|
@ -0,0 +1,13 @@
|
|||
@import 'mixins_and_variables_and_functions';
|
||||
|
||||
.jira-connect-users-container {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: px-to-rem(350px);
|
||||
}
|
||||
|
||||
.devise-layout-html body .navless-container {
|
||||
@include media-breakpoint-down(xs) {
|
||||
padding-top: 65px;
|
||||
}
|
||||
}
|
|
@ -1,10 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class JiraConnect::EventsController < JiraConnect::ApplicationController
|
||||
# See https://developer.atlassian.com/cloud/jira/software/app-descriptor/#lifecycle
|
||||
|
||||
skip_before_action :verify_atlassian_jwt!, only: :installed
|
||||
before_action :verify_qsh_claim!, only: :uninstalled
|
||||
|
||||
def installed
|
||||
return head :ok if atlassian_jwt_valid?
|
||||
|
||||
installation = JiraConnectInstallation.new(install_params)
|
||||
|
||||
if installation.save
|
||||
|
|
11
app/controllers/jira_connect/users_controller.rb
Normal file
11
app/controllers/jira_connect/users_controller.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class JiraConnect::UsersController < ApplicationController
|
||||
feature_category :integrations
|
||||
|
||||
layout 'devise_experimental_onboarding_issues'
|
||||
|
||||
def show
|
||||
@jira_app_link = params.delete(:return_to)
|
||||
end
|
||||
end
|
|
@ -3,7 +3,7 @@
|
|||
module ExternalLinkHelper
|
||||
def external_link(body, url, options = {})
|
||||
link_to url, { target: '_blank', rel: 'noopener noreferrer' }.merge(options) do
|
||||
"#{body} #{icon('external-link')}".html_safe
|
||||
"#{body} #{sprite_icon('external-link')}".html_safe
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,37 +1,61 @@
|
|||
%h1
|
||||
GitLab for Jira Configuration
|
||||
%header.jira-connect-header
|
||||
= brand_header_logo
|
||||
|
||||
%form#add-subscription-form.subscription-form{ action: jira_connect_subscriptions_path }
|
||||
.ak-field-group
|
||||
%label
|
||||
Namespace
|
||||
.jira-connect-user
|
||||
- if current_user
|
||||
- user_link = link_to(current_user.to_reference, user_path(current_user), target: '_blank', rel: 'noopener noreferrer')
|
||||
= _('Signed in to GitLab as %{user_link}').html_safe % { user_link: user_link }
|
||||
- elsif @subscriptions.present?
|
||||
= link_to _('Sign in to GitLab'), jira_connect_users_path, target: '_blank', rel: 'noopener noreferrer', class: 'js-jira-connect-sign-in'
|
||||
|
||||
.ak-field-group.field-group-input
|
||||
%input#namespace-input.ak-field-text{ type: 'text', required: true }
|
||||
%button.ak-button.ak-button__appearance-primary{ type: 'submit' }
|
||||
Link namespace to Jira
|
||||
.jira-connect-app
|
||||
%h1
|
||||
GitLab for Jira Configuration
|
||||
|
||||
%table.subscriptions
|
||||
%thead
|
||||
%tr
|
||||
%th Namespace
|
||||
%th Added
|
||||
%th
|
||||
%tbody
|
||||
- @subscriptions.each do |subscription|
|
||||
%tr
|
||||
%td= subscription.namespace.full_path
|
||||
%td= subscription.created_at
|
||||
%td= link_to 'Remove', jira_connect_subscription_path(subscription), class: 'remove-subscription'
|
||||
- if current_user.blank? && @subscriptions.empty?
|
||||
%h2.heading-with-border Sign in to GitLab.com to get started.
|
||||
|
||||
%p
|
||||
%strong Browser limitations:
|
||||
Adding a namespace currently works only in browsers that allow cross site cookies. Please make sure to use
|
||||
%a{ href: 'https://www.mozilla.org/en-US/firefox/', target: '_blank', rel: 'noopener noreferrer' } Firefox
|
||||
or
|
||||
%a{ href: 'https://www.google.com/chrome/index.html', target: '_blank', rel: 'noopener noreferrer' } Google Chrome
|
||||
or enable cross-site cookies in your browser when adding a namespace.
|
||||
%a{ href: 'https://gitlab.com/gitlab-org/gitlab/-/issues/263509', target: '_blank', rel: 'noopener noreferrer' } Learn more
|
||||
.gl-mt-5
|
||||
= external_link _('Sign in to GitLab'), jira_connect_users_path, class: 'ak-button ak-button__appearance-primary js-jira-connect-sign-in'
|
||||
|
||||
.gl-mt-5
|
||||
%p Note: this integration only works with accounts on GitLab.com (SaaS).
|
||||
- else
|
||||
%form#add-subscription-form.subscription-form{ action: jira_connect_subscriptions_path }
|
||||
.ak-field-group
|
||||
%label
|
||||
GitLab namespace
|
||||
|
||||
.ak-field-group.field-group-input
|
||||
%input#namespace-input.ak-field-text{ type: 'text', required: true, placeholder: 'e.g. "MyCompany" or "MyCompany/GroupName"' }
|
||||
%button.ak-button.ak-button__appearance-primary{ type: 'submit' }
|
||||
Link namespace to Jira
|
||||
|
||||
- if @subscriptions.present?
|
||||
%table.subscriptions
|
||||
%thead
|
||||
%tr
|
||||
%th Namespace
|
||||
%th Added
|
||||
%th
|
||||
%tbody
|
||||
- @subscriptions.each do |subscription|
|
||||
%tr
|
||||
%td= subscription.namespace.full_path
|
||||
%td= subscription.created_at
|
||||
%td= link_to 'Remove', jira_connect_subscription_path(subscription), class: 'remove-subscription'
|
||||
- else
|
||||
%h4.empty-subscriptions
|
||||
No linked namespaces
|
||||
|
||||
%p.browser-limitations-notice
|
||||
%strong Browser limitations:
|
||||
Adding a namespace currently works only in browsers that allow cross site cookies. Please make sure to use
|
||||
%a{ href: 'https://www.mozilla.org/en-US/firefox/', target: '_blank', rel: 'noopener noreferrer' } Firefox
|
||||
or
|
||||
%a{ href: 'https://www.google.com/chrome/index.html', target: '_blank', rel: 'noopener noreferrer' } Google Chrome
|
||||
or enable cross-site cookies in your browser when adding a namespace.
|
||||
%a{ href: 'https://gitlab.com/gitlab-org/gitlab/-/issues/263509', target: '_blank', rel: 'noopener noreferrer' } Learn more
|
||||
|
||||
= page_specific_javascript_tag('jira_connect.js')
|
||||
- add_page_specific_style 'page_bundles/jira_connect'
|
||||
|
|
12
app/views/jira_connect/users/show.html.haml
Normal file
12
app/views/jira_connect/users/show.html.haml
Normal file
|
@ -0,0 +1,12 @@
|
|||
.jira-connect-users-container.gl-text-center
|
||||
- user_link = link_to(current_user.to_reference, user_path(current_user), target: '_blank', rel: 'noopener noreferrer')
|
||||
%h2= _('You are signed into GitLab as %{user_link}').html_safe % { user_link: user_link }
|
||||
|
||||
%p= s_('Integrations|You can now close this window and return to the GitLab for Jira application.')
|
||||
|
||||
- if @jira_app_link
|
||||
%p= external_link s_('Integrations|Return to GitLab for Jira'), @jira_app_link, class: 'btn btn-success'
|
||||
|
||||
%p= link_to _('Sign out'), destroy_user_session_path, method: :post
|
||||
|
||||
- add_page_specific_style 'page_bundles/jira_connect_users'
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix Jira Connect App update webhooks
|
||||
merge_request: 45151
|
||||
author:
|
||||
type: fixed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add user sign in indicator to Jira connect app
|
||||
merge_request: 42628
|
||||
author:
|
||||
type: changed
|
|
@ -182,6 +182,7 @@ module Gitlab
|
|||
config.assets.precompile << "page_bundles/ide.css"
|
||||
config.assets.precompile << "page_bundles/issues_list.css"
|
||||
config.assets.precompile << "page_bundles/jira_connect.css"
|
||||
config.assets.precompile << "page_bundles/jira_connect_users.css"
|
||||
config.assets.precompile << "page_bundles/merge_conflicts.css"
|
||||
config.assets.precompile << "page_bundles/merge_requests.css"
|
||||
config.assets.precompile << "page_bundles/milestone.css"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
name: global_default_branch_name
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35269
|
||||
rollout_issue_url:
|
||||
group: group::source code
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
name: mr_commit_neighbor_nav
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28596
|
||||
rollout_issue_url:
|
||||
group: group::source code
|
||||
type: development
|
||||
default_enabled: true
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace :jira_connect do
|
|||
root to: proc { [404, {}, ['']] }, as: 'base'
|
||||
|
||||
get 'app_descriptor' => 'app_descriptor#show'
|
||||
get :users, to: 'users#show'
|
||||
|
||||
namespace :events do
|
||||
post 'installed'
|
||||
|
|
|
@ -385,8 +385,8 @@ end
|
|||
GitLab's GraphQL API is versionless, which means we maintain backwards
|
||||
compatibility with older versions of the API with every change. Rather
|
||||
than removing a field or [enum value](#enums), we need to _deprecate_ it instead.
|
||||
In future, GitLab
|
||||
[may remove deprecated parts of the schema](https://gitlab.com/gitlab-org/gitlab/-/issues/32292).
|
||||
The deprecated parts of the schema can then be removed in a future release
|
||||
in accordance with [GitLab's deprecation process](../api/graphql/index.md#deprecation-process).
|
||||
|
||||
Fields and enum values are deprecated using the `deprecated` property.
|
||||
The value of the property is a `Hash` of:
|
||||
|
|
|
@ -14149,6 +14149,9 @@ msgstr ""
|
|||
msgid "Integrations|Projects using custom settings will not be impacted unless the project owner chooses to use instance-level defaults."
|
||||
msgstr ""
|
||||
|
||||
msgid "Integrations|Return to GitLab for Jira"
|
||||
msgstr ""
|
||||
|
||||
msgid "Integrations|Save settings?"
|
||||
msgstr ""
|
||||
|
||||
|
@ -14173,6 +14176,9 @@ msgstr ""
|
|||
msgid "Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created."
|
||||
msgstr ""
|
||||
|
||||
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
|
||||
msgstr ""
|
||||
|
||||
msgid "Interested parties can even contribute by pushing commits if they want to."
|
||||
msgstr ""
|
||||
|
||||
|
@ -24241,6 +24247,9 @@ msgstr ""
|
|||
msgid "Sign in to \"%{group_name}\""
|
||||
msgstr ""
|
||||
|
||||
msgid "Sign in to GitLab"
|
||||
msgstr ""
|
||||
|
||||
msgid "Sign in using smart card"
|
||||
msgstr ""
|
||||
|
||||
|
@ -24286,6 +24295,9 @@ msgstr ""
|
|||
msgid "Signed in"
|
||||
msgstr ""
|
||||
|
||||
msgid "Signed in to GitLab as %{user_link}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Signed in with %{authentication} authentication"
|
||||
msgstr ""
|
||||
|
||||
|
@ -29859,6 +29871,9 @@ msgstr ""
|
|||
msgid "You are receiving this message because you are a GitLab administrator for %{url}."
|
||||
msgstr ""
|
||||
|
||||
msgid "You are signed into GitLab as %{user_link}"
|
||||
msgstr ""
|
||||
|
||||
msgid "You are trying to upload something other than an image. Please upload a .png, .jpg, .jpeg, .gif, .bmp, .tiff or .ico."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
"@babel/preset-env": "^7.10.1",
|
||||
"@gitlab/at.js": "1.5.5",
|
||||
"@gitlab/svgs": "1.171.0",
|
||||
"@gitlab/ui": "21.30.1",
|
||||
"@gitlab/ui": "21.32.1",
|
||||
"@gitlab/visual-review-tools": "1.6.1",
|
||||
"@rails/actioncable": "^6.0.3-3",
|
||||
"@rails/ujs": "^6.0.3-2",
|
||||
|
|
|
@ -4,14 +4,20 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe JiraConnect::EventsController do
|
||||
describe '#installed' do
|
||||
subject do
|
||||
post :installed, params: {
|
||||
clientKey: '1234',
|
||||
sharedSecret: 'secret',
|
||||
let(:client_key) { '1234' }
|
||||
let(:shared_secret) { 'secret' }
|
||||
let(:params) do
|
||||
{
|
||||
clientKey: client_key,
|
||||
sharedSecret: shared_secret,
|
||||
baseUrl: 'https://test.atlassian.net'
|
||||
}
|
||||
end
|
||||
|
||||
subject do
|
||||
post :installed, params: params
|
||||
end
|
||||
|
||||
it 'saves the jira installation data' do
|
||||
expect { subject }.to change { JiraConnectInstallation.count }.by(1)
|
||||
end
|
||||
|
@ -19,15 +25,15 @@ RSpec.describe JiraConnect::EventsController do
|
|||
it 'saves the correct values' do
|
||||
subject
|
||||
|
||||
installation = JiraConnectInstallation.find_by_client_key('1234')
|
||||
installation = JiraConnectInstallation.find_by_client_key(client_key)
|
||||
|
||||
expect(installation.shared_secret).to eq('secret')
|
||||
expect(installation.shared_secret).to eq(shared_secret)
|
||||
expect(installation.base_url).to eq('https://test.atlassian.net')
|
||||
end
|
||||
|
||||
context 'client key already exists' do
|
||||
it 'returns 422' do
|
||||
create(:jira_connect_installation, client_key: '1234')
|
||||
create(:jira_connect_installation, client_key: client_key)
|
||||
|
||||
subject
|
||||
|
||||
|
@ -35,6 +41,23 @@ RSpec.describe JiraConnect::EventsController do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when it is a version update and shared_secret is not sent' do
|
||||
let(:params) do
|
||||
{
|
||||
clientKey: client_key,
|
||||
baseUrl: 'https://test.atlassian.net'
|
||||
}
|
||||
end
|
||||
|
||||
it 'validates the JWT token in authorization header and returns 200 without creating a new installation' do
|
||||
create(:jira_connect_installation, client_key: client_key, shared_secret: shared_secret)
|
||||
request.headers["Authorization"] = "Bearer #{Atlassian::Jwt.encode({ iss: client_key }, shared_secret)}"
|
||||
|
||||
expect { subject }.not_to change { JiraConnectInstallation.count }
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#uninstalled' do
|
||||
let!(:installation) { create(:jira_connect_installation) }
|
||||
let(:qsh) { Atlassian::Jwt.create_query_string_hash('https://gitlab.test/events/uninstalled', 'POST', 'https://gitlab.test') }
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
import appDataQuery from '~/static_site_editor/graphql/queries/app_data.query.graphql';
|
||||
import hasSubmittedChanges from '~/static_site_editor/graphql/resolvers/has_submitted_changes';
|
||||
|
||||
describe('static_site_editor/graphql/resolvers/has_submitted_changes', () => {
|
||||
it('updates the cache with the data passed in input', () => {
|
||||
const cachedData = { appData: { original: 'foo' } };
|
||||
const newValue = { input: { hasSubmittedChanges: true } };
|
||||
|
||||
const cache = {
|
||||
readQuery: jest.fn().mockReturnValue(cachedData),
|
||||
writeQuery: jest.fn(),
|
||||
};
|
||||
hasSubmittedChanges(null, newValue, { cache });
|
||||
|
||||
expect(cache.readQuery).toHaveBeenCalledWith({ query: appDataQuery });
|
||||
expect(cache.writeQuery).toHaveBeenCalledWith({
|
||||
query: appDataQuery,
|
||||
data: {
|
||||
appData: {
|
||||
__typename: 'AppData',
|
||||
original: 'foo',
|
||||
hasSubmittedChanges: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
|
@ -6,12 +6,15 @@ RSpec.describe ExternalLinkHelper do
|
|||
include IconsHelper
|
||||
|
||||
it 'returns external link with icon' do
|
||||
expect(external_link('https://gitlab.com', 'https://gitlab.com').to_s)
|
||||
.to eq('<a target="_blank" rel="noopener noreferrer" href="https://gitlab.com">https://gitlab.com <i aria-hidden="true" data-hidden="true" class="fa fa-external-link"></i></a>')
|
||||
link = external_link('https://gitlab.com', 'https://gitlab.com').to_s
|
||||
expect(link).to start_with('<a target="_blank" rel="noopener noreferrer" href="https://gitlab.com">https://gitlab.com')
|
||||
expect(link).to include('data-testid="external-link-icon"')
|
||||
end
|
||||
|
||||
it 'allows options when creating external link with icon' do
|
||||
expect(external_link('https://gitlab.com', 'https://gitlab.com', { "data-foo": "bar", class: "externalLink" }).to_s)
|
||||
.to eq('<a target="_blank" rel="noopener noreferrer" data-foo="bar" class="externalLink" href="https://gitlab.com">https://gitlab.com <i aria-hidden="true" data-hidden="true" class="fa fa-external-link"></i></a>')
|
||||
link = external_link('https://gitlab.com', 'https://gitlab.com', { "data-foo": "bar", class: "externalLink" }).to_s
|
||||
|
||||
expect(link).to start_with('<a target="_blank" rel="noopener noreferrer" data-foo="bar" class="externalLink" href="https://gitlab.com">https://gitlab.com')
|
||||
expect(link).to include('data-testid="external-link-icon"')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe 'jira_connect/subscriptions/index.html.haml' do
|
||||
let(:user) { build_stubbed(:user) }
|
||||
|
||||
before do
|
||||
allow(view).to receive(:current_user).and_return(user)
|
||||
assign(:subscriptions, [])
|
||||
end
|
||||
|
||||
context 'when the user is signed in' do
|
||||
it 'shows link to user profile' do
|
||||
render
|
||||
|
||||
expect(rendered).to have_link(user.to_reference)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user is not signed in' do
|
||||
let(:user) { nil }
|
||||
|
||||
it 'shows "Sign in" link' do
|
||||
render
|
||||
|
||||
expect(rendered).to have_link('Sign in to GitLab')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -866,10 +866,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.171.0.tgz#abc3092bf804f0898301626130e0f3231834924a"
|
||||
integrity sha512-TPfdqIxQDda+0CQHhb9XdF50lmqDmADu6yT8R4oZi6BoUtWLdiHbyFt+RnVU6t7EmjIKicNAii7Ga+f2ljCfUA==
|
||||
|
||||
"@gitlab/ui@21.30.1":
|
||||
version "21.30.1"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-21.30.1.tgz#561bd10c5264e48d16be4c5706827f40ec31286f"
|
||||
integrity sha512-JdLA8x7fOk1qgsqBeNhlmg1VTJIrl+ECWea8whoyqWnI95GPuiM5ZSnehZHA6FoNwB9n/u1GnVSLCHcqvHZW0w==
|
||||
"@gitlab/ui@21.32.1":
|
||||
version "21.32.1"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-21.32.1.tgz#8ed29de1093afc36ea31d3cf93b047bcfe0c6543"
|
||||
integrity sha512-ZZi/rJfDTXMytX1vNV2FU+l0fG6J7V2+1M7CWIkxdPIPVJ1LopkkfwnbBP29zrwBFBmguXcPoRfTjGa2oSNdbg==
|
||||
dependencies:
|
||||
"@babel/standalone" "^7.0.0"
|
||||
"@gitlab/vue-toasted" "^1.3.0"
|
||||
|
|
Loading…
Reference in a new issue