WindykacjaUpdateStatus.php.view.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. var DBG = DBG || 0;
  2. var DBG1 = true;
  3. var EXECUTE_NEXT_ACTION_LIMIT = 1000;
  4. var EXECUTE_NEXT_ACTION_INTERVAL = 100;
  5. if (!HTML_ID) throw "Missing HTML_ID";
  6. if (!TOTAL) throw "Missing TOTAL";
  7. if (!EXECUTE_SINGLE_TASK_URL) throw "Missing EXECUTE_SINGLE_TASK_URL";
  8. if (!global.p5VendorJs) throw "Missing vendor.js";
  9. var createReactClass = global.p5VendorJs.createReactClass;
  10. var h = global.p5VendorJs.React.createElement;
  11. var ReactDOM = global.p5VendorJs.ReactDOM;
  12. // var AsyncTypeahead = window.p5VendorJs.AsyncTypeahead;
  13. // responseBody:
  14. // - percentDone
  15. // - totalToUpdate
  16. // - total
  17. // - totalDone
  18. var sendRequest = (function () { // uses: EXECUTE_SINGLE_TASK_URL
  19. var _versionSent = 1;
  20. var _versionReceived = 0;
  21. return function () {// return function (limit, page, sorted, filtered) {
  22. // var filterTableProps = {
  23. // limit: limit || REQUEST_DATA_LIMIT,
  24. // page: page || 0,
  25. // sorted: sorted || [],
  26. // filtered: filtered || [],
  27. // };
  28. _versionSent++;
  29. var this_version = _versionSent;
  30. return global.fetch(EXECUTE_SINGLE_TASK_URL, {
  31. header: { 'contentType': 'applications/json' },
  32. credentials: 'same-origin',
  33. method: 'GET',
  34. // body: JSON.stringify(filterTableProps), // POST
  35. }).then(function (result) {
  36. if (this_version < _versionReceived) throw "Skipped response: already received newer version.";
  37. return result.json()
  38. }).then(function (data) {
  39. DBG && console.log("DBG:EXECUTE_SINGLE_TASK_URL:Data", { data })
  40. _versionReceived = this_version;
  41. // DBG && console.log("DBG:sendRequest:afterReceived", { _versionSent, _versionReceived, _lastPropsJson, this_version, this_lastPropsJson });
  42. return data.body; // body: { rows: [], total: int }
  43. })
  44. }
  45. })();
  46. var P5UI__WindykacjaStatusUpdate = createReactClass({
  47. getInitialState: function () {
  48. return {
  49. errorMsg: '',
  50. loading: false,
  51. version: 0,
  52. responseBody: null,
  53. execLimit: EXECUTE_NEXT_ACTION_LIMIT,
  54. execCounter: 0,
  55. execAgain: true,
  56. }
  57. },
  58. componentDidMount: function () {
  59. this.runUpdateStatus();
  60. },
  61. runAgainIfNotDone: function () {
  62. if (!this.state.execAgain) return;
  63. if (this.state.responseBody && 100 === this.state.responseBody.percentDone && 0 === this.state.responseBody.totalToUpdate) {
  64. return;
  65. }
  66. if (this.state.execCounter > this.state.execLimit) {
  67. this.setState({
  68. errorMsg: "Osiągnięto limit wywołań funkcji",
  69. })
  70. return;
  71. }
  72. var _runUpdateStatus = this.runUpdateStatus.bind(this);
  73. setTimeout(_runUpdateStatus, EXECUTE_NEXT_ACTION_INTERVAL)
  74. },
  75. runUpdateStatus: function () {
  76. DBG && console.log('DBG:runUpdateStatus', {});
  77. this.setState({ loading: true });
  78. var _runAgainIfNotDone = this.runAgainIfNotDone.bind(this);
  79. var _setState = this.setState.bind(this);
  80. var _version = this.state.version + 1; // TODO: handle race condition
  81. sendRequest().then(responseBody => {
  82. _setState({
  83. responseBody: responseBody,
  84. version: _version,
  85. loading: false,
  86. execCounter: this.state.execCounter + 1,
  87. }, _runAgainIfNotDone);
  88. }).catch(function (e) {
  89. if ("Skipped request" === ('' + e).substr(0, "Skipped request".length)) {
  90. console.log("DBG:sendRequest:Skipped", e)
  91. _setState({
  92. loading: false,
  93. }, );
  94. return;
  95. }
  96. console.log("Error:sendRequest", e)
  97. _setState({
  98. loading: false,
  99. errorMsg: '' + e,
  100. });
  101. });
  102. },
  103. handleClickRestart: function (event) {
  104. event.preventDefault()
  105. location.reload()
  106. },
  107. handleClickPause: function (event) {
  108. event.preventDefault()
  109. this.setState({ execAgain: false })
  110. },
  111. handleClickPlay: function (event) {
  112. event.preventDefault()
  113. this.setState({ execAgain: true })
  114. this.runUpdateStatus();
  115. },
  116. render: function () {
  117. DBG && console.log('DBG:render', { state: this.state });
  118. var isDone = (this.state.responseBody && 100 === this.state.responseBody.percentDone && 0 === this.state.responseBody.totalToUpdate);
  119. var percent = (this.state.responseBody) ? Math.round(this.state.responseBody.percentDone, 2) : 0;
  120. var panelClass = (percent < 100) ? "warning" : "success";
  121. if (this.state.errorMsg) panelClass = "danger";
  122. var iconPause = h('i', { className: "glyphicon glyphicon-pause" });
  123. var iconPlay = h('i', { className: "glyphicon glyphicon-play" });
  124. return h('div', { p5_node_id: 'p5-windykacja-status-update-widget' }, [
  125. h('div', { className: "panel panel-" + panelClass }, [
  126. h('div', { className: "panel-heading" }, [
  127. ]),
  128. h('div', { className: "panel-body", style: { paddingBottom: "0" } }, [
  129. h('p', {}, [
  130. "Aktaulizacja statusu " + this.props.total + " rekordów ",
  131. " ",
  132. (!isDone)
  133. ? (
  134. (this.state.execAgain)
  135. ? h('button', { className: "btn btn-xs btn-default", onClick: this.handleClickPause }, [ iconPause, "Zatrzymaj" ])
  136. : h('button', { className: "btn btn-xs btn-default", onClick: this.handleClickPlay }, [ iconPlay, "Uruchom ponownie" ])
  137. )
  138. : '',
  139. ]),
  140. h('div', { className: "progress" }, [
  141. h('div', { className: "progress-bar",
  142. role: "progressbar",
  143. ariaValuenow: percent,
  144. ariaValuemin: "0", ariaValuemax: "100",
  145. style: { width: "" + percent + "%" },
  146. }, [
  147. "" + percent + "%"
  148. ]),
  149. ]),
  150. (this.state.responseBody)
  151. ? h('p', {}, "Wykonano " + this.state.responseBody.totalDone + " z " + this.state.responseBody.total)
  152. : '',
  153. (this.state.errorMsg) ? h('div', { className: "alert alert-danger" }, [
  154. this.state.errorMsg,
  155. " ",
  156. h('button', { className: "btn btn-primary", onClick: this.handleClickRestart }, "Uruchom ponownie")
  157. ]) : "",
  158. ]),
  159. ]),
  160. ]);
  161. }
  162. });
  163. ReactDOM.render(
  164. h(P5UI__WindykacjaStatusUpdate, {
  165. total: TOTAL,
  166. }),
  167. document.getElementById(HTML_ID)
  168. )