daml/templates/gsg-trigger.patch
Robin Krom 345e26790c
create-daml-app: Use alias templates for display names (#12390)
* create-daml-app: Use alias templates for display names

We introduce Alias contracts to the create-daml-app Daml model and use
them to display aliases in the UI instead of party identifier strings.

CHANGELOG_BEGIN
CHANGELOG_END

* fix tests

* addressing review

* Add comments to Setup.daml

* factor out alias to option conversion

CHANGELOG_BEGIN
CHANGELOG_END

* small fix in setup.daml

* replace user dropdown with input in login screen

* fix compatibility tests

* fix alias loading flick in mainscreen

* remove canton incompatible sandbox options from daml.yaml

* fix gsg-trigger.patc
2022-01-27 14:07:39 +01:00

229 lines
7.5 KiB
Diff

diff -Naur create-daml-app/daml/ChatBot.daml gsg-trigger/daml/ChatBot.daml
--- create-daml-app/daml/ChatBot.daml 1970-01-01 01:00:00.000000000 +0100
+++ gsg-trigger/daml/ChatBot.daml 2022-01-12 17:55:45.838308273 +0100
@@ -0,0 +1,29 @@
+module ChatBot where
+
+import qualified Daml.Trigger as T
+import qualified User
+import qualified DA.List.Total as List
+import DA.Action (when)
+import DA.Optional (whenSome)
+
+autoReply : T.Trigger ()
+autoReply = T.Trigger
+ { initialize = pure ()
+ , updateState = \_ -> pure ()
+ , rule = \p -> do
+ message_contracts <- T.query @User.Message
+ let messages = map snd message_contracts
+ debug $ "Messages so far: " <> show (length messages)
+ let lastMessage = List.maximumOn (.receivedAt) messages
+ debug $ "Last message: " <> show lastMessage
+ whenSome lastMessage $ \m ->
+ when (m.receiver == p) $ do
+ users <- T.query @User.User
+ debug users
+ let isSender = (\user -> user.username == m.sender)
+ let replyTo = List.head $ filter (\(_, user) -> isSender user) users
+ whenSome replyTo $ \(sender, _) ->
+ T.dedupExercise sender (User.SendMessage p "Please, tell me more about that.")
+ , registeredTemplates = T.AllInDar
+ , heartbeat = None
+ }
diff -Naur create-daml-app/daml/NoOp.daml gsg-trigger/daml/NoOp.daml
--- create-daml-app/daml/NoOp.daml 1970-01-01 01:00:00.000000000 +0100
+++ gsg-trigger/daml/NoOp.daml 2022-01-12 17:55:45.838308273 +0100
@@ -0,0 +1,13 @@
+module NoOp where
+
+import qualified Daml.Trigger as T
+
+noOp : T.Trigger ()
+noOp = T.Trigger with
+ initialize = pure ()
+ updateState = \_ -> pure ()
+ rule = \_ -> do
+ debug "triggered"
+ pure ()
+ registeredTemplates = T.AllInDar
+ heartbeat = None
diff -Naur create-daml-app/daml/User.daml gsg-trigger/daml/User.daml
--- create-daml-app/daml/User.daml 2022-01-12 17:55:49.754285111 +0100
+++ gsg-trigger/daml/User.daml 2022-01-12 17:55:45.838308273 +0100
@@ -6,7 +6,6 @@
-- MAIN_TEMPLATE_BEGIN
template User with
username: Party
- public: Party
following: [Party]
where
signatory username
@@ -26,6 +25,17 @@
archive self
create this with following = userToFollow :: following
-- FOLLOW_END
+ -- SEND_BEGIN
+ -- New definition for SendMessage
+ nonconsuming choice SendMessage: ContractId Message with
+ sender: Party
+ content: Text
+ controller sender
+ do
+ assertMsg "Designated user must follow you back to send a message" (elem sender following)
+ now <- getTime
+ create Message with sender, receiver = username, content, receivedAt = now
+ -- SEND_END
-- ALIAS_BEGIN
template Alias with
@@ -46,3 +56,13 @@
archive self
create this with alias = newAlias
-- ALIAS_END
+
+-- MESSAGE_BEGIN
+template Message with
+ sender: Party
+ receiver: Party
+ content: Text
+ receivedAt: Time
+ where
+ signatory sender, receiver
+-- MESSAGE_END
--- create-daml-app/daml.yaml.template 2022-01-26 17:29:37.149557361 +0100
+++ gsg-trigger/daml.yaml.template 2022-01-26 17:29:27.749276386 +0100
@@ -6,10 +6,12 @@
- Alice
- Bob
- Charlie
+# trigger-dependencies-begin
dependencies:
- daml-prim
- daml-stdlib
- daml-trigger
+# trigger-dependencies-end
start-navigator: false
codegen:
js:
diff -Naur create-daml-app/ui/src/components/MainView.tsx.template gsg-trigger/ui/src/components/MainView.tsx.template
--- create-daml-app/ui/src/components/MainView.tsx.template 2022-01-12 18:39:11.584886272 +0100
+++ gsg-trigger/ui/src/components/MainView.tsx.template 2022-01-12 18:17:12.021819139 +0100
@@ -83,6 +83,15 @@
/>
{/* USERLIST_END */}
</Segment>
+ <Segment>
+ <Header as='h2'>
+ <Icon name='pencil square' />
+ <Header.Content>
+ Messages
+ <Header.Subheader>Send a message to a follower</Header.Subheader>
+ </Header.Content>
+ </Header>
+ </Segment>
</Grid.Column>
</Grid.Row>
</Grid>
diff -Naur create-daml-app/ui/src/components/MessageEdit.tsx.template gsg-trigger/ui/src/components/MessageEdit.tsx.template
--- create-daml-app/ui/src/components/MessageEdit.tsx.template 1970-01-01 01:00:00.000000000 +0100
+++ gsg-trigger/ui/src/components/MessageEdit.tsx.template 2022-01-12 17:55:45.838308273 +0100
@@ -0,0 +1,65 @@
+import React from 'react'
+import { Form, Button } from 'semantic-ui-react';
+import { Party } from '@daml/types';
+import { User } from '@daml.js/__PROJECT_NAME__';
+import { useParty, useLedger } from '@daml/react';
+
+type Props = {
+ followers: Party[];
+}
+
+/**
+ * React component to edit a message to send to a follower.
+ */
+const MessageEdit: React.FC<Props> = ({followers}) => {
+ const sender = useParty();
+ const [receiver, setReceiver] = React.useState<string | undefined>();
+ const [content, setContent] = React.useState("");
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
+ const ledger = useLedger();
+
+ const submitMessage = async (event: React.FormEvent) => {
+ try {
+ event.preventDefault();
+ if (receiver === undefined) {
+ return;
+ }
+ setIsSubmitting(true);
+ await ledger.exerciseByKey(User.User.SendMessage, receiver, {sender, content});
+ setContent("");
+ } catch (error) {
+ alert(`Error sending message:\n${JSON.stringify(error)}`);
+ } finally {
+ setIsSubmitting(false);
+ }
+ };
+
+ return (
+ <Form onSubmit={submitMessage}>
+ <Form.Dropdown
+ selection
+ className='test-select-message-receiver'
+ placeholder="Select a follower"
+ options={followers.map(follower => ({ key: follower, text: follower, value: follower }))}
+ value={receiver}
+ onChange={event => setReceiver(event.currentTarget.textContent ?? undefined)}
+ />
+ <Form.Input
+ className='test-select-message-content'
+ placeholder="Write a message"
+ value={content}
+ onChange={event => setContent(event.currentTarget.value)}
+ />
+ <Button
+ fluid
+ className='test-select-message-send-button'
+ type="submit"
+ disabled={isSubmitting || receiver === undefined || content === ""}
+ loading={isSubmitting}
+ content="Send"
+ />
+ </Form>
+ );
+};
+
+export default MessageEdit;
diff -Naur create-daml-app/ui/src/components/MessageList.tsx.template gsg-trigger/ui/src/components/MessageList.tsx.template
--- create-daml-app/ui/src/components/MessageList.tsx.template 1970-01-01 01:00:00.000000000 +0100
+++ gsg-trigger/ui/src/components/MessageList.tsx.template 2022-01-12 17:55:45.834308296 +0100
@@ -0,0 +1,28 @@
+import React from 'react'
+import { List, ListItem } from 'semantic-ui-react';
+import { User } from '@daml.js/__PROJECT_NAME__';
+import { useStreamQueries } from '@daml/react';
+
+/**
+ * React component displaying the list of messages for the current user.
+ */
+const MessageList: React.FC = () => {
+ const messagesResult = useStreamQueries(User.Message);
+
+ return (
+ <List relaxed>
+ {messagesResult.contracts.map(message => {
+ const {sender, receiver, content} = message.payload;
+ return (
+ <ListItem
+ className='test-select-message-item'
+ key={message.contractId}>
+ <strong>{sender} &rarr; {receiver}:</strong> {content}
+ </ListItem>
+ );
+ })}
+ </List>
+ );
+};
+
+export default MessageList;