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

CSCfi / metadata-submitter-frontend / 20331691855

18 Dec 2025 09:07AM UTC coverage: 55.065% (-3.3%) from 58.346%
20331691855

push

github

Hang Le
Update dependency @vitest/coverage-v8 to v4 (merge commit)

Merge branch 'renovate/vitest-coverage-v8-4.x' into 'main'
* Update dependency @vitest/coverage-v8 to v4

See merge request https://gitlab.ci.csc.fi/sds-dev/sd-submit/metadata-submitter-frontend/-/merge_requests/1182

Approved-by: Liisa Lado-Villar <145-lilado@users.noreply.gitlab.ci.csc.fi>
Co-authored-by: renovate-bot <group_183_bot_aa67d732ac40e4c253df6728543b928a@noreply.gitlab.ci.csc.fi>
Merged by Hang Le <lhang@csc.fi>

476 of 1055 branches covered (45.12%)

Branch coverage included in aggregate %.

1307 of 2183 relevant lines covered (59.87%)

8.04 hits per line

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

46.43
/src/components/SubmissionWizard/WizardSteps/WizardCreateSubmissionStep.tsx
1
/* Workflows are disabled for MVP */
2
import React, { useEffect, useState } from "react"
3

4
import {
5
  Button,
6
  CardContent,
7
  // FormControl,
8
  // FormControlLabel,
9
  // FormLabel,
10
  // FormHelperText,
11
  // Grid,
12
  // Radio,
13
  // RadioGroup,
14
  TextField,
15
  Typography,
16
} from "@mui/material"
17
import { styled } from "@mui/system"
18
import { useForm, Controller } from "react-hook-form"
19
import { useTranslation } from "react-i18next"
20

21
import WizardStepContentHeader from "../WizardComponents/WizardStepContentHeader"
22

23
import checkUnsavedInputHook from "components/SubmissionWizard/WizardHooks/WizardCheckUnsavedInputHook"
24
import { ResponseStatus } from "constants/responseStatus"
25
import { ExtraObjectTypes } from "constants/wizardObject"
26
import { WorkflowTypes } from "constants/wizardWorkflow"
27
import { updateStatus } from "features/statusMessageSlice"
28
import { resetUnsavedForm } from "features/unsavedFormSlice"
29
import { setObjectType } from "features/wizardObjectTypeSlice"
30
import { createSubmission, updateSubmission } from "features/wizardSubmissionSlice"
31
import { setWorkflowType } from "features/workflowTypeSlice"
32
import { useAppSelector, useAppDispatch } from "hooks"
33
import type { SubmissionDataFromForm } from "types"
34

35
const Form = styled("form")(({ theme }) => ({
5✔
36
  "& .MuiCardContent-root": { padding: "4rem" },
37
  "& .MuiTextField-root": {
38
    margin: "1rem 0",
39
  },
40
  "&  .MuiFormHelperText-root": {
41
    color: theme.palette.secondary.main,
42
    fontSize: "1rem",
43
  },
44
}))
45

46
/**
47
 * Define React Hook Form for adding new submission. Ref is added to RHF so submission can be triggered outside this component.
48
 */
