Implement drag and drop between Foundry and Gotham

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:

  1. Verify that Data Bank Service returns synonymous data.
  2. Create enrichment utility functions.
  3. Add enrichment to a drag zone or Add enrichment to a drop zone.

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:

Copied!
1 2 3 { "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:

Copied!
1 {<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:

Copied!
1 2 3 4 5 6 7 { "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.

Copied!
1 2 3 4 5 6 7 8 9 10 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:

Copied!
1 2 3 4 5 6 7 8 9 10 11 { "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.

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

  1. 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 ↗️.
Copied!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 // 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: { "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\"]" } );
  1. 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:
Copied!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 // 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:

Copied!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 { "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.

  1. In order to add enrichment to your drag zone, call the getEnrichedData function from step two of the previous section. Enrichment should happen when your page or component mounts, rather than in the dragstart handler. This is because you cannot make expensive, blocking calls in the dragstart handler. The returned enriched data will contain the original data in your request as well as additional synonymous data.

  2. In the dragstart handler, 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 uses JSON.stringify ↗️ to put data in string format.

Copied!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 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.

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.

Copied!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 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) } }

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.