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!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 lines
5.1KB

  1. //
  2. // Copyright (C) Stanislaw Adaszewski, 2020
  3. // Contact: s.adaszewski@gmail.com
  4. // Website: https://adared.ch/wba
  5. // License: GNU Affero General Public License, Version 3
  6. //
  7. import { h, Component } from 'preact';
  8. import { route } from 'preact-router';
  9. import makeArvadosRequest from 'make-arvados-request';
  10. import WBTable from 'wb-table';
  11. import WBPagination from 'wb-pagination';
  12. import WBCheckboxes from 'wb-checkboxes';
  13. import wbFormatDate from 'wb-format-date';
  14. import wbFetchObjects from 'wb-fetch-objects';
  15. import WBNameAndUuid from 'wb-name-and-uuid';
  16. import WBProcessState from 'wb-process-state';
  17. function maskRows(rows) {
  18. return rows.map(r => r.map(c => '-'));
  19. }
  20. class WBProcessListing extends Component {
  21. constructor(...args) {
  22. super(...args);
  23. this.state.rows = [];
  24. this.state.numPages = 0;
  25. this.state.requestStates = [ 'Uncommitted', 'Committed', 'Final' ];
  26. this.state.reqStateMask = [ true, true, true ];
  27. }
  28. componentDidMount() {
  29. this.fetchItems();
  30. }
  31. cancelProcess(uuid) {
  32. const { app } = this.props;
  33. const { arvHost, arvToken } = app.state;
  34. let prom = makeArvadosRequest(arvHost, arvToken,
  35. '/arvados/v1/container_requests/' + encodeURIComponent(uuid),
  36. { method: 'PUT', data: JSON.stringify({ priority: 0 }) });
  37. prom = prom.then(() => {
  38. this.setState({ rows: maskRows(this.state.rows) });
  39. this.fetchItems();
  40. });
  41. }
  42. prepareRows(requests, containerLookup, ownerLookup, outputLookup) {
  43. const { app, renderRenameLink, renderDeleteButton,
  44. renderSelectionCell, renderSharingButton,
  45. renderEditDescription } = this.props;
  46. return requests.map(item => {
  47. return ( [
  48. renderSelectionCell(item),
  49. (<div>
  50. <div>
  51. <a href={ '/process/' + item['uuid'] }>
  52. { item['name'] }
  53. </a> { renderRenameLink(item, () => this.fetchItems()) }
  54. </div>
  55. <div>{ item['uuid'] }</div>
  56. <div class="mt-2">
  57. { item.description } { renderEditDescription(item, () => this.fetchItems()) }
  58. </div>
  59. </div>),
  60. ( <WBProcessState app={ app } process={ item } lazy={ true } /> ),
  61. ( <WBNameAndUuid app={ app } uuid={ item['owner_uuid'] } lazy={ true } /> ),
  62. wbFormatDate(item['created_at']),
  63. ( <WBNameAndUuid app={ app } uuid={ item['output_uuid'] } lazy={ true } /> ),
  64. (<div>
  65. <button class="btn btn-outline-warning m-1" onclick={ () => this.cancelProcess(item.uuid) }>
  66. <i class="fas fa-stop-circle"></i>
  67. </button>
  68. { renderDeleteButton(item, () => this.fetchItems()) }
  69. { renderSharingButton(item) }
  70. </div>)
  71. ] );
  72. });
  73. }
  74. fetchItems() {
  75. const { arvHost, arvToken } = this.props.appState;
  76. const { requestStates, reqStateMask } = this.state;
  77. const { activePage, itemsPerPage, ownerUuid,
  78. requestingContainerUuid, waitForNextProps,
  79. textSearch } = this.props;
  80. if (waitForNextProps)
  81. return;
  82. const filters = [
  83. [ 'requesting_container_uuid', '=', requestingContainerUuid ]
  84. ];
  85. if (!reqStateMask.reduce((a, b) => a & b))
  86. filters.push([ 'state', 'in', requestStates.filter((_, idx) => reqStateMask[idx]) ]);
  87. if (ownerUuid)
  88. filters.push([ 'owner_uuid', '=', ownerUuid ]);
  89. if (textSearch)
  90. filters.push([ 'any', 'ilike', '%' + textSearch + '%' ])
  91. let prom = makeArvadosRequest(arvHost, arvToken,
  92. '/arvados/v1/container_requests?filters=' + encodeURIComponent(JSON.stringify(filters)) +
  93. '&limit=' + itemsPerPage +
  94. '&offset=' + (itemsPerPage * activePage));
  95. prom = prom.then(xhr =>
  96. this.setState({
  97. 'numPages': Math.ceil(xhr.response['items_available'] / xhr.response['limit']),
  98. 'rows': this.prepareRows(xhr.response.items)
  99. }));
  100. }
  101. componentWillReceiveProps(nextProps, nextState) {
  102. this.props = nextProps;
  103. this.setState({ 'rows': maskRows(this.state.rows) });
  104. this.fetchItems();
  105. }
  106. render({ appState, ownerUuid, activePage, onPageChanged, getPageUrl },
  107. { rows, numPages, requestStates, containerStates,
  108. reqStateMask, contStateMask }) {
  109. return (
  110. <div>
  111. <WBCheckboxes items={ requestStates } checked={ reqStateMask }
  112. cssClass="float-left mx-2 my-2" title="Request State: "
  113. onChange={ () => this.fetchItems() } />
  114. <WBTable columns={ [ '', 'Name', 'Status', 'Owner', 'Created At', 'Output', 'Actions' ] }
  115. headerClasses={ [ 'w-1' ] }
  116. rows={ rows } />
  117. <WBPagination numPages={ numPages }
  118. activePage={ activePage }
  119. getPageUrl={ getPageUrl }
  120. onPageChanged={ onPageChanged } />
  121. </div>
  122. );
  123. }
  124. }
  125. WBProcessListing.defaultProps = {
  126. itemsPerPage: 100,
  127. ownerUuid: null,
  128. requestingContainerUuid: null,
  129. renderRenameLink: () => null,
  130. renderDeleteButton: () => null,
  131. renderSelectionCell: () => null,
  132. renderSharingButton: () => null,
  133. renderEditDescription: () => null
  134. };
  135. export default WBProcessListing;