Compare commits

...

8 Commits

Author SHA1 Message Date
Henry
872a5fad28 feat: public board enhancements (#134)
* feat: hide dropdown on comments for public boards

* feat: fix height of modal and add scrollable content area

* feat: add view only badge to public boards

* feat: prevent card title from overlapping close button

* chore: gen translations
2025-08-01 22:03:38 +01:00
Henry
400b94a5f2 feat: enhance member invite error handling and add invite more toggle (#133) 2025-07-30 22:24:05 +01:00
Henry
638b8b6b79 fix: update public board lookup to filter by workspace slug and show not found message (#131)
* fix: update public board lookup to filter by workspace slug

* feat: show not found message for public boards

* chore: update lang
2025-07-28 22:59:28 +01:00
Ridham Khandar
ca1dd92ab4 fix: disable create list and label button when input is empty (#130) 2025-07-28 21:49:24 +01:00
Ridham Khandar
f8827da73a fix: creating a new label when adding a new card resets all fields (#119)
* fix: creating a new label when adding a new card resets all fields

* fix: persist form data and modal stacking without breaking the animations
2025-07-28 21:49:13 +01:00
Henry
babaa9f1b1 feat: setup plunk for transactional/marketing emails 2025-07-28 07:09:30 +01:00
Henry
0cefd17484 fix: prevent member dropdown from being cutoff (#127) 2025-07-26 21:34:05 +01:00
Henry
974a5ff0f3 fix: update board slug availability check to be unique to workspace (#126) 2025-07-26 21:18:26 +01:00
41 changed files with 1107 additions and 458 deletions

View File

@@ -32,6 +32,7 @@ checksums:
Are%20you%20sure%20you%20want%20to%20delete%20the%20workspace%20%7B0%7D%3F/singular: 27ba2854202dd77c51e78c64e5c93946
Are%20you%20sure%20you%20want%20to%20delete%20this%20card%3F/singular: 131a5a7cccca7be8b32c987d9fa0b0c0
Are%20you%20sure%20you%20want%20to%20delete%20this%20comment%3F/singular: 55fe6f1b52b71b91b2a079cfda3cc7fe
Are%20you%20sure%20you%20want%20to%20delete%20this%20label%3F/singular: 037fbaf1d04356937e6afb574714f51f
Are%20you%20sure%20you%20want%20to%20delete%20your%20account%3F/singular: 428b74d781063224c3e63980e1094ec3
assigned%20%3C0%3E%7BmemberName%7D%3C%2F0%3E%20to%20the%20card/singular: 4fb1c419a78a0f010a3e5790801551fc
Awaiting%20Customer/singular: 122c108794f321c10e05a08f09b11457
@@ -127,8 +128,10 @@ checksums:
Enter%20your%20name/singular: cd95fbdd0533f2c2e8edf9d9bd9aa8df
Enter%20your%20password/singular: ea4fdd034522dead21bae0c0abb52eae
Error%20deleting%20account/singular: d42965a9bc9e5ec4ed57890268924643
Error%20deleting%20label/singular: 94387e3a45ec768ae7715701ae00136e
Error%20deleting%20workspace/singular: 0aec9bd8170bc84f5ea5c9a47c52ed26
Error%20disconnecting%20Trello/singular: a8766853864eddc480113778a708871b
Error%20inviting%20member/singular: 91553b606a6ebed3534cd2e5635ce004
Error%20updating%20display%20name/singular: 0d7979a25d290123ed8b8906bf468f1a
Error%20updating%20profile%20image/singular: 462a56a6e574abc9e13cb48f1266adad
Error%20updating%20workspace%20description/singular: 7a9fd7c69b90ab848ee1f1d4a4995381
@@ -185,7 +188,9 @@ checksums:
Individuals/singular: 83bfc81f20e60556c44ec80c7d0603ec
Integrations/singular: 0ccce343287704cd90150c32e2fcad36
Interviewing/singular: 4ccdcdc784547e925077c3297bddee95
Invalid%20email%20address/singular: b2d9f25626f2d15c7c63e0281bccc247
Invite/singular: 181884cea804cbde665f160811ee7ad0
Invite%20another/singular: acb543563dab7edbcf46060a53ade3a3
Invite%20member/singular: ade922db1be6b26bc979565ce5de2bc7
Junior/singular: ed1bd2c59a824fdcdd56fc8a0660fe9f
Kanban%20is%20better%20with%20a%20team.%20Perfect%20for%20small%20and%20growing%20teams%20looking%20to%20collaborate./singular: a77bee43046b260797c8936ad23e9223
@@ -308,6 +313,7 @@ checksums:
Theme/singular: 21fe00b7a518089576fb83c08631107a
They%20won't%20be%20able%20to%20access%20this%20workspace./singular: 93b740350fe3430319fbca85349e41d9
This%20action%20can't%20be%20undone./singular: cb222ff89715d8c971e8c25d121e1dbd
This%20board%20is%20private%20or%20does%20not%20exist/singular: a217ff3f04463b4df8c86adb6f83c6bc
This%20board%20URL%20has%20already%20been%20taken/singular: 1d8b40332a031b5b77a3658e48dd51ca
This%20will%20result%20in%20the%20permanent%20deletion%20of%20all%20data%20associated%20with%20this%20workspace./singular: a31141558af793635c1ddd2fa0a33499
This%20will%20result%20in%20the%20permanent%20deletion%20of%20all%20data%20associated%20with%20your%20account./singular: b49224632bd6c3b7f5e462912aeb1081
@@ -353,11 +359,14 @@ checksums:
URL%20must%20be%20at%20least%203%20characters%20long/singular: 1b74ac9ec61fd34b16530ed599009ed1
Use%20template/singular: 33f0ca0aa8f4b0de99aad267a61a094d
User/singular: 61073457a5c3901084b557d065f876be
User%20is%20already%20a%20member%20of%20this%20workspace/singular: bc246386f0975f750f2133222bb4735e
Video/singular: 8050c90e4289b105a0780f0fdda6ff66
View%20and%20manage%20your%20API%20keys./singular: 88e23ee79056846dd9ce63ceee690549
View%20and%20manage%20your%20billing%20and%20subscription./singular: 7469502543aac6f02149813546d1cb38
View%20docs/singular: 43ce54f27bb1e3f1880b56e03ab38871
View%20only/singular: 21f5f7ba3b49050c4f406113479d6a7a
View%20our%20roadmap./singular: 1dd7ec80e1635951b1c90d592d1d07dc
View%20workspace/singular: c9e4b789330b08c18ca8db7044409e5f
Visibility/singular: 1ff412f8fcde0f460acbf11153649646
We%20are%20using%20the%20%3C0%3EAGPL-3.0%20license%3C%2F0%3E./singular: 08c5ddd938a2a70f61d684e41e18697a
We're%20just%20getting%20started.%20/singular: 2dfa121e0ff1914e08068308a81973c0

View File

@@ -86,8 +86,10 @@ export default function CheckboxDropdown({
</label>
{handleEdit && (
<button
type="button"
className="invisible ml-auto group-hover:visible"
onClick={(event) => {
event.preventDefault();
event.stopPropagation();
handleEdit(item.key);
}}
@@ -100,8 +102,12 @@ export default function CheckboxDropdown({
))}
{handleCreate && (
<button
type="button"
className="flex w-full items-center rounded-[5px] p-2 px-2 text-[12px] text-dark-900 hover:bg-light-200 dark:hover:bg-dark-300"
onClick={() => handleCreate()}
onClick={(e) => {
e.preventDefault();
handleCreate();
}}
>
<HiMiniPlus size={20} className="pr-1.5" />
{createNewItemLabel}

View File

@@ -1,3 +1,5 @@
import { t } from "@lingui/core/macro";
import Button from "~/components/Button";
import { useModal } from "~/providers/modal";
import { usePopup } from "~/providers/popup";
@@ -17,8 +19,8 @@ export function DeleteLabelConfirmation({
onSuccess: () => refetch(),
onError: () =>
showPopup({
header: "Error deleting label",
message: "Please try again later, or contact customer support.",
header: t`Error deleting label`,
message: t`Please try again later, or contact customer support.`,
icon: "error",
}),
});
@@ -34,17 +36,17 @@ export function DeleteLabelConfirmation({
<div className="p-5">
<div className="flex w-full flex-col justify-between pb-4">
<h2 className="text-md pb-4 font-medium text-neutral-900 dark:text-dark-1000">
Are you sure you want to delete this label?
{t`Are you sure you want to delete this label?`}
</h2>
<p className="text-sm font-medium text-light-900 dark:text-dark-900">
{"This action can't be undone."}
{t`This action can't be undone.`}
</p>
</div>
<div className="mt-5 flex justify-end space-x-2 sm:mt-6">
<Button variant="secondary" onClick={() => closeModal()}>
Cancel
{t`Cancel`}
</Button>
<Button onClick={handleDeleteLabel}>Delete</Button>
<Button onClick={handleDeleteLabel}>{t`Delete`}</Button>
</div>
</div>
);

View File

@@ -15,6 +15,7 @@ import {
ReactRenderer,
useEditor,
} from "@tiptap/react";
import { useEffect } from "react";
import StarterKit from "@tiptap/starter-kit";
import Suggestion from "@tiptap/suggestion";
import { forwardRef, useImperativeHandle, useRef, useState } from "react";
@@ -343,9 +344,19 @@ export default function Editor({
editable: !readOnly,
injectCSS: false,
},
[content],
[], // creating the editor only once
);
// this will sync external content changes without re-creating the editor instance
useEffect(() => {
if (!editor) return;
const currentHTML = editor.getHTML();
const safeContent = content ?? "";
if (safeContent !== currentHTML) {
editor.commands.setContent(safeContent, false);
}
}, [content, editor]);
return (
<div ref={containerRef}>
<style jsx global>{`

View File

@@ -63,12 +63,16 @@ export function LabelForm({
);
try {
refetch();
if (!isCreateAnotherEnabled) closeModal();
reset({
name: "",
colour: colours[(currentColourIndex + 1) % colours.length],
isCreateAnotherEnabled,
});
if (!isCreateAnotherEnabled) {
closeModal();
} else {
const newFormState = {
name: "",
colour: colours[(currentColourIndex + 1) % colours.length],
isCreateAnotherEnabled,
};
reset(newFormState);
}
} catch (e) {
console.log(e);
}
@@ -79,10 +83,6 @@ export function LabelForm({
onSuccess: () => {
refetch();
closeModal();
reset({
name: "",
colour: colours[0],
});
},
});
@@ -229,6 +229,9 @@ export function LabelForm({
<Button
type="submit"
isLoading={updateLabel.isPending || createLabel.isPending}
disabled={
!watch("name")
}
>
{isEdit ? t`Update label` : t`Create label`}
</Button>

View File

@@ -7,15 +7,19 @@ interface Props {
children: React.ReactNode;
modalSize?: "sm" | "md" | "lg";
positionFromTop?: "sm" | "md" | "lg";
isVisible?: boolean;
}
const Modal: React.FC<Props> = ({
children,
modalSize = "sm",
positionFromTop = "md",
isVisible,
}) => {
const { isOpen, closeModal } = useModal();
const shouldShow = isVisible !== undefined ? isVisible : isOpen;
const modalSizeMap = {
sm: "max-w-[400px]",
md: "max-w-[550px]",
@@ -29,7 +33,7 @@ const Modal: React.FC<Props> = ({
};
return (
<Transition.Root show={isOpen} as={Fragment}>
<Transition.Root show={shouldShow} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={closeModal}>
<Transition.Child
as={Fragment}

View File

@@ -0,0 +1,48 @@
import { useEffect } from "react";
import { useModal } from "~/providers/modal";
interface UseModalFormStateOptions<T> {
modalType: string;
initialValues: T;
resetOnClose?: boolean;
}
export function useModalFormState<T extends Record<string, any>>({
modalType,
initialValues,
resetOnClose = false,
}: UseModalFormStateOptions<T>) {
const { modalContentType, isOpen, getModalState, setModalState, clearModalState } = useModal();
const isCurrentModal = modalContentType === modalType;
const savedState = getModalState(modalType) as T | undefined;
// get current form state (using the saved values if available, otherwise the initial values)
const formState = savedState || initialValues;
const saveFormState = (state: Partial<T>) => {
if (!isCurrentModal) return;
const currentState = getModalState(modalType) || initialValues;
const newState = { ...currentState, ...state };
setModalState(modalType, newState);
};
const clearFormState = () => {
clearModalState(modalType);
};
useEffect(() => {
if (resetOnClose && !isOpen && savedState) {
clearModalState(modalType);
}
}, [isOpen, resetOnClose, savedState, modalType, clearModalState]);
return {
formState,
saveFormState,
clearFormState,
isCurrentModal,
hasSavedState: !!savedState,
};
}

View File

@@ -13,7 +13,7 @@ msgstr ""
"Language-Team: \n"
"Plural-Forms: \n"
#: src/views/card/components/Comment.tsx:121
#: src/views/card/components/Comment.tsx:123
msgid " (edited)"
msgstr " (bearbeitet)"
@@ -28,7 +28,7 @@ msgid "{0} | {1}"
msgstr "{0} | {1}"
#. placeholder {0}: labelPublicIds.length
#: src/views/board/components/NewCardForm.tsx:365
#: src/views/board/components/NewCardForm.tsx:392
msgid "{0} labels"
msgstr "{0} Labels"
@@ -48,7 +48,7 @@ msgstr "Eine leistungsstarke, flexible Kanban-App, die dir hilft, Arbeit zu orga
msgid "Account deleted"
msgstr "Konto gelöscht"
#: src/views/public/board/CardModal.tsx:104
#: src/views/public/board/CardModal.tsx:128
#: src/views/card/index.tsx:256
msgid "Activity"
msgstr "Aktivität"
@@ -62,11 +62,11 @@ msgid "Add a card"
msgstr "Karte hinzufügen"
#: src/views/card/components/NewCommentForm.tsx:57
#: src/views/card/components/Comment.tsx:144
#: src/views/card/components/Comment.tsx:146
msgid "Add a comment..."
msgstr "Kommentar hinzufügen..."
#: src/components/Editor.tsx:302
#: src/components/Editor.tsx:303
msgid "Add description... (type '/' to open commands)"
msgstr "Beschreibung hinzufügen... (tippe '/' um Befehle zu öffnen)"
@@ -75,7 +75,7 @@ msgstr "Beschreibung hinzufügen... (tippe '/' um Befehle zu öffnen)"
msgid "Add label"
msgstr "Label hinzufügen"
#: src/views/members/components/InviteMemberForm.tsx:50
#: src/views/members/components/InviteMemberForm.tsx:85
#: src/views/card/components/MemberSelector.tsx:130
msgid "Add member"
msgstr "Mitglied hinzufügen"
@@ -145,6 +145,10 @@ msgstr "Bist du sicher, dass du diese Karte löschen möchtest?"
msgid "Are you sure you want to delete this comment?"
msgstr "Bist du sicher, dass du diesen Kommentar löschen möchtest?"
#: src/components/DeleteLabelConfirmation.tsx:39
msgid "Are you sure you want to delete this label?"
msgstr "Sind Sie sicher, dass Sie dieses Label löschen möchten?"
#: src/views/settings/components/DeleteAccountConfirmation.tsx:54
msgid "Are you sure you want to delete your account?"
msgstr "Bist du sicher, dass du dein Konto löschen möchtest?"
@@ -178,7 +182,7 @@ msgstr "Abrechnungsportal"
msgid "Blog Post"
msgstr "Blogbeitrag"
#: src/views/board/index.tsx:241
#: src/views/board/index.tsx:332
msgid "Board"
msgstr "Board"
@@ -190,7 +194,8 @@ msgstr "Der Name des Boards darf 100 Zeichen nicht überschreiten"
msgid "Board name is required"
msgstr "Boardname ist erforderlich"
#: src/views/board/index.tsx:267
#: src/views/public/board/index.tsx:143
#: src/views/board/index.tsx:358
msgid "Board not found"
msgstr "Board nicht gefunden"
@@ -202,7 +207,7 @@ msgstr "Board-URL darf nur Buchstaben, Zahlen und Bindestriche enthalten"
msgid "Board URL cannot exceed 60 characters"
msgstr "Board-URL darf 60 Zeichen nicht überschreiten"
#: src/views/public/board/index.tsx:53
#: src/views/public/board/index.tsx:59
msgid "Board URL copied to clipboard"
msgstr "Board-URL in die Zwischenablage kopiert"
@@ -246,7 +251,8 @@ msgstr "Fehlerbericht"
#: src/views/members/components/DeleteMemberConfirmation.tsx:55
#: src/views/card/components/DeleteCommentConfirmation.tsx:76
#: src/views/card/components/DeleteCardConfirmation.tsx:86
#: src/views/card/components/Comment.tsx:156
#: src/views/card/components/Comment.tsx:158
#: src/components/DeleteLabelConfirmation.tsx:47
msgid "Cancel"
msgstr "Abbrechen"
@@ -254,7 +260,7 @@ msgstr "Abbrechen"
msgid "Card not found"
msgstr "Karte nicht gefunden"
#: src/views/board/components/NewCardForm.tsx:254
#: src/views/board/components/NewCardForm.tsx:278
msgid "Card title"
msgstr "Kartentitel"
@@ -347,7 +353,7 @@ msgid "Control who can view and edit your boards."
msgstr "Kontrolliere, wer deine Boards ansehen und bearbeiten kann."
#: src/views/board/components/NewListForm.tsx:140
#: src/views/board/components/NewCardForm.tsx:391
#: src/views/board/components/NewCardForm.tsx:418
#: src/components/LabelForm.tsx:212
msgid "Create another"
msgstr "Weitere erstellen"
@@ -356,15 +362,15 @@ msgstr "Weitere erstellen"
msgid "Create board"
msgstr "Board erstellen"
#: src/views/board/components/NewCardForm.tsx:401
#: src/views/board/components/NewCardForm.tsx:428
msgid "Create card"
msgstr "Karte erstellen"
#: src/components/LabelForm.tsx:233
#: src/components/LabelForm.tsx:236
msgid "Create label"
msgstr "Label erstellen"
#: src/views/board/components/NewListForm.tsx:148
#: src/views/board/components/NewListForm.tsx:152
msgid "Create list"
msgstr "Liste erstellen"
@@ -377,11 +383,11 @@ msgid "Create new key"
msgstr "Neuen Schlüssel erstellen"
#: src/views/card/components/LabelSelector.tsx:98
#: src/views/board/components/NewCardForm.tsx:327
#: src/views/board/components/NewCardForm.tsx:354
msgid "Create new label"
msgstr "Neues Label erstellen"
#: src/views/board/index.tsx:335
#: src/views/board/index.tsx:426
msgid "Create new list"
msgstr "Neue Liste erstellen"
@@ -417,6 +423,7 @@ msgstr "Dunkel"
#: src/views/card/components/DeleteCommentConfirmation.tsx:82
#: src/views/card/components/DeleteCardConfirmation.tsx:92
#: src/components/LabelForm.tsx:226
#: src/components/DeleteLabelConfirmation.tsx:49
msgid "Delete"
msgstr "Löschen"
@@ -434,7 +441,7 @@ msgstr "Board löschen"
msgid "Delete card"
msgstr "Karte löschen"
#: src/views/card/components/Comment.tsx:89
#: src/views/card/components/Comment.tsx:91
msgid "Delete comment"
msgstr "Kommentar löschen"
@@ -510,7 +517,7 @@ msgstr "Erledigt"
msgid "Edit board URL"
msgstr "Board-URL bearbeiten"
#: src/views/card/components/Comment.tsx:80
#: src/views/card/components/Comment.tsx:82
msgid "Edit comment"
msgstr "Kommentar bearbeiten"
@@ -530,7 +537,7 @@ msgstr "Bearbeitung"
msgid "email"
msgstr "E-Mail"
#: src/views/members/components/InviteMemberForm.tsx:64
#: src/views/members/components/InviteMemberForm.tsx:99
msgid "Email"
msgstr "E-Mail"
@@ -554,6 +561,10 @@ msgstr "Gib dein Passwort ein"
msgid "Error deleting account"
msgstr "Fehler beim Löschen des Kontos"
#: src/components/DeleteLabelConfirmation.tsx:22
msgid "Error deleting label"
msgstr "Fehler beim Löschen des Labels"
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:45
msgid "Error deleting workspace"
msgstr "Fehler beim Löschen des Arbeitsbereichs"
@@ -562,6 +573,11 @@ msgstr "Fehler beim Löschen des Arbeitsbereichs"
msgid "Error disconnecting Trello"
msgstr "Fehler beim Trennen von Trello"
#: src/views/members/components/InviteMemberForm.tsx:57
#: src/views/members/components/InviteMemberForm.tsx:63
msgid "Error inviting member"
msgstr "Fehler beim Einladen des Mitglieds"
#: src/views/settings/components/UpdateDisplayNameForm.tsx:54
msgid "Error updating display name"
msgstr "Fehler beim Aktualisieren des Anzeigenamens"
@@ -676,7 +692,7 @@ msgstr "Loslegen"
msgid "Get started by creating a new board"
msgstr "Beginne, indem du ein neues Board erstellst"
#: src/views/board/index.tsx:327
#: src/views/board/index.tsx:418
msgid "Get started by creating a new list"
msgstr "Beginne mit dem Erstellen einer neuen Liste"
@@ -799,11 +815,19 @@ msgstr "Integrationen"
msgid "Interviewing"
msgstr "Vorstellungsgespräch"
#: src/views/members/components/InviteMemberForm.tsx:26
msgid "Invalid email address"
msgstr "Ungültige E-Mail-Adresse"
#: src/views/members/index.tsx:169
msgid "Invite"
msgstr "Einladen"
#: src/views/members/components/InviteMemberForm.tsx:82
#: src/views/members/components/InviteMemberForm.tsx:113
msgid "Invite another"
msgstr "Weitere Person einladen"
#: src/views/members/components/InviteMemberForm.tsx:123
#: src/views/card/components/MemberSelector.tsx:112
msgid "Invite member"
msgstr "Mitglied einladen"
@@ -826,7 +850,7 @@ msgid "Keep in mind that this action is irreversible."
msgstr "Beachten Sie, dass diese Aktion nicht rückgängig gemacht werden kann."
#: src/views/card/index.tsx:113
#: src/views/board/components/NewCardForm.tsx:331
#: src/views/board/components/NewCardForm.tsx:358
#: src/views/board/components/Filters.tsx:101
msgid "Labels"
msgstr "Labels"
@@ -855,7 +879,7 @@ msgstr "Lizenz"
msgid "Light"
msgstr "Hell"
#: src/views/public/board/index.tsx:51
#: src/views/public/board/index.tsx:57
msgid "Link copied"
msgstr "Link kopiert"
@@ -893,7 +917,7 @@ msgstr "Mittlere Priorität"
#: src/views/members/index.tsx:161
#: src/views/card/index.tsx:121
#: src/views/board/components/NewCardForm.tsx:290
#: src/views/board/components/NewCardForm.tsx:317
#: src/views/board/components/Filters.tsx:93
#: src/components/SideNavigation.tsx:73
msgid "Members"
@@ -933,7 +957,7 @@ msgstr "Neu"
msgid "New board"
msgstr "Neues Board"
#: src/views/board/components/NewCardForm.tsx:237
#: src/views/board/components/NewCardForm.tsx:261
msgid "New card"
msgstr "Neue Karte"
@@ -945,7 +969,7 @@ msgstr "Neuer Import"
msgid "New label"
msgstr "Neues Label"
#: src/views/board/index.tsx:304
#: src/views/board/index.tsx:395
#: src/views/board/components/NewListForm.tsx:112
msgid "New list"
msgstr "Neue Liste"
@@ -978,7 +1002,7 @@ msgstr "Keine Boards gefunden"
msgid "No credit card required"
msgstr "Keine Kreditkarte erforderlich"
#: src/views/board/index.tsx:324
#: src/views/board/index.tsx:415
msgid "No lists"
msgstr "Keine Listen"
@@ -1059,6 +1083,7 @@ msgstr "Bitte wähle eine Datei zum Hochladen aus."
#: src/views/settings/components/DeleteAccountConfirmation.tsx:40
#: src/views/settings/components/Avatar.tsx:40
#: src/views/settings/components/Avatar.tsx:98
#: src/views/members/components/InviteMemberForm.tsx:64
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
#: src/views/card/index.tsx:159
#: src/views/card/components/NewCommentForm.tsx:31
@@ -1067,16 +1092,17 @@ msgstr "Bitte wähle eine Datei zum Hochladen aus."
#: src/views/card/components/LabelSelector.tsx:73
#: src/views/card/components/DeleteCommentConfirmation.tsx:45
#: src/views/card/components/DeleteCardConfirmation.tsx:52
#: src/views/card/components/Comment.tsx:62
#: src/views/card/components/Comment.tsx:64
#: src/views/boards/components/ImportBoardsForm.tsx:205
#: src/views/board/index.tsx:135
#: src/views/board/index.tsx:191
#: src/views/board/components/VisibilityButton.tsx:53
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
#: src/views/board/components/NewListForm.tsx:78
#: src/views/board/components/NewCardForm.tsx:128
#: src/views/board/components/NewCardForm.tsx:145
#: src/components/NewWorkspaceForm.tsx:41
#: src/components/FeedbackModal.tsx:41
#: src/components/DeleteLabelConfirmation.tsx:23
msgid "Please try again later, or contact customer support."
msgstr "Bitte versuche es später noch einmal oder kontaktiere den Kundensupport."
@@ -1187,7 +1213,7 @@ msgstr "Rolle"
msgid "Run on your own infrastructure"
msgstr "Auf eigener Infrastruktur betreiben"
#: src/views/card/components/Comment.tsx:163
#: src/views/card/components/Comment.tsx:165
msgid "Save"
msgstr "Speichern"
@@ -1335,9 +1361,14 @@ msgstr "Sie werden keinen Zugriff mehr auf diesen Workspace haben."
#: src/views/card/components/DeleteCommentConfirmation.tsx:68
#: src/views/card/components/DeleteCardConfirmation.tsx:78
#: src/components/DeleteLabelConfirmation.tsx:42
msgid "This action can't be undone."
msgstr "Diese Aktion kann nicht rückgängig gemacht werden."
#: src/views/public/board/index.tsx:146
msgid "This board is private or does not exist"
msgstr "Dieses Board ist privat oder existiert nicht"
#: src/views/board/components/UpdateBoardSlugForm.tsx:135
msgid "This board URL has already been taken"
msgstr "Diese Board-URL ist bereits vergeben"
@@ -1383,7 +1414,7 @@ msgstr "Priorisierung"
msgid "Unable to add comment"
msgstr "Kommentar konnte nicht hinzugefügt werden"
#: src/views/board/components/NewCardForm.tsx:125
#: src/views/board/components/NewCardForm.tsx:142
msgid "Unable to create card"
msgstr "Karte konnte nicht erstellt werden"
@@ -1424,7 +1455,7 @@ msgstr "Board-Sichtbarkeit konnte nicht aktualisiert werden"
msgid "Unable to update card"
msgstr "Karte konnte nicht aktualisiert werden"
#: src/views/card/components/Comment.tsx:61
#: src/views/card/components/Comment.tsx:63
msgid "Unable to update comment"
msgstr "Kommentar konnte nicht aktualisiert werden"
@@ -1477,11 +1508,11 @@ msgstr "Unbegrenzte listen"
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:82
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:90
#: src/views/settings/components/UpdateDisplayNameForm.tsx:79
#: src/views/board/components/UpdateBoardSlugForm.tsx:173
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
msgid "Update"
msgstr "Aktualisieren"
#: src/components/LabelForm.tsx:233
#: src/components/LabelForm.tsx:236
msgid "Update label"
msgstr "Label aktualisieren"
@@ -1526,6 +1557,10 @@ msgstr "Vorlage verwenden"
msgid "User"
msgstr "Benutzer"
#: src/views/members/components/InviteMemberForm.tsx:58
msgid "User is already a member of this workspace"
msgstr "Benutzer ist bereits Mitglied dieses Arbeitsbereichs"
#: src/views/boards/components/TemplateBoards.tsx:37
msgid "Video"
msgstr "Video"
@@ -1542,10 +1577,18 @@ msgstr "Verwalte deine Abrechnung und dein Abonnement."
msgid "View docs"
msgstr "Dokumentation ansehen"
#: src/views/public/board/index.tsx:120
msgid "View only"
msgstr "Nur ansehen"
#: src/views/home/components/Features.tsx:147
msgid "View our roadmap."
msgstr "Sieh dir unsere roadmap an."
#: src/views/public/board/index.tsx:149
msgid "View workspace"
msgstr "Workspace anzeigen"
#: src/views/board/components/VisibilityButton.tsx:91
msgid "Visibility"
msgstr "Sichtbarkeit"
@@ -1578,7 +1621,7 @@ msgstr "Als Trello 2011 auf den markt kam, beeindruckte es alle mit seiner sorgf
msgid "Why make an open source Trello?"
msgstr "Warum ein open source Trello entwickeln?"
#: src/views/board/index.tsx:241
#: src/views/board/index.tsx:332
msgid "Workspace"
msgstr "Arbeitsbereich"

File diff suppressed because one or more lines are too long

View File

@@ -13,7 +13,7 @@ msgstr ""
"Language-Team: \n"
"Plural-Forms: \n"
#: src/views/card/components/Comment.tsx:121
#: src/views/card/components/Comment.tsx:123
msgid " (edited)"
msgstr " (edited)"
@@ -28,7 +28,7 @@ msgid "{0} | {1}"
msgstr "{0} | {1}"
#. placeholder {0}: labelPublicIds.length
#: src/views/board/components/NewCardForm.tsx:365
#: src/views/board/components/NewCardForm.tsx:392
msgid "{0} labels"
msgstr "{0} labels"
@@ -60,7 +60,7 @@ msgstr "A powerful, flexible kanban app that helps you organise work, track prog
msgid "Account deleted"
msgstr "Account deleted"
#: src/views/public/board/CardModal.tsx:104
#: src/views/public/board/CardModal.tsx:128
#: src/views/card/index.tsx:256
msgid "Activity"
msgstr "Activity"
@@ -74,11 +74,11 @@ msgid "Add a card"
msgstr "Add a card"
#: src/views/card/components/NewCommentForm.tsx:57
#: src/views/card/components/Comment.tsx:144
#: src/views/card/components/Comment.tsx:146
msgid "Add a comment..."
msgstr "Add a comment..."
#: src/components/Editor.tsx:302
#: src/components/Editor.tsx:303
msgid "Add description... (type '/' to open commands)"
msgstr "Add description... (type '/' to open commands)"
@@ -87,7 +87,7 @@ msgstr "Add description... (type '/' to open commands)"
msgid "Add label"
msgstr "Add label"
#: src/views/members/components/InviteMemberForm.tsx:50
#: src/views/members/components/InviteMemberForm.tsx:85
#: src/views/card/components/MemberSelector.tsx:130
msgid "Add member"
msgstr "Add member"
@@ -161,6 +161,10 @@ msgstr "Are you sure you want to delete this card?"
msgid "Are you sure you want to delete this comment?"
msgstr "Are you sure you want to delete this comment?"
#: src/components/DeleteLabelConfirmation.tsx:39
msgid "Are you sure you want to delete this label?"
msgstr "Are you sure you want to delete this label?"
#: src/views/settings/components/DeleteAccountConfirmation.tsx:54
msgid "Are you sure you want to delete your account?"
msgstr "Are you sure you want to delete your account?"
@@ -198,7 +202,7 @@ msgstr "Billing portal"
msgid "Blog Post"
msgstr "Blog Post"
#: src/views/board/index.tsx:241
#: src/views/board/index.tsx:332
msgid "Board"
msgstr "Board"
@@ -214,7 +218,8 @@ msgstr "Board name cannot exceed 100 characters"
msgid "Board name is required"
msgstr "Board name is required"
#: src/views/board/index.tsx:267
#: src/views/public/board/index.tsx:143
#: src/views/board/index.tsx:358
msgid "Board not found"
msgstr "Board not found"
@@ -226,7 +231,7 @@ msgstr "Board URL can only contain letters, numbers, and hyphens"
msgid "Board URL cannot exceed 60 characters"
msgstr "Board URL cannot exceed 60 characters"
#: src/views/public/board/index.tsx:53
#: src/views/public/board/index.tsx:59
msgid "Board URL copied to clipboard"
msgstr "Board URL copied to clipboard"
@@ -274,7 +279,8 @@ msgstr "Bug Report"
#: src/views/members/components/DeleteMemberConfirmation.tsx:55
#: src/views/card/components/DeleteCommentConfirmation.tsx:76
#: src/views/card/components/DeleteCardConfirmation.tsx:86
#: src/views/card/components/Comment.tsx:156
#: src/views/card/components/Comment.tsx:158
#: src/components/DeleteLabelConfirmation.tsx:47
msgid "Cancel"
msgstr "Cancel"
@@ -282,7 +288,7 @@ msgstr "Cancel"
msgid "Card not found"
msgstr "Card not found"
#: src/views/board/components/NewCardForm.tsx:254
#: src/views/board/components/NewCardForm.tsx:278
msgid "Card title"
msgstr "Card title"
@@ -375,7 +381,7 @@ msgid "Control who can view and edit your boards."
msgstr "Control who can view and edit your boards."
#: src/views/board/components/NewListForm.tsx:140
#: src/views/board/components/NewCardForm.tsx:391
#: src/views/board/components/NewCardForm.tsx:418
#: src/components/LabelForm.tsx:212
msgid "Create another"
msgstr "Create another"
@@ -392,15 +398,15 @@ msgstr "Create another"
msgid "Create board"
msgstr "Create board"
#: src/views/board/components/NewCardForm.tsx:401
#: src/views/board/components/NewCardForm.tsx:428
msgid "Create card"
msgstr "Create card"
#: src/components/LabelForm.tsx:233
#: src/components/LabelForm.tsx:236
msgid "Create label"
msgstr "Create label"
#: src/views/board/components/NewListForm.tsx:148
#: src/views/board/components/NewListForm.tsx:152
msgid "Create list"
msgstr "Create list"
@@ -413,11 +419,11 @@ msgid "Create new key"
msgstr "Create new key"
#: src/views/card/components/LabelSelector.tsx:98
#: src/views/board/components/NewCardForm.tsx:327
#: src/views/board/components/NewCardForm.tsx:354
msgid "Create new label"
msgstr "Create new label"
#: src/views/board/index.tsx:335
#: src/views/board/index.tsx:426
msgid "Create new list"
msgstr "Create new list"
@@ -453,6 +459,7 @@ msgstr "Dark"
#: src/views/card/components/DeleteCommentConfirmation.tsx:82
#: src/views/card/components/DeleteCardConfirmation.tsx:92
#: src/components/LabelForm.tsx:226
#: src/components/DeleteLabelConfirmation.tsx:49
msgid "Delete"
msgstr "Delete"
@@ -470,7 +477,7 @@ msgstr "Delete board"
msgid "Delete card"
msgstr "Delete card"
#: src/views/card/components/Comment.tsx:89
#: src/views/card/components/Comment.tsx:91
msgid "Delete comment"
msgstr "Delete comment"
@@ -546,7 +553,7 @@ msgstr "Done"
msgid "Edit board URL"
msgstr "Edit board URL"
#: src/views/card/components/Comment.tsx:80
#: src/views/card/components/Comment.tsx:82
msgid "Edit comment"
msgstr "Edit comment"
@@ -566,7 +573,7 @@ msgstr "Editing"
msgid "email"
msgstr "email"
#: src/views/members/components/InviteMemberForm.tsx:64
#: src/views/members/components/InviteMemberForm.tsx:99
msgid "Email"
msgstr "Email"
@@ -590,6 +597,10 @@ msgstr "Enter your password"
msgid "Error deleting account"
msgstr "Error deleting account"
#: src/components/DeleteLabelConfirmation.tsx:22
msgid "Error deleting label"
msgstr "Error deleting label"
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:45
msgid "Error deleting workspace"
msgstr "Error deleting workspace"
@@ -598,6 +609,11 @@ msgstr "Error deleting workspace"
msgid "Error disconnecting Trello"
msgstr "Error disconnecting Trello"
#: src/views/members/components/InviteMemberForm.tsx:57
#: src/views/members/components/InviteMemberForm.tsx:63
msgid "Error inviting member"
msgstr "Error inviting member"
#: src/views/settings/components/UpdateDisplayNameForm.tsx:54
msgid "Error updating display name"
msgstr "Error updating display name"
@@ -713,7 +729,7 @@ msgstr "Get Started"
msgid "Get started by creating a new board"
msgstr "Get started by creating a new board"
#: src/views/board/index.tsx:327
#: src/views/board/index.tsx:418
msgid "Get started by creating a new list"
msgstr "Get started by creating a new list"
@@ -840,11 +856,19 @@ msgstr "Integrations"
msgid "Interviewing"
msgstr "Interviewing"
#: src/views/members/components/InviteMemberForm.tsx:26
msgid "Invalid email address"
msgstr "Invalid email address"
#: src/views/members/index.tsx:169
msgid "Invite"
msgstr "Invite"
#: src/views/members/components/InviteMemberForm.tsx:82
#: src/views/members/components/InviteMemberForm.tsx:113
msgid "Invite another"
msgstr "Invite another"
#: src/views/members/components/InviteMemberForm.tsx:123
#: src/views/card/components/MemberSelector.tsx:112
msgid "Invite member"
msgstr "Invite member"
@@ -867,7 +891,7 @@ msgid "Keep in mind that this action is irreversible."
msgstr "Keep in mind that this action is irreversible."
#: src/views/card/index.tsx:113
#: src/views/board/components/NewCardForm.tsx:331
#: src/views/board/components/NewCardForm.tsx:358
#: src/views/board/components/Filters.tsx:101
msgid "Labels"
msgstr "Labels"
@@ -896,7 +920,7 @@ msgstr "License"
msgid "Light"
msgstr "Light"
#: src/views/public/board/index.tsx:51
#: src/views/public/board/index.tsx:57
msgid "Link copied"
msgstr "Link copied"
@@ -934,7 +958,7 @@ msgstr "Medium Priority"
#: src/views/members/index.tsx:161
#: src/views/card/index.tsx:121
#: src/views/board/components/NewCardForm.tsx:290
#: src/views/board/components/NewCardForm.tsx:317
#: src/views/board/components/Filters.tsx:93
#: src/components/SideNavigation.tsx:73
msgid "Members"
@@ -974,7 +998,7 @@ msgstr "New"
msgid "New board"
msgstr "New board"
#: src/views/board/components/NewCardForm.tsx:237
#: src/views/board/components/NewCardForm.tsx:261
msgid "New card"
msgstr "New card"
@@ -986,7 +1010,7 @@ msgstr "New import"
msgid "New label"
msgstr "New label"
#: src/views/board/index.tsx:304
#: src/views/board/index.tsx:395
#: src/views/board/components/NewListForm.tsx:112
msgid "New list"
msgstr "New list"
@@ -1023,7 +1047,7 @@ msgstr "No boards found"
msgid "No credit card required"
msgstr "No credit card required"
#: src/views/board/index.tsx:324
#: src/views/board/index.tsx:415
msgid "No lists"
msgstr "No lists"
@@ -1104,6 +1128,7 @@ msgstr "Please select a file to upload."
#: src/views/settings/components/DeleteAccountConfirmation.tsx:40
#: src/views/settings/components/Avatar.tsx:40
#: src/views/settings/components/Avatar.tsx:98
#: src/views/members/components/InviteMemberForm.tsx:64
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
#: src/views/card/index.tsx:159
#: src/views/card/components/NewCommentForm.tsx:31
@@ -1112,16 +1137,17 @@ msgstr "Please select a file to upload."
#: src/views/card/components/LabelSelector.tsx:73
#: src/views/card/components/DeleteCommentConfirmation.tsx:45
#: src/views/card/components/DeleteCardConfirmation.tsx:52
#: src/views/card/components/Comment.tsx:62
#: src/views/card/components/Comment.tsx:64
#: src/views/boards/components/ImportBoardsForm.tsx:205
#: src/views/board/index.tsx:135
#: src/views/board/index.tsx:191
#: src/views/board/components/VisibilityButton.tsx:53
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
#: src/views/board/components/NewListForm.tsx:78
#: src/views/board/components/NewCardForm.tsx:128
#: src/views/board/components/NewCardForm.tsx:145
#: src/components/NewWorkspaceForm.tsx:41
#: src/components/FeedbackModal.tsx:41
#: src/components/DeleteLabelConfirmation.tsx:23
msgid "Please try again later, or contact customer support."
msgstr "Please try again later, or contact customer support."
@@ -1232,7 +1258,7 @@ msgstr "Role"
msgid "Run on your own infrastructure"
msgstr "Run on your own infrastructure"
#: src/views/card/components/Comment.tsx:163
#: src/views/card/components/Comment.tsx:165
msgid "Save"
msgstr "Save"
@@ -1384,9 +1410,14 @@ msgstr "They won't be able to access this workspace."
#: src/views/card/components/DeleteCommentConfirmation.tsx:68
#: src/views/card/components/DeleteCardConfirmation.tsx:78
#: src/components/DeleteLabelConfirmation.tsx:42
msgid "This action can't be undone."
msgstr "This action can't be undone."
#: src/views/public/board/index.tsx:146
msgid "This board is private or does not exist"
msgstr "This board is private or does not exist"
#: src/views/board/components/UpdateBoardSlugForm.tsx:135
msgid "This board URL has already been taken"
msgstr "This board URL has already been taken"
@@ -1436,7 +1467,7 @@ msgstr "Triaging"
msgid "Unable to add comment"
msgstr "Unable to add comment"
#: src/views/board/components/NewCardForm.tsx:125
#: src/views/board/components/NewCardForm.tsx:142
msgid "Unable to create card"
msgstr "Unable to create card"
@@ -1477,7 +1508,7 @@ msgstr "Unable to update board visibility"
msgid "Unable to update card"
msgstr "Unable to update card"
#: src/views/card/components/Comment.tsx:61
#: src/views/card/components/Comment.tsx:63
msgid "Unable to update comment"
msgstr "Unable to update comment"
@@ -1530,11 +1561,11 @@ msgstr "Unlimited lists"
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:82
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:90
#: src/views/settings/components/UpdateDisplayNameForm.tsx:79
#: src/views/board/components/UpdateBoardSlugForm.tsx:173
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
msgid "Update"
msgstr "Update"
#: src/components/LabelForm.tsx:233
#: src/components/LabelForm.tsx:236
msgid "Update label"
msgstr "Update label"
@@ -1579,6 +1610,10 @@ msgstr "Use template"
msgid "User"
msgstr "User"
#: src/views/members/components/InviteMemberForm.tsx:58
msgid "User is already a member of this workspace"
msgstr "User is already a member of this workspace"
#: src/views/boards/components/TemplateBoards.tsx:37
msgid "Video"
msgstr "Video"
@@ -1595,10 +1630,18 @@ msgstr "View and manage your billing and subscription."
msgid "View docs"
msgstr "View docs"
#: src/views/public/board/index.tsx:120
msgid "View only"
msgstr "View only"
#: src/views/home/components/Features.tsx:147
msgid "View our roadmap."
msgstr "View our roadmap."
#: src/views/public/board/index.tsx:149
msgid "View workspace"
msgstr "View workspace"
#: src/views/board/components/VisibilityButton.tsx:91
msgid "Visibility"
msgstr "Visibility"
@@ -1635,7 +1678,7 @@ msgstr "When Trello launched in 2011, it blew everyone away with its carefully d
msgid "Why make an open source Trello?"
msgstr "Why make an open source Trello?"
#: src/views/board/index.tsx:241
#: src/views/board/index.tsx:332
msgid "Workspace"
msgstr "Workspace"

File diff suppressed because one or more lines are too long

View File

@@ -13,7 +13,7 @@ msgstr ""
"Language-Team: \n"
"Plural-Forms: \n"
#: src/views/card/components/Comment.tsx:121
#: src/views/card/components/Comment.tsx:123
msgid " (edited)"
msgstr " (editado)"
@@ -28,7 +28,7 @@ msgid "{0} | {1}"
msgstr "{0} | {1}"
#. placeholder {0}: labelPublicIds.length
#: src/views/board/components/NewCardForm.tsx:365
#: src/views/board/components/NewCardForm.tsx:392
msgid "{0} labels"
msgstr "{0} etiquetas"
@@ -48,7 +48,7 @@ msgstr "Una aplicación kanban potente y flexible que te ayuda a organizar el tr
msgid "Account deleted"
msgstr "Cuenta eliminada"
#: src/views/public/board/CardModal.tsx:104
#: src/views/public/board/CardModal.tsx:128
#: src/views/card/index.tsx:256
msgid "Activity"
msgstr "Actividad"
@@ -62,11 +62,11 @@ msgid "Add a card"
msgstr "Añadir una tarjeta"
#: src/views/card/components/NewCommentForm.tsx:57
#: src/views/card/components/Comment.tsx:144
#: src/views/card/components/Comment.tsx:146
msgid "Add a comment..."
msgstr "Añadir un comentario..."
#: src/components/Editor.tsx:302
#: src/components/Editor.tsx:303
msgid "Add description... (type '/' to open commands)"
msgstr "Añadir descripción... (escribe '/' para abrir comandos)"
@@ -75,7 +75,7 @@ msgstr "Añadir descripción... (escribe '/' para abrir comandos)"
msgid "Add label"
msgstr "Añadir etiqueta"
#: src/views/members/components/InviteMemberForm.tsx:50
#: src/views/members/components/InviteMemberForm.tsx:85
#: src/views/card/components/MemberSelector.tsx:130
msgid "Add member"
msgstr "Añadir miembro"
@@ -145,6 +145,10 @@ msgstr "¿Estás seguro de que quieres eliminar esta tarjeta?"
msgid "Are you sure you want to delete this comment?"
msgstr "¿Estás seguro de que quieres eliminar este comentario?"
#: src/components/DeleteLabelConfirmation.tsx:39
msgid "Are you sure you want to delete this label?"
msgstr "¿Estás seguro de que quieres eliminar esta etiqueta?"
#: src/views/settings/components/DeleteAccountConfirmation.tsx:54
msgid "Are you sure you want to delete your account?"
msgstr "¿Estás seguro de que quieres eliminar tu cuenta?"
@@ -178,7 +182,7 @@ msgstr "Portal de facturación"
msgid "Blog Post"
msgstr "Entrada de blog"
#: src/views/board/index.tsx:241
#: src/views/board/index.tsx:332
msgid "Board"
msgstr "Tablero"
@@ -190,7 +194,8 @@ msgstr "El nombre del tablero no puede exceder los 100 caracteres"
msgid "Board name is required"
msgstr "El nombre del tablero es obligatorio"
#: src/views/board/index.tsx:267
#: src/views/public/board/index.tsx:143
#: src/views/board/index.tsx:358
msgid "Board not found"
msgstr "Tablero no encontrado"
@@ -202,7 +207,7 @@ msgstr "La URL del tablero solo puede contener letras, números y guiones"
msgid "Board URL cannot exceed 60 characters"
msgstr "La URL del tablero no puede exceder los 60 caracteres"
#: src/views/public/board/index.tsx:53
#: src/views/public/board/index.tsx:59
msgid "Board URL copied to clipboard"
msgstr "URL del tablero copiada al portapapeles"
@@ -246,7 +251,8 @@ msgstr "Informe de error"
#: src/views/members/components/DeleteMemberConfirmation.tsx:55
#: src/views/card/components/DeleteCommentConfirmation.tsx:76
#: src/views/card/components/DeleteCardConfirmation.tsx:86
#: src/views/card/components/Comment.tsx:156
#: src/views/card/components/Comment.tsx:158
#: src/components/DeleteLabelConfirmation.tsx:47
msgid "Cancel"
msgstr "Cancelar"
@@ -254,7 +260,7 @@ msgstr "Cancelar"
msgid "Card not found"
msgstr "Tarjeta no encontrada"
#: src/views/board/components/NewCardForm.tsx:254
#: src/views/board/components/NewCardForm.tsx:278
msgid "Card title"
msgstr "Título de la tarjeta"
@@ -347,7 +353,7 @@ msgid "Control who can view and edit your boards."
msgstr "Controla quién puede ver y editar tus tableros."
#: src/views/board/components/NewListForm.tsx:140
#: src/views/board/components/NewCardForm.tsx:391
#: src/views/board/components/NewCardForm.tsx:418
#: src/components/LabelForm.tsx:212
msgid "Create another"
msgstr "Crear otro"
@@ -356,15 +362,15 @@ msgstr "Crear otro"
msgid "Create board"
msgstr "Crear tablero"
#: src/views/board/components/NewCardForm.tsx:401
#: src/views/board/components/NewCardForm.tsx:428
msgid "Create card"
msgstr "Crear tarjeta"
#: src/components/LabelForm.tsx:233
#: src/components/LabelForm.tsx:236
msgid "Create label"
msgstr "Crear etiqueta"
#: src/views/board/components/NewListForm.tsx:148
#: src/views/board/components/NewListForm.tsx:152
msgid "Create list"
msgstr "Crear lista"
@@ -377,11 +383,11 @@ msgid "Create new key"
msgstr "Crear nueva clave"
#: src/views/card/components/LabelSelector.tsx:98
#: src/views/board/components/NewCardForm.tsx:327
#: src/views/board/components/NewCardForm.tsx:354
msgid "Create new label"
msgstr "Crear nueva etiqueta"
#: src/views/board/index.tsx:335
#: src/views/board/index.tsx:426
msgid "Create new list"
msgstr "Crear nueva lista"
@@ -417,6 +423,7 @@ msgstr "Oscuro"
#: src/views/card/components/DeleteCommentConfirmation.tsx:82
#: src/views/card/components/DeleteCardConfirmation.tsx:92
#: src/components/LabelForm.tsx:226
#: src/components/DeleteLabelConfirmation.tsx:49
msgid "Delete"
msgstr "Eliminar"
@@ -434,7 +441,7 @@ msgstr "Eliminar tablero"
msgid "Delete card"
msgstr "Eliminar tarjeta"
#: src/views/card/components/Comment.tsx:89
#: src/views/card/components/Comment.tsx:91
msgid "Delete comment"
msgstr "Eliminar comentario"
@@ -510,7 +517,7 @@ msgstr "Terminado"
msgid "Edit board URL"
msgstr "Editar URL del tablero"
#: src/views/card/components/Comment.tsx:80
#: src/views/card/components/Comment.tsx:82
msgid "Edit comment"
msgstr "Editar comentario"
@@ -530,7 +537,7 @@ msgstr "Editando"
msgid "email"
msgstr "correo electrónico"
#: src/views/members/components/InviteMemberForm.tsx:64
#: src/views/members/components/InviteMemberForm.tsx:99
msgid "Email"
msgstr "Correo electrónico"
@@ -554,6 +561,10 @@ msgstr "Introduce tu contraseña"
msgid "Error deleting account"
msgstr "Error al eliminar la cuenta"
#: src/components/DeleteLabelConfirmation.tsx:22
msgid "Error deleting label"
msgstr "Error al eliminar la etiqueta"
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:45
msgid "Error deleting workspace"
msgstr "Error al eliminar el espacio de trabajo"
@@ -562,6 +573,11 @@ msgstr "Error al eliminar el espacio de trabajo"
msgid "Error disconnecting Trello"
msgstr "Error al desconectar Trello"
#: src/views/members/components/InviteMemberForm.tsx:57
#: src/views/members/components/InviteMemberForm.tsx:63
msgid "Error inviting member"
msgstr "Error al invitar al miembro"
#: src/views/settings/components/UpdateDisplayNameForm.tsx:54
msgid "Error updating display name"
msgstr "Error al actualizar el nombre visible"
@@ -676,7 +692,7 @@ msgstr "Comenzar"
msgid "Get started by creating a new board"
msgstr "Comienza creando un nuevo tablero"
#: src/views/board/index.tsx:327
#: src/views/board/index.tsx:418
msgid "Get started by creating a new list"
msgstr "Comienza creando una nueva lista"
@@ -799,11 +815,19 @@ msgstr "Integraciones"
msgid "Interviewing"
msgstr "Entrevistando"
#: src/views/members/components/InviteMemberForm.tsx:26
msgid "Invalid email address"
msgstr "Dirección de correo electrónico no válida"
#: src/views/members/index.tsx:169
msgid "Invite"
msgstr "Invitar"
#: src/views/members/components/InviteMemberForm.tsx:82
#: src/views/members/components/InviteMemberForm.tsx:113
msgid "Invite another"
msgstr "Invitar a otro"
#: src/views/members/components/InviteMemberForm.tsx:123
#: src/views/card/components/MemberSelector.tsx:112
msgid "Invite member"
msgstr "Invitar miembro"
@@ -826,7 +850,7 @@ msgid "Keep in mind that this action is irreversible."
msgstr "Ten en cuenta que esta acción es irreversible."
#: src/views/card/index.tsx:113
#: src/views/board/components/NewCardForm.tsx:331
#: src/views/board/components/NewCardForm.tsx:358
#: src/views/board/components/Filters.tsx:101
msgid "Labels"
msgstr "Etiquetas"
@@ -855,7 +879,7 @@ msgstr "Licencia"
msgid "Light"
msgstr "Claro"
#: src/views/public/board/index.tsx:51
#: src/views/public/board/index.tsx:57
msgid "Link copied"
msgstr "Enlace copiado"
@@ -893,7 +917,7 @@ msgstr "Prioridad media"
#: src/views/members/index.tsx:161
#: src/views/card/index.tsx:121
#: src/views/board/components/NewCardForm.tsx:290
#: src/views/board/components/NewCardForm.tsx:317
#: src/views/board/components/Filters.tsx:93
#: src/components/SideNavigation.tsx:73
msgid "Members"
@@ -933,7 +957,7 @@ msgstr "Nuevo"
msgid "New board"
msgstr "Nuevo tablero"
#: src/views/board/components/NewCardForm.tsx:237
#: src/views/board/components/NewCardForm.tsx:261
msgid "New card"
msgstr "Nueva tarjeta"
@@ -945,7 +969,7 @@ msgstr "Nueva importación"
msgid "New label"
msgstr "Nueva etiqueta"
#: src/views/board/index.tsx:304
#: src/views/board/index.tsx:395
#: src/views/board/components/NewListForm.tsx:112
msgid "New list"
msgstr "Nueva lista"
@@ -978,7 +1002,7 @@ msgstr "No se encontraron tableros"
msgid "No credit card required"
msgstr "No se requiere tarjeta de crédito"
#: src/views/board/index.tsx:324
#: src/views/board/index.tsx:415
msgid "No lists"
msgstr "Sin listas"
@@ -1059,6 +1083,7 @@ msgstr "Por favor selecciona un archivo para subir."
#: src/views/settings/components/DeleteAccountConfirmation.tsx:40
#: src/views/settings/components/Avatar.tsx:40
#: src/views/settings/components/Avatar.tsx:98
#: src/views/members/components/InviteMemberForm.tsx:64
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
#: src/views/card/index.tsx:159
#: src/views/card/components/NewCommentForm.tsx:31
@@ -1067,16 +1092,17 @@ msgstr "Por favor selecciona un archivo para subir."
#: src/views/card/components/LabelSelector.tsx:73
#: src/views/card/components/DeleteCommentConfirmation.tsx:45
#: src/views/card/components/DeleteCardConfirmation.tsx:52
#: src/views/card/components/Comment.tsx:62
#: src/views/card/components/Comment.tsx:64
#: src/views/boards/components/ImportBoardsForm.tsx:205
#: src/views/board/index.tsx:135
#: src/views/board/index.tsx:191
#: src/views/board/components/VisibilityButton.tsx:53
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
#: src/views/board/components/NewListForm.tsx:78
#: src/views/board/components/NewCardForm.tsx:128
#: src/views/board/components/NewCardForm.tsx:145
#: src/components/NewWorkspaceForm.tsx:41
#: src/components/FeedbackModal.tsx:41
#: src/components/DeleteLabelConfirmation.tsx:23
msgid "Please try again later, or contact customer support."
msgstr "Por favor, inténtalo de nuevo más tarde o contacta con atención al cliente."
@@ -1187,7 +1213,7 @@ msgstr "Rol"
msgid "Run on your own infrastructure"
msgstr "Ejecuta en tu propia infraestructura"
#: src/views/card/components/Comment.tsx:163
#: src/views/card/components/Comment.tsx:165
msgid "Save"
msgstr "Guardar"
@@ -1335,9 +1361,14 @@ msgstr "No podrán acceder a este espacio de trabajo."
#: src/views/card/components/DeleteCommentConfirmation.tsx:68
#: src/views/card/components/DeleteCardConfirmation.tsx:78
#: src/components/DeleteLabelConfirmation.tsx:42
msgid "This action can't be undone."
msgstr "Esta acción no se puede deshacer."
#: src/views/public/board/index.tsx:146
msgid "This board is private or does not exist"
msgstr "Este tablero es privado o no existe"
#: src/views/board/components/UpdateBoardSlugForm.tsx:135
msgid "This board URL has already been taken"
msgstr "Esta URL de tablero ya ha sido utilizada"
@@ -1383,7 +1414,7 @@ msgstr "Clasificación"
msgid "Unable to add comment"
msgstr "No se puede añadir el comentario"
#: src/views/board/components/NewCardForm.tsx:125
#: src/views/board/components/NewCardForm.tsx:142
msgid "Unable to create card"
msgstr "No se puede crear la tarjeta"
@@ -1424,7 +1455,7 @@ msgstr "No se puede actualizar la visibilidad del tablero"
msgid "Unable to update card"
msgstr "No se puede actualizar la tarjeta"
#: src/views/card/components/Comment.tsx:61
#: src/views/card/components/Comment.tsx:63
msgid "Unable to update comment"
msgstr "No se puede actualizar el comentario"
@@ -1477,11 +1508,11 @@ msgstr "Listas ilimitadas"
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:82
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:90
#: src/views/settings/components/UpdateDisplayNameForm.tsx:79
#: src/views/board/components/UpdateBoardSlugForm.tsx:173
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
msgid "Update"
msgstr "Actualizar"
#: src/components/LabelForm.tsx:233
#: src/components/LabelForm.tsx:236
msgid "Update label"
msgstr "Actualizar etiqueta"
@@ -1526,6 +1557,10 @@ msgstr "Usar plantilla"
msgid "User"
msgstr "Usuario"
#: src/views/members/components/InviteMemberForm.tsx:58
msgid "User is already a member of this workspace"
msgstr "El usuario ya es miembro de este espacio de trabajo"
#: src/views/boards/components/TemplateBoards.tsx:37
msgid "Video"
msgstr "Video"
@@ -1542,10 +1577,18 @@ msgstr "Ver y gestionar tu facturación y suscripción."
msgid "View docs"
msgstr "Ver documentación"
#: src/views/public/board/index.tsx:120
msgid "View only"
msgstr "Solo visualización"
#: src/views/home/components/Features.tsx:147
msgid "View our roadmap."
msgstr "Ver nuestra hoja de ruta."
#: src/views/public/board/index.tsx:149
msgid "View workspace"
msgstr "Ver espacio de trabajo"
#: src/views/board/components/VisibilityButton.tsx:91
msgid "Visibility"
msgstr "Visibilidad"
@@ -1578,7 +1621,7 @@ msgstr "Cuando Trello se lanzó en 2011, impresionó a todos con su simplicidad
msgid "Why make an open source Trello?"
msgstr "¿Por qué crear un Trello de código abierto?"
#: src/views/board/index.tsx:241
#: src/views/board/index.tsx:332
msgid "Workspace"
msgstr "Espacio de trabajo"

File diff suppressed because one or more lines are too long

View File

@@ -13,7 +13,7 @@ msgstr ""
"Language-Team: \n"
"Plural-Forms: \n"
#: src/views/card/components/Comment.tsx:121
#: src/views/card/components/Comment.tsx:123
msgid " (edited)"
msgstr " (modifié)"
@@ -28,7 +28,7 @@ msgid "{0} | {1}"
msgstr "{0} | {1}"
#. placeholder {0}: labelPublicIds.length
#: src/views/board/components/NewCardForm.tsx:365
#: src/views/board/components/NewCardForm.tsx:392
msgid "{0} labels"
msgstr "{0} étiquettes"
@@ -48,7 +48,7 @@ msgstr "Une application kanban puissante et flexible qui vous aide à organiser
msgid "Account deleted"
msgstr "Compte supprimé"
#: src/views/public/board/CardModal.tsx:104
#: src/views/public/board/CardModal.tsx:128
#: src/views/card/index.tsx:256
msgid "Activity"
msgstr "Activité"
@@ -62,11 +62,11 @@ msgid "Add a card"
msgstr "Ajouter une carte"
#: src/views/card/components/NewCommentForm.tsx:57
#: src/views/card/components/Comment.tsx:144
#: src/views/card/components/Comment.tsx:146
msgid "Add a comment..."
msgstr "Ajouter un commentaire..."
#: src/components/Editor.tsx:302
#: src/components/Editor.tsx:303
msgid "Add description... (type '/' to open commands)"
msgstr "Ajouter une description... (tapez '/' pour ouvrir les commandes)"
@@ -75,7 +75,7 @@ msgstr "Ajouter une description... (tapez '/' pour ouvrir les commandes)"
msgid "Add label"
msgstr "Ajouter une étiquette"
#: src/views/members/components/InviteMemberForm.tsx:50
#: src/views/members/components/InviteMemberForm.tsx:85
#: src/views/card/components/MemberSelector.tsx:130
msgid "Add member"
msgstr "Ajouter un membre"
@@ -145,6 +145,10 @@ msgstr "Êtes-vous sûr de vouloir supprimer cette carte ?"
msgid "Are you sure you want to delete this comment?"
msgstr "Êtes-vous sûr de vouloir supprimer ce commentaire ?"
#: src/components/DeleteLabelConfirmation.tsx:39
msgid "Are you sure you want to delete this label?"
msgstr "Êtes-vous sûr de vouloir supprimer cette étiquette ?"
#: src/views/settings/components/DeleteAccountConfirmation.tsx:54
msgid "Are you sure you want to delete your account?"
msgstr "Êtes-vous sûr de vouloir supprimer votre compte ?"
@@ -178,7 +182,7 @@ msgstr "Portail de facturation"
msgid "Blog Post"
msgstr "Article de blog"
#: src/views/board/index.tsx:241
#: src/views/board/index.tsx:332
msgid "Board"
msgstr "Tableau"
@@ -190,7 +194,8 @@ msgstr "Le nom du tableau ne peut pas dépasser 100 caractères"
msgid "Board name is required"
msgstr "Le nom du tableau est requis"
#: src/views/board/index.tsx:267
#: src/views/public/board/index.tsx:143
#: src/views/board/index.tsx:358
msgid "Board not found"
msgstr "Tableau introuvable"
@@ -202,7 +207,7 @@ msgstr "L'URL du tableau ne peut contenir que des lettres, des chiffres et des t
msgid "Board URL cannot exceed 60 characters"
msgstr "L'URL du tableau ne peut pas dépasser 60 caractères"
#: src/views/public/board/index.tsx:53
#: src/views/public/board/index.tsx:59
msgid "Board URL copied to clipboard"
msgstr "URL du tableau copiée dans le presse-papiers"
@@ -246,7 +251,8 @@ msgstr "Rapport de bug"
#: src/views/members/components/DeleteMemberConfirmation.tsx:55
#: src/views/card/components/DeleteCommentConfirmation.tsx:76
#: src/views/card/components/DeleteCardConfirmation.tsx:86
#: src/views/card/components/Comment.tsx:156
#: src/views/card/components/Comment.tsx:158
#: src/components/DeleteLabelConfirmation.tsx:47
msgid "Cancel"
msgstr "Annuler"
@@ -254,7 +260,7 @@ msgstr "Annuler"
msgid "Card not found"
msgstr "Carte introuvable"
#: src/views/board/components/NewCardForm.tsx:254
#: src/views/board/components/NewCardForm.tsx:278
msgid "Card title"
msgstr "Titre de la carte"
@@ -347,7 +353,7 @@ msgid "Control who can view and edit your boards."
msgstr "Contrôlez qui peut voir et modifier vos tableaux."
#: src/views/board/components/NewListForm.tsx:140
#: src/views/board/components/NewCardForm.tsx:391
#: src/views/board/components/NewCardForm.tsx:418
#: src/components/LabelForm.tsx:212
msgid "Create another"
msgstr "Créer un autre"
@@ -356,15 +362,15 @@ msgstr "Créer un autre"
msgid "Create board"
msgstr "Créer un tableau"
#: src/views/board/components/NewCardForm.tsx:401
#: src/views/board/components/NewCardForm.tsx:428
msgid "Create card"
msgstr "Créer une carte"
#: src/components/LabelForm.tsx:233
#: src/components/LabelForm.tsx:236
msgid "Create label"
msgstr "Créer une étiquette"
#: src/views/board/components/NewListForm.tsx:148
#: src/views/board/components/NewListForm.tsx:152
msgid "Create list"
msgstr "Créer une liste"
@@ -377,11 +383,11 @@ msgid "Create new key"
msgstr "Créer une nouvelle clé"
#: src/views/card/components/LabelSelector.tsx:98
#: src/views/board/components/NewCardForm.tsx:327
#: src/views/board/components/NewCardForm.tsx:354
msgid "Create new label"
msgstr "Créer une nouvelle étiquette"
#: src/views/board/index.tsx:335
#: src/views/board/index.tsx:426
msgid "Create new list"
msgstr "Créer une nouvelle liste"
@@ -417,6 +423,7 @@ msgstr "Sombre"
#: src/views/card/components/DeleteCommentConfirmation.tsx:82
#: src/views/card/components/DeleteCardConfirmation.tsx:92
#: src/components/LabelForm.tsx:226
#: src/components/DeleteLabelConfirmation.tsx:49
msgid "Delete"
msgstr "Supprimer"
@@ -434,7 +441,7 @@ msgstr "Supprimer le tableau"
msgid "Delete card"
msgstr "Supprimer la carte"
#: src/views/card/components/Comment.tsx:89
#: src/views/card/components/Comment.tsx:91
msgid "Delete comment"
msgstr "Supprimer le commentaire"
@@ -510,7 +517,7 @@ msgstr "Fait"
msgid "Edit board URL"
msgstr "Modifier l'URL du tableau"
#: src/views/card/components/Comment.tsx:80
#: src/views/card/components/Comment.tsx:82
msgid "Edit comment"
msgstr "Modifier le commentaire"
@@ -530,7 +537,7 @@ msgstr "Édition"
msgid "email"
msgstr "e-mail"
#: src/views/members/components/InviteMemberForm.tsx:64
#: src/views/members/components/InviteMemberForm.tsx:99
msgid "Email"
msgstr "E-mail"
@@ -554,6 +561,10 @@ msgstr "Saisissez votre mot de passe"
msgid "Error deleting account"
msgstr "Erreur lors de la suppression du compte"
#: src/components/DeleteLabelConfirmation.tsx:22
msgid "Error deleting label"
msgstr "Erreur lors de la suppression de l'étiquette"
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:45
msgid "Error deleting workspace"
msgstr "Erreur lors de la suppression de l'espace de travail"
@@ -562,6 +573,11 @@ msgstr "Erreur lors de la suppression de l'espace de travail"
msgid "Error disconnecting Trello"
msgstr "Erreur lors de la déconnexion de Trello"
#: src/views/members/components/InviteMemberForm.tsx:57
#: src/views/members/components/InviteMemberForm.tsx:63
msgid "Error inviting member"
msgstr "Erreur lors de l'invitation du membre"
#: src/views/settings/components/UpdateDisplayNameForm.tsx:54
msgid "Error updating display name"
msgstr "Erreur lors de la mise à jour du nom d'affichage"
@@ -676,7 +692,7 @@ msgstr "Commencer"
msgid "Get started by creating a new board"
msgstr "Commencez par créer un nouveau tableau"
#: src/views/board/index.tsx:327
#: src/views/board/index.tsx:418
msgid "Get started by creating a new list"
msgstr "Commencez par créer une nouvelle liste"
@@ -799,11 +815,19 @@ msgstr "Intégrations"
msgid "Interviewing"
msgstr "Entretien"
#: src/views/members/components/InviteMemberForm.tsx:26
msgid "Invalid email address"
msgstr "Adresse e-mail invalide"
#: src/views/members/index.tsx:169
msgid "Invite"
msgstr "Inviter"
#: src/views/members/components/InviteMemberForm.tsx:82
#: src/views/members/components/InviteMemberForm.tsx:113
msgid "Invite another"
msgstr "Inviter un autre"
#: src/views/members/components/InviteMemberForm.tsx:123
#: src/views/card/components/MemberSelector.tsx:112
msgid "Invite member"
msgstr "Inviter un membre"
@@ -826,7 +850,7 @@ msgid "Keep in mind that this action is irreversible."
msgstr "Gardez à l'esprit que cette action est irréversible."
#: src/views/card/index.tsx:113
#: src/views/board/components/NewCardForm.tsx:331
#: src/views/board/components/NewCardForm.tsx:358
#: src/views/board/components/Filters.tsx:101
msgid "Labels"
msgstr "Étiquettes"
@@ -855,7 +879,7 @@ msgstr "Licence"
msgid "Light"
msgstr "Clair"
#: src/views/public/board/index.tsx:51
#: src/views/public/board/index.tsx:57
msgid "Link copied"
msgstr "Lien copié"
@@ -893,7 +917,7 @@ msgstr "Priorité moyenne"
#: src/views/members/index.tsx:161
#: src/views/card/index.tsx:121
#: src/views/board/components/NewCardForm.tsx:290
#: src/views/board/components/NewCardForm.tsx:317
#: src/views/board/components/Filters.tsx:93
#: src/components/SideNavigation.tsx:73
msgid "Members"
@@ -933,7 +957,7 @@ msgstr "Nouveau"
msgid "New board"
msgstr "Nouveau tableau"
#: src/views/board/components/NewCardForm.tsx:237
#: src/views/board/components/NewCardForm.tsx:261
msgid "New card"
msgstr "Nouvelle carte"
@@ -945,7 +969,7 @@ msgstr "Nouvel import"
msgid "New label"
msgstr "Nouvelle étiquette"
#: src/views/board/index.tsx:304
#: src/views/board/index.tsx:395
#: src/views/board/components/NewListForm.tsx:112
msgid "New list"
msgstr "Nouvelle liste"
@@ -978,7 +1002,7 @@ msgstr "Aucun tableau trouvé"
msgid "No credit card required"
msgstr "Aucune carte de crédit requise"
#: src/views/board/index.tsx:324
#: src/views/board/index.tsx:415
msgid "No lists"
msgstr "Aucune liste"
@@ -1059,6 +1083,7 @@ msgstr "Veuillez sélectionner un fichier à télécharger."
#: src/views/settings/components/DeleteAccountConfirmation.tsx:40
#: src/views/settings/components/Avatar.tsx:40
#: src/views/settings/components/Avatar.tsx:98
#: src/views/members/components/InviteMemberForm.tsx:64
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
#: src/views/card/index.tsx:159
#: src/views/card/components/NewCommentForm.tsx:31
@@ -1067,16 +1092,17 @@ msgstr "Veuillez sélectionner un fichier à télécharger."
#: src/views/card/components/LabelSelector.tsx:73
#: src/views/card/components/DeleteCommentConfirmation.tsx:45
#: src/views/card/components/DeleteCardConfirmation.tsx:52
#: src/views/card/components/Comment.tsx:62
#: src/views/card/components/Comment.tsx:64
#: src/views/boards/components/ImportBoardsForm.tsx:205
#: src/views/board/index.tsx:135
#: src/views/board/index.tsx:191
#: src/views/board/components/VisibilityButton.tsx:53
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
#: src/views/board/components/NewListForm.tsx:78
#: src/views/board/components/NewCardForm.tsx:128
#: src/views/board/components/NewCardForm.tsx:145
#: src/components/NewWorkspaceForm.tsx:41
#: src/components/FeedbackModal.tsx:41
#: src/components/DeleteLabelConfirmation.tsx:23
msgid "Please try again later, or contact customer support."
msgstr "Veuillez réessayer plus tard ou contacter le service client."
@@ -1187,7 +1213,7 @@ msgstr "Rôle"
msgid "Run on your own infrastructure"
msgstr "Exécutez sur votre propre infrastructure"
#: src/views/card/components/Comment.tsx:163
#: src/views/card/components/Comment.tsx:165
msgid "Save"
msgstr "Enregistrer"
@@ -1335,9 +1361,14 @@ msgstr "Ils ne pourront plus accéder à cet espace de travail."
#: src/views/card/components/DeleteCommentConfirmation.tsx:68
#: src/views/card/components/DeleteCardConfirmation.tsx:78
#: src/components/DeleteLabelConfirmation.tsx:42
msgid "This action can't be undone."
msgstr "Cette action ne peut pas être annulée."
#: src/views/public/board/index.tsx:146
msgid "This board is private or does not exist"
msgstr "Ce tableau est privé ou n'existe pas"
#: src/views/board/components/UpdateBoardSlugForm.tsx:135
msgid "This board URL has already been taken"
msgstr "Cette URL de tableau est déjà utilisée"
@@ -1383,7 +1414,7 @@ msgstr "Triage"
msgid "Unable to add comment"
msgstr "Impossible d'ajouter un commentaire"
#: src/views/board/components/NewCardForm.tsx:125
#: src/views/board/components/NewCardForm.tsx:142
msgid "Unable to create card"
msgstr "Impossible de créer la carte"
@@ -1424,7 +1455,7 @@ msgstr "Impossible de mettre à jour la visibilité du tableau"
msgid "Unable to update card"
msgstr "Impossible de mettre à jour la carte"
#: src/views/card/components/Comment.tsx:61
#: src/views/card/components/Comment.tsx:63
msgid "Unable to update comment"
msgstr "Impossible de mettre à jour le commentaire"
@@ -1477,11 +1508,11 @@ msgstr "Listes illimitées"
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:82
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:90
#: src/views/settings/components/UpdateDisplayNameForm.tsx:79
#: src/views/board/components/UpdateBoardSlugForm.tsx:173
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
msgid "Update"
msgstr "Mettre à jour"
#: src/components/LabelForm.tsx:233
#: src/components/LabelForm.tsx:236
msgid "Update label"
msgstr "Mettre à jour l'étiquette"
@@ -1526,6 +1557,10 @@ msgstr "Utiliser le modèle"
msgid "User"
msgstr "Utilisateur"
#: src/views/members/components/InviteMemberForm.tsx:58
msgid "User is already a member of this workspace"
msgstr "L'utilisateur est déjà membre de cet espace de travail"
#: src/views/boards/components/TemplateBoards.tsx:37
msgid "Video"
msgstr "Vidéo"
@@ -1542,10 +1577,18 @@ msgstr "Consultez et gérez votre facturation et votre abonnement."
msgid "View docs"
msgstr "Voir la documentation"
#: src/views/public/board/index.tsx:120
msgid "View only"
msgstr "Affichage uniquement"
#: src/views/home/components/Features.tsx:147
msgid "View our roadmap."
msgstr "Consultez notre feuille de route."
#: src/views/public/board/index.tsx:149
msgid "View workspace"
msgstr "Voir l'espace de travail"
#: src/views/board/components/VisibilityButton.tsx:91
msgid "Visibility"
msgstr "Visibilité"
@@ -1578,7 +1621,7 @@ msgstr "Quand Trello a été lancé en 2011, il a impressionné tout le monde pa
msgid "Why make an open source Trello?"
msgstr "Pourquoi créer un Trello open source ?"
#: src/views/board/index.tsx:241
#: src/views/board/index.tsx:332
msgid "Workspace"
msgstr "Espace de travail"

File diff suppressed because one or more lines are too long

View File

@@ -13,7 +13,7 @@ msgstr ""
"Language-Team: \n"
"Plural-Forms: \n"
#: src/views/card/components/Comment.tsx:121
#: src/views/card/components/Comment.tsx:123
msgid " (edited)"
msgstr " (modificato)"
@@ -28,7 +28,7 @@ msgid "{0} | {1}"
msgstr "{0} | {1}"
#. placeholder {0}: labelPublicIds.length
#: src/views/board/components/NewCardForm.tsx:365
#: src/views/board/components/NewCardForm.tsx:392
msgid "{0} labels"
msgstr "{0} etichette"
@@ -48,7 +48,7 @@ msgstr "Un'app kanban potente e flessibile che ti aiuta a organizzare il lavoro,
msgid "Account deleted"
msgstr "Account eliminato"
#: src/views/public/board/CardModal.tsx:104
#: src/views/public/board/CardModal.tsx:128
#: src/views/card/index.tsx:256
msgid "Activity"
msgstr "Attività"
@@ -62,11 +62,11 @@ msgid "Add a card"
msgstr "Aggiungi una carta"
#: src/views/card/components/NewCommentForm.tsx:57
#: src/views/card/components/Comment.tsx:144
#: src/views/card/components/Comment.tsx:146
msgid "Add a comment..."
msgstr "Aggiungi un commento..."
#: src/components/Editor.tsx:302
#: src/components/Editor.tsx:303
msgid "Add description... (type '/' to open commands)"
msgstr "Aggiungi descrizione... (digita '/' per aprire i comandi)"
@@ -75,7 +75,7 @@ msgstr "Aggiungi descrizione... (digita '/' per aprire i comandi)"
msgid "Add label"
msgstr "Aggiungi etichetta"
#: src/views/members/components/InviteMemberForm.tsx:50
#: src/views/members/components/InviteMemberForm.tsx:85
#: src/views/card/components/MemberSelector.tsx:130
msgid "Add member"
msgstr "Aggiungi membro"
@@ -145,6 +145,10 @@ msgstr "Sei sicuro di voler eliminare questa carta?"
msgid "Are you sure you want to delete this comment?"
msgstr "Sei sicuro di voler eliminare questo commento?"
#: src/components/DeleteLabelConfirmation.tsx:39
msgid "Are you sure you want to delete this label?"
msgstr "Sei sicuro di voler eliminare questa etichetta?"
#: src/views/settings/components/DeleteAccountConfirmation.tsx:54
msgid "Are you sure you want to delete your account?"
msgstr "Sei sicuro di voler eliminare il tuo account?"
@@ -178,7 +182,7 @@ msgstr "Portale di fatturazione"
msgid "Blog Post"
msgstr "Post del blog"
#: src/views/board/index.tsx:241
#: src/views/board/index.tsx:332
msgid "Board"
msgstr "Bacheca"
@@ -190,7 +194,8 @@ msgstr "Il nome della bacheca non può superare i 100 caratteri"
msgid "Board name is required"
msgstr "Il nome della bacheca è obbligatorio"
#: src/views/board/index.tsx:267
#: src/views/public/board/index.tsx:143
#: src/views/board/index.tsx:358
msgid "Board not found"
msgstr "Bacheca non trovata"
@@ -202,7 +207,7 @@ msgstr "L'URL della bacheca può contenere solo lettere, numeri e trattini"
msgid "Board URL cannot exceed 60 characters"
msgstr "L'URL della bacheca non può superare i 60 caratteri"
#: src/views/public/board/index.tsx:53
#: src/views/public/board/index.tsx:59
msgid "Board URL copied to clipboard"
msgstr "URL della bacheca copiato negli appunti"
@@ -246,7 +251,8 @@ msgstr "Segnalazione bug"
#: src/views/members/components/DeleteMemberConfirmation.tsx:55
#: src/views/card/components/DeleteCommentConfirmation.tsx:76
#: src/views/card/components/DeleteCardConfirmation.tsx:86
#: src/views/card/components/Comment.tsx:156
#: src/views/card/components/Comment.tsx:158
#: src/components/DeleteLabelConfirmation.tsx:47
msgid "Cancel"
msgstr "Annulla"
@@ -254,7 +260,7 @@ msgstr "Annulla"
msgid "Card not found"
msgstr "Carta non trovata"
#: src/views/board/components/NewCardForm.tsx:254
#: src/views/board/components/NewCardForm.tsx:278
msgid "Card title"
msgstr "Titolo della carta"
@@ -347,7 +353,7 @@ msgid "Control who can view and edit your boards."
msgstr "Controlla chi può visualizzare e modificare le tue bacheche."
#: src/views/board/components/NewListForm.tsx:140
#: src/views/board/components/NewCardForm.tsx:391
#: src/views/board/components/NewCardForm.tsx:418
#: src/components/LabelForm.tsx:212
msgid "Create another"
msgstr "Crea un altro"
@@ -356,15 +362,15 @@ msgstr "Crea un altro"
msgid "Create board"
msgstr "Crea bacheca"
#: src/views/board/components/NewCardForm.tsx:401
#: src/views/board/components/NewCardForm.tsx:428
msgid "Create card"
msgstr "Crea carta"
#: src/components/LabelForm.tsx:233
#: src/components/LabelForm.tsx:236
msgid "Create label"
msgstr "Crea etichetta"
#: src/views/board/components/NewListForm.tsx:148
#: src/views/board/components/NewListForm.tsx:152
msgid "Create list"
msgstr "Crea lista"
@@ -377,11 +383,11 @@ msgid "Create new key"
msgstr "Crea nuova chiave"
#: src/views/card/components/LabelSelector.tsx:98
#: src/views/board/components/NewCardForm.tsx:327
#: src/views/board/components/NewCardForm.tsx:354
msgid "Create new label"
msgstr "Crea nuova etichetta"
#: src/views/board/index.tsx:335
#: src/views/board/index.tsx:426
msgid "Create new list"
msgstr "Crea nuova lista"
@@ -417,6 +423,7 @@ msgstr "Scuro"
#: src/views/card/components/DeleteCommentConfirmation.tsx:82
#: src/views/card/components/DeleteCardConfirmation.tsx:92
#: src/components/LabelForm.tsx:226
#: src/components/DeleteLabelConfirmation.tsx:49
msgid "Delete"
msgstr "Elimina"
@@ -434,7 +441,7 @@ msgstr "Elimina bacheca"
msgid "Delete card"
msgstr "Elimina carta"
#: src/views/card/components/Comment.tsx:89
#: src/views/card/components/Comment.tsx:91
msgid "Delete comment"
msgstr "Elimina commento"
@@ -510,7 +517,7 @@ msgstr "Fatto"
msgid "Edit board URL"
msgstr "Modifica URL della bacheca"
#: src/views/card/components/Comment.tsx:80
#: src/views/card/components/Comment.tsx:82
msgid "Edit comment"
msgstr "Modifica commento"
@@ -530,7 +537,7 @@ msgstr "Modifica"
msgid "email"
msgstr "email"
#: src/views/members/components/InviteMemberForm.tsx:64
#: src/views/members/components/InviteMemberForm.tsx:99
msgid "Email"
msgstr "Email"
@@ -554,6 +561,10 @@ msgstr "Inserisci la tua password"
msgid "Error deleting account"
msgstr "Errore durante l'eliminazione dell'account"
#: src/components/DeleteLabelConfirmation.tsx:22
msgid "Error deleting label"
msgstr "Errore durante l'eliminazione dell'etichetta"
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:45
msgid "Error deleting workspace"
msgstr "Errore durante l'eliminazione dell'area di lavoro"
@@ -562,6 +573,11 @@ msgstr "Errore durante l'eliminazione dell'area di lavoro"
msgid "Error disconnecting Trello"
msgstr "Errore durante la disconnessione da Trello"
#: src/views/members/components/InviteMemberForm.tsx:57
#: src/views/members/components/InviteMemberForm.tsx:63
msgid "Error inviting member"
msgstr "Errore durante l'invito del membro"
#: src/views/settings/components/UpdateDisplayNameForm.tsx:54
msgid "Error updating display name"
msgstr "Errore durante l'aggiornamento del nome visualizzato"
@@ -676,7 +692,7 @@ msgstr "Inizia ora"
msgid "Get started by creating a new board"
msgstr "Inizia creando una nuova bacheca"
#: src/views/board/index.tsx:327
#: src/views/board/index.tsx:418
msgid "Get started by creating a new list"
msgstr "Inizia creando una nuova lista"
@@ -799,11 +815,19 @@ msgstr "Integrazioni"
msgid "Interviewing"
msgstr "Colloquio"
#: src/views/members/components/InviteMemberForm.tsx:26
msgid "Invalid email address"
msgstr "Indirizzo email non valido"
#: src/views/members/index.tsx:169
msgid "Invite"
msgstr "Invita"
#: src/views/members/components/InviteMemberForm.tsx:82
#: src/views/members/components/InviteMemberForm.tsx:113
msgid "Invite another"
msgstr "Invita un altro"
#: src/views/members/components/InviteMemberForm.tsx:123
#: src/views/card/components/MemberSelector.tsx:112
msgid "Invite member"
msgstr "Invita membro"
@@ -826,7 +850,7 @@ msgid "Keep in mind that this action is irreversible."
msgstr "Tieni presente che questa azione è irreversibile."
#: src/views/card/index.tsx:113
#: src/views/board/components/NewCardForm.tsx:331
#: src/views/board/components/NewCardForm.tsx:358
#: src/views/board/components/Filters.tsx:101
msgid "Labels"
msgstr "Etichette"
@@ -855,7 +879,7 @@ msgstr "Licenza"
msgid "Light"
msgstr "Chiaro"
#: src/views/public/board/index.tsx:51
#: src/views/public/board/index.tsx:57
msgid "Link copied"
msgstr "Link copiato"
@@ -893,7 +917,7 @@ msgstr "Media priorità"
#: src/views/members/index.tsx:161
#: src/views/card/index.tsx:121
#: src/views/board/components/NewCardForm.tsx:290
#: src/views/board/components/NewCardForm.tsx:317
#: src/views/board/components/Filters.tsx:93
#: src/components/SideNavigation.tsx:73
msgid "Members"
@@ -933,7 +957,7 @@ msgstr "Nuovo"
msgid "New board"
msgstr "Nuova bacheca"
#: src/views/board/components/NewCardForm.tsx:237
#: src/views/board/components/NewCardForm.tsx:261
msgid "New card"
msgstr "Nuova carta"
@@ -945,7 +969,7 @@ msgstr "Nuova importazione"
msgid "New label"
msgstr "Nuova etichetta"
#: src/views/board/index.tsx:304
#: src/views/board/index.tsx:395
#: src/views/board/components/NewListForm.tsx:112
msgid "New list"
msgstr "Nuova lista"
@@ -978,7 +1002,7 @@ msgstr "Nessuna bacheca trovata"
msgid "No credit card required"
msgstr "Nessuna carta di credito richiesta"
#: src/views/board/index.tsx:324
#: src/views/board/index.tsx:415
msgid "No lists"
msgstr "Nessuna lista"
@@ -1059,6 +1083,7 @@ msgstr "Seleziona un file da caricare."
#: src/views/settings/components/DeleteAccountConfirmation.tsx:40
#: src/views/settings/components/Avatar.tsx:40
#: src/views/settings/components/Avatar.tsx:98
#: src/views/members/components/InviteMemberForm.tsx:64
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
#: src/views/card/index.tsx:159
#: src/views/card/components/NewCommentForm.tsx:31
@@ -1067,16 +1092,17 @@ msgstr "Seleziona un file da caricare."
#: src/views/card/components/LabelSelector.tsx:73
#: src/views/card/components/DeleteCommentConfirmation.tsx:45
#: src/views/card/components/DeleteCardConfirmation.tsx:52
#: src/views/card/components/Comment.tsx:62
#: src/views/card/components/Comment.tsx:64
#: src/views/boards/components/ImportBoardsForm.tsx:205
#: src/views/board/index.tsx:135
#: src/views/board/index.tsx:191
#: src/views/board/components/VisibilityButton.tsx:53
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
#: src/views/board/components/NewListForm.tsx:78
#: src/views/board/components/NewCardForm.tsx:128
#: src/views/board/components/NewCardForm.tsx:145
#: src/components/NewWorkspaceForm.tsx:41
#: src/components/FeedbackModal.tsx:41
#: src/components/DeleteLabelConfirmation.tsx:23
msgid "Please try again later, or contact customer support."
msgstr "Riprova più tardi o contatta l'assistenza clienti."
@@ -1187,7 +1213,7 @@ msgstr "Ruolo"
msgid "Run on your own infrastructure"
msgstr "Esegui sulla tua infrastruttura"
#: src/views/card/components/Comment.tsx:163
#: src/views/card/components/Comment.tsx:165
msgid "Save"
msgstr "Salva"
@@ -1335,9 +1361,14 @@ msgstr "Non potranno accedere a questo spazio di lavoro."
#: src/views/card/components/DeleteCommentConfirmation.tsx:68
#: src/views/card/components/DeleteCardConfirmation.tsx:78
#: src/components/DeleteLabelConfirmation.tsx:42
msgid "This action can't be undone."
msgstr "Questa azione non può essere annullata."
#: src/views/public/board/index.tsx:146
msgid "This board is private or does not exist"
msgstr "Questa bacheca è privata o non esiste"
#: src/views/board/components/UpdateBoardSlugForm.tsx:135
msgid "This board URL has already been taken"
msgstr "Questo URL della bacheca è già stato utilizzato"
@@ -1383,7 +1414,7 @@ msgstr "Smistamento"
msgid "Unable to add comment"
msgstr "Impossibile aggiungere il commento"
#: src/views/board/components/NewCardForm.tsx:125
#: src/views/board/components/NewCardForm.tsx:142
msgid "Unable to create card"
msgstr "Impossibile creare la scheda"
@@ -1424,7 +1455,7 @@ msgstr "Impossibile aggiornare la visibilità della bacheca"
msgid "Unable to update card"
msgstr "Impossibile aggiornare la scheda"
#: src/views/card/components/Comment.tsx:61
#: src/views/card/components/Comment.tsx:63
msgid "Unable to update comment"
msgstr "Impossibile aggiornare il commento"
@@ -1477,11 +1508,11 @@ msgstr "Liste illimitate"
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:82
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:90
#: src/views/settings/components/UpdateDisplayNameForm.tsx:79
#: src/views/board/components/UpdateBoardSlugForm.tsx:173
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
msgid "Update"
msgstr "Aggiorna"
#: src/components/LabelForm.tsx:233
#: src/components/LabelForm.tsx:236
msgid "Update label"
msgstr "Aggiorna etichetta"
@@ -1526,6 +1557,10 @@ msgstr "Usa template"
msgid "User"
msgstr "Utente"
#: src/views/members/components/InviteMemberForm.tsx:58
msgid "User is already a member of this workspace"
msgstr "L'utente è già membro di questo spazio di lavoro"
#: src/views/boards/components/TemplateBoards.tsx:37
msgid "Video"
msgstr "Video"
@@ -1542,10 +1577,18 @@ msgstr "Visualizza e gestisci la tua fatturazione e abbonamento."
msgid "View docs"
msgstr "Visualizza documenti"
#: src/views/public/board/index.tsx:120
msgid "View only"
msgstr "Solo visualizzazione"
#: src/views/home/components/Features.tsx:147
msgid "View our roadmap."
msgstr "Visualizza la nostra roadmap."
#: src/views/public/board/index.tsx:149
msgid "View workspace"
msgstr "Visualizza spazio di lavoro"
#: src/views/board/components/VisibilityButton.tsx:91
msgid "Visibility"
msgstr "Visibilità"
@@ -1578,7 +1621,7 @@ msgstr "Quando Trello fu lanciato nel 2011, stupì tutti con la sua semplicità
msgid "Why make an open source Trello?"
msgstr "Perché creare un Trello open source?"
#: src/views/board/index.tsx:241
#: src/views/board/index.tsx:332
msgid "Workspace"
msgstr "Spazio di lavoro"

File diff suppressed because one or more lines are too long

View File

@@ -13,7 +13,7 @@ msgstr ""
"Language-Team: \n"
"Plural-Forms: \n"
#: src/views/card/components/Comment.tsx:121
#: src/views/card/components/Comment.tsx:123
msgid " (edited)"
msgstr " (bewerkt)"
@@ -28,7 +28,7 @@ msgid "{0} | {1}"
msgstr "{0} | {1}"
#. placeholder {0}: labelPublicIds.length
#: src/views/board/components/NewCardForm.tsx:365
#: src/views/board/components/NewCardForm.tsx:392
msgid "{0} labels"
msgstr "{0} labels"
@@ -48,7 +48,7 @@ msgstr "Een krachtige, flexibele kanban-app die je helpt werk te organiseren, vo
msgid "Account deleted"
msgstr "Account verwijderd"
#: src/views/public/board/CardModal.tsx:104
#: src/views/public/board/CardModal.tsx:128
#: src/views/card/index.tsx:256
msgid "Activity"
msgstr "Activiteit"
@@ -62,11 +62,11 @@ msgid "Add a card"
msgstr "Voeg een kaart toe"
#: src/views/card/components/NewCommentForm.tsx:57
#: src/views/card/components/Comment.tsx:144
#: src/views/card/components/Comment.tsx:146
msgid "Add a comment..."
msgstr "Voeg een reactie toe..."
#: src/components/Editor.tsx:302
#: src/components/Editor.tsx:303
msgid "Add description... (type '/' to open commands)"
msgstr "Voeg beschrijving toe... (typ '/' om commando's te openen)"
@@ -75,7 +75,7 @@ msgstr "Voeg beschrijving toe... (typ '/' om commando's te openen)"
msgid "Add label"
msgstr "Label toevoegen"
#: src/views/members/components/InviteMemberForm.tsx:50
#: src/views/members/components/InviteMemberForm.tsx:85
#: src/views/card/components/MemberSelector.tsx:130
msgid "Add member"
msgstr "Lid toevoegen"
@@ -145,6 +145,10 @@ msgstr "Weet je zeker dat je deze kaart wilt verwijderen?"
msgid "Are you sure you want to delete this comment?"
msgstr "Weet je zeker dat je deze opmerking wilt verwijderen?"
#: src/components/DeleteLabelConfirmation.tsx:39
msgid "Are you sure you want to delete this label?"
msgstr "Weet je zeker dat je dit label wilt verwijderen?"
#: src/views/settings/components/DeleteAccountConfirmation.tsx:54
msgid "Are you sure you want to delete your account?"
msgstr "Weet je zeker dat je je account wilt verwijderen?"
@@ -178,7 +182,7 @@ msgstr "Factureringsportaal"
msgid "Blog Post"
msgstr "Blogbericht"
#: src/views/board/index.tsx:241
#: src/views/board/index.tsx:332
msgid "Board"
msgstr "Bord"
@@ -190,7 +194,8 @@ msgstr "Bordnaam mag niet langer zijn dan 100 tekens"
msgid "Board name is required"
msgstr "Bordnaam is verplicht"
#: src/views/board/index.tsx:267
#: src/views/public/board/index.tsx:143
#: src/views/board/index.tsx:358
msgid "Board not found"
msgstr "Bord niet gevonden"
@@ -202,7 +207,7 @@ msgstr "Board URL kan alleen letters, cijfers en koppeltekens bevatten"
msgid "Board URL cannot exceed 60 characters"
msgstr "Board URL mag niet langer zijn dan 60 tekens"
#: src/views/public/board/index.tsx:53
#: src/views/public/board/index.tsx:59
msgid "Board URL copied to clipboard"
msgstr "Board URL gekopieerd naar klembord"
@@ -246,7 +251,8 @@ msgstr "Bugrapport"
#: src/views/members/components/DeleteMemberConfirmation.tsx:55
#: src/views/card/components/DeleteCommentConfirmation.tsx:76
#: src/views/card/components/DeleteCardConfirmation.tsx:86
#: src/views/card/components/Comment.tsx:156
#: src/views/card/components/Comment.tsx:158
#: src/components/DeleteLabelConfirmation.tsx:47
msgid "Cancel"
msgstr "Annuleren"
@@ -254,7 +260,7 @@ msgstr "Annuleren"
msgid "Card not found"
msgstr "Kaart niet gevonden"
#: src/views/board/components/NewCardForm.tsx:254
#: src/views/board/components/NewCardForm.tsx:278
msgid "Card title"
msgstr "Kaarttitel"
@@ -347,7 +353,7 @@ msgid "Control who can view and edit your boards."
msgstr "Bepaal wie je borden kan bekijken en bewerken."
#: src/views/board/components/NewListForm.tsx:140
#: src/views/board/components/NewCardForm.tsx:391
#: src/views/board/components/NewCardForm.tsx:418
#: src/components/LabelForm.tsx:212
msgid "Create another"
msgstr "Maak nog een"
@@ -356,15 +362,15 @@ msgstr "Maak nog een"
msgid "Create board"
msgstr "Maak bord"
#: src/views/board/components/NewCardForm.tsx:401
#: src/views/board/components/NewCardForm.tsx:428
msgid "Create card"
msgstr "Maak kaart"
#: src/components/LabelForm.tsx:233
#: src/components/LabelForm.tsx:236
msgid "Create label"
msgstr "Maak label"
#: src/views/board/components/NewListForm.tsx:148
#: src/views/board/components/NewListForm.tsx:152
msgid "Create list"
msgstr "Lijst maken"
@@ -377,11 +383,11 @@ msgid "Create new key"
msgstr "Nieuwe sleutel aanmaken"
#: src/views/card/components/LabelSelector.tsx:98
#: src/views/board/components/NewCardForm.tsx:327
#: src/views/board/components/NewCardForm.tsx:354
msgid "Create new label"
msgstr "Maak nieuw label"
#: src/views/board/index.tsx:335
#: src/views/board/index.tsx:426
msgid "Create new list"
msgstr "Maak nieuwe lijst"
@@ -417,6 +423,7 @@ msgstr "Donker"
#: src/views/card/components/DeleteCommentConfirmation.tsx:82
#: src/views/card/components/DeleteCardConfirmation.tsx:92
#: src/components/LabelForm.tsx:226
#: src/components/DeleteLabelConfirmation.tsx:49
msgid "Delete"
msgstr "Verwijderen"
@@ -434,7 +441,7 @@ msgstr "Board verwijderen"
msgid "Delete card"
msgstr "Kaart verwijderen"
#: src/views/card/components/Comment.tsx:89
#: src/views/card/components/Comment.tsx:91
msgid "Delete comment"
msgstr "Reactie verwijderen"
@@ -510,7 +517,7 @@ msgstr "Klaar"
msgid "Edit board URL"
msgstr "Board URL bewerken"
#: src/views/card/components/Comment.tsx:80
#: src/views/card/components/Comment.tsx:82
msgid "Edit comment"
msgstr "Reactie bewerken"
@@ -530,7 +537,7 @@ msgstr "Bewerken"
msgid "email"
msgstr "e-mail"
#: src/views/members/components/InviteMemberForm.tsx:64
#: src/views/members/components/InviteMemberForm.tsx:99
msgid "Email"
msgstr "E-mail"
@@ -554,6 +561,10 @@ msgstr "Voer je wachtwoord in"
msgid "Error deleting account"
msgstr "Fout bij verwijderen account"
#: src/components/DeleteLabelConfirmation.tsx:22
msgid "Error deleting label"
msgstr "Fout bij het verwijderen van label"
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:45
msgid "Error deleting workspace"
msgstr "Fout bij verwijderen werkruimte"
@@ -562,6 +573,11 @@ msgstr "Fout bij verwijderen werkruimte"
msgid "Error disconnecting Trello"
msgstr "Fout bij ontkoppelen van Trello"
#: src/views/members/components/InviteMemberForm.tsx:57
#: src/views/members/components/InviteMemberForm.tsx:63
msgid "Error inviting member"
msgstr "Fout bij het uitnodigen van lid"
#: src/views/settings/components/UpdateDisplayNameForm.tsx:54
msgid "Error updating display name"
msgstr "Fout bij bijwerken weergavenaam"
@@ -676,7 +692,7 @@ msgstr "Aan de slag"
msgid "Get started by creating a new board"
msgstr "Begin door een nieuw bord te maken"
#: src/views/board/index.tsx:327
#: src/views/board/index.tsx:418
msgid "Get started by creating a new list"
msgstr "Begin door een nieuwe lijst te maken"
@@ -799,11 +815,19 @@ msgstr "Integraties"
msgid "Interviewing"
msgstr "Interviewen"
#: src/views/members/components/InviteMemberForm.tsx:26
msgid "Invalid email address"
msgstr "Ongeldig e-mailadres"
#: src/views/members/index.tsx:169
msgid "Invite"
msgstr "Uitnodigen"
#: src/views/members/components/InviteMemberForm.tsx:82
#: src/views/members/components/InviteMemberForm.tsx:113
msgid "Invite another"
msgstr "Nog iemand uitnodigen"
#: src/views/members/components/InviteMemberForm.tsx:123
#: src/views/card/components/MemberSelector.tsx:112
msgid "Invite member"
msgstr "Lid uitnodigen"
@@ -826,7 +850,7 @@ msgid "Keep in mind that this action is irreversible."
msgstr "Houd er rekening mee dat deze actie onomkeerbaar is."
#: src/views/card/index.tsx:113
#: src/views/board/components/NewCardForm.tsx:331
#: src/views/board/components/NewCardForm.tsx:358
#: src/views/board/components/Filters.tsx:101
msgid "Labels"
msgstr "Labels"
@@ -855,7 +879,7 @@ msgstr "Licentie"
msgid "Light"
msgstr "Licht"
#: src/views/public/board/index.tsx:51
#: src/views/public/board/index.tsx:57
msgid "Link copied"
msgstr "Link gekopieerd"
@@ -893,7 +917,7 @@ msgstr "Gemiddelde prioriteit"
#: src/views/members/index.tsx:161
#: src/views/card/index.tsx:121
#: src/views/board/components/NewCardForm.tsx:290
#: src/views/board/components/NewCardForm.tsx:317
#: src/views/board/components/Filters.tsx:93
#: src/components/SideNavigation.tsx:73
msgid "Members"
@@ -933,7 +957,7 @@ msgstr "Nieuw"
msgid "New board"
msgstr "Nieuw bord"
#: src/views/board/components/NewCardForm.tsx:237
#: src/views/board/components/NewCardForm.tsx:261
msgid "New card"
msgstr "Nieuwe kaart"
@@ -945,7 +969,7 @@ msgstr "Nieuwe import"
msgid "New label"
msgstr "Nieuw label"
#: src/views/board/index.tsx:304
#: src/views/board/index.tsx:395
#: src/views/board/components/NewListForm.tsx:112
msgid "New list"
msgstr "Nieuwe lijst"
@@ -978,7 +1002,7 @@ msgstr "Geen borden gevonden"
msgid "No credit card required"
msgstr "Geen creditcard vereist"
#: src/views/board/index.tsx:324
#: src/views/board/index.tsx:415
msgid "No lists"
msgstr "Geen lijsten"
@@ -1059,6 +1083,7 @@ msgstr "Selecteer een bestand om te uploaden."
#: src/views/settings/components/DeleteAccountConfirmation.tsx:40
#: src/views/settings/components/Avatar.tsx:40
#: src/views/settings/components/Avatar.tsx:98
#: src/views/members/components/InviteMemberForm.tsx:64
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
#: src/views/card/index.tsx:159
#: src/views/card/components/NewCommentForm.tsx:31
@@ -1067,16 +1092,17 @@ msgstr "Selecteer een bestand om te uploaden."
#: src/views/card/components/LabelSelector.tsx:73
#: src/views/card/components/DeleteCommentConfirmation.tsx:45
#: src/views/card/components/DeleteCardConfirmation.tsx:52
#: src/views/card/components/Comment.tsx:62
#: src/views/card/components/Comment.tsx:64
#: src/views/boards/components/ImportBoardsForm.tsx:205
#: src/views/board/index.tsx:135
#: src/views/board/index.tsx:191
#: src/views/board/components/VisibilityButton.tsx:53
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
#: src/views/board/components/NewListForm.tsx:78
#: src/views/board/components/NewCardForm.tsx:128
#: src/views/board/components/NewCardForm.tsx:145
#: src/components/NewWorkspaceForm.tsx:41
#: src/components/FeedbackModal.tsx:41
#: src/components/DeleteLabelConfirmation.tsx:23
msgid "Please try again later, or contact customer support."
msgstr "Probeer het later opnieuw of neem contact op met de klantenservice."
@@ -1187,7 +1213,7 @@ msgstr "Rol"
msgid "Run on your own infrastructure"
msgstr "Draai op je eigen infrastructuur"
#: src/views/card/components/Comment.tsx:163
#: src/views/card/components/Comment.tsx:165
msgid "Save"
msgstr "Opslaan"
@@ -1335,9 +1361,14 @@ msgstr "Ze zullen geen toegang meer hebben tot deze werkruimte."
#: src/views/card/components/DeleteCommentConfirmation.tsx:68
#: src/views/card/components/DeleteCardConfirmation.tsx:78
#: src/components/DeleteLabelConfirmation.tsx:42
msgid "This action can't be undone."
msgstr "Deze actie kan niet ongedaan worden gemaakt."
#: src/views/public/board/index.tsx:146
msgid "This board is private or does not exist"
msgstr "Dit bord is privé of bestaat niet"
#: src/views/board/components/UpdateBoardSlugForm.tsx:135
msgid "This board URL has already been taken"
msgstr "Deze board URL is al in gebruik"
@@ -1383,7 +1414,7 @@ msgstr "Triage"
msgid "Unable to add comment"
msgstr "Kan geen reactie toevoegen"
#: src/views/board/components/NewCardForm.tsx:125
#: src/views/board/components/NewCardForm.tsx:142
msgid "Unable to create card"
msgstr "Kan kaart niet aanmaken"
@@ -1424,7 +1455,7 @@ msgstr "Kan bordzichtbaarheid niet bijwerken"
msgid "Unable to update card"
msgstr "Kan kaart niet bijwerken"
#: src/views/card/components/Comment.tsx:61
#: src/views/card/components/Comment.tsx:63
msgid "Unable to update comment"
msgstr "Kan reactie niet bijwerken"
@@ -1477,11 +1508,11 @@ msgstr "Onbeperkt aantal lijsten"
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:82
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:90
#: src/views/settings/components/UpdateDisplayNameForm.tsx:79
#: src/views/board/components/UpdateBoardSlugForm.tsx:173
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
msgid "Update"
msgstr "Bijwerken"
#: src/components/LabelForm.tsx:233
#: src/components/LabelForm.tsx:236
msgid "Update label"
msgstr "Label bijwerken"
@@ -1526,6 +1557,10 @@ msgstr "Sjabloon gebruiken"
msgid "User"
msgstr "Gebruiker"
#: src/views/members/components/InviteMemberForm.tsx:58
msgid "User is already a member of this workspace"
msgstr "Gebruiker is al lid van deze werkruimte"
#: src/views/boards/components/TemplateBoards.tsx:37
msgid "Video"
msgstr "Video"
@@ -1542,10 +1577,18 @@ msgstr "Bekijk en beheer je facturering en abonnement."
msgid "View docs"
msgstr "Bekijk documentatie"
#: src/views/public/board/index.tsx:120
msgid "View only"
msgstr "Alleen bekijken"
#: src/views/home/components/Features.tsx:147
msgid "View our roadmap."
msgstr "Bekijk onze roadmap."
#: src/views/public/board/index.tsx:149
msgid "View workspace"
msgstr "Werkruimte bekijken"
#: src/views/board/components/VisibilityButton.tsx:91
msgid "Visibility"
msgstr "Zichtbaarheid"
@@ -1578,7 +1621,7 @@ msgstr "Toen Trello in 2011 werd gelanceerd, blies het iedereen omver met zijn z
msgid "Why make an open source Trello?"
msgstr "Waarom een open source Trello maken?"
#: src/views/board/index.tsx:241
#: src/views/board/index.tsx:332
msgid "Workspace"
msgstr "Werkruimte"

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,15 @@
import { createContext, useContext, useState } from "react";
interface ModalState {
contentType: string;
entityId?: string;
entityLabel?: string;
}
interface Props {
children: React.ReactNode;
}
type ModalContextType = {
isOpen: boolean;
openModal: (
@@ -11,33 +21,64 @@ type ModalContextType = {
modalContentType: string;
entityId: string;
entityLabel: string;
modalStates: Record<string, any>;
setModalState: (modalType: string, state: any) => void;
getModalState: (modalType: string) => any;
clearModalState: (modalType: string) => void;
clearAllModalStates: () => void;
};
interface Props {
children: React.ReactNode;
}
const ModalContext = createContext<ModalContextType | undefined>(undefined);
export const ModalProvider: React.FC<Props> = ({ children }) => {
const [isOpen, setIsOpen] = useState(false);
const [entityId, setEntityId] = useState("");
const [entityLabel, setEntityLabel] = useState("");
const [modalContentType, setModalContentType] = useState("");
const [modalStack, setModalStack] = useState<ModalState[]>([]);
const [modalStates, setModalStates] = useState<Record<string, any>>({});
const isOpen = modalStack.length > 0;
const currentModal = modalStack[modalStack.length - 1];
const modalContentType = currentModal?.contentType || "";
const entityId = currentModal?.entityId || "";
const entityLabel = currentModal?.entityLabel || "";
const openModal = (
contentType: string,
entityId?: string,
entityLabel?: string,
) => {
setIsOpen(true);
setModalContentType(contentType);
if (entityId) setEntityId(entityId);
if (entityLabel) setEntityLabel(entityLabel);
const newModal: ModalState = { contentType, entityId, entityLabel };
setModalStack(prev => [...prev, newModal]);
};
const closeModal = () => {
setIsOpen(false);
setModalStack(prev => {
if (prev.length <= 1) {
return [];
}
return prev.slice(0, -1);
});
};
const setModalState = (modalType: string, state: any) => {
setModalStates(prev => ({
...prev,
[modalType]: state
}));
};
const getModalState = (modalType: string) => {
return modalStates[modalType];
};
const clearModalState = (modalType: string) => {
setModalStates(prev => {
const newStates = { ...prev };
delete newStates[modalType];
return newStates;
});
};
const clearAllModalStates = () => {
setModalStates({});
};
return (
@@ -49,6 +90,11 @@ export const ModalProvider: React.FC<Props> = ({ children }) => {
modalContentType,
entityId,
entityLabel,
modalStates,
setModalState,
getModalState,
clearModalState,
clearAllModalStates,
}}
>
{children}

View File

@@ -18,6 +18,7 @@ import Editor from "~/components/Editor";
import Input from "~/components/Input";
import LabelIcon from "~/components/LabelIcon";
import Toggle from "~/components/Toggle";
import { useModalFormState } from "~/hooks/useModalFormState";
import { useModal } from "~/providers/modal";
import { usePopup } from "~/providers/popup";
import { api } from "~/utils/api";
@@ -49,17 +50,24 @@ export function NewCardForm({
const utils = api.useUtils();
// persists the form values
const { formState, saveFormState } = useModalFormState<NewCardFormInput>({
modalType: "NEW_CARD",
initialValues: {
title: "",
description: "",
listPublicId,
labelPublicIds: [],
memberPublicIds: [],
isCreateAnotherEnabled: false,
position: "start",
},
resetOnClose: true,
});
const { register, handleSubmit, reset, setValue, watch } =
useForm<NewCardFormInput>({
defaultValues: {
title: "",
description: "",
listPublicId,
labelPublicIds: [],
memberPublicIds: [],
isCreateAnotherEnabled: false,
position: "start",
},
values: formState,
});
const labelPublicIds = watch("labelPublicIds") || [];
@@ -67,6 +75,15 @@ export function NewCardForm({
const isCreateAnotherEnabled = watch("isCreateAnotherEnabled");
const position = watch("position");
const title = watch("title");
const description = watch("description");
// saving form state whenever form values change
useEffect(() => {
const subscription = watch((data) => {
saveFormState(data as NewCardFormInput);
});
return () => subscription.unsubscribe();
}, [watch, saveFormState]);
const { data: boardData } = api.board.byId.useQuery(queryParams, {
enabled: !!boardPublicId,
@@ -131,17 +148,24 @@ export function NewCardForm({
},
onSuccess: async () => {
const isCreateAnotherEnabled = watch("isCreateAnotherEnabled");
if (!isCreateAnotherEnabled) closeModal();
if (!isCreateAnotherEnabled) {
// close modal (state will auto-clear due to resetOnClose: true)
closeModal();
} else {
// reset form for creating another card
const newFormState = {
title: "",
description: "",
listPublicId: watch("listPublicId"),
labelPublicIds: [],
memberPublicIds: [],
isCreateAnotherEnabled,
position,
};
reset(newFormState);
saveFormState(newFormState);
}
await utils.board.byId.invalidate(queryParams);
reset({
title: "",
description: "",
listPublicId: watch("listPublicId"),
labelPublicIds: [],
memberPublicIds: [],
isCreateAnotherEnabled,
position,
});
},
});
@@ -264,8 +288,11 @@ export function NewCardForm({
<div className="mt-2">
<div className="block max-h-48 min-h-24 w-full overflow-y-auto rounded-md border-0 bg-dark-300 bg-white/5 px-3 py-2 text-sm shadow-sm ring-1 ring-inset ring-light-600 focus-within:ring-2 focus-within:ring-inset focus-within:ring-light-700 dark:ring-dark-700 dark:focus-within:ring-dark-700 sm:leading-6">
<Editor
content=""
onChange={(value) => setValue("description", value)}
content={description}
onChange={(value) => {
setValue("description", value);
saveFormState({ ...formState, description: value });
}}
/>
</div>
</div>

View File

@@ -145,7 +145,12 @@ export function NewListForm({
/>
<div>
<Button type="submit">{t`Create list`}</Button>
<Button
type="submit"
disabled={createList.isPending || !watch("name")}
>
{t`Create list`}
</Button>
</div>
</div>
</form>

View File

@@ -167,7 +167,8 @@ export function UpdateBoardSlugForm({
!isDirty ||
updateBoardSlug.isPending ||
errors.slug?.message !== undefined ||
isBoardSlugAvailable?.isReserved
isBoardSlugAvailable?.isReserved ||
checkBoardSlugAvailability.isLoading
}
>
{t`Update`}

View File

@@ -45,7 +45,7 @@ export default function BoardPage() {
const utils = api.useUtils();
const { showPopup } = usePopup();
const { workspace } = useWorkspace();
const { openModal, modalContentType, entityId } = useModal();
const { openModal, modalContentType, entityId, isOpen } = useModal();
const [selectedPublicListId, setSelectedPublicListId] =
useState<PublicListId>("");
const [isInitialLoading, setIsInitialLoading] = useState(true);
@@ -235,6 +235,97 @@ export default function BoardPage() {
}
};
const renderModalContent = () => {
return (
<>
<Modal
modalSize="sm"
isVisible={isOpen && modalContentType === "DELETE_BOARD"}
>
<DeleteBoardConfirmation boardPublicId={boardId ?? ""} />
</Modal>
<Modal
modalSize="sm"
isVisible={isOpen && modalContentType === "DELETE_LIST"}
>
<DeleteListConfirmation
listPublicId={selectedPublicListId}
queryParams={queryParams}
/>
</Modal>
<Modal
modalSize="md"
isVisible={isOpen && modalContentType === "NEW_CARD"}
>
<NewCardForm
boardPublicId={boardId ?? ""}
listPublicId={selectedPublicListId}
queryParams={queryParams}
/>
</Modal>
<Modal
modalSize="sm"
isVisible={isOpen && modalContentType === "NEW_LIST"}
>
<NewListForm
boardPublicId={boardId ?? ""}
queryParams={queryParams}
/>
</Modal>
<Modal
modalSize="sm"
isVisible={isOpen && modalContentType === "NEW_WORKSPACE"}
>
<NewWorkspaceForm />
</Modal>
<Modal
modalSize="sm"
isVisible={isOpen && modalContentType === "NEW_LABEL"}
>
<LabelForm boardPublicId={boardId ?? ""} refetch={refetchBoard} />
</Modal>
<Modal
modalSize="sm"
isVisible={isOpen && modalContentType === "EDIT_LABEL"}
>
<LabelForm
boardPublicId={boardId ?? ""}
refetch={refetchBoard}
isEdit
/>
</Modal>
<Modal
modalSize="sm"
isVisible={isOpen && modalContentType === "DELETE_LABEL"}
>
<DeleteLabelConfirmation
refetch={refetchBoard}
labelPublicId={entityId}
/>
</Modal>
<Modal
modalSize="sm"
isVisible={isOpen && modalContentType === "UPDATE_BOARD_SLUG"}
>
<UpdateBoardSlugForm
boardPublicId={boardId ?? ""}
workspaceSlug={workspace.slug ?? ""}
boardSlug={boardData?.slug ?? ""}
queryParams={queryParams}
/>
</Modal>
</>
);
};
return (
<>
<PageHead
@@ -422,63 +513,7 @@ export default function BoardPage() {
</>
) : null}
</div>
<Modal
modalSize={
modalContentType === "NEW_CARD" ||
modalContentType === "NEW_FEEDBACK"
? "md"
: "sm"
}
>
{modalContentType === "NEW_FEEDBACK" && <FeedbackModal />}
{modalContentType === "DELETE_BOARD" && (
<DeleteBoardConfirmation boardPublicId={boardId ?? ""} />
)}
{modalContentType === "DELETE_LIST" && (
<DeleteListConfirmation
listPublicId={selectedPublicListId}
queryParams={queryParams}
/>
)}
{modalContentType === "NEW_CARD" && (
<NewCardForm
boardPublicId={boardId ?? ""}
listPublicId={selectedPublicListId}
queryParams={queryParams}
/>
)}
{modalContentType === "NEW_LIST" && (
<NewListForm
boardPublicId={boardId ?? ""}
queryParams={queryParams}
/>
)}
{modalContentType === "NEW_WORKSPACE" && <NewWorkspaceForm />}
{modalContentType === "NEW_LABEL" && (
<LabelForm boardPublicId={boardId ?? ""} refetch={refetchBoard} />
)}
{modalContentType === "EDIT_LABEL" && (
<LabelForm
boardPublicId={boardId ?? ""}
refetch={refetchBoard}
isEdit
/>
)}
{modalContentType === "DELETE_LABEL" && (
<DeleteLabelConfirmation
refetch={refetchBoard}
labelPublicId={entityId}
/>
)}
{modalContentType === "UPDATE_BOARD_SLUG" && (
<UpdateBoardSlugForm
boardPublicId={boardId ?? ""}
workspaceSlug={workspace.slug ?? ""}
boardSlug={boardData?.slug ?? ""}
queryParams={queryParams}
/>
)}
</Modal>
{renderModalContent()}
</div>
</>
);

View File

@@ -155,11 +155,13 @@ const ActivityList = ({
cardPublicId,
isLoading,
isAdmin,
isViewOnly,
}: {
activities: NonNullable<GetCardByIdOutput>["activities"];
cardPublicId: string;
isLoading: boolean;
isAdmin?: boolean;
isViewOnly?: boolean;
}) => {
const { data } = authClient.useSession();
const { locale } = useLocalisation();
@@ -193,6 +195,7 @@ const ActivityList = ({
isEdited={!!activity.comment?.updatedAt}
isAuthor={activity.comment?.createdBy === data?.user.id}
isAdmin={isAdmin ?? false}
isViewOnly={!!isViewOnly}
/>
);

View File

@@ -27,6 +27,7 @@ const Comment = ({
isAuthor,
isAdmin,
isEdited = false,
isViewOnly = false,
}: {
publicId: string | undefined;
cardPublicId: string;
@@ -38,6 +39,7 @@ const Comment = ({
isAuthor: boolean;
isAdmin: boolean;
isEdited: boolean;
isViewOnly: boolean;
}) => {
const [isEditing, setIsEditing] = useState(false);
const utils = api.useUtils();
@@ -124,7 +126,7 @@ const Comment = ({
</p>
</div>
{dropdownItems.length > 0 && (
{dropdownItems.length > 0 && !isViewOnly && (
<div className="absolute right-4 top-4">
<Dropdown items={dropdownItems}>
<HiEllipsisHorizontal className="h-5 w-5 text-light-900 dark:text-dark-800" />

View File

@@ -1,26 +1,43 @@
import { zodResolver } from "@hookform/resolvers/zod";
import { t } from "@lingui/core/macro";
import { useEffect } from "react";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { HiXMark } from "react-icons/hi2";
import { z } from "zod";
import type { InviteMemberInput } from "@kan/api/types";
import Button from "~/components/Button";
import Input from "~/components/Input";
import Toggle from "~/components/Toggle";
import { useModal } from "~/providers/modal";
import { usePopup } from "~/providers/popup";
import { useWorkspace } from "~/providers/workspace";
import { api } from "~/utils/api";
export function InviteMemberForm() {
const utils = api.useUtils();
const [isCreateAnotherEnabled, setIsCreateAnotherEnabled] = useState(false);
const { closeModal } = useModal();
const { workspace } = useWorkspace();
const { showPopup } = usePopup();
const { register, handleSubmit } = useForm<InviteMemberInput>({
const InviteMemberSchema = z.object({
email: z.string().email({ message: t`Invalid email address` }),
workspacePublicId: z.string(),
});
const {
register,
handleSubmit,
reset,
formState: { errors },
} = useForm<InviteMemberInput>({
defaultValues: {
email: "",
workspacePublicId: workspace.publicId || "",
},
resolver: zodResolver(InviteMemberSchema),
});
const refetchBoards = () => utils.board.all.refetch();
@@ -31,6 +48,24 @@ export function InviteMemberForm() {
await utils.workspace.byId.refetch();
await refetchBoards();
},
onError: (error) => {
reset();
if (!isCreateAnotherEnabled) closeModal();
if (error.data?.code === "CONFLICT") {
showPopup({
header: t`Error inviting member`,
message: t`User is already a member of this workspace`,
icon: "error",
});
} else {
showPopup({
header: t`Error inviting member`,
message: t`Please try again later, or contact customer support.`,
icon: "error",
});
}
},
});
const onSubmit = (data: InviteMemberInput) => {
@@ -69,10 +104,16 @@ export function InviteMemberForm() {
await handleSubmit(onSubmit)();
}
}}
errorMessage={errors.email?.message}
/>
</div>
<div className="mt-12 flex items-center justify-end border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600">
<Toggle
label={t`Invite another`}
isChecked={isCreateAnotherEnabled}
onChange={() => setIsCreateAnotherEnabled(!isCreateAnotherEnabled)}
/>
<div>
<Button
type="submit"

View File

@@ -97,7 +97,7 @@ export default function MembersPage() {
</td>
<td
className={twMerge(
"w-auto min-w-[120px] sm:w-[35%] sm:min-w-[150px]",
"w-auto min-w-[120px] overflow-visible sm:w-[35%] sm:min-w-[150px]",
isLastRow && "rounded-br-lg",
)}
>
@@ -121,7 +121,7 @@ export default function MembersPage() {
</div>
<div
className={twMerge(
"relative",
"relative z-50",
(workspace.role !== "admin" || showSkeleton) && "hidden",
)}
>
@@ -172,10 +172,10 @@ export default function MembersPage() {
</div>
<div className="mt-8 flow-root">
<div className="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div className="inline-block min-w-full px-4 py-2 align-middle sm:px-6 lg:px-8">
<div className="-mx-4 -my-2 sm:-mx-6 lg:-mx-8">
<div className="inline-block min-w-full overflow-x-auto px-4 py-2 pb-16 align-middle sm:px-6 lg:px-8">
<div className="h-full shadow ring-1 ring-black ring-opacity-5 sm:rounded-lg">
<table className="min-w-full divide-y divide-light-600 dark:divide-dark-600">
<table className="min-w-full divide-y divide-light-600 overflow-visible dark:divide-dark-600">
<thead className="rounded-t-lg bg-light-300 dark:bg-dark-200">
<tr>
<th
@@ -192,7 +192,7 @@ export default function MembersPage() {
</th>
</tr>
</thead>
<tbody className="divide-y divide-light-600 bg-light-50 dark:divide-dark-600 dark:bg-dark-100">
<tbody className="divide-y divide-light-600 overflow-visible bg-light-50 dark:divide-dark-600 dark:bg-dark-100">
{!isLoading &&
data?.members.map((member, index) => (
<TableRow

View File

@@ -1,10 +1,11 @@
import { useRouter } from "next/router";
import { t } from "@lingui/core/macro";
import { useEffect, useRef, useState } from "react";
import { HiXMark } from "react-icons/hi2";
import { authClient } from "@kan/auth/client";
import Badge from "~/components/Badge";
import Editor from "~/components/Editor";
import LabelIcon from "~/components/LabelIcon";
import { useModal } from "~/providers/modal";
import { api } from "~/utils/api";
import ActivityList from "~/views/card/components/ActivityList";
@@ -20,7 +21,9 @@ export function CardModal({
}) {
const router = useRouter();
const { closeModal, isOpen } = useModal();
const { data: session } = authClient.useSession();
const [showFade, setShowFade] = useState(false);
const [showTopFade, setShowTopFade] = useState(false);
const scrollRef = useRef<HTMLDivElement>(null);
const { data, isLoading } = api.card.byId.useQuery(
{
@@ -33,85 +36,115 @@ export function CardModal({
const labels = data?.labels ?? [];
const handleScroll = () => {
if (!scrollRef.current) return;
const { scrollTop, scrollHeight, clientHeight } = scrollRef.current;
const isAtBottom = scrollTop + clientHeight >= scrollHeight - 5;
const isAtTop = scrollTop <= 5;
setShowFade(!isAtBottom);
setShowTopFade(!isAtTop);
};
useEffect(() => {
const scrollElement = scrollRef.current;
if (!scrollElement) return;
handleScroll();
scrollElement.addEventListener("scroll", handleScroll);
return () => scrollElement.removeEventListener("scroll", handleScroll);
}, [data]);
return (
<div className="flex h-full flex-1 flex-row">
<div className="flex h-full w-full flex-col overflow-hidden">
<div className="h-full max-h-[calc(100vh-4rem)] overflow-y-auto p-8">
<div className="flex w-full items-center justify-between">
<button
className="absolute right-[2rem] top-[2rem] rounded p-1 hover:bg-light-300 focus:outline-none dark:hover:bg-dark-300"
onClick={async (e) => {
e.preventDefault();
closeModal();
try {
await router.replace(
`/${workspaceSlug}/${boardSlug}`,
undefined,
{
shallow: true,
},
);
} catch (error) {
console.error(error);
}
}}
>
<HiXMark
size={18}
className="dark:text-dark-9000 text-light-900"
/>
</button>
{isLoading ? (
<div className="flex space-x-2">
<div className="h-[2.3rem] w-[300px] animate-pulse rounded-[5px] bg-light-300 dark:bg-dark-300" />
</div>
) : (
<>
<h1 className="font-medium leading-[2.3rem] tracking-tight text-neutral-900 dark:text-dark-1000 sm:text-[1.2rem]">
{data?.title}
</h1>
</>
)}
</div>
<div className="h-full p-8">
<div className="mb-6">
{labels.map((label) => (
<div
key={label.publicId}
className="my-1 mr-1 inline-flex w-fit items-center gap-x-1.5 rounded-full px-2 py-1 text-[12px] font-medium text-light-800 ring-1 ring-inset ring-light-600 dark:text-dark-1000 dark:ring-dark-800"
<div className="flex w-full items-center justify-between">
<button
className="absolute right-[2rem] top-[2rem] rounded p-1 hover:bg-light-300 focus:outline-none dark:hover:bg-dark-300"
onClick={async (e) => {
e.preventDefault();
closeModal();
try {
await router.replace(
`/${workspaceSlug}/${boardSlug}`,
undefined,
{
shallow: true,
},
);
} catch (error) {
console.error(error);
}
}}
>
<svg
fill={label.colourCode ?? "#3730a3"}
className="h-2 w-2"
viewBox="0 0 6 6"
aria-hidden="true"
>
<circle cx={3} cy={3} r={3} />
</svg>
<div>{label.name}</div>
</div>
))}
</div>
{data?.description && (
<div className="mb-10 flex w-full max-w-2xl justify-between">
<div className="mt-2">
<Editor content={data.description} readOnly />
</div>
</div>
)}
<div className="border-t-[1px] border-light-600 pb-4 pt-12 dark:border-dark-400">
<h2 className="text-md pb-4 font-medium text-light-900 dark:text-dark-1000">
{t`Activity`}
</h2>
<div>
{cardPublicId && (
<ActivityList
cardPublicId={cardPublicId}
activities={data?.activities ?? []}
isLoading={isLoading}
<HiXMark
size={18}
className="dark:text-dark-9000 text-light-900"
/>
</button>
{isLoading ? (
<div className="flex space-x-2">
<div className="h-[2.3rem] w-[300px] animate-pulse rounded-[5px] bg-light-300 dark:bg-dark-300" />
</div>
) : (
<>
<h1 className="pr-8 font-bold leading-[2.3rem] tracking-tight text-neutral-900 dark:text-dark-1000 sm:text-[1.2rem]">
{data?.title}
</h1>
</>
)}
</div>
{labels.length > 0 && (
<div className="mt-2">
{labels.map((label) => (
<Badge
key={label.publicId}
value={label.name}
iconLeft={<LabelIcon colourCode={label.colourCode} />}
/>
))}
</div>
)}
</div>
<div className="relative">
<div
ref={scrollRef}
className="h-full max-h-[425px] overflow-y-auto"
>
{data?.description && (
<div className="mb-10 flex w-full max-w-2xl justify-between">
<div className="mt-2">
<Editor content={data.description} readOnly />
</div>
</div>
)}
<div className="border-t-[1px] border-light-600 pb-4 pt-12 dark:border-dark-400">
<h2 className="text-md pb-4 font-medium text-light-900 dark:text-dark-1000">
{t`Activity`}
</h2>
<div>
{cardPublicId && (
<ActivityList
cardPublicId={cardPublicId}
activities={data?.activities ?? []}
isLoading={isLoading}
isViewOnly={true}
/>
)}
</div>
</div>
</div>
{showTopFade && (
<div className="pointer-events-none absolute left-0 right-0 top-0 h-6 bg-gradient-to-b from-white/80 to-transparent dark:from-dark-100/80" />
)}
{showFade && (
<div className="pointer-events-none absolute bottom-0 left-0 right-0 h-6 bg-gradient-to-t from-white/80 to-transparent dark:from-dark-100/80" />
)}
</div>
</div>
</div>

View File

@@ -3,8 +3,9 @@ import { useRouter } from "next/router";
import { t } from "@lingui/core/macro";
import { keepPreviousData } from "@tanstack/react-query";
import { useEffect, useState } from "react";
import { HiLink } from "react-icons/hi2";
import { HiLink, HiOutlineLockClosed } from "react-icons/hi2";
import Button from "~/components/Button";
import Modal from "~/components/modal";
import { PageHead } from "~/components/PageHead";
import PatternedBackground from "~/components/PatternedBackground";
@@ -28,9 +29,14 @@ export default function PublicBoardView() {
? router.query.boardSlug[0]
: router.query.boardSlug;
const workspaceSlug = Array.isArray(router.query.workspaceSlug)
? router.query.workspaceSlug[0]
: router.query.workspaceSlug;
const { data, isLoading } = api.board.bySlug.useQuery(
{
boardSlug: boardSlug ?? "",
workspaceSlug: workspaceSlug ?? "",
members: formatToArray(router.query.members),
labels: formatToArray(router.query.labels),
},
@@ -106,7 +112,13 @@ export default function PublicBoardView() {
</h1>
)}
{data && (
<div className="flex items-center space-x-2">
<div className="z-10 flex items-center space-x-2">
<div className="inline-flex cursor-default items-center justify-center whitespace-nowrap rounded-md border-[1px] border-light-300 bg-light-50 px-3 py-2 text-sm font-semibold text-light-950 shadow-sm dark:border-dark-300 dark:bg-dark-50 dark:text-dark-950">
<span className="mr-2">
<HiOutlineLockClosed />
</span>
{t`View only`}
</div>
<Filters
labels={data.labels ?? []}
members={[]}
@@ -116,17 +128,30 @@ export default function PublicBoardView() {
)}
</div>
<div className="scrollbar-w-none scrollbar-track-rounded-[4px] scrollbar-thumb-rounded-[4px] scrollbar-h-[8px] relative flex-1 overflow-y-hidden overflow-x-scroll overscroll-contain scrollbar scrollbar-track-light-200 scrollbar-thumb-light-400 dark:scrollbar-track-dark-100 dark:scrollbar-thumb-dark-300">
<div className="scrollbar-w-none scrollbar-track-rounded-[4px] scrollbar-thumb-rounded-[4px] scrollbar-h-[8px] relative h-full flex-1 overflow-y-hidden overflow-x-scroll overscroll-contain scrollbar scrollbar-track-light-200 scrollbar-thumb-light-400 dark:scrollbar-track-dark-100 dark:scrollbar-thumb-dark-300">
{isLoading ? (
<div className="ml-[2rem] flex">
<div className="0 mr-5 h-[500px] w-[18rem] animate-pulse rounded-md bg-light-200 dark:bg-dark-100" />
<div className="0 mr-5 h-[275px] w-[18rem] animate-pulse rounded-md bg-light-200 dark:bg-dark-100" />
<div className="0 mr-5 h-[375px] w-[18rem] animate-pulse rounded-md bg-light-200 dark:bg-dark-100" />
</div>
) : !data ? (
<div className="z-10 flex h-full w-full flex-col items-center justify-center space-y-8 pb-[150px]">
<div className="flex flex-col items-center">
<HiOutlineLockClosed className="h-10 w-10 text-light-800 dark:text-dark-800" />
<p className="mb-2 mt-4 text-[14px] font-bold text-light-1000 dark:text-dark-950">
{t`Board not found`}
</p>
<p className="text-[14px] text-light-900 dark:text-dark-900">
{t`This board is private or does not exist`}
</p>
</div>
<Button href={`/${workspaceSlug}`}>{t`View workspace`}</Button>
</div>
) : (
<div className="flex">
<div className="min-w-[2rem]" />
{data?.lists.map((list) => (
{data.lists.map((list) => (
<div
key={list.publicId}
className="dark-text-dark-1000 mr-5 h-fit min-w-[18rem] max-w-[18rem] rounded-md border border-light-400 bg-light-300 py-2 pl-2 pr-1 text-neutral-900 dark:border-dark-300 dark:bg-dark-100"

View File

@@ -23,13 +23,15 @@ services:
- STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY}
- STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET}
# SMTP
# Email
- SMTP_HOST=${SMTP_HOST}
- SMTP_PORT=${SMTP_PORT}
- SMTP_USER=${SMTP_USER}
- SMTP_PASSWORD=${SMTP_PASSWORD}
- SMTP_SECURE=${SMTP_SECURE}
- EMAIL_FROM=${EMAIL_FROM}
- PLUNK_API_KEY=${PLUNK_API_KEY}
- PLUNK_API_URL=${PLUNK_API_URL}
# S3 storage
- S3_ACCESS_KEY_ID=${S3_ACCESS_KEY_ID}

View File

@@ -111,15 +111,21 @@ export const boardRouter = createTRPCRouter({
.meta({
openapi: {
method: "GET",
path: "/board/{boardSlug}",
path: "/workspaces/{workspaceSlug}/boards/{boardSlug}",
summary: "Get board by slug",
description: "Retrieves a board by its slug",
description:
"Retrieves a board by its slug within a specific workspace",
tags: ["Boards"],
protect: false,
},
})
.input(
z.object({
workspaceSlug: z
.string()
.min(3)
.max(24)
.regex(/^(?![-]+$)[a-zA-Z0-9-]+$/),
boardSlug: z
.string()
.min(3)
@@ -131,10 +137,26 @@ export const boardRouter = createTRPCRouter({
)
.output(z.custom<Awaited<ReturnType<typeof boardRepo.getBySlug>>>())
.query(async ({ ctx, input }) => {
const result = await boardRepo.getBySlug(ctx.db, input.boardSlug, {
members: input.members ?? [],
labels: input.labels ?? [],
});
const workspace = await workspaceRepo.getBySlugWithBoards(
ctx.db,
input.workspaceSlug,
);
if (!workspace)
throw new TRPCError({
message: `Workspace with slug ${input.workspaceSlug} not found`,
code: "NOT_FOUND",
});
const result = await boardRepo.getBySlug(
ctx.db,
input.boardSlug,
workspace.id,
{
members: input.members ?? [],
labels: input.labels ?? [],
},
);
return result;
}),
@@ -276,6 +298,21 @@ export const boardRouter = createTRPCRouter({
await assertUserInWorkspace(ctx.db, userId, board.workspaceId);
if (input.slug) {
const isBoardSlugAvailable = await boardRepo.isBoardSlugAvailable(
ctx.db,
input.slug,
board.workspaceId,
);
if (!isBoardSlugAvailable) {
throw new TRPCError({
message: `Board slug ${input.slug} is not available`,
code: "BAD_REQUEST",
});
}
}
const result = await boardRepo.update(ctx.db, {
name: input.name,
slug: input.slug,
@@ -407,11 +444,23 @@ export const boardRouter = createTRPCRouter({
}),
)
.query(async ({ ctx, input }) => {
const board = await boardRepo.getWorkspaceAndBoardIdByBoardPublicId(
ctx.db,
input.boardPublicId,
);
if (!board)
throw new TRPCError({
message: `Board with public ID ${input.boardPublicId} not found`,
code: "NOT_FOUND",
});
const isBoardSlugAvailable = await boardRepo.isBoardSlugAvailable(
ctx.db,
input.boardSlug,
input.boardPublicId,
board.workspaceId,
);
return {
isReserved: !isBoardSlugAvailable,
};

View File

@@ -56,7 +56,7 @@ export const memberRouter = createTRPCRouter({
if (isInvitedEmailAlreadyMember) {
throw new TRPCError({
message: `User with email ${input.email} is already a member of this workspace`,
code: "BAD_REQUEST",
code: "CONFLICT",
});
}
@@ -88,6 +88,12 @@ export const memberRouter = createTRPCRouter({
callbackURL: `/boards?type=invite&memberPublicId=${invite.publicId}`,
});
await memberRepo.softDelete(ctx.db, {
memberId: invite.id,
deletedAt: new Date(),
deletedBy: userId,
});
throw new TRPCError({
message: `Failed to send magic link invitation to user with email ${input.email}.`,
code: "INTERNAL_SERVER_ERROR",

View File

@@ -11,7 +11,7 @@ import type { dbClient } from "@kan/db/client";
import * as memberRepo from "@kan/db/repository/member.repo";
import * as userRepo from "@kan/db/repository/user.repo";
import * as schema from "@kan/db/schema";
import { sendEmail } from "@kan/email";
import { cloudMailerClient, sendEmail } from "@kan/email";
import { createStripeClient } from "@kan/stripe";
export const configuredProviders = socialProviderList.reduce<
@@ -183,6 +183,17 @@ export const initAuth = (db: dbClient) => {
return Promise.resolve(true);
},
async after(user) {
if (cloudMailerClient) {
await cloudMailerClient.events.track({
event: "user-signup",
email: user.email,
data: {
name: user.name,
userId: user.id,
},
});
}
if (
user.image &&
!user.image.includes(process.env.NEXT_PUBLIC_STORAGE_DOMAIN!)

View File

@@ -1,4 +1,4 @@
import { and, asc, desc, eq, exists, inArray, isNull, or, sql } from "drizzle-orm";
import { and, asc, desc, eq, inArray, isNull, or } from "drizzle-orm";
import type { dbClient } from "@kan/db/client";
import type { BoardVisibilityStatus } from "@kan/db/schema";
@@ -201,6 +201,7 @@ export const getByPublicId = async (
export const getBySlug = async (
db: dbClient,
boardSlug: string,
workspaceId: number,
filters: {
members: string[];
labels: string[];
@@ -293,6 +294,7 @@ export const getBySlug = async (
},
where: and(
eq(boards.slug, boardSlug),
eq(boards.workspaceId, workspaceId),
isNull(boards.deletedAt),
eq(boards.visibility, "public"),
),
@@ -481,30 +483,18 @@ export const getWorkspaceAndBoardIdByBoardPublicId = async (
export const isBoardSlugAvailable = async (
db: dbClient,
boardSlug: string,
boardPublicId: string,
workspaceId: number,
) => {
const result = await db
.select({ id: boards.id })
.from(boards)
.where(
and(
eq(boards.publicId, boardPublicId),
exists(
db
.select({ id: boards.id })
.from(boards)
.where(
and(
eq(boards.slug, boardSlug),
eq(boards.workspaceId, sql`${boards.workspaceId}`), // Reference outer query's workspaceId
isNull(boards.deletedAt),
),
)
.limit(1),
),
),
)
.limit(1);
const result = await db.query.boards.findFirst({
columns: {
id: true,
},
where: and(
eq(boards.slug, boardSlug),
eq(boards.workspaceId, workspaceId),
isNull(boards.deletedAt),
),
});
return result.length === 0;
return result === undefined;
};

View File

@@ -23,6 +23,7 @@
"typecheck": "tsc --noEmit --emitDeclarationOnly false"
},
"dependencies": {
"@plunk/node": "^3.0.3",
"@react-email/components": "^0.0.25",
"nodemailer": "^7.0.3",
"react-email": "^3.0.1"

View File

@@ -0,0 +1,8 @@
import Plunk from "@plunk/node";
export const cloudMailerClient =
process.env.NEXT_PUBLIC_KAN_ENV === "cloud"
? new Plunk(process.env.PLUNK_API_KEY ?? "", {
baseUrl: process.env.PLUNK_API_URL,
})
: null;

View File

@@ -1,3 +1,4 @@
export const name = "email";
export { sendEmail } from "./sendEmail";
export { cloudMailerClient } from "./cloudMailerClient";

View File

@@ -1,6 +1,7 @@
import { render } from "@react-email/render";
import nodemailer from "nodemailer";
import { cloudMailerClient } from "./cloudMailerClient";
import JoinWorkspaceTemplate from "./templates/join-workspace";
import MagicLinkTemplate from "./templates/magic-link";
import ResetPasswordTemplate from "./templates/reset-password";
@@ -44,6 +45,15 @@ export const sendEmail = async (
html,
};
if (cloudMailerClient) {
const response = await cloudMailerClient.emails.send({
...options,
body: html,
});
return response;
}
const response = await transporter.sendMail(options);
if (!response.accepted.length) {

10
pnpm-lock.yaml generated
View File

@@ -409,6 +409,9 @@ importers:
packages/email:
dependencies:
'@plunk/node':
specifier: ^3.0.3
version: 3.0.3
'@react-email/components':
specifier: ^0.0.25
version: 0.0.25(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -2194,6 +2197,9 @@ packages:
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
'@plunk/node@3.0.3':
resolution: {integrity: sha512-f3NT418/EdLjebQ4arAwR64cnz7d5H7i1CeKh8+B0cVBrwzHvF+Q+QkhutF+FAp49yuI/BYc71qQH+RFc2fxxQ==}
'@popperjs/core@2.11.8':
resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
@@ -8910,6 +8916,10 @@ snapshots:
'@pkgjs/parseargs@0.11.0':
optional: true
'@plunk/node@3.0.3':
dependencies:
tslib: 2.8.1
'@popperjs/core@2.11.8': {}
'@react-aria/focus@3.19.0(react@18.3.1)':

View File

@@ -109,7 +109,9 @@
"S3_FORCE_PATH_STYLE",
"PORT",
"BETTER_AUTH_SECRET",
"BETTER_AUTH_TRUSTED_ORIGINS"
"BETTER_AUTH_TRUSTED_ORIGINS",
"PLUNK_API_KEY",
"PLUNK_API_URL"
],
"globalPassThroughEnv": [
"NODE_ENV",