better architecture lol

dev
Philippe PITTOLI 2019-12-05 02:28:17 +01:00
parent d5fb4d13fb
commit 038e2151fd
4 changed files with 254 additions and 365 deletions

View File

@ -19,9 +19,9 @@
# widgets: # widgets:
# navbar: [return to list button] [logout] # navbar: [return to list button] [logout]
# element button: # element button:
# [todo list name] # [project list name]
# or # or
# [todo list name] [RIGTHS] [DELETE] # [project list name] [RIGTHS] [DELETE]
# #
# page 2: # page 2:
# display: # display:
@ -47,7 +47,7 @@ Modal = require "./modal.ls"
projector = create-projector! projector = create-projector!
model = { 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 # XXX FIXME TODO: TESTING THINGS
current-view: "login" current-view: "login"
@ -58,7 +58,7 @@ model = {
# { uid => user data } # { uid => user data }
users: {} users: {}
todo-list: [] project-list: []
port: 9999 port: 9999
authd-url: undefined authd-url: undefined
@ -69,9 +69,6 @@ model = {
previous-error: undefined previous-error: undefined
error: undefined error: undefined
# TODO: authentication token
jwt: undefined
} }
model.authd-url = model.authd-url =
@ -124,9 +121,9 @@ model.authd-ws.user-on-socket-close ++= [ authd-on-websocket-close ]
# authd message handlers # authd message handlers
model.authd-ws.add-event-listener \token, (message) -> model.authd-ws.add-event-listener \token, (message) ->
model.jwt := message.token model.current-view := "project-list"
model.current-view := "todo-list" model.todod-ws.token := message.token
model.todod-ws.list-lists model.jwt model.todod-ws.list-lists!
projector.schedule-render! projector.schedule-render!
model.authd-ws.add-event-listener \error, (message) -> 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) -> model.todod-ws.add-event-listener \lists-list, (message) ->
console.log message console.log message
model.todo-list := message.lists.map (x) -> model.project-list := message.lists.map (x) ->
Project.new x, model Project x, model.todod-ws
projector.schedule-render! projector.schedule-render!
model.todod-ws.add-event-listener \new-list, (message) -> model.todod-ws.add-event-listener \new-list, (message) ->
console.log 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! projector.schedule-render!
model.todod-ws.add-event-listener \tasks, (message) -> model.todod-ws.add-event-listener \tasks, (message) ->
console.log 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! projector.schedule-render!
model.todod-ws.add-event-listener \list-removed, (message) -> model.todod-ws.add-event-listener \list-removed, (message) ->
console.log message console.log message
if model.current-view == "todo" && model.viewed-project == message.list if model.current-view == "project" && model.viewed-project == message.list
model.current-view := "todo-list" model.current-view := "project-list"
model.viewed-project := void model.viewed-project := void
projector.schedule-render! 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 = -> render-navbar = ->
h \div.navbar [ h \div.navbar [
@ -195,7 +192,7 @@ render-navbar = ->
h \a.navbar-item.is-size-2 { h \a.navbar-item.is-size-2 {
onclick: -> onclick: ->
model.viewed-project := void model.viewed-project := void
model.current-view := "todo-list" model.current-view := "project-list"
} [ "⌂" ] } [ "⌂" ]
] ]
h \div.navbar-end [ h \div.navbar-end [
@ -208,15 +205,15 @@ render-navbar = ->
] ]
] ]
render-todo-list = -> render-project-list = ->
h \div.section model.todo-list.map (project) -> h \div.section model.project-list.map (project) ->
if project if project
h \div.box { h \div.box {
key: project.id key: project.id
onclick: -> onclick: ->
model.current-view := "todo" model.current-view := "project"
model.viewed-project := project.id 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 bulma.title 4 project.title
] ]
@ -224,39 +221,26 @@ render-todo-list = ->
render-new-project-button = -> render-new-project-button = ->
h \div.button.is-primary.is-large.is-fullwidth { h \div.button.is-primary.is-large.is-fullwidth {
onclick: -> 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"] columns: ["Unassigned", "Work in progress", "To be checked", "Being checked", "Done"]
} }
} [ "New project!" ] } [ "New project!" ]
render-todo = (todo-id) -> render-project = (project-id) ->
todo = model.todo-list.find((.id == todo-id)) project = model.project-list.find((.id == project-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
projector.schedule-render! if project
} [ "X" ] project.render!
else else
h \div.notification.is-error [ 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: # Pages:
# login # login
# todo-list # project-list
# todo # project
# network-error # network-error
# #
@ -266,11 +250,11 @@ render-body = ->
when "login" when "login"
authd.login-page model authd.login-page model
when "todo-list" when "project-list"
h \div#todo-list [ h \div#project-list [
render-navbar! render-navbar!
render-todo-list! render-project-list!
render-new-project-button! render-new-project-button!
] ]
@ -288,11 +272,11 @@ render-body = ->
render-new-project-button! render-new-project-button!
] ]
when "todo" when "project"
h \div [ h \div [
render-navbar! render-navbar!
render-todo model.viewed-project render-project model.viewed-project
] ]
else else

