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