1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-07-24 15:49:46 +02:00

feat: Version 2

Closes #627, closes #1047
This commit is contained in:
Maksim Eltyshev 2025-05-10 02:09:06 +02:00
parent ad7fb51cfa
commit 2ee1166747
1557 changed files with 76832 additions and 47042 deletions

View file

@ -1,3 +1,8 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* Action.js
*
@ -8,7 +13,6 @@
const Types = {
CREATE_CARD: 'createCard',
MOVE_CARD: 'moveCard',
COMMENT_CARD: 'commentCard',
};
module.exports = {
@ -44,7 +48,6 @@ module.exports = {
},
userId: {
model: 'User',
required: true,
columnName: 'user_id',
},
},

View file

@ -1,3 +1,8 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* Attachment.js
*
@ -5,22 +10,27 @@
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
*/
const Types = {
FILE: 'file',
LINK: 'link',
};
module.exports = {
Types,
attributes: {
// ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗
// ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
// ╩ ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
dirname: {
type: {
type: 'string',
isIn: Object.values(Types),
required: true,
},
filename: {
type: 'string',
required: true,
},
image: {
data: {
type: 'json',
required: true,
},
name: {
type: 'string',
@ -42,18 +52,7 @@ module.exports = {
},
creatorUserId: {
model: 'User',
required: true,
columnName: 'creator_user_id',
},
},
customToJSON() {
return {
..._.omit(this, ['dirname', 'filename', 'image.thumbnailsExtension']),
url: `${sails.config.custom.baseUrl}/attachments/${this.id}/download/${this.filename}`,
coverUrl: this.image
? `${sails.config.custom.baseUrl}/attachments/${this.id}/download/thumbnails/cover-256.${this.image.thumbnailsExtension}`
: null,
};
},
};

View file

@ -0,0 +1,49 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* BackgroundImage.js
*
* @description :: A model definition represents a database table/collection.
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
*/
module.exports = {
attributes: {
// ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗
// ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
// ╩ ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
dirname: {
type: 'string',
required: true,
},
extension: {
type: 'string',
required: true,
},
sizeInBytes: {
type: 'string', // TODO: should be number somehow
required: true,
columnName: 'size_in_bytes',
},
// ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗
// ║╣ ║║║╠╩╗║╣ ║║╚═╗
// ╚═╝╩ ╩╚═╝╚═╝═╩╝╚═╝
// ╔═╗╔═╗╔═╗╔═╗╔═╗╦╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
// ╠═╣╚═╗╚═╗║ ║║ ║╠═╣ ║ ║║ ║║║║╚═╗
// ╩ ╩╚═╝╚═╝╚═╝╚═╝╩╩ ╩ ╩ ╩╚═╝╝╚╝╚═╝
projectId: {
model: 'Project',
required: true,
columnName: 'project_id',
},
},
tableName: 'background_image',
};

View file

@ -0,0 +1,40 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* BaseCustomFieldGroup.js
*
* @description :: A model definition represents a database table/collection.
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
*/
module.exports = {
attributes: {
// ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗
// ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
// ╩ ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
name: {
type: 'string',
required: true,
},
// ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗
// ║╣ ║║║╠╩╗║╣ ║║╚═╗
// ╚═╝╩ ╩╚═╝╚═╝═╩╝╚═╝
// ╔═╗╔═╗╔═╗╔═╗╔═╗╦╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
// ╠═╣╚═╗╚═╗║ ║║ ║╠═╣ ║ ║║ ║║║║╚═╗
// ╩ ╩╚═╝╚═╝╚═╝╚═╝╩╩ ╩ ╩ ╩╚═╝╝╚╝╚═╝
projectId: {
model: 'Project',
required: true,
columnName: 'project_id',
},
},
tableName: 'base_custom_field_group',
};

View file

@ -1,3 +1,8 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* Board.js
*
@ -5,11 +10,20 @@
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
*/
const Card = require('./Card');
const Views = {
KANBAN: 'kanban',
GRID: 'grid',
LIST: 'list',
};
const ImportTypes = {
TRELLO: 'trello',
};
module.exports = {
Views,
ImportTypes,
attributes: {
@ -25,6 +39,28 @@ module.exports = {
type: 'string',
required: true,
},
defaultView: {
type: 'string',
isIn: Object.values(Views),
defaultsTo: Views.KANBAN,
columnName: 'default_view',
},
defaultCardType: {
type: 'string',
isIn: Object.values(Card.Types),
defaultsTo: Card.Types.PROJECT,
columnName: 'default_card_type',
},
limitCardTypesToDefaultOne: {
type: 'boolean',
defaultsTo: false,
columnName: 'limit_card_types_to_default_one',
},
alwaysDisplayCardCreator: {
type: 'boolean',
defaultsTo: false,
columnName: 'always_display_card_creator',
},
// ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗
// ║╣ ║║║╠╩╗║╣ ║║╚═╗

View file

@ -1,3 +1,8 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* BoardMembership.js
*
@ -10,8 +15,24 @@ const Roles = {
VIEWER: 'viewer',
};
const SHARED_RULES = {
role: {},
canComment: { setTo: null },
};
const RULES_BY_ROLE = {
[Roles.EDITOR]: {
canComment: { setTo: null },
},
[Roles.VIEWER]: {
canComment: { defaultTo: false },
},
};
module.exports = {
Roles,
SHARED_RULES,
RULES_BY_ROLE,
attributes: {
// ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗
@ -37,6 +58,12 @@ module.exports = {
// ╠═╣╚═╗╚═╗║ ║║ ║╠═╣ ║ ║║ ║║║║╚═╗
// ╩ ╩╚═╝╚═╝╚═╝╚═╝╩╩ ╩ ╩ ╩╚═╝╝╚╝╚═╝
// Denormalization
projectId: {
model: 'Project',
required: true,
columnName: 'project_id',
},
boardId: {
model: 'Board',
required: true,

View file

@ -0,0 +1,40 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* BoardSubscription.js
*
* @description :: A model definition represents a database table/collection.
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
*/
module.exports = {
attributes: {
// ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗
// ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
// ╩ ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
// ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗
// ║╣ ║║║╠╩╗║╣ ║║╚═╗
// ╚═╝╩ ╩╚═╝╚═╝═╩╝╚═╝
// ╔═╗╔═╗╔═╗╔═╗╔═╗╦╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
// ╠═╣╚═╗╚═╗║ ║║ ║╠═╣ ║ ║║ ║║║║╚═╗
// ╩ ╩╚═╝╚═╝╚═╝╚═╝╩╩ ╩ ╩ ╩╚═╝╝╚╝╚═╝
boardId: {
model: 'Board',
required: true,
columnName: 'board_id',
},
userId: {
model: 'User',
required: true,
columnName: 'user_id',
},
},
tableName: 'board_subscription',
};

View file

@ -1,3 +1,8 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* Card.js
*
@ -5,15 +10,27 @@
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
*/
const Types = {
PROJECT: 'project',
STORY: 'story',
};
module.exports = {
Types,
attributes: {
// ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗
// ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
// ╩ ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
type: {
type: 'string',
isIn: Object.values(Types),
required: true,
},
position: {
type: 'number',
required: true,
allowNull: true,
},
name: {
type: 'string',
@ -28,14 +45,13 @@ module.exports = {
type: 'ref',
columnName: 'due_date',
},
isDueDateCompleted: {
type: 'boolean',
allowNull: true,
columnName: 'is_due_date_completed',
},
stopwatch: {
type: 'json',
},
listChangedAt: {
type: 'ref',
columnName: 'list_changed_at',
},
// ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗
// ║╣ ║║║╠╩╗║╣ ║║╚═╗
@ -45,6 +61,7 @@ module.exports = {
// ╠═╣╚═╗╚═╗║ ║║ ║╠═╣ ║ ║║ ║║║║╚═╗
// ╩ ╩╚═╝╚═╝╚═╝╚═╝╩╩ ╩ ╩ ╩╚═╝╝╚╝╚═╝
// Denormalization
boardId: {
model: 'Board',
required: true,
@ -59,6 +76,10 @@ module.exports = {
model: 'User',
columnName: 'creator_user_id',
},
prevListId: {
model: 'List',
columnName: 'prev_list_id',
},
coverAttachmentId: {
model: 'Attachment',
columnName: 'cover_attachment_id',
@ -78,14 +99,18 @@ module.exports = {
via: 'cardId',
through: 'CardLabel',
},
tasks: {
collection: 'Task',
taskLists: {
collection: 'TaskList',
via: 'cardId',
},
attachments: {
collection: 'Attachment',
via: 'cardId',
},
comments: {
collection: 'Comment',
via: 'cardId',
},
actions: {
collection: 'Action',
via: 'cardId',

View file

@ -1,3 +1,8 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* CardLabel.js
*

View file

@ -1,3 +1,8 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* CardMembership.js
*

View file

@ -1,3 +1,8 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* CardSubscription.js
*

View file

@ -1,5 +1,10 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* Archive.js
* Comment.js
*
* @description :: A model definition represents a database table/collection.
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
@ -11,20 +16,9 @@ module.exports = {
// ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
// ╩ ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
fromModel: {
text: {
type: 'string',
required: true,
columnName: 'from_model',
},
originalRecordId: {
type: 'string',
required: true,
columnName: 'original_record_id',
},
originalRecord: {
type: 'json',
required: true,
columnName: 'original_record',
},
// ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗
@ -34,7 +28,15 @@ module.exports = {
// ╔═╗╔═╗╔═╗╔═╗╔═╗╦╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
// ╠═╣╚═╗╚═╗║ ║║ ║╠═╣ ║ ║║ ║║║║╚═╗
// ╩ ╩╚═╝╚═╝╚═╝╚═╝╩╩ ╩ ╩ ╩╚═╝╝╚╝╚═╝
},
archiveModelIdentity: false,
cardId: {
model: 'Card',
required: true,
columnName: 'card_id',
},
userId: {
model: 'User',
columnName: 'user_id',
},
},
};

View file

@ -0,0 +1,52 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* CustomField.js
*
* @description :: A model definition represents a database table/collection.
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
*/
module.exports = {
attributes: {
// ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗
// ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
// ╩ ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
position: {
type: 'number',
required: true,
},
name: {
type: 'string',
required: true,
},
showOnFrontOfCard: {
type: 'boolean',
required: true,
columnName: 'show_on_front_of_card',
},
// ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗
// ║╣ ║║║╠╩╗║╣ ║║╚═╗
// ╚═╝╩ ╩╚═╝╚═╝═╩╝╚═╝
// ╔═╗╔═╗╔═╗╔═╗╔═╗╦╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
// ╠═╣╚═╗╚═╗║ ║║ ║╠═╣ ║ ║║ ║║║║╚═╗
// ╩ ╩╚═╝╚═╝╚═╝╚═╝╩╩ ╩ ╩ ╩╚═╝╝╚╝╚═╝
baseCustomFieldGroupId: {
model: 'BaseCustomFieldGroup',
columnName: 'base_custom_field_group_id',
},
customFieldGroupId: {
model: 'CustomFieldGroup',
columnName: 'custom_field_group_id',
},
},
tableName: 'custom_field',
};

View file

@ -0,0 +1,52 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* CustomFieldGroup.js
*
* @description :: A model definition represents a database table/collection.
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
*/
module.exports = {
attributes: {
// ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗
// ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
// ╩ ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
position: {
type: 'number',
required: true,
},
name: {
type: 'string',
isNotEmptyString: true,
allowNull: true,
},
// ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗
// ║╣ ║║║╠╩╗║╣ ║║╚═╗
// ╚═╝╩ ╩╚═╝╚═╝═╩╝╚═╝
// ╔═╗╔═╗╔═╗╔═╗╔═╗╦╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
// ╠═╣╚═╗╚═╗║ ║║ ║╠═╣ ║ ║║ ║║║║╚═╗
// ╩ ╩╚═╝╚═╝╚═╝╚═╝╩╩ ╩ ╩ ╩╚═╝╝╚╝╚═╝
boardId: {
model: 'Board',
columnName: 'board_id',
},
cardId: {
model: 'Card',
columnName: 'card_id',
},
baseCustomFieldGroupId: {
model: 'BaseCustomFieldGroup',
columnName: 'base_custom_field_group_id',
},
},
tableName: 'custom_field_group',
};

View file

@ -0,0 +1,50 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* CustomFieldValue.js
*
* @description :: A model definition represents a database table/collection.
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
*/
module.exports = {
attributes: {
// ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗
// ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
// ╩ ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
content: {
type: 'string',
required: true,
},
// ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗
// ║╣ ║║║╠╩╗║╣ ║║╚═╗
// ╚═╝╩ ╩╚═╝╚═╝═╩╝╚═╝
// ╔═╗╔═╗╔═╗╔═╗╔═╗╦╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
// ╠═╣╚═╗╚═╗║ ║║ ║╠═╣ ║ ║║ ║║║║╚═╗
// ╩ ╩╚═╝╚═╝╚═╝╚═╝╩╩ ╩ ╩ ╩╚═╝╝╚╝╚═╝
cardId: {
model: 'Card',
required: true,
columnName: 'card_id',
},
customFieldGroupId: {
model: 'CustomFieldGroup',
required: true,
columnName: 'custom_field_group_id',
},
customFieldId: {
model: 'CustomField',
required: true,
columnName: 'custom_field_id',
},
},
tableName: 'custom_field_value',
};

View file

@ -0,0 +1,35 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* FileReference.js
*
* @description :: A model definition represents a database table/collection.
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
*/
module.exports = {
attributes: {
// ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗
// ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
// ╩ ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
total: {
type: 'number',
allowNull: true,
defaultsTo: 0,
},
// ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗
// ║╣ ║║║╠╩╗║╣ ║║╚═╗
// ╚═╝╩ ╩╚═╝╚═╝═╩╝╚═╝
// ╔═╗╔═╗╔═╗╔═╗╔═╗╦╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
// ╠═╣╚═╗╚═╗║ ║║ ║╠═╣ ║ ║║ ║║║║╚═╗
// ╩ ╩╚═╝╚═╝╚═╝╚═╝╩╩ ╩ ╩ ╩╚═╝╝╚╝╚═╝
},
tableName: 'file_reference',
};

View file

@ -1,5 +1,10 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* ProjectManager.js
* IdentityProviderUser.js
*
* @description :: A model definition represents a database table/collection.
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
@ -7,6 +12,10 @@
module.exports = {
attributes: {
// ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗
// ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
// ╩ ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
issuer: {
type: 'string',
isNotEmptyString: true,
@ -17,9 +26,6 @@ module.exports = {
isNotEmptyString: true,
allowNull: true,
},
// ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗
// ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
// ╩ ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
// ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗
// ║╣ ║║║╠╩╗║╣ ║║╚═╗

View file

@ -1,3 +1,8 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* Label.js
*
@ -6,31 +11,48 @@
*/
const COLORS = [
'berry-red',
'pumpkin-orange',
'lagoon-blue',
'pink-tulip',
'light-mud',
'orange-peel',
'bright-moss',
'antique-blue',
'dark-granite',
'lagune-blue',
'sunny-grass',
'muddy-grey',
'autumn-leafs',
'morning-sky',
'light-orange',
'midnight-blue',
'tank-green',
'gun-metal',
'wet-moss',
'red-burgundy',
'light-concrete',
'apricot-red',
'desert-sand',
'navy-blue',
'antique-blue',
'egg-yellow',
'coral-green',
'desert-sand',
'dark-granite',
'fresh-salad',
'lagoon-blue',
'midnight-blue',
'light-orange',
'pumpkin-orange',
'light-concrete',
'sunny-grass',
'navy-blue',
'lilac-eyes',
'apricot-red',
'orange-peel',
'silver-glint',
'bright-moss',
'deep-ocean',
'summer-sky',
'berry-red',
'light-cocoa',
'grey-stone',
'tank-green',
'coral-green',
'sugar-plum',
'pink-tulip',
'shady-rust',
'wet-rock',
'wet-moss',
'turquoise-sea',
'lavender-fields',
'piggy-red',
'light-mud',
'gun-metal',
'modern-green',
'french-coast',
'sweet-lilac',
'red-burgundy',
'pirate-gold',
];
module.exports = {

View file

@ -1,3 +1,8 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* List.js
*
@ -5,13 +10,27 @@
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
*/
const SortTypes = {
NAME_ASC: 'name_asc',
DUE_DATE_ASC: 'dueDate_asc',
CREATED_AT_ASC: 'createdAt_asc',
CREATED_AT_DESC: 'createdAt_desc',
const Types = {
ACTIVE: 'active',
CLOSED: 'closed',
ARCHIVE: 'archive',
TRASH: 'trash',
};
const SortFieldNames = {
NAME: 'name',
DUE_DATE: 'dueDate',
CREATED_AT: 'createdAt',
};
// TODO: should not be here
const SortOrders = {
ASC: 'asc',
DESC: 'desc',
};
const FINITE_TYPES = [Types.ACTIVE, Types.CLOSED];
const COLORS = [
'berry-red',
'pumpkin-orange',
@ -22,11 +41,14 @@ const COLORS = [
'bright-moss',
'antique-blue',
'dark-granite',
'lagune-blue',
'turquoise-sea',
];
module.exports = {
SortTypes,
Types,
SortFieldNames,
SortOrders,
FINITE_TYPES,
COLORS,
attributes: {
@ -34,13 +56,19 @@ module.exports = {
// ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
// ╩ ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
type: {
type: 'string',
isIn: Object.values(Types),
required: true,
},
position: {
type: 'number',
required: true,
allowNull: true,
},
name: {
type: 'string',
required: true,
isNotEmptyString: true,
allowNull: true,
},
color: {
type: 'string',

View file

@ -1,3 +1,8 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* Notification.js
*
@ -5,12 +10,28 @@
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
*/
const Types = {
MOVE_CARD: 'moveCard',
COMMENT_CARD: 'commentCard',
};
module.exports = {
Types,
attributes: {
// ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗
// ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
// ╩ ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
type: {
type: 'string',
isIn: Object.values(Types),
required: true,
},
data: {
type: 'json',
required: true,
},
isRead: {
type: 'boolean',
defaultsTo: false,
@ -30,15 +51,28 @@ module.exports = {
required: true,
columnName: 'user_id',
},
actionId: {
model: 'Action',
creatorUserId: {
model: 'User',
columnName: 'creator_user_id',
},
// Denormalization
boardId: {
model: 'Board',
required: true,
columnName: 'action_id',
columnName: 'board_id',
},
cardId: {
model: 'Card',
required: true,
columnName: 'card_id',
},
commentId: {
model: 'Comment',
columnName: 'comment_id',
},
actionId: {
model: 'Action',
columnName: 'action_id',
},
},
};

View file

@ -0,0 +1,56 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* NotificationService.js
*
* @description :: A model definition represents a database table/collection.
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
*/
const Formats = {
TEXT: 'text',
MARKDOWN: 'markdown',
HTML: 'html',
};
module.exports = {
Formats,
attributes: {
// ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗
// ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
// ╩ ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
url: {
type: 'string',
required: true,
},
format: {
type: 'string',
isIn: Object.values(Formats),
required: true,
},
// ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗
// ║╣ ║║║╠╩╗║╣ ║║╚═╗
// ╚═╝╩ ╩╚═╝╚═╝═╩╝╚═╝
// ╔═╗╔═╗╔═╗╔═╗╔═╗╦╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
// ╠═╣╚═╗╚═╗║ ║║ ║╠═╣ ║ ║║ ║║║║╚═╗
// ╩ ╩╚═╝╚═╝╚═╝╚═╝╩╩ ╩ ╩ ╩╚═╝╝╚╝╚═╝
userId: {
model: 'User',
columnName: 'user_id',
},
boardId: {
model: 'Board',
columnName: 'board_id',
},
},
tableName: 'notification_service',
};

View file

@ -1,3 +1,8 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* Project.js
*
@ -5,6 +10,11 @@
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
*/
const Types = {
PRIVATE: 'private',
SHARED: 'shared',
};
const BackgroundTypes = {
GRADIENT: 'gradient',
IMAGE: 'image',
@ -39,6 +49,7 @@ const BACKGROUND_GRADIENTS = [
];
module.exports = {
Types,
BackgroundTypes,
BACKGROUND_GRADIENTS,
@ -51,12 +62,27 @@ module.exports = {
type: 'string',
required: true,
},
background: {
type: 'json',
description: {
type: 'string',
isNotEmptyString: true,
allowNull: true,
},
backgroundImage: {
type: 'json',
columnName: 'background_image',
backgroundType: {
type: 'string',
isIn: Object.values(BackgroundTypes),
allowNull: true,
columnName: 'background_type',
},
backgroundGradient: {
type: 'string',
isIn: BACKGROUND_GRADIENTS,
allowNull: true,
columnName: 'background_gradient',
},
isHidden: {
type: 'boolean',
defaultsTo: false, // TODO: implement via normalizeValues?
columnName: 'is_hidden',
},
// ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗
@ -67,6 +93,14 @@ module.exports = {
// ╠═╣╚═╗╚═╗║ ║║ ║╠═╣ ║ ║║ ║║║║╚═╗
// ╩ ╩╚═╝╚═╝╚═╝╚═╝╩╩ ╩ ╩ ╩╚═╝╝╚╝╚═╝
ownerProjectManagerId: {
model: 'ProjectManager',
columnName: 'owner_project_manager_id',
},
backgroundImageId: {
model: 'BackgroundImage',
columnName: 'background_image_id',
},
managerUsers: {
collection: 'User',
via: 'projectId',
@ -77,16 +111,4 @@ module.exports = {
via: 'projectId',
},
},
customToJSON() {
const fileManager = sails.hooks['file-manager'].getInstance();
return {
..._.omit(this, ['backgroundImage']),
backgroundImage: this.backgroundImage && {
url: `${fileManager.buildUrl(`${sails.config.custom.projectBackgroundImagesPathSegment}/${this.backgroundImage.dirname}/original.${this.backgroundImage.extension}`)}`,
coverUrl: `${fileManager.buildUrl(`${sails.config.custom.projectBackgroundImagesPathSegment}/${this.backgroundImage.dirname}/cover-336.${this.backgroundImage.extension}`)}`,
},
};
},
};

View file

@ -0,0 +1,40 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* ProjectFavorite.js
*
* @description :: A model definition represents a database table/collection.
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
*/
module.exports = {
attributes: {
// ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗
// ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
// ╩ ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
// ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗
// ║╣ ║║║╠╩╗║╣ ║║╚═╗
// ╚═╝╩ ╩╚═╝╚═╝═╩╝╚═╝
// ╔═╗╔═╗╔═╗╔═╗╔═╗╦╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
// ╠═╣╚═╗╚═╗║ ║║ ║╠═╣ ║ ║║ ║║║║╚═╗
// ╩ ╩╚═╝╚═╝╚═╝╚═╝╩╩ ╩ ╩ ╩╚═╝╝╚╝╚═╝
projectId: {
model: 'Project',
required: true,
columnName: 'project_id',
},
userId: {
model: 'User',
required: true,
columnName: 'user_id',
},
},
tableName: 'project_favorite',
};

View file

@ -1,3 +1,8 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* ProjectManager.js
*

View file

@ -1,3 +1,8 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* Session.js
*

View file

@ -1,3 +1,8 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* Task.js
*
@ -33,10 +38,14 @@ module.exports = {
// ╠═╣╚═╗╚═╗║ ║║ ║╠═╣ ║ ║║ ║║║║╚═╗
// ╩ ╩╚═╝╚═╝╚═╝╚═╝╩╩ ╩ ╩ ╩╚═╝╝╚╝╚═╝
cardId: {
model: 'Card',
taskListId: {
model: 'TaskList',
required: true,
columnName: 'card_id',
columnName: 'task_list_id',
},
assigneeUserId: {
model: 'User',
columnName: 'assignee_user_id',
},
},
};

View file

@ -0,0 +1,49 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* TaskList.js
*
* @description :: A model definition represents a database table/collection.
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
*/
module.exports = {
attributes: {
// ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦ ╦╔═╗╔═╗
// ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
// ╩ ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
position: {
type: 'number',
required: true,
},
name: {
type: 'string',
required: true,
},
showOnFrontOfCard: {
type: 'boolean',
defaultsTo: true,
columnName: 'show_on_front_of_card',
},
// ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗
// ║╣ ║║║╠╩╗║╣ ║║╚═╗
// ╚═╝╩ ╩╚═╝╚═╝═╩╝╚═╝
// ╔═╗╔═╗╔═╗╔═╗╔═╗╦╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
// ╠═╣╚═╗╚═╗║ ║║ ║╠═╣ ║ ║║ ║║║║╚═╗
// ╩ ╩╚═╝╚═╝╚═╝╚═╝╩╩ ╩ ╩ ╩╚═╝╝╚╝╚═╝
cardId: {
model: 'Card',
required: true,
columnName: 'card_id',
},
},
tableName: 'task_list',
};

View file

@ -1,3 +1,8 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
/**
* User.js
*
@ -5,6 +10,29 @@
* @docs :: https://sailsjs.com/docs/concepts/models-and-orm/models
*/
const Roles = {
ADMIN: 'admin',
PROJECT_OWNER: 'projectOwner',
BOARD_USER: 'boardUser',
};
// TODO: should not be here
const EditorModes = {
WYSIWYG: 'wysiwyg',
MARKUP: 'markup',
};
const HomeViews = {
GRID_PROJECTS: 'gridProjects',
GROUPED_PROJECTS: 'groupedProjects',
};
const ProjectOrders = {
BY_DEFAULT: 'byDefault',
ALPHABETICALLY: 'alphabetically',
BY_CREATION_TIME: 'byCreationTime',
};
const LANGUAGES = [
'ar-YE',
'bg-BG',
@ -37,12 +65,31 @@ const LANGUAGES = [
'zh-TW',
];
const PRIVATE_FIELD_NAMES = ['email', 'isSsoUser'];
const PERSONAL_FIELD_NAMES = [
'language',
'subscribeToOwnCards',
'subscribeToCardWhenCommenting',
'turnOffRecentCardHighlighting',
'enableFavoritesByDefault',
'defaultEditorMode',
'defaultHomeView',
'defaultProjectsOrder',
];
const OIDC = {
id: '_oidc',
};
module.exports = {
Roles,
EditorModes,
HomeViews,
ProjectOrders,
LANGUAGES,
PRIVATE_FIELD_NAMES,
PERSONAL_FIELD_NAMES,
OIDC,
attributes: {
@ -57,16 +104,13 @@ module.exports = {
},
password: {
type: 'string',
isNotEmptyString: true,
allowNull: true,
},
isAdmin: {
type: 'boolean',
defaultsTo: false,
columnName: 'is_admin',
},
isSso: {
type: 'boolean',
defaultsTo: false,
columnName: 'is_sso',
role: {
type: 'string',
isIn: Object.values(Roles),
required: true,
},
name: {
type: 'string',
@ -103,9 +147,48 @@ module.exports = {
defaultsTo: false,
columnName: 'subscribe_to_own_cards',
},
deletedAt: {
type: 'ref',
columnName: 'deleted_at',
subscribeToCardWhenCommenting: {
type: 'boolean',
defaultsTo: true,
columnName: 'subscribe_to_card_when_commenting',
},
turnOffRecentCardHighlighting: {
type: 'boolean',
defaultsTo: false,
columnName: 'turn_off_recent_card_highlighting',
},
enableFavoritesByDefault: {
type: 'boolean',
defaultsTo: false,
columnName: 'enable_favorites_by_default',
},
defaultEditorMode: {
type: 'string',
isIn: Object.values(EditorModes),
defaultsTo: EditorModes.WYSIWYG,
columnName: 'default_editor_mode',
},
defaultHomeView: {
type: 'string',
isIn: Object.values(HomeViews),
defaultsTo: HomeViews.GROUPED_PROJECTS,
columnName: 'default_home_view',
},
defaultProjectsOrder: {
type: 'string',
isIn: Object.values(ProjectOrders),
defaultsTo: ProjectOrders.BY_DEFAULT,
columnName: 'default_projects_order',
},
isSsoUser: {
type: 'boolean',
defaultsTo: false,
columnName: 'is_sso_user',
},
isDeactivated: {
type: 'boolean',
defaultsTo: false,
columnName: 'is_deactivated',
},
passwordChangedAt: {
type: 'ref',
@ -140,27 +223,7 @@ module.exports = {
via: 'userId',
through: 'CardMembership',
},
identityProviders: {
collection: 'IdentityProviderUser',
via: 'userId',
},
},
tableName: 'user_account',
customToJSON() {
const fileManager = sails.hooks['file-manager'].getInstance();
const isDefaultAdmin = this.email === sails.config.custom.defaultAdminEmail;
return {
..._.omit(this, ['password', 'isSso', 'avatar', 'passwordChangedAt']),
isLocked: this.isSso || isDefaultAdmin,
isRoleLocked: (this.isSso && !sails.config.custom.oidcIgnoreRoles) || isDefaultAdmin,
isUsernameLocked: (this.isSso && !sails.config.custom.oidcIgnoreUsername) || isDefaultAdmin,
isDeletionLocked: isDefaultAdmin,
avatarUrl:
this.avatar &&
`${fileManager.buildUrl(`${sails.config.custom.userAvatarsPathSegment}/${this.avatar.dirname}/square-100.${this.avatar.extension}`)}`,
};
},
};