Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(provider): provider attributes and actions #451

Merged
merged 60 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
ebe6471
added server-access and server-form files
jigar-arc10 Aug 22, 2024
6342ed9
added wallet import page - wip, fixed issue with file upload in serve…
jigar-arc10 Aug 23, 2024
7f89ed8
added become-provider steps ui
jigar-arc10 Aug 29, 2024
58055d7
server access step added with state support
jigar-arc10 Sep 18, 2024
192d116
added provider config and provider attribute screen
jigar-arc10 Sep 19, 2024
da07743
added provider process with hoc to prevent access to pages
jigar-arc10 Oct 7, 2024
329e06c
added progress for becoming prvider for final stage
jigar-arc10 Oct 8, 2024
51e5ef0
Code clean up and added navigation logic to homecontainer
jigar-arc10 Oct 10, 2024
c977e2e
package lock updated
jigar-arc10 Oct 10, 2024
66d0f11
fixed package-lock.json merge issue
jigar-arc10 Oct 10, 2024
25ed729
more cleanup and remove general warnings
jigar-arc10 Oct 10, 2024
897066e
removed unused npm package
jigar-arc10 Oct 10, 2024
aefe70b
fix minor error on api
jigar-arc10 Oct 11, 2024
8e5eb6a
Added dashboard and actions page
jigar-arc10 Oct 11, 2024
ea30723
change status api endpoint
jigar-arc10 Oct 11, 2024
d024c0d
Merge branch 'feature/provider-console/become-provider-process' into …
jigar-arc10 Oct 11, 2024
ead4eac
added stat line and pie charts
jigar-arc10 Oct 11, 2024
f5c243f
Added console apis to get dashboard data and show appropriate details
jigar-arc10 Oct 11, 2024
4472dbd
fixed actions and changed home component
jigar-arc10 Oct 12, 2024
8df762a
token varification and refresh token fix
jigar-arc10 Oct 15, 2024
d4288b3
changed wallet connect from wallet status to wallet provider
jigar-arc10 Oct 15, 2024
6e8b289
fixed issue in loading provider status
jigar-arc10 Oct 16, 2024
44934ae
fixed home loading issue
jigar-arc10 Oct 16, 2024
d91d340
fixed refresh token, added disabled menu items
jigar-arc10 Oct 16, 2024
fd62ae2
fixed build process
jigar-arc10 Oct 16, 2024
3276a95
feat(provider): added sentry and docker
jigar-arc10 Oct 17, 2024
8f123e1
fix(provider): fixed wallet switching and getting status
jigar-arc10 Oct 18, 2024
5fa9f63
feat(provider): reduced number of events in dashboard
jigar-arc10 Oct 18, 2024
2b0d5e0
feat(provider): added docker compose changes for provider-console
jigar-arc10 Oct 18, 2024
781a99c
feat(provider): added deployments and deployment detail page
jigar-arc10 Oct 18, 2024
ee5d564
fix(provider): change hours to seconds for calculation purpose)
jigar-arc10 Oct 18, 2024
7057434
feat(provider): added auth for deployments and deployment details page
jigar-arc10 Oct 18, 2024
8648e13
feat(provider): added env and removed settingsprovider
jigar-arc10 Oct 29, 2024
f1637fd
fix(provider): fix lint errors and removed console.logs
jigar-arc10 Oct 29, 2024
614c4ba
fix(provider): become-provider looped, fixed it
jigar-arc10 Oct 30, 2024
5d08b82
fix(provider): router and reset process fixed
jigar-arc10 Oct 30, 2024
1110b35
fix(provider): removed Get Started button for now
jigar-arc10 Oct 30, 2024
f2696bf
fix(provider): removed unused import in nav
jigar-arc10 Oct 30, 2024
7344be9
fix(provider): change functions to react fc component
jigar-arc10 Oct 30, 2024
7f9da2b
fix(provider): fix lint issues
jigar-arc10 Oct 30, 2024
c9df37a
fix(provider): change functions to react fc component
jigar-arc10 Oct 31, 2024
1f2d277
fix(provider): rebased main
jigar-arc10 Oct 31, 2024
a97c913
fix(provider): added docker build and fix build related issues
jigar-arc10 Nov 5, 2024
91e8bcd
feat(provider): control machine edit, add from sidebar
jigar-arc10 Nov 5, 2024
c2bb251
feat(provider): added attributes screen
jigar-arc10 Nov 5, 2024
f4629af
fix(provider): control machine auto connect on page load
jigar-arc10 Nov 5, 2024
aa5009a
Merge branch 'feature/provider/control-machine' into feature/provider…
jigar-arc10 Nov 5, 2024
3811d55
fix(provider): fix loading not showing while connecting provider cont…
jigar-arc10 Nov 6, 2024
2df1f61
Merge branch 'feature/provider/control-machine' into feature/provider…
jigar-arc10 Nov 6, 2024
226e744
fix(provider): close drawer on successfull connection
jigar-arc10 Nov 6, 2024
4927267
feat(provider): change favicon to akash favicon
jigar-arc10 Nov 6, 2024
799001a
Merge branch 'feature/provider/control-machine' into feature/provider…
jigar-arc10 Nov 6, 2024
38ec68e
feat(provider): provider add, edit and remove and show acitons list page
jigar-arc10 Nov 6, 2024
e587c32
fix(provider): fix url when provider process finish
jigar-arc10 Nov 6, 2024
13c537b
Merge branch 'main' into feature/provider/control-machine
jigar-arc10 Nov 14, 2024
eeb82b8
fix(provider): merge issues with main
jigar-arc10 Nov 14, 2024
1303c66
Merge branch 'feature/provider/control-machine' into feature/provider…
jigar-arc10 Nov 14, 2024
45c82f0
Merge branch 'main' into feature/provider/attributes-actions
jigar-arc10 Nov 26, 2024
78913de
fix(provider): changed to useQuery and fix lint
jigar-arc10 Dec 2, 2024
bb76982
chore(provider): removed comment
jigar-arc10 Dec 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import React from "react";
import { Controller, SubmitHandler, useFieldArray, useForm } from "react-hook-form";
import {
Alert,
AlertDescription,
AlertTitle,
Button,
Form,
FormControl,
Expand All @@ -14,21 +17,25 @@ import {
SelectContent,
SelectItem,
SelectTrigger,
Separator
} from "@akashnetwork/ui/components";
Separator } from "@akashnetwork/ui/components";
import { zodResolver } from "@hookform/resolvers/zod";
import { Plus, Trash } from "iconoir-react";
import { useAtom } from "jotai";
import { z } from "zod";

