mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-21 14:36:31 +00:00
feat(journey): the journal settings list who a linked trip lets in
Under the contributors, the journey settings on desktop and phone get a section of their own, Through trips, with everyone a trip's journal link lets in, their role and the trip they come through. It is read only there, since the trip's settings manage it, and it leaves out whoever is a contributor already. getJourneyFull answers it as trip_access.
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
import type { JourneyContributors } from '../entities/JourneyContributors.entity';
|
||||
import type { DB } from '../kysely/db';
|
||||
import { readLinkHideSkeletons, readLinkRole, type TripJournalLinkKyselyDB } from './TripJournalLinks.repository';
|
||||
import {
|
||||
linkReach,
|
||||
readLinkHideSkeletons,
|
||||
readLinkRole,
|
||||
type TripJournalLinkKyselyDB,
|
||||
type TripJournalLinkRole,
|
||||
} from './TripJournalLinks.repository';
|
||||
import { TrekRepository } from './_shared/trek-repository';
|
||||
|
||||
/** JG18's contributor-list row (`getJourneyFull`) — the junction plus the joined username/avatar. */
|
||||
@@ -16,6 +22,16 @@ export interface JourneyContributorListRow {
|
||||
/** The `journey_contributors`/`users` tables {@link JourneyContributorsRepository.listForJourney} reads. */
|
||||
type JourneyContributorListKyselyDB = Pick<DB, 'journey_contributors' | 'users'>;
|
||||
|
||||
/** Someone a trip's journal link lets in, with the trip they come through (#2683). */
|
||||
export interface JourneyTripAccessRow {
|
||||
user_id: number;
|
||||
role: TripJournalLinkRole;
|
||||
username: string;
|
||||
avatar: string | null;
|
||||
trip_id: number;
|
||||
trip_title: string;
|
||||
}
|
||||
|
||||
/** The table the access reads below take a person's own contributor row from. */
|
||||
type JourneyContributorRowKyselyDB = Pick<DB, 'journey_contributors'>;
|
||||
|
||||
@@ -79,6 +95,24 @@ export class JourneyContributorsRepository extends TrekRepository<JourneyContrib
|
||||
.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* #2683 — the people the trips' journal links let into this journal, one row
|
||||
* per trip they come through, leaving out whoever is a contributor already:
|
||||
* the settings show them apart, since they are managed in the trip.
|
||||
*/
|
||||
async listTripAccessForJourney(journeyId: number): Promise<JourneyTripAccessRow[]> {
|
||||
const direct = new Set((await this.listForJourney(journeyId)).map((c) => c.user_id));
|
||||
const rows = await linkReach(this.kysely<TripJournalLinkKyselyDB>())
|
||||
.innerJoin('users as u', 'u.id', 'm.user_id')
|
||||
.select(['m.user_id', 'm.role', 'u.username', 'u.avatar', 't.id as trip_id', 't.title as trip_title'])
|
||||
.where('l.journey_id', '=', journeyId)
|
||||
.orderBy('u.username', 'asc')
|
||||
.execute();
|
||||
return rows
|
||||
.filter((r) => !direct.has(r.user_id))
|
||||
.map((r) => ({ ...r, role: r.role === 'editor' ? 'editor' : 'viewer' }));
|
||||
}
|
||||
|
||||
/** JG18 — `getJourneyFull`'s contributor list, joined to `users` for `username`/`avatar` (`avatar_url` is computed in the SERVICE, unchanged). */
|
||||
async listForJourney(journeyId: number): Promise<JourneyContributorListRow[]> {
|
||||
const rows = await this.kysely<JourneyContributorListKyselyDB>()
|
||||
|
||||
@@ -270,12 +270,10 @@ export class JourneyDomainService {
|
||||
// linked trips (JG17)
|
||||
const trips = await this.journeyTripsRepo.listForJourney(journeyId);
|
||||
|
||||
// contributors (JG18)
|
||||
const contributorsRaw = await this.contributorsRepo.listForJourney(journeyId);
|
||||
const contributors = contributorsRaw.map((c) => ({
|
||||
...c,
|
||||
avatar_url: avatarUrl(c),
|
||||
}));
|
||||
const withAvatar = <R extends { avatar: string | null }>(rows: R[]) => rows.map((r) => ({ ...r, avatar_url: avatarUrl(r) }));
|
||||
const contributors = withAvatar(await this.contributorsRepo.listForJourney(journeyId)); // JG18
|
||||
// Who a trip's journal link lets in besides them (#2683), shown apart in the settings.
|
||||
const tripAccess = withAvatar(await this.contributorsRepo.listTripAccessForJourney(journeyId));
|
||||
|
||||
// stats
|
||||
const entryCount = entries.filter((e) => e.type === 'entry').length;
|
||||
@@ -306,6 +304,7 @@ export class JourneyDomainService {
|
||||
gallery,
|
||||
trips,
|
||||
contributors,
|
||||
trip_access: tripAccess,
|
||||
stats: { entries: entryCount, photos: photoCount, places: places.length },
|
||||
hide_skeletons: hideSkeletons,
|
||||
// What the eye toggle cannot say: how much was waved away one at a time, and
|
||||
|
||||
Reference in New Issue
Block a user