1
0
mirror of https://github.com/flarum/core.git synced 2025-05-07 07:55:44 +02:00

Revamp admin extensions page

- New look
- Groups extensions by keywords
This commit is contained in:
Toby Zerner 2015-10-12 15:02:59 +10:30
parent b53e612007
commit 4c2ff6e82d
3 changed files with 116 additions and 68 deletions

View File

@ -7,9 +7,36 @@ import AddExtensionModal from 'flarum/components/AddExtensionModal';
import LoadingModal from 'flarum/components/LoadingModal'; import LoadingModal from 'flarum/components/LoadingModal';
import ItemList from 'flarum/utils/ItemList'; import ItemList from 'flarum/utils/ItemList';
import icon from 'flarum/helpers/icon'; import icon from 'flarum/helpers/icon';
import listItems from 'flarum/helpers/listItems';
export default class ExtensionsPage extends Component { export default class ExtensionsPage extends Component {
view() { view() {
const groups = [
{keyword: 'discussion', title: 'Discussions', extensions: []},
{keyword: 'formatting', title: 'Formatting', extensions: []},
{keyword: 'moderation', title: 'Moderation', extensions: []},
{keyword: 'theme', title: 'Themes', extensions: []},
{keyword: 'authentication', title: 'Authentication', extensions: []},
{keyword: 'locale', title: 'Language Packs', extensions: []},
{title: 'Other', extensions: []}
];
Object.keys(app.extensions).forEach(id => {
const extension = app.extensions[id];
const keywords = extension.keywords;
const grouped = keywords && groups.some(group => {
if (keywords.indexOf(group.keyword) !== -1) {
group.extensions.push(extension);
return true;
}
});
if (!grouped) {
groups[groups.length - 1].extensions.push(extension);
}
});
return ( return (
<div className="ExtensionsPage"> <div className="ExtensionsPage">
<div className="ExtensionsPage-header"> <div className="ExtensionsPage-header">
@ -25,33 +52,31 @@ export default class ExtensionsPage extends Component {
<div className="ExtensionsPage-list"> <div className="ExtensionsPage-list">
<div className="container"> <div className="container">
<ul className="ExtensionList"> {groups.filter(group => group.extensions.length).map(group => (
{Object.keys(app.extensions) <div className="ExtensionGroup">
.sort((a, b) => app.extensions[a].extra['flarum-extension'].title.localeCompare(app.extensions[b].extra['flarum-extension'].title)) <h3>{group.title}</h3>
.map(name => { <ul className="ExtensionList">
const extension = app.extensions[name]; {group.extensions
.sort((a, b) => a.extra['flarum-extension'].title.localeCompare(b.extra['flarum-extension'].title))
return <li className={'ExtensionListItem ' + (!this.isEnabled(name) ? 'disabled' : '')}> .map(extension => {
{Dropdown.component({ return <li className={'ExtensionListItem ' + (!this.isEnabled(extension.id) ? 'disabled' : '')}>
icon: 'ellipsis-v', <ul className="ExtensionListItem-controls" style={extension.extra['flarum-extension'].icon}>
children: this.controlItems(name).toArray(), {listItems(this.controlItems(extension.id).toArray())}
className: 'ExtensionListItem-controls', </ul>
buttonClassName: 'Button Button--icon Button--flat', <div className="ExtensionListItem-content">
menuClassName: 'Dropdown-menu--right' <span className="ExtensionListItem-icon ExtensionIcon" style={extension.extra['flarum-extension'].icon}>
{extension.extra['flarum-extension'].icon ? icon(extension.extra['flarum-extension'].icon.name) : ''}
</span>
<h4 className="ExtensionListItem-title" title={extension.description}>
{extension.extra['flarum-extension'].title}
</h4>
<div className="ExtensionListItem-version">{extension.version}</div>
</div>
</li>;
})} })}
<div className="ExtensionListItem-content"> </ul>
<span className="ExtensionListItem-icon ExtensionIcon" style={extension.extra['flarum-extension'].icon}> </div>
{extension.extra['flarum-extension'].icon ? icon(extension.extra['flarum-extension'].icon.name) : ''} ))}
</span>
<h4 className="ExtensionListItem-title">
{extension.extra['flarum-extension'].title} {' '}
<small className="ExtensionListItem-version">{extension.version}</small>
</h4>
<div className="ExtensionListItem-description">{extension.description}</div>
</div>
</li>;
})}
</ul>
</div> </div>
</div> </div>
</div> </div>
@ -63,14 +88,10 @@ export default class ExtensionsPage extends Component {
const extension = app.extensions[name]; const extension = app.extensions[name];
const enabled = this.isEnabled(name); const enabled = this.isEnabled(name);
items.add('info', <span>
Package Name: {extension.name}<br/>
Installed in: {name}
</span>);
if (app.extensionSettings[name]) { if (app.extensionSettings[name]) {
items.add('settings', Button.component({ items.add('settings', Button.component({
icon: 'cog', icon: 'cog',
className: 'Button',
children: 'Settings', children: 'Settings',
onclick: app.extensionSettings[name] onclick: app.extensionSettings[name]
})); }));
@ -78,6 +99,7 @@ export default class ExtensionsPage extends Component {
items.add('toggle', Button.component({ items.add('toggle', Button.component({
icon: 'power-off', icon: 'power-off',
className: 'Button',
children: enabled ? 'Disable' : 'Enable', children: enabled ? 'Disable' : 'Enable',
onclick: () => { onclick: () => {
app.request({ app.request({
@ -93,6 +115,7 @@ export default class ExtensionsPage extends Component {
if (!enabled) { if (!enabled) {
items.add('uninstall', Button.component({ items.add('uninstall', Button.component({
icon: 'trash-o', icon: 'trash-o',
className: 'Button',
children: 'Uninstall', children: 'Uninstall',
onclick: () => { onclick: () => {
app.request({ app.request({
@ -105,13 +128,6 @@ export default class ExtensionsPage extends Component {
})); }));
} }
// items.add('separator2', Separator.component());
// items.add('support', LinkButton.component({
// icon: 'support',
// children: 'Support'
// }));
return items; return items;
} }

View File

@ -6,6 +6,16 @@
.ExtensionsPage-list { .ExtensionsPage-list {
padding: 30px 0; padding: 30px 0;
} }
.ExtensionGroup {
margin-bottom: 20px;
h3 {
color: @muted-color;
text-transform: uppercase;
font-size: 12px;
margin: 0 0 10px;
}
}
.ExtensionList { .ExtensionList {
margin: 0; margin: 0;
@ -15,8 +25,8 @@
> li { > li {
float: left; float: left;
width: 350px; text-align: center;
height: 80px; position: relative;
} }
} }
.ExtensionListItem.disabled .ExtensionListItem-content { .ExtensionListItem.disabled .ExtensionListItem-content {
@ -28,48 +38,64 @@
} }
} }
.ExtensionListItem-controls { .ExtensionListItem-controls {
float: right; position: absolute;
margin-top: -5px; left: 0;
visibility: hidden; right: 0;
top: 0;
height: 120px;
border-radius: 6px;
background-image: none !important;
opacity: 0;
z-index: 1; z-index: 1;
margin: 0;
padding: 5px 5px 0;
.light-contents();
.transition(opacity 0.2s);
display: flex;
align-items: stretch;
align-content: stretch;
flex-direction: column;
.ExtensionListItem:hover &, &.open { .ExtensionListItem:hover & {
visibility: visible; opacity: 1;
}
> li {
display: flex;
width: 100%;
height: 100%;
margin-bottom: 5px;
}
.Button {
.Button--block();
} }
} }
.ExtensionListItem { .ExtensionListItem {
padding-left: 42px; width: 120px;
padding-right: 20px; height: 160px;
padding-bottom: 20px; margin-right: 15px;
} margin-bottom: 15px;
.ExtensionListItem-icon {
float: left;
margin-left: -42px;
text-align: center;
padding: 3px;
font-size: 14px;
} }
.ExtensionListItem-title { .ExtensionListItem-title {
font-size: 14px; font-size: 14px;
margin: 3px 0 5px; margin: 10px 0 2px;
white-space: nowrap;
small { overflow: hidden;
color: @muted-more-color; text-overflow: ellipsis;
font-size: 11px;
font-weight: normal;
margin-left: 5px;
}
} }
.ExtensionListItem-description { .ExtensionListItem-version {
font-size: 12px; color: @muted-more-color;
color: @muted-color; font-size: 11px;
font-weight: normal;
} }
.ExtensionIcon { .ExtensionIcon {
width: 28px; width: 120px;
height: 28px; height: 120px;
background: @control-bg; background: @control-bg;
color: @control-color; color: @control-color;
border-radius: 6px; border-radius: 6px;
display: inline-block; display: inline-block;
font-size: 60px;
line-height: 120px;
text-align: center;
} }

View File

@ -53,6 +53,10 @@ class ExtensionManager
if (file_exists($manifest = $extensionsDir . '/' . $dir . '/composer.json')) { if (file_exists($manifest = $extensionsDir . '/' . $dir . '/composer.json')) {
$extension = json_decode(file_get_contents($manifest), true); $extension = json_decode(file_get_contents($manifest), true);
if (empty($extension['name'])) {
continue;
}
if (isset($extension['extra']['flarum-extension']['icon'])) { if (isset($extension['extra']['flarum-extension']['icon'])) {
$icon = &$extension['extra']['flarum-extension']['icon']; $icon = &$extension['extra']['flarum-extension']['icon'];
@ -76,6 +80,8 @@ class ExtensionManager
} }
} }
$extension['id'] = $dir;
$extensions[$dir] = $extension; $extensions[$dir] = $extension;
} }
} }