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.

178 lines
6.6KB

  1. import { h, Component, createRef } from 'preact';
  2. import { route } from 'preact-router';
  3. import WBNavbarCommon from 'wb-navbar-common';
  4. import WBArvadosCrumbs from 'wb-arvados-crumbs';
  5. import WBBrowseDialog from 'wb-browse-dialog';
  6. import WBTable from 'wb-table';
  7. import makeArvadosRequest from 'make-arvados-request';
  8. import { wbDisableControls, wbEnableControls } from 'wb-disable-controls';
  9. import linkState from 'linkstate';
  10. import wbParseWorkflowDef from 'wb-parse-workflow-def';
  11. import { wbParseWorkflowInputs, wbSubmitContainerRequest } from 'wb-submit-container-request';
  12. import WBWorkflowInput from 'wb-workflow-input';
  13. class WBLaunchWorkflowPage extends Component {
  14. constructor(...args) {
  15. super(...args);
  16. this.browseDialogRef = createRef();
  17. this.state.inputs = {};
  18. this.state.errors = [];
  19. this.state.placeInSubProject = true;
  20. }
  21. componentDidMount() {
  22. let { app, workflowUuid } = this.props;
  23. let { arvHost, arvToken } = app.state;
  24. let prom = makeArvadosRequest(arvHost, arvToken,
  25. '/arvados/v1/workflows/' + workflowUuid);
  26. prom = prom.then(xhr => {
  27. const def = wbParseWorkflowDef(xhr.response.definition);
  28. const inputs = {};
  29. const main = def['$graph'].find(a => (a.id === '#main'));
  30. main.inputs.map(a => (inputs[a.id] = JSON.stringify(a.default)));
  31. this.setState({
  32. 'workflow': xhr.response,
  33. 'workflowDefinition': def,
  34. 'defaultProcessName': xhr.response.name + ' ' + (new Date().toISOString()),
  35. 'defaultProcessDescription': xhr.response.description,
  36. inputs
  37. });
  38. });
  39. }
  40. submit() {
  41. // first see if all inputs are parseable
  42. const { app, workflowUuid } = this.props;
  43. const { arvHost, arvToken, currentUser } = app.state;
  44. const { workflowDefinition, projectUuid,
  45. processName, processDescription,
  46. defaultProcessName, defaultProcessDescription,
  47. placeInSubProject } = this.state;
  48. const errors = [];
  49. const inputs = wbParseWorkflowInputs(workflowDefinition,
  50. this.state.inputs, errors);
  51. if (errors.length > 0) {
  52. this.setState({ errors });
  53. return;
  54. }
  55. const params = {
  56. arvHost, arvToken, inputs,
  57. processName: processName || defaultProcessName,
  58. processDescription: processDescription || defaultProcessDescription,
  59. projectUuid: projectUuid || currentUser.uuid,
  60. workflowUuid, workflowDefinition, placeInSubProject
  61. }
  62. wbDisableControls();
  63. let prom = wbSubmitContainerRequest(params);
  64. prom = prom.then(xhr => {
  65. wbEnableControls();
  66. route('/process/' + xhr.response.uuid);
  67. });
  68. prom = prom.catch(exc => {
  69. wbEnableControls();
  70. this.setState({ errors: [ exc.message ] });
  71. });
  72. }
  73. render({ app, workflowUuid },
  74. { workflow, workflowDefinition, projectUuid, processName, processDescription,
  75. defaultProcessName, defaultProcessDescription, errors, placeInSubProject }) {
  76. return (
  77. <div>
  78. <WBNavbarCommon app={ app } />
  79. <WBBrowseDialog app={ app } ref={ this.browseDialogRef } />
  80. { workflow ?
  81. (<form class="container-fluid">
  82. <h1>Launch Workflow</h1>
  83. <div class="form-group">
  84. <label>Workflow</label>
  85. <WBArvadosCrumbs app={ app } uuid={ workflowUuid } />
  86. </div>
  87. <div class="form-group">
  88. <label for="projectUuid">Project UUID</label>
  89. <div class="input-group mb-3">
  90. <input type="text" class="form-control" id="projectUuid"
  91. placeholder="Enter Project UUID" aria-label="Project UUID"
  92. aria-describedby="button-addon2" value={ projectUuid }
  93. onChange={ linkState(this, 'projectUuid') } />
  94. <div class="input-group-append">
  95. <button class="btn btn-primary" type="button"
  96. id="button-addon2" onclick={ e => { e.preventDefault();
  97. this.browseDialogRef.current.show('owner', false,
  98. projectUuid => this.setState({ projectUuid })); } }>Browse</button>
  99. </div>
  100. </div>
  101. { projectUuid ? (
  102. <WBArvadosCrumbs app={ app } uuid={ projectUuid } />
  103. ) : null }
  104. </div>
  105. <div class="form-check mb-3">
  106. <input class="form-check-input" type="checkbox"
  107. checked={ placeInSubProject ? 'checked' : null }
  108. onchange={ e => (this.state.placeInSubProject = e.target.checked) }
  109. id="placeInSubProject" />
  110. <label class="form-check-label" for="placeInSubProject">
  111. Place in a daily sub-project
  112. </label>
  113. </div>
  114. <div class="form-group">
  115. <label for="processName">Process Name</label>
  116. <input type="text" class="form-control" id="processName"
  117. placeholder={ defaultProcessName } value={ processName }
  118. onChange={ linkState(this, 'processName') }/>
  119. </div>
  120. <div class="form-group">
  121. <label for="processDescription">Process Description</label>
  122. <input type="text" class="form-control" id="processDescription"
  123. placeholder={ defaultProcessDescription } value={ processDescription }
  124. onChange={ linkState(this, 'processDescription') } />
  125. </div>
  126. <div class="form-group">
  127. <label for="inputs">Inputs</label>
  128. <WBTable columns={ [ 'Name', 'Value'] }
  129. rows={ workflowDefinition.$graph.find(a => (a.id === '#main')).inputs.map(it => [
  130. it.label || it.id,
  131. ( <WBWorkflowInput app={ app } inputSpec={ it }
  132. inputsDict={ this.state.inputs }
  133. browseDialogRef={ this.browseDialogRef } /> )
  134. ]) } />
  135. </div>
  136. { errors.length > 0 ? (
  137. <div class="form-group">
  138. { errors.map(err => (
  139. <div class="alert alert-danger" role="alert">
  140. { err }
  141. </div>
  142. ))}
  143. </div>
  144. ) : null }
  145. <div class="form-group">
  146. <button class="btn btn-success" onclick={ e => { e.preventDefault(); this.submit(); } }>
  147. Submit
  148. </button>
  149. </div>
  150. </form>) : <div>Loading...</div> }
  151. </div>
  152. );
  153. }
  154. }
  155. export default WBLaunchWorkflowPage;