Added skeleton when loading all flows

This commit is contained in:
Lucas Oliveira 2023-08-30 22:56:43 -03:00
commit ee27839009
6 changed files with 101 additions and 29 deletions

View 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>
);
};

View 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 }

View file

@ -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}

View file

@ -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>
</>

View file

@ -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;

View file

@ -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;