Skip to content

Commit 369fe1b

Browse files
authored
Merge pull request #146 from kaleido-io/bugfixes
Bugfixes
2 parents 1748880 + 6738384 commit 369fe1b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+556
-684
lines changed

src/App.tsx

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import {
3131
} from './components/Snackbar/MessageSnackbar';
3232
import { ApplicationContext } from './contexts/ApplicationContext';
3333
import { SnackbarContext } from './contexts/SnackbarContext';
34-
import { INamespace, IStatus, NAMESPACES_PATH } from './interfaces';
34+
import { FF_EVENTS, INamespace, IStatus, NAMESPACES_PATH } from './interfaces';
3535
import { FF_Paths } from './interfaces/constants';
3636
import { themeOptions } from './theme';
3737
import { fetchWithCredentials, summarizeFetchError } from './utils';
@@ -50,14 +50,18 @@ const App: React.FC = () => {
5050
const [selectedNamespace, setSelectedNamespace] = useState('');
5151
const ws = useRef<ReconnectingWebSocket | null>(null);
5252
const [identity, setIdentity] = useState('');
53-
const [lastEvent, setLastEvent] = useState<MessageEvent>();
5453
const [message, setMessage] = useState('');
5554
const [messageType, setMessageType] = useState<SnackbarMessageType>('error');
5655
const [orgID, setOrgID] = useState('');
5756
const [orgName, setOrgName] = useState('');
5857
const [nodeID, setNodeID] = useState('');
5958
const [nodeName, setNodeName] = useState('');
6059
const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws';
60+
// Event Context
61+
const [newEvents, setNewEvents] = useState<FF_EVENTS[]>([]);
62+
const [lastRefreshTime, setLastRefresh] = useState<string>(
63+
new Date().toISOString()
64+
);
6165

6266
const { pathname: currentPath } = useMemo(() => {
6367
return window.location;
@@ -116,7 +120,10 @@ const App: React.FC = () => {
116120
);
117121
ws.current.onmessage = (event: any) => {
118122
const eventData = JSON.parse(event.data);
119-
setLastEvent(eventData);
123+
const eventType: FF_EVENTS = eventData.type;
124+
if (Object.values(FF_EVENTS).includes(eventType)) {
125+
setNewEvents((existing) => [eventType, ...existing]);
126+
}
120127
};
121128

122129
return () => {
@@ -134,6 +141,11 @@ const App: React.FC = () => {
134141
});
135142
};
136143

144+
const clearNewEvents = () => {
145+
setNewEvents([]);
146+
setLastRefresh(new Date().toISOString());
147+
};
148+
137149
if (initialized) {
138150
if (initError) {
139151
// figure out what to display
@@ -158,8 +170,9 @@ const App: React.FC = () => {
158170
nodeID,
159171
nodeName,
160172
identity,
161-
lastEvent,
162-
setLastEvent,
173+
newEvents,
174+
clearNewEvents,
175+
lastRefreshTime,
163176
}}
164177
>
165178
<SnackbarContext.Provider

src/components/AppWrapper.tsx

Lines changed: 79 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ import { DateFilterContext } from '../contexts/DateFilterContext';
1111
import { FilterContext } from '../contexts/FilterContext';
1212
import { SlideContext } from '../contexts/SlideContext';
1313
import {
14-
CreatedFilterOptions,
15-
ICreatedTimeFilter,
14+
ITimeFilterObject,
1615
NAMESPACES_PATH,
16+
TimeFilterEnum,
1717
} from '../interfaces';
18-
import { getCreatedTimeFilter, isValidUUID } from '../utils';
18+
import { getTimeFilterObject, isValidUUID } from '../utils';
1919
import { Navigation, NAV_WIDTH } from './Navigation/Navigation';
2020

2121
const Main = styled('main')({
@@ -38,7 +38,7 @@ export const SLIDE_QUERY_KEY = 'slide';
3838
export const TIME_QUERY_KEY = 'time';
3939

4040
export const AppWrapper: React.FC = () => {
41-
const { pathname } = useLocation();
41+
const { pathname, search } = useLocation();
4242
const { selectedNamespace } = useContext(ApplicationContext);
4343
const [filterAnchor, setFilterAnchor] = useState<HTMLButtonElement | null>(
4444
null
@@ -47,12 +47,9 @@ export const AppWrapper: React.FC = () => {
4747
// Table filters
4848
const [filterArray, setFilterArray] = useState<string[]>([]);
4949
const [filterString, setFilterString] = useState('');
50-
// Slide filters
51-
const [slideQuery, setSlideQuery] = useState<string | null>(null);
50+
const [slideID, setSlideID] = useState<string | null>(null);
5251
// Date filter
53-
const [dateFilter, setDateFilter] = useState<ICreatedTimeFilter>(
54-
getCreatedTimeFilter('24hours')
55-
);
52+
const [dateFilter, setDateFilter] = useState<ITimeFilterObject>();
5653

5754
if (pathname === '/') {
5855
return (
@@ -63,28 +60,68 @@ export const AppWrapper: React.FC = () => {
6360
);
6461
}
6562

66-
// Table Filters
6763
useEffect(() => {
68-
const filterArray = searchParams.getAll(FILTERS_QUERY_KEY);
69-
setFilterArray(filterArray);
70-
setFilterString(`&${filterArray.join('&')}`);
71-
}, [pathname]);
64+
initializeTimeSearchParams();
65+
initializeSlideSearchParams();
66+
initializeTableFilterSearchParams();
67+
}, [pathname, search]);
7268

73-
// Slide ID
74-
useEffect(() => {
75-
const slideQuery = searchParams.get(SLIDE_QUERY_KEY);
76-
slideQuery !== null && setSlideQuery(slideQuery);
77-
}, [pathname, setSearchParams]);
69+
const initializeTimeSearchParams = () => {
70+
// If date has already been set
71+
if (
72+
dateFilter?.filterShortString &&
73+
dateFilter?.filterShortString in TimeFilterEnum
74+
) {
75+
setTimeSearchParam(dateFilter.filterShortString);
76+
return;
77+
}
78+
// If time param is invalid
79+
const existingTimeParam = searchParams.get(TIME_QUERY_KEY);
80+
if (existingTimeParam === null || !(existingTimeParam in TimeFilterEnum)) {
81+
setTimeSearchParam(TimeFilterEnum['24hours']);
82+
} else {
83+
// Set filter string for components to consume
84+
setDateFilter(getTimeFilterObject(existingTimeParam as TimeFilterEnum));
85+
}
86+
};
7887

79-
// Time string
80-
useEffect(() => {
81-
const timeString = searchParams.get(TIME_QUERY_KEY) as CreatedFilterOptions;
82-
if (timeString === null) {
83-
addDateToParams(dateFilter.filterShortString);
88+
const setTimeSearchParam = (timeFilter: TimeFilterEnum) => {
89+
searchParams.set(TIME_QUERY_KEY, timeFilter);
90+
setSearchParams(searchParams);
91+
if (
92+
getTimeFilterObject(timeFilter).filterShortString !==
93+
dateFilter?.filterShortString
94+
) {
95+
setDateFilter(getTimeFilterObject(timeFilter));
96+
}
97+
};
98+
99+
const initializeSlideSearchParams = () => {
100+
setSlideID(null);
101+
const existingSlideParam = searchParams.get(SLIDE_QUERY_KEY);
102+
if (existingSlideParam === null || !isValidUUID(existingSlideParam)) {
103+
setSlideSearchParam(null);
84104
} else {
85-
setDateFilter(getCreatedTimeFilter(timeString));
105+
setSlideSearchParam(existingSlideParam);
86106
}
87-
}, [pathname]);
107+
};
108+
109+
const setSlideSearchParam = (slideID: string | null) => {
110+
if (slideID === null) {
111+
searchParams.delete(SLIDE_QUERY_KEY);
112+
setSearchParams(searchParams);
113+
} else if (isValidUUID(slideID)) {
114+
searchParams.set(SLIDE_QUERY_KEY, slideID);
115+
setSearchParams(searchParams);
116+
setSlideID(slideID);
117+
}
118+
};
119+
120+
const initializeTableFilterSearchParams = () => {
121+
const existingFilterArray = searchParams.getAll(FILTERS_QUERY_KEY);
122+
setFilterArray(existingFilterArray);
123+
setFilterString(`&${existingFilterArray.join('&')}`);
124+
};
88125

89126
const addFilterToParams = (filter: string) => {
90127
searchParams.append(FILTERS_QUERY_KEY, filter);
@@ -101,21 +138,22 @@ export const AppWrapper: React.FC = () => {
101138
setFilterString('');
102139
};
103140

104-
const addSlideToParams = (slideID: string | undefined) => {
105-
if (slideID === undefined) {
106-
searchParams.delete(SLIDE_QUERY_KEY);
107-
} else {
108-
isValidUUID(slideID) && searchParams.set(SLIDE_QUERY_KEY, slideID);
141+
const removeFilter = (filterToRemove: string) => {
142+
const filters = searchParams.getAll(FILTERS_QUERY_KEY);
143+
searchParams.delete(FILTERS_QUERY_KEY);
144+
if (filters.length > 0) {
145+
filters.forEach((f) => {
146+
if (f !== filterToRemove) {
147+
searchParams.append(FILTERS_QUERY_KEY, f);
148+
}
149+
});
109150
setSearchParams(searchParams);
151+
const filterArray = searchParams.getAll(FILTERS_QUERY_KEY);
152+
setFilterArray(filterArray);
153+
setFilterString(`&${filterArray.join('&')}`);
110154
}
111155
};
112156

113-
const addDateToParams = (timeFilterString: CreatedFilterOptions) => {
114-
searchParams.set(TIME_QUERY_KEY, timeFilterString);
115-
setSearchParams(searchParams);
116-
setDateFilter(getCreatedTimeFilter(timeFilterString));
117-
};
118-
119157
return (
120158
<RootDiv>
121159
<FilterContext.Provider
@@ -125,20 +163,21 @@ export const AppWrapper: React.FC = () => {
125163
filterString,
126164
filterArray,
127165
addFilterToParams,
166+
removeFilter,
128167
clearAllFilters,
129168
}}
130169
>
131170
<DateFilterContext.Provider
132171
value={{
133172
searchParams,
134173
dateFilter,
135-
addDateToParams,
174+
setTimeSearchParam,
136175
}}
137176
>
138177
<SlideContext.Provider
139178
value={{
140-
slideQuery,
141-
addSlideToParams,
179+
slideID,
180+
setSlideSearchParam,
142181
}}
143182
>
144183
<Main>

src/components/Cards/EventCards/BaseCard.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ interface Props {
3333
color?: string;
3434
onClick?: () => void;
3535
link?: string;
36-
linkState?: any;
3736
}
3837

3938
export const BaseCard: React.FC<Props> = ({
@@ -44,7 +43,6 @@ export const BaseCard: React.FC<Props> = ({
4443
color,
4544
onClick,
4645
link,
47-
linkState,
4846
}) => {
4947
const navigate = useNavigate();
5048

@@ -106,7 +104,7 @@ export const BaseCard: React.FC<Props> = ({
106104
{link && (
107105
<IconButton
108106
size="small"
109-
onClick={() => navigate(link, linkState ?? undefined)}
107+
onClick={() => navigate(link)}
110108
sx={{
111109
elevation: 0,
112110
backgroundColor: 'background.paper',

src/components/Cards/EventCards/EventCardWrapper.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ export const EventCardWrapper = ({
2323
onHandleViewEvent,
2424
onHandleViewTx,
2525
link,
26-
linkState,
2726
}: Props) => {
2827
const { t } = useTranslation();
2928

@@ -45,7 +44,6 @@ export const EventCardWrapper = ({
4544
status={<HashPopover address={event.id} shortHash paper />}
4645
color={FF_EVENTS_CATEGORY_MAP[event.type]?.color}
4746
link={link}
48-
linkState={linkState}
4947
/>
5048
</>
5149
);

src/components/Charts/Histogram.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ interface Props {
2121
indexBy: string;
2222
isEmpty: boolean;
2323
keys: string[];
24+
isLoading: boolean;
2425
}
2526

2627
export const Histogram: React.FC<Props> = ({
@@ -32,6 +33,7 @@ export const Histogram: React.FC<Props> = ({
3233
indexBy,
3334
isEmpty,
3435
keys,
36+
isLoading,
3537
}) => {
3638
const [xAxisValues, setXAxisValues] = useState<(string | number)[]>([]);
3739

@@ -51,7 +53,7 @@ export const Histogram: React.FC<Props> = ({
5153
backgroundColor: 'background.paper',
5254
}}
5355
>
54-
{!data ? (
56+
{!data || isLoading ? (
5557
<FFCircleLoader height="100%" color="warning"></FFCircleLoader>
5658
) : isEmpty ? (
5759
<EmptyStateCard text={emptyText}></EmptyStateCard>

src/components/Filters/FilterButton.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ interface Props {
2626

2727
export const FilterButton: React.FC<Props> = ({ onSetFilterAnchor }) => {
2828
const { t } = useTranslation();
29-
const { clearAllFilters, filterArray } = useContext(FilterContext);
29+
const { clearAllFilters, filterArray, removeFilter } =
30+
useContext(FilterContext);
3031

3132
const handleOpenFilter = (event: React.MouseEvent<HTMLButtonElement>) => {
3233
onSetFilterAnchor(event);
@@ -51,11 +52,7 @@ export const FilterButton: React.FC<Props> = ({ onSetFilterAnchor }) => {
5152
<Grid container alignItems="center" justifyContent="flex-end">
5253
{filterArray.map((filter, index) => (
5354
<Grid key={`${filter}${index}`} item>
54-
<Chip
55-
// TODO: Add back
56-
// onDelete={() => handleRemoveFilter(filter)}
57-
label={filter}
58-
/>
55+
<Chip onDelete={() => removeFilter(filter)} label={filter} />
5956
</Grid>
6057
))}
6158
<Grid item>

src/components/Header.tsx

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ interface Props {
3333
title: string | JSX.Element;
3434
subtitle: string;
3535
onRefresh?: any;
36-
numNewEvents?: number;
37-
showNumNewEvents?: boolean;
36+
showRefreshBtn?: boolean;
3837
noDateFilter?: boolean;
3938
noNsFilter?: boolean;
4039
}
@@ -43,8 +42,7 @@ export const Header: React.FC<Props> = ({
4342
title,
4443
subtitle,
4544
onRefresh,
46-
numNewEvents = 0,
47-
showNumNewEvents = false,
45+
showRefreshBtn = false,
4846
noDateFilter = false,
4947
noNsFilter = false,
5048
}) => {
@@ -88,17 +86,15 @@ export const Header: React.FC<Props> = ({
8886
alignItems="center"
8987
>
9088
<Grid item pr={1}>
91-
{numNewEvents > 0 && (
89+
{showRefreshBtn && (
9290
<Button
9391
onClick={onRefresh}
9492
variant="contained"
9593
color="info"
9694
sx={{ borderRadius: '16px' }}
9795
>
9896
<Typography sx={{ fontSize: '14px' }}>
99-
{`${t('refresh')}${
100-
showNumNewEvents ? ` (${numNewEvents})` : ''
101-
}`}
97+
{t('refresh')}
10298
</Typography>
10399
</Button>
104100
)}

0 commit comments

Comments
 (0)