Refactored the way we show time using Intl
(#2178)
This commit is contained in:
parent
1b6d679d89
commit
b7ea8629a2
12 changed files with 107 additions and 136 deletions
|
@ -255,7 +255,7 @@ export const OtpPolicy = ({ realm, realmUpdated }: OtpPolicyProps) => {
|
||||||
aria-label={t("otpPolicyPeriod")}
|
aria-label={t("otpPolicyPeriod")}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["seconds", "minutes"]}
|
units={["second", "minute"]}
|
||||||
validated={errors.otpPolicyPeriod ? "error" : "default"}
|
validated={errors.otpPolicyPeriod ? "error" : "default"}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -307,7 +307,7 @@ export const WebauthnPolicy = ({
|
||||||
aria-label={t("webAuthnPolicyCreateTimeout")}
|
aria-label={t("webAuthnPolicyCreateTimeout")}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["seconds", "minutes", "hours"]}
|
units={["second", "minute", "hour"]}
|
||||||
validated={
|
validated={
|
||||||
errors.webAuthnPolicyCreateTimeout ? "error" : "default"
|
errors.webAuthnPolicyCreateTimeout ? "error" : "default"
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ export const AdvancedSettings = ({
|
||||||
control={control}
|
control={control}
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
<TimeSelector
|
<TimeSelector
|
||||||
units={["minutes", "days", "hours"]}
|
units={["minute", "day", "hour"]}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
|
@ -64,7 +64,7 @@ export const AdvancedSettings = ({
|
||||||
id="accessTokenLifespan"
|
id="accessTokenLifespan"
|
||||||
name="attributes.access.token.lifespan"
|
name="attributes.access.token.lifespan"
|
||||||
defaultValue=""
|
defaultValue=""
|
||||||
units={["minutes", "days", "hours"]}
|
units={["minute", "day", "hour"]}
|
||||||
control={control}
|
control={control}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,6 @@ export default function CreateInitialAccessToken() {
|
||||||
data-testid="expiration"
|
data-testid="expiration"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["days", "hours", "minutes", "seconds"]}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import React, { useEffect, useMemo, useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
import {
|
import {
|
||||||
Select,
|
Select,
|
||||||
SelectOption,
|
SelectOption,
|
||||||
|
@ -8,10 +10,17 @@ import {
|
||||||
TextInputProps,
|
TextInputProps,
|
||||||
ToggleMenuBaseProps,
|
ToggleMenuBaseProps,
|
||||||
} from "@patternfly/react-core";
|
} from "@patternfly/react-core";
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
export type Unit = "seconds" | "minutes" | "hours" | "days";
|
export type Unit = "second" | "minute" | "hour" | "day";
|
||||||
|
|
||||||
|
type TimeUnit = { unit: Unit; label: string; multiplier: number };
|
||||||
|
|
||||||
|
const allTimes: TimeUnit[] = [
|
||||||
|
{ unit: "second", label: "times.seconds", multiplier: 1 },
|
||||||
|
{ unit: "minute", label: "times.minutes", multiplier: 60 },
|
||||||
|
{ unit: "hour", label: "times.hours", multiplier: 3600 },
|
||||||
|
{ unit: "day", label: "times.days", multiplier: 86400 },
|
||||||
|
];
|
||||||
|
|
||||||
export type TimeSelectorProps = TextInputProps &
|
export type TimeSelectorProps = TextInputProps &
|
||||||
ToggleMenuBaseProps & {
|
ToggleMenuBaseProps & {
|
||||||
|
@ -21,9 +30,28 @@ export type TimeSelectorProps = TextInputProps &
|
||||||
className?: string;
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getTimeUnit = (value: number) =>
|
||||||
|
allTimes.reduce(
|
||||||
|
(v, time) =>
|
||||||
|
value % time.multiplier === 0 && v.multiplier < time.multiplier
|
||||||
|
? time
|
||||||
|
: v,
|
||||||
|
allTimes[0]
|
||||||
|
);
|
||||||
|
|
||||||
|
export const toHumanFormat = (value: number, locale: string) => {
|
||||||
|
const timeUnit = getTimeUnit(value);
|
||||||
|
const formatter = new Intl.NumberFormat(locale, {
|
||||||
|
style: "unit",
|
||||||
|
unit: timeUnit.unit,
|
||||||
|
unitDisplay: "long",
|
||||||
|
});
|
||||||
|
return formatter.format(value / timeUnit.multiplier);
|
||||||
|
};
|
||||||
|
|
||||||
export const TimeSelector = ({
|
export const TimeSelector = ({
|
||||||
value,
|
value,
|
||||||
units = ["seconds", "minutes", "hours", "days"],
|
units = ["second", "minute", "hour", "day"],
|
||||||
onChange,
|
onChange,
|
||||||
className,
|
className,
|
||||||
min,
|
min,
|
||||||
|
@ -32,36 +60,26 @@ export const TimeSelector = ({
|
||||||
}: TimeSelectorProps) => {
|
}: TimeSelectorProps) => {
|
||||||
const { t } = useTranslation("common");
|
const { t } = useTranslation("common");
|
||||||
|
|
||||||
const allTimes: { unit: Unit; label: string; multiplier: number }[] = [
|
const times = useMemo(
|
||||||
{ unit: "seconds", label: t("times.seconds"), multiplier: 1 },
|
() => units.map((unit) => allTimes.find((time) => time.unit === unit)!),
|
||||||
{ unit: "minutes", label: t("times.minutes"), multiplier: 60 },
|
[units]
|
||||||
{ unit: "hours", label: t("times.hours"), multiplier: 3600 },
|
);
|
||||||
{ unit: "days", label: t("times.days"), multiplier: 86400 },
|
|
||||||
];
|
const defaultMultiplier = useMemo(
|
||||||
|
() => allTimes.find((time) => time.unit === units[0])?.multiplier,
|
||||||
const times = units.map(
|
[units]
|
||||||
(unit) => allTimes.find((time) => time.unit === unit)!
|
|
||||||
);
|
);
|
||||||
const defaultMultiplier = allTimes.find(
|
|
||||||
(time) => time.unit === units[0]
|
|
||||||
)?.multiplier;
|
|
||||||
|
|
||||||
const [timeValue, setTimeValue] = useState<"" | number>("");
|
const [timeValue, setTimeValue] = useState<"" | number>("");
|
||||||
const [multiplier, setMultiplier] = useState(defaultMultiplier);
|
const [multiplier, setMultiplier] = useState(defaultMultiplier);
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const x = times.reduce(
|
const multiplier = getTimeUnit(value).multiplier;
|
||||||
(v, time) =>
|
|
||||||
value % time.multiplier === 0 && v < time.multiplier
|
|
||||||
? time.multiplier
|
|
||||||
: v,
|
|
||||||
1
|
|
||||||
);
|
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
setMultiplier(x);
|
setMultiplier(multiplier);
|
||||||
setTimeValue(value / x);
|
setTimeValue(value / multiplier);
|
||||||
} else {
|
} else {
|
||||||
setTimeValue(value);
|
setTimeValue(value);
|
||||||
setMultiplier(defaultMultiplier);
|
setMultiplier(defaultMultiplier);
|
||||||
|
@ -118,7 +136,7 @@ export const TimeSelector = ({
|
||||||
key={time.label}
|
key={time.label}
|
||||||
value={time.multiplier}
|
value={time.multiplier}
|
||||||
>
|
>
|
||||||
{time.label}
|
{t(time.label)}
|
||||||
</SelectOption>
|
</SelectOption>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
|
|
23
src/components/time-selector/time-selector.test.ts
Normal file
23
src/components/time-selector/time-selector.test.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import { getTimeUnit, toHumanFormat } from "./TimeSelector";
|
||||||
|
|
||||||
|
describe("Time conversion functions", () => {
|
||||||
|
it("should convert milliseconds to unit", () => {
|
||||||
|
const givenTime = 86400;
|
||||||
|
|
||||||
|
//when
|
||||||
|
const timeUnit = getTimeUnit(givenTime);
|
||||||
|
|
||||||
|
//then
|
||||||
|
expect(timeUnit.unit).toEqual("day");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should convert to human format", () => {
|
||||||
|
const givenTime = 86400 * 2;
|
||||||
|
|
||||||
|
//when
|
||||||
|
const timeString = toHumanFormat(givenTime, "en");
|
||||||
|
|
||||||
|
//then
|
||||||
|
expect(timeString).toEqual("2 days");
|
||||||
|
});
|
||||||
|
});
|
|
@ -78,7 +78,7 @@ export const RealmSettingsSessionsTab = ({
|
||||||
aria-label="sso-session-idle-input"
|
aria-label="sso-session-idle-input"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -105,7 +105,7 @@ export const RealmSettingsSessionsTab = ({
|
||||||
aria-label="sso-session-max-input"
|
aria-label="sso-session-max-input"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -132,7 +132,7 @@ export const RealmSettingsSessionsTab = ({
|
||||||
aria-label="sso-session-idle-remember-me-input"
|
aria-label="sso-session-idle-remember-me-input"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -159,7 +159,7 @@ export const RealmSettingsSessionsTab = ({
|
||||||
data-testid="sso-session-max-remember-me-input"
|
data-testid="sso-session-max-remember-me-input"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -197,7 +197,7 @@ export const RealmSettingsSessionsTab = ({
|
||||||
aria-label="client-session-idle-input"
|
aria-label="client-session-idle-input"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -224,7 +224,7 @@ export const RealmSettingsSessionsTab = ({
|
||||||
aria-label="client-session-max-input"
|
aria-label="client-session-max-input"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -262,7 +262,7 @@ export const RealmSettingsSessionsTab = ({
|
||||||
aria-label="offline-session-idle-input"
|
aria-label="offline-session-idle-input"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -318,7 +318,7 @@ export const RealmSettingsSessionsTab = ({
|
||||||
aria-label="offline-session-max-input"
|
aria-label="offline-session-max-input"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -358,7 +358,7 @@ export const RealmSettingsSessionsTab = ({
|
||||||
aria-label="login-timeout-input"
|
aria-label="login-timeout-input"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -385,7 +385,7 @@ export const RealmSettingsSessionsTab = ({
|
||||||
aria-label="login-action-timeout-input"
|
aria-label="login-action-timeout-input"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -19,11 +19,14 @@ import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/r
|
||||||
import { FormAccess } from "../components/form-access/FormAccess";
|
import { FormAccess } from "../components/form-access/FormAccess";
|
||||||
import { HelpItem } from "../components/help-enabler/HelpItem";
|
import { HelpItem } from "../components/help-enabler/HelpItem";
|
||||||
import { FormPanel } from "../components/scroll-form/FormPanel";
|
import { FormPanel } from "../components/scroll-form/FormPanel";
|
||||||
import { TimeSelector } from "../components/time-selector/TimeSelector";
|
import {
|
||||||
|
TimeSelector,
|
||||||
|
toHumanFormat,
|
||||||
|
} from "../components/time-selector/TimeSelector";
|
||||||
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
|
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
|
||||||
import { forHumans, interpolateTimespan } from "../util";
|
|
||||||
|
|
||||||
import "./realm-settings-section.css";
|
import "./realm-settings-section.css";
|
||||||
|
import { useWhoAmI } from "../context/whoami/WhoAmI";
|
||||||
|
|
||||||
type RealmSettingsSessionsTabProps = {
|
type RealmSettingsSessionsTabProps = {
|
||||||
realm: RealmRepresentation;
|
realm: RealmRepresentation;
|
||||||
|
@ -38,6 +41,7 @@ export const RealmSettingsTokensTab = ({
|
||||||
}: RealmSettingsSessionsTabProps) => {
|
}: RealmSettingsSessionsTabProps) => {
|
||||||
const { t } = useTranslation("realm-settings");
|
const { t } = useTranslation("realm-settings");
|
||||||
const serverInfo = useServerInfo();
|
const serverInfo = useServerInfo();
|
||||||
|
const { whoAmI } = useWhoAmI();
|
||||||
|
|
||||||
const [defaultSigAlgDrpdwnIsOpen, setDefaultSigAlgDrpdwnOpen] =
|
const [defaultSigAlgDrpdwnIsOpen, setDefaultSigAlgDrpdwnOpen] =
|
||||||
useState(false);
|
useState(false);
|
||||||
|
@ -200,9 +204,12 @@ export const RealmSettingsTokensTab = ({
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={t("accessTokenLifespan")}
|
label={t("accessTokenLifespan")}
|
||||||
fieldId="accessTokenLifespan"
|
fieldId="accessTokenLifespan"
|
||||||
helperText={`It is recommended for this value to be shorter than the SSO session idle timeout: ${interpolateTimespan(
|
helperText={t("recommendedSsoTimeout", {
|
||||||
forHumans(realm.ssoSessionIdleTimeout!)
|
time: toHumanFormat(
|
||||||
)}`}
|
realm.ssoSessionIdleTimeout!,
|
||||||
|
whoAmI.getLocale()
|
||||||
|
),
|
||||||
|
})}
|
||||||
labelIcon={
|
labelIcon={
|
||||||
<HelpItem
|
<HelpItem
|
||||||
helpText="realm-settings-help:accessTokenLifespan"
|
helpText="realm-settings-help:accessTokenLifespan"
|
||||||
|
@ -225,7 +232,7 @@ export const RealmSettingsTokensTab = ({
|
||||||
aria-label="access-token-lifespan"
|
aria-label="access-token-lifespan"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -252,7 +259,7 @@ export const RealmSettingsTokensTab = ({
|
||||||
aria-label="access-token-lifespan-implicit"
|
aria-label="access-token-lifespan-implicit"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -278,7 +285,7 @@ export const RealmSettingsTokensTab = ({
|
||||||
aria-label="client-login-timeout"
|
aria-label="client-login-timeout"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -307,7 +314,7 @@ export const RealmSettingsTokensTab = ({
|
||||||
aria-label="offline-session-max-input"
|
aria-label="offline-session-max-input"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -347,7 +354,7 @@ export const RealmSettingsTokensTab = ({
|
||||||
aria-label="user-initiated-action-lifespan"
|
aria-label="user-initiated-action-lifespan"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -374,7 +381,7 @@ export const RealmSettingsTokensTab = ({
|
||||||
aria-label="default-admin-initated-input"
|
aria-label="default-admin-initated-input"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -401,7 +408,7 @@ export const RealmSettingsTokensTab = ({
|
||||||
aria-label="email-verification-input"
|
aria-label="email-verification-input"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={(value: any) => onChange(value.toString())}
|
onChange={(value: any) => onChange(value.toString())}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -422,7 +429,7 @@ export const RealmSettingsTokensTab = ({
|
||||||
aria-label="idp-email-verification"
|
aria-label="idp-email-verification"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -443,7 +450,7 @@ export const RealmSettingsTokensTab = ({
|
||||||
aria-label="forgot-pw-input"
|
aria-label="forgot-pw-input"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -464,7 +471,7 @@ export const RealmSettingsTokensTab = ({
|
||||||
aria-label="execute-actions-input"
|
aria-label="execute-actions-input"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -132,7 +132,7 @@ export const EventConfigForm = ({
|
||||||
<TimeSelector
|
<TimeSelector
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -358,11 +358,8 @@ export default {
|
||||||
userProfileSuccess: "User profile settings successfully updated.",
|
userProfileSuccess: "User profile settings successfully updated.",
|
||||||
userProfileError: "Could not update user profile settings: {{error}}",
|
userProfileError: "Could not update user profile settings: {{error}}",
|
||||||
status: "Status",
|
status: "Status",
|
||||||
convertedToYearsValue: "{{convertedToYears}}",
|
recommendedSsoTimeout:
|
||||||
convertedToDaysValue: "{{convertedToDays}}",
|
"It is recommended for this value to be shorter than the SSO session idle timeout: {{time}}",
|
||||||
convertedToHoursValue: "{{convertedToHours}}",
|
|
||||||
convertedToMinutesValue: "{{convertedToMinutes}}",
|
|
||||||
convertedToSecondsValue: "{{convertedToSeconds}}",
|
|
||||||
supportedLocales: "Supported locales",
|
supportedLocales: "Supported locales",
|
||||||
defaultLocale: "Default locale",
|
defaultLocale: "Default locale",
|
||||||
selectLocales: "Select locales",
|
selectLocales: "Select locales",
|
||||||
|
|
|
@ -27,7 +27,7 @@ export const LifespanField = () => {
|
||||||
render={({ onChange, value }) => (
|
render={({ onChange, value }) => (
|
||||||
<TimeSelector
|
<TimeSelector
|
||||||
value={value}
|
value={value}
|
||||||
units={["minutes", "hours", "days"]}
|
units={["minute", "hour", "day"]}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
menuAppendTo="parent"
|
menuAppendTo="parent"
|
||||||
/>
|
/>
|
||||||
|
|
73
src/util.ts
73
src/util.ts
|
@ -1,5 +1,4 @@
|
||||||
import { cloneDeep } from "lodash-es";
|
import { cloneDeep } from "lodash-es";
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import FileSaver from "file-saver";
|
import FileSaver from "file-saver";
|
||||||
import type { IFormatter, IFormatterValueType } from "@patternfly/react-table";
|
import type { IFormatter, IFormatterValueType } from "@patternfly/react-table";
|
||||||
import { unflatten, flatten } from "flat";
|
import { unflatten, flatten } from "flat";
|
||||||
|
@ -150,78 +149,6 @@ export const alphaRegexPattern = /[^A-Za-z]/g;
|
||||||
export const emailRegexPattern =
|
export const emailRegexPattern =
|
||||||
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||||
|
|
||||||
export const forHumans = (seconds: number) => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const levels: [
|
|
||||||
[number, string],
|
|
||||||
[number, string],
|
|
||||||
[number, string],
|
|
||||||
[number, string],
|
|
||||||
[number, string]
|
|
||||||
] = [
|
|
||||||
[Math.floor(seconds / 31536000), t("common:times.years")],
|
|
||||||
[Math.floor((seconds % 31536000) / 86400), t("common:times.days")],
|
|
||||||
[
|
|
||||||
Math.floor(((seconds % 31536000) % 86400) / 3600),
|
|
||||||
t("common:times.hours"),
|
|
||||||
],
|
|
||||||
[
|
|
||||||
Math.floor((((seconds % 31536000) % 86400) % 3600) / 60),
|
|
||||||
t("common:times.minutes"),
|
|
||||||
],
|
|
||||||
[(((seconds % 31536000) % 86400) % 3600) % 60, t("common:times.seconds")],
|
|
||||||
];
|
|
||||||
let returntext = "";
|
|
||||||
|
|
||||||
for (let i = 0, max = levels.length; i < max; i++) {
|
|
||||||
if (levels[i][0] === 0) continue;
|
|
||||||
returntext +=
|
|
||||||
" " +
|
|
||||||
levels[i][0] +
|
|
||||||
" " +
|
|
||||||
(levels[i][0] === 1
|
|
||||||
? levels[i][1].substr(0, levels[i][1].length - 1)
|
|
||||||
: levels[i][1]);
|
|
||||||
}
|
|
||||||
return returntext.trim();
|
|
||||||
};
|
|
||||||
|
|
||||||
export const interpolateTimespan = (forHumans: string) => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const timespan = forHumans.split(" ");
|
|
||||||
|
|
||||||
if (timespan[1] === "Years") {
|
|
||||||
return t(`realm-settings:convertedToYearsValue`, {
|
|
||||||
convertedToYears: forHumans,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timespan[1] === "Days") {
|
|
||||||
return t(`realm-settings:convertedToDaysValue`, {
|
|
||||||
convertedToYears: forHumans,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timespan[1] === "Hours") {
|
|
||||||
return t(`realm-settings:convertedToHoursValue`, {
|
|
||||||
convertedToHours: forHumans,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timespan[1] === "Minutes") {
|
|
||||||
return t(`realm-settings:convertedToMinutesValue`, {
|
|
||||||
convertedToMinutes: forHumans,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timespan[1] === "Seconds") {
|
|
||||||
return t(`realm-settings:convertedToSecondsValue`, {
|
|
||||||
convertedToSeconds: forHumans,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const KEY_PROVIDER_TYPE = "org.keycloak.keys.KeyProvider";
|
export const KEY_PROVIDER_TYPE = "org.keycloak.keys.KeyProvider";
|
||||||
|
|
||||||
export const prettyPrintJSON = (value: any) => JSON.stringify(value, null, 2);
|
export const prettyPrintJSON = (value: any) => JSON.stringify(value, null, 2);
|
||||||
|
|
Loading…
Reference in a new issue