Brand new dialogs! :fire:

Commit
c075b9d45b13c24636234c2a2492b9aa93ee4854
Author
Marius Peter <marius.peter@tutanota.com>
Author date
Committer
Marius Peter <marius.peter@tutanota.com>
Committer date
Changed files
src/MyFitnessTracker/MFTConfirmDialog.class.st
index 8321f57b..278ee1ff 100644..100644
@@ -1,72 +1,43 @@
1 1 Class {
2 2 #name : #MFTConfirmDialog,
3 Removed: #superclass : #SBSComponent,
4 Removed: #instVars : [
5 Removed: 'action',
6 Removed: 'component'
7 Removed: ],
3 Added: #superclass : #MFTDialog,
8 4 #category : #'MyFitnessTracker-Dialogs'
9 5 }
10 6
11 7 { #category : #public }
12 Removed: MFTConfirmDialog class >> delete: anObject [
8 Added: MFTConfirmDialog class >> add: anObject [
13 9
14 10 ^ self new
15 Removed: action: #delete;
11 Added: action: #add;
16 12 component: anObject;
17 13 yourself
18 14 ]
19 15
20 Removed: { #category : #accessing }
21 Removed: MFTConfirmDialog >> action [
16 Added: { #category : #public }
17 Added: MFTConfirmDialog class >> delete: anObject [
22 18
23 Removed: ^ action
19 Added: ^ self new
20 Added: action: #delete;
21 Added: component: anObject;
22 Added: yourself
24 23 ]
25 24
26 Removed: { #category : #accessing }
27 Removed: MFTConfirmDialog >> action: anObject [
25 Added: { #category : #'as yet unclassified' }
26 Added: MFTConfirmDialog >> heading [
28 27
29 Removed: action := anObject
28 Added: ^ 'You are about to ' , action , ' a ' , component class asString
29 Added: , ':'
30 30 ]
31 31
32 Removed: { #category : #accessing }
33 Removed: MFTConfirmDialog >> component [
34 Removed:
35 Removed: ^ component
36 Removed: ]
37 Removed:
38 Removed: { #category : #accessing }
39 Removed: MFTConfirmDialog >> component: anObject [
40 Removed:
41 Removed: component := anObject
42 Removed: ]
43 Removed:
44 32 { #category : #rendering }
45 33 MFTConfirmDialog >> renderContentOn: html [
46 34
47 Removed: html container: [
48 Removed: html heading:
49 Removed: 'You are about to ' , action , ' the following component:'.
50 Removed: html heading
51 Removed: level: 2;
52 Removed: with: component class.
35 Added: self renderDialogOn: html with: [
53 36 html render: component.
54 Removed: html form: [
55 Removed: html
56 Removed: label: [
57 Removed: html
58 Removed: text: 'Are you sure?';
59 Removed: space;
60 Removed: strong: 'This action cannot be undone.' ];
61 Removed: break.
62 Removed: html buttonGroup: [
63 Removed: html formButton
64 Removed: beDanger;
65 Removed: beSubmit;
66 Removed: callback: [ self answer: true ];
67 Removed: with: 'Confirm'.
68 Removed: html formButton
69 Removed: beSecondary;
70 Removed: callback: [ self answer: false ];
71 Removed: with: 'Cancel' ] ] ]
37 Added: html label: [
38 Added: html text: 'Are you sure?'.
39 Added: action = #delete ifTrue: [
40 Added: html
41 Added: space;
42 Added: strong: 'This action cannot be undone.' ] ] ]
72 43 ]
src/MyFitnessTracker/MFTDateDialog.class.st
index 00000000..3737d6a1 000000..100644
@@ -0,0 +1,47 @@
1 Added: Class {
2 Added: #name : #MFTDateDialog,
3 Added: #superclass : #MFTDialog,
4 Added: #instVars : [
5 Added: 'date'
6 Added: ],
7 Added: #category : #'MyFitnessTracker-Dialogs'
8 Added: }
9 Added:
10 Added: { #category : #accessing }
11 Added: MFTDateDialog >> date [
12 Added:
13 Added: ^ date
14 Added: ]
15 Added:
16 Added: { #category : #accessing }
17 Added: MFTDateDialog >> date: anObject [
18 Added:
19 Added: date := anObject
20 Added: ]
21 Added:
22 Added: { #category : #initialization }
23 Added: MFTDateDialog >> initialize [
24 Added:
25 Added: super initialize.
26 Added: date := Date today
27 Added: ]
28 Added:
29 Added: { #category : #rendering }
30 Added: MFTDateDialog >> renderContentOn: html [
31 Added:
32 Added: self renderDialogOn: html with: [
33 Added: html dateInput5 formControl
34 Added: value: date yyyymmdd;
35 Added: callback: [ :value | date := Date fromString: value ] ]
36 Added: ]
37 Added:
38 Added: { #category : #rendering }
39 Added: MFTDateDialog >> renderSubmitOn: html [
40 Added:
41 Added: html buttonGroup: [
42 Added: html formButton
43 Added: beSubmit;
44 Added: bePrimary;
45 Added: callback: [ self answer: date ];
46 Added: with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]) ]
47 Added: ]
src/MyFitnessTracker/MFTDialog.class.st
index 3a13fb47..82103ce1 100644..100644
@@ -2,59 +2,138 @@
2 2 #name : #MFTDialog,
3 3 #superclass : #SBSComponent,
4 4 #instVars : [
5 Removed: 'addOrEdit'
5 Added: 'heading',
6 Added: 'component',
7 Added: 'action',
8 Added: 'completion'
6 9 ],
7 10 #category : #'MyFitnessTracker-Dialogs'
8 11 }
9 12
10 13 { #category : #actions }
11 Removed: MFTDialog class >> edit: aMFTWorkout [
14 Added: MFTDialog class >> edit: anObject [
12 15
13 16 ^ self new
14 Removed: workout: aMFTWorkout;
15 Removed: exercises: aMFTWorkout exercises;
16 Removed: addOrEdit: #edit;
17 Added: action: #edit;
18 Added: component: anObject;
17 19 yourself
18 20 ]
19 21
20 22 { #category : #accessing }
21 Removed: MFTDialog >> addOrEdit [
23 Added: MFTDialog >> action [
22 24
23 Removed: ^ addOrEdit
25 Added: ^ action
24 26 ]
25 27
26 28 { #category : #accessing }
27 Removed: MFTDialog >> addOrEdit: aRole [
29 Added: MFTDialog >> action: anObject [
28 30
29 Removed: addOrEdit := aRole
31 Added: action := anObject
30 32 ]
31 33
34 Added: { #category : #delegation }
35 Added: MFTDialog >> answer [
36 Added:
37 Added: self answer: component
38 Added: ]
39 Added:
40 Added: { #category : #accessing }
41 Added: MFTDialog >> completion [
42 Added:
43 Added: ^ completion
44 Added: ]
45 Added:
46 Added: { #category : #accessing }
47 Added: MFTDialog >> completion: anObject [
48 Added:
49 Added: completion := anObject
50 Added: ]
51 Added:
52 Added: { #category : #accessing }
53 Added: MFTDialog >> component [
54 Added:
55 Added: ^ component
56 Added: ]
57 Added:
58 Added: { #category : #accessing }
59 Added: MFTDialog >> component: anObject [
60 Added:
61 Added: component := anObject
62 Added: ]
63 Added:
64 Added: { #category : #'t - rotating' }
65 Added: MFTDialog >> heading [
66 Added:
67 Added: ^ action capitalized , ' ' , (heading ifNil: [
68 Added: ('^MFT(.*)Dialog$' asRegex
69 Added: search: self class name;
70 Added: subexpression: 2) asCapitalizedPhrase ifNil: [
71 Added: 'Default Component' ] ])
72 Added: ]
73 Added:
74 Added: { #category : #accessing }
75 Added: MFTDialog >> heading: aString [
76 Added:
77 Added: heading := aString
78 Added: ]
79 Added:
32 80 { #category : #initialization }
33 81 MFTDialog >> initialize [
34 82
35 83 super initialize.
36 Removed: addOrEdit := #add
84 Added: action := #add
37 85 ]
38 86
39 87 { #category : #rendering }
88 Added: MFTDialog >> renderCompletionOn: html [
89 Added:
90 Added: completion ifNotNil: [
91 Added: html progress
92 Added: class: 'my-3';
93 Added: with: [
94 Added: html progressBar
95 Added: beStriped;
96 Added: beAnimated;
97 Added: successBackground;
98 Added: valueNow: completion;
99 Added: with: completion percent ] ]
100 Added: ]
101 Added:
102 Added: { #category : #rendering }
40 103 MFTDialog >> renderContentOn: html [
41 104
42 105 self renderDialogOn: html with: [
43 Removed: html heading: 'Default ' , self class name.
44 Removed: html form: [
45 Removed: html formGroup: [
46 Removed: html label: 'Don''t do anything'.
47 Removed: html formButton
48 Removed: beSecondary;
49 Removed: formControl;
50 Removed: callback: [ self answer: nil ];
51 Removed: with: 'Cancel' ] ] ]
106 Added: html text:
107 Added: 'By default, ' , self class name , ' doesn''t do anything.' ]
52 108 ]
53 109
54 110 { #category : #rendering }
55 111 MFTDialog >> renderDialogOn: html with: aBlock [
56 112
57 113 html container
58 Removed: class: 'w-50';
59 Removed: with: aBlock
114 Added: style: 'max-width: 40rem';
115 Added: with: [
116 Added: html heading: self heading.
117 Added: html form: [
118 Added: aBlock value.
119 Added: html horizontalRule.
120 Added: self renderSubmitOn: html ].
121 Added: self renderCompletionOn: html ]
122 Added: ]
123 Added:
124 Added: { #category : #rendering }
125 Added: MFTDialog >> renderSubmitOn: html [
126 Added:
127 Added: html buttonGroup: [
128 Added: html formButton
129 Added: beSubmit;
130 Added: bePrimary;
131 Added: beDangerIf: action = #delete;
132 Added: callback: [ self answer: true ];
133 Added: with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]).
134 Added: html formButton
135 Added: beSubmit;
136 Added: beSecondary;
137 Added: callback: [ self answer: false ];
138 Added: with: (completion ifNil: [ 'Cancel' ] ifNotNil: [ 'Skip' ]) ]
60 139 ]
src/MyFitnessTracker/MFTExerciseDialog.class.st
index da53b0bc..ae22f5ec 100644..100644
@@ -1,11 +1,7 @@
1 1 Class {
2 2 #name : #MFTExerciseDialog,
3 Removed: #superclass : #SBSComponent,
3 Added: #superclass : #MFTDialog,
4 4 #instVars : [
5 Removed: 'selectedExercise',
6 Removed: 'currentFilter',
7 Removed: 'allExercises',
8 Removed: 'addOrEdit',
9 5 'exercise',
10 6 'sets'
11 7 ],
@@ -16,55 +12,30 @@
16 12 MFTExerciseDialog class >> edit: aMFTExercise [
17 13
18 14 ^ self new
19 Removed: selectedExercise: aMFTExercise;
15 Added: exercise: aMFTExercise;
20 16 sets: aMFTExercise sets;
21 Removed: addOrEdit: #edit;
17 Added: action: #edit;
22 18 yourself
23 19 ]
24 20
25 21 { #category : #accessing }
26 Removed: MFTExerciseDialog >> addOrEdit [
27 Removed:
28 Removed: ^ addOrEdit
29 Removed: ]
30 Removed:
31 Removed: { #category : #accessing }
32 Removed: MFTExerciseDialog >> addOrEdit: aRole [
33 Removed:
34 Removed: addOrEdit := aRole
35 Removed: ]
36 Removed:
37 Removed: { #category : #accessing }
38 22 MFTExerciseDialog >> exercise [
39 23
40 24 ^ exercise
41 25 ]
42 26
43 27 { #category : #accessing }
44 Removed: MFTExerciseDialog >> exercise: aMFTExercise [
28 Added: MFTExerciseDialog >> exercise: anObject [
45 29
46 Removed: exercise := aMFTExercise
30 Added: exercise := anObject
47 31 ]
48 32
49 Removed: { #category : #rendering }
50 Removed: MFTExerciseDialog >> filteredExercises [
51 Removed:
52 Removed: ^ currentFilter isEmpty
53 Removed: ifTrue: [ allExercises ]
54 Removed: ifFalse: [
55 Removed: allExercises select: [ :each |
56 Removed: each englishName asLowercase includesSubstring:
57 Removed: currentFilter asLowercase ] ]
58 Removed: ]
59 Removed:
60 33 { #category : #initialization }
61 34 MFTExerciseDialog >> initialize [
62 35
63 36 super initialize.
64 37 exercise := MFTExercise new.
65 Removed: allExercises := MFTUtils allExercises.
66 Removed: sets := OrderedCollection new.
67 Removed: addOrEdit := #add
38 Added: sets := OrderedCollection new
68 39 ]
69 40
70 41 { #category : #rendering }
@@ -85,43 +56,30 @@
85 56 { #category : #rendering }
86 57 MFTExerciseDialog >> renderContentOn: html [
87 58
88 Removed: html container: [
89 Removed: html heading: addOrEdit capitalized , ' exercise'.
90 Removed: html form: [
91 Removed: self renderExerciseSelectOn: html.
92 Removed: self renderSetsTableOn: html.
93 Removed: self renderSubmitExerciseOn: html ] ]
59 Added: self renderDialogOn: html with: [
60 Added: self renderExerciseSelectOn: html.
61 Added: self renderSetsTableOn: html ]
94 62 ]
95 63
96 64 { #category : #rendering }
97 65 MFTExerciseDialog >> renderExerciseSelectOn: html [
98 66
67 Added: | allExercises selectedExercise |
68 Added: allExercises := MFTUtils allExercises.
69 Added: selectedExercise := allExercises
70 Added: detect: [ :each |
71 Added: each englishName = exercise englishName ]
72 Added: ifNone: [ nil ].
99 73 html formGroup: [
100 74 html label: 'Exercise'.
101 Removed: html formGroup: [ "html label: 'Filter exercises'.
102 Removed: html textInput
103 Removed: class: 'form-control';
104 Removed: placeholder: 'Type to search...';
105 Removed: callback: [ :value | currentFilter := value ];
106 Removed: onKeyUp:
107 Removed: (html jQuery this load html: [ :h |
108 Removed: self renderFilteredExercisesOn: h ]) "
109 Removed: html select formControl
110 Removed: list: MFTUtils allExercises;
111 Removed: selected: selectedExercise;
112 Removed: labels: [ :each | each englishName ];
113 Removed: callback: [ :value | selectedExercise := value ] ] ]
75 Added: html select formControl
76 Added: list: allExercises;
77 Added: selected: selectedExercise;
78 Added: callback: [ :value | exercise := value ];
79 Added: labels: [ :each | each englishName ] ]
114 80 ]
115 81
116 82 { #category : #rendering }
117 Removed: MFTExerciseDialog >> renderFilteredExercisesOn: html [
118 Removed:
119 Removed: html unorderedList: [
120 Removed: self filteredExercises do: [ :eachExercise |
121 Removed: html listItem: eachExercise englishName ] ]
122 Removed: ]
123 Removed:
124 Removed: { #category : #rendering }
125 83 MFTExerciseDialog >> renderSetsRowsOn: html [
126 84 "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?"
127 85
@@ -130,23 +88,24 @@
130 88 html tableData: [
131 89 html buttonGroup: [
132 90 html outlineButton
133 Removed: beSecondary;
91 Added: beDanger;
134 92 beSmall;
135 93 callback: [ sets removeAt: i ];
136 94 with: 'Remove'.
137 95 html outlineButton
138 96 beSecondary;
139 97 beSmall;
140 Removed: callback: [ sets add: set afterIndex: i ];
98 Added: callback: [
99 Added: sets add: (MFTSet reps: set reps rpe: set rpe) afterIndex: i ];
141 100 with: 'Duplicate' ] ].
142 101 html tableData: [
143 102 html numberInput
144 103 value: set reps;
145 Removed: callback: [ :value | value ifNotNil: [ set reps: value ] ] ].
104 Added: callback: [ :value | set reps: value ] ].
146 105 html tableData: [
147 106 html numberInput
148 107 value: set rpe;
149 Removed: callback: [ :value | value ifNotNil: [ set rpe: value ] ] ] ] ]
108 Added: callback: [ :value | set rpe: value ] ] ] ]
150 109 ]
151 110
152 111 { #category : #rendering }
@@ -162,26 +121,20 @@
162 121 self renderAddSetRowOn: html ] ]
163 122 ]
164 123
165 Removed: { #category : #rendering }
166 Removed: MFTExerciseDialog >> renderSubmitExerciseOn: html [
124 Added: { #category : #delegation }
125 Added: MFTExerciseDialog >> renderSubmitOn: html [
167 126
168 Removed: html formGroup: [ "html text: (sets collect: #reps).
169 Removed: html break.
170 Removed: html text: (sets collect: #rpe)."
171 Removed: html buttonGroup: [
172 Removed: html formButton
173 Removed: bePrimary;
174 Removed: beSubmit;
175 Removed: callback: [
176 Removed: sets removeAllSuchThat: [ :set |
177 Removed: set reps isNil or: [ set reps = '' ] ].
178 Removed: exercise := selectedExercise sets: sets.
179 Removed: self answer: exercise ];
180 Removed: with: 'Submit'.
181 Removed: html formButton
182 Removed: beSecondary;
183 Removed: callback: [ self answer: nil ];
184 Removed: with: 'Cancel' ] ]
127 Added: html buttonGroup: [
128 Added: html formButton
129 Added: beSubmit;
130 Added: bePrimary;
131 Added: callback: [ self answer: (exercise sets: sets) ];
132 Added: with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]).
133 Added: html formButton
134 Added: beSubmit;
135 Added: beSecondary;
136 Added: callback: [ self answer: nil ];
137 Added: with: (completion ifNil: [ 'Cancel' ] ifNotNil: [ 'Skip' ]) ]
185 138 ]
186 139
187 140 { #category : #rendering }
@@ -192,18 +145,6 @@
192 145 tableHeading;
193 146 tableHeading: 'Reps';
194 147 tableHeading: 'RPE' ]
195 Removed: ]
196 Removed:
197 Removed: { #category : #accessing }
198 Removed: MFTExerciseDialog >> selectedExercise [
199 Removed:
200 Removed: ^ selectedExercise
201 Removed: ]
202 Removed:
203 Removed: { #category : #accessing }
204 Removed: MFTExerciseDialog >> selectedExercise: aMFTExercise [
205 Removed:
206 Removed: selectedExercise := aMFTExercise
207 148 ]
208 149
209 150 { #category : #accessing }
src/MyFitnessTracker/MFTExercisesDialog.class.st
index 00000000..19bd16b5 000000..100644
@@ -0,0 +1,131 @@
1 Added: Class {
2 Added: #name : #MFTExercisesDialog,
3 Added: #superclass : #MFTDialog,
4 Added: #instVars : [
5 Added: 'exercises'
6 Added: ],
7 Added: #category : #'MyFitnessTracker-Dialogs'
8 Added: }
9 Added:
10 Added: { #category : #adding }
11 Added: MFTExercisesDialog >> addExercise [
12 Added:
13 Added: | exercise |
14 Added: exercise := self call: MFTExerciseDialog new.
15 Added: exercise ifNotNil: [ exercises add: exercise ]
16 Added: ]
17 Added:
18 Added: { #category : #accessing }
19 Added: MFTExercisesDialog >> editExerciseAt: i [
20 Added:
21 Added: | oldExercise newExercise |
22 Added: oldExercise := exercises at: i.
23 Added: newExercise := self call: (MFTExerciseDialog edit: oldExercise).
24 Added: newExercise ifNotNil: [ exercises at: i put: newExercise ]
25 Added: ]
26 Added:
27 Added: { #category : #accessing }
28 Added: MFTExercisesDialog >> exercises [
29 Added:
30 Added: ^ exercises
31 Added: ]
32 Added:
33 Added: { #category : #accessing }
34 Added: MFTExercisesDialog >> exercises: aCollection [
35 Added:
36 Added: exercises := aCollection
37 Added: ]
38 Added:
39 Added: { #category : #initialization }
40 Added: MFTExercisesDialog >> initialize [
41 Added:
42 Added: super initialize.
43 Added: exercises := OrderedCollection new
44 Added: ]
45 Added:
46 Added: { #category : #rendering }
47 Added: MFTExercisesDialog >> renderAddExerciseRowOn: html [
48 Added:
49 Added: html tableRow: [
50 Added: html tableData: [
51 Added: html outlineButton
52 Added: bePrimary;
53 Added: beSmall;
54 Added: callback: [ self addExercise ];
55 Added: with: 'Add'.
56 Added: html
57 Added: tableData;
58 Added: tableData.
59 Added: ((exercises collect: #sets) anySatisfy: #isNotEmpty) ifTrue: [
60 Added: html tableData ] ] ]
61 Added: ]
62 Added:
63 Added: { #category : #rendering }
64 Added: MFTExercisesDialog >> renderContentOn: html [
65 Added:
66 Added: self renderDialogOn: html with: [
67 Added: html table
68 Added: class: 'table table-hover';
69 Added: with: [
70 Added: exercises ifNotEmpty: [
71 Added: self renderTableHeaderOn: html.
72 Added: self renderExercisesRowsOn: html ].
73 Added: self renderAddExerciseRowOn: html ] ]
74 Added: ]
75 Added:
76 Added: { #category : #rendering }
77 Added: MFTExercisesDialog >> renderExerciseActionsButtonGroupOn: html at: i [
78 Added:
79 Added: html buttonGroup: [
80 Added: html outlineButton
81 Added: beSecondary;
82 Added: beSmall;
83 Added: callback: [ exercises removeAt: i ];
84 Added: with: 'Delete'.
85 Added: html outlineButton
86 Added: beSecondary;
87 Added: beSmall;
88 Added: callback: [ self editExerciseAt: i ];
89 Added: with: 'Edit' ]
90 Added: ]
91 Added:
92 Added: { #category : #rendering }
93 Added: MFTExercisesDialog >> renderExercisesRowsOn: html [
94 Added:
95 Added: exercises doWithIndex: [ :exercise :i |
96 Added: html tableRow: [
97 Added: html tableData: [
98 Added: self renderExerciseActionsButtonGroupOn: html at: i ].
99 Added: html tableData: exercise englishName.
100 Added: html tableData: exercise primaryMuscle englishName.
101 Added: ((exercises collect: #sets) anySatisfy: #isNotEmpty) ifTrue: [
102 Added: html tableData: exercise repsBySet asCommaString ] ] ]
103 Added: ]
104 Added:
105 Added: { #category : #rendering }
106 Added: MFTExercisesDialog >> renderSubmitOn: html [
107 Added:
108 Added: html buttonGroup: [
109 Added: html formButton
110 Added: beSubmit;
111 Added: bePrimary;
112 Added: callback: [ self answer: exercises ];
113 Added: with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]).
114 Added: html formButton
115 Added: beSubmit;
116 Added: beSecondary;
117 Added: callback: [ self answer: OrderedCollection new ];
118 Added: with: (completion ifNil: [ 'Cancel' ] ifNotNil: [ 'Skip' ]) ]
119 Added: ]
120 Added:
121 Added: { #category : #rendering }
122 Added: MFTExercisesDialog >> renderTableHeaderOn: html [
123 Added:
124 Added: html tableHead: [
125 Added: html
126 Added: tableHeading;
127 Added: tableHeading: 'Exercise';
128 Added: tableHeading: 'Primary Muscle'.
129 Added: ((exercises collect: #sets) anySatisfy: #isNotEmpty) ifTrue: [
130 Added: html tableHeading: 'Sets' ] ]
131 Added: ]
src/MyFitnessTracker/MFTPrimaryMuscleDialog.class.st
index 00000000..02aa81ea 000000..100644
@@ -0,0 +1,62 @@
1 Added: Class {
2 Added: #name : #MFTPrimaryMuscleDialog,
3 Added: #superclass : #MFTDialog,
4 Added: #instVars : [
5 Added: 'primaryMuscle'
6 Added: ],
7 Added: #category : #'MyFitnessTracker-Dialogs'
8 Added: }
9 Added:
10 Added: { #category : #initialization }
11 Added: MFTPrimaryMuscleDialog >> initialize [
12 Added:
13 Added: super initialize.
14 Added: primaryMuscle := MFTMuscle new
15 Added: ]
16 Added:
17 Added: { #category : #accessing }
18 Added: MFTPrimaryMuscleDialog >> primaryMuscle [
19 Added:
20 Added: ^ primaryMuscle
21 Added: ]
22 Added:
23 Added: { #category : #accessing }
24 Added: MFTPrimaryMuscleDialog >> primaryMuscle: anObject [
25 Added:
26 Added: primaryMuscle := anObject
27 Added: ]
28 Added:
29 Added: { #category : #rendering }
30 Added: MFTPrimaryMuscleDialog >> renderContentOn: html [
31 Added:
32 Added: | allMuscles selectedMuscle |
33 Added: allMuscles := MFTUtils allMuscleGroups.
34 Added: selectedMuscle := allMuscles
35 Added: detect: [ :each |
36 Added: each englishName = primaryMuscle englishName ]
37 Added: ifNone: [ nil ].
38 Added:
39 Added: self renderDialogOn: html with: [
40 Added: html formGroup: [
41 Added: html select formControl
42 Added: list: allMuscles;
43 Added: selected: selectedMuscle;
44 Added: labels: [ :muscleGroup | muscleGroup englishName ];
45 Added: callback: [ :group | component := group ] ] ]
46 Added: ]
47 Added:
48 Added: { #category : #rendering }
49 Added: MFTPrimaryMuscleDialog >> renderSubmitOn: html [
50 Added:
51 Added: html buttonGroup: [
52 Added: html formButton
53 Added: beSubmit;
54 Added: bePrimary;
55 Added: callback: [ self answer: primaryMuscle ];
56 Added: with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]).
57 Added: html formButton
58 Added: beSubmit;
59 Added: beSecondary;
60 Added: callback: [ self answer: MFTMuscle new ];
61 Added: with: (completion ifNil: [ 'Cancel' ] ifNotNil: [ 'Skip' ]) ]
62 Added: ]
src/MyFitnessTracker/MFTSecondaryMusclesDialog.class.st
index 00000000..aa521965 000000..100644
@@ -0,0 +1,63 @@
1 Added: Class {
2 Added: #name : #MFTSecondaryMusclesDialog,
3 Added: #superclass : #MFTDialog,
4 Added: #instVars : [
5 Added: 'secondaryMuscles'
6 Added: ],
7 Added: #category : #'MyFitnessTracker-Dialogs'
8 Added: }
9 Added:
10 Added: { #category : #initialization }
11 Added: MFTSecondaryMusclesDialog >> initialize [
12 Added:
13 Added: super initialize.
14 Added: secondaryMuscles := OrderedCollection with: MFTMuscle new
15 Added: ]
16 Added:
17 Added: { #category : #rendering }
18 Added: MFTSecondaryMusclesDialog >> renderContentOn: html [
19 Added:
20 Added: | allMuscles selectedMuscles |
21 Added: allMuscles := MFTUtils allMuscleGroups.
22 Added: "selectedMuscles := allMuscles
23 Added: detect: [ :each |
24 Added: each englishName
25 Added: = (secondaryMuscles collect: #englishName) ]
26 Added: ifNone: [ nil ]."
27 Added:
28 Added: self renderDialogOn: html with: [
29 Added: html multiSelect formControl
30 Added: list: allMuscles;
31 Added: "selected: selectedMuscles;"labels: [ :muscleGroup |
32 Added: muscleGroup englishName ];
33 Added: callback: [ :groups |
34 Added: groups ifNotEmpty: [ secondaryMuscles := groups ] ] ]
35 Added: ]
36 Added:
37 Added: { #category : #rendering }
38 Added: MFTSecondaryMusclesDialog >> renderSubmitOn: html [
39 Added:
40 Added: html buttonGroup: [
41 Added: html formButton
42 Added: beSubmit;
43 Added: bePrimary;
44 Added: callback: [ self answer: secondaryMuscles ];
45 Added: with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]).
46 Added: html formButton
47 Added: beSubmit;
48 Added: beSecondary;
49 Added: callback: [ self answer: OrderedCollection new ];
50 Added: with: (completion ifNil: [ 'Cancel' ] ifNotNil: [ 'Skip' ]) ]
51 Added: ]
52 Added:
53 Added: { #category : #accessing }
54 Added: MFTSecondaryMusclesDialog >> secondaryMuscles [
55 Added:
56 Added: ^ secondaryMuscles
57 Added: ]
58 Added:
59 Added: { #category : #accessing }
60 Added: MFTSecondaryMusclesDialog >> secondaryMuscles: anObject [
61 Added:
62 Added: secondaryMuscles := anObject
63 Added: ]
src/MyFitnessTracker/MFTStringDialog.class.st
index 00000000..92fdcfae 000000..100644
@@ -0,0 +1,55 @@
1 Added: Class {
2 Added: #name : #MFTStringDialog,
3 Added: #superclass : #MFTDialog,
4 Added: #instVars : [
5 Added: 'string'
6 Added: ],
7 Added: #category : #'MyFitnessTracker-Dialogs'
8 Added: }
9 Added:
10 Added: { #category : #actions }
11 Added: MFTStringDialog class >> edit: aString [
12 Added:
13 Added: ^ self new
14 Added: string: aString;
15 Added: yourself
16 Added: ]
17 Added:
18 Added: { #category : #initialization }
19 Added: MFTStringDialog >> initialize [
20 Added:
21 Added: super initialize.
22 Added: string := String new
23 Added: ]
24 Added:
25 Added: { #category : #rendering }
26 Added: MFTStringDialog >> renderContentOn: html [
27 Added:
28 Added: self renderDialogOn: html with: [
29 Added: html textInput formControl
30 Added: value: string;
31 Added: callback: [ :value | string := value ] ]
32 Added: ]
33 Added:
34 Added: { #category : #rendering }
35 Added: MFTStringDialog >> renderSubmitOn: html [
36 Added:
37 Added: html buttonGroup: [
38 Added: html formButton
39 Added: beSubmit;
40 Added: bePrimary;
41 Added: callback: [ self answer: string ];
42 Added: with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]) ]
43 Added: ]
44 Added:
45 Added: { #category : #accessing }
46 Added: MFTStringDialog >> string [
47 Added:
48 Added: ^ string
49 Added: ]
50 Added:
51 Added: { #category : #accessing }
52 Added: MFTStringDialog >> string: anObject [
53 Added:
54 Added: string := anObject
55 Added: ]
src/MyFitnessTracker/MFTWeightDialog.class.st
index 809ad96e..81bb269d 100644..100644
@@ -7,64 +7,54 @@
7 7 #category : #'MyFitnessTracker-Dialogs'
8 8 }
9 9
10 Added: { #category : #actions }
11 Added: MFTWeightDialog class >> edit: aMFTWeight [
12 Added:
13 Added: ^ self new
14 Added: action: #edit;
15 Added: weight: aMFTWeight;
16 Added: yourself
17 Added: ]
18 Added:
10 19 { #category : #initialization }
11 20 MFTWeightDialog >> initialize [
12 21
13 22 super initialize.
14 Removed: weight := MFTWeight new.
15 Removed: addOrEdit := #add
23 Added: weight := MFTWeight new
16 24 ]
17 25
18 26 { #category : #rendering }
19 27 MFTWeightDialog >> renderContentOn: html [
20 28
21 29 self renderDialogOn: html with: [
22 Removed: html heading: self addOrEdit asCapitalizedPhrase , ' weight'.
23 Removed: html form with: [
24 Removed: self renderDateInputOn: html.
25 Removed: self renderWeightInputOn: html.
26 Removed: self renderSubmitWeightOn: html ] ]
30 Added: html formGroup: [
31 Added: html label: 'Date'.
32 Added: html dateInput5 formControl
33 Added: value: weight date yyyymmdd;
34 Added: callback: [ :value | weight date: (Date fromString: value) ] ].
35 Added: html formGroup: [
36 Added: html label: 'Weight'.
37 Added: html numberInput formControl
38 Added: placeholder: weight value;
39 Added: callback: [ :value | weight value: value ] ] ]
27 40 ]
28 41
29 42 { #category : #rendering }
30 Removed: MFTWeightDialog >> renderDateInputOn: html [
43 Added: MFTWeightDialog >> renderSubmitOn: html [
31 44
32 Removed: html formGroup: [
33 Removed: html label: 'Date'.
34 Removed: html dateInput5 formControl
35 Removed: value: weight date yyyymmdd;
36 Removed: callback: [ :date | weight date: (Date fromString: date) ] ]
45 Added: html buttonGroup: [
46 Added: html formButton
47 Added: beSubmit;
48 Added: bePrimary;
49 Added: callback: [ self answer: weight ];
50 Added: with: (completion ifNil: [ 'Submit' ] ifNotNil: [ 'Next' ]).
51 Added: html formButton
52 Added: beSubmit;
53 Added: beSecondary;
54 Added: callback: [ self answer: nil ];
55 Added: with: (completion ifNil: [ 'Cancel' ] ifNotNil: [ 'Skip' ]) ]
37 56 ]
38 57
39 Removed: { #category : #rendering }
40 Removed: MFTWeightDialog >> renderSubmitWeightOn: html [
41 Removed:
42 Removed: html buttonGroup
43 Removed: class: 'mt-3';
44 Removed: with: [
45 Removed: html formButton
46 Removed: bePrimary;
47 Removed: beSubmit;
48 Removed: callback: [ self answer: weight ];
49 Removed: with: 'Submit'.
50 Removed: html formButton
51 Removed: beSecondary;
52 Removed: callback: [ self answer: nil ];
53 Removed: with: 'Cancel' ]
54 Removed: ]
55 Removed:
56 Removed: { #category : #rendering }
57 Removed: MFTWeightDialog >> renderWeightInputOn: html [
58 Removed:
59 Removed: html formGroup: [
60 Removed: html label: 'Weight'.
61 Removed: html textInput
62 Removed: formControl;
63 Removed: placeholder: weight value;
64 Removed: callback: [ :value | weight value: value ];
65 Removed: with: weight value ]
66 Removed: ]
67 Removed:
68 58 { #category : #accessing }
69 59 MFTWeightDialog >> weight [
70 60
@@ -72,7 +62,7 @@
72 62 ]
73 63
74 64 { #category : #accessing }
75 Removed: MFTWeightDialog >> weight: anObject [
65 Added: MFTWeightDialog >> weight: aMFTWeight [
76 66
77 Removed: weight := anObject
67 Added: weight := aMFTWeight
78 68 ]
src/MyFitnessTracker/MFTWorkoutDialog.class.st
index 4c81c912..00000000 100644..000000
@@ -1,196 +0,0 @@
1 Removed: Class {
2 Removed: #name : #MFTWorkoutDialog,
3 Removed: #superclass : #MFTDialog,
4 Removed: #instVars : [
5 Removed: 'workout',
6 Removed: 'exercises'
7 Removed: ],
8 Removed: #category : #'MyFitnessTracker-Dialogs'
9 Removed: }
10 Removed:
11 Removed: { #category : #adding }
12 Removed: MFTWorkoutDialog >> addExercise [
13 Removed:
14 Removed: | exercise |
15 Removed: exercise := self call: MFTExerciseDialog new.
16 Removed: exercise ifNotNil: [ exercises add: exercise ]
17 Removed: ]
18 Removed:
19 Removed: { #category : #'as yet unclassified' }
20 Removed: MFTWorkoutDialog >> editExerciseAt: i [
21 Removed:
22 Removed: | oldExercise newExercise |
23 Removed: oldExercise := exercises at: i.
24 Removed: newExercise := self call: (MFTExerciseDialog edit: oldExercise).
25 Removed: newExercise ifNotNil: [ exercises at: i put: newExercise ]
26 Removed: ]
27 Removed:
28 Removed: { #category : #accessing }
29 Removed: MFTWorkoutDialog >> exercises [
30 Removed:
31 Removed: ^ exercises
32 Removed: ]
33 Removed:
34 Removed: { #category : #accessing }
35 Removed: MFTWorkoutDialog >> exercises: anObject [
36 Removed:
37 Removed: exercises := anObject
38 Removed: ]
39 Removed:
40 Removed: { #category : #initialization }
41 Removed: MFTWorkoutDialog >> initialize [
42 Removed:
43 Removed: super initialize.
44 Removed: workout := MFTWorkout new.
45 Removed: exercises := OrderedCollection new.
46 Removed: addOrEdit := #add
47 Removed: ]
48 Removed:
49 Removed: { #category : #rendering }
50 Removed: MFTWorkoutDialog >> renderAddExerciseButtonOn: html [
51 Removed:
52 Removed: html outlineButton
53 Removed: bePrimary;
54 Removed: beSmall;
55 Removed: callback: [ self addExercise ];
56 Removed: with: 'Add'
57 Removed: ]
58 Removed:
59 Removed: { #category : #rendering }
60 Removed: MFTWorkoutDialog >> renderAddExerciseRowOn: html [
61 Removed:
62 Removed: html tableRow: [
63 Removed: html tableData: [ self renderAddExerciseButtonOn: html ].
64 Removed: 1 to: 3 do: [ :each | html tableData ] ]
65 Removed: ]
66 Removed:
67 Removed: { #category : #rendering }
68 Removed: MFTWorkoutDialog >> renderContentOn: html [
69 Removed:
70 Removed: self renderDialogOn: html with: [
71 Removed: html heading: self addOrEdit asCapitalizedPhrase , ' workout'.
72 Removed: html form: [
73 Removed: self renderDateInputOn: html.
74 Removed: self renderExercisesTableOn: html.
75 Removed: self renderPrimaryMuscleSelectOn: html.
76 Removed: "TODO: use the workout guessPrimaryMuscle."
77 Removed: self renderSecondaryMusclesSelectOn: html.
78 Removed: self renderSubmitWorkoutOn: html ] ]
79 Removed: ]
80 Removed:
81 Removed: { #category : #rendering }
82 Removed: MFTWorkoutDialog >> renderDateInputOn: html [
83 Removed:
84 Removed: html formGroup: [
85 Removed: html label: 'Date'.
86 Removed: html dateInput5 formControl
87 Removed: value: workout date yyyymmdd;
88 Removed: callback: [ :date | workout date: (Date fromString: date) ] ]
89 Removed: ]
90 Removed:
91 Removed: { #category : #rendering }
92 Removed: MFTWorkoutDialog >> renderExerciseActionsButtonGroupOn: html at: i [
93 Removed:
94 Removed: html buttonGroup: [
95 Removed: html outlineButton
96 Removed: beSecondary;
97 Removed: beSmall;
98 Removed: callback: [ exercises removeAt: i ];
99 Removed: with: 'Delete'.
100 Removed: html outlineButton
101 Removed: beSecondary;
102 Removed: beSmall;
103 Removed: callback: [ self editExerciseAt: i ];
104 Removed: with: 'Edit' ]
105 Removed: ]
106 Removed:
107 Removed: { #category : #rendering }
108 Removed: MFTWorkoutDialog >> renderExercisesRowsOn: html [
109 Removed:
110 Removed: exercises doWithIndex: [ :exercise :i |
111 Removed: html tableRow: [
112 Removed: html tableData: [
113 Removed: self renderExerciseActionsButtonGroupOn: html at: i ].
114 Removed: html tableData: exercise englishName.
115 Removed: html tableData: exercise primaryMuscle englishName.
116 Removed: html tableData: exercise repsBySet asCommaString ] ]
117 Removed: ]
118 Removed:
119 Removed: { #category : #rendering }
120 Removed: MFTWorkoutDialog >> renderExercisesTableOn: html [
121 Removed:
122 Removed: html formGroup: [
123 Removed: html label: 'Exercises'.
124 Removed: html table
125 Removed: class: 'table table-hover';
126 Removed: with: [
127 Removed: exercises isNotEmpty ifTrue: [ self renderTableHeaderOn: html ].
128 Removed: self renderExercisesRowsOn: html.
129 Removed: self renderAddExerciseRowOn: html ] ]
130 Removed: ]
131 Removed:
132 Removed: { #category : #rendering }
133 Removed: MFTWorkoutDialog >> renderPrimaryMuscleSelectOn: html [
134 Removed: "TODO: use the workout guessPrimaryMuscle."
135 Removed:
136 Removed: html formGroup: [
137 Removed: html label: 'Primary muscle'.
138 Removed: html select formControl
139 Removed: list: MFTUtils allMuscleGroups;
140 Removed: selected: workout primaryMuscle;
141 Removed: labels: [ :muscleGroup | muscleGroup englishName ];
142 Removed: callback: [ :group | workout primaryMuscle: group ] ]
143 Removed: ]
144 Removed:
145 Removed: { #category : #rendering }
146 Removed: MFTWorkoutDialog >> renderSecondaryMusclesSelectOn: html [
147 Removed:
148 Removed: html formGroup: [
149 Removed: html label: 'Secondary muscles'.
150 Removed: html multiSelect formControl
151 Removed: list: MFTUtils allMuscleGroups;
152 Removed: selected: workout secondaryMuscles;
153 Removed: labels: [ :muscleGroup | muscleGroup englishName ];
154 Removed: callback: [ :groups | workout secondaryMuscles: groups ] ]
155 Removed: ]
156 Removed:
157 Removed: { #category : #rendering }
158 Removed: MFTWorkoutDialog >> renderSubmitWorkoutOn: html [
159 Removed:
160 Removed: html buttonGroup
161 Removed: class: 'mt-3';
162 Removed: with: [
163 Removed: html formButton
164 Removed: bePrimary;
165 Removed: beSubmit;
166 Removed: callback: [ self answer: (workout exercises: exercises) ];
167 Removed: with: 'Submit'.
168 Removed: html formButton
169 Removed: beSecondary;
170 Removed: callback: [ self answer: nil ];
171 Removed: with: 'Cancel' ]
172 Removed: ]
173 Removed:
174 Removed: { #category : #rendering }
175 Removed: MFTWorkoutDialog >> renderTableHeaderOn: html [
176 Removed:
177 Removed: html tableHead: [
178 Removed: html
179 Removed: tableHeading;
180 Removed: tableHeading: 'Name';
181 Removed: tableHeading: 'Muscles'.
182 Removed: ((exercises collect: #sets) anySatisfy: #isNotEmpty) ifTrue: [
183 Removed: html tableHeading: 'Sets' ] ]
184 Removed: ]
185 Removed:
186 Removed: { #category : #accessing }
187 Removed: MFTWorkoutDialog >> workout [
188 Removed:
189 Removed: ^ workout
190 Removed: ]
191 Removed:
192 Removed: { #category : #accessing }
193 Removed: MFTWorkoutDialog >> workout: aMFTWorkout [
194 Removed:
195 Removed: workout := aMFTWorkout
196 Removed: ]