mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-01 21:13:09 +00:00
feat(portal): add notifications sidebar (#2516)
* feat(portal): add notifications sidebar * chore: add service * chore: simplify style * chore: fix comments * WIP, moving notifications to patch-db * revamp notifications * chore: small adjustments --------- Co-authored-by: Matt Hill <mattnine@protonmail.com>
This commit is contained in:
@@ -339,6 +339,7 @@ export module Mock {
|
||||
},
|
||||
},
|
||||
},
|
||||
read: false,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
@@ -349,6 +350,7 @@ export module Mock {
|
||||
title: 'SSH Key Added',
|
||||
message: 'A new SSH key was added. If you did not do this, shit is bad.',
|
||||
data: null,
|
||||
read: false,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
@@ -359,6 +361,7 @@ export module Mock {
|
||||
title: 'SSH Key Removed',
|
||||
message: 'A SSH key was removed.',
|
||||
data: null,
|
||||
read: false,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
@@ -367,7 +370,7 @@ export module Mock {
|
||||
code: 4,
|
||||
level: NotificationLevel.Error,
|
||||
title: 'Service Crashed',
|
||||
message: new Array(40)
|
||||
message: new Array(3)
|
||||
.fill(
|
||||
`2021-11-27T18:36:30.451064Z 2021-11-27T18:36:30Z tor: Thread interrupt
|
||||
2021-11-27T18:36:30.452833Z 2021-11-27T18:36:30Z Shutdown: In progress...
|
||||
@@ -376,6 +379,7 @@ export module Mock {
|
||||
)
|
||||
.join(''),
|
||||
data: null,
|
||||
read: false,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -9,7 +9,13 @@ import {
|
||||
ServiceOutboundProxy,
|
||||
HealthCheckResult,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { StartOSDiskInfo, LogsRes, ServerLogsReq } from '@start9labs/shared'
|
||||
import {
|
||||
StartOSDiskInfo,
|
||||
FetchLogsReq,
|
||||
FetchLogsRes,
|
||||
FollowLogsRes,
|
||||
FollowLogsReq,
|
||||
} from '@start9labs/shared'
|
||||
import { customSmtp } from '@start9labs/start-sdk/lib/config/configConstants'
|
||||
|
||||
export module RR {
|
||||
@@ -50,14 +56,11 @@ export module RR {
|
||||
uptime: number // seconds
|
||||
}
|
||||
|
||||
export type GetServerLogsReq = ServerLogsReq // server.logs & server.kernel-logs
|
||||
export type GetServerLogsRes = LogsRes
|
||||
export type GetServerLogsReq = FetchLogsReq // server.logs & server.kernel-logs & server.tor-logs
|
||||
export type GetServerLogsRes = FetchLogsRes
|
||||
|
||||
export type FollowServerLogsReq = { limit?: number } // server.logs.follow & server.kernel-logs.follow
|
||||
export type FollowServerLogsRes = {
|
||||
'start-cursor': string
|
||||
guid: string
|
||||
}
|
||||
export type FollowServerLogsReq = FollowLogsReq & { limit?: number } // server.logs.follow & server.kernel-logs.follow & server.tor-logs.follow
|
||||
export type FollowServerLogsRes = FollowLogsRes
|
||||
|
||||
export type GetServerMetricsReq = {} // server.metrics
|
||||
export type GetServerMetricsRes = {
|
||||
@@ -109,17 +112,29 @@ export module RR {
|
||||
|
||||
// notification
|
||||
|
||||
export type FollowNotificationsReq = {}
|
||||
export type FollowNotificationsRes = {
|
||||
notifications: ServerNotifications
|
||||
guid: string
|
||||
}
|
||||
|
||||
export type GetNotificationsReq = {
|
||||
before?: number
|
||||
limit?: number
|
||||
} // notification.list
|
||||
export type GetNotificationsRes = ServerNotification<number>[]
|
||||
|
||||
export type DeleteNotificationReq = { id: number } // notification.delete
|
||||
export type DeleteNotificationReq = { ids: number[] } // notification.delete
|
||||
export type DeleteNotificationRes = null
|
||||
|
||||
export type DeleteAllNotificationsReq = { before: number } // notification.delete-before
|
||||
export type DeleteAllNotificationsRes = null
|
||||
export type MarkSeenNotificationReq = DeleteNotificationReq // notification.mark-seen
|
||||
export type MarkSeenNotificationRes = null
|
||||
|
||||
export type MarkSeenAllNotificationsReq = { before: number } // notification.mark-seen-before
|
||||
export type MarkSeenAllNotificationsRes = null
|
||||
|
||||
export type MarkUnseenNotificationReq = DeleteNotificationReq // notification.mark-unseen
|
||||
export type MarkUnseenNotificationRes = null
|
||||
|
||||
// network
|
||||
|
||||
@@ -298,8 +313,8 @@ export module RR {
|
||||
export type GetPackageCredentialsReq = { id: string } // package.credentials
|
||||
export type GetPackageCredentialsRes = Record<string, string>
|
||||
|
||||
export type GetPackageLogsReq = ServerLogsReq & { id: string } // package.logs
|
||||
export type GetPackageLogsRes = LogsRes
|
||||
export type GetPackageLogsReq = FetchLogsReq & { id: string } // package.logs
|
||||
export type GetPackageLogsRes = FetchLogsRes
|
||||
|
||||
export type FollowPackageLogsReq = FollowServerLogsReq & { id: string } // package.logs.follow
|
||||
export type FollowPackageLogsRes = FollowServerLogsRes
|
||||
@@ -562,7 +577,7 @@ export interface SSHKey {
|
||||
fingerprint: string
|
||||
}
|
||||
|
||||
export type ServerNotifications = ServerNotification<any>[]
|
||||
export type ServerNotifications = ServerNotification<number>[]
|
||||
|
||||
export interface ServerNotification<T extends number> {
|
||||
id: number
|
||||
@@ -573,6 +588,7 @@ export interface ServerNotification<T extends number> {
|
||||
title: string
|
||||
message: string
|
||||
data: NotificationData<T>
|
||||
read: boolean
|
||||
}
|
||||
|
||||
export enum NotificationLevel {
|
||||
|
||||
@@ -125,13 +125,21 @@ export abstract class ApiService {
|
||||
params: RR.GetNotificationsReq,
|
||||
): Promise<RR.GetNotificationsRes>
|
||||
|
||||
abstract deleteNotification(
|
||||
abstract markSeenNotifications(
|
||||
params: RR.MarkSeenNotificationReq,
|
||||
): Promise<RR.MarkSeenNotificationRes>
|
||||
|
||||
abstract markSeenAllNotifications(
|
||||
params: RR.MarkSeenAllNotificationsReq,
|
||||
): Promise<RR.MarkSeenAllNotificationsRes>
|
||||
|
||||
abstract markUnseenNotifications(
|
||||
params: RR.DeleteNotificationReq,
|
||||
): Promise<RR.DeleteNotificationRes>
|
||||
|
||||
abstract deleteAllNotifications(
|
||||
params: RR.DeleteAllNotificationsReq,
|
||||
): Promise<RR.DeleteAllNotificationsRes>
|
||||
abstract deleteNotifications(
|
||||
params: RR.DeleteNotificationReq,
|
||||
): Promise<RR.DeleteNotificationRes>
|
||||
|
||||
// network
|
||||
|
||||
@@ -308,8 +316,6 @@ export abstract class ApiService {
|
||||
|
||||
abstract getSetupStatus(): Promise<SetupStatus | null>
|
||||
|
||||
abstract followLogs(): Promise<string>
|
||||
|
||||
abstract setInterfaceClearnetAddress(
|
||||
params: RR.SetInterfaceClearnetAddressReq,
|
||||
): Promise<RR.SetInterfaceClearnetAddressRes>
|
||||
|
||||
@@ -117,10 +117,6 @@ export class LiveApiService extends ApiService {
|
||||
return this.openWebsocket(config)
|
||||
}
|
||||
|
||||
async followLogs(): Promise<string> {
|
||||
return this.rpcRequest({ method: 'setup.logs.follow', params: {} })
|
||||
}
|
||||
|
||||
openLogsWebsocket$(config: WebSocketSubjectConfig<Log>): Observable<Log> {
|
||||
return this.openWebsocket(config)
|
||||
}
|
||||
@@ -259,21 +255,33 @@ export class LiveApiService extends ApiService {
|
||||
return this.rpcRequest({ method: 'notification.list', params })
|
||||
}
|
||||
|
||||
async deleteNotification(
|
||||
async deleteNotifications(
|
||||
params: RR.DeleteNotificationReq,
|
||||
): Promise<RR.DeleteNotificationRes> {
|
||||
return this.rpcRequest({ method: 'notification.delete', params })
|
||||
}
|
||||
|
||||
async deleteAllNotifications(
|
||||
params: RR.DeleteAllNotificationsReq,
|
||||
): Promise<RR.DeleteAllNotificationsRes> {
|
||||
async markSeenNotifications(
|
||||
params: RR.MarkSeenNotificationReq,
|
||||
): Promise<RR.MarkSeenNotificationRes> {
|
||||
return this.rpcRequest({ method: 'notification.mark-seen', params })
|
||||
}
|
||||
|
||||
async markSeenAllNotifications(
|
||||
params: RR.MarkSeenAllNotificationsReq,
|
||||
): Promise<RR.MarkSeenAllNotificationsRes> {
|
||||
return this.rpcRequest({
|
||||
method: 'notification.delete-before',
|
||||
method: 'notification.mark-seen-before',
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
async markUnseenNotifications(
|
||||
params: RR.MarkUnseenNotificationReq,
|
||||
): Promise<RR.MarkUnseenNotificationRes> {
|
||||
return this.rpcRequest({ method: 'notification.mark-unseen', params })
|
||||
}
|
||||
|
||||
// network
|
||||
|
||||
async addProxy(params: RR.AddProxyReq): Promise<RR.AddProxyRes> {
|
||||
|
||||
@@ -473,28 +473,34 @@ export class MockApiService extends ApiService {
|
||||
params: RR.GetNotificationsReq,
|
||||
): Promise<RR.GetNotificationsRes> {
|
||||
await pauseFor(2000)
|
||||
const patch = [
|
||||
{
|
||||
op: PatchOp.REPLACE,
|
||||
path: '/server-info/unread-notification-count',
|
||||
value: 0,
|
||||
},
|
||||
]
|
||||
this.mockRevision(patch)
|
||||
|
||||
return Mock.Notifications
|
||||
}
|
||||
|
||||
async deleteNotification(
|
||||
async deleteNotifications(
|
||||
params: RR.DeleteNotificationReq,
|
||||
): Promise<RR.DeleteNotificationRes> {
|
||||
await pauseFor(2000)
|
||||
return null
|
||||
}
|
||||
|
||||
async deleteAllNotifications(
|
||||
params: RR.DeleteAllNotificationsReq,
|
||||
): Promise<RR.DeleteAllNotificationsRes> {
|
||||
async markSeenNotifications(
|
||||
params: RR.MarkSeenNotificationReq,
|
||||
): Promise<RR.MarkSeenNotificationRes> {
|
||||
await pauseFor(2000)
|
||||
return null
|
||||
}
|
||||
|
||||
async markSeenAllNotifications(
|
||||
params: RR.MarkSeenAllNotificationsReq,
|
||||
): Promise<RR.MarkSeenAllNotificationsRes> {
|
||||
await pauseFor(2000)
|
||||
return null
|
||||
}
|
||||
|
||||
async markUnseenNotifications(
|
||||
params: RR.MarkUnseenNotificationReq,
|
||||
): Promise<RR.MarkUnseenNotificationRes> {
|
||||
await pauseFor(2000)
|
||||
return null
|
||||
}
|
||||
@@ -1244,11 +1250,6 @@ export class MockApiService extends ApiService {
|
||||
return getSetupStatusMock()
|
||||
}
|
||||
|
||||
async followLogs(): Promise<string> {
|
||||
await pauseFor(1000)
|
||||
return 'fake-guid'
|
||||
}
|
||||
|
||||
async setInterfaceClearnetAddress(
|
||||
params: RR.SetInterfaceClearnetAddressReq,
|
||||
): Promise<RR.SetInterfaceClearnetAddressRes> {
|
||||
|
||||
@@ -88,7 +88,10 @@ export const mockPatchData: DataModel = {
|
||||
outboundProxy: null,
|
||||
},
|
||||
'last-backup': new Date(new Date().valueOf() - 604800001).toISOString(),
|
||||
'unread-notification-count': 4,
|
||||
unreadNotifications: {
|
||||
count: 4,
|
||||
recent: Mock.Notifications,
|
||||
},
|
||||
'eos-version-compat': '>=0.3.0 <=0.3.0.1',
|
||||
'status-info': {
|
||||
'current-backup': null,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { InputSpec } from '@start9labs/start-sdk/lib/config/configTypes'
|
||||
import { Url } from '@start9labs/shared'
|
||||
import { Manifest } from '@start9labs/marketplace'
|
||||
import { BackupJob } from '../api/api.types'
|
||||
import { BackupJob, ServerNotifications } from '../api/api.types'
|
||||
import { customSmtp } from '@start9labs/start-sdk/lib/config/configConstants'
|
||||
import { NetworkInterfaceType } from '@start9labs/start-sdk/lib/util/utils'
|
||||
import { DependencyInfo } from 'src/app/apps/portal/routes/service/types/dependency-info'
|
||||
@@ -61,7 +61,10 @@ export interface ServerInfo {
|
||||
ui: AddressInfo
|
||||
network: NetworkInfo
|
||||
'last-backup': string | null
|
||||
'unread-notification-count': number
|
||||
unreadNotifications: {
|
||||
count: number
|
||||
recent: ServerNotifications
|
||||
}
|
||||
'status-info': ServerStatusInfo
|
||||
'eos-version-compat': string
|
||||
pubkey: string
|
||||
|
||||
Reference in New Issue
Block a user