Added skeleton when loading all flows
This commit is contained in:
parent
34da831213
commit
ee27839009
6 changed files with 101 additions and 29 deletions
16
src/frontend/src/components/skeletonCardComponent/index.tsx
Normal file
16
src/frontend/src/components/skeletonCardComponent/index.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { Skeleton } from "../ui/skeleton";
|
||||
|
||||
export const SkeletonCardComponent = (): JSX.Element => {
|
||||
return (
|
||||
<div className="skeleton-card">
|
||||
<div className="skeleton-card-wrapper">
|
||||
<Skeleton className="h-8 w-8 rounded-full" />
|
||||
<Skeleton className="h-4 w-[120px]" />
|
||||
</div>
|
||||
<div className="skeleton-card-text">
|
||||
<Skeleton className="h-3 w-[250px]" />
|
||||
<Skeleton className="h-3 w-[200px]" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
15
src/frontend/src/components/ui/skeleton.tsx
Normal file
15
src/frontend/src/components/ui/skeleton.tsx
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { cn } from "../../utils/utils"
|
||||
|
||||
function Skeleton({
|
||||
className,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLDivElement>) {
|
||||
return (
|
||||
<div
|
||||
className={cn("animate-pulse rounded-md bg-border", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export { Skeleton }
|
||||
|
|
@ -39,6 +39,7 @@ const TabsContextInitialValue: TabsContextType = {
|
|||
save: () => {},
|
||||
tabId: "",
|
||||
setTabId: (index: string) => {},
|
||||
isLoading: true,
|
||||
flows: [],
|
||||
removeFlow: (id: string) => {},
|
||||
addFlow: async (flowData?: any) => "",
|
||||
|
|
@ -76,6 +77,8 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
|||
|
||||
const [tabId, setTabId] = useState("");
|
||||
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const [flows, setFlows] = useState<Array<FlowType>>([]);
|
||||
const [id, setId] = useState(uid());
|
||||
const { templates, reactFlowInstance } = useContext(typesContext);
|
||||
|
|
@ -87,10 +90,10 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
|||
const [getTweak, setTweak] = useState<tweakType>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if(!isAuthenticated){
|
||||
if (!isAuthenticated) {
|
||||
hardReset();
|
||||
}
|
||||
}, [isAuthenticated])
|
||||
}, [isAuthenticated]);
|
||||
|
||||
const newNodeId = useRef(uid());
|
||||
function incrementNodeId() {
|
||||
|
|
@ -122,11 +125,13 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
|||
}
|
||||
|
||||
function refreshFlows() {
|
||||
setIsLoading(true);
|
||||
getTabsDataFromDB().then((DbData) => {
|
||||
if (DbData && Object.keys(templates).length > 0) {
|
||||
try {
|
||||
processDBData(DbData);
|
||||
updateStateWithDbData(DbData);
|
||||
setIsLoading(false);
|
||||
} catch (e) {}
|
||||
}
|
||||
});
|
||||
|
|
@ -235,6 +240,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
|||
setTabId("");
|
||||
|
||||
setFlows([]);
|
||||
setIsLoading(true);
|
||||
setId(uid());
|
||||
}
|
||||
|
||||
|
|
@ -647,6 +653,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
|||
paste,
|
||||
getTweak,
|
||||
setTweak,
|
||||
isLoading,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
|
|
|||
|
|
@ -3,12 +3,20 @@ import { Link, useNavigate } from "react-router-dom";
|
|||
import { CardComponent } from "../../components/cardComponent";
|
||||
import IconComponent from "../../components/genericIconComponent";
|
||||
import Header from "../../components/headerComponent";
|
||||
import { SkeletonCardComponent } from "../../components/skeletonCardComponent";
|
||||
import { Button } from "../../components/ui/button";
|
||||
import { USER_PROJECTS_HEADER } from "../../constants/constants";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
export default function HomePage(): JSX.Element {
|
||||
const { flows, setTabId, downloadFlows, uploadFlows, addFlow, removeFlow } =
|
||||
useContext(TabsContext);
|
||||
const {
|
||||
flows,
|
||||
setTabId,
|
||||
downloadFlows,
|
||||
uploadFlows,
|
||||
addFlow,
|
||||
removeFlow,
|
||||
isLoading,
|
||||
} = useContext(TabsContext);
|
||||
|
||||
// Set a null id
|
||||
useEffect(() => {
|
||||
|
|
@ -16,6 +24,10 @@ export default function HomePage(): JSX.Element {
|
|||
}, []);
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
console.log(isLoading);
|
||||
}, [isLoading]);
|
||||
|
||||
// Personal flows display
|
||||
return (
|
||||
<>
|
||||
|
|
@ -62,31 +74,40 @@ export default function HomePage(): JSX.Element {
|
|||
Manage your personal projects. Download or upload your collection.
|
||||
</span>
|
||||
<div className="main-page-flows-display">
|
||||
{flows.map((flow, idx) => (
|
||||
<CardComponent
|
||||
key={idx}
|
||||
flow={flow}
|
||||
id={flow.id}
|
||||
button={
|
||||
<Link to={"/flow/" + flow.id}>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="whitespace-nowrap "
|
||||
>
|
||||
<IconComponent
|
||||
name="ExternalLink"
|
||||
className="main-page-nav-button"
|
||||
/>
|
||||
Edit Flow
|
||||
</Button>
|
||||
</Link>
|
||||
}
|
||||
onDelete={() => {
|
||||
removeFlow(flow.id);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
{isLoading && flows.length == 0 ? (
|
||||
<>
|
||||
<SkeletonCardComponent />
|
||||
<SkeletonCardComponent />
|
||||
<SkeletonCardComponent />
|
||||
<SkeletonCardComponent />
|
||||
</>
|
||||
) : (
|
||||
flows.map((flow, idx) => (
|
||||
<CardComponent
|
||||
key={idx}
|
||||
flow={flow}
|
||||
id={flow.id}
|
||||
button={
|
||||
<Link to={"/flow/" + flow.id}>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="whitespace-nowrap "
|
||||
>
|
||||
<IconComponent
|
||||
name="ExternalLink"
|
||||
className="main-page-nav-button"
|
||||
/>
|
||||
Edit Flow
|
||||
</Button>
|
||||
</Link>
|
||||
}
|
||||
onDelete={() => {
|
||||
removeFlow(flow.id);
|
||||
}}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -126,6 +126,18 @@
|
|||
@apply form-input block w-full truncate rounded-md border-border bg-background px-3 text-left shadow-sm placeholder:text-muted-foreground focus:border-ring focus:placeholder-transparent focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 sm:text-sm;
|
||||
}
|
||||
|
||||
.skeleton-card {
|
||||
@apply bg-background h-48 p-4 border rounded-lg flex flex-col gap-6;
|
||||
}
|
||||
|
||||
.skeleton-card-wrapper {
|
||||
@apply flex items-center space-x-4;
|
||||
}
|
||||
|
||||
.skeleton-card-text {
|
||||
@apply flex flex-col gap-3;
|
||||
}
|
||||
|
||||
/* The same as primary-input but no-truncate */
|
||||
.textarea-primary {
|
||||
@apply form-input block w-full rounded-md border-border bg-background px-3 text-left shadow-sm placeholder:text-muted-foreground focus:border-ring focus:placeholder-transparent focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 sm:text-sm;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ export type TabsContextType = {
|
|||
saveFlow: (flow: FlowType) => Promise<void>;
|
||||
save: () => void;
|
||||
tabId: string;
|
||||
isLoading: boolean;
|
||||
setTabId: (index: string) => void;
|
||||
flows: Array<FlowType>;
|
||||
removeFlow: (id: string) => void;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue