| @@ -21,7 +21,7 @@ class WBCollectionListing extends Component { | |||
| } | |||
| prepareRows(items, ownerLookup) { | |||
| let { app, renderRenameLink } = this.props; | |||
| let { app, renderRenameLink, renderDeleteButton } = this.props; | |||
| return items.map(item => [ | |||
| (<div> | |||
| @@ -56,9 +56,7 @@ class WBCollectionListing extends Component { | |||
| <i class="fas fa-list-ul"></i> | |||
| </a> | |||
| <button class="btn btn-outline-danger m-1" title="Delete"> | |||
| <i class="fas fa-trash"></i> | |||
| </button> | |||
| { renderDeleteButton(item, () => this.fetchItems()) } | |||
| </div>) | |||
| ]); | |||
| } | |||
| @@ -22,7 +22,7 @@ class WBProcessListing extends Component { | |||
| } | |||
| prepareRows(items) { | |||
| const { renderRenameLink } = this.props; | |||
| const { renderRenameLink, renderDeleteButton } = this.props; | |||
| return items.map(item => [ | |||
| (<div> | |||
| <div> | |||
| @@ -38,7 +38,7 @@ class WBProcessListing extends Component { | |||
| item['created_at'].replace('T', ' ').substr(0, item['created_at'].length - 11) + '', | |||
| item['output_uuid'], | |||
| (<div> | |||
| <button class="btn btn-outline-danger"><i class="fas fa-trash"></i></button> | |||
| { renderDeleteButton(item, () => this.fetchItems()) } | |||
| </div>) | |||
| ]); | |||
| } | |||
| @@ -17,7 +17,7 @@ class WBProjectListing extends Component { | |||
| } | |||
| prepareRows(items) { | |||
| let { app, renderRenameLink } = this.props; | |||
| let { app, renderRenameLink, renderDeleteButton } = this.props; | |||
| return items.map(item => [ | |||
| (<div> | |||
| @@ -36,6 +36,7 @@ class WBProjectListing extends Component { | |||
| onclick={ () => (app.addToToolbox(item.uuid)) }> | |||
| <i class="fas fa-toolbox"></i> | |||
| </button> | |||
| { renderDeleteButton(item, () => this.fetchItems()) } | |||
| </div>) | |||
| ]); | |||
| } | |||
| @@ -21,7 +21,7 @@ class WBWorkflowListing extends Component { | |||
| } | |||
| prepareRows(items, ownerLookup) { | |||
| const { renderRenameLink } = this.props; | |||
| const { renderRenameLink, renderDeleteButton } = this.props; | |||
| return items.map(item => [ | |||
| ( | |||
| <div> | |||
| @@ -40,7 +40,7 @@ class WBWorkflowListing extends Component { | |||
| <a class="btn btn-outline-success mx-1 my-1" title="Launch" | |||
| href={ urlForObject(item, 'launch') }><i class="fas fa-running"></i></a> | |||
| <button class="btn btn-outline-primary mx-1 my-1" title="View"><i class="far fa-eye"></i></button> | |||
| <button class="btn btn-outline-danger mx-1 my-1" title="Delete"><i class="fas fa-trash"></i></button> | |||
| { renderDeleteButton(item, () => this.fetchItems()) } | |||
| </div>) | |||
| ]); | |||
| } | |||
| @@ -0,0 +1,53 @@ | |||
| import { h, Component, createRef } from 'preact'; | |||
| import WBDialog from 'wb-dialog'; | |||
| import WBArvadosCrumbs from 'wb-arvados-crumbs'; | |||
| import linkState from 'linkstate'; | |||
| import wbDeleteObject from 'wb-delete-object'; | |||
| import arvadosTypeName from 'arvados-type-name'; | |||
| class WBDeleteDialog extends Component { | |||
| constructor(...args) { | |||
| super(...args); | |||
| this.dialogRef = createRef(); | |||
| } | |||
| show(item, callback) { | |||
| this.setState({ | |||
| 'item': item, | |||
| 'callback': callback || (() => {}) | |||
| }); | |||
| this.dialogRef.current.show(); | |||
| } | |||
| hide() { | |||
| this.dialogRef.current.hide(); | |||
| } | |||
| render({ app }, { item, callback }) { | |||
| const { arvHost, arvToken } = app.state; | |||
| return ( | |||
| <WBDialog title="Delete" ref={ this.dialogRef }> | |||
| <div> | |||
| <div class="mb-3"> | |||
| Are you sure you want to delete the following { item ? arvadosTypeName(item.uuid) : null }: | |||
| </div> | |||
| { item ? <WBArvadosCrumbs app={ app } uuid={ item.uuid } /> : null } | |||
| <div>???</div> | |||
| </div> | |||
| <div> | |||
| <input type="submit" class="btn btn-danger mr-2" value="Delete" | |||
| onclick={ e => { e.preventDefault(); | |||
| wbDeleteObject(arvHost, arvToken, item.uuid).then(callback); } } /> | |||
| <button class="btn btn-secondary mr-2" onclick={ e => { e.preventDefault(); | |||
| this.hide(); } }> | |||
| Cancel | |||
| </button> | |||
| </div> | |||
| </WBDialog> | |||
| ); | |||
| } | |||
| } | |||
| export default WBDeleteDialog; | |||
| @@ -0,0 +1,11 @@ | |||
| import makeArvadosRequest from 'make-arvados-request'; | |||
| import arvadosTypeName from 'arvados-type-name'; | |||
| function wbDeleteObject(arvHost, arvToken, uuid) { | |||
| const typeName = arvadosTypeName(uuid); | |||
| return makeArvadosRequest(arvHost, arvToken, | |||
| '/arvados/v1/' + typeName + 's/' + | |||
| uuid, { 'method': 'DELETE' }); | |||
| } | |||
| export default wbDeleteObject; | |||
| @@ -9,11 +9,13 @@ import WBProcessListing from 'wb-process-listing'; | |||
| import WBCollectionListing from 'wb-collection-listing'; | |||
| import WBWorkflowListing from 'wb-workflow-listing'; | |||
| import WBRenameDialog from 'wb-rename-dialog'; | |||
| import WBDeleteDialog from 'wb-delete-dialog'; | |||
| class WBBrowse extends Component { | |||
| constructor(...args) { | |||
| super(...args); | |||
| this.renameDialogRef = createRef(); | |||
| this.deleteDialogRef = createRef(); | |||
| } | |||
| getUrl(params) { | |||
| @@ -45,6 +47,15 @@ class WBBrowse extends Component { | |||
| ); | |||
| } | |||
| renderDeleteButton(item, callback) { | |||
| return ( | |||
| <button class="btn btn-outline-danger m-1" title="Delete" | |||
| onclick={ () => this.deleteDialogRef.current.show(item, callback) }> | |||
| <i class="fas fa-trash"></i> | |||
| </button> | |||
| ); | |||
| } | |||
| render({ ownerUuid, activePage, appState, app, | |||
| objTypeTab, collectionPage, processPage, workflowPage }) { | |||
| @@ -52,6 +63,8 @@ class WBBrowse extends Component { | |||
| <div> | |||
| <WBRenameDialog app={ app } ref={ this.renameDialogRef } /> | |||
| <WBDeleteDialog app={ app } ref={ this.deleteDialogRef } /> | |||
| <WBNavbarCommon app={ app } activeItem={ !ownerUuid ? 'all-projects' : | |||
| (ownerUuid === app.state.currentUser.uuid ? 'home' : null) } /> | |||
| @@ -66,7 +79,8 @@ class WBBrowse extends Component { | |||
| itemsPerPage="5" | |||
| activePage={ Number(activePage || 0) } | |||
| onPageChanged={ i => route('/browse/' + (ownerUuid || '') + '/' + i) } | |||
| renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } /> | |||
| renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } | |||
| renderDeleteButton={ (it, cb) => this.renderDeleteButton(it, cb) } /> | |||
| <WBTabs tabs={ [ | |||
| { 'id': 'collection', 'name': 'Collections', 'isActive': (!objTypeTab || objTypeTab === 'collection') }, | |||
| @@ -81,7 +95,8 @@ class WBBrowse extends Component { | |||
| itemsPerPage="20" | |||
| activePage={ Number(collectionPage || 0) } | |||
| getPageUrl={ i => this.getUrl({ 'collectionPage': i }) } | |||
| renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } /> | |||
| renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } | |||
| renderDeleteButton={ (it, cb) => this.renderDeleteButton(it, cb) } /> | |||
| ) : (objTypeTab === 'process' ? ( | |||
| <WBProcessListing appState={ appState } | |||
| @@ -89,7 +104,8 @@ class WBBrowse extends Component { | |||
| itemsPerPage="20" | |||
| activePage={ Number(processPage || 0) } | |||
| onPageChanged={ i => this.route({ 'processPage': i }) } | |||
| renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } /> | |||
| renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } | |||
| renderDeleteButton={ (it, cb) => this.renderDeleteButton(it, cb) } /> | |||
| ) : (objTypeTab === 'workflow' ? ( | |||
| <WBWorkflowListing app={ app } | |||
| @@ -97,7 +113,8 @@ class WBBrowse extends Component { | |||
| itemsPerPage="20" | |||
| page={ Number(workflowPage || 0) } | |||
| getPageUrl={ i => this.getUrl({ 'workflowPage': i }) } | |||
| renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } /> | |||
| renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } | |||
| renderDeleteButton={ (it, cb) => this.renderDeleteButton(it, cb) } /> | |||
| ) : null)) | |||
| } | |||
| @@ -34,10 +34,13 @@ class WBDialog extends Component { | |||
| </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> | |||
| { children[1] ? children[1] : [ | |||
| <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> | |||