From f45bbf41b88e1c49ccee1b4fc393fedfa89c7982 Mon Sep 17 00:00:00 2001 From: Gabriel Dutra Date: Thu, 31 Oct 2019 13:25:25 -0300 Subject: [PATCH] Migrate settings-screen to React --- client/app/assets/less/inc/base.less | 6 +-- client/app/components/SettingsWrapper.jsx | 37 +++++++++++++++++++ .../app/components/cards-list/CardsList.less | 1 + client/app/components/settings-screen.html | 21 ----------- client/app/components/settings-screen.js | 16 -------- .../pages/data-sources/DataSourcesList.jsx | 10 ++--- .../app/pages/data-sources/EditDataSource.jsx | 5 ++- .../pages/destinations/DestinationsList.jsx | 10 ++--- .../pages/destinations/EditDestination.jsx | 5 ++- client/app/pages/groups/GroupDataSources.jsx | 7 ++-- client/app/pages/groups/GroupMembers.jsx | 7 ++-- client/app/pages/groups/GroupsList.jsx | 12 +++--- .../query-snippets/QuerySnippetsList.jsx | 12 +++--- .../pages/settings/OrganizationSettings.jsx | 10 ++--- client/app/pages/users/UserProfile.jsx | 8 ++-- client/app/pages/users/UsersList.jsx | 10 ++--- client/app/pages/users/index.js | 4 +- client/app/services/settingsMenu.js | 6 ++- 18 files changed, 91 insertions(+), 96 deletions(-) create mode 100644 client/app/components/SettingsWrapper.jsx delete mode 100644 client/app/components/settings-screen.html delete mode 100644 client/app/components/settings-screen.js diff --git a/client/app/assets/less/inc/base.less b/client/app/assets/less/inc/base.less index 8566d47b5..2a4ce1269 100755 --- a/client/app/assets/less/inc/base.less +++ b/client/app/assets/less/inc/base.less @@ -85,7 +85,7 @@ strong { // Fixed width layout for specific pages @media (min-width: 768px) { - settings-screen, home-page, page-dashboard-list, page-queries-list, page-alerts-list, alert-page, queries-search-results-page, .fixed-container { + .settings-screen, home-page, page-dashboard-list, page-queries-list, page-alerts-list, alert-page, queries-search-results-page, .fixed-container { .container { width: 750px; } @@ -93,7 +93,7 @@ strong { } @media (min-width: 992px) { - settings-screen, home-page, page-dashboard-list, page-queries-list, page-alerts-list, alert-page, queries-search-results-page, .fixed-container { + .settings-screen, home-page, page-dashboard-list, page-queries-list, page-alerts-list, alert-page, queries-search-results-page, .fixed-container { .container { width: 970px; } @@ -101,7 +101,7 @@ strong { } @media (min-width: 1200px) { - settings-screen, home-page, page-dashboard-list, page-queries-list, page-alerts-list, alert-page, queries-search-results-page, .fixed-container { + .settings-screen, home-page, page-dashboard-list, page-queries-list, page-alerts-list, alert-page, queries-search-results-page, .fixed-container { .container { width: 1170px; } diff --git a/client/app/components/SettingsWrapper.jsx b/client/app/components/SettingsWrapper.jsx new file mode 100644 index 000000000..592dd6fff --- /dev/null +++ b/client/app/components/SettingsWrapper.jsx @@ -0,0 +1,37 @@ +import React from 'react'; +import Menu from 'antd/lib/menu'; +import { PageHeader } from '@/components/PageHeader'; +import { $location } from '@/services/ng'; +import settingsMenu from '@/services/settingsMenu'; + + +function wrapSettingsTab(options, WrappedComponent) { + if (options) { + settingsMenu.add(options); + } + + return function SettingsTab(props) { + const activeItem = settingsMenu.getActiveItem($location.path()); + return ( +
+
+ +
+ + {settingsMenu.items.map(item => ( + {item.title} + ))} + +
+
+ +
+
+
+
+
+ ); + }; +} + +export default wrapSettingsTab; diff --git a/client/app/components/cards-list/CardsList.less b/client/app/components/cards-list/CardsList.less index ef9fbb1ab..809581126 100644 --- a/client/app/components/cards-list/CardsList.less +++ b/client/app/components/cards-list/CardsList.less @@ -2,6 +2,7 @@ @import '../../assets/less/inc/variables'; .visual-card-list { + width: 100%; margin: -5px 0 0 -5px; // compensate for .visual-card spacing } diff --git a/client/app/components/settings-screen.html b/client/app/components/settings-screen.html deleted file mode 100644 index d3a3c0a9e..000000000 --- a/client/app/components/settings-screen.html +++ /dev/null @@ -1,21 +0,0 @@ -
- - -
- -
-
- -
-
-
-
diff --git a/client/app/components/settings-screen.js b/client/app/components/settings-screen.js deleted file mode 100644 index 80b168157..000000000 --- a/client/app/components/settings-screen.js +++ /dev/null @@ -1,16 +0,0 @@ -import settingsMenu from '@/services/settingsMenu'; -import template from './settings-screen.html'; - -export default function init(ngModule) { - ngModule.component('settingsScreen', { - transclude: true, - template, - controller($location, currentUser) { - this.settingsMenu = settingsMenu; - this.isActive = menuItem => menuItem.isActive($location.path()); - this.isAvailable = permission => permission === undefined || currentUser.hasPermission(permission); - }, - }); -} - -init.init = true; diff --git a/client/app/pages/data-sources/DataSourcesList.jsx b/client/app/pages/data-sources/DataSourcesList.jsx index 3666ebd77..fd9f8bfad 100644 --- a/client/app/pages/data-sources/DataSourcesList.jsx +++ b/client/app/pages/data-sources/DataSourcesList.jsx @@ -2,7 +2,6 @@ import React from 'react'; import Button from 'antd/lib/button'; import { react2angular } from 'react2angular'; import { isEmpty, get } from 'lodash'; -import settingsMenu from '@/services/settingsMenu'; import { DataSource, IMG_ROOT } from '@/services/data-source'; import { policy } from '@/services/policy'; import navigateTo from '@/services/navigateTo'; @@ -13,6 +12,7 @@ import LoadingState from '@/components/items-list/components/LoadingState'; import CreateSourceDialog from '@/components/CreateSourceDialog'; import DynamicComponent from '@/components/DynamicComponent'; import helper from '@/components/dynamic-form/dynamicFormHelper'; +import wrapSettingsTab from '@/components/SettingsWrapper'; import recordEvent from '@/services/recordEvent'; class DataSourcesList extends React.Component { @@ -115,14 +115,12 @@ class DataSourcesList extends React.Component { } export default function init(ngModule) { - settingsMenu.add({ + ngModule.component('pageDataSourcesList', react2angular(wrapSettingsTab({ permission: 'admin', title: 'Data Sources', path: 'data_sources', order: 1, - }); - - ngModule.component('pageDataSourcesList', react2angular(DataSourcesList)); + }, DataSourcesList))); return routesToAngularRoutes([ { @@ -137,7 +135,7 @@ export default function init(ngModule) { isNewDataSourcePage: true, }, ], { - template: '', + template: '', controller($scope, $exceptionHandler) { 'ngInject'; diff --git a/client/app/pages/data-sources/EditDataSource.jsx b/client/app/pages/data-sources/EditDataSource.jsx index 32910e110..65f0d39aa 100644 --- a/client/app/pages/data-sources/EditDataSource.jsx +++ b/client/app/pages/data-sources/EditDataSource.jsx @@ -12,6 +12,7 @@ import LoadingState from '@/components/items-list/components/LoadingState'; import DynamicForm from '@/components/dynamic-form/DynamicForm'; import helper from '@/components/dynamic-form/dynamicFormHelper'; import HelpTrigger, { TYPES as HELP_TRIGGER_TYPES } from '@/components/HelpTrigger'; +import wrapSettingsTab from '@/components/SettingsWrapper'; class EditDataSource extends React.Component { static propTypes = { @@ -134,11 +135,11 @@ class EditDataSource extends React.Component { } export default function init(ngModule) { - ngModule.component('pageEditDataSource', react2angular(EditDataSource)); + ngModule.component('pageEditDataSource', react2angular(wrapSettingsTab(null, EditDataSource))); return { '/data_sources/:dataSourceId': { - template: '', + template: '', title: 'Data Sources', controller($scope, $exceptionHandler) { 'ngInject'; diff --git a/client/app/pages/destinations/DestinationsList.jsx b/client/app/pages/destinations/DestinationsList.jsx index 2f68efddf..3a95bb81c 100644 --- a/client/app/pages/destinations/DestinationsList.jsx +++ b/client/app/pages/destinations/DestinationsList.jsx @@ -2,7 +2,6 @@ import React from 'react'; import Button from 'antd/lib/button'; import { react2angular } from 'react2angular'; import { isEmpty, get } from 'lodash'; -import settingsMenu from '@/services/settingsMenu'; import { Destination, IMG_ROOT } from '@/services/destination'; import { policy } from '@/services/policy'; import navigateTo from '@/services/navigateTo'; @@ -12,6 +11,7 @@ import CardsList from '@/components/cards-list/CardsList'; import LoadingState from '@/components/items-list/components/LoadingState'; import CreateSourceDialog from '@/components/CreateSourceDialog'; import helper from '@/components/dynamic-form/dynamicFormHelper'; +import wrapSettingsTab from '@/components/SettingsWrapper'; class DestinationsList extends React.Component { state = { @@ -110,14 +110,12 @@ class DestinationsList extends React.Component { } export default function init(ngModule) { - settingsMenu.add({ + ngModule.component('pageDestinationsList', react2angular(wrapSettingsTab({ permission: 'admin', title: 'Alert Destinations', path: 'destinations', order: 4, - }); - - ngModule.component('pageDestinationsList', react2angular(DestinationsList)); + }, DestinationsList))); return routesToAngularRoutes([ { @@ -132,7 +130,7 @@ export default function init(ngModule) { isNewDestinationPage: true, }, ], { - template: '', + template: '', controller($scope, $exceptionHandler) { 'ngInject'; diff --git a/client/app/pages/destinations/EditDestination.jsx b/client/app/pages/destinations/EditDestination.jsx index 91ec92f26..180c73648 100644 --- a/client/app/pages/destinations/EditDestination.jsx +++ b/client/app/pages/destinations/EditDestination.jsx @@ -11,6 +11,7 @@ import PromiseRejectionError from '@/lib/promise-rejection-error'; import LoadingState from '@/components/items-list/components/LoadingState'; import DynamicForm from '@/components/dynamic-form/DynamicForm'; import helper from '@/components/dynamic-form/dynamicFormHelper'; +import wrapSettingsTab from '@/components/SettingsWrapper'; class EditDestination extends React.Component { static propTypes = { @@ -109,11 +110,11 @@ class EditDestination extends React.Component { } export default function init(ngModule) { - ngModule.component('pageEditDestination', react2angular(EditDestination)); + ngModule.component('pageEditDestination', react2angular(wrapSettingsTab(null, EditDestination))); return { '/destinations/:destinationId': { - template: '', + template: '', title: 'Alert Destinations', controller($scope, $exceptionHandler) { 'ngInject'; diff --git a/client/app/pages/groups/GroupDataSources.jsx b/client/app/pages/groups/GroupDataSources.jsx index 8570dedbb..f50888750 100644 --- a/client/app/pages/groups/GroupDataSources.jsx +++ b/client/app/pages/groups/GroupDataSources.jsx @@ -21,6 +21,7 @@ import GroupName from '@/components/groups/GroupName'; import ListItemAddon from '@/components/groups/ListItemAddon'; import Sidebar from '@/components/groups/DetailsPageSidebar'; import Layout from '@/components/layouts/ContentWithSidebar'; +import wrapSettingsTab from '@/components/SettingsWrapper'; import notification from '@/services/notification'; import { currentUser } from '@/services/auth'; @@ -222,7 +223,7 @@ class GroupDataSources extends React.Component { } export default function init(ngModule) { - ngModule.component('pageGroupDataSources', react2angular(liveItemsList( + ngModule.component('pageGroupDataSources', react2angular(wrapSettingsTab(null, liveItemsList( GroupDataSources, new ResourceItemsSource({ isPlainList: true, @@ -237,7 +238,7 @@ export default function init(ngModule) { }, }), new StateStorage({ orderByField: 'name' }), - ))); + )))); return routesToAngularRoutes([ { @@ -247,7 +248,7 @@ export default function init(ngModule) { }, ], { reloadOnSearch: false, - template: '', + template: '', controller($scope, $exceptionHandler) { 'ngInject'; diff --git a/client/app/pages/groups/GroupMembers.jsx b/client/app/pages/groups/GroupMembers.jsx index e08f158f1..d78ec46e7 100644 --- a/client/app/pages/groups/GroupMembers.jsx +++ b/client/app/pages/groups/GroupMembers.jsx @@ -18,6 +18,7 @@ import GroupName from '@/components/groups/GroupName'; import ListItemAddon from '@/components/groups/ListItemAddon'; import Sidebar from '@/components/groups/DetailsPageSidebar'; import Layout from '@/components/layouts/ContentWithSidebar'; +import wrapSettingsTab from '@/components/SettingsWrapper'; import notification from '@/services/notification'; import { currentUser } from '@/services/auth'; @@ -187,7 +188,7 @@ class GroupMembers extends React.Component { } export default function init(ngModule) { - ngModule.component('pageGroupMembers', react2angular(liveItemsList( + ngModule.component('pageGroupMembers', react2angular(wrapSettingsTab(null, liveItemsList( GroupMembers, new ResourceItemsSource({ isPlainList: true, @@ -202,7 +203,7 @@ export default function init(ngModule) { }, }), new StateStorage({ orderByField: 'name' }), - ))); + )))); return routesToAngularRoutes([ { @@ -212,7 +213,7 @@ export default function init(ngModule) { }, ], { reloadOnSearch: false, - template: '', + template: '', controller($scope, $exceptionHandler) { 'ngInject'; diff --git a/client/app/pages/groups/GroupsList.jsx b/client/app/pages/groups/GroupsList.jsx index 276414adf..179ef87d0 100644 --- a/client/app/pages/groups/GroupsList.jsx +++ b/client/app/pages/groups/GroupsList.jsx @@ -14,9 +14,9 @@ import ItemsTable, { Columns } from '@/components/items-list/components/ItemsTab import CreateGroupDialog from '@/components/groups/CreateGroupDialog'; import DeleteGroupButton from '@/components/groups/DeleteGroupButton'; +import wrapSettingsTab from '@/components/SettingsWrapper'; import { Group } from '@/services/group'; -import settingsMenu from '@/services/settingsMenu'; import { currentUser } from '@/services/auth'; import navigateTo from '@/services/navigateTo'; import { routesToAngularRoutes } from '@/lib/utils'; @@ -121,14 +121,12 @@ class GroupsList extends React.Component { } export default function init(ngModule) { - settingsMenu.add({ + ngModule.component('pageGroupsList', react2angular(wrapSettingsTab({ permission: 'list_users', title: 'Groups', path: 'groups', order: 3, - }); - - ngModule.component('pageGroupsList', react2angular(liveItemsList( + }, liveItemsList( GroupsList, new ResourceItemsSource({ isPlainList: true, @@ -143,7 +141,7 @@ export default function init(ngModule) { }, }), new StateStorage({ orderByField: 'name', itemsPerPage: 10 }), - ))); + )))); return routesToAngularRoutes([ { @@ -153,7 +151,7 @@ export default function init(ngModule) { }, ], { reloadOnSearch: false, - template: '', + template: '', controller($scope, $exceptionHandler) { 'ngInject'; diff --git a/client/app/pages/query-snippets/QuerySnippetsList.jsx b/client/app/pages/query-snippets/QuerySnippetsList.jsx index 63de53122..71bbc2ec9 100644 --- a/client/app/pages/query-snippets/QuerySnippetsList.jsx +++ b/client/app/pages/query-snippets/QuerySnippetsList.jsx @@ -14,10 +14,10 @@ import { StateStorage } from '@/components/items-list/classes/StateStorage'; import LoadingState from '@/components/items-list/components/LoadingState'; import ItemsTable, { Columns } from '@/components/items-list/components/ItemsTable'; +import wrapSettingsTab from '@/components/SettingsWrapper'; import { QuerySnippet } from '@/services/query-snippet'; import navigateTo from '@/services/navigateTo'; -import settingsMenu from '@/services/settingsMenu'; import { currentUser } from '@/services/auth'; import { policy } from '@/services/policy'; import notification from '@/services/notification'; @@ -183,14 +183,12 @@ class QuerySnippetsList extends React.Component { } export default function init(ngModule) { - settingsMenu.add({ + ngModule.component('pageQuerySnippetsList', react2angular(wrapSettingsTab({ permission: 'create_query', title: 'Query Snippets', path: 'query_snippets', order: 5, - }); - - ngModule.component('pageQuerySnippetsList', react2angular(liveItemsList( + }, liveItemsList( QuerySnippetsList, new ResourceItemsSource({ isPlainList: true, @@ -205,7 +203,7 @@ export default function init(ngModule) { }, }), new StateStorage({ orderByField: 'trigger', itemsPerPage: 10 }), - ))); + )))); return routesToAngularRoutes([ { @@ -221,7 +219,7 @@ export default function init(ngModule) { }, ], { reloadOnSearch: false, - template: '', + template: '', controller($scope, $exceptionHandler) { 'ngInject'; diff --git a/client/app/pages/settings/OrganizationSettings.jsx b/client/app/pages/settings/OrganizationSettings.jsx index cfb970008..1effcc92f 100644 --- a/client/app/pages/settings/OrganizationSettings.jsx +++ b/client/app/pages/settings/OrganizationSettings.jsx @@ -13,10 +13,10 @@ import LoadingState from '@/components/items-list/components/LoadingState'; import { routesToAngularRoutes } from '@/lib/utils'; import { clientConfig } from '@/services/auth'; -import settingsMenu from '@/services/settingsMenu'; import recordEvent from '@/services/recordEvent'; import OrgSettings from '@/services/organizationSettings'; import HelpTrigger from '@/components/HelpTrigger'; +import wrapSettingsTab from '@/components/SettingsWrapper'; import DynamicComponent from '@/components/DynamicComponent'; const Option = Select.Option; @@ -255,14 +255,12 @@ class OrganizationSettings extends React.Component { } export default function init(ngModule) { - settingsMenu.add({ + ngModule.component('pageOrganizationSettings', react2angular(wrapSettingsTab({ permission: 'admin', title: 'Settings', path: 'settings/organization', order: 6, - }); - - ngModule.component('pageOrganizationSettings', react2angular(OrganizationSettings)); + }, OrganizationSettings))); return routesToAngularRoutes([ { @@ -272,7 +270,7 @@ export default function init(ngModule) { }, ], { reloadOnSearch: false, - template: '', + template: '', controller($scope, $exceptionHandler) { 'ngInject'; diff --git a/client/app/pages/users/UserProfile.jsx b/client/app/pages/users/UserProfile.jsx index 7298b899f..323f4c9c8 100644 --- a/client/app/pages/users/UserProfile.jsx +++ b/client/app/pages/users/UserProfile.jsx @@ -6,9 +6,9 @@ import EmailSettingsWarning from '@/components/EmailSettingsWarning'; import UserEdit from '@/components/users/UserEdit'; import UserShow from '@/components/users/UserShow'; import LoadingState from '@/components/items-list/components/LoadingState'; +import wrapSettingsTab from '@/components/SettingsWrapper'; import { User } from '@/services/user'; -import settingsMenu from '@/services/settingsMenu'; import { $route } from '@/services/ng'; import { currentUser } from '@/services/auth'; import PromiseRejectionError from '@/lib/promise-rejection-error'; @@ -57,13 +57,11 @@ class UserProfile extends React.Component { } export default function init(ngModule) { - settingsMenu.add({ + ngModule.component('pageUserProfile', react2angular(wrapSettingsTab({ title: 'Account', path: 'users/me', order: 7, - }); - - ngModule.component('pageUserProfile', react2angular(UserProfile)); + }, UserProfile))); } init.init = true; diff --git a/client/app/pages/users/UsersList.jsx b/client/app/pages/users/UsersList.jsx index 111de07f9..3b969bf49 100644 --- a/client/app/pages/users/UsersList.jsx +++ b/client/app/pages/users/UsersList.jsx @@ -21,8 +21,8 @@ import ItemsTable, { Columns } from '@/components/items-list/components/ItemsTab import Layout from '@/components/layouts/ContentWithSidebar'; import CreateUserDialog from '@/components/users/CreateUserDialog'; +import wrapSettingsTab from '@/components/SettingsWrapper'; -import settingsMenu from '@/services/settingsMenu'; import { currentUser } from '@/services/auth'; import { policy } from '@/services/policy'; import { User } from '@/services/user'; @@ -231,15 +231,13 @@ class UsersList extends React.Component { } export default function init(ngModule) { - settingsMenu.add({ + ngModule.component('pageUsersList', react2angular(wrapSettingsTab({ permission: 'list_users', title: 'Users', path: 'users', isActive: path => path.startsWith('/users') && (path !== '/users/me'), order: 2, - }); - - ngModule.component('pageUsersList', react2angular(itemsList( + }, itemsList( UsersList, new ResourceItemsSource({ getRequest(request, { params: { currentPage } }) { @@ -265,7 +263,7 @@ export default function init(ngModule) { }, }), new UrlStateStorage({ orderByField: 'created_at', orderByReverse: true }), - ))); + )))); } init.init = true; diff --git a/client/app/pages/users/index.js b/client/app/pages/users/index.js index 07d713e77..997a02288 100644 --- a/client/app/pages/users/index.js +++ b/client/app/pages/users/index.js @@ -25,7 +25,7 @@ export default function init() { key: 'disabled', }, ], { - template: '', + template: '', reloadOnSearch: false, controller($scope, $exceptionHandler) { 'ngInject'; @@ -47,7 +47,7 @@ export default function init() { }, ], { reloadOnSearch: false, - template: '', + template: '', controller($scope, $exceptionHandler) { 'ngInject'; diff --git a/client/app/services/settingsMenu.js b/client/app/services/settingsMenu.js index 45ee63015..c706c78af 100644 --- a/client/app/services/settingsMenu.js +++ b/client/app/services/settingsMenu.js @@ -1,4 +1,4 @@ -import { isFunction, extend, omit, sortBy } from 'lodash'; +import { isFunction, extend, omit, sortBy, find } from 'lodash'; class SettingsMenuItem { constructor(menuItem) { @@ -26,6 +26,10 @@ class SettingsMenu { this.items.push(new SettingsMenuItem(item)); this.items = sortBy(this.items, 'order'); } + + getActiveItem(path) { + return find(this.items, item => item.isActive(path)); + } } export default new SettingsMenu();