|
@@ -30,18 +30,17 @@ export class queryService {
|
|
|
|
|
|
// Search and Filter: Pure Observables. To be moved out to become a separate service again.
|
|
|
private filterFromObs(...conditions: Conditions[]) {
|
|
|
- let enquiry = conditions[0]
|
|
|
- let key = Object.keys(enquiry)[0]
|
|
|
+ let searchObj = Object.assign({}, ...conditions)
|
|
|
this.dataFromStorage.subscribe({
|
|
|
next: element => {
|
|
|
- if (key == "regex") {
|
|
|
- if (this.filterViaRegex(element, enquiry)) {
|
|
|
+ if (Object.keys(conditions).length == 1 && searchObj.hasOwnProperty('regex')) {
|
|
|
+ if (this.filterViaRegex(element, searchObj.regex)) {
|
|
|
this.filteredResult.next(element)
|
|
|
} else {
|
|
|
// console.log(`${element.header.messageName} does not match search criteria`)
|
|
|
- }
|
|
|
+ }
|
|
|
} else {
|
|
|
- if (this.hasKeyAndValue(element, ...conditions)) {
|
|
|
+ if (this.filterByKeyValue(element, ...conditions)) {
|
|
|
this.filteredResult.next(element)
|
|
|
} else {
|
|
|
// console.log(`${element.header.messageName} does not match search criteria`)
|
|
@@ -70,41 +69,51 @@ export class queryService {
|
|
|
}
|
|
|
|
|
|
// Logic 2: Success: More superior version than Logic 1 since it can perform flat searches like {messageID : 1234} without specifying its nested properties
|
|
|
- private hasKeyAndValue(data, ...conditions): boolean {
|
|
|
+ private filterByKeyValue(data, ...conditions): boolean {
|
|
|
// Merge all conditions into searchObj
|
|
|
let searchObj = Object.assign({}, ...conditions)
|
|
|
+ let dateCheck = true
|
|
|
+ if (searchObj.hasOwnProperty("dateRange")) {
|
|
|
+ dateCheck = this.filterByDateRange(data, searchObj.dateRange)
|
|
|
+ // Must delete, otherwise the function below will attempt to match date range with the date property and it will inevitably returns false
|
|
|
+ delete searchObj.dateRange
|
|
|
+ }
|
|
|
if (typeof data !== 'object' || typeof searchObj !== 'object') {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- let matchKeys = Object.keys(searchObj);
|
|
|
- let isMatchingObject = (object) => {
|
|
|
- return matchKeys.every((key) => {
|
|
|
- let lodashPath = key.replace(/\[(\w+)\]/g, '.$1').replace(/^\./, '');
|
|
|
- let objectValue = _.get(object, lodashPath);
|
|
|
- let searchValue = searchObj[key];
|
|
|
-
|
|
|
- if (Array.isArray(searchValue) && key === 'msgTag') {
|
|
|
- // Check if any of the search values are included in the object value
|
|
|
- return searchValue.some((value) => {
|
|
|
- return Array.isArray(objectValue) ? objectValue.includes(value) : objectValue === value;
|
|
|
- });
|
|
|
- } else if (typeof searchValue === 'object' && typeof objectValue === 'object') {
|
|
|
- return isMatchingObject(objectValue);
|
|
|
- } else {
|
|
|
- return objectValue === searchValue;
|
|
|
+ if(dateCheck == true){
|
|
|
+ let matchKeys = Object.keys(searchObj);
|
|
|
+ let isMatchingObject = (object) => {
|
|
|
+ return matchKeys.every((key) => {
|
|
|
+ let lodashPath = key.replace(/\[(\w+)\]/g, '.$1').replace(/^\./, '');
|
|
|
+ let objectValue = _.get(object, lodashPath);
|
|
|
+ let searchValue = searchObj[key];
|
|
|
+
|
|
|
+ if (Array.isArray(searchValue) && key === 'msgTag') {
|
|
|
+ // Check if any of the search values are included in the object value
|
|
|
+ return searchValue.some((value) => {
|
|
|
+ return Array.isArray(objectValue) ? objectValue.includes(value) : objectValue === value;
|
|
|
+ });
|
|
|
+ } else if (typeof searchValue === 'object' && typeof objectValue === 'object') {
|
|
|
+ return isMatchingObject(objectValue);
|
|
|
+ } else {
|
|
|
+ return objectValue === searchValue;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ let isObjectMatching = (object) => {
|
|
|
+ if (typeof object !== 'object') {
|
|
|
+ return false;
|
|
|
}
|
|
|
- });
|
|
|
- };
|
|
|
-
|
|
|
- let isObjectMatching = (object) => {
|
|
|
- if (typeof object !== 'object') {
|
|
|
- return false;
|
|
|
- }
|
|
|
- return isMatchingObject(object) || Object.values(object).some(isObjectMatching);
|
|
|
- };
|
|
|
-
|
|
|
- return isObjectMatching(data);
|
|
|
+ return isMatchingObject(object) || Object.values(object).some(isObjectMatching);
|
|
|
+ };
|
|
|
+
|
|
|
+ return isObjectMatching(data);
|
|
|
+ } else {
|
|
|
+ return false
|
|
|
+ }
|
|
|
|
|
|
/* This function first merges all the ...conditions objects into a single searchObj object using the Object.assign() method.
|
|
|
It then checks whether both data and searchObj are of type object. If either one is not an object, the function returns false.
|
|
@@ -124,11 +133,18 @@ export class queryService {
|
|
|
|
|
|
private filterViaRegex(element: any, inquiry: any): boolean {
|
|
|
// create a new regular expression to use regex.test
|
|
|
- const regex = new RegExp(inquiry.regex);
|
|
|
+ const regex = new RegExp(inquiry);
|
|
|
const hasMatchingSubstring = regex.test(JSON.stringify(element));
|
|
|
return hasMatchingSubstring;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ private filterByDateRange(data: any, dateRange: DateRange): boolean {
|
|
|
+ const start = new Date(dateRange.startDate);
|
|
|
+ const end = new Date(dateRange.endDate);
|
|
|
+ const target = new Date(data.header.dateCreated);
|
|
|
+ return target >= start && target <= end;
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
|
|
@@ -143,9 +159,13 @@ export interface Conditions {
|
|
|
msgTag?: string[],
|
|
|
msgPayload?: string,
|
|
|
messageID?: string,
|
|
|
- regex?: string
|
|
|
+ regex?: string,
|
|
|
+ dateRange?: DateRange
|
|
|
+}
|
|
|
+export interface DateRange {
|
|
|
+ startDate?: string | Date,
|
|
|
+ endDate?: string | Date
|
|
|
}
|
|
|
-
|
|
|
export interface Storage {
|
|
|
type: string,
|
|
|
address: string
|