166 lines
4.2 KiB
Vue
166 lines
4.2 KiB
Vue
<template>
|
|
<div class="q-my-md" v-bind="$attrs">
|
|
<q-field v-model="selectedField" :label="displayName" labelColor="primary" :clearable="isSelected" stack-label
|
|
:rules="rulesExp" lazy-rules="ondemand" @clear="clear" ref="fieldRef">
|
|
<template v-slot:control>
|
|
{{ isSelected ? selectedField.app?.name : "(未選択)" }}
|
|
</template>
|
|
<template v-slot:hint v-if="!isSelected">
|
|
{{ placeholder }}
|
|
</template>
|
|
<template v-slot:append>
|
|
<q-icon name="search" class="cursor-pointer" color="primary" @click="showDg" />
|
|
</template>
|
|
</q-field>
|
|
<div v-if="selectedField.fields && selectedField.fields.length > 0">
|
|
<q-list bordered>
|
|
<q-virtual-scroll style="max-height: 160px;" :items="selectedField.fields" separator v-slot="{ item, index }">
|
|
<q-item :key="index" dense clickable>
|
|
<q-item-section>
|
|
<q-item-label>
|
|
{{ item.label }}
|
|
</q-item-label>
|
|
</q-item-section>
|
|
<q-item-section side>
|
|
<q-btn round flat size="sm" icon="clear" @click="removeField(index)" />
|
|
</q-item-section>
|
|
</q-item>
|
|
</q-virtual-scroll>
|
|
</q-list>
|
|
</div>
|
|
<show-dialog v-model:visible="show" name="フィールド一覧" @close="closeAFBox">
|
|
<AppFieldSelectBox v-model:selectedField="selectedField" :selectType="selectType" ref="afBox"
|
|
:fieldTypes="fieldTypes" />
|
|
</show-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { computed, defineComponent, ref, watchEffect } from 'vue';
|
|
import AppFieldSelectBox from '../AppFieldSelectBox.vue';
|
|
import ShowDialog from '../ShowDialog.vue';
|
|
import { useFlowEditorStore } from 'stores/flowEditor';
|
|
|
|
export interface IApp {
|
|
id: string,
|
|
name: string
|
|
}
|
|
export interface IField {
|
|
name: string,
|
|
code: string,
|
|
type: string,
|
|
label?: string
|
|
}
|
|
|
|
export interface IAppFields {
|
|
app?: IApp,
|
|
fields: IField[]
|
|
}
|
|
|
|
export default defineComponent({
|
|
inheritAttrs: false,
|
|
name: 'AppFieldSelect2',
|
|
components: {
|
|
ShowDialog,
|
|
AppFieldSelectBox
|
|
},
|
|
props: {
|
|
displayName: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
name: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
placeholder: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
modelValue: {
|
|
type: Object,
|
|
default: null
|
|
},
|
|
selectType: {
|
|
type: String,
|
|
default: 'single'
|
|
},
|
|
fieldTypes: {
|
|
type: Array,
|
|
default: () => []
|
|
},
|
|
//例:[val=>!!val ||'入力してください']
|
|
rules: {
|
|
type: String,
|
|
default: undefined
|
|
},
|
|
required: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
requiredMessage: {
|
|
type: String,
|
|
default: ''
|
|
}
|
|
},
|
|
setup(props, { emit }) {
|
|
const show = ref(false);
|
|
const afBox = ref();
|
|
const fieldRef = ref();
|
|
const selectedField = ref<IAppFields>({
|
|
app: undefined,
|
|
fields: []
|
|
});
|
|
if (props.modelValue && 'app' in props.modelValue && 'fields' in props.modelValue) {
|
|
selectedField.value = props.modelValue as IAppFields;
|
|
}
|
|
const store = useFlowEditorStore();
|
|
|
|
const clear = () => {
|
|
selectedField.value = {
|
|
fields: []
|
|
};
|
|
}
|
|
|
|
const removeField = (index: number) => {
|
|
selectedField.value.fields.splice(index, 1);
|
|
}
|
|
|
|
const closeAFBox = (val: string) => {
|
|
if (val == 'OK') {
|
|
console.log(afBox.value);
|
|
selectedField.value = afBox.value.selField;
|
|
fieldRef.value.validate();
|
|
}
|
|
};
|
|
|
|
const isSelected = computed(() => {
|
|
return !!selectedField.value.app
|
|
});
|
|
|
|
const customExp = props.rules === undefined ? [] : eval(props.rules);
|
|
const errmsg = props.requiredMessage?props.requiredMessage:`${props.displayName}が必須です。`;
|
|
const requiredExp = props.required ? [((val: any) => (val && val.app && val.fields && val.fields.length > 0) || errmsg)] : [];
|
|
const rulesExp = [...requiredExp, ...customExp];
|
|
|
|
watchEffect(() => {
|
|
emit('update:modelValue', selectedField.value);
|
|
});
|
|
|
|
return {
|
|
store,
|
|
afBox,
|
|
show,
|
|
showDg: () => { show.value = true },
|
|
selectedField,
|
|
clear,
|
|
removeField,
|
|
closeAFBox,
|
|
isSelected,
|
|
rulesExp,
|
|
fieldRef
|
|
};
|
|
}
|
|
});
|
|
</script>
|