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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -15,6 +15,7 @@
<script setup lang="ts">
import { getComponent } from '@/js/conditions';
import { search } from '@/js/helper';
import type { CachedSelectedAppData, WhereCondition } from '@/types/model';
import type { KucEvent } from '@/types/my-kintone';
import { defineProps, defineEmits, computed } from 'vue';
@@ -23,16 +24,23 @@ const props = defineProps<{
modelValue: string;
selectedAppData: CachedSelectedAppData;
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<{
(e: 'update:modelValue', value: string): void;
(e: 'update:modelValue', data: EmitData): void;
}>();
const updateValue = (event: KucEvent) => {
emit('update:modelValue', event.detail.value);
emit('update:modelValue', { obj: whereCondition.value, value: event.detail.value });
};
</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 type { DropdownItem } from 'kintone-ui-component';
@@ -7,11 +7,21 @@ export const EMPTY_OPTION = {
label: '--------',
} as DropdownItem;
export const getEmptyWhereCondition = () => ({ field: '', condition: '', data: '' }) as WhereCondition;
export const getEmptyOnCondition = () => ({ leftField: '', rightField: '' });
export const getEmptyFieldsMapping = () => ({ leftField: '', rightField: '' });
export function generateId(): string {
const timestamp = new Date().getTime().toString(36);
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);
}

View File

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

View File

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