Skip to content

Commit 278c8b3

Browse files
committed
refactor: update help drawer and enhance documentation loading
1 parent 36d75c7 commit 278c8b3

File tree

14 files changed

+1816
-83
lines changed

14 files changed

+1816
-83
lines changed

package-lock.json

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

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,11 @@
102102
"react-icons": "^5.5.0",
103103
"react-imask": "^7.6.1",
104104
"react-layout-masonry": "^2.0.0",
105+
"react-markdown": "^10.1.0",
105106
"react-router-dom": "6.27.0",
106107
"recharts": "^2.15.3",
108+
"rehype-raw": "^7.0.0",
109+
"remark-gfm": "^4.0.1",
107110
"semver": "^7.7.3",
108111
"tiny-invariant": "^1.3.3",
109112
"ufo": "^1.6.1",
@@ -191,4 +194,4 @@
191194
"inquirer": "9.3.5"
192195
}
193196
}
194-
}
197+
}

public/locales/en/remnawave.json

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,15 +1764,6 @@
17641764
"reset-usage": "Reset usage"
17651765
}
17661766
},
1767-
"help-drawer": {
1768-
"shared": {
1769-
"templates-xray-json": "<h2>Xray JSON Subscription Format</h2> <p> The Xray JSON format provides native JSON-based subscription support for compatible clients. Simply append <code>/json</code> to your subscription URL to enable this format. </p> <h3>Supported Applications</h3> <ul> <li><strong>v2rayNG</strong> — version 1.8.29 or higher</li> <li><strong>V2rayN</strong> — version 6.40 or higher</li> <li><strong>Streisand</strong> — all versions</li> <li><strong>Happ</strong> — all versions</li> <li><strong>V2Box</strong> — all versions</li> <li><strong>ktor-client</strong> — all versions</li> </ul> <h3>Usage Instructions</h3> <p><strong>Step 1:</strong> Modify your subscription URL</p> <p style=\"margin-left: 20px;\"> Append <code>/json</code> to the end of your subscription link:<br /> <code style=\"display: inline-block; margin-top: 8px; padding: 8px 12px; background: rgba(0,0,0,0.05); border-radius: 4px;\"> https://&lt;server&gt;/api/sub/xxxx/json </code> </p> <p><strong>Step 2:</strong> Verify compatibility</p> <p style=\"margin-left: 20px;\"> Ensure your client application meets the minimum version requirements listed above. </p> <p><strong>Alternatively:</strong> Enable JSON At the base path</p> <p style=\"margin-left: 20px;\"> Enable the \"Serve JSON at base subscription\" option in the subscription settings. This will serve the JSON subscription at the base subscription path (without having to append /json). </p> <h3>Fallback Behavior</h3> <p> For clients that don't support the JSON format (such as Base64 or Mihomo-based clients), the subscription will automatically fall back to the standard format compatible with your client. </p>",
1770-
"unknown-screen-provided": "Unknown screen provided.",
1771-
"loading-help-drawer": "Loading help drawer...",
1772-
"internal-squads-grid": "<h2>Internal Squads</h2> <p>The main purpose of internal squads is <strong>access control</strong> for users.</p> <p>Internal squads are directly linked to <strong>profiles</strong> and their <strong>inbounds</strong>. You can assign them as many active inbounds as needed (which are located inside profiles). And since profiles and their inbounds are directly linked to nodes – using an internal squad, we can finely control which users or groups of users can have access to nodes.</p> <hr /> <p>In each squad's card (in the general list), you can see the number of active inbounds, as well as the number of members in this squad (users who belong to it).</p> <p>By clicking on the additional actions button (in the squad card), you can also quickly add or remove all users. If you need to assign a squad to <em>specific</em> users – you can do this in the <strong>\"Users\"</strong> section.</p> <p>Managing users and nodes that can be accessible to them can sometimes be very confusing – use the <strong>\"Available Nodes\"</strong> button to quickly see which nodes are available to this squad. Let me remind you that when creating or modifying a <strong>node</strong>, we also select which <strong>profile</strong> will be used and which <strong>inbounds</strong> from it will be active on the node. And since we also select <strong>inbounds</strong> inside the squad, we can use these relationships to determine specific nodes that this squad (and consequently its members) will have access to.</p> <hr /> <p>For example, we have two user groups: <strong>free</strong> and <strong>paid</strong>. And we want <strong>free</strong> users to have access to <em>server group #1</em>, and paid users to have access to both <em>server group #1</em> and additionally to <em>server group #2</em>.</p> <p>For this purpose, we create two squads: <strong>Free</strong> and <strong>Premium</strong>, and inside each of them we select the corresponding inbounds.</p> <p>And let's say we're creating a user – in this case, if we have a free user – we simply activate the <strong>Free</strong> internal squad for them. And when we have a paid user – we activate both squads – <strong>Free</strong> and <strong>Premium</strong> (if the user needs access to all nodes/inbounds). But we can also activate only one squad for a paid user – <strong>Premium</strong>, in which case the user will not have access to the nodes/inbounds from the <strong>Free</strong> group.</p>",
1773-
"external-squads-grid": "<h2>External Squads</h2> <p>Using external squads, you can override certain settings or templates that users use when requesting a subscription. <em>A user cannot have more than one active external squad.</em></p> <p>For example, for different user groups, you can set different routing (for Happ, v2rayTUN), and different routing can also be within templates.</p> <p>Using the additional menu, you can quickly assign an external squad to all users (or conversely remove all users from an external squad).</p> <p>If a user has no external squad selected – global settings from the \"<strong>Subscription</strong>\" section are used, as well as the \"<strong>Default</strong>\" client config template.</p> <hr /> <p>Let's smoothly move on to reviewing the settings available in the external squad card.</p> <h3>Template Override</h3> <p>When a user requests a subscription – depending on the client application from which the request came, the user may receive different templates. For example, if the application runs on the Mihomo core – Remnawave will detect this and provide the <strong>Default</strong> template of the <strong>Mihomo</strong> type. (You can manage templates in the corresponding section).</p> <p>Inside Remnawave, you can create an infinite number of templates for each type (Mihomo, Stash, Xray Json, Singbox, Clash), but by default, the <strong>Default</strong> template will always be provided.</p> <p><strong>To override this behavior is exactly what this setting inside the external squad exists for.</strong></p> <p>Let's say, for a specific external squad we want to use a <em>Custom Template</em> that belongs to the <strong>Mihomo</strong> type, in this case we select this template in the corresponding section and save the changes. If a request comes from a user who belongs to this external squad – instead of the <em>Default</em> template, they will receive the <em>Custom Template</em>.</p> <p>If you leave the override field empty – the user who is in this squad will receive the <em>Default</em> template.</p> <p><em>Please note, template override in the \"Response Rules\" section has a higher priority than override in this section.</em></p> <h3>Settings (Subscription)</h3> <p>In this section, general settings that are located in the \"Subscription\" → \"Settings\" section are overridden. Accordingly, by overriding settings within the squad, you can override many parameters at once for an entire group of users.</p> <p>Keep in mind, if any of the parameters is explicitly overridden (including an empty value) – it will be overridden. Only deletion of the override (trash icon) will cancel the override.</p> <p>For example, in general settings my profile header is set as \"Remnawave\", but for 10 users I want to override it, for example to \"Remnawave v.2.x\", in this case I override this parameter in this section, and then assign this external squad to the needed 10 users.</p> <h3>Hosts</h3> <p>Based on the logic from the previous point – in this section you can completely override some parameters that you might have noticed in the card of each <strong>host</strong> you created.</p> <p><strong>Values overridden here will be applied to all hosts that the user receives in the subscription.</strong></p> <p>For example, by overriding <code>vlessRouteId</code> we can assign a specific value and thus \"<em>route</em>\" an entire group of users (those who will be in this squad). Naturally, the other half of such routing settings is located in the server configuration – the Config Profile.</p>"
1774-
}
1775-
},
17761767
"help-action-icon": {
17771768
"shared": {
17781769
"help-article": "Help Article"
@@ -1782,5 +1773,11 @@
17821773
"widget": {
17831774
"available-nodes": "Available Nodes"
17841775
}
1776+
},
1777+
"help-drawer": {
1778+
"shared": {
1779+
"failed-to-load-documentation": "Failed to load documentation",
1780+
"loading-documentation": "Loading documentation..."
1781+
}
17851782
}
1786-
}
1783+
}

