Skip to content
Snippets Groups Projects
Unverified Commit 7b979a8c authored by Alexander Polyankin's avatar Alexander Polyankin Committed by GitHub
Browse files

Add question last cached time info (#23787)

parent 56ed43e1
No related branches found
No related tags found
No related merge requests found
Showing
with 97 additions and 24 deletions
......@@ -16,10 +16,7 @@ interface CacheSectionProps {
onSave: (cache_ttl: number | null) => Promise<any>;
}
export const CacheSection = ({
initialCacheTTL,
onSave,
}: CacheSectionProps) => {
const CacheSection = ({ initialCacheTTL, onSave }: CacheSectionProps) => {
const [cacheTTL, setCacheTTL] = useState(initialCacheTTL);
const handleChange = useCallback(
......@@ -70,3 +67,5 @@ export const CacheSection = ({
</CacheSectionRoot>
);
};
export default CacheSection;
export * from "./CacheSection";
export { default } from "./CacheSection";
......@@ -17,7 +17,7 @@ const propTypes = {
message: PropTypes.string,
};
export function CacheTTLField({ field, message, ...props }) {
function CacheTTLField({ field, message, ...props }) {
const hasError = !!field.error;
return (
<CacheTTLFieldContainer {...props} data-testid="cache-ttl-field">
......@@ -40,3 +40,5 @@ export function CacheTTLField({ field, message, ...props }) {
}
CacheTTLField.propTypes = propTypes;
export default CacheTTLField;
import React from "react";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { CacheTTLField } from "./CacheTTLField";
import CacheTTLField from "./CacheTTLField";
function setup({ name = "cache_ttl", message, value }) {
const onChange = jest.fn();
......
export * from "./CacheTTLField";
export { default } from "./CacheTTLField";
import React from "react";
import { Dashboard } from "metabase-types/api";
import { CacheSection } from "../CacheSection";
import CacheSection from "../CacheSection";
interface DashboardCacheSectionProps {
dashboard: Dashboard;
onSave: (cache_ttl: number | null) => Promise<Dashboard>;
}
export const DashboardCacheSection = ({
const DashboardCacheSection = ({
dashboard,
onSave,
}: DashboardCacheSectionProps) => {
return <CacheSection initialCacheTTL={dashboard.cache_ttl} onSave={onSave} />;
};
export default DashboardCacheSection;
export * from "./DashboardCacheSection";
export { default } from "./DashboardCacheSection";
......@@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useState } from "react";
import PropTypes from "prop-types";
import { t } from "ttag";
import Select, { Option } from "metabase/core/components/Select";
import { CacheTTLField } from "../CacheTTLField";
import CacheTTLField from "../CacheTTLField";
import {
CacheFieldContainer,
FieldContainer,
......@@ -20,7 +20,7 @@ const propTypes = {
field: PropTypes.object.isRequired,
};
export function DatabaseCacheTTLField({ field }) {
function DatabaseCacheTTLField({ field }) {
const [mode, setMode] = useState(
field.value > 0 ? MODE.CUSTOM : MODE.INSTANCE_DEFAULT,
);
......@@ -55,3 +55,5 @@ export function DatabaseCacheTTLField({ field }) {
}
DatabaseCacheTTLField.propTypes = propTypes;
export default DatabaseCacheTTLField;
import React from "react";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { DatabaseCacheTTLField } from "./DatabaseCacheTTLField";
import DatabaseCacheTTLField from "./DatabaseCacheTTLField";
function setup({ value = null } = {}) {
const onChange = jest.fn();
......
export * from "./DatabaseCacheTTLField";
export { default } from "./DatabaseCacheTTLField";
import styled from "@emotion/styled";
import { color } from "metabase/lib/colors";
export const QueryStartLabel = styled.div`
color: ${color("text-dark")};
font-weight: bold;
margin-bottom: 0.5rem;
`;
import React from "react";
import { t } from "ttag";
import { getRelativeTime } from "metabase/lib/time";
import Question from "metabase-lib/lib/Question";
import { CacheSection } from "../CacheSection";
import CacheSection from "../CacheSection";
import { QueryStartLabel } from "./QuestionCacheSection.styled";
interface QuestionCacheSectionProps {
export interface QuestionCacheSectionProps {
question: Question;
onSave: (cache_ttl: number | null) => Promise<Question>;
}
export const QuestionCacheSection = ({
const QuestionCacheSection = ({
question,
onSave,
}: QuestionCacheSectionProps) => {
return <CacheSection initialCacheTTL={question.cacheTTL()} onSave={onSave} />;
const cacheTimestamp = question.lastQueryStart();
const cacheRelativeTime = cacheTimestamp && getRelativeTime(cacheTimestamp);
return (
<div>
{cacheTimestamp && (
<QueryStartLabel>
{t`Question last cached ${cacheRelativeTime}`}
</QueryStartLabel>
)}
<CacheSection initialCacheTTL={question.cacheTTL()} onSave={onSave} />
</div>
);
};
export default QuestionCacheSection;
import React from "react";
import { render, screen } from "@testing-library/react";
import Question from "metabase-lib/lib/Question";
import { createMockCard } from "metabase-types/api/mocks";
import QuestionCacheSection, {
QuestionCacheSectionProps,
} from "./QuestionCacheSection";
describe("QuestionCacheSection", () => {
beforeEach(() => {
jest.useFakeTimers();
jest.setSystemTime(new Date(2020, 0, 10));
});
afterEach(() => {
jest.useRealTimers();
});
it("should show the time of the last cached query", () => {
const props = getProps({
question: new Question(
createMockCard({
last_query_start: "2020-01-05T00:00:00Z",
}),
),
});
render(<QuestionCacheSection {...props} />);
const cacheLabel = screen.getByText("Question last cached 5 days ago");
expect(cacheLabel).toBeInTheDocument();
});
});
const getProps = (
opts?: Partial<QuestionCacheSectionProps>,
): QuestionCacheSectionProps => ({
question: new Question(createMockCard()),
onSave: jest.fn(),
...opts,
});
export * from "./QuestionCacheSection";
export { default } from "./QuestionCacheSection";
......@@ -31,7 +31,7 @@ function getInitialMode(question, implicitCacheTTL) {
return MODE.DEFAULT;
}
export function QuestionCacheTTLField({ field, question, ...props }) {
function QuestionCacheTTLField({ field, question, ...props }) {
const implicitCacheTTL = useMemo(
() => getQuestionsImplicitCacheTTL(question),
[question],
......@@ -73,3 +73,5 @@ export function QuestionCacheTTLField({ field, question, ...props }) {
}
QuestionCacheTTLField.propTypes = propTypes;
export default QuestionCacheTTLField;
......@@ -3,7 +3,7 @@ import { t } from "ttag";
import styled from "@emotion/styled";
import { space } from "metabase/styled-components/theme";
import Radio from "metabase/core/components/Radio";
import { CacheTTLField } from "../CacheTTLField";
import CacheTTLField from "../CacheTTLField";
export function CacheTTLInput(props) {
return <CacheTTLField {...props} message={t`Cache results for`} />;
......
......@@ -3,7 +3,7 @@ import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { msToMinutes, msToHours } from "metabase/lib/time";
import MetabaseSettings from "metabase/lib/settings";
import { QuestionCacheTTLField } from "./QuestionCacheTTLField";
import QuestionCacheTTLField from "./QuestionCacheTTLField";
const TEN_MINUTES = 10 * 60 * 1000;
......
export * from "./QuestionCacheTTLField";
export { default } from "./QuestionCacheTTLField";
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment