@sankhyalabs/core 6.1.0 → 6.2.0-dev.1
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/.docs/classes/Change.md +11 -11
- package/.docs/classes/ColumnFilterManager.md +6 -6
- package/.docs/classes/DataUnit.md +178 -157
- package/.docs/classes/DataUnitLoaderUtils.md +6 -6
- package/.docs/classes/LangUtils.md +195 -0
- package/.docs/classes/SelectionInfo.md +16 -16
- package/.docs/enumerations/ChangeOperation.md +4 -4
- package/.docs/enumerations/SelectionMode.md +2 -2
- package/.docs/functions/defaultDataLoader.md +1 -1
- package/.docs/globals.md +1 -0
- package/.docs/interfaces/DUActionInterceptor.md +1 -1
- package/.docs/interfaces/PageRequest.md +3 -3
- package/.docs/interfaces/PaginationInfoBuilderParams.md +3 -3
- package/.docs/interfaces/QuickFilter.md +3 -3
- package/.docs/interfaces/Record.md +4 -4
- package/.docs/interfaces/SavedRecord.md +5 -5
- package/.docs/interfaces/WaitingChange.md +3 -3
- package/.docs/type-aliases/DataUnitEventOptions.md +1 -1
- package/dist/dataunit/Changes.d.ts +52 -0
- package/dist/dataunit/Changes.js +64 -0
- package/dist/dataunit/Changes.js.map +1 -0
- package/dist/dataunit/DataUnit.d.ts +16 -129
- package/dist/dataunit/DataUnit.js +97 -177
- package/dist/dataunit/DataUnit.js.map +1 -1
- package/dist/dataunit/DataUnitHelper.d.ts +2 -1
- package/dist/dataunit/DataUnitHelper.js.map +1 -1
- package/dist/dataunit/SelectionInfo.d.ts +16 -0
- package/dist/dataunit/SelectionInfo.js +39 -0
- package/dist/dataunit/SelectionInfo.js.map +1 -0
- package/dist/dataunit/formatting/PrettyFormatter.js +5 -3
- package/dist/dataunit/formatting/PrettyFormatter.js.map +1 -1
- package/dist/dataunit/interfaces/dataUnit.d.ts +61 -0
- package/dist/dataunit/interfaces/dataUnit.js +13 -0
- package/dist/dataunit/interfaces/dataUnit.js.map +1 -0
- package/dist/dataunit/loader/utils/dataUnitLoaderUtils.d.ts +2 -1
- package/dist/dataunit/loader/utils/dataUnitLoaderUtils.js.map +1 -1
- package/dist/dataunit/loading/LoadDataRequest.d.ts +1 -1
- package/dist/dataunit/loading/LoadDataResponse.d.ts +1 -1
- package/dist/dataunit/sorting/FieldComparator.d.ts +1 -1
- package/dist/dataunit/state/slice/AddedRecordsSlice.d.ts +1 -1
- package/dist/dataunit/state/slice/ChangesSlice.d.ts +2 -1
- package/dist/dataunit/state/slice/ChangesSlice.js +2 -1
- package/dist/dataunit/state/slice/ChangesSlice.js.map +1 -1
- package/dist/dataunit/state/slice/LoadingControlSlice.js.map +1 -1
- package/dist/dataunit/state/slice/RecordsSlice.d.ts +1 -1
- package/dist/dataunit/state/slice/RecordsSlice.js +1 -1
- package/dist/dataunit/state/slice/RecordsSlice.js.map +1 -1
- package/dist/dataunit/state/slice/SelectionSlice.d.ts +2 -1
- package/dist/dataunit/state/slice/SelectionSlice.js +2 -1
- package/dist/dataunit/state/slice/SelectionSlice.js.map +1 -1
- package/dist/dataunit/state/slice/SnapshotSlice.d.ts +1 -1
- package/dist/dataunit/state/slice/WaitingChangesSlice.d.ts +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/utils/ColumnFilterManager.d.ts +2 -1
- package/dist/utils/ColumnFilterManager.js.map +1 -1
- package/dist/utils/LangUtils.d.ts +83 -0
- package/dist/utils/LangUtils.js +121 -0
- package/dist/utils/LangUtils.js.map +1 -0
- package/dist/utils/SortingUtils.d.ts +1 -1
- package/package.json +3 -2
- package/reports/test-report.xml +741 -524
- package/src/dataunit/Changes.ts +77 -0
- package/src/dataunit/DataUnit.ts +253 -397
- package/src/dataunit/DataUnitHelper.ts +2 -1
- package/src/dataunit/SelectionInfo.ts +55 -0
- package/src/dataunit/formatting/PrettyFormatter.ts +4 -5
- package/src/dataunit/interfaces/dataUnit.ts +71 -0
- package/src/dataunit/loader/utils/dataUnitLoaderUtils.ts +2 -1
- package/src/dataunit/loading/LoadDataRequest.ts +1 -1
- package/src/dataunit/loading/LoadDataResponse.ts +1 -1
- package/src/dataunit/sorting/FieldComparator.ts +1 -1
- package/src/dataunit/state/slice/AddedRecordsSlice.ts +1 -1
- package/src/dataunit/state/slice/ChangesSlice.ts +2 -1
- package/src/dataunit/state/slice/LoadingControlSlice.ts +1 -2
- package/src/dataunit/state/slice/RecordsSlice.ts +3 -2
- package/src/dataunit/state/slice/SelectionSlice.ts +2 -1
- package/src/dataunit/state/slice/SnapshotSlice.ts +1 -1
- package/src/dataunit/state/slice/WaitingChangesSlice.ts +1 -1
- package/src/dataunit/state/slice/test/RecordsSlice.spec.ts +1 -1
- package/src/index.ts +6 -2
- package/src/utils/ColumnFilterManager.ts +2 -1
- package/src/utils/LangUtils.ts +129 -0
- package/src/utils/SortingUtils.ts +1 -1
- package/test/dataunit/AccessParentsDataUnit.spec.ts +69 -0
- package/test/dataunit/Actions.spec.ts +74 -0
- package/test/dataunit/Change.spec.ts +66 -0
- package/test/dataunit/FieldManager.spec.ts +286 -0
- package/test/dataunit/FilterSortsLockersAndObservers.spec.ts +339 -0
- package/test/dataunit/InfoManager.spec.ts +254 -0
- package/test/dataunit/LoadDataAndMetadata.spec.ts +269 -0
- package/test/dataunit/RecodsSelection.spec.ts +229 -0
- package/test/dataunit/RecordsManager.spec.ts +323 -0
- package/test/dataunit/SavingData.spec.ts +206 -0
- package/test/dataunit/SelectionInfo.spec.ts +143 -0
- package/test/dataunit/formatting/PrettyFormatter.spec.ts +1 -1
- package/test/dataunit/loader/dataUnitInMemoryLoader.spec.ts +2 -1
- package/test/dataunit/loader/utils/createDataUnitMock.ts +34 -0
- package/test/dataunit/loader/utils/dataUnitLoaderUtils.spec.ts +1 -1
- package/test/dataunit/resources/metadata.ts +39 -0
- package/test/dataunit/resources/records.ts +29 -0
- package/test/util/ColumnFilterManager.spec.ts +2 -1
- package/test/util/LangUtils.spec.ts +117 -0
- package/tsconfig.json +1 -0
- package/src/dataunit/test/DataUnit.spec.ts +0 -44
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import DataUnit
|
|
1
|
+
import DataUnit from './DataUnit.js';
|
|
2
|
+
import { Record } from './interfaces/dataUnit.js';
|
|
2
3
|
import { DataType } from './metadata/DataType.js';
|
|
3
4
|
import { LoadDataRequest, LoadDataResponse, PaginationInfo, Sort, SortMode, StringUtils } from '../index.js';
|
|
4
5
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Record, SelectionMode } from "./interfaces/dataUnit.js";
|
|
2
|
+
import { Filter, Sort } from "./metadata/UnitMetadata.js";
|
|
3
|
+
|
|
4
|
+
export class SelectionInfo {
|
|
5
|
+
|
|
6
|
+
public mode: SelectionMode;
|
|
7
|
+
public filters?: Array<Filter>;
|
|
8
|
+
public sort?: Array<Sort>;
|
|
9
|
+
public getAllRecords?: () => Array<Record>;
|
|
10
|
+
private _records: Array<Record>;
|
|
11
|
+
private _total?: number;
|
|
12
|
+
|
|
13
|
+
constructor(records: Array<Record>, mode: SelectionMode = SelectionMode.SOME_RECORDS, total?: number, filters?: Array<Filter>, sort?: Array<Sort>) {
|
|
14
|
+
this._records = records;
|
|
15
|
+
this._total = total;
|
|
16
|
+
this.mode = mode;
|
|
17
|
+
this.filters = filters;
|
|
18
|
+
this.sort = sort;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public get records(): Array<Record> {
|
|
22
|
+
if (this.isAllRecords()) {
|
|
23
|
+
if (this.getAllRecords != undefined) {
|
|
24
|
+
return this.getAllRecords();
|
|
25
|
+
}
|
|
26
|
+
throw new Error("Erro interno: Impossível retornar os registros selecionados numa seleção virtual.");
|
|
27
|
+
}
|
|
28
|
+
return this._records;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public get recordIds(): Array<string> | undefined {
|
|
32
|
+
|
|
33
|
+
const records = this.records;
|
|
34
|
+
|
|
35
|
+
if (records == undefined) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
return records.map(record => record.__record__id__);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public get length(): number {
|
|
42
|
+
if (this.isAllRecords()) {
|
|
43
|
+
return this._total || 0;
|
|
44
|
+
}
|
|
45
|
+
return this.records == undefined ? 0 : (this.records as Array<Record>).length;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public isAllRecords(): boolean {
|
|
49
|
+
return this.mode === SelectionMode.ALL_RECORDS;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public isEmpty(): boolean {
|
|
53
|
+
return this.length === 0;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -7,7 +7,7 @@ import { FieldDescriptor, UserInterface } from '../metadata/UnitMetadata.js';
|
|
|
7
7
|
|
|
8
8
|
export const getFormattedValue = (value: any, descriptor?: FieldDescriptor) => {
|
|
9
9
|
if(descriptor?.userInterface === UserInterface.FILE){
|
|
10
|
-
return
|
|
10
|
+
return getFileFormat(value);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
if(descriptor?.dataType === DataType.OBJECT){
|
|
@@ -131,10 +131,9 @@ const getMask = (value: string, descriptor: FieldDescriptor | undefined): string
|
|
|
131
131
|
return mask;
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
const
|
|
135
|
-
if (
|
|
136
|
-
|
|
134
|
+
const getFileFormat = (value: any) => {
|
|
135
|
+
if (value == undefined) return '';
|
|
136
|
+
if (!value || !Array.isArray(value)) return value;
|
|
137
137
|
if (value.length === 1) return value[0].name;
|
|
138
|
-
|
|
139
138
|
return `${value.length} arquivos`;
|
|
140
139
|
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Filter } from "../metadata/UnitMetadata.js";
|
|
2
|
+
import { DataUnitAction, ExecutionContext } from "../state/action/DataUnitAction.js";
|
|
3
|
+
|
|
4
|
+
export interface LoadDataParams {
|
|
5
|
+
quickFilter?: QuickFilter;
|
|
6
|
+
executionCtx?: ExecutionContext;
|
|
7
|
+
checkLastFilter?: boolean;
|
|
8
|
+
source?: string;
|
|
9
|
+
selectFirstRecord?: boolean;
|
|
10
|
+
keepSelection?: boolean
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface DUActionInterceptor {
|
|
14
|
+
interceptAction(action: DataUnitAction): DataUnitAction | Promise<DataUnitAction>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface Record {
|
|
18
|
+
__record__id__: string;
|
|
19
|
+
__record__label__?: string;
|
|
20
|
+
__parent__record__id__?: string;
|
|
21
|
+
__owner__dataunit__name__?: string;
|
|
22
|
+
[key: string]: any;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface SavedRecord extends Record {
|
|
26
|
+
__old__id__?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export enum ChangeOperation {
|
|
30
|
+
INSERT = "INSERT",
|
|
31
|
+
COPY = "COPY",
|
|
32
|
+
UPDATE = "UPDATE",
|
|
33
|
+
DELETE = "DELETE",
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface WaitingChange {
|
|
37
|
+
waitmessage: string;
|
|
38
|
+
blocking: boolean;
|
|
39
|
+
promise?: Promise<any>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface PageRequest {
|
|
43
|
+
limit: number;
|
|
44
|
+
offset: number;
|
|
45
|
+
quickFilter?: QuickFilter;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface QuickFilter {
|
|
49
|
+
term: string;
|
|
50
|
+
fields?: Array<string>;
|
|
51
|
+
filter?: Filter;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface PageResponse {
|
|
55
|
+
limit: number;
|
|
56
|
+
offset: number;
|
|
57
|
+
total: number;
|
|
58
|
+
hasMore: boolean;
|
|
59
|
+
records: Array<Record>;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export enum SelectionMode {
|
|
63
|
+
ALL_RECORDS = "ALL_RECORDS",
|
|
64
|
+
SOME_RECORDS = "SOME_RECORDS"
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export type DataUnitEventOptions = { [key: string]: any };
|
|
68
|
+
|
|
69
|
+
export type HideFieldOptions = {
|
|
70
|
+
visibleOnConfig: boolean
|
|
71
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import DataUnit
|
|
1
|
+
import DataUnit from '../../DataUnit.js';
|
|
2
|
+
import { Record } from '../../interfaces/dataUnit.js';
|
|
2
3
|
import { Filter, Sort } from '../../metadata/UnitMetadata.js';
|
|
3
4
|
import { LoadDataRequest } from '../../loading/LoadDataRequest.js';
|
|
4
5
|
import { PaginationInfo } from '../../loading/PaginationInfo.js';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { ActionReducer, StateAction } from "../StateManager.js";
|
|
3
3
|
import { Action } from "../action/DataUnitAction.js";
|
|
4
4
|
import StateManager from "../StateManager.js";
|
|
5
|
-
import { Record } from "../../
|
|
5
|
+
import { Record } from "../../interfaces/dataUnit.js";
|
|
6
6
|
|
|
7
7
|
class AddedRecordsReducerImpl implements ActionReducer{
|
|
8
8
|
|
|
@@ -6,7 +6,8 @@ import { getSelection } from "./SelectionSlice.js";
|
|
|
6
6
|
import { getRecords } from "./RecordsSlice.js";
|
|
7
7
|
import { getRemovedRecords } from "./RemovedRecordsSlice.js";
|
|
8
8
|
import { getAddedRecords, isAddedRecord } from "./AddedRecordsSlice.js";
|
|
9
|
-
import {
|
|
9
|
+
import { ChangeOperation, Record } from "../../interfaces/dataUnit.js";
|
|
10
|
+
import { Change } from "../../Changes.js";
|
|
10
11
|
import { getWaitingChanges } from "./WaitingChangesSlice.js";
|
|
11
12
|
import { getSelectionRecords } from "./SnapshotSlice.js";
|
|
12
13
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { ChangeOperation } from "../../DataUnit.js";
|
|
1
|
+
import { ChangeOperation } from "../../interfaces/dataUnit.js";
|
|
3
2
|
import { LoadDataRequest } from "../../loading/LoadDataRequest.js";
|
|
4
3
|
import { PaginationInfo } from "../../loading/PaginationInfo.js";
|
|
5
4
|
import { Action } from "../action/DataUnitAction.js";
|
|
@@ -2,7 +2,8 @@ import { ActionReducer, StateAction } from "../StateManager.js";
|
|
|
2
2
|
import StateManager from "../StateManager.js";
|
|
3
3
|
import { getRemovedRecords } from "./RemovedRecordsSlice.js";
|
|
4
4
|
import { Action } from "../action/DataUnitAction.js";
|
|
5
|
-
import { Record, SavedRecord } from "../../
|
|
5
|
+
import { Record, SavedRecord } from "../../interfaces/dataUnit.js";
|
|
6
|
+
|
|
6
7
|
|
|
7
8
|
class RecordsReducerImpl implements ActionReducer {
|
|
8
9
|
|
|
@@ -12,7 +13,7 @@ class RecordsReducerImpl implements ActionReducer {
|
|
|
12
13
|
switch (action.type) {
|
|
13
14
|
|
|
14
15
|
case Action.DATA_LOADED:
|
|
15
|
-
return action.payload ? action.payload.records :
|
|
16
|
+
return action.payload ? action.payload.records : [];
|
|
16
17
|
case Action.RECORDS_REMOVED:
|
|
17
18
|
|
|
18
19
|
const {records, buffered} = action.payload;
|
|
@@ -2,7 +2,8 @@ import { ActionReducer, StateAction } from "../StateManager.js";
|
|
|
2
2
|
import { Action } from "../action/DataUnitAction.js";
|
|
3
3
|
import StateManager from "../StateManager.js";
|
|
4
4
|
import { getCurrentRecords, getSelectionRecords } from "./SnapshotSlice.js";
|
|
5
|
-
import { Record, SavedRecord,
|
|
5
|
+
import { Record, SavedRecord, SelectionMode } from "../../interfaces/dataUnit.js";
|
|
6
|
+
import { SelectionInfo } from "../../SelectionInfo.js";
|
|
6
7
|
import { getCurrentRequest, getPaginationInfo } from "./LoadingControlSlice.js";
|
|
7
8
|
import { PaginationInfo } from "../../loading/PaginationInfo.js";
|
|
8
9
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
import { ActionReducer } from "../StateManager.js";
|
|
3
3
|
import StateManager from "../StateManager.js";
|
|
4
|
-
import { Record } from "../../
|
|
4
|
+
import { Record } from "../../interfaces/dataUnit.js";
|
|
5
5
|
import { getRecords } from "./RecordsSlice.js";
|
|
6
6
|
import { getSelection } from "./SelectionSlice.js";
|
|
7
7
|
import { getChangedFieldValue, getChanges } from "./ChangesSlice.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
import * as RecordsReducerModule from '../RecordsSlice';
|
|
3
3
|
import StateManager from '../../StateManager';
|
|
4
|
-
import { Record } from '../../../
|
|
4
|
+
import { Record } from '../../../interfaces/dataUnit';
|
|
5
5
|
import { Action } from '../../action/DataUnitAction';
|
|
6
6
|
|
|
7
7
|
jest.spyOn(RecordsReducerModule, "getRecords").mockImplementation(() => [
|
package/src/index.ts
CHANGED
|
@@ -9,7 +9,10 @@ import { HttpProvider } from "./http/HttpProvider.js";
|
|
|
9
9
|
import { SkwHttpProvider } from "./http/SkwHttpProvider.js";
|
|
10
10
|
import { RequestMetadata } from "./http/RequestMetadata.js";
|
|
11
11
|
import { AuthorizedServiceCaller } from "./http/AuthorizedServiceCaller.js";
|
|
12
|
-
import DataUnit
|
|
12
|
+
import DataUnit from "./dataunit/DataUnit.js";
|
|
13
|
+
import {SavedRecord, Record, ChangeOperation, DUActionInterceptor, WaitingChange, PageRequest, QuickFilter, SelectionMode, DataUnitEventOptions} from "./dataunit/interfaces/dataUnit.js";
|
|
14
|
+
import { Change } from "./dataunit/Changes.js";
|
|
15
|
+
import { SelectionInfo } from "./dataunit/SelectionInfo.js";
|
|
13
16
|
import { DataType } from "./dataunit/metadata/DataType.js";
|
|
14
17
|
import { UnitMetadata, FieldDescriptor, UserInterface, Sort, SortMode, SortingProvider, Filter, DependencyType, ChildDescriptor, ChildLink } from "./dataunit/metadata/UnitMetadata.js";
|
|
15
18
|
import { DataUnitAction, Action, ExecutionContext } from "./dataunit/state/action/DataUnitAction.js";
|
|
@@ -50,6 +53,7 @@ import { DataUnitLoaderUtils, PaginationInfoBuilderParams } from "./dataunit/loa
|
|
|
50
53
|
import { ColumnFilterManager } from "./utils/ColumnFilterManager.js";
|
|
51
54
|
import { DataUnitInMemoryLoaderConfig, RECORD_DATE_FORMAT } from "./dataunit/loader/DataUnitInMemoryLoaderConfig.js";
|
|
52
55
|
import Base64Utils from "./utils/Base64Utils.js";
|
|
56
|
+
import { LangUtils} from './utils/LangUtils.js';
|
|
53
57
|
|
|
54
58
|
/*Classes públicas no pacote*/
|
|
55
59
|
export {
|
|
@@ -136,5 +140,5 @@ export {
|
|
|
136
140
|
DataUnitInMemoryLoaderConfig,
|
|
137
141
|
RECORD_DATE_FORMAT,
|
|
138
142
|
Base64Utils,
|
|
139
|
-
|
|
143
|
+
LangUtils,
|
|
140
144
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Filter } from '../dataunit/metadata/UnitMetadata.js';
|
|
2
|
-
import DataUnit
|
|
2
|
+
import DataUnit from '../dataunit/DataUnit.js';
|
|
3
|
+
import { Record } from '../dataunit/interfaces/dataUnit.js';
|
|
3
4
|
import { FieldComparator } from '../dataunit/sorting/FieldComparator.js';
|
|
4
5
|
import { LoadDataRequest } from '../dataunit/loading/LoadDataRequest.js';
|
|
5
6
|
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* A classe `LangUtils` fornece métodos utilitários para gerenciar configurações de
|
|
4
|
+
* idioma, incluindo recuperar, definir e aplicar preferências de idioma.
|
|
5
|
+
*/
|
|
6
|
+
export class LangUtils {
|
|
7
|
+
/**
|
|
8
|
+
* Classe estática contendo os códigos de idioma predefinidos.
|
|
9
|
+
*
|
|
10
|
+
* @property PT_BR - Português (Brasil)
|
|
11
|
+
* @property EN_US - Inglês (Estados Unidos)
|
|
12
|
+
* @property ES_ES - Espanhol (Espanha)
|
|
13
|
+
*/
|
|
14
|
+
public static ELanguages = class {
|
|
15
|
+
static PT_BR = "pt_BR";
|
|
16
|
+
static EN_US = "en_US";
|
|
17
|
+
static ES_ES = "es_ES";
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Converte o idioma fornecido para um dos códigos predefinidos.
|
|
22
|
+
*
|
|
23
|
+
* @param lang - O idioma a ser convertido (ex.: "en", "es", "pt-BR").
|
|
24
|
+
* @returns O código de idioma correspondente (ex.: "en_US", "es_ES").
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* LangUtils.convertLanguage("en"); // Retorna "en_US"
|
|
28
|
+
* LangUtils.convertLanguage("es-es"); // Retorna "es_ES"
|
|
29
|
+
*/
|
|
30
|
+
private static convertLanguage(lang: string): string {
|
|
31
|
+
switch (lang.toLocaleLowerCase()) {
|
|
32
|
+
case "en":
|
|
33
|
+
case "en_us":
|
|
34
|
+
case "en-us":
|
|
35
|
+
return LangUtils.ELanguages.EN_US;
|
|
36
|
+
case "es":
|
|
37
|
+
case "es_es":
|
|
38
|
+
case "es-es":
|
|
39
|
+
return LangUtils.ELanguages.ES_ES;
|
|
40
|
+
default:
|
|
41
|
+
return LangUtils.ELanguages.PT_BR;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Captura o idioma atualmente definido. Primeiro verifica se há um idioma
|
|
47
|
+
* armazenado nos cookies. Caso contrário, utiliza o idioma definido no elemento
|
|
48
|
+
* `<html>`. Se nenhum valor for encontrado nos cookies ou no elemento `<html>`,
|
|
49
|
+
* é utilizada a configuração do navegador. Caso o navegador também não forneça
|
|
50
|
+
* um idioma, o padrão será `"pt_BR"`.
|
|
51
|
+
*
|
|
52
|
+
* @returns O idioma definido (ex.: "pt_BR", "en_US").
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* LangUtils.getLanguage(); // Retorna o idioma atual
|
|
56
|
+
*/
|
|
57
|
+
public static getLanguage(): string {
|
|
58
|
+
const cookieLanguage = this.getLanguageFromCookie();
|
|
59
|
+
|
|
60
|
+
if (cookieLanguage) {
|
|
61
|
+
return this.convertLanguage(cookieLanguage);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return this.getHtmlLanguage();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Recupera o valor do atributo `lang` do elemento `<html>`. Se o ambiente
|
|
69
|
+
* estiver em modo de desenvolvimento, o idioma padrão será `"pt_BR"`. Caso
|
|
70
|
+
* contrário, utiliza o idioma do navegador ou `"pt-BR"` como padrão.
|
|
71
|
+
*
|
|
72
|
+
* @returns O idioma definido no elemento `<html>` ou o padrão.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* LangUtils.getHtmlLanguage(); // Retorna "pt_BR" no modo desenvolvimento
|
|
76
|
+
*/
|
|
77
|
+
public static getHtmlLanguage(): string {
|
|
78
|
+
if (process.env.NODE_ENV === 'development') {
|
|
79
|
+
return LangUtils.ELanguages.PT_BR;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const lang = document.documentElement.lang || navigator.language || "pt-BR";
|
|
83
|
+
|
|
84
|
+
return this.convertLanguage(lang);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Define o atributo `lang` no elemento `<html>` e atualiza o cookie de idioma.
|
|
89
|
+
*
|
|
90
|
+
* @param language - O idioma a ser definido (ex.: "pt_BR", "en_US").
|
|
91
|
+
*
|
|
92
|
+
* > **Nota:** Definir o idioma no elemento `<html>` é essencial para garantir que o conteúdo
|
|
93
|
+
* da página seja interpretado corretamente por navegadores, leitores de tela e mecanismos de
|
|
94
|
+
* busca, melhorando a acessibilidade e a indexação.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* LangUtils.setHtmlLanguage("en_US"); // Define o idioma como "en_US"
|
|
98
|
+
*/
|
|
99
|
+
public static setHtmlLanguage(language: string): void {
|
|
100
|
+
document.documentElement.lang = language;
|
|
101
|
+
document.cookie = `lang=${language}; path=/;`;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Recupera o valor do cookie de idioma.
|
|
106
|
+
*
|
|
107
|
+
* @returns O valor do cookie de idioma ou `null` se não existir.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* LangUtils.getLanguageFromCookie(); // Retorna "pt_BR" se o cookie existir
|
|
111
|
+
*/
|
|
112
|
+
public static getLanguageFromCookie(): string | null {
|
|
113
|
+
const match = document.cookie.match(new RegExp('(^| )lang=([^;]+)'));
|
|
114
|
+
return match ? match[2] : null;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Define o atributo `lang` no elemento `<html>` com base no cookie de idioma, se existir.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* LangUtils.applyLanguageFromCookie(); // Aplica o idioma do cookie ao elemento `<html>`
|
|
122
|
+
*/
|
|
123
|
+
public static applyLanguageFromCookie(): void {
|
|
124
|
+
const langFromCookie = this.getLanguageFromCookie();
|
|
125
|
+
if (langFromCookie) {
|
|
126
|
+
this.setHtmlLanguage(langFromCookie);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import DataUnit from "../dataunit/DataUnit.js";
|
|
2
2
|
import { FieldDescriptor, Sort, SortMode } from "../dataunit/metadata/UnitMetadata.js";
|
|
3
3
|
import { FieldComparator } from "../dataunit/sorting/FieldComparator.js";
|
|
4
|
-
import { Record } from '../dataunit/
|
|
4
|
+
import { Record } from '../dataunit/interfaces/dataUnit.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* `SortingUtils`: Utilizado para auxiliar na ordenacao de registros.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import DataUnit from "../../src/dataunit/DataUnit";
|
|
2
|
+
import { createDataUnitMock } from "./loader/utils/createDataUnitMock";
|
|
3
|
+
import { metadata } from "./resources/metadata";
|
|
4
|
+
|
|
5
|
+
describe('Access parent dataUnits', () => {
|
|
6
|
+
let dataUnit: DataUnit;
|
|
7
|
+
let metadataLoaderMock = jest.fn();
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
jest.clearAllMocks();
|
|
11
|
+
window.requestAnimationFrame = (functionCallback: Function) => functionCallback();
|
|
12
|
+
({ dataUnit, metadataLoaderMock } = createDataUnitMock());
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
describe('getChildInfo', () => {
|
|
16
|
+
beforeEach(async () => {
|
|
17
|
+
await dataUnit.loadMetadata();
|
|
18
|
+
await dataUnit.loadData();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should return metadata children data', () => {
|
|
22
|
+
const name = dataUnit.getChildInfo('child');
|
|
23
|
+
expect(name).toStrictEqual(metadata.children![0]);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should return undefined when dont has metadata', async () => {
|
|
27
|
+
metadataLoaderMock.mockResolvedValue(undefined);
|
|
28
|
+
await dataUnit.loadMetadata();
|
|
29
|
+
const name = dataUnit.getChildInfo('child');
|
|
30
|
+
expect(name).toBeUndefined();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should return undefined when dont has metadata children data', async () => {
|
|
34
|
+
metadataLoaderMock.mockResolvedValue({ ...metadata, children: undefined });
|
|
35
|
+
await dataUnit.loadMetadata();
|
|
36
|
+
const name = dataUnit.getChildInfo('child');
|
|
37
|
+
expect(name).toBeUndefined();
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('getParentDataUnit', () => {
|
|
42
|
+
it('should return parent dataUnit', () => {
|
|
43
|
+
const childDataUnit = new DataUnit('child', dataUnit);
|
|
44
|
+
const parentDataUnit = childDataUnit.getParentDataUnit();
|
|
45
|
+
expect(parentDataUnit).toStrictEqual(dataUnit);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe('isParentDirty', () => {
|
|
50
|
+
it('should return true when parent is dirty', async () => {
|
|
51
|
+
dataUnit.selectFirst();
|
|
52
|
+
await dataUnit.setFieldValue('column_name_1', 'new_value');
|
|
53
|
+
const childDataUnit = new DataUnit('child', dataUnit);
|
|
54
|
+
const parentIsDirty = childDataUnit.isParentDirty();
|
|
55
|
+
expect(parentIsDirty).toBeTruthy();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should return false when parent is not dirty', () => {
|
|
59
|
+
const childDataUnit = new DataUnit('child', dataUnit);
|
|
60
|
+
const parentIsDirty = childDataUnit.isParentDirty();
|
|
61
|
+
expect(parentIsDirty).toBeFalsy();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('should return false when dont has parent', () => {
|
|
65
|
+
const parentIsDirty = dataUnit.isParentDirty();
|
|
66
|
+
expect(parentIsDirty).toBeFalsy();
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
});
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import DataUnit from "../../src/dataunit/DataUnit";
|
|
2
|
+
import { Action, DataUnitAction } from "../../src/dataunit/state/action/DataUnitAction";
|
|
3
|
+
import { createDataUnitMock } from "./loader/utils/createDataUnitMock";
|
|
4
|
+
import { recordsTest } from "./resources/records";
|
|
5
|
+
|
|
6
|
+
describe('Actions', () => {
|
|
7
|
+
let dataUnit: DataUnit;
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
jest.clearAllMocks();
|
|
11
|
+
window.requestAnimationFrame = (functionCallback: Function) => functionCallback();
|
|
12
|
+
({ dataUnit } = createDataUnitMock());
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
describe('savingCanceled', () => {
|
|
16
|
+
it('should emit event savingCanceled', async () => {
|
|
17
|
+
const savingCanceled = jest.fn();
|
|
18
|
+
const observer = async (action: DataUnitAction) => {
|
|
19
|
+
if (action.type === Action.SAVING_CANCELED) {
|
|
20
|
+
savingCanceled();
|
|
21
|
+
}
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
dataUnit.subscribe(observer);
|
|
25
|
+
dataUnit.selectFirst();
|
|
26
|
+
await dataUnit.setFieldValue('column_name_1', 'new_value');
|
|
27
|
+
dataUnit.savingCanceled([{ name: 'column_name_1', message: 'cancel_saving' }], 'test_1');
|
|
28
|
+
expect(savingCanceled).toHaveBeenCalled();
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe('clearInvalid', () => {
|
|
33
|
+
beforeEach(async () => {
|
|
34
|
+
await dataUnit.loadMetadata();
|
|
35
|
+
await dataUnit.loadData();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should emit event savingCanceled', async () => {
|
|
39
|
+
const invalidateClean = jest.fn();
|
|
40
|
+
const observer = async (action: DataUnitAction) => {
|
|
41
|
+
if (action.type === Action.INVALIDATE_CLEAN) {
|
|
42
|
+
invalidateClean();
|
|
43
|
+
}
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
dataUnit.subscribe(observer);
|
|
47
|
+
dataUnit.selectFirst();
|
|
48
|
+
await dataUnit.setFieldValue('column_name_1', 'new_value');
|
|
49
|
+
dataUnit.clearInvalid('test_1', 'column_name_1');
|
|
50
|
+
expect(invalidateClean).toHaveBeenCalled();
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe('redo', () => {
|
|
55
|
+
beforeEach(async () => {
|
|
56
|
+
await dataUnit.loadMetadata();
|
|
57
|
+
await dataUnit.loadData();
|
|
58
|
+
const saveLoaderMock = jest.fn().mockResolvedValue(recordsTest);
|
|
59
|
+
dataUnit.saveLoader = saveLoaderMock;
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
it('should return true when field value changes can redo', async () => {
|
|
64
|
+
dataUnit.selectFirst();
|
|
65
|
+
await dataUnit.setFieldValue('column_name_1', 'new_value');
|
|
66
|
+
dataUnit.undo();
|
|
67
|
+
let fieldValue = dataUnit.getFieldValue('column_name_1');
|
|
68
|
+
expect(fieldValue).toBe('column_value_1');
|
|
69
|
+
dataUnit.redo();
|
|
70
|
+
fieldValue = dataUnit.getFieldValue('column_name_1');
|
|
71
|
+
expect(fieldValue).toBe('new_value');
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Change } from "../../src/dataunit/Changes";
|
|
2
|
+
import { ChangeOperation } from "../../src/dataunit/interfaces/dataUnit";
|
|
3
|
+
|
|
4
|
+
describe('Change', () => {
|
|
5
|
+
let change: Change;
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
change = new Change(
|
|
8
|
+
'test',
|
|
9
|
+
{ __record__id__: 'test_1' },
|
|
10
|
+
undefined,
|
|
11
|
+
ChangeOperation.COPY,
|
|
12
|
+
'source_id',
|
|
13
|
+
);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should return operation', () => {
|
|
17
|
+
const response = change.operation;
|
|
18
|
+
expect(response).toBe('COPY');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should return false when operation is not insert', () => {
|
|
22
|
+
const response = change.isInsert();
|
|
23
|
+
expect(response).toBeFalsy();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should return true when operation is insert', () => {
|
|
27
|
+
change = new Change(
|
|
28
|
+
'test',
|
|
29
|
+
{ __record__id__: 'test_1' },
|
|
30
|
+
undefined,
|
|
31
|
+
ChangeOperation.INSERT,
|
|
32
|
+
'source_id',
|
|
33
|
+
);
|
|
34
|
+
const response = change.isInsert();
|
|
35
|
+
expect(response).toBeTruthy();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should return true when operation is copy', () => {
|
|
39
|
+
const response = change.isCopy();
|
|
40
|
+
expect(response).toBeTruthy();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should return true when operation is delete', () => {
|
|
44
|
+
change = new Change(
|
|
45
|
+
'test',
|
|
46
|
+
{ __record__id__: 'test_1' },
|
|
47
|
+
undefined,
|
|
48
|
+
ChangeOperation.DELETE,
|
|
49
|
+
'source_id',
|
|
50
|
+
);
|
|
51
|
+
const response = change.isDelete();
|
|
52
|
+
expect(response).toBeTruthy();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('should return true when operation is update', () => {
|
|
56
|
+
change = new Change(
|
|
57
|
+
'test',
|
|
58
|
+
{ __record__id__: 'test_1' },
|
|
59
|
+
undefined,
|
|
60
|
+
ChangeOperation.UPDATE,
|
|
61
|
+
'source_id',
|
|
62
|
+
);
|
|
63
|
+
const response = change.isUpdate();
|
|
64
|
+
expect(response).toBeTruthy();
|
|
65
|
+
});
|
|
66
|
+
});
|