useTasks reference(useTasks 参考文档)¶
Learn more about the useTasks hook.
/*
* Copyright 2025 Palantir Technologies, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import useSWR from "swr";
import { useOsdkClient } from "@osdk/react";
import { OsdkITask } from "@advanced-to-do-application/sdk";
import { IProject } from "./useProjects";
import { useCallback, useEffect, useState } from "react";
import useAdmin from "./useAdmin";
import _ from "lodash";
import type { User } from "@osdk/foundry.admin";
import type { InterfaceMetadata } from "@osdk/api";
export interface ITask {
osdkTask: OsdkITask.OsdkInstance;
createdBy: User;
assignedTo: User;
}
function useTasks(project: IProject) {
const client = useOsdkClient();
const [metadata, setMetadata] = useState<InterfaceMetadata>();
const { getBatchUserDetails } = useAdmin();
// `$includeAllBaseObjectProperties: true,` means that although we are fetching the object through its interface implementation,
// we are still going to get all the base object properties; when we pivot to the base object using $as, we don not need to fetch them again.
const fetcher = useCallback(async () => {
const tasksPage = await client(OsdkITask).where({
projectId: { $eq: project.$primaryKey },
}).fetchPage({
$includeAllBaseObjectProperties: true,
$orderBy: { "dueDate": "desc", "status": "asc" },
});
// Get the user details for the createdBy field.
const createdByIds = _.uniq(tasksPage.data.map((task) => task.createdBy as string));
const createdByUserList = await getBatchUserDetails(createdByIds);
// Get the user details for the assignedTo field.
const assignedToIds = _.uniq(tasksPage.data.map((task) => task.assignedTo as string));
const assignedToUserList = await getBatchUserDetails(assignedToIds);
const tasksList: ITask[] = tasksPage.data.map((task) => ({
osdkTask: task,
assignedTo: assignedToUserList[task.assignedTo as string],
createdBy: createdByUserList[task.createdBy as string],
}));
return tasksList;
} , [getBatchUserDetails, project.$primaryKey, client]);
const { data, isLoading, isValidating, error, mutate } = useSWR<ITask[]>(
["tasks",project.$primaryKey],
fetcher,
{ revalidateOnFocus: false }
);
// This shows how we read the object type metadata and use the property display name from the ontology.
const getObjectTypeMetadata = useCallback(async () => {
const objectTypeMetadata = await client.fetchMetadata(OsdkITask);
setMetadata(objectTypeMetadata);
} , [client]);
useEffect(() => {
getObjectTypeMetadata();
}, [getObjectTypeMetadata]);
useEffect(() => {
// Subscribe to the object set to get real-time updates.
const subscription = client(OsdkITask)
.where({
projectId: { $eq: project.$primaryKey },
})
.subscribe(
{
onChange(update) {
if (update.state === "ADDED_OR_UPDATED") {
// An object has received an update or an object was added to the object set.
const currentObject = data?.find((task) => task.osdkTask.$primaryKey === update.object.$primaryKey);
if (currentObject !== undefined) {
// Get the user details for the createdBy field and the assignedTo field.
getBatchUserDetails([update.object.createdBy as string, update.object.assignedTo as string]).then((userList) => {
const updatedObject: ITask = {
osdkTask: update.object,
assignedTo: userList[update.object.assignedTo as string],
createdBy: userList[update.object.createdBy as string],
};
// Replace the object in date with the new one to mutate without fetching.
mutate((currentData: ITask[] | undefined) => {
if (!currentData) return [];
return currentData.map((task) => task.osdkTask.$primaryKey === update.object.$primaryKey ? updatedObject : task);
}, { revalidate: false });
});
}
}
else if (update.state === "REMOVED") {
// remove the object from the data mutate without fetching.
mutate((currentData: ITask[] | undefined) => {
if (!currentData) return [];
return currentData.filter((task) => task.osdkTask.$primaryKey !== update.object.$primaryKey);
}, { revalidate: false });
}
},
onSuccessfulSubscription() {
// The subscription was successful and you can expect to receive updates.
},
onError(err) {
// There was an error with the subscription and you will not receive any more updates.
console.error(err);
},
onOutOfDate() {
// We could not keep track of all changes. Reload the objects in your set.
},
},
);
subscription.unsubscribe();
},[data, getBatchUserDetails, mutate, project.$primaryKey, client]);
return {
tasks: data ?? [],
isLoading,
isValidating,
isError: error,
metadata,
};
}
export default useTasks;
中文翻译¶
useTasks 参考文档¶
/*
* 版权所有 2025 Palantir Technologies, Inc. 保留所有权利。
*
* 根据 Apache 许可证 2.0 版("许可证")授权;
* 除非遵守许可证,否则您不得使用此文件。
* 您可以在以下网址获取许可证副本:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 除非适用法律要求或书面同意,否则按"原样"分发的软件
* 不提供任何明示或暗示的保证或条件。
* 请参阅许可证以了解管理权限和限制的具体语言。
*/
import useSWR from "swr";
import { useOsdkClient } from "@osdk/react";
import { OsdkITask } from "@advanced-to-do-application/sdk";
import { IProject } from "./useProjects";
import { useCallback, useEffect, useState } from "react";
import useAdmin from "./useAdmin";
import _ from "lodash";
import type { User } from "@osdk/foundry.admin";
import type { InterfaceMetadata } from "@osdk/api";
export interface ITask {
osdkTask: OsdkITask.OsdkInstance;
createdBy: User;
assignedTo: User;
}
function useTasks(project: IProject) {
const client = useOsdkClient();
const [metadata, setMetadata] = useState<InterfaceMetadata>();
const { getBatchUserDetails } = useAdmin();
// `$includeAllBaseObjectProperties: true` 表示虽然我们通过接口实现获取对象,
// 但仍然会获取所有基础对象属性;当我们使用 $as 切换到基础对象时,无需再次获取这些属性。
const fetcher = useCallback(async () => {
const tasksPage = await client(OsdkITask).where({
projectId: { $eq: project.$primaryKey },
}).fetchPage({
$includeAllBaseObjectProperties: true,
$orderBy: { "dueDate": "desc", "status": "asc" },
});
// 获取 createdBy 字段的用户详情。
const createdByIds = _.uniq(tasksPage.data.map((task) => task.createdBy as string));
const createdByUserList = await getBatchUserDetails(createdByIds);
// 获取 assignedTo 字段的用户详情。
const assignedToIds = _.uniq(tasksPage.data.map((task) => task.assignedTo as string));
const assignedToUserList = await getBatchUserDetails(assignedToIds);
const tasksList: ITask[] = tasksPage.data.map((task) => ({
osdkTask: task,
assignedTo: assignedToUserList[task.assignedTo as string],
createdBy: createdByUserList[task.createdBy as string],
}));
return tasksList;
} , [getBatchUserDetails, project.$primaryKey, client]);
const { data, isLoading, isValidating, error, mutate } = useSWR<ITask[]>(
["tasks",project.$primaryKey],
fetcher,
{ revalidateOnFocus: false }
);
// 这展示了如何读取对象类型元数据(object type metadata)并使用本体(ontology)中的属性显示名称。
const getObjectTypeMetadata = useCallback(async () => {
const objectTypeMetadata = await client.fetchMetadata(OsdkITask);
setMetadata(objectTypeMetadata);
} , [client]);
useEffect(() => {
getObjectTypeMetadata();
}, [getObjectTypeMetadata]);
useEffect(() => {
// 订阅对象集以获取实时更新。
const subscription = client(OsdkITask)
.where({
projectId: { $eq: project.$primaryKey },
})
.subscribe(
{
onChange(update) {
if (update.state === "ADDED_OR_UPDATED") {
// 对象收到更新或对象被添加到对象集中。
const currentObject = data?.find((task) => task.osdkTask.$primaryKey === update.object.$primaryKey);
if (currentObject !== undefined) {
// 获取 createdBy 字段和 assignedTo 字段的用户详情。
getBatchUserDetails([update.object.createdBy as string, update.object.assignedTo as string]).then((userList) => {
const updatedObject: ITask = {
osdkTask: update.object,
assignedTo: userList[update.object.assignedTo as string],
createdBy: userList[update.object.createdBy as string],
};
// 替换 data 中的对象,无需重新获取即可进行突变(mutate)。
mutate((currentData: ITask[] | undefined) => {
if (!currentData) return [];
return currentData.map((task) => task.osdkTask.$primaryKey === update.object.$primaryKey ? updatedObject : task);
}, { revalidate: false });
});
}
}
else if (update.state === "REMOVED") {
// 从 data 中移除对象,无需重新获取即可进行突变。
mutate((currentData: ITask[] | undefined) => {
if (!currentData) return [];
return currentData.filter((task) => task.osdkTask.$primaryKey !== update.object.$primaryKey);
}, { revalidate: false });
}
},
onSuccessfulSubscription() {
// 订阅成功,您可以期待收到更新。
},
onError(err) {
// 订阅出现错误,您将不再收到任何更新。
console.error(err);
},
onOutOfDate() {
// 无法跟踪所有更改。请重新加载集合中的对象。
},
},
);
subscription.unsubscribe();
},[data, getBatchUserDetails, mutate, project.$primaryKey, client]);
return {
tasks: data ?? [],
isLoading,
isValidating,
isError: error,
metadata,
};
}
export default useTasks;