condition merged
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -17,7 +17,7 @@ const props = defineProps<{
|
|||||||
const savedData = inject<SavedData>('savedData') as SavedData;
|
const savedData = inject<SavedData>('savedData') as SavedData;
|
||||||
const cachedData = inject<CachedData>('cachedData') as CachedData;
|
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 = reactive([
|
const columns = reactive([
|
||||||
{
|
{
|
||||||
@@ -31,7 +31,7 @@ const columns = reactive([
|
|||||||
const vnode = h(TableCombobox, {
|
const vnode = h(TableCombobox, {
|
||||||
items: computed(() =>
|
items: computed(() =>
|
||||||
getFieldsDropdownItems(selectedAppData.appFields, {
|
getFieldsDropdownItems(selectedAppData.appFields, {
|
||||||
subTableCode: table.value,
|
subTableCode: '', //table.value,
|
||||||
baseFilter: undefined,
|
baseFilter: undefined,
|
||||||
defaultLabel: 'すべてのレコード',
|
defaultLabel: 'すべてのレコード',
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
import type { CachedData, CachedSelectedAppData, FieldsJoinMapping, WhereCondition } 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 } from 'vue';
|
||||||
import { generateId, getFieldObj, getFieldsDropdownItems, search } from '@/js/helper';
|
import { generateId, getFieldObj, getFieldsDropdownItems, search } from '@/js/helper';
|
||||||
import { getLeftAvailableJoinType, getRightAvailableJoinType, isForceDisable } from '@/js/join';
|
import { getLeftAvailableJoinType, getRightAvailableJoinType, isLeftJoinForceDisable, isRightJoinForceDisable, } from '@/js/join';
|
||||||
import { getLeftAvailableMappingType, getRightAvailableMappingType } from '@/js/mapping';
|
import { getLeftAvailableMappingType, getRightAvailableMappingType } from '@/js/mapping';
|
||||||
import TableCombobox from './TableCombobox.vue';
|
import TableCombobox from './TableCombobox.vue';
|
||||||
import { type FieldType, type OneOf } from '@/js/kintone-rest-api-client';
|
import { type FieldType, type OneOf } from '@/js/kintone-rest-api-client';
|
||||||
@@ -23,10 +23,12 @@ const table = computed(() => selectedAppData.table.table);
|
|||||||
|
|
||||||
const filterFunc = {
|
const filterFunc = {
|
||||||
connect: {
|
connect: {
|
||||||
|
subTable: table,
|
||||||
left: (right?: OneOf | '') => getLeftAvailableJoinType(right),
|
left: (right?: OneOf | '') => getLeftAvailableJoinType(right),
|
||||||
right: (left?: OneOf | '') => getRightAvailableJoinType(left),
|
right: (left?: OneOf | '') => getRightAvailableJoinType(left),
|
||||||
},
|
},
|
||||||
mapping: {
|
mapping: {
|
||||||
|
subTable: computed(() => ''),
|
||||||
left: (right?: OneOf | '') => getLeftAvailableMappingType(right),
|
left: (right?: OneOf | '') => getLeftAvailableMappingType(right),
|
||||||
right: (left?: OneOf | '') => getRightAvailableMappingType(left),
|
right: (left?: OneOf | '') => getRightAvailableMappingType(left),
|
||||||
},
|
},
|
||||||
@@ -45,11 +47,11 @@ const columns = reactive([
|
|||||||
items: computed(() => {
|
items: computed(() => {
|
||||||
const dependFilterField = getField('rightField', rowData.id);
|
const dependFilterField = getField('rightField', rowData.id);
|
||||||
return getFieldsDropdownItems(selectedAppData.appFields, {
|
return getFieldsDropdownItems(selectedAppData.appFields, {
|
||||||
subTableCode: table.value,
|
subTableCode: filterFunc[props.type].subTable.value,
|
||||||
baseFilter: filterFunc[props.type].left() as FieldType[],
|
baseFilter: filterFunc[props.type].left() as FieldType[],
|
||||||
filterType: filterFunc[props.type].left(dependFilterField),
|
filterType: filterFunc[props.type].left(dependFilterField),
|
||||||
dependFilterField,
|
dependFilterField,
|
||||||
defaultDisableCallback: isForceDisable,
|
defaultDisableCallback: isLeftJoinForceDisable,
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
modelValue: computed(() => (search(props.modelValue, rowData.id) as FieldsJoinMapping)?.leftField || ''),
|
modelValue: computed(() => (search(props.modelValue, rowData.id) as FieldsJoinMapping)?.leftField || ''),
|
||||||
@@ -89,7 +91,7 @@ const columns = reactive([
|
|||||||
baseFilter: filterFunc[props.type].right() as FieldType[],
|
baseFilter: filterFunc[props.type].right() as FieldType[],
|
||||||
filterType: filterFunc[props.type].right(dependFilterField),
|
filterType: filterFunc[props.type].right(dependFilterField),
|
||||||
dependFilterField,
|
dependFilterField,
|
||||||
defaultDisableCallback: isForceDisable,
|
defaultDisableCallback: props.type === 'connect' ? isRightJoinForceDisable : undefined,
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
modelValue: computed(() => (search(props.modelValue, rowData.id) as FieldsJoinMapping)?.rightField || ''),
|
modelValue: computed(() => (search(props.modelValue, rowData.id) as FieldsJoinMapping)?.rightField || ''),
|
||||||
@@ -112,7 +114,7 @@ function getField(key: 'leftField' | 'rightField', id: string) {
|
|||||||
const dataRow = search(props.modelValue, id) as FieldsJoinMapping | undefined;
|
const dataRow = search(props.modelValue, id) as FieldsJoinMapping | undefined;
|
||||||
const fieldCode = dataRow ? dataRow[key] || '' : '';
|
const fieldCode = dataRow ? dataRow[key] || '' : '';
|
||||||
const targetFieldMap = key === 'leftField' ? selectedAppData.appFields : cachedData.currentAppFields;
|
const targetFieldMap = key === 'leftField' ? selectedAppData.appFields : cachedData.currentAppFields;
|
||||||
const targetTable = key === 'leftField' ? table.value : '';
|
const targetTable = key === 'leftField' ? filterFunc[props.type].subTable.value : '';
|
||||||
return getFieldObj(fieldCode, targetFieldMap, targetTable);
|
return getFieldObj(fieldCode, targetFieldMap, targetTable);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<kuc-combobox
|
<kuc-combobox
|
||||||
|
className="kuc-text-input"
|
||||||
:items="items.value"
|
:items="items.value"
|
||||||
:value="modelValue.value"
|
:value="modelValue.value"
|
||||||
@change="updateValue"
|
@change="updateValue"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<kuc-combobox
|
<kuc-combobox
|
||||||
v-if="items?.length"
|
v-if="items?.length"
|
||||||
:items="items"
|
:items="items"
|
||||||
:value="modelValue"
|
:value="value"
|
||||||
@change="updateValue"
|
@change="updateValue"
|
||||||
:disabled="selectedAppData.loading == undefined ? false : selectedAppData.loading"
|
:disabled="selectedAppData.loading == undefined ? false : selectedAppData.loading"
|
||||||
/>
|
/>
|
||||||
@@ -14,7 +14,7 @@ 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 type { ComboboxChangeEventDetail } from 'kintone-ui-component';
|
import type { ComboboxChangeEventDetail } from 'kintone-ui-component';
|
||||||
import { defineProps, defineEmits, computed } from 'vue';
|
import { defineProps, defineEmits, computed, watch, ref } from 'vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: string;
|
modelValue: string;
|
||||||
@@ -25,7 +25,25 @@ const props = defineProps<{
|
|||||||
|
|
||||||
const whereCondition = computed(() => search(props.whereConditions, props.id) as WhereCondition | undefined);
|
const whereCondition = computed(() => search(props.whereConditions, props.id) as WhereCondition | undefined);
|
||||||
|
|
||||||
const items = computed(() => getAvailableCondition(whereCondition.value?.field || '', props.selectedAppData.appFields, props.selectedAppData.table.table));
|
const items = computed(() =>
|
||||||
|
getAvailableCondition(
|
||||||
|
whereCondition.value?.field || '',
|
||||||
|
props.selectedAppData.appFields,
|
||||||
|
props.selectedAppData.table.table,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
const value = ref(props.modelValue);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => items,
|
||||||
|
() => {
|
||||||
|
const option = items.value?.[0] || { value: '' };
|
||||||
|
value.value = option.value;
|
||||||
|
updateValue({ detail: option });
|
||||||
|
},
|
||||||
|
{ deep: true },
|
||||||
|
);
|
||||||
|
|
||||||
type EmitData = {
|
type EmitData = {
|
||||||
obj?: WhereCondition;
|
obj?: WhereCondition;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
/* config 页面 */
|
/* config 页面 */
|
||||||
#app {
|
#app {
|
||||||
width: 60vw;
|
width: 60vw;
|
||||||
min-width: 920px;
|
min-width: 940px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 最上面的说明 */
|
/* 最上面的说明 */
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
/* laebl input 单行的情况 */
|
/* laebl input 单行的情况 */
|
||||||
.flex-row .kintoneplugin-label {
|
.flex-row .kintoneplugin-label {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
width: 10em;
|
width: 8.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 遮罩 */
|
/* 遮罩 */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { FieldLayout, FieldsJoinMapping, JoinTable, Record, RecordForParameter, SavedData, WhereCondition } from "@/types/model";
|
import type { FieldLayout, FieldsJoinMapping, JoinTable, Record, RecordForParameter, SavedData, WhereCondition } from "@/types/model";
|
||||||
import { isType, type OneOf } from "./kintone-rest-api-client";
|
import type { isType, OneOf } from "./kintone-rest-api-client";
|
||||||
declare var KintoneRestAPIClient: typeof import("@kintone/rest-api-client").KintoneRestAPIClient;
|
declare var KintoneRestAPIClient: typeof import("@kintone/rest-api-client").KintoneRestAPIClient;
|
||||||
export class KintoneIndexEventHandler {
|
export class KintoneIndexEventHandler {
|
||||||
private config: SavedData<FieldLayout>;
|
private config: SavedData<FieldLayout>;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { FieldsInfo } from '@/types/model';
|
import type { FieldsInfo } from '@/types/model';
|
||||||
import type { FieldType } from './kintone-rest-api-client';
|
import { isType, type FieldType, type OneOf } from './kintone-rest-api-client';
|
||||||
import { getFieldObj } from './helper';
|
import { getFieldObj } from './helper';
|
||||||
|
|
||||||
// conditionValue = '' | 'eq' | 'ne'
|
// conditionValue = '' | 'eq' | 'ne'
|
||||||
@@ -18,18 +18,27 @@ export type ConditionValue = ""| "="
|
|||||||
|
|
||||||
type ConditionItem = {
|
type ConditionItem = {
|
||||||
value: ConditionValue;
|
value: ConditionValue;
|
||||||
label: string;
|
label: string | ((field: OneOf) => string);
|
||||||
type: ComponentType;
|
type: ComponentType; // | ((field: OneOf) => ComponentType);
|
||||||
func: (a: string, b: string) => boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const conditionList: ConditionItem[] = [
|
export const conditionList: ConditionItem[] = [
|
||||||
{ value: '', label: '--------', type: '', func: (a: string, b: string) => true },
|
{ value: '=', label: '=(等しい)', type: 'input' },
|
||||||
{ value: '=', label: '=(等しい)', type: 'input', func: (a: string, b: string) => a === b },
|
{ value: '!=', label: '≠ (等しくない)', type: 'input' },
|
||||||
{ value: '!=', label: '≠ (等しくない)', type: 'input', func: (a: string, b: string) => a !== b },
|
{ value: '<=', label: (field) => isDateTimeType(field) ? '≦ (以前)' : '≦ (以下)', type: 'input' },
|
||||||
{ value: '>=', label: 'test combobox', type: 'select', func: (a: string, b: string) => a < b },
|
{ value: '<', label: '< (より前)', type: 'input' },
|
||||||
|
{ value: '>', label: '> (より後)', type: 'input' },
|
||||||
|
{ value: '>=', label: (field) => isDateTimeType(field) ? '≧ (以降)' : '≧ (以上)', type: 'input' },
|
||||||
|
{ value: 'like', label: '次のキーワードを含む', type: 'input' },
|
||||||
|
{ value: 'not like', label:'次のキーワードを含まない', type: 'input' },
|
||||||
|
{ value: 'in', label: '次のいずれかを含む', type: 'input' },
|
||||||
|
{ value: 'not in', label: '次のいずれも含まない', type: 'input' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const isDateTimeType = (field: OneOf) => {
|
||||||
|
return isType.DATETIME(field) || isType.TIME(field) || isType.DATE(field) || isType.CREATED_TIME(field) || isType.UPDATED_TIME(field);
|
||||||
|
}
|
||||||
|
|
||||||
// search from conditionList
|
// search from conditionList
|
||||||
// conditionItem = conditionMap[conditionValue]
|
// conditionItem = conditionMap[conditionValue]
|
||||||
export const conditionMap: Record<ConditionValue, ConditionItem> = conditionList.reduce(
|
export const conditionMap: Record<ConditionValue, ConditionItem> = conditionList.reduce(
|
||||||
@@ -42,26 +51,66 @@ export const conditionMap: Record<ConditionValue, ConditionItem> = conditionList
|
|||||||
|
|
||||||
type FieldConditions = Partial<Record<FieldType, ConditionValue[]>>;
|
type FieldConditions = Partial<Record<FieldType, ConditionValue[]>>;
|
||||||
|
|
||||||
|
const textCondition: ConditionValue[] = ['=', '!=', 'in', 'like','not like'];
|
||||||
|
const numberCondition: ConditionValue[] = ['=', '!=', '<=', '>='];
|
||||||
|
const timeCondition: ConditionValue[] = ['=', '!=', '<=', '>=', '<', '>'];
|
||||||
|
const containsCondition: ConditionValue[] = ['in', 'not in'];
|
||||||
|
|
||||||
// FieldType -> ConditionValue[]
|
// FieldType -> ConditionValue[]
|
||||||
const fieldConditions: FieldConditions = {
|
const fieldConditions: FieldConditions = {
|
||||||
SINGLE_LINE_TEXT: ['eq', 'ne'],
|
SINGLE_LINE_TEXT: textCondition,
|
||||||
NUMBER: ['ne', 'test'],
|
MULTI_LINE_TEXT: containsCondition,
|
||||||
|
RICH_TEXT: containsCondition,
|
||||||
|
NUMBER: numberCondition,
|
||||||
|
CHECK_BOX: containsCondition,
|
||||||
|
RADIO_BUTTON: containsCondition,
|
||||||
|
DROP_DOWN: containsCondition,
|
||||||
|
MULTI_SELECT: containsCondition,
|
||||||
|
USER_SELECT: containsCondition,
|
||||||
|
ORGANIZATION_SELECT: containsCondition,
|
||||||
|
GROUP_SELECT: containsCondition,
|
||||||
|
LINK: textCondition,
|
||||||
|
CALC: numberCondition,
|
||||||
|
|
||||||
|
TIME: timeCondition,
|
||||||
|
DATE: timeCondition,
|
||||||
|
DATETIME: timeCondition,
|
||||||
|
CREATED_TIME: timeCondition,
|
||||||
|
CREATOR: containsCondition,
|
||||||
|
UPDATED_TIME: timeCondition,
|
||||||
|
MODIFIER: containsCondition,
|
||||||
|
RECORD_NUMBER: numberCondition,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// fieldCode -> conditionList: ConditionItem[]
|
// fieldCode -> conditionList: ConditionItem[]
|
||||||
export const getAvailableCondition = (fieldCode: string, fieldsInfo: FieldsInfo, subTableCode: string | '') => {
|
export const getAvailableCondition = (fieldCode: string, fieldsInfo: FieldsInfo, subTableCode: string | '') => {
|
||||||
if (!fieldCode || !fieldsInfo.fields) return;
|
if (!fieldCode || !fieldsInfo.fields) return;
|
||||||
const fieldObj = getFieldObj(fieldCode, fieldsInfo, subTableCode);
|
const fieldObj = getFieldObj(fieldCode, fieldsInfo, '');
|
||||||
if (!fieldObj) return;
|
if (!fieldObj) return;
|
||||||
const conditions = fieldConditions[fieldObj.type] || [];
|
const conditions = fieldConditions[fieldObj.type] || textCondition; // TODO a fallback here
|
||||||
return conditions.map((condition) => conditionMap[condition]);
|
return conditions.map((condition) => {
|
||||||
|
const res = {...conditionMap[condition]}
|
||||||
|
res.label = typeof res.label === 'function' ? res.label(fieldObj) : res.label;
|
||||||
|
return res;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const component = {
|
const component = {
|
||||||
'': undefined,
|
|
||||||
input: 'kuc-text',
|
input: 'kuc-text',
|
||||||
select: 'kuc-combobox',
|
select: 'kuc-combobox',
|
||||||
|
time: 'time',
|
||||||
|
date: 'date',
|
||||||
|
datetime: 'datetime',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const dateTimeComponent: Partial<Record<FieldType, ComponentType>> = {
|
||||||
|
TIME: 'time',
|
||||||
|
DATE: 'date',
|
||||||
|
DATETIME: 'datetime',
|
||||||
|
CREATED_TIME: 'datetime',
|
||||||
|
UPDATED_TIME: 'datetime',
|
||||||
|
}
|
||||||
|
|
||||||
export type ComponentType = keyof typeof component;
|
export type ComponentType = keyof typeof component;
|
||||||
export const getComponent = (value: ConditionValue) => {
|
export const getComponent = (value: ConditionValue) => {
|
||||||
if (!value) return;
|
if (!value) return;
|
||||||
|
|||||||
@@ -1,99 +1,135 @@
|
|||||||
import type { CalcType, LinkType } from '@/types/my-kintone';
|
import type { CalcType, LinkProtocolType } from '@/types/my-kintone';
|
||||||
import { isType, type FieldType, type OneOf } from './kintone-rest-api-client';
|
import { isType, type FieldType, type OneOf } from './kintone-rest-api-client';
|
||||||
|
import { KintoneFormFieldProperty } from '@kintone/rest-api-client';
|
||||||
|
|
||||||
export function isForceDisable(field: OneOf) {
|
export function isLeftJoinForceDisable(field: OneOf) {
|
||||||
if (isType.CALC(field)) {
|
if (isType.CALC(field)) {
|
||||||
return field.format === 'DAY_HOUR_MINUTE' || field.format === 'HOUR_MINUTE';
|
return field.format === 'DAY_HOUR_MINUTE' || field.format === 'HOUR_MINUTE';
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isRightJoinForceDisable(field: OneOf) {
|
||||||
|
if (isLookup(field)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
export type SpecialType<T = string, F = any> = {
|
export type SpecialType<T = string, F = any> = {
|
||||||
type: T;
|
type: T;
|
||||||
format: F;
|
format: F;
|
||||||
check: (field: OneOf, depField?: OneOf) => boolean;
|
check: (checkField: OneOf, selectedField?: OneOf) => boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
// LEFT
|
// LEFT
|
||||||
export type LeftCalcJoinType = SpecialType<'CALC_JOIN_FOR_LEFT', Record<CalcType, FieldType[]>>;
|
// LEFT - lookup
|
||||||
|
export type LookupTypeL2R = SpecialType<'LOOKUP_FROM_LEFT', FieldType[]>;
|
||||||
|
export const forMayLookup = (format: FieldType[]): LookupTypeL2R => {
|
||||||
|
return {
|
||||||
|
type: 'LOOKUP_FROM_LEFT',
|
||||||
|
format,
|
||||||
|
check: function (checkField: OneOf, selectedLeftField?: OneOf) {
|
||||||
|
if (isLookup(checkField) && selectedLeftField) {
|
||||||
|
return isLookup(selectedLeftField) ? checkField.type === selectedLeftField.type : false;
|
||||||
|
}
|
||||||
|
return !!this.format?.find((e) => e === checkField.type);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export const calcJoinType: LeftCalcJoinType = {
|
export const mayLookupText = forMayLookup(['SINGLE_LINE_TEXT']);
|
||||||
type: 'CALC_JOIN_FOR_LEFT',
|
export const mayLookupNumber = forMayLookup(['NUMBER']);
|
||||||
|
export const mayLookupTextNumber = forMayLookup(['SINGLE_LINE_TEXT', 'NUMBER']);
|
||||||
|
|
||||||
|
// LEFT - calc
|
||||||
|
export type CalcTypeL2R = SpecialType<'CALC_FROM_LEFT', Record<CalcType, Array<FieldType | LookupTypeL2R>>>;
|
||||||
|
|
||||||
|
export const leftCalcType: CalcTypeL2R = {
|
||||||
|
type: 'CALC_FROM_LEFT',
|
||||||
format: {
|
format: {
|
||||||
NUMBER: ['SINGLE_LINE_TEXT', 'NUMBER'],
|
NUMBER: [mayLookupTextNumber],
|
||||||
NUMBER_DIGIT: ['SINGLE_LINE_TEXT', 'NUMBER'],
|
NUMBER_DIGIT: [mayLookupTextNumber],
|
||||||
DATE: ['DATE'],
|
DATE: ['DATE'],
|
||||||
TIME: ['TIME'],
|
TIME: ['TIME'],
|
||||||
DATETIME: ['DATETIME'],
|
DATETIME: ['DATETIME'],
|
||||||
HOUR_MINUTE: [],
|
HOUR_MINUTE: [],
|
||||||
DAY_HOUR_MINUTE: [],
|
DAY_HOUR_MINUTE: [],
|
||||||
},
|
},
|
||||||
check: function (field: OneOf, rightField?: OneOf) {
|
check: function (checkField: OneOf, selectedLeftField?: OneOf) {
|
||||||
let allowed: FieldType[] = [];
|
let allowed: Array<FieldType | LookupTypeL2R> = [];
|
||||||
if (rightField && isType.CALC(rightField)) {
|
if (selectedLeftField && isType.CALC(selectedLeftField)) {
|
||||||
allowed = this.format[rightField.format];
|
allowed = this.format[selectedLeftField.format];
|
||||||
}
|
}
|
||||||
if (field && isType.CALC(field)) {
|
return !!allowed.find((e) => {
|
||||||
return !!allowed.find((e) => e === field.format);
|
if (isSpecialType(e) && isLookupFromLeft(e)) {
|
||||||
|
return e.check(checkField, selectedLeftField);
|
||||||
}
|
}
|
||||||
return false;
|
return e === checkField.type;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export type LinkJoinType = SpecialType<'LINK_JOIN', Record<LinkType, LinkType[]>>;
|
// LEFT - link
|
||||||
|
export type LinkType = SpecialType<'LINK', Record<LinkProtocolType, LinkProtocolType[]>>;
|
||||||
|
|
||||||
// 入力値の種別が同じ場合のみ
|
export const linkType: LinkType = {
|
||||||
export const linkJoinType: LinkJoinType = {
|
type: 'LINK',
|
||||||
type: 'LINK_JOIN',
|
|
||||||
format: {
|
format: {
|
||||||
|
// 入力値の種別が同じ場合のみ
|
||||||
WEB: ['WEB'],
|
WEB: ['WEB'],
|
||||||
CALL: ['CALL'],
|
CALL: ['CALL'],
|
||||||
MAIL: ['MAIL'],
|
MAIL: ['MAIL'],
|
||||||
},
|
},
|
||||||
check: function (field: OneOf, dependField?: OneOf) {
|
check: function (checkField: OneOf, selectedField?: OneOf) {
|
||||||
let allowed: LinkType[] = [];
|
let allowed: LinkProtocolType[] = [];
|
||||||
if (dependField && isType.LINK(dependField)) {
|
if (selectedField && isType.LINK(selectedField)) {
|
||||||
allowed = this.format[dependField.protocol];
|
allowed = this.format[selectedField.protocol];
|
||||||
}
|
}
|
||||||
if (field && isType.LINK(field)) {
|
if (checkField && isType.LINK(checkField)) {
|
||||||
return !!allowed.find((e) => e === field.protocol);
|
return !!allowed.find((e) => e === checkField.protocol);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// LEFT - rule
|
||||||
|
export type AvailableRight = FieldType | CalcTypeL2R | LinkType | LookupTypeL2R;
|
||||||
const availableLeftJoinType = {
|
const availableLeftJoinType = {
|
||||||
SINGLE_LINE_TEXT: ['SINGLE_LINE_TEXT'],
|
SINGLE_LINE_TEXT: [mayLookupText],
|
||||||
NUMBER: ['NUMBER'],
|
NUMBER: [mayLookupNumber],
|
||||||
CALC: [calcJoinType],
|
CALC: [leftCalcType],
|
||||||
DATE: ['DATE'],
|
DATE: ['DATE'],
|
||||||
TIME: ['TIME'],
|
TIME: ['TIME'],
|
||||||
DATETIME: ['DATETIME'],
|
DATETIME: ['DATETIME'],
|
||||||
LINK: [linkJoinType],
|
LINK: [linkType],
|
||||||
} as Record<FieldType, Array<FieldType | LeftCalcJoinType | LinkJoinType>>;
|
} as Record<FieldType, AvailableRight[]>;
|
||||||
|
|
||||||
// RIGHT
|
// RIGHT - calc
|
||||||
export type RightCalcJoinType = SpecialType<'CALC_JOIN_FOR_RIGHT', CalcType[]>;
|
export type CalcTypeR2L = SpecialType<'CALC_FROM_RIGHT', CalcType[]>;
|
||||||
|
|
||||||
export const forCalc = (format: CalcType[]): RightCalcJoinType => {
|
export const forCalc = (format: CalcType[]): CalcTypeR2L => {
|
||||||
return {
|
return {
|
||||||
type: 'CALC_JOIN_FOR_RIGHT',
|
type: 'CALC_FROM_RIGHT',
|
||||||
format,
|
format,
|
||||||
check: function (field: OneOf, leftField?: OneOf) {
|
check: function (checkField: OneOf, selectedRightField?: OneOf) {
|
||||||
return isType.CALC(field) && !!this.format?.find((e) => e === field.format);
|
return isType.CALC(checkField) && !!this.format?.find((e) => e === checkField.format);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// RIGHT - rule
|
||||||
|
export type AvailableLeft = FieldType | CalcTypeR2L | LinkType;
|
||||||
const availableRightJoinType = {
|
const availableRightJoinType = {
|
||||||
SINGLE_LINE_TEXT: ['SINGLE_LINE_TEXT', forCalc(['NUMBER', 'NUMBER_DIGIT'])],
|
SINGLE_LINE_TEXT: ['SINGLE_LINE_TEXT', forCalc(['NUMBER', 'NUMBER_DIGIT'])],
|
||||||
NUMBER: ['NUMBER', forCalc(['NUMBER', 'NUMBER_DIGIT'])],
|
NUMBER: ['NUMBER', forCalc(['NUMBER', 'NUMBER_DIGIT'])],
|
||||||
DATE: ['DATE', forCalc(['DATE'])],
|
DATE: ['DATE', forCalc(['DATE'])],
|
||||||
TIME: ['TIME', forCalc(['TIME'])],
|
TIME: ['TIME', forCalc(['TIME'])],
|
||||||
DATETIME: ['DATETIME', forCalc(['DATETIME'])],
|
DATETIME: ['DATETIME', forCalc(['DATETIME'])],
|
||||||
LINK: [linkJoinType],
|
LINK: [linkType],
|
||||||
} as Record<FieldType, Array<FieldType | RightCalcJoinType | LinkJoinType>>;
|
} as Record<FieldType, AvailableLeft[]>;
|
||||||
|
|
||||||
|
// methods
|
||||||
// undefined means all
|
// undefined means all
|
||||||
export function getRightAvailableJoinType(left?: OneOf | '') {
|
export function getRightAvailableJoinType(left?: OneOf | '') {
|
||||||
if (left === undefined) {
|
if (left === undefined) {
|
||||||
@@ -114,14 +150,22 @@ export function isSpecialType(obj: FieldType | SpecialType): obj is SpecialType
|
|||||||
return typeof obj === 'object' && !Array.isArray(obj) && 'type' in obj;
|
return typeof obj === 'object' && !Array.isArray(obj) && 'type' in obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isLinkJoinType(obj: SpecialType): obj is LinkJoinType {
|
export function isLookupFromLeft(obj: SpecialType): obj is LookupTypeL2R {
|
||||||
return obj.type === 'LINK_JOIN';
|
return obj.type === 'LOOKUP_FROM_LEFT';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isLeftCalcJoinType(obj: SpecialType): obj is LeftCalcJoinType {
|
export function isLinkType(obj: SpecialType): obj is LinkType {
|
||||||
return obj.type === 'CALC_JOIN_FOR_LEFT';
|
return obj.type === 'LINK';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isRightCalcJoinType(obj: SpecialType): obj is RightCalcJoinType {
|
export function isCalcFromLeft(obj: SpecialType): obj is CalcTypeL2R {
|
||||||
return obj.type === 'CALC_JOIN_FOR_RIGHT';
|
return obj.type === 'CALC_FROM_LEFT';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isCalcFromRight(obj: SpecialType): obj is CalcTypeR2L {
|
||||||
|
return obj.type === 'CALC_FROM_RIGHT';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isLookup(field: OneOf): field is KintoneFormFieldProperty.Lookup {
|
||||||
|
return 'lookup' in field;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,75 +1,26 @@
|
|||||||
import type { CalcType, LinkType, SelectType } from '@/types/my-kintone';
|
import { type FieldType, type OneOf } from './kintone-rest-api-client';
|
||||||
import { isType, type FieldType, type OneOf } from './kintone-rest-api-client';
|
import {
|
||||||
import { calcJoinType, linkJoinType, type SpecialType, isSpecialType } from './join';
|
leftCalcType,
|
||||||
import { KintoneFormFieldProperty } from '@kintone/rest-api-client';
|
linkType,
|
||||||
|
type SpecialType,
|
||||||
// LEFT
|
mayLookupTextNumber,
|
||||||
export type LeftLookupMappingType = SpecialType<'LOOKUP_MAPPING_FOR_LEFT', FieldType[]>;
|
mayLookupText,
|
||||||
|
type AvailableRight,
|
||||||
export const lookupMappingType = (format: FieldType[]): LeftLookupMappingType => {
|
type AvailableLeft,
|
||||||
return {
|
isLookup,
|
||||||
type: 'LOOKUP_MAPPING_FOR_LEFT',
|
forCalc,
|
||||||
format,
|
type CalcTypeR2L,
|
||||||
check: function (field: OneOf, rightField?: OneOf) {
|
isSpecialType,
|
||||||
if (rightField && isLookup(rightField) && !isLookup(field)) {
|
} from './join';
|
||||||
return false;
|
import type { SelectType } from '@/types/my-kintone';
|
||||||
}
|
|
||||||
return !!this.format?.find((e) => e === field.type);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const mayLookupText = lookupMappingType(['SINGLE_LINE_TEXT']);
|
|
||||||
const mayLookupNumber = lookupMappingType(['NUMBER']);
|
|
||||||
|
|
||||||
export type LeftCalcMappingType = SpecialType<
|
|
||||||
'CALC_MAPPING_FOR_LEFT',
|
|
||||||
Record<CalcType, Array<FieldType | LeftLookupMappingType>>
|
|
||||||
>;
|
|
||||||
|
|
||||||
// same as join
|
|
||||||
export const calcMappingType: LeftCalcMappingType = {
|
|
||||||
type: 'CALC_MAPPING_FOR_LEFT',
|
|
||||||
format: {
|
|
||||||
NUMBER: [mayLookupText, mayLookupNumber],
|
|
||||||
NUMBER_DIGIT: [mayLookupText, mayLookupNumber],
|
|
||||||
DATE: ['DATE'],
|
|
||||||
TIME: ['TIME'],
|
|
||||||
DATETIME: ['DATETIME'],
|
|
||||||
HOUR_MINUTE: [],
|
|
||||||
DAY_HOUR_MINUTE: [],
|
|
||||||
},
|
|
||||||
check: function (field: OneOf, rightField?: OneOf) {
|
|
||||||
let allowed: Array<FieldType | LeftLookupMappingType> = [];
|
|
||||||
if (rightField && isType.CALC(rightField)) {
|
|
||||||
allowed = this.format[rightField.format];
|
|
||||||
}
|
|
||||||
if (field && isType.CALC(field)) {
|
|
||||||
return !!allowed.find((e) => {
|
|
||||||
if (isSpecialType(e) && isLeftLookupMappingType(e)) {
|
|
||||||
return e.check(field, rightField);
|
|
||||||
}
|
|
||||||
return e === field.format
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export type LinkMappingType = SpecialType<'LINK_MAPPING', Record<LinkType, LinkType[]>>;
|
|
||||||
|
|
||||||
// same as join
|
|
||||||
export const linkMappingType = {
|
|
||||||
...linkJoinType,
|
|
||||||
type: 'LINK_MAPPING',
|
|
||||||
} as LinkMappingType;
|
|
||||||
|
|
||||||
|
// LEFT - rule
|
||||||
const availableLeftMappingType = {
|
const availableLeftMappingType = {
|
||||||
SINGLE_LINE_TEXT: [mayLookupText],
|
SINGLE_LINE_TEXT: [mayLookupText],
|
||||||
MULTI_LINE_TEXT: ['MULTI_LINE_TEXT'],
|
MULTI_LINE_TEXT: ['MULTI_LINE_TEXT'],
|
||||||
RICH_TEXT: ['RICH_TEXT'],
|
RICH_TEXT: ['RICH_TEXT'],
|
||||||
NUMBER: [mayLookupNumber, mayLookupText],
|
NUMBER: [mayLookupTextNumber],
|
||||||
CALC: [calcMappingType],
|
CALC: [leftCalcType],
|
||||||
RADIO_BUTTON: ['RADIO_BUTTON'],
|
RADIO_BUTTON: ['RADIO_BUTTON'],
|
||||||
CHECK_BOX: ['CHECK_BOX'],
|
CHECK_BOX: ['CHECK_BOX'],
|
||||||
MULTI_SELECT: ['MULTI_SELECT'], // TODO 带选项字段报错
|
MULTI_SELECT: ['MULTI_SELECT'], // TODO 带选项字段报错
|
||||||
@@ -80,45 +31,43 @@ const availableLeftMappingType = {
|
|||||||
DATE: ['DATE', 'DATETIME'],
|
DATE: ['DATE', 'DATETIME'],
|
||||||
TIME: ['TIME'],
|
TIME: ['TIME'],
|
||||||
DATETIME: ['DATETIME'],
|
DATETIME: ['DATETIME'],
|
||||||
LINK: [linkMappingType, mayLookupText],
|
LINK: [linkType, mayLookupText],
|
||||||
//LOOKUP
|
//LOOKUP
|
||||||
RECORD_NUMBER: [mayLookupText, mayLookupNumber],
|
RECORD_NUMBER: [mayLookupTextNumber],
|
||||||
CREATOR: ['USER_SELECT'],
|
CREATOR: ['USER_SELECT'],
|
||||||
CREATED_TIME: ['DATETIME'],
|
CREATED_TIME: ['DATETIME'],
|
||||||
MODIFIER: ['USER_SELECT'],
|
MODIFIER: ['USER_SELECT'],
|
||||||
UPDATED_TIME: ['DATETIME'],
|
UPDATED_TIME: ['DATETIME'],
|
||||||
} as Record<FieldType, Array<FieldType | LeftCalcMappingType | LinkMappingType | LeftLookupMappingType>>;
|
} as Record<FieldType, AvailableRight[]>;
|
||||||
|
|
||||||
// RIGHT
|
// RIGHT
|
||||||
export type RightCalcMappingType = SpecialType<'CALC_MAPPING_FOR_RIGHT', CalcType[]>;
|
export type LookupTypeR2L = SpecialType<'LOOKUP_FROM_RIGHT', Array<FieldType | CalcTypeR2L>>;
|
||||||
export type RightLookupMappingType = SpecialType<'LOOKUP_MAPPING_FOR_RIGHT', FieldType[]>;
|
|
||||||
|
|
||||||
export const forCalc = (format: CalcType[]): RightCalcMappingType => {
|
export const isSameLookupOr = (format: Array<FieldType | CalcTypeR2L>): LookupTypeR2L => {
|
||||||
return {
|
return {
|
||||||
type: 'CALC_MAPPING_FOR_RIGHT',
|
type: 'LOOKUP_FROM_RIGHT',
|
||||||
format,
|
format,
|
||||||
check: function (field: OneOf, leftField?: OneOf) {
|
check: function (checkField: OneOf, selectedRightField?: OneOf) {
|
||||||
return isType.CALC(field) && !!this.format?.find((e) => e === field.format);
|
if (selectedRightField && isLookup(selectedRightField)) {
|
||||||
},
|
return isLookup(checkField) ? checkField.type === selectedRightField.type : false;
|
||||||
};
|
}
|
||||||
};
|
return !!this.format?.find((e) => {
|
||||||
|
if (isSpecialType(e)) {
|
||||||
export const forLookup = (format: FieldType[]): RightLookupMappingType => {
|
return e.check(checkField, selectedRightField);
|
||||||
return {
|
}
|
||||||
type: 'LOOKUP_MAPPING_FOR_RIGHT',
|
return e === checkField.type;
|
||||||
format,
|
});
|
||||||
check: function (field: OneOf, leftField?: OneOf) {
|
|
||||||
if (!isLookup(field)) return false;
|
|
||||||
return !!this.format?.find((e) => e === field.type);
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const availableRightMappingType = {
|
const availableRightMappingType = {
|
||||||
SINGLE_LINE_TEXT: ['SINGLE_LINE_TEXT', 'NUMBER', forCalc(['NUMBER', 'NUMBER_DIGIT']), 'LINK', 'RECORD_NUMBER'],
|
SINGLE_LINE_TEXT: [
|
||||||
|
isSameLookupOr(['SINGLE_LINE_TEXT', 'NUMBER', forCalc(['NUMBER', 'NUMBER_DIGIT']), 'LINK', 'RECORD_NUMBER']),
|
||||||
|
],
|
||||||
MULTI_LINE_TEXT: ['MULTI_LINE_TEXT'],
|
MULTI_LINE_TEXT: ['MULTI_LINE_TEXT'],
|
||||||
RICH_TEXT: ['RICH_TEXT'],
|
RICH_TEXT: ['RICH_TEXT'],
|
||||||
NUMBER: ['NUMBER', forCalc(['NUMBER', 'NUMBER_DIGIT']), forLookup(['NUMBER']), 'RECORD_NUMBER'],
|
NUMBER: [isSameLookupOr(['NUMBER', forCalc(['NUMBER', 'NUMBER_DIGIT']), 'RECORD_NUMBER'])],
|
||||||
RADIO_BUTTON: ['RADIO_BUTTON'],
|
RADIO_BUTTON: ['RADIO_BUTTON'],
|
||||||
CHECK_BOX: ['CHECK_BOX'],
|
CHECK_BOX: ['CHECK_BOX'],
|
||||||
MULTI_SELECT: ['MULTI_SELECT'], // TODO 带选项字段报错
|
MULTI_SELECT: ['MULTI_SELECT'], // TODO 带选项字段报错
|
||||||
@@ -129,9 +78,10 @@ const availableRightMappingType = {
|
|||||||
DATE: ['DATE', forCalc(['DATE'])],
|
DATE: ['DATE', forCalc(['DATE'])],
|
||||||
TIME: ['TIME', forCalc(['TIME'])],
|
TIME: ['TIME', forCalc(['TIME'])],
|
||||||
DATETIME: ['DATE', 'DATETIME', forCalc(['DATETIME']), 'CREATED_TIME', 'UPDATED_TIME'],
|
DATETIME: ['DATE', 'DATETIME', forCalc(['DATETIME']), 'CREATED_TIME', 'UPDATED_TIME'],
|
||||||
LINK: [linkMappingType],
|
LINK: [linkType],
|
||||||
} as Record<FieldType, Array<FieldType | RightCalcMappingType | RightLookupMappingType | LinkMappingType>>;
|
} as Record<FieldType, Array<AvailableLeft | LookupTypeR2L>>;
|
||||||
|
|
||||||
|
// methods
|
||||||
// undefined means all
|
// undefined means all
|
||||||
export function getRightAvailableMappingType(left?: OneOf | '') {
|
export function getRightAvailableMappingType(left?: OneOf | '') {
|
||||||
if (left === undefined) {
|
if (left === undefined) {
|
||||||
@@ -148,14 +98,6 @@ export function getLeftAvailableMappingType(right?: OneOf | '') {
|
|||||||
return right ? availableRightMappingType[right.type] : [];
|
return right ? availableRightMappingType[right.type] : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isLeftLookupMappingType(obj: SpecialType): obj is LeftLookupMappingType {
|
export function isSelectType(field: OneOf): field is SelectType {
|
||||||
return obj.type === 'LOOKUP_MAPPING_FOR_LEFT';
|
return 'options' in field;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isLookup(field: OneOf): field is KintoneFormFieldProperty.Lookup {
|
|
||||||
return 'lookup' in field;
|
|
||||||
}
|
|
||||||
|
|
||||||
// export function isSelectType(field: OneOf): field is SelectType {
|
|
||||||
// return 'options' in field;
|
|
||||||
// }
|
|
||||||
|
|||||||
@@ -1,20 +1,14 @@
|
|||||||
|
import { KintoneFormFieldProperty } from '@kintone/rest-api-client';
|
||||||
|
|
||||||
export interface KucEvent<T> {
|
export interface KucEvent<T> {
|
||||||
detail: T;
|
detail: T;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CalcType = 'NUMBER' | 'NUMBER_DIGIT' | 'DATETIME' | 'DATE' | 'TIME' | 'HOUR_MINUTE' | 'DAY_HOUR_MINUTE';
|
export type CalcType = 'NUMBER' | 'NUMBER_DIGIT' | 'DATETIME' | 'DATE' | 'TIME' | 'HOUR_MINUTE' | 'DAY_HOUR_MINUTE';
|
||||||
export type LinkType = 'WEB' | 'CALL' | 'MAIL';
|
export type LinkProtocolType = 'WEB' | 'CALL' | 'MAIL';
|
||||||
|
|
||||||
type Options = {
|
export type SelectType =
|
||||||
[optionName: string]: {
|
| KintoneFormFieldProperty.CheckBox
|
||||||
label: string;
|
| KintoneFormFieldProperty.RadioButton
|
||||||
index: string;
|
| KintoneFormFieldProperty.DropDown
|
||||||
};
|
| KintoneFormFieldProperty.MultiSelect;
|
||||||
};
|
|
||||||
|
|
||||||
export type SelectType = {
|
|
||||||
type: 'CHECK_BOX' | 'RADIO_BUTTON' | 'DROP_DOWN' | 'MULTI_SELECT';
|
|
||||||
code: string;
|
|
||||||
label: string;
|
|
||||||
options: Options;
|
|
||||||
};
|
|
||||||
|
|||||||
Reference in New Issue
Block a user