From 1918d3b0d806a211ece2188847b577babae651a5 Mon Sep 17 00:00:00 2001 From: Tim Pechersky Date: Wed, 15 Dec 2021 15:56:46 +0000 Subject: [PATCH] edit dashboard experience --- frontend/pages/dashboard/[dashboardId].js | 22 +- frontend/src/components/AutoCompleter.js | 7 +- frontend/src/components/CheckboxABI.js | 160 +++---- frontend/src/components/NewDashboardChart.js | 409 +++++++++++------- frontend/src/components/NewDashboardName.js | 9 +- frontend/src/components/SubscriptionReport.js | 2 +- frontend/src/core/constants.js | 25 ++ frontend/src/core/hooks/useDashboard.js | 27 +- frontend/src/core/hooks/usePresignedURL.js | 15 +- .../core/providers/OverlayProvider/index.js | 106 +---- .../src/core/providers/UIProvider/index.js | 198 ++++++++- .../core/services/subscriptions.service.js | 6 + frontend/src/core/utils/massageAbi.js | 74 ---- 13 files changed, 642 insertions(+), 418 deletions(-) delete mode 100644 frontend/src/core/utils/massageAbi.js diff --git a/frontend/pages/dashboard/[dashboardId].js b/frontend/pages/dashboard/[dashboardId].js index 0a3c0d63..06f05687 100644 --- a/frontend/pages/dashboard/[dashboardId].js +++ b/frontend/pages/dashboard/[dashboardId].js @@ -23,6 +23,7 @@ import SubscriptionReport from "../../src/components/SubscriptionReport"; import { AiOutlinePlusCircle } from "react-icons/ai"; import { v4 } from "uuid"; import { DRAWER_TYPES } from "../../src/core/providers/OverlayProvider/constants"; +import Page404 from "../../src/components/FourOFour"; const HOUR_KEY = "Hourly"; const DAY_KEY = "Daily"; @@ -158,12 +159,12 @@ const Analytics = () => { const updateCallback = ({ name }) => { updateDashboard.mutate({ - id: dashboardCache.data.data.id, + id: dashboardCache.data.id, dashboard: { - dashboard_id: dashboardCache.data.data.id, + dashboard_id: dashboardCache.data.id, name: name, subscription_cache: - dashboardCache.data.data.resource_data.subscription_setting, + dashboardCache.data.resource_data.subscription_setting, }, }); }; @@ -175,6 +176,13 @@ const Analytics = () => { ) return ; + if ( + dashboardCache.isLoadingError && + dashboardCache?.error?.response?.status === 404 + ) { + return ; + } + const plotMinW = "250px"; return ( @@ -193,7 +201,7 @@ const Analytics = () => { as={Heading} colorScheme="blue" placeholder="enter note here" - defaultValue={dashboardCache.data.data.resource_data.name} + defaultValue={dashboardCache.data.resource_data.name} onSubmit={(nextValue) => updateCallback({ name: nextValue, @@ -224,7 +232,7 @@ const Analytics = () => { onClick={() => overlay.toggleDrawer({ type: DRAWER_TYPES.NEW_DASHBOARD_ITEM, - props: dashboardCache.data.data.resource_data, + props: dashboardCache.data.resource_data, }) } mr={8} @@ -273,7 +281,7 @@ const Analytics = () => { ); })} - {dashboardCache.data.data.resource_data.subscription_settings[0] === + {dashboardCache.data.resource_data.subscription_settings[0] === undefined && ( - )} - dropdownItem={(item) => { - const badgeColor = color(`${item.color}`); - return ( - <> - - {item.label} - - - ABI - - - {item.address} - - + + {ui.dashboardUpdate.subscription_settings.length > 0 && ( + <> + Subscriptions: + + {ui.dashboardUpdate.subscription_settings.map( + (subscribedItem, idx) => { + const subscriptionItem = + subscriptionsCache.data.subscriptions.find( + (subscription) => + subscription.id === subscribedItem?.subscription_id ); - }} - /> - {subscribedItem?.subscription?.id && ( - - Metric: - item.name} - list={Object.values(drawerState[idx].generic)} - isItemChecked={(item) => item.checked} - isAllChecked={Object.values(drawerState[idx].generic).every( - (item) => !!item.checked - )} - isIndeterminate={ - Object.values(drawerState[idx].generic).some( - (item) => item.checked - ) && - !Object.values(drawerState[idx].generic).every( - (item) => item.checked - ) - } - setItemChecked={(item, isChecked) => - setGeneric((currentState) => { - const newState = { ...currentState }; - newState[item.value].checked = isChecked; - return newState; - }) - } - setAll={(isChecked) => - setGeneric((currentState) => { - const newState = { ...currentState }; - Object.keys(newState).forEach( - (key) => (newState[key].checked = isChecked) - ); - return newState; - }) - } - /> + return ( + + {subscribedItem?.subscription_id && ( + <> +

+ + + {`${subscriptionItem.label} (${subscriptionItem.address})`} + + + +

- -
- )} -
- ); - })} - - + + + {subscribedItem?.subscription_id && ( + + } + variant="ghost" + colorScheme="red" + size="sm" + onClick={() => + ui.dispatchDashboardUpdate({ + type: DASHBOARD_UPDATE_ACTIONS.DROP_SUBSCRIPTION, + payload: { + subscriptionId: + subscribedItem.subscription_id, + }, + }) + } + /> + Metric: + item} + list={GENERIC_METRICS} + isItemChecked={(item) => + subscribedItem.generic.some( + (subscribedGenericItem) => + subscribedGenericItem.name === item + ) + } + isAllChecked={GENERIC_METRICS.some((item) => + subscribedItem.generic.some( + (subscribedGenericItem) => + subscribedGenericItem.name === item + ) + )} + isIndeterminate={GENERIC_METRICS.some( + (item) => + subscribedItem.generic.some( + (subscribedGenericItem) => + subscribedGenericItem.name == item + ) + )} + setItemChecked={(item, isChecked) => + ui.dispatchDashboardUpdate({ + type: isChecked + ? DASHBOARD_UPDATE_ACTIONS.APPEND_METRIC + : DASHBOARD_UPDATE_ACTIONS.DROP_METRIC, + scope: + DASHBOARD_CONFIGURE_SETTING_SCOPES.METRIC_NAME, + payload: { + subscriptionId: + subscribedItem.subscription_id, + data: item, + propertyName: "generic", + }, + }) + } + setAll={(isChecked) => + ui.dispatchDashboardUpdate({ + type: isChecked + ? DASHBOARD_UPDATE_ACTIONS.APPEND_METRIC + : DASHBOARD_UPDATE_ACTIONS.DROP_METRIC, + scope: + DASHBOARD_CONFIGURE_SETTING_SCOPES.METRICS_ARRAY, + payload: { + subscriptionId: + subscribedItem.subscription_id, + data: GENERIC_METRICS.map( + (genericMetricName) => { + return { name: genericMetricName }; + } + ), + propertyName: "generic", + }, + }) + } + /> + + + + )} + + + + )} + {subscribedItem?.subscription_id === undefined && ( + <> + + !ui.dashboardUpdate.subscription_settings.some( + (subscriptiponSetting) => + pickerItem.id === + subscriptiponSetting.subscription_id + ) && pickerItem.abi === "True" + )} + itemToString={(item) => item?.label} + onSelect={(selectedItem) => { + ui.dispatchDashboardUpdate({ + type: DASHBOARD_UPDATE_ACTIONS.OVERRIDE_SUBSCRIPTION, + payload: { + subscriptionId: selectedItem.id, + index: idx, + }, + }); + }} + getLeftAddonColor={(item) => item?.color ?? "inherit"} + getLabelColor={(item) => + item?.color ? color(item.color) : undefined + } + placeholder="Select subcription" + getDefaultValue={(item) => + item?.label ? item.label : "" + } + filterFn={filterFn} + empyListCTA={(inputValue) => ( + + )} + dropdownItem={(item) => { + const badgeColor = color(`${item.color}`); + return ( + <> + + {item.label} + + + ABI + + + {item.address} + + + ); + }} + /> + + + )} + + ); + } + )} + + + )} + + + ); }; diff --git a/frontend/src/components/NewDashboardName.js b/frontend/src/components/NewDashboardName.js index bf9439d4..431f93cd 100644 --- a/frontend/src/components/NewDashboardName.js +++ b/frontend/src/components/NewDashboardName.js @@ -20,9 +20,12 @@ import { colors, animals, } from "unique-names-generator"; +import UIContext from "../core/providers/UIProvider/context"; +import { DASHBOARD_UPDATE_ACTIONS } from "../core/constants"; const NewDashboardName = (props) => { const overlay = useContext(OverlayContext); + const { dispatchDashboardUpdate } = useContext(UIContext); const { createDashboard } = useDashboard(); const [name, setName] = useState(props.initialName); const [placeholder] = useState( @@ -35,6 +38,10 @@ const NewDashboardName = (props) => { const router = useRouter(); useEffect(() => { if (createDashboard.isSuccess && createDashboard.data) { + createDashboard.reset(); + dispatchDashboardUpdate({ + type: DASHBOARD_UPDATE_ACTIONS.RESET_TO_DEFAULT, + }); router.push({ pathname: "/dashboard/[dashboardId]", query: { dashboardId: createDashboard.data.id }, @@ -45,7 +52,7 @@ const NewDashboardName = (props) => { props: createDashboard.data.resource_data, }); } - }, [createDashboard, router, overlay]); + }, [createDashboard, router, overlay, dispatchDashboardUpdate]); return ( <> diff --git a/frontend/src/components/SubscriptionReport.js b/frontend/src/components/SubscriptionReport.js index e337f39e..735b05fb 100644 --- a/frontend/src/components/SubscriptionReport.js +++ b/frontend/src/components/SubscriptionReport.js @@ -25,7 +25,7 @@ const SubscriptionReport = ({ timeRange, url, id, refetchLinks }) => { url: url, isEnabled: true, id: id, - cacheType: timeRange, + cacheType: `${timeRange} subscription_report`, requestNewURLCallback: refetchLinks, hideToastOn404: true, }); diff --git a/frontend/src/core/constants.js b/frontend/src/core/constants.js index e8dd161a..ad88a62b 100644 --- a/frontend/src/core/constants.js +++ b/frontend/src/core/constants.js @@ -77,3 +77,28 @@ export const CHART_METRICS = { FUNCTIONS: "function", EVENTS: "event", }; + +export const DASHBOARD_UPDATE_ACTIONS = { + RENAME_DASHBOARD: 0, + APPEND_METRIC: 1, + DROP_METRIC: 2, + APPEND_SUBSCRIPTION: 4, + DROP_SUBSCRIPTION: 6, + OVERRIDE_DASHBOARD: 7, + OVERRIDE_SUBSCRIPTION: 8, + RESET_TO_DEFAULT: 9, +}; + +export const DASHBOARD_CONFIGURE_SETTING_SCOPES = { + METRICS_ARRAY: 1, //Scope to change whole array (methods | events | generics) + METRIC_NAME: 2, //Scope to one metric based on name + METRICS_ALL: 3, //Scope to replace whole subscription_setting object keeping subscriptionId +}; + +export const GENERIC_METRICS = [ + "transactions_in", + "transactions_out", + "value_in", + "value_out", + "balance", +]; diff --git a/frontend/src/core/hooks/useDashboard.js b/frontend/src/core/hooks/useDashboard.js index 8493f7d7..f15d4022 100644 --- a/frontend/src/core/hooks/useDashboard.js +++ b/frontend/src/core/hooks/useDashboard.js @@ -22,6 +22,22 @@ const useDashboard = (dashboardId) => { } ); + // const dashboardUpdateState = useQuery( + // ["DashboardUpdateState", { dashboardId: dashboardId }], + // () => + // new Promise((resolve, reject) => + // reject("Dashboard Update State has no network functionality") + // ), + // { + // ...queryCacheProps, + // staleTime: Infinity, + // onError: (error) => { + // toast(error, "error"); + // }, + // enabled: false, + // } + // ); + const _createDashboard = async (dashboard) => { const _dashboard = { ...dashboard }; if (!_dashboard.subscription_settings) { @@ -74,9 +90,14 @@ const useDashboard = (dashboardId) => { } ); + const _getDashboard = async (dashboardId) => { + const response = await DashboardService.getDashboard(dashboardId); + return response.data; + }; + const dashboardCache = useQuery( - ["dashboards", { dashboardId }], - () => DashboardService.getDashboard(dashboardId), + ["dashboards", { dashboardId: dashboardId }], + () => _getDashboard(dashboardId), { ...queryCacheProps, onError: (error) => { @@ -87,7 +108,7 @@ const useDashboard = (dashboardId) => { ); const dashboardLinksCache = useQuery( - ["dashboardLinks", { dashboardId }], + ["dashboardLinks", { dashboardId: dashboardId }], () => DashboardService.getDashboardLinks(dashboardId), { ...queryCacheProps, diff --git a/frontend/src/core/hooks/usePresignedURL.js b/frontend/src/core/hooks/usePresignedURL.js index d5dc75e6..14fc7b3e 100644 --- a/frontend/src/core/hooks/usePresignedURL.js +++ b/frontend/src/core/hooks/usePresignedURL.js @@ -2,7 +2,6 @@ import { useQuery } from "react-query"; import { queryCacheProps } from "./hookCommon"; import { useToast } from "."; import axios from "axios"; -import { useEffect } from "react"; const usePresignedURL = ({ url, @@ -24,11 +23,15 @@ const usePresignedURL = ({ return response.data; }; - const { data, isLoading, error, refetch, failureCount } = useQuery( - ["presignedURL", cacheType, id], + const { data, isLoading, error, failureCount } = useQuery( + ["presignedURL", cacheType, id, url], getFromPresignedURL, { ...queryCacheProps, + refetchOnMount: false, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + staleTime: Infinity, enabled: isEnabled && url ? true : false, keepPreviousData: true, onError: (e) => { @@ -44,12 +47,6 @@ const usePresignedURL = ({ } ); - useEffect(() => { - if (url && isEnabled) { - refetch(); - } - }, [url, isEnabled, refetch]); - return { data, isLoading, diff --git a/frontend/src/core/providers/OverlayProvider/index.js b/frontend/src/core/providers/OverlayProvider/index.js index 94efaa7a..b1d14e13 100644 --- a/frontend/src/core/providers/OverlayProvider/index.js +++ b/frontend/src/core/providers/OverlayProvider/index.js @@ -37,7 +37,7 @@ import useDashboard from "../../hooks/useDashboard"; import SignUp from "../../../components/SignUp"; import NewDashboardChart from "../../../components/NewDashboardChart"; import { useRouter } from "../../hooks"; -import { emptySubscriptionSettingItem } from "../../utils/massageAbi"; +import { DASHBOARD_UPDATE_ACTIONS } from "../../constants"; const NewDashboardName = React.lazy(() => import("../../../components/NewDashboardName") ); @@ -73,9 +73,6 @@ const OverlayProvider = ({ children }) => { const drawerDisclosure = useDisclosure(); const modalDisclosure = useDisclosure(); const alertDisclosure = useDisclosure(); - const [drawerState, setDrawerState] = useState([ - emptySubscriptionSettingItem, - ]); useLayoutEffect(() => { if (modal.type === MODAL_TYPES.OFF && modalDisclosure.isOpen) { @@ -119,7 +116,9 @@ const OverlayProvider = ({ children }) => { !modalDisclosure.isOpen && ui.isAppView && !ui.isLoggedIn && - !ui.isLoggingOut + !ui.isLoggingOut && + !ui.isLoggingIn && + ui.isAppReady ) { toggleModal({ type: MODAL_TYPES.LOGIN }); } else if ( @@ -134,12 +133,14 @@ const OverlayProvider = ({ children }) => { ui.isAppView, ui.isLoggedIn, ui.isLoggingOut, + ui.isLoggingIn, + ui.isAppReady, ]); const finishNewDashboard = () => { toggleDrawer({ type: DRAWER_TYPES.OFF, - props: dashboardCache.data.data.resource_data, + props: dashboardCache.data.resource_data, }); window.sessionStorage.removeItem("new_dashboard"); }; @@ -183,74 +184,7 @@ const OverlayProvider = ({ children }) => { }; const submitNewDashboardItem = () => { - const newDashboard = { ...drawer.props }; - drawerState.forEach((drawerSubscriptionSetting) => { - let index = newDashboard.subscription_settings.findIndex( - (subscriptionSetting) => - subscriptionSetting.subscription_id === - drawerSubscriptionSetting.subscription.id - ); - if (index === -1) { - newDashboard.subscription_settings.push({ - subscription_id: drawerSubscriptionSetting.subscription.id, - events: [], - generic: [], - methods: [], - }); - index = newDashboard.subscription_settings.length - 1; - } - - let temp = []; - Object.values(drawerSubscriptionSetting.generic).forEach( - (drawerGenericItem) => { - if ( - drawerGenericItem.checked && - !newDashboard.subscription_settings[index].generic.some( - (metric) => metric === drawerGenericItem.value - ) - ) { - temp.push({ name: drawerGenericItem.value }); - } - } - ); - newDashboard.subscription_settings[index].generic = [ - ...newDashboard.subscription_settings[index].generic, - ...temp, - ]; - temp = []; - - Object.values(drawerSubscriptionSetting.events).forEach( - (drawerEventItem) => { - const isSome = newDashboard.subscription_settings[index].events.some( - (metric) => metric === drawerEventItem.name - ); - if (drawerEventItem.checked && !isSome) { - temp.push({ name: drawerEventItem.name }); - } - } - ); - newDashboard.subscription_settings[index].events = [ - ...newDashboard.subscription_settings[index].events, - ...temp, - ]; - temp = []; - - Object.values(drawerSubscriptionSetting.methods).forEach( - (drawerFunctionItem) => { - const isSome = newDashboard.subscription_settings[index].methods.some( - (metric) => metric === drawerFunctionItem.name - ); - if (drawerFunctionItem.checked && !isSome) { - temp.push({ name: drawerFunctionItem.name }); - } - } - ); - newDashboard.subscription_settings[index].methods = [ - ...newDashboard.subscription_settings[index].methods, - ...temp, - ]; - }); - updateDashboard.mutate({ dashboard: newDashboard, id: dashboardId }); + updateDashboard.mutate({ dashboard: ui.dashboardUpdate, id: dashboardId }); }; useEffect(() => { @@ -259,12 +193,17 @@ const OverlayProvider = ({ children }) => { updateDashboard.isSuccess ) { toggleDrawer({ type: DRAWER_TYPES.OFF, props: undefined }); + updateDashboard.reset(); } - }, [updateDashboard.isSuccess, drawer.type]); + }, [updateDashboard, drawer.type]); useEffect(() => { - if (createDashboard.isSuccess) { + if ( + drawer.type === DRAWER_TYPES.NEW_DASHBOARD && + createDashboard.isSuccess + ) { finishNewDashboard(); + createDashboard.reset(); } //eslint-disable-next-line }, [createDashboard.isSuccess]); @@ -274,15 +213,17 @@ const OverlayProvider = ({ children }) => { createDashboard.isSuccess && drawer.type === DRAWER_TYPES.NEW_DASHBOARD_ITEM ) { - setDrawerState([emptySubscriptionSettingItem]); toggleDrawer({ type: DRAWER_TYPES.OFF, props: undefined }); } }, [createDashboard.isSuccess, drawer.type]); const cancelDashboardItem = () => { - setDrawerState([emptySubscriptionSettingItem]); toggleDrawer({ type: DRAWER_TYPES.OFF, props: undefined }); + ui.dispatchDashboardUpdate({ + type: DASHBOARD_UPDATE_ACTIONS.RESET_TO_DEFAULT, + }); }; + return ( { {drawer.type === DRAWER_TYPES.NEW_DASHBOARD && "New dashboard"} {drawer.type === DRAWER_TYPES.NEW_DASHBOARD_ITEM && - "New dashboard element"} + "Edit dashboard"} @@ -413,14 +354,10 @@ const OverlayProvider = ({ children }) => { )} {drawer.type === DRAWER_TYPES.NEW_DASHBOARD_ITEM && ( - } - > + }> )} @@ -430,7 +367,6 @@ const OverlayProvider = ({ children }) => { variant="outline" mr={3} onClick={() => { - console.log("cancel click on drawer", drawer.type); if (drawer.type === DRAWER_TYPES.NEW_DASHBOARD) { toggleAlert(() => finishNewDashboard()); } diff --git a/frontend/src/core/providers/UIProvider/index.js b/frontend/src/core/providers/UIProvider/index.js index 58f2541f..640a1aca 100644 --- a/frontend/src/core/providers/UIProvider/index.js +++ b/frontend/src/core/providers/UIProvider/index.js @@ -4,13 +4,18 @@ import React, { useEffect, useCallback, useLayoutEffect, + useReducer, } from "react"; import { useBreakpointValue } from "@chakra-ui/react"; -import { useStorage, useQuery, useRouter } from "../../hooks"; +import { useStorage, useQuery, useRouter, useDashboard } from "../../hooks"; import UIContext from "./context"; import UserContext from "../UserProvider/context"; import { v4 as uuid4 } from "uuid"; import { PreferencesService } from "../../services"; +import { + DASHBOARD_CONFIGURE_SETTING_SCOPES, + DASHBOARD_UPDATE_ACTIONS, +} from "../../constants"; const onboardingSteps = [ { @@ -29,6 +34,8 @@ const onboardingSteps = [ const UIProvider = ({ children }) => { const router = useRouter(); + const { dashboardId } = router.params; + const { dashboardCache } = useDashboard(dashboardId); const { user, isInit } = useContext(UserContext); const isMobileView = useBreakpointValue({ base: true, @@ -274,12 +281,187 @@ const UIProvider = ({ children }) => { onboardingRedirectCheckPassed, ]); - //***************Overlay's states ************************/ - // const [newDashboardForm, setNewDashboardForm] = useStorage( - // window.sessionStorage, - // "newDashboardForm", - // null - // ); + //***************New chart item 's state ************************/ + const dashboardUpdateReducer = useCallback( + (state, command) => { + let newState = undefined; + let index = -1; + switch (command.type) { + case DASHBOARD_UPDATE_ACTIONS.RESET_TO_DEFAULT: + newState = { ...state }; + if (!dashboardCache.isLoading && dashboardCache.data?.resource_data) { + newState = { ...dashboardCache.data.resource_data }; + } + return newState; + case DASHBOARD_UPDATE_ACTIONS.RENAME_DASHBOARD: + return { ...state, name: command.payload }; + case DASHBOARD_UPDATE_ACTIONS.OVERRIDE_DASHBOARD: + return { ...command.payload }; + case DASHBOARD_UPDATE_ACTIONS.APPEND_SUBSCRIPTION: + newState = { ...state }; + + if ( + state.subscription_settings.every( + (subscriptionSetting) => + subscriptionSetting.subscription_id !== + command.payload.subscriptionId + ) + ) { + newState.subscription_settings.push({ + subscription_id: command.payload.subscriptionId, + all_methods: false, + all_events: false, + generic: [], + methods: [], + events: [], + }); + } + return newState; + case DASHBOARD_UPDATE_ACTIONS.OVERRIDE_SUBSCRIPTION: + newState = { ...state }; + index = + dashboardCache.data?.resource_data?.subscription_settings?.findIndex( + (subscriptionSetting) => + subscriptionSetting.subscription_id === + command.payload.subscriptionId + ); + + newState.subscription_settings[command.payload.index] = + index !== -1 + ? JSON.parse( + JSON.stringify( + dashboardCache.data?.resource_data?.subscription_settings[ + index + ] + ) + ) + : { + subscription_id: command.payload.subscriptionId, + all_methods: false, + all_events: false, + generic: [], + methods: [], + events: [], + }; + return newState; + case DASHBOARD_UPDATE_ACTIONS.DROP_SUBSCRIPTION: + newState = { ...state }; + newState.subscription_settings = + newState.subscription_settings.filter( + (subscriptionSetting) => + subscriptionSetting.subscription_id !== + command.payload.subscriptionId + ); + return newState; + case DASHBOARD_UPDATE_ACTIONS.APPEND_METRIC: + switch (command.scope) { + case DASHBOARD_CONFIGURE_SETTING_SCOPES.METRICS_ARRAY: + newState = { ...state }; + index = state.subscription_settings.findIndex( + (subscriptionSetting) => + subscriptionSetting.subscription_id === + command.payload.subscriptionId + ); + if (index !== -1) { + newState.subscription_settings[index][ + command.payload.propertyName + ] = [...command.payload.data]; + } + return newState; + + case DASHBOARD_CONFIGURE_SETTING_SCOPES.METRIC_NAME: + newState = { ...state }; + index = state.subscription_settings.findIndex( + (subscriptionSetting) => + subscriptionSetting.subscription_id === + command.payload.subscriptionId + ); + if (index !== -1) { + if ( + !newState.subscription_settings[index][ + command.payload.propertyName + ].some((method) => method.name === command.payload.data.name) + ) { + newState.subscription_settings[index][ + command.payload.propertyName + ].push({ + name: command.payload.data, + }); + } + } + return newState; + + default: + throw new Error(); + } + case DASHBOARD_UPDATE_ACTIONS.DROP_METRIC: + switch (command.scope) { + case DASHBOARD_CONFIGURE_SETTING_SCOPES.METRICS_ARRAY: + newState = { ...state }; + index = state.subscription_settings.findIndex( + (subscriptionSetting) => + subscriptionSetting.subscription_id === + command.payload.subscriptionId + ); + newState.subscription_settings[index][ + command.payload.propertyName + ] = []; + return newState; + + case DASHBOARD_CONFIGURE_SETTING_SCOPES.METRIC_NAME: + newState = { ...state }; + index = state.subscription_settings.findIndex( + (subscriptionSetting) => + subscriptionSetting.subscription_id === + command.payload.subscriptionId + ); + newState.subscription_settings[index][ + command.payload.propertyName + ] = newState.subscription_settings[index][ + command.payload.propertyName + ].filter((metric) => metric.name !== command.payload.data); + return newState; + + default: + throw new Error(`unhandled case command.scope: ${command.scope}`); + } + default: + throw new Error(`unhandled case command.type: ${command.type}`); + } + }, + [dashboardCache.data, dashboardCache.isLoading] + ); + const [dashboardUpdate, dispatchDashboardUpdate] = useReducer( + dashboardUpdateReducer, + { + name: undefined, + subscription_settings: [ + { + subscription_id: undefined, + all_methods: false, + all_events: false, + generic: [], + methods: [], + events: [], + }, + ], + } + ); + + useEffect(() => { + if (!dashboardCache.isLoading && dashboardCache.data?.resource_data) { + const dashboardCachedData = JSON.parse( + JSON.stringify({ ...dashboardCache.data.resource_data }) + ); + dispatchDashboardUpdate({ + type: DASHBOARD_UPDATE_ACTIONS.OVERRIDE_DASHBOARD, + payload: dashboardCachedData, + }); + } + }, [dashboardId, dashboardCache.isLoading, dashboardCache.data]); + + //***************New dashboard state ************************/ + const [newDashboardForm, setNewDashboardForm] = useState(); return ( @@ -318,6 +500,8 @@ const UIProvider = ({ children }) => { setLoggingIn, newDashboardForm, setNewDashboardForm, + dashboardUpdate, + dispatchDashboardUpdate, }} > {children} diff --git a/frontend/src/core/services/subscriptions.service.js b/frontend/src/core/services/subscriptions.service.js index 0b2c8872..c32fd601 100644 --- a/frontend/src/core/services/subscriptions.service.js +++ b/frontend/src/core/services/subscriptions.service.js @@ -74,3 +74,9 @@ export const getSubscriptionABI = (id) => () => { url: `${API}/subscriptions/${id}/abi`, }); }; + +export const getSubscription = (id) => + http({ + method: "GET", + url: `${API}/subscriptions/${id}`, + }); diff --git a/frontend/src/core/utils/massageAbi.js b/frontend/src/core/utils/massageAbi.js deleted file mode 100644 index 1e4b33a7..00000000 --- a/frontend/src/core/utils/massageAbi.js +++ /dev/null @@ -1,74 +0,0 @@ -const massageAbi = (abi) => { - const coder = require("web3-eth-abi"); - const getSignature = (item) => { - if (item.type === `function`) { - const retval = coder.encodeFunctionSignature(item); - return retval; - } else if (item.type === `event`) { - const retval = coder.encodeEventSignature(item); - return retval; - } - console.error("item passed to getKay was neither fn neither event!"); - }; - const filtered = abi.filter( - (item) => item.type === `event` || item.type === `function` - ); - - const signed = filtered.map((item) => { - item.signature = getSignature(item); - return item; - }); - const events = []; - const functions = []; - - signed.forEach((item) => { - if (item.type === "event") { - events.push(item); - } - if (item.type === "function") { - functions.push(item); - } - }); - - const keyEv = {}; - const keyFn = {}; - const eventsObj = - events.length > 0 - ? events.reduce( - (acc, curr) => ((acc[curr.signature] = { ...curr }), keyEv) - ) - : []; - const fnsObj = - functions.length > 0 - ? functions.reduce( - (acc, curr) => ((acc[curr.signature] = { ...curr }), keyFn) - ) - : 0; - - return { fnsObj, eventsObj }; -}; - -export const emptySubscriptionSettingItem = { - all_methods: false, - all_events: false, - subscription: undefined, - generic: { - transactions_in: { - value: "transactions_in", - name: "transactions in", - checked: false, - }, - transactions_out: { - value: "transactions_out", - name: "transactions out", - checked: false, - }, - value_in: { value: "value_in", name: "value in", checked: false }, - value_out: { value: "value_out", name: "value out", checked: false }, - balance: { value: "balance", name: "balance", checked: false }, - }, - events: {}, - methods: {}, -}; - -export default massageAbi;