Skip to content

Commit

Permalink
Merge pull request #202 from Tauffer-Consulting/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
vinicvaz authored Dec 28, 2023
2 parents 1c54bdf + dd2c7be commit e9c9a36
Show file tree
Hide file tree
Showing 52 changed files with 2,403 additions and 1,250 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/release-frontend-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ jobs:
tags: ghcr.io/tauffer-consulting/domino-frontend:k8s-dev
context: frontend
file: frontend/Dockerfile.prod # Path to the Dockerfile
env:
API_ENV: dev

release-domino-frontend-compose:
name: Domino Frontend Image
Expand All @@ -58,5 +56,4 @@ jobs:
context: frontend
file: frontend/Dockerfile.prod # Path to the Dockerfile
env:
API_ENV: local
DOMINO_DEPLOY_MODE: local-compose
3 changes: 0 additions & 3 deletions .github/workflows/release-frontend.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ jobs:
tags: ghcr.io/tauffer-consulting/domino-frontend:k8s
context: frontend
file: frontend/Dockerfile.prod # Path to the Dockerfile
env:
VITE_API_ENV: prod

release-domino-frontend-compose:
name: Domino Frontend Image
Expand All @@ -58,5 +56,4 @@ jobs:
context: frontend
file: frontend/Dockerfile.prod # Path to the Dockerfile
env:
API_ENV: local
DOMINO_DEPLOY_MODE: local-compose
2 changes: 1 addition & 1 deletion docker-compose-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -362,8 +362,8 @@ services:
container_name: domino-frontend
command: yarn start
environment:
- API_ENV=local
- DOMINO_DEPLOY_MODE=local-compose
- API_URL=http://localhost:8000
ports:
- 3000:3000
volumes:
Expand Down
2 changes: 1 addition & 1 deletion frontend/.env.production
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# These values are placeholders
API_ENV="local"
DOMINO_DEPLOY_MODE="local-compose"
API_URL="http://localhost:8000"
25 changes: 10 additions & 15 deletions frontend/Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
# Refs:
# https://dev.to/otomato_io/how-to-optimize-production-docker-images-running-nodejs-with-yarn-504b
# https://snyk.io/blog/10-best-practices-to-containerize-nodejs-web-applications-with-docker/
FROM node:18-alpine

ENV VITE_API_ENV=dev

# ENV PATH /app/node_modules/.bin:$PATH
# Build Stage
FROM node:18-alpine as build
WORKDIR /usr/src/app
COPY --chown=node:node . /usr/src/app
RUN mkdir -p node_modules/.cache
RUN chmod -R 777 node_modules/.cache
RUN mkdir -p node_modules/.vite
RUN chmod -R 777 node_modules/.vite

RUN yarn install --frozen-lockfile && yarn cache clean
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

# Final Stage
FROM node:18-alpine
WORKDIR /usr/src/app
COPY --from=build /usr/src/app/node_modules ./node_modules
COPY . .
RUN chmod -R 777 node_modules/
USER node
CMD ["yarn", "start"]
2 changes: 1 addition & 1 deletion frontend/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#!/bin/sh
set -e

echo "API_ENV=$API_ENV" >> .env.production
echo "DOMINO_DEPLOY_MODE=$DOMINO_DEPLOY_MODE" >> .env.production
echo "API_URL=$API_URL" >> .env.production

/usr/share/nginx/html/import-meta-env -x .env.production -p /usr/share/nginx/html/index.html || exit 1

Expand Down
14 changes: 8 additions & 6 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@
"node": ">=18 < 20"
},
"dependencies": {
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@iconify/react": "^4.1.1",
"@import-meta-env/cli": "^0.6.6",
"@import-meta-env/unplugin": "^0.4.10",
"@material-ui/core": "^4.12.4",
"@mui/icons-material": "^5.11.0",
"@mui/lab": "^5.0.0-alpha.113",
"@mui/material": "^5.11.1",
"@mui/lab": "^5.0.0-alpha.155",
"@mui/material": "^5.14.20",
"@mui/x-data-grid": "^6.15.0",
"@mui/x-date-pickers": "^6.5.0",
"@types/dompurify": "^3.0.5",
"@types/react": ">=18",
"@types/react-dom": "^18.0.9",
"@types/react-plotly.js": "^2.6.3",
"@types/uuid": "^9.0.0",
Expand All @@ -25,7 +26,6 @@
"axios": "^1.2.1",
"axios-mock-adapter": "^1.21.2",
"cross-env": "^7.0.3",
"date-fns": "^2.30.0",
"dayjs": "^1.11.7",
"dotenv": "^16.3.1",
"elkjs": "^0.8.2",
Expand All @@ -36,8 +36,10 @@
"react-draggable": "^4.4.5",
"react-hook-form": "^7.45.1",
"react-markdown": "9.0.0",
"react-pdf": "^7.6.0",
"react-plotly.js": "^2.6.0",
"react-router-dom": "^6.6.0",
"react-to-print": "^2.14.15",
"react-toastify": "^9.1.1",
"reactflow": "^11.4.0",
"remark-gfm": "^4.0.0",
Expand Down
9 changes: 5 additions & 4 deletions frontend/src/@types/utils/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ declare global {
) => infer R
? R
: T extends (
instance: ReactFlowInstance<NodeData, EdgeData>,
) => Promise<infer R>
? R
: never;
instance: ReactFlowInstance<NodeData, EdgeData>,
) => Promise<infer R>
? R
: never;
}

export {};
73 changes: 73 additions & 0 deletions frontend/src/components/DownloadB64Button/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Tooltip, type ButtonProps, Button } from "@mui/material";
import React, { useCallback } from "react";

interface Props extends ButtonProps {
base64_content: string;
file_type: string;
}

