@sankhyalabs/core 1.0.71 → 2.0.0

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.
Files changed (75) hide show
  1. package/.eslintrc.cjs +2 -1
  2. package/dist/dataunit/DataUnit.d.ts +35 -18
  3. package/dist/dataunit/DataUnit.js +236 -93
  4. package/dist/dataunit/DataUnit.js.map +1 -1
  5. package/dist/dataunit/loading/LoadDataRequest.d.ts +9 -0
  6. package/dist/dataunit/loading/LoadDataRequest.js +2 -0
  7. package/dist/dataunit/loading/LoadDataRequest.js.map +1 -0
  8. package/dist/dataunit/loading/LoadDataResponse.d.ts +6 -0
  9. package/dist/dataunit/loading/LoadDataResponse.js +2 -0
  10. package/dist/dataunit/loading/LoadDataResponse.js.map +1 -0
  11. package/dist/dataunit/loading/PaginationInfo.d.ts +7 -0
  12. package/dist/dataunit/loading/PaginationInfo.js +2 -0
  13. package/dist/dataunit/loading/PaginationInfo.js.map +1 -0
  14. package/dist/dataunit/metadata/DataType.d.ts +1 -0
  15. package/dist/dataunit/metadata/DataType.js +14 -3
  16. package/dist/dataunit/metadata/DataType.js.map +1 -1
  17. package/dist/dataunit/state/action/DataUnitAction.d.ts +7 -1
  18. package/dist/dataunit/state/action/DataUnitAction.js +2 -0
  19. package/dist/dataunit/state/action/DataUnitAction.js.map +1 -1
  20. package/dist/dataunit/state/slice/ChangesSlice.d.ts +1 -0
  21. package/dist/dataunit/state/slice/ChangesSlice.js +3 -0
  22. package/dist/dataunit/state/slice/ChangesSlice.js.map +1 -1
  23. package/dist/dataunit/state/slice/LoadingControlSlice.d.ts +19 -0
  24. package/dist/dataunit/state/slice/LoadingControlSlice.js +45 -0
  25. package/dist/dataunit/state/slice/LoadingControlSlice.js.map +1 -0
  26. package/dist/dataunit/state/slice/RecordsSlice.js +10 -2
  27. package/dist/dataunit/state/slice/RecordsSlice.js.map +1 -1
  28. package/dist/dataunit/state/slice/SelectionSlice.js +0 -4
  29. package/dist/dataunit/state/slice/SelectionSlice.js.map +1 -1
  30. package/dist/dataunit/state/slice/WaitingChangesSlice.js.map +1 -1
  31. package/dist/exceptions/ErrorException.d.ts +2 -1
  32. package/dist/exceptions/ErrorException.js +2 -1
  33. package/dist/exceptions/ErrorException.js.map +1 -1
  34. package/dist/exceptions/WarningException.d.ts +2 -1
  35. package/dist/exceptions/WarningException.js +2 -1
  36. package/dist/exceptions/WarningException.js.map +1 -1
  37. package/dist/index.d.ts +7 -3
  38. package/dist/index.js +3 -2
  39. package/dist/index.js.map +1 -1
  40. package/dist/ui/FloatingManager.d.ts +10 -0
  41. package/dist/ui/FloatingManager.js +62 -1
  42. package/dist/ui/FloatingManager.js.map +1 -1
  43. package/dist/utils/ArrayUtils.d.ts +14 -0
  44. package/dist/utils/ArrayUtils.js +30 -0
  45. package/dist/utils/ArrayUtils.js.map +1 -0
  46. package/dist/utils/DateUtils.d.ts +2 -0
  47. package/dist/utils/DateUtils.js +14 -0
  48. package/dist/utils/DateUtils.js.map +1 -1
  49. package/dist/utils/NumberUtils.d.ts +17 -0
  50. package/dist/utils/NumberUtils.js +27 -0
  51. package/dist/utils/NumberUtils.js.map +1 -1
  52. package/dist/utils/StringUtils.d.ts +14 -2
  53. package/dist/utils/StringUtils.js +30 -2
  54. package/dist/utils/StringUtils.js.map +1 -1
  55. package/jest.config.ts +4 -4
  56. package/package.json +1 -1
  57. package/src/dataunit/DataUnit.ts +258 -102
  58. package/src/dataunit/loading/LoadDataRequest.ts +10 -0
  59. package/src/dataunit/loading/LoadDataResponse.ts +7 -0
  60. package/src/dataunit/loading/PaginationInfo.ts +8 -0
  61. package/src/dataunit/metadata/DataType.ts +28 -15
  62. package/src/dataunit/state/action/DataUnitAction.ts +8 -1
  63. package/src/dataunit/state/slice/ChangesSlice.ts +4 -0
  64. package/src/dataunit/state/slice/LoadingControlSlice.ts +60 -0
  65. package/src/dataunit/state/slice/RecordsSlice.ts +12 -5
  66. package/src/dataunit/state/slice/SelectionSlice.ts +0 -5
  67. package/src/dataunit/state/slice/WaitingChangesSlice.ts +0 -1
  68. package/src/exceptions/ErrorException.ts +3 -1
  69. package/src/exceptions/WarningException.ts +4 -1
  70. package/src/index.ts +15 -3
  71. package/src/ui/FloatingManager.ts +75 -5
  72. package/src/utils/ArrayUtils.ts +32 -0
  73. package/src/utils/DateUtils.ts +19 -3
  74. package/src/utils/NumberUtils.ts +33 -0
  75. package/src/utils/StringUtils.ts +35 -3
