padding: theme.spacing.unit
},
tableCell: {
- wordWrap: 'break-word'
+ wordWrap: 'break-word',
+ paddingRight: '24px'
},
tableCellWorkflows: {
'&:nth-last-child(2)': {
renderHeadCell = (column: DataColumn<T>, index: number) => {
const { name, key, renderHeader, filters, sortDirection } = column;
- const { onSortToggle, onFiltersChange } = this.props;
- return <TableCell key={key || index}>
+ const { onSortToggle, onFiltersChange, classes } = this.props;
+ return <TableCell className={classes.tableCell} key={key || index}>
{renderHeader ?
renderHeader() :
countNodes(filters) > 0
cluster?: string;
projectUuid?: string;
inTrash: boolean;
+ pastVersions: boolean;
dateFrom: string;
dateTo: string;
saveQuery: boolean;
describe('search-bar-actions', () => {
describe('getAdvancedDataFromQuery', () => {
it('should correctly build advanced data record from query #1', () => {
- const r = getAdvancedDataFromQuery('val0 has:"file size":"100mb" val2 has:"user":"daniel" is:starred val2 val0 is:trashed');
+ const r = getAdvancedDataFromQuery('val0 has:"file size":"100mb" val2 has:"user":"daniel" is:starred val2 val0');
expect(r).toEqual({
searchValue: 'val0 val2',
type: undefined,
cluster: undefined,
projectUuid: undefined,
- inTrash: true,
+ inTrash: false,
+ pastVersions: false,
dateFrom: '',
dateTo: '',
properties: [{
});
it('should correctly build advanced data record from query #2', () => {
- const r = getAdvancedDataFromQuery('document from:2017-08-01 pdf has:"filesize":"101mb" is:trashed type:arvados#collection cluster:c97qx');
+ const r = getAdvancedDataFromQuery('document from:2017-08-01 pdf has:"filesize":"101mb" is:trashed type:arvados#collection cluster:c97qx is:pastVersion');
expect(r).toEqual({
searchValue: 'document pdf',
type: ResourceKind.COLLECTION,
cluster: 'c97qx',
projectUuid: undefined,
inTrash: true,
+ pastVersions: true,
dateFrom: '2017-08-01',
dateTo: '',
properties: [{
cluster: 'c97qx',
projectUuid: undefined,
inTrash: true,
+ pastVersions: false,
dateFrom: '2017-08-01',
dateTo: '',
properties: [
expect(q).toBe('document pdf type:arvados#collection cluster:c97qx is:trashed from:2017-08-01 has:"file size":"101mb" has:"Species":"Human" has:"Species":"Canine"');
});
+ it('should build query from advanced data #2', () => {
+ const q = getQueryFromAdvancedData({
+ searchValue: 'document pdf',
+ type: ResourceKind.COLLECTION,
+ cluster: 'c97qx',
+ projectUuid: undefined,
+ inTrash: false,
+ pastVersions: true,
+ dateFrom: '2017-08-01',
+ dateTo: '',
+ properties: [
+ { key: 'file size', value: '101mb' },
+ { key: 'Species', value: 'Human' },
+ { key: 'Species', value: 'Canine' },
+ ],
+ saveQuery: false,
+ queryName: ''
+ });
+ expect(q).toBe('document pdf type:arvados#collection cluster:c97qx is:pastVersion from:2017-08-01 has:"file size":"101mb" has:"Species":"Human" has:"Species":"Canine"');
+ });
+
it('should add has:"key":"value" expression to query from same property key', () => {
const searchValue = 'document pdf has:"file size":"101mb" has:"Species":"Canine"';
const prevData = {
cluster: undefined,
projectUuid: undefined,
inTrash: false,
+ pastVersions: false,
dateFrom: '',
dateTo: '',
properties: [
cluster: undefined,
projectUuid: undefined,
inTrash: false,
+ pastVersions: false,
dateFrom: '',
dateTo: '',
properties: [
cluster: undefined,
projectUuid: undefined,
inTrash: false,
+ pastVersions: false,
dateFrom: '',
dateTo: '',
properties: [
cluster: data.cluster,
projectUuid: data.projectUuid,
inTrash: data.inTrash,
+ pastVersions: data.pastVersions,
dateFrom: data.dateFrom,
dateTo: data.dateTo,
};
['cluster', 'cluster'],
['project', 'projectUuid'],
[`is:${parser.States.TRASHED}`, 'inTrash'],
+ [`is:${parser.States.PAST_VERSION}`, 'pastVersions'],
['from', 'dateFrom'],
['to', 'dateTo']
];
cluster: getValue(Keywords.CLUSTER),
projectUuid: getValue(Keywords.PROJECT),
inTrash: parser.isTrashed(tokens),
+ pastVersions: parser.isPastVersion(tokens),
dateFrom: getValue(Keywords.FROM) || '',
dateTo: getValue(Keywords.TO) || '',
properties: vocabulary
}
export enum States {
- TRASHED = 'trashed'
+ TRASHED = 'trashed',
+ PAST_VERSION = 'pastVersion'
}
const keyValuePattern = (key: string) => new RegExp(`${key}:([^ ]*)`);
}, [] as Property[]);
-export const isTrashed = (tokens: string[]) => {
+export const isTrashed = (tokens: string[]) => isSomeState(States.TRASHED, tokens);
+
+export const isPastVersion = (tokens: string[]) => isSomeState(States.PAST_VERSION, tokens);
+
+const isSomeState = (state: string, tokens: string[]) => {
for (const token of tokens) {
const match = token.match(keyValuePattern(Keywords.IS)) || ['', ''];
if (match) {
const [, value] = match;
- if(value === States.TRASHED) {
+ if(value === state) {
return true;
}
}
typeFilters(dataExplorer.columns)
),
order: getOrder(dataExplorer),
- includeTrash: getAdvancedDataFromQuery(query).inTrash
+ includeTrash: getAdvancedDataFromQuery(query).inTrash,
+ includeOldVersions: getAdvancedDataFromQuery(query).pastVersions
});
const getOrder = (dataExplorer: DataExplorer) => {
import { ArvadosTheme } from '~/common/custom-theme';
import { compose, Dispatch } from 'redux';
import { WorkflowResource } from '~/models/workflow';
-import { ResourceStatus } from '~/views/workflow-panel/workflow-panel-view';
+import { ResourceStatus as WorkflowStatus } from '~/views/workflow-panel/workflow-panel-view';
import { getUuidPrefix, openRunProcess } from '~/store/workflow-panel/workflow-panel-actions';
import { openSharingDialog } from '~/store/sharing-dialog/sharing-dialog-actions';
import { UserResource } from '~/models/user';
const renderWorkflowStatus = (uuidPrefix: string, ownerUuid?: string) => {
if (ownerUuid === getPublicUuid(uuidPrefix)) {
- return renderStatus(ResourceStatus.PUBLIC);
+ return renderStatus(WorkflowStatus.PUBLIC);
} else {
- return renderStatus(ResourceStatus.PRIVATE);
+ return renderStatus(WorkflowStatus.PRIVATE);
}
};
return { type: resource ? resource.kind : '' };
})((props: { type: string }) => renderType(props.type));
+export const ResourceStatus = connect((state: RootState, props: { uuid: string }) => {
+ return { resource: getResource<GroupContentsResource>(props.uuid)(state.resources) };
+ })((props: { resource: GroupContentsResource }) =>
+ (props.resource && props.resource.kind === ResourceKind.COLLECTION)
+ ? <CollectionStatus uuid={props.resource.uuid} />
+ : <ProcessStatus uuid={props.resource.uuid} />
+ );
+
+export const CollectionStatus = connect((state: RootState, props: { uuid: string }) => {
+ return { collection: getResource<CollectionResource>(props.uuid)(state.resources) };
+ })((props: { collection: CollectionResource }) =>
+ (props.collection.uuid !== props.collection.currentVersionUuid)
+ ? <Typography>old version</Typography>
+ : <Typography>current</Typography>
+ );
+
export const ProcessStatus = compose(
connect((state: RootState, props: { uuid: string }) => {
return { process: getProcess(props.uuid)(state.resources) };
component={CheckboxField}
label="In trash" />;
+export const SearchBarPastVersionsField = () =>
+ <Field
+ name='pastVersions'
+ component={CheckboxField}
+ label="Past versions" />;
+
export const SearchBarDateFromField = () =>
<Field
name='dateFrom'
import {
SearchBarTypeField, SearchBarClusterField, SearchBarProjectField, SearchBarTrashField,
SearchBarDateFromField, SearchBarDateToField, SearchBarPropertiesField,
- SearchBarSaveSearchField, SearchBarQuerySearchField
+ SearchBarSaveSearchField, SearchBarQuerySearchField, SearchBarPastVersionsField
} from '~/views-components/form-fields/search-bar-form-fields';
import { treePickerActions } from "~/store/tree-picker/tree-picker-actions";
<Grid item xs={5}>
<SearchBarTrashField />
</Grid>
+ <Grid item xs={5}>
+ <SearchBarPastVersionsField />
+ </Grid>
</Grid>
<IconButton onClick={closeAdvanceView} className={classes.closeIcon}>
<CloseIcon />
import { SEARCH_RESULTS_PANEL_ID } from '~/store/search-results-panel/search-results-panel-actions';
import { DataExplorer } from '~/views-components/data-explorer/data-explorer';
import {
- ProcessStatus, ResourceCluster,
+ ResourceCluster,
ResourceFileSize,
ResourceLastModifiedDate,
ResourceName,
ResourceOwner,
+ ResourceStatus,
ResourceType
} from '~/views-components/data-explorer/renderers';
import { createTree } from '~/models/tree';
export enum SearchResultsPanelColumnNames {
CLUSTER = "Cluster",
NAME = "Name",
- PROJECT = "Project",
STATUS = "Status",
TYPE = 'Type',
OWNER = "Owner",
filters: createTree(),
render: (uuid: string) => <ResourceName uuid={uuid} />
},
- {
- name: SearchResultsPanelColumnNames.PROJECT,
- selected: true,
- configurable: true,
- filters: createTree(),
- render: uuid => <ResourceFileSize uuid={uuid} />
- },
{
name: SearchResultsPanelColumnNames.STATUS,
selected: true,
configurable: true,
filters: createTree(),
- render: uuid => <ProcessStatus uuid={uuid} />
+ render: uuid => <ResourceStatus uuid={uuid} />
},
{
name: SearchResultsPanelColumnNames.TYPE,