@wger-project/react-components 25.10.16 → 25.11.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/build/chunks/{browser-ponyfill-DL_vVusK.js → browser-ponyfill-CyEkMYuR.js} +3 -3
- package/build/chunks/{browser-ponyfill-DL_vVusK.js.map → browser-ponyfill-CyEkMYuR.js.map} +1 -1
- package/build/locales/de/translation.json +334 -334
- package/build/locales/en/translation.json +12 -2
- package/build/locales/fil/translation.json +3 -0
- package/build/locales/fr/translation.json +347 -337
- package/build/locales/hr/translation.json +344 -244
- package/build/locales/it/translation.json +333 -333
- package/build/locales/ko/translation.json +327 -327
- package/build/locales/pt_PT/translation.json +330 -330
- package/build/locales/sk/translation.json +26 -1
- package/build/locales/sl/translation.json +321 -321
- package/build/locales/ta/translation.json +325 -325
- package/build/locales/uk/translation.json +344 -334
- package/build/locales/zh_Hans/translation.json +332 -332
- package/build/main.js +137 -236
- package/build/main.js.map +1 -1
- package/package.json +13 -13
- package/src/components/BodyWeight/Form/WeightForm.tsx +3 -4
- package/src/components/BodyWeight/WeightChart/index.tsx +26 -29
- package/src/components/Exercises/Detail/Head/ExerciseDeleteDialog.tsx +3 -4
- package/src/components/Exercises/ExerciseOverview.tsx +4 -4
- package/src/components/Exercises/Filter/NameAutcompleter.tsx +41 -39
- package/src/components/Exercises/Filter/NameAutocompleter.test.tsx +2 -1
- package/src/components/Measurements/Screens/MeasurementCategoryDetail.test.tsx +4 -2
- package/src/components/Measurements/widgets/MeasurementChart.tsx +27 -30
- package/src/components/Nutrition/components/BmiCalculator.tsx +40 -42
- package/src/components/Nutrition/widgets/IngredientAutcompleter.tsx +1 -1
- package/src/components/Nutrition/widgets/charts/MacrosPieChart.tsx +17 -19
- package/src/components/Nutrition/widgets/charts/NutritionDiaryChart.tsx +39 -38
- package/src/components/Nutrition/widgets/charts/NutritionalValuesDashboardChart.tsx +27 -29
- package/src/components/Nutrition/widgets/charts/NutritionalValuesPlannedLoggedChart.tsx +20 -19
- package/src/components/Nutrition/widgets/forms/NutritionDiaryEntryForm.tsx +15 -4
- package/src/components/WorkoutRoutines/Detail/RoutineDetailsTable.tsx +3 -3
- package/src/components/WorkoutRoutines/Detail/WorkoutStats.tsx +17 -19
- package/src/components/WorkoutRoutines/models/Day.ts +16 -6
- package/src/components/WorkoutRoutines/models/SlotEntry.ts +7 -2
- package/src/components/WorkoutRoutines/widgets/DayDetails.tsx +4 -4
- package/src/components/WorkoutRoutines/widgets/LogWidgets.tsx +35 -38
- package/src/components/WorkoutRoutines/widgets/RoutineDetailsCard.tsx +8 -11
- package/src/components/WorkoutRoutines/widgets/SlotDetails.tsx +4 -4
- package/src/components/WorkoutRoutines/widgets/forms/DayForm.tsx +21 -9
- package/src/components/WorkoutRoutines/widgets/forms/DayTypeSelect.tsx +66 -0
- package/src/components/WorkoutRoutines/widgets/forms/SessionForm.test.tsx +0 -2
- package/src/components/WorkoutRoutines/widgets/forms/SessionLogsForm.tsx +4 -4
- package/src/components/WorkoutRoutines/widgets/forms/SlotEntryForm.test.tsx +12 -10
- package/src/components/WorkoutRoutines/widgets/forms/SlotEntryForm.tsx +2 -1
- package/src/components/WorkoutRoutines/widgets/forms/SlotForm.tsx +1 -1
- package/src/services/exerciseTranslation.ts +24 -9
- package/src/services/responseType.ts +3 -29
- package/src/tests/exercises/searchResponse.ts +47 -22
|
@@ -15,8 +15,9 @@ import LoadingButton from "@mui/material/Button";
|
|
|
15
15
|
import Grid from '@mui/material/Grid';
|
|
16
16
|
import { WgerTextField } from "components/Common/forms/WgerTextField";
|
|
17
17
|
import { DeleteConfirmationModal } from "components/Core/Modals/DeleteConfirmationModal";
|
|
18
|
-
import { Day } from "components/WorkoutRoutines/models/Day";
|
|
18
|
+
import { Day, DayType } from "components/WorkoutRoutines/models/Day";
|
|
19
19
|
import { useDeleteDayQuery, useEditDayQuery } from "components/WorkoutRoutines/queries";
|
|
20
|
+
import { DayTypeSelect } from "components/WorkoutRoutines/widgets/forms/DayTypeSelect";
|
|
20
21
|
import { DefaultRoundingMenu } from "components/WorkoutRoutines/widgets/forms/RoutineForm";
|
|
21
22
|
import { Form, Formik } from "formik";
|
|
22
23
|
import React, { useState } from "react";
|
|
@@ -74,21 +75,25 @@ export const DayForm = (props: {
|
|
|
74
75
|
description: Yup.string()
|
|
75
76
|
.max(descriptionMaxLength, t('forms.maxLength', { chars: descriptionMaxLength })),
|
|
76
77
|
isRest: Yup.boolean(),
|
|
77
|
-
needsLogsToAdvance: Yup.boolean()
|
|
78
|
+
needsLogsToAdvance: Yup.boolean(),
|
|
79
|
+
type: Yup.string(),
|
|
78
80
|
});
|
|
79
81
|
|
|
80
82
|
const handleSubmit = (values: Partial<{
|
|
81
83
|
name: string,
|
|
82
84
|
description: string,
|
|
83
85
|
isRest: boolean,
|
|
84
|
-
needsLogsToAdvance: boolean
|
|
85
|
-
|
|
86
|
+
needsLogsToAdvance: boolean,
|
|
87
|
+
type: string
|
|
88
|
+
}>) =>
|
|
89
|
+
editDayQuery.mutate(Day.clone(
|
|
86
90
|
props.day,
|
|
87
91
|
{
|
|
88
92
|
...(values.name !== undefined && { name: values.name }),
|
|
89
93
|
...(values.description !== undefined && { description: values.description }),
|
|
90
94
|
...({ isRest: values.isRest }),
|
|
91
95
|
...(values.needsLogsToAdvance !== undefined && { needLogsToAdvance: values.needsLogsToAdvance }),
|
|
96
|
+
...(values.type !== undefined && { type: values.type as DayType }),
|
|
92
97
|
})
|
|
93
98
|
);
|
|
94
99
|
|
|
@@ -98,7 +103,8 @@ export const DayForm = (props: {
|
|
|
98
103
|
name: props.day.name,
|
|
99
104
|
description: props.day.description,
|
|
100
105
|
isRest: props.day.isRest,
|
|
101
|
-
needsLogsToAdvance: props.day.needLogsToAdvance
|
|
106
|
+
needsLogsToAdvance: props.day.needLogsToAdvance,
|
|
107
|
+
type: props.day.type,
|
|
102
108
|
}}
|
|
103
109
|
validationSchema={validationSchema}
|
|
104
110
|
onSubmit={(values, { setSubmitting }) => {
|
|
@@ -110,19 +116,25 @@ export const DayForm = (props: {
|
|
|
110
116
|
{(formik) => (
|
|
111
117
|
<Form>
|
|
112
118
|
<Grid container spacing={2}>
|
|
113
|
-
<Grid size={{ xs: 12, sm: 6 }}>
|
|
119
|
+
<Grid size={{ xs: 12, sm: 6, md: 4 }}>
|
|
114
120
|
<WgerTextField
|
|
115
121
|
fieldName="name"
|
|
116
122
|
title="Name"
|
|
117
123
|
fieldProps={{ disabled: isRestDay }}
|
|
118
124
|
/>
|
|
119
125
|
</Grid>
|
|
120
|
-
<Grid size={{ xs:
|
|
126
|
+
<Grid size={{ xs: 12, sm: 6, md: 3 }}>
|
|
127
|
+
<DayTypeSelect
|
|
128
|
+
fieldName="type"
|
|
129
|
+
title="Type"
|
|
130
|
+
/>
|
|
131
|
+
</Grid>
|
|
132
|
+
<Grid size={{ xs: 12, sm: 6, md: 2 }}>
|
|
121
133
|
<FormControlLabel
|
|
122
134
|
control={<Switch checked={isRestDay} onChange={handleRestDayChange} />}
|
|
123
135
|
label={t('routines.restDay')} />
|
|
124
136
|
</Grid>
|
|
125
|
-
<Grid size={{ xs:
|
|
137
|
+
<Grid size={{ xs: 12, sm: 4, md: 3 }}>
|
|
126
138
|
<FormControlLabel
|
|
127
139
|
disabled={isRestDay}
|
|
128
140
|
control={<Switch
|
|
@@ -188,7 +200,7 @@ export const DayForm = (props: {
|
|
|
188
200
|
</Dialog>
|
|
189
201
|
|
|
190
202
|
<DeleteConfirmationModal
|
|
191
|
-
title={t('deleteConfirmation', { name: props.day.
|
|
203
|
+
title={t('deleteConfirmation', { name: props.day.displayName })}
|
|
192
204
|
message={t('routines.deleteDayConfirmation')}
|
|
193
205
|
isOpen={openDeleteDialog}
|
|
194
206
|
closeFn={handleCancelDeleteDay}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import MenuItem from "@mui/material/MenuItem";
|
|
2
|
+
import TextField from "@mui/material/TextField";
|
|
3
|
+
import { useField } from "formik";
|
|
4
|
+
import { useTranslation } from "react-i18next";
|
|
5
|
+
|
|
6
|
+
interface DayTypeSelectProps {
|
|
7
|
+
fieldName: string,
|
|
8
|
+
title: string,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const DayTypeSelect = (props: DayTypeSelectProps) => {
|
|
12
|
+
const { t } = useTranslation();
|
|
13
|
+
const [field, meta] = useField(props.fieldName);
|
|
14
|
+
|
|
15
|
+
const options = [
|
|
16
|
+
{
|
|
17
|
+
value: 'custom',
|
|
18
|
+
label: t('routines.day.custom'),
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
value: 'enom',
|
|
22
|
+
label: t('routines.day.enom'),
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
value: 'amrap',
|
|
26
|
+
label: t('routines.day.amrap'),
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
value: 'hiit',
|
|
30
|
+
label: t('routines.day.hiit'),
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
value: 'tabata',
|
|
34
|
+
label: t('routines.day.tabata'),
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
value: 'edt',
|
|
38
|
+
label: t('routines.day.edt'),
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
value: 'rft',
|
|
42
|
+
label: t('routines.day.rft'),
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
value: 'afap',
|
|
46
|
+
label: t('routines.day.afap'),
|
|
47
|
+
}
|
|
48
|
+
] as const;
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
return <>
|
|
52
|
+
<TextField
|
|
53
|
+
fullWidth
|
|
54
|
+
select
|
|
55
|
+
label={t('routines.set.type')}
|
|
56
|
+
variant="standard"
|
|
57
|
+
{...field}
|
|
58
|
+
>
|
|
59
|
+
{options!.map((option) => (
|
|
60
|
+
<MenuItem key={option.value} value={option.value}>
|
|
61
|
+
{option.value.toUpperCase()} - <small>{option.label}</small>
|
|
62
|
+
</MenuItem>
|
|
63
|
+
))}
|
|
64
|
+
</TextField>
|
|
65
|
+
</>;
|
|
66
|
+
};
|
|
@@ -6,6 +6,7 @@ import Grid from '@mui/material/Grid';
|
|
|
6
6
|
import { WgerTextField } from "components/Common/forms/WgerTextField";
|
|
7
7
|
import { LoadingPlaceholder } from "components/Core/LoadingWidget/LoadingWidget";
|
|
8
8
|
import { NameAutocompleter } from "components/Exercises/Filter/NameAutcompleter";
|
|
9
|
+
import { Exercise } from "components/Exercises/models/exercise";
|
|
9
10
|
import { useLanguageQuery } from "components/Exercises/queries";
|
|
10
11
|
import { RIR_VALUES_SELECT } from "components/WorkoutRoutines/models/BaseConfig";
|
|
11
12
|
import { LogEntryForm } from "components/WorkoutRoutines/models/WorkoutLog";
|
|
@@ -15,7 +16,6 @@ import { DateTime } from "luxon";
|
|
|
15
16
|
import React, { useState } from 'react';
|
|
16
17
|
import { useTranslation } from "react-i18next";
|
|
17
18
|
import { getLanguageByShortName } from "services";
|
|
18
|
-
import { ExerciseSearchResponse } from "services/responseType";
|
|
19
19
|
import { REP_UNIT_REPETITIONS, SNACKBAR_AUTO_HIDE_DURATION } from "utils/consts";
|
|
20
20
|
import * as yup from "yup";
|
|
21
21
|
|
|
@@ -96,11 +96,11 @@ export const SessionLogsForm = ({ dayId, routineId, selectedDate }: SessionLogsF
|
|
|
96
96
|
setSnackbarOpen(true);
|
|
97
97
|
};
|
|
98
98
|
|
|
99
|
-
const handleCallback = async (
|
|
99
|
+
const handleCallback = async (exercise: Exercise | null, formik: FormikProps<{
|
|
100
100
|
logs: LogEntryForm[]
|
|
101
101
|
}>) => {
|
|
102
102
|
|
|
103
|
-
if (
|
|
103
|
+
if (exercise === null) {
|
|
104
104
|
return;
|
|
105
105
|
}
|
|
106
106
|
|
|
@@ -115,7 +115,7 @@ export const SessionLogsForm = ({ dayId, routineId, selectedDate }: SessionLogsF
|
|
|
115
115
|
repetitionsTarget: '',
|
|
116
116
|
rir: '',
|
|
117
117
|
rirTarget: '',
|
|
118
|
-
exercise:
|
|
118
|
+
exercise: exercise,
|
|
119
119
|
};
|
|
120
120
|
}
|
|
121
121
|
return log;
|
|
@@ -40,16 +40,18 @@ describe('SlotEntryTypeField', () => {
|
|
|
40
40
|
const dropdown = screen.getByRole('combobox', { name: 'routines.set.type' });
|
|
41
41
|
await user.click(dropdown);
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
expect(screen.
|
|
45
|
-
expect(screen.getByText(
|
|
46
|
-
expect(screen.getByText(
|
|
47
|
-
expect(screen.getByText(
|
|
48
|
-
expect(screen.getByText(
|
|
49
|
-
expect(screen.getByText(
|
|
50
|
-
expect(screen.getByText(
|
|
51
|
-
|
|
52
|
-
|
|
43
|
+
// One in the options menu, one in the selected value
|
|
44
|
+
expect(screen.queryAllByText(/routines\.set\.normalSet/)).toHaveLength(2);
|
|
45
|
+
expect(screen.getByText(/routines\.set\.dropSet/)).toBeInTheDocument();
|
|
46
|
+
expect(screen.getByText(/routines\.set\.myo/)).toBeInTheDocument();
|
|
47
|
+
expect(screen.getByText(/routines\.set\.partial/)).toBeInTheDocument();
|
|
48
|
+
expect(screen.getByText(/routines\.set\.forced/)).toBeInTheDocument();
|
|
49
|
+
expect(screen.getByText(/routines\.set\.tut/)).toBeInTheDocument();
|
|
50
|
+
expect(screen.getByText(/routines\.set\.iso/)).toBeInTheDocument();
|
|
51
|
+
expect(screen.getByText(/routines\.set\.jump/)).toBeInTheDocument();
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
const myoOption = screen.getByRole('option', { name: /routines\.set\.myo/ });
|
|
53
55
|
await user.click(myoOption);
|
|
54
56
|
expect(mockEditSlotEntry).toHaveBeenCalledWith(SlotEntry.clone(testDayLegs.slots[0].entries[0], { type: 'myo' }));
|
|
55
57
|
});
|
|
@@ -55,6 +55,7 @@ export const SlotEntryTypeField = (props: { slotEntry: SlotEntry, routineId: num
|
|
|
55
55
|
editQuery.mutate(SlotEntry.clone(props.slotEntry, { type: newValue as SlotEntryType }));
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
+
|
|
58
59
|
return <>
|
|
59
60
|
<TextField
|
|
60
61
|
fullWidth
|
|
@@ -67,7 +68,7 @@ export const SlotEntryTypeField = (props: { slotEntry: SlotEntry, routineId: num
|
|
|
67
68
|
>
|
|
68
69
|
{options!.map((option) => (
|
|
69
70
|
<MenuItem key={option.value} value={option.value}>
|
|
70
|
-
{option.label}
|
|
71
|
+
{option.value.toUpperCase()} - {option.label}
|
|
71
72
|
</MenuItem>
|
|
72
73
|
))}
|
|
73
74
|
</TextField>
|
|
@@ -26,7 +26,7 @@ export const SlotForm = (props: { slot: Slot, routineId: number }) => {
|
|
|
26
26
|
size={"small"}
|
|
27
27
|
value={slotComment}
|
|
28
28
|
disabled={editSlotQuery.isPending}
|
|
29
|
-
onChange={(e) =>
|
|
29
|
+
onChange={(e) => setSlotComment(e.target.value)}
|
|
30
30
|
onBlur={handleBlur}
|
|
31
31
|
slotProps={{
|
|
32
32
|
input: { endAdornment: editSlotQuery.isPending && <LoadingProgressIcon /> }
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
|
+
import { Exercise, ExerciseAdapter } from "components/Exercises/models/exercise";
|
|
2
3
|
import { Translation, TranslationAdapter } from "components/Exercises/models/translation";
|
|
3
4
|
import { ENGLISH_LANGUAGE_CODE, LANGUAGE_SHORT_ENGLISH } from "utils/consts";
|
|
4
5
|
import { makeHeader, makeUrl } from "utils/url";
|
|
5
|
-
import {
|
|
6
|
+
import { ResponseType } from "./responseType";
|
|
6
7
|
|
|
7
8
|
export const EXERCISE_PATH = 'exercise';
|
|
8
9
|
export const EXERCISE_TRANSLATION_PATH = 'exercise-translation';
|
|
9
|
-
export const EXERCISE_SEARCH_PATH = 'exercise/search';
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
/*
|
|
@@ -15,7 +15,7 @@ export const EXERCISE_SEARCH_PATH = 'exercise/search';
|
|
|
15
15
|
export const getExerciseTranslations = async (id: number): Promise<Translation[]> => {
|
|
16
16
|
const url = makeUrl(EXERCISE_PATH, { query: { exercise: id } });
|
|
17
17
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
18
|
-
const { data } = await axios.get<ResponseType<
|
|
18
|
+
const { data } = await axios.get<ResponseType<Translation>>(url, {
|
|
19
19
|
headers: makeHeader(),
|
|
20
20
|
});
|
|
21
21
|
const adapter = new TranslationAdapter();
|
|
@@ -24,19 +24,34 @@ export const getExerciseTranslations = async (id: number): Promise<Translation[]
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
/*
|
|
27
|
-
*
|
|
27
|
+
* Search for exercises by name using the exerciseinfo endpoint
|
|
28
28
|
*/
|
|
29
|
-
export const searchExerciseTranslations = async (name: string,
|
|
29
|
+
export const searchExerciseTranslations = async (name: string,languageCode: string = ENGLISH_LANGUAGE_CODE,searchEnglish: boolean = true): Promise<Exercise[]> => {
|
|
30
30
|
const languages = [languageCode];
|
|
31
31
|
if (languageCode !== LANGUAGE_SHORT_ENGLISH && searchEnglish) {
|
|
32
32
|
languages.push(LANGUAGE_SHORT_ENGLISH);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
const url = makeUrl('exerciseinfo', {
|
|
36
|
+
query: {
|
|
37
|
+
name__search: name,
|
|
38
|
+
language__code: languages.join(','),
|
|
39
|
+
limit: 50,
|
|
40
|
+
}
|
|
41
|
+
});
|
|
35
42
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
43
|
+
try {
|
|
44
|
+
const { data } = await axios.get<ResponseType<Exercise>>(url);
|
|
45
|
+
|
|
46
|
+
if (!data || !data.results || !Array.isArray(data.results)) {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const adapter = new ExerciseAdapter();
|
|
51
|
+
return data.results.map((item: unknown) => adapter.fromJson(item));
|
|
52
|
+
} catch {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
40
55
|
};
|
|
41
56
|
|
|
42
57
|
|
|
@@ -1,35 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/*
|
|
2
|
+
* Generic paginated response from the wger API
|
|
3
|
+
*/
|
|
3
4
|
export interface ResponseType<T> {
|
|
4
5
|
count: number,
|
|
5
6
|
next: number | null,
|
|
6
7
|
previous: number | null,
|
|
7
8
|
results: T[]
|
|
8
9
|
}
|
|
9
|
-
|
|
10
|
-
export interface ExerciseSearchResponse {
|
|
11
|
-
value: string,
|
|
12
|
-
data: {
|
|
13
|
-
id: number,
|
|
14
|
-
base_id: number,
|
|
15
|
-
name: string,
|
|
16
|
-
category: string,
|
|
17
|
-
image: string | null,
|
|
18
|
-
image_thumbnail: string | null,
|
|
19
|
-
},
|
|
20
|
-
exercise?: Exercise
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export interface ExerciseSearchType {
|
|
24
|
-
suggestions: ExerciseSearchResponse[];
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface IngredientSearchResponse {
|
|
28
|
-
value: string,
|
|
29
|
-
data: {
|
|
30
|
-
id: number,
|
|
31
|
-
name: string,
|
|
32
|
-
image: string | null,
|
|
33
|
-
image_thumbnail: string | null,
|
|
34
|
-
}
|
|
35
|
-
}
|
|
@@ -1,23 +1,48 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
1
|
+
import { Exercise } from "components/Exercises/models/exercise";
|
|
2
|
+
import { Category } from "components/Exercises/models/category";
|
|
3
|
+
import { Translation } from "components/Exercises/models/translation";
|
|
4
|
+
|
|
5
|
+
export const searchResponse: Exercise[] = [
|
|
6
|
+
new Exercise(
|
|
7
|
+
998, // id
|
|
8
|
+
"uuid-998", // uuid
|
|
9
|
+
new Category(8, "Bauch"), // category
|
|
10
|
+
[], // equipment
|
|
11
|
+
[], // muscles
|
|
12
|
+
[], // musclesSecondary
|
|
13
|
+
[], // images
|
|
14
|
+
null, // variationId
|
|
15
|
+
[
|
|
16
|
+
new Translation(
|
|
17
|
+
1149, // id
|
|
18
|
+
"uuid-1149", // uuid
|
|
19
|
+
"Crunches an Negativbank", // name
|
|
20
|
+
"", // description
|
|
21
|
+
1 // language (German)
|
|
22
|
+
)
|
|
23
|
+
], // translations
|
|
24
|
+
[], // videos
|
|
25
|
+
[] // authors
|
|
26
|
+
),
|
|
27
|
+
new Exercise(
|
|
28
|
+
979, // id
|
|
29
|
+
"uuid-979", // uuid
|
|
30
|
+
new Category(11, "Brust"), // category
|
|
31
|
+
[], // equipment
|
|
32
|
+
[], // muscles
|
|
33
|
+
[], // musclesSecondary
|
|
34
|
+
[], // images
|
|
35
|
+
null, // variationId
|
|
36
|
+
[
|
|
37
|
+
new Translation(
|
|
38
|
+
1213, // id
|
|
39
|
+
"uuid-1213", // uuid
|
|
40
|
+
"Crunches am Seil", // name
|
|
41
|
+
"", // description
|
|
42
|
+
1 // language (German)
|
|
43
|
+
)
|
|
44
|
+
], // translations
|
|
45
|
+
[], // videos
|
|
46
|
+
[] // authors
|
|
47
|
+
)
|
|
23
48
|
];
|