Skip to content
Merged
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
2 changes: 1 addition & 1 deletion packages/app/app/initializers/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ export function initialize() {

export default {
name: 'config',
initialize
initialize,
};
6 changes: 5 additions & 1 deletion packages/app/config/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ module.exports = function (environment) {
};

if (environment === 'development') {
ENV['ember-cli-mirage'] = { enabled: !(process.env.DISABLE_MOCKS || process.env.APP_ENV === 'localElide') };
ENV['ember-cli-mirage'] = {
enabled: !(
process.env.DISABLE_MOCKS || process.env.APP_ENV === 'localElide'
),
};
/*
* ENV.APP.LOG_RESOLVER = true;
* ENV.APP.LOG_ACTIVE_GENERATION = true;
Expand Down
2 changes: 1 addition & 1 deletion packages/data/addon/adapters/dimensions/elide.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export default class ElideDimensionAdapter extends EmberObject implements NaviDi
operator: pred.operator,
values: pred.values.map(String),
})),
sorts: [],
sorts: [{ type: 'dimension', field: id, parameters, direction: 'asc' }],
dataSource: source,
limit: null,
requestVersion: '2.0',
Expand Down
40 changes: 35 additions & 5 deletions packages/data/addon/adapters/facts/elide.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ export function getElideFilterField(fieldName: string, parameters: Parameters =
return `${field}${paramsStr}`;
}

type PaginationOptions = {
first: number;
after: number;
};

export default class ElideFactsAdapter extends EmberObject implements NaviFactAdapter {
/**
* @property {Object} apollo - apollo client query manager using the overridden elide service
Expand All @@ -91,7 +96,7 @@ export default class ElideFactsAdapter extends EmberObject implements NaviFactAd
if (Object.keys(nonDefaultParams).length !== 0) {
const canonicalName = canonicalizeMetric({ metric: base.field, parameters: base.parameters });
throw new FactAdapterError(
`Parameters are not supported in elide unles ${canonicalName} is added as a column.`
`Parameters are not supported in elide unless ${canonicalName} is added as a column.`
);
}
}
Expand Down Expand Up @@ -170,7 +175,7 @@ export default class ElideFactsAdapter extends EmberObject implements NaviFactAd
* @param request
* @returns graphql query string for a v2 request
*/
private dataQueryFromRequest(request: RequestV2): string {
private dataQueryFromRequest(request: RequestV2, pagination?: PaginationOptions | null): string {
const args = [];
const { table, columns, sorts, limit, filters } = request;
const columnCanonicalToAlias = columns.reduce((canonicalToAlias: Record<string, string>, column, idx) => {
Expand Down Expand Up @@ -216,10 +221,22 @@ export default class ElideFactsAdapter extends EmberObject implements NaviFactAd
const limitStr = limit ? `first: "${limit}"` : null;
limitStr && args.push(limitStr);

if (pagination) {
pagination.first && args.push(`first: "${pagination.first}"`);
pagination.after && args.push(`after: "${pagination.after}"`);
}

const argsString = args.length ? `(${args.join(',')})` : '';

let pageInfoString: string;
if (pagination === null) {
pageInfoString = '';
} else {
pageInfoString = ' pageInfo { startCursor endCursor totalRecords }';
}

return JSON.stringify({
query: `{ ${table}${argsString} { edges { node { ${columnsStr} } } } }`,
query: `{ ${table}${argsString} { edges { node { ${columnsStr} } }${pageInfoString} } }`,
});
}

Expand All @@ -230,7 +247,20 @@ export default class ElideFactsAdapter extends EmberObject implements NaviFactAd
*/
createAsyncQuery(request: RequestV2, options: RequestOptions = {}): Promise<AsyncQueryResponse> {
const mutation: DocumentNode = GQLQueries['asyncFactsMutation'];
const query = this.dataQueryFromRequest(request);
let pagination: PaginationOptions | undefined;
if (options.perPage) {
const page = options.page ?? 1;
if (request.limit && !(page === 1 && request.limit === options.perPage)) {
throw new FactAdapterError(
`The request specified a limit of ${request.limit} which conflicts with page=${page} and perPage=${options.perPage}`
);
}
pagination = {
after: (page - 1) * options.perPage,
first: options.perPage,
};
}
const query = this.dataQueryFromRequest(request, pagination);
const asyncAfterSeconds = DEFAULT_ASYNC_AFTER_SECONDS;
const id: string = options.requestId || v1();
const dataSourceName = request.dataSource || options.dataSourceName;
Expand Down Expand Up @@ -265,7 +295,7 @@ export default class ElideFactsAdapter extends EmberObject implements NaviFactAd
* @param _options
*/
urlForFindQuery(request: RequestV2, _options: RequestOptions): string {
return this.dataQueryFromRequest(request);
return this.dataQueryFromRequest(request, null);
}

/**
Expand Down
6 changes: 6 additions & 0 deletions packages/data/addon/adapters/facts/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ export enum TableExportResultType {
JSON = 'JSON',
}

export type PageInfo = {
startCursor: `${number}`;
endCursor: `${number}`;
totalRecords: number;
};

export type AsyncQueryResponse = {
asyncQuery: {
edges: [
Expand Down
33 changes: 26 additions & 7 deletions packages/data/addon/mirage/routes/bard-lite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,13 +275,14 @@ export default function (

this.get('/dimensions/:dimension/values', function (_db, request) {
faker.seed(request.url.length);
let dimension = request.params.dimension,
rows = _getDimensionValues({ name: dimension, show: [] });

const dimension = request.params.dimension;
const { filters, page, perPage } = request.queryParams;
let rows = _getDimensionValues({ name: dimension, show: [] });
let meta;
// Handle value filters
if ('filters' in request.queryParams) {
const { values } = parseFilters(request.queryParams.filters)[0],
fieldMatch = request.queryParams.filters.match(/\|(id|key)/);
if (filters) {
const { values } = parseFilters(request.queryParams.filters)[0];
const fieldMatch = request.queryParams.filters.match(/\|(id|key)/);

rows =
fieldMatch && fieldMatch.length > 0
Expand All @@ -291,8 +292,26 @@ export default function (
})
: rows.filter((row) => values.some((value) => row.description?.toLowerCase().includes(value.toLowerCase())));
}
if (page && perPage) {
const pageNum = Number(page);
const perPageNum = Number(perPage);
const skipped = (pageNum - 1) * perPageNum;
const totalResults = rows.length;
rows = rows.slice(skipped);
rows = rows.slice(0, perPageNum);
meta = {
pagination: {
currentPage: pageNum,
rowsPerPage: perPageNum,
numberOfResults: totalResults,
},
};
}

return { rows };
return {
rows,
...(meta ? { meta } : {}),
};
});

this.get('/dimensions/:dimension/search', function (_db, request) {
Expand Down
28 changes: 21 additions & 7 deletions packages/data/addon/mirage/routes/graphql.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ const DATE_FILTER_OPS = {
*/
function _getSeedForRequest(table, args, fields) {
const tableLength = table.length;
const argsLength = Object.keys(args).join(' ').length;
const skippedArgs = ['first', 'after', 'sort'];
const argsLength = Object.keys(args)
.filter((key) => !skippedArgs.includes(key))
.join(' ').length;
const fieldsLength = fields.join(' ').length;
return tableLength + argsLength + fieldsLength;
}
Expand Down Expand Up @@ -330,6 +333,7 @@ function _parseArgs(args, table, aliases) {
return { field, direction };
}),
first: (limit) => limit,
after: (after) => after,
};

const parsed = {};
Expand All @@ -355,7 +359,7 @@ function _getResponseBody(db, asyncQueryRecord) {
if (responseTime - createdOn >= ASYNC_RESPONSE_DELAY) {
const { table, args, fields, aliases } = _parseGQLQuery(JSON.parse(query).query || '');
const fieldToAlias = invert(aliases);
const { filter = [], sort = [], first } = _parseArgs(args, table, aliases);
const { filter = [], sort = [], first, after } = _parseArgs(args, table, aliases);
const seed = _getSeedForRequest(table, args, fields);
faker.seed(seed);

Expand Down Expand Up @@ -413,11 +417,6 @@ function _getResponseBody(db, asyncQueryRecord) {
}, currRow)
);

// handle limit in request
if (first && first < rows.length) {
rows = rows.slice(0, first);
}

// sort rows
if (sort.length) {
rows = orderBy(
Expand All @@ -427,10 +426,25 @@ function _getResponseBody(db, asyncQueryRecord) {
);
}

// handle limit in request
const totalRecords = rows.length;
if (after && after < rows.length) {
rows = rows.slice(after);
}
if (first && first < rows.length) {
rows = rows.slice(0, first);
}

const startNumber = after ?? 0;
return JSON.stringify({
data: {
[table]: {
edges: rows.map((node) => ({ node })),
pageInfo: {
startCursor: `${startNumber}`,
endCursor: `${startNumber + rows.length}`,
totalRecords,
},
},
},
});
Expand Down
12 changes: 12 additions & 0 deletions packages/data/addon/models/navi-dimension-response.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Copyright 2021, Yahoo Holdings Inc.
* Licensed under the terms of the MIT license. See accompanying LICENSE.md file for terms.
*/
import EmberObject from '@ember/object';
import type NaviDimensionModel from 'navi-data/models/navi-dimension';
import type { ResponseV1 } from 'navi-data/serializers/facts/interface';

export default class NaviDimensionResponse extends EmberObject {
readonly values: NaviDimensionModel[] = [];
readonly meta?: ResponseV1['meta'] = {};
}
12 changes: 6 additions & 6 deletions packages/data/addon/models/navi-facts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
*/

import EmberObject from '@ember/object';
import { taskFor } from 'ember-concurrency-ts';
import type NaviFactsService from 'navi-data/services/navi-facts';
import type { RequestV2 } from 'navi-data/adapters/facts/interface';
import type NaviFactResponse from 'navi-data/models/navi-fact-response';
import { taskFor } from 'ember-concurrency-ts';

export default class NaviFacts extends EmberObject {
/**
Expand All @@ -28,16 +28,16 @@ export default class NaviFacts extends EmberObject {
declare _factService: NaviFactsService;

/**
* @returns Promise with the response model object for next page or null when trying to go past last page
* @returns Promise with the response model object for previous page or null when trying to access pages less than the first page
*/
next(): Promise<NaviFacts | null> {
return taskFor(this._factService.fetchNext).perform(this.response, this.request);
previous(): Promise<NaviFacts | null> {
return taskFor(this._factService.fetchPrevious).perform(this.response, this.request);
}

/**
* @returns Promise with the response model object for previous page or null when trying to access pages less than the first page
* @returns Promise with the response model object for next page or null when trying to go past last page
*/
previous(): Promise<NaviFacts | null> {
next(): Promise<NaviFacts | null> {
return taskFor(this._factService.fetchNext).perform(this.response, this.request);
}
}
10 changes: 6 additions & 4 deletions packages/data/addon/serializers/dimensions/bard.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2020, Yahoo Holdings Inc.
* Copyright 2021, Yahoo Holdings Inc.
* Licensed under the terms of the MIT license. See accompanying LICENSE.md file for terms.
*/

Expand All @@ -8,17 +8,19 @@ import NaviDimensionSerializer from './interface';
import NaviDimensionModel from '../../models/navi-dimension';
import { FiliDimensionResponse, DefaultField } from 'navi-data/adapters/dimensions/bard';
import { DimensionColumn } from 'navi-data/models/metadata/dimension';
import NaviDimensionResponse from 'navi-data/models/navi-dimension-response';

export default class BardDimensionSerializer extends EmberObject implements NaviDimensionSerializer {
normalize(dimensionColumn: DimensionColumn, rawPayload: FiliDimensionResponse): NaviDimensionModel[] {
normalize(dimensionColumn: DimensionColumn, rawPayload: FiliDimensionResponse): NaviDimensionResponse {
if (rawPayload?.rows.length) {
const field = dimensionColumn.parameters?.field || DefaultField;
return rawPayload.rows.map((row) => {
const values = rawPayload.rows.map((row) => {
//TODO remove when https://github.com/yahoo/fili/issues/1088 lands
const value = 'desc' === field ? row.description : row[field];
return NaviDimensionModel.create({ value, dimensionColumn });
});
return NaviDimensionResponse.create({ values, meta: rawPayload.meta });
}
return [];
return NaviDimensionResponse.create();
}
}
33 changes: 24 additions & 9 deletions packages/data/addon/serializers/dimensions/elide.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,47 @@
* Copyright 2021, Yahoo Holdings Inc.
* Licensed under the terms of the MIT license. See accompanying LICENSE.md file for terms.
*/

import NaviDimensionSerializer from './interface';
import NaviDimensionModel from '../../models/navi-dimension';
import { AsyncQueryResponse } from 'navi-data/adapters/facts/interface';
import EmberObject from '@ember/object';
import { DimensionColumn } from 'navi-data/models/metadata/dimension';
import ElideDimensionMetadataModel from 'navi-data/models/metadata/elide/dimension';
import { assert } from '@ember/debug';
import NaviDimensionModel from '../../models/navi-dimension';
import NaviDimensionResponse from 'navi-data/models/navi-dimension-response';
import { getPaginationFromPageInfo } from '../facts/elide';
import type { AsyncQueryResponse } from 'navi-data/adapters/facts/interface';
import type NaviDimensionSerializer from './interface';
import type { DimensionColumn } from 'navi-data/models/metadata/dimension';
import type ElideDimensionMetadataModel from 'navi-data/models/metadata/elide/dimension';
import type { ServiceOptions } from 'navi-data/services/navi-dimension';

export type ResponseEdge = {
node: Record<string, string>;
};

export default class ElideDimensionSerializer extends EmberObject implements NaviDimensionSerializer {
normalize(dimension: DimensionColumn, rawPayload?: AsyncQueryResponse): NaviDimensionModel[] {
normalize(
dimension: DimensionColumn,
rawPayload?: AsyncQueryResponse,
options: ServiceOptions = {}
): NaviDimensionResponse {
const responseStr = rawPayload?.asyncQuery.edges[0].node.result?.responseBody;
const { tableId } = (dimension.columnMetadata as ElideDimensionMetadataModel).lookupColumn;
assert('The tableId is defined', tableId);

if (responseStr) {
const response = JSON.parse(responseStr);
return response.data[tableId as string].edges.map((edge: ResponseEdge) =>
const { edges, pageInfo } = response.data[tableId];
const values = edges.map((edge: ResponseEdge) =>
NaviDimensionModel.create({
value: edge.node.col0,
dimensionColumn: dimension,
})
);
return NaviDimensionResponse.create({
values,
meta: {
pagination: getPaginationFromPageInfo(pageInfo, options),
},
});
}
return [];
return NaviDimensionResponse.create();
}
}
9 changes: 5 additions & 4 deletions packages/data/addon/serializers/dimensions/interface.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/**
* Copyright 2020, Yahoo Holdings Inc.
* Copyright 2021, Yahoo Holdings Inc.
* Licensed under the terms of the MIT license. See accompanying LICENSE.md file for terms.
*/
import NaviDimensionModel from '../../models/navi-dimension';
import EmberObject from '@ember/object';
import { DimensionColumn } from 'navi-data/models/metadata/dimension';
import type { DimensionColumn } from 'navi-data/models/metadata/dimension';
import type { ServiceOptions } from 'navi-data/services/navi-dimension';
import type NaviDimensionResponse from 'navi-data/models/navi-dimension-response';

export default interface NaviDimensionSerializer extends EmberObject {
normalize(dimension: DimensionColumn, rawPayload: unknown): NaviDimensionModel[];
normalize(dimension: DimensionColumn, rawPayload: unknown, options: ServiceOptions): NaviDimensionResponse;
}
Loading