diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx
index 9a9191afc5..df54f37dc6 100644
--- a/packages/app/src/App.tsx
+++ b/packages/app/src/App.tsx
@@ -110,7 +110,6 @@ import { ScoreBoardPage } from '@oriflame/backstage-plugin-score-card';
import { StackstormPage } from '@backstage/plugin-stackstorm';
import { PuppetDbPage } from '@backstage/plugin-puppetdb';
import { DevToolsPage } from '@backstage/plugin-devtools';
-import { NomadPage } from '@backstage/plugin-nomad';
import { customDevToolsPage } from './components/devtools/CustomDevToolsPage';
import { CatalogUnprocessedEntitiesPage } from '@backstage/plugin-catalog-unprocessed-entities';
@@ -303,7 +302,6 @@ const routes = (
}>
{customDevToolsPage}
- } />
);
diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx
index f6950f5c62..043a9fc3aa 100644
--- a/packages/app/src/components/catalog/EntityPage.tsx
+++ b/packages/app/src/components/catalog/EntityPage.tsx
@@ -112,7 +112,10 @@ import {
EntityOwnershipCard,
EntityUserProfileCard,
} from '@backstage/plugin-org';
-import { EntityNomadContent } from '@backstage/plugin-nomad';
+import {
+ EntityNomadContent,
+ EntityNomadJobVersionListCard,
+} from '@backstage/plugin-nomad';
import {
EntityPagerDutyCard,
isPagerDutyAvailable,
@@ -173,6 +176,7 @@ import {
isLinguistAvailable,
EntityLinguistCard,
} from '@backstage/plugin-linguist';
+import { isNomadJobIDAvailable } from '@backstage/plugin-nomad';
const customEntityFilterKind = ['Component', 'API', 'System'];
@@ -443,6 +447,14 @@ const overviewContent = (
+
+
+
+
+
+
+
+
);
diff --git a/plugins/nomad-backend/src/service/router.ts b/plugins/nomad-backend/src/service/router.ts
index 161471f63a..aa863e3493 100644
--- a/plugins/nomad-backend/src/service/router.ts
+++ b/plugins/nomad-backend/src/service/router.ts
@@ -16,21 +16,32 @@
import { errorHandler, requestLoggingHandler } from '@backstage/backend-common';
import { Config } from '@backstage/config';
import { InputError } from '@backstage/errors';
-import express, { RequestHandler } from 'express';
+import express from 'express';
import Router from 'express-promise-router';
import { Logger } from 'winston';
-const createEndpoint = (
+export interface RouterOptions {
+ logger: Logger;
+ config: Config;
+}
+
+export async function createRouter(
options: RouterOptions,
- endpoint: string,
-): RequestHandler => {
+): Promise {
const { config, logger } = options;
// Get Nomad addr and token from config
const addr = config.getString('nomad.addr');
const token = config.getOptionalString('nomad.token');
- return async function (req, resp) {
+ const router = Router();
+ router.use(express.json());
+
+ router.get('/health', (_, resp) => {
+ resp.json({ status: 'ok' });
+ });
+
+ router.get('/v1/allocations', async (req, resp) => {
// Check namespace argument
const namespace = (req.query.namespace as string) ?? '';
if (!namespace || namespace === '') {
@@ -39,12 +50,7 @@ const createEndpoint = (
// Check filter argument
const filter = (req.query.filter as string) ?? '';
- if (!filter || filter === '') {
- throw new InputError(`Missing "filter" query parameter`);
- }
- logger.debug(
- `${endpoint} request headers: namespace=${namespace} filter=${filter}`,
- );
+ logger.debug(`request headers: namespace=${namespace} filter=${filter}`);
// Issue the request
const allocationsResp = await fetch(
@@ -62,27 +68,39 @@ const createEndpoint = (
// Deserialize and return
const allocationsBody = await allocationsResp.json();
- logger.debug(`${endpoint} response: ${allocationsBody}`);
+ logger.debug(`/v1/allocations response: ${allocationsBody}`);
resp.json(allocationsBody);
- };
-};
-
-export interface RouterOptions {
- logger: Logger;
- config: Config;
-}
-
-export async function createRouter(
- options: RouterOptions,
-): Promise {
- const router = Router();
- router.use(express.json());
-
- router.get('/health', (_, resp) => {
- resp.json({ status: 'ok' });
});
- router.get('/v1/allocations', createEndpoint(options, '/v1/allocations'));
- router.get('/v1/deployments', createEndpoint(options, '/v1/deployments'));
+
+ router.get('/v1/job/:job_id/versions', async (req, resp) => {
+ // Check namespace argument
+ const namespace = (req.query.namespace as string) ?? '';
+ if (!namespace || namespace === '') {
+ throw new InputError(`Missing "namespace" query parameter`);
+ }
+
+ // Get job ID
+ const jobID = (req.params.job_id as string) ?? '';
+
+ // Issue the request
+ const versionsResp = await fetch(
+ `${addr}/v1/job/${jobID}/versions?namespace=${encodeURIComponent(
+ namespace,
+ )}`,
+ {
+ method: 'GET',
+ headers: {
+ Accept: 'application/json',
+ 'X-Nomad-Token': token || '',
+ },
+ },
+ );
+
+ // Deserialize and return
+ const versionsBody = await versionsResp.json();
+ logger.debug(`/v1/job/:job_id/versions response: ${versionsBody}`);
+ resp.json(versionsBody);
+ });
router.use(requestLoggingHandler());
router.use(errorHandler());
diff --git a/plugins/nomad/src/Router.tsx b/plugins/nomad/src/Router.tsx
index 11c79c31d7..dadeda86db 100644
--- a/plugins/nomad/src/Router.tsx
+++ b/plugins/nomad/src/Router.tsx
@@ -19,7 +19,7 @@ import { Entity } from '@backstage/catalog-model';
import { useEntity } from '@backstage/plugin-catalog-react';
import { MissingAnnotationEmptyState } from '@backstage/core-components';
import { Route, Routes } from 'react-router-dom';
-import { AllocationListTable } from './components/AllocationList/AllocationListTable';
+import { EntityNomadAllocationListTable } from './components/EntityNomadAllocationListTable/EntityNomadAllocationListTable';
/** @public */
export const NOMAD_NAMESPACE_ANNOTATION = 'nomad.io/namespace';
@@ -31,7 +31,11 @@ export const NOMAD_JOB_ID_ANNOTATION = 'nomad.io/job-id';
export const NOMAD_GROUP_ANNOTATION = 'nomad.io/group';
/** @public */
-export const isNomadAvailable = (entity: Entity) =>
+export const isNomadJobIDAvailable = (entity: Entity) =>
+ Boolean(entity.metadata.annotations?.[NOMAD_JOB_ID_ANNOTATION]);
+
+/** @public */
+export const isNomadAllocationsAvailable = (entity: Entity) =>
Boolean(entity.metadata.annotations?.[NOMAD_JOB_ID_ANNOTATION]) ||
Boolean(entity.metadata.annotations?.[NOMAD_GROUP_ANNOTATION]);
@@ -39,7 +43,7 @@ export const isNomadAvailable = (entity: Entity) =>
export const EmbeddedRouter = () => {
const { entity } = useEntity();
- if (!isNomadAvailable(entity)) {
+ if (!isNomadAllocationsAvailable(entity)) {
return (
{
return (
- } />
+ } />
);
};
diff --git a/plugins/nomad/src/api.ts b/plugins/nomad/src/api.ts
index 0cdba4a969..814bba5b6d 100644
--- a/plugins/nomad/src/api.ts
+++ b/plugins/nomad/src/api.ts
@@ -37,13 +37,13 @@ export type NomadApi = {
) => Promise;
/**
- * listDeployments is for listing all deployments matching some part of 'filter'.
+ * listJobVersions is for listing all deployments matching some part of 'filter'.
*
* See: https://developer.hashicorp.com/nomad/api-docs/deployments#list-deployments
*/
- listDeployments: (
- options: ListDeploymentsRequest,
- ) => Promise;
+ listJobVersions: (
+ options: ListJobVersionsRequest,
+ ) => Promise;
};
/** @public */
@@ -79,37 +79,22 @@ export interface DeploymentStatus {
}
/** @public */
-export interface ListDeploymentsRequest {
+export interface ListJobVersionsRequest {
namespace: string;
- filter: string;
+ jobID: string;
}
/** @public */
-export interface ListDeploymentsResponse {
- deployments: Deployment[];
+export interface ListJobVersionsResponse {
+ versions: Version[];
}
/** @public */
-export interface Deployment {
+export interface Version {
ID: string;
- JobID: string;
- JobVersion: number;
- JobModifyIndex: number;
- TaskGroups: {
- [taskGroup: string]: {
- Promoted: boolean;
- DesiredCanaries: number;
- DesiredTotal: number;
- PlacedAllocs: number;
- HealthyAllocs: number;
- UnhealthyAllocs: number;
- };
- };
- JobSpecModifyIndex: number;
- JobCreateIndex: number;
- Status: string;
- CreateIndex: number;
- ModifyIndex: number;
+ SubmitTime: number;
+ Stable: boolean;
+ Version: number;
}
/** @public */
@@ -154,20 +139,22 @@ export class NomadHttpApi implements NomadApi {
}
// TODO: pagination
- async listDeployments(
- options: ListDeploymentsRequest,
- ): Promise {
+ async listJobVersions(
+ options: ListJobVersionsRequest,
+ ): Promise {
const apiUrl = await this.discoveryApi.getBaseUrl('nomad');
const resp = await this.fetchApi.fetch(
- `${apiUrl}/v1/deployments?namespace=${encodeURIComponent(
- options.namespace,
- )}&filter=${encodeURIComponent(options.filter)}`,
+ `${apiUrl}/v1/job/${
+ options.jobID
+ }/versions?namespace=${encodeURIComponent(options.namespace)}`,
);
if (!resp.ok) throw await FetchError.forResponse(resp);
+ const respJson = await resp.json();
+
return Promise.resolve({
- deployments: await resp.json(),
+ versions: respJson.Versions,
});
}
}
diff --git a/plugins/nomad/src/components/AllocationList/AllocationListTable.tsx b/plugins/nomad/src/components/EntityNomadAllocationListTable/EntityNomadAllocationListTable.tsx
similarity index 87%
rename from plugins/nomad/src/components/AllocationList/AllocationListTable.tsx
rename to plugins/nomad/src/components/EntityNomadAllocationListTable/EntityNomadAllocationListTable.tsx
index 9130eb4007..d07563dd6b 100644
--- a/plugins/nomad/src/components/AllocationList/AllocationListTable.tsx
+++ b/plugins/nomad/src/components/EntityNomadAllocationListTable/EntityNomadAllocationListTable.tsx
@@ -16,6 +16,7 @@
import {
Link,
+ MissingAnnotationEmptyState,
ResponseErrorPanel,
StatusError,
StatusOK,
@@ -32,6 +33,7 @@ import {
NOMAD_GROUP_ANNOTATION,
NOMAD_JOB_ID_ANNOTATION,
NOMAD_NAMESPACE_ANNOTATION,
+ isNomadAllocationsAvailable,
} from '../../Router';
import useAsync from 'react-use/lib/useAsync';
@@ -92,13 +94,14 @@ const columns: TableColumn[] = [
];
/**
- * AllocationListTable is roughly based off Nomad's Allocations tab's view.
+ * EntityNomadAllocationListTable is roughly based off Nomad's Allocations tab's view.
*/
-export const AllocationListTable = () => {
+export const EntityNomadAllocationListTable = () => {
// Wait on entity
const { entity } = useEntity();
// Get ref to the backend API
+ const [init, setInit] = useState(true);
const configApi = useApi(configApiRef);
const nomadApi = useApi(nomadApiRef);
const nomadAddr = configApi.getString('nomad.addr');
@@ -107,6 +110,13 @@ export const AllocationListTable = () => {
const [allocations, setAllocations] = useState([]);
const [err, setErr] = useState();
+ // Check that attributes are available
+ if (!isNomadAllocationsAvailable(entity)) {
+ ;
+ }
+
// Get plugin attributes
const namespace =
entity.metadata.annotations?.[NOMAD_NAMESPACE_ANNOTATION] ?? 'default';
@@ -137,10 +147,8 @@ export const AllocationListTable = () => {
.sort(({ ClientStatus: a }, { ClientStatus: b }) => {
if (a === 'running' || b !== 'running') {
return -1;
- } else if (a === b || a !== 'running') {
- return 0;
}
- return 1;
+ return 0;
});
setAllocations(results.map(row => ({ ...row, id: row.ID, nomadAddr })));
@@ -148,14 +156,21 @@ export const AllocationListTable = () => {
} catch (e) {
setAllocations([]);
setErr(e);
- return;
}
};
// Start querying for allocations every 5s
useAsync(async () => {
- query();
- return () => clearInterval(setInterval(query, 5000));
+ if (init) {
+ setInit(false);
+ query();
+ }
+
+ const interval = setTimeout(() => {
+ query();
+ }, 5_000);
+
+ return () => clearTimeout(interval);
}, [allocations, entity]);
// Store a ref to a potential error
diff --git a/plugins/nomad/src/components/EntityNomadJobVersionListCard/EntityNomadJobVersionListCard.tsx b/plugins/nomad/src/components/EntityNomadJobVersionListCard/EntityNomadJobVersionListCard.tsx
new file mode 100644
index 0000000000..909fd7a236
--- /dev/null
+++ b/plugins/nomad/src/components/EntityNomadJobVersionListCard/EntityNomadJobVersionListCard.tsx
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2020 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ InfoCard,
+ MissingAnnotationEmptyState,
+ ResponseErrorPanel,
+ Table,
+ TableColumn,
+} from '@backstage/core-components';
+import { useEntity } from '@backstage/plugin-catalog-react';
+import React, { useEffect, useState } from 'react';
+import { Version, nomadApiRef } from '../../api';
+import { configApiRef, useApi } from '@backstage/core-plugin-api';
+import {
+ NOMAD_JOB_ID_ANNOTATION,
+ NOMAD_NAMESPACE_ANNOTATION,
+ isNomadJobIDAvailable,
+} from '../../Router';
+import OpenInNewIcon from '@material-ui/icons/OpenInNew';
+import { Chip } from '@material-ui/core';
+
+type rowType = Version & { nomadAddr: string };
+
+const columns: TableColumn[] = [
+ {
+ title: 'Version',
+ field: 'Version',
+ render: row => row.Version,
+ },
+ {
+ title: 'Stable',
+ field: 'Stable',
+ render: row => ,
+ },
+ {
+ title: 'Submitted',
+ field: 'SubmitTime',
+ render: row => new Date(row.SubmitTime / 1000000).toLocaleString(),
+ },
+];
+
+/**
+ * EntityNomadJobVersionListCard is roughly based on the Nomad UI's versions tab.
+ */
+export const EntityNomadJobVersionListCard = () => {
+ // Wait on entity
+ const { entity } = useEntity();
+
+ // Get ref to the backend API
+ const configApi = useApi(configApiRef);
+ const nomadApi = useApi(nomadApiRef);
+ const nomadAddr = configApi.getString('nomad.addr');
+
+ // Store results of calling API
+ const [init, setInit] = useState(true);
+ const [versions, setVersions] = useState([]);
+ const [err, setErr] = useState();
+
+ // Get plugin attributes
+ const namespace =
+ entity.metadata.annotations?.[NOMAD_NAMESPACE_ANNOTATION] ?? 'default';
+ const jobID = entity.metadata.annotations?.[NOMAD_JOB_ID_ANNOTATION] ?? '';
+
+ // Start querying for allocations every 10s
+ useEffect(() => {
+ // Create a query to update allocations
+ const query = async () => {
+ try {
+ // Make call to nomad-backend
+ const resp = await nomadApi.listJobVersions({ namespace, jobID });
+
+ setVersions(
+ resp.versions.map(row => ({ ...row, id: row.ID, nomadAddr })),
+ );
+ setErr(undefined);
+ } catch (e) {
+ setVersions([]);
+ setErr(e);
+ }
+ };
+
+ if (init) {
+ setInit(false);
+ query();
+ }
+
+ const interval = setTimeout(() => {
+ query();
+ }, 10_000);
+
+ return () => clearTimeout(interval);
+ }, [init, jobID, namespace, nomadAddr, nomadApi]);
+
+ // Store a ref to a potential error
+ if (err) {
+ return ;
+ }
+
+ // Check that job ID is set
+ if (!isNomadJobIDAvailable(entity)) {
+ return (
+
+
+
+ );
+ }
+
+ return (
+
+ title="Job Versions"
+ actions={[
+ {
+ icon: () => ,
+ tooltip: 'Open Job Versions Tab in Nomad',
+ isFreeAction: true,
+ onClick: () => window.open(`${nomadAddr}/ui/jobs/${jobID}/versions`),
+ },
+ ]}
+ options={{
+ search: false,
+ padding: 'dense',
+ sorting: true,
+ draggable: false,
+ paging: false,
+ debounceInterval: 500,
+ filterCellStyle: { padding: '0 16px 0 20px' },
+ }}
+ columns={columns}
+ data={versions}
+ />
+ );
+};
diff --git a/plugins/nomad/src/components/NomadComponent/NomadComponent.test.tsx b/plugins/nomad/src/components/NomadComponent/NomadComponent.test.tsx
deleted file mode 100644
index 31b7319fd6..0000000000
--- a/plugins/nomad/src/components/NomadComponent/NomadComponent.test.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2023 The Backstage Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React from 'react';
-import { NomadComponent } from './NomadComponent';
-import { rest } from 'msw';
-import { setupServer } from 'msw/node';
-import { screen } from '@testing-library/react';
-import {
- setupRequestMockHandlers,
- renderInTestApp,
-} from '@backstage/test-utils';
-
-describe('NomadComponent', () => {
- const server = setupServer();
- // Enable sane handlers for network requests
- setupRequestMockHandlers(server);
-
- // setup mock response
- beforeEach(() => {
- server.use(
- rest.get('/*', (_, res, ctx) => res(ctx.status(200), ctx.json({}))),
- );
- });
-
- it('should render', async () => {
- await renderInTestApp();
- expect(screen.getByText('Welcome to nomad!')).toBeInTheDocument();
- });
-});
diff --git a/plugins/nomad/src/components/NomadComponent/NomadComponent.tsx b/plugins/nomad/src/components/NomadComponent/NomadComponent.tsx
deleted file mode 100644
index cd7334d7eb..0000000000
--- a/plugins/nomad/src/components/NomadComponent/NomadComponent.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2023 The Backstage Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React from 'react';
-import { Typography, Grid } from '@material-ui/core';
-import {
- InfoCard,
- Header,
- Page,
- Content,
- ContentHeader,
- HeaderLabel,
- SupportButton,
-} from '@backstage/core-components';
-import { NomadFetchComponent } from '../NomadFetchComponent';
-
-export const NomadComponent = () => (
-
-
-
-
- A description of your plugin goes here.
-
-
-
-
-
- All content should be wrapped in a card like this.
-
-
-
-
-
-
-
-
-
-);
diff --git a/plugins/nomad/src/components/NomadComponent/index.ts b/plugins/nomad/src/components/NomadComponent/index.ts
deleted file mode 100644
index aeecd0d9e6..0000000000
--- a/plugins/nomad/src/components/NomadComponent/index.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright 2023 The Backstage Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-export { NomadComponent } from './NomadComponent';
diff --git a/plugins/nomad/src/components/NomadFetchComponent/NomadFetchComponent.test.tsx b/plugins/nomad/src/components/NomadFetchComponent/NomadFetchComponent.test.tsx
deleted file mode 100644
index 48c27dce05..0000000000
--- a/plugins/nomad/src/components/NomadFetchComponent/NomadFetchComponent.test.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2023 The Backstage Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React from 'react';
-import { render, screen } from '@testing-library/react';
-import { NomadFetchComponent } from './NomadFetchComponent';
-import { rest } from 'msw';
-import { setupServer } from 'msw/node';
-import { setupRequestMockHandlers } from '@backstage/test-utils';
-
-describe('NomadFetchComponent', () => {
- const server = setupServer();
- // Enable sane handlers for network requests
- setupRequestMockHandlers(server);
-
- // setup mock response
- beforeEach(() => {
- server.use(
- rest.get('https://randomuser.me/*', (_, res, ctx) =>
- res(ctx.status(200), ctx.delay(2000), ctx.json({})),
- ),
- );
- });
- it('should render', async () => {
- await render();
- expect(await screen.findByTestId('progress')).toBeInTheDocument();
- });
-});
diff --git a/plugins/nomad/src/components/NomadFetchComponent/NomadFetchComponent.tsx b/plugins/nomad/src/components/NomadFetchComponent/NomadFetchComponent.tsx
deleted file mode 100644
index 0cd3061a3e..0000000000
--- a/plugins/nomad/src/components/NomadFetchComponent/NomadFetchComponent.tsx
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2023 The Backstage Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React from 'react';
-import { makeStyles } from '@material-ui/core/styles';
-import {
- Table,
- TableColumn,
- Progress,
- ResponseErrorPanel,
-} from '@backstage/core-components';
-import { fetchApiRef, useApi } from '@backstage/core-plugin-api';
-import useAsync from 'react-use/lib/useAsync';
-
-const useStyles = makeStyles({
- avatar: {
- height: 32,
- width: 32,
- borderRadius: '50%',
- },
-});
-
-type User = {
- gender: string; // "male"
- name: {
- title: string; // "Mr",
- first: string; // "Duane",
- last: string; // "Reed"
- };
- location: object; // {street: {number: 5060, name: "Hickory Creek Dr"}, city: "Albany", state: "New South Wales",…}
- email: string; // "duane.reed@example.com"
- login: object; // {uuid: "4b785022-9a23-4ab9-8a23-cb3fb43969a9", username: "blackdog796", password: "patch",…}
- dob: object; // {date: "1983-06-22T12:30:23.016Z", age: 37}
- registered: object; // {date: "2006-06-13T18:48:28.037Z", age: 14}
- phone: string; // "07-2154-5651"
- cell: string; // "0405-592-879"
- id: {
- name: string; // "TFN",
- value: string; // "796260432"
- };
- picture: { medium: string }; // {medium: "https://randomuser.me/api/portraits/men/95.jpg",…}
- nat: string; // "AU"
-};
-
-type DenseTableProps = {
- users: User[];
-};
-
-export const DenseTable = ({ users }: DenseTableProps) => {
- const classes = useStyles();
-
- const columns: TableColumn[] = [
- { title: 'Avatar', field: 'avatar' },
- { title: 'Name', field: 'name' },
- { title: 'Email', field: 'email' },
- { title: 'Nationality', field: 'nationality' },
- ];
-
- const data = users.map(user => {
- return {
- avatar: (
-
- ),
- name: `${user.name.first} ${user.name.last}`,
- email: user.email,
- nationality: user.nat,
- };
- });
-
- return (
-
- );
-};
-
-export const NomadFetchComponent = () => {
- const { fetch } = useApi(fetchApiRef);
- const { value, loading, error } = useAsync(async (): Promise => {
- const response = await fetch('https://randomuser.me/api/?results=20');
- const data = await response.json();
- return data.results;
- }, []);
-
- if (loading) {
- return ;
- } else if (error) {
- return ;
- }
-
- return ;
-};
diff --git a/plugins/nomad/src/components/NomadFetchComponent/index.ts b/plugins/nomad/src/components/index.ts
similarity index 79%
rename from plugins/nomad/src/components/NomadFetchComponent/index.ts
rename to plugins/nomad/src/components/index.ts
index 8e30a21fd1..d113bf73d9 100644
--- a/plugins/nomad/src/components/NomadFetchComponent/index.ts
+++ b/plugins/nomad/src/components/index.ts
@@ -13,4 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-export { NomadFetchComponent } from './NomadFetchComponent';
+import { EntityNomadJobVersionListCard } from './EntityNomadJobVersionListCard/EntityNomadJobVersionListCard';
+
+export { EntityNomadJobVersionListCard };
diff --git a/plugins/nomad/src/index.ts b/plugins/nomad/src/index.ts
index 59ae5efaee..601c133b52 100644
--- a/plugins/nomad/src/index.ts
+++ b/plugins/nomad/src/index.ts
@@ -13,5 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-export { nomadPlugin, NomadPage, EntityNomadContent } from './plugin';
-export { isNomadAvailable, EmbeddedRouter } from './Router';
+export { nomadPlugin } from './plugin';
+export {
+ isNomadAllocationsAvailable,
+ isNomadJobIDAvailable,
+ EmbeddedRouter,
+} from './Router';
+export { EntityNomadJobVersionListCard } from './components';
diff --git a/plugins/nomad/src/plugin.ts b/plugins/nomad/src/plugin.ts
index 1b45e803b4..65181724d5 100644
--- a/plugins/nomad/src/plugin.ts
+++ b/plugins/nomad/src/plugin.ts
@@ -44,22 +44,3 @@ export const nomadPlugin = createPlugin({
entityContent: entityContentRouteRef,
},
});
-
-/** @public */
-export const NomadPage = nomadPlugin.provide(
- createRoutableExtension({
- name: 'NomadPage',
- component: () =>
- import('./components/NomadComponent').then(m => m.NomadComponent),
- mountPoint: rootRouteRef,
- }),
-);
-
-/** @public */
-export const EntityNomadContent = nomadPlugin.provide(
- createRoutableExtension({
- name: 'EntityNomadContent',
- component: () => import('./Router').then(m => m.EmbeddedRouter),
- mountPoint: entityContentRouteRef,
- }),
-);