@@ -21,7 +21,7 @@ class WBCollectionListing extends Component { | |||||
} | } | ||||
prepareRows(items, ownerLookup) { | prepareRows(items, ownerLookup) { | ||||
let { app, renderRenameLink } = this.props; | |||||
let { app, renderRenameLink, renderDeleteButton } = this.props; | |||||
return items.map(item => [ | return items.map(item => [ | ||||
(<div> | (<div> | ||||
@@ -56,9 +56,7 @@ class WBCollectionListing extends Component { | |||||
<i class="fas fa-list-ul"></i> | <i class="fas fa-list-ul"></i> | ||||
</a> | </a> | ||||
<button class="btn btn-outline-danger m-1" title="Delete"> | |||||
<i class="fas fa-trash"></i> | |||||
</button> | |||||
{ renderDeleteButton(item, () => this.fetchItems()) } | |||||
</div>) | </div>) | ||||
]); | ]); | ||||
} | } | ||||
@@ -22,7 +22,7 @@ class WBProcessListing extends Component { | |||||
} | } | ||||
prepareRows(items) { | prepareRows(items) { | ||||
const { renderRenameLink } = this.props; | |||||
const { renderRenameLink, renderDeleteButton } = this.props; | |||||
return items.map(item => [ | return items.map(item => [ | ||||
(<div> | (<div> | ||||
<div> | <div> | ||||
@@ -38,7 +38,7 @@ class WBProcessListing extends Component { | |||||
item['created_at'].replace('T', ' ').substr(0, item['created_at'].length - 11) + '', | item['created_at'].replace('T', ' ').substr(0, item['created_at'].length - 11) + '', | ||||
item['output_uuid'], | item['output_uuid'], | ||||
(<div> | (<div> | ||||
<button class="btn btn-outline-danger"><i class="fas fa-trash"></i></button> | |||||
{ renderDeleteButton(item, () => this.fetchItems()) } | |||||
</div>) | </div>) | ||||
]); | ]); | ||||
} | } | ||||
@@ -17,7 +17,7 @@ class WBProjectListing extends Component { | |||||
} | } | ||||
prepareRows(items) { | prepareRows(items) { | ||||
let { app, renderRenameLink } = this.props; | |||||
let { app, renderRenameLink, renderDeleteButton } = this.props; | |||||
return items.map(item => [ | return items.map(item => [ | ||||
(<div> | (<div> | ||||
@@ -36,6 +36,7 @@ class WBProjectListing extends Component { | |||||
onclick={ () => (app.addToToolbox(item.uuid)) }> | onclick={ () => (app.addToToolbox(item.uuid)) }> | ||||
<i class="fas fa-toolbox"></i> | <i class="fas fa-toolbox"></i> | ||||
</button> | </button> | ||||
{ renderDeleteButton(item, () => this.fetchItems()) } | |||||
</div>) | </div>) | ||||
]); | ]); | ||||
} | } | ||||
@@ -21,7 +21,7 @@ class WBWorkflowListing extends Component { | |||||
} | } | ||||
prepareRows(items, ownerLookup) { | prepareRows(items, ownerLookup) { | ||||
const { renderRenameLink } = this.props; | |||||
const { renderRenameLink, renderDeleteButton } = this.props; | |||||
return items.map(item => [ | return items.map(item => [ | ||||
( | ( | ||||
<div> | <div> | ||||
@@ -40,7 +40,7 @@ class WBWorkflowListing extends Component { | |||||
<a class="btn btn-outline-success mx-1 my-1" title="Launch" | <a class="btn btn-outline-success mx-1 my-1" title="Launch" | ||||
href={ urlForObject(item, 'launch') }><i class="fas fa-running"></i></a> | 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-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>) | </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 WBCollectionListing from 'wb-collection-listing'; | ||||
import WBWorkflowListing from 'wb-workflow-listing'; | import WBWorkflowListing from 'wb-workflow-listing'; | ||||
import WBRenameDialog from 'wb-rename-dialog'; | import WBRenameDialog from 'wb-rename-dialog'; | ||||
import WBDeleteDialog from 'wb-delete-dialog'; | |||||
class WBBrowse extends Component { | class WBBrowse extends Component { | ||||
constructor(...args) { | constructor(...args) { | ||||
super(...args); | super(...args); | ||||
this.renameDialogRef = createRef(); | this.renameDialogRef = createRef(); | ||||
this.deleteDialogRef = createRef(); | |||||
} | } | ||||
getUrl(params) { | 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, | render({ ownerUuid, activePage, appState, app, | ||||
objTypeTab, collectionPage, processPage, workflowPage }) { | objTypeTab, collectionPage, processPage, workflowPage }) { | ||||
@@ -52,6 +63,8 @@ class WBBrowse extends Component { | |||||
<div> | <div> | ||||
<WBRenameDialog app={ app } ref={ this.renameDialogRef } /> | <WBRenameDialog app={ app } ref={ this.renameDialogRef } /> | ||||
<WBDeleteDialog app={ app } ref={ this.deleteDialogRef } /> | |||||
<WBNavbarCommon app={ app } activeItem={ !ownerUuid ? 'all-projects' : | <WBNavbarCommon app={ app } activeItem={ !ownerUuid ? 'all-projects' : | ||||
(ownerUuid === app.state.currentUser.uuid ? 'home' : null) } /> | (ownerUuid === app.state.currentUser.uuid ? 'home' : null) } /> | ||||
@@ -66,7 +79,8 @@ class WBBrowse extends Component { | |||||
itemsPerPage="5" | itemsPerPage="5" | ||||
activePage={ Number(activePage || 0) } | activePage={ Number(activePage || 0) } | ||||
onPageChanged={ i => route('/browse/' + (ownerUuid || '') + '/' + i) } | 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={ [ | <WBTabs tabs={ [ | ||||
{ 'id': 'collection', 'name': 'Collections', 'isActive': (!objTypeTab || objTypeTab === 'collection') }, | { 'id': 'collection', 'name': 'Collections', 'isActive': (!objTypeTab || objTypeTab === 'collection') }, | ||||
@@ -81,7 +95,8 @@ class WBBrowse extends Component { | |||||
itemsPerPage="20" | itemsPerPage="20" | ||||
activePage={ Number(collectionPage || 0) } | activePage={ Number(collectionPage || 0) } | ||||
getPageUrl={ i => this.getUrl({ 'collectionPage': i }) } | 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' ? ( | ) : (objTypeTab === 'process' ? ( | ||||
<WBProcessListing appState={ appState } | <WBProcessListing appState={ appState } | ||||
@@ -89,7 +104,8 @@ class WBBrowse extends Component { | |||||
itemsPerPage="20" | itemsPerPage="20" | ||||
activePage={ Number(processPage || 0) } | activePage={ Number(processPage || 0) } | ||||
onPageChanged={ i => this.route({ 'processPage': i }) } | 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' ? ( | ) : (objTypeTab === 'workflow' ? ( | ||||
<WBWorkflowListing app={ app } | <WBWorkflowListing app={ app } | ||||
@@ -97,7 +113,8 @@ class WBBrowse extends Component { | |||||
itemsPerPage="20" | itemsPerPage="20" | ||||
page={ Number(workflowPage || 0) } | page={ Number(workflowPage || 0) } | ||||
getPageUrl={ i => this.getUrl({ 'workflowPage': i }) } | 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)) | ) : null)) | ||||
} | } | ||||
@@ -34,10 +34,13 @@ class WBDialog extends Component { | |||||
</div> | </div> | ||||
<div class="modal-footer"> | <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> | </div> | ||||
</div> | </div> | ||||