From 0a49f5e151b759b07d58227306cfcf64e92c7883 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Mon, 4 Dec 2023 18:25:15 -0300 Subject: [PATCH 01/30] fix: install differences modal - add error state --- .../src/context/workspaces/repositories.tsx | 25 +++++++------------ .../components/DifferencesModal/index.tsx | 23 +++++++++++++---- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/frontend/src/context/workspaces/repositories.tsx b/frontend/src/context/workspaces/repositories.tsx index 8c24563d..0b09f1bc 100644 --- a/frontend/src/context/workspaces/repositories.tsx +++ b/frontend/src/context/workspaces/repositories.tsx @@ -126,22 +126,15 @@ const PiecesProvider: React.FC<{ children: React.ReactNode }> = ({ const handleAddRepository = useCallback( async (payload: Omit) => - await postRepository({ ...payload, workspace_id: workspace?.id ?? "" }) - .then(async (data) => { - toast.success(`Repository added successfully!`); - handleRefreshWorkspaces(); - await handleRefreshRepositories(); - return data; - }) - .catch((e) => { - if (e.response?.status === 403) { - toast.error( - `You don't have permission to add repositories to this workspace.`, - ); - return; - } - toast.error(`Error adding repository, try again later.`); - }), + await postRepository({ + ...payload, + workspace_id: workspace?.id ?? "", + }).then(async (data) => { + toast.success(`Repository added successfully!`); + handleRefreshWorkspaces(); + await handleRefreshRepositories(); + return data; + }), [postRepository, handleRefreshWorkspaces, workspace?.id], ); diff --git a/frontend/src/features/workflowEditor/components/DifferencesModal/index.tsx b/frontend/src/features/workflowEditor/components/DifferencesModal/index.tsx index 3b89770b..16e4e77a 100644 --- a/frontend/src/features/workflowEditor/components/DifferencesModal/index.tsx +++ b/frontend/src/features/workflowEditor/components/DifferencesModal/index.tsx @@ -27,6 +27,7 @@ enum installStateEnum { notInstalled = 0, installing = 1, installed = 2, + error = 3, } export const DifferencesModal = forwardRef( @@ -53,10 +54,11 @@ export const DifferencesModal = forwardRef( version: e.requiredVersion, url: `https://github.com/${e.source}`, }; - - return await handleAddRepository(addRepository).catch((e) => { - console.log(e); - }); + try { + await handleAddRepository(addRepository); + } catch (e) { + throw new Error(); + } }, [handleAddRepository], ); @@ -68,7 +70,7 @@ export const DifferencesModal = forwardRef( setInstallState(2); } catch (e) { toast.error(e as string); - setInstallState(0); + setInstallState(3); } }, [installRepositories, uninstalledPieces]); @@ -169,6 +171,11 @@ export const DifferencesModal = forwardRef( borderColor: theme.palette.success.main, color: theme.palette.success.main, } + : installState === 3 + ? { + borderColor: theme.palette.error.main, + color: theme.palette.error.main, + } : {} } > @@ -185,6 +192,12 @@ export const DifferencesModal = forwardRef( Success )} + {installState === 3 && ( + <> + + Error + + )} From cd2efefeaedfe9d219a232008fcce061c504c0af Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Mon, 4 Dec 2023 18:25:27 -0300 Subject: [PATCH 02/30] feat: add download button --- .../CustomTabMenu/TaskResult.tsx | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskResult.tsx b/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskResult.tsx index a1bf4a37..058c81c6 100644 --- a/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskResult.tsx +++ b/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskResult.tsx @@ -1,5 +1,5 @@ -import { CircularProgress, Container, Typography } from "@mui/material"; -import { type CSSProperties } from "react"; +import { Button, CircularProgress, Container, Typography } from "@mui/material"; +import { useCallback, type CSSProperties } from "react"; import ReactMarkdown from "react-markdown"; import Plot from "react-plotly.js"; import remarkGfm from "remark-gfm"; @@ -116,6 +116,48 @@ export const TaskResult = (props: ITaskResultProps) => { } }; + const downloadContent = useCallback(() => { + let href = ""; + switch (file_type) { + case "txt": + href = `data:text/plain;base64,${base64_content}`; + break; + case "json": + href = `data:application/json;base64,${base64_content}`; + break; + case "jpeg": + 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; + case "plotly_json": + href = `data:text/plain;base64,${base64_content}`; + break; + default: + href = `data:text/plain;base64,${base64_content}`; + break; + } + + const a = document.createElement("a"); // Create + a.href = href; // Image Base64 Goes here + a.download = `download.${file_type}`; // File name Here + a.click(); // Downloaded file + }, [base64_content, file_type]); + return ( { justifyContent: "center", }} > + {renderContent()} ); From 1b50c0d583bb573eb95f501f5e624b85fd7ff9e8 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Tue, 5 Dec 2023 17:17:18 -0300 Subject: [PATCH 03/30] feat: add edges styles when running --- .../WorkflowPanel/WorkflowPanel.tsx | 28 +++++++++++++------ .../CustomTabMenu/TaskResult.tsx | 22 +++++++++++---- .../components/WorkflowDetail/index.tsx | 2 +- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/frontend/src/components/WorkflowPanel/WorkflowPanel.tsx b/frontend/src/components/WorkflowPanel/WorkflowPanel.tsx index 0fac200c..5276cd2f 100644 --- a/frontend/src/components/WorkflowPanel/WorkflowPanel.tsx +++ b/frontend/src/components/WorkflowPanel/WorkflowPanel.tsx @@ -37,8 +37,8 @@ import { CustomConnectionLine } from "./ConnectionLine"; import DefaultEdge from "./DefaultEdge"; import { CustomNode } from "./DefaultNode"; import RunNodeComponent from "./RunNode"; - import "reactflow/dist/style.css"; +import { type RunNode } from "./types"; // Load CustomNode const DEFAULT_NODE_TYPES: NodeTypes = { @@ -251,14 +251,24 @@ const WorkflowPanel = forwardRef( ...node.data, }, })); - const edges = [...rawEdges].map((edge: Edge) => ({ - ...edge, - markerEnd: { - type: MarkerType.ArrowClosed, - width: 20, - height: 20, - }, - })); + + const edges = [...rawEdges].map((edge: Edge) => { + const animated = nodes.some( + (n: RunNode) => + (n.id === edge.source || n.id === edge.target) && + n.data?.state === "running", + ); + + return { + ...edge, + markerEnd: { + type: MarkerType.ArrowClosed, + width: 20, + height: 20, + }, + animated, + }; + }); return { nodes, diff --git a/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskResult.tsx b/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskResult.tsx index 058c81c6..de8fd818 100644 --- a/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskResult.tsx +++ b/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskResult.tsx @@ -1,4 +1,10 @@ -import { Button, CircularProgress, Container, Typography } from "@mui/material"; +import { + Button, + CircularProgress, + Container, + Tooltip, + Typography, +} from "@mui/material"; import { useCallback, type CSSProperties } from "react"; import ReactMarkdown from "react-markdown"; import Plot from "react-plotly.js"; @@ -122,6 +128,7 @@ export const TaskResult = (props: ITaskResultProps) => { case "txt": href = `data:text/plain;base64,${base64_content}`; break; + case "plotly_json": case "json": href = `data:application/json;base64,${base64_content}`; break; @@ -144,9 +151,6 @@ export const TaskResult = (props: ITaskResultProps) => { case "html": href = `data:text/html;base64,${base64_content}`; break; - case "plotly_json": - href = `data:text/plain;base64,${base64_content}`; - break; default: href = `data:text/plain;base64,${base64_content}`; break; @@ -167,10 +171,18 @@ export const TaskResult = (props: ITaskResultProps) => { flexDirection: "column", alignItems: "center", justifyContent: "center", + overflowY: "scroll", + overflowX: "hidden", }} > - {renderContent()} + {!!base64_content && !!file_type && ( + + + + )} ); }; diff --git a/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx b/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx index 451b7b39..5eaa52d9 100644 --- a/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx +++ b/frontend/src/features/myWorkflows/components/WorkflowDetail/index.tsx @@ -195,7 +195,7 @@ export const WorkflowDetail: React.FC = () => { } }, [selectedRun, refresh]); - useInterval(refresh, 1000, autoUpdate); + useInterval(refresh, 3000, autoUpdate); return ( From 187e7daea6041f7c0d093ebb9ff9f19609f31715 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Tue, 5 Dec 2023 17:34:25 -0300 Subject: [PATCH 04/30] feat: general codeeditor input. can accept any language --- .../PieceForm/PieceFormItem/arrayInput.tsx | 11 ++++- .../PieceForm/PieceFormItem/index.tsx | 47 ++++--------------- 2 files changed, 18 insertions(+), 40 deletions(-) diff --git a/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/arrayInput.tsx b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/arrayInput.tsx index 5b74fde1..be6b4510 100644 --- a/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/arrayInput.tsx +++ b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/arrayInput.tsx @@ -125,7 +125,7 @@ const ArrayInput: React.FC = ({ return "DatetimeInput"; } else if ( subItemSchema?.type === "string" && - subItemSchema?.widget === "codeeditor" + subItemSchema?.widget.includes("codeeditor") ) { return "CodeEditorInput"; } else if (subItemSchema?.type === "object") { @@ -300,7 +300,14 @@ const ArrayInput: React.FC = ({ )} {!fromUpstream && elementType === "CodeEditorInput" && ( - + )} {!fromUpstream && elementType === "Unknown" && ( diff --git a/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/index.tsx b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/index.tsx index dcd35dc6..75ed4e89 100644 --- a/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/index.tsx +++ b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/index.tsx @@ -181,50 +181,21 @@ const PieceFormItem: React.FC = ({ ("type" in schema && "widget" in schema && schema.type === "string" && - (schema.widget === "codeeditor" || - schema.widget === "codeeditor-python")) || + schema.widget?.includes("codeeditor")) ?? ("widget" in schema && - (schema.widget === "codeeditor" || - schema.widget === "codeeditor-python") && - anyOfType === "string") - ) { - inputElement = ( - - name={`inputs.${itemKey}.value`} - language="python" - placeholder="Enter Python code." - /> - ); - } else if ( - ("type" in schema && - "widget" in schema && - schema.type === "string" && - schema.widget === "codeeditor-json") || - ("widget" in schema && - (schema.widget === "codeeditor" || schema.widget === "codeeditor-json") && - anyOfType === "string") - ) { - inputElement = ( - - name={`inputs.${itemKey}.value`} - language="json" - placeholder="Enter JSON code." - /> - ); - } else if ( - ("type" in schema && - "widget" in schema && - schema.type === "string" && - schema.widget === "codeeditor-sql") || - ("widget" in schema && - (schema.widget === "codeeditor" || schema.widget === "codeeditor-sql") && + schema.widget?.includes("codeeditor") && anyOfType === "string") ) { + const language = + schema.widget === "codeeditor" + ? "python" + : schema.widget.replace("codeeditor-", ""); + inputElement = ( name={`inputs.${itemKey}.value`} - language="sql" - placeholder="Enter SQL code." + language={language} + placeholder={`Enter yor ${language} code here.`} /> ); } else if ( From 46d4088c7a63456beac53b4ea699eaef60b29b3a Mon Sep 17 00:00:00 2001 From: vinicvaz Date: Thu, 7 Dec 2023 08:20:39 -0300 Subject: [PATCH 05/30] fix list workflow schedule arg --- rest/schemas/responses/workflow.py | 12 +++--- rest/services/workflow_service.py | 64 +++++++++++++++--------------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/rest/schemas/responses/workflow.py b/rest/schemas/responses/workflow.py index 14cce53f..f277b5cf 100644 --- a/rest/schemas/responses/workflow.py +++ b/rest/schemas/responses/workflow.py @@ -57,7 +57,7 @@ class WorkflowConfigResponse(BaseModel): @field_validator('schedule') def set_schedule(cls, schedule): return schedule or ScheduleIntervalTypeResponse.none - + class BaseWorkflowModel(BaseModel): workflow: WorkflowConfigResponse tasks: Dict[ @@ -82,20 +82,20 @@ class GetWorkflowsResponseData(BaseModel): @field_validator('schedule') def set_schedule(cls, schedule): return schedule or ScheduleIntervalTypeResponse.none - + @field_validator('created_at', mode='before') def add_utc_timezone_created_at(cls, v): if isinstance(v, datetime) and v.tzinfo is None: v = v.replace(tzinfo=timezone.utc) return v - + @field_validator('last_changed_at', mode='before') def add_utc_timezone_last_changed_at(cls, v): if isinstance(v, datetime) and v.tzinfo is None: v = v.replace(tzinfo=timezone.utc) return v - + @field_validator('next_dagrun', mode='before') def add_utc_timezone_next_dagrun(cls, v): if isinstance(v, datetime) and v.tzinfo is None: @@ -152,7 +152,7 @@ class GetWorkflowRunsResponseData(BaseModel): @field_validator('state') def set_state(cls, state): return state or WorkflowRunState.none - + model_config = ConfigDict(populate_by_name=True) @@ -178,7 +178,7 @@ class GetWorkflowRunTasksResponseData(BaseModel): def set_state(cls, state): return state or WorkflowRunTaskState.none - + model_config = ConfigDict(populate_by_name=True) diff --git a/rest/services/workflow_service.py b/rest/services/workflow_service.py index e111710d..28ee8582 100644 --- a/rest/services/workflow_service.py +++ b/rest/services/workflow_service.py @@ -67,7 +67,7 @@ def create_workflow( ) -> CreateWorkflowResponse: # If workflow with this name already exists for the group raise conflict workflow = self.workflow_repository.find_by_name_and_workspace_id( - body.workflow.name, + body.workflow.name, workspace_id=workspace_id ) if workflow: @@ -89,15 +89,15 @@ def create_workflow( workspace_id=workspace_id ) workflow = self.workflow_repository.create(new_workflow) - + data_dict = body.model_dump() data_dict['workflow']['id'] = workflow_id - + try: self._validate_workflow_tasks(tasks_dict=data_dict.get('tasks'), workspace_id=workspace_id) _, workflow_code, pieces_repositories_ids = self._create_dag_code_from_raw_json(data_dict, workspace_id=workspace_id) - + workflow_piece_repository_associations = [ WorkflowPieceRepositoryAssociative( workflow_id=workflow.id, @@ -158,7 +158,7 @@ async def list_workflows( workspace_id=workspace_id, page=page, page_size=page_size, - filters=filters.dict(exclude_none=True), + filters=filters.model_dump(exclude_none=True), descending=True ) @@ -167,14 +167,14 @@ async def list_workflows( for workflow, _ in workflows } - # TODO - Create chunks of N dag_ids if necessary + # TODO - Create chunks of N dag_ids if necessary airflow_dags_responses = await self.get_airflow_dags_by_id_gather_chunk(list(workflow_uuid_map.keys())) - + max_total_errors_limit = 100 import_errors_response = self.airflow_client.list_import_errors(limit=max_total_errors_limit) if import_errors_response.status_code != 200: raise BaseException("Error when trying to fetch import errors from airflow webserver.") - + import_errors_response_content = import_errors_response.json() if import_errors_response_content['total_entries'] >= max_total_errors_limit: # TODO handle to many import errors @@ -203,7 +203,7 @@ async def list_workflows( is_paused = False if response and not is_dag_broken: - schedule = response.get("schedule") + schedule = response.get("schedule_interval") if isinstance(schedule, dict): schedule = schedule.get("value") status = WorkflowStatus.active.value @@ -211,7 +211,7 @@ async def list_workflows( is_paused = response.get("is_paused") is_active = response.get("is_active") next_dagrun = response.get("next_dagrun") - + data.append( GetWorkflowsResponseData( id=dag_data.id, @@ -253,7 +253,7 @@ def get_workflow(self, workspace_id: int, workflow_id: str, auth_context: Author raise ForbiddenException() airflow_dag_info = self.airflow_client.get_dag_by_id(dag_id=workflow.uuid_name) - + if airflow_dag_info.status_code == 404: airflow_dag_info = { 'is_paused': 'creating', @@ -272,7 +272,7 @@ def get_workflow(self, workspace_id: int, workflow_id: str, auth_context: Author } else: airflow_dag_info = airflow_dag_info.json() - + # Airflow 2.4.0 deprecated schedule_interval in dag but the API (2.7.2) still using it schedule = airflow_dag_info.pop("schedule_interval") if isinstance(schedule, dict): @@ -293,11 +293,11 @@ def get_workflow(self, workspace_id: int, workflow_id: str, auth_context: Author ) return response - + def check_existing_workflow(self): pass - + def _validate_workflow_tasks(self, tasks_dict: dict, workspace_id: int): # get all repositories ids necessary for tasks # get all workspaces ids necessary for repositories referenced by tasks @@ -309,7 +309,7 @@ def _validate_workflow_tasks(self, tasks_dict: dict, workspace_id: int): pieces_names.add(v['piece']['name']) pieces_source_images.add(v['piece']['source_image']) shared_storage_sources.append(v['workflow_shared_storage']['source']) - + shared_storage_source = list(set(shared_storage_sources)) if len(shared_storage_source) > 1: raise BadRequestException("Workflow can't have more than one shared storage source.") @@ -333,7 +333,7 @@ def _validate_workflow_tasks(self, tasks_dict: dict, workspace_id: int): for secret in shared_storage_secrets: if not secret.value and not secret.required: raise BadRequestException("Missing secrets for shared storage.") - + # Find necessary repositories from pieces names and workspace_id necessary_repositories_and_pieces = self.piece_repository.find_repositories_by_piece_name_and_workspace_id( pieces_names=pieces_names, @@ -358,13 +358,13 @@ def _validate_workflow_tasks(self, tasks_dict: dict, workspace_id: int): def _get_storage_repository_from_tasks(self, tasks: list, workspace_id: int): if not tasks: return None - + usage_task = tasks[list(tasks.keys())[0]] workflow_shared_storage = usage_task.get('workflow_shared_storage', None) shared_source = WorkflowSharedStorageSourceEnum(workflow_shared_storage['source']).name shared_model = storage_default_piece_model_map.get(shared_source, None) - + if not shared_model: return None @@ -410,7 +410,7 @@ def _create_dag_code_from_raw_json(self, data: dict, workspace_id: int): if 'end_date' in workflow_kwargs and not workflow_kwargs['end_date']: workflow_kwargs.pop('end_date') - + # TODO define how to use generate report remove_from_dag_kwargs = ['name', 'workspace_id', 'generate_report', 'description', 'id'] for key in remove_from_dag_kwargs: @@ -424,7 +424,7 @@ def _create_dag_code_from_raw_json(self, data: dict, workspace_id: int): raw_input_kwargs = task_value.get('piece_input_kwargs', {}) workflow_shared_storage = task_value.get('workflow_shared_storage', None) container_resources = task_value.get('container_resources', None) - + if container_resources: container_resources['requests']['cpu'] = f'{container_resources["requests"]["cpu"]}m' container_resources['requests']['memory'] = f'{container_resources["requests"]["memory"]}Mi' @@ -470,7 +470,7 @@ def _create_dag_code_from_raw_json(self, data: dict, workspace_id: int): input_kwargs[input_key] = array_input_kwargs else: input_kwargs[input_key] = input_value['value'] - + # piece_request = {"id": 1, "name": "SimpleLogPiece"} piece_db = self.piece_repository.find_repository_by_piece_name_and_workspace_id( @@ -500,7 +500,7 @@ def _create_dag_code_from_raw_json(self, data: dict, workspace_id: int): ) workflow_processed_schema['tasks'] = stream_tasks_dict io_obj = io.StringIO() - stream.dump(io_obj) + stream.dump(io_obj) py_code = io_obj.getvalue() return workflow_processed_schema, py_code, pieces_repositories_ids @@ -523,7 +523,7 @@ def run_workflow(self, workflow_id: int): "is_paused": False } update_response = self.airflow_client.update_dag( - dag_id=airflow_workflow_id, + dag_id=airflow_workflow_id, payload=payload ) if update_response.status_code == 404: @@ -553,7 +553,7 @@ async def delete_workflow_files(self, workflow_uuid): path=f"{settings.DOMINO_LOCAL_WORKFLOWS_REPOSITORY}/{workflow_uuid}.py" ) return - + self.github_rest_client.delete_file( repo_name=settings.DOMINO_GITHUB_WORKFLOWS_REPOSITORY, file_path=f"workflows/{workflow_uuid}.py" @@ -617,11 +617,11 @@ def list_workflow_runs(self, workflow_id: int, page: int, page_size: int): ) ) return response - + records = len(response_data['dag_runs']) total = response_data['total_entries'] last_page = ceil(total / page_size) - 1 - + # Airflow API returns always the same number of elements defined by page size. # So if we are in the last page we need to remove the extra elements. # Example: total = 12, page_size = 10, last_page = 1. @@ -651,7 +651,7 @@ def list_run_tasks(self, workflow_id: int, workflow_run_id: str, page: int, page workflow = self.workflow_repository.find_by_id(id=workflow_id) if not workflow: raise ResourceNotFoundException("Workflow not found") - + airflow_workflow_id = workflow.uuid_name response = self.airflow_client.get_all_run_tasks_instances( @@ -704,17 +704,17 @@ def parse_log(log_text: str): # If the log is empty probably it is still running so we can parse all logs from the start pattern if not log: log = re.findall(f"[^\n]*{start_command_pattern}.*", log_text, re.DOTALL) - + if not log: return [] - + # Parse the log lines output_lines = [] for line in log[0].split('\n')[:-1]: # Remove pod manager info it exists l = re.sub(r"{pod_manager.py:[0-9]*}", '', line) # Get datetime pattern - datetime_pattern = r'\[*\d{4}[-/]\d{2}[-/]\d{2} \d{2}:\d{2}:\d{2}(,|.)\d+\]*' + datetime_pattern = r'\[*\d{4}[-/]\d{2}[-/]\d{2} \d{2}:\d{2}:\d{2}(,|.)\d+\]*' # Remove duplicated datetimes if they exist (they are added by the airflow logger and the domino so in some cases we have 2 datetimes in one line) matches = list(re.finditer(datetime_pattern, l)) if len(matches) > 1: @@ -750,8 +750,8 @@ def parse_log(log_text: str): if l: output_lines.append(l) continue - - # Is header, get the header and the values for the domino header and the content + + # Is header, get the header and the values for the domino header and the content header_value = header_match.group() content_value = l.replace(header_value, '') content_value = content_value.strip() From 9e2f2e4935a233c1e375c30cc0ffb45785b6121d Mon Sep 17 00:00:00 2001 From: vinicvaz Date: Thu, 7 Dec 2023 10:07:45 -0300 Subject: [PATCH 06/30] openai version --- rest/core/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest/core/settings.py b/rest/core/settings.py index 83c6437e..5d96b398 100644 --- a/rest/core/settings.py +++ b/rest/core/settings.py @@ -50,7 +50,7 @@ class Settings(BaseSettings): ), dict( path="Tauffer-Consulting/openai_domino_pieces", - version='development', + version='0.7.1', source='github', require_token=True, url='https://github.com/Tauffer-Consulting/openai_domino_pieces' From be6ee1a8ea678ddb48c2ae624b54af4dce3dc8b4 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Thu, 7 Dec 2023 12:28:11 -0300 Subject: [PATCH 07/30] feat: add html display result --- frontend/package.json | 2 + .../CustomTabMenu/TaskResult.tsx | 17 +- frontend/yarn.lock | 1478 +++++++++-------- 3 files changed, 800 insertions(+), 697 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 52d2f0ac..b7c07f4c 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -27,6 +27,7 @@ "cross-env": "^7.0.3", "date-fns": "^2.30.0", "dayjs": "^1.11.7", + "dompurify": "^3.0.6", "dotenv": "^16.3.1", "elkjs": "^0.8.2", "localforage": "^1.10.0", @@ -69,6 +70,7 @@ "not op_mini all" ], "devDependencies": { + "@types/dompurify": "^3.0.5", "@typescript-eslint/eslint-plugin": "^6.4.0", "@typescript-eslint/parser": "^6.5.0", "eslint": "^8.0.1", diff --git a/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskResult.tsx b/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskResult.tsx index de8fd818..19b257c3 100644 --- a/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskResult.tsx +++ b/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskResult.tsx @@ -5,6 +5,7 @@ import { Tooltip, Typography, } from "@mui/material"; +import DOMPurify from "dompurify"; import { useCallback, type CSSProperties } from "react"; import ReactMarkdown from "react-markdown"; import Plot from "react-plotly.js"; @@ -96,16 +97,12 @@ export const TaskResult = (props: ITaskResultProps) => { */} ); - case "html": - return ( -
- HTML result display not yet implemented -
- // + ); +}; + +export default HtmlRenderer; diff --git a/frontend/src/components/RenderB64/index.tsx b/frontend/src/components/RenderB64/index.tsx index 96a23be5..f0027760 100644 --- a/frontend/src/components/RenderB64/index.tsx +++ b/frontend/src/components/RenderB64/index.tsx @@ -1,6 +1,6 @@ import { Typography } from "@mui/material"; +import HtmlRenderer from "components/HTMLRender"; import { RenderPDF } from "components/RenderPDF"; -import DOMPurify from "dompurify"; import React, { type CSSProperties } from "react"; import ReactMarkdown from "react-markdown"; import Plot from "react-plotly.js"; @@ -72,9 +72,8 @@ export const RenderB64: React.FC = ({ return ; case "html": { const decodedHTML = atob(base64_content); - const sanitizedHTML = DOMPurify.sanitize(decodedHTML); - return
; + return ; } case "plotly_json": { const utf8String = atob(base64_content); diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 2914ca11..ff878816 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2749,11 +2749,6 @@ dompurify@^2.2.0: resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.4.7.tgz#277adeb40a2c84be2d42a8bcd45f582bfa4d0cfc" integrity sha512-kxxKlPEDa6Nc5WJi+qRgPbOAbgTpSULL+vI3NUXsZMlkJxTqYI9wg5ZTay2sFrdZRWHPWNi+EdAhcJf81WtoMQ== -dompurify@^3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.6.tgz#925ebd576d54a9531b5d76f0a5bef32548351dae" - integrity sha512-ilkD8YEnnGh1zJ240uJsW7AzE+2qpbOUYjacomn3AvJ6J4JhKGSZ2nh4wUIXPZrEPppaCLx5jFe8T89Rk8tQ7w== - dotenv@^16.3.1: version "16.3.1" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" @@ -6632,6 +6627,7 @@ string-split-by@^1.0.0: parenthesis "^3.1.5" "string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.3: + name string-width-cjs version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -6719,6 +6715,7 @@ stringify-entities@^4.0.0: character-entities-legacy "^3.0.0" "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: + name strip-ansi-cjs version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== From a422bfc2d0da30cb5c85737f3ecce7f9670a4778 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Mon, 18 Dec 2023 15:15:45 -0300 Subject: [PATCH 21/30] fix: iframe styles --- frontend/src/components/HTMLRender/index.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/HTMLRender/index.tsx b/frontend/src/components/HTMLRender/index.tsx index 2d20c5bc..22dd76e5 100644 --- a/frontend/src/components/HTMLRender/index.tsx +++ b/frontend/src/components/HTMLRender/index.tsx @@ -9,7 +9,9 @@ const HtmlRenderer: React.FC = ({ html }) => { ); }; From 428d65784f33cb1b038a929904a170e841359b60 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Mon, 18 Dec 2023 20:37:14 -0300 Subject: [PATCH 22/30] feat: use react-to-print lib --- frontend/package.json | 2 +- frontend/src/@types/global.d.ts | 1 - frontend/src/@types/html2pdf.js.d.ts | 1 - frontend/src/components/DownloadPDF/index.tsx | 27 ++++ .../components/ResultsReport/PDFView.tsx | 27 +--- .../components/ResultsReport/PaperA42.tsx | 54 ++----- .../components/ResultsReport/index.tsx | 29 ++-- frontend/yarn.lock | 134 +----------------- rest/schemas/responses/workflow.py | 13 +- rest/services/workflow_service.py | 9 +- 10 files changed, 81 insertions(+), 216 deletions(-) delete mode 100644 frontend/src/@types/html2pdf.js.d.ts create mode 100644 frontend/src/components/DownloadPDF/index.tsx diff --git a/frontend/package.json b/frontend/package.json index 4ea0e1bc..6f6509c1 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -30,7 +30,6 @@ "dayjs": "^1.11.7", "dotenv": "^16.3.1", "elkjs": "^0.8.2", - "html2pdf.js": "^0.10.1", "localforage": "^1.10.0", "plotly.js": "^2.27.1", "react": "^18.2.0", @@ -41,6 +40,7 @@ "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", diff --git a/frontend/src/@types/global.d.ts b/frontend/src/@types/global.d.ts index d5f360c1..cf982313 100644 --- a/frontend/src/@types/global.d.ts +++ b/frontend/src/@types/global.d.ts @@ -1,4 +1,3 @@ /* eslint-disable @typescript-eslint/triple-slash-reference */ /// /// -/// diff --git a/frontend/src/@types/html2pdf.js.d.ts b/frontend/src/@types/html2pdf.js.d.ts deleted file mode 100644 index c9a972e2..00000000 --- a/frontend/src/@types/html2pdf.js.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module "html2pdf.js"; diff --git a/frontend/src/components/DownloadPDF/index.tsx b/frontend/src/components/DownloadPDF/index.tsx new file mode 100644 index 00000000..a0c9f404 --- /dev/null +++ b/frontend/src/components/DownloadPDF/index.tsx @@ -0,0 +1,27 @@ +import React, { useEffect, useState } from "react"; +import { useReactToPrint } from "react-to-print"; + +interface Props { + contentId: string; +} + +export const DownloadAsPDF: React.FC = ({ contentId }) => { + const [content, setContent] = useState(null); + const handlePrint = useReactToPrint({ + content: () => content, + }); + + useEffect(() => { + const content = document.getElementById(contentId); + + if (content) { + setContent(content); + } + }, [contentId]); + + return ( +
+ +
+ ); +}; diff --git a/frontend/src/features/myWorkflows/components/ResultsReport/PDFView.tsx b/frontend/src/features/myWorkflows/components/ResultsReport/PDFView.tsx index 76fc1e76..069f80d5 100644 --- a/frontend/src/features/myWorkflows/components/ResultsReport/PDFView.tsx +++ b/frontend/src/features/myWorkflows/components/ResultsReport/PDFView.tsx @@ -1,5 +1,4 @@ -import * as html2pdf from "html2pdf.js"; -import React, { useRef } from "react"; +import React from "react"; import { PaperA42 } from "./PaperA42"; @@ -8,30 +7,6 @@ interface Props { } const DynamicContent: React.FC = ({ jsxContent }) => { - const contentRef = useRef(null); - - const _downloadPDF = () => { - const content = contentRef.current; - const pdfOptions = { - margin: 10, - filename: "document.pdf", - image: { type: "jpeg", quality: 0.98 }, - html2canvas: { scale: 2 }, - jsPDF: { unit: "mm", format: "a4", orientation: "portrait" }, - }; - - html2pdf() - .from(content) - .set(pdfOptions) - .outputPdf((pdf: BlobPart) => { - const blob = new Blob([pdf], { type: "application/pdf" }); - const link = document.createElement("a"); - link.href = URL.createObjectURL(blob); - link.download = pdfOptions.filename; - link.click(); - }); - }; - return ( {jsxContent.map((element, index) => ( diff --git a/frontend/src/features/myWorkflows/components/ResultsReport/PaperA42.tsx b/frontend/src/features/myWorkflows/components/ResultsReport/PaperA42.tsx index b4356636..fc21e0b4 100644 --- a/frontend/src/features/myWorkflows/components/ResultsReport/PaperA42.tsx +++ b/frontend/src/features/myWorkflows/components/ResultsReport/PaperA42.tsx @@ -1,63 +1,27 @@ import { Container, Paper } from "@mui/material"; -import React, { useRef, useEffect, useState } from "react"; +import React from "react"; const A4_ASPECT_RATIO = 1.414; export const PaperA42: React.FC<{ children?: React.ReactNode }> = ({ children, }) => { - const paperRef = useRef(null); - const [folders, setFolders] = useState(1); - - useEffect(() => { - const handleResize = () => { - if (paperRef.current) { - const paperRect = paperRef.current.getBoundingClientRect(); - - const contentElement = paperRef.current - .firstChild as HTMLElement | null; - const contentRect = contentElement?.getBoundingClientRect(); - - if (contentRect && contentRect.height > paperRect.height) { - setFolders(Math.ceil(contentRect.height / paperRect.height)); - } else { - setFolders(1); - } - } - }; - - // Initial check and listen for resize events - handleResize(); - window.addEventListener("resize", handleResize); - - // Cleanup event listener on component unmount - return () => { - window.removeEventListener("resize", handleResize); - }; - }, []); - return ( - {Array.from({ length: folders }, (_, index) => ( - - {children} - - ))} + + {children} + ); }; diff --git a/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx b/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx index f904671a..1549498b 100644 --- a/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx +++ b/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx @@ -1,3 +1,4 @@ +import { DownloadAsPDF } from "components/DownloadPDF"; import { RenderB64 } from "components/RenderB64"; import { useAuthenticatedGetWorkflowRunResultReport } from "features/myWorkflows/api"; import React, { useMemo } from "react"; @@ -25,17 +26,21 @@ export const ResultsReport: React.FC = () => { }, [data]); return ( -
- -
+ <> + +
+ +
+ ); }; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index ff878816..3fa40b44 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -179,7 +179,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/runtime@^7.12.5", "@babel/runtime@^7.14.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.6", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.2", "@babel/runtime@^7.23.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": +"@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.6", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.2", "@babel/runtime@^7.23.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": version "7.23.6" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.6.tgz#c05e610dc228855dc92ef1b53d07389ed8ab521d" integrity sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ== @@ -1413,11 +1413,6 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563" integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng== -"@types/raf@^3.4.0": - version "3.4.3" - resolved "https://registry.yarnpkg.com/@types/raf/-/raf-3.4.3.tgz#85f1d1d17569b28b8db45e16e996407a56b0ab04" - integrity sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw== - "@types/react-dom@^18.0.9": version "18.2.17" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.17.tgz#375c55fab4ae671bd98448dcfa153268d01d6f64" @@ -1862,11 +1857,6 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - available-typed-arrays@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" @@ -1908,11 +1898,6 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-arraybuffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#1c37589a7c4b0746e34bd1feb951da2df01c1bdc" - integrity sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ== - big-integer@^1.6.44: version "1.6.52" resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" @@ -1985,11 +1970,6 @@ browserslist@^4.22.2: node-releases "^2.0.14" update-browserslist-db "^1.0.13" -btoa@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73" - integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g== - buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" @@ -2054,20 +2034,6 @@ canvas@^2.11.2: nan "^2.17.0" simple-get "^3.0.3" -canvg@^3.0.6: - version "3.0.10" - resolved "https://registry.yarnpkg.com/canvg/-/canvg-3.0.10.tgz#8e52a2d088b6ffa23ac78970b2a9eebfae0ef4b3" - integrity sha512-qwR2FRNO9NlzTeKIPIKpnTY6fqwuYSequ8Ru8c0YkYU7U0oW+hLUvWadLvAu1Rl72OMNiFhoLu4f8eUjQ7l/+Q== - dependencies: - "@babel/runtime" "^7.12.5" - "@types/raf" "^3.4.0" - core-js "^3.8.3" - raf "^3.4.1" - regenerator-runtime "^0.13.7" - rgbcolor "^1.0.1" - stackblur-canvas "^2.0.0" - svg-pathdata "^6.0.3" - ccount@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" @@ -2325,11 +2291,6 @@ convert-source-map@^2.0.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== -core-js@^3.6.0, core-js@^3.8.3: - version "3.34.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.34.0.tgz#5705e6ad5982678612e96987d05b27c6c7c274a5" - integrity sha512-aDdvlDder8QmY91H88GzNi9EtQi2TjvQhpCX6B1v/dAZHU1AuLgHvRh54RiOerpEhEW46Tkf+vgAViB/CWC0ag== - core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" @@ -2407,13 +2368,6 @@ css-global-keywords@^1.0.1: resolved "https://registry.yarnpkg.com/css-global-keywords/-/css-global-keywords-1.0.1.tgz#72a9aea72796d019b1d2a3252de4e5aaa37e4a69" integrity sha512-X1xgQhkZ9n94WDwntqst5D/FKkmiU0GlJSFZSV3kLvyJ1WC5VeyoXDOuleUD+SIuH9C7W05is++0Woh0CGfKjQ== -css-line-break@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/css-line-break/-/css-line-break-2.1.0.tgz#bfef660dfa6f5397ea54116bb3cb4873edbc4fa0" - integrity sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w== - dependencies: - utrie "^1.0.2" - css-system-font-keywords@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/css-system-font-keywords/-/css-system-font-keywords-1.0.0.tgz#85c6f086aba4eb32c571a3086affc434b84823ed" @@ -2744,11 +2698,6 @@ dom-helpers@^5.0.1: "@babel/runtime" "^7.8.7" csstype "^3.0.2" -dompurify@^2.2.0: - version "2.4.7" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.4.7.tgz#277adeb40a2c84be2d42a8bcd45f582bfa4d0cfc" - integrity sha512-kxxKlPEDa6Nc5WJi+qRgPbOAbgTpSULL+vI3NUXsZMlkJxTqYI9wg5ZTay2sFrdZRWHPWNi+EdAhcJf81WtoMQ== - dotenv@^16.3.1: version "16.3.1" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" @@ -2959,11 +2908,6 @@ es6-iterator@^2.0.3: es5-ext "^0.10.35" es6-symbol "^3.1.1" -es6-promise@^4.2.5: - version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" - integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== - es6-symbol@^3.1.1, es6-symbol@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" @@ -3407,11 +3351,6 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" -fflate@^0.4.8: - version "0.4.8" - resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.4.8.tgz#f90b82aefbd8ac174213abb338bd7ef848f0f5ae" - integrity sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA== - file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -4097,23 +4036,6 @@ html-void-elements@^2.0.0: resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-2.0.1.tgz#29459b8b05c200b6c5ee98743c41b979d577549f" integrity sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A== -html2canvas@^1.0.0, html2canvas@^1.0.0-rc.5: - version "1.4.1" - resolved "https://registry.yarnpkg.com/html2canvas/-/html2canvas-1.4.1.tgz#7cef1888311b5011d507794a066041b14669a543" - integrity sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA== - dependencies: - css-line-break "^2.1.0" - text-segmentation "^1.0.3" - -html2pdf.js@^0.10.1: - version "0.10.1" - resolved "https://registry.yarnpkg.com/html2pdf.js/-/html2pdf.js-0.10.1.tgz#9363910cca52a54113633e552a726722209a8eed" - integrity sha512-3onwwhOWsZfNjIZwV6YIJ6FVhXk+X9YxHSqzeS6hup+1dGi2DHI+zZYUJ+iFnvtaYcjlhyrILL1fvRCUOa8Fcg== - dependencies: - es6-promise "^4.2.5" - html2canvas "^1.0.0" - jspdf "^2.3.1" - https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -4583,21 +4505,6 @@ json5@^2.2.2, json5@^2.2.3: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -jspdf@^2.3.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/jspdf/-/jspdf-2.5.1.tgz#00c85250abf5447a05f3b32ab9935ab4a56592cc" - integrity sha512-hXObxz7ZqoyhxET78+XR34Xu2qFGrJJ2I2bE5w4SM8eFaFEkW2xcGRVUss360fYelwRSid/jT078kbNvmoW0QA== - dependencies: - "@babel/runtime" "^7.14.0" - atob "^2.1.2" - btoa "^1.2.1" - fflate "^0.4.8" - optionalDependencies: - canvg "^3.0.6" - core-js "^3.6.0" - dompurify "^2.2.0" - html2canvas "^1.0.0-rc.5" - "jsx-ast-utils@^2.4.1 || ^3.0.0": version "3.3.5" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" @@ -6042,6 +5949,11 @@ react-router@6.21.0: dependencies: "@remix-run/router" "1.14.0" +react-to-print@^2.14.15: + version "2.14.15" + resolved "https://registry.yarnpkg.com/react-to-print/-/react-to-print-2.14.15.tgz#edb4ce8a92205cf37fd8c3d57de829034aa5c911" + integrity sha512-SKnwOzU2cJ8eaAkoJO7+gNhvfEDmm+Y34IdcHsjtHioUevUPhprqbVtvNJlZ2JkGJ8ExK2QNWM9pXECTDR5D8w== + react-toastify@^9.1.1: version "9.1.3" resolved "https://registry.yarnpkg.com/react-toastify/-/react-toastify-9.1.3.tgz#1e798d260d606f50e0fab5ee31daaae1d628c5ff" @@ -6150,11 +6062,6 @@ refractor@^4.8.0: hastscript "^7.0.0" parse-entities "^4.0.0" -regenerator-runtime@^0.13.7: - version "0.13.11" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" - integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== - regenerator-runtime@^0.14.0: version "0.14.0" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" @@ -6378,11 +6285,6 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rgbcolor@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/rgbcolor/-/rgbcolor-1.0.1.tgz#d6505ecdb304a6595da26fa4b43307306775945d" - integrity sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw== - right-now@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/right-now/-/right-now-1.0.0.tgz#6e89609deebd7dcdaf8daecc9aea39cf585a0918" @@ -6595,11 +6497,6 @@ stack-trace@0.0.9: resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695" integrity sha512-vjUc6sfgtgY0dxCdnc40mK6Oftjo9+2K8H/NG81TMhgL392FtiPA9tn9RLyTxXmTLPJPjF3VyzFp6bsWFLisMQ== -stackblur-canvas@^2.0.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/stackblur-canvas/-/stackblur-canvas-2.6.0.tgz#7876bab4ea99bfc97b69ce662614d7a1afb2d71b" - integrity sha512-8S1aIA+UoF6erJYnglGPug6MaHYGo1Ot7h5fuXx4fUPvcvQfcdw2o/ppCse63+eZf8PPidSu4v1JnmEVtEDnpg== - static-eval@^2.0.5: version "2.1.0" resolved "https://registry.yarnpkg.com/static-eval/-/static-eval-2.1.0.tgz#a16dbe54522d7fa5ef1389129d813fd47b148014" @@ -6841,11 +6738,6 @@ svg-path-sdf@^1.1.3: parse-svg-path "^0.1.2" svg-path-bounds "^1.0.1" -svg-pathdata@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/svg-pathdata/-/svg-pathdata-6.0.3.tgz#80b0e0283b652ccbafb69ad4f8f73e8d3fbf2cac" - integrity sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw== - swr@^2.0.0: version "2.2.4" resolved "https://registry.yarnpkg.com/swr/-/swr-2.2.4.tgz#03ec4c56019902fbdc904d78544bd7a9a6fa3f07" @@ -6879,13 +6771,6 @@ tar@^6.1.11: mkdirp "^1.0.3" yallist "^4.0.0" -text-segmentation@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/text-segmentation/-/text-segmentation-1.0.3.tgz#52a388159efffe746b24a63ba311b6ac9f2d7943" - integrity sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw== - dependencies: - utrie "^1.0.2" - text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -7325,13 +7210,6 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -utrie@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/utrie/-/utrie-1.0.2.tgz#d42fe44de9bc0119c25de7f564a6ed1b2c87a645" - integrity sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw== - dependencies: - base64-arraybuffer "^1.0.2" - uuid@^9.0.0: version "9.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" diff --git a/rest/schemas/responses/workflow.py b/rest/schemas/responses/workflow.py index 367dfe4e..6c7aea5a 100644 --- a/rest/schemas/responses/workflow.py +++ b/rest/schemas/responses/workflow.py @@ -196,8 +196,19 @@ class GetWorkflowRunTaskResultResponse(BaseModel): base64_content: Optional[str] = None file_type: Optional[str] = None +class GetWorkflowResultReport(BaseModel): + base64_content: Optional[str] = None + file_type: Optional[str] = None + dag_id: str + duration: Optional[float] = None + start_date: Optional[datetime] = None + end_date: Optional[datetime] = None + execution_date: Optional[datetime] = None + task_id: str + state: Optional[WorkflowRunTaskState] = None + class GetWorkflowResultReportResponse(BaseModel): - data: List[GetWorkflowRunTaskResultResponse] + data: List[GetWorkflowResultReport] class GetWorkflowRunTaskLogsResponse(BaseModel): data: List[str] diff --git a/rest/services/workflow_service.py b/rest/services/workflow_service.py index 57780bf5..11fee115 100644 --- a/rest/services/workflow_service.py +++ b/rest/services/workflow_service.py @@ -745,7 +745,14 @@ def generate_report(self, workflow_id: int, workflow_run_id: str): result_list.append( dict( base64_content=task_result.get("base64_content"), - file_type=task_result.get("file_type") + file_type=task_result.get("file_type"), + dag_id=task.get("dag_id"), + duration=task.get("duration"), + start_date=task.get("start_date"), + end_date=task.get("end_date"), + execution_date=task.get("execution_date"), + task_id=task.get("task_id"), + state=task.get("state"), ) ) except BaseException as e: From 7904456ef8d7853d4ab08edd0dfa9744b265215a Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Wed, 20 Dec 2023 22:18:32 -0300 Subject: [PATCH 23/30] chore: improve react-to-print styles --- frontend/src/components/DownloadPDF/index.tsx | 11 +++- .../api/runs/getWorkflowRunReport.ts | 16 ++++- .../components/ResultsReport/PDFView.tsx | 21 ------ .../components/ResultsReport/PaperA4.tsx | 23 +++++-- .../components/ResultsReport/PaperA42.tsx | 27 -------- .../components/ResultsReport/PieceReport.tsx | 32 ++++++++++ .../components/ResultsReport/index.tsx | 64 ++++++++++--------- .../CustomTabMenu/TaskDetail.tsx | 11 ++-- rest/schemas/responses/workflow.py | 1 + rest/services/workflow_service.py | 6 +- 10 files changed, 121 insertions(+), 91 deletions(-) delete mode 100644 frontend/src/features/myWorkflows/components/ResultsReport/PDFView.tsx delete mode 100644 frontend/src/features/myWorkflows/components/ResultsReport/PaperA42.tsx create mode 100644 frontend/src/features/myWorkflows/components/ResultsReport/PieceReport.tsx diff --git a/frontend/src/components/DownloadPDF/index.tsx b/frontend/src/components/DownloadPDF/index.tsx index a0c9f404..65bc272f 100644 --- a/frontend/src/components/DownloadPDF/index.tsx +++ b/frontend/src/components/DownloadPDF/index.tsx @@ -13,15 +13,22 @@ export const DownloadAsPDF: React.FC = ({ contentId }) => { useEffect(() => { const content = document.getElementById(contentId); - + console.log("content", content); if (content) { setContent(content); } }, [contentId]); + const handlePrintWithTimeout = () => { + // Add a short timeout to ensure styles are applied before printing + setTimeout(() => { + handlePrint(); + }, 2000); // Adjust the timeout duration as needed + }; + return (
- +
); }; diff --git a/frontend/src/features/myWorkflows/api/runs/getWorkflowRunReport.ts b/frontend/src/features/myWorkflows/api/runs/getWorkflowRunReport.ts index 47d87a82..465446c1 100644 --- a/frontend/src/features/myWorkflows/api/runs/getWorkflowRunReport.ts +++ b/frontend/src/features/myWorkflows/api/runs/getWorkflowRunReport.ts @@ -1,5 +1,6 @@ import { type AxiosResponse } from "axios"; import { useWorkspaces } from "context/workspaces"; +import { type taskState } from "features/myWorkflows/types"; import { dominoApiClient } from "services/clients/domino.client"; import useSWR from "swr"; @@ -8,6 +9,19 @@ export interface IGetWorkflowRunResultReportParams { runId: string; } +export interface IGetWorkflowRunResultReportResponse { + base64_content: string; + file_type: string; + piece_name: string; + dag_id: string; + duration: number; + start_date: string; + end_date: string; + execution_date: string; + task_id: string; + state: taskState; +} + const getWorkflowRunResultReportUrl = ({ workspace, workflowId, @@ -32,7 +46,7 @@ const getWorkflowRunResultReport: ({ IGetWorkflowRunResultReportParams & { workspace: string } >) => Promise< | AxiosResponse<{ - data: Array<{ base64_content: string; file_type: string }>; + data: IGetWorkflowRunResultReportResponse[]; }> | undefined > = async ({ workspace, workflowId, runId }) => { diff --git a/frontend/src/features/myWorkflows/components/ResultsReport/PDFView.tsx b/frontend/src/features/myWorkflows/components/ResultsReport/PDFView.tsx deleted file mode 100644 index 069f80d5..00000000 --- a/frontend/src/features/myWorkflows/components/ResultsReport/PDFView.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from "react"; - -import { PaperA42 } from "./PaperA42"; - -interface Props { - jsxContent: JSX.Element[]; -} - -const DynamicContent: React.FC = ({ jsxContent }) => { - return ( - - {jsxContent.map((element, index) => ( -
- {element} -
- ))} -
- ); -}; - -export default DynamicContent; diff --git a/frontend/src/features/myWorkflows/components/ResultsReport/PaperA4.tsx b/frontend/src/features/myWorkflows/components/ResultsReport/PaperA4.tsx index 270c41cb..549ab732 100644 --- a/frontend/src/features/myWorkflows/components/ResultsReport/PaperA4.tsx +++ b/frontend/src/features/myWorkflows/components/ResultsReport/PaperA4.tsx @@ -1,21 +1,34 @@ import { Container, Paper } from "@mui/material"; import React from "react"; -const A4_ASPECT_RATIO = 1.414; +const _A4_ASPECT_RATIO = 1.414; -export const PaperA4: React.FC<{ children?: React.ReactNode }> = ({ +export const PaperA4: React.FC<{ children?: React.ReactNode; id: string }> = ({ children, + id, }) => { return ( - {children} + + {children} + ); }; diff --git a/frontend/src/features/myWorkflows/components/ResultsReport/PaperA42.tsx b/frontend/src/features/myWorkflows/components/ResultsReport/PaperA42.tsx deleted file mode 100644 index fc21e0b4..00000000 --- a/frontend/src/features/myWorkflows/components/ResultsReport/PaperA42.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { Container, Paper } from "@mui/material"; -import React from "react"; - -const A4_ASPECT_RATIO = 1.414; - -export const PaperA42: React.FC<{ children?: React.ReactNode }> = ({ - children, -}) => { - return ( - - - {children} - - - ); -}; diff --git a/frontend/src/features/myWorkflows/components/ResultsReport/PieceReport.tsx b/frontend/src/features/myWorkflows/components/ResultsReport/PieceReport.tsx new file mode 100644 index 00000000..d65dc9cd --- /dev/null +++ b/frontend/src/features/myWorkflows/components/ResultsReport/PieceReport.tsx @@ -0,0 +1,32 @@ +import { Grid } from "@mui/material"; +import { RenderB64 } from "components/RenderB64"; +import { type IWorkflowRunTasks } from "features/myWorkflows/types"; +import React from "react"; + +import { TaskDetails } from "../WorkflowDetail/CustomTabMenu/TaskDetail"; + +interface Props { + taskData: IWorkflowRunTasks & { + pieceName: string; + base64_content: string; + file_type: string; + }; +} + +export const PieceReport: React.FC = ({ taskData }) => { + return ( + + + {/* this is the infos about the piece */} + + + + {/* This is the result (if exists) */} + + + + ); +}; diff --git a/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx b/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx index 1549498b..fab6409d 100644 --- a/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx +++ b/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx @@ -1,10 +1,11 @@ +import { Grid, useMediaQuery } from "@mui/material"; import { DownloadAsPDF } from "components/DownloadPDF"; -import { RenderB64 } from "components/RenderB64"; import { useAuthenticatedGetWorkflowRunResultReport } from "features/myWorkflows/api"; -import React, { useMemo } from "react"; +import React from "react"; import { useParams } from "react-router-dom"; -import DynamicContent from "./PDFView"; +import { PaperA4 } from "./PaperA4"; +import { PieceReport } from "./PieceReport"; export const ResultsReport: React.FC = () => { const { id, runId } = useParams<{ id: string; runId: string }>(); @@ -13,34 +14,37 @@ export const ResultsReport: React.FC = () => { runId, }); - const content = useMemo(() => { - return ( - data?.data.map((d, i) => ( - - )) ?? [] - ); - }, [data]); + const isPrint = useMediaQuery("print"); return ( - <> - -
- -
- + + + {isPrint ? null : } + + + + + {data?.data.map((d, i) => ( + + ))} + + + + ); }; diff --git a/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskDetail.tsx b/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskDetail.tsx index c5427060..91e26d56 100644 --- a/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskDetail.tsx +++ b/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskDetail.tsx @@ -29,10 +29,13 @@ export const TaskDetails = (props: ITaskDetailsProps) => { end: props.taskData.duration * 1000, }); - return `${duration.hours} ${(duration?.hours ?? 0) > 1 ? "hours" : "hour" - } : ${duration.minutes} ${(duration?.minutes ?? 0) > 1 ? "minutes" : "minute" - } : ${duration.seconds} ${(duration?.seconds ?? 0) > 1 ? "seconds" : "second" - }`; + return `${duration.hours} ${ + (duration?.hours ?? 0) > 1 ? "hours" : "hour" + } : ${duration.minutes} ${ + (duration?.minutes ?? 0) > 1 ? "minutes" : "minute" + } : ${duration.seconds} ${ + (duration?.seconds ?? 0) > 1 ? "seconds" : "second" + }`; } else { return "Not done yet"; } diff --git a/rest/schemas/responses/workflow.py b/rest/schemas/responses/workflow.py index 6c7aea5a..e7836eb0 100644 --- a/rest/schemas/responses/workflow.py +++ b/rest/schemas/responses/workflow.py @@ -199,6 +199,7 @@ class GetWorkflowRunTaskResultResponse(BaseModel): class GetWorkflowResultReport(BaseModel): base64_content: Optional[str] = None file_type: Optional[str] = None + piece_name: Optional[str] = None dag_id: str duration: Optional[float] = None start_date: Optional[datetime] = None diff --git a/rest/services/workflow_service.py b/rest/services/workflow_service.py index 11fee115..72d6ffd5 100644 --- a/rest/services/workflow_service.py +++ b/rest/services/workflow_service.py @@ -719,7 +719,6 @@ def generate_report(self, workflow_id: int, workflow_run_id: str): all_run_tasks = response_data["task_instances"] while len(all_run_tasks) < total_tasks: - self.logger.info("oi amigo") page+=1 response = self.airflow_client.get_all_run_tasks_instances( dag_id=airflow_workflow_id, @@ -742,10 +741,15 @@ def generate_report(self, workflow_id: int, workflow_run_id: str): task_try_number=task["try_number"] ) + node = workflow.ui_schema.get("nodes", {}).get(task["task_id"], {}) + piece_name = node.get("data", {}).get("style", {}).get("label", None) or \ + node.get("data", {}).get("name", None) + result_list.append( dict( base64_content=task_result.get("base64_content"), file_type=task_result.get("file_type"), + piece_name=piece_name, dag_id=task.get("dag_id"), duration=task.get("duration"), start_date=task.get("start_date"), From 72a91838f06086d711db4a91aae2919835c6c61b Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Tue, 26 Dec 2023 16:15:28 -0300 Subject: [PATCH 24/30] feat: improve results report page style --- frontend/src/components/DownloadPDF/index.tsx | 9 +- frontend/src/components/HTMLRender/index.tsx | 42 +++++++-- .../components/ResultsReport/PaperA4.tsx | 1 + .../components/ResultsReport/PieceReport.tsx | 35 ++++--- .../components/ResultsReport/index.tsx | 93 +++++++++++++++++-- .../CustomTabMenu/TaskResult.tsx | 7 +- 6 files changed, 150 insertions(+), 37 deletions(-) diff --git a/frontend/src/components/DownloadPDF/index.tsx b/frontend/src/components/DownloadPDF/index.tsx index 65bc272f..e2b2079d 100644 --- a/frontend/src/components/DownloadPDF/index.tsx +++ b/frontend/src/components/DownloadPDF/index.tsx @@ -1,3 +1,4 @@ +import { Button } from "@mui/material"; import React, { useEffect, useState } from "react"; import { useReactToPrint } from "react-to-print"; @@ -12,8 +13,6 @@ export const DownloadAsPDF: React.FC = ({ contentId }) => { }); useEffect(() => { - const content = document.getElementById(contentId); - console.log("content", content); if (content) { setContent(content); } @@ -27,8 +26,8 @@ export const DownloadAsPDF: React.FC = ({ contentId }) => { }; return ( -
- -
+ ); }; diff --git a/frontend/src/components/HTMLRender/index.tsx b/frontend/src/components/HTMLRender/index.tsx index 22dd76e5..4c679596 100644 --- a/frontend/src/components/HTMLRender/index.tsx +++ b/frontend/src/components/HTMLRender/index.tsx @@ -1,18 +1,44 @@ -import React from "react"; +import React, { useRef, useState } from "react"; interface Props { html: string; } const HtmlRenderer: React.FC = ({ html }) => { + const iframeRef = useRef(null); + const [minHeight, setMinHeight] = useState(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 ( - +
+ +
); }; diff --git a/frontend/src/features/myWorkflows/components/ResultsReport/PaperA4.tsx b/frontend/src/features/myWorkflows/components/ResultsReport/PaperA4.tsx index 549ab732..0049c8c8 100644 --- a/frontend/src/features/myWorkflows/components/ResultsReport/PaperA4.tsx +++ b/frontend/src/features/myWorkflows/components/ResultsReport/PaperA4.tsx @@ -20,6 +20,7 @@ export const PaperA4: React.FC<{ children?: React.ReactNode; id: string }> = ({ > = ({ taskData }) => { +export const PieceReport: React.FC = ({ taskData, id }) => { return ( - - - {/* this is the infos about the piece */} - + + + + + - + + {/* This is the result (if exists) */} - + + + ); diff --git a/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx b/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx index fab6409d..ccd44f6f 100644 --- a/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx +++ b/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx @@ -1,7 +1,23 @@ -import { Grid, useMediaQuery } from "@mui/material"; -import { DownloadAsPDF } from "components/DownloadPDF"; -import { useAuthenticatedGetWorkflowRunResultReport } from "features/myWorkflows/api"; -import React from "react"; +import LogoutIcon from "@mui/icons-material/Logout"; +import { + Container, + Divider, + Grid, + List, + ListItem, + ListItemButton, + ListItemIcon, + ListItemText, + Paper, + Typography, + useMediaQuery, +} from "@mui/material"; +// import { DownloadAsPDF } from "components/DownloadPDF"; +import { + useAuthenticatedGetWorkflowId, + useAuthenticatedGetWorkflowRunResultReport, +} from "features/myWorkflows/api"; +import React, { useCallback } from "react"; import { useParams } from "react-router-dom"; import { PaperA4 } from "./PaperA4"; @@ -16,6 +32,19 @@ export const ResultsReport: React.FC = () => { const isPrint = useMediaQuery("print"); + const handleClickScroll = useCallback((id: string) => { + const element = document.getElementById(id); + console.log(element); + if (element) { + // Find the PaperA4 element containing the target element + element.scrollIntoView({ behavior: "smooth", block: "start" }); + } + }, []); + + const { data: workflow } = useAuthenticatedGetWorkflowId({ + id: id as string, + }); + return ( { margin: 0, }} > - - {isPrint ? null : } + + + + + Pieces : + + + + {data?.data.map((task) => ( + <> + + { + handleClickScroll(task.task_id); + }} + > + + + + + + + + + ))} + + + - + + + + {workflow?.name} tasks results + + + {data?.data.map((d, i) => ( Date: Tue, 26 Dec 2023 20:38:54 -0300 Subject: [PATCH 25/30] chore: general styles --- frontend/package.json | 1 - .../components/ResultsReport/PaperA4.tsx | 4 +- .../components/ResultsReport/PieceReport.tsx | 2 +- .../components/ResultsReport/index.tsx | 70 ++++++++++++++++--- .../CustomTabMenu/TaskDetail.tsx | 36 +++++----- frontend/yarn.lock | 9 +-- 6 files changed, 83 insertions(+), 39 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 6f6509c1..bdac0a12 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -26,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", diff --git a/frontend/src/features/myWorkflows/components/ResultsReport/PaperA4.tsx b/frontend/src/features/myWorkflows/components/ResultsReport/PaperA4.tsx index 0049c8c8..2b85c2dc 100644 --- a/frontend/src/features/myWorkflows/components/ResultsReport/PaperA4.tsx +++ b/frontend/src/features/myWorkflows/components/ResultsReport/PaperA4.tsx @@ -16,6 +16,7 @@ export const PaperA4: React.FC<{ children?: React.ReactNode; id: string }> = ({ maxHeight: "88vh", display: "flex", flexDirection: "column", + marginTop: "36px", }} > = ({ sx={{ width: "100%", overflowX: "hidden", - overflowY: "scroll", - "&::WebkitScrollbar": { display: "none" }, + overflowY: "auto", }} > {children} diff --git a/frontend/src/features/myWorkflows/components/ResultsReport/PieceReport.tsx b/frontend/src/features/myWorkflows/components/ResultsReport/PieceReport.tsx index 24dfce98..90c36fc9 100644 --- a/frontend/src/features/myWorkflows/components/ResultsReport/PieceReport.tsx +++ b/frontend/src/features/myWorkflows/components/ResultsReport/PieceReport.tsx @@ -22,7 +22,7 @@ export const PieceReport: React.FC = ({ taskData, id }) => { style={{ marginBottom: "10mm", width: "100%" }} > - + diff --git a/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx b/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx index ccd44f6f..b22f5f8b 100644 --- a/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx +++ b/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx @@ -1,5 +1,6 @@ import LogoutIcon from "@mui/icons-material/Logout"; import { + Button, Container, Divider, Grid, @@ -13,18 +14,21 @@ import { useMediaQuery, } from "@mui/material"; // import { DownloadAsPDF } from "components/DownloadPDF"; +import dayjs from "dayjs"; import { useAuthenticatedGetWorkflowId, useAuthenticatedGetWorkflowRunResultReport, } from "features/myWorkflows/api"; -import React, { useCallback } from "react"; -import { useParams } from "react-router-dom"; +import React, { useCallback, useMemo } from "react"; +import { useNavigate, useParams } from "react-router-dom"; import { PaperA4 } from "./PaperA4"; import { PieceReport } from "./PieceReport"; export const ResultsReport: React.FC = () => { const { id, runId } = useParams<{ id: string; runId: string }>(); + + const navigate = useNavigate(); const { data } = useAuthenticatedGetWorkflowRunResultReport({ workflowId: id, runId, @@ -34,9 +38,7 @@ export const ResultsReport: React.FC = () => { const handleClickScroll = useCallback((id: string) => { const element = document.getElementById(id); - console.log(element); if (element) { - // Find the PaperA4 element containing the target element element.scrollIntoView({ behavior: "smooth", block: "start" }); } }, []); @@ -45,6 +47,26 @@ export const ResultsReport: React.FC = () => { id: id as string, }); + const { startDate, endDate } = useMemo(() => { + if (!data?.data) { + return { + startDate: null, + endDate: null, + }; + } + + const startDate = dayjs(data?.data[0]?.start_date).format( + "YYYY-MM-DD HH:mm:ss", + ); + const endDate = dayjs(data?.data[data?.data.length - 1]?.end_date).format( + "YYYY-MM-DD HH:mm:ss", + ); + return { + startDate, + endDate, + }; + }, [data]); + return ( { margin: 0, }} > - + + @@ -62,7 +92,7 @@ export const ResultsReport: React.FC = () => { - {data?.data.map((task) => ( + {data?.data.map((task, idx) => ( <> { - + {idx !== data?.data.length - 1 ? : null} ))} @@ -103,10 +133,30 @@ export const ResultsReport: React.FC = () => { alignItems="center" justifyContent="center" sx={{ marginY: 4 }} + direction="column" > - - {workflow?.name} tasks results - + + + {workflow?.name} tasks results + + + + + {startDate ? ( + + Start date: {startDate}{" "} + + ) : null} + {endDate ? ( + + End date: {endDate}{" "} + + ) : null} + {data?.data.map((d, i) => ( diff --git a/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskDetail.tsx b/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskDetail.tsx index 91e26d56..8a37e11d 100644 --- a/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskDetail.tsx +++ b/frontend/src/features/myWorkflows/components/WorkflowDetail/CustomTabMenu/TaskDetail.tsx @@ -8,11 +8,14 @@ import { Typography, Container, } from "@mui/material"; -import { intervalToDuration } from "date-fns"; +import dayjs from "dayjs"; +import duration from "dayjs/plugin/duration"; import { taskStatesColorMap } from "features/myWorkflows/constants"; import { type IWorkflowRunTasks } from "features/myWorkflows/types/runs"; import { useMemo } from "react"; +dayjs.extend(duration); + interface IWorkflowRunTasksExtended extends IWorkflowRunTasks { pieceName: string; } @@ -24,23 +27,26 @@ interface ITaskDetailsProps { export const TaskDetails = (props: ITaskDetailsProps) => { const duration = useMemo(() => { if (props.taskData.duration) { - const duration = intervalToDuration({ - start: 0, - end: props.taskData.duration * 1000, - }); + const duration = dayjs.duration(props.taskData.duration * 1000); - return `${duration.hours} ${ - (duration?.hours ?? 0) > 1 ? "hours" : "hour" - } : ${duration.minutes} ${ - (duration?.minutes ?? 0) > 1 ? "minutes" : "minute" - } : ${duration.seconds} ${ - (duration?.seconds ?? 0) > 1 ? "seconds" : "second" + return `${duration.hours()} ${ + duration.hours() > 1 ? "hours" : "hour" + } : ${duration.minutes()} ${ + duration.minutes() > 1 ? "minutes" : "minute" + } : ${duration.seconds()} ${ + duration.seconds() > 1 ? "seconds" : "second" }`; } else { return "Not done yet"; } }, [props.taskData.duration]); + const formatDate = (date?: string | null) => { + return date + ? dayjs(date).format("YYYY-MM-DD HH:mm:ss") + : "Not executed yet"; + }; + return ( { fontWeight="500" > - {props.taskData.start_date - ? new Date(props.taskData.start_date).toLocaleString() - : "Not executed yet"} + {formatDate(props.taskData.start_date)} { fontWeight="500" > - {props.taskData.end_date - ? new Date(props.taskData.end_date).toLocaleString() - : "Not ended yet"} + {formatDate(props.taskData.end_date)} Date: Wed, 27 Dec 2023 14:11:15 -0300 Subject: [PATCH 26/30] feat: add loading --- .../components/ResultsReport/index.tsx | 5 ++ .../components/ResultsReport/skeleton.tsx | 71 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 frontend/src/features/myWorkflows/components/ResultsReport/skeleton.tsx diff --git a/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx b/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx index b22f5f8b..17b85772 100644 --- a/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx +++ b/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx @@ -24,6 +24,7 @@ import { useNavigate, useParams } from "react-router-dom"; import { PaperA4 } from "./PaperA4"; import { PieceReport } from "./PieceReport"; +import { ResultsReportSkeleton } from "./skeleton"; export const ResultsReport: React.FC = () => { const { id, runId } = useParams<{ id: string; runId: string }>(); @@ -67,6 +68,10 @@ export const ResultsReport: React.FC = () => { }; }, [data]); + if (!data?.data) { + return ; + } + return ( { + const array = Array(5).fill(0); + + return ( + + + + + + + Pieces : + + + + {array.map((_, idx) => ( + <> + + {}}> + } /> + + + {idx !== array.length - 1 ? : null} + + ))} + + + + + + + + + + + ); +}; From 4d5cb8068756c6c98a309625a3cda99489eb425b Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Thu, 28 Dec 2023 12:05:47 -0300 Subject: [PATCH 27/30] chore: styles improvements --- frontend/src/components/DownloadPDF/index.tsx | 14 +- .../components/ResultsReport/PaperA4.tsx | 10 +- .../components/ResultsReport/PieceReport.tsx | 80 ++++++++-- .../components/ResultsReport/index.tsx | 151 +++++++++++++----- .../components/ResultsReport/skeleton.tsx | 13 +- .../WorkflowDetail/WorkflowRunDetail.tsx | 2 +- .../WorkflowDetail/WorkflowRunsTable.tsx | 8 +- .../components/WorkflowDetail/index.tsx | 4 +- .../myWorkflows/pages/WorkflowsPage.tsx | 4 +- 9 files changed, 215 insertions(+), 71 deletions(-) diff --git a/frontend/src/components/DownloadPDF/index.tsx b/frontend/src/components/DownloadPDF/index.tsx index e2b2079d..1735eb2d 100644 --- a/frontend/src/components/DownloadPDF/index.tsx +++ b/frontend/src/components/DownloadPDF/index.tsx @@ -1,21 +1,21 @@ -import { Button } from "@mui/material"; +import { Button, type ButtonProps } from "@mui/material"; import React, { useEffect, useState } from "react"; import { useReactToPrint } from "react-to-print"; -interface Props { +interface Props extends ButtonProps { contentId: string; } -export const DownloadAsPDF: React.FC = ({ contentId }) => { +export const DownloadAsPDF: React.FC = ({ contentId, ...props }) => { const [content, setContent] = useState(null); const handlePrint = useReactToPrint({ content: () => content, }); useEffect(() => { - if (content) { - setContent(content); - } + // Fetch the content element using the contentId + const newContent = document.getElementById(contentId); + setContent(newContent); }, [contentId]); const handlePrintWithTimeout = () => { @@ -26,7 +26,7 @@ export const DownloadAsPDF: React.FC = ({ contentId }) => { }; return ( - ); diff --git a/frontend/src/features/myWorkflows/components/ResultsReport/PaperA4.tsx b/frontend/src/features/myWorkflows/components/ResultsReport/PaperA4.tsx index 2b85c2dc..ce97ad13 100644 --- a/frontend/src/features/myWorkflows/components/ResultsReport/PaperA4.tsx +++ b/frontend/src/features/myWorkflows/components/ResultsReport/PaperA4.tsx @@ -10,13 +10,15 @@ export const PaperA4: React.FC<{ children?: React.ReactNode; id: string }> = ({ return ( = ({ taskData, id }) => { + const { startDate, endDate, duration } = useMemo(() => { + if (!taskData.start_date || !taskData.end_date || !taskData.duration) { + return { + startDate: null, + endDate: null, + duration: null, + }; + } + + const durationRaw = dayjs.duration(taskData.duration * 1000); + + const duration = `${durationRaw.hours()} ${ + durationRaw.hours() > 1 ? "hours" : "hour" + } : ${durationRaw.minutes()} ${ + durationRaw.minutes() > 1 ? "minutes" : "minute" + } : ${durationRaw.seconds()} ${ + durationRaw.seconds() > 1 ? "seconds" : "second" + }`; + + const startDate = dayjs(taskData.start_date).format("YYYY-MM-DD HH:mm:ss"); + const endDate = dayjs(taskData.end_date).format("YYYY-MM-DD HH:mm:ss"); + return { + duration, + startDate, + endDate, + }; + }, [taskData]); + return ( - + - + @@ -36,6 +67,35 @@ export const PieceReport: React.FC = ({ taskData, id }) => { /> + + + + {startDate ? ( + + Start date: {startDate}{" "} + + ) : null} + {endDate ? ( + + End date: {endDate}{" "} + + ) : null} + {duration ? ( + + Duration: {duration}{" "} + + ) : null} + + ); }; diff --git a/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx b/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx index 17b85772..24aeb9b9 100644 --- a/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx +++ b/frontend/src/features/myWorkflows/components/ResultsReport/index.tsx @@ -10,11 +10,13 @@ import { ListItemIcon, ListItemText, Paper, + Tooltip, Typography, useMediaQuery, } from "@mui/material"; -// import { DownloadAsPDF } from "components/DownloadPDF"; +import { DownloadAsPDF } from "components/DownloadPDF"; import dayjs from "dayjs"; +import duration from "dayjs/plugin/duration"; import { useAuthenticatedGetWorkflowId, useAuthenticatedGetWorkflowRunResultReport, @@ -26,6 +28,8 @@ import { PaperA4 } from "./PaperA4"; import { PieceReport } from "./PieceReport"; import { ResultsReportSkeleton } from "./skeleton"; +dayjs.extend(duration); + export const ResultsReport: React.FC = () => { const { id, runId } = useParams<{ id: string; runId: string }>(); @@ -48,23 +52,32 @@ export const ResultsReport: React.FC = () => { id: id as string, }); - const { startDate, endDate } = useMemo(() => { + const { startDate, endDate, duration } = useMemo(() => { if (!data?.data) { return { startDate: null, endDate: null, + duration: null, }; } - const startDate = dayjs(data?.data[0]?.start_date).format( - "YYYY-MM-DD HH:mm:ss", - ); - const endDate = dayjs(data?.data[data?.data.length - 1]?.end_date).format( - "YYYY-MM-DD HH:mm:ss", - ); + const startDate = dayjs(data?.data[0]?.start_date); + const endDate = dayjs(data?.data[data?.data.length - 1]?.end_date); + + const durationRaw = dayjs.duration(endDate.diff(startDate)); + + const formattedDuration = `${durationRaw.hours()} ${ + durationRaw.hours() > 1 ? "hours" : "hour" + } : ${durationRaw.minutes()} ${ + durationRaw.minutes() > 1 ? "minutes" : "minute" + } : ${durationRaw.seconds()} ${ + durationRaw.seconds() > 1 ? "seconds" : "second" + }`; + return { - startDate, - endDate, + startDate: startDate.format("YYYY-MM-DD HH:mm:ss"), + endDate: endDate.format("YYYY-MM-DD HH:mm:ss"), + duration: formattedDuration, }; }, [data]); @@ -75,27 +88,29 @@ export const ResultsReport: React.FC = () => { return ( - + + + Pieces : - {data?.data.map((task, idx) => ( <> @@ -105,6 +120,7 @@ export const ResultsReport: React.FC = () => { sx={{ maxHeight: "60px", overflow: "hidden" }} > { handleClickScroll(task.task_id); }} @@ -112,17 +128,38 @@ export const ResultsReport: React.FC = () => { - + + {task.piece_name} + + } + /> {idx !== data?.data.length - 1 ? : null} ))} + + + {" "} + + - + { xs={12} alignItems="center" justifyContent="center" - sx={{ marginY: 4 }} + sx={{ marginTop: 10 }} direction="column" > - - - {workflow?.name} tasks results - - - - - {startDate ? ( - - Start date: {startDate}{" "} + + + + Workflow: {workflow?.name} - ) : null} - {endDate ? ( - - End date: {endDate}{" "} + + + + + + Pieces Results - ) : null} + + + + + + {startDate ? ( + + + Workflow start date: + + {startDate}{" "} + + ) : null} + {endDate ? ( + + + Workflow end date: + {" "} + {endDate}{" "} + + ) : null} + {duration ? ( + + + Workflow total duration: + {" "} + {duration}{" "} + + ) : null} + @@ -176,6 +251,8 @@ export const ResultsReport: React.FC = () => { } /> ))} + + diff --git a/frontend/src/features/myWorkflows/components/ResultsReport/skeleton.tsx b/frontend/src/features/myWorkflows/components/ResultsReport/skeleton.tsx index 4b68b350..90397236 100644 --- a/frontend/src/features/myWorkflows/components/ResultsReport/skeleton.tsx +++ b/frontend/src/features/myWorkflows/components/ResultsReport/skeleton.tsx @@ -21,16 +21,19 @@ export const ResultsReportSkeleton: React.FC = () => { return ( - - + + @@ -61,7 +64,7 @@ export const ResultsReportSkeleton: React.FC = () => { diff --git a/frontend/src/features/myWorkflows/components/WorkflowDetail/WorkflowRunDetail.tsx b/frontend/src/features/myWorkflows/components/WorkflowDetail/WorkflowRunDetail.tsx index 15c5cc96..99092e27 100644 --- a/frontend/src/features/myWorkflows/components/WorkflowDetail/WorkflowRunDetail.tsx +++ b/frontend/src/features/myWorkflows/components/WorkflowDetail/WorkflowRunDetail.tsx @@ -89,7 +89,7 @@ export const WorkflowRunDetail = forwardRef( })); return ( - + {runId ? ( nodeId ? ( ( headerName: "", maxWidth: 10, renderCell: ({ row }) => ( - + { navigation( @@ -112,7 +112,7 @@ export const WorkflowRunsTable = forwardRef( }} disabled={row.state !== "success" && row.state !== "failed"} > - + ), @@ -150,7 +150,7 @@ export const WorkflowRunsTable = forwardRef( return ( - + {isLoading ? ( { - + {/* Left Column */} {/* WorkflowRunsTable */} @@ -223,7 +223,7 @@ export const WorkflowDetail: React.FC = () => { {/* WorkflowPanel */} - + { return ( - + + + From 785f5cae7e5f23658cb9f604f59aec2821c268b2 Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Thu, 28 Dec 2023 14:44:30 -0300 Subject: [PATCH 28/30] feat: remove API_ENV in frontend --- .github/workflows/release-frontend-dev.yaml | 1 - .github/workflows/release-frontend.yaml | 1 - docker-compose-dev.yaml | 1 - frontend/.env.production | 1 - frontend/entrypoint.sh | 1 - frontend/src/config/environment.config.ts | 3 -- .../src/services/clients/domino.client.ts | 4 +-- .../src/services/config/endpoints.config.ts | 29 ++++--------------- .../templates/domino-frontend-deployment.yml | 2 -- .../docker-compose-without-database.yaml | 1 - src/domino/cli/utils/docker-compose.yaml | 1 - 11 files changed, 8 insertions(+), 37 deletions(-) diff --git a/.github/workflows/release-frontend-dev.yaml b/.github/workflows/release-frontend-dev.yaml index 39550034..ac086d0c 100644 --- a/.github/workflows/release-frontend-dev.yaml +++ b/.github/workflows/release-frontend-dev.yaml @@ -56,5 +56,4 @@ jobs: context: frontend file: frontend/Dockerfile.prod # Path to the Dockerfile env: - API_ENV: local DOMINO_DEPLOY_MODE: local-compose diff --git a/.github/workflows/release-frontend.yaml b/.github/workflows/release-frontend.yaml index c6523813..4c97dcb0 100644 --- a/.github/workflows/release-frontend.yaml +++ b/.github/workflows/release-frontend.yaml @@ -56,5 +56,4 @@ jobs: context: frontend file: frontend/Dockerfile.prod # Path to the Dockerfile env: - API_ENV: local DOMINO_DEPLOY_MODE: local-compose diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index 2801dda9..370d20e9 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -362,7 +362,6 @@ services: container_name: domino-frontend command: yarn start environment: - - API_ENV=local - DOMINO_DEPLOY_MODE=local-compose - API_URL=http://localhost:8000 ports: diff --git a/frontend/.env.production b/frontend/.env.production index 29636617..e75e70e3 100644 --- a/frontend/.env.production +++ b/frontend/.env.production @@ -1,4 +1,3 @@ # These values are placeholders -API_ENV="local" DOMINO_DEPLOY_MODE="local-compose" API_URL="http://localhost:8000" diff --git a/frontend/entrypoint.sh b/frontend/entrypoint.sh index d4be6975..d556689e 100644 --- a/frontend/entrypoint.sh +++ b/frontend/entrypoint.sh @@ -1,7 +1,6 @@ #!/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 diff --git a/frontend/src/config/environment.config.ts b/frontend/src/config/environment.config.ts index bd529c68..f534c049 100644 --- a/frontend/src/config/environment.config.ts +++ b/frontend/src/config/environment.config.ts @@ -2,11 +2,9 @@ * @todo add other envs when available */ export type INodeEnv = "development"; -export type IApiEnv = "local" | "dev" | "prod"; export interface IEnvironment { NODE_ENV: INodeEnv; - API_ENV: IApiEnv; USE_MOCK: boolean; API_URL: string; } @@ -16,7 +14,6 @@ export interface IEnvironment { */ export const environment: IEnvironment = { NODE_ENV: import.meta.env.NODE_ENV as INodeEnv, - API_ENV: import.meta.env.API_ENV as IApiEnv, API_URL: import.meta.env.API_URL as string, USE_MOCK: !!import.meta.env.VITE_USE_MOCK, }; diff --git a/frontend/src/services/clients/domino.client.ts b/frontend/src/services/clients/domino.client.ts index b8f7ad76..65703fd1 100644 --- a/frontend/src/services/clients/domino.client.ts +++ b/frontend/src/services/clients/domino.client.ts @@ -3,12 +3,12 @@ import { environment } from "config/environment.config"; import { dispatchLogout } from "context/authentication"; import { toast } from "react-toastify"; -import { endpoints } from "../config/endpoints.config"; +import { endpoint } from "../config/endpoints.config"; import { dominoMock } from "./domino.mock"; export const dominoApiClient = axios.create({ - baseURL: endpoints?.api ?? "", + baseURL: endpoint, }); if (environment.USE_MOCK) { diff --git a/frontend/src/services/config/endpoints.config.ts b/frontend/src/services/config/endpoints.config.ts index c5bca99a..e145c179 100644 --- a/frontend/src/services/config/endpoints.config.ts +++ b/frontend/src/services/config/endpoints.config.ts @@ -1,28 +1,11 @@ -import { environment, type IApiEnv } from "config/environment.config"; - -interface IEndpoints { - api: string; -} - -/** - * Stores all endpoints accessed by the application - */ -const configEndpoints: Record = { - local: { - api: "http://localhost:8000/", - }, - dev: { - api: "http://localhost/api", - }, - prod: { - api: environment.API_URL, - }, -}; +import { environment } from "config/environment.config"; /** * Exports all endpoints, already set up by current env */ -export const endpoints = - configEndpoints[environment.API_ENV] ?? configEndpoints.dev; -export default endpoints; +console.log(environment); + +export const endpoint = environment.API_URL ?? "http://localhost:8000/"; + +export default endpoint; diff --git a/helm/domino/templates/domino-frontend-deployment.yml b/helm/domino/templates/domino-frontend-deployment.yml index fcbc7418..b4158b1a 100644 --- a/helm/domino/templates/domino-frontend-deployment.yml +++ b/helm/domino/templates/domino-frontend-deployment.yml @@ -28,8 +28,6 @@ spec: ["-c","yarn start"] {{- end }} env: - - name: API_ENV - value: {{ .Values.frontend.apiEnv }} - name: DOMINO_DEPLOY_MODE value: {{ .Values.frontend.deployMode }} - name: API_URL diff --git a/src/domino/cli/utils/docker-compose-without-database.yaml b/src/domino/cli/utils/docker-compose-without-database.yaml index dd3c61b9..ec1aee52 100644 --- a/src/domino/cli/utils/docker-compose-without-database.yaml +++ b/src/domino/cli/utils/docker-compose-without-database.yaml @@ -317,7 +317,6 @@ services: domino_rest: condition: service_started environment: - - API_ENV=local - DOMINO_DEPLOY_MODE=local-compose - API_URL=http://localhost:8000 diff --git a/src/domino/cli/utils/docker-compose.yaml b/src/domino/cli/utils/docker-compose.yaml index 2a03824e..df0b34ba 100644 --- a/src/domino/cli/utils/docker-compose.yaml +++ b/src/domino/cli/utils/docker-compose.yaml @@ -348,7 +348,6 @@ services: domino_rest: condition: service_started environment: - - API_ENV=local - DOMINO_DEPLOY_MODE=local-compose - API_URL=http://localhost:8000 From dd6eed921b58b1f1d5eabb065b9d28dbabd48f7a Mon Sep 17 00:00:00 2001 From: Nathan Vieira Marcelino Date: Thu, 28 Dec 2023 14:46:22 -0300 Subject: [PATCH 29/30] chore: typo --- .../components/SidebarForm/PieceForm/PieceFormItem/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/index.tsx b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/index.tsx index 75ed4e89..78b1fb01 100644 --- a/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/index.tsx +++ b/frontend/src/features/workflowEditor/components/SidebarForm/PieceForm/PieceFormItem/index.tsx @@ -195,7 +195,7 @@ const PieceFormItem: React.FC = ({ name={`inputs.${itemKey}.value`} language={language} - placeholder={`Enter yor ${language} code here.`} + placeholder={`Enter your ${language} code here.`} /> ); } else if ( From dd2c7be1694225715d5ba0111aa032a6b2eef845 Mon Sep 17 00:00:00 2001 From: vinicvaz Date: Thu, 28 Dec 2023 15:24:32 -0300 Subject: [PATCH 30/30] update version --- src/domino/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/domino/VERSION b/src/domino/VERSION index 53a48a1e..fab77af2 100644 --- a/src/domino/VERSION +++ b/src/domino/VERSION @@ -1 +1 @@ -0.8.2 \ No newline at end of file +0.8.3 \ No newline at end of file