From fc34a43dd0efb83e175d1d1699be91540441182d Mon Sep 17 00:00:00 2001 From: Maxim Chervonny Date: Tue, 19 Jan 2021 12:27:22 +0300 Subject: [PATCH 1/8] add link to bucketS settings page --- catalog/app/containers/Bucket/Overview.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/catalog/app/containers/Bucket/Overview.js b/catalog/app/containers/Bucket/Overview.js index 683b5164c4d..d4911d88c2a 100644 --- a/catalog/app/containers/Bucket/Overview.js +++ b/catalog/app/containers/Bucket/Overview.js @@ -2,6 +2,7 @@ import cx from 'classnames' import * as dateFns from 'date-fns' import * as R from 'ramda' import * as React from 'react' +import { Link as RRLink } from 'react-router-dom' import * as M from '@material-ui/core' import { fade } from '@material-ui/core/styles' import useComponentSize from '@rehooks/component-size' @@ -751,6 +752,12 @@ const useHeadStyles = M.makeStyles((t) => ({ borderRadius: 0, }, }, + settings: { + color: t.palette.common.white, + position: 'absolute', + right: t.spacing(2), + top: t.spacing(2), + }, })) function Head({ req, s3, overviewUrl, bucket, description }) { @@ -759,6 +766,7 @@ function Head({ req, s3, overviewUrl, bucket, description }) { const colorPool = useConst(() => mkKeyedPool(COLOR_MAP)) const statsData = useData(requests.bucketStats, { req, s3, bucket, overviewUrl }) const pkgCountData = useData(requests.countPackageRevisions, { req, bucket }) + const { urls } = NamedRoutes.use() return ( @@ -804,6 +812,11 @@ function Head({ req, s3, overviewUrl, bucket, description }) { fallback={() => null} /> + + + settings + + Date: Tue, 19 Jan 2021 15:01:20 +0300 Subject: [PATCH 2/8] navigate to admin bucket --- catalog/app/constants/routes.js | 2 +- catalog/app/containers/Admin/Admin.js | 2 +- catalog/app/containers/Admin/Buckets.js | 22 ++++++++++++++++++++++ catalog/app/containers/Bucket/Overview.js | 2 +- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/catalog/app/constants/routes.js b/catalog/app/constants/routes.js index a5afdc78f14..c7e44cfcf66 100644 --- a/catalog/app/constants/routes.js +++ b/catalog/app/constants/routes.js @@ -144,5 +144,5 @@ export const admin = { export const adminUsers = admin export const adminBuckets = { path: '/admin/buckets', - url: () => '/admin/buckets', + url: (bucket) => (bucket ? `/admin/buckets${mkSearch({ bucket })}` : '/admin/buckets'), } diff --git a/catalog/app/containers/Admin/Admin.js b/catalog/app/containers/Admin/Admin.js index 32c8052ac35..c1d651a143f 100644 --- a/catalog/app/containers/Admin/Admin.js +++ b/catalog/app/containers/Admin/Admin.js @@ -84,7 +84,7 @@ export default function Admin({ location }) { - + diff --git a/catalog/app/containers/Admin/Buckets.js b/catalog/app/containers/Admin/Buckets.js index 843a3dff158..958e1c067a7 100644 --- a/catalog/app/containers/Admin/Buckets.js +++ b/catalog/app/containers/Admin/Buckets.js @@ -2,6 +2,7 @@ import * as dateFns from 'date-fns' import * as R from 'ramda' import * as React from 'react' import * as redux from 'react-redux' +import { useHistory } from 'react-router-dom' import * as RF from 'redux-form/es/immutable' import * as M from '@material-ui/core' @@ -13,7 +14,9 @@ import * as BucketConfig from 'utils/BucketConfig' import * as Config from 'utils/Config' import Delay from 'utils/Delay' import * as Dialogs from 'utils/Dialogs' +import * as NamedRoutes from 'utils/NamedRoutes' import * as Cache from 'utils/ResourceCache' +import { useRoute } from 'utils/router' import { useTracker } from 'utils/tracking' import * as validators from 'utils/validators' @@ -843,6 +846,10 @@ function CRUD({ buckets }) { }) const { open: openDialog, render: renderDialogs } = Dialogs.use() + const { paths, urls } = NamedRoutes.use() + const { location, match } = useRoute(paths.adminBuckets) + const history = useHistory() + const toolbarActions = [ { title: 'Add bucket', @@ -871,9 +878,24 @@ function CRUD({ buckets }) { }, ] + const openedBucket = React.useMemo(() => { + if (match && location.query && location.query.bucket) { + return rows.find(({ name }) => name === location.query.bucket) + } + return null + }, [match, location, rows]) + + const onBucketClose = React.useCallback(() => { + history.push(urls.adminBuckets()) + }, [history, urls]) + return ( {renderDialogs({ maxWidth: 'xs', fullWidth: true })} + + {openedBucket && } + + diff --git a/catalog/app/containers/Bucket/Overview.js b/catalog/app/containers/Bucket/Overview.js index d4911d88c2a..ac76f7e548b 100644 --- a/catalog/app/containers/Bucket/Overview.js +++ b/catalog/app/containers/Bucket/Overview.js @@ -812,7 +812,7 @@ function Head({ req, s3, overviewUrl, bucket, description }) { fallback={() => null} /> - + settings From 63dd2601029475eafd8c4af4c8adb0a163dd86aa Mon Sep 17 00:00:00 2001 From: Maxim Chervonny Date: Tue, 19 Jan 2021 15:12:01 +0300 Subject: [PATCH 3/8] fix max rows attribute --- catalog/app/containers/Admin/Buckets.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/catalog/app/containers/Admin/Buckets.js b/catalog/app/containers/Admin/Buckets.js index 958e1c067a7..9cf7ef98380 100644 --- a/catalog/app/containers/Admin/Buckets.js +++ b/catalog/app/containers/Admin/Buckets.js @@ -199,7 +199,7 @@ function BucketFields({ add = false, reindex }) { margin="normal" multiline rows={1} - maxRows={3} + rowsMax={3} /> Date: Tue, 19 Jan 2021 15:15:12 +0300 Subject: [PATCH 4/8] show/close Edit dialog on query change --- catalog/app/containers/Admin/Buckets.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/catalog/app/containers/Admin/Buckets.js b/catalog/app/containers/Admin/Buckets.js index 9cf7ef98380..37d0d61dd44 100644 --- a/catalog/app/containers/Admin/Buckets.js +++ b/catalog/app/containers/Admin/Buckets.js @@ -860,8 +860,9 @@ function CRUD({ buckets }) { }, ] - const edit = (bucket) => () => - openDialog(({ close }) => ) + const edit = (bucket) => () => { + history.push(urls.adminBuckets(bucket.name)) + } const inlineActions = (bucket) => [ { @@ -878,7 +879,7 @@ function CRUD({ buckets }) { }, ] - const openedBucket = React.useMemo(() => { + const editingBucket = React.useMemo(() => { if (match && location.query && location.query.bucket) { return rows.find(({ name }) => name === location.query.bucket) } @@ -892,8 +893,8 @@ function CRUD({ buckets }) { return ( {renderDialogs({ maxWidth: 'xs', fullWidth: true })} - - {openedBucket && } + + {editingBucket && } From 10c1b2f4a0f5aed88f90633e01d45b2ff6a6fd9c Mon Sep 17 00:00:00 2001 From: Maxim Chervonny Date: Tue, 19 Jan 2021 17:11:58 +0300 Subject: [PATCH 5/8] simplify getting route query --- catalog/app/constants/routes.js | 2 +- catalog/app/containers/Admin/Buckets.js | 25 ++++++++++++------------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/catalog/app/constants/routes.js b/catalog/app/constants/routes.js index c7e44cfcf66..d7c6ec6dc3f 100644 --- a/catalog/app/constants/routes.js +++ b/catalog/app/constants/routes.js @@ -144,5 +144,5 @@ export const admin = { export const adminUsers = admin export const adminBuckets = { path: '/admin/buckets', - url: (bucket) => (bucket ? `/admin/buckets${mkSearch({ bucket })}` : '/admin/buckets'), + url: (bucket) => `/admin/buckets${mkSearch({ bucket })}`, } diff --git a/catalog/app/containers/Admin/Buckets.js b/catalog/app/containers/Admin/Buckets.js index 37d0d61dd44..a64a891698f 100644 --- a/catalog/app/containers/Admin/Buckets.js +++ b/catalog/app/containers/Admin/Buckets.js @@ -15,8 +15,8 @@ import * as Config from 'utils/Config' import Delay from 'utils/Delay' import * as Dialogs from 'utils/Dialogs' import * as NamedRoutes from 'utils/NamedRoutes' +import parseSearch from 'utils/parseSearch' import * as Cache from 'utils/ResourceCache' -import { useRoute } from 'utils/router' import { useTracker } from 'utils/tracking' import * as validators from 'utils/validators' @@ -838,7 +838,7 @@ const columns = [ }, ] -function CRUD({ buckets }) { +function CRUD({ bucketName, buckets }) { const rows = Cache.suspend(buckets) const ordering = Table.useOrdering({ rows, column: columns[0] }) const pagination = Pagination.use(ordering.ordered, { @@ -846,8 +846,7 @@ function CRUD({ buckets }) { }) const { open: openDialog, render: renderDialogs } = Dialogs.use() - const { paths, urls } = NamedRoutes.use() - const { location, match } = useRoute(paths.adminBuckets) + const { urls } = NamedRoutes.use() const history = useHistory() const toolbarActions = [ @@ -879,12 +878,10 @@ function CRUD({ buckets }) { }, ] - const editingBucket = React.useMemo(() => { - if (match && location.query && location.query.bucket) { - return rows.find(({ name }) => name === location.query.bucket) - } - return null - }, [match, location, rows]) + const editingBucket = React.useMemo( + () => (bucketName ? rows.find(({ name }) => name === bucketName) : null), + [bucketName, rows], + ) const onBucketClose = React.useCallback(() => { history.push(urls.adminBuckets()) @@ -893,7 +890,8 @@ function CRUD({ buckets }) { return ( {renderDialogs({ maxWidth: 'xs', fullWidth: true })} - + + {editingBucket && } @@ -931,7 +929,8 @@ function CRUD({ buckets }) { ) } -export default function Buckets() { +export default function Buckets({ location }) { + const { bucket } = parseSearch(location.search) const req = APIConnector.use() const buckets = Cache.useData(data.BucketsResource, { req }) return ( @@ -944,7 +943,7 @@ export default function Buckets() { } > - + ) From 08448808b69047d8d613ea578acadd16bd4fdba5 Mon Sep 17 00:00:00 2001 From: Maxim Chervonny Date: Wed, 20 Jan 2021 11:02:15 +0300 Subject: [PATCH 6/8] revert route path comparison --- catalog/app/containers/Admin/Admin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/catalog/app/containers/Admin/Admin.js b/catalog/app/containers/Admin/Admin.js index c1d651a143f..32c8052ac35 100644 --- a/catalog/app/containers/Admin/Admin.js +++ b/catalog/app/containers/Admin/Admin.js @@ -84,7 +84,7 @@ export default function Admin({ location }) { - + From cd52ea46fdfbc50f69681e6022b0acd8dd65e407 Mon Sep 17 00:00:00 2001 From: Maxim Chervonny Date: Thu, 21 Jan 2021 16:06:46 +0300 Subject: [PATCH 7/8] restrict admin link to admin users --- catalog/app/containers/Bucket/Overview.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/catalog/app/containers/Bucket/Overview.js b/catalog/app/containers/Bucket/Overview.js index ac76f7e548b..36102431017 100644 --- a/catalog/app/containers/Bucket/Overview.js +++ b/catalog/app/containers/Bucket/Overview.js @@ -3,6 +3,7 @@ import * as dateFns from 'date-fns' import * as R from 'ramda' import * as React from 'react' import { Link as RRLink } from 'react-router-dom' +import * as redux from 'react-redux' import * as M from '@material-ui/core' import { fade } from '@material-ui/core/styles' import useComponentSize from '@rehooks/component-size' @@ -13,6 +14,7 @@ import * as Preview from 'components/Preview' import Skeleton from 'components/Skeleton' import StackedAreaChart from 'components/StackedAreaChart' import Thumbnail from 'components/Thumbnail' +import * as authSelectors from 'containers/Auth/selectors' import * as AWS from 'utils/AWS' import AsyncResult from 'utils/AsyncResult' import * as BucketConfig from 'utils/BucketConfig' @@ -767,6 +769,7 @@ function Head({ req, s3, overviewUrl, bucket, description }) { const statsData = useData(requests.bucketStats, { req, s3, bucket, overviewUrl }) const pkgCountData = useData(requests.countPackageRevisions, { req, bucket }) const { urls } = NamedRoutes.use() + const isAdmin = redux.useSelector(authSelectors.isAdmin) return ( @@ -812,11 +815,13 @@ function Head({ req, s3, overviewUrl, bucket, description }) { fallback={() => null} /> - - - settings - - + {isAdmin && ( + + + settings + + + )} Date: Thu, 21 Jan 2021 16:17:56 +0300 Subject: [PATCH 8/8] redirect to root buckets list --- catalog/app/containers/Admin/Buckets.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/catalog/app/containers/Admin/Buckets.js b/catalog/app/containers/Admin/Buckets.js index a64a891698f..7d98246e177 100644 --- a/catalog/app/containers/Admin/Buckets.js +++ b/catalog/app/containers/Admin/Buckets.js @@ -2,7 +2,7 @@ import * as dateFns from 'date-fns' import * as R from 'ramda' import * as React from 'react' import * as redux from 'react-redux' -import { useHistory } from 'react-router-dom' +import { Redirect, useHistory } from 'react-router-dom' import * as RF from 'redux-form/es/immutable' import * as M from '@material-ui/core' @@ -887,6 +887,11 @@ function CRUD({ bucketName, buckets }) { history.push(urls.adminBuckets()) }, [history, urls]) + if (bucketName && !editingBucket) { + // Bucket name set in URL, but it was not found in buckets list + return + } + return ( {renderDialogs({ maxWidth: 'xs', fullWidth: true })}