react-admin-corebos
Version:
coreBOS web service data provider for react-admin
311 lines (280 loc) • 10.7 kB
text/typescript
//@ts-ignore
import * as cbconn from '@corebos/ws-lib/WSClientm';
const getUitype10Filter = (key: string, value: any, resource: string, relatedModule: string, joinCondition: string) => {
const window_: any = window;
const fields = window_?.coreBOS?.Describe?.[resource]?.fields ?? [];
const keyField = fields.filter((field: any) => field.name === key)[0] ?? {};
let refTo = '';
if (relatedModule) {
refTo = relatedModule;
} else {
refTo = keyField?.type?.refersTo?.[0] || '';
}
const fieldName = (keyField && keyField.uitype === "10") ? `${key} : (${refTo}) id` : key;
const valueID = value?.split('x')[1] ?? value;
const nsrch = [{
'fieldname': fieldName,
'operation': 'contains',
'value': valueID,
'valuetype': 'raw',
'joincondition': joinCondition,
'groupid': 'ragroup',
'groupjoin': 'and'
}];
return nsrch;
}
const getRaFilterQuery = (filter: any, resource: string, relatedModule: string, joinCondition: string) => {
let search: string = '';
Object.keys(filter).forEach((key: string) => {
const value: any = filter[key];
const window_: any = window;
let nsrch: any[] = [];
if (key.startsWith('cblistsearch_')) {
let [, module] = key.split('_');
let enamefield = window_.coreBOS.Describe[module].labelFields;
if (enamefield.indexOf(',') !== -1) {
let enames = enamefield.split(',');
const grprand = Math.floor(Math.random() * 10);
for (const element of enames) {
nsrch.push(
{
'fieldname': element,
'operation': 'contains',
'value': value,
'valuetype': 'raw',
'joincondition': 'OR',
'groupid': 'racblegrp' + grprand,
'groupjoin': 'and'
}
);
}
} else {
nsrch = [{
'fieldname': window_.coreBOS.Describe[module].labelFields,
'operation': 'contains',
'value': value,
'valuetype': 'raw',
'joincondition': joinCondition,
'groupid': 'racblgroup',
'groupjoin': 'and'
}];
}
} else if (key.startsWith('cbfiltersearch_')) {
nsrch = JSON.parse(value);
} else if (key.startsWith('cbfilter_')) {
nsrch = [{
'fieldname': value?.fieldname,
'operation': value?.operation,
'value': value?.value,
'valuetype': value?.valuetype,
'joincondition': value?.joincondition,
'groupid': value?.groupid,
'groupjoin': value?.groupjoin
}];
} else {
nsrch = getUitype10Filter(key, value, resource, relatedModule, joinCondition);
}
if (search === '') {
search = JSON.stringify(nsrch);
} else {
let osrch = JSON.parse(search);
if (osrch[osrch.length - 1].joincondition === '') {
osrch[osrch.length - 1].joincondition = 'or';
}
osrch[osrch.length - 1].groupjoin = 'and';
search = JSON.stringify(osrch.concat(nsrch));
}
});
return search;
}
const findOperation = (condition: any) => {
const cond = condition || {};
let op = '';
let vals = '';
switch (cond?.operation) {
case 'equal':
op = `${cond.field} = '${cond.value}'`;
break;
case 'like':
op = `${cond.field} like '%${cond.value}%'`;
break;
case 'notlike':
case 'not like':
op = `${cond.field} not like '%${cond.value}%'`;
break;
case 'sw':
op = `${cond.field} like '${cond.value}%'`;
break;
case 'notsw':
case 'not sw':
op = `${cond.field} not like '${cond.value}%'`;
break;
case 'ew':
op = `${cond.field} like '%${cond.value}'`;
break;
case 'notew':
case 'not ew':
op = `${cond.field} not like '%${cond.value}'`;
break;
case 'empty':
op = `(${cond.field} is null or ${cond.field}='' or ${cond.field}=0)`;
break;
case 'notempty':
case 'not empty':
op = `(${cond.field} is not null and ${cond.field}!='' and ${cond.field}!=0)`;
break;
case 'in':
if (Array.isArray(cond.value)) {
vals = "'" + cond.value.join("','") + "'";
} else {
vals = "'" + cond.value + "'";
}
op = `${cond.field} in (${vals})`;
break;
case 'notin':
case 'not in':
if (Array.isArray(cond.value)) {
vals = "'" + cond.value.join("','") + "'";
} else {
vals = "'" + cond.value + "'";
}
op = `${cond.field} not in (${vals})`;
break;
default:
op = `${cond.field} ${cond.operation} '${cond.value}'`;
break;
}
return op;
}
const getCbFilterQuery = (filter: any) => {
let search: string = '';
let prevglue = '';
let apglue = '';
let prevgroup = 'notsetyet';
let group = '';
for (const element of filter) {
let cond = element;
if (prevgroup === 'notsetyet') {
prevgroup = cond.group;
}
let op = findOperation(cond);
if (prevgroup !== cond.group) {
search += (search === '' ? '' : prevglue) + ' (' + group + ')';
group = op;
apglue = prevglue;
prevgroup = cond.group;
} else {
group += ` ${prevglue} ${op}`;
}
prevglue = cond.glue;
}
search += (search === '' ? group : ' ' + apglue + ' (' + group + ')');
return search;
}
const convertFilter2Query = (filter: any, joinConditionValue: string, resource: string, relatedModule: string = '') => {
const joinCondition = joinConditionValue || 'OR';
let search: string = '';
if (!Array.isArray(filter)) { // react admin filter format
if (typeof filter == 'object') {
search = ' where ' + getRaFilterQuery(filter, resource, relatedModule, joinCondition);
}
return search;
}
search += getCbFilterQuery(filter);
return (search === '' ? '' : ' where (' + search + ') ');
}
const execQuery = (resource: string, quesrParams: any, additionalWhereClause?: any, searchingFields?: any) => {
const { filter, ...params } = quesrParams;
const { relatedModule, extraFields, moduleRelationType, joinCondition, ...restFilters } = filter;
let query: string = '';
let where: string = '';
let searchFields = searchingFields || extraFields;
searchFields = searchFields ?? '*';
query = `select ${searchFields} from ${resource}`;
if (filter && Object.keys(filter).length) {
let filters: any = {};
if (moduleRelationType && moduleRelationType === 'N:N') {
filters = Object.entries(restFilters).map((arrKey) => {
return ({ field: arrKey[0] ? arrKey[0] : `Related.${relatedModule}`, value: arrKey[1], operation: 'equal', glue: joinCondition ?? 'OR', group: 1 });
});
} else {
filters = restFilters;
}
where = convertFilter2Query(filters, params.joinCondition ?? 'OR', resource, relatedModule);
}
if (!additionalWhereClause) {
query += where;
} else {
query += where !== '' ? where + " and " + additionalWhereClause : ' where ' + additionalWhereClause;
}
let { field, order } = params.sort;
field = field || '';
order = order || '';
if (field !== '') {
query += appendOrder(field, order);
}
let { page, perPage } = params.pagination;
if (perPage) {
page = page || 1;
query += appendPagination(page, perPage);
}
query = encodeURIComponent(query);
return cbconn.doQueryWithTotal(query).then((data: any) => {
return { 'data': data.result, 'total': Number(data.totalrows) }
}).catch((er: any) => {
return { data: [], total: 0 }
})
}
export const appendPagination = (pageNumber: number, perPage: number) => {
const page = pageNumber || 1;
return ' limit ' + ((page - 1) * perPage) + ',' + perPage;
};
export const appendOrder = (field: any, order: string) => {
return ' order by ' + field + ' ' + order;
};
const dataProvider: any = { // react-admin DataProvider
getList: async (resource: string, params: any, additionalWhereClause?: string, additionalFields?: any) => {
params = {
...params,
joinCondition: 'AND'
};
return execQuery(resource, params, additionalWhereClause, additionalFields)
},
getOne: (resource: string, params: any) =>
cbconn.doRetrieve(params.id)
.then((data: any) => { return { 'data': data } })
,
getMany: (resource: string, params: any) =>
cbconn.doMassRetrieve(params.ids)
.then((data: any) => {
let d: any = [];
for (const value of Object.values(data)) {
d.push(value);
}
const result: any = { 'data': d };
return result;
}),
getManyReference: (resource: string, params: any) => {
return execQuery(resource, params)
},
update: (resource: string, params: any) =>
cbconn.doUpdate(resource, params.data)
.then((data: any) => { return { 'data': data } })
,
updateMany: (resource: string, params: any) =>
cbconn.doInvoke('MassUpdate', JSON.stringify(params.data))
.then((data: any) => { return { 'data': data } })
,
create: (resource: string, params: any) =>
cbconn.doCreate(resource, params.data)
.then((data: any) => { return { 'data': data, id: data['id'] } })
,
delete: (resource: string, params: any) =>
cbconn.doDelete(params.id)
.then((data: any) => { return { 'data': data } })
,
deleteMany: (resource: string, params: any) =>
cbconn.doMassDelete(params.ids)
.then((data: any) => { return { 'data': data } })
};
export default dataProvider;