From 038e2151fd2325a32d5432b53fa6f73374d2d781 Mon Sep 17 00:00:00 2001
From: Philippe PITTOLI
Date: Thu, 5 Dec 2019 02:28:17 +0100
Subject: [PATCH] better architecture lol
---
client/index.ls | 80 ++++-----
client/project.ls | 150 ++++-------------
client/task.ls | 349 ++++++++++++++++++++--------------------
client/todowebsocket.ls | 40 ++---
4 files changed, 254 insertions(+), 365 deletions(-)
diff --git a/client/index.ls b/client/index.ls
index c71bf05..ee84ac2 100644
--- a/client/index.ls
+++ b/client/index.ls
@@ -19,9 +19,9 @@
# widgets:
# navbar: [return to list button] [logout]
# element button:
-# [todo list name]
+# [project list name]
# or
-# [todo list name] [RIGTHS] [DELETE]
+# [project list name] [RIGTHS] [DELETE]
#
# page 2:
# display:
@@ -47,7 +47,7 @@ Modal = require "./modal.ls"
projector = create-projector!
model = {
- # view: login, todo-list, todo, network-error (TODO: other views, such as rights)
+ # view: login, project-list, project, network-error (TODO: other views, such as rights)
# XXX FIXME TODO: TESTING THINGS
current-view: "login"
@@ -58,7 +58,7 @@ model = {
# { uid => user data }
users: {}
- todo-list: []
+ project-list: []
port: 9999
authd-url: undefined
@@ -69,9 +69,6 @@ model = {
previous-error: undefined
error: undefined
-
- # TODO: authentication token
- jwt: undefined
}
model.authd-url =
@@ -124,9 +121,9 @@ model.authd-ws.user-on-socket-close ++= [ authd-on-websocket-close ]
# authd message handlers
model.authd-ws.add-event-listener \token, (message) ->
- model.jwt := message.token
- model.current-view := "todo-list"
- model.todod-ws.list-lists model.jwt
+ model.current-view := "project-list"
+ model.todod-ws.token := message.token
+ model.todod-ws.list-lists!
projector.schedule-render!
model.authd-ws.add-event-listener \error, (message) ->
@@ -165,29 +162,29 @@ model.todod-ws.user-on-socket-close ++= [ on-websocket-close ]
model.todod-ws.add-event-listener \lists-list, (message) ->
console.log message
- model.todo-list := message.lists.map (x) ->
- Project.new x, model
+ model.project-list := message.lists.map (x) ->
+ Project x, model.todod-ws
projector.schedule-render!
model.todod-ws.add-event-listener \new-list, (message) ->
console.log message
- model.todo-list := model.todo-list ++ [ (Project.new message.list, model) ]
+ model.project-list := model.project-list ++ [ (Project message.list, model.todod-ws) ]
projector.schedule-render!
model.todod-ws.add-event-listener \tasks, (message) ->
console.log message
- model.todo-list.find((.id == message.list)).tasks := message.tasks
+ model.project-list.find((.id == message.list)).tasks := message.tasks
projector.schedule-render!
model.todod-ws.add-event-listener \list-removed, (message) ->
console.log message
- if model.current-view == "todo" && model.viewed-project == message.list
- model.current-view := "todo-list"
+ if model.current-view == "project" && model.viewed-project == message.list
+ model.current-view := "project-list"
model.viewed-project := void
projector.schedule-render!
- model.todo-list := model.todo-list.filter((.id != message.list))
+ model.project-list := model.project-list.filter((.id != message.list))
render-navbar = ->
h \div.navbar [
@@ -195,7 +192,7 @@ render-navbar = ->
h \a.navbar-item.is-size-2 {
onclick: ->
model.viewed-project := void
- model.current-view := "todo-list"
+ model.current-view := "project-list"
} [ "⌂" ]
]
h \div.navbar-end [
@@ -208,15 +205,15 @@ render-navbar = ->
]
]
-render-todo-list = ->
- h \div.section model.todo-list.map (project) ->
+render-project-list = ->
+ h \div.section model.project-list.map (project) ->
if project
h \div.box {
key: project.id
onclick: ->
- model.current-view := "todo"
+ model.current-view := "project"
model.viewed-project := project.id
- model.todod-ws.get-list model.jwt, project.id
+ model.todod-ws.get-list project.id
} [
bulma.title 4 project.title
]
@@ -224,39 +221,26 @@ render-todo-list = ->
render-new-project-button = ->
h \div.button.is-primary.is-large.is-fullwidth {
onclick: ->
- model.todod-ws.add-list model.jwt, "New project", {
+ model.todod-ws.add-list "New project", {
columns: ["Unassigned", "Work in progress", "To be checked", "Being checked", "Done"]
}
} [ "New project!" ]
-render-todo = (todo-id) ->
- todo = model.todo-list.find((.id == todo-id))
- if todo
- todo.render!
- h \div.button.is-danger.is-outlined {
- onclick: ->
- console.log "La modal est crée"
- model.modal := Modal {
- +visible
- content:
- h \p [ "Are you sure you want to remove board #{todo.title}?" ]
- on-validation: ->
- model.todod-ws.remove-list model.jwt, todo.id
- }
- console.log "La modal est crée 2 le retour", model.modal
+render-project = (project-id) ->
+ project = model.project-list.find((.id == project-id))
- projector.schedule-render!
- } [ "X" ]
+ if project
+ project.render!
else
h \div.notification.is-error [
- bulma.title 3 "Error, we did not get the todo id " + todo-id
+ bulma.title 3 "Error, we did not get the project id " + project-id
]
#
# Pages:
# login
-# todo-list
-# todo
+# project-list
+# project
# network-error
#
@@ -266,11 +250,11 @@ render-body = ->
when "login"
authd.login-page model
- when "todo-list"
- h \div#todo-list [
+ when "project-list"
+ h \div#project-list [
render-navbar!
- render-todo-list!
+ render-project-list!
render-new-project-button!
]
@@ -288,11 +272,11 @@ render-body = ->
render-new-project-button!
]
- when "todo"
+ when "project"
h \div [
render-navbar!
- render-todo model.viewed-project
+ render-project model.viewed-project
]
else
diff --git a/client/project.ls b/client/project.ls
index 50cf09f..5601148 100644
--- a/client/project.ls
+++ b/client/project.ls
@@ -2,136 +2,42 @@
h = require 'maquette' .h
bulma = require "./bulma.ls"
Task = require "./task.ls"
+Modal = require './modal.ls'
-module.exports = {
+Project = (self, todod-ws) ->
+ self.todod-ws = todod-ws
+ self.tasks = self.tasks.map (e) -> Task e, self, model
- new: (self, model) ->
- self.tasks = self.tasks.map (e) -> Task.new e, self, model
+ modal = void
- self.render-column = (column) ->
- console.log "render column: ", column
- # bulma.modal {} [(h \div {} [ "rendering " + column ])]
- # h \div.column.is-3 {
- # key: column
- # } [
- # h \div.card.is-column-header {
- # key: column
- # } [
- # h \div.card-header [
- # if model.editing == column.id + ".title"
- # h \input.input {
- # type: "text",
- # value: column
- # onchange: (e) ->
- # console.log "onchange??"
- # model.editing := undefined
+ self.render-column = (column) ->
- # # FIXME: columns = extra properties
- # # model.todod-ws.edit-column self.id, column, {
- # # name: e.target.value
- # # }
- # }
- # else
- # h \div.card-header-title [
- # bulma.title 3 column
- # ]
+ self.render = ->
- # h \a.card-header-icon {
- # key: "edit"
- # onclick: ->
+ # console.log "Project to render: ", self
+ h \div.project {} [
+ h \div.button.is-danger.is-outlined {
+ onclick: ->
+ modal := Modal {
+ +visible
+ content:
+ h \p [ "Are you sure you want to remove board #{self.title}?" ]
+ on-validation: ->
+ self.todod-ws.remove-list self.id
+ }
+ } [ "X" ]
- # # FIXME: columns = extra properties
- # # if model.editing == column + ".title"
- # # model.editing := undefined
- # # else
- # # model.editing := column + ".title"
- # } [
- # "Edit"
- # ]
-
- # if self.tasks.filter((.column == column)).length == 0
- # h \a.card-header-icon {
- # key: "delete"
- # onclick: ->
- # # FIXME
- # # model.editing := column + ".delete"
- # } [
- # "Delete"
- # ]
- # ]
- # if model.editing == column.id + ".delete"
- # h \div.card-content [
- # h \div.button.is-fullwidth.is-danger {
- # onclick: ->
- # model.todod-ws.delete-column self.id, column.id
- # } [ "Delete me!"]
- # ]
- # ]
-
- # for task in self.tasks
- # continue if task.column != column
-
- # task.render!
-
- # h \div.button.is-fullwidth {
- # onclick: ->
- # model.todod-ws.new-task self.id, column.id, {
- # title: "General Kenobi…"
- # description: ""
- # }
- # } [ "New task" ]
- # ]
-
- self.render = ->
-
- console.log "Project to render: ", self
- h \div.list {} [
- h \div.columns [
- if self.extra_properties.columns
- for dom in self.extra_properties.columns.map((column) -> self.render-column(column))
- dom
- ]
+ h \div.columns [
+ if self.extra_properties.columns
+ for dom in self.extra_properties.columns.map((column) -> self.render-column(column))
+ dom
]
- # h \div.column.is-2 {
- # key: "new-column"
- # } [
- # h \div.button.is-fullwidth {
- # onclick: ->
- # model.todod-ws.new-column self.id, "Hello, there!"
- # } [ "New Column" ]
- # ]
- # ]
- # ]
+ if modal
+ modal.render!
+ ]
- # h \div.project {
- # key: self.id
- # } [
- # h \div.hero.is-dark { key: "title" } [
- # h \div.hero-body [
- # # FIXME: Consider using a .level for this.
- # h \div.is-pulled-right {
- # onclick: ->
- # model.editing := self.id + ".name"
- # } [
- # "Edit"
- # ]
+ self
- # if model.editing == self.id + ".name"
- # h \input.input {
- # onchange: (e) ->
- # model.editing := undefined
- # model.todod-ws.edit-project self.id, {
- # name: e.target.value
- # }
- # value: self.name
- # }
- # else
- # h \div.title [ self.name ]
- # ]
- # ]
-
-
- self
-}
+module.exports = Project
diff --git a/client/task.ls b/client/task.ls
index 7433cf2..4edf69a 100644
--- a/client/task.ls
+++ b/client/task.ls
@@ -30,201 +30,200 @@ get-next = (collection, element) ->
found-element := true
-module.exports = {
+Task = (self, project, model) ->
+ self.render = ->
+ author = model.users[self.author]
+ if typeof(author) != "object" and author != "request sent"
+ model.users[self.author] = "request sent"
+ # FIXME: This should go directly to authd.
+ model.todod-ws.get-user self.author
- new: (self, project, model) ->
- self.render = ->
- author = model.users[self.author]
- if typeof(author) != "object" and author != "request sent"
- model.users[self.author] = "request sent"
- # FIXME: This should go directly to authd.
- model.todod-ws.get-user self.author
+ assigned_to = model.users[self.assigned_to]
+ if self.assigned_to and typeof(assigned_to) != "object" and assigned_to != "request sent"
+ model.users[self.assigned_to] = "request sent"
+ # FIXME: This should go directly to authd.
+ model.todod-ws.get-user self.assigned_to
- assigned_to = model.users[self.assigned_to]
- if self.assigned_to and typeof(assigned_to) != "object" and assigned_to != "request sent"
- model.users[self.assigned_to] = "request sent"
- # FIXME: This should go directly to authd.
- model.todod-ws.get-user self.assigned_to
+ is-selected = model.selected == self.id
- is-selected = model.selected == self.id
-
- h (\div.card.is- + (self.color || "dark")), {
- key: self.id
- classes: {
- "is-selected": is-selected
- }
- onclick: ->
- model.selected := self.id
- } [
- h \div.card-content [
- h \div.media [
- h \div.media-left [
- h \img.image.is-48x48.avatar {
- alt: "user image"
- src: if typeof(assigned_to) == "object"
- assigned_to.avatar
- else
- "https://bulma.io/images/placeholders/96x96.png"
- }
- ]
- h \div.media-content [
- if model.editing == self.id + ".title"
- h \input.input {
- value: self.title
- onchange: (e) ->
- model.editing := undefined
- model.todod-ws.edit-task project.id, self.id, {
- title: e.target.value
- }
- } [ self.title ]
+ h (\div.card.is- + (self.color || "dark")), {
+ key: self.id
+ classes: {
+ "is-selected": is-selected
+ }
+ onclick: ->
+ model.selected := self.id
+ } [
+ h \div.card-content [
+ h \div.media [
+ h \div.media-left [
+ h \img.image.is-48x48.avatar {
+ alt: "user image"
+ src: if typeof(assigned_to) == "object"
+ assigned_to.avatar
else
- h \a [
- bulma.title 4 self.title
- ]
-
- if typeof(model.users[self.assigned_to]) == "object"
- user = model.users[self.assigned_to]
-
- h \div.subtitle.is-6 [
- "@" + (user.full_name || user.login)
- ]
- ]
- if ! is-selected && self.description != ""
- h \div.media-right {key: "description-icon"} [
- h \span.icon.is-size-1 [ "🗎" ]
+ "https://bulma.io/images/placeholders/96x96.png"
+ }
+ ]
+ h \div.media-content [
+ if model.editing == self.id + ".title"
+ h \input.input {
+ value: self.title
+ onchange: (e) ->
+ model.editing := undefined
+ model.todod-ws.edit-task project.id, self.id, {
+ title: e.target.value
+ }
+ } [ self.title ]
+ else
+ h \a [
+ bulma.title 4 self.title
]
- if is-selected
- h \div.media-right {key: "edit"} [
- h \a.small {
- onclick: ->
- if model.editing == self.id + ".title"
- model.editing := undefined
- else
- model.editing := self.id + ".title"
- } [
- "Edit"
- ]
- ]
+ if typeof(model.users[self.assigned_to]) == "object"
+ user = model.users[self.assigned_to]
- if is-selected
- h \div.media-right {key: "delete"} [
- h \a.small {
- onclick: ->
- model.editing := self.id + ".delete"
- } [
- "Delete"
- ]
+ h \div.subtitle.is-6 [
+ "@" + (user.full_name || user.login)
]
]
-
- if is-selected
- h \div.content {
- key: self.description
- after-create: (dom) ->
- dom.innerHTML = nmd self.description
- } [
- if model.editing == self.id + ".description"
- h \form.form [
- h \textarea.textarea {
- value: model.editing-data
- oninput: (e) ->
- model.editing-data := e.target.value
- }
- h \div.button.is-fullwidth {
- onclick: ->
- model.todod-ws.edit-task project.id, self.id, {
- description: model.editing-data
- }
- model.editing-data := undefined
- model.editing := undefined
- } [ "Update" ]
- ]
+ if ! is-selected && self.description != ""
+ h \div.media-right {key: "description-icon"} [
+ h \span.icon.is-size-1 [ "🗎" ]
]
if is-selected
- h \span.button.is-small {
- onclick: ->
- model.editing-data := self.description
- model.editing := self.id + ".description"
- } [
- "edit"
+ h \div.media-right {key: "edit"} [
+ h \a.small {
+ onclick: ->
+ if model.editing == self.id + ".title"
+ model.editing := undefined
+ else
+ model.editing := self.id + ".title"
+ } [
+ "Edit"
+ ]
+ ]
+
+ if is-selected
+ h \div.media-right {key: "delete"} [
+ h \a.small {
+ onclick: ->
+ model.editing := self.id + ".delete"
+ } [
+ "Delete"
+ ]
]
]
if is-selected
- h \div.card-footer {key: "assign"} [
- if model.editing == self.id + ".assigned_to"
- h \div.card-footer-item {
- key: "assign.clicked"
- } [
- h \input.input {
- onchange: (e) ->
- model.editing := undefined
- model.todod-ws.edit-task project.id, self.id, {
- assigned_to: Number e.target.value
- }
+ h \div.content {
+ key: self.description
+ after-create: (dom) ->
+ dom.innerHTML = nmd self.description
+ } [
+ if model.editing == self.id + ".description"
+ h \form.form [
+ h \textarea.textarea {
+ value: model.editing-data
+ oninput: (e) ->
+ model.editing-data := e.target.value
}
- ]
- else
- h \a.card-footer-item {
- key: "assign"
- onclick: ->
- model.editing := self.id + ".assigned_to"
- } [ "Assign" ]
- ]
-
- if is-selected
- h \div.card-footer {key: "color"} [
- if model.editing == self.id + ".color"
- h \div.card-footer-item {
- key: "color.clicked"
- } [
- h \input.input {
- onchange: (e) ->
- model.editing := undefined
- model.todod-ws.edit-task project.id, self.id, {
- color: e.target.value
- }
- }
- ]
- else
- h \a.card-footer-item {
- key: "assign"
- onclick: ->
- model.editing := self.id + ".color"
- } [ "Change Color" ]
- ]
-
- if is-selected
- h \div.card-footer {key: "move"} [
- h \a.card-footer-item {
- key: "⇐"
- onclick: ->
- model.todod-ws.edit-task project.id, self.id, {
- column: get-previous project.columns.map((.id)), self.column
- }
- } [ "⇐" ]
-
- if model.editing == self.id + ".delete"
- h \a.card-footer-item {
- key: "delete"
- } [
- h \div.button.is-danger {
+ h \div.button.is-fullwidth {
onclick: ->
- model.todod-ws.delete-task project.id, self.id
- } [ "Delete! For real!" ]
+ model.todod-ws.edit-task project.id, self.id, {
+ description: model.editing-data
+ }
+ model.editing-data := undefined
+ model.editing := undefined
+ } [ "Update" ]
]
+ ]
- h \a.card-footer-item {
- key: "⇒"
- onclick: ->
- model.todod-ws.edit-task project.id, self.id, {
- column: get-next project.columns.map((.id)), self.column
- }
- } [ "⇒" ]
+ if is-selected
+ h \span.button.is-small {
+ onclick: ->
+ model.editing-data := self.description
+ model.editing := self.id + ".description"
+ } [
+ "edit"
]
]
- self
-}
+ if is-selected
+ h \div.card-footer {key: "assign"} [
+ if model.editing == self.id + ".assigned_to"
+ h \div.card-footer-item {
+ key: "assign.clicked"
+ } [
+ h \input.input {
+ onchange: (e) ->
+ model.editing := undefined
+ model.todod-ws.edit-task project.id, self.id, {
+ assigned_to: Number e.target.value
+ }
+ }
+ ]
+ else
+ h \a.card-footer-item {
+ key: "assign"
+ onclick: ->
+ model.editing := self.id + ".assigned_to"
+ } [ "Assign" ]
+ ]
+
+ if is-selected
+ h \div.card-footer {key: "color"} [
+ if model.editing == self.id + ".color"
+ h \div.card-footer-item {
+ key: "color.clicked"
+ } [
+ h \input.input {
+ onchange: (e) ->
+ model.editing := undefined
+ model.todod-ws.edit-task project.id, self.id, {
+ color: e.target.value
+ }
+ }
+ ]
+ else
+ h \a.card-footer-item {
+ key: "assign"
+ onclick: ->
+ model.editing := self.id + ".color"
+ } [ "Change Color" ]
+ ]
+
+ if is-selected
+ h \div.card-footer {key: "move"} [
+ h \a.card-footer-item {
+ key: "⇐"
+ onclick: ->
+ model.todod-ws.edit-task project.id, self.id, {
+ column: get-previous project.columns.map((.id)), self.column
+ }
+ } [ "⇐" ]
+
+ if model.editing == self.id + ".delete"
+ h \a.card-footer-item {
+ key: "delete"
+ } [
+ h \div.button.is-danger {
+ onclick: ->
+ model.todod-ws.delete-task project.id, self.id
+ } [ "Delete! For real!" ]
+ ]
+
+ h \a.card-footer-item {
+ key: "⇒"
+ onclick: ->
+ model.todod-ws.edit-task project.id, self.id, {
+ column: get-next project.columns.map((.id)), self.column
+ }
+ } [ "⇒" ]
+ ]
+ ]
+
+ self
+
+module.exports = Task
diff --git a/client/todowebsocket.ls b/client/todowebsocket.ls
index a07a851..c9d24f1 100644
--- a/client/todowebsocket.ls
+++ b/client/todowebsocket.ls
@@ -80,39 +80,39 @@ module.exports = {
self.socket.send JSON.stringify { mtype: type, payload: opts }
- self.list-lists = (token) ->
+ self.list-lists = ->
self.send request-types[\list-lists], JSON.stringify {
- token: token
+ token: self.token
}
- self.get-list = (token, list-id) ->
+ self.get-list = (list-id) ->
self.send request-types[\get-list], JSON.stringify {
- token: token
+ token: self.token
list: list-id
}
- self.get-tasks = (token, list-id) ->
+ self.get-tasks = (list-id) ->
self.send request-types[\get-tasks], JSON.stringify {
- token: token
+ token: self.token
list: list-id
}
- self.get-task = (token, task-id) ->
+ self.get-task = (task-id) ->
self.send request-types[\get-task], JSON.stringify {
- token: token
+ token: self.token
task: task-id
}
- self.remove-list = (token, list-id) ->
+ self.remove-list = (list-id) ->
self.send request-types[\remove-list], JSON.stringify {
- token: token
+ token: self.token
list: list-id
}
# TODO: extra properties
- self.add-list = (token, title, opts) ->
+ self.add-list = (title, opts) ->
payload = {
- token: token
+ token: self.token
title: title
}
@@ -121,9 +121,9 @@ module.exports = {
self.send request-types[\add-list], JSON.stringify payload
- self.edit-list = (token, list-id, opts) ->
+ self.edit-list = (list-id, opts) ->
payload = {
- token: token
+ token: self.token
list: list-id
}
@@ -132,16 +132,16 @@ module.exports = {
self.send request-types[\edit-list], JSON.stringify payload
- self.remove-task = (token, task-id) ->
+ self.remove-task = (task-id) ->
self.send request-types[\remove-task], JSON.stringify {
- token: token
+ token: self.token
task: task-id
}
# TODO: extra properties
- self.add-task = (token, list-id, title, opts) ->
+ self.add-task = (list-id, title, opts) ->
payload = {
- token: token
+ token: self.token
list: list-id
title: title
}
@@ -151,9 +151,9 @@ module.exports = {
self.send request-types[\add-task], JSON.stringify payload
- self.edit-task = (token, id, opts) ->
+ self.edit-task = (id, opts) ->
payload = {
- token: token
+ token: self.token
list: list-id
}