diff --git a/framework/core/js/admin/src/components/ExtensionsPage.js b/framework/core/js/admin/src/components/ExtensionsPage.js
index 5d7bdf35a..cc49dfce6 100644
--- a/framework/core/js/admin/src/components/ExtensionsPage.js
+++ b/framework/core/js/admin/src/components/ExtensionsPage.js
@@ -11,31 +11,7 @@ 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);
- }
- });
+ const extensions = Object.keys(app.extensions).map(id => app.extensions[id]);
return (
@@ -52,31 +28,35 @@ export default class ExtensionsPage extends Component {
- {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}
-
- ;
- })}
-
-
- ))}
+
+ {extensions
+ .sort((a, b) => a.extra['flarum-extension'].title.localeCompare(b.extra['flarum-extension'].title))
+ .map(extension => {
+ const controls = this.controlItems(extension.id).toArray();
+
+ return -
+
+
+ {extension.extra['flarum-extension'].icon ? icon(extension.extra['flarum-extension'].icon.name) : ''}
+
+ {controls.length ? (
+
+ {controls}
+
+ ) : ''}
+
+
{extension.version}
+
+ ;
+ })}
+
@@ -85,37 +65,19 @@ export default class ExtensionsPage extends Component {
controlItems(name) {
const items = new ItemList();
- const extension = app.extensions[name];
const enabled = this.isEnabled(name);
if (app.extensionSettings[name]) {
items.add('settings', Button.component({
icon: 'cog',
- className: 'Button',
children: 'Settings',
onclick: app.extensionSettings[name]
}));
}
- items.add('toggle', Button.component({
- icon: 'power-off',
- className: 'Button',
- children: enabled ? 'Disable' : 'Enable',
- onclick: () => {
- app.request({
- url: app.forum.attribute('apiUrl') + '/extensions/' + name,
- method: 'PATCH',
- data: {enabled: !enabled}
- }).then(() => window.location.reload());
-
- app.modal.show(new LoadingModal());
- }
- }));
-
if (!enabled) {
items.add('uninstall', Button.component({
icon: 'trash-o',
- className: 'Button',
children: 'Uninstall',
onclick: () => {
app.request({
@@ -136,4 +98,19 @@ export default class ExtensionsPage extends Component {
return enabled.indexOf(name) !== -1;
}
+
+ toggle(id) {
+ const enabled = this.isEnabled(id);
+
+ app.request({
+ url: app.forum.attribute('apiUrl') + '/extensions/' + id,
+ method: 'PATCH',
+ data: {enabled: !enabled}
+ }).then(() => {
+ if (enabled) localStorage.setItem('enabledExtension', id);
+ window.location.reload();
+ });
+
+ app.modal.show(new LoadingModal());
+ }
}
diff --git a/framework/core/js/admin/src/initializers/boot.js b/framework/core/js/admin/src/initializers/boot.js
index ff2760bd8..ea253756e 100644
--- a/framework/core/js/admin/src/initializers/boot.js
+++ b/framework/core/js/admin/src/initializers/boot.js
@@ -54,4 +54,12 @@ export default function boot(app) {
}).start();
app.booted = true;
+
+ // If an extension has just been enabled, then we will run its settings
+ // callback.
+ const enabled = localStorage.getItem('enabledExtension');
+ if (enabled && app.extensionSettings[enabled]) {
+ app.extensionSettings[enabled]();
+ localStorage.removeItem('enabledExtension');
+ }
}
diff --git a/framework/core/less/admin/ExtensionsPage.less b/framework/core/less/admin/ExtensionsPage.less
index bab8d548b..02b74b473 100644
--- a/framework/core/less/admin/ExtensionsPage.less
+++ b/framework/core/less/admin/ExtensionsPage.less
@@ -25,50 +25,19 @@
> li {
float: left;
- text-align: center;
+ text-align: left;
position: relative;
}
}
-.ExtensionListItem.disabled .ExtensionListItem-content {
- opacity: 0.5;
- color: @muted-color;
-
+.ExtensionListItem.disabled {
+ .ExtensionListItem-title {
+ opacity: 0.5;
+ color: @muted-color;
+ }
.ExtensionListItem-icon {
opacity: 0.5;
}
}
-.ExtensionListItem-controls {
- 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 & {
- opacity: 1;
- }
- > li {
- display: flex;
- width: 100%;
- height: 100%;
- margin-bottom: 5px;
- }
- .Button {
- .Button--block();
- }
-}
.ExtensionListItem {
width: 120px;
height: 160px;
@@ -76,17 +45,30 @@
margin-bottom: 15px;
}
.ExtensionListItem-title {
- font-size: 14px;
- margin: 10px 0 2px;
+ display: block;
+ font-size: 13px;
+ font-weight: bold;
+ margin: 8px 0 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
+ cursor: pointer;
}
.ExtensionListItem-version {
color: @muted-more-color;
font-size: 11px;
font-weight: normal;
}
+.ExtensionListItem-controls {
+ float: right;
+ display: none;
+ margin-right: -5px;
+ margin-top: 1px;
+
+ .ExtensionListItem:hover &, &.open {
+ display: block;
+ }
+}
.ExtensionIcon {
width: 120px;