Skip to content

Commit be402ac

Browse files
committed
Merge branch 'development'
2 parents 80d2978 + d811bd1 commit be402ac

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+909
-492
lines changed

src/components/deeploys/ApplicationCard.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,19 @@ export default function ApplicationCard({ app }: { app: DeeployApp }) {
77
return (
88
<BorderedCard>
99
<div className="row justify-between gap-3 lg:gap-6">
10-
<div className="min-w-[212px]">
11-
<CardItem label="Version" value={<>{app.alias}</>} isBold />
10+
<div className="min-w-[168px]">
11+
<CardItem label="Alias" value={<>{app.alias}</>} isBold />
1212
</div>
1313

14-
<div className="min-w-[212px]">
14+
<div className="min-w-[168px]">
1515
<CardItem label="Plugin Signature" value={<>{app.pluginSignature}</>} />
1616
</div>
1717

1818
<div className="min-w-[64px]">
1919
<CardItem label="Nodes" value={<>{app.nodes}</>} />
2020
</div>
2121

22-
<div className="min-w-[82px]">
22+
<div className="min-w-[64px]">
2323
<CardItem
2424
label="GPU/CPU"
2525
value={<SmallTag variant={app.processor === 'GPU' ? 'green' : 'blue'}>{app.processor}</SmallTag>}
@@ -32,10 +32,10 @@ export default function ApplicationCard({ app }: { app: DeeployApp }) {
3232

3333
<div className="min-w-[112px]">
3434
<CardItem
35-
label="Deadline"
35+
label="Expiration Date"
3636
value={
3737
<>
38-
{new Date(app.deadline).toLocaleDateString('en-US', {
38+
{new Date(app.expiresAt).toLocaleDateString('en-US', {
3939
month: 'short',
4040
day: 'numeric',
4141
year: 'numeric',
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { InteractionContextType, useInteractionContext } from '@lib/contexts/interaction';
2+
import { routePath } from '@lib/routes/route-paths';
3+
import db from '@lib/storage/db';
4+
import { BorderedCard } from '@shared/cards/BorderedCard';
5+
import { CardItem } from '@shared/cards/CardItem';
6+
import ContextMenuWithTrigger from '@shared/ContextMenuWithTrigger';
7+
import { Job, Project } from '@typedefs/deployment';
8+
import { useLiveQuery } from 'dexie-react-hooks';
9+
import { toast } from 'react-hot-toast';
10+
import { RiDeleteBinLine } from 'react-icons/ri';
11+
import { Link } from 'react-router-dom';
12+
13+
export default function DraftCard({ project }: { project: Project }) {
14+
const confirm = useInteractionContext() as InteractionContextType;
15+
16+
const jobs: Job[] | undefined = useLiveQuery(() => db.jobs.where('projectId').equals(project.id).toArray(), [project]);
17+
18+
const onDeleteProject = async () => {
19+
try {
20+
const confirmed = await confirm(
21+
<div className="col gap-3">
22+
<div>Are you sure you want to delete the following project draft?</div>
23+
24+
<div className="row gap-2">
25+
<div className="mt-[1px] h-2.5 w-2.5 rounded-full" style={{ backgroundColor: project.color }}></div>
26+
<div className="font-medium">{project.name}</div>
27+
</div>
28+
</div>,
29+
);
30+
31+
if (!confirmed) return;
32+
33+
await db.projects.delete(project.id);
34+
toast.success('Project draft deleted successfully.');
35+
} catch (error) {
36+
console.error('Error deleting project draft:', error);
37+
toast.error('Failed to delete project draft.');
38+
}
39+
};
40+
41+
return (
42+
<Link to={`${routePath.deeploys}/${routePath.project}/${project.id}`}>
43+
<BorderedCard isHoverable>
44+
<div className="row justify-between gap-3 lg:gap-6">
45+
<div className="min-w-[82px]">
46+
<CardItem label="ID" value={<>#{project.id}</>} isBold />
47+
</div>
48+
49+
<div className="min-w-[212px]">
50+
<CardItem
51+
label="Name"
52+
value={
53+
<div className="row gap-2">
54+
<div
55+
className="mt-[1px] h-2.5 w-2.5 rounded-full"
56+
style={{ backgroundColor: project.color }}
57+
></div>
58+
<div>{project.name}</div>
59+
</div>
60+
}
61+
isBold
62+
/>
63+
</div>
64+
65+
<div className="min-w-[90px]">
66+
<CardItem label="Jobs" value={<>{jobs?.length ?? 0}</>} />
67+
</div>
68+
69+
<div className="min-w-[212px]">
70+
<CardItem
71+
label="Created"
72+
value={
73+
<>
74+
{new Date(project.createdAt).toLocaleString('en-US', {
75+
month: 'short',
76+
day: 'numeric',
77+
year: 'numeric',
78+
hour: 'numeric',
79+
minute: 'numeric',
80+
})}
81+
</>
82+
}
83+
/>
84+
</div>
85+
86+
<ContextMenuWithTrigger
87+
items={[
88+
{
89+
key: 'delete',
90+
label: 'Delete',
91+
description: 'Removes the draft from storage',
92+
icon: <RiDeleteBinLine />,
93+
onPress: () => onDeleteProject(),
94+
},
95+
]}
96+
/>
97+
</div>
98+
</BorderedCard>
99+
</Link>
100+
);
101+
}

src/components/deeploys/Drafts.tsx

Lines changed: 8 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,29 @@
1-
import { routePath } from '@lib/routes/route-paths';
21
import db from '@lib/storage/db';
3-
import { BorderedCard } from '@shared/cards/BorderedCard';
4-
import { CardItem } from '@shared/cards/CardItem';
52
import EmptyData from '@shared/EmptyData';
63
import ListHeader from '@shared/ListHeader';
4+
import { Project } from '@typedefs/deployment';
75
import { useLiveQuery } from 'dexie-react-hooks';
86
import { RiDraftLine } from 'react-icons/ri';
9-
import { Link } from 'react-router-dom';
7+
import DraftCard from './DraftCard';
108

119
function Drafts() {
12-
const drafts = useLiveQuery(() => db.projects.toArray());
10+
const drafts: Project[] | undefined = useLiveQuery(() => db.projects.toArray());
1311

1412
return (
1513
<div className="list">
1614
<ListHeader>
1715
<div className="min-w-[82px]">ID</div>
1816
<div className="min-w-[212px]">Name</div>
17+
<div className="min-w-[90px]">Jobs</div>
1918
<div className="min-w-[212px]">Created</div>
19+
20+
{/* Accounts for the context menu button */}
21+
<div className="min-w-[32px]"></div>
2022
</ListHeader>
2123

2224
{drafts?.map((project) => (
2325
<div key={project.id}>
24-
{/* TODO: Move to a component */}
25-
<Link to={`${routePath.deeploys}/${routePath.project}/${project.id}`}>
26-
<BorderedCard isHoverable>
27-
<div className="row justify-between gap-3 lg:gap-6">
28-
<div className="min-w-[82px]">
29-
<CardItem label="ID" value={<>#{project.id}</>} isBold />
30-
</div>
31-
32-
<div className="min-w-[212px]">
33-
<CardItem
34-
label="Name"
35-
value={
36-
<div className="row gap-2">
37-
<div
38-
className="mt-[1px] h-2.5 w-2.5 rounded-full"
39-
style={{ backgroundColor: project.color }}
40-
></div>
41-
<div>{project.name}</div>
42-
</div>
43-
}
44-
isBold
45-
/>
46-
</div>
47-
48-
<div className="min-w-[212px]">
49-
<CardItem
50-
label="Created"
51-
value={
52-
<>
53-
{new Date(project.datetime).toLocaleString('en-US', {
54-
month: 'short',
55-
day: 'numeric',
56-
year: 'numeric',
57-
hour: 'numeric',
58-
minute: 'numeric',
59-
})}
60-
</>
61-
}
62-
/>
63-
</div>
64-
</div>
65-
</BorderedCard>
66-
</Link>
26+
<DraftCard project={project} />
6727
</div>
6828
))}
6929

src/components/deeploys/Running.tsx

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,41 +6,25 @@ import { RiDraftLine } from 'react-icons/ri';
66

77
const running: DeeployApp[] = [
88
{
9-
alias: 'native_app_x',
10-
pluginSignature: 'CONTAINER_APP_RUNNER',
11-
nodes: 3,
12-
processor: 'GPU',
13-
runningNodes: '2/3',
14-
deadline: '2026-12-25',
15-
},
16-
{
17-
alias: 'some_app_name_05',
18-
pluginSignature: 'SOME_PLUGIN_01',
19-
nodes: 4,
20-
processor: 'GPU',
21-
runningNodes: '4/4',
22-
deadline: '2027-02-14',
23-
},
24-
{
25-
alias: 'service_pubapi_etc',
26-
pluginSignature: 'CONTAINER_APP_RUNNER',
9+
alias: 'postgres_service',
10+
pluginSignature: 'DB_RUNNER_1',
2711
nodes: 1,
2812
processor: 'CPU',
2913
runningNodes: '1/1',
30-
deadline: '2026-11-30',
14+
expiresAt: '2026-11-30',
3115
},
3216
];
3317

3418
function Running() {
3519
return (
3620
<div className="list">
3721
<ListHeader>
38-
<div className="min-w-[212px]">Alias</div>
39-
<div className="min-w-[212px]">Plugin Signature</div>
22+
<div className="min-w-[168px]">Alias</div>
23+
<div className="min-w-[168px]">Plugin Signature</div>
4024
<div className="min-w-[64px]">Nodes</div>
41-
<div className="min-w-[82px]">GPU/CPU</div>
25+
<div className="min-w-[64px]">GPU/CPU</div>
4226
<div className="min-w-[112px]">Running Nodes</div>
43-
<div className="min-w-[112px]">Deadline</div>
27+
<div className="min-w-[112px]">Expiration Date</div>
4428
</ListHeader>
4529

4630
{running.map((app, index) => (

src/components/job/JobFormButtons.tsx

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Button } from '@heroui/button';
22
import { DeploymentContextType, useDeploymentContext } from '@lib/contexts/deployment';
3+
import { downloadDataAsJson } from '@lib/utils';
34
import { customContainerTypeValue } from '@schemas/common';
45
import { specificationsBaseKeys } from '@schemas/steps/specifications';
56
import { FieldValues, useFormContext } from 'react-hook-form';
@@ -58,22 +59,6 @@ function JobFormButtons({ steps }: Props) {
5859
downloadDataAsJson(formData, `job-${formData.formType}-${Date.now()}.json`);
5960
};
6061

61-
const downloadDataAsJson = (data: any, filename: string) => {
62-
const jsonString = JSON.stringify(data, null, 2);
63-
const blob = new Blob([jsonString], { type: 'application/json' });
64-
const url = URL.createObjectURL(blob);
65-
66-
const link = document.createElement('a');
67-
link.href = url;
68-
link.download = filename;
69-
document.body.appendChild(link);
70-
link.click();
71-
document.body.removeChild(link);
72-
73-
// Clean up the URL object
74-
URL.revokeObjectURL(url);
75-
};
76-
7762
return (
7863
<div className="row w-full justify-between pt-2">
7964
<div className="row gap-2">

src/components/job/JobFormWrapper.tsx

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import JobFormHeader from '@components/job/JobFormHeader';
66
import { APPLICATION_TYPES } from '@data/applicationTypes';
77
import { BOOLEAN_TYPES } from '@data/booleanTypes';
88
import { CONTAINER_TYPES } from '@data/containerTypes';
9-
import { DYNAMIC_ENV_TYPES } from '@data/dynamicEnvTypes';
109
import { PLUGIN_SIGNATURE_TYPES } from '@data/pluginSignatureTypes';
1110
import { POLICY_TYPES } from '@data/policyTypes';
1211
import { SERVICE_TYPES } from '@data/serviceTypes';
@@ -40,7 +39,7 @@ function JobFormWrapper() {
4039
customMemory: '',
4140
},
4241
deployment: {
43-
enableNgrok: BOOLEAN_TYPES[0],
42+
enableTunneling: BOOLEAN_TYPES[0],
4443
},
4544
});
4645

@@ -49,17 +48,7 @@ function JobFormWrapper() {
4948
deployment: {
5049
...getBaseSchemaDefaults().deployment,
5150
port: '',
52-
envVars: [{ key: '', value: '' }],
53-
// dynamicEnvVars: [
54-
// {
55-
// key: '',
56-
// values: [
57-
// { type: DYNAMIC_ENV_TYPES[0], value: '' },
58-
// { type: DYNAMIC_ENV_TYPES[0], value: '' },
59-
// { type: DYNAMIC_ENV_TYPES[0], value: '' },
60-
// ],
61-
// },
62-
// ],
51+
// envVars: [{ key: '', value: '' }],
6352
restartPolicy: POLICY_TYPES[0],
6453
imagePullPolicy: POLICY_TYPES[0],
6554
},
@@ -82,17 +71,17 @@ function JobFormWrapper() {
8271
deployment: {
8372
...getBaseSchemaDefaults().deployment,
8473
serviceType: SERVICE_TYPES[0],
85-
envVars: [{ key: '', value: '' }],
86-
dynamicEnvVars: [
87-
{
88-
key: '',
89-
values: [
90-
{ type: DYNAMIC_ENV_TYPES[0], value: '' },
91-
{ type: DYNAMIC_ENV_TYPES[0], value: '' },
92-
{ type: DYNAMIC_ENV_TYPES[0], value: '' },
93-
],
94-
},
95-
],
74+
// envVars: [{ key: '', value: '' }],
75+
// dynamicEnvVars: [
76+
// {
77+
// key: '',
78+
// values: [
79+
// { type: DYNAMIC_ENV_TYPES[0], value: '' },
80+
// { type: DYNAMIC_ENV_TYPES[0], value: '' },
81+
// { type: DYNAMIC_ENV_TYPES[0], value: '' },
82+
// ],
83+
// },
84+
// ],
9685
},
9786
});
9887

src/components/job/job-steps/PaymentSummary.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ function PaymentSummary() {
5454

5555
<SlateCard>
5656
<div className="row justify-between gap-8 p-2">
57-
<div className="text-lg font-medium text-slate-500">Amount due</div>
57+
<div className="text-[15px] font-semibold text-slate-500">Amount due</div>
5858

5959
<div className="text-xl font-semibold text-primary">
6060
<span className="text-slate-500">$USDC</span> {getJobCost(specifications)}

0 commit comments

Comments
 (0)