1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-07-18 20:59:44 +02:00
planka/server/api/helpers/insert-to-positionables.js

126 lines
2.7 KiB
JavaScript
Raw Normal View History

2019-08-31 04:07:25 +05:00
const GAP = 2 ** 14;
const MIN_GAP = 0.125;
const MAX_POSITION = 2 ** 50;
2019-08-31 04:07:25 +05:00
const findBeginnings = positions => {
2019-08-31 04:07:25 +05:00
positions.unshift(0);
let prevPosition = positions.pop();
const beginnings = [prevPosition];
// eslint-disable-next-line consistent-return
_.forEachRight(positions, position => {
2019-08-31 04:07:25 +05:00
if (prevPosition - MIN_GAP >= position) {
return false;
}
prevPosition = position;
beginnings.unshift(prevPosition);
});
return beginnings;
};
const getRepositionsMap = positions => {
2019-08-31 04:07:25 +05:00
const repositionsMap = {};
if (positions.length <= 1) {
if (!_.isUndefined(positions[0]) && positions[0] > MAX_POSITION) {
return null;
}
return repositionsMap;
}
let prevPosition = positions.shift();
for (let i = 0; i < positions.length; i += 1) {
2019-08-31 04:07:25 +05:00
const position = positions[i];
const nextPosition = positions[i + 1];
if (prevPosition + MIN_GAP <= position) {
break;
}
if (!_.isUndefined(nextPosition) && prevPosition + MIN_GAP * 2 <= nextPosition) {
2019-08-31 04:07:25 +05:00
(repositionsMap[position] || (repositionsMap[position] = [])).push(
prevPosition + (nextPosition - prevPosition) / 2,
2019-08-31 04:07:25 +05:00
);
break;
}
prevPosition += GAP;
if (prevPosition > MAX_POSITION) {
return null;
}
(repositionsMap[position] || (repositionsMap[position] = [])).push(prevPosition);
2019-08-31 04:07:25 +05:00
}
return repositionsMap;
};
const getFullRepositionsMap = positions => {
2019-08-31 04:07:25 +05:00
const repositionsMap = {};
_.forEach(positions, (position, index) => {
(repositionsMap[position] || (repositionsMap[position] = [])).push(GAP * (index + 1));
2019-08-31 04:07:25 +05:00
});
return repositionsMap;
};
module.exports = {
sync: true,
inputs: {
position: {
type: 'number',
required: true,
2019-08-31 04:07:25 +05:00
},
records: {
type: 'ref',
required: true,
},
2019-08-31 04:07:25 +05:00
},
fn(inputs, exits) {
2019-08-31 04:07:25 +05:00
const lowers = [];
const uppers = [];
inputs.records.forEach(({ position }) => {
(position <= inputs.position ? lowers : uppers).push(position);
});
const beginnings = findBeginnings([...lowers, inputs.position]);
const repositionsMap =
getRepositionsMap([...beginnings, ...uppers]) ||
getFullRepositionsMap([...lowers, inputs.position, ...uppers]);
2019-08-31 04:07:25 +05:00
const position = repositionsMap[inputs.position]
2019-08-31 04:07:25 +05:00
? repositionsMap[inputs.position].pop()
: inputs.position;
const repositions = [];
_.forEachRight(inputs.records, ({ id, position: currentPosition }) => {
if (_.isEmpty(repositionsMap[currentPosition])) {
2019-08-31 04:07:25 +05:00
return;
}
repositions.unshift({
id,
position: repositionsMap[currentPosition].pop(),
2019-08-31 04:07:25 +05:00
});
});
return exits.success({
position,
repositions,
2019-08-31 04:07:25 +05:00
});
},
2019-08-31 04:07:25 +05:00
};