TableAjax.php.p5UI__TableAjaxSortableLabel.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. var DBG = DBG || false;
  2. var DBG1 = true;
  3. if (!global.p5VendorJs) throw "Missing p5 Vendor js libs";
  4. if (!global.p5VendorJs.Redux) throw "Missing p5 Vendor js lib: Redux";
  5. var createReactClass = global.p5VendorJs.createReactClass;
  6. var h = global.p5VendorJs.React.createElement;
  7. var ReactDOM = global.p5VendorJs.ReactDOM;
  8. var Redux = global.p5VendorJs.Redux;
  9. var ReduxThunk = global.p5VendorJs.ReduxThunk;
  10. var createStoreWithThunkMiddleware = Redux.applyMiddleware(ReduxThunk)(Redux.createStore); // TODO: to vendor.js
  11. var P5UI__TableAjaxSortableLabel = createReactClass({
  12. // props.store: Redux store { getState(), subscribe(f), dispatch(f) }
  13. // props.actions: store actions { toggleSort(fieldName) }
  14. // props.namespace: string
  15. // props.isSortable: bool
  16. // props.fieldName: string
  17. // props.fieldProps: legacy field props object { type, friendly, xsdRefType, description, ... }
  18. // props.maxLabelLines: max number of lines in cell found in all row by parent
  19. getStateFromStore: function () {
  20. var state = this.props.store.getState();
  21. return {
  22. currSortCol: state.currSortCol,
  23. currSortFlip: state.currSortFlip
  24. };
  25. },
  26. getInitialState: function () {
  27. return this.getStateFromStore();
  28. },
  29. componentDidMount: function () {
  30. DBG && console.log('DBG::P5UI__TableAjaxSortableLabel::componentDidMount (field:'+this.props.fieldName+')');
  31. this.unsubscribe = this.props.store.subscribe(this.storeUpdated)
  32. },
  33. componentWillUnmount: function () {
  34. this.unsubscribe()
  35. },
  36. storeUpdated: function () {
  37. DBG && console.log('DBG::P5UI__TableAjaxSortableLabel::storeUpdated (field:'+this.props.fieldName+')');
  38. this.setState(this.getStateFromStore())
  39. },
  40. shouldComponentUpdate: function (nextProps, nextState) {
  41. DBG && console.log('DBG::P5UI__TableAjaxSortableLabel::shouldComponentUpdate (field:'+this.props.fieldName+')', { state: this.state, nextState });
  42. if (this.props.fieldName !== this.state.currSortCol && this.props.fieldName !== nextState.currSortCol) return false;
  43. return (
  44. this.state.currSortCol !== nextState.currSortCol
  45. || this.state.currSortFlip !== nextState.currSortFlip
  46. );
  47. },
  48. handleChange: function (checked) { // handleChange: function (event) {
  49. DBG && console.log('DBG::P5UI__TableAjaxSortableLabel::handleChange (field:'+this.props.fieldName+')');
  50. if (!this.props.isSortable) return;
  51. this.props.store.dispatch( this.props.actions.toggleSort( this.props.fieldName ) )
  52. },
  53. convertLabelHtmlLinesToRect: function (htmlLines) {
  54. return htmlLines.split('<br>').reduce(function (reactNodesList, line) {
  55. return reactNodesList.length
  56. ? reactNodesList.concat( h('br'), line )
  57. : reactNodesList.concat( line )
  58. ;
  59. }, []);
  60. },
  61. render: function () {
  62. DBG && console.log('DBG::P5UI__TableAjaxSortableLabel::render (field:'+this.props.fieldName+')', { props: this.props, state: this.state });
  63. var isSorted = ( this.props.isSortable && this.props.fieldName === this.state.currSortCol );
  64. var sortFlip = this.state.currSortFlip;
  65. var sortClass = "glyphicon glyphicon-triangle-" + ( sortFlip ? "bottom" : "top" );
  66. var fieldProps = this.props.fieldProps;
  67. var label = [ this.props.fieldName ];
  68. if (fieldProps.friendly) {
  69. var htmlLabel = fieldProps.friendly;
  70. { // fix vertical-align=bottom, using `this.props.maxLabelLines`
  71. var lines = fieldProps.friendly.split('<br>').length;
  72. if (lines < this.props.maxLabelLines) htmlLabel = '<br>'.repeat(this.props.maxLabelLines - lines) + htmlLabel
  73. }
  74. label = this.convertLabelHtmlLinesToRect(htmlLabel);
  75. }
  76. var labelElements = ('ref' === fieldProps.type && fieldProps.xsdRefType)
  77. ? [
  78. h('i', { style: { 'padding-right': "2px" }, className: "glyphicon glyphicon-export" }),
  79. fieldProps.xsdRefType
  80. ]
  81. : label
  82. ;
  83. var title = this.props.fieldName;
  84. if (fieldProps.description && fieldProps.description.length > 0) {
  85. title = p5Utils__format("{0} ({1})", [ fieldProps.description, this.props.fieldName ])
  86. }
  87. else if (fieldProps._tsRetId > 0) {
  88. title = p5Utils__format("Kliknij na pole i przejdź do powiązanych rekordów ({0})", [ title ])
  89. }
  90. if ('ref' === fieldProps.type && fieldProps.xsdRefType) {
  91. if (fieldProps.description && fieldProps.description.length > 0 && fieldProps.description !== this.props.fieldName) {
  92. title = p5Utils__format("{0} (ref {1})", [ fieldProps.description, this.props.fieldName ])
  93. } else {
  94. title = p5Utils__format("(ref {0})", [ this.props.fieldName ])
  95. }
  96. }
  97. return h('span', {
  98. onClick: this.handleChange,
  99. title: title,
  100. className: "pull-left",
  101. style: Object.assign({
  102. }, this.props.isSortable ? { cursor: "pointer" } : {})
  103. }, labelElements.concat([
  104. (isSorted) ? h('span', {
  105. className: sortClass,
  106. style: {
  107. margin: "0 0 0 3px",
  108. color: "#bbb"
  109. }
  110. }) : null
  111. ]));
  112. }
  113. });
  114. global.p5VendorJs['P5UI__TableAjaxSortableLabel'] = P5UI__TableAjaxSortableLabel;