used respond_to formats for persisting flash messages instead
This commit is contained in:
parent
f42397d19a
commit
a16547e5c2
|
@ -1,46 +0,0 @@
|
||||||
import _ from 'underscore';
|
|
||||||
import createFlash from '~/flash';
|
|
||||||
import AccessorUtilities from '~/lib/utils/accessor';
|
|
||||||
|
|
||||||
const FLASH_QUEUE_KEY = 'flash-key';
|
|
||||||
|
|
||||||
export function popFlashMessage() {
|
|
||||||
const page = $('body').attr('data-page');
|
|
||||||
let savedFlashMessages;
|
|
||||||
let returnVal = false;
|
|
||||||
|
|
||||||
if (!page) {
|
|
||||||
return returnVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AccessorUtilities.isLocalStorageAccessSafe()) {
|
|
||||||
savedFlashMessages = JSON.parse(window.localStorage.getItem(FLASH_QUEUE_KEY));
|
|
||||||
const queuedMessage = _.findWhere(savedFlashMessages, { bodyData: page });
|
|
||||||
if (queuedMessage) {
|
|
||||||
const queuedMessageIndex = _.findIndex(savedFlashMessages, { bodyData: page });
|
|
||||||
createFlash(queuedMessage.message, queuedMessage.type);
|
|
||||||
savedFlashMessages.splice(queuedMessageIndex, 1);
|
|
||||||
window.localStorage.setItem(FLASH_QUEUE_KEY, JSON.stringify(savedFlashMessages));
|
|
||||||
}
|
|
||||||
returnVal = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function saveFlashMessage(bodyData, message, type) {
|
|
||||||
let savedFlashMessages;
|
|
||||||
|
|
||||||
if (AccessorUtilities.isLocalStorageAccessSafe()) {
|
|
||||||
savedFlashMessages = JSON.parse(window.localStorage.getItem(FLASH_QUEUE_KEY));
|
|
||||||
if (!savedFlashMessages) {
|
|
||||||
savedFlashMessages = [];
|
|
||||||
}
|
|
||||||
savedFlashMessages.push({
|
|
||||||
bodyData,
|
|
||||||
message,
|
|
||||||
type,
|
|
||||||
});
|
|
||||||
window.localStorage.setItem(FLASH_QUEUE_KEY, JSON.stringify(savedFlashMessages));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -33,7 +33,6 @@ import './milestone_select';
|
||||||
import './projects_dropdown';
|
import './projects_dropdown';
|
||||||
import './render_gfm';
|
import './render_gfm';
|
||||||
import initBreadcrumbs from './breadcrumb';
|
import initBreadcrumbs from './breadcrumb';
|
||||||
import { popFlashMessage } from './lib/utils/flash_queue';
|
|
||||||
|
|
||||||
import initDispatcher from './dispatcher';
|
import initDispatcher from './dispatcher';
|
||||||
|
|
||||||
|
@ -263,5 +262,4 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
initDispatcher();
|
initDispatcher();
|
||||||
popFlashMessage();
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
<script>
|
<script>
|
||||||
import axios from '~/lib/utils/axios_utils';
|
import axios from '~/lib/utils/axios_utils';
|
||||||
import createFlash from '~/flash';
|
import createFlash from '~/flash';
|
||||||
import { saveFlashMessage } from '~/lib/utils/flash_queue';
|
|
||||||
import GlModal from '~/vue_shared/components/gl_modal.vue';
|
import GlModal from '~/vue_shared/components/gl_modal.vue';
|
||||||
import { redirectTo } from '~/lib/utils/url_utility';
|
|
||||||
import { s__, sprintf } from '~/locale';
|
import { s__, sprintf } from '~/locale';
|
||||||
|
import { visitUrl } from '~/lib/utils/url_utility';
|
||||||
import eventHub from '../event_hub';
|
import eventHub from '../event_hub';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -27,20 +26,17 @@
|
||||||
},
|
},
|
||||||
text() {
|
text() {
|
||||||
return s__(`Milestones|Promoting this milestone will make it available for all projects inside the group.
|
return s__(`Milestones|Promoting this milestone will make it available for all projects inside the group.
|
||||||
Existing project milestones with the same name will be merged.
|
Existing project milestones with the same title will be merged.
|
||||||
This action cannot be reversed.`);
|
This action cannot be reversed.`);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
eventHub.$emit('promoteMilestoneModal.requestStarted', this.url);
|
eventHub.$emit('promoteMilestoneModal.requestStarted', this.url);
|
||||||
return axios.post(this.url)
|
return axios.post(this.url, { params: { format: 'json' } })
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
eventHub.$emit('promoteMilestoneModal.requestFinished', { milestoneUrl: this.url, successful: true });
|
eventHub.$emit('promoteMilestoneModal.requestFinished', { milestoneUrl: this.url, successful: true });
|
||||||
const responseURL = new URL(response.request.responseURL);
|
visitUrl(response.data.url);
|
||||||
const bodyData = responseURL.searchParams.get('body_data');
|
|
||||||
saveFlashMessage(bodyData, `${this.milestoneTitle} promoted to group milestone`, 'notice');
|
|
||||||
redirectTo(`${responseURL.protocol}//${responseURL.host}${responseURL.pathname}`);
|
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
eventHub.$emit('promoteMilestoneModal.requestFinished', { milestoneUrl: this.url, successful: false });
|
eventHub.$emit('promoteMilestoneModal.requestFinished', { milestoneUrl: this.url, successful: false });
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
<script>
|
<script>
|
||||||
import axios from '~/lib/utils/axios_utils';
|
import axios from '~/lib/utils/axios_utils';
|
||||||
import { saveFlashMessage } from '~/lib/utils/flash_queue';
|
|
||||||
import createFlash from '~/flash';
|
import createFlash from '~/flash';
|
||||||
import GlModal from '~/vue_shared/components/gl_modal.vue';
|
import GlModal from '~/vue_shared/components/gl_modal.vue';
|
||||||
import { redirectTo } from '~/lib/utils/url_utility';
|
|
||||||
import { s__, sprintf } from '~/locale';
|
import { s__, sprintf } from '~/locale';
|
||||||
|
import { visitUrl } from '~/lib/utils/url_utility';
|
||||||
import eventHub from '../event_hub';
|
import eventHub from '../event_hub';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -32,7 +31,7 @@
|
||||||
computed: {
|
computed: {
|
||||||
text() {
|
text() {
|
||||||
return s__(`Milestones|Promoting this label will make it available for all projects inside the group.
|
return s__(`Milestones|Promoting this label will make it available for all projects inside the group.
|
||||||
Existing project labels with the same name will be merged. This action cannot be reversed.`);
|
Existing project labels with the same title will be merged. This action cannot be reversed.`);
|
||||||
},
|
},
|
||||||
title() {
|
title() {
|
||||||
const label = `<span
|
const label = `<span
|
||||||
|
@ -48,13 +47,10 @@
|
||||||
methods: {
|
methods: {
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
eventHub.$emit('promoteLabelModal.requestStarted', this.url);
|
eventHub.$emit('promoteLabelModal.requestStarted', this.url);
|
||||||
return axios.post(this.url)
|
return axios.post(this.url, { params: { format: 'json' } })
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
eventHub.$emit('promoteLabelModal.requestFinished', { labelUrl: this.url, successful: true });
|
eventHub.$emit('promoteLabelModal.requestFinished', { labelUrl: this.url, successful: true });
|
||||||
const responseURL = new URL(response.request.responseURL);
|
visitUrl(response.data.url);
|
||||||
const bodyData = responseURL.searchParams.get('body_data');
|
|
||||||
saveFlashMessage(bodyData, `${this.labelTitle} promoted to group label`, 'notice');
|
|
||||||
redirectTo(`${responseURL.protocol}//${responseURL.host}${responseURL.pathname}`);
|
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
eventHub.$emit('promoteLabelModal.requestFinished', { labelUrl: this.url, successful: false });
|
eventHub.$emit('promoteLabelModal.requestFinished', { labelUrl: this.url, successful: false });
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
class Projects::LabelsController < Projects::ApplicationController
|
class Projects::LabelsController < Projects::ApplicationController
|
||||||
include ToggleSubscriptionAction
|
include ToggleSubscriptionAction
|
||||||
include FlashHelper
|
|
||||||
|
|
||||||
before_action :check_issuables_available!
|
before_action :check_issuables_available!
|
||||||
before_action :label, only: [:edit, :update, :destroy, :promote]
|
before_action :label, only: [:edit, :update, :destroy, :promote]
|
||||||
|
@ -113,11 +112,14 @@ class Projects::LabelsController < Projects::ApplicationController
|
||||||
begin
|
begin
|
||||||
return render_404 unless promote_service.execute(@label)
|
return render_404 unless promote_service.execute(@label)
|
||||||
|
|
||||||
|
flash[:notice] = "#{@label.title} promoted to group label."
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
redirect_to(project_labels_path(@project, body_data: get_body_data_page(project_labels_path(@project))), status: 303)
|
redirect_to(project_labels_path(@project), status: 303)
|
||||||
|
end
|
||||||
|
format.json do
|
||||||
|
render json: { url: project_labels_path(@project) }
|
||||||
end
|
end
|
||||||
format.js
|
|
||||||
end
|
end
|
||||||
rescue ActiveRecord::RecordInvalid => e
|
rescue ActiveRecord::RecordInvalid => e
|
||||||
Gitlab::AppLogger.error "Failed to promote label \"#{@label.title}\" to group label"
|
Gitlab::AppLogger.error "Failed to promote label \"#{@label.title}\" to group label"
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
class Projects::MilestonesController < Projects::ApplicationController
|
class Projects::MilestonesController < Projects::ApplicationController
|
||||||
include MilestoneActions
|
include MilestoneActions
|
||||||
include FlashHelper
|
|
||||||
|
|
||||||
before_action :check_issuables_available!
|
before_action :check_issuables_available!
|
||||||
before_action :milestone, only: [:edit, :update, :destroy, :show, :merge_requests, :participants, :labels, :promote]
|
before_action :milestone, only: [:edit, :update, :destroy, :show, :merge_requests, :participants, :labels, :promote]
|
||||||
|
@ -72,7 +71,16 @@ class Projects::MilestonesController < Projects::ApplicationController
|
||||||
|
|
||||||
def promote
|
def promote
|
||||||
Milestones::PromoteService.new(project, current_user).execute(milestone)
|
Milestones::PromoteService.new(project, current_user).execute(milestone)
|
||||||
redirect_to project_milestones_path(project, body_data: get_body_data_page(project_milestones_path(project))), status: 303
|
|
||||||
|
flash[:notice] = "#{milestone.title} promoted to group milestone"
|
||||||
|
respond_to do |format|
|
||||||
|
format.html do
|
||||||
|
redirect_to project_milestones_path(project)
|
||||||
|
end
|
||||||
|
format.json do
|
||||||
|
render json: { url: project_milestones_path(project) }
|
||||||
|
end
|
||||||
|
end
|
||||||
rescue Milestones::PromoteService::PromoteMilestoneError => error
|
rescue Milestones::PromoteService::PromoteMilestoneError => error
|
||||||
redirect_to milestone, alert: error.message
|
redirect_to milestone, alert: error.message
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
module FlashHelper
|
|
||||||
def get_body_data_page(path)
|
|
||||||
return unless path.empty? == false
|
|
||||||
|
|
||||||
path_controller = Rails.application.routes.recognize_path(path)
|
|
||||||
[path_controller[:controller].split('/'), path_controller[:action]].compact.join(':')
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -32,7 +32,8 @@
|
||||||
milestone_title: @milestone.title,
|
milestone_title: @milestone.title,
|
||||||
url: promote_project_milestone_path(@milestone.project, @milestone),
|
url: promote_project_milestone_path(@milestone.project, @milestone),
|
||||||
container: 'body' },
|
container: 'body' },
|
||||||
disabled: true }
|
disabled: true,
|
||||||
|
type: 'button' }
|
||||||
= _('Promote')
|
= _('Promote')
|
||||||
#promote-milestone-modal
|
#promote-milestone-modal
|
||||||
|
|
||||||
|
|
|
@ -48,15 +48,16 @@
|
||||||
|
|
||||||
.pull-right.hidden-xs.hidden-sm
|
.pull-right.hidden-xs.hidden-sm
|
||||||
- if label.is_a?(ProjectLabel) && label.project.group && can?(current_user, :admin_label, label.project.group)
|
- if label.is_a?(ProjectLabel) && label.project.group && can?(current_user, :admin_label, label.project.group)
|
||||||
%a.js-promote-project-label-button.btn.btn-transparent.btn-action.has-tooltip{ title: _('Promote to Group Label'),
|
%button.js-promote-project-label-button.btn.btn-transparent.btn-action.has-tooltip{ title: _('Promote to Group Label'),
|
||||||
|
disabled: true,
|
||||||
|
type: 'button',
|
||||||
data: { url: promote_project_label_path(label.project, label),
|
data: { url: promote_project_label_path(label.project, label),
|
||||||
label_title: label.title,
|
label_title: label.title,
|
||||||
label_color: label.color,
|
label_color: label.color,
|
||||||
label_text_color: label.text_color,
|
label_text_color: label.text_color,
|
||||||
target: '#promote-label-modal',
|
target: '#promote-label-modal',
|
||||||
container: 'body',
|
container: 'body',
|
||||||
toggle: 'modal' },
|
toggle: 'modal' } }
|
||||||
disabled: true }
|
|
||||||
= sprite_icon('level-up')
|
= sprite_icon('level-up')
|
||||||
- if can?(current_user, :admin_label, label)
|
- if can?(current_user, :admin_label, label)
|
||||||
= link_to edit_label_path(label), title: "Edit", class: 'btn btn-transparent btn-action', data: {toggle: "tooltip"} do
|
= link_to edit_label_path(label), title: "Edit", class: 'btn btn-transparent btn-action', data: {toggle: "tooltip"} do
|
||||||
|
|
|
@ -51,13 +51,14 @@
|
||||||
\
|
\
|
||||||
|
|
||||||
- if @project.group
|
- if @project.group
|
||||||
%a.js-promote-project-milestone-button.btn.btn-xs.btn-grouped.has-tooltip{ title: _('Promote to Group Milestone'),
|
%button.js-promote-project-milestone-button.btn.btn-xs.btn-grouped.has-tooltip{ title: _('Promote to Group Milestone'),
|
||||||
|
disabled: true,
|
||||||
|
type: 'button',
|
||||||
data: { url: promote_project_milestone_path(milestone.project, milestone),
|
data: { url: promote_project_milestone_path(milestone.project, milestone),
|
||||||
milestone_title: milestone.title,
|
milestone_title: milestone.title,
|
||||||
target: '#promote-milestone-modal',
|
target: '#promote-milestone-modal',
|
||||||
container: 'body',
|
container: 'body',
|
||||||
toggle: 'modal' },
|
toggle: 'modal' } }
|
||||||
disabled: true }
|
|
||||||
= _('Promote')
|
= _('Promote')
|
||||||
|
|
||||||
= link_to 'Close Milestone', project_milestone_path(@project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-xs btn-close btn-grouped"
|
= link_to 'Close Milestone', project_milestone_path(@project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-xs btn-close btn-grouped"
|
||||||
|
|
|
@ -133,7 +133,7 @@ describe Projects::LabelsController do
|
||||||
it 'gives access' do
|
it 'gives access' do
|
||||||
post :promote, namespace_id: project.namespace.to_param, project_id: project, id: label_1.to_param
|
post :promote, namespace_id: project.namespace.to_param, project_id: project, id: label_1.to_param
|
||||||
|
|
||||||
expect(response.location).to include(namespace_project_labels_path)
|
expect(response).to redirect_to(namespace_project_labels_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'promotes the label' do
|
it 'promotes the label' do
|
||||||
|
|
|
@ -98,7 +98,8 @@ describe Projects::MilestonesController do
|
||||||
it 'shows group milestone' do
|
it 'shows group milestone' do
|
||||||
post :promote, namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid
|
post :promote, namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid
|
||||||
|
|
||||||
expect(response.location).to include(project_milestones_path(project))
|
expect(flash[:notice]).to eq("#{milestone.title} promoted to group milestone")
|
||||||
|
expect(response).to redirect_to(project_milestones_path(project))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import Vue from 'vue';
|
||||||
import promoteLabelModal from '~/pages/projects/labels/components/promote_label_modal.vue';
|
import promoteLabelModal from '~/pages/projects/labels/components/promote_label_modal.vue';
|
||||||
import eventHub from '~/pages/projects/labels/event_hub';
|
import eventHub from '~/pages/projects/labels/event_hub';
|
||||||
import axios from '~/lib/utils/axios_utils';
|
import axios from '~/lib/utils/axios_utils';
|
||||||
import * as urlUtility from '~/lib/utils/url_utility';
|
|
||||||
import mountComponent from '../../../helpers/vue_mount_component_helper';
|
import mountComponent from '../../../helpers/vue_mount_component_helper';
|
||||||
|
|
||||||
describe('Promote label modal', () => {
|
describe('Promote label modal', () => {
|
||||||
|
@ -59,11 +58,9 @@ describe('Promote label modal', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
const redirectSpy = spyOn(urlUtility, 'redirectTo');
|
|
||||||
|
|
||||||
vm.onSubmit()
|
vm.onSubmit()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
expect(redirectSpy).toHaveBeenCalledWith(responseURL);
|
|
||||||
expect(eventHub.$emit).toHaveBeenCalledWith('promoteLabelModal.requestFinished', { labelUrl: labelMockData.url, successful: true });
|
expect(eventHub.$emit).toHaveBeenCalledWith('promoteLabelModal.requestFinished', { labelUrl: labelMockData.url, successful: true });
|
||||||
})
|
})
|
||||||
.then(done)
|
.then(done)
|
||||||
|
@ -78,12 +75,10 @@ describe('Promote label modal', () => {
|
||||||
expect(eventHub.$emit).toHaveBeenCalledWith('promoteLabelModal.requestStarted', labelMockData.url);
|
expect(eventHub.$emit).toHaveBeenCalledWith('promoteLabelModal.requestStarted', labelMockData.url);
|
||||||
return Promise.reject(dummyError);
|
return Promise.reject(dummyError);
|
||||||
});
|
});
|
||||||
const redirectSpy = spyOn(urlUtility, 'redirectTo');
|
|
||||||
|
|
||||||
vm.onSubmit()
|
vm.onSubmit()
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
expect(error).toBe(dummyError);
|
expect(error).toBe(dummyError);
|
||||||
expect(redirectSpy).not.toHaveBeenCalled();
|
|
||||||
expect(eventHub.$emit).toHaveBeenCalledWith('promoteLabelModal.requestFinished', { labelUrl: labelMockData.url, successful: false });
|
expect(eventHub.$emit).toHaveBeenCalledWith('promoteLabelModal.requestFinished', { labelUrl: labelMockData.url, successful: false });
|
||||||
})
|
})
|
||||||
.then(done)
|
.then(done)
|
||||||
|
|
|
@ -2,7 +2,6 @@ import Vue from 'vue';
|
||||||
import promoteMilestoneModal from '~/pages/milestones/shared/components/promote_milestone_modal.vue';
|
import promoteMilestoneModal from '~/pages/milestones/shared/components/promote_milestone_modal.vue';
|
||||||
import eventHub from '~/pages/milestones/shared/event_hub';
|
import eventHub from '~/pages/milestones/shared/event_hub';
|
||||||
import axios from '~/lib/utils/axios_utils';
|
import axios from '~/lib/utils/axios_utils';
|
||||||
import * as urlUtility from '~/lib/utils/url_utility';
|
|
||||||
import mountComponent from '../../../../helpers/vue_mount_component_helper';
|
import mountComponent from '../../../../helpers/vue_mount_component_helper';
|
||||||
|
|
||||||
describe('Promote milestone modal', () => {
|
describe('Promote milestone modal', () => {
|
||||||
|
@ -54,11 +53,9 @@ describe('Promote milestone modal', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
const redirectSpy = spyOn(urlUtility, 'redirectTo');
|
|
||||||
|
|
||||||
vm.onSubmit()
|
vm.onSubmit()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
expect(redirectSpy).toHaveBeenCalledWith(responseURL);
|
|
||||||
expect(eventHub.$emit).toHaveBeenCalledWith('promoteMilestoneModal.requestFinished', { milestoneUrl: milestoneMockData.url, successful: true });
|
expect(eventHub.$emit).toHaveBeenCalledWith('promoteMilestoneModal.requestFinished', { milestoneUrl: milestoneMockData.url, successful: true });
|
||||||
})
|
})
|
||||||
.then(done)
|
.then(done)
|
||||||
|
@ -73,12 +70,10 @@ describe('Promote milestone modal', () => {
|
||||||
expect(eventHub.$emit).toHaveBeenCalledWith('promoteMilestoneModal.requestStarted', milestoneMockData.url);
|
expect(eventHub.$emit).toHaveBeenCalledWith('promoteMilestoneModal.requestStarted', milestoneMockData.url);
|
||||||
return Promise.reject(dummyError);
|
return Promise.reject(dummyError);
|
||||||
});
|
});
|
||||||
const redirectSpy = spyOn(urlUtility, 'redirectTo');
|
|
||||||
|
|
||||||
vm.onSubmit()
|
vm.onSubmit()
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
expect(error).toBe(dummyError);
|
expect(error).toBe(dummyError);
|
||||||
expect(redirectSpy).not.toHaveBeenCalled();
|
|
||||||
expect(eventHub.$emit).toHaveBeenCalledWith('promoteMilestoneModal.requestFinished', { milestoneUrl: milestoneMockData.url, successful: false });
|
expect(eventHub.$emit).toHaveBeenCalledWith('promoteMilestoneModal.requestFinished', { milestoneUrl: milestoneMockData.url, successful: false });
|
||||||
})
|
})
|
||||||
.then(done)
|
.then(done)
|
||||||
|
|
Loading…
Reference in New Issue