mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-28 22:43:30 +03:00
Improved theme upload/activate flow and error styles (#1142)
no issue * Update error and warning styles * Refined upload dialog * Theme upload and activation style refinements
This commit is contained in:
parent
b34be95c17
commit
bd90585956
@ -597,59 +597,109 @@
|
||||
}
|
||||
|
||||
/*Errors */
|
||||
.theme-validation-errors {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.theme-validation-errors p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.theme-validation-errordescription {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.theme-validation-errordescription span {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.theme-validation-errortype {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
.theme-validation-errortype.fatal {
|
||||
color: var(--red);
|
||||
.theme-validation-container {
|
||||
max-height: calc(100vh - 12vw - 110px);
|
||||
overflow-y: scroll;
|
||||
margin: -40px -40px 0;
|
||||
padding: 40px 40px 0;
|
||||
}
|
||||
|
||||
.theme-validation-item {
|
||||
margin: 0 0 15px;
|
||||
padding: 15px 20px;
|
||||
margin: 12px 0 0;
|
||||
padding: 12px 16px;
|
||||
border: 1px solid #e5eff5;
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: var(--whitegrey);
|
||||
border: 1px solid var(--lightgrey);
|
||||
}
|
||||
|
||||
.theme-validation-item h4 {
|
||||
margin: 0;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 500;
|
||||
font-size: 1.4rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.theme-validation-rule-text {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.theme-validation-item.theme-fatal-error {
|
||||
background: color-mod(var(--red) alpha(0.04));
|
||||
border: 1px solid color-mod(var(--red) alpha(0.4));
|
||||
}
|
||||
|
||||
.theme-validation-item.theme-fatal-error .theme-validation-rule-text::before,
|
||||
.theme-validation-item.theme-error .theme-validation-rule-text::before,
|
||||
.theme-validation-item.theme-warning .theme-validation-rule-text::before
|
||||
{
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.theme-validation-item.theme-fatal-error .theme-validation-rule-text::before {
|
||||
content: "Fatal error:";
|
||||
color: var(--red);
|
||||
}
|
||||
|
||||
.theme-validation-item.theme-error .theme-validation-rule-text::before {
|
||||
content: "Error:";
|
||||
}
|
||||
|
||||
.theme-validation-item.theme-warning .theme-validation-rule-text::before {
|
||||
content: "Warning:";
|
||||
}
|
||||
|
||||
.theme-fatal-error .theme-validation-type-label::before,
|
||||
.theme-error .theme-validation-type-label::before,
|
||||
.theme-warning .theme-validation-type-label::before {
|
||||
content: "";
|
||||
display: block;
|
||||
border-top-right-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
width: 8px;
|
||||
height: 16px;
|
||||
margin-top: 3px;
|
||||
margin-left: -17px;
|
||||
}
|
||||
|
||||
.theme-fatal-error .theme-validation-type-label::before,
|
||||
.theme-error .theme-validation-type-label::before {
|
||||
background: color-mod(var(--red) alpha(0.85));
|
||||
}
|
||||
|
||||
.theme-warning .theme-validation-type-label::before {
|
||||
background: color-mod(var(--yellow));
|
||||
}
|
||||
|
||||
.theme-validation-list ul {
|
||||
list-style: disc;
|
||||
}
|
||||
|
||||
.theme-validation-list code,
|
||||
.theme-validation-rule-text code {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.theme-validation-item h6 {
|
||||
font-size: 1.4rem;
|
||||
font-size: 1.3rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.theme-validation-item {
|
||||
background: var(--whitegrey-l2);
|
||||
}
|
||||
|
||||
.theme-validation-toggle-details {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-grow: 1;
|
||||
align-items: center;
|
||||
align-items: flex-start;
|
||||
padding: 0;
|
||||
color: var(--darkgrey);
|
||||
text-decoration: none!important;
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
.theme-validation-rule-icon {
|
||||
@ -660,14 +710,22 @@
|
||||
transition: all 0.1s ease-out;
|
||||
}
|
||||
|
||||
.theme-validation-rule-icon svg {
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.theme-validation-rule-icon svg path {
|
||||
fill: var(--midgrey);
|
||||
}
|
||||
|
||||
.theme-validation-details {
|
||||
margin-top: 15px;
|
||||
margin-top: 12px;
|
||||
padding-top: 12px;
|
||||
font-size: 1.3rem;
|
||||
font-weight: 300;
|
||||
border-top: 1px solid var(--lightgrey);
|
||||
}
|
||||
|
||||
.theme-validation-list {
|
||||
margin-top: 1em;
|
||||
p.theme-validation-details {
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
@ -1,13 +1,16 @@
|
||||
<a href="" class="theme-validation-toggle-details" {{action "toggleDetails"}} data-test-toggle-details>
|
||||
<h4 class="theme-validation-rule-text">
|
||||
{{{error.rule}}}
|
||||
</h4>
|
||||
<div class="theme-validation-rule-icon">
|
||||
{{#if showDetails}}
|
||||
{{svg-jar "arrow-down"}}
|
||||
{{else}}
|
||||
{{svg-jar "arrow-right"}}
|
||||
{{/if}}
|
||||
<div class="theme-validation-type-label"></div>
|
||||
<div class="flex items-center flex-auto">
|
||||
<h4 class="theme-validation-rule-text">
|
||||
{{{error.rule}}}
|
||||
</h4>
|
||||
<div class="theme-validation-rule-icon">
|
||||
{{#if showDetails}}
|
||||
{{svg-jar "arrow-down"}}
|
||||
{{else}}
|
||||
{{svg-jar "arrow-right"}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
|
@ -1,52 +1,60 @@
|
||||
<header class="modal-header">
|
||||
<h1 data-test-theme-warnings-title>
|
||||
{{#unless this.canActivate}}
|
||||
{{this.title}}
|
||||
{{else}}
|
||||
{{this.title}} with {{#if this.errors}}errors{{else}}warnings{{/if}}
|
||||
{{/unless}}
|
||||
</h1>
|
||||
</header>
|
||||
<a class="close" href="#" title="Close" {{action "closeModal"}}>{{svg-jar "close"}}<span class="hidden">Close</span></a>
|
||||
<div class="theme-validation-container">
|
||||
<header class="modal-header">
|
||||
<h1 data-test-theme-warnings-title>
|
||||
{{#unless this.canActivate}}
|
||||
{{this.title}}
|
||||
{{else}}
|
||||
{{this.title}} with {{#if this.errors}}errors{{else}}warnings{{/if}}
|
||||
{{/unless}}
|
||||
</h1>
|
||||
</header>
|
||||
<a class="close" href="#" title="Close" {{action "closeModal"}}>{{svg-jar "close"}}<span class="hidden">Close</span></a>
|
||||
|
||||
<div class="modal-body">
|
||||
<ul class="theme-validation-errors" data-test-theme-warnings>
|
||||
<div class="modal-body">
|
||||
{{#if this.fatalErrors}}
|
||||
<div class="theme-validation-errordescription">
|
||||
<h2 class="theme-validation-errortype fatal">Fatal Errors</h2>
|
||||
<p><em>(Must-fix to activate theme)</em></p>
|
||||
<div>
|
||||
<h2 class="mb0 mt4 f5 fw6 red">Fatal Errors</h2>
|
||||
<p class="mb2 red">Must-fix to activate theme</p>
|
||||
</div>
|
||||
<ul class="pa0" data-test-theme-warnings>
|
||||
{{#each this.fatalErrors as |error|}}
|
||||
<li class="theme-validation-item theme-fatal-error">
|
||||
{{gh-theme-error-li error=error}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{/if}}
|
||||
{{#each this.fatalErrors as |error|}}
|
||||
<li class="theme-validation-item">
|
||||
{{gh-theme-error-li error=error}}
|
||||
</li>
|
||||
{{/each}}
|
||||
|
||||
{{#if this.errors}}
|
||||
<div class="theme-validation-errordescription">
|
||||
<h2 class="theme-validation-errortype">Errors</h2>
|
||||
<p><em>(Very recommended to fix, functionality <span>could</span> be restricted)</em></p>
|
||||
<div>
|
||||
<h2 class="mb0 mt4 f5 fw6">Errors</h2>
|
||||
<p class="mb2">Highly recommended to fix, functionality <span>could</span> be restricted</p>
|
||||
</div>
|
||||
|
||||
<ul class="pa0" data-test-theme-warnings>
|
||||
{{#each this.errors as |error|}}
|
||||
<li class="theme-validation-item theme-error">
|
||||
{{gh-theme-error-li error=error}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{/if}}
|
||||
{{#each this.errors as |error|}}
|
||||
<li class="theme-validation-item">
|
||||
{{gh-theme-error-li error=error}}
|
||||
</li>
|
||||
{{/each}}
|
||||
|
||||
{{#if (and this.warnings (or this.fatalErrors this.errors))}}
|
||||
<div class="theme-validation-errordescription">
|
||||
<h2 class="theme-validation-errortype">Warnings</h2>
|
||||
<div>
|
||||
<h2 class="mb0 mt4 f5 fw6">Warnings</h2>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#each this.warnings as |error|}}
|
||||
<li class="theme-validation-item">
|
||||
{{gh-theme-error-li error=error}}
|
||||
</li>
|
||||
{{/each}}
|
||||
|
||||
</ul>
|
||||
{{#if this.warnings}}
|
||||
<ul class="pa0" data-test-theme-warnings>
|
||||
{{#each this.warnings as |error|}}
|
||||
<li class="theme-validation-item theme-warning">
|
||||
{{gh-theme-error-li error=error}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
|
@ -1,122 +1,140 @@
|
||||
<header class="modal-header" data-test-modal="upload-theme">
|
||||
<h1>
|
||||
<div class="theme-validation-container">
|
||||
<header class="modal-header" data-test-modal="upload-theme">
|
||||
<h1>
|
||||
{{#if theme}}
|
||||
{{#if hasWarningsOrErrors}}
|
||||
Upload successful with {{#if validationErrors}}errors{{else}}warnings{{/if}}
|
||||
{{else}}
|
||||
Upload successful!
|
||||
{{/if}}
|
||||
{{else if (or validationErrors fatalValidationErrors)}}
|
||||
Invalid theme
|
||||
{{else}}
|
||||
Upload a theme
|
||||
{{/if}}
|
||||
</h1>
|
||||
</header>
|
||||
<a class="close" href="#" title="Close" {{action "closeModal"}}>{{svg-jar "close"}}<span class="hidden">Close</span></a>
|
||||
|
||||
<div class="modal-body">
|
||||
{{#if theme}}
|
||||
{{#if hasWarningsOrErrors}}
|
||||
Upload successful with {{#if validationErrors}}errors{{else}}warnings{{/if}}
|
||||
{{else}}
|
||||
Upload successful!
|
||||
{{/if}}
|
||||
{{else if (or validationErrors fatalValidationErrors)}}
|
||||
Invalid theme
|
||||
{{else}}
|
||||
Upload a theme
|
||||
{{/if}}
|
||||
</h1>
|
||||
</header>
|
||||
<a class="close" href="#" title="Close" {{action "closeModal"}}>{{svg-jar "close"}}<span class="hidden">Close</span></a>
|
||||
|
||||
<div class="modal-body">
|
||||
{{#if theme}}
|
||||
{{#if hasWarningsOrErrors}}
|
||||
<ul class="theme-validation-errors">
|
||||
<li>
|
||||
<p>
|
||||
"{{themeName}}" uploaded successfully but some {{#if validationErrors}}errors{{else}}warnings{{/if}} were detected.
|
||||
You are still able to use and activate the theme. Here's your report...
|
||||
</p>
|
||||
</li>
|
||||
<p>
|
||||
{{#if canActivateTheme}}
|
||||
The theme <strong>"{{themeName}}"</strong> was uploaded successfully but we detected some {{#if validationErrors}}errors{{else}}warnings{{/if}}. You are still able to activate and use the theme but it is recommended to fix these {{#if validationErrors}}errors{{else}}warnings{{/if}} before you do so.
|
||||
{{else}}
|
||||
The theme <strong>"{{themeName}}"</strong> was uploaded successfully but we detected some
|
||||
{{#if validationErrors}}errors{{else}}warnings{{/if}}.
|
||||
{{/if}}
|
||||
</p>
|
||||
|
||||
{{#if validationErrors}}
|
||||
<div class="theme-validation-errordescription">
|
||||
<h2 class="theme-validation-errortype">Errors</h2>
|
||||
<p><em>(Very recommended to fix, functionality <span>could</span> be restricted)</em></p>
|
||||
<div>
|
||||
<h2 class="mb0 mt4 f5 fw6">Errors</h2>
|
||||
<p class="mb2">Highly recommended to fix, functionality <strong>could</strong> be restricted</p>
|
||||
</div>
|
||||
<ul class="pa0">
|
||||
{{#each validationErrors as |error|}}
|
||||
<li class="theme-validation-item theme-error">
|
||||
{{gh-theme-error-li error=error}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{/if}}
|
||||
{{#each validationErrors as |error|}}
|
||||
<li class="theme-validation-item">
|
||||
{{gh-theme-error-li error=error}}
|
||||
</li>
|
||||
{{/each}}
|
||||
|
||||
{{#if validationWarnings}}
|
||||
<div class="theme-validation-errordescription">
|
||||
<h2 class="theme-validation-errortype">Warnings</h2>
|
||||
<div>
|
||||
<h2 class="mb0 mt4 f5 fw6">Warnings</h2>
|
||||
</div>
|
||||
<ul class="pa0">
|
||||
{{#each validationWarnings as |error|}}
|
||||
<li class="theme-validation-item theme-warning">
|
||||
{{gh-theme-error-li error=error}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{/if}}
|
||||
{{#each validationWarnings as |error|}}
|
||||
<li class="theme-validation-item">
|
||||
{{else}}
|
||||
<p>
|
||||
"{{themeName}}" uploaded successfully.
|
||||
{{#if canActivateTheme}}Do you want to activate it now?{{/if}}
|
||||
</p>
|
||||
{{/if}}
|
||||
{{else if displayOverwriteWarning}}
|
||||
<p>
|
||||
The theme folder <strong>"{{fileThemeName}}"</strong> already exists. Do you want to overwrite it?
|
||||
</p>
|
||||
{{else if (or validationErrors fatalValidationErrors)}}
|
||||
|
||||
<p>
|
||||
This theme is invalid and cannot be activated. Fix the following errors and re-upload the theme.
|
||||
</p>
|
||||
|
||||
{{#if fatalValidationErrors}}
|
||||
<div>
|
||||
<h2 class="mb0 mt4 f5 fw6">Fatal Errors</h2>
|
||||
<p class="mb2">Must-fix to activate theme</p>
|
||||
</div>
|
||||
|
||||
<ul class="pa0">
|
||||
{{#each fatalValidationErrors as |error|}}
|
||||
<li class="theme-validation-item theme-fatal-error">
|
||||
{{gh-theme-error-li error=error}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{else}}
|
||||
<p>
|
||||
"{{themeName}}" uploaded successfully.
|
||||
{{#if canActivateTheme}}Do you want to activate it now?{{/if}}
|
||||
</p>
|
||||
{{/if}}
|
||||
{{else if displayOverwriteWarning}}
|
||||
<p>
|
||||
"{{fileThemeName}}" will overwrite an existing theme of the same name. Are you sure?
|
||||
</p>
|
||||
{{else if (or validationErrors fatalValidationErrors)}}
|
||||
<ul class="theme-validation-errors">
|
||||
{{#if fatalValidationErrors}}
|
||||
<div class="theme-validation-errordescription">
|
||||
<h2 class="theme-validation-errortype fatal">Fatal Errors</h2>
|
||||
<p><em>(Must-fix to activate theme)</em></p>
|
||||
</div>
|
||||
</ul>
|
||||
{{/if}}
|
||||
{{#each fatalValidationErrors as |error|}}
|
||||
<li class="theme-validation-item">
|
||||
{{gh-theme-error-li error=error}}
|
||||
</li>
|
||||
{{/each}}
|
||||
|
||||
{{#if validationErrors}}
|
||||
<div class="theme-validation-errordescription">
|
||||
<h2 class="theme-validation-errortype">Errors</h2>
|
||||
<p><em>(Very recommended to fix, functionality <span>could</span> be restricted)</em></p>
|
||||
<div>
|
||||
<h2 class="mb0 mt4 f5 fw6">Errors</h2>
|
||||
<p class="mb2">Highly recommended to fix, functionality <strong>could</strong> be restricted</p>
|
||||
</div>
|
||||
<ul class="pa0">
|
||||
{{#each validationErrors as |error|}}
|
||||
<li class="theme-validation-item theme-error">
|
||||
{{gh-theme-error-li error=error}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{/if}}
|
||||
{{#each validationErrors as |error|}}
|
||||
<li class="theme-validation-item">
|
||||
{{gh-theme-error-li error=error}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{else}}
|
||||
{{gh-file-uploader
|
||||
url=uploadUrl
|
||||
paramName="file"
|
||||
accept=accept
|
||||
labelText="Click to select or drag-and-drop your theme zip file here."
|
||||
validate=(action "validateTheme")
|
||||
uploadStarted=(action "uploadStarted")
|
||||
uploadFinished=(action "uploadFinished")
|
||||
uploadSuccess=(action "uploadSuccess")
|
||||
uploadFailed=(action "uploadFailed")
|
||||
listenTo="themeUploader"}}
|
||||
{{/if}}
|
||||
{{else}}
|
||||
{{gh-file-uploader
|
||||
url=uploadUrl
|
||||
paramName="file"
|
||||
accept=accept
|
||||
labelText="Click to select or drag-and-drop your theme zip file here."
|
||||
validate=(action "validateTheme")
|
||||
uploadStarted=(action "uploadStarted")
|
||||
uploadFinished=(action "uploadFinished")
|
||||
uploadSuccess=(action "uploadSuccess")
|
||||
uploadFailed=(action "uploadFailed")
|
||||
listenTo="themeUploader"}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button {{action "closeModal"}} disabled={{closeDisabled}} class="gh-btn" data-test-close-button>
|
||||
<span>{{#if theme}}Close{{else}}Cancel{{/if}}</span>
|
||||
</button>
|
||||
{{#if displayOverwriteWarning}}
|
||||
<button {{action "confirmOverwrite"}} class="gh-btn gh-btn-red" data-test-overwrite-button>
|
||||
<span>Overwrite</span>
|
||||
<div class="flex items-center justify-between {{if (or displayOverwriteWarning canActivateTheme validationErrors) "flex-auto"}}">
|
||||
<button {{action "closeModal"}} disabled={{closeDisabled}} class="gh-btn" data-test-close-button>
|
||||
<span>{{#if theme}}Close{{else}}Cancel{{/if}}</span>
|
||||
</button>
|
||||
{{/if}}
|
||||
{{#if validationErrors}}
|
||||
<button {{action "reset"}} class="gh-btn gh-btn-green" data-test-try-again-button>
|
||||
<span>Try Again</span>
|
||||
</button>
|
||||
{{/if}}
|
||||
{{#if canActivateTheme}}
|
||||
<button {{action "activate"}} class="gh-btn gh-btn-green" data-test-activate-now-button>
|
||||
<span>Activate Now</span>
|
||||
</button>
|
||||
{{/if}}
|
||||
<div class="flex items-center">
|
||||
{{#if displayOverwriteWarning}}
|
||||
<button {{action "confirmOverwrite"}} class="gh-btn gh-btn-red" data-test-overwrite-button>
|
||||
<span>Overwrite</span>
|
||||
</button>
|
||||
{{/if}}
|
||||
{{#if canActivateTheme}}
|
||||
<button {{action "activate"}} class="gh-btn" data-test-activate-now-button>
|
||||
<span>Activate with errors</span>
|
||||
</button>
|
||||
{{/if}}
|
||||
{{#if validationErrors}}
|
||||
<button {{action "reset"}} class="gh-btn gh-btn-blue ml2" data-test-try-again-button>
|
||||
<span>Retry</span>
|
||||
</button>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -26,7 +26,7 @@ export default function mockThemes(server) {
|
||||
server.del('/themes/:theme/', function ({themes}, {params}) {
|
||||
themes.findBy({name: params.theme}).destroy();
|
||||
|
||||
return new Response(204, {}, null);
|
||||
return new Response(204);
|
||||
});
|
||||
|
||||
server.put('/themes/:theme/activate/', function ({themes}, {params}) {
|
||||
|
Loading…
Reference in New Issue
Block a user