fix multi input

This commit is contained in:
2025-02-08 09:50:48 +08:00
parent 2023ca601f
commit 88343bbfdf
8 changed files with 145 additions and 201 deletions

View File

@@ -7,7 +7,6 @@ export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
CellInput: typeof import('./src/components/basic/conditions/CellInput.vue')['default']
Config: typeof import('./src/components/Config.vue')['default']
ErrorDialog: typeof import('./src/components/basic/ErrorDialog.vue')['default']
PluginDropdown: typeof import('./src/components/basic/PluginDropdown.vue')['default']

View File

@@ -24,8 +24,7 @@
</plugin-row>
<plugin-row class="flex-row">
<plugin-label label="絞込条件" />
<plugin-table-condition-row :modelValue="table.whereConditions" :table="table"
@update:modelValue="(newData:any) => table.whereConditions = newData"/>
<plugin-table-condition-row :modelValue="table.whereConditions" />
</plugin-row>
</div>
<div class="table-action-area">

View File

@@ -1,8 +1,5 @@
<template>
<kuc-table className='plugin-kuc-table condition-table'
:columns="columns"
:data="modelValue"
/>
<kuc-table className="plugin-kuc-table condition-table" :columns="columns" :data="modelValue" />
</template>
<script setup lang="ts">
@@ -15,30 +12,25 @@ import TableConditionValue from './conditions/TableConditionValue.vue';
const props = defineProps<{
modelValue: WhereCondition[];
table:JoinTable;
}>();
const emit = defineEmits<{
(event: 'update:modelValue', value: WhereCondition[]): void;
}>();
const savedData = inject<SavedData>('savedData') as SavedData;
const cachedData = inject<CachedData>('cachedData') as CachedData;
const selectedAppData = inject<CachedSelectedAppData>('selectedAppData') as CachedSelectedAppData;
// const table = computed(() => selectedAppData.table.table);
const canSave = inject<(canSave: boolean) => void>('canSave') as (canSave: boolean) => void;
watch(
()=>props.modelValue,
(newValue,oldValue)=>{
console.log(newValue);
console.log(oldValue);
},{
deep:true,
immediate:true
}
)
() => props.modelValue,
(newValue, oldValue) => {
console.log(newValue);
console.log(oldValue);
},
{
deep: true,
immediate: true,
},
);
const columns = reactive([
{
@@ -63,10 +55,10 @@ const columns = reactive([
dataList: props.modelValue,
id: rowData.id,
'onUpdate:modelValue': (data) => {
const obj = (data.obj as WhereCondition);
const obj = data.obj as WhereCondition;
if (obj) {
obj.field = data.value;
obj.condition = '',
obj.condition = '';
obj.data = '';
}
},
@@ -85,8 +77,8 @@ const columns = reactive([
selectedAppData,
id: rowData.id,
whereConditions: props.modelValue,
'onUpdate:modelValue': ({obj, value}) => {
obj && (obj.condition = value);
'onUpdate:modelValue': ({ obj, value }) => {
obj && (obj.condition = value);
},
});
render(vnode, container);
@@ -104,14 +96,8 @@ const columns = reactive([
canSave,
id: rowData.id,
whereConditions: props.modelValue,
'onUpdate:modelValue': ({obj, value}) => {
if(obj){
obj.data = value;
const newData = props.modelValue.map((item) =>
item.id === obj.id ? { ...item, data: value } : item
);
emit('update:modelValue', newData);
}
'onUpdate:modelValue': ({ obj, value }) => {
obj && (obj.data = value);
},
});
render(vnode, container);
@@ -119,5 +105,4 @@ const columns = reactive([
},
},
]);
</script>

View File

@@ -1,22 +0,0 @@
<template>
<kuc-text className="kuc-text-input" :value="modelValue" @change="updateValue" />
</template>
<script setup lang="ts">
import type { KucEvent } from '@/types/my-kintone';
import type { TextInputEventDetail } from 'kintone-ui-component';
import { defineProps, defineEmits, type Ref } from 'vue';
const props = defineProps<{
modelValue: string;
}>();
const emit = defineEmits<{
(e: 'update:modelValue', value: string): void;
}>();
const updateValue = ({ detail }: KucEvent<TextInputEventDetail>) => {
emit('update:modelValue', detail.value || '');
};
</script>

View File

@@ -27,29 +27,32 @@
:disabled="selectedAppData.loading == undefined ? false : selectedAppData.loading"
/>
<kuc-multi-choice
v-else-if="valueType === 'kuc-multichoice'"
:value="multiValue"
v-else-if="isMultiChoice"
:value="multiChoice"
:items="multiChoiceItems"
:requiredIcon="true"
@change="updateMultiValue"
@change="updateMultiChoice"
:disabled="selectedAppData.loading == undefined ? false : selectedAppData.loading"
/>
<table-condition-value-multi-input
v-else-if="valueType === 'multi-input'"
v-else-if="isMultiInput"
:value="multiInput"
@change="updateTableValue"
@change="updateMultiInput"
:disabled="selectedAppData.loading == undefined ? false : selectedAppData.loading"
/>
</template>
<script setup lang="ts">
import { getComponent } from '@/js/conditions';
import { getComponent, multiValueComponent } from '@/js/conditions';
import { getFieldObj, isStringArray, search } from '@/js/helper';
import { isType } from '@/js/kintone-rest-api-client';
import { isSelectType } from '@/js/mapping';
import type { CachedSelectedAppData, StringValue, WhereCondition } from '@/types/model';
import type { KucEvent } from '@/types/my-kintone';
import type { ComboboxChangeEventDetail, TextInputEventDetail, MultiChoiceChangeEventDetail } from 'kintone-ui-component';
import type {
ComboboxChangeEventDetail,
TextInputEventDetail,
MultiChoiceChangeEventDetail,
} from 'kintone-ui-component';
import { defineProps, defineEmits, computed, type Ref, inject, provide, ref, watch, watchEffect } from 'vue';
const props = defineProps<{
@@ -78,25 +81,6 @@ const placeholder = computed(() => {
return '';
});
const multiChoiceItems = computed(() => {
const field = getFieldObj(whereCondition.value?.field || '', props.selectedAppData.appFields, '');
const items = [{
label: '--',
value: '',
}];
if (field && isSelectType(field)) {
const opts = field.options;
const multiOpts = Object.values(opts).map((opt) => {
return {
label: opt.label,
value: opt.label,
};
});
items.push(...multiOpts);
}
return items;
});
const valueType = computed(() => {
const field = getFieldObj(whereCondition.value?.field || '', props.selectedAppData.appFields, '');
return getComponent(whereCondition.value?.condition || '', field);
@@ -115,36 +99,44 @@ const updateValue = (event: KucEvent<ComboboxChangeEventDetail | TextInputEventD
emit('update:modelValue', { obj: whereCondition.value, value: event.detail.value || '' });
};
const multiValue = ref(isStringArray(props.modelValue.value) ? props.modelValue.value : []);
// multi choice
const isMultiChoice = computed(() => valueType.value === multiValueComponent.multiChoice);
watch(
() => props.modelValue,
() => {
const field = getFieldObj(whereCondition.value?.field || '', props.selectedAppData.appFields, '');
const vType = valueType.value;
const moduleValue = props.modelValue.value;
if (field && isSelectType(field) && vType === 'kuc-multichoice') {
multiValue.value = isStringArray(moduleValue) ? moduleValue : [];
}
},
);
const multiInput = ref(isStringArray(props.modelValue.value) ? (props.modelValue.value as string[]) : ['', '']);
watchEffect(() => {
const vType = valueType.value;
const moduleValue = props.modelValue.value;
if (vType === 'multi-input') {
multiInput.value = isStringArray(moduleValue) ? (moduleValue as string[]) : ['', ''];
const multiChoice = computed(() => {
if (!isMultiChoice.value) {
return props.modelValue.value;
}
return isStringArray(props.modelValue.value) ? props.modelValue.value : [];
});
const updateMultiValue = (event: KucEvent<MultiChoiceChangeEventDetail>) => {
const multiChoiceItems = computed(() => {
if (!isMultiChoice.value) {
return [];
}
const field = getFieldObj(whereCondition.value?.field || '', props.selectedAppData.appFields, '');
const items = [{ label: '--', value: '' }];
if (field && isSelectType(field)) {
const multiOpts = Object.values(field.options).map((opt) => ({ label: opt.label, value: opt.label }));
items.push(...multiOpts);
}
return items;
});
const updateMultiChoice = (event: KucEvent<MultiChoiceChangeEventDetail>) => {
emit('update:modelValue', { obj: whereCondition.value, value: event.detail.value || [] });
};
const updateTableValue = (event: KucEvent<string[]>) => {
let value = event.detail || ['', ''];
multiInput.value = value;
emit('update:modelValue', { obj: whereCondition.value, value: value });
// multi input
const isMultiInput = computed(() => valueType.value === multiValueComponent.multiInput);
const multiInput = computed(() => {
if (!isMultiInput.value) {
return props.modelValue.value as string[];
}
return isStringArray(props.modelValue.value) ? props.modelValue.value as string[] : ['', ''];
});
const updateMultiInput = (event: KucEvent<string[]>) => {
emit('update:modelValue', { obj: whereCondition.value, value: event.detail || ['', ''] });
};
</script>

View File

@@ -1,82 +1,45 @@
<template>
<kuc-table
className="table-option"
:columns="columns"
:data="data"
@change.stop="updateValue"
:headerVisible="false"
/>
</template>
<template>
<!-- <kuc-table className='table-option'
:columns="columns"
:data="data"
@change="updateValue"
:headerVisible="false"
ref="table"/> -->
<div ref="tableContainer"></div>
</template>
<script setup lang="ts">
import type { KucEvent } from '@/types/my-kintone';
import { Table, Text, type TableChangeEventDetail } from 'kintone-ui-component';
import { defineProps, defineEmits, computed, ref, watch, inject, type Ref, onMounted, onUnmounted } from 'vue';
interface MuiltItem{
value:string
}
<script setup lang="ts">
import type { KucEvent } from '@/types/my-kintone';
import { Table, Text, type TableChangeEventDetail } from 'kintone-ui-component';
import { defineProps, defineEmits, ref, watch, h, render, reactive } from 'vue';
interface MultiItem {
value: string;
}
const props = defineProps<{
value: string[];
}>();
const props = defineProps<{
value: string[];
}>();
const tableContainer = ref<HTMLDivElement>();
const table = ref<Table | null>(null);
const data = ref<MuiltItem[]>((props.value || ['', '']).map(x => ({ value: x })));
watch(
() => props.value,
(newValue)=>{
data.value =(newValue || ['', '']).map((x) => ({ value: x }));
if (table.value) {
table.value.data = data.value; // 更新 Table 数据
}
const data = ref<MultiItem[]>((props.value || ['', '']).map((x) => ({ value: x })));
const columns = reactive([
{
title: '',
field: 'value',
render: (cellData: string) => {
return new Text({ value: cellData });
},
{
deep:true,immediate:true
});
const emit = defineEmits<{
(e: 'change', data: KucEvent<string[]>): void;
(e: 'update:modelValue', value: string[]): void;
}>();
},
]);
const emit = defineEmits<{
(e: 'change', data: KucEvent<string[]>): void;
}>();
const updateValue=(event:KucEvent<TableChangeEventDetail<MuiltItem>>)=>{
data.value = event.detail.data||[{value:''},{value:''}];
if (table.value) {
table.value.data = data.value;
}
const muiltData = event.detail.data ? event.detail.data.map(x=>x.value) :[];
emit('change', { detail: [...muiltData] });
// emit('update:modelValue', [...muiltData] );
// emit('change', muiltData);
}
const updateValue = (event: KucEvent<TableChangeEventDetail<MultiItem>>) => {
data.value = event.detail.data || [{ value: '' }, { value: '' }];
const multiData = event.detail.data ? event.detail.data.map((x) => x.value) : [];
emit('change', { detail: [...multiData] });
};
onMounted(()=>{
table.value = new Table({
className:'table-option',
headerVisible:false,
actionButton:true,
columns:[
{
field:"value",
render:(cellData:any)=>{
const text = new Text({value:cellData});
return text;
}
},
],
data:data.value
});
table.value.addEventListener('change', updateValue);
tableContainer.value?.appendChild(table.value);
});
onUnmounted(() => {
if (table.value) {
table.value.removeEventListener('change', updateValue);
}
});
</script>
</script>

View File

@@ -62,11 +62,14 @@
border-right: 1px solid #e3e7e8;
padding-top: 24px;
}
.table-area {
border-bottom: none;
}
.footer-row {
padding: 24px 0;
margin-bottom: 32px;
text-align: right;
border-top: none;
/* border-top: none; */
}
/* 底部按钮空间 */
@@ -141,10 +144,14 @@
.plugin-kuc-table > table > tbody > tr > td:first-child {
border-left-color: #e3e7e8;
}
.plugin-kuc-table > table > tbody > tr > .kuc-table-1-18-0__table__body__row__action {
.plugin-kuc-table > table > tbody > tr > td[class$="table__body__row__action"] {
height: 55px;
align-items: center;
}
.table-option > table > tbody > tr > td[class$="table__body__row__action"] {
height: 40px;
align-items: center;
}
.plugin-kuc-table:not(.condition-table) > table > tbody > tr > td:nth-child(2) {
--kuc-table-header-1-width: 30px;
text-align: center;

View File

@@ -14,24 +14,32 @@ type ConditionItem = {
};
export const conditionList: ConditionItem[] = [
{ value: '=', label: '=(等しい)', type: (field) => dateTimeComponent[field.type] || 'input' },
{ value: '!=', label: '≠ (等しくない)', type: (field) => dateTimeComponent[field.type] || 'input' },
{ value: '=', label: '=(等しい)', type: (field) => dateTimeComponentMap[field.type] || 'input' },
{ value: '!=', label: '≠ (等しくない)', type: (field) => dateTimeComponentMap[field.type] || 'input' },
{
value: '<=',
label: (field) => (isDateTimeType(field) ? '≦ (以前)' : '≦ (以下)'),
type: (field) => dateTimeComponent[field.type] || 'input',
type: (field) => dateTimeComponentMap[field.type] || 'input',
},
{ value: '<', label: '< (より前)', type: (field) => dateTimeComponent[field.type] || 'input' },
{ value: '<', label: '< (より前)', type: (field) => dateTimeComponentMap[field.type] || 'input' },
{
value: '>=',
label: (field) => (isDateTimeType(field) ? '≧ (以降)' : '≧ (以上)'),
type: (field) => dateTimeComponent[field.type] || 'input',
type: (field) => dateTimeComponentMap[field.type] || 'input',
},
{ value: '>', label: '> (より後)', type: (field) => dateTimeComponent[field.type] || 'input' },
{ value: '>', label: '> (より後)', type: (field) => dateTimeComponentMap[field.type] || 'input' },
{ value: 'like', label: '次のキーワードを含む', type: 'input' },
{ value: 'not like', label: '次のキーワードを含まない', type: 'input' },
{ value: 'in', label: '次のいずれかを含む', type: (field) => MultiChoiceComponent[field.type] || 'input' },
{ value: 'not in', label: '次のいずれも含まない', type: (field) => MultiChoiceComponent[field.type] || 'input' },
{
value: 'in',
label: (field) => (isMultiInputType(field) ? '次のいずれかと等しい' : '次のいずれかを含む'),
type: (field) => multiValueComponentMap[field.type] || 'input',
},
{
value: 'not in',
label: (field) => (isMultiInputType(field) ? '次のいずれとも等しくない' : '次のいずれも含まない'),
type: (field) => multiValueComponentMap[field.type] || 'input',
},
];
// search from conditionList
@@ -89,21 +97,35 @@ export const getAvailableCondition = (fieldCode: string, fieldsInfo: FieldsInfo,
});
};
const component = {
input: 'kuc-text',
select: 'kuc-combobox',
const dateTimeComponent = {
time: 'kuc-time',
date: 'date',
datetime: 'datetime',
} as const;
export const multiValueComponent = {
multiChoice: 'kuc-multichoice',
multiInput: 'multi-input',
} as const;
const component = {
input: 'kuc-text',
select: 'kuc-combobox',
...dateTimeComponent,
...multiValueComponent,
} as const;
export type ComponentType = keyof typeof component;
const isDateTimeType = (field: OneOf) => {
return field.type in dateTimeComponentMap;
};
export const isDateTimeType = (field: OneOf) => {
return field.type in dateTimeComponent;
const isMultiInputType = (field: OneOf) => {
return multiValueComponentMap[field.type] === 'multiInput';
};
const dateTimeComponent: Partial<Record<FieldType, ComponentType>> = {
const dateTimeComponentMap: Partial<Record<FieldType, keyof typeof dateTimeComponent>> = {
TIME: 'time',
DATE: 'date',
DATETIME: 'datetime',
@@ -111,7 +133,7 @@ const dateTimeComponent: Partial<Record<FieldType, ComponentType>> = {
UPDATED_TIME: 'datetime',
};
const MultiChoiceComponent: Partial<Record<FieldType, ComponentType>> = {
const multiValueComponentMap: Partial<Record<FieldType, keyof typeof multiValueComponent>> = {
CHECK_BOX: 'multiChoice',
DROP_DOWN: 'multiChoice',
RADIO_BUTTON: 'multiChoice',
@@ -120,7 +142,6 @@ const MultiChoiceComponent: Partial<Record<FieldType, ComponentType>> = {
LINK: 'multiInput',
};
export type ComponentType = keyof typeof component;
export const getComponent = (value: ConditionValue, fieldObj: OneOf) => {
if (!value || !fieldObj) return;
const condition = conditionMap[value].type;