[Pharo] Personal fitness tracker web app.
Divorce Dialogs and Forms.
Changed files
src/MyFitnessTracker/MFTForm.class.st
@@ -0,0 +1,58 @@
1
Added:
"
2
Added:
I represent a user-fillable form.
3
Added:
4
Added:
Upon submitting the form (""submit"" button), I return (`WAComponent>>#answer:`) the `#modelObject` with its attributes populated by the appropriate `MFTFormComponent` subclasses.
5
Added:
Upon canceling the form (""cancel"" button), I return `nil`.
6
Added:
"
7
Added:
Class {
8
Added:
#name : 'MFTForm',
9
Added:
#superclass : 'SBSComponent',
10
Added:
#instVars : [
11
Added:
'heading',
12
Added:
'modelObject'
13
Added:
],
14
Added:
#category : 'MyFitnessTracker-Forms',
15
Added:
#package : 'MyFitnessTracker',
16
Added:
#tag : 'Forms'
17
Added:
}
18
Added:
19
Added:
{ #category : 'accessing' }
20
Added:
MFTForm >> modelObject [
21
Added:
22
Added:
^ modelObject
23
Added:
]
24
Added:
25
Added:
{ #category : 'accessing' }
26
Added:
MFTForm >> modelObject: anObject [
27
Added:
28
Added:
modelObject := anObject
29
Added:
]
30
Added:
31
Added:
{ #category : 'as yet unclassified' }
32
Added:
MFTForm >> renderFormOn: html with: aBlock [
33
Added:
34
Added:
html container
35
Added:
style: 'max-width: 40rem';
36
Added:
with: [
37
Added:
html heading level1 with: heading.
38
Added:
html form: [
39
Added:
aBlock value.
40
Added:
html horizontalRule.
41
Added:
self renderSubmitOn: html ] ]
42
Added:
]
43
Added:
44
Added:
{ #category : 'as yet unclassified' }
45
Added:
MFTForm >> renderSubmitOn: html [
46
Added:
47
Added:
html buttonGroup: [
48
Added:
html formButton
49
Added:
beSubmit;
50
Added:
bePrimary;
51
Added:
callback: [ self answer: modelObject ];
52
Added:
with: 'Submit'.
53
Added:
html formButton
54
Added:
beSubmit;
55
Added:
beSecondary;
56
Added:
callback: [ self answer: nil ];
57
Added:
with: 'Cancel' ]
58
Added:
]
src/MyFitnessTracker/MFTFormComponent.class.st
@@ -3,30 +3,56 @@
3
3
#superclass : 'SBSComponent',
4
4
#instVars : [
5
5
'heading',
6
Removed:
'data'
6
Added:
'modelObject'
7
7
],
8
8
#category : 'MyFitnessTracker-Forms',
9
9
#package : 'MyFitnessTracker',
10
10
#tag : 'Forms'
11
11
}
12
12
13
Added:
{ #category : 'as yet unclassified' }
14
Added:
MFTFormComponent class >> formComponentFor: anAttribute [
15
Added:
16
Added:
| formComponents |
17
Added:
formComponents := Dictionary newFrom: {
18
Added:
(#date -> MFTDateFormComponent).
19
Added:
(#primaryMuscleGroup
20
Added:
-> MFTPrimaryMuscleGroupFormComponent).
21
Added:
(#setGroups -> MFTSetGroupsFormComponent) }.
22
Added:
^ formComponents at: anAttribute ifAbsent: [
23
Added:
self error:
24
Added:
('no appropriate {1} subclass for setting attribute "{2}"'
25
Added:
format: {
26
Added:
self.
27
Added:
anAttribute }) ]
28
Added:
]
29
Added:
30
Added:
{ #category : 'as yet unclassified' }
31
Added:
MFTFormComponent class >> set: anAttribute [
32
Added:
33
Added:
| formComponent |
34
Added:
formComponent := self formComponentFor: anAttribute.
35
Added:
^ formComponent new modelObject:
36
Added:
thisContext sender receiver modelObject
37
Added:
]
38
Added:
13
39
{ #category : 'accessing' }
14
Removed:
MFTFormComponent >> data [
40
Added:
MFTFormComponent >> modelObject [
15
41
16
Removed:
^ data
42
Added:
^ modelObject
17
43
]
18
44
19
45
{ #category : 'accessing' }
20
Removed:
MFTFormComponent >> data: anObject [
46
Added:
MFTFormComponent >> modelObject: anObject [
21
47
22
Removed:
data := anObject
48
Added:
modelObject := anObject
23
49
]
24
50
25
Removed:
{ #category : 'rendering' }
51
Added:
{ #category : 'as yet unclassified' }
26
52
MFTFormComponent >> renderFormComponentOn: html with: aBlock [
27
53
28
54
html formGroup
29
Removed:
class: 'my-3';
55
Added:
class: 'my-4';
30
56
with: [
31
57
html heading level3 with: heading.
32
58
aBlock value ]
src/MyFitnessTracker/MFTPrimaryMuscleGroupFormComponent.class.st
@@ -10,8 +10,7 @@
10
10
MFTPrimaryMuscleGroupFormComponent >> initialize [
11
11
12
12
super initialize.
13
Removed:
heading := 'Primary Muscle Group'.
14
Removed:
data := MFTSQLite3Database allMuscleGroups first
13
Added:
heading := 'Primary Muscle Group'
15
14
]
16
15
17
16
{ #category : 'rendering' }
@@ -19,14 +18,15 @@
19
18
20
19
| allMuscleGroups selectedMuscleGroup |
21
20
allMuscleGroups := MFTSQLite3Database allMuscleGroups.
22
Removed:
selectedMuscleGroup := data ifNotNil: [
21
Added:
selectedMuscleGroup := modelObject primaryMuscleGroup ifNotNil: [
23
22
allMuscleGroups detect: [ :muscleGroup |
24
Removed:
muscleGroup englishName = data englishName ] ].
23
Added:
muscleGroup englishName
24
Added:
= modelObject primaryMuscleGroup englishName ] ].
25
25
26
26
self renderFormComponentOn: html with: [
27
27
html select formControl
28
28
list: allMuscleGroups;
29
29
selected: selectedMuscleGroup;
30
30
labels: [ :muscleGroup | muscleGroup englishName ];
31
Removed:
callback: [ :group | data := group ] ]
31
Added:
callback: [ :group | modelObject primaryMuscleGroup: group ] ]
32
32
]
src/MyFitnessTracker/MFTSetGroupsFormComponent.class.st
@@ -1,9 +1,6 @@
1
1
Class {
2
2
#name : 'MFTSetGroupsFormComponent',
3
3
#superclass : 'MFTFormComponent',
4
Removed:
#instVars : [
5
Removed:
'setGroups'
6
Removed:
],
7
4
#category : 'MyFitnessTracker-Forms',
8
5
#package : 'MyFitnessTracker',
9
6
#tag : 'Forms'
@@ -15,7 +12,7 @@
15
12
| setGroup |
16
13
setGroup := self session pageManager activePage call:
17
14
(MFTSetGroupDialog new heading: 'Exercise').
18
Removed:
setGroup ifNotNil: [ setGroups add: setGroup ]
15
Added:
setGroup ifNotNil: [ modelObject add: setGroup ]
19
16
]
20
17
21
18
{ #category : 'adding' }
@@ -41,8 +38,7 @@
41
38
MFTSetGroupsFormComponent >> initialize [
42
39
43
40
super initialize.
44
Removed:
heading := 'Set Groups'.
45
Removed:
setGroups := OrderedCollection new
41
Added:
heading := 'Exercises'
46
42
]
47
43
48
44
{ #category : 'rendering' }
@@ -58,7 +54,7 @@
58
54
beSecondary;
59
55
beSmall;
60
56
callback: [ self addSetGroupForExerciseCount: 2 ];
61
Removed:
with: 'Add super set'.
57
Added:
with: 'Add superset'.
62
58
html outlineButton
63
59
beSecondary;
64
60
beSmall;
@@ -75,29 +71,75 @@
75
71
MFTSetGroupsFormComponent >> renderContentOn: html [
76
72
77
73
self renderFormComponentOn: html with: [
78
Removed:
setGroups ifNotEmpty: [ self renderSetsTableOn: html ].
74
Added:
modelObject setGroups ifNotEmpty: [ self renderSetGroupsTableOn: html ].
79
75
self renderAddSetGroupButtonsOn: html ]
80
76
]
81
77
82
78
{ #category : 'rendering' }
83
79
MFTSetGroupsFormComponent >> renderLoad [
84
80
85
Removed:
^ (setGroups flatCollect: #sets) anySatisfy: #hasLoad
81
Added:
^ (modelObject setGroups flatCollect: #sets) anySatisfy: #hasLoad
86
82
]
87
83
88
84
{ #category : 'rendering' }
89
85
MFTSetGroupsFormComponent >> renderRestAfter [
90
86
91
Removed:
^ (setGroups flatCollect: #sets) anySatisfy: #hasRestAfter
87
Added:
^ (modelObject setGroups flatCollect: #sets) anySatisfy: #hasRestAfter
92
88
]
93
89
94
90
{ #category : 'rendering' }
95
91
MFTSetGroupsFormComponent >> renderRpe [
96
92
97
Removed:
^ (setGroups flatCollect: #sets) anySatisfy: #hasRpe
93
Added:
^ (modelObject setGroups flatCollect: #sets) anySatisfy: #hasRpe
98
94
]
99
95
100
96
{ #category : 'rendering' }
97
Added:
MFTSetGroupsFormComponent >> renderSetGroupButtonsOn: html For: setGroup [
98
Added:
99
Added:
html buttonGroupVertical: [
100
Added:
html outlineButton
101
Added:
beDanger;
102
Added:
beSmall;
103
Added:
callback: [ modelObject setGroups remove: setGroup ];
104
Added:
with: 'Remove'.
105
Added:
html outlineButton
106
Added:
beSecondary;
107
Added:
beSmall;
108
Added:
callback: [ self editSetGroup: setGroup ];
109
Added:
with: 'Edit'.
110
Added:
html outlineButton
111
Added:
beSecondary;
112
Added:
beSmall;
113
Added:
callback: [
114
Added:
modelObject setGroups
115
Added:
add: setGroup
116
Added:
afterIndex: (modelObject setGroups indexOf: setGroup) ];
117
Added:
with: 'Duplicate' ]
118
Added:
]
119
Added:
120
Added:
{ #category : 'rendering' }
121
Added:
MFTSetGroupsFormComponent >> renderSetGroupsRowsOn: html [
122
Added:
123
Added:
| renderLoad renderRpe renderRestAfter |
124
Added:
renderLoad := self renderLoad.
125
Added:
renderRpe := self renderRpe.
126
Added:
renderRestAfter := self renderRestAfter.
127
Added:
modelObject setGroups do: [ :setGroup |
128
Added:
html tableRow with: [
129
Added:
html tableData
130
Added:
attributeAt: 'rowspan' put: setGroup sets size + 1;
131
Added:
style: 'vertical-align: middle';
132
Added:
with: [ self renderSetGroupButtonsOn: html For: setGroup ] ].
133
Added:
setGroup sets do: [ :set |
134
Added:
html tableRow: [
135
Added:
html tableData: set exercise englishName.
136
Added:
html tableData: set reps.
137
Added:
setGroup hasLoad ifTrue: [ html tableData: set load ].
138
Added:
setGroup hasRpe ifTrue: [ html tableData: set rpe ].
139
Added:
setGroup hasRestAfter ifTrue: [ html tableData: set restAfter ] ] ] ]
140
Added:
]
141
Added:
142
Added:
{ #category : 'rendering' }
101
143
MFTSetGroupsFormComponent >> renderSetGroupsTableHeaderOn: html [
102
144
103
145
html tableHead: [
@@ -111,7 +153,7 @@
111
153
]
112
154
113
155
{ #category : 'rendering' }
114
Removed:
MFTSetGroupsFormComponent >> renderSetsTableOn: html [
156
Added:
MFTSetGroupsFormComponent >> renderSetGroupsTableOn: html [
115
157
116
158
html table
117
159
class: 'table table-bordered';
src/MyFitnessTracker/MFTWorkoutDialog.class.st
@@ -1,76 +0,0 @@
1
Removed:
Class {
2
Removed:
#name : 'MFTWorkoutDialog',
3
Removed:
#superclass : 'MFTDialog',
4
Removed:
#instVars : [
5
Removed:
'workout',
6
Removed:
'datePicker',
7
Removed:
'setGroupsPicker',
8
Removed:
'primaryMuscleGroupPicker',
9
Removed:
'secondaryMuscleGroupsPicker'
10
Removed:
],
11
Removed:
#category : 'MyFitnessTracker-Dialogs',
12
Removed:
#package : 'MyFitnessTracker',
13
Removed:
#tag : 'Dialogs'
14
Removed:
}
15
Removed:
16
Removed:
{ #category : 'actions' }
17
Removed:
MFTWorkoutDialog class >> edit: aString [
18
Removed:
19
Removed:
^ self new
20
Removed:
action: #edit;
21
Removed:
string: aString;
22
Removed:
yourself
23
Removed:
]
24
Removed:
25
Removed:
{ #category : 'initialization' }
26
Removed:
MFTWorkoutDialog >> initialize [
27
Removed:
28
Removed:
super initialize.
29
Removed:
workout := MFTWorkout placeholderCollection first.
30
Removed:
datePicker := MFTDateFormComponent new.
31
Removed:
setGroupsPicker := MFTSetGroupsFormComponent new.
32
Removed:
primaryMuscleGroupPicker := MFTPrimaryMuscleGroupFormComponent new
33
Removed:
]
34
Removed:
35
Removed:
{ #category : 'rendering' }
36
Removed:
MFTWorkoutDialog >> renderContentOn: html [
37
Removed:
38
Removed:
self renderDialogOn: html with: [
39
Removed:
html render: datePicker.
40
Removed:
html render: setGroupsPicker.
41
Removed:
html render: primaryMuscleGroupPicker ]
42
Removed:
]
43
Removed:
44
Removed:
{ #category : 'rendering' }
45
Removed:
MFTWorkoutDialog >> renderSubmitOn: html [
46
Removed:
47
Removed:
html buttonGroup: [
48
Removed:
html formButton
49
Removed:
beSubmit;
50
Removed:
bePrimary;
51
Removed:
callback: [
52
Removed:
workout
53
Removed:
date: datePicker data;
54
Removed:
setGroups: setGroupsPicker data;
55
Removed:
primaryMuscleGroup: primaryMuscleGroupPicker data. ";
56
Removed:
secondaryMuscleGroups: secondaryMuscleGroupsPicker data"
57
Removed:
self answer: workout ];
58
Removed:
with: 'Submit'.
59
Removed:
html formButton
60
Removed:
beSubmit;
61
Removed:
beSecondary;
62
Removed:
callback: [ self answer: nil ];
63
Removed:
with: 'Cancel' ]
64
Removed:
]
65
Removed:
66
Removed:
{ #category : 'accessing' }
67
Removed:
MFTWorkoutDialog >> workout [
68
Removed:
69
Removed:
^ workout
70
Removed:
]
71
Removed:
72
Removed:
{ #category : 'accessing' }
73
Removed:
MFTWorkoutDialog >> workout: anObject [
74
Removed:
75
Removed:
workout := anObject
76
Removed:
]
src/MyFitnessTracker/MFTWorkoutForm.class.st
@@ -0,0 +1,25 @@
1
Added:
Class {
2
Added:
#name : 'MFTWorkoutForm',
3
Added:
#superclass : 'MFTForm',
4
Added:
#category : 'MyFitnessTracker-Forms',
5
Added:
#package : 'MyFitnessTracker',
6
Added:
#tag : 'Forms'
7
Added:
}
8
Added:
9
Added:
{ #category : 'initialization' }
10
Added:
MFTWorkoutForm >> initialize [
11
Added:
12
Added:
super initialize.
13
Added:
heading := 'Workout'.
14
Added:
modelObject := MFTWorkout placeholderCollection first
15
Added:
]
16
Added:
17
Added:
{ #category : 'rendering' }
18
Added:
MFTWorkoutForm >> renderContentOn: html [
19
Added:
20
Added:
self renderFormOn: html with: [
21
Added:
html
22
Added:
render: (MFTFormComponent set: #date);
23
Added:
render: (MFTFormComponent set: #setGroups);
24
Added:
render: (MFTFormComponent set: #primaryMuscleGroup) ]
25
Added:
]