138 lines
3.6 KiB
Vue
138 lines
3.6 KiB
Vue
<template>
|
|
<div v-bind="$attrs">
|
|
<q-field v-model="selectedField" :label="displayName" labelColor="primary" :clearable="isSelected" stack-label
|
|
:bottom-slots="!isSelected"
|
|
:rules="rulesExp"
|
|
>
|
|
<template v-slot:control>
|
|
<q-chip color="primary" text-color="white" v-if="isSelected">
|
|
{{ selectedField.name }}
|
|
</q-chip>
|
|
</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>
|
|
<show-dialog v-model:visible="show" name="フィールド一覧" @close="closeDg" min-width="400px">
|
|
<template v-slot:toolbar>
|
|
<q-input dense debounce="300" v-model="filter" placeholder="検索" clearable>
|
|
<template v-slot:before>
|
|
<q-icon name="search" />
|
|
</template>
|
|
</q-input>
|
|
</template>
|
|
<field-select ref="appDg" name="フィールド" :type="selectType" :appId="store.appInfo?.appId" :selectedFields="selectedFields" :fieldTypes="fieldTypes" :filter="filter"></field-select>
|
|
</show-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { defineComponent, ref, watchEffect, computed } from 'vue';
|
|
import ShowDialog from '../ShowDialog.vue';
|
|
import FieldSelect from '../FieldSelect.vue';
|
|
import { useFlowEditorStore } from 'stores/flowEditor';
|
|
interface IField {
|
|
name: string,
|
|
code: string,
|
|
type: string
|
|
}
|
|
export default defineComponent({
|
|
name: 'FieldInput',
|
|
inheritAttrs:false,
|
|
components: {
|
|
ShowDialog,
|
|
FieldSelect,
|
|
},
|
|
props: {
|
|
displayName: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
name: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
placeholder: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
selectType:{
|
|
type:String,
|
|
default:'single'
|
|
},
|
|
fieldTypes:{
|
|
type:Array,
|
|
default:()=>[]
|
|
},
|
|
hint: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
modelValue: {
|
|
type: Object,
|
|
default: null
|
|
},
|
|
//例:[val=>!!val ||'入力してください']
|
|
rules: {
|
|
type: String,
|
|
default: undefined
|
|
},
|
|
required: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
requiredMessage: {
|
|
type: String,
|
|
default: ''
|
|
}
|
|
},
|
|
|
|
setup(props, { emit }) {
|
|
const appDg = ref();
|
|
const show = ref(false);
|
|
const selectedField = ref(props.modelValue);
|
|
const selectedFields =computed(()=>!selectedField.value?[]: [selectedField.value]);
|
|
const store = useFlowEditorStore();
|
|
const isSelected = computed(() => {
|
|
return selectedField.value !== null && typeof selectedField.value === 'object' && ('name' in selectedField.value)
|
|
});
|
|
//ルール設定
|
|
const customExp = props.rules === undefined ? [] : eval(props.rules);
|
|
const errmsg = props.requiredMessage?props.requiredMessage:`${props.displayName}が必須です。`;
|
|
const requiredExp = props.required ? [((val: any) => (!!val && typeof val==='object' && !!val.name) || errmsg)] : [];
|
|
const rulesExp = [...requiredExp, ...customExp];
|
|
|
|
const showDg = () => {
|
|
show.value = true;
|
|
};
|
|
|
|
const closeDg = (val: string) => {
|
|
if (val == 'OK') {
|
|
selectedField.value = appDg.value.selected[0];
|
|
}
|
|
};
|
|
|
|
watchEffect(() => {
|
|
emit('update:modelValue', selectedField.value);
|
|
});
|
|
|
|
return {
|
|
store,
|
|
appDg,
|
|
show,
|
|
showDg,
|
|
closeDg,
|
|
selectedField,
|
|
isSelected,
|
|
filter:ref(''),
|
|
selectedFields,
|
|
rulesExp
|
|
};
|
|
}
|
|
});
|
|
</script>
|