Metamigo -> Bridge
This commit is contained in:
parent
242f3cf6b8
commit
a445762a37
145 changed files with 396 additions and 16668 deletions
|
|
@ -241,7 +241,7 @@ export const Sidebar: FC<SidebarProps> = ({ open, setOpen }) => {
|
|||
fontFamily: poppins.style.fontFamily,
|
||||
}}
|
||||
>
|
||||
Metamigo
|
||||
CDR Bridge
|
||||
</Typography>
|
||||
</Grid>
|
||||
)}
|
||||
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
|
@ -2,10 +2,12 @@ import type { Metadata } from "next";
|
|||
import { InternalLayout } from "./_components/InternalLayout";
|
||||
import { LicenseInfo } from "@mui/x-license";
|
||||
|
||||
LicenseInfo.setLicenseKey("7c9bf25d9e240f76e77cbf7d2ba58a23Tz02NjU4OCxFPTE3MTU4NjIzMzQ2ODgsUz1wcm8sTE09c3Vic2NyaXB0aW9uLEtWPTI=");
|
||||
LicenseInfo.setLicenseKey(
|
||||
"7c9bf25d9e240f76e77cbf7d2ba58a23Tz02NjU4OCxFPTE3MTU4NjIzMzQ2ODgsUz1wcm8sTE09c3Vic2NyaXB0aW9uLEtWPTI=",
|
||||
);
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Metamigo",
|
||||
title: "CDR Bridge",
|
||||
description: "",
|
||||
};
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "metamigo-frontend",
|
||||
"name": "bridge-frontend",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@auth/kysely-adapter": "^0.7.0",
|
||||
"@auth/kysely-adapter": "^1.0.0",
|
||||
"@emotion/cache": "^11.11.0",
|
||||
"@emotion/react": "^11.11.4",
|
||||
"@emotion/styled": "^11.11.5",
|
||||
|
|
@ -17,14 +17,14 @@
|
|||
"@mui/lab": "^5.0.0-alpha.170",
|
||||
"@mui/material": "^5",
|
||||
"@mui/material-nextjs": "^5.15.11",
|
||||
"@mui/x-data-grid-pro": "^7.1.1",
|
||||
"@mui/x-date-pickers-pro": "^7.1.1",
|
||||
"@mui/x-license": "^7.1.1",
|
||||
"@mui/x-data-grid-pro": "^7.3.0",
|
||||
"@mui/x-date-pickers-pro": "^7.2.0",
|
||||
"@mui/x-license": "^7.2.0",
|
||||
"date-fns": "^3.6.0",
|
||||
"kysely": "^0.26.1",
|
||||
"material-ui-popup-state": "^5.1.0",
|
||||
"mui-chips-input": "^2.1.4",
|
||||
"next": "14.1.4",
|
||||
"next": "14.2.2",
|
||||
"next-auth": "^4.24.7",
|
||||
"pg": "^8.11.5",
|
||||
"react": "18.2.0",
|
||||
|
|
@ -41,8 +41,8 @@
|
|||
"@types/pg": "^8.11.5",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"eslint": "^9",
|
||||
"eslint-config-next": "14.1.4",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "14.2.2",
|
||||
"ts-config": "*",
|
||||
"typescript": "^5"
|
||||
}
|
||||
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
3
apps/bridge-worker/babel.config.json
Normal file
3
apps/bridge-worker/babel.config.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"presets": ["@digiresilience/babel-preset-bridge"]
|
||||
}
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
/* eslint-disable camelcase */
|
||||
import { SavedVoiceProvider } from "@digiresilience/metamigo-db";
|
||||
import { SavedVoiceProvider } from "@digiresilience/bridge-db";
|
||||
import Twilio from "twilio";
|
||||
import { CallInstance } from "twilio/lib/rest/api/v2010/account/call";
|
||||
import { Zammad, getOrCreateUser } from "./zammad";
|
||||
|
||||
export const twilioClientFor = (
|
||||
provider: SavedVoiceProvider
|
||||
provider: SavedVoiceProvider,
|
||||
): Twilio.Twilio => {
|
||||
const { accountSid, apiKeySid, apiKeySecret } = provider.credentials;
|
||||
if (!accountSid || !apiKeySid || !apiKeySecret)
|
||||
throw new Error(
|
||||
`twilio provider ${provider.name} does not have credentials`
|
||||
`twilio provider ${provider.name} does not have credentials`,
|
||||
);
|
||||
|
||||
return Twilio(apiKeySid, apiKeySecret, {
|
||||
|
|
@ -20,7 +20,7 @@ export const twilioClientFor = (
|
|||
|
||||
export const createZammadTicket = async (
|
||||
call: CallInstance,
|
||||
mp3: Buffer
|
||||
mp3: Buffer,
|
||||
): Promise<void> => {
|
||||
const title = `Call from ${call.fromFormatted} at ${call.startTime}`;
|
||||
const body = `<ul>
|
||||
|
|
@ -36,7 +36,7 @@ export const createZammadTicket = async (
|
|||
{
|
||||
token: "EviH_WL0p6YUlCoIER7noAZEAPsYA_fVU4FZCKdpq525Vmzzvl8d7dNuP_8d-Amb",
|
||||
},
|
||||
"https://demo.digiresilience.org"
|
||||
"https://demo.digiresilience.org",
|
||||
);
|
||||
try {
|
||||
const customer = await getOrCreateUser(zammad, call.fromFormatted);
|
||||
|
|
@ -1,12 +1,16 @@
|
|||
import pgPromise from "pg-promise";
|
||||
import * as pgMonitor from "pg-monitor";
|
||||
import { dbInitOptions, IRepositories, AppDatabase } from "@digiresilience/metamigo-db";
|
||||
import config from "@digiresilience/metamigo-config";
|
||||
import {
|
||||
dbInitOptions,
|
||||
IRepositories,
|
||||
AppDatabase,
|
||||
} from "@digiresilience/bridge-db";
|
||||
import config from "@digiresilience/bridge-config";
|
||||
import type { IInitOptions } from "pg-promise";
|
||||
|
||||
export const initDiagnostics = (
|
||||
logSql: boolean,
|
||||
initOpts: IInitOptions<IRepositories>
|
||||
initOpts: IInitOptions<IRepositories>,
|
||||
): void => {
|
||||
if (logSql) {
|
||||
pgMonitor.attach(initOpts);
|
||||
|
|
@ -44,4 +48,4 @@ export const withDb = <T>(f: (db: AppDatabase) => Promise<T>): Promise<T> => {
|
|||
}
|
||||
};
|
||||
|
||||
export type { AppDatabase } from "@digiresilience/metamigo-db";
|
||||
export type { AppDatabase } from "@digiresilience/bridge-db";
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { defState } from "@digiresilience/montar";
|
||||
import { configureLogger } from "@digiresilience/metamigo-common";
|
||||
import config from "@digiresilience/metamigo-config";
|
||||
import { configureLogger } from "@digiresilience/bridge-common";
|
||||
import config from "@digiresilience/bridge-config";
|
||||
|
||||
export const logger = defState("workerLogger", {
|
||||
start: async () => configureLogger(config),
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "metamigo-worker",
|
||||
"name": "bridge-worker",
|
||||
"version": "0.2.0",
|
||||
"main": "build/main/index.js",
|
||||
"type": "module",
|
||||
|
|
@ -10,8 +10,8 @@
|
|||
"html-to-text": "^9.0.5",
|
||||
"node-fetch": "^3",
|
||||
"pg-promise": "^11.6.0",
|
||||
"remeda": "^1.57.2",
|
||||
"twilio": "^5.0.3"
|
||||
"remeda": "^1.60.1",
|
||||
"twilio": "^5.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ts-config": "*",
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
"prettier": "^3.2.5",
|
||||
"ts-node": "^10.9.2",
|
||||
"typedoc": "^0.25.13",
|
||||
"typescript": "^5.4.4"
|
||||
"typescript": "^5.4.5"
|
||||
},
|
||||
"nodemonConfig": {
|
||||
"ignore": [
|
||||
|
|
@ -3,29 +3,35 @@ import { convert } from "html-to-text";
|
|||
import fetch from "node-fetch";
|
||||
import { URLSearchParams } from "url";
|
||||
import { withDb, AppDatabase } from "../db";
|
||||
import { loadConfig } from "@digiresilience/metamigo-config";
|
||||
import { loadConfig } from "@digiresilience/bridge-config";
|
||||
import { tagMap } from "../lib/tag-map";
|
||||
|
||||
type FormattedZammadTicket = {
|
||||
data: Record<string, unknown>,
|
||||
data: Record<string, unknown>;
|
||||
predictions: Record<string, unknown>[];
|
||||
};
|
||||
|
||||
const getZammadTickets = async (page: number, minUpdatedTimestamp: Date): Promise<[boolean, FormattedZammadTicket[]]> => {
|
||||
const { leafcutter: { zammadApiUrl, zammadApiKey, contributorName, contributorId } } = await loadConfig();
|
||||
const getZammadTickets = async (
|
||||
page: number,
|
||||
minUpdatedTimestamp: Date,
|
||||
): Promise<[boolean, FormattedZammadTicket[]]> => {
|
||||
const {
|
||||
leafcutter: { zammadApiUrl, zammadApiKey, contributorName, contributorId },
|
||||
} = await loadConfig();
|
||||
const headers = { Authorization: `Token ${zammadApiKey}` };
|
||||
let shouldContinue = false;
|
||||
const docs = [];
|
||||
const ticketsQuery = new URLSearchParams({
|
||||
"expand": "true",
|
||||
"sort_by": "updated_at",
|
||||
"order_by": "asc",
|
||||
"query": "state.name: closed",
|
||||
"per_page": "25",
|
||||
"page": `${page}`,
|
||||
expand: "true",
|
||||
sort_by: "updated_at",
|
||||
order_by: "asc",
|
||||
query: "state.name: closed",
|
||||
per_page: "25",
|
||||
page: `${page}`,
|
||||
});
|
||||
const rawTickets = await fetch(`${zammadApiUrl}/tickets/search?${ticketsQuery}`,
|
||||
{ headers }
|
||||
const rawTickets = await fetch(
|
||||
`${zammadApiUrl}/tickets/search?${ticketsQuery}`,
|
||||
{ headers },
|
||||
);
|
||||
const tickets: any = await rawTickets.json();
|
||||
console.log({ tickets });
|
||||
|
|
@ -41,14 +47,25 @@ const getZammadTickets = async (page: number, minUpdatedTimestamp: Date): Promis
|
|||
shouldContinue = true;
|
||||
|
||||
if (source_closed_at <= minUpdatedTimestamp) {
|
||||
console.log(`Skipping ticket`, { source_id, source_updated_at, source_closed_at, minUpdatedTimestamp });
|
||||
console.log(`Skipping ticket`, {
|
||||
source_id,
|
||||
source_updated_at,
|
||||
source_closed_at,
|
||||
minUpdatedTimestamp,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
console.log(`Processing ticket`, { source_id, source_updated_at, source_closed_at, minUpdatedTimestamp });
|
||||
console.log(`Processing ticket`, {
|
||||
source_id,
|
||||
source_updated_at,
|
||||
source_closed_at,
|
||||
minUpdatedTimestamp,
|
||||
});
|
||||
|
||||
const rawArticles = await fetch(`${zammadApiUrl}/ticket_articles/by_ticket/${source_id}`,
|
||||
{ headers }
|
||||
const rawArticles = await fetch(
|
||||
`${zammadApiUrl}/ticket_articles/by_ticket/${source_id}`,
|
||||
{ headers },
|
||||
);
|
||||
const articles: any = await rawArticles.json();
|
||||
let articleText = "";
|
||||
|
|
@ -69,7 +86,9 @@ const getZammadTickets = async (page: number, minUpdatedTimestamp: Date): Promis
|
|||
o_id: source_id,
|
||||
});
|
||||
|
||||
const rawTags = await fetch(`${zammadApiUrl}/tags?${tagsQuery}`, { headers });
|
||||
const rawTags = await fetch(`${zammadApiUrl}/tags?${tagsQuery}`, {
|
||||
headers,
|
||||
});
|
||||
const { tags }: any = await rawTags.json();
|
||||
const transformedTags = [];
|
||||
for (const tag of tags) {
|
||||
|
|
@ -88,7 +107,7 @@ const getZammadTickets = async (page: number, minUpdatedTimestamp: Date): Promis
|
|||
source_created_at,
|
||||
source_updated_at,
|
||||
},
|
||||
predictions: []
|
||||
predictions: [],
|
||||
};
|
||||
|
||||
const result = transformedTags.map((tag) => {
|
||||
|
|
@ -115,12 +134,17 @@ const getZammadTickets = async (page: number, minUpdatedTimestamp: Date): Promis
|
|||
return [shouldContinue, docs];
|
||||
};
|
||||
|
||||
const fetchFromZammad = async (minUpdatedTimestamp: Date): Promise<FormattedZammadTicket[]> => {
|
||||
const fetchFromZammad = async (
|
||||
minUpdatedTimestamp: Date,
|
||||
): Promise<FormattedZammadTicket[]> => {
|
||||
const pages = [...Array.from({ length: 10000 }).keys()];
|
||||
const allTickets: FormattedZammadTicket[] = [];
|
||||
|
||||
for await (const page of pages) {
|
||||
const [shouldContinue, tickets] = await getZammadTickets(page + 1, minUpdatedTimestamp);
|
||||
const [shouldContinue, tickets] = await getZammadTickets(
|
||||
page + 1,
|
||||
minUpdatedTimestamp,
|
||||
);
|
||||
|
||||
if (!shouldContinue) {
|
||||
break;
|
||||
|
|
@ -135,7 +159,9 @@ const fetchFromZammad = async (minUpdatedTimestamp: Date): Promise<FormattedZamm
|
|||
};
|
||||
|
||||
const sendToLabelStudio = async (tickets: FormattedZammadTicket[]) => {
|
||||
const { leafcutter: { labelStudioApiUrl, labelStudioApiKey } } = await loadConfig();
|
||||
const {
|
||||
leafcutter: { labelStudioApiUrl, labelStudioApiKey },
|
||||
} = await loadConfig();
|
||||
|
||||
const headers = {
|
||||
Authorization: `Token ${labelStudioApiKey}`,
|
||||
|
|
@ -157,10 +183,14 @@ const sendToLabelStudio = async (tickets: FormattedZammadTicket[]) => {
|
|||
|
||||
const importLabelStudioTask = async (): Promise<void> => {
|
||||
withDb(async (db: AppDatabase) => {
|
||||
const { leafcutter: { contributorName } } = await loadConfig();
|
||||
const {
|
||||
leafcutter: { contributorName },
|
||||
} = await loadConfig();
|
||||
const settingName = `${contributorName}ImportLabelStudioTask`;
|
||||
const res: any = await db.settings.findByName(settingName);
|
||||
const startTimestamp = res?.value?.minUpdatedTimestamp ? new Date(res.value.minUpdatedTimestamp as string) : new Date("2023-03-01");
|
||||
const startTimestamp = res?.value?.minUpdatedTimestamp
|
||||
? new Date(res.value.minUpdatedTimestamp as string)
|
||||
: new Date("2023-03-01");
|
||||
const tickets = await fetchFromZammad(startTimestamp);
|
||||
|
||||
if (tickets.length > 0) {
|
||||
|
|
@ -168,7 +198,9 @@ const importLabelStudioTask = async (): Promise<void> => {
|
|||
const lastTicket = tickets.pop();
|
||||
const newLastTimestamp = lastTicket.data.source_closed_at;
|
||||
console.log({ newLastTimestamp });
|
||||
await db.settings.upsert(settingName, { minUpdatedTimestamp: newLastTimestamp });
|
||||
await db.settings.upsert(settingName, {
|
||||
minUpdatedTimestamp: newLastTimestamp,
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
import fetch from "node-fetch";
|
||||
import { URLSearchParams } from "url";
|
||||
import { withDb, AppDatabase } from "../db";
|
||||
import { loadConfig } from "@digiresilience/metamigo-config";
|
||||
import { loadConfig } from "@digiresilience/bridge-config";
|
||||
|
||||
type LabelStudioTicket = {
|
||||
id: string;
|
||||
|
|
@ -27,12 +27,11 @@ type LeafcutterTicket = {
|
|||
source_updated_at: string;
|
||||
};
|
||||
|
||||
const getLabelStudioTickets = async (page: number): Promise<LabelStudioTicket[]> => {
|
||||
const getLabelStudioTickets = async (
|
||||
page: number,
|
||||
): Promise<LabelStudioTicket[]> => {
|
||||
const {
|
||||
leafcutter: {
|
||||
labelStudioApiUrl,
|
||||
labelStudioApiKey,
|
||||
}
|
||||
leafcutter: { labelStudioApiUrl, labelStudioApiKey },
|
||||
} = await loadConfig();
|
||||
|
||||
const headers = {
|
||||
|
|
@ -44,8 +43,10 @@ const getLabelStudioTickets = async (page: number): Promise<LabelStudioTicket[]>
|
|||
page: `${page}`,
|
||||
});
|
||||
console.log({ url: `${labelStudioApiUrl}/projects/1/tasks?${ticketsQuery}` });
|
||||
const res = await fetch(`${labelStudioApiUrl}/projects/1/tasks?${ticketsQuery}`,
|
||||
{ headers });
|
||||
const res = await fetch(
|
||||
`${labelStudioApiUrl}/projects/1/tasks?${ticketsQuery}`,
|
||||
{ headers },
|
||||
);
|
||||
console.log({ res });
|
||||
const tasksResult: any = await res.json();
|
||||
console.log({ tasksResult });
|
||||
|
|
@ -53,7 +54,9 @@ const getLabelStudioTickets = async (page: number): Promise<LabelStudioTicket[]>
|
|||
return tasksResult;
|
||||
};
|
||||
|
||||
const fetchFromLabelStudio = async (minUpdatedTimestamp: Date): Promise<LabelStudioTicket[]> => {
|
||||
const fetchFromLabelStudio = async (
|
||||
minUpdatedTimestamp: Date,
|
||||
): Promise<LabelStudioTicket[]> => {
|
||||
const pages = [...Array.from({ length: 10000 }).keys()];
|
||||
const allDocs: LabelStudioTicket[] = [];
|
||||
|
||||
|
|
@ -85,8 +88,8 @@ const sendToLeafcutter = async (tickets: LabelStudioTicket[]) => {
|
|||
contributorId,
|
||||
opensearchApiUrl,
|
||||
opensearchUsername,
|
||||
opensearchPassword
|
||||
}
|
||||
opensearchPassword,
|
||||
},
|
||||
} = await loadConfig();
|
||||
|
||||
console.log({ tickets });
|
||||
|
|
@ -96,11 +99,7 @@ const sendToLeafcutter = async (tickets: LabelStudioTicket[]) => {
|
|||
const {
|
||||
id,
|
||||
annotations,
|
||||
data: {
|
||||
source_id,
|
||||
source_created_at,
|
||||
source_updated_at
|
||||
}
|
||||
data: { source_id, source_created_at, source_updated_at },
|
||||
} = ticket;
|
||||
|
||||
const getTags = (tags: Record<string, any>[], name: string) =>
|
||||
|
|
@ -127,7 +126,7 @@ const sendToLeafcutter = async (tickets: LabelStudioTicket[]) => {
|
|||
origin: contributorId,
|
||||
origin_id: source_id as string,
|
||||
source_created_at: source_created_at as string,
|
||||
source_updated_at: source_updated_at as string
|
||||
source_updated_at: source_updated_at as string,
|
||||
};
|
||||
});
|
||||
|
||||
|
|
@ -145,19 +144,30 @@ const sendToLeafcutter = async (tickets: LabelStudioTicket[]) => {
|
|||
console.log({ result });
|
||||
};
|
||||
|
||||
|
||||
const importLeafcutterTask = async (): Promise<void> => {
|
||||
withDb(async (db: AppDatabase) => {
|
||||
const { leafcutter: { contributorName } } = await loadConfig();
|
||||
const {
|
||||
leafcutter: { contributorName },
|
||||
} = await loadConfig();
|
||||
const settingName = `${contributorName}ImportLeafcutterTask`;
|
||||
const res: any = await db.settings.findByName(settingName);
|
||||
const startTimestamp = res?.value?.minUpdatedTimestamp ? new Date(res.value.minUpdatedTimestamp as string) : new Date("2023-03-01");
|
||||
const startTimestamp = res?.value?.minUpdatedTimestamp
|
||||
? new Date(res.value.minUpdatedTimestamp as string)
|
||||
: new Date("2023-03-01");
|
||||
const newLastTimestamp = new Date();
|
||||
console.log({ contributorName, settingName, res, startTimestamp, newLastTimestamp });
|
||||
console.log({
|
||||
contributorName,
|
||||
settingName,
|
||||
res,
|
||||
startTimestamp,
|
||||
newLastTimestamp,
|
||||
});
|
||||
const tickets = await fetchFromLabelStudio(startTimestamp);
|
||||
console.log({ tickets });
|
||||
await sendToLeafcutter(tickets);
|
||||
await db.settings.upsert(settingName, { minUpdatedTimestamp: newLastTimestamp });
|
||||
await db.settings.upsert(settingName, {
|
||||
minUpdatedTimestamp: newLastTimestamp,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import Twilio from "twilio";
|
||||
import config from "@digiresilience/metamigo-config";
|
||||
import config from "@digiresilience/bridge-config";
|
||||
import { withDb, AppDatabase } from "../db";
|
||||
|
||||
interface VoiceLineDeleteTaskOptions {
|
||||
|
|
@ -9,7 +9,7 @@ interface VoiceLineDeleteTaskOptions {
|
|||
}
|
||||
|
||||
const voiceLineDeleteTask = async (
|
||||
payload: VoiceLineDeleteTaskOptions
|
||||
payload: VoiceLineDeleteTaskOptions,
|
||||
): Promise<void> =>
|
||||
withDb(async (db: AppDatabase) => {
|
||||
const { voiceLineId, providerId, providerLineSid } = payload;
|
||||
|
|
@ -19,7 +19,7 @@ const voiceLineDeleteTask = async (
|
|||
const { accountSid, apiKeySid, apiKeySecret } = provider.credentials;
|
||||
if (!accountSid || !apiKeySid || !apiKeySecret)
|
||||
throw new Error(
|
||||
`twilio provider ${provider.name} does not have credentials`
|
||||
`twilio provider ${provider.name} does not have credentials`,
|
||||
);
|
||||
|
||||
const client = Twilio(apiKeySid, apiKeySecret, {
|
||||
|
|
@ -30,7 +30,7 @@ const voiceLineDeleteTask = async (
|
|||
if (
|
||||
number &&
|
||||
number.voiceUrl ===
|
||||
`${config.frontend.url}/api/v1/voice/twilio/record/${voiceLineId}`
|
||||
`${config.frontend.url}/api/v1/voice/twilio/record/${voiceLineId}`
|
||||
)
|
||||
await client.incomingPhoneNumbers(providerLineSid).update({
|
||||
voiceUrl: "",
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import Twilio from "twilio";
|
||||
import config from "@digiresilience/metamigo-config";
|
||||
import config from "@digiresilience/bridge-config";
|
||||
import { withDb, AppDatabase } from "../db";
|
||||
|
||||
interface VoiceLineUpdateTaskOptions {
|
||||
|
|
@ -7,7 +7,7 @@ interface VoiceLineUpdateTaskOptions {
|
|||
}
|
||||
|
||||
const voiceLineUpdateTask = async (
|
||||
payload: VoiceLineUpdateTaskOptions
|
||||
payload: VoiceLineUpdateTaskOptions,
|
||||
): Promise<void> =>
|
||||
withDb(async (db: AppDatabase) => {
|
||||
const { voiceLineId } = payload;
|
||||
|
|
@ -22,7 +22,7 @@ const voiceLineUpdateTask = async (
|
|||
const { accountSid, apiKeySid, apiKeySecret } = provider.credentials;
|
||||
if (!accountSid || !apiKeySid || !apiKeySecret)
|
||||
throw new Error(
|
||||
`twilio provider ${provider.name} does not have credentials`
|
||||
`twilio provider ${provider.name} does not have credentials`,
|
||||
);
|
||||
|
||||
const client = Twilio(apiKeySid, apiKeySecret, {
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import * as Worker from "graphile-worker";
|
||||
import { defState } from "@digiresilience/montar";
|
||||
import config from "@digiresilience/metamigo-config";
|
||||
import config from "@digiresilience/bridge-config";
|
||||
|
||||
const startWorkerUtils = async (): Promise<Worker.WorkerUtils> => {
|
||||
const workerUtils = await Worker.makeWorkerUtils({
|
||||
|
|
@ -20,15 +20,15 @@
|
|||
"@mui/icons-material": "^5",
|
||||
"@mui/lab": "^5.0.0-alpha.170",
|
||||
"@mui/material": "^5",
|
||||
"@mui/x-data-grid-pro": "^7.1.1",
|
||||
"@mui/x-date-pickers-pro": "^7.1.1",
|
||||
"@opensearch-project/opensearch": "^2.6.0",
|
||||
"@mui/x-data-grid-pro": "^7.3.0",
|
||||
"@mui/x-date-pickers-pro": "^7.2.0",
|
||||
"@opensearch-project/opensearch": "^2.7.0",
|
||||
"cryptr": "^6.3.0",
|
||||
"date-fns": "^3.6.0",
|
||||
"http-proxy-middleware": "^3.0.0",
|
||||
"leafcutter-ui": "*",
|
||||
"material-ui-popup-state": "^5.1.0",
|
||||
"next": "14.1.4",
|
||||
"next": "14.2.2",
|
||||
"next-auth": "^4.24.7",
|
||||
"next-http-proxy-middleware": "^1.2.6",
|
||||
"opensearch-common": "*",
|
||||
|
|
@ -47,17 +47,17 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.24.4",
|
||||
"@types/node": "^20.12.6",
|
||||
"@types/react": "18.2.75",
|
||||
"@types/node": "^20.12.7",
|
||||
"@types/react": "18.2.79",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"babel-loader": "^9.1.3",
|
||||
"eslint": "^9.0.0",
|
||||
"eslint-config-next": "^14.1.4",
|
||||
"eslint": "^8.0.0",
|
||||
"eslint-config-next": "^14.2.2",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-jsx-a11y": "^6.8.0",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"eslint-plugin-react": "^7.34.1",
|
||||
"typescript": "5.4.4"
|
||||
"typescript": "5.4.5"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,114 +53,115 @@ const MenuItem = ({
|
|||
}: any) => {
|
||||
const { roboto } = fonts;
|
||||
|
||||
return (<Link href={href} target={target}>
|
||||
<ListItemButton
|
||||
sx={{
|
||||
p: 0,
|
||||
mb: 1,
|
||||
bl: iconSize === 0 ? "1px solid white" : "inherit",
|
||||
}}
|
||||
selected={selected}
|
||||
>
|
||||
{iconSize > 0 ? (
|
||||
<ListItemIcon
|
||||
sx={{
|
||||
color: `white`,
|
||||
minWidth: 0,
|
||||
mr: 2,
|
||||
textAlign: "center",
|
||||
margin: open ? "0 8 0 0" : "0 auto",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
return (
|
||||
<Link href={href} target={target}>
|
||||
<ListItemButton
|
||||
sx={{
|
||||
p: 0,
|
||||
mb: 1,
|
||||
bl: iconSize === 0 ? "1px solid white" : "inherit",
|
||||
}}
|
||||
selected={selected}
|
||||
>
|
||||
{iconSize > 0 ? (
|
||||
<ListItemIcon
|
||||
sx={{
|
||||
width: iconSize,
|
||||
height: iconSize,
|
||||
mr: 0.5,
|
||||
mt: "-4px",
|
||||
color: `white`,
|
||||
minWidth: 0,
|
||||
mr: 2,
|
||||
textAlign: "center",
|
||||
margin: open ? "0 8 0 0" : "0 auto",
|
||||
}}
|
||||
>
|
||||
<Icon />
|
||||
</Box>
|
||||
</ListItemIcon>
|
||||
) : (
|
||||
<Box
|
||||
sx={{
|
||||
width: 30,
|
||||
height: "28px",
|
||||
position: "relative",
|
||||
ml: "9px",
|
||||
mr: "1px",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
width: "1px",
|
||||
height: "56px",
|
||||
backgroundColor: "white",
|
||||
position: "absolute",
|
||||
left: "3px",
|
||||
top: "-10px",
|
||||
}}
|
||||
/>
|
||||
<Box
|
||||
sx={{
|
||||
width: "42px",
|
||||
height: "42px",
|
||||
position: "absolute",
|
||||
top: "-27px",
|
||||
left: "3px",
|
||||
border: "solid 1px #fff",
|
||||
borderColor: "transparent transparent transparent #fff",
|
||||
borderRadius: "60px",
|
||||
rotate: "-35deg",
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
{open && (
|
||||
<ListItemText
|
||||
inset={inset}
|
||||
primary={
|
||||
<Typography
|
||||
variant="body1"
|
||||
<Box
|
||||
sx={{
|
||||
fontSize: 16,
|
||||
fontFamily: roboto.style.fontFamily,
|
||||
fontWeight: "bold",
|
||||
border: 0,
|
||||
textAlign: "left",
|
||||
color: "white",
|
||||
width: iconSize,
|
||||
height: iconSize,
|
||||
mr: 0.5,
|
||||
mt: "-4px",
|
||||
}}
|
||||
>
|
||||
{name}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{badge && badge > 0 ? (
|
||||
<ListItemSecondaryAction>
|
||||
<Typography
|
||||
color="textSecondary"
|
||||
variant="body1"
|
||||
className="badge"
|
||||
<Icon />
|
||||
</Box>
|
||||
</ListItemIcon>
|
||||
) : (
|
||||
<Box
|
||||
sx={{
|
||||
backgroundColor: "#FFB620",
|
||||
color: "black !important",
|
||||
borderRadius: 10,
|
||||
px: 1,
|
||||
fontSize: 12,
|
||||
fontWeight: "bold",
|
||||
width: 30,
|
||||
height: "28px",
|
||||
position: "relative",
|
||||
ml: "9px",
|
||||
mr: "1px",
|
||||
}}
|
||||
>
|
||||
{badge}
|
||||
</Typography>
|
||||
</ListItemSecondaryAction>
|
||||
) : null}
|
||||
</ListItemButton>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
<Box
|
||||
sx={{
|
||||
width: "1px",
|
||||
height: "56px",
|
||||
backgroundColor: "white",
|
||||
position: "absolute",
|
||||
left: "3px",
|
||||
top: "-10px",
|
||||
}}
|
||||
/>
|
||||
<Box
|
||||
sx={{
|
||||
width: "42px",
|
||||
height: "42px",
|
||||
position: "absolute",
|
||||
top: "-27px",
|
||||
left: "3px",
|
||||
border: "solid 1px #fff",
|
||||
borderColor: "transparent transparent transparent #fff",
|
||||
borderRadius: "60px",
|
||||
rotate: "-35deg",
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
{open && (
|
||||
<ListItemText
|
||||
inset={inset}
|
||||
primary={
|
||||
<Typography
|
||||
variant="body1"
|
||||
sx={{
|
||||
fontSize: 16,
|
||||
fontFamily: roboto.style.fontFamily,
|
||||
fontWeight: "bold",
|
||||
border: 0,
|
||||
textAlign: "left",
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
{name}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{badge && badge > 0 ? (
|
||||
<ListItemSecondaryAction>
|
||||
<Typography
|
||||
color="textSecondary"
|
||||
variant="body1"
|
||||
className="badge"
|
||||
sx={{
|
||||
backgroundColor: "#FFB620",
|
||||
color: "black !important",
|
||||
borderRadius: 10,
|
||||
px: 1,
|
||||
fontSize: 12,
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
{badge}
|
||||
</Typography>
|
||||
</ListItemSecondaryAction>
|
||||
) : null}
|
||||
</ListItemButton>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
interface SidebarProps {
|
||||
open: boolean;
|
||||
|
|
@ -577,13 +578,13 @@ export const Sidebar: FC<SidebarProps> = ({ open, setOpen }) => {
|
|||
selected={pathname.endsWith("/admin/zammad")}
|
||||
open={open}
|
||||
/>
|
||||
{false && roles.includes("metamigo") && (
|
||||
{false && roles.includes("bridge") && (
|
||||
<MenuItem
|
||||
name="Metamigo"
|
||||
href="/admin/metamigo"
|
||||
name="Bridge"
|
||||
href="/admin/bridge"
|
||||
Icon={FeaturedPlayListIcon}
|
||||
iconSize={0}
|
||||
selected={pathname.endsWith("/admin/metamigo")}
|
||||
selected={pathname.endsWith("/admin/bridge")}
|
||||
open={open}
|
||||
/>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ const nextConfig = {
|
|||
experimental: {
|
||||
missingSuspenseWithCSRBailout: false,
|
||||
},
|
||||
transpilePackages: ["leafcutter-ui", "metamigo-ui", "opensearch-common", "ui"],
|
||||
transpilePackages: ["leafcutter-ui", "bridge-ui", "opensearch-common", "ui"],
|
||||
publicRuntimeConfig: {
|
||||
linkURL: process.env.LINK_URL ?? "http://localhost:3000",
|
||||
metamigoURL: process.env.METAMIGO_URL ?? "http://localhost:8002",
|
||||
bridgeURL: process.env.BRIDGE_URL ?? "http://localhost:8002",
|
||||
labelStudioURL: process.env.LABEL_STUDIO_URL ?? "http://localhost:8006",
|
||||
muiLicenseKey: process.env.MUI_LICENSE_KEY ?? "",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -18,15 +18,15 @@
|
|||
"@mui/icons-material": "^5",
|
||||
"@mui/lab": "^5.0.0-alpha.170",
|
||||
"@mui/material": "^5",
|
||||
"@mui/x-data-grid-pro": "^7.1.1",
|
||||
"@mui/x-date-pickers-pro": "^7.1.1",
|
||||
"@mui/x-data-grid-pro": "^7.3.0",
|
||||
"@mui/x-date-pickers-pro": "^7.2.0",
|
||||
"date-fns": "^3.6.0",
|
||||
"graphql-request": "^6.1.0",
|
||||
"leafcutter-ui": "*",
|
||||
"material-ui-popup-state": "^5.1.0",
|
||||
"metamigo-ui": "*",
|
||||
"bridge-ui": "*",
|
||||
"mui-chips-input": "^2.1.4",
|
||||
"next": "14.1.4",
|
||||
"next": "14.2.2",
|
||||
"next-auth": "^4.24.7",
|
||||
"opensearch-common": "*",
|
||||
"react": "18.2.0",
|
||||
|
|
@ -42,17 +42,17 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.24.4",
|
||||
"@types/node": "^20.12.6",
|
||||
"@types/react": "18.2.75",
|
||||
"@types/node": "^20.12.7",
|
||||
"@types/react": "18.2.79",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"babel-loader": "^9.1.3",
|
||||
"eslint": "^9.0.0",
|
||||
"eslint-config-next": "^14.1.4",
|
||||
"eslint": "^8.0.0",
|
||||
"eslint-config-next": "^14.2.2",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-jsx-a11y": "^6.8.0",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"eslint-plugin-react": "^7.34.1",
|
||||
"typescript": "5.4.4"
|
||||
"typescript": "5.4.5"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
@digiresilience:registry=https://gitlab.com/api/v4/packages/npm/
|
||||
@guardianproject-ops:registry=https://gitlab.com/api/v4/packages/npm/
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"presets": [
|
||||
"@digiresilience/babel-preset-metamigo"
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue