Robert Autenrieth
Robert Autenrieth

Reputation: 76

Adding a button to Navigator to exercise a choice

Navigator contains a feature where users can define their own table views, see DAML docs for Navigator.

Is it possible to create a view where one column renders a button that, when clicked, immediately exercises a choice?

Upvotes: 2

Views: 67

Answers (1)

Robert Autenrieth
Robert Autenrieth

Reputation: 76

Yes, this is possible. The customized views allow you to render arbitrary React components, so let's create one to exercise a choice.

First, start with a working frontend-config.js file. The DAML quickstart project contains one.

Then, make sure you import at least the following symbols at the top of the file:

import React from 'react';
import { Button, DamlLfValue, withExercise } from '@da/ui-core';

Then, define the following top level values (for example, just below export const version={...}):


// Create a React component to render a button that exercises a choice on click.
const ExerciseChoiceButtonBase = (props) => (
  <Button
    onClick={(e) => {
      props.exercise(props.contractId, props.choiceName, props.choiceArgument);
      e.stopPropagation();
    }}
  >
    {props.title}
  </Button>
)
ExerciseChoiceButtonBase.displayName = 'ExerciseChoiceButtonBase';

// Inject the `exercise` property to the props of the wrapped component.
// The value of that property is a convenience function to send a
// network request to exercise a choice.
const ExerciseChoiceButton = withExercise()(ExerciseChoiceButtonBase)
ExerciseChoiceButton.displayName = 'ExerciseChoiceButton';

Finally, use the following code in your table cell definition:

{
        key: "id",
        title: "Action",
        createCell: ({rowData}) => {
          // Render our new component.
          // The contract ID and choice argument are computed from the current contract row.
          return ({
            type: "react",
            value: <ExerciseChoiceButton
              title='Transfer to issuer'
              contractId={rowData.id}
              choiceArgument={
                DamlLfValue.record(undefined, [
                  {label: 'newOwner', value: DamlLfValue.party(DamlLfValue.toJSON(rowData.argument).issuer)}
                ])
              }
              choiceName='Iou_Transfer'
            />
          });
        },
        sortable: true,
        width: 80,
        weight: 3,
        alignment: "left"
}

Another option would be create a React component where the onClick handler sends a REST API request using fetch(). Inspect the network traffic when exercising a choice through the Navigator UI in order to find out the format of the request.

Upvotes: 2

Related Questions