Skip to content

Commit c71a680

Browse files
committed
feat(hosts): add node linking and enhance host form UI
- Adds multi-select field for linking nodes to hosts - Converts host creation/editing modals to drawers - Updates host card to display linked nodes with country flags - Improves layout and responsiveness of host components - Enhances form footer organization and button placement
1 parent 8a1a94a commit c71a680

File tree

32 files changed

+904
-71
lines changed

32 files changed

+904
-71
lines changed

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
"@monaco-editor/react": "^4.7.0",
6060
"@noble/post-quantum": "^0.5.2",
6161
"@paralleldrive/cuid2": "2.2.2",
62-
"@remnawave/backend-contract": "2.1.65",
62+
"@remnawave/backend-contract": "2.1.67",
6363
"@stablelib/base64": "^2.0.1",
6464
"@stablelib/x25519": "^2.0.1",
6565
"@tabler/icons-react": "^3.35.0",

public/locales/en/remnawave.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,9 @@
430430
"misc-settings": "Misc settings",
431431
"shuffle-host": "Shuffle Host",
432432
"mihomo-specific": "Mihomo Specific",
433-
"enable-x25519mlkem768": "Enable x25519mlkem768"
433+
"enable-x25519mlkem768": "Enable x25519mlkem768",
434+
"pick-nodes-which-resolved-from-this-host-only-visual-assignment": "Pick nodes which resolved from this host. Only visual assignment.",
435+
"nodes": "Nodes"
434436
},
435437
"base-node-form": {
436438
"country": "Country",
@@ -1654,5 +1656,16 @@
16541656
"hourly-request-statistics": "Hourly Request Statistics",
16551657
"no-hourly-data-available": "No hourly data available"
16561658
}
1659+
},
1660+
"linked-hosts-drawer": {
1661+
"widget": {
1662+
"assigned-hosts": "Assigned hosts",
1663+
"no-hosts-assigned-to-this-node": "No hosts assigned to this node"
1664+
}
1665+
},
1666+
"get-node-linked-hosts": {
1667+
"feature": {
1668+
"linked-hosts": "Linked hosts"
1669+
}
16571670
}
16581671
}

src/entities/dashboard/modal-store/modal-states.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export const MODALS = {
1616
CREATE_INFRA_BILLING_NODE_MODAL: 'CREATE_INFRA_BILLING_NODE_MODAL',
1717
EDIT_NODE_BY_UUID_MODAL: 'EDIT_NODE_BY_UUID_MODAL',
1818
SHOW_NODE_USERS_USAGE_DRAWER: 'SHOW_NODE_USERS_USAGE_DRAWER',
19+
SHOW_NODE_LINKED_HOSTS_DRAWER: 'SHOW_NODE_LINKED_HOSTS_DRAWER',
1920
RENAME_SQUAD_OR_CONFIG_PROFILE_MODAL: 'RENAME_SQUAD_OR_CONFIG_PROFILE_MODAL',
2021
INTERNAL_SQUAD_ACCESSIBLE_NODES_DRAWER: 'INTERNAL_SQUAD_ACCESSIBLE_NODES_DRAWER',
2122
CONFIG_PROFILE_SHOW_INBOUNDS_DRAWER: 'CONFIG_PROFILE_SHOW_INBOUNDS_DRAWER'
@@ -38,6 +39,9 @@ export interface ModalInternalStates {
3839
name: string
3940
uuid: string
4041
}
42+
SHOW_NODE_LINKED_HOSTS_DRAWER: {
43+
nodeUuid: string
44+
}
4145
SHOW_NODE_USERS_USAGE_DRAWER: {
4246
nodeUuid: string
4347
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { useTranslation } from 'react-i18next'
2+
import { TbServerCog } from 'react-icons/tb'
3+
import { Menu } from '@mantine/core'
4+
import { memo } from 'react'
5+
6+
import { MODALS, useModalsStore } from '@entities/dashboard/modal-store'
7+
8+
import { IProps } from './interfaces'
9+
10+
const GetNodeLinkedHostsFeatureComponent = (props: IProps) => {
11+
const { nodeUuid } = props
12+
const { t } = useTranslation()
13+
14+
const { open: openModal, setInternalData } = useModalsStore()
15+
16+
return (
17+
<Menu.Item
18+
leftSection={<TbServerCog size="16px" />}
19+
onClick={() => {
20+
setInternalData({
21+
internalState: {
22+
nodeUuid
23+
},
24+
modalKey: MODALS.SHOW_NODE_LINKED_HOSTS_DRAWER
25+
})
26+
openModal(MODALS.SHOW_NODE_LINKED_HOSTS_DRAWER)
27+
}}
28+
>
29+
{t('get-node-linked-hosts.feature.linked-hosts')}
30+
</Menu.Item>
31+
)
32+
}
33+
34+
export const GetNodeLinkedHostsFeature = memo(GetNodeLinkedHostsFeatureComponent)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './get-node-linked-hosts.feature'
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './props.interface'
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export interface IProps {
2+
nodeUuid: string
3+
}

src/pages/dashboard/hosts/ui/components/hosts.page.component.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/* eslint-disable @stylistic/indent */
2+
13
import { useTranslation } from 'react-i18next'
24
import { motion } from 'motion/react'
35
import { Grid } from '@mantine/core'
@@ -21,7 +23,8 @@ export default function HostsPageComponent(props: IProps) {
2123
hostTags,
2224
isHostsLoading,
2325
isConfigProfilesLoading,
24-
isHostTagsLoading
26+
isHostTagsLoading,
27+
isNodesLoading
2528
} = props
2629
const [selectedHosts, setSelectedHosts] = useState<string[]>([])
2730

@@ -40,7 +43,10 @@ export default function HostsPageComponent(props: IProps) {
4043
<Grid.Col span={12}>
4144
<HostsPageHeaderWidget />
4245

43-
{isHostsLoading || isConfigProfilesLoading || isHostTagsLoading ? (
46+
{isHostsLoading ||
47+
isConfigProfilesLoading ||
48+
isHostTagsLoading ||
49+
isNodesLoading ? (
4450
<LoadingScreen height="60vh" />
4551
) : (
4652
<motion.div

src/pages/dashboard/hosts/ui/components/interfaces/props.interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ export interface IProps {
1111
isConfigProfilesLoading: boolean
1212
isHostsLoading: boolean
1313
isHostTagsLoading: boolean
14+
isNodesLoading: boolean
1415
}

0 commit comments

Comments
 (0)