2025-01-26 22:24:34 +03:00
|
|
|
|
import { Suspense } from 'react';
|
2024-06-07 20:17:03 +03:00
|
|
|
|
import { useIntl } from 'react-intl';
|
|
|
|
|
|
2025-02-10 01:32:16 +03:00
|
|
|
|
import { urls, useConceptNavigation } from '@/app';
|
2025-02-12 21:36:03 +03:00
|
|
|
|
import { InfoUsers, SelectUser, useLabelUser, useRoleStore, UserRole } from '@/features/users';
|
|
|
|
|
|
2025-02-10 01:32:16 +03:00
|
|
|
|
import { Overlay, Tooltip } from '@/components/Container';
|
|
|
|
|
import { MiniButton } from '@/components/Control';
|
|
|
|
|
import { useDropdown } from '@/components/Dropdown';
|
2024-09-15 21:18:32 +03:00
|
|
|
|
import {
|
|
|
|
|
IconDateCreate,
|
|
|
|
|
IconDateUpdate,
|
|
|
|
|
IconEditor,
|
|
|
|
|
IconFolderEdit,
|
|
|
|
|
IconFolderOpened,
|
|
|
|
|
IconOwner
|
|
|
|
|
} from '@/components/Icons';
|
2025-02-10 01:32:16 +03:00
|
|
|
|
import { Loader } from '@/components/Loader';
|
|
|
|
|
import { ValueIcon } from '@/components/View';
|
2025-01-26 22:24:34 +03:00
|
|
|
|
import { useDialogsStore } from '@/stores/dialogs';
|
|
|
|
|
import { useModificationStore } from '@/stores/modification';
|
2024-06-07 20:17:03 +03:00
|
|
|
|
import { prefixes } from '@/utils/constants';
|
2025-02-12 01:34:35 +03:00
|
|
|
|
import { promptText } from '@/utils/labels';
|
2024-06-07 20:17:03 +03:00
|
|
|
|
|
2025-02-20 20:22:05 +03:00
|
|
|
|
import { type ILibraryItemData } from '../backend/types';
|
2025-02-12 12:45:12 +03:00
|
|
|
|
import { useMutatingLibrary } from '../backend/useMutatingLibrary';
|
|
|
|
|
import { useSetLocation } from '../backend/useSetLocation';
|
|
|
|
|
import { useSetOwner } from '../backend/useSetOwner';
|
|
|
|
|
import { useLibrarySearchStore } from '../stores/librarySearch';
|
2025-02-10 01:32:16 +03:00
|
|
|
|
|
2025-02-20 14:45:12 +03:00
|
|
|
|
interface EditorLibraryItemProps {
|
2025-02-12 15:12:59 +03:00
|
|
|
|
schema: ILibraryItemData;
|
|
|
|
|
isAttachedToOSS: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-20 14:45:12 +03:00
|
|
|
|
export function EditorLibraryItem({ schema, isAttachedToOSS }: EditorLibraryItemProps) {
|
2025-01-21 12:00:09 +03:00
|
|
|
|
const getUserLabel = useLabelUser();
|
2025-01-15 23:03:23 +03:00
|
|
|
|
const role = useRoleStore(state => state.role);
|
2024-06-07 20:17:03 +03:00
|
|
|
|
const intl = useIntl();
|
2024-09-15 21:18:32 +03:00
|
|
|
|
const router = useConceptNavigation();
|
2025-01-26 22:24:34 +03:00
|
|
|
|
const setGlobalLocation = useLibrarySearchStore(state => state.setLocation);
|
|
|
|
|
|
2025-01-29 14:51:34 +03:00
|
|
|
|
const isProcessing = useMutatingLibrary();
|
2025-01-26 22:24:34 +03:00
|
|
|
|
const { isModified } = useModificationStore();
|
|
|
|
|
|
|
|
|
|
const { setOwner } = useSetOwner();
|
|
|
|
|
const { setLocation } = useSetLocation();
|
|
|
|
|
|
|
|
|
|
const showEditEditors = useDialogsStore(state => state.showEditEditors);
|
|
|
|
|
const showEditLocation = useDialogsStore(state => state.showChangeLocation);
|
2024-06-07 20:17:03 +03:00
|
|
|
|
|
|
|
|
|
const ownerSelector = useDropdown();
|
2025-02-12 13:07:26 +03:00
|
|
|
|
const onSelectUser = function (newValue: number) {
|
2025-01-26 22:24:34 +03:00
|
|
|
|
ownerSelector.hide();
|
2025-02-20 14:45:12 +03:00
|
|
|
|
if (newValue === schema.owner) {
|
2025-01-26 22:24:34 +03:00
|
|
|
|
return;
|
|
|
|
|
}
|
2025-02-12 01:34:35 +03:00
|
|
|
|
if (!window.confirm(promptText.ownerChange)) {
|
2025-01-26 22:24:34 +03:00
|
|
|
|
return;
|
|
|
|
|
}
|
2025-02-20 14:45:12 +03:00
|
|
|
|
void setOwner({ itemID: schema.id, owner: newValue });
|
2025-01-26 22:24:34 +03:00
|
|
|
|
};
|
2024-06-07 20:17:03 +03:00
|
|
|
|
|
2025-02-22 14:03:13 +03:00
|
|
|
|
function handleOpenLibrary(event: React.MouseEvent<Element>) {
|
2025-02-20 14:45:12 +03:00
|
|
|
|
setGlobalLocation(schema.location);
|
2025-01-26 22:24:34 +03:00
|
|
|
|
router.push(urls.library, event.ctrlKey || event.metaKey);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleEditLocation() {
|
|
|
|
|
showEditLocation({
|
2025-02-20 14:45:12 +03:00
|
|
|
|
initial: schema.location,
|
|
|
|
|
onChangeLocation: newLocation => void setLocation({ itemID: schema.id, location: newLocation })
|
2025-01-26 22:24:34 +03:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleEditEditors() {
|
|
|
|
|
showEditEditors({
|
2025-02-20 14:45:12 +03:00
|
|
|
|
itemID: schema.id,
|
|
|
|
|
initialEditors: schema.editors
|
2025-01-26 22:24:34 +03:00
|
|
|
|
});
|
|
|
|
|
}
|
2024-09-15 21:18:32 +03:00
|
|
|
|
|
2024-06-07 20:17:03 +03:00
|
|
|
|
return (
|
|
|
|
|
<div className='flex flex-col'>
|
2024-09-15 21:18:32 +03:00
|
|
|
|
<div className='flex justify-stretch sm:mb-1 max-w-[30rem] gap-3'>
|
|
|
|
|
<MiniButton
|
|
|
|
|
noHover
|
|
|
|
|
noPadding
|
|
|
|
|
title='Открыть в библиотеке'
|
|
|
|
|
icon={<IconFolderOpened size='1.25rem' className='icon-primary' />}
|
|
|
|
|
onClick={handleOpenLibrary}
|
|
|
|
|
/>
|
|
|
|
|
<ValueIcon
|
2025-02-20 20:22:05 +03:00
|
|
|
|
className='text-ellipsis grow'
|
2024-09-15 21:18:32 +03:00
|
|
|
|
icon={<IconFolderEdit size='1.25rem' className='icon-primary' />}
|
2025-02-20 14:45:12 +03:00
|
|
|
|
value={schema.location}
|
|
|
|
|
title={isAttachedToOSS ? 'Путь наследуется от ОСС' : 'Путь'}
|
2025-01-26 22:24:34 +03:00
|
|
|
|
onClick={handleEditLocation}
|
2025-02-20 14:45:12 +03:00
|
|
|
|
disabled={isModified || isProcessing || isAttachedToOSS || role < UserRole.OWNER}
|
2024-09-15 21:18:32 +03:00
|
|
|
|
/>
|
|
|
|
|
</div>
|
2024-06-07 20:17:03 +03:00
|
|
|
|
|
2024-08-21 21:36:02 +03:00
|
|
|
|
{ownerSelector.isOpen ? (
|
2024-09-19 20:52:17 +03:00
|
|
|
|
<Overlay position='top-[-0.5rem] left-[4rem] cc-icons'>
|
2024-08-21 21:36:02 +03:00
|
|
|
|
{ownerSelector.isOpen ? (
|
2025-02-20 14:45:12 +03:00
|
|
|
|
<SelectUser className='w-[25rem] sm:w-[26rem] text-sm' value={schema.owner} onChange={onSelectUser} />
|
2024-08-21 21:36:02 +03:00
|
|
|
|
) : null}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
</Overlay>
|
|
|
|
|
) : null}
|
2024-08-23 12:35:05 +03:00
|
|
|
|
<ValueIcon
|
2024-06-21 19:16:41 +03:00
|
|
|
|
className='sm:mb-1'
|
2024-08-21 21:36:02 +03:00
|
|
|
|
icon={<IconOwner size='1.25rem' className='icon-primary' />}
|
2025-02-20 14:45:12 +03:00
|
|
|
|
value={getUserLabel(schema.owner)}
|
|
|
|
|
title={isAttachedToOSS ? 'Владелец наследуется от ОСС' : 'Владелец'}
|
2024-08-21 21:36:02 +03:00
|
|
|
|
onClick={ownerSelector.toggle}
|
2025-02-20 14:45:12 +03:00
|
|
|
|
disabled={isModified || isProcessing || isAttachedToOSS || role < UserRole.OWNER}
|
2024-06-21 19:16:41 +03:00
|
|
|
|
/>
|
2024-06-07 20:17:03 +03:00
|
|
|
|
|
2024-08-21 21:36:02 +03:00
|
|
|
|
<div className='sm:mb-1 flex justify-between items-center'>
|
2024-08-23 12:35:05 +03:00
|
|
|
|
<ValueIcon
|
2024-08-21 21:36:02 +03:00
|
|
|
|
id='editor_stats'
|
|
|
|
|
dense
|
|
|
|
|
icon={<IconEditor size='1.25rem' className='icon-primary' />}
|
2025-02-20 14:45:12 +03:00
|
|
|
|
value={schema.editors.length}
|
2025-01-26 22:24:34 +03:00
|
|
|
|
onClick={handleEditEditors}
|
|
|
|
|
disabled={isModified || isProcessing || role < UserRole.OWNER}
|
2024-08-21 21:36:02 +03:00
|
|
|
|
/>
|
|
|
|
|
<Tooltip anchorSelect='#editor_stats' layer='z-modalTooltip'>
|
2025-01-21 12:00:09 +03:00
|
|
|
|
<Suspense fallback={<Loader scale={2} />}>
|
2025-02-20 14:45:12 +03:00
|
|
|
|
<InfoUsers items={schema.editors} prefix={prefixes.user_editors} header='Редакторы' />
|
2025-01-21 12:00:09 +03:00
|
|
|
|
</Suspense>
|
2024-08-21 21:36:02 +03:00
|
|
|
|
</Tooltip>
|
|
|
|
|
|
2024-08-23 12:35:05 +03:00
|
|
|
|
<ValueIcon
|
2024-08-21 21:36:02 +03:00
|
|
|
|
dense
|
|
|
|
|
disabled
|
2024-12-16 23:51:31 +03:00
|
|
|
|
icon={<IconDateUpdate size='1.25rem' className='text-ok-600' />}
|
2025-02-20 14:45:12 +03:00
|
|
|
|
value={new Date(schema.time_update).toLocaleString(intl.locale)}
|
2024-08-21 21:36:02 +03:00
|
|
|
|
title='Дата обновления'
|
|
|
|
|
/>
|
|
|
|
|
|
2024-08-23 12:35:05 +03:00
|
|
|
|
<ValueIcon
|
2024-08-21 21:36:02 +03:00
|
|
|
|
dense
|
|
|
|
|
disabled
|
2024-12-16 23:51:31 +03:00
|
|
|
|
icon={<IconDateCreate size='1.25rem' className='text-ok-600' />}
|
2025-02-20 14:45:12 +03:00
|
|
|
|
value={new Date(schema.time_create).toLocaleString(intl.locale, {
|
2024-08-21 21:36:02 +03:00
|
|
|
|
year: '2-digit',
|
|
|
|
|
month: '2-digit',
|
|
|
|
|
day: '2-digit'
|
|
|
|
|
})}
|
|
|
|
|
title='Дата создания'
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2024-06-07 20:17:03 +03:00
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|