Files
planka/server/api/helpers/cards/copy-custom-fields.js

186 lines
6.2 KiB
JavaScript
Raw Normal View History

/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
const { POSITION_GAP } = require('../../../constants');
module.exports = {
inputs: {
fromRecord: {
type: 'ref',
required: true,
},
toRecord: {
type: 'ref',
required: true,
},
detachBoardCustomFieldGroups: {
type: 'boolean',
defaultsTo: true,
},
detachBaseCustomFieldGroups: {
type: 'boolean',
defaultsTo: true,
},
},
async fn(inputs) {
const boardCustomFieldGroups = inputs.detachBoardCustomFieldGroups
? await CustomFieldGroup.qm.getByBoardId(inputs.fromRecord.boardId)
: [];
const cardCustomFieldGroups = await CustomFieldGroup.qm.getByCardId(inputs.fromRecord.id);
const customFieldGroups = [...boardCustomFieldGroups, ...cardCustomFieldGroups];
const customFieldGroupIds = sails.helpers.utils.mapRecords(customFieldGroups);
const customFields = await CustomField.qm.getByCustomFieldGroupIds(customFieldGroupIds);
let customFieldGroupsByBaseCustomFieldGroupId;
let baseCustomFieldGroupById;
let customFieldsByBaseCustomFieldGroupId;
let nextCustomFieldsTotal = customFields.length;
if (inputs.detachBaseCustomFieldGroups) {
customFieldGroupsByBaseCustomFieldGroupId = _.groupBy(
customFieldGroups.filter(({ baseCustomFieldGroupId }) => baseCustomFieldGroupId),
'baseCustomFieldGroupId',
);
const baseCustomFieldGroupIds = Object.keys(customFieldGroupsByBaseCustomFieldGroupId);
if (baseCustomFieldGroupIds.length > 0) {
const baseCustomFieldGroups =
await BaseCustomFieldGroup.qm.getByIds(baseCustomFieldGroupIds);
baseCustomFieldGroupById = _.keyBy(baseCustomFieldGroups, 'id');
const baseCustomFields = await CustomField.qm.getByBaseCustomFieldGroupIds(
Object.keys(baseCustomFieldGroupById),
);
customFieldsByBaseCustomFieldGroupId = _.groupBy(
baseCustomFields,
'baseCustomFieldGroupId',
);
nextCustomFieldsTotal += Object.entries(customFieldGroupsByBaseCustomFieldGroupId).reduce(
(result, [baseCustomFieldGroupId, customFieldGroupsItem]) => {
const customFieldsItem = customFieldsByBaseCustomFieldGroupId[baseCustomFieldGroupId];
if (!customFieldsItem) {
return result;
}
return result + customFieldsItem.length * customFieldGroupsItem.length;
},
0,
);
}
}
const customFieldValues = await CustomFieldValue.qm.getByCardId(inputs.fromRecord.id);
const ids = await sails.helpers.utils.generateIds(
customFieldGroups.length + nextCustomFieldsTotal,
);
const nextCustomFieldGroupIdByCustomFieldGroupId = {};
const nextCustomFieldGroupsValues = customFieldGroups.map((customFieldGroup, index) => {
const id = ids.shift();
nextCustomFieldGroupIdByCustomFieldGroupId[customFieldGroup.id] = id;
const values = {
..._.pick(customFieldGroup, ['position']),
id,
cardId: inputs.toRecord.id,
position: customFieldGroup.boardId
? POSITION_GAP * (index + 1)
: customFieldGroup.position + POSITION_GAP * boardCustomFieldGroups.length,
};
if (inputs.detachBaseCustomFieldGroups) {
values.name =
customFieldGroup.name ||
baseCustomFieldGroupById[customFieldGroup.baseCustomFieldGroupId].name;
} else {
Object.assign(values, {
name: customFieldGroup.name,
baseCustomFieldGroupId: customFieldGroup.baseCustomFieldGroupId,
});
}
return values;
});
const nextCustomFieldGroups = await CustomFieldGroup.qm.create(nextCustomFieldGroupsValues);
const nextCustomFieldIdByCustomFieldId = {};
const nextCustomFieldsValues = customFields.map((customField) => {
const id = ids.shift();
nextCustomFieldIdByCustomFieldId[customField.id] = id;
return {
..._.pick(customField, ['position', 'name', 'showOnFrontOfCard']),
id,
customFieldGroupId:
nextCustomFieldGroupIdByCustomFieldGroupId[customField.customFieldGroupId],
};
});
if (inputs.detachBaseCustomFieldGroups) {
Object.entries(customFieldGroupsByBaseCustomFieldGroupId).forEach(
([baseCustomFieldGroupId, customFieldGroupsItem]) => {
const customFieldsItem = customFieldsByBaseCustomFieldGroupId[baseCustomFieldGroupId];
if (!customFieldsItem) {
return;
}
customFieldGroupsItem.forEach((customFieldGroup) => {
customFieldsItem.forEach((customField) => {
const groupedId = `${customFieldGroup.id}:${customField.id}`;
const id = ids.shift();
nextCustomFieldIdByCustomFieldId[groupedId] = id;
nextCustomFieldsValues.push({
..._.pick(customField, ['position', 'name', 'showOnFrontOfCard']),
id,
customFieldGroupId: nextCustomFieldGroupIdByCustomFieldGroupId[customFieldGroup.id],
});
});
});
},
);
}
const nextCustomFields = await CustomField.qm.create(nextCustomFieldsValues);
const nextCustomFieldValuesValues = customFieldValues.map((customFieldValue) => {
const groupedId = `${customFieldValue.customFieldGroupId}:${customFieldValue.customFieldId}`;
return {
..._.pick(customFieldValue, ['content']),
cardId: inputs.toRecord.id,
customFieldGroupId:
nextCustomFieldGroupIdByCustomFieldGroupId[customFieldValue.customFieldGroupId] ||
customFieldValue.customFieldGroupId,
customFieldId:
nextCustomFieldIdByCustomFieldId[groupedId] ||
nextCustomFieldIdByCustomFieldId[customFieldValue.customFieldId] ||
customFieldValue.customFieldId,
};
});
const nextCustomFieldValues = await CustomFieldValue.qm.create(nextCustomFieldValuesValues);
return {
customFieldGroups: nextCustomFieldGroups,
customFields: nextCustomFields,
customFieldValues: nextCustomFieldValues,
};
},
};