Skip to content

Commit

Permalink
Merge pull request #9345 from linode/staging
Browse files Browse the repository at this point in the history
Release v1.96.2 - `staging` → `master`
  • Loading branch information
jaalah-akamai authored Jun 29, 2023
2 parents 7943375 + 9a9d04e commit d4f1eee
Show file tree
Hide file tree
Showing 62 changed files with 437 additions and 1,437 deletions.
11 changes: 10 additions & 1 deletion packages/manager/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,17 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).

## [2023-06-27] - v1.96.1
## [2023-06-29] - v1.96.2

### Fixed:
- Issue where Cloud Manager was not displaying all linodes capable of being "cloned" ([#9294](https://github.com/linode/manager/pull/9294))
- Firewall custom ports validation w/ unit tests ([#9336](https://github.com/linode/manager/pull/9336))

### Tech Stories:

- React Query - Linodes - General Refactors ([#9294](https://github.com/linode/manager/pull/9294))

## [2023-06-27] - v1.96.1

### Fixed:

Expand Down
2 changes: 1 addition & 1 deletion packages/manager/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "linode-manager",
"author": "Linode",
"description": "The Linode Manager website",
"version": "1.96.1",
"version": "1.96.2",
"private": true,
"bugs": {
"url": "https://github.com/Linode/manager/issues"
Expand Down
16 changes: 0 additions & 16 deletions packages/manager/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import { ADOBE_ANALYTICS_URL, NUM_ADOBE_SCRIPTS } from './constants';
import { reportException } from './exceptionReporting';
import { useAuthentication } from './hooks/useAuthentication';
import useFeatureFlagsLoad from './hooks/useFeatureFlagLoad';
import useLinodes from './hooks/useLinodes';
import { loadScript } from './hooks/useScript';
import { oauthClientsEventHandler } from './queries/accountOAuth';
import { databaseEventsHandler } from './queries/databases';
Expand Down Expand Up @@ -59,12 +58,6 @@ const BaseApp = withFeatureFlagProvider(

const { enqueueSnackbar } = useSnackbar();

const {
linodes: {
error: { read: linodesError },
},
} = useLinodes();

const [goToOpen, setGoToOpen] = React.useState(false);

const theme = preferences?.theme;
Expand Down Expand Up @@ -263,15 +256,6 @@ const BaseApp = withFeatureFlagProvider(
};
}, [handleMigrationEvent]);

/**
* in the event that we encounter an "invalid OAuth token" error from the API,
* we can simply refrain from rendering any content since the user will
* imminently be redirected to the login page.
*/
if (hasOauthError(linodesError)) {
return null;
}

return (
<ErrorBoundary fallback={<TheApplicationIsOnFire />}>
{/** Accessibility helper */}
Expand Down
121 changes: 35 additions & 86 deletions packages/manager/src/containers/withLinodes.container.ts
Original file line number Diff line number Diff line change
@@ -1,91 +1,40 @@
import { Linode } from '@linode/api-v4/lib/linodes';
import { APIError, Filter, Params } from '@linode/api-v4/lib/types';
import { path } from 'ramda';
import { connect, InferableComponentEnhancerWithProps } from 'react-redux';
import { ApplicationState } from 'src/store';
import { requestLinodes } from 'src/store/linodes/linode.requests';
import { State } from 'src/store/linodes/linodes.reducer';
import { LinodeWithMaintenanceAndDisplayStatus } from 'src/store/linodes/types';
import { ThunkDispatch } from 'src/store/types';
import { GetAllData } from 'src/utilities/getAll';

export interface DispatchProps {
getLinodes: (
params?: Params,
filters?: Filter
) => Promise<GetAllData<Linode>>;
import React from 'react';
import { CreateLinodeRequest, Linode } from '@linode/api-v4/lib/linodes';
import { APIError } from '@linode/api-v4/lib/types';
import {
useAllLinodesQuery,
useCreateLinodeMutation,
} from 'src/queries/linodes/linodes';

interface Actions {
createLinode: (data: CreateLinodeRequest) => Promise<Linode>;
}

/* tslint:disable-next-line */
export interface StateProps {
linodesError?: APIError[];
linodesLoading: State['loading'];
linodesData: LinodeWithMaintenanceAndDisplayStatus[];
linodesLastUpdated: State['lastUpdated'];
linodesResults: State['results'];
export interface WithLinodesProps {
linodesError: APIError[] | null;
linodesLoading: boolean;
linodesData: Linode[] | undefined;
linodeActions: Actions;
}

type MapProps<ReduxStateProps, OwnProps> = (
ownProps: OwnProps,
linodes: Linode[],
loading: boolean,
error?: APIError[]
) => ReduxStateProps & Partial<StateProps>;

export type Props = DispatchProps & StateProps;

interface Connected {
<ReduxStateProps, OwnProps>(
mapStateToProps: MapProps<ReduxStateProps, OwnProps>
): InferableComponentEnhancerWithProps<
ReduxStateProps & Partial<StateProps> & DispatchProps & OwnProps,
OwnProps
>;
<ReduxStateProps, OwnProps>(): InferableComponentEnhancerWithProps<
ReduxStateProps & DispatchProps & OwnProps,
OwnProps
>;
}

const connected: Connected = <ReduxState extends {}, OwnProps extends {}>(
mapStateToProps?: MapProps<ReduxState, OwnProps>
) =>
connect<
(ReduxState & Partial<StateProps>) | StateProps,
DispatchProps,
OwnProps,
ApplicationState
>(
(state, ownProps) => {
const {
loading,
error,
itemsById,
lastUpdated,
results,
} = state.__resources.linodes;
const linodes = Object.values(itemsById);
if (mapStateToProps) {
return mapStateToProps(
ownProps,
linodes,
loading,
path(['read'], error)
);
}

return {
linodesError: path(['read'], error),
linodesLoading: loading,
linodesData: linodes,
linodesResults: results,
linodesLastUpdated: lastUpdated,
};
export const withLinodes = <Props>(
Component: React.ComponentType<Props & WithLinodesProps>
) => (props: Props) => {
const {
data: linodesData,
isLoading: linodesLoading,
error: linodesError,
} = useAllLinodesQuery();

const { mutateAsync: createLinode } = useCreateLinodeMutation();

return React.createElement(Component, {
...props,
linodesData,
linodesLoading,
linodesError,
linodeActions: {
createLinode,
},
(dispatch: ThunkDispatch) => ({
getLinodes: (params, filter) =>
dispatch(requestLinodes({ params, filter })),
})
);

export default connected;
});
};
26 changes: 8 additions & 18 deletions packages/manager/src/features/Account/EnableManaged.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,20 @@ import Typography from 'src/components/core/Typography';
import ExternalLink from 'src/components/ExternalLink';
import Grid from '@mui/material/Unstable_Grid2';
import { SupportLink } from 'src/components/SupportLink';
import withLinodes, {
DispatchProps,
} from 'src/containers/withLinodes.container';
import { pluralize } from 'src/utilities/pluralize';
import { updateAccountSettingsData } from 'src/queries/accountSettings';
import { useQueryClient } from 'react-query';
import { useLinodesQuery } from 'src/queries/linodes/linodes';

interface Props {
isManaged: boolean;
}

interface StateProps {
linodeCount: number;
}

type CombinedProps = Props & StateProps & DispatchProps;

interface ContentProps {
isManaged: boolean;
openConfirmationModal: () => void;
}

export const ManagedContent = (props: ContentProps) => {
const { isManaged, openConfirmationModal } = props;

Expand Down Expand Up @@ -66,13 +59,16 @@ export const ManagedContent = (props: ContentProps) => {
);
};

export const EnableManaged = (props: CombinedProps) => {
const { isManaged, linodeCount } = props;
export const EnableManaged = (props: Props) => {
const { isManaged } = props;
const queryClient = useQueryClient();
const { data: linodes } = useLinodesQuery();
const [isOpen, setOpen] = React.useState<boolean>(false);
const [error, setError] = React.useState<string | undefined>();
const [isLoading, setLoading] = React.useState<boolean>(false);

const linodeCount = linodes?.results ?? 0;

const handleClose = () => {
setOpen(false);
setError(undefined);
Expand All @@ -94,7 +90,7 @@ export const EnableManaged = (props: CombinedProps) => {
.catch(handleError);
};

const actions = () => (
const actions = (
<ActionsPanel>
<Button buttonType="secondary" onClick={handleClose} data-qa-cancel>
Cancel
Expand Down Expand Up @@ -137,9 +133,3 @@ export const EnableManaged = (props: CombinedProps) => {
</>
);
};

export default withLinodes<StateProps, Props>(
(ownProps, entities, loading, error) => ({
linodeCount: entities.length,
})
)(EnableManaged);
41 changes: 14 additions & 27 deletions packages/manager/src/features/Account/GlobalSettings.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,35 @@
import { Linode } from '@linode/api-v4/lib/linodes';
import { APIError } from '@linode/api-v4/lib/types';
import { useSnackbar } from 'notistack';
import { isEmpty } from 'ramda';
import * as React from 'react';
import { connect, MapDispatchToProps } from 'react-redux';
import { RouteComponentProps } from 'react-router-dom';
import { compose } from 'recompose';
import { AnyAction } from 'redux';
import { ThunkDispatch } from 'redux-thunk';
import { CircleProgress } from 'src/components/CircleProgress';
import { ErrorState } from 'src/components/ErrorState/ErrorState';
import { useReduxLoad } from 'src/hooks/useReduxLoad';
import { ApplicationState } from 'src/store';
import { handleOpen } from 'src/store/backupDrawer';
import { getLinodesWithoutBackups } from 'src/store/selectors/getLinodesWithBackups';
import { MapState } from 'src/store/types';
import { getAPIErrorOrDefault } from 'src/utilities/errorUtils';
import AutoBackups from './AutoBackups';
import EnableManaged from './EnableManaged';
import { EnableManaged } from './EnableManaged';
import EnableObjectStorage from './EnableObjectStorage';
import NetworkHelper from './NetworkHelper';
import CloseAccountSetting from './CloseAccountSetting';
import {
useAccountSettings,
useMutateAccountSettings,
} from 'src/queries/accountSettings';
import { useAllLinodesQuery } from 'src/queries/linodes/linodes';

interface StateProps {
linodesWithoutBackups: Linode[];
}

interface DispatchProps {
interface Props {
actions: {
openBackupsDrawer: () => void;
};
}

type CombinedProps = StateProps & DispatchProps & RouteComponentProps<{}>;

const GlobalSettings = (props: CombinedProps) => {
const GlobalSettings = (props: Props) => {
const {
actions: { openBackupsDrawer },
linodesWithoutBackups,
} = props;

const {
Expand All @@ -50,12 +38,15 @@ const GlobalSettings = (props: CombinedProps) => {
error: accountSettingsError,
} = useAccountSettings();

const { data: linodes } = useAllLinodesQuery();

const linodesWithoutBackups =
linodes?.filter((linode) => !linode.backups.enabled) ?? [];

const { enqueueSnackbar } = useSnackbar();

const { mutateAsync: updateAccount } = useMutateAccountSettings();

const { _loading } = useReduxLoad(['linodes']);

const displayError = (errors: APIError[] | undefined) => {
if (!errors) {
return;
Expand All @@ -70,9 +61,10 @@ const GlobalSettings = (props: CombinedProps) => {
});
};

if (accountSettingsLoading || _loading) {
if (accountSettingsLoading) {
return <CircleProgress />;
}

if (accountSettingsError) {
return (
<ErrorState
Expand Down Expand Up @@ -119,11 +111,8 @@ const GlobalSettings = (props: CombinedProps) => {
</div>
);
};
const mapStateToProps: MapState<StateProps, {}> = (state) => ({
linodesWithoutBackups: getLinodesWithoutBackups(state.__resources),
});

const mapDispatchToProps: MapDispatchToProps<DispatchProps, {}> = (
const mapDispatchToProps: MapDispatchToProps<Props, {}> = (
dispatch: ThunkDispatch<ApplicationState, undefined, AnyAction>
) => {
return {
Expand All @@ -133,8 +122,6 @@ const mapDispatchToProps: MapDispatchToProps<DispatchProps, {}> = (
};
};

const connected = connect(mapStateToProps, mapDispatchToProps);

const enhanced = compose<CombinedProps, {}>(connected)(GlobalSettings);
const connected = connect(undefined, mapDispatchToProps);

export default enhanced;
export default connected(GlobalSettings);
Loading

0 comments on commit d4f1eee

Please sign in to comment.