From c3989cc9525de9d2493c2e6a5868eda41435ecf8 Mon Sep 17 00:00:00 2001 From: Charlie <13856015+KyrneDev@users.noreply.github.com> Date: Tue, 24 Nov 2020 09:44:40 -0800 Subject: [PATCH] AdminUX Overhaul (#2409) - Extensions now have their own pages - The API for extensions to register permissions and settings has been overhauled via the `flarum/admin/utils/ExtensionData` util - An extension grid has been added as a widget to the Dashboard page --- js/src/admin/AdminApplication.js | 26 +- js/src/admin/compat.js | 18 +- js/src/admin/components/AdminHeader.js | 19 + js/src/admin/components/AdminNav.js | 138 ++++--- js/src/admin/components/AppearancePage.js | 8 + js/src/admin/components/BasicsPage.js | 4 + js/src/admin/components/DashboardPage.js | 17 +- .../admin/components/ExtensionLinkButton.js | 29 ++ js/src/admin/components/ExtensionPage.js | 376 ++++++++++++++++++ .../components/ExtensionPermissionGrid.js | 39 ++ js/src/admin/components/ExtensionsPage.js | 158 -------- js/src/admin/components/ExtensionsWidget.js | 48 +++ js/src/admin/components/HeaderSecondary.js | 8 + js/src/admin/components/MailPage.js | 8 +- js/src/admin/components/PermissionGrid.js | 50 +-- js/src/admin/components/PermissionsPage.js | 4 + .../admin/resolvers/ExtensionPageResolver.ts | 19 + js/src/admin/routes.js | 5 +- js/src/admin/utils/ExtensionData.js | 167 ++++++++ .../admin/utils/getCategorizedExtensions.js | 25 ++ js/src/admin/utils/isExtensionEnabled.js | 5 + js/src/common/components/Button.js | 5 + js/src/common/components/SelectDropdown.js | 3 + less/admin.less | 4 +- less/admin/AdminHeader.less | 19 + less/admin/AdminNav.less | 201 ++++++++-- less/admin/AppearancePage.less | 2 +- less/admin/BasicsPage.less | 1 - less/admin/DashboardPage.less | 13 +- less/admin/ExtensionPage.less | 153 +++++++ less/admin/ExtensionWidget.less | 93 +++++ less/admin/ExtensionsPage.less | 115 ------ less/admin/MailPage.less | 1 - less/admin/PermissionsPage.less | 7 +- 34 files changed, 1362 insertions(+), 426 deletions(-) create mode 100644 js/src/admin/components/AdminHeader.js create mode 100644 js/src/admin/components/ExtensionLinkButton.js create mode 100644 js/src/admin/components/ExtensionPage.js create mode 100644 js/src/admin/components/ExtensionPermissionGrid.js delete mode 100644 js/src/admin/components/ExtensionsPage.js create mode 100644 js/src/admin/components/ExtensionsWidget.js create mode 100644 js/src/admin/resolvers/ExtensionPageResolver.ts create mode 100644 js/src/admin/utils/ExtensionData.js create mode 100644 js/src/admin/utils/getCategorizedExtensions.js create mode 100644 js/src/admin/utils/isExtensionEnabled.js create mode 100644 less/admin/AdminHeader.less create mode 100644 less/admin/ExtensionPage.less create mode 100644 less/admin/ExtensionWidget.less delete mode 100644 less/admin/ExtensionsPage.less diff --git a/js/src/admin/AdminApplication.js b/js/src/admin/AdminApplication.js index 1e75a3c30..153ec13a7 100644 --- a/js/src/admin/AdminApplication.js +++ b/js/src/admin/AdminApplication.js @@ -1,13 +1,29 @@ import HeaderPrimary from './components/HeaderPrimary'; import HeaderSecondary from './components/HeaderSecondary'; import routes from './routes'; +import ExtensionPage from './components/ExtensionPage'; import Application from '../common/Application'; import Navigation from '../common/components/Navigation'; import AdminNav from './components/AdminNav'; +import ExtensionData from './utils/ExtensionData'; export default class AdminApplication extends Application { + // Deprecated as of beta 15 extensionSettings = {}; + extensionData = new ExtensionData(); + + extensionCategories = { + discussion: 70, + moderation: 60, + feature: 50, + formatting: 40, + theme: 30, + authentication: 20, + language: 10, + other: 0, + }; + history = { canGoBack: () => true, getPrevious: () => {}, @@ -34,7 +50,13 @@ export default class AdminApplication extends Application { m.route.prefix = '#'; super.mount(); - m.mount(document.getElementById('app-navigation'), { view: () => Navigation.component({ className: 'App-backControl', drawer: true }) }); + m.mount(document.getElementById('app-navigation'), { + view: () => + Navigation.component({ + className: 'App-backControl', + drawer: true, + }), + }); m.mount(document.getElementById('header-navigation'), Navigation); m.mount(document.getElementById('header-primary'), HeaderPrimary); m.mount(document.getElementById('header-secondary'), HeaderSecondary); @@ -43,7 +65,7 @@ export default class AdminApplication extends Application { // If an extension has just been enabled, then we will run its settings // callback. const enabled = localStorage.getItem('enabledExtension'); - if (enabled && this.extensionSettings[enabled]) { + if (enabled && this.extensionSettings[enabled] && typeof this.extensionSettings[enabled] === 'function') { this.extensionSettings[enabled](); localStorage.removeItem('enabledExtension'); } diff --git a/js/src/admin/compat.js b/js/src/admin/compat.js index 84bc61671..117e92d35 100644 --- a/js/src/admin/compat.js +++ b/js/src/admin/compat.js @@ -1,17 +1,21 @@ import compat from '../common/compat'; import saveSettings from './utils/saveSettings'; +import ExtensionData from './utils/ExtensionData'; +import isExtensionEnabled from './utils/isExtensionEnabled'; +import getCategorizedExtensions from './utils/getCategorizedExtensions'; import SettingDropdown from './components/SettingDropdown'; import EditCustomFooterModal from './components/EditCustomFooterModal'; import SessionDropdown from './components/SessionDropdown'; import HeaderPrimary from './components/HeaderPrimary'; import AppearancePage from './components/AppearancePage'; import StatusWidget from './components/StatusWidget'; +import ExtensionsWidget from './components/ExtensionsWidget'; import HeaderSecondary from './components/HeaderSecondary'; import SettingsModal from './components/SettingsModal'; import DashboardWidget from './components/DashboardWidget'; -import AddExtensionModal from './components/AddExtensionModal'; -import ExtensionsPage from './components/ExtensionsPage'; +import ExtensionPage from './components/ExtensionPage'; +import ExtensionLinkButton from './components/ExtensionLinkButton'; import AdminLinkButton from './components/AdminLinkButton'; import PermissionGrid from './components/PermissionGrid'; import MailPage from './components/MailPage'; @@ -23,6 +27,7 @@ import EditCustomHeaderModal from './components/EditCustomHeaderModal'; import PermissionsPage from './components/PermissionsPage'; import PermissionDropdown from './components/PermissionDropdown'; import AdminNav from './components/AdminNav'; +import AdminHeader from './components/AdminHeader'; import EditCustomCssModal from './components/EditCustomCssModal'; import EditGroupModal from './components/EditGroupModal'; import routes from './routes'; @@ -30,17 +35,21 @@ import AdminApplication from './AdminApplication'; export default Object.assign(compat, { 'utils/saveSettings': saveSettings, + 'utils/ExtensionData': ExtensionData, + 'utils/isExtensionEnabled': isExtensionEnabled, + 'utils/getCategorizedExtensions': getCategorizedExtensions, 'components/SettingDropdown': SettingDropdown, 'components/EditCustomFooterModal': EditCustomFooterModal, 'components/SessionDropdown': SessionDropdown, 'components/HeaderPrimary': HeaderPrimary, 'components/AppearancePage': AppearancePage, 'components/StatusWidget': StatusWidget, + 'components/ExtensionsWidget': ExtensionsWidget, 'components/HeaderSecondary': HeaderSecondary, 'components/SettingsModal': SettingsModal, 'components/DashboardWidget': DashboardWidget, - 'components/AddExtensionModal': AddExtensionModal, - 'components/ExtensionsPage': ExtensionsPage, + 'components/ExtensionPage': ExtensionPage, + 'components/ExtensionLinkButton': ExtensionLinkButton, 'components/AdminLinkButton': AdminLinkButton, 'components/PermissionGrid': PermissionGrid, 'components/MailPage': MailPage, @@ -52,6 +61,7 @@ export default Object.assign(compat, { 'components/PermissionsPage': PermissionsPage, 'components/PermissionDropdown': PermissionDropdown, 'components/AdminNav': AdminNav, + 'components/AdminHeader': AdminHeader, 'components/EditCustomCssModal': EditCustomCssModal, 'components/EditGroupModal': EditGroupModal, routes: routes, diff --git a/js/src/admin/components/AdminHeader.js b/js/src/admin/components/AdminHeader.js new file mode 100644 index 000000000..5472a8064 --- /dev/null +++ b/js/src/admin/components/AdminHeader.js @@ -0,0 +1,19 @@ +import Component from '../../common/Component'; +import classList from '../../common/utils/classList'; +import icon from '../../common/helpers/icon'; + +export default class AdminHeader extends Component { + view(vnode) { + return [ +