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.

119 lines
3.6KB

  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, createRef } from 'preact';
  8. import WBDialog from 'wb-dialog';
  9. import WBTable from 'wb-table';
  10. import WBPagination from 'wb-pagination';
  11. import makeArvadosRequest from 'make-arvados-request';
  12. import arvadosObjectName from 'arvados-object-name';
  13. class WBPickObjectDialog extends Component {
  14. constructor(...args) {
  15. super(...args);
  16. this.state.title = 'WBPickObjectDialog';
  17. this.state.rows = [];
  18. this.state.textSearch = null;
  19. this.dialogRef = createRef();
  20. }
  21. show(title, objectType, accept, filters=[]) {
  22. this.setState({ title, objectType, page: 0, rows: [], accept, filters, textSearch: null });
  23. this.dialogRef.current.show();
  24. this.fetchData();
  25. }
  26. hide() {
  27. this.dialogRef.current.hide();
  28. }
  29. fetchData() {
  30. const { app, itemsPerPage } = this.props;
  31. const { arvHost, arvToken } = app.state;
  32. const { objectType, page, textSearch } = this.state;
  33. let { filters } = this.state;
  34. if (textSearch)
  35. filters = filters.concat([['any', 'ilike', '%' + textSearch + '%']]);
  36. const order = (objectType === 'user') ?
  37. ['last_name asc', 'first_name asc'] :
  38. ['name asc'];
  39. let prom = makeArvadosRequest(arvHost, arvToken,
  40. '/arvados/v1/' + objectType +
  41. 's?offset=' + (page * itemsPerPage) +
  42. '&limit=' + itemsPerPage +
  43. '&filters=' + encodeURIComponent(JSON.stringify(filters)) +
  44. '&order=' + encodeURIComponent(JSON.stringify(order))
  45. );
  46. prom = prom.then(xhr => this.setState({
  47. numPages: Math.ceil(xhr.response.items_available / itemsPerPage),
  48. rows: this.prepareRows(xhr.response.items)
  49. }));
  50. return prom;
  51. }
  52. prepareRows(items) {
  53. const { accept } = this.state;
  54. const { dialogRef } = this;
  55. return items.map(it => [
  56. (<div>
  57. <div>
  58. <a href="#" onclick={ () => { dialogRef.current.hide(); accept(it); } }>
  59. { arvadosObjectName(it) }
  60. </a>
  61. </div>
  62. <div>{ it.uuid }</div>
  63. </div>)
  64. ]);
  65. }
  66. search(textSearch) {
  67. this.setState({ textSearch, page: 0});
  68. this.fetchData();
  69. }
  70. render({}, { title, rows, page, numPages, textSearch }) {
  71. return (
  72. <WBDialog title={ title } ref={ this.dialogRef }>
  73. <div>
  74. <div class="input-group mb-3">
  75. <input type="text" class="form-control" placeholder="Search"
  76. aria-label="Search" value={ textSearch }
  77. onkeydown={ e => { if (e.keyCode === 13) {
  78. e.preventDefault();
  79. this.search(e.target.value);
  80. } } }
  81. onchange={ e => this.search(e.target.value) } />
  82. <div class="input-group-append">
  83. <button class="btn btn-outline-primary" type="button" onclick={ e => e.preventDefault() }>Search</button>
  84. </div>
  85. </div>
  86. <WBTable columns={ [ 'Name' ] } rows={ rows } />
  87. <WBPagination activePage={ page } numPages={ numPages } chunkSize={ 3 }
  88. onPageChanged={ i => { this.setState({ page: i }); this.fetchData(); } } />
  89. </div>
  90. <div>
  91. <button class="btn btn-secondary"
  92. onclick={ e => { e.preventDefault(); this.hide(); } }>
  93. Cancel
  94. </button>
  95. </div>
  96. </WBDialog>
  97. );
  98. }
  99. }
  100. WBPickObjectDialog.defaultProps = {
  101. itemsPerPage: 20
  102. };
  103. export default WBPickObjectDialog;