Importer update add support for meta data and multiple inserts for some entities like addresses and phones, updated other things

This commit is contained in:
Simon Pocrnjič
2025-10-09 22:28:48 +02:00
parent c8029c9eb0
commit 0598261cdc
27 changed files with 2517 additions and 375 deletions
+134 -2
View File
@@ -55,6 +55,7 @@ const bulkGlobal = ref({
default_field: "",
transform: "",
apply_mode: "both",
group: "",
});
const unassigned = computed(() =>
(props.template.mappings || []).filter((m) => !m.target_field)
@@ -104,6 +105,21 @@ function saveUnassigned(m) {
} else {
m.target_field = null;
}
if (st.group) {
m.options = m.options && typeof m.options === "object" ? m.options : {};
m.options.group = st.group;
}
// If targeting any .meta field, allow setting options.key via UI
if (st.field === "meta") {
if (st.metaKey && String(st.metaKey).trim() !== "") {
m.options = m.options && typeof m.options === "object" ? m.options : {};
m.options.key = String(st.metaKey).trim();
}
if (st.metaType && String(st.metaType).trim() !== "") {
m.options = m.options && typeof m.options === "object" ? m.options : {};
m.options.type = String(st.metaType).trim();
}
}
updateMapping(m);
}
@@ -141,13 +157,22 @@ function addRow(entity) {
const row = newRows.value[entity];
if (!row || !row.source || !row.field) return;
const target_field = `${entity}.${row.field}`;
const opts = {};
if (row.group) opts.group = row.group;
if (entity === "contract" && row.field === "meta" && row.metaKey) {
opts.key = String(row.metaKey).trim();
}
const payload = {
source_column: row.source,
target_field,
transform: row.transform || null,
apply_mode: row.apply_mode || "both",
options: Object.keys(opts).length ? opts : null,
position: (props.template.mappings?.length || 0) + 1,
};
if (row.field === "meta" && row.metaType) {
opts.type = String(row.metaType).trim();
}
useForm(payload).post(
route("importTemplates.mappings.add", { template: props.template.uuid }),
{
@@ -165,6 +190,7 @@ function updateMapping(m) {
target_field: m.target_field,
transform: m.transform,
apply_mode: m.apply_mode,
options: m.options || null,
position: m.position,
};
useForm(payload).put(
@@ -602,6 +628,15 @@ watch(
<option value="update">update</option>
</select>
</div>
<div>
<label class="block text-xs text-indigo-900">Group (za vse)</label>
<input
v-model="bulkGlobal.group"
type="text"
class="mt-1 w-full border rounded p-2"
placeholder="1, 2, home, work"
/>
</div>
</div>
<div class="mt-3">
<button
@@ -614,6 +649,7 @@ watch(
default_field: bulkGlobal.default_field || null,
transform: bulkGlobal.transform || null,
apply_mode: bulkGlobal.apply_mode || 'both',
group: bulkGlobal.group || '',
}).post(
route('importTemplates.mappings.bulk', {
template: props.template.uuid,
@@ -626,6 +662,7 @@ watch(
bulkGlobal.default_field = '';
bulkGlobal.transform = '';
bulkGlobal.apply_mode = 'both';
bulkGlobal.group = '';
},
}
);
@@ -710,6 +747,39 @@ watch(
</option>
</select>
</div>
<div>
<label class="block text-xs text-gray-600">Group</label>
<input
v-model="(unassignedState[m.id] ||= {}).group"
class="mt-1 w-full border rounded p-2"
type="text"
placeholder="1, 2, home, work"
/>
</div>
<div v-if="(unassignedState[m.id] || {}).field === 'meta'">
<label class="block text-xs text-gray-600">Meta key</label>
<input
v-model="(unassignedState[m.id] ||= {}).metaKey"
class="mt-1 w-full border rounded p-2"
type="text"
placeholder="npr.: note, category"
/>
<label class="block text-xs text-gray-600 mt-2">Meta type</label>
<select
v-model="(unassignedState[m.id] ||= {}).metaType"
class="mt-1 w-full border rounded p-2"
>
<option value="">(auto/string)</option>
<option value="string">string</option>
<option value="number">number</option>
<option value="date">date</option>
<option value="boolean">boolean</option>
</select>
<p class="text-[11px] text-gray-500 mt-1">
Če ne določiš, lahko uporabiš tudi zapis cilja kot
<code>contract.meta[key]</code>.
</p>
</div>
<div>
<label class="block text-xs text-gray-600">Transform</label>
<select v-model="m.transform" class="mt-1 w-full border rounded p-2">
@@ -800,7 +870,7 @@ watch(
class="flex items-center justify-between p-2 border rounded gap-3"
>
<div
class="grid grid-cols-1 sm:grid-cols-5 gap-2 flex-1 items-center"
class="grid grid-cols-1 sm:grid-cols-6 gap-2 flex-1 items-center"
>
<input
v-model="m.source_column"
@@ -822,6 +892,28 @@ watch(
<option value="update">update</option>
<option value="keyref">keyref (use as lookup key)</option>
</select>
<input
v-model="(m.options ||= {}).group"
class="border rounded p-2 text-sm"
placeholder="Group"
/>
<input
v-if="/^(contracts?\.meta)(\.|\[|$)/.test(m.target_field || '')"
v-model="(m.options ||= {}).key"
class="border rounded p-2 text-sm"
placeholder="Meta key"
/>
<select
v-if="/^(contracts?\.meta)(\.|\[|$)/.test(m.target_field || '')"
v-model="(m.options ||= {}).type"
class="border rounded p-2 text-sm"
>
<option value="">(auto/string)</option>
<option value="string">string</option>
<option value="number">number</option>
<option value="date">date</option>
<option value="boolean">boolean</option>
</select>
<div class="flex items-center gap-2">
<button
class="px-2 py-1 text-xs border rounded"
@@ -859,7 +951,7 @@ watch(
<!-- Add new mapping row -->
<div class="p-3 bg-gray-50 rounded border">
<div class="grid grid-cols-1 sm:grid-cols-5 gap-2 items-end">
<div class="grid grid-cols-1 sm:grid-cols-6 gap-2 items-end">
<div>
<label class="block text-xs text-gray-600"
>Source column (ne-dodeljene)</label
@@ -919,6 +1011,35 @@ watch(
<option value="keyref">keyref (use as lookup key)</option>
</select>
</div>
<div>
<label class="block text-xs text-gray-600">Group</label>
<input
v-model="(newRows[entity] ||= {}).group"
class="mt-1 w-full border rounded p-2"
type="text"
placeholder="1, 2, home, work"
/>
</div>
<div v-if="(newRows[entity] || {}).field === 'meta'">
<label class="block text-xs text-gray-600">Meta key</label>
<input
v-model="(newRows[entity] ||= {}).metaKey"
class="mt-1 w-full border rounded p-2"
type="text"
placeholder="npr.: note, category"
/>
<label class="block text-xs text-gray-600 mt-2">Meta type</label>
<select
v-model="(newRows[entity] ||= {}).metaType"
class="mt-1 w-full border rounded p-2"
>
<option value="">(auto/string)</option>
<option value="string">string</option>
<option value="number">number</option>
<option value="date">date</option>
<option value="boolean">boolean</option>
</select>
</div>
<div class="sm:col-span-1">
<button
@click.prevent="addRow(entity)"
@@ -992,6 +1113,15 @@ watch(
<option value="keyref">keyref (use as lookup key)</option>
</select>
</div>
<div>
<label class="block text-xs text-gray-600">Group (za vse)</label>
<input
v-model="(bulkRows[entity] ||= {}).group"
class="mt-1 w-full border rounded p-2"
type="text"
placeholder="1, 2, home, work"
/>
</div>
</div>
<div class="mt-2">
<button
@@ -1006,6 +1136,7 @@ watch(
default_field: b.default_field || null,
transform: b.transform || null,
apply_mode: b.apply_mode || 'both',
group: b.group || '',
}).post(
route('importTemplates.mappings.bulk', {
template: props.template.uuid,
@@ -1051,6 +1182,7 @@ watch(
target_field: `${s.entity}.${s.field}`,
transform: b.transform || null,
apply_mode: b.apply_mode || 'both',
options: b.group ? { group: b.group } : null,
position: (props.template.mappings?.length || 0) + 1,
};
useForm(payload).post(