Skip to content

Commit

Permalink
fix types
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinwcyu committed Jul 4, 2024
1 parent 0b1ce09 commit d0ec30d
Show file tree
Hide file tree
Showing 11 changed files with 225 additions and 180 deletions.
4 changes: 2 additions & 2 deletions .config/jest/mocks/react-inlinesvg.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ export const cacheStore: { [key: string]: StorageItem } = Object.create(null);

const SVG_FILE_NAME_REGEX = /(.+)\/(.+)\.svg$/;

const InlineSVG = ({ src }: { src: string }) => {
const InlineSVG = ({ src, innerRef, ...rest }: { src: string; innerRef: React.ForwardedRef<SVGElement> }) => {
// testId will be the file name without extension (e.g. `public/img/icons/angle-double-down.svg` -> `angle-double-down`)
const testId = src.replace(SVG_FILE_NAME_REGEX, '$2');
return <svg xmlns="http://www.w3.org/2000/svg" data-testid={testId} viewBox="0 0 24 24" />;
return <svg xmlns="http://www.w3.org/2000/svg" data-testid={testId} {...rest} viewBox="0 0 24 24" />;
};

export default InlineSVG;
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@
"@grafana/plugin-e2e": "^1.6.0",
"@grafana/tsconfig": "^1.3.0-rc1",
"@playwright/test": "^1.45.1",
"@swc/core": "^1.3.90",
"@swc/core": "^1.6.7",
"@swc/helpers": "^0.5.11",
"@swc/jest": "^0.2.26",
"@testing-library/dom": "^10.3.0",
"@testing-library/jest-dom": "6.4.6",
"@testing-library/react": "16.0.0",
"@testing-library/user-event": "^14.5.2",
Expand Down
24 changes: 13 additions & 11 deletions src/DataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export class DataSource extends DataSourceWithBackend<SitewiseQuery, SitewiseOpt
rangeRaw: options.rangeRaw,
} as DataQueryRequest<SitewiseQuery>;

let res: DataQueryResponse;
let res: DataQueryResponse | undefined;

try {
res = await this.query(request).toPromise();
Expand Down Expand Up @@ -153,16 +153,18 @@ export class DataSource extends DataSourceWithBackend<SitewiseQuery, SitewiseOpt
return super.query(request).toPromise();
},
cachedResponse: cachedInfo?.cachedResponse,
}).toObservable().pipe(
// Cache the last (done) response
tap({
next: (response) => {
if (response.state === LoadingState.Done) {
this.relativeRangeCache.set(request, response);
}
},
},)
);
})
.toObservable()
.pipe(
// Cache the last (done) response
tap({
next: (response) => {
if (response.state === LoadingState.Done) {
this.relativeRangeCache.set(request, response);
}
},
})
);
}
}

Expand Down
25 changes: 14 additions & 11 deletions src/SiteWiseQueryPaginator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import { SitewiseNextQuery, SitewiseQuery } from 'types';
*/
export interface SitewiseQueryPaginatorOptions {
// The initial query request.
request: DataQueryRequest<SitewiseQuery>,
request: DataQueryRequest<SitewiseQuery>;
// The function to call to execute the query.
queryFn: (request: DataQueryRequest<SitewiseQuery>) => Promise<DataQueryResponse>;
queryFn: (request: DataQueryRequest<SitewiseQuery>) => Promise<DataQueryResponse | undefined>;
// The cached response to set as the initial response.
cachedResponse?: {
start?: DataQueryResponse,
end?: DataQueryResponse,
},
start?: DataQueryResponse;
end?: DataQueryResponse;
};
}

