Compare commits
No commits in common. "e9967ebdc677599d78020bc683a9bd903b428815" and "1a9d532d02265a05f1165cb5553a5b7bdfd94224" have entirely different histories.
e9967ebdc6
...
1a9d532d02
8
main.go
8
main.go
@ -761,9 +761,7 @@ func scheduleList(w http.ResponseWriter, r *http.Request, sess *session.T) { //
|
|||||||
w.Header().Add("Access-Control-Allow-Origin", "*")
|
w.Header().Add("Access-Control-Allow-Origin", "*")
|
||||||
|
|
||||||
request := struct {
|
request := struct {
|
||||||
NodeID int
|
NodeID int
|
||||||
StartDate time.Time
|
|
||||||
EndDate time.Time
|
|
||||||
}{}
|
}{}
|
||||||
body, _ := io.ReadAll(r.Body)
|
body, _ := io.ReadAll(r.Body)
|
||||||
if len(body) > 0 {
|
if len(body) > 0 {
|
||||||
@ -775,14 +773,14 @@ func scheduleList(w http.ResponseWriter, r *http.Request, sess *session.T) { //
|
|||||||
}
|
}
|
||||||
|
|
||||||
var schedules []Schedule
|
var schedules []Schedule
|
||||||
schedules, err = FutureSchedules(sess.UserID, request.NodeID, request.StartDate, request.EndDate)
|
schedules, err = FutureSchedules(sess.UserID, request.NodeID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
responseError(w, err)
|
responseError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
responseData(w, map[string]interface{}{
|
responseData(w, map[string]interface{}{
|
||||||
"OK": true,
|
"OK": true,
|
||||||
"ScheduleEvents": schedules,
|
"ScheduleEvents": schedules,
|
||||||
})
|
})
|
||||||
} // }}}
|
} // }}}
|
||||||
|
26
schedule.go
26
schedule.go
@ -215,17 +215,9 @@ func ExpiredSchedules() (schedules []Schedule) { // {{{
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
} // }}}
|
} // }}}
|
||||||
func FutureSchedules(userID int, nodeID int, start time.Time, end time.Time) (schedules []Schedule, err error) { // {{{
|
func FutureSchedules(userID int, nodeID int) (schedules []Schedule, err error) {// {{{
|
||||||
schedules = []Schedule{}
|
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(`
|
res := service.Db.Conn.QueryRow(`
|
||||||
WITH schedule_events AS (
|
WITH schedule_events AS (
|
||||||
SELECT
|
SELECT
|
||||||
@ -251,14 +243,6 @@ func FutureSchedules(userID int, nodeID int, start time.Time, end time.Time) (sc
|
|||||||
WHEN $2 > 0 THEN n.id = $2
|
WHEN $2 > 0 THEN n.id = $2
|
||||||
ELSE true
|
ELSE true
|
||||||
END
|
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
|
) AND
|
||||||
time >= NOW() AND
|
time >= NOW() AND
|
||||||
NOT acknowledged
|
NOT acknowledged
|
||||||
@ -267,10 +251,8 @@ func FutureSchedules(userID int, nodeID int, start time.Time, end time.Time) (sc
|
|||||||
COALESCE(jsonb_agg(s.*), '[]'::jsonb)
|
COALESCE(jsonb_agg(s.*), '[]'::jsonb)
|
||||||
FROM schedule_events s
|
FROM schedule_events s
|
||||||
`,
|
`,
|
||||||
userID,
|
userID,
|
||||||
nodeID,
|
nodeID,
|
||||||
start,
|
|
||||||
end,
|
|
||||||
)
|
)
|
||||||
var j []byte
|
var j []byte
|
||||||
err = res.Scan(&j)
|
err = res.Scan(&j)
|
||||||
@ -286,4 +268,4 @@ func FutureSchedules(userID int, nodeID int, start time.Time, end time.Time) (sc
|
|||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
} // }}}
|
}// }}}
|
||||||
|
@ -802,38 +802,6 @@ header .menu {
|
|||||||
grid-gap: 8px;
|
grid-gap: 8px;
|
||||||
margin-top: 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) {
|
@media only screen and (max-width: 932px) {
|
||||||
#app.node {
|
#app.node {
|
||||||
grid-template-areas: "header" "crumbs" "child-nodes" "name" "content" "checklist" "schedule" "files" "blank";
|
grid-template-areas: "header" "crumbs" "child-nodes" "name" "content" "checklist" "schedule" "files" "blank";
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
</script>
|
</script>
|
||||||
<script type="text/javascript" src="/js/{{ .VERSION }}/lib/sjcl.js"></script>
|
<script type="text/javascript" src="/js/{{ .VERSION }}/lib/sjcl.js"></script>
|
||||||
<script type="text/javascript" src="/js/{{ .VERSION }}/lib/node_modules/marked/marked.min.js"></script>
|
<script type="text/javascript" src="/js/{{ .VERSION }}/lib/node_modules/marked/marked.min.js"></script>
|
||||||
<script type="text/javascript" src="/js/{{ .VERSION }}/lib/fullcalendar.min.js"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
6
static/js/lib/fullcalendar.min.js
vendored
6
static/js/lib/fullcalendar.min.js
vendored
File diff suppressed because one or more lines are too long
@ -986,41 +986,6 @@ class ProfileSettings extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ScheduleEventList extends Component {
|
class ScheduleEventList extends Component {
|
||||||
static CALENDAR = Symbol('CALENDAR')
|
|
||||||
static LIST = Symbol('LIST')
|
|
||||||
constructor() {//{{{
|
|
||||||
super()
|
|
||||||
this.tab = signal(ScheduleEventList.CALENDAR)
|
|
||||||
}//}}}
|
|
||||||
render() {//{{{
|
|
||||||
var tab
|
|
||||||
switch (this.tab.value) {
|
|
||||||
case ScheduleEventList.CALENDAR:
|
|
||||||
tab = html`<${ScheduleCalendarTab} />`
|
|
||||||
break;
|
|
||||||
case ScheduleEventList.LIST:
|
|
||||||
tab = html`<${ScheduleEventListTab} />`
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<div style="margin: 32px">
|
|
||||||
<div class="folder">
|
|
||||||
<div class="tabs">
|
|
||||||
<div onclick=${() => this.tab.value = ScheduleEventList.CALENDAR} class="tab ${this.tab.value == ScheduleEventList.CALENDAR ? 'selected' : ''}">Calendar</div>
|
|
||||||
<div onclick=${() => this.tab.value = ScheduleEventList.LIST} class="tab ${this.tab.value == ScheduleEventList.LIST ? 'selected' : ''}">List</div>
|
|
||||||
<div class="hack"></div>
|
|
||||||
</div>
|
|
||||||
<div class="content">
|
|
||||||
${tab}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
}//}}}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ScheduleEventListTab extends Component {
|
|
||||||
constructor() {//{{{
|
constructor() {//{{{
|
||||||
super()
|
super()
|
||||||
this.events = signal(null)
|
this.events = signal(null)
|
||||||
@ -1030,12 +995,7 @@ class ScheduleEventListTab extends Component {
|
|||||||
if (this.events.value === null)
|
if (this.events.value === null)
|
||||||
return
|
return
|
||||||
|
|
||||||
let events = this.events.value.sort((a, b) => {
|
let events = this.events.value.map(evt => {
|
||||||
if (a.Time < b.Time) return -1
|
|
||||||
if (a.Time > b.Time) return 1
|
|
||||||
return 0
|
|
||||||
}).map(evt => {
|
|
||||||
console.log(evt)
|
|
||||||
const dt = evt.Time.split('T')
|
const dt = evt.Time.split('T')
|
||||||
const remind = () => {
|
const remind = () => {
|
||||||
if (evt.RemindMinutes > 0)
|
if (evt.RemindMinutes > 0)
|
||||||
@ -1072,45 +1032,5 @@ class ScheduleEventListTab extends Component {
|
|||||||
}//}}}
|
}//}}}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ScheduleCalendarTab extends Component {
|
|
||||||
constructor() {//{{{
|
|
||||||
super()
|
|
||||||
}//}}}
|
|
||||||
componentDidMount() {
|
|
||||||
let calendarEl = document.getElementById('fullcalendar');
|
|
||||||
this.calendar = new FullCalendar.Calendar(calendarEl, {
|
|
||||||
initialView: 'dayGridMonth',
|
|
||||||
events: this.events,
|
|
||||||
eventTimeFormat: {
|
|
||||||
hour12: false,
|
|
||||||
hour: '2-digit',
|
|
||||||
minute: '2-digit',
|
|
||||||
},
|
|
||||||
firstDay: 1,
|
|
||||||
});
|
|
||||||
this.calendar.render();
|
|
||||||
}
|
|
||||||
render() {
|
|
||||||
return html`<div id="fullcalendar"></div>`
|
|
||||||
}
|
|
||||||
events(info, successCallback, failureCallback) {
|
|
||||||
const req = {
|
|
||||||
StartDate: info.startStr,
|
|
||||||
EndDate: info.endStr,
|
|
||||||
}
|
|
||||||
_app.current.request('/schedule/list', req)
|
|
||||||
.then(data => {
|
|
||||||
const fullcalendarEvents = data.ScheduleEvents.map(sch => {
|
|
||||||
return {
|
|
||||||
title: sch.Description,
|
|
||||||
start: sch.Time,
|
|
||||||
url: `/?node=${sch.Node.ID}`,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
successCallback(fullcalendarEvents)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// vim: foldmethod=marker
|
// vim: foldmethod=marker
|
||||||
|
@ -932,47 +932,6 @@ header {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#fullcalendar {
|
|
||||||
margin: 32px;
|
|
||||||
color: #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
.folder {
|
|
||||||
.tabs {
|
|
||||||
border-left: 1px solid #888;
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
.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;
|
|
||||||
|
|
||||||
&.selected {
|
|
||||||
border-bottom: none;
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.hack {
|
|
||||||
border-bottom: 1px solid #888;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.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) {
|
@media only screen and (max-width: 932px) {
|
||||||
#app.node {
|
#app.node {
|
||||||
.layout-crumbs();
|
.layout-crumbs();
|
||||||
|
Loading…
Reference in New Issue
Block a user