Skip to content

Commit 42450f1

Browse files
authored
add TTL to create cluster flow cached state (#1404)
1 parent b8db9fe commit 42450f1

File tree

6 files changed

+40
-16
lines changed

6 files changed

+40
-16
lines changed

www/src/components/account/billing/BillingPricingCards.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export function ContactUs({ ...props }: ButtonProps) {
1818
return (
1919
<Button
2020
as="a"
21-
href="https://plural.sh/contact-sales"
21+
href="https://www.plural.sh/contact"
2222
target="_blank"
2323
rel="noopener noreferer"
2424
width="100%"

www/src/components/create-cluster/CreateCluster.tsx

+9-5
Original file line numberDiff line numberDiff line change
@@ -36,28 +36,32 @@ export const CUR_CREATE_CLUSTER_STEP_KEY = 'cur-create-cluster-step'
3636
export const CLOUD_OPTION_KEY = 'cloud-option'
3737
export const HOSTING_OPTION_KEY = 'hosting-option'
3838
export const CUR_CONSOLE_INSTANCE_KEY = 'cur-console-instance-id'
39+
const TTL_KEY = 'create-cluster-ttl'
3940

4041
export function CreateCluster() {
4142
const theme = useTheme()
4243
const navigate = useNavigate()
4344
const [curStep, setCurStep] = usePersistedState<CreateClusterStepKey>(
4445
CUR_CREATE_CLUSTER_STEP_KEY,
45-
CreateClusterStepKey.ChooseCloud
46+
CreateClusterStepKey.ChooseCloud,
47+
{ key: TTL_KEY }
4648
)
4749
const [cloudOption, setCloudOption] = usePersistedState<CloudOption>(
4850
CLOUD_OPTION_KEY,
49-
'local'
51+
'local',
52+
{ key: TTL_KEY }
5053
)
5154
const [hostingOption, setHostingOption] =
5255
usePersistedState<ConsoleInstanceType>(
5356
HOSTING_OPTION_KEY,
54-
ConsoleInstanceType.Shared
57+
ConsoleInstanceType.Shared,
58+
{ key: TTL_KEY }
5559
)
5660
const [finishEnabled, setFinishEnabled] = useState(false)
5761
const [continueBtn, setContinueBtn] = useState<ReactElement | undefined>()
5862
const [consoleInstanceId, setConsoleInstanceId] = usePersistedState<
5963
Nullable<string>
60-
>(CUR_CONSOLE_INSTANCE_KEY, null)
64+
>(CUR_CONSOLE_INSTANCE_KEY, null, { key: TTL_KEY })
6165

6266
const steps = cloudOption === 'local' ? localSteps : cloudSteps
6367
const curStepIndex = steps.findIndex((step) => step.key === curStep)
@@ -142,7 +146,7 @@ export function CreateCluster() {
142146
secondary
143147
startIcon={<SendMessageIcon />}
144148
as="a"
145-
href="https://plural.sh/contact-sales"
149+
href="https://www.plural.sh/contact"
146150
target="_blank"
147151
rel="noopener noreferrer"
148152
>

www/src/components/create-cluster/steps/ChooseCloudStep.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export function ChooseCloudStep() {
6161
</CalloutLinkButton>
6262
<CalloutLinkButton
6363
secondary
64-
href="https://plural.sh/contact-sales"
64+
href="https://www.plural.sh/contact"
6565
>
6666
Contact sales
6767
</CalloutLinkButton>

www/src/components/create-cluster/steps/ChooseHostingOptionStep.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export function ChooseHostingOptionStep() {
5656
>
5757
If you would like to create a dedicated cloud instance, please
5858
contact sales to inquire about upgrading to an Enterprise plan.
59-
<CalloutLinkButton href="https://plural.sh/contact-sales">
59+
<CalloutLinkButton href="https://www.plural.sh/contact">
6060
Contact sales
6161
</CalloutLinkButton>
6262
</Flex>

www/src/components/overview/clusters/ClustersHelpSection.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export default function ClustersHelpSection(): ReactElement {
4747
floating
4848
startIcon={<SendMessageIcon />}
4949
forwardedAs="a"
50-
href="https://plural.sh/contact-sales"
50+
href="https://www.plural.sh/contact"
5151
target="_blank"
5252
rel="noopener noreferrer"
5353
>

www/src/hooks/usePersistedState.tsx

+27-7
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,49 @@ import {
88

99
const identity = (x: any) => x
1010

11+
// 12 hours, but only used if TTL key explicitly provided
12+
const DEFAULT_TTL_DURATION = 12 * 60 * 60 * 1000
13+
14+
type TTLConfig = {
15+
key: string
16+
duration?: number
17+
}
18+
1119
// useState with localStorage persistence
1220
function usePersistedState<T>(
1321
key: string,
1422
defaultValue: T,
23+
ttl?: TTLConfig,
1524
parser = identity
1625
): [T, Dispatch<SetStateAction<T>>] {
17-
const getLocalStorageValue = useCallback(() => {
26+
const ttlKey = ttl ? `plural-${ttl.key}-timestamp` : ''
27+
const itemKey = `plural-${key}`
28+
const getInitialVal = useCallback(() => {
1829
try {
19-
const item = localStorage.getItem(`plural-${key}`)
20-
30+
// if TTL key provided, check if it's expired or not found
31+
if (ttl) {
32+
const timestamp = JSON.parse(localStorage.getItem(ttlKey) ?? 'null')
33+
if (
34+
!timestamp ||
35+
Date.now() - timestamp > (ttl.duration ?? DEFAULT_TTL_DURATION)
36+
)
37+
return defaultValue
38+
}
39+
const item = localStorage.getItem(itemKey)
2140
if (item) return parser(JSON.parse(item))
2241
} catch (error) {
2342
console.log('Error on localStorage.getItem of', key)
2443
}
2544

2645
return defaultValue
27-
}, [key, defaultValue, parser])
46+
}, [key, defaultValue, parser, ttl])
2847

29-
const [state, setState] = useState<T>(getLocalStorageValue())
48+
const [state, setState] = useState<T>(getInitialVal())
3049

3150
useEffect(() => {
32-
localStorage.setItem(`plural-${key}`, JSON.stringify(state))
33-
}, [key, state])
51+
localStorage.setItem(itemKey, JSON.stringify(state))
52+
if (ttlKey !== '') localStorage.setItem(ttlKey, JSON.stringify(Date.now()))
53+
}, [key, state, ttlKey])
3454

3555
return [state, setState]
3656
}

0 commit comments

Comments
 (0)