Redirect back to account settings when exiting the Theme Editor
refs CNVS-22055 This change replaces the 'X' close button with a 'Cancel' button. Also now, whenever you exit out of the Theme Editor, via either 'Apply' or 'Cancel' you will be redirected back to the account settings page instead of the preview iframe location. These changes should make things work better once CNVS-2196 is implemented. This change also cleans up the Theme Editor header a bit, adding the Canvas logo, and adjusting some padding/margins. Test plan: 1. Open Theme Editor and click 'Cancel'. You should be redirected back account settings page and the appropriate message should display. 2. Open Theme Editor, make some changes, click 'Preview', click 'Cancel'. You should be redirected to the account settings page, the theme changes should be reset/removed and the appropriate message should display. 3. Open Theme Editor, make some changes, click 'Preview', click 'Apply'. You should be redirected to the account settings page and the appropriate message should display. Change-Id: If5f1aa67a87a1587d8f26b9134ccf9d33a299229 Reviewed-on: https://gerrit.instructure.com/58913 Reviewed-by: Ryan Shaw <ryan@instructure.com> Tested-by: Jenkins Reviewed-by: Colleen Palmer <colleen@instructure.com> Product-Review: Colleen Palmer <colleen@instructure.com> QA-Review: Matt Fairbourn <mfairbourn@instructure.com>
This commit is contained in:
parent
1c2d97102d
commit
c8f7ca0aae
|
@ -72,16 +72,17 @@ class BrandConfigsController < ApplicationController
|
|||
@domain_root_account.brand_config = new_md5 && BrandConfig.find(new_md5)
|
||||
@domain_root_account.save!
|
||||
BrandConfig.destroy_if_unused(old_md5)
|
||||
redirect_to :back, notice: t('Success! All users on this domain will now see this branding.')
|
||||
redirect_to account_path(@domain_root_account), notice: t('Success! All users on this domain will now see this branding.')
|
||||
end
|
||||
|
||||
# When you close the theme editor, it will send a DELETE to this action to
|
||||
# clear out the session brand_config that you were prevewing.
|
||||
def destroy
|
||||
session.delete(:brand_config_md5)
|
||||
BrandConfig.destroy_if_unused(session.delete(:brand_config_md5))
|
||||
flash[:notice] = t('Theme editor changes have been cancelled.')
|
||||
render json: {success: true}
|
||||
if session.delete(:brand_config_md5).presence
|
||||
session.delete(:brand_config_md5)
|
||||
BrandConfig.destroy_if_unused(session.delete(:brand_config_md5))
|
||||
end
|
||||
redirect_to account_path(@domain_root_account), notice: t('Theme editor changes have been cancelled.')
|
||||
end
|
||||
|
||||
protected
|
||||
|
|
|
@ -37,15 +37,20 @@ define([
|
|||
className="screenreader-only"
|
||||
htmlFor="sharedThemes"
|
||||
>
|
||||
{I18n.t('Start From a Template Theme:')}
|
||||
{I18n.t('Start From a Theme Template')}
|
||||
</label>
|
||||
<select
|
||||
id="sharedThemes"
|
||||
defaultValue={this.defaultValue()}
|
||||
onChange={event => this.selectBrandConfig(event.target.value)}
|
||||
className="ic-Input"
|
||||
>
|
||||
<option value="" disabled selected> {I18n.t('-- Start From a Template --')} </option>
|
||||
<option value={USE_CANVAS_DEFAULT}>{I18n.t('Canvas Default')}</option>
|
||||
<option value="" disabled selected>
|
||||
{I18n.t('Start from a template...')}
|
||||
</option>
|
||||
<option value={USE_CANVAS_DEFAULT}>
|
||||
{I18n.t('Canvas Default')}
|
||||
</option>
|
||||
{this.props.sharedBrandConfigs.map(brandConfig =>
|
||||
<option key={brandConfig.md5} value={brandConfig.md5}>
|
||||
{brandConfig.name}
|
||||
|
|
|
@ -71,6 +71,10 @@ define([
|
|||
})
|
||||
},
|
||||
|
||||
onProgress(data) {
|
||||
this.setState({progress: data.completion})
|
||||
},
|
||||
|
||||
getDefault(variableName) {
|
||||
var val = this.state.changedValues[variableName] && this.state.changedValues[variableName].val
|
||||
if (val) return val
|
||||
|
@ -87,34 +91,24 @@ define([
|
|||
submitHtmlForm('/brand_configs/save_to_user_session', 'POST', md5)
|
||||
},
|
||||
|
||||
redirectToWhatIframeIsShowing() {
|
||||
window.top.location = this.refs.previewIframe.getDOMNode().contentWindow.location
|
||||
},
|
||||
|
||||
exit() {
|
||||
handleCancelClicked() {
|
||||
if (this.props.hasUnsavedChanges || this.state.somethingChanged) {
|
||||
var msg = I18n.t('You are about to lose any unsaved changes.\n\n' +
|
||||
var msg = I18n.t('You are about to lose any changes that you have not yet applied to your account.\n\n' +
|
||||
'Would you still like to proceed?')
|
||||
if (confirm(msg)) {
|
||||
$.ajax('/brand_configs', {type: 'DELETE'})
|
||||
.then(this.redirectToWhatIframeIsShowing)
|
||||
.then(null, () => alert(I18n.t('Something went wrong, please try again.')))
|
||||
if (!confirm(msg)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
this.redirectToWhatIframeIsShowing()
|
||||
}
|
||||
submitHtmlForm('/brand_configs', 'DELETE');
|
||||
},
|
||||
|
||||
saveToAccount() {
|
||||
handleApplyClicked() {
|
||||
var msg = I18n.t('This will apply these changes to your entire account. Would you like to proceed?')
|
||||
if (confirm(msg)) submitHtmlForm('/brand_configs/save_to_account', 'POST')
|
||||
},
|
||||
|
||||
onProgress(data) {
|
||||
this.setState({progress: data.completion})
|
||||
},
|
||||
|
||||
preview() {
|
||||
handleFormSubmit() {
|
||||
var newMd5
|
||||
|
||||
this.setState({showProgressModal: true})
|
||||
|
@ -143,61 +137,61 @@ define([
|
|||
render() {
|
||||
return (
|
||||
<div id="main">
|
||||
<form
|
||||
ref="ThemeEditorForm"
|
||||
onSubmit={preventDefault(this.preview)}
|
||||
encType="multipart/form-data"
|
||||
acceptCharset="UTF-8"
|
||||
action="/brand_configs"
|
||||
method="POST"
|
||||
className="Theme__container"
|
||||
>
|
||||
<input name="utf8" type="hidden" value="✓" />
|
||||
<input name="authenticity_token" type="hidden" value={$.cookie('_csrf_token')} />
|
||||
<div className="Theme__editor">
|
||||
<div className="Theme__editor-header">
|
||||
<h1 className="Theme__editor-header_title">
|
||||
<button
|
||||
type='button'
|
||||
className="Theme__editor-header_title-icon btn-link pull-left"
|
||||
onClick={this.exit}
|
||||
title={I18n.t('Exit Theme Editor')}
|
||||
>
|
||||
<i className="icon-x" />
|
||||
<span className="screenreader-only">{I18n.t('Exit Theme Editor')}</span>
|
||||
</button>
|
||||
<form
|
||||
ref="ThemeEditorForm"
|
||||
onSubmit={preventDefault(this.handleFormSubmit)}
|
||||
encType="multipart/form-data"
|
||||
acceptCharset="UTF-8"
|
||||
action="/brand_configs"
|
||||
method="POST"
|
||||
className="Theme__container">
|
||||
<input name="utf8" type="hidden" value="✓" />
|
||||
<input name="authenticity_token" type="hidden" value={$.cookie('_csrf_token')} />
|
||||
<div className="Theme__editor">
|
||||
|
||||
{I18n.t('Theme Editor')}
|
||||
</h1>
|
||||
<div className="Theme__editor-header_actions">
|
||||
<span
|
||||
data-tooltip="bottom"
|
||||
title={this.state.somethingChanged ?
|
||||
I18n.t('you need to "Preview Your Changes" before applying to everyone') :
|
||||
null
|
||||
}
|
||||
>
|
||||
<div className="Theme__editor-header">
|
||||
<div className="Theme__editor-header_title">
|
||||
<i className="Theme__editor-header_title-icon icon-instructure" />
|
||||
<h1 className="Theme__editor-header_title-text">
|
||||
{I18n.t('Theme Editor')}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div className="Theme__editor-header_actions">
|
||||
<span
|
||||
data-tooltip="bottom"
|
||||
title={this.state.somethingChanged ?
|
||||
I18n.t('You need to "Preview Your Changes" before applying to everyone.') :
|
||||
null
|
||||
}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
className="Theme__editor-header_button Button Button--success"
|
||||
disabled={!this.props.hasUnsavedChanges || this.state.somethingChanged}
|
||||
onClick={this.handleApplyClicked}
|
||||
>
|
||||
{I18n.t('Apply')}
|
||||
</button>
|
||||
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
className="Theme__editor-header_button Button Button--success"
|
||||
disabled={!this.props.hasUnsavedChanges || this.state.somethingChanged}
|
||||
onClick={this.saveToAccount}
|
||||
className="Theme__editor-header_button Button"
|
||||
onClick={this.handleCancelClicked}
|
||||
>
|
||||
{I18n.t('Apply')}
|
||||
{I18n.t('Cancel')}
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SharedBrandConfigPicker
|
||||
sharedBrandConfigs={this.props.sharedBrandConfigs}
|
||||
activeBrandConfigMd5={this.props.brandConfig.md5}
|
||||
saveToSession={this.saveToSession}
|
||||
/>
|
||||
|
||||
<div id="Theme__editor-tabs">
|
||||
<div id="te-editor">
|
||||
<div className="Theme__editor-tabs_panel">
|
||||
<div className="Theme__editor-tabs">
|
||||
<div id="te-editor-panel" className="Theme__editor-tabs_panel">
|
||||
<SharedBrandConfigPicker
|
||||
sharedBrandConfigs={this.props.sharedBrandConfigs}
|
||||
activeBrandConfigMd5={this.props.brandConfig.md5}
|
||||
saveToSession={this.saveToSession}
|
||||
/>
|
||||
<ThemeEditorAccordion
|
||||
variableSchema={this.props.variableSchema}
|
||||
brandConfigVariables={this.props.brandConfig.variables}
|
||||
|
@ -207,40 +201,46 @@ define([
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="Theme__preview">
|
||||
{ this.state.somethingChanged ?
|
||||
<div className="Theme__preview-overlay">
|
||||
<div className="Theme__preview-overlay__container">
|
||||
<button type="submit" className="Button Button--primary" disabled={this.invalidForm()}>
|
||||
<i className="icon-refresh" />
|
||||
{I18n.t('Preview Your Changes')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="Theme__preview">
|
||||
{ this.state.somethingChanged ?
|
||||
<div className="Theme__preview-overlay">
|
||||
<div className="Theme__preview-overlay__container">
|
||||
<button
|
||||
type="submit"
|
||||
className="Button Button--primary"
|
||||
disabled={this.invalidForm()}>
|
||||
<i className="icon-refresh" />
|
||||
<span className="Theme__preview-button-text">
|
||||
{I18n.t('Preview Your Changes')}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
: null }
|
||||
<iframe ref="previewIframe" src="/?editing_brand_config=1" />
|
||||
</div>
|
||||
: null }
|
||||
<iframe ref="previewIframe" src="/?editing_brand_config=1" />
|
||||
</div>
|
||||
</form>
|
||||
<Modal
|
||||
isOpen={this.state.showProgressModal}
|
||||
className='ReactModal__Content--canvas ReactModal__Content--mini-modal'
|
||||
overlayClassName='ReactModal__Overlay--Theme__editor_progress'
|
||||
>
|
||||
<div className="Theme__editor_progress">
|
||||
<h4>{I18n.t('Generating Preview...')}</h4>
|
||||
<ProgressBar
|
||||
progress={this.state.progress}
|
||||
title={I18n.t('%{percent} complete', {
|
||||
percent: I18n.toPercentage(this.state.progress, {precision: 0})
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<Modal
|
||||
isOpen={this.state.showProgressModal}
|
||||
className='ReactModal__Content--canvas ReactModal__Content--mini-modal'
|
||||
overlayClassName='ReactModal__Overlay--Theme__editor_progress'>
|
||||
<div className="Theme__editor_progress">
|
||||
<h4>{I18n.t('Generating Preview...')}</h4>
|
||||
<ProgressBar
|
||||
progress={this.state.progress}
|
||||
title={I18n.t('%{percent} complete', {
|
||||
percent: I18n.toPercentage(this.state.progress, {precision: 0})
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
|
|
|
@ -80,6 +80,9 @@ $te-border-color: darken($ic-color-neutral, 10);
|
|||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.Theme__preview-button-text {
|
||||
padding-left: $ic-sp;
|
||||
}
|
||||
.Theme__preview iframe {
|
||||
border: none;
|
||||
width: 100%;
|
||||
|
@ -90,31 +93,40 @@ $te-border-color: darken($ic-color-neutral, 10);
|
|||
|
||||
.Theme__editor-header {
|
||||
background: $ic-color-dark;
|
||||
padding: 10px 0;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
.Theme__editor-header_title {
|
||||
padding: 0 0 0 $ic-sp;
|
||||
margin: 0;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@include overwrite-default-icon-size(18px);
|
||||
}
|
||||
|
||||
.Theme__editor-header_title-text {
|
||||
color: $ic-color-light;
|
||||
line-height: normal;
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
font-weight: 300;
|
||||
margin: 0 0 0 $ic-sp;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.Theme__editor-header_title-icon {
|
||||
color: $ic-color-light;
|
||||
line-height: 1;
|
||||
color: #D5412F;
|
||||
}
|
||||
|
||||
.Theme__editor-header_actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.Theme__editor-Button--trigger {
|
||||
|
||||
}
|
||||
.Theme__editor-header_button {
|
||||
margin: 0 $ic-sp;
|
||||
margin-left: $ic-sp/2;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,6 +137,10 @@ $te-border-color: darken($ic-color-neutral, 10);
|
|||
padding: $ic-sp;
|
||||
border-top: 1px solid $te-border-color;
|
||||
border-bottom: 1px solid $te-border-color;
|
||||
|
||||
select {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
//// Tabs for Theme Editor
|
||||
///////
|
||||
|
|
Loading…
Reference in New Issue