Rough extension management implementation

This commit is contained in:
Toby Zerner
2015-08-03 12:03:30 +09:30
parent 66ee6e57ee
commit 70901b1420
13 changed files with 370 additions and 8 deletions

View File

@ -12,4 +12,6 @@ app.initializers.add('routes', routes);
app.initializers.add('preload', preload, -100);
app.initializers.add('boot', boot, -100);
app.extensionSettings = {};
export default app;

View File

@ -0,0 +1,21 @@
import Modal from 'flarum/components/Modal';
export default class AddExtensionModal extends Modal {
className() {
return 'AddExtensionModal Modal--small';
}
title() {
return 'Add Extension';
}
content() {
return (
<div className="Modal-body">
<p>One day, this dialog will allow you to add an extension to your forum with ease. We're building an ecosystem as we speak!</p>
<p>In the meantime, if you manage to get your hands on a new extension, simply drop it in your forum's <code>extensions</code> directory.</p>
<p>If you're a developer, you can <a href="">read the docs</a> and have a go at building your own.</p>
</div>
);
}
}

View File

@ -1,9 +1,101 @@
import Component from 'flarum/Component';
import LinkButton from 'flarum/components/LinkButton';
import Button from 'flarum/components/Button';
import Dropdown from 'flarum/components/Dropdown';
import Separator from 'flarum/components/Separator';
import AddExtensionModal from 'flarum/components/AddExtensionModal';
import ItemList from 'flarum/utils/ItemList';
export default class ExtensionsPage extends Component {
view() {
return (
<div className="ExtensionsPage"/>
<div className="ExtensionsPage">
<div className="ExtensionsPage-header">
<div className="container">
{Button.component({
children: 'Add Extension',
icon: 'plus',
className: 'Button Button--primary',
onclick: () => app.modal.show(new AddExtensionModal())
})}
</div>
</div>
<div className="ExtensionsPage-list">
<div className="container">
<ul className="ExtensionList">
{app.extensions
.sort((a, b) => a.name.localeCompare(b.name))
.map(extension => (
<li className={'ExtensionListItem ' + (!this.isEnabled(extension.name) ? 'disabled' : '')}>
{Dropdown.component({
icon: 'ellipsis-v',
children: this.controlItems(extension).toArray(),
className: 'ExtensionListItem-controls',
buttonClassName: 'Button Button--icon Button--flat',
menuClassName: 'Dropdown-menu--right'
})}
<div className="ExtensionListItem-content">
<span className="ExtensionListItem-icon ExtensionIcon"/>
<h4 className="ExtensionListItem-title">
{extension.title}{' '}
<small className="ExtensionListItem-version">{extension.version}</small>
</h4>
<div className="ExtensionListItem-description">{extension.description}</div>
</div>
</li>
))}
</ul>
</div>
</div>
</div>
);
}
controlItems(extension) {
const items = new ItemList();
const enabled = this.isEnabled(extension.name);
if (app.extensionSettings[extension.name]) {
items.add('settings', Button.component({
icon: 'cog',
children: 'Settings',
onclick: app.extensionSettings[extension.name]
}));
}
items.add('toggle', Button.component({
icon: enabled ? 'times' : 'check',
children: enabled ? 'Disable' : 'Enable',
onclick: () => {
app.request({
url: app.forum.attribute('apiUrl') + '/extensions/' + extension.name,
method: 'PATCH',
data: {enabled: !enabled}
}).then(() => window.location.reload());
}
}));
if (!enabled) {
items.add('uninstall', Button.component({
icon: 'trash-o',
children: 'Uninstall'
}));
}
items.add('separator2', Separator.component());
items.add('support', LinkButton.component({
icon: 'support',
children: 'Support'
}));
return items;
}
isEnabled(name) {
const enabled = JSON.parse(app.config.extensions_enabled);
return enabled.indexOf(name) !== -1;
}
}