From f57223024adff8629f155ac719720fab38f4df64 Mon Sep 17 00:00:00 2001 From: James Date: Mon, 13 Dec 2021 14:09:13 -0500 Subject: [PATCH] feat: allows selection of revisions in certain locales to compare --- .../elements/ReactSelect/index.scss | 3 ++ .../views/Revision/Compare/index.scss | 4 ++ .../views/Revision/Compare/index.tsx | 33 ++++++++++-- .../views/Revision/Compare/types.ts | 10 ++-- .../views/Revision/Restore/index.scss | 20 +++++++ .../views/Revision/Restore/index.tsx | 54 +++++++++++++++++++ .../views/Revision/Restore/types.ts | 8 +++ .../views/Revision/SelectLocales/index.scss | 9 ++++ .../views/Revision/SelectLocales/index.tsx | 24 +++++++++ .../views/Revision/SelectLocales/types.ts | 7 +++ .../components/views/Revision/index.scss | 35 +++++++++++- src/admin/components/views/Revision/index.tsx | 29 +++++++--- src/admin/components/views/Revision/shared.ts | 4 ++ src/admin/components/views/Revision/types.ts | 12 +++++ 14 files changed, 233 insertions(+), 19 deletions(-) create mode 100644 src/admin/components/views/Revision/Restore/index.scss create mode 100644 src/admin/components/views/Revision/Restore/index.tsx create mode 100644 src/admin/components/views/Revision/Restore/types.ts create mode 100644 src/admin/components/views/Revision/SelectLocales/index.scss create mode 100644 src/admin/components/views/Revision/SelectLocales/index.tsx create mode 100644 src/admin/components/views/Revision/SelectLocales/types.ts create mode 100644 src/admin/components/views/Revision/shared.ts diff --git a/src/admin/components/elements/ReactSelect/index.scss b/src/admin/components/elements/ReactSelect/index.scss index d56ccc0f05..ef8b6dabb5 100644 --- a/src/admin/components/elements/ReactSelect/index.scss +++ b/src/admin/components/elements/ReactSelect/index.scss @@ -10,6 +10,7 @@ div.react-select { .rs__value-container { padding: base(.25) 0; + min-height: base(1.5); > * { margin-top: 0; @@ -20,6 +21,8 @@ div.react-select { &--is-multi { margin-left: - base(.25); + padding-top: 0; + padding-bottom: 0; } } diff --git a/src/admin/components/views/Revision/Compare/index.scss b/src/admin/components/views/Revision/Compare/index.scss index 2c1efe3067..259e890e17 100644 --- a/src/admin/components/views/Revision/Compare/index.scss +++ b/src/admin/components/views/Revision/Compare/index.scss @@ -8,4 +8,8 @@ background-color: $color-red; color: white; } + + &__label { + margin-bottom: base(.25); + } } diff --git a/src/admin/components/views/Revision/Compare/index.tsx b/src/admin/components/views/Revision/Compare/index.tsx index 7a37fe4c6a..70d15b933d 100644 --- a/src/admin/components/views/Revision/Compare/index.tsx +++ b/src/admin/components/views/Revision/Compare/index.tsx @@ -1,9 +1,11 @@ import React, { useState, useCallback, useEffect } from 'react'; +import qs from 'qs'; import { useConfig } from '@payloadcms/config-provider'; import format from 'date-fns/format'; import { Props } from './types'; import ReactSelect from '../../../elements/ReactSelect'; import { PaginatedDocs } from '../../../../../mongoose/types'; +import { publishedVersionOption } from '../shared'; import './index.scss'; @@ -11,8 +13,12 @@ const baseClass = 'compare-revision'; const maxResultsPerRequest = 10; +const baseOptions = [ + publishedVersionOption, +]; + const CompareRevision: React.FC = (props) => { - const { onChange, value, baseURL } = props; + const { onChange, value, baseURL, parentID } = props; const { admin: { @@ -20,14 +26,30 @@ const CompareRevision: React.FC = (props) => { }, } = useConfig(); - const [options, setOptions] = useState([]); + const [options, setOptions] = useState(baseOptions); const [lastLoadedPage, setLastLoadedPage] = useState(1); const [errorLoading, setErrorLoading] = useState(''); const getResults = useCallback(async ({ lastLoadedPage: lastLoadedPageArg, } = {}) => { - const response = await fetch(`${baseURL}?limit=${maxResultsPerRequest}&page=${lastLoadedPageArg}&depth=0`); + const query = { + limit: maxResultsPerRequest, + page: lastLoadedPageArg, + depth: 0, + where: undefined, + }; + + if (parentID) { + query.where = { + parent: { + equals: parentID, + }, + }; + } + + const search = qs.stringify(query); + const response = await fetch(`${baseURL}?${search}`); if (response.ok) { const data: PaginatedDocs = await response.json(); @@ -44,7 +66,7 @@ const CompareRevision: React.FC = (props) => { } else { setErrorLoading('An error has occurred.'); } - }, [dateFormat, baseURL]); + }, [dateFormat, baseURL, parentID]); const classes = [ 'field-type', @@ -58,6 +80,9 @@ const CompareRevision: React.FC = (props) => { return (
+
+ Compare revision against: +
{!errorLoading && ( void, - value: Option, + value: CompareOption, baseURL: string + parentID?: string } -export type Option = { - label: string - value: string - relationTo?: string - options?: Option[] -} type CLEAR = { type: 'CLEAR' diff --git a/src/admin/components/views/Revision/Restore/index.scss b/src/admin/components/views/Revision/Restore/index.scss new file mode 100644 index 0000000000..d399eef8a0 --- /dev/null +++ b/src/admin/components/views/Revision/Restore/index.scss @@ -0,0 +1,20 @@ +@import '../../../../scss/styles.scss'; + +.restore-revision { + cursor: pointer; + + &__modal { + @include blur-bg; + display: flex; + align-items: center; + height: 100%; + + &__toggle { + @extend %btn-reset; + } + + .btn { + margin-right: $baseline; + } + } +} diff --git a/src/admin/components/views/Revision/Restore/index.tsx b/src/admin/components/views/Revision/Restore/index.tsx new file mode 100644 index 0000000000..73d0cc42d6 --- /dev/null +++ b/src/admin/components/views/Revision/Restore/index.tsx @@ -0,0 +1,54 @@ +import React, { Fragment, useCallback, useState } from 'react'; +import { Modal, useModal } from '@faceless-ui/modal'; +import { Button, MinimalTemplate, Pill } from '../../..'; +import { Props } from './types'; + +import './index.scss'; + +const baseClass = 'restore-revision'; +const modalSlug = 'restore-revision'; + +const Restore: React.FC = ({ collection, global, className }) => { + const { toggle } = useModal(); + const [processing, setProcessing] = useState(false); + + const handleRestore = useCallback(() => { + console.log(collection, global); + }, [collection, global]); + + return ( + + toggle(modalSlug)} + className={[baseClass, className].filter(Boolean).join(' ')} + > + Restore this revision + + + +

Confirm revision restoration

+

+ You are about to restore this document. Are you sure? +

+ + +
+
+
+ ); +}; + +export default Restore; diff --git a/src/admin/components/views/Revision/Restore/types.ts b/src/admin/components/views/Revision/Restore/types.ts new file mode 100644 index 0000000000..76f68acb2c --- /dev/null +++ b/src/admin/components/views/Revision/Restore/types.ts @@ -0,0 +1,8 @@ +import { SanitizedCollectionConfig } from '../../../../../collections/config/types'; +import { SanitizedGlobalConfig } from '../../../../../globals/config/types'; + +export type Props = { + collection?: SanitizedCollectionConfig + global?: SanitizedGlobalConfig + className?: string +} diff --git a/src/admin/components/views/Revision/SelectLocales/index.scss b/src/admin/components/views/Revision/SelectLocales/index.scss new file mode 100644 index 0000000000..6b3b8f45cb --- /dev/null +++ b/src/admin/components/views/Revision/SelectLocales/index.scss @@ -0,0 +1,9 @@ +@import '../../../../scss/styles.scss'; + +.select-revision-locales { + flex-grow: 1; + + &__label { + margin-bottom: base(.25); + } +} diff --git a/src/admin/components/views/Revision/SelectLocales/index.tsx b/src/admin/components/views/Revision/SelectLocales/index.tsx new file mode 100644 index 0000000000..19a273fd66 --- /dev/null +++ b/src/admin/components/views/Revision/SelectLocales/index.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import ReactSelect from '../../../elements/ReactSelect'; +import { Props } from './types'; + +import './index.scss'; + +const baseClass = 'select-revision-locales'; + +const SelectLocales: React.FC = ({ onChange, value, options }) => ( +
+
+ Show locales: +
+ +
+); + +export default SelectLocales; diff --git a/src/admin/components/views/Revision/SelectLocales/types.ts b/src/admin/components/views/Revision/SelectLocales/types.ts new file mode 100644 index 0000000000..f3602d6730 --- /dev/null +++ b/src/admin/components/views/Revision/SelectLocales/types.ts @@ -0,0 +1,7 @@ +import { LocaleOption } from '../types'; + +export type Props = { + onChange: (options: LocaleOption[]) => void + value: LocaleOption[] + options: LocaleOption[] +} diff --git a/src/admin/components/views/Revision/index.scss b/src/admin/components/views/Revision/index.scss index c6ec7fcb45..04d03cc2dc 100644 --- a/src/admin/components/views/Revision/index.scss +++ b/src/admin/components/views/Revision/index.scss @@ -12,10 +12,30 @@ &__header { margin-bottom: $baseline; + display: flex; + align-items: center; + flex-wrap: wrap; + + h2 { + margin: 0; + } } - &__intro { - margin-bottom: base(.5); + &__controls { + display: flex; + margin-bottom: $baseline; + margin-left: base(-.5); + margin-right: base(-.5); + + > * { + margin-left: base(.5); + margin-right: base(.5); + width: 50%; + } + } + + &__restore { + margin: 0 0 0 $baseline; } @include mid-break { @@ -24,9 +44,20 @@ margin-right: 0; } + &__intro, &__header { padding-left: $baseline; padding-right: $baseline; + display: block; + } + + &__controls { + display: block; + margin: 0 $baseline; + } + + &__restore { + margin: base(.5) 0 0 0; } } } diff --git a/src/admin/components/views/Revision/index.tsx b/src/admin/components/views/Revision/index.tsx index b2f3a170ad..d75481231a 100644 --- a/src/admin/components/views/Revision/index.tsx +++ b/src/admin/components/views/Revision/index.tsx @@ -8,25 +8,30 @@ import Loading from '../../elements/Loading'; import { useStepNav } from '../../elements/StepNav'; import { StepNavItem } from '../../elements/StepNav/types'; import Meta from '../../utilities/Meta'; -import { Props } from './types'; +import { LocaleOption, CompareOption, Props } from './types'; import CompareRevision from './Compare'; -import { Option } from './Compare/types'; +import { publishedVersionOption } from './shared'; +import Restore from './Restore'; import './index.scss'; +import SelectLocales from './SelectLocales'; const baseClass = 'view-revision'; const ViewRevision: React.FC = ({ collection, global }) => { - const { serverURL, routes: { admin, api }, admin: { dateFormat } } = useConfig(); + const { serverURL, routes: { admin, api }, admin: { dateFormat }, localization } = useConfig(); const { setStepNav } = useStepNav(); const { params: { id, revisionID } } = useRouteMatch<{ id?: string, revisionID: string }>(); - const [compareValue, setCompareValue] = useState