Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Tech Stories
---

Improve getQueryParamsFromQueryString type safety ([#10645](https://github.com/linode/manager/pull/10645))
4 changes: 2 additions & 2 deletions packages/manager/src/components/OrderBy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
useMutatePreferences,
usePreferences,
} from 'src/queries/profile/preferences';
import { ManagerPreferences } from 'src/types/ManagerPreferences';
import { getQueryParamsFromQueryString } from 'src/utilities/queryParams';
import {
sortByArrayLength,
Expand All @@ -19,6 +18,7 @@ import {
} from 'src/utilities/sort-by';

import type { Order } from 'src/hooks/useOrder';
import type { ManagerPreferences } from 'src/types/ManagerPreferences';

export interface OrderByProps<T> extends State {
data: T[];
Expand Down Expand Up @@ -165,7 +165,7 @@ export const OrderBy = <T,>(props: CombinedProps<T>) => {
const initialValues = getInitialValuesFromUserPreferences(
props.preferenceKey ?? '',
preferences ?? {},
params as Record<string, string>,
params,
props.orderBy,
props.order
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Firewall, FirewallDeviceEntityType } from '@linode/api-v4';
import { styled } from '@mui/material/styles';
import * as React from 'react';
import { useLocation } from 'react-router-dom';
Expand All @@ -15,7 +14,8 @@ import { getQueryParamsFromQueryString } from 'src/utilities/queryParams';
import { Autocomplete } from '../Autocomplete/Autocomplete';
import { LinkButton } from '../LinkButton';

import type { LinodeCreateType } from 'src/features/Linodes/LinodesCreate/types';
import type { Firewall, FirewallDeviceEntityType } from '@linode/api-v4';
import type { LinodeCreateQueryParams } from 'src/features/Linodes/types';

interface Props {
disabled?: boolean;
Expand All @@ -37,15 +37,17 @@ export const SelectFirewallPanel = (props: Props) => {
const [isDrawerOpen, setIsDrawerOpen] = React.useState(false);
const location = useLocation();
const isFromLinodeCreate = location.pathname.includes('/linodes/create');
const queryParams = getQueryParamsFromQueryString(location.search);
const queryParams = getQueryParamsFromQueryString<LinodeCreateQueryParams>(
location.search
);

const handleCreateFirewallClick = () => {
setIsDrawerOpen(true);
if (isFromLinodeCreate) {
sendLinodeCreateFormStepEvent({
action: 'click',
category: 'button',
createType: (queryParams.type as LinodeCreateType) ?? 'Distributions',
createType: queryParams.type ?? 'Distributions',
formStepName: 'Firewall Panel',
label: 'Create Firewall',
version: 'v1',
Expand Down Expand Up @@ -91,8 +93,7 @@ export const SelectFirewallPanel = (props: Props) => {
sendLinodeCreateFormStepEvent({
action: 'click',
category: 'select',
createType:
(queryParams.type as LinodeCreateType) ?? 'Distributions',
createType: queryParams.type ?? 'Distributions',
formStepName: 'Firewall Panel',
label: 'Assign Firewall',
version: 'v1',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { useLocation } from 'react-router-dom';
import { Notice } from 'src/components/Notice/Notice';
import { Paper } from 'src/components/Paper';
import { RegionSelect } from 'src/components/RegionSelect/RegionSelect';
import { useIsGeckoEnabled } from 'src/components/RegionSelect/RegionSelect.utils';
import { isDistributedRegionSupported } from 'src/components/RegionSelect/RegionSelect.utils';
import { useIsGeckoEnabled } from 'src/components/RegionSelect/RegionSelect.utils';
import { TwoStepRegionSelect } from 'src/components/RegionSelect/TwoStepRegionSelect';
import { RegionHelperText } from 'src/components/SelectRegionPanel/RegionHelperText';
import { Typography } from 'src/components/Typography';
Expand All @@ -31,7 +31,7 @@ import { Link } from '../Link';

import type { RegionSelectProps } from '../RegionSelect/RegionSelect.types';
import type { Capabilities } from '@linode/api-v4/lib/regions';
import type { LinodeCreateType } from 'src/features/Linodes/LinodesCreate/types';
import type { LinodeCreateQueryParams } from 'src/features/Linodes/types';

export interface SelectRegionPanelProps {
RegionSelectProps?: Partial<RegionSelectProps<true>>;
Expand Down Expand Up @@ -66,7 +66,9 @@ export const SelectRegionPanel = (props: SelectRegionPanelProps) => {
const flags = useFlags();
const location = useLocation();
const theme = useTheme();
const params = getQueryParamsFromQueryString(location.search);
const params = getQueryParamsFromQueryString<LinodeCreateQueryParams>(
location.search
);

const { isGeckoGAEnabled } = useIsGeckoEnabled();

Expand Down Expand Up @@ -99,8 +101,7 @@ export const SelectRegionPanel = (props: SelectRegionPanelProps) => {
});

const hideDistributedRegions =
!flags.gecko2?.enabled ||
!isDistributedRegionSupported(params.type as LinodeCreateType);
!flags.gecko2?.enabled || !isDistributedRegionSupported(params.type);

const showDistributedRegionIconHelperText = Boolean(
!hideDistributedRegions &&
Expand All @@ -113,7 +114,7 @@ export const SelectRegionPanel = (props: SelectRegionPanelProps) => {
);

const disabledRegions = getDisabledRegions({
linodeCreateTab: params.type as LinodeCreateType,
linodeCreateTab: params.type,
regions: regions ?? [],
selectedImage: image,
});
Expand Down Expand Up @@ -151,7 +152,7 @@ export const SelectRegionPanel = (props: SelectRegionPanelProps) => {
sendLinodeCreateFormStepEvent({
action: 'click',
category: 'link',
createType: (params.type as LinodeCreateType) ?? 'Distributions',
createType: params.type ?? 'Distributions',
label: DOCS_LINK_LABEL_DC_PRICING,
version: 'v1',
})
Expand All @@ -177,8 +178,7 @@ export const SelectRegionPanel = (props: SelectRegionPanelProps) => {
</Typography>
</Notice>
) : null}
{isGeckoGAEnabled &&
isDistributedRegionSupported(params.type as LinodeCreateType) ? (
{isGeckoGAEnabled && isDistributedRegionSupported(params.type) ? (
<TwoStepRegionSelect
showDistributedRegionIconHelperText={
showDistributedRegionIconHelperText
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import type {
Linode,
NodeBalancer,
} from '@linode/api-v4';
import type { LinodeCreateType } from 'src/features/Linodes/LinodesCreate/types';
import type { LinodeCreateQueryParams } from 'src/features/Linodes/types';

export const READ_ONLY_DEVICES_HIDDEN_MESSAGE =
'Only services you have permission to modify are shown.';
Expand Down Expand Up @@ -80,7 +80,9 @@ export const CreateFirewallDrawer = React.memo(

const location = useLocation();
const isFromLinodeCreate = location.pathname.includes('/linodes/create');
const queryParams = getQueryParamsFromQueryString(location.search);
const queryParams = getQueryParamsFromQueryString<LinodeCreateQueryParams>(
location.search
);

const {
errors,
Expand Down Expand Up @@ -224,8 +226,7 @@ export const CreateFirewallDrawer = React.memo(
sendLinodeCreateFormStepEvent({
action: 'click',
category: 'link',
createType:
(queryParams.type as LinodeCreateType) ?? 'Distributions',
createType: queryParams.type ?? 'Distributions',
formStepName: 'Create Firewall Drawer',
label: 'Learn more',
version: 'v1',
Expand Down Expand Up @@ -379,8 +380,7 @@ export const CreateFirewallDrawer = React.memo(
sendLinodeCreateFormStepEvent({
action: 'click',
category: 'button',
createType:
(queryParams.type as LinodeCreateType) ?? 'Distributions',
createType: queryParams.type ?? 'Distributions',
formStepName: 'Create Firewall Drawer',
label: 'Create Firewall',
version: 'v1',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,16 @@ import { useRegionsQuery } from 'src/queries/regions/regions';
import { getQueryParamsFromQueryString } from 'src/utilities/queryParams';

import type { CreateImagePayload } from '@linode/api-v4';
import type { LinodeConfigAndDiskQueryParams } from 'src/features/Linodes/types';

export const CreateImageTab = () => {
const location = useLocation();

const queryParams = React.useMemo(
() => getQueryParamsFromQueryString(location.search),
() =>
getQueryParamsFromQueryString<LinodeConfigAndDiskQueryParams>(
location.search
),
[location.search]
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import {
Disk,
Linode,
cloneLinode,
cloneLinodeDisk,
} from '@linode/api-v4/lib/linodes';
import { APIError } from '@linode/api-v4/lib/types';
import Grid from '@mui/material/Unstable_Grid2';
import { cloneLinode, cloneLinodeDisk } from '@linode/api-v4/lib/linodes';
import { useTheme } from '@mui/material/styles';
import Grid from '@mui/material/Unstable_Grid2';
import { castDraft } from 'immer';
import { intersection, pathOr } from 'ramda';
import * as React from 'react';
Expand Down Expand Up @@ -46,6 +40,10 @@ import {
defaultState,
} from './utilities';

import type { Disk, Linode } from '@linode/api-v4/lib/linodes';
import type { APIError } from '@linode/api-v4/lib/types';
import type { LinodeConfigAndDiskQueryParams } from 'src/features/Linodes/types';

const Configs = React.lazy(() => import('./Configs'));
const Disks = React.lazy(() => import('./Disks'));
const LinodesDetailHeader = React.lazy(
Expand Down Expand Up @@ -126,7 +124,10 @@ const CloneLanding = () => {
// A config and/or disk can be selected via query param. Memoized
// so it can be used as a dep in the useEffects that consume it.
const queryParams = React.useMemo(
() => getQueryParamsFromQueryString(location.search),
() =>
getQueryParamsFromQueryString<LinodeConfigAndDiskQueryParams>(
location.search
),
[location.search]
);

Expand Down
Loading