import providerProcessStore from "@src/store/providerProcessStore";
import { useControlMachine } from "@src/context/ControlMachineProvider";
import providerProcessStore, { ProviderAttribute } from "@src/store/providerProcessStore";
import restClient from "@src/utils/restClient";
import { sanitizeMachineAccess } from "@src/utils/sanityUtils";
import { providerAttributesFormValuesSchema } from "../../types/providerAttributes";
import { ResetProviderForm } from "./ResetProviderProcess";

const attributeKeys = Object.keys(providerAttributesFormValuesSchema.shape);

interface ProviderAttributesProps {
onComplete: () => void;
existingAttributes?: ProviderAttribute[];
editMode?: boolean;
onComplete?: () => void;
}

const providerFormSchema = z.object({
Expand All @@ -43,40 +50,68 @@ const providerFormSchema = z.object({

type ProviderFormValues = z.infer<typeof providerFormSchema>;

export const ProviderAttributes: React.FC<ProviderAttributesProps> = ({ onComplete }) => {
export const ProviderAttributes: React.FunctionComponent<ProviderAttributesProps> = ({ onComplete, existingAttributes, editMode }) => {
const [providerPricing, setProviderPricing] = useAtom(providerProcessStore.providerProcessAtom);
const form = useForm<ProviderFormValues>({
resolver: zodResolver(providerFormSchema),
defaultValues: {
attributes: [{ key: "", value: "", customKey: "" }]
attributes: existingAttributes
? existingAttributes.map(attr => ({
key: attributeKeys.includes(attr.key) ? attr.key : "unknown-attributes",
value: attr.value,
customKey: attributeKeys.includes(attr.key) ? "" : attr.key
}))
: [{ key: "", value: "", customKey: "" }]
}
});

const { control } = form;

const { fields, append, remove } = useFieldArray({
control,
name: "attributes"
});

const { activeControlMachine } = useControlMachine();

const [showSuccess, setShowSuccess] = React.useState(false);

const updateProviderAttributesAndProceed: SubmitHandler<ProviderFormValues> = async data => {
const updatedProviderPricing = {
...providerPricing,
attributes: data.attributes.map(attr => ({
...attr,
customKey: attr.customKey || ""
}))
};
setProviderPricing(updatedProviderPricing);
onComplete();
if (!editMode) {
const updatedProviderPricing = {
...providerPricing,
attributes: data.attributes.map(attr => ({
key: attr.key === "unknown-attributes" ? attr.customKey || "" : attr.key || "",
value: attr.value
}))
};
setProviderPricing(updatedProviderPricing);
onComplete && onComplete();
} else {
const attributes = data.attributes.map(attr => ({
key: attr.key === "unknown-attributes" ? attr.customKey || "" : attr.key || "",
value: attr.value
}));
const request = {
control_machine: sanitizeMachineAccess(activeControlMachine),
attributes
};

const response = await restClient.post(`/update-provider-attributes`, request);
if (response) {
setShowSuccess(true);
setTimeout(() => setShowSuccess(false), 10000);
}
}
};

return (
<div className="flex w-full flex-col items-center pt-10">
<div className="w-full max-w-2xl space-y-6">
<div>
<h3 className="text-xl font-bold">Provider Attributes</h3>
<p className="text-muted-foreground text-sm">Please enter your provider attributes.</p>
<h3 className="text-xl font-bold">{existingAttributes ? "Edit Provider Attributes" : "Provider Attributes"}</h3>
<p className="text-muted-foreground text-sm">
{existingAttributes ? "Please update your provider attributes." : "Please enter your provider attributes."}
</p>
</div>
<div>
<Separator />
Expand Down Expand Up @@ -154,16 +189,20 @@ export const ProviderAttributes: React.FC<ProviderAttributesProps> = ({ onComple
<Separator />
</div>
<div className="flex w-full justify-between">
<div className="flex justify-start">
<ResetProviderForm />
</div>
<div className="flex justify-start">{!editMode && <ResetProviderForm />}</div>
<div className="flex justify-end">
<Button type="submit">Next</Button>
<Button type="submit">{editMode ? "Update Attributes" : "Next"}</Button>
</div>
</div>
</form>
</Form>
</div>
{showSuccess && (
<Alert>
<AlertTitle>Success</AlertTitle>
<AlertDescription>Provider attributes updated successfully</AlertDescription>
</Alert>
)}
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export const WalletImport: React.FC<WalletImportProps> = ({ onComplete }) => {
};
await setControlMachine(machineWithAddress);
resetProviderProcess();
router.push(`/action?id=${response.action_id}`);
router.push(`/actions/${response.action_id}`);
} else {
throw new Error("Invalid response from server");
}
Expand Down
12 changes: 6 additions & 6 deletions apps/provider-console/src/components/layout/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ export const Sidebar: React.FC<Props> = ({ isMobileOpen, handleDrawerToggle, isN
{
title: "Actions",
icon: props => <ClipboardCheck {...props} />,
url: "#",
activeRoutes: ["#"],
disabled: true
url: UrlService.actions(),
activeRoutes: [UrlService.actions()],
disabled: false
},
{
title: "Pricing",
Expand All @@ -71,9 +71,9 @@ export const Sidebar: React.FC<Props> = ({ isMobileOpen, handleDrawerToggle, isN
{
title: "Attributes",
icon: props => <ListSelect {...props} />,
url: "#",
activeRoutes: ["#"],
disabled: true
url: UrlService.attributes(),
activeRoutes: [UrlService.attributes()],
disabled: false
},
{
title: "Settings",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ export const ProviderActionDetails: React.FC<{ actionId: string | null }> = ({ a
<div className="rounded-md border">
{actionDetails?.tasks.map((task, index) => (
<div key={index}>
<div className="flex cursor-pointer items-center justify-between p-4" onClick={() => toggleAccordion(index)}>
<div
className="flex cursor-pointer items-center justify-between p-4 hover:bg-gray-50 dark:hover:bg-gray-600/50"
onClick={() => toggleAccordion(index)}
>
<div className="flex items-center">
{openAccordions[index] ? <ArrowDown className="mr-2 h-5 w-5" /> : <ArrowRight className="mr-2 h-5 w-5" />}
<span>{task.description}</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ export const ProviderActionList: React.FC<ProviderActionListProps> = ({ actions
};

const handleRowClick = (actionId: string) => {
router.push(`/action-details/?id=${actionId}`);
router.push(`/actions/${actionId}`);
};

return (
<div className="w-full">
<ul className="divide-y divide-gray-200">
{actions.length > 0 ? (
actions.map(action => (
<li key={action.id} className="cursor-pointer py-4 hover:bg-gray-50" onClick={() => handleRowClick(action.id)}>
<li key={action.id} className="cursor-pointer py-4 hover:bg-gray-50 dark:hover:bg-gray-600/50" onClick={() => handleRowClick(action.id)}>
<div className="grid grid-cols-12 items-center gap-4">
<div className="col-span-4">
<p className="text-base font-medium">{action.name}</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
"use client";

import React from "react";
import { useSearchParams } from "next/navigation";

import { Layout } from "@src/components/layout/Layout";
import { ProviderActionDetails } from "@src/components/shared/ProviderActionDetails";

export default function ActionDetailsPage() {
const searchParams = useSearchParams();
const actionId = searchParams.get("id");
type Props = {
id: string | null;
};

if (!actionId) {
const ActionDetailsPage: React.FC<Props> = ({ id }) => {
if (!id) {
return (
<Layout>
<div>Error: No action ID provided</div>
Expand All @@ -21,8 +21,18 @@ export default function ActionDetailsPage() {
return (
<Layout>
<div className="container mx-auto">
<ProviderActionDetails actionId={actionId} />
<ProviderActionDetails actionId={id} />
</div>
</Layout>
);
};

export default ActionDetailsPage;

export async function getServerSideProps({ params }) {
return {
props: {
id: params?.id
}
};
}
28 changes: 28 additions & 0 deletions apps/provider-console/src/pages/actions/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"use client";

import { Layout } from "@src/components/layout/Layout";
import { ProviderActionList } from "@src/components/shared/ProviderActionList";
import { Title } from "@src/components/shared/Title";
import { useProviderActions } from "@src/queries/useProviderQuery";

const ActionsList: React.FC = () => {
const { data: actions } = useProviderActions();
return (
<Layout>
<div className="flex items-center">
<div className="w-10 flex-1">
<Title>User Actions</Title>
</div>
</div>
<div className="mt-10">
<div className="text-sm font-semibold">
<div className="items-center space-x-2">
<ProviderActionList actions={actions} />
</div>
</div>
</div>
</Layout>
);
};

export default ActionsList;
33 changes: 33 additions & 0 deletions apps/provider-console/src/pages/attributes/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from "react";
import { useQuery } from "react-query";

import { ProviderAttributes } from "@src/components/become-provider/ProviderAttributes";
import { Layout } from "@src/components/layout/Layout";
import { useSelectedChain } from "@src/context/CustomChainProvider";
import consoleClient from "@src/utils/consoleClient";

const Attributes: React.FunctionComponent = () => {
const { address } = useSelectedChain();
const { data: providerDetails, isLoading: isLoadingProviderDetails }: { data: any; isLoading: boolean } = useQuery(
"providerDetails",
() => consoleClient.get(`/v1/providers/${address}`),
{
refetchOnWindowFocus: false,
retry: 3
}
);

return (
<Layout>
{isLoadingProviderDetails ? (
<div>Loading...</div>
) : (
<div>
<ProviderAttributes existingAttributes={providerDetails.attributes} editMode={true} />
</div>
)}
</Layout>
);
};

export default Attributes;
2 changes: 1 addition & 1 deletion apps/provider-console/src/store/providerProcessStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ interface ProviderPricing {
endpointBidPrice: number
}

interface ProviderAttribute { key: string, value: string, customKey: string }
export interface ProviderAttribute { key: string, value: string }

interface ProviderProcess {
machines: MachineInformation[],
Expand Down
15 changes: 15 additions & 0 deletions apps/provider-console/src/utils/sanityUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ControlMachineWithAddress } from "@src/types/controlMachine";

export function sanitizeMachineAccess(machine: ControlMachineWithAddress | null) {
if (!machine) {
return undefined;
}
return {
hostname: machine.access.hostname,
port: machine.access.port,
username: machine.access.username,
keyfile: machine.access.file || null,
password: machine.access.password || null,
passphrase: machine.access.passphrase || null
};
}
2 changes: 2 additions & 0 deletions apps/provider-console/src/utils/urlUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ export const domainName = "https://provider.akash.network";
export class UrlService {
static home = () => "/";
static deployments = () => "/deployments";
static attributes = () => "/attributes";
static getStarted = () => "/get-started";
static privacyPolicy = () => "/privacy-policy";
static termsOfService = () => "/terms-of-service";
static actions = () => "/actions";
}
Loading