mirror of
https://github.com/usememos/memos.git
synced 2025-06-05 22:09:59 +02:00
chore: update resource icons
This commit is contained in:
@ -21,11 +21,14 @@ const ResourceListView = (props: Props) => {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={resource.id}
|
key={resource.id}
|
||||||
className="max-w-full flex flex-row justify-start items-center flex-nowrap bg-gray-100 dark:bg-zinc-800 px-2 py-1 rounded text-gray-500"
|
className="max-w-full flex flex-row justify-start items-center flex-nowrap gap-x-1 bg-gray-100 dark:bg-zinc-800 px-2 py-1 rounded text-gray-500"
|
||||||
>
|
>
|
||||||
<ResourceIcon resource={resource} className="w-4 h-auto mr-1" />
|
<ResourceIcon resource={resource} className="!w-4 !h-auto !opacity-100" />
|
||||||
<span className="text-sm max-w-xs truncate">{resource.filename}</span>
|
<span className="text-sm max-w-[8rem] truncate">{resource.filename}</span>
|
||||||
<Icon.X className="w-4 h-auto ml-1 cursor-pointer hover:opacity-80" onClick={() => handleDeleteResource(resource.id)} />
|
<Icon.X
|
||||||
|
className="w-4 h-auto cursor-pointer opacity-60 hover:opacity-100"
|
||||||
|
onClick={() => handleDeleteResource(resource.id)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@ -1,34 +1,22 @@
|
|||||||
import { useState } from "react";
|
|
||||||
import { getDateTimeString } from "@/helpers/datetime";
|
import { getDateTimeString } from "@/helpers/datetime";
|
||||||
import Icon from "./Icon";
|
import ResourceIcon from "./ResourceIcon";
|
||||||
import ResourceCover from "./ResourceCover";
|
|
||||||
import ResourceItemDropdown from "./ResourceItemDropdown";
|
import ResourceItemDropdown from "./ResourceItemDropdown";
|
||||||
import "@/less/resource-card.less";
|
import "@/less/resource-card.less";
|
||||||
|
|
||||||
const ResourceCard = ({ resource, handleCheckClick, handleUncheckClick }: ResourceItemType) => {
|
interface Props {
|
||||||
const [isSelected, setIsSelected] = useState<boolean>(false);
|
resource: Resource;
|
||||||
|
}
|
||||||
const handleSelectBtnClick = () => {
|
|
||||||
if (isSelected) {
|
|
||||||
handleUncheckClick();
|
|
||||||
} else {
|
|
||||||
handleCheckClick();
|
|
||||||
}
|
|
||||||
setIsSelected(!isSelected);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
const ResourceCard = ({ resource }: Props) => {
|
||||||
return (
|
return (
|
||||||
<div className="resource-card">
|
<div className="resource-card">
|
||||||
<div className="w-full p-2 flex flex-row justify-between items-center absolute top-0 left-0">
|
<div className="w-full p-2 flex flex-row justify-end items-center absolute top-0 left-0">
|
||||||
<div onClick={() => handleSelectBtnClick()}>
|
|
||||||
{isSelected ? <Icon.CheckCircle2 className="resource-checkbox !flex" /> : <Icon.Circle className="resource-checkbox" />}
|
|
||||||
</div>
|
|
||||||
<div className="more-action-btn">
|
<div className="more-action-btn">
|
||||||
<ResourceItemDropdown resource={resource} />
|
<ResourceItemDropdown resource={resource} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-row justify-center items-center pb-2 pt-4 px-2">
|
<div className="w-full flex flex-row justify-center items-center pb-2 pt-4 px-2">
|
||||||
<ResourceCover resource={resource} />
|
<ResourceIcon resource={resource} strokeWidth={1} />
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-col justify-start items-center px-1 select-none">
|
<div className="w-full flex flex-col justify-start items-center px-1 select-none">
|
||||||
<div className="w-full text-base text-center text-ellipsis overflow-hidden line-clamp-3">{resource.filename}</div>
|
<div className="w-full text-base text-center text-ellipsis overflow-hidden line-clamp-3">{resource.filename}</div>
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import { getResourceType, getResourceUrl } from "@/utils/resource";
|
|
||||||
import Icon from "./Icon";
|
|
||||||
import showPreviewImageDialog from "./PreviewImageDialog";
|
|
||||||
import SquareDiv from "./kit/SquareDiv";
|
|
||||||
import "@/less/resource-cover.less";
|
|
||||||
|
|
||||||
interface ResourceCoverProps {
|
|
||||||
resource: Resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ResourceCover = ({ resource }: ResourceCoverProps) => {
|
|
||||||
const resourceType = getResourceType(resource);
|
|
||||||
const resourceUrl = getResourceUrl(resource);
|
|
||||||
switch (resourceType) {
|
|
||||||
case "image/*":
|
|
||||||
return (
|
|
||||||
<SquareDiv className="h-20 w-20 flex items-center justify-center overflow-clip">
|
|
||||||
<img
|
|
||||||
className="max-w-full max-h-full object-cover shadow"
|
|
||||||
src={resource.externalLink ? resourceUrl : resourceUrl + "?thumbnail=1"}
|
|
||||||
onClick={() => showPreviewImageDialog(resourceUrl)}
|
|
||||||
/>
|
|
||||||
</SquareDiv>
|
|
||||||
);
|
|
||||||
case "video/*":
|
|
||||||
return <Icon.FileVideo2 className="resource-cover" />;
|
|
||||||
case "audio/*":
|
|
||||||
return <Icon.FileAudio className="resource-cover" />;
|
|
||||||
case "text/*":
|
|
||||||
return <Icon.FileText className="resource-cover" />;
|
|
||||||
case "application/epub+zip":
|
|
||||||
return <Icon.Book className="resource-cover" />;
|
|
||||||
case "application/pdf":
|
|
||||||
return <Icon.Book className="resource-cover" />;
|
|
||||||
case "application/msword":
|
|
||||||
return <Icon.FileEdit className="resource-cover" />;
|
|
||||||
case "application/msexcel":
|
|
||||||
return <Icon.SheetIcon className="resource-cover" />;
|
|
||||||
case "application/zip":
|
|
||||||
return <Icon.FileArchiveIcon className="resource-cover" />;
|
|
||||||
case "application/x-java-archive":
|
|
||||||
return <Icon.BinaryIcon className="resource-cover" />;
|
|
||||||
default:
|
|
||||||
return <Icon.File className="resource-cover" />;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default React.memo(ResourceCover);
|
|
@ -1,34 +1,55 @@
|
|||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
|
import React from "react";
|
||||||
import { getResourceType, getResourceUrl } from "@/utils/resource";
|
import { getResourceType, getResourceUrl } from "@/utils/resource";
|
||||||
import Icon from "./Icon";
|
import Icon from "./Icon";
|
||||||
import showPreviewImageDialog from "./PreviewImageDialog";
|
import showPreviewImageDialog from "./PreviewImageDialog";
|
||||||
import SquareDiv from "./kit/SquareDiv";
|
import SquareDiv from "./kit/SquareDiv";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
className: string;
|
|
||||||
resource: Resource;
|
resource: Resource;
|
||||||
|
className?: string;
|
||||||
|
strokeWidth?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ResourceIcon = (props: Props) => {
|
const ResourceIcon = (props: Props) => {
|
||||||
const { className, resource } = props;
|
const { resource } = props;
|
||||||
|
const resourceType = getResourceType(resource);
|
||||||
|
const resourceUrl = getResourceUrl(resource);
|
||||||
|
const className = classNames("w-full h-auto", props.className);
|
||||||
|
const strokeWidth = props.strokeWidth;
|
||||||
|
|
||||||
if (getResourceType(resource).startsWith("image")) {
|
switch (resourceType) {
|
||||||
const url = getResourceUrl(resource);
|
case "image/*":
|
||||||
return (
|
return (
|
||||||
<SquareDiv key={resource.id} className={classNames("cursor-pointer rounded hover:shadow", className)}>
|
<SquareDiv className={classNames(className, "flex items-center justify-center overflow-clip")}>
|
||||||
<img
|
<img
|
||||||
className="min-h-full min-w-full w-auto h-auto rounded"
|
className="max-w-full max-h-full object-cover shadow"
|
||||||
src={resource.externalLink ? url : url + "?thumbnail=1"}
|
src={resource.externalLink ? resourceUrl : resourceUrl + "?thumbnail=1"}
|
||||||
onClick={() => showPreviewImageDialog([url], 0)}
|
onClick={() => showPreviewImageDialog(resourceUrl)}
|
||||||
decoding="async"
|
/>
|
||||||
loading="lazy"
|
</SquareDiv>
|
||||||
/>
|
);
|
||||||
</SquareDiv>
|
case "video/*":
|
||||||
);
|
return <Icon.FileVideo2 strokeWidth={strokeWidth} className={classNames(className, "opacity-50")} />;
|
||||||
|
case "audio/*":
|
||||||
|
return <Icon.FileAudio strokeWidth={strokeWidth} className={classNames(className, "opacity-50")} />;
|
||||||
|
case "text/*":
|
||||||
|
return <Icon.FileText strokeWidth={strokeWidth} className={classNames(className, "opacity-50")} />;
|
||||||
|
case "application/epub+zip":
|
||||||
|
return <Icon.Book strokeWidth={strokeWidth} className={classNames(className, "opacity-50")} />;
|
||||||
|
case "application/pdf":
|
||||||
|
return <Icon.Book strokeWidth={strokeWidth} className={classNames(className, "opacity-50")} />;
|
||||||
|
case "application/msword":
|
||||||
|
return <Icon.FileEdit strokeWidth={strokeWidth} className={classNames(className, "opacity-50")} />;
|
||||||
|
case "application/msexcel":
|
||||||
|
return <Icon.SheetIcon strokeWidth={strokeWidth} className={classNames(className, "opacity-50")} />;
|
||||||
|
case "application/zip":
|
||||||
|
return <Icon.FileArchiveIcon strokeWidth={strokeWidth} className={classNames(className, "opacity-50")} />;
|
||||||
|
case "application/x-java-archive":
|
||||||
|
return <Icon.BinaryIcon strokeWidth={strokeWidth} className={classNames(className, "opacity-50")} />;
|
||||||
|
default:
|
||||||
|
return <Icon.File strokeWidth={strokeWidth} className={classNames(className, "opacity-50")} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ResourceIcon = Icon.FileText;
|
|
||||||
return <ResourceIcon className={className} />;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ResourceIcon;
|
export default React.memo(ResourceIcon);
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
import { Checkbox } from "@mui/joy";
|
|
||||||
import { useState } from "react";
|
|
||||||
import ResourceItemDropdown from "./ResourceItemDropdown";
|
|
||||||
|
|
||||||
const ResourceItem = ({ resource, handleCheckClick, handleUncheckClick }: ResourceItemType) => {
|
|
||||||
const [isSelected, setIsSelected] = useState<boolean>(false);
|
|
||||||
|
|
||||||
const handleSelectBtnClick = () => {
|
|
||||||
if (isSelected) {
|
|
||||||
handleUncheckClick();
|
|
||||||
} else {
|
|
||||||
handleCheckClick();
|
|
||||||
}
|
|
||||||
setIsSelected(!isSelected);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div key={resource.id} className="px-2 py-2 w-full grid grid-cols-10">
|
|
||||||
<span className="col-span-1 w-full flex justify-center m-auto truncate ">
|
|
||||||
<Checkbox checked={isSelected} onChange={handleSelectBtnClick} />
|
|
||||||
</span>
|
|
||||||
<span className="col-span-2 w-full m-auto truncate text-base pr-2">{resource.id}</span>
|
|
||||||
<span className="col-span-6 w-full m-auto truncate text-base pr-2">{resource.filename}</span>
|
|
||||||
<div className="col-span-1 w-full flex flex-row justify-end items-center pr-2">
|
|
||||||
<ResourceItemDropdown resource={resource} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ResourceItem;
|
|
@ -1,23 +0,0 @@
|
|||||||
import React, { DependencyList, EffectCallback, useEffect, useRef } from "react";
|
|
||||||
|
|
||||||
const useIsoMorphicEffect = (effect: EffectCallback, deps?: DependencyList | undefined) => {
|
|
||||||
useEffect(effect, deps);
|
|
||||||
};
|
|
||||||
|
|
||||||
function useLatestValue<T>(value: T) {
|
|
||||||
const cache = useRef(value);
|
|
||||||
|
|
||||||
useIsoMorphicEffect(() => {
|
|
||||||
cache.current = value;
|
|
||||||
}, [value]);
|
|
||||||
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Add React.useEvent ?? once the useEvent hook is available
|
|
||||||
function useEvent<F extends (...args: any[]) => any, P extends any[] = Parameters<F>, R = ReturnType<F>>(cb: (...args: P) => R) {
|
|
||||||
const cache = useLatestValue(cb);
|
|
||||||
return React.useCallback((...args: P) => cache.current(...args), [cache]);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default useEvent;
|
|
@ -1,3 +0,0 @@
|
|||||||
.resource-cover {
|
|
||||||
@apply w-20 h-auto ml-auto mr-auto opacity-40;
|
|
||||||
}
|
|
@ -7,12 +7,10 @@ import Empty from "@/components/Empty";
|
|||||||
import Icon from "@/components/Icon";
|
import Icon from "@/components/Icon";
|
||||||
import MobileHeader from "@/components/MobileHeader";
|
import MobileHeader from "@/components/MobileHeader";
|
||||||
import ResourceCard from "@/components/ResourceCard";
|
import ResourceCard from "@/components/ResourceCard";
|
||||||
import ResourceItem from "@/components/ResourceItem";
|
|
||||||
import ResourceSearchBar from "@/components/ResourceSearchBar";
|
import ResourceSearchBar from "@/components/ResourceSearchBar";
|
||||||
import Dropdown from "@/components/kit/Dropdown";
|
import Dropdown from "@/components/kit/Dropdown";
|
||||||
import { DEFAULT_MEMO_LIMIT } from "@/helpers/consts";
|
import { DEFAULT_MEMO_LIMIT } from "@/helpers/consts";
|
||||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||||
import useEvent from "@/hooks/useEvent";
|
|
||||||
import useLoading from "@/hooks/useLoading";
|
import useLoading from "@/hooks/useLoading";
|
||||||
import { useResourceStore } from "@/store/module";
|
import { useResourceStore } from "@/store/module";
|
||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
@ -23,8 +21,6 @@ const ResourcesDashboard = () => {
|
|||||||
const user = useCurrentUser();
|
const user = useCurrentUser();
|
||||||
const resourceStore = useResourceStore();
|
const resourceStore = useResourceStore();
|
||||||
const resources = resourceStore.state.resources;
|
const resources = resourceStore.state.resources;
|
||||||
const [selectedList, setSelectedList] = useState<Array<ResourceId>>([]);
|
|
||||||
const [listStyle, setListStyle] = useState<"GRID" | "TABLE">("TABLE");
|
|
||||||
const [queryText, setQueryText] = useState<string>("");
|
const [queryText, setQueryText] = useState<string>("");
|
||||||
const [dragActive, setDragActive] = useState(false);
|
const [dragActive, setDragActive] = useState(false);
|
||||||
const [isComplete, setIsComplete] = useState<boolean>(false);
|
const [isComplete, setIsComplete] = useState<boolean>(false);
|
||||||
@ -50,19 +46,6 @@ const ResourcesDashboard = () => {
|
|||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleCheckBtnClick = useEvent((resourceId: ResourceId) => {
|
|
||||||
setSelectedList([...selectedList, resourceId]);
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleUncheckBtnClick = useEvent((resourceId: ResourceId) => {
|
|
||||||
setSelectedList(selectedList.filter((id) => id !== resourceId));
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleStyleChangeBtnClick = (listStyle: "GRID" | "TABLE") => {
|
|
||||||
setListStyle(listStyle);
|
|
||||||
setSelectedList([]);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDeleteUnusedResourcesBtnClick = async () => {
|
const handleDeleteUnusedResourcesBtnClick = async () => {
|
||||||
let warningText = t("resource.warning-text-unused");
|
let warningText = t("resource.warning-text-unused");
|
||||||
const allResources = await fetchAllResources();
|
const allResources = await fetchAllResources();
|
||||||
@ -91,27 +74,6 @@ const ResourcesDashboard = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteSelectedBtnClick = () => {
|
|
||||||
if (selectedList.length == 0) {
|
|
||||||
toast.error(t("resource.no-files-selected"));
|
|
||||||
} else {
|
|
||||||
const warningText = t("resource.warning-text");
|
|
||||||
showCommonDialog({
|
|
||||||
title: t("resource.delete-resource"),
|
|
||||||
content: warningText,
|
|
||||||
style: "warning",
|
|
||||||
dialogName: "delete-resource-dialog",
|
|
||||||
onConfirm: async () => {
|
|
||||||
for (const resourceId of selectedList) {
|
|
||||||
await resourceStore.deleteResourceById(resourceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
setSelectedList([]);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFetchMoreResourceBtnClick = async () => {
|
const handleFetchMoreResourceBtnClick = async () => {
|
||||||
try {
|
try {
|
||||||
const fetchedResource = await resourceStore.fetchResourceListWithLimit(DEFAULT_MEMO_LIMIT, resources.length);
|
const fetchedResource = await resourceStore.fetchResourceListWithLimit(DEFAULT_MEMO_LIMIT, resources.length);
|
||||||
@ -149,7 +111,6 @@ const ResourcesDashboard = () => {
|
|||||||
if (query === queryText) return;
|
if (query === queryText) return;
|
||||||
await fetchAllResources();
|
await fetchAllResources();
|
||||||
setQueryText(query);
|
setQueryText(query);
|
||||||
setSelectedList([]);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDrag = (e: React.DragEvent<HTMLDivElement>) => {
|
const handleDrag = (e: React.DragEvent<HTMLDivElement>) => {
|
||||||
@ -166,24 +127,8 @@ const ResourcesDashboard = () => {
|
|||||||
() =>
|
() =>
|
||||||
resources
|
resources
|
||||||
.filter((res: Resource) => (queryText === "" ? true : res.filename.toLowerCase().includes(queryText.toLowerCase())))
|
.filter((res: Resource) => (queryText === "" ? true : res.filename.toLowerCase().includes(queryText.toLowerCase())))
|
||||||
.map((resource) =>
|
.map((resource) => <ResourceCard key={resource.id} resource={resource}></ResourceCard>),
|
||||||
listStyle === "TABLE" ? (
|
[resources, queryText]
|
||||||
<ResourceItem
|
|
||||||
key={resource.id}
|
|
||||||
resource={resource}
|
|
||||||
handleCheckClick={() => handleCheckBtnClick(resource.id)}
|
|
||||||
handleUncheckClick={() => handleUncheckBtnClick(resource.id)}
|
|
||||||
></ResourceItem>
|
|
||||||
) : (
|
|
||||||
<ResourceCard
|
|
||||||
key={resource.id}
|
|
||||||
resource={resource}
|
|
||||||
handleCheckClick={() => handleCheckBtnClick(resource.id)}
|
|
||||||
handleUncheckClick={() => handleUncheckBtnClick(resource.id)}
|
|
||||||
></ResourceCard>
|
|
||||||
)
|
|
||||||
),
|
|
||||||
[resources, queryText, listStyle]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleDrop = async (e: React.DragEvent<HTMLDivElement>) => {
|
const handleDrop = async (e: React.DragEvent<HTMLDivElement>) => {
|
||||||
@ -230,11 +175,6 @@ const ResourcesDashboard = () => {
|
|||||||
<ResourceSearchBar setQuery={handleSearchResourceInputChange} />
|
<ResourceSearchBar setQuery={handleSearchResourceInputChange} />
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-row justify-end items-center space-x-2 mt-3 z-1">
|
<div className="w-full flex flex-row justify-end items-center space-x-2 mt-3 z-1">
|
||||||
{selectedList.length > 0 && (
|
|
||||||
<Button onClick={() => handleDeleteSelectedBtnClick()} color="danger">
|
|
||||||
<Icon.Trash2 className="w-4 h-auto" />
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
<Button
|
<Button
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
showCreateResourceDialog({
|
showCreateResourceDialog({
|
||||||
@ -267,24 +207,6 @@ const ResourcesDashboard = () => {
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<div className="flex rounded-lg cursor-pointer h-8 overflow-clip border dark:border-zinc-600">
|
|
||||||
<div
|
|
||||||
className={`flex justify-center items-center px-3 ${
|
|
||||||
listStyle === "GRID" ? "bg-white dark:bg-zinc-700" : "bg-gray-200 dark:bg-zinc-800 opacity-60"
|
|
||||||
}`}
|
|
||||||
onClick={() => handleStyleChangeBtnClick("GRID")}
|
|
||||||
>
|
|
||||||
<Icon.Grid className="w-4 h-auto opacity-80" />
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className={`flex justify-center items-center px-3 ${
|
|
||||||
listStyle === "TABLE" ? "bg-white dark:bg-zinc-700" : "bg-gray-200 dark:bg-zinc-800 opacity-60"
|
|
||||||
}`}
|
|
||||||
onClick={() => handleStyleChangeBtnClick("TABLE")}
|
|
||||||
>
|
|
||||||
<Icon.List className="w-4 h-auto opacity-80" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-col justify-start items-start mt-4 mb-6">
|
<div className="w-full flex flex-col justify-start items-start mt-4 mb-6">
|
||||||
{loadingState.isLoading ? (
|
{loadingState.isLoading ? (
|
||||||
@ -294,19 +216,11 @@ const ResourcesDashboard = () => {
|
|||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
listStyle === "TABLE" || resourceList.length === 0
|
resourceList.length === 0
|
||||||
? "flex flex-col justify-start items-start w-full"
|
? "flex flex-col justify-start items-start w-full"
|
||||||
: "w-full h-auto grid grid-cols-2 md:grid-cols-4 md:px-6 gap-6"
|
: "w-full h-auto grid grid-cols-2 md:grid-cols-4 md:px-6 gap-6"
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{listStyle === "TABLE" && (
|
|
||||||
<div className="px-2 py-2 w-full grid grid-cols-10 border-b dark:border-b-zinc-600">
|
|
||||||
<span></span>
|
|
||||||
<span className="col-span-2">ID</span>
|
|
||||||
<span className="col-span-6">{t("common.name")}</span>
|
|
||||||
<span></span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{resourceList.length === 0 ? (
|
{resourceList.length === 0 ? (
|
||||||
<div className="w-full mt-8 mb-8 flex flex-col justify-center items-center italic">
|
<div className="w-full mt-8 mb-8 flex flex-col justify-center items-center italic">
|
||||||
<Empty />
|
<Empty />
|
||||||
|
Reference in New Issue
Block a user