Browse Source

chore: rework useSubmit (#2649)

rework useSubmit
pull/2399/head
Bernd Storath 1 day ago
committed by GitHub
parent
commit
bc95a2851f
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 9
      src/app/components/ClientCard/OneTimeLinkBtn.vue
  2. 18
      src/app/components/ClientCard/Switch.vue
  3. 9
      src/app/components/Clients/CreateDialog.vue
  4. 9
      src/app/components/Ui/UserMenu.vue
  5. 47
      src/app/composables/useSubmit.ts
  6. 9
      src/app/pages/admin/config.vue
  7. 9
      src/app/pages/admin/general.vue
  8. 9
      src/app/pages/admin/hooks.vue
  9. 27
      src/app/pages/admin/interface.vue
  10. 18
      src/app/pages/clients/[id].vue
  11. 9
      src/app/pages/login.vue
  12. 45
      src/app/pages/me.vue
  13. 9
      src/app/pages/setup/2.vue
  14. 9
      src/app/pages/setup/4.vue
  15. 9
      src/app/pages/setup/migrate.vue
  16. 6
      src/server/api/session.post.ts

9
src/app/components/ClientCard/OneTimeLinkBtn.vue

@ -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();

18
src/app/components/ClientCard/Switch.vue

@ -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();

9
src/app/components/Clients/CreateDialog.vue

@ -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'),

9
src/app/components/Ui/UserMenu.vue

@ -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');

47
src/app/composables/useSubmit.ts

@ -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({

9
src/app/pages/admin/config.vue

@ -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 }
);

9
src/app/pages/admin/general.vue

@ -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 }
);

9
src/app/pages/admin/hooks.vue

@ -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 }
);

27
src/app/pages/admin/interface.vue

@ -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'),

18
src/app/pages/clients/[id].vue

@ -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('/');

9
src/app/pages/login.vue

@ -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) {

45
src/app/pages/me.vue

@ -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') {

9
src/app/pages/setup/2.vue

@ -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) {

9
src/app/pages/setup/4.vue

@ -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) {

9
src/app/pages/setup/migrate.vue

@ -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) {

6
src/server/api/session.post.ts

@ -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 };
});

Loading…
Cancel
Save