@@ -1,3 +1,5 @@
1
+ import DateUtils from "../../utils/DateUtils.js";
2
+
1
3
  export enum DataType {
2
4
  NUMBER = "NUMBER",
3
5
  DATE = "DATE",
@@ -12,25 +14,36 @@ export const convertType = (dataType: DataType, value: any): any => {
12
14
  return value;
13
15
  }
14
16
 
15
- if(typeof value === "object" && dataType !== DataType.OBJECT && "value" in value){
17
+ if (typeof value === "object" && dataType !== DataType.OBJECT && "value" in value){
16
18
  value = value.value;
17
19
  }
18
20
 
19
- switch (dataType) {
20
- case DataType.NUMBER:
21
- return value === "" || isNaN(value) ? null : Number(value);
22
- case DataType.OBJECT:
23
- return typeof value === "string" ? JSON.parse(value) : value;
24
- case DataType.BOOLEAN:
25
- if(typeof value == 'string'){
26
- return Boolean(value === 'true');
27
- }
28
- return Boolean(value);
29
- case DataType.DATE:
30
- return new Date(value.toString());
31
- default:
21
+ return getConvertedValue(dataType, value);
22
+ }
23
+
24
+ export const getConvertedValue = (dataType: DataType, value: any) => {
25
+ switch (dataType) {
26
+ case DataType.NUMBER:
27
+ return value === "" || isNaN(Number(value)) ? null : Number(value);
28
+ case DataType.OBJECT:
29
+ return typeof value === "string" ? JSON.parse(value) : value;
30
+ case DataType.BOOLEAN:
31
+ if (typeof value === "string") {
32
+ return Boolean(value === 'true');
33
+ }
34
+ return Boolean(value);
35
+ case DataType.DATE:
36
+ if (value == undefined || typeof value !== "string") {
37
+ return DateUtils.validateDate(value, true);
38
+ }
39
+ const newDate = DateUtils.validateDate(new Date(value), true);
40
+ if (newDate == undefined) {
32
41
  return value;
33
- }
42
+ }
43
+ return newDate;
44
+ default:
45
+ return value;
46
+ }
34
47
  }
35
48
 
36
49
  export const toString = ( dataType: DataType|undefined, value: any): string => {
@@ -19,6 +19,10 @@ export class DataUnitAction implements StateAction{
19
19
  return this._payload;
20
20
  }
21
21
  }
22
+ export interface ExecutionContext{
23
+ before?: (action: DataUnitAction) => DataUnitAction;
24
+ after?: (action: DataUnitAction) => void;
25
+ }
22
26
 
23
27
  export enum Action{
24
28
 
@@ -49,6 +53,9 @@ export enum Action{
49
53
  NEXT_SELECTED = "nextSelected",
50
54
  PREVIOUS_SELECTED = "previousSelected",
51
55
 
52
- STATE_CHANGED = "stateChanged"
56
+ STATE_CHANGED = "stateChanged",
57
+
58
+ LOADING_RECORD = "loadingRecord",
59
+ RECORD_LOADED = "recordLoaded"
53
60
 
54
61
  }
@@ -68,6 +68,10 @@ export const isDirty = (stateManager: StateManager): boolean => {
68
68
  return true;
69
69
  }
70
70
 
71
+ return hasDirtyRecords(stateManager);
72
+ }
73
+
74
+ export const hasDirtyRecords = (stateManager: StateManager): boolean => {
71
75
  if(getWaitingChanges(stateManager) !== undefined){
72
76
  return true;
73
77
  }
@@ -0,0 +1,60 @@
1
+
2
+ import { LoadDataRequest } from "../../loading/LoadDataRequest.js";
3
+ import { PaginationInfo } from "../../loading/PaginationInfo.js";
4
+ import { Action } from "../action/DataUnitAction.js";
5
+ import StateManager, { ActionReducer, StateAction } from "../StateManager.js";
6
+
7
+ class LoadingControlReducerImpl implements ActionReducer {
8
+
9
+ public sliceName: string = "loadingControl";
10
+
11
+ public reduce(stateManager: StateManager, currentState: LoadingControlState, action: StateAction): LoadingControlState {
12
+ switch (action.type) {
13
+ case Action.LOADING_DATA :
14
+ return {...currentState, lastRequest: action.payload};
15
+ case Action.DATA_LOADED:
16
+ return {...currentState, paginationInfo: action.payload?.paginationInfo};
17
+ }
18
+ return currentState;
19
+ }
20
+ }
21
+
22
+ export const LoadingControlReducer = new LoadingControlReducerImpl();
23
+
24
+ export const getPaginationInfo = (stateManager: StateManager): PaginationInfo|void => {
25
+ const state: LoadingControlState = stateManager.select(LoadingControlReducer.sliceName, (state: LoadingControlState) => state);
26
+ return state ? state.paginationInfo : undefined;
27
+ };
28
+
29
+ export const getCurrentRequest = (stateManager: StateManager): LoadDataRequest|void => {
30
+ const state: LoadingControlState = stateManager.select(LoadingControlReducer.sliceName, (state: LoadingControlState) => state);
31
+ return state ? state.lastRequest : undefined;
32
+ };
33
+
34
+ export const getCurrentPage = (stateManager: StateManager): number => {
35
+ const paginationInfo = getPaginationInfo(stateManager);
36
+ return paginationInfo ? paginationInfo.currentPage : 0;
37
+ };
38
+
39
+ export const getLastPage = (stateManager: StateManager, pageSize: number): number => {
40
+ const paginationInfo = getPaginationInfo(stateManager);
41
+ return paginationInfo ? Math.ceil(paginationInfo.total / pageSize) : 0;
42
+ };
43
+
44
+ export const hasMorePages = (stateManager: StateManager): boolean => {
45
+ const paginationInfo = getPaginationInfo(stateManager);
46
+ if(paginationInfo && paginationInfo.hasMore){
47
+ return true;
48
+ }
49
+ return false;
50
+ }
51
+
52
+ export const hasPreviousPages = (stateManager: StateManager): boolean => {
53
+ const paginationInfo = getPaginationInfo(stateManager);
54
+ return paginationInfo ? paginationInfo.currentPage > 0 : false;
55
+ }
56
+
57
+ interface LoadingControlState{
58
+ lastRequest: LoadDataRequest;
59
+ paginationInfo: PaginationInfo;
60
+ }
@@ -1,10 +1,8 @@
1
-
2
1
  import { ActionReducer, StateAction } from "../StateManager.js";
3
- import { Action } from "../action/DataUnitAction.js";
4
2
  import StateManager from "../StateManager.js";
5
- import { Record, SavedRecord } from "../../DataUnit.js";
6
3
  import { getRemovedRecords } from "./RemovedRecordsSlice.js";
7
-
4
+ import { Action } from "../action/DataUnitAction.js";
5
+ import { Record, SavedRecord } from "../../DataUnit.js";
8
6
 
9
7
  class RecordsReducerImpl implements ActionReducer {
10
8
 
@@ -14,7 +12,7 @@ class RecordsReducerImpl implements ActionReducer {
14
12
  switch (action.type) {
15
13
 
16
14
  case Action.DATA_LOADED:
17
- return action.payload;
15
+ return action.payload ? action.payload.records : undefined;
18
16
  case Action.RECORDS_REMOVED:
19
17
 
20
18
  const {records, buffered} = action.payload;
@@ -50,6 +48,15 @@ class RecordsReducerImpl implements ActionReducer {
50
48
  }
51
49
  });
52
50
  return newRecords.concat(Array.from(recordsMap.values()));
51
+
52
+ case Action.RECORD_LOADED:
53
+ action.payload.forEach((record: any) => {
54
+ for(let i = 0; i < currentState.length; i++){
55
+ if(currentState[i].__record__id__ === record.__record__id__){
56
+ currentState[i] = record;
57
+ }
58
+ }
59
+ });
53
60
  }
54
61
  return currentState;
55
62
  }
@@ -98,11 +98,6 @@ export const SelectionReducer = new SelectionReducerImpl();
98
98
 
99
99
  export const getSelection = (stateManager: StateManager): Array<string> => {
100
100
  let selection: Array<string> = getCurrentSelection(stateManager);
101
- const currentRecords = Array.from((getCurrentRecords(stateManager)||new Map()).keys());
102
-
103
- if(selection){
104
- selection = selection.filter( id => currentRecords.includes(id));
105
- }
106
101
 
107
102
  if (!selection || selection.length === 0) {
108
103
  return [];
@@ -2,7 +2,6 @@
2
2
  import { WaitingChange } from "../../DataUnit.js";
3
3
  import { Action } from "../action/DataUnitAction.js";
4
4
  import StateManager, { ActionReducer, StateAction } from "../StateManager.js";
5
- import { getSelection } from "./SelectionSlice.js";
6
5
 
7
6
  class WaitingCheangesReducerImpl implements ActionReducer{
8
7
 
@@ -2,10 +2,12 @@ export default class ErrorException extends Error {
2
2
 
3
3
  public title: string;
4
4
  public message: string;
5
+ public errorCode: string;
5
6
 
6
- constructor(title: string, message: string) {
7
+ constructor(title: string, message: string, errorCode: string = "") {
7
8
  super(message);
8
9
  this.title = title;
9
10
  this.message = message;
11
+ this.errorCode = errorCode;
10
12
  }
11
13
  }
@@ -3,10 +3,13 @@ export default class WarningException extends Error {
3
3
 
4
4
  public title: string;
5
5
  public message: string;
6
+ public errorCode: string;
6
7
 
7
- constructor(title: string, message: string) {
8
+ constructor(title: string, message: string, errorCode: string = "") {
8
9
  super(message);
9
10
  this.title = title;
10
11
  this.message = message;
12
+ this.errorCode = errorCode;
13
+
11
14
  }
12
15
  }
package/src/index.ts CHANGED
@@ -3,6 +3,7 @@ import { NumberUtils } from "./utils/NumberUtils.js";
3
3
  import { MaskFormatter } from "./utils/MaskFormatter.js";
4
4
  import FloatingManager from "./ui/FloatingManager.js";
5
5
  import DateUtils from "./utils/DateUtils.js";
6
+ import ArrayUtils from "./utils/ArrayUtils.js";
6
7
  import { TimeFormatter } from "./utils/TimeFormatter.js";
7
8
  import { HttpProvider } from "./http/HttpProvider.js";
8
9
  import { SkwHttpProvider } from "./http/SkwHttpProvider.js";
@@ -10,8 +11,8 @@ import { RequestMetadata } from "./http/RequestMetadata.js";
10
11
  import { AuthorizedServiceCaller } from "./http/AuthorizedServiceCaller.js";
11
12
  import DataUnit, {SavedRecord, Record, Change, ChangeOperation, DUActionInterceptor, WaitingChange, PageRequest, QuickFilter} from "./dataunit/DataUnit.js";
12
13
  import { DataType } from "./dataunit/metadata/DataType.js";
13
- import { UnitMetadata, FieldDescriptor, UserInterface, Sort, Filter } from "./dataunit/metadata/UnitMetadata.js";
14
- import { DataUnitAction, Action } from "./dataunit/state/action/DataUnitAction.js";
14
+ import { UnitMetadata, FieldDescriptor, UserInterface, Sort, SortMode, SortingProvider, Filter, DependencyType } from "./dataunit/metadata/UnitMetadata.js";
15
+ import { DataUnitAction, Action, ExecutionContext } from "./dataunit/state/action/DataUnitAction.js";
15
16
  import ApplicationContext from "./utils/ApplicationContext.js";
16
17
  import ReadyUtil from "./utils/ReadyUtil.js";
17
18
  import ObjectUtils from "./utils/ObjectUtils.js";
@@ -19,6 +20,9 @@ import WarningException from "./exceptions/WarningException.js";
19
20
  import WaitingChangeException from "./exceptions/WaitingChangeException.js";
20
21
  import ErrorException from "./exceptions/ErrorException.js";
21
22
  import { ErrorTracking } from "./traking/ErrorTraking.js";
23
+ import { PaginationInfo } from "./dataunit/loading/PaginationInfo.js";
24
+ import { LoadDataRequest } from "./dataunit/loading/LoadDataRequest.js";
25
+ import { LoadDataResponse } from "./dataunit/loading/LoadDataResponse.js";
22
26
 
23
27
  /*Classes públicas no pacote*/
24
28
  export {
@@ -27,6 +31,7 @@ export {
27
31
  NumberUtils,
28
32
  FloatingManager,
29
33
  DateUtils,
34
+ ArrayUtils,
30
35
  TimeFormatter,
31
36
  SkwHttpProvider,
32
37
  HttpProvider,
@@ -39,6 +44,7 @@ export {
39
44
  UnitMetadata,
40
45
  FieldDescriptor,
41
46
  UserInterface,
47
+ DependencyType,
42
48
  DataUnitAction,
43
49
  Action,
44
50
  Change,
@@ -55,5 +61,11 @@ export {
55
61
  WarningException,
56
62
  WaitingChangeException,
57
63
  ErrorException,
58
- ErrorTracking
64
+ ErrorTracking,
65
+ ExecutionContext,
66
+ PaginationInfo,
67
+ SortingProvider,
68
+ SortMode,
69
+ LoadDataRequest,
70
+ LoadDataResponse
59
71
  };
@@ -6,16 +6,19 @@ interface FloatingOptions {
6
6
  bottom?: string;
7
7
  innerClickTest?: Function;
8
8
  backClickListener?: Function;
9
+ isFixed?: boolean;
10
+ useOverlay?: boolean;
11
+ overlayClassName?: string;
9
12
  }
10
13
 
11
- class FloatingEntry {
12
14
 
15
+ class FloatingEntry {
13
16
  private weakRefParent?: WeakRef<HTMLElement>;
14
17
  private weakRefContent?: WeakRef<HTMLElement>;
15
18
  private strongRefParent?: HTMLElement;
16
19
  private strongRefContent?: HTMLElement;
17
20
  public options: FloatingOptions;
18
-
21
+
19
22
  constructor(parent: HTMLElement, content: HTMLElement, opts: FloatingOptions) {
20
23
  try{
21
24
  this.weakRefParent = new WeakRef(parent);
@@ -26,7 +29,7 @@ class FloatingEntry {
26
29
  }
27
30
  this.options = opts;
28
31
  }
29
-
32
+
30
33
  public get parent():HTMLElement|undefined{
31
34
  if(this.weakRefParent){
32
35
  return this.weakRefParent.deref();
@@ -42,8 +45,12 @@ class FloatingEntry {
42
45
  }
43
46
  }
44
47
 
45
- export default class FloatingManager {
46
48
 
49
+ export default class FloatingManager {
50
+ public static MODAL_DEFAULT_CLASSNAME = "FloatingManager__modal";
51
+ public static MODAL_ELEMENT_ID = "FloatingManager__overlay";
52
+ public static STYLE_ELEMENT_ID = "FloatingManager__style";
53
+
47
54
  private static initialized: boolean;
48
55
  private static entries: Array<FloatingEntry>;
49
56
 
@@ -83,6 +90,7 @@ export default class FloatingManager {
83
90
  delete FloatingManager.entries[id];
84
91
  }
85
92
  }
93
+ FloatingManager.hideOverlay();
86
94
  }
87
95
 
88
96
  private static handleDocumentEvent(event: Event) {
@@ -137,18 +145,80 @@ export default class FloatingManager {
137
145
  return alreadyFloatingIndex;
138
146
  }
139
147
 
140
- content.style.position = 'absolute';
148
+ content.style.position = options.isFixed ? 'fixed' : 'absolute';
141
149
  FloatingManager.applyStyle(content, "top", options.top);
142
150
  FloatingManager.applyStyle(content, "left", options.left);
143
151
  FloatingManager.applyStyle(content, "right", options.right);
144
152
  FloatingManager.applyStyle(content, "bottom", options.bottom);
145
153
 
154
+ FloatingManager.showOverlay(options);
146
155
  parent.appendChild(content);
147
156
  FloatingManager.entries.push(new FloatingEntry(parent, content, options));
148
157
 
149
158
  return FloatingManager.entries.length - 1;
150
159
  }
151
160
 
161
+ private static showOverlay(options: FloatingOptions){
162
+ if(options.useOverlay){
163
+ this.createOrUpdatOverlay().style.display = "block";
164
+ }
165
+ }
166
+
167
+ private static hideOverlay(){
168
+
169
+ if(FloatingManager.entries.filter(entry => entry.options.useOverlay).length > 0){
170
+ return;
171
+ }
172
+
173
+ const overlayElement:HTMLElement|null = document.querySelector(`div#${FloatingManager.MODAL_ELEMENT_ID}`);
174
+ if(overlayElement != undefined){
175
+ overlayElement.style.display = "none";
176
+ }
177
+ }
178
+
179
+ private static createOrUpdatOverlay(className: string = FloatingManager.MODAL_DEFAULT_CLASSNAME):HTMLDivElement{
180
+ let overlayElement: HTMLDivElement = document.querySelector(`div#${FloatingManager.MODAL_ELEMENT_ID}`) as HTMLDivElement;
181
+ if(!overlayElement){
182
+ overlayElement = document.createElement("div");
183
+ overlayElement.id = FloatingManager.MODAL_ELEMENT_ID;
184
+ const body = document.querySelector("body");
185
+ if(body){
186
+ body.appendChild(overlayElement);
187
+ }
188
+ }
189
+ if(className === FloatingManager.MODAL_DEFAULT_CLASSNAME){
190
+ FloatingManager.createStyleElement();
191
+ } else {
192
+ overlayElement.classList.remove(FloatingManager.MODAL_DEFAULT_CLASSNAME);
193
+ }
194
+ overlayElement.classList.add(className);
195
+ return overlayElement;
196
+ }
197
+
198
+ private static createStyleElement():void{
199
+ let styleElement:HTMLStyleElement = document.querySelector(`style#${FloatingManager.STYLE_ELEMENT_ID}`) as HTMLStyleElement;
200
+ if(styleElement == undefined){
201
+ styleElement = document.createElement("style");
202
+ styleElement.id = FloatingManager.STYLE_ELEMENT_ID;
203
+ styleElement.appendChild(document.createTextNode(`
204
+ .${FloatingManager.MODAL_DEFAULT_CLASSNAME} {
205
+ position: fixed;
206
+ z-index: 1;
207
+ padding: 0;
208
+ top: 0px;
209
+ left: 0px;
210
+ width: 100%;
211
+ height: 100vh;
212
+ box-sizing: border-box;
213
+ background: rgba(0, 0, 0, 0.1);
214
+ }`));
215
+ const header = document.querySelector("head");
216
+ if(header){
217
+ header.appendChild(styleElement);
218
+ }
219
+ }
220
+ }
221
+
152
222
  public static updateFloatPosition(content: HTMLElement, parent: HTMLElement, options: FloatingOptions = { autoClose: true }) {
153
223
  const alreadyFloatingIndex = FloatingManager.getFloatIndex(content, parent);
154
224
  if (alreadyFloatingIndex > -1) {
@@ -0,0 +1,32 @@
1
+ import { StringUtils } from "./StringUtils.js";
2
+
3
+ export default class ArrayUtils {
4
+ /**
5
+ * Filtra um array a partir de um critério textual.
6
+ *
7
+ * @param argument - Texto a ser usado no filtro
8
+ * @param originalArray - Array no formato original
9
+ * @param alphabeticalSorting - Determina se o resultado deve ser ordenado ou mantido na ordem original. Por padrão ordena.
10
+ * @param fieldName - Caso o objeto deva ser filtrado por um campo diferente de "label", pode-se usar esse parâmetro
11
+ * @returns Um array filtrado e ordenado conforme necessidade. Se "argument" for omitido, ou nulo, o array original é retornado.
12
+ */
13
+ static applyStringFilter(argument: string, originalArray: Array<any>, alphabeticalSorting: boolean = true, fieldName: string = "label"): Array<any>{
14
+ if(!argument){
15
+ return originalArray;
16
+ }
17
+ const normalizedArgument = ArrayUtils.normalizeSearchString(argument);
18
+ const filteredArray = originalArray.filter(item => {
19
+ const itemValue: string = ArrayUtils.normalizeSearchString(item[fieldName]);
20
+ return itemValue.includes(normalizedArgument);
21
+ });
22
+ return alphabeticalSorting ? ArrayUtils.sortAlphabetically(filteredArray, fieldName) : filteredArray;
23
+ }
24
+
25
+ private static normalizeSearchString(original:string ): string{
26
+ return StringUtils.replaceAccentuatedCharsKeepSymbols(original.toUpperCase());
27
+ }
28
+
29
+ static sortAlphabetically(originalArray: Array<any>, fieldName: string = "label"): Array<any>{
30
+ return originalArray.sort((fieldA, fieldB) => StringUtils.compare(fieldA[fieldName], fieldB[fieldName]));
31
+ }
32
+ }
@@ -1,11 +1,11 @@
1
1
  export default class DateUtils{
2
2
 
3
- public static clearTime(date:Date, adjustDayLightSavingTime:boolean = true):Date{
3
+ public static clearTime(date:Date, adjustDayLightSavingTime:boolean = true): Date {
4
4
  const newDate: Date = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0);
5
5
  return adjustDayLightSavingTime ? DateUtils.adjustDLST(newDate) : newDate;
6
6
  }
7
7
 
8
- public static strToDate(strValue:string, adjustDayLightSavingTime:boolean = true, monthYearMode:boolean = false): Date | undefined{
8
+ public static strToDate(strValue:string, adjustDayLightSavingTime:boolean = true, monthYearMode:boolean = false): Date | undefined {
9
9
  /** monthYearMode é um booleano para usar o formato MM/YYYY.
10
10
  * Quando ativado, é retornado o primeiro dia do mês apenas para construir a data.
11
11
  * Não há necessidade de verificar o horário de verão quando utilizado esse modo. */
@@ -41,7 +41,23 @@ export default class DateUtils{
41
41
  return date;
42
42
  }
43
43
 
44
- private static adjustDLST(date:Date):Date{
44
+ public static getToday(withTime: boolean = false) {
45
+ const today = new Date();
46
+
47
+ if (withTime) {
48
+ return today;
49
+ } else {
50
+ return DateUtils.clearTime(today);
51
+ }
52
+ }
53
+
54
+ public static validateDate(value: Date, hasTime: boolean = false): Date | undefined {
55
+ return value instanceof Date && !isNaN(value.valueOf())
56
+ ? hasTime ? value : DateUtils.clearTime(value)
57
+ : undefined;
58
+ }
59
+
60
+ private static adjustDLST(date:Date): Date {
45
61
 
46
62
  //Work around para corrigir o Bug do horário de verão.
47
63
  if(date.getHours() == 23){
@@ -1,3 +1,4 @@
1
+ import { StringUtils } from "./StringUtils.js";
1
2
 
2
3
  const NUMBERINPUTS_REGEX_SCIENTIFIC_PARTS: RegExp = /^([+-])?(\d+).?(\d*)[eE]([-+]?\d+)$/;
3
4
 
@@ -172,4 +173,36 @@ export class NumberUtils {
172
173
  return value.replace(/\./g, '_').replace(/\,/g, '.').replace(/\_/g, ',');
173
174
  }
174
175
 
176
+
177
+
178
+ /**
179
+ * @getValueOrDefault: retorna o valor passado como number, caso NaN retorna o defaultValue
180
+ *
181
+ * @param value numero a ser validado
182
+ * @param defaultValue numero a ser retornado caso o value seja inválido
183
+ *
184
+ * @returns o proprio numero passado ou zero
185
+ */
186
+ static getValueOrDefault = (value: any, defaultValue: number): number => {
187
+ value = StringUtils.isEmpty(value) ? undefined : value;
188
+ value = Number(value);
189
+
190
+ if (isNaN(value)){
191
+ return Number(defaultValue);
192
+ }
193
+
194
+ return value;
195
+
196
+ }
197
+
198
+ /**
199
+ * @getValueOrZero: valida se o parametro é undefined caso seja retorna zero.
200
+ *
201
+ * @param value numero a ser validado
202
+ *
203
+ * @returns o proprio numero passado ou zero
204
+ */
205
+ static getValueOrZero = (value: any): number => {
206
+ return NumberUtils.getValueOrDefault(value, 0);
207
+ }
175
208
  }
@@ -57,10 +57,17 @@ export class StringUtils {
57
57
  text = text.replace(/[Ç]/, "C");
58
58
  return text.replace(/[^a-z0-9]/gi, "");
59
59
  }
60
-
60
+
61
+ /**
62
+ * Remove acentos de vogais, substitui Ç por c e retorna a string em caixa alta mantendo espaços e símbolos.
63
+ * @param text String para ser transformada.
64
+ */
65
+ static replaceAccentuatedCharsKeepSymbols(text: string): string {
66
+ return text.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toUpperCase();
67
+ }
68
+
61
69
  /**
62
70
  * Calcula um código hash para uma string.
63
- *
64
71
  * @param value String que será gerado o hash code.
65
72
  */
66
73
  static hashCode(value: string): string {
@@ -76,7 +83,6 @@ export class StringUtils {
76
83
 
77
84
  /**
78
85
  * Converte um valor em string para booleano
79
- *
80
86
  * @param value Valor a ser convertido
81
87
  * @param defaultValue Será retornado esse caso seja passado valores diferentes do esperado(true, false, "true", "false", "S", "N")
82
88
  */
@@ -107,4 +113,30 @@ export class StringUtils {
107
113
  }
108
114
  return str;
109
115
  }
116
+
117
+
118
+ /**
119
+ * Utilitário para determinar a ordem de strings. Geralmente usado no método "sort" de um array.
120
+ * Retorna um número negativo se o primeiro argumento é menor que o segundo, zero se os dois são iguais
121
+ * e um número positivo quando o primeiro é maior que o segundo.if they're equal, and a positive value otherwise.
122
+ * @param a - Primeira string para comparação
123
+ * @param b - Segunda string para comparação
124
+ * @returns Um valor maior, menor ou igual a zero para determinar se a ordem precisa ser alterada.
125
+ */
126
+ static compare(a: string, b: string): number{
127
+
128
+ if(a === undefined){
129
+ return b === undefined ? 0 : 1;
130
+ } else if(b === undefined){
131
+ return -1;
132
+ }
133
+
134
+ if(a === null){
135
+ return b === null ? 0 : 1;
136
+ } else if(b === null){
137
+ return -1;
138
+ }
139
+
140
+ return a.localeCompare(b);
141
+ }
110
142
  }