Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions api/thirdfort/consumer/tasksteps/type/v1/form.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
syntax = "proto3";

package thirdfort.consumer.tasksteps.type.v1;

message FormTaskStepParams {
// The display name of the form.
string display_name = 1;

// Markdown formatted description providing more context for the form.
string description = 2;

// Defines a specific field in the form.
message FormField {
// Machine-readable name of the field.
string name = 1;

// Human-readable display name of the field.
string display_name = 2;

// Human-readable description of the field.
string description = 3;

// The type of the field.
oneof field_type {
TextField text_field = 4;
}
}
// The fields to display in the form.
repeated FormField fields = 3;

// The text to display on the submit button.
string submit_button_text = 4;
}

// The field is a text input.
message TextField {
// The placeholder text to display in the text input.
string placeholder = 1;

// The maximum length of the text input.
int32 max_length = 2;

// Flag to determine whether the text input is required.
bool required = 3;
}


// The data submitted by the user in response to a form.
message FormTaskStepData {
// Defines a specific field in the form.
repeated FormFieldData fields = 1;

message FormFieldData {
// Name of the field.
string name = 1;

// The value of the field.
string value = 2;
}
}
184 changes: 184 additions & 0 deletions mobile/libs/genproto/thirdfort/consumer/tasksteps/type/v1/form_pb.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
// @generated by protoc-gen-es v2.2.3 with parameter "target=ts"
// @generated from file thirdfort/consumer/tasksteps/type/v1/form.proto (package thirdfort.consumer.tasksteps.type.v1, syntax proto3)
/* eslint-disable */

import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1";
import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1";
import type { Message } from "@bufbuild/protobuf";

/**
* Describes the file thirdfort/consumer/tasksteps/type/v1/form.proto.
*/
export const file_thirdfort_consumer_tasksteps_type_v1_form: GenFile = /*@__PURE__*/
fileDesc("Ci90aGlyZGZvcnQvY29uc3VtZXIvdGFza3N0ZXBzL3R5cGUvdjEvZm9ybS5wcm90bxIkdGhpcmRmb3J0LmNvbnN1bWVyLnRhc2tzdGVwcy50eXBlLnYxIssCChJGb3JtVGFza1N0ZXBQYXJhbXMSFAoMZGlzcGxheV9uYW1lGAEgASgJEhMKC2Rlc2NyaXB0aW9uGAIgASgJElIKBmZpZWxkcxgDIAMoCzJCLnRoaXJkZm9ydC5jb25zdW1lci50YXNrc3RlcHMudHlwZS52MS5Gb3JtVGFza1N0ZXBQYXJhbXMuRm9ybUZpZWxkEhoKEnN1Ym1pdF9idXR0b25fdGV4dBgEIAEoCRqZAQoJRm9ybUZpZWxkEgwKBG5hbWUYASABKAkSFAoMZGlzcGxheV9uYW1lGAIgASgJEhMKC2Rlc2NyaXB0aW9uGAMgASgJEkUKCnRleHRfZmllbGQYBCABKAsyLy50aGlyZGZvcnQuY29uc3VtZXIudGFza3N0ZXBzLnR5cGUudjEuVGV4dEZpZWxkSABCDAoKZmllbGRfdHlwZSJGCglUZXh0RmllbGQSEwoLcGxhY2Vob2xkZXIYASABKAkSEgoKbWF4X2xlbmd0aBgCIAEoBRIQCghyZXF1aXJlZBgDIAEoCCKWAQoQRm9ybVRhc2tTdGVwRGF0YRJUCgZmaWVsZHMYASADKAsyRC50aGlyZGZvcnQuY29uc3VtZXIudGFza3N0ZXBzLnR5cGUudjEuRm9ybVRhc2tTdGVwRGF0YS5Gb3JtRmllbGREYXRhGiwKDUZvcm1GaWVsZERhdGESDAoEbmFtZRgBIAEoCRINCgV2YWx1ZRgCIAEoCULoAgooY29tLnRoaXJkZm9ydC5jb25zdW1lci50YXNrc3RlcHMudHlwZS52MUIJRm9ybVByb3RvUAFafGdpdGh1Yi5jb20vdGhpcmRmb3J0L3RoaXJkZm9ydC1tb2JpbGUtZnVsbHN0YWNrLWNvZGUtcmV2aWV3L3NlcnZlci9saWJzL2dlbnByb3RvL3RoaXJkZm9ydC9jb25zdW1lci90YXNrc3RlcHMvdHlwZS92MTt0eXBldjGiAgRUQ1RUqgIkVGhpcmRmb3J0LkNvbnN1bWVyLlRhc2tzdGVwcy5UeXBlLlYxygIkVGhpcmRmb3J0XENvbnN1bWVyXFRhc2tzdGVwc1xUeXBlXFYx4gIwVGhpcmRmb3J0XENvbnN1bWVyXFRhc2tzdGVwc1xUeXBlXFYxXEdQQk1ldGFkYXRh6gIoVGhpcmRmb3J0OjpDb25zdW1lcjo6VGFza3N0ZXBzOjpUeXBlOjpWMWIGcHJvdG8z");

