Refine batch edit actions

This commit is contained in:
Sam Becker 2024-07-17 23:31:20 -05:00
parent d6e6b5ecaf
commit 35c1453847
6 changed files with 73 additions and 27 deletions

View File

@ -1,8 +1,7 @@
'use client'; 'use client';
import MoreMenu from '@/components/more/MoreMenu'; import MoreMenu from '@/components/more/MoreMenu';
import { GRID_HOMEPAGE_ENABLED } from '@/site/config'; import { PATH_ADMIN_CONFIGURATION, PATH_GRID_INFERRED } from '@/site/paths';
import { PATH_ADMIN_CONFIGURATION, PATH_GRID, PATH_ROOT } from '@/site/paths';
import { useAppState } from '@/state/AppState'; import { useAppState } from '@/state/AppState';
import { BiCog } from 'react-icons/bi'; import { BiCog } from 'react-icons/bi';
import { ImCheckboxUnchecked } from 'react-icons/im'; import { ImCheckboxUnchecked } from 'react-icons/im';
@ -33,7 +32,7 @@ export default function AdminAppMenu() {
: <ImCheckboxUnchecked : <ImCheckboxUnchecked
className="text-[0.75rem]" className="text-[0.75rem]"
/>, />,
href: GRID_HOMEPAGE_ENABLED ? PATH_ROOT : PATH_GRID, href: PATH_GRID_INFERRED,
action: () => { action: () => {
if (isSelecting) { if (isSelecting) {
setSelectedPhotoIds?.(undefined); setSelectedPhotoIds?.(undefined);

View File

@ -10,12 +10,16 @@ import DeleteButton from './DeleteButton';
import { useState } from 'react'; import { useState } from 'react';
import TagInput from '@/components/TagInput'; import TagInput from '@/components/TagInput';
import { convertTagsForForm, Tags } from '@/tag'; import { convertTagsForForm, Tags } from '@/tag';
import { usePathname } from 'next/navigation';
import { PATH_GRID_INFERRED } from '@/site/paths';
export default function AdminBatchEditPanelClient({ export default function AdminBatchEditPanelClient({
existingTags, existingTags,
}: { }: {
existingTags: Tags existingTags: Tags
}) { }) {
const pathname = usePathname();
const { const {
isUserSignedIn, isUserSignedIn,
selectedPhotoIds, selectedPhotoIds,
@ -62,7 +66,11 @@ export default function AdminBatchEditPanelClient({
/> />
</>; </>;
return isUserSignedIn && selectedPhotoIds !== undefined return (
isUserSignedIn &&
pathname === PATH_GRID_INFERRED &&
selectedPhotoIds !== undefined
)
? <SiteGrid ? <SiteGrid
className="sticky top-0 z-10 mb-5 -mt-2 pt-2" className="sticky top-0 z-10 mb-5 -mt-2 pt-2"
contentMain={<Note contentMain={<Note

View File

@ -260,7 +260,8 @@ export default function TagInput({
className={clsx( className={clsx(
'grow !min-w-0 !p-0 -my-2 text-xl', 'grow !min-w-0 !p-0 -my-2 text-xl',
'!border-none !ring-transparent', '!border-none !ring-transparent',
'placeholder:text-dim placeholder:text-[15px]', 'placeholder:text-dim placeholder:text-[14px]',
'placeholder:translate-x-[2px]',
'placeholder:translate-y-[-1.5px]', 'placeholder:translate-y-[-1.5px]',
)} )}
size={10} size={10}

View File

@ -15,6 +15,9 @@ import {
PATH_ADMIN_PHOTOS, PATH_ADMIN_PHOTOS,
PATH_ADMIN_TAGS, PATH_ADMIN_TAGS,
PATH_ADMIN_UPLOADS, PATH_ADMIN_UPLOADS,
PATH_FEED_INFERRED,
PATH_GRID_INFERRED,
PATH_ROOT,
PATH_SIGN_IN, PATH_SIGN_IN,
pathForPhoto, pathForPhoto,
pathForTag, pathForTag,
@ -23,7 +26,7 @@ import Modal from '../Modal';
import { clsx } from 'clsx/lite'; import { clsx } from 'clsx/lite';
import { useDebounce } from 'use-debounce'; import { useDebounce } from 'use-debounce';
import Spinner from '../Spinner'; import Spinner from '../Spinner';
import { useRouter } from 'next/navigation'; import { usePathname, useRouter } from 'next/navigation';
import { useTheme } from 'next-themes'; import { useTheme } from 'next-themes';
import { BiDesktop, BiMoon, BiSun } from 'react-icons/bi'; import { BiDesktop, BiMoon, BiSun } from 'react-icons/bi';
import { IoInvertModeSharp } from 'react-icons/io5'; import { IoInvertModeSharp } from 'react-icons/io5';
@ -42,6 +45,7 @@ import { Tags, addHiddenToTags, formatTag } from '@/tag';
import { FaTag } from 'react-icons/fa'; import { FaTag } from 'react-icons/fa';
import { formatCount, formatCountDescriptive } from '@/utility/string'; import { formatCount, formatCountDescriptive } from '@/utility/string';
import CommandKItem from './CommandKItem'; import CommandKItem from './CommandKItem';
import { GRID_HOMEPAGE_ENABLED } from '@/site/config';
const LISTENER_KEYDOWN = 'keydown'; const LISTENER_KEYDOWN = 'keydown';
const MINIMUM_QUERY_LENGTH = 2; const MINIMUM_QUERY_LENGTH = 2;
@ -73,11 +77,15 @@ export default function CommandKClient({
showDebugTools?: boolean showDebugTools?: boolean
footer?: string footer?: string
}) { }) {
const pathname = usePathname();
const { const {
isUserSignedIn, isUserSignedIn,
setUserEmail, setUserEmail,
isCommandKOpen: isOpen, isCommandKOpen: isOpen,
hiddenPhotosCount, hiddenPhotosCount,
selectedPhotoIds,
setSelectedPhotoIds,
arePhotosMatted, arePhotosMatted,
shouldShowBaselineGrid, shouldShowBaselineGrid,
shouldDebugImageFallbacks, shouldDebugImageFallbacks,
@ -246,16 +254,27 @@ export default function CommandKClient({
}); });
} }
const pagesItems: CommandKItem[] = [{
label: 'Home',
path: PATH_ROOT,
}];
if (GRID_HOMEPAGE_ENABLED) {
pagesItems.push({
label: 'Feed',
path: PATH_FEED_INFERRED,
});
} else {
pagesItems.push({
label: 'Grid',
path: PATH_GRID_INFERRED,
});
}
const sectionPages: CommandKSection = { const sectionPages: CommandKSection = {
heading: 'Pages', heading: 'Pages',
accessory: <HiDocumentText size={15} className="translate-x-[-1px]" />, accessory: <HiDocumentText size={15} className="translate-x-[-1px]" />,
items: ([{ items: pagesItems,
label: 'Home',
path: '/',
}, {
label: 'Grid',
path:'/grid',
}]),
}; };
const adminSection: CommandKSection = { const adminSection: CommandKSection = {
@ -278,6 +297,17 @@ export default function CommandKClient({
label: 'App Config', label: 'App Config',
annotation: <BiLockAlt />, annotation: <BiLockAlt />,
path: PATH_ADMIN_CONFIGURATION, path: PATH_ADMIN_CONFIGURATION,
}, {
label: selectedPhotoIds === undefined
? 'Select Multiple Photos'
: 'Exit Select Multiple Photos',
annotation: <BiLockAlt />,
path: selectedPhotoIds === undefined
? PATH_GRID_INFERRED
: undefined,
action: selectedPhotoIds === undefined
? () => setSelectedPhotoIds?.([])
: () => setSelectedPhotoIds?.(undefined),
}] as CommandKItem[]) }] as CommandKItem[])
.concat(showDebugTools .concat(showDebugTools
? [{ ? [{
@ -393,15 +423,20 @@ export default function CommandKClient({
value={key} value={key}
keywords={keywords} keywords={keywords}
onSelect={() => { onSelect={() => {
if (action) {
action();
if (!path) { setIsOpen?.(false); }
}
if (path) { if (path) {
setKeyPending(key); if (path !== pathname) {
startTransition(async () => { setKeyPending(key);
shouldCloseAfterPending.current = true; startTransition(async () => {
router.push(path, { scroll: true }); shouldCloseAfterPending.current = true;
}); router.push(path, { scroll: true });
} else { });
setIsOpen?.(false); } else {
action?.(); setIsOpen?.(false);
}
} }
}} }}
accessory={accessory} accessory={accessory}

View File

@ -4,9 +4,8 @@ import IconFeed from '@/site/IconFeed';
import IconGrid from '@/site/IconGrid'; import IconGrid from '@/site/IconGrid';
import { import {
PATH_ADMIN_PHOTOS, PATH_ADMIN_PHOTOS,
PATH_FEED, PATH_FEED_INFERRED,
PATH_GRID, PATH_GRID_INFERRED,
PATH_ROOT,
} from '@/site/paths'; } from '@/site/paths';
import { BiLockAlt } from 'react-icons/bi'; import { BiLockAlt } from 'react-icons/bi';
import IconSearch from './IconSearch'; import IconSearch from './IconSearch';
@ -27,7 +26,7 @@ export default function ViewSwitcher({
const renderItemFeed = () => const renderItemFeed = () =>
<SwitcherItem <SwitcherItem
icon={<IconFeed />} icon={<IconFeed />}
href={GRID_HOMEPAGE_ENABLED ? PATH_FEED : PATH_ROOT} href={PATH_FEED_INFERRED}
active={currentSelection === 'feed'} active={currentSelection === 'feed'}
noPadding noPadding
/>; />;
@ -35,7 +34,7 @@ export default function ViewSwitcher({
const renderItemGrid = () => const renderItemGrid = () =>
<SwitcherItem <SwitcherItem
icon={<IconGrid />} icon={<IconGrid />}
href={GRID_HOMEPAGE_ENABLED ? PATH_ROOT : PATH_GRID} href={PATH_GRID_INFERRED}
active={currentSelection === 'grid'} active={currentSelection === 'grid'}
noPadding noPadding
/>; />;

View File

@ -1,5 +1,5 @@
import { Photo } from '@/photo'; import { Photo } from '@/photo';
import { BASE_URL } from './config'; import { BASE_URL, GRID_HOMEPAGE_ENABLED } from './config';
import { Camera } from '@/camera'; import { Camera } from '@/camera';
import { FilmSimulation } from '@/simulation'; import { FilmSimulation } from '@/simulation';
import { parameterize } from '@/utility/string'; import { parameterize } from '@/utility/string';
@ -13,6 +13,10 @@ export const PATH_ADMIN = '/admin';
export const PATH_API = '/api'; export const PATH_API = '/api';
export const PATH_SIGN_IN = '/sign-in'; export const PATH_SIGN_IN = '/sign-in';
export const PATH_OG = '/og'; export const PATH_OG = '/og';
// eslint-disable-next-line max-len
export const PATH_GRID_INFERRED = GRID_HOMEPAGE_ENABLED ? PATH_ROOT : PATH_GRID;
// eslint-disable-next-line max-len
export const PATH_FEED_INFERRED = GRID_HOMEPAGE_ENABLED ? PATH_FEED : PATH_ROOT;
// Path prefixes // Path prefixes
export const PREFIX_PHOTO = '/p'; export const PREFIX_PHOTO = '/p';