todo-webclient/client/index.ls

316 lines
7.0 KiB
Plaintext
Raw Normal View History

2019-11-20 19:22:51 +01:00
# first:
# connection to authd
# display the authd widget
#
# second:
# connection to todod
# rewrite the whole body component
2019-12-03 03:47:27 +01:00
# page 1: (TODO) list of lists (or todos)
# display:
# navbar
2019-11-20 19:22:51 +01:00
#
2019-12-03 03:47:27 +01:00
# "element 1" button
# "element 2" button
# ...
# "element x" button
#
# "new list" button
# widgets:
# navbar: [return to list button] [logout]
# element button:
# [todo list name]
# or
# [todo list name] [RIGTHS] [DELETE]
#
# page 2:
# display:
# (TODO) list of tasks (this client has a kanban display of tasks, with columns)
# (TODO) task widget
# widgets:
# task widget:
# TODO
#
# page 3: (TODO) pages about
2019-11-20 19:22:51 +01:00
2019-12-05 01:45:21 +01:00
maquette = require "maquette"
nmd = require "nano-markdown"
authd = require "./authd.ls"
todows = require "./todowebsocket.ls"
bulma = require "./bulma.ls"
Task = require "./task.ls"
Project = require "./project.ls"
Modal = require "./modal.ls"
# ValidationModal = require "./validation-modal.ls"
2019-11-20 19:22:51 +01:00
{create-projector, h} = maquette
projector = create-projector!
model = {
2019-12-03 03:47:27 +01:00
# view: login, todo-list, todo, network-error (TODO: other views, such as rights)
# XXX FIXME TODO: TESTING THINGS
2019-12-05 01:45:21 +01:00
current-view: "login"
2019-12-03 03:47:27 +01:00
2019-12-05 01:45:21 +01:00
viewed-project: void
2019-12-03 03:47:27 +01:00
2019-12-05 01:45:21 +01:00
# current-view: "testing-modals"
2019-12-03 03:47:27 +01:00
# { uid => user data }
2019-11-20 19:22:51 +01:00
users: {}
2019-12-03 03:47:27 +01:00
2019-11-22 18:42:46 +01:00
todo-list: []
port: 9999
2019-12-03 03:47:27 +01:00
authd-url: undefined
2019-11-22 18:42:46 +01:00
todod-url: undefined
authd-ws: undefined
todod-ws: undefined
previous-error: undefined
error: undefined
2019-12-03 03:47:27 +01:00
# TODO: authentication token
2019-11-22 18:42:46 +01:00
jwt: undefined
2019-11-20 19:22:51 +01:00
}
2019-12-03 03:47:27 +01:00
model.authd-url =
(if location.protocol == 'https' then 'wss' else 'ws') +
'://' + location.hostname + \: +
model.port +
"/auth.JSON"
2019-11-22 18:42:46 +01:00
model.todod-url =
2019-12-03 03:47:27 +01:00
(if location.protocol == 'https' then 'wss' else 'ws') +
'://' + location.hostname + \: +
2019-11-22 18:42:46 +01:00
model.port +
2019-12-03 05:29:09 +01:00
"/todo.JSON"
2019-11-20 19:22:51 +01:00
2019-12-03 03:47:27 +01:00
console.log "authd url: " + model.authd-url
console.log "todod url: " + model.todod-url
2019-11-20 19:22:51 +01:00
2019-11-22 16:52:50 +01:00
#
# network configuration
#
2019-11-22 18:42:46 +01:00
model.authd-ws = authd.create-socket model.authd-url
model.todod-ws = todows.create-socket model.todod-url
2019-11-22 16:52:50 +01:00
2019-12-03 03:47:27 +01:00
#
# authd messages management
#
# authd socket errors
authd-on-websocket-error = (event) ->
console.log "WebSocket error.", event
model.current-view := "network-error"
projector.schedule-render!
authd-on-websocket-close = (event) ->
model.current-view := "login"
console.log "WebSocket has been closed.", event
# model.todod-ws.reopen!
projector.schedule-render!
# record changes that need to happen on a network event
model.authd-ws.user-on-socket-error ++= [ authd-on-websocket-error ]
2019-12-03 05:29:09 +01:00
model.authd-ws.user-on-socket-close ++= [ authd-on-websocket-close ]
2019-12-03 03:47:27 +01:00
# authd message handlers
2019-12-03 05:29:09 +01:00
model.authd-ws.add-event-listener \token, (message) ->
2019-12-03 03:47:27 +01:00
model.jwt := message.token
model.current-view := "todo-list"
2019-12-03 05:29:09 +01:00
model.todod-ws.list-lists model.jwt
2019-12-03 03:47:27 +01:00
projector.schedule-render!
2019-12-03 05:29:09 +01:00
model.authd-ws.add-event-listener \error, (message) ->
# console.log "authd error", message
2019-12-03 03:47:27 +01:00
projector.schedule-render!
2019-12-03 05:29:09 +01:00
model.authd-ws.add-event-listener \user, (message) ->
2019-12-03 03:47:27 +01:00
model.users[message.user.uid] := message.user
projector.schedule-render!
# TODO: user-added, user-edited
2019-12-03 03:47:27 +01:00
#
# todod messages management
#
# todod socket errors
2019-11-22 16:52:50 +01:00
on-websocket-error = (event) ->
console.log "WebSocket error.", event
2019-11-22 18:42:46 +01:00
model.current-view := "network-error"
2019-11-22 16:52:50 +01:00
projector.schedule-render!
2019-11-20 19:22:51 +01:00
2019-11-22 18:42:46 +01:00
on-websocket-close = (event) ->
2019-11-20 19:22:51 +01:00
model.current-view := "login"
2019-11-22 18:42:46 +01:00
console.log "WebSocket has been closed.", event
# model.todod-ws.reopen!
2019-11-20 19:22:51 +01:00
2019-11-22 16:52:50 +01:00
projector.schedule-render!
# record changes that need to happen on a network event
2019-12-03 03:47:27 +01:00
model.todod-ws.user-on-socket-error ++= [ on-websocket-error ]
2019-12-03 05:29:09 +01:00
model.todod-ws.user-on-socket-close ++= [ on-websocket-close ]
model.todod-ws.add-event-listener \lists-list, (message) ->
console.log message
2019-12-05 01:45:21 +01:00
model.todo-list := message.lists.map (x) ->
Project.new x, model
projector.schedule-render!
2019-11-22 18:42:46 +01:00
model.todod-ws.add-event-listener \new-list, (message) ->
console.log message
2019-12-05 01:45:21 +01:00
model.todo-list := model.todo-list ++ [ (Project.new message.list, model) ]
projector.schedule-render!
model.todod-ws.add-event-listener \tasks, (message) ->
console.log message
2019-12-05 01:45:21 +01:00
model.todo-list.find((.id == message.list)).tasks := message.tasks
2019-12-03 05:29:09 +01:00
projector.schedule-render!
2019-11-22 18:42:46 +01:00
2019-12-05 01:45:21 +01:00
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"
model.viewed-project := void
projector.schedule-render!
model.todo-list := model.todo-list.filter((.id != message.list))
2019-11-22 18:42:46 +01:00
render-navbar = ->
h \div.navbar [
h \div.navbar-start [
2019-12-03 03:47:27 +01:00
h \a.navbar-item.is-size-2 {
2019-11-22 18:42:46 +01:00
onclick: ->
2019-12-05 01:45:21 +01:00
model.viewed-project := void
2019-11-22 18:42:46 +01:00
model.current-view := "todo-list"
} [ "⌂" ]
]
h \div.navbar-end [
h \a.navbar-item {
onclick: ->
model.current-view := "login"
2019-12-03 03:47:27 +01:00
# TODO: remove anything related to the old session on the client
2019-11-22 18:42:46 +01:00
model.todod-ws.reopen!
} [ "Logout" ]
]
]
render-todo-list = ->
h \div.section model.todo-list.map (project) ->
2019-12-05 01:45:21 +01:00
if project
h \div.box {
key: project.id
onclick: ->
model.current-view := "todo"
model.viewed-project := project.id
model.todod-ws.get-list model.jwt, project.id
} [
bulma.title 4 project.title
]
2019-11-22 16:52:50 +01:00
2019-11-22 18:42:46 +01:00
render-new-project-button = ->
h \div.button.is-primary.is-large.is-fullwidth {
onclick: ->
model.todod-ws.add-list model.jwt, "New project", {
columns: ["Unassigned", "Work in progress", "To be checked", "Being checked", "Done"]
}
2019-12-03 03:47:27 +01:00
} [ "New project!" ]
2019-11-22 18:42:46 +01:00
render-todo = (todo-id) ->
2019-12-05 01:45:21 +01:00
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
projector.schedule-render!
} [ "X" ]
2019-12-03 03:47:27 +01:00
else
h \div.notification.is-error [
bulma.title 3 "Error, we did not get the todo id " + todo-id
]
2019-11-22 16:52:50 +01:00
#
# Pages:
# login
# todo-list
# todo
# network-error
#
2019-11-22 18:42:46 +01:00
render-body = ->
2019-11-20 19:22:51 +01:00
h \div.section [
switch model.current-view
when "login"
2019-11-22 18:42:46 +01:00
authd.login-page model
2019-11-20 19:22:51 +01:00
2019-11-22 18:42:46 +01:00
when "todo-list"
h \div#todo-list [
2019-11-20 19:22:51 +01:00
render-navbar!
2019-11-22 18:42:46 +01:00
render-todo-list!
render-new-project-button!
2019-11-20 19:22:51 +01:00
]
# FIXME: TODO: XXX: modal testing
when "testing-modals"
h \div#testing-modals [
render-navbar!
console.log "rendering a modal"
# bulma.asking-modal model, {}, [ (h \button.button {} [ "rendering a modal" ]) ]
2019-12-04 23:30:12 +01:00
if model.modal
model.modal.render!
render-new-project-button!
]
2019-11-22 18:42:46 +01:00
when "todo"
2019-11-20 19:22:51 +01:00
h \div [
render-navbar!
2019-11-22 18:42:46 +01:00
render-todo model.viewed-project
2019-11-20 19:22:51 +01:00
]
else
h \div.notification.is-error [
"Wait, what? Internal error!"
]
2019-12-05 01:45:21 +01:00
if model.modal
model.modal.render!
2019-11-20 19:22:51 +01:00
]
2019-11-22 18:42:46 +01:00
renderer = ->
render-navbar!
render-body!
2019-11-20 19:22:51 +01:00
document.add-event-listener 'DOMContentLoaded' ->
projector.append document.body, renderer