View File

@ -2,136 +2,42 @@
h = require 'maquette' .h h = require 'maquette' .h
bulma = require "./bulma.ls" bulma = require "./bulma.ls"
Task = require "./task.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) -> modal = void
self.tasks = self.tasks.map (e) -> Task.new e, self, model
self.render-column = (column) ->
console.log "render column: ", column
# bulma.modal {} [(h \div {} [ "rendering " + column ])]
# h \div.column.is-3 { self.render-column = (column) ->
# 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
# # FIXME: columns = extra properties self.render = ->
# # model.todod-ws.edit-column self.id, column, {
# # name: e.target.value
# # }
# }
# else
# h \div.card-header-title [
# bulma.title 3 column
# ]
# h \a.card-header-icon { # console.log "Project to render: ", self
# key: "edit" h \div.project {} [
# onclick: -> 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 h \div.columns [
# # if model.editing == column + ".title" if self.extra_properties.columns
# # model.editing := undefined for dom in self.extra_properties.columns.map((column) -> self.render-column(column))
# # else dom
# # 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.column.is-2 { if modal
# key: "new-column" modal.render!
# } [ ]
# h \div.button.is-fullwidth {
# onclick: ->
# model.todod-ws.new-column self.id, "Hello, there!"
# } [ "New Column" ]
# ]
# ]
# ]
# h \div.project { self
# 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"
# ]
# if model.editing == self.id + ".name" module.exports = Project
# 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
}

View File

