Skip to content

Commit

Permalink
feat: favourite ui feature (argoproj#8210)
Browse files Browse the repository at this point in the history
* feat: favourite ui feature (argoproj#8210)

Signed-off-by: saumeya <[email protected]>
  • Loading branch information
saumeya authored Jan 28, 2022
1 parent d2a3a4d commit 85c114d
Show file tree
Hide file tree
Showing 6 changed files with 271 additions and 189 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {Checkbox} from 'argo-ui';
import {useData} from 'argo-ui/v2';
import * as minimatch from 'minimatch';
import * as React from 'react';
import {Context} from '../../../shared/context';
import {Application, ApplicationDestination, Cluster, HealthStatusCode, HealthStatuses, SyncStatusCode, SyncStatuses} from '../../../shared/models';
import {AppsListPreferences, services} from '../../../shared/services';
import {Filter, FiltersGroup} from '../filter/filter';
Expand All @@ -13,6 +15,7 @@ export interface FilterResult {
health: boolean;
namespaces: boolean;
clusters: boolean;
favourite: boolean;
labels: boolean;
}

Expand All @@ -28,6 +31,7 @@ export function getFilterResults(applications: Application[], pref: AppsListPref
sync: pref.syncFilter.length === 0 || pref.syncFilter.includes(app.status.sync.status),
health: pref.healthFilter.length === 0 || pref.healthFilter.includes(app.status.health.status),
namespaces: pref.namespacesFilter.length === 0 || pref.namespacesFilter.some(ns => app.spec.destination.namespace && minimatch(app.spec.destination.namespace, ns)),
favourite: !pref.showFavorites || pref.favoritesAppList.includes(app.metadata.name),
clusters:
pref.clustersFilter.length === 0 ||
pref.clustersFilter.some(filterString => {
Expand Down Expand Up @@ -211,13 +215,31 @@ const NamespaceFilter = (props: AppFilterProps) => {
);
};

const FavoriteFilter = (props: AppFilterProps) => {
const ctx = React.useContext(Context);
return (
<div className='filter'>
<Checkbox
checked={!!props.pref.showFavorites}
id='favouriteFilter'
onChange={val => {
ctx.navigation.goto('.', {showFavorites: val}, {replace: true});
services.viewPreferences.updatePreferences({appList: {...props.pref, showFavorites: val}});
}}
/>{' '}
<label htmlFor='favouriteFilter'>FAVORITES ONLY</label>
</div>
);
};

export const ApplicationsFilter = (props: AppFilterProps) => {
const setShown = (val: boolean) => {
services.viewPreferences.updatePreferences({appList: {...props.pref, hideFilters: !val}});
};

return (
<FiltersGroup setShown={setShown} expanded={!props.pref.hideFilters} content={props.children}>
<FavoriteFilter {...props} />
<SyncFilter {...props} />
<HealthFilter {...props} />
<LabelsFilter {...props} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@
&__external-links-icon-container {
position: relative;
display: inline-block;
width: 28px;
}

.filters-group__panel {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ const ViewPref = ({children}: {children: (pref: AppsListPreferences & {page: num
.split(',')
.filter(item => !!item);
}
if (params.get('showFavorites') != null) {
viewPref.showFavorites = params.get('showFavorites') === 'true';
}
if (params.get('view') != null) {
viewPref.view = params.get('view') as AppsListViewType;
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {DropDownMenu} from 'argo-ui';
import {DataLoader, DropDownMenu, Tooltip} from 'argo-ui';
import * as React from 'react';
import {Key, KeybindingContext, useNav} from 'argo-ui/v2';
import {Cluster} from '../../../shared/components';
Expand All @@ -9,6 +9,7 @@ import * as AppUtils from '../utils';
import {OperationState} from '../utils';
import {ApplicationsLabels} from './applications-labels';
import {ApplicationsSource} from './applications-source';
import {services} from '../../../shared/services';
require('./applications-table.scss');

export const ApplicationsTable = (props: {
Expand All @@ -34,66 +35,98 @@ export const ApplicationsTable = (props: {
return (
<Consumer>
{ctx => (
<div className='applications-table argo-table-list argo-table-list--clickable'>
{props.applications.map((app, i) => (
<div
key={app.metadata.name}
className={`argo-table-list__row
<DataLoader load={() => services.viewPreferences.getPreferences()}>
{pref => {
const favList = pref.appList.favoritesAppList || [];
return (
<div className='applications-table argo-table-list argo-table-list--clickable'>
{props.applications.map((app, i) => (
<div
key={app.metadata.name}
className={`argo-table-list__row
applications-list__entry applications-list__entry--health-${app.status.health.status} ${selectedApp === i ? 'applications-tiles__selected' : ''}`}>
<div className={`row applications-list__table-row`} onClick={e => ctx.navigation.goto(`/applications/${app.metadata.name}`, {}, {event: e})}>
<div className='columns small-4'>
<div className='row'>
<div className='show-for-xxlarge columns small-3'>Project:</div>
<div className='columns small-12 xxlarge-9'>{app.spec.project}</div>
</div>
<div className='row'>
<div className='show-for-xxlarge columns small-3'>Name:</div>
<div className='columns small-12 xxlarge-9'>
{app.metadata.name} <ApplicationURLs urls={AppUtils.getExternalUrls(app.metadata.annotations, app.status.summary.externalURLs)} />
</div>
</div>
</div>
<div className='columns small-6'>
<div className='row'>
<div className='show-for-xxlarge columns small-2'>Source:</div>
<div className='columns small-12 xxlarge-10 applications-table-source' style={{position: 'relative'}}>
<div className='applications-table-source__link'>
<ApplicationsSource source={app.spec.source} />
<div
className={`row applications-list__table-row`}
onClick={e => ctx.navigation.goto(`/applications/${app.metadata.name}`, {}, {event: e})}>
<div className='columns small-4'>
<div className='row'>
<div className=' columns small-2'>
<div>
<Tooltip content={favList?.includes(app.metadata.name) ? 'Remove Favorite' : 'Add Favorite'}>
<button
onClick={e => {
e.stopPropagation();
favList?.includes(app.metadata.name)
? favList.splice(favList.indexOf(app.metadata.name), 1)
: favList.push(app.metadata.name);
services.viewPreferences.updatePreferences({appList: {...pref.appList, favoritesAppList: favList}});
}}>
<i
className={'fas fa-star'}
style={{
cursor: 'pointer',
marginRight: '7px',
color: favList?.includes(app.metadata.name) ? '#1FBDD0' : 'grey'
}}
/>
</button>
</Tooltip>
<ApplicationURLs urls={AppUtils.getExternalUrls(app.metadata.annotations, app.status.summary.externalURLs)} />
</div>
</div>
<div className='show-for-xxlarge columns small-4'>Project:</div>
<div className='columns small-12 xxlarge-6'>{app.spec.project}</div>
</div>
<div className='row'>
<div className=' columns small-2' />
<div className='show-for-xxlarge columns small-4'>Name:</div>
<div className='columns small-12 xxlarge-6'>{app.metadata.name}</div>
</div>
</div>
<div className='applications-table-source__labels'>
<ApplicationsLabels app={app} />

<div className='columns small-6'>
<div className='row'>
<div className='show-for-xxlarge columns small-2'>Source:</div>
<div className='columns small-12 xxlarge-10 applications-table-source' style={{position: 'relative'}}>
<div className='applications-table-source__link'>
<ApplicationsSource source={app.spec.source} />
</div>
<div className='applications-table-source__labels'>
<ApplicationsLabels app={app} />
</div>
</div>
</div>
<div className='row'>
<div className='show-for-xxlarge columns small-2'>Destination:</div>
<div className='columns small-12 xxlarge-10'>
<Cluster server={app.spec.destination.server} name={app.spec.destination.name} />/{app.spec.destination.namespace}
</div>
</div>
</div>
<div className='columns small-2'>
<AppUtils.HealthStatusIcon state={app.status.health} /> <span>{app.status.health.status}</span> <br />
<AppUtils.ComparisonStatusIcon status={app.status.sync.status} />
<span>{app.status.sync.status}</span> <OperationState app={app} quiet={true} />
<DropDownMenu
anchor={() => (
<button className='argo-button argo-button--light argo-button--lg argo-button--short'>
<i className='fa fa-ellipsis-v' />
</button>
)}
items={[
{title: 'Sync', action: () => props.syncApplication(app.metadata.name)},
{title: 'Refresh', action: () => props.refreshApplication(app.metadata.name)},
{title: 'Delete', action: () => props.deleteApplication(app.metadata.name)}
]}
/>
</div>
</div>
</div>
<div className='row'>
<div className='show-for-xxlarge columns small-2'>Destination:</div>
<div className='columns small-12 xxlarge-10'>
<Cluster server={app.spec.destination.server} name={app.spec.destination.name} />/{app.spec.destination.namespace}
</div>
</div>
</div>
<div className='columns small-2'>
<AppUtils.HealthStatusIcon state={app.status.health} /> <span>{app.status.health.status}</span>
<br />
<AppUtils.ComparisonStatusIcon status={app.status.sync.status} />
<span>{app.status.sync.status}</span> <OperationState app={app} quiet={true} />
<DropDownMenu
anchor={() => (
<button className='argo-button argo-button--light argo-button--lg argo-button--short'>
<i className='fa fa-ellipsis-v' />
</button>
)}
items={[
{title: 'Sync', action: () => props.syncApplication(app.metadata.name)},
{title: 'Refresh', action: () => props.refreshApplication(app.metadata.name)},
{title: 'Delete', action: () => props.deleteApplication(app.metadata.name)}
]}
/>
</div>
))}
</div>
</div>
))}
</div>
);
}}
</DataLoader>
)}
</Consumer>
);
Expand Down
Loading

0 comments on commit 85c114d

Please sign in to comment.