@@ -18,7 +18,7 @@ class WBProjectListing extends Component { | |||
prepareRows(items) { | |||
const { app, renderRenameLink, renderDeleteButton, | |||
renderSelectionCell } = this.props; | |||
renderSelectionCell, renderSharingButton } = this.props; | |||
return items.map(item => [ | |||
renderSelectionCell(item), | |||
@@ -39,6 +39,7 @@ class WBProjectListing extends Component { | |||
<i class="fas fa-toolbox"></i> | |||
</button> | |||
{ renderDeleteButton(item, () => this.fetchItems()) } | |||
{ renderSharingButton(item) } | |||
</div>) | |||
]); | |||
} | |||
@@ -42,6 +42,7 @@ class WBBrowseDialog extends Component { | |||
this.state.bottomPage = 0; | |||
this.state.collectionPath = ''; | |||
this.state.textSearch = ''; | |||
this.state.id = ('id' in this.props) ? this.props.id : uuid.v4(); | |||
} | |||
navigateBack() { | |||
@@ -134,10 +135,14 @@ class WBBrowseDialog extends Component { | |||
); | |||
} | |||
render({ app, id, selectMany, selectWhat }, | |||
show(callback) { | |||
$('#' + this.state.id).modal(); | |||
} | |||
render({ app, selectMany, selectWhat }, | |||
{ history, currentUrl, mode, uuid, | |||
topPage, bottomPage, textSearch, | |||
collectionPath }) { | |||
collectionPath, id }) { | |||
return ( | |||
<div class="modal" id={ id } tabindex="-1" role="dialog"> | |||
@@ -13,6 +13,7 @@ import WBWorkflowView from 'wb-workflow-view'; | |||
import WBLaunchWorkflowPage from 'wb-launch-workflow-page'; | |||
import WBDownloadPage from 'wb-download-page'; | |||
import WBImageViewerPage from 'wb-image-viewer-page'; | |||
import WBSharingPage from 'wb-sharing-page'; | |||
import arvadosTypeName from 'arvados-type-name'; | |||
class WBApp extends Component { | |||
@@ -97,6 +98,8 @@ class WBApp extends Component { | |||
<WBDownloadPage path="/download/:blocksBlobUrl/:inline?" app={ this } /> | |||
<WBImageViewerPage path="/image-viewer/:blobUrl" app={ this } /> | |||
<WBSharingPage path="/sharing/:uuid" app={ this } /> | |||
</Router> | |||
); | |||
} | |||
@@ -109,6 +109,15 @@ class WBBrowse extends Component { | |||
); | |||
} | |||
renderSharingButton(item) { | |||
return ( | |||
<a class="btn btn-outline-success m-1" title="Share" | |||
href={ '/sharing/' + item.uuid }> | |||
<i class="fas fa-share-alt"></i> | |||
</a> | |||
); | |||
} | |||
moveOrCopyOp(op) { | |||
const { ownerUuid, app } = this.props; | |||
const { selected } = this.state; | |||
@@ -164,7 +173,8 @@ class WBBrowse extends Component { | |||
getPageUrl={ i => this.getUrl({ 'activePage': i }) } | |||
renderRenameLink={ (it, cb) => this.renderRenameLink(it, cb) } | |||
renderDeleteButton={ (it, cb) => this.renderDeleteButton(it, cb) } | |||
renderSelectionCell={ it => this.renderSelectionCell(it) } /> | |||
renderSelectionCell={ it => this.renderSelectionCell(it) } | |||
renderSharingButton={ it => this.renderSharingButton(it) } /> | |||
{ (mode !== 'browse') ? null : ( | |||
<WBTabs tabs={ [ | |||
@@ -0,0 +1,71 @@ | |||
import { h, Component, createRef } from 'preact'; | |||
import WBNavbarCommon from 'wb-navbar-common'; | |||
import WBArvadosCrumbs from 'wb-arvados-crumbs'; | |||
import WBNameAndUuid from 'wb-name-and-uuid'; | |||
import WBSelect from 'wb-select'; | |||
import WBTable from 'wb-table'; | |||
import WBBrowseDialog from 'wb-browse-dialog'; | |||
import makeArvadosRequest from 'make-arvados-request'; | |||
class WBSharingPage extends Component { | |||
constructor(...args) { | |||
super(...args); | |||
this.state.rows = []; | |||
this.browseDialogRef = createRef(); | |||
} | |||
componentDidMount() { | |||
this.fetchData(); | |||
} | |||
fetchData() { | |||
const { app, uuid } = this.props; | |||
const { arvHost, arvToken } = app.state; | |||
let prom = makeArvadosRequest(arvHost, arvToken, | |||
'/arvados/v1/permissions/' + encodeURIComponent(uuid)); | |||
prom = prom.then(xhr => this.setState({ | |||
'rows': this.prepareRows(xhr.response.items) | |||
})); | |||
} | |||
deletePermission(uuid) { | |||
throw Error('Not implemented'); | |||
} | |||
prepareRows(items) { | |||
const { app } = this.props; | |||
return items.map(it => [ | |||
( <WBNameAndUuid app={ app } uuid={ it.tail_uuid } /> ), | |||
( <WBSelect value={ it.name } options={ ['can_read', 'can_write', 'can_manage'] } /> ), | |||
( <button class="btn btn-outline-danger m-1" title="Delete" | |||
onclick={ () => this.deletePermission(it.uuid) }> | |||
<i class="fas fa-trash"></i> | |||
</button> ) | |||
]); | |||
} | |||
render({ app, uuid }, { rows }) { | |||
return ( | |||
<div> | |||
<WBNavbarCommon app={ app } /> | |||
<WBArvadosCrumbs app={ app } uuid={ uuid } /> | |||
<div class="my-2"> | |||
This is the sharing management page for { uuid } | |||
</div> | |||
<WBTable columns={ [ 'Name', 'Permission', '' ] } | |||
headerClasses={ [ null, null, 'w-1' ] } | |||
rows={ rows } /> | |||
<WBBrowseDialog app={ app } ref={ this.browseDialogRef } /> | |||
<button class="btn btn-primary" | |||
onclick={ () => this.browseDialogRef.current.show() }>Add</button> | |||
</div> | |||
); | |||
} | |||
} | |||
export default WBSharingPage; |
@@ -0,0 +1,19 @@ | |||
import { h, Component } from 'preact'; | |||
class WBSelect extends Component { | |||
render({ value, options, onChange }) { | |||
return ( | |||
<select class="form-control" onchange={ onChange }> | |||
{ options.map(o => { | |||
const name = (typeof(o) === 'string') ? o : o.name; | |||
const id = (typeof(o) === 'object') ? o.id : name; | |||
return ( | |||
<option selected={ (value === id) } value={ id }>{ name }</option> | |||
); | |||
}) } | |||
</select> | |||
); | |||
} | |||
} | |||
export default WBSelect; |