subreddit-add: added cron scheduler input

This commit is contained in:
Tigor Hutasuhut 2024-05-03 11:59:44 +07:00
parent 4e7f91d098
commit f4399555b4
5 changed files with 139 additions and 1 deletions

View file

@ -60,6 +60,7 @@ func (routes *Routes) registerHTMXRoutes(router chi.Router) {
router.Post("/subreddits/start", routes.SubredditStartDownloadHTMX) router.Post("/subreddits/start", routes.SubredditStartDownloadHTMX)
router.Post("/subreddits/check", routes.SubredditCheckHTMX) router.Post("/subreddits/check", routes.SubredditCheckHTMX)
router.Get("/subreddits/validate/schedule", routes.SubredditValidateScheduleHTMX)
} }
func (routes *Routes) registerWWWRoutes(router chi.Router) { func (routes *Routes) registerWWWRoutes(router chi.Router) {

View file

@ -99,7 +99,7 @@ func (routes *Routes) SubredditCheckHTMX(rw http.ResponseWriter, r *http.Request
} }
if exist { if exist {
rw.WriteHeader(http.StatusNotFound) rw.WriteHeader(http.StatusConflict)
data.Error = "subreddit already registered" data.Error = "subreddit already registered"
if err := addview.SubredditInputForm(data).Render(r.Context(), rw); err != nil { if err := addview.SubredditInputForm(data).Render(r.Context(), rw); err != nil {
log.New(r.Context()).Err(err).Error("failed to render subreddit input form") log.New(r.Context()).Err(err).Error("failed to render subreddit input form")

View file

@ -0,0 +1,53 @@
package routes
import (
"fmt"
"net/http"
"strconv"
"time"
"github.com/tigorlazuardi/redmage/pkg/log"
"github.com/tigorlazuardi/redmage/views/subredditsview/addview"
)
func (routes *Routes) SubredditValidateScheduleHTMX(rw http.ResponseWriter, r *http.Request) {
ctx, span := tracer.Start(r.Context(), "*Routes.SubredditValidateScheduleHTMX")
defer span.End()
var data addview.ScheduleInputData
enabled, _ := strconv.Atoi(r.FormValue("enable_schedule"))
data.Disabled = enabled == 0
data.Value = r.FormValue("schedule")
if data.Value == "" {
if err := addview.ScheduleInput(data).Render(ctx, rw); err != nil {
log.New(ctx).Err(err).Error("failed to render schedule input")
}
return
}
if data.Disabled {
if err := addview.ScheduleInput(data).Render(ctx, rw); err != nil {
log.New(ctx).Err(err).Error("failed to render schedule input")
}
return
}
scheduler, err := cronParser.Parse(data.Value)
if err != nil {
data.Error = fmt.Sprintf("Invalid schedule format: %s", err.Error())
if err := addview.ScheduleInput(data).Render(ctx, rw); err != nil {
log.New(ctx).Err(err).Error("failed to render schedule input")
}
return
}
next := scheduler.Next(time.Now())
data.Valid = fmt.Sprintf("Schedule is valid. Next run at: %s", next.Format("Monday, _2 January 2006 15:04:05 MST"))
if err := addview.ScheduleInput(data).Render(ctx, rw); err != nil {
log.New(ctx).Err(err).Error("failed to render schedule input")
}
}

View file

@ -29,6 +29,9 @@ templ AddviewContent(c *views.Context) {
<label id="subreddit-type-input" class="form-control w-full"> <label id="subreddit-type-input" class="form-control w-full">
@SubredditTypeInput(SubredditTypeData{}) @SubredditTypeInput(SubredditTypeData{})
</label> </label>
<div class="flex gap-4 content-center">
@scheduleInputContainer()
</div>
</form> </form>
} }
</main> </main>

View file

@ -0,0 +1,81 @@
package addview
import "github.com/tigorlazuardi/redmage/views/utils"
type ScheduleInputData struct {
Value string
Error string
Valid string
Disabled bool
}
templ scheduleInputContainer() {
@ScheduleInput(ScheduleInputData{})
<script>
document.addEventListener('DOMContentLoaded', () => htmx.trigger('#schedule-input-group', 'change'))
</script>
}
templ ScheduleInput(data ScheduleInputData) {
<div
id="schedule-input-group"
class="form-control w-full my-auto"
hx-get="/htmx/subreddits/validate/schedule"
hx-trigger="change, input delay:1s"
hx-include="this"
hx-target="this"
hx-swap="outerHTML"
>
<label class="label">
<span
class={ utils.CX(map[string]bool{
"label-text": true,
"text-error": data.Error != "",
"text-success": data.Valid != "",
"text-base": true,
}) }
>Schedule</span>
<div class="tooltip" data-tip="Whether to enable scheduler or not">
if data.Disabled {
<input type="checkbox" name="enable_schedule" value="1" class="toggle toggle-primary"/>
} else {
<input type="checkbox" name="enable_schedule" value="1" class="toggle toggle-primary" checked/>
}
</div>
</label>
if data.Disabled {
<input name="schedule" type="text" placeholder="e.g. '@daily' or '0 0 * * MON'" class="input input-bordered" disabled/>
} else {
<input
name="schedule"
type="text"
placeholder="e.g. '@daily' or '0 0 * * MON'"
value={ data.Value }
class={ utils.CX(map[string]bool{
"input": true,
"input-bordered": true,
"input-error": data.Error != "",
"text-error": data.Error != "",
"input-success": data.Valid != "",
"text-success": data.Valid != "",
}) }
/>
}
<div class="label">
<span
class={ utils.CX(map[string]bool{
"label-text": true,
"text-error": data.Error != "",
"text-success": data.Valid != "",
"min-h-[1rem]": true,
}) }
>
if data.Valid != "" {
{ data.Valid }
} else {
{ data.Error }
}
</span>
</div>
</div>
}