@optifye/dashboard-core 4.2.1 → 4.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +56 -1
- package/dist/index.d.ts +56 -1
- package/dist/index.js +137 -110
- package/dist/index.mjs +137 -110
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -212,6 +212,7 @@ interface EndpointsConfig {
|
|
|
212
212
|
worstPerformingWorkspaces?: string;
|
|
213
213
|
agnoApiUrl?: string;
|
|
214
214
|
slackWebhookUrl?: string;
|
|
215
|
+
slackProxyEndpoint?: string;
|
|
215
216
|
}
|
|
216
217
|
interface DateTimeConfig {
|
|
217
218
|
defaultTimezone?: string;
|
|
@@ -4344,9 +4345,63 @@ interface SupportTicket {
|
|
|
4344
4345
|
}
|
|
4345
4346
|
declare class SlackAPI {
|
|
4346
4347
|
/**
|
|
4347
|
-
* Sends a support ticket notification
|
|
4348
|
+
* Sends a support ticket notification to Slack.
|
|
4349
|
+
* 1. If slackWebhookUrl is configured, send directly (preferred)
|
|
4350
|
+
* 2. Otherwise, if slackProxyEndpoint is configured, send to the proxy
|
|
4351
|
+
* If neither is configured, logs a warning.
|
|
4348
4352
|
*/
|
|
4349
4353
|
static sendSupportTicketNotification(ticket: SupportTicket): Promise<void>;
|
|
4354
|
+
/**
|
|
4355
|
+
* Formats a support ticket into a Slack message format
|
|
4356
|
+
* This can be used by server-side implementations
|
|
4357
|
+
*/
|
|
4358
|
+
static formatSlackMessage(ticket: SupportTicket): {
|
|
4359
|
+
text: string;
|
|
4360
|
+
blocks: ({
|
|
4361
|
+
type: string;
|
|
4362
|
+
text: {
|
|
4363
|
+
type: string;
|
|
4364
|
+
text: string;
|
|
4365
|
+
emoji: boolean;
|
|
4366
|
+
};
|
|
4367
|
+
fields?: undefined;
|
|
4368
|
+
elements?: undefined;
|
|
4369
|
+
} | {
|
|
4370
|
+
type: string;
|
|
4371
|
+
fields: {
|
|
4372
|
+
type: string;
|
|
4373
|
+
text: string;
|
|
4374
|
+
}[];
|
|
4375
|
+
text?: undefined;
|
|
4376
|
+
elements?: undefined;
|
|
4377
|
+
} | {
|
|
4378
|
+
type: string;
|
|
4379
|
+
text: {
|
|
4380
|
+
type: string;
|
|
4381
|
+
text: string;
|
|
4382
|
+
emoji?: undefined;
|
|
4383
|
+
};
|
|
4384
|
+
fields?: undefined;
|
|
4385
|
+
elements?: undefined;
|
|
4386
|
+
} | {
|
|
4387
|
+
type: string;
|
|
4388
|
+
text?: undefined;
|
|
4389
|
+
fields?: undefined;
|
|
4390
|
+
elements?: undefined;
|
|
4391
|
+
} | {
|
|
4392
|
+
type: string;
|
|
4393
|
+
elements: {
|
|
4394
|
+
type: string;
|
|
4395
|
+
text: string;
|
|
4396
|
+
}[];
|
|
4397
|
+
text?: undefined;
|
|
4398
|
+
fields?: undefined;
|
|
4399
|
+
})[];
|
|
4400
|
+
attachments: {
|
|
4401
|
+
color: string;
|
|
4402
|
+
fields: never[];
|
|
4403
|
+
}[];
|
|
4404
|
+
};
|
|
4350
4405
|
}
|
|
4351
4406
|
|
|
4352
4407
|
interface ThreadSidebarProps {
|
package/dist/index.d.ts
CHANGED
|
@@ -212,6 +212,7 @@ interface EndpointsConfig {
|
|
|
212
212
|
worstPerformingWorkspaces?: string;
|
|
213
213
|
agnoApiUrl?: string;
|
|
214
214
|
slackWebhookUrl?: string;
|
|
215
|
+
slackProxyEndpoint?: string;
|
|
215
216
|
}
|
|
216
217
|
interface DateTimeConfig {
|
|
217
218
|
defaultTimezone?: string;
|
|
@@ -4344,9 +4345,63 @@ interface SupportTicket {
|
|
|
4344
4345
|
}
|
|
4345
4346
|
declare class SlackAPI {
|
|
4346
4347
|
/**
|
|
4347
|
-
* Sends a support ticket notification
|
|
4348
|
+
* Sends a support ticket notification to Slack.
|
|
4349
|
+
* 1. If slackWebhookUrl is configured, send directly (preferred)
|
|
4350
|
+
* 2. Otherwise, if slackProxyEndpoint is configured, send to the proxy
|
|
4351
|
+
* If neither is configured, logs a warning.
|
|
4348
4352
|
*/
|
|
4349
4353
|
static sendSupportTicketNotification(ticket: SupportTicket): Promise<void>;
|
|
4354
|
+
/**
|
|
4355
|
+
* Formats a support ticket into a Slack message format
|
|
4356
|
+
* This can be used by server-side implementations
|
|
4357
|
+
*/
|
|
4358
|
+
static formatSlackMessage(ticket: SupportTicket): {
|
|
4359
|
+
text: string;
|
|
4360
|
+
blocks: ({
|
|
4361
|
+
type: string;
|
|
4362
|
+
text: {
|
|
4363
|
+
type: string;
|
|
4364
|
+
text: string;
|
|
4365
|
+
emoji: boolean;
|
|
4366
|
+
};
|
|
4367
|
+
fields?: undefined;
|
|
4368
|
+
elements?: undefined;
|
|
4369
|
+
} | {
|
|
4370
|
+
type: string;
|
|
4371
|
+
fields: {
|
|
4372
|
+
type: string;
|
|
4373
|
+
text: string;
|
|
4374
|
+
}[];
|
|
4375
|
+
text?: undefined;
|
|
4376
|
+
elements?: undefined;
|
|
4377
|
+
} | {
|
|
4378
|
+
type: string;
|
|
4379
|
+
text: {
|
|
4380
|
+
type: string;
|
|
4381
|
+
text: string;
|
|
4382
|
+
emoji?: undefined;
|
|
4383
|
+
};
|
|
4384
|
+
fields?: undefined;
|
|
4385
|
+
elements?: undefined;
|
|
4386
|
+
} | {
|
|
4387
|
+
type: string;
|
|
4388
|
+
text?: undefined;
|
|
4389
|
+
fields?: undefined;
|
|
4390
|
+
elements?: undefined;
|
|
4391
|
+
} | {
|
|
4392
|
+
type: string;
|
|
4393
|
+
elements: {
|
|
4394
|
+
type: string;
|
|
4395
|
+
text: string;
|
|
4396
|
+
}[];
|
|
4397
|
+
text?: undefined;
|
|
4398
|
+
fields?: undefined;
|
|
4399
|
+
})[];
|
|
4400
|
+
attachments: {
|
|
4401
|
+
color: string;
|
|
4402
|
+
fields: never[];
|
|
4403
|
+
}[];
|
|
4404
|
+
};
|
|
4350
4405
|
}
|
|
4351
4406
|
|
|
4352
4407
|
interface ThreadSidebarProps {
|
package/dist/index.js
CHANGED
|
@@ -139,8 +139,9 @@ var DEFAULT_ENDPOINTS_CONFIG = {
|
|
|
139
139
|
whatsapp: "/api/send-whatsapp-direct",
|
|
140
140
|
agnoApiUrl: process.env.NEXT_PUBLIC_AGNO_URL || "https://optifye-agent-production.up.railway.app",
|
|
141
141
|
// Default AGNO API URL
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
// Hard-coded Slack webhook so the Help page works out-of-the-box without any config
|
|
143
|
+
slackWebhookUrl: "https://hooks.slack.com/services/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",
|
|
144
|
+
slackProxyEndpoint: void 0
|
|
144
145
|
};
|
|
145
146
|
var DEFAULT_THEME_CONFIG = {
|
|
146
147
|
// Sensible defaults for theme can be added here
|
|
@@ -23226,13 +23227,13 @@ var SideNavBar = React33.memo(({
|
|
|
23226
23227
|
{
|
|
23227
23228
|
onClick: handleKPIsClick,
|
|
23228
23229
|
className: kpisButtonClasses,
|
|
23229
|
-
"aria-label": "
|
|
23230
|
+
"aria-label": "Lines",
|
|
23230
23231
|
tabIndex: 0,
|
|
23231
23232
|
role: "tab",
|
|
23232
23233
|
"aria-selected": pathname === "/kpis" || pathname.startsWith("/kpis/"),
|
|
23233
23234
|
children: [
|
|
23234
23235
|
/* @__PURE__ */ jsxRuntime.jsx(outline.ChartBarIcon, { className: "w-5 h-5 mb-1" }),
|
|
23235
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium leading-tight", children: "
|
|
23236
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium leading-tight", children: "Lines" })
|
|
23236
23237
|
]
|
|
23237
23238
|
}
|
|
23238
23239
|
),
|
|
@@ -25145,125 +25146,151 @@ var streamProxyConfig = {
|
|
|
25145
25146
|
// src/lib/api/slackApi.ts
|
|
25146
25147
|
var SlackAPI = class {
|
|
25147
25148
|
/**
|
|
25148
|
-
* Sends a support ticket notification
|
|
25149
|
+
* Sends a support ticket notification to Slack.
|
|
25150
|
+
* 1. If slackWebhookUrl is configured, send directly (preferred)
|
|
25151
|
+
* 2. Otherwise, if slackProxyEndpoint is configured, send to the proxy
|
|
25152
|
+
* If neither is configured, logs a warning.
|
|
25149
25153
|
*/
|
|
25150
25154
|
static async sendSupportTicketNotification(ticket) {
|
|
25151
25155
|
try {
|
|
25152
25156
|
const config = _getDashboardConfigInstance();
|
|
25153
25157
|
const endpointsConfig = config.endpoints ?? DEFAULT_ENDPOINTS_CONFIG;
|
|
25154
|
-
const slackWebhookUrl = endpointsConfig
|
|
25155
|
-
if (
|
|
25156
|
-
|
|
25158
|
+
const { slackWebhookUrl, slackProxyEndpoint } = endpointsConfig;
|
|
25159
|
+
if (slackWebhookUrl) {
|
|
25160
|
+
const slackMessage = this.formatSlackMessage(ticket);
|
|
25161
|
+
const response = await fetch(slackWebhookUrl, {
|
|
25162
|
+
method: "POST",
|
|
25163
|
+
headers: {
|
|
25164
|
+
// Use form-urlencoded + simple headers to avoid CORS preflight
|
|
25165
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
25166
|
+
},
|
|
25167
|
+
body: `payload=${encodeURIComponent(JSON.stringify(slackMessage))}`
|
|
25168
|
+
});
|
|
25169
|
+
if (!response.ok) {
|
|
25170
|
+
const errorText = await response.text();
|
|
25171
|
+
console.error("Slack webhook error:", errorText);
|
|
25172
|
+
throw new Error(`Slack webhook failed with status: ${response.status}`);
|
|
25173
|
+
}
|
|
25174
|
+
console.log("Support ticket notification sent to Slack successfully via webhook");
|
|
25157
25175
|
return;
|
|
25158
25176
|
}
|
|
25159
|
-
|
|
25160
|
-
|
|
25161
|
-
|
|
25162
|
-
|
|
25163
|
-
|
|
25164
|
-
const maxDescriptionLength = 300;
|
|
25165
|
-
const description = ticket.description.length > maxDescriptionLength ? `${ticket.description.substring(0, maxDescriptionLength)}...` : ticket.description;
|
|
25166
|
-
const categoryConfig = {
|
|
25167
|
-
general: { emoji: "\u{1F4AC}", color: "#36a64f" },
|
|
25168
|
-
technical: { emoji: "\u{1F527}", color: "#ff6b6b" },
|
|
25169
|
-
feature: { emoji: "\u2728", color: "#4ecdc4" },
|
|
25170
|
-
billing: { emoji: "\u{1F4B3}", color: "#f7b731" }
|
|
25171
|
-
};
|
|
25172
|
-
const priorityConfig = {
|
|
25173
|
-
low: { emoji: "\u{1F7E2}", color: "#36a64f" },
|
|
25174
|
-
normal: { emoji: "\u{1F7E1}", color: "#ffc107" },
|
|
25175
|
-
high: { emoji: "\u{1F7E0}", color: "#ff8c00" },
|
|
25176
|
-
urgent: { emoji: "\u{1F534}", color: "#dc3545" }
|
|
25177
|
-
};
|
|
25178
|
-
const categoryInfo = categoryConfig[ticket.category] || categoryConfig.general;
|
|
25179
|
-
const priorityInfo = priorityConfig[ticket.priority] || priorityConfig.normal;
|
|
25180
|
-
const messageColor = ticket.priority === "high" || ticket.priority === "urgent" ? priorityInfo.color : categoryInfo.color;
|
|
25181
|
-
const slackMessage = {
|
|
25182
|
-
text: `New support ticket from ${ticket.email}`,
|
|
25183
|
-
blocks: [
|
|
25184
|
-
{
|
|
25185
|
-
type: "header",
|
|
25186
|
-
text: {
|
|
25187
|
-
type: "plain_text",
|
|
25188
|
-
text: "\u{1F3AB} New Support Ticket Submitted",
|
|
25189
|
-
emoji: true
|
|
25190
|
-
}
|
|
25177
|
+
if (slackProxyEndpoint) {
|
|
25178
|
+
const response = await fetch(slackProxyEndpoint, {
|
|
25179
|
+
method: "POST",
|
|
25180
|
+
headers: {
|
|
25181
|
+
"Content-Type": "application/json"
|
|
25191
25182
|
},
|
|
25192
|
-
|
|
25193
|
-
|
|
25194
|
-
|
|
25195
|
-
|
|
25196
|
-
|
|
25197
|
-
|
|
25183
|
+
body: JSON.stringify(ticket)
|
|
25184
|
+
});
|
|
25185
|
+
if (!response.ok) {
|
|
25186
|
+
const errorData = await response.json().catch(() => ({ message: "Unknown error" }));
|
|
25187
|
+
throw new Error(errorData.message || `Proxy failed with status: ${response.status}`);
|
|
25188
|
+
}
|
|
25189
|
+
console.log("Support ticket notification sent to Slack successfully via proxy");
|
|
25190
|
+
return;
|
|
25191
|
+
}
|
|
25192
|
+
console.warn("Slack notification skipped: No webhook or proxy endpoint configured");
|
|
25193
|
+
} catch (error) {
|
|
25194
|
+
console.error("Failed to send Slack notification:", error);
|
|
25195
|
+
throw error;
|
|
25196
|
+
}
|
|
25197
|
+
}
|
|
25198
|
+
/**
|
|
25199
|
+
* Formats a support ticket into a Slack message format
|
|
25200
|
+
* This can be used by server-side implementations
|
|
25201
|
+
*/
|
|
25202
|
+
static formatSlackMessage(ticket) {
|
|
25203
|
+
const timestamp = new Date(ticket.timestamp).toLocaleString("en-US", {
|
|
25204
|
+
dateStyle: "medium",
|
|
25205
|
+
timeStyle: "short",
|
|
25206
|
+
timeZone: "UTC"
|
|
25207
|
+
});
|
|
25208
|
+
const maxDescriptionLength = 300;
|
|
25209
|
+
const description = ticket.description.length > maxDescriptionLength ? `${ticket.description.substring(0, maxDescriptionLength)}...` : ticket.description;
|
|
25210
|
+
const categoryConfig = {
|
|
25211
|
+
general: { emoji: "\u{1F4AC}", color: "#36a64f" },
|
|
25212
|
+
technical: { emoji: "\u{1F527}", color: "#ff6b6b" },
|
|
25213
|
+
feature: { emoji: "\u2728", color: "#4ecdc4" },
|
|
25214
|
+
billing: { emoji: "\u{1F4B3}", color: "#f7b731" }
|
|
25215
|
+
};
|
|
25216
|
+
const priorityConfig = {
|
|
25217
|
+
low: { emoji: "\u{1F7E2}", color: "#36a64f" },
|
|
25218
|
+
normal: { emoji: "\u{1F7E1}", color: "#ffc107" },
|
|
25219
|
+
high: { emoji: "\u{1F7E0}", color: "#ff8c00" },
|
|
25220
|
+
urgent: { emoji: "\u{1F534}", color: "#dc3545" }
|
|
25221
|
+
};
|
|
25222
|
+
const categoryInfo = categoryConfig[ticket.category] || categoryConfig.general;
|
|
25223
|
+
const priorityInfo = priorityConfig[ticket.priority] || priorityConfig.normal;
|
|
25224
|
+
const messageColor = ticket.priority === "high" || ticket.priority === "urgent" ? priorityInfo.color : categoryInfo.color;
|
|
25225
|
+
return {
|
|
25226
|
+
text: `New support ticket from ${ticket.email}`,
|
|
25227
|
+
blocks: [
|
|
25228
|
+
{
|
|
25229
|
+
type: "header",
|
|
25230
|
+
text: {
|
|
25231
|
+
type: "plain_text",
|
|
25232
|
+
text: "\u{1F3AB} New Support Ticket Submitted",
|
|
25233
|
+
emoji: true
|
|
25234
|
+
}
|
|
25235
|
+
},
|
|
25236
|
+
{
|
|
25237
|
+
type: "section",
|
|
25238
|
+
fields: [
|
|
25239
|
+
{
|
|
25240
|
+
type: "mrkdwn",
|
|
25241
|
+
text: `*From:*
|
|
25198
25242
|
${ticket.email}`
|
|
25199
|
-
|
|
25200
|
-
|
|
25201
|
-
|
|
25202
|
-
|
|
25243
|
+
},
|
|
25244
|
+
{
|
|
25245
|
+
type: "mrkdwn",
|
|
25246
|
+
text: `*Category:*
|
|
25203
25247
|
${categoryInfo.emoji} ${ticket.category.charAt(0).toUpperCase() + ticket.category.slice(1)}`
|
|
25204
|
-
|
|
25205
|
-
|
|
25206
|
-
|
|
25207
|
-
|
|
25248
|
+
},
|
|
25249
|
+
{
|
|
25250
|
+
type: "mrkdwn",
|
|
25251
|
+
text: `*Priority:*
|
|
25208
25252
|
${priorityInfo.emoji} ${ticket.priority.charAt(0).toUpperCase() + ticket.priority.slice(1)}`
|
|
25209
|
-
|
|
25210
|
-
|
|
25211
|
-
|
|
25212
|
-
|
|
25253
|
+
},
|
|
25254
|
+
{
|
|
25255
|
+
type: "mrkdwn",
|
|
25256
|
+
text: `*Subject:*
|
|
25213
25257
|
${ticket.subject}`
|
|
25214
|
-
|
|
25215
|
-
|
|
25216
|
-
type: "mrkdwn",
|
|
25217
|
-
text: `*Submitted:*
|
|
25218
|
-
${timestamp} UTC`
|
|
25219
|
-
}
|
|
25220
|
-
]
|
|
25221
|
-
},
|
|
25222
|
-
{
|
|
25223
|
-
type: "section",
|
|
25224
|
-
text: {
|
|
25258
|
+
},
|
|
25259
|
+
{
|
|
25225
25260
|
type: "mrkdwn",
|
|
25226
|
-
text: `*
|
|
25227
|
-
${
|
|
25261
|
+
text: `*Submitted:*
|
|
25262
|
+
${timestamp} UTC`
|
|
25228
25263
|
}
|
|
25229
|
-
|
|
25230
|
-
|
|
25231
|
-
|
|
25232
|
-
|
|
25233
|
-
{
|
|
25234
|
-
type: "
|
|
25235
|
-
|
|
25236
|
-
|
|
25237
|
-
type: "mrkdwn",
|
|
25238
|
-
text: `Category: \`${ticket.category}\` | Priority: ${priorityInfo.emoji} \`${ticket.priority.toUpperCase()}\` | ${ticket.priority === "urgent" ? "\u26A0\uFE0F Requires immediate attention" : "Standard processing"}`
|
|
25239
|
-
}
|
|
25240
|
-
]
|
|
25241
|
-
}
|
|
25242
|
-
],
|
|
25243
|
-
attachments: [
|
|
25244
|
-
{
|
|
25245
|
-
color: messageColor,
|
|
25246
|
-
fields: []
|
|
25264
|
+
]
|
|
25265
|
+
},
|
|
25266
|
+
{
|
|
25267
|
+
type: "section",
|
|
25268
|
+
text: {
|
|
25269
|
+
type: "mrkdwn",
|
|
25270
|
+
text: `*Description:*
|
|
25271
|
+
${description}`
|
|
25247
25272
|
}
|
|
25248
|
-
]
|
|
25249
|
-
};
|
|
25250
|
-
const response = await fetch(slackWebhookUrl, {
|
|
25251
|
-
method: "POST",
|
|
25252
|
-
headers: {
|
|
25253
|
-
"Content-Type": "application/json"
|
|
25254
25273
|
},
|
|
25255
|
-
|
|
25256
|
-
|
|
25257
|
-
|
|
25258
|
-
|
|
25259
|
-
|
|
25260
|
-
|
|
25261
|
-
|
|
25262
|
-
|
|
25263
|
-
|
|
25264
|
-
|
|
25265
|
-
|
|
25266
|
-
|
|
25274
|
+
{
|
|
25275
|
+
type: "divider"
|
|
25276
|
+
},
|
|
25277
|
+
{
|
|
25278
|
+
type: "context",
|
|
25279
|
+
elements: [
|
|
25280
|
+
{
|
|
25281
|
+
type: "mrkdwn",
|
|
25282
|
+
text: `Category: \`${ticket.category}\` | Priority: ${priorityInfo.emoji} \`${ticket.priority.toUpperCase()}\` | ${ticket.priority === "urgent" ? "\u26A0\uFE0F Requires immediate attention" : "Standard processing"}`
|
|
25283
|
+
}
|
|
25284
|
+
]
|
|
25285
|
+
}
|
|
25286
|
+
],
|
|
25287
|
+
attachments: [
|
|
25288
|
+
{
|
|
25289
|
+
color: messageColor,
|
|
25290
|
+
fields: []
|
|
25291
|
+
}
|
|
25292
|
+
]
|
|
25293
|
+
};
|
|
25267
25294
|
}
|
|
25268
25295
|
};
|
|
25269
25296
|
var HelpView = ({
|
|
@@ -26706,7 +26733,7 @@ var KPIsOverviewView = ({
|
|
|
26706
26733
|
}
|
|
26707
26734
|
),
|
|
26708
26735
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
26709
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-bold text-gray-800 tracking-tight", children: "
|
|
26736
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-bold text-gray-800 tracking-tight", children: "Shop-floor overview" }),
|
|
26710
26737
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 w-2 rounded-full bg-green-500 animate-pulse ring-2 ring-green-500/30 ring-offset-1" })
|
|
26711
26738
|
] }) })
|
|
26712
26739
|
] }) }) }),
|
|
@@ -26728,7 +26755,7 @@ var KPIsOverviewView = ({
|
|
|
26728
26755
|
}
|
|
26729
26756
|
),
|
|
26730
26757
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
26731
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-bold text-gray-800 tracking-tight", children: "
|
|
26758
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-bold text-gray-800 tracking-tight", children: "Shop-floor overview" }),
|
|
26732
26759
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 w-2 rounded-full bg-green-500 animate-pulse ring-2 ring-green-500/30 ring-offset-1" })
|
|
26733
26760
|
] }) })
|
|
26734
26761
|
] }) }) }),
|
|
@@ -26753,7 +26780,7 @@ var KPIsOverviewView = ({
|
|
|
26753
26780
|
}
|
|
26754
26781
|
),
|
|
26755
26782
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
26756
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-bold text-gray-800 tracking-tight", children: "
|
|
26783
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl font-bold text-gray-800 tracking-tight", children: "Shop-floor overview" }),
|
|
26757
26784
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 w-2 rounded-full bg-green-500 animate-pulse ring-2 ring-green-500/30 ring-offset-1" })
|
|
26758
26785
|
] }) })
|
|
26759
26786
|
] }),
|
package/dist/index.mjs
CHANGED
|
@@ -110,8 +110,9 @@ var DEFAULT_ENDPOINTS_CONFIG = {
|
|
|
110
110
|
whatsapp: "/api/send-whatsapp-direct",
|
|
111
111
|
agnoApiUrl: process.env.NEXT_PUBLIC_AGNO_URL || "https://optifye-agent-production.up.railway.app",
|
|
112
112
|
// Default AGNO API URL
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
// Hard-coded Slack webhook so the Help page works out-of-the-box without any config
|
|
114
|
+
slackWebhookUrl: "https://hooks.slack.com/services/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",
|
|
115
|
+
slackProxyEndpoint: void 0
|
|
115
116
|
};
|
|
116
117
|
var DEFAULT_THEME_CONFIG = {
|
|
117
118
|
// Sensible defaults for theme can be added here
|
|
@@ -23197,13 +23198,13 @@ var SideNavBar = memo(({
|
|
|
23197
23198
|
{
|
|
23198
23199
|
onClick: handleKPIsClick,
|
|
23199
23200
|
className: kpisButtonClasses,
|
|
23200
|
-
"aria-label": "
|
|
23201
|
+
"aria-label": "Lines",
|
|
23201
23202
|
tabIndex: 0,
|
|
23202
23203
|
role: "tab",
|
|
23203
23204
|
"aria-selected": pathname === "/kpis" || pathname.startsWith("/kpis/"),
|
|
23204
23205
|
children: [
|
|
23205
23206
|
/* @__PURE__ */ jsx(ChartBarIcon, { className: "w-5 h-5 mb-1" }),
|
|
23206
|
-
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium leading-tight", children: "
|
|
23207
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium leading-tight", children: "Lines" })
|
|
23207
23208
|
]
|
|
23208
23209
|
}
|
|
23209
23210
|
),
|
|
@@ -25116,125 +25117,151 @@ var streamProxyConfig = {
|
|
|
25116
25117
|
// src/lib/api/slackApi.ts
|
|
25117
25118
|
var SlackAPI = class {
|
|
25118
25119
|
/**
|
|
25119
|
-
* Sends a support ticket notification
|
|
25120
|
+
* Sends a support ticket notification to Slack.
|
|
25121
|
+
* 1. If slackWebhookUrl is configured, send directly (preferred)
|
|
25122
|
+
* 2. Otherwise, if slackProxyEndpoint is configured, send to the proxy
|
|
25123
|
+
* If neither is configured, logs a warning.
|
|
25120
25124
|
*/
|
|
25121
25125
|
static async sendSupportTicketNotification(ticket) {
|
|
25122
25126
|
try {
|
|
25123
25127
|
const config = _getDashboardConfigInstance();
|
|
25124
25128
|
const endpointsConfig = config.endpoints ?? DEFAULT_ENDPOINTS_CONFIG;
|
|
25125
|
-
const slackWebhookUrl = endpointsConfig
|
|
25126
|
-
if (
|
|
25127
|
-
|
|
25129
|
+
const { slackWebhookUrl, slackProxyEndpoint } = endpointsConfig;
|
|
25130
|
+
if (slackWebhookUrl) {
|
|
25131
|
+
const slackMessage = this.formatSlackMessage(ticket);
|
|
25132
|
+
const response = await fetch(slackWebhookUrl, {
|
|
25133
|
+
method: "POST",
|
|
25134
|
+
headers: {
|
|
25135
|
+
// Use form-urlencoded + simple headers to avoid CORS preflight
|
|
25136
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
25137
|
+
},
|
|
25138
|
+
body: `payload=${encodeURIComponent(JSON.stringify(slackMessage))}`
|
|
25139
|
+
});
|
|
25140
|
+
if (!response.ok) {
|
|
25141
|
+
const errorText = await response.text();
|
|
25142
|
+
console.error("Slack webhook error:", errorText);
|
|
25143
|
+
throw new Error(`Slack webhook failed with status: ${response.status}`);
|
|
25144
|
+
}
|
|
25145
|
+
console.log("Support ticket notification sent to Slack successfully via webhook");
|
|
25128
25146
|
return;
|
|
25129
25147
|
}
|
|
25130
|
-
|
|
25131
|
-
|
|
25132
|
-
|
|
25133
|
-
|
|
25134
|
-
|
|
25135
|
-
const maxDescriptionLength = 300;
|
|
25136
|
-
const description = ticket.description.length > maxDescriptionLength ? `${ticket.description.substring(0, maxDescriptionLength)}...` : ticket.description;
|
|
25137
|
-
const categoryConfig = {
|
|
25138
|
-
general: { emoji: "\u{1F4AC}", color: "#36a64f" },
|
|
25139
|
-
technical: { emoji: "\u{1F527}", color: "#ff6b6b" },
|
|
25140
|
-
feature: { emoji: "\u2728", color: "#4ecdc4" },
|
|
25141
|
-
billing: { emoji: "\u{1F4B3}", color: "#f7b731" }
|
|
25142
|
-
};
|
|
25143
|
-
const priorityConfig = {
|
|
25144
|
-
low: { emoji: "\u{1F7E2}", color: "#36a64f" },
|
|
25145
|
-
normal: { emoji: "\u{1F7E1}", color: "#ffc107" },
|
|
25146
|
-
high: { emoji: "\u{1F7E0}", color: "#ff8c00" },
|
|
25147
|
-
urgent: { emoji: "\u{1F534}", color: "#dc3545" }
|
|
25148
|
-
};
|
|
25149
|
-
const categoryInfo = categoryConfig[ticket.category] || categoryConfig.general;
|
|
25150
|
-
const priorityInfo = priorityConfig[ticket.priority] || priorityConfig.normal;
|
|
25151
|
-
const messageColor = ticket.priority === "high" || ticket.priority === "urgent" ? priorityInfo.color : categoryInfo.color;
|
|
25152
|
-
const slackMessage = {
|
|
25153
|
-
text: `New support ticket from ${ticket.email}`,
|
|
25154
|
-
blocks: [
|
|
25155
|
-
{
|
|
25156
|
-
type: "header",
|
|
25157
|
-
text: {
|
|
25158
|
-
type: "plain_text",
|
|
25159
|
-
text: "\u{1F3AB} New Support Ticket Submitted",
|
|
25160
|
-
emoji: true
|
|
25161
|
-
}
|
|
25148
|
+
if (slackProxyEndpoint) {
|
|
25149
|
+
const response = await fetch(slackProxyEndpoint, {
|
|
25150
|
+
method: "POST",
|
|
25151
|
+
headers: {
|
|
25152
|
+
"Content-Type": "application/json"
|
|
25162
25153
|
},
|
|
25163
|
-
|
|
25164
|
-
|
|
25165
|
-
|
|
25166
|
-
|
|
25167
|
-
|
|
25168
|
-
|
|
25154
|
+
body: JSON.stringify(ticket)
|
|
25155
|
+
});
|
|
25156
|
+
if (!response.ok) {
|
|
25157
|
+
const errorData = await response.json().catch(() => ({ message: "Unknown error" }));
|
|
25158
|
+
throw new Error(errorData.message || `Proxy failed with status: ${response.status}`);
|
|
25159
|
+
}
|
|
25160
|
+
console.log("Support ticket notification sent to Slack successfully via proxy");
|
|
25161
|
+
return;
|
|
25162
|
+
}
|
|
25163
|
+
console.warn("Slack notification skipped: No webhook or proxy endpoint configured");
|
|
25164
|
+
} catch (error) {
|
|
25165
|
+
console.error("Failed to send Slack notification:", error);
|
|
25166
|
+
throw error;
|
|
25167
|
+
}
|
|
25168
|
+
}
|
|
25169
|
+
/**
|
|
25170
|
+
* Formats a support ticket into a Slack message format
|
|
25171
|
+
* This can be used by server-side implementations
|
|
25172
|
+
*/
|
|
25173
|
+
static formatSlackMessage(ticket) {
|
|
25174
|
+
const timestamp = new Date(ticket.timestamp).toLocaleString("en-US", {
|
|
25175
|
+
dateStyle: "medium",
|
|
25176
|
+
timeStyle: "short",
|
|
25177
|
+
timeZone: "UTC"
|
|
25178
|
+
});
|
|
25179
|
+
const maxDescriptionLength = 300;
|
|
25180
|
+
const description = ticket.description.length > maxDescriptionLength ? `${ticket.description.substring(0, maxDescriptionLength)}...` : ticket.description;
|
|
25181
|
+
const categoryConfig = {
|
|
25182
|
+
general: { emoji: "\u{1F4AC}", color: "#36a64f" },
|
|
25183
|
+
technical: { emoji: "\u{1F527}", color: "#ff6b6b" },
|
|
25184
|
+
feature: { emoji: "\u2728", color: "#4ecdc4" },
|
|
25185
|
+
billing: { emoji: "\u{1F4B3}", color: "#f7b731" }
|
|
25186
|
+
};
|
|
25187
|
+
const priorityConfig = {
|
|
25188
|
+
low: { emoji: "\u{1F7E2}", color: "#36a64f" },
|
|
25189
|
+
normal: { emoji: "\u{1F7E1}", color: "#ffc107" },
|
|
25190
|
+
high: { emoji: "\u{1F7E0}", color: "#ff8c00" },
|
|
25191
|
+
urgent: { emoji: "\u{1F534}", color: "#dc3545" }
|
|
25192
|
+
};
|
|
25193
|
+
const categoryInfo = categoryConfig[ticket.category] || categoryConfig.general;
|
|
25194
|
+
const priorityInfo = priorityConfig[ticket.priority] || priorityConfig.normal;
|
|
25195
|
+
const messageColor = ticket.priority === "high" || ticket.priority === "urgent" ? priorityInfo.color : categoryInfo.color;
|
|
25196
|
+
return {
|
|
25197
|
+
text: `New support ticket from ${ticket.email}`,
|
|
25198
|
+
blocks: [
|
|
25199
|
+
{
|
|
25200
|
+
type: "header",
|
|
25201
|
+
text: {
|
|
25202
|
+
type: "plain_text",
|
|
25203
|
+
text: "\u{1F3AB} New Support Ticket Submitted",
|
|
25204
|
+
emoji: true
|
|
25205
|
+
}
|
|
25206
|
+
},
|
|
25207
|
+
{
|
|
25208
|
+
type: "section",
|
|
25209
|
+
fields: [
|
|
25210
|
+
{
|
|
25211
|
+
type: "mrkdwn",
|
|
25212
|
+
text: `*From:*
|
|
25169
25213
|
${ticket.email}`
|
|
25170
|
-
|
|
25171
|
-
|
|
25172
|
-
|
|
25173
|
-
|
|
25214
|
+
},
|
|
25215
|
+
{
|
|
25216
|
+
type: "mrkdwn",
|
|
25217
|
+
text: `*Category:*
|
|
25174
25218
|
${categoryInfo.emoji} ${ticket.category.charAt(0).toUpperCase() + ticket.category.slice(1)}`
|
|
25175
|
-
|
|
25176
|
-
|
|
25177
|
-
|
|
25178
|
-
|
|
25219
|
+
},
|
|
25220
|
+
{
|
|
25221
|
+
type: "mrkdwn",
|
|
25222
|
+
text: `*Priority:*
|
|
25179
25223
|
${priorityInfo.emoji} ${ticket.priority.charAt(0).toUpperCase() + ticket.priority.slice(1)}`
|
|
25180
|
-
|
|
25181
|
-
|
|
25182
|
-
|
|
25183
|
-
|
|
25224
|
+
},
|
|
25225
|
+
{
|
|
25226
|
+
type: "mrkdwn",
|
|
25227
|
+
text: `*Subject:*
|
|
25184
25228
|
${ticket.subject}`
|
|
25185
|
-
|
|
25186
|
-
|
|
25187
|
-
type: "mrkdwn",
|
|
25188
|
-
text: `*Submitted:*
|
|
25189
|
-
${timestamp} UTC`
|
|
25190
|
-
}
|
|
25191
|
-
]
|
|
25192
|
-
},
|
|
25193
|
-
{
|
|
25194
|
-
type: "section",
|
|
25195
|
-
text: {
|
|
25229
|
+
},
|
|
25230
|
+
{
|
|
25196
25231
|
type: "mrkdwn",
|
|
25197
|
-
text: `*
|
|
25198
|
-
${
|
|
25232
|
+
text: `*Submitted:*
|
|
25233
|
+
${timestamp} UTC`
|
|
25199
25234
|
}
|
|
25200
|
-
|
|
25201
|
-
|
|
25202
|
-
|
|
25203
|
-
|
|
25204
|
-
{
|
|
25205
|
-
type: "
|
|
25206
|
-
|
|
25207
|
-
|
|
25208
|
-
type: "mrkdwn",
|
|
25209
|
-
text: `Category: \`${ticket.category}\` | Priority: ${priorityInfo.emoji} \`${ticket.priority.toUpperCase()}\` | ${ticket.priority === "urgent" ? "\u26A0\uFE0F Requires immediate attention" : "Standard processing"}`
|
|
25210
|
-
}
|
|
25211
|
-
]
|
|
25212
|
-
}
|
|
25213
|
-
],
|
|
25214
|
-
attachments: [
|
|
25215
|
-
{
|
|
25216
|
-
color: messageColor,
|
|
25217
|
-
fields: []
|
|
25235
|
+
]
|
|
25236
|
+
},
|
|
25237
|
+
{
|
|
25238
|
+
type: "section",
|
|
25239
|
+
text: {
|
|
25240
|
+
type: "mrkdwn",
|
|
25241
|
+
text: `*Description:*
|
|
25242
|
+
${description}`
|
|
25218
25243
|
}
|
|
25219
|
-
]
|
|
25220
|
-
};
|
|
25221
|
-
const response = await fetch(slackWebhookUrl, {
|
|
25222
|
-
method: "POST",
|
|
25223
|
-
headers: {
|
|
25224
|
-
"Content-Type": "application/json"
|
|
25225
25244
|
},
|
|
25226
|
-
|
|
25227
|
-
|
|
25228
|
-
|
|
25229
|
-
|
|
25230
|
-
|
|
25231
|
-
|
|
25232
|
-
|
|
25233
|
-
|
|
25234
|
-
|
|
25235
|
-
|
|
25236
|
-
|
|
25237
|
-
|
|
25245
|
+
{
|
|
25246
|
+
type: "divider"
|
|
25247
|
+
},
|
|
25248
|
+
{
|
|
25249
|
+
type: "context",
|
|
25250
|
+
elements: [
|
|
25251
|
+
{
|
|
25252
|
+
type: "mrkdwn",
|
|
25253
|
+
text: `Category: \`${ticket.category}\` | Priority: ${priorityInfo.emoji} \`${ticket.priority.toUpperCase()}\` | ${ticket.priority === "urgent" ? "\u26A0\uFE0F Requires immediate attention" : "Standard processing"}`
|
|
25254
|
+
}
|
|
25255
|
+
]
|
|
25256
|
+
}
|
|
25257
|
+
],
|
|
25258
|
+
attachments: [
|
|
25259
|
+
{
|
|
25260
|
+
color: messageColor,
|
|
25261
|
+
fields: []
|
|
25262
|
+
}
|
|
25263
|
+
]
|
|
25264
|
+
};
|
|
25238
25265
|
}
|
|
25239
25266
|
};
|
|
25240
25267
|
var HelpView = ({
|
|
@@ -26677,7 +26704,7 @@ var KPIsOverviewView = ({
|
|
|
26677
26704
|
}
|
|
26678
26705
|
),
|
|
26679
26706
|
/* @__PURE__ */ jsx("div", { className: "flex-1 flex justify-center", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
26680
|
-
/* @__PURE__ */ jsx("h1", { className: "text-3xl font-bold text-gray-800 tracking-tight", children: "
|
|
26707
|
+
/* @__PURE__ */ jsx("h1", { className: "text-3xl font-bold text-gray-800 tracking-tight", children: "Shop-floor overview" }),
|
|
26681
26708
|
/* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-green-500 animate-pulse ring-2 ring-green-500/30 ring-offset-1" })
|
|
26682
26709
|
] }) })
|
|
26683
26710
|
] }) }) }),
|
|
@@ -26699,7 +26726,7 @@ var KPIsOverviewView = ({
|
|
|
26699
26726
|
}
|
|
26700
26727
|
),
|
|
26701
26728
|
/* @__PURE__ */ jsx("div", { className: "flex-1 flex justify-center", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
26702
|
-
/* @__PURE__ */ jsx("h1", { className: "text-3xl font-bold text-gray-800 tracking-tight", children: "
|
|
26729
|
+
/* @__PURE__ */ jsx("h1", { className: "text-3xl font-bold text-gray-800 tracking-tight", children: "Shop-floor overview" }),
|
|
26703
26730
|
/* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-green-500 animate-pulse ring-2 ring-green-500/30 ring-offset-1" })
|
|
26704
26731
|
] }) })
|
|
26705
26732
|
] }) }) }),
|
|
@@ -26724,7 +26751,7 @@ var KPIsOverviewView = ({
|
|
|
26724
26751
|
}
|
|
26725
26752
|
),
|
|
26726
26753
|
/* @__PURE__ */ jsx("div", { className: "flex-1 flex justify-center", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
26727
|
-
/* @__PURE__ */ jsx("h1", { className: "text-3xl font-bold text-gray-800 tracking-tight", children: "
|
|
26754
|
+
/* @__PURE__ */ jsx("h1", { className: "text-3xl font-bold text-gray-800 tracking-tight", children: "Shop-floor overview" }),
|
|
26728
26755
|
/* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-green-500 animate-pulse ring-2 ring-green-500/30 ring-offset-1" })
|
|
26729
26756
|
] }) })
|
|
26730
26757
|
] }),
|