gitscope
https://dev.kronoz.win/r/marzneshin.git
app/dashboard/src/stores/inbounds.store.ts · v0.1.4
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 8d3056a Mrdn 2y ago if (id !== undefined) {
49 8d3056a Mrdn 2y ago useDashboard.setState({ loading: true });
50 8d3056a Mrdn 2y ago return fetch(`/inbounds/${id}/hosts`)
51 8d3056a Mrdn 2y ago .then((hosts: Hosts) => {
52 8d3056a Mrdn 2y ago return hosts
53 8d3056a Mrdn 2y ago })
54 8d3056a Mrdn 2y ago .finally(() => {
55 8d3056a Mrdn 2y ago useDashboard.setState({ loading: false });
56 8d3056a Mrdn 2y ago });
57 8d3056a Mrdn 2y ago } else { return [] }
58 89f8f93 Mardin 2y ago };
59 89f8f93 Mardin 2y ago
60 89f8f93 Mardin 2y ago type InboundsStateType = {
61 89f8f93 Mardin 2y ago // Loading
62 89f8f93 Mardin 2y ago loading: boolean;
63 89f8f93 Mardin 2y ago setLoading: (value: boolean) => void;
64 89f8f93 Mardin 2y ago // Inbounds
65 16e5ea1 Mrdn 2y ago selectedInbound: InboundType | undefined;
66 89f8f93 Mardin 2y ago selectInbound: (inbound: InboundType) => void;
67 a61ba53 Mrdn 2y ago refetchInbounds: () => void;
68 89f8f93 Mardin 2y ago // Hosts
69 6aab6f0 Mrdn 2y ago refetchHosts: () => void;
70 6aab6f0 Mrdn 2y ago hostsFilters: HostsFilterType;
71 6aab6f0 Mrdn 2y ago inboundsFilters: InboundsFilterType;
72 6aab6f0 Mrdn 2y ago onHostsFilterChange: (filters: Partial<HostsFilterType>) => void;
73 6aab6f0 Mrdn 2y ago onInboundsFilterChange: (filters: Partial<InboundsFilterType>) => void;
74 89f8f93 Mardin 2y ago selectedHost: HostType | null;
75 89f8f93 Mardin 2y ago selectHost: (host: HostType) => void;
76 89f8f93 Mardin 2y ago isEditingHost: boolean;
77 89f8f93 Mardin 2y ago onEditingHost: (isEditingHost: boolean, host: HostType | null) => void;
78 89f8f93 Mardin 2y ago editHost: (inboundId: number | undefined, host: HostType) => Promise<boolean | void>;
79 89f8f93 Mardin 2y ago isCreatingHost: boolean;
80 89f8f93 Mardin 2y ago onCreatingHost: (isCreatingHost: boolean) => void;
81 89f8f93 Mardin 2y ago createHost: (inboundId: number | undefined, host: HostSchema) => Promise<boolean | void>;
82 89f8f93 Mardin 2y ago isDeletingHost: boolean;
83 89f8f93 Mardin 2y ago onDeletingHost: (isDeletingHost: boolean, host: HostType) => void;
84 89f8f93 Mardin 2y ago deleteHost: (hostId: number) => void;
85 89f8f93 Mardin 2y ago };
86 89f8f93 Mardin 2y ago
87 89f8f93 Mardin 2y ago export const useInbounds = create(
88 6aab6f0 Mrdn 2y ago subscribeWithSelector<InboundsStateType>((set, get) => ({
89 89f8f93 Mardin 2y ago selectedHost: null,
90 16e5ea1 Mrdn 2y ago selectedInbound: undefined,
91 89f8f93 Mardin 2y ago loading: false,
92 89f8f93 Mardin 2y ago isDeletingHost: false,
93 89f8f93 Mardin 2y ago isCreatingHost: false,
94 89f8f93 Mardin 2y ago isEditingHost: false,
95 6aab6f0 Mrdn 2y ago hostsFilters: {
96 6aab6f0 Mrdn 2y ago name: '',
97 6aab6f0 Mrdn 2y ago limit: pageSizeManagers.hosts.getPageSize(),
98 6aab6f0 Mrdn 2y ago sort: '-created_at',
99 6aab6f0 Mrdn 2y ago },
100 6aab6f0 Mrdn 2y ago inboundsFilters: {
101 6aab6f0 Mrdn 2y ago name: '',
102 6aab6f0 Mrdn 2y ago limit: pageSizeManagers.inbounds.getPageSize(),
103 6aab6f0 Mrdn 2y ago sort: '-created_at',
104 6aab6f0 Mrdn 2y ago },
105 6aab6f0 Mrdn 2y ago onHostsFilterChange: (filters) => {
106 6aab6f0 Mrdn 2y ago set({
107 6aab6f0 Mrdn 2y ago hostsFilters: {
108 6aab6f0 Mrdn 2y ago ...get().hostsFilters,
109 6aab6f0 Mrdn 2y ago ...filters,
110 6aab6f0 Mrdn 2y ago },
111 6aab6f0 Mrdn 2y ago });
112 6aab6f0 Mrdn 2y ago },
113 6aab6f0 Mrdn 2y ago onInboundsFilterChange: (filters) => {
114 6aab6f0 Mrdn 2y ago set({
115 6aab6f0 Mrdn 2y ago hostsFilters: {
116 6aab6f0 Mrdn 2y ago ...get().inboundsFilters,
117 6aab6f0 Mrdn 2y ago ...filters,
118 6aab6f0 Mrdn 2y ago },
119 6aab6f0 Mrdn 2y ago });
120 6aab6f0 Mrdn 2y ago },
121 89f8f93 Mardin 2y ago setLoading: (value) => {
122 89f8f93 Mardin 2y ago set({ loading: value })
123 89f8f93 Mardin 2y ago },
124 89f8f93 Mardin 2y ago refetchInbounds: () => {
125 16e5ea1 Mrdn 2y ago queryClient.invalidateQueries({ queryKey: [queryIds.inbounds] });
126 89f8f93 Mardin 2y ago },
127 16e5ea1 Mrdn 2y ago refetchHosts: async () => {
128 16e5ea1 Mrdn 2y ago queryClient.invalidateQueries({ queryKey: [queryIds.hosts] });
129 6aab6f0 Mrdn 2y ago },
130 89f8f93 Mardin 2y ago selectInbound: (host): void => {
131 89f8f93 Mardin 2y ago set({ selectedInbound: host })
132 89f8f93 Mardin 2y ago },
133 89f8f93 Mardin 2y ago selectHost: (host: HostType): void => {
134 89f8f93 Mardin 2y ago set({ selectedHost: host })
135 89f8f93 Mardin 2y ago },
136 89f8f93 Mardin 2y ago onEditingHost: (isEditingHost: boolean, host: HostType | null) => {
137 89f8f93 Mardin 2y ago set({ isEditingHost, selectedHost: host });
138 89f8f93 Mardin 2y ago },
139 89f8f93 Mardin 2y ago editHost: async (hostId: number | undefined, body: HostSchema): Promise<boolean | void> => {
140 89f8f93 Mardin 2y ago if (hostId !== undefined) {
141 89f8f93 Mardin 2y ago useDashboard.setState({ loading: true });
142 89f8f93 Mardin 2y ago return fetch(`/inbounds/hosts/${hostId}`, { method: 'PUT', body })
143 89f8f93 Mardin 2y ago .then(() => true)
144 89f8f93 Mardin 2y ago .catch(() => false)
145 89f8f93 Mardin 2y ago .finally(() => {
146 89f8f93 Mardin 2y ago useDashboard.setState({ loading: false });
147 89f8f93 Mardin 2y ago });
148 89f8f93 Mardin 2y ago }
149 89f8f93 Mardin 2y ago },
150 89f8f93 Mardin 2y ago onCreatingHost: (isCreatingHost: boolean) => {
151 89f8f93 Mardin 2y ago set({ isCreatingHost });
152 89f8f93 Mardin 2y ago },
153 89f8f93 Mardin 2y ago createHost: async (inboundId: number | undefined, body: HostSchema): Promise<boolean | void> => {
154 89f8f93 Mardin 2y ago if (inboundId !== undefined) {
155 89f8f93 Mardin 2y ago useDashboard.setState({ loading: true });
156 16e5ea1 Mrdn 2y ago return fetch(`/inbounds/${inboundId}/hosts`, { method: 'POST', body })
157 89f8f93 Mardin 2y ago .then(() => true)
158 89f8f93 Mardin 2y ago .catch(() => false)
159 89f8f93 Mardin 2y ago .finally(() => {
160 89f8f93 Mardin 2y ago useDashboard.setState({ loading: false });
161 89f8f93 Mardin 2y ago });
162 89f8f93 Mardin 2y ago }
163 89f8f93 Mardin 2y ago },
164 89f8f93 Mardin 2y ago onDeletingHost: (isDeletingHost: boolean, host: HostType | null) => {
165 89f8f93 Mardin 2y ago set({ isDeletingHost, selectedHost: host });
166 89f8f93 Mardin 2y ago },
167 89f8f93 Mardin 2y ago deleteHost: async (hostId: number): Promise<boolean> => {
168 89f8f93 Mardin 2y ago useDashboard.setState({ loading: true });
169 89f8f93 Mardin 2y ago return fetch(`/inbounds/hosts/${hostId}`, { method: 'DELETE' })
170 89f8f93 Mardin 2y ago .then(() => true)
171 89f8f93 Mardin 2y ago .catch(() => false)
172 89f8f93 Mardin 2y ago .finally(() => {
173 89f8f93 Mardin 2y ago useDashboard.setState({ loading: false });
174 89f8f93 Mardin 2y ago });
175 89f8f93 Mardin 2y ago },
176 89f8f93 Mardin 2y ago }))
177 89f8f93 Mardin 2y ago );