Ghost/ghost/admin/app/services/ui.js
Kevin Ansfield 3d16b95e0f 🎨 Adjusted post settings menu design so it can stay open whilst editing
refs https://github.com/TryGhost/Team/issues/840

We wanted to switch to a settings menu that stays open to the right of the editor rather than a popover that blocks all other interaction with the post to solve two use-cases:

1.  when editing it's fairly common to select some text from the post contents when setting excerpt and meta data text, with the previous design not letting you scroll or select whilst the menu got in the way of that
2. having the menu open with meta data visible before publishing can help you see everything is set as you want and help you feel confident when publishing/sending content

---

- removed `psmRedesign` labs flag
- swapped labs component/css for main component and deleted labs component
- cleaned up now-unused `ui.showSettingsMenu` property and related actions/classes
2021-07-02 19:04:57 +01:00

121 lines
2.8 KiB
JavaScript

import Service, {inject as service} from '@ember/service';
import {action} from '@ember/object';
import {get} from '@ember/object';
import {isEmpty} from '@ember/utils';
import {tracked} from '@glimmer/tracking';
function collectMetadataClasses(transition, prop) {
let oldClasses = [];
let newClasses = [];
let {from, to} = transition;
while (from) {
oldClasses = oldClasses.concat(get(from, `metadata.${prop}`) || []);
from = from.parent;
}
while (to) {
newClasses = newClasses.concat(get(to, `metadata.${prop}`) || []);
to = to.parent;
}
return {oldClasses, newClasses};
}
function updateBodyClasses(transition) {
let {body} = document;
let {oldClasses, newClasses} = collectMetadataClasses(transition, 'bodyClasses');
oldClasses.forEach((oldClass) => {
body.classList.remove(oldClass);
});
newClasses.forEach((newClass) => {
body.classList.add(newClass);
});
}
export default class UiService extends Service {
@service config;
@service dropdown;
@service mediaQueries;
@service router;
@tracked isFullScreen = false;
@tracked mainClass = '';
@tracked showMobileMenu = false;
get isMobile() {
return this.mediaQueries.isMobile;
}
get isSideNavHidden() {
return this.isFullScreen || this.isMobile;
}
get hasSideNav() {
return !this.isSideNavHidden;
}
constructor() {
super(...arguments);
this.router.on('routeDidChange', (transition) => {
updateBodyClasses(transition);
this.updateDocumentTitle();
let {newClasses: mainClasses} = collectMetadataClasses(transition, 'mainClasses');
this.mainClass = mainClasses.join(' ');
});
}
@action
closeMenus() {
this.dropdown.closeDropdowns();
this.showMobileMenu = false;
}
@action
closeMobileMenu() {
this.showMobileMenu = false;
}
@action
openMobileMenu() {
this.showMobileMenu = true;
}
@action
setMainClass(mainClass) {
this.mainClass = mainClass;
}
@action
updateDocumentTitle() {
let {currentRoute} = this.router;
let tokens = [];
while (currentRoute) {
let titleToken = get(currentRoute, 'metadata.titleToken');
if (typeof titleToken === 'function') {
titleToken = titleToken();
}
if (titleToken) {
tokens.unshift(titleToken);
}
currentRoute = currentRoute.parent;
}
let blogTitle = this.config.get('blogTitle');
if (!isEmpty(tokens)) {
window.document.title = `${tokens.join(' - ')} - ${blogTitle}`;
} else {
window.document.title = blogTitle;
}
}
}