Improve navigation. Ctrl + click - open in new tab

This commit is contained in:
IRBorisov 2024-04-07 19:45:07 +03:00
parent f041bd172e
commit a5ca411cb5
11 changed files with 34 additions and 19 deletions

View File

@ -4,6 +4,7 @@ import { FaSquarePlus } from 'react-icons/fa6';
import { IoLibrary } from 'react-icons/io5';
import { IconManuals } from '@/components/Icons';
import { CProps } from '@/components/props';
import { useConceptNavigation } from '@/context/NavigationContext';
import { useConceptOptions } from '@/context/OptionsContext';
import { animateNavigation } from '@/styling/animations';
@ -18,10 +19,10 @@ function Navigation() {
const router = useConceptNavigation();
const { noNavigationAnimation } = useConceptOptions();
const navigateHome = () => router.push(urls.home);
const navigateLibrary = () => router.push(urls.library);
const navigateHelp = () => router.push(urls.manuals);
const navigateCreateNew = () => router.push(urls.create_schema);
const navigateHome = (event: CProps.EventMouse) => router.push(urls.home, event.ctrlKey);
const navigateLibrary = (event: CProps.EventMouse) => router.push(urls.library, event.ctrlKey);
const navigateHelp = (event: CProps.EventMouse) => router.push(urls.manuals, event.ctrlKey);
const navigateCreateNew = (event: CProps.EventMouse) => router.push(urls.create_schema, event.ctrlKey);
return (
<nav

View File

@ -6,7 +6,7 @@ import { globals } from '@/utils/constants';
interface NavigationButtonProps extends CProps.Titled {
text?: string;
icon: React.ReactNode;
onClick?: () => void;
onClick?: (event: CProps.EventMouse) => void;
}
function NavigationButton({ icon, title, titleHtml, hideTitle, onClick, text }: NavigationButtonProps) {

View File

@ -1,6 +1,7 @@
import { LuLogOut, LuMoon, LuSun } from 'react-icons/lu';
import { IconHelp, IconHelpOff, IconUser } from '@/components/Icons';
import { CProps } from '@/components/props';
import Dropdown from '@/components/ui/Dropdown';
import DropdownButton from '@/components/ui/DropdownButton';
import { useAuth } from '@/context/AuthContext';
@ -19,9 +20,9 @@ function UserDropdown({ isOpen, hideDropdown }: UserDropdownProps) {
const router = useConceptNavigation();
const { user, logout } = useAuth();
function navigateProfile() {
function navigateProfile(event: CProps.EventMouse) {
hideDropdown();
router.push(urls.profile);
router.push(urls.profile, event.ctrlKey);
}
function logoutAndRedirect() {

View File

@ -43,4 +43,6 @@ export namespace CProps {
export type AnimatedButton = Titled & Omit<HTMLMotionProps<'button'>, 'type'>;
export type AnimatedDiv = HTMLMotionProps<'div'>;
export type EventMouse = React.MouseEvent<Element, MouseEvent>;
}

View File

@ -35,7 +35,7 @@ function Checkbox({
}
}, [disabled, setValue]);
function handleClick(event: React.MouseEvent<HTMLButtonElement, MouseEvent>): void {
function handleClick(event: CProps.EventMouse): void {
event.preventDefault();
if (disabled || !setValue) {
return;

View File

@ -4,6 +4,7 @@ import { useMemo } from 'react';
import { globals } from '@/utils/constants';
import { CheckboxChecked, CheckboxNull } from '../Icons';
import { CProps } from '../props';
import { CheckboxProps } from './Checkbox';
export interface CheckboxTristateProps extends Omit<CheckboxProps, 'value' | 'setValue'> {
@ -32,7 +33,7 @@ function CheckboxTristate({
}
}, [disabled, setValue]);
function handleClick(event: React.MouseEvent<HTMLButtonElement, MouseEvent>): void {
function handleClick(event: CProps.EventMouse): void {
event.preventDefault();
if (disabled || !setValue) {
return;

View File

@ -44,8 +44,8 @@ export interface DataTableProps<TData extends RowData>
conditionalRowStyles?: IConditionalStyle<TData>[];
noDataComponent?: React.ReactNode;
onRowClicked?: (rowData: TData, event: React.MouseEvent<Element, MouseEvent>) => void;
onRowDoubleClicked?: (rowData: TData, event: React.MouseEvent<Element, MouseEvent>) => void;
onRowClicked?: (rowData: TData, event: CProps.EventMouse) => void;
onRowDoubleClicked?: (rowData: TData, event: CProps.EventMouse) => void;
enableRowSelection?: boolean;
rowSelection?: RowSelectionState;

View File

@ -1,5 +1,7 @@
import { Cell, flexRender, Row, Table } from '@tanstack/react-table';
import { CProps } from '@/components/props';
import { IConditionalStyle } from '.';
import SelectRow from './SelectRow';
@ -12,8 +14,8 @@ interface TableBodyProps<TData> {
lastSelected: string | undefined;
setLastSelected: React.Dispatch<React.SetStateAction<string | undefined>>;
onRowClicked?: (rowData: TData, event: React.MouseEvent<Element, MouseEvent>) => void;
onRowDoubleClicked?: (rowData: TData, event: React.MouseEvent<Element, MouseEvent>) => void;
onRowClicked?: (rowData: TData, event: CProps.EventMouse) => void;
onRowDoubleClicked?: (rowData: TData, event: CProps.EventMouse) => void;
}
function TableBody<TData>({
@ -26,7 +28,7 @@ function TableBody<TData>({
onRowClicked,
onRowDoubleClicked
}: TableBodyProps<TData>) {
function handleRowClicked(target: Row<TData>, event: React.MouseEvent<Element, MouseEvent>) {
function handleRowClicked(target: Row<TData>, event: CProps.EventMouse) {
if (onRowClicked) {
onRowClicked(target.original, event);
}

View File

@ -6,7 +6,7 @@ import { useLocation, useNavigate } from 'react-router-dom';
import { globals } from '@/utils/constants';
interface INavigationContext {
push: (path: string) => void;
push: (path: string, newTab?: boolean) => void;
replace: (path: string) => void;
back: () => void;
forward: () => void;
@ -50,7 +50,11 @@ export const NavigationState = ({ children }: NavigationStateProps) => {
}, []);
const push = useCallback(
(path: string) => {
(path: string, newTab?: boolean) => {
if (newTab) {
window.open(`${path}`, '_blank');
return;
}
if (validate()) {
scrollTop();
router(path);

View File

@ -6,6 +6,7 @@ import { useIntl } from 'react-intl';
import { urls } from '@/app/urls';
import BadgeHelp from '@/components/man/BadgeHelp';
import { CProps } from '@/components/props';
import DataTable, { createColumnHelper, VisibilityState } from '@/components/ui/DataTable';
import FlexColumn from '@/components/ui/FlexColumn';
import TextURL from '@/components/ui/TextURL';
@ -34,7 +35,9 @@ function ViewLibrary({ items, resetQuery }: ViewLibraryProps) {
const { getUserLabel } = useUsers();
const [itemsPerPage, setItemsPerPage] = useLocalStorage<number>(storage.libraryPagination, 50);
const handleOpenItem = (item: ILibraryItem) => router.push(urls.schema(item.id));
function handleOpenItem(item: ILibraryItem, event: CProps.EventMouse) {
router.push(urls.schema(item.id), event.ctrlKey);
}
const windowSize = useWindowSize();

View File

@ -4,6 +4,7 @@ import clsx from 'clsx';
import { useCallback, useLayoutEffect, useMemo, useState } from 'react';
import ConstituentaBadge from '@/components/info/ConstituentaBadge';
import { CProps } from '@/components/props';
import DataTable, { createColumnHelper, RowSelectionState, VisibilityState } from '@/components/ui/DataTable';
import FlexColumn from '@/components/ui/FlexColumn';
import { useConceptOptions } from '@/context/OptionsContext';
@ -45,7 +46,7 @@ function RSTable({ items, maxHeight, enableSelection, selected, setSelected, onE
}, [windowSize]);
const handleRowClicked = useCallback(
(cst: IConstituenta, event: React.MouseEvent<Element, MouseEvent>) => {
(cst: IConstituenta, event: CProps.EventMouse) => {
if (event.altKey) {
event.preventDefault();
onEdit(cst.id);
@ -55,7 +56,7 @@ function RSTable({ items, maxHeight, enableSelection, selected, setSelected, onE
);
const handleRowDoubleClicked = useCallback(
(cst: IConstituenta, event: React.MouseEvent<Element, MouseEvent>) => {
(cst: IConstituenta, event: CProps.EventMouse) => {
event.preventDefault();
onEdit(cst.id);
},