@singularsystems/neo-core 0.10.61 → 0.10.63

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.
@@ -4,7 +4,7 @@ import { ITooltipOptions } from "./TooltipOptions";
4
4
  export interface IButtonOptions {
5
5
  /** True if the click event of this button must be invoked when the parent form of this button is submitted. */
6
6
  isSubmit?: boolean;
7
- /** The id of the form this button should attached to. Use this if the button is not a descendent of the form. */
7
+ /** The id of the form this button should attach to. Use this if the button is not nested within the form. */
8
8
  form?: string;
9
9
  /** Bootstrap variant */
10
10
  variant?: variant;
@@ -27,10 +27,11 @@ export default class DatePicker {
27
27
  constructor(container: HTMLDivElement, options?: IPartialDateProps);
28
28
  inputFocused(e: FocusEvent): void;
29
29
  inputBlurred(): void;
30
+ onInputBlurred(closePopup: boolean): void;
30
31
  inputChanged(): void;
31
32
  inputKeyDown(e: KeyboardEvent): void;
32
33
  private removePopup;
33
- private setBindValueAndClose;
34
+ private setBindValue;
34
35
  private setBindProperty;
35
36
  private setInputValue;
36
37
  private show;
@@ -47,24 +47,27 @@ var DatePicker = /** @class */ (function () {
47
47
  }
48
48
  };
49
49
  DatePicker.prototype.inputBlurred = function () {
50
+ this.onInputBlurred(true);
51
+ };
52
+ DatePicker.prototype.onInputBlurred = function (closePopup) {
50
53
  if (this.inputHasChanged) {
51
54
  if (this.input.value) {
52
55
  // if this is time only, use the existing value to preserve the date.
53
56
  var refDate = this.options.timeOnly && this.bindProperty.value;
54
57
  var parsedDate = DateUtils.tryParse(this.input.value, this.options.formatString, false, refDate || new Date());
55
58
  if (parsedDate) {
56
- this.setBindValueAndClose(parsedDate, false);
59
+ this.setBindValue(parsedDate, { preserveTime: false, close: closePopup });
57
60
  }
58
61
  else {
59
- this.setBindValueAndClose(this.bindProperty.value, false);
62
+ this.setBindValue(this.bindProperty.value, { preserveTime: false, close: closePopup });
60
63
  }
61
64
  }
62
65
  else {
63
- this.setBindValueAndClose(null, true);
66
+ this.setBindValue(null, { preserveTime: true, close: closePopup });
64
67
  }
65
68
  }
66
69
  else {
67
- if (this.options.autoClose)
70
+ if (this.options.autoClose && closePopup)
68
71
  this.removePopup(true);
69
72
  }
70
73
  this.input.readOnly = this.isReadOnly;
@@ -78,6 +81,9 @@ var DatePicker = /** @class */ (function () {
78
81
  this.setCurrentViewDate(parsedDate);
79
82
  this.populateContentContainer(true);
80
83
  }
84
+ if (!this.popup) {
85
+ this.show();
86
+ }
81
87
  }
82
88
  };
83
89
  DatePicker.prototype.inputKeyDown = function (e) {
@@ -85,13 +91,22 @@ var DatePicker = /** @class */ (function () {
85
91
  if (e.key === "Escape") {
86
92
  // Revert to previous value
87
93
  e.preventDefault();
88
- this.setBindValueAndClose(this.bindProperty.value, false);
94
+ this.setBindValue(this.bindProperty.value, { preserveTime: false, close: false });
89
95
  }
90
96
  else if (e.key === "Enter") {
91
- // Set date to today if the current value is null
92
- e.preventDefault();
93
- if (!this.bindProperty.value) {
94
- this.setBindValueAndClose(new Date(), true);
97
+ var prevValue = this.input.value;
98
+ if (!this.bindProperty.value && !this.input.value) {
99
+ // Set date to today if the current value is null
100
+ this.setBindValue(new Date(), { preserveTime: true, close: false });
101
+ }
102
+ else {
103
+ this.onInputBlurred(false);
104
+ }
105
+ if (this.input.value !== prevValue) {
106
+ e.preventDefault();
107
+ }
108
+ else {
109
+ this.removePopup(true);
95
110
  }
96
111
  }
97
112
  };
@@ -109,17 +124,17 @@ var DatePicker = /** @class */ (function () {
109
124
  this.popup = null;
110
125
  }
111
126
  };
112
- DatePicker.prototype.setBindValueAndClose = function (dateValue, preserveTime) {
127
+ DatePicker.prototype.setBindValue = function (dateValue, options) {
113
128
  this.inputHasChanged = false;
114
129
  var oldValue = this.bindProperty.value;
115
- if (oldValue && dateValue && preserveTime) {
130
+ if (oldValue && dateValue && options.preserveTime) {
116
131
  // preserve the time component of the original date.
117
132
  dateValue.setHours(oldValue.getHours(), oldValue.getMinutes(), oldValue.getSeconds(), oldValue.getMilliseconds());
118
133
  }
119
134
  // Note: this may have the side effect of calling update().
120
135
  this.setBindProperty(dateValue, false);
121
136
  this.setInputValue();
122
- if (!this.options.alwaysShow) {
137
+ if (!this.options.alwaysShow && options.close) {
123
138
  this.removePopup(true);
124
139
  }
125
140
  };
@@ -156,7 +171,7 @@ var DatePicker = /** @class */ (function () {
156
171
  };
157
172
  DatePicker.prototype.positionPopup = function (fromBottom) {
158
173
  if (this.popup) {
159
- PositionHelper.checkScreenBounds(this.container, this.popup, fromBottom);
174
+ PositionHelper.checkScreenBounds(this.container, this.popup, fromBottom, this.options.popupAlignRight);
160
175
  }
161
176
  };
162
177
  /**
@@ -319,8 +334,7 @@ var DatePicker = /** @class */ (function () {
319
334
  var cell = this.createAndAppend(trBody, "td");
320
335
  var date = currentDate.getDate();
321
336
  var month = currentDate.getMonth();
322
- cell.innerText = date.toString();
323
- this.setupCell(cell, currentDate.getFullYear() + "," + month + "," + date, currentDate.getTime() >= this.options.minDateNoTime.getTime() && currentDate.getTime() <= this.options.maxDateNoTime.getTime(), currentDate.getTime() == this.today.getTime(), this.boundDateNoTime != null && currentDate.getTime() == this.boundDateNoTime.getTime());
337
+ this.setupCell(cell, date.toString(), currentDate.getFullYear() + "," + month + "," + date, currentDate.getTime() >= this.options.minDateNoTime.getTime() && currentDate.getTime() <= this.options.maxDateNoTime.getTime(), currentDate.getTime() == this.today.getTime(), this.boundDateNoTime != null && currentDate.getTime() == this.boundDateNoTime.getTime());
324
338
  if (month != this.currentViewDate.getMonth()) {
325
339
  cell.classList.add("outside-month");
326
340
  }
@@ -345,8 +359,7 @@ var DatePicker = /** @class */ (function () {
345
359
  trBody = this.createAndAppend(tBody, "tr");
346
360
  }
347
361
  var cell = this.createAndAppend(trBody, "td");
348
- cell.innerText = DateUtils.i18n.monthNames[i];
349
- this.setupCell(cell, i, monthEndDate > this.options.minDateNoTime.getTime() && monthStartDate <= this.options.maxDateNoTime.getTime(), this.today.getFullYear() == year && this.today.getMonth() == i, this.boundDateNoTime != null && this.boundDateNoTime.getFullYear() == year && this.boundDateNoTime.getMonth() == i);
362
+ this.setupCell(cell, DateUtils.i18n.monthNames[i], i, monthEndDate > this.options.minDateNoTime.getTime() && monthStartDate <= this.options.maxDateNoTime.getTime(), this.today.getFullYear() == year && this.today.getMonth() == i, this.boundDateNoTime != null && this.boundDateNoTime.getFullYear() == year && this.boundDateNoTime.getMonth() == i);
350
363
  }
351
364
  this.prevButton.disabled = this.options.minDateNoTime.getFullYear() >= year;
352
365
  this.nextButton.disabled = this.options.maxDateNoTime.getFullYear() <= year;
@@ -361,13 +374,12 @@ var DatePicker = /** @class */ (function () {
361
374
  trBody = this.createAndAppend(tBody, "tr");
362
375
  }
363
376
  var cell = this.createAndAppend(trBody, "td");
364
- cell.innerText = (year + i).toString();
365
- this.setupCell(cell, cell.innerText, year + i >= this.options.minDateNoTime.getFullYear() && year + i <= this.options.maxDateNoTime.getFullYear(), this.today.getFullYear() == year + i, this.boundDateNoTime != null && this.boundDateNoTime.getFullYear() == year + i);
377
+ this.setupCell(cell, (year + i).toString(), (year + i).toString(), year + i >= this.options.minDateNoTime.getFullYear() && year + i <= this.options.maxDateNoTime.getFullYear(), this.today.getFullYear() == year + i, this.boundDateNoTime != null && this.boundDateNoTime.getFullYear() == year + i);
366
378
  }
367
379
  this.prevButton.disabled = this.options.minDateNoTime.getFullYear() >= year;
368
380
  this.nextButton.disabled = this.options.maxDateNoTime.getFullYear() < year + YearsInYearView;
369
381
  };
370
- DatePicker.prototype.setupCell = function (cell, data, selectable, current, isSelected) {
382
+ DatePicker.prototype.setupCell = function (cell, innerText, data, selectable, current, isSelected) {
371
383
  if (selectable) {
372
384
  cell.classList.add("selectable");
373
385
  cell.dataset["date"] = data;
@@ -381,55 +393,56 @@ var DatePicker = /** @class */ (function () {
381
393
  if (isSelected) {
382
394
  cell.classList.add("selected");
383
395
  }
396
+ var cellContent = this.createAndAppend(cell, "span");
397
+ cellContent.innerText = innerText;
384
398
  };
385
399
  DatePicker.prototype.contentClick = function (e) {
400
+ var _a;
386
401
  e.preventDefault();
387
402
  if (e.target) {
388
- if (this.currentViewType == ViewType.Days) {
389
- this.dayClicked(e.target);
390
- }
391
- else if (this.currentViewType == ViewType.Months) {
392
- this.monthClicked(e.target);
403
+ var element = e.target;
404
+ if (!element.dataset["date"]) {
405
+ element = element.parentElement;
393
406
  }
394
- else {
395
- this.yearClicked(e.target);
407
+ var dateString = (_a = element) === null || _a === void 0 ? void 0 : _a.dataset["date"];
408
+ if (dateString) {
409
+ if (this.currentViewType == ViewType.Days) {
410
+ this.dayClicked(dateString);
411
+ }
412
+ else if (this.currentViewType == ViewType.Months) {
413
+ this.monthClicked(dateString);
414
+ }
415
+ else {
416
+ this.yearClicked(dateString);
417
+ }
396
418
  }
397
419
  }
398
420
  };
399
- DatePicker.prototype.dayClicked = function (element) {
400
- var datePartsString = element.dataset["date"];
401
- if (datePartsString) {
402
- var dateParts = datePartsString.split(",");
403
- this.setBindValueAndClose(new Date(parseInt(dateParts[0]), parseInt(dateParts[1]), parseInt(dateParts[2])), true);
404
- }
421
+ DatePicker.prototype.dayClicked = function (datePartsString) {
422
+ var dateParts = datePartsString.split(",");
423
+ this.setBindValue(new Date(parseInt(dateParts[0]), parseInt(dateParts[1]), parseInt(dateParts[2])), { preserveTime: true, close: true });
405
424
  };
406
- DatePicker.prototype.monthClicked = function (element) {
407
- var monthString = element.dataset["date"];
408
- if (monthString) {
409
- this.currentViewDate.setMonth(parseInt(monthString));
410
- if (this.options.monthView) {
411
- this.setBindValueAndClose(this.currentViewDate, true);
412
- }
413
- else {
414
- this.currentViewType = ViewType.Days;
415
- this.canAutoSetDate = true;
416
- this.populateContentContainer(false);
417
- this.contentAnimationHelper.fadeAndScale(true);
418
- }
425
+ DatePicker.prototype.monthClicked = function (monthString) {
426
+ this.currentViewDate.setMonth(parseInt(monthString));
427
+ if (this.options.monthView) {
428
+ this.setBindValue(this.currentViewDate, { preserveTime: true, close: true });
429
+ }
430
+ else {
431
+ this.currentViewType = ViewType.Days;
432
+ this.canAutoSetDate = true;
433
+ this.populateContentContainer(false);
434
+ this.contentAnimationHelper.fadeAndScale(true);
419
435
  }
420
436
  };
421
- DatePicker.prototype.yearClicked = function (element) {
422
- var yearString = element.dataset["date"];
423
- if (yearString) {
424
- this.currentViewDate.setFullYear(parseInt(yearString));
425
- if (this.options.yearView) {
426
- this.setBindValueAndClose(this.currentViewDate, true);
427
- }
428
- else {
429
- this.currentViewType = ViewType.Months;
430
- this.populateContentContainer(false);
431
- this.contentAnimationHelper.fadeAndScale(true);
432
- }
437
+ DatePicker.prototype.yearClicked = function (yearString) {
438
+ this.currentViewDate.setFullYear(parseInt(yearString));
439
+ if (this.options.yearView) {
440
+ this.setBindValue(this.currentViewDate, { preserveTime: true, close: true });
441
+ }
442
+ else {
443
+ this.currentViewType = ViewType.Months;
444
+ this.populateContentContainer(false);
445
+ this.contentAnimationHelper.fadeAndScale(true);
433
446
  }
434
447
  };
435
448
  DatePicker.prototype.headerClick = function (e) {
@@ -26,6 +26,10 @@ export default class DatePickerOptions {
26
26
  * `isClosing` will be false during scrolling with `autoChangeDate` set.
27
27
  * */
28
28
  onDateSelected?: (isClosing: boolean) => void;
29
+ /**
30
+ * If the datepicker popup should be aligned to the right of the input.
31
+ */
32
+ popupAlignRight?: boolean;
29
33
  }
30
34
  export declare class ProcessedDatePickerOptions extends DatePickerOptions {
31
35
  minDateNoTime: Date;
@@ -1,6 +1,7 @@
1
- import { ModelFieldInfo } from "../ModelFieldInfo";
1
+ import { IModelFieldInfoContainer, ModelFieldInfo } from "../ModelFieldInfo";
2
+ import PropertyInfo from "../PropertyInfo";
2
3
  import ValueObject from "../ValueObject";
3
- export declare abstract class CriteriaBase extends ValueObject {
4
+ export declare abstract class CriteriaBase extends ValueObject implements IModelFieldInfoContainer {
4
5
  /**
5
6
  * Extra information about lookup fields in this object.
6
7
  */
@@ -13,4 +14,5 @@ export declare abstract class CriteriaBase extends ValueObject {
13
14
  * You must also call this.makeObservable(); instead of using the @NeoModel decorator.
14
15
  */
15
16
  protected initialiseFieldInfo(fields: (keyof this)[]): void;
17
+ setModelFieldInfo(property: PropertyInfo, displayValue: string): any;
16
18
  }
@@ -25,6 +25,17 @@ var CriteriaBase = /** @class */ (function (_super) {
25
25
  }
26
26
  }
27
27
  };
28
+ CriteriaBase.prototype.setModelFieldInfo = function (property, displayValue) {
29
+ var fieldInfo = this.fieldInfo[property.propertyName];
30
+ if (!fieldInfo) {
31
+ fieldInfo = new ModelFieldInfo(property.readableName, displayValue);
32
+ this.fieldInfo[property.propertyName] = fieldInfo;
33
+ }
34
+ else {
35
+ fieldInfo.valueString = displayValue;
36
+ }
37
+ return fieldInfo;
38
+ };
28
39
  __decorate([
29
40
  Dictionary(ModelFieldInfo),
30
41
  __metadata("design:type", Object)
@@ -1,4 +1,4 @@
1
- import { TransformMetaType, PartialPlainObject, PlainFlatObject, PartialOrNull } from './IModelBase';
1
+ import { TransformMetaType, PartialPlainObject, PlainFlatObject, PartialOrNull, IMakeBindableOptions } from './IModelBase';
2
2
  import { NeoTypeInfo } from './NeoTypeInfo';
3
3
  import { IDeserialiseOptions } from '../Data/Deserialiser';
4
4
  export declare abstract class BindableBase {
@@ -30,6 +30,12 @@ export declare abstract class BindableBase {
30
30
  * This method can be used as an alternative to the @NeoModel decorator.
31
31
  */
32
32
  protected makeObservable(): void;
33
+ /**
34
+ * Makes the model bindable (and observable if it inherits from ModelBase) by creating its 'meta' object.
35
+ * Must be called in the constructor, preferably directly after the super() call.
36
+ * This method can be used as an alternative to the @NeoModel decorator.
37
+ */
38
+ protected makeBindable(options?: IMakeBindableOptions): void;
33
39
  static neo: NeoTypeInfo;
34
40
  /**
35
41
  * Creates a new instance of this type, and deserialises the plain javascript object graph into it.
@@ -1,7 +1,7 @@
1
1
  import { __assign, __decorate, __metadata } from "tslib";
2
2
  import { NoTracking, Observable } from './Decorators';
3
3
  import { JSFormatter } from '../Data/Serialiser';
4
- import { ensureTypeInfo } from './NeoTypeInfo';
4
+ import { NeoTypeInfo } from './NeoTypeInfo';
5
5
  import { Utils } from '../Utils';
6
6
  import { SerialiseType } from './Misc';
7
7
  var BindableBase = /** @class */ (function () {
@@ -42,11 +42,15 @@ var BindableBase = /** @class */ (function () {
42
42
  * This method can be used as an alternative to the @NeoModel decorator.
43
43
  */
44
44
  BindableBase.prototype.makeObservable = function () {
45
- // Ensure neo info is set
46
- var ctor = this.constructor;
47
- // Call this in case no property decorators were added
48
- ensureTypeInfo(ctor);
49
- ctor.neo.makeObservable(this);
45
+ this.makeBindable({ makeObservable: true });
46
+ };
47
+ /**
48
+ * Makes the model bindable (and observable if it inherits from ModelBase) by creating its 'meta' object.
49
+ * Must be called in the constructor, preferably directly after the super() call.
50
+ * This method can be used as an alternative to the @NeoModel decorator.
51
+ */
52
+ BindableBase.prototype.makeBindable = function (options) {
53
+ NeoTypeInfo.makeObservable(this, options);
50
54
  };
51
55
  /**
52
56
  * Creates a new instance of this type, and deserialises the plain javascript object graph into it.
@@ -41,6 +41,19 @@ export declare type PartialPlainNonTrackedObject<T> = PartialPlainObject<T> & {
41
41
  export interface NeoModelConstructor extends Function {
42
42
  neo: NeoTypeInfo;
43
43
  }
44
+ export interface IMakeBindableOptions {
45
+ /**
46
+ * Specifies whether properties should be observable
47
+ * * If this is `true`, all properties will be observable by default.
48
+ * * If `false` only properties decorated with @Attributes.Observable will be made observable.
49
+ * * If `undefined`, only types that inherit from `ModelBase` will be observable by default.
50
+ */
51
+ makeObservable?: boolean;
52
+ /**
53
+ * If `true`, this instance will not be converted. In inheritence heirarchies, use this to ensure only the last derived type converts the instance.
54
+ */
55
+ skipConversion?: boolean;
56
+ }
44
57
  export interface IDebounceOptions {
45
58
  delayMs?: number;
46
59
  }
@@ -1,9 +1,9 @@
1
1
  import { NeoTypeInfo } from './NeoTypeInfo';
2
- import { NeoModelConstructor } from './IModelBase';
2
+ import { IMakeBindableOptions, NeoModelConstructor } from './IModelBase';
3
3
  export default interface IModelCreatorBase {
4
4
  shouldInitialiseAllMembers: boolean;
5
5
  initialise(typeInfo: NeoTypeInfo, originalConstructor: NeoModelConstructor): void;
6
6
  isBindableBase(type: NeoModelConstructor): boolean;
7
7
  isModelBase(type: NeoModelConstructor): boolean;
8
- convertInstance(instance: {}): {};
8
+ convertInstance(instance: {}, options: IMakeBindableOptions): {};
9
9
  }
File without changes
File without changes
@@ -2,6 +2,7 @@ import { __assign, __extends } from "tslib";
2
2
  import { JSFormatter } from '../Data/Serialiser';
3
3
  import { Utils } from '../Utils';
4
4
  import { ObservableValue } from './ObservableValue';
5
+ import { NeoTypeInfo } from './NeoTypeInfo';
5
6
  var List = /** @class */ (function (_super) {
6
7
  __extends(List, _super);
7
8
  function List(childObjectType) {
@@ -179,8 +180,7 @@ var List = /** @class */ (function (_super) {
179
180
  }
180
181
  else {
181
182
  var ctor = this.childObjectType.prototype.constructor;
182
- ctor.neo.ensureInitialised();
183
- return ctor.neo.metaItem;
183
+ return NeoTypeInfo.ensureInitialised(ctor).metaItem;
184
184
  }
185
185
  };
186
186
  Object.defineProperty(List.prototype, "isValid", {
@@ -1,7 +1,8 @@
1
1
  import { NeoTypeInfo } from './NeoTypeInfo';
2
- import { NeoModelConstructor } from './IModelBase';
2
+ import { IMakeBindableOptions, NeoModelConstructor } from './IModelBase';
3
3
  import PropertyInfo from './PropertyInfo';
4
- export declare abstract class ModelCreatorBase {
4
+ import IModelCreatorBase from './IModelCreatorBase';
5
+ export declare abstract class ModelCreatorBase implements IModelCreatorBase {
5
6
  protected typeInfo: NeoTypeInfo;
6
7
  protected alwaysInitialiseMembers: boolean;
7
8
  /**
@@ -19,5 +20,5 @@ export declare abstract class ModelCreatorBase {
19
20
  protected ensureChildInfo(instance: {}, propertyInfo: PropertyInfo): void;
20
21
  protected addMethodInfo(methodName: string, method: Function): void;
21
22
  protected addProperty(propertyName: string, descriptor: PropertyDescriptor): void;
22
- abstract convertInstance(instance: {}): {};
23
+ abstract convertInstance(instance: {}, options: IMakeBindableOptions): {};
23
24
  }
@@ -1,4 +1,17 @@
1
1
  import ValueObject from "./ValueObject";
2
+ import PropertyInfo from "./PropertyInfo";
3
+ export interface IModelFieldInfoContainer {
4
+ /**
5
+ * Extra information about lookup fields in this object.
6
+ */
7
+ fieldInfo: {
8
+ [K in keyof this]?: ModelFieldInfo;
9
+ };
10
+ /**
11
+ * Sets the model field info for a property.
12
+ */
13
+ setModelFieldInfo(property: PropertyInfo, displayValue: string): ModelFieldInfo;
14
+ }
2
15
  export declare class ModelFieldInfo extends ValueObject {
3
16
  constructor(displayName: string, valueString: string);
4
17
  /**
@@ -9,4 +22,8 @@ export declare class ModelFieldInfo extends ValueObject {
9
22
  * Lookup of the field value
10
23
  */
11
24
  valueString: string;
25
+ /**
26
+ * If the instance is a container of ModelFieldInfo, the instance is returned, otherwise null is returned.
27
+ */
28
+ static asModelFieldInfoContainer(instance: any): IModelFieldInfoContainer | null;
12
29
  }
@@ -17,6 +17,16 @@ var ModelFieldInfo = /** @class */ (function (_super) {
17
17
  _this.valueString = valueString;
18
18
  return _this;
19
19
  }
20
+ /**
21
+ * If the instance is a container of ModelFieldInfo, the instance is returned, otherwise null is returned.
22
+ */
23
+ ModelFieldInfo.asModelFieldInfoContainer = function (instance) {
24
+ if (instance.fieldInfo &&
25
+ instance.setModelFieldInfo) {
26
+ return instance;
27
+ }
28
+ return null;
29
+ };
20
30
  ModelFieldInfo = __decorate([
21
31
  NeoModel,
22
32
  __metadata("design:paramtypes", [String, String])
@@ -1,10 +1,11 @@
1
1
  import { Rule } from '../Validation/Rules';
2
2
  import { PropertyInstanceMap } from './PropertyInstance';
3
3
  import PropertyInfo, { PropertyInfoMap } from './PropertyInfo';
4
- import { NeoModelConstructor, IModelBase, IMetaItem } from './IModelBase';
4
+ import { NeoModelConstructor, IModelBase, IMetaItem, IMakeBindableOptions } from './IModelBase';
5
5
  export declare class NeoTypeInfo {
6
6
  private modelCreator;
7
7
  private objectConstructor;
8
+ private wrapperConstructor?;
8
9
  private _inheritsBindableBase;
9
10
  private _inheritsModelBase;
10
11
  private _metaItem;
@@ -35,7 +36,16 @@ export declare class NeoTypeInfo {
35
36
  ensureInitialised(): void;
36
37
  /** Gets the override constructor which can setup a neo model. */
37
38
  getOverrideConstructor(): Function;
38
- makeObservable(instance: any): {};
39
+ private createWrapperConstructor;
40
+ makeObservable(instance: any, options?: IMakeBindableOptions): any;
39
41
  private defineProxyProperty;
42
+ /**
43
+ * Makes a class instance observable.
44
+ * Must be called in the constructor, preferably directly after the super() call.
45
+ * This method can be used as an alternative to the @NeoModel decorator.
46
+ */
47
+ static makeObservable(instance: any, options?: IMakeBindableOptions): void;
48
+ /** Ensures the type and its metadata are initialised. */
49
+ static ensureInitialised(constructor: NeoModelConstructor): NeoTypeInfo;
40
50
  }
41
51
  export declare function ensureTypeInfo(constructor: NeoModelConstructor): NeoModelConstructor;
@@ -9,6 +9,7 @@ import NeoTypes from '../AppServices/NeoTypes';
9
9
  import { RelationType } from './Misc';
10
10
  var ignoredPropertyNames = ["$mobx"];
11
11
  var inversifyMetadataKey = "inversify:tagged";
12
+ var hasConvertedSymbol = Symbol("hasConvertedModel");
12
13
  var NeoTypeInfo = /** @class */ (function () {
13
14
  function NeoTypeInfo() {
14
15
  this._inheritsBindableBase = false;
@@ -164,11 +165,22 @@ var NeoTypeInfo = /** @class */ (function () {
164
165
  NeoTypeInfo.prototype.ensureInitialised = function () {
165
166
  if (!this.modelCreator) {
166
167
  // create a new instance which will cause the type to be setup.
167
- this.getOverrideConstructor()();
168
+ if (this.wrapperConstructor) {
169
+ this.wrapperConstructor();
170
+ }
171
+ else {
172
+ void new this.objectConstructor();
173
+ }
168
174
  }
169
175
  };
170
176
  /** Gets the override constructor which can setup a neo model. */
171
177
  NeoTypeInfo.prototype.getOverrideConstructor = function () {
178
+ if (!this.wrapperConstructor) {
179
+ this.wrapperConstructor = this.createWrapperConstructor();
180
+ }
181
+ return this.wrapperConstructor;
182
+ };
183
+ NeoTypeInfo.prototype.createWrapperConstructor = function () {
172
184
  var _a;
173
185
  var self = this;
174
186
  var baseType = Object.getPrototypeOf(self.objectConstructor);
@@ -214,9 +226,22 @@ var NeoTypeInfo = /** @class */ (function () {
214
226
  newConstructor.prototype = self.objectConstructor.prototype;
215
227
  return newConstructor;
216
228
  };
217
- NeoTypeInfo.prototype.makeObservable = function (instance) {
218
- this.ensureStaticRuntimeInfo(instance);
219
- return this.modelCreator.convertInstance(instance);
229
+ NeoTypeInfo.prototype.makeObservable = function (instance, options) {
230
+ options = (options !== null && options !== void 0 ? options : {});
231
+ if (!options.skipConversion) {
232
+ this.ensureStaticRuntimeInfo(instance);
233
+ if (options.makeObservable === undefined) {
234
+ options.makeObservable = this.inheritsModelBase;
235
+ }
236
+ if (instance[hasConvertedSymbol]) {
237
+ throw Error("makeObservable() or makeBindable() has been called multiple times on type " + this.objectConstructor.name + ". Make sure this is only called on the last derived type.");
238
+ }
239
+ else {
240
+ instance[hasConvertedSymbol] = true;
241
+ }
242
+ return this.modelCreator.convertInstance(instance, options);
243
+ }
244
+ return instance;
220
245
  };
221
246
  NeoTypeInfo.prototype.defineProxyProperty = function (baseType, newConstructor, propertyKey) {
222
247
  Object.defineProperty(newConstructor, propertyKey, {
@@ -224,6 +249,22 @@ var NeoTypeInfo = /** @class */ (function () {
224
249
  set: function (value) { return baseType[propertyKey] = value; }
225
250
  });
226
251
  };
252
+ /**
253
+ * Makes a class instance observable.
254
+ * Must be called in the constructor, preferably directly after the super() call.
255
+ * This method can be used as an alternative to the @NeoModel decorator.
256
+ */
257
+ NeoTypeInfo.makeObservable = function (instance, options) {
258
+ var ctor = instance.constructor;
259
+ ensureTypeInfo(ctor);
260
+ ctor.neo.makeObservable(instance, options);
261
+ };
262
+ /** Ensures the type and its metadata are initialised. */
263
+ NeoTypeInfo.ensureInitialised = function (constructor) {
264
+ var typeInfo = ensureTypeInfo(constructor).neo;
265
+ typeInfo.ensureInitialised();
266
+ return typeInfo;
267
+ };
227
268
  return NeoTypeInfo;
228
269
  }());
229
270
  export { NeoTypeInfo };
@@ -1,10 +1,10 @@
1
- export { IBindableBase, IModelBase, NeoModelConstructor, PlainObject, PlainTrackedObject, PartialPlainObject, PartialPlainNonTrackedObject, TransformMetaType } from './IModelBase';
1
+ export { IBindableBase, IModelBase, NeoModelConstructor, PlainObject, PlainTrackedObject, PartialPlainObject, PartialPlainNonTrackedObject, TransformMetaType, IMakeBindableOptions } from './IModelBase';
2
2
  export { ILookupBase } from './LookupBase';
3
3
  export { IPropertyInstance, PropertyAccessor } from './PropertyInstance';
4
4
  export { IObservableValue, ObservableValue } from './ObservableValue';
5
5
  export { ObservableProperty } from './ObservableProperty';
6
6
  export { ISelectedItem } from './Misc';
7
- export { ModelFieldInfo } from './ModelFieldInfo';
7
+ export { ModelFieldInfo, IModelFieldInfoContainer } from './ModelFieldInfo';
8
8
  import * as GraphTraverser from './ModelGraphTraverser';
9
9
  export { GraphTraverser };
10
10
  export { AuditValues, AuditValuesBase } from './BaseModels/AuditValues';
@@ -16,14 +16,16 @@ export declare const Settings: {
16
16
  infoIcon: any;
17
17
  expanded: any;
18
18
  collapsed: any;
19
+ sortAsc: any;
20
+ sortDesc: any;
19
21
  };
20
22
  /** Grid default settings */
21
23
  grid: {
22
- /** When specified, the default bootstrap table borders (sides and cells) will be added */
24
+ /** Causes the table to have a border, cells will also have a left and right border. True by default. */
23
25
  isBordered: boolean;
24
26
  /** When specified, every alternating row will receive a slightly darker background color. */
25
27
  isStriped: boolean;
26
- /** When specified, the standard bootstrap table borders (sides and cells) will be removed. */
28
+ /** Removes the default top and bottom borders from rows. */
27
29
  isBorderless: boolean;
28
30
  /** When specified, a background color will be applied on a row if it is being hovered over. */
29
31
  showHover: boolean;
package/dist/Settings.js CHANGED
@@ -14,15 +14,17 @@ export var Settings = {
14
14
  warningIcon: "fa-exclamation-triangle",
15
15
  infoIcon: "fa-exclamation-circle",
16
16
  expanded: "far-minus-square",
17
- collapsed: "far-plus-square"
17
+ collapsed: "far-plus-square",
18
+ sortAsc: "sort-up",
19
+ sortDesc: "sort-down",
18
20
  },
19
21
  /** Grid default settings */
20
22
  grid: {
21
- /** When specified, the default bootstrap table borders (sides and cells) will be added */
23
+ /** Causes the table to have a border, cells will also have a left and right border. True by default. */
22
24
  isBordered: true,
23
25
  /** When specified, every alternating row will receive a slightly darker background color. */
24
26
  isStriped: false,
25
- /** When specified, the standard bootstrap table borders (sides and cells) will be removed. */
27
+ /** Removes the default top and bottom borders from rows. */
26
28
  isBorderless: false,
27
29
  /** When specified, a background color will be applied on a row if it is being hovered over. */
28
30
  showHover: false,
@@ -1,5 +1,4 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
- import NeoModel from '../../Model/NeoModel';
3
2
  import { Observable, Computed } from '../../Model/Decorators';
4
3
  import PropertyInstance from '../../Model/PropertyInstance';
5
4
  import RuleValidator from './RuleValidator';
@@ -7,6 +6,7 @@ import { ContainerValidationState } from '../ValidationState';
7
6
  import PropertyValidator from './PropertyValidator';
8
7
  import PropertyInfo from '../../Model/PropertyInfo';
9
8
  import ValidationDisplayHelper from '../DisplayHelper';
9
+ import { NeoTypeInfo } from '../../Model/NeoTypeInfo';
10
10
  var ModelValidator = /** @class */ (function () {
11
11
  function ModelValidator(model, objectRules) {
12
12
  var _this = this;
@@ -25,6 +25,7 @@ var ModelValidator = /** @class */ (function () {
25
25
  _this.objectRules.push(new RuleValidator(tempPropertyInstance_1, rule));
26
26
  });
27
27
  }
28
+ NeoTypeInfo.makeObservable(this);
28
29
  }
29
30
  ModelValidator.prototype.addProperty = function (property) {
30
31
  this.ruleProperties.push(property);
@@ -128,10 +129,6 @@ var ModelValidator = /** @class */ (function () {
128
129
  __metadata("design:type", ContainerValidationState),
129
130
  __metadata("design:paramtypes", [])
130
131
  ], ModelValidator.prototype, "ruleState", null);
131
- ModelValidator = __decorate([
132
- NeoModel,
133
- __metadata("design:paramtypes", [Object, Array])
134
- ], ModelValidator);
135
132
  return ModelValidator;
136
133
  }());
137
134
  export default ModelValidator;
@@ -2,14 +2,15 @@ import { __decorate, __metadata } from "tslib";
2
2
  import { ContainerValidationState } from '../ValidationState';
3
3
  import { ValidationDisplayMode } from '../Misc';
4
4
  import { ValidationDisplayInfo } from '../DisplayHelper';
5
- import NeoModel from '../../Model/NeoModel';
6
5
  import { Observable, Computed } from '../../Model/Decorators';
6
+ import { NeoTypeInfo } from '../../Model/NeoTypeInfo';
7
7
  var PropertyValidator = /** @class */ (function () {
8
8
  function PropertyValidator(propertyInstance, ruleList) {
9
9
  this.propertyInstance = propertyInstance;
10
10
  this.ruleList = ruleList;
11
11
  /** True if an element bound to this property has lost focus. Used for displaying rules. */
12
12
  this.hasBlurred = false;
13
+ NeoTypeInfo.makeObservable(this);
13
14
  }
14
15
  Object.defineProperty(PropertyValidator.prototype, "ruleState", {
15
16
  get: function () {
@@ -58,10 +59,6 @@ var PropertyValidator = /** @class */ (function () {
58
59
  __metadata("design:type", ContainerValidationState),
59
60
  __metadata("design:paramtypes", [])
60
61
  ], PropertyValidator.prototype, "ruleState", null);
61
- PropertyValidator = __decorate([
62
- NeoModel,
63
- __metadata("design:paramtypes", [Object, Array])
64
- ], PropertyValidator);
65
62
  return PropertyValidator;
66
63
  }());
67
64
  export default PropertyValidator;
@@ -1,8 +1,7 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
- import { Rule } from '../Rules';
3
2
  import { RuleContext, AsyncStage } from '../RuleContext';
4
- import NeoModel from '../../Model/NeoModel';
5
3
  import { Observable, Computed } from '../../Model/Decorators';
4
+ import { NeoTypeInfo } from '../../Model/NeoTypeInfo';
6
5
  var RuleValidator = /** @class */ (function () {
7
6
  function RuleValidator(propertyInstance, rule) {
8
7
  this.propertyInstance = propertyInstance;
@@ -13,6 +12,7 @@ var RuleValidator = /** @class */ (function () {
13
12
  // Properties this rule has been added to, including the primary property.
14
13
  this.properties = [];
15
14
  this.refreshValue = 0;
15
+ NeoTypeInfo.makeObservable(this);
16
16
  }
17
17
  Object.defineProperty(RuleValidator.prototype, "ruleId", {
18
18
  get: function () {
@@ -46,10 +46,6 @@ var RuleValidator = /** @class */ (function () {
46
46
  __metadata("design:type", Object),
47
47
  __metadata("design:paramtypes", [])
48
48
  ], RuleValidator.prototype, "ruleContext", null);
49
- RuleValidator = __decorate([
50
- NeoModel,
51
- __metadata("design:paramtypes", [Object, Rule])
52
- ], RuleValidator);
53
49
  return RuleValidator;
54
50
  }());
55
51
  export default RuleValidator;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@singularsystems/neo-core",
3
- "version": "0.10.61",
3
+ "version": "0.10.63",
4
4
  "description": "Core functionality for the Neo client library",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",