diff --git a/frontend/src/js/component/wb-collection-listing.js b/frontend/src/js/component/wb-collection-listing.js
index 9523399..9e84eaf 100644
--- a/frontend/src/js/component/wb-collection-listing.js
+++ b/frontend/src/js/component/wb-collection-listing.js
@@ -21,12 +21,14 @@ class WBCollectionListing extends Component {
}
prepareRows(items, ownerLookup) {
- let { app } = this.props;
-
+ let { app, renderRenameLink } = this.props;
+
return items.map(item => [
(
),
diff --git a/frontend/src/js/component/wb-process-listing.js b/frontend/src/js/component/wb-process-listing.js
index 2d1021c..2c2bb27 100644
--- a/frontend/src/js/component/wb-process-listing.js
+++ b/frontend/src/js/component/wb-process-listing.js
@@ -22,11 +22,14 @@ class WBProcessListing extends Component {
}
prepareRows(items) {
+ const { renderRenameLink } = this.props;
return items.map(item => [
(),
diff --git a/frontend/src/js/component/wb-project-listing.js b/frontend/src/js/component/wb-project-listing.js
index 9d37885..8a40e53 100644
--- a/frontend/src/js/component/wb-project-listing.js
+++ b/frontend/src/js/component/wb-project-listing.js
@@ -17,13 +17,15 @@ class WBProjectListing extends Component {
}
prepareRows(items) {
- let { app } = this.props;
-
+ let { app, renderRenameLink } = this.props;
+
return items.map(item => [
(),
@@ -78,7 +80,8 @@ class WBProjectListing extends Component {
WBProjectListing.defaultProps = {
'itemsPerPage': 100,
- 'ownerUuid': null
+ 'ownerUuid': null,
+ 'renderRenameLink': () => null
};
export default WBProjectListing;
diff --git a/frontend/src/js/component/wb-workflow-listing.js b/frontend/src/js/component/wb-workflow-listing.js
index f7bb05b..95cd285 100644
--- a/frontend/src/js/component/wb-workflow-listing.js
+++ b/frontend/src/js/component/wb-workflow-listing.js
@@ -6,6 +6,7 @@ import WBNameAndUuid from 'wb-name-and-uuid';
import wbFetchObjects from 'wb-fetch-objects';
import wbFormatDate from 'wb-format-date';
import urlForObject from 'url-for-object';
+import arvadosObjectName from 'arvados-object-name';
class WBWorkflowListing extends Component {
@@ -20,8 +21,18 @@ class WBWorkflowListing extends Component {
}
prepareRows(items, ownerLookup) {
+ const { renderRenameLink } = this.props;
return items.map(item => [
- ( ),
+ (
+
+ ),
item.description,
( ),
wbFormatDate(item.created_at),
diff --git a/frontend/src/js/dialog/wb-rename-dialog.js b/frontend/src/js/dialog/wb-rename-dialog.js
new file mode 100644
index 0000000..af31897
--- /dev/null
+++ b/frontend/src/js/dialog/wb-rename-dialog.js
@@ -0,0 +1,45 @@
+import { h, Component, createRef } from 'preact';
+import WBDialog from 'wb-dialog';
+import linkState from 'linkstate';
+import wbRenameObject from 'wb-rename-object';
+
+class WBRenameDialog extends Component {
+ constructor(...args) {
+ super(...args);
+ this.dialogRef = createRef();
+ this.state.inputId = uuid.v4();
+ }
+
+ show(item, callback) {
+ const { inputId } = this.state;
+ this.setState({
+ 'item': item,
+ 'newName': null,
+ 'callback': callback || (() => {})
+ });
+ this.dialogRef.current.show();
+ $('#' + inputId).focus();
+ }
+
+ hide() {
+ this.dialogRef.current.hide();
+ }
+
+ render({ app }, { item, newName, callback, inputId }) {
+ const { arvHost, arvToken } = app.state;
+ return (
+ {
+ if (newName)
+ wbRenameObject(arvHost, arvToken, item.uuid, newName).then(callback);
+ } }>
+
+
+
+
+ );
+ }
+}
+
+export default WBRenameDialog;
diff --git a/frontend/src/js/misc/wb-rename-object.js b/frontend/src/js/misc/wb-rename-object.js
new file mode 100644
index 0000000..bbd5a8a
--- /dev/null
+++ b/frontend/src/js/misc/wb-rename-object.js
@@ -0,0 +1,16 @@
+import makeArvadosRequest from 'make-arvados-request';
+import arvadosTypeName from 'arvados-type-name';
+
+function wbRenameObject(arvHost, arvToken, uuid, newName) {
+ const update = {
+ 'name': newName
+ };
+ const typeName = arvadosTypeName(uuid);
+ return makeArvadosRequest(arvHost, arvToken,
+ '/arvados/v1/' + typeName + 's/' +
+ uuid + '?' + typeName + '=' +
+ encodeURIComponent(JSON.stringify(update)),
+ { 'method': 'PUT' });
+}
+
+export default wbRenameObject;
diff --git a/frontend/src/js/page/wb-browse.js b/frontend/src/js/page/wb-browse.js
index c61bc83..7b170b1 100644
--- a/frontend/src/js/page/wb-browse.js
+++ b/frontend/src/js/page/wb-browse.js
@@ -1,4 +1,4 @@
-import { h, Component } from 'preact';
+import { h, Component, createRef } from 'preact';
import { route } from 'preact-router';
import WBNavbarCommon from 'wb-navbar-common';
import WBProjectListing from 'wb-project-listing';
@@ -8,8 +8,14 @@ import WBTabs from 'wb-tabs';
import WBProcessListing from 'wb-process-listing';
import WBCollectionListing from 'wb-collection-listing';
import WBWorkflowListing from 'wb-workflow-listing';
+import WBRenameDialog from 'wb-rename-dialog';
class WBBrowse extends Component {
+ constructor(...args) {
+ super(...args);
+ this.renameDialogRef = createRef();
+ }
+
getUrl(params) {
let res = '/browse/' +
('ownerUuid' in params ? params.ownerUuid : (this.props.ownerUuid || '')) + '/' +
@@ -26,11 +32,26 @@ class WBBrowse extends Component {
route(this.getUrl(params));
}
+ renameDialog(item, callback) {
+ // throw Error('Not implemented');
+ this.renameDialogRef.current.show(item, callback);
+ }
+
+ renderRenameLink(item, callback) {
+ return (
+ { e.preventDefault(); this.renameDialog(item, callback); } }>
+
+
+ );
+ }
+
render({ ownerUuid, activePage, appState, app,
objTypeTab, collectionPage, processPage, workflowPage }) {
return (
+
+
@@ -44,7 +65,8 @@ class WBBrowse extends Component {
ownerUuid={ ownerUuid }
itemsPerPage="5"
activePage={ Number(activePage || 0) }
- onPageChanged={ i => route('/browse/' + (ownerUuid || '') + '/' + i)} />
+ onPageChanged={ i => route('/browse/' + (ownerUuid || '') + '/' + i) }
+ renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } />
this.getUrl({ 'collectionPage': i }) } />
+ getPageUrl={ i => this.getUrl({ 'collectionPage': i }) }
+ renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } />
) : (objTypeTab === 'process' ? (
this.route({ 'processPage': i }) } />
+ onPageChanged={ i => this.route({ 'processPage': i }) }
+ renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } />
) : (objTypeTab === 'workflow' ? (
this.getUrl({ 'workflowPage': i }) } />
+ getPageUrl={ i => this.getUrl({ 'workflowPage': i }) }
+ renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } />
) : null))
}
diff --git a/frontend/src/js/widget/wb-dialog.js b/frontend/src/js/widget/wb-dialog.js
new file mode 100644
index 0000000..570a625
--- /dev/null
+++ b/frontend/src/js/widget/wb-dialog.js
@@ -0,0 +1,56 @@
+import { h, Component } from 'preact';
+
+class WBDialog extends Component {
+ constructor(...args) {
+ super(...args);
+ this.state.id = uuid.v4();
+ }
+
+ show() {
+ const { id } = this.state;
+ $('#' + id).modal();
+ }
+
+ hide() {
+ const { id } = this.state;
+ $('#' + id).modal('hide');
+ }
+
+ render({ title, children, accept, reject }, { id }) {
+ return (
+
+ );
+ }
+}
+
+WBDialog.defaultProps = {
+ 'title': 'Dialog',
+ 'accept': () => {},
+ 'reject': () => {}
+};
+
+export default WBDialog;