@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.
Files changed (52) hide show
  1. package/README.md +1 -1
  2. package/build/chunks/{browser-ponyfill-DL_vVusK.js → browser-ponyfill-CyEkMYuR.js} +3 -3
  3. package/build/chunks/{browser-ponyfill-DL_vVusK.js.map → browser-ponyfill-CyEkMYuR.js.map} +1 -1
  4. package/build/locales/de/translation.json +334 -334
  5. package/build/locales/en/translation.json +12 -2
  6. package/build/locales/fil/translation.json +3 -0
  7. package/build/locales/fr/translation.json +347 -337
  8. package/build/locales/hr/translation.json +344 -244
  9. package/build/locales/it/translation.json +333 -333
  10. package/build/locales/ko/translation.json +327 -327
  11. package/build/locales/pt_PT/translation.json +330 -330
  12. package/build/locales/sk/translation.json +26 -1
  13. package/build/locales/sl/translation.json +321 -321
  14. package/build/locales/ta/translation.json +325 -325
  15. package/build/locales/uk/translation.json +344 -334
  16. package/build/locales/zh_Hans/translation.json +332 -332
  17. package/build/main.js +137 -236
  18. package/build/main.js.map +1 -1
  19. package/package.json +13 -13
  20. package/src/components/BodyWeight/Form/WeightForm.tsx +3 -4
  21. package/src/components/BodyWeight/WeightChart/index.tsx +26 -29
  22. package/src/components/Exercises/Detail/Head/ExerciseDeleteDialog.tsx +3 -4
  23. package/src/components/Exercises/ExerciseOverview.tsx +4 -4
  24. package/src/components/Exercises/Filter/NameAutcompleter.tsx +41 -39
  25. package/src/components/Exercises/Filter/NameAutocompleter.test.tsx +2 -1
  26. package/src/components/Measurements/Screens/MeasurementCategoryDetail.test.tsx +4 -2
  27. package/src/components/Measurements/widgets/MeasurementChart.tsx +27 -30
  28. package/src/components/Nutrition/components/BmiCalculator.tsx +40 -42
  29. package/src/components/Nutrition/widgets/IngredientAutcompleter.tsx +1 -1
  30. package/src/components/Nutrition/widgets/charts/MacrosPieChart.tsx +17 -19
  31. package/src/components/Nutrition/widgets/charts/NutritionDiaryChart.tsx +39 -38
  32. package/src/components/Nutrition/widgets/charts/NutritionalValuesDashboardChart.tsx +27 -29
  33. package/src/components/Nutrition/widgets/charts/NutritionalValuesPlannedLoggedChart.tsx +20 -19
  34. package/src/components/Nutrition/widgets/forms/NutritionDiaryEntryForm.tsx +15 -4
  35. package/src/components/WorkoutRoutines/Detail/RoutineDetailsTable.tsx +3 -3
  36. package/src/components/WorkoutRoutines/Detail/WorkoutStats.tsx +17 -19
  37. package/src/components/WorkoutRoutines/models/Day.ts +16 -6
  38. package/src/components/WorkoutRoutines/models/SlotEntry.ts +7 -2
  39. package/src/components/WorkoutRoutines/widgets/DayDetails.tsx +4 -4
  40. package/src/components/WorkoutRoutines/widgets/LogWidgets.tsx +35 -38
  41. package/src/components/WorkoutRoutines/widgets/RoutineDetailsCard.tsx +8 -11
  42. package/src/components/WorkoutRoutines/widgets/SlotDetails.tsx +4 -4
  43. package/src/components/WorkoutRoutines/widgets/forms/DayForm.tsx +21 -9
  44. package/src/components/WorkoutRoutines/widgets/forms/DayTypeSelect.tsx +66 -0
  45. package/src/components/WorkoutRoutines/widgets/forms/SessionForm.test.tsx +0 -2
  46. package/src/components/WorkoutRoutines/widgets/forms/SessionLogsForm.tsx +4 -4
  47. package/src/components/WorkoutRoutines/widgets/forms/SlotEntryForm.test.tsx +12 -10
  48. package/src/components/WorkoutRoutines/widgets/forms/SlotEntryForm.tsx +2 -1
  49. package/src/components/WorkoutRoutines/widgets/forms/SlotForm.tsx +1 -1
  50. package/src/services/exerciseTranslation.ts +24 -9
  51. package/src/services/responseType.ts +3 -29
  52. package/src/tests/exercises/searchResponse.ts +47 -22
