Skip to content

Commit 40ec846

Browse files
committed
wip improve editor
1 parent 7550ae8 commit 40ec846

13 files changed

Lines changed: 208 additions & 119 deletions

File tree

resources/js/components/ui/dialog/DialogContent.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
} from 'reka-ui'
1212
import { X } from 'lucide-vue-next'
1313
import { cn } from '@/utils/cn'
14+
import { useParentHTMLDialogElement } from "@/composables/useParentDialogElement";
1415
1516
const props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>()
1617
const emits = defineEmits<DialogContentEmits>()
@@ -21,11 +22,12 @@ const delegatedProps = computed(() => {
2122
return delegated
2223
})
2324
24-
const forwarded = useForwardPropsEmits(delegatedProps, emits)
25+
const forwarded = useForwardPropsEmits(delegatedProps, emits);
26+
const parentHTMLDialogElement = useParentHTMLDialogElement();
2527
</script>
2628

2729
<template>
28-
<DialogPortal>
30+
<DialogPortal :to="parentHTMLDialogElement ?? undefined">
2931
<DialogOverlay
3032
class="fixed inset-0 z-50 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"
3133
/>

resources/js/components/ui/dialog/DialogScrollContent.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
} from 'reka-ui'
1212
import { X } from 'lucide-vue-next'
1313
import { cn } from '@/utils/cn'
14+
import { useParentHTMLDialogElement } from "@/composables/useParentDialogElement";
1415
1516
const props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>()
1617
const emits = defineEmits<DialogContentEmits>()
@@ -23,6 +24,7 @@
2324
2425
const forwarded = useForwardPropsEmits(delegatedProps, emits)
2526
const overlay = useTemplateRef<InstanceType<typeof DialogOverlay>>('overlay');
27+
const parentHTMLDialogElement = useParentHTMLDialogElement();
2628
defineExpose({
2729
scrollToTop: () => {
2830
overlay.value.$el.scrollTo(0, 0);
@@ -31,7 +33,7 @@
3133
</script>
3234

3335
<template>
34-
<DialogPortal>
36+
<DialogPortal :to="parentHTMLDialogElement ?? undefined">
3537
<DialogOverlay
3638
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"
3739
ref="overlay"

resources/js/composables/useParentDialogElement.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,12 @@ export function provideParentDialogElement(dialog: Ref<HTMLElement>) {
1212
);
1313
}
1414

15+
export function useParentHTMLDialogElement() {
16+
return inject<ComputedRef<HTMLDialogElement | undefined>>('parentDialog', undefined);
17+
}
18+
1519
export function useParentDialogElement() {
16-
const parentDialogElement = inject<ComputedRef<HTMLDialogElement | undefined>>('parentDialog', undefined);
20+
const parentHTMLDialogElement = useParentHTMLDialogElement();
1721
const rekaDialogContext = injectDialogRootContext(null);
1822

1923
if(rekaDialogContext) {
@@ -24,8 +28,8 @@ export function useParentDialogElement() {
2428
rekaDialogElement.value = rekaDialogContext?.contentElement.value?.parentElement;
2529
});
2630

27-
return computed(() => parentDialogElement.value ?? rekaDialogElement.value);
31+
return computed(() => parentHTMLDialogElement.value ?? rekaDialogElement.value);
2832
}
2933

30-
return parentDialogElement;
34+
return parentHTMLDialogElement;
3135
}

resources/js/content/ContentEmbedManager.ts

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ type ContentEmbed = {
1414

1515
export class ContentEmbedManager<Root extends Form | Show> {
1616
embeds: { [embedKey:string]: EmbedData } = {};
17-
onEmbedsUpdated: Root extends Form ? (embeds: FormEditorFieldData['value']['embeds']) => any : null
1817
root: Form | Show;
1918

2019
state = reactive<{
@@ -81,23 +80,21 @@ export class ContentEmbedManager<Root extends Form | Show> {
8180
return id;
8281
}
8382

84-
syncEmbeds(embed: EmbedData, locale: string | null, nodes: { id?:string }[]) {
85-
if(this.contentEmbeds[embed.key]) {
86-
this.contentEmbeds[embed.key] = {
87-
...Object.fromEntries(
88-
Object.entries(this.contentEmbeds[embed.key])
89-
.map(([id, contentEmbed]) => [
90-
id,
91-
({
92-
...contentEmbed,
93-
removed: contentEmbed.value?._locale == locale
94-
? !nodes.some(node => String(node.id) === id)
95-
: contentEmbed.removed,
96-
})
97-
])
98-
),
99-
};
100-
}
83+
syncEmbeds(embed: EmbedData, locale: string | null, ids: (string | number)[]) {
84+
this.contentEmbeds[embed.key] = {
85+
...Object.fromEntries(
86+
Object.entries(this.contentEmbeds[embed.key] ?? {})
87+
.map(([id, contentEmbed]) => [
88+
id,
89+
({
90+
...contentEmbed,
91+
removed: contentEmbed.value?._locale == locale
92+
? !ids.some(i => String(i) === id)
93+
: contentEmbed.removed,
94+
})
95+
])
96+
),
97+
};
10198
}
10299

103100
postResolveForm(id: string, embed: EmbedData): Promise<FormData> {
@@ -134,8 +131,6 @@ export class ContentEmbedManager<Root extends Form | Show> {
134131
},
135132
}
136133

137-
this.onEmbedsUpdated(this.serializedEmbeds);
138-
139134
return {
140135
id
141136
};

resources/js/content/ContentUploadManager.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { api } from "@/api/api";
22
import { route } from "@/utils/url";
33
import { Form } from "@/form/Form";
4-
import { FormEditorFieldData, FormUploadFieldValueData } from "@/types";
4+
import { FormEditorFieldData } from "@/types";
55
import { Show } from "@/show/Show";
6-
import { FormEditorUploadData, MaybeLocalizedContent } from "@/content/types";
6+
import { FormEditorUploadData } from "@/content/types";
77
import { reactive } from "vue";
88

99
type ContentUpload = {
@@ -13,9 +13,7 @@ type ContentUpload = {
1313

1414
export class ContentUploadManager<Root extends Form | Show> {
1515
root: Form | Show;
16-
onUploadsUpdated: Root extends Form ? (uploads: { [id:string]: FormEditorUploadData }) => any : null;
1716
editorField: Root extends Form ? FormEditorFieldData : null;
18-
1917
state = reactive<{ contentUploads: { [id:string]: ContentUpload } }>({
2018
contentUploads: {}
2119
});
@@ -80,12 +78,10 @@ export class ContentUploadManager<Root extends Form | Show> {
8078
})
8179
])
8280
);
83-
// this.onUploadsUpdated(this.serializedUploads);
8481
}
8582

8683
updateUpload(id: string, value: FormEditorUploadData) {
8784
this.contentUploads[id].value = { ...this.contentUploads[id].value, ...value };
88-
// this.onUploadsUpdated(this.serializedUploads);
8985
}
9086

9187
async postForm(id: string | null, locale: string | null, data: FormEditorUploadData): Promise<{ id:string }> {
@@ -105,8 +101,6 @@ export class ContentUploadManager<Root extends Form | Show> {
105101
value: responseData,
106102
}
107103

108-
this.onUploadsUpdated(this.serializedUploads);
109-
110104
return { id };
111105
}
112106
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<script setup lang="ts">
2+
3+
import { trans_choice } from "@/utils/i18n";
4+
import { FormFieldProps } from "@/form/types";
5+
import { FormFieldData } from "@/types";
6+
import { useParentForm } from "@/form/useParentForm";
7+
8+
const form = useParentForm();
9+
defineProps<FormFieldProps<FormFieldData, any>>();
10+
defineOptions({ inheritAttrs: false });
11+
</script>
12+
13+
<template>
14+
<template v-if="form.fieldError(fieldErrorKey)">
15+
{{ form.fieldError(fieldErrorKey) }}
16+
</template>
17+
<template v-else-if="'localized' in field && field.localized">
18+
<template v-if="form.fieldError(`${fieldErrorKey}.${locale}`)">
19+
{{ form.fieldError(`${fieldErrorKey}.${locale}`) }}
20+
</template>
21+
<template v-else>
22+
{{
23+
trans_choice(
24+
'sharp::form.validation_error.localized',
25+
form.fieldLocalesContainingError(fieldErrorKey).length,
26+
{ locales: form.fieldLocalesContainingError(fieldErrorKey).map(l => l.toUpperCase()) }
27+
)
28+
}}
29+
</template>
30+
</template>
31+
</template>

resources/js/form/components/FormFieldLayout.vue

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import { useId } from "@/composables/useId";
1111
1212
import FormFieldLocaleSelect from "@/form/components/FormFieldLocaleSelect.vue";
13+
import FormFieldError from "@/form/components/FormFieldError.vue";
1314
1415
defineOptions({
1516
inheritAttrs: false
@@ -23,6 +24,7 @@
2324
}>();
2425
const emit = defineEmits<FormFieldEmits & {
2526
(e: 'label-click'),
27+
(e: 'locale-select:close-auto-focus', event: Event),
2628
}>();
2729
const form = useParentForm();
2830
const id = useId(`form-field_${props.fieldErrorKey}`);
@@ -99,7 +101,12 @@
99101
</div>
100102
</template>
101103
<template v-if="'localized' in field && field.localized">
102-
<FormFieldLocaleSelect v-bind="props" is-field-layout @locale-change="emit('locale-change', $event)" />
104+
<FormFieldLocaleSelect
105+
v-bind="props"
106+
is-field-layout
107+
@locale-change="emit('locale-change', $event)"
108+
@close-auto-focus="emit('locale-select:close-auto-focus', $event)"
109+
/>
103110
</template>
104111
<!-- <template v-if="'localized' in field && field.localized">-->
105112
<!-- <div class="ml-auto flex items-center h-3.5 gap-0 md:gap-1">-->
@@ -148,25 +155,7 @@
148155

149156
<template v-if="form.fieldHasError(field, fieldErrorKey)">
150157
<div :id="`${id}-error`" class="mb-1 text-sm text-destructive leading-4">
151-
<span class="">
152-
<template v-if="form.fieldError(fieldErrorKey)">
153-
{{ form.fieldError(fieldErrorKey) }}
154-
</template>
155-
<template v-else-if="'localized' in field && field.localized">
156-
<template v-if="form.fieldError(`${fieldErrorKey}.${locale}`)">
157-
{{ form.fieldError(`${fieldErrorKey}.${locale}`) }}
158-
</template>
159-
<template v-else>
160-
{{
161-
trans_choice(
162-
'sharp::form.validation_error.localized',
163-
form.fieldLocalesContainingError(fieldErrorKey).length,
164-
{ locales: form.fieldLocalesContainingError(fieldErrorKey).map(l => l.toUpperCase()) }
165-
)
166-
}}
167-
</template>
168-
</template>
169-
</span>
158+
<FormFieldError v-bind="props" />
170159
</div>
171160
</template>
172161
</div>

resources/js/form/components/FormFieldLocaleSelect.vue

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { FormFieldData } from "@/types";
88
import { useParentForm } from "@/form/useParentForm";
99
1010
const props = defineProps<FormFieldProps<FormFieldData, any> & { isFieldLayout?: boolean }>();
11-
const emit = defineEmits<FormFieldEmits>();
11+
const emit = defineEmits<FormFieldEmits & { (e: 'close-auto-focus', event: Event): void }>();
1212
const form = useParentForm();
1313
</script>
1414

@@ -19,13 +19,13 @@ const form = useParentForm();
1919
:class="{ '-my-2': isFieldLayout }"
2020
:aria-label="__('sharp::form.field_locale_selector.aria_label', { field_label:field.label })"
2121
/>
22-
<SelectContent>
23-
<template v-for="itemLocale in form.locales" :key="itemLocale">
24-
<SelectItem :value="itemLocale">
22+
<SelectContent @close-auto-focus="emit('close-auto-focus', $event)">
23+
<template v-for="formLocale in form.locales" :key="formLocale">
24+
<SelectItem :value="formLocale">
2525
<div class="flex items-center">
26-
<span class="uppercase text-xs">{{ itemLocale }}</span>
27-
<template v-if="form.fieldLocalesContainingError(fieldErrorKey).includes(itemLocale)">
28-
<svg class="ml-1 h-2 w-2 fill-destructive" viewBox="0 0 8 8" aria-hidden="true">
26+
<span class="uppercase text-xs">{{ formLocale }}</span>
27+
<template v-if="form.fieldLocalesContainingError(fieldErrorKey).includes(formLocale)">
28+
<svg class="ml-1 size-2 fill-destructive" viewBox="0 0 8 8" aria-hidden="true">
2929
<circle cx="4" cy="4" r="3" />
3030
</svg>
3131
</template>

0 commit comments

Comments
 (0)