@ -30,201 +30,200 @@ get-next = (collection, element) ->
found-element := true 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) -> assigned_to = model.users[self.assigned_to]
self.render = -> if self.assigned_to and typeof(assigned_to) != "object" and assigned_to != "request sent"
author = model.users[self.author] model.users[self.assigned_to] = "request sent"
if typeof(author) != "object" and author != "request sent" # FIXME: This should go directly to authd.
model.users[self.author] = "request sent" model.todod-ws.get-user self.assigned_to
# FIXME: This should go directly to authd.
model.todod-ws.get-user self.author
assigned_to = model.users[self.assigned_to] is-selected = model.selected == self.id
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 h (\div.card.is- + (self.color || "dark")), {
key: self.id
h (\div.card.is- + (self.color || "dark")), { classes: {
key: self.id "is-selected": is-selected
classes: { }
"is-selected": is-selected onclick: ->
} model.selected := self.id
onclick: -> } [
model.selected := self.id h \div.card-content [
} [ h \div.media [
h \div.card-content [ h \div.media-left [
h \div.media [ h \img.image.is-48x48.avatar {
h \div.media-left [ alt: "user image"
h \img.image.is-48x48.avatar { src: if typeof(assigned_to) == "object"
alt: "user image" assigned_to.avatar
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 ]
else else
h \a [ "https://bulma.io/images/placeholders/96x96.png"
bulma.title 4 self.title }
] ]
h \div.media-content [
if typeof(model.users[self.assigned_to]) == "object" if model.editing == self.id + ".title"
user = model.users[self.assigned_to] h \input.input {
value: self.title
h \div.subtitle.is-6 [ onchange: (e) ->
"@" + (user.full_name || user.login) model.editing := undefined
] model.todod-ws.edit-task project.id, self.id, {
] title: e.target.value
if ! is-selected && self.description != "" }
h \div.media-right {key: "description-icon"} [ } [ self.title ]
h \span.icon.is-size-1 [ "🗎" ] else
h \a [
bulma.title 4 self.title
] ]
if is-selected if typeof(model.users[self.assigned_to]) == "object"
h \div.media-right {key: "edit"} [ user = model.users[self.assigned_to]
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.subtitle.is-6 [
h \div.media-right {key: "delete"} [ "@" + (user.full_name || user.login)
h \a.small {
onclick: ->
model.editing := self.id + ".delete"
} [
"Delete"
]
] ]
] ]
if ! is-selected && self.description != ""
if is-selected h \div.media-right {key: "description-icon"} [
h \div.content { h \span.icon.is-size-1 [ "🗎" ]
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 if is-selected
h \span.button.is-small { h \div.media-right {key: "edit"} [
onclick: -> h \a.small {
model.editing-data := self.description onclick: ->
model.editing := self.id + ".description" if model.editing == self.id + ".title"
} [ model.editing := undefined
"edit" 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 if is-selected
h \div.card-footer {key: "assign"} [ h \div.content {
if model.editing == self.id + ".assigned_to" key: self.description
h \div.card-footer-item { after-create: (dom) ->
key: "assign.clicked" dom.innerHTML = nmd self.description
} [ } [
h \input.input { if model.editing == self.id + ".description"
onchange: (e) -> h \form.form [
model.editing := undefined h \textarea.textarea {
model.todod-ws.edit-task project.id, self.id, { value: model.editing-data
assigned_to: Number e.target.value oninput: (e) ->
} model.editing-data := e.target.value
} }
] h \div.button.is-fullwidth {
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: -> onclick: ->
model.todod-ws.delete-task project.id, self.id model.todod-ws.edit-task project.id, self.id, {
} [ "Delete! For real!" ] description: model.editing-data
}
model.editing-data := undefined
model.editing := undefined
} [ "Update" ]
] ]
]
h \a.card-footer-item { if is-selected
key: "⇒" h \span.button.is-small {
onclick: -> onclick: ->
model.todod-ws.edit-task project.id, self.id, { model.editing-data := self.description
column: get-next project.columns.map((.id)), self.column 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

View File

@ -80,39 +80,39 @@ module.exports = {
self.socket.send JSON.stringify { mtype: type, payload: opts } self.socket.send JSON.stringify { mtype: type, payload: opts }
self.list-lists = (token) -> self.list-lists = ->
self.send request-types[\list-lists], JSON.stringify { 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 { self.send request-types[\get-list], JSON.stringify {
token: token token: self.token
list: list-id list: list-id
} }
self.get-tasks = (token, list-id) -> self.get-tasks = (list-id) ->
self.send request-types[\get-tasks], JSON.stringify { self.send request-types[\get-tasks], JSON.stringify {
token: token token: self.token
list: list-id list: list-id
} }
self.get-task = (token, task-id) -> self.get-task = (task-id) ->
self.send request-types[\get-task], JSON.stringify { self.send request-types[\get-task], JSON.stringify {
token: token token: self.token
task: task-id task: task-id
} }
self.remove-list = (token, list-id) -> self.remove-list = (list-id) ->
self.send request-types[\remove-list], JSON.stringify { self.send request-types[\remove-list], JSON.stringify {
token: token token: self.token
list: list-id list: list-id
} }
# TODO: extra properties # TODO: extra properties
self.add-list = (token, title, opts) -> self.add-list = (title, opts) ->
payload = { payload = {
token: token token: self.token
title: title title: title
} }
@ -121,9 +121,9 @@ module.exports = {
self.send request-types[\add-list], JSON.stringify payload self.send request-types[\add-list], JSON.stringify payload
self.edit-list = (token, list-id, opts) -> self.edit-list = (list-id, opts) ->
payload = { payload = {
token: token token: self.token
list: list-id list: list-id
} }
@ -132,16 +132,16 @@ module.exports = {
self.send request-types[\edit-list], JSON.stringify payload 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 { self.send request-types[\remove-task], JSON.stringify {
token: token token: self.token
task: task-id task: task-id
} }
# TODO: extra properties # TODO: extra properties
self.add-task = (token, list-id, title, opts) -> self.add-task = (list-id, title, opts) ->
payload = { payload = {
token: token token: self.token
list: list-id list: list-id
title: title title: title
} }
@ -151,9 +151,9 @@ module.exports = {
self.send request-types[\add-task], JSON.stringify payload self.send request-types[\add-task], JSON.stringify payload
self.edit-task = (token, id, opts) -> self.edit-task = (id, opts) ->
payload = { payload = {
token: token token: self.token
list: list-id list: list-id
} }