@mikezimm/fps-core-v7
Version:
Library of reusable core interfaces, types and constants migrated from fps-library-v2
188 lines • 11.1 kB
JavaScript
import { startPerformOpV2, updatePerformanceEndV2 } from "../../../../components/molecules/Performance/functions";
import { makeid } from "../../../../logic/Strings/guids";
import { check4This, Check4 } from '../../../../logic/Links/CheckSearch';
import { checkDeepProperty } from "../../../../logic/Objects/deep";
// import { getSumableNumber } from "../../../logic/Math/getNumber";
import { EmptyFPSItemSearch } from "../../../../components/molecules/AnyContent/IFPSItemSearch";
import { getBestAnalyticsLinkAndIcon } from "./getBestAnalyticsLinkAndIcon";
import { sortObjectArrayByNumberKey } from "../../../../logic/Arrays/sorting/numbers";
import { getSumableNumber } from "../../../../logic/Math/getNumber";
export function createKeyObject(keyZ, prime, labelV, otherKeys) {
prime = prime ? prime : `<< EMPTY ${keyZ} >>`;
const result = {
primaryKey: prime,
link: '',
countT: 0,
countI: 0,
countV: 0,
percentT: 0,
percentV: 0,
percentB: 0,
labelV: labelV,
FPSItem: {
IsA: { allIsAKeys: [], allIsAKeysStr: '' },
Search: EmptyFPSItemSearch,
// 2024-09-07: Added Search and File to pass the updated IFPSItem requirements
File: undefined,
},
sum: 0,
avg: 0,
items: [],
keyZ: keyZ,
};
// create empty arrays as needed
[0, 1, 2, 3, 4, 5].map(num => {
if (otherKeys.length > num) {
result[`key${num}`] = [];
}
});
return result;
}
export function easyAnalyticsSummary(items, wpFilterProps) {
const performanceSettings = { label: 'summary', updateMiliseconds: true, includeMsStr: true, op: 'analyze' };
let processOp = performanceSettings ? startPerformOpV2(performanceSettings) : null;
const Titles = summarizeArrayByKey(items, 'Titles', 'Title', ['Author/Office', 'Author/Title', 'language', 'CodeVersion']);
const Sites = summarizeArrayByKey(items, 'SiteTitle', 'Title', ['Author/Office', 'Author/Title', 'language', 'CodeVersion']);
const Offices = summarizeArrayByKey(items, 'Author/Office', 'Title', ['SiteTitle', 'Author/Title', 'language', 'CodeVersion']);
const Languages = summarizeArrayByKey(items, 'language', 'Title', ['SiteTitle', 'Author/Title', 'Author/Office', 'CodeVersion']);
const Users = summarizeArrayByKey(items, 'Author/Title', 'Title', ['Author/Office', 'SiteTitle', 'language', 'CodeVersion']);
const Dates = summarizeArrayByKey(items, 'createdAge', 'Title', ['Author/Office', 'SiteTitle', 'language', 'Author/Title', 'CodeVersion']);
const CodeVersion = summarizeArrayByKey(items, 'CodeVersion', 'Title', ['Author/Office', 'SiteTitle', 'language', 'Author/Title', 'createdAge']);
// https://github.com/fps-solutions/SP-API-Tester/issues/52
// If there is a filter prop for the index, then build the summary. Else just copy the Titles one so it has the correct structure.
// const x0 = wpFilterProps.length < 1 ? EmptyObjArraySummary :summarizeArrayByKey( items, wpFilterProps[0], 'Title',[ 'Author/Office', 'SiteTitle', 'language', 'Author/Title', 'createdAge' ] );
// const x1 = wpFilterProps.length < 2 ? EmptyObjArraySummary :summarizeArrayByKey( items, wpFilterProps[1], 'Title',[ 'Author/Office', 'SiteTitle', 'language', 'Author/Title', 'createdAge' ] );
// const x2 = wpFilterProps.length < 3 ? EmptyObjArraySummary :summarizeArrayByKey( items, wpFilterProps[2], 'Title',[ 'Author/Office', 'SiteTitle', 'language', 'Author/Title', 'createdAge' ] );
// const x3 = wpFilterProps.length < 4 ? EmptyObjArraySummary :summarizeArrayByKey( items, wpFilterProps[3], 'Title',[ 'Author/Office', 'SiteTitle', 'language', 'Author/Title', 'createdAge' ] );
// const x4 = wpFilterProps.length < 5 ? EmptyObjArraySummary :summarizeArrayByKey( items, wpFilterProps[4], 'Title',[ 'Author/Office', 'SiteTitle', 'language', 'Author/Title', 'createdAge' ] );
// const x5 = wpFilterProps.length < 6 ? EmptyObjArraySummary :summarizeArrayByKey( items, wpFilterProps[5], 'Title',[ 'Author/Office', 'SiteTitle', 'language', 'Author/Title', 'createdAge' ] );
// const x6 = wpFilterProps.length < 7 ? EmptyObjArraySummary :summarizeArrayByKey( items, wpFilterProps[6], 'Title',[ 'Author/Office', 'SiteTitle', 'language', 'Author/Title', 'createdAge' ] );
// https://github.com/fps-solutions/SP-API-Tester/issues/52
const OldxIdx = [0, 1, 2, 3, 4, 5, 6].map((i) => {
return wpFilterProps.length < (i + 1) ? EmptyObjArraySummary : summarizeArrayByKey(items, wpFilterProps[i], 'Title', ['Author/Office', 'SiteTitle', 'language', 'Author/Title', 'createdAge']);
});
//2024-09-07: Added processOp as IPerformanceOp for this line to pass Linting since it should be a value.
processOp = updatePerformanceEndV2({ op: processOp, updateMiliseconds: performanceSettings.updateMiliseconds, count: items.length * 6 });
const result = {
Titles: Titles,
Sites: Sites,
Offices: Offices,
Languages: Languages,
Users: Users,
Dates: Dates,
CodeVersion: CodeVersion,
//2024-09-07: Added processOp as IPerformanceOp for these to lines to pass Linting since it should be a value.
processOp: processOp,
unifiedPerformanceOps: { process: processOp },
refreshId: makeid(5),
stats: {
Titles: Titles.keys.length,
Sites: Sites.keys.length,
Offices: Offices.keys.length,
Languages: Languages.keys.length,
Users: Users.keys.length,
Dates: Dates.keys.length,
CodeVersion: CodeVersion.keys.length,
x0: OldxIdx[0].keys.length,
x1: OldxIdx[1].keys.length,
x2: OldxIdx[2].keys.length,
x3: OldxIdx[3].keys.length,
// https://github.com/fps-solutions/SP-API-Tester/issues/52
x4: OldxIdx[4].keys.length,
x5: OldxIdx[5].keys.length,
x6: OldxIdx[6].keys.length,
},
x0: OldxIdx[0],
x1: OldxIdx[1],
x2: OldxIdx[2],
x3: OldxIdx[3],
// https://github.com/fps-solutions/SP-API-Tester/issues/52
x4: OldxIdx[4],
x5: OldxIdx[5],
x6: OldxIdx[6],
};
if (check4This(Check4.sourceResults_Eq_true) === true)
console.log('sourceResults easyAnalyticsSummary', result);
return result;
}
const EmptyObjArraySummary = {
keys: [],
summaries: [],
topLabels: [],
};
export function summarizeArrayByKey(items, key, valProp, otherKeys) {
const summary = JSON.parse(JSON.stringify(EmptyObjArraySummary));
const keyIsDate = key.indexOf('Age') > -1 ? true : false;
items.map((item, idx0) => {
let itemValue = key.indexOf('.') < 0 ? item[key] : `${checkDeepProperty(item, key.split('.'), 'EmptyString', false)}`;
// if itemValue is a date, then convert to integer to group by date in the past
if (keyIsDate === true)
itemValue = parseInt(itemValue, 10) + 0; // Added 0 to make this non mutating
// Get index of this item and create object if it does not exist
let idx = summary.keys.indexOf(itemValue);
if (idx < 0) {
idx = summary.keys.length;
summary.keys.push(itemValue);
const keyItem = createKeyObject(key, keyIsDate === true ? getDateLabel(itemValue) : itemValue, valProp, otherKeys);
// Only add link if it is for a site.
if (key === 'SiteTitle')
keyItem.link = getBestAnalyticsLinkAndIcon(item, false, ['SiteLink', 'PageLink', 'PageURL']).linkUrl;
summary.summaries.push(keyItem);
}
item.primeIdx = idx0;
const thisSum = summary.summaries[idx];
thisSum.countT++;
if (itemValue)
thisSum.countI++;
if (typeof itemValue === 'number' || typeof itemValue === 'bigint') {
thisSum.countV++;
thisSum.sum += getSumableNumber(itemValue);
}
// Add other keys for additional information
otherKeys.map((oKey, idx) => {
// 2024-09-07: Set sumKeyValue: any and used below to pass linting and build errors... only used for analytics now and never had an issue yet.
const sumKeyValue = thisSum[`key${idx}`];
if (item[oKey] && sumKeyValue && sumKeyValue.indexOf(item[oKey]) < 0) {
/**
* 2024-09-07: Checked with chatGPT and it said this should update the original array if it's an array....
* Reference Types: If thisSum['key0'] is an array (which is a reference type),
* then sumKeyValue is a reference to the same array. In this case,
* updating sumKeyValue by calling push() will also update the array
* stored in thisSum['key0'] because they both refer to the same underlying array.
*/
sumKeyValue.push(item[oKey]);
}
});
thisSum.items.push(item);
});
summary.summaries.map(thisSum => {
if (thisSum.sum > 0)
thisSum.avg = thisSum.sum / thisSum.countV;
});
// Sort by count unless it's an age, then asc sort by date ( which is the avg value of the column )
// 2023-10-06: https://github.com/mikezimm/fps-library-v2/issues/120
// Only sort if not date... sortObjectArrayByNumberKey( summary.summaries, 'desc', keyIsDate === true ? 'avg' : 'countT' );
// if key === createdAge then it is already reverse sorted during fetch and will show latest on top.
if (key !== 'createdAge')
summary.summaries = sortObjectArrayByNumberKey(summary.summaries, 'desc', keyIsDate === true ? 'avg' : 'countT');
// Get top 10 labels by count
summary.topLabels = summary.summaries.slice(0, 9).map(thisSum => { return thisSum.primaryKey; });
// Get % T - 100 = max item: https://stackoverflow.com/a/16751601
const sumCountT = summary.summaries.map(thisSum => { return thisSum.countT; }).reduce((partialSum, a) => partialSum + a, 0);
const countMax = Math.max(...summary.summaries.map(thisSum => { return thisSum.countT; }));
if (sumCountT !== 0)
summary.summaries.map(thisSum => { thisSum.percentT = (thisSum.countT / sumCountT) * 100; });
if (countMax !== 0)
summary.summaries.map(thisSum => { thisSum.percentB = (thisSum.countT / countMax) * 100; });
summary.summaries.map(thisSum => {
thisSum.FPSItem.Search.searchText = thisSum.primaryKey;
thisSum.FPSItem.Search.searchTextLC = thisSum.primaryKey.toLowerCase();
});
return summary;
}
function getDateLabel(daysAgo) {
const date = new Date();
date.setDate(date.getDate() - daysAgo);
return date.toLocaleDateString();
}
//# sourceMappingURL=summarizeArrayByKey.js.map