src/features/dashboard/hosts/hosts-filters/hosts-filters.feature.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export const HostsFiltersFeature = (props: IProps) => {
8989
variant="filled"
9090
>
9191
<Accordion.Item value="filters">
92-
<Accordion.Control>
92+
<Accordion.Control component="a">
9393
<Group align="center" gap="md" wrap="nowrap">
9494
<ActionIcon color="gray" size="input-sm" variant="light">
9595
<HiFilter size={20} />

src/features/ui/dashboard/config-profiles/header-action-buttons/config-profiles-header-action-buttons.feature.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { useTranslation } from 'react-i18next'
1717
import { useField } from '@mantine/form'
1818

1919
import { QueryKeys, useCreateConfigProfile, useGetConfigProfiles } from '@shared/api/hooks'
20+
import { HelpActionIconShared } from '@shared/ui/help-drawer'
2021
import { ROUTES } from '@shared/constants'
2122
import { queryClient } from '@shared/api'
2223

@@ -98,6 +99,8 @@ export const ConfigProfilesHeaderActionButtonsFeature = () => {
9899

99100
return (
100101
<Group grow preventGrowOverflow={false} wrap="wrap">
102+
<HelpActionIconShared hidden={false} screen="PAGE_CONFIG_PROFILES" />
103+
101104
<ActionIconGroup>
102105
<Tooltip label={t('common.update')} withArrow>
103106
<ActionIcon

src/features/ui/dashboard/external-squads/header-action-buttons/header-action-buttons.feature.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export const ExternalSquadsHeaderActionButtonsFeature = () => {
5656

5757
return (
5858
<Group grow preventGrowOverflow={false} wrap="wrap">
59-
<HelpActionIconShared hidden={false} screen="EXTERNAL_SQUADS_GRID" />
59+
<HelpActionIconShared hidden={false} screen="PAGE_EXTERNAL_SQUADS" />
6060

6161
<ActionIconGroup>
6262
<Tooltip

src/features/ui/dashboard/hosts/header-action-buttons/header-action-buttons.feature.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ActionIcon, ActionIconGroup, Group, Tooltip } from '@mantine/core'
22
import { TbPlus, TbRefresh } from 'react-icons/tb'
33
import { useTranslation } from 'react-i18next'
44

5+
import { HelpActionIconShared } from '@shared/ui/help-drawer/help-action-icon.shared'
56
import { MODALS, useModalsStoreOpenWithData } from '@entities/dashboard/modal-store'
67
import { QueryKeys, useGetHosts } from '@shared/api/hooks'
78
import { queryClient } from '@shared/api'
@@ -25,6 +26,8 @@ export const HeaderActionButtonsFeature = () => {
2526

2627
return (
2728
<Group grow preventGrowOverflow={false} wrap="wrap">
29+
<HelpActionIconShared hidden={false} screen="PAGE_HOSTS" />
30+
2831
<ActionIconGroup>
2932
<Tooltip label={t('common.update')} withArrow>
3033
<ActionIcon

src/features/ui/dashboard/internal-squads/header-action-buttons/header-action-buttons.feature.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export const InternalSquadsHeaderActionButtonsFeature = () => {
6262

6363
return (
6464
<Group grow preventGrowOverflow={false} wrap="wrap">
65-
<HelpActionIconShared hidden={false} screen="INTERNAL_SQUADS_GRID" />
65+
<HelpActionIconShared hidden={false} screen="PAGE_INTERNAL_SQUADS" />
6666

6767
<ActionIconGroup>
6868
<Tooltip label={t('common.update')} withArrow>

src/pages/dashboard/config-profiles/components/config-profile-by-uuid.page.component.tsx

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import { GetConfigProfileByUuidCommand, GetSnippetsCommand } from '@remnawave/backend-contract'
2-
import { Box, Drawer, Flex, Transition } from '@mantine/core'
2+
import { ActionIcon, Box, Drawer, Flex, Group, Transition } from '@mantine/core'
3+
import { TbArrowBack, TbFile } from 'react-icons/tb'
34
import { useMediaQuery } from '@mantine/hooks'
45
import { useTranslation } from 'react-i18next'
5-
import { TbFile } from 'react-icons/tb'
6+
import { useNavigate } from 'react-router-dom'
67

78
import { ConfigEditorWidget } from '@widgets/dashboard/config-profiles/config-editor/config-editor.widget'
89
import { SnippetsDrawerWidget } from '@widgets/dashboard/config-profiles/snippets-drawer'
910
import { MODALS, useModalClose, useModalIsOpen } from '@entities/dashboard/modal-store'
1011
import { PageHeaderShared } from '@shared/ui/page-header/page-header.shared'
12+
import { HelpActionIconShared } from '@shared/ui/help-drawer'
13+
import { ROUTES } from '@shared/constants'
1114
import { Page } from '@shared/ui/page'
1215

1316
interface Props {
@@ -20,6 +23,7 @@ export const ConfigProfileByUuidPageComponent = (props: Props) => {
2023

2124
const { t } = useTranslation()
2225
const isMobile = useMediaQuery('(max-width: 1200px)')
26+
const navigate = useNavigate()
2327

2428
const isOpen = useModalIsOpen(MODALS.CONFIG_PROFILE_SHOW_SNIPPETS_DRAWER)
2529
const close = useModalClose(MODALS.CONFIG_PROFILE_SHOW_SNIPPETS_DRAWER)
@@ -28,6 +32,22 @@ export const ConfigProfileByUuidPageComponent = (props: Props) => {
2832
<>
2933
<Page title={t('constants.config-profiles')}>
3034
<PageHeaderShared
35+
actions={
36+
<Group>
37+
<HelpActionIconShared hidden={false} screen="PAGE_CONFIG_PROFILES" />
38+
39+
<ActionIcon
40+
color="gray"
41+
onClick={() =>
42+
navigate(ROUTES.DASHBOARD.MANAGEMENT.CONFIG_PROFILES)
43+
}
44+
size="input-md"
45+
variant="light"
46+
>
47+
<TbArrowBack size={24} />
48+
</ActionIcon>
49+
</Group>
50+
}
3151
description={configProfile.uuid}
3252
icon={<TbFile size={24} />}
3353
title={configProfile.name}

src/pages/dashboard/templates/ui/components/template-editor-page.component..tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export const TemplateEditorPageComponent = (props: Props) => {
3232
<Group>
3333
<HelpActionIconShared
3434
hidden={!isHelpDrawerVisible}
35-
screen="TEMPLATES_JSON"
35+
screen="EDITOR_TEMPLATES_XRAY_JSON"
3636
/>
3737

3838
<ActionIcon

0 commit comments

Comments
 (0)