Skip to content
Open
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
109 changes: 62 additions & 47 deletions console/src/routes/channels-catalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,21 @@ function countKeys(value: Record<string, unknown>): number {
}

export function countDiscordGuilds(config: AdminConfig): number {
return countKeys(config.discord.guilds);
return countKeys(config.discord?.guilds ?? {});
}

export function countDiscordOverrides(config: AdminConfig): number {
return Object.values(config.discord.guilds).reduce((total, guild) => {
return Object.values(config.discord?.guilds ?? {}).reduce((total, guild) => {
return total + countKeys(guild.channels);
}, 0);
}

export function countTeams(config: AdminConfig): number {
return countKeys(config.msteams.teams);
return countKeys(config.msteams?.teams ?? {});
}

export function countTeamsOverrides(config: AdminConfig): number {
return Object.values(config.msteams.teams).reduce((total, team) => {
return Object.values(config.msteams?.teams ?? {}).reduce((total, team) => {
return total + countKeys(team.channels);
}, 0);
}
Expand All @@ -61,8 +61,9 @@ function describeDiscord(
): ChannelCatalogItem {
const guildCount = countDiscordGuilds(config);
const overrideCount = countDiscordOverrides(config);
const enabled =
config.discord.commandsOnly || config.discord.groupPolicy !== 'disabled';
const enabled = config.discord
? config.discord.commandsOnly || config.discord.groupPolicy !== 'disabled'
: false;
const tokenConfigured = options.discordTokenConfigured === true;
const active = enabled && tokenConfigured;
const configured =
Expand All @@ -76,7 +77,9 @@ function describeDiscord(
return {
kind: 'discord',
label: 'Discord',
summary: `${pluralize(guildCount, 'guild default')} · ${pluralize(overrideCount, 'explicit override')}`,
summary: config.discord
? `${pluralize(guildCount, 'guild default')} · ${pluralize(overrideCount, 'explicit override')}`
: 'Not configured',
statusTone,
statusLabel:
statusTone === 'active'
Expand All @@ -92,12 +95,13 @@ function describeWhatsApp(
options: ChannelCatalogOptions,
): ChannelCatalogItem {
const linked = options.whatsappLinked === true;
const enabled =
config.whatsapp.dmPolicy !== 'disabled' ||
config.whatsapp.groupPolicy !== 'disabled';
const enabled = config.whatsapp
? config.whatsapp.dmPolicy !== 'disabled' ||
config.whatsapp.groupPolicy !== 'disabled'
: false;
const summary = linked
? enabled
? `Linked device · groups ${config.whatsapp.groupPolicy}`
? `Linked device · groups ${config.whatsapp?.groupPolicy}`
: 'Linked device available but transport is off'
: enabled
? 'Link device to enable WhatsApp'
Expand All @@ -124,15 +128,16 @@ function describeTelegram(
): ChannelCatalogItem {
const tokenConfigured = options.telegramTokenConfigured === true;
const inboundEnabled =
config.telegram.dmPolicy !== 'disabled' ||
config.telegram.groupPolicy !== 'disabled';
const active = config.telegram.enabled && tokenConfigured && inboundEnabled;
config.telegram?.dmPolicy !== 'disabled' ||
config.telegram?.groupPolicy !== 'disabled';
const active =
(config.telegram?.enabled ?? false) && tokenConfigured && inboundEnabled;
const configured =
active ||
config.telegram.enabled ||
(config.telegram?.enabled ?? false) ||
tokenConfigured ||
config.telegram.allowFrom.length > 0 ||
config.telegram.groupAllowFrom.length > 0;
(config.telegram?.allowFrom?.length ?? 0) > 0 ||
(config.telegram?.groupAllowFrom?.length ?? 0) > 0;
const statusTone = active
? 'active'
: configured
Expand All @@ -142,7 +147,9 @@ function describeTelegram(
return {
kind: 'telegram',
label: 'Telegram',
summary: `DM ${config.telegram.dmPolicy} · groups ${config.telegram.groupPolicy}`,
summary: config.telegram
? `DM ${config.telegram.dmPolicy} · groups ${config.telegram.groupPolicy}`
: 'Not configured',
statusTone,
statusLabel:
statusTone === 'active'
Expand All @@ -160,14 +167,16 @@ function describeSlack(
const botTokenConfigured = options.slackBotTokenConfigured === true;
const appTokenConfigured = options.slackAppTokenConfigured === true;
const active =
config.slack.enabled && botTokenConfigured && appTokenConfigured;
(config.slack?.enabled ?? false) &&
botTokenConfigured &&
appTokenConfigured;
const configured =
active ||
config.slack.enabled ||
(config.slack?.enabled ?? false) ||
botTokenConfigured ||
appTokenConfigured ||
config.slack.allowFrom.length > 0 ||
config.slack.groupAllowFrom.length > 0;
(config.slack?.allowFrom?.length ?? 0) > 0 ||
(config.slack?.groupAllowFrom?.length ?? 0) > 0;
const statusTone = active
? 'active'
: configured
Expand All @@ -177,7 +186,9 @@ function describeSlack(
return {
kind: 'slack',
label: 'Slack',
summary: `DM ${config.slack.dmPolicy} · channels ${config.slack.groupPolicy}`,
summary: config.slack
? `DM ${config.slack.dmPolicy} · channels ${config.slack.groupPolicy}`
: 'Not configured',
statusTone,
statusLabel:
statusTone === 'active'
Expand All @@ -194,17 +205,17 @@ function describeEmail(
): ChannelCatalogItem {
const passwordConfigured = options.emailPasswordConfigured === true;
const active =
config.email.enabled &&
(config.email?.enabled ?? false) &&
passwordConfigured &&
!!config.email.address &&
!!config.email.imapHost &&
!!config.email.smtpHost;
!!config.email?.address &&
!!config.email?.imapHost &&
!!config.email?.smtpHost;
const configured =
active ||
!!config.email.address ||
!!config.email.imapHost ||
!!config.email.smtpHost ||
config.email.allowFrom.length > 0;
!!config.email?.address ||
!!config.email?.imapHost ||
!!config.email?.smtpHost ||
(config.email?.allowFrom?.length ?? 0) > 0;
const statusTone = active
? 'active'
: configured
Expand All @@ -214,7 +225,7 @@ function describeEmail(
return {
kind: 'email',
label: 'Email',
summary: config.email.address || 'No mailbox address configured yet',
summary: config.email?.address || 'No mailbox address configured yet',
statusTone,
statusLabel:
statusTone === 'active'
Expand All @@ -229,14 +240,14 @@ function describeMSTeams(config: AdminConfig): ChannelCatalogItem {
const teamCount = countTeams(config);
const overrideCount = countTeamsOverrides(config);
const active =
config.msteams.enabled &&
!!config.msteams.appId &&
!!config.msteams.tenantId;
(config.msteams?.enabled ?? false) &&
!!config.msteams?.appId &&
!!config.msteams?.tenantId;
const configured =
active ||
config.msteams.enabled ||
!!config.msteams.appId ||
!!config.msteams.tenantId ||
(config.msteams?.enabled ?? false) ||
!!config.msteams?.appId ||
!!config.msteams?.tenantId ||
teamCount > 0 ||
overrideCount > 0;
const statusTone = active
Expand All @@ -248,7 +259,9 @@ function describeMSTeams(config: AdminConfig): ChannelCatalogItem {
return {
kind: 'msteams',
label: 'Microsoft Teams',
summary: `${pluralize(teamCount, 'team default')} · ${pluralize(overrideCount, 'channel override')}`,
summary: config.msteams
? `${pluralize(teamCount, 'team default')} · ${pluralize(overrideCount, 'channel override')}`
: 'Not configured',
statusTone,
statusLabel:
statusTone === 'active'
Expand All @@ -263,22 +276,24 @@ function describeIMessage(
config: AdminConfig,
options: ChannelCatalogOptions,
): ChannelCatalogItem {
const isRemote = config.imessage.backend === 'bluebubbles';
const isRemote = config.imessage?.backend === 'bluebubbles';
const passwordConfigured = options.imessagePasswordConfigured === true;
const active = isRemote
? config.imessage.enabled &&
? (config.imessage?.enabled ?? false) &&
passwordConfigured &&
!!config.imessage.serverUrl &&
!!config.imessage.webhookPath
: config.imessage.enabled &&
!!config.imessage.cliPath &&
!!config.imessage.dbPath;
!!config.imessage?.serverUrl &&
!!config.imessage?.webhookPath
: (config.imessage?.enabled ?? false) &&
!!config.imessage?.cliPath &&
!!config.imessage?.dbPath;
const statusTone = active ? 'active' : 'available';

return {
kind: 'imessage',
label: 'iMessage',
summary: `${isRemote ? 'Remote' : 'Local'} backend · DM ${config.imessage.dmPolicy}`,
summary: config.imessage
? `${isRemote ? 'Remote' : 'Local'} backend · DM ${config.imessage.dmPolicy}`
: 'Not configured',
statusTone,
statusLabel: statusTone === 'active' ? 'active' : 'available',
};
Expand Down
9 changes: 9 additions & 0 deletions console/src/routes/jobs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,14 @@ export function JobsPage() {
</p>
) : null}

{allItems.length === 0 ? (
<div className="page-empty">
<p>Jobs are async tasks created by the agent or triggered manually.</p>
<a className="primary-button" href="/admin/scheduler">
New Job
</a>
</div>
) : (
<section
className={
selectedItem ? 'jobs-board-layout has-detail' : 'jobs-board-layout'
Expand Down Expand Up @@ -862,6 +870,7 @@ export function JobsPage() {
/>
) : null}
</section>
)}
</div>
);
}
Loading
Loading