| @@ -22,7 +22,8 @@ class WBCollectionListing extends Component { | |||||
| prepareRows(items, ownerLookup) { | prepareRows(items, ownerLookup) { | ||||
| let { app, renderRenameLink, renderDeleteButton, | let { app, renderRenameLink, renderDeleteButton, | ||||
| renderSelectionCell, renderSharingButton } = this.props; | |||||
| renderSelectionCell, renderSharingButton, | |||||
| renderEditDescription } = this.props; | |||||
| return items.map(item => [ | return items.map(item => [ | ||||
| renderSelectionCell(item), | renderSelectionCell(item), | ||||
| @@ -34,7 +35,9 @@ class WBCollectionListing extends Component { | |||||
| </div> | </div> | ||||
| <div>{ item['uuid'] }</div> | <div>{ item['uuid'] }</div> | ||||
| </div>), | </div>), | ||||
| item['description'], | |||||
| (<div> | |||||
| { item['description'] } { renderEditDescription(item, () => this.fetchItems()) } | |||||
| </div>), | |||||
| (<div> | (<div> | ||||
| <div> | <div> | ||||
| { ownerLookup[item.owner_uuid] ? ( | { ownerLookup[item.owner_uuid] ? ( | ||||
| @@ -153,7 +156,9 @@ class WBCollectionListing extends Component { | |||||
| WBCollectionListing.defaultProps = { | WBCollectionListing.defaultProps = { | ||||
| 'itemsPerPage': 100, | 'itemsPerPage': 100, | ||||
| 'ownerUuid': null | |||||
| 'ownerUuid': null, | |||||
| 'renderSharingButton': () => null, | |||||
| 'renderEditDescription': () => null | |||||
| }; | }; | ||||
| export default WBCollectionListing; | export default WBCollectionListing; | ||||
| @@ -29,7 +29,9 @@ class WBProcessListing extends Component { | |||||
| prepareRows(requests, containerLookup, ownerLookup, outputLookup) { | prepareRows(requests, containerLookup, ownerLookup, outputLookup) { | ||||
| const { app, renderRenameLink, renderDeleteButton, | const { app, renderRenameLink, renderDeleteButton, | ||||
| renderSelectionCell, renderSharingButton } = this.props; | |||||
| renderSelectionCell, renderSharingButton, | |||||
| renderEditDescription } = this.props; | |||||
| return requests.map(item => { | return requests.map(item => { | ||||
| return ( [ | return ( [ | ||||
| renderSelectionCell(item), | renderSelectionCell(item), | ||||
| @@ -40,6 +42,9 @@ class WBProcessListing extends Component { | |||||
| </a> { renderRenameLink(item, () => this.fetchItems()) } | </a> { renderRenameLink(item, () => this.fetchItems()) } | ||||
| </div> | </div> | ||||
| <div>{ item['uuid'] }</div> | <div>{ item['uuid'] }</div> | ||||
| <div class="mt-2"> | |||||
| { item.description } { renderEditDescription(item, () => this.fetchItems()) } | |||||
| </div> | |||||
| </div>), | </div>), | ||||
| ( <WBProcessState app={ app } process={ item } /> ), | ( <WBProcessState app={ app } process={ item } /> ), | ||||
| ( <WBNameAndUuid app={ app } uuid={ item['owner_uuid'] } /> ), | ( <WBNameAndUuid app={ app } uuid={ item['owner_uuid'] } /> ), | ||||
| @@ -121,7 +126,8 @@ WBProcessListing.defaultProps = { | |||||
| renderRenameLink: () => null, | renderRenameLink: () => null, | ||||
| renderDeleteButton: () => null, | renderDeleteButton: () => null, | ||||
| renderSelectionCell: () => null, | renderSelectionCell: () => null, | ||||
| renderSharingButton: () => null | |||||
| renderSharingButton: () => null, | |||||
| renderEditDescription: () => null | |||||
| }; | }; | ||||
| export default WBProcessListing; | export default WBProcessListing; | ||||
| @@ -18,7 +18,8 @@ class WBProjectListing extends Component { | |||||
| prepareRows(items) { | prepareRows(items) { | ||||
| const { app, renderRenameLink, renderDeleteButton, | const { app, renderRenameLink, renderDeleteButton, | ||||
| renderSelectionCell, renderSharingButton } = this.props; | |||||
| renderSelectionCell, renderSharingButton, | |||||
| renderEditDescription } = this.props; | |||||
| return items.map(item => [ | return items.map(item => [ | ||||
| renderSelectionCell(item), | renderSelectionCell(item), | ||||
| @@ -30,7 +31,9 @@ class WBProjectListing extends Component { | |||||
| </div> | </div> | ||||
| <div>{ item['uuid'] }</div> | <div>{ item['uuid'] }</div> | ||||
| </div>), | </div>), | ||||
| item['description'], | |||||
| (<div> | |||||
| { item['description'] } { renderEditDescription(item, () => this.fetchItems()) } | |||||
| </div>), | |||||
| item['owner_uuid'], | item['owner_uuid'], | ||||
| (<div> | (<div> | ||||
| { renderDeleteButton(item, () => this.fetchItems()) } | { renderDeleteButton(item, () => this.fetchItems()) } | ||||
| @@ -87,7 +90,8 @@ WBProjectListing.defaultProps = { | |||||
| 'ownerUuid': null, | 'ownerUuid': null, | ||||
| 'renderRenameLink': () => null, | 'renderRenameLink': () => null, | ||||
| 'renderDeleteButton': () => null, | 'renderDeleteButton': () => null, | ||||
| 'renderSelectionCell': () => null | |||||
| 'renderSelectionCell': () => null, | |||||
| 'renderEditDescription': () => null | |||||
| }; | }; | ||||
| export default WBProjectListing; | export default WBProjectListing; | ||||
| @@ -22,7 +22,9 @@ class WBWorkflowListing extends Component { | |||||
| prepareRows(items, ownerLookup) { | prepareRows(items, ownerLookup) { | ||||
| const { renderRenameLink, renderDeleteButton, | const { renderRenameLink, renderDeleteButton, | ||||
| renderSelectionCell, renderSharingButton } = this.props; | |||||
| renderSelectionCell, renderSharingButton, | |||||
| renderEditDescription } = this.props; | |||||
| return items.map(item => [ | return items.map(item => [ | ||||
| renderSelectionCell(item), | renderSelectionCell(item), | ||||
| ( | ( | ||||
| @@ -35,7 +37,9 @@ class WBWorkflowListing extends Component { | |||||
| <div>{ item.uuid }</div> | <div>{ item.uuid }</div> | ||||
| </div> | </div> | ||||
| ), | ), | ||||
| item.description, | |||||
| (<div> | |||||
| { item.description } { renderEditDescription(item, () => this.fetchItems()) } | |||||
| </div>), | |||||
| ( <WBNameAndUuid uuid={ item.owner_uuid } lookup={ ownerLookup } /> ), | ( <WBNameAndUuid uuid={ item.owner_uuid } lookup={ ownerLookup } /> ), | ||||
| wbFormatDate(item.created_at), | wbFormatDate(item.created_at), | ||||
| (<div> | (<div> | ||||
| @@ -97,7 +101,9 @@ class WBWorkflowListing extends Component { | |||||
| WBWorkflowListing.defaultProps = { | WBWorkflowListing.defaultProps = { | ||||
| 'itemsPerPage': 100, | 'itemsPerPage': 100, | ||||
| 'ownerUuid': null | |||||
| 'ownerUuid': null, | |||||
| 'renderSharingButton': () => null, | |||||
| 'renderEditDescription': () => null | |||||
| }; | }; | ||||
| export default WBWorkflowListing; | export default WBWorkflowListing; | ||||
| @@ -0,0 +1,52 @@ | |||||
| import { h, Component, createRef } from 'preact'; | |||||
| import WBDialog from 'wb-dialog'; | |||||
| import linkState from 'linkstate'; | |||||
| import makeArvadosRequest from 'make-arvados-request'; | |||||
| import arvadosTypeName from 'arvados-type-name'; | |||||
| class WBEditDescriptionDialog 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, | |||||
| 'newDescription': null, | |||||
| 'callback': callback || (() => {}) | |||||
| }); | |||||
| this.dialogRef.current.show(); | |||||
| $('#' + inputId).focus(); | |||||
| } | |||||
| hide() { | |||||
| this.dialogRef.current.hide(); | |||||
| } | |||||
| render({ app }, { item, newDescription, callback, inputId }) { | |||||
| const { arvHost, arvToken } = app.state; | |||||
| return ( | |||||
| <WBDialog title="Edit Description" ref={ this.dialogRef } accept={ () => | |||||
| makeArvadosRequest(arvHost, arvToken, | |||||
| '/arvados/v1/' + arvadosTypeName(item.uuid) + | |||||
| 's/' + item.uuid, { | |||||
| method: 'PUT', | |||||
| data: JSON.stringify({ | |||||
| description: newDescription || null | |||||
| }) | |||||
| }).then(callback) | |||||
| }> | |||||
| <div> | |||||
| <input type="text" class="form-control" id={ inputId } | |||||
| placeholder={ (item && item.description) ? item.description : 'Type new description here' } | |||||
| value={ newDescription } onChange={ linkState(this, 'newDescription') } /> | |||||
| </div> | |||||
| </WBDialog> | |||||
| ); | |||||
| } | |||||
| } | |||||
| export default WBEditDescriptionDialog; | |||||
| @@ -11,6 +11,7 @@ import WBWorkflowListing from 'wb-workflow-listing'; | |||||
| import WBRenameDialog from 'wb-rename-dialog'; | import WBRenameDialog from 'wb-rename-dialog'; | ||||
| import WBDeleteDialog from 'wb-delete-dialog'; | import WBDeleteDialog from 'wb-delete-dialog'; | ||||
| import WBNewProjectDialog from 'wb-new-project-dialog'; | import WBNewProjectDialog from 'wb-new-project-dialog'; | ||||
| import WBEditDescriptionDialog from 'wb-edit-description-dialog'; | |||||
| import wbMoveObject from 'wb-move-object'; | import wbMoveObject from 'wb-move-object'; | ||||
| import wbCopyCollection from 'wb-copy-collection'; | import wbCopyCollection from 'wb-copy-collection'; | ||||
| import arvadosTypeName from 'arvados-type-name'; | import arvadosTypeName from 'arvados-type-name'; | ||||
| @@ -45,6 +46,7 @@ class WBBrowse extends Component { | |||||
| this.newProjectDialogRef = createRef(); | this.newProjectDialogRef = createRef(); | ||||
| this.projectListingRef = createRef(); | this.projectListingRef = createRef(); | ||||
| this.projectTabsRef = createRef(); | this.projectTabsRef = createRef(); | ||||
| this.editDescriptionDialogRef = createRef(); | |||||
| this.state.selected = {}; | this.state.selected = {}; | ||||
| } | } | ||||
| @@ -85,6 +87,16 @@ class WBBrowse extends Component { | |||||
| ); | ); | ||||
| } | } | ||||
| renderEditDescription(item, callback) { | |||||
| return ( | |||||
| <a href="#" title="Edit description" onclick={ e => { e.preventDefault(); | |||||
| this.editDescriptionDialogRef.current.show(item, callback); } }> | |||||
| <i class="fas fa-edit text-secondary"></i> | |||||
| </a> | |||||
| ); | |||||
| } | |||||
| renderDeleteButton(item, callback) { | renderDeleteButton(item, callback) { | ||||
| return ( | return ( | ||||
| <button class="btn btn-outline-danger m-1" title="Delete" | <button class="btn btn-outline-danger m-1" title="Delete" | ||||
| @@ -148,6 +160,7 @@ class WBBrowse extends Component { | |||||
| const commonProps = { | const commonProps = { | ||||
| renderRenameLink: (it, cb) => this.renderRenameLink(it, cb), | renderRenameLink: (it, cb) => this.renderRenameLink(it, cb), | ||||
| renderEditDescription: (it, cb) => this.renderEditDescription(it, cb), | |||||
| renderDeleteButton: (it, cb) => this.renderDeleteButton(it, cb), | renderDeleteButton: (it, cb) => this.renderDeleteButton(it, cb), | ||||
| renderSelectionCell: it => this.renderSelectionCell(it), | renderSelectionCell: it => this.renderSelectionCell(it), | ||||
| renderSharingButton: it => this.renderSharingButton(it), | renderSharingButton: it => this.renderSharingButton(it), | ||||
| @@ -167,6 +180,8 @@ class WBBrowse extends Component { | |||||
| <WBNewProjectDialog app={ app } ref={ this.newProjectDialogRef } /> | <WBNewProjectDialog app={ app } ref={ this.newProjectDialogRef } /> | ||||
| <WBEditDescriptionDialog app={ app } ref={ this.editDescriptionDialogRef } /> | |||||
| <WBNavbarCommon app={ app } | <WBNavbarCommon app={ app } | ||||
| activeItem={ mode === 'shared-with-me' ? 'shared-with-me' : | activeItem={ mode === 'shared-with-me' ? 'shared-with-me' : | ||||
| (!ownerUuid) ? 'all-projects' : | (!ownerUuid) ? 'all-projects' : | ||||