Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

poc(): item query metrics #1741

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/common/src/core/types/Metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ export interface IMetric {
* This will be added to the `IMetric` as it's processed.
*/
entityInfo?: IEntityInfo;

modified?: Date;

created?: Date;

reportingTo?: Array<{ entityId: string; metricId: string }>;
}

/**
Expand Down
30 changes: 22 additions & 8 deletions packages/common/src/metrics/resolveMetric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ import { portalSearchItemsAsItems } from "../search/_internal/portalSearchItems"
*/
export async function resolveMetric(
metric: IMetric,
context: IArcGISContext
context: IArcGISContext,
options?: { defaultFieldName?: string }
): Promise<IResolvedMetric> {
// At this point the source references should have been resolved
// so we can force case to a MetricSource and switch on the type
Expand All @@ -35,10 +36,10 @@ export async function resolveMetric(
// call the appropriate resolver
switch (source.type) {
case "static-value":
return resolveStaticValueMetric(metric, context);
return resolveStaticValueMetric(metric, context, options);

case "service-query":
return resolveServiceQueryMetric(metric, context);
return resolveServiceQueryMetric(metric, context, options);

case "item-query":
return resolveItemQueryMetric(metric, context);
Expand All @@ -56,12 +57,14 @@ export async function resolveMetric(
*/
function resolveStaticValueMetric(
metric: IMetric,
context: IArcGISContext
context: IArcGISContext,
options: { defaultFieldName?: string } = {}
): Promise<IResolvedMetric> {
const { defaultFieldName } = options;
const source = metric.source as IStaticValueMetricSource;
// cut off the parent identifier from the metric id and use that
// as the output field name
const fieldName = metric.id.split("_")[0];
const fieldName = defaultFieldName || metric.id.split("_")[0];
const result: IMetricFeature = {
attributes: {
id: metric.entityInfo.id,
Expand All @@ -71,6 +74,10 @@ function resolveStaticValueMetric(
valueType: source.valueType,
},
};

// if we are using a default field name, save the metric id onto the feature
defaultFieldName && (result.attributes.metricId = metric.id);

return Promise.resolve({
features: [result],
generatedAt: new Date().getTime(),
Expand All @@ -86,12 +93,14 @@ function resolveStaticValueMetric(
*/
async function resolveServiceQueryMetric(
metric: IMetric,
context: IArcGISContext
context: IArcGISContext,
options: { defaultFieldName?: string } = {}
): Promise<IResolvedMetric> {
const { defaultFieldName } = options;
const source = metric.source as IServiceQueryMetricSource;
// cut off the parent identifier from the metric id and use that
// as the output field name
const fieldName = metric.id.split("_")[0];
const fieldName = defaultFieldName || metric.id.split("_")[0];
// If no where is provided, default to "1=1"
source.where = source.where || "1=1";

Expand Down Expand Up @@ -125,6 +134,9 @@ async function resolveServiceQueryMetric(
},
};

// if we are using a default field name, save the metric id onto the feature
defaultFieldName && (result.attributes.metricId = metric.id);

return {
features: [result],
generatedAt: new Date().getTime(),
Expand Down Expand Up @@ -210,7 +222,9 @@ async function resolveItemQueryMetric(
// valueFromItem is itself a metric so we call resolveDynamicValues again
// attach in the entity info, so it's present for the next level of recursion
valueFromItem.entityInfo = result.attributes;
const vResult = await resolveMetric(valueFromItem, context);
const vResult = await resolveMetric(valueFromItem, context, {
defaultFieldName: fieldName,
});
vals.push(...vResult.features);
}
}
Expand Down
33 changes: 32 additions & 1 deletion packages/common/src/objects/get-prop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* getProp({a: [{key: "x", val:1}, {key: "y", val:3}]}, "a[1].val") => 3
* getProp({a: [{key: "x", val:1}, {key: "y", val:3}]}, "a[findBy(key,y)].val") => 3
* getProp({a: [{key: "x", val:1}, {key: "y", val:3}]}, "a[findBy(val,1)].key") => "x"
* getProp({a: [{key: [{ innerkey: "100" }], val:1}, {key: [{ innerkey: "3" }], val:3}]}, "a[deepFindBy(key|innerkey, "100")].val") => 1
* ```
*/
export const getProp = (obj: { [index: string]: any }, path: string): any => {
Expand Down Expand Up @@ -56,6 +57,7 @@ function applyOperation(arr: any[], operation: string): any {
if (!parts || parts.length !== 2) return undefined;

let result: any;
let val: number | string;

const fnName = parts[0];
const args = parts[1]
Expand All @@ -65,14 +67,43 @@ function applyOperation(arr: any[], operation: string): any {
switch (fnName) {
case "findBy":
const prop = args[0];
let val: number | string;
if (isNumeric(args[1])) {
val = parseFloat(args[1]);
} else {
val = args[1].replace(/'/g, "");
}

result = arr.find((p: any) => p[prop] === val);
break;

case "deepFindBy":
const splitProps = args[0].split("|");
const firstProp = splitProps.shift();
const restOfProps = splitProps.join("|");

// call deep find by recursively
if (splitProps.length >= 1) {
result = arr.find((p: any) => {
const getPropVal = getProp(
p,
`${firstProp}[deepFindBy(${restOfProps}, ${args[1]})]`
);
return getPropVal;
});
}

// find the value
else {
if (isNumeric(args[1])) {
val = parseFloat(args[1]);
} else {
val = args[1].replace(/'/g, "");
}
result = arr.find((p: any) => p[firstProp] === val);
}

break;

default:
result = undefined;
}
Expand Down
Loading