Improve extensions page

- Allow extensions to define an icon in their flarum.json
- Show a "please wait" modal when enabling/disabling an extension
- Styling tweaks
This commit is contained in:
Toby Zerner
2015-08-07 08:51:03 +09:30
parent 4e01aa10d8
commit 3f809761d3
6 changed files with 65 additions and 21 deletions

View File

@ -4,7 +4,9 @@ import Button from 'flarum/components/Button';
import Dropdown from 'flarum/components/Dropdown'; import Dropdown from 'flarum/components/Dropdown';
import Separator from 'flarum/components/Separator'; import Separator from 'flarum/components/Separator';
import AddExtensionModal from 'flarum/components/AddExtensionModal'; import AddExtensionModal from 'flarum/components/AddExtensionModal';
import LoadingModal from 'flarum/components/LoadingModal';
import ItemList from 'flarum/utils/ItemList'; import ItemList from 'flarum/utils/ItemList';
import icon from 'flarum/helpers/icon';
export default class ExtensionsPage extends Component { export default class ExtensionsPage extends Component {
view() { view() {
@ -36,7 +38,9 @@ export default class ExtensionsPage extends Component {
menuClassName: 'Dropdown-menu--right' menuClassName: 'Dropdown-menu--right'
})} })}
<div className="ExtensionListItem-content"> <div className="ExtensionListItem-content">
<span className="ExtensionListItem-icon ExtensionIcon"/> <span className="ExtensionListItem-icon ExtensionIcon" style={extension.icon}>
{extension.icon ? icon(extension.icon.name) : ''}
</span>
<h4 className="ExtensionListItem-title"> <h4 className="ExtensionListItem-title">
{extension.title}{' '} {extension.title}{' '}
<small className="ExtensionListItem-version">{extension.version}</small> <small className="ExtensionListItem-version">{extension.version}</small>
@ -65,7 +69,7 @@ export default class ExtensionsPage extends Component {
} }
items.add('toggle', Button.component({ items.add('toggle', Button.component({
icon: enabled ? 'times' : 'check', icon: 'power-off',
children: enabled ? 'Disable' : 'Enable', children: enabled ? 'Disable' : 'Enable',
onclick: () => { onclick: () => {
app.request({ app.request({
@ -73,22 +77,24 @@ export default class ExtensionsPage extends Component {
method: 'PATCH', method: 'PATCH',
data: {enabled: !enabled} data: {enabled: !enabled}
}).then(() => window.location.reload()); }).then(() => window.location.reload());
app.modal.show(new LoadingModal());
} }
})); }));
if (!enabled) { // if (!enabled) {
items.add('uninstall', Button.component({ // items.add('uninstall', Button.component({
icon: 'trash-o', // icon: 'trash-o',
children: 'Uninstall' // children: 'Uninstall'
})); // }));
} // }
items.add('separator2', Separator.component()); // items.add('separator2', Separator.component());
items.add('support', LinkButton.component({ // items.add('support', LinkButton.component({
icon: 'support', // icon: 'support',
children: 'Support' // children: 'Support'
})); // }));
return items; return items;
} }

View File

@ -0,0 +1,19 @@
import Modal from 'flarum/components/Modal';
export default class LoadingModal extends Modal {
isDismissible() {
return false;
}
className() {
return 'LoadingModal Modal--small';
}
title() {
return 'Please Wait...';
}
content() {
return '';
}
}

View File

@ -28,6 +28,7 @@ export default class Modal extends Component {
return ( return (
<div className={'Modal modal-dialog ' + this.className()}> <div className={'Modal modal-dialog ' + this.className()}>
<div className="Modal-content"> <div className="Modal-content">
{this.isDismissible() ? (
<div className="Modal-close App-backControl"> <div className="Modal-close App-backControl">
{Button.component({ {Button.component({
icon: 'times', icon: 'times',
@ -35,6 +36,7 @@ export default class Modal extends Component {
className: 'Button Button--icon Button--link' className: 'Button Button--icon Button--link'
})} })}
</div> </div>
) : ''}
<form onsubmit={this.onsubmit.bind(this)}> <form onsubmit={this.onsubmit.bind(this)}>
<div className="Modal-header"> <div className="Modal-header">
@ -50,6 +52,15 @@ export default class Modal extends Component {
); );
} }
/**
* Determine whether or not the modal should be dismissible via an 'x' button.
*
* @return {Boolean}
*/
isDismissible() {
return true;
}
/** /**
* Get the class name to apply to the modal. * Get the class name to apply to the modal.
* *

View File

@ -50,7 +50,7 @@ export default class ModalManager extends Component {
m.redraw(true); m.redraw(true);
this.$().modal('show'); this.$().modal({backdrop: this.component.isDismissible() ? true : 'static'}).modal('show');
this.onready(); this.onready();
} }

View File

@ -22,6 +22,10 @@
.ExtensionListItem.disabled .ExtensionListItem-content { .ExtensionListItem.disabled .ExtensionListItem-content {
opacity: 0.5; opacity: 0.5;
color: @muted-color; color: @muted-color;
.ExtensionListItem-icon {
opacity: 0.5;
}
} }
.ExtensionListItem-controls { .ExtensionListItem-controls {
float: right; float: right;
@ -41,6 +45,9 @@
.ExtensionListItem-icon { .ExtensionListItem-icon {
float: left; float: left;
margin-left: -42px; margin-left: -42px;
text-align: center;
padding: 3px;
font-size: 14px;
} }
.ExtensionListItem-title { .ExtensionListItem-title {
font-size: 14px; font-size: 14px;

View File

@ -3,6 +3,7 @@
padding-top: @header-height; padding-top: @header-height;
padding-bottom: 50px; padding-bottom: 50px;
overflow-x: hidden; overflow-x: hidden;
min-height: 100vh;
@media @phone { @media @phone {
padding-top: @header-height-phone; padding-top: @header-height-phone;