mirror of
https://github.com/flarum/framework.git
synced 2024-12-05 09:03:36 +08:00
Revamp admin extensions page
- New look - Groups extensions by keywords
This commit is contained in:
parent
a03dcd4e3f
commit
b3e52c0474
|
@ -7,9 +7,36 @@ import AddExtensionModal from 'flarum/components/AddExtensionModal';
|
|||
import LoadingModal from 'flarum/components/LoadingModal';
|
||||
import ItemList from 'flarum/utils/ItemList';
|
||||
import icon from 'flarum/helpers/icon';
|
||||
import listItems from 'flarum/helpers/listItems';
|
||||
|
||||
export default class ExtensionsPage extends Component {
|
||||
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 (
|
||||
<div className="ExtensionsPage">
|
||||
<div className="ExtensionsPage-header">
|
||||
|
@ -25,33 +52,31 @@ export default class ExtensionsPage extends Component {
|
|||
|
||||
<div className="ExtensionsPage-list">
|
||||
<div className="container">
|
||||
<ul className="ExtensionList">
|
||||
{Object.keys(app.extensions)
|
||||
.sort((a, b) => app.extensions[a].extra['flarum-extension'].title.localeCompare(app.extensions[b].extra['flarum-extension'].title))
|
||||
.map(name => {
|
||||
const extension = app.extensions[name];
|
||||
|
||||
return <li className={'ExtensionListItem ' + (!this.isEnabled(name) ? 'disabled' : '')}>
|
||||
{Dropdown.component({
|
||||
icon: 'ellipsis-v',
|
||||
children: this.controlItems(name).toArray(),
|
||||
className: 'ExtensionListItem-controls',
|
||||
buttonClassName: 'Button Button--icon Button--flat',
|
||||
menuClassName: 'Dropdown-menu--right'
|
||||
{groups.filter(group => group.extensions.length).map(group => (
|
||||
<div className="ExtensionGroup">
|
||||
<h3>{group.title}</h3>
|
||||
<ul className="ExtensionList">
|
||||
{group.extensions
|
||||
.sort((a, b) => a.extra['flarum-extension'].title.localeCompare(b.extra['flarum-extension'].title))
|
||||
.map(extension => {
|
||||
return <li className={'ExtensionListItem ' + (!this.isEnabled(extension.id) ? 'disabled' : '')}>
|
||||
<ul className="ExtensionListItem-controls" style={extension.extra['flarum-extension'].icon}>
|
||||
{listItems(this.controlItems(extension.id).toArray())}
|
||||
</ul>
|
||||
<div className="ExtensionListItem-content">
|
||||
<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">
|
||||
<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">
|
||||
{extension.extra['flarum-extension'].title} {' '}
|
||||
<small className="ExtensionListItem-version">{extension.version}</small>
|
||||
</h4>
|
||||
<div className="ExtensionListItem-description">{extension.description}</div>
|
||||
</div>
|
||||
</li>;
|
||||
})}
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -63,14 +88,10 @@ export default class ExtensionsPage extends Component {
|
|||
const extension = app.extensions[name];
|
||||
const enabled = this.isEnabled(name);
|
||||
|
||||
items.add('info', <span>
|
||||
Package Name: {extension.name}<br/>
|
||||
Installed in: {name}
|
||||
</span>);
|
||||
|
||||
if (app.extensionSettings[name]) {
|
||||
items.add('settings', Button.component({
|
||||
icon: 'cog',
|
||||
className: 'Button',
|
||||
children: 'Settings',
|
||||
onclick: app.extensionSettings[name]
|
||||
}));
|
||||
|
@ -78,6 +99,7 @@ export default class ExtensionsPage extends Component {
|
|||
|
||||
items.add('toggle', Button.component({
|
||||
icon: 'power-off',
|
||||
className: 'Button',
|
||||
children: enabled ? 'Disable' : 'Enable',
|
||||
onclick: () => {
|
||||
app.request({
|
||||
|
@ -93,6 +115,7 @@ export default class ExtensionsPage extends Component {
|
|||
if (!enabled) {
|
||||
items.add('uninstall', Button.component({
|
||||
icon: 'trash-o',
|
||||
className: 'Button',
|
||||
children: 'Uninstall',
|
||||
onclick: () => {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,16 @@
|
|||
.ExtensionsPage-list {
|
||||
padding: 30px 0;
|
||||
}
|
||||
.ExtensionGroup {
|
||||
margin-bottom: 20px;
|
||||
|
||||
h3 {
|
||||
color: @muted-color;
|
||||
text-transform: uppercase;
|
||||
font-size: 12px;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.ExtensionList {
|
||||
margin: 0;
|
||||
|
@ -15,8 +25,8 @@
|
|||
|
||||
> li {
|
||||
float: left;
|
||||
width: 350px;
|
||||
height: 80px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
.ExtensionListItem.disabled .ExtensionListItem-content {
|
||||
|
@ -28,48 +38,64 @@
|
|||
}
|
||||
}
|
||||
.ExtensionListItem-controls {
|
||||
float: right;
|
||||
margin-top: -5px;
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: 120px;
|
||||
border-radius: 6px;
|
||||
background-image: none !important;
|
||||
opacity: 0;
|
||||
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 {
|
||||
visibility: visible;
|
||||
.ExtensionListItem:hover & {
|
||||
opacity: 1;
|
||||
}
|
||||
> li {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.Button {
|
||||
.Button--block();
|
||||
}
|
||||
}
|
||||
.ExtensionListItem {
|
||||
padding-left: 42px;
|
||||
padding-right: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
.ExtensionListItem-icon {
|
||||
float: left;
|
||||
margin-left: -42px;
|
||||
text-align: center;
|
||||
padding: 3px;
|
||||
font-size: 14px;
|
||||
width: 120px;
|
||||
height: 160px;
|
||||
margin-right: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.ExtensionListItem-title {
|
||||
font-size: 14px;
|
||||
margin: 3px 0 5px;
|
||||
|
||||
small {
|
||||
color: @muted-more-color;
|
||||
font-size: 11px;
|
||||
font-weight: normal;
|
||||
margin-left: 5px;
|
||||
}
|
||||
margin: 10px 0 2px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.ExtensionListItem-description {
|
||||
font-size: 12px;
|
||||
color: @muted-color;
|
||||
.ExtensionListItem-version {
|
||||
color: @muted-more-color;
|
||||
font-size: 11px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.ExtensionIcon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
background: @control-bg;
|
||||
color: @control-color;
|
||||
border-radius: 6px;
|
||||
display: inline-block;
|
||||
font-size: 60px;
|
||||
line-height: 120px;
|
||||
text-align: center;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,10 @@ class ExtensionManager
|
|||
if (file_exists($manifest = $extensionsDir . '/' . $dir . '/composer.json')) {
|
||||
$extension = json_decode(file_get_contents($manifest), true);
|
||||
|
||||
if (empty($extension['name'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($extension['extra']['flarum-extension']['icon'])) {
|
||||
$icon = &$extension['extra']['flarum-extension']['icon'];
|
||||
|
||||
|
@ -76,6 +80,8 @@ class ExtensionManager
|
|||
}
|
||||
}
|
||||
|
||||
$extension['id'] = $dir;
|
||||
|
||||
$extensions[$dir] = $extension;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user