Update to bootstrap 4
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -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
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -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 |
|
||||||
|
|||||||
@@ -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
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
Package { #name : #ContactBook }
|
Package { #name : 'ContactBook' }
|
||||||
|
|||||||
Reference in New Issue
Block a user