• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

alkem-io / client-web / #9729

03 Jan 2025 09:34AM UTC coverage: 5.783%. First build
#9729

Pull #7381

travis-ci

Pull Request #7381: WIP: Knowledge base BoK instead of Subspace in Written Knowledge creation

190 of 10858 branches covered (1.75%)

Branch coverage included in aggregate %.

0 of 91 new or added lines in 4 files covered. (0.0%)

1523 of 18763 relevant lines covered (8.12%)

0.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/main/topLevelPages/myDashboard/newVirtualContributorWizard/AddContent/AddContentForm.tsx
1
import { Formik } from 'formik';
2
import { useTranslation } from 'react-i18next';
3
import { pullAt } from 'lodash';
4
import * as yup from 'yup';
5
import { Box, Button, Tooltip } from '@mui/material';
6
import LibraryBooksOutlined from '@mui/icons-material/LibraryBooksOutlined';
7
import AttachmentOutlinedIcon from '@mui/icons-material/AttachmentOutlined';
8
import { gutters } from '@/core/ui/grid/utils';
9
import { LONG_MARKDOWN_TEXT_LENGTH, MID_TEXT_LENGTH, SMALL_TEXT_LENGTH } from '@/core/ui/forms/field-length.constants';
10
import { Actions } from '@/core/ui/actions/Actions';
11
import { TranslatedValidatedMessageWithPayload } from '@/domain/shared/i18n/ValidationMessageTranslation';
12
import MarkdownValidator from '@/core/ui/forms/MarkdownInput/MarkdownValidator';
13
import { BoKCalloutsFormValues } from './AddContentProps';
14
import { PostItem } from './PostItem';
15
import { DocumentItem } from '@/main/topLevelPages/myDashboard/newVirtualContributorWizard/AddContent/DocumentItem';
16
import useLoadingState from '@/domain/shared/utils/useLoadingState';
17

18
const MAX_POSTS = 25;
19

20
const newPost = () => ({
×
21
  title: '',
22
  description: '',
×
23
});
24

25
const newDocument = () => ({
26
  name: '',
27
  url: '',
×
28
});
29

