ユーザーが手動でフィールドリストを追加または削除する必要はなくなり、プログラムが自動的にアプリのすべてのフィールドに対してリストを作成します。

This commit is contained in:
Mouriya
2024-06-17 03:18:52 +09:00
parent e2a625ba12
commit 0e8d1957a3

View File

@@ -20,41 +20,48 @@
<div class="q-mx-md"> <div class="q-mx-md">
<div class="row q-col-gutter-x-xs flex-center"> <div class="row q-col-gutter-x-xs flex-center">
<div class="col-5"> <div class="col-6">
<div class="q-mx-xs">ソース</div> <div class="q-mx-xs">ソース</div>
</div> </div>
<div class="col-1"> <!-- <div class="col-1">
</div> </div> -->
<div class="col-5"> <div class="col-6">
<div class="q-mx-xs">目標</div> <div class="q-mx-xs">目標</div>
</div> </div>
<div class="col-1"><q-btn flat round dense icon="add" size="sm" @click="addMappingObject" /> <!-- <div class="col-1"><q-btn flat round dense icon="add" size="sm" @click="addMappingObject" /> -->
<!-- </div> -->
</div> </div>
</div> <q-virtual-scroll style="max-height: 75vh;" :items="mappingProps" separator v-slot="{ item, index }">
<div class="q-my-sm" v-for="(item, index) in mappingProps" :key="item.id"> <!-- <div class="q-my-sm" v-for="(item, index) in mappingProps" :key="item.id"> -->
<div class="row q-col-gutter-x-xs flex-center"> <div class="row q-my-md q-col-gutter-x-md flex-center">
<div class="col-5"> <div class="col-6">
<ConditionObject :config="config" v-model="item.from" /> <ConditionObject :config="config" v-model="item.from" />
</div> </div>
<div class="col-1"> <!-- <div class="col-1">
</div> </div> -->
<div class="col-5"> <div class="col-6">
<q-field v-model="item.vName" type="text" outlined dense> <q-field v-model="item.vName" type="text" outlined dense>
<template v-slot:append> <!-- <template v-slot:append>
<q-icon name="search" class="cursor-pointer" <q-icon name="search" class="cursor-pointer"
@click="() => { mappingProps[index].to.isDialogVisible = true }" /> @click="() => { mappingProps[index].to.isDialogVisible = true }" />
</template> </template> -->
<template v-slot:control> <template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0" <div class="self-center full-width no-outline" tabindex="0"
v-if="item.to.app?.name && item.to.fields?.length > 0 && item.to.fields[0].label"> v-if="item.to.app?.name && item.to.fields?.length > 0 && item.to.fields[0].label">
{{ `${item.to.app?.name} : ${item.to.fields[0].label}` }} {{ `${item.to.fields[0].label}` }}
<q-tooltip>
<div>アプリ : {{ item.to.app.name }}</div>
<div>フィールドのコード : {{ item.to.fields[0].code }}</div>
<div>フィールドのタイプ : {{ item.to.fields[0].type }}</div>
<!-- <div>フィールドのタイプ : {{ item.to.fields[0] }}</div> -->
</q-tooltip>
</div> </div>
</template> </template>
</q-field> </q-field>
</div> </div>
<div class="col-1"> <!-- <div class="col-1">
<q-btn flat round dense icon="delete" size="sm" @click="() => deleteMappingObject(index)" /> <q-btn flat round dense icon="delete" size="sm" @click="() => deleteMappingObject(index)" />
</div> </div> -->
</div> </div>
<show-dialog v-model:visible="mappingProps[index].to.isDialogVisible" name="フィールド一覧" <show-dialog v-model:visible="mappingProps[index].to.isDialogVisible" name="フィールド一覧"
@@ -65,7 +72,8 @@
</FieldSelect> </FieldSelect>
<AppFieldSelectBox v-else v-model:selectedField="mappingProps[index].to" /> <AppFieldSelectBox v-else v-model:selectedField="mappingProps[index].to" />
</show-dialog> </show-dialog>
</div> <!-- </div> -->
</q-virtual-scroll>
</div> </div>
</show-dialog> </show-dialog>
</div> </div>
@@ -73,12 +81,13 @@
<script lang="ts"> <script lang="ts">
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import { computed, defineComponent, reactive, ref, watchEffect } from 'vue'; import { computed, defineComponent, watch, isRef, reactive, ref, watchEffect } from 'vue';
import ConditionObject from '../ConditionEditor/ConditionObject.vue'; import ConditionObject from '../ConditionEditor/ConditionObject.vue';
import ShowDialog from '../ShowDialog.vue'; import ShowDialog from '../ShowDialog.vue';
import AppFieldSelectBox from '../AppFieldSelectBox.vue'; import AppFieldSelectBox from '../AppFieldSelectBox.vue';
import FieldSelect from '../FieldSelect.vue'; import FieldSelect from '../FieldSelect.vue';
import IAppFields from './AppFieldSelect.vue'; import IAppFields from './AppFieldSelect.vue';
import { api } from 'boot/axios';
type Props = { type Props = {
props?: { props?: {
@@ -99,7 +108,6 @@ type ValueType = {
}; };
} }
const defaultMappingProp = () => ({ id: uuidv4(), from: {}, to: { app: {}, fields: [], isDialogVisible: false } });
export default defineComponent({ export default defineComponent({
name: 'DataMapping', name: 'DataMapping',
@@ -137,28 +145,69 @@ export default defineComponent({
}, },
setup(props, { emit }) { setup(props, { emit }) {
const source = props.context.find(element => element?.props?.name === 'sources')
const sourceApp = computed(() => source?.props?.modelValue?.app);
const sourceAppId = computed(() => sourceApp.value?.id);
const closeDg = () => { const closeDg = () => {
emit('update:modelValue', mappingProps emit('update:modelValue', mappingProps.value
); );
} }
const closeToDg = () => { const closeToDg = () => {
emit('update:modelValue', mappingProps emit('update:modelValue', mappingProps.value
); );
} }
const mappingProps: ValueType[] = props.modelValue const mappingProps = computed(() => props.modelValue ?? []);
? props.modelValue
: reactive([defaultMappingProp()]);
watch(() => sourceAppId.value, async (newId, oldId) => {
if (!newId) return;
const a = await api.get('api/v1/appfields', {
params: {
app: newId
}
}).then(res => {
return Object.values(res.data.properties)
.map(f => ({ name: f.label, objectType: 'field', ...f }))
.map(f => {
return {
id: uuidv4(),
from: {},
to: {
app: sourceApp.value,
fields: [f],
isDialogVisible: false
}
}
})
})
const modelValue = props.modelValue ?? [];
const deleteMappingObject = (index: number) => mappingProps.length === 1 if (modelValue.length === 0 || newId !== oldId) {
? mappingProps.splice(0, mappingProps.length, defaultMappingProp()) emit('update:modelValue', a);
: mappingProps.splice(index, 1); return;
}
const modelValueFieldNames = modelValue.map(item => item.to.fields[0].name);
const newFields = a.filter(field => !modelValueFieldNames.includes(field.to.fields[0].name));
const updatedModelValue = [...modelValue, ...newFields];
emit('update:modelValue', updatedModelValue);
})
console.log(mappingProps.value);
// const deleteMappingObject = (index: number) => mappingProps.length === 1
// ? mappingProps.splice(0, mappingProps.length, defaultMappingProp())
// : mappingProps.splice(index, 1);
const mappingObjectsInputDisplay = computed(() => const mappingObjectsInputDisplay = computed(() =>
mappingProps ? (mappingProps.value && Array.isArray(mappingProps.value)) ?
mappingProps mappingProps.value
.filter(item => item.from?.sharedText && item.to.fields?.length > 0) .filter(item => item.from?.sharedText && item.to.fields?.length > 0)
.map(item => { .map(item => {
return `field(${item.to.app?.id},${item.to.fields[0].label}) = ${item.from.sharedText} `; return `field(${item.to.app?.id},${item.to.fields[0].label}) = ${item.from.sharedText} `;
@@ -166,18 +215,14 @@ export default defineComponent({
: [] : []
); );
const source = props.context.find(element => element?.props?.name === 'sources')
const sourceApp = computed(() => source?.props?.modelValue?.app);
const sourceAppId = computed(() => sourceApp.value?.id);
const btnDisable = computed(() => props.onlySourceSelect ? !(source?.props?.modelValue?.app?.id) : false); const btnDisable = computed(() => props.onlySourceSelect ? !(source?.props?.modelValue?.app?.id) : false);
//集計処理方法 //集計処理方法
watchEffect(() => { watchEffect(() => {
emit('update:modelValue', mappingProps); emit('update:modelValue', mappingProps.value);
}); });
return { return {
uuidv4, uuidv4,
@@ -186,8 +231,8 @@ export default defineComponent({
toDgIsShow: ref(false), toDgIsShow: ref(false),
closeToDg, closeToDg,
mappingProps, mappingProps,
addMappingObject: () => mappingProps.push(defaultMappingProp()), // addMappingObject: () => mappingProps.push(defaultMappingProp()),
deleteMappingObject, // deleteMappingObject,
mappingObjectsInputDisplay, mappingObjectsInputDisplay,
sourceApp, sourceApp,
sourceAppId, sourceAppId,