Skip to content

Commit 55360e9

Browse files
authored
feat(web): support sort files of storage & fix monitor data undefined (#1819)
* feat(web): add storage sort & fix monitor data undefind * fix icon
1 parent f72e024 commit 55360e9

File tree

5 files changed

+162
-13
lines changed

5 files changed

+162
-13
lines changed

web/src/components/CommonIcon/index.tsx

+18-1
Original file line numberDiff line numberDiff line change
@@ -771,4 +771,21 @@ export const DownIcon = (props: any) => {
771771

772772
</svg>
773773
);
774-
};
774+
};
775+
export const AscendingIcon = createIcon({
776+
displayName: "AscendingIcon",
777+
viewBox: "0 0 1024 1024",
778+
d: "M666.656 452.992l45.888-44.608-258.24-265.664v782.816h64V300.352z"
779+
});
780+
781+
export const DescendingIcon = createIcon({
782+
displayName: "DescendingIcon",
783+
viewBox: "0 0 1024 1024",
784+
d: "M372.16 615.264l-45.888 44.608 258.272 265.664V142.72h-64v625.152z"
785+
});
786+
787+
export const SortingIcon = createIcon({
788+
displayName: "SortingIcon",
789+
viewBox: "0 0 1024 1024",
790+
d: "M610.624 128l258.24 265.664-45.856 44.608-148.384-152.64v625.184h-64V128zM160 659.84l45.888-44.576 148.384 152.64V142.72h64v782.816L160 659.872z"
791+
});

web/src/hooks/useAwsS3.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ function useAwsS3() {
2727

2828
const files = res.Contents || [];
2929
const dirs = res.CommonPrefixes || [];
30-
// console.log(files, dirs)
30+
3131
return { data: [...files, ...dirs], marker: res.NextMarker };
3232
};
3333

