feat: add "back to objects" link on the works page

The works page of an object had no way back except the sidebar. The link
goes straight to the objects of the same project, so it also works when
the page was opened by a direct URL.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Тимур Городецкий
2026-10-23 17:52:12 +05:00
parent 10ba9a6623
commit f3e098ee84
4 changed files with 25 additions and 2 deletions
@@ -10,6 +10,20 @@ $toggle-size: 20px;
width: 100%; width: 100%;
} }
// «← К объектам» — как «← Вернуться назад» в форме отчёта.
.backLink {
align-self: flex-start;
color: $navy-600;
font-size: $fs-sm;
font-weight: 500;
text-decoration: none;
&:hover {
color: $navy-900;
text-decoration: underline;
}
}
.container { .container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -8,5 +8,7 @@ import { WorksPageContent } from './WorksPageContent';
*/ */
export const WorksPage: React.FC = () => { export const WorksPage: React.FC = () => {
const { route } = useRouter(); const { route } = useRouter();
return <WorksPageContent key={route.objectId ?? ''} objectId={route.objectId ?? ''} />; return (
<WorksPageContent key={route.objectId ?? ''} objectId={route.objectId ?? ''} projectId={route.projectId} />
);
}; };
@@ -2,6 +2,7 @@ import * as React from 'react';
import { Alert, Button, confirmModal, Spinner } from '@tnsu/ui-kit'; import { Alert, Button, confirmModal, Spinner } from '@tnsu/ui-kit';
import { useAppServices } from '../../app/AppServicesContext'; import { useAppServices } from '../../app/AppServicesContext';
import { EmptyState } from '../../shared/components/EmptyState'; import { EmptyState } from '../../shared/components/EmptyState';
import { RouteLink } from '../../app/routing/RouteLink';
import { ContextMenu, IContextMenuItem, IMenuAnchor } from '../_tree/ContextMenu'; import { ContextMenu, IContextMenuItem, IMenuAnchor } from '../_tree/ContextMenu';
import { TreePageHeader } from '../_tree/TreePageHeader'; import { TreePageHeader } from '../_tree/TreePageHeader';
import { flattenVisible, toggleId } from '../_tree/treeRules'; import { flattenVisible, toggleId } from '../_tree/treeRules';
@@ -28,9 +29,11 @@ const MENU_OFFSET_PX = 4;
interface Props { interface Props {
objectId: string; objectId: string;
/** Для ссылки «← К объектам» — объекты того же проекта. */
projectId: string | undefined;
} }
export const WorksPageContent: React.FC<Props> = ({ objectId }) => { export const WorksPageContent: React.FC<Props> = ({ objectId, projectId }) => {
const services = useAppServices(); const services = useAppServices();
const repository = React.useMemo( const repository = React.useMemo(
() => () =>
@@ -112,6 +115,9 @@ export const WorksPageContent: React.FC<Props> = ({ objectId }) => {
return ( return (
<div className={styles.page}> <div className={styles.page}>
<RouteLink className={styles.backLink} to={{ page: 'objects', projectId }}>
{WORKS_TEXTS.backToObjects}
</RouteLink>
<TreePageHeader icon="clipboard" title={data.headerLabel} /> <TreePageHeader icon="clipboard" title={data.headerLabel} />
<div className={styles.container}> <div className={styles.container}>
{data.canEdit && <div className={styles.toolbar}>{addButton(WORKS_TEXTS.addWork)}</div>} {data.canEdit && <div className={styles.toolbar}>{addButton(WORKS_TEXTS.addWork)}</div>}
@@ -2,6 +2,7 @@
export const WORKS_TEXTS = { export const WORKS_TEXTS = {
defaultHeader: 'ОБЪЕКТЫ ПРОЕКТА', defaultHeader: 'ОБЪЕКТЫ ПРОЕКТА',
backToObjects: '← К объектам',
addWork: 'Добавить работу', addWork: 'Добавить работу',
addFirst: '+ Добавить работу', addFirst: '+ Добавить работу',
columns: { columns: {