fix bug for +/-

This commit is contained in:
2025-01-23 17:13:34 +08:00
parent 6bd86ae92c
commit 36a24ebdff
11 changed files with 146 additions and 62 deletions

View File

@@ -14,7 +14,7 @@ const props = withDefaults(
defineProps<{ defineProps<{
canAdd?: boolean; canAdd?: boolean;
canDelete?: boolean; canDelete?: boolean;
tableId: number; tableId: string;
}>(), }>(),
{ {
canAdd: true, canAdd: true,
@@ -25,7 +25,12 @@ const props = withDefaults(
const savedData = inject<SavedData>('savedData') as SavedData; const savedData = inject<SavedData>('savedData') as SavedData;
const onClick = (type: 'add' | 'remove') => { const onClick = (type: 'add' | 'remove') => {
if (type === 'add') { if (type === 'add') {
const currentIndex = savedData.joinTables.findIndex((t) => t.id === props.tableId);
if (currentIndex !== -1) {
savedData.joinTables.splice(currentIndex + 1, 0, createEmptyJoinTable());
} else {
savedData.joinTables.push(createEmptyJoinTable()); savedData.joinTables.push(createEmptyJoinTable());
}
} else if (savedData.joinTables.length > 1) { } else if (savedData.joinTables.length > 1) {
savedData.joinTables = savedData.joinTables.filter((t) => t.id !== props.tableId); savedData.joinTables = savedData.joinTables.filter((t) => t.id !== props.tableId);
} }

View File

@@ -16,15 +16,15 @@
</plugin-row> </plugin-row>
<plugin-row class="flex-row" v-if="isJoinConditionShown(table)"> <plugin-row class="flex-row" v-if="isJoinConditionShown(table)">
<plugin-label label="連結条件" /> <plugin-label label="連結条件" />
<plugin-table-connect-row connector="=" v-model="table.onConditions" /> <plugin-table-connect-row connector="=" :modelValue="table.onConditions" />
</plugin-row> </plugin-row>
<plugin-row class="flex-row"> <plugin-row class="flex-row">
<plugin-label label="取得フィールド" /> <plugin-label label="取得フィールド" />
<plugin-table-connect-row connector="→" v-model="table.fieldsMapping" /> <plugin-table-connect-row connector="→" :modelValue="table.fieldsMapping" />
</plugin-row> </plugin-row>
<plugin-row class="flex-row"> <plugin-row class="flex-row">
<plugin-label label="絞込条件" /> <plugin-label label="絞込条件" />
<plugin-table-condition-row v-model="table.whereConditions" /> <plugin-table-condition-row :modelValue="table.whereConditions"/>
</plugin-row> </plugin-row>
</div> </div>
<div class="table-action-area"> <div class="table-action-area">

View File

@@ -4,12 +4,13 @@
<script setup lang="ts"> <script setup lang="ts">
import type { CachedData, CachedSelectedAppData, SavedData, WhereCondition } from '@/types/model'; import type { CachedData, CachedSelectedAppData, SavedData, WhereCondition } from '@/types/model';
import { defineProps, inject, computed, render, h } from 'vue'; import { defineProps, inject, computed, render, h, reactive } from 'vue';
import TableCombobox from './TableCombobox.vue'; import TableCombobox from './TableCombobox.vue';
import { getFieldsDropdownItems } from '@/js/helper'; import { generateId, getFieldsDropdownItems, search } from '@/js/helper';
import type { ConditionValue } from '@/js/conditions'; import type { ConditionValue } from '@/js/conditions';
import TableCondition from './conditions/TableCondition.vue'; import TableCondition from './conditions/TableCondition.vue';
import TableConditionValue from './conditions/TableConditionValue.vue'; import TableConditionValue from './conditions/TableConditionValue.vue';
import type { KucTableEvent } from '@/types/my-kintone';
const props = defineProps<{ const props = defineProps<{
modelValue: WhereCondition[]; modelValue: WhereCondition[];
@@ -20,23 +21,33 @@ const cachedData = inject<CachedData>('cachedData') as CachedData;
const selectedAppData = inject<CachedSelectedAppData>('selectedAppData') as CachedSelectedAppData; const selectedAppData = inject<CachedSelectedAppData>('selectedAppData') as CachedSelectedAppData;
const table = computed(() => selectedAppData.table.table); const table = computed(() => selectedAppData.table.table);
const columns = [ const columns = reactive([
{ {
title: '取得元アプリのフィールド', title: '取得元アプリのフィールド',
field: 'field', field: 'field',
render: (cellData: string, rowData: any, rowIndex: number) => { render: (cellData: string, rowData: WhereCondition) => {
if (!rowData.id) {
rowData.id = generateId();
}
const container = document.createElement('div'); const container = document.createElement('div');
const vnode = h(TableCombobox, { const vnode = h(TableCombobox, {
items: computed(() => getFieldsDropdownItems(selectedAppData.appFields, { items: computed(() =>
getFieldsDropdownItems(selectedAppData.appFields, {
subTableCode: table.value, subTableCode: table.value,
defaultLabel: 'すべてのレコード', defaultLabel: 'すべてのレコード',
})), }),
modelValue: props.modelValue[rowIndex].field, ),
modelValue: (search(props.modelValue, rowData.id) as WhereCondition)?.field || '',
selectedAppData, selectedAppData,
'onUpdate:modelValue': (newValue: string) => { dataList: props.modelValue,
props.modelValue[rowIndex].field = newValue; id: rowData.id,
props.modelValue[rowIndex].condition = ''; 'onUpdate:modelValue': (data) => {
props.modelValue[rowIndex].data = ''; const obj = (data.obj as WhereCondition);
if (obj) {
obj.field = data.value;
obj.condition = '',
obj.data = '';
}
}, },
}); });
render(vnode, container); render(vnode, container);
@@ -46,16 +57,18 @@ const columns = [
{ {
title: '', title: '',
field: 'condition', field: 'condition',
render: (cellData: string, rowData: any, rowIndex: number) => { render: (cellData: string, rowData: WhereCondition) => {
const container = document.createElement('div'); const container = document.createElement('div');
const vnode = h(TableCondition, { const vnode = h(TableCondition, {
modelValue: props.modelValue[rowIndex].condition, modelValue: (search(props.modelValue, rowData.id) as WhereCondition)?.condition || '',
index: rowIndex,
selectedAppData, selectedAppData,
id: rowData.id,
whereConditions: props.modelValue, whereConditions: props.modelValue,
'onUpdate:modelValue': (newValue: string) => { 'onUpdate:modelValue': ({obj, value}) => {
props.modelValue[rowIndex].condition = newValue as ConditionValue; if (obj) {
props.modelValue[rowIndex].data = ''; obj.condition = value;
obj.data = '';
}
}, },
}); });
render(vnode, container); render(vnode, container);
@@ -65,20 +78,21 @@ const columns = [
{ {
title: '', title: '',
field: 'data', field: 'data',
render: (cellData: string, rowData: any, rowIndex: number) => { render: (cellData: string, rowData: WhereCondition) => {
const container = document.createElement('div'); const container = document.createElement('div');
const vnode = h(TableConditionValue, { const vnode = h(TableConditionValue, {
modelValue: props.modelValue[rowIndex].data, modelValue: (search(props.modelValue, rowData.id) as WhereCondition)?.data || '',
index: rowIndex,
selectedAppData, selectedAppData,
id: rowData.id,
whereConditions: props.modelValue, whereConditions: props.modelValue,
'onUpdate:modelValue': (newValue: string) => { 'onUpdate:modelValue': ({obj, value}) => {
props.modelValue[rowIndex].data = newValue; obj && (obj.data = value);
}, },
}); });
render(vnode, container); render(vnode, container);
return container; return container;
}, },
}, },
]; ]);
</script> </script>

View File

@@ -3,9 +3,9 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import type { CachedData, CachedSelectedAppData, FieldsJoinMapping } from '@/types/model'; import type { CachedData, CachedSelectedAppData, FieldsJoinMapping, WhereCondition } from '@/types/model';
import { defineProps, inject, computed, reactive, render, h } from 'vue'; import { defineProps, inject, computed, reactive, render, h, watch } from 'vue';
import { getFieldsDropdownItems } from '@/js/helper'; import { generateId, getFieldsDropdownItems, search } from '@/js/helper';
import TableCombobox from './TableCombobox.vue'; import TableCombobox from './TableCombobox.vue';
const props = defineProps<{ const props = defineProps<{
@@ -21,14 +21,23 @@ const columns = reactive([
{ {
title: '取得元アプリのフィールド', title: '取得元アプリのフィールド',
field: 'leftField', field: 'leftField',
render: (cellData: string, rowData: any, rowIndex: number) => { render: (cellData: string, rowData: WhereCondition) => {
if (!rowData.id) {
rowData.id = generateId();
}
const container = document.createElement('div'); const container = document.createElement('div');
const vnode = h(TableCombobox, { const vnode = h(TableCombobox, {
items: computed(() => getFieldsDropdownItems(selectedAppData.appFields, { subTableCode: table.value, filterType: undefined })), items: computed(() =>
modelValue: props.modelValue[rowIndex].leftField, getFieldsDropdownItems(selectedAppData.appFields, { subTableCode: table.value, filterType: undefined }),
),
modelValue: (search(props.modelValue, rowData.id) as FieldsJoinMapping)?.leftField || '',
selectedAppData, selectedAppData,
'onUpdate:modelValue': (newValue: string) => { dataList: props.modelValue,
props.modelValue[rowIndex].leftField = newValue; id: rowData.id,
'onUpdate:modelValue': (data) => {
if (data.obj) {
(data.obj as FieldsJoinMapping).leftField = data.value;
}
}, },
}); });
render(vnode, container); render(vnode, container);
@@ -45,14 +54,21 @@ const columns = reactive([
{ {
title: 'このアプリのフィールド', title: 'このアプリのフィールド',
field: 'rightField', field: 'rightField',
render: (cellData: string, rowData: any, rowIndex: number) => { render: (cellData: string, rowData: WhereCondition) => {
if (!rowData.id) {
rowData.id = generateId();
}
const container = document.createElement('div'); const container = document.createElement('div');
const vnode = h(TableCombobox, { const vnode = h(TableCombobox, {
items: computed(()=>getFieldsDropdownItems(cachedData.currentAppFields, { filterType: undefined })), items: computed(() => getFieldsDropdownItems(cachedData.currentAppFields, { filterType: undefined })),
modelValue: props.modelValue[rowIndex].rightField, modelValue: (search(props.modelValue, rowData.id) as FieldsJoinMapping)?.rightField || '',
selectedAppData, selectedAppData,
'onUpdate:modelValue': (newValue: string) => { dataList: props.modelValue,
props.modelValue[rowIndex].rightField = newValue; id: rowData.id,
'onUpdate:modelValue': (data) => {
if (data.obj) {
(data.obj as FieldsJoinMapping).rightField = data.value;
}
}, },
}); });
render(vnode, container); render(vnode, container);

View File

@@ -9,6 +9,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { search } from '@/js/helper';
import type { CachedSelectedAppData } from '@/types/model'; import type { CachedSelectedAppData } from '@/types/model';
import type { KucEvent } from '@/types/my-kintone'; import type { KucEvent } from '@/types/my-kintone';
import type { DropdownItem } from 'kintone-ui-component'; import type { DropdownItem } from 'kintone-ui-component';
@@ -17,6 +18,8 @@ import { defineProps, defineEmits, type Ref, watch, ref } from 'vue';
const props = defineProps<{ const props = defineProps<{
items: Ref<DropdownItem[]>; items: Ref<DropdownItem[]>;
modelValue: string; modelValue: string;
dataList: any[];
id: string;
selectedAppData: CachedSelectedAppData; selectedAppData: CachedSelectedAppData;
}>(); }>();
@@ -33,11 +36,16 @@ watch(
}, },
); );
type EmitData = {
obj?: any;
value: string;
};
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'update:modelValue', value: string): void; (e: 'update:modelValue', data: EmitData): void;
}>(); }>();
const updateValue = (event: KucEvent) => { const updateValue = (event: KucEvent) => {
emit('update:modelValue', event.detail.value); emit('update:modelValue', { obj: search(props.dataList, props.id), value: event.detail.value });
}; };
</script> </script>

View File

@@ -9,7 +9,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { getAvailableCondition } from '@/js/conditions'; import { getAvailableCondition, type ConditionValue } from '@/js/conditions';
import { search } from '@/js/helper';
import type { CachedSelectedAppData, WhereCondition } from '@/types/model'; import type { CachedSelectedAppData, WhereCondition } from '@/types/model';
import type { KucEvent } from '@/types/my-kintone'; import type { KucEvent } from '@/types/my-kintone';
import { defineProps, defineEmits, computed } from 'vue'; import { defineProps, defineEmits, computed } from 'vue';
@@ -18,18 +19,23 @@ const props = defineProps<{
modelValue: string; modelValue: string;
selectedAppData: CachedSelectedAppData; selectedAppData: CachedSelectedAppData;
whereConditions: WhereCondition[]; whereConditions: WhereCondition[];
index: number; id: string;
}>(); }>();
const items = computed(() => const whereCondition = computed(() => search(props.whereConditions, props.id) as WhereCondition | undefined);
getAvailableCondition(props.whereConditions[props.index]?.field, props.selectedAppData.appFields),
); const items = computed(() => getAvailableCondition(whereCondition.value?.field || '', props.selectedAppData.appFields));
type EmitData = {
obj?: WhereCondition;
value: ConditionValue;
};
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'update:modelValue', value: string): void; (e: 'update:modelValue', data: EmitData): void;
}>(); }>();
const updateValue = (event: KucEvent) => { const updateValue = (event: KucEvent) => {
emit('update:modelValue', event.detail.value); emit('update:modelValue', { obj: whereCondition.value, value: event.detail.value as ConditionValue });
}; };
</script> </script>

View File

@@ -15,6 +15,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { getComponent } from '@/js/conditions'; import { getComponent } from '@/js/conditions';
import { search } from '@/js/helper';
import type { CachedSelectedAppData, WhereCondition } from '@/types/model'; import type { CachedSelectedAppData, WhereCondition } from '@/types/model';
import type { KucEvent } from '@/types/my-kintone'; import type { KucEvent } from '@/types/my-kintone';
import { defineProps, defineEmits, computed } from 'vue'; import { defineProps, defineEmits, computed } from 'vue';
@@ -23,16 +24,23 @@ const props = defineProps<{
modelValue: string; modelValue: string;
selectedAppData: CachedSelectedAppData; selectedAppData: CachedSelectedAppData;
whereConditions: WhereCondition[]; whereConditions: WhereCondition[];
index: number; id: string;
}>(); }>();
const type = computed(() => getComponent(props.whereConditions[props.index]?.condition)); const whereCondition = computed(() => search(props.whereConditions, props.id) as WhereCondition | undefined);
const type = computed(() => getComponent(whereCondition.value?.condition || ''));
type EmitData = {
obj?: WhereCondition;
value: string;
};
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'update:modelValue', value: string): void; (e: 'update:modelValue', data: EmitData): void;
}>(); }>();
const updateValue = (event: KucEvent) => { const updateValue = (event: KucEvent) => {
emit('update:modelValue', event.detail.value); emit('update:modelValue', { obj: whereCondition.value, value: event.detail.value });
}; };
</script> </script>

View File

@@ -0,0 +1,11 @@
import type { FieldType } from "./kintone-rest-api-client";
const availableJoinType: FieldType[] = [
'SINGLE_LINE_TEXT',
'NUMBER',
'CALC',
'DATE',
'TIME',
'DATETIME',
'LINK'
] as const

View File

@@ -1,4 +1,4 @@
import type { FieldsInfo, JoinTable, WhereCondition } from '@/types/model'; import type { FieldsInfo, FieldsJoinMapping, JoinTable, WhereCondition } from '@/types/model';
import { client, isType, type FieldType, type App, type Layout } from './kintone-rest-api-client'; import { client, isType, type FieldType, type App, type Layout } from './kintone-rest-api-client';
import type { DropdownItem } from 'kintone-ui-component'; import type { DropdownItem } from 'kintone-ui-component';
@@ -7,11 +7,21 @@ export const EMPTY_OPTION = {
label: '--------', label: '--------',
} as DropdownItem; } as DropdownItem;
export const getEmptyWhereCondition = () => ({ field: '', condition: '', data: '' }) as WhereCondition; export function generateId(): string {
export const getEmptyOnCondition = () => ({ leftField: '', rightField: '' }); const timestamp = new Date().getTime().toString(36);
export const getEmptyFieldsMapping = () => ({ leftField: '', rightField: '' }); const randomNum = Math.random().toString(36).substring(2, 11);
return `${timestamp}-${randomNum}`;
}
export function createEmptyJoinTable(id = Number(new Date())) { export function search(list: Array<WhereCondition|FieldsJoinMapping>, id: string) {
return list.find(item => item.id === id);
}
export const getEmptyWhereCondition = () => ({ field: '', condition: '', data: '', id: generateId()} as WhereCondition);
export const getEmptyOnCondition = () => ({ leftField: '', rightField: '', id: generateId() } as FieldsJoinMapping);
export const getEmptyFieldsMapping = () => ({ leftField: '', rightField: '', id: generateId() } as FieldsJoinMapping);
export function createEmptyJoinTable(id = generateId()) {
return resetTable({ id, app: '' } as JoinTable); return resetTable({ id, app: '' } as JoinTable);
} }

View File

@@ -3,18 +3,20 @@ import type { Layout, Properties } from '@/js/kintone-rest-api-client';
import type { DropdownItem } from 'kintone-ui-component'; import type { DropdownItem } from 'kintone-ui-component';
export interface FieldsJoinMapping { export interface FieldsJoinMapping {
id: string;
leftField: string; leftField: string;
rightField: string; rightField: string;
} }
export interface WhereCondition { export interface WhereCondition {
id: string;
field: string; field: string;
condition: ConditionValue; condition: ConditionValue;
data: string; data: string;
} }
export interface JoinTable { export interface JoinTable {
id: number; // 用于唯一区分 id: string;
app: string; // 取得元アプリ app: string; // 取得元アプリ
table: string; // テーブル table: string; // テーブル
onConditions: FieldsJoinMapping[]; // 連結条件 onConditions: FieldsJoinMapping[]; // 連結条件

View File

@@ -1,5 +1,9 @@
import type { TableChangeEventDetail } from 'kintone-ui-component';
export interface KucEvent { export interface KucEvent {
detail: { detail: {
value: string; value: string;
}; };
} }
export interface KucTableEvent {
detail: TableChangeEventDetail;
}