mirror of
https://github.com/khairul169/vaulterm.git
synced 2025-04-28 16:49:39 +07:00
feat: update host selection ux
This commit is contained in:
parent
b0932c39b1
commit
4f9578ffce
49
frontend/pages/hosts/components/host-actions.tsx
Normal file
49
frontend/pages/hosts/components/host-actions.tsx
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import React from "react";
|
||||||
|
import MenuButton from "@/components/ui/menu-button";
|
||||||
|
import { Button, GetProps } from "tamagui";
|
||||||
|
import Icons from "@/components/ui/icons";
|
||||||
|
|
||||||
|
type Props = GetProps<typeof Button> & {
|
||||||
|
onSelect?: (() => void) | null;
|
||||||
|
onEdit?: (() => void) | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const HostActions = ({ onSelect, onEdit, ...props }: Props) => {
|
||||||
|
if (!onSelect && !onEdit) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MenuButton
|
||||||
|
placement="bottom-end"
|
||||||
|
trigger={
|
||||||
|
<Button
|
||||||
|
circular
|
||||||
|
bg="$colorTransparent"
|
||||||
|
icon={<Icons name="dots-vertical" size={20} />}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{onSelect != null && (
|
||||||
|
<MenuButton.Item
|
||||||
|
onPress={onSelect}
|
||||||
|
icon={<Icons name="cursor-pointer" size={16} />}
|
||||||
|
>
|
||||||
|
Select
|
||||||
|
</MenuButton.Item>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{onEdit != null && (
|
||||||
|
<MenuButton.Item
|
||||||
|
onPress={onEdit}
|
||||||
|
icon={<Icons name="pencil" size={16} />}
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</MenuButton.Item>
|
||||||
|
)}
|
||||||
|
</MenuButton>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default HostActions;
|
@ -10,16 +10,9 @@ type HostItemProps = {
|
|||||||
selected?: boolean;
|
selected?: boolean;
|
||||||
onMultiTap: () => void;
|
onMultiTap: () => void;
|
||||||
onTap?: () => void;
|
onTap?: () => void;
|
||||||
onEdit?: (() => void) | null;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const HostItem = ({
|
const HostItem = ({ host, selected, onMultiTap, onTap }: HostItemProps) => {
|
||||||
host,
|
|
||||||
selected,
|
|
||||||
onMultiTap,
|
|
||||||
onTap,
|
|
||||||
onEdit,
|
|
||||||
}: HostItemProps) => {
|
|
||||||
return (
|
return (
|
||||||
<MultiTapPressable
|
<MultiTapPressable
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
@ -64,23 +57,6 @@ const HostItem = ({
|
|||||||
{host.host}
|
{host.host}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{onEdit != null && (
|
|
||||||
<Button
|
|
||||||
circular
|
|
||||||
opacity={0}
|
|
||||||
$sm={{ opacity: 1 }}
|
|
||||||
$group-hover={{ opacity: 1 }}
|
|
||||||
animation="quick"
|
|
||||||
animateOnly={["opacity"]}
|
|
||||||
onPress={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
onEdit();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Icons name="pencil" size={16} />
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</XStack>
|
</XStack>
|
||||||
</Card>
|
</Card>
|
||||||
</MultiTapPressable>
|
</MultiTapPressable>
|
||||||
|
@ -7,6 +7,7 @@ import { hostFormModal } from "./form";
|
|||||||
import { GridLayout } from "@/components/ui/grid-view";
|
import { GridLayout } from "@/components/ui/grid-view";
|
||||||
import HostItem from "./host-item";
|
import HostItem from "./host-item";
|
||||||
import { useHosts } from "../hooks/query";
|
import { useHosts } from "../hooks/query";
|
||||||
|
import HostActions from "./host-actions";
|
||||||
|
|
||||||
type HostsListProps = {
|
type HostsListProps = {
|
||||||
allowEdit?: boolean;
|
allowEdit?: boolean;
|
||||||
@ -115,7 +116,7 @@ const HostList = ({
|
|||||||
<ItemList
|
<ItemList
|
||||||
data={groups}
|
data={groups}
|
||||||
selected={selected}
|
selected={selected}
|
||||||
onTap={onSelectedChange ? onSelect : undefined}
|
onTap={selected.length > 0 ? onSelect : undefined}
|
||||||
onMultiTap={(group) => onParentIdChange?.(group.id)}
|
onMultiTap={(group) => onParentIdChange?.(group.id)}
|
||||||
onEdit={allowEdit ? onEdit : undefined}
|
onEdit={allowEdit ? onEdit : undefined}
|
||||||
/>
|
/>
|
||||||
@ -132,9 +133,10 @@ const HostList = ({
|
|||||||
<ItemList
|
<ItemList
|
||||||
data={hosts}
|
data={hosts}
|
||||||
selected={selected}
|
selected={selected}
|
||||||
onTap={onSelectedChange ? onSelect : undefined}
|
onTap={selected.length > 0 ? onSelect : undefined}
|
||||||
onMultiTap={onOpenTerminal}
|
onMultiTap={onOpenTerminal}
|
||||||
onEdit={allowEdit ? onEdit : undefined}
|
onEdit={allowEdit ? onEdit : undefined}
|
||||||
|
onSelect={onSelectedChange ? onSelect : undefined}
|
||||||
/>
|
/>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
)}
|
)}
|
||||||
@ -148,6 +150,7 @@ type ItemListProps = {
|
|||||||
onTap?: (host: any) => void;
|
onTap?: (host: any) => void;
|
||||||
onMultiTap?: (host: any) => void;
|
onMultiTap?: (host: any) => void;
|
||||||
onEdit?: (host: any) => void;
|
onEdit?: (host: any) => void;
|
||||||
|
onSelect?: (host: any) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ItemList = ({
|
const ItemList = ({
|
||||||
@ -156,6 +159,7 @@ const ItemList = ({
|
|||||||
onTap,
|
onTap,
|
||||||
onMultiTap,
|
onMultiTap,
|
||||||
onEdit,
|
onEdit,
|
||||||
|
onSelect,
|
||||||
}: ItemListProps) => (
|
}: ItemListProps) => (
|
||||||
<GridLayout
|
<GridLayout
|
||||||
data={data}
|
data={data}
|
||||||
@ -163,13 +167,21 @@ const ItemList = ({
|
|||||||
padding="$2"
|
padding="$2"
|
||||||
gap="$2.5"
|
gap="$2.5"
|
||||||
renderItem={(host: any) => (
|
renderItem={(host: any) => (
|
||||||
<HostItem
|
<View position="relative" h="100%">
|
||||||
host={host}
|
<HostItem
|
||||||
selected={selected?.includes(host.id)}
|
host={host}
|
||||||
onTap={onEdit ? () => onTap?.(host) : undefined}
|
selected={selected?.includes(host.id)}
|
||||||
onMultiTap={() => onMultiTap?.(host)}
|
onTap={() => onTap?.(host)}
|
||||||
onEdit={onEdit ? () => onEdit?.(host) : undefined}
|
onMultiTap={() => onMultiTap?.(host)}
|
||||||
/>
|
/>
|
||||||
|
<HostActions
|
||||||
|
position="absolute"
|
||||||
|
top="$2"
|
||||||
|
right="$2"
|
||||||
|
onSelect={onSelect ? () => onSelect?.(host) : undefined}
|
||||||
|
onEdit={onEdit ? () => onEdit?.(host) : undefined}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user