mirror of
https://github.com/prymitive/karma
synced 2026-05-07 03:26:52 +00:00
fix(ui): replace NavBarSlide animation with react-reveal
This commit is contained in:
committed by
Łukasz Mierzwa
parent
7eaa7cbf34
commit
c1d6b894ca
@@ -1,22 +0,0 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { CSSTransition } from "react-transition-group";
|
||||
|
||||
const NavBarSlide = ({ children, duration, ...props }) => (
|
||||
<CSSTransition
|
||||
classNames="components-animation-navbar"
|
||||
timeout={500}
|
||||
appear={false}
|
||||
enter={true}
|
||||
exit={true}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</CSSTransition>
|
||||
);
|
||||
NavBarSlide.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
||||
export { NavBarSlide };
|
||||
@@ -8,14 +8,16 @@ import ReactResizeDetector from "react-resize-detector";
|
||||
|
||||
import IdleTimer from "react-idle-timer";
|
||||
|
||||
import { Fade } from "react-reveal";
|
||||
|
||||
import { AlertStore } from "Stores/AlertStore";
|
||||
import { Settings } from "Stores/Settings";
|
||||
import { SilenceFormStore } from "Stores/SilenceFormStore";
|
||||
import { IsMobile } from "Common/Device";
|
||||
import { NavBarSlide } from "Components/Animations/NavBarSlide";
|
||||
import { OverviewModal } from "Components/OverviewModal";
|
||||
import { MainModal } from "Components/MainModal";
|
||||
import { SilenceModal } from "Components/SilenceModal";
|
||||
import { ThemeContext } from "Components/Theme";
|
||||
import { FetchIndicator } from "./FetchIndicator";
|
||||
import { FilterInput } from "./FilterInput";
|
||||
|
||||
@@ -38,6 +40,7 @@ const NavBar = observer(
|
||||
super(props);
|
||||
|
||||
this.idleTimer = null;
|
||||
this.animationTimer = null;
|
||||
|
||||
this.activityStatus = observable(
|
||||
{
|
||||
@@ -65,7 +68,10 @@ const NavBar = observer(
|
||||
);
|
||||
|
||||
this.activityStatusReaction = reaction(
|
||||
() => props.alertStore.status.paused,
|
||||
() =>
|
||||
props.alertStore.status.paused ||
|
||||
props.alertStore.filters.values.filter((f) => f.applied === false)
|
||||
.length > 0,
|
||||
(paused) =>
|
||||
paused
|
||||
? this.idleTimer && this.idleTimer.pause()
|
||||
@@ -93,14 +99,32 @@ const NavBar = observer(
|
||||
document.body.style.paddingTop = `${paddingTop}px`;
|
||||
};
|
||||
|
||||
onHide = () => {
|
||||
this.activityStatus.hide();
|
||||
this.updateBodyPaddingTop();
|
||||
onToggle = () => {
|
||||
if (this.activityStatus.idle) {
|
||||
this.activityStatus.hide();
|
||||
this.updateBodyPaddingTop();
|
||||
} else {
|
||||
this.updateBodyPaddingTop();
|
||||
this.activityStatus.show();
|
||||
}
|
||||
};
|
||||
|
||||
onShow = () => {
|
||||
this.updateBodyPaddingTop();
|
||||
this.activityStatus.show();
|
||||
onIdleTimerActive = () => {
|
||||
clearTimeout(this.animationTimer);
|
||||
this.activityStatus.setActive();
|
||||
this.onToggle();
|
||||
};
|
||||
|
||||
onIdleTimerIdle = () => {
|
||||
const { settingsStore } = this.props;
|
||||
|
||||
if (settingsStore.filterBarConfig.config.autohide) {
|
||||
this.activityStatus.setIdle();
|
||||
this.animationTimer = setTimeout(
|
||||
this.onToggle,
|
||||
this.context.animations.duration
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
onResize = (width, height) => {
|
||||
@@ -126,30 +150,19 @@ const NavBar = observer(
|
||||
|
||||
const isMobile = IsMobile();
|
||||
|
||||
const isLoading =
|
||||
alertStore.filters.values.filter((f) => f.applied === false).length > 0;
|
||||
|
||||
return (
|
||||
<IdleTimer
|
||||
ref={(ref) => {
|
||||
this.idleTimer = ref;
|
||||
}}
|
||||
onActive={this.activityStatus.setActive}
|
||||
onIdle={() => {
|
||||
if (settingsStore.filterBarConfig.config.autohide) {
|
||||
this.activityStatus.setIdle();
|
||||
}
|
||||
}}
|
||||
onActive={this.onIdleTimerActive}
|
||||
onIdle={this.onIdleTimerIdle}
|
||||
timeout={isMobile ? MobileIdleTimeout : DesktopIdleTimeout}
|
||||
>
|
||||
<div
|
||||
className={`container p-0 m-0 mw-100 ${this.activityStatus.className}`}
|
||||
>
|
||||
<NavBarSlide
|
||||
in={!this.activityStatus.idle || isLoading}
|
||||
onEntering={this.onShow}
|
||||
onExited={this.onHide}
|
||||
>
|
||||
<Fade top when={!this.activityStatus.idle}>
|
||||
<nav
|
||||
className={`navbar navbar-expand navbar-dark p-1 bg-primary-transparent d-inline-block ${
|
||||
fixedTop ? "fixed-top" : "w-100"
|
||||
@@ -176,12 +189,13 @@ const NavBar = observer(
|
||||
settingsStore={settingsStore}
|
||||
/>
|
||||
</nav>
|
||||
</NavBarSlide>
|
||||
</Fade>
|
||||
</div>
|
||||
</IdleTimer>
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
NavBar.contextType = ThemeContext;
|
||||
|
||||
export { NavBar };
|
||||
|
||||
@@ -4,9 +4,12 @@ import { shallow, mount } from "enzyme";
|
||||
|
||||
import moment from "moment";
|
||||
|
||||
import { MockThemeContext } from "__mocks__/Theme";
|
||||
import { AlertStore, NewUnappliedFilter } from "Stores/AlertStore";
|
||||
import { Settings } from "Stores/Settings";
|
||||
import { SilenceFormStore } from "Stores/SilenceFormStore";
|
||||
import { ThemeContext } from "Components/Theme";
|
||||
|
||||
import { NavBar } from ".";
|
||||
|
||||
let alertStore;
|
||||
@@ -17,9 +20,12 @@ beforeEach(() => {
|
||||
alertStore = new AlertStore([]);
|
||||
settingsStore = new Settings();
|
||||
silenceFormStore = new SilenceFormStore();
|
||||
settingsStore.filterBarConfig.config.autohide = true;
|
||||
// fix startsAt & endsAt dates so they don't change between tests
|
||||
silenceFormStore.data.startsAt = moment([2018, 1, 30, 10, 25, 50]).utc();
|
||||
silenceFormStore.data.endsAt = moment([2018, 1, 30, 11, 25, 50]).utc();
|
||||
|
||||
jest.spyOn(React, "useContext").mockImplementation(() => MockThemeContext);
|
||||
});
|
||||
|
||||
const RenderNavbar = () => {
|
||||
@@ -38,7 +44,11 @@ const MountedNavbar = () => {
|
||||
alertStore={alertStore}
|
||||
settingsStore={settingsStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
/>
|
||||
/>,
|
||||
{
|
||||
wrappingComponent: ThemeContext.Provider,
|
||||
wrappingComponentProps: { value: MockThemeContext },
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
@@ -151,9 +161,9 @@ describe("<IdleTimer />", () => {
|
||||
});
|
||||
|
||||
it("doesn't hide on mobile if there are unapplied filters", () => {
|
||||
alertStore.filters.values.push(NewUnappliedFilter("cluster=dev"));
|
||||
global.window.innerWidth = 500;
|
||||
const tree = MountedNavbar();
|
||||
alertStore.filters.values.push(NewUnappliedFilter("cluster=dev"));
|
||||
jest.runTimersToTime(1000 * 13);
|
||||
tree.update();
|
||||
expect(tree.find(".container").hasClass("visible")).toBe(true);
|
||||
@@ -161,9 +171,9 @@ describe("<IdleTimer />", () => {
|
||||
});
|
||||
|
||||
it("doesn't hide on desktop if there are unapplied filters", () => {
|
||||
alertStore.filters.values.push(NewUnappliedFilter("cluster=dev"));
|
||||
global.window.innerWidth = 769;
|
||||
const tree = MountedNavbar();
|
||||
alertStore.filters.values.push(NewUnappliedFilter("cluster=dev"));
|
||||
jest.runTimersToTime(1000 * 60 * 3 + 1000);
|
||||
tree.update();
|
||||
expect(tree.find(".container").hasClass("visible")).toBe(true);
|
||||
@@ -171,32 +181,32 @@ describe("<IdleTimer />", () => {
|
||||
});
|
||||
|
||||
it("hides on mobile if all unapplied filters finish applying", () => {
|
||||
alertStore.filters.values.push(NewUnappliedFilter("cluster=dev"));
|
||||
global.window.innerWidth = 500;
|
||||
const tree = MountedNavbar();
|
||||
alertStore.filters.values.push(NewUnappliedFilter("cluster=dev"));
|
||||
jest.runTimersToTime(1000 * 13);
|
||||
tree.update();
|
||||
expect(tree.find(".container").hasClass("visible")).toBe(true);
|
||||
expect(tree.find(".container").hasClass("invisible")).toBe(false);
|
||||
|
||||
alertStore.filters.applyAllFilters();
|
||||
jest.runTimersToTime(1000);
|
||||
jest.runTimersToTime(1000 * 13);
|
||||
tree.update();
|
||||
expect(tree.find(".container").hasClass("visible")).toBe(false);
|
||||
expect(tree.find(".container").hasClass("invisible")).toBe(true);
|
||||
});
|
||||
|
||||
it("hides on desktop if all unapplied filters finish applying", () => {
|
||||
alertStore.filters.values.push(NewUnappliedFilter("cluster=dev"));
|
||||
global.window.innerWidth = 769;
|
||||
const tree = MountedNavbar();
|
||||
alertStore.filters.values.push(NewUnappliedFilter("cluster=dev"));
|
||||
jest.runTimersToTime(1000 * 60 * 3 + 1000);
|
||||
tree.update();
|
||||
expect(tree.find(".container").hasClass("visible")).toBe(true);
|
||||
expect(tree.find(".container").hasClass("invisible")).toBe(false);
|
||||
|
||||
alertStore.filters.applyAllFilters();
|
||||
jest.runTimersToTime(1000);
|
||||
jest.runTimersToTime(1000 * 60 * 3 + 1000);
|
||||
tree.update();
|
||||
expect(tree.find(".container").hasClass("visible")).toBe(false);
|
||||
expect(tree.find(".container").hasClass("invisible")).toBe(true);
|
||||
@@ -206,13 +216,13 @@ describe("<IdleTimer />", () => {
|
||||
const tree = MountedNavbar();
|
||||
const instance = tree.instance();
|
||||
|
||||
instance.activityStatus.setIdle();
|
||||
instance.onIdleTimerIdle();
|
||||
jest.runOnlyPendingTimers();
|
||||
tree.update();
|
||||
expect(tree.find(".container").hasClass("visible")).toBe(false);
|
||||
expect(tree.find(".container").hasClass("invisible")).toBe(true);
|
||||
|
||||
instance.activityStatus.setActive();
|
||||
instance.onIdleTimerActive();
|
||||
jest.runOnlyPendingTimers();
|
||||
tree.update();
|
||||
expect(tree.find(".container").hasClass("visible")).toBe(true);
|
||||
@@ -223,7 +233,7 @@ describe("<IdleTimer />", () => {
|
||||
const tree = MountedNavbar();
|
||||
const instance = tree.instance();
|
||||
|
||||
instance.activityStatus.setIdle();
|
||||
instance.onIdleTimerIdle();
|
||||
jest.runOnlyPendingTimers();
|
||||
tree.update();
|
||||
expect(
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
.components-animation-navbar {
|
||||
will-change: opacity;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
.components-animation-navbar-appear,
|
||||
.components-animation-navbar-enter {
|
||||
opacity: 0.01;
|
||||
}
|
||||
.components-animation-navbar-appear-active,
|
||||
.components-animation-navbar-enter-active {
|
||||
opacity: 1;
|
||||
transition: opacity 0.5s ease-in;
|
||||
}
|
||||
|
||||
.components-animation-navbar-exit {
|
||||
opacity: 1;
|
||||
}
|
||||
.components-animation-navbar-exit-active {
|
||||
opacity: 0.01;
|
||||
transition: opacity 0.5s ease-out;
|
||||
}
|
||||
@@ -122,7 +122,6 @@ $color-default: #708090;
|
||||
@import "Styles/Components/DropdownSlide";
|
||||
@import "Styles/Components/History";
|
||||
@import "Styles/Components/HistoryLabel";
|
||||
@import "Styles/Components/NavBarSlide";
|
||||
@import "Styles/Components/SilenceModal";
|
||||
@import "Styles/Components/Pagination";
|
||||
|
||||
|
||||
@@ -104,7 +104,6 @@ $color-default: #708090;
|
||||
@import "Styles/Components/DropdownSlide";
|
||||
@import "Styles/Components/History";
|
||||
@import "Styles/Components/HistoryLabel";
|
||||
@import "Styles/Components/NavBarSlide";
|
||||
@import "Styles/Components/SilenceModal";
|
||||
@import "Styles/Components/Pagination";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user