-
Notifications
You must be signed in to change notification settings - Fork 0
/
searcher.tsx
136 lines (88 loc) · 3.77 KB
/
searcher.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import {EntityValues, FirestoreTextSearchController} from "firecms";
interface MyObject {
id: string;
data: string[];
}
const paths: { [pathName: string]: MyObject[] } = {};
const ShowLogs = false;
export class Searcher {
static timeoutId: NodeJS.Timeout | undefined;
static debounceTime = 300;
static textSearchController: FirestoreTextSearchController = ({ path, searchString }) => {
// Clear previous timeout if exists
if (Searcher.timeoutId) {
clearTimeout(Searcher.timeoutId);
}
// Create a new Promise to wrap the search logic
return new Promise<readonly string[]>((resolve) => {
// Schedule a new search with a delay of 300 milliseconds
Searcher.timeoutId = setTimeout(() => {
const result = Searcher.filterObjectsByData(path, searchString);
if (ShowLogs) console.log('Search->', searchString, result);
// Resolve the Promise with the search results or empty array if undefined
resolve(result || []);
}, Searcher.debounceTime);
});
};
static clearMap(): void {
Object.keys(paths).forEach((key) => delete paths[key]);
}
static addObjectIfNotExists(path: string, id: string, newData: string[]): void {
if (!id && id === "") return;
const objects = paths[path] || [];
const existingObject = objects.find(obj => obj.id === id);
if (existingObject) {
existingObject.data = newData;
if (ShowLogs) console.log(`Updated object with ID ${id} in path ${path}. Data: ${existingObject.data}`);
} else {
const newObject: MyObject = { id, data: newData };
objects.push(newObject);
paths[path] = objects;
if (ShowLogs) console.log(`Added object with ID ${id} to path ${path}. Data: ${newObject.data}`);
}
}
static deleteObjectById(path: string, id: string): void {
const objects = paths[path] || [];
const index = objects.findIndex(obj => obj.id === id);
if (index !== -1) {
objects.splice(index, 1);
if (ShowLogs) console.log(`Deleted object with ID ${id} from path ${path}.`);
} else {
if (ShowLogs) console.log(`Object with ID ${id} does not exist in path ${path}. Nothing to delete.`);
}
}
static filterObjectsByData(path: string, input: string): Promise<readonly string[]> | undefined {
const objects = paths[path] || [];
const lowercasedInput = input.toLowerCase();
const filteredObjects = objects.filter(obj =>
obj.data.some(data => {
const lowercasedData = data.toLowerCase();
let inputIndex = 0;
for (let i = 0; i < lowercasedData.length; i++) {
if (ShowLogs) console.log('Search loop->', lowercasedInput[inputIndex]);
if (lowercasedData[i] === lowercasedInput[inputIndex]) {
inputIndex++;
}
if (inputIndex === lowercasedInput.length) {
return true;
}
}
return false;
})
);
const ids = filteredObjects.map(obj => obj.id);
if (ShowLogs) console.log('Search->', input, ids);
return Promise.resolve(ids);
}
static convertValuesToArray(values: EntityValues<any>)
{
const valuesArray = Object.values(values).flatMap(value => {
if (Array.isArray(value)) {
return value.map(String);
}
return String(value);
});
if (ShowLogs) console.log('converted values: ' + valuesArray);
return valuesArray;
}
}