Skip to content
Snippets Groups Projects
Unverified Commit 0079088e authored by Raphael Krut-Landau's avatar Raphael Krut-Landau Committed by GitHub
Browse files

feat(admin/performance): Improve short label for duration policy (#45933)

Closes #45127
parent 6b5ce3b6
Branches
Tags
No related merge requests found
......@@ -8,7 +8,13 @@ import {
getSaveButton,
setupStrategyEditorForDatabases as baseSetup,
} from "metabase/admin/performance/components/test-utils";
import { getShortStrategyLabel } from "metabase/admin/performance/utils";
import { PLUGIN_CACHING } from "metabase/plugins";
import {
type ScheduleStrategy,
type DurationStrategy,
CacheDurationUnit,
} from "metabase-types/api";
import { createMockTokenFeatures } from "metabase-types/api/mocks";
function setup(opts: SetupOpts = {}) {
......@@ -33,7 +39,9 @@ describe("StrategyEditorForDatabases", () => {
const rootStrategyHeading = await screen.findByText("Default policy");
expect(rootStrategyHeading).toBeInTheDocument();
expect(
await screen.findByLabelText("Edit default policy (currently: Duration)"),
await screen.findByLabelText(
"Edit default policy (currently: Duration: 1h)",
),
).toBeInTheDocument();
expect(
await screen.findAllByLabelText(/Edit policy for database/),
......@@ -50,19 +58,19 @@ describe("StrategyEditorForDatabases", () => {
).toBeInTheDocument();
expect(
await screen.findByLabelText(
"Edit policy for database 'Database 3' (currently: Duration)",
"Edit policy for database 'Database 3' (currently: Duration: 1h)",
),
).toBeInTheDocument();
expect(
await screen.findByLabelText(
"Edit policy for database 'Database 4' (currently inheriting the default policy, Duration)",
"Edit policy for database 'Database 4' (currently inheriting the default policy, Duration: 1h)",
),
).toBeInTheDocument();
});
it("lets user change the default policy from 'Duration' to 'Adaptive' to 'Don't cache results'", async () => {
const editButton = await screen.findByLabelText(
`Edit default policy (currently: Duration)`,
`Edit default policy (currently: Duration: 1h)`,
);
await userEvent.click(editButton);
expect(
......@@ -83,7 +91,9 @@ describe("StrategyEditorForDatabases", () => {
);
expect(
await screen.findByLabelText(`Edit default policy (currently: Duration)`),
await screen.findByLabelText(
`Edit default policy (currently: Duration: 48h)`,
),
).toBeInTheDocument();
const noCacheStrategyRadioButton = await screen.findByRole("radio", {
......@@ -174,7 +184,7 @@ describe("StrategyEditorForDatabases", () => {
await screen.findByLabelText(/Edit policy for database 'Database 1'/),
).toHaveAttribute(
"aria-label",
"Edit policy for database 'Database 1' (currently: Duration)",
"Edit policy for database 'Database 1' (currently: Duration: 48h)",
);
// Switch to Adaptive strategy
......@@ -200,4 +210,23 @@ describe("StrategyEditorForDatabases", () => {
),
).toBeInTheDocument();
});
it("can abbreviate a 'Schedule' strategy", () => {
const strategy: ScheduleStrategy = {
type: "schedule",
schedule: "0 0 * * * ?",
};
const result = getShortStrategyLabel(strategy);
expect(result).toBe("Scheduled: hourly");
});
it("can abbreviate a 'Duration' strategy", () => {
const strategy: DurationStrategy = {
type: "duration",
duration: 5,
unit: CacheDurationUnit.Hours,
};
const result = getShortStrategyLabel(strategy);
expect(result).toBe("Duration: 5h");
});
});
import { t } from "ttag";
import { match } from "ts-pattern";
import { c, t } from "ttag";
import { memoize } from "underscore";
import type { SchemaObjectDescription } from "yup/lib/schema";
......@@ -235,9 +236,23 @@ export const getShortStrategyLabel = (
}
const type = strategies[strategy.type];
const mainLabel = getLabelString(type.shortLabel ?? type.label, model);
if (strategy.type === "schedule") {
const frequency = getFrequencyFromCron(strategy.schedule);
return `${mainLabel}: ${frequency}`;
/** Part of the label shown after the colon */
const subLabel = match(strategy)
.with({ type: "schedule" }, strategy =>
getFrequencyFromCron(strategy.schedule),
)
.with(
{ type: "duration" },
strategy =>
c(
"{0} is a number. Indicates a number of hours (the length of a cache)",
).t`${strategy.duration}h`,
)
.otherwise(() => null);
if (subLabel) {
return c(
"{0} is the primary label for a cache invalidation strategy. {1} is a further description.",
).t`${mainLabel}: ${subLabel}`;
} else {
return mainLabel;
}
......
import type { ScheduleSettings } from "metabase-types/api";
import type {
AdaptiveStrategy,
ScheduleSettings,
InheritStrategy,
} from "metabase-types/api";
import {
cronToScheduleSettings,
getShortStrategyLabel,
hourTo24HourFormat,
hourToTwelveHourFormat,
scheduleSettingsToCron,
......@@ -276,3 +281,28 @@ describe("hourTo24HourFormat", () => {
expect(hourTo24HourFormat(NaN, NaN)).toBeNaN();
});
});
describe("getShortStrategyLabel", () => {
it("should return null if no strategy is provided", () => {
const result = getShortStrategyLabel();
expect(result).toBeNull();
});
it("can abbreviate an 'Adaptive' strategy", () => {
const strategy: AdaptiveStrategy = {
type: "ttl",
multiplier: 2,
min_duration_ms: 1000,
};
const result = getShortStrategyLabel(strategy);
expect(result).toBe("Adaptive");
});
it("can abbreviate a 'Use default' aka inherit strategy", () => {
const strategy: InheritStrategy = {
type: "inherit",
};
const result = getShortStrategyLabel(strategy);
expect(result).toBe("Use default");
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment