summaryrefslogtreecommitdiff
path: root/pharo-mooc/tiny-blog/src/TinyBlog-Components
diff options
context:
space:
mode:
Diffstat (limited to 'pharo-mooc/tiny-blog/src/TinyBlog-Components')
-rw-r--r--pharo-mooc/tiny-blog/src/TinyBlog-Components/TBAdminComponent.class.st24
-rw-r--r--pharo-mooc/tiny-blog/src/TinyBlog-Components/TBAdminHeaderComponent.class.st34
-rw-r--r--pharo-mooc/tiny-blog/src/TinyBlog-Components/TBApplicationRootComponent.class.st57
-rw-r--r--pharo-mooc/tiny-blog/src/TinyBlog-Components/TBAuthenticationComponent.class.st125
-rw-r--r--pharo-mooc/tiny-blog/src/TinyBlog-Components/TBCategoriesComponent.class.st61
-rw-r--r--pharo-mooc/tiny-blog/src/TinyBlog-Components/TBHeaderComponent.class.st78
-rw-r--r--pharo-mooc/tiny-blog/src/TinyBlog-Components/TBPostComponent.class.st42
-rw-r--r--pharo-mooc/tiny-blog/src/TinyBlog-Components/TBPostsListComponent.class.st142
-rw-r--r--pharo-mooc/tiny-blog/src/TinyBlog-Components/TBScreenComponent.class.st37
-rw-r--r--pharo-mooc/tiny-blog/src/TinyBlog-Components/TBSession.class.st33
-rw-r--r--pharo-mooc/tiny-blog/src/TinyBlog-Components/package.st1
11 files changed, 634 insertions, 0 deletions
diff --git a/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBAdminComponent.class.st b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBAdminComponent.class.st
new file mode 100644
index 0000000..c35cc95
--- /dev/null
+++ b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBAdminComponent.class.st
@@ -0,0 +1,24 @@
+Class {
+ #name : 'TBAdminComponent',
+ #superclass : 'TBScreenComponent',
+ #category : 'TinyBlog-Components',
+ #package : 'TinyBlog-Components'
+}
+
+{ #category : 'initialization' }
+TBAdminComponent >> createHeaderComponent [
+ ^ TBAdminHeaderComponent from: self
+]
+
+{ #category : 'rendering' }
+TBAdminComponent >> goToPostListView [
+ self answer
+]
+
+{ #category : 'acccessing' }
+TBAdminComponent >> renderContentOn: html [
+ super renderContentOn: html.
+ html container: [
+ html heading: 'Blog Admin'.
+ html horizontalRule ]
+]
diff --git a/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBAdminHeaderComponent.class.st b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBAdminHeaderComponent.class.st
new file mode 100644
index 0000000..cf7e8cd
--- /dev/null
+++ b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBAdminHeaderComponent.class.st
@@ -0,0 +1,34 @@
+Class {
+ #name : 'TBAdminHeaderComponent',
+ #superclass : 'TBHeaderComponent',
+ #category : 'TinyBlog-Components',
+ #package : 'TinyBlog-Components'
+}
+
+{ #category : 'rendering' }
+TBAdminHeaderComponent >> renderButtonsOn: html [
+ html form: [
+ self renderDisconnectButtonOn: html.
+ self renderPublicViewButton: html ]
+]
+
+{ #category : 'rendering' }
+TBAdminHeaderComponent >> renderDisconnectButtonOn: html [
+ html formButton
+ beSecondary;
+ callback: [ self session reset ];
+ with: [
+ html text: 'Disconnect'.
+ html span class: 'glyphicon glyphicon-logout' ]
+]
+
+{ #category : 'rendering' }
+TBAdminHeaderComponent >> renderPublicViewButton: html [
+ self session isLogged ifTrue: [
+ html formButton
+ beSecondary;
+ callback: [ component goToPostListView ];
+ with: [
+ html span class: 'glyphicon glyphicon-eye-open'.
+ html text: ' Public View' ] ]
+]
diff --git a/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBApplicationRootComponent.class.st b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBApplicationRootComponent.class.st
new file mode 100644
index 0000000..6c8d80c
--- /dev/null
+++ b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBApplicationRootComponent.class.st
@@ -0,0 +1,57 @@
+Class {
+ #name : 'TBApplicationRootComponent',
+ #superclass : 'WAComponent',
+ #instVars : [
+ 'main'
+ ],
+ #category : 'TinyBlog-Components',
+ #package : 'TinyBlog-Components'
+}
+
+{ #category : 'testing' }
+TBApplicationRootComponent class >> canBeRoot [
+ ^ true
+]
+
+{ #category : 'initialization' }
+TBApplicationRootComponent class >> initialize [
+ "self initialize"
+ | app |
+ app := WAAdmin register: self asApplicationAt: 'TinyBlog'.
+ app
+ preferenceAt: #sessionClass put: TBSession.
+ app
+ addLibrary: JQDeploymentLibrary;
+ addLibrary: JQUiDeploymentLibrary;
+ addLibrary: SBSDeploymentLibrary
+]
+
+{ #category : 'rendering' }
+TBApplicationRootComponent >> children [
+ ^ { main }
+]
+
+{ #category : 'initialization' }
+TBApplicationRootComponent >> initialize [
+ super initialize.
+ main := TBPostsListComponent new
+]
+
+{ #category : 'initialization' }
+TBApplicationRootComponent >> main: aComponent [
+
+ main := aComponent
+]
+
+{ #category : 'rendering' }
+TBApplicationRootComponent >> renderContentOn: html [
+ html render: main.
+ SBSDeploymentLibrary addLoadScriptTo: html
+]
+
+{ #category : 'rendering' }
+TBApplicationRootComponent >> updateRoot: anHtmlRoot [
+ super updateRoot: anHtmlRoot.
+ anHtmlRoot beHtml5.
+ anHtmlRoot title: 'TinyBlog'
+]
diff --git a/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBAuthenticationComponent.class.st b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBAuthenticationComponent.class.st
new file mode 100644
index 0000000..b76cb6b
--- /dev/null
+++ b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBAuthenticationComponent.class.st
@@ -0,0 +1,125 @@
+Class {
+ #name : 'TBAuthenticationComponent',
+ #superclass : 'SBSComponent',
+ #instVars : [
+ 'password',
+ 'account',
+ 'component'
+ ],
+ #category : 'TinyBlog-Components',
+ #package : 'TinyBlog-Components'
+}
+
+{ #category : 'instance creation' }
+TBAuthenticationComponent class >> from: aComponent [
+ ^ self new
+ component: aComponent;
+ yourself
+]
+
+{ #category : 'accessing' }
+TBAuthenticationComponent >> account [
+
+ ^ account
+]
+
+{ #category : 'accessing' }
+TBAuthenticationComponent >> account: anObject [
+
+ account := anObject
+]
+
+{ #category : 'accessing' }
+TBAuthenticationComponent >> component [
+
+ ^ component
+]
+
+{ #category : 'accessing' }
+TBAuthenticationComponent >> component: anObject [
+
+ component := anObject
+]
+
+{ #category : 'accessing' }
+TBAuthenticationComponent >> password [
+
+ ^ password
+]
+
+{ #category : 'accessing' }
+TBAuthenticationComponent >> password: anObject [
+
+ password := anObject
+]
+
+{ #category : 'rendering' }
+TBAuthenticationComponent >> renderAccountFieldOn: html [
+ html
+ formGroup: [ html label with: 'Account'.
+ html textInput
+ formControl;
+ attributeAt: 'autofocus' put: 'true';
+ callback: [ :value | account := value ];
+ value: account ]
+]
+
+{ #category : 'rendering' }
+TBAuthenticationComponent >> renderBodyOn: html [
+ html
+ modalBody: [
+ html form: [
+ self renderAccountFieldOn: html.
+ self renderPasswordFieldOn: html.
+ html modalFooter: [ self renderButtonsOn: html ] ] ]
+]
+
+{ #category : 'rendering' }
+TBAuthenticationComponent >> renderButtonsOn: html [
+ html formButton
+ beSecondary;
+ dataDismiss: 'modal';
+ value: 'Cancel'.
+ html formButton
+ "beSubmit;"
+ bePrimary;
+ callback: [ self validate ];
+ value: 'SignIn'
+]
+
+{ #category : 'rendering' }
+TBAuthenticationComponent >> renderContentOn: html [
+ html modal
+ id: 'myAuthDialog';
+ fade;
+ with: [
+ html modalDialog: [
+ html modalContent: [
+ self renderHeaderOn: html.
+ self renderBodyOn: html ] ] ]
+]
+
+{ #category : 'rendering' }
+TBAuthenticationComponent >> renderHeaderOn: html [
+ html
+ modalHeader: [
+ html modalCloseButton.
+ html modalTitle
+ level: 4;
+ with: 'Authentication' ]
+]
+
+{ #category : 'rendering' }
+TBAuthenticationComponent >> renderPasswordFieldOn: html [
+ html
+ formGroup: [ html label with: 'Password'.
+ html passwordInput
+ formControl;
+ callback: [ :value | password := value ];
+ value: password ]
+]
+
+{ #category : 'rendering' }
+TBAuthenticationComponent >> validate [
+ ^ component tryConnectionWithLogin: self account andPassword: self password
+]
diff --git a/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBCategoriesComponent.class.st b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBCategoriesComponent.class.st
new file mode 100644
index 0000000..6776186
--- /dev/null
+++ b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBCategoriesComponent.class.st
@@ -0,0 +1,61 @@
+Class {
+ #name : 'TBCategoriesComponent',
+ #superclass : 'TBScreenComponent',
+ #instVars : [
+ 'categories',
+ 'postsList'
+ ],
+ #category : 'TinyBlog-Components',
+ #package : 'TinyBlog-Components'
+}
+
+{ #category : 'instance creation' }
+TBCategoriesComponent class >> categories: categories postsList: aTBScreen [
+ ^ self new categories: categories; postsList: aTBScreen
+]
+
+{ #category : 'accessing' }
+TBCategoriesComponent >> categories [
+
+ ^ categories
+]
+
+{ #category : 'accessing' }
+TBCategoriesComponent >> categories: anObject [
+
+ categories := anObject
+]
+
+{ #category : 'accessing' }
+TBCategoriesComponent >> postsList [
+
+ ^ postsList
+]
+
+{ #category : 'accessing' }
+TBCategoriesComponent >> postsList: anObject [
+
+ postsList := anObject
+]
+
+{ #category : 'actions' }
+TBCategoriesComponent >> renderCategoryLinkOn: html with: aCategory [
+ html listGroupLinkedItem
+ class: 'active' if: aCategory = self postsList currentCategory;
+ callback: [ self selectCategory: aCategory ];
+ with: aCategory
+]
+
+{ #category : 'actions' }
+TBCategoriesComponent >> renderContentOn: html [
+ html listGroup: [
+ html listGroupItem
+ with: [ html strong: 'Categories' ].
+ categories do: [ :cat |
+ self renderCategoryLinkOn: html with: cat ] ]
+]
+
+{ #category : 'actions' }
+TBCategoriesComponent >> selectCategory: aCategory [
+ postsList currentCategory: aCategory
+]
diff --git a/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBHeaderComponent.class.st b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBHeaderComponent.class.st
new file mode 100644
index 0000000..4a95f2a
--- /dev/null
+++ b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBHeaderComponent.class.st
@@ -0,0 +1,78 @@
+Class {
+ #name : 'TBHeaderComponent',
+ #superclass : 'SBSComponent',
+ #instVars : [
+ 'component'
+ ],
+ #category : 'TinyBlog-Components',
+ #package : 'TinyBlog-Components'
+}
+
+{ #category : 'instance creation' }
+TBHeaderComponent class >> from: aComponent [
+ ^ self new
+ component: aComponent;
+ yourself
+]
+
+{ #category : 'accessing' }
+TBHeaderComponent >> component [
+
+ ^ component
+]
+
+{ #category : 'accessing' }
+TBHeaderComponent >> component: anObject [
+
+ component := anObject
+]
+
+{ #category : 'rendering' }
+TBHeaderComponent >> renderBrandOn: html [
+ html navigationBarBrand
+ url: self application url;
+ with: 'TinyBlog'
+]
+
+{ #category : 'rendering' }
+TBHeaderComponent >> renderButtonsOn: html [
+ self session isLogged
+ ifTrue: [ self renderSimpleAdminButtonOn: html ]
+ ifFalse: [ self renderModalLoginButtonOn: html ]
+]
+
+{ #category : 'rendering' }
+TBHeaderComponent >> renderContentOn: html [
+ | bar |
+ bar := html navigationBar.
+
+ bar background beLight.
+ bar with: [
+ html container: [
+ self renderBrandOn: html.
+ self renderButtonsOn: html
+ ]
+ ]
+]
+
+{ #category : 'rendering' }
+TBHeaderComponent >> renderModalLoginButtonOn: html [
+ html render: (TBAuthenticationComponent from: component).
+ html formButton beSecondary;
+ dataTarget: '#myAuthDialog';
+ dataToggle: 'modal';
+ with: [
+ html span class: 'glyphicon glyphicon-lock'.
+ html text: 'Login' ]
+]
+
+{ #category : 'rendering' }
+TBHeaderComponent >> renderSimpleAdminButtonOn: html [
+ html form: [
+ html formButton
+ beSecondary;
+ callback: [ component goToAdministrationView ];
+ with: [
+ html span class: 'glyphicon glyphicon-list-alt'.
+ html text: ' Admin View' ]]
+]
diff --git a/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBPostComponent.class.st b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBPostComponent.class.st
new file mode 100644
index 0000000..f534bf7
--- /dev/null
+++ b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBPostComponent.class.st
@@ -0,0 +1,42 @@
+Class {
+ #name : 'TBPostComponent',
+ #superclass : 'SBSComponent',
+ #instVars : [
+ 'post'
+ ],
+ #category : 'TinyBlog-Components',
+ #package : 'TinyBlog-Components'
+}
+
+{ #category : 'initialization' }
+TBPostComponent >> date [
+ ^ post date
+]
+
+{ #category : 'initialization' }
+TBPostComponent >> initialize [
+ super initialize.
+ post := TBPost new
+]
+
+{ #category : 'initialization' }
+TBPostComponent >> post: aPost [
+ post := aPost
+]
+
+{ #category : 'initialization' }
+TBPostComponent >> renderContentOn: html [
+ html heading level: 2; with: self title.
+ html heading level: 6; with: self date.
+ html text: self text
+]
+
+{ #category : 'initialization' }
+TBPostComponent >> text [
+ ^ post text
+]
+
+{ #category : 'initialization' }
+TBPostComponent >> title [
+ ^ post title
+]
diff --git a/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBPostsListComponent.class.st b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBPostsListComponent.class.st
new file mode 100644
index 0000000..82a9a73
--- /dev/null
+++ b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBPostsListComponent.class.st
@@ -0,0 +1,142 @@
+Class {
+ #name : 'TBPostsListComponent',
+ #superclass : 'TBScreenComponent',
+ #instVars : [
+ 'postComponents',
+ 'currentCategory',
+ 'showLoginError'
+ ],
+ #category : 'TinyBlog-Components',
+ #package : 'TinyBlog-Components'
+}
+
+{ #category : 'rendering' }
+TBPostsListComponent >> basicRenderCategoriesOn: html [
+ html render: self categoriesComponent
+]
+
+{ #category : 'rendering' }
+TBPostsListComponent >> basicRenderPostsOn: html [
+ self readSelectedPosts do: [ :p | html render: (self postComponentFor: p) ]
+]
+
+{ #category : 'rendering' }
+TBPostsListComponent >> categoriesComponent [
+ ^ TBCategoriesComponent
+ categories: self blog allCategories
+ postsList: self
+]
+
+{ #category : 'initialization' }
+TBPostsListComponent >> children [
+ ^ self postComponents, super children
+]
+
+{ #category : 'accessing' }
+TBPostsListComponent >> currentCategory [
+
+ ^ currentCategory
+]
+
+{ #category : 'accessing' }
+TBPostsListComponent >> currentCategory: anObject [
+
+ currentCategory := anObject
+]
+
+{ #category : 'as yet unclassified' }
+TBPostsListComponent >> goToAdministrationView [
+ self call: TBAdminComponent new
+]
+
+{ #category : 'as yet unclassified' }
+TBPostsListComponent >> hasLoginError [
+ ^ showLoginError ifNil: [ false ]
+]
+
+{ #category : 'initialization' }
+TBPostsListComponent >> initialize [
+ super initialize.
+ postComponents := OrderedCollection new
+]
+
+{ #category : 'as yet unclassified' }
+TBPostsListComponent >> loginErrorMessage [
+ ^ 'Incorrect login and/or password'
+]
+
+{ #category : 'as yet unclassified' }
+TBPostsListComponent >> loginErrorOccurred [
+ showLoginError := true
+]
+
+{ #category : 'rendering' }
+TBPostsListComponent >> postComponentFor: aPost [
+ ^ TBPostComponent new post: aPost
+]
+
+{ #category : 'initialization' }
+TBPostsListComponent >> postComponents [
+ postComponents := self readSelectedPosts
+ collect: [ :each | TBPostComponent new post: each ].
+ ^ postComponents
+]
+
+{ #category : 'initialization' }
+TBPostsListComponent >> readSelectedPosts [
+ ^ self currentCategory
+ ifNil: [ self blog allVisibleBlogPosts ]
+ ifNotNil: [ self blog allVisibleBlogPostsFromCategory: self currentCategory ]
+]
+
+{ #category : 'rendering' }
+TBPostsListComponent >> renderCategoryColumnOn: html [
+ html column
+ extraSmallSize: 12;
+ smallSize: 2;
+ mediumSize: 4;
+ with: [ self basicRenderCategoriesOn: html ]
+]
+
+{ #category : 'rendering' }
+TBPostsListComponent >> renderContentOn: html [
+ super renderContentOn: html.
+ html container: [
+ html row
+ with: [
+ html column
+ extraSmallSize: 12;
+ smallSize: 2;
+ mediumSize: 4;
+ with: [ html render: self categoriesComponent ].
+ self renderPostColumnOn: html ] ]
+]
+
+{ #category : 'rendering' }
+TBPostsListComponent >> renderLoginErrorMessageIfAnyOn: html [
+ self hasLoginError ifTrue: [
+ showLoginError := false.
+ html alert
+ beDanger;
+ with: self loginErrorMessage ]
+]
+
+{ #category : 'rendering' }
+TBPostsListComponent >> renderPostColumnOn: html [
+ html column
+ extraSmallSize: 12;
+ smallSize: 10;
+ mediumSize: 8;
+ with: [
+ self renderLoginErrorMessageIfAnyOn: html.
+ self basicRenderPostsOn: html ]
+]
+
+{ #category : 'as yet unclassified' }
+TBPostsListComponent >> tryConnectionWithLogin: login andPassword: password [
+ (login = self blog administrator login and: [ (SHA256 hashMessage: password) = self blog administrator password ])
+ ifTrue: [
+ self session currentAdmin: self blog administrator.
+ self goToAdministrationView ]
+ ifFalse: [ self loginErrorOccurred ]
+]
diff --git a/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBScreenComponent.class.st b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBScreenComponent.class.st
new file mode 100644
index 0000000..ef15b8f
--- /dev/null
+++ b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBScreenComponent.class.st
@@ -0,0 +1,37 @@
+Class {
+ #name : 'TBScreenComponent',
+ #superclass : 'SBSRootComponent',
+ #instVars : [
+ 'header'
+ ],
+ #category : 'TinyBlog-Components',
+ #package : 'TinyBlog-Components'
+}
+
+{ #category : 'acccessing' }
+TBScreenComponent >> blog [
+ "Return the current blog. In the future we will ask the
+ session to return the blog of the currently logged in user."
+ ^ TBBlog current
+]
+
+{ #category : 'acccessing' }
+TBScreenComponent >> children [
+ ^ { header }
+]
+
+{ #category : 'initialization' }
+TBScreenComponent >> createHeaderComponent [
+ ^ TBHeaderComponent from: self
+]
+
+{ #category : 'initialization' }
+TBScreenComponent >> initialize [
+ super initialize.
+ header := self createHeaderComponent
+]
+
+{ #category : 'acccessing' }
+TBScreenComponent >> renderContentOn: html [
+ html render: header
+]
diff --git a/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBSession.class.st b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBSession.class.st
new file mode 100644
index 0000000..f56c40b
--- /dev/null
+++ b/pharo-mooc/tiny-blog/src/TinyBlog-Components/TBSession.class.st
@@ -0,0 +1,33 @@
+Class {
+ #name : 'TBSession',
+ #superclass : 'WASession',
+ #instVars : [
+ 'currentAdmin'
+ ],
+ #category : 'TinyBlog-Components',
+ #package : 'TinyBlog-Components'
+}
+
+{ #category : 'accessing' }
+TBSession >> currentAdmin [
+
+ ^ currentAdmin
+]
+
+{ #category : 'accessing' }
+TBSession >> currentAdmin: anObject [
+
+ currentAdmin := anObject
+]
+
+{ #category : 'testing' }
+TBSession >> isLogged [
+ ^ self currentAdmin notNil
+]
+
+{ #category : 'initialization' }
+TBSession >> reset [
+ currentAdmin := nil.
+ self requestContext redirectTo: self application url.
+ self unregister
+]
diff --git a/pharo-mooc/tiny-blog/src/TinyBlog-Components/package.st b/pharo-mooc/tiny-blog/src/TinyBlog-Components/package.st
new file mode 100644
index 0000000..1f12c30
--- /dev/null
+++ b/pharo-mooc/tiny-blog/src/TinyBlog-Components/package.st
@@ -0,0 +1 @@
+Package { #name : 'TinyBlog-Components' }