@mapomodule/form 2.0.0-beta.5 → 2.0.0-beta.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.d.ts.map +1 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +4 -1
- package/dist/runtime/components/MapoFocusPortal.vue +3 -1
- package/dist/runtime/components/MapoFocusPortal.vue.d.ts.map +1 -1
- package/dist/runtime/components/MapoFormTabs.vue +4 -2
- package/dist/runtime/components/MapoFormTabs.vue.d.ts.map +1 -1
- package/dist/runtime/components/fields/MapoDateField.vue +3 -1
- package/dist/runtime/components/fields/MapoDateField.vue.d.ts.map +1 -1
- package/dist/runtime/components/fields/MapoDateTimeField.vue +5 -3
- package/dist/runtime/components/fields/MapoDateTimeField.vue.d.ts.map +1 -1
- package/dist/runtime/components/fields/MapoEnhancedMediaField.vue +7 -5
- package/dist/runtime/components/fields/MapoEnhancedMediaField.vue.d.ts.map +1 -1
- package/dist/runtime/components/fields/MapoFileField.vue +3 -1
- package/dist/runtime/components/fields/MapoFileField.vue.d.ts.map +1 -1
- package/dist/runtime/components/fields/MapoFksField.vue +6 -2
- package/dist/runtime/components/fields/MapoFksField.vue.d.ts.map +1 -1
- package/dist/runtime/components/fields/MapoMapField.vue +4 -2
- package/dist/runtime/components/fields/MapoMapField.vue.d.ts.map +1 -1
- package/dist/runtime/components/fields/MapoMediaField.vue +3 -1
- package/dist/runtime/components/fields/MapoMediaField.vue.d.ts.map +1 -1
- package/dist/runtime/components/fields/MapoMediaM2mField.vue +5 -1
- package/dist/runtime/components/fields/MapoMediaM2mField.vue.d.ts.map +1 -1
- package/dist/runtime/components/fields/MapoRepeater.vue +32 -22
- package/dist/runtime/components/fields/MapoRepeater.vue.d.ts.map +1 -1
- package/dist/runtime/components/fields/MapoRepeaterItem.vue +13 -8
- package/dist/runtime/components/fields/MapoRepeaterItem.vue.d.ts.map +1 -1
- package/dist/runtime/components/fields/MapoSeoPreview.vue +16 -12
- package/dist/runtime/components/fields/MapoSeoPreview.vue.d.ts.map +1 -1
- package/dist/runtime/components/fields/MapoWygEditor.vue +5 -1
- package/dist/runtime/components/fields/MapoWygEditor.vue.d.ts.map +1 -1
- package/dist/runtime/composables/useMapoForm.d.ts.map +1 -1
- package/dist/runtime/composables/useMapoForm.js +4 -2
- package/dist/runtime/composables/useUnsavedChangesGuard.d.ts.map +1 -1
- package/dist/runtime/composables/useUnsavedChangesGuard.js +3 -2
- package/package.json +9 -8
- package/src/__tests__/useMapoForm.test.ts +5 -0
- package/src/module.ts +9 -0
- package/src/runtime/components/MapoFocusPortal.vue +3 -1
- package/src/runtime/components/MapoFormTabs.vue +4 -1
- package/src/runtime/components/fields/MapoDateField.vue +3 -1
- package/src/runtime/components/fields/MapoDateTimeField.vue +3 -1
- package/src/runtime/components/fields/MapoEnhancedMediaField.vue +8 -5
- package/src/runtime/components/fields/MapoFileField.vue +3 -1
- package/src/runtime/components/fields/MapoFksField.vue +7 -2
- package/src/runtime/components/fields/MapoMapField.vue +5 -2
- package/src/runtime/components/fields/MapoMediaField.vue +4 -1
- package/src/runtime/components/fields/MapoMediaM2mField.vue +8 -1
- package/src/runtime/components/fields/MapoRepeater.vue +33 -26
- package/src/runtime/components/fields/MapoRepeaterItem.vue +14 -8
- package/src/runtime/components/fields/MapoSeoPreview.vue +17 -13
- package/src/runtime/components/fields/MapoWygEditor.vue +8 -1
- package/src/runtime/composables/useMapoForm.ts +4 -2
- package/src/runtime/composables/useUnsavedChangesGuard.ts +3 -3
package/dist/module.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAErE,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;;AAED,wBAkOyC"}
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineNuxtModule, createResolver, addPlugin, addTypeTemplate, extendPages, addComponent, addImports } from '@nuxt/kit';
|
|
1
|
+
import { defineNuxtModule, createResolver, hasNuxtModule, installModule, addPlugin, addTypeTemplate, extendPages, addComponent, addImports } from '@nuxt/kit';
|
|
2
2
|
|
|
3
3
|
const module$1 = defineNuxtModule({
|
|
4
4
|
meta: {
|
|
@@ -16,6 +16,9 @@ const module$1 = defineNuxtModule({
|
|
|
16
16
|
(nuxt.options.imports.transform.include ??= []).push(
|
|
17
17
|
/@mapomodule[\\/]form[\\/]/
|
|
18
18
|
);
|
|
19
|
+
if (!hasNuxtModule("@mapomodule/i18n")) {
|
|
20
|
+
await installModule(await resolver.resolvePath("@mapomodule/i18n"));
|
|
21
|
+
}
|
|
19
22
|
nuxt.options.runtimeConfig.public.mapoForm = {
|
|
20
23
|
groups: { expanded: options.groups?.expanded ?? true },
|
|
21
24
|
debounce: options.debounce ?? 300,
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { computed, ref, onMounted, onUnmounted } from "vue";
|
|
3
3
|
import { watch } from "vue";
|
|
4
|
+
import { useI18n } from "vue-i18n";
|
|
4
5
|
import { useFocusMode } from "../composables/useFocusMode.js";
|
|
5
6
|
import MapoForm from "./MapoForm.vue";
|
|
7
|
+
const { t } = useI18n();
|
|
6
8
|
const { focusTarget, exit } = useFocusMode();
|
|
7
9
|
const isOpen = computed(() => focusTarget.value !== null);
|
|
8
10
|
const canUseDocument = typeof document !== "undefined";
|
|
@@ -66,7 +68,7 @@ function onUpdate(val) {
|
|
|
66
68
|
variant="ghost"
|
|
67
69
|
color="neutral"
|
|
68
70
|
icon="i-lucide-x"
|
|
69
|
-
label="
|
|
71
|
+
:label="t('mapo.close')"
|
|
70
72
|
size="sm"
|
|
71
73
|
@click="exit"
|
|
72
74
|
/>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapoFocusPortal.vue.d.ts","sourceRoot":"","sources":["../../../src/runtime/components/MapoFocusPortal.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MapoFocusPortal.vue.d.ts","sourceRoot":"","sources":["../../../src/runtime/components/MapoFocusPortal.vue"],"names":[],"mappings":"AAudA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { ref, computed } from "vue";
|
|
3
|
+
import { useI18n } from "vue-i18n";
|
|
3
4
|
import { injectMapoForm } from "../composables/useMapoForm.js";
|
|
4
5
|
import MapoFormGroup from "./MapoFormGroup.vue";
|
|
5
6
|
import MapoFormFlatSection from "./MapoFormFlatSection.vue";
|
|
7
|
+
const { t } = useI18n();
|
|
6
8
|
const props = defineProps({
|
|
7
9
|
tabs: { type: Array, required: true }
|
|
8
10
|
});
|
|
@@ -21,7 +23,7 @@ const form = injectMapoForm();
|
|
|
21
23
|
const tabsWithErrors = computed(() => {
|
|
22
24
|
const errorKeys = new Set(Object.keys(form.errors.value));
|
|
23
25
|
return new Set(
|
|
24
|
-
props.tabs.filter((tab) => tabHasErrors(tab, errorKeys)).map((
|
|
26
|
+
props.tabs.filter((tab) => tabHasErrors(tab, errorKeys)).map((t2) => t2.name)
|
|
25
27
|
);
|
|
26
28
|
});
|
|
27
29
|
</script>
|
|
@@ -46,7 +48,7 @@ const tabsWithErrors = computed(() => {
|
|
|
46
48
|
<span
|
|
47
49
|
v-if="tabsWithErrors.has(tab.name)"
|
|
48
50
|
class="inline-block h-1.5 w-1.5 rounded-full bg-red-500"
|
|
49
|
-
aria-label="
|
|
51
|
+
:aria-label="t('mapo.form.tabErrors')"
|
|
50
52
|
/>
|
|
51
53
|
</button>
|
|
52
54
|
<!-- Extra content appended to the tab bar (actions, badges, …). -->
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapoFormTabs.vue.d.ts","sourceRoot":"","sources":["../../../src/runtime/components/MapoFormTabs.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MapoFormTabs.vue.d.ts","sourceRoot":"","sources":["../../../src/runtime/components/MapoFormTabs.vue"],"names":[],"mappings":"AA4HA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAOnD,KAAK,WAAW,GAAG;IAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;CAAE,CAAC;AAGxC,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAsO3C,QAAA,MAAM,UAAU,kSAEd,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AACzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { computed, ref } from "vue";
|
|
3
|
+
import { useI18n } from "vue-i18n";
|
|
3
4
|
import { parseDate, CalendarDate } from "@internationalized/date";
|
|
4
5
|
const props = defineProps({
|
|
5
6
|
modelValue: { type: null, required: true },
|
|
@@ -9,6 +10,7 @@ const props = defineProps({
|
|
|
9
10
|
disabled: { type: Boolean, required: false }
|
|
10
11
|
});
|
|
11
12
|
const emit = defineEmits(["update:modelValue"]);
|
|
13
|
+
const { t } = useI18n();
|
|
12
14
|
const open = ref(false);
|
|
13
15
|
const calendarValue = computed(() => {
|
|
14
16
|
const v = props.modelValue;
|
|
@@ -21,7 +23,7 @@ const calendarValue = computed(() => {
|
|
|
21
23
|
});
|
|
22
24
|
const displayLabel = computed(() => {
|
|
23
25
|
const v = calendarValue.value;
|
|
24
|
-
if (!v) return "
|
|
26
|
+
if (!v) return t("mapo.dateField.selectDate");
|
|
25
27
|
return `${String(v.day).padStart(2, "0")}/${String(v.month).padStart(2, "0")}/${v.year}`;
|
|
26
28
|
});
|
|
27
29
|
const attrs = computed(() => props.descriptor.attrs ?? {});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapoDateField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoDateField.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MapoDateField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoDateField.vue"],"names":[],"mappings":"AA0GA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,4EAA4E;AAC5E,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,cAAc,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAyMF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
today,
|
|
7
7
|
getLocalTimeZone
|
|
8
8
|
} from "@internationalized/date";
|
|
9
|
+
import { useI18n } from "vue-i18n";
|
|
9
10
|
const props = defineProps({
|
|
10
11
|
modelValue: { type: null, required: true },
|
|
11
12
|
descriptor: { type: Object, required: true },
|
|
@@ -14,6 +15,7 @@ const props = defineProps({
|
|
|
14
15
|
disabled: { type: Boolean, required: false }
|
|
15
16
|
});
|
|
16
17
|
const emit = defineEmits(["update:modelValue"]);
|
|
18
|
+
const { t } = useI18n();
|
|
17
19
|
const open = ref(false);
|
|
18
20
|
const tzMode = computed(() => props.descriptor.attrs?.tz ?? "naive");
|
|
19
21
|
const calendarValue = computed(() => {
|
|
@@ -48,7 +50,7 @@ function emitFromCalendar(v) {
|
|
|
48
50
|
}
|
|
49
51
|
const displayLabel = computed(() => {
|
|
50
52
|
const v = calendarValue.value;
|
|
51
|
-
if (!v) return "
|
|
53
|
+
if (!v) return t("mapo.dateField.selectDateTime");
|
|
52
54
|
const date = `${String(v.day).padStart(2, "0")}/${String(v.month).padStart(2, "0")}/${v.year}`;
|
|
53
55
|
const time = `${String(v.hour).padStart(2, "0")}:${String(v.minute).padStart(2, "0")}`;
|
|
54
56
|
return `${date} ${time}`;
|
|
@@ -72,8 +74,8 @@ function onTimeChange(part, val) {
|
|
|
72
74
|
Math.min(part === "hour" ? 23 : 59, parseInt(val) || 0)
|
|
73
75
|
);
|
|
74
76
|
const base = calendarValue.value ?? (() => {
|
|
75
|
-
const
|
|
76
|
-
return new CalendarDateTime(
|
|
77
|
+
const t2 = today(getLocalTimeZone());
|
|
78
|
+
return new CalendarDateTime(t2.year, t2.month, t2.day, 0, 0);
|
|
77
79
|
})();
|
|
78
80
|
const merged = part === "hour" ? new CalendarDateTime(base.year, base.month, base.day, n, base.minute) : new CalendarDateTime(base.year, base.month, base.day, base.hour, n);
|
|
79
81
|
emitFromCalendar(merged);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapoDateTimeField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoDateTimeField.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MapoDateTimeField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoDateTimeField.vue"],"names":[],"mappings":"AA6MA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,0EAA0E;AAC1E,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,cAAc,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAgWF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { ref, computed } from "vue";
|
|
3
|
+
import { useI18n } from "vue-i18n";
|
|
3
4
|
import { useMediaManager } from "../../composables/useMediaManager.js";
|
|
4
5
|
const props = defineProps({
|
|
5
6
|
modelValue: { type: null, required: true },
|
|
@@ -9,6 +10,7 @@ const props = defineProps({
|
|
|
9
10
|
disabled: { type: Boolean, required: false }
|
|
10
11
|
});
|
|
11
12
|
const emit = defineEmits(["update:modelValue"]);
|
|
13
|
+
const { t } = useI18n();
|
|
12
14
|
const dialogOpen = ref(false);
|
|
13
15
|
const { MediaDialog, available } = useMediaManager();
|
|
14
16
|
const current = computed(
|
|
@@ -61,7 +63,7 @@ function clear() {
|
|
|
61
63
|
<MapoMediaPreview v-if="current" :media="current" size="md" />
|
|
62
64
|
<div v-else class="flex flex-col items-center gap-1 text-dimmed">
|
|
63
65
|
<UIcon name="i-lucide-image-plus" class="size-7" />
|
|
64
|
-
<span class="text-[10px]">
|
|
66
|
+
<span class="text-[10px]">{{ t("mapo.select") }}</span>
|
|
65
67
|
</div>
|
|
66
68
|
</div>
|
|
67
69
|
</div>
|
|
@@ -79,7 +81,7 @@ function clear() {
|
|
|
79
81
|
size="xs"
|
|
80
82
|
variant="ghost"
|
|
81
83
|
color="neutral"
|
|
82
|
-
title="
|
|
84
|
+
:title="t('mapo.change')"
|
|
83
85
|
@click="dialogOpen = true"
|
|
84
86
|
/>
|
|
85
87
|
<UButton
|
|
@@ -88,7 +90,7 @@ function clear() {
|
|
|
88
90
|
size="xs"
|
|
89
91
|
variant="ghost"
|
|
90
92
|
color="neutral"
|
|
91
|
-
title="
|
|
93
|
+
:title="t('mapo.remove')"
|
|
92
94
|
@click="clear"
|
|
93
95
|
/>
|
|
94
96
|
</div>
|
|
@@ -97,13 +99,13 @@ function clear() {
|
|
|
97
99
|
<UInput
|
|
98
100
|
v-model="altValue"
|
|
99
101
|
size="sm"
|
|
100
|
-
placeholder="
|
|
102
|
+
:placeholder="t('mapo.enhancedMediaField.altText')"
|
|
101
103
|
:disabled="readonly || disabled || !current"
|
|
102
104
|
/>
|
|
103
105
|
<UInput
|
|
104
106
|
v-model="captionValue"
|
|
105
107
|
size="sm"
|
|
106
|
-
placeholder="
|
|
108
|
+
:placeholder="t('mapo.enhancedMediaField.caption')"
|
|
107
109
|
:disabled="readonly || disabled || !current"
|
|
108
110
|
/>
|
|
109
111
|
</div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapoEnhancedMediaField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoEnhancedMediaField.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MapoEnhancedMediaField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoEnhancedMediaField.vue"],"names":[],"mappings":"AA8JA,OAAO,KAAK,EACV,uBAAuB,EACvB,kBAAkB,EAEnB,MAAM,sBAAsB,CAAC;AAG9B,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,kBAAkB,GAAG,IAAI,GAAG,SAAS,CAAC;IAClD,UAAU,EAAE,uBAAuB,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AA+UF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { ref, computed } from "vue";
|
|
3
|
+
import { useI18n } from "vue-i18n";
|
|
3
4
|
const props = defineProps({
|
|
4
5
|
modelValue: { type: null, required: true },
|
|
5
6
|
descriptor: { type: Object, required: true },
|
|
@@ -8,6 +9,7 @@ const props = defineProps({
|
|
|
8
9
|
disabled: { type: Boolean, required: false }
|
|
9
10
|
});
|
|
10
11
|
const emit = defineEmits(["update:modelValue"]);
|
|
12
|
+
const { t } = useI18n();
|
|
11
13
|
const inputRef = ref(null);
|
|
12
14
|
const currentFileName = computed(() => {
|
|
13
15
|
if (props.modelValue instanceof File) return props.modelValue.name;
|
|
@@ -69,7 +71,7 @@ const accept = computed(
|
|
|
69
71
|
variant="ghost"
|
|
70
72
|
color="neutral"
|
|
71
73
|
icon="i-lucide-x"
|
|
72
|
-
aria-label="
|
|
74
|
+
:aria-label="t('mapo.fileField.removeFile')"
|
|
73
75
|
@click="clear"
|
|
74
76
|
/>
|
|
75
77
|
</div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapoFileField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoFileField.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MapoFileField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoFileField.vue"],"names":[],"mappings":"AAiHA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,cAAc,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AA6MF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { ref, computed, watch, onMounted } from "vue";
|
|
3
|
+
import { useI18n } from "vue-i18n";
|
|
3
4
|
import { useNuxtApp } from "#app";
|
|
4
5
|
import { debounce } from "@mapomodule/utils";
|
|
5
6
|
const props = defineProps({
|
|
@@ -10,6 +11,7 @@ const props = defineProps({
|
|
|
10
11
|
disabled: { type: Boolean, required: false }
|
|
11
12
|
});
|
|
12
13
|
const emit = defineEmits(["update:modelValue"]);
|
|
14
|
+
const { t } = useI18n();
|
|
13
15
|
const attrs = computed(() => props.descriptor.attrs);
|
|
14
16
|
const isMultiple = computed(
|
|
15
17
|
() => props.descriptor.type === "m2m" || !!attrs.value.multiple
|
|
@@ -43,7 +45,7 @@ const internalValue = computed({
|
|
|
43
45
|
set: (val) => emit("update:modelValue", val)
|
|
44
46
|
});
|
|
45
47
|
const placeholder = computed(
|
|
46
|
-
() => isMultiple.value ? "
|
|
48
|
+
() => isMultiple.value ? t("mapo.fksField.searchSelect") : t("mapo.search")
|
|
47
49
|
);
|
|
48
50
|
function getLabel(item) {
|
|
49
51
|
if (item !== null && item !== void 0 && typeof item !== "object") {
|
|
@@ -111,7 +113,9 @@ function getItemKey(item) {
|
|
|
111
113
|
<!-- Empty state -->
|
|
112
114
|
<template #empty>
|
|
113
115
|
<span class="text-sm text-gray-500">
|
|
114
|
-
{{
|
|
116
|
+
{{
|
|
117
|
+
searchTerm ? t("mapo.fksField.noResults") : t("mapo.fksField.noItems")
|
|
118
|
+
}}
|
|
115
119
|
</span>
|
|
116
120
|
</template>
|
|
117
121
|
</USelectMenu>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapoFksField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoFksField.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MapoFksField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoFksField.vue"],"names":[],"mappings":"AAmKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,aAAa,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAiQF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { ref, computed, defineAsyncComponent } from "vue";
|
|
3
|
+
import { useI18n } from "vue-i18n";
|
|
3
4
|
const LeafletMap = defineAsyncComponent(
|
|
4
5
|
() => import("./MapoMapFieldClient.vue")
|
|
5
6
|
);
|
|
7
|
+
const { t } = useI18n();
|
|
6
8
|
const props = defineProps({
|
|
7
9
|
modelValue: { type: null, required: true },
|
|
8
10
|
descriptor: { type: Object, required: true },
|
|
@@ -43,7 +45,7 @@ function clear() {
|
|
|
43
45
|
<div class="flex gap-2">
|
|
44
46
|
<UInput
|
|
45
47
|
v-model="latInput"
|
|
46
|
-
placeholder="
|
|
48
|
+
:placeholder="t('mapo.latitude')"
|
|
47
49
|
class="flex-1"
|
|
48
50
|
:readonly="readonly"
|
|
49
51
|
:disabled="disabled"
|
|
@@ -51,7 +53,7 @@ function clear() {
|
|
|
51
53
|
/>
|
|
52
54
|
<UInput
|
|
53
55
|
v-model="lngInput"
|
|
54
|
-
placeholder="
|
|
56
|
+
:placeholder="t('mapo.longitude')"
|
|
55
57
|
class="flex-1"
|
|
56
58
|
:readonly="readonly"
|
|
57
59
|
:disabled="disabled"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapoMapField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoMapField.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MapoMapField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoMapField.vue"],"names":[],"mappings":"AA6HA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAS1D,sDAAsD;AACtD,UAAU,MAAM;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,8EAA8E;AAC9E,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,aAAa,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAqOF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { ref, computed } from "vue";
|
|
3
|
+
import { useI18n } from "vue-i18n";
|
|
3
4
|
import { useMediaManager } from "../../composables/useMediaManager.js";
|
|
4
5
|
const props = defineProps({
|
|
5
6
|
modelValue: { type: null, required: true },
|
|
@@ -9,6 +10,7 @@ const props = defineProps({
|
|
|
9
10
|
disabled: { type: Boolean, required: false }
|
|
10
11
|
});
|
|
11
12
|
const emit = defineEmits(["update:modelValue"]);
|
|
13
|
+
const { t } = useI18n();
|
|
12
14
|
const dialogOpen = ref(false);
|
|
13
15
|
const { MediaDialog, available } = useMediaManager();
|
|
14
16
|
const current = computed(() => {
|
|
@@ -67,7 +69,7 @@ function clear() {
|
|
|
67
69
|
:block="!current"
|
|
68
70
|
@click="dialogOpen = true"
|
|
69
71
|
>
|
|
70
|
-
{{ current ? "
|
|
72
|
+
{{ current ? t("mapo.change") : t("mapo.mediaField.selectMedia") }}
|
|
71
73
|
</UButton>
|
|
72
74
|
|
|
73
75
|
<!-- Dialog -->
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapoMediaField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoMediaField.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MapoMediaField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoMediaField.vue"],"names":[],"mappings":"AA6GA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGvE,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAClD,UAAU,EAAE,eAAe,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAgOF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { ref, computed } from "vue";
|
|
3
|
+
import { useI18n } from "vue-i18n";
|
|
3
4
|
import { useMediaManager } from "../../composables/useMediaManager.js";
|
|
4
5
|
const props = defineProps({
|
|
5
6
|
modelValue: { type: null, required: true },
|
|
@@ -9,6 +10,7 @@ const props = defineProps({
|
|
|
9
10
|
disabled: { type: Boolean, required: false }
|
|
10
11
|
});
|
|
11
12
|
const emit = defineEmits(["update:modelValue"]);
|
|
13
|
+
const { t } = useI18n();
|
|
12
14
|
const dialogOpen = ref(false);
|
|
13
15
|
const { MediaDialog, available } = useMediaManager();
|
|
14
16
|
const current = computed(() => {
|
|
@@ -84,7 +86,9 @@ function onDragEnd() {
|
|
|
84
86
|
color="neutral"
|
|
85
87
|
@click="dialogOpen = true"
|
|
86
88
|
>
|
|
87
|
-
{{
|
|
89
|
+
{{
|
|
90
|
+
current.length > 0 ? t("mapo.mediaM2MField.addMedia") : t("mapo.mediaField.selectMedia")
|
|
91
|
+
}}
|
|
88
92
|
</UButton>
|
|
89
93
|
|
|
90
94
|
<!-- Dialog -->
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapoMediaM2mField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoMediaM2mField.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MapoMediaM2mField.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoMediaM2mField.vue"],"names":[],"mappings":"AAuIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAG1E,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC;IACtD,UAAU,EAAE,kBAAkB,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AA+QF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { ref, computed, watchEffect } from "vue";
|
|
3
|
+
import { useI18n } from "vue-i18n";
|
|
3
4
|
import { VueDraggable } from "vue-draggable-plus";
|
|
4
5
|
import { useConfirmStore } from "@mapomodule/store/runtime/stores/confirm";
|
|
5
6
|
import { injectMapoForm } from "../../composables/useMapoForm.js";
|
|
@@ -13,6 +14,7 @@ const props = defineProps({
|
|
|
13
14
|
});
|
|
14
15
|
const emit = defineEmits(["update:modelValue"]);
|
|
15
16
|
const form = injectMapoForm();
|
|
17
|
+
const { t } = useI18n();
|
|
16
18
|
const attrs = computed(() => props.descriptor.attrs ?? {});
|
|
17
19
|
const items = computed({
|
|
18
20
|
get: () => Array.isArray(props.modelValue) ? props.modelValue : [],
|
|
@@ -69,7 +71,8 @@ function remainingSlots() {
|
|
|
69
71
|
function minBound() {
|
|
70
72
|
return attrs.value.minItems ?? 0;
|
|
71
73
|
}
|
|
72
|
-
async function askConfirm(message, title
|
|
74
|
+
async function askConfirm(message, title) {
|
|
75
|
+
title ??= t("mapo.confirm");
|
|
73
76
|
try {
|
|
74
77
|
return await useConfirmStore().ask({ title, message });
|
|
75
78
|
} catch {
|
|
@@ -86,8 +89,8 @@ async function deleteItem(index) {
|
|
|
86
89
|
if (!canDelete.value) return;
|
|
87
90
|
if (attrs.value.confirmDelete !== false) {
|
|
88
91
|
const confirmed = await askConfirm(
|
|
89
|
-
"
|
|
90
|
-
"
|
|
92
|
+
t("mapo.confirmDelete"),
|
|
93
|
+
t("mapo.repeater.deleteItem")
|
|
91
94
|
);
|
|
92
95
|
if (!confirmed) return;
|
|
93
96
|
}
|
|
@@ -198,14 +201,14 @@ async function bulkDelete() {
|
|
|
198
201
|
if (count === 0) return;
|
|
199
202
|
if (items.value.length - count < minBound()) {
|
|
200
203
|
await askConfirm(
|
|
201
|
-
|
|
202
|
-
"
|
|
204
|
+
t("mapo.repeater.minItemsBlock", { min: minBound() }),
|
|
205
|
+
t("mapo.repeater.actionBlocked")
|
|
203
206
|
);
|
|
204
207
|
return;
|
|
205
208
|
}
|
|
206
209
|
const confirmed = await askConfirm(
|
|
207
|
-
|
|
208
|
-
"
|
|
210
|
+
t("mapo.repeater.confirmBulkDelete", { count }),
|
|
211
|
+
t("mapo.repeater.deleteItems")
|
|
209
212
|
);
|
|
210
213
|
if (!confirmed) return;
|
|
211
214
|
pushUndo();
|
|
@@ -250,7 +253,7 @@ const errorPrefix = (index) => `${props.descriptor.key}.${index}`;
|
|
|
250
253
|
class="flex flex-wrap items-center gap-2 rounded border border-gray-200 bg-gray-50 px-3 py-2"
|
|
251
254
|
>
|
|
252
255
|
<span class="text-sm font-medium text-gray-700">
|
|
253
|
-
{{
|
|
256
|
+
{{ t("mapo.repeater.nItems", { n: items.length }, items.length) }}
|
|
254
257
|
<span v-if="attrs.maxItems" class="text-gray-400"
|
|
255
258
|
>/ {{ attrs.maxItems }}</span
|
|
256
259
|
>
|
|
@@ -258,10 +261,10 @@ const errorPrefix = (index) => `${props.descriptor.key}.${index}`;
|
|
|
258
261
|
|
|
259
262
|
<div class="flex flex-1 flex-wrap items-center justify-end gap-2">
|
|
260
263
|
<UButton size="xs" variant="ghost" color="neutral" @click="collapseAll">
|
|
261
|
-
|
|
264
|
+
{{ t("mapo.repeater.collapseAll") }}
|
|
262
265
|
</UButton>
|
|
263
266
|
<UButton size="xs" variant="ghost" color="neutral" @click="expandAll">
|
|
264
|
-
|
|
267
|
+
{{ t("mapo.repeater.expandAll") }}
|
|
265
268
|
</UButton>
|
|
266
269
|
<UButton
|
|
267
270
|
v-if="undoStack.length"
|
|
@@ -269,7 +272,7 @@ const errorPrefix = (index) => `${props.descriptor.key}.${index}`;
|
|
|
269
272
|
variant="ghost"
|
|
270
273
|
color="neutral"
|
|
271
274
|
icon="i-lucide-undo-2"
|
|
272
|
-
title="
|
|
275
|
+
:title="t('mapo.repeater.undoLastAction')"
|
|
273
276
|
@click="undo"
|
|
274
277
|
/>
|
|
275
278
|
|
|
@@ -279,8 +282,10 @@ const errorPrefix = (index) => `${props.descriptor.key}.${index}`;
|
|
|
279
282
|
:variant="selectionMode ? 'solid' : 'ghost'"
|
|
280
283
|
color="neutral"
|
|
281
284
|
icon="i-lucide-check-square"
|
|
282
|
-
title="
|
|
283
|
-
:label="
|
|
285
|
+
:title="t('mapo.repeater.bulkSelection')"
|
|
286
|
+
:label="
|
|
287
|
+
selectionMode ? t('mapo.repeater.exitSelection') : t('mapo.select')
|
|
288
|
+
"
|
|
284
289
|
@click="toggleSelectionMode"
|
|
285
290
|
/>
|
|
286
291
|
|
|
@@ -300,7 +305,7 @@ const errorPrefix = (index) => `${props.descriptor.key}.${index}`;
|
|
|
300
305
|
:disabled="!canAdd"
|
|
301
306
|
@click="addItem"
|
|
302
307
|
>
|
|
303
|
-
|
|
308
|
+
{{ t("mapo.add") }}
|
|
304
309
|
</UButton>
|
|
305
310
|
</div>
|
|
306
311
|
</div>
|
|
@@ -312,11 +317,11 @@ const errorPrefix = (index) => `${props.descriptor.key}.${index}`;
|
|
|
312
317
|
class="flex items-center gap-2 rounded border border-primary-200 bg-primary-50 px-3 py-2"
|
|
313
318
|
>
|
|
314
319
|
<span class="text-sm font-medium text-primary-700">
|
|
315
|
-
{{ selectionCount }}
|
|
320
|
+
{{ t("mapo.repeater.nSelected", { n: selectionCount }) }}
|
|
316
321
|
</span>
|
|
317
322
|
<div class="flex flex-1 flex-wrap items-center gap-2">
|
|
318
323
|
<UButton size="xs" variant="ghost" color="neutral" @click="selectAll">
|
|
319
|
-
|
|
324
|
+
{{ t("mapo.repeater.all") }}
|
|
320
325
|
</UButton>
|
|
321
326
|
<UButton
|
|
322
327
|
size="xs"
|
|
@@ -324,7 +329,7 @@ const errorPrefix = (index) => `${props.descriptor.key}.${index}`;
|
|
|
324
329
|
color="neutral"
|
|
325
330
|
@click="clearSelection"
|
|
326
331
|
>
|
|
327
|
-
|
|
332
|
+
{{ t("mapo.clear") }}
|
|
328
333
|
</UButton>
|
|
329
334
|
<UButton
|
|
330
335
|
size="xs"
|
|
@@ -333,11 +338,16 @@ const errorPrefix = (index) => `${props.descriptor.key}.${index}`;
|
|
|
333
338
|
icon="i-lucide-copy"
|
|
334
339
|
:disabled="remainingSlots() <= 0"
|
|
335
340
|
:title="
|
|
336
|
-
remainingSlots() < selectionCount ?
|
|
341
|
+
remainingSlots() < selectionCount ? t('mapo.repeater.duplicateLimited', {
|
|
342
|
+
slots: remainingSlots(),
|
|
343
|
+
count: selectionCount
|
|
344
|
+
}) : t('mapo.repeater.duplicateSelected')
|
|
337
345
|
"
|
|
338
346
|
@click="bulkDuplicate"
|
|
339
347
|
>
|
|
340
|
-
|
|
348
|
+
{{ t("mapo.duplicate") }} ({{
|
|
349
|
+
Math.min(selectionCount, remainingSlots())
|
|
350
|
+
}})
|
|
341
351
|
</UButton>
|
|
342
352
|
<UButton
|
|
343
353
|
size="xs"
|
|
@@ -346,7 +356,7 @@ const errorPrefix = (index) => `${props.descriptor.key}.${index}`;
|
|
|
346
356
|
icon="i-lucide-arrow-up"
|
|
347
357
|
@click="bulkMoveToTop"
|
|
348
358
|
>
|
|
349
|
-
|
|
359
|
+
{{ t("mapo.repeater.moveToTop") }}
|
|
350
360
|
</UButton>
|
|
351
361
|
<UButton
|
|
352
362
|
size="xs"
|
|
@@ -356,7 +366,7 @@ const errorPrefix = (index) => `${props.descriptor.key}.${index}`;
|
|
|
356
366
|
:disabled="!canDelete"
|
|
357
367
|
@click="bulkDelete"
|
|
358
368
|
>
|
|
359
|
-
|
|
369
|
+
{{ t("mapo.delete") }} ({{ selectionCount }})
|
|
360
370
|
</UButton>
|
|
361
371
|
</div>
|
|
362
372
|
</div>
|
|
@@ -439,7 +449,7 @@ const errorPrefix = (index) => `${props.descriptor.key}.${index}`;
|
|
|
439
449
|
v-if="items.length === 0"
|
|
440
450
|
class="rounded border border-dashed border-gray-300 py-8 text-center text-sm text-gray-400"
|
|
441
451
|
>
|
|
442
|
-
|
|
452
|
+
{{ t("mapo.repeater.empty") }}
|
|
443
453
|
</div>
|
|
444
454
|
</div>
|
|
445
455
|
</template>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapoRepeater.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoRepeater.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MapoRepeater.vue.d.ts","sourceRoot":"","sources":["../../../../src/runtime/components/fields/MapoRepeater.vue"],"names":[],"mappings":"AAujBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAI/D,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAgjCF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|