Build and type fixes
This commit is contained in:
parent
d5bd58ac3e
commit
656f3fbe71
64 changed files with 1878 additions and 1501 deletions
1
.nvmrc
Normal file
1
.nvmrc
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
v20
|
||||||
15
apps/leafcutter/.gitpod.Dockerfile
vendored
15
apps/leafcutter/.gitpod.Dockerfile
vendored
|
|
@ -1,15 +0,0 @@
|
||||||
FROM gitpod/workspace-full
|
|
||||||
|
|
||||||
# set up aws
|
|
||||||
RUN rm -rf ~/.aws
|
|
||||||
RUN mkdir ~/.aws
|
|
||||||
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "/home/gitpod/awscliv2.zip"
|
|
||||||
RUN unzip ~/awscliv2.zip -d ~/awscliv2
|
|
||||||
RUN sudo ~/awscliv2/aws/install --update
|
|
||||||
RUN brew install aws-vault
|
|
||||||
|
|
||||||
RUN brew install kubectl
|
|
||||||
RUN brew install pipx
|
|
||||||
RUN pipx install aws-sso-util
|
|
||||||
RUN npm i -g prettier
|
|
||||||
RUN npm i -g npm-check-updates
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
tasks:
|
|
||||||
- init: npm install
|
|
||||||
command: npm run dev
|
|
||||||
|
|
||||||
image:
|
|
||||||
file: .gitpod.Dockerfile
|
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
import { FC } from "react";
|
import { FC, PropsWithChildren } from "react";
|
||||||
import { Box } from "@mui/material";
|
import { Box } from "@mui/material";
|
||||||
import { useAppContext } from "./AppProvider";
|
import { useAppContext } from "./AppProvider";
|
||||||
|
|
||||||
interface AboutBoxProps {
|
type AboutBoxProps = PropsWithChildren<{
|
||||||
backgroundColor: string;
|
backgroundColor: string;
|
||||||
}
|
}>;
|
||||||
|
|
||||||
export const AboutBox: FC<AboutBoxProps> = ({ backgroundColor, children }: any) => {
|
export const AboutBox: FC<AboutBoxProps> = ({
|
||||||
|
backgroundColor,
|
||||||
|
children,
|
||||||
|
}: any) => {
|
||||||
const {
|
const {
|
||||||
colors: { white },
|
colors: { white },
|
||||||
} = useAppContext();
|
} = useAppContext();
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ export const AccountButton: FC = () => {
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Image src={UserIcon} alt="account" width="30px" height="30px" />
|
<Image src={UserIcon} alt="account" width={30} height={30} />
|
||||||
</Button>
|
</Button>
|
||||||
<Menu {...bindMenu(popupState)}>
|
<Menu {...bindMenu(popupState)}>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,16 @@
|
||||||
import { FC, createContext, useContext, useReducer, useState } from "react";
|
import {
|
||||||
|
FC,
|
||||||
|
createContext,
|
||||||
|
useContext,
|
||||||
|
useReducer,
|
||||||
|
useState,
|
||||||
|
PropsWithChildren,
|
||||||
|
} from "react";
|
||||||
import { colors, typography } from "styles/theme";
|
import { colors, typography } from "styles/theme";
|
||||||
|
|
||||||
const basePath = process.env.GITLAB_CI ? "/link/link-stack/apps/leafcutter" : "";
|
const basePath = process.env.GITLAB_CI
|
||||||
|
? "/link/link-stack/apps/leafcutter"
|
||||||
|
: "";
|
||||||
const imageURL = (image: any) =>
|
const imageURL = (image: any) =>
|
||||||
typeof image === "string" ? `${basePath}${image}` : `${basePath}${image.src}`;
|
typeof image === "string" ? `${basePath}${image}` : `${basePath}${image.src}`;
|
||||||
|
|
||||||
|
|
@ -9,16 +18,16 @@ const AppContext = createContext({
|
||||||
colors,
|
colors,
|
||||||
typography,
|
typography,
|
||||||
imageURL,
|
imageURL,
|
||||||
query: null,
|
query: null as any,
|
||||||
updateQuery: null,
|
updateQuery: null as any,
|
||||||
updateQueryType: null,
|
updateQueryType: null as any,
|
||||||
replaceQuery: null,
|
replaceQuery: null as any,
|
||||||
clearQuery: null,
|
clearQuery: null as any,
|
||||||
foundCount: 0,
|
foundCount: 0,
|
||||||
setFoundCount: null,
|
setFoundCount: null as any,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const AppProvider: FC = ({ children }) => {
|
export const AppProvider: FC<PropsWithChildren> = ({ children }) => {
|
||||||
const initialState = {
|
const initialState = {
|
||||||
incidentType: {
|
incidentType: {
|
||||||
display: "Incident Type",
|
display: "Incident Type",
|
||||||
|
|
@ -82,7 +91,10 @@ export const AppProvider: FC = ({ children }) => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const reducer = (state: any, action: any) => {
|
const reducer = (state: any, action: any) => {
|
||||||
const key = action.payload ? Object.keys(action.payload)[0] : null;
|
const key = action.payload?.[0];
|
||||||
|
if (!key) {
|
||||||
|
throw new Error("Unknown key");
|
||||||
|
}
|
||||||
const newState = { ...state };
|
const newState = { ...state };
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case "UPDATE":
|
case "UPDATE":
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,19 @@ import { useRouter } from "next/router";
|
||||||
import { useTranslate } from "react-polyglot";
|
import { useTranslate } from "react-polyglot";
|
||||||
import { useAppContext } from "./AppProvider";
|
import { useAppContext } from "./AppProvider";
|
||||||
|
|
||||||
const CheckboxItem = ({ title, description, checked, onChange }) => {
|
type CheckboxItemProps = {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
checked: boolean;
|
||||||
|
onChange: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const CheckboxItem: FC<CheckboxItemProps> = ({
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
checked,
|
||||||
|
onChange,
|
||||||
|
}) => {
|
||||||
const {
|
const {
|
||||||
typography: { p, small },
|
typography: { p, small },
|
||||||
} = useAppContext();
|
} = useAppContext();
|
||||||
|
|
@ -48,10 +60,10 @@ export const GettingStartedDialog: FC = () => {
|
||||||
typography: { h4 },
|
typography: { h4 },
|
||||||
} = useAppContext();
|
} = useAppContext();
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
const [completedItems, setCompletedItems] = useState([]);
|
const [completedItems, setCompletedItems] = useState([] as any[]);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const open = router.query.tooltip?.toString() === "checklist";
|
const open = router.query.tooltip?.toString() === "checklist";
|
||||||
const toggleCompletedItem = (item) => {
|
const toggleCompletedItem = (item: any) => {
|
||||||
if (completedItems.includes(item)) {
|
if (completedItems.includes(item)) {
|
||||||
setCompletedItems(completedItems.filter((i) => i !== item));
|
setCompletedItems(completedItems.filter((i) => i !== item));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ export const LanguageSelect = () => {
|
||||||
colors: { white, leafcutterElectricBlue },
|
colors: { white, leafcutterElectricBlue },
|
||||||
} = useAppContext();
|
} = useAppContext();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const locales = { en: "English", fr: "Français" };
|
const locales: any = { en: "English", fr: "Français" };
|
||||||
const popupState = usePopupState({ variant: "popover", popupId: "language" });
|
const popupState = usePopupState({ variant: "popover", popupId: "language" });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -36,7 +36,7 @@ export const LanguageSelect = () => {
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{locales[router.locale] ?? locales.en}
|
{locales[router.locale as any] ?? locales.en}
|
||||||
<KeyboardArrowDownIcon />
|
<KeyboardArrowDownIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<Menu {...bindMenu(popupState)}>
|
<Menu {...bindMenu(popupState)}>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { FC, PropsWithChildren } from "react";
|
||||||
import { Grid, Container } from "@mui/material";
|
import { Grid, Container } from "@mui/material";
|
||||||
import CookieConsent from "react-cookie-consent";
|
import CookieConsent from "react-cookie-consent";
|
||||||
import { useCookies } from "react-cookie";
|
import { useCookies } from "react-cookie";
|
||||||
|
|
@ -7,7 +8,7 @@ import { GettingStartedDialog } from "./GettingStartedDialog";
|
||||||
import { useAppContext } from "./AppProvider";
|
import { useAppContext } from "./AppProvider";
|
||||||
// import { Footer } from "./Footer";
|
// import { Footer } from "./Footer";
|
||||||
|
|
||||||
export const Layout = ({ children }) => {
|
export const Layout: FC<PropsWithChildren> = ({ children }) => {
|
||||||
const [cookies, setCookie] = useCookies(["cookieConsent"]);
|
const [cookies, setCookie] = useCookies(["cookieConsent"]);
|
||||||
const consentGranted = cookies.cookieConsent === "true";
|
const consentGranted = cookies.cookieConsent === "true";
|
||||||
const {
|
const {
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
/* eslint-disable react/require-default-props */
|
/* eslint-disable react/require-default-props */
|
||||||
import { FC } from "react";
|
import { FC, PropsWithChildren } from "react";
|
||||||
import { Box } from "@mui/material";
|
import { Box } from "@mui/material";
|
||||||
import { useAppContext } from "./AppProvider";
|
import { useAppContext } from "./AppProvider";
|
||||||
|
|
||||||
interface PageHeaderProps {
|
type PageHeaderProps = PropsWithChildren<{
|
||||||
backgroundColor: string;
|
backgroundColor: string;
|
||||||
sx?: any;
|
sx?: any;
|
||||||
}
|
}>;
|
||||||
|
|
||||||
export const PageHeader: FC<PageHeaderProps> = ({
|
export const PageHeader: FC<PageHeaderProps> = ({
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { FC, useState } from "react";
|
import { FC, PropsWithChildren, useState } from "react";
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Grid,
|
Grid,
|
||||||
|
|
@ -29,7 +29,14 @@ interface QueryBuilderSectionProps {
|
||||||
tooltipDescription: string;
|
tooltipDescription: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Tooltip = ({ title, description, children, open }) => {
|
type TooltipProps = PropsWithChildren<{
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
children: any;
|
||||||
|
open: boolean;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
const Tooltip: FC<TooltipProps> = ({ title, description, children, open }) => {
|
||||||
const {
|
const {
|
||||||
colors: { white, leafcutterElectricBlue, almostBlack },
|
colors: { white, leafcutterElectricBlue, almostBlack },
|
||||||
typography: { h5, small },
|
typography: { h5, small },
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ export const QueryDateRangeSelector: FC<QueryDateRangeSelectorProps> = () => {
|
||||||
startDate: { values: [date] },
|
startDate: { values: [date] },
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
// @ts-ignore
|
||||||
renderInput={(params) => (
|
renderInput={(params) => (
|
||||||
<TextField
|
<TextField
|
||||||
{...params}
|
{...params}
|
||||||
|
|
@ -89,6 +90,7 @@ export const QueryDateRangeSelector: FC<QueryDateRangeSelectorProps> = () => {
|
||||||
endDate: { values: [date] },
|
endDate: { values: [date] },
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
// @ts-ignore
|
||||||
renderInput={(params) => (
|
renderInput={(params) => (
|
||||||
<TextField
|
<TextField
|
||||||
{...params}
|
{...params}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export const QueryListSelector: FC<QueryListSelectorProps> = ({
|
||||||
values,
|
values,
|
||||||
width,
|
width,
|
||||||
}) => {
|
}) => {
|
||||||
const [selectionModel, setSelectionModel] = useState([]);
|
const [selectionModel, setSelectionModel] = useState([] as any[]);
|
||||||
const {
|
const {
|
||||||
colors: { leafcutterLightBlue, pink, leafcutterElectricBlue, warningPink },
|
colors: { leafcutterLightBlue, pink, leafcutterElectricBlue, warningPink },
|
||||||
typography: { small },
|
typography: { small },
|
||||||
|
|
@ -70,19 +70,19 @@ export const QueryListSelector: FC<QueryListSelectorProps> = ({
|
||||||
rows={rows}
|
rows={rows}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
density="compact"
|
density="compact"
|
||||||
pageSize={100}
|
pageSizeOptions={[100]}
|
||||||
checkboxSelection
|
checkboxSelection
|
||||||
disableSelectionOnClick
|
disableRowSelectionOnClick
|
||||||
hideFooter
|
hideFooter
|
||||||
disableColumnMenu
|
disableColumnMenu
|
||||||
scrollbarSize={10}
|
scrollbarSize={10}
|
||||||
onSelectionModelChange={(newSelectionModel) => {
|
onRowSelectionModelChange={(newSelectionModel) => {
|
||||||
setSelectionModel(newSelectionModel);
|
setSelectionModel(newSelectionModel);
|
||||||
updateQuery({
|
updateQuery({
|
||||||
[keyName]: { values: newSelectionModel },
|
[keyName]: { values: newSelectionModel },
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
selectionModel={selectionModel}
|
rowSelectionModel={selectionModel}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ export const QueryText: FC = () => {
|
||||||
query: q,
|
query: q,
|
||||||
} = useAppContext();
|
} = useAppContext();
|
||||||
|
|
||||||
const displayNames = {
|
const displayNames: any = {
|
||||||
incidentType: t("incidentType"),
|
incidentType: t("incidentType"),
|
||||||
startDate: t("startDate"),
|
startDate: t("startDate"),
|
||||||
endDate: t("endDate"),
|
endDate: t("endDate"),
|
||||||
|
|
@ -41,6 +41,7 @@ export const QueryText: FC = () => {
|
||||||
queryType === "include" ? ` ${t("is")} ` : ` ${t("isNot")} `
|
queryType === "include" ? ` ${t("is")} ` : ` ${t("isNot")} `
|
||||||
} ${values
|
} ${values
|
||||||
.map(
|
.map(
|
||||||
|
// @ts-expect-error
|
||||||
(value: string) => `<em>${taxonomy[key]?.[value]?.display ?? ""}</em>`
|
(value: string) => `<em>${taxonomy[key]?.[value]?.display ?? ""}</em>`
|
||||||
)
|
)
|
||||||
.join(` ${t("or")} `)}</span>`;
|
.join(` ${t("or")} `)}</span>`;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export const RawDataViewer: FC<RawDataViewerProps> = ({ rows, height }) => {
|
||||||
headerName: t("date"),
|
headerName: t("date"),
|
||||||
editable: false,
|
editable: false,
|
||||||
flex: 0.7,
|
flex: 0.7,
|
||||||
valueFormatter: ({ value }) => new Date(value).toLocaleDateString(),
|
valueFormatter: ({ value }: any) => new Date(value).toLocaleDateString(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: "incident",
|
field: "incident",
|
||||||
|
|
@ -58,7 +58,10 @@ export const RawDataViewer: FC<RawDataViewerProps> = ({ rows, height }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Box sx={{ width: "100%", height }} onClick={(e: any) => e.stopPropagation()}>
|
<Box
|
||||||
|
sx={{ width: "100%", height }}
|
||||||
|
onClick={(e: any) => e.stopPropagation()}
|
||||||
|
>
|
||||||
<Grid container direction="column" spacing={2}>
|
<Grid container direction="column" spacing={2}>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<DataGridPro
|
<DataGridPro
|
||||||
|
|
@ -66,8 +69,8 @@ export const RawDataViewer: FC<RawDataViewerProps> = ({ rows, height }) => {
|
||||||
rows={rows}
|
rows={rows}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
density="compact"
|
density="compact"
|
||||||
pageSize={100}
|
pageSizeOptions={[100]}
|
||||||
disableSelectionOnClick
|
disableRowSelectionOnClick
|
||||||
hideFooter
|
hideFooter
|
||||||
disableColumnMenu
|
disableColumnMenu
|
||||||
scrollbarSize={10}
|
scrollbarSize={10}
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,9 @@ export const VisualizationBuilder: FC<VisualizationBuilderProps> = ({
|
||||||
clearQuery,
|
clearQuery,
|
||||||
} = useAppContext();
|
} = useAppContext();
|
||||||
const { visualizations } = visualizationMap;
|
const { visualizations } = visualizationMap;
|
||||||
const [selectedVisualizationType, setSelectedVisualizationType] =
|
const [selectedVisualizationType, setSelectedVisualizationType] = useState(
|
||||||
useState(null);
|
null as any
|
||||||
|
);
|
||||||
const toggleSelectedVisualizationType = (visualizationType: string) => {
|
const toggleSelectedVisualizationType = (visualizationType: string) => {
|
||||||
if (visualizationType === selectedVisualizationType) {
|
if (visualizationType === selectedVisualizationType) {
|
||||||
setSelectedVisualizationType(null);
|
setSelectedVisualizationType(null);
|
||||||
|
|
@ -72,7 +73,7 @@ export const VisualizationBuilder: FC<VisualizationBuilderProps> = ({
|
||||||
updateSearches();
|
updateSearches();
|
||||||
}, [setSavedSearches]);
|
}, [setSavedSearches]);
|
||||||
|
|
||||||
const showSavedSearchPopup = (event) => {
|
const showSavedSearchPopup = (event: any) => {
|
||||||
setAnchorEl(event.currentTarget);
|
setAnchorEl(event.currentTarget);
|
||||||
};
|
};
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
|
|
@ -104,8 +105,10 @@ export const VisualizationBuilder: FC<VisualizationBuilderProps> = ({
|
||||||
const updateSearch = (name: string) => {
|
const updateSearch = (name: string) => {
|
||||||
handleClose();
|
handleClose();
|
||||||
closeDialog();
|
closeDialog();
|
||||||
const found = savedSearches.find((search) => search.name === name);
|
const found: any = savedSearches.find(
|
||||||
replaceQuery(found.query);
|
(search: any) => search.name === name
|
||||||
|
);
|
||||||
|
replaceQuery(found?.query);
|
||||||
};
|
};
|
||||||
|
|
||||||
const clearSearch = () => clearQuery();
|
const clearSearch = () => clearQuery();
|
||||||
|
|
@ -240,7 +243,7 @@ export const VisualizationBuilder: FC<VisualizationBuilderProps> = ({
|
||||||
<ListItemText>{t("saveCurrentSearch")}</ListItemText>
|
<ListItemText>{t("saveCurrentSearch")}</ListItemText>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<Divider />
|
<Divider />
|
||||||
{savedSearches.map((savedSearch) => (
|
{savedSearches.map((savedSearch: any) => (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
key={savedSearch.name}
|
key={savedSearch.name}
|
||||||
onClick={() => updateSearch(savedSearch.name)}
|
onClick={() => updateSearch(savedSearch.name)}
|
||||||
|
|
@ -322,6 +325,7 @@ export const VisualizationBuilder: FC<VisualizationBuilderProps> = ({
|
||||||
<VisualizationSelectCard
|
<VisualizationSelectCard
|
||||||
key={key}
|
key={key}
|
||||||
visualizationType={key}
|
visualizationType={key}
|
||||||
|
// @ts-expect-error
|
||||||
title={visualizations[key].name}
|
title={visualizations[key].name}
|
||||||
enabled={
|
enabled={
|
||||||
selectedVisualizationType === key ||
|
selectedVisualizationType === key ||
|
||||||
|
|
@ -347,6 +351,7 @@ export const VisualizationBuilder: FC<VisualizationBuilderProps> = ({
|
||||||
const { id, type, title, description } = template;
|
const { id, type, title, description } = template;
|
||||||
const cleanTitle = title
|
const cleanTitle = title
|
||||||
.replace("Templated", "")
|
.replace("Templated", "")
|
||||||
|
// @ts-expect-error
|
||||||
.replace(visualizations[type].name, "");
|
.replace(visualizations[type].name, "");
|
||||||
const metricType = cleanTitle.replace(/\s/g, "").toLowerCase();
|
const metricType = cleanTitle.replace(/\s/g, "").toLowerCase();
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ export const VisualizationSelectCard: FC<VisualizationSelectCardProps> = ({
|
||||||
cdrLinkOrange,
|
cdrLinkOrange,
|
||||||
},
|
},
|
||||||
} = useAppContext();
|
} = useAppContext();
|
||||||
const images = {
|
const images: any = {
|
||||||
horizontalBar,
|
horizontalBar,
|
||||||
horizontalBarStacked,
|
horizontalBarStacked,
|
||||||
verticalBar,
|
verticalBar,
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ export const Welcome = () => {
|
||||||
const { data: session } = useSession();
|
const { data: session } = useSession();
|
||||||
const {
|
const {
|
||||||
user: { name },
|
user: { name },
|
||||||
} = session;
|
} = session as any;
|
||||||
const {
|
const {
|
||||||
colors: { white, leafcutterElectricBlue },
|
colors: { white, leafcutterElectricBlue },
|
||||||
typography: { h1, h4, p },
|
typography: { h1, h4, p },
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ export const getUserMetadata = async (username: string) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return res?.body._source;
|
return res?.body._source;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const saveUserMetadata = async (username: string, metadata: any) => {
|
export const saveUserMetadata = async (username: string, metadata: any) => {
|
||||||
const client = createClient();
|
const client = createClient();
|
||||||
|
|
@ -112,7 +112,7 @@ export const saveUserMetadata = async (username: string, metadata: any) => {
|
||||||
index: userMetadataIndexName,
|
index: userMetadataIndexName,
|
||||||
body: { doc: { username, ...metadata } }
|
body: { doc: { username, ...metadata } }
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
/* User */
|
/* User */
|
||||||
|
|
||||||
|
|
@ -130,13 +130,13 @@ const getCurrentUserIndex = async (email: string) => {
|
||||||
|
|
||||||
const indicesResponse = await client.indices.get({
|
const indicesResponse = await client.indices.get({
|
||||||
index: `.kibana_*_${userIndexName}_1`,
|
index: `.kibana_*_${userIndexName}_1`,
|
||||||
})
|
});
|
||||||
const currentUserIndex = Object.keys(indicesResponse.body)[0];
|
const currentUserIndex = Object.keys(indicesResponse.body)[0];
|
||||||
|
|
||||||
return currentUserIndex;
|
return currentUserIndex;
|
||||||
}
|
};
|
||||||
|
|
||||||
const getIndexPattern = async (index: string) => {
|
const getIndexPattern: any = async (index: string) => {
|
||||||
const client = createClient();
|
const client = createClient();
|
||||||
const query = {
|
const query = {
|
||||||
query: {
|
query: {
|
||||||
|
|
@ -335,6 +335,7 @@ export const performQuery = async (searchQuery: any, limit: number) => {
|
||||||
|
|
||||||
if (searchQuery.relativeDate.values.length > 0) {
|
if (searchQuery.relativeDate.values.length > 0) {
|
||||||
searchQuery.relativeDate.values.forEach((value: string) => {
|
searchQuery.relativeDate.values.forEach((value: string) => {
|
||||||
|
// @ts-expect-error
|
||||||
body.query.bool.must.push({
|
body.query.bool.must.push({
|
||||||
range: {
|
range: {
|
||||||
date: {
|
date: {
|
||||||
|
|
@ -347,6 +348,7 @@ export const performQuery = async (searchQuery: any, limit: number) => {
|
||||||
|
|
||||||
if (searchQuery.startDate.values.length > 0) {
|
if (searchQuery.startDate.values.length > 0) {
|
||||||
searchQuery.startDate.values.forEach((value: string) => {
|
searchQuery.startDate.values.forEach((value: string) => {
|
||||||
|
// @ts-expect-error
|
||||||
body.query.bool.must.push({
|
body.query.bool.must.push({
|
||||||
range: {
|
range: {
|
||||||
date: {
|
date: {
|
||||||
|
|
@ -359,6 +361,7 @@ export const performQuery = async (searchQuery: any, limit: number) => {
|
||||||
|
|
||||||
if (searchQuery.endDate.values.length > 0) {
|
if (searchQuery.endDate.values.length > 0) {
|
||||||
searchQuery.endDate.values.forEach((value: string) => {
|
searchQuery.endDate.values.forEach((value: string) => {
|
||||||
|
// @ts-expect-error
|
||||||
body.query.bool.must.push({
|
body.query.bool.must.push({
|
||||||
range: {
|
range: {
|
||||||
date: {
|
date: {
|
||||||
|
|
@ -370,54 +373,63 @@ export const performQuery = async (searchQuery: any, limit: number) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchQuery.incidentType.values.length > 0) {
|
if (searchQuery.incidentType.values.length > 0) {
|
||||||
|
// @ts-expect-error
|
||||||
body.query.bool.must.push({
|
body.query.bool.must.push({
|
||||||
terms: { "incident.keyword": searchQuery.incidentType.values },
|
terms: { "incident.keyword": searchQuery.incidentType.values },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchQuery.targetedGroup.values.length > 0) {
|
if (searchQuery.targetedGroup.values.length > 0) {
|
||||||
|
// @ts-expect-error
|
||||||
body.query.bool.must.push({
|
body.query.bool.must.push({
|
||||||
terms: { "targeted_group.keyword": searchQuery.targetedGroup.values },
|
terms: { "targeted_group.keyword": searchQuery.targetedGroup.values },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchQuery.platform.values.length > 0) {
|
if (searchQuery.platform.values.length > 0) {
|
||||||
|
// @ts-expect-error
|
||||||
body.query.bool.must.push({
|
body.query.bool.must.push({
|
||||||
terms: { "technology.keyword": searchQuery.platform.values },
|
terms: { "technology.keyword": searchQuery.platform.values },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchQuery.device.values.length > 0) {
|
if (searchQuery.device.values.length > 0) {
|
||||||
|
// @ts-expect-error
|
||||||
body.query.bool.must.push({
|
body.query.bool.must.push({
|
||||||
terms: { "technology.keyword": searchQuery.device.values },
|
terms: { "technology.keyword": searchQuery.device.values },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchQuery.service.values.length > 0) {
|
if (searchQuery.service.values.length > 0) {
|
||||||
|
// @ts-expect-error
|
||||||
body.query.bool.must.push({
|
body.query.bool.must.push({
|
||||||
terms: { "technology.keyword": searchQuery.service.values },
|
terms: { "technology.keyword": searchQuery.service.values },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchQuery.maker.values.length > 0) {
|
if (searchQuery.maker.values.length > 0) {
|
||||||
|
// @ts-expect-error
|
||||||
body.query.bool.must.push({
|
body.query.bool.must.push({
|
||||||
terms: { "technology.keyword": searchQuery.maker.values },
|
terms: { "technology.keyword": searchQuery.maker.values },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchQuery.subregion.values.length > 0) {
|
if (searchQuery.subregion.values.length > 0) {
|
||||||
|
// @ts-expect-error
|
||||||
body.query.bool.must.push({
|
body.query.bool.must.push({
|
||||||
terms: { "region.keyword": searchQuery.subregion.values },
|
terms: { "region.keyword": searchQuery.subregion.values },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchQuery.country.values.length > 0) {
|
if (searchQuery.country.values.length > 0) {
|
||||||
|
// @ts-expect-error
|
||||||
body.query.bool.must.push({
|
body.query.bool.must.push({
|
||||||
terms: { "country.keyword": searchQuery.country.values },
|
terms: { "country.keyword": searchQuery.country.values },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchQuery.continent.values.length > 0) {
|
if (searchQuery.continent.values.length > 0) {
|
||||||
|
// @ts-expect-error
|
||||||
body.query.bool.must.push({
|
body.query.bool.must.push({
|
||||||
terms: { "continent.keyword": searchQuery.continent.values },
|
terms: { "continent.keyword": searchQuery.continent.values },
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -13,51 +13,50 @@
|
||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/cache": "^11.10.3",
|
"@emotion/cache": "^11.11.0",
|
||||||
"@emotion/react": "^11.10.4",
|
"@emotion/react": "^11.11.0",
|
||||||
"@emotion/server": "^11.10.0",
|
"@emotion/server": "^11.11.0",
|
||||||
"@emotion/styled": "^11.10.4",
|
"@emotion/styled": "^11.11.0",
|
||||||
"@fontsource/playfair-display": "^4.5.12",
|
"@fontsource/playfair-display": "^5.0.1",
|
||||||
"@fontsource/poppins": "^4.5.10",
|
"@fontsource/poppins": "^5.0.1",
|
||||||
"@fontsource/roboto": "^4.5.8",
|
"@fontsource/roboto": "^5.0.1",
|
||||||
"@mui/icons-material": "^5",
|
"@mui/icons-material": "^5",
|
||||||
"@mui/lab": "^5.0.0-alpha.102",
|
"@mui/lab": "^5.0.0-alpha.131",
|
||||||
"@mui/material": "^5",
|
"@mui/material": "^5",
|
||||||
"@mui/styles": "^5",
|
"@mui/x-data-grid-pro": "^6.5.0",
|
||||||
"@mui/x-data-grid-pro": "^5.17.5",
|
"@mui/x-date-pickers-pro": "^6.5.0",
|
||||||
"@mui/x-date-pickers-pro": "^5.0.3",
|
|
||||||
"@opensearch-project/opensearch": "^2.0.0",
|
"@opensearch-project/opensearch": "^2.0.0",
|
||||||
"date-fns": "^2.29.3",
|
"date-fns": "^2.30.0",
|
||||||
"http-proxy-middleware": "^2.0.6",
|
"http-proxy-middleware": "^2.0.6",
|
||||||
"material-ui-popup-state": "^4.1.0",
|
"material-ui-popup-state": "^5.0.8",
|
||||||
"next": "^12.3",
|
"next": "^13.4",
|
||||||
"next-auth": "^4.12.2",
|
"next-auth": "^4.22.1",
|
||||||
"next-http-proxy-middleware": "^1.2.4",
|
"next-http-proxy-middleware": "^1.2.5",
|
||||||
"nodemailer": "^6.8.0",
|
"nodemailer": "^6.9.2",
|
||||||
"react": "^17",
|
"react": "^18",
|
||||||
"react-cookie": "^4.1.1",
|
"react-cookie": "^4.1.1",
|
||||||
"react-cookie-consent": "^8.0.1",
|
"react-cookie-consent": "^8.0.1",
|
||||||
"react-dom": "^17",
|
"react-dom": "^18",
|
||||||
"react-iframe": "^1.8.4",
|
"react-iframe": "^1.8.5",
|
||||||
"react-markdown": "^8.0.3",
|
"react-markdown": "^8.0.7",
|
||||||
"react-polyglot": "^0.7.2",
|
"react-polyglot": "^0.7.2",
|
||||||
"sharp": "^0.31.3",
|
"sharp": "^0.32.1",
|
||||||
"swr": "^1.3.0",
|
"swr": "^2.1.5",
|
||||||
"uuid": "^9.0.0"
|
"uuid": "^9.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.19.3",
|
"@babel/core": "^7.21.8",
|
||||||
"@types/react": "^17",
|
"@types/react": "^18",
|
||||||
"@types/uuid": "^8.3.4",
|
"@types/uuid": "^9.0.1",
|
||||||
"babel-loader": "^8.2.5",
|
"babel-loader": "^9.1.2",
|
||||||
"eslint": "^8.24.0",
|
"eslint": "^8.41.0",
|
||||||
"eslint-config-airbnb": "^19.0.4",
|
"eslint-config-airbnb": "^19.0.4",
|
||||||
"eslint-config-next": "^12.3.1",
|
"eslint-config-next": "^13.4.3",
|
||||||
"eslint-config-prettier": "^8.5.0",
|
"eslint-config-prettier": "^8.8.0",
|
||||||
"eslint-plugin-import": "^2.26.0",
|
"eslint-plugin-import": "^2.27.5",
|
||||||
"eslint-plugin-jsx-a11y": "^6.6.1",
|
"eslint-plugin-jsx-a11y": "^6.7.1",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"eslint-plugin-react": "^7.31.8",
|
"eslint-plugin-react": "^7.32.2",
|
||||||
"typescript": "^4.9.5"
|
"typescript": "^5.0.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,13 +22,11 @@ import "@fontsource/playfair-display/900.css";
|
||||||
import "styles/global.css";
|
import "styles/global.css";
|
||||||
import { LicenseInfo } from "@mui/x-data-grid-pro";
|
import { LicenseInfo } from "@mui/x-data-grid-pro";
|
||||||
|
|
||||||
LicenseInfo.setLicenseKey(
|
LicenseInfo.setLicenseKey(process.env.MUI_LICENSE_KEY ?? "");
|
||||||
"fd009c623acc055adb16370731be92e4T1JERVI6NDA3NTQsRVhQSVJZPTE2ODAyNTAwMTUwMDAsS0VZVkVSU0lPTj0x"
|
|
||||||
);
|
|
||||||
|
|
||||||
const clientSideEmotionCache: any = createEmotionCache();
|
const clientSideEmotionCache: any = createEmotionCache();
|
||||||
|
|
||||||
const messages = { en, fr };
|
const messages: any = { en, fr };
|
||||||
|
|
||||||
interface LeafcutterWebProps extends AppProps {
|
interface LeafcutterWebProps extends AppProps {
|
||||||
// eslint-disable-next-line react/require-default-props
|
// eslint-disable-next-line react/require-default-props
|
||||||
|
|
@ -36,7 +34,7 @@ interface LeafcutterWebProps extends AppProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
const LeafcutterWeb = (props: LeafcutterWebProps) => {
|
const LeafcutterWeb = (props: LeafcutterWebProps) => {
|
||||||
const { locale } = useRouter();
|
const { locale = "en" } = useRouter();
|
||||||
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
|
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,12 @@ import Apple from "next-auth/providers/apple";
|
||||||
export default NextAuth({
|
export default NextAuth({
|
||||||
providers: [
|
providers: [
|
||||||
Google({
|
Google({
|
||||||
clientId: process.env.GOOGLE_CLIENT_ID,
|
clientId: process.env.GOOGLE_CLIENT_ID ?? "",
|
||||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
clientSecret: process.env.GOOGLE_CLIENT_SECRET ?? "",
|
||||||
}),
|
}),
|
||||||
Apple({
|
Apple({
|
||||||
clientId: process.env.APPLE_CLIENT_ID,
|
clientId: process.env.APPLE_CLIENT_ID ?? "",
|
||||||
clientSecret: process.env.APPLE_CLIENT_SECRET
|
clientSecret: process.env.APPLE_CLIENT_SECRET ?? "",
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
secret: process.env.NEXTAUTH_SECRET,
|
secret: process.env.NEXTAUTH_SECRET,
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ import { NextApiRequest, NextApiResponse } from "next";
|
||||||
import { getToken } from "next-auth/jwt";
|
import { getToken } from "next-auth/jwt";
|
||||||
|
|
||||||
const withAuthInfo =
|
const withAuthInfo =
|
||||||
(handler) => async (req: NextApiRequest, res: NextApiResponse) => {
|
(handler: any) => async (req: NextApiRequest, res: NextApiResponse) => {
|
||||||
const session = await getToken({
|
const session: any = await getToken({
|
||||||
req,
|
req,
|
||||||
secret: process.env.NEXTAUTH_SECRET,
|
secret: process.env.NEXTAUTH_SECRET,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||||
return res.status(500).json({ message: "Only POST requests are allowed" });
|
return res.status(500).json({ message: "Only POST requests are allowed" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { email } = session;
|
const { email }: any = session;
|
||||||
const { name, query } = JSON.parse(req.body);
|
const { name, query } = JSON.parse(req.body);
|
||||||
const result = await getUserMetadata(email);
|
const result = await getUserMetadata(email);
|
||||||
const { savedSearches } = result;
|
const { savedSearches } = result;
|
||||||
|
|
@ -24,8 +24,8 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||||
savedSearches: [...savedSearches, { name, query }]
|
savedSearches: [...savedSearches, { name, query }]
|
||||||
});
|
});
|
||||||
const { savedSearches: updatedSavedSearches } = await getUserMetadata(email);
|
const { savedSearches: updatedSavedSearches } = await getUserMetadata(email);
|
||||||
return res.json(updatedSavedSearches)
|
return res.json(updatedSavedSearches);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,14 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||||
return res.status(500).json({ message: "Only POST requests are allowed" });
|
return res.status(500).json({ message: "Only POST requests are allowed" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { email } = session;
|
const { email }: any = session;
|
||||||
const { name } = JSON.parse(req.body);
|
const { name } = JSON.parse(req.body);
|
||||||
const { savedSearches } = await getUserMetadata(email);
|
const { savedSearches } = await getUserMetadata(email);
|
||||||
const updatedSavedSearches = savedSearches.filter(search => search.name !== name);
|
const updatedSavedSearches = savedSearches.filter((search: any) => search.name !== name);
|
||||||
const result = await saveUserMetadata(email, { savedSearches: updatedSavedSearches })
|
const result = await saveUserMetadata(email, { savedSearches: updatedSavedSearches });
|
||||||
|
|
||||||
return res.json({ result })
|
return res.json({ result });
|
||||||
}
|
};
|
||||||
|
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,10 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||||
return res.status(500).json({ message: "Only GET requests are allowed" });
|
return res.status(500).json({ message: "Only GET requests are allowed" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { email } = session;
|
const { email }: any = session;
|
||||||
const { savedSearches } = await getUserMetadata(email);
|
const { savedSearches } = await getUserMetadata(email);
|
||||||
|
|
||||||
return res.json(savedSearches)
|
return res.json(savedSearches);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|
|
||||||
|
|
@ -25,13 +25,14 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||||
const { id } = ticket;
|
const { id } = ticket;
|
||||||
try {
|
try {
|
||||||
const country = ticket.country[0] ?? "none";
|
const country = ticket.country[0] ?? "none";
|
||||||
|
// @ts-expect-error
|
||||||
const translatedCountry = taxonomy.country[country]?.display ?? "none";
|
const translatedCountry = taxonomy.country[country]?.display ?? "none";
|
||||||
const countryDetails = unRegions.find((c) => c.name === translatedCountry);
|
const countryDetails: any = unRegions.find((c) => c.name === translatedCountry);
|
||||||
const augmentedTicket = {
|
const augmentedTicket = {
|
||||||
...ticket,
|
...ticket,
|
||||||
region: countryDetails['sub-region']?.toLowerCase().replace(" ", "-") ?? null,
|
region: countryDetails['sub-region']?.toLowerCase().replace(" ", "-") ?? null,
|
||||||
continent: countryDetails.region?.toLowerCase().replace(" ", "-") ?? null,
|
continent: countryDetails.region?.toLowerCase().replace(" ", "-") ?? null,
|
||||||
}
|
};
|
||||||
const out = await client.create({
|
const out = await client.create({
|
||||||
id: uuid(),
|
id: uuid(),
|
||||||
index: "sample_tagged_tickets",
|
index: "sample_tagged_tickets",
|
||||||
|
|
@ -41,13 +42,13 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||||
console.log(out);
|
console.log(out);
|
||||||
succeeded.push(id);
|
succeeded.push(id);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e)
|
console.log(e);
|
||||||
failed.push(id);
|
failed.push(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const results = { succeeded, failed };
|
const results = { succeeded, failed };
|
||||||
return res.json(results)
|
return res.json(results);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,14 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||||
|
|
||||||
const { visualizationID, title, description, query } = req.body;
|
const { visualizationID, title, description, query } = req.body;
|
||||||
const id = await createUserVisualization({
|
const id = await createUserVisualization({
|
||||||
email: session.email,
|
email: session.email as string,
|
||||||
visualizationID,
|
visualizationID,
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
query
|
query
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.json({ id })
|
return res.json({ id });
|
||||||
};
|
};
|
||||||
|
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,9 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const { id } = req.body;
|
const { id } = req.body;
|
||||||
await deleteUserVisualization(session.email, id);
|
await deleteUserVisualization(session.email as string, id);
|
||||||
|
|
||||||
return res.json({ id })
|
return res.json({ id });
|
||||||
};
|
};
|
||||||
|
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,14 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||||
|
|
||||||
const { id, title, description, query } = req.body;
|
const { id, title, description, query } = req.body;
|
||||||
await updateUserVisualization({
|
await updateUserVisualization({
|
||||||
email: session.email,
|
email: session.email as string,
|
||||||
id,
|
id,
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
query
|
query
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.json({ id })
|
return res.json({ id });
|
||||||
};
|
};
|
||||||
|
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useEffect } from "react";
|
import { FC, useEffect } from "react";
|
||||||
import { GetServerSideProps, GetServerSidePropsContext } from "next";
|
import { GetServerSideProps, GetServerSidePropsContext } from "next";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { useTranslate } from "react-polyglot";
|
import { useTranslate } from "react-polyglot";
|
||||||
|
|
@ -12,7 +12,11 @@ import { useAppContext } from "components/AppProvider";
|
||||||
import { PageHeader } from "components/PageHeader";
|
import { PageHeader } from "components/PageHeader";
|
||||||
import { VisualizationBuilder } from "components/VisualizationBuilder";
|
import { VisualizationBuilder } from "components/VisualizationBuilder";
|
||||||
|
|
||||||
const Create = ({ templates }) => {
|
type CreateProps = {
|
||||||
|
templates: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Create: FC<CreateProps> = ({ templates }) => {
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
const {
|
const {
|
||||||
colors: { cdrLinkOrange },
|
colors: { cdrLinkOrange },
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { GetServerSideProps, GetServerSidePropsContext } from "next";
|
import { NextPage, GetServerSideProps, GetServerSidePropsContext } from "next";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
@ -15,7 +15,13 @@ import { WelcomeDialog } from "components/WelcomeDialog";
|
||||||
import { VisualizationCard } from "components/VisualizationCard";
|
import { VisualizationCard } from "components/VisualizationCard";
|
||||||
import { useAppContext } from "components/AppProvider";
|
import { useAppContext } from "components/AppProvider";
|
||||||
|
|
||||||
const MyVisualizations = ({ visualizations }) => {
|
type MyVisualizationsProps = {
|
||||||
|
visualizations: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
const MyVisualizations: NextPage<MyVisualizationsProps> = ({
|
||||||
|
visualizations,
|
||||||
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const cookieName = "homeIntroComplete";
|
const cookieName = "homeIntroComplete";
|
||||||
const [cookies, setCookie] = useCookies([cookieName]);
|
const [cookies, setCookie] = useCookies([cookieName]);
|
||||||
|
|
@ -85,7 +91,7 @@ const MyVisualizations = ({ visualizations }) => {
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
) : null}
|
) : null}
|
||||||
{visualizations.map((visualization, index) => (
|
{visualizations.map((visualization: any, index: number) => (
|
||||||
<VisualizationCard
|
<VisualizationCard
|
||||||
id={visualization.id}
|
id={visualization.id}
|
||||||
key={index}
|
key={index}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
|
import { NextPage } from "next";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { Box, Grid, Container, IconButton } from "@mui/material";
|
import { Box, Grid, Container, IconButton } from "@mui/material";
|
||||||
|
|
@ -9,7 +10,11 @@ import LeafcutterLogoLarge from "images/leafcutter-logo-large.png";
|
||||||
import { signIn, getSession } from "next-auth/react";
|
import { signIn, getSession } from "next-auth/react";
|
||||||
import { useAppContext } from "components/AppProvider";
|
import { useAppContext } from "components/AppProvider";
|
||||||
|
|
||||||
const Login = ({ session }) => {
|
type LoginProps = {
|
||||||
|
session: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Login: NextPage<LoginProps> = ({ session }) => {
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
const {
|
const {
|
||||||
colors: { leafcutterElectricBlue, lightGray },
|
colors: { leafcutterElectricBlue, lightGray },
|
||||||
|
|
@ -112,7 +117,7 @@ const Login = ({ session }) => {
|
||||||
|
|
||||||
export default Login;
|
export default Login;
|
||||||
|
|
||||||
export async function getServerSideProps(context) {
|
export async function getServerSideProps(context: any) {
|
||||||
const session = (await getSession(context)) ?? null;
|
const session = (await getSession(context)) ?? null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
import { FC, useLayoutEffect } from "react";
|
import { useLayoutEffect } from "react";
|
||||||
|
import { NextPage, GetServerSideProps, GetServerSidePropsContext } from "next";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { Grid, CircularProgress } from "@mui/material";
|
import { Grid, CircularProgress } from "@mui/material";
|
||||||
import Iframe from "react-iframe";
|
import Iframe from "react-iframe";
|
||||||
import { useAppContext } from "components/AppProvider";
|
import { useAppContext } from "components/AppProvider";
|
||||||
|
import { checkAuth } from "lib/checkAuth";
|
||||||
|
|
||||||
export const Setup: FC = () => {
|
const Setup: NextPage = () => {
|
||||||
const {
|
const {
|
||||||
colors: { leafcutterElectricBlue },
|
colors: { leafcutterElectricBlue },
|
||||||
} = useAppContext();
|
} = useAppContext();
|
||||||
|
|
@ -44,3 +46,7 @@ export const Setup: FC = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Setup;
|
export default Setup;
|
||||||
|
|
||||||
|
export const getServerSideProps: GetServerSideProps = async (
|
||||||
|
context: GetServerSidePropsContext
|
||||||
|
) => checkAuth(context);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { GetServerSideProps, GetServerSidePropsContext } from "next";
|
import { NextPage, GetServerSideProps, GetServerSidePropsContext } from "next";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { Grid, Box } from "@mui/material";
|
import { Grid, Box } from "@mui/material";
|
||||||
import { useTranslate } from "react-polyglot";
|
import { useTranslate } from "react-polyglot";
|
||||||
|
|
@ -9,7 +9,11 @@ import { PageHeader } from "components/PageHeader";
|
||||||
import { VisualizationCard } from "components/VisualizationCard";
|
import { VisualizationCard } from "components/VisualizationCard";
|
||||||
import { useAppContext } from "components/AppProvider";
|
import { useAppContext } from "components/AppProvider";
|
||||||
|
|
||||||
const Trends = ({ visualizations }) => {
|
type TrendsProps = {
|
||||||
|
visualizations: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Trends: NextPage<TrendsProps> = ({ visualizations }) => {
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
const {
|
const {
|
||||||
colors: { cdrLinkOrange },
|
colors: { cdrLinkOrange },
|
||||||
|
|
@ -58,7 +62,7 @@ const Trends = ({ visualizations }) => {
|
||||||
spacing={3}
|
spacing={3}
|
||||||
justifyContent="space-between"
|
justifyContent="space-between"
|
||||||
>
|
>
|
||||||
{visualizations.map((visualization, index) => (
|
{visualizations.map((visualization: any, index: number) => (
|
||||||
<VisualizationCard
|
<VisualizationCard
|
||||||
key={index}
|
key={index}
|
||||||
id={visualization.id}
|
id={visualization.id}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,16 @@
|
||||||
/* eslint-disable no-underscore-dangle */
|
/* eslint-disable no-underscore-dangle */
|
||||||
import { GetServerSideProps, GetServerSidePropsContext } from "next";
|
import { NextPage, GetServerSideProps, GetServerSidePropsContext } from "next";
|
||||||
import { Client } from "@opensearch-project/opensearch";
|
import { Client } from "@opensearch-project/opensearch";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { Layout } from "components/Layout";
|
import { Layout } from "components/Layout";
|
||||||
import { VisualizationDetail } from "components/VisualizationDetail";
|
import { VisualizationDetail } from "components/VisualizationDetail";
|
||||||
import { checkAuth } from "lib/checkAuth";
|
import { checkAuth } from "lib/checkAuth";
|
||||||
|
|
||||||
const Visualization = ({ visualization }) => (
|
type VisualizationProps = {
|
||||||
|
visualization: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Visualization: NextPage<VisualizationProps> = ({ visualization }) => (
|
||||||
<Layout>
|
<Layout>
|
||||||
<Head>
|
<Head>
|
||||||
<title>Digital Threat Dashboard – Leafcutter</title>
|
<title>Digital Threat Dashboard – Leafcutter</title>
|
||||||
|
|
@ -43,7 +47,8 @@ export const getServerSideProps: GetServerSideProps = async (
|
||||||
const response = rawResponse.body;
|
const response = rawResponse.body;
|
||||||
|
|
||||||
const hits = response.hits.hits.filter(
|
const hits = response.hits.hits.filter(
|
||||||
(hit) => hit._id.split(":")[1] === visualizationID[0]
|
// @ts-expect-error
|
||||||
|
(hit: any) => hit._id.split(":")[1] === visualizationID[0]
|
||||||
);
|
);
|
||||||
const hit = hits[0];
|
const hit = hits[0];
|
||||||
res.props.visualization = {
|
res.props.visualization = {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"strict": false,
|
"strict": true,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
|
|
|
||||||
76
apps/link/components/InternalZammadWrapper.tsx
Normal file
76
apps/link/components/InternalZammadWrapper.tsx
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
import { FC, useState } from "react";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
import Iframe from "react-iframe";
|
||||||
|
|
||||||
|
type InternalZammadWrapperProps = {
|
||||||
|
path: string;
|
||||||
|
hideSidebar?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const InternalZammadWrapper: FC<InternalZammadWrapperProps> = ({
|
||||||
|
path,
|
||||||
|
hideSidebar = true,
|
||||||
|
}) => {
|
||||||
|
const router = useRouter();
|
||||||
|
const [display, setDisplay] = useState("none");
|
||||||
|
const url = `${origin}/zammad${path}`;
|
||||||
|
console.log({ origin, path, url });
|
||||||
|
|
||||||
|
return (
|
||||||
|
// @ts-ignore
|
||||||
|
<Iframe
|
||||||
|
id="link"
|
||||||
|
url={url}
|
||||||
|
width="100%"
|
||||||
|
height="100%"
|
||||||
|
frameBorder={0}
|
||||||
|
styles={{ display }}
|
||||||
|
onLoad={() => {
|
||||||
|
const linkElement = document.querySelector("iframe");
|
||||||
|
if (
|
||||||
|
linkElement.contentDocument &&
|
||||||
|
linkElement.contentDocument?.querySelector &&
|
||||||
|
linkElement.contentDocument.querySelector("#navigation") &&
|
||||||
|
linkElement.contentDocument.querySelector("body") &&
|
||||||
|
linkElement.contentDocument.querySelector(".sidebar")
|
||||||
|
) {
|
||||||
|
// @ts-ignore
|
||||||
|
linkElement.contentDocument.querySelector("#navigation").style =
|
||||||
|
"display: none";
|
||||||
|
// @ts-ignore
|
||||||
|
linkElement.contentDocument.querySelector("body").style =
|
||||||
|
"font-family: Arial";
|
||||||
|
|
||||||
|
if (hideSidebar) {
|
||||||
|
// @ts-ignore
|
||||||
|
linkElement.contentDocument.querySelector(".sidebar").style =
|
||||||
|
"display: none";
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
if (linkElement.contentDocument.querySelector(".overview-header")) {
|
||||||
|
// @ts-ignore
|
||||||
|
linkElement.contentDocument.querySelector(".overview-header").style =
|
||||||
|
"display: none";
|
||||||
|
}
|
||||||
|
|
||||||
|
setDisplay("inherit");
|
||||||
|
|
||||||
|
if (linkElement.contentWindow) {
|
||||||
|
linkElement.contentWindow.addEventListener('hashchange', () => {
|
||||||
|
const hash = linkElement.contentWindow?.location?.hash ?? ""
|
||||||
|
if (hash.startsWith("#ticket/zoom/")) {
|
||||||
|
setDisplay("none");
|
||||||
|
const ticketID = hash.split("/").pop();
|
||||||
|
router.push(`/tickets/${ticketID}`);
|
||||||
|
setTimeout(() => {
|
||||||
|
setDisplay("inherit");
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -1,6 +1,12 @@
|
||||||
import { FC, useState } from "react";
|
import { FC } from "react";
|
||||||
import { useRouter } from "next/router";
|
import dynamic from "next/dynamic";
|
||||||
import Iframe from "react-iframe";
|
|
||||||
|
const InternalZammadWrapper = dynamic(
|
||||||
|
import("./InternalZammadWrapper").then((mod) => mod.InternalZammadWrapper),
|
||||||
|
{
|
||||||
|
ssr: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
type ZammadWrapperProps = {
|
type ZammadWrapperProps = {
|
||||||
path: string;
|
path: string;
|
||||||
|
|
@ -9,72 +15,5 @@ type ZammadWrapperProps = {
|
||||||
|
|
||||||
export const ZammadWrapper: FC<ZammadWrapperProps> = ({
|
export const ZammadWrapper: FC<ZammadWrapperProps> = ({
|
||||||
path,
|
path,
|
||||||
hideSidebar = true,
|
hideSidebar,
|
||||||
}) => {
|
}) => <InternalZammadWrapper path={path} hideSidebar={hideSidebar} />;
|
||||||
const router = useRouter();
|
|
||||||
const origin =
|
|
||||||
typeof window !== "undefined" && window.location.origin
|
|
||||||
? window.location.origin
|
|
||||||
: "";
|
|
||||||
const [display, setDisplay] = useState("none");
|
|
||||||
const url = `${origin}/zammad${path}`;
|
|
||||||
console.log({ origin, path, url });
|
|
||||||
|
|
||||||
return (
|
|
||||||
// @ts-ignore
|
|
||||||
<Iframe
|
|
||||||
id="link"
|
|
||||||
url={url}
|
|
||||||
width="100%"
|
|
||||||
height="100%"
|
|
||||||
frameBorder={0}
|
|
||||||
styles={{ display }}
|
|
||||||
onLoad={() => {
|
|
||||||
const linkElement = document.querySelector("iframe");
|
|
||||||
if (
|
|
||||||
linkElement.contentDocument &&
|
|
||||||
linkElement.contentDocument?.querySelector &&
|
|
||||||
linkElement.contentDocument.querySelector("#navigation") &&
|
|
||||||
linkElement.contentDocument.querySelector("body") &&
|
|
||||||
linkElement.contentDocument.querySelector(".sidebar")
|
|
||||||
) {
|
|
||||||
// @ts-ignore
|
|
||||||
linkElement.contentDocument.querySelector("#navigation").style =
|
|
||||||
"display: none";
|
|
||||||
// @ts-ignore
|
|
||||||
linkElement.contentDocument.querySelector("body").style =
|
|
||||||
"font-family: Arial";
|
|
||||||
|
|
||||||
if (hideSidebar) {
|
|
||||||
// @ts-ignore
|
|
||||||
linkElement.contentDocument.querySelector(".sidebar").style =
|
|
||||||
"display: none";
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
if (linkElement.contentDocument.querySelector(".overview-header")) {
|
|
||||||
// @ts-ignore
|
|
||||||
linkElement.contentDocument.querySelector(".overview-header").style =
|
|
||||||
"display: none";
|
|
||||||
}
|
|
||||||
|
|
||||||
setDisplay("inherit");
|
|
||||||
|
|
||||||
if (linkElement.contentWindow) {
|
|
||||||
linkElement.contentWindow.addEventListener('hashchange', () => {
|
|
||||||
const hash = linkElement.contentWindow?.location?.hash ?? ""
|
|
||||||
if (hash.startsWith("#ticket/zoom/")) {
|
|
||||||
setDisplay("none");
|
|
||||||
const ticketID = hash.split("/").pop();
|
|
||||||
router.push(`/tickets/${ticketID}`);
|
|
||||||
setTimeout(() => {
|
|
||||||
setDisplay("inherit");
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
|
||||||
30
apps/link/middleware.ts
Normal file
30
apps/link/middleware.ts
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { withAuth } from "next-auth/middleware";
|
||||||
|
|
||||||
|
export default withAuth(
|
||||||
|
() => { },
|
||||||
|
{
|
||||||
|
pages: {
|
||||||
|
signIn: `/login`,
|
||||||
|
},
|
||||||
|
callbacks: {
|
||||||
|
authorized: ({ token, req }) => {
|
||||||
|
const {
|
||||||
|
url,
|
||||||
|
headers,
|
||||||
|
} = req;
|
||||||
|
|
||||||
|
// check login page
|
||||||
|
const parsedURL = new URL(url);
|
||||||
|
if (parsedURL.pathname.startsWith('/login')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check session auth
|
||||||
|
const authorizedDomains = ["redaranj.com", "digiresilience.org"];
|
||||||
|
const userDomain = token?.email?.toLowerCase().split("@").pop() ?? "unauthorized.net";
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
reactStrictMode: true,
|
||||||
rewrites: async () => ({
|
rewrites: async () => ({
|
||||||
fallback: [
|
fallback: [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -11,45 +11,45 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chatscope/chat-ui-kit-react": "^1.10.1",
|
"@chatscope/chat-ui-kit-react": "^1.10.1",
|
||||||
"@chatscope/chat-ui-kit-styles": "^1.4.0",
|
"@chatscope/chat-ui-kit-styles": "^1.4.0",
|
||||||
"@emotion/cache": "^11.10.5",
|
"@emotion/cache": "^11.11.0",
|
||||||
"@emotion/react": "^11.10.5",
|
"@emotion/react": "^11.11.0",
|
||||||
"@emotion/server": "^11.10.0",
|
"@emotion/server": "^11.11.0",
|
||||||
"@emotion/styled": "^11.10.5",
|
"@emotion/styled": "^11.11.0",
|
||||||
"@fontsource/playfair-display": "^4.5.13",
|
"@fontsource/playfair-display": "^5.0.1",
|
||||||
"@fontsource/poppins": "^4.5.10",
|
"@fontsource/poppins": "^5.0.1",
|
||||||
"@fontsource/roboto": "^4.5.8",
|
"@fontsource/roboto": "^5.0.1",
|
||||||
"@mui/icons-material": "^5",
|
"@mui/icons-material": "^5",
|
||||||
"@mui/lab": "^5.0.0-alpha.118",
|
"@mui/lab": "^5.0.0-alpha.131",
|
||||||
"@mui/material": "^5",
|
"@mui/material": "^5",
|
||||||
"@mui/x-data-grid-pro": "^5.17.22",
|
"@mui/x-data-grid-pro": "^6.5.0",
|
||||||
"@mui/x-date-pickers-pro": "^5.0.17",
|
"@mui/x-date-pickers-pro": "^6.5.0",
|
||||||
"date-fns": "^2.29.3",
|
"date-fns": "^2.30.0",
|
||||||
"graphql-request": "^5.2.0",
|
"graphql-request": "^6.1.0",
|
||||||
"http-proxy-middleware": "^2.0.6",
|
"http-proxy-middleware": "^2.0.6",
|
||||||
"material-ui-popup-state": "^5.0.4",
|
"material-ui-popup-state": "^5.0.8",
|
||||||
"next": "^12",
|
"next": "^13",
|
||||||
"next-auth": "^4.19.2",
|
"next-auth": "^4.22.1",
|
||||||
"next-http-proxy-middleware": "^1.2.5",
|
"next-http-proxy-middleware": "^1.2.5",
|
||||||
"react": "^17",
|
"react": "^18",
|
||||||
"react-dom": "^17",
|
"react-dom": "^18",
|
||||||
"react-iframe": "^1.8.5",
|
"react-iframe": "^1.8.5",
|
||||||
"react-polyglot": "^0.7.2",
|
"react-polyglot": "^0.7.2",
|
||||||
"sharp": "^0.30.7",
|
"sharp": "^0.32.1",
|
||||||
"swr": "^2.0.3"
|
"swr": "^2.1.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.20.12",
|
"@babel/core": "^7.21.8",
|
||||||
"@types/react": "^18",
|
"@types/react": "^18",
|
||||||
"@types/uuid": "^9.0.0",
|
"@types/uuid": "^9.0.1",
|
||||||
"babel-loader": "^9.1.2",
|
"babel-loader": "^9.1.2",
|
||||||
"eslint": "^8.33.0",
|
"eslint": "^8.41.0",
|
||||||
"eslint-config-airbnb": "^19.0.4",
|
"eslint-config-airbnb": "^19.0.4",
|
||||||
"eslint-config-next": "^13.1.6",
|
"eslint-config-next": "^13.4.3",
|
||||||
"eslint-config-prettier": "^8.6.0",
|
"eslint-config-prettier": "^8.8.0",
|
||||||
"eslint-plugin-import": "^2.27.5",
|
"eslint-plugin-import": "^2.27.5",
|
||||||
"eslint-plugin-jsx-a11y": "^6.7.1",
|
"eslint-plugin-jsx-a11y": "^6.7.1",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"eslint-plugin-react": "^7.32.2",
|
"eslint-plugin-react": "^7.32.2",
|
||||||
"typescript": "^4.9.5"
|
"typescript": "^5.0.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
13
apps/link/pages/404.tsx
Normal file
13
apps/link/pages/404.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { FC } from "react";
|
||||||
|
import Head from "next/head";
|
||||||
|
import { Layout } from "components/Layout";
|
||||||
|
|
||||||
|
const FourOhFour: FC = () => (
|
||||||
|
<Layout>
|
||||||
|
<Head>
|
||||||
|
<title>Link Shell</title>
|
||||||
|
</Head>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default FourOhFour;
|
||||||
13
apps/link/pages/500.tsx
Normal file
13
apps/link/pages/500.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { FC } from "react";
|
||||||
|
import Head from "next/head";
|
||||||
|
import { Layout } from "components/Layout";
|
||||||
|
|
||||||
|
const FiveHundred: FC = () => (
|
||||||
|
<Layout>
|
||||||
|
<Head>
|
||||||
|
<title>Link Shell</title>
|
||||||
|
</Head>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default FiveHundred;
|
||||||
|
|
@ -17,9 +17,7 @@ import { LicenseInfo } from "@mui/x-data-grid-pro";
|
||||||
import { SWRConfig } from "swr";
|
import { SWRConfig } from "swr";
|
||||||
import { GraphQLClient } from "graphql-request";
|
import { GraphQLClient } from "graphql-request";
|
||||||
|
|
||||||
LicenseInfo.setLicenseKey(
|
LicenseInfo.setLicenseKey(process.env.MUI_LICENSE_KEY);
|
||||||
"fd009c623acc055adb16370731be92e4T1JERVI6NDA3NTQsRVhQSVJZPTE2ODAyNTAwMTUwMDAsS0VZVkVSU0lPTj0x"
|
|
||||||
);
|
|
||||||
|
|
||||||
const clientSideEmotionCache: any = createEmotionCache();
|
const clientSideEmotionCache: any = createEmotionCache();
|
||||||
|
|
||||||
|
|
@ -28,15 +26,18 @@ interface LinkWebProps extends AppProps {
|
||||||
emotionCache?: EmotionCache;
|
emotionCache?: EmotionCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
const LinkWeb = (props: LinkWebProps) => {
|
export default function LinkWeb(props: LinkWebProps) {
|
||||||
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
|
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
|
||||||
|
|
||||||
const [csrfToken, setCsrfToken] = useState("");
|
const [csrfToken, setCsrfToken] = useState("");
|
||||||
const origin = typeof window !== 'undefined' && window.location.origin
|
const origin =
|
||||||
? window.location.origin : null;
|
typeof window !== "undefined" && window.location.origin
|
||||||
|
? window.location.origin
|
||||||
|
: null;
|
||||||
const client = new GraphQLClient(`${origin}/graphql`, {
|
const client = new GraphQLClient(`${origin}/graphql`, {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"Accept": "application/json",
|
Accept: "application/json",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const graphQLFetcher = async ({ document, variables }: any) => {
|
const graphQLFetcher = async ({ document, variables }: any) => {
|
||||||
|
|
@ -49,7 +50,7 @@ const LinkWeb = (props: LinkWebProps) => {
|
||||||
requestHeaders
|
requestHeaders
|
||||||
);
|
);
|
||||||
|
|
||||||
const token = headers.get('CSRF-Token');
|
const token = headers.get("CSRF-Token");
|
||||||
setCsrfToken(token);
|
setCsrfToken(token);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|
@ -67,6 +68,4 @@ const LinkWeb = (props: LinkWebProps) => {
|
||||||
</CacheProvider>
|
</CacheProvider>
|
||||||
</SessionProvider>
|
</SessionProvider>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
export default LinkWeb;
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
// @ts-nocheck
|
|
||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { Grid } from "@mui/material";
|
import { Grid } from "@mui/material";
|
||||||
|
|
@ -30,3 +29,5 @@ const LabelStudio: FC = () => (
|
||||||
);
|
);
|
||||||
|
|
||||||
export default LabelStudio;
|
export default LabelStudio;
|
||||||
|
|
||||||
|
export const getServerSideProps = async (context: any) => {};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
// @ts-nocheck
|
|
||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { Grid } from "@mui/material";
|
import { Grid } from "@mui/material";
|
||||||
|
|
@ -30,3 +29,5 @@ const Metamigo: FC = () => (
|
||||||
);
|
);
|
||||||
|
|
||||||
export default Metamigo;
|
export default Metamigo;
|
||||||
|
|
||||||
|
export const getServerSideProps = async (context: any) => {};
|
||||||
|
|
|
||||||
|
|
@ -29,3 +29,5 @@ const Zammad: FC = () => (
|
||||||
);
|
);
|
||||||
|
|
||||||
export default Zammad;
|
export default Zammad;
|
||||||
|
|
||||||
|
export const getServerSideProps = async (context: any) => {};
|
||||||
|
|
|
||||||
|
|
@ -28,3 +28,5 @@ const Home = () => (
|
||||||
);
|
);
|
||||||
|
|
||||||
export default Home;
|
export default Home;
|
||||||
|
|
||||||
|
export const getServerSideProps = async (context: any) => {};
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
// @ts-nocheck
|
|
||||||
import { FC, useState } from "react";
|
import { FC, useState } from "react";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { Grid, Button } from "@mui/material";
|
import { Grid } from "@mui/material";
|
||||||
import { Layout } from "components/Layout";
|
import { Layout } from "components/Layout";
|
||||||
import Iframe from "react-iframe";
|
import Iframe from "react-iframe";
|
||||||
|
|
||||||
|
|
@ -35,3 +34,5 @@ const About: FC = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default About;
|
export default About;
|
||||||
|
|
||||||
|
export const getServerSideProps = async (context: any) => {};
|
||||||
|
|
|
||||||
|
|
@ -35,3 +35,5 @@ const Create: FC = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Create;
|
export default Create;
|
||||||
|
|
||||||
|
export const getServerSideProps = async (context: any) => {};
|
||||||
|
|
|
||||||
|
|
@ -35,3 +35,5 @@ const FAQ: FC = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FAQ;
|
export default FAQ;
|
||||||
|
|
||||||
|
export const getServerSideProps = async (context: any) => {};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
// @ts-nocheck
|
|
||||||
import { FC, useState } from "react";
|
import { FC, useState } from "react";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { Grid, Button } from "@mui/material";
|
import { Grid, Button } from "@mui/material";
|
||||||
|
|
@ -35,3 +34,5 @@ const Leafcutter: FC = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Leafcutter;
|
export default Leafcutter;
|
||||||
|
|
||||||
|
export const getServerSideProps = async (context: any) => {};
|
||||||
|
|
|
||||||
|
|
@ -35,3 +35,5 @@ const Trends: FC = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Trends;
|
export default Trends;
|
||||||
|
|
||||||
|
export const getServerSideProps = async (context: any) => {};
|
||||||
|
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
import Head from "next/head";
|
|
||||||
import { Grid } from "@mui/material";
|
|
||||||
import { Layout } from "components/Layout";
|
|
||||||
import { ZammadWrapper } from "components/ZammadWrapper";
|
|
||||||
|
|
||||||
const Link = () => (
|
|
||||||
<Layout>
|
|
||||||
<Head>
|
|
||||||
<title>Link Shell</title>
|
|
||||||
</Head>
|
|
||||||
<Grid
|
|
||||||
container
|
|
||||||
spacing={0}
|
|
||||||
sx={{ height: "100%", width: "100%" }}
|
|
||||||
direction="column"
|
|
||||||
>
|
|
||||||
<Grid
|
|
||||||
item
|
|
||||||
sx={{
|
|
||||||
height: "100%",
|
|
||||||
width: "100%",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ZammadWrapper path="/zammad/#ticket/zoom/518/1490" />
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Layout>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default Link;
|
|
||||||
|
|
@ -1,12 +1,18 @@
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
|
import { FC } from "react";
|
||||||
import { Box, Grid, Container, IconButton } from "@mui/material";
|
import { Box, Grid, Container, IconButton } from "@mui/material";
|
||||||
import { Apple as AppleIcon, Google as GoogleIcon } from "@mui/icons-material";
|
import { Apple as AppleIcon, Google as GoogleIcon } from "@mui/icons-material";
|
||||||
import { signIn, getSession } from "next-auth/react";
|
import { signIn, getSession } from "next-auth/react";
|
||||||
|
|
||||||
const Login = ({ session }) => {
|
type LoginProps = {
|
||||||
const origin = typeof window !== 'undefined' && window.location.origin
|
session: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Login: FC<LoginProps> = ({ session }) => {
|
||||||
|
const origin =
|
||||||
|
typeof window !== "undefined" && window.location.origin
|
||||||
? window.location.origin
|
? window.location.origin
|
||||||
: '';
|
: "";
|
||||||
const buttonStyles = {
|
const buttonStyles = {
|
||||||
borderRadius: 500,
|
borderRadius: 500,
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
|
|
||||||
|
|
@ -29,3 +29,5 @@ const Profile: NextPage = () => (
|
||||||
);
|
);
|
||||||
|
|
||||||
export default Profile;
|
export default Profile;
|
||||||
|
|
||||||
|
export const getServerSideProps = async (context: any) => {};
|
||||||
|
|
|
||||||
|
|
@ -29,3 +29,5 @@ const Assigned: FC = () => (
|
||||||
);
|
);
|
||||||
|
|
||||||
export default Assigned;
|
export default Assigned;
|
||||||
|
|
||||||
|
export const getServerSideProps = async (context: any) => {};
|
||||||
|
|
|
||||||
|
|
@ -29,3 +29,5 @@ const Pending: FC = () => (
|
||||||
);
|
);
|
||||||
|
|
||||||
export default Pending;
|
export default Pending;
|
||||||
|
|
||||||
|
export const getServerSideProps = async (context: any) => {};
|
||||||
|
|
|
||||||
|
|
@ -29,3 +29,5 @@ const Unassigned: FC = () => (
|
||||||
);
|
);
|
||||||
|
|
||||||
export default Unassigned;
|
export default Unassigned;
|
||||||
|
|
||||||
|
export const getServerSideProps = async (context: any) => {};
|
||||||
|
|
|
||||||
|
|
@ -29,3 +29,5 @@ const Urgent: FC = () => (
|
||||||
);
|
);
|
||||||
|
|
||||||
export default Urgent;
|
export default Urgent;
|
||||||
|
|
||||||
|
export const getServerSideProps = async (context: any) => {};
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import MicIcon from "@material-ui/icons/Mic";
|
||||||
import StopIcon from "@material-ui/icons/Stop";
|
import StopIcon from "@material-ui/icons/Stop";
|
||||||
import Button from "@material-ui/core/Button";
|
import Button from "@material-ui/core/Button";
|
||||||
import { makeStyles, useTheme } from "@material-ui/core/styles";
|
import { makeStyles, useTheme } from "@material-ui/core/styles";
|
||||||
import AudioPlayer from "material-ui-audio-player";
|
// import AudioPlayer from "material-ui-audio-player";
|
||||||
import { useStopwatch } from "react-timer-hook";
|
import { useStopwatch } from "react-timer-hook";
|
||||||
import style from "./MicInput.module.css";
|
import style from "./MicInput.module.css";
|
||||||
// import type { ReactMicProps } from "react-mic";
|
// import type { ReactMicProps } from "react-mic";
|
||||||
|
|
@ -130,7 +130,7 @@ const MicInput = (props: any) => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className={style.playerWrapper}>
|
<div className={style.playerWrapper}>
|
||||||
{canPlay && (
|
{/* canPlay && (
|
||||||
<AudioPlayer
|
<AudioPlayer
|
||||||
elevation={0}
|
elevation={0}
|
||||||
src={decodedValue}
|
src={decodedValue}
|
||||||
|
|
@ -138,7 +138,7 @@ const MicInput = (props: any) => {
|
||||||
volume={false}
|
volume={false}
|
||||||
useStyles={useStyles}
|
useStyles={useStyles}
|
||||||
/>
|
/>
|
||||||
)}
|
) */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,33 +3,31 @@
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apollo/client": "^3.7.4",
|
"@apollo/client": "^3.7.14",
|
||||||
"@digiresilience/metamigo-config": "*",
|
"@digiresilience/metamigo-config": "*",
|
||||||
"@hapi/boom": "^10.0.0",
|
"@hapi/boom": "^10.0.1",
|
||||||
"@hapi/wreck": "^18.0.0",
|
"@hapi/wreck": "^18.0.1",
|
||||||
"@mui/icons-material": "^5",
|
"@mui/icons-material": "^5",
|
||||||
"@mui/material": "^5",
|
"@mui/material": "^5",
|
||||||
"@mui/styles": "^5",
|
"@twilio/voice-sdk": "^2.5.0",
|
||||||
"@twilio/voice-sdk": "^2.2.0",
|
|
||||||
"http-proxy-middleware": "^2.0.6",
|
"http-proxy-middleware": "^2.0.6",
|
||||||
"jsonwebtoken": "^9.0.0",
|
"jsonwebtoken": "^9.0.0",
|
||||||
"jwks-rsa": "^3.0.1",
|
"jwks-rsa": "^3.0.1",
|
||||||
"material-ui-audio-player": "^1.7.1",
|
"next": "13.4.3",
|
||||||
"next": "12.3.4",
|
"next-auth": "4.22.1",
|
||||||
"next-auth": "4.18.8",
|
"ra-data-graphql": "^4.10.1",
|
||||||
"ra-data-graphql": "^4.6.0",
|
"ra-i18n-polyglot": "^4.10.6",
|
||||||
"ra-i18n-polyglot": "^4.7.0",
|
"ra-input-rich-text": "^4.10.6",
|
||||||
"ra-input-rich-text": "^4.7.1",
|
"ra-language-english": "^4.10.6",
|
||||||
"ra-language-english": "^4.7.0",
|
|
||||||
"ra-postgraphile": "^6.1.0",
|
"ra-postgraphile": "^6.1.0",
|
||||||
"react": "^17",
|
"react": "^18",
|
||||||
"react-admin": "^4.7.1",
|
"react-admin": "^4.10.6",
|
||||||
"react-digit-input": "^2.1.0",
|
"react-digit-input": "^2.1.0",
|
||||||
"react-dom": "^17",
|
"react-dom": "^18",
|
||||||
"react-qr-code": "^2.0.11",
|
"react-qr-code": "^2.0.11",
|
||||||
"react-redux": "^8.0.5",
|
"react-redux": "^8.0.5",
|
||||||
"react-timer-hook": "^3.0.5",
|
"react-timer-hook": "^3.0.6",
|
||||||
"swr": "^2.0.0",
|
"swr": "^2.1.5",
|
||||||
"twilio-client": "^1.15.0"
|
"twilio-client": "^1.15.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
@ -42,14 +40,14 @@
|
||||||
"fmt": "prettier --ignore-path .eslintignore \"**/*.{js,jsx,ts,tsx,graphql,md}\" --list-different"
|
"fmt": "prettier --ignore-path .eslintignore \"**/*.{js,jsx,ts,tsx,graphql,md}\" --list-different"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@next/eslint-plugin-next": "^13.1.2",
|
"@next/eslint-plugin-next": "^13.4.3",
|
||||||
"@types/hapi__wreck": "17.0.1",
|
"@types/hapi__wreck": "17.0.1",
|
||||||
"@types/react": "^17",
|
"@types/react": "^18",
|
||||||
"@types/react-mic": "12.4.3",
|
"@types/react-mic": "12.4.3",
|
||||||
"babel-preset-link": "*",
|
"babel-preset-link": "*",
|
||||||
"eslint-config-link": "*",
|
"eslint-config-link": "*",
|
||||||
"jest-config-link": "*",
|
"jest-config-link": "*",
|
||||||
"tsconfig-link": "*",
|
"tsconfig-link": "*",
|
||||||
"typescript": "^4.9.5"
|
"typescript": "^5.0.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2598
package-lock.json
generated
2598
package-lock.json
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue