diff --git a/README.md b/README.md index 9de30de..29b7ff9 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,10 @@ Create an empty database. The configured user needs to be able to create and alt Create a configuration file `$HOME/.config/notes.yaml` with the following content: ```yaml +network: + address: '[::]' + port: 1371 + websocket: domains: - notes.com diff --git a/main.go b/main.go index e69bb90..1b1b6a1 100644 --- a/main.go +++ b/main.go @@ -761,7 +761,9 @@ func scheduleList(w http.ResponseWriter, r *http.Request, sess *session.T) { // w.Header().Add("Access-Control-Allow-Origin", "*") request := struct { - NodeID int + NodeID int + StartDate time.Time + EndDate time.Time }{} body, _ := io.ReadAll(r.Body) if len(body) > 0 { @@ -773,14 +775,14 @@ func scheduleList(w http.ResponseWriter, r *http.Request, sess *session.T) { // } var schedules []Schedule - schedules, err = FutureSchedules(sess.UserID, request.NodeID) + schedules, err = FutureSchedules(sess.UserID, request.NodeID, request.StartDate, request.EndDate) if err != nil { responseError(w, err) return } responseData(w, map[string]interface{}{ - "OK": true, + "OK": true, "ScheduleEvents": schedules, }) } // }}} diff --git a/node.go b/node.go index 66b5a3e..a78785b 100644 --- a/node.go +++ b/node.go @@ -325,6 +325,10 @@ func CreateNode(userID, parentID int, name string) (node Node, err error) { // { return } // }}} func UpdateNode(userID, nodeID, timeOffset int, content string, cryptoKeyID int, markdown bool) (err error) { // {{{ + if nodeID == 0 { + return + } + var timezone string row := service.Db.Conn.QueryRow(`SELECT timezone FROM _webservice.user WHERE id=$1`, userID) err = row.Scan(&timezone) diff --git a/schedule.go b/schedule.go index 823126a..fe4b7b5 100644 --- a/schedule.go +++ b/schedule.go @@ -36,7 +36,6 @@ func scheduleHandler() { // {{{ tick := time.NewTicker(time.Minute) for { schedules := ExpiredSchedules() - logger.Info("FOO", "schedules", schedules) for _, event := range schedules { notificationManager.Send( event.UserID, @@ -216,9 +215,17 @@ func ExpiredSchedules() (schedules []Schedule) { // {{{ } return } // }}} -func FutureSchedules(userID int, nodeID int) (schedules []Schedule, err error) {// {{{ +func FutureSchedules(userID int, nodeID int, start time.Time, end time.Time) (schedules []Schedule, err error) { // {{{ schedules = []Schedule{} + var foo string + row := service.Db.Conn.QueryRow(`SELECT TO_CHAR($1::date AT TIME ZONE 'UTC', 'yyyy-mm-dd HH24:MI')`, start) + err = row.Scan(&foo) + if err != nil { + return + } + logger.Info("FOO", "date", foo) + res := service.Db.Conn.QueryRow(` WITH schedule_events AS ( SELECT @@ -230,7 +237,7 @@ func FutureSchedules(userID int, nodeID int) (schedules []Schedule, err error) { 'updated', n.updated ) AS node, s.schedule_uuid, - time AT TIME ZONE 'UTC' AS time, + time AT TIME ZONE u.timezone AS time, s.description, s.acknowledged, s.remind_minutes AS RemindMinutes @@ -244,6 +251,14 @@ func FutureSchedules(userID int, nodeID int) (schedules []Schedule, err error) { WHEN $2 > 0 THEN n.id = $2 ELSE true END + ) AND ( + CASE WHEN TO_CHAR($3::date, 'yyyy-mm-dd HH24:MI') = '0001-01-01 00:00' THEN TRUE + ELSE (s.time AT TIME ZONE u.timezone) >= $3 + END + ) AND ( + CASE WHEN TO_CHAR($4::date, 'yyyy-mm-dd HH24:MI') = '0001-01-01 00:00' THEN TRUE + ELSE (s.time AT TIME ZONE u.timezone) <= $4 + END ) AND time >= NOW() AND NOT acknowledged @@ -252,8 +267,10 @@ func FutureSchedules(userID int, nodeID int) (schedules []Schedule, err error) { COALESCE(jsonb_agg(s.*), '[]'::jsonb) FROM schedule_events s `, - userID, - nodeID, + userID, + nodeID, + start, + end, ) var j []byte err = res.Scan(&j) @@ -269,4 +286,4 @@ func FutureSchedules(userID int, nodeID int) (schedules []Schedule, err error) { } return -}// }}} +} // }}} diff --git a/static/css/main.css b/static/css/main.css index b4a783f..2617798 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -13,6 +13,11 @@ html { *:after { box-sizing: inherit; } +*, +*:focus, +*:hover { + outline: none; +} [onClick] { cursor: pointer; } @@ -413,6 +418,7 @@ header .menu { cursor: pointer; } #checklist .checklist-item { + transform: translate(0, 0); display: grid; grid-template-columns: repeat(3, min-content); grid-gap: 0 8px; @@ -778,6 +784,56 @@ header .menu { #schedule-events .header { font-weight: bold; } +#input-text { + border: 1px solid #000 !important; + padding: 16px; + width: 300px; +} +#input-text .label { + margin-bottom: 4px; +} +#input-text input[type=text] { + width: 100%; + padding: 4px; +} +#input-text .buttons { + display: grid; + grid-template-columns: 1fr 64px 64px; + grid-gap: 8px; + margin-top: 8px; +} +#fullcalendar { + margin: 32px; + color: #444; +} +.folder .tabs { + border-left: 1px solid #888; + display: flex; +} +.folder .tabs .tab { + padding: 16px 32px; + border-top: 1px solid #888; + border-bottom: 1px solid #888; + border-right: 1px solid #888; + color: #444; + background: #eee; + cursor: pointer; +} +.folder .tabs .tab.selected { + border-bottom: none; + background: #fff; +} +.folder .tabs .hack { + border-bottom: 1px solid #888; + width: 100%; +} +.folder .content { + padding-top: 1px; + border-left: 1px solid #888; + border-right: 1px solid #888; + border-bottom: 1px solid #888; + padding-bottom: 1px; +} @media only screen and (max-width: 932px) { #app.node { grid-template-areas: "header" "crumbs" "child-nodes" "name" "content" "checklist" "schedule" "files" "blank"; diff --git a/static/index.html b/static/index.html index ac87bce..5ed40a5 100644 --- a/static/index.html +++ b/static/index.html @@ -27,6 +27,7 @@ +
diff --git a/static/js/checklist.mjs b/static/js/checklist.mjs index 1e639a8..b84cd8b 100644 --- a/static/js/checklist.mjs +++ b/static/js/checklist.mjs @@ -110,10 +110,11 @@ export class Checklist extends Component { this.groupElements = {} this.state = { confirmDeletion: true, + continueAddingItems: true, } window._checklist = this }//}}} - render({ ui, groups }, { confirmDeletion }) {//{{{ + render({ ui, groups }, { confirmDeletion, continueAddingItems }) {//{{{ this.groupElements = {} if (groups.length == 0 && !ui.node.value.ShowChecklist.value) return @@ -136,6 +137,10 @@ export class Checklist extends Component { this.setState({ confirmDeletion: !confirmDeletion })} /> +