/**
Expand All @@ -39,7 +39,10 @@ export class SitewiseQueryPaginator {
* @returns An observable that emits the paginated query responses.
*/
toObservable() {
const { request: { requestId }, cachedResponse } = this.options;
const {
request: { requestId },
cachedResponse,
} = this.options;
const subject = new Subject<DataQueryResponse>();

if (cachedResponse?.start) {
Expand All @@ -63,7 +66,7 @@ export class SitewiseQueryPaginator {
try {
let retrievedData = cachedResponse?.start?.data;
let nextQueries: SitewiseNextQuery[] | undefined;
const errorEncountered = false; // whether there's a error response
const errorEncountered = false; // whether there's a error response
let count = 1;

do {
Expand All @@ -77,12 +80,12 @@ export class SitewiseQueryPaginator {

const response = await queryFn(paginatingRequest);
if (retrievedData == null) {
retrievedData = response.data;
retrievedData = response?.data || [];
} else {
retrievedData = appendMatchingFrames(retrievedData, response.data);
retrievedData = appendMatchingFrames(retrievedData, response?.data || []);
}

if (response.state === LoadingState.Error) {
if (response?.state === LoadingState.Error) {
subject.next({ ...response, data: retrievedData, state: LoadingState.Error, key: requestId });
break;
}
Expand All @@ -95,7 +98,7 @@ export class SitewiseQueryPaginator {

if (cachedResponse?.end != null && !errorEncountered) {
retrievedData = appendMatchingFrames(retrievedData, cachedResponse.end.data);
subject.next({ ...cachedResponse.end, data: retrievedData , state: LoadingState.Done, key: requestId });
subject.next({ ...cachedResponse.end, data: retrievedData, state: LoadingState.Done, key: requestId });
}

subject.complete();
Expand Down
75 changes: 37 additions & 38 deletions src/components/ConfigEditor.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { DataSourcePluginOptionsEditorProps } from '@grafana/data';
import { ConfigEditor } from './ConfigEditor';
import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/react';
import { SitewiseOptions, SitewiseSecureJsonData } from 'types';
const datasourceOptions = {
Expand All @@ -27,42 +28,40 @@ const defaultProps: DataSourcePluginOptionsEditorProps<SitewiseOptions, Sitewise
options: datasourceOptions,
onOptionsChange: jest.fn(),
};
describe('edge configuration', () => {
it('should show correct fields if Standard authentication', () => {
render(
<ConfigEditor {...defaultProps} options={{ ...datasourceOptions, jsonData: { defaultRegion: 'Edge' } }} />
);
expect(screen.getByText('Edge settings')).toBeInTheDocument();
expect(screen.getByText('Authentication Provider')).toBeInTheDocument();
});
it('should show correct fields if linux authentication', () => {
render(
<ConfigEditor
{...defaultProps}
options={{ ...datasourceOptions, jsonData: { defaultRegion: 'Edge', edgeAuthMode: 'linux' } }}
/>
);
expect(screen.getByText('Edge settings')).toBeInTheDocument();
expect(screen.getByText('Username')).toBeInTheDocument();
expect(screen.getByText('Password')).toBeInTheDocument();
});
it('should display warning if region is Edge but no endpoint is specified', () => {
render(
<ConfigEditor
{...defaultProps}
options={{ ...datasourceOptions, jsonData: { defaultRegion: 'Edge', endpoint: '' } }}
/>
);
expect(screen.getByText('Edge settings')).toBeInTheDocument();
expect(screen.getByTestId('endpoint-warning')).toBeInTheDocument();
});
describe('edge configuration', () => {
it('should show correct fields if Standard authentication', () => {
render(<ConfigEditor {...defaultProps} options={{ ...datasourceOptions, jsonData: { defaultRegion: 'Edge' } }} />);
expect(screen.getByText('Edge settings')).toBeInTheDocument();
expect(screen.getByText('Authentication Provider')).toBeInTheDocument();
});
describe('non-edge configuration', () => {
it('should show correct fields if region is not edge', () => {
render(
<ConfigEditor {...defaultProps} options={{ ...datasourceOptions, jsonData: { defaultRegion: 'us-east-2' } }} />
);
expect(screen.queryByText('Edge settings')).not.toBeInTheDocument();
expect(screen.getByText('Authentication Provider')).toBeInTheDocument();
});
});
it('should show correct fields if linux authentication', () => {
render(
<ConfigEditor
{...defaultProps}
options={{ ...datasourceOptions, jsonData: { defaultRegion: 'Edge', edgeAuthMode: 'linux' } }}
/>
);
expect(screen.getByText('Edge settings')).toBeInTheDocument();
expect(screen.getByText('Username')).toBeInTheDocument();
expect(screen.getByText('Password')).toBeInTheDocument();
});
it('should display warning if region is Edge but no endpoint is specified', () => {
render(
<ConfigEditor
{...defaultProps}
options={{ ...datasourceOptions, jsonData: { defaultRegion: 'Edge', endpoint: '' } }}
/>
);
expect(screen.getByText('Edge settings')).toBeInTheDocument();
expect(screen.getByTestId('endpoint-warning')).toBeInTheDocument();
});
});
describe('non-edge configuration', () => {
it('should show correct fields if region is not edge', () => {
render(
<ConfigEditor {...defaultProps} options={{ ...datasourceOptions, jsonData: { defaultRegion: 'us-east-2' } }} />
);
expect(screen.queryByText('Edge settings')).not.toBeInTheDocument();
expect(screen.getByText('Authentication Provider')).toBeInTheDocument();
});
});
2 changes: 1 addition & 1 deletion src/components/browser/hierarchy/AssetHierarchyList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const AssetHierarchyList: FunctionComponent<Props> = ({
// try to load children if none passed in
if (!children && asset && cache) {
const fetchData = async () => {
const results = await cache.getAssociatedAssets(asset.id, hierarchy.id);
const results = (await cache.getAssociatedAssets(asset.id, hierarchy.id)) || [];
setChildren(results.toArray());
};
fetchData();
Expand Down
4 changes: 3 additions & 1 deletion src/components/query/PropertyQueryEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export class PropertyQueryEditor extends PureComponent<Props, State> {
try {
update.asset = await cache.getAssetInfo(query.assetIds![0]);
const ps = await cache.listAssetProperties(query.assetIds[0]);
update.assetProperties = ps.map(({ id, name }) => ({ id, name }));
update.assetProperties = ps?.map(({ id, name }) => ({ id, name })) || [];
} catch (err) {
console.warn('error reading asset info', err);
update.property = undefined;
Expand Down Expand Up @@ -362,6 +362,7 @@ export class PropertyQueryEditor extends PureComponent<Props, State> {
<EditorField label="Asset" htmlFor="asset" width={30}>
<Select
id="asset"
inputId="asset"
aria-label="Asset"
isMulti={true}
key={query.region ? query.region : 'default'}
Expand Down Expand Up @@ -396,6 +397,7 @@ export class PropertyQueryEditor extends PureComponent<Props, State> {
<EditorField label="Property" htmlFor="property" width={30}>
<Select
id="property"
inputId="property"
aria-label="Property"
isLoading={loading}
options={assetPropertyOptions}
Expand Down
2 changes: 1 addition & 1 deletion src/components/query/QueryEditor.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ describe('QueryEditor', () => {
});

async function openOptionsCollapse() {
const collapseLabel = await screen.queryByTestId('collapse-title');
const collapseLabel = screen.queryByTestId('collapse-title');
if (collapseLabel) {
return userEvent.click(collapseLabel);
}
Expand Down
9 changes: 4 additions & 5 deletions src/getNextQueries.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { DataFrame, DataQueryRequest, DataQueryResponse } from "@grafana/data";
import { SitewiseCustomMeta, SitewiseNextQuery, SitewiseQuery } from "types";
import { DataFrame, DataQueryRequest, DataQueryResponse } from '@grafana/data';
import { SitewiseCustomMeta, SitewiseNextQuery, SitewiseQuery } from 'types';


export function getNextQueries(request: DataQueryRequest<SitewiseQuery>, rsp: DataQueryResponse) {
if (rsp.data?.length) {
export function getNextQueries(request: DataQueryRequest<SitewiseQuery>, rsp?: DataQueryResponse) {
if (rsp?.data?.length) {
const next: SitewiseNextQuery[] = [];
for (const frame of rsp.data as DataFrame[]) {
const meta = frame.meta?.custom as SitewiseCustomMeta;
Expand Down
25 changes: 16 additions & 9 deletions src/sitewiseCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ export class SitewiseCache {
private topLevelAssets?: DataFrameView<AssetSummary>;
private assetPropertiesByAssetId = new Map<string, DataFrameView<{ id: string; name: string }>>();

constructor(private ds: DataSource, private region: string) {}
constructor(
private ds: DataSource,
private region: string
) {}

async getAssetInfo(id: string): Promise<AssetInfo> {
async getAssetInfo(id: string): Promise<AssetInfo | undefined> {
const v = this.assetsById.get(id);
if (v) {
return Promise.resolve(v);
Expand Down Expand Up @@ -60,7 +63,7 @@ export class SitewiseCache {
return this.assetsById.get(id);
}

async listAssetProperties(assetId: string): Promise<DataFrameView<{ id: string; name: string }>> {
async listAssetProperties(assetId: string): Promise<DataFrameView<{ id: string; name: string }> | undefined> {
const ap = this.assetPropertiesByAssetId.get(assetId);

if (ap) {
Expand Down Expand Up @@ -90,7 +93,7 @@ export class SitewiseCache {
.toPromise();
}

async getModels(): Promise<DataFrameView<AssetModelSummary>> {
async getModels(): Promise<DataFrameView<AssetModelSummary> | undefined> {
if (this.models) {
return Promise.resolve(this.models);
}
Expand All @@ -114,7 +117,7 @@ export class SitewiseCache {
}

// No cache for now
async getAssetsOfType(modelId: string): Promise<DataFrameView<AssetSummary>> {
async getAssetsOfType(modelId: string): Promise<DataFrameView<AssetSummary> | undefined> {
const query: ListAssetsQuery = {
refId: 'getAssetsOfType',
queryType: QueryType.ListAssets,
Expand All @@ -136,7 +139,7 @@ export class SitewiseCache {
.toPromise();
}

async getAssociatedAssets(assetId: string, hierarchyId?: string): Promise<DataFrameView<AssetSummary>> {
async getAssociatedAssets(assetId: string, hierarchyId?: string): Promise<DataFrameView<AssetSummary> | undefined> {
const query: ListAssociatedAssetsQuery = {
queryType: QueryType.ListAssociatedAssets,
refId: 'associatedAssets',
Expand All @@ -159,7 +162,7 @@ export class SitewiseCache {
.toPromise();
}

async getTopLevelAssets(): Promise<DataFrameView<AssetSummary>> {
async getTopLevelAssets(): Promise<DataFrameView<AssetSummary> | undefined> {
if (this.topLevelAssets) {
return Promise.resolve(this.topLevelAssets);
}
Expand Down Expand Up @@ -192,7 +195,7 @@ export class SitewiseCache {
icon: 'arrow-right',
}));
try {
const topLevel = await this.getTopLevelAssets();
const topLevel = (await this.getTopLevelAssets()) || [];
for (const asset of topLevel) {
options.push({
label: asset.name,
Expand Down Expand Up @@ -260,9 +263,13 @@ export function frameToAssetInfo(res: DescribeAssetResult): AssetInfo {
};
}

export function assetSummaryToAssetInfo(res: DataFrameView<AssetSummary>): AssetInfo[] {
export function assetSummaryToAssetInfo(res?: DataFrameView<AssetSummary>): AssetInfo[] {
const results: AssetInfo[] = [];

if (!res) {
return results;
}

for (const info of res.toArray()) {
const hierarchy: AssetPropertyInfo[] = JSON.parse(info.hierarchies); // has Id, Name
const properties: AssetPropertyInfo[] = [];
Expand Down
Loading

0 comments on commit d0ec30d

Please sign in to comment.