mirror of
https://github.com/prymitive/karma
synced 2026-05-07 03:26:52 +00:00
fix(ui): rewrite Fetcher with hooks
This commit is contained in:
committed by
Łukasz Mierzwa
parent
071a8ec06d
commit
ca7a8fceaf
@@ -1,136 +1,140 @@
|
||||
import React, { Component } from "react";
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
import { reaction } from "mobx";
|
||||
import { useObserver } from "mobx-react";
|
||||
|
||||
import moment from "moment";
|
||||
|
||||
import { AlertStore, AlertStoreStatuses } from "Stores/AlertStore";
|
||||
import { Settings } from "Stores/Settings";
|
||||
|
||||
const Fetcher = observer(
|
||||
class Fetcher extends Component {
|
||||
static propTypes = {
|
||||
alertStore: PropTypes.instanceOf(AlertStore).isRequired,
|
||||
settingsStore: PropTypes.instanceOf(Settings).isRequired,
|
||||
const Fetcher = ({ alertStore, settingsStore }) => {
|
||||
const timer = useRef(null);
|
||||
|
||||
const getSortSettings = () => {
|
||||
let sortSettings = {
|
||||
useDefaults: false,
|
||||
sortOrder: "",
|
||||
sortLabel: "",
|
||||
sortReverse: "",
|
||||
};
|
||||
|
||||
getSortSettings = () => {
|
||||
const { settingsStore } = this.props;
|
||||
|
||||
let sortSettings = {
|
||||
useDefaults: false,
|
||||
sortOrder: "",
|
||||
sortLabel: "",
|
||||
sortReverse: "",
|
||||
};
|
||||
|
||||
sortSettings.useDefaults =
|
||||
settingsStore.gridConfig.config.sortOrder ===
|
||||
settingsStore.gridConfig.options.default.value;
|
||||
|
||||
if (sortSettings.useDefaults === true) {
|
||||
return sortSettings;
|
||||
}
|
||||
|
||||
sortSettings.sortOrder = settingsStore.gridConfig.config.sortOrder;
|
||||
|
||||
// don't sort if sorting is disabled
|
||||
if (
|
||||
sortSettings.sortOrder ===
|
||||
settingsStore.gridConfig.options.disabled.value
|
||||
)
|
||||
return sortSettings;
|
||||
|
||||
sortSettings.sortReverse =
|
||||
settingsStore.gridConfig.config.reverseSort !== null
|
||||
? settingsStore.gridConfig.config.reverseSort === true
|
||||
? "1"
|
||||
: "0"
|
||||
: "";
|
||||
|
||||
if (settingsStore.gridConfig.config.sortLabel !== null) {
|
||||
sortSettings.sortLabel = settingsStore.gridConfig.config.sortLabel;
|
||||
}
|
||||
sortSettings.useDefaults =
|
||||
settingsStore.gridConfig.config.sortOrder ===
|
||||
settingsStore.gridConfig.options.default.value;
|
||||
|
||||
if (sortSettings.useDefaults === true) {
|
||||
return sortSettings;
|
||||
};
|
||||
|
||||
fetchIfIdle = () => {
|
||||
const { alertStore, settingsStore } = this.props;
|
||||
|
||||
const nextTick = moment(alertStore.status.lastUpdateAt).add(
|
||||
settingsStore.fetchConfig.config.interval,
|
||||
"seconds"
|
||||
);
|
||||
|
||||
const pastDeadline = moment().isSameOrAfter(nextTick);
|
||||
|
||||
const status = alertStore.status.value.toString();
|
||||
const updateInProgress =
|
||||
status === AlertStoreStatuses.Fetching.toString() ||
|
||||
status === AlertStoreStatuses.Processing.toString();
|
||||
|
||||
if (pastDeadline && !updateInProgress && !alertStore.status.paused) {
|
||||
this.callFetch();
|
||||
}
|
||||
};
|
||||
|
||||
timerTick = () => {
|
||||
window.requestAnimationFrame(this.fetchIfIdle);
|
||||
};
|
||||
|
||||
callFetch = () => {
|
||||
const { alertStore, settingsStore } = this.props;
|
||||
|
||||
const sortSettings = this.getSortSettings();
|
||||
alertStore.fetchWithThrottle(
|
||||
settingsStore.multiGridConfig.config.gridLabel,
|
||||
settingsStore.multiGridConfig.config.gridSortReverse,
|
||||
sortSettings.sortOrder,
|
||||
sortSettings.sortLabel,
|
||||
sortSettings.sortReverse
|
||||
);
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
// start first fetch once the browser is done doing busy loading
|
||||
window.requestAnimationFrame(this.fetchIfIdle);
|
||||
this.timer = setInterval(this.timerTick, 1000);
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
const { alertStore } = this.props;
|
||||
sortSettings.sortOrder = settingsStore.gridConfig.config.sortOrder;
|
||||
|
||||
if (!alertStore.status.paused) {
|
||||
this.callFetch();
|
||||
}
|
||||
// don't sort if sorting is disabled
|
||||
if (
|
||||
sortSettings.sortOrder === settingsStore.gridConfig.options.disabled.value
|
||||
)
|
||||
return sortSettings;
|
||||
|
||||
sortSettings.sortReverse =
|
||||
settingsStore.gridConfig.config.reverseSort !== null
|
||||
? settingsStore.gridConfig.config.reverseSort === true
|
||||
? "1"
|
||||
: "0"
|
||||
: "";
|
||||
|
||||
if (settingsStore.gridConfig.config.sortLabel !== null) {
|
||||
sortSettings.sortLabel = settingsStore.gridConfig.config.sortLabel;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
return sortSettings;
|
||||
};
|
||||
|
||||
const fetchIfIdle = () => {
|
||||
const nextTick = moment(alertStore.status.lastUpdateAt).add(
|
||||
settingsStore.fetchConfig.config.interval,
|
||||
"seconds"
|
||||
);
|
||||
|
||||
const pastDeadline = moment().isSameOrAfter(nextTick);
|
||||
|
||||
const status = alertStore.status.value.toString();
|
||||
const updateInProgress =
|
||||
status === AlertStoreStatuses.Fetching.toString() ||
|
||||
status === AlertStoreStatuses.Processing.toString();
|
||||
|
||||
if (pastDeadline && !updateInProgress && !alertStore.status.paused) {
|
||||
callFetch();
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { alertStore, settingsStore } = this.props;
|
||||
const callFetch = () => {
|
||||
if (alertStore.status.paused) return;
|
||||
|
||||
return (
|
||||
// data-filters is there to register filters for observation in mobx
|
||||
<span
|
||||
data-filters={alertStore.filters.values.map((f) => f.raw).join(" ")}
|
||||
data-interval={settingsStore.fetchConfig.config.interval}
|
||||
data-multigrid-label={settingsStore.multiGridConfig.config.gridLabel}
|
||||
data-multigrid-sort-reverse={
|
||||
settingsStore.multiGridConfig.config.gridSortReverse
|
||||
const sortSettings = getSortSettings();
|
||||
alertStore.fetchWithThrottle(
|
||||
settingsStore.multiGridConfig.config.gridLabel,
|
||||
settingsStore.multiGridConfig.config.gridSortReverse,
|
||||
sortSettings.sortOrder,
|
||||
sortSettings.sortLabel,
|
||||
sortSettings.sortReverse
|
||||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
return () => clearInterval(timer.current);
|
||||
}, []);
|
||||
|
||||
useEffect(
|
||||
() =>
|
||||
reaction(
|
||||
() => alertStore.filters.values.map((f) => f.raw).join(" "),
|
||||
() => {
|
||||
callFetch();
|
||||
},
|
||||
{ fireImmediately: true }
|
||||
),
|
||||
[] // eslint-disable-line react-hooks/exhaustive-deps
|
||||
);
|
||||
|
||||
useEffect(
|
||||
() =>
|
||||
reaction(
|
||||
() => alertStore.status.paused,
|
||||
(paused) => {
|
||||
if (paused) {
|
||||
clearInterval(timer.current);
|
||||
timer.current = null;
|
||||
} else {
|
||||
timer.current = setInterval(
|
||||
() => window.requestAnimationFrame(fetchIfIdle),
|
||||
1000
|
||||
);
|
||||
}
|
||||
data-grid-sort-order={settingsStore.gridConfig.config.sortOrder}
|
||||
data-grid-sort-label={settingsStore.gridConfig.config.sortLabel}
|
||||
data-grid-sort-reverse={settingsStore.gridConfig.config.reverseSort}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
{ fireImmediately: true }
|
||||
),
|
||||
[] // eslint-disable-line react-hooks/exhaustive-deps
|
||||
);
|
||||
|
||||
return useObserver(() => (
|
||||
// data-filters is there to register filters for observation in mobx
|
||||
<span
|
||||
data-filters={alertStore.filters.values.map((f) => f.raw).join(" ")}
|
||||
data-interval={settingsStore.fetchConfig.config.interval}
|
||||
data-multigrid-label={settingsStore.multiGridConfig.config.gridLabel}
|
||||
data-multigrid-sort-reverse={
|
||||
settingsStore.multiGridConfig.config.gridSortReverse
|
||||
}
|
||||
data-grid-sort-order={settingsStore.gridConfig.config.sortOrder}
|
||||
data-grid-sort-label={settingsStore.gridConfig.config.sortLabel}
|
||||
data-grid-sort-reverse={settingsStore.gridConfig.config.reverseSort}
|
||||
/>
|
||||
));
|
||||
};
|
||||
Fetcher.propTypes = {
|
||||
alertStore: PropTypes.instanceOf(AlertStore).isRequired,
|
||||
settingsStore: PropTypes.instanceOf(Settings).isRequired,
|
||||
};
|
||||
|
||||
export { Fetcher };
|
||||
|
||||
@@ -87,6 +87,10 @@ describe("<Fetcher />", () => {
|
||||
MountedFetcher();
|
||||
expect(fetchSpy).toHaveBeenCalledTimes(1);
|
||||
|
||||
advanceBy(3 * 1000);
|
||||
jest.runOnlyPendingTimers();
|
||||
expect(fetchSpy).toHaveBeenCalledTimes(2);
|
||||
|
||||
settingsStore.fetchConfig.config.interval = 600;
|
||||
|
||||
advanceBy(3 * 1000);
|
||||
@@ -120,18 +124,12 @@ describe("<Fetcher />", () => {
|
||||
expect(fetchSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("calls alertStore.fetchWithThrottle again after interval change", () => {
|
||||
const fetchSpy = jest.spyOn(alertStore, "fetchWithThrottle");
|
||||
MountedFetcher();
|
||||
settingsStore.fetchConfig.config.interval = 60;
|
||||
expect(fetchSpy).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it("calls alertStore.fetchWithThrottle again after filter change", () => {
|
||||
MockEmptyAPIResponseWithoutFilters();
|
||||
const fetchSpy = jest.spyOn(alertStore, "fetchWithThrottle");
|
||||
MountedFetcher();
|
||||
const tree = MountedFetcher();
|
||||
alertStore.filters.values = [];
|
||||
tree.setProps({});
|
||||
expect(fetchSpy).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
@@ -301,6 +299,7 @@ describe("<Fetcher />", () => {
|
||||
alertStore.status.resume();
|
||||
settingsStore.gridConfig.config.reverseSort = !settingsStore.gridConfig
|
||||
.config.reverseSort;
|
||||
jest.runOnlyPendingTimers();
|
||||
expect(fetchSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user