From 4c2ff6e82db74a99d8fffbdfcc9f2b212b3ce9a8 Mon Sep 17 00:00:00 2001 From: Toby Zerner Date: Mon, 12 Oct 2015 15:02:59 +1030 Subject: [PATCH] Revamp admin extensions page - New look - Groups extensions by keywords --- js/admin/src/components/ExtensionsPage.js | 92 +++++++++++++---------- less/admin/ExtensionsPage.less | 86 +++++++++++++-------- src/Extension/ExtensionManager.php | 6 ++ 3 files changed, 116 insertions(+), 68 deletions(-) diff --git a/js/admin/src/components/ExtensionsPage.js b/js/admin/src/components/ExtensionsPage.js index 7b111dc54..5d7bdf35a 100644 --- a/js/admin/src/components/ExtensionsPage.js +++ b/js/admin/src/components/ExtensionsPage.js @@ -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 (
@@ -25,33 +52,31 @@ export default class ExtensionsPage extends Component {
-
    - {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
  • - {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 => ( +
    +

    {group.title}

    +
      + {group.extensions + .sort((a, b) => a.extra['flarum-extension'].title.localeCompare(b.extra['flarum-extension'].title)) + .map(extension => { + return
    • +
        + {listItems(this.controlItems(extension.id).toArray())} +
      +
      + + {extension.extra['flarum-extension'].icon ? icon(extension.extra['flarum-extension'].icon.name) : ''} + +

      + {extension.extra['flarum-extension'].title} +

      +
      {extension.version}
      +
      +
    • ; })} -
      - - {extension.extra['flarum-extension'].icon ? icon(extension.extra['flarum-extension'].icon.name) : ''} - -

      - {extension.extra['flarum-extension'].title} {' '} - {extension.version} -

      -
      {extension.description}
      -
      - ; - })} -
    +
+
+ ))}
@@ -63,14 +88,10 @@ export default class ExtensionsPage extends Component { const extension = app.extensions[name]; const enabled = this.isEnabled(name); - items.add('info', - Package Name: {extension.name}
- Installed in: {name} -
); - 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; } diff --git a/less/admin/ExtensionsPage.less b/less/admin/ExtensionsPage.less index da8caf68a..bab8d548b 100644 --- a/less/admin/ExtensionsPage.less +++ b/less/admin/ExtensionsPage.less @@ -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; } diff --git a/src/Extension/ExtensionManager.php b/src/Extension/ExtensionManager.php index f1a8617a6..31c7b4700 100644 --- a/src/Extension/ExtensionManager.php +++ b/src/Extension/ExtensionManager.php @@ -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; } }