R: Refactor global names and LocationChange dialog

This commit is contained in:
Ivan 2025-02-12 01:34:35 +03:00
parent b6f1ff3337
commit 8346850cf6
30 changed files with 173 additions and 138 deletions

View File

@ -5,7 +5,7 @@ import { axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport';
import { DELAYS } from '@/backend/configuration';
import { LibraryItemID } from '@/features/library/models/library';
import { UserID } from '@/features/users/models/user';
import { errors, information } from '@/utils/labels';
import { errorMsg, infoMsg } from '@/utils/labels';
/**
* Represents CurrentUser information.
@ -21,8 +21,8 @@ export interface ICurrentUser {
* Represents login data, used to authenticate users.
*/
export const schemaUserLogin = z.object({
username: z.string().nonempty(errors.requiredField),
password: z.string().nonempty(errors.requiredField)
username: z.string().nonempty(errorMsg.requiredField),
password: z.string().nonempty(errorMsg.requiredField)
});
/**
@ -35,17 +35,17 @@ export type IUserLoginDTO = z.infer<typeof schemaUserLogin>;
*/
export const schemaChangePassword = z
.object({
old_password: z.string().nonempty(errors.requiredField),
new_password: z.string().nonempty(errors.requiredField),
new_password2: z.string().nonempty(errors.requiredField)
old_password: z.string().nonempty(errorMsg.requiredField),
new_password: z.string().nonempty(errorMsg.requiredField),
new_password2: z.string().nonempty(errorMsg.requiredField)
})
.refine(schema => schema.new_password === schema.new_password2, {
path: ['new_password2'],
message: errors.passwordsMismatch
message: errorMsg.passwordsMismatch
})
.refine(schema => schema.old_password !== schema.new_password, {
path: ['new_password'],
message: errors.passwordsSame
message: errorMsg.passwordsSame
});
/**
@ -105,7 +105,7 @@ export const authApi = {
endpoint: '/users/api/change-password',
request: {
data: data,
successMessage: information.changesSaved
successMessage: infoMsg.changesSaved
}
}),
requestPasswordReset: (data: IRequestPasswordDTO) =>

View File

@ -6,7 +6,7 @@ import { DELAYS } from '@/backend/configuration';
import { ossApi } from '@/features/oss/backend/api';
import { IRSFormDTO, rsformsApi } from '@/features/rsform/backend/api';
import { UserID } from '@/features/users/models/user';
import { errors, information } from '@/utils/labels';
import { errorMsg, infoMsg } from '@/utils/labels';
import { AccessPolicy, ILibraryItem, IVersionInfo, LibraryItemID, LibraryItemType, VersionID } from '../models/library';
import { validateLocation } from '../models/libraryAPI';
@ -25,12 +25,12 @@ export interface IRenameLocationDTO {
export const schemaCloneLibraryItem = z.object({
id: z.number(),
item_type: z.nativeEnum(LibraryItemType),
title: z.string().nonempty(errors.requiredField),
alias: z.string().nonempty(errors.requiredField),
title: z.string().nonempty(errorMsg.requiredField),
alias: z.string().nonempty(errorMsg.requiredField),
comment: z.string(),
visible: z.boolean(),
read_only: z.boolean(),
location: z.string().refine(data => validateLocation(data), { message: errors.invalidLocation }),
location: z.string().refine(data => validateLocation(data), { message: errorMsg.invalidLocation }),
access_policy: z.nativeEnum(AccessPolicy),
items: z.array(z.number()).optional()
@ -52,7 +52,7 @@ export const schemaCreateLibraryItem = z
comment: z.string(),
visible: z.boolean(),
read_only: z.boolean(),
location: z.string().refine(data => validateLocation(data), { message: errors.invalidLocation }),
location: z.string().refine(data => validateLocation(data), { message: errorMsg.invalidLocation }),
access_policy: z.nativeEnum(AccessPolicy),
file: z.instanceof(File).optional(),
@ -60,11 +60,11 @@ export const schemaCreateLibraryItem = z
})
.refine(data => !!data.file || !!data.title, {
path: ['title'],
message: errors.requiredField
message: errorMsg.requiredField
})
.refine(data => !!data.file || !!data.alias, {
path: ['alias'],
message: errors.requiredField
message: errorMsg.requiredField
});
/**
@ -78,8 +78,8 @@ export type ICreateLibraryItemDTO = z.infer<typeof schemaCreateLibraryItem>;
export const schemaUpdateLibraryItem = z.object({
id: z.number(),
item_type: z.nativeEnum(LibraryItemType),
title: z.string().nonempty(errors.requiredField),
alias: z.string().nonempty(errors.requiredField),
title: z.string().nonempty(errorMsg.requiredField),
alias: z.string().nonempty(errorMsg.requiredField),
comment: z.string(),
visible: z.boolean(),
read_only: z.boolean()
@ -117,7 +117,7 @@ export interface IVersionCreatedResponse {
*/
export const schemaVersionUpdate = z.object({
id: z.number(),
version: z.string().nonempty(errors.requiredField),
version: z.string().nonempty(errorMsg.requiredField),
description: z.string()
});
@ -161,7 +161,7 @@ export const libraryApi = {
endpoint: !data.file ? '/api/library' : '/api/rsforms/create-detailed',
request: {
data: data,
successMessage: information.newLibraryItem
successMessage: infoMsg.newLibraryItem
},
options: !data.file
? undefined
@ -176,7 +176,7 @@ export const libraryApi = {
endpoint: `/api/library/${data.id}`,
request: {
data: data,
successMessage: information.changesSaved
successMessage: infoMsg.changesSaved
}
}),
setOwner: ({ itemID, owner }: { itemID: LibraryItemID; owner: UserID }) =>
@ -184,7 +184,7 @@ export const libraryApi = {
endpoint: `/api/library/${itemID}/set-owner`,
request: {
data: { user: owner },
successMessage: information.changesSaved
successMessage: infoMsg.changesSaved
}
}),
setLocation: ({ itemID, location }: { itemID: LibraryItemID; location: string }) =>
@ -192,7 +192,7 @@ export const libraryApi = {
endpoint: `/api/library/${itemID}/set-location`,
request: {
data: { location: location },
successMessage: information.moveComplete
successMessage: infoMsg.moveComplete
}
}),
setAccessPolicy: ({ itemID, policy }: { itemID: LibraryItemID; policy: AccessPolicy }) =>
@ -200,7 +200,7 @@ export const libraryApi = {
endpoint: `/api/library/${itemID}/set-access-policy`,
request: {
data: { access_policy: policy },
successMessage: information.changesSaved
successMessage: infoMsg.changesSaved
}
}),
setEditors: ({ itemID, editors }: { itemID: LibraryItemID; editors: UserID[] }) =>
@ -208,7 +208,7 @@ export const libraryApi = {
endpoint: `/api/library/${itemID}/set-editors`,
request: {
data: { users: editors },
successMessage: information.changesSaved
successMessage: infoMsg.changesSaved
}
}),
@ -216,7 +216,7 @@ export const libraryApi = {
axiosDelete({
endpoint: `/api/library/${target}`,
request: {
successMessage: information.itemDestroyed
successMessage: infoMsg.itemDestroyed
}
}),
cloneItem: (data: ICloneLibraryItemDTO) =>
@ -224,7 +224,7 @@ export const libraryApi = {
endpoint: `/api/library/${data.id}/clone`,
request: {
data: data,
successMessage: newSchema => information.cloneComplete(newSchema.alias)
successMessage: newSchema => infoMsg.cloneComplete(newSchema.alias)
}
}),
renameLocation: (data: IRenameLocationDTO) =>
@ -232,7 +232,7 @@ export const libraryApi = {
endpoint: '/api/library/rename-location',
request: {
data: data,
successMessage: information.locationRenamed
successMessage: infoMsg.locationRenamed
}
}),
@ -241,14 +241,14 @@ export const libraryApi = {
endpoint: `/api/library/${itemID}/create-version`,
request: {
data: data,
successMessage: information.newVersion(data.version)
successMessage: infoMsg.newVersion(data.version)
}
}),
versionRestore: ({ versionID }: { versionID: VersionID }) =>
axiosPatch<undefined, IRSFormDTO>({
endpoint: `/api/versions/${versionID}/restore`,
request: {
successMessage: information.versionRestored
successMessage: infoMsg.versionRestored
}
}),
versionUpdate: (data: IVersionUpdateDTO) =>
@ -256,14 +256,14 @@ export const libraryApi = {
endpoint: `/api/versions/${data.id}`,
request: {
data: data,
successMessage: information.changesSaved
successMessage: infoMsg.changesSaved
}
}),
versionDelete: (data: { itemID: LibraryItemID; versionID: VersionID }) =>
axiosDelete({
endpoint: `/api/versions/${data.versionID}`,
request: {
successMessage: information.versionDestroyed
successMessage: infoMsg.versionDestroyed
}
})
};

