WIP 5
|
|
@ -9,9 +9,9 @@
|
|||
"fmt": "prettier \"profile/**/*.js\" --write"
|
||||
},
|
||||
"dependencies": {
|
||||
"@rushstack/eslint-patch": "^1.7.2",
|
||||
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
||||
"@typescript-eslint/parser": "^7.2.0",
|
||||
"@rushstack/eslint-patch": "^1.8.0",
|
||||
"@typescript-eslint/eslint-plugin": "^7.3.1",
|
||||
"@typescript-eslint/parser": "^7.3.1",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-config-xo-space": "^0.35.0",
|
||||
"eslint-plugin-cypress": "^2.15.1",
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
"eslint-plugin-no-use-extend-native": "^0.5.0",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"eslint-plugin-unicorn": "51.0.1",
|
||||
"@babel/eslint-parser": "7.23.10"
|
||||
"@babel/eslint-parser": "7.24.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^7.32.0",
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
"use client";
|
||||
|
||||
import { FC, useEffect, useState } from "react";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { RawDataViewer } from "./RawDataViewer";
|
||||
|
||||
export const LiveDataViewer: FC = () => {
|
||||
const { query, setFoundCount } = useAppContext();
|
||||
const [rows, setRows] = useState<any[]>([]);
|
||||
const searchQuery = encodeURI(JSON.stringify(query));
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
const result = await fetch(
|
||||
`/api/visualizations/query?searchQuery=${searchQuery}`,
|
||||
);
|
||||
const json = await result.json();
|
||||
setRows(json);
|
||||
setFoundCount(json?.length ?? 0);
|
||||
};
|
||||
fetchData();
|
||||
}, [searchQuery, setFoundCount]);
|
||||
|
||||
return <RawDataViewer rows={rows} height={350} />;
|
||||
};
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
import type { NextAuthOptions } from "next-auth";
|
||||
import Google from "next-auth/providers/google";
|
||||
import Apple from "next-auth/providers/apple";
|
||||
|
||||
export const authOptions: NextAuthOptions = {
|
||||
providers: [
|
||||
Google({
|
||||
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 ?? "",
|
||||
}),
|
||||
],
|
||||
secret: process.env.NEXTAUTH_SECRET,
|
||||
};
|
||||
23
packages/leafcutter-ui/actions/visualizations.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
"use server";
|
||||
|
||||
import { performLeafcutterQuery, performZammadQuery, createUserVisualization } from "opensearch-common";
|
||||
|
||||
export const createUserVisualizationAction = async ({visualizationID, title, description, query}: any) => {
|
||||
const email = "darren@redaranj.com";
|
||||
const id = await createUserVisualization({
|
||||
email,
|
||||
visualizationID,
|
||||
title,
|
||||
description,
|
||||
query
|
||||
});
|
||||
return id;
|
||||
}
|
||||
|
||||
export const searchVisualizationsAction = async (
|
||||
kind: string,
|
||||
searchQuery: string,
|
||||
) =>
|
||||
kind === "zammad"
|
||||
? performZammadQuery(searchQuery, 1000)
|
||||
: performLeafcutterQuery(searchQuery, 1000);
|
||||
|
|
@ -5,7 +5,7 @@ import Link from "next/link";
|
|||
import Image from "next/image";
|
||||
import { useTranslate } from "react-polyglot";
|
||||
import { Grid, Container, Box, Button } from "@mui/material";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
import { AboutBox } from "./AboutBox";
|
||||
import { AboutFeature } from "./AboutFeature";
|
||||
import { PageHeader } from "./PageHeader";
|
||||
|
|
@ -21,7 +21,7 @@ export const About: FC = () => {
|
|||
const {
|
||||
colors: { white, leafcutterElectricBlue, cdrLinkOrange },
|
||||
typography: { h1, h4, p },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import { FC, PropsWithChildren } from "react";
|
||||
import { Box } from "@mui/material";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
type AboutBoxProps = PropsWithChildren<{
|
||||
backgroundColor: string;
|
||||
|
|
@ -14,7 +14,7 @@ export const AboutBox: FC<AboutBoxProps> = ({
|
|||
}: any) => {
|
||||
const {
|
||||
colors: { white },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
|
||||
return (
|
||||
<Box
|
||||
|
|
@ -4,7 +4,7 @@ import { FC } from "react";
|
|||
import Image from "next/legacy/image";
|
||||
import { Grid, Box, GridSize } from "@mui/material";
|
||||
import AboutDots from "../images/about-dots.png";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
interface AboutFeatureProps {
|
||||
title: string;
|
||||
|
|
@ -25,7 +25,7 @@ export const AboutFeature: FC<AboutFeatureProps> = ({
|
|||
}) => {
|
||||
const {
|
||||
typography: { h2, p },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
|
||||
return (
|
||||
<Box
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
import { FC } from "react";
|
||||
import Link from "next/link";
|
||||
import { Button as MUIButton } from "@mui/material";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
interface ButtonProps {
|
||||
text: string;
|
||||
|
|
@ -14,7 +14,7 @@ interface ButtonProps {
|
|||
export const Button: FC<ButtonProps> = ({ text, color, href }) => {
|
||||
const {
|
||||
colors: { white, almostBlack },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
|
||||
return (
|
||||
<Link href={href} passHref>
|
||||
|
|
@ -5,7 +5,7 @@ import { useTranslate } from "react-polyglot";
|
|||
import { useRouter, usePathname } from "next/navigation";
|
||||
import { Box, Grid } from "@mui/material";
|
||||
import { useCookies } from "react-cookie";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
import { PageHeader } from "./PageHeader";
|
||||
import { VisualizationBuilder } from "./VisualizationBuilder";
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ export const Create: FC<CreateProps> = ({ templates }) => {
|
|||
const {
|
||||
colors: { cdrLinkOrange },
|
||||
typography: { h1, h4 },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
const router = useRouter();
|
||||
const pathname = usePathname() ?? "";
|
||||
const cookieName = "searchIntroComplete";
|
||||
|
|
@ -5,7 +5,7 @@ import { useTranslate } from "react-polyglot";
|
|||
import { Box, Grid } from "@mui/material";
|
||||
import { PageHeader } from "./PageHeader";
|
||||
import { Question } from "./Question";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
import FaqHeader from "../images/faq-header.svg";
|
||||
|
||||
export const FAQ: FC = () => {
|
||||
|
|
@ -13,7 +13,7 @@ export const FAQ: FC = () => {
|
|||
const {
|
||||
colors: { lavender },
|
||||
typography: { h1, h4, p },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
|
||||
const questions = [
|
||||
{
|
||||
|
|
@ -9,14 +9,14 @@ import leafcutterLogo from "../images/leafcutter-logo.png";
|
|||
import footerLogo from "../images/footer-logo.png";
|
||||
import twitterLogo from "../images/twitter-logo.png";
|
||||
import gitlabLogo from "../images/gitlab-logo.png";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
export const Footer: FC = () => {
|
||||
const t = useTranslate();
|
||||
const {
|
||||
colors: { white, leafcutterElectricBlue },
|
||||
typography: { bodySmall },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
const smallLinkStyles: any = {
|
||||
...bodySmall,
|
||||
color: white,
|
||||
|
|
@ -5,7 +5,7 @@ import { Dialog, Box, Grid, Checkbox, IconButton } from "@mui/material";
|
|||
import { Close as CloseIcon } from "@mui/icons-material";
|
||||
import { useRouter, usePathname, useSearchParams } from "next/navigation";
|
||||
import { useTranslate } from "react-polyglot";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
type CheckboxItemProps = {
|
||||
title: string;
|
||||
|
|
@ -22,7 +22,7 @@ const CheckboxItem: FC<CheckboxItemProps> = ({
|
|||
}) => {
|
||||
const {
|
||||
typography: { p, small },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
|
||||
return (
|
||||
<Grid item container spacing={0}>
|
||||
|
|
@ -60,7 +60,7 @@ export const GettingStartedDialog: FC = () => {
|
|||
const {
|
||||
colors: { almostBlack },
|
||||
typography: { h4 },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
const t = useTranslate();
|
||||
const router = useRouter();
|
||||
const [completedItems, setCompletedItems] = useState([] as any[]);
|
||||
|
|
@ -10,13 +10,14 @@ import { useCookies } from "react-cookie";
|
|||
import { Welcome } from "./Welcome";
|
||||
import { WelcomeDialog } from "./WelcomeDialog";
|
||||
import { VisualizationCard } from "./VisualizationCard";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
type HomeProps = {
|
||||
visualizations: any;
|
||||
showWelcome?: boolean;
|
||||
};
|
||||
|
||||
export const Home: FC<HomeProps> = ({ visualizations = [] }) => {
|
||||
export const Home: FC<HomeProps> = ({ visualizations = [], showWelcome = true }) => {
|
||||
const router = useRouter();
|
||||
const pathname = usePathname() ?? "";
|
||||
const cookieName = "homeIntroComplete";
|
||||
|
|
@ -25,7 +26,7 @@ export const Home: FC<HomeProps> = ({ visualizations = [] }) => {
|
|||
const {
|
||||
colors: { white, leafcutterElectricBlue },
|
||||
typography: { h4 },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
const homeIntroComplete = parseInt(cookies[cookieName], 10) || 0;
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -37,14 +38,14 @@ export const Home: FC<HomeProps> = ({ visualizations = [] }) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Welcome />
|
||||
{showWelcome && <Welcome />}
|
||||
<Grid
|
||||
container
|
||||
spacing={3}
|
||||
sx={{ pt: "22px", pb: "22px" }}
|
||||
direction="row-reverse"
|
||||
>
|
||||
<Link href="/create" passHref>
|
||||
<Link href={`${process.env.LEAFCUTTER_BASE_PATH ?? ""}/create`} passHref>
|
||||
<Button
|
||||
sx={{
|
||||
fontSize: 14,
|
||||
|
|
@ -8,7 +8,7 @@ import {
|
|||
useState,
|
||||
PropsWithChildren,
|
||||
} from "react";
|
||||
import { colors, typography } from "leafcutter-common/styles/theme";
|
||||
import { colors, typography } from "../styles/theme";
|
||||
|
||||
const basePath = process.env.GITLAB_CI
|
||||
? "/link/link-stack/apps/leafcutter"
|
||||
|
|
@ -16,10 +16,12 @@ const basePath = process.env.GITLAB_CI
|
|||
const imageURL = (image: any) =>
|
||||
typeof image === "string" ? `${basePath}${image}` : `${basePath}${image.src}`;
|
||||
|
||||
const AppContext = createContext({
|
||||
const LeafcutterContext = createContext({
|
||||
colors,
|
||||
typography,
|
||||
imageURL,
|
||||
datasource: "leafcutter",
|
||||
setDatasource: null as any,
|
||||
query: null as any,
|
||||
updateQuery: null as any,
|
||||
updateQueryType: null as any,
|
||||
|
|
@ -29,7 +31,7 @@ const AppContext = createContext({
|
|||
setFoundCount: null as any,
|
||||
});
|
||||
|
||||
export const AppProvider: FC<PropsWithChildren> = ({ children }) => {
|
||||
export const LeafcutterProvider: FC<PropsWithChildren> = ({ children }) => {
|
||||
const initialState = {
|
||||
incidentType: {
|
||||
display: "Incident Type",
|
||||
|
|
@ -134,14 +136,17 @@ export const AppProvider: FC<PropsWithChildren> = ({ children }) => {
|
|||
const replaceQuery = (payload: any) => dispatch({ type: "REPLACE", payload });
|
||||
const clearQuery = () => dispatch({ type: "CLEAR" });
|
||||
const [foundCount, setFoundCount] = useState(0);
|
||||
const [datasource, setDatasource] = useState("leafcutter");
|
||||
|
||||
return (
|
||||
<AppContext.Provider
|
||||
<LeafcutterContext.Provider
|
||||
// eslint-disable-next-line react/jsx-no-constructed-context-values
|
||||
value={{
|
||||
colors,
|
||||
typography,
|
||||
imageURL,
|
||||
datasource,
|
||||
setDatasource,
|
||||
query,
|
||||
updateQuery,
|
||||
updateQueryType,
|
||||
|
|
@ -152,10 +157,10 @@ export const AppProvider: FC<PropsWithChildren> = ({ children }) => {
|
|||
}}
|
||||
>
|
||||
{children}
|
||||
</AppContext.Provider>
|
||||
</LeafcutterContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export function useAppContext() {
|
||||
return useContext(AppContext);
|
||||
export function useLeafcutterContext() {
|
||||
return useContext(LeafcutterContext);
|
||||
}
|
||||
6
packages/leafcutter-ui/components/LeafcutterWrapper.tsx
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import { FC, PropsWithChildren } from "react";
|
||||
import { Box } from "@mui/material";
|
||||
|
||||
export const LeafcutterWrapper: FC<PropsWithChildren> = ({ children }) => {
|
||||
return <Box sx={{ p: 3 }}>{children}</Box>;
|
||||
};
|
||||
21
packages/leafcutter-ui/components/LiveDataViewer.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
"use client";
|
||||
|
||||
import { FC, useEffect, useState } from "react";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
import { RawDataViewer } from "./RawDataViewer";
|
||||
import { searchVisualizationsAction } from "../actions/visualizations";
|
||||
|
||||
export const LiveDataViewer: FC = () => {
|
||||
const { query, setFoundCount, datasource } = useLeafcutterContext();
|
||||
const [rows, setRows] = useState<any[]>([]);
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
const result = await searchVisualizationsAction(datasource, query);
|
||||
setRows(result);
|
||||
setFoundCount(result?.length ?? 0);
|
||||
};
|
||||
fetchData();
|
||||
}, [query, setFoundCount, datasource]);
|
||||
|
||||
return <RawDataViewer rows={rows} height={350} />;
|
||||
};
|
||||
|
|
@ -11,7 +11,7 @@ import {
|
|||
Public as PublicIcon,
|
||||
} from "@mui/icons-material";
|
||||
import { VisualizationDetailDialog } from "./VisualizationDetailDialog";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
interface MetricSelectCardProps {
|
||||
visualizationID: string;
|
||||
|
|
@ -35,7 +35,7 @@ export const MetricSelectCard: FC<MetricSelectCardProps> = ({
|
|||
typography: { small },
|
||||
colors: { white, leafcutterElectricBlue, cdrLinkOrange },
|
||||
query,
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
/* const images = {
|
||||
actor: PrivacyTipIcon,
|
||||
incidenttype: PrivacyTipIcon,
|
||||
|
|
@ -34,7 +34,7 @@ export const OpenSearchWrapper: FC<OpenSearchWrapperProps> = ({
|
|||
>
|
||||
<Iframe
|
||||
id="opensearch"
|
||||
url={`/opensearch/${url}&_g=(filters%3A!()%2CrefreshInterval%3A(pause%3A!t%2Cvalue%3A0)%2Ctime%3A(from%3Anow-3y%2Cto%3Anow))`}
|
||||
url={`/dashboards/${url}&_g=(filters%3A!()%2CrefreshInterval%3A(pause%3A!t%2Cvalue%3A0)%2Ctime%3A(from%3Anow-3y%2Cto%3Anow))`}
|
||||
width="100%"
|
||||
height="100%"
|
||||
frameBorder={0}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
/* eslint-disable react/require-default-props */
|
||||
import { FC, PropsWithChildren } from "react";
|
||||
import { Box } from "@mui/material";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
type PageHeaderProps = PropsWithChildren<{
|
||||
backgroundColor: string;
|
||||
|
|
@ -17,7 +17,7 @@ export const PageHeader: FC<PageHeaderProps> = ({
|
|||
}: any) => {
|
||||
const {
|
||||
colors: { white },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
|
||||
return (
|
||||
<Box
|
||||
|
|
@ -21,7 +21,7 @@ import taxonomy from "../config/taxonomy.json";
|
|||
import { QueryBuilderSection } from "./QueryBuilderSection";
|
||||
import { QueryListSelector } from "./QueryListSelector";
|
||||
import { QueryDateRangeSelector } from "./QueryDateRangeSelector";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
import { Tooltip } from "./Tooltip";
|
||||
|
||||
interface QueryBuilderProps {}
|
||||
|
|
@ -32,7 +32,7 @@ export const QueryBuilder: FC<QueryBuilderProps> = () => {
|
|||
const {
|
||||
typography: { p },
|
||||
colors: { leafcutterElectricBlue, mediumGray, almostBlack },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
|
||||
const openAdvancedOptions = () => {
|
||||
setDialogOpen(false);
|
||||
|
|
@ -17,7 +17,7 @@ import {
|
|||
ExpandMore as ExpandMoreIcon,
|
||||
Help as HelpIcon,
|
||||
} from "@mui/icons-material";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
interface QueryBuilderSectionProps {
|
||||
name: string;
|
||||
|
|
@ -42,7 +42,7 @@ const Tooltip: FC<TooltipProps> = ({ title, description, children, open }) => {
|
|||
const {
|
||||
colors: { white, leafcutterElectricBlue, almostBlack },
|
||||
typography: { h5, small },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
|
||||
return (
|
||||
<MUITooltip
|
||||
|
|
@ -108,7 +108,7 @@ export const QueryBuilderSection: FC<QueryBuilderSectionProps> = ({
|
|||
colors: { white, leafcutterElectricBlue, warningPink, almostBlack },
|
||||
typography: { h6, small },
|
||||
updateQueryType,
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
const updateType = (type: string) => {
|
||||
setQueryType(type);
|
||||
updateQueryType({
|
||||
|
|
@ -4,7 +4,7 @@ import { FC, useState, useEffect } from "react";
|
|||
import { Box, Grid, TextField, Select, MenuItem } from "@mui/material";
|
||||
import { DatePicker } from "@mui/x-date-pickers-pro";
|
||||
import { useTranslate } from "react-polyglot";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
interface QueryDateRangeSelectorProps {}
|
||||
|
||||
|
|
@ -13,7 +13,7 @@ export const QueryDateRangeSelector: FC<QueryDateRangeSelectorProps> = () => {
|
|||
const [relativeDate, setRelativeDate] = useState("");
|
||||
const [startDate, setStartDate] = useState(null);
|
||||
const [endDate, setEndDate] = useState(null);
|
||||
const { updateQuery, query } = useAppContext();
|
||||
const { updateQuery, query } = useLeafcutterContext();
|
||||
useEffect(() => {
|
||||
if (!query) return;
|
||||
setStartDate(query.startDate.values[0] ?? null);
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
import { FC, useState, useEffect } from "react";
|
||||
import { Box, Grid, Tooltip } from "@mui/material";
|
||||
import { DataGridPro, GridColDef } from "@mui/x-data-grid-pro";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
interface QueryListSelectorProps {
|
||||
title: string;
|
||||
|
|
@ -24,7 +24,7 @@ export const QueryListSelector: FC<QueryListSelectorProps> = ({
|
|||
typography: { small },
|
||||
query,
|
||||
updateQuery,
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
const isExclude = query?.[keyName]?.queryType === "exclude";
|
||||
const columns: GridColDef[] = [
|
||||
{
|
||||
|
|
@ -5,14 +5,14 @@ import { Box, Grid } from "@mui/material";
|
|||
import { useTranslate } from "react-polyglot";
|
||||
import taxonomy from "../config/taxonomy.json";
|
||||
import { colors } from "../styles/theme";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
export const QueryText: FC = () => {
|
||||
const t = useTranslate();
|
||||
const {
|
||||
typography: { h6 },
|
||||
query: q,
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
|
||||
const displayNames: any = {
|
||||
incidentType: t("incidentType"),
|
||||
|
|
@ -14,7 +14,7 @@ import {
|
|||
ExpandMore as ExpandMoreIcon,
|
||||
Circle as CircleIcon,
|
||||
} from "@mui/icons-material";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
interface QuestionProps {
|
||||
question: string;
|
||||
|
|
@ -26,7 +26,7 @@ export const Question: FC<QuestionProps> = ({ question, answer }) => {
|
|||
const {
|
||||
colors: { lavender, darkLavender },
|
||||
typography: { h5, p },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
|
||||
return (
|
||||
<Accordion
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
"use client";
|
||||
|
||||
import { FC } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Box, Grid } from "@mui/material";
|
||||
import { DataGridPro } from "@mui/x-data-grid-pro";
|
||||
import { useTranslate } from "react-polyglot";
|
||||
|
|
@ -12,14 +13,23 @@ interface RawDataViewerProps {
|
|||
|
||||
export const RawDataViewer: FC<RawDataViewerProps> = ({ rows, height }) => {
|
||||
const t = useTranslate();
|
||||
const router = useRouter();
|
||||
const columns = [
|
||||
{
|
||||
field: "date",
|
||||
headerName: t("date"),
|
||||
field: "open_date",
|
||||
headerName: "Open Date", //t("date"),
|
||||
editable: false,
|
||||
flex: 0.7,
|
||||
valueFormatter: ({ value }: any) => new Date(value).toLocaleDateString(),
|
||||
},
|
||||
{
|
||||
field: "close_date",
|
||||
headerName: "Close Date", // t("date"),
|
||||
editable: false,
|
||||
flex: 0.7,
|
||||
valueFormatter: ({ value }: any) => new Date(value).toLocaleDateString(),
|
||||
},
|
||||
|
||||
{
|
||||
field: "incident",
|
||||
headerName: t("incident"),
|
||||
|
|
@ -77,6 +87,7 @@ export const RawDataViewer: FC<RawDataViewerProps> = ({ rows, height }) => {
|
|||
disableColumnMenu
|
||||
scrollbarSize={10}
|
||||
disableVirtualization
|
||||
onCellClick={(e) => router.push("/tickets/" + e.row.id)}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
|
@ -12,7 +12,7 @@ import {
|
|||
} from "@mui/material";
|
||||
import { Close as CloseIcon } from "@mui/icons-material";
|
||||
import { useTranslate } from "react-polyglot";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
interface TooltipProps {
|
||||
title: string;
|
||||
|
|
@ -38,7 +38,7 @@ export const Tooltip: FC<TooltipProps> = ({
|
|||
const {
|
||||
typography: { p, small },
|
||||
colors: { white, leafcutterElectricBlue, almostBlack },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
const router = useRouter();
|
||||
const pathname = usePathname() ?? "";
|
||||
const searchParams = useSearchParams();
|
||||
|
|
@ -5,7 +5,7 @@ import { Grid, Box } from "@mui/material";
|
|||
import { useTranslate } from "react-polyglot";
|
||||
import { PageHeader } from "./PageHeader";
|
||||
import { VisualizationCard } from "./VisualizationCard";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
type TrendsProps = {
|
||||
visualizations: any;
|
||||
|
|
@ -16,7 +16,7 @@ export const Trends: FC<TrendsProps> = ({ visualizations }) => {
|
|||
const {
|
||||
colors: { cdrLinkOrange },
|
||||
typography: { h1, h4, p },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -32,7 +32,7 @@ import { Tooltip } from "./Tooltip";
|
|||
import visualizationMap from "../config/visualizationMap.json";
|
||||
import { VisualizationSelectCard } from "./VisualizationSelectCard";
|
||||
import { MetricSelectCard } from "./MetricSelectCard";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
interface VisualizationBuilderProps {
|
||||
templates: any[];
|
||||
|
|
@ -49,7 +49,9 @@ export const VisualizationBuilder: FC<VisualizationBuilderProps> = ({
|
|||
query,
|
||||
replaceQuery,
|
||||
clearQuery,
|
||||
} = useAppContext();
|
||||
datasource,
|
||||
setDatasource,
|
||||
} = useLeafcutterContext();
|
||||
const { visualizations } = visualizationMap;
|
||||
const [selectedVisualizationType, setSelectedVisualizationType] = useState(
|
||||
null as any,
|
||||
|
|
@ -194,6 +196,24 @@ export const VisualizationBuilder: FC<VisualizationBuilderProps> = ({
|
|||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() =>
|
||||
setDatasource(
|
||||
datasource === "leafcutter" ? "zammad" : "leafcutter",
|
||||
)
|
||||
}
|
||||
sx={{
|
||||
backgroundColor: cdrLinkOrange,
|
||||
textTransform: "none",
|
||||
fontStyle: "italic",
|
||||
fontWeight: "bold",
|
||||
mr: 2,
|
||||
}}
|
||||
>
|
||||
{datasource === "zammad" ? "Switch to Global" : "Switch to Local"}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
aria-describedby={elementID}
|
||||
variant="contained"
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
import { FC, useState } from "react";
|
||||
import { Grid, Card, Box } from "@mui/material";
|
||||
import Iframe from "react-iframe";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
import { VisualizationDetailDialog } from "./VisualizationDetailDialog";
|
||||
|
||||
interface VisualizationCardProps {
|
||||
|
|
@ -24,7 +24,7 @@ export const VisualizationCard: FC<VisualizationCardProps> = ({
|
|||
const {
|
||||
typography: { h4, p },
|
||||
colors: { leafcutterLightBlue, leafcutterElectricBlue },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
const finalURL = `${process.env.NEXT_PUBLIC_LEAFCUTTER_URL}${url}&_g=(filters%3A!()%2CrefreshInterval%3A(pause%3A!t%2Cvalue%3A0)%2Ctime%3A(from%3Anow-3y%2Cto%3Anow))`;
|
||||
|
||||
return (
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
import { FC } from "react";
|
||||
import { Box } from "@mui/material";
|
||||
import Iframe from "react-iframe";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
interface VisualizationDetailProps {
|
||||
id: string;
|
||||
|
|
@ -23,7 +23,7 @@ export const VisualizationDetail: FC<VisualizationDetailProps> = ({
|
|||
const {
|
||||
colors: { mediumGray },
|
||||
typography: { h4, p },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
const finalURL = `${url}&_g=(filters%3A!()%2CrefreshInterval%3A(pause%3A!t%2Cvalue%3A0)%2Ctime%3A(from%3Anow-3y%2Cto%3Anow))`;
|
||||
console.log({ finalURL });
|
||||
return (
|
||||
|
|
@ -11,7 +11,7 @@ import {
|
|||
TextField,
|
||||
} from "@mui/material";
|
||||
import { useTranslate } from "react-polyglot";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
import { VisualizationDetail } from "./VisualizationDetail";
|
||||
|
||||
interface VisualizationDetailDialogProps {
|
||||
|
|
@ -37,7 +37,7 @@ export const VisualizationDetailDialog: FC<VisualizationDetailDialogProps> = ({
|
|||
const {
|
||||
colors: { leafcutterElectricBlue, leafcutterLightBlue, white, almostBlack },
|
||||
query,
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
|
||||
const deleteAndClose = async () => {
|
||||
await fetch(`/api/visualizations/delete`, {
|
||||
|
|
@ -13,7 +13,7 @@ import lineStacked from "../images/line-stacked.svg";
|
|||
import dataTable from "../images/data-table.svg";
|
||||
import metric from "../images/metric.svg";
|
||||
import tagCloud from "../images/tag-cloud.svg";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
interface VisualizationSelectCardProps {
|
||||
visualizationType: string;
|
||||
|
|
@ -38,7 +38,7 @@ export const VisualizationSelectCard: FC<VisualizationSelectCardProps> = ({
|
|||
leafcutterLightBlue,
|
||||
cdrLinkOrange,
|
||||
},
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
const images: any = {
|
||||
horizontalBar,
|
||||
horizontalBarStacked,
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
import { Box, Grid } from "@mui/material";
|
||||
import { useSession } from "next-auth/react";
|
||||
import { useTranslate } from "react-polyglot";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
export const Welcome = () => {
|
||||
const t = useTranslate();
|
||||
|
|
@ -17,7 +17,7 @@ export const Welcome = () => {
|
|||
const {
|
||||
colors: { white, leafcutterElectricBlue },
|
||||
typography: { h1, h4, p },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
|
||||
return (
|
||||
<Box
|
||||
|
|
@ -4,7 +4,7 @@ import { Box, Grid, Dialog, Button } from "@mui/material";
|
|||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
// import { useSession } from "next-auth/react";
|
||||
// import { useTranslate } from "react-polyglot";
|
||||
import { useAppContext } from "./AppProvider";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
|
||||
export const WelcomeDialog = () => {
|
||||
// const t = useTranslate();
|
||||
|
|
@ -15,7 +15,7 @@ export const WelcomeDialog = () => {
|
|||
const {
|
||||
colors: { white, leafcutterElectricBlue },
|
||||
typography: { h1, h6, p },
|
||||
} = useAppContext();
|
||||
} = useLeafcutterContext();
|
||||
const activeTooltip = searchParams?.get("tooltip")?.toString();
|
||||
const open = activeTooltip === "welcome";
|
||||
|
||||
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 164 KiB After Width: | Height: | Size: 164 KiB |
|
Before Width: | Height: | Size: 520 B After Width: | Height: | Size: 520 B |
|
Before Width: | Height: | Size: 557 B After Width: | Height: | Size: 557 B |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 875 B After Width: | Height: | Size: 875 B |
|
Before Width: | Height: | Size: 686 KiB After Width: | Height: | Size: 686 KiB |
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 107 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 215 B After Width: | Height: | Size: 215 B |
|
Before Width: | Height: | Size: 632 B After Width: | Height: | Size: 632 B |
|
Before Width: | Height: | Size: 625 B After Width: | Height: | Size: 625 B |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 844 B After Width: | Height: | Size: 844 B |
|
Before Width: | Height: | Size: 322 B After Width: | Height: | Size: 322 B |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 570 B After Width: | Height: | Size: 570 B |
|
Before Width: | Height: | Size: 473 B After Width: | Height: | Size: 473 B |
|
Before Width: | Height: | Size: 447 B After Width: | Height: | Size: 447 B |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 643 B After Width: | Height: | Size: 643 B |
|
Before Width: | Height: | Size: 643 B After Width: | Height: | Size: 643 B |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 547 B After Width: | Height: | Size: 547 B |
|
Before Width: | Height: | Size: 419 B After Width: | Height: | Size: 419 B |
|
Before Width: | Height: | Size: 548 B After Width: | Height: | Size: 548 B |
|
Before Width: | Height: | Size: 549 B After Width: | Height: | Size: 549 B |
|
Before Width: | Height: | Size: 806 B After Width: | Height: | Size: 806 B |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 845 B After Width: | Height: | Size: 845 B |
|
Before Width: | Height: | Size: 976 B After Width: | Height: | Size: 976 B |
|
Before Width: | Height: | Size: 704 B After Width: | Height: | Size: 704 B |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 464 B After Width: | Height: | Size: 464 B |
|
Before Width: | Height: | Size: 292 B After Width: | Height: | Size: 292 B |
|
Before Width: | Height: | Size: 341 B After Width: | Height: | Size: 341 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 449 B After Width: | Height: | Size: 449 B |
|
Before Width: | Height: | Size: 449 B After Width: | Height: | Size: 449 B |
|
|
@ -1,5 +1,9 @@
|
|||
import en from "./locales/en.json";
|
||||
import fr from "./locales/fr.json";
|
||||
export const locales = {
|
||||
en,
|
||||
fr,
|
||||
};
|
||||
export { Home } from "./components/Home";
|
||||
export { Create } from "./components/Create";
|
||||
export { Trends } from "./components/Trends";
|
||||
|
|
@ -10,7 +14,6 @@ export { Preview } from "./components/Preview";
|
|||
export { GettingStartedDialog } from "./components/GettingStartedDialog";
|
||||
export { VisualizationDetail } from "./components/VisualizationDetail";
|
||||
export { OpenSearchWrapper } from "./components/OpenSearchWrapper";
|
||||
export const locales = {
|
||||
en,
|
||||
fr,
|
||||
};
|
||||
export { LeafcutterWrapper } from "./components/LeafcutterWrapper";
|
||||
export { LeafcutterProvider, useLeafcutterContext } from "./components/LeafcutterProvider";
|
||||
|
||||