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 { useAppContext } from "./AppProvider";
|
||||
|
||||
interface AboutBoxProps {
|
||||
type AboutBoxProps = PropsWithChildren<{
|
||||
backgroundColor: string;
|
||||
}
|
||||
}>;
|
||||
|
||||
export const AboutBox: FC<AboutBoxProps> = ({ backgroundColor, children }: any) => {
|
||||
export const AboutBox: FC<AboutBoxProps> = ({
|
||||
backgroundColor,
|
||||
children,
|
||||
}: any) => {
|
||||
const {
|
||||
colors: { white },
|
||||
} = 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>
|
||||
<Menu {...bindMenu(popupState)}>
|
||||
<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";
|
||||
|
||||
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) =>
|
||||
typeof image === "string" ? `${basePath}${image}` : `${basePath}${image.src}`;
|
||||
|
||||
|
|
@ -9,16 +18,16 @@ const AppContext = createContext({
|
|||
colors,
|
||||
typography,
|
||||
imageURL,
|
||||
query: null,
|
||||
updateQuery: null,
|
||||
updateQueryType: null,
|
||||
replaceQuery: null,
|
||||
clearQuery: null,
|
||||
query: null as any,
|
||||
updateQuery: null as any,
|
||||
updateQueryType: null as any,
|
||||
replaceQuery: null as any,
|
||||
clearQuery: null as any,
|
||||
foundCount: 0,
|
||||
setFoundCount: null,
|
||||
setFoundCount: null as any,
|
||||
});
|
||||
|
||||
export const AppProvider: FC = ({ children }) => {
|
||||
export const AppProvider: FC<PropsWithChildren> = ({ children }) => {
|
||||
const initialState = {
|
||||
incidentType: {
|
||||
display: "Incident Type",
|
||||
|
|
@ -82,7 +91,10 @@ export const AppProvider: FC = ({ children }) => {
|
|||
},
|
||||
};
|
||||
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 };
|
||||
switch (action.type) {
|
||||
case "UPDATE":
|
||||
|
|
|
|||
|
|
@ -5,7 +5,19 @@ import { useRouter } from "next/router";
|
|||
import { useTranslate } from "react-polyglot";
|
||||
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 {
|
||||
typography: { p, small },
|
||||
} = useAppContext();
|
||||
|
|
@ -48,10 +60,10 @@ export const GettingStartedDialog: FC = () => {
|
|||
typography: { h4 },
|
||||
} = useAppContext();
|
||||
const t = useTranslate();
|
||||
const [completedItems, setCompletedItems] = useState([]);
|
||||
const [completedItems, setCompletedItems] = useState([] as any[]);
|
||||
const router = useRouter();
|
||||
const open = router.query.tooltip?.toString() === "checklist";
|
||||
const toggleCompletedItem = (item) => {
|
||||
const toggleCompletedItem = (item: any) => {
|
||||
if (completedItems.includes(item)) {
|
||||
setCompletedItems(completedItems.filter((i) => i !== item));
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export const LanguageSelect = () => {
|
|||
colors: { white, leafcutterElectricBlue },
|
||||
} = useAppContext();
|
||||
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" });
|
||||
|
||||
return (
|
||||
|
|
@ -36,7 +36,7 @@ export const LanguageSelect = () => {
|
|||
},
|
||||
}}
|
||||
>
|
||||
{locales[router.locale] ?? locales.en}
|
||||
{locales[router.locale as any] ?? locales.en}
|
||||
<KeyboardArrowDownIcon />
|
||||
</IconButton>
|
||||
<Menu {...bindMenu(popupState)}>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { FC, PropsWithChildren } from "react";
|
||||
import { Grid, Container } from "@mui/material";
|
||||
import CookieConsent from "react-cookie-consent";
|
||||
import { useCookies } from "react-cookie";
|
||||
|
|
@ -7,7 +8,7 @@ import { GettingStartedDialog } from "./GettingStartedDialog";
|
|||
import { useAppContext } from "./AppProvider";
|
||||
// import { Footer } from "./Footer";
|
||||
|
||||
export const Layout = ({ children }) => {
|
||||
export const Layout: FC<PropsWithChildren> = ({ children }) => {
|
||||
const [cookies, setCookie] = useCookies(["cookieConsent"]);
|
||||
const consentGranted = cookies.cookieConsent === "true";
|
||||
const {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
/* eslint-disable react/require-default-props */
|
||||
import { FC } from "react";
|
||||
import { FC, PropsWithChildren } from "react";
|
||||
import { Box } from "@mui/material";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
|
||||
interface PageHeaderProps {
|
||||
type PageHeaderProps = PropsWithChildren<{
|
||||
backgroundColor: string;
|
||||
sx?: any;
|
||||
}
|
||||
}>;
|
||||
|
||||
export const PageHeader: FC<PageHeaderProps> = ({
|
||||
backgroundColor,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { FC, useState } from "react";
|
||||
import { FC, PropsWithChildren, useState } from "react";
|
||||
import {
|
||||
Box,
|
||||
Grid,
|
||||
|
|
@ -29,7 +29,14 @@ interface QueryBuilderSectionProps {
|
|||
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 {
|
||||
colors: { white, leafcutterElectricBlue, almostBlack },
|
||||
typography: { h5, small },
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ export const QueryDateRangeSelector: FC<QueryDateRangeSelectorProps> = () => {
|
|||
startDate: { values: [date] },
|
||||
});
|
||||
}}
|
||||
// @ts-ignore
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
|
|
@ -89,6 +90,7 @@ export const QueryDateRangeSelector: FC<QueryDateRangeSelectorProps> = () => {
|
|||
endDate: { values: [date] },
|
||||
});
|
||||
}}
|
||||
// @ts-ignore
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export const QueryListSelector: FC<QueryListSelectorProps> = ({
|
|||
values,
|
||||
width,
|
||||
}) => {
|
||||
const [selectionModel, setSelectionModel] = useState([]);
|
||||
const [selectionModel, setSelectionModel] = useState([] as any[]);
|
||||
const {
|
||||
colors: { leafcutterLightBlue, pink, leafcutterElectricBlue, warningPink },
|
||||
typography: { small },
|
||||
|
|
@ -70,19 +70,19 @@ export const QueryListSelector: FC<QueryListSelectorProps> = ({
|
|||
rows={rows}
|
||||
columns={columns}
|
||||
density="compact"
|
||||
pageSize={100}
|
||||
pageSizeOptions={[100]}
|
||||
checkboxSelection
|
||||
disableSelectionOnClick
|
||||
disableRowSelectionOnClick
|
||||
hideFooter
|
||||
disableColumnMenu
|
||||
scrollbarSize={10}
|
||||
onSelectionModelChange={(newSelectionModel) => {
|
||||
onRowSelectionModelChange={(newSelectionModel) => {
|
||||
setSelectionModel(newSelectionModel);
|
||||
updateQuery({
|
||||
[keyName]: { values: newSelectionModel },
|
||||
});
|
||||
}}
|
||||
selectionModel={selectionModel}
|
||||
rowSelectionModel={selectionModel}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export const QueryText: FC = () => {
|
|||
query: q,
|
||||
} = useAppContext();
|
||||
|
||||
const displayNames = {
|
||||
const displayNames: any = {
|
||||
incidentType: t("incidentType"),
|
||||
startDate: t("startDate"),
|
||||
endDate: t("endDate"),
|
||||
|
|
@ -41,6 +41,7 @@ export const QueryText: FC = () => {
|
|||
queryType === "include" ? ` ${t("is")} ` : ` ${t("isNot")} `
|
||||
} ${values
|
||||
.map(
|
||||
// @ts-expect-error
|
||||
(value: string) => `<em>${taxonomy[key]?.[value]?.display ?? ""}</em>`
|
||||
)
|
||||
.join(` ${t("or")} `)}</span>`;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export const RawDataViewer: FC<RawDataViewerProps> = ({ rows, height }) => {
|
|||
headerName: t("date"),
|
||||
editable: false,
|
||||
flex: 0.7,
|
||||
valueFormatter: ({ value }) => new Date(value).toLocaleDateString(),
|
||||
valueFormatter: ({ value }: any) => new Date(value).toLocaleDateString(),
|
||||
},
|
||||
{
|
||||
field: "incident",
|
||||
|
|
@ -58,7 +58,10 @@ export const RawDataViewer: FC<RawDataViewerProps> = ({ rows, height }) => {
|
|||
|
||||
return (
|
||||
<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 item>
|
||||
<DataGridPro
|
||||
|
|
@ -66,8 +69,8 @@ export const RawDataViewer: FC<RawDataViewerProps> = ({ rows, height }) => {
|
|||
rows={rows}
|
||||
columns={columns}
|
||||
density="compact"
|
||||
pageSize={100}
|
||||
disableSelectionOnClick
|
||||
pageSizeOptions={[100]}
|
||||
disableRowSelectionOnClick
|
||||
hideFooter
|
||||
disableColumnMenu
|
||||
scrollbarSize={10}
|
||||
|
|
@ -76,6 +79,6 @@ export const RawDataViewer: FC<RawDataViewerProps> = ({ rows, height }) => {
|
|||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
</Grid >
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -49,8 +49,9 @@ export const VisualizationBuilder: FC<VisualizationBuilderProps> = ({
|
|||
clearQuery,
|
||||
} = useAppContext();
|
||||
const { visualizations } = visualizationMap;
|
||||
const [selectedVisualizationType, setSelectedVisualizationType] =
|
||||
useState(null);
|
||||
const [selectedVisualizationType, setSelectedVisualizationType] = useState(
|
||||
null as any
|
||||
);
|
||||
const toggleSelectedVisualizationType = (visualizationType: string) => {
|
||||
if (visualizationType === selectedVisualizationType) {
|
||||
setSelectedVisualizationType(null);
|
||||
|
|
@ -72,7 +73,7 @@ export const VisualizationBuilder: FC<VisualizationBuilderProps> = ({
|
|||
updateSearches();
|
||||
}, [setSavedSearches]);
|
||||
|
||||
const showSavedSearchPopup = (event) => {
|
||||
const showSavedSearchPopup = (event: any) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
const handleClose = () => {
|
||||
|
|
@ -104,8 +105,10 @@ export const VisualizationBuilder: FC<VisualizationBuilderProps> = ({
|
|||
const updateSearch = (name: string) => {
|
||||
handleClose();
|
||||
closeDialog();
|
||||
const found = savedSearches.find((search) => search.name === name);
|
||||
replaceQuery(found.query);
|
||||
const found: any = savedSearches.find(
|
||||
(search: any) => search.name === name
|
||||
);
|
||||
replaceQuery(found?.query);
|
||||
};
|
||||
|
||||
const clearSearch = () => clearQuery();
|
||||
|
|
@ -240,7 +243,7 @@ export const VisualizationBuilder: FC<VisualizationBuilderProps> = ({
|
|||
<ListItemText>{t("saveCurrentSearch")}</ListItemText>
|
||||
</MenuItem>
|
||||
<Divider />
|
||||
{savedSearches.map((savedSearch) => (
|
||||
{savedSearches.map((savedSearch: any) => (
|
||||
<MenuItem
|
||||
key={savedSearch.name}
|
||||
onClick={() => updateSearch(savedSearch.name)}
|
||||
|
|
@ -322,6 +325,7 @@ export const VisualizationBuilder: FC<VisualizationBuilderProps> = ({
|
|||
<VisualizationSelectCard
|
||||
key={key}
|
||||
visualizationType={key}
|
||||
// @ts-expect-error
|
||||
title={visualizations[key].name}
|
||||
enabled={
|
||||
selectedVisualizationType === key ||
|
||||
|
|
@ -347,6 +351,7 @@ export const VisualizationBuilder: FC<VisualizationBuilderProps> = ({
|
|||
const { id, type, title, description } = template;
|
||||
const cleanTitle = title
|
||||
.replace("Templated", "")
|
||||
// @ts-expect-error
|
||||
.replace(visualizations[type].name, "");
|
||||
const metricType = cleanTitle.replace(/\s/g, "").toLowerCase();
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ export const VisualizationSelectCard: FC<VisualizationSelectCardProps> = ({
|
|||
cdrLinkOrange,
|
||||
},
|
||||
} = useAppContext();
|
||||
const images = {
|
||||
const images: any = {
|
||||
horizontalBar,
|
||||
horizontalBarStacked,
|
||||
verticalBar,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ export const Welcome = () => {
|
|||
const { data: session } = useSession();
|
||||
const {
|
||||
user: { name },
|
||||
} = session;
|
||||
} = session as any;
|
||||
const {
|
||||
colors: { white, leafcutterElectricBlue },
|
||||
typography: { h1, h4, p },
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ export const getUserMetadata = async (username: string) => {
|
|||
}
|
||||
|
||||
return res?.body._source;
|
||||
}
|
||||
};
|
||||
|
||||
export const saveUserMetadata = async (username: string, metadata: any) => {
|
||||
const client = createClient();
|
||||
|
|
@ -112,7 +112,7 @@ export const saveUserMetadata = async (username: string, metadata: any) => {
|
|||
index: userMetadataIndexName,
|
||||
body: { doc: { username, ...metadata } }
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/* User */
|
||||
|
||||
|
|
@ -130,13 +130,13 @@ const getCurrentUserIndex = async (email: string) => {
|
|||
|
||||
const indicesResponse = await client.indices.get({
|
||||
index: `.kibana_*_${userIndexName}_1`,
|
||||
})
|
||||
});
|
||||
const currentUserIndex = Object.keys(indicesResponse.body)[0];
|
||||
|
||||
return currentUserIndex;
|
||||
}
|
||||
};
|
||||
|
||||
const getIndexPattern = async (index: string) => {
|
||||
const getIndexPattern: any = async (index: string) => {
|
||||
const client = createClient();
|
||||
const query = {
|
||||
query: {
|
||||
|
|
@ -335,6 +335,7 @@ export const performQuery = async (searchQuery: any, limit: number) => {
|
|||
|
||||
if (searchQuery.relativeDate.values.length > 0) {
|
||||
searchQuery.relativeDate.values.forEach((value: string) => {
|
||||
// @ts-expect-error
|
||||
body.query.bool.must.push({
|
||||
range: {
|
||||
date: {
|
||||
|
|
@ -347,6 +348,7 @@ export const performQuery = async (searchQuery: any, limit: number) => {
|
|||
|
||||
if (searchQuery.startDate.values.length > 0) {
|
||||
searchQuery.startDate.values.forEach((value: string) => {
|
||||
// @ts-expect-error
|
||||
body.query.bool.must.push({
|
||||
range: {
|
||||
date: {
|
||||
|
|
@ -359,6 +361,7 @@ export const performQuery = async (searchQuery: any, limit: number) => {
|
|||
|
||||
if (searchQuery.endDate.values.length > 0) {
|
||||
searchQuery.endDate.values.forEach((value: string) => {
|
||||
// @ts-expect-error
|
||||
body.query.bool.must.push({
|
||||
range: {
|
||||
date: {
|
||||
|
|
@ -370,54 +373,63 @@ export const performQuery = async (searchQuery: any, limit: number) => {
|
|||
}
|
||||
|
||||
if (searchQuery.incidentType.values.length > 0) {
|
||||
// @ts-expect-error
|
||||
body.query.bool.must.push({
|
||||
terms: { "incident.keyword": searchQuery.incidentType.values },
|
||||
});
|
||||
}
|
||||
|
||||
if (searchQuery.targetedGroup.values.length > 0) {
|
||||
// @ts-expect-error
|
||||
body.query.bool.must.push({
|
||||
terms: { "targeted_group.keyword": searchQuery.targetedGroup.values },
|
||||
});
|
||||
}
|
||||
|
||||
if (searchQuery.platform.values.length > 0) {
|
||||
// @ts-expect-error
|
||||
body.query.bool.must.push({
|
||||
terms: { "technology.keyword": searchQuery.platform.values },
|
||||
});
|
||||
}
|
||||
|
||||
if (searchQuery.device.values.length > 0) {
|
||||
// @ts-expect-error
|
||||
body.query.bool.must.push({
|
||||
terms: { "technology.keyword": searchQuery.device.values },
|
||||
});
|
||||
}
|
||||
|
||||
if (searchQuery.service.values.length > 0) {
|
||||
// @ts-expect-error
|
||||
body.query.bool.must.push({
|
||||
terms: { "technology.keyword": searchQuery.service.values },
|
||||
});
|
||||
}
|
||||
|
||||
if (searchQuery.maker.values.length > 0) {
|
||||
// @ts-expect-error
|
||||
body.query.bool.must.push({
|
||||
terms: { "technology.keyword": searchQuery.maker.values },
|
||||
});
|
||||
}
|
||||
|
||||
if (searchQuery.subregion.values.length > 0) {
|
||||
// @ts-expect-error
|
||||
body.query.bool.must.push({
|
||||
terms: { "region.keyword": searchQuery.subregion.values },
|
||||
});
|
||||
}
|
||||
|
||||
if (searchQuery.country.values.length > 0) {
|
||||
// @ts-expect-error
|
||||
body.query.bool.must.push({
|
||||
terms: { "country.keyword": searchQuery.country.values },
|
||||
});
|
||||
}
|
||||
|
||||
if (searchQuery.continent.values.length > 0) {
|
||||
// @ts-expect-error
|
||||
body.query.bool.must.push({
|
||||
terms: { "continent.keyword": searchQuery.continent.values },
|
||||
});
|
||||
|
|
|
|||
|
|
@ -13,51 +13,50 @@
|
|||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/cache": "^11.10.3",
|
||||
"@emotion/react": "^11.10.4",
|
||||
"@emotion/server": "^11.10.0",
|
||||
"@emotion/styled": "^11.10.4",
|
||||
"@fontsource/playfair-display": "^4.5.12",
|
||||
"@fontsource/poppins": "^4.5.10",
|
||||
"@fontsource/roboto": "^4.5.8",
|
||||
"@emotion/cache": "^11.11.0",
|
||||
"@emotion/react": "^11.11.0",
|
||||
"@emotion/server": "^11.11.0",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@fontsource/playfair-display": "^5.0.1",
|
||||
"@fontsource/poppins": "^5.0.1",
|
||||
"@fontsource/roboto": "^5.0.1",
|
||||
"@mui/icons-material": "^5",
|
||||
"@mui/lab": "^5.0.0-alpha.102",
|
||||
"@mui/lab": "^5.0.0-alpha.131",
|
||||
"@mui/material": "^5",
|
||||
"@mui/styles": "^5",
|
||||
"@mui/x-data-grid-pro": "^5.17.5",
|
||||
"@mui/x-date-pickers-pro": "^5.0.3",
|
||||
"@mui/x-data-grid-pro": "^6.5.0",
|
||||
"@mui/x-date-pickers-pro": "^6.5.0",
|
||||
"@opensearch-project/opensearch": "^2.0.0",
|
||||
"date-fns": "^2.29.3",
|
||||
"date-fns": "^2.30.0",
|
||||
"http-proxy-middleware": "^2.0.6",
|
||||
"material-ui-popup-state": "^4.1.0",
|
||||
"next": "^12.3",
|
||||
"next-auth": "^4.12.2",
|
||||
"next-http-proxy-middleware": "^1.2.4",
|
||||
"nodemailer": "^6.8.0",
|
||||
"react": "^17",
|
||||
"material-ui-popup-state": "^5.0.8",
|
||||
"next": "^13.4",
|
||||
"next-auth": "^4.22.1",
|
||||
"next-http-proxy-middleware": "^1.2.5",
|
||||
"nodemailer": "^6.9.2",
|
||||
"react": "^18",
|
||||
"react-cookie": "^4.1.1",
|
||||
"react-cookie-consent": "^8.0.1",
|
||||
"react-dom": "^17",
|
||||
"react-iframe": "^1.8.4",
|
||||
"react-markdown": "^8.0.3",
|
||||
"react-dom": "^18",
|
||||
"react-iframe": "^1.8.5",
|
||||
"react-markdown": "^8.0.7",
|
||||
"react-polyglot": "^0.7.2",
|
||||
"sharp": "^0.31.3",
|
||||
"swr": "^1.3.0",
|
||||
"sharp": "^0.32.1",
|
||||
"swr": "^2.1.5",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19.3",
|
||||
"@types/react": "^17",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"babel-loader": "^8.2.5",
|
||||
"eslint": "^8.24.0",
|
||||
"@babel/core": "^7.21.8",
|
||||
"@types/react": "^18",
|
||||
"@types/uuid": "^9.0.1",
|
||||
"babel-loader": "^9.1.2",
|
||||
"eslint": "^8.41.0",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-next": "^12.3.1",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.6.1",
|
||||
"eslint-config-next": "^13.4.3",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-jsx-a11y": "^6.7.1",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-react": "^7.31.8",
|
||||
"typescript": "^4.9.5"
|
||||
"eslint-plugin-react": "^7.32.2",
|
||||
"typescript": "^5.0.4"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,13 +22,11 @@ import "@fontsource/playfair-display/900.css";
|
|||
import "styles/global.css";
|
||||
import { LicenseInfo } from "@mui/x-data-grid-pro";
|
||||
|
||||
LicenseInfo.setLicenseKey(
|
||||
"fd009c623acc055adb16370731be92e4T1JERVI6NDA3NTQsRVhQSVJZPTE2ODAyNTAwMTUwMDAsS0VZVkVSU0lPTj0x"
|
||||
);
|
||||
LicenseInfo.setLicenseKey(process.env.MUI_LICENSE_KEY ?? "");
|
||||
|
||||
const clientSideEmotionCache: any = createEmotionCache();
|
||||
|
||||
const messages = { en, fr };
|
||||
const messages: any = { en, fr };
|
||||
|
||||
interface LeafcutterWebProps extends AppProps {
|
||||
// eslint-disable-next-line react/require-default-props
|
||||
|
|
@ -36,7 +34,7 @@ interface LeafcutterWebProps extends AppProps {
|
|||
}
|
||||
|
||||
const LeafcutterWeb = (props: LeafcutterWebProps) => {
|
||||
const { locale } = useRouter();
|
||||
const { locale = "en" } = useRouter();
|
||||
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@ import Apple from "next-auth/providers/apple";
|
|||
export default NextAuth({
|
||||
providers: [
|
||||
Google({
|
||||
clientId: process.env.GOOGLE_CLIENT_ID,
|
||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
||||
clientId: process.env.GOOGLE_CLIENT_ID ?? "",
|
||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET ?? "",
|
||||
}),
|
||||
Apple({
|
||||
clientId: process.env.APPLE_CLIENT_ID,
|
||||
clientSecret: process.env.APPLE_CLIENT_SECRET
|
||||
clientId: process.env.APPLE_CLIENT_ID ?? "",
|
||||
clientSecret: process.env.APPLE_CLIENT_SECRET ?? "",
|
||||
}),
|
||||
],
|
||||
secret: process.env.NEXTAUTH_SECRET,
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ import { NextApiRequest, NextApiResponse } from "next";
|
|||
import { getToken } from "next-auth/jwt";
|
||||
|
||||
const withAuthInfo =
|
||||
(handler) => async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const session = await getToken({
|
||||
(handler: any) => async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const session: any = await getToken({
|
||||
req,
|
||||
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" });
|
||||
}
|
||||
|
||||
const { email } = session;
|
||||
const { email }: any = session;
|
||||
const { name, query } = JSON.parse(req.body);
|
||||
const result = await getUserMetadata(email);
|
||||
const { savedSearches } = result;
|
||||
|
|
@ -24,8 +24,8 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||
savedSearches: [...savedSearches, { name, query }]
|
||||
});
|
||||
const { savedSearches: updatedSavedSearches } = await getUserMetadata(email);
|
||||
return res.json(updatedSavedSearches)
|
||||
}
|
||||
return res.json(updatedSavedSearches);
|
||||
};
|
||||
|
||||
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" });
|
||||
}
|
||||
|
||||
const { email } = session;
|
||||
const { email }: any = session;
|
||||
const { name } = JSON.parse(req.body);
|
||||
const { savedSearches } = await getUserMetadata(email);
|
||||
const updatedSavedSearches = savedSearches.filter(search => search.name !== name);
|
||||
const result = await saveUserMetadata(email, { savedSearches: updatedSavedSearches })
|
||||
const updatedSavedSearches = savedSearches.filter((search: any) => search.name !== name);
|
||||
const result = await saveUserMetadata(email, { savedSearches: updatedSavedSearches });
|
||||
|
||||
return res.json({ result })
|
||||
}
|
||||
return res.json({ result });
|
||||
};
|
||||
|
||||
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" });
|
||||
}
|
||||
|
||||
const { email } = session;
|
||||
const { email }: any = session;
|
||||
const { savedSearches } = await getUserMetadata(email);
|
||||
|
||||
return res.json(savedSearches)
|
||||
}
|
||||
return res.json(savedSearches);
|
||||
};
|
||||
|
||||
export default handler;
|
||||
|
|
|
|||
|
|
@ -25,13 +25,14 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||
const { id } = ticket;
|
||||
try {
|
||||
const country = ticket.country[0] ?? "none";
|
||||
// @ts-expect-error
|
||||
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 = {
|
||||
...ticket,
|
||||
region: countryDetails['sub-region']?.toLowerCase().replace(" ", "-") ?? null,
|
||||
continent: countryDetails.region?.toLowerCase().replace(" ", "-") ?? null,
|
||||
}
|
||||
};
|
||||
const out = await client.create({
|
||||
id: uuid(),
|
||||
index: "sample_tagged_tickets",
|
||||
|
|
@ -41,13 +42,13 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||
console.log(out);
|
||||
succeeded.push(id);
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
console.log(e);
|
||||
failed.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
const results = { succeeded, failed };
|
||||
return res.json(results)
|
||||
return res.json(results);
|
||||
};
|
||||
|
||||
export default handler;
|
||||
|
|
|
|||
|
|
@ -18,14 +18,14 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||
|
||||
const { visualizationID, title, description, query } = req.body;
|
||||
const id = await createUserVisualization({
|
||||
email: session.email,
|
||||
email: session.email as string,
|
||||
visualizationID,
|
||||
title,
|
||||
description,
|
||||
query
|
||||
});
|
||||
|
||||
return res.json({ id })
|
||||
return res.json({ id });
|
||||
};
|
||||
|
||||
export default handler;
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||
}
|
||||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -18,14 +18,14 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||
|
||||
const { id, title, description, query } = req.body;
|
||||
await updateUserVisualization({
|
||||
email: session.email,
|
||||
email: session.email as string,
|
||||
id,
|
||||
title,
|
||||
description,
|
||||
query
|
||||
});
|
||||
|
||||
return res.json({ id })
|
||||
return res.json({ id });
|
||||
};
|
||||
|
||||
export default handler;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useEffect } from "react";
|
||||
import { FC, useEffect } from "react";
|
||||
import { GetServerSideProps, GetServerSidePropsContext } from "next";
|
||||
import Head from "next/head";
|
||||
import { useTranslate } from "react-polyglot";
|
||||
|
|
@ -12,7 +12,11 @@ import { useAppContext } from "components/AppProvider";
|
|||
import { PageHeader } from "components/PageHeader";
|
||||
import { VisualizationBuilder } from "components/VisualizationBuilder";
|
||||
|
||||
const Create = ({ templates }) => {
|
||||
type CreateProps = {
|
||||
templates: any;
|
||||
};
|
||||
|
||||
const Create: FC<CreateProps> = ({ templates }) => {
|
||||
const t = useTranslate();
|
||||
const {
|
||||
colors: { cdrLinkOrange },
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useEffect } from "react";
|
||||
import { GetServerSideProps, GetServerSidePropsContext } from "next";
|
||||
import { NextPage, GetServerSideProps, GetServerSidePropsContext } from "next";
|
||||
import { useRouter } from "next/router";
|
||||
import Head from "next/head";
|
||||
import Link from "next/link";
|
||||
|
|
@ -15,7 +15,13 @@ import { WelcomeDialog } from "components/WelcomeDialog";
|
|||
import { VisualizationCard } from "components/VisualizationCard";
|
||||
import { useAppContext } from "components/AppProvider";
|
||||
|
||||
const MyVisualizations = ({ visualizations }) => {
|
||||
type MyVisualizationsProps = {
|
||||
visualizations: any;
|
||||
};
|
||||
|
||||
const MyVisualizations: NextPage<MyVisualizationsProps> = ({
|
||||
visualizations,
|
||||
}) => {
|
||||
const router = useRouter();
|
||||
const cookieName = "homeIntroComplete";
|
||||
const [cookies, setCookie] = useCookies([cookieName]);
|
||||
|
|
@ -85,7 +91,7 @@ const MyVisualizations = ({ visualizations }) => {
|
|||
</Grid>
|
||||
</Grid>
|
||||
) : null}
|
||||
{visualizations.map((visualization, index) => (
|
||||
{visualizations.map((visualization: any, index: number) => (
|
||||
<VisualizationCard
|
||||
id={visualization.id}
|
||||
key={index}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import Head from "next/head";
|
||||
import { NextPage } from "next";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
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 { useAppContext } from "components/AppProvider";
|
||||
|
||||
const Login = ({ session }) => {
|
||||
type LoginProps = {
|
||||
session: any;
|
||||
};
|
||||
|
||||
const Login: NextPage<LoginProps> = ({ session }) => {
|
||||
const t = useTranslate();
|
||||
const {
|
||||
colors: { leafcutterElectricBlue, lightGray },
|
||||
|
|
@ -112,7 +117,7 @@ const Login = ({ session }) => {
|
|||
|
||||
export default Login;
|
||||
|
||||
export async function getServerSideProps(context) {
|
||||
export async function getServerSideProps(context: any) {
|
||||
const session = (await getSession(context)) ?? null;
|
||||
|
||||
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 { Grid, CircularProgress } from "@mui/material";
|
||||
import Iframe from "react-iframe";
|
||||
import { useAppContext } from "components/AppProvider";
|
||||
import { checkAuth } from "lib/checkAuth";
|
||||
|
||||
export const Setup: FC = () => {
|
||||
const Setup: NextPage = () => {
|
||||
const {
|
||||
colors: { leafcutterElectricBlue },
|
||||
} = useAppContext();
|
||||
|
|
@ -44,3 +46,7 @@ export const Setup: FC = () => {
|
|||
};
|
||||
|
||||
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 { Grid, Box } from "@mui/material";
|
||||
import { useTranslate } from "react-polyglot";
|
||||
|
|
@ -9,7 +9,11 @@ import { PageHeader } from "components/PageHeader";
|
|||
import { VisualizationCard } from "components/VisualizationCard";
|
||||
import { useAppContext } from "components/AppProvider";
|
||||
|
||||
const Trends = ({ visualizations }) => {
|
||||
type TrendsProps = {
|
||||
visualizations: any;
|
||||
};
|
||||
|
||||
const Trends: NextPage<TrendsProps> = ({ visualizations }) => {
|
||||
const t = useTranslate();
|
||||
const {
|
||||
colors: { cdrLinkOrange },
|
||||
|
|
@ -58,7 +62,7 @@ const Trends = ({ visualizations }) => {
|
|||
spacing={3}
|
||||
justifyContent="space-between"
|
||||
>
|
||||
{visualizations.map((visualization, index) => (
|
||||
{visualizations.map((visualization: any, index: number) => (
|
||||
<VisualizationCard
|
||||
key={index}
|
||||
id={visualization.id}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,16 @@
|
|||
/* eslint-disable no-underscore-dangle */
|
||||
import { GetServerSideProps, GetServerSidePropsContext } from "next";
|
||||
import { NextPage, GetServerSideProps, GetServerSidePropsContext } from "next";
|
||||
import { Client } from "@opensearch-project/opensearch";
|
||||
import Head from "next/head";
|
||||
import { Layout } from "components/Layout";
|
||||
import { VisualizationDetail } from "components/VisualizationDetail";
|
||||
import { checkAuth } from "lib/checkAuth";
|
||||
|
||||
const Visualization = ({ visualization }) => (
|
||||
type VisualizationProps = {
|
||||
visualization: any;
|
||||
};
|
||||
|
||||
const Visualization: NextPage<VisualizationProps> = ({ visualization }) => (
|
||||
<Layout>
|
||||
<Head>
|
||||
<title>Digital Threat Dashboard – Leafcutter</title>
|
||||
|
|
@ -43,7 +47,8 @@ export const getServerSideProps: GetServerSideProps = async (
|
|||
const response = rawResponse.body;
|
||||
|
||||
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];
|
||||
res.props.visualization = {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": false,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noEmit": 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 { useRouter } from "next/router";
|
||||
import Iframe from "react-iframe";
|
||||
import { FC } from "react";
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const InternalZammadWrapper = dynamic(
|
||||
import("./InternalZammadWrapper").then((mod) => mod.InternalZammadWrapper),
|
||||
{
|
||||
ssr: false,
|
||||
}
|
||||
);
|
||||
|
||||
type ZammadWrapperProps = {
|
||||
path: string;
|
||||
|
|
@ -9,72 +15,5 @@ type ZammadWrapperProps = {
|
|||
|
||||
export const ZammadWrapper: FC<ZammadWrapperProps> = ({
|
||||
path,
|
||||
hideSidebar = true,
|
||||
}) => {
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
hideSidebar,
|
||||
}) => <InternalZammadWrapper path={path} hideSidebar={hideSidebar} />;
|
||||
|
|
|
|||
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 = {
|
||||
reactStrictMode: true,
|
||||
rewrites: async () => ({
|
||||
fallback: [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,45 +11,45 @@
|
|||
"dependencies": {
|
||||
"@chatscope/chat-ui-kit-react": "^1.10.1",
|
||||
"@chatscope/chat-ui-kit-styles": "^1.4.0",
|
||||
"@emotion/cache": "^11.10.5",
|
||||
"@emotion/react": "^11.10.5",
|
||||
"@emotion/server": "^11.10.0",
|
||||
"@emotion/styled": "^11.10.5",
|
||||
"@fontsource/playfair-display": "^4.5.13",
|
||||
"@fontsource/poppins": "^4.5.10",
|
||||
"@fontsource/roboto": "^4.5.8",
|
||||
"@emotion/cache": "^11.11.0",
|
||||
"@emotion/react": "^11.11.0",
|
||||
"@emotion/server": "^11.11.0",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@fontsource/playfair-display": "^5.0.1",
|
||||
"@fontsource/poppins": "^5.0.1",
|
||||
"@fontsource/roboto": "^5.0.1",
|
||||
"@mui/icons-material": "^5",
|
||||
"@mui/lab": "^5.0.0-alpha.118",
|
||||
"@mui/lab": "^5.0.0-alpha.131",
|
||||
"@mui/material": "^5",
|
||||
"@mui/x-data-grid-pro": "^5.17.22",
|
||||
"@mui/x-date-pickers-pro": "^5.0.17",
|
||||
"date-fns": "^2.29.3",
|
||||
"graphql-request": "^5.2.0",
|
||||
"@mui/x-data-grid-pro": "^6.5.0",
|
||||
"@mui/x-date-pickers-pro": "^6.5.0",
|
||||
"date-fns": "^2.30.0",
|
||||
"graphql-request": "^6.1.0",
|
||||
"http-proxy-middleware": "^2.0.6",
|
||||
"material-ui-popup-state": "^5.0.4",
|
||||
"next": "^12",
|
||||
"next-auth": "^4.19.2",
|
||||
"material-ui-popup-state": "^5.0.8",
|
||||
"next": "^13",
|
||||
"next-auth": "^4.22.1",
|
||||
"next-http-proxy-middleware": "^1.2.5",
|
||||
"react": "^17",
|
||||
"react-dom": "^17",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"react-iframe": "^1.8.5",
|
||||
"react-polyglot": "^0.7.2",
|
||||
"sharp": "^0.30.7",
|
||||
"swr": "^2.0.3"
|
||||
"sharp": "^0.32.1",
|
||||
"swr": "^2.1.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.12",
|
||||
"@babel/core": "^7.21.8",
|
||||
"@types/react": "^18",
|
||||
"@types/uuid": "^9.0.0",
|
||||
"@types/uuid": "^9.0.1",
|
||||
"babel-loader": "^9.1.2",
|
||||
"eslint": "^8.33.0",
|
||||
"eslint": "^8.41.0",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-next": "^13.1.6",
|
||||
"eslint-config-prettier": "^8.6.0",
|
||||
"eslint-config-next": "^13.4.3",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-jsx-a11y": "^6.7.1",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"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 { GraphQLClient } from "graphql-request";
|
||||
|
||||
LicenseInfo.setLicenseKey(
|
||||
"fd009c623acc055adb16370731be92e4T1JERVI6NDA3NTQsRVhQSVJZPTE2ODAyNTAwMTUwMDAsS0VZVkVSU0lPTj0x"
|
||||
);
|
||||
LicenseInfo.setLicenseKey(process.env.MUI_LICENSE_KEY);
|
||||
|
||||
const clientSideEmotionCache: any = createEmotionCache();
|
||||
|
||||
|
|
@ -28,15 +26,18 @@ interface LinkWebProps extends AppProps {
|
|||
emotionCache?: EmotionCache;
|
||||
}
|
||||
|
||||
const LinkWeb = (props: LinkWebProps) => {
|
||||
export default function LinkWeb(props: LinkWebProps) {
|
||||
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
|
||||
|
||||
const [csrfToken, setCsrfToken] = useState("");
|
||||
const origin = typeof window !== 'undefined' && window.location.origin
|
||||
? window.location.origin : null;
|
||||
const origin =
|
||||
typeof window !== "undefined" && window.location.origin
|
||||
? window.location.origin
|
||||
: null;
|
||||
const client = new GraphQLClient(`${origin}/graphql`, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Accept": "application/json",
|
||||
Accept: "application/json",
|
||||
},
|
||||
});
|
||||
const graphQLFetcher = async ({ document, variables }: any) => {
|
||||
|
|
@ -49,7 +50,7 @@ const LinkWeb = (props: LinkWebProps) => {
|
|||
requestHeaders
|
||||
);
|
||||
|
||||
const token = headers.get('CSRF-Token');
|
||||
const token = headers.get("CSRF-Token");
|
||||
setCsrfToken(token);
|
||||
|
||||
return data;
|
||||
|
|
@ -67,6 +68,4 @@ const LinkWeb = (props: LinkWebProps) => {
|
|||
</CacheProvider>
|
||||
</SessionProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default LinkWeb;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
// @ts-nocheck
|
||||
import { FC } from "react";
|
||||
import Head from "next/head";
|
||||
import { Grid } from "@mui/material";
|
||||
|
|
@ -30,3 +29,5 @@ const LabelStudio: FC = () => (
|
|||
);
|
||||
|
||||
export default LabelStudio;
|
||||
|
||||
export const getServerSideProps = async (context: any) => {};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
// @ts-nocheck
|
||||
import { FC } from "react";
|
||||
import Head from "next/head";
|
||||
import { Grid } from "@mui/material";
|
||||
|
|
@ -30,3 +29,5 @@ const Metamigo: FC = () => (
|
|||
);
|
||||
|
||||
export default Metamigo;
|
||||
|
||||
export const getServerSideProps = async (context: any) => {};
|
||||
|
|
|
|||
|
|
@ -29,3 +29,5 @@ const Zammad: FC = () => (
|
|||
);
|
||||
|
||||
export default Zammad;
|
||||
|
||||
export const getServerSideProps = async (context: any) => {};
|
||||
|
|
|
|||
|
|
@ -28,3 +28,5 @@ const Home = () => (
|
|||
);
|
||||
|
||||
export default Home;
|
||||
|
||||
export const getServerSideProps = async (context: any) => {};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// @ts-nocheck
|
||||
import { FC, useState } from "react";
|
||||
import Head from "next/head";
|
||||
import { Grid, Button } from "@mui/material";
|
||||
import { Grid } from "@mui/material";
|
||||
import { Layout } from "components/Layout";
|
||||
import Iframe from "react-iframe";
|
||||
|
||||
|
|
@ -35,3 +34,5 @@ const About: FC = () => {
|
|||
};
|
||||
|
||||
export default About;
|
||||
|
||||
export const getServerSideProps = async (context: any) => {};
|
||||
|
|
|
|||
|
|
@ -35,3 +35,5 @@ const Create: FC = () => {
|
|||
};
|
||||
|
||||
export default Create;
|
||||
|
||||
export const getServerSideProps = async (context: any) => {};
|
||||
|
|
|
|||
|
|
@ -35,3 +35,5 @@ const FAQ: FC = () => {
|
|||
};
|
||||
|
||||
export default FAQ;
|
||||
|
||||
export const getServerSideProps = async (context: any) => {};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
// @ts-nocheck
|
||||
import { FC, useState } from "react";
|
||||
import Head from "next/head";
|
||||
import { Grid, Button } from "@mui/material";
|
||||
|
|
@ -35,3 +34,5 @@ const Leafcutter: FC = () => {
|
|||
};
|
||||
|
||||
export default Leafcutter;
|
||||
|
||||
export const getServerSideProps = async (context: any) => {};
|
||||
|
|
|
|||
|
|
@ -35,3 +35,5 @@ const Trends: FC = () => {
|
|||
};
|
||||
|
||||
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 { FC } from "react";
|
||||
import { Box, Grid, Container, IconButton } from "@mui/material";
|
||||
import { Apple as AppleIcon, Google as GoogleIcon } from "@mui/icons-material";
|
||||
import { signIn, getSession } from "next-auth/react";
|
||||
|
||||
const Login = ({ session }) => {
|
||||
const origin = typeof window !== 'undefined' && window.location.origin
|
||||
type LoginProps = {
|
||||
session: any;
|
||||
};
|
||||
|
||||
const Login: FC<LoginProps> = ({ session }) => {
|
||||
const origin =
|
||||
typeof window !== "undefined" && window.location.origin
|
||||
? window.location.origin
|
||||
: '';
|
||||
: "";
|
||||
const buttonStyles = {
|
||||
borderRadius: 500,
|
||||
width: "100%",
|
||||
|
|
|
|||
|
|
@ -29,3 +29,5 @@ const Profile: NextPage = () => (
|
|||
);
|
||||
|
||||
export default Profile;
|
||||
|
||||
export const getServerSideProps = async (context: any) => {};
|
||||
|
|
|
|||
|
|
@ -29,3 +29,5 @@ const Assigned: FC = () => (
|
|||
);
|
||||
|
||||
export default Assigned;
|
||||
|
||||
export const getServerSideProps = async (context: any) => {};
|
||||
|
|
|
|||
|
|
@ -29,3 +29,5 @@ const Pending: FC = () => (
|
|||
);
|
||||
|
||||
export default Pending;
|
||||
|
||||
export const getServerSideProps = async (context: any) => {};
|
||||
|
|
|
|||
|
|
@ -29,3 +29,5 @@ const Unassigned: FC = () => (
|
|||
);
|
||||
|
||||
export default Unassigned;
|
||||
|
||||
export const getServerSideProps = async (context: any) => {};
|
||||
|
|
|
|||
|
|
@ -29,3 +29,5 @@ const Urgent: FC = () => (
|
|||
);
|
||||
|
||||
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 Button from "@material-ui/core/Button";
|
||||
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 style from "./MicInput.module.css";
|
||||
// import type { ReactMicProps } from "react-mic";
|
||||
|
|
@ -130,7 +130,7 @@ const MicInput = (props: any) => {
|
|||
)}
|
||||
</div>
|
||||
<div className={style.playerWrapper}>
|
||||
{canPlay && (
|
||||
{/* canPlay && (
|
||||
<AudioPlayer
|
||||
elevation={0}
|
||||
src={decodedValue}
|
||||
|
|
@ -138,7 +138,7 @@ const MicInput = (props: any) => {
|
|||
volume={false}
|
||||
useStyles={useStyles}
|
||||
/>
|
||||
)}
|
||||
) */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,33 +3,31 @@
|
|||
"version": "0.2.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.7.4",
|
||||
"@apollo/client": "^3.7.14",
|
||||
"@digiresilience/metamigo-config": "*",
|
||||
"@hapi/boom": "^10.0.0",
|
||||
"@hapi/wreck": "^18.0.0",
|
||||
"@hapi/boom": "^10.0.1",
|
||||
"@hapi/wreck": "^18.0.1",
|
||||
"@mui/icons-material": "^5",
|
||||
"@mui/material": "^5",
|
||||
"@mui/styles": "^5",
|
||||
"@twilio/voice-sdk": "^2.2.0",
|
||||
"@twilio/voice-sdk": "^2.5.0",
|
||||
"http-proxy-middleware": "^2.0.6",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"jwks-rsa": "^3.0.1",
|
||||
"material-ui-audio-player": "^1.7.1",
|
||||
"next": "12.3.4",
|
||||
"next-auth": "4.18.8",
|
||||
"ra-data-graphql": "^4.6.0",
|
||||
"ra-i18n-polyglot": "^4.7.0",
|
||||
"ra-input-rich-text": "^4.7.1",
|
||||
"ra-language-english": "^4.7.0",
|
||||
"next": "13.4.3",
|
||||
"next-auth": "4.22.1",
|
||||
"ra-data-graphql": "^4.10.1",
|
||||
"ra-i18n-polyglot": "^4.10.6",
|
||||
"ra-input-rich-text": "^4.10.6",
|
||||
"ra-language-english": "^4.10.6",
|
||||
"ra-postgraphile": "^6.1.0",
|
||||
"react": "^17",
|
||||
"react-admin": "^4.7.1",
|
||||
"react": "^18",
|
||||
"react-admin": "^4.10.6",
|
||||
"react-digit-input": "^2.1.0",
|
||||
"react-dom": "^17",
|
||||
"react-dom": "^18",
|
||||
"react-qr-code": "^2.0.11",
|
||||
"react-redux": "^8.0.5",
|
||||
"react-timer-hook": "^3.0.5",
|
||||
"swr": "^2.0.0",
|
||||
"react-timer-hook": "^3.0.6",
|
||||
"swr": "^2.1.5",
|
||||
"twilio-client": "^1.15.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
|
@ -42,14 +40,14 @@
|
|||
"fmt": "prettier --ignore-path .eslintignore \"**/*.{js,jsx,ts,tsx,graphql,md}\" --list-different"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next/eslint-plugin-next": "^13.1.2",
|
||||
"@next/eslint-plugin-next": "^13.4.3",
|
||||
"@types/hapi__wreck": "17.0.1",
|
||||
"@types/react": "^17",
|
||||
"@types/react": "^18",
|
||||
"@types/react-mic": "12.4.3",
|
||||
"babel-preset-link": "*",
|
||||
"eslint-config-link": "*",
|
||||
"jest-config-link": "*",
|
||||
"tsconfig-link": "*",
|
||||
"typescript": "^4.9.5"
|
||||
"typescript": "^5.0.4"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2600
package-lock.json
generated
2600
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