/**
* @generated from message thirdfort.consumer.tasksteps.type.v1.FormTaskStepParams
*/
export type FormTaskStepParams = Message<"thirdfort.consumer.tasksteps.type.v1.FormTaskStepParams"> & {
/**
* The display name of the form.
*
* @generated from field: string display_name = 1;
*/
displayName: string;

/**
* Markdown formatted description providing more context for the form.
*
* @generated from field: string description = 2;
*/
description: string;

/**
* The fields to display in the form.
*
* @generated from field: repeated thirdfort.consumer.tasksteps.type.v1.FormTaskStepParams.FormField fields = 3;
*/
fields: FormTaskStepParams_FormField[];

/**
* The text to display on the submit button.
*
* @generated from field: string submit_button_text = 4;
*/
submitButtonText: string;
};

/**
* Describes the message thirdfort.consumer.tasksteps.type.v1.FormTaskStepParams.
* Use `create(FormTaskStepParamsSchema)` to create a new message.
*/
export const FormTaskStepParamsSchema: GenMessage<FormTaskStepParams> = /*@__PURE__*/
messageDesc(file_thirdfort_consumer_tasksteps_type_v1_form, 0);

/**
* Defines a specific field in the form.
*
* @generated from message thirdfort.consumer.tasksteps.type.v1.FormTaskStepParams.FormField
*/
export type FormTaskStepParams_FormField = Message<"thirdfort.consumer.tasksteps.type.v1.FormTaskStepParams.FormField"> & {
/**
* Machine-readable name of the field.
*
* @generated from field: string name = 1;
*/
name: string;

/**
* Human-readable display name of the field.
*
* @generated from field: string display_name = 2;
*/
displayName: string;

/**
* Human-readable description of the field.
*
* @generated from field: string description = 3;
*/
description: string;

/**
* The type of the field.
*
* @generated from oneof thirdfort.consumer.tasksteps.type.v1.FormTaskStepParams.FormField.field_type
*/
fieldType: {
/**
* @generated from field: thirdfort.consumer.tasksteps.type.v1.TextField text_field = 4;
*/
value: TextField;
case: "textField";
} | { case: undefined; value?: undefined };
};

/**
* Describes the message thirdfort.consumer.tasksteps.type.v1.FormTaskStepParams.FormField.
* Use `create(FormTaskStepParams_FormFieldSchema)` to create a new message.
*/
export const FormTaskStepParams_FormFieldSchema: GenMessage<FormTaskStepParams_FormField> = /*@__PURE__*/
messageDesc(file_thirdfort_consumer_tasksteps_type_v1_form, 0, 0);

/**
* The field is a text input.
*
* @generated from message thirdfort.consumer.tasksteps.type.v1.TextField
*/
export type TextField = Message<"thirdfort.consumer.tasksteps.type.v1.TextField"> & {
/**
* The placeholder text to display in the text input.
*
* @generated from field: string placeholder = 1;
*/
placeholder: string;

/**
* The maximum length of the text input.
*
* @generated from field: int32 max_length = 2;
*/
maxLength: number;

/**
* Flag to determine whether the text input is required.
*
* @generated from field: bool required = 3;
*/
required: boolean;
};