export const DownloadB64Button: React.FC<Props> = ({
base64_content,
file_type,
...props
}) => {
const downloadContent = useCallback(() => {
let href = "";
switch (file_type) {
case "txt":
href = `data:text/plain;base64,${base64_content}`;
break;
case "plotly_json":
case "json":
href = `data:application/json;base64,${base64_content}`;
break;
case "jpeg":
case "jpg":
case "png":
case "bmp":
case "gif":
case "tiff":
href = `data:image/${file_type};base64,${base64_content}`;
break;
case "svg":
href = `data:image/svg+xml;base64,${base64_content}`;
break;
case "md":
href = `data:text/markdown;base64,${base64_content}`;
break;
case "pdf":
href = `data:application/pdf;base64,${base64_content}`;
break;
case "html":
href = `data:text/html;base64,${base64_content}`;
break;
default:
href = `data:text/plain;base64,${base64_content}`;
break;
}

const a = document.createElement("a"); // Create <a>
a.href = href; // Image Base64 Goes here
a.download = `download.${file_type}`; // File name Here
a.click(); // Downloaded file
}, [base64_content, file_type]);

return (
<Tooltip
title={
!base64_content || !file_type
? "Missing base64_content of file_type"
: "Will download the raw result content "
}
>
<Button
variant="contained"
onClick={downloadContent}
disabled={!base64_content || !file_type}
{...props}
>
Download content
</Button>
</Tooltip>
);
};
33 changes: 33 additions & 0 deletions frontend/src/components/DownloadPDF/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Button, type ButtonProps } from "@mui/material";
import React, { useEffect, useState } from "react";
import { useReactToPrint } from "react-to-print";

interface Props extends ButtonProps {
contentId: string;
}

export const DownloadAsPDF: React.FC<Props> = ({ contentId, ...props }) => {
const [content, setContent] = useState<HTMLElement | null>(null);
const handlePrint = useReactToPrint({
content: () => content,
});

useEffect(() => {
// Fetch the content element using the contentId
const newContent = document.getElementById(contentId);
setContent(newContent);
}, [contentId]);

const handlePrintWithTimeout = () => {
// Add a short timeout to ensure styles are applied before printing
setTimeout(() => {
handlePrint();
}, 2000); // Adjust the timeout duration as needed
};

return (
<Button variant="outlined" onClick={handlePrintWithTimeout} {...props}>
Generate PDF
</Button>
);
};
45 changes: 45 additions & 0 deletions frontend/src/components/HTMLRender/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React, { useRef, useState } from "react";

interface Props {
html: string;
}

const HtmlRenderer: React.FC<Props> = ({ html }) => {
const iframeRef = useRef<HTMLIFrameElement | null>(null);
const [minHeight, setMinHeight] = useState<number>(0);

const handleLoad = () => {
const iframe = iframeRef.current;
if (iframe) {
const newMinHeight =
iframe.contentWindow?.document.body.scrollHeight ?? 0;
setMinHeight(newMinHeight);
iframe.style.height = `${newMinHeight}px`;
}
};

return (
<div
style={{
minHeight: `${minHeight}px`,
height: "100%",
width: "100%",
overflowY: "hidden",
overflowX: "auto",
}}
>
<iframe
ref={iframeRef}
title="html-renderer"
srcDoc={html}
width="100%"
height="100%"
style={{ border: "none" }}
scrolling="no"
onLoad={handleLoad}
></iframe>
</div>
);
};

export default HtmlRenderer;
92 changes: 92 additions & 0 deletions frontend/src/components/RenderB64/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { Typography } from "@mui/material";
import HtmlRenderer from "components/HTMLRender";
import { RenderPDF } from "components/RenderPDF";
import React, { type CSSProperties } from "react";
import ReactMarkdown from "react-markdown";
import Plot from "react-plotly.js";
import remarkGfm from "remark-gfm";

interface Props {
base64_content: string;
file_type: string;
style?: CSSProperties;
}

export const RenderB64: React.FC<Props> = ({
base64_content,
file_type,
style,
}) => {
if (!base64_content || !file_type) {
return <Typography variant="h2">No content</Typography>;
}
switch (file_type) {
case "txt":
return <pre style={style}>{window.atob(base64_content)}</pre>;
case "json":
return (
<pre style={style}>
{JSON.stringify(JSON.parse(window.atob(base64_content)), null, 2)}
</pre>
);
case "jpeg":
case "jpg":
case "png":
case "bmp":
case "gif":
case "tiff":
return (
<img
src={`data:image/${file_type};base64,${base64_content}`}
alt="Content"
style={{ maxWidth: "100%", maxHeight: "100%", ...style }}
/>
);
case "svg":
return (
<object
type="image/svg+xml"
data={`data:image/svg+xml;base64,${base64_content}`}
style={{ maxWidth: "100%", maxHeight: "100%", ...style }}
>
Your browser does not support SVG
</object>
);
case "md":
return (
<div
style={{ overflow: "auto", maxWidth: "100%", width: "100%" }}
className="markdown-container"
>
<ReactMarkdown
className="react-markdown-component"
remarkPlugins={[remarkGfm]}
>
{window.atob(base64_content)}
</ReactMarkdown>
;
</div>
);

case "pdf":
return <RenderPDF base64Content={base64_content} />;
case "html": {
const decodedHTML = atob(base64_content);

return <HtmlRenderer html={decodedHTML} />;
}
case "plotly_json": {
const utf8String = atob(base64_content);
const decodedJSON = JSON.parse(utf8String);
return (
<Plot
data={decodedJSON.data}
layout={decodedJSON.layout}
style={{ width: "100%", height: "100%" }}
/>
);
}
default:
return <div>Unsupported file type</div>;
}
};
Loading

0 comments on commit e9c9a36

Please sign in to comment.