Implement drag and drop between Foundry and Gotham(在 Foundry 与 Gotham 之间实现拖放功能)¶
:::callout{theme="neutral"} To access data enrichment, your enrollment must have both Gotham and Foundry, with type mapping enabled. If your application performs drag-and-drop operations with only Gotham or only Foundry, you do not need to implement data enrichment. :::
The following tutorial outlines the steps needed to implement data enrichment. Note that there are sections for adding enrichment to drag and drop zones, but enrichment only needs to happen either at the drag zone or at the drop zone depending on your workflow. Refer to the enrichment guidelines for more information.
Drag and drop enrichment tutorial¶
The steps are as follows:
- Verify that Data Bank Service returns synonymous data.
- Create enrichment utility functions.
- Add enrichment to a drag zone or Add enrichment to a drop zone.
:::callout{theme="neutral"} We recommend installing the latest version of our platform for increased drag and drop interoperability between your application and the Palantir platform. :::
Verify that Data Bank Service returns synonymous data¶
To implement data enrichment, you must first verify that Data Bank Service returns synonymous data as expected.
Supported media types¶
Currently, Data Bank Service supports enriching the media types in the list below, and it is currently possible to enrich data of the Foundry object RID media type with data of the Gotham object media type and vice versa.
"application/x-vnd.palantir.rid.phonograph2-objects.object",
"application/x-vnd.palantir.rid.gotham.object",
Required data structure¶
Below is an example of the required data structure for Data Bank Service requests. Note that JSON objects must first be serialized for Data Bank Service requests; we outline how to use JSON.stringify ↗ for this in the upcoming steps. The request format is as follows:
{
"dataTransfers": [serializedData1, serializedData2, ...]
}
serializedData in the snippet above refers to data that is sent to Data Bank Service for enrichment after being serialized. The dataTransfers object above is not to be confused with the DataTransfer object, they have similar names but distinct purposes. The object above contains the data we want to enrich, and enrichment may happen before writing to the DataTransfer object, or after the DataTransfer object has been dropped in a drop zone.
Each serializedData object has the following structure:
{<media type>: <serialized data>}
For example, if you have Gotham object identifiers and you want to enrich this data with the synonymous Foundry data, your serialized data representation would be as follows:
{
"dataTransfers": [
{
"[\"application/x-vnd.palantir.rid.gotham.object\"]: [\"ri.gotham.XXXXXXXX\", \"ri.gotham.YYYYYYYY\", \"ri.gotham.ZZZZZZZZZZ\"]"
}
]
}
In the snippet above, the media type is application/x-vnd.palantir.rid.gotham.object, which is followed by an array of data with that media type. Data Bank Service will return the mapped synonymous media type, along with data of that media type. Note that the quotations (") must be escaped with a \ to properly format the serialized array.
Use this request format in the curl request below, replacing the application/x-vnd.palantir.rid.gotham.object media type with your media type and adding the data you plan to enrich. Replace <BEARER TOKEN> with your bearer token and <HOSTNAME> with your enrollment host name. Note that the media type's data is in string format, and escapes internal quotation marks with the \ character.
curl --location --request PUT "https://<HOSTNAME>/data-bank-service/api/data-transfer/batchEnrichDataTransfer" \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <BEARER TOKEN>' \
--data '{
"dataTransfers": [
{
"application/x-vnd.palantir.rid.gotham.object": "[\"ri.gotham.XXXXXXXX\", \"ri.gotham.YYYYYYYY\", \"ri.gotham.ZZZZZZZZZZ\"]"
}
]
}'
If your data has synonyms, you should get a response similar to the following:
{
"dataTransfers": [
{
"dataTransfer": {
"application/x-vnd.palantir.rid.gotham.object": "[\"ri.gotham.XXXXXXXX\", \"ri.gotham.YYYYYYYY\", \"ri.gotham.ZZZZZZZZZZ\"]",
"application/x-vnd.palantir.rid.phonograph2-objects.object": "[\"ri.phonograph2-objects.main.object.XXXXXXXX\", \"ri.phonograph2-objects.main.object.YYYYYYYY\", \"ri.phonograph2-objects.main.object.ZZZZZZZZZZ\"]",
},
"errors": []
}
]
}
Note the dataTransfers object mentioned above, the Gotham media type application/x-vnd.palantir.rid.gotham.object followed by data of that media type, and the Foundry media type application/x-vnd.palantir.rid.phonograph2-objects.object followed by data of that media type.
If you do not get synonyms for your object, confirm that your enrollment and Ontology have type mapping enabled. If your Ontology does have type mapping enabled, confirm that type mapping is enabled for your object type by following the type mapping documentation. We also recommend verifying that the data you are sending is mapped to the expected synonymous media type, and that it is supported by Data Bank Service.
In the rest of this tutorial, we will break down the steps for using this request and show you how to use the response to enrich your drag and drop workflows.
:::callout{theme="success"} Now that you have verified that Data Bank Service has synonyms for your data, continue the tutorial to add enrichment to your application. :::
Create enrichment utility functions¶
- Create a function that makes a request to Data Bank Service. Below is an example of how to create the request options for a Data Bank Service request using the Fetch API ↗.
// create a function for creating your request options object using your serialized data
function getRequestOptions(
bearerToken
// serializedData is a mapping of media types to serialized versions of their data
serializedData
){
return {
method: "PUT",
headers: new Headers({
"Authorization": bearerToken,
"Content-Type": "application/json"
}),
body: JSON.stringify({
"dataTransfers": [ serializedData ]
}),
redirect: "follow"
};
}
// use this function as follows
// replace <BEARER TOKEN> with your Bearer Token
const requestOptions = getRequestOptions(
"<BEARER TOKEN>",
{
["application/x-vnd.palantir.rid.gotham.object"]:
"[\"ri.gotham.XXXXXXXX\", \"ri.gotham.YYYYYYYY\", \"ri.gotham.ZZZZZZZZZZ\"]"
}
);
- Hit the Data Bank Service enrichment endpoint to get additional synonymous media types and data of that media type that can be used to enrich a drag or drop zone:
// replace <HOSTNAME> with your enrollment HOSTNAME
const batchEnrichDataTransferURL =
"https://<HOSTNAME>/data-bank-service/api/data-transfer/batchEnrichDataTransfer";
// bearerToken is of type string
// serializedData is of type {[mediaType: string]: string}
function getEnrichedData(
bearerToken,
serializedData
){
// call the function defined in Step 1
const requestOptions = getRequestOptions(bearerToken, serializedData);
const enrichedData =
await fetch(batchEnrichDataTransferURL, requestOptions)
.then((response) => response.json())
.catch((error) => console.error(error));
// since we are only enriching one data transfer, grab the first entry
const enrichedFirstDataTransfer = enrichedData.dataTransfers?.[0]?.dataTransfer;
return enrichedFirstDataTransfer;
}
This endpoint returns a serialized list of objects that each contain the resolved enriched data and a potential list of errors associated with that enrichment. This endpoint returns data in the following format:
{
"dataTransfers":
[
{
"dataTransfer": {"<media type>": "<serialized data>"},
"errors": "[<error1>, <error2>...]"
},
{
"dataTransfer": {"<media type>": "<serialized data>"},
"errors": "[<error1>, <error2>...]"
},
...
]
}
A potential error to look out for is the request media type not being supported by Data Bank Service.
Add enrichment to a drag zone¶
Note that enrichment only needs to be added to a drag or drop zone. Consult the enrichment guidelines to determine if this section of the tutorial is relevant to your workflow.
-
In order to add enrichment to your drag zone, call the
getEnrichedDatafunction from step two of the previous section. Enrichment should happen when your page or component mounts, rather than in thedragstarthandler. This is because you cannot make expensive, blocking calls in thedragstarthandler. The returned enriched data will contain the original data in your request as well as additional synonymous data. -
In the
dragstarthandler, add the obtained enriched data to the drag event's DataTransfer. When this data is added to the drag event's DataTransfer, the user will be able to drag this payload onto both Foundry and Gotham drop zones if enrichment is successful. The code below shows how to request enriched data with Gotham object IDs and usesJSON.stringify↗ to put data in string format.
const gothamObjectIds = ["ri.gotham.XXXXXXXX", "ri.gotham.YYYYYYYY", "ri.gotham.ZZZZZZZZZZ"];
async function getEnrichedFoundryData(){
const enrichedData = await getEnrichedData(
"<BEARER TOKEN>",
{"application/x-vnd.palantir.rid.gotham.object": JSON.stringify(gothamObjectIds)}
);
const enrichedFoundryIdData = enrichedData?.["application/x-vnd.palantir.rid.phonograph2-objects.object"]
if (enrichedFoundryIdData != null){
try {
return JSON.parse(enrichedFoundryIdData);
} catch (error) {
// we were unable to parse the data
console.error(error);
return undefined;
}
}
}
let enrichedFoundryIdData = null;
// here we asynchronously update enriched data
// this is necessary because we cannot implement enrichment in the dragstart handler, as that would be blocking
getEnrichedFoundryData().then((data) => {
enrichedFoundryIdData = data;
});
async function handleDragStart(event) {
event.dataTransfer.setData("application/x-vnd.palantir.rid.gotham.object", JSON.stringify(gothamObjectIds));
if(enrichedFoundryIdData != null){
event.dataTransfer.setData("application/x-vnd.palantir.rid.phonograph2-objects.object", enrichedFoundryIdData)
}
// event.dataTransfer now contains the original Gotham object media type data
// as well as synonymous foundry data
event.dataTransfer.effectAllowed = "move";
}
Using the code above, if you have Gotham object IDs for objects with Foundry synonyms, you can add synonymous data to your DataTransfer so your drag payload can be accepted by both Gotham and Foundry drop zones.
:::callout{theme="success"} After this step, you should be able to drag your drag zone onto both Gotham and Foundry drop zones. Refer to the Palantir media types documentation to find drop zones that can accept your drag zone. :::
Add enrichment to a drop zone¶
Note that enrichment only needs to be added to a drag or drop zone. Consult the enrichment guidelines to determine if this section of the tutorial is relevant to your workflow.
To add enrichment to your drop zone, you need to enrich data from the event's DataTransfer. In the code snippet below, the code expects Gotham object IDs, but can enrich data from the DataTransfer if there is no Gotham object media type on the DataTransfer. For simplicity, assume the drop handler below first tried to access Gotham object data directly from the DataTransfer, and upon failing, moves on to the enrichment in the code block below.
function handleDrop(event) {
// prevent default open-link behavior
event.preventDefault();
// perform some styling cleanup
removeStylingFromDropZone("valid-small-hover");
removeStylingFromDropZone("valid-small");
dropHoveringOverDropZoneCount = 0;
dragInsideApplicationCount = 0;
// <Attempt to access Gotham object data from the DataTransfer, which returns early on success and continues otherwise>
// The Foundry object RIDs media type data can be enriched to Gotham object media type data
const foundryData = event.dataTransfer.getData(
"application/x-vnd.palantir.rid.phonograph2-objects.object"
);
try {
if(foundryData != null && foundryData !== ""){
// try to parse the returned data & send enrichment request,
// if we can't parse the data it must be mis-formatted
const foundryDataParsed = JSON.parse(foundryData);
const serializedData = {
["application/x-vnd.palantir.rid.phonograph2-objects.object"]: foundryDataParsed
}
const enrichedData = await getEnrichedData(
"<BEARER TOKEN>",
serializedData
);
if(enrichedData?.["application/x-vnd.palantir.rid.gotham.object"] != null){
doCoolThingWithGothamObjectIds(
enrichedData["application/x-vnd.palantir.rid.gotham.object"]
);
}
}
} catch (error) {
console.error("Unable to parse data", error)
}
}
:::callout{theme="success"} At this point, your drop zone should be able to accept both Gotham and Foundry data. Refer to the Palantir media types documentation to find drag zones you can drag onto your drop zone. :::
Conclusion¶
Using the code snippets above, you can send a request to the Data Bank Service endpoint to enrich your data so it contains synonyms that are compatible across Gotham and Foundry. This enables draggable data to be accepted by both Gotham and Foundry drop zones, and can enable drop zones to accept both Foundry and Gotham data.
中文翻译¶
在 Foundry 与 Gotham 之间实现拖放功能¶
:::callout{theme="neutral"} 要使用数据富化功能,您的环境必须同时拥有 Gotham 和 Foundry,并启用类型映射。如果您的应用仅与 Gotham 或仅与 Foundry 进行拖放操作,则无需实现数据富化。 :::
以下教程概述了实现数据富化所需的步骤。请注意,其中包含向拖拽区域和放置区域添加富化功能的章节,但根据您的工作流程,富化只需在拖拽区域或放置区域之一进行。更多信息请参阅富化指南。
拖放富化教程¶
步骤如下:
:::callout{theme="neutral"} 我们建议安装最新版本的平台,以增强您的应用与 Palantir 平台之间的拖放互操作性。 :::
验证数据银行服务返回同义数据¶
要实现数据富化,您必须首先验证数据银行服务(Data Bank Service)能按预期返回同义数据。
支持的媒体类型¶
目前,数据银行服务支持对以下列表中的媒体类型进行富化,并且当前可以将 Foundry 对象 RID 媒体类型的数据富化为 Gotham 对象 媒体类型的数据,反之亦然。
"application/x-vnd.palantir.rid.phonograph2-objects.object",
"application/x-vnd.palantir.rid.gotham.object",
所需的数据结构¶
以下是数据银行服务请求所需数据结构的示例。请注意,JSON 对象必须先序列化才能用于数据银行服务请求;我们将在后续步骤中说明如何使用 JSON.stringify ↗。请求格式如下:
{
"dataTransfers": [serializedData1, serializedData2, ...]
}
上述代码片段中的 serializedData 指的是序列化后发送给数据银行服务进行富化的数据。请注意,不要将上述 dataTransfers 对象与 DataTransfer 对象 混淆,它们名称相似但用途不同。上述对象包含我们要富化的数据,富化可以在写入 DataTransfer 对象之前进行,也可以在 DataTransfer 对象被放置到放置区域之后进行。
每个 serializedData 对象具有以下结构:
{<媒体类型>: <序列化数据>}
例如,如果您有 Gotham 对象标识符,并希望用同义的 Foundry 数据来富化这些数据,那么您的序列化数据表示形式如下:
{
"dataTransfers": [
{
"[\"application/x-vnd.palantir.rid.gotham.object\"]: [\"ri.gotham.XXXXXXXX\", \"ri.gotham.YYYYYYYY\", \"ri.gotham.ZZZZZZZZZZ\"]"
}
]
}
在上面的代码片段中,媒体类型是 application/x-vnd.palantir.rid.gotham.object,后面跟着该媒体类型的数据数组。数据银行服务将返回映射后的同义媒体类型及其对应的数据。请注意,引号 (") 必须使用 \ 进行转义,以正确格式化序列化后的数组。
在下面的 curl 请求中使用此请求格式,将 application/x-vnd.palantir.rid.gotham.object 媒体类型替换为您自己的媒体类型,并添加您计划富化的数据。将 <BEARER TOKEN> 替换为您的 bearer token,将 <HOSTNAME> 替换为您环境的主机名。请注意,媒体类型的数据是字符串格式,并使用 \ 字符转义内部引号。
curl --location --request PUT "https://<HOSTNAME>/data-bank-service/api/data-transfer/batchEnrichDataTransfer" \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <BEARER TOKEN>' \
--data '{
"dataTransfers": [
{
"application/x-vnd.palantir.rid.gotham.object": "[\"ri.gotham.XXXXXXXX\", \"ri.gotham.YYYYYYYY\", \"ri.gotham.ZZZZZZZZZZ\"]"
}
]
}'
如果您的数据存在同义词,您应该会收到类似以下的响应:
{
"dataTransfers": [
{
"dataTransfer": {
"application/x-vnd.palantir.rid.gotham.object": "[\"ri.gotham.XXXXXXXX\", \"ri.gotham.YYYYYYYY\", \"ri.gotham.ZZZZZZZZZZ\"]",
"application/x-vnd.palantir.rid.phonograph2-objects.object": "[\"ri.phonograph2-objects.main.object.XXXXXXXX\", \"ri.phonograph2-objects.main.object.YYYYYYYY\", \"ri.phonograph2-objects.main.object.ZZZZZZZZZZ\"]",
},
"errors": []
}
]
}
请注意上面提到的 dataTransfers 对象,其中包含 Gotham 媒体类型 application/x-vnd.palantir.rid.gotham.object 及其对应的数据,以及 Foundry 媒体类型 application/x-vnd.palantir.rid.phonograph2-objects.object 及其对应的数据。
如果您的对象没有返回同义词,请确认您的环境和本体(Ontology)已启用类型映射。如果您的本体确实启用了类型映射,请按照类型映射文档确认您的对象类型已启用类型映射。我们还建议验证您发送的数据是否映射到了预期的同义媒体类型,并且该媒体类型受数据银行服务支持。
在本教程的其余部分,我们将分解使用此请求的步骤,并向您展示如何使用响应来富化您的拖放工作流程。
:::callout{theme="success"} 现在您已验证数据银行服务拥有您数据的同义词,请继续本教程,向您的应用添加富化功能。 :::
创建富化工具函数¶
- 创建一个向数据银行服务发起请求的函数。以下是使用 Fetch API ↗ 创建数据银行服务请求选项的示例。
// 创建一个函数,使用序列化数据创建请求选项对象
function getRequestOptions(
bearerToken
// serializedData 是媒体类型到其序列化数据的映射
serializedData
){
return {
method: "PUT",
headers: new Headers({
"Authorization": bearerToken,
"Content-Type": "application/json"
}),
body: JSON.stringify({
"dataTransfers": [ serializedData ]
}),
redirect: "follow"
};
}
// 按如下方式使用此函数
// 将 <BEARER TOKEN> 替换为您的 Bearer Token
const requestOptions = getRequestOptions(
"<BEARER TOKEN>",
{
["application/x-vnd.palantir.rid.gotham.object"]:
"[\"ri.gotham.XXXXXXXX\", \"ri.gotham.YYYYYYYY\", \"ri.gotham.ZZZZZZZZZZ\"]"
}
);
- 调用数据银行服务的富化端点,以获取额外的同义媒体类型及其数据,这些数据可用于富化拖拽区域或放置区域:
// 将 <HOSTNAME> 替换为您环境的 HOSTNAME
const batchEnrichDataTransferURL =
"https://<HOSTNAME>/data-bank-service/api/data-transfer/batchEnrichDataTransfer";
// bearerToken 类型为 string
// serializedData 类型为 {[mediaType: string]: string}
function getEnrichedData(
bearerToken,
serializedData
){
// 调用步骤 1 中定义的函数
const requestOptions = getRequestOptions(bearerToken, serializedData);
const enrichedData =
await fetch(batchEnrichDataTransferURL, requestOptions)
.then((response) => response.json())
.catch((error) => console.error(error));
// 因为我们只富化一个数据传输,所以获取第一个条目
const enrichedFirstDataTransfer = enrichedData.dataTransfers?.[0]?.dataTransfer;
return enrichedFirstDataTransfer;
}
此端点返回一个序列化对象列表,每个对象包含已解析的富化数据以及与该富化相关的潜在错误列表。此端点返回的数据格式如下:
{
"dataTransfers":
[
{
"dataTransfer": {"<媒体类型>": "<序列化数据>"},
"errors": "[<错误1>, <错误2>...]"
},
{
"dataTransfer": {"<媒体类型>": "<序列化数据>"},
"errors": "[<错误1>, <错误2>...]"
},
...
]
}
一个需要注意的潜在错误是请求的媒体类型不受数据银行服务支持。
向拖拽区域添加富化功能¶
请注意,富化只需添加到拖拽或放置区域。请查阅富化指南,以确定本教程的此部分是否与您的工作流程相关。
-
为了向拖拽区域添加富化功能,请调用上一节第二步中的
getEnrichedData函数。富化应在页面或组件挂载时进行,而不是在dragstart处理程序中。这是因为您无法在dragstart处理程序中执行耗时、阻塞的调用。返回的富化数据将包含您请求中的原始数据以及额外的同义数据。 -
在
dragstart处理程序中,将获取到的富化数据添加到拖拽事件的 DataTransfer 中。当这些数据被添加到拖拽事件的 DataTransfer 后,如果富化成功,用户将能够将此负载拖放到 Foundry 和 Gotham 的放置区域。下面的代码展示了如何使用 Gotham 对象 ID 请求富化数据,并使用JSON.stringify↗ 将数据转换为字符串格式。
const gothamObjectIds = ["ri.gotham.XXXXXXXX", "ri.gotham.YYYYYYYY", "ri.gotham.ZZZZZZZZZZ"];
async function getEnrichedFoundryData(){
const enrichedData = await getEnrichedData(
"<BEARER TOKEN>",
{"application/x-vnd.palantir.rid.gotham.object": JSON.stringify(gothamObjectIds)}
);
const enrichedFoundryIdData = enrichedData?.["application/x-vnd.palantir.rid.phonograph2-objects.object"]
if (enrichedFoundryIdData != null){
try {
return JSON.parse(enrichedFoundryIdData);
} catch (error) {
// 无法解析数据
console.error(error);
return undefined;
}
}
}
let enrichedFoundryIdData = null;
// 这里我们异步更新富化数据
// 这是必要的,因为我们不能在 dragstart 处理程序中实现富化,因为那会是阻塞的
getEnrichedFoundryData().then((data) => {
enrichedFoundryIdData = data;
});
async function handleDragStart(event) {
event.dataTransfer.setData("application/x-vnd.palantir.rid.gotham.object", JSON.stringify(gothamObjectIds));
if(enrichedFoundryIdData != null){
event.dataTransfer.setData("application/x-vnd.palantir.rid.phonograph2-objects.object", enrichedFoundryIdData)
}
// event.dataTransfer 现在包含原始的 Gotham 对象媒体类型数据
// 以及同义的 Foundry 数据
event.dataTransfer.effectAllowed = "move";
}
使用上述代码,如果您拥有具有 Foundry 同义词的对象的 Gotham 对象 ID,您可以将同义数据添加到您的 DataTransfer 中,以便您的拖拽负载能够被 Gotham 和 Foundry 的放置区域接受。
:::callout{theme="success"} 完成此步骤后,您应该能够将拖拽区域拖放到 Gotham 和 Foundry 的放置区域上。请参阅 Palantir 媒体类型文档 查找可以接受您拖拽区域的放置区域。 :::
向放置区域添加富化功能¶
请注意,富化只需添加到拖拽或放置区域。请查阅富化指南,以确定本教程的此部分是否与您的工作流程相关。
要向放置区域添加富化功能,您需要富化来自事件 DataTransfer 的数据。在下面的代码片段中,代码期望接收 Gotham 对象 ID,但如果 DataTransfer 上没有 Gotham 对象媒体类型,则可以对 DataTransfer 中的数据进行富化。为简单起见,假设下面的放置处理程序首先尝试直接从 DataTransfer 访问 Gotham 对象数据,如果失败,则继续执行下面代码块中的富化逻辑。
function handleDrop(event) {
// 阻止默认的打开链接行为
event.preventDefault();
// 执行一些样式清理
removeStylingFromDropZone("valid-small-hover");
removeStylingFromDropZone("valid-small");
dropHoveringOverDropZoneCount = 0;
dragInsideApplicationCount = 0;
// <尝试从 DataTransfer 访问 Gotham 对象数据,成功则提前返回,否则继续>
// Foundry 对象 RID 媒体类型数据可以富化为 Gotham 对象媒体类型数据
const foundryData = event.dataTransfer.getData(
"application/x-vnd.palantir.rid.phonograph2-objects.object"
);
try {
if(foundryData != null && foundryData !== ""){
// 尝试解析返回的数据并发送富化请求,
// 如果无法解析数据,则说明格式错误
const foundryDataParsed = JSON.parse(foundryData);
const serializedData = {
["application/x-vnd.palantir.rid.phonograph2-objects.object"]: foundryDataParsed
}
const enrichedData = await getEnrichedData(
"<BEARER TOKEN>",
serializedData
);
if(enrichedData?.["application/x-vnd.palantir.rid.gotham.object"] != null){
doCoolThingWithGothamObjectIds(
enrichedData["application/x-vnd.palantir.rid.gotham.object"]
);
}
}
} catch (error) {
console.error("无法解析数据", error)
}
}
:::callout{theme="success"} 至此,您的放置区域应该能够接受 Gotham 和 Foundry 的数据。请参阅 Palantir 媒体类型文档 查找可以拖放到您放置区域的拖拽区域。 :::
结论¶
使用上述代码片段,您可以向数据银行服务端点发送请求以富化您的数据,使其包含在 Gotham 和 Foundry 之间兼容的同义词。这使得可拖拽数据能够被 Gotham 和 Foundry 的放置区域接受,并且可以使放置区域能够接受 Foundry 和 Gotham 的数据。