chore: added a sample frontend
Signed-off-by: blam <ben@blam.sh> Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
@@ -23,6 +23,8 @@ import MapIcon from '@material-ui/icons/MyLocation';
|
||||
import LayersIcon from '@material-ui/icons/Layers';
|
||||
import LibraryBooks from '@material-ui/icons/LibraryBooks';
|
||||
import CreateComponentIcon from '@material-ui/icons/AddCircleOutline';
|
||||
import Add from '@material-ui/icons/Add';
|
||||
import List from '@material-ui/icons/List';
|
||||
import SearchIcon from '@material-ui/icons/Search';
|
||||
import MenuIcon from '@material-ui/icons/Menu';
|
||||
import MoneyIcon from '@material-ui/icons/MonetizationOn';
|
||||
@@ -46,6 +48,8 @@ import {
|
||||
SidebarScrollWrapper,
|
||||
SidebarSpace,
|
||||
useSidebarOpenState,
|
||||
SidebarSubmenu,
|
||||
SidebarSubmenuItem,
|
||||
} from '@backstage/core-components';
|
||||
import { MyGroupsSidebarItem } from '@backstage/plugin-org';
|
||||
import GroupIcon from '@material-ui/icons/People';
|
||||
@@ -106,7 +110,16 @@ export const Root = ({ children }: PropsWithChildren<{}>) => (
|
||||
<SidebarItem icon={ExtensionIcon} to="api-docs" text="APIs" />
|
||||
<SidebarItem icon={LibraryBooks} to="docs" text="Docs" />
|
||||
<SidebarItem icon={LayersIcon} to="explore" text="Explore" />
|
||||
<SidebarItem icon={CreateComponentIcon} to="create" text="Create..." />
|
||||
<SidebarItem icon={CreateComponentIcon} to="create" text="Create...">
|
||||
<SidebarSubmenu title="Create">
|
||||
<SidebarSubmenuItem icon={Add} title="Create new" to="create" />
|
||||
<SidebarSubmenuItem
|
||||
icon={List}
|
||||
title="View my jobs"
|
||||
to="create/tasks/me"
|
||||
/>
|
||||
</SidebarSubmenu>
|
||||
</SidebarItem>
|
||||
{/* End global nav */}
|
||||
<SidebarDivider />
|
||||
<SidebarScrollWrapper>
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
"@rjsf/core": "^3.2.1",
|
||||
"@material-table/core": "^4.3.29",
|
||||
"@rjsf/material-ui": "^3.2.1",
|
||||
"@types/json-schema": "^7.0.9",
|
||||
"@uiw/react-codemirror": "^4.7.0",
|
||||
|
||||
@@ -70,6 +70,18 @@ export class ScaffolderClient implements ScaffolderApi {
|
||||
this.useLongPollingLogs = options.useLongPollingLogs ?? false;
|
||||
}
|
||||
|
||||
async listTasks(): Promise<ScaffolderTask[]> {
|
||||
const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder');
|
||||
const url = `${baseUrl}/v2/tasks`;
|
||||
|
||||
const response = await this.fetchApi.fetch(url);
|
||||
if (!response.ok) {
|
||||
throw await ResponseError.fromResponse(response);
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
}
|
||||
|
||||
async getIntegrationsList(
|
||||
options: ScaffolderGetIntegrationsListOptions,
|
||||
): Promise<ScaffolderGetIntegrationsListResponse> {
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2022 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 {
|
||||
Content,
|
||||
Header,
|
||||
Lifecycle,
|
||||
Link,
|
||||
Page,
|
||||
Progress,
|
||||
} from '@backstage/core-components';
|
||||
import { useApi, useRouteRef } from '@backstage/core-plugin-api';
|
||||
import { Grid } from '@material-ui/core';
|
||||
import React from 'react';
|
||||
import { scaffolderApiRef } from '../../api';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
import MaterialTable, { Column } from '@material-table/core';
|
||||
import { rootRouteRef } from '../../routes';
|
||||
import { Duration, Interval, DateTime } from 'luxon';
|
||||
import humanizeDuration from 'humanize-duration';
|
||||
import {
|
||||
StatusError,
|
||||
StatusPending,
|
||||
StatusOK,
|
||||
} from '@backstage/core-components';
|
||||
|
||||
const CreatedAtColumn = ({ createdAt }: { createdAt: string }) => {
|
||||
const createdAtTime = DateTime.fromISO(createdAt);
|
||||
const formatted = Interval.fromDateTimes(createdAtTime, DateTime.local())
|
||||
.toDuration()
|
||||
.valueOf();
|
||||
|
||||
return <p>{humanizeDuration(formatted, { round: true })} ago</p>;
|
||||
};
|
||||
|
||||
const TemplateTitle = ({ templateName }: { templateName?: string }) => {
|
||||
const scaffolder = useApi(scaffolderApiRef);
|
||||
const { value, loading, error } = useAsync(
|
||||
() =>
|
||||
scaffolder.getTemplateParameterSchema({
|
||||
kind: 'Template',
|
||||
namespace: 'default',
|
||||
name: templateName,
|
||||
}),
|
||||
[scaffolder, templateName],
|
||||
);
|
||||
|
||||
if (loading) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <p>{value?.title}</p>;
|
||||
};
|
||||
|
||||
const Status = ({ status }) => {
|
||||
switch (status) {
|
||||
case 'processing':
|
||||
return <StatusPending>{status}</StatusPending>;
|
||||
case 'completed':
|
||||
return <StatusOK>{status}</StatusOK>;
|
||||
case 'error':
|
||||
default:
|
||||
return <StatusError>{status}</StatusError>;
|
||||
}
|
||||
};
|
||||
export const MyTaskPage = () => {
|
||||
const scaffolderApi = useApi(scaffolderApiRef);
|
||||
const { value, loading, error } = useAsync(
|
||||
() => scaffolderApi.listTasks(),
|
||||
[scaffolderApi],
|
||||
);
|
||||
|
||||
const rootLink = useRouteRef(rootRouteRef);
|
||||
|
||||
return (
|
||||
<Page themeId="home">
|
||||
<Header
|
||||
pageTitleOverride="My Tasks"
|
||||
title={
|
||||
<>
|
||||
All my tasks <Lifecycle shorthand />
|
||||
</>
|
||||
}
|
||||
subtitle="All tasks that have been started by me"
|
||||
/>
|
||||
<Content>
|
||||
{loading ? (
|
||||
<Progress />
|
||||
) : (
|
||||
<MaterialTable
|
||||
data={value!}
|
||||
title="My Tasks"
|
||||
columns={[
|
||||
{
|
||||
title: 'Task ID',
|
||||
field: 'id',
|
||||
render: row => (
|
||||
<Link to={`${rootLink()}/tasks/${row.id}`}>{row.id}</Link>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Name',
|
||||
render: row => (
|
||||
<TemplateTitle templateName={row.spec.metadata?.name} />
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Created',
|
||||
field: 'createdAt',
|
||||
render: row => <CreatedAtColumn createdAt={row.createdAt} />,
|
||||
},
|
||||
{
|
||||
title: 'Status',
|
||||
field: 'status',
|
||||
render: row => <Status status={row.status} />,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
</Content>
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2022 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 { MyTaskPage } from './MyTaskPage';
|
||||
@@ -3988,6 +3988,25 @@
|
||||
react-beautiful-dnd "^13.0.0"
|
||||
react-double-scrollbar "0.0.15"
|
||||
|
||||
"@material-table/core@^4.3.29":
|
||||
version "4.3.29"
|
||||
resolved "https://registry.npmjs.org/@material-table/core/-/core-4.3.29.tgz#7f60fe4fc191e016d9be663fa437e00b012eae05"
|
||||
integrity sha512-7vz1oc3bo1eSzk450NgpA61xQjlgCBg7q1TDGrB8ZDMyx2NvLRxTyNBtW8JEPLaQLoCWoDFK7F/VHOYRN1fKuQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
"@date-io/date-fns" "^1.3.13"
|
||||
"@material-ui/icons" "^4.11.2"
|
||||
"@material-ui/pickers" "^3.2.10"
|
||||
"@material-ui/styles" "^4.11.4"
|
||||
classnames "^2.2.6"
|
||||
date-fns "^2.16.1"
|
||||
debounce "^1.2.0"
|
||||
fast-deep-equal "^3.1.3"
|
||||
prop-types "^15.7.2"
|
||||
react-beautiful-dnd "^13.0.0"
|
||||
react-double-scrollbar "0.0.15"
|
||||
uuid "^3.4.0"
|
||||
|
||||
"@material-ui/core@^4.11.0", "@material-ui/core@^4.11.3", "@material-ui/core@^4.12.1", "@material-ui/core@^4.12.2", "@material-ui/core@^4.9.10", "@material-ui/core@^4.9.13":
|
||||
version "4.12.4"
|
||||
resolved "https://registry.npmjs.org/@material-ui/core/-/core-4.12.4.tgz#4ac17488e8fcaf55eb6a7f5efb2a131e10138a73"
|
||||
|
||||
Reference in New Issue
Block a user