feat: add release communications
This commit is contained in:
969
frontend/src/api/schema.d.ts
vendored
969
frontend/src/api/schema.d.ts
vendored
@@ -100,6 +100,246 @@ export interface paths {
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/developer/release-updates/{id}/archive": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
post: operations["SocializeApiModulesReleaseCommunicationsHandlersArchiveDeveloperReleaseUpdateHandler"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/developer/release-updates": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get: operations["SocializeApiModulesReleaseCommunicationsHandlersListDeveloperReleaseUpdatesHandler"];
|
||||
put?: never;
|
||||
post: operations["SocializeApiModulesReleaseCommunicationsHandlersCreateDeveloperReleaseUpdateHandler"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/developer/release-updates/{id}": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get: operations["SocializeApiModulesReleaseCommunicationsHandlersGetDeveloperReleaseUpdateHandler"];
|
||||
put: operations["SocializeApiModulesReleaseCommunicationsHandlersUpdateDeveloperReleaseUpdateHandler"];
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/release-updates/unread": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get: operations["SocializeApiModulesReleaseCommunicationsHandlersGetUnreadReleaseUpdatesHandler"];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/developer/release-commits/import": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
post: operations["SocializeApiModulesReleaseCommunicationsHandlersImportDeveloperReleaseCommitsHandler"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/developer/release-commits": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get: operations["SocializeApiModulesReleaseCommunicationsHandlersListDeveloperReleaseCommitsHandler"];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/release-updates": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get: operations["SocializeApiModulesReleaseCommunicationsHandlersListReleaseUpdatesHandler"];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/release-updates/read-all": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
post: operations["SocializeApiModulesReleaseCommunicationsHandlersMarkAllReleaseUpdatesReadHandler"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/release-updates/{id}/read": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
post: operations["SocializeApiModulesReleaseCommunicationsHandlersMarkReleaseUpdateReadHandler"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/developer/release-updates/{id}/publish": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
post: operations["SocializeApiModulesReleaseCommunicationsHandlersPublishDeveloperReleaseUpdateHandler"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/developer/release-updates/{id}/send-email": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
post: operations["SocializeApiModulesReleaseCommunicationsHandlersSendDeveloperReleaseUpdateEmailHandler"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/developer/release-commits/{sha}/link": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
post: operations["SocializeApiModulesReleaseCommunicationsHandlersLinkDeveloperReleaseCommitHandler"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/developer/release-commits/{sha}/unlink": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
post: operations["SocializeApiModulesReleaseCommunicationsHandlersUnlinkDeveloperReleaseCommitHandler"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/developer/release-commits/{sha}/internal-only": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
post: operations["SocializeApiModulesReleaseCommunicationsHandlersMarkDeveloperReleaseCommitInternalOnlyHandler"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/developer/release-commits/{sha}/ignore": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
post: operations["SocializeApiModulesReleaseCommunicationsHandlersIgnoreDeveloperReleaseCommitHandler"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/organizations/{organizationId}/members": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
@@ -1227,6 +1467,131 @@ export interface components {
|
||||
/** Format: int32 */
|
||||
requiredApproverCount?: number;
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsContractsReleaseUpdateDto: {
|
||||
/** Format: guid */
|
||||
id?: string;
|
||||
title?: string;
|
||||
summary?: string;
|
||||
body?: string | null;
|
||||
category?: string;
|
||||
importance?: string;
|
||||
audience?: string;
|
||||
status?: string;
|
||||
deploymentLabel?: string | null;
|
||||
buildVersion?: string | null;
|
||||
commitRange?: string | null;
|
||||
/** Format: date-time */
|
||||
createdAt?: string;
|
||||
/** Format: date-time */
|
||||
updatedAt?: string;
|
||||
/** Format: date-time */
|
||||
publishedAt?: string | null;
|
||||
/** Format: date-time */
|
||||
archivedAt?: string | null;
|
||||
/** Format: guid */
|
||||
manualEmailSentByUserId?: string | null;
|
||||
/** Format: date-time */
|
||||
manualEmailSentAt?: string | null;
|
||||
manualEmailAudience?: string | null;
|
||||
/** Format: int32 */
|
||||
manualEmailRecipientCount?: number | null;
|
||||
isRead?: boolean;
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersCreateDeveloperReleaseUpdateRequest: {
|
||||
title: string;
|
||||
summary: string;
|
||||
body?: string | null;
|
||||
category: string;
|
||||
importance: string;
|
||||
audience: string;
|
||||
deploymentLabel?: string | null;
|
||||
buildVersion?: string | null;
|
||||
commitRange?: string | null;
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsContractsReleaseUpdateUnreadSummaryDto: {
|
||||
/** Format: int32 */
|
||||
unreadCount?: number;
|
||||
/** Format: int32 */
|
||||
importantUnreadCount?: number;
|
||||
updates?: components["schemas"]["SocializeApiModulesReleaseCommunicationsContractsReleaseUpdateDto"][];
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsContractsReleaseCommitImportResultDto: {
|
||||
/** Format: int32 */
|
||||
importedCount?: number;
|
||||
/** Format: int32 */
|
||||
updatedCount?: number;
|
||||
/** Format: int32 */
|
||||
skippedCount?: number;
|
||||
commits?: components["schemas"]["SocializeApiModulesReleaseCommunicationsContractsReleaseCommitDto"][];
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsContractsReleaseCommitDto: {
|
||||
sha?: string;
|
||||
shortSha?: string;
|
||||
subject?: string;
|
||||
authorName?: string | null;
|
||||
authorEmail?: string | null;
|
||||
/** Format: date-time */
|
||||
authoredAt?: string | null;
|
||||
/** Format: date-time */
|
||||
committedAt?: string | null;
|
||||
sourceBranch?: string | null;
|
||||
deploymentLabel?: string | null;
|
||||
externalUrl?: string | null;
|
||||
communicationStatus?: string;
|
||||
/** Format: guid */
|
||||
releaseUpdateId?: string | null;
|
||||
/** Format: date-time */
|
||||
importedAt?: string;
|
||||
/** Format: date-time */
|
||||
updatedAt?: string;
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersImportDeveloperReleaseCommitsRequest: {
|
||||
sinceSha?: string | null;
|
||||
untilSha?: string | null;
|
||||
sourceBranch?: string | null;
|
||||
deploymentLabel?: string | null;
|
||||
commits?: components["schemas"]["SocializeApiModulesReleaseCommunicationsHandlersImportDeveloperReleaseCommitDto"][] | null;
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersImportDeveloperReleaseCommitDto: {
|
||||
sha?: string;
|
||||
shortSha?: string | null;
|
||||
subject?: string;
|
||||
authorName?: string | null;
|
||||
authorEmail?: string | null;
|
||||
/** Format: date-time */
|
||||
authoredAt?: string | null;
|
||||
/** Format: date-time */
|
||||
committedAt?: string | null;
|
||||
sourceBranch?: string | null;
|
||||
deploymentLabel?: string | null;
|
||||
externalUrl?: string | null;
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsContractsReleaseUpdateEmailSendResultDto: {
|
||||
/** Format: int32 */
|
||||
recipientCount?: number;
|
||||
/** Format: date-time */
|
||||
sentAt?: string;
|
||||
testMode?: boolean;
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersSendDeveloperReleaseUpdateEmailRequest: {
|
||||
testMode?: boolean;
|
||||
confirmResend?: boolean;
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersLinkDeveloperReleaseCommitRequest: {
|
||||
/** Format: guid */
|
||||
releaseUpdateId?: string;
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersUpdateDeveloperReleaseUpdateRequest: {
|
||||
title: string;
|
||||
summary: string;
|
||||
body?: string | null;
|
||||
category: string;
|
||||
importance: string;
|
||||
audience: string;
|
||||
deploymentLabel?: string | null;
|
||||
buildVersion?: string | null;
|
||||
commitRange?: string | null;
|
||||
};
|
||||
SocializeApiModulesOrganizationsHandlersOrganizationMemberDto: {
|
||||
/** Format: guid */
|
||||
userId?: string;
|
||||
@@ -2277,6 +2642,610 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersArchiveDeveloperReleaseUpdateHandler: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
id: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Success */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsContractsReleaseUpdateDto"];
|
||||
};
|
||||
};
|
||||
/** @description Unauthorized */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Forbidden */
|
||||
403: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersListDeveloperReleaseUpdatesHandler: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Success */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsContractsReleaseUpdateDto"][];
|
||||
};
|
||||
};
|
||||
/** @description Unauthorized */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Forbidden */
|
||||
403: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersCreateDeveloperReleaseUpdateHandler: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsHandlersCreateDeveloperReleaseUpdateRequest"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Success */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsContractsReleaseUpdateDto"];
|
||||
};
|
||||
};
|
||||
/** @description Bad Request */
|
||||
400: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/problem+json": components["schemas"]["FastEndpointsErrorResponse"];
|
||||
};
|
||||
};
|
||||
/** @description Unauthorized */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Forbidden */
|
||||
403: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersGetDeveloperReleaseUpdateHandler: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
id: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Success */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsContractsReleaseUpdateDto"];
|
||||
};
|
||||
};
|
||||
/** @description Unauthorized */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Forbidden */
|
||||
403: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersUpdateDeveloperReleaseUpdateHandler: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
id: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsHandlersUpdateDeveloperReleaseUpdateRequest"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Success */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsContractsReleaseUpdateDto"];
|
||||
};
|
||||
};
|
||||
/** @description Bad Request */
|
||||
400: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/problem+json": components["schemas"]["FastEndpointsErrorResponse"];
|
||||
};
|
||||
};
|
||||
/** @description Unauthorized */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Forbidden */
|
||||
403: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersGetUnreadReleaseUpdatesHandler: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Success */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsContractsReleaseUpdateUnreadSummaryDto"];
|
||||
};
|
||||
};
|
||||
/** @description Unauthorized */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersImportDeveloperReleaseCommitsHandler: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsHandlersImportDeveloperReleaseCommitsRequest"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Success */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsContractsReleaseCommitImportResultDto"];
|
||||
};
|
||||
};
|
||||
/** @description Unauthorized */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Forbidden */
|
||||
403: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersListDeveloperReleaseCommitsHandler: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Success */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsContractsReleaseCommitDto"][];
|
||||
};
|
||||
};
|
||||
/** @description Unauthorized */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Forbidden */
|
||||
403: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersListReleaseUpdatesHandler: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Success */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsContractsReleaseUpdateDto"][];
|
||||
};
|
||||
};
|
||||
/** @description Unauthorized */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersMarkAllReleaseUpdatesReadHandler: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description No Content */
|
||||
204: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Unauthorized */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersMarkReleaseUpdateReadHandler: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
id: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description No Content */
|
||||
204: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Unauthorized */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersPublishDeveloperReleaseUpdateHandler: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
id: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Success */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsContractsReleaseUpdateDto"];
|
||||
};
|
||||
};
|
||||
/** @description Unauthorized */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Forbidden */
|
||||
403: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersSendDeveloperReleaseUpdateEmailHandler: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
id: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsHandlersSendDeveloperReleaseUpdateEmailRequest"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Success */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsContractsReleaseUpdateEmailSendResultDto"];
|
||||
};
|
||||
};
|
||||
/** @description Unauthorized */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Forbidden */
|
||||
403: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersLinkDeveloperReleaseCommitHandler: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
sha: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsHandlersLinkDeveloperReleaseCommitRequest"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Success */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsContractsReleaseCommitDto"];
|
||||
};
|
||||
};
|
||||
/** @description Unauthorized */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Forbidden */
|
||||
403: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersUnlinkDeveloperReleaseCommitHandler: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
sha: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Success */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsContractsReleaseCommitDto"];
|
||||
};
|
||||
};
|
||||
/** @description Unauthorized */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Forbidden */
|
||||
403: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersMarkDeveloperReleaseCommitInternalOnlyHandler: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
sha: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Success */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsContractsReleaseCommitDto"];
|
||||
};
|
||||
};
|
||||
/** @description Unauthorized */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Forbidden */
|
||||
403: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
SocializeApiModulesReleaseCommunicationsHandlersIgnoreDeveloperReleaseCommitHandler: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
sha: string;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Success */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["SocializeApiModulesReleaseCommunicationsContractsReleaseCommitDto"];
|
||||
};
|
||||
};
|
||||
/** @description Unauthorized */
|
||||
401: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Forbidden */
|
||||
403: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
};
|
||||
};
|
||||
SocializeApiModulesOrganizationsHandlersAddOrganizationMemberHandler: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
|
||||
@@ -0,0 +1,245 @@
|
||||
import { computed, ref } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
import { useClient } from '@/plugins/api.js';
|
||||
|
||||
const DEFAULT_COMMIT_FILTERS = Object.freeze({
|
||||
status: '',
|
||||
updateId: '',
|
||||
author: '',
|
||||
search: '',
|
||||
});
|
||||
|
||||
export const RELEASE_UPDATE_CATEGORIES = ['Feature', 'Improvement', 'Fix', 'Breaking Change'];
|
||||
export const RELEASE_UPDATE_IMPORTANCE = ['Normal', 'Important'];
|
||||
export const RELEASE_UPDATE_AUDIENCES = ['Everyone', 'OrganizationOwners', 'Developers'];
|
||||
export const RELEASE_COMMIT_STATUSES = ['Unreviewed', 'Linked', 'InternalOnly', 'Ignored'];
|
||||
|
||||
export const useReleaseCommunicationsStore = defineStore('release-communications', () => {
|
||||
const client = useClient();
|
||||
const updates = ref([]);
|
||||
const unreadSummary = ref({ unreadCount: 0, importantUnreadCount: 0, updates: [] });
|
||||
const developerUpdates = ref([]);
|
||||
const selectedUpdate = ref(null);
|
||||
const commits = ref([]);
|
||||
const commitFilters = ref({ ...DEFAULT_COMMIT_FILTERS });
|
||||
const isLoading = ref(false);
|
||||
const isSaving = ref(false);
|
||||
const isSendingEmail = ref(false);
|
||||
const isImporting = ref(false);
|
||||
const error = ref(null);
|
||||
|
||||
const unreadCount = computed(() => unreadSummary.value?.unreadCount ?? 0);
|
||||
const importantUnreadCount = computed(() => unreadSummary.value?.importantUnreadCount ?? 0);
|
||||
const unreviewedCommitCount = computed(() =>
|
||||
commits.value.filter(commit => commit.communicationStatus === 'Unreviewed').length
|
||||
);
|
||||
|
||||
const filteredCommits = computed(() => {
|
||||
const query = commitFilters.value.search.trim().toLowerCase();
|
||||
const author = commitFilters.value.author.trim().toLowerCase();
|
||||
|
||||
return commits.value.filter(commit => {
|
||||
if (commitFilters.value.status && commit.communicationStatus !== commitFilters.value.status) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (commitFilters.value.updateId && commit.releaseUpdateId !== commitFilters.value.updateId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (author) {
|
||||
const authorText = `${commit.authorName ?? ''} ${commit.authorEmail ?? ''}`.toLowerCase();
|
||||
if (!authorText.includes(author)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (query) {
|
||||
const haystack = [
|
||||
commit.sha,
|
||||
commit.shortSha,
|
||||
commit.subject,
|
||||
commit.authorName,
|
||||
commit.authorEmail,
|
||||
commit.deploymentLabel,
|
||||
commit.sourceBranch,
|
||||
].filter(Boolean).join(' ').toLowerCase();
|
||||
if (!haystack.includes(query)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
});
|
||||
|
||||
async function loadUserUpdates() {
|
||||
isLoading.value = true;
|
||||
error.value = null;
|
||||
try {
|
||||
const [updatesResponse, unreadResponse] = await Promise.all([
|
||||
client.get('/api/release-updates'),
|
||||
client.get('/api/release-updates/unread'),
|
||||
]);
|
||||
updates.value = updatesResponse.data ?? [];
|
||||
unreadSummary.value = unreadResponse.data ?? { unreadCount: 0, importantUnreadCount: 0, updates: [] };
|
||||
} catch (loadError) {
|
||||
console.error('Failed to load release updates:', loadError);
|
||||
error.value = 'releaseCommunications.errors.loadFailed';
|
||||
throw loadError;
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function markRead(id) {
|
||||
await client.post(`/api/release-updates/${id}/read`);
|
||||
updates.value = updates.value.map(update => update.id === id ? { ...update, isRead: true } : update);
|
||||
await loadUnreadSummary();
|
||||
}
|
||||
|
||||
async function markAllRead() {
|
||||
await client.post('/api/release-updates/read-all');
|
||||
updates.value = updates.value.map(update => ({ ...update, isRead: true }));
|
||||
await loadUnreadSummary();
|
||||
}
|
||||
|
||||
async function loadUnreadSummary() {
|
||||
const response = await client.get('/api/release-updates/unread');
|
||||
unreadSummary.value = response.data ?? { unreadCount: 0, importantUnreadCount: 0, updates: [] };
|
||||
}
|
||||
|
||||
async function loadDeveloperUpdates() {
|
||||
isLoading.value = true;
|
||||
error.value = null;
|
||||
try {
|
||||
const response = await client.get('/api/developer/release-updates');
|
||||
developerUpdates.value = response.data ?? [];
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function loadDeveloperUpdate(id) {
|
||||
isLoading.value = true;
|
||||
try {
|
||||
const response = await client.get(`/api/developer/release-updates/${id}`);
|
||||
selectedUpdate.value = response.data;
|
||||
return selectedUpdate.value;
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function saveDeveloperUpdate(payload, id = null) {
|
||||
isSaving.value = true;
|
||||
try {
|
||||
const response = id
|
||||
? await client.put(`/api/developer/release-updates/${id}`, payload)
|
||||
: await client.post('/api/developer/release-updates', payload);
|
||||
selectedUpdate.value = response.data;
|
||||
await loadDeveloperUpdates();
|
||||
return response.data;
|
||||
} finally {
|
||||
isSaving.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function publishUpdate(id) {
|
||||
const response = await client.post(`/api/developer/release-updates/${id}/publish`);
|
||||
selectedUpdate.value = response.data;
|
||||
await loadDeveloperUpdates();
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async function archiveUpdate(id) {
|
||||
const response = await client.post(`/api/developer/release-updates/${id}/archive`);
|
||||
selectedUpdate.value = response.data;
|
||||
await loadDeveloperUpdates();
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async function sendUpdateEmail(id, payload) {
|
||||
isSendingEmail.value = true;
|
||||
try {
|
||||
return (await client.post(`/api/developer/release-updates/${id}/send-email`, payload)).data;
|
||||
} finally {
|
||||
isSendingEmail.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function loadCommits() {
|
||||
const response = await client.get('/api/developer/release-commits');
|
||||
commits.value = response.data ?? [];
|
||||
}
|
||||
|
||||
async function importCommits(payload) {
|
||||
isImporting.value = true;
|
||||
try {
|
||||
const response = await client.post('/api/developer/release-commits/import', payload);
|
||||
await loadCommits();
|
||||
return response.data;
|
||||
} finally {
|
||||
isImporting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function linkCommit(sha, releaseUpdateId) {
|
||||
await client.post(`/api/developer/release-commits/${sha}/link`, { releaseUpdateId });
|
||||
await loadCommits();
|
||||
}
|
||||
|
||||
async function unlinkCommit(sha) {
|
||||
await client.post(`/api/developer/release-commits/${sha}/unlink`);
|
||||
await loadCommits();
|
||||
}
|
||||
|
||||
async function markCommitInternalOnly(sha) {
|
||||
await client.post(`/api/developer/release-commits/${sha}/internal-only`);
|
||||
await loadCommits();
|
||||
}
|
||||
|
||||
async function ignoreCommit(sha) {
|
||||
await client.post(`/api/developer/release-commits/${sha}/ignore`);
|
||||
await loadCommits();
|
||||
}
|
||||
|
||||
function resetCommitFilters() {
|
||||
commitFilters.value = { ...DEFAULT_COMMIT_FILTERS };
|
||||
}
|
||||
|
||||
return {
|
||||
updates,
|
||||
unreadSummary,
|
||||
developerUpdates,
|
||||
selectedUpdate,
|
||||
commits,
|
||||
commitFilters,
|
||||
filteredCommits,
|
||||
unreadCount,
|
||||
importantUnreadCount,
|
||||
unreviewedCommitCount,
|
||||
isLoading,
|
||||
isSaving,
|
||||
isSendingEmail,
|
||||
isImporting,
|
||||
error,
|
||||
loadUserUpdates,
|
||||
loadUnreadSummary,
|
||||
markRead,
|
||||
markAllRead,
|
||||
loadDeveloperUpdates,
|
||||
loadDeveloperUpdate,
|
||||
saveDeveloperUpdate,
|
||||
publishUpdate,
|
||||
archiveUpdate,
|
||||
sendUpdateEmail,
|
||||
loadCommits,
|
||||
importCommits,
|
||||
linkCommit,
|
||||
unlinkCommit,
|
||||
markCommitInternalOnly,
|
||||
ignoreCommit,
|
||||
resetCommitFilters,
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,155 @@
|
||||
<script setup>
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import {
|
||||
RELEASE_COMMIT_STATUSES,
|
||||
useReleaseCommunicationsStore,
|
||||
} from '@/features/release-communications/stores/releaseCommunicationsStore.js';
|
||||
|
||||
const { t } = useI18n();
|
||||
const store = useReleaseCommunicationsStore();
|
||||
const importJson = ref('[]');
|
||||
|
||||
const updateOptions = computed(() =>
|
||||
store.developerUpdates.map(update => ({ title: update.title, value: update.id }))
|
||||
);
|
||||
|
||||
onMounted(async () => {
|
||||
await Promise.all([store.loadDeveloperUpdates(), store.loadCommits()]);
|
||||
});
|
||||
|
||||
async function importPayload() {
|
||||
const commits = JSON.parse(importJson.value);
|
||||
await store.importCommits({ commits });
|
||||
}
|
||||
|
||||
function formatDate(value) {
|
||||
return value ? new Date(value).toLocaleString() : '';
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="commits-page">
|
||||
<header class="page-header">
|
||||
<div>
|
||||
<div class="eyebrow">{{ t('releaseCommunications.commits.eyebrow') }}</div>
|
||||
<h1>{{ t('releaseCommunications.commits.title') }}</h1>
|
||||
<p>{{ t('releaseCommunications.commits.description') }}</p>
|
||||
</div>
|
||||
<strong>{{ store.unreviewedCommitCount }} {{ t('releaseCommunications.commits.unreviewed') }}</strong>
|
||||
</header>
|
||||
|
||||
<section class="import-panel">
|
||||
<v-textarea
|
||||
v-model="importJson"
|
||||
:label="t('releaseCommunications.commits.importJson')"
|
||||
rows="5"
|
||||
variant="outlined"
|
||||
/>
|
||||
<v-btn :loading="store.isImporting" @click="importPayload">{{ t('releaseCommunications.commits.import') }}</v-btn>
|
||||
</section>
|
||||
|
||||
<section class="filter-panel">
|
||||
<v-text-field v-model="store.commitFilters.search" :label="t('releaseCommunications.commits.search')" density="compact" variant="outlined" hide-details />
|
||||
<v-select v-model="store.commitFilters.status" :items="RELEASE_COMMIT_STATUSES" :label="t('releaseCommunications.commits.status')" density="compact" variant="outlined" hide-details clearable />
|
||||
<v-select v-model="store.commitFilters.updateId" :items="updateOptions" :label="t('releaseCommunications.commits.linkedUpdate')" density="compact" variant="outlined" hide-details clearable />
|
||||
<v-text-field v-model="store.commitFilters.author" :label="t('releaseCommunications.commits.author')" density="compact" variant="outlined" hide-details clearable />
|
||||
<v-btn variant="outlined" @click="store.resetCommitFilters">{{ t('releaseCommunications.commits.clear') }}</v-btn>
|
||||
</section>
|
||||
|
||||
<section class="commit-table">
|
||||
<article
|
||||
v-for="commit in store.filteredCommits"
|
||||
:key="commit.sha"
|
||||
class="commit-row"
|
||||
>
|
||||
<div>
|
||||
<code>{{ commit.shortSha }}</code>
|
||||
<strong>{{ commit.subject }}</strong>
|
||||
<small>{{ commit.authorName }} / {{ formatDate(commit.committedAt) }}</small>
|
||||
</div>
|
||||
<span>{{ commit.communicationStatus }}</span>
|
||||
<v-select
|
||||
:model-value="commit.releaseUpdateId"
|
||||
:items="updateOptions"
|
||||
:label="t('releaseCommunications.commits.link')"
|
||||
density="compact"
|
||||
variant="outlined"
|
||||
hide-details
|
||||
clearable
|
||||
@update:model-value="value => value ? store.linkCommit(commit.sha, value) : store.unlinkCommit(commit.sha)"
|
||||
/>
|
||||
<div class="commit-actions">
|
||||
<v-btn size="small" variant="outlined" @click="store.markCommitInternalOnly(commit.sha)">{{ t('releaseCommunications.commits.internalOnly') }}</v-btn>
|
||||
<v-btn size="small" variant="outlined" @click="store.ignoreCommit(commit.sha)">{{ t('releaseCommunications.commits.ignore') }}</v-btn>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.commits-page {
|
||||
display: grid;
|
||||
gap: 18px;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.page-header,
|
||||
.filter-panel,
|
||||
.commit-row,
|
||||
.commit-actions {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
color: rgb(var(--v-theme-primary));
|
||||
font-size: 0.75rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.import-panel,
|
||||
.filter-panel,
|
||||
.commit-row {
|
||||
border: 1px solid #d8dee8;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
.filter-panel {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.commit-table {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.commit-row {
|
||||
align-items: center;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) 120px minmax(220px, 320px) auto;
|
||||
}
|
||||
|
||||
.commit-row > div:first-child {
|
||||
display: grid;
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.filter-panel,
|
||||
.commit-row {
|
||||
grid-template-columns: 1fr;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,246 @@
|
||||
<script setup>
|
||||
import { computed, onMounted, reactive, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import {
|
||||
RELEASE_UPDATE_AUDIENCES,
|
||||
RELEASE_UPDATE_CATEGORIES,
|
||||
RELEASE_UPDATE_IMPORTANCE,
|
||||
useReleaseCommunicationsStore,
|
||||
} from '@/features/release-communications/stores/releaseCommunicationsStore.js';
|
||||
|
||||
const { t } = useI18n();
|
||||
const store = useReleaseCommunicationsStore();
|
||||
const editingId = ref(null);
|
||||
const form = reactive({
|
||||
title: '',
|
||||
summary: '',
|
||||
body: '',
|
||||
category: 'Feature',
|
||||
importance: 'Normal',
|
||||
audience: 'Everyone',
|
||||
deploymentLabel: '',
|
||||
buildVersion: '',
|
||||
commitRange: '',
|
||||
});
|
||||
const emailTestMode = ref(true);
|
||||
const confirmResend = ref(false);
|
||||
const emailResult = ref(null);
|
||||
|
||||
const linkedCommits = computed(() =>
|
||||
editingId.value
|
||||
? store.commits.filter(commit => commit.releaseUpdateId === editingId.value)
|
||||
: []
|
||||
);
|
||||
|
||||
onMounted(async () => {
|
||||
await Promise.all([store.loadDeveloperUpdates(), store.loadCommits()]);
|
||||
});
|
||||
|
||||
function editUpdate(update) {
|
||||
editingId.value = update.id;
|
||||
Object.assign(form, {
|
||||
title: update.title ?? '',
|
||||
summary: update.summary ?? '',
|
||||
body: update.body ?? '',
|
||||
category: update.category ?? 'Feature',
|
||||
importance: update.importance ?? 'Normal',
|
||||
audience: update.audience ?? 'Everyone',
|
||||
deploymentLabel: update.deploymentLabel ?? '',
|
||||
buildVersion: update.buildVersion ?? '',
|
||||
commitRange: update.commitRange ?? '',
|
||||
});
|
||||
store.selectedUpdate = update;
|
||||
}
|
||||
|
||||
function newUpdate() {
|
||||
editingId.value = null;
|
||||
Object.assign(form, {
|
||||
title: '',
|
||||
summary: '',
|
||||
body: '',
|
||||
category: 'Feature',
|
||||
importance: 'Normal',
|
||||
audience: 'Everyone',
|
||||
deploymentLabel: '',
|
||||
buildVersion: '',
|
||||
commitRange: '',
|
||||
});
|
||||
emailResult.value = null;
|
||||
}
|
||||
|
||||
async function save() {
|
||||
await store.saveDeveloperUpdate({ ...form }, editingId.value);
|
||||
editingId.value = store.selectedUpdate?.id ?? editingId.value;
|
||||
}
|
||||
|
||||
async function sendEmail() {
|
||||
if (!editingId.value || !window.confirm(t('releaseCommunications.developer.confirmEmail'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
emailResult.value = await store.sendUpdateEmail(editingId.value, {
|
||||
testMode: emailTestMode.value,
|
||||
confirmResend: confirmResend.value,
|
||||
});
|
||||
await store.loadDeveloperUpdate(editingId.value);
|
||||
await store.loadDeveloperUpdates();
|
||||
}
|
||||
|
||||
function formatDate(value) {
|
||||
return value ? new Date(value).toLocaleString() : t('releaseCommunications.emptyValue');
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="developer-updates-page">
|
||||
<header class="page-header">
|
||||
<div>
|
||||
<div class="eyebrow">{{ t('releaseCommunications.developer.eyebrow') }}</div>
|
||||
<h1>{{ t('releaseCommunications.developer.title') }}</h1>
|
||||
</div>
|
||||
<v-btn @click="newUpdate">{{ t('releaseCommunications.developer.newUpdate') }}</v-btn>
|
||||
</header>
|
||||
|
||||
<section class="editor-grid">
|
||||
<form
|
||||
class="editor-panel"
|
||||
@submit.prevent="save"
|
||||
>
|
||||
<v-text-field v-model="form.title" :label="t('title')" density="compact" variant="outlined" />
|
||||
<v-textarea v-model="form.summary" :label="t('releaseCommunications.summary')" rows="2" variant="outlined" />
|
||||
<v-textarea v-model="form.body" :label="t('releaseCommunications.body')" rows="5" variant="outlined" />
|
||||
<div class="form-row">
|
||||
<v-select v-model="form.category" :items="RELEASE_UPDATE_CATEGORIES" :label="t('releaseCommunications.category')" density="compact" variant="outlined" />
|
||||
<v-select v-model="form.importance" :items="RELEASE_UPDATE_IMPORTANCE" :label="t('releaseCommunications.importance')" density="compact" variant="outlined" />
|
||||
<v-select v-model="form.audience" :items="RELEASE_UPDATE_AUDIENCES" :label="t('releaseCommunications.audience')" density="compact" variant="outlined" />
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<v-text-field v-model="form.deploymentLabel" :label="t('releaseCommunications.deploymentLabel')" density="compact" variant="outlined" />
|
||||
<v-text-field v-model="form.buildVersion" :label="t('releaseCommunications.buildVersion')" density="compact" variant="outlined" />
|
||||
<v-text-field v-model="form.commitRange" :label="t('releaseCommunications.commitRange')" density="compact" variant="outlined" />
|
||||
</div>
|
||||
<div class="actions">
|
||||
<v-btn type="submit" :loading="store.isSaving">{{ t('save') }}</v-btn>
|
||||
<v-btn v-if="editingId" variant="outlined" @click="store.publishUpdate(editingId)">{{ t('releaseCommunications.developer.publish') }}</v-btn>
|
||||
<v-btn v-if="editingId" variant="outlined" @click="store.archiveUpdate(editingId)">{{ t('releaseCommunications.developer.archive') }}</v-btn>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="editingId"
|
||||
class="email-panel"
|
||||
>
|
||||
<strong>{{ t('releaseCommunications.developer.pushEmail') }}</strong>
|
||||
<v-checkbox v-model="emailTestMode" :label="t('releaseCommunications.developer.testMode')" density="compact" hide-details />
|
||||
<v-checkbox v-model="confirmResend" :label="t('releaseCommunications.developer.confirmResend')" density="compact" hide-details />
|
||||
<v-btn variant="outlined" :loading="store.isSendingEmail" @click="sendEmail">{{ t('releaseCommunications.developer.sendEmail') }}</v-btn>
|
||||
<small v-if="emailResult">{{ t('releaseCommunications.developer.emailResult', { count: emailResult.recipientCount }) }}</small>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<aside class="updates-panel">
|
||||
<button
|
||||
v-for="update in store.developerUpdates"
|
||||
:key="update.id"
|
||||
class="update-row"
|
||||
type="button"
|
||||
@click="editUpdate(update)"
|
||||
>
|
||||
<strong>{{ update.title }}</strong>
|
||||
<span>{{ update.status }} / {{ update.audience }}</span>
|
||||
<small>{{ formatDate(update.publishedAt ?? update.createdAt) }}</small>
|
||||
</button>
|
||||
</aside>
|
||||
</section>
|
||||
|
||||
<section
|
||||
v-if="editingId"
|
||||
class="linked-commits"
|
||||
>
|
||||
<h2>{{ t('releaseCommunications.developer.linkedCommits') }}</h2>
|
||||
<div v-if="!linkedCommits.length" class="page-message">{{ t('releaseCommunications.developer.noLinkedCommits') }}</div>
|
||||
<div
|
||||
v-for="commit in linkedCommits"
|
||||
:key="commit.sha"
|
||||
class="commit-chip"
|
||||
>
|
||||
<code>{{ commit.shortSha }}</code>
|
||||
<span>{{ commit.subject }}</span>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.developer-updates-page {
|
||||
display: grid;
|
||||
gap: 20px;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.page-header,
|
||||
.actions,
|
||||
.form-row {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
color: rgb(var(--v-theme-primary));
|
||||
font-size: 0.75rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.editor-grid {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.3fr) minmax(280px, 0.7fr);
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.editor-panel,
|
||||
.updates-panel,
|
||||
.linked-commits {
|
||||
border: 1px solid #d8dee8;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.update-row {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
gap: 3px;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
background: transparent;
|
||||
padding: 10px 0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.email-panel {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
margin-top: 16px;
|
||||
border-top: 1px solid #e2e8f0;
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
.commit-chip {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.editor-grid,
|
||||
.form-row {
|
||||
grid-template-columns: 1fr;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,167 @@
|
||||
<script setup>
|
||||
import { computed, onMounted } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useReleaseCommunicationsStore } from '@/features/release-communications/stores/releaseCommunicationsStore.js';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const store = useReleaseCommunicationsStore();
|
||||
|
||||
const highlightedId = computed(() => route.query.updateId);
|
||||
|
||||
onMounted(async () => {
|
||||
await store.loadUserUpdates();
|
||||
if (highlightedId.value) {
|
||||
await store.markRead(highlightedId.value);
|
||||
}
|
||||
});
|
||||
|
||||
function formatDate(value) {
|
||||
return value ? new Date(value).toLocaleString() : '';
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="updates-page">
|
||||
<header class="updates-header">
|
||||
<div>
|
||||
<div class="eyebrow">{{ t('releaseCommunications.user.eyebrow') }}</div>
|
||||
<h1>{{ t('releaseCommunications.user.title') }}</h1>
|
||||
<p>{{ t('releaseCommunications.user.description') }}</p>
|
||||
</div>
|
||||
<v-btn
|
||||
variant="outlined"
|
||||
:disabled="!store.unreadCount"
|
||||
@click="store.markAllRead"
|
||||
>
|
||||
{{ t('releaseCommunications.user.markAllRead') }}
|
||||
</v-btn>
|
||||
</header>
|
||||
|
||||
<div
|
||||
v-if="store.isLoading"
|
||||
class="page-message"
|
||||
>
|
||||
{{ t('loading') }}
|
||||
</div>
|
||||
|
||||
<section
|
||||
v-else
|
||||
class="updates-list"
|
||||
>
|
||||
<article
|
||||
v-for="update in store.updates"
|
||||
:key="update.id"
|
||||
class="update-entry"
|
||||
:class="{ 'update-entry-unread': !update.isRead, 'update-entry-highlight': update.id === highlightedId }"
|
||||
@click="!update.isRead && store.markRead(update.id)"
|
||||
>
|
||||
<div class="update-meta">
|
||||
<span>{{ update.category }}</span>
|
||||
<span>{{ update.importance }}</span>
|
||||
<time>{{ formatDate(update.publishedAt) }}</time>
|
||||
</div>
|
||||
<h2>{{ update.title }}</h2>
|
||||
<p>{{ update.summary }}</p>
|
||||
<div
|
||||
v-if="update.body"
|
||||
class="update-body"
|
||||
>
|
||||
{{ update.body }}
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<div
|
||||
v-if="!store.updates.length"
|
||||
class="page-message"
|
||||
>
|
||||
{{ t('releaseCommunications.user.empty') }}
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.updates-page {
|
||||
display: grid;
|
||||
gap: 20px;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.updates-header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.eyebrow,
|
||||
.update-meta {
|
||||
color: rgb(var(--v-theme-primary));
|
||||
font-size: 0.75rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.updates-header h1 {
|
||||
margin: 4px 0;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
|
||||
.updates-header p {
|
||||
margin: 0;
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.updates-list {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.update-entry {
|
||||
border: 1px solid #d8dee8;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.update-entry-unread {
|
||||
border-color: rgb(var(--v-theme-primary));
|
||||
box-shadow: inset 3px 0 0 rgb(var(--v-theme-primary));
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.update-entry-highlight {
|
||||
outline: 2px solid rgb(var(--v-theme-primary));
|
||||
}
|
||||
|
||||
.update-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
margin-bottom: 8px;
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.update-entry h2 {
|
||||
margin: 0 0 6px;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.update-entry p {
|
||||
margin: 0;
|
||||
color: #334155;
|
||||
}
|
||||
|
||||
.update-body {
|
||||
margin-top: 12px;
|
||||
color: #475569;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.page-message {
|
||||
padding: 24px;
|
||||
color: #64748b;
|
||||
}
|
||||
</style>
|
||||
@@ -5,6 +5,7 @@
|
||||
import { useAuthStore } from '@/features/auth/stores/authStore.js';
|
||||
import { useChannelsStore } from '@/features/channels/stores/channelsStore.js';
|
||||
import { useNotificationsStore } from '@/features/notifications/stores/notificationsStore.js';
|
||||
import { useReleaseCommunicationsStore } from '@/features/release-communications/stores/releaseCommunicationsStore.js';
|
||||
import { getNotificationRoute } from '@/features/notifications/notificationRoutes.js';
|
||||
import { useContentItemsStore } from '@/features/content/stores/contentItemsStore.js';
|
||||
import { useCampaignsStore } from '@/features/campaigns/stores/campaignsStore.js';
|
||||
@@ -22,6 +23,8 @@
|
||||
mdiMagnify,
|
||||
mdiPlus,
|
||||
mdiBugOutline,
|
||||
mdiBullhornOutline,
|
||||
mdiSourceCommit,
|
||||
} from '@mdi/js';
|
||||
|
||||
const props = defineProps({
|
||||
@@ -38,6 +41,7 @@
|
||||
const channelsStore = useChannelsStore();
|
||||
const contentItemsStore = useContentItemsStore();
|
||||
const notificationsStore = useNotificationsStore();
|
||||
const releaseCommunicationsStore = useReleaseCommunicationsStore();
|
||||
const campaignsStore = useCampaignsStore();
|
||||
const isNotificationsOpen = ref(false);
|
||||
const isSearchFocused = ref(false);
|
||||
@@ -51,7 +55,10 @@
|
||||
const primaryLinks = [
|
||||
{ to: '/app/dashboard', labelKey: 'nav.overview', icon: mdiHomeOutline },
|
||||
{ to: '/app/media-library', labelKey: 'nav.mediaLibrary', icon: mdiImageMultipleOutline },
|
||||
{ to: '/app/updates', labelKey: 'nav.whatsNew', icon: mdiBullhornOutline, badge: 'updates' },
|
||||
{ to: '/app/feedback', labelKey: 'nav.feedbackReview', icon: mdiBugOutline, roles: ['developer'] },
|
||||
{ to: '/app/developer/updates', labelKey: 'nav.releaseUpdates', icon: mdiBullhornOutline, roles: ['developer'] },
|
||||
{ to: '/app/developer/release-commits', labelKey: 'nav.releaseCommits', icon: mdiSourceCommit, roles: ['developer'], badge: 'commits' },
|
||||
];
|
||||
const visiblePrimaryLinks = computed(() =>
|
||||
primaryLinks.filter(link => !link.roles || authStore.hasAnyRole(link.roles))
|
||||
@@ -231,6 +238,14 @@
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
releaseCommunicationsStore.loadUnreadSummary().catch(error => {
|
||||
console.error('Failed to load release update unread count:', error);
|
||||
});
|
||||
if (authStore.hasAnyRole(['developer'])) {
|
||||
releaseCommunicationsStore.loadCommits().catch(error => {
|
||||
console.error('Failed to load release commit count:', error);
|
||||
});
|
||||
}
|
||||
document.addEventListener('click', handleDocumentClick);
|
||||
window.addEventListener('resize', updateCollapsedSearchPanelPosition);
|
||||
window.addEventListener('scroll', updateCollapsedSearchPanelPosition, true);
|
||||
@@ -450,7 +465,21 @@
|
||||
active-class="sidebar-link-active"
|
||||
:title="!isExpanded ? t(link.labelKey) : null"
|
||||
>
|
||||
<v-icon :icon="link.icon" />
|
||||
<span class="sidebar-link-icon-wrap">
|
||||
<v-icon :icon="link.icon" />
|
||||
<span
|
||||
v-if="link.badge === 'updates' && releaseCommunicationsStore.unreadCount"
|
||||
class="sidebar-notification-badge"
|
||||
>
|
||||
{{ Math.min(releaseCommunicationsStore.unreadCount, 9) }}
|
||||
</span>
|
||||
<span
|
||||
v-if="link.badge === 'commits' && releaseCommunicationsStore.unreviewedCommitCount"
|
||||
class="sidebar-notification-badge"
|
||||
>
|
||||
{{ Math.min(releaseCommunicationsStore.unreviewedCommitCount, 9) }}
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
v-if="isExpanded"
|
||||
class="sidebar-link-label"
|
||||
@@ -781,6 +810,10 @@
|
||||
@apply relative flex items-center justify-center;
|
||||
}
|
||||
|
||||
.sidebar-link-icon-wrap {
|
||||
@apply relative flex items-center justify-center;
|
||||
}
|
||||
|
||||
.sidebar-notification-badge {
|
||||
@apply absolute -right-2 -top-2 flex h-5 min-w-[1.25rem] items-center justify-center rounded-full px-1 text-[10px] font-black;
|
||||
background: #ef4444;
|
||||
|
||||
@@ -560,6 +560,9 @@
|
||||
"mediaLibrary": "Media Library",
|
||||
"myFeedback": "My Feedback",
|
||||
"feedbackReview": "Feedback Review",
|
||||
"whatsNew": "What's New",
|
||||
"releaseUpdates": "Release Updates",
|
||||
"releaseCommits": "Release Commits",
|
||||
"channels": "Channels",
|
||||
"campaigns": "Campaigns",
|
||||
"reviewQueue": "Review Queue",
|
||||
@@ -592,6 +595,58 @@
|
||||
"feedbackReporterCommented": "Reporter replied"
|
||||
}
|
||||
},
|
||||
"releaseCommunications": {
|
||||
"summary": "Summary",
|
||||
"body": "Body",
|
||||
"category": "Category",
|
||||
"importance": "Importance",
|
||||
"audience": "Audience",
|
||||
"deploymentLabel": "Deployment label",
|
||||
"buildVersion": "Build version",
|
||||
"commitRange": "Commit range",
|
||||
"emptyValue": "Not set",
|
||||
"errors": {
|
||||
"loadFailed": "Could not load product updates."
|
||||
},
|
||||
"user": {
|
||||
"eyebrow": "Product updates",
|
||||
"title": "What's New",
|
||||
"description": "Features, improvements, and fixes published since you last checked.",
|
||||
"markAllRead": "Mark all read",
|
||||
"empty": "No published updates yet."
|
||||
},
|
||||
"developer": {
|
||||
"eyebrow": "SaaS operator",
|
||||
"title": "Release updates",
|
||||
"newUpdate": "New update",
|
||||
"publish": "Publish",
|
||||
"archive": "Archive",
|
||||
"pushEmail": "Push email",
|
||||
"testMode": "Send to me only",
|
||||
"confirmResend": "Confirm resend",
|
||||
"sendEmail": "Send email",
|
||||
"confirmEmail": "Send this release update by email?",
|
||||
"emailResult": "Email sent to {count} recipient(s).",
|
||||
"linkedCommits": "Linked commits",
|
||||
"noLinkedCommits": "No commits linked to this update yet."
|
||||
},
|
||||
"commits": {
|
||||
"eyebrow": "SaaS operator",
|
||||
"title": "Release commits",
|
||||
"description": "Import shipped commits and reconcile them with curated update entries.",
|
||||
"unreviewed": "unreviewed",
|
||||
"importJson": "Commit JSON payload",
|
||||
"import": "Import commits",
|
||||
"search": "Search",
|
||||
"status": "Status",
|
||||
"linkedUpdate": "Linked update",
|
||||
"author": "Author",
|
||||
"clear": "Clear",
|
||||
"link": "Update",
|
||||
"internalOnly": "Internal only",
|
||||
"ignore": "Ignore"
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
"button": "Feedback",
|
||||
"open": "Send product feedback",
|
||||
|
||||
@@ -560,6 +560,9 @@
|
||||
"mediaLibrary": "Bibliotheque media",
|
||||
"myFeedback": "Mon feedback",
|
||||
"feedbackReview": "Revue feedback",
|
||||
"whatsNew": "Nouveautés",
|
||||
"releaseUpdates": "Mises à jour",
|
||||
"releaseCommits": "Commits release",
|
||||
"channels": "Canaux",
|
||||
"campaigns": "Campagnes",
|
||||
"reviewQueue": "File de révision",
|
||||
@@ -592,6 +595,58 @@
|
||||
"feedbackReporterCommented": "Réponse du rapporteur"
|
||||
}
|
||||
},
|
||||
"releaseCommunications": {
|
||||
"summary": "Résumé",
|
||||
"body": "Détail",
|
||||
"category": "Catégorie",
|
||||
"importance": "Importance",
|
||||
"audience": "Audience",
|
||||
"deploymentLabel": "Libellé de déploiement",
|
||||
"buildVersion": "Version build",
|
||||
"commitRange": "Plage de commits",
|
||||
"emptyValue": "Non défini",
|
||||
"errors": {
|
||||
"loadFailed": "Impossible de charger les mises à jour produit."
|
||||
},
|
||||
"user": {
|
||||
"eyebrow": "Mises à jour produit",
|
||||
"title": "Nouveautés",
|
||||
"description": "Fonctionnalités, améliorations et corrections publiées depuis votre dernière visite.",
|
||||
"markAllRead": "Tout marquer lu",
|
||||
"empty": "Aucune mise à jour publiée pour le moment."
|
||||
},
|
||||
"developer": {
|
||||
"eyebrow": "Opérateur SaaS",
|
||||
"title": "Mises à jour release",
|
||||
"newUpdate": "Nouvelle mise à jour",
|
||||
"publish": "Publier",
|
||||
"archive": "Archiver",
|
||||
"pushEmail": "Email push",
|
||||
"testMode": "M'envoyer seulement",
|
||||
"confirmResend": "Confirmer le renvoi",
|
||||
"sendEmail": "Envoyer email",
|
||||
"confirmEmail": "Envoyer cette mise à jour par email?",
|
||||
"emailResult": "Email envoyé à {count} destinataire(s).",
|
||||
"linkedCommits": "Commits liés",
|
||||
"noLinkedCommits": "Aucun commit lié à cette mise à jour."
|
||||
},
|
||||
"commits": {
|
||||
"eyebrow": "Opérateur SaaS",
|
||||
"title": "Commits release",
|
||||
"description": "Importez les commits livrés et associez-les aux mises à jour rédigées.",
|
||||
"unreviewed": "non révisés",
|
||||
"importJson": "Payload JSON de commits",
|
||||
"import": "Importer commits",
|
||||
"search": "Recherche",
|
||||
"status": "Statut",
|
||||
"linkedUpdate": "Mise à jour liée",
|
||||
"author": "Auteur",
|
||||
"clear": "Effacer",
|
||||
"link": "Mise à jour",
|
||||
"internalOnly": "Interne seulement",
|
||||
"ignore": "Ignorer"
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
"button": "Feedback",
|
||||
"open": "Envoyer un feedback produit",
|
||||
|
||||
@@ -36,6 +36,7 @@ import { useContentItemsStore } from '@/features/content/stores/contentItemsStor
|
||||
import { useClientsStore } from '@/features/clients/stores/clientsStore.js';
|
||||
import { useCampaignsStore } from '@/features/campaigns/stores/campaignsStore.js';
|
||||
import { useNotificationsStore } from '@/features/notifications/stores/notificationsStore.js';
|
||||
import { useReleaseCommunicationsStore } from '@/features/release-communications/stores/releaseCommunicationsStore.js';
|
||||
import { useChannelsStore } from '@/features/channels/stores/channelsStore.js';
|
||||
import { i18n } from '@/plugins/i18n.js';
|
||||
import config from '@/config.js';
|
||||
@@ -101,5 +102,6 @@ useChannelsStore();
|
||||
useReviewQueueStore();
|
||||
useContentItemsStore();
|
||||
useNotificationsStore();
|
||||
useReleaseCommunicationsStore();
|
||||
|
||||
app.mount('#app');
|
||||
|
||||
@@ -33,6 +33,9 @@ const MyFeedbackListView = () => import('@/features/feedback/views/MyFeedbackLis
|
||||
const MyFeedbackDetailView = () => import('@/features/feedback/views/MyFeedbackDetailView.vue');
|
||||
const DeveloperFeedbackListView = () => import('@/features/feedback/views/DeveloperFeedbackListView.vue');
|
||||
const DeveloperFeedbackDetailView = () => import('@/features/feedback/views/DeveloperFeedbackDetailView.vue');
|
||||
const UpdatesView = () => import('@/features/release-communications/views/UpdatesView.vue');
|
||||
const DeveloperUpdatesView = () => import('@/features/release-communications/views/DeveloperUpdatesView.vue');
|
||||
const DeveloperReleaseCommitsView = () => import('@/features/release-communications/views/DeveloperReleaseCommitsView.vue');
|
||||
|
||||
const routes = [
|
||||
{
|
||||
@@ -123,6 +126,24 @@ const routes = [
|
||||
component: MyFeedbackDetailView,
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
{
|
||||
path: '/app/updates',
|
||||
name: 'release-updates',
|
||||
component: UpdatesView,
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
{
|
||||
path: '/app/developer/updates',
|
||||
name: 'developer-release-updates',
|
||||
component: DeveloperUpdatesView,
|
||||
meta: { requiresAuth: true, roles: ['developer'] },
|
||||
},
|
||||
{
|
||||
path: '/app/developer/release-commits',
|
||||
name: 'developer-release-commits',
|
||||
component: DeveloperReleaseCommitsView,
|
||||
meta: { requiresAuth: true, roles: ['developer'] },
|
||||
},
|
||||
{
|
||||
path: '/app/feedback',
|
||||
name: 'developer-feedback',
|
||||
|
||||
Reference in New Issue
Block a user