@sankhyalabs/core 5.10.1 → 5.11.0-dev.2
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/ApplicationContext.md +3 -3
- package/.docs/classes/Change.md +11 -11
- package/.docs/classes/DataUnit.md +204 -121
- package/.docs/classes/DateUtils.md +11 -11
- package/.docs/classes/FieldComparator.md +87 -0
- package/.docs/classes/IDBRepository.md +518 -0
- package/.docs/classes/SelectionInfo.md +11 -11
- package/.docs/classes/SkwHttpProvider.md +7 -7
- package/.docs/classes/StringUtils.md +2 -2
- package/.docs/enums/Action.md +33 -22
- package/.docs/enums/ChangeOperation.md +4 -4
- package/.docs/enums/DataType.md +5 -5
- package/.docs/enums/SelectionMode.md +2 -2
- package/.docs/interfaces/DUActionInterceptor.md +1 -1
- package/.docs/interfaces/ILoadResult.md +36 -0
- package/.docs/interfaces/IRepository.md +245 -0
- package/.docs/interfaces/IRepositoryIndex.md +66 -0
- package/.docs/interfaces/LoadDataRequest.md +20 -7
- package/.docs/interfaces/PageRequest.md +3 -3
- package/.docs/interfaces/PaginationInfo.md +16 -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/SortingProvider.md +2 -1
- package/.docs/interfaces/WaitingChange.md +3 -3
- package/.docs/modules.md +5 -0
- package/dist/dataunit/DataUnit.d.ts +20 -2
- package/dist/dataunit/DataUnit.js +32 -9
- package/dist/dataunit/DataUnit.js.map +1 -1
- package/dist/dataunit/DataUnitHelper.js +1 -1
- package/dist/dataunit/DataUnitHelper.js.map +1 -1
- package/dist/dataunit/loading/LoadDataRequest.d.ts +2 -0
- package/dist/dataunit/loading/PaginationInfo.d.ts +4 -2
- package/dist/dataunit/metadata/DataType.d.ts +2 -0
- package/dist/dataunit/metadata/DataType.js +38 -0
- package/dist/dataunit/metadata/DataType.js.map +1 -1
- package/dist/dataunit/metadata/UnitMetadata.d.ts +1 -1
- package/dist/dataunit/sorting/FieldComparator.d.ts +7 -0
- package/dist/dataunit/sorting/FieldComparator.js +25 -0
- package/dist/dataunit/sorting/FieldComparator.js.map +1 -0
- package/dist/dataunit/state/action/DataUnitAction.d.ts +1 -0
- package/dist/dataunit/state/action/DataUnitAction.js +1 -0
- package/dist/dataunit/state/action/DataUnitAction.js.map +1 -1
- package/dist/dataunit/state/slice/InvalidFieldsSlice.js.map +1 -1
- package/dist/dataunit/state/slice/LoadingControlSlice.js +3 -1
- package/dist/dataunit/state/slice/LoadingControlSlice.js.map +1 -1
- package/dist/dataunit/state/slice/SelectionSlice.js +1 -1
- package/dist/dataunit/state/slice/SelectionSlice.js.map +1 -1
- package/dist/http/SkwHttpProvider.js +6 -6
- package/dist/http/SkwHttpProvider.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/repository/ILoadResult.d.ts +4 -0
- package/dist/repository/ILoadResult.js +2 -0
- package/dist/repository/ILoadResult.js.map +1 -0
- package/dist/repository/IRepository.d.ts +74 -0
- package/dist/repository/IRepository.js +2 -0
- package/dist/repository/IRepository.js.map +1 -0
- package/dist/repository/indexeddb/IDBRepository.d.ts +49 -0
- package/dist/repository/indexeddb/IDBRepository.js +344 -0
- package/dist/repository/indexeddb/IDBRepository.js.map +1 -0
- package/dist/repository/indexeddb/IRepositoryIndex.d.ts +4 -0
- package/dist/repository/indexeddb/IRepositoryIndex.js +2 -0
- package/dist/repository/indexeddb/IRepositoryIndex.js.map +1 -0
- package/dist/traking/ErrorTraking.js +1 -1
- package/dist/traking/ErrorTraking.js.map +1 -1
- package/dist/ui/FloatingManager.js +1 -1
- package/dist/ui/FloatingManager.js.map +1 -1
- package/dist/utils/ApplicationContext.js.map +1 -1
- package/dist/utils/DateUtils.js.map +1 -1
- package/dist/utils/ElementIDUtils.js +2 -2
- package/dist/utils/ElementIDUtils.js.map +1 -1
- package/dist/utils/NumberUtils.js +2 -2
- package/dist/utils/NumberUtils.js.map +1 -1
- package/dist/utils/StringUtils.js +4 -5
- package/dist/utils/StringUtils.js.map +1 -1
- package/package.json +2 -1
- package/src/dataunit/DataUnit.ts +38 -13
- package/src/dataunit/DataUnitHelper.ts +1 -2
- package/src/dataunit/loading/LoadDataRequest.ts +3 -0
- package/src/dataunit/loading/PaginationInfo.ts +5 -2
- package/src/dataunit/metadata/DataType.ts +48 -1
- package/src/dataunit/metadata/UnitMetadata.ts +2 -2
- package/src/dataunit/sorting/FieldComparator.ts +38 -0
- package/src/dataunit/state/action/DataUnitAction.ts +1 -0
- package/src/dataunit/state/slice/InvalidFieldsSlice.ts +0 -1
- package/src/dataunit/state/slice/LoadingControlSlice.ts +3 -1
- package/src/dataunit/state/slice/SelectionSlice.ts +1 -1
- package/src/http/SkwHttpProvider.ts +6 -9
- package/src/index.ts +10 -0
- package/src/repository/ILoadResult.ts +4 -0
- package/src/repository/IRepository.ts +82 -0
- package/src/repository/indexeddb/IDBRepository.ts +355 -0
- package/src/repository/indexeddb/IRepositoryIndex.ts +4 -0
- package/src/traking/ErrorTraking.ts +1 -1
- package/src/ui/FloatingManager.ts +1 -1
- package/src/utils/ApplicationContext.ts +0 -2
- package/src/utils/DateUtils.ts +0 -2
- package/src/utils/ElementIDUtils.ts +2 -2
- package/src/utils/NumberUtils.ts +2 -2
- package/src/utils/StringUtils.ts +4 -5
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { ILoadResult } from "./ILoadResult.js";
|
|
2
|
+
|
|
3
|
+
export interface IRepository<T>{
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Recupera registros do repositório
|
|
7
|
+
*
|
|
8
|
+
* @param filterFunction - Teste para determinar se um registro está no universo desejado
|
|
9
|
+
* @param sortingFunction - Critério comparação para ordenação
|
|
10
|
+
* @param offset - Determina que o resultado descarta os registros iniciais
|
|
11
|
+
* @param limit - Descarta o resultado a partir de uma quantidade de registros
|
|
12
|
+
* @returns Promessa de um array que satisfaça aos critérios informados
|
|
13
|
+
*/
|
|
14
|
+
load(filterFunction?: (value: T) => boolean, sortingFunction?: (itemA: T, itemB: T) => number, offset?: number, limit?: number): Promise<ILoadResult<T>>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
* Itera todos os items colecionando os valores distintos.
|
|
19
|
+
*
|
|
20
|
+
* @param itemProcessor - Uma função que processa um item e gera a chave e valor
|
|
21
|
+
* @returns Promessa de array com os valores distintos.
|
|
22
|
+
*/
|
|
23
|
+
distict(itemProcessor: (item: T) => {key: string, value: any}): Promise<Map<string, any>>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Adiciona registros no final do repositório
|
|
27
|
+
*
|
|
28
|
+
* @param items - Os items a serem adicionados
|
|
29
|
+
* @returns Promessa de execução
|
|
30
|
+
*/
|
|
31
|
+
push(items: Array<T>): Promise<void>;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Limpa todo o repositório
|
|
35
|
+
*
|
|
36
|
+
* @returns Promessa de execução
|
|
37
|
+
*/
|
|
38
|
+
clear(): Promise<void>;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Remove itens do repositório
|
|
42
|
+
*
|
|
43
|
+
* @param items - Os itens a serem removidos
|
|
44
|
+
* @returns Promessa de execução
|
|
45
|
+
*/
|
|
46
|
+
delete(items: Array<T>): Promise<void>;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Altera itens já persistido no repositório
|
|
50
|
+
*
|
|
51
|
+
* @param items - Os itens a serem alterados
|
|
52
|
+
* @returns Promessa de execução
|
|
53
|
+
*/
|
|
54
|
+
update(items: Array<T>): Promise<void>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Insere itens em uma posição de referência
|
|
58
|
+
*
|
|
59
|
+
* @param itemReference - O item posterior aos inseridos
|
|
60
|
+
* @param items - Os itens a serem inseridos
|
|
61
|
+
* @returns Promessa de execução
|
|
62
|
+
*/
|
|
63
|
+
insert(itemReference: T, items: Array<T>): Promise<void>;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Determina se o repositório está em condições normais de funcionamento.
|
|
67
|
+
* Caso o banco tenha sido excluido, retorna false.
|
|
68
|
+
*/
|
|
69
|
+
isOperating(): boolean;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Determina se o repositório está vazio ou ainda não foi criado.
|
|
73
|
+
*/
|
|
74
|
+
isEmpty(): Promise<boolean>;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Conta os itens do repositório
|
|
78
|
+
*
|
|
79
|
+
* @returns Promessa de quantidade
|
|
80
|
+
*/
|
|
81
|
+
count(): Promise<number>;
|
|
82
|
+
}
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
import ErrorException from "../../exceptions/ErrorException.js";
|
|
2
|
+
import { ILoadResult } from "../ILoadResult.js";
|
|
3
|
+
import { openDB, IDBPDatabase, IDBPTransaction } from 'idb';
|
|
4
|
+
import { IRepositoryIndex } from "./IRepositoryIndex.js";
|
|
5
|
+
import { IRepository } from "../IRepository.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Abstração para simplificar o uso do indexed DB
|
|
9
|
+
*
|
|
10
|
+
* Além de facilitar os comandos de incluir, remover alterar e obter
|
|
11
|
+
* objetos, esse repositório preserva a ordem de inserção na lista,
|
|
12
|
+
* além de permitir filtros e ordenações compostas
|
|
13
|
+
* (impossíveis com uso de índices).
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
export class IDBRepository<T> implements IRepository<T>{
|
|
17
|
+
|
|
18
|
+
private _dbName: string;
|
|
19
|
+
private _dbVersion: number;
|
|
20
|
+
private _storeName: string;
|
|
21
|
+
private _addedStoreName: string;
|
|
22
|
+
private _indexKeyPath: string;
|
|
23
|
+
private _indexes?: Array<IRepositoryIndex>;
|
|
24
|
+
private _db?: IDBPDatabase;
|
|
25
|
+
private _operating: boolean = true;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Construtor padrão
|
|
29
|
+
*
|
|
30
|
+
* @param dbName - Nome do DB
|
|
31
|
+
* @param dbVersion - Versão do DB
|
|
32
|
+
* @param storeName - Nome da store
|
|
33
|
+
* @param indexKeyPath - Um atributo que identifique os objetos guardados
|
|
34
|
+
*/
|
|
35
|
+
constructor(dbName: string, dbVersion: number, storeName: string, indexKeyPath: string, indexes?: Array<IRepositoryIndex>){
|
|
36
|
+
this._dbName = dbName;
|
|
37
|
+
this._dbVersion = dbVersion;
|
|
38
|
+
this._storeName = storeName;
|
|
39
|
+
this._addedStoreName = `${this._storeName}_ADDED__[REPOSITORY]`;
|
|
40
|
+
this._indexKeyPath = indexKeyPath;
|
|
41
|
+
this._indexes = indexes;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public async load(filterFunction?: (value: T) => boolean, sortingFunction?: (itemA: T, itemB: T) => number, offset?: number, limit?: number): Promise<ILoadResult<T>>{
|
|
45
|
+
try{
|
|
46
|
+
const db = await this.openDB();
|
|
47
|
+
const addedItems: Array<IAddedItem<T>> = await this.getAddedItems(db);
|
|
48
|
+
|
|
49
|
+
const tx = db.transaction(this._storeName);
|
|
50
|
+
let cursor = await tx.objectStore(this._storeName).openCursor();
|
|
51
|
+
const collectedValues: Array<T> = [];
|
|
52
|
+
let itemsCount: number = 0;
|
|
53
|
+
|
|
54
|
+
while (cursor) {
|
|
55
|
+
appendResult(
|
|
56
|
+
addedItems
|
|
57
|
+
.filter(addedItem => addedItem.position === itemsCount)
|
|
58
|
+
.map(addedItems => addedItems.item),
|
|
59
|
+
collectedValues,
|
|
60
|
+
filterFunction
|
|
61
|
+
);
|
|
62
|
+
appendResult(cursor.value, collectedValues, filterFunction);
|
|
63
|
+
itemsCount++;
|
|
64
|
+
cursor = await cursor.continue();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const returnValue = sortingFunction != undefined ? collectedValues.sort(sortingFunction) : collectedValues;
|
|
68
|
+
const start = offset||0;
|
|
69
|
+
const end = limit ? start + limit : returnValue.length;
|
|
70
|
+
|
|
71
|
+
return Promise.resolve({result: returnValue.slice(start, end), count: collectedValues.length});
|
|
72
|
+
} catch (error){
|
|
73
|
+
console.error(error);
|
|
74
|
+
throw new ErrorException("Erro ao buscar itens", `Não foi possível listar a store "${this._storeName}". Verifique o console para maiores detalhes.`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public async distict(itemProcessor: (item: T) => {key: string, value: any}): Promise<Map<string, any>>{
|
|
79
|
+
try{
|
|
80
|
+
const db = await this.openDB();
|
|
81
|
+
const tx = db.transaction([this._storeName, this._addedStoreName]);
|
|
82
|
+
|
|
83
|
+
const itemCollector = {
|
|
84
|
+
result: new Map<string, any>,
|
|
85
|
+
collect: (item: T) => {
|
|
86
|
+
const processedItem = itemProcessor(item);
|
|
87
|
+
if(processedItem != undefined){
|
|
88
|
+
itemCollector.result.set(processedItem.key, processedItem.value);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
await iterateStore(this._storeName, tx, value => itemCollector.collect(value));
|
|
94
|
+
await iterateStore(this._addedStoreName, tx, value => itemCollector.collect(value.item));
|
|
95
|
+
|
|
96
|
+
return Promise.resolve(itemCollector.result);
|
|
97
|
+
} catch (error){
|
|
98
|
+
console.error(error);
|
|
99
|
+
throw new ErrorException("Erro ao buscar distinct", `Não foi possível listar a store "${this._storeName}". Verifique o console para maiores detalhes.`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
public async push(items: Array<T>): Promise<void>{
|
|
104
|
+
if(items == undefined || items.length === 0){
|
|
105
|
+
return Promise.resolve();
|
|
106
|
+
}
|
|
107
|
+
try{
|
|
108
|
+
const db = await this.openDB();
|
|
109
|
+
return new Promise((accept, reject) =>{
|
|
110
|
+
Promise.all(items.map(item => db.add(this._storeName, item)))
|
|
111
|
+
.then(()=>accept())
|
|
112
|
+
.catch(reason => {
|
|
113
|
+
console.error(reason);
|
|
114
|
+
reject(new ErrorException("Erro ao adicionar registro", `Não foi possível adicionar registros no repositório ${this._storeName}. Verifique o console para maiores detalhes.`));
|
|
115
|
+
})
|
|
116
|
+
});
|
|
117
|
+
} catch (error){
|
|
118
|
+
console.error(error);
|
|
119
|
+
throw new ErrorException("Erro ao adicionar registro", `Não foi possível adicionar registros no repositório ${this._storeName}. Verifique o console para maiores detalhes.`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
public async clear(): Promise<void>{
|
|
124
|
+
try{
|
|
125
|
+
const db = await this.openDB();
|
|
126
|
+
[this._storeName, this._addedStoreName].forEach(storeName => {
|
|
127
|
+
if(db.objectStoreNames.contains(storeName)){
|
|
128
|
+
db.clear(storeName);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
return Promise.resolve();
|
|
132
|
+
} catch (error){
|
|
133
|
+
console.error(error);
|
|
134
|
+
throw new ErrorException("Erro ao limpar repositório", `Limpar o repositório ${this._storeName}. Verifique o console para maiores detalhes.`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
public async delete(items: Array<T>): Promise<void>{
|
|
139
|
+
try{
|
|
140
|
+
const db = await this.openDB();
|
|
141
|
+
const tx = db.transaction([this._storeName, this._addedStoreName], "readwrite");
|
|
142
|
+
const addedStore = tx.objectStore(this._addedStoreName);
|
|
143
|
+
const store = tx.objectStore(this._storeName);
|
|
144
|
+
|
|
145
|
+
items.forEach(async item => {
|
|
146
|
+
let key = await addedStore.index(this._indexKeyPath).getKey(IDBKeyRange.only((item as any)[this._indexKeyPath]));
|
|
147
|
+
if(key != undefined){
|
|
148
|
+
addedStore.delete(key);
|
|
149
|
+
} else {
|
|
150
|
+
key = await store.index(this._indexKeyPath).getKey(IDBKeyRange.only((item as any)[this._indexKeyPath]));
|
|
151
|
+
if(key == undefined){
|
|
152
|
+
throw new ErrorException("Erro interno: Erro ao remover itens", "Tentando remover um item que não está no repositório.");
|
|
153
|
+
}
|
|
154
|
+
store.delete(key);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
return Promise.resolve();
|
|
159
|
+
} catch (error){
|
|
160
|
+
console.error(error);
|
|
161
|
+
throw new ErrorException("Erro ao remover itens", `Verifique o console para maiores detalhes.`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
public async update(items: Array<T>): Promise<void>{
|
|
166
|
+
try{
|
|
167
|
+
const db = await this.openDB();
|
|
168
|
+
|
|
169
|
+
const tx = db.transaction([this._storeName, this._addedStoreName], "readwrite");
|
|
170
|
+
const addedStore = tx.objectStore(this._addedStoreName);
|
|
171
|
+
const store = tx.objectStore(this._storeName);
|
|
172
|
+
|
|
173
|
+
items.forEach(async item => {
|
|
174
|
+
let key = await addedStore.index(this._indexKeyPath).getKey(IDBKeyRange.only((item as any)[this._indexKeyPath]));
|
|
175
|
+
if(key != undefined){
|
|
176
|
+
const {position} = await addedStore.get(IDBKeyRange.only(key)) as IAddedItem<T>;
|
|
177
|
+
addedStore.put({position, item}, key);
|
|
178
|
+
} else {
|
|
179
|
+
key = await store.index(this._indexKeyPath).getKey(IDBKeyRange.only((item as any)[this._indexKeyPath]));
|
|
180
|
+
if(key == undefined){
|
|
181
|
+
throw new ErrorException("Erro interno: Erro ao alterar itens", "Tentando modificar um item que não está no repositório.");
|
|
182
|
+
}
|
|
183
|
+
store.put(item, key);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
return Promise.resolve();
|
|
188
|
+
} catch (error){
|
|
189
|
+
console.error(error);
|
|
190
|
+
throw new ErrorException("Erro ao alterar itens", `Verifique o console para maiores detalhes.`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
public async insert(itemReference: T, items: Array<T>): Promise<void>{
|
|
195
|
+
try{
|
|
196
|
+
const db = await this.openDB();
|
|
197
|
+
const position = await this.getItemPosition(db, item => item[this._indexKeyPath] === (itemReference as any)[this._indexKeyPath]);
|
|
198
|
+
if(position == -1){
|
|
199
|
+
console.error(itemReference);
|
|
200
|
+
return Promise.reject("Erro interno: Item de referência não localizado na inclusão");
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
items.forEach(item =>{
|
|
204
|
+
const tx = db.transaction(this._addedStoreName, "readwrite");
|
|
205
|
+
tx.objectStore(this._addedStoreName).add({item, position});
|
|
206
|
+
});
|
|
207
|
+
return Promise.resolve();
|
|
208
|
+
} catch (error){
|
|
209
|
+
console.error(error);
|
|
210
|
+
throw new ErrorException("Falha ao tentar inserir item", `Verifique o console para maiores detalhes.`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
public isOperating(): boolean{
|
|
215
|
+
return this._operating;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
public async isEmpty(): Promise<boolean>{
|
|
219
|
+
try{
|
|
220
|
+
if((await indexedDB.databases()).find(db => db.name === this._dbName) == undefined){
|
|
221
|
+
return Promise.resolve(false);
|
|
222
|
+
}
|
|
223
|
+
const db = await this.openDB();
|
|
224
|
+
if(!db.objectStoreNames.contains(this._storeName)){
|
|
225
|
+
return Promise.resolve(false);
|
|
226
|
+
}
|
|
227
|
+
const tx = db.transaction(this._storeName);
|
|
228
|
+
const store = tx.objectStore(this._storeName);
|
|
229
|
+
return Promise.resolve(await store.count() === 0);
|
|
230
|
+
} catch (error){
|
|
231
|
+
console.error(error);
|
|
232
|
+
throw new ErrorException("Falha ao verificar se o repositório está vazio", `Verifique o console para maiores detalhes.`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
public async count(): Promise<number>{
|
|
237
|
+
try{
|
|
238
|
+
if((await indexedDB.databases()).find(db => db.name === this._dbName) == undefined){
|
|
239
|
+
return Promise.resolve(0);
|
|
240
|
+
}
|
|
241
|
+
const db = await this.openDB();
|
|
242
|
+
const tx = db.transaction([this._storeName, this._addedStoreName]);
|
|
243
|
+
return Promise.resolve(await tx.objectStore(this._storeName).count() + await tx.objectStore(this._addedStoreName).count());
|
|
244
|
+
} catch (error){
|
|
245
|
+
console.error(error);
|
|
246
|
+
throw new ErrorException("Falha ao contar itens do repositório", `Verifique o console para maiores detalhes.`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
private async openDB(): Promise<IDBPDatabase>{
|
|
251
|
+
try{
|
|
252
|
+
if(this._db){
|
|
253
|
+
return this._db;
|
|
254
|
+
}
|
|
255
|
+
this._db = await openDB(this._dbName, this._dbVersion, {
|
|
256
|
+
upgrade: (db) => {
|
|
257
|
+
this.createStore(db, this._storeName);
|
|
258
|
+
this.createStore(db, this._addedStoreName, "item.");
|
|
259
|
+
},
|
|
260
|
+
terminated: () => {
|
|
261
|
+
this._operating = false;
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
return this._db;
|
|
265
|
+
} catch (error){
|
|
266
|
+
console.error(error);
|
|
267
|
+
throw new ErrorException("Erro interno: Falha ao tentar abrir o indexedDB", `Verifique o console para maiores detalhes.`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
private createStore(db: IDBPDatabase, name: string, indexPrefix: string = "") {
|
|
272
|
+
if(!db.objectStoreNames.contains(name)){
|
|
273
|
+
const store = db.createObjectStore(name, {autoIncrement: true});
|
|
274
|
+
store.createIndex(this._indexKeyPath, `${indexPrefix}${this._indexKeyPath}`, {unique: true});
|
|
275
|
+
if(this._indexes == undefined || this._indexes.length === 0){
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
this._indexes.forEach(index => {
|
|
279
|
+
store.createIndex(index.name, `${indexPrefix}${index.path}`, index);
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
private async getItemPosition(db: IDBPDatabase, itemTest: (item: any) => boolean): Promise<number>{
|
|
285
|
+
|
|
286
|
+
const addedIndex = await this.getItemPositionByAdded(db, itemTest);
|
|
287
|
+
if(addedIndex > -1){
|
|
288
|
+
return Promise.resolve(addedIndex);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const tx = db.transaction(this._storeName);
|
|
292
|
+
let cursor = await tx.objectStore(this._storeName).openCursor();
|
|
293
|
+
let found: boolean = false;
|
|
294
|
+
let position = 0;
|
|
295
|
+
while (cursor) {
|
|
296
|
+
if(itemTest(cursor.value)){
|
|
297
|
+
found = true;
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
position++;
|
|
301
|
+
cursor = await cursor.continue();
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return Promise.resolve(found ? position : -1);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
private async getItemPositionByAdded(db: IDBPDatabase, itemTest: (item: any) => boolean): Promise<number>{
|
|
308
|
+
const addedItems: Array<IAddedItem<T>> = await this.getAddedItems(db);
|
|
309
|
+
if(addedItems && addedItems.length > 0){
|
|
310
|
+
const foundItem = addedItems.find(addedItem => itemTest(addedItem.item))
|
|
311
|
+
if(foundItem != null){
|
|
312
|
+
return Promise.resolve(foundItem.position);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return Promise.resolve(-1);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
private async getAddedItems(db: IDBPDatabase): Promise<Array<IAddedItem<T>>>{
|
|
320
|
+
const tx = db.transaction(this._addedStoreName);
|
|
321
|
+
return tx.objectStore(this._addedStoreName).getAll();
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Metodo utilitário usado para iterar uma store.
|
|
327
|
+
*/
|
|
328
|
+
const iterateStore = async (storeName: string, tx: IDBPTransaction, callBack: (value: any) => void) =>{
|
|
329
|
+
let cursor = await tx.objectStore(storeName).openCursor();
|
|
330
|
+
while (cursor) {
|
|
331
|
+
callBack(cursor.value);
|
|
332
|
+
cursor = await cursor.continue();
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Metodo utilitário usado para simplificar a lógica de coletar valores considerando um filtro.
|
|
338
|
+
*/
|
|
339
|
+
const appendResult = <T>(toAppend: Array<T>|T, collectedValues: Array<T>, filterFunction?: (value: T) => boolean) => {
|
|
340
|
+
if(toAppend != undefined){
|
|
341
|
+
(Array.isArray(toAppend) ? toAppend : [toAppend]).forEach(item => {
|
|
342
|
+
if(filterFunction == undefined || filterFunction(item)){
|
|
343
|
+
collectedValues.push(item);
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Interface usada para armazenar items adicionados e a posição onde eles devem ficar.
|
|
351
|
+
*/
|
|
352
|
+
interface IAddedItem<T>{
|
|
353
|
+
item: T;
|
|
354
|
+
position: number
|
|
355
|
+
}
|
|
@@ -17,7 +17,7 @@ export class ErrorTracking {
|
|
|
17
17
|
const rollbar = (window as any).Rollbar;
|
|
18
18
|
if(rollbar){
|
|
19
19
|
rollbar.configure({
|
|
20
|
-
checkIgnore: function(isUncaught:boolean, args:Array<any>,
|
|
20
|
+
checkIgnore: function(isUncaught:boolean, args:Array<any>, _payload:any) {
|
|
21
21
|
return args[1] ? ErrorTracking.isInternalException(args[1]) : false;
|
|
22
22
|
}
|
|
23
23
|
});
|
|
@@ -400,7 +400,7 @@ export default class FloatingManager {
|
|
|
400
400
|
public static unsubscribeOverlayControl(identifier: HTMLElement | number){
|
|
401
401
|
if(!identifier) return;
|
|
402
402
|
|
|
403
|
-
|
|
403
|
+
const item: HTMLElement = identifier instanceof HTMLElement ? identifier : this.overlayElements[identifier -1];
|
|
404
404
|
|
|
405
405
|
const oldZIndex = item.getAttribute(FloatingManager.DATA_OLD_ZINDEX_ATTRIBUTE_NAME) || '';
|
|
406
406
|
item.setAttribute(FloatingManager.DATA_OLD_ZINDEX_ATTRIBUTE_NAME, oldZIndex);
|
package/src/utils/DateUtils.ts
CHANGED
|
@@ -64,7 +64,7 @@ export class ElementIDUtils {
|
|
|
64
64
|
* @returns - Atributo `data-element-id` do elemento modificado com sufixo e/ou ID.
|
|
65
65
|
*/
|
|
66
66
|
private static getDataElementID(element: HTMLElement, suffix?: string, iDInfo?: IElementIDInfo) {
|
|
67
|
-
|
|
67
|
+
const dataElementID = ElementIDUtils.getDataElementIDAttribute(element);
|
|
68
68
|
if(dataElementID != null){
|
|
69
69
|
return this.addSuffix(StringUtils.toCamelCase((dataElementID as string)), suffix, element);
|
|
70
70
|
}
|
|
@@ -74,7 +74,7 @@ export class ElementIDUtils {
|
|
|
74
74
|
if(validAttribute) return this.addSuffix(validAttribute, suffix, element);
|
|
75
75
|
if(suffix) return String(suffix);
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
const tagName = StringUtils.toCamelCase(element.tagName);
|
|
78
78
|
element.setAttribute(ElementIDUtils.DATA_ELEMENT_ID_ATTRIBUTE_NAME, tagName);
|
|
79
79
|
|
|
80
80
|
return tagName;
|
package/src/utils/NumberUtils.ts
CHANGED
|
@@ -164,7 +164,7 @@ export class NumberUtils {
|
|
|
164
164
|
//keep only decimal character in order to correct format the string
|
|
165
165
|
//This transformation is due the "stringtoNumber" method is a general method that tries to convert all formated strings
|
|
166
166
|
if (formatnumber === 'EN-US') {
|
|
167
|
-
value = value.replace(
|
|
167
|
+
value = value.replace(/,/g, '');
|
|
168
168
|
} else {
|
|
169
169
|
value = value.replace(/\./g, '');
|
|
170
170
|
}
|
|
@@ -185,7 +185,7 @@ export class NumberUtils {
|
|
|
185
185
|
*/
|
|
186
186
|
static changeFormat = (value: string): string => {
|
|
187
187
|
//Formatting output following formatnumber
|
|
188
|
-
return value.replace(/\./g, '_').replace(
|
|
188
|
+
return value.replace(/\./g, '_').replace(/,/g, '.').replace(/_/g, ',');
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
|
package/src/utils/StringUtils.ts
CHANGED
|
@@ -69,7 +69,7 @@ export class StringUtils {
|
|
|
69
69
|
['quot', '"']
|
|
70
70
|
];
|
|
71
71
|
|
|
72
|
-
for(
|
|
72
|
+
for(const entity of entities) {
|
|
73
73
|
text = text.replace(new RegExp(`&${entity[0]};`), entity[1]);
|
|
74
74
|
}
|
|
75
75
|
|
|
@@ -307,20 +307,19 @@ export class StringUtils {
|
|
|
307
307
|
*/
|
|
308
308
|
static formatBytes(bytes: number): string {
|
|
309
309
|
const units = ["B", "KB", "MB", "GB"];
|
|
310
|
-
let unit: string, value: string, base: number;
|
|
311
310
|
|
|
312
311
|
if (bytes < 1024) {
|
|
313
312
|
return `${bytes.toString()}B`;
|
|
314
313
|
}
|
|
315
314
|
|
|
316
|
-
base = Math.log(bytes) / Math.log(1024);
|
|
315
|
+
const base = Math.log(bytes) / Math.log(1024);
|
|
317
316
|
const offSet = Math.floor(base);
|
|
318
317
|
if (offSet >= units.length) {
|
|
319
318
|
return `${bytes.toString()}B`;
|
|
320
319
|
}
|
|
321
320
|
|
|
322
|
-
value = this.prettyPrecision(Math.pow(1024, base - offSet).toFixed(2).toString());
|
|
323
|
-
unit = units[offSet];
|
|
321
|
+
const value = this.prettyPrecision(Math.pow(1024, base - offSet).toFixed(2).toString());
|
|
322
|
+
const unit = units[offSet];
|
|
324
323
|
|
|
325
324
|
return `${value}${unit}`;
|
|
326
325
|
}
|