chore: rework useSubmit (#2649)

rework useSubmit
This commit is contained in:
Bernd Storath
2026-06-03 10:08:07 +02:00
committed by GitHub
parent e03d743307
commit bc95a2851f
16 changed files with 124 additions and 127 deletions
@@ -14,10 +14,11 @@ const props = defineProps<{ client: LocalClient }>();
const clientsStore = useClientsStore();
const _showOneTimeLink = useSubmit(
`/api/client/${props.client.id}/generateOneTimeLink`,
{
method: 'post',
},
(data) =>
$fetch(`/api/client/${props.client.id}/generateOneTimeLink`, {
method: 'post',
body: data,
}),
{
revert: async () => {
await clientsStore.refresh();
+10 -8
View File
@@ -18,10 +18,11 @@ const enabled = ref(props.client.enabled);
const clientsStore = useClientsStore();
const _disableClient = useSubmit(
`/api/client/${props.client.id}/disable`,
{
method: 'post',
},
(data) =>
$fetch(`/api/client/${props.client.id}/disable`, {
method: 'post',
body: data,
}),
{
revert: async () => {
await clientsStore.refresh();
@@ -31,10 +32,11 @@ const _disableClient = useSubmit(
);
const _enableClient = useSubmit(
`/api/client/${props.client.id}/enable`,
{
method: 'post',
},
(data) =>
$fetch(`/api/client/${props.client.id}/enable`, {
method: 'post',
body: data,
}),
{
revert: async () => {
await clientsStore.refresh();
+5 -4
View File
@@ -43,10 +43,11 @@ function createClient() {
}
const _createClient = useSubmit(
'/api/client',
{
method: 'post',
},
(data) =>
$fetch('/api/client', {
method: 'post',
body: data,
}),
{
revert: () => clientsStore.refresh(),
successMsg: t('client.created'),
+5 -4
View File
@@ -70,10 +70,11 @@ const authStore = useAuthStore();
const toggleState = ref(false);
const _submit = useSubmit(
'/api/session',
{
method: 'delete',
},
(data) =>
$fetch('/api/session', {
method: 'delete',
body: data,
}),
{
revert: async () => {
await navigateTo('/login');
+11 -36
View File
@@ -1,49 +1,24 @@
import type {
NitroFetchRequest,
NitroFetchOptions,
TypedInternalResponse,
ExtractedRouteMethod,
} from 'nitropack/types';
import { FetchError } from 'ofetch';
type RevertFn<
R extends NitroFetchRequest,
T = unknown,
O extends NitroFetchOptions<R> = NitroFetchOptions<R>,
> = (
success: boolean,
data:
| TypedInternalResponse<
R,
T,
NitroFetchOptions<R> extends O ? 'get' : ExtractedRouteMethod<R, O>
>
| undefined
) => Promise<void>;
type RevertFn<T> = (success: boolean, data: T | undefined) => Promise<void>;
type SubmitOpts<
R extends NitroFetchRequest,
T = unknown,
O extends NitroFetchOptions<R> = NitroFetchOptions<R>,
> = {
revert: RevertFn<R, T, O>;
type SubmitOpts<T> = {
revert: RevertFn<T>;
successMsg?: string;
noSuccessToast?: boolean;
};
export function useSubmit<
R extends NitroFetchRequest,
O extends NitroFetchOptions<R> & { body?: never },
T = unknown,
>(url: R, options: O, opts: SubmitOpts<R, T, O>) {
type Body = Record<string, unknown> | null | undefined;
export function useSubmit<T>(
fetcher: (data: Body) => Promise<T>,
opts: SubmitOpts<T>
) {
const toast = useToast();
return async (data: unknown) => {
return async (data: Body) => {
try {
const res = await $fetch(url, {
...options,
body: data,
});
const res = await fetcher(data);
if (!opts.noSuccessToast) {
toast.showToast({
+5 -4
View File
@@ -121,10 +121,11 @@ const { data: _data, refresh } = await useFetch(`/api/admin/userconfig`, {
const data = toRef(_data.value);
const _submit = useSubmit(
`/api/admin/userconfig`,
{
method: 'post',
},
(data) =>
$fetch(`/api/admin/userconfig`, {
method: 'post',
body: data,
}),
{ revert }
);
+5 -4
View File
@@ -46,10 +46,11 @@ const { data: _data, refresh } = await useFetch(`/api/admin/general`, {
const data = toRef(_data.value);
const _submit = useSubmit(
`/api/admin/general`,
{
method: 'post',
},
(data) =>
$fetch(`/api/admin/general`, {
method: 'post',
body: data,
}),
{ revert }
);
+5 -4
View File
@@ -40,10 +40,11 @@ const { data: _data, refresh } = await useFetch(`/api/admin/hooks`, {
const data = toRef(_data.value);
const _submit = useSubmit(
`/api/admin/hooks`,
{
method: 'post',
},
(data) =>
$fetch(`/api/admin/hooks`, {
method: 'post',
body: data,
}),
{ revert }
);
+15 -12
View File
@@ -176,10 +176,11 @@ const { data: _data, refresh } = await useFetch(`/api/admin/interface`, {
const data = toRef(_data.value);
const _submit = useSubmit(
`/api/admin/interface`,
{
method: 'post',
},
(data) =>
$fetch(`/api/admin/interface`, {
method: 'post',
body: data,
}),
{
revert: async (success) => {
await revert();
@@ -201,10 +202,11 @@ async function revert() {
}
const _changeCidr = useSubmit(
`/api/admin/interface/cidr`,
{
method: 'post',
},
(data) =>
$fetch(`/api/admin/interface/cidr`, {
method: 'post',
body: data,
}),
{
revert,
successMsg: t('admin.interface.cidrSuccess'),
@@ -216,10 +218,11 @@ async function changeCidr(ipv4Cidr: string, ipv6Cidr: string) {
}
const _restartInterface = useSubmit(
`/api/admin/interface/restart`,
{
method: 'post',
},
(data) =>
$fetch(`/api/admin/interface/restart`, {
method: 'post',
body: data,
}),
{
revert,
successMsg: t('admin.interface.restartSuccess'),
+10 -8
View File
@@ -225,10 +225,11 @@ const { data: _data, refresh } = await useFetch(`/api/client/${id}`, {
const data = toRef(_data.value);
const _submit = useSubmit(
`/api/client/${id}`,
{
method: 'post',
},
(data) =>
$fetch(`/api/client/${id}`, {
method: 'post',
body: data,
}),
{
revert: async (success) => {
if (success) {
@@ -250,10 +251,11 @@ async function revert() {
}
const _deleteClient = useSubmit(
`/api/client/${id}`,
{
method: 'delete',
},
(data) =>
$fetch(`/api/client/${id}`, {
method: 'delete',
body: data,
}),
{
revert: async () => {
await navigateTo('/');
+5 -4
View File
@@ -78,10 +78,11 @@ const totpRequired = ref(false);
const totp = ref<string>('');
const _submit = useSubmit(
'/api/session',
{
method: 'post',
},
(data) =>
$fetch('/api/session', {
method: 'post',
body: data,
}),
{
revert: async (success, data) => {
if (success) {
+25 -20
View File
@@ -127,10 +127,11 @@ const name = ref(authStore.userData?.name);
const email = ref(authStore.userData?.email);
const _submit = useSubmit(
`/api/me`,
{
method: 'post',
},
(data) =>
$fetch(`/api/me`, {
method: 'post',
body: data,
}),
{
revert: () => {
return authStore.update();
@@ -147,10 +148,11 @@ const newPassword = ref('');
const confirmPassword = ref('');
const _updatePassword = useSubmit(
`/api/me/password`,
{
method: 'post',
},
(data) =>
$fetch(`/api/me/password`, {
method: 'post',
body: data,
}),
{
revert: async () => {
currentPassword.value = '';
@@ -171,10 +173,11 @@ function updatePassword() {
const twofa = ref<{ key: string; qrcode: string } | null>(null);
const _setup2fa = useSubmit(
`/api/me/totp`,
{
method: 'post',
},
(data) =>
$fetch(`/api/me/totp`, {
method: 'post',
body: data,
}),
{
revert: async (success, data) => {
if (success && data?.type === 'setup') {
@@ -199,10 +202,11 @@ async function setup2fa() {
const code = ref<string>('');
const _enable2fa = useSubmit(
`/api/me/totp`,
{
method: 'post',
},
(data) =>
$fetch(`/api/me/totp`, {
method: 'post',
body: data,
}),
{
revert: async (success, data) => {
if (success && data?.type === 'created') {
@@ -224,10 +228,11 @@ async function enable2fa() {
const disable2faPassword = ref('');
const _disable2fa = useSubmit(
`/api/me/totp`,
{
method: 'post',
},
(data) =>
$fetch(`/api/me/totp`, {
method: 'post',
body: data,
}),
{
revert: async (success, data) => {
if (success && data?.type === 'deleted') {
+5 -4
View File
@@ -50,10 +50,11 @@ const password = ref<string>('');
const confirmPassword = ref<string>('');
const _submit = useSubmit(
'/api/setup/2',
{
method: 'post',
},
(data) =>
$fetch('/api/setup/2', {
method: 'post',
body: data,
}),
{
revert: async (success) => {
if (success) {
+5 -4
View File
@@ -43,10 +43,11 @@ const host = ref<null | string>(null);
const port = ref<number>(51820);
const _submit = useSubmit(
'/api/setup/4',
{
method: 'post',
},
(data) =>
$fetch('/api/setup/4', {
method: 'post',
body: data,
}),
{
revert: async (success) => {
if (success) {
+5 -4
View File
@@ -36,10 +36,11 @@ function onChangeFile(evt: Event) {
}
const _submit = useSubmit(
'/api/setup/migrate',
{
method: 'post',
},
(data) =>
$fetch('/api/setup/migrate', {
method: 'post',
body: data,
}),
{
revert: async (success) => {
if (success) {
+3 -3
View File
@@ -18,9 +18,9 @@ export default defineEventHandler(async (event) => {
statusMessage: 'Invalid username or password',
});
case 'TOTP_REQUIRED':
return { status: 'TOTP_REQUIRED' };
return { status: 'TOTP_REQUIRED' as const };
case 'INVALID_TOTP_CODE':
return { status: 'INVALID_TOTP_CODE' };
return { status: 'INVALID_TOTP_CODE' as const };
case 'USER_DISABLED':
throw createError({
statusCode: 401,
@@ -47,5 +47,5 @@ export default defineEventHandler(async (event) => {
SERVER_DEBUG(`New Session: ${data.id} for ${user.id} (${user.username})`);
return { status: 'success' };
return { status: 'success' as const };
});