Inline question choices, compact one-click inbox cards, drop snooze
This commit is contained in:
+33
-38
@@ -88,11 +88,10 @@ func (s *Store) GetInboxItem(ctx context.Context, id string) (api.InboxItem, err
|
||||
}
|
||||
|
||||
type InboxFilter struct {
|
||||
ProjectID string
|
||||
TaskID string
|
||||
SessionID string
|
||||
State api.InboxState
|
||||
IncludeSnoozed bool
|
||||
ProjectID string
|
||||
TaskID string
|
||||
SessionID string
|
||||
State api.InboxState
|
||||
}
|
||||
|
||||
func (s *Store) ListInbox(ctx context.Context, f InboxFilter) ([]api.InboxItem, error) {
|
||||
@@ -111,10 +110,6 @@ func (s *Store) ListInbox(ctx context.Context, f InboxFilter) ([]api.InboxItem,
|
||||
where = append(where, "agent_session_id = ?")
|
||||
args = append(args, f.SessionID)
|
||||
}
|
||||
if !f.IncludeSnoozed {
|
||||
where = append(where, "(snoozed_until IS NULL OR snoozed_until <= ?)")
|
||||
args = append(args, now())
|
||||
}
|
||||
|
||||
rows, err := s.db.QueryContext(ctx, `SELECT id FROM inbox_items WHERE `+strings.Join(where, " AND ")+` ORDER BY created_at`, args...)
|
||||
if err != nil {
|
||||
@@ -162,21 +157,26 @@ func (s *Store) Respond(ctx context.Context, actor string, resolutions []Resolut
|
||||
return err
|
||||
}
|
||||
|
||||
var options *string
|
||||
if resp.Options != nil {
|
||||
b, err := json.Marshal(*resp.Options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s := string(b)
|
||||
options = &s
|
||||
}
|
||||
|
||||
_, err = tx.ExecContext(ctx, `
|
||||
INSERT INTO inbox_responses (id, item_id, user_login, type, option, text, attachments, snooze_until, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`, resp.Id, resp.ItemId, resp.User, string(resp.Type), resp.Option, resp.Text, string(attachments),
|
||||
formatTimePtr(resp.SnoozeUntil), formatTime(resp.CreatedAt))
|
||||
INSERT INTO inbox_responses (id, item_id, user_login, type, options, text, attachments, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`, resp.Id, resp.ItemId, resp.User, string(resp.Type), options, resp.Text, string(attachments), formatTime(resp.CreatedAt))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if r.State == api.Open {
|
||||
_, err = tx.ExecContext(ctx, `UPDATE inbox_items SET snoozed_until = ? WHERE id = ?`, formatTimePtr(resp.SnoozeUntil), resp.ItemId)
|
||||
} else {
|
||||
_, err = tx.ExecContext(ctx, `UPDATE inbox_items SET state = ?, resolved_by = ?, resolved_at = ?, snoozed_until = NULL WHERE id = ?`,
|
||||
string(r.State), actor, now(), resp.ItemId)
|
||||
}
|
||||
_, err = tx.ExecContext(ctx, `UPDATE inbox_items SET state = ?, resolved_by = ?, resolved_at = ? WHERE id = ?`,
|
||||
string(r.State), actor, now(), resp.ItemId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -194,7 +194,7 @@ var ErrNotOpen = errors.New("inbox item is not open")
|
||||
|
||||
func (s *Store) WithdrawItem(ctx context.Context, id string) error {
|
||||
return s.write(ctx, func(tx *sql.Tx, emit emitFunc) error {
|
||||
res, err := tx.ExecContext(ctx, `UPDATE inbox_items SET state = ?, resolved_at = ?, snoozed_until = NULL WHERE id = ? AND state = ?`,
|
||||
res, err := tx.ExecContext(ctx, `UPDATE inbox_items SET state = ?, resolved_at = ? WHERE id = ? AND state = ?`,
|
||||
string(api.Dismissed), now(), id, string(api.Open))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -228,7 +228,7 @@ func dismissTaskInbox(ctx context.Context, tx *sql.Tx, emit emitFunc, taskID, ac
|
||||
rows.Close()
|
||||
|
||||
for _, id := range ids {
|
||||
_, err = tx.ExecContext(ctx, `UPDATE inbox_items SET state = ?, resolved_by = ?, resolved_at = ?, snoozed_until = NULL WHERE id = ?`,
|
||||
_, err = tx.ExecContext(ctx, `UPDATE inbox_items SET state = ?, resolved_by = ?, resolved_at = ? WHERE id = ?`,
|
||||
string(api.Dismissed), actor, now(), id)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -324,16 +324,15 @@ func getItem(ctx context.Context, q querier, id string) (api.InboxItem, error) {
|
||||
payload := ""
|
||||
state := ""
|
||||
createdAt := ""
|
||||
snoozed := sql.NullString{}
|
||||
resolvedBy := sql.NullString{}
|
||||
resolvedAt := sql.NullString{}
|
||||
|
||||
err := q.QueryRowContext(ctx, `
|
||||
SELECT id, project_id, task_id, agent_session_id, thread_id, kind, priority, blocking, payload, state,
|
||||
snoozed_until, created_at, resolved_by, resolved_at
|
||||
created_at, resolved_by, resolved_at
|
||||
FROM inbox_items WHERE id = ?
|
||||
`, id).Scan(&item.Id, &item.ProjectId, &item.TaskId, &item.AgentSessionId, &item.ThreadId, &kind, &priority, &item.Blocking,
|
||||
&payload, &state, &snoozed, &createdAt, &resolvedBy, &resolvedAt)
|
||||
&payload, &state, &createdAt, &resolvedBy, &resolvedAt)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
@@ -349,10 +348,6 @@ func getItem(ctx context.Context, q querier, id string) (api.InboxItem, error) {
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
item.SnoozedUntil, err = parseTimePtr(snoozed)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
item.ResolvedAt, err = parseTimePtr(resolvedAt)
|
||||
if err != nil {
|
||||
return item, err
|
||||
@@ -367,7 +362,7 @@ func getItem(ctx context.Context, q querier, id string) (api.InboxItem, error) {
|
||||
|
||||
func getResponses(ctx context.Context, q querier, itemID string) ([]api.InboxResponse, error) {
|
||||
rows, err := q.QueryContext(ctx, `
|
||||
SELECT id, item_id, user_login, type, option, text, attachments, snooze_until, created_at, delivered_at
|
||||
SELECT id, item_id, user_login, type, options, text, attachments, created_at, delivered_at
|
||||
FROM inbox_responses WHERE item_id = ? ORDER BY created_at
|
||||
`, itemID)
|
||||
if err != nil {
|
||||
@@ -379,21 +374,25 @@ func getResponses(ctx context.Context, q querier, itemID string) ([]api.InboxRes
|
||||
for rows.Next() {
|
||||
r := api.InboxResponse{}
|
||||
typ := ""
|
||||
option := sql.NullString{}
|
||||
options := sql.NullString{}
|
||||
text := sql.NullString{}
|
||||
attachments := ""
|
||||
snooze := sql.NullString{}
|
||||
createdAt := ""
|
||||
delivered := sql.NullString{}
|
||||
|
||||
err = rows.Scan(&r.Id, &r.ItemId, &r.User, &typ, &option, &text, &attachments, &snooze, &createdAt, &delivered)
|
||||
err = rows.Scan(&r.Id, &r.ItemId, &r.User, &typ, &options, &text, &attachments, &createdAt, &delivered)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r.Type = api.InboxResponseType(typ)
|
||||
if option.Valid {
|
||||
r.Option = &option.String
|
||||
if options.Valid {
|
||||
chosen := []string{}
|
||||
err = json.Unmarshal([]byte(options.String), &chosen)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r.Options = &chosen
|
||||
}
|
||||
if text.Valid {
|
||||
r.Text = &text.String
|
||||
@@ -402,10 +401,6 @@ func getResponses(ctx context.Context, q querier, itemID string) ([]api.InboxRes
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r.SnoozeUntil, err = parseTimePtr(snooze)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r.CreatedAt, err = parseTime(createdAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user