30
export const AddContentForm = ({
31
  onSubmit,
32
  onCancel,
×
33
}: {
34
  onCancel: () => void;
35
  onSubmit: (values: BoKCalloutsFormValues) => Promise<void>;
36
}) => {
37
  const { t } = useTranslation();
38

39
  const [handleSubmit, isSubmitting] = useLoadingState(onSubmit);
×
40

NEW
41
  const validationSchema = yup.object().shape({
×
42
    posts: yup
43
      .array()
×
44
      .of(
45
        yup.object().shape({
46
          title: yup
47
            .string()
48
            .min(3, ({ min }) => TranslatedValidatedMessageWithPayload('forms.validations.minLength')({ min }))
49
            .max(SMALL_TEXT_LENGTH, ({ max }) =>
50
              TranslatedValidatedMessageWithPayload('forms.validations.maxLength')({ max })
51
            )
52
            .required(TranslatedValidatedMessageWithPayload('forms.validations.requiredField')),
53
          description: MarkdownValidator(LONG_MARKDOWN_TEXT_LENGTH),
54
        })
55
      )
56
      .min(1, ({ min }) => TranslatedValidatedMessageWithPayload('forms.validations.minLength')({ min })),
57
    documents: yup.array().of(
58
      yup.object().shape({
59
        name: yup
60
          .string()
61
          .min(3, ({ min }) => TranslatedValidatedMessageWithPayload('forms.validations.minLength')({ min }))
62
          .max(SMALL_TEXT_LENGTH, ({ max }) =>
63
            TranslatedValidatedMessageWithPayload('forms.validations.maxLength')({ max })
64
          )
65
          .required(TranslatedValidatedMessageWithPayload('forms.validations.requiredField')),
66
        url: yup
67
          .string()
68
          .required(TranslatedValidatedMessageWithPayload('forms.validations.requiredField'))
69
          .max(MID_TEXT_LENGTH, ({ max }) =>
70
            TranslatedValidatedMessageWithPayload('forms.validations.maxLength')({ max })
71
          ),
72
      })
×
73
    ),
74
  });
75

76
  const initialValues: BoKCalloutsFormValues = {
77
    posts: [
78
      {
79
        title: t('createVirtualContributorWizard.addContent.post.exampleTitle'),
80
        description: t('createVirtualContributorWizard.addContent.post.exampleDescription'),
81
      },
82
    ],
83
    documents: [],
84
  };
85

86
  return (
87
    <Formik initialValues={initialValues} validationSchema={validationSchema} onSubmit={handleSubmit} validateOnMount>
×
88
      {({ values: { posts, documents }, isValid, setFieldValue, submitForm }) => {
89
        const moreThanOnePost = posts.length > 1;
90
        const maxPostsReached = posts.length >= MAX_POSTS;
×
91

×
92
        const handleAddPost = () => {
93
          const newArray = [...posts, newPost()];
×
94
          setFieldValue('posts', newArray);
×
95
        };
×
96
        const handleDeletePost = (index: number) => {
97
          const nextPosts = [...posts];
×
98
          pullAt(nextPosts, index);
×
99
          setFieldValue('posts', nextPosts);
×
100
        };
×
101
        const handleAddDocument = () => {
102
          const newArrayDocuments = [...documents, newDocument()];
×
103
          setFieldValue('documents', newArrayDocuments);
×
104
        };
×
105
        const handleDeleteDocument = (index: number) => {
106
          const nextDocuments = [...documents];
×
107
          pullAt(nextDocuments, index);
×
108
          setFieldValue('documents', nextDocuments);
×
109
        };
×
110

111
        return (
112
          <>
×
113
            {posts.map((post, index) => (
114
              <PostItem key={index} post={post} index={index} onDelete={handleDeletePost} hasDelete={moreThanOnePost} />
115
            ))}
×
116

117
            <Tooltip
118
              title={
119
                maxPostsReached
120
                  ? t('createVirtualContributorWizard.addContent.post.tooltip')
×
121
                  : t('createVirtualContributorWizard.addContent.post.addAnotherPost')
122
              }
123
              placement="bottom-start"
124
            >
125
              <Box>
126
                <Button
127
                  color="primary"
128
                  variant="outlined"
129
                  startIcon={<LibraryBooksOutlined />}
130
                  disabled={maxPostsReached}
131
                  onClick={() => handleAddPost()}
132
                >
×
133
                  {t('createVirtualContributorWizard.addContent.post.addAnotherPost')}
134
                </Button>
135
              </Box>
136
            </Tooltip>
137

138
            {documents?.map((document, index) => (
139
              <DocumentItem
140
                key={index}
141
                document={document}
142
                index={index}
143
                onDelete={handleDeleteDocument}
144
                onChange={fileName => setFieldValue(`documents[${index}].name`, fileName)}
145
              />
146
            ))}
147
            <Tooltip title={t('createVirtualContributorWizard.addContent.documents.addAnother')} placement={'bottom'}>
148
              <Box>
149
                <Button
150
                  color="primary"
151
                  variant="outlined"
152
                  startIcon={<AttachmentOutlinedIcon />}
153
                  onClick={handleAddDocument}
154
                >
155
                  {t('createVirtualContributorWizard.addContent.documents.addAnother')}
156
                </Button>
157
              </Box>
×
158
            </Tooltip>
159

160
            <Box
161
              sx={{
162
                position: 'absolute',
×
163
                bottom: 0,
164
                right: 0,
165
                zIndex: 1400,
166
                width: '100%',
167
                padding: gutters(),
168
                paddingTop: gutters(0.5),
169
                backgroundColor: 'background.paper',
170
              }}
171
            >
172
              <Actions justifyContent="flex-end">
173
                <Button variant="text" onClick={onCancel}>
174
                  {t('buttons.cancel')}
175
                </Button>
176
                <Tooltip
177
                  title={
178
                    Boolean(posts.length) ? undefined : t('createVirtualContributorWizard.addContent.submitDisabled')
179
                  }
180
                  placement={'bottom-start'}
181
                >
182
                  <span>
183
                    <Button variant="contained" loading={isSubmitting} disabled={!isValid} onClick={() => submitForm()}>
184
                      {t('buttons.continue')}
185
                    </Button>
186
                  </span>
187
                </Tooltip>
188
              </Actions>
189
            </Box>
190
          </>
191
        );
×
192
      }}
193
    </Formik>
194
  );
195
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc