Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 29 additions & 7 deletions src/app/configure-tasks-app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import { AutoArchiveSection } from '@/app/configure-tasks-app/ui/AutoArchiveSect
import { ClientViewSettingsSection } from '@/app/configure-tasks-app/ui/ClientViewSettingsSection'
import { StatusCustomizationSection } from '@/app/configure-tasks-app/ui/StatusCustomizationSection'
import { ClientViewSettings } from '@/types/dto/workspaceSettings.dto'
import { SilentError } from '@/components/templates/SilentError'
import { Stack } from '@mui/material'
import { z } from 'zod'

async function getAllWorkflowStates(token: string): Promise<WorkflowStateResponse[]> {
const res = await fetch(`${apiUrl}/api/workflow-states?token=${token}`, {
Expand Down Expand Up @@ -58,6 +60,23 @@ async function getWorkspaceSetting(token: string): Promise<{ autoArchiveAfterDay
return await res.json()
}

async function loadConfigureTasksAppPageData(token: string) {
try {
const [workflowStates, assignee, templates, tokenPayload, workspaceSetting] = await Promise.all([
getAllWorkflowStates(token),
addTypeToAssignee(await getAssigneeList(token)),
getAllTemplates(token),
getTokenPayload(token),
getWorkspaceSetting(token),
])

return { workflowStates, assignee, templates, tokenPayload, workspaceSetting }
} catch (error) {
console.warn('configure-tasks-app: failed to load configuration', error)
return null
}
}

interface ConfigureTasksAppPageProps {
searchParams: Promise<{
token: string
Expand All @@ -67,13 +86,16 @@ interface ConfigureTasksAppPageProps {
export default async function ConfigureTasksAppPage(props: ConfigureTasksAppPageProps) {
const searchParams = await props.searchParams
const { token } = searchParams
const [workflowStates, assignee, templates, tokenPayload, workspaceSetting] = await Promise.all([
getAllWorkflowStates(token),
addTypeToAssignee(await getAssigneeList(token)),
getAllTemplates(token),
getTokenPayload(token),
getWorkspaceSetting(token),
])
if (!z.string().safeParse(token).success) {
return <SilentError message="Please provide a Valid Token" />
}

const pageData = await loadConfigureTasksAppPageData(token)
if (!pageData) {
return <SilentError message="Tasks app configuration is unavailable for this workspace" />
}

const { workflowStates, assignee, templates, tokenPayload, workspaceSetting } = pageData

return (
<ClientSideStateUpdate
Expand Down
23 changes: 17 additions & 6 deletions src/app/notification-center/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ async function getNotificationDetail(token: string) {
const copilot = new CopilotAPI(token)
const tokenPayload = await copilot.getTokenPayload()

if (!tokenPayload) throw new Error('Failed to get token payload')
if (!tokenPayload?.notificationId) return null

return await copilot.getIUNotification(z.string().parse(tokenPayload.notificationId), tokenPayload.workspaceId) // notification "id" is expected in tokenPayload
return await copilot.getIUNotification(tokenPayload.notificationId, tokenPayload.workspaceId)
}

export default async function NotificationCenter(props: { searchParams: Promise<{ token: string }> }) {
Expand All @@ -21,13 +21,24 @@ export default async function NotificationCenter(props: { searchParams: Promise<
return <SilentError message="Please provide a Valid Token" />
}

const notificationDetail = await getNotificationDetail(token)
let notificationDetail
try {
notificationDetail = await getNotificationDetail(token)
} catch (error) {
console.warn('notification-center: failed to load notification', error)
return <SilentError message="This notification could not be opened in Tasks" />
}

if (!notificationDetail) return <SilentError message="Failed to get notification detail" />

const params = NotificationInProductCtaParamsSchema.parse(notificationDetail.deliveryTargets?.inProduct?.ctaParams)
const params = NotificationInProductCtaParamsSchema.safeParse(
notificationDetail.deliveryTargets?.inProduct?.ctaParams,
)
if (!params.success) {
return <SilentError message="This notification is not linked to a task" />
}

redirectIfTaskCta({ ...params, ...searchParams }, UserType.INTERNAL_USER, true)
redirectIfTaskCta({ ...params.data, ...searchParams }, UserType.INTERNAL_USER, true)

// Silent Error is shown if redirect fails. Only possible reason for redirect to not work can be of the taskId not found
return <SilentError message="TaskId is not found" />
}
20 changes: 17 additions & 3 deletions src/utils/CopilotAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,15 +361,29 @@ export class CopilotAPI {
async _getNotificationSettings(): Promise<NotificationSettingsResponse> {
console.info('CopilotAPI#_getNotificationSettings')
const appId = z.string({ message: 'Missing AppID in environment' }).parse(APP_ID)
const installs = await this.copilot.listAppInstalls()

let installs
try {
installs = await this.copilot.listAppInstalls()
} catch (error) {
console.warn('CopilotAPI#_getNotificationSettings | Failed to list app installs', error)
return { notifications: [] }
}

const install = installs.find((entry) => entry.appId === appId)
if (!install?.id) {
console.info('CopilotAPI#_getNotificationSettings | No matching app install in workspace; no settings')
return { notifications: [] }
}
const workspaceId = await this._resolveWorkspaceId()
const response = await this._manualFetch(`installs/${install.id}/notification-settings`, undefined, workspaceId)
return NotificationSettingsResponseSchema.parse(response)

try {
const response = await this._manualFetch(`installs/${install.id}/notification-settings`, undefined, workspaceId)
return NotificationSettingsResponseSchema.parse(response)
} catch (error) {
console.warn('CopilotAPI#_getNotificationSettings | Failed to fetch notification settings', error)
return { notifications: [] }
}
}

// A single IU's live per-category notification preferences. Never cached — the platform evaluates
Expand Down
Loading