Skip to content

Commit

Permalink
14796 front end change (digital-asset#14811)
Browse files Browse the repository at this point in the history
* added graphql resolve field

CHANGELOG_BEGIN
CHANGELOG_END

* render interface prefix; add interface in the route path; added graphql resolve field

* pass in interface id if the choice exercised via interface

* render interface choice in popup when click wrench icon
  • Loading branch information
chunlokling-da authored Aug 25, 2022
1 parent 1a90e9c commit 51ce902
Show file tree
Hide file tree
Showing 20 changed files with 171 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ final case class CommandRow(
template: Option[String],
recordArgument: Option[String],
contractId: Option[String],
interfaceId: Option[String],
choice: Option[String],
argumentValue: Option[String],
) {
Expand Down Expand Up @@ -58,6 +59,7 @@ final case class CommandRow(
(for {
tp <- Try(template.get)
tid <- Try(parseOpaqueIdentifier(tp).get)
iidOp <- Try(interfaceId.map(parseOpaqueIdentifier(_).get))
t <- Try(types.template(tid).get)
cId <- Try(contractId.get)
ch <- Try(choice.get)
Expand All @@ -72,6 +74,7 @@ final case class CommandRow(
Instant.parse(platformTime),
ApiTypes.ContractId(cId),
tid,
iidOp,
ApiTypes.Choice(ch),
arg,
)
Expand Down Expand Up @@ -103,6 +106,7 @@ object CommandRow {
None,
None,
None,
None,
)
case e: ExerciseCommand =>
CommandRow(
Expand All @@ -114,6 +118,7 @@ object CommandRow {
Some(e.template.asOpaqueString),
None,
Some(e.contract.unwrap),
e.interfaceId.map(_.asOpaqueString),
Some(e.choice.unwrap),
Some(ApiCodecVerbose.apiValueToJsValue(e.argument).compactPrint),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,11 @@ final class GraphQLSchema(customEndpoints: Set[CustomEndpoint[_]]) {
),
Field("parameter", JsonType.DamlLfTypeType, resolve = _.value.parameter),
Field("consuming", BooleanType, resolve = _.value.consuming),
Field(
"inheritedInterface",
OptionType(StringType),
resolve = _.value.inheritedInterface.map(_.asOpaqueString),
),
),
)

Expand Down Expand Up @@ -196,6 +201,11 @@ final class GraphQLSchema(customEndpoints: Set[CustomEndpoint[_]]) {
resolve = context =>
buildTemplateContractPager(context).fetch(context.ctx.ledger, context.ctx.templates),
),
Field(
"implementedInterfaces",
ListType(StringType),
resolve = _.value.implementedInterfaces.toList.map(_.asOpaqueString),
),
),
)

Expand Down Expand Up @@ -498,6 +508,11 @@ final class GraphQLSchema(customEndpoints: Set[CustomEndpoint[_]]) {
StringType,
resolve = context => Tag.unwrap[String, ApiTypes.ContractIdTag](context.value.contract),
),
Field(
"interfaceId",
OptionType(StringType),
resolve = _.value.interfaceId.map(_.asOpaqueString),
),
Field(
"choice",
StringType,
Expand Down Expand Up @@ -708,6 +723,7 @@ final class GraphQLSchema(customEndpoints: Set[CustomEndpoint[_]]) {
val TemplateIdArgument = Argument("templateId", IDType)
val ContractIdArgument = Argument("contractId", IDType)
val ChoiceIdArgument = Argument("choiceId", IDType)
val InterfaceIdArgument = Argument("interfaceId", OptionInputType(IDType))
val AnyArgument = Argument("argument", OptionInputType(JsonType.ApiValueType))

val MutationType = ObjectType(
Expand Down Expand Up @@ -738,11 +754,13 @@ final class GraphQLSchema(customEndpoints: Set[CustomEndpoint[_]]) {
Field(
"exercise",
CommandIdType,
arguments = ContractIdArgument :: ChoiceIdArgument :: AnyArgument :: Nil,
arguments =
ContractIdArgument :: InterfaceIdArgument :: ChoiceIdArgument :: AnyArgument :: Nil,
resolve = context => {
val command = ExerciseChoice(
context.ctx.party,
ApiTypes.ContractId(context.arg(ContractIdArgument)),
context.arg(InterfaceIdArgument).map(InterfaceStringId(_)),
ApiTypes.Choice(context.arg(ChoiceIdArgument)),
context.arg(AnyArgument).orNull,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ final case class ExerciseCommand(
platformTime: Instant,
contract: ApiTypes.ContractId,
template: DamlLfIdentifier,
interfaceId: Option[DamlLfIdentifier],
choice: ApiTypes.Choice,
argument: ApiValue,
) extends Command
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
package com.daml.navigator.model.converter

import java.time.Instant

import com.daml.lf.data.Ref
import com.daml.lf.data.LawlessTraversals._
import com.daml.lf.iface
Expand All @@ -13,9 +12,12 @@ import com.daml.ledger.api.{v1 => V1}
import com.daml.ledger.api.refinements.ApiTypes
import com.daml.ledger.api.validation.NoLoggingValueValidator.{validateRecord, validateValue}
import com.daml.navigator.{model => Model}
import com.daml.navigator.model.{IdentifierApiConversions, IdentifierDamlConversions}
import com.daml.navigator.model.{
DamlLfIdentifier,
IdentifierApiConversions,
IdentifierDamlConversions,
}
import com.daml.platform.participant.util.LfEngineToApi.{lfValueToApiRecord, lfValueToApiValue}

import scalaz.Tag
import scalaz.syntax.bifunctor._
import scalaz.syntax.traverse._
Expand Down Expand Up @@ -467,7 +469,7 @@ case object LedgerApiV1 {
case cmd: Model.CreateCommand =>
writeCreateContract(party, cmd.template, cmd.argument)
case cmd: Model.ExerciseCommand =>
writeExerciseChoice(party, cmd.contract, cmd.choice, cmd.argument)
writeExerciseChoice(party, cmd.contract, cmd.interfaceId, cmd.choice, cmd.argument)
}
}

Expand Down Expand Up @@ -497,6 +499,7 @@ case object LedgerApiV1 {
def writeExerciseChoice(
party: Model.PartyState,
contractId: ApiTypes.ContractId,
interfaceId: Option[DamlLfIdentifier],
choiceId: ApiTypes.Choice,
value: Model.ApiValue,
): Result[V1.commands.Command] = {
Expand All @@ -514,7 +517,7 @@ case object LedgerApiV1 {
V1.commands.Command(
V1.commands.Command.Command.Exercise(
V1.commands.ExerciseCommand(
Some(contract.template.id.asApi),
interfaceId.orElse(Some(contract.template.id)).map(_.asApi),
Tag.unwrap(contractId),
Tag.unwrap(choiceId),
Some(argument),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ package object model extends NavigatorModelAliases[String] {
type TemplateStringId = String @@ TemplateStringIdTag
val TemplateStringId = Tag.of[TemplateStringIdTag]

type InterfaceStringId = String @@ InterfaceStringIdTag
val InterfaceStringId = Tag.of[InterfaceStringIdTag]

// ----------------------------------------------------------------------------------------------
// Types used in the ledger API
// ----------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -100,11 +103,14 @@ package object model extends NavigatorModelAliases[String] {
}
}

def parseOpaqueIdentifier(id: TemplateStringId): Option[DamlLfRef.Identifier] =
def parseTemplateOpaqueIdentifier(id: TemplateStringId): Option[DamlLfRef.Identifier] =
parseOpaqueIdentifier(TemplateStringId.unwrap(id))

def parseInterfaceOpaqueIdentifier(id: InterfaceStringId): Option[DamlLfRef.Identifier] =
parseOpaqueIdentifier(InterfaceStringId.unwrap(id))
}

package model {
sealed trait TemplateStringIdTag
sealed trait InterfaceStringIdTag
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ object Store {
case class ExerciseChoice(
party: PartyState,
contractId: ApiTypes.ContractId,
interfaceId: Option[InterfaceStringId],
choiceId: ApiTypes.Choice,
argument: ApiValue,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,16 @@ class PlatformStore(
case CreateContract(party, templateId, value) =>
createContract(state.time.time.getCurrentTime, party, templateId, value, sender())

case ExerciseChoice(party, contractId, choiceId, value) =>
exerciseChoice(state.time.time.getCurrentTime, party, contractId, choiceId, value, sender())
case ExerciseChoice(party, contractId, interfaceId, choiceId, value) =>
exerciseChoice(
state.time.time.getCurrentTime,
party,
contractId,
interfaceId,
choiceId,
value,
sender(),
)

case GetParties(search) =>
val lowerCaseSearch = search.toLowerCase
Expand Down Expand Up @@ -461,7 +469,7 @@ class PlatformStore(
val workflowId = workflowIdGenerator.generateRandom
val index = commandIndex.incrementAndGet()

parseOpaqueIdentifier(templateId).fold({
parseTemplateOpaqueIdentifier(templateId).fold({
val msg = s"Create contract command not sent, '$templateId' is not a valid Daml-LF identifier"
log.warning(msg)
sender ! Failure(StoreException(msg))
Expand All @@ -476,6 +484,7 @@ class PlatformStore(
platformTime: Instant,
party: PartyState,
contractId: ApiTypes.ContractId,
interfaceId: Option[InterfaceStringId],
choice: ApiTypes.Choice,
value: ApiValue,
sender: ActorRef,
Expand All @@ -500,6 +509,7 @@ class PlatformStore(
platformTime,
contractId,
contract.template.id,
interfaceId.flatMap(parseInterfaceOpaqueIdentifier),
choice,
value,
)
Expand Down
5 changes: 4 additions & 1 deletion navigator/backend/src/test/resources/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ type Choice {
name: String!
parameter: DamlLfType!
consuming: Boolean!
inheritedInterface: String
}

interface Command {
Expand Down Expand Up @@ -126,6 +127,7 @@ interface Event {
type ExerciseCommand implements Node & Command {
contract: Contract
contractId: String!
interfaceId: String
choice: String!
argument: DamlLfValue!
}
Expand Down Expand Up @@ -160,7 +162,7 @@ type LedgerTime {
type Mutation {
advanceTime(time: Time!): LedgerTime!
create(templateId: ID!, argument: DamlLfValue): CommandId!
exercise(contractId: ID!, choiceId: ID!, argument: DamlLfValue): CommandId!
exercise(contractId: ID!, interfaceId: ID, choiceId: ID!, argument: DamlLfValue): CommandId!
}

interface Node {
Expand Down Expand Up @@ -202,6 +204,7 @@ type Template implements Node & DamlLfNode {
parameterDef: DamlLfDefDataType!
choices: [Choice!]!
contracts(search: String, filter: [FilterCriterion!], includeArchived: Boolean, count: Int, start: String, sort: [SortCriterion!]): ContractPagination!
implementedInterfaces: [String!]!
}

type TemplateEdge {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class RowSpec extends AnyWordSpec with Matchers {
Instant.EPOCH,
ApiTypes.ContractId("#0:0"),
C.complexRecordId,
Some(C.complexRecordId),
ApiTypes.Choice("text"),
C.simpleTextV,
)
Expand Down
6 changes: 6 additions & 0 deletions navigator/frontend/src/api/Queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface ContractDetailsById_node_Contract_template_choices {
__typename: "Choice";
name: string;
parameter: OpaqueTypes.DamlLfType;
inheritedInterface: string | null;
}

export interface ContractDetailsById_node_Contract_template {
Expand Down Expand Up @@ -67,6 +68,7 @@ export interface ContractExercise {

export interface ContractExerciseVariables {
contractId: string;
interfaceId?: string | null;
choiceId: string;
argument?: OpaqueTypes.DamlLfValue | null;
}
Expand Down Expand Up @@ -99,6 +101,7 @@ export interface ContractsQuery_contracts_edges_node_archiveEvent {
export interface ContractsQuery_contracts_edges_node_template_choices {
__typename: "Choice";
name: string;
inheritedInterface: string | null;
}

export interface ContractsQuery_contracts_edges_node_template {
Expand Down Expand Up @@ -237,6 +240,7 @@ export interface ContractsByTemplateQuery_node_Contract {
export interface ContractsByTemplateQuery_node_Template_choices {
__typename: "Choice";
name: string;
inheritedInterface: string | null;
}

export interface ContractsByTemplateQuery_node_Template_contracts_edges_node_createEvent_transaction {
Expand All @@ -258,6 +262,7 @@ export interface ContractsByTemplateQuery_node_Template_contracts_edges_node_arc
export interface ContractsByTemplateQuery_node_Template_contracts_edges_node_template_choices {
__typename: "Choice";
name: string;
inheritedInterface: string | null;
}

export interface ContractsByTemplateQuery_node_Template_contracts_edges_node_template {
Expand Down Expand Up @@ -325,6 +330,7 @@ export interface TemplatesQuery_templates_edges_node_contracts {
export interface TemplatesQuery_templates_edges_node {
__typename: "Template";
id: string;
implementedInterfaces: string[];
topLevelDecl: string;
contracts: TemplatesQuery_templates_edges_node_contracts;
}
Expand Down
Loading

0 comments on commit 51ce902

Please sign in to comment.