2019-07-23 10:54:44 +02:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const _ = require('lodash');
|
2019-07-24 11:51:35 +02:00
|
|
|
const { isSortable, isVisible, isRelation } = require('./attributes');
|
2019-07-23 10:54:44 +02:00
|
|
|
|
|
|
|
const DEFAULT_LIST_LENGTH = 4;
|
|
|
|
const MAX_ROW_SIZE = 12;
|
|
|
|
|
|
|
|
const typeToSize = type => {
|
|
|
|
switch (type) {
|
|
|
|
case 'checkbox':
|
|
|
|
case 'boolean':
|
|
|
|
case 'date':
|
|
|
|
case 'biginteger':
|
|
|
|
case 'decimal':
|
|
|
|
case 'float':
|
|
|
|
case 'integer':
|
|
|
|
case 'number':
|
|
|
|
return MAX_ROW_SIZE / 3;
|
|
|
|
case 'json':
|
|
|
|
case 'group':
|
|
|
|
case 'wysiwyg':
|
|
|
|
return MAX_ROW_SIZE;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return MAX_ROW_SIZE / 2;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-07-24 11:51:35 +02:00
|
|
|
async function createDefaultLayouts(schema) {
|
2019-07-23 10:54:44 +02:00
|
|
|
return {
|
2019-07-24 11:51:35 +02:00
|
|
|
list: createDefaultListLayout(schema),
|
|
|
|
editRelations: createDefaultEditRelationsLayout(schema),
|
|
|
|
edit: createDefaultEditLayout(schema),
|
2019-07-23 10:54:44 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-07-24 11:51:35 +02:00
|
|
|
function createDefaultListLayout(schema) {
|
|
|
|
return Object.keys(schema.attributes)
|
|
|
|
.filter(name => isSortable(schema, name))
|
2019-07-23 10:54:44 +02:00
|
|
|
.slice(0, DEFAULT_LIST_LENGTH);
|
|
|
|
}
|
|
|
|
|
2019-07-24 11:51:35 +02:00
|
|
|
function createDefaultEditRelationsLayout(schema) {
|
|
|
|
if (schema.modelType === 'group') return [];
|
|
|
|
|
|
|
|
return Object.keys(schema.attributes).filter(name =>
|
|
|
|
hasRelationAttribute(schema, name)
|
2019-07-23 10:54:44 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
const rowSize = els => els.reduce((sum, el) => sum + el.size, 0);
|
2019-07-24 11:51:35 +02:00
|
|
|
|
|
|
|
function createDefaultEditLayout(schema) {
|
|
|
|
const keys = Object.keys(schema.attributes).filter(name =>
|
|
|
|
hasEditableAttribute(schema, name)
|
2019-07-23 10:54:44 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
let layout = [[]];
|
|
|
|
let currentRowIndex = 0;
|
|
|
|
for (let key of keys) {
|
2019-07-24 11:51:35 +02:00
|
|
|
const attribute = schema.attributes[key];
|
2019-07-23 10:54:44 +02:00
|
|
|
const attributeSize = typeToSize(attribute.type);
|
|
|
|
let currenRowSize = rowSize(layout[currentRowIndex]);
|
|
|
|
|
|
|
|
if (currenRowSize + attributeSize > MAX_ROW_SIZE) {
|
|
|
|
currentRowIndex += 1;
|
|
|
|
layout[currentRowIndex] = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
layout[currentRowIndex].push({
|
|
|
|
name: key,
|
|
|
|
size: attributeSize,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return layout;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Synchronisation functions */
|
|
|
|
|
2019-07-24 11:51:35 +02:00
|
|
|
function syncLayouts(configuration, schema) {
|
|
|
|
if (_.isEmpty(configuration.layouts)) return createDefaultLayouts(schema);
|
2019-07-23 10:54:44 +02:00
|
|
|
|
|
|
|
const { list = [], editRelations = [], edit = [] } =
|
|
|
|
configuration.layouts || {};
|
|
|
|
|
2019-07-24 11:51:35 +02:00
|
|
|
const cleanList = list.filter(attr => isSortable(schema, attr));
|
2019-07-23 10:54:44 +02:00
|
|
|
|
|
|
|
const cleanEditRelations = editRelations.filter(attr =>
|
2019-07-24 11:51:35 +02:00
|
|
|
hasRelationAttribute(schema, attr)
|
2019-07-23 10:54:44 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
const cleanEdit = edit.reduce((acc, row) => {
|
2019-07-24 11:51:35 +02:00
|
|
|
let newRow = row.filter(el => hasEditableAttribute(schema, el.name));
|
|
|
|
|
|
|
|
// TODO: recompute row sizes
|
2019-07-23 10:54:44 +02:00
|
|
|
|
|
|
|
if (newRow.length > 0) {
|
|
|
|
acc.push(newRow);
|
|
|
|
}
|
|
|
|
return acc;
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
let layout = {
|
2019-07-24 11:51:35 +02:00
|
|
|
list: cleanList.length > 0 ? cleanList : createDefaultListLayout(schema),
|
2019-07-23 10:54:44 +02:00
|
|
|
editRelations:
|
|
|
|
cleanEditRelations.length > 0
|
|
|
|
? cleanEditRelations
|
2019-07-24 11:51:35 +02:00
|
|
|
: createDefaultEditRelationsLayout(schema),
|
|
|
|
edit: cleanEdit.length > 0 ? cleanEdit : createDefaultEditLayout(schema),
|
2019-07-23 10:54:44 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
const newAttributes = _.difference(
|
2019-07-24 11:51:35 +02:00
|
|
|
Object.keys(schema.attributes),
|
2019-07-23 10:54:44 +02:00
|
|
|
Object.keys(configuration.metadatas)
|
|
|
|
);
|
|
|
|
|
|
|
|
if (newAttributes.length === 0) return layout;
|
|
|
|
|
|
|
|
/** Add new attributes where they belong */
|
|
|
|
|
|
|
|
if (layout.list.length < DEFAULT_LIST_LENGTH) {
|
|
|
|
// add newAttributes
|
|
|
|
// only add valid listable attributes
|
|
|
|
layout.list = _.uniq(
|
|
|
|
layout.list
|
2019-07-24 11:51:35 +02:00
|
|
|
.concat(newAttributes.filter(key => isSortable(schema, key)))
|
2019-07-23 10:54:44 +02:00
|
|
|
.slice(0, DEFAULT_LIST_LENGTH)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// add new relations to layout
|
2019-07-24 11:51:35 +02:00
|
|
|
if (schema.type !== 'group') {
|
|
|
|
const newRelations = newAttributes.filter(key =>
|
|
|
|
hasRelationAttribute(schema, key)
|
|
|
|
);
|
2019-07-23 10:54:44 +02:00
|
|
|
|
2019-07-24 11:51:35 +02:00
|
|
|
layout.editRelations = _.uniq(layout.editRelations.concat(newRelations));
|
|
|
|
}
|
2019-07-23 10:54:44 +02:00
|
|
|
|
|
|
|
// add new attributes to edit view
|
2019-07-23 14:26:55 +02:00
|
|
|
const newEditAttributes = newAttributes.filter(
|
2019-07-24 11:51:35 +02:00
|
|
|
key => hasEditableAttribute(schema, key) && isVisible(schema, key)
|
2019-07-23 10:54:44 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
let currentRowIndex = Math.max(layout.edit.length - 1, 0);
|
|
|
|
for (let key of newEditAttributes) {
|
2019-07-24 11:51:35 +02:00
|
|
|
const attribute = schema.attributes[key];
|
2019-07-23 10:54:44 +02:00
|
|
|
const attributeSize = typeToSize(attribute.type);
|
|
|
|
let currenRowSize = rowSize(layout.edit[currentRowIndex]);
|
|
|
|
|
|
|
|
if (currenRowSize + attributeSize > MAX_ROW_SIZE) {
|
|
|
|
currentRowIndex += 1;
|
|
|
|
layout.edit[currentRowIndex] = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
layout.edit[currentRowIndex].push({
|
|
|
|
name: key,
|
|
|
|
size: attributeSize,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return layout;
|
|
|
|
}
|
|
|
|
|
2019-07-24 11:51:35 +02:00
|
|
|
const hasRelationAttribute = (schema, name) => {
|
|
|
|
if (!_.has(schema.attributes, name)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return isRelation(schema.attributes[name]);
|
|
|
|
};
|
|
|
|
|
|
|
|
const hasEditableAttribute = (schema, name) => {
|
|
|
|
if (!_.has(schema.attributes, name)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!isVisible(schema, name)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isRelation(schema.attributes[name])) {
|
|
|
|
if (schema.modelType === 'group') return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
2019-07-23 10:54:44 +02:00
|
|
|
module.exports = {
|
|
|
|
createDefaultLayouts,
|
|
|
|
syncLayouts,
|
|
|
|
};
|