Migrate Settings Screen to React (#4323)

* Migrate settings-screen to React

* Use black instead of blue color for active item

* Revert "Use black instead of blue color for active item"

This reverts commit 0e4ececa6aba68f6484fefaae8ab85153d177bf8.

* Add selectable=false to the Menu
This commit is contained in:
Gabriel Dutra 2019-11-10 04:07:40 -03:00 committed by Arik Fraimovich
parent 6716bb390c
commit 80878abf7b
18 changed files with 91 additions and 96 deletions

View File

@ -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;
}

View File

@ -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 (
<div className="settings-screen">
<div className="container">
<PageHeader title="Settings" />
<div className="bg-white tiled">
<Menu selectedKeys={[activeItem && activeItem.title]} selectable={false} mode="horizontal">
{settingsMenu.items.map(item => (
<Menu.Item key={item.title}><a href={item.path}>{item.title}</a></Menu.Item>
))}
</Menu>
<div className="p-15">
<div>
<WrappedComponent {...props} />
</div>
</div>
</div>
</div>
</div>
);
};
}
export default wrapSettingsTab;

View File

@ -2,6 +2,7 @@
@import '../../assets/less/inc/variables';
.visual-card-list {
width: 100%;
margin: -5px 0 0 -5px; // compensate for .visual-card spacing
}

View File

@ -1,21 +0,0 @@
<div class="container">
<page-header title="'Settings'"></page-header>
<div class="bg-white tiled">
<ul class="tab-nav">
<li
ng-repeat="menuItem in $ctrl.settingsMenu.items"
ng-if="$ctrl.isAvailable(menuItem.permission)"
ng-class="{'active': $ctrl.isActive(menuItem)}"
>
<a href="{{menuItem.path}}">{{menuItem.title}}</a>
</li>
</ul>
<div class="p-15">
<div ng-transclude>
</div>
</div>
</div>
</div>

View File

@ -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;

View File

@ -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: '<settings-screen><page-data-sources-list></page-data-sources-list></settings-screen>',
template: '<page-data-sources-list></page-data-sources-list>',
controller($scope, $exceptionHandler) {
'ngInject';

View File

@ -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: '<settings-screen><page-edit-data-source on-error="handleError"></page-edit-data-source></settings-screen>',
template: '<page-edit-data-source on-error="handleError"></page-edit-data-source>',
title: 'Data Sources',
controller($scope, $exceptionHandler) {
'ngInject';

View File

@ -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: '<settings-screen><page-destinations-list></page-destinations-list></settings-screen>',
template: '<page-destinations-list></page-destinations-list>',
controller($scope, $exceptionHandler) {
'ngInject';

View File

@ -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: '<settings-screen><page-edit-destination on-error="handleError"></page-edit-destination></settings-screen>',
template: '<page-edit-destination on-error="handleError"></page-edit-destination>',
title: 'Alert Destinations',
controller($scope, $exceptionHandler) {
'ngInject';

View File

@ -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: '<settings-screen><page-group-data-sources on-error="handleError"></page-group-data-sources></settings-screen>',
template: '<page-group-data-sources on-error="handleError"></page-group-data-sources>',
controller($scope, $exceptionHandler) {
'ngInject';

View File

@ -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: '<settings-screen><page-group-members on-error="handleError"></page-group-members></settings-screen>',
template: '<page-group-members on-error="handleError"></page-group-members>',
controller($scope, $exceptionHandler) {
'ngInject';

View File

@ -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: '<settings-screen><page-groups-list on-error="handleError"></page-groups-list></settings-screen>',
template: '<page-groups-list on-error="handleError"></page-groups-list>',
controller($scope, $exceptionHandler) {
'ngInject';

View File

@ -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: '<settings-screen><page-query-snippets-list on-error="handleError"></page-query-snippets-list></settings-screen>',
template: '<page-query-snippets-list on-error="handleError"></page-query-snippets-list>',
controller($scope, $exceptionHandler) {
'ngInject';

View File

@ -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: '<settings-screen><page-organization-settings on-error="handleError"></page-organization-settings></settings-screen>',
template: '<page-organization-settings on-error="handleError"></page-organization-settings>',
controller($scope, $exceptionHandler) {
'ngInject';

View File

@ -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;

View File

@ -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;

View File

@ -25,7 +25,7 @@ export default function init() {
key: 'disabled',
},
], {
template: '<settings-screen><page-users-list on-error="handleError"></page-users-list></settings-screen>',
template: '<page-users-list on-error="handleError"></page-users-list>',
reloadOnSearch: false,
controller($scope, $exceptionHandler) {
'ngInject';
@ -47,7 +47,7 @@ export default function init() {
},
], {
reloadOnSearch: false,
template: '<settings-screen><page-user-profile on-error="handleError"></page-user-profile></settings-screen>',
template: '<page-user-profile on-error="handleError"></page-user-profile>',
controller($scope, $exceptionHandler) {
'ngInject';

View File

@ -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();