Skip to content

Commit

Permalink
fix(ui): Toolbar wrap hides search. Refactor Page (argoproj#5593)
Browse files Browse the repository at this point in the history
Signed-off-by: Remington Breeze <remington@breeze.software>
  • Loading branch information
rbreeze authored Mar 1, 2021
1 parent c6d3728 commit 8c97ade
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
&__title {
font-weight: bolder;
font-size: 15px;
color: $argo-color-gray-6;
color: $argo-color-gray-7;
padding-top: 0.25em;
padding-bottom: 0.5em;
margin-left: 1em;
Expand Down Expand Up @@ -143,7 +143,7 @@
white-space: nowrap;
i {
cursor: pointer;
color: $argo-color-gray-4;
color: $argo-color-gray-4;
margin-right: 1em;
&::before {
font-size: 1.5em;
Expand Down Expand Up @@ -193,7 +193,7 @@
cursor: pointer;
&:hover {
color: $argo-color-gray-6;
}
}
}
i.fa-times {
cursor: pointer;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {Autocomplete, ErrorNotification, MockupList, NotificationType, SlidingPanel} from 'argo-ui';
import {Autocomplete, ErrorNotification, MockupList, NotificationType, SlidingPanel, Toolbar} from 'argo-ui';
import * as classNames from 'classnames';
import * as minimatch from 'minimatch';
import * as React from 'react';
import {RouteComponentProps} from 'react-router';
import {Observable} from 'rxjs';

import {ClusterCtx, DataLoader, EmptyState, ObservableQuery, Page, Paginate, Query, Spinner} from '../../../shared/components';
import {Consumer, ContextApis} from '../../../shared/context';
import {AddAuthToToolbar, ClusterCtx, DataLoader, EmptyState, ObservableQuery, Page, Paginate, Query, Spinner} from '../../../shared/components';
import {Consumer, Context, ContextApis} from '../../../shared/context';
import * as models from '../../../shared/models';
import {AppsListPreferences, AppsListViewType, services} from '../../../shared/services';
import {ApplicationCreatePanel} from '../application-create-panel/application-create-panel';
Expand Down Expand Up @@ -156,6 +156,40 @@ function tryJsonParse(input: string) {
}
}

const FlexTopBar = (props: {toolbar: Toolbar | Observable<Toolbar>}) => {
const ctx = React.useContext(Context);
const loadToolbar = AddAuthToToolbar(props.toolbar, ctx);
return (
<div className='top-bar row' key='tool-bar' style={{padding: '0 15px', alignItems: 'center'}}>
<DataLoader load={() => loadToolbar}>
{toolbar => (
<React.Fragment>
<div>
{toolbar.actionMenu && (
<div>
{toolbar.actionMenu.items.map((item, i) => (
<button
disabled={!!item.disabled}
qe-id={item.qeId}
className='argo-button argo-button--base'
onClick={() => item.action()}
style={{marginRight: 2}}
key={i}>
{item.iconClassName && <i className={item.iconClassName} style={{marginLeft: '-5px', marginRight: '5px'}} />}
{item.title}
</button>
))}
</div>
)}
</div>
<div style={{marginLeft: 'auto'}}>{toolbar.tools}</div>
</React.Fragment>
)}
</DataLoader>
</div>
);
};

export const ApplicationsList = (props: RouteComponentProps<{}>) => {
const query = new URLSearchParams(props.location.search);
const appInput = tryJsonParse(query.get('new'));
Expand Down Expand Up @@ -209,56 +243,56 @@ export const ApplicationsList = (props: RouteComponentProps<{}>) => {
<ClusterCtx.Provider value={clusters}>
<Consumer>
{ctx => (
<Page
title='Applications'
toolbar={services.viewPreferences.getPreferences().map(pref => ({
breadcrumbs: [{title: 'Applications', path: '/applications'}],
tools: (
<React.Fragment key='app-list-tools'>
<span className='applications-list__view-type'>
<i
className={classNames('fa fa-th', {selected: pref.appList.view === 'tiles'})}
title='Tiles'
onClick={() => {
ctx.navigation.goto('.', {view: 'tiles'});
services.viewPreferences.updatePreferences({appList: {...pref.appList, view: 'tiles'}});
}}
/>
<i
className={classNames('fa fa-th-list', {selected: pref.appList.view === 'list'})}
title='List'
onClick={() => {
ctx.navigation.goto('.', {view: 'list'});
services.viewPreferences.updatePreferences({appList: {...pref.appList, view: 'list'}});
}}
/>
<i
className={classNames('fa fa-chart-pie', {selected: pref.appList.view === 'summary'})}
title='Summary'
onClick={() => {
ctx.navigation.goto('.', {view: 'summary'});
services.viewPreferences.updatePreferences({appList: {...pref.appList, view: 'summary'}});
}}
/>
</span>
</React.Fragment>
),
actionMenu: {
items: [
{
title: 'New App',
iconClassName: 'fa fa-plus',
qeId: 'applications-list-button-new-app',
action: () => ctx.navigation.goto('.', {new: '{}'})
},
{
title: 'Sync Apps',
iconClassName: 'fa fa-sync',
action: () => ctx.navigation.goto('.', {syncApps: true})
}
]
}
}))}>
<Page title='Applications' toolbar={{breadcrumbs: [{title: 'Applications', path: '/applications'}]}} hideAuth={true}>
<FlexTopBar
toolbar={services.viewPreferences.getPreferences().map(pref => ({
tools: (
<React.Fragment key='app-list-tools'>
<span className='applications-list__view-type'>
<i
className={classNames('fa fa-th', {selected: pref.appList.view === 'tiles'})}
title='Tiles'
onClick={() => {
ctx.navigation.goto('.', {view: 'tiles'});
services.viewPreferences.updatePreferences({appList: {...pref.appList, view: 'tiles'}});
}}
/>
<i
className={classNames('fa fa-th-list', {selected: pref.appList.view === 'list'})}
title='List'
onClick={() => {
ctx.navigation.goto('.', {view: 'list'});
services.viewPreferences.updatePreferences({appList: {...pref.appList, view: 'list'}});
}}
/>
<i
className={classNames('fa fa-chart-pie', {selected: pref.appList.view === 'summary'})}
title='Summary'
onClick={() => {
ctx.navigation.goto('.', {view: 'summary'});
services.viewPreferences.updatePreferences({appList: {...pref.appList, view: 'summary'}});
}}
/>
</span>
</React.Fragment>
),
actionMenu: {
items: [
{
title: 'New App',
iconClassName: 'fa fa-plus',
qeId: 'applications-list-button-new-app',
action: () => ctx.navigation.goto('.', {new: '{}'})
},
{
title: 'Sync Apps',
iconClassName: 'fa fa-sync',
action: () => ctx.navigation.goto('.', {syncApps: true})
}
]
}
}))}
/>
<div className='applications-list'>
<ViewPref>
{pref => (
Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/shared/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export {DataLoader, ErrorNotification} from 'argo-ui';

export * from './array-input/array-input';
export * from './expandable/expandable';
export * from './page';
export * from './page/page';
export * from './checkbox/checkbox-field';
export * from './colors';
export * from './cluster';
Expand Down
63 changes: 0 additions & 63 deletions ui/src/app/shared/components/page.tsx

This file was deleted.

11 changes: 11 additions & 0 deletions ui/src/app/shared/components/page/page.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.page-wrapper {
.page {
$single-toolbar-height: 50px;
&--has-toolbar {
padding-top: $single-toolbar-height;
}
&__top-bar {
height: $single-toolbar-height;
}
}
}
51 changes: 51 additions & 0 deletions ui/src/app/shared/components/page/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import {DataLoader, Page as ArgoPage, Toolbar, Utils} from 'argo-ui';
import * as React from 'react';
import {BehaviorSubject, Observable} from 'rxjs';
import {Context, ContextApis} from '../../context';
import {services} from '../../services';
const mostRecentLoggedIn = new BehaviorSubject<boolean>(false);

import './page.scss';

function isLoggedIn(): Observable<boolean> {
services.users.get().then(info => mostRecentLoggedIn.next(info.loggedIn));
return mostRecentLoggedIn;
}

export const AddAuthToToolbar = (init: Toolbar | Observable<Toolbar>, ctx: ContextApis): Observable<Toolbar> => {
return Utils.toObservable(init).map(toolbar => {
toolbar = toolbar || {};
toolbar.tools = [
toolbar.tools,
<DataLoader key='loginPanel' load={() => isLoggedIn()}>
{loggedIn =>
loggedIn ? (
<a key='logout' onClick={() => ctx.navigation.goto('/auth/logout')}>
Log out
</a>
) : (
<a key='login' onClick={() => ctx.navigation.goto('/login')}>
Log in
</a>
)
}
</DataLoader>
];
return toolbar;
});
};

interface PageProps extends React.Props<any> {
title: string;
hideAuth?: boolean;
toolbar?: Toolbar | Observable<Toolbar>;
}

export const Page = (props: PageProps) => {
const ctx = React.useContext(Context);
return (
<div className={`${props.hideAuth ? 'page-wrapper' : ''}`}>
<ArgoPage title={props.title} children={props.children} toolbar={!props.hideAuth ? AddAuthToToolbar(props.toolbar, ctx) : props.toolbar} />
</div>
);
};

0 comments on commit 8c97ade

Please sign in to comment.