/**
* Describes the message thirdfort.consumer.tasksteps.type.v1.TextField.
* Use `create(TextFieldSchema)` to create a new message.
*/
export const TextFieldSchema: GenMessage<TextField> = /*@__PURE__*/
messageDesc(file_thirdfort_consumer_tasksteps_type_v1_form, 1);

/**
* The data submitted by the user in response to a form.
*
* @generated from message thirdfort.consumer.tasksteps.type.v1.FormTaskStepData
*/
export type FormTaskStepData = Message<"thirdfort.consumer.tasksteps.type.v1.FormTaskStepData"> & {
/**
* Defines a specific field in the form.
*
* @generated from field: repeated thirdfort.consumer.tasksteps.type.v1.FormTaskStepData.FormFieldData fields = 1;
*/
fields: FormTaskStepData_FormFieldData[];
};

/**
* Describes the message thirdfort.consumer.tasksteps.type.v1.FormTaskStepData.
* Use `create(FormTaskStepDataSchema)` to create a new message.
*/
export const FormTaskStepDataSchema: GenMessage<FormTaskStepData> = /*@__PURE__*/
messageDesc(file_thirdfort_consumer_tasksteps_type_v1_form, 2);

/**
* @generated from message thirdfort.consumer.tasksteps.type.v1.FormTaskStepData.FormFieldData
*/
export type FormTaskStepData_FormFieldData = Message<"thirdfort.consumer.tasksteps.type.v1.FormTaskStepData.FormFieldData"> & {
/**
* Name of the field.
*
* @generated from field: string name = 1;
*/
name: string;

/**
* The value of the field.
*
* @generated from field: string value = 2;
*/
value: string;
};

/**
* Describes the message thirdfort.consumer.tasksteps.type.v1.FormTaskStepData.FormFieldData.
* Use `create(FormTaskStepData_FormFieldDataSchema)` to create a new message.
*/
export const FormTaskStepData_FormFieldDataSchema: GenMessage<FormTaskStepData_FormFieldData> = /*@__PURE__*/
messageDesc(file_thirdfort_consumer_tasksteps_type_v1_form, 2, 0);

92 changes: 92 additions & 0 deletions mobile/src/components/FormField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { useState } from 'react';
import { View, Text, StyleSheet, TextInput, Platform } from 'react-native';

import { FormTaskStepParams_FormField} from '../../libs/genproto/thirdfort/consumer/tasksteps/type/v1/form_pb';

import { typography, scheme } from '../styles/values';

type FormFieldProps = {
params: FormTaskStepParams_FormField
}

export function FormField({params}: FormFieldProps) {

if (!params.fieldType || !params.fieldType.case) return null;

const [isFocused, setIsFocused] = useState<boolean>(false);

switch (params.fieldType.case) {
case 'textField':
return (
<View style={styles.container}>
<Text style={styles.label}>
{params.displayName}
</Text>

<TextInput
style={[
styles.input,
isFocused && styles.inputSelected,
]}
placeholder={params.description}
/>
</View>
);
default:
return null;
}
};

const styles = StyleSheet.create({
container: {
display: 'flex',
flex: 1,
flexDirection: 'column',
},
label: {
color: '#333',
position: 'absolute',
left: 10,
backgroundColor: scheme.background1,
paddingHorizontal: 5,
paddingVertical: 3,
height: 22,
zIndex: 9,
},
inputSelected: {
borderColor: scheme.secondary,
borderWidth: 2,
},
input: {
height: 70,
borderColor: '#ccc',
backgroundColor: '#fff',
borderWidth: 1,
borderRadius: 4,
fontSize: 16,
width: '100%',
paddingHorizontal: 20,
color: scheme.bodyPanel,
zIndex: 1,
elevation: 0,
},
inputError: {
borderColor: scheme.error,
},
iconError: {
position: 'absolute',
right: 20,
top: 45,
zIndex: 999,
},
requireField: {
alignContent: 'flex-end',
textAlign: 'right',
height: 25,
},
requiredText: {
...typography.smallRegular,
fontSize: 12,
textAlign: 'right',
},
});
Loading