1
0

Update to bootstrap 4

This commit is contained in:
2025-10-01 01:00:08 +02:00
parent 8e1b8329bf
commit 4dbc1a7c7c
7 changed files with 89 additions and 83 deletions

View File

@@ -3,16 +3,17 @@ I represent a person with a name and an email address. I'm usually
part of a contact book. part of a contact book.
" "
Class { Class {
#name : #Contact, #name : 'Contact',
#superclass : #Object, #superclass : 'Object',
#instVars : [ #instVars : [
'fullname', 'fullname',
'email' 'email'
], ],
#category : #ContactBook #category : 'ContactBook',
#package : 'ContactBook'
} }
{ #category : #'instance creation' } { #category : 'instance creation' }
Contact class >> newNamed: aNameString email: anEmailString [ Contact class >> newNamed: aNameString email: anEmailString [
^ self new ^ self new
fullname: aNameString; fullname: aNameString;
@@ -20,38 +21,38 @@ Contact class >> newNamed: aNameString email: anEmailString [
yourself yourself
] ]
{ #category : #accessing } { #category : 'accessing' }
Contact >> email [ Contact >> email [
^ email ^ email
] ]
{ #category : #accessing } { #category : 'accessing' }
Contact >> email: anObject [ Contact >> email: anObject [
email := anObject email := anObject
] ]
{ #category : #accessing } { #category : 'accessing' }
Contact >> fullname [ Contact >> fullname [
^ fullname ^ fullname
] ]
{ #category : #accessing } { #category : 'accessing' }
Contact >> fullname: aString [ Contact >> fullname: aString [
fullname := aString fullname := aString
] ]
{ #category : #'as yet unclassified' } { #category : 'as yet unclassified' }
Contact >> gravatarUrl [ Contact >> gravatarUrl [
^ 'http://www.gravatar.com/avatar/', ^ 'http://www.gravatar.com/avatar/',
(MD5 hashMessage: email asString trimBoth asLowercase) hex, (MD5 hashMessage: email asString trimBoth asLowercase) hex,
'.jpg' '.jpg'
] ]
{ #category : #accessing } { #category : 'accessing' }
Contact >> printOn: aStream [ Contact >> printOn: aStream [
aStream aStream
nextPutAll: self fullname; nextPutAll: self fullname;

View File

@@ -1,13 +1,14 @@
Class { Class {
#name : #ContactBook, #name : 'ContactBook',
#superclass : #Object, #superclass : 'Object',
#instVars : [ #instVars : [
'contacts' 'contacts'
], ],
#category : #ContactBook #category : 'ContactBook',
#package : 'ContactBook'
} }
{ #category : #demos } { #category : 'demos' }
ContactBook class >> createDefault [ ContactBook class >> createDefault [
^ self new ^ self new
addContact: (Contact newNamed: 'Damien Cassou' email: 'damien@cassou.me'); addContact: (Contact newNamed: 'Damien Cassou' email: 'damien@cassou.me');
@@ -17,28 +18,28 @@ ContactBook class >> createDefault [
yourself yourself
] ]
{ #category : #writing } { #category : 'writing' }
ContactBook >> addContact: aContact [ ContactBook >> addContact: aContact [
self contacts add: aContact self contacts add: aContact
] ]
{ #category : #reading } { #category : 'reading' }
ContactBook >> contacts [ ContactBook >> contacts [
^ contacts ^ contacts
] ]
{ #category : #initialization } { #category : 'initialization' }
ContactBook >> initialize [ ContactBook >> initialize [
super initialize. super initialize.
contacts := OrderedCollection new contacts := OrderedCollection new
] ]
{ #category : #deleting } { #category : 'deleting' }
ContactBook >> removeContact: aContact [ ContactBook >> removeContact: aContact [
self contacts remove: aContact self contacts remove: aContact
] ]
{ #category : #initialization } { #category : 'initialization' }
ContactBook >> size [ ContactBook >> size [
^ contacts size ^ contacts size
] ]

View File

@@ -1,14 +1,15 @@
Class { Class {
#name : #ContactBookTest, #name : 'ContactBookTest',
#superclass : #TestCase, #superclass : 'TestCase',
#instVars : [ #instVars : [
'blog', 'blog',
'post' 'post'
], ],
#category : #ContactBook #category : 'ContactBook',
#package : 'ContactBook'
} }
{ #category : #running } { #category : 'running' }
ContactBookTest >> setUp [ ContactBookTest >> setUp [
blog := ContactBook new. blog := ContactBook new.
blog addContact: (Contact newNamed: 'Tudor Girba' email: 'tudor@tudorgirba.com'). blog addContact: (Contact newNamed: 'Tudor Girba' email: 'tudor@tudorgirba.com').
@@ -16,25 +17,25 @@ ContactBookTest >> setUp [
post := Contact newNamed: 'Clara Allende' email: 'clari.allende@gmail.com' post := Contact newNamed: 'Clara Allende' email: 'clari.allende@gmail.com'
] ]
{ #category : #tests } { #category : 'tests' }
ContactBookTest >> testAddContact [ ContactBookTest >> testAddContact [
blog addContact: post. blog addContact: post.
self assert: blog size equals: 2 self assert: blog size equals: 2
] ]
{ #category : #tests } { #category : 'tests' }
ContactBookTest >> testContacts [ ContactBookTest >> testContacts [
blog addContact: post. blog addContact: post.
self assert: blog contacts size equals: 2 self assert: blog contacts size equals: 2
] ]
{ #category : #tests } { #category : 'tests' }
ContactBookTest >> testRemoveContact [ ContactBookTest >> testRemoveContact [
blog removeContact: blog contacts first. blog removeContact: blog contacts first.
self assert: blog size equals: 0 self assert: blog size equals: 0
] ]
{ #category : #tests } { #category : 'tests' }
ContactBookTest >> testSize [ ContactBookTest >> testSize [
self assert: blog size equals: 1 self assert: blog size equals: 1
] ]

View File

@@ -1,10 +1,11 @@
Class { Class {
#name : #ContactTest, #name : 'ContactTest',
#superclass : #TestCase, #superclass : 'TestCase',
#category : #ContactBook #category : 'ContactBook',
#package : 'ContactBook'
} }
{ #category : #tests } { #category : 'tests' }
ContactTest >> testCreation [ ContactTest >> testCreation [
| contact | | contact |
@@ -15,7 +16,7 @@ ContactTest >> testCreation [
self assert: contact email equals: 'marcus.denker@inria.fr' self assert: contact email equals: 'marcus.denker@inria.fr'
] ]
{ #category : #tests } { #category : 'tests' }
ContactTest >> testPrinting [ ContactTest >> testPrinting [
| contact | | contact |

View File

@@ -1,94 +1,95 @@
Class { Class {
#name : #WAContact, #name : 'WAContact',
#superclass : #WAComponent, #superclass : 'WAComponent',
#instVars : [ #instVars : [
'contact' 'contact'
], ],
#category : #ContactBook #category : 'ContactBook',
#package : 'ContactBook'
} }
{ #category : #'as yet unclassified' } { #category : 'as yet unclassified' }
WAContact class >> editContact: aContact [ WAContact class >> editContact: aContact [
^ self new ^ self new
setContact: aContact; setContact: aContact;
yourself yourself
] ]
{ #category : #initialization } { #category : 'initialization' }
WAContact >> contact [ WAContact >> contact [
^ contact ^ contact
] ]
{ #category : #initialization } { #category : 'initialization' }
WAContact >> initialize [ WAContact >> initialize [
super initialize. super initialize.
contact := Contact new contact := Contact new
] ]
{ #category : #'as yet unclassified' } { #category : 'as yet unclassified' }
WAContact >> renderButtonsOn: html [ WAContact >> renderButtonsOn: html [
html tbsFormGroup: [ html formGroup: [
html tbsButtonGroup: [ html buttonGroup: [
self self
renderSubmitButtonOn: html; renderSubmitButtonOn: html;
renderCancelButtonOn: html ] ] renderCancelButtonOn: html ] ]
] ]
{ #category : #'as yet unclassified' } { #category : 'as yet unclassified' }
WAContact >> renderCancelButtonOn: html [ WAContact >> renderCancelButtonOn: html [
html tbsButton html outlineButton
beDanger; beDanger;
cancelCallback: [ self answer: nil ]; cancelCallback: [ self answer: nil ];
with: 'Cancel' with: 'Cancel'
] ]
{ #category : #'as yet unclassified' } { #category : 'as yet unclassified' }
WAContact >> renderContentOn: html [ WAContact >> renderContentOn: html [
html tbsContainer: [ html container: [
html heading with: 'Contact Editing'. html heading with: 'Contact Editing'.
html tbsForm with: [ html form with: [
self renderFieldsOn: html. self renderFieldsOn: html.
self renderButtonsOn: html ] ] self renderButtonsOn: html ] ]
] ]
{ #category : #'as yet unclassified' } { #category : 'as yet unclassified' }
WAContact >> renderEmailFieldOn: html [ WAContact >> renderEmailFieldOn: html [
html tbsFormGroup: [ html formGroup: [
html label: 'Email'. html label: 'Email'.
html emailInput html emailInput
tbsFormControl; formControl;
placeholder: 'your@email.eu'; placeholder: 'your@email.eu';
callback: [ :value | self contact email: value ]; callback: [ :value | self contact email: value ];
value: (self contact email ifNil: '') ] value: (self contact email ifNil: '') ]
] ]
{ #category : #'as yet unclassified' } { #category : 'as yet unclassified' }
WAContact >> renderFieldsOn: html [ WAContact >> renderFieldsOn: html [
self renderFullnameFieldOn: html. self renderFullnameFieldOn: html.
self renderEmailFieldOn: html self renderEmailFieldOn: html
] ]
{ #category : #'as yet unclassified' } { #category : 'as yet unclassified' }
WAContact >> renderFullnameFieldOn: html [ WAContact >> renderFullnameFieldOn: html [
html tbsFormGroup: [ html formGroup: [
html label: 'Fullname'. html label: 'Fullname'.
html textInput html textInput
tbsFormControl; formControl;
placeholder: 'fullname'; placeholder: 'fullname';
callback: [ :value | self contact fullname: value ]; callback: [ :value | self contact fullname: value ];
value: (self contact fullname ifNil: '') ] value: (self contact fullname ifNil: '') ]
] ]
{ #category : #'as yet unclassified' } { #category : 'as yet unclassified' }
WAContact >> renderSubmitButtonOn: html [ WAContact >> renderSubmitButtonOn: html [
html tbsSubmitButton html submitButton
beSuccess; beSuccess;
bePrimary; bePrimary;
callback: [ self answer: self contact ]; callback: [ self answer: self contact ];
with: 'Save' with: 'Save'
] ]
{ #category : #initialization } { #category : 'initialization' }
WAContact >> setContact: aContact [ WAContact >> setContact: aContact [
contact := aContact contact := aContact
] ]

View File

@@ -1,49 +1,50 @@
Class { Class {
#name : #WAContactBook, #name : 'WAContactBook',
#superclass : #WAComponent, #superclass : 'WAComponent',
#instVars : [ #instVars : [
'contactBook' 'contactBook'
], ],
#category : #ContactBook #category : 'ContactBook',
#package : 'ContactBook'
} }
{ #category : #initialization } { #category : 'initialization' }
WAContactBook class >> initialize [ WAContactBook class >> initialize [
(WAAdmin register: self asApplicationAt: 'contacts') (WAAdmin register: self asApplicationAt: 'contacts')
addLibrary: JQDeploymentLibrary; addLibrary: JQDeploymentLibrary;
addLibrary: TBSDeploymentLibrary addLibrary: SBSDevelopmentLibrary
] ]
{ #category : #rendering } { #category : 'rendering' }
WAContactBook >> addContact [ WAContactBook >> addContact [
(self call: WAContact new) (self call: WAContact new)
ifNotNil: [ :contact | contactBook addContact: contact ] ifNotNil: [ :contact | contactBook addContact: contact ]
] ]
{ #category : #accessing } { #category : 'accessing' }
WAContactBook >> contactBook [ WAContactBook >> contactBook [
^ contactBook ifNil: [ contactBook := ContactBook createDefault ] ^ contactBook ifNil: [ contactBook := ContactBook createDefault ]
] ]
{ #category : #accessing } { #category : 'accessing' }
WAContactBook >> contacts [ WAContactBook >> contacts [
^ self contactBook contacts ^ self contactBook contacts
] ]
{ #category : #iterating } { #category : 'iterating' }
WAContactBook >> contactsDo: aBlock [ WAContactBook >> contactsDo: aBlock [
self contacts do: aBlock self contacts do: aBlock
] ]
{ #category : #rendering } { #category : 'rendering' }
WAContactBook >> renderButtonsForContact: aContact on: html [ WAContactBook >> renderButtonsForContact: aContact on: html [
html tbsButtonGroup: [ html buttonGroup: [
self self
renderEditButtonForContact: aContact on: html; renderEditButtonForContact: aContact on: html;
renderRemoveButtonForContact: aContact on: html ] renderRemoveButtonForContact: aContact on: html ]
] ]
{ #category : #rendering } { #category : 'rendering' }
WAContactBook >> renderContact: aContact on: html [ WAContactBook >> renderContact: aContact on: html [
html tableRow: [ html tableRow: [
html html
@@ -53,9 +54,9 @@ WAContactBook >> renderContact: aContact on: html [
tableData: [ self renderButtonsForContact: aContact on: html ] ] tableData: [ self renderButtonsForContact: aContact on: html ] ]
] ]
{ #category : #rendering } { #category : 'rendering' }
WAContactBook >> renderContactsOn: html [ WAContactBook >> renderContactsOn: html [
html tbsTable: [ html table: [
html tableHead: [ html tableHead: [
html html
tableHeading: 'Name'; tableHeading: 'Name';
@@ -64,51 +65,51 @@ WAContactBook >> renderContactsOn: html [
self contactsDo: [ :contact | self renderContact: contact on: html ] ] self contactsDo: [ :contact | self renderContact: contact on: html ] ]
] ]
{ #category : #rendering } { #category : 'rendering' }
WAContactBook >> renderContentOn: html [ WAContactBook >> renderContentOn: html [
"Main entry point of the view. Render both a title and the list of contacts." "Main entry point of the view. Render both a title and the list of contacts."
html html
tbsContainer: [ container: [
html heading html heading
level: 1; level: 1;
with: 'My Contact Book'. with: 'My Contact Book'.
html tbsForm: [ html form: [
self renderContactsOn: html. self renderContactsOn: html.
self renderGlobalButtonsOn: html ] ] self renderGlobalButtonsOn: html ] ]
] ]
{ #category : #rendering } { #category : 'rendering' }
WAContactBook >> renderEditButtonForContact: aContact on: html [ WAContactBook >> renderEditButtonForContact: aContact on: html [
html tbsButton html outlineButton
beSuccess; beSuccess;
callback: [ self call: (WAContact editContact: aContact) ]; callback: [ self call: (WAContact editContact: aContact) ];
with: 'Edit' with: 'Edit'
] ]
{ #category : #rendering } { #category : 'rendering' }
WAContactBook >> renderGlobalButtonsOn: html [ WAContactBook >> renderGlobalButtonsOn: html [
html tbsButtonGroup: [ html buttonGroup: [
html tbsButton html outlineButton
beSuccess; beSuccess;
callback: [ self addContact ]; callback: [ self addContact ];
with: 'New contact' ] with: 'New contact' ]
] ]
{ #category : #rendering } { #category : 'rendering' }
WAContactBook >> renderPhotoOf: aContact on: html [ WAContactBook >> renderPhotoOf: aContact on: html [
html image url: aContact gravatarUrl html image url: aContact gravatarUrl
] ]
{ #category : #rendering } { #category : 'rendering' }
WAContactBook >> renderRemoveButtonForContact: aContact on: html [ WAContactBook >> renderRemoveButtonForContact: aContact on: html [
html tbsButton html outlineButton
beDanger; beDanger;
callback: [ self contactBook removeContact: aContact ]; callback: [ self contactBook removeContact: aContact ];
with: 'Remove' with: 'Remove'
] ]
{ #category : #updating } { #category : 'updating' }
WAContactBook >> updateRoot: anHtmlRoot [ WAContactBook >> updateRoot: anHtmlRoot [
super updateRoot: anHtmlRoot. super updateRoot: anHtmlRoot.
anHtmlRoot title: 'Contact Book' anHtmlRoot title: 'Contact Book'

View File

@@ -1 +1 @@
Package { #name : #ContactBook } Package { #name : 'ContactBook' }