49
const CreateSubmissionForm = () => {
5✔
50
  const dispatch = useAppDispatch()
3✔
51
  const projectId = useAppSelector(state => state.projectId)
6✔
52
  const submission = useAppSelector(state => state.submission)
6✔
53

54
  const { t } = useTranslation()
3✔
55

56
  // Temporary disable workflow selection and use SD only
57
  const [selectedWorkflowType] = useState(WorkflowTypes.sd)
3✔
58

59
  useEffect(() => {
3✔
60
    if (submission?.name && submission?.title && submission?.description) {
1!
61
      // set default form values
62
      reset({
1✔
63
        name: submission.name,
64
        title: submission.title,
65
        description: submission.description,
66
      })
67
    }
68
  }, [submission])
69

70
  const {
71
    handleSubmit,
72
    control,
73
    reset,
74
    getValues,
75
    formState: { isSubmitting, dirtyFields, defaultValues },
76
  } = useForm()
3✔
77

78
  const onSubmit = async (data: SubmissionDataFromForm) => {
3✔
79
    if (selectedWorkflowType === "") {
×
80
      return
×
81
    }
82

83
    if (submission && submission?.submissionId) {
×
84
      dispatch(updateSubmission(Object.assign({ ...data, submission })))
×
85
        .then(() => {
86
          reset(data, { keepValues: true }) // reset form state
×
87
          dispatch(resetUnsavedForm())
×
88
          dispatch(
×
89
            updateStatus({
90
              status: ResponseStatus.success,
91
              helperText: "snackbarMessages.success.submission.updated",
92
            })
93
          )
94
        })
95
        .catch((error: string) => {
96
          dispatch(updateStatus({ status: ResponseStatus.error, response: JSON.parse(error) }))
×
97
        })
98
    } else {
99
      // Create a new submission
100
      // dispatch(setWorkflowType(data.workflowType))
101
      dispatch(setWorkflowType(WorkflowTypes.sd))
×
102
      dispatch(setObjectType(ExtraObjectTypes.submissionDetails))
×
103
      dispatch(createSubmission(projectId, data))
×
104
        .then(() => {
105
          // RHF does not reset form state after submit
106
          reset(data, { keepValues: true })
×
107
          dispatch(resetUnsavedForm())
×
108
          dispatch(
×
109
            updateStatus({
110
              status: ResponseStatus.success,
111
              helperText: "snackbarMessages.success.submission.created",
112
            })
113
          )
114
        })
115
        .catch((error: string) => {
116
          dispatch(updateStatus({ status: ResponseStatus.error, response: JSON.parse(error) }))
×
117
        })
118
    }
119
  }
120

121
  // Temporary disable workflow selection and use SD only
122
  // const workflowType = useAppSelector(state => state.workflowType)
123
  // const [selectedWorkflowType, setSelectedWorkflowType] = useState(workflowType)
124

125
  const SaveButton = (
126
    <Button
3✔
127
      disabled={isSubmitting}
128
      size="small"
129
      variant="contained"
130
      type="submit"
131
      aria-label={t("ariaLabels.saveDetails")}
132
      data-testid="form-ready"
133
    >
134
      {t("save")}
135
    </Button>
136
  )
137

138
  return (
3✔
139
    <Form
140
      onSubmit={handleSubmit(async data => onSubmit(data as SubmissionDataFromForm))}
×
141
      onBlur={() => checkUnsavedInputHook(dirtyFields, defaultValues, getValues, dispatch)}
×
142
    >
143
      <WizardStepContentHeader action={SaveButton} />
144
      <CardContent>
145
        <Typography variant="h4" gutterBottom component="div" color="secondary" fontWeight="700">
146
          {t("newSubmission.nameSubmission")}
147
        </Typography>
148
        <Controller
149
          control={control}
150
          name="name"
151
          defaultValue={""}
152
          render={({ field, fieldState: { error } }) => (
153
            <TextField
3✔
154
              {...field}
155
              label={`${t("newSubmission.datasetName")}*`}
156
              variant="outlined"
157
              fullWidth
158
              error={!!error}
159
              helperText={
160
                error
3!
161
                  ? t("newSubmission.errors.missingName")
162
                  : t("newSubmission.helpers.datasetName")
163
              }
164
              disabled={isSubmitting}
165
              slotProps={{ htmlInput: { "data-testid": "submissionName" } }}
166
            />
167
          )}
168
          rules={{ required: true, validate: { name: value => value.length > 0 } }}
×
169
        />
170
        <Controller
171
          control={control}
172
          name="title"
173
          defaultValue={""}
174
          render={({ field, fieldState: { error } }) => (
175
            <TextField
3✔
176
              {...field}
177
              label={`${t("newSubmission.datasetTitle")}*`}
178
              variant="outlined"
179
              fullWidth
180
              error={!!error}
181
              helperText={
182
                error
3!
183
                  ? t("newSubmission.errors.missingTitle")
184
                  : t("newSubmission.helpers.datasetTitle")
185
              }
186
              disabled={isSubmitting}
187
              slotProps={{ htmlInput: { "data-testid": "datasetTitle" } }}
188
            />
189
          )}
190
          rules={{ required: true, validate: { title: value => value.length > 0 } }}
×
191
        />
192
        <Controller
193
          control={control}
194
          name="description"
195
          defaultValue={""}
196
          render={({ field, fieldState: { error } }) => (
197
            <TextField
3✔
198
              {...field}
199
              label={`${t("newSubmission.datasetDescription")}*`}
200
              variant="outlined"
201
              fullWidth
202
              multiline
203
              rows={5}
204
              error={!!error}
205
              helperText={
206
                error
3!
207
                  ? t("newSubmission.errors.missingDescription")
208
                  : t("newSubmission.helpers.datasetDescription")
209
              }
210
              disabled={isSubmitting}
211
              slotProps={{ htmlInput: { "data-testid": "submissionDescription" } }}
212
            />
213
          )}
214
          rules={{ required: true, validate: { description: value => value.length > 0 } }}
×
215
        />
216

217
        {/* Temporary disable workflow selection and use SD only */}
218
        <Controller
219
          control={control}
220
          name="workflowType"
221
          defaultValue={selectedWorkflowType}
222
          data-testid={WorkflowTypes.sd}
223
          render={() => <input id="hiddenWorkflow" type="hidden" name="workflowType" />}
3✔
224
        />
225
        {/* <Grid sx={{ mt: 2 }} container spacing={2}>
226
        <Grid>
227
          <FormLabel
228
            id="submission-type-selection-label"
229
            required
230
            error={selectedWorkflowType === "" && isSubmitted}
231
            sx={theme => ({
232
              background: theme.palette.background.default,
233
              borderRadius: theme.spacing(0.4),
234
              height: "100%",
235
              display: "flex",
236
              alignItems: "center",
237
              padding: theme.spacing(0, 3, 0, 1.5),
238
              fontWeight: 600,
239
              color: theme.palette.secondary.main,
240
            })}
241
          >
242
            {t("newSubmission.typeOfSubmission")}
243
          </FormLabel>
244
        </Grid>
245
        <Grid size={{ xs: 6 }}>
246
          <FormControl>
247
            <Controller
248
              control={control}
249
              name="workflowType"
250
              defaultValue={selectedWorkflowType}
251
              render={({ field }) => {
252
                const handleChangeWorkflow = (e: React.ChangeEvent<HTMLInputElement>) => {
253
                  field.onChange(e.target.value)
254
                  setSelectedWorkflowType(e.target.value)
255
                }
256

257
                return (
258
                  <RadioGroup
259
                    {...field}
260
                    name="submission-type-selection"
261
                    aria-labelledby="submission-type-selection-label"
262
                    onChange={handleChangeWorkflow}
263
                  >
264
                    {workflows.map(workflow => (
265
                      <FormControlLabel
266
                        key={workflow}
267
                        value={workflow}
268
                        control={<Radio />}
269
                        label={workflow}
270
                        data-testid={workflow}
271
                        disabled={submission.submissionId !== ""}
272
                      />
273
                    ))}
274
                  </RadioGroup>
275
                )
276
              }}
277
            />
278
            {selectedWorkflowType === "" && isSubmitted && (
279
              <FormHelperText error data-testid="missing-workflow-error">
280
                {t("newSubmission.errors.missingWorkflow")}
281
              </FormHelperText>
282
            )}
283
          </FormControl>
284
        </Grid>
285
        </Grid> */}
286
      </CardContent>
287
    </Form>
288
  )
289
}
290

291
/*
292
 * Show form to create submission as first step of new submission wizard
293
 */
294

295
const WizardCreateSubmissionStep = () => <CreateSubmissionForm />
5✔
296

297
export default WizardCreateSubmissionStep
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

© 2026 Coveralls, Inc