This commit is contained in:
parent
89e0b7f9bc
commit
44128365c0
53
api/schedule_history_list_by_day.go
Normal file
53
api/schedule_history_list_by_day.go
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stephenafamo/bob"
|
||||||
|
"github.com/stephenafamo/bob/dialect/sqlite/dialect"
|
||||||
|
"github.com/tigorlazuardi/redmage/models"
|
||||||
|
"github.com/tigorlazuardi/redmage/pkg/errs"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ScheduleHistoryListByDateParams struct {
|
||||||
|
Date time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (params *ScheduleHistoryListByDateParams) FillFromQuery(query Queryable) {
|
||||||
|
var err error
|
||||||
|
params.Date, err = time.Parse("2006-01-02", query.Get("date"))
|
||||||
|
if err != nil {
|
||||||
|
params.Date = time.Now()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (params *ScheduleHistoryListByDateParams) CountQuery() (expr []bob.Mod[*dialect.SelectQuery]) {
|
||||||
|
unixTopTime := time.Date(params.Date.Year(), params.Date.Month(), params.Date.Day(), 23, 59, 59, 0, params.Date.Location()).Unix()
|
||||||
|
unixLowTime := time.Date(params.Date.Year(), params.Date.Month(), params.Date.Day(), 0, 0, 0, 0, params.Date.Location()).Unix()
|
||||||
|
expr = append(expr, models.SelectWhere.ScheduleHistories.CreatedAt.GTE(unixLowTime))
|
||||||
|
expr = append(expr, models.SelectWhere.ScheduleHistories.CreatedAt.LTE(unixTopTime))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (params *ScheduleHistoryListByDateParams) Query() (expr []bob.Mod[*dialect.SelectQuery]) {
|
||||||
|
expr = params.CountQuery()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *API) ScheduleHistoryListByDate(ctx context.Context, params ScheduleHistoryListByDateParams) (result ScheduleHistoryListResult, err error) {
|
||||||
|
ctx, span := tracer.Start(ctx, "*API.ScheduleHistoryListByDate")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
result.Schedules, err = models.ScheduleHistories.Query(ctx, api.db, params.Query()...).All()
|
||||||
|
if err != nil {
|
||||||
|
return result, errs.Wrapw(err, "failed to list schedule histories", "query", params)
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Total, err = models.ScheduleHistories.Query(ctx, api.db, params.CountQuery()...).Count()
|
||||||
|
if err != nil {
|
||||||
|
return result, errs.Wrapw(err, "failed to count schedule histories", "query", params)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
|
@ -2,13 +2,11 @@ package routes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/tigorlazuardi/redmage/api"
|
|
||||||
"github.com/tigorlazuardi/redmage/pkg/errs"
|
"github.com/tigorlazuardi/redmage/pkg/errs"
|
||||||
"github.com/tigorlazuardi/redmage/pkg/log"
|
"github.com/tigorlazuardi/redmage/pkg/log"
|
||||||
"github.com/tigorlazuardi/redmage/views"
|
"github.com/tigorlazuardi/redmage/views"
|
||||||
"github.com/tigorlazuardi/redmage/views/schedulehistoriesview"
|
"github.com/tigorlazuardi/redmage/views/schedulehistories"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (routes *Routes) PageScheduleHistory(rw http.ResponseWriter, req *http.Request) {
|
func (routes *Routes) PageScheduleHistory(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
@ -17,36 +15,24 @@ func (routes *Routes) PageScheduleHistory(rw http.ResponseWriter, req *http.Requ
|
||||||
|
|
||||||
c := views.NewContext(routes.Config, req)
|
c := views.NewContext(routes.Config, req)
|
||||||
|
|
||||||
var data schedulehistoriesview.Data
|
var data schedulehistories.Data
|
||||||
if tz := req.URL.Query().Get("tz"); tz == "" {
|
|
||||||
data.Timezone = time.Local
|
|
||||||
} else {
|
|
||||||
var err error
|
|
||||||
data.Timezone, err = time.LoadLocation(tz)
|
|
||||||
if err != nil {
|
|
||||||
data.Timezone = time.Local
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var params api.ScheduleHistoryListParams
|
data.Params.FillFromQuery(req.URL.Query())
|
||||||
params.FillFromQuery(req.URL.Query())
|
result, err := routes.API.ScheduleHistoryListByDate(ctx, data.Params)
|
||||||
|
|
||||||
result, err := routes.API.ScheduleHistoryList(ctx, params)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.New(ctx).Err(err).Error("Failed to list schedule histories")
|
log.New(ctx).Err(err).Error("Failed to list schedule histories")
|
||||||
code, message := errs.HTTPMessage(err)
|
code, message := errs.HTTPMessage(err)
|
||||||
rw.WriteHeader(code)
|
rw.WriteHeader(code)
|
||||||
data.Error = message
|
data.Error = message
|
||||||
if err := schedulehistoriesview.ScheduleHistoriesview(c, data).Render(ctx, rw); err != nil {
|
if err := schedulehistories.View(c, data).Render(ctx, rw); err != nil {
|
||||||
log.New(ctx).Err(err).Error("Failed to render schedule histories view")
|
log.New(ctx).Err(err).Error("Failed to render schedule histories view")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
data.Schedules = result.Schedules
|
data.ScheduleHistories = result.Schedules
|
||||||
data.Total = result.Total
|
|
||||||
|
|
||||||
if err := schedulehistoriesview.ScheduleHistoriesview(c, data).Render(ctx, rw); err != nil {
|
if err := schedulehistories.View(c, data).Render(ctx, rw); err != nil {
|
||||||
log.New(ctx).Err(err).Error("Failed to render schedule histories view")
|
log.New(ctx).Err(err).Error("Failed to render schedule histories view")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
46
views/icons/chevrons_bold.templ
Normal file
46
views/icons/chevrons_bold.templ
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
package icons
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
templ ChevronBoldRight(class ...string) {
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"
|
||||||
|
viewBox="-5.5 0 26 26"
|
||||||
|
version="1.1"
|
||||||
|
if len(class) > 0 {
|
||||||
|
class={ strings.Join(class, " ") }
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<desc>Created with Sketch Beta.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Page-1" stroke="currentColor" stroke-width="1" fill="currentColor" fill-rule="evenodd" sketch:type="MSPage">
|
||||||
|
<g id="Icon-Set-Filled" sketch:type="MSLayerGroup" transform="translate(-474.000000, -1196.000000)" fill="currentColor">
|
||||||
|
<path d="M488.404,1207.36 L477.637,1197.6 C476.806,1196.76 475.459,1196.76 474.629,1197.6 C473.798,1198.43 473.798,1199.77 474.629,1200.6 L483.885,1209 L474.629,1217.4 C473.798,1218.23 473.798,1219.57 474.629,1220.4 C475.459,1221.24 476.806,1221.24 477.637,1220.4 L488.404,1210.64 C488.854,1210.19 489.052,1209.59 489.015,1209 C489.052,1208.41 488.854,1207.81 488.404,1207.36" id="chevron-right" sketch:type="MSShapeGroup"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ ChevronBoldLeft(class ...string) {
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"
|
||||||
|
viewBox="-5.5 0 26 26"
|
||||||
|
version="1.1"
|
||||||
|
if len(class) > 0 {
|
||||||
|
class={ strings.Join(class, " ") }
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<title>chevron-left</title>
|
||||||
|
<desc>Created with Sketch Beta.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Page-1" stroke="currentColor" stroke-width="1" fill="currentColor" fill-rule="evenodd" sketch:type="MSPage">
|
||||||
|
<g id="Icon-Set-Filled" sketch:type="MSLayerGroup" transform="translate(-423.000000, -1196.000000)" fill="currentColor">
|
||||||
|
<path d="M428.115,1209 L437.371,1200.6 C438.202,1199.77 438.202,1198.43 437.371,1197.6 C436.541,1196.76 435.194,1196.76 434.363,1197.6 L423.596,1207.36 C423.146,1207.81 422.948,1208.41 422.985,1209 C422.948,1209.59 423.146,1210.19 423.596,1210.64 L434.363,1220.4 C435.194,1221.24 436.541,1221.24 437.371,1220.4 C438.202,1219.57 438.202,1218.23 437.371,1217.4 L428.115,1209" id="chevron-left" sketch:type="MSShapeGroup"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
}
|
22
views/icons/refresh.templ
Normal file
22
views/icons/refresh.templ
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package icons
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
templ Refresh(class ...string) {
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
if len(class) > 0 {
|
||||||
|
class={ strings.Join(class, " ") }
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M3 3V8M3 8H8M3 8L6 5.29168C7.59227 3.86656 9.69494 3 12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.71683 21 4.13247 18.008 3.22302 14"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
}
|
151
views/schedulehistories/view.templ
Normal file
151
views/schedulehistories/view.templ
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
package schedulehistories
|
||||||
|
|
||||||
|
import "github.com/tigorlazuardi/redmage/views"
|
||||||
|
import "github.com/tigorlazuardi/redmage/views/components"
|
||||||
|
import "github.com/tigorlazuardi/redmage/models"
|
||||||
|
import "github.com/tigorlazuardi/redmage/api"
|
||||||
|
import "fmt"
|
||||||
|
import "time"
|
||||||
|
import "github.com/tigorlazuardi/redmage/views/icons"
|
||||||
|
|
||||||
|
type Data struct {
|
||||||
|
ScheduleHistories models.ScheduleHistorySlice
|
||||||
|
Params api.ScheduleHistoryListByDateParams
|
||||||
|
Error string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (data Data) isCurrentDay() bool {
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
|
return now.Format(time.DateOnly) == data.Params.Date.Format(time.DateOnly)
|
||||||
|
}
|
||||||
|
|
||||||
|
templ View(c *views.Context, data Data) {
|
||||||
|
@components.Doctype() {
|
||||||
|
@components.Head(c,
|
||||||
|
components.HeadTitle("Schedule History"),
|
||||||
|
)
|
||||||
|
@components.Body(c) {
|
||||||
|
@components.Container() {
|
||||||
|
@Content(c, data)
|
||||||
|
}
|
||||||
|
@components.NotificationContainer() {
|
||||||
|
if data.Error != "" {
|
||||||
|
@components.ErrorNotication(data.Error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
templ Content(c *views.Context, data Data) {
|
||||||
|
<main class="prose min-w-full">
|
||||||
|
<h1>Schedule History ({ time.Local.String() })</h1>
|
||||||
|
<div class="divider my-0"></div>
|
||||||
|
<div
|
||||||
|
class="flex flex-wrap justify-between my-4 items-center"
|
||||||
|
hx-boost="true"
|
||||||
|
hx-select="#root-content"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-target="#root-content"
|
||||||
|
>
|
||||||
|
if data.isCurrentDay() {
|
||||||
|
<a
|
||||||
|
href="/history"
|
||||||
|
class="btn btn-primary btn-outline btn-square text-base-100"
|
||||||
|
>
|
||||||
|
@icons.Refresh("w-6 h-6")
|
||||||
|
</a>
|
||||||
|
} else {
|
||||||
|
<a
|
||||||
|
href={ templ.SafeURL(fmt.Sprintf("/history?date=%s", data.Params.Date.Add(time.Hour*24).Format(time.DateOnly))) }
|
||||||
|
class="btn btn-primary btn-outline btn-square text-base-100"
|
||||||
|
>
|
||||||
|
@icons.ChevronBoldLeft("w-6 h-6")
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
<span class="max-xs:hidden text-primary font-bold sm:text-2xl">{ data.Params.Date.Format("Monday, 02 January 2006") }</span>
|
||||||
|
<span class="xs:hidden text-primary font-bold">{ data.Params.Date.Format("Mon, 02 Jan") }</span>
|
||||||
|
<div class="tooltip" data-tip="Next">
|
||||||
|
<a
|
||||||
|
href={ templ.SafeURL(fmt.Sprintf("/history?date=%s", data.Params.Date.Add(time.Hour*-24).Format(time.DateOnly))) }
|
||||||
|
class="btn btn-primary btn-outline btn-square text-base-100 no-underline"
|
||||||
|
>
|
||||||
|
@icons.ChevronBoldRight("w-6 h-6")
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
if len(data.ScheduleHistories) == 0 {
|
||||||
|
<h2>There are no history schedules found for current date.</h2>
|
||||||
|
}
|
||||||
|
if len(data.ScheduleHistories) > 0 {
|
||||||
|
<div class="grid sm:grid-cols-[1fr,9fr] gap-x-4 gap-y-2 sm:gap-y-4">
|
||||||
|
<span class="font-bold max-sm:hidden text-center">Time</span>
|
||||||
|
<span class="font-bold max-sm:hidden">Event</span>
|
||||||
|
for i, schedule := range data.ScheduleHistories {
|
||||||
|
if i > 0 {
|
||||||
|
<div class="divider sm:hidden"></div>
|
||||||
|
}
|
||||||
|
<div
|
||||||
|
x-data={ fmt.Sprintf(`{ time: %d, get tooltip() { return dayjs.unix(this.time).tz(dayjs.tz.guess()).format('ddd, D MMM YYYY HH:mm:ss Z') } }`, schedule.CreatedAt) }
|
||||||
|
:data-tip="tooltip"
|
||||||
|
class="tooltip"
|
||||||
|
>
|
||||||
|
<p class="font-bold max-sm:text-left my-0">
|
||||||
|
{ time.Unix(schedule.CreatedAt, 0).Format("15:04:05") }
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
if api.ScheduleStatus(schedule.Status) == api.ScheduleStatusDisabled {
|
||||||
|
<span>
|
||||||
|
Subreddit
|
||||||
|
@subredditLink(schedule.Subreddit)
|
||||||
|
scheduler has been set to { api.ScheduleStatusDisabled.String() } status.
|
||||||
|
</span>
|
||||||
|
} else if api.ScheduleStatus(schedule.Status) == api.ScheduleStatusEnabled {
|
||||||
|
<span>
|
||||||
|
Subreddit
|
||||||
|
@subredditLink(schedule.Subreddit)
|
||||||
|
{ " " }
|
||||||
|
has been <b>{ api.ScheduleStatusEnabled.String() }</b> { "for" } automatic scheduling.
|
||||||
|
</span>
|
||||||
|
} else if api.ScheduleStatus(schedule.Status) == api.ScheduleStatusStandby {
|
||||||
|
<span>
|
||||||
|
Subreddit
|
||||||
|
@subredditLink(schedule.Subreddit)
|
||||||
|
{ " " }
|
||||||
|
has finished
|
||||||
|
<b class="text-secondary">{ api.ScheduleStatusDownloading.String() }</b>
|
||||||
|
and turned to <b>{ api.ScheduleStatusStandby.String() }</b> status.
|
||||||
|
</span>
|
||||||
|
} else if api.ScheduleStatus(schedule.Status) == api.ScheduleStatusEnqueued {
|
||||||
|
<span>
|
||||||
|
Subreddit
|
||||||
|
@subredditLink(schedule.Subreddit)
|
||||||
|
{ " " }
|
||||||
|
is <b class="text-accent">{ api.ScheduleStatusEnqueued.String() } </b> { "for" } downloading.
|
||||||
|
</span>
|
||||||
|
} else if api.ScheduleStatus(schedule.Status) == api.ScheduleStatusDownloading {
|
||||||
|
<span>
|
||||||
|
Subreddit
|
||||||
|
@subredditLink(schedule.Subreddit)
|
||||||
|
{ " " }
|
||||||
|
has started <b class="text-secondary">{ api.ScheduleStatusDownloading.String() }</b>.
|
||||||
|
</span>
|
||||||
|
} else if api.ScheduleStatus(schedule.Status) == api.ScheduleStatusError {
|
||||||
|
<span>
|
||||||
|
Subreddit
|
||||||
|
@subredditLink(schedule.Subreddit)
|
||||||
|
{ " " }
|
||||||
|
finishes <b class="text-secondary">{ api.ScheduleStatusDownloading.String() }</b>
|
||||||
|
with <b class="text-error">{ api.ScheduleStatusError.String() }</b> of <span class="text-error">"{ schedule.ErrorMessage }"</span>.
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</main>
|
||||||
|
}
|
||||||
|
|
||||||
|
templ subredditLink(subreddit string) {
|
||||||
|
<a href={ templ.URL(fmt.Sprintf("/subreddits/details/%s", subreddit)) } class="text-primary">{ subreddit }</a>
|
||||||
|
}
|
|
@ -1,46 +0,0 @@
|
||||||
package schedulehistoriesview
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/tigorlazuardi/redmage/models"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Data struct {
|
|
||||||
Error string
|
|
||||||
Schedules models.ScheduleHistorySlice
|
|
||||||
Total int64
|
|
||||||
Timezone *time.Location
|
|
||||||
}
|
|
||||||
|
|
||||||
func (data *Data) splitByDays() (out []*splitByDaySchedules) {
|
|
||||||
for _, schedule := range data.Schedules {
|
|
||||||
day := time.Unix(schedule.CreatedAt, 0).In(data.Timezone)
|
|
||||||
date := time.Date(day.Year(), day.Month(), day.Day(), 0, 0, 0, 0, day.Location())
|
|
||||||
|
|
||||||
var found bool
|
|
||||||
inner:
|
|
||||||
for _, split := range out {
|
|
||||||
if split.Date.Equal(date) {
|
|
||||||
found = true
|
|
||||||
split.Schedules = append(split.Schedules, schedule)
|
|
||||||
break inner
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
out = append(out, &splitByDaySchedules{
|
|
||||||
Day: day,
|
|
||||||
Date: date,
|
|
||||||
Schedules: models.ScheduleHistorySlice{schedule},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
type splitByDaySchedules struct {
|
|
||||||
Day time.Time
|
|
||||||
Date time.Time
|
|
||||||
Schedules models.ScheduleHistorySlice
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
package schedulehistoriesview
|
|
||||||
|
|
||||||
import "github.com/tigorlazuardi/redmage/views"
|
|
||||||
import "github.com/tigorlazuardi/redmage/views/components"
|
|
||||||
import "time"
|
|
||||||
import "github.com/tigorlazuardi/redmage/api"
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
templ ScheduleHistoriesview(c *views.Context, data Data) {
|
|
||||||
@components.Doctype() {
|
|
||||||
@components.Head(c,
|
|
||||||
components.HeadTitle("Schedule History"),
|
|
||||||
)
|
|
||||||
@components.Body(c) {
|
|
||||||
@ScheduleHistoriesContent(c, data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
templ ScheduleHistoriesContent(c *views.Context, data Data) {
|
|
||||||
<main class="prose min-w-full">
|
|
||||||
@components.Container() {
|
|
||||||
if data.Error != "" {
|
|
||||||
@components.ErrorToast(data.Error)
|
|
||||||
} else {
|
|
||||||
<h1>Schedule History ({ time.Local.String() })</h1>
|
|
||||||
<div class="divider my-0"></div>
|
|
||||||
if data.Total < 1 {
|
|
||||||
<h2>There are no history schedules to be found. You can populate this page's history by manually trigger a <a href="/subreddits" class="text-primary">Subreddit</a> { "for" } downloading.</h2>
|
|
||||||
}
|
|
||||||
if data.Total > 0 {
|
|
||||||
<div class="grid">
|
|
||||||
for _, scheduleGroup := range data.splitByDays() {
|
|
||||||
<h2>{ scheduleGroup.Day.Format("Monday, _2 January 2006") }</h2>
|
|
||||||
<div class="divider"></div>
|
|
||||||
<div class="hidden sm:grid sm:grid-cols-[8rem,auto]">
|
|
||||||
<span class="font-bold">Time</span>
|
|
||||||
<span class="font-bold">Event</span>
|
|
||||||
</div>
|
|
||||||
for _, schedule := range scheduleGroup.Schedules {
|
|
||||||
<div class="grid sm:grid-cols-[8rem,auto] mb-4 sm:mb-2">
|
|
||||||
<span>
|
|
||||||
<div
|
|
||||||
data-name="schedule-tooltip"
|
|
||||||
class="tooltip"
|
|
||||||
data-tip={ time.Unix(schedule.CreatedAt, 10).In(time.Local).Format(time.RFC3339) }
|
|
||||||
>
|
|
||||||
<span class="font-bold">{ time.Unix(schedule.CreatedAt, 10).In(time.Local).Format("15:04:05") }</span>
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
if api.ScheduleStatus(schedule.Status) == api.ScheduleStatusDisabled {
|
|
||||||
<span>
|
|
||||||
Subreddit
|
|
||||||
@subredditLink(schedule.Subreddit)
|
|
||||||
scheduler has been set to { api.ScheduleStatusDisabled.String() } status.
|
|
||||||
</span>
|
|
||||||
} else if api.ScheduleStatus(schedule.Status) == api.ScheduleStatusEnabled {
|
|
||||||
<span>
|
|
||||||
Subreddit
|
|
||||||
@subredditLink(schedule.Subreddit)
|
|
||||||
{ " " }
|
|
||||||
has been <b>{ api.ScheduleStatusEnabled.String() }</b> { "for" } automatic scheduling.
|
|
||||||
</span>
|
|
||||||
} else if api.ScheduleStatus(schedule.Status) == api.ScheduleStatusStandby {
|
|
||||||
<span>
|
|
||||||
Subreddit
|
|
||||||
@subredditLink(schedule.Subreddit)
|
|
||||||
{ " " }
|
|
||||||
has finished
|
|
||||||
<b class="text-secondary">{ api.ScheduleStatusDownloading.String() }</b>
|
|
||||||
and turned to <b>{ api.ScheduleStatusStandby.String() }</b> status.
|
|
||||||
</span>
|
|
||||||
} else if api.ScheduleStatus(schedule.Status) == api.ScheduleStatusEnqueued {
|
|
||||||
<span>
|
|
||||||
Subreddit
|
|
||||||
@subredditLink(schedule.Subreddit)
|
|
||||||
{ " " }
|
|
||||||
is <b class="text-accent">{ api.ScheduleStatusEnqueued.String() } </b> { "for" } downloading.
|
|
||||||
</span>
|
|
||||||
} else if api.ScheduleStatus(schedule.Status) == api.ScheduleStatusDownloading {
|
|
||||||
<span>
|
|
||||||
Subreddit
|
|
||||||
@subredditLink(schedule.Subreddit)
|
|
||||||
{ " " }
|
|
||||||
has started <b class="text-secondary">{ api.ScheduleStatusDownloading.String() }</b>.
|
|
||||||
</span>
|
|
||||||
} else if api.ScheduleStatus(schedule.Status) == api.ScheduleStatusError {
|
|
||||||
<span>
|
|
||||||
Subreddit
|
|
||||||
@subredditLink(schedule.Subreddit)
|
|
||||||
{ " " }
|
|
||||||
finishes <b class="text-secondary">{ api.ScheduleStatusDownloading.String() }</b>
|
|
||||||
with <b class="text-error">{ api.ScheduleStatusError.String() }</b> of <span class="text-error">"{ schedule.ErrorMessage }"</span>.
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<script> document.querySelectorAll(`[data-name="schedule-tooltip"]`).forEach((el) => el.dataset.tip = dayjs(el.dataset.tip).tz(dayjs.tz.guess()).format('ddd, D MMM YYYY HH:mm:ss Z') ) </script>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</main>
|
|
||||||
}
|
|
||||||
|
|
||||||
templ subredditLink(subreddit string) {
|
|
||||||
<a href={ templ.URL(fmt.Sprintf("/subreddits/details/%s", subreddit)) } class="text-primary">{ subreddit }</a>
|
|
||||||
}
|
|
Loading…
Reference in a new issue