@@ -1,7 +1,7 @@
1
1
  import { NutritionalValues } from "components/Nutrition/helpers/nutritionalValues";
2
2
  import React from 'react';
3
3
  import { useTranslation } from "react-i18next";
4
- import { Bar, BarChart, CartesianGrid, Legend, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts';
4
+ import { Bar, BarChart, CartesianGrid, Legend, Tooltip, XAxis, YAxis } from 'recharts';
5
5
  import { generateChartColors } from "utils/colors";
6
6
  import { numberLocale } from "utils/numbers";
7
7
 
@@ -50,46 +50,47 @@ export const NutritionDiaryChart = ({ showPlanned, planned, today, avg7Days }: N
50
50
  ];
51
51
 
52
52
  return (
53
- <ResponsiveContainer width={"100%"} height={300}>
54
- <BarChart
55
- data={data}
56
- margin={{
57
- top: 20,
58
- right: 30,
59
- left: 20,
60
- bottom: 5,
61
- }}
62
- >
63
- <CartesianGrid strokeDasharray="3 4" />
64
- <XAxis dataKey="name" />
65
- <YAxis
66
- type="number"
67
- orientation="left"
68
- unit={t('nutrition.gramShort')}
69
- />
70
- <Tooltip formatter={(value: number) => numberLocale(value, i18n.language)} />
71
- <Legend />
72
- {showPlanned &&
73
- <Bar
74
- dataKey="planned"
75
- unit={t('nutrition.gramShort')}
76
- name={t('nutrition.planned')}
77
- fill={colorGenerator.next().value!}
78
- />
79
- }
80
- <Bar
81
- dataKey="today"
82
- unit={t('nutrition.gramShort')}
83
- name={t('nutrition.today')}
84
- fill={colorGenerator.next().value!}
85
- />
53
+ <BarChart
54
+ data={data}
55
+ margin={{
56
+ top: 20,
57
+ right: 30,
58
+ left: 20,
59
+ bottom: 5,
60
+ }}
61
+ responsive
62
+ width={"100%"}
63
+ height={300}
64
+ >
65
+ <CartesianGrid strokeDasharray="3 4" />
66
+ <XAxis dataKey="name" />
67
+ <YAxis
68
+ type="number"
69
+ orientation="left"
70
+ unit={t('nutrition.gramShort')}
71
+ />
72
+ <Tooltip formatter={(value: number) => numberLocale(value, i18n.language)} />
73
+ <Legend />
74
+ {showPlanned &&
86
75
  <Bar
87
- dataKey="avg7Days"
76
+ dataKey="planned"
88
77
  unit={t('nutrition.gramShort')}
89
- name={t('nutrition.7dayAvg')}
78
+ name={t('nutrition.planned')}
90
79
  fill={colorGenerator.next().value!}
91
80
  />
92
- </BarChart>
93
- </ResponsiveContainer>
81
+ }
82
+ <Bar
83
+ dataKey="today"
84
+ unit={t('nutrition.gramShort')}
85
+ name={t('nutrition.today')}
86
+ fill={colorGenerator.next().value!}
87
+ />
88
+ <Bar
89
+ dataKey="avg7Days"
90
+ unit={t('nutrition.gramShort')}
91
+ name={t('nutrition.7dayAvg')}
92
+ fill={colorGenerator.next().value!}
93
+ />
94
+ </BarChart>
94
95
  );
95
96
  };
@@ -3,7 +3,7 @@ import { NutritionalValues } from "components/Nutrition/helpers/nutritionalValue
3
3
  import { LinearPlannedLoggedChart } from "components/Nutrition/widgets/charts/LinearPlannedLoggedChart";
4
4
  import React from 'react';
