feat: a calendar to subscribe to, and the backlog's corners
- Each person can subscribe their dates in Google Calendar, Outlook or
Apple Calendar: GET /api/calendar/{token}.ics (no session) brings
their unfinished tickets with a due date (assigned or followed), the
planned and running sprints and the planned releases of their
projects, as all-day events linking to the web. The token is made,
renewed or dropped under /me/calendar (and in GraphQL); in the web,
from «Calendario» in «Mi trabajo».
- The backlog panel keeps the selected rows' background inside its
rounded corners.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { API_CONFIG } from '@task-stream/web/shared/infrastructure';
|
||||
import { CalendarFeed, CalendarGateway } from '@task-stream/web/tracker/domain';
|
||||
import { map, Observable } from 'rxjs';
|
||||
import {
|
||||
CreateCalendarFeedDocument,
|
||||
MyCalendarFeedDocument,
|
||||
RevokeCalendarFeedDocument,
|
||||
} from '../graphql/generated';
|
||||
import { GraphqlOperations } from './graphql-operations';
|
||||
|
||||
@Injectable()
|
||||
export class GraphqlCalendarGateway extends CalendarGateway {
|
||||
private readonly gql = inject(GraphqlOperations);
|
||||
private readonly api = inject(API_CONFIG);
|
||||
|
||||
mine(): Observable<CalendarFeed | null> {
|
||||
return this.gql
|
||||
.query(MyCalendarFeedDocument)
|
||||
.pipe(
|
||||
map((d) => (d.myCalendarFeed ? this.toFeed(d.myCalendarFeed) : null)),
|
||||
);
|
||||
}
|
||||
|
||||
create(): Observable<CalendarFeed> {
|
||||
return this.gql
|
||||
.mutate(CreateCalendarFeedDocument, {})
|
||||
.pipe(map((d) => this.toFeed(d.createCalendarFeed)));
|
||||
}
|
||||
|
||||
revoke(): Observable<void> {
|
||||
return this.gql
|
||||
.mutate(RevokeCalendarFeedDocument, {})
|
||||
.pipe(map(() => undefined));
|
||||
}
|
||||
|
||||
/** The API answers the secret; calendar apps need the whole address. */
|
||||
private toFeed(feed: { token: string; createdAt: string }): CalendarFeed {
|
||||
const base = new URL(
|
||||
this.api.restUrl.replace(/\/+$/, '') + '/',
|
||||
location.origin,
|
||||
);
|
||||
return {
|
||||
url: new URL(`calendar/${feed.token}.ics`, base).toString(),
|
||||
createdAt: feed.createdAt,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user