1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-07-18 12:49:43 +02:00
This commit is contained in:
Symon Baikov 2025-07-17 20:58:30 +02:00 committed by GitHub
commit 08ade97063
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 145 additions and 59 deletions

View file

@ -3,11 +3,11 @@
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
import React, { useCallback, useMemo } from 'react';
import React, { useCallback, useMemo, useState } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { useSelector } from 'react-redux';
import { Progress } from 'semantic-ui-react';
import { Progress, Checkbox } from 'semantic-ui-react';
import { useToggle } from '../../../../lib/hooks';
import selectors from '../../../../selectors';
@ -15,12 +15,13 @@ import Task from './Task';
import styles from './TaskList.module.scss';
const TaskList = React.memo(({ id }) => {
const TaskList = React.memo(({ id, showHideCheckedToggle }) => {
const selectTasksByTaskListId = useMemo(() => selectors.makeSelectTasksByTaskListId(), []);
const tasks = useSelector((state) => selectTasksByTaskListId(state, id));
const [isOpened, toggleOpened] = useToggle();
const [hideChecked, setHideChecked] = useState(false);
// TODO: move to selector?
const completedTasksTotal = useMemo(
@ -36,6 +37,11 @@ const TaskList = React.memo(({ id }) => {
[toggleOpened],
);
const filteredTasks = useMemo(
() => (hideChecked ? tasks.filter((task) => !task.isCompleted) : tasks),
[tasks, hideChecked],
);
if (tasks.length === 0) {
return null;
}
@ -62,11 +68,23 @@ const TaskList = React.memo(({ id }) => {
</span>
</div>
{isOpened && (
<ul className={styles.tasks}>
{tasks.map((task) => (
<Task key={task.id} id={task.id} />
))}
</ul>
<>
{showHideCheckedToggle && (
<div style={{ margin: '8px 0' }}>
<Checkbox
label="Скрыть отмеченные пункты"
checked={hideChecked}
onChange={() => setHideChecked((prev) => !prev)}
toggle
/>
</div>
)}
<ul className={styles.tasks}>
{filteredTasks.map((task) => (
<Task key={task.id} id={task.id} />
))}
</ul>
</>
)}
</>
);
@ -74,6 +92,11 @@ const TaskList = React.memo(({ id }) => {
TaskList.propTypes = {
id: PropTypes.string.isRequired,
showHideCheckedToggle: PropTypes.bool,
};
TaskList.defaultProps = {
showHideCheckedToggle: false,
};
export default TaskList;

View file

@ -19,7 +19,7 @@ import TaskList from '../../../task-lists/TaskList';
import styles from './Item.module.scss';
const Item = React.memo(({ id, index }) => {
const Item = React.memo(({ id, index, hideChecked }) => {
const selectTaskListById = useMemo(() => selectors.makeSelectTaskListById(), []);
const taskList = useSelector((state) => selectTaskListById(state, id));
@ -64,7 +64,7 @@ const Item = React.memo(({ id, index }) => {
<span className={styles.moduleHeaderTitle}>{taskList.name}</span>
</div>
</div>
<TaskList id={id} />
<TaskList id={id} hideChecked={hideChecked} />
</div>
</div>
);
@ -78,6 +78,7 @@ const Item = React.memo(({ id, index }) => {
Item.propTypes = {
id: PropTypes.string.isRequired,
index: PropTypes.number.isRequired,
hideChecked: PropTypes.bool.isRequired,
};
export default Item;

View file

@ -3,9 +3,11 @@
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
import React, { useCallback } from 'react';
import React, { useCallback, useState, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { DragDropContext, Droppable } from 'react-beautiful-dnd';
import { Checkbox } from 'semantic-ui-react';
import { useTranslation } from 'react-i18next';
import { closePopup } from '../../../../lib/popup';
import selectors from '../../../../selectors';
@ -16,8 +18,19 @@ import Item from './Item';
import globalStyles from '../../../../styles.module.scss';
const HIDE_CHECKED_KEY = 'planka_hide_checked_tasks';
const TaskLists = React.memo(() => {
const [t] = useTranslation();
const taskListIds = useSelector(selectors.selectTaskListIdsForCurrentCard);
const [hideChecked, setHideChecked] = useState(() => {
const stored = localStorage.getItem(HIDE_CHECKED_KEY);
return stored === 'true';
});
useEffect(() => {
localStorage.setItem(HIDE_CHECKED_KEY, hideChecked);
}, [hideChecked]);
const dispatch = useDispatch();
@ -58,19 +71,31 @@ const TaskLists = React.memo(() => {
);
return (
<DragDropContext onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
<Droppable droppableId="card" type={DroppableTypes.TASK_LIST} direction="vertical">
{({ innerRef, droppableProps, placeholder }) => (
// eslint-disable-next-line react/jsx-props-no-spreading
<div {...droppableProps} ref={innerRef}>
{taskListIds.map((taskListId, index) => (
<Item key={taskListId} id={taskListId} index={index} />
))}
{placeholder}
</div>
)}
</Droppable>
</DragDropContext>
<>
{taskListIds.length > 0 && (
<div style={{ margin: '8px 0' }}>
<Checkbox
label={t('common.taskList_hideChecked')}
checked={hideChecked}
onChange={() => setHideChecked((prev) => !prev)}
toggle
/>
</div>
)}
<DragDropContext onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
<Droppable droppableId="card" type={DroppableTypes.TASK_LIST} direction="vertical">
{({ innerRef, droppableProps, placeholder }) => (
// eslint-disable-next-line react/jsx-props-no-spreading
<div {...droppableProps} ref={innerRef}>
{taskListIds.map((taskListId, index) => (
<Item key={taskListId} id={taskListId} index={index} hideChecked={hideChecked} />
))}
{placeholder}
</div>
)}
</Droppable>
</DragDropContext>
</>
);
});

View file

@ -21,7 +21,7 @@ import AddTask from './AddTask';
import styles from './TaskList.module.scss';
const TaskList = React.memo(({ id }) => {
const TaskList = React.memo(({ id, hideChecked }) => {
const selectTaskListById = useMemo(() => selectors.makeSelectTaskListById(), []);
const selectListById = useMemo(() => selectors.makeSelectListById(), []);
const selectTasksByTaskListId = useMemo(() => selectors.makeSelectTasksByTaskListId(), []);
@ -45,10 +45,14 @@ const TaskList = React.memo(({ id }) => {
const [isAddOpened, setIsAddOpened] = useState(false);
const [, , setIsClosableActive] = useContext(ClosableContext);
// TODO: move to selector?
const filteredTasks = useMemo(
() => (hideChecked ? tasks.filter((task) => !task.isCompleted) : tasks),
[tasks, hideChecked],
);
const completedTasksTotal = useMemo(
() => tasks.reduce((result, task) => (task.isCompleted ? result + 1 : result), 0),
[tasks],
() => filteredTasks.reduce((result, task) => (task.isCompleted ? result + 1 : result), 0),
[filteredTasks],
);
const handleAddClick = useCallback(() => {
@ -65,20 +69,20 @@ const TaskList = React.memo(({ id }) => {
return (
<>
{tasks.length > 0 && (
{filteredTasks.length > 0 && (
<>
<span className={styles.progressWrapper}>
<Progress
autoSuccess
value={completedTasksTotal}
total={tasks.length}
total={filteredTasks.length}
color="blue"
size="tiny"
className={styles.progress}
/>
</span>
<span className={styles.count}>
{completedTasksTotal}/{tasks.length}
{completedTasksTotal}/{filteredTasks.length}
</span>
</>
)}
@ -90,7 +94,7 @@ const TaskList = React.memo(({ id }) => {
{({ innerRef, droppableProps, placeholder }) => (
// eslint-disable-next-line react/jsx-props-no-spreading
<div {...droppableProps} ref={innerRef} className={styles.tasks}>
{tasks.map((task, index) => (
{filteredTasks.map((task, index) => (
<Task key={task.id} id={task.id} index={index} />
))}
{placeholder}
@ -117,6 +121,7 @@ const TaskList = React.memo(({ id }) => {
TaskList.propTypes = {
id: PropTypes.string.isRequired,
hideChecked: PropTypes.bool.isRequired,
};
export default TaskList;

View file

@ -162,6 +162,7 @@ export default {
users: 'المستخدمين',
viewer: 'مشاهد',
writeComment: 'اكتب تعليقاً...',
taskList_hideChecked: 'إخفاء العناصر المحددة',
},
action: {
@ -232,6 +233,7 @@ export default {
unsubscribe: 'إلغاء الاشتراك',
uploadNewAvatar: 'رفع صورة رمزية جديدة',
uploadNewImage: 'رفع صورة جديدة',
moveListToBoard: 'نقل القائمة إلى لوحة أخرى',
},
},
};

View file

@ -167,6 +167,7 @@ export default {
users: 'Потребители',
viewer: 'Зрител',
writeComment: 'Напишете коментар...',
taskList_hideChecked: 'Скриване на отметки',
},
action: {

View file

@ -293,6 +293,7 @@ export default {
visualTaskManagementWithLists: 'Vizuální správa úkolů pomocí seznamů.',
withoutBaseGroup: 'Bez základní skupiny',
writeComment: 'Napsat komentář...',
taskList_hideChecked: 'Skrýt označené položky',
},
action: {
@ -406,6 +407,7 @@ export default {
unsubscribe: 'Neodebírat',
uploadNewAvatar: 'Nahrát nový avatar',
uploadNewImage: 'Nahrát nový obrázek',
moveListToBoard: 'Přesunout seznam na jinou nástěnku',
},
},
};

View file

@ -321,6 +321,7 @@ export default {
visualTaskManagementWithLists: 'Visuel opgavestyring med lister',
withoutBaseGroup: 'Uden standardgruppe',
writeComment: 'Skriv en kommentar...',
taskList_hideChecked: 'Skjul afkrydsede elementer',
},
action: {
@ -434,6 +435,7 @@ export default {
unsubscribe: 'Opsig abonnement',
uploadNewAvatar: 'Tilføj nyt profilbillede',
uploadNewImage: 'Tilføj nyt billede',
moveListToBoard: 'Flyt liste til anden tavle',
},
},
};

View file

@ -310,6 +310,7 @@ export default {
visualTaskManagementWithLists: 'Visuelle Aufgabenverwaltung mit Listen.',
withoutBaseGroup: 'Ohne Basisgruppe',
writeComment: 'Kommentar verfassen...',
taskList_hideChecked: 'Ausgecheckte Elemente ausblenden',
},
action: {
@ -416,8 +417,6 @@ export default {
showCardsWithThisUser: 'Karten mit diesem Benutzer zeigen',
showDeactivated: 'Deaktivierte anzeigen',
showFewerAttachments: 'Weniger Anhänge anzeigen',
showLess: 'Weniger anzeigen',
showMore: 'Mehr anzeigen',
sortList_title: 'Liste sortieren',
start: 'Start',
stop: 'Stopp',
@ -425,6 +424,7 @@ export default {
unsubscribe: 'De-abonnieren',
uploadNewAvatar: 'Neuen Avatar hochladen',
uploadNewImage: 'Neues Bild hochladen',
moveListToBoard: 'Liste auf andere Arbeitsbereich verschieben',
},
},
};

View file

@ -337,6 +337,7 @@ export default {
visualTaskManagementWithLists: 'Οπτική διαχείριση εργασιών με λίστες.',
withoutBaseGroup: 'Χωρίς βασική ομάδα',
writeComment: 'Γράψτε ένα σχόλιο...',
taskList_hideChecked: 'Απόκρυψη επιλεγμένων στοιχείων',
},
action: {
@ -450,6 +451,7 @@ export default {
unsubscribe: 'Απεγγραφή',
uploadNewAvatar: 'Μεταφόρτωση νέου avatar',
uploadNewImage: 'Μεταφόρτωση νέας εικόνας',
moveListToBoard: 'Μετακίνηση λίστας σε άλλο πίνακα',
},
},
};

View file

@ -327,6 +327,7 @@ export default {
webhooks: 'Webhooks',
withoutBaseGroup: 'Without base group',
writeComment: 'Write a comment...',
taskList_hideChecked: 'Hide checked items',
},
action: {
@ -435,8 +436,6 @@ export default {
showCardsWithThisUser: 'Show cards with this user',
showDeactivated: 'Show deactivated',
showFewerAttachments: 'Show fewer attachments',
showLess: 'Show less',
showMore: 'Show more',
sortList_title: 'Sort List',
start: 'Start',
stop: 'Stop',
@ -444,6 +443,7 @@ export default {
unsubscribe: 'Unsubscribe',
uploadNewAvatar: 'Upload new avatar',
uploadNewImage: 'Upload new image',
moveListToBoard: 'Move list to another board',
},
},
};

View file

@ -322,6 +322,7 @@ export default {
webhooks: 'Webhooks',
withoutBaseGroup: 'Without base group',
writeComment: 'Write a comment...',
taskList_hideChecked: 'Hide checked items',
},
action: {
@ -430,8 +431,6 @@ export default {
showCardsWithThisUser: 'Show cards with this user',
showDeactivated: 'Show deactivated',
showFewerAttachments: 'Show fewer attachments',
showLess: 'Show less',
showMore: 'Show more',
sortList_title: 'Sort List',
start: 'Start',
stop: 'Stop',
@ -439,6 +438,7 @@ export default {
unsubscribe: 'Unsubscribe',
uploadNewAvatar: 'Upload new avatar',
uploadNewImage: 'Upload new image',
moveListToBoard: 'Move list to another board',
},
},
};

View file

@ -315,6 +315,7 @@ export default {
visualTaskManagementWithLists: 'Gestión visual de tareas con listas',
withoutBaseGroup: 'Sin grupo base',
writeComment: 'Escribir un comentario...',
taskList_hideChecked: 'Ocultar elementos marcados',
},
action: {
@ -423,6 +424,7 @@ export default {
unsubscribe: 'Desuscribirse',
uploadNewAvatar: 'Subir un nuevo avatar',
uploadNewImage: 'Subir una nueva imagen',
moveListToBoard: 'Mover lista a otro tablero',
},
},
};

View file

@ -164,6 +164,7 @@ export default {
users: 'کاربران',
viewer: 'بیننده',
writeComment: 'نظر بنویسید...',
taskList_hideChecked: 'پنهان کردن آیتم‌های انتخاب شده',
},
action: {
@ -234,6 +235,7 @@ export default {
unsubscribe: 'لغو اشتراک',
uploadNewAvatar: 'آپلود آواتار جدید',
uploadNewImage: 'آپلود تصویر جدید',
moveListToBoard: 'انتقال لیست به برد دیگر',
},
},
};

View file

@ -319,6 +319,7 @@ export default {
visualTaskManagementWithLists: 'Visuaalinen tehtävien hallinta listoilla.',
withoutBaseGroup: 'Ilman perusryhmää',
writeComment: 'Kirjoita kommentti...',
taskList_hideChecked: 'Piilota valitut kohdat',
},
action: {
@ -432,6 +433,7 @@ export default {
unsubscribe: 'Peru tilaus',
uploadNewAvatar: 'Lataa uusi avatar',
uploadNewImage: 'Lataa uusi kuva',
moveListToBoard: 'Siirrä lista toiselle taululle',
},
},
};

View file

@ -331,6 +331,7 @@ export default {
webhooks: 'Webhooks',
withoutBaseGroup: 'Sans groupe de base',
writeComment: 'Écrire un commentaire...',
taskList_hideChecked: 'Masquer les éléments marqués',
},
action: {
activateUser: 'Activer lutilisateur',
@ -447,6 +448,7 @@ export default {
unsubscribe: 'Se désabonner',
uploadNewAvatar: 'Télécharger un nouvel avatar',
uploadNewImage: 'Télécharger une nouvelle image',
moveListToBoard: 'Déplacer la liste vers un autre tableau',
},
},
};

View file

@ -165,6 +165,7 @@ export default {
users: 'Felhasználók',
viewer: 'Néző',
writeComment: 'Írjon egy megjegyzést...',
taskList_hideChecked: 'Elrejtett elemek megjelenítése',
},
action: {
@ -235,6 +236,7 @@ export default {
unsubscribe: 'Leiratkozás',
uploadNewAvatar: 'Új avatar feltöltése',
uploadNewImage: 'Új kép feltöltése',
moveListToBoard: 'Lista áthelyezése másik táblára',
},
},
};

View file

@ -160,6 +160,7 @@ export default {
users: 'Pengguna',
viewer: 'Penglihat',
writeComment: 'Tuliskan komentar...',
taskList_hideChecked: 'Sembunyikan item yang terpilih',
},
action: {
@ -227,6 +228,7 @@ export default {
unsubscribe: 'Berhenti berlangganan',
uploadNewAvatar: 'Unggah avatar baru',
uploadNewImage: 'Unggah gambar baru',
moveListToBoard: 'Pindahkan daftar ke papan lain',
},
},
};

View file

@ -1,12 +1,9 @@
import dateFns from 'date-fns/locale/it';
import timeAgo from 'javascript-time-ago/locale/it';
import markdownEditor from './markdown-editor.json';
export default {
dateFns,
timeAgo,
markdownEditor,
format: {
date: 'd/M/yyyy',
@ -317,6 +314,7 @@ export default {
visualTaskManagementWithLists: 'Gestione visiva dei task con liste',
withoutBaseGroup: 'Senza gruppo base',
writeComment: 'Scrivi un commento...',
taskList_hideChecked: 'Nascondi elementi selezionati',
},
action: {
@ -429,6 +427,7 @@ export default {
unsubscribe: 'Annulla iscrizione',
uploadNewAvatar: 'Carica nuovo avatar',
uploadNewImage: 'Carica nuova immagine',
moveListToBoard: 'Muovi lista a un altra bacheca',
},
},
};

View file

@ -1,12 +1,9 @@
import dateFns from 'date-fns/locale/ja';
import timeAgo from 'javascript-time-ago/locale/ja';
import markdownEditor from './markdown-editor.json';
export default {
dateFns,
timeAgo,
markdownEditor,
format: {
date: 'yyyy/M/d',
@ -160,6 +157,7 @@ export default {
users: 'ユーザー',
viewer: 'ビューア',
writeComment: 'コメントを書く…',
taskList_hideChecked: '選択した項目を非表示にする',
},
action: {
@ -227,6 +225,7 @@ export default {
unsubscribe: '購読解除',
uploadNewAvatar: '新しいアバターをアップロード',
uploadNewImage: '新しい画像をアップロード',
moveListToBoard: 'リストを別のボードに移動',
},
},
};

View file

@ -1,12 +1,9 @@
import dateFns from 'date-fns/locale/ko';
import timeAgo from 'javascript-time-ago/locale/ko';
import markdownEditor from './markdown-editor.json';
export default {
dateFns,
timeAgo,
markdownEditor,
format: {
date: 'yyyy년 M월 d일',
@ -165,6 +162,7 @@ export default {
users: '사용자들',
viewer: '뷰어',
writeComment: '댓글 작성...',
taskList_hideChecked: '완료된 항목 숨기기',
},
action: {
@ -237,6 +235,7 @@ export default {
unsubscribe: '구독 취소',
uploadNewAvatar: '새 아바타 업로드',
uploadNewImage: '새 이미지 업로드',
moveListToBoard: '목록을 다른 보드로 이동',
},
},
};

View file

@ -1,12 +1,9 @@
import dateFns from 'date-fns/locale/nl';
import timeAgo from 'javascript-time-ago/locale/nl';
import markdownEditor from './markdown-editor.json';
export default {
dateFns,
timeAgo,
markdownEditor,
format: {
date: 'd-M-yyyy',
@ -161,6 +158,7 @@ export default {
users: 'Gebruikers',
viewer: 'Kijker',
writeComment: 'Schrijf een opmerking...',
taskList_hideChecked: 'Verberg geselecteerde items',
},
action: {
@ -228,6 +226,7 @@ export default {
unsubscribe: 'Afmelden',
uploadNewAvatar: 'Nieuwe avatar uploaden',
uploadNewImage: 'Nieuwe afbeelding uploaden',
moveListToBoard: 'Lijst verplaatsen naar ander bord',
},
},
};

View file

@ -293,6 +293,7 @@ export default {
visualTaskManagementWithLists: 'Wizualne zarządzanie zadaniami z listami.',
withoutBaseGroup: 'Bez grupy bazowej',
writeComment: 'Napisz komentarz...',
taskList_hideChecked: 'Ukryj zaznaczone elementy',
},
action: {
@ -406,6 +407,7 @@ export default {
unsubscribe: 'Odsubskrybuj',
uploadNewAvatar: 'Wgraj nowy awatar',
uploadNewImage: 'Wgraj nowy obraz',
moveListToBoard: 'Przenieś listę na inną tablicę',
},
},
};

View file

@ -1,12 +1,9 @@
import dateFns from 'date-fns/locale/pt-BR';
import timeAgo from 'javascript-time-ago/locale/pt';
import markdownEditor from './markdown-editor.json';
export default {
dateFns,
timeAgo,
markdownEditor,
format: {
date: 'dd/MM/yyyy',
@ -161,6 +158,7 @@ export default {
users: 'Usuários',
viewer: 'Visualizador',
writeComment: 'Escreva um comentário...',
taskList_hideChecked: 'Ocultar itens marcados',
},
action: {
@ -228,6 +226,7 @@ export default {
unsubscribe: 'Cancelar inscrição',
uploadNewAvatar: 'Enviar novo avatar',
uploadNewImage: 'Enviar nova imagem',
moveListToBoard: 'Mover lista para outro quadro',
},
},
};

View file

@ -299,6 +299,7 @@ export default {
visualTaskManagementWithLists: 'Визуальное управление задачами с помощью списков',
withoutBaseGroup: 'Без основной группы',
writeComment: 'Напишите комментарий...',
taskList_hideChecked: 'Скрыть отмеченные пункты',
},
action: {
@ -412,6 +413,7 @@ export default {
unsubscribe: 'Отписаться',
uploadNewAvatar: 'Загрузить новый аватар',
uploadNewImage: 'Загрузить новое изображение',
moveListToBoard: 'Переместить в другую доску',
},
},
};

View file

@ -1,12 +1,9 @@
import dateFns from 'date-fns/locale/sk';
import timeAgo from 'javascript-time-ago/locale/sk';
import markdownEditor from './markdown-editor.json';
export default {
dateFns,
timeAgo,
markdownEditor,
format: {
date: 'd.M.yyyy',
@ -145,6 +142,7 @@ export default {
username: 'Používateľské meno',
users: 'Používatelia',
writeComment: 'Napísať komentár...',
taskList_hideChecked: 'Skryť označené položky',
},
action: {
@ -209,6 +207,7 @@ export default {
unsubscribe: 'Neodoberať',
uploadNewAvatar: 'Nahrať nový avatar',
uploadNewImage: 'Nahrať nový obrázok',
moveListToBoard: 'Presunúť zoznam na inú tabuľu',
},
},
};

View file

@ -1,12 +1,9 @@
import dateFns from 'date-fns/locale/sr';
import timeAgo from 'javascript-time-ago/locale/sr';
import markdownEditor from './markdown-editor.json';
export default {
dateFns,
timeAgo,
markdownEditor,
format: {
date: 'd.M.yyyy.',
@ -166,6 +163,7 @@ export default {
users: 'Корисници',
viewer: 'Прегледач',
writeComment: 'Напиши коментар...',
taskList_hideChecked: 'Сакриј означене ставке',
},
action: {
@ -236,6 +234,7 @@ export default {
unsubscribe: 'Укини претплату',
uploadNewAvatar: 'Постави нови аватар',
uploadNewImage: 'Постави нову слику',
moveListToBoard: 'Премести на другу таблу',
},
},
};

View file

@ -163,6 +163,7 @@ export default {
users: 'Korisnici',
viewer: 'Pregledač',
writeComment: 'Napiši komentar...',
taskList_hideChecked: 'Sakrij označene stavke',
},
action: {
@ -233,6 +234,7 @@ export default {
unsubscribe: 'Ukini pretplatu',
uploadNewAvatar: 'Postavi novi avatar',
uploadNewImage: 'Postavi novu sliku',
moveListToBoard: 'Premesti spisak na drugu tablu',
},
},
};

View file

@ -143,6 +143,7 @@ export default {
username: 'Användarnamn',
users: 'Användare',
writeComment: 'Skriv en kommentar...',
taskList_hideChecked: 'Dölj markerade objekt',
},
action: {
@ -207,6 +208,7 @@ export default {
unsubscribe: 'Avprenumerera',
uploadNewAvatar: 'Ladda upp ny avatar',
uploadNewImage: 'Ladda upp ny bild',
moveListToBoard: 'Flytta lista till annan tavla',
},
},
};

View file

@ -144,6 +144,7 @@ export default {
username: 'kullanıcı adı',
users: 'kullanıcı',
writeComment: 'Yorum yazın...',
taskList_hideChecked: 'Görevleri gizle',
},
action: {
@ -207,6 +208,7 @@ export default {
unsubscribe: 'Abonelikten çık',
uploadNewAvatar: 'Yeni avatar yükle',
uploadNewImage: 'Yeni resim yükle',
moveListToBoard: 'Listeyi başka bir panoya taşı',
},
},
};

View file

@ -295,6 +295,7 @@ export default {
visualTaskManagementWithLists: 'Візуальне управління завданнями за допомогою списків.',
withoutBaseGroup: 'Без базової групи',
writeComment: 'Написати коментар...',
taskList_hideChecked: 'Приховати позначені елементи',
},
action: {
@ -408,6 +409,7 @@ export default {
unsubscribe: 'Відписатися',
uploadNewAvatar: 'Завантажити новий аватар',
uploadNewImage: 'Завантажити нове зображення',
moveListToBoard: 'Перемістити список на іншу дошку',
},
},
};

View file

@ -140,6 +140,7 @@ export default {
username: 'Foydalanuvchi nomi',
users: 'Foydalanuvchilar',
writeComment: 'Izoh yozish...',
taskList_hideChecked: 'Ko chirish',
},
action: {
@ -203,6 +204,7 @@ export default {
unsubscribe: 'Obunani bekor qilish',
uploadNewAvatar: 'Yangi avatar yuklash',
uploadNewImage: 'Yangi rasm yuklash',
moveListToBoard: "Ro'yxatni boshqa doskaga ko'chirish",
},
},
};

View file

@ -305,6 +305,7 @@ export default {
webhooks: 'Webhooks',
withoutBaseGroup: '无基础组',
writeComment: '编写评论...',
taskList_hideChecked: '隐藏已完成的任务',
},
action: {
@ -422,6 +423,7 @@ export default {
unsubscribe: '取消关注',
uploadNewAvatar: '上传新头像',
uploadNewImage: '上传图片',
moveListToBoard: '移动列表到另一个面板',
},
},
};

View file

@ -153,6 +153,7 @@ export default {
users: '使用者',
viewer: '檢視',
writeComment: '編寫評論...',
taskList_hideChecked: '隱藏已完成的任務',
},
action: {
@ -220,6 +221,7 @@ export default {
unsubscribe: '取消訂閱',
uploadNewAvatar: '上傳新頭像',
uploadNewImage: '上傳圖片',
moveListToBoard: '移動列表到另一個面板',
},
},
};