Merge pull request #504 from storytold/feature/page/workflow_upload

new workflow upload page
This commit is contained in:
wil authored and GitHub committed 2024-02-22 15:39:28 -05:00
commit fab438eace
6 files changed
+290 -4

No files matched your search

@@ -0,0 +1,28 @@
import MakeRequest from "../MakeRequest";
export interface UploadWorkflowRequest {
uuid_idempotency_token: String,
google_drive_link: String,
title: String,
description: String,
commit_hash?: String
creator_set_visibility: String
// maybe_lora_upload_path?: String,
// maybe_name: String,
// maybe_description: String,
// visibility: String,
// maybe_cover_image_media_file_token?: String,
}
export interface UploadWorkflowResponse {
success: boolean,
// maybe_sd_model_token?: String,
// maybe_lora_model_token?: String,
}
export const UploadWorkflow = MakeRequest<string, UploadWorkflowRequest, UploadWorkflowResponse,{}>({
method: "POST",
routingFunction: () => "/v1/workflow/upload/prompt",
});
@@ -0,0 +1 @@
export { default } from "./useWorkflowUpload";
@@ -0,0 +1,72 @@
import { useState } from "react";
import { UploadWorkflow } from "@storyteller/components/src/api/video_workflow/UploadWorkflow";
import { FetchStatus } from "@storyteller/components/src/api/_common/SharedFetchTypes";
import { useInferenceJobs } from "hooks";
import { FrontendInferenceJobType } from "@storyteller/components/src/jobs/InferenceJob";
import { v4 as uuidv4 } from "uuid";
// this hook is mostly for organizational purposes while I work -V
export default function useWorkflow() {
const [uploadPath, uploadPathSet] = useState("");
const [title, titleSet] = useState("");
const [description, descriptionSet] = useState("");
const [commitHash, commitHashSet] = useState("");
const [visibility, visibilitySet] = useState("private");
const [writeStatus, writeStatusSet] = useState(FetchStatus.paused);
const { enqueue } = useInferenceJobs(FrontendInferenceJobType.VideoWorkflow, true);
const onChange = ({ target }: { target: { name: string; value: any } }) => {
const todo: { [key: string]: (x: any) => void } = {
uploadPathSet,
descriptionSet,
titleSet,
visibilitySet,
commitHashSet
};
todo[target.name + "Set"](target.value);
};
const upload = () => {
writeStatusSet(FetchStatus.in_progress);
console.log(`
google_drive_link: ${uploadPath},
title: ${title},
description: ${description},
commit_hash: ${commitHash},
creator_set_visibility: ${visibility}
`);
UploadWorkflow("", {
uuid_idempotency_token: uuidv4(),
google_drive_link: uploadPath,
title,
description,
commit_hash:commitHash,
creator_set_visibility: visibility
})
.then((res: any) => {
if (res.success && res.inference_job_token) {
writeStatusSet(FetchStatus.success);
enqueue(res.inference_job_token);
}
})
.catch(err => {
writeStatusSet(FetchStatus.error);
});
};
return {
uploadPath,
title,
description,
commitHash,
visibility,
writeStatus,
onChange,
upload,
};
}
@@ -30,9 +30,16 @@ import { TtsModelViewPage } from "./pages/tts/tts_model_view/TtsModelViewPage";
import { TtsResultDeletePage } from "./pages/tts/tts_result_delete/TtsResultDeletePage";
import { TtsResultViewPage } from "./pages/tts/tts_result_view/TtsResultViewPage";
import { ContributeIndexPage } from "./pages/contribute/ContributeIndexPage";
import { UploadTtsModelPage } from "./pages/upload/UploadTtsModelPage";
import { UploadW2lPhotoPage } from "./pages/upload/UploadW2lPhotoPage";
import { UploadW2lVideoPage } from "./pages/upload/UploadW2lVideoPage";
import { UploadVocoderPage } from "./pages/upload/UploadVocoderPage";
import { UploadVoiceConversionModel } from "./pages/upload/UploadVoiceConversionModel";
import UploadSdWeightPage from "./pages/upload/UploadSdWeightPage";
import UploadLoraWeightPage from "./pages/upload/UploadLoraWeightPage";
import UploadWorkflowPage from "./pages/upload/UploadWorkflowPage";
import { W2lResultViewPage } from "./pages/w2l/w2l_result_view/W2lResultViewPage";
import { W2lTemplateListPage } from "./pages/w2l/w2l_template_list/W2lTemplateListPage";
import { W2lTemplateUploadJob } from "@storyteller/components/src/jobs/W2lTemplateUploadJobs";
@@ -61,7 +68,7 @@ import { PatronPage } from "./pages/patrons/PatronPage";
import { Language } from "@storyteller/components/src/i18n/Language";
import { VoiceCloneRequestPage } from "./pages/clone_voice_requests/VoiceCloneRequestPage";
import { VocodesPage } from "./pages/vocodes/VocodesPage";
import { UploadVocoderPage } from "./pages/upload/UploadVocoderPage";
import { PricingPage } from "./pages/premium/PricingPage";
import { CheckoutSuccessPage } from "./pages/premium/CheckoutSuccessPage";
import { CheckoutCancelPage } from "./pages/premium/CheckoutCancelPage";
@@ -78,7 +85,7 @@ import {
} from "@storyteller/components/src/jobs/InferenceJob";
//import { LandingPage } from "./pages/landing/LandingPage";
import { VcModelListPage } from "./pages/vc/vc_model_list/VcModelListPage";
import { UploadVoiceConversionModel } from "./pages/upload/UploadVoiceConversionModel";
import { VoiceConversionModelListItem } from "@storyteller/components/src/api/voice_conversion/ListVoiceConversionModels";
import { CommunityCommissionsPage } from "./pages/contest/CommunityCommissionsPage";
import { ProductUsageInfoPage } from "./pages/product_usage_info/ProductUsageInfoPage";
@@ -106,10 +113,10 @@ import ExplorePage from "./pages/explore/ExplorePage";
import SearchPage from "./pages/search/SearchPage";
import { SearchProvider } from "context/SearchContext";
import WeightEditPage from "./pages/weight/WeightEditPage";
import UploadSdWeightPage from "./pages/upload/UploadSdWeightPage";
import { FooterNav } from "./nav/FooterNav";
import FbxToGltfPage from "./pages/fbx_to_gltf/FbxToGltfPage";
import UploadLoraWeightPage from "./pages/upload/UploadLoraWeightPage";
import VideoWorkflowPage from "./pages/video_workflow/VideoWorkflow";
import ScrollToTop from "./_common/ScrollToTop";
import TextToImagePage from "./pages/text_to_image/TextToImagePage";
@@ -117,6 +124,7 @@ import DomainConfigProvider from "context/DomainConfigContext";
import DevUpload from "./pages/dev_upload/DevUpload";
import DevMediaInput from "./pages/dev_upload/DevMediaInput";
interface Props {
sessionWrapper: SessionWrapper;
querySessionAction: () => void;
@@ -565,6 +573,12 @@ class PageContainer extends React.Component<
/>
</Route>
<Route path="/upload/workflow">
<UploadWorkflowPage
sessionWrapper={this.props.sessionWrapper}
/>
</Route>
<Route path="/contribute">
<ContributeIndexPage
sessionWrapper={this.props.sessionWrapper}
@@ -10,6 +10,7 @@ import {
faVolumeHigh,
faTags,
faHandsHelping,
faArrowsTurnToDots,
} from "@fortawesome/free-solid-svg-icons";
import { usePrefixedDocumentTitle } from "../../../../common/UsePrefixedDocumentTitle";
@@ -132,6 +133,13 @@ function ContributeIndexPage(props: Props) {
to="/upload/lora"
/>
</div>
<div className="col-12 col-md-6">
<Button
icon={faArrowsTurnToDots}
label="Upload Workflow"
to="/upload/workflow"
/>
</div>
</div>
</div>
</div>
@@ -0,0 +1,163 @@
import React from "react";
import {
faCircleExclamation,
faEye,
faArrowsTurnToDots
} from "@fortawesome/free-solid-svg-icons";
import { usePrefixedDocumentTitle } from "common/UsePrefixedDocumentTitle";
import PageHeader from "components/layout/PageHeader";
import {
Button,
Container,
SplitPanel,
TempInput,
TempSelect,
TempTextArea,
} from "components/common";
import { FrontendInferenceJobType } from "@storyteller/components/src/jobs/InferenceJob";
import InferenceJobsList from "components/layout/InferenceJobsList";
import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper";
import useWorkflowUpload from "hooks/useWorkflowUpload";
interface UploadWorkflowPageProps {
sessionWrapper: SessionWrapper;
}
export default function UploadWorkflowPage({
sessionWrapper,
}: UploadWorkflowPageProps) {
usePrefixedDocumentTitle("Edit Voice");
const visibilityOptions = [
{ label: "Public", value: "public" },
{ label: "Private", value: "private" },
];
const failures = (fail = "") => {
switch (fail) {
default:
return "Uknown failure";
}
};
const {
//state values
uploadPath,
title,
description,
commitHash,
visibility,
// callback functions
onChange,
upload,
} = useWorkflowUpload();
if (!sessionWrapper.isLoggedIn()) {
return (
<Container type="panel">
<PageHeader
titleIcon={faCircleExclamation}
title="Access Denied"
subText="This weight does not exist or is not owned by you."
panel={true}
extension={
<div className="d-flex">
<Button
label="Back to homepage"
to={`/weight/{}`}
className="d-flex"
/>
</div>
}
/>
</Container>
);
}
return (
<Container type="panel">
<InferenceJobsList
{...{
failures,
jobType: FrontendInferenceJobType.VideoWorkflow,
}}
/>
<PageHeader
title="Upload Workflow"
titleIcon={faArrowsTurnToDots}
subText="Upload a Workflow. Once your weight is successfully uploaded, you'll be able to start using it and sharing it with others."
panel={false}
/>
<SplitPanel dividerFooter={true}>
<SplitPanel.Body padding={true}>
<div className="row gx-4 gy-3">
<div className="col-12 col-lg-7 order-first order-lg-last">
<TempInput
{...{
label: "Download URL, eg. Google Drive link",
name: "uploadPath",
onChange,
placeholder: "Download URL",
value: uploadPath,
required: true,
}}
/>
<TempInput
{...{
label: "Title",
name: "title",
onChange,
placeholder: "Title",
value: title,
required: true,
}}
/>
<TempTextArea
{...{
label: "Description",
name: "description",
onChange,
placeholder: "Description",
value: description,
}}
/>
<TempInput
{...{
label: "Commit Hash",
name: "commitHash",
onChange,
placeholder: "Commit Hash",
value: commitHash,
}}
/>
<TempSelect
{...{
icon: faEye,
label: "Visibility",
name: "visibility",
onChange,
options: visibilityOptions,
value: visibility,
}}
/>
</div>
</div>
</SplitPanel.Body>
<SplitPanel.Footer padding={true}>
<div className="d-flex gap-2 justify-content-end">
<Button
{...{
label: "Upload Workflow",
onClick: upload,
}}
/>
</div>
</SplitPanel.Footer>
</SplitPanel>
</Container>
);
}