R: Refactor users feature boundary

This commit is contained in:
Ivan 2025-02-12 13:07:55 +03:00
parent fd6295f279
commit 92a0ec5968
20 changed files with 43 additions and 54 deletions

View File

@ -3,18 +3,16 @@ import { z } from 'zod';
import { axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport'; import { axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport';
import { DELAYS } from '@/backend/configuration'; import { DELAYS } from '@/backend/configuration';
import { LibraryItemID } from '@/features/library/models/library';
import { UserID } from '@/features/users/models/user';
import { errorMsg, infoMsg } from '@/utils/labels'; import { errorMsg, infoMsg } from '@/utils/labels';
/** /**
* Represents CurrentUser information. * Represents CurrentUser information.
*/ */
export interface ICurrentUser { export interface ICurrentUser {
id: UserID | null; id: number | null;
username: string; username: string;
is_staff: boolean; is_staff: boolean;
editor: LibraryItemID[]; editor: number[];
} }
/** /**

View File

@ -5,7 +5,6 @@ import { axiosDelete, axiosGet, axiosPatch, axiosPost } from '@/backend/apiTrans
import { DELAYS } from '@/backend/configuration'; import { DELAYS } from '@/backend/configuration';
import { ossApi } from '@/features/oss/backend/api'; import { ossApi } from '@/features/oss/backend/api';
import { IRSFormDTO, rsformsApi } from '@/features/rsform/backend/api'; import { IRSFormDTO, rsformsApi } from '@/features/rsform/backend/api';
import { UserID } from '@/features/users/models/user';
import { errorMsg, infoMsg } from '@/utils/labels'; import { errorMsg, infoMsg } from '@/utils/labels';
import { AccessPolicy, ILibraryItem, IVersionInfo, LibraryItemID, LibraryItemType, VersionID } from '../models/library'; import { AccessPolicy, ILibraryItem, IVersionInfo, LibraryItemID, LibraryItemType, VersionID } from '../models/library';
@ -179,7 +178,7 @@ export const libraryApi = {
successMessage: infoMsg.changesSaved successMessage: infoMsg.changesSaved
} }
}), }),
setOwner: ({ itemID, owner }: { itemID: LibraryItemID; owner: UserID }) => setOwner: ({ itemID, owner }: { itemID: LibraryItemID; owner: number }) =>
axiosPatch({ axiosPatch({
endpoint: `/api/library/${itemID}/set-owner`, endpoint: `/api/library/${itemID}/set-owner`,
request: { request: {
@ -203,7 +202,7 @@ export const libraryApi = {
successMessage: infoMsg.changesSaved successMessage: infoMsg.changesSaved
} }
}), }),
setEditors: ({ itemID, editors }: { itemID: LibraryItemID; editors: UserID[] }) => setEditors: ({ itemID, editors }: { itemID: LibraryItemID; editors: number[] }) =>
axiosPatch({ axiosPatch({
endpoint: `/api/library/${itemID}/set-editors`, endpoint: `/api/library/${itemID}/set-editors`,
request: { request: {

View File

@ -2,9 +2,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
import { ossApi } from '@/features/oss/backend/api'; import { ossApi } from '@/features/oss/backend/api';
import { rsformsApi } from '@/features/rsform/backend/api'; import { rsformsApi } from '@/features/rsform/backend/api';
import { UserID } from '@/features/users/models/user';
import { LibraryItemID } from '../models/library';
import { libraryApi } from './api'; import { libraryApi } from './api';
export const useSetEditors = () => { export const useSetEditors = () => {
@ -36,6 +34,6 @@ export const useSetEditors = () => {
}); });
return { return {
setEditors: (data: { itemID: LibraryItemID; editors: UserID[] }) => mutation.mutateAsync(data) setEditors: (data: { itemID: number; editors: number[] }) => mutation.mutateAsync(data)
}; };
}; };

View File

@ -2,9 +2,8 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
import { IOperationSchemaDTO, ossApi } from '@/features/oss/backend/api'; import { IOperationSchemaDTO, ossApi } from '@/features/oss/backend/api';
import { rsformsApi } from '@/features/rsform/backend/api'; import { rsformsApi } from '@/features/rsform/backend/api';
import { UserID } from '@/features/users/models/user';
import { ILibraryItem, LibraryItemID } from '../models/library'; import { ILibraryItem } from '../models/library';
import { libraryApi } from './api'; import { libraryApi } from './api';
export const useSetOwner = () => { export const useSetOwner = () => {
@ -40,6 +39,6 @@ export const useSetOwner = () => {
}); });
return { return {
setOwner: (data: { itemID: LibraryItemID; owner: UserID }) => mutation.mutateAsync(data) setOwner: (data: { itemID: number; owner: number }) => mutation.mutateAsync(data)
}; };
}; };

View File

@ -16,13 +16,10 @@ import {
import { Loader } from '@/components/Loader'; import { Loader } from '@/components/Loader';
import { CProps } from '@/components/props'; import { CProps } from '@/components/props';
import { ValueIcon } from '@/components/View'; import { ValueIcon } from '@/components/View';
import { useLabelUser } from '@/features/users/backend/useLabelUser'; import { InfoUsers, SelectUser, useLabelUser, useRoleStore } from '@/features/users';
import { InfoUsers } from '@/features/users/components/InfoUsers'; import { UserRole } from '@/features/users/models/user';
import { SelectUser } from '@/features/users/components/SelectUser';
import { UserID, UserRole } from '@/features/users/models/user';
import { useDialogsStore } from '@/stores/dialogs'; import { useDialogsStore } from '@/stores/dialogs';
import { useModificationStore } from '@/stores/modification'; import { useModificationStore } from '@/stores/modification';
import { useRoleStore } from '@/stores/role';
import { prefixes } from '@/utils/constants'; import { prefixes } from '@/utils/constants';
import { promptText } from '@/utils/labels'; import { promptText } from '@/utils/labels';
@ -53,7 +50,7 @@ export function EditorLibraryItem({ controller }: EditorLibraryItemProps) {
const showEditLocation = useDialogsStore(state => state.showChangeLocation); const showEditLocation = useDialogsStore(state => state.showChangeLocation);
const ownerSelector = useDropdown(); const ownerSelector = useDropdown();
const onSelectUser = function (newValue: UserID) { const onSelectUser = function (newValue: number) {
ownerSelector.hide(); ownerSelector.hide();
if (newValue === controller.schema.owner) { if (newValue === controller.schema.owner) {
return; return;
@ -79,7 +76,7 @@ export function EditorLibraryItem({ controller }: EditorLibraryItemProps) {
function handleEditEditors() { function handleEditEditors() {
showEditEditors({ showEditEditors({
itemID: controller.schema.id, itemID: controller.schema.id,
initial: controller.schema.editors initialEditors: controller.schema.editors
}); });
} }

View File

@ -7,36 +7,32 @@ import { MiniButton } from '@/components/Control';
import { IconRemove } from '@/components/Icons'; import { IconRemove } from '@/components/Icons';
import { Label } from '@/components/Input'; import { Label } from '@/components/Input';
import { ModalForm } from '@/components/Modal'; import { ModalForm } from '@/components/Modal';
import { useUsers } from '@/features/users/backend/useUsers'; import { SelectUser, TableUsers, useUsers } from '@/features/users';
import { SelectUser } from '@/features/users/components/SelectUser';
import { UserID } from '@/features/users/models/user';
import { useDialogsStore } from '@/stores/dialogs'; import { useDialogsStore } from '@/stores/dialogs';
import { useSetEditors } from '../../backend/useSetEditors'; import { useSetEditors } from '../../backend/useSetEditors';
import { LibraryItemID } from '../../models/library';
import TableUsers from './TableUsers';
export interface DlgEditEditorsProps { export interface DlgEditEditorsProps {
itemID: LibraryItemID; itemID: number;
initial: UserID[]; initialEditors: number[];
} }
function DlgEditEditors() { function DlgEditEditors() {
const { initial, itemID } = useDialogsStore(state => state.props as DlgEditEditorsProps); const { initialEditors: initial, itemID } = useDialogsStore(state => state.props as DlgEditEditorsProps);
const { setEditors } = useSetEditors(); const { setEditors } = useSetEditors();
const [selected, setSelected] = useState<UserID[]>(initial); const [selected, setSelected] = useState<number[]>(initial);
const { users } = useUsers(); const { users } = useUsers();
function handleSubmit() { function handleSubmit() {
void setEditors({ itemID: itemID, editors: selected }); void setEditors({ itemID: itemID, editors: selected });
} }
function onDeleteEditor(target: UserID) { function onDeleteEditor(target: number) {
setSelected(prev => prev.filter(id => id !== target)); setSelected(prev => prev.filter(id => id !== target));
} }
function onAddEditor(target: UserID) { function onAddEditor(target: number) {
setSelected(prev => [...prev, target]); setSelected(prev => [...prev, target]);
} }

View File

@ -2,8 +2,6 @@
* Module: Models for LibraryItem. * Module: Models for LibraryItem.
*/ */
import { UserID } from '@/features/users/models/user';
/** /**
* Represents type of library items. * Represents type of library items.
*/ */
@ -69,14 +67,14 @@ export interface ILibraryItem {
access_policy: AccessPolicy; access_policy: AccessPolicy;
time_create: string; time_create: string;
time_update: string; time_update: string;
owner: UserID | null; owner: number | null;
} }
/** /**
* Represents {@link ILibraryItem} constant data loaded for both OSS and RSForm. * Represents {@link ILibraryItem} constant data loaded for both OSS and RSForm.
*/ */
export interface ILibraryItemData extends ILibraryItem { export interface ILibraryItemData extends ILibraryItem {
editors: UserID[]; editors: number[];
} }
/** /**
@ -119,5 +117,5 @@ export interface ILibraryFilter {
isVisible?: boolean; isVisible?: boolean;
isOwned?: boolean; isOwned?: boolean;
isEditor?: boolean; isEditor?: boolean;
filterUser?: UserID; filterUser?: number;
} }

View File

@ -10,7 +10,7 @@ import { MiniButton, TextURL } from '@/components/Control';
import DataTable, { createColumnHelper, IConditionalStyle, VisibilityState } from '@/components/DataTable'; import DataTable, { createColumnHelper, IConditionalStyle, VisibilityState } from '@/components/DataTable';
import { IconFolderTree } from '@/components/Icons'; import { IconFolderTree } from '@/components/Icons';
import { CProps } from '@/components/props'; import { CProps } from '@/components/props';
import { useLabelUser } from '@/features/users/backend/useLabelUser'; import { useLabelUser } from '@/features/users';
import useWindowSize from '@/hooks/useWindowSize'; import useWindowSize from '@/hooks/useWindowSize';
import { useFitHeight } from '@/stores/appLayout'; import { useFitHeight } from '@/stores/appLayout';
import { usePreferencesStore } from '@/stores/preferences'; import { usePreferencesStore } from '@/stores/preferences';

View File

@ -16,7 +16,7 @@ import {
} from '@/components/Icons'; } from '@/components/Icons';
import { CProps } from '@/components/props'; import { CProps } from '@/components/props';
import { SearchBar } from '@/components/shared/SearchBar'; import { SearchBar } from '@/components/shared/SearchBar';
import { SelectUser } from '@/features/users/components/SelectUser'; import { SelectUser } from '@/features/users';
import { prefixes } from '@/utils/constants'; import { prefixes } from '@/utils/constants';
import { tripleToggleColor } from '@/utils/utils'; import { tripleToggleColor } from '@/utils/utils';

View File

@ -1,7 +1,6 @@
import { create } from 'zustand'; import { create } from 'zustand';
import { persist } from 'zustand/middleware'; import { persist } from 'zustand/middleware';
import { UserID } from '@/features/users/models/user';
import { toggleTristateFlag } from '@/utils/utils'; import { toggleTristateFlag } from '@/utils/utils';
import { ILibraryFilter, LocationHead } from '../models/library'; import { ILibraryFilter, LocationHead } from '../models/library';
@ -34,8 +33,8 @@ interface LibrarySearchStore {
isEditor: boolean | undefined; isEditor: boolean | undefined;
toggleEditor: () => void; toggleEditor: () => void;
filterUser: UserID | undefined; filterUser: number | undefined;
setFilterUser: (value: UserID | undefined) => void; setFilterUser: (value: number | undefined) => void;
resetFilter: () => void; resetFilter: () => void;
} }

View File

@ -20,8 +20,8 @@ import {
} from '@/components/Icons'; } from '@/components/Icons';
import { useAuthSuspense } from '@/features/auth/backend/useAuth'; import { useAuthSuspense } from '@/features/auth/backend/useAuth';
import { useMutatingOss } from '@/features/oss/backend/useMutatingOss'; import { useMutatingOss } from '@/features/oss/backend/useMutatingOss';
import { useRoleStore } from '@/features/users';
import { UserRole } from '@/features/users/models/user'; import { UserRole } from '@/features/users/models/user';
import { useRoleStore } from '@/stores/role';
import { describeAccessMode as describeUserRole, labelAccessMode as labelUserRole } from '@/utils/labels'; import { describeAccessMode as describeUserRole, labelAccessMode as labelUserRole } from '@/utils/labels';
import { sharePage } from '@/utils/utils'; import { sharePage } from '@/utils/utils';

View File

@ -8,10 +8,10 @@ import { useDeleteItem } from '@/features/library/backend/useDeleteItem';
import { ILibraryItemEditor, LibraryItemID } from '@/features/library/models/library'; import { ILibraryItemEditor, LibraryItemID } from '@/features/library/models/library';
import { useLibrarySearchStore } from '@/features/library/stores/librarySearch'; import { useLibrarySearchStore } from '@/features/library/stores/librarySearch';
import { RSTabID } from '@/features/rsform/pages/RSFormPage/RSEditContext'; import { RSTabID } from '@/features/rsform/pages/RSFormPage/RSEditContext';
import { useRoleStore } from '@/features/users';
import { UserRole } from '@/features/users/models/user'; import { UserRole } from '@/features/users/models/user';
import { useDialogsStore } from '@/stores/dialogs'; import { useDialogsStore } from '@/stores/dialogs';
import { usePreferencesStore } from '@/stores/preferences'; import { usePreferencesStore } from '@/stores/preferences';
import { useRoleStore } from '@/stores/role';
import { promptText } from '@/utils/labels'; import { promptText } from '@/utils/labels';
import { IOperationPosition } from '../../backend/api'; import { IOperationPosition } from '../../backend/api';

View File

@ -9,8 +9,8 @@ import { useMutatingLibrary } from '@/features/library/backend/useMutatingLibrar
import { useSetAccessPolicy } from '@/features/library/backend/useSetAccessPolicy'; import { useSetAccessPolicy } from '@/features/library/backend/useSetAccessPolicy';
import SelectAccessPolicy from '@/features/library/components/SelectAccessPolicy'; import SelectAccessPolicy from '@/features/library/components/SelectAccessPolicy';
import { AccessPolicy, ILibraryItemEditor } from '@/features/library/models/library'; import { AccessPolicy, ILibraryItemEditor } from '@/features/library/models/library';
import { useRoleStore } from '@/features/users';
import { UserRole } from '@/features/users/models/user'; import { UserRole } from '@/features/users/models/user';
import { useRoleStore } from '@/stores/role';
import { PARAMETER } from '@/utils/constants'; import { PARAMETER } from '@/utils/constants';
interface ToolbarItemAccessProps { interface ToolbarItemAccessProps {

View File

@ -7,9 +7,9 @@ import { BadgeHelp } from '@/components/shared/BadgeHelp';
import { HelpTopic } from '@/features/help/models/helpTopic'; import { HelpTopic } from '@/features/help/models/helpTopic';
import { useMutatingLibrary } from '@/features/library/backend/useMutatingLibrary'; import { useMutatingLibrary } from '@/features/library/backend/useMutatingLibrary';
import { AccessPolicy, ILibraryItemEditor, LibraryItemType } from '@/features/library/models/library'; import { AccessPolicy, ILibraryItemEditor, LibraryItemType } from '@/features/library/models/library';
import { useRoleStore } from '@/features/users';
import { UserRole } from '@/features/users/models/user'; import { UserRole } from '@/features/users/models/user';
import { useModificationStore } from '@/stores/modification'; import { useModificationStore } from '@/stores/modification';
import { useRoleStore } from '@/stores/role';
import { PARAMETER } from '@/utils/constants'; import { PARAMETER } from '@/utils/constants';
import { tooltipText } from '@/utils/labels'; import { tooltipText } from '@/utils/labels';
import { prepareTooltip } from '@/utils/utils'; import { prepareTooltip } from '@/utils/utils';

View File

@ -34,10 +34,10 @@ import {
import { useAuthSuspense } from '@/features/auth/backend/useAuth'; import { useAuthSuspense } from '@/features/auth/backend/useAuth';
import { AccessPolicy, LocationHead } from '@/features/library/models/library'; import { AccessPolicy, LocationHead } from '@/features/library/models/library';
import { OssTabID } from '@/features/oss/pages/OssPage/OssEditContext'; import { OssTabID } from '@/features/oss/pages/OssPage/OssEditContext';
import { useRoleStore } from '@/features/users';
import { UserRole } from '@/features/users/models/user'; import { UserRole } from '@/features/users/models/user';
import { useDialogsStore } from '@/stores/dialogs'; import { useDialogsStore } from '@/stores/dialogs';
import { useModificationStore } from '@/stores/modification'; import { useModificationStore } from '@/stores/modification';
import { useRoleStore } from '@/stores/role';
import { EXTEOR_TRS_FILE } from '@/utils/constants'; import { EXTEOR_TRS_FILE } from '@/utils/constants';
import { describeAccessMode, labelAccessMode, tooltipText } from '@/utils/labels'; import { describeAccessMode, labelAccessMode, tooltipText } from '@/utils/labels';
import { generatePageQR, promptUnsaved, sharePage } from '@/utils/utils'; import { generatePageQR, promptUnsaved, sharePage } from '@/utils/utils';

View File

@ -8,11 +8,11 @@ import { useDeleteItem } from '@/features/library/backend/useDeleteItem';
import { ILibraryItemEditor, LibraryItemID, VersionID } from '@/features/library/models/library'; import { ILibraryItemEditor, LibraryItemID, VersionID } from '@/features/library/models/library';
import { useLibrarySearchStore } from '@/features/library/stores/librarySearch'; import { useLibrarySearchStore } from '@/features/library/stores/librarySearch';
import { OssTabID } from '@/features/oss/pages/OssPage/OssEditContext'; import { OssTabID } from '@/features/oss/pages/OssPage/OssEditContext';
import { useRoleStore } from '@/features/users';
import { UserRole } from '@/features/users/models/user'; import { UserRole } from '@/features/users/models/user';
import { useDialogsStore } from '@/stores/dialogs'; import { useDialogsStore } from '@/stores/dialogs';
import { useModificationStore } from '@/stores/modification'; import { useModificationStore } from '@/stores/modification';
import { usePreferencesStore } from '@/stores/preferences'; import { usePreferencesStore } from '@/stores/preferences';
import { useRoleStore } from '@/stores/role';
import { PARAMETER, prefixes } from '@/utils/constants'; import { PARAMETER, prefixes } from '@/utils/constants';
import { promptText } from '@/utils/labels'; import { promptText } from '@/utils/labels';
import { promptUnsaved } from '@/utils/utils'; import { promptUnsaved } from '@/utils/utils';

View File

@ -3,10 +3,10 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { useState } from 'react'; import { useState } from 'react';
import { useRoleStore } from '@/features/users';
import { UserRole } from '@/features/users/models/user'; import { UserRole } from '@/features/users/models/user';
import useWindowSize from '@/hooks/useWindowSize'; import useWindowSize from '@/hooks/useWindowSize';
import { useFitHeight } from '@/stores/appLayout'; import { useFitHeight } from '@/stores/appLayout';
import { useRoleStore } from '@/stores/role';
import { PARAMETER } from '@/utils/constants'; import { PARAMETER } from '@/utils/constants';
import { IConstituenta } from '../../../models/rsform'; import { IConstituenta } from '../../../models/rsform';

View File

@ -3,16 +3,17 @@
import { MiniButton } from '@/components/Control'; import { MiniButton } from '@/components/Control';
import DataTable, { createColumnHelper } from '@/components/DataTable'; import DataTable, { createColumnHelper } from '@/components/DataTable';
import { IconRemove } from '@/components/Icons'; import { IconRemove } from '@/components/Icons';
import { IUserInfo, UserID } from '@/features/users/models/user';
import { IUserInfo } from '../models/user';
interface TableUsersProps { interface TableUsersProps {
items: IUserInfo[]; items: IUserInfo[];
onDelete: (target: UserID) => void; onDelete: (target: number) => void;
} }
const columnHelper = createColumnHelper<IUserInfo>(); const columnHelper = createColumnHelper<IUserInfo>();
function TableUsers({ items, onDelete }: TableUsersProps) { export function TableUsers({ items, onDelete }: TableUsersProps) {
const columns = [ const columns = [
columnHelper.accessor('last_name', { columnHelper.accessor('last_name', {
id: 'last_name', id: 'last_name',
@ -53,5 +54,3 @@ function TableUsers({ items, onDelete }: TableUsersProps) {
/> />
); );
} }
export default TableUsers;

View File

@ -0,0 +1,6 @@
export { useLabelUser } from './backend/useLabelUser';
export { useUsers } from './backend/useUsers';
export { InfoUsers } from './components/InfoUsers';
export { SelectUser } from './components/SelectUser';
export { TableUsers } from './components/TableUsers';
export { useRoleStore } from './stores/role';

View File

@ -1,6 +1,6 @@
import { create } from 'zustand'; import { create } from 'zustand';
import { UserRole } from '@/features/users/models/user'; import { UserRole } from '../models/user';
export interface RoleFlags { export interface RoleFlags {
isOwner: boolean; isOwner: boolean;