Bridge integration
This commit is contained in:
parent
42a5e09c94
commit
162390008b
56 changed files with 776 additions and 591 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
export default function Page() {
|
import { Home } from "bridge-ui";
|
||||||
return <h1>Home</h1>;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return <Home />;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import {
|
||||||
import { signIn } from "next-auth/react";
|
import { signIn } from "next-auth/react";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import LinkLogo from "@/app/_images/link-logo-small.png";
|
import LinkLogo from "@/app/_images/link-logo-small.png";
|
||||||
import { colors } from "ui";
|
import { colors, fonts } from "ui";
|
||||||
import { useSearchParams } from "next/navigation";
|
import { useSearchParams } from "next/navigation";
|
||||||
|
|
||||||
type LoginProps = {
|
type LoginProps = {
|
||||||
|
|
@ -34,6 +34,7 @@ export const Login: FC<LoginProps> = ({ session }) => {
|
||||||
const params = useSearchParams();
|
const params = useSearchParams();
|
||||||
const error = params.get("error");
|
const error = params.get("error");
|
||||||
const { darkGray, cdrLinkOrange, white } = colors;
|
const { darkGray, cdrLinkOrange, white } = colors;
|
||||||
|
const { poppins } = fonts;
|
||||||
const buttonStyles = {
|
const buttonStyles = {
|
||||||
borderRadius: 500,
|
borderRadius: 500,
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
|
@ -102,7 +103,7 @@ export const Login: FC<LoginProps> = ({ session }) => {
|
||||||
fontWeight: 700,
|
fontWeight: 700,
|
||||||
mt: 1,
|
mt: 1,
|
||||||
ml: 0.5,
|
ml: 0.5,
|
||||||
fontFamily: "Poppins",
|
fontFamily: poppins.style.fontFamily,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
CDR Bridge
|
CDR Bridge
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
FROM node:20 AS base
|
FROM node:20 AS base
|
||||||
|
|
||||||
FROM base AS builder
|
FROM base AS builder
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import {
|
||||||
import { signIn } from "next-auth/react";
|
import { signIn } from "next-auth/react";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import LinkLogo from "public/link-logo-small.png";
|
import LinkLogo from "public/link-logo-small.png";
|
||||||
import { colors } from "app/_styles/theme";
|
import { colors, fonts } from "ui";
|
||||||
import { useSearchParams } from "next/navigation";
|
import { useSearchParams } from "next/navigation";
|
||||||
|
|
||||||
type LoginProps = {
|
type LoginProps = {
|
||||||
|
|
@ -34,6 +34,7 @@ export const Login: FC<LoginProps> = ({ session }) => {
|
||||||
const params = useSearchParams();
|
const params = useSearchParams();
|
||||||
const error = params.get("error");
|
const error = params.get("error");
|
||||||
const { darkGray, cdrLinkOrange, white } = colors;
|
const { darkGray, cdrLinkOrange, white } = colors;
|
||||||
|
const { poppins } = fonts;
|
||||||
const buttonStyles = {
|
const buttonStyles = {
|
||||||
borderRadius: 500,
|
borderRadius: 500,
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
|
@ -102,7 +103,7 @@ export const Login: FC<LoginProps> = ({ session }) => {
|
||||||
fontWeight: 700,
|
fontWeight: 700,
|
||||||
mt: 1,
|
mt: 1,
|
||||||
ml: 0.5,
|
ml: 0.5,
|
||||||
fontFamily: "Poppins",
|
fontFamily: poppins.style.fontFamily,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
CDR Link
|
CDR Link
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ export const InternalLayout: FC<PropsWithChildren> = ({ children }) => {
|
||||||
<Sidebar open={open} setOpen={setOpen} />
|
<Sidebar open={open} setOpen={setOpen} />
|
||||||
<Grid
|
<Grid
|
||||||
item
|
item
|
||||||
sx={{ ml: open ? "270px" : "100px", width: "100%", height: "100vh" }}
|
sx={{ ml: open ? "270px" : "70px", width: "100%", height: "100vh" }}
|
||||||
>
|
>
|
||||||
{children as any}
|
{children as any}
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { usePathname, useRouter } from "next/navigation";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { Grid, Box, TextField, Autocomplete } from "@mui/material";
|
import { Grid, Box, TextField, Autocomplete } from "@mui/material";
|
||||||
import { searchQuery } from "@/app/_graphql/searchQuery";
|
import { searchQuery } from "@/app/_graphql/searchQuery";
|
||||||
import { colors } from "@/app/_styles/theme";
|
import { colors } from "ui";
|
||||||
|
|
||||||
type SearchResultProps = {
|
type SearchResultProps = {
|
||||||
props: any;
|
props: any;
|
||||||
|
|
|
||||||
|
|
@ -35,10 +35,10 @@ import LinkLogo from "public/link-logo-small.png";
|
||||||
import { useSession, signOut } from "next-auth/react";
|
import { useSession, signOut } from "next-auth/react";
|
||||||
import { getTicketOverviewCountsQuery } from "app/_graphql/getTicketOverviewCountsQuery";
|
import { getTicketOverviewCountsQuery } from "app/_graphql/getTicketOverviewCountsQuery";
|
||||||
import { SearchBox } from "./SearchBox";
|
import { SearchBox } from "./SearchBox";
|
||||||
import { fonts } from "app/_styles/theme";
|
import { fonts } from "ui";
|
||||||
|
|
||||||
const openWidth = 270;
|
const openWidth = 270;
|
||||||
const closedWidth = 100;
|
const closedWidth = 70;
|
||||||
|
|
||||||
const MenuItem = ({
|
const MenuItem = ({
|
||||||
name,
|
name,
|
||||||
|
|
@ -49,6 +49,7 @@ const MenuItem = ({
|
||||||
selected = false,
|
selected = false,
|
||||||
open = true,
|
open = true,
|
||||||
badge,
|
badge,
|
||||||
|
depth = 0,
|
||||||
target = "_self",
|
target = "_self",
|
||||||
}: any) => {
|
}: any) => {
|
||||||
const { roboto } = fonts;
|
const { roboto } = fonts;
|
||||||
|
|
@ -90,8 +91,8 @@ const MenuItem = ({
|
||||||
width: 30,
|
width: 30,
|
||||||
height: "28px",
|
height: "28px",
|
||||||
position: "relative",
|
position: "relative",
|
||||||
ml: "9px",
|
ml: "8px",
|
||||||
mr: "1px",
|
mr: "2px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
|
|
@ -114,9 +115,21 @@ const MenuItem = ({
|
||||||
border: "solid 1px #fff",
|
border: "solid 1px #fff",
|
||||||
borderColor: "transparent transparent transparent #fff",
|
borderColor: "transparent transparent transparent #fff",
|
||||||
borderRadius: "60px",
|
borderRadius: "60px",
|
||||||
rotate: "-35deg",
|
rotate: "-50deg",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
{depth > 0 && (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
width: depth * 22,
|
||||||
|
height: "1px",
|
||||||
|
backgroundColor: "white",
|
||||||
|
position: "absolute",
|
||||||
|
left: "26px",
|
||||||
|
top: "14px",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
{open && (
|
{open && (
|
||||||
|
|
@ -132,6 +145,7 @@ const MenuItem = ({
|
||||||
border: 0,
|
border: 0,
|
||||||
textAlign: "left",
|
textAlign: "left",
|
||||||
color: "white",
|
color: "white",
|
||||||
|
ml: depth * 3,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{name}
|
{name}
|
||||||
|
|
@ -220,7 +234,7 @@ export const Sidebar: FC<SidebarProps> = ({ open, setOpen }) => {
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
top: 20,
|
top: 24,
|
||||||
right: open ? -8 : -16,
|
right: open ? -8 : -16,
|
||||||
color: "#1C75FD",
|
color: "#1C75FD",
|
||||||
rotate: open ? "90deg" : "-90deg",
|
rotate: open ? "90deg" : "-90deg",
|
||||||
|
|
@ -231,8 +245,8 @@ export const Sidebar: FC<SidebarProps> = ({ open, setOpen }) => {
|
||||||
>
|
>
|
||||||
<ExpandCircleDownIcon
|
<ExpandCircleDownIcon
|
||||||
sx={{
|
sx={{
|
||||||
width: 30,
|
width: 24,
|
||||||
height: 30,
|
height: 24,
|
||||||
background: "white",
|
background: "white",
|
||||||
borderRadius: 500,
|
borderRadius: 500,
|
||||||
}}
|
}}
|
||||||
|
|
@ -338,9 +352,7 @@ export const Sidebar: FC<SidebarProps> = ({ open, setOpen }) => {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>{open && <SearchBox />}</Grid>
|
||||||
<SearchBox />
|
|
||||||
</Grid>
|
|
||||||
<Grid
|
<Grid
|
||||||
item
|
item
|
||||||
container
|
container
|
||||||
|
|
@ -558,7 +570,7 @@ export const Sidebar: FC<SidebarProps> = ({ open, setOpen }) => {
|
||||||
<>
|
<>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
name="Admin"
|
name="Admin"
|
||||||
href="/admin/zammad"
|
href="/admin/bridge"
|
||||||
Icon={SettingsIcon}
|
Icon={SettingsIcon}
|
||||||
iconSize={20}
|
iconSize={20}
|
||||||
open={open}
|
open={open}
|
||||||
|
|
@ -570,6 +582,56 @@ export const Sidebar: FC<SidebarProps> = ({ open, setOpen }) => {
|
||||||
onClick={undefined}
|
onClick={undefined}
|
||||||
>
|
>
|
||||||
<List component="div" disablePadding>
|
<List component="div" disablePadding>
|
||||||
|
<MenuItem
|
||||||
|
name="CDR Bridge"
|
||||||
|
href="/admin/bridge"
|
||||||
|
selected={pathname.endsWith("/admin/bridge")}
|
||||||
|
open={open}
|
||||||
|
/>
|
||||||
|
<Collapse
|
||||||
|
in={pathname.startsWith("/admin/bridge")}
|
||||||
|
timeout="auto"
|
||||||
|
unmountOnExit
|
||||||
|
onClick={undefined}
|
||||||
|
>
|
||||||
|
<List component="div" disablePadding>
|
||||||
|
<MenuItem
|
||||||
|
name="WhatsApp"
|
||||||
|
href="/admin/bridge/whatsapp"
|
||||||
|
depth={1}
|
||||||
|
selected={pathname.endsWith("/admin/bridge/whatsapp")}
|
||||||
|
open={open}
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
name="Signal"
|
||||||
|
href="/admin/bridge/signal"
|
||||||
|
depth={1}
|
||||||
|
selected={pathname.endsWith("/admin/bridge/signal")}
|
||||||
|
open={open}
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
name="Facebook"
|
||||||
|
href="/admin/bridge/facebook"
|
||||||
|
depth={1}
|
||||||
|
selected={pathname.endsWith("/admin/bridge/facebook")}
|
||||||
|
open={open}
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
name="Voice"
|
||||||
|
href="/admin/bridge/voice"
|
||||||
|
depth={1}
|
||||||
|
selected={pathname.endsWith("/admin/bridge/voice")}
|
||||||
|
open={open}
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
name="Webhooks"
|
||||||
|
href="/admin/bridge/webhooks"
|
||||||
|
depth={1}
|
||||||
|
selected={pathname.endsWith("/admin/bridge/webhooks")}
|
||||||
|
open={open}
|
||||||
|
/>
|
||||||
|
</List>
|
||||||
|
</Collapse>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
name="Zammad Settings"
|
name="Zammad Settings"
|
||||||
href="/admin/zammad"
|
href="/admin/zammad"
|
||||||
|
|
@ -578,16 +640,6 @@ export const Sidebar: FC<SidebarProps> = ({ open, setOpen }) => {
|
||||||
selected={pathname.endsWith("/admin/zammad")}
|
selected={pathname.endsWith("/admin/zammad")}
|
||||||
open={open}
|
open={open}
|
||||||
/>
|
/>
|
||||||
{false && roles.includes("bridge") && (
|
|
||||||
<MenuItem
|
|
||||||
name="Bridge"
|
|
||||||
href="/admin/bridge"
|
|
||||||
Icon={FeaturedPlayListIcon}
|
|
||||||
iconSize={0}
|
|
||||||
selected={pathname.endsWith("/admin/bridge")}
|
|
||||||
open={open}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{roles.includes("label_studio") && (
|
{roles.includes("label_studio") && (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
name="Label Studio"
|
name="Label Studio"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { Create } from "bridge-ui";
|
||||||
|
|
||||||
|
type PageProps = {
|
||||||
|
params: { segment: string[] };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Page({ params: { segment } }: PageProps) {
|
||||||
|
const service = segment[0];
|
||||||
|
|
||||||
|
return <Create service={service} />;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { db } from "bridge-common";
|
||||||
|
import { serviceConfig, Detail } from "bridge-ui";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
params: { segment: string[] };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default async function Page({ params: { segment } }: Props) {
|
||||||
|
const service = segment[0];
|
||||||
|
const id = segment?.[1];
|
||||||
|
|
||||||
|
if (!id) return null;
|
||||||
|
|
||||||
|
const {
|
||||||
|
[service]: { table },
|
||||||
|
} = serviceConfig;
|
||||||
|
|
||||||
|
const row = await db
|
||||||
|
.selectFrom(table)
|
||||||
|
.selectAll()
|
||||||
|
.where("id", "=", id)
|
||||||
|
.executeTakeFirst();
|
||||||
|
|
||||||
|
if (!row) return null;
|
||||||
|
|
||||||
|
return <Detail service={service} row={row} />;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { db } from "bridge-common";
|
||||||
|
import { serviceConfig, Edit } from "bridge-ui";
|
||||||
|
|
||||||
|
type PageProps = {
|
||||||
|
params: { segment: string[] };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default async function Page({ params: { segment } }: PageProps) {
|
||||||
|
const service = segment[0];
|
||||||
|
const id = segment?.[1];
|
||||||
|
|
||||||
|
if (!id) return null;
|
||||||
|
|
||||||
|
const {
|
||||||
|
[service]: { table },
|
||||||
|
} = serviceConfig;
|
||||||
|
|
||||||
|
const row = await db
|
||||||
|
.selectFrom(table)
|
||||||
|
.selectAll()
|
||||||
|
.where("id", "=", id)
|
||||||
|
.executeTakeFirst();
|
||||||
|
|
||||||
|
if (!row) return null;
|
||||||
|
|
||||||
|
return <Edit service={service} row={row} />;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
import { ServiceLayout } from "bridge-ui";
|
||||||
|
|
||||||
|
export default ServiceLayout;
|
||||||
22
apps/link/app/(main)/admin/bridge/[...segment]/page.tsx
Normal file
22
apps/link/app/(main)/admin/bridge/[...segment]/page.tsx
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { db } from "bridge-common";
|
||||||
|
import { serviceConfig, List } from "bridge-ui";
|
||||||
|
|
||||||
|
type PageProps = {
|
||||||
|
params: {
|
||||||
|
segment: string[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default async function Page({ params: { segment } }: PageProps) {
|
||||||
|
const service = segment[0];
|
||||||
|
|
||||||
|
if (!service) return null;
|
||||||
|
|
||||||
|
const config = serviceConfig[service];
|
||||||
|
|
||||||
|
if (!config) return null;
|
||||||
|
|
||||||
|
const rows = await db.selectFrom(config.table).selectAll().execute();
|
||||||
|
|
||||||
|
return <List service={service} rows={rows} />;
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
// import { Admin } from "./_components/Admin";
|
import { Home } from "bridge-ui";
|
||||||
import { Box } from "@mui/material";
|
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return <Box />;
|
return <Home />;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,10 @@ export const DocsWrapper: FC = () => (
|
||||||
sx={{ height: "100%", width: "100%" }}
|
sx={{ height: "100%", width: "100%" }}
|
||||||
direction="column"
|
direction="column"
|
||||||
>
|
>
|
||||||
<Grid item sx={{ height: "100vh", width: "100%" }}>
|
<Grid
|
||||||
|
item
|
||||||
|
sx={{ height: "calc(100vh + 120px)", width: "100%", mt: "-121px" }}
|
||||||
|
>
|
||||||
<Iframe
|
<Iframe
|
||||||
id="docs"
|
id="docs"
|
||||||
url={"https://digiresilience.org/docs/link/about/"}
|
url={"https://digiresilience.org/docs/link/about/"}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ export const dynamic = "force-dynamic";
|
||||||
export default async function Page() {
|
export default async function Page() {
|
||||||
return (
|
return (
|
||||||
<LeafcutterWrapper>
|
<LeafcutterWrapper>
|
||||||
<Home visualizations={{}} />
|
<Home visualizations={[]} showWelcome={false} />
|
||||||
</LeafcutterWrapper>
|
</LeafcutterWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,11 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { FC, useState } from "react";
|
import { FC } from "react";
|
||||||
import {
|
import { useFormState } from "react-dom";
|
||||||
Grid,
|
import { Grid } from "@mui/material";
|
||||||
Button,
|
import { Dialog, Button, TextField, Autocomplete } from "ui";
|
||||||
Dialog,
|
import { createTicketAction } from "app/_actions/tickets";
|
||||||
DialogActions,
|
import useSWR from "swr";
|
||||||
DialogContent,
|
|
||||||
TextField,
|
|
||||||
Autocomplete,
|
|
||||||
} from "@mui/material";
|
|
||||||
import useSWR, { useSWRConfig } from "swr";
|
|
||||||
import { createTicketMutation } from "app/_graphql/createTicketMutation";
|
|
||||||
|
|
||||||
interface TicketCreateDialogProps {
|
interface TicketCreateDialogProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
|
|
@ -22,133 +16,83 @@ export const TicketCreateDialog: FC<TicketCreateDialogProps> = ({
|
||||||
open,
|
open,
|
||||||
closeDialog,
|
closeDialog,
|
||||||
}) => {
|
}) => {
|
||||||
const [kind, setKind] = useState("note");
|
const initialState = {
|
||||||
const [customerID, setCustomerID] = useState("");
|
messages: [],
|
||||||
const [groupID, setGroupID] = useState("");
|
errors: [],
|
||||||
const [ownerID, setOwnerID] = useState("");
|
values: {
|
||||||
const [priorityID, setPriorityID] = useState("");
|
customerId: "",
|
||||||
const [stateID, setStateID] = useState("");
|
groupId: "",
|
||||||
const [tags, setTags] = useState([]);
|
ownerId: "",
|
||||||
const [title, setTitle] = useState("");
|
priorityId: "",
|
||||||
const [body, setBody] = useState("");
|
stateId: "",
|
||||||
const backgroundColor = "#1982FC";
|
tags: [],
|
||||||
const color = "white";
|
title: "",
|
||||||
const { fetcher } = useSWRConfig();
|
|
||||||
const ticket = {
|
|
||||||
customerId: customerID,
|
|
||||||
groupId: groupID,
|
|
||||||
ownerId: ownerID,
|
|
||||||
priorityId: priorityID,
|
|
||||||
stateId: stateID,
|
|
||||||
tags,
|
|
||||||
title,
|
|
||||||
article: {
|
article: {
|
||||||
body,
|
body: "",
|
||||||
type: kind,
|
type: "note",
|
||||||
internal: kind === "note",
|
internal: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
const [formState, formAction] = useFormState(
|
||||||
|
createTicketAction,
|
||||||
|
initialState,
|
||||||
|
);
|
||||||
const { data: users, error: usersError }: any = useSWR({
|
const { data: users, error: usersError }: any = useSWR({
|
||||||
url: "/api/v1/users",
|
url: "/api/v1/users",
|
||||||
method: "GET",
|
method: "GET",
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log({ users, usersError });
|
|
||||||
|
|
||||||
const customers =
|
const customers =
|
||||||
users?.filter((user: any) => user.role_ids.includes(3)) ?? [];
|
users?.filter((user: any) => user.role_ids.includes(3)) ?? [];
|
||||||
const formattedCustomers = customers.map((customer: any) => ({
|
const formattedCustomers = customers.map((customer: any) => ({
|
||||||
label: customer.login,
|
label: customer.login,
|
||||||
id: `${customer.id}`,
|
id: `${customer.id}`,
|
||||||
}));
|
}));
|
||||||
const createTicket = async () => {
|
|
||||||
await fetcher({
|
|
||||||
document: createTicketMutation,
|
|
||||||
variables: {
|
|
||||||
input: {
|
|
||||||
ticket,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
closeDialog();
|
|
||||||
setBody("");
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} maxWidth="md" fullWidth>
|
<Dialog
|
||||||
<DialogContent>
|
title="Create Ticket"
|
||||||
<Grid container direction="column" spacing={2}>
|
open={open}
|
||||||
<Grid item>
|
onClose={closeDialog}
|
||||||
<TextField
|
formAction={formAction}
|
||||||
label={"Title"}
|
buttons={
|
||||||
fullWidth
|
|
||||||
value={title}
|
|
||||||
onChange={(e: any) => setTitle(e.target.value)}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item>
|
|
||||||
<Autocomplete
|
|
||||||
disablePortal
|
|
||||||
options={formattedCustomers}
|
|
||||||
value={customerID}
|
|
||||||
sx={{ width: 300 }}
|
|
||||||
onChange={(e: any) => setCustomerID(e.target.value.id)}
|
|
||||||
renderInput={(params) => (
|
|
||||||
<TextField {...params} label="Customer" />
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid item>
|
|
||||||
<TextField
|
|
||||||
label={"Details"}
|
|
||||||
multiline
|
|
||||||
rows={10}
|
|
||||||
fullWidth
|
|
||||||
value={body}
|
|
||||||
onChange={(e: any) => setBody(e.target.value)}
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</DialogContent>
|
|
||||||
<DialogActions sx={{ px: 3, pt: 0, pb: 3 }}>
|
|
||||||
<Grid container justifyContent="space-between">
|
<Grid container justifyContent="space-between">
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Button
|
<Button
|
||||||
sx={{
|
text="Cancel"
|
||||||
backgroundColor: "white",
|
kind="secondary"
|
||||||
color: "#666",
|
|
||||||
fontFamily: "Poppins, sans-serif",
|
|
||||||
fontWeight: 700,
|
|
||||||
borderRadius: 2,
|
|
||||||
textTransform: "none",
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setBody("");
|
|
||||||
closeDialog();
|
closeDialog();
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Button
|
<Button text="Save" type="submit" kind="primary" />
|
||||||
sx={{
|
</Grid>
|
||||||
backgroundColor,
|
</Grid>
|
||||||
color,
|
}
|
||||||
fontFamily: "Poppins, sans-serif",
|
|
||||||
fontWeight: 700,
|
|
||||||
borderRadius: 2,
|
|
||||||
textTransform: "none",
|
|
||||||
px: 3,
|
|
||||||
}}
|
|
||||||
onClick={createTicket}
|
|
||||||
>
|
>
|
||||||
Create Ticket
|
<Grid container direction="column" spacing={3}>
|
||||||
</Button>
|
<Grid item>
|
||||||
|
<Autocomplete
|
||||||
|
name="customerId"
|
||||||
|
label="Customer"
|
||||||
|
options={formattedCustomers}
|
||||||
|
formState={formState}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item>
|
||||||
|
<TextField name="title" label="Title" formState={formState} />
|
||||||
|
</Grid>
|
||||||
|
<Grid item>
|
||||||
|
<TextField
|
||||||
|
name="details"
|
||||||
|
label="Details"
|
||||||
|
lines={10}
|
||||||
|
formState={formState}
|
||||||
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@ import { FC, useState } from "react";
|
||||||
import { Grid, Box } from "@mui/material";
|
import { Grid, Box } from "@mui/material";
|
||||||
import { GridColDef } from "@mui/x-data-grid-pro";
|
import { GridColDef } from "@mui/x-data-grid-pro";
|
||||||
import { StyledDataGrid } from "app/(main)/_components/StyledDataGrid";
|
import { StyledDataGrid } from "app/(main)/_components/StyledDataGrid";
|
||||||
import { Button } from "app/_components/Button";
|
import { Button, List, typography } from "ui";
|
||||||
import { typography } from "app/_styles/theme";
|
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { TicketCreateDialog } from "./TicketCreateDialog";
|
import { TicketCreateDialog } from "./TicketCreateDialog";
|
||||||
|
|
||||||
|
|
@ -26,83 +25,61 @@ export const TicketList: FC<TicketListProps> = ({ title, tickets }) => {
|
||||||
{
|
{
|
||||||
field: "title",
|
field: "title",
|
||||||
headerName: "Title",
|
headerName: "Title",
|
||||||
flex: 5,
|
flex: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: "customer",
|
field: "customer",
|
||||||
headerName: "Sender",
|
headerName: "Sender",
|
||||||
valueGetter: (params: any) => params.row?.customer?.fullname,
|
valueGetter: (value: any) => value?.fullname,
|
||||||
flex: 2,
|
flex: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: "createdAt",
|
field: "createdAt",
|
||||||
headerName: "Created At",
|
headerName: "Created At",
|
||||||
valueGetter: (params: any) =>
|
valueGetter: (value: any) => new Date(value).toLocaleString(),
|
||||||
new Date(params.row?.createdAt).toLocaleString(),
|
|
||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: "updatedAt",
|
field: "updatedAt",
|
||||||
headerName: "Updated At",
|
headerName: "Updated At",
|
||||||
valueGetter: (params: any) =>
|
valueGetter: (value: any) => new Date(value).toLocaleString(),
|
||||||
new Date(params.row?.updatedAt).toLocaleString(),
|
|
||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: "group",
|
field: "group",
|
||||||
headerName: "Group",
|
headerName: "Group",
|
||||||
valueGetter: (params: any) => params.row?.group?.name,
|
valueGetter: (value: any) => value?.name,
|
||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const rowClick = ({ row }) => {
|
const onRowClick = (id: any) => {
|
||||||
router.push(`/tickets/${row.internalId}`);
|
router.push(`/tickets/${id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Box sx={{ height: "100vh", backgroundColor: "#ddd", p: 3 }}>
|
<List
|
||||||
<Grid container direction="column">
|
title={title}
|
||||||
<Grid
|
rows={tickets}
|
||||||
item
|
columns={gridColumns}
|
||||||
container
|
onRowClick={onRowClick}
|
||||||
direction="row"
|
getRowID={(row: any) => {
|
||||||
justifyContent="space-between"
|
console.log({ row });
|
||||||
alignItems="center"
|
return row.internalId;
|
||||||
>
|
|
||||||
<Grid item>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
backgroundColor: "#ddd",
|
|
||||||
px: "8px",
|
|
||||||
pb: "16px",
|
|
||||||
...typography.h4,
|
|
||||||
fontSize: 24,
|
|
||||||
}}
|
}}
|
||||||
>
|
buttons={
|
||||||
{title}
|
<Grid container direction="row-reverse" alignItems="center">
|
||||||
</Box>
|
|
||||||
</Grid>
|
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Button
|
<Button
|
||||||
href={""}
|
|
||||||
onClick={() => setDialogOpen(true)}
|
onClick={() => setDialogOpen(true)}
|
||||||
text="Create"
|
text="Create"
|
||||||
color="#1982FC"
|
color="primary"
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
}
|
||||||
<StyledDataGrid
|
|
||||||
name={title}
|
|
||||||
columns={gridColumns}
|
|
||||||
rows={tickets}
|
|
||||||
onRowClick={rowClick}
|
|
||||||
/>
|
/>
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Box>
|
|
||||||
<TicketCreateDialog
|
<TicketCreateDialog
|
||||||
open={dialogOpen}
|
open={dialogOpen}
|
||||||
closeDialog={() => setDialogOpen(false)}
|
closeDialog={() => setDialogOpen(false)}
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,6 @@ export const ZammadOverview: FC<ZammadOverviewProps> = ({ name }) => {
|
||||||
}, [name]);
|
}, [name]);
|
||||||
|
|
||||||
const shouldRender = tickets && !error;
|
const shouldRender = tickets && !error;
|
||||||
console.log({ shouldRender, tickets, error });
|
|
||||||
return shouldRender && <TicketList title={name} tickets={tickets} />;
|
return shouldRender && <TicketList title={name} tickets={tickets} />;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,12 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { FC, useEffect, useState } from "react";
|
import { FC, useState } from "react";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { getTicketQuery } from "app/_graphql/getTicketQuery";
|
import { getTicketQuery } from "app/_graphql/getTicketQuery";
|
||||||
import { getTicketArticlesQuery } from "app/_graphql/getTicketArticlesQuery";
|
import { getTicketArticlesQuery } from "app/_graphql/getTicketArticlesQuery";
|
||||||
import {
|
import { Grid, Box, Typography } from "@mui/material";
|
||||||
Grid,
|
import { Button, fonts, colors } from "ui";
|
||||||
Box,
|
|
||||||
Typography,
|
|
||||||
Button,
|
|
||||||
// Dialog,
|
|
||||||
// DialogActions,
|
|
||||||
// DialogContent,
|
|
||||||
} from "@mui/material";
|
|
||||||
import "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css";
|
import "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css";
|
||||||
import {
|
import {
|
||||||
MainContainer,
|
MainContainer,
|
||||||
|
|
@ -28,6 +22,8 @@ interface TicketDetailProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TicketDetail: FC<TicketDetailProps> = ({ id }) => {
|
export const TicketDetail: FC<TicketDetailProps> = ({ id }) => {
|
||||||
|
const { poppins, roboto } = fonts;
|
||||||
|
const { veryLightGray, lightGray } = colors;
|
||||||
const [dialogOpen, setDialogOpen] = useState(false);
|
const [dialogOpen, setDialogOpen] = useState(false);
|
||||||
const [articleKind, setArticleKind] = useState("note");
|
const [articleKind, setArticleKind] = useState("note");
|
||||||
const { data: ticketData, error: ticketError }: any = useSWR(
|
const { data: ticketData, error: ticketError }: any = useSWR(
|
||||||
|
|
@ -52,7 +48,6 @@ export const TicketDetail: FC<TicketDetailProps> = ({ id }) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const closeDialog = () => setDialogOpen(false);
|
const closeDialog = () => setDialogOpen(false);
|
||||||
console.log({ recentViewData, recentViewError });
|
|
||||||
|
|
||||||
const ticket = ticketData?.ticket;
|
const ticket = ticketData?.ticket;
|
||||||
const ticketArticles = ticketArticlesData?.ticketArticles;
|
const ticketArticles = ticketArticlesData?.ticketArticles;
|
||||||
|
|
@ -79,13 +74,19 @@ export const TicketDetail: FC<TicketDetailProps> = ({ id }) => {
|
||||||
>
|
>
|
||||||
<Typography
|
<Typography
|
||||||
variant="h5"
|
variant="h5"
|
||||||
sx={{ fontFamily: "Poppins", fontWeight: 700 }}
|
sx={{
|
||||||
|
fontFamily: poppins.style.fontFamily,
|
||||||
|
fontWeight: 700,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{ticket.title}
|
{ticket.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography
|
<Typography
|
||||||
variant="h6"
|
variant="h6"
|
||||||
sx={{ fontFamily: "Roboto", fontWeight: 400 }}
|
sx={{
|
||||||
|
fontFamily: roboto.style.fontFamily,
|
||||||
|
fontWeight: 400,
|
||||||
|
}}
|
||||||
>{`Ticket #${ticket.number} (created ${new Date(
|
>{`Ticket #${ticket.number} (created ${new Date(
|
||||||
ticket.createdAt,
|
ticket.createdAt,
|
||||||
).toLocaleDateString()})`}</Typography>
|
).toLocaleDateString()})`}</Typography>
|
||||||
|
|
@ -118,8 +119,8 @@ export const TicketDetail: FC<TicketDetailProps> = ({ id }) => {
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
height: 80,
|
height: 80,
|
||||||
background: "#eeeeee",
|
background: veryLightGray,
|
||||||
borderTop: "1px solid #ddd",
|
borderTop: `1px solid ${lightGray}`,
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
|
@ -128,59 +129,31 @@ export const TicketDetail: FC<TicketDetailProps> = ({ id }) => {
|
||||||
>
|
>
|
||||||
<Grid
|
<Grid
|
||||||
container
|
container
|
||||||
spacing={4}
|
spacing={6}
|
||||||
justifyContent="center"
|
justifyContent="center"
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
alignContent="center"
|
alignContent="center"
|
||||||
|
sx={{ height: "100%", pt: 6 }}
|
||||||
>
|
>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
text="Write note to agent"
|
||||||
disableElevation
|
color="#FFB620"
|
||||||
sx={{
|
|
||||||
fontFamily: "Poppins, sans-serif",
|
|
||||||
fontWeight: 700,
|
|
||||||
borderRadius: 2,
|
|
||||||
textTransform: "none",
|
|
||||||
backgroundColor: "#1982FC",
|
|
||||||
padding: "6px 30px",
|
|
||||||
margin: "20px 0px",
|
|
||||||
whiteSpace: "nowrap",
|
|
||||||
py: "10px",
|
|
||||||
mt: 2,
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
setArticleKind(firstArticleKind);
|
|
||||||
setDialogOpen(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Reply to ticket
|
|
||||||
</Button>
|
|
||||||
</Grid>
|
|
||||||
<Grid item>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
disableElevation
|
|
||||||
sx={{
|
|
||||||
fontFamily: "Poppins, sans-serif",
|
|
||||||
fontWeight: 700,
|
|
||||||
borderRadius: 2,
|
|
||||||
textTransform: "none",
|
|
||||||
color: "black",
|
|
||||||
backgroundColor: "#FFB620",
|
|
||||||
padding: "6px 30px",
|
|
||||||
margin: "20px 0px",
|
|
||||||
whiteSpace: "nowrap",
|
|
||||||
py: "10px",
|
|
||||||
mt: 2,
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setArticleKind("note");
|
setArticleKind("note");
|
||||||
setDialogOpen(true);
|
setDialogOpen(true);
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
Write note to agent
|
</Grid>
|
||||||
</Button>
|
<Grid item>
|
||||||
|
<Button
|
||||||
|
text="Reply to ticket"
|
||||||
|
kind="primary"
|
||||||
|
onClick={() => {
|
||||||
|
setArticleKind(firstArticleKind);
|
||||||
|
setDialogOpen(true);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,23 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { FC, useEffect, useState } from "react";
|
import { FC, useEffect, useState } from "react";
|
||||||
import {
|
import { Grid, Box, MenuItem } from "@mui/material";
|
||||||
Grid,
|
import { useFormState } from "react-dom";
|
||||||
Box,
|
import { Select, Button } from "ui";
|
||||||
// Typography,
|
|
||||||
// TextField,
|
|
||||||
// Stack,
|
|
||||||
Select,
|
|
||||||
MenuItem,
|
|
||||||
} from "@mui/material";
|
|
||||||
import { MuiChipsInput } from "mui-chips-input";
|
import { MuiChipsInput } from "mui-chips-input";
|
||||||
import useSWR, { useSWRConfig } from "swr";
|
import useSWR, { useSWRConfig } from "swr";
|
||||||
import { getTicketQuery } from "app/_graphql/getTicketQuery";
|
import { getTicketQuery } from "app/_graphql/getTicketQuery";
|
||||||
import { updateTicketMutation } from "app/_graphql/updateTicketMutation";
|
|
||||||
import { updateTagsMutation } from "app/_graphql/updateTagsMutation";
|
|
||||||
import "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css";
|
|
||||||
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
|
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
|
||||||
|
import { updateTicketAction } from "app/_actions/tickets";
|
||||||
|
|
||||||
interface TicketEditProps {
|
interface TicketEditProps {
|
||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TicketEdit: FC<TicketEditProps> = ({ id }) => {
|
export const TicketEdit: FC<TicketEditProps> = ({ id }) => {
|
||||||
const [selectedGroup, setSelectedGroup] = useState("");
|
const selectedTags = [];
|
||||||
const [selectedOwner, setSelectedOwner] = useState("");
|
const pendingVisible = false;
|
||||||
const [selectedPriority, setSelectedPriority] = useState("");
|
const pendingDate = new Date();
|
||||||
const [selectedState, setSelectedState] = useState("");
|
|
||||||
const [pendingDate, setPendingDate] = useState(new Date());
|
|
||||||
const [pendingVisible, setPendingVisible] = useState(false);
|
|
||||||
const [selectedTags, setSelectedTags] = useState([]);
|
|
||||||
const handleDelete = () => {
|
const handleDelete = () => {
|
||||||
console.info("You clicked the delete icon.");
|
console.info("You clicked the delete icon.");
|
||||||
};
|
};
|
||||||
|
|
@ -58,24 +46,28 @@ export const TicketEdit: FC<TicketEditProps> = ({ id }) => {
|
||||||
const ticket = ticketData?.ticket;
|
const ticket = ticketData?.ticket;
|
||||||
if (ticket) {
|
if (ticket) {
|
||||||
const groupID = ticket.group.id?.split("/").pop();
|
const groupID = ticket.group.id?.split("/").pop();
|
||||||
setSelectedGroup(groupID);
|
// setSelectedGroup(groupID);
|
||||||
const ownerID = ticket.owner.id?.split("/").pop();
|
const ownerID = ticket.owner.id?.split("/").pop();
|
||||||
setSelectedOwner(ownerID);
|
// setSelectedOwner(ownerID);
|
||||||
const priorityID = ticket.priority.id?.split("/").pop();
|
const priorityID = ticket.priority.id?.split("/").pop();
|
||||||
setSelectedPriority(priorityID);
|
// setSelectedPriority(priorityID);
|
||||||
const stateID = ticket.state.id?.split("/").pop();
|
const stateID = ticket.state.id?.split("/").pop();
|
||||||
setSelectedState(stateID);
|
// setSelectedState(stateID);
|
||||||
setSelectedTags(ticket.tags);
|
// setSelectedTags(ticket.tags);
|
||||||
}
|
}
|
||||||
}, [ticketData, ticketError]);
|
}, [ticketData, ticketError]);
|
||||||
|
|
||||||
|
/*
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
const stateName = filteredStates?.find(
|
const stateName = filteredStates?.find(
|
||||||
(state: any) => state.id === selectedState,
|
(state: any) => state.id === selectedState,
|
||||||
)?.name;
|
)?.name;
|
||||||
setPendingVisible(stateName?.includes("pending") ?? false);
|
setPendingVisible(stateName?.includes("pending") ?? false);
|
||||||
}, [selectedState]);
|
}, [selectedState]);
|
||||||
|
*/
|
||||||
const updateTicket = async (input: any) => {
|
const updateTicket = async (input: any) => {
|
||||||
|
/*
|
||||||
console.log({ input });
|
console.log({ input });
|
||||||
const res = await fetcher({
|
const res = await fetcher({
|
||||||
document: updateTicketMutation,
|
document: updateTicketMutation,
|
||||||
|
|
@ -85,8 +77,10 @@ export const TicketEdit: FC<TicketEditProps> = ({ id }) => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
console.log({ res });
|
console.log({ res });
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
const updateTags = async (tags: string[]) => {
|
const updateTags = async (tags: string[]) => {
|
||||||
|
/*
|
||||||
console.log({ tags });
|
console.log({ tags });
|
||||||
const res = await fetcher({
|
const res = await fetcher({
|
||||||
document: updateTagsMutation,
|
document: updateTagsMutation,
|
||||||
|
|
@ -96,18 +90,50 @@ export const TicketEdit: FC<TicketEditProps> = ({ id }) => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
console.log({ res });
|
console.log({ res });
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
const initialState = {
|
||||||
|
messages: [],
|
||||||
|
errors: [],
|
||||||
|
values: {
|
||||||
|
customer: "",
|
||||||
|
group: "",
|
||||||
|
owner: "",
|
||||||
|
priority: "",
|
||||||
|
state: "",
|
||||||
|
tags: [],
|
||||||
|
title: "",
|
||||||
|
article: {
|
||||||
|
body: "",
|
||||||
|
type: "note",
|
||||||
|
internal: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const [formState, formAction] = useFormState(
|
||||||
|
updateTicketAction,
|
||||||
|
initialState,
|
||||||
|
);
|
||||||
const shouldRender = ticketData && !ticketError;
|
const shouldRender = ticketData && !ticketError;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
shouldRender && (
|
shouldRender && (
|
||||||
<Box sx={{ height: "100vh", background: "#ddd", p: 2 }}>
|
<Box sx={{ height: "100vh", background: "#ddd", p: 2 }}>
|
||||||
|
<form action={formAction}>
|
||||||
<Grid container direction="column" spacing={3}>
|
<Grid container direction="column" spacing={3}>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Box sx={{ m: 1 }}>Group</Box>
|
<Box sx={{ m: 1 }}>Group</Box>
|
||||||
<Select
|
<Select
|
||||||
defaultValue={selectedGroup}
|
name="group"
|
||||||
value={selectedGroup}
|
label="Group"
|
||||||
|
formState={formState}
|
||||||
|
getOptions={() =>
|
||||||
|
groups?.map((group: any) => ({
|
||||||
|
value: group.id,
|
||||||
|
label: group.name,
|
||||||
|
})) ?? []
|
||||||
|
}
|
||||||
|
/*
|
||||||
onChange={(e: any) => {
|
onChange={(e: any) => {
|
||||||
const newGroup = e.target.value;
|
const newGroup = e.target.value;
|
||||||
setSelectedGroup(newGroup);
|
setSelectedGroup(newGroup);
|
||||||
|
|
@ -115,45 +141,43 @@ export const TicketEdit: FC<TicketEditProps> = ({ id }) => {
|
||||||
groupId: `gid://zammad/Group/${newGroup}`,
|
groupId: `gid://zammad/Group/${newGroup}`,
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
size="small"
|
*/
|
||||||
sx={{
|
/>
|
||||||
width: "100%",
|
|
||||||
backgroundColor: "white",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{groups?.map((group: any) => (
|
|
||||||
<MenuItem key={group.id} value={`${group.id}`}>
|
|
||||||
{group.name}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Box sx={{ m: 1, mt: 0 }}>Owner</Box>
|
<Box sx={{ m: 1, mt: 0 }}>Owner</Box>
|
||||||
<Select
|
<Select
|
||||||
value={selectedOwner}
|
name="owner"
|
||||||
|
label="Owner"
|
||||||
|
formState={formState}
|
||||||
|
getOptions={() =>
|
||||||
|
agents?.map((user: any) => ({
|
||||||
|
value: user.id,
|
||||||
|
label: `${user.firstname} ${user.lastname}`,
|
||||||
|
})) ?? []
|
||||||
|
}
|
||||||
|
/*
|
||||||
onChange={(e: any) => {
|
onChange={(e: any) => {
|
||||||
const newOwner = e.target.value;
|
const newOwner = e.target.value;
|
||||||
setSelectedOwner(newOwner);
|
setSelectedOwner(newOwner);
|
||||||
updateTicket({ ownerId: `gid://zammad/User/${newOwner}` });
|
updateTicket({ ownerId: `gid://zammad/User/${newOwner}` });
|
||||||
}}
|
}}
|
||||||
size="small"
|
*/
|
||||||
sx={{
|
/>
|
||||||
width: "100%",
|
|
||||||
backgroundColor: "white",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{agents?.map((user: any) => (
|
|
||||||
<MenuItem key={user.id} value={`${user.id}`}>
|
|
||||||
{user.firstname} {user.lastname}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Box sx={{ m: 1, mt: 0 }}>State</Box>
|
<Box sx={{ m: 1, mt: 0 }}>State</Box>
|
||||||
<Select
|
<Select
|
||||||
value={selectedState}
|
name="state"
|
||||||
|
label="State"
|
||||||
|
formState={formState}
|
||||||
|
getOptions={() =>
|
||||||
|
filteredStates?.map((state: any) => ({
|
||||||
|
value: state.id,
|
||||||
|
label: state.name,
|
||||||
|
})) ?? []
|
||||||
|
}
|
||||||
|
/*
|
||||||
onChange={(e: any) => {
|
onChange={(e: any) => {
|
||||||
const newState = e.target.value;
|
const newState = e.target.value;
|
||||||
setSelectedState(newState);
|
setSelectedState(newState);
|
||||||
|
|
@ -162,64 +186,57 @@ export const TicketEdit: FC<TicketEditProps> = ({ id }) => {
|
||||||
pendingTime: pendingDate.toISOString(),
|
pendingTime: pendingDate.toISOString(),
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
size="small"
|
*/
|
||||||
sx={{
|
/>
|
||||||
width: "100%",
|
|
||||||
backgroundColor: "white",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{filteredStates?.map((state: any) => (
|
|
||||||
<MenuItem key={state.id} value={state.id}>
|
|
||||||
{state.name}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid
|
<Grid
|
||||||
item
|
item
|
||||||
xs={12}
|
xs={12}
|
||||||
sx={{ display: pendingVisible ? "inherit" : "none" }}
|
sx={{ display: pendingVisible ? "inherit" : "none" }}
|
||||||
>
|
>
|
||||||
<DatePicker
|
{/* <DatePicker
|
||||||
label="Pending Date"
|
label="Pending Date"
|
||||||
value={pendingDate}
|
value={pendingDate}
|
||||||
onChange={(newValue: any) => {
|
onChange={(newValue: any) => {
|
||||||
|
|
||||||
console.log(newValue);
|
console.log(newValue);
|
||||||
setPendingDate(newValue);
|
setPendingDate(newValue);
|
||||||
updateTicket({
|
updateTicket({
|
||||||
pendingTime: newValue.toISOString(),
|
pendingTime: newValue.toISOString(),
|
||||||
});
|
})
|
||||||
|
|
||||||
}}
|
}}
|
||||||
slotProps={{ textField: { size: "small" } }}
|
slotProps={{ textField: { size: "small" } }}
|
||||||
sx={{
|
sx={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
backgroundColor: "white",
|
backgroundColor: "white",
|
||||||
}}
|
}}
|
||||||
/>
|
/> */}
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Box sx={{ m: 1, mt: 0 }}>Priority</Box>
|
<Box sx={{ m: 1, mt: 0 }}>Priority</Box>
|
||||||
<Select
|
<Select
|
||||||
value={selectedPriority}
|
name="priority"
|
||||||
|
label="Priority"
|
||||||
|
formState={formState}
|
||||||
|
getOptions={() =>
|
||||||
|
priorities?.map((priority: any) => ({
|
||||||
|
value: priority.id,
|
||||||
|
label: priority.name,
|
||||||
|
})) ?? []
|
||||||
|
}
|
||||||
|
/*
|
||||||
onChange={(e: any) => {
|
onChange={(e: any) => {
|
||||||
|
|
||||||
const newPriority = e.target.value;
|
const newPriority = e.target.value;
|
||||||
setSelectedPriority(newPriority);
|
setSelectedPriority(newPriority);
|
||||||
updateTicket({
|
updateTicket({
|
||||||
priorityId: `gid://zammad/Ticket::Priority/${newPriority}`,
|
priorityId: `gid://zammad/Ticket::Priority/${newPriority}`,
|
||||||
});
|
});
|
||||||
|
|
||||||
}}
|
}}
|
||||||
size="small"
|
*/
|
||||||
sx={{
|
/>
|
||||||
width: "100%",
|
|
||||||
backgroundColor: "white",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{priorities?.map((priority: any) => (
|
|
||||||
<MenuItem key={priority.id} value={priority.id}>
|
|
||||||
{priority.name}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid item>
|
<Grid item>
|
||||||
|
|
@ -228,12 +245,20 @@ export const TicketEdit: FC<TicketEditProps> = ({ id }) => {
|
||||||
sx={{ backgroundColor: "white", width: "100%" }}
|
sx={{ backgroundColor: "white", width: "100%" }}
|
||||||
value={selectedTags}
|
value={selectedTags}
|
||||||
onChange={(tags: any) => {
|
onChange={(tags: any) => {
|
||||||
|
/*
|
||||||
setSelectedTags(tags);
|
setSelectedTags(tags);
|
||||||
updateTags(tags);
|
updateTags(tags);
|
||||||
|
*/
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Grid item container direction="row-reverse">
|
||||||
|
<Grid item>
|
||||||
|
<Button text="Save" kind="primary" type="submit" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</form>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
||||||
113
apps/link/app/_actions/tickets.ts
Normal file
113
apps/link/app/_actions/tickets.ts
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
"use server";
|
||||||
|
|
||||||
|
import { revalidatePath } from "next/cache";
|
||||||
|
import { createTicketMutation } from "app/_graphql/createTicketMutation";
|
||||||
|
import { updateTicketMutation } from "app/_graphql/updateTicketMutation";
|
||||||
|
import { updateTagsMutation } from "app/_graphql/updateTagsMutation";
|
||||||
|
// import { executeMutation } from "app/_lib/graphql";
|
||||||
|
// import { AddAssetMutation } from "../_graphql/AddAssetMutation";
|
||||||
|
|
||||||
|
export const createTicketAction = async (
|
||||||
|
currentState: any,
|
||||||
|
formData: FormData,
|
||||||
|
) => {
|
||||||
|
/*
|
||||||
|
|
||||||
|
const createTicket = async () => {
|
||||||
|
await fetcher({
|
||||||
|
document: createTicketMutation,
|
||||||
|
variables: {
|
||||||
|
input: {
|
||||||
|
ticket,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
closeDialog();
|
||||||
|
setBody("");
|
||||||
|
};
|
||||||
|
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
const ticket = {
|
||||||
|
title: formData.get("title"),
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = await executeMutation({
|
||||||
|
project,
|
||||||
|
mutation: AddAssetMutation,
|
||||||
|
variables: {
|
||||||
|
input: asset,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
revalidatePath(`/${project}/assets`);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...currentState,
|
||||||
|
values: { ...asset, ...result.addAsset, project },
|
||||||
|
success: true,
|
||||||
|
};
|
||||||
|
} catch (e: any) {
|
||||||
|
return { success: false, message: e?.message ?? "Unknown error" };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateTicketAction = async (
|
||||||
|
currentState: any,
|
||||||
|
formData: FormData,
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const { id, project } = currentState.values;
|
||||||
|
const updatedTicket = {
|
||||||
|
title: formData.get("title"),
|
||||||
|
};
|
||||||
|
await executeMutation({
|
||||||
|
project,
|
||||||
|
mutation: UpdateAssetMutation,
|
||||||
|
variables: {
|
||||||
|
id,
|
||||||
|
input: updatedAsset,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
revalidatePath(`/${project}/assets/${id}`);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...currentState,
|
||||||
|
values: { ...currentState.values, ...updatedAsset, id, project },
|
||||||
|
success: true,
|
||||||
|
};
|
||||||
|
} catch (e: any) {
|
||||||
|
return { success: false, message: e?.message ?? "Unknown error" };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateTicketTagsAction = async (
|
||||||
|
currentState: any,
|
||||||
|
formData: FormData,
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const { id, project } = currentState.values;
|
||||||
|
const updatedTicket = {
|
||||||
|
title: formData.get("title"),
|
||||||
|
};
|
||||||
|
await executeMutation({
|
||||||
|
project,
|
||||||
|
mutation: UpdateAssetMutation,
|
||||||
|
variables: {
|
||||||
|
id,
|
||||||
|
input: updatedAsset,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
revalidatePath(`/${project}/assets/${id}`);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...currentState,
|
||||||
|
values: { ...currentState.values, ...updatedAsset, id, project },
|
||||||
|
success: true,
|
||||||
|
};
|
||||||
|
} catch (e: any) {
|
||||||
|
return { success: false, message: e?.message ?? "Unknown error" };
|
||||||
|
}
|
||||||
|
};
|
||||||
3
apps/link/app/_actions/users.ts
Normal file
3
apps/link/app/_actions/users.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
"use server";
|
||||||
|
|
||||||
|
const fetchUsersAction = async () => {};
|
||||||
|
|
@ -104,23 +104,19 @@ export const MultiProvider: FC<PropsWithChildren> = ({ children }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
<CssBaseline />
|
|
||||||
<NextAppDirEmotionCacheProvider options={{ key: "css" }}>
|
<NextAppDirEmotionCacheProvider options={{ key: "css" }}>
|
||||||
|
<CssBaseline />
|
||||||
<SWRConfig value={{ fetcher: multiFetcher }}>
|
<SWRConfig value={{ fetcher: multiFetcher }}>
|
||||||
<SessionProvider>
|
<SessionProvider>
|
||||||
<CookiesProvider>
|
<CookiesProvider>
|
||||||
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||||
<I18n locale={locale} messages={messages[locale]}>
|
<I18n locale={locale} messages={messages[locale]}>
|
||||||
<LeafcutterProvider>
|
<LeafcutterProvider>{children}</LeafcutterProvider>
|
||||||
{children}
|
|
||||||
</LeafcutterProvider>
|
|
||||||
</I18n>
|
</I18n>
|
||||||
</LocalizationProvider>
|
</LocalizationProvider>
|
||||||
</CookiesProvider>
|
</CookiesProvider>
|
||||||
</SessionProvider>
|
</SessionProvider>
|
||||||
</SWRConfig>
|
</SWRConfig>
|
||||||
</NextAppDirEmotionCacheProvider>
|
</NextAppDirEmotionCacheProvider>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,113 +0,0 @@
|
||||||
import { Roboto, Playfair_Display, Poppins } from "next/font/google";
|
|
||||||
|
|
||||||
const roboto = Roboto({
|
|
||||||
weight: ["400"],
|
|
||||||
subsets: ["latin"],
|
|
||||||
display: "swap",
|
|
||||||
});
|
|
||||||
|
|
||||||
const playfair = Playfair_Display({
|
|
||||||
weight: ["900"],
|
|
||||||
subsets: ["latin"],
|
|
||||||
display: "swap",
|
|
||||||
});
|
|
||||||
|
|
||||||
const poppins = Poppins({
|
|
||||||
weight: ["400", "700"],
|
|
||||||
subsets: ["latin"],
|
|
||||||
display: "swap",
|
|
||||||
});
|
|
||||||
|
|
||||||
export const fonts = {
|
|
||||||
roboto,
|
|
||||||
playfair,
|
|
||||||
poppins,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
export const colors: any = {
|
|
||||||
lightGray: "#ededf0",
|
|
||||||
mediumGray: "#e3e5e5",
|
|
||||||
darkGray: "#33302f",
|
|
||||||
mediumBlue: "#4285f4",
|
|
||||||
green: "#349d7b",
|
|
||||||
lavender: "#a5a6f6",
|
|
||||||
darkLavender: "#5d5fef",
|
|
||||||
pink: "#fcddec",
|
|
||||||
cdrLinkOrange: "#ff7115",
|
|
||||||
coreYellow: "#fac942",
|
|
||||||
helpYellow: "#fff4d5",
|
|
||||||
dwcDarkBlue: "#191847",
|
|
||||||
hazyMint: "#ecf7f8",
|
|
||||||
leafcutterElectricBlue: "#4d6aff",
|
|
||||||
leafcutterLightBlue: "#fafbfd",
|
|
||||||
waterbearElectricPurple: "#332c83",
|
|
||||||
waterbearLightSmokePurple: "#eff3f8",
|
|
||||||
bumpedPurple: "#212058",
|
|
||||||
mutedPurple: "#373669",
|
|
||||||
warningPink: "#ef5da8",
|
|
||||||
lightPink: "#fff0f7",
|
|
||||||
lightGreen: "#f0fff3",
|
|
||||||
lightOrange: "#fff5f0",
|
|
||||||
beige: "#f6f2f1",
|
|
||||||
almostBlack: "#33302f",
|
|
||||||
white: "#ffffff",
|
|
||||||
};
|
|
||||||
|
|
||||||
export const typography: any = {
|
|
||||||
h1: {
|
|
||||||
fontFamily: playfair.style.fontFamily,
|
|
||||||
fontSize: 45,
|
|
||||||
fontWeight: 700,
|
|
||||||
lineHeight: 1.1,
|
|
||||||
margin: 0,
|
|
||||||
},
|
|
||||||
h2: {
|
|
||||||
fontFamily: poppins.style.fontFamily,
|
|
||||||
fontSize: 35,
|
|
||||||
fontWeight: 700,
|
|
||||||
lineHeight: 1.1,
|
|
||||||
margin: 0,
|
|
||||||
},
|
|
||||||
h3: {
|
|
||||||
fontFamily: poppins.style.fontFamily,
|
|
||||||
fontWeight: 400,
|
|
||||||
fontSize: 27,
|
|
||||||
lineHeight: 1.1,
|
|
||||||
margin: 0,
|
|
||||||
},
|
|
||||||
h4: {
|
|
||||||
fontFamily: poppins.style.fontFamily,
|
|
||||||
fontWeight: 700,
|
|
||||||
fontSize: 18,
|
|
||||||
},
|
|
||||||
h5: {
|
|
||||||
fontFamily: roboto.style.fontFamily,
|
|
||||||
fontWeight: 700,
|
|
||||||
fontSize: 16,
|
|
||||||
lineHeight: "24px",
|
|
||||||
textTransform: "uppercase",
|
|
||||||
textAlign: "center",
|
|
||||||
margin: 1,
|
|
||||||
},
|
|
||||||
h6: {
|
|
||||||
fontFamily: roboto.style.fontFamily,
|
|
||||||
fontWeight: 400,
|
|
||||||
fontSize: 14,
|
|
||||||
textAlign: "center",
|
|
||||||
},
|
|
||||||
p: {
|
|
||||||
fontFamily: roboto.style.fontFamily,
|
|
||||||
fontSize: 17,
|
|
||||||
lineHeight: "26.35px",
|
|
||||||
fontWeight: 400,
|
|
||||||
margin: 0,
|
|
||||||
},
|
|
||||||
small: {
|
|
||||||
fontFamily: roboto.style.fontFamily,
|
|
||||||
fontSize: 13,
|
|
||||||
lineHeight: "18px",
|
|
||||||
fontWeight: 400,
|
|
||||||
margin: 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
@ -20,11 +20,12 @@
|
||||||
"@mui/material": "^5",
|
"@mui/material": "^5",
|
||||||
"@mui/x-data-grid-pro": "^7.3.2",
|
"@mui/x-data-grid-pro": "^7.3.2",
|
||||||
"@mui/x-date-pickers-pro": "^7.3.2",
|
"@mui/x-date-pickers-pro": "^7.3.2",
|
||||||
|
"bridge-common": "*",
|
||||||
|
"bridge-ui": "*",
|
||||||
"date-fns": "^3.6.0",
|
"date-fns": "^3.6.0",
|
||||||
"graphql-request": "^6.1.0",
|
"graphql-request": "^6.1.0",
|
||||||
"leafcutter-ui": "*",
|
"leafcutter-ui": "*",
|
||||||
"material-ui-popup-state": "^5.1.0",
|
"material-ui-popup-state": "^5.1.0",
|
||||||
"bridge-ui": "*",
|
|
||||||
"mui-chips-input": "^2.1.4",
|
"mui-chips-input": "^2.1.4",
|
||||||
"next": "14.2.3",
|
"next": "14.2.3",
|
||||||
"next-auth": "^4.24.7",
|
"next-auth": "^4.24.7",
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ services:
|
||||||
container_name: leafcutter
|
container_name: leafcutter
|
||||||
restart: ${RESTART}
|
restart: ${RESTART}
|
||||||
build:
|
build:
|
||||||
context: ../../
|
context: .
|
||||||
dockerfile: ../../apps/leafcutter/Dockerfile
|
dockerfile: ../../apps/leafcutter/Dockerfile
|
||||||
image: registry.gitlab.com/digiresilience/link/link-stack/leafcutter:${LINK_STACK_VERSION}
|
image: registry.gitlab.com/digiresilience/link/link-stack/leafcutter:${LINK_STACK_VERSION}
|
||||||
expose:
|
expose:
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ services:
|
||||||
container_name: link
|
container_name: link
|
||||||
restart: ${RESTART}
|
restart: ${RESTART}
|
||||||
build:
|
build:
|
||||||
context: ../../
|
context: .
|
||||||
dockerfile: ../../apps/link/Dockerfile
|
dockerfile: ../../apps/link/Dockerfile
|
||||||
image: registry.gitlab.com/digiresilience/link/link-stack/link:${LINK_STACK_VERSION}
|
image: registry.gitlab.com/digiresilience/link/link-stack/link:${LINK_STACK_VERSION}
|
||||||
expose:
|
expose:
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
FROM memcached:1.6.23-bookworm
|
FROM memcached:1.6.27-bookworm
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
FROM nginxproxy/nginx-proxy:1.5.1
|
FROM nginxproxy/nginx-proxy:1.5.2
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
FROM opensearchproject/opensearch-dashboards:2.12.0
|
FROM opensearchproject/opensearch-dashboards:2.13.0
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
FROM opensearchproject/opensearch:2.12.0
|
FROM opensearchproject/opensearch:2.13.0
|
||||||
RUN /usr/share/opensearch/bin/opensearch-plugin install ingest-attachment -b
|
RUN /usr/share/opensearch/bin/opensearch-plugin install ingest-attachment -b
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
FROM bbernhard/signal-cli-rest-api:0.81
|
FROM bbernhard/signal-cli-rest-api:0.83
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
ARG ZAMMAD_VERSION=6.2.0
|
# need to include changes from https://github.com/zammad/zammad/blob/506c295c1d15f8dc19fc8bb69af1fb721bf10f49/contrib/docker/setup.sh
|
||||||
|
|
||||||
|
ARG ZAMMAD_VERSION=6.3.0
|
||||||
|
|
||||||
FROM node:16.18.0-slim as node
|
FROM node:16.18.0-slim as node
|
||||||
FROM zammad/zammad-docker-compose:${ZAMMAD_VERSION} AS builder
|
FROM zammad/zammad-docker-compose:${ZAMMAD_VERSION} AS builder
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import { Button, Dialog, TextField, Select, MultiValueField } from "ui";
|
||||||
import { generateCreateAction } from "../lib/actions";
|
import { generateCreateAction } from "../lib/actions";
|
||||||
import { FieldDescription } from "../lib/service";
|
import { FieldDescription } from "../lib/service";
|
||||||
import { serviceConfig } from "../config/config";
|
import { serviceConfig } from "../config/config";
|
||||||
|
import { getBasePath } from "../lib/frontendUtils";
|
||||||
|
|
||||||
type CreateProps = {
|
type CreateProps = {
|
||||||
service: string;
|
service: string;
|
||||||
|
|
@ -51,7 +52,7 @@ export const Create: FC<CreateProps> = ({ service }) => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (formState.success) {
|
if (formState.success) {
|
||||||
router.push(`/${entity}/${formState.values.id}`);
|
router.push(`${getBasePath()}${entity}/${formState.values.id}`);
|
||||||
}
|
}
|
||||||
}, [formState.success, router, entity, formState.values.id]);
|
}, [formState.success, router, entity, formState.values.id]);
|
||||||
|
|
||||||
|
|
@ -60,14 +61,14 @@ export const Create: FC<CreateProps> = ({ service }) => {
|
||||||
open
|
open
|
||||||
title={`Create ${displayName}`}
|
title={`Create ${displayName}`}
|
||||||
formAction={formAction}
|
formAction={formAction}
|
||||||
onClose={() => router.push(`/${entity}`)}
|
onClose={() => router.push(`${getBasePath()}${entity}`)}
|
||||||
buttons={
|
buttons={
|
||||||
<Grid container justifyContent="space-between">
|
<Grid container justifyContent="space-between">
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Button
|
<Button
|
||||||
text="Cancel"
|
text="Cancel"
|
||||||
kind="secondary"
|
kind="secondary"
|
||||||
onClick={() => router.push(`/${entity}`)}
|
onClick={() => router.push(`${getBasePath()}${entity}`)}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import { type Database } from "bridge-common";
|
||||||
import { generateDeleteAction } from "../lib/actions";
|
import { generateDeleteAction } from "../lib/actions";
|
||||||
import { serviceConfig } from "../config/config";
|
import { serviceConfig } from "../config/config";
|
||||||
import { FieldDescription } from "../lib/service";
|
import { FieldDescription } from "../lib/service";
|
||||||
|
import { getBasePath } from "../lib/frontendUtils";
|
||||||
|
|
||||||
type DetailProps = {
|
type DetailProps = {
|
||||||
service: string;
|
service: string;
|
||||||
|
|
@ -29,7 +30,7 @@ export const Detail: FC<DetailProps> = ({ service, row }) => {
|
||||||
const continueDeleteAction = async () => {
|
const continueDeleteAction = async () => {
|
||||||
await deleteAction?.(id);
|
await deleteAction?.(id);
|
||||||
setShowDeleteConfirmation(false);
|
setShowDeleteConfirmation(false);
|
||||||
router.push(`/${entity}`);
|
router.push(`${getBasePath()}${entity}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -37,7 +38,7 @@ export const Detail: FC<DetailProps> = ({ service, row }) => {
|
||||||
<Dialog
|
<Dialog
|
||||||
open
|
open
|
||||||
title={`${displayName} Detail`}
|
title={`${displayName} Detail`}
|
||||||
onClose={() => router.push(`/${entity}`)}
|
onClose={() => router.push(`${getBasePath()}${entity}`)}
|
||||||
buttons={
|
buttons={
|
||||||
<Grid container justifyContent="space-between">
|
<Grid container justifyContent="space-between">
|
||||||
<Grid item container xs="auto" spacing={2}>
|
<Grid item container xs="auto" spacing={2}>
|
||||||
|
|
@ -52,12 +53,16 @@ export const Detail: FC<DetailProps> = ({ service, row }) => {
|
||||||
<Button
|
<Button
|
||||||
text="Edit"
|
text="Edit"
|
||||||
kind="secondary"
|
kind="secondary"
|
||||||
href={`/${entity}/${id}/edit`}
|
href={`${getBasePath()}${entity}/${id}/edit`}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Button text="Done" kind="primary" href={`/${entity}`} />
|
<Button
|
||||||
|
text="Done"
|
||||||
|
kind="primary"
|
||||||
|
href={`${getBasePath()}${entity}`}
|
||||||
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import { type Database } from "bridge-common";
|
||||||
import { generateUpdateAction } from "../lib/actions";
|
import { generateUpdateAction } from "../lib/actions";
|
||||||
import { serviceConfig } from "../config/config";
|
import { serviceConfig } from "../config/config";
|
||||||
import { FieldDescription } from "../lib/service";
|
import { FieldDescription } from "../lib/service";
|
||||||
|
import { getBasePath } from "../lib/frontendUtils";
|
||||||
|
|
||||||
type EditProps = {
|
type EditProps = {
|
||||||
service: string;
|
service: string;
|
||||||
|
|
@ -51,7 +52,7 @@ export const Edit: FC<EditProps> = ({ service, row }) => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (formState.success) {
|
if (formState.success) {
|
||||||
router.push(`/${entity}`);
|
router.push(`${getBasePath()}${entity}`);
|
||||||
}
|
}
|
||||||
}, [formState.success, router, entity]);
|
}, [formState.success, router, entity]);
|
||||||
|
|
||||||
|
|
@ -60,14 +61,14 @@ export const Edit: FC<EditProps> = ({ service, row }) => {
|
||||||
open
|
open
|
||||||
title={`Edit ${displayName}`}
|
title={`Edit ${displayName}`}
|
||||||
formAction={formAction}
|
formAction={formAction}
|
||||||
onClose={() => router.push(`/${entity}`)}
|
onClose={() => router.push(`${getBasePath()}${entity}`)}
|
||||||
buttons={
|
buttons={
|
||||||
<Grid container justifyContent="space-between">
|
<Grid container justifyContent="space-between">
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Button
|
<Button
|
||||||
text="Cancel"
|
text="Cancel"
|
||||||
kind="secondary"
|
kind="secondary"
|
||||||
onClick={() => router.push(`/${entity}`)}
|
onClick={() => router.push(`${getBasePath()}${entity}`)}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
|
|
|
||||||
5
packages/bridge-ui/components/Home.tsx
Normal file
5
packages/bridge-ui/components/Home.tsx
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { FC } from "react";
|
||||||
|
|
||||||
|
export const Home: FC = () => {
|
||||||
|
return <h1>Home</h1>;
|
||||||
|
};
|
||||||
|
|
@ -6,6 +6,7 @@ import { List as InternalList, Button } from "ui";
|
||||||
import { type Selectable } from "kysely";
|
import { type Selectable } from "kysely";
|
||||||
import { type Database } from "bridge-common";
|
import { type Database } from "bridge-common";
|
||||||
import { serviceConfig } from "../config/config";
|
import { serviceConfig } from "../config/config";
|
||||||
|
import { getBasePath } from "../lib/frontendUtils";
|
||||||
|
|
||||||
type ListProps = {
|
type ListProps = {
|
||||||
service: string;
|
service: string;
|
||||||
|
|
@ -18,7 +19,7 @@ export const List: FC<ListProps> = ({ service, rows }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const onRowClick = (id: string) => {
|
const onRowClick = (id: string) => {
|
||||||
router.push(`/${entity}/${id}`);
|
router.push(`${getBasePath()}${entity}/${id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -28,7 +29,11 @@ export const List: FC<ListProps> = ({ service, rows }) => {
|
||||||
columns={listColumns}
|
columns={listColumns}
|
||||||
onRowClick={onRowClick}
|
onRowClick={onRowClick}
|
||||||
buttons={
|
buttons={
|
||||||
<Button text="Create" kind="primary" href={`/${entity}/create`} />
|
<Button
|
||||||
|
text="Create"
|
||||||
|
kind="primary"
|
||||||
|
href={`${getBasePath()}${entity}/create`}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -149,9 +149,14 @@ export const webhooksConfig: ServiceConfig = {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: "description",
|
field: "backendType",
|
||||||
headerName: "Description",
|
headerName: "Type",
|
||||||
flex: 2,
|
flex: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: "endpointUrl",
|
||||||
|
headerName: "Endpoint",
|
||||||
|
flex: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: "updatedAt",
|
field: "updatedAt",
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
export { Home } from "./components/Home";
|
||||||
export { List } from "./components/List";
|
export { List } from "./components/List";
|
||||||
export { Create } from "./components/Create";
|
export { Create } from "./components/Create";
|
||||||
export { Edit } from "./components/Edit";
|
export { Edit } from "./components/Edit";
|
||||||
|
|
|
||||||
10
packages/bridge-ui/lib/frontendUtils.ts
Normal file
10
packages/bridge-ui/lib/frontendUtils.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
export const getBasePath = (): string => {
|
||||||
|
if (
|
||||||
|
typeof window !== "undefined" &&
|
||||||
|
window?.location?.pathname?.includes("/admin/bridge")
|
||||||
|
) {
|
||||||
|
return "/admin/bridge/";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "/";
|
||||||
|
};
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,18 +1,27 @@
|
||||||
"use server";
|
"use server";
|
||||||
|
|
||||||
import { performLeafcutterQuery, performZammadQuery, createUserVisualization } from "opensearch-common";
|
import {
|
||||||
|
performLeafcutterQuery,
|
||||||
|
performZammadQuery,
|
||||||
|
createUserVisualization,
|
||||||
|
} from "opensearch-common";
|
||||||
|
|
||||||
export const createUserVisualizationAction = async ({visualizationID, title, description, query}: any) => {
|
export const createUserVisualizationAction = async ({
|
||||||
const email = "darren@redaranj.com";
|
visualizationID,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
query,
|
||||||
|
}: any) => {
|
||||||
|
const email = "xxx@example.com";
|
||||||
const id = await createUserVisualization({
|
const id = await createUserVisualization({
|
||||||
email,
|
email,
|
||||||
visualizationID,
|
visualizationID,
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
query
|
query,
|
||||||
});
|
});
|
||||||
return id;
|
return id;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const searchVisualizationsAction = async (
|
export const searchVisualizationsAction = async (
|
||||||
kind: string,
|
kind: string,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
import { useEffect, FC } from "react";
|
import { useEffect, FC } from "react";
|
||||||
import { useRouter, usePathname } from "next/navigation";
|
import { useRouter, usePathname } from "next/navigation";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import ReactMarkdown from "react-markdown";
|
|
||||||
import { Grid, Button } from "@mui/material";
|
import { Grid, Button } from "@mui/material";
|
||||||
import { useTranslate } from "react-polyglot";
|
import { useTranslate } from "react-polyglot";
|
||||||
import { useCookies } from "react-cookie";
|
import { useCookies } from "react-cookie";
|
||||||
|
|
@ -11,13 +10,18 @@ import { Welcome } from "./Welcome";
|
||||||
import { WelcomeDialog } from "./WelcomeDialog";
|
import { WelcomeDialog } from "./WelcomeDialog";
|
||||||
import { VisualizationCard } from "./VisualizationCard";
|
import { VisualizationCard } from "./VisualizationCard";
|
||||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||||
|
import { getBasePath } from "../lib/utils";
|
||||||
|
|
||||||
type HomeProps = {
|
type HomeProps = {
|
||||||
visualizations: any;
|
visualizations: any;
|
||||||
showWelcome?: boolean;
|
showWelcome?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Home: FC<HomeProps> = ({ visualizations = [], showWelcome = true }) => {
|
export const Home: FC<HomeProps> = ({
|
||||||
|
visualizations = [],
|
||||||
|
showWelcome = true,
|
||||||
|
}) => {
|
||||||
|
console.log("Home", visualizations);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const pathname = usePathname() ?? "";
|
const pathname = usePathname() ?? "";
|
||||||
const cookieName = "homeIntroComplete";
|
const cookieName = "homeIntroComplete";
|
||||||
|
|
@ -45,7 +49,7 @@ export const Home: FC<HomeProps> = ({ visualizations = [], showWelcome = true })
|
||||||
sx={{ pt: "22px", pb: "22px" }}
|
sx={{ pt: "22px", pb: "22px" }}
|
||||||
direction="row-reverse"
|
direction="row-reverse"
|
||||||
>
|
>
|
||||||
<Link href={`${process.env.LEAFCUTTER_BASE_PATH ?? ""}/create`} passHref>
|
<Link href={`${getBasePath()}/create`} passHref>
|
||||||
<Button
|
<Button
|
||||||
sx={{
|
sx={{
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
|
|
@ -81,7 +85,11 @@ export const Home: FC<HomeProps> = ({ visualizations = [], showWelcome = true })
|
||||||
justifyContent="center"
|
justifyContent="center"
|
||||||
>
|
>
|
||||||
<Grid item sx={{ ...h4, width: 450, textAlign: "center" }}>
|
<Grid item sx={{ ...h4, width: 450, textAlign: "center" }}>
|
||||||
<ReactMarkdown>{t("noSavedVisualizations")}</ReactMarkdown>
|
{"You don’t have any saved visualizations. Go to "}
|
||||||
|
<Link href={`${getBasePath()}/create`}>Search and Create</Link>
|
||||||
|
{" or "}
|
||||||
|
<Link href={`${getBasePath()}/trends`}>Trends</Link>
|
||||||
|
{" to get started."}
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
|
||||||
9
packages/leafcutter-ui/lib/frontendUtils.ts
Normal file
9
packages/leafcutter-ui/lib/frontendUtils.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
export const getBasePath = (): string => {
|
||||||
|
const basePath = process.env.LEAFCUTTER_BASE_PATH;
|
||||||
|
|
||||||
|
if (basePath && basePath !== "") {
|
||||||
|
return `${basePath}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
};
|
||||||
9
packages/leafcutter-ui/lib/utils.ts
Normal file
9
packages/leafcutter-ui/lib/utils.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
export const getBasePath = (): string => {
|
||||||
|
const basePath = process.env.NEXT_PUBLIC_LEAFCUTTER_BASE_PATH;
|
||||||
|
|
||||||
|
if (basePath && basePath !== "") {
|
||||||
|
return `${basePath}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
};
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -329,7 +329,7 @@ export const getUserVisualizations = async (email: string, limit: number) => {
|
||||||
url: getEmbedURL("private", getDocumentID(hit)),
|
url: getEmbedURL("private", getDocumentID(hit)),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return results;
|
return []; //results;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Global */
|
/* Global */
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
38
packages/ui/components/Autocomplete.tsx
Normal file
38
packages/ui/components/Autocomplete.tsx
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
import { FC } from "react";
|
||||||
|
import { TextField, Autocomplete as AutocompleteInternal } from "@mui/material";
|
||||||
|
import { colors } from "../styles/theme";
|
||||||
|
|
||||||
|
type AutocompleteProps = {
|
||||||
|
name: string;
|
||||||
|
label: string;
|
||||||
|
options: any[];
|
||||||
|
formState: Record<string, any>;
|
||||||
|
disabled?: boolean;
|
||||||
|
required?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Autocomplete: FC<AutocompleteProps> = ({
|
||||||
|
name,
|
||||||
|
label,
|
||||||
|
options,
|
||||||
|
formState,
|
||||||
|
disabled = false,
|
||||||
|
required = false,
|
||||||
|
}) => (
|
||||||
|
<AutocompleteInternal
|
||||||
|
disablePortal
|
||||||
|
options={options}
|
||||||
|
defaultValue={formState.values[name]}
|
||||||
|
fullWidth
|
||||||
|
size="small"
|
||||||
|
renderInput={(params) => (
|
||||||
|
<TextField
|
||||||
|
{...params}
|
||||||
|
label={label}
|
||||||
|
disabled={disabled}
|
||||||
|
required={required}
|
||||||
|
sx={{ backgroundColor: colors.white }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
@ -10,6 +10,7 @@ interface ListProps {
|
||||||
rows: any;
|
rows: any;
|
||||||
columns: GridColDef<any>[];
|
columns: GridColDef<any>[];
|
||||||
onRowClick?: (id: string) => void;
|
onRowClick?: (id: string) => void;
|
||||||
|
getRowID?: (row: any) => any;
|
||||||
buttons?: React.ReactNode;
|
buttons?: React.ReactNode;
|
||||||
paginate?: boolean;
|
paginate?: boolean;
|
||||||
}
|
}
|
||||||
|
|
@ -19,12 +20,20 @@ export const List: FC<ListProps> = ({
|
||||||
rows,
|
rows,
|
||||||
columns,
|
columns,
|
||||||
onRowClick,
|
onRowClick,
|
||||||
|
getRowID,
|
||||||
buttons,
|
buttons,
|
||||||
paginate = false,
|
paginate = false,
|
||||||
}) => {
|
}) => {
|
||||||
const { h3 } = typography;
|
const { h3 } = typography;
|
||||||
const { mediumGray, lightGray, veryLightGray, mediumBlue, white, darkGray } =
|
const { mediumGray, lightGray, veryLightGray, mediumBlue, white, darkGray } =
|
||||||
colors;
|
colors;
|
||||||
|
const getRowIDInternal = (row: any) => {
|
||||||
|
if (getRowID) {
|
||||||
|
return getRowID(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
return row.id;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ height: "100vh", backgroundColor: lightGray, p: 3 }}>
|
<Box sx={{ height: "100vh", backgroundColor: lightGray, p: 3 }}>
|
||||||
|
|
@ -92,7 +101,7 @@ export const List: FC<ListProps> = ({
|
||||||
scrollbarSize={0}
|
scrollbarSize={0}
|
||||||
disableVirtualization
|
disableVirtualization
|
||||||
disableColumnMenu
|
disableColumnMenu
|
||||||
onRowClick={(row: any) => onRowClick?.(row.id)}
|
onRowClick={({ row }: any) => onRowClick?.(getRowIDInternal(row))}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ import { fonts } from "../styles/theme";
|
||||||
// import { useSession, signOut } from "next-auth/react";
|
// import { useSession, signOut } from "next-auth/react";
|
||||||
|
|
||||||
const openWidth = 270;
|
const openWidth = 270;
|
||||||
const closedWidth = 100;
|
const closedWidth = 70;
|
||||||
|
|
||||||
const MenuItem = ({
|
const MenuItem = ({
|
||||||
name,
|
name,
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import Image from "next/image";
|
||||||
import { fonts } from "../styles/theme";
|
import { fonts } from "../styles/theme";
|
||||||
|
|
||||||
const openWidth = 270;
|
const openWidth = 270;
|
||||||
const closedWidth = 100;
|
const closedWidth = 70;
|
||||||
|
|
||||||
export const SidebarItem: FC = ({
|
export const SidebarItem: FC = ({
|
||||||
name,
|
name,
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import {
|
||||||
IconButton,
|
IconButton,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { Refresh as RefreshIcon } from "@mui/icons-material";
|
import { Refresh as RefreshIcon } from "@mui/icons-material";
|
||||||
import { colors } from "../styles/theme";
|
import { colors, fonts } from "../styles/theme";
|
||||||
|
|
||||||
type TextFieldProps = {
|
type TextFieldProps = {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
@ -28,7 +28,8 @@ export const TextField: FC<TextFieldProps> = ({
|
||||||
lines = 1,
|
lines = 1,
|
||||||
helperText,
|
helperText,
|
||||||
}) => {
|
}) => {
|
||||||
const { darkMediumGray } = colors;
|
const { darkMediumGray, white } = colors;
|
||||||
|
const { roboto } = fonts;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InternalTextField
|
<InternalTextField
|
||||||
|
|
@ -58,7 +59,8 @@ export const TextField: FC<TextFieldProps> = ({
|
||||||
) : null,
|
) : null,
|
||||||
|
|
||||||
sx: {
|
sx: {
|
||||||
backgroundColor: "#fff",
|
fontFamily: roboto.style.fontFamily,
|
||||||
|
backgroundColor: white,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ export { Button } from "./components/Button";
|
||||||
export { TextField } from "./components/TextField";
|
export { TextField } from "./components/TextField";
|
||||||
export { DisplayTextField } from "./components/DisplayTextField";
|
export { DisplayTextField } from "./components/DisplayTextField";
|
||||||
export { Select } from "./components/Select";
|
export { Select } from "./components/Select";
|
||||||
|
export { Autocomplete } from "./components/Autocomplete";
|
||||||
export { MultiValueField } from "./components/MultiValueField";
|
export { MultiValueField } from "./components/MultiValueField";
|
||||||
export { Dialog } from "./components/Dialog";
|
export { Dialog } from "./components/Dialog";
|
||||||
export { fonts, typography, colors } from "./styles/theme";
|
export { fonts, typography, colors } from "./styles/theme";
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue