Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions resources/js/commands/components/CommandFormModal.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { CommandManager } from "../CommandManager";
import { ref, watchEffect } from "vue";
import { ref, useTemplateRef, watchEffect } from "vue";
import type SharpForm from '@/form/components/Form.vue';
import {
Dialog,
Expand All @@ -14,6 +14,8 @@
import { Button } from "@/components/ui/button";
import { __ } from "@/utils/i18n";
import { CommandFormExtraData } from "@/commands/types";
import { useEventListener } from "@vueuse/core";
import { FormEvents } from "@/form/Form";

const props = defineProps<{
commands: CommandManager,
Expand All @@ -23,6 +25,12 @@
const modalOpen = ref(false);
const currentFormUpdatedKey = ref(0);

const content = useTemplateRef<InstanceType<typeof DialogScrollContent>>('content');

useEventListener<FormEvents>(() => props.commands.state.currentCommandForm, 'error', () => {
content.value.scrollToTop();
});

watchEffect(() => {
modalOpen.value = !!props.commands.state.currentCommandForm;
currentFormUpdatedKey.value++;
Expand All @@ -34,7 +42,11 @@
v-model:open="modalOpen"
@update:open="!$event && $nextTick(() => commands.finish())"
>
<DialogScrollContent class="sm:max-w-[558px] gap-8" @pointer-down-outside.prevent>
<DialogScrollContent
class="sm:max-w-[558px] gap-8"
@pointer-down-outside.prevent
ref="content"
>
<template v-if="commands.state.currentCommandForm">
<DialogHeader>
<DialogTitle>
Expand All @@ -49,6 +61,8 @@
<SharpForm
:post-fn="(data) => commands.postForm(data)"
:form="commands.state.currentCommandForm"
:show-error-alert="commands.state.currentCommandForm.hasErrors"
:error-alert-message="commands.state.currentCommandForm.fieldError('error')"
@loading="(loading) => commands.state.currentCommandFormLoading = loading"
:key="`form-${currentFormUpdatedKey}`"
modal
Expand Down
45 changes: 26 additions & 19 deletions resources/js/components/ui/dialog/DialogScrollContent.vue
Original file line number Diff line number Diff line change
@@ -1,33 +1,40 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import {
DialogClose,
DialogContent,
type DialogContentEmits,
type DialogContentProps,
DialogOverlay,
DialogPortal,
useForwardPropsEmits,
} from 'reka-ui'
import { X } from 'lucide-vue-next'
import { cn } from '@/utils/cn'
import { type HTMLAttributes, computed, useTemplateRef } from 'vue'
import {
DialogClose,
DialogContent,
type DialogContentEmits,
type DialogContentProps,
DialogOverlay,
DialogPortal,
useForwardPropsEmits,
} from 'reka-ui'
import { X } from 'lucide-vue-next'
import { cn } from '@/utils/cn'

const props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<DialogContentEmits>()
const props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>()
const emits = defineEmits<DialogContentEmits>()

const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props

return delegated
})
return delegated
})

const forwarded = useForwardPropsEmits(delegatedProps, emits)
const forwarded = useForwardPropsEmits(delegatedProps, emits)
const overlay = useTemplateRef<InstanceType<typeof DialogOverlay>>('overlay');
defineExpose({
scrollToTop: () => {
overlay.value.$el.scrollTo(0, 0);
},
});
</script>

<template>
<DialogPortal>
<DialogOverlay
class="fixed inset-0 z-50 grid grid-cols-1 place-items-center overflow-y-auto bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
ref="overlay"
>
<DialogContent
:class="
Expand Down
3 changes: 3 additions & 0 deletions resources/js/form/Form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ export class Form implements FormData, CommandFormData, EventTarget {
set errors(errors) {
this.state.errors = errors;
}
get hasErrors() {
return Object.keys(this.errors).length > 0;
}

get meta() {
return this.state.meta;
Expand Down
11 changes: 8 additions & 3 deletions resources/js/form/components/Form.vue
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,21 @@
<template>
<Tabs v-model="selectedTabSlug" :unmount-on-hide="false">
<template v-if="showErrorAlert">
<div class="container">
<Alert class="mb-4" variant="destructive">
<div :class="modal ? 'mb-8' : 'mb-4 container'">
<Alert variant="destructive">
<template v-if="errorAlertMessage">
<AlertTitle>
<AlertTitle v-if="!modal">
{{ __('sharp::modals.error.title') }}
</AlertTitle>
<AlertDescription>
{{ errorAlertMessage }}
</AlertDescription>
</template>
<template v-else-if="modal">
<AlertDescription>
{{ __('sharp::form.validation_error.title') }} {{ __('sharp::form.validation_error.description') }}
</AlertDescription>
</template>
<template v-else>
<AlertTitle>
{{ __('sharp::form.validation_error.title') }}
Expand Down
Loading