IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an email to s dot adaszewski at gmail dot com. User accounts are meant only to report issues and/or generate pull requests. This is a purpose-specific Git hosting for ADARED projects. Thank you for your understanding!
Browse Source

Added renaming functionality.

pull/1/head
parent
commit
220ad9dd27
8 changed files with 175 additions and 14 deletions
  1. +5
    -3
      frontend/src/js/component/wb-collection-listing.js
  2. +4
    -1
      frontend/src/js/component/wb-process-listing.js
  3. +7
    -4
      frontend/src/js/component/wb-project-listing.js
  4. +12
    -1
      frontend/src/js/component/wb-workflow-listing.js
  5. +45
    -0
      frontend/src/js/dialog/wb-rename-dialog.js
  6. +16
    -0
      frontend/src/js/misc/wb-rename-object.js
  7. +30
    -5
      frontend/src/js/page/wb-browse.js
  8. +56
    -0
      frontend/src/js/widget/wb-dialog.js

+ 5
- 3
frontend/src/js/component/wb-collection-listing.js View File

@@ -21,12 +21,14 @@ class WBCollectionListing extends Component {
}
prepareRows(items, ownerLookup) {
let { app } = this.props;
let { app, renderRenameLink } = this.props;
return items.map(item => [
(<div>
<div>
<a href={ urlForObject(item) }>{ item['name'] }</a>
<a href={ urlForObject(item) }>
{ item['name'] }
</a> { renderRenameLink(item, () => this.fetchItems()) }
</div>
<div>{ item['uuid'] }</div>
</div>),


+ 4
- 1
frontend/src/js/component/wb-process-listing.js View File

@@ -22,11 +22,14 @@ class WBProcessListing extends Component {
}
prepareRows(items) {
const { renderRenameLink } = this.props;
return items.map(item => [
(<div>
<div>
<a href="#"
onclick={ e => { e.preventDefault(); route('/process/' + item['uuid']) }}>{ item['name'] }</a>
onclick={ e => { e.preventDefault(); route('/process/' + item['uuid']) }}>
{ item['name'] }
</a> { renderRenameLink(item, () => this.fetchItems()) }
</div>
<div>{ item['uuid'] }</div>
</div>),


+ 7
- 4
frontend/src/js/component/wb-project-listing.js View File

@@ -17,13 +17,15 @@ class WBProjectListing extends Component {
}
prepareRows(items) {
let { app } = this.props;
let { app, renderRenameLink } = this.props;
return items.map(item => [
(<div>
<div>
<a href="#"
onclick={ e => { e.preventDefault(); route('/browse/' + item['uuid']) }}>{ item['name'] }</a>
onclick={ e => { e.preventDefault(); route('/browse/' + item['uuid']) }}>
{ item['name'] }
</a> { renderRenameLink(item, () => this.fetchItems()) }
</div>
<div>{ item['uuid'] }</div>
</div>),
@@ -78,7 +80,8 @@ class WBProjectListing extends Component {
WBProjectListing.defaultProps = {
'itemsPerPage': 100,
'ownerUuid': null
'ownerUuid': null,
'renderRenameLink': () => null
};
export default WBProjectListing;

+ 12
- 1
frontend/src/js/component/wb-workflow-listing.js View File

@@ -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 => [
( <WBNameAndUuid uuid={ item.uuid } lookup={ { [item.uuid]: item } } /> ),
(
<div>
<div>
<a href={ urlForObject(item) }>
{ arvadosObjectName(item) }
</a> { renderRenameLink(item, () => this.fetchItems()) }
</div>
<div>{ item.uuid }</div>
</div>
),
item.description,
( <WBNameAndUuid uuid={ item.owner_uuid } lookup={ ownerLookup } /> ),
wbFormatDate(item.created_at),


+ 45
- 0
frontend/src/js/dialog/wb-rename-dialog.js View File

@@ -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 (
<WBDialog title="Rename" ref={ this.dialogRef } accept={ () => {
if (newName)
wbRenameObject(arvHost, arvToken, item.uuid, newName).then(callback);
} }>
<div>
<input type="text" class="form-control" id={ inputId }
placeholder={ item ? item.name : 'Type new name here' }
value={ newName } onChange={ linkState(this, 'newName') } />
</div>
</WBDialog>
);
}
}
export default WBRenameDialog;

+ 16
- 0
frontend/src/js/misc/wb-rename-object.js View File

@@ -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;

+ 30
- 5
frontend/src/js/page/wb-browse.js View File

@@ -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 (
<a href="#" title="Rename" onclick={ e => { e.preventDefault(); this.renameDialog(item, callback); } }>
<i class="fas fa-edit text-secondary"></i>
</a>
);
}
render({ ownerUuid, activePage, appState, app,
objTypeTab, collectionPage, processPage, workflowPage }) {
return (
<div>
<WBRenameDialog app={ app } ref={ this.renameDialogRef } />
<WBNavbarCommon app={ app } activeItem={ !ownerUuid ? 'all-projects' :
(ownerUuid === app.state.currentUser.uuid ? 'home' : null) } />
@@ -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) } />
<WBTabs tabs={ [
{ 'id': 'collection', 'name': 'Collections', 'isActive': (!objTypeTab || objTypeTab === 'collection') },
@@ -58,21 +80,24 @@ class WBBrowse extends Component {
ownerUuid={ ownerUuid }
itemsPerPage="20"
activePage={ Number(collectionPage || 0) }
getPageUrl={ i => this.getUrl({ 'collectionPage': i }) } />
getPageUrl={ i => this.getUrl({ 'collectionPage': i }) }
renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } />
) : (objTypeTab === 'process' ? (
<WBProcessListing appState={ appState }
ownerUuid={ ownerUuid }
itemsPerPage="20"
activePage={ Number(processPage || 0) }
onPageChanged={ i => this.route({ 'processPage': i }) } />
onPageChanged={ i => this.route({ 'processPage': i }) }
renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } />
) : (objTypeTab === 'workflow' ? (
<WBWorkflowListing app={ app }
ownerUuid={ ownerUuid }
itemsPerPage="20"
page={ Number(workflowPage || 0) }
getPageUrl={ i => this.getUrl({ 'workflowPage': i }) } />
getPageUrl={ i => this.getUrl({ 'workflowPage': i }) }
renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } />
) : null))
}


+ 56
- 0
frontend/src/js/widget/wb-dialog.js View File

@@ -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 (
<form class="m-0">
<div class="modal" id={ id } tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{ title }</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
{ children[0] }
</div>
<div class="modal-footer">
<input type="submit" class="btn btn-primary" value="Accept"
onclick={ e => { e.preventDefault(); this.hide(); accept(); } } />
<button type="button" class="btn btn-secondary"
onclick={ () => { this.hide(); reject(); } }>Cancel</button>
</div>
</div>
</div>
</div>
</form>
);
}
}
WBDialog.defaultProps = {
'title': 'Dialog',
'accept': () => {},
'reject': () => {}
};
export default WBDialog;

Loading…
Cancel
Save