5
5
  import { useTranslation } from "react-i18next";
6
- import { Cell, Pie, PieChart, ResponsiveContainer } from 'recharts';
6
+ import { Cell, Pie, PieChart } from 'recharts';
7
7
  import { numberLocale } from "utils/numbers";
8
8
 
9
9
 
@@ -32,34 +32,32 @@ export const NutritionalValuesDashboardChart = (props: {
32
32
 
33
33
 
34
34
  return <Stack direction={'row'}>
35
- <ResponsiveContainer width={'50%'} height={140}>
36
- <PieChart>
37
- <Pie
38
- // cx={0}
39
- // cy={'10'}
40
- height={100}
41
- data={data}
42
- startAngle={200}
43
- endAngle={-20}
44
- innerRadius={60}
45
- outerRadius={70}
46
- paddingAngle={2}
47
- dataKey="value"
48
- >
49
- {data.map((entry, index) => (
50
- <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
51
- ))}
52
- </Pie>
53
- <g>
54
- <text x={'50%'} y={'45%'} fontSize="1.25em" textAnchor="middle">{/*fill="#333"*/}
55
- {t('nutrition.valueEnergyKcal', { value: numberLocale(energyDiff, i18n.language) })}
56
- </text>
57
- <text x={'50%'} y={'60%'} fontSize="1em" textAnchor="middle">
58
- {props.planned.energy > 0 && t(energyPercentage < 100 ? 'nutrition.valueRemaining' : 'nutrition.valueTooMany')}
59
- </text>
60
- </g>
61
- </PieChart>
62
- </ResponsiveContainer>
35
+ <PieChart responsive width={'50%'} height={140}>
36
+ <Pie
37
+ // cx={0}
38
+ // cy={'10'}
39
+ height={100}
40
+ data={data}
41
+ startAngle={200}
42
+ endAngle={-20}
43
+ innerRadius={60}
44
+ outerRadius={70}
45
+ paddingAngle={2}
46
+ dataKey="value"
47
+ >
48
+ {data.map((entry, index) => (
49
+ <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
50
+ ))}
51
+ </Pie>
52
+ <g>
53
+ <text x={'50%'} y={'45%'} fontSize="1.25em" textAnchor="middle">{/*fill="#333"*/}
54
+ {t('nutrition.valueEnergyKcal', { value: numberLocale(energyDiff, i18n.language) })}
55
+ </text>
56
+ <text x={'50%'} y={'60%'} fontSize="1em" textAnchor="middle">
57
+ {props.planned.energy > 0 && t(energyPercentage < 100 ? 'nutrition.valueRemaining' : 'nutrition.valueTooMany')}
58
+ </text>
59
+ </g>
60
+ </PieChart>
63
61
  <Stack width={'50%'} spacing={1}>
64
62
  <LinearPlannedLoggedChart
65
63
  title={t('nutrition.protein')}
@@ -1,7 +1,7 @@
1
1
  import { NutritionalValues } from "components/Nutrition/helpers/nutritionalValues";
2
2
  import React from 'react';
3
3
  import { useTranslation } from "react-i18next";
4
- import { Bar, BarChart, CartesianGrid, ResponsiveContainer, XAxis, YAxis } from 'recharts';
4
+ import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from 'recharts';
5
5
  import { generateChartColors } from "utils/colors";
6
6
 
7
7
 
@@ -32,23 +32,24 @@ export const NutritionalValuesPlannedLoggedChart = (props: {
32
32
 
33
33
 
34
34
  return (
35
- <ResponsiveContainer width={"100%"} height={150}>
36
- <BarChart
37
- data={data}
38
- layout="vertical"
39
- margin={{
40
- left: 60,
41
- }}
42
- >
43
- <CartesianGrid strokeDasharray="3 4" />
44
- <XAxis type={'number'} unit={'%'} />
45
- <YAxis type={'category'} dataKey={'name'} />
46
- <Bar
47
- dataKey="value"
48
- unit={'%'}
49
- fill={colorGenerator.next().value!}
50
- />
51
- </BarChart>
52
- </ResponsiveContainer>
35
+ <BarChart
36
+ data={data}
37
+ layout="vertical"
38
+ margin={{
39
+ left: 60,
40
+ }}
41
+ responsive
42
+ width={"100%"}
43
+ height={150}
44
+ >
45
+ <CartesianGrid strokeDasharray="3 4" />
46
+ <XAxis type={'number'} unit={'%'} />
47
+ <YAxis type={'category'} dataKey={'name'} />
48
+ <Bar
49
+ dataKey="value"
50
+ unit={'%'}
51
+ fill={colorGenerator.next().value!}
52
+ />
53
+ </BarChart>
53
54
  );
54
55
  };
@@ -39,6 +39,8 @@ export const NutritionDiaryEntryForm = ({ planId, entry, mealId, meals, closeFn
39
39
  .min(1, t('forms.minValue', { value: '1' })),
40
40
  ingredient: yup
41
41
  .number()
42
+ .nullable()
43
+ .moreThan(0, t('forms.fieldRequired'))
42
44
  .required(t('forms.fieldRequired')),
43
45
  datetime: yup
44
46
  .date()
@@ -51,7 +53,7 @@ export const NutritionDiaryEntryForm = ({ planId, entry, mealId, meals, closeFn
51
53
  initialValues={{
52
54
  datetime: new Date(),
53
55
  amount: 0,
54
- ingredient: 0,
56
+ ingredient: null,
55
57
  }}
56
58
  validationSchema={validationSchema}
57
59
  onSubmit={async (values) => {
@@ -66,7 +68,7 @@ export const NutritionDiaryEntryForm = ({ planId, entry, mealId, meals, closeFn
66
68
  planId: planId,
67
69
  amount: newAmount,
68
70
  datetime: values.datetime,
69
- ingredientId: values.ingredient
71
+ ingredientId: values.ingredient!
70
72
  });
71
73
  editDiaryQuery.mutate(newDiaryEntry);
72
74
  } else {
@@ -75,7 +77,7 @@ export const NutritionDiaryEntryForm = ({ planId, entry, mealId, meals, closeFn
75
77
  planId: planId,
76
78
  amount: newAmount,
77
79
  datetime: values.datetime,
78
- ingredientId: values.ingredient,
80
+ ingredientId: values.ingredient!,
79
81
  mealId: selectedMeal,
80
82
  }));
81
83
  }
@@ -90,7 +92,16 @@ export const NutritionDiaryEntryForm = ({ planId, entry, mealId, meals, closeFn
90
92
  <Form>
91
93
  <Stack spacing={2}>
92
94
  <IngredientAutocompleter
93
- callback={(value: Ingredient | null) => formik.setFieldValue('ingredient', value?.id)} />
95
+ callback={(value: Ingredient | null) => {
96
+ formik.setFieldTouched('ingredient', true);
97
+ formik.setFieldValue('ingredient', value?.id ?? null);
98
+ }}
99
+ />
100
+ {formik.touched.ingredient && formik.errors.ingredient && (
101
+ <div style={{ color: 'crimson', fontSize: '0.7rem', marginLeft: '12px' }}>
102
+ {formik.errors.ingredient}
103
+ </div>
104
+ )}
94
105
  <TextField
95
106
  fullWidth
96
107
  id="amount"
@@ -212,7 +212,7 @@ export const RoutineTable = (props: {
212
212
  borderBottomWidth: showLogs ? 0 : null
213
213
  }}>{slotEntry.exercise?.getTranslation(language).name}</TableCell>
214
214
  {iterations.map((iteration) => {
215
- const setConfig = props.routine.getSetConfigData(day.id, iteration, slotEntry.id);
215
+ const setConfig = props.routine.getSetConfigData(day.id!, iteration, slotEntry.id!);
216
216
 
217
217
  return <React.Fragment key={iteration}>
218
218
  <TableCell align={'center'} sx={sx}>
@@ -268,7 +268,7 @@ export const RoutineTable = (props: {
268
268
  <small>{t('nutrition.logged')}</small>
269
269
  </TableCell>
270
270
  {iterations.map((iteration) => {
271
- const setConfig = props.routine.getSetConfigData(day.id, iteration, slotEntry.id);
271
+ const setConfig = props.routine.getSetConfigData(day.id!, iteration, slotEntry.id!);
272
272
  const iterationLogs = groupedLogs[iteration] ?? [];
273
273
 
274
274
  const logs = iterationLogs.filter((log) => log.slotEntryId === slotEntry.id);
@@ -330,7 +330,7 @@ export const RoutineTable = (props: {
330
330
  sx={{ backgroundColor: theme.palette.action.hover }}
331
331
  className={classes.stickyColumn}
332
332
  >
333
- <b>{day.getDisplayName()}</b>
333
+ <b>{day.displayName}</b>
334
334
  </TableCell>
335
335
  <TableCell sx={{ backgroundColor: theme.palette.action.hover }} colSpan={5 * iterations.length}>
336
336
  </TableCell>
@@ -209,25 +209,23 @@ export const WorkoutStats = () => {
209
209
 
210
210
  <Grid size={12}>
211
211
  <Box width="100%" height={400}>
212
- <ResponsiveContainer width="100%" height="100%">
213
- <LineChart width={500} height={300}>
214
- <CartesianGrid strokeDasharray="3 3" />
215
- <XAxis dataKey="category" type="category" allowDuplicatedCategory={false} />
216
- <YAxis dataKey="value" />
217
- <Tooltip
218
- formatter={(value: number) => Number.isInteger(value) ? value.toFixed(0) : value.toFixed(2)} />
219
- <Legend
220
- layout={"vertical"}
221
- verticalAlign="middle"
222
- align="right"
223
- wrapperStyle={{ paddingLeft: "20px" }}
224
- />
225
- {chartData.map((s) => (
226
- <Line dataKey="value" data={s.data} name={s.name} key={s.name}
227
- stroke={colorGenerator.next()!.value!} />
228
- ))}
229
- </LineChart>
230
- </ResponsiveContainer>
212
+ <LineChart width="100%" height="100%" responsive>
213
+ <CartesianGrid strokeDasharray="3 3" />
214
+ <XAxis dataKey="category" type="category" allowDuplicatedCategory={false} />
215
+ <YAxis dataKey="value" />
216
+ <Tooltip
217
+ formatter={(value: number) => Number.isInteger(value) ? value.toFixed(0) : value.toFixed(2)} />
218
+ <Legend
219
+ layout={"vertical"}
220
+ verticalAlign="middle"
221
+ align="right"
222
+ wrapperStyle={{ paddingLeft: "20px" }}
223
+ />
224
+ {chartData.map((s) => (
225
+ <Line dataKey="value" data={s.data} name={s.name} key={s.name}
226
+ stroke={colorGenerator.next()!.value!} />
227
+ ))}
228
+ </LineChart>
231
229
  </Box>
232
230
  </Grid>
233
231
 
@@ -4,6 +4,8 @@ import { Slot } from "components/WorkoutRoutines/models/Slot";
4
4
  import i18n from 'i18next';
5
5
  import { Adapter } from "utils/Adapter";
6
6
 
7
+ export type DayType = 'custom' | 'enom' | 'amrap' | 'hiit' | 'tabata' | 'edt' | 'rft' | 'afap';
8
+
7
9
  interface DayConstructorParams {
8
10
  id?: number;
9
11
  routineId: number | null;
@@ -12,7 +14,7 @@ interface DayConstructorParams {
12
14
  description?: string;
13
15
  isRest?: boolean;
14
16
  needLogsToAdvance?: boolean;
15
- type?: 'custom' | 'enom' | 'amrap' | 'hiit' | 'tabata' | 'edt' | 'rft' | 'afap';
17
+ type?: DayType;
16
18
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
19
  config?: any | null;
18
20
  slots?: Slot[];
@@ -30,7 +32,7 @@ export class Day {
30
32
  description: string;
31
33
  isRest: boolean;
32
34
  needLogsToAdvance: boolean;
33
- type: 'custom' | 'enom' | 'amrap' | 'hiit' | 'tabata' | 'edt' | 'rft' | 'afap';
35
+ type: DayType;
34
36
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
37
  config: any | null;
36
38
 
@@ -53,6 +55,14 @@ export class Day {
53
55
  return this.type !== 'custom';
54
56
  }
55
57
 
58
+ public get displayNameWithType(): string {
59
+ return this.isSpecialType ? `${this.type.toUpperCase()} - ${this.displayName}` : this.displayName;
60
+ }
61
+
62
+ public get displayName(): string {
63
+ return this.isRest ? i18n.t('routines.restDay') : this.name;
64
+ }
65
+
56
66
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
67
  static fromJson(json: any): Day {
58
68
  return adapter.fromJson(json);
@@ -73,9 +83,6 @@ export class Day {
73
83
  });
74
84
  }
75
85
 
76
- public getDisplayName(): string {
77
- return this.isRest ? i18n.t('routines.restDay') : this.name;
78
- }
79
86
 
80
87
  toJson() {
81
88
  return adapter.toJson(this);
@@ -83,7 +90,10 @@ export class Day {
83
90
 
84
91
  }
85
92
 
86
- export const getDayName = (day: Day | null): string => day === null || day.isRest ? i18n.t('routines.restDay') : day.getDisplayName();
93
+ /*
94
+ * Returns the display name of the day, or "Rest day" if it's a rest day or null
95
+ */
96
+ export const getDayName = (day: Day | null): string => day === null || day.isRest ? i18n.t('routines.restDay') : day.displayNameWithType;
87
97
 
88
98
 
89
99
  class DayAdapter implements Adapter<Day> {
@@ -133,11 +133,16 @@ export class SlotEntry {
133
133
  order: overrides?.order ?? other.order,
134
134
  comment: overrides?.comment ?? other.comment,
135
135
 
136
- repetitionUnit: overrides?.repetitionUnit ?? (other.repetitionUnit ?? undefined),
136
+ // NOTE: temporarily commented out to avoid issues. The constructor will see the
137
+ // unit objects and set the ids accordingly, ignoring the explicit IDs. This is
138
+ // probably OK since we always load the whole routine again after an edit, but
139
+ // it is a bit ugly.
140
+
141
+ // repetitionUnit: overrides?.repetitionUnit ?? (other.repetitionUnit ?? undefined),
137
142
  repetitionUnitId: overrides?.repetitionUnitId ?? other.repetitionUnitId,
138
143
  repetitionRounding: overrides?.repetitionRounding ?? other.repetitionRounding,
139
144
 
140
- weightUnit: overrides?.weightUnit ?? (other.weightUnit ?? undefined),
145
+ // weightUnit: overrides?.weightUnit ?? (other.weightUnit ?? undefined),
141
146
  weightUnitId: overrides?.weightUnitId ?? other.weightUnitId,
142
147
  weightRounding: overrides?.weightRounding ?? other.weightRounding,
143
148
  });
@@ -24,6 +24,7 @@ import {
24
24
  import Grid from '@mui/material/Grid';
25
25
  import { LoadingPlaceholder, LoadingProgressIcon } from "components/Core/LoadingWidget/LoadingWidget";
26
26
  import { NameAutocompleter } from "components/Exercises/Filter/NameAutcompleter";
27
+ import { Exercise } from "components/Exercises/models/exercise";
27
28
  import { useProfileQuery } from "components/User/queries/profile";
28
29
  import { Day } from "components/WorkoutRoutines/models/Day";
29
30
  import { Slot } from "components/WorkoutRoutines/models/Slot";
@@ -43,7 +44,6 @@ import { SlotDetails } from "components/WorkoutRoutines/widgets/SlotDetails";
43
44
  import React, { useState } from "react";
44
45
  import { useTranslation } from "react-i18next";
45
46
  import { Link } from "react-router-dom";
46
- import { ExerciseSearchResponse } from "services/responseType";
47
47
  import { SNACKBAR_AUTO_HIDE_DURATION, WEIGHT_UNIT_KG, WEIGHT_UNIT_LB } from "utils/consts";
48
48
  import { makeLink, WgerLink } from "utils/url";
49
49
 
@@ -135,7 +135,7 @@ export const DayDragAndDropGrid = (props: {
135
135
  provided.draggableProps.style ?? {}
136
136
  )}
137
137
 
138
- label={day.getDisplayName()}
138
+ label={day.displayName}
139
139
  value={day.id}
140
140
  icon={<DragIndicatorIcon />}
141
141
  iconPosition="start"
@@ -381,13 +381,13 @@ export const DayDetails = (props: {
381
381
  && <Grid size={12}>
382
382
  <Box height={20} />
383
383
  <NameAutocompleter
384
- callback={(exercise: ExerciseSearchResponse | null) => {
384
+ callback={(exercise: Exercise | null) => {
385
385
  if (exercise === null) {
386
386
  return;
387
387
  }
388
388
  addSlotEntryQuery.mutate(new SlotEntry({
389
389
  slotId: slot.id!,
390
- exerciseId: exercise.data.base_id,
390
+ exerciseId: exercise.id!,
391
391
  type: 'normal',
392
392
  order: slot.entries.length + 1,
393
393
  weightUnitId: userProfileQuery.data!.useMetric ? WEIGHT_UNIT_KG : WEIGHT_UNIT_LB,
@@ -27,7 +27,6 @@ import { useTranslation } from "react-i18next";
27
27
  import {
28
28
  CartesianGrid,
29
29
  Legend,
30
- ResponsiveContainer,
31
30
  Scatter,
32
31
  ScatterChart,
33
32
  Tooltip,
@@ -292,43 +291,41 @@ export const TimeSeriesChart = (props: { data: WorkoutLog[] }) => {
292
291
 
293
292
  return (
294
293
  <Box>
295
- <ResponsiveContainer width={"100%"} height={250}>
296
- <ScatterChart>
297
- <XAxis
298
- dataKey="time"
299
- domain={["auto", "auto"]}
300
- name="Time"
301
- tickFormatter={unixTime => luxonDateTimeToLocale(DateTime.fromMillis(unixTime))}
302
- type="number"
303
- />
304
- <YAxis
305
- domain={["auto", "auto"]}
306
- dataKey="value"
307
- name="Value"
308
- unit="kg"
309
- />
310
-
311
- {Array.from(result).map(([key, value]) => {
312
- const color = colorGenerator.next().value!;
313
- const formattedData = formatData(value);
314
-
315
- return <Scatter
316
- key={key}
317
- data={formattedData}
318
- fill={color}
319
- line={{ stroke: color }}
320
- lineType="joint"
321
- lineJointType="monotoneX"
322
- name={key?.toString()}
323
- />;
324
- }
325
- )}
326
-
327
- <Tooltip content={<ExerciseLogTooltip />} />
328
- <CartesianGrid strokeDasharray="3 3" />
329
- <Legend />
330
- </ScatterChart>
331
- </ResponsiveContainer>
294
+ <ScatterChart responsive width={"100%"} height={250}>
295
+ <XAxis
296
+ dataKey="time"
297
+ domain={["auto", "auto"]}
298
+ name="Time"
299
+ tickFormatter={unixTime => luxonDateTimeToLocale(DateTime.fromMillis(unixTime))}
300
+ type="number"
301
+ />
302
+ <YAxis
303
+ domain={["auto", "auto"]}
304
+ dataKey="value"
305
+ name="Value"
306
+ unit="kg"
307
+ />
308
+
309
+ {Array.from(result).map(([key, value]) => {
310
+ const color = colorGenerator.next().value!;
311
+ const formattedData = formatData(value);
312
+
313
+ return <Scatter
314
+ key={key}
315
+ data={formattedData}
316
+ fill={color}
317
+ line={{ stroke: color }}
318
+ lineType="joint"
319
+ lineJointType="monotoneX"
320
+ name={key?.toString()}
321
+ />;
322
+ }
323
+ )}
324
+
325
+ <Tooltip content={<ExerciseLogTooltip />} />
326
+ <CartesianGrid strokeDasharray="3 3" />
327
+ <Legend />
328
+ </ScatterChart>
332
329
  </Box>
333
330
  );
334
331
  };
@@ -111,10 +111,7 @@ export function SetConfigDataDetails(props: {
111
111
  }
112
112
 
113
113
 
114
- function SlotDataList(props: {
115
- slotData: SlotData,
116
- index: number,
117
- }) {
114
+ function SlotDataList(props: { slotData: SlotData }) {
118
115
  return (
119
116
  <Grid
120
117
  container
@@ -163,6 +160,9 @@ export const DayDetailsCard = (props: { dayData: RoutineDayData, routineId: numb
163
160
  const theme = useTheme();
164
161
  const [t, i18n] = useTranslation();
165
162
 
163
+ const isToday = isSameDay(props.dayData.date, new Date());
164
+ const subheader = <Typography sx={{ whiteSpace: 'pre-line' }}>{props.dayData.day?.description}</Typography>;
165
+
166
166
  return (
167
167
  <Card sx={{ minWidth: 275 }}>
168
168
  <CardHeader
@@ -178,19 +178,16 @@ export const DayDetailsCard = (props: { dayData: RoutineDayData, routineId: numb
178
178
  <Addchart />
179
179
  </IconButton>
180
180
  </Tooltip>}
181
- title={getDayName(props.dayData.day)}
182
- avatar={isSameDay(props.dayData.date, new Date()) ? <TodayIcon /> : undefined}
183
- subheader={<Typography sx={{ whiteSpace: 'pre-line' }}>{props.dayData.day?.description}</Typography>}
181
+ title={<Typography variant={"h5"}>{getDayName(props.dayData.day)}</Typography>}
182
+ avatar={isToday ? <TodayIcon /> : null}
183
+ subheader={subheader}
184
184
  />
185
185
  {props.dayData.slots.length > 0 && <CardContent sx={{ padding: 0, marginBottom: 0 }}>
186
186
  <Stack>
187
187
  {props.dayData.slots.map((slotData, index) => (
188
188
  <div key={index}>
189
189
  <Box padding={1}>
190
- <SlotDataList
191
- slotData={slotData}
192
- index={index}
193
- />
190
+ <SlotDataList slotData={slotData} />
194
191
  </Box>
195
192
  <Divider />
196
193
  </div>
@@ -4,6 +4,7 @@ import EditOffIcon from '@mui/icons-material/EditOff';
4
4
  import { Alert, AlertTitle, IconButton, Typography } from "@mui/material";
5
5
  import Grid from '@mui/material/Grid';
6
6
  import { NameAutocompleter } from "components/Exercises/Filter/NameAutcompleter";
7
+ import { Exercise } from "components/Exercises/models/exercise";
7
8
  import { useLanguageQuery } from "components/Exercises/queries";
8
9
  import { BaseConfig } from "components/WorkoutRoutines/models/BaseConfig";
9
10
  import { Slot } from "components/WorkoutRoutines/models/Slot";
@@ -21,7 +22,6 @@ import {
21
22
  import React, { useState } from "react";
22
23
  import { useTranslation } from "react-i18next";
23
24
  import { getLanguageByShortName } from "services";
24
- import { ExerciseSearchResponse } from "services/responseType";
25
25
 
26
26
  /*
27
27
  * Converts a number to an alphabetic string, useful for counting
@@ -95,12 +95,12 @@ export const SlotEntryDetails = (props: {
95
95
 
96
96
  const isPending = editSlotEntryQuery.isPending || deleteSlotEntryQuery.isPending;
97
97
 
98
- const handleExerciseChange = (searchResponse: ExerciseSearchResponse | null) => {
99
- if (searchResponse === null) {
98
+ const handleExerciseChange = (exercise: Exercise | null) => {
99
+ if (exercise === null) {
100
100
  return;
101
101
  }
102
102
 
103
- editSlotEntryQuery.mutate(SlotEntry.clone(props.slotEntry, { exerciseId: searchResponse.data.base_id }));
103
+ editSlotEntryQuery.mutate(SlotEntry.clone(props.slotEntry, { exerciseId: exercise.id! }));
104
104
  setEditExercise(false);
105
105
  };
106
106