gitscope
https://dev.kronoz.win/r/marzneshin.git
app/dashboard/src/stores/inbounds.store.ts · v0.1.3
Source
1 89f8f93 Mardin 2y ago import { create } from 'zustand';
2 89f8f93 Mardin 2y ago import { subscribeWithSelector } from 'zustand/middleware';
3 89f8f93 Mardin 2y ago import { useDashboard } from './dashboard.store';
4 89f8f93 Mardin 2y ago import { fetch } from 'service/http';
5 89f8f93 Mardin 2y ago import { Inbounds, InboundType } from 'types/inbounds';
6 89f8f93 Mardin 2y ago import { z } from 'zod';
7 6aab6f0 Mrdn 2y ago import { HostsFilterType, InboundsFilterType } from 'types';
8 6aab6f0 Mrdn 2y ago import { pageSizeManagers } from 'utils/userPreferenceStorage';
9 6aab6f0 Mrdn 2y ago import { queryClient } from 'service/react-query';
10 a61ba53 Mrdn 2y ago import { queryIds } from 'constants/query-ids';
11 89f8f93 Mardin 2y ago
12 89f8f93 Mardin 2y ago const isPortThenValue = (value: number) => (value <= 65535 && value !== 0) ? value : null;
13 89f8f93 Mardin 2y ago
14 89f8f93 Mardin 2y ago export const hostSchema = z.object({
15 89f8f93 Mardin 2y ago remark: z.string().min(1, 'Remark is required'),
16 89f8f93 Mardin 2y ago address: z.string().min(1, 'Address is required'),
17 89f8f93 Mardin 2y ago port: z
18 89f8f93 Mardin 2y ago .string()
19 89f8f93 Mardin 2y ago .or(z.number())
20 89f8f93 Mardin 2y ago .nullable()
21 89f8f93 Mardin 2y ago .transform((value) => {
22 89f8f93 Mardin 2y ago if (typeof value === 'number') return isPortThenValue(value);
23 89f8f93 Mardin 2y ago if (value !== null && !isNaN(parseInt(value))) return isPortThenValue(Number(parseInt(value)));
24 89f8f93 Mardin 2y ago return null;
25 89f8f93 Mardin 2y ago }),
26 89f8f93 Mardin 2y ago path: z.string(),
27 89f8f93 Mardin 2y ago sni: z.string(),
28 89f8f93 Mardin 2y ago host: z.string(),
29 89f8f93 Mardin 2y ago security: z.enum(['inbound_default', 'none', 'tls']),
30 89f8f93 Mardin 2y ago alpn: z.string().optional(),
31 89f8f93 Mardin 2y ago fingerprint: z.string().optional(),
32 89f8f93 Mardin 2y ago });
33 89f8f93 Mardin 2y ago
34 89f8f93 Mardin 2y ago export type HostSchema = z.infer<typeof hostSchema>;
35 89f8f93 Mardin 2y ago export type HostType = HostSchema & { id?: number };
36 89f8f93 Mardin 2y ago export type Hosts = HostType[];
37 89f8f93 Mardin 2y ago
38 89f8f93 Mardin 2y ago export const fetchInbounds = async () => {
39 89f8f93 Mardin 2y ago useDashboard.setState({ loading: true });
40 89f8f93 Mardin 2y ago return fetch('/inbounds')
41 a61ba53 Mrdn 2y ago .then((inbounds: Inbounds) => inbounds)
42 89f8f93 Mardin 2y ago .finally(() => {
43 89f8f93 Mardin 2y ago useDashboard.setState({ loading: false });
44 89f8f93 Mardin 2y ago });
45 89f8f93 Mardin 2y ago };
46 89f8f93 Mardin 2y ago
47 16e5ea1 Mrdn 2y ago export const fetchInboundHosts = async (id: number | undefined): Promise<Hosts> => {
48 89f8f93 Mardin 2y ago useDashboard.setState({ loading: true });
49 89f8f93 Mardin 2y ago return fetch(`/inbounds/${id}/hosts`)
50 16e5ea1 Mrdn 2y ago .then((hosts: Hosts) => {
51 16e5ea1 Mrdn 2y ago return hosts
52 16e5ea1 Mrdn 2y ago })
53 89f8f93 Mardin 2y ago .finally(() => {
54 89f8f93 Mardin 2y ago useDashboard.setState({ loading: false });
55 89f8f93 Mardin 2y ago });
56 89f8f93 Mardin 2y ago };
57 89f8f93 Mardin 2y ago
58 89f8f93 Mardin 2y ago type InboundsStateType = {
59 89f8f93 Mardin 2y ago // Loading
60 89f8f93 Mardin 2y ago loading: boolean;
61 89f8f93 Mardin 2y ago setLoading: (value: boolean) => void;
62 89f8f93 Mardin 2y ago // Inbounds
63 16e5ea1 Mrdn 2y ago selectedInbound: InboundType | undefined;
64 89f8f93 Mardin 2y ago selectInbound: (inbound: InboundType) => void;
65 a61ba53 Mrdn 2y ago refetchInbounds: () => void;
66 89f8f93 Mardin 2y ago // Hosts
67 6aab6f0 Mrdn 2y ago refetchHosts: () => void;
68 6aab6f0 Mrdn 2y ago hostsFilters: HostsFilterType;
69 6aab6f0 Mrdn 2y ago inboundsFilters: InboundsFilterType;
70 6aab6f0 Mrdn 2y ago onHostsFilterChange: (filters: Partial<HostsFilterType>) => void;
71 6aab6f0 Mrdn 2y ago onInboundsFilterChange: (filters: Partial<InboundsFilterType>) => void;
72 89f8f93 Mardin 2y ago selectedHost: HostType | null;
73 89f8f93 Mardin 2y ago selectHost: (host: HostType) => void;
74 89f8f93 Mardin 2y ago isEditingHost: boolean;
75 89f8f93 Mardin 2y ago onEditingHost: (isEditingHost: boolean, host: HostType | null) => void;
76 89f8f93 Mardin 2y ago editHost: (inboundId: number | undefined, host: HostType) => Promise<boolean | void>;
77 89f8f93 Mardin 2y ago isCreatingHost: boolean;
78 89f8f93 Mardin 2y ago onCreatingHost: (isCreatingHost: boolean) => void;
79 89f8f93 Mardin 2y ago createHost: (inboundId: number | undefined, host: HostSchema) => Promise<boolean | void>;
80 89f8f93 Mardin 2y ago isDeletingHost: boolean;
81 89f8f93 Mardin 2y ago onDeletingHost: (isDeletingHost: boolean, host: HostType) => void;
82 89f8f93 Mardin 2y ago deleteHost: (hostId: number) => void;
83 89f8f93 Mardin 2y ago };
84 89f8f93 Mardin 2y ago
85 89f8f93 Mardin 2y ago export const useInbounds = create(
86 6aab6f0 Mrdn 2y ago subscribeWithSelector<InboundsStateType>((set, get) => ({
87 89f8f93 Mardin 2y ago selectedHost: null,
88 16e5ea1 Mrdn 2y ago selectedInbound: undefined,
89 89f8f93 Mardin 2y ago loading: false,
90 89f8f93 Mardin 2y ago isDeletingHost: false,
91 89f8f93 Mardin 2y ago isCreatingHost: false,
92 89f8f93 Mardin 2y ago isEditingHost: false,
93 6aab6f0 Mrdn 2y ago hostsFilters: {
94 6aab6f0 Mrdn 2y ago name: '',
95 6aab6f0 Mrdn 2y ago limit: pageSizeManagers.hosts.getPageSize(),
96 6aab6f0 Mrdn 2y ago sort: '-created_at',
97 6aab6f0 Mrdn 2y ago },
98 6aab6f0 Mrdn 2y ago inboundsFilters: {
99 6aab6f0 Mrdn 2y ago name: '',
100 6aab6f0 Mrdn 2y ago limit: pageSizeManagers.inbounds.getPageSize(),
101 6aab6f0 Mrdn 2y ago sort: '-created_at',
102 6aab6f0 Mrdn 2y ago },
103 6aab6f0 Mrdn 2y ago onHostsFilterChange: (filters) => {
104 6aab6f0 Mrdn 2y ago set({
105 6aab6f0 Mrdn 2y ago hostsFilters: {
106 6aab6f0 Mrdn 2y ago ...get().hostsFilters,
107 6aab6f0 Mrdn 2y ago ...filters,
108 6aab6f0 Mrdn 2y ago },
109 6aab6f0 Mrdn 2y ago });
110 6aab6f0 Mrdn 2y ago },
111 6aab6f0 Mrdn 2y ago onInboundsFilterChange: (filters) => {
112 6aab6f0 Mrdn 2y ago set({
113 6aab6f0 Mrdn 2y ago hostsFilters: {
114 6aab6f0 Mrdn 2y ago ...get().inboundsFilters,
115 6aab6f0 Mrdn 2y ago ...filters,
116 6aab6f0 Mrdn 2y ago },
117 6aab6f0 Mrdn 2y ago });
118 6aab6f0 Mrdn 2y ago },
119 89f8f93 Mardin 2y ago setLoading: (value) => {
120 89f8f93 Mardin 2y ago set({ loading: value })
121 89f8f93 Mardin 2y ago },
122 89f8f93 Mardin 2y ago refetchInbounds: () => {
123 16e5ea1 Mrdn 2y ago queryClient.invalidateQueries({ queryKey: [queryIds.inbounds] });
124 89f8f93 Mardin 2y ago },
125 16e5ea1 Mrdn 2y ago refetchHosts: async () => {
126 16e5ea1 Mrdn 2y ago queryClient.invalidateQueries({ queryKey: [queryIds.hosts] });
127 6aab6f0 Mrdn 2y ago },
128 89f8f93 Mardin 2y ago selectInbound: (host): void => {
129 89f8f93 Mardin 2y ago set({ selectedInbound: host })
130 89f8f93 Mardin 2y ago },
131 89f8f93 Mardin 2y ago selectHost: (host: HostType): void => {
132 89f8f93 Mardin 2y ago set({ selectedHost: host })
133 89f8f93 Mardin 2y ago },
134 89f8f93 Mardin 2y ago onEditingHost: (isEditingHost: boolean, host: HostType | null) => {
135 89f8f93 Mardin 2y ago set({ isEditingHost, selectedHost: host });
136 89f8f93 Mardin 2y ago },
137 89f8f93 Mardin 2y ago editHost: async (hostId: number | undefined, body: HostSchema): Promise<boolean | void> => {
138 89f8f93 Mardin 2y ago if (hostId !== undefined) {
139 89f8f93 Mardin 2y ago useDashboard.setState({ loading: true });
140 89f8f93 Mardin 2y ago return fetch(`/inbounds/hosts/${hostId}`, { method: 'PUT', body })
141 89f8f93 Mardin 2y ago .then(() => true)
142 89f8f93 Mardin 2y ago .catch(() => false)
143 89f8f93 Mardin 2y ago .finally(() => {
144 89f8f93 Mardin 2y ago useDashboard.setState({ loading: false });
145 89f8f93 Mardin 2y ago });
146 89f8f93 Mardin 2y ago }
147 89f8f93 Mardin 2y ago },
148 89f8f93 Mardin 2y ago onCreatingHost: (isCreatingHost: boolean) => {
149 89f8f93 Mardin 2y ago set({ isCreatingHost });
150 89f8f93 Mardin 2y ago },
151 89f8f93 Mardin 2y ago createHost: async (inboundId: number | undefined, body: HostSchema): Promise<boolean | void> => {
152 89f8f93 Mardin 2y ago if (inboundId !== undefined) {
153 89f8f93 Mardin 2y ago useDashboard.setState({ loading: true });
154 16e5ea1 Mrdn 2y ago return fetch(`/inbounds/${inboundId}/hosts`, { method: 'POST', body })
155 89f8f93 Mardin 2y ago .then(() => true)
156 89f8f93 Mardin 2y ago .catch(() => false)
157 89f8f93 Mardin 2y ago .finally(() => {
158 89f8f93 Mardin 2y ago useDashboard.setState({ loading: false });
159 89f8f93 Mardin 2y ago });
160 89f8f93 Mardin 2y ago }
161 89f8f93 Mardin 2y ago },
162 89f8f93 Mardin 2y ago onDeletingHost: (isDeletingHost: boolean, host: HostType | null) => {
163 89f8f93 Mardin 2y ago set({ isDeletingHost, selectedHost: host });
164 89f8f93 Mardin 2y ago },
165 89f8f93 Mardin 2y ago deleteHost: async (hostId: number): Promise<boolean> => {
166 89f8f93 Mardin 2y ago useDashboard.setState({ loading: true });
167 89f8f93 Mardin 2y ago return fetch(`/inbounds/hosts/${hostId}`, { method: 'DELETE' })
168 89f8f93 Mardin 2y ago .then(() => true)
169 89f8f93 Mardin 2y ago .catch(() => false)
170 89f8f93 Mardin 2y ago .finally(() => {
171 89f8f93 Mardin 2y ago useDashboard.setState({ loading: false });
172 89f8f93 Mardin 2y ago });
173 89f8f93 Mardin 2y ago },
174 89f8f93 Mardin 2y ago }))
175 89f8f93 Mardin 2y ago );