From c1b01d88b54b261b2483fa39aa7d85e1e1f8221d Mon Sep 17 00:00:00 2001 From: svetaStrech Date: Sun, 31 Dec 2023 12:06:03 +0200 Subject: [PATCH] RND-370-add-info-button-to-the-3-dots --- ui_src/src/components/connectorInfo/index.js | 102 ++++++++++++++++++ .../src/components/connectorInfo/style.scss | 30 ++++++ ui_src/src/const/apiEndpoints.js | 1 + .../ProduceConsumList/index.js | 44 +++++--- .../domain/users/createUserDetails/index.js | 8 +- 5 files changed, 165 insertions(+), 20 deletions(-) create mode 100644 ui_src/src/components/connectorInfo/index.js create mode 100644 ui_src/src/components/connectorInfo/style.scss diff --git a/ui_src/src/components/connectorInfo/index.js b/ui_src/src/components/connectorInfo/index.js new file mode 100644 index 000000000..f6f49cfdb --- /dev/null +++ b/ui_src/src/components/connectorInfo/index.js @@ -0,0 +1,102 @@ +// Copyright 2022-2023 The Memphis.dev Authors +// Licensed under the Memphis Business Source License 1.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// Changed License: [Apache License, Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0), as published by the Apache Foundation. +// +// https://github.com/memphisdev/memphis/blob/master/LICENSE +// +// Additional Use Grant: You may make use of the Licensed Work (i) only as part of your own product or service, provided it is not a message broker or a message queue product or service; and (ii) provided that you do not use, provide, distribute, or make available the Licensed Work as a Service. +// A "Service" is a commercial offering, product, hosted, or managed service, that allows third parties (other than your own employees and contractors acting on your behalf) to access and/or use the Licensed Work or a substantial set of the features or functionality of the Licensed Work to third parties as a software-as-a-service, platform-as-a-service, infrastructure-as-a-service or other similar services that compete with Licensor products or services. + +import './style.scss'; + +import React, { useEffect, useState } from 'react'; +import Modal from '../modal'; +import Spinner from '../spinner'; +import { ApiEndpoints } from '../../const/apiEndpoints'; +import { httpRequest } from '../../services/http'; +import { sendTrace } from '../../services/genericServices'; +import { connectorTypesSource, connectorTypesSink } from '../../connectors'; + +const ConnectorInfo = ({ open, clickOutside, connectorId }) => { + const [loading, setLoading] = useState(false); + const [info, setInfo] = useState(null); + + useEffect(() => { + !open && setInfo(null); + open && getConnectorInfo(connectorId); + }, [open]); + + const getConnectorInfo = async (connectorId) => { + setLoading(true); + try { + const data = await httpRequest('GET', `${ApiEndpoints.GET_CONNECTOR_DETAILS}?connector_id=${connectorId}`); + arrangeData(data); + sendTrace('getConnectorInfo', { + connector_type: data?.connector_type, + type: data?.type + }); + } catch (error) { + } finally { + setLoading(false); + } + }; + + const arrangeData = (data) => { + let fieldInputs; + if (data?.connector_type === 'source') { + let field = connectorTypesSource.find((connector) => connector?.name?.toLocaleLowerCase() === data?.type); + fieldInputs = field?.inputs?.Source; + } else if (data?.connector_type === 'sink') { + let field = connectorTypesSink.find((connector) => connector?.name?.toLocaleLowerCase() === data?.type); + fieldInputs = field?.inputs?.Sink; + } + let formFields = []; + fieldInputs?.forEach((field) => { + formFields.push({ name: field?.display, value: data[field?.name] || data?.settings[field?.name] }); + if (field?.children) { + field?.options?.forEach((option) => { + if (data?.settings[option?.toLocaleLowerCase()?.replace(/ /g, '_')]) { + formFields.push({ name: option, value: data?.settings[option?.toLocaleLowerCase()?.replace(/ /g, '_')] }); + } + }); + } + }); + setInfo(formFields); + }; + + return ( + +
+ {loading && ( +
+ +
+ )} + {!loading && + info?.map((field, index) => { + return ( +
+ + +
+ ); + })} +
+
+ ); +}; + +export default ConnectorInfo; diff --git a/ui_src/src/components/connectorInfo/style.scss b/ui_src/src/components/connectorInfo/style.scss new file mode 100644 index 000000000..28c2e6886 --- /dev/null +++ b/ui_src/src/components/connectorInfo/style.scss @@ -0,0 +1,30 @@ +.connector-info { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + padding-top: 30px; + overflow-y: auto; + .loader { + width: 100%; + display: flex; + justify-content: center; + margin-top: 10px; + } + .field-conainer { + display: flex; + flex-direction: column; + margin-bottom: 20px; + .field-name { + color: #737373; + font-family: 'Inter'; + font-size: 12px; + text-transform: capitalize; + } + .field-value { + color: #000; + font-family: 'Inter'; + font-size: 14px; + } + } +} diff --git a/ui_src/src/const/apiEndpoints.js b/ui_src/src/const/apiEndpoints.js index 5b22d47e4..fa06076d3 100644 --- a/ui_src/src/const/apiEndpoints.js +++ b/ui_src/src/const/apiEndpoints.js @@ -59,6 +59,7 @@ export const ApiEndpoints = { STOP_CONNECTOR: '/stations/stopConnector', GET_CONNECTOR_ERRORS: '/stations/getConnectorErrors', PURGE_CONNECTOR_ERRORS: '/stations/purgeConnectorErrors', + GET_CONNECTOR_DETAILS: '/stations/getConnectorDetails', //Async Tasks GET_ASYNC_TASKS: '/asyncTasks/getAsyncTasks', diff --git a/ui_src/src/domain/stationOverview/stationObservabilty/ProduceConsumList/index.js b/ui_src/src/domain/stationOverview/stationObservabilty/ProduceConsumList/index.js index 4ede0af93..65b139678 100644 --- a/ui_src/src/domain/stationOverview/stationObservabilty/ProduceConsumList/index.js +++ b/ui_src/src/domain/stationOverview/stationObservabilty/ProduceConsumList/index.js @@ -26,6 +26,7 @@ import { ReactComponent as ConnectIcon } from '../../../../assets/images/connect import { IoPlayCircleOutline, IoRemoveCircleOutline, IoPause, IoWarning } from 'react-icons/io5'; import { HiDotsVertical } from 'react-icons/hi'; import { MdError } from 'react-icons/md'; +import { IoMdInformationCircle } from 'react-icons/io'; import OverflowTip from '../../../../components/tooltip/overflowtip'; import { ReactComponent as UnsupportedIcon } from '../../../../assets/images/unsupported.svg'; import StatusIndication from '../../../../components/indication'; @@ -45,9 +46,10 @@ import Spinner from '../../../../components/spinner'; import TooltipComponent from '../../../../components/tooltip/tooltip'; import { isCloud } from '../../../../services/valueConvertor'; import { sendTrace } from '../../../../services/genericServices'; -import { BiLogoGoLang, BiLogoPython } from "react-icons/bi" -import { SiDotnet } from "react-icons/si"; -import { DiJavascript1 } from "react-icons/di"; +import { BiLogoGoLang, BiLogoPython } from 'react-icons/bi'; +import { SiDotnet } from 'react-icons/si'; +import { DiJavascript1 } from 'react-icons/di'; +import ConnectorInfo from '../../../../components/connectorInfo'; const overlayStylesConnectors = { borderRadius: '8px', @@ -93,6 +95,7 @@ const ProduceConsumList = ({ producer }) => { const [selectedConnector, setSelectedConnector] = useState(null); const [openConnectorModal, setOpenConnectorModal] = useState(false); const [openConnectorError, setOpenConnectorError] = useState(false); + const [openConnectorInfo, setOpenConnectorInfo] = useState(false); const [actionItem, setActionItem] = useState(null); const [loading, setLoader] = useState(false); const producerItemsList = [ @@ -370,15 +373,15 @@ const ProduceConsumList = ({ producer }) => { const lang = item?.sdk_language; const mapping = { - go: , - "node.js": , - python: , - ".NET": + go: , + 'node.js': , + python: , + '.NET': }; const iconComponent = lang ? mapping[lang] : ; - return
{iconComponent}
; + return
{iconComponent}
; } return ( @@ -471,9 +474,7 @@ const ProduceConsumList = ({ producer }) => { ) : ( - - {getIconByLang(row)} - + {getIconByLang(row)} )} {row.name} @@ -530,6 +531,14 @@ const ProduceConsumList = ({ producer }) => { icon={} loader={loading && actionItem === 1} /> + { + setOpenConnectorInfo(true); + setOpenConnectorPopover(false); + }} + icon={} + /> { @@ -565,9 +574,7 @@ const ProduceConsumList = ({ producer }) => { ) : ( - - {getIconByLang(row)} - + {getIconByLang(row)} )} {row?.name} @@ -626,6 +633,14 @@ const ProduceConsumList = ({ producer }) => { icon={} loader={loading && actionItem === 1} /> + { + setOpenConnectorInfo(true); + setOpenConnectorPopover(false); + }} + icon={} + /> { @@ -816,6 +831,7 @@ const ProduceConsumList = ({ producer }) => { setGenerateModal(false)} /> setOpenConnectorError(false)} connectorId={selectedConnector?.id} /> + setOpenConnectorInfo(false)} connectorId={selectedConnector?.id} /> ); }; diff --git a/ui_src/src/domain/users/createUserDetails/index.js b/ui_src/src/domain/users/createUserDetails/index.js index 8af93f11a..bf68b1660 100644 --- a/ui_src/src/domain/users/createUserDetails/index.js +++ b/ui_src/src/domain/users/createUserDetails/index.js @@ -123,17 +123,13 @@ const CreateUserDetails = ({ createUserRef, closeModal, handleLoader, userList, formFields?.allow_read_permissions === null || formFields?.allow_read_permissions === undefined ? null - : rbacTypeRead === 'stations' - ? formFields?.allow_read_permissions - : [formFields?.allow_read_permissions]; + : formFields?.allow_read_permissions; bodyRequest['allow_write_permissions'] = formFields?.allow_write_permissions?.length === 0 || formFields?.allow_write_permissions === null || formFields?.allow_write_permissions === undefined ? null - : rbacTypeWrite === 'stations' - ? formFields?.allow_write_permissions - : [formFields?.allow_write_permissions]; + : formFields?.allow_write_permissions; } const data = await httpRequest('POST', ApiEndpoints.ADD_USER, bodyRequest); if (data) {