Started rework for regular and irregular set groups.

Commit
0db1e8370e51569a7900282eef0c54514673d996
Author
Marius Peter <marius.peter@tutanota.com>
Author date
Committer
Marius Peter <marius.peter@tutanota.com>
Committer date
Changed files
src/MyFitnessTracker/MFTDialog.class.st
index c2d5e347..f39b68c5 100644..100644
@@ -3,6 +3,7 @@
3 3 #superclass : #SBSComponent,
4 4 #instVars : [
5 5 'heading',
6 Added: 'subheading',
6 7 'component',
7 8 'action',
8 9 'completion'
@@ -131,7 +132,9 @@
131 132 html container
132 133 style: 'max-width: 40rem';
133 134 with: [
134 Removed: html heading: self heading.
135 Added: html heading level1 with: self heading.
136 Added: subheading ifNotNil: [
137 Added: html heading level3 textMuted with: subheading ].
135 138 html form: [
136 139 aBlock value.
137 140 html horizontalRule.
@@ -154,4 +157,16 @@
154 157 beSecondary;
155 158 callback: [ self answer: false ];
156 159 with: (completion ifNil: [ 'Cancel' ] ifNotNil: [ 'Skip' ]) ]
160 Added: ]
161 Added:
162 Added: { #category : #accessing }
163 Added: MFTDialog >> subheading [
164 Added:
165 Added: ^ subheading
166 Added: ]
167 Added:
168 Added: { #category : #accessing }
169 Added: MFTDialog >> subheading: aString [
170 Added:
171 Added: subheading := aString
157 172 ]
src/MyFitnessTracker/MFTExerciseDialog.class.st
index 00000000..61458c4f 000000..100644
@@ -0,0 +1,77 @@
1 Added: Class {
2 Added: #name : #MFTExerciseDialog,
3 Added: #superclass : #MFTDialog,
4 Added: #instVars : [
5 Added: 'allExercises',
6 Added: 'selectedExercise'
7 Added: ],
8 Added: #category : #'MyFitnessTracker-Dialog'
9 Added: }
10 Added:
11 Added: { #category : #actions }
12 Added: MFTExerciseDialog class >> edit: aMFTExercise [
13 Added:
14 Added: ^ self new
15 Added: exercise: aMFTExercise;
16 Added: sets: aMFTExercise sets;
17 Added: action: #edit;
18 Added: yourself
19 Added: ]
20 Added:
21 Added: { #category : #accessing }
22 Added: MFTExerciseDialog >> allExercises [
23 Added:
24 Added: ^ allExercises
25 Added: ]
26 Added:
27 Added: { #category : #accessing }
28 Added: MFTExerciseDialog >> allExercises: anObject [
29 Added:
30 Added: allExercises := anObject
31 Added: ]
32 Added:
33 Added: { #category : #initialization }
34 Added: MFTExerciseDialog >> initialize [
35 Added:
36 Added: super initialize.
37 Added: allExercises := MFTSQLite3Database allExercises.
38 Added: selectedExercise := allExercises first
39 Added: ]
40 Added:
41 Added: { #category : #rendering }
42 Added: MFTExerciseDialog >> renderContentOn: html [
43 Added:
44 Added: self renderDialogOn: html with: [ self renderExerciseSelectOn: html ]
45 Added: ]
46 Added:
47 Added: { #category : #rendering }
48 Added: MFTExerciseDialog >> renderExerciseSelectOn: html [
49 Added:
50 Added: selectedExercise := allExercises
51 Added: detect: [ :exercise |
52 Added: exercise id = selectedExercise id ]
53 Added: ifNone: [ allExercises first ].
54 Added: html formGroup: [
55 Added: html label: 'Exercise'.
56 Added: html select formControl
57 Added: list: allExercises;
58 Added: selected: selectedExercise;
59 Added: callback: [ :value | selectedExercise := value ];
60 Added: labels: [ :each | each englishName ] ]
61 Added: ]
62 Added:
63 Added: { #category : #delegation }
64 Added: MFTExerciseDialog >> renderSubmitOn: html [
65 Added:
66 Added: html buttonGroup: [
67 Added: html formButton
68 Added: beSubmit;
69 Added: bePrimary;
70 Added: callback: [ self answer: selectedExercise ];
71 Added: with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]).
72 Added: html formButton
73 Added: beSubmit;
74 Added: beSecondary;
75 Added: callback: [ self answer: nil ];
76 Added: with: (completion ifNil: [ 'Cancel' ] ifNotNil: [ 'Skip' ]) ]
77 Added: ]
src/MyFitnessTracker/MFTExerciseDialogOld.class.st
index 00000000..7983d21f 000000..100644
@@ -0,0 +1,170 @@
1 Added: Class {
2 Added: #name : #MFTExerciseDialogOld,
3 Added: #superclass : #MFTDialog,
4 Added: #instVars : [
5 Added: 'exercise',
6 Added: 'sets'
7 Added: ],
8 Added: #category : #'MyFitnessTracker-Dialog'
9 Added: }
10 Added:
11 Added: { #category : #actions }
12 Added: MFTExerciseDialogOld class >> edit: aMFTExercise [
13 Added:
14 Added: ^ self new
15 Added: exercise: aMFTExercise;
16 Added: sets: aMFTExercise sets;
17 Added: action: #edit;
18 Added: yourself
19 Added: ]
20 Added:
21 Added: { #category : #accessing }
22 Added: MFTExerciseDialogOld >> exercise [
23 Added:
24 Added: ^ exercise
25 Added: ]
26 Added:
27 Added: { #category : #accessing }
28 Added: MFTExerciseDialogOld >> exercise: anObject [
29 Added:
30 Added: exercise := anObject
31 Added: ]
32 Added:
33 Added: { #category : #initialization }
34 Added: MFTExerciseDialogOld >> initialize [
35 Added:
36 Added: super initialize.
37 Added: exercise := MFTExercise new.
38 Added: sets := OrderedCollection new
39 Added: ]
40 Added:
41 Added: { #category : #rendering }
42 Added: MFTExerciseDialogOld >> renderAddSetRowOn: html [
43 Added:
44 Added: html tableRow: [
45 Added: html tableData: [
46 Added: html outlineButton
47 Added: bePrimary;
48 Added: beSmall;
49 Added: callback: [ sets add: MFTSet new ];
50 Added: with: 'Add' ].
51 Added: html
52 Added: tableData;
53 Added: tableData;
54 Added: tableData ]
55 Added: ]
56 Added:
57 Added: { #category : #rendering }
58 Added: MFTExerciseDialogOld >> renderContentOn: html [
59 Added:
60 Added: self renderDialogOn: html with: [
61 Added: self renderExercisesSelectOn: html.
62 Added: self renderSetGroupTableOn: html ]
63 Added: ]
64 Added:
65 Added: { #category : #rendering }
66 Added: MFTExerciseDialogOld >> renderExerciseSelectOn: html [
67 Added:
68 Added: | allExercises selectedExercise |
69 Added: allExercises := MFTUtils allExercises.
70 Added: selectedExercise := allExercises
71 Added: detect: [ :each |
72 Added: each englishName = exercise englishName ]
73 Added: ifNone: [ nil ].
74 Added: html formGroup: [
75 Added: html label: 'Exercise'.
76 Added: html select formControl
77 Added: list: allExercises;
78 Added: selected: selectedExercise;
79 Added: callback: [ :value | exercise := value ];
80 Added: labels: [ :each | each englishName ] ]
81 Added: ]
82 Added:
83 Added: { #category : #rendering }
84 Added: MFTExerciseDialogOld >> renderSetsRowsOn: html [
85 Added: "TODO: something fishy is going on here. Why are reps and rpe instantiated as nil, but become the empty string after adding additional empty sets?"
86 Added:
87 Added: sets doWithIndex: [ :set :i |
88 Added: html tableRow: [
89 Added: html tableData: [
90 Added: html buttonGroup: [
91 Added: html outlineButton
92 Added: beDanger;
93 Added: beSmall;
94 Added: callback: [ sets removeAt: i ];
95 Added: with: 'Remove'.
96 Added: html outlineButton
97 Added: beSecondary;
98 Added: beSmall;
99 Added: callback: [ sets add: set copy afterIndex: i ];
100 Added: with: 'Duplicate' ] ].
101 Added: html tableData: [
102 Added: html numberInput formControl
103 Added: value: set reps;
104 Added: callback: [ :value | set reps: value asInteger ] ].
105 Added: html tableData: [
106 Added: html numberInput formControl
107 Added: value: set weight;
108 Added: callback: [ :value |
109 Added: value
110 Added: ifNotEmpty: [ set weight: value asNumber ]
111 Added: ifEmpty: [ set weight: nil ] ] ].
112 Added: html tableData: [
113 Added: html numberInput formControl
114 Added: value: set rpe;
115 Added: callback: [ :value |
116 Added: value
117 Added: ifNotEmpty: [ set rpe: value asInteger ]
118 Added: ifEmpty: [ set rpe: nil ] ] ] ] ]
119 Added: ]
120 Added:
121 Added: { #category : #rendering }
122 Added: MFTExerciseDialogOld >> renderSetsTableOn: html [
123 Added:
124 Added: html formGroup: [
125 Added: html label: 'Sets'.
126 Added: html table
127 Added: class: 'table table-hover';
128 Added: with: [
129 Added: sets ifNotEmpty: [ self renderTableHeaderOn: html ].
130 Added: self renderSetsRowsOn: html.
131 Added: self renderAddSetRowOn: html ] ]
132 Added: ]
133 Added:
134 Added: { #category : #delegation }
135 Added: MFTExerciseDialogOld >> renderSubmitOn: html [
136 Added:
137 Added: html buttonGroup: [
138 Added: html formButton
139 Added: beSubmit;
140 Added: bePrimary;
141 Added: callback: [ self answer: (exercise sets: sets) ];
142 Added: with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]).
143 Added: html formButton
144 Added: beSubmit;
145 Added: beSecondary;
146 Added: callback: [ self answer: MFTExercise new ];
147 Added: with: (completion ifNil: [ 'Cancel' ] ifNotNil: [ 'Skip' ]) ]
148 Added: ]
149 Added:
150 Added: { #category : #rendering }
151 Added: MFTExerciseDialogOld >> renderTableHeaderOn: html [
152 Added:
153 Added: html tableHead: [
154 Added: html
155 Added: tableHeading;
156 Added: tableHeading: 'Reps';tableHeading: 'Weight';
157 Added: tableHeading: 'RPE' ]
158 Added: ]
159 Added:
160 Added: { #category : #accessing }
161 Added: MFTExerciseDialogOld >> sets [
162 Added:
163 Added: ^ sets
164 Added: ]
165 Added:
166 Added: { #category : #accessing }
167 Added: MFTExerciseDialogOld >> sets: anObject [
168 Added:
169 Added: sets := anObject
170 Added: ]
src/MyFitnessTracker/MFTExercisesDialog.class.st
index 00000000..634da467 000000..100644
@@ -0,0 +1,147 @@
1 Added: Class {
2 Added: #name : #MFTExercisesDialog,
3 Added: #superclass : #MFTDialog,
4 Added: #instVars : [
5 Added: 'exercises'
6 Added: ],
7 Added: #category : #'MyFitnessTracker-Dialog'
8 Added: }
9 Added:
10 Added: { #category : #actions }
11 Added: MFTExercisesDialog class >> edit: aMFTExerciseCollection [
12 Added:
13 Added: self halt.
14 Added: ^ self new
15 Added: exercises: aMFTExerciseCollection;
16 Added: action: #edit;
17 Added: yourself
18 Added: ]
19 Added:
20 Added: { #category : #adding }
21 Added: MFTExercisesDialog >> addExercise [
22 Added:
23 Added: | exercise |
24 Added: exercise := self call: MFTExerciseDialog new.
25 Added: exercise ifNotNil: [ exercises add: exercise ]
26 Added: ]
27 Added:
28 Added: { #category : #accessing }
29 Added: MFTExercisesDialog >> editExerciseAt: i [
30 Added:
31 Added: | oldExercise newExercise |
32 Added: oldExercise := exercises at: i.
33 Added: newExercise := self call: (MFTExerciseDialog edit: oldExercise).
34 Added: newExercise ifNotNil: [ exercises at: i put: newExercise ]
35 Added: ]
36 Added:
37 Added: { #category : #accessing }
38 Added: MFTExercisesDialog >> exercises [
39 Added:
40 Added: ^ exercises
41 Added: ]
42 Added:
43 Added: { #category : #accessing }
44 Added: MFTExercisesDialog >> exercises: aCollection [
45 Added:
46 Added: exercises := aCollection
47 Added: ]
48 Added:
49 Added: { #category : #initialization }
50 Added: MFTExercisesDialog >> initialize [
51 Added:
52 Added: super initialize.
53 Added: exercises := OrderedCollection new
54 Added: ]
55 Added:
56 Added: { #category : #rendering }
57 Added: MFTExercisesDialog >> renderAddExerciseRowOn: html [
58 Added:
59 Added: html buttonGroup: [
60 Added: html outlineButton
61 Added: bePrimary;
62 Added: beSmall;
63 Added: callback: [ self addExercise ];
64 Added: with: 'Add' ]
65 Added: ]
66 Added:
67 Added: { #category : #rendering }
68 Added: MFTExercisesDialog >> renderContentOn: html [
69 Added:
70 Added: self renderDialogOn: html with: [
71 Added: html table
72 Added: class: 'table table-hover';
73 Added: with: [ exercises ifNotEmpty: [ self renderExerciseTableOn: html ] ].
74 Added: self renderAddExerciseRowOn: html ]
75 Added: ]
76 Added:
77 Added: { #category : #rendering }
78 Added: MFTExercisesDialog >> renderExerciseActionsButtonGroupOn: html at: i [
79 Added:
80 Added: html buttonGroup: [
81 Added: html outlineButton
82 Added: beSecondary;
83 Added: beSmall;
84 Added: callback: [ exercises removeAt: i ];
85 Added: with: 'Delete'.
86 Added: html outlineButton
87 Added: beSecondary;
88 Added: beSmall;
89 Added: callback: [ self editExerciseAt: i ];
90 Added: with: 'Edit' ]
91 Added: ]
92 Added:
93 Added: { #category : #rendering }
94 Added: MFTExercisesDialog >> renderExerciseTableOn: html [
95 Added:
96 Added: self renderExercisesTableHeaderOn: html.
97 Added: exercises doWithIndex: [ :exercise :i |
98 Added: html tableRow: [
99 Added: html tableData: [
100 Added: self renderExerciseActionsButtonGroupOn: html at: i ].
101 Added: html tableData: exercise englishName.
102 Added: html tableData: exercise primaryMuscle englishName.
103 Added: ((exercises collect: #sets) anySatisfy: #isNotEmpty) ifTrue: [
104 Added: html tableData
105 Added: style: 'text-align: right';
106 Added: with: exercise repsBySet size ].
107 Added: ((exercises collect: #volume) anySatisfy: [ :volume | volume ~~ 0 ])
108 Added: ifTrue: [
109 Added: html tableData
110 Added: style: 'text-align: right';
111 Added: with: exercise volume ] ] ]
112 Added: ]
113 Added:
114 Added: { #category : #rendering }
115 Added: MFTExercisesDialog >> renderExercisesTableHeaderOn: html [
116 Added:
117 Added: html tableHead: [
118 Added: html
119 Added: tableHeading;
120 Added: tableHeading: 'Exercise';
121 Added: tableHeading: 'Primary Muscle'.
122 Added: ((exercises collect: #sets) anySatisfy: #isNotEmpty) ifTrue: [
123 Added: html tableHeading
124 Added: style: 'text-align: right';
125 Added: with: 'Sets' ].
126 Added: ((exercises collect: #volume) anySatisfy: [ :volume | volume ~~ 0 ])
127 Added: ifTrue: [
128 Added: html tableHeading
129 Added: style: 'text-align: right';
130 Added: with: 'Volume' ] ]
131 Added: ]
132 Added:
133 Added: { #category : #rendering }
134 Added: MFTExercisesDialog >> renderSubmitOn: html [
135 Added:
136 Added: html buttonGroup: [
137 Added: html formButton
138 Added: beSubmit;
139 Added: bePrimary;
140 Added: callback: [ self answer: exercises ];
141 Added: with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]).
142 Added: html formButton
143 Added: beSubmit;
144 Added: beSecondary;
145 Added: callback: [ self answer: OrderedCollection new ];
146 Added: with: (completion ifNil: [ 'Cancel' ] ifNotNil: [ 'Skip' ]) ]
147 Added: ]
src/MyFitnessTracker/MFTSet.class.st
index 2990905c..3ee7bcf6 100644..100644
@@ -124,12 +124,39 @@
124 124 (self new
125 125 id: 9;
126 126 workoutId: 3;
127 Removed: exerciseId: 12;
127 Added: exerciseId: 16;
128 128 groupId: 2;
129 129 number: 3;
130 130 reps: 5;
131 131 load: 100;
132 Removed: rpe: 10) }.
132 Added: rpe: 8).
133 Added: (self new
134 Added: id: 10;
135 Added: workoutId: 3;
136 Added: exerciseId: 17;
137 Added: groupId: 2;
138 Added: number: 4;
139 Added: reps: 5;
140 Added: load: 120;
141 Added: rpe: 9).
142 Added: (self new
143 Added: id: 11;
144 Added: workoutId: 3;
145 Added: exerciseId: 16;
146 Added: groupId: 2;
147 Added: number: 3;
148 Added: reps: 6;
149 Added: load: 110;
150 Added: rpe: 9).
151 Added: (self new
152 Added: id: 12;
153 Added: workoutId: 3;
154 Added: exerciseId: 17;
155 Added: groupId: 2;
156 Added: number: 4;
157 Added: reps: 5;
158 Added: load: 120;
159 Added: rpe: 9) }.
133 160
134 161 ^ OrderedCollection withAll: {
135 162 forWorkout1.
@@ -189,6 +216,12 @@
189 216
190 217 ^ MFTSQLite3Database allExercises detect: [ :exercise |
191 218 exercise id = exerciseId ]
219 Added: ]
220 Added:
221 Added: { #category : #accessing }
222 Added: MFTSet >> exercise: aMFTExercise [
223 Added:
224 Added: exerciseId := aMFTExercise id
192 225 ]
193 226
194 227 { #category : #accessing }
src/MyFitnessTracker/MFTSetDialog.class.st
index 27b2a5d3..c26e4434 100644..100644
@@ -20,57 +20,43 @@
20 20 MFTSetDialog >> initialize [
21 21
22 22 super initialize.
23 Removed: set := MFTSet new
23 Added: set := MFTSet new reps: 8
24 24 ]
25 25
26 26 { #category : #rendering }
27 27 MFTSetDialog >> renderContentOn: html [
28 28
29 29 self renderDialogOn: html with: [
30 Removed: self renderExerciseSelectOn: html.
31 Removed: html formGroup: [
32 Removed: html label: 'Reps'.
33 Removed: html numberInput formControl
34 Removed: value: set reps;
35 Removed: callback: [ :value | set reps: value asInteger ] ].
36 Removed: html formGroup: [
37 Removed: html label: 'Load'.
38 Removed: html numberInput formControl
39 Removed: value: set load;
40 Removed: callback: [ :value |
41 Removed: value ifNotEmpty: [ set load: value asNumber ] ] ].
42 Removed: html formGroup: [
43 Removed: html label: 'RPE'.
44 Removed: html numberInput formControl
45 Removed: value: set rpe;
46 Removed: callback: [ :value |
47 Removed: value ifNotEmpty: [ set rpe: value asInteger ] ] ].
48 Removed: html formGroup: [
49 Removed: html label: 'Rest after (s)'.
50 Removed: html numberInput formControl
51 Removed: value: set restAfter;
52 Removed: callback: [ :value |
53 Removed: value ifNotEmpty: [ set restAfter: value asNumber ] ] ] ]
30 Added: html table: [
31 Added: html tableRow: [
32 Added: html tableHeading: 'Reps'.
33 Added: html tableData: [
34 Added: html numberInput formControl
35 Added: value: set reps;
36 Added: callback: [ :value | set reps: value asInteger ] ] ].
37 Added: html tableRow: [
38 Added: html tableHeading: 'Load'.
39 Added: html tableData: [
40 Added: html numberInput formControl
41 Added: value: set load;
42 Added: callback: [ :value |
43 Added: value ifNotEmpty: [ set load: value asNumber ] ] ] ].
44 Added: html tableRow: [
45 Added: html tableHeading: 'RPE'.
46 Added: html tableData: [
47 Added: html numberInput formControl
48 Added: value: set rpe;
49 Added: callback: [ :value |
50 Added: value ifNotEmpty: [ set rpe: value asInteger ] ] ] ].
51 Added: html tableRow: [
52 Added: html tableHeading: 'Rest after (s)'.
53 Added: html tableData: [
54 Added: html numberInput formControl
55 Added: value: set restAfter;
56 Added: callback: [ :value |
57 Added: value ifNotEmpty: [ set restAfter: value asNumber ] ] ] ] ] ]
54 58 ]
55 59
56 Removed: { #category : #rendering }
57 Removed: MFTSetDialog >> renderExerciseSelectOn: html [
58 Removed:
59 Removed: | allExercises selectedExercise |
60 Removed: allExercises := MFTSQLite3Database allExercises.
61 Removed: selectedExercise := allExercises
62 Removed: detect: [ :exercise |
63 Removed: exercise id = set exerciseId ]
64 Removed: ifNone: [ nil ].
65 Removed: html formGroup: [
66 Removed: html label: 'Exercise'.
67 Removed: html select formControl
68 Removed: list: allExercises;
69 Removed: selected: selectedExercise;
70 Removed: callback: [ :exercise | set exerciseId: exercise id ];
71 Removed: labels: [ :exercise | exercise englishName ] ]
72 Removed: ]
73 Removed:
74 60 { #category : #delegation }
75 61 MFTSetDialog >> renderSubmitOn: html [
76 62
@@ -78,25 +64,13 @@
78 64 html formButton
79 65 beSubmit;
80 66 bePrimary;
81 Removed: callback: [
82 Removed: self answer: (set reps ifNotNil: [ set ] ifNil: [ nil ]) ];
67 Added: callback: [ self answer: (set reps ifNotNil: [ set ]) ];
83 68 with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]).
84 69 html formButton
85 70 beSubmit;
86 71 beSecondary;
87 72 callback: [ self answer: nil ];
88 73 with: (completion ifNil: [ 'Cancel' ] ifNotNil: [ 'Skip' ]) ]
89 Removed: ]
90 Removed:
91 Removed: { #category : #rendering }
92 Removed: MFTSetDialog >> renderTableHeaderOn: html [
93 Removed:
94 Removed: html tableHead: [
95 Removed: html
96 Removed: tableHeading;
97 Removed: tableHeading: 'Reps';
98 Removed: tableHeading: 'Weight';
99 Removed: tableHeading: 'RPE' ]
100 74 ]
101 75
102 76 { #category : #accessing }
src/MyFitnessTracker/MFTSetGroup.class.st
index 1b9bf64f..c3203dfc 100644..100644
@@ -17,6 +17,62 @@
17 17 yourself
18 18 ]
19 19
20 Added: { #category : #adding }
21 Added: MFTSetGroup >> addSet: aMFTSet [
22 Added:
23 Added: sets add: aMFTSet
24 Added: ]
25 Added:
26 Added: { #category : #initialization }
27 Added: MFTSetGroup >> description [
28 Added:
29 Added: self isSuperset ifTrue: [
30 Added: | ex1 ex2 |
31 Added: ex1 := sets first exercise.
32 Added: ex2 := sets second exercise.
33 Added: ex1 primaryMuscleGroupId = ex2 primaryMuscleGroupId ifTrue: [
34 Added: ^ 'agonist superset ({1})' format:
35 Added: { ex1 primaryMuscleGroup englishName } ].
36 Added: (MFTMuscleGroup antagonistIds includes: {
37 Added: ex1 primaryMuscleGroupId.
38 Added: ex2 primaryMuscleGroupId } asSet) ifTrue: [
39 Added: ^ 'antagonist superset' ].
40 Added: ^ 'superset' ].
41 Added: self isTriSet ifTrue: [ ^ 'tri-set' ].
42 Added: self isGiantSet ifTrue: [ ^ 'giant set' ].
43 Added: ^ 'regular set'
44 Added: ]
45 Added:
46 Added: { #category : #'as yet unclassified' }
47 Added: MFTSetGroup >> duplicateSet: aMFTSet [
48 Added:
49 Added: sets add: aMFTSet after: aMFTSet
50 Added: ]
51 Added:
52 Added: { #category : #testing }
53 Added: MFTSetGroup >> hasLoad [
54 Added:
55 Added: ^ sets anySatisfy: #hasLoad
56 Added: ]
57 Added:
58 Added: { #category : #testing }
59 Added: MFTSetGroup >> hasRestAfter [
60 Added:
61 Added: ^ sets anySatisfy: #hasRestAfter
62 Added: ]
63 Added:
64 Added: { #category : #testing }
65 Added: MFTSetGroup >> hasRpe [
66 Added:
67 Added: ^ sets anySatisfy: #hasRpe
68 Added: ]
69 Added:
70 Added: { #category : #testing }
71 Added: MFTSetGroup >> hasVolume [
72 Added:
73 Added: ^ sets anySatisfy: #hasVolume
74 Added: ]
75 Added:
20 76 { #category : #accessing }
21 77 MFTSetGroup >> id [
22 78
@@ -37,23 +93,47 @@
37 93 ]
38 94
39 95 { #category : #testing }
40 Removed: MFTSetGroup >> isGiantset [
96 Added: MFTSetGroup >> isGiantSet [
41 97
42 98 ^ self uniqueExercisesInSets >= 4
43 99 ]
44 100
45 101 { #category : #testing }
102 Added: MFTSetGroup >> isIrregularSetGroup [
103 Added:
104 Added: ^ self isRegularSetGroup not
105 Added: ]
106 Added:
107 Added: { #category : #testing }
108 Added: MFTSetGroup >> isRegularSetGroup [
109 Added:
110 Added: ^ self uniqueExercisesInSets = 1
111 Added: ]
112 Added:
113 Added: { #category : #testing }
46 114 MFTSetGroup >> isSuperset [
47 115
48 116 ^ self uniqueExercisesInSets = 2
49 117 ]
50 118
51 119 { #category : #testing }
52 Removed: MFTSetGroup >> isTriset [
120 Added: MFTSetGroup >> isTriSet [
53 121
54 122 ^ self uniqueExercisesInSets = 3
55 123 ]
56 124
125 Added: { #category : #adding }
126 Added: MFTSetGroup >> removeSet: aMFTSet [
127 Added:
128 Added: sets remove: aMFTSet
129 Added: ]
130 Added:
131 Added: { #category : #adding }
132 Added: MFTSetGroup >> removeSets: aMFTSetCollection [
133 Added:
134 Added: sets removeAll: aMFTSetCollection
135 Added: ]
136 Added:
57 137 { #category : #accessing }
58 138 MFTSetGroup >> sets [
59 139
@@ -69,20 +149,9 @@
69 149 { #category : #initialization }
70 150 MFTSetGroup >> type [
71 151
72 Removed: self isSuperset ifTrue: [
73 Removed: | ex1 ex2 |
74 Removed: ex1 := sets first exercise.
75 Removed: ex2 := sets second exercise.
76 Removed: ex1 primaryMuscleGroupId = ex2 primaryMuscleGroupId ifTrue: [
77 Removed: ^ 'agonist superset ({1})' format:
78 Removed: { ex1 primaryMuscleGroup englishName } ].
79 Removed: (MFTMuscleGroup antagonistIds includes: {
80 Removed: ex1 primaryMuscleGroupId.
81 Removed: ex2 primaryMuscleGroupId } asSet) ifTrue: [
82 Removed: ^ 'antagonist superset' ].
83 Removed: ^ 'superset' ].
84 Removed: self isTriset ifTrue: [ ^ 'tri-set' ].
85 Removed: self isGiantset ifTrue: [ ^ 'giant set' ].
152 Added: self isSuperset ifTrue: [ ^ 'superset' ].
153 Added: self isTriSet ifTrue: [ ^ 'tri-set' ].
154 Added: self isGiantSet ifTrue: [ ^ 'giant set' ].
86 155 ^ 'regular set'
87 156 ]
88 157
@@ -93,4 +162,16 @@
93 162 | uniqueExerciseIds |
94 163 uniqueExerciseIds := (sets collect: #exerciseId) asSet.
95 164 ^ uniqueExerciseIds size
165 Added: ]
166 Added:
167 Added: { #category : #'as yet unclassified' }
168 Added: MFTSetGroup >> updateSet: aMFTSet1 with: aMFTSet2 [
169 Added:
170 Added: sets at: (sets indexOf: aMFTSet1) put: aMFTSet2
171 Added: ]
172 Added:
173 Added: { #category : #'as yet unclassified' }
174 Added: MFTSetGroup >> volume [
175 Added:
176 Added: ^ (sets collect: #volume) sum
96 177 ]
src/MyFitnessTracker/MFTSetGroupDialog.class.st
index 00000000..2ae7e2b6 000000..100644
@@ -0,0 +1,304 @@
1 Added: Class {
2 Added: #name : #MFTSetGroupDialog,
3 Added: #superclass : #MFTDialog,
4 Added: #instVars : [
5 Added: 'allExercises',
6 Added: 'selectedExercises',
7 Added: 'setGroups'
8 Added: ],
9 Added: #category : #'MyFitnessTracker-Dialog'
10 Added: }
11 Added:
12 Added: { #category : #adding }
13 Added: MFTSetGroupDialog >> addSet [
14 Added:
15 Added: | set |
16 Added: set := self call: MFTSetDialog new.
17 Added: set ifNil: [ ^ self ].
18 Added: setGroups ifEmpty: [
19 Added: setGroups := OrderedCollection with: MFTSetGroup new ].
20 Added: setGroups first addSet: (set exercise: selectedExercises first)
21 Added: ]
22 Added:
23 Added: { #category : #adding }
24 Added: MFTSetGroupDialog >> addSetGroup: aMFTExerciseCollection [
25 Added:
26 Added: | sets |
27 Added: sets := self call:
28 Added: ((MFTSetsDialog newForIrregularSetGroup:
29 Added: aMFTExerciseCollection) subheading:
30 Added: ((selectedExercises collect: #englishName) joinUsing: '/')).
31 Added: sets ifEmpty: [ ^ self ].
32 Added: setGroups add: (MFTSetGroup new sets: sets)
33 Added: ]
34 Added:
35 Added: { #category : #'as yet unclassified' }
36 Added: MFTSetGroupDialog >> duplicateSetGroup: aMFTSetGroup [
37 Added:
38 Added: setGroups add: aMFTSetGroup after: aMFTSetGroup
39 Added: ]
40 Added:
41 Added: { #category : #actions }
42 Added: MFTSetGroupDialog >> edit: aMFTSetGroup [
43 Added:
44 Added: nil
45 Added: ]
46 Added:
47 Added: { #category : #actions }
48 Added: MFTSetGroupDialog >> editSetGroup: aMFTSetGroup [
49 Added:
50 Added: | setOrGroup |
51 Added: setOrGroup := aMFTSetGroup isRegularSetGroup
52 Added: ifTrue: [
53 Added: self call: (MFTSetDialog edit: aMFTSetGroup) ]
54 Added: ifFalse: [
55 Added: self call: (MFTSetsDialog edit: aMFTSetGroup) ]
56 Added: ]
57 Added:
58 Added: { #category : #initialization }
59 Added: MFTSetGroupDialog >> initialize [
60 Added:
61 Added: super initialize.
62 Added: setGroups := OrderedCollection with:
63 Added: (MFTSetGroup new sets:
64 Added: (OrderedCollection with: (MFTSet new reps: 8))).
65 Added: allExercises := MFTSQLite3Database allExercises.
66 Added: selectedExercises := OrderedCollection with: allExercises first
67 Added: ]
68 Added:
69 Added: { #category : #rendering }
70 Added: MFTSetGroupDialog >> makeGiantSet [
71 Added:
72 Added: self heading: 'Giant Sets'.
73 Added: selectedExercises := OrderedCollection withAll:
74 Added: (allExercises copyFrom: 1 to: 5).
75 Added: setGroups first sets: (selectedExercises collect: [ :exercise |
76 Added: MFTSet new
77 Added: reps: 8;
78 Added: exercise: exercise ])
79 Added: ]
80 Added:
81 Added: { #category : #rendering }
82 Added: MFTSetGroupDialog >> makeRegularExercise [
83 Added:
84 Added: self heading: 'Sets'.
85 Added: selectedExercises := OrderedCollection with: allExercises first.
86 Added: self populateSetGroupsForExercises: selectedExercises
87 Added: ]
88 Added:
89 Added: { #category : #rendering }
90 Added: MFTSetGroupDialog >> makeSuperset [
91 Added:
92 Added: self heading: 'Supersets'.
93 Added: selectedExercises := OrderedCollection
94 Added: with: allExercises first
95 Added: with: allExercises second.
96 Added: self populateSetGroupsForExercises: selectedExercises
97 Added: ]
98 Added:
99 Added: { #category : #rendering }
100 Added: MFTSetGroupDialog >> makeTriset [
101 Added:
102 Added: self heading: 'Tri-sets'.
103 Added: selectedExercises := OrderedCollection
104 Added: with: allExercises first
105 Added: with: allExercises second
106 Added: with: allExercises third.
107 Added: self populateSetGroupsForExercises: selectedExercises
108 Added: ]
109 Added:
110 Added: { #category : #'as yet unclassified' }
111 Added: MFTSetGroupDialog >> populateSetGroupsForExercises: aMFTExerciseCollection [
112 Added:
113 Added: setGroups := OrderedCollection with:
114 Added: (MFTSetGroup new sets:
115 Added: (aMFTExerciseCollection collect: [ :exercise |
116 Added: MFTSet new
117 Added: reps: 8;
118 Added: exercise: exercise ]))
119 Added: ]
120 Added:
121 Added: { #category : #removing }
122 Added: MFTSetGroupDialog >> removeSetGroup: aMFTSetGroup [
123 Added:
124 Added: setGroups remove: aMFTSetGroup
125 Added: ]
126 Added:
127 Added: { #category : #rendering }
128 Added: MFTSetGroupDialog >> renderConfigureSetGroupButtonsOn: html [
129 Added:
130 Added: selectedExercises size = 1
131 Added: ifTrue: [
132 Added: html outlineButton bePrimary beSmall
133 Added: class: 'me-2';
134 Added: callback: [ self addSet ];
135 Added: with: 'Add set' ]
136 Added: ifFalse: [
137 Added: html outlineButton bePrimary beSmall
138 Added: class: 'me-2';
139 Added: callback: [ self addSetGroup: selectedExercises ];
140 Added: with: 'Add set group' ].
141 Added: html buttonGroup: [
142 Added: selectedExercises size ~~ 1 ifTrue: [
143 Added: html outlineButton beSecondary beSmall
144 Added: callback: [ self makeRegularExercise ];
145 Added: with: 'Regular exercise' ].
146 Added: selectedExercises size ~~ 2 ifTrue: [
147 Added: html outlineButton beSecondary beSmall
148 Added: callback: [ self makeSuperset ];
149 Added: with: 'Superset' ].
150 Added: selectedExercises size ~~ 3 ifTrue: [
151 Added: html outlineButton beSecondary beSmall
152 Added: callback: [ self makeTriset ];
153 Added: with: 'Tri-set' ].
154 Added: selectedExercises size < 4 ifTrue: [
155 Added: html outlineButton beSecondary beSmall
156 Added: callback: [ self makeGiantSet ];
157 Added: with: 'Giant set' ] ]
158 Added: ]
159 Added:
160 Added: { #category : #rendering }
161 Added: MFTSetGroupDialog >> renderContentOn: html [
162 Added:
163 Added: self renderDialogOn: html with: [
164 Added: self renderSelectExercisesOn: html.
165 Added: html horizontalRule.
166 Added: (setGroups collect: #sets) ifNotEmpty: [
167 Added: self renderSetGroupTableOn: html ].
168 Added: self renderConfigureSetGroupButtonsOn: html ]
169 Added: ]
170 Added:
171 Added: { #category : #rendering }
172 Added: MFTSetGroupDialog >> renderSelectExercisesOn: html [
173 Added: " selectedExercises := allExercises
174 Added: detect: [ :exercise |
175 Added: exercise id = selectedExercise id ]
176 Added: ifNone: [ allExercises first ]."
177 Added:
178 Added: selectedExercises doWithIndex: [ :selectedExercise :i |
179 Added: html formGroup: [
180 Added: html label: 'Exercise ' , (selectedExercises size > 1
181 Added: ifTrue: [ i asString ]
182 Added: ifFalse: [ '' ]).
183 Added: html select formControl
184 Added: list: allExercises;
185 Added: selected: selectedExercise;
186 Added: callback: [ :exercise | selectedExercises at: i put: exercise ];
187 Added: labels: [ :each | each englishName ] ] ]
188 Added: ]
189 Added:
190 Added: { #category : #rendering }
191 Added: MFTSetGroupDialog >> renderSetGroupRowsOn: html [
192 Added:
193 Added: | renderLoad |
194 Added: renderLoad := setGroups anySatisfy: #hasLoad.
195 Added: setGroups do: [ :group |
196 Added: html tableRow with: [
197 Added: html tableData
198 Added: attributeAt: 'rowspan' put: group sets size + 1;
199 Added: style: 'vertical-align: middle';
200 Added: with: [
201 Added: html buttonGroup: [
202 Added: html outlineButton
203 Added: beDanger;
204 Added: beSmall;
205 Added: callback: [ self removeSetGroup: group ];
206 Added: with: 'Remove'.
207 Added: html outlineButton
208 Added: beSecondary;
209 Added: beSmall;
210 Added: callback: [ self editSetGroup: group ];
211 Added: with: 'Edit'.
212 Added: html outlineButton
213 Added: beSecondary;
214 Added: beSmall;
215 Added: callback: [ self duplicateSetGroup: group ];
216 Added: with: 'Duplicate' ] ] ].
217 Added: group sets do: [ :set |
218 Added: html tableRow: [ "This row spans the amount of sets for a given exercise."
219 Added: group isIrregularSetGroup ifTrue: [
220 Added: html tableData with: set exercise englishName capitalized ].
221 Added: html tableData
222 Added: style: 'text-align: right';
223 Added: with: set reps.
224 Added: renderLoad ifTrue: [
225 Added: html tableData
226 Added: style: 'text-align: right';
227 Added: with: set load ] ] ] ]
228 Added: ]
229 Added:
230 Added: { #category : #rendering }
231 Added: MFTSetGroupDialog >> renderSetGroupTableHeaderOn: html [
232 Added:
233 Added: | allSets |
234 Added: allSets := setGroups collect: #sets.
235 Added: html tableHead: [
236 Added: html tableHeading.
237 Added: (setGroups anySatisfy: #isIrregularSetGroup) ifTrue: [
238 Added: html tableHeading with: 'Exercise' ].
239 Added: html tableHeading
240 Added: style: 'text-align: right';
241 Added: with: 'Reps'.
242 Added: (setGroups anySatisfy: #hasLoad) ifTrue: [
243 Added: html tableHeading
244 Added: style: 'text-align: right';
245 Added: with: 'Load' ].
246 Added: (setGroups anySatisfy: #hasRpe) ifTrue: [
247 Added: html tableHeading
248 Added: style: 'text-align: right';
249 Added: with: 'RPE' ].
250 Added: (setGroups anySatisfy: #hasRestAfter) ifTrue: [
251 Added: html tableHeading
252 Added: style: 'text-align: right';
253 Added: with: 'Rest After (s)' ] ]
254 Added: ]
255 Added:
256 Added: { #category : #rendering }
257 Added: MFTSetGroupDialog >> renderSetGroupTableOn: html [
258 Added:
259 Added: html table
260 Added: class: 'table table-bordered';
261 Added: with: [
262 Added: self renderSetGroupTableHeaderOn: html.
263 Added: self renderSetGroupRowsOn: html ]
264 Added: ]
265 Added:
266 Added: { #category : #rendering }
267 Added: MFTSetGroupDialog >> renderSubmitOn: html [
268 Added:
269 Added: html buttonGroup: [
270 Added: html formButton
271 Added: beSubmit;
272 Added: bePrimary;
273 Added: callback: [ self answer: setGroups ];
274 Added: with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]).
275 Added: html formButton
276 Added: beSubmit;
277 Added: beSecondary;
278 Added: callback: [ self answer: nil ];
279 Added: with: (completion ifNil: [ 'Cancel' ] ifNotNil: [ 'Skip' ]) ]
280 Added: ]
281 Added:
282 Added: { #category : #accessing }
283 Added: MFTSetGroupDialog >> selectedExercises [
284 Added:
285 Added: ^ selectedExercises
286 Added: ]
287 Added:
288 Added: { #category : #accessing }
289 Added: MFTSetGroupDialog >> selectedExercises: aMFTExerciseCollection [
290 Added:
291 Added: selectedExercises := aMFTExerciseCollection
292 Added: ]
293 Added:
294 Added: { #category : #accessing }
295 Added: MFTSetGroupDialog >> setGroups [
296 Added:
297 Added: ^ setGroups
298 Added: ]
299 Added:
300 Added: { #category : #accessing }
301 Added: MFTSetGroupDialog >> setGroups: anObject [
302 Added:
303 Added: setGroups := anObject
304 Added: ]
src/MyFitnessTracker/MFTSetGroupsDialog.class.st
index 87c0fade..982894b3 100644..100644
@@ -17,27 +17,13 @@
17 17 ]
18 18
19 19 { #category : #adding }
20 Removed: MFTSetGroupsDialog >> addSetGroup [
20 Added: MFTSetGroupsDialog >> addExercise [
21 21
22 Removed: | setGroup setsSize |
23 Removed: setsSize := setGroups size + 1.
24 Removed: setGroup := self call:
25 Removed: (MFTSetDialog new heading: 'Set #' , setsSize asString).
26 Removed: setGroup ifNil: [ ^ self ].
27 Removed: setGroup
28 Removed: number: setsSize;
29 Removed: group: setsSize.
30 Removed: setGroup add: setGroup
22 Added: | setGroup |
23 Added: setGroup := self call: (MFTSetGroupDialog new heading: 'Exercise').
24 Added: setGroup ifNotNil: [ setGroups add: setGroup ]
31 25 ]
32 26
33 Removed: { #category : #adding }
34 Removed: MFTSetGroupsDialog >> addSuperset [
35 Removed:
36 Removed: | superset |
37 Removed: superset := self call: MFTSupersetDialog new.
38 Removed: superset ifNotNil: [ setGroups add: superset ]
39 Removed: ]
40 Removed:
41 27 { #category : #initialization }
42 28 MFTSetGroupsDialog >> initialize [
43 29
@@ -46,24 +32,13 @@
46 32 ]
47 33
48 34 { #category : #rendering }
49 Removed: MFTSetGroupsDialog >> renderAddSetGroupsButtonsOn: html [
35 Added: MFTSetGroupsDialog >> renderAddSetGroupButtonsOn: html [
50 36
51 Removed: html buttonGroup: [
52 Removed: html outlineButton
53 Removed: bePrimary;
54 Removed: beSmall;
55 Removed: callback: [ self addSetGroup ];
56 Removed: with: 'Add exercise'.
57 Removed: html outlineButton
58 Removed: beSecondary;
59 Removed: beSmall;
60 Removed: callback: [ self addSuperset ];
61 Removed: with: 'Add superset'.
62 Removed: html outlineButton
63 Removed: beSecondary;
64 Removed: beSmall;
65 Removed: callback: [ self addSuperset ];
66 Removed: with: 'Add tri-set' ]
37 Added: html outlineButton
38 Added: bePrimary;
39 Added: beSmall;
40 Added: callback: [ self addExercise ];
41 Added: with: 'Add exercise'
67 42 ]
68 43
69 44 { #category : #rendering }
@@ -71,7 +46,7 @@
71 46
72 47 self renderDialogOn: html with: [
73 48 setGroups ifNotEmpty: [ self renderSetsTableOn: html ].
74 Removed: self renderAddSetGroupsButtonsOn: html ]
49 Added: self renderAddSetGroupButtonsOn: html ]
75 50 ]
76 51
77 52 { #category : #rendering }
@@ -93,32 +68,58 @@
93 68 ]
94 69
95 70 { #category : #rendering }
96 Removed: MFTSetGroupsDialog >> renderSetsRowsOn: html [
71 Added: MFTSetGroupsDialog >> renderSetGroupButtonsOn: html For: setGroup [
97 72
73 Added: ^ html buttonGroup: [
74 Added: html outlineButton
75 Added: beDanger;
76 Added: beSmall;
77 Added: callback: [ setGroups remove: setGroup ];
78 Added: with: 'Remove'.
79 Added: html outlineButton
80 Added: beSecondary;
81 Added: beSmall;
82 Added: callback: [
83 Added: setGroups
84 Added: add: setGroup
85 Added: afterIndex: (setGroups indexOf: setGroup) ];
86 Added: with: 'Duplicate' ]
87 Added: ]
88 Added:
89 Added: { #category : #rendering }
90 Added: MFTSetGroupsDialog >> renderSetGroupsRowsOn: html [
91 Added:
98 92 | renderLoad renderRpe renderRestAfter |
99 93 renderLoad := self renderLoad.
100 94 renderRpe := self renderRpe.
101 95 renderRestAfter := self renderRestAfter.
102 96 setGroups do: [ :setGroup |
103 Removed: html tableRow: [
104 Removed: html tableData: [
105 Removed: html buttonGroup: [
106 Removed: html outlineButton
107 Removed: beDanger;
108 Removed: beSmall;
109 Removed: callback: [ setGroups remove: setGroup ];
110 Removed: with: 'Remove'.
111 Removed: html outlineButton
112 Removed: beSecondary;
113 Removed: beSmall;
114 Removed: callback: [
115 Removed: setGroups
116 Removed: add: setGroup
117 Removed: afterIndex: (setGroups indexOf: setGroup) ];
118 Removed: with: 'Duplicate' ] ] ] ]
97 Added: html tableRow
98 Added: attributeAt: 'rowspan' put: setGroup sets size + 1;
99 Added: with: [
100 Added: html tableData: [
101 Added: self renderSetGroupButtonsOn: html For: setGroup ] ].
102 Added: setGroup sets do: [ :set |
103 Added: html tableRow: [
104 Added: html tableData.
105 Added: html tableData: set exercise englishName.
106 Added: html tableData: set reps ] ] ]
119 107 ]
120 108
121 109 { #category : #rendering }
110 Added: MFTSetGroupsDialog >> renderSetGroupsTableHeaderOn: html [
111 Added:
112 Added: html tableHead: [
113 Added: html
114 Added: tableHeading;
115 Added: tableHeading: 'Exercise';
116 Added: tableHeading: 'Reps'.
117 Added: self renderLoad ifTrue: [ html tableHeading: 'Load' ].
118 Added: self renderRpe ifTrue: [ html tableHeading: 'RPE' ].
119 Added: self renderRestAfter ifTrue: [ html tableHeading: 'Rest after (s) ' ] ]
120 Added: ]
121 Added:
122 Added: { #category : #rendering }
122 123 MFTSetGroupsDialog >> renderSetsTableHeaderOn: html [
123 124
124 125 html tableHead: [
@@ -137,8 +138,8 @@
137 138 html table
138 139 class: 'table table-hover table-bordered';
139 140 with: [
140 Removed: self renderSetsTableHeaderOn: html.
141 Removed: self renderSetsRowsOn: html ]
141 Added: self renderSetGroupsTableHeaderOn: html.
142 Added: self renderSetGroupsRowsOn: html ]
142 143 ]
143 144
144 145 { #category : #rendering }
src/MyFitnessTracker/MFTSetsDialog.class.st
index 00000000..226592f2 000000..100644
@@ -0,0 +1,101 @@
1 Added: Class {
2 Added: #name : #MFTSetsDialog,
3 Added: #superclass : #MFTDialog,
4 Added: #instVars : [
5 Added: 'sets'
6 Added: ],
7 Added: #category : #'MyFitnessTracker-Dialog'
8 Added: }
9 Added:
10 Added: { #category : #actions }
11 Added: MFTSetsDialog class >> edit: aMFTSetCollection [
12 Added:
13 Added: ^ self new
14 Added: sets: aMFTSetCollection;
15 Added: action: #edit;
16 Added: yourself
17 Added: ]
18 Added:
19 Added: { #category : #actions }
20 Added: MFTSetsDialog class >> newForIrregularSetGroup: aMFTExerciseCollection [
21 Added:
22 Added: ^ self new
23 Added: sets: (aMFTExerciseCollection collect: [ :exercise |
24 Added: MFTSet new
25 Added: reps: 8;
26 Added: exercise: exercise ]);
27 Added: yourself
28 Added: ]
29 Added:
30 Added: { #category : #initialization }
31 Added: MFTSetsDialog >> initialize [
32 Added:
33 Added: super initialize.
34 Added: sets := OrderedCollection new
35 Added: ]
36 Added:
37 Added: { #category : #rendering }
38 Added: MFTSetsDialog >> renderContentOn: html [
39 Added:
40 Added: self renderDialogOn: html with: [
41 Added: html table
42 Added: class: 'table table-bordered';
43 Added: with: [
44 Added: html tableRow: [
45 Added: html
46 Added: tableHeading: 'Exercise';
47 Added: tableHeading: 'Reps';
48 Added: tableHeading: 'Load';
49 Added: tableHeading: 'RPE';
50 Added: tableHeading: 'Rest after (s)' ].
51 Added: sets do: [ :set |
52 Added: html tableRow: [
53 Added: html tableData: set exercise englishName.
54 Added: html tableData: [
55 Added: html numberInput formControl
56 Added: value: set reps;
57 Added: callback: [ :value | set reps: value asInteger ] ].
58 Added: html tableData: [
59 Added: html numberInput formControl
60 Added: value: set load;
61 Added: callback: [ :value |
62 Added: value ifNotEmpty: [ set load: value asNumber ] ] ].
63 Added: html tableData: [
64 Added: html numberInput formControl
65 Added: value: set rpe;
66 Added: callback: [ :value |
67 Added: value ifNotEmpty: [ set rpe: value asInteger ] ] ].
68 Added: html tableData: [
69 Added: html numberInput formControl
70 Added: value: set restAfter;
71 Added: callback: [ :value |
72 Added: value ifNotEmpty: [ set restAfter: value asNumber ] ] ] ] ] ] ]
73 Added: ]
74 Added:
75 Added: { #category : #delegation }
76 Added: MFTSetsDialog >> renderSubmitOn: html [
77 Added:
78 Added: html buttonGroup: [
79 Added: html formButton
80 Added: beSubmit;
81 Added: bePrimary;
82 Added: callback: [ self answer: sets ];
83 Added: with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]).
84 Added: html formButton
85 Added: beSubmit;
86 Added: beSecondary;
87 Added: callback: [ self answer: nil ];
88 Added: with: (completion ifNil: [ 'Cancel' ] ifNotNil: [ 'Skip' ]) ]
89 Added: ]
90 Added:
91 Added: { #category : #accessing }
92 Added: MFTSetsDialog >> sets [
93 Added:
94 Added: ^ sets
95 Added: ]
96 Added:
97 Added: { #category : #accessing }
98 Added: MFTSetsDialog >> sets: anObject [
99 Added:
100 Added: sets := anObject
101 Added: ]
src/MyFitnessTracker/MFTWorkout.class.st
index 08ddd887..7a302a21 100644..100644
@@ -62,6 +62,18 @@
62 62 ]
63 63
64 64 { #category : #'as yet unclassified' }
65 Added: MFTWorkout >> allSetGroupsAreRegular [
66 Added:
67 Added: ^ self anySetGroupIsIrregular not
68 Added: ]
69 Added:
70 Added: { #category : #'as yet unclassified' }
71 Added: MFTWorkout >> anySetGroupIsIrregular [
72 Added:
73 Added: ^ setGroups anySatisfy: [ :group | group isRegularSetGroup not ]
74 Added: ]
75 Added:
76 Added: { #category : #'as yet unclassified' }
65 77 MFTWorkout >> anySetHasLoad [
66 78
67 79 ^ self sets anySatisfy: #hasLoad
@@ -155,63 +167,68 @@
155 167 ]
156 168
157 169 { #category : #rendering }
158 Removed: MFTWorkout >> renderSetGroupsTableOn: html [
170 Added: MFTWorkout >> renderSetGroupRowsOn: html [
159 171
160 Removed: | renderLoad renderVolume |
172 Added: | renderSetGroupsType renderLoad renderVolume |
173 Added: "No need to render the type of set group, if it is regular."
174 Added: renderSetGroupsType := self allSetGroupsAreRegular not.
161 175 renderLoad := self anySetHasLoad.
162 176 renderVolume := self anySetHasVolume.
163 177
164 Removed: html table
165 Removed: class: 'table table-bordered';
166 Removed: with: [
167 Removed: self renderSetsTableHeaderOn: html.
168 Removed: self setGroups do: [ :group |
169 Removed: html tableRow: [
170 Removed: html tableHeading
171 Removed: attributeAt: 'rowspan' put: group sets size + 1;
172 Removed: style: 'vertical-align: middle';
173 Removed: with: [ html text: group type capitalized ] ].
174 Removed: group sets do: [ :set |
175 Removed: html tableRow: [
176 Removed: html tableData: set exercise englishName capitalized.
177 Removed: html tableData
178 Removed: style: 'text-align: right';
179 Removed: with: set reps.
180 Removed: renderLoad ifTrue: [
181 Removed: html tableData
182 Removed: style: 'text-align: right';
183 Removed: with: set load ].
184 Removed: renderVolume ifTrue: [
185 Removed: html tableData
186 Removed: style: 'text-align: right';
187 Removed: with: set volume ] ] ] ].
188 Removed: self renderSetsTableFooterOn: html ]
178 Added: self setGroups do: [ :group |
179 Added: | setsGroupedByExercise |
180 Added: setsGroupedByExercise := group sets groupedBy: #exercise.
181 Added: renderSetGroupsType ifTrue: [
182 Added: html tableRow: [ "This row spans the amount of sets for this group + the amount of exercises + 1."
183 Added: html tableHeading
184 Added: attributeAt: 'rowspan'
185 Added: put: group sets size + setsGroupedByExercise keys size + 1;
186 Added: style: 'vertical-align: middle';
187 Added: with: [ html text: group type capitalized ] ] ].
188 Added: setsGroupedByExercise keysAndValuesDo: [ :exercise :sets |
189 Added: html tableRow: [ "This row spans the amount of sets for a given exercise."
190 Added: html tableData
191 Added: attributeAt: 'rowspan' put: sets size + 1;
192 Added: style: 'vertical-align: middle';
193 Added: with: exercise englishName capitalized ].
194 Added: sets do: [ :set |
195 Added: html tableRow: [
196 Added: html tableData
197 Added: style: 'text-align: right';
198 Added: with: set reps.
199 Added: renderLoad ifTrue: [
200 Added: html tableData
201 Added: style: 'text-align: right';
202 Added: with: set load ].
203 Added: renderVolume ifTrue: [
204 Added: html tableData
205 Added: style: 'text-align: right';
206 Added: with: set volume ] ] ] ] ]
189 207 ]
190 208
191 209 { #category : #rendering }
192 Removed: MFTWorkout >> renderSetsTableFooterOn: html [
210 Added: MFTWorkout >> renderSetGroupsTableFooterOn: html [
193 211
194 Removed: | totalReps totalVolume |
212 Added: | totalReps |
195 213 totalReps := (self sets collect: #reps) sum.
196 Removed: totalVolume := (self sets collect: #volume) sum.
197 214 html tableFoot: [
198 Removed: html tableData.
215 Added: self anySetGroupIsIrregular ifTrue: [ html tableHeading ].
199 216 html tableData: 'Total'.
200 217 html tableData
201 218 style: 'text-align: right';
202 219 with: totalReps.
203 220 self anySetHasLoad ifTrue: [ html tableData ].
204 Removed: totalVolume ~~ 0 ifTrue: [
221 Added: self volume ~~ 0 ifTrue: [
205 222 html tableData
206 223 style: 'text-align: right';
207 Removed: with: totalVolume ] ]
224 Added: with: self volume ] ]
208 225 ]
209 226
210 227 { #category : #rendering }
211 Removed: MFTWorkout >> renderSetsTableHeaderOn: html [
228 Added: MFTWorkout >> renderSetGroupsTableHeaderOn: html [
212 229
213 230 html tableHead: [
214 Removed: html tableHeading.
231 Added: self allSetGroupsAreRegular ifFalse: [ html tableHeading ].
215 232 html tableHeading: 'Exercise'.
216 233 html tableHeading
217 234 style: 'text-align: right';
@@ -224,6 +241,17 @@
224 241 html tableHeading
225 242 style: 'text-align: right';
226 243 with: 'Volume' ] ]
244 Added: ]
245 Added:
246 Added: { #category : #rendering }
247 Added: MFTWorkout >> renderSetGroupsTableOn: html [
248 Added:
249 Added: html table
250 Added: class: 'table table-bordered';
251 Added: with: [
252 Added: self renderSetGroupsTableHeaderOn: html.
253 Added: self renderSetGroupRowsOn: html.
254 Added: self renderSetGroupsTableFooterOn: html ]
227 255 ]
228 256
229 257 { #category : #accessing }
src/MyFitnessTracker/MFTWorkoutTask.class.st
index b91b732a..fa6c245f 100644..100644
@@ -38,9 +38,10 @@
38 38 action: action;
39 39 date: workout date;
40 40 completion: 20)).
41 Removed: workout sets: (self call: (MFTSetsDialog new
41 Added: workout setGroups: (self call: (MFTSetGroupsDialog new
42 42 action: action;
43 Removed: sets: workout sets;
43 Added: heading: 'Exercises';
44 Added: setGroups: workout setGroups;
44 45 completion: 40)).
45 46 primaryMuscleGroup := self call: (MFTPrimaryMuscleGroupDialog new
46 47 action: action;