Skip to content

Commit

Permalink
Feature: Full Schedule Support in Calendar Subscriptions (#3289)
Browse files Browse the repository at this point in the history
* add full schedule config support

* update API to support fullSchedule option

* add full schedule support to UI

* regen schema

* clarify behavior
  • Loading branch information
mastercactapus authored Oct 6, 2023
1 parent 466beaa commit 625d5e7
Show file tree
Hide file tree
Showing 14 changed files with 320 additions and 70 deletions.
49 changes: 39 additions & 10 deletions calsub/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,58 @@ func (s *Store) ServeICalData(w http.ResponseWriter, req *http.Request) {
return
}

// filter out other users
filtered := shifts[:0]
for _, s := range shifts {
if s.UserID != info.UserID.String() {
continue
}
filtered = append(filtered, s)
}

var subCfg SubscriptionConfig
err = json.Unmarshal(info.Config, &subCfg)
if errutil.HTTPError(ctx, w, err) {
return
}

if !subCfg.FullSchedule {
// filter out other users
filtered := shifts[:0]
for _, s := range shifts {
if s.UserID != info.UserID.String() {
continue
}
filtered = append(filtered, s)
}
shifts = filtered
}

data := renderData{
ApplicationName: cfg.ApplicationName(),
ScheduleID: info.ScheduleID,
ScheduleName: info.ScheduleName,
Shifts: filtered,
Shifts: shifts,
ReminderMinutes: subCfg.ReminderMinutes,
Version: version.GitVersion(),
GeneratedAt: info.Now,
FullSchedule: subCfg.FullSchedule,
}

if subCfg.FullSchedule {
// When rendering the full schedule, we need to fetch the names of all users.
data.UserNames = make(map[string]string)
var uniqueIDs []uuid.UUID
for _, s := range shifts {

// We'll use the map to track which IDs we've already seen.
// That way we don't ask the DB for the same user multiple times.
if _, ok := data.UserNames[s.UserID]; ok {
continue
}
data.UserNames[s.UserID] = "Unknown User"
uniqueIDs = append(uniqueIDs, uuid.MustParse(s.UserID))
}

users, err := gadb.New(s.db).CalSubUserNames(ctx, uniqueIDs)
if errutil.HTTPError(ctx, w, err) {
return
}

for _, u := range users {
data.UserNames[u.ID.String()] = u.Name
}
}

calData, err := data.renderICal()
Expand Down
79 changes: 51 additions & 28 deletions calsub/queries.sql
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
-- name: FindOneCalSub :one
SELECT id,
SELECT
id,
NAME,
user_id,
disabled,
schedule_id,
config,
last_access
FROM user_calendar_subscriptions
WHERE id = $1;
FROM
user_calendar_subscriptions
WHERE
id = $1;

-- name: CalSubUserNames :many
SELECT
id,
name
FROM
users
WHERE
id = ANY ($1::uuid[]);

-- name: CalSubRenderInfo :one
SELECT
Expand All @@ -23,59 +35,70 @@ WHERE
sub.id = $1;

-- name: FindOneCalSubForUpdate :one
SELECT id,
SELECT
id,
NAME,
user_id,
disabled,
schedule_id,
config,
last_access
FROM user_calendar_subscriptions
WHERE id = $1 FOR
UPDATE;
FROM
user_calendar_subscriptions
WHERE
id = $1
FOR UPDATE;

-- name: FindManyCalSubByUser :many
SELECT id,
SELECT
id,
NAME,
user_id,
disabled,
schedule_id,
config,
last_access
FROM user_calendar_subscriptions
WHERE user_id = $1;
FROM
user_calendar_subscriptions
WHERE
user_id = $1;

-- name: DeleteManyCalSub :exec
DELETE FROM user_calendar_subscriptions
WHERE id = ANY($1::uuid [ ])
WHERE id = ANY ($1::uuid[])
AND user_id = $2;

-- name: CreateCalSub :one
INSERT INTO user_calendar_subscriptions (
id,
NAME,
user_id,
disabled,
schedule_id,
config
)
VALUES ($1, $2, $3, $4, $5, $6) RETURNING created_at;
INSERT INTO user_calendar_subscriptions(id, NAME, user_id, disabled, schedule_id, config)
VALUES ($1, $2, $3, $4, $5, $6)
RETURNING
created_at;

-- name: Now :one
SELECT now()::timestamptz;
SELECT
now()::timestamptz;

-- name: CalSubAuthUser :one
UPDATE user_calendar_subscriptions
SET last_access = now()
WHERE NOT disabled
UPDATE
user_calendar_subscriptions
SET
last_access = now()
WHERE
NOT disabled
AND id = $1
AND date_trunc('second', created_at) = $2 RETURNING user_id;
AND date_trunc('second', created_at) = $2
RETURNING
user_id;

-- name: UpdateCalSub :exec
UPDATE user_calendar_subscriptions
SET NAME = $1,
UPDATE
user_calendar_subscriptions
SET
NAME = $1,
disabled = $2,
config = $3,
last_update = now()
WHERE id = $4
WHERE
id = $4
AND user_id = $5;

2 changes: 2 additions & 0 deletions calsub/renderdata.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ type renderData struct {
ReminderMinutes []int
Version string
GeneratedAt time.Time
FullSchedule bool
UserNames map[string]string
}
2 changes: 1 addition & 1 deletion calsub/renderical.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ METHOD:PUBLISH
{{- range $i, $s := .Shifts}}
BEGIN:VEVENT
UID:{{index $eventUIDs $i}}
SUMMARY:On-Call ({{$.ApplicationName}}: {{$.ScheduleName}}){{if $s.Truncated}} Begins*
SUMMARY:{{if $.FullSchedule}}{{index $.UserNames $s.UserID}} {{end}}On-Call ({{$.ApplicationName}}: {{$.ScheduleName}}){{if $s.Truncated}} Begins*
DESCRIPTION:The end time of this shift is unknown and will continue beyond what is displayed.
{{- end }}
DTSTAMP:{{$genTime.UTC.Format "20060102T150405Z"}}
Expand Down
1 change: 1 addition & 0 deletions calsub/subscriptionconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
// SubscriptionConfig is the configuration for a calendar subscription.
type SubscriptionConfig struct {
ReminderMinutes []int
FullSchedule bool
}

var (
Expand Down
Loading

0 comments on commit 625d5e7

Please sign in to comment.