View File

@ -1,19 +1,28 @@
'use client';
import { zodResolver } from '@hookform/resolvers/zod';
import clsx from 'clsx';
import { useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { z } from 'zod';
import { Label, TextArea } from '@/components/Input';
import { ModalForm } from '@/components/Modal';
import { useAuthSuspense } from '@/features/auth/backend/useAuth';
import { useDialogsStore } from '@/stores/dialogs';
import { limits } from '@/utils/constants';
import { errorMsg } from '@/utils/labels';
import SelectLocationContext from '../components/SelectLocationContext';
import SelectLocationHead from '../components/SelectLocationHead';
import { LocationHead } from '../models/library';
import { combineLocation, validateLocation } from '../models/libraryAPI';
const schemaLocation = z.object({
location: z.string().refine(data => validateLocation(data), { message: errorMsg.invalidLocation })
});
type ILocationType = z.infer<typeof schemaLocation>;
export interface DlgChangeLocationProps {
initial: string;
onChangeLocation: (newLocation: string) => void;
@ -22,20 +31,21 @@ export interface DlgChangeLocationProps {
function DlgChangeLocation() {
const { initial, onChangeLocation } = useDialogsStore(state => state.props as DlgChangeLocationProps);
const { user } = useAuthSuspense();
const [head, setHead] = useState<LocationHead>(initial.substring(0, 2) as LocationHead);
const [body, setBody] = useState<string>(initial.substring(3));
const location = combineLocation(head, body);
const isValid = initial !== location && validateLocation(location);
const {
handleSubmit,
control,
formState: { errors, isValid, isDirty }
} = useForm<ILocationType>({
resolver: zodResolver(schemaLocation),
defaultValues: {
location: initial
},
mode: 'onChange'
});
function handleSelectLocation(newValue: string) {
setHead(newValue.substring(0, 2) as LocationHead);
setBody(newValue.length > 3 ? newValue.substring(3) : '');
}
function handleSubmit() {
onChangeLocation(location);
return true;
function onSubmit(data: ILocationType) {
onChangeLocation(data.location);
}
return (
@ -44,20 +54,45 @@ function DlgChangeLocation() {
header='Изменение расположения'
submitText='Переместить'
submitInvalidTooltip={`Допустимы буквы, цифры, подчерк, пробел и "!". Сегмент пути не может начинаться и заканчиваться пробелом. Общая длина (с корнем) не должна превышать ${limits.location_len}`}
canSubmit={isValid}
onSubmit={handleSubmit}
canSubmit={isValid && isDirty}
onSubmit={event => void handleSubmit(onSubmit)(event)}
className={clsx('w-[35rem]', 'pb-3 px-6 flex gap-3 h-[9rem]')}
>
<div className='flex flex-col gap-2 min-w-[7rem] h-min'>
<Label className='select-none' text='Корень' />
<Controller
control={control}
name='location'
render={({ field }) => (
<SelectLocationHead
value={head} // prettier: split-lines
onChange={setHead}
value={field.value.substring(0, 2) as LocationHead}
onChange={newValue => field.onChange(combineLocation(newValue, field.value.substring(3)))}
excluded={!user.is_staff ? [LocationHead.LIBRARY] : []}
/>
)}
/>
</div>
<SelectLocationContext value={location} onChange={handleSelectLocation} className='max-h-[9.2rem]' />
<TextArea id='dlg_cst_body' label='Путь' rows={3} value={body} onChange={event => setBody(event.target.value)} />
<Controller
control={control}
name='location'
render={({ field }) => (
<SelectLocationContext className='max-h-[9.2rem]' value={field.value} onChange={field.onChange} />
)}
/>
<Controller
control={control} //
name='location'
render={({ field }) => (
<TextArea
id='dlg_location'
label='Путь'
rows={3}
value={field.value.substring(3)}
onChange={event => field.onChange(combineLocation(field.value.substring(0, 2), event.target.value))}
error={errors.location}
/>
)}
/>
</ModalForm>
);
}

View File

@ -8,7 +8,7 @@ import { MiniButton } from '@/components/Control';
import { IconCSV } from '@/components/Icons';
import { useAppLayoutStore } from '@/stores/appLayout';
import { useDialogsStore } from '@/stores/dialogs';
import { information } from '@/utils/labels';
import { infoMsg } from '@/utils/labels';
import { convertToCSV } from '@/utils/utils';
import { useApplyLibraryFilter } from '../../backend/useApplyLibraryFilter';
@ -43,7 +43,7 @@ export function LibraryPage() {
function handleDownloadCSV() {
if (filtered.length === 0) {
toast.error(information.noDataToExport);
toast.error(infoMsg.noDataToExport);
return;
}
const blob = convertToCSV(filtered);

View File

@ -12,7 +12,7 @@ import { FolderNode } from '@/features/library/models/FolderTree';
import useWindowSize from '@/hooks/useWindowSize';
import { useFitHeight } from '@/stores/appLayout';
import { PARAMETER, prefixes } from '@/utils/constants';
import { information } from '@/utils/labels';
import { infoMsg } from '@/utils/labels';
import { useLibrary } from '../../backend/useLibrary';
import SelectLocation from '../../components/SelectLocation';
@ -54,7 +54,7 @@ function ViewSideLocation({ isVisible, onRenameLocation }: ViewSideLocationProps
if (event.ctrlKey || event.metaKey) {
navigator.clipboard
.writeText(target.getPath())
.then(() => toast.success(information.pathReady))
.then(() => toast.success(infoMsg.pathReady))
.catch(console.error);
} else {
setLocation(target.getPath());

View File

@ -13,7 +13,7 @@ import {
schemaCstSubstitute
} from '@/features/oss/models/oss';
import { IConstituentaReference, ITargetCst } from '@/features/rsform/models/rsform';
import { information } from '@/utils/labels';
import { infoMsg } from '@/utils/labels';
/**
* Represents {@link IOperation} data from server.
@ -182,7 +182,7 @@ export const ossApi = {
endpoint: `/api/oss/${itemID}/update-positions`,
request: {
data: { positions: positions },
successMessage: isSilent ? undefined : information.changesSaved
successMessage: isSilent ? undefined : infoMsg.changesSaved
}
}),
@ -191,7 +191,7 @@ export const ossApi = {
endpoint: `/api/oss/${itemID}/create-operation`,
request: {
data: data,
successMessage: response => information.newOperation(response.new_operation.alias)
successMessage: response => infoMsg.newOperation(response.new_operation.alias)
}
}),
operationDelete: ({ itemID, data }: { itemID: LibraryItemID; data: IOperationDeleteDTO }) =>
@ -199,7 +199,7 @@ export const ossApi = {
endpoint: `/api/oss/${itemID}/delete-operation`,
request: {
data: data,
successMessage: information.operationDestroyed
successMessage: infoMsg.operationDestroyed
}
}),
inputCreate: ({ itemID, data }: { itemID: LibraryItemID; data: ITargetOperation }) =>
@ -207,7 +207,7 @@ export const ossApi = {
endpoint: `/api/oss/${itemID}/create-input`,
request: {
data: data,
successMessage: information.newLibraryItem
successMessage: infoMsg.newLibraryItem
}
}),
inputUpdate: ({ itemID, data }: { itemID: LibraryItemID; data: IInputUpdateDTO }) =>
@ -215,7 +215,7 @@ export const ossApi = {
endpoint: `/api/oss/${itemID}/set-input`,
request: {
data: data,
successMessage: information.changesSaved
successMessage: infoMsg.changesSaved
}
}),
operationUpdate: ({ itemID, data }: { itemID: LibraryItemID; data: IOperationUpdateDTO }) =>
@ -223,7 +223,7 @@ export const ossApi = {
endpoint: `/api/oss/${itemID}/update-operation`,
request: {
data: data,
successMessage: information.changesSaved
successMessage: infoMsg.changesSaved
}
}),
operationExecute: ({ itemID, data }: { itemID: LibraryItemID; data: ITargetOperation }) =>
@ -231,7 +231,7 @@ export const ossApi = {
endpoint: `/api/oss/${itemID}/execute-operation`,
request: {
data: data,
successMessage: information.operationExecuted
successMessage: infoMsg.operationExecuted
}
}),
@ -240,7 +240,7 @@ export const ossApi = {
endpoint: `/api/oss/relocate-constituents`,
request: {
data: data,
successMessage: information.changesSaved
successMessage: infoMsg.changesSaved
}
}),
getPredecessor: (data: ITargetCst) =>

View File

@ -12,7 +12,7 @@ import {
isSetTypification
} from '@/features/rsform/models/rslangAPI';
import { limits, PARAMETER } from '@/utils/constants';
import { information } from '@/utils/labels';
import { infoMsg } from '@/utils/labels';
import { TextMatcher } from '@/utils/utils';
import { Graph } from '../../../models/Graph';
@ -416,7 +416,7 @@ export class SubstitutionValidator {
if (this.msg.length > 0) {
this.msg += '\n';
}
this.msg += information.substitutionsCorrect;
this.msg += infoMsg.substitutionsCorrect;
return true;
}

View File

@ -24,7 +24,7 @@ import { useMainHeight } from '@/stores/appLayout';
import { useModificationStore } from '@/stores/modification';
import { APP_COLORS } from '@/styling/colors';
import { PARAMETER } from '@/utils/constants';
import { errors } from '@/utils/labels';
import { errorMsg } from '@/utils/labels';
import { useInputCreate } from '../../../backend/useInputCreate';
import { useMutatingOss } from '../../../backend/useMutatingOss';
@ -167,7 +167,7 @@ function OssFlow() {
return;
}
if (libraryItems.find(item => item.alias === operation.alias && item.location === controller.schema.location)) {
toast.error(errors.inputAlreadyExists);
toast.error(errorMsg.inputAlreadyExists);
return;
}
void inputCreate({
@ -205,7 +205,7 @@ function OssFlow() {
function handleSaveImage() {
const canvas: HTMLElement | null = document.querySelector('.react-flow__viewport');
if (canvas === null) {
toast.error(errors.imageFailed);
toast.error(errorMsg.imageFailed);
return;
}
@ -231,7 +231,7 @@ function OssFlow() {
})
.catch(error => {
console.error(error);
toast.error(errors.imageFailed);
toast.error(errorMsg.imageFailed);
});
}

View File

@ -12,7 +12,7 @@ import { UserRole } from '@/features/users/models/user';
import { useDialogsStore } from '@/stores/dialogs';
import { usePreferencesStore } from '@/stores/preferences';
import { useRoleStore } from '@/stores/role';
import { prompts } from '@/utils/labels';
import { promptText } from '@/utils/labels';
import { IOperationPosition } from '../../backend/api';
import { useOssSuspense } from '../../backend/useOSS';
@ -123,7 +123,7 @@ export const OssEditState = ({ itemID, children }: React.PropsWithChildren<OssEd
}
function deleteSchema() {
if (!window.confirm(prompts.deleteOSS)) {
if (!window.confirm(promptText.deleteOSS)) {
return;
}
void deleteItem(schema.id).then(() => {

View File

@ -10,7 +10,7 @@ import {
VersionID
} from '@/features/library/models/library';
import { ICstSubstitute, ICstSubstitutions } from '@/features/oss/models/oss';
import { information } from '@/utils/labels';
import { infoMsg } from '@/utils/labels';
import {
ConstituentaID,
@ -173,7 +173,7 @@ export const rsformsApi = {
endpoint: `/api/rsforms/${data.itemID}/load-trs`,
request: {
data: data,
successMessage: information.uploadSuccess
successMessage: infoMsg.uploadSuccess
},
options: {
headers: {
@ -187,7 +187,7 @@ export const rsformsApi = {
endpoint: `/api/rsforms/${itemID}/create-cst`,
request: {
data: data,
successMessage: response => information.newConstituent(response.new_cst.alias)
successMessage: response => infoMsg.newConstituent(response.new_cst.alias)
}
}),
cstUpdate: ({ itemID, data }: { itemID: LibraryItemID; data: ICstUpdateDTO }) =>
@ -195,7 +195,7 @@ export const rsformsApi = {
endpoint: `/api/rsforms/${itemID}/update-cst`,
request: {
data: data,
successMessage: information.changesSaved
successMessage: infoMsg.changesSaved
}
}),
cstDelete: ({ itemID, data }: { itemID: LibraryItemID; data: IConstituentaList }) =>
@ -203,7 +203,7 @@ export const rsformsApi = {
endpoint: `/api/rsforms/${itemID}/delete-multiple-cst`,
request: {
data: data,
successMessage: information.constituentsDestroyed(data.items.length)
successMessage: infoMsg.constituentsDestroyed(data.items.length)
}
}),
cstRename: ({ itemID, data }: { itemID: LibraryItemID; data: ICstRenameDTO }) =>
@ -211,7 +211,7 @@ export const rsformsApi = {
endpoint: `/api/rsforms/${itemID}/rename-cst`,
request: {
data: data,
successMessage: information.changesSaved
successMessage: infoMsg.changesSaved
}
}),
cstSubstitute: ({ itemID, data }: { itemID: LibraryItemID; data: ICstSubstitutions }) =>
@ -219,7 +219,7 @@ export const rsformsApi = {
endpoint: `/api/rsforms/${itemID}/substitute`,
request: {
data: data,
successMessage: information.substituteSingle
successMessage: infoMsg.substituteSingle
}
}),
cstMove: ({ itemID, data }: { itemID: LibraryItemID; data: ICstMoveDTO }) =>
@ -233,7 +233,7 @@ export const rsformsApi = {
endpoint: `/api/rsforms/${itemID}/produce-structure`,
request: {
data: data,
successMessage: response => information.addedConstituents(response.cst_list.length)
successMessage: response => infoMsg.addedConstituents(response.cst_list.length)
}
}),
inlineSynthesis: ({ itemID, data }: { itemID: LibraryItemID; data: IInlineSynthesisDTO }) =>
@ -241,18 +241,18 @@ export const rsformsApi = {
endpoint: `/api/rsforms/${itemID}/inline-synthesis`,
request: {
data: data,
successMessage: information.inlineSynthesisComplete
successMessage: infoMsg.inlineSynthesisComplete
}
}),
restoreOrder: ({ itemID }: { itemID: LibraryItemID }) =>
axiosPatch<undefined, IRSFormDTO>({
endpoint: `/api/rsforms/${itemID}/restore-order`,
request: { successMessage: information.reorderComplete }
request: { successMessage: infoMsg.reorderComplete }
}),
resetAliases: ({ itemID }: { itemID: LibraryItemID }) =>
axiosPatch<undefined, IRSFormDTO>({
endpoint: `/api/rsforms/${itemID}/reset-aliases`,
request: { successMessage: information.reindexComplete }
request: { successMessage: infoMsg.reindexComplete }
}),
checkConstituenta: ({ itemID, data }: { itemID: LibraryItemID; data: ICheckConstituentaDTO }) =>

View File

@ -13,7 +13,7 @@ import SelectLibraryItem from '@/features/library/components/SelectLibraryItem';
import { ILibraryItem } from '@/features/library/models/library';
import { ICstSubstitute, IMultiSubstitution } from '@/features/oss/models/oss';
import { APP_COLORS } from '@/styling/colors';
import { errors } from '@/utils/labels';
import { errorMsg } from '@/utils/labels';
import { ConstituentaID, IConstituenta, IRSForm } from '../models/rsform';
import BadgeConstituenta from './BadgeConstituenta';
@ -116,12 +116,12 @@ function PickSubstitutions({
toDelete.includes(newSubstitution.substitution) ||
replacements.includes(newSubstitution.original)
) {
toast.error(errors.reuseOriginal);
toast.error(errorMsg.reuseOriginal);
return;
}
if (leftArgument === rightArgument) {
if ((deleteRight && rightCst?.is_inherited) || (!deleteRight && leftCst?.is_inherited)) {
toast.error(errors.substituteInherited);
toast.error(errorMsg.substituteInherited);
return;
}
}

View File

@ -11,7 +11,7 @@ import { useVersionCreate } from '@/features/library/backend/useVersionCreate';
import { IVersionInfo, LibraryItemID, VersionID } from '@/features/library/models/library';
import { nextVersion } from '@/features/library/models/libraryAPI';
import { useDialogsStore } from '@/stores/dialogs';
import { errors } from '@/utils/labels';
import { errorMsg } from '@/utils/labels';
import { ConstituentaID } from '../models/rsform';
@ -53,7 +53,7 @@ function DlgCreateVersion() {
header='Создание версии'
className={clsx('cc-column', 'w-[30rem]', 'py-2 px-6')}
canSubmit={canSubmit}
submitInvalidTooltip={errors.versionTaken}
submitInvalidTooltip={errorMsg.versionTaken}
submitText='Создать'
onSubmit={event => void handleSubmit(onSubmit)(event)}
>

View File

@ -9,7 +9,7 @@ import { TabLabel, TabList, TabPanel, Tabs } from '@/components/Tabs';
import { HelpTopic } from '@/features/help/models/helpTopic';
import usePartialUpdate from '@/hooks/usePartialUpdate';
import { useDialogsStore } from '@/stores/dialogs';
import { prompts } from '@/utils/labels';
import { promptText } from '@/utils/labels';
import { ICstCreateDTO } from '../../backend/api';
import { useRSForm } from '../../backend/useRSForm';
@ -62,7 +62,7 @@ function DlgCstTemplate() {
function handlePrompt(): boolean {
const definedSomeArgs = substitutes.arguments.some(arg => !!arg.value);
if (!definedSomeArgs && !window.confirm(prompts.templateUndefined)) {
if (!definedSomeArgs && !window.confirm(promptText.templateUndefined)) {
return false;
}
return true;

View File

@ -15,7 +15,7 @@ import { useVersionDelete } from '@/features/library/backend/useVersionDelete';
import { useVersionUpdate } from '@/features/library/backend/useVersionUpdate';
import { LibraryItemID, VersionID } from '@/features/library/models/library';
import { useDialogsStore } from '@/stores/dialogs';
import { errors } from '@/utils/labels';
import { errorMsg } from '@/utils/labels';
import { useRSFormSuspense } from '../../backend/useRSForm';
import TableVersions from './TableVersions';
@ -105,7 +105,7 @@ function DlgEditVersions() {
<div className='cc-icons'>
<MiniButton
type='submit'
title={isValid ? 'Сохранить изменения' : errors.versionTaken}
title={isValid ? 'Сохранить изменения' : errorMsg.versionTaken}
disabled={!isDirty || !isValid || isProcessing}
icon={<IconSave size='1.25rem' className='icon-primary' />}
/>

View File

@ -9,7 +9,7 @@ import { Label, TextArea } from '@/components/Input';
import { ModalForm } from '@/components/Modal';
import { HelpTopic } from '@/features/help/models/helpTopic';
import { useDialogsStore } from '@/stores/dialogs';
import { prompts } from '@/utils/labels';
import { promptText } from '@/utils/labels';
import { useGenerateLexeme } from '../../backend/cctext/useGenerateLexeme';
import { useInflectText } from '../../backend/cctext/useInflectText';
@ -93,7 +93,7 @@ function DlgEditWordForms() {
function handleGenerateLexeme() {
if (forms.length > 0) {
if (!window.confirm(prompts.generateWordforms)) {
if (!window.confirm(promptText.generateWordforms)) {
return;
}
}

View File

@ -6,7 +6,7 @@ import { ReactFlowProvider } from 'reactflow';
import { ModalView } from '@/components/Modal';
import { HelpTopic } from '@/features/help/models/helpTopic';
import { useDialogsStore } from '@/stores/dialogs';
import { errors } from '@/utils/labels';
import { errorMsg } from '@/utils/labels';
import { ITypeInfo } from '../../models/rslang';
import { TMGraph } from '../../models/TMGraph';
@ -26,7 +26,7 @@ function DlgShowTypeGraph() {
})();
if (graph.nodes.length === 0) {
toast.error(errors.typeStructureFailed);
toast.error(errorMsg.typeStructureFailed);
hideDialog();
return null;
}

View File

@ -5,7 +5,7 @@ import { MiniButton } from '@/components/Control';
import { IconEdit } from '@/components/Icons';
import { useDialogsStore } from '@/stores/dialogs';
import { useModificationStore } from '@/stores/modification';
import { tooltips } from '@/utils/labels';
import { tooltipText } from '@/utils/labels';
import { useMutatingRSForm } from '../../../backend/useMutatingRSForm';
import { IConstituenta } from '../../../models/rsform';
@ -32,7 +32,7 @@ function EditorControls({ constituenta, disabled, onEditTerm }: EditorControlsPr
<Overlay position='top-1 left-[4.7rem]' className='flex select-none'>
{!disabled || isProcessing ? (
<MiniButton
title={isModified ? tooltips.unsaved : `Редактировать словоформы термина`}
title={isModified ? tooltipText.unsaved : `Редактировать словоформы термина`}
noHover
onClick={onEditTerm}
icon={<IconEdit size='1rem' className='icon-primary' />}
@ -53,7 +53,7 @@ function EditorControls({ constituenta, disabled, onEditTerm }: EditorControlsPr
{!disabled || isProcessing ? (
<MiniButton
noHover
title={isModified ? tooltips.unsaved : 'Переименовать конституенту'}
title={isModified ? tooltipText.unsaved : 'Переименовать конституенту'}
onClick={handleRenameCst}
icon={<IconEdit size='1rem' className='icon-primary' />}
disabled={isModified}

View File

@ -14,7 +14,7 @@ import { CProps } from '@/components/props';
import { Indicator } from '@/components/View';
import { useDialogsStore } from '@/stores/dialogs';
import { useModificationStore } from '@/stores/modification';
import { errors } from '@/utils/labels';
import { errorMsg } from '@/utils/labels';
import { ICstUpdateDTO, schemaCstUpdate } from '../../../backend/api';
import { useCstUpdate } from '../../../backend/useCstUpdate';
@ -103,7 +103,7 @@ function FormConstituenta({ disabled, id, toggleReset, schema, activeCst, onOpen
function handleTypeGraph(event: CProps.EventMouse) {
if ((localParse && !localParse.parseResult) || activeCst.parse.status !== ParsingStatus.VERIFIED) {
toast.error(errors.typeStructureFailed);
toast.error(errorMsg.typeStructureFailed);
return;
}
event.stopPropagation();

View File

@ -23,7 +23,7 @@ import { useFindPredecessor } from '@/features/oss/backend/useFindPredecessor';
import { useModificationStore } from '@/stores/modification';
import { usePreferencesStore } from '@/stores/preferences';
import { PARAMETER } from '@/utils/constants';
import { tooltips } from '@/utils/labels';
import { tooltipText } from '@/utils/labels';
import { prepareTooltip } from '@/utils/utils';
import { useMutatingRSForm } from '../../../backend/useMutatingRSForm';
@ -106,7 +106,7 @@ function ToolbarConstituenta({
onClick={() => controller.createCst(activeCst?.cst_type, false)}
/>
<MiniButton
titleHtml={isModified ? tooltips.unsaved : prepareTooltip('Клонировать конституенту', 'Alt + V')}
titleHtml={isModified ? tooltipText.unsaved : prepareTooltip('Клонировать конституенту', 'Alt + V')}
icon={<IconClone size='1.25rem' className='icon-green' />}
disabled={disabled || isModified}
onClick={controller.cloneCst}

View File

@ -12,7 +12,7 @@ import { HelpTopic } from '@/features/help/models/helpTopic';
import { useDialogsStore } from '@/stores/dialogs';
import { usePreferencesStore } from '@/stores/preferences';
import { transformAST } from '@/utils/codemirror';
import { errors } from '@/utils/labels';
import { errorMsg } from '@/utils/labels';
import { ICheckConstituentaDTO } from '../../../backend/api';
import { useCheckConstituenta } from '../../../backend/useCheckConstituenta';
@ -141,7 +141,7 @@ function EditorRSExpression({
} else {
handleCheckExpression(parse => {
if (!parse.astText) {
toast.error(errors.astFailed);
toast.error(errorMsg.astFailed);
} else {
showAST({ syntaxTree: parse.ast, expression: getDefinitionPrefix(activeCst) + value });
}

View File

@ -29,7 +29,7 @@ import { useDialogsStore } from '@/stores/dialogs';
import { useModificationStore } from '@/stores/modification';
import { useRoleStore } from '@/stores/role';
import { prefixes } from '@/utils/constants';
import { prompts } from '@/utils/labels';
import { promptText } from '@/utils/labels';
import InfoUsers from './InfoUsers';
@ -60,7 +60,7 @@ function EditorLibraryItem({ controller }: EditorLibraryItemProps) {
if (newValue === controller.schema.owner) {
return;
}
if (!window.confirm(prompts.ownerChange)) {
if (!window.confirm(promptText.ownerChange)) {
return;
}
void setOwner({ itemID: controller.schema.id, owner: newValue });

View File

@ -11,7 +11,7 @@ import { UserRole } from '@/features/users/models/user';
import { useModificationStore } from '@/stores/modification';
import { useRoleStore } from '@/stores/role';
import { PARAMETER } from '@/utils/constants';
import { tooltips } from '@/utils/labels';
import { tooltipText } from '@/utils/labels';
import { prepareTooltip } from '@/utils/utils';
import { sharePage } from '@/utils/utils';
@ -60,7 +60,7 @@ function ToolbarRSFormCard({ controller, onSubmit }: ToolbarRSFormCardProps) {
/>
) : null}
<MiniButton
titleHtml={tooltips.shareItem(controller.schema.access_policy)}
titleHtml={tooltipText.shareItem(controller.schema.access_policy)}
icon={<IconShare size='1.25rem' className='icon-primary' />}
onClick={sharePage}
disabled={controller.schema.access_policy !== AccessPolicy.PUBLIC}

View File

@ -9,7 +9,7 @@ import { useVersionRestore } from '@/features/library/backend/useVersionRestore'
import { useDialogsStore } from '@/stores/dialogs';
import { useModificationStore } from '@/stores/modification';
import { PARAMETER } from '@/utils/constants';
import { prompts } from '@/utils/labels';
import { promptText } from '@/utils/labels';
import { promptUnsaved } from '@/utils/utils';
import { useRSEdit } from '../RSEditContext';
@ -27,7 +27,7 @@ function ToolbarVersioning({ blockReload }: ToolbarVersioningProps) {
const showEditVersions = useDialogsStore(state => state.showEditVersions);
function handleRestoreVersion() {
if (!controller.schema.version || !window.confirm(prompts.restoreArchive)) {
if (!controller.schema.version || !window.confirm(promptText.restoreArchive)) {
return;
}
void versionRestore({ versionID: controller.schema.version }).then(() => controller.navigateVersion(undefined));

View File

@ -10,7 +10,7 @@ import { type RowSelectionState } from '@/components/DataTable';
import { IconCSV } from '@/components/Icons';
import { SearchBar } from '@/components/shared/SearchBar';
import { useFitHeight } from '@/stores/appLayout';
import { information } from '@/utils/labels';
import { infoMsg } from '@/utils/labels';
import { convertToCSV } from '@/utils/utils';
import { useMutatingRSForm } from '../../../backend/useMutatingRSForm';
@ -37,7 +37,7 @@ function EditorRSList() {
function handleDownloadCSV() {
if (filtered.length === 0) {
toast.error(information.noDataToExport);
toast.error(infoMsg.noDataToExport);
return;
}
const blob = convertToCSV(filtered);

View File

@ -25,7 +25,7 @@ import { useMainHeight } from '@/stores/appLayout';
import { useDialogsStore } from '@/stores/dialogs';
import { APP_COLORS } from '@/styling/colors';
import { PARAMETER } from '@/utils/constants';
import { errors } from '@/utils/labels';
import { errorMsg } from '@/utils/labels';
import { useMutatingRSForm } from '../../../backend/useMutatingRSForm';
import { colorBgGraphNode } from '../../../colors';
@ -188,7 +188,7 @@ function TGFlow() {
function handleSaveImage() {
const canvas: HTMLElement | null = document.querySelector('.react-flow__viewport');
if (canvas === null) {
toast.error(errors.imageFailed);
toast.error(errorMsg.imageFailed);
return;
}
@ -214,7 +214,7 @@ function TGFlow() {
})
.catch(error => {
console.error(error);
toast.error(errors.imageFailed);
toast.error(errorMsg.imageFailed);
});
}

View File

@ -39,7 +39,7 @@ import { useDialogsStore } from '@/stores/dialogs';
import { useModificationStore } from '@/stores/modification';
import { useRoleStore } from '@/stores/role';
import { EXTEOR_TRS_FILE } from '@/utils/constants';
import { describeAccessMode, labelAccessMode, tooltips } from '@/utils/labels';
import { describeAccessMode, labelAccessMode, tooltipText } from '@/utils/labels';
import { generatePageQR, promptUnsaved, sharePage } from '@/utils/utils';
import { useCstSubstitute } from '../../backend/useCstSubstitute';
@ -239,7 +239,7 @@ function MenuRSTabs() {
<Dropdown isOpen={schemaMenu.isOpen}>
<DropdownButton
text='Поделиться'
titleHtml={tooltips.shareItem(controller.schema.access_policy)}
titleHtml={tooltipText.shareItem(controller.schema.access_policy)}
icon={<IconShare size='1rem' className='icon-primary' />}
onClick={handleShare}
disabled={controller.schema.access_policy !== AccessPolicy.PUBLIC}

View File

@ -14,7 +14,7 @@ import { useModificationStore } from '@/stores/modification';
import { usePreferencesStore } from '@/stores/preferences';
import { useRoleStore } from '@/stores/role';
import { PARAMETER, prefixes } from '@/utils/constants';
import { prompts } from '@/utils/labels';
import { promptText } from '@/utils/labels';
import { promptUnsaved } from '@/utils/utils';
import { ICstCreateDTO } from '../../backend/api';
@ -166,7 +166,7 @@ export const RSEditState = ({
}
function deleteSchema() {
if (!window.confirm(prompts.deleteLibraryItem)) {
if (!window.confirm(promptText.deleteLibraryItem)) {
return;
}
const ossID = schema.oss.length > 0 ? schema.oss[0].id : undefined;

View File

@ -4,7 +4,7 @@ import { z } from 'zod';
import { axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport';
import { DELAYS } from '@/backend/configuration';
import { patterns } from '@/utils/constants';
import { errors, information } from '@/utils/labels';
import { errorMsg, infoMsg } from '@/utils/labels';
import { IUserInfo, IUserProfile } from '../models/user';
@ -13,15 +13,15 @@ import { IUserInfo, IUserProfile } from '../models/user';
*/
export const schemaUserSignup = z
.object({
username: z.string().nonempty(errors.requiredField).regex(RegExp(patterns.login), errors.loginFormat),
email: z.string().email(errors.emailField),
username: z.string().nonempty(errorMsg.requiredField).regex(RegExp(patterns.login), errorMsg.loginFormat),
email: z.string().email(errorMsg.emailField),
first_name: z.string(),
last_name: z.string(),
password: z.string().nonempty(errors.requiredField),
password2: z.string().nonempty(errors.requiredField)
password: z.string().nonempty(errorMsg.requiredField),
password2: z.string().nonempty(errorMsg.requiredField)
})
.refine(schema => schema.password === schema.password2, { path: ['password2'], message: errors.passwordsMismatch });
.refine(schema => schema.password === schema.password2, { path: ['password2'], message: errorMsg.passwordsMismatch });
/**
* Represents signup data, used to create new users.
@ -32,7 +32,7 @@ export type IUserSignupDTO = z.infer<typeof schemaUserSignup>;
* Represents user data, intended to update user profile in persistent storage.
*/
export const schemaUpdateProfile = z.object({
email: z.string().email(errors.emailField),
email: z.string().email(errorMsg.emailField),
first_name: z.string(),
last_name: z.string()
});
@ -70,7 +70,7 @@ export const usersApi = {
endpoint: '/users/api/signup',
request: {
data: data,
successMessage: createdUser => information.newUser(createdUser.username)
successMessage: createdUser => infoMsg.newUser(createdUser.username)
}
}),
@ -79,7 +79,7 @@ export const usersApi = {
endpoint: '/users/api/profile',
request: {
data: data,
successMessage: information.changesSaved
successMessage: infoMsg.changesSaved
}
})
};

View File

@ -89,7 +89,7 @@ export function describeLibraryItemType(itemType: LibraryItemType): string {
/**
* UI info descriptors.
*/
export const information = {
export const infoMsg = {
changesSaved: 'Изменения сохранены',
pathReady: 'Путь скопирован',
@ -124,7 +124,7 @@ export const information = {
/**
* UI error descriptors.
*/
export const errors = {
export const errorMsg = {
astFailed: 'Невозможно построить дерево разбора',
typeStructureFailed: 'Структура отсутствует',
passwordsMismatch: 'Пароли не совпадают',
@ -145,7 +145,7 @@ export const errors = {
/**
* UI tooltip descriptors.
*/
export const tooltips = {
export const tooltipText = {
unsaved: 'Сохраните или отмените изменения',
shareItem: (policy?: AccessPolicy) =>
policy === AccessPolicy.PUBLIC ? 'Поделиться схемой' : 'Поделиться можно только <br/>открытой схемой'
@ -154,7 +154,7 @@ export const tooltips = {
/**
* UI prompt messages.
*/
export const prompts = {
export const promptText = {
promptUnsaved: 'Присутствуют несохраненные изменения. Продолжить без их учета?',
deleteLibraryItem: 'Вы уверены, что хотите удалить данную схему?',
deleteOSS:

View File

@ -5,7 +5,7 @@
import { AxiosError, AxiosHeaderValue, AxiosResponse, isAxiosError } from 'axios';
import { toast } from 'react-toastify';
import { information, prompts } from './labels';
import { infoMsg, promptText } from './labels';
/**
* Checks if arguments is Node.
@ -106,7 +106,7 @@ export function convertBase64ToBlob(base64String: string): Uint8Array {
* Prompt user of confirming discarding changes before continue.
*/
export function promptUnsaved(): boolean {
return window.confirm(prompts.promptUnsaved);
return window.confirm(promptText.promptUnsaved);
}
/**
@ -195,7 +195,7 @@ export function sharePage() {
const url = currentRef.includes('?') ? currentRef + '&share' : currentRef + '?share';
navigator.clipboard
.writeText(url)
.then(() => toast.success(information.linkReady))
.then(() => toast.success(infoMsg.linkReady))
.catch(console.error);
}