Add endpoint to undo dismissed reminder
User can undo their own reminders.
This commit is contained in:
parent
fdf46fa083
commit
8a7b8d9c7f
@ -1374,6 +1374,16 @@ endpoints:
|
||||
name: reminderID
|
||||
required: true
|
||||
title: reminder ID
|
||||
- name: undismiss
|
||||
method: PATCH
|
||||
title: Undismiss reminder
|
||||
path: "/{reminderID}/undismiss"
|
||||
parameters:
|
||||
path:
|
||||
- type: uint64
|
||||
name: reminderID
|
||||
required: true
|
||||
title: reminder ID
|
||||
- name: snooze
|
||||
method: PATCH
|
||||
title: Snooze reminder
|
||||
|
||||
@ -25,18 +25,20 @@ type (
|
||||
Read(context.Context, *request.ReminderRead) (interface{}, error)
|
||||
Delete(context.Context, *request.ReminderDelete) (interface{}, error)
|
||||
Dismiss(context.Context, *request.ReminderDismiss) (interface{}, error)
|
||||
Undismiss(context.Context, *request.ReminderUndismiss) (interface{}, error)
|
||||
Snooze(context.Context, *request.ReminderSnooze) (interface{}, error)
|
||||
}
|
||||
|
||||
// HTTP API interface
|
||||
Reminder struct {
|
||||
List func(http.ResponseWriter, *http.Request)
|
||||
Create func(http.ResponseWriter, *http.Request)
|
||||
Update func(http.ResponseWriter, *http.Request)
|
||||
Read func(http.ResponseWriter, *http.Request)
|
||||
Delete func(http.ResponseWriter, *http.Request)
|
||||
Dismiss func(http.ResponseWriter, *http.Request)
|
||||
Snooze func(http.ResponseWriter, *http.Request)
|
||||
List func(http.ResponseWriter, *http.Request)
|
||||
Create func(http.ResponseWriter, *http.Request)
|
||||
Update func(http.ResponseWriter, *http.Request)
|
||||
Read func(http.ResponseWriter, *http.Request)
|
||||
Delete func(http.ResponseWriter, *http.Request)
|
||||
Dismiss func(http.ResponseWriter, *http.Request)
|
||||
Undismiss func(http.ResponseWriter, *http.Request)
|
||||
Snooze func(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
)
|
||||
|
||||
@ -138,6 +140,22 @@ func NewReminder(h ReminderAPI) *Reminder {
|
||||
|
||||
api.Send(w, r, value)
|
||||
},
|
||||
Undismiss: func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
params := request.NewReminderUndismiss()
|
||||
if err := params.Fill(r); err != nil {
|
||||
api.Send(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
value, err := h.Undismiss(r.Context(), params)
|
||||
if err != nil {
|
||||
api.Send(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
api.Send(w, r, value)
|
||||
},
|
||||
Snooze: func(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
params := request.NewReminderSnooze()
|
||||
@ -166,6 +184,7 @@ func (h Reminder) MountRoutes(r chi.Router, middlewares ...func(http.Handler) ht
|
||||
r.Get("/reminder/{reminderID}", h.Read)
|
||||
r.Delete("/reminder/{reminderID}", h.Delete)
|
||||
r.Patch("/reminder/{reminderID}/dismiss", h.Dismiss)
|
||||
r.Patch("/reminder/{reminderID}/undismiss", h.Undismiss)
|
||||
r.Patch("/reminder/{reminderID}/snooze", h.Snooze)
|
||||
})
|
||||
}
|
||||
|
||||
@ -95,6 +95,10 @@ func (ctrl *Reminder) Dismiss(ctx context.Context, r *request.ReminderDismiss) (
|
||||
return api.OK(), ctrl.reminder.Dismiss(ctx, r.ReminderID)
|
||||
}
|
||||
|
||||
func (ctrl *Reminder) Undismiss(ctx context.Context, r *request.ReminderUndismiss) (interface{}, error) {
|
||||
return api.OK(), ctrl.reminder.Undismiss(ctx, r.ReminderID)
|
||||
}
|
||||
|
||||
func (ctrl *Reminder) Snooze(ctx context.Context, r *request.ReminderSnooze) (interface{}, error) {
|
||||
return api.OK(), ctrl.reminder.Snooze(ctx, r.ReminderID, r.RemindAt)
|
||||
}
|
||||
|
||||
@ -162,6 +162,13 @@ type (
|
||||
ReminderID uint64 `json:",string"`
|
||||
}
|
||||
|
||||
ReminderUndismiss struct {
|
||||
// ReminderID PATH parameter
|
||||
//
|
||||
// reminder ID
|
||||
ReminderID uint64 `json:",string"`
|
||||
}
|
||||
|
||||
ReminderSnooze struct {
|
||||
// ReminderID PATH parameter
|
||||
//
|
||||
@ -708,6 +715,41 @@ func (r *ReminderDismiss) Fill(req *http.Request) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
// NewReminderUndismiss request
|
||||
func NewReminderUndismiss() *ReminderUndismiss {
|
||||
return &ReminderUndismiss{}
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ReminderUndismiss) Auditable() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"reminderID": r.ReminderID,
|
||||
}
|
||||
}
|
||||
|
||||
// Auditable returns all auditable/loggable parameters
|
||||
func (r ReminderUndismiss) GetReminderID() uint64 {
|
||||
return r.ReminderID
|
||||
}
|
||||
|
||||
// Fill processes request and fills internal variables
|
||||
func (r *ReminderUndismiss) Fill(req *http.Request) (err error) {
|
||||
|
||||
{
|
||||
var val string
|
||||
// path params
|
||||
|
||||
val = chi.URLParam(req, "reminderID")
|
||||
r.ReminderID, err = payload.ParseUint64(val), nil
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// NewReminderSnooze request
|
||||
func NewReminderSnooze() *ReminderSnooze {
|
||||
return &ReminderSnooze{}
|
||||
|
||||
@ -39,6 +39,7 @@ type (
|
||||
Update(context.Context, *types.Reminder) (*types.Reminder, error)
|
||||
|
||||
Dismiss(context.Context, uint64) error
|
||||
Undismiss(context.Context, uint64) error
|
||||
Snooze(context.Context, uint64, *time.Time) error
|
||||
|
||||
Delete(context.Context, uint64) error
|
||||
@ -232,6 +233,42 @@ func (svc reminder) Dismiss(ctx context.Context, ID uint64) (err error) {
|
||||
return svc.recordAction(ctx, raProps, ReminderActionDismiss, err)
|
||||
}
|
||||
|
||||
func (svc reminder) Undismiss(ctx context.Context, ID uint64) (err error) {
|
||||
var (
|
||||
r *types.Reminder
|
||||
|
||||
raProps = &reminderActionProps{reminder: &types.Reminder{ID: ID}}
|
||||
)
|
||||
|
||||
err = func() (err error) {
|
||||
if ID == 0 {
|
||||
return ReminderErrInvalidID()
|
||||
}
|
||||
|
||||
if r, err = store.LookupReminderByID(ctx, svc.store, ID); err != nil {
|
||||
return ReminderErrNotFound()
|
||||
}
|
||||
|
||||
if svc.checkAssignTo(ctx, r) {
|
||||
return ReminderErrNotAllowedToUndismiss()
|
||||
}
|
||||
|
||||
raProps.setReminder(r)
|
||||
|
||||
// Assign changed values
|
||||
r.DismissedAt = nil
|
||||
r.DismissedBy = 0
|
||||
|
||||
if err = store.UpdateReminder(ctx, svc.store, r); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}()
|
||||
|
||||
return svc.recordAction(ctx, raProps, ReminderActionDismiss, err)
|
||||
}
|
||||
|
||||
func (svc reminder) Snooze(ctx context.Context, ID uint64, remindAt *time.Time) (err error) {
|
||||
var (
|
||||
r *types.Reminder
|
||||
|
||||
87
server/system/service/reminder_actions.gen.go
generated
87
server/system/service/reminder_actions.gen.go
generated
@ -11,12 +11,13 @@ package service
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cortezaproject/corteza/server/pkg/actionlog"
|
||||
"github.com/cortezaproject/corteza/server/pkg/errors"
|
||||
"github.com/cortezaproject/corteza/server/pkg/locale"
|
||||
"github.com/cortezaproject/corteza/server/system/types"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type (
|
||||
@ -55,7 +56,6 @@ var (
|
||||
// setReminder updates reminderActionProps's reminder
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func (p *reminderActionProps) setReminder(reminder *types.Reminder) *reminderActionProps {
|
||||
p.reminder = reminder
|
||||
return p
|
||||
@ -64,7 +64,6 @@ func (p *reminderActionProps) setReminder(reminder *types.Reminder) *reminderAct
|
||||
// setNew updates reminderActionProps's new
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func (p *reminderActionProps) setNew(new *types.Reminder) *reminderActionProps {
|
||||
p.new = new
|
||||
return p
|
||||
@ -73,7 +72,6 @@ func (p *reminderActionProps) setNew(new *types.Reminder) *reminderActionProps {
|
||||
// setUpdated updates reminderActionProps's updated
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func (p *reminderActionProps) setUpdated(updated *types.Reminder) *reminderActionProps {
|
||||
p.updated = updated
|
||||
return p
|
||||
@ -82,7 +80,6 @@ func (p *reminderActionProps) setUpdated(updated *types.Reminder) *reminderActio
|
||||
// setFilter updates reminderActionProps's filter
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func (p *reminderActionProps) setFilter(filter *types.ReminderFilter) *reminderActionProps {
|
||||
p.filter = filter
|
||||
return p
|
||||
@ -91,7 +88,6 @@ func (p *reminderActionProps) setFilter(filter *types.ReminderFilter) *reminderA
|
||||
// Serialize converts reminderActionProps to actionlog.Meta
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func (p reminderActionProps) Serialize() actionlog.Meta {
|
||||
var (
|
||||
m = make(actionlog.Meta)
|
||||
@ -135,7 +131,6 @@ func (p reminderActionProps) Serialize() actionlog.Meta {
|
||||
// tr translates string and replaces meta value placeholder with values
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func (p reminderActionProps) Format(in string, err error) string {
|
||||
var (
|
||||
pairs = []string{"{{err}}"}
|
||||
@ -252,7 +247,6 @@ func (p reminderActionProps) Format(in string, err error) string {
|
||||
// String returns loggable description as string
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func (a *reminderAction) String() string {
|
||||
var props = &reminderActionProps{}
|
||||
|
||||
@ -280,7 +274,6 @@ func (e *reminderAction) ToAction() *actionlog.Action {
|
||||
// ReminderActionSearch returns "system:reminder.search" action
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func ReminderActionSearch(props ...*reminderActionProps) *reminderAction {
|
||||
a := &reminderAction{
|
||||
timestamp: time.Now(),
|
||||
@ -300,7 +293,6 @@ func ReminderActionSearch(props ...*reminderActionProps) *reminderAction {
|
||||
// ReminderActionLookup returns "system:reminder.lookup" action
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func ReminderActionLookup(props ...*reminderActionProps) *reminderAction {
|
||||
a := &reminderAction{
|
||||
timestamp: time.Now(),
|
||||
@ -320,7 +312,6 @@ func ReminderActionLookup(props ...*reminderActionProps) *reminderAction {
|
||||
// ReminderActionCreate returns "system:reminder.create" action
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func ReminderActionCreate(props ...*reminderActionProps) *reminderAction {
|
||||
a := &reminderAction{
|
||||
timestamp: time.Now(),
|
||||
@ -340,7 +331,6 @@ func ReminderActionCreate(props ...*reminderActionProps) *reminderAction {
|
||||
// ReminderActionUpdate returns "system:reminder.update" action
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func ReminderActionUpdate(props ...*reminderActionProps) *reminderAction {
|
||||
a := &reminderAction{
|
||||
timestamp: time.Now(),
|
||||
@ -360,7 +350,6 @@ func ReminderActionUpdate(props ...*reminderActionProps) *reminderAction {
|
||||
// ReminderActionDelete returns "system:reminder.delete" action
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func ReminderActionDelete(props ...*reminderActionProps) *reminderAction {
|
||||
a := &reminderAction{
|
||||
timestamp: time.Now(),
|
||||
@ -380,13 +369,31 @@ func ReminderActionDelete(props ...*reminderActionProps) *reminderAction {
|
||||
// ReminderActionDismiss returns "system:reminder.dismiss" action
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func ReminderActionDismiss(props ...*reminderActionProps) *reminderAction {
|
||||
a := &reminderAction{
|
||||
timestamp: time.Now(),
|
||||
resource: "system:reminder",
|
||||
action: "dismiss",
|
||||
log: "deleted {{reminder}}",
|
||||
log: "dismissed {{reminder}}",
|
||||
severity: actionlog.Notice,
|
||||
}
|
||||
|
||||
if len(props) > 0 {
|
||||
a.props = props[0]
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
// ReminderActionUndismiss returns "system:reminder.undismiss" action
|
||||
//
|
||||
// This function is auto-generated.
|
||||
func ReminderActionUndismiss(props ...*reminderActionProps) *reminderAction {
|
||||
a := &reminderAction{
|
||||
timestamp: time.Now(),
|
||||
resource: "system:reminder",
|
||||
action: "undismiss",
|
||||
log: "undismissed {{reminder}}",
|
||||
severity: actionlog.Notice,
|
||||
}
|
||||
|
||||
@ -400,13 +407,12 @@ func ReminderActionDismiss(props ...*reminderActionProps) *reminderAction {
|
||||
// ReminderActionSnooze returns "system:reminder.snooze" action
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func ReminderActionSnooze(props ...*reminderActionProps) *reminderAction {
|
||||
a := &reminderAction{
|
||||
timestamp: time.Now(),
|
||||
resource: "system:reminder",
|
||||
action: "snooze",
|
||||
log: "deleted {{reminder}}",
|
||||
log: "snoozed {{reminder}}",
|
||||
severity: actionlog.Notice,
|
||||
}
|
||||
|
||||
@ -423,9 +429,7 @@ func ReminderActionSnooze(props ...*reminderActionProps) *reminderAction {
|
||||
|
||||
// ReminderErrGeneric returns "system:reminder.generic" as *errors.Error
|
||||
//
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func ReminderErrGeneric(mm ...*reminderActionProps) *errors.Error {
|
||||
var p = &reminderActionProps{}
|
||||
if len(mm) > 0 {
|
||||
@ -459,9 +463,7 @@ func ReminderErrGeneric(mm ...*reminderActionProps) *errors.Error {
|
||||
|
||||
// ReminderErrNotFound returns "system:reminder.notFound" as *errors.Error
|
||||
//
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func ReminderErrNotFound(mm ...*reminderActionProps) *errors.Error {
|
||||
var p = &reminderActionProps{}
|
||||
if len(mm) > 0 {
|
||||
@ -493,9 +495,7 @@ func ReminderErrNotFound(mm ...*reminderActionProps) *errors.Error {
|
||||
|
||||
// ReminderErrInvalidID returns "system:reminder.invalidID" as *errors.Error
|
||||
//
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func ReminderErrInvalidID(mm ...*reminderActionProps) *errors.Error {
|
||||
var p = &reminderActionProps{}
|
||||
if len(mm) > 0 {
|
||||
@ -527,9 +527,7 @@ func ReminderErrInvalidID(mm ...*reminderActionProps) *errors.Error {
|
||||
|
||||
// ReminderErrNotAllowedToAssign returns "system:reminder.notAllowedToAssign" as *errors.Error
|
||||
//
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func ReminderErrNotAllowedToAssign(mm ...*reminderActionProps) *errors.Error {
|
||||
var p = &reminderActionProps{}
|
||||
if len(mm) > 0 {
|
||||
@ -561,9 +559,7 @@ func ReminderErrNotAllowedToAssign(mm ...*reminderActionProps) *errors.Error {
|
||||
|
||||
// ReminderErrNotAllowedToDismiss returns "system:reminder.notAllowedToDismiss" as *errors.Error
|
||||
//
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func ReminderErrNotAllowedToDismiss(mm ...*reminderActionProps) *errors.Error {
|
||||
var p = &reminderActionProps{}
|
||||
if len(mm) > 0 {
|
||||
@ -593,11 +589,41 @@ func ReminderErrNotAllowedToDismiss(mm ...*reminderActionProps) *errors.Error {
|
||||
return e
|
||||
}
|
||||
|
||||
// ReminderErrNotAllowedToRead returns "system:reminder.notAllowedToRead" as *errors.Error
|
||||
//
|
||||
// ReminderErrNotAllowedToUndismiss returns "system:reminder.notAllowedToUndismiss" as *errors.Error
|
||||
//
|
||||
// This function is auto-generated.
|
||||
func ReminderErrNotAllowedToUndismiss(mm ...*reminderActionProps) *errors.Error {
|
||||
var p = &reminderActionProps{}
|
||||
if len(mm) > 0 {
|
||||
p = mm[0]
|
||||
}
|
||||
|
||||
var e = errors.New(
|
||||
errors.KindInternal,
|
||||
|
||||
p.Format("not allowed to undo dismissed reminders of other users", nil),
|
||||
|
||||
errors.Meta("type", "notAllowedToUndismiss"),
|
||||
errors.Meta("resource", "system:reminder"),
|
||||
|
||||
errors.Meta(reminderPropsMetaKey{}, p),
|
||||
|
||||
// translation namespace & key
|
||||
errors.Meta(locale.ErrorMetaNamespace{}, "system"),
|
||||
errors.Meta(locale.ErrorMetaKey{}, "reminder.errors.notAllowedToUndismiss"),
|
||||
|
||||
errors.StackSkip(1),
|
||||
)
|
||||
|
||||
if len(mm) > 0 {
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// ReminderErrNotAllowedToRead returns "system:reminder.notAllowedToRead" as *errors.Error
|
||||
//
|
||||
// This function is auto-generated.
|
||||
func ReminderErrNotAllowedToRead(mm ...*reminderActionProps) *errors.Error {
|
||||
var p = &reminderActionProps{}
|
||||
if len(mm) > 0 {
|
||||
@ -635,7 +661,6 @@ func ReminderErrNotAllowedToRead(mm ...*reminderActionProps) *errors.Error {
|
||||
// It will wrap unrecognized/internal errors with generic errors.
|
||||
//
|
||||
// This function is auto-generated.
|
||||
//
|
||||
func (svc reminder) recordAction(ctx context.Context, props *reminderActionProps, actionFn func(...*reminderActionProps) *reminderAction, err error) error {
|
||||
if svc.actionlog == nil || actionFn == nil {
|
||||
// action log disabled or no action fn passed, return error as-is
|
||||
|
||||
@ -45,10 +45,13 @@ actions:
|
||||
log: "deleted {{reminder}}"
|
||||
|
||||
- action: dismiss
|
||||
log: "deleted {{reminder}}"
|
||||
log: "dismissed {{reminder}}"
|
||||
|
||||
- action: undismiss
|
||||
log: "undismissed {{reminder}}"
|
||||
|
||||
- action: snooze
|
||||
log: "deleted {{reminder}}"
|
||||
log: "snoozed {{reminder}}"
|
||||
|
||||
errors:
|
||||
- error: notFound
|
||||
@ -65,5 +68,8 @@ errors:
|
||||
- error: notAllowedToDismiss
|
||||
message: "not allowed to dismiss reminders of other users"
|
||||
|
||||
- error: notAllowedToUndismiss
|
||||
message: "not allowed to undo dismissed reminders of other users"
|
||||
|
||||
- error: notAllowedToRead
|
||||
message: "not allowed to read reminders of other users"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user