Ghost/ghost/admin/app/components/editor/modals/publish-flow/confirm.js
Kevin Ansfield b9707a2b4a Moved logic for publish confirm button text states into backing class (#2397)
refs a021553203

- keeps text and logic together, avoids duplication of button code just for changing the running/success text
- added a `buttonTextMap` to keep the high-level text states in one place
- added `publishType` getter for easier switching between states in other getters and to have one place for the logic
- updated `confirmButtonText` getter and added `confirmRunningText` and `confirmSuccessText` getters that read from the button text map so the pattern used for getting text to pass as arguments in the template is consistent
2022-05-27 11:45:40 +01:00

123 lines
3.9 KiB
JavaScript

import Component from '@glimmer/component';
import moment from 'moment';
import {htmlSafe} from '@ember/template';
import {isArray} from '@ember/array';
import {isServerUnreachableError} from 'ghost-admin/services/ajax';
import {inject as service} from '@ember/service';
import {task} from 'ember-concurrency';
import {tracked} from '@glimmer/tracking';
function isString(str) {
return toString.call(str) === '[object String]';
}
export default class PublishFlowOptions extends Component {
@service settings;
@tracked errorMessage;
// store any derived state from PublishOptions on creation so the copy
// doesn't change whilst the post is saving
willEmail = this.args.publishOptions.willEmail;
willPublish = this.args.publishOptions.willPublish;
buttonTextMap = {
'publish+send': {
idle: 'Publish & Send',
running: 'Publishing & sending',
success: 'Published & sent'
},
send: {
idle: 'Send email',
running: 'Sending',
success: 'Sent'
},
publish: {
idle: 'Publish',
running: 'Publishing',
success: 'Published'
},
schedule: {
// idle: '', - uses underlying publish type text
running: 'Scheduling',
success: 'Scheduled'
}
};
get publishType() {
const {publishOptions} = this.args;
if (this.willPublish && this.willEmail) {
return 'publish+send';
} else if (publishOptions.willOnlyEmail) {
return 'send';
} else {
return 'publish';
}
}
get confirmButtonText() {
let buttonText = '';
buttonText = this.buttonTextMap[this.publishType].idle;
if (this.publishType === 'publish') {
buttonText += ` ${this.args.publishOptions.post.displayName}`;
}
if (this.args.publishOptions.isScheduled) {
const scheduleMoment = moment.tz(this.args.publishOptions.scheduledAtUTC, this.settings.get('timezone'));
buttonText += `, on ${scheduleMoment.format('MMMM Do')}`;
} else {
buttonText += ', right now';
}
return buttonText;
}
get confirmRunningText() {
const publishType = this.args.publishOptions.isScheduled ? 'schedule' : this.publishType;
return this.buttonTextMap[publishType].running;
}
get confirmSuccessText() {
const publishType = this.args.publishOptions.isScheduled ? 'schedule' : this.publishType;
return this.buttonTextMap[publishType].success;
}
@task({drop: true})
*confirmTask() {
this.errorMessage = null;
try {
yield this.args.saveTask.perform();
} catch (e) {
if (e === undefined && this.args.publishOptions.post.errors.length !== 0) {
// validation error
const validationError = this.args.publishOptions.post.errors.messages[0];
this.errorMessage = `Validation failed: ${validationError}`;
return false;
}
let errorMessage = '';
if (isServerUnreachableError(e)) {
errorMessage = 'Unable to connect, please check your internet connection and try again.';
} else if (e && isString(e)) {
errorMessage = e;
} else if (e && isArray(e)) {
// This is here because validation errors are returned as an array
// TODO: remove this once validations are fixed
errorMessage = e[0];
} else if (e?.payload?.errors?.[0].message) {
errorMessage = e.payload.errors[0].message;
} else {
errorMessage = 'Unknown Error';
}
this.errorMessage = htmlSafe(errorMessage);
return false;
}
}
}