diff --git a/web/src/helpers/api.ts b/web/src/helpers/api.ts
index d3bc20ec..5a005759 100644
--- a/web/src/helpers/api.ts
+++ b/web/src/helpers/api.ts
@@ -1,4 +1,5 @@
import axios from "axios";
+import { Resource } from "@/types/proto/api/v2/resource_service_pb";
import { GetUserResponse } from "@/types/proto/api/v2/user_service_pb";
export function getSystemStatus() {
@@ -143,17 +144,6 @@ export function getResourceList() {
return axios.get("/api/v1/resource");
}
-export function getResourceListWithLimit(resourceFind?: ResourceFind) {
- const queryList = [];
- if (resourceFind?.offset) {
- queryList.push(`offset=${resourceFind.offset}`);
- }
- if (resourceFind?.limit) {
- queryList.push(`limit=${resourceFind.limit}`);
- }
- return axios.get(`/api/v1/resource?${queryList.join("&")}`);
-}
-
export function createResource(resourceCreate: ResourceCreate) {
return axios.post("/api/v1/resource", resourceCreate);
}
diff --git a/web/src/helpers/datetime.ts b/web/src/helpers/datetime.ts
index 72683b08..c801d58e 100644
--- a/web/src/helpers/datetime.ts
+++ b/web/src/helpers/datetime.ts
@@ -57,7 +57,7 @@ export function getTimeString(t?: Date | number | string): string {
* - "pt-BR" locale: "30/01/2023 22:05:00"
* - "pl" locale: "30.01.2023, 22:05:00"
*/
-export function getDateTimeString(t?: Date | number | string, locale = i18n.language): string {
+export function getDateTimeString(t?: Date | number | string | any, locale = i18n.language): string {
const tsFromDate = getTimeStampByDate(t ? t : Date.now());
return new Date(tsFromDate).toLocaleDateString(locale, {
diff --git a/web/src/pages/Resources.tsx b/web/src/pages/Resources.tsx
index 75de982f..1ce1e33f 100644
--- a/web/src/pages/Resources.tsx
+++ b/web/src/pages/Resources.tsx
@@ -1,29 +1,45 @@
-import { useEffect } from "react";
-import { toast } from "react-hot-toast";
+import axios from "axios";
+import { useEffect, useState } from "react";
+import { Link } from "react-router-dom";
import Empty from "@/components/Empty";
import Icon from "@/components/Icon";
import MobileHeader from "@/components/MobileHeader";
-import ResourceCard from "@/components/ResourceCard";
+import ResourceIcon from "@/components/ResourceIcon";
import useLoading from "@/hooks/useLoading";
-import { useResourceStore } from "@/store/module";
+import { ListResourcesResponse, Resource } from "@/types/proto/api/v2/resource_service_pb";
import { useTranslate } from "@/utils/i18n";
+const fetchAllResources = async () => {
+ const { data } = await axios.get("/api/v2/resources");
+ return data.resources;
+};
+
+function groupResourcesByDate(resources: Resource[]) {
+ const grouped = new Map();
+ resources.forEach((item) => {
+ const date = new Date(item.createdTs as any);
+ const year = date.getFullYear();
+ const month = date.getMonth() + 1;
+ const timestamp = Date.UTC(year, month - 1, 1);
+ if (!grouped.has(timestamp)) {
+ grouped.set(timestamp, []);
+ }
+ grouped.get(timestamp)?.push(item);
+ });
+ return grouped;
+}
+
const Resources = () => {
const t = useTranslate();
const loadingState = useLoading();
- const resourceStore = useResourceStore();
- const resources = resourceStore.state.resources;
+ const [resources, setResources] = useState([]);
+ const groupedResources = groupResourcesByDate(resources);
useEffect(() => {
- resourceStore
- .fetchResourceList()
- .then(() => {
- loadingState.setFinish();
- })
- .catch((error) => {
- console.error(error);
- toast.error(error.response.data.message);
- });
+ fetchAllResources().then((resources) => {
+ setResources(resources);
+ loadingState.setFinish();
+ });
}, []);
return (
@@ -41,22 +57,51 @@ const Resources = () => {
{t("resource.fetching-data")}
) : (
-
+ <>
{resources.length === 0 ? (
) : (
- resources.map((resource) => )
+
+ {Array.from(groupedResources.entries()).map(([timestamp, resources]) => {
+ const date = new Date(timestamp);
+ return (
+
+
+ {date.getFullYear()}
+ {date.toLocaleString("default", { month: "short" })}
+
+
+ {resources.map((resource) => {
+ return (
+
+
+
+
+
+
+ {new Date(resource.createdTs as any).toLocaleDateString()}
+
+
+ #{resource.relatedMemoId}
+
+
+
+ );
+ })}
+
+
+ );
+ })}
+
)}
-
+ >
)}
diff --git a/web/src/store/module/resource.ts b/web/src/store/module/resource.ts
index c5af9bdb..755bb638 100644
--- a/web/src/store/module/resource.ts
+++ b/web/src/store/module/resource.ts
@@ -1,17 +1,10 @@
import * as api from "@/helpers/api";
+import { Resource } from "@/types/proto/api/v2/resource_service_pb";
import { useTranslate } from "@/utils/i18n";
import store, { useAppSelector } from "../";
import { deleteResource, patchResource, setResources } from "../reducer/resource";
import { useGlobalStore } from "./global";
-const convertResponseModelResource = (resource: Resource): Resource => {
- return {
- ...resource,
- createdTs: resource.createdTs * 1000,
- updatedTs: resource.updatedTs * 1000,
- };
-};
-
export const useResourceStore = () => {
const state = useAppSelector((state) => state.resource);
const t = useTranslate();
@@ -24,14 +17,12 @@ export const useResourceStore = () => {
return store.getState().resource;
},
async fetchResourceList(): Promise {
- const { data } = await api.getResourceList();
- const resourceList = data.map((m) => convertResponseModelResource(m));
+ const { data: resourceList } = await api.getResourceList();
store.dispatch(setResources(resourceList));
return resourceList;
},
async createResource(resourceCreate: ResourceCreate): Promise {
- const { data } = await api.createResource(resourceCreate);
- const resource = convertResponseModelResource(data);
+ const { data: resource } = await api.createResource(resourceCreate);
const resourceList = state.resources;
store.dispatch(setResources([resource, ...resourceList]));
return resource;
@@ -44,8 +35,7 @@ export const useResourceStore = () => {
const formData = new FormData();
formData.append("file", file, filename);
- const { data } = await api.createResourceWithBlob(formData);
- const resource = convertResponseModelResource(data);
+ const { data: resource } = await api.createResourceWithBlob(formData);
const resourceList = state.resources;
store.dispatch(setResources([resource, ...resourceList]));
return resource;
@@ -60,8 +50,7 @@ export const useResourceStore = () => {
const formData = new FormData();
formData.append("file", file, filename);
- const { data } = await api.createResourceWithBlob(formData);
- const resource = convertResponseModelResource(data);
+ const { data: resource } = await api.createResourceWithBlob(formData);
newResourceList = [resource, ...newResourceList];
}
const resourceList = state.resources;
@@ -73,8 +62,7 @@ export const useResourceStore = () => {
store.dispatch(deleteResource(id));
},
async patchResource(resourcePatch: ResourcePatch): Promise {
- const { data } = await api.patchResource(resourcePatch);
- const resource = convertResponseModelResource(data);
+ const { data: resource } = await api.patchResource(resourcePatch);
store.dispatch(patchResource(resource));
return resource;
},
diff --git a/web/src/store/reducer/resource.ts b/web/src/store/reducer/resource.ts
index 5b09b92f..de11ed05 100644
--- a/web/src/store/reducer/resource.ts
+++ b/web/src/store/reducer/resource.ts
@@ -1,5 +1,6 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { uniqBy } from "lodash-es";
+import { Resource } from "@/types/proto/api/v2/resource_service_pb";
interface State {
resources: Resource[];
diff --git a/web/src/types/modules/memo.d.ts b/web/src/types/modules/memo.d.ts
index 47e68475..ddd5d6c7 100644
--- a/web/src/types/modules/memo.d.ts
+++ b/web/src/types/modules/memo.d.ts
@@ -16,7 +16,7 @@ interface Memo {
pinned: boolean;
creatorName: string;
- resourceList: Resource[];
+ resourceList: any[];
relationList: MemoRelation[];
}
diff --git a/web/src/types/modules/resource.d.ts b/web/src/types/modules/resource.d.ts
index da7b2380..722b5ee4 100644
--- a/web/src/types/modules/resource.d.ts
+++ b/web/src/types/modules/resource.d.ts
@@ -1,17 +1,5 @@
type ResourceId = number;
-interface Resource {
- id: ResourceId;
-
- createdTs: number;
- updatedTs: number;
-
- filename: string;
- externalLink: string;
- type: string;
- size: string;
-}
-
interface ResourceCreate {
filename: string;
externalLink: string;
diff --git a/web/src/types/proto/api/v2/resource_service_pb.d.ts b/web/src/types/proto/api/v2/resource_service_pb.d.ts
index c7f16054..ed39c197 100644
--- a/web/src/types/proto/api/v2/resource_service_pb.d.ts
+++ b/web/src/types/proto/api/v2/resource_service_pb.d.ts
@@ -3,7 +3,7 @@
/* eslint-disable */
// @ts-nocheck
-import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
+import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage, Timestamp } from "@bufbuild/protobuf";
import { Message, proto3 } from "@bufbuild/protobuf";
/**
@@ -16,9 +16,9 @@ export declare class Resource extends Message {
id: number;
/**
- * @generated from field: int64 created_ts = 2;
+ * @generated from field: google.protobuf.Timestamp created_ts = 2;
*/
- createdTs: bigint;
+ createdTs?: Timestamp;
/**
* @generated from field: string filename = 3;
diff --git a/web/src/types/proto/api/v2/resource_service_pb.js b/web/src/types/proto/api/v2/resource_service_pb.js
index e252dd7c..8143e36a 100644
--- a/web/src/types/proto/api/v2/resource_service_pb.js
+++ b/web/src/types/proto/api/v2/resource_service_pb.js
@@ -3,7 +3,7 @@
/* eslint-disable */
// @ts-nocheck
-import { proto3 } from "@bufbuild/protobuf";
+import { proto3, Timestamp } from "@bufbuild/protobuf";
/**
* @generated from message memos.api.v2.Resource
@@ -12,7 +12,7 @@ export const Resource = proto3.makeMessageType(
"memos.api.v2.Resource",
() => [
{ no: 1, name: "id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
- { no: 2, name: "created_ts", kind: "scalar", T: 3 /* ScalarType.INT64 */ },
+ { no: 2, name: "created_ts", kind: "message", T: Timestamp },
{ no: 3, name: "filename", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 4, name: "external_link", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 5, name: "type", kind: "scalar", T: 9 /* ScalarType.STRING */ },
diff --git a/web/src/types/resourceItem.d.ts b/web/src/types/resourceItem.d.ts
deleted file mode 100644
index 25bcea80..00000000
--- a/web/src/types/resourceItem.d.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-interface ResourceProps {
- resource: Resource;
- handleCheckClick: () => void;
- handleUncheckClick: () => void;
-}
-
-type ResourceItemType = ResourceProps;
diff --git a/web/src/utils/resource.ts b/web/src/utils/resource.ts
index 36635eff..863dc9db 100644
--- a/web/src/utils/resource.ts
+++ b/web/src/utils/resource.ts
@@ -1,3 +1,5 @@
+import { Resource } from "@/types/proto/api/v2/resource_service_pb";
+
export const getResourceUrl = (resource: Resource, withOrigin = true) => {
if (resource.externalLink) {
return resource.externalLink;
|