Bridge integration
This commit is contained in:
parent
42a5e09c94
commit
162390008b
56 changed files with 776 additions and 591 deletions
|
|
@ -8,6 +8,7 @@ import { Button, Dialog, TextField, Select, MultiValueField } from "ui";
|
|||
import { generateCreateAction } from "../lib/actions";
|
||||
import { FieldDescription } from "../lib/service";
|
||||
import { serviceConfig } from "../config/config";
|
||||
import { getBasePath } from "../lib/frontendUtils";
|
||||
|
||||
type CreateProps = {
|
||||
service: string;
|
||||
|
|
@ -51,7 +52,7 @@ export const Create: FC<CreateProps> = ({ service }) => {
|
|||
|
||||
useEffect(() => {
|
||||
if (formState.success) {
|
||||
router.push(`/${entity}/${formState.values.id}`);
|
||||
router.push(`${getBasePath()}${entity}/${formState.values.id}`);
|
||||
}
|
||||
}, [formState.success, router, entity, formState.values.id]);
|
||||
|
||||
|
|
@ -60,14 +61,14 @@ export const Create: FC<CreateProps> = ({ service }) => {
|
|||
open
|
||||
title={`Create ${displayName}`}
|
||||
formAction={formAction}
|
||||
onClose={() => router.push(`/${entity}`)}
|
||||
onClose={() => router.push(`${getBasePath()}${entity}`)}
|
||||
buttons={
|
||||
<Grid container justifyContent="space-between">
|
||||
<Grid item>
|
||||
<Button
|
||||
text="Cancel"
|
||||
kind="secondary"
|
||||
onClick={() => router.push(`/${entity}`)}
|
||||
onClick={() => router.push(`${getBasePath()}${entity}`)}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { type Database } from "bridge-common";
|
|||
import { generateDeleteAction } from "../lib/actions";
|
||||
import { serviceConfig } from "../config/config";
|
||||
import { FieldDescription } from "../lib/service";
|
||||
import { getBasePath } from "../lib/frontendUtils";
|
||||
|
||||
type DetailProps = {
|
||||
service: string;
|
||||
|
|
@ -29,7 +30,7 @@ export const Detail: FC<DetailProps> = ({ service, row }) => {
|
|||
const continueDeleteAction = async () => {
|
||||
await deleteAction?.(id);
|
||||
setShowDeleteConfirmation(false);
|
||||
router.push(`/${entity}`);
|
||||
router.push(`${getBasePath()}${entity}`);
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
@ -37,7 +38,7 @@ export const Detail: FC<DetailProps> = ({ service, row }) => {
|
|||
<Dialog
|
||||
open
|
||||
title={`${displayName} Detail`}
|
||||
onClose={() => router.push(`/${entity}`)}
|
||||
onClose={() => router.push(`${getBasePath()}${entity}`)}
|
||||
buttons={
|
||||
<Grid container justifyContent="space-between">
|
||||
<Grid item container xs="auto" spacing={2}>
|
||||
|
|
@ -52,12 +53,16 @@ export const Detail: FC<DetailProps> = ({ service, row }) => {
|
|||
<Button
|
||||
text="Edit"
|
||||
kind="secondary"
|
||||
href={`/${entity}/${id}/edit`}
|
||||
href={`${getBasePath()}${entity}/${id}/edit`}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button text="Done" kind="primary" href={`/${entity}`} />
|
||||
<Button
|
||||
text="Done"
|
||||
kind="primary"
|
||||
href={`${getBasePath()}${entity}`}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { type Database } from "bridge-common";
|
|||
import { generateUpdateAction } from "../lib/actions";
|
||||
import { serviceConfig } from "../config/config";
|
||||
import { FieldDescription } from "../lib/service";
|
||||
import { getBasePath } from "../lib/frontendUtils";
|
||||
|
||||
type EditProps = {
|
||||
service: string;
|
||||
|
|
@ -51,7 +52,7 @@ export const Edit: FC<EditProps> = ({ service, row }) => {
|
|||
|
||||
useEffect(() => {
|
||||
if (formState.success) {
|
||||
router.push(`/${entity}`);
|
||||
router.push(`${getBasePath()}${entity}`);
|
||||
}
|
||||
}, [formState.success, router, entity]);
|
||||
|
||||
|
|
@ -60,14 +61,14 @@ export const Edit: FC<EditProps> = ({ service, row }) => {
|
|||
open
|
||||
title={`Edit ${displayName}`}
|
||||
formAction={formAction}
|
||||
onClose={() => router.push(`/${entity}`)}
|
||||
onClose={() => router.push(`${getBasePath()}${entity}`)}
|
||||
buttons={
|
||||
<Grid container justifyContent="space-between">
|
||||
<Grid item>
|
||||
<Button
|
||||
text="Cancel"
|
||||
kind="secondary"
|
||||
onClick={() => router.push(`/${entity}`)}
|
||||
onClick={() => router.push(`${getBasePath()}${entity}`)}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
|
|
|
|||
5
packages/bridge-ui/components/Home.tsx
Normal file
5
packages/bridge-ui/components/Home.tsx
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import { FC } from "react";
|
||||
|
||||
export const Home: FC = () => {
|
||||
return <h1>Home</h1>;
|
||||
};
|
||||
|
|
@ -6,6 +6,7 @@ import { List as InternalList, Button } from "ui";
|
|||
import { type Selectable } from "kysely";
|
||||
import { type Database } from "bridge-common";
|
||||
import { serviceConfig } from "../config/config";
|
||||
import { getBasePath } from "../lib/frontendUtils";
|
||||
|
||||
type ListProps = {
|
||||
service: string;
|
||||
|
|
@ -18,7 +19,7 @@ export const List: FC<ListProps> = ({ service, rows }) => {
|
|||
const router = useRouter();
|
||||
|
||||
const onRowClick = (id: string) => {
|
||||
router.push(`/${entity}/${id}`);
|
||||
router.push(`${getBasePath()}${entity}/${id}`);
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
@ -28,7 +29,11 @@ export const List: FC<ListProps> = ({ service, rows }) => {
|
|||
columns={listColumns}
|
||||
onRowClick={onRowClick}
|
||||
buttons={
|
||||
<Button text="Create" kind="primary" href={`/${entity}/create`} />
|
||||
<Button
|
||||
text="Create"
|
||||
kind="primary"
|
||||
href={`${getBasePath()}${entity}/create`}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -149,9 +149,14 @@ export const webhooksConfig: ServiceConfig = {
|
|||
flex: 1,
|
||||
},
|
||||
{
|
||||
field: "description",
|
||||
headerName: "Description",
|
||||
flex: 2,
|
||||
field: "backendType",
|
||||
headerName: "Type",
|
||||
flex: 1,
|
||||
},
|
||||
{
|
||||
field: "endpointUrl",
|
||||
headerName: "Endpoint",
|
||||
flex: 1,
|
||||
},
|
||||
{
|
||||
field: "updatedAt",
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
export { Home } from "./components/Home";
|
||||
export { List } from "./components/List";
|
||||
export { Create } from "./components/Create";
|
||||
export { Edit } from "./components/Edit";
|
||||
|
|
|
|||
10
packages/bridge-ui/lib/frontendUtils.ts
Normal file
10
packages/bridge-ui/lib/frontendUtils.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
export const getBasePath = (): string => {
|
||||
if (
|
||||
typeof window !== "undefined" &&
|
||||
window?.location?.pathname?.includes("/admin/bridge")
|
||||
) {
|
||||
return "/admin/bridge/";
|
||||
}
|
||||
|
||||
return "/";
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,18 +1,27 @@
|
|||
"use server";
|
||||
|
||||
import { performLeafcutterQuery, performZammadQuery, createUserVisualization } from "opensearch-common";
|
||||
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 createUserVisualizationAction = async ({
|
||||
visualizationID,
|
||||
title,
|
||||
description,
|
||||
query,
|
||||
}: any) => {
|
||||
const email = "xxx@example.com";
|
||||
const id = await createUserVisualization({
|
||||
email,
|
||||
visualizationID,
|
||||
title,
|
||||
description,
|
||||
query,
|
||||
});
|
||||
return id;
|
||||
};
|
||||
|
||||
export const searchVisualizationsAction = async (
|
||||
kind: string,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
import { useEffect, FC } from "react";
|
||||
import { useRouter, usePathname } from "next/navigation";
|
||||
import Link from "next/link";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import { Grid, Button } from "@mui/material";
|
||||
import { useTranslate } from "react-polyglot";
|
||||
import { useCookies } from "react-cookie";
|
||||
|
|
@ -11,13 +10,18 @@ import { Welcome } from "./Welcome";
|
|||
import { WelcomeDialog } from "./WelcomeDialog";
|
||||
import { VisualizationCard } from "./VisualizationCard";
|
||||
import { useLeafcutterContext } from "./LeafcutterProvider";
|
||||
import { getBasePath } from "../lib/utils";
|
||||
|
||||
type HomeProps = {
|
||||
visualizations: any;
|
||||
showWelcome?: boolean;
|
||||
};
|
||||
|
||||
export const Home: FC<HomeProps> = ({ visualizations = [], showWelcome = true }) => {
|
||||
export const Home: FC<HomeProps> = ({
|
||||
visualizations = [],
|
||||
showWelcome = true,
|
||||
}) => {
|
||||
console.log("Home", visualizations);
|
||||
const router = useRouter();
|
||||
const pathname = usePathname() ?? "";
|
||||
const cookieName = "homeIntroComplete";
|
||||
|
|
@ -45,7 +49,7 @@ export const Home: FC<HomeProps> = ({ visualizations = [], showWelcome = true })
|
|||
sx={{ pt: "22px", pb: "22px" }}
|
||||
direction="row-reverse"
|
||||
>
|
||||
<Link href={`${process.env.LEAFCUTTER_BASE_PATH ?? ""}/create`} passHref>
|
||||
<Link href={`${getBasePath()}/create`} passHref>
|
||||
<Button
|
||||
sx={{
|
||||
fontSize: 14,
|
||||
|
|
@ -81,7 +85,11 @@ export const Home: FC<HomeProps> = ({ visualizations = [], showWelcome = true })
|
|||
justifyContent="center"
|
||||
>
|
||||
<Grid item sx={{ ...h4, width: 450, textAlign: "center" }}>
|
||||
<ReactMarkdown>{t("noSavedVisualizations")}</ReactMarkdown>
|
||||
{"You don’t have any saved visualizations. Go to "}
|
||||
<Link href={`${getBasePath()}/create`}>Search and Create</Link>
|
||||
{" or "}
|
||||
<Link href={`${getBasePath()}/trends`}>Trends</Link>
|
||||
{" to get started."}
|
||||
</Grid>
|
||||
</Grid>
|
||||
) : null}
|
||||
|
|
|
|||
9
packages/leafcutter-ui/lib/frontendUtils.ts
Normal file
9
packages/leafcutter-ui/lib/frontendUtils.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
export const getBasePath = (): string => {
|
||||
const basePath = process.env.LEAFCUTTER_BASE_PATH;
|
||||
|
||||
if (basePath && basePath !== "") {
|
||||
return `${basePath}`;
|
||||
}
|
||||
|
||||
return "";
|
||||
};
|
||||
9
packages/leafcutter-ui/lib/utils.ts
Normal file
9
packages/leafcutter-ui/lib/utils.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
export const getBasePath = (): string => {
|
||||
const basePath = process.env.NEXT_PUBLIC_LEAFCUTTER_BASE_PATH;
|
||||
|
||||
if (basePath && basePath !== "") {
|
||||
return `${basePath}`;
|
||||
}
|
||||
|
||||
return "";
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -329,7 +329,7 @@ export const getUserVisualizations = async (email: string, limit: number) => {
|
|||
url: getEmbedURL("private", getDocumentID(hit)),
|
||||
}));
|
||||
|
||||
return results;
|
||||
return []; //results;
|
||||
};
|
||||
|
||||
/* Global */
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
38
packages/ui/components/Autocomplete.tsx
Normal file
38
packages/ui/components/Autocomplete.tsx
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import { FC } from "react";
|
||||
import { TextField, Autocomplete as AutocompleteInternal } from "@mui/material";
|
||||
import { colors } from "../styles/theme";
|
||||
|
||||
type AutocompleteProps = {
|
||||
name: string;
|
||||
label: string;
|
||||
options: any[];
|
||||
formState: Record<string, any>;
|
||||
disabled?: boolean;
|
||||
required?: boolean;
|
||||
};
|
||||
|
||||
export const Autocomplete: FC<AutocompleteProps> = ({
|
||||
name,
|
||||
label,
|
||||
options,
|
||||
formState,
|
||||
disabled = false,
|
||||
required = false,
|
||||
}) => (
|
||||
<AutocompleteInternal
|
||||
disablePortal
|
||||
options={options}
|
||||
defaultValue={formState.values[name]}
|
||||
fullWidth
|
||||
size="small"
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
label={label}
|
||||
disabled={disabled}
|
||||
required={required}
|
||||
sx={{ backgroundColor: colors.white }}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
|
|
@ -10,6 +10,7 @@ interface ListProps {
|
|||
rows: any;
|
||||
columns: GridColDef<any>[];
|
||||
onRowClick?: (id: string) => void;
|
||||
getRowID?: (row: any) => any;
|
||||
buttons?: React.ReactNode;
|
||||
paginate?: boolean;
|
||||
}
|
||||
|
|
@ -19,12 +20,20 @@ export const List: FC<ListProps> = ({
|
|||
rows,
|
||||
columns,
|
||||
onRowClick,
|
||||
getRowID,
|
||||
buttons,
|
||||
paginate = false,
|
||||
}) => {
|
||||
const { h3 } = typography;
|
||||
const { mediumGray, lightGray, veryLightGray, mediumBlue, white, darkGray } =
|
||||
colors;
|
||||
const getRowIDInternal = (row: any) => {
|
||||
if (getRowID) {
|
||||
return getRowID(row);
|
||||
}
|
||||
|
||||
return row.id;
|
||||
};
|
||||
|
||||
return (
|
||||
<Box sx={{ height: "100vh", backgroundColor: lightGray, p: 3 }}>
|
||||
|
|
@ -92,7 +101,7 @@ export const List: FC<ListProps> = ({
|
|||
scrollbarSize={0}
|
||||
disableVirtualization
|
||||
disableColumnMenu
|
||||
onRowClick={(row: any) => onRowClick?.(row.id)}
|
||||
onRowClick={({ row }: any) => onRowClick?.(getRowIDInternal(row))}
|
||||
/>
|
||||
</Box>
|
||||
</Grid>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import { fonts } from "../styles/theme";
|
|||
// import { useSession, signOut } from "next-auth/react";
|
||||
|
||||
const openWidth = 270;
|
||||
const closedWidth = 100;
|
||||
const closedWidth = 70;
|
||||
|
||||
const MenuItem = ({
|
||||
name,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import Image from "next/image";
|
|||
import { fonts } from "../styles/theme";
|
||||
|
||||
const openWidth = 270;
|
||||
const closedWidth = 100;
|
||||
const closedWidth = 70;
|
||||
|
||||
export const SidebarItem: FC = ({
|
||||
name,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
IconButton,
|
||||
} from "@mui/material";
|
||||
import { Refresh as RefreshIcon } from "@mui/icons-material";
|
||||
import { colors } from "../styles/theme";
|
||||
import { colors, fonts } from "../styles/theme";
|
||||
|
||||
type TextFieldProps = {
|
||||
name: string;
|
||||
|
|
@ -28,7 +28,8 @@ export const TextField: FC<TextFieldProps> = ({
|
|||
lines = 1,
|
||||
helperText,
|
||||
}) => {
|
||||
const { darkMediumGray } = colors;
|
||||
const { darkMediumGray, white } = colors;
|
||||
const { roboto } = fonts;
|
||||
|
||||
return (
|
||||
<InternalTextField
|
||||
|
|
@ -58,7 +59,8 @@ export const TextField: FC<TextFieldProps> = ({
|
|||
) : null,
|
||||
|
||||
sx: {
|
||||
backgroundColor: "#fff",
|
||||
fontFamily: roboto.style.fontFamily,
|
||||
backgroundColor: white,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ export { Button } from "./components/Button";
|
|||
export { TextField } from "./components/TextField";
|
||||
export { DisplayTextField } from "./components/DisplayTextField";
|
||||
export { Select } from "./components/Select";
|
||||
export { Autocomplete } from "./components/Autocomplete";
|
||||
export { MultiValueField } from "./components/MultiValueField";
|
||||
export { Dialog } from "./components/Dialog";
|
||||
export { fonts, typography, colors } from "./styles/theme";
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue