Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
289 lines
7.7 KiB
Go
289 lines
7.7 KiB
Go
package automation
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
intAuth "github.com/cortezaproject/corteza/server/pkg/auth"
|
|
"github.com/cortezaproject/corteza/server/pkg/expr"
|
|
"github.com/cortezaproject/corteza/server/pkg/filter"
|
|
. "github.com/cortezaproject/corteza/server/pkg/expr"
|
|
"github.com/cortezaproject/corteza/server/pkg/wfexec"
|
|
"github.com/cortezaproject/corteza/server/system/types"
|
|
sqlxtypes "github.com/jmoiron/sqlx/types"
|
|
)
|
|
|
|
|
|
type(
|
|
reminderService interface {
|
|
FindByID(ctx context.Context,ID uint64) (*types.Reminder, error)
|
|
Find(ctx context.Context, filter types.ReminderFilter) (types.ReminderSet,types.ReminderFilter,error)
|
|
Create(ctx context.Context, reminder *types.Reminder) (*types.Reminder,error)
|
|
Update(ctx context.Context, reminder *types.Reminder) (*types.Reminder,error)
|
|
Delete(ctx context.Context, ID uint64) error
|
|
Dismiss(ctx context.Context, ID uint64) error
|
|
Snooze(ctx context.Context, ID uint64,remindAt *time.Time) error
|
|
}
|
|
|
|
remindersHandler struct {
|
|
reg remindersHandlerRegistry
|
|
rSvc reminderService
|
|
}
|
|
|
|
reminderSetIterator struct {
|
|
// Item buffer, current item pointer, and total items traversed
|
|
ptr uint
|
|
buffer types.ReminderSet
|
|
total uint
|
|
|
|
// When filter limit is set, this constraints it
|
|
iterLimit uint
|
|
useIterLimit bool
|
|
|
|
// Item loader for additional chunks
|
|
filter types.ReminderFilter
|
|
loader func() error
|
|
|
|
// Total reported by the first page
|
|
resTotal uint
|
|
}
|
|
reminderLookup interface {
|
|
GetLookup() (bool, uint64, *types.Reminder)
|
|
}
|
|
|
|
)
|
|
func RemindersHandler(reg remindersHandlerRegistry,rSvc reminderService) *remindersHandler {
|
|
h := &remindersHandler{
|
|
reg : reg,
|
|
rSvc: rSvc,
|
|
}
|
|
h.register()
|
|
return h
|
|
|
|
}
|
|
|
|
func (h remindersHandler) lookup(ctx context.Context, args *remindersLookupArgs) (results *remindersLookupResults, err error){
|
|
results = &remindersLookupResults{}
|
|
results.Reminder, err = lookupReminder(ctx, h.rSvc, args)
|
|
return
|
|
}
|
|
|
|
func (h remindersHandler) search(ctx context.Context,args *remindersSearchArgs) (results *remindersSearchResults,err error){
|
|
results = &remindersSearchResults{}
|
|
var (
|
|
f=types.ReminderFilter{
|
|
Resource: args.Resource,
|
|
AssignedTo: args.AssignedTo,
|
|
ExcludeDismissed: args.ExcludeDismissed,
|
|
ScheduledOnly: args.ScheduledOnly,
|
|
}
|
|
)
|
|
|
|
if args.hasSort {
|
|
if err = f.Sort.Set(args.Sort); err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
if args.hasPageCursor && args.PageCursor != "" {
|
|
f.PageCursor = &filter.PagingCursor{}
|
|
if err = f.PageCursor.UnmarshalJSON([]byte(args.PageCursor)); err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
if args.hasLimit {
|
|
f.Limit = uint(args.Limit)
|
|
}
|
|
|
|
// Total cannot be fetched together with a page cursor
|
|
f.IncTotal = args.IncTotal && f.PageCursor == nil
|
|
|
|
var auxf types.ReminderFilter
|
|
results.Reminders, auxf, err = h.rSvc.Find(ctx, f)
|
|
results.Total=uint64(auxf.Total)
|
|
return
|
|
}
|
|
func (h remindersHandler) each(ctx context.Context, args *remindersEachArgs) (out wfexec.IteratorHandler, err error){
|
|
var(
|
|
i = &reminderSetIterator{}
|
|
f=types.ReminderFilter{
|
|
Resource: args.Resource,
|
|
AssignedTo: args.AssignedTo,
|
|
ExcludeDismissed: args.ExcludeDismissed,
|
|
ScheduledOnly: args.ScheduledOnly,
|
|
}
|
|
)
|
|
if args.hasSort {
|
|
if err = f.Sort.Set(args.Sort); err != nil {
|
|
return
|
|
}
|
|
}
|
|
if args.hasPageCursor && args.PageCursor != "" {
|
|
f.NextPage = &filter.PagingCursor{}
|
|
if err = f.NextPage.UnmarshalJSON([]byte(args.PageCursor)); err != nil {
|
|
return
|
|
}
|
|
}
|
|
f.IncTotal = args.IncTotal
|
|
|
|
if args.hasLimit {
|
|
i.useIterLimit = true
|
|
i.iterLimit = uint(args.Limit)
|
|
f.Limit = uint(args.Limit)
|
|
if args.Limit > uint64(wfexec.MaxIteratorBufferSize) {
|
|
f.Limit = wfexec.MaxIteratorBufferSize
|
|
}
|
|
i.iterLimit = uint(args.Limit)
|
|
} else {
|
|
f.Limit = wfexec.MaxIteratorBufferSize
|
|
}
|
|
i.filter = f
|
|
i.loader = func() (err error) {
|
|
if i.filter.PageCursor != nil && i.filter.NextPage == nil {
|
|
return
|
|
}
|
|
i.total += i.ptr
|
|
i.ptr = 0
|
|
i.filter.PageCursor = i.filter.NextPage
|
|
i.filter.NextPage = nil
|
|
|
|
// Total is fetched with the first page only; a paged query cannot carry it
|
|
i.filter.IncTotal = i.filter.IncTotal && i.filter.PageCursor == nil
|
|
|
|
i.buffer, i.filter, err = h.rSvc.Find(ctx, i.filter)
|
|
if i.filter.IncTotal {
|
|
i.resTotal = i.filter.Total
|
|
}
|
|
|
|
return
|
|
}
|
|
return i, i.loader()
|
|
}
|
|
|
|
func (h remindersHandler) create(ctx context.Context, args *remindersCreateArgs) (results *remindersCreateResults, err error) {
|
|
|
|
results = &remindersCreateResults{}
|
|
currentUser := intAuth.GetIdentityFromContext(ctx).Identity()
|
|
|
|
reminder := &types.Reminder{
|
|
Resource:args.Resource,
|
|
AssignedTo: args.AssignedTo,
|
|
AssignedBy: args.AssignedBy,
|
|
RemindAt: args.RemindAt,
|
|
Payload: args.Payload,
|
|
}
|
|
if reminder.AssignedTo == 0 {
|
|
reminder.AssignedTo = currentUser
|
|
}
|
|
if reminder.AssignedBy == 0 {
|
|
reminder.AssignedBy = currentUser
|
|
}
|
|
if len(reminder.Payload) == 0 {
|
|
reminder.Payload = sqlxtypes.JSONText(`{"title": "", "note": ""}`)
|
|
}
|
|
if reminder.RemindAt == nil {
|
|
return nil, fmt.Errorf("remindAt is required")
|
|
}
|
|
results.Reminder, err = h.rSvc.Create(ctx, reminder)
|
|
return
|
|
}
|
|
|
|
func (h remindersHandler) update(ctx context.Context, args *remindersUpdateArgs) (results *remindersUpdateResults, err error) {
|
|
results = &remindersUpdateResults{}
|
|
reminder, err := lookupReminder(ctx, h.rSvc, args)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if args.hasResource {
|
|
reminder.Resource = args.Resource
|
|
}
|
|
if args.hasAssignedTo {
|
|
reminder.AssignedTo = args.AssignedTo
|
|
}
|
|
if args.hasAssignedBy {
|
|
reminder.AssignedBy = args.AssignedBy
|
|
}
|
|
if args.hasRemindAt {
|
|
reminder.RemindAt = args.RemindAt
|
|
}
|
|
if args.hasPayload {
|
|
reminder.Payload = args.Payload
|
|
}
|
|
results.Reminder, err = h.rSvc.Update(ctx, reminder)
|
|
return
|
|
}
|
|
func (h remindersHandler) dismiss(ctx context.Context, args *remindersDismissArgs) error {
|
|
if id, err := getReminderID(ctx, h.rSvc, args); err != nil {
|
|
return err
|
|
} else {
|
|
return h.rSvc.Dismiss(ctx, id)
|
|
}
|
|
}
|
|
func (h remindersHandler) snooze(ctx context.Context, args *remindersSnoozeArgs) error {
|
|
if id, err := getReminderID(ctx, h.rSvc, args); err != nil {
|
|
return err
|
|
} else {
|
|
return h.rSvc.Snooze(ctx, id, args.RemindAt)
|
|
}
|
|
}
|
|
func (h remindersHandler) delete(ctx context.Context, args *remindersDeleteArgs) error {
|
|
if id, err := getReminderID(ctx, h.rSvc, args); err != nil {
|
|
return err
|
|
} else {
|
|
return h.rSvc.Delete(ctx, id)
|
|
}
|
|
}
|
|
func getReminderID(ctx context.Context, svc reminderService, args reminderLookup) (uint64, error) {
|
|
_, ID, reminder := args.GetLookup()
|
|
|
|
switch {
|
|
case reminder != nil:
|
|
return reminder.ID, nil
|
|
case ID > 0:
|
|
return ID, nil
|
|
}
|
|
|
|
lookupResult, err := lookupReminder(ctx, svc, args)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return lookupResult.ID, nil
|
|
}
|
|
|
|
func lookupReminder(ctx context.Context, svc reminderService, args reminderLookup) (*types.Reminder, error) {
|
|
_, ID, reminder := args.GetLookup()
|
|
switch {
|
|
case reminder != nil:
|
|
return reminder, nil
|
|
case ID > 0:
|
|
return svc.FindByID(ctx, ID)
|
|
}
|
|
return nil, fmt.Errorf("empty lookup params")
|
|
}
|
|
|
|
func (i *reminderSetIterator) More(context.Context, *expr.Vars) (bool, error) {
|
|
a := wfexec.GenericResourceNextCheck(i.useIterLimit, i.ptr, uint(len(i.buffer)), i.total, i.iterLimit, i.filter.NextPage != nil)
|
|
return a, nil
|
|
}
|
|
func (i *reminderSetIterator) Start(context.Context, *expr.Vars) error {
|
|
i.ptr = 0
|
|
return nil
|
|
}
|
|
func (i *reminderSetIterator) Next(context.Context, *expr.Vars) (out *expr.Vars, err error) {
|
|
if len(i.buffer)-int(i.ptr) <= 0 {
|
|
if err = i.loader(); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
out = &expr.Vars{}
|
|
reminder := *i.buffer[i.ptr] // Make a copy
|
|
reminder.Payload = sqlxtypes.JSONText(string(i.buffer[i.ptr].Payload))
|
|
out.Set("reminder", Must(NewReminder(&reminder)))
|
|
out.Set("total", Must(NewInteger(i.resTotal)))
|
|
|
|
i.ptr++
|
|
return out, nil
|
|
}
|