Skip to content

Commit

Permalink
refactor: [M3-8240] - Allow URL path to open OBJ create access key dr…
Browse files Browse the repository at this point in the history
…awer (linode#10749)

Co-authored-by: Jaalah Ramos <[email protected]>
Co-authored-by: Mariah Jacobs <[email protected]>
  • Loading branch information
3 people authored Aug 13, 2024
1 parent 55a2971 commit ec4bfed
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 62 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Tech Stories
---

Allow URL path to open OBJ Create Access Key drawer ([#10749](https://github.com/linode/manager/pull/10749))
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import {
ObjectStorageKey,
CreateObjectStorageKeyPayload,
UpdateObjectStorageKeyPayload,
createObjectStorageKeys,
revokeObjectStorageKey,
updateObjectStorageKey,
} from '@linode/api-v4/lib/object-storage';
import { FormikBag, FormikHelpers } from 'formik';
import * as React from 'react';

import { DocumentTitleSegment } from 'src/components/DocumentTitle';
Expand All @@ -31,9 +27,16 @@ import { AccessKeyDrawer } from './AccessKeyDrawer';
import { AccessKeyTable } from './AccessKeyTable/AccessKeyTable';
import { OMC_AccessKeyDrawer } from './OMC_AccessKeyDrawer';
import { RevokeAccessKeyDialog } from './RevokeAccessKeyDialog';
import { MODE, OpenAccessDrawer } from './types';
import ViewPermissionsDrawer from './ViewPermissionsDrawer';

import type { MODE, OpenAccessDrawer } from './types';
import type {
CreateObjectStorageKeyPayload,
ObjectStorageKey,
UpdateObjectStorageKeyPayload,
} from '@linode/api-v4/lib/object-storage';
import type { FormikBag, FormikHelpers } from 'formik';

interface Props {
accessDrawerOpen: boolean;
closeAccessDrawer: () => void;
Expand Down Expand Up @@ -85,7 +88,6 @@ export const AccessKeyLanding = (props: Props) => {

const displayKeysDialog = useOpenClose();
const revokeKeysDialog = useOpenClose();
const viewPermissionsDrawer = useOpenClose();
const flags = useFlags();
const { account } = useAccountManagement();

Expand Down Expand Up @@ -249,13 +251,8 @@ export const AccessKeyLanding = (props: Props) => {
objectStorageKey: ObjectStorageKey | null = null
) => {
setKeyToEdit(objectStorageKey);
switch (mode) {
case 'creating':
case 'editing':
openAccessDrawer(mode);
break;
case 'viewing':
viewPermissionsDrawer.open();
if (mode !== 'creating') {
openAccessDrawer(mode);
}
};

Expand Down Expand Up @@ -311,8 +308,8 @@ export const AccessKeyLanding = (props: Props) => {

<ViewPermissionsDrawer
objectStorageKey={keyToEdit}
onClose={viewPermissionsDrawer.close}
open={viewPermissionsDrawer.isOpen}
onClose={closeAccessDrawer}
open={mode === 'viewing' && accessDrawerOpen}
/>
<SecretTokenDialog
objectStorageKey={keyToDisplay}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,12 @@ export const ObjectStorageLanding = () => {
action?: 'create';
tab?: 'access-keys' | 'buckets';
}>();
const isCreateBucketOpen = tab === 'buckets' && action === 'create';

const {
_isRestrictedUser,
account,
accountSettings,
} = useAccountManagement();

const flags = useFlags();

const isObjMultiClusterEnabled = isFeatureEnabledV2(
Expand All @@ -68,62 +67,58 @@ export const ObjectStorageLanding = () => {

const userHasNoBucketCreated =
objectStorageBucketsResponse?.buckets.length === 0;
const createOrEditDrawer = useOpenClose();

const openDrawer = useOpenClose();

const tabs = [
{
routeName: `/object-storage/buckets`,
title: 'Buckets',
},
{
routeName: `/object-storage/access-keys`,
title: 'Access Keys',
},
{ routeName: `/object-storage/buckets`, title: 'Buckets' },
{ routeName: `/object-storage/access-keys`, title: 'Access Keys' },
];

const realTabs = ['buckets', 'access-keys'];

const openDrawer = (mode: MODE) => {
const handleOpenAccessDrawer = (mode: MODE) => {
setMode(mode);
createOrEditDrawer.open();
openDrawer.open();
};

const navToURL = (index: number) => {
history.push(tabs[index].routeName);
};
const navToURL = (index: number) => history.push(tabs[index].routeName);

const objPromotionalOffers = (
flags.promotionalOffers ?? []
).filter((promotionalOffer) =>
promotionalOffer.features.includes('Object Storage')
);
const objPromotionalOffers =
flags.promotionalOffers?.filter((offer) =>
offer.features.includes('Object Storage')
) ?? [];

// A user needs to explicitly cancel Object Storage in their Account Settings in order to stop
// being billed. If they have the service enabled but do not have any buckets, show a warning.
// Users must explicitly cancel Object Storage in their Account Settings to avoid being billed.
// Display a warning if the service is active but no buckets are present.
const shouldDisplayBillingNotice =
!areBucketsLoading &&
!bucketsErrors &&
userHasNoBucketCreated &&
accountSettings?.object_storage === 'active';

// No need to display header since the it is redundant with the docs and CTA of the empty state
// Meanwhile it will still display the header for the access keys tab at all times
const shouldHideDocsAndCreateButtons =
!areBucketsLoading && tab === 'buckets' && userHasNoBucketCreated;

const createButtonText =
tab === 'access-keys' ? 'Create Access Key' : 'Create Bucket';
const isAccessKeysTab = tab === 'access-keys';
const isCreateAction = action === 'create';

const createButtonText = isAccessKeysTab
? 'Create Access Key'
: 'Create Bucket';

const createButtonAction = () => {
if (tab === 'access-keys') {
if (isAccessKeysTab) {
setMode('creating');

return createOrEditDrawer.open();
history.replace('/object-storage/access-keys/create');
openDrawer.open();
} else {
history.replace('/object-storage/buckets/create');
}

history.replace('/object-storage/buckets/create');
};

const tabIndex = tab === 'access-keys' ? 1 : 0;
const isCreateBucketOpen = !isAccessKeysTab && isCreateAction;
const isCreateAccessKeyOpen = isAccessKeysTab && isCreateAction;

return (
<React.Fragment>
<DocumentTitleSegment segment="Object Storage" />
Expand All @@ -137,14 +132,7 @@ export const ObjectStorageLanding = () => {
shouldHideDocsAndCreateButtons={shouldHideDocsAndCreateButtons}
title="Object Storage"
/>
<Tabs
index={
realTabs.findIndex((t) => t === tab) !== -1
? realTabs.findIndex((t) => t === tab)
: 0
}
onChange={navToURL}
>
<Tabs index={tabIndex} onChange={navToURL}>
<TabLinkList tabs={tabs} />

{objPromotionalOffers.map((promotionalOffer) => (
Expand All @@ -166,11 +154,14 @@ export const ObjectStorageLanding = () => {
</SafeTabPanel>
<SafeTabPanel index={1}>
<AccessKeyLanding
accessDrawerOpen={createOrEditDrawer.isOpen}
closeAccessDrawer={createOrEditDrawer.close}
closeAccessDrawer={() => {
openDrawer.close();
history.replace('/object-storage/access-keys');
}}
accessDrawerOpen={isCreateAccessKeyOpen || openDrawer.isOpen}
isRestrictedUser={_isRestrictedUser}
mode={mode}
openAccessDrawer={openDrawer}
openAccessDrawer={handleOpenAccessDrawer}
/>
</SafeTabPanel>
</TabPanels>
Expand Down
7 changes: 5 additions & 2 deletions packages/manager/src/features/ObjectStorage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import * as React from 'react';
import { Route, RouteComponentProps, Switch } from 'react-router-dom';
import { Route, Switch } from 'react-router-dom';

import { ProductInformationBanner } from 'src/components/ProductInformationBanner/ProductInformationBanner';
import { SuspenseLoader } from 'src/components/SuspenseLoader';

import type { RouteComponentProps } from 'react-router-dom';

const ObjectStorageLanding = React.lazy(() =>
import('./ObjectStorageLanding').then((module) => ({
default: module.ObjectStorageLanding,
}))
);

const BucketDetail = React.lazy(() => import('./BucketDetail'));

type CombinedProps = RouteComponentProps;
Expand All @@ -26,7 +29,7 @@ export const ObjectStorage: React.FC<CombinedProps> = (props) => {
/>
<Route
component={ObjectStorageLanding}
path={'/object-storage/:tab?/:action?'}
path={`${path}/:tab?/:action?`}
/>
</Switch>
</React.Suspense>
Expand Down

0 comments on commit ec4bfed

Please sign in to comment.