diff --git a/src/framework/processing/py/port/api/props.py b/src/framework/processing/py/port/api/props.py index 77dfef4e..5b20b020 100644 --- a/src/framework/processing/py/port/api/props.py +++ b/src/framework/processing/py/port/api/props.py @@ -114,10 +114,12 @@ class PropsUIPromptConsentForm: """Tables to be shown to the participant prior to donation Attributes: + id: A unique string to identify the table after donation. tables: a list of tables meta_tables: a list of optional tables, for example for logging data """ + id: str tables: list[PropsUIPromptConsentFormTable] meta_tables: list[PropsUIPromptConsentFormTable] description: Optional[Translatable] = None @@ -139,6 +141,7 @@ def translate_meta_tables(self): def toDict(self): dict = {} dict["__type__"] = "PropsUIPromptConsentForm" + dict["id"] = self.id dict["tables"] = self.translate_tables() dict["metaTables"] = self.translate_meta_tables() dict["description"] = self.description and self.description.toDict() diff --git a/src/framework/processing/py/port/script.py b/src/framework/processing/py/port/script.py index 776db282..1a971ae5 100644 --- a/src/framework/processing/py/port/script.py +++ b/src/framework/processing/py/port/script.py @@ -52,11 +52,8 @@ def process(sessionId): # STEP 2: ask for consent meta_data.append(("debug", f"{key}: prompt consent")) - prompt = prompt_consent(data, meta_data) + prompt = prompt_consent(f"{sessionId}-{key}", data, meta_data) consent_result = yield render_donation_page(prompt) - if consent_result.__type__ == "PayloadJSON": - meta_data.append(("debug", f"{key}: donate consent data")) - yield donate(f"{sessionId}-{key}", consent_result.value) if consent_result.__type__ == "PayloadFalse": value = json.dumps('{"status" : "donation declined"}') yield donate(f"{sessionId}-{key}", value) @@ -135,7 +132,7 @@ def extract_file(zipfile_ref, filename): return "invalid" -def prompt_consent(data, meta_data): +def prompt_consent(id, data, meta_data): table_title = props.Translatable({ "en": "Zip file contents", @@ -156,7 +153,7 @@ def prompt_consent(data, meta_data): meta_frame = pd.DataFrame(meta_data, columns=["type", "message"]) meta_table = props.PropsUIPromptConsentFormTable("log_messages", log_title, meta_frame) - return props.PropsUIPromptConsentForm(tables, [meta_table]) + return props.PropsUIPromptConsentForm(id, tables, [meta_table]) def donate(key, json_string): diff --git a/src/framework/processing/worker_engine.ts b/src/framework/processing/worker_engine.ts index 9d4d6a99..dcfb5b74 100755 --- a/src/framework/processing/worker_engine.ts +++ b/src/framework/processing/worker_engine.ts @@ -1,5 +1,5 @@ import { CommandHandler, ProcessingEngine } from '../types/modules' -import { CommandSystemEvent, isCommand, Response } from '../types/commands' +import { CommandSystemEvent, CommandSystemDonate, isCommand, Response, PayloadDonate } from '../types/commands' export default class WorkerProcessingEngine implements ProcessingEngine { sessionId: String @@ -88,9 +88,32 @@ export default class WorkerProcessingEngine implements ProcessingEngine { handleRunCycle (command: any): void { if (isCommand(command)) { this.commandHandler.onCommand(command).then( - (response) => this.nextRunCycle(response), + (response) => { + switch(response.payload.__type__) { + case "PayloadDonate": + const donateCommand = constructDonateCommand(response.payload) + this.commandHandler.onCommand(donateCommand).then( + (response) => { + this.nextRunCycle(response) + } + ) + break + + default: + this.nextRunCycle(response) + } + }, () => {} ) } } } + +function constructDonateCommand(payload: PayloadDonate) { + const donateCommand: CommandSystemDonate = { + "__type__": "CommandSystemDonate", + "key": payload.key, + "json_string": payload.value, + } + return donateCommand +} diff --git a/src/framework/types/commands.ts b/src/framework/types/commands.ts index c2b7ae26..19b015ea 100644 --- a/src/framework/types/commands.ts +++ b/src/framework/types/commands.ts @@ -43,7 +43,8 @@ export type PayloadResolved = PayloadTrue | PayloadString | PayloadFile | - PayloadJSON + PayloadJSON | + PayloadDonate export interface PayloadVoid { __type__: 'PayloadVoid' @@ -73,6 +74,12 @@ export function isPayloadJSON (arg: any): arg is PayloadJSON { return isInstanceOf(arg, 'PayloadJSON', ['value']) } +export interface PayloadDonate { + __type__: 'PayloadDonate' + value: string + key: string +} + export type Command = CommandUI | CommandSystem diff --git a/src/framework/types/prompts.ts b/src/framework/types/prompts.ts index a8a1fdc4..ccd5ab7d 100644 --- a/src/framework/types/prompts.ts +++ b/src/framework/types/prompts.ts @@ -57,11 +57,12 @@ export interface PropsUIPromptConsentForm { description?: Text donateQuestion?: Text donateButton?: Text + id: string tables: PropsUIPromptConsentFormTable[] metaTables: PropsUIPromptConsentFormTable[] } export function isPropsUIPromptConsentForm (arg: any): arg is PropsUIPromptConsentForm { - return isInstanceOf(arg, 'PropsUIPromptConsentForm', ['tables', 'metaTables']) + return isInstanceOf(arg, 'PropsUIPromptConsentForm', ['id', 'tables', 'metaTables']) } export interface PropsUIPromptConsentFormTable { diff --git a/src/framework/visualisation/react/ui/prompts/consent_form.tsx b/src/framework/visualisation/react/ui/prompts/consent_form.tsx index 6aee8597..224fb915 100644 --- a/src/framework/visualisation/react/ui/prompts/consent_form.tsx +++ b/src/framework/visualisation/react/ui/prompts/consent_form.tsx @@ -23,7 +23,7 @@ export const ConsentForm = (props: Props): JSX.Element => { const tablesOut = React.useRef>(tablesIn.current) const [waiting, setWaiting] = React.useState(false) - const { locale, resolve } = props + const { locale, resolve, id } = props const cancelButton = Translator.translate(cancelButtonLabel, props.locale) function rowCell (dataFrame: any, column: string, row: number): PropsUITableCell { @@ -104,7 +104,7 @@ export const ConsentForm = (props: Props): JSX.Element => { function handleDonate (): void { setWaiting(true) const value = serializeConsentData() - resolve?.({ __type__: 'PayloadJSON', value }) + resolve?.({ __type__: 'PayloadDonate', "value": value, "key": id }) } function handleCancel (): void {