ref: Refactoring

This commit is contained in:
Maksim Eltyshev
2025-11-27 18:24:55 +01:00
parent 7be2343076
commit 54e230d4c1
80 changed files with 252 additions and 159 deletions
@@ -11,8 +11,8 @@ import { Link } from 'react-router-dom';
import { Comment } from 'semantic-ui-react'; import { Comment } from 'semantic-ui-react';
import selectors from '../../../selectors'; import selectors from '../../../selectors';
import { isUserStatic } from '../../../utils/record-helpers';
import Paths from '../../../constants/Paths'; import Paths from '../../../constants/Paths';
import { StaticUserIds } from '../../../constants/StaticUsers';
import { ActivityTypes } from '../../../constants/Enums'; import { ActivityTypes } from '../../../constants/Enums';
import TimeAgo from '../../common/TimeAgo'; import TimeAgo from '../../common/TimeAgo';
import UserAvatar from '../../users/UserAvatar'; import UserAvatar from '../../users/UserAvatar';
@@ -30,12 +30,11 @@ const Item = React.memo(({ id }) => {
const [t] = useTranslation(); const [t] = useTranslation();
const userName = const userName = isUserStatic(user)
user.id === StaticUserIds.DELETED ? t(`common.${user.name}`, {
? t(`common.${user.name}`, { context: 'title',
context: 'title', })
}) : user.name;
: user.name;
const cardName = card ? card.name : activity.data.card.name; const cardName = card ? card.name : activity.data.card.name;
@@ -10,7 +10,7 @@ import { useTranslation, Trans } from 'react-i18next';
import { Comment } from 'semantic-ui-react'; import { Comment } from 'semantic-ui-react';
import selectors from '../../../selectors'; import selectors from '../../../selectors';
import { StaticUserIds } from '../../../constants/StaticUsers'; import { isUserStatic } from '../../../utils/record-helpers';
import { ActivityTypes } from '../../../constants/Enums'; import { ActivityTypes } from '../../../constants/Enums';
import TimeAgo from '../../common/TimeAgo'; import TimeAgo from '../../common/TimeAgo';
import UserAvatar from '../../users/UserAvatar'; import UserAvatar from '../../users/UserAvatar';
@@ -26,12 +26,11 @@ const Item = React.memo(({ id }) => {
const [t] = useTranslation(); const [t] = useTranslation();
const userName = const userName = isUserStatic(user)
user.id === StaticUserIds.DELETED ? t(`common.${user.name}`, {
? t(`common.${user.name}`, { context: 'title',
context: 'title', })
}) : user.name;
: user.name;
let contentNode; let contentNode;
switch (activity.type) { switch (activity.type) {
@@ -15,13 +15,13 @@ import ListView from './ListView';
const FiniteContent = React.memo(() => { const FiniteContent = React.memo(() => {
const board = useSelector(selectors.selectCurrentBoard); const board = useSelector(selectors.selectCurrentBoard);
const cardIds = useSelector(selectors.selectFilteredCardIdsForCurrentBoard); const cardIds = useSelector(selectors.selectFilteredCardIdsForCurrentBoard);
const hasAnyFiniteList = useSelector((state) => !!selectors.selectFirstFiniteListId(state)); const canAddCard = useSelector((state) => !!selectors.selectFirstKanbanListId(state));
const dispatch = useDispatch(); const dispatch = useDispatch();
const handleCardCreate = useCallback( const handleCardCreate = useCallback(
(data, autoOpen) => { (data, autoOpen) => {
dispatch(entryActions.createCardInFirstFiniteList(data, undefined, autoOpen)); dispatch(entryActions.createCardInCurrentContext(data, undefined, autoOpen));
}, },
[dispatch], [dispatch],
); );
@@ -39,7 +39,7 @@ const FiniteContent = React.memo(() => {
default: default:
} }
return <View cardIds={cardIds} onCardCreate={hasAnyFiniteList ? handleCardCreate : undefined} />; return <View cardIds={cardIds} onCardCreate={canAddCard ? handleCardCreate : undefined} />;
}); });
export default FiniteContent; export default FiniteContent;
@@ -23,7 +23,7 @@ import styles from './KanbanContent.module.scss';
import globalStyles from '../../../../styles.module.scss'; import globalStyles from '../../../../styles.module.scss';
const KanbanContent = React.memo(() => { const KanbanContent = React.memo(() => {
const listIds = useSelector(selectors.selectFiniteListIdsForCurrentBoard); const listIds = useSelector(selectors.selectKanbanListIdsForCurrentBoard);
const canAddList = useSelector((state) => { const canAddList = useSelector((state) => {
const isEditModeEnabled = selectors.selectIsEditModeEnabled(state); // TODO: move out? const isEditModeEnabled = selectors.selectIsEditModeEnabled(state); // TODO: move out?
@@ -21,6 +21,7 @@
top: 2px; top: 2px;
transition: background 85ms ease; transition: background 85ms ease;
width: 20px; width: 20px;
z-index: 1000;
&:hover { &:hover {
background: #ebeef0; background: #ebeef0;
@@ -52,6 +53,7 @@
background: #fff; background: #fff;
border-radius: 3px; border-radius: 3px;
box-shadow: 0 1px 0 #ccc; box-shadow: 0 1px 0 #ccc;
overflow: hidden;
position: relative; position: relative;
&:hover { &:hover {
@@ -10,7 +10,7 @@ import { useTranslation } from 'react-i18next';
import { Icon } from 'semantic-ui-react'; import { Icon } from 'semantic-ui-react';
import selectors from '../../../selectors'; import selectors from '../../../selectors';
import { StaticUserIds } from '../../../constants/StaticUsers'; import { isUserStatic } from '../../../utils/record-helpers';
import TimeAgo from '../../common/TimeAgo'; import TimeAgo from '../../common/TimeAgo';
import UserAvatar from '../../users/UserAvatar'; import UserAvatar from '../../users/UserAvatar';
@@ -32,7 +32,7 @@ const CreationDetailsStep = React.memo(({ userId }) => {
</span> </span>
<span className={styles.content}> <span className={styles.content}>
<div className={styles.name}> <div className={styles.name}>
{user.id === StaticUserIds.DELETED {isUserStatic(user)
? t(`common.${user.name}`, { ? t(`common.${user.name}`, {
context: 'title', context: 'title',
}) })
@@ -9,32 +9,32 @@ import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Gallery, Item as GalleryItem } from 'react-photoswipe-gallery'; import { Gallery, Item as GalleryItem } from 'react-photoswipe-gallery';
import { Button, Grid, Icon } from 'semantic-ui-react'; import { Button, Grid, Icon } from 'semantic-ui-react';
import { useDidUpdate } from '../../../../lib/hooks'; import { useDidUpdate } from '../../../lib/hooks';
import selectors from '../../../../selectors'; import selectors from '../../../selectors';
import entryActions from '../../../../entry-actions'; import entryActions from '../../../entry-actions';
import { usePopupInClosableContext } from '../../../../hooks'; import { usePopupInClosableContext } from '../../../hooks';
import { isUsableMarkdownElement } from '../../../../utils/element-helpers'; import { isUsableMarkdownElement } from '../../../utils/element-helpers';
import { BoardMembershipRoles, CardTypes, ListTypes } from '../../../../constants/Enums'; import { BoardMembershipRoles, CardTypes, ListTypes } from '../../../constants/Enums';
import { CardTypeIcons } from '../../../../constants/Icons'; import { CardTypeIcons } from '../../../constants/Icons';
import { ClosableContext } from '../../../../contexts'; import { ClosableContext } from '../../../contexts';
import NameField from './NameField';
import Thumbnail from './Thumbnail'; import Thumbnail from './Thumbnail';
import NameField from '../NameField'; import CustomFieldGroups from './CustomFieldGroups';
import CustomFieldGroups from '../CustomFieldGroups'; import Communication from './Communication';
import Communication from '../Communication'; import CreationDetailsStep from './CreationDetailsStep';
import CreationDetailsStep from '../CreationDetailsStep'; import MoreActionsStep from './MoreActionsStep';
import MoreActionsStep from '../MoreActionsStep'; import Markdown from '../../common/Markdown';
import Markdown from '../../../common/Markdown'; import EditMarkdown from '../../common/EditMarkdown';
import EditMarkdown from '../../../common/EditMarkdown'; import ConfirmationStep from '../../common/ConfirmationStep';
import ConfirmationStep from '../../../common/ConfirmationStep'; import UserAvatar from '../../users/UserAvatar';
import UserAvatar from '../../../users/UserAvatar'; import BoardMembershipsStep from '../../board-memberships/BoardMembershipsStep';
import BoardMembershipsStep from '../../../board-memberships/BoardMembershipsStep'; import LabelChip from '../../labels/LabelChip';
import LabelChip from '../../../labels/LabelChip'; import LabelsStep from '../../labels/LabelsStep';
import LabelsStep from '../../../labels/LabelsStep'; import ListsStep from '../../lists/ListsStep';
import ListsStep from '../../../lists/ListsStep'; import Attachments from '../../attachments/Attachments';
import Attachments from '../../../attachments/Attachments'; import AddAttachmentStep from '../../attachments/AddAttachmentStep';
import AddAttachmentStep from '../../../attachments/AddAttachmentStep'; import AddCustomFieldGroupStep from '../../custom-field-groups/AddCustomFieldGroupStep';
import AddCustomFieldGroupStep from '../../../custom-field-groups/AddCustomFieldGroupStep';
import styles from './StoryContent.module.scss'; import styles from './StoryContent.module.scss';
@@ -99,7 +99,7 @@
} }
.coverWrapper { .coverWrapper {
padding-bottom: 20px; padding-bottom: 10px;
} }
.cursorPointer { .cursorPointer {
@@ -283,7 +283,7 @@
} }
.moduleWrapperAttachments { .moduleWrapperAttachments {
margin-bottom: 20px; margin-bottom: 10px;
} }
.moreActionsButton { .moreActionsButton {
@@ -1,8 +0,0 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
import StoryContent from './StoryContent';
export default StoryContent;
@@ -8,7 +8,7 @@ import PropTypes from 'prop-types';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { Item as GalleryItem } from 'react-photoswipe-gallery'; import { Item as GalleryItem } from 'react-photoswipe-gallery';
import selectors from '../../../../selectors'; import selectors from '../../../selectors';
import styles from './Thumbnail.module.scss'; import styles from './Thumbnail.module.scss';
@@ -14,8 +14,7 @@ import { useDidUpdate } from '../../../lib/hooks';
import selectors from '../../../selectors'; import selectors from '../../../selectors';
import entryActions from '../../../entry-actions'; import entryActions from '../../../entry-actions';
import { usePopupInClosableContext } from '../../../hooks'; import { usePopupInClosableContext } from '../../../hooks';
import { isListArchiveOrTrash } from '../../../utils/record-helpers'; import { isListArchiveOrTrash, isUserStatic } from '../../../utils/record-helpers';
import { StaticUserIds } from '../../../constants/StaticUsers';
import { BoardMembershipRoles } from '../../../constants/Enums'; import { BoardMembershipRoles } from '../../../constants/Enums';
import { ClosableContext } from '../../../contexts'; import { ClosableContext } from '../../../contexts';
import Edit from './Edit'; import Edit from './Edit';
@@ -107,7 +106,7 @@ const Item = React.memo(({ id }) => {
) : ( ) : (
<div className={classNames(styles.bubble, isCurrentUser && styles.bubbleRight)}> <div className={classNames(styles.bubble, isCurrentUser && styles.bubbleRight)}>
<div className={styles.header}> <div className={styles.header}>
{user.id === StaticUserIds.DELETED {isUserStatic(user)
? t(`common.${user.name}`, { ? t(`common.${user.name}`, {
context: 'title', context: 'title',
}) })
@@ -17,9 +17,9 @@ import AddStep from './AddStep';
import styles from './UsersPane.module.scss'; import styles from './UsersPane.module.scss';
const UsersPane = React.memo(() => { const UsersPane = React.memo(() => {
const activeUsersTotal = useSelector(selectors.selectActiveUsersTotal);
const activeUsersLimit = useSelector(selectors.selectActiveUsersLimit); const activeUsersLimit = useSelector(selectors.selectActiveUsersLimit);
const users = useSelector(selectors.selectUsers); const users = useSelector(selectors.selectUsers);
const activeUsersTotal = useSelector(selectors.selectActiveUsersTotal);
const canAdd = useSelector((state) => { const canAdd = useSelector((state) => {
const oidcBootstrap = selectors.selectOidcBootstrap(state); const oidcBootstrap = selectors.selectOidcBootstrap(state);
@@ -12,7 +12,7 @@ import selectors from '../../../selectors';
import matchPaths from '../../../utils/match-paths'; import matchPaths from '../../../utils/match-paths';
import Paths from '../../../constants/Paths'; import Paths from '../../../constants/Paths';
const Linkify = React.memo(({ href, content, stopPropagation, ...props }) => { const Link = React.memo(({ href, content, stopPropagation, ...props }) => {
const selectCardById = useMemo(() => selectors.makeSelectCardById(), []); const selectCardById = useMemo(() => selectors.makeSelectCardById(), []);
const url = useMemo(() => { const url = useMemo(() => {
@@ -68,14 +68,14 @@ const Linkify = React.memo(({ href, content, stopPropagation, ...props }) => {
); );
}); });
Linkify.propTypes = { Link.propTypes = {
href: PropTypes.string.isRequired, href: PropTypes.string.isRequired,
content: PropTypes.string.isRequired, content: PropTypes.string.isRequired,
stopPropagation: PropTypes.bool, stopPropagation: PropTypes.bool,
}; };
Linkify.defaultProps = { Link.defaultProps = {
stopPropagation: false, stopPropagation: false,
}; };
export default Linkify; export default Link;
@@ -14,8 +14,8 @@ import { Button } from 'semantic-ui-react';
import selectors from '../../../selectors'; import selectors from '../../../selectors';
import entryActions from '../../../entry-actions'; import entryActions from '../../../entry-actions';
import { mentionMarkupToText } from '../../../utils/mentions'; import { mentionMarkupToText } from '../../../utils/mentions';
import { isUserStatic } from '../../../utils/record-helpers';
import Paths from '../../../constants/Paths'; import Paths from '../../../constants/Paths';
import { StaticUserIds } from '../../../constants/StaticUsers';
import { NotificationTypes } from '../../../constants/Enums'; import { NotificationTypes } from '../../../constants/Enums';
import TimeAgo from '../../common/TimeAgo'; import TimeAgo from '../../common/TimeAgo';
import UserAvatar from '../../users/UserAvatar'; import UserAvatar from '../../users/UserAvatar';
@@ -42,12 +42,11 @@ const Item = React.memo(({ id, onClose }) => {
dispatch(entryActions.deleteNotification(id)); dispatch(entryActions.deleteNotification(id));
}, [id, dispatch]); }, [id, dispatch]);
const creatorUserName = const creatorUserName = isUserStatic(creatorUser)
creatorUser.id === StaticUserIds.DELETED ? t(`common.${creatorUser.name}`, {
? t(`common.${creatorUser.name}`, { context: 'title',
context: 'title', })
}) : creatorUser.name;
: creatorUser.name;
const cardName = card ? card.name : notification.data.card.name; const cardName = card ? card.name : notification.data.card.name;
@@ -13,7 +13,7 @@ import { useSelector } from 'react-redux';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import selectors from '../../../selectors'; import selectors from '../../../selectors';
import { StaticUserIds } from '../../../constants/StaticUsers'; import { isUserStatic } from '../../../utils/record-helpers';
import styles from './UserAvatar.module.scss'; import styles from './UserAvatar.module.scss';
@@ -62,7 +62,7 @@ const UserAvatar = React.memo(
const contentNode = ( const contentNode = (
<span <span
title={ title={
user.id === StaticUserIds.DELETED isUserStatic(user)
? t(`common.${user.name}`, { ? t(`common.${user.name}`, {
context: 'title', context: 'title',
}) })
+1 -1
View File
@@ -186,7 +186,7 @@ export default {
CARDS_IN_CURRENT_LIST_FETCH: `${PREFIX}/CARDS_IN_CURRENT_LIST_FETCH`, CARDS_IN_CURRENT_LIST_FETCH: `${PREFIX}/CARDS_IN_CURRENT_LIST_FETCH`,
CARDS_UPDATE_HANDLE: `${PREFIX}/CARDS_UPDATE_HANDLE`, CARDS_UPDATE_HANDLE: `${PREFIX}/CARDS_UPDATE_HANDLE`,
CARD_CREATE: `${PREFIX}/CARD_CREATE`, CARD_CREATE: `${PREFIX}/CARD_CREATE`,
CARD_IN_FIRST_FINITE_LIST_CREATE: `${PREFIX}/CARD_IN_FIRST_FINITE_LIST_CREATE`, CARD_IN_CURRENT_CONTEXT_CREATE: `${PREFIX}/CARD_IN_CURRENT_CONTEXT_CREATE`,
CARD_IN_CURRENT_LIST_CREATE: `${PREFIX}/CARD_IN_CURRENT_LIST_CREATE`, CARD_IN_CURRENT_LIST_CREATE: `${PREFIX}/CARD_IN_CURRENT_LIST_CREATE`,
CARD_CREATE_HANDLE: `${PREFIX}/CARD_CREATE_HANDLE`, CARD_CREATE_HANDLE: `${PREFIX}/CARD_CREATE_HANDLE`,
CARD_UPDATE: `${PREFIX}/CARD_UPDATE`, CARD_UPDATE: `${PREFIX}/CARD_UPDATE`,
+3 -3
View File
@@ -28,8 +28,8 @@ const createCard = (listId, data, index, autoOpen = false) => ({
}, },
}); });
const createCardInFirstFiniteList = (data, index = 0, autoOpen = false) => ({ const createCardInCurrentContext = (data, index = 0, autoOpen = false) => ({
type: EntryActionTypes.CARD_IN_FIRST_FINITE_LIST_CREATE, type: EntryActionTypes.CARD_IN_CURRENT_CONTEXT_CREATE,
payload: { payload: {
data, data,
index, index,
@@ -180,7 +180,7 @@ export default {
fetchCardsInCurrentList, fetchCardsInCurrentList,
handleCardsUpdate, handleCardsUpdate,
createCard, createCard,
createCardInFirstFiniteList, createCardInCurrentContext,
createCardInCurrentList, createCardInCurrentList,
handleCardCreate, handleCardCreate,
updateCard, updateCard,
+4 -4
View File
@@ -7,7 +7,7 @@ import { attr, fk, many } from 'redux-orm';
import BaseModel from './BaseModel'; import BaseModel from './BaseModel';
import buildSearchParts from '../utils/build-search-parts'; import buildSearchParts from '../utils/build-search-parts';
import { isListFinite } from '../utils/record-helpers'; import { isListKanban } from '../utils/record-helpers';
import ActionTypes from '../constants/ActionTypes'; import ActionTypes from '../constants/ActionTypes';
import Config from '../constants/Config'; import Config from '../constants/Config';
import { BoardContexts, BoardViews } from '../constants/Enums'; import { BoardContexts, BoardViews } from '../constants/Enums';
@@ -285,8 +285,8 @@ export default class extends BaseModel {
return this.lists.orderBy(['position', 'id.length', 'id']); return this.lists.orderBy(['position', 'id.length', 'id']);
} }
getFiniteListsQuerySet() { getKanbanListsQuerySet() {
return this.getListsQuerySet().filter((list) => isListFinite(list)); return this.getListsQuerySet().filter((list) => isListKanban(list));
} }
getCustomFieldGroupsQuerySet() { getCustomFieldGroupsQuerySet() {
@@ -316,7 +316,7 @@ export default class extends BaseModel {
} }
getCardsModelArray() { getCardsModelArray() {
return this.getFiniteListsQuerySet() return this.getKanbanListsQuerySet()
.toModelArray() .toModelArray()
.flatMap((listModel) => listModel.getCardsModelArray()); .flatMap((listModel) => listModel.getCardsModelArray());
} }
+5 -7
View File
@@ -336,13 +336,11 @@ export default class extends BaseModel {
return []; return [];
} }
if (searchRegex) { cardModels = cardModels.filter(
cardModels = cardModels.filter( (cardModel) =>
(cardModel) => searchRegex.test(cardModel.name) ||
searchRegex.test(cardModel.name) || (cardModel.description && searchRegex.test(cardModel.description)),
(cardModel.description && searchRegex.test(cardModel.description)), );
);
}
} else { } else {
const searchParts = buildSearchParts(this.board.search); const searchParts = buildSearchParts(this.board.search);
+4 -4
View File
@@ -167,10 +167,10 @@ export function* createCard(listId, data, index, autoOpen) {
} }
} }
export function* createCardInFirstFiniteList(data, index, autoOpen) { export function* createCardInCurrentContext(data, index, autoOpen) {
const firstFiniteListId = yield select(selectors.selectFirstFiniteListId); const firstKanbanListId = yield select(selectors.selectFirstKanbanListId);
yield call(createCard, firstFiniteListId, data, index, autoOpen); yield call(createCard, firstKanbanListId, data, index, autoOpen);
} }
export function* createCardInCurrentList(data, autoOpen) { export function* createCardInCurrentList(data, autoOpen) {
@@ -601,7 +601,7 @@ export default {
fetchCardsInCurrentList, fetchCardsInCurrentList,
handleCardsUpdate, handleCardsUpdate,
createCard, createCard,
createCardInFirstFiniteList, createCardInCurrentContext,
createCardInCurrentList, createCardInCurrentList,
handleCardCreate, handleCardCreate,
updateCard, updateCard,
+2 -2
View File
@@ -20,9 +20,9 @@ export default function* cardsWatchers() {
services.createCard(listId, data, index, autoOpen), services.createCard(listId, data, index, autoOpen),
), ),
takeEvery( takeEvery(
EntryActionTypes.CARD_IN_FIRST_FINITE_LIST_CREATE, EntryActionTypes.CARD_IN_CURRENT_CONTEXT_CREATE,
({ payload: { data, index, autoOpen } }) => ({ payload: { data, index, autoOpen } }) =>
services.createCardInFirstFiniteList(data, index, autoOpen), services.createCardInCurrentContext(data, index, autoOpen),
), ),
takeEvery(EntryActionTypes.CARD_IN_CURRENT_LIST_CREATE, ({ payload: { data, autoOpen } }) => takeEvery(EntryActionTypes.CARD_IN_CURRENT_LIST_CREATE, ({ payload: { data, autoOpen } }) =>
services.createCardInCurrentList(data, autoOpen), services.createCardInCurrentList(data, autoOpen),
+3 -3
View File
@@ -271,7 +271,7 @@ export const selectTrashListIdForCurrentBoard = createSelector(
}, },
); );
export const selectFiniteListIdsForCurrentBoard = createSelector( export const selectKanbanListIdsForCurrentBoard = createSelector(
orm, orm,
(state) => selectPath(state).boardId, (state) => selectPath(state).boardId,
({ Board }, id) => { ({ Board }, id) => {
@@ -286,7 +286,7 @@ export const selectFiniteListIdsForCurrentBoard = createSelector(
} }
return boardModel return boardModel
.getFiniteListsQuerySet() .getKanbanListsQuerySet()
.toRefArray() .toRefArray()
.map((list) => list.id); .map((list) => list.id);
}, },
@@ -482,7 +482,7 @@ export default {
selectLabelsForCurrentBoard, selectLabelsForCurrentBoard,
selectArchiveListIdForCurrentBoard, selectArchiveListIdForCurrentBoard,
selectTrashListIdForCurrentBoard, selectTrashListIdForCurrentBoard,
selectFiniteListIdsForCurrentBoard, selectKanbanListIdsForCurrentBoard,
selectAvailableListsForCurrentBoard, selectAvailableListsForCurrentBoard,
selectCardsExceptCurrentForCurrentBoard, selectCardsExceptCurrentForCurrentBoard,
selectFilteredCardIdsForCurrentBoard, selectFilteredCardIdsForCurrentBoard,
+3 -3
View File
@@ -127,7 +127,7 @@ export const selectCurrentList = createSelector(
}, },
); );
export const selectFirstFiniteListId = createSelector( export const selectFirstKanbanListId = createSelector(
orm, orm,
(state) => selectPath(state).boardId, (state) => selectPath(state).boardId,
({ Board }, id) => { ({ Board }, id) => {
@@ -141,7 +141,7 @@ export const selectFirstFiniteListId = createSelector(
return boardModel; return boardModel;
} }
const listModel = boardModel.getFiniteListsQuerySet().first(); const listModel = boardModel.getKanbanListsQuerySet().first();
return listModel && listModel.id; return listModel && listModel.id;
}, },
); );
@@ -174,6 +174,6 @@ export default {
selectIsListWithIdAvailableForCurrentUser, selectIsListWithIdAvailableForCurrentUser,
selectCurrentListId, selectCurrentListId,
selectCurrentList, selectCurrentList,
selectFirstFiniteListId, selectFirstKanbanListId,
selectFilteredCardIdsForCurrentList, selectFilteredCardIdsForCurrentList,
}; };
+1 -1
View File
@@ -75,7 +75,7 @@ export const selectNextListPosition = createSelector(
return boardModel; return boardModel;
} }
return nextPosition(boardModel.getFiniteListsQuerySet().toRefArray(), index, excludedId); return nextPosition(boardModel.getKanbanListsQuerySet().toRefArray(), index, excludedId);
}, },
); );
+5
View File
@@ -3,8 +3,11 @@
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/ */
import { StaticUserIds } from '../constants/StaticUsers';
import { ListTypes, UserRoles } from '../constants/Enums'; import { ListTypes, UserRoles } from '../constants/Enums';
export const isUserStatic = (user) => [StaticUserIds.DELETED].includes(user.id);
export const isUserAdminOrProjectOwner = (user) => export const isUserAdminOrProjectOwner = (user) =>
[UserRoles.ADMIN, UserRoles.PROJECT_OWNER].includes(user.role); [UserRoles.ADMIN, UserRoles.PROJECT_OWNER].includes(user.role);
@@ -12,3 +15,5 @@ export const isListArchiveOrTrash = (list) =>
[ListTypes.ARCHIVE, ListTypes.TRASH].includes(list.type); [ListTypes.ARCHIVE, ListTypes.TRASH].includes(list.type);
export const isListFinite = (list) => [ListTypes.ACTIVE, ListTypes.CLOSED].includes(list.type); export const isListFinite = (list) => [ListTypes.ACTIVE, ListTypes.CLOSED].includes(list.type);
export const isListKanban = (list) => [ListTypes.ACTIVE, ListTypes.CLOSED].includes(list.type);
+1
View File
@@ -11,6 +11,7 @@ const USERNAME_REGEX = /^[a-zA-Z0-9]+((_|\.)?[a-zA-Z0-9])*$/;
export const isUrl = (string) => export const isUrl = (string) =>
isURL(string, { isURL(string, {
protocols: ['http', 'https'], protocols: ['http', 'https'],
require_tld: false,
require_protocol: true, require_protocol: true,
max_allowed_length: 2048, max_allowed_length: 2048,
}); });
+2 -2
View File
@@ -23,10 +23,10 @@
* - name: before * - name: before
* in: query * in: query
* required: false * required: false
* description: Pagination cursor (JSON object with id and listChangedAt) * description: Pagination cursor (JSON object with listChangedAt and id)
* schema: * schema:
* type: string * type: string
* example: '{"id": "1357158568008091269", "listChangedAt": "2024-01-01T00:00:00.000Z"}' * example: '{"listChangedAt": "2024-01-01T00:00:00.000Z", "id": "1357158568008091269"}'
* - name: search * - name: search
* in: query * in: query
* required: false * required: false
+1 -1
View File
@@ -87,7 +87,7 @@ module.exports = {
}, },
type: { type: {
type: 'string', type: 'string',
isIn: List.FINITE_TYPES, isIn: List.KANBAN_TYPES,
required: true, required: true,
}, },
position: { position: {
+1 -1
View File
@@ -100,7 +100,7 @@ module.exports = {
throw Errors.LIST_NOT_FOUND; // Forbidden throw Errors.LIST_NOT_FOUND; // Forbidden
} }
if (!sails.helpers.lists.isFinite(list)) { if (!sails.helpers.lists.isKanban(list)) {
throw Errors.NOT_ENOUGH_RIGHTS; throw Errors.NOT_ENOUGH_RIGHTS;
} }
+2 -2
View File
@@ -97,7 +97,7 @@ module.exports = {
boardId: idInput, boardId: idInput,
type: { type: {
type: 'string', type: 'string',
isIn: List.FINITE_TYPES, isIn: List.KANBAN_TYPES,
}, },
position: { position: {
type: 'number', type: 'number',
@@ -146,7 +146,7 @@ module.exports = {
throw Errors.LIST_NOT_FOUND; // Forbidden throw Errors.LIST_NOT_FOUND; // Forbidden
} }
if (!sails.helpers.lists.isFinite(list)) { if (!sails.helpers.lists.isKanban(list)) {
throw Errors.NOT_ENOUGH_RIGHTS; throw Errors.NOT_ENOUGH_RIGHTS;
} }
+1 -1
View File
@@ -14,7 +14,7 @@
* operationId: getUsers * operationId: getUsers
* responses: * responses:
* 200: * 200:
* description: List of users retrieved successfully * description: Users retrieved successfully
* content: * content:
* application/json: * application/json:
* schema: * schema:
+1 -1
View File
@@ -14,7 +14,7 @@
* operationId: getWebhooks * operationId: getWebhooks
* responses: * responses:
* 200: * 200:
* description: List of webhooks retrieved successfully * description: Webhooks retrieved successfully
* content: * content:
* application/json: * application/json:
* schema: * schema:
+3 -3
View File
@@ -23,7 +23,7 @@ const buildBodyByFormat = (board, card, action, actorUser, t) => {
switch (action.type) { switch (action.type) {
case Action.Types.CREATE_CARD: { case Action.Types.CREATE_CARD: {
const listName = sails.helpers.lists.makeName(action.data.list); const listName = sails.helpers.lists.resolveName(action.data.list, t);
return { return {
text: t('%s created %s in %s on %s', actorUser.name, card.name, listName, board.name), text: t('%s created %s in %s on %s', actorUser.name, card.name, listName, board.name),
@@ -44,8 +44,8 @@ const buildBodyByFormat = (board, card, action, actorUser, t) => {
}; };
} }
case Action.Types.MOVE_CARD: { case Action.Types.MOVE_CARD: {
const fromListName = sails.helpers.lists.makeName(action.data.fromList); const fromListName = sails.helpers.lists.resolveName(action.data.fromList, t);
const toListName = sails.helpers.lists.makeName(action.data.toList); const toListName = sails.helpers.lists.resolveName(action.data.toList, t);
return { return {
text: t( text: t(
@@ -17,7 +17,7 @@ module.exports = {
async fn(inputs) { async fn(inputs) {
return List.qm.getByBoardId(inputs.id, { return List.qm.getByBoardId(inputs.id, {
exceptIdOrIds: inputs.exceptListIdOrIds, exceptIdOrIds: inputs.exceptListIdOrIds,
typeOrTypes: List.FINITE_TYPES, typeOrTypes: List.KANBAN_TYPES,
}); });
}, },
}; };
+20 -6
View File
@@ -41,12 +41,26 @@ module.exports = {
async fn(inputs) { async fn(inputs) {
const { values } = inputs; const { values } = inputs;
if (sails.helpers.lists.isFinite(inputs.list)) { if (values.list) {
const typeState = List.TYPE_STATE_BY_TYPE[values.list.type];
if (inputs.record.isClosed) {
if (typeState === List.TypeStates.OPENED) {
values.isClosed = false;
}
} else if (typeState === List.TypeStates.CLOSED) {
values.isClosed = true;
}
}
const list = values.list || inputs.list;
if (sails.helpers.lists.isFinite(list)) {
if (_.isUndefined(values.position)) { if (_.isUndefined(values.position)) {
throw 'positionMustBeInValues'; throw 'positionMustBeInValues';
} }
const cards = await Card.qm.getByListId(inputs.list.id); const cards = await Card.qm.getByListId(list.id);
const { position, repositions } = sails.helpers.utils.insertToPositionables( const { position, repositions } = sails.helpers.utils.insertToPositionables(
values.position, values.position,
@@ -84,7 +98,6 @@ module.exports = {
let card = await Card.qm.createOne({ let card = await Card.qm.createOne({
..._.pick(inputs.record, [ ..._.pick(inputs.record, [
'boardId', 'boardId',
'listId',
'prevListId', 'prevListId',
'type', 'type',
'name', 'name',
@@ -95,6 +108,7 @@ module.exports = {
'isClosed', 'isClosed',
]), ]),
...values, ...values,
listId: list.id,
creatorUserId: values.creatorUser.id, creatorUserId: values.creatorUser.id,
listChangedAt: new Date().toISOString(), listChangedAt: new Date().toISOString(),
}); });
@@ -240,7 +254,7 @@ module.exports = {
included: { included: {
projects: [inputs.project], projects: [inputs.project],
boards: [inputs.board], boards: [inputs.board],
lists: [inputs.list], lists: [list],
cardMemberships: nextCardMemberships, cardMemberships: nextCardMemberships,
cardLabels: nextCardLabels, cardLabels: nextCardLabels,
taskLists: nextTaskLists, taskLists: nextTaskLists,
@@ -277,19 +291,19 @@ module.exports = {
} }
await sails.helpers.actions.createOne.with({ await sails.helpers.actions.createOne.with({
list,
webhooks, webhooks,
values: { values: {
card, card,
type: Action.Types.CREATE_CARD, // TODO: introduce separate type? type: Action.Types.CREATE_CARD, // TODO: introduce separate type?
data: { data: {
card: _.pick(card, ['name']), card: _.pick(card, ['name']),
list: _.pick(inputs.list, ['id', 'type', 'name']), list: _.pick(list, ['id', 'type', 'name']),
}, },
user: values.creatorUser, user: values.creatorUser,
}, },
project: inputs.project, project: inputs.project,
board: inputs.board, board: inputs.board,
list: inputs.list,
}); });
return { return {
+1 -1
View File
@@ -25,7 +25,7 @@ module.exports = {
async fn(inputs) { async fn(inputs) {
const { values } = inputs; const { values } = inputs;
const lists = await sails.helpers.boards.getFiniteListsById(values.board.id); const lists = await sails.helpers.boards.getKanbanListsById(values.board.id);
const { position, repositions } = sails.helpers.utils.insertToPositionables( const { position, repositions } = sails.helpers.utils.insertToPositionables(
values.position, values.position,
@@ -3,7 +3,6 @@
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/ */
// TODO: rename?
module.exports = { module.exports = {
sync: true, sync: true,
@@ -15,6 +14,6 @@ module.exports = {
}, },
fn(inputs) { fn(inputs) {
return inputs.record.name || _.upperFirst(inputs.record.type); return List.KANBAN_TYPES.includes(inputs.record.type);
}, },
}; };
+27
View File
@@ -0,0 +1,27 @@
/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
module.exports = {
sync: true,
inputs: {
record: {
type: 'ref',
required: true,
},
t: {
type: 'ref',
},
},
fn(inputs) {
if (inputs.record.name) {
return inputs.record.name;
}
const name = _.upperFirst(inputs.record.type);
return inputs.t ? inputs.t(name) : name;
},
};
+1 -1
View File
@@ -58,7 +58,7 @@ module.exports = {
const board = values.board || inputs.board; const board = values.board || inputs.board;
if (!_.isUndefined(values.position)) { if (!_.isUndefined(values.position)) {
const lists = await sails.helpers.boards.getFiniteListsById(board.id, inputs.record.id); const lists = await sails.helpers.boards.getKanbanListsById(board.id, inputs.record.id);
const { position, repositions } = sails.helpers.utils.insertToPositionables( const { position, repositions } = sails.helpers.utils.insertToPositionables(
values.position, values.position,
@@ -29,8 +29,8 @@ const buildBodyByFormat = (board, card, notification, actorUser, t) => {
switch (notification.type) { switch (notification.type) {
case Notification.Types.MOVE_CARD: { case Notification.Types.MOVE_CARD: {
const fromListName = sails.helpers.lists.makeName(notification.data.fromList); const fromListName = sails.helpers.lists.resolveName(notification.data.fromList, t);
const toListName = sails.helpers.lists.makeName(notification.data.toList); const toListName = sails.helpers.lists.resolveName(notification.data.toList, t);
return { return {
text: t( text: t(
@@ -144,8 +144,8 @@ const buildEmail = (board, card, notification, actorUser, notifiableUser, t) =>
let html; let html;
switch (notification.type) { switch (notification.type) {
case Notification.Types.MOVE_CARD: { case Notification.Types.MOVE_CARD: {
const fromListName = sails.helpers.lists.makeName(notification.data.fromList); const fromListName = sails.helpers.lists.resolveName(notification.data.fromList, t);
const toListName = sails.helpers.lists.makeName(notification.data.toList); const toListName = sails.helpers.lists.resolveName(notification.data.toList, t);
html = `<p>${t( html = `<p>${t(
'%s moved %s from %s to %s on %s', '%s moved %s from %s to %s on %s',
@@ -243,10 +243,6 @@ module.exports = {
arrayOfValues.map((values) => { arrayOfValues.map((values) => {
const id = ids.shift(); const id = ids.shift();
const isCommentRelated =
values.type === Notification.Types.COMMENT_CARD ||
values.type === Notification.Types.MENTION_IN_COMMENT;
const nextValues = { const nextValues = {
...values, ...values,
id, id,
@@ -254,10 +250,10 @@ module.exports = {
boardId: values.card.boardId, boardId: values.card.boardId,
cardId: values.card.id, cardId: values.card.id,
}; };
if (values.comment) {
if (isCommentRelated) {
nextValues.commentId = values.comment.id; nextValues.commentId = values.comment.id;
} else { }
if (values.action) {
nextValues.actionId = values.action.id; nextValues.actionId = values.action.id;
} }
+14 -17
View File
@@ -29,8 +29,8 @@ const buildBodyByFormat = (board, card, notification, actorUser, t) => {
switch (notification.type) { switch (notification.type) {
case Notification.Types.MOVE_CARD: { case Notification.Types.MOVE_CARD: {
const fromListName = sails.helpers.lists.makeName(notification.data.fromList); const fromListName = sails.helpers.lists.resolveName(notification.data.fromList, t);
const toListName = sails.helpers.lists.makeName(notification.data.toList); const toListName = sails.helpers.lists.resolveName(notification.data.toList, t);
return { return {
text: t( text: t(
@@ -152,8 +152,8 @@ const buildAndSendEmail = async (
let html; let html;
switch (notification.type) { switch (notification.type) {
case Notification.Types.MOVE_CARD: { case Notification.Types.MOVE_CARD: {
const fromListName = sails.helpers.lists.makeName(notification.data.fromList); const fromListName = sails.helpers.lists.resolveName(notification.data.fromList, t);
const toListName = sails.helpers.lists.makeName(notification.data.toList); const toListName = sails.helpers.lists.resolveName(notification.data.toList, t);
html = `<p>${t( html = `<p>${t(
'%s moved %s from %s to %s on %s', '%s moved %s from %s to %s on %s',
@@ -234,13 +234,11 @@ module.exports = {
async fn(inputs) { async fn(inputs) {
const { values } = inputs; const { values } = inputs;
const isCommentRelated = if (values.comment) {
values.type === Notification.Types.COMMENT_CARD ||
values.type === Notification.Types.MENTION_IN_COMMENT;
if (isCommentRelated) {
values.commentId = values.comment.id; values.commentId = values.comment.id;
} else { }
if (values.action) {
values.actionId = values.action.id; values.actionId = values.action.id;
} }
@@ -268,13 +266,12 @@ module.exports = {
boards: [inputs.board], boards: [inputs.board],
lists: [inputs.list], lists: [inputs.list],
cards: [values.card], cards: [values.card],
...(isCommentRelated ...(values.comment && {
? { comments: [values.comment],
comments: [values.comment], }),
} ...(values.action && {
: { actions: [values.action],
actions: [values.action], }),
}),
}, },
}), }),
user: values.creatorUser, user: values.creatorUser,
+1
View File
@@ -7,6 +7,7 @@ module.exports = {
inputs: { inputs: {
roleOrRoles: { roleOrRoles: {
type: 'json', type: 'json',
required: true,
}, },
}, },
@@ -56,19 +56,12 @@ const getIdsByEndlessListId = async (
const searchParts = buildSearchParts(search); const searchParts = buildSearchParts(search);
if (searchParts.length > 0) { if (searchParts.length > 0) {
let ilikeValues = searchParts.map((searchPart) => { const ilikeValues = searchParts.map((searchPart) => {
queryValues.push(searchPart); queryValues.push(searchPart);
return `'%' || $${queryValues.length} || '%'`; return `'%' || $${queryValues.length} || '%'`;
}); });
query += ` AND ((card.name ILIKE ALL(ARRAY[${ilikeValues.join(', ')}]))`; query += ` AND ((card.name ILIKE ALL(ARRAY[${ilikeValues.join(', ')}])) OR (card.description ILIKE ALL(ARRAY[${ilikeValues.join(', ')}])))`;
ilikeValues = searchParts.map((searchPart) => {
queryValues.push(searchPart);
return `'%' || $${queryValues.length} || '%'`;
});
query += ` OR (card.description ILIKE ALL(ARRAY[${ilikeValues.join(', ')}])))`;
} }
} }
} }
+3
View File
@@ -95,6 +95,8 @@ const SortOrders = {
const FINITE_TYPES = [Types.ACTIVE, Types.CLOSED]; const FINITE_TYPES = [Types.ACTIVE, Types.CLOSED];
const KANBAN_TYPES = [Types.ACTIVE, Types.CLOSED];
const TYPE_STATE_BY_TYPE = { const TYPE_STATE_BY_TYPE = {
[Types.ACTIVE]: TypeStates.OPENED, [Types.ACTIVE]: TypeStates.OPENED,
[Types.CLOSED]: Types.CLOSED, [Types.CLOSED]: Types.CLOSED,
@@ -119,6 +121,7 @@ module.exports = {
SortFieldNames, SortFieldNames,
SortOrders, SortOrders,
FINITE_TYPES, FINITE_TYPES,
KANBAN_TYPES,
TYPE_STATE_BY_TYPE, TYPE_STATE_BY_TYPE,
COLORS, COLORS,
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "أرشيف",
"Card Created": "تم إنشاء البطاقة", "Card Created": "تم إنشاء البطاقة",
"Card Moved": "تم نقل البطاقة", "Card Moved": "تم نقل البطاقة",
"New Comment": "تعليق جديد", "New Comment": "تعليق جديد",
@@ -6,6 +7,7 @@
"This is a test text message!": "هذه رسالة نصية تجريبية!", "This is a test text message!": "هذه رسالة نصية تجريبية!",
"This is a *test* **markdown** `message`!": "هذه *رسالة* **markdown** `تجريبية`!", "This is a *test* **markdown** `message`!": "هذه *رسالة* **markdown** `تجريبية`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "هذه <i>رسالة</i> <b>html</b> <code>تجريبية</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "هذه <i>رسالة</i> <b>html</b> <code>تجريبية</code>!",
"Trash": "سلة المهملات",
"You Were Added to Card": "تمت إضافتك إلى البطاقة", "You Were Added to Card": "تمت إضافتك إلى البطاقة",
"You Were Mentioned in Comment": "تم ذكرك في تعليق", "You Were Mentioned in Comment": "تم ذكرك في تعليق",
"%s added you to %s on %s": "%s أضافك إلى %s في %s", "%s added you to %s on %s": "%s أضافك إلى %s في %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Архив",
"Card Created": "Картата е създадена", "Card Created": "Картата е създадена",
"Card Moved": "Картата е преместена", "Card Moved": "Картата е преместена",
"New Comment": "Нов коментар", "New Comment": "Нов коментар",
@@ -6,6 +7,7 @@
"This is a test text message!": "Това е тестово текстово съобщение!", "This is a test text message!": "Това е тестово текстово съобщение!",
"This is a *test* **markdown** `message`!": "Това е *тестово* **markdown** `съобщение`!", "This is a *test* **markdown** `message`!": "Това е *тестово* **markdown** `съобщение`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Това е <i>тестово</i> <b>html</b> <code>съобщение</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Това е <i>тестово</i> <b>html</b> <code>съобщение</code>!",
"Trash": "Кошче",
"You Were Added to Card": "Бяхте добавени към картата", "You Were Added to Card": "Бяхте добавени към картата",
"You Were Mentioned in Comment": "Бяхте споменати в коментар", "You Were Mentioned in Comment": "Бяхте споменати в коментар",
"%s added you to %s on %s": "%s ви добави към %s на %s", "%s added you to %s on %s": "%s ви добави към %s на %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Arxivar",
"Card Created": "Targeta creada", "Card Created": "Targeta creada",
"Card Moved": "Targeta moguda", "Card Moved": "Targeta moguda",
"New Comment": "Comentari nou", "New Comment": "Comentari nou",
@@ -6,6 +7,7 @@
"This is a test text message!": "Aquest és un missatge de text de prova!", "This is a test text message!": "Aquest és un missatge de text de prova!",
"This is a *test* **markdown** `message`!": "Aquest és un *missatge* **markdown** `de prova`!", "This is a *test* **markdown** `message`!": "Aquest és un *missatge* **markdown** `de prova`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Aquest és un <i>missatge</i> <b>html</b> <code>de prova</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Aquest és un <i>missatge</i> <b>html</b> <code>de prova</code>!",
"Trash": "Paperera",
"You Were Added to Card": "Has estat afegit a la targeta", "You Were Added to Card": "Has estat afegit a la targeta",
"You Were Mentioned in Comment": "Has estat mencionat en un comentari", "You Were Mentioned in Comment": "Has estat mencionat en un comentari",
"%s added you to %s on %s": "%s t'ha afegit a %s el %s", "%s added you to %s on %s": "%s t'ha afegit a %s el %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Archiv",
"Card Created": "Karta vytvořena", "Card Created": "Karta vytvořena",
"Card Moved": "Karta přesunuta", "Card Moved": "Karta přesunuta",
"New Comment": "Nový komentář", "New Comment": "Nový komentář",
@@ -6,6 +7,7 @@
"This is a test text message!": "Toto je testovací textová zpráva!", "This is a test text message!": "Toto je testovací textová zpráva!",
"This is a *test* **markdown** `message`!": "Toto je *testovací* **markdown** `zpráva`!", "This is a *test* **markdown** `message`!": "Toto je *testovací* **markdown** `zpráva`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Toto je <i>testovací</i> <b>html</b> <code>zpráva</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Toto je <i>testovací</i> <b>html</b> <code>zpráva</code>!",
"Trash": "Koš",
"You Were Added to Card": "Byli jste přidáni ke kartě", "You Were Added to Card": "Byli jste přidáni ke kartě",
"You Were Mentioned in Comment": "Byli jste zmíněni v komentáři", "You Were Mentioned in Comment": "Byli jste zmíněni v komentáři",
"%s added you to %s on %s": "%s vás přidal k %s dne %s", "%s added you to %s on %s": "%s vás přidal k %s dne %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Arkiv",
"Card Created": "Kort oprettet", "Card Created": "Kort oprettet",
"Card Moved": "Kort flyttet", "Card Moved": "Kort flyttet",
"New Comment": "Ny kommentar", "New Comment": "Ny kommentar",
@@ -6,6 +7,7 @@
"This is a test text message!": "Dette er en test tekstbesked!", "This is a test text message!": "Dette er en test tekstbesked!",
"This is a *test* **markdown** `message`!": "Dette er en *test* **markdown** `besked`!", "This is a *test* **markdown** `message`!": "Dette er en *test* **markdown** `besked`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Dette er en <i>test</i> <b>html</b> <code>besked</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Dette er en <i>test</i> <b>html</b> <code>besked</code>!",
"Trash": "Papirkurv",
"You Were Added to Card": "Du blev tilføjet til kortet", "You Were Added to Card": "Du blev tilføjet til kortet",
"You Were Mentioned in Comment": "Du blev nævnt i en kommentar", "You Were Mentioned in Comment": "Du blev nævnt i en kommentar",
"%s added you to %s on %s": "%s tilføjede dig til %s den %s", "%s added you to %s on %s": "%s tilføjede dig til %s den %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Archiv",
"Card Created": "Karte erstellt", "Card Created": "Karte erstellt",
"Card Moved": "Karte verschoben", "Card Moved": "Karte verschoben",
"New Comment": "Neuer Kommentar", "New Comment": "Neuer Kommentar",
@@ -6,6 +7,7 @@
"This is a test text message!": "Dies ist eine Test-Textnachricht!", "This is a test text message!": "Dies ist eine Test-Textnachricht!",
"This is a *test* **markdown** `message`!": "Dies ist eine *Test*-**Markdown**-`Nachricht`!", "This is a *test* **markdown** `message`!": "Dies ist eine *Test*-**Markdown**-`Nachricht`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Dies ist eine <i>Test</i>-<b>HTML</b>-<code>Nachricht</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Dies ist eine <i>Test</i>-<b>HTML</b>-<code>Nachricht</code>!",
"Trash": "Papierkorb",
"You Were Added to Card": "Sie wurden zur Karte hinzugefügt", "You Were Added to Card": "Sie wurden zur Karte hinzugefügt",
"You Were Mentioned in Comment": "Sie wurden in einem Kommentar erwähnt", "You Were Mentioned in Comment": "Sie wurden in einem Kommentar erwähnt",
"%s added you to %s on %s": "%s hat Sie zu %s am %s hinzugefügt", "%s added you to %s on %s": "%s hat Sie zu %s am %s hinzugefügt",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Αρχείο",
"Card Created": "Η κάρτα δημιουργήθηκε", "Card Created": "Η κάρτα δημιουργήθηκε",
"Card Moved": "Η κάρτα μετακινήθηκε", "Card Moved": "Η κάρτα μετακινήθηκε",
"New Comment": "Νέο σχόλιο", "New Comment": "Νέο σχόλιο",
@@ -6,6 +7,7 @@
"This is a test text message!": "Αυτό είναι ένα δοκιμαστικό μήνυμα!", "This is a test text message!": "Αυτό είναι ένα δοκιμαστικό μήνυμα!",
"This is a *test* **markdown** `message`!": "Αυτό είναι ένα *δοκιμαστικό* **markdown** `μήνυμα`!", "This is a *test* **markdown** `message`!": "Αυτό είναι ένα *δοκιμαστικό* **markdown** `μήνυμα`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Αυτό είναι ένα <i>δοκιμαστικό</i> <b>html</b> <code>μήνυμα</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Αυτό είναι ένα <i>δοκιμαστικό</i> <b>html</b> <code>μήνυμα</code>!",
"Trash": "Κάδος απορριμμάτων",
"You Were Added to Card": "Προστέθηκες στην κάρτα", "You Were Added to Card": "Προστέθηκες στην κάρτα",
"You Were Mentioned in Comment": "Αναφέρθηκες σε σχόλιο", "You Were Mentioned in Comment": "Αναφέρθηκες σε σχόλιο",
"%s added you to %s on %s": "%s σε πρόσθεσε στο %s στο %s", "%s added you to %s on %s": "%s σε πρόσθεσε στο %s στο %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Archive",
"Card Created": "Card Created", "Card Created": "Card Created",
"Card Moved": "Card Moved", "Card Moved": "Card Moved",
"New Comment": "New Comment", "New Comment": "New Comment",
@@ -6,6 +7,7 @@
"This is a test text message!": "This is a test text message!", "This is a test text message!": "This is a test text message!",
"This is a *test* **markdown** `message`!": "This is a *test* **markdown** `message`!", "This is a *test* **markdown** `message`!": "This is a *test* **markdown** `message`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "This is a <i>test</i> <b>html</b> <code>message</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "This is a <i>test</i> <b>html</b> <code>message</code>!",
"Trash": "Trash",
"You Were Added to Card": "You Were Added to Card", "You Were Added to Card": "You Were Added to Card",
"You Were Mentioned in Comment": "You Were Mentioned in Comment", "You Were Mentioned in Comment": "You Were Mentioned in Comment",
"%s added you to %s on %s": "%s added you to %s on %s", "%s added you to %s on %s": "%s added you to %s on %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Archive",
"Card Created": "Card Created", "Card Created": "Card Created",
"Card Moved": "Card Moved", "Card Moved": "Card Moved",
"New Comment": "New Comment", "New Comment": "New Comment",
@@ -6,6 +7,7 @@
"This is a test text message!": "This is a test text message!", "This is a test text message!": "This is a test text message!",
"This is a *test* **markdown** `message`!": "This is a *test* **markdown** `message`!", "This is a *test* **markdown** `message`!": "This is a *test* **markdown** `message`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "This is a <i>test</i> <b>html</b> <code>message</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "This is a <i>test</i> <b>html</b> <code>message</code>!",
"Trash": "Trash",
"You Were Added to Card": "You Were Added to Card", "You Were Added to Card": "You Were Added to Card",
"You Were Mentioned in Comment": "You Were Mentioned in Comment", "You Were Mentioned in Comment": "You Were Mentioned in Comment",
"%s added you to %s on %s": "%s added you to %s on %s", "%s added you to %s on %s": "%s added you to %s on %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Archivo",
"Card Created": "Tarjeta creada", "Card Created": "Tarjeta creada",
"Card Moved": "Tarjeta movida", "Card Moved": "Tarjeta movida",
"New Comment": "Nuevo comentario", "New Comment": "Nuevo comentario",
@@ -6,6 +7,7 @@
"This is a test text message!": "¡Este es un mensaje de texto de prueba!", "This is a test text message!": "¡Este es un mensaje de texto de prueba!",
"This is a *test* **markdown** `message`!": "¡Este es un *mensaje* **markdown** `de prueba`!", "This is a *test* **markdown** `message`!": "¡Este es un *mensaje* **markdown** `de prueba`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "¡Este es un <i>mensaje</i> <b>html</b> <code>de prueba</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "¡Este es un <i>mensaje</i> <b>html</b> <code>de prueba</code>!",
"Trash": "Papelera",
"You Were Added to Card": "Fuiste añadido a la tarjeta", "You Were Added to Card": "Fuiste añadido a la tarjeta",
"You Were Mentioned in Comment": "Fuiste mencionado en un comentario", "You Were Mentioned in Comment": "Fuiste mencionado en un comentario",
"%s added you to %s on %s": "%s te añadió a %s en %s", "%s added you to %s on %s": "%s te añadió a %s en %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Arhiiv",
"Card Created": "Kaart loodud", "Card Created": "Kaart loodud",
"Card Moved": "Kaart liigutatud", "Card Moved": "Kaart liigutatud",
"New Comment": "Uus kommentaar", "New Comment": "Uus kommentaar",
@@ -6,6 +7,7 @@
"This is a test text message!": "See on testi tekstisõnum!", "This is a test text message!": "See on testi tekstisõnum!",
"This is a *test* **markdown** `message`!": "See on *testi* **markdown** `sõnum`!", "This is a *test* **markdown** `message`!": "See on *testi* **markdown** `sõnum`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "See on <i>testi</i> <b>html</b> <code>sõnum</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "See on <i>testi</i> <b>html</b> <code>sõnum</code>!",
"Trash": "Prügikast",
"You Were Added to Card": "Teid lisati kaardile", "You Were Added to Card": "Teid lisati kaardile",
"You Were Mentioned in Comment": "Teid mainiti kommentaaris", "You Were Mentioned in Comment": "Teid mainiti kommentaaris",
"%s added you to %s on %s": "%s lisas teid %s-le %s", "%s added you to %s on %s": "%s lisas teid %s-le %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "بایگانی",
"Card Created": "کارت ایجاد شد", "Card Created": "کارت ایجاد شد",
"Card Moved": "کارت منتقل شد", "Card Moved": "کارت منتقل شد",
"New Comment": "نظر جدید", "New Comment": "نظر جدید",
@@ -6,6 +7,7 @@
"This is a test text message!": "این یک پیام متنی آزمایشی است!", "This is a test text message!": "این یک پیام متنی آزمایشی است!",
"This is a *test* **markdown** `message`!": "این یک *پیام* **markdown** `آزمایشی` است!", "This is a *test* **markdown** `message`!": "این یک *پیام* **markdown** `آزمایشی` است!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "این یک <i>پیام</i> <b>html</b> <code>آزمایشی</code> است!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "این یک <i>پیام</i> <b>html</b> <code>آزمایشی</code> است!",
"Trash": "سطل زباله",
"You Were Added to Card": "شما به کارت اضافه شدید", "You Were Added to Card": "شما به کارت اضافه شدید",
"You Were Mentioned in Comment": "در نظری از شما نام برده شد", "You Were Mentioned in Comment": "در نظری از شما نام برده شد",
"%s added you to %s on %s": "%s شما را به %s در %s اضافه کرد", "%s added you to %s on %s": "%s شما را به %s در %s اضافه کرد",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Arkisto",
"Card Created": "Kortti luotu", "Card Created": "Kortti luotu",
"Card Moved": "Kortti siirretty", "Card Moved": "Kortti siirretty",
"New Comment": "Uusi kommentti", "New Comment": "Uusi kommentti",
@@ -6,6 +7,7 @@
"This is a test text message!": "Tämä on testiviesti!", "This is a test text message!": "Tämä on testiviesti!",
"This is a *test* **markdown** `message`!": "Tämä on *testi* **markdown** `viesti`!", "This is a *test* **markdown** `message`!": "Tämä on *testi* **markdown** `viesti`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Tämä on <i>testi</i> <b>html</b> <code>viesti</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Tämä on <i>testi</i> <b>html</b> <code>viesti</code>!",
"Trash": "Roskakori",
"You Were Added to Card": "Sinut lisättiin korttiin", "You Were Added to Card": "Sinut lisättiin korttiin",
"You Were Mentioned in Comment": "Sinut mainittiin kommentissa", "You Were Mentioned in Comment": "Sinut mainittiin kommentissa",
"%s added you to %s on %s": "%s lisäsi sinut kohteeseen %s kohteessa %s", "%s added you to %s on %s": "%s lisäsi sinut kohteeseen %s kohteessa %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Archive",
"Card Created": "Carte créée", "Card Created": "Carte créée",
"Card Moved": "Carte déplacée", "Card Moved": "Carte déplacée",
"New Comment": "Nouveau commentaire", "New Comment": "Nouveau commentaire",
@@ -6,6 +7,7 @@
"This is a test text message!": "Ceci est un message texte de test !", "This is a test text message!": "Ceci est un message texte de test !",
"This is a *test* **markdown** `message`!": "Ceci est un *message* **markdown** `de test` !", "This is a *test* **markdown** `message`!": "Ceci est un *message* **markdown** `de test` !",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Ceci est un <i>test</i> <b>html</b> <code>message</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Ceci est un <i>test</i> <b>html</b> <code>message</code>!",
"Trash": "Corbeille",
"You Were Added to Card": "Vous avez été ajouté à la carte", "You Were Added to Card": "Vous avez été ajouté à la carte",
"You Were Mentioned in Comment": "Vous avez été mentionné dans un commentaire", "You Were Mentioned in Comment": "Vous avez été mentionné dans un commentaire",
"%s added you to %s on %s": "%s vous a ajouté à %s le %s", "%s added you to %s on %s": "%s vous a ajouté à %s le %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Archívum",
"Card Created": "Kártya létrehozva", "Card Created": "Kártya létrehozva",
"Card Moved": "Kártya áthelyezve", "Card Moved": "Kártya áthelyezve",
"New Comment": "Új hozzászólás", "New Comment": "Új hozzászólás",
@@ -6,6 +7,7 @@
"This is a test text message!": "Ez itt egy szöveges teszt üzenet!", "This is a test text message!": "Ez itt egy szöveges teszt üzenet!",
"This is a *test* **markdown** `message`!": "Ez itt egy **markdown** formátumú *teszt* `üzenet`!", "This is a *test* **markdown** `message`!": "Ez itt egy **markdown** formátumú *teszt* `üzenet`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Ez egy <b>html</b> formátumú <i>teszt</i> <code>üzenet</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Ez egy <b>html</b> formátumú <i>teszt</i> <code>üzenet</code>!",
"Trash": "Kuka",
"You Were Added to Card": "Hozzádrendeltek egy kártyát", "You Were Added to Card": "Hozzádrendeltek egy kártyát",
"You Were Mentioned in Comment": "Megemlítettek egy kártyán", "You Were Mentioned in Comment": "Megemlítettek egy kártyán",
"%s added you to %s on %s": "%s hozzárendelt téged a(z) %s kártyához a(z) %s projektben", "%s added you to %s on %s": "%s hozzárendelt téged a(z) %s kártyához a(z) %s projektben",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Arsip",
"Card Created": "Kartu dibuat", "Card Created": "Kartu dibuat",
"Card Moved": "Kartu dipindahkan", "Card Moved": "Kartu dipindahkan",
"New Comment": "Komentar baru", "New Comment": "Komentar baru",
@@ -6,6 +7,7 @@
"This is a test text message!": "Ini adalah pesan teks tes!", "This is a test text message!": "Ini adalah pesan teks tes!",
"This is a *test* **markdown** `message`!": "Ini adalah *pesan* **markdown** `tes`!", "This is a *test* **markdown** `message`!": "Ini adalah *pesan* **markdown** `tes`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Ini adalah <i>pesan</i> <b>html</b> <code>tes</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Ini adalah <i>pesan</i> <b>html</b> <code>tes</code>!",
"Trash": "Sampah",
"You Were Added to Card": "Anda ditambahkan ke kartu", "You Were Added to Card": "Anda ditambahkan ke kartu",
"You Were Mentioned in Comment": "Anda disebutkan dalam komentar", "You Were Mentioned in Comment": "Anda disebutkan dalam komentar",
"%s added you to %s on %s": "%s menambahkan Anda ke %s pada %s", "%s added you to %s on %s": "%s menambahkan Anda ke %s pada %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Archivio",
"Card Created": "Nuova task creata", "Card Created": "Nuova task creata",
"Card Moved": "Task spostata", "Card Moved": "Task spostata",
"New Comment": "Nuovo commento", "New Comment": "Nuovo commento",
@@ -6,6 +7,7 @@
"This is a test text message!": "Questo è un messaggio di testo di test!", "This is a test text message!": "Questo è un messaggio di testo di test!",
"This is a *test* **markdown** `message`!": "Questo è un *test* **markdown** `messaggio`!", "This is a *test* **markdown** `message`!": "Questo è un *test* **markdown** `messaggio`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Questo è un <i>test</i> <b>html</b> <code>messaggio</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Questo è un <i>test</i> <b>html</b> <code>messaggio</code>!",
"Trash": "Cestino",
"You Were Added to Card": "Sei stato aggiunto alla task", "You Were Added to Card": "Sei stato aggiunto alla task",
"You Were Mentioned in Comment": "Sei stato menzionato nel commento", "You Were Mentioned in Comment": "Sei stato menzionato nel commento",
"%s created %s in %s on %s": "%s ha creato %s in %s in %s", "%s created %s in %s on %s": "%s ha creato %s in %s in %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "アーカイブ",
"Card Created": "カードが作成されました", "Card Created": "カードが作成されました",
"Card Moved": "カードが移動されました", "Card Moved": "カードが移動されました",
"New Comment": "新しいコメント", "New Comment": "新しいコメント",
@@ -6,6 +7,7 @@
"This is a test text message!": "これはテストテキストメッセージです!", "This is a test text message!": "これはテストテキストメッセージです!",
"This is a *test* **markdown** `message`!": "これは*テスト***markdown**`メッセージ`です!", "This is a *test* **markdown** `message`!": "これは*テスト***markdown**`メッセージ`です!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "これは<i>テスト</i><b>html</b><code>メッセージ</code>です!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "これは<i>テスト</i><b>html</b><code>メッセージ</code>です!",
"Trash": "ゴミ箱",
"You Were Added to Card": "カードに追加されました", "You Were Added to Card": "カードに追加されました",
"You Were Mentioned in Comment": "コメントでメンションされました", "You Were Mentioned in Comment": "コメントでメンションされました",
"%s added you to %s on %s": "%sが%sの%sにあなたを追加しました", "%s added you to %s on %s": "%sが%sの%sにあなたを追加しました",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "보관함",
"Card Created": "카드가 생성됨", "Card Created": "카드가 생성됨",
"Card Moved": "카드가 이동됨", "Card Moved": "카드가 이동됨",
"New Comment": "새 댓글", "New Comment": "새 댓글",
@@ -6,6 +7,7 @@
"This is a test text message!": "이것은 테스트 텍스트 메시지입니다!", "This is a test text message!": "이것은 테스트 텍스트 메시지입니다!",
"This is a *test* **markdown** `message`!": "이것은 *테스트* **markdown** `메시지`입니다!", "This is a *test* **markdown** `message`!": "이것은 *테스트* **markdown** `메시지`입니다!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "이것은 <i>테스트</i> <b>html</b> <code>메시지</code>입니다!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "이것은 <i>테스트</i> <b>html</b> <code>메시지</code>입니다!",
"Trash": "휴지통",
"You Were Added to Card": "카드에 추가되었습니다", "You Were Added to Card": "카드에 추가되었습니다",
"You Were Mentioned in Comment": "댓글에서 언급되었습니다", "You Were Mentioned in Comment": "댓글에서 언급되었습니다",
"%s added you to %s on %s": "%s님이 %s의 %s에 당신을 추가했습니다", "%s added you to %s on %s": "%s님이 %s의 %s에 당신을 추가했습니다",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Archief",
"Card Created": "Kaart aangemaakt", "Card Created": "Kaart aangemaakt",
"Card Moved": "Kaart verplaatst", "Card Moved": "Kaart verplaatst",
"New Comment": "Nieuwe reactie", "New Comment": "Nieuwe reactie",
@@ -6,6 +7,7 @@
"This is a test text message!": "Dit is een test tekstbericht!", "This is a test text message!": "Dit is een test tekstbericht!",
"This is a *test* **markdown** `message`!": "Dit is een *test* **markdown** `bericht`!", "This is a *test* **markdown** `message`!": "Dit is een *test* **markdown** `bericht`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Dit is een <i>test</i> <b>html</b> <code>bericht</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Dit is een <i>test</i> <b>html</b> <code>bericht</code>!",
"Trash": "Prullenbak",
"You Were Added to Card": "Je bent toegevoegd aan kaart", "You Were Added to Card": "Je bent toegevoegd aan kaart",
"You Were Mentioned in Comment": "Je bent genoemd in reactie", "You Were Mentioned in Comment": "Je bent genoemd in reactie",
"%s added you to %s on %s": "%s heeft je toegevoegd aan %s op %s", "%s added you to %s on %s": "%s heeft je toegevoegd aan %s op %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Archiwum",
"Card Created": "Karta utworzona", "Card Created": "Karta utworzona",
"Card Moved": "Karta przeniesiona", "Card Moved": "Karta przeniesiona",
"New Comment": "Nowy komentarz", "New Comment": "Nowy komentarz",
@@ -6,6 +7,7 @@
"This is a test text message!": "To jest testowa wiadomość tekstowa!", "This is a test text message!": "To jest testowa wiadomość tekstowa!",
"This is a *test* **markdown** `message`!": "To jest *testowa* **markdown** `wiadomość`!", "This is a *test* **markdown** `message`!": "To jest *testowa* **markdown** `wiadomość`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "To jest <i>testowa</i> <b>html</b> <code>wiadomość</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "To jest <i>testowa</i> <b>html</b> <code>wiadomość</code>!",
"Trash": "Kosz",
"You Were Added to Card": "Zostałeś dodany do karty", "You Were Added to Card": "Zostałeś dodany do karty",
"You Were Mentioned in Comment": "Zostałeś wspomniany w komentarzu", "You Were Mentioned in Comment": "Zostałeś wspomniany w komentarzu",
"%s added you to %s on %s": "%s dodał cię do %s w dniu %s", "%s added you to %s on %s": "%s dodał cię do %s w dniu %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Arquivo",
"Card Created": "Cartão criado", "Card Created": "Cartão criado",
"Card Moved": "Cartão movido", "Card Moved": "Cartão movido",
"New Comment": "Novo comentário", "New Comment": "Novo comentário",
@@ -6,6 +7,7 @@
"This is a test text message!": "Esta é uma mensagem de texto de teste!", "This is a test text message!": "Esta é uma mensagem de texto de teste!",
"This is a *test* **markdown** `message`!": "Esta é uma *mensagem* **markdown** `de teste`!", "This is a *test* **markdown** `message`!": "Esta é uma *mensagem* **markdown** `de teste`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Esta é uma <i>mensagem</i> <b>html</b> <code>de teste</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Esta é uma <i>mensagem</i> <b>html</b> <code>de teste</code>!",
"Trash": "Lixeira",
"You Were Added to Card": "Você foi adicionado ao cartão", "You Were Added to Card": "Você foi adicionado ao cartão",
"You Were Mentioned in Comment": "Você foi mencionado em comentário", "You Were Mentioned in Comment": "Você foi mencionado em comentário",
"%s added you to %s on %s": "%s adicionou você a %s em %s", "%s added you to %s on %s": "%s adicionou você a %s em %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Arquivo",
"Card Created": "Cartão criado", "Card Created": "Cartão criado",
"Card Moved": "Cartão movido", "Card Moved": "Cartão movido",
"New Comment": "Novo comentário", "New Comment": "Novo comentário",
@@ -6,6 +7,7 @@
"This is a test text message!": "Esta é uma mensagem de texto de teste!", "This is a test text message!": "Esta é uma mensagem de texto de teste!",
"This is a *test* **markdown** `message`!": "Esta é uma *mensagem* **markdown** `de teste`!", "This is a *test* **markdown** `message`!": "Esta é uma *mensagem* **markdown** `de teste`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Esta é uma <i>mensagem</i> <b>html</b> <code>de teste</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Esta é uma <i>mensagem</i> <b>html</b> <code>de teste</code>!",
"Trash": "Lixo",
"You Were Added to Card": "Foi adicionado ao cartão", "You Were Added to Card": "Foi adicionado ao cartão",
"You Were Mentioned in Comment": "Foi mencionado num comentário", "You Were Mentioned in Comment": "Foi mencionado num comentário",
"%s added you to %s on %s": "%s adicionou-o a %s em %s", "%s added you to %s on %s": "%s adicionou-o a %s em %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Arhivă",
"Card Created": "Card creat", "Card Created": "Card creat",
"Card Moved": "Card mutat", "Card Moved": "Card mutat",
"New Comment": "Comentariu nou", "New Comment": "Comentariu nou",
@@ -6,6 +7,7 @@
"This is a test text message!": "Acesta este un mesaj text de test!", "This is a test text message!": "Acesta este un mesaj text de test!",
"This is a *test* **markdown** `message`!": "Acesta este un *mesaj* **markdown** `de test`!", "This is a *test* **markdown** `message`!": "Acesta este un *mesaj* **markdown** `de test`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Acesta este un <i>mesaj</i> <b>html</b> <code>de test</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Acesta este un <i>mesaj</i> <b>html</b> <code>de test</code>!",
"Trash": "Coș de gunoi",
"You Were Added to Card": "Ați fost adăugat la card", "You Were Added to Card": "Ați fost adăugat la card",
"You Were Mentioned in Comment": "Ați fost menționat într-un comentariu", "You Were Mentioned in Comment": "Ați fost menționat într-un comentariu",
"%s added you to %s on %s": "%s v-a adăugat la %s pe %s", "%s added you to %s on %s": "%s v-a adăugat la %s pe %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Архив",
"Card Created": "Карточка создана", "Card Created": "Карточка создана",
"Card Moved": "Карточка перемещена", "Card Moved": "Карточка перемещена",
"New Comment": "Новый комментарий", "New Comment": "Новый комментарий",
@@ -6,6 +7,7 @@
"This is a test text message!": "Это тестовое сообщение!", "This is a test text message!": "Это тестовое сообщение!",
"This is a *test* **markdown** `message`!": "Это *тестовое* **markdown** `сообщение`!", "This is a *test* **markdown** `message`!": "Это *тестовое* **markdown** `сообщение`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Это <i>тестовое</i> <b>html</b> <code>сообщение</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Это <i>тестовое</i> <b>html</b> <code>сообщение</code>!",
"Trash": "Корзина",
"You Were Added to Card": "Вы были добавлены к карточке", "You Were Added to Card": "Вы были добавлены к карточке",
"You Were Mentioned in Comment": "Вы были упомянуты в комментарии", "You Were Mentioned in Comment": "Вы были упомянуты в комментарии",
"%s added you to %s on %s": "%s добавил(а) вас к %s на %s", "%s added you to %s on %s": "%s добавил(а) вас к %s на %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Archív",
"Card Created": "Karta vytvorená", "Card Created": "Karta vytvorená",
"Card Moved": "Karta presunutá", "Card Moved": "Karta presunutá",
"New Comment": "Nový komentár", "New Comment": "Nový komentár",
@@ -6,6 +7,7 @@
"This is a test text message!": "Toto je testovacia textová správa!", "This is a test text message!": "Toto je testovacia textová správa!",
"This is a *test* **markdown** `message`!": "Toto je *testovacia* **markdown** `správa`!", "This is a *test* **markdown** `message`!": "Toto je *testovacia* **markdown** `správa`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Toto je <i>testovacia</i> <b>html</b> <code>správa</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Toto je <i>testovacia</i> <b>html</b> <code>správa</code>!",
"Trash": "Kôš",
"You Were Added to Card": "Boli ste pridaní ku karte", "You Were Added to Card": "Boli ste pridaní ku karte",
"You Were Mentioned in Comment": "Boli ste spomenutí v komentári", "You Were Mentioned in Comment": "Boli ste spomenutí v komentári",
"%s added you to %s on %s": "%s vás pridal k %s dňa %s", "%s added you to %s on %s": "%s vás pridal k %s dňa %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Архива",
"Card Created": "Картица креирана", "Card Created": "Картица креирана",
"Card Moved": "Картица премештена", "Card Moved": "Картица премештена",
"New Comment": "Нови коментар", "New Comment": "Нови коментар",
@@ -6,6 +7,7 @@
"This is a test text message!": "Ово је тест текстуална порука!", "This is a test text message!": "Ово је тест текстуална порука!",
"This is a *test* **markdown** `message`!": "Ово је *тест* **markdown** `порука`!", "This is a *test* **markdown** `message`!": "Ово је *тест* **markdown** `порука`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Ово је <i>тест</i> <b>html</b> <code>порука</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Ово је <i>тест</i> <b>html</b> <code>порука</code>!",
"Trash": "Корпа за отпатке",
"You Were Added to Card": "Додати сте на картицу", "You Were Added to Card": "Додати сте на картицу",
"You Were Mentioned in Comment": "Поменути сте у коментару", "You Were Mentioned in Comment": "Поменути сте у коментару",
"%s added you to %s on %s": "%s вас је додао на %s дана %s", "%s added you to %s on %s": "%s вас је додао на %s дана %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Arhiva",
"Card Created": "Kartica kreirana", "Card Created": "Kartica kreirana",
"Card Moved": "Kartica premeštena", "Card Moved": "Kartica premeštena",
"New Comment": "Novi komentar", "New Comment": "Novi komentar",
@@ -6,6 +7,7 @@
"This is a test text message!": "Ovo je test tekstualna poruka!", "This is a test text message!": "Ovo je test tekstualna poruka!",
"This is a *test* **markdown** `message`!": "Ovo je *test* **markdown** `poruka`!", "This is a *test* **markdown** `message`!": "Ovo je *test* **markdown** `poruka`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Ovo je <i>test</i> <b>html</b> <code>poruka</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Ovo je <i>test</i> <b>html</b> <code>poruka</code>!",
"Trash": "Korpa za otpatke",
"You Were Added to Card": "Dodati ste na karticu", "You Were Added to Card": "Dodati ste na karticu",
"You Were Mentioned in Comment": "Pomenuti ste u komentaru", "You Were Mentioned in Comment": "Pomenuti ste u komentaru",
"%s added you to %s on %s": "%s vas je dodao na %s dana %s", "%s added you to %s on %s": "%s vas je dodao na %s dana %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Arkiv",
"Card Created": "Kort skapat", "Card Created": "Kort skapat",
"Card Moved": "Kort flyttat", "Card Moved": "Kort flyttat",
"New Comment": "Ny kommentar", "New Comment": "Ny kommentar",
@@ -6,6 +7,7 @@
"This is a test text message!": "Detta är ett test textmeddelande!", "This is a test text message!": "Detta är ett test textmeddelande!",
"This is a *test* **markdown** `message`!": "Detta är ett *test* **markdown** `meddelande`!", "This is a *test* **markdown** `message`!": "Detta är ett *test* **markdown** `meddelande`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Detta är ett <i>test</i> <b>html</b> <code>meddelande</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Detta är ett <i>test</i> <b>html</b> <code>meddelande</code>!",
"Trash": "Papperskorg",
"You Were Added to Card": "Du lades till på kort", "You Were Added to Card": "Du lades till på kort",
"You Were Mentioned in Comment": "Du nämndes i kommentar", "You Were Mentioned in Comment": "Du nämndes i kommentar",
"%s added you to %s on %s": "%s lade till dig på %s den %s", "%s added you to %s on %s": "%s lade till dig på %s den %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Arşiv",
"Card Created": "Kart oluşturuldu", "Card Created": "Kart oluşturuldu",
"Card Moved": "Kart taşındı", "Card Moved": "Kart taşındı",
"New Comment": "Yeni yorum", "New Comment": "Yeni yorum",
@@ -6,6 +7,7 @@
"This is a test text message!": "Bu bir test metin mesajıdır!", "This is a test text message!": "Bu bir test metin mesajıdır!",
"This is a *test* **markdown** `message`!": "Bu bir *test* **markdown** `mesajı`!", "This is a *test* **markdown** `message`!": "Bu bir *test* **markdown** `mesajı`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Bu bir <i>test</i> <b>html</b> <code>mesajı</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Bu bir <i>test</i> <b>html</b> <code>mesajı</code>!",
"Trash": "Çöp kutusu",
"You Were Added to Card": "Karta eklendiniz", "You Were Added to Card": "Karta eklendiniz",
"You Were Mentioned in Comment": "Bir yorumda bahsedildiniz", "You Were Mentioned in Comment": "Bir yorumda bahsedildiniz",
"%s added you to %s on %s": "%s sizi %s'ye %s tarihinde ekledi", "%s added you to %s on %s": "%s sizi %s'ye %s tarihinde ekledi",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Архів",
"Card Created": "Картку створено", "Card Created": "Картку створено",
"Card Moved": "Картку переміщено", "Card Moved": "Картку переміщено",
"New Comment": "Новий коментар", "New Comment": "Новий коментар",
@@ -6,6 +7,7 @@
"This is a test text message!": "Це нове повідомлення!", "This is a test text message!": "Це нове повідомлення!",
"This is a *test* **markdown** `message`!": "Це *тестове* **markdown** `повідомлення`!", "This is a *test* **markdown** `message`!": "Це *тестове* **markdown** `повідомлення`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Це <i>тестове</i> <b>html</b> <code>повідомлення</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Це <i>тестове</i> <b>html</b> <code>повідомлення</code>!",
"Trash": "Кошик",
"You Were Added to Card": "Вас було додано до картки", "You Were Added to Card": "Вас було додано до картки",
"You Were Mentioned in Comment": "Вас було згадано у коментарі", "You Were Mentioned in Comment": "Вас було згадано у коментарі",
"%s added you to %s on %s": "%s додав(ла) вас до %s на %s", "%s added you to %s on %s": "%s додав(ла) вас до %s на %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "Arxiv",
"Card Created": "Karta yaratildi", "Card Created": "Karta yaratildi",
"Card Moved": "Karta ko'chirildi", "Card Moved": "Karta ko'chirildi",
"New Comment": "Yangi izoh", "New Comment": "Yangi izoh",
@@ -6,6 +7,7 @@
"This is a test text message!": "Bu test matn xabari!", "This is a test text message!": "Bu test matn xabari!",
"This is a *test* **markdown** `message`!": "Bu *test* **markdown** `xabar`!", "This is a *test* **markdown** `message`!": "Bu *test* **markdown** `xabar`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "Bu <i>test</i> <b>html</b> <code>xabar</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "Bu <i>test</i> <b>html</b> <code>xabar</code>!",
"Trash": "Chiqindi quti",
"You Were Added to Card": "Siz kartaga qo'shildingiz", "You Were Added to Card": "Siz kartaga qo'shildingiz",
"You Were Mentioned in Comment": "Siz izohda eslatildingiz", "You Were Mentioned in Comment": "Siz izohda eslatildingiz",
"%s added you to %s on %s": "%s sizni %s ga %s da qo'shdi", "%s added you to %s on %s": "%s sizni %s ga %s da qo'shdi",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "归档",
"Card Created": "卡片已创建", "Card Created": "卡片已创建",
"Card Moved": "卡片已移动", "Card Moved": "卡片已移动",
"New Comment": "新评论", "New Comment": "新评论",
@@ -6,6 +7,7 @@
"This is a test text message!": "这是一条测试文本消息!", "This is a test text message!": "这是一条测试文本消息!",
"This is a *test* **markdown** `message`!": "这是一条*测试***markdown**`消息`!", "This is a *test* **markdown** `message`!": "这是一条*测试***markdown**`消息`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "这是一条<i>测试</i><b>html</b><code>消息</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "这是一条<i>测试</i><b>html</b><code>消息</code>!",
"Trash": "回收站",
"You Were Added to Card": "您已被添加到卡片", "You Were Added to Card": "您已被添加到卡片",
"You Were Mentioned in Comment": "您在评论中被提及", "You Were Mentioned in Comment": "您在评论中被提及",
"%s added you to %s on %s": "%s 在 %s 将您添加到 %s", "%s added you to %s on %s": "%s 在 %s 将您添加到 %s",
+2
View File
@@ -1,4 +1,5 @@
{ {
"Archive": "封存",
"Card Created": "卡片已建立", "Card Created": "卡片已建立",
"Card Moved": "卡片已移動", "Card Moved": "卡片已移動",
"New Comment": "新留言", "New Comment": "新留言",
@@ -6,6 +7,7 @@
"This is a test text message!": "這是一則測試文字訊息!", "This is a test text message!": "這是一則測試文字訊息!",
"This is a *test* **markdown** `message`!": "這是一則*測試***markdown**`訊息`!", "This is a *test* **markdown** `message`!": "這是一則*測試***markdown**`訊息`!",
"This is a <i>test</i> <b>html</b> <code>message</code>!": "這是一則<i>測試</i><b>html</b><code>訊息</code>!", "This is a <i>test</i> <b>html</b> <code>message</code>!": "這是一則<i>測試</i><b>html</b><code>訊息</code>!",
"Trash": "垃圾桶",
"You Were Added to Card": "您已被加入卡片", "You Were Added to Card": "您已被加入卡片",
"You Were Mentioned in Comment": "您在留言中被提及", "You Were Mentioned in Comment": "您在留言中被提及",
"%s added you to %s on %s": "%s 在 %s 將您加入 %s", "%s added you to %s on %s": "%s 在 %s 將您加入 %s",
+1
View File
@@ -16,6 +16,7 @@ const USERNAME_REGEX = /^[a-zA-Z0-9]+((_|\.)?[a-zA-Z0-9])*$/;
const isUrl = (value) => const isUrl = (value) =>
validator.isURL(value, { validator.isURL(value, {
protocols: ['http', 'https'], protocols: ['http', 'https'],
require_tld: false,
require_protocol: true, require_protocol: true,
}); });