DiscussionPostForm.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import React from 'react';
  2. import { Form, Field, withFormik, FormikProps } from 'formik';
  3. import * as Yup from 'yup';
  4. import TxButton from '@polkadot/joy-utils/react/components/TxButton';
  5. import * as JoyForms from '@polkadot/joy-utils/react/components/forms';
  6. import { SubmittableResult } from '@polkadot/api';
  7. import { Button } from 'semantic-ui-react';
  8. import { TxFailedCallback, TxCallback } from '@polkadot/react-components/Status/types';
  9. import { ParsedPost, DiscussionContraints } from '@polkadot/joy-utils/types/proposals';
  10. import { ThreadId } from '@joystream/types/common';
  11. import { MemberId } from '@joystream/types/members';
  12. type OuterProps = {
  13. post?: ParsedPost;
  14. threadId: ThreadId;
  15. memberId: MemberId;
  16. onSuccess: () => void;
  17. constraints: DiscussionContraints;
  18. };
  19. type FormValues = {
  20. text: string;
  21. };
  22. type InnerProps = OuterProps & FormikProps<FormValues>;
  23. const LabelledField = JoyForms.LabelledField<FormValues>();
  24. const DiscussionPostFormInner = (props: InnerProps) => {
  25. const {
  26. isValid,
  27. isSubmitting,
  28. setSubmitting,
  29. resetForm,
  30. values,
  31. post,
  32. memberId,
  33. threadId,
  34. onSuccess
  35. } = props;
  36. const isEditForm = post && post.postId;
  37. const onSubmit = (sendTx: () => void) => {
  38. if (isValid) sendTx();
  39. };
  40. const onTxFailed: TxFailedCallback = (txResult: SubmittableResult | null) => {
  41. setSubmitting(false);
  42. };
  43. const onTxSuccess: TxCallback = (_txResult: SubmittableResult) => {
  44. setSubmitting(false);
  45. resetForm();
  46. onSuccess();
  47. };
  48. const buildTxParams = () => {
  49. if (!isValid) return [];
  50. if (isEditForm) {
  51. return [
  52. memberId,
  53. threadId,
  54. post?.postId,
  55. values.text
  56. ];
  57. }
  58. return [
  59. memberId,
  60. threadId,
  61. values.text
  62. ];
  63. };
  64. return (
  65. <Form className="ui form JoyForm">
  66. <LabelledField name='text' {...props}>
  67. <Field
  68. component='textarea'
  69. id='text'
  70. name='text'
  71. disabled={isSubmitting}
  72. rows={5}
  73. placeholder='Content of the post...' />
  74. </LabelledField>
  75. <LabelledField invisibleLabel {...props}>
  76. <TxButton
  77. type="submit"
  78. label={isEditForm ? 'Update' : 'Add Post'}
  79. isDisabled={isSubmitting || !isValid}
  80. params={buildTxParams()}
  81. tx={isEditForm ? 'proposalsDiscussion.updatePost' : 'proposalsDiscussion.addPost'}
  82. onClick={onSubmit}
  83. txFailedCb={onTxFailed}
  84. txSuccessCb={onTxSuccess}
  85. />
  86. { isEditForm ? (
  87. <Button
  88. type="button"
  89. size="large"
  90. disabled={isSubmitting}
  91. color="red"
  92. onClick={() => onSuccess()}
  93. content="Cancel"
  94. />
  95. ) : (
  96. <Button
  97. type="button"
  98. size="large"
  99. disabled={isSubmitting}
  100. onClick={() => resetForm()}
  101. content="Clear"
  102. />
  103. ) }
  104. </LabelledField>
  105. </Form>
  106. );
  107. };
  108. const DiscussionPostFormOuter = withFormik<OuterProps, FormValues>({
  109. // Transform outer props into form values
  110. mapPropsToValues: props => {
  111. const { post } = props;
  112. return { text: post && post.postId ? post.text : '' };
  113. },
  114. validationSchema: ({ constraints: c }: OuterProps) => (Yup.object().shape({
  115. text: Yup
  116. .string()
  117. .required('Post content is required')
  118. .max(c.maxPostLength, `The content cannot be longer than ${c.maxPostLength} characters`)
  119. })),
  120. handleSubmit: values => {
  121. // do submitting things
  122. }
  123. })(DiscussionPostFormInner);
  124. export default DiscussionPostFormOuter;