fix: move webUrl construction into the st2 client
Signed-off-by: pamelin <pamelin@expediagroup.com>
This commit is contained in:
Vendored
+2
-2
@@ -14,12 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
export interface Config {
|
||||
stackstorm?: {
|
||||
stackstorm: {
|
||||
/**
|
||||
* StackStorm Web UI url
|
||||
* Used in links to StackStorm web UI
|
||||
* @visibility frontend
|
||||
*/
|
||||
webUrl?: string;
|
||||
webUrl: string;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { UrlPatternDiscovery } from '@backstage/core-app-api';
|
||||
import { ConfigReader, UrlPatternDiscovery } from '@backstage/core-app-api';
|
||||
import { MockFetchApi, setupRequestMockHandlers } from '@backstage/test-utils';
|
||||
import { rest } from 'msw';
|
||||
import { setupServer } from 'msw/node';
|
||||
@@ -177,31 +177,50 @@ describe('StackstormClient', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
setupHandlers();
|
||||
client = new StackstormClient({
|
||||
discoveryApi: discoveryApi,
|
||||
fetchApi: new MockFetchApi(),
|
||||
});
|
||||
client = StackstormClient.fromConfig(
|
||||
new ConfigReader({
|
||||
stackstorm: {
|
||||
webUrl: 'http://stackstorm.example.com:8080',
|
||||
},
|
||||
}),
|
||||
{
|
||||
discoveryApi: discoveryApi,
|
||||
fetchApi: new MockFetchApi(),
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it('get executions should return executions with emulated pagination', async () => {
|
||||
it('getExecutions should return executions with emulated pagination', async () => {
|
||||
const got = await client.getExecutions(2, 1);
|
||||
expect(got.length).toEqual(2);
|
||||
expect(got).toMatchObject(executions.slice(1, 3));
|
||||
});
|
||||
|
||||
it('get execution should return one execution', async () => {
|
||||
it('getExecution should return one execution', async () => {
|
||||
const got = await client.getExecution('63dcac3e18ba00e09e7bb3b6');
|
||||
expect(got).toMatchObject(executionWithDetails);
|
||||
});
|
||||
|
||||
it('get packs should return list of all packs', async () => {
|
||||
it('getPacks should return list of all packs', async () => {
|
||||
const got = await client.getPacks();
|
||||
expect(got.length).toEqual(packs.length);
|
||||
expect(got).toMatchObject(packs);
|
||||
});
|
||||
|
||||
it('get actions should return list of actions', async () => {
|
||||
it('getActions should return list of actions', async () => {
|
||||
const got = await client.getActions('core');
|
||||
expect(got).toMatchObject(actions);
|
||||
});
|
||||
|
||||
it('getExecutionHistoryUrl should return webUrl for executions', async () => {
|
||||
const got = client.getExecutionHistoryUrl('123abc');
|
||||
expect(got).toEqual('http://stackstorm.example.com:8080/?#/history/123abc');
|
||||
});
|
||||
|
||||
it('getActionUrl should return webUrl for action', async () => {
|
||||
const got = client.getActionUrl('core.shell');
|
||||
expect(got).toEqual(
|
||||
'http://stackstorm.example.com:8080/?#/actions/core.shell',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,21 +14,39 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Action, Execution, Pack, StackstormApi } from './types';
|
||||
import { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api';
|
||||
import { ConfigApi, DiscoveryApi, FetchApi } from '@backstage/core-plugin-api';
|
||||
|
||||
export class StackstormClient implements StackstormApi {
|
||||
private readonly discoveryApi: DiscoveryApi;
|
||||
private readonly fetchApi: FetchApi;
|
||||
private readonly webUrl: string;
|
||||
|
||||
constructor({
|
||||
private constructor({
|
||||
discoveryApi,
|
||||
fetchApi,
|
||||
webUrl,
|
||||
}: {
|
||||
discoveryApi: DiscoveryApi;
|
||||
fetchApi: FetchApi;
|
||||
webUrl: string;
|
||||
}) {
|
||||
this.discoveryApi = discoveryApi;
|
||||
this.fetchApi = fetchApi;
|
||||
this.webUrl = webUrl;
|
||||
}
|
||||
|
||||
static fromConfig(
|
||||
config: ConfigApi,
|
||||
dependencies: {
|
||||
discoveryApi: DiscoveryApi;
|
||||
fetchApi: FetchApi;
|
||||
},
|
||||
): StackstormClient {
|
||||
return new StackstormClient({
|
||||
discoveryApi: dependencies.discoveryApi,
|
||||
fetchApi: dependencies.fetchApi,
|
||||
webUrl: config.getString('stackstorm.webUrl'),
|
||||
});
|
||||
}
|
||||
|
||||
private async get<T = any>(input: string): Promise<T> {
|
||||
@@ -87,4 +105,12 @@ export class StackstormClient implements StackstormApi {
|
||||
const path = `/actions?${new URLSearchParams(params)}`;
|
||||
return this.get<Action[]>(path);
|
||||
}
|
||||
|
||||
getExecutionHistoryUrl(id: string): string {
|
||||
return `${this.webUrl}/?#/history/${id}`;
|
||||
}
|
||||
|
||||
getActionUrl(ref: string): string {
|
||||
return `${this.webUrl}/?#/actions/${ref}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,4 +56,6 @@ export interface StackstormApi {
|
||||
getExecution(id: string): Promise<Execution>;
|
||||
getPacks(): Promise<Pack[]>;
|
||||
getActions(pack: string): Promise<Action[]>;
|
||||
getExecutionHistoryUrl(id: string): string;
|
||||
getActionUrl(ref: string): string;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
import React, { useState } from 'react';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
import { Progress } from '@backstage/core-components';
|
||||
import { useApi, configApiRef } from '@backstage/core-plugin-api';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import {
|
||||
List,
|
||||
ListItemText,
|
||||
@@ -55,7 +55,6 @@ type ActionItemsProps = {
|
||||
export const ActionItems = ({ pack }: ActionItemsProps) => {
|
||||
const classes = useStyles();
|
||||
const st2 = useApi(stackstormApiRef);
|
||||
const config = useApi(configApiRef);
|
||||
|
||||
const { value, loading, error } = useAsync(async (): Promise<Action[]> => {
|
||||
const data = await st2.getActions(pack.ref);
|
||||
@@ -76,12 +75,7 @@ export const ActionItems = ({ pack }: ActionItemsProps) => {
|
||||
key={a.ref}
|
||||
button
|
||||
className={classes.nested}
|
||||
onClick={() =>
|
||||
window.open(
|
||||
`${config.getString('stackstorm.webUrl')}/?#/actions/${a.ref}`,
|
||||
'_blank',
|
||||
)
|
||||
}
|
||||
onClick={() => window.open(st2.getActionUrl(a.ref), '_blank')}
|
||||
>
|
||||
<ListItemText primary={a.name} secondary={a.description} />
|
||||
<ListItemSecondaryAction>{a.runner_type}</ListItemSecondaryAction>
|
||||
|
||||
@@ -13,12 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { configApiRef } from '@backstage/core-plugin-api';
|
||||
import {
|
||||
MockConfigApi,
|
||||
renderInTestApp,
|
||||
TestApiProvider,
|
||||
} from '@backstage/test-utils';
|
||||
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
|
||||
import React from 'react';
|
||||
import { Execution, StackstormApi, stackstormApiRef } from '../../api';
|
||||
import { ExecutionPanel } from './ExecutionPanel';
|
||||
@@ -54,19 +49,16 @@ const execution: Execution = {
|
||||
describe('ExecutionPanel', () => {
|
||||
const mockApi: jest.Mocked<StackstormApi> = {
|
||||
getExecution: jest.fn().mockResolvedValue(execution),
|
||||
getExecutionHistoryUrl: jest
|
||||
.fn()
|
||||
.mockResolvedValue(
|
||||
'http://stackstorm.example.com:8080/?#/history/63dcac3e18ba00e09e7bb3b6',
|
||||
),
|
||||
} as any;
|
||||
|
||||
it('should render execution details', async () => {
|
||||
const { getByText } = await renderInTestApp(
|
||||
<TestApiProvider
|
||||
apis={[
|
||||
[stackstormApiRef, mockApi],
|
||||
[
|
||||
configApiRef,
|
||||
new MockConfigApi({ stackstorm: { webUrl: 'http://localhost' } }),
|
||||
],
|
||||
]}
|
||||
>
|
||||
<TestApiProvider apis={[[stackstormApiRef, mockApi]]}>
|
||||
<ExecutionPanel id="63dcac3e18ba00e09e7bb3b6" />
|
||||
</TestApiProvider>,
|
||||
);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
import React from 'react';
|
||||
import { CodeSnippet, Progress } from '@backstage/core-components';
|
||||
import { configApiRef, useApi } from '@backstage/core-plugin-api';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import { Execution, stackstormApiRef } from '../../api';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
import { Alert } from '@material-ui/lab';
|
||||
@@ -65,11 +65,9 @@ const TRow = withStyles(theme => ({
|
||||
}))(TableRow);
|
||||
|
||||
const ExecutionCard = ({ e }: { e: Execution }) => {
|
||||
const config = useApi(configApiRef);
|
||||
const st2 = useApi(stackstormApiRef);
|
||||
const classes = useStyles();
|
||||
|
||||
const webUrl = `${config.getString('stackstorm.webUrl')}/?#/history/${e.id}`;
|
||||
|
||||
return (
|
||||
<Card className={classes.card}>
|
||||
<CardContent>
|
||||
@@ -139,7 +137,11 @@ const ExecutionCard = ({ e }: { e: Execution }) => {
|
||||
/>
|
||||
</CardContent>
|
||||
<CardActions>
|
||||
<Button size="small" href={webUrl} target="_blank">
|
||||
<Button
|
||||
size="small"
|
||||
href={`${st2.getExecutionHistoryUrl(e.id)}`}
|
||||
target="_blank"
|
||||
>
|
||||
View in ST2
|
||||
</Button>
|
||||
</CardActions>
|
||||
|
||||
@@ -83,19 +83,16 @@ const executions: Execution[] = [
|
||||
describe('ExecutionsTable', () => {
|
||||
const mockApi: jest.Mocked<StackstormApi> = {
|
||||
getExecutions: jest.fn().mockResolvedValue(executions),
|
||||
getExecutionHistoryUrl: jest
|
||||
.fn()
|
||||
.mockResolvedValue(
|
||||
'http://stackstorm.example.com:8080/?#/history/123abc',
|
||||
),
|
||||
} as any;
|
||||
|
||||
it('should render all executions', async () => {
|
||||
const { getByText } = await renderInTestApp(
|
||||
<TestApiProvider
|
||||
apis={[
|
||||
[stackstormApiRef, mockApi],
|
||||
[
|
||||
configApiRef,
|
||||
new MockConfigApi({ stackstorm: { webUrl: 'http://localhost' } }),
|
||||
],
|
||||
]}
|
||||
>
|
||||
<TestApiProvider apis={[[stackstormApiRef, mockApi]]}>
|
||||
<ExecutionsTable />
|
||||
</TestApiProvider>,
|
||||
);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Link, Table, TableColumn } from '@backstage/core-components';
|
||||
import { useApi, configApiRef, errorApiRef } from '@backstage/core-plugin-api';
|
||||
import { useApi, errorApiRef } from '@backstage/core-plugin-api';
|
||||
import { Execution, stackstormApiRef } from '../../api';
|
||||
import { Status } from './Status';
|
||||
import { ExecutionPanel } from './ExecutionPanel';
|
||||
@@ -37,7 +37,7 @@ export const DenseTable = ({
|
||||
onPageChange,
|
||||
onRowsPerPageChange,
|
||||
}: DenseTableProps) => {
|
||||
const config = useApi(configApiRef);
|
||||
const st2 = useApi(stackstormApiRef);
|
||||
|
||||
const columns: TableColumn<Execution>[] = [
|
||||
{
|
||||
@@ -54,13 +54,7 @@ export const DenseTable = ({
|
||||
{
|
||||
title: 'Execution ID',
|
||||
field: 'id',
|
||||
render: e => (
|
||||
<Link
|
||||
to={`${config.getString('stackstorm.webUrl')}/?#/history/${e.id}`}
|
||||
>
|
||||
{e.id}
|
||||
</Link>
|
||||
),
|
||||
render: e => <Link to={st2.getExecutionHistoryUrl(e.id)}>{e.id}</Link>,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
configApiRef,
|
||||
createApiFactory,
|
||||
createPlugin,
|
||||
createRoutableExtension,
|
||||
@@ -35,11 +36,12 @@ export const stackstormPlugin = createPlugin({
|
||||
createApiFactory({
|
||||
api: stackstormApiRef,
|
||||
deps: {
|
||||
configApi: configApiRef,
|
||||
discoveryApi: discoveryApiRef,
|
||||
fetchApi: fetchApiRef,
|
||||
},
|
||||
factory: ({ discoveryApi, fetchApi }) =>
|
||||
new StackstormClient({
|
||||
factory: ({ configApi, discoveryApi, fetchApi }) =>
|
||||
StackstormClient.fromConfig(configApi, {
|
||||
discoveryApi,
|
||||
fetchApi,
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user