[ARVADOS-WORKBENCH2] updated: 1.1.4-484-g1bdd1df
Git user
git at public.curoverse.com
Mon Aug 6 14:34:58 EDT 2018
Summary of changes:
src/services/tag-service/tag-service.ts | 7 +-
.../collection-panel/collection-panel-action.ts | 6 +-
src/validators/validators.tsx | 9 ++
src/views/collection-panel/collection-panel.tsx | 22 ++--
src/views/collection-panel/collection-tag-form.tsx | 118 +++++++++++++++++++++
5 files changed, 148 insertions(+), 14 deletions(-)
create mode 100644 src/validators/validators.tsx
create mode 100644 src/views/collection-panel/collection-tag-form.tsx
via 1bdd1dfe632195c85e4dbda768dd342811a468b0 (commit)
from f7cdbfa28c3867076fe25feb5d89b62592a9bf81 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
commit 1bdd1dfe632195c85e4dbda768dd342811a468b0
Author: Janicki Artur <artur.janicki at contractors.roche.com>
Date: Mon Aug 6 20:34:51 2018 +0200
add form for create tag, modify service and action
Feature #13854
Arvados-DCO-1.1-Signed-off-by: Janicki Artur <artur.janicki at contractors.roche.com>
diff --git a/src/services/tag-service/tag-service.ts b/src/services/tag-service/tag-service.ts
index d8caca2..c3019a6 100644
--- a/src/services/tag-service/tag-service.ts
+++ b/src/services/tag-service/tag-service.ts
@@ -6,6 +6,7 @@ import { LinkService } from "../link-service/link-service";
import { LinkClass } from "../../models/link";
import { FilterBuilder } from "../../common/api/filter-builder";
import { TagTailType, TagResource } from "../../models/tag";
+import { OrderBuilder } from "../../common/api/order-builder";
export class TagService {
@@ -30,8 +31,12 @@ export class TagService {
.addEqual("tailUuid", TagTailType.COLLECTION)
.addEqual("linkClass", LinkClass.TAG);
+ const order = OrderBuilder
+ .create<TagResource>()
+ .addAsc('createdAt');
+
return this.linkService
- .list({ filters })
+ .list({ filters, order })
.then(results => {
return results.items.map((tag => tag as TagResource ));
});
diff --git a/src/store/collection-panel/collection-panel-action.ts b/src/store/collection-panel/collection-panel-action.ts
index 01f430c..f389dc4 100644
--- a/src/store/collection-panel/collection-panel-action.ts
+++ b/src/store/collection-panel/collection-panel-action.ts
@@ -22,6 +22,8 @@ export const collectionPanelActions = unionize({
export type CollectionPanelAction = UnionOf<typeof collectionPanelActions>;
+export const COLLECTION_TAG_FORM_NAME = 'collectionTagForm';
+
export const loadCollection = (uuid: string, kind: ResourceKind) =>
(dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
dispatch(collectionPanelActions.LOAD_COLLECTION({ uuid, kind }));
@@ -43,9 +45,11 @@ export const loadCollectionTags = (uuid: string) =>
};
-export const createCollectionTag = (uuid: string, data: TagProperty) =>
+export const createCollectionTag = (data: TagProperty) =>
(dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
dispatch(collectionPanelActions.CREATE_COLLECTION_TAG({ data }));
+ const item = getState().collectionPanel.item;
+ const uuid = item ? item.uuid : '';
return services.tagService
.create(uuid, data)
.then(tag => {
diff --git a/src/validators/validators.tsx b/src/validators/validators.tsx
new file mode 100644
index 0000000..fdeb8fa
--- /dev/null
+++ b/src/validators/validators.tsx
@@ -0,0 +1,9 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { require } from './require';
+import { maxLength } from './max-length';
+
+export const TAG_KEY_VALIDATION = [require, maxLength(255)];
+export const TAG_VALUE_VALIDATION = [require, maxLength(255)];
\ No newline at end of file
diff --git a/src/views/collection-panel/collection-panel.tsx b/src/views/collection-panel/collection-panel.tsx
index 271fb8b..c6554f9 100644
--- a/src/views/collection-panel/collection-panel.tsx
+++ b/src/views/collection-panel/collection-panel.tsx
@@ -15,8 +15,8 @@ import { MoreOptionsIcon, CollectionIcon, CopyIcon } from '../../components/icon
import { DetailsAttribute } from '../../components/details-attribute/details-attribute';
import { CollectionResource } from '../../models/collection';
import * as CopyToClipboard from 'react-copy-to-clipboard';
-import { createCollectionTag } from '../../store/collection-panel/collection-panel-action';
import { TagResource } from '../../models/tag';
+import { CollectionTagForm } from './collection-tag-form';
type CssRules = 'card' | 'iconHeader' | 'tag' | 'copyIcon';
@@ -29,7 +29,8 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
color: theme.customs.colors.yellow700
},
tag: {
- marginRight: theme.spacing.unit
+ marginRight: theme.spacing.unit,
+ marginBottom: theme.spacing.unit
},
copyIcon: {
marginLeft: theme.spacing.unit,
@@ -94,14 +95,12 @@ export const CollectionPanel = withStyles(styles)(
<CardHeader title="Tags" />
<CardContent>
<Grid container direction="column">
- <Grid item xs={12}>
- {/* Temporarty button to add new tag */}
- <Button onClick={this.addTag}>Add Tag</Button>
- </Grid>
+ <Grid item xs={12}><CollectionTagForm /></Grid>
<Grid item xs={12}>
{
tags.map(tag => {
return <Chip key={tag.etag} className={classes.tag}
+ onDelete={handleDelete}
label={renderTagLabel(tag)} />;
})
}
@@ -115,7 +114,7 @@ export const CollectionPanel = withStyles(styles)(
<CardContent>
<Grid container direction="column">
<Grid item xs={4}>
- Tags
+ Files
</Grid>
</Grid>
</CardContent>
@@ -123,11 +122,6 @@ export const CollectionPanel = withStyles(styles)(
</div>;
}
- // Temporary method to add new tag
- addTag = () => {
- this.props.dispatch<any>(createCollectionTag(this.props.item.uuid, { key: 'test', value: 'value for tag'}));
- }
-
componentWillReceiveProps({ match, item, onItemRouteChange }: CollectionPanelProps) {
if (!item || match.params.id !== item.uuid) {
onItemRouteChange(match.params.id);
@@ -141,4 +135,8 @@ export const CollectionPanel = withStyles(styles)(
const renderTagLabel = (tag: TagResource) => {
const { properties } = tag;
return `${properties.key}: ${properties.value}`;
+};
+
+const handleDelete = () => {
+ alert('tag has been deleted');
};
\ No newline at end of file
diff --git a/src/views/collection-panel/collection-tag-form.tsx b/src/views/collection-panel/collection-tag-form.tsx
new file mode 100644
index 0000000..89cf880
--- /dev/null
+++ b/src/views/collection-panel/collection-tag-form.tsx
@@ -0,0 +1,118 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+import { reduxForm, Field, reset } from 'redux-form';
+import { compose, Dispatch } from 'redux';
+import { ArvadosTheme } from '../../common/custom-theme';
+import { StyleRulesCallback, withStyles, WithStyles, TextField, Button, CircularProgress } from '@material-ui/core';
+import { TagProperty } from '../../models/tag';
+import { createCollectionTag, COLLECTION_TAG_FORM_NAME } from '../../store/collection-panel/collection-panel-action';
+import { TAG_VALUE_VALIDATION, TAG_KEY_VALIDATION } from '../../validators/validators';
+
+type CssRules = 'form' | 'textField' | 'buttonWrapper' | 'saveButton' | 'circularProgress';
+
+const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
+ form: {
+ marginBottom: theme.spacing.unit * 4
+ },
+ textField: {
+ marginRight: theme.spacing.unit
+ },
+ buttonWrapper: {
+ position: 'relative',
+ display: 'inline-block'
+ },
+ saveButton: {
+ boxShadow: 'none'
+ },
+ circularProgress: {
+ position: 'absolute',
+ top: 0,
+ bottom: 0,
+ left: 0,
+ right: 0,
+ margin: 'auto'
+ }
+});
+
+interface CollectionTagFormDataProps {
+ submitting: boolean;
+ invalid: boolean;
+ pristine: boolean;
+}
+
+interface CollectionTagFormActionProps {
+ handleSubmit: any;
+}
+
+interface TextFieldProps {
+ label: string;
+ floatinglabeltext: string;
+ className?: string;
+ input?: string;
+ meta?: any;
+}
+
+type CollectionTagFormProps = CollectionTagFormDataProps & CollectionTagFormActionProps & WithStyles<CssRules>;
+
+export const CollectionTagForm = compose(
+ reduxForm({
+ form: COLLECTION_TAG_FORM_NAME,
+ onSubmit: (data: TagProperty, dispatch: Dispatch) => {
+ dispatch<any>(createCollectionTag(data));
+ dispatch(reset(COLLECTION_TAG_FORM_NAME));
+ }
+ }),
+ withStyles(styles))(
+
+ class CollectionTagForm extends React.Component<CollectionTagFormProps> {
+
+ render() {
+ const { classes, submitting, pristine, invalid, handleSubmit } = this.props;
+ return (
+ <form className={classes.form} onSubmit={handleSubmit}>
+ <Field name="key"
+ disabled={submitting}
+ component={this.renderTextField}
+ floatinglabeltext="Key"
+ validate={TAG_KEY_VALIDATION}
+ className={classes.textField}
+ label="Key" />
+ <Field name="value"
+ disabled={submitting}
+ component={this.renderTextField}
+ floatinglabeltext="Value"
+ validate={TAG_VALUE_VALIDATION}
+ className={classes.textField}
+ label="Value" />
+ <div className={classes.buttonWrapper}>
+ <Button type="submit" className={classes.saveButton}
+ color="primary"
+ size='small'
+ disabled={invalid || submitting || pristine}
+ variant="contained">
+ ADD
+ </Button>
+ {submitting && <CircularProgress size={20} className={classes.circularProgress} />}
+ </div>
+ </form>
+ );
+ }
+
+ renderTextField = ({ input, label, meta: { touched, error }, ...custom }: TextFieldProps) => (
+ <TextField
+ helperText={touched && error}
+ label={label}
+ className={this.props.classes.textField}
+ error={touched && !!error}
+ autoComplete='off'
+ {...input}
+ {...custom}
+ />
+ )
+
+ }
+
+ );
\ No newline at end of file
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list