cx 22.1.0 → 22.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ui.js CHANGED
@@ -4721,21 +4721,26 @@ var History = /*#__PURE__*/ (function() {
4721
4721
  permanentNavigateConfirmation = permanent;
4722
4722
  };
4723
4723
 
4724
- History.confirmAndNavigate = function confirmAndNavigate(state, title, url, replace) {
4725
- var _this2 = this;
4726
-
4727
- if (!navigateConfirmationCallback) return this.navigate(state, title, url, replace);
4728
- var result = navigateConfirmationCallback(url);
4724
+ History.confirm = function confirm(continueCallback, state) {
4725
+ if (!navigateConfirmationCallback) return continueCallback();
4726
+ var result = navigateConfirmationCallback(state);
4729
4727
  Promise.resolve(result).then(function(value) {
4730
4728
  if (value) {
4731
4729
  if (!permanentNavigateConfirmation) navigateConfirmationCallback = null;
4732
-
4733
- _this2.navigate(state, title, url, replace);
4730
+ continueCallback();
4734
4731
  }
4735
4732
  });
4736
4733
  return false;
4737
4734
  };
4738
4735
 
4736
+ History.confirmAndNavigate = function confirmAndNavigate(state, title, url, replace) {
4737
+ var _this2 = this;
4738
+
4739
+ return this.confirm(function() {
4740
+ return _this2.navigate(state, title, url, replace);
4741
+ }, url);
4742
+ };
4743
+
4739
4744
  History.navigate = function navigate(state, title, url, replace) {
4740
4745
  var _this3 = this;
4741
4746
 
package/dist/widgets.css CHANGED
@@ -4124,6 +4124,14 @@ th.cxe-calendar-display {
4124
4124
  width: 5px;
4125
4125
  cursor: col-resize; }
4126
4126
 
4127
+ .cxe-grid-col-resizer-prev-col {
4128
+ position: absolute;
4129
+ left: 0;
4130
+ top: 0;
4131
+ bottom: 0;
4132
+ width: 5px;
4133
+ cursor: col-resize; }
4134
+
4127
4135
  .cxe-grid-resize-overlay {
4128
4136
  position: absolute;
4129
4137
  display: block;
package/dist/widgets.js CHANGED
@@ -5874,7 +5874,10 @@ var Tab = /*#__PURE__*/ (function(_HtmlElement) {
5874
5874
  };
5875
5875
 
5876
5876
  _proto.handleClick = function handleClick(e, instance) {
5877
- if (this.onClick) instance.invoke("onClick", e, instance);
5877
+ if (this.onClick && instance.invoke("onClick", e, instance) === false) {
5878
+ return;
5879
+ }
5880
+
5878
5881
  e.preventDefault();
5879
5882
  e.stopPropagation();
5880
5883
  var data = instance.data;
@@ -17863,6 +17866,108 @@ var Grid = /*#__PURE__*/ (function(_Widget) {
17863
17866
  );
17864
17867
  };
17865
17868
 
17869
+ _proto.renderResizer = function renderResizer(instance, hdinst, header, colIndex, forPreviousColumn) {
17870
+ var widget = instance.widget;
17871
+ var CSS = widget.CSS,
17872
+ baseClass = widget.baseClass;
17873
+ var hdwidget = hdinst.widget;
17874
+ var resizerClassName = "col-resizer";
17875
+ if (forPreviousColumn) resizerClassName += "-prev-col";
17876
+ return /*#__PURE__*/ jsx("div", {
17877
+ className: CSS.element(baseClass, resizerClassName),
17878
+ onClick: function onClick(e) {
17879
+ e.stopPropagation();
17880
+ },
17881
+ onMouseDown: function onMouseDown(e) {
17882
+ if (e.buttons != 1) return;
17883
+ var resizeOverlayEl = document.createElement("div");
17884
+ var headerCell = e.target.parentElement;
17885
+ if (forPreviousColumn) headerCell = headerCell.previousSibling;
17886
+ var scrollAreaEl = headerCell.parentElement.parentElement.parentElement.parentElement;
17887
+ var gridEl = scrollAreaEl.parentElement;
17888
+ var initialWidth = headerCell.offsetWidth;
17889
+ var initialPosition = getCursorPos(e);
17890
+ resizeOverlayEl.className = CSS.element(baseClass, "resize-overlay");
17891
+ resizeOverlayEl.style.width = initialWidth + "px";
17892
+ resizeOverlayEl.style.left =
17893
+ headerCell.getBoundingClientRect().left - gridEl.getBoundingClientRect().left + "px";
17894
+ gridEl.appendChild(resizeOverlayEl);
17895
+ captureMouse2(e, {
17896
+ onMouseMove: function onMouseMove(e) {
17897
+ var cursor = getCursorPos(e);
17898
+ var width = Math.max(30, Math.round(initialWidth + cursor.clientX - initialPosition.clientX));
17899
+ resizeOverlayEl.style.width = width + "px";
17900
+ },
17901
+ onMouseUp: function onMouseUp(e) {
17902
+ var _objectSpread2$1;
17903
+
17904
+ if (!resizeOverlayEl) return; //dblclick
17905
+
17906
+ var width = resizeOverlayEl.offsetWidth;
17907
+ hdinst.assignedWidth = width;
17908
+ gridEl.removeChild(resizeOverlayEl);
17909
+ resizeOverlayEl = null;
17910
+ if (widget.onColumnResize)
17911
+ instance.invoke(
17912
+ "onColumnResize",
17913
+ {
17914
+ width: width,
17915
+ column: hdwidget
17916
+ },
17917
+ hdinst
17918
+ );
17919
+ header.set("width", width);
17920
+ instance.setState({
17921
+ dimensionsVersion: instance.state.dimensionsVersion + 1,
17922
+ colWidth: _objectSpread2(
17923
+ _objectSpread2({}, instance.state.colWidth),
17924
+ {},
17925
+ ((_objectSpread2$1 = {}), (_objectSpread2$1[hdwidget.uniqueColumnId] = width), _objectSpread2$1)
17926
+ )
17927
+ });
17928
+ },
17929
+ onDblClick: function onDblClick() {
17930
+ var _objectSpread3;
17931
+
17932
+ var table = gridEl.querySelector("table");
17933
+ var parentEl = table.parentElement;
17934
+ var tableClone = table.cloneNode(true);
17935
+ tableClone.childNodes.forEach(function(tbody) {
17936
+ tbody.childNodes.forEach(function(tr) {
17937
+ tr.childNodes.forEach(function(td, index) {
17938
+ if (index == colIndex) {
17939
+ td.style.maxWidth = null;
17940
+ td.style.minWidth = null;
17941
+ td.style.width = "auto";
17942
+ } else {
17943
+ td.style.display = "none";
17944
+ }
17945
+ });
17946
+ });
17947
+ });
17948
+ tableClone.style.position = "absolute";
17949
+ tableClone.style.visibility = "hidden";
17950
+ tableClone.style.top = 0;
17951
+ tableClone.style.left = 0;
17952
+ tableClone.style.width = "auto";
17953
+ parentEl.appendChild(tableClone);
17954
+ var width = tableClone.offsetWidth;
17955
+ parentEl.removeChild(tableClone);
17956
+ header.set("width", width);
17957
+ instance.setState({
17958
+ dimensionsVersion: instance.state.dimensionsVersion + 1,
17959
+ colWidth: _objectSpread2(
17960
+ _objectSpread2({}, instance.state.colWidth),
17961
+ {},
17962
+ ((_objectSpread3 = {}), (_objectSpread3[hdwidget.uniqueColumnId] = width), _objectSpread3)
17963
+ )
17964
+ });
17965
+ }
17966
+ });
17967
+ }
17968
+ });
17969
+ };
17970
+
17866
17971
  _proto.renderHeader = function renderHeader(context, instance, key, fixed, fixedColumns) {
17867
17972
  var _this3 = this;
17868
17973
 
@@ -17893,7 +17998,8 @@ var Grid = /*#__PURE__*/ (function(_Widget) {
17893
17998
  content = void 0,
17894
17999
  sortIcon = void 0,
17895
18000
  tool = void 0;
17896
- var resizer = null;
18001
+ var resizer = null,
18002
+ prevColumnResizer = null;
17897
18003
 
17898
18004
  if (header) {
17899
18005
  empty[l] = false;
@@ -17956,100 +18062,13 @@ var Grid = /*#__PURE__*/ (function(_Widget) {
17956
18062
  }
17957
18063
 
17958
18064
  if ((hdwidget.resizable || header.data.resizable) && header.data.colSpan < 2) {
17959
- resizer = /*#__PURE__*/ jsx("div", {
17960
- className: CSS.element(baseClass, "col-resizer"),
17961
- onClick: function onClick(e) {
17962
- e.stopPropagation();
17963
- },
17964
- onMouseDown: function onMouseDown(e) {
17965
- if (e.buttons != 1) return;
17966
- var resizeOverlayEl = document.createElement("div");
17967
- var headerCell = e.target.parentElement;
17968
- var scrollAreaEl = headerCell.parentElement.parentElement.parentElement.parentElement;
17969
- var gridEl = scrollAreaEl.parentElement;
17970
- var initialWidth = headerCell.offsetWidth;
17971
- var initialPosition = getCursorPos(e);
17972
- resizeOverlayEl.className = CSS.element(baseClass, "resize-overlay");
17973
- resizeOverlayEl.style.width = initialWidth + "px";
17974
- resizeOverlayEl.style.left =
17975
- headerCell.getBoundingClientRect().left - gridEl.getBoundingClientRect().left + "px";
17976
- gridEl.appendChild(resizeOverlayEl);
17977
- captureMouse2(e, {
17978
- onMouseMove: function onMouseMove(e) {
17979
- var cursor = getCursorPos(e);
17980
- var width = Math.max(30, Math.round(initialWidth + cursor.clientX - initialPosition.clientX));
17981
- resizeOverlayEl.style.width = width + "px";
17982
- },
17983
- onMouseUp: function onMouseUp(e) {
17984
- var _objectSpread2$1;
17985
-
17986
- if (!resizeOverlayEl) return; //dblclick
17987
-
17988
- var width = resizeOverlayEl.offsetWidth;
17989
- hdinst.assignedWidth = width;
17990
- gridEl.removeChild(resizeOverlayEl);
17991
- resizeOverlayEl = null;
17992
- if (widget.onColumnResize)
17993
- instance.invoke(
17994
- "onColumnResize",
17995
- {
17996
- width: width,
17997
- column: hdwidget
17998
- },
17999
- hdinst
18000
- );
18001
- header.set("width", width);
18002
- instance.setState({
18003
- dimensionsVersion: instance.state.dimensionsVersion + 1,
18004
- colWidth: _objectSpread2(
18005
- _objectSpread2({}, instance.state.colWidth),
18006
- {},
18007
- ((_objectSpread2$1 = {}),
18008
- (_objectSpread2$1[hdwidget.uniqueColumnId] = width),
18009
- _objectSpread2$1)
18010
- )
18011
- });
18012
- },
18013
- onDblClick: function onDblClick() {
18014
- var _objectSpread3;
18015
-
18016
- var table = gridEl.querySelector("table");
18017
- var parentEl = table.parentElement;
18018
- var tableClone = table.cloneNode(true);
18019
- tableClone.childNodes.forEach(function(tbody) {
18020
- tbody.childNodes.forEach(function(tr) {
18021
- tr.childNodes.forEach(function(td, index) {
18022
- if (index == colIndex) {
18023
- td.style.maxWidth = null;
18024
- td.style.minWidth = null;
18025
- td.style.width = "auto";
18026
- } else {
18027
- td.style.display = "none";
18028
- }
18029
- });
18030
- });
18031
- });
18032
- tableClone.style.position = "absolute";
18033
- tableClone.style.visibility = "hidden";
18034
- tableClone.style.top = 0;
18035
- tableClone.style.left = 0;
18036
- tableClone.style.width = "auto";
18037
- parentEl.appendChild(tableClone);
18038
- var width = tableClone.offsetWidth;
18039
- parentEl.removeChild(tableClone);
18040
- header.set("width", width);
18041
- instance.setState({
18042
- dimensionsVersion: instance.state.dimensionsVersion + 1,
18043
- colWidth: _objectSpread2(
18044
- _objectSpread2({}, instance.state.colWidth),
18045
- {},
18046
- ((_objectSpread3 = {}), (_objectSpread3[hdwidget.uniqueColumnId] = width), _objectSpread3)
18047
- )
18048
- });
18049
- }
18050
- });
18051
- }
18052
- });
18065
+ resizer = _this3.renderResizer(instance, hdinst, header, colIndex);
18066
+
18067
+ if (colIndex > 0) {
18068
+ var hdinstPrev = line.children[colIndex - 1];
18069
+ var headerPrev = hdinstPrev.components["header" + (l + 1)];
18070
+ prevColumnResizer = _this3.renderResizer(instance, hdinstPrev, headerPrev, colIndex, true);
18071
+ }
18053
18072
  }
18054
18073
  }
18055
18074
 
@@ -18076,7 +18095,7 @@ var Grid = /*#__PURE__*/ (function(_Widget) {
18076
18095
  },
18077
18096
  onContextMenu: onContextMenu,
18078
18097
  "data-unique-col-id": hdwidget.uniqueColumnId,
18079
- children: [getContent(content), sortIcon, tool, resizer]
18098
+ children: [getContent(content), sortIcon, tool, prevColumnResizer, resizer]
18080
18099
  },
18081
18100
  colIndex
18082
18101
  )
@@ -20116,16 +20135,33 @@ var GridComponent = /*#__PURE__*/ (function(_VDOM$Component) {
20116
20135
  }
20117
20136
  }
20118
20137
 
20119
- if (futureState.cellEdit && !wasCellEditing)
20120
- _this11.cellEditUndoData = _this11.getRecordAt(futureState.cursor).data;
20138
+ if (futureState.cellEdit && !wasCellEditing) {
20139
+ var _record = _this11.getRecordAt(futureState.cursor);
20140
+
20141
+ var cellEditUndoData = _record.data;
20142
+ if (
20143
+ widget.onBeforeCellEdit &&
20144
+ _this11.props.instance.invoke(
20145
+ "onBeforeCellEdit",
20146
+ {
20147
+ column: visibleColumns[futureState.cursorCellIndex],
20148
+ data: cellEditUndoData,
20149
+ field: visibleColumns[futureState.cursorCellIndex].field
20150
+ },
20151
+ _record
20152
+ ) === false
20153
+ )
20154
+ return;
20155
+ _this11.cellEditUndoData = cellEditUndoData;
20156
+ }
20121
20157
 
20122
20158
  _this11.setState(newState, function() {
20123
20159
  if (_this11.state.focused && !_this11.state.cellEdit && wasCellEditing) FocusManager.focus(_this11.dom.el);
20124
20160
 
20125
20161
  if (scrollIntoView) {
20126
- var _record = _this11.getRecordAt(index);
20162
+ var _record2 = _this11.getRecordAt(index);
20127
20163
 
20128
- var item = _record && _this11.dom.table.querySelector('tbody[data-record-key="' + _record.key + '"]');
20164
+ var item = _record2 && _this11.dom.table.querySelector('tbody[data-record-key="' + _record2.key + '"]');
20129
20165
 
20130
20166
  var hscroll = false;
20131
20167
 
@@ -20136,7 +20172,7 @@ var GridComponent = /*#__PURE__*/ (function(_VDOM$Component) {
20136
20172
  item =
20137
20173
  item.firstChild.children[_this11.state.cursorCellIndex - _this11.props.instance.fixedColumnCount];
20138
20174
  } else {
20139
- var fixedItem = _this11.dom.fixedTable.querySelector('tbody[data-record-key="' + _record.key + '"]');
20175
+ var fixedItem = _this11.dom.fixedTable.querySelector('tbody[data-record-key="' + _record2.key + '"]');
20140
20176
 
20141
20177
  var cell = fixedItem && fixedItem.firstChild.children[_this11.state.cursorCellIndex];
20142
20178
  if (cell) scrollElementIntoView(cell, false, true, 10);
@@ -20347,10 +20383,10 @@ var GridComponent = /*#__PURE__*/ (function(_VDOM$Component) {
20347
20383
 
20348
20384
  case KeyCode.down:
20349
20385
  for (var _cursor = this.state.cursor + 1; ; _cursor++) {
20350
- var _record2 = this.getRecordAt(_cursor);
20386
+ var _record3 = this.getRecordAt(_cursor);
20351
20387
 
20352
- if (!_record2) break;
20353
- if (_record2.type != "data") continue;
20388
+ if (!_record3) break;
20389
+ if (_record3.type != "data") continue;
20354
20390
  this.moveCursor(_cursor, {
20355
20391
  focused: true,
20356
20392
  scrollIntoView: true,
@@ -20366,10 +20402,10 @@ var GridComponent = /*#__PURE__*/ (function(_VDOM$Component) {
20366
20402
 
20367
20403
  case KeyCode.up:
20368
20404
  for (var _cursor2 = this.state.cursor - 1; _cursor2 >= 0; _cursor2--) {
20369
- var _record3 = this.getRecordAt(_cursor2);
20405
+ var _record4 = this.getRecordAt(_cursor2);
20370
20406
 
20371
- if (!_record3) break;
20372
- if (_record3.type != "data") continue;
20407
+ if (!_record4) break;
20408
+ if (_record4.type != "data") continue;
20373
20409
  this.moveCursor(_cursor2, {
20374
20410
  focused: true,
20375
20411
  scrollIntoView: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cx",
3
- "version": "22.1.0",
3
+ "version": "22.1.3",
4
4
  "description": "Advanced JavaScript UI framework for admin and dashboard applications with ready to use grid, form and chart components.",
5
5
  "main": "index.js",
6
6
  "jsnext:main": "src/index.js",
@@ -1,10 +1,26 @@
1
1
  import * as Cx from "../core";
2
2
  import { BoundedObjectProps } from "../svg/BoundedObject";
3
3
 
4
-
5
4
  interface PieLabelProps extends BoundedObjectProps {
5
+ /** Distance in pixels, for which the labels will be separated from the pie chart. Default value is 100px. */
6
+ distance: Cx.NumberProp;
7
+
8
+ /**
9
+ * Index of the color in the default color palette.
10
+ */
11
+ lineColorIndex?: Cx.NumberProp;
12
+
13
+ /** A color used to paint the guideline. */
14
+ lineStroke?: Cx.StringProp;
6
15
 
7
- /** Distance in pixels, for which the labels will be separated from the pie chart. Default value is 100px. */
8
- distance: Cx.NumberProp
16
+ /** CSS class applied to the line element. */
17
+ lineClass?: Cx.StringProp;
18
+
19
+ /** CSS style applied to the line element. */
20
+ lineStyle?: Cx.StringProp;
21
+
22
+ /** Base CSS class to be applied to the element. Defaults to `pielabel`. */
23
+ baseClass?: string;
9
24
  }
10
- export class PieLabel extends Cx.Widget<PieLabelProps> {};
25
+
26
+ export class PieLabel extends Cx.Widget<PieLabelProps> {}
@@ -1,11 +1,21 @@
1
1
  import { VDOM } from "../ui/Widget";
2
2
  import { BoundedObject } from "../svg/BoundedObject";
3
3
  import { Rect } from "../svg/util/Rect";
4
+ import { parseStyle } from "../util/parseStyle";
4
5
 
5
6
  export class PieLabel extends BoundedObject {
7
+ init() {
8
+ this.lineStyle = parseStyle(this.lineStyle);
9
+ super.init();
10
+ }
11
+
6
12
  declareData(...args) {
7
13
  super.declareData(...args, {
8
14
  distance: undefined,
15
+ lineStyle: { structured: true },
16
+ lineStroke: undefined,
17
+ lineClass: { structured: true },
18
+ lineColorIndex: undefined,
9
19
  });
10
20
  }
11
21
 
@@ -25,16 +35,22 @@ export class PieLabel extends BoundedObject {
25
35
  }
26
36
 
27
37
  render(context, instance, key) {
28
- let { originalBounds, actualBounds } = instance;
38
+ let { originalBounds, actualBounds, data } = instance;
29
39
 
30
40
  return (
31
- <g key={key}>
41
+ <g key={key} className={data.classNames}>
32
42
  <line
43
+ className={this.CSS.element(
44
+ this.baseClass,
45
+ "line",
46
+ data.lineColorIndex != null && "color-" + data.lineColorIndex
47
+ )}
33
48
  x1={actualBounds.l < originalBounds.l ? actualBounds.r : actualBounds.l}
34
49
  y1={(actualBounds.t + actualBounds.b) / 2}
35
50
  x2={(originalBounds.l + originalBounds.r) / 2}
36
51
  y2={(originalBounds.t + originalBounds.b) / 2}
37
- stroke="gray"
52
+ stroke={data.lineStroke}
53
+ style={data.lineStyle}
38
54
  />
39
55
  <g transform={`translate(${instance.actualBounds.l} ${instance.actualBounds.t})`}>
40
56
  {this.renderChildren(context, instance)}
@@ -45,3 +61,5 @@ export class PieLabel extends BoundedObject {
45
61
  }
46
62
 
47
63
  PieLabel.prototype.distance = 100;
64
+ PieLabel.prototype.baseClass = "pielabel";
65
+ PieLabel.prototype.styled = true;
@@ -1,27 +1,29 @@
1
- import * as Cx from '../core';
1
+ import * as Cx from "../core";
2
2
 
3
3
  declare type FocusOutCallback = (Element) => void;
4
4
 
5
5
  export class FocusManager {
6
- static subscribe(callback: FocusOutCallback): void;
6
+ static subscribe(callback: FocusOutCallback): void;
7
7
 
8
- static onFocusOut(el : Element, callback: FocusOutCallback): () => void;
8
+ static onFocusOut(el: Element, callback: FocusOutCallback): () => void;
9
9
 
10
- static oneFocusOut(el: Element, callback: FocusOutCallback): () => void;
10
+ static oneFocusOut(el: Element, callback: FocusOutCallback): () => void;
11
11
 
12
- static nudge(): () => void;
12
+ static nudge(): () => void;
13
13
 
14
- static focus(el: Element): () => void;
14
+ static focus(el: Element): () => void;
15
15
 
16
- static focusFirst(el: Element): () => void;
16
+ static focusFirst(el: Element): () => void;
17
17
 
18
- static setInterval(interval: number) : void;
18
+ static setInterval(interval: number): void;
19
19
  }
20
20
 
21
21
  export function oneFocusOut(component: any, el: Element, callback: FocusOutCallback);
22
22
 
23
- export function offFocusOut(component: any) : void;
23
+ export function offFocusOut(component: any): void;
24
24
 
25
- export function preventFocus(e: Event) : void;
25
+ export function preventFocus(e: Event): void;
26
26
 
27
27
  export function preventFocusOnTouch(e: Event, force?: boolean): void;
28
+
29
+ export function unfocusElement(target?: Element, forceBlur?: boolean): void;
@@ -1,4 +1,4 @@
1
- import { View } from './../../data/View';
1
+ import { View } from "./../../data/View";
2
2
 
3
3
  export class History {
4
4
  static connect(store: View, urlBinding: string, hashBinding?: string);
@@ -11,5 +11,7 @@ export class History {
11
11
 
12
12
  static reloadOnNextChange();
13
13
 
14
- static addNavigateConfirmation(callback: ((url?: string) => boolean | Promise<boolean>), executeOnlyOnce?: boolean);
14
+ static addNavigateConfirmation(callback: (url?: string) => boolean | Promise<boolean>, executeOnlyOnce?: boolean);
15
+
16
+ static confirm(continueCallback: () => void, state: any);
15
17
  }
@@ -1,6 +1,6 @@
1
- import {Url} from './Url';
2
- import {batchUpdatesAndNotify} from '../batchUpdates';
3
- import {SubscriberList} from '../../util/SubscriberList';
1
+ import { Url } from "./Url";
2
+ import { batchUpdatesAndNotify } from "../batchUpdates";
3
+ import { SubscriberList } from "../../util/SubscriberList";
4
4
 
5
5
  let last = 0,
6
6
  next = 1,
@@ -10,16 +10,14 @@ let last = 0,
10
10
  navigateConfirmationCallback = null,
11
11
  permanentNavigateConfirmation = false;
12
12
 
13
-
14
13
  export class History {
15
-
16
14
  static connect(store, urlBinding, hashBinding) {
17
15
  this.store = store;
18
16
  this.urlBinding = urlBinding;
19
17
  this.hashBinding = hashBinding;
20
18
  this.updateStore();
21
19
  window.onpopstate = () => {
22
- this.updateStore()
20
+ this.updateStore();
23
21
  };
24
22
  }
25
23
 
@@ -40,24 +38,24 @@ export class History {
40
38
  permanentNavigateConfirmation = permanent;
41
39
  }
42
40
 
43
- static confirmAndNavigate(state, title, url, replace) {
44
- if (!navigateConfirmationCallback)
45
- return this.navigate(state, title, url, replace);
46
-
47
- let result = navigateConfirmationCallback(url);
48
-
49
- Promise
50
- .resolve(result)
51
- .then(value => {
52
- if (value) {
53
- if (!permanentNavigateConfirmation)
54
- navigateConfirmationCallback = null;
55
- this.navigate(state, title, url, replace);
56
- }
57
- });
41
+ static confirm(continueCallback, state) {
42
+ if (!navigateConfirmationCallback) return continueCallback();
43
+
44
+ let result = navigateConfirmationCallback(state);
45
+ Promise.resolve(result).then((value) => {
46
+ if (value) {
47
+ if (!permanentNavigateConfirmation) navigateConfirmationCallback = null;
48
+ continueCallback();
49
+ }
50
+ });
51
+
58
52
  return false;
59
53
  }
60
54
 
55
+ static confirmAndNavigate(state, title, url, replace) {
56
+ return this.confirm(() => this.navigate(state, title, url, replace), url);
57
+ }
58
+
61
59
  static navigate(state, title, url, replace = false) {
62
60
  url = Url.resolve(url);
63
61
 
@@ -66,50 +64,51 @@ export class History {
66
64
  return true;
67
65
  }
68
66
 
69
- let transition, changed = false;
70
- batchUpdatesAndNotify(() => {
71
- changed = this.updateStore(url);
72
- if (changed)
73
- transitions[++last] = transition = {
74
- url,
75
- state,
76
- title,
77
- replace
67
+ let transition,
68
+ changed = false;
69
+ batchUpdatesAndNotify(
70
+ () => {
71
+ changed = this.updateStore(url);
72
+ if (changed)
73
+ transitions[++last] = transition = {
74
+ url,
75
+ state,
76
+ title,
77
+ replace,
78
+ };
79
+ },
80
+ () => {
81
+ if (transition) transition.completed = true;
82
+
83
+ //update history once the page is rendered and the title is set
84
+ while (transitions[next] && transitions[next].completed) {
85
+ let tr = transitions[next];
86
+ delete transitions[next];
87
+ next++;
88
+ let op = tr.replace ? "replaceState" : "pushState";
89
+ window.history[op](tr.state, tr.title, tr.url);
90
+ if (subscribers) subscribers.notify(tr.url, op);
78
91
  }
79
- }, () => {
80
- if (transition)
81
- transition.completed = true;
82
-
83
- //update history once the page is rendered and the title is set
84
- while (transitions[next] && transitions[next].completed) {
85
- let tr = transitions[next];
86
- delete transitions[next];
87
- next++;
88
- let op = tr.replace ? "replaceState" : "pushState";
89
- window.history[op](tr.state, tr.title, tr.url);
90
- if (subscribers)
91
- subscribers.notify(tr.url, op);
92
92
  }
93
- });
93
+ );
94
94
 
95
95
  return changed;
96
96
  }
97
97
 
98
98
  static updateStore(href) {
99
- let url = Url.unresolve(href || document.location.href), hash = null;
100
- let hashIndex = url.indexOf('#');
99
+ let url = Url.unresolve(href || document.location.href),
100
+ hash = null;
101
+ let hashIndex = url.indexOf("#");
101
102
  if (hashIndex !== -1) {
102
103
  hash = url.substring(hashIndex);
103
104
  url = url.substring(0, hashIndex);
104
105
  }
105
- if (this.hashBinding)
106
- this.store.set(this.hashBinding, hash);
106
+ if (this.hashBinding) this.store.set(this.hashBinding, hash);
107
107
  return this.store.set(this.urlBinding, url);
108
108
  }
109
109
 
110
110
  static subscribe(callback) {
111
- if (!subscribers)
112
- subscribers = new SubscriberList();
113
- return subscribers.subscribe(callback)
111
+ if (!subscribers) subscribers = new SubscriberList();
112
+ return subscribers.subscribe(callback);
114
113
  }
115
114
  }
@@ -305,6 +305,9 @@ interface GridProps extends Cx.StyledContainerProps {
305
305
  /** Set to true to enable cell editing. Please note that all editable columns should specify the editor field. */
306
306
  cellEditable?: boolean;
307
307
 
308
+ /** A callback function which is executed before a cell editor is initalized. Return false from the callback to prevent the cell from going into the edit mode. */
309
+ onBeforeCellEdit?: (change, record) => any;
310
+
308
311
  /** A callback function which is executed after a cell has been successfully edited. */
309
312
  onCellEdited?: (change, record) => void;
310
313