web/src/pages/app/setting/SysSetting/AppMonitor/AreaCard/index.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ function mergeArrays(dataArrays: (DataPoint[] | null)[]): DataPoint[] {
6464
if (matchingPoint) {
6565
mergedPoint[`value${index}`] = matchingPoint[`value${index}`] ?? 0;
6666
} else {
67-
mergedPoint[`value${index}`] = 0;
67+
mergedPoint[`value${index}`] = undefined;
6868
}
6969
});
7070
return mergedPoint;
@@ -203,9 +203,9 @@ export default function AreaCard(props: {
203203
<Tooltip
204204
formatter={(value, index) => [
205205
podsArray[extractNumber(index as string) + 1] +
206-
": " +
207-
Number(value).toFixed(3) +
208-
unit,
206+
": " +
207+
Number(value).toFixed(3) +
208+
unit,
209209
]}
210210
labelFormatter={(value) => formatDate(new Date(value)).split(" ")[1]}
211211
labelStyle={{ color: "#24282C" }}

web/src/pages/app/setting/SysSetting/DatabaseMonitor/AreaCard/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ function mergeArrays(dataArrays: (DataPoint[] | null)[]): DataPoint[] {
7171
} else {
7272
Object.keys(arr[0]).forEach((key) => {
7373
if (key !== "xData") {
74-
mergedPoint[key] = 0;
74+
mergedPoint[key] = undefined;
7575
}
7676
});
7777
}

web/src/pages/app/storages/mods/FileList/index.tsx

+138-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState } from "react";
1+
import { useMemo, useState } from "react";
22
import { useHotkeys } from "react-hotkeys-hook";
33
import {
44
Button,
@@ -21,10 +21,13 @@ import { t } from "i18next";
2121
import { Key } from "ts-key-enum";
2222

2323
import {
24+
AscendingIcon,
25+
DescendingIcon,
2426
LinkIcon,
2527
OutlineViewOnIcon,
2628
RecycleDeleteIcon,
2729
RefreshIcon,
30+
SortingIcon,
2831
UploadIcon,
2932
} from "@/components/CommonIcon";
3033
import ConfirmButton from "@/components/ConfirmButton";
@@ -45,6 +48,33 @@ import UploadButton from "../UploadButton";
4548

4649
import useAwsS3 from "@/hooks/useAwsS3";
4750
import useGlobalStore from "@/pages/globalStore";
51+
52+
type TOrderType = null | "ascFilename" | "descFilename" | "ascFileType" | "descFileType" | "ascSize" | "descSize" | "ascDate" | "descDate"
53+
54+
const SortIcon = ({ currentOrderType, orderTypeAsc, orderTypeDesc, onSort }: {
55+
currentOrderType: TOrderType,
56+
orderTypeAsc: TOrderType,
57+
orderTypeDesc: TOrderType,
58+
onSort: () => void
59+
}) => {
60+
const isAsc = currentOrderType === orderTypeAsc;
61+
const isDesc = currentOrderType === orderTypeDesc;
62+
63+
let icon = <SortingIcon boxSize={3} className="absolute top-[1.5px]" />;
64+
65+
if (isAsc) {
66+
icon = <AscendingIcon boxSize={3} className="absolute top-[1.5px]" />;
67+
} else if (isDesc) {
68+
icon = <DescendingIcon boxSize={3} className="absolute top-[1.5px]" />;
69+
}
70+
71+
return (
72+
<span onClick={onSort} className="cursor-pointer relative">
73+
{icon}
74+
</span>
75+
);
76+
};
77+
4878
export default function FileList() {
4979
const { getList, getFileUrl, deleteFile } = useAwsS3();
5080
const { currentStorage, prefix, setPrefix, markerArray, setMarkerArray, getFilePath } =
@@ -60,6 +90,8 @@ export default function FileList() {
6090
const confirmDialog = useConfirmDialog();
6191
const { showError, showLoading, showSuccess } = useGlobalStore();
6292

93+
const [orderType, setOrderType] = useState<TOrderType>(null);
94+
6395
const {
6496
data: queryData,
6597
refetch,
@@ -77,6 +109,74 @@ export default function FileList() {
77109
},
78110
);
79111

112+
const compareFilename = (a: any, b: any) => {
113+
if (a.Key && b.Key) {
114+
return a.Key.localeCompare(b.Key);
115+
} else if (a.Key) {
116+
return 1;
117+
} else if (b.Key) {
118+
return -1;
119+
} else {
120+
return a.Prefix.localeCompare(b.Prefix);
121+
}
122+
}
123+
124+
const compareFileType = (a: any, b: any) => {
125+
const fileNameA = a.Key?.split('/');
126+
const fileNameB = b.Key?.split('/');
127+
128+
if (!fileNameA && fileNameB) return 1;
129+
if (fileNameA && !fileNameB) return -1;
130+
if (!fileNameA && !fileNameB) return 0;
131+
132+
return formateType(fileNameA[fileNameA.length - 1])
133+
.localeCompare(formateType(fileNameB[fileNameB.length - 1]));
134+
}
135+
136+
const compareDate = (a: any, b: any) => {
137+
const dateA = new Date(a.LastModified);
138+
const dateB = new Date(b.LastModified);
139+
140+
if (dateA > dateB) {
141+
return 1;
142+
} else if (dateA < dateB) {
143+
return -1;
144+
} else {
145+
return 0;
146+
}
147+
}
148+
149+
const sortData = (data: any, orderType: TOrderType) => {
150+
if (!data) return [];
151+
152+
const sorted = [...data].sort((a, b) => {
153+
switch (orderType) {
154+
case 'ascFilename':
155+
return compareFilename(a, b);
156+
case 'descFilename':
157+
return compareFilename(b, a);
158+
case 'ascFileType':
159+
return compareFileType(a, b);
160+
case 'descFileType':
161+
return compareFileType(b, a);
162+
case 'ascSize':
163+
return (a.Size || 0) - (b.Size || 0);
164+
case 'descSize':
165+
return (b.Size || 0) - (a.Size || 0);
166+
case 'ascDate':
167+
return compareDate(a, b);
168+
case 'descDate':
169+
return compareDate(b, a);
170+
default:
171+
return 0;
172+
}
173+
});
174+
175+
return sorted;
176+
}
177+
178+
const renderData = useMemo(() => sortData(queryData?.data, orderType), [queryData, orderType]);
179+
80180
useHotkeys(
81181
["ctrl+a", "meta+a"],
82182
(e) => {
@@ -260,17 +360,49 @@ export default function FileList() {
260360
})}
261361
>
262362
<Tr>
263-
<Th>{t("StoragePanel.FileName")}</Th>
264-
<Th>{t("StoragePanel.FileType")}</Th>
265-
<Th>{t("StoragePanel.Size")}</Th>
266-
<Th>{t("StoragePanel.Time")}</Th>
363+
<Th>
364+
<span>{t("StoragePanel.FileName")}</span>
365+
<SortIcon
366+
currentOrderType={orderType}
367+
orderTypeAsc="ascFilename"
368+
orderTypeDesc="descFilename"
369+
onSort={() => setOrderType(orderType === "ascFilename" ? "descFilename" : "ascFilename")}
370+
/>
371+
</Th>
372+
<Th>
373+
<span>{t("StoragePanel.FileType")}</span>
374+
<SortIcon
375+
currentOrderType={orderType}
376+
orderTypeAsc="ascFileType"
377+
orderTypeDesc="descFileType"
378+
onSort={() => setOrderType(orderType === "ascFileType" ? "descFileType" : "ascFileType")}
379+
/>
380+
</Th>
381+
<Th>
382+
<span>{t("StoragePanel.Size")}</span>
383+
<SortIcon
384+
currentOrderType={orderType}
385+
orderTypeAsc="ascSize"
386+
orderTypeDesc="descSize"
387+
onSort={() => setOrderType(orderType === "ascSize" ? "descSize" : "ascSize")}
388+
/>
389+
</Th>
390+
<Th>
391+
<span>{t("StoragePanel.Time")}</span>
392+
<SortIcon
393+
currentOrderType={orderType}
394+
orderTypeAsc="ascDate"
395+
orderTypeDesc="descDate"
396+
onSort={() => setOrderType(orderType === "ascDate" ? "descDate" : "ascDate")}
397+
/>
398+
</Th>
267399
<Th isNumeric>
268400
<span className="mr-2">{t("Operation")}</span>
269401
</Th>
270402
</Tr>
271403
</Thead>
272404
<Tbody className="text-grayModern-500">
273-
{queryData.data.map((file: TFile) => {
405+
{renderData?.map((file: TFile) => {
274406
const fileName = file.Key?.split("/");
275407
const dirName = file.Prefix?.split("/") || [];
276408
const fileType = file.Prefix

0 commit comments

Comments
 (0)