On the releases page, «Página pública» (owners and admins) opens a
secret link to a page with the release's notes, readable without an
account, also for private projects: the notes written, or the draft
from its finished tickets while there are none (without repeating the
title the page already shows). The link can be copied, renewed (the old
one stops working) or withdrawn. Stored in Mongo (`release_note_shares`).
API: shareReleaseNotes / unshareReleaseNotes / releaseNotesShare,
publicReleaseNotes(token); GET/PUT/DELETE /api/releases/{id}/public-notes,
GET /api/shared/release-notes/{token}. Web: /notes/:token.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
183 lines
5.5 KiB
TypeScript
183 lines
5.5 KiB
TypeScript
import { Routes } from '@angular/router';
|
|
import { authGuard } from '@task-stream/web/identity/presenters';
|
|
import {
|
|
provideCalendarFacade,
|
|
provideExploreFacade,
|
|
provideHomeFacade,
|
|
provideMyHomeFacade,
|
|
provideMyViewsFacade,
|
|
provideProposeFacade,
|
|
} from '@task-stream/web/tracker/application';
|
|
|
|
/**
|
|
* The tracker. Home needs a session; project pages and «Explorar» don't:
|
|
* public projects can be read by anyone (the API decides what each visitor
|
|
* sees, and pages hide what they cannot change).
|
|
*
|
|
* Each page's state is provided by its route, not the root: it loads with the
|
|
* page, and the route's injector keeps it for when you come back.
|
|
*/
|
|
export const trackerRoutes: Routes = [
|
|
{
|
|
path: '',
|
|
canActivate: [authGuard],
|
|
title: 'Proyectos · TaskStream',
|
|
providers: [
|
|
provideHomeFacade(),
|
|
provideMyHomeFacade(),
|
|
provideMyViewsFacade(),
|
|
provideCalendarFacade(),
|
|
],
|
|
loadComponent: () =>
|
|
import('./pages/projects.page').then((m) => m.ProjectsPage),
|
|
},
|
|
{
|
|
path: 'portfolio',
|
|
canActivate: [authGuard],
|
|
title: 'Cartera · TaskStream',
|
|
loadComponent: () =>
|
|
import('./pages/portfolio.page').then((m) => m.PortfolioPage),
|
|
},
|
|
{
|
|
path: 'explore',
|
|
title: 'Proyectos públicos · TaskStream',
|
|
providers: [provideExploreFacade()],
|
|
loadComponent: () =>
|
|
import('./pages/explore.page').then((m) => m.ExplorePage),
|
|
},
|
|
{
|
|
// A project's dashboard for its clients: the token is the access.
|
|
path: 'share/:token',
|
|
title: 'Estado del proyecto · TaskStream',
|
|
loadComponent: () =>
|
|
import('./pages/shared-dashboard.page').then(
|
|
(m) => m.SharedDashboardPage,
|
|
),
|
|
},
|
|
{
|
|
// A release's notes for its clients: the token is the access.
|
|
path: 'notes/:token',
|
|
title: 'Notas de la versión · TaskStream',
|
|
loadComponent: () =>
|
|
import('./pages/public-release-notes.page').then(
|
|
(m) => m.PublicReleaseNotesPage,
|
|
),
|
|
},
|
|
// The Spanish paths, from links shared before.
|
|
{ path: 'cartera', redirectTo: 'portfolio' },
|
|
{ path: 'explorar', redirectTo: 'explore' },
|
|
{
|
|
path: 'p/:key',
|
|
loadComponent: () =>
|
|
import('./pages/project-shell.page').then((m) => m.ProjectShellPage),
|
|
children: [
|
|
{ path: '', pathMatch: 'full', redirectTo: 'board' },
|
|
// The Spanish path, from links shared before.
|
|
{ path: 'proponer', redirectTo: 'propose' },
|
|
{
|
|
path: 'board',
|
|
title: 'Tablero · TaskStream',
|
|
loadComponent: () =>
|
|
import('./pages/board.page').then((m) => m.BoardPage),
|
|
},
|
|
{
|
|
path: 'propose',
|
|
title: 'Proponer · TaskStream',
|
|
providers: [provideProposeFacade()],
|
|
loadComponent: () =>
|
|
import('./pages/propose.page').then((m) => m.ProposePage),
|
|
},
|
|
{
|
|
path: 'list',
|
|
title: 'Lista · TaskStream',
|
|
loadComponent: () =>
|
|
import('./pages/list.page').then((m) => m.ListPage),
|
|
},
|
|
{
|
|
path: 'issues/:issueKey',
|
|
title: 'Ticket · TaskStream',
|
|
loadComponent: () =>
|
|
import('./pages/issue.page').then((m) => m.IssuePage),
|
|
},
|
|
{
|
|
path: 'backlog',
|
|
title: 'Backlog · TaskStream',
|
|
loadComponent: () =>
|
|
import('./pages/backlog.page').then((m) => m.BacklogPage),
|
|
},
|
|
{
|
|
path: 'sprints',
|
|
title: 'Sprints · TaskStream',
|
|
loadComponent: () =>
|
|
import('./pages/sprints.page').then((m) => m.SprintsPage),
|
|
},
|
|
{
|
|
path: 'calendar',
|
|
title: 'Calendario · TaskStream',
|
|
loadComponent: () =>
|
|
import('./pages/calendar.page').then((m) => m.CalendarPage),
|
|
},
|
|
{
|
|
path: 'roadmap',
|
|
title: 'Hoja de ruta · TaskStream',
|
|
loadComponent: () =>
|
|
import('./pages/roadmap.page').then((m) => m.RoadmapPage),
|
|
},
|
|
{
|
|
path: 'epics',
|
|
title: 'Épicas · TaskStream',
|
|
loadComponent: () =>
|
|
import('./pages/epics.page').then((m) => m.EpicsPage),
|
|
},
|
|
{
|
|
path: 'trash',
|
|
title: 'Papelera · TaskStream',
|
|
loadComponent: () =>
|
|
import('./pages/trash.page').then((m) => m.TrashPage),
|
|
},
|
|
{
|
|
path: 'releases',
|
|
title: 'Releases · TaskStream',
|
|
loadComponent: () =>
|
|
import('./pages/releases.page').then((m) => m.ReleasesPage),
|
|
},
|
|
{
|
|
path: 'report/:kind/:id',
|
|
title: 'Informe · TaskStream',
|
|
loadComponent: () =>
|
|
import('./pages/report.page').then((m) => m.ReportPage),
|
|
},
|
|
{
|
|
path: 'dashboard',
|
|
title: 'Seguimiento · TaskStream',
|
|
loadComponent: () =>
|
|
import('./pages/dashboard.page').then((m) => m.DashboardPage),
|
|
},
|
|
{
|
|
path: 'analytics',
|
|
title: 'Estadísticas · TaskStream',
|
|
loadComponent: () =>
|
|
import('./pages/analytics.page').then((m) => m.AnalyticsPage),
|
|
},
|
|
{
|
|
path: 'settings',
|
|
title: 'Configuración · TaskStream',
|
|
loadComponent: () =>
|
|
import('./pages/settings.page').then((m) => m.SettingsPage),
|
|
},
|
|
{
|
|
path: 'activity',
|
|
title: 'Actividad · TaskStream',
|
|
loadComponent: () =>
|
|
import('./pages/activity.page').then((m) => m.ActivityPage),
|
|
},
|
|
{
|
|
path: 'members',
|
|
title: 'Miembros · TaskStream',
|
|
loadComponent: () =>
|
|
import('./pages/members.page').then((m) => m.MembersPage),
|
|
},
|
|
],
|
|
},
|
|
];
|