Compare commits
5 Commits
fix/openap
...
feat/free-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3fb4996af | ||
|
|
aa8357841a | ||
|
|
4c0689e5d5 | ||
|
|
95497da944 | ||
|
|
2fa718417f |
@@ -29,7 +29,6 @@ S3_SECRET_ACCESS_KEY=
|
||||
S3_FORCE_PATH_STYLE=
|
||||
NEXT_PUBLIC_STORAGE_URL=
|
||||
NEXT_PUBLIC_AVATAR_BUCKET_NAME=
|
||||
NEXT_PUBLIC_ATTACHMENTS_BUCKET_NAME=
|
||||
NEXT_PUBLIC_STORAGE_DOMAIN=
|
||||
|
||||
# Auth config (optional)
|
||||
|
||||
@@ -170,7 +170,6 @@ pnpm dev
|
||||
| `NEXT_PUBLIC_STORAGE_URL` | Storage service URL | For file uploads | `https://storage.kanbn.com` |
|
||||
| `NEXT_PUBLIC_STORAGE_DOMAIN` | Storage domain name | For file uploads | `kanbn.com` |
|
||||
| `NEXT_PUBLIC_AVATAR_BUCKET_NAME` | S3 bucket name for avatars | For file uploads | `avatars` |
|
||||
| `NEXT_PUBLIC_ATTATCHMENTS_BUCKET_NAME` | S3 bucket name for attatchments | For file uploads | `attatchments` |
|
||||
| `NEXT_PUBLIC_ALLOW_CREDENTIALS` | Allow email & password login | For authentication | `true` |
|
||||
| `NEXT_PUBLIC_DISABLE_SIGN_UP` | Disable sign up | For authentication | `false` |
|
||||
| `NEXT_PUBLIC_WHITE_LABEL_HIDE_POWERED_BY` | Hide “Powered by kan.bn” on public boards (self-host) | For white labelling | `true` |
|
||||
|
||||
@@ -60,7 +60,6 @@ checksums:
|
||||
Are%20you%20sure%20you%20want%20to%20delete%20your%20account%3F/singular: 428b74d781063224c3e63980e1094ec3
|
||||
assigned%20%3C0%3E%7B0%7D%3C%2F0%3E%20to%20the%20card/singular: 9df6d89fa83706123dedd8cba2243d04
|
||||
Assignees/singular: 96fc0e28a783d80decfd4716a440ac08
|
||||
Attachment%20uploaded/singular: c0233f8c2560f95ac0834f35eb07b9e7
|
||||
Awaiting%20Customer/singular: 122c108794f321c10e05a08f09b11457
|
||||
Backlog/singular: 35919fd5b10ad212839a75e72829fe4e
|
||||
Basic%20Kanban/singular: e46ebc406749486f3907436970d4d6c7
|
||||
@@ -172,7 +171,6 @@ checksums:
|
||||
Documentation/singular: 1563fcb5ddb5037b0709ccd3dd384a92
|
||||
Don't%20have%20an%20account%3F%20%3C0%3E%3C1%3ESign%20up%3C%2F1%3E%3C%2F0%3E/singular: 6ae8282ab8b4a01b4ce87b119e13714b
|
||||
Done/singular: ffd408fa29d5bc9039ef8ea1b9b699bb
|
||||
Download%20failed/singular: 142b391cca3e05f2af9617092f7358c5
|
||||
Edit%20board%20URL/singular: d8276dfc0189f371ec7d80a2047c07aa
|
||||
Edit%20comment/singular: 7e4b46525fcb6b47b71798e31c46e374
|
||||
Edit%20label/singular: 0309e0be1512b1e0b0ceb87c69a53d03
|
||||
@@ -211,7 +209,6 @@ checksums:
|
||||
Failed%20to%20copy%20invite%20link/singular: 635884d5ed8d6ee20b85a003939b4ae7
|
||||
Failed%20to%20create%20board/singular: a746e2afe881c3bf0a8e82a931ca3495
|
||||
Failed%20to%20login%20with%20%7B0%7D.%20Please%20try%20again./singular: 669a4b4247a73f53fb9b8b16e42d166f
|
||||
Failed%20to%20upload%20attachment.%20Please%20try%20again./singular: f8a50d1c8491404f73d3cf701e11f297
|
||||
FAQ/singular: 47e0ee2eb40b4e7e732e05e2233fc71c
|
||||
FAQs/singular: dc36d7992372ccd419b39ef51cf5b16c
|
||||
Fast%20%26%20lightweight/singular: 4f2a80c555a5427b94eef5124aa10775
|
||||
@@ -298,7 +295,6 @@ checksums:
|
||||
Link%20copied/singular: 4a4805700b31ec65bcb3ca962bccfd1b
|
||||
List/singular: 94f13e7ef909a4de9db7abaa1f9f0b61
|
||||
List%20name/singular: e925e2e6ccaf0eb4064a888aaea8d3c2
|
||||
Lists/singular: 9f4a73afc8de321175d71935134ef066
|
||||
Login%20%7C%20kan.bn/singular: 42a6c8dcd73e0d46e652646dc86871eb
|
||||
Logout/singular: 07948fdf20705e04a7bf68ab197512bf
|
||||
Long-term/singular: 51cb6f0b112250c5a091ca5f0866904b
|
||||
@@ -333,10 +329,8 @@ checksums:
|
||||
Newsletter/singular: dcfb9666301924431ac8ae88e5b6f9d7
|
||||
Next%20Steps/singular: 12392fe73ae60b6e5a9d851256b8477e
|
||||
No%20%7B0%7D/singular: a7a95e1dfdb4396da9e2be0e27f42323
|
||||
No%20authentication%20methods%20are%20currently%20available/singular: f718c896810da3612202887f9a4374fa
|
||||
No%20boards%20found/singular: e044088d2c51b6bdf660fafa86ee1e17
|
||||
No%20credit%20card%20required/singular: 2090aa4171dc0b60735069f89b592883
|
||||
No%20download%20URL%20available%20for%20this%20attachment./singular: e367d39420b2242f9d2fd749c87f446a
|
||||
No%20lists/singular: cedf633d99c77ff4356e089f2d98c0a6
|
||||
No%20results%20found%20for%20%22%7BdebouncedQuery%7D%22./singular: 5db6294712528cd897b15ae36f4fd834
|
||||
Offer/singular: 82b4e0c9a3f5b4bd93590847de7c32a1
|
||||
@@ -482,7 +476,6 @@ checksums:
|
||||
Unable%20to%20create%20list/singular: 7fbbf8314f8d08a4123c7daef09fed05
|
||||
Unable%20to%20create%20template/singular: 7495f1434c9188849bffd015811d5337
|
||||
Unable%20to%20create%20workspace/singular: c1c949477e121d73ed6683eddf9cd874
|
||||
Unable%20to%20delete%20attachment/singular: 99d0b17b78d44e15f13d876d155f0efc
|
||||
Unable%20to%20delete%20card/singular: 50ff06aa1265fe464f776aba33f1bef9
|
||||
Unable%20to%20delete%20checklist/singular: d7067e2c009f4919f0cca77df3c228ee
|
||||
Unable%20to%20delete%20checklist%20item/singular: a74144593b625e4d8d7ecf734462c60d
|
||||
@@ -516,7 +509,6 @@ checksums:
|
||||
updated%20the%20title%20to%20%3C0%3E%7B0%7D%3C%2F0%3E/singular: aca196d729401d8adc5c8ca9d558840e
|
||||
Upgrade%20to%20Pro/singular: 972773025e763ddf53273df6d37a729a
|
||||
Upgrade%20to%20Pro%20(%2429%2Fmonth)/singular: 9a91ea70f5eb55aac96640bf0fd7feff
|
||||
Upload%20failed/singular: 5b7b755f05330164dbfb00096c500ee3
|
||||
Urgent/singular: e79afcd4398e52e10e7e8243a7eecabe
|
||||
URL%20can%20only%20contain%20letters%2C%20numbers%2C%20and%20hyphens/singular: 875d37d2d920f98ef60a314eda8a5d9a
|
||||
URL%20cannot%20exceed%2024%20characters/singular: 395c25732b84ac1f5b63ee310da08e93
|
||||
@@ -571,7 +563,6 @@ checksums:
|
||||
Your%20account%20has%20been%20deleted./singular: 8c8d944e07388c5877effdb2c2803dcf
|
||||
Your%20boards%20have%20been%20imported./singular: 403972e7a25afc2415762c1c2b1ec868
|
||||
Your%20display%20name%20has%20been%20updated./singular: 15e5fff36c554c16ec5214427fae1bf4
|
||||
Your%20file%20has%20been%20uploaded%20successfully./singular: 19d84e934877efc0fef285ff3d6e7849
|
||||
Your%20password%20has%20been%20changed./singular: 8f730f68d52b7efa727aa0784282ebcb
|
||||
Your%20profile%20image%20has%20been%20updated./singular: 099e1780348cd7bf617721344371a430
|
||||
Your%20Trello%20account%20has%20been%20disconnected./singular: 126aeeb73f7e4cad338056e4c933f39b
|
||||
|
||||
@@ -30,50 +30,23 @@ const config = {
|
||||
typescript: { ignoreBuildErrors: true },
|
||||
|
||||
images: {
|
||||
remotePatterns: (() => {
|
||||
/** @type {Array<{protocol: "http" | "https", hostname: string}>} */
|
||||
const patterns = [
|
||||
{
|
||||
protocol: "https",
|
||||
hostname:
|
||||
env("S3_FORCE_PATH_STYLE") === "true"
|
||||
? `${env("NEXT_PUBLIC_STORAGE_DOMAIN")}`
|
||||
: `*.${env("NEXT_PUBLIC_STORAGE_DOMAIN")}`,
|
||||
},
|
||||
{
|
||||
protocol: "http",
|
||||
hostname: "localhost",
|
||||
},
|
||||
{
|
||||
protocol: "https",
|
||||
hostname: "*.googleusercontent.com",
|
||||
},
|
||||
];
|
||||
|
||||
// Extract root domain from S3_ENDPOINT and add wildcard pattern
|
||||
const s3Endpoint = env("S3_ENDPOINT");
|
||||
if (s3Endpoint) {
|
||||
try {
|
||||
const url = new URL(s3Endpoint);
|
||||
const hostname = url.hostname;
|
||||
const protocol = url.protocol.replace(":", "");
|
||||
|
||||
// Extract root domain (last 2 parts: e.g. cloudflarestorage.com)
|
||||
const parts = hostname.split(".");
|
||||
if (parts.length >= 2) {
|
||||
const rootDomain = parts.slice(-2).join(".");
|
||||
patterns.push({
|
||||
protocol: protocol === "http" ? "http" : "https",
|
||||
hostname: `*.${rootDomain}`,
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
// If S3_ENDPOINT is not a valid URL, ignore it
|
||||
}
|
||||
}
|
||||
|
||||
return patterns;
|
||||
})(),
|
||||
remotePatterns: [
|
||||
{
|
||||
protocol: "https",
|
||||
hostname:
|
||||
env("S3_FORCE_PATH_STYLE") === "true"
|
||||
? `${env("NEXT_PUBLIC_STORAGE_DOMAIN")}`
|
||||
: `*.${env("NEXT_PUBLIC_STORAGE_DOMAIN")}`,
|
||||
},
|
||||
{
|
||||
protocol: "http",
|
||||
hostname: "localhost",
|
||||
},
|
||||
{
|
||||
protocol: "https",
|
||||
hostname: "*.googleusercontent.com",
|
||||
},
|
||||
],
|
||||
},
|
||||
webpack(config) {
|
||||
config.module.rules.push({
|
||||
|
||||
@@ -65,7 +65,6 @@
|
||||
"superjson": "2.2.1",
|
||||
"tailwind-merge": "^2.5.2",
|
||||
"tippy.js": "^6.3.7",
|
||||
"tiptap-markdown": "^0.8",
|
||||
"zod": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -303,10 +303,6 @@ export function Auth({ setIsMagicLinkSent, isSignUp }: AuthProps) {
|
||||
|
||||
const password = watch("password");
|
||||
|
||||
const isMagicLinkAvailable = useMemo(() => {
|
||||
return isCloudEnv || (isEmailSendingEnabled && !isSignUp);
|
||||
}, [isCloudEnv, isEmailSendingEnabled, isSignUp]);
|
||||
|
||||
// Determine if we should operate in magic link mode for current form state (login only)
|
||||
const isMagicLinkMode = useMemo(() => {
|
||||
// Magic link only viable when email sending enabled AND not sign up.
|
||||
@@ -362,16 +358,7 @@ export function Auth({ setIsMagicLinkSent, isSignUp }: AuthProps) {
|
||||
</div>
|
||||
)}
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
{!isCredentialsEnabled && socialProviders?.length === 0 && (
|
||||
<div className="flex w-full items-center gap-4">
|
||||
<div className="h-[1px] w-1/3 bg-light-600 dark:bg-dark-600" />
|
||||
<span className="text-center text-sm text-light-900 dark:text-dark-900">
|
||||
{t`No authentication methods are currently available`}
|
||||
</span>
|
||||
<div className="h-[1px] w-1/3 bg-light-600 dark:bg-dark-600" />
|
||||
</div>
|
||||
)}
|
||||
{!isCredentialsEnabled && socialProviders?.length !== 0 && (
|
||||
{socialProviders?.length !== 0 && (
|
||||
<div className="mb-[1.5rem] flex w-full items-center gap-4">
|
||||
<div className="h-[1px] w-full bg-light-600 dark:bg-dark-600" />
|
||||
<span className="text-sm text-light-900 dark:text-dark-900">
|
||||
@@ -394,54 +381,46 @@ export function Auth({ setIsMagicLinkSent, isSignUp }: AuthProps) {
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{(isCredentialsEnabled || isMagicLinkAvailable) && (
|
||||
<>
|
||||
<div>
|
||||
<Input
|
||||
{...register("email", { required: true })}
|
||||
placeholder={t`Enter your email address`}
|
||||
/>
|
||||
{errors.email && (
|
||||
<p className="mt-2 text-xs text-red-400">
|
||||
{t`Please enter a valid email address`}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{isCredentialsEnabled && (
|
||||
<div>
|
||||
<Input
|
||||
type="password"
|
||||
{...register("password", { required: true })}
|
||||
placeholder={t`Enter your password`}
|
||||
/>
|
||||
{errors.password && (
|
||||
<p className="mt-2 text-xs text-red-400">
|
||||
{errors.password.message ??
|
||||
t`Please enter a valid password`}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<Input
|
||||
{...register("email", { required: true })}
|
||||
placeholder={t`Enter your email address`}
|
||||
/>
|
||||
{errors.email && (
|
||||
<p className="mt-2 text-xs text-red-400">
|
||||
{t`Please enter a valid email address`}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
{isCredentialsEnabled && (
|
||||
<div>
|
||||
<Input
|
||||
type="password"
|
||||
{...register("password", { required: true })}
|
||||
placeholder={t`Enter your password`}
|
||||
/>
|
||||
{errors.password && (
|
||||
<p className="mt-2 text-xs text-red-400">
|
||||
{errors.password.message ?? t`Please enter a valid password`}
|
||||
</p>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
)}
|
||||
{loginError && (
|
||||
<p className="mt-2 text-xs text-red-400">{loginError}</p>
|
||||
)}
|
||||
</div>
|
||||
{(isCredentialsEnabled || isMagicLinkAvailable) && (
|
||||
<div className="mt-[1.5rem] flex items-center gap-4">
|
||||
<Button
|
||||
isLoading={isLoginWithEmailPending}
|
||||
fullWidth
|
||||
size="lg"
|
||||
variant="secondary"
|
||||
>
|
||||
{isSignUp ? t`Sign up with ` : t`Continue with `}
|
||||
{isMagicLinkMode ? t`magic link` : t`email`}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
<div className="mt-[1.5rem] flex items-center gap-4">
|
||||
<Button
|
||||
isLoading={isLoginWithEmailPending}
|
||||
fullWidth
|
||||
size="lg"
|
||||
variant="secondary"
|
||||
>
|
||||
{isSignUp ? t`Sign up with ` : t`Continue with `}
|
||||
{isMagicLinkMode ? t`magic link` : t`email`}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -7,7 +7,6 @@ import type { Instance as TippyInstance } from "tippy.js";
|
||||
import { Button } from "@headlessui/react";
|
||||
import { t } from "@lingui/core/macro";
|
||||
import Link from "@tiptap/extension-link";
|
||||
import Mention from "@tiptap/extension-mention";
|
||||
import Placeholder from "@tiptap/extension-placeholder";
|
||||
import {
|
||||
BubbleMenu,
|
||||
@@ -40,10 +39,9 @@ import {
|
||||
} from "react-icons/hi2";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import tippy from "tippy.js";
|
||||
import { Markdown } from "tiptap-markdown";
|
||||
|
||||
import { getAvatarUrl } from "~/utils/helpers";
|
||||
import Mention from "@tiptap/extension-mention";
|
||||
import Avatar from "./Avatar";
|
||||
import { getAvatarUrl } from "~/utils/helpers";
|
||||
|
||||
declare module "@tiptap/core" {
|
||||
interface Commands<ReturnType> {
|
||||
@@ -79,7 +77,7 @@ export interface RenderSuggestionsProps {
|
||||
command: (item: SlashCommandItem) => void;
|
||||
}
|
||||
|
||||
export interface WorkspaceMember {
|
||||
export type WorkspaceMember = {
|
||||
publicId: string;
|
||||
user: {
|
||||
id: string;
|
||||
@@ -87,7 +85,7 @@ export interface WorkspaceMember {
|
||||
image: string | null;
|
||||
} | null;
|
||||
email: string;
|
||||
}
|
||||
};
|
||||
|
||||
const CommandsList = forwardRef<
|
||||
{ onKeyDown: (props: SuggestionKeyDownProps) => boolean },
|
||||
@@ -202,11 +200,7 @@ const RenderSuggestions = () => {
|
||||
};
|
||||
};
|
||||
|
||||
interface MentionItem {
|
||||
id: string;
|
||||
label: string;
|
||||
image: string | null;
|
||||
}
|
||||
type MentionItem = { id: string; label: string; image: string | null };
|
||||
|
||||
const MentionList = forwardRef<
|
||||
{ onKeyDown: (props: SuggestionKeyDownProps) => boolean },
|
||||
@@ -244,32 +238,30 @@ const MentionList = forwardRef<
|
||||
return (
|
||||
<div className="w-56 rounded-md border-[1px] border-light-200 bg-light-50 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:border-dark-500 dark:bg-dark-200">
|
||||
<div className="max-h-[350px] overflow-y-auto p-1 scrollbar-thin scrollbar-thumb-light-200 dark:scrollbar-thumb-dark-300">
|
||||
{items.length > 0 ? (
|
||||
items.map((item, index) => (
|
||||
<button
|
||||
key={item.id}
|
||||
onClick={() => command(item)}
|
||||
className={twMerge(
|
||||
"group flex w-full items-center rounded-[5px] p-2 hover:bg-light-200 dark:hover:bg-dark-300",
|
||||
index === selectedIndex && "bg-light-200 dark:bg-dark-300",
|
||||
)}
|
||||
>
|
||||
<Avatar
|
||||
size="xs"
|
||||
name={item.label}
|
||||
imageUrl={item.image ? getAvatarUrl(item.image) : undefined}
|
||||
email={item.label}
|
||||
/>
|
||||
<span className="ml-3 text-[12px] font-medium text-dark-900 dark:text-dark-1000">
|
||||
{item.label}
|
||||
</span>
|
||||
</button>
|
||||
))
|
||||
) : (
|
||||
<div className="flex items-center justify-start p-2">
|
||||
<span className="text-[12px] text-dark-900 dark:text-dark-1000">
|
||||
No results
|
||||
{items.length > 0 ? items.map((item, index) => (
|
||||
<button
|
||||
key={item.id}
|
||||
onClick={() => command(item)}
|
||||
className={twMerge(
|
||||
"group flex w-full items-center rounded-[5px] p-2 hover:bg-light-200 dark:hover:bg-dark-300",
|
||||
index === selectedIndex && "bg-light-200 dark:bg-dark-300",
|
||||
)}
|
||||
>
|
||||
<Avatar
|
||||
size="xs"
|
||||
name={item.label}
|
||||
imageUrl={
|
||||
item.image ? getAvatarUrl(item.image) : undefined
|
||||
}
|
||||
email={item.label}
|
||||
/>
|
||||
<span className="ml-3 text-[12px] font-medium text-dark-900 dark:text-dark-1000">
|
||||
{item.label}
|
||||
</span>
|
||||
</button>
|
||||
)) : (
|
||||
<div className="flex items-center justify-start p-2">
|
||||
<span className="text-dark-900 text-[12px] dark:text-dark-1000">No results</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -444,7 +436,6 @@ export default function Editor({
|
||||
{
|
||||
extensions: [
|
||||
StarterKit,
|
||||
Markdown,
|
||||
Placeholder.configure({
|
||||
placeholder: readOnly
|
||||
? ""
|
||||
@@ -471,37 +462,35 @@ export default function Editor({
|
||||
}),
|
||||
Mention.configure({
|
||||
HTMLAttributes: {
|
||||
class: "mention",
|
||||
class: 'mention',
|
||||
},
|
||||
suggestion: {
|
||||
char: "@",
|
||||
items: ({ query }: { query: string }) => {
|
||||
const all: MentionItem[] = workspaceMembers.map(
|
||||
(member: WorkspaceMember) => ({
|
||||
id: member.publicId,
|
||||
label: member?.user?.name ?? member.email,
|
||||
image: member?.user?.image ?? null,
|
||||
}),
|
||||
);
|
||||
const all: MentionItem[] = workspaceMembers.map((member: WorkspaceMember) => ({
|
||||
id: member.publicId,
|
||||
label: member?.user?.name ?? member.email,
|
||||
image: member?.user?.image ?? null,
|
||||
}));
|
||||
const q = query.toLowerCase();
|
||||
return all.filter((u) => u.label.toLowerCase().includes(q));
|
||||
},
|
||||
command: ({ editor, range, props }: any) => {
|
||||
const mentionHTML = `<span data-type="mention" data-id="${props.id}" data-label="${props.label}">@${props.label}</span> `;
|
||||
|
||||
editor
|
||||
.chain()
|
||||
.focus()
|
||||
.deleteRange(range)
|
||||
.insertContent(mentionHTML)
|
||||
.focus()
|
||||
.run();
|
||||
const mentionHTML = `<span data-type="mention" data-id="${props.id}" data-label="${props.label}">@${props.label}</span> `;
|
||||
|
||||
editor
|
||||
.chain()
|
||||
.focus()
|
||||
.deleteRange(range)
|
||||
.insertContent(mentionHTML)
|
||||
.focus()
|
||||
.run();
|
||||
},
|
||||
render: renderMentionSuggestions,
|
||||
},
|
||||
renderText({ options, node }) {
|
||||
return `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`;
|
||||
},
|
||||
render: renderMentionSuggestions,
|
||||
},
|
||||
renderText({ options, node }) {
|
||||
return `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`;
|
||||
},
|
||||
}),
|
||||
],
|
||||
content,
|
||||
|
||||
@@ -122,10 +122,10 @@ export default function SideNavigation({
|
||||
)}
|
||||
>
|
||||
<div>
|
||||
<div className="hidden h-[45px] items-center justify-between pb-3 md:flex">
|
||||
<div className="hidden h-14 items-center justify-between pb-[18px] pt-1.5 md:flex">
|
||||
{!isCollapsed && (
|
||||
<Link href="/" className="block">
|
||||
<h1 className="pl-2 text-[16px] font-bold tracking-tight text-neutral-900 dark:text-dark-1000">
|
||||
<h1 className="pl-2 text-lg font-bold tracking-tight text-neutral-900 dark:text-dark-1000">
|
||||
kan.bn
|
||||
</h1>
|
||||
</Link>
|
||||
|
||||
@@ -90,7 +90,6 @@ export const env = createEnv({
|
||||
NEXT_PUBLIC_BASE_URL: z.string().url(),
|
||||
NEXT_PUBLIC_STORAGE_URL: z.string().url().optional(),
|
||||
NEXT_PUBLIC_AVATAR_BUCKET_NAME: z.string().optional(),
|
||||
NEXT_PUBLIC_ATTACHMENTS_BUCKET_NAME: z.string().optional(),
|
||||
NEXT_PUBLIC_STORAGE_DOMAIN: z.string().optional(),
|
||||
NEXT_PUBLIC_ALLOW_CREDENTIALS: z
|
||||
.string()
|
||||
@@ -126,8 +125,6 @@ export const env = createEnv({
|
||||
NEXT_PUBLIC_BASE_URL: process.env.NEXT_PUBLIC_BASE_URL,
|
||||
NEXT_PUBLIC_STORAGE_URL: process.env.NEXT_PUBLIC_STORAGE_URL,
|
||||
NEXT_PUBLIC_AVATAR_BUCKET_NAME: process.env.NEXT_PUBLIC_AVATAR_BUCKET_NAME,
|
||||
NEXT_PUBLIC_ATTACHMENTS_BUCKET_NAME:
|
||||
process.env.NEXT_PUBLIC_ATTACHMENTS_BUCKET_NAME,
|
||||
NEXT_PUBLIC_STORAGE_DOMAIN: process.env.NEXT_PUBLIC_STORAGE_DOMAIN,
|
||||
NEXT_PUBLIC_ALLOW_CREDENTIALS: process.env.NEXT_PUBLIC_ALLOW_CREDENTIALS,
|
||||
NEXT_PUBLIC_DISABLE_SIGN_UP: process.env.NEXT_PUBLIC_DISABLE_SIGN_UP,
|
||||
|
||||
@@ -31,17 +31,17 @@ msgstr "{0}"
|
||||
#. placeholder {1}: board?.name ?? t`Board`
|
||||
#. placeholder {1}: workspace.name ?? t`Workspace`
|
||||
#: src/views/boards/index.tsx:22
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/card/index.tsx:216
|
||||
msgid "{0} | {1}"
|
||||
msgstr "{0} | {1}"
|
||||
|
||||
#. placeholder {0}: labelPublicIds.length
|
||||
#: src/views/board/components/NewCardForm.tsx:443
|
||||
#: src/views/board/components/NewCardForm.tsx:442
|
||||
msgid "{0} labels"
|
||||
msgstr "{0} Labels"
|
||||
|
||||
#. placeholder {0}: isTemplate ? "Template" : "Board"
|
||||
#: src/views/board/index.tsx:389
|
||||
#: src/views/board/index.tsx:387
|
||||
msgid "{0} not found"
|
||||
msgstr "{0} nicht gefunden"
|
||||
|
||||
@@ -79,8 +79,8 @@ msgstr "Konto"
|
||||
msgid "Account deleted"
|
||||
msgstr "Konto gelöscht"
|
||||
|
||||
#: src/views/card/index.tsx:308
|
||||
#: src/views/public/board/CardModal.tsx:157
|
||||
#: src/views/card/index.tsx:291
|
||||
#: src/views/public/board/CardModal.tsx:143
|
||||
msgid "Activity"
|
||||
msgstr "Aktivität"
|
||||
|
||||
@@ -109,7 +109,7 @@ msgstr "Element hinzufügen..."
|
||||
msgid "Add checklist"
|
||||
msgstr "Checkliste hinzufügen"
|
||||
|
||||
#: src/components/Editor.tsx:451
|
||||
#: src/components/Editor.tsx:442
|
||||
msgid "Add description... (type '/' to open commands or '@' to mention)"
|
||||
msgstr "Beschreibung hinzufügen... (tippe '/' um Befehle zu öffnen oder '@' um jemanden zu erwähnen)"
|
||||
|
||||
@@ -270,10 +270,6 @@ msgstr "hat <0>{0}</0> der Karte zugewiesen"
|
||||
msgid "Assignees"
|
||||
msgstr "Zugewiesene Personen"
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:25
|
||||
msgid "Attachment uploaded"
|
||||
msgstr "Anhang hochgeladen"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:47
|
||||
msgid "Awaiting Customer"
|
||||
msgstr "Warten auf Kunden"
|
||||
@@ -308,9 +304,9 @@ msgstr "Abrechnungsportal"
|
||||
msgid "Blog Post"
|
||||
msgstr "Blogbeitrag"
|
||||
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/public/board/index.tsx:101
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/card/index.tsx:216
|
||||
#: src/views/public/board/index.tsx:100
|
||||
msgid "Board"
|
||||
msgstr "Board"
|
||||
|
||||
@@ -327,7 +323,7 @@ msgstr "Der Name des Boards darf 100 Zeichen nicht überschreiten"
|
||||
msgid "Board name is required"
|
||||
msgstr "Boardname ist erforderlich"
|
||||
|
||||
#: src/views/public/board/index.tsx:153
|
||||
#: src/views/public/board/index.tsx:151
|
||||
msgid "Board not found"
|
||||
msgstr "Board nicht gefunden"
|
||||
|
||||
@@ -335,19 +331,19 @@ msgstr "Board nicht gefunden"
|
||||
msgid "Board sharing & invites"
|
||||
msgstr "Board-Freigabe & Einladungen"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:46
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:45
|
||||
msgid "Board URL can only contain letters, numbers, and hyphens"
|
||||
msgstr "Board-URL darf nur Buchstaben, Zahlen und Bindestriche enthalten"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:44
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:43
|
||||
msgid "Board URL cannot exceed 60 characters"
|
||||
msgstr "Board-URL darf 60 Zeichen nicht überschreiten"
|
||||
|
||||
#: src/views/public/board/index.tsx:68
|
||||
#: src/views/public/board/index.tsx:67
|
||||
msgid "Board URL copied to clipboard"
|
||||
msgstr "Board-URL in die Zwischenablage kopiert"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:42
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:41
|
||||
msgid "Board URL must be at least 3 characters long"
|
||||
msgstr "Board-URL muss mindestens 3 Zeichen lang sein"
|
||||
|
||||
@@ -356,7 +352,7 @@ msgstr "Board-URL muss mindestens 3 Zeichen lang sein"
|
||||
msgid "Board visibility"
|
||||
msgstr "Board-Sichtbarkeit"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:46
|
||||
#: src/views/board/components/VisibilityButton.tsx:45
|
||||
msgid "Board visibility updated"
|
||||
msgstr "Board-Sichtbarkeit aktualisiert"
|
||||
|
||||
@@ -391,15 +387,15 @@ msgstr "Fehlerbericht"
|
||||
msgid "Cancel"
|
||||
msgstr "Abbrechen"
|
||||
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/card/index.tsx:216
|
||||
msgid "Card"
|
||||
msgstr "Karte"
|
||||
|
||||
#: src/views/card/index.tsx:264
|
||||
#: src/views/card/index.tsx:262
|
||||
msgid "Card not found"
|
||||
msgstr "Karte nicht gefunden"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:310
|
||||
#: src/views/board/components/NewCardForm.tsx:309
|
||||
msgid "Card title"
|
||||
msgstr "Kartentitel"
|
||||
|
||||
@@ -432,7 +428,7 @@ msgstr "Checklistenname"
|
||||
msgid "Checklists"
|
||||
msgstr "Checklisten"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:180
|
||||
#: src/views/board/components/Filters.tsx:155
|
||||
msgid "Clear filters"
|
||||
msgstr "Filter löschen"
|
||||
|
||||
@@ -523,7 +519,7 @@ msgstr "Kontaktiere uns"
|
||||
msgid "Content Creation"
|
||||
msgstr "Content-Erstellung"
|
||||
|
||||
#: src/components/AuthForm.tsx:434
|
||||
#: src/components/AuthForm.tsx:420
|
||||
msgid "Continue with "
|
||||
msgstr "Fortfahren mit "
|
||||
|
||||
@@ -546,8 +542,8 @@ msgid "Create {0}"
|
||||
msgstr "{0} erstellen"
|
||||
|
||||
#: src/components/LabelForm.tsx:213
|
||||
#: src/views/board/components/NewCardForm.tsx:469
|
||||
#: src/views/board/components/NewListForm.tsx:141
|
||||
#: src/views/board/components/NewCardForm.tsx:468
|
||||
#: src/views/board/components/NewListForm.tsx:140
|
||||
msgid "Create another"
|
||||
msgstr "Weitere erstellen"
|
||||
|
||||
@@ -555,7 +551,7 @@ msgstr "Weitere erstellen"
|
||||
msgid "Create API key"
|
||||
msgstr "API-Schlüssel erstellen"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:479
|
||||
#: src/views/board/components/NewCardForm.tsx:478
|
||||
msgid "Create card"
|
||||
msgstr "Karte erstellen"
|
||||
|
||||
@@ -571,7 +567,7 @@ msgstr "Einladungslink erstellen"
|
||||
msgid "Create label"
|
||||
msgstr "Label erstellen"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:153
|
||||
#: src/views/board/components/NewListForm.tsx:152
|
||||
msgid "Create list"
|
||||
msgstr "Liste erstellen"
|
||||
|
||||
@@ -584,12 +580,12 @@ msgstr "Neue(n) {0} erstellen"
|
||||
msgid "Create new key"
|
||||
msgstr "Neuen Schlüssel erstellen"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:405
|
||||
#: src/views/board/components/NewCardForm.tsx:404
|
||||
#: src/views/card/components/LabelSelector.tsx:97
|
||||
msgid "Create new label"
|
||||
msgstr "Neues Label erstellen"
|
||||
|
||||
#: src/views/board/index.tsx:478
|
||||
#: src/views/board/index.tsx:475
|
||||
msgid "Create new list"
|
||||
msgstr "Neue Liste erstellen"
|
||||
|
||||
@@ -773,12 +769,8 @@ msgstr "Du hast noch kein Konto? <0><1>Registrieren</1></0>"
|
||||
msgid "Done"
|
||||
msgstr "Erledigt"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:141
|
||||
msgid "Download failed"
|
||||
msgstr "Download fehlgeschlagen"
|
||||
|
||||
#: src/views/board/components/BoardDropdown.tsx:41
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:116
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:115
|
||||
msgid "Edit board URL"
|
||||
msgstr "Board-URL bearbeiten"
|
||||
|
||||
@@ -790,7 +782,7 @@ msgstr "Kommentar bearbeiten"
|
||||
msgid "Edit label"
|
||||
msgstr "Label bearbeiten"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:162
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:161
|
||||
msgid "Edit workspace URL"
|
||||
msgstr "Workspace-URL bearbeiten"
|
||||
|
||||
@@ -798,7 +790,7 @@ msgstr "Workspace-URL bearbeiten"
|
||||
msgid "Editing"
|
||||
msgstr "Bearbeitung"
|
||||
|
||||
#: src/components/AuthForm.tsx:435
|
||||
#: src/components/AuthForm.tsx:421
|
||||
msgid "email"
|
||||
msgstr "E-Mail"
|
||||
|
||||
@@ -818,11 +810,11 @@ msgstr "Geben Sie Ihr aktuelles Passwort ein"
|
||||
msgid "Enter your current password and choose a new secure password."
|
||||
msgstr "Geben Sie Ihr aktuelles Passwort ein und wählen Sie ein neues sicheres Passwort."
|
||||
|
||||
#: src/components/AuthForm.tsx:398
|
||||
#: src/components/AuthForm.tsx:387
|
||||
msgid "Enter your email address"
|
||||
msgstr "Gib deine E-Mail-Adresse ein"
|
||||
|
||||
#: src/components/AuthForm.tsx:384
|
||||
#: src/components/AuthForm.tsx:375
|
||||
msgid "Enter your name"
|
||||
msgstr "Gib deinen Namen ein"
|
||||
|
||||
@@ -830,7 +822,7 @@ msgstr "Gib deinen Namen ein"
|
||||
msgid "Enter your new password"
|
||||
msgstr "Geben Sie Ihr neues Passwort ein"
|
||||
|
||||
#: src/components/AuthForm.tsx:411
|
||||
#: src/components/AuthForm.tsx:400
|
||||
msgid "Enter your password"
|
||||
msgstr "Gib dein Passwort ein"
|
||||
|
||||
@@ -939,11 +931,6 @@ msgstr "Board konnte nicht erstellt werden"
|
||||
msgid "Failed to login with {0}. Please try again."
|
||||
msgstr "Anmeldung mit {0} fehlgeschlagen. Bitte versuche es erneut."
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:33
|
||||
#: src/views/card/components/AttachmentUpload.tsx:79
|
||||
msgid "Failed to upload attachment. Please try again."
|
||||
msgstr "Fehler beim Hochladen des Anhangs. Bitte versuchen Sie es erneut."
|
||||
|
||||
#: src/views/home/components/Header.tsx:41
|
||||
msgid "FAQ"
|
||||
msgstr "FAQ"
|
||||
@@ -987,7 +974,7 @@ msgstr "Feedback"
|
||||
msgid "Feedback sent"
|
||||
msgstr "Feedback gesendet"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:174
|
||||
#: src/views/board/components/Filters.tsx:149
|
||||
msgid "Filter"
|
||||
msgstr "Filter"
|
||||
|
||||
@@ -1000,8 +987,6 @@ msgid "For long-term sustainability, we recognise all good open source projects
|
||||
msgstr "Für langfristige Nachhaltigkeit erkennen wir an, dass alle guten Open-Source-Projekte eine Einnahmequelle benötigen. Unsere stammt aus dem kostenpflichtigen Cloud-Angebot für Workspaces mit mehreren Benutzern und für benutzerdefinierte Workspace-Slugs. Es besteht keine Verpflichtung, es zu nutzen, und Sie können die Software kostenlos auf Ihrer eigenen Infrastruktur selbst hosten."
|
||||
|
||||
#: src/views/pricing/components/Pricing.tsx:32
|
||||
#: src/views/pricing/components/Pricing.tsx:32
|
||||
#: src/views/pricing/components/PricingTiers.tsx:30
|
||||
#: src/views/pricing/components/PricingTiers.tsx:30
|
||||
msgid "Free"
|
||||
msgstr "Kostenlos"
|
||||
@@ -1043,7 +1028,7 @@ msgstr "Loslegen"
|
||||
msgid "Get started by creating a new {0}"
|
||||
msgstr "Beginnen Sie, indem Sie eine(n) neue(n) {0} erstellen"
|
||||
|
||||
#: src/views/board/index.tsx:470
|
||||
#: src/views/board/index.tsx:467
|
||||
msgid "Get started by creating a new list"
|
||||
msgstr "Beginne mit dem Erstellen einer neuen Liste"
|
||||
|
||||
@@ -1257,9 +1242,9 @@ msgstr "Kanban neu gedacht"
|
||||
msgid "Keep in mind that this action is irreversible."
|
||||
msgstr "Beachten Sie, dass diese Aktion nicht rückgängig gemacht werden kann."
|
||||
|
||||
#: src/views/board/components/Filters.tsx:115
|
||||
#: src/views/board/components/NewCardForm.tsx:409
|
||||
#: src/views/card/index.tsx:119
|
||||
#: src/views/board/components/Filters.tsx:101
|
||||
#: src/views/board/components/NewCardForm.tsx:408
|
||||
#: src/views/card/index.tsx:117
|
||||
msgid "Labels"
|
||||
msgstr "Labels"
|
||||
|
||||
@@ -1309,22 +1294,18 @@ msgstr "Lizenz"
|
||||
msgid "Light"
|
||||
msgstr "Hell"
|
||||
|
||||
#: src/views/public/board/index.tsx:66
|
||||
#: src/views/public/board/index.tsx:65
|
||||
msgid "Link copied"
|
||||
msgstr "Link kopiert"
|
||||
|
||||
#: src/views/card/index.tsx:111
|
||||
#: src/views/card/index.tsx:109
|
||||
msgid "List"
|
||||
msgstr "Liste"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:129
|
||||
#: src/views/board/components/NewListForm.tsx:128
|
||||
msgid "List name"
|
||||
msgstr "Listenname"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:123
|
||||
msgid "Lists"
|
||||
msgstr "Listen"
|
||||
|
||||
#: src/views/auth/login/index.tsx:33
|
||||
msgid "Login | kan.bn"
|
||||
msgstr "Login | kan.bn"
|
||||
@@ -1345,7 +1326,7 @@ msgstr "Von Teams weltweit geliebt"
|
||||
msgid "Low Priority"
|
||||
msgstr "Niedrige Priorität"
|
||||
|
||||
#: src/components/AuthForm.tsx:435
|
||||
#: src/components/AuthForm.tsx:421
|
||||
msgid "magic link"
|
||||
msgstr "Magic Link"
|
||||
|
||||
@@ -1367,9 +1348,9 @@ msgid "Medium Priority"
|
||||
msgstr "Mittlere Priorität"
|
||||
|
||||
#: src/components/SideNavigation.tsx:101
|
||||
#: src/views/board/components/Filters.tsx:107
|
||||
#: src/views/board/components/NewCardForm.tsx:367
|
||||
#: src/views/card/index.tsx:128
|
||||
#: src/views/board/components/Filters.tsx:93
|
||||
#: src/views/board/components/NewCardForm.tsx:366
|
||||
#: src/views/card/index.tsx:126
|
||||
#: src/views/members/index.tsx:178
|
||||
msgid "Members"
|
||||
msgstr "Mitglieder"
|
||||
@@ -1422,7 +1403,7 @@ msgstr "Neue(r) {0}"
|
||||
msgid "New API key"
|
||||
msgstr "Neuer API-Schlüssel"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:293
|
||||
#: src/views/board/components/NewCardForm.tsx:292
|
||||
msgid "New card"
|
||||
msgstr "Neue Karte"
|
||||
|
||||
@@ -1438,8 +1419,8 @@ msgstr "Neuer Import"
|
||||
msgid "New label"
|
||||
msgstr "Neues Label"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:113
|
||||
#: src/views/board/index.tsx:442
|
||||
#: src/views/board/components/NewListForm.tsx:112
|
||||
#: src/views/board/index.tsx:439
|
||||
msgid "New list"
|
||||
msgstr "Neue Liste"
|
||||
|
||||
@@ -1476,10 +1457,6 @@ msgstr "Nächste Schritte"
|
||||
msgid "No {0}"
|
||||
msgstr "Keine {0}"
|
||||
|
||||
#: src/components/AuthForm.tsx:365
|
||||
msgid "No authentication methods are currently available"
|
||||
msgstr "Derzeit sind keine Authentifizierungsmethoden verfügbar"
|
||||
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:242
|
||||
msgid "No boards found"
|
||||
msgstr "Keine Boards gefunden"
|
||||
@@ -1488,11 +1465,7 @@ msgstr "Keine Boards gefunden"
|
||||
msgid "No credit card required"
|
||||
msgstr "Keine Kreditkarte erforderlich"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:142
|
||||
msgid "No download URL available for this attachment."
|
||||
msgstr "Für diesen Anhang ist keine Download-URL verfügbar."
|
||||
|
||||
#: src/views/board/index.tsx:467
|
||||
#: src/views/board/index.tsx:464
|
||||
msgid "No lists"
|
||||
msgstr "Keine Listen"
|
||||
|
||||
@@ -1524,7 +1497,7 @@ msgstr "Open Source"
|
||||
msgid "Open Source Friends"
|
||||
msgstr "Open-Source-Freunde"
|
||||
|
||||
#: src/components/AuthForm.tsx:374
|
||||
#: src/components/AuthForm.tsx:365
|
||||
msgid "or"
|
||||
msgstr "oder"
|
||||
|
||||
@@ -1606,15 +1579,15 @@ msgstr "Plattform"
|
||||
msgid "Please confirm your new password"
|
||||
msgstr "Bitte bestätigen Sie Ihr neues Passwort"
|
||||
|
||||
#: src/components/AuthForm.tsx:402
|
||||
#: src/components/AuthForm.tsx:391
|
||||
msgid "Please enter a valid email address"
|
||||
msgstr "Bitte gib eine gültige E-Mail-Adresse ein"
|
||||
|
||||
#: src/components/AuthForm.tsx:388
|
||||
#: src/components/AuthForm.tsx:379
|
||||
msgid "Please enter a valid name"
|
||||
msgstr "Bitte gib einen gültigen Namen ein"
|
||||
|
||||
#: src/components/AuthForm.tsx:416
|
||||
#: src/components/AuthForm.tsx:404
|
||||
msgid "Please enter a valid password"
|
||||
msgstr "Bitte gib ein gültiges Passwort ein"
|
||||
|
||||
@@ -1625,16 +1598,15 @@ msgstr "Bitte wähle eine Datei zum Hochladen aus."
|
||||
#: src/components/DeleteLabelConfirmation.tsx:26
|
||||
#: src/components/FeedbackModal.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:158
|
||||
#: src/views/board/components/NewCardForm.tsx:177
|
||||
#: src/views/board/components/NewListForm.tsx:79
|
||||
#: src/views/board/components/NewCardForm.tsx:176
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/NewTemplateForm.tsx:61
|
||||
#: src/views/board/components/NewTemplateForm.tsx:77
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:73
|
||||
#: src/views/board/components/VisibilityButton.tsx:54
|
||||
#: src/views/board/index.tsx:151
|
||||
#: src/views/board/index.tsx:207
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
#: src/views/board/components/VisibilityButton.tsx:53
|
||||
#: src/views/board/index.tsx:149
|
||||
#: src/views/board/index.tsx:205
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:205
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:73
|
||||
#: src/views/card/components/ChecklistItemRow.tsx:60
|
||||
#: src/views/card/components/ChecklistItemRow.tsx:88
|
||||
#: src/views/card/components/ChecklistNameInput.tsx:46
|
||||
@@ -1648,7 +1620,7 @@ msgstr "Bitte wähle eine Datei zum Hochladen aus."
|
||||
#: src/views/card/components/NewChecklistForm.tsx:70
|
||||
#: src/views/card/components/NewChecklistItemForm.tsx:89
|
||||
#: src/views/card/components/NewCommentForm.tsx:31
|
||||
#: src/views/card/index.tsx:177
|
||||
#: src/views/card/index.tsx:175
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
#: src/views/members/components/InviteMemberForm.tsx:241
|
||||
@@ -1692,7 +1664,7 @@ msgstr "Prioritäts-E-Mail-Support"
|
||||
msgid "Privacy policy"
|
||||
msgstr "Datenschutzrichtlinie"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:74
|
||||
#: src/views/board/components/VisibilityButton.tsx:73
|
||||
msgid "Private"
|
||||
msgstr "Privat"
|
||||
|
||||
@@ -1712,7 +1684,7 @@ msgstr "Profilbild aktualisiert"
|
||||
msgid "Profile picture"
|
||||
msgstr "Profilbild"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:69
|
||||
#: src/views/board/components/VisibilityButton.tsx:68
|
||||
msgid "Public"
|
||||
msgstr "Öffentlich"
|
||||
|
||||
@@ -1914,7 +1886,7 @@ msgstr "Registrierung deaktiviert"
|
||||
msgid "Sign up is currently disabled. Please try again later."
|
||||
msgstr "Die Registrierung ist derzeit deaktiviert. Bitte versuche es später erneut."
|
||||
|
||||
#: src/components/AuthForm.tsx:434
|
||||
#: src/components/AuthForm.tsx:420
|
||||
msgid "Sign up with "
|
||||
msgstr "Registrieren mit "
|
||||
|
||||
@@ -1981,8 +1953,8 @@ msgstr "Team-Plan"
|
||||
msgid "Teams"
|
||||
msgstr "Teams"
|
||||
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/board/index.tsx:398
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/board/index.tsx:396
|
||||
msgid "Template"
|
||||
msgstr "Vorlage"
|
||||
|
||||
@@ -2032,7 +2004,7 @@ msgid "The open source <0/> alternative to Trello"
|
||||
msgstr "Die open source <0/> alternative zu Trello"
|
||||
|
||||
#. placeholder {0}: isPublic ? "public" : "private"
|
||||
#: src/views/board/components/VisibilityButton.tsx:47
|
||||
#: src/views/board/components/VisibilityButton.tsx:46
|
||||
msgid "The visibility of your board has been set to {0}."
|
||||
msgstr "Die Sichtbarkeit deines Boards wurde auf {0} gesetzt."
|
||||
|
||||
@@ -2056,11 +2028,11 @@ msgstr "Diese Aktion kann nicht rückgängig gemacht werden."
|
||||
msgid "This API key will only be shown once. Please save it in a secure location."
|
||||
msgstr "Dieser API-Schlüssel wird nur einmal angezeigt. Bitte speichern Sie ihn an einem sicheren Ort."
|
||||
|
||||
#: src/views/public/board/index.tsx:156
|
||||
#: src/views/public/board/index.tsx:154
|
||||
msgid "This board is private or does not exist"
|
||||
msgstr "Dieses Board ist privat oder existiert nicht"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:136
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:135
|
||||
msgid "This board URL has already been taken"
|
||||
msgstr "Diese Board-URL ist bereits vergeben"
|
||||
|
||||
@@ -2130,7 +2102,7 @@ msgstr "Checklistenelement kann nicht hinzugefügt werden"
|
||||
msgid "Unable to add comment"
|
||||
msgstr "Kommentar konnte nicht hinzugefügt werden"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:174
|
||||
#: src/views/board/components/NewCardForm.tsx:173
|
||||
msgid "Unable to create card"
|
||||
msgstr "Karte konnte nicht erstellt werden"
|
||||
|
||||
@@ -2138,7 +2110,7 @@ msgstr "Karte konnte nicht erstellt werden"
|
||||
msgid "Unable to create checklist"
|
||||
msgstr "Checkliste kann nicht erstellt werden"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/NewListForm.tsx:77
|
||||
msgid "Unable to create list"
|
||||
msgstr "Liste konnte nicht erstellt werden"
|
||||
|
||||
@@ -2151,10 +2123,6 @@ msgstr "Vorlage konnte nicht erstellt werden"
|
||||
msgid "Unable to create workspace"
|
||||
msgstr "Workspace konnte nicht erstellt werden"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:72
|
||||
msgid "Unable to delete attachment"
|
||||
msgstr "Anhang kann nicht gelöscht werden"
|
||||
|
||||
#: src/views/card/components/DeleteCardConfirmation.tsx:51
|
||||
msgid "Unable to delete card"
|
||||
msgstr "Karte konnte nicht gelöscht werden"
|
||||
@@ -2179,16 +2147,16 @@ msgstr "Mitglied konnte nicht entfernt werden"
|
||||
msgid "Unable to send feedback"
|
||||
msgstr "Feedback konnte nicht gesendet werden"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:71
|
||||
msgid "Unable to update board URL"
|
||||
msgstr "Board-URL kann nicht aktualisiert werden"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:53
|
||||
#: src/views/board/components/VisibilityButton.tsx:52
|
||||
msgid "Unable to update board visibility"
|
||||
msgstr "Board-Sichtbarkeit konnte nicht aktualisiert werden"
|
||||
|
||||
#: src/views/board/index.tsx:206
|
||||
#: src/views/card/index.tsx:176
|
||||
#: src/views/board/index.tsx:204
|
||||
#: src/views/card/index.tsx:174
|
||||
msgid "Unable to update card"
|
||||
msgstr "Karte konnte nicht aktualisiert werden"
|
||||
|
||||
@@ -2208,7 +2176,7 @@ msgstr "Kommentar konnte nicht aktualisiert werden"
|
||||
msgid "Unable to update labels"
|
||||
msgstr "Labels konnten nicht aktualisiert werden"
|
||||
|
||||
#: src/views/board/index.tsx:150
|
||||
#: src/views/board/index.tsx:148
|
||||
#: src/views/card/components/ListSelector.tsx:51
|
||||
msgid "Unable to update list"
|
||||
msgstr "Liste konnte nicht aktualisiert werden"
|
||||
@@ -2264,7 +2232,7 @@ msgstr "Unbegrenzte Mitglieder"
|
||||
msgid "Unlimited workspaces"
|
||||
msgstr "Unbegrenzte Workspaces"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:175
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
|
||||
#: src/views/settings/components/UpdateDisplayNameForm.tsx:80
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:91
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:83
|
||||
@@ -2303,11 +2271,6 @@ msgstr "Upgrade auf Pro"
|
||||
msgid "Upgrade to Pro ($29/month)"
|
||||
msgstr "Upgrade auf Pro ($29/Monat)"
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:32
|
||||
#: src/views/card/components/AttachmentUpload.tsx:78
|
||||
msgid "Upload failed"
|
||||
msgstr "Hochladen fehlgeschlagen"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:38
|
||||
#: src/views/boards/components/TemplateBoards.tsx:55
|
||||
msgid "Urgent"
|
||||
@@ -2357,7 +2320,7 @@ msgstr "Verwalte deine Abrechnung und dein Abonnement."
|
||||
msgid "View docs"
|
||||
msgstr "Dokumentation ansehen"
|
||||
|
||||
#: src/views/public/board/index.tsx:129
|
||||
#: src/views/public/board/index.tsx:128
|
||||
msgid "View only"
|
||||
msgstr "Nur ansehen"
|
||||
|
||||
@@ -2365,11 +2328,11 @@ msgstr "Nur ansehen"
|
||||
msgid "View our roadmap."
|
||||
msgstr "Sieh dir unsere roadmap an."
|
||||
|
||||
#: src/views/public/board/index.tsx:159
|
||||
#: src/views/public/board/index.tsx:157
|
||||
msgid "View workspace"
|
||||
msgstr "Workspace anzeigen"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:92
|
||||
#: src/views/board/components/VisibilityButton.tsx:91
|
||||
msgid "Visibility"
|
||||
msgstr "Sichtbarkeit"
|
||||
|
||||
@@ -2406,10 +2369,10 @@ msgid "Why make an open source Trello?"
|
||||
msgstr "Warum ein open source Trello entwickeln?"
|
||||
|
||||
#: src/components/SettingsLayout.tsx:39
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/boards/index.tsx:22
|
||||
#: src/views/members/index.tsx:173
|
||||
#: src/views/public/board/index.tsx:101
|
||||
#: src/views/public/board/index.tsx:100
|
||||
#: src/views/public/boards/index.tsx:66
|
||||
msgid "Workspace"
|
||||
msgstr "Arbeitsbereich"
|
||||
@@ -2539,10 +2502,6 @@ msgstr "Deine Boards wurden importiert."
|
||||
msgid "Your display name has been updated."
|
||||
msgstr "Dein Anzeigename wurde aktualisiert."
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:26
|
||||
msgid "Your file has been uploaded successfully."
|
||||
msgstr "Ihre Datei wurde erfolgreich hochgeladen."
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:70
|
||||
msgid "Your password has been changed."
|
||||
msgstr "Ihr Passwort wurde geändert."
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -31,17 +31,17 @@ msgstr "{0}"
|
||||
#. placeholder {1}: board?.name ?? t`Board`
|
||||
#. placeholder {1}: workspace.name ?? t`Workspace`
|
||||
#: src/views/boards/index.tsx:22
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/card/index.tsx:216
|
||||
msgid "{0} | {1}"
|
||||
msgstr "{0} | {1}"
|
||||
|
||||
#. placeholder {0}: labelPublicIds.length
|
||||
#: src/views/board/components/NewCardForm.tsx:443
|
||||
#: src/views/board/components/NewCardForm.tsx:442
|
||||
msgid "{0} labels"
|
||||
msgstr "{0} labels"
|
||||
|
||||
#. placeholder {0}: isTemplate ? "Template" : "Board"
|
||||
#: src/views/board/index.tsx:389
|
||||
#: src/views/board/index.tsx:387
|
||||
msgid "{0} not found"
|
||||
msgstr "{0} not found"
|
||||
|
||||
@@ -91,8 +91,8 @@ msgstr "Account"
|
||||
msgid "Account deleted"
|
||||
msgstr "Account deleted"
|
||||
|
||||
#: src/views/card/index.tsx:308
|
||||
#: src/views/public/board/CardModal.tsx:157
|
||||
#: src/views/card/index.tsx:291
|
||||
#: src/views/public/board/CardModal.tsx:143
|
||||
msgid "Activity"
|
||||
msgstr "Activity"
|
||||
|
||||
@@ -121,7 +121,7 @@ msgstr "Add an item..."
|
||||
msgid "Add checklist"
|
||||
msgstr "Add checklist"
|
||||
|
||||
#: src/components/Editor.tsx:451
|
||||
#: src/components/Editor.tsx:442
|
||||
msgid "Add description... (type '/' to open commands or '@' to mention)"
|
||||
msgstr "Add description... (type '/' to open commands or '@' to mention)"
|
||||
|
||||
@@ -306,10 +306,6 @@ msgstr "assigned <0>{0}</0> to the card"
|
||||
msgid "Assignees"
|
||||
msgstr "Assignees"
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:25
|
||||
msgid "Attachment uploaded"
|
||||
msgstr "Attachment uploaded"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:47
|
||||
msgid "Awaiting Customer"
|
||||
msgstr "Awaiting Customer"
|
||||
@@ -348,9 +344,9 @@ msgstr "Billing portal"
|
||||
msgid "Blog Post"
|
||||
msgstr "Blog Post"
|
||||
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/public/board/index.tsx:101
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/card/index.tsx:216
|
||||
#: src/views/public/board/index.tsx:100
|
||||
msgid "Board"
|
||||
msgstr "Board"
|
||||
|
||||
@@ -376,7 +372,7 @@ msgstr "Board name cannot exceed 100 characters"
|
||||
msgid "Board name is required"
|
||||
msgstr "Board name is required"
|
||||
|
||||
#: src/views/public/board/index.tsx:153
|
||||
#: src/views/public/board/index.tsx:151
|
||||
msgid "Board not found"
|
||||
msgstr "Board not found"
|
||||
|
||||
@@ -384,19 +380,19 @@ msgstr "Board not found"
|
||||
msgid "Board sharing & invites"
|
||||
msgstr "Board sharing & invites"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:46
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:45
|
||||
msgid "Board URL can only contain letters, numbers, and hyphens"
|
||||
msgstr "Board URL can only contain letters, numbers, and hyphens"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:44
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:43
|
||||
msgid "Board URL cannot exceed 60 characters"
|
||||
msgstr "Board URL cannot exceed 60 characters"
|
||||
|
||||
#: src/views/public/board/index.tsx:68
|
||||
#: src/views/public/board/index.tsx:67
|
||||
msgid "Board URL copied to clipboard"
|
||||
msgstr "Board URL copied to clipboard"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:42
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:41
|
||||
msgid "Board URL must be at least 3 characters long"
|
||||
msgstr "Board URL must be at least 3 characters long"
|
||||
|
||||
@@ -405,7 +401,7 @@ msgstr "Board URL must be at least 3 characters long"
|
||||
msgid "Board visibility"
|
||||
msgstr "Board visibility"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:46
|
||||
#: src/views/board/components/VisibilityButton.tsx:45
|
||||
msgid "Board visibility updated"
|
||||
msgstr "Board visibility updated"
|
||||
|
||||
@@ -448,15 +444,15 @@ msgstr "Bug Report"
|
||||
msgid "Cancel"
|
||||
msgstr "Cancel"
|
||||
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/card/index.tsx:216
|
||||
msgid "Card"
|
||||
msgstr "Card"
|
||||
|
||||
#: src/views/card/index.tsx:264
|
||||
#: src/views/card/index.tsx:262
|
||||
msgid "Card not found"
|
||||
msgstr "Card not found"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:310
|
||||
#: src/views/board/components/NewCardForm.tsx:309
|
||||
msgid "Card title"
|
||||
msgstr "Card title"
|
||||
|
||||
@@ -493,7 +489,7 @@ msgstr "Checklist name"
|
||||
msgid "Checklists"
|
||||
msgstr "Checklists"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:180
|
||||
#: src/views/board/components/Filters.tsx:155
|
||||
msgid "Clear filters"
|
||||
msgstr "Clear filters"
|
||||
|
||||
@@ -588,7 +584,7 @@ msgstr "Contact us"
|
||||
msgid "Content Creation"
|
||||
msgstr "Content Creation"
|
||||
|
||||
#: src/components/AuthForm.tsx:434
|
||||
#: src/components/AuthForm.tsx:420
|
||||
msgid "Continue with "
|
||||
msgstr "Continue with "
|
||||
|
||||
@@ -611,8 +607,8 @@ msgid "Create {0}"
|
||||
msgstr "Create {0}"
|
||||
|
||||
#: src/components/LabelForm.tsx:213
|
||||
#: src/views/board/components/NewCardForm.tsx:469
|
||||
#: src/views/board/components/NewListForm.tsx:141
|
||||
#: src/views/board/components/NewCardForm.tsx:468
|
||||
#: src/views/board/components/NewListForm.tsx:140
|
||||
msgid "Create another"
|
||||
msgstr "Create another"
|
||||
|
||||
@@ -628,7 +624,7 @@ msgstr "Create API key"
|
||||
#~ msgid "Create board"
|
||||
#~ msgstr "Create board"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:479
|
||||
#: src/views/board/components/NewCardForm.tsx:478
|
||||
msgid "Create card"
|
||||
msgstr "Create card"
|
||||
|
||||
@@ -644,7 +640,7 @@ msgstr "Create invite link"
|
||||
msgid "Create label"
|
||||
msgstr "Create label"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:153
|
||||
#: src/views/board/components/NewListForm.tsx:152
|
||||
msgid "Create list"
|
||||
msgstr "Create list"
|
||||
|
||||
@@ -661,12 +657,12 @@ msgstr "Create new {0}"
|
||||
msgid "Create new key"
|
||||
msgstr "Create new key"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:405
|
||||
#: src/views/board/components/NewCardForm.tsx:404
|
||||
#: src/views/card/components/LabelSelector.tsx:97
|
||||
msgid "Create new label"
|
||||
msgstr "Create new label"
|
||||
|
||||
#: src/views/board/index.tsx:478
|
||||
#: src/views/board/index.tsx:475
|
||||
msgid "Create new list"
|
||||
msgstr "Create new list"
|
||||
|
||||
@@ -862,12 +858,8 @@ msgstr "Don't have an account? <0><1>Sign up</1></0>"
|
||||
msgid "Done"
|
||||
msgstr "Done"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:141
|
||||
msgid "Download failed"
|
||||
msgstr "Download failed"
|
||||
|
||||
#: src/views/board/components/BoardDropdown.tsx:41
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:116
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:115
|
||||
msgid "Edit board URL"
|
||||
msgstr "Edit board URL"
|
||||
|
||||
@@ -879,7 +871,7 @@ msgstr "Edit comment"
|
||||
msgid "Edit label"
|
||||
msgstr "Edit label"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:162
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:161
|
||||
msgid "Edit workspace URL"
|
||||
msgstr "Edit workspace URL"
|
||||
|
||||
@@ -887,7 +879,7 @@ msgstr "Edit workspace URL"
|
||||
msgid "Editing"
|
||||
msgstr "Editing"
|
||||
|
||||
#: src/components/AuthForm.tsx:435
|
||||
#: src/components/AuthForm.tsx:421
|
||||
msgid "email"
|
||||
msgstr "email"
|
||||
|
||||
@@ -907,11 +899,11 @@ msgstr "Enter your current password"
|
||||
msgid "Enter your current password and choose a new secure password."
|
||||
msgstr "Enter your current password and choose a new secure password."
|
||||
|
||||
#: src/components/AuthForm.tsx:398
|
||||
#: src/components/AuthForm.tsx:387
|
||||
msgid "Enter your email address"
|
||||
msgstr "Enter your email address"
|
||||
|
||||
#: src/components/AuthForm.tsx:384
|
||||
#: src/components/AuthForm.tsx:375
|
||||
msgid "Enter your name"
|
||||
msgstr "Enter your name"
|
||||
|
||||
@@ -919,7 +911,7 @@ msgstr "Enter your name"
|
||||
msgid "Enter your new password"
|
||||
msgstr "Enter your new password"
|
||||
|
||||
#: src/components/AuthForm.tsx:411
|
||||
#: src/components/AuthForm.tsx:400
|
||||
msgid "Enter your password"
|
||||
msgstr "Enter your password"
|
||||
|
||||
@@ -1028,11 +1020,6 @@ msgstr "Failed to create board"
|
||||
msgid "Failed to login with {0}. Please try again."
|
||||
msgstr "Failed to login with {0}. Please try again."
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:33
|
||||
#: src/views/card/components/AttachmentUpload.tsx:79
|
||||
msgid "Failed to upload attachment. Please try again."
|
||||
msgstr "Failed to upload attachment. Please try again."
|
||||
|
||||
#: src/views/home/components/Header.tsx:41
|
||||
msgid "FAQ"
|
||||
msgstr "FAQ"
|
||||
@@ -1076,7 +1063,7 @@ msgstr "Feedback"
|
||||
msgid "Feedback sent"
|
||||
msgstr "Feedback sent"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:174
|
||||
#: src/views/board/components/Filters.tsx:149
|
||||
msgid "Filter"
|
||||
msgstr "Filter"
|
||||
|
||||
@@ -1144,7 +1131,7 @@ msgstr "Get started by creating a new {0}"
|
||||
#~ msgid "Get started by creating a new board"
|
||||
#~ msgstr "Get started by creating a new board"
|
||||
|
||||
#: src/views/board/index.tsx:470
|
||||
#: src/views/board/index.tsx:467
|
||||
msgid "Get started by creating a new list"
|
||||
msgstr "Get started by creating a new list"
|
||||
|
||||
@@ -1366,9 +1353,9 @@ msgstr "Kanban reimagined"
|
||||
msgid "Keep in mind that this action is irreversible."
|
||||
msgstr "Keep in mind that this action is irreversible."
|
||||
|
||||
#: src/views/board/components/Filters.tsx:115
|
||||
#: src/views/board/components/NewCardForm.tsx:409
|
||||
#: src/views/card/index.tsx:119
|
||||
#: src/views/board/components/Filters.tsx:101
|
||||
#: src/views/board/components/NewCardForm.tsx:408
|
||||
#: src/views/card/index.tsx:117
|
||||
msgid "Labels"
|
||||
msgstr "Labels"
|
||||
|
||||
@@ -1418,22 +1405,18 @@ msgstr "License"
|
||||
msgid "Light"
|
||||
msgstr "Light"
|
||||
|
||||
#: src/views/public/board/index.tsx:66
|
||||
#: src/views/public/board/index.tsx:65
|
||||
msgid "Link copied"
|
||||
msgstr "Link copied"
|
||||
|
||||
#: src/views/card/index.tsx:111
|
||||
#: src/views/card/index.tsx:109
|
||||
msgid "List"
|
||||
msgstr "List"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:129
|
||||
#: src/views/board/components/NewListForm.tsx:128
|
||||
msgid "List name"
|
||||
msgstr "List name"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:123
|
||||
msgid "Lists"
|
||||
msgstr "Lists"
|
||||
|
||||
#: src/views/auth/login/index.tsx:33
|
||||
msgid "Login | kan.bn"
|
||||
msgstr "Login | kan.bn"
|
||||
@@ -1454,7 +1437,7 @@ msgstr "Loved by teams worldwide"
|
||||
msgid "Low Priority"
|
||||
msgstr "Low Priority"
|
||||
|
||||
#: src/components/AuthForm.tsx:435
|
||||
#: src/components/AuthForm.tsx:421
|
||||
msgid "magic link"
|
||||
msgstr "magic link"
|
||||
|
||||
@@ -1476,9 +1459,9 @@ msgid "Medium Priority"
|
||||
msgstr "Medium Priority"
|
||||
|
||||
#: src/components/SideNavigation.tsx:101
|
||||
#: src/views/board/components/Filters.tsx:107
|
||||
#: src/views/board/components/NewCardForm.tsx:367
|
||||
#: src/views/card/index.tsx:128
|
||||
#: src/views/board/components/Filters.tsx:93
|
||||
#: src/views/board/components/NewCardForm.tsx:366
|
||||
#: src/views/card/index.tsx:126
|
||||
#: src/views/members/index.tsx:178
|
||||
msgid "Members"
|
||||
msgstr "Members"
|
||||
@@ -1543,7 +1526,7 @@ msgstr "New API key"
|
||||
#~ msgid "New board"
|
||||
#~ msgstr "New board"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:293
|
||||
#: src/views/board/components/NewCardForm.tsx:292
|
||||
msgid "New card"
|
||||
msgstr "New card"
|
||||
|
||||
@@ -1559,8 +1542,8 @@ msgstr "New import"
|
||||
msgid "New label"
|
||||
msgstr "New label"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:113
|
||||
#: src/views/board/index.tsx:442
|
||||
#: src/views/board/components/NewListForm.tsx:112
|
||||
#: src/views/board/index.tsx:439
|
||||
msgid "New list"
|
||||
msgstr "New list"
|
||||
|
||||
@@ -1601,10 +1584,6 @@ msgstr "Next Steps"
|
||||
msgid "No {0}"
|
||||
msgstr "No {0}"
|
||||
|
||||
#: src/components/AuthForm.tsx:365
|
||||
msgid "No authentication methods are currently available"
|
||||
msgstr "No authentication methods are currently available"
|
||||
|
||||
#: src/views/boards/components/BoardsList.tsx:35
|
||||
#~ msgid "No boards"
|
||||
#~ msgstr "No boards"
|
||||
@@ -1617,11 +1596,7 @@ msgstr "No boards found"
|
||||
msgid "No credit card required"
|
||||
msgstr "No credit card required"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:142
|
||||
msgid "No download URL available for this attachment."
|
||||
msgstr "No download URL available for this attachment."
|
||||
|
||||
#: src/views/board/index.tsx:467
|
||||
#: src/views/board/index.tsx:464
|
||||
msgid "No lists"
|
||||
msgstr "No lists"
|
||||
|
||||
@@ -1653,7 +1628,7 @@ msgstr "Open source"
|
||||
msgid "Open Source Friends"
|
||||
msgstr "Open Source Friends"
|
||||
|
||||
#: src/components/AuthForm.tsx:374
|
||||
#: src/components/AuthForm.tsx:365
|
||||
msgid "or"
|
||||
msgstr "or"
|
||||
|
||||
@@ -1735,15 +1710,15 @@ msgstr "Platform"
|
||||
msgid "Please confirm your new password"
|
||||
msgstr "Please confirm your new password"
|
||||
|
||||
#: src/components/AuthForm.tsx:402
|
||||
#: src/components/AuthForm.tsx:391
|
||||
msgid "Please enter a valid email address"
|
||||
msgstr "Please enter a valid email address"
|
||||
|
||||
#: src/components/AuthForm.tsx:388
|
||||
#: src/components/AuthForm.tsx:379
|
||||
msgid "Please enter a valid name"
|
||||
msgstr "Please enter a valid name"
|
||||
|
||||
#: src/components/AuthForm.tsx:416
|
||||
#: src/components/AuthForm.tsx:404
|
||||
msgid "Please enter a valid password"
|
||||
msgstr "Please enter a valid password"
|
||||
|
||||
@@ -1754,16 +1729,15 @@ msgstr "Please select a file to upload."
|
||||
#: src/components/DeleteLabelConfirmation.tsx:26
|
||||
#: src/components/FeedbackModal.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:158
|
||||
#: src/views/board/components/NewCardForm.tsx:177
|
||||
#: src/views/board/components/NewListForm.tsx:79
|
||||
#: src/views/board/components/NewCardForm.tsx:176
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/NewTemplateForm.tsx:61
|
||||
#: src/views/board/components/NewTemplateForm.tsx:77
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:73
|
||||
#: src/views/board/components/VisibilityButton.tsx:54
|
||||
#: src/views/board/index.tsx:151
|
||||
#: src/views/board/index.tsx:207
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
#: src/views/board/components/VisibilityButton.tsx:53
|
||||
#: src/views/board/index.tsx:149
|
||||
#: src/views/board/index.tsx:205
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:205
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:73
|
||||
#: src/views/card/components/ChecklistItemRow.tsx:60
|
||||
#: src/views/card/components/ChecklistItemRow.tsx:88
|
||||
#: src/views/card/components/ChecklistNameInput.tsx:46
|
||||
@@ -1777,7 +1751,7 @@ msgstr "Please select a file to upload."
|
||||
#: src/views/card/components/NewChecklistForm.tsx:70
|
||||
#: src/views/card/components/NewChecklistItemForm.tsx:89
|
||||
#: src/views/card/components/NewCommentForm.tsx:31
|
||||
#: src/views/card/index.tsx:177
|
||||
#: src/views/card/index.tsx:175
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
#: src/views/members/components/InviteMemberForm.tsx:241
|
||||
@@ -1821,7 +1795,7 @@ msgstr "Priority email support"
|
||||
msgid "Privacy policy"
|
||||
msgstr "Privacy policy"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:74
|
||||
#: src/views/board/components/VisibilityButton.tsx:73
|
||||
msgid "Private"
|
||||
msgstr "Private"
|
||||
|
||||
@@ -1841,7 +1815,7 @@ msgstr "Profile image updated"
|
||||
msgid "Profile picture"
|
||||
msgstr "Profile picture"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:69
|
||||
#: src/views/board/components/VisibilityButton.tsx:68
|
||||
msgid "Public"
|
||||
msgstr "Public"
|
||||
|
||||
@@ -2063,7 +2037,7 @@ msgstr "Sign up disabled"
|
||||
msgid "Sign up is currently disabled. Please try again later."
|
||||
msgstr "Sign up is currently disabled. Please try again later."
|
||||
|
||||
#: src/components/AuthForm.tsx:434
|
||||
#: src/components/AuthForm.tsx:420
|
||||
msgid "Sign up with "
|
||||
msgstr "Sign up with "
|
||||
|
||||
@@ -2130,8 +2104,8 @@ msgstr "Team Plan"
|
||||
msgid "Teams"
|
||||
msgstr "Teams"
|
||||
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/board/index.tsx:398
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/board/index.tsx:396
|
||||
msgid "Template"
|
||||
msgstr "Template"
|
||||
|
||||
@@ -2181,7 +2155,7 @@ msgid "The open source <0/> alternative to Trello"
|
||||
msgstr "The open source <0/> alternative to Trello"
|
||||
|
||||
#. placeholder {0}: isPublic ? "public" : "private"
|
||||
#: src/views/board/components/VisibilityButton.tsx:47
|
||||
#: src/views/board/components/VisibilityButton.tsx:46
|
||||
msgid "The visibility of your board has been set to {0}."
|
||||
msgstr "The visibility of your board has been set to {0}."
|
||||
|
||||
@@ -2205,11 +2179,11 @@ msgstr "This action can't be undone."
|
||||
msgid "This API key will only be shown once. Please save it in a secure location."
|
||||
msgstr "This API key will only be shown once. Please save it in a secure location."
|
||||
|
||||
#: src/views/public/board/index.tsx:156
|
||||
#: src/views/public/board/index.tsx:154
|
||||
msgid "This board is private or does not exist"
|
||||
msgstr "This board is private or does not exist"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:136
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:135
|
||||
msgid "This board URL has already been taken"
|
||||
msgstr "This board URL has already been taken"
|
||||
|
||||
@@ -2287,7 +2261,7 @@ msgstr "Unable to add checklist item"
|
||||
msgid "Unable to add comment"
|
||||
msgstr "Unable to add comment"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:174
|
||||
#: src/views/board/components/NewCardForm.tsx:173
|
||||
msgid "Unable to create card"
|
||||
msgstr "Unable to create card"
|
||||
|
||||
@@ -2295,7 +2269,7 @@ msgstr "Unable to create card"
|
||||
msgid "Unable to create checklist"
|
||||
msgstr "Unable to create checklist"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/NewListForm.tsx:77
|
||||
msgid "Unable to create list"
|
||||
msgstr "Unable to create list"
|
||||
|
||||
@@ -2308,10 +2282,6 @@ msgstr "Unable to create template"
|
||||
msgid "Unable to create workspace"
|
||||
msgstr "Unable to create workspace"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:72
|
||||
msgid "Unable to delete attachment"
|
||||
msgstr "Unable to delete attachment"
|
||||
|
||||
#: src/views/card/components/DeleteCardConfirmation.tsx:51
|
||||
msgid "Unable to delete card"
|
||||
msgstr "Unable to delete card"
|
||||
@@ -2336,16 +2306,16 @@ msgstr "Unable to remove member"
|
||||
msgid "Unable to send feedback"
|
||||
msgstr "Unable to send feedback"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:71
|
||||
msgid "Unable to update board URL"
|
||||
msgstr "Unable to update board URL"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:53
|
||||
#: src/views/board/components/VisibilityButton.tsx:52
|
||||
msgid "Unable to update board visibility"
|
||||
msgstr "Unable to update board visibility"
|
||||
|
||||
#: src/views/board/index.tsx:206
|
||||
#: src/views/card/index.tsx:176
|
||||
#: src/views/board/index.tsx:204
|
||||
#: src/views/card/index.tsx:174
|
||||
msgid "Unable to update card"
|
||||
msgstr "Unable to update card"
|
||||
|
||||
@@ -2365,7 +2335,7 @@ msgstr "Unable to update comment"
|
||||
msgid "Unable to update labels"
|
||||
msgstr "Unable to update labels"
|
||||
|
||||
#: src/views/board/index.tsx:150
|
||||
#: src/views/board/index.tsx:148
|
||||
#: src/views/card/components/ListSelector.tsx:51
|
||||
msgid "Unable to update list"
|
||||
msgstr "Unable to update list"
|
||||
@@ -2425,7 +2395,7 @@ msgstr "Unlimited members"
|
||||
msgid "Unlimited workspaces"
|
||||
msgstr "Unlimited workspaces"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:175
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
|
||||
#: src/views/settings/components/UpdateDisplayNameForm.tsx:80
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:91
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:83
|
||||
@@ -2476,11 +2446,6 @@ msgstr "Upgrade to Pro ($29/month)"
|
||||
#~ msgid "Upgrade to Team Plan"
|
||||
#~ msgstr "Upgrade to Team Plan"
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:32
|
||||
#: src/views/card/components/AttachmentUpload.tsx:78
|
||||
msgid "Upload failed"
|
||||
msgstr "Upload failed"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:38
|
||||
#: src/views/boards/components/TemplateBoards.tsx:55
|
||||
msgid "Urgent"
|
||||
@@ -2530,7 +2495,7 @@ msgstr "View and manage your billing and subscription."
|
||||
msgid "View docs"
|
||||
msgstr "View docs"
|
||||
|
||||
#: src/views/public/board/index.tsx:129
|
||||
#: src/views/public/board/index.tsx:128
|
||||
msgid "View only"
|
||||
msgstr "View only"
|
||||
|
||||
@@ -2538,11 +2503,11 @@ msgstr "View only"
|
||||
msgid "View our roadmap."
|
||||
msgstr "View our roadmap."
|
||||
|
||||
#: src/views/public/board/index.tsx:159
|
||||
#: src/views/public/board/index.tsx:157
|
||||
msgid "View workspace"
|
||||
msgstr "View workspace"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:92
|
||||
#: src/views/board/components/VisibilityButton.tsx:91
|
||||
msgid "Visibility"
|
||||
msgstr "Visibility"
|
||||
|
||||
@@ -2587,10 +2552,10 @@ msgid "Why make an open source Trello?"
|
||||
msgstr "Why make an open source Trello?"
|
||||
|
||||
#: src/components/SettingsLayout.tsx:39
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/boards/index.tsx:22
|
||||
#: src/views/members/index.tsx:173
|
||||
#: src/views/public/board/index.tsx:101
|
||||
#: src/views/public/board/index.tsx:100
|
||||
#: src/views/public/boards/index.tsx:66
|
||||
msgid "Workspace"
|
||||
msgstr "Workspace"
|
||||
@@ -2724,10 +2689,6 @@ msgstr "Your boards have been imported."
|
||||
msgid "Your display name has been updated."
|
||||
msgstr "Your display name has been updated."
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:26
|
||||
msgid "Your file has been uploaded successfully."
|
||||
msgstr "Your file has been uploaded successfully."
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:70
|
||||
msgid "Your password has been changed."
|
||||
msgstr "Your password has been changed."
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -31,17 +31,17 @@ msgstr "{0}"
|
||||
#. placeholder {1}: board?.name ?? t`Board`
|
||||
#. placeholder {1}: workspace.name ?? t`Workspace`
|
||||
#: src/views/boards/index.tsx:22
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/card/index.tsx:216
|
||||
msgid "{0} | {1}"
|
||||
msgstr "{0} | {1}"
|
||||
|
||||
#. placeholder {0}: labelPublicIds.length
|
||||
#: src/views/board/components/NewCardForm.tsx:443
|
||||
#: src/views/board/components/NewCardForm.tsx:442
|
||||
msgid "{0} labels"
|
||||
msgstr "{0} etiquetas"
|
||||
|
||||
#. placeholder {0}: isTemplate ? "Template" : "Board"
|
||||
#: src/views/board/index.tsx:389
|
||||
#: src/views/board/index.tsx:387
|
||||
msgid "{0} not found"
|
||||
msgstr "{0} no encontrado"
|
||||
|
||||
@@ -79,8 +79,8 @@ msgstr "Cuenta"
|
||||
msgid "Account deleted"
|
||||
msgstr "Cuenta eliminada"
|
||||
|
||||
#: src/views/card/index.tsx:308
|
||||
#: src/views/public/board/CardModal.tsx:157
|
||||
#: src/views/card/index.tsx:291
|
||||
#: src/views/public/board/CardModal.tsx:143
|
||||
msgid "Activity"
|
||||
msgstr "Actividad"
|
||||
|
||||
@@ -109,7 +109,7 @@ msgstr "Añadir un elemento..."
|
||||
msgid "Add checklist"
|
||||
msgstr "Añadir lista de verificación"
|
||||
|
||||
#: src/components/Editor.tsx:451
|
||||
#: src/components/Editor.tsx:442
|
||||
msgid "Add description... (type '/' to open commands or '@' to mention)"
|
||||
msgstr "Añadir descripción... (escribe '/' para abrir comandos o '@' para mencionar)"
|
||||
|
||||
@@ -270,10 +270,6 @@ msgstr "asignó <0>{0}</0> a la tarjeta"
|
||||
msgid "Assignees"
|
||||
msgstr "Asignados"
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:25
|
||||
msgid "Attachment uploaded"
|
||||
msgstr "Archivo adjunto subido"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:47
|
||||
msgid "Awaiting Customer"
|
||||
msgstr "Esperando al cliente"
|
||||
@@ -308,9 +304,9 @@ msgstr "Portal de facturación"
|
||||
msgid "Blog Post"
|
||||
msgstr "Entrada de blog"
|
||||
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/public/board/index.tsx:101
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/card/index.tsx:216
|
||||
#: src/views/public/board/index.tsx:100
|
||||
msgid "Board"
|
||||
msgstr "Tablero"
|
||||
|
||||
@@ -327,7 +323,7 @@ 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/public/board/index.tsx:153
|
||||
#: src/views/public/board/index.tsx:151
|
||||
msgid "Board not found"
|
||||
msgstr "Tablero no encontrado"
|
||||
|
||||
@@ -335,19 +331,19 @@ msgstr "Tablero no encontrado"
|
||||
msgid "Board sharing & invites"
|
||||
msgstr "Compartir tablero e invitaciones"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:46
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:45
|
||||
msgid "Board URL can only contain letters, numbers, and hyphens"
|
||||
msgstr "La URL del tablero solo puede contener letras, números y guiones"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:44
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:43
|
||||
msgid "Board URL cannot exceed 60 characters"
|
||||
msgstr "La URL del tablero no puede exceder los 60 caracteres"
|
||||
|
||||
#: src/views/public/board/index.tsx:68
|
||||
#: src/views/public/board/index.tsx:67
|
||||
msgid "Board URL copied to clipboard"
|
||||
msgstr "URL del tablero copiada al portapapeles"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:42
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:41
|
||||
msgid "Board URL must be at least 3 characters long"
|
||||
msgstr "La URL del tablero debe tener al menos 3 caracteres"
|
||||
|
||||
@@ -356,7 +352,7 @@ msgstr "La URL del tablero debe tener al menos 3 caracteres"
|
||||
msgid "Board visibility"
|
||||
msgstr "Visibilidad del tablero"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:46
|
||||
#: src/views/board/components/VisibilityButton.tsx:45
|
||||
msgid "Board visibility updated"
|
||||
msgstr "Visibilidad del tablero actualizada"
|
||||
|
||||
@@ -391,15 +387,15 @@ msgstr "Informe de error"
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/card/index.tsx:216
|
||||
msgid "Card"
|
||||
msgstr "Tarjeta"
|
||||
|
||||
#: src/views/card/index.tsx:264
|
||||
#: src/views/card/index.tsx:262
|
||||
msgid "Card not found"
|
||||
msgstr "Tarjeta no encontrada"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:310
|
||||
#: src/views/board/components/NewCardForm.tsx:309
|
||||
msgid "Card title"
|
||||
msgstr "Título de la tarjeta"
|
||||
|
||||
@@ -432,7 +428,7 @@ msgstr "Nombre de la lista de verificación"
|
||||
msgid "Checklists"
|
||||
msgstr "Listas de verificación"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:180
|
||||
#: src/views/board/components/Filters.tsx:155
|
||||
msgid "Clear filters"
|
||||
msgstr "Borrar filtros"
|
||||
|
||||
@@ -523,7 +519,7 @@ msgstr "Contáctanos"
|
||||
msgid "Content Creation"
|
||||
msgstr "Creación de contenido"
|
||||
|
||||
#: src/components/AuthForm.tsx:434
|
||||
#: src/components/AuthForm.tsx:420
|
||||
msgid "Continue with "
|
||||
msgstr "Continuar con "
|
||||
|
||||
@@ -546,8 +542,8 @@ msgid "Create {0}"
|
||||
msgstr "Crear {0}"
|
||||
|
||||
#: src/components/LabelForm.tsx:213
|
||||
#: src/views/board/components/NewCardForm.tsx:469
|
||||
#: src/views/board/components/NewListForm.tsx:141
|
||||
#: src/views/board/components/NewCardForm.tsx:468
|
||||
#: src/views/board/components/NewListForm.tsx:140
|
||||
msgid "Create another"
|
||||
msgstr "Crear otro"
|
||||
|
||||
@@ -555,7 +551,7 @@ msgstr "Crear otro"
|
||||
msgid "Create API key"
|
||||
msgstr "Crear clave API"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:479
|
||||
#: src/views/board/components/NewCardForm.tsx:478
|
||||
msgid "Create card"
|
||||
msgstr "Crear tarjeta"
|
||||
|
||||
@@ -571,7 +567,7 @@ msgstr "Crear enlace de invitación"
|
||||
msgid "Create label"
|
||||
msgstr "Crear etiqueta"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:153
|
||||
#: src/views/board/components/NewListForm.tsx:152
|
||||
msgid "Create list"
|
||||
msgstr "Crear lista"
|
||||
|
||||
@@ -584,12 +580,12 @@ msgstr "Crear nuevo {0}"
|
||||
msgid "Create new key"
|
||||
msgstr "Crear nueva clave"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:405
|
||||
#: src/views/board/components/NewCardForm.tsx:404
|
||||
#: src/views/card/components/LabelSelector.tsx:97
|
||||
msgid "Create new label"
|
||||
msgstr "Crear nueva etiqueta"
|
||||
|
||||
#: src/views/board/index.tsx:478
|
||||
#: src/views/board/index.tsx:475
|
||||
msgid "Create new list"
|
||||
msgstr "Crear nueva lista"
|
||||
|
||||
@@ -773,12 +769,8 @@ msgstr "¿No tienes una cuenta? <0><1>Regístrate</1></0>"
|
||||
msgid "Done"
|
||||
msgstr "Terminado"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:141
|
||||
msgid "Download failed"
|
||||
msgstr "Error en la descarga"
|
||||
|
||||
#: src/views/board/components/BoardDropdown.tsx:41
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:116
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:115
|
||||
msgid "Edit board URL"
|
||||
msgstr "Editar URL del tablero"
|
||||
|
||||
@@ -790,7 +782,7 @@ msgstr "Editar comentario"
|
||||
msgid "Edit label"
|
||||
msgstr "Editar etiqueta"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:162
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:161
|
||||
msgid "Edit workspace URL"
|
||||
msgstr "Editar URL del espacio de trabajo"
|
||||
|
||||
@@ -798,7 +790,7 @@ msgstr "Editar URL del espacio de trabajo"
|
||||
msgid "Editing"
|
||||
msgstr "Editando"
|
||||
|
||||
#: src/components/AuthForm.tsx:435
|
||||
#: src/components/AuthForm.tsx:421
|
||||
msgid "email"
|
||||
msgstr "correo electrónico"
|
||||
|
||||
@@ -818,11 +810,11 @@ msgstr "Introduce tu contraseña actual"
|
||||
msgid "Enter your current password and choose a new secure password."
|
||||
msgstr "Introduce tu contraseña actual y elige una nueva contraseña segura."
|
||||
|
||||
#: src/components/AuthForm.tsx:398
|
||||
#: src/components/AuthForm.tsx:387
|
||||
msgid "Enter your email address"
|
||||
msgstr "Introduce tu dirección de correo electrónico"
|
||||
|
||||
#: src/components/AuthForm.tsx:384
|
||||
#: src/components/AuthForm.tsx:375
|
||||
msgid "Enter your name"
|
||||
msgstr "Introduce tu nombre"
|
||||
|
||||
@@ -830,7 +822,7 @@ msgstr "Introduce tu nombre"
|
||||
msgid "Enter your new password"
|
||||
msgstr "Introduce tu nueva contraseña"
|
||||
|
||||
#: src/components/AuthForm.tsx:411
|
||||
#: src/components/AuthForm.tsx:400
|
||||
msgid "Enter your password"
|
||||
msgstr "Introduce tu contraseña"
|
||||
|
||||
@@ -939,11 +931,6 @@ msgstr "Error al crear el tablero"
|
||||
msgid "Failed to login with {0}. Please try again."
|
||||
msgstr "Error al iniciar sesión con {0}. Por favor, inténtalo de nuevo."
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:33
|
||||
#: src/views/card/components/AttachmentUpload.tsx:79
|
||||
msgid "Failed to upload attachment. Please try again."
|
||||
msgstr "Error al subir el archivo adjunto. Por favor, inténtalo de nuevo."
|
||||
|
||||
#: src/views/home/components/Header.tsx:41
|
||||
msgid "FAQ"
|
||||
msgstr "FAQ"
|
||||
@@ -987,7 +974,7 @@ msgstr "Comentarios"
|
||||
msgid "Feedback sent"
|
||||
msgstr "Comentarios enviados"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:174
|
||||
#: src/views/board/components/Filters.tsx:149
|
||||
msgid "Filter"
|
||||
msgstr "Filtrar"
|
||||
|
||||
@@ -1000,8 +987,6 @@ msgid "For long-term sustainability, we recognise all good open source projects
|
||||
msgstr "Para la sostenibilidad a largo plazo, reconocemos que todos los buenos proyectos de código abierto necesitan una fuente de ingresos. La nuestra proviene de la oferta de nube de pago para espacios de trabajo con múltiples usuarios y para slugs de espacio de trabajo personalizados. No hay obligación de usarla, y puedes alojar el software en tu propia infraestructura sin costo alguno."
|
||||
|
||||
#: src/views/pricing/components/Pricing.tsx:32
|
||||
#: src/views/pricing/components/Pricing.tsx:32
|
||||
#: src/views/pricing/components/PricingTiers.tsx:30
|
||||
#: src/views/pricing/components/PricingTiers.tsx:30
|
||||
msgid "Free"
|
||||
msgstr "Gratis"
|
||||
@@ -1043,7 +1028,7 @@ msgstr "Comenzar"
|
||||
msgid "Get started by creating a new {0}"
|
||||
msgstr "Comienza creando un nuevo {0}"
|
||||
|
||||
#: src/views/board/index.tsx:470
|
||||
#: src/views/board/index.tsx:467
|
||||
msgid "Get started by creating a new list"
|
||||
msgstr "Comienza creando una nueva lista"
|
||||
|
||||
@@ -1257,9 +1242,9 @@ msgstr "Kanban reinventado"
|
||||
msgid "Keep in mind that this action is irreversible."
|
||||
msgstr "Ten en cuenta que esta acción es irreversible."
|
||||
|
||||
#: src/views/board/components/Filters.tsx:115
|
||||
#: src/views/board/components/NewCardForm.tsx:409
|
||||
#: src/views/card/index.tsx:119
|
||||
#: src/views/board/components/Filters.tsx:101
|
||||
#: src/views/board/components/NewCardForm.tsx:408
|
||||
#: src/views/card/index.tsx:117
|
||||
msgid "Labels"
|
||||
msgstr "Etiquetas"
|
||||
|
||||
@@ -1309,22 +1294,18 @@ msgstr "Licencia"
|
||||
msgid "Light"
|
||||
msgstr "Claro"
|
||||
|
||||
#: src/views/public/board/index.tsx:66
|
||||
#: src/views/public/board/index.tsx:65
|
||||
msgid "Link copied"
|
||||
msgstr "Enlace copiado"
|
||||
|
||||
#: src/views/card/index.tsx:111
|
||||
#: src/views/card/index.tsx:109
|
||||
msgid "List"
|
||||
msgstr "Lista"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:129
|
||||
#: src/views/board/components/NewListForm.tsx:128
|
||||
msgid "List name"
|
||||
msgstr "Nombre de la lista"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:123
|
||||
msgid "Lists"
|
||||
msgstr "Listas"
|
||||
|
||||
#: src/views/auth/login/index.tsx:33
|
||||
msgid "Login | kan.bn"
|
||||
msgstr "Iniciar sesión | kan.bn"
|
||||
@@ -1345,7 +1326,7 @@ msgstr "Amado por equipos en todo el mundo"
|
||||
msgid "Low Priority"
|
||||
msgstr "Prioridad baja"
|
||||
|
||||
#: src/components/AuthForm.tsx:435
|
||||
#: src/components/AuthForm.tsx:421
|
||||
msgid "magic link"
|
||||
msgstr "enlace mágico"
|
||||
|
||||
@@ -1367,9 +1348,9 @@ msgid "Medium Priority"
|
||||
msgstr "Prioridad media"
|
||||
|
||||
#: src/components/SideNavigation.tsx:101
|
||||
#: src/views/board/components/Filters.tsx:107
|
||||
#: src/views/board/components/NewCardForm.tsx:367
|
||||
#: src/views/card/index.tsx:128
|
||||
#: src/views/board/components/Filters.tsx:93
|
||||
#: src/views/board/components/NewCardForm.tsx:366
|
||||
#: src/views/card/index.tsx:126
|
||||
#: src/views/members/index.tsx:178
|
||||
msgid "Members"
|
||||
msgstr "Miembros"
|
||||
@@ -1422,7 +1403,7 @@ msgstr "Nuevo {0}"
|
||||
msgid "New API key"
|
||||
msgstr "Nueva clave API"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:293
|
||||
#: src/views/board/components/NewCardForm.tsx:292
|
||||
msgid "New card"
|
||||
msgstr "Nueva tarjeta"
|
||||
|
||||
@@ -1438,8 +1419,8 @@ msgstr "Nueva importación"
|
||||
msgid "New label"
|
||||
msgstr "Nueva etiqueta"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:113
|
||||
#: src/views/board/index.tsx:442
|
||||
#: src/views/board/components/NewListForm.tsx:112
|
||||
#: src/views/board/index.tsx:439
|
||||
msgid "New list"
|
||||
msgstr "Nueva lista"
|
||||
|
||||
@@ -1476,10 +1457,6 @@ msgstr "Próximos pasos"
|
||||
msgid "No {0}"
|
||||
msgstr "Sin {0}"
|
||||
|
||||
#: src/components/AuthForm.tsx:365
|
||||
msgid "No authentication methods are currently available"
|
||||
msgstr "No hay métodos de autenticación disponibles actualmente"
|
||||
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:242
|
||||
msgid "No boards found"
|
||||
msgstr "No se encontraron tableros"
|
||||
@@ -1488,11 +1465,7 @@ msgstr "No se encontraron tableros"
|
||||
msgid "No credit card required"
|
||||
msgstr "No se requiere tarjeta de crédito"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:142
|
||||
msgid "No download URL available for this attachment."
|
||||
msgstr "No hay URL de descarga disponible para este archivo adjunto."
|
||||
|
||||
#: src/views/board/index.tsx:467
|
||||
#: src/views/board/index.tsx:464
|
||||
msgid "No lists"
|
||||
msgstr "Sin listas"
|
||||
|
||||
@@ -1524,7 +1497,7 @@ msgstr "Código abierto"
|
||||
msgid "Open Source Friends"
|
||||
msgstr "Amigos de código abierto"
|
||||
|
||||
#: src/components/AuthForm.tsx:374
|
||||
#: src/components/AuthForm.tsx:365
|
||||
msgid "or"
|
||||
msgstr "o"
|
||||
|
||||
@@ -1606,15 +1579,15 @@ msgstr "Plataforma"
|
||||
msgid "Please confirm your new password"
|
||||
msgstr "Por favor, confirma tu nueva contraseña"
|
||||
|
||||
#: src/components/AuthForm.tsx:402
|
||||
#: src/components/AuthForm.tsx:391
|
||||
msgid "Please enter a valid email address"
|
||||
msgstr "Por favor, introduce una dirección de correo electrónico válida"
|
||||
|
||||
#: src/components/AuthForm.tsx:388
|
||||
#: src/components/AuthForm.tsx:379
|
||||
msgid "Please enter a valid name"
|
||||
msgstr "Por favor, introduce un nombre válido"
|
||||
|
||||
#: src/components/AuthForm.tsx:416
|
||||
#: src/components/AuthForm.tsx:404
|
||||
msgid "Please enter a valid password"
|
||||
msgstr "Por favor, introduce una contraseña válida"
|
||||
|
||||
@@ -1625,16 +1598,15 @@ msgstr "Por favor selecciona un archivo para subir."
|
||||
#: src/components/DeleteLabelConfirmation.tsx:26
|
||||
#: src/components/FeedbackModal.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:158
|
||||
#: src/views/board/components/NewCardForm.tsx:177
|
||||
#: src/views/board/components/NewListForm.tsx:79
|
||||
#: src/views/board/components/NewCardForm.tsx:176
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/NewTemplateForm.tsx:61
|
||||
#: src/views/board/components/NewTemplateForm.tsx:77
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:73
|
||||
#: src/views/board/components/VisibilityButton.tsx:54
|
||||
#: src/views/board/index.tsx:151
|
||||
#: src/views/board/index.tsx:207
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
#: src/views/board/components/VisibilityButton.tsx:53
|
||||
#: src/views/board/index.tsx:149
|
||||
#: src/views/board/index.tsx:205
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:205
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:73
|
||||
#: src/views/card/components/ChecklistItemRow.tsx:60
|
||||
#: src/views/card/components/ChecklistItemRow.tsx:88
|
||||
#: src/views/card/components/ChecklistNameInput.tsx:46
|
||||
@@ -1648,7 +1620,7 @@ msgstr "Por favor selecciona un archivo para subir."
|
||||
#: src/views/card/components/NewChecklistForm.tsx:70
|
||||
#: src/views/card/components/NewChecklistItemForm.tsx:89
|
||||
#: src/views/card/components/NewCommentForm.tsx:31
|
||||
#: src/views/card/index.tsx:177
|
||||
#: src/views/card/index.tsx:175
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
#: src/views/members/components/InviteMemberForm.tsx:241
|
||||
@@ -1692,7 +1664,7 @@ msgstr "Soporte prioritario por email"
|
||||
msgid "Privacy policy"
|
||||
msgstr "Política de privacidad"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:74
|
||||
#: src/views/board/components/VisibilityButton.tsx:73
|
||||
msgid "Private"
|
||||
msgstr "Privado"
|
||||
|
||||
@@ -1712,7 +1684,7 @@ msgstr "Imagen de perfil actualizada"
|
||||
msgid "Profile picture"
|
||||
msgstr "Foto de perfil"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:69
|
||||
#: src/views/board/components/VisibilityButton.tsx:68
|
||||
msgid "Public"
|
||||
msgstr "Público"
|
||||
|
||||
@@ -1914,7 +1886,7 @@ msgstr "Registro deshabilitado"
|
||||
msgid "Sign up is currently disabled. Please try again later."
|
||||
msgstr "El registro está actualmente deshabilitado. Por favor, inténtalo de nuevo más tarde."
|
||||
|
||||
#: src/components/AuthForm.tsx:434
|
||||
#: src/components/AuthForm.tsx:420
|
||||
msgid "Sign up with "
|
||||
msgstr "Registrarse con "
|
||||
|
||||
@@ -1981,8 +1953,8 @@ msgstr "Plan de Equipo"
|
||||
msgid "Teams"
|
||||
msgstr "Equipos"
|
||||
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/board/index.tsx:398
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/board/index.tsx:396
|
||||
msgid "Template"
|
||||
msgstr "Plantilla"
|
||||
|
||||
@@ -2032,7 +2004,7 @@ msgid "The open source <0/> alternative to Trello"
|
||||
msgstr "La alternativa de código abierto <0/> a Trello"
|
||||
|
||||
#. placeholder {0}: isPublic ? "public" : "private"
|
||||
#: src/views/board/components/VisibilityButton.tsx:47
|
||||
#: src/views/board/components/VisibilityButton.tsx:46
|
||||
msgid "The visibility of your board has been set to {0}."
|
||||
msgstr "La visibilidad de tu tablero ha sido establecida a {0}."
|
||||
|
||||
@@ -2056,11 +2028,11 @@ msgstr "Esta acción no se puede deshacer."
|
||||
msgid "This API key will only be shown once. Please save it in a secure location."
|
||||
msgstr "Esta clave API solo se mostrará una vez. Por favor, guárdala en un lugar seguro."
|
||||
|
||||
#: src/views/public/board/index.tsx:156
|
||||
#: src/views/public/board/index.tsx:154
|
||||
msgid "This board is private or does not exist"
|
||||
msgstr "Este tablero es privado o no existe"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:136
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:135
|
||||
msgid "This board URL has already been taken"
|
||||
msgstr "Esta URL de tablero ya ha sido utilizada"
|
||||
|
||||
@@ -2130,7 +2102,7 @@ msgstr "No se puede añadir el elemento a la lista de verificación"
|
||||
msgid "Unable to add comment"
|
||||
msgstr "No se puede añadir el comentario"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:174
|
||||
#: src/views/board/components/NewCardForm.tsx:173
|
||||
msgid "Unable to create card"
|
||||
msgstr "No se puede crear la tarjeta"
|
||||
|
||||
@@ -2138,7 +2110,7 @@ msgstr "No se puede crear la tarjeta"
|
||||
msgid "Unable to create checklist"
|
||||
msgstr "No se puede crear la lista de verificación"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/NewListForm.tsx:77
|
||||
msgid "Unable to create list"
|
||||
msgstr "No se puede crear la lista"
|
||||
|
||||
@@ -2151,10 +2123,6 @@ msgstr "No se puede crear la plantilla"
|
||||
msgid "Unable to create workspace"
|
||||
msgstr "No se puede crear el espacio de trabajo"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:72
|
||||
msgid "Unable to delete attachment"
|
||||
msgstr "No se puede eliminar el archivo adjunto"
|
||||
|
||||
#: src/views/card/components/DeleteCardConfirmation.tsx:51
|
||||
msgid "Unable to delete card"
|
||||
msgstr "No se puede eliminar la tarjeta"
|
||||
@@ -2179,16 +2147,16 @@ msgstr "No se puede eliminar al miembro"
|
||||
msgid "Unable to send feedback"
|
||||
msgstr "No se pudieron enviar los comentarios"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:71
|
||||
msgid "Unable to update board URL"
|
||||
msgstr "No se puede actualizar la URL del tablero"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:53
|
||||
#: src/views/board/components/VisibilityButton.tsx:52
|
||||
msgid "Unable to update board visibility"
|
||||
msgstr "No se puede actualizar la visibilidad del tablero"
|
||||
|
||||
#: src/views/board/index.tsx:206
|
||||
#: src/views/card/index.tsx:176
|
||||
#: src/views/board/index.tsx:204
|
||||
#: src/views/card/index.tsx:174
|
||||
msgid "Unable to update card"
|
||||
msgstr "No se puede actualizar la tarjeta"
|
||||
|
||||
@@ -2208,7 +2176,7 @@ msgstr "No se puede actualizar el comentario"
|
||||
msgid "Unable to update labels"
|
||||
msgstr "No se pueden actualizar las etiquetas"
|
||||
|
||||
#: src/views/board/index.tsx:150
|
||||
#: src/views/board/index.tsx:148
|
||||
#: src/views/card/components/ListSelector.tsx:51
|
||||
msgid "Unable to update list"
|
||||
msgstr "No se puede actualizar la lista"
|
||||
@@ -2264,7 +2232,7 @@ msgstr "Miembros ilimitados"
|
||||
msgid "Unlimited workspaces"
|
||||
msgstr "Espacios de trabajo ilimitados"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:175
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
|
||||
#: src/views/settings/components/UpdateDisplayNameForm.tsx:80
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:91
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:83
|
||||
@@ -2303,11 +2271,6 @@ msgstr "Actualizar a Pro"
|
||||
msgid "Upgrade to Pro ($29/month)"
|
||||
msgstr "Actualizar a Pro ($29/mes)"
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:32
|
||||
#: src/views/card/components/AttachmentUpload.tsx:78
|
||||
msgid "Upload failed"
|
||||
msgstr "Error al subir"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:38
|
||||
#: src/views/boards/components/TemplateBoards.tsx:55
|
||||
msgid "Urgent"
|
||||
@@ -2357,7 +2320,7 @@ msgstr "Ver y gestionar tu facturación y suscripción."
|
||||
msgid "View docs"
|
||||
msgstr "Ver documentación"
|
||||
|
||||
#: src/views/public/board/index.tsx:129
|
||||
#: src/views/public/board/index.tsx:128
|
||||
msgid "View only"
|
||||
msgstr "Solo visualización"
|
||||
|
||||
@@ -2365,11 +2328,11 @@ msgstr "Solo visualización"
|
||||
msgid "View our roadmap."
|
||||
msgstr "Ver nuestra hoja de ruta."
|
||||
|
||||
#: src/views/public/board/index.tsx:159
|
||||
#: src/views/public/board/index.tsx:157
|
||||
msgid "View workspace"
|
||||
msgstr "Ver espacio de trabajo"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:92
|
||||
#: src/views/board/components/VisibilityButton.tsx:91
|
||||
msgid "Visibility"
|
||||
msgstr "Visibilidad"
|
||||
|
||||
@@ -2406,10 +2369,10 @@ msgid "Why make an open source Trello?"
|
||||
msgstr "¿Por qué crear un Trello de código abierto?"
|
||||
|
||||
#: src/components/SettingsLayout.tsx:39
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/boards/index.tsx:22
|
||||
#: src/views/members/index.tsx:173
|
||||
#: src/views/public/board/index.tsx:101
|
||||
#: src/views/public/board/index.tsx:100
|
||||
#: src/views/public/boards/index.tsx:66
|
||||
msgid "Workspace"
|
||||
msgstr "Espacio de trabajo"
|
||||
@@ -2539,10 +2502,6 @@ msgstr "Tus tableros han sido importados."
|
||||
msgid "Your display name has been updated."
|
||||
msgstr "Tu nombre de visualización ha sido actualizado."
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:26
|
||||
msgid "Your file has been uploaded successfully."
|
||||
msgstr "Tu archivo se ha subido correctamente."
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:70
|
||||
msgid "Your password has been changed."
|
||||
msgstr "Tu contraseña ha sido cambiada."
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -31,17 +31,17 @@ msgstr "{0}"
|
||||
#. placeholder {1}: board?.name ?? t`Board`
|
||||
#. placeholder {1}: workspace.name ?? t`Workspace`
|
||||
#: src/views/boards/index.tsx:22
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/card/index.tsx:216
|
||||
msgid "{0} | {1}"
|
||||
msgstr "{0} | {1}"
|
||||
|
||||
#. placeholder {0}: labelPublicIds.length
|
||||
#: src/views/board/components/NewCardForm.tsx:443
|
||||
#: src/views/board/components/NewCardForm.tsx:442
|
||||
msgid "{0} labels"
|
||||
msgstr "{0} étiquettes"
|
||||
|
||||
#. placeholder {0}: isTemplate ? "Template" : "Board"
|
||||
#: src/views/board/index.tsx:389
|
||||
#: src/views/board/index.tsx:387
|
||||
msgid "{0} not found"
|
||||
msgstr "{0} introuvable"
|
||||
|
||||
@@ -79,8 +79,8 @@ msgstr "Compte"
|
||||
msgid "Account deleted"
|
||||
msgstr "Compte supprimé"
|
||||
|
||||
#: src/views/card/index.tsx:308
|
||||
#: src/views/public/board/CardModal.tsx:157
|
||||
#: src/views/card/index.tsx:291
|
||||
#: src/views/public/board/CardModal.tsx:143
|
||||
msgid "Activity"
|
||||
msgstr "Activité"
|
||||
|
||||
@@ -109,7 +109,7 @@ msgstr "Ajouter un élément..."
|
||||
msgid "Add checklist"
|
||||
msgstr "Ajouter une checklist"
|
||||
|
||||
#: src/components/Editor.tsx:451
|
||||
#: src/components/Editor.tsx:442
|
||||
msgid "Add description... (type '/' to open commands or '@' to mention)"
|
||||
msgstr "Ajouter une description... (tapez '/' pour ouvrir les commandes ou '@' pour mentionner)"
|
||||
|
||||
@@ -270,10 +270,6 @@ msgstr "a assigné <0>{0}</0> à la carte"
|
||||
msgid "Assignees"
|
||||
msgstr "Assignés"
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:25
|
||||
msgid "Attachment uploaded"
|
||||
msgstr "Pièce jointe téléversée"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:47
|
||||
msgid "Awaiting Customer"
|
||||
msgstr "En attente du client"
|
||||
@@ -308,9 +304,9 @@ msgstr "Portail de facturation"
|
||||
msgid "Blog Post"
|
||||
msgstr "Article de blog"
|
||||
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/public/board/index.tsx:101
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/card/index.tsx:216
|
||||
#: src/views/public/board/index.tsx:100
|
||||
msgid "Board"
|
||||
msgstr "Tableau"
|
||||
|
||||
@@ -327,7 +323,7 @@ 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/public/board/index.tsx:153
|
||||
#: src/views/public/board/index.tsx:151
|
||||
msgid "Board not found"
|
||||
msgstr "Tableau introuvable"
|
||||
|
||||
@@ -335,19 +331,19 @@ msgstr "Tableau introuvable"
|
||||
msgid "Board sharing & invites"
|
||||
msgstr "Partage de tableau & invitations"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:46
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:45
|
||||
msgid "Board URL can only contain letters, numbers, and hyphens"
|
||||
msgstr "L'URL du tableau ne peut contenir que des lettres, des chiffres et des traits d'union"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:44
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:43
|
||||
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:68
|
||||
#: src/views/public/board/index.tsx:67
|
||||
msgid "Board URL copied to clipboard"
|
||||
msgstr "URL du tableau copiée dans le presse-papiers"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:42
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:41
|
||||
msgid "Board URL must be at least 3 characters long"
|
||||
msgstr "L'URL du tableau doit comporter au moins 3 caractères"
|
||||
|
||||
@@ -356,7 +352,7 @@ msgstr "L'URL du tableau doit comporter au moins 3 caractères"
|
||||
msgid "Board visibility"
|
||||
msgstr "Visibilité du tableau"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:46
|
||||
#: src/views/board/components/VisibilityButton.tsx:45
|
||||
msgid "Board visibility updated"
|
||||
msgstr "Visibilité du tableau mise à jour"
|
||||
|
||||
@@ -391,15 +387,15 @@ msgstr "Rapport de bug"
|
||||
msgid "Cancel"
|
||||
msgstr "Annuler"
|
||||
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/card/index.tsx:216
|
||||
msgid "Card"
|
||||
msgstr "Carte"
|
||||
|
||||
#: src/views/card/index.tsx:264
|
||||
#: src/views/card/index.tsx:262
|
||||
msgid "Card not found"
|
||||
msgstr "Carte introuvable"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:310
|
||||
#: src/views/board/components/NewCardForm.tsx:309
|
||||
msgid "Card title"
|
||||
msgstr "Titre de la carte"
|
||||
|
||||
@@ -432,7 +428,7 @@ msgstr "Nom de la checklist"
|
||||
msgid "Checklists"
|
||||
msgstr "Listes de contrôle"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:180
|
||||
#: src/views/board/components/Filters.tsx:155
|
||||
msgid "Clear filters"
|
||||
msgstr "Effacer les filtres"
|
||||
|
||||
@@ -523,7 +519,7 @@ msgstr "Contactez-nous"
|
||||
msgid "Content Creation"
|
||||
msgstr "Création de contenu"
|
||||
|
||||
#: src/components/AuthForm.tsx:434
|
||||
#: src/components/AuthForm.tsx:420
|
||||
msgid "Continue with "
|
||||
msgstr "Continuer avec "
|
||||
|
||||
@@ -546,8 +542,8 @@ msgid "Create {0}"
|
||||
msgstr "Créer {0}"
|
||||
|
||||
#: src/components/LabelForm.tsx:213
|
||||
#: src/views/board/components/NewCardForm.tsx:469
|
||||
#: src/views/board/components/NewListForm.tsx:141
|
||||
#: src/views/board/components/NewCardForm.tsx:468
|
||||
#: src/views/board/components/NewListForm.tsx:140
|
||||
msgid "Create another"
|
||||
msgstr "Créer un autre"
|
||||
|
||||
@@ -555,7 +551,7 @@ msgstr "Créer un autre"
|
||||
msgid "Create API key"
|
||||
msgstr "Créer une clé API"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:479
|
||||
#: src/views/board/components/NewCardForm.tsx:478
|
||||
msgid "Create card"
|
||||
msgstr "Créer une carte"
|
||||
|
||||
@@ -571,7 +567,7 @@ msgstr "Créer un lien d'invitation"
|
||||
msgid "Create label"
|
||||
msgstr "Créer une étiquette"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:153
|
||||
#: src/views/board/components/NewListForm.tsx:152
|
||||
msgid "Create list"
|
||||
msgstr "Créer une liste"
|
||||
|
||||
@@ -584,12 +580,12 @@ msgstr "Créer un nouveau {0}"
|
||||
msgid "Create new key"
|
||||
msgstr "Créer une nouvelle clé"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:405
|
||||
#: src/views/board/components/NewCardForm.tsx:404
|
||||
#: src/views/card/components/LabelSelector.tsx:97
|
||||
msgid "Create new label"
|
||||
msgstr "Créer une nouvelle étiquette"
|
||||
|
||||
#: src/views/board/index.tsx:478
|
||||
#: src/views/board/index.tsx:475
|
||||
msgid "Create new list"
|
||||
msgstr "Créer une nouvelle liste"
|
||||
|
||||
@@ -773,12 +769,8 @@ msgstr "Vous n'avez pas de compte ? <0><1>Inscrivez-vous</1></0>"
|
||||
msgid "Done"
|
||||
msgstr "Fait"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:141
|
||||
msgid "Download failed"
|
||||
msgstr "Échec du téléchargement"
|
||||
|
||||
#: src/views/board/components/BoardDropdown.tsx:41
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:116
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:115
|
||||
msgid "Edit board URL"
|
||||
msgstr "Modifier l'URL du tableau"
|
||||
|
||||
@@ -790,7 +782,7 @@ msgstr "Modifier le commentaire"
|
||||
msgid "Edit label"
|
||||
msgstr "Modifier l'étiquette"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:162
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:161
|
||||
msgid "Edit workspace URL"
|
||||
msgstr "Modifier l'URL de l'espace de travail"
|
||||
|
||||
@@ -798,7 +790,7 @@ msgstr "Modifier l'URL de l'espace de travail"
|
||||
msgid "Editing"
|
||||
msgstr "Édition"
|
||||
|
||||
#: src/components/AuthForm.tsx:435
|
||||
#: src/components/AuthForm.tsx:421
|
||||
msgid "email"
|
||||
msgstr "e-mail"
|
||||
|
||||
@@ -818,11 +810,11 @@ msgstr "Saisissez votre mot de passe actuel"
|
||||
msgid "Enter your current password and choose a new secure password."
|
||||
msgstr "Saisissez votre mot de passe actuel et choisissez un nouveau mot de passe sécurisé."
|
||||
|
||||
#: src/components/AuthForm.tsx:398
|
||||
#: src/components/AuthForm.tsx:387
|
||||
msgid "Enter your email address"
|
||||
msgstr "Saisissez votre adresse e-mail"
|
||||
|
||||
#: src/components/AuthForm.tsx:384
|
||||
#: src/components/AuthForm.tsx:375
|
||||
msgid "Enter your name"
|
||||
msgstr "Saisissez votre nom"
|
||||
|
||||
@@ -830,7 +822,7 @@ msgstr "Saisissez votre nom"
|
||||
msgid "Enter your new password"
|
||||
msgstr "Saisissez votre nouveau mot de passe"
|
||||
|
||||
#: src/components/AuthForm.tsx:411
|
||||
#: src/components/AuthForm.tsx:400
|
||||
msgid "Enter your password"
|
||||
msgstr "Saisissez votre mot de passe"
|
||||
|
||||
@@ -939,11 +931,6 @@ msgstr "Échec de la création du tableau"
|
||||
msgid "Failed to login with {0}. Please try again."
|
||||
msgstr "Échec de connexion avec {0}. Veuillez réessayer."
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:33
|
||||
#: src/views/card/components/AttachmentUpload.tsx:79
|
||||
msgid "Failed to upload attachment. Please try again."
|
||||
msgstr "Échec du téléversement de la pièce jointe. Veuillez réessayer."
|
||||
|
||||
#: src/views/home/components/Header.tsx:41
|
||||
msgid "FAQ"
|
||||
msgstr "FAQ"
|
||||
@@ -987,7 +974,7 @@ msgstr "Commentaires"
|
||||
msgid "Feedback sent"
|
||||
msgstr "Commentaires envoyés"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:174
|
||||
#: src/views/board/components/Filters.tsx:149
|
||||
msgid "Filter"
|
||||
msgstr "Filtrer"
|
||||
|
||||
@@ -1000,8 +987,6 @@ msgid "For long-term sustainability, we recognise all good open source projects
|
||||
msgstr "Pour une durabilité à long terme, nous reconnaissons que tous les bons projets open source ont besoin d'une source de revenus. La nôtre provient de l'offre cloud payante pour les espaces de travail avec plusieurs utilisateurs et pour les slugs d'espace de travail personnalisés. Il n'y a aucune obligation de l'utiliser, et vous pouvez auto-héberger le logiciel sur votre propre infrastructure gratuitement."
|
||||
|
||||
#: src/views/pricing/components/Pricing.tsx:32
|
||||
#: src/views/pricing/components/Pricing.tsx:32
|
||||
#: src/views/pricing/components/PricingTiers.tsx:30
|
||||
#: src/views/pricing/components/PricingTiers.tsx:30
|
||||
msgid "Free"
|
||||
msgstr "Gratuit"
|
||||
@@ -1043,7 +1028,7 @@ msgstr "Commencer"
|
||||
msgid "Get started by creating a new {0}"
|
||||
msgstr "Commencez par créer un nouveau {0}"
|
||||
|
||||
#: src/views/board/index.tsx:470
|
||||
#: src/views/board/index.tsx:467
|
||||
msgid "Get started by creating a new list"
|
||||
msgstr "Commencez par créer une nouvelle liste"
|
||||
|
||||
@@ -1257,9 +1242,9 @@ msgstr "Kanban réinventé"
|
||||
msgid "Keep in mind that this action is irreversible."
|
||||
msgstr "Gardez à l'esprit que cette action est irréversible."
|
||||
|
||||
#: src/views/board/components/Filters.tsx:115
|
||||
#: src/views/board/components/NewCardForm.tsx:409
|
||||
#: src/views/card/index.tsx:119
|
||||
#: src/views/board/components/Filters.tsx:101
|
||||
#: src/views/board/components/NewCardForm.tsx:408
|
||||
#: src/views/card/index.tsx:117
|
||||
msgid "Labels"
|
||||
msgstr "Étiquettes"
|
||||
|
||||
@@ -1309,22 +1294,18 @@ msgstr "Licence"
|
||||
msgid "Light"
|
||||
msgstr "Clair"
|
||||
|
||||
#: src/views/public/board/index.tsx:66
|
||||
#: src/views/public/board/index.tsx:65
|
||||
msgid "Link copied"
|
||||
msgstr "Lien copié"
|
||||
|
||||
#: src/views/card/index.tsx:111
|
||||
#: src/views/card/index.tsx:109
|
||||
msgid "List"
|
||||
msgstr "Liste"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:129
|
||||
#: src/views/board/components/NewListForm.tsx:128
|
||||
msgid "List name"
|
||||
msgstr "Nom de la liste"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:123
|
||||
msgid "Lists"
|
||||
msgstr "Listes"
|
||||
|
||||
#: src/views/auth/login/index.tsx:33
|
||||
msgid "Login | kan.bn"
|
||||
msgstr "Connexion | kan.bn"
|
||||
@@ -1345,7 +1326,7 @@ msgstr "Adoré par les équipes du monde entier"
|
||||
msgid "Low Priority"
|
||||
msgstr "Priorité basse"
|
||||
|
||||
#: src/components/AuthForm.tsx:435
|
||||
#: src/components/AuthForm.tsx:421
|
||||
msgid "magic link"
|
||||
msgstr "lien magique"
|
||||
|
||||
@@ -1367,9 +1348,9 @@ msgid "Medium Priority"
|
||||
msgstr "Priorité moyenne"
|
||||
|
||||
#: src/components/SideNavigation.tsx:101
|
||||
#: src/views/board/components/Filters.tsx:107
|
||||
#: src/views/board/components/NewCardForm.tsx:367
|
||||
#: src/views/card/index.tsx:128
|
||||
#: src/views/board/components/Filters.tsx:93
|
||||
#: src/views/board/components/NewCardForm.tsx:366
|
||||
#: src/views/card/index.tsx:126
|
||||
#: src/views/members/index.tsx:178
|
||||
msgid "Members"
|
||||
msgstr "Membres"
|
||||
@@ -1422,7 +1403,7 @@ msgstr "Nouveau {0}"
|
||||
msgid "New API key"
|
||||
msgstr "Nouvelle clé API"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:293
|
||||
#: src/views/board/components/NewCardForm.tsx:292
|
||||
msgid "New card"
|
||||
msgstr "Nouvelle carte"
|
||||
|
||||
@@ -1438,8 +1419,8 @@ msgstr "Nouvel import"
|
||||
msgid "New label"
|
||||
msgstr "Nouvelle étiquette"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:113
|
||||
#: src/views/board/index.tsx:442
|
||||
#: src/views/board/components/NewListForm.tsx:112
|
||||
#: src/views/board/index.tsx:439
|
||||
msgid "New list"
|
||||
msgstr "Nouvelle liste"
|
||||
|
||||
@@ -1476,10 +1457,6 @@ msgstr "Prochaines étapes"
|
||||
msgid "No {0}"
|
||||
msgstr "Aucun {0}"
|
||||
|
||||
#: src/components/AuthForm.tsx:365
|
||||
msgid "No authentication methods are currently available"
|
||||
msgstr "Aucune méthode d'authentification n'est actuellement disponible"
|
||||
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:242
|
||||
msgid "No boards found"
|
||||
msgstr "Aucun tableau trouvé"
|
||||
@@ -1488,11 +1465,7 @@ msgstr "Aucun tableau trouvé"
|
||||
msgid "No credit card required"
|
||||
msgstr "Aucune carte de crédit requise"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:142
|
||||
msgid "No download URL available for this attachment."
|
||||
msgstr "Aucune URL de téléchargement disponible pour cette pièce jointe."
|
||||
|
||||
#: src/views/board/index.tsx:467
|
||||
#: src/views/board/index.tsx:464
|
||||
msgid "No lists"
|
||||
msgstr "Aucune liste"
|
||||
|
||||
@@ -1524,7 +1497,7 @@ msgstr "Open source"
|
||||
msgid "Open Source Friends"
|
||||
msgstr "Amis Open Source"
|
||||
|
||||
#: src/components/AuthForm.tsx:374
|
||||
#: src/components/AuthForm.tsx:365
|
||||
msgid "or"
|
||||
msgstr "ou"
|
||||
|
||||
@@ -1606,15 +1579,15 @@ msgstr "Plateforme"
|
||||
msgid "Please confirm your new password"
|
||||
msgstr "Veuillez confirmer votre nouveau mot de passe"
|
||||
|
||||
#: src/components/AuthForm.tsx:402
|
||||
#: src/components/AuthForm.tsx:391
|
||||
msgid "Please enter a valid email address"
|
||||
msgstr "Veuillez saisir une adresse e-mail valide"
|
||||
|
||||
#: src/components/AuthForm.tsx:388
|
||||
#: src/components/AuthForm.tsx:379
|
||||
msgid "Please enter a valid name"
|
||||
msgstr "Veuillez saisir un nom valide"
|
||||
|
||||
#: src/components/AuthForm.tsx:416
|
||||
#: src/components/AuthForm.tsx:404
|
||||
msgid "Please enter a valid password"
|
||||
msgstr "Veuillez saisir un mot de passe valide"
|
||||
|
||||
@@ -1625,16 +1598,15 @@ msgstr "Veuillez sélectionner un fichier à télécharger."
|
||||
#: src/components/DeleteLabelConfirmation.tsx:26
|
||||
#: src/components/FeedbackModal.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:158
|
||||
#: src/views/board/components/NewCardForm.tsx:177
|
||||
#: src/views/board/components/NewListForm.tsx:79
|
||||
#: src/views/board/components/NewCardForm.tsx:176
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/NewTemplateForm.tsx:61
|
||||
#: src/views/board/components/NewTemplateForm.tsx:77
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:73
|
||||
#: src/views/board/components/VisibilityButton.tsx:54
|
||||
#: src/views/board/index.tsx:151
|
||||
#: src/views/board/index.tsx:207
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
#: src/views/board/components/VisibilityButton.tsx:53
|
||||
#: src/views/board/index.tsx:149
|
||||
#: src/views/board/index.tsx:205
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:205
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:73
|
||||
#: src/views/card/components/ChecklistItemRow.tsx:60
|
||||
#: src/views/card/components/ChecklistItemRow.tsx:88
|
||||
#: src/views/card/components/ChecklistNameInput.tsx:46
|
||||
@@ -1648,7 +1620,7 @@ msgstr "Veuillez sélectionner un fichier à télécharger."
|
||||
#: src/views/card/components/NewChecklistForm.tsx:70
|
||||
#: src/views/card/components/NewChecklistItemForm.tsx:89
|
||||
#: src/views/card/components/NewCommentForm.tsx:31
|
||||
#: src/views/card/index.tsx:177
|
||||
#: src/views/card/index.tsx:175
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
#: src/views/members/components/InviteMemberForm.tsx:241
|
||||
@@ -1692,7 +1664,7 @@ msgstr "Support par e-mail prioritaire"
|
||||
msgid "Privacy policy"
|
||||
msgstr "Politique de confidentialité"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:74
|
||||
#: src/views/board/components/VisibilityButton.tsx:73
|
||||
msgid "Private"
|
||||
msgstr "Privé"
|
||||
|
||||
@@ -1712,7 +1684,7 @@ msgstr "Image de profil mise à jour"
|
||||
msgid "Profile picture"
|
||||
msgstr "Photo de profil"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:69
|
||||
#: src/views/board/components/VisibilityButton.tsx:68
|
||||
msgid "Public"
|
||||
msgstr "Public"
|
||||
|
||||
@@ -1914,7 +1886,7 @@ msgstr "Inscription désactivée"
|
||||
msgid "Sign up is currently disabled. Please try again later."
|
||||
msgstr "L'inscription est actuellement désactivée. Veuillez réessayer plus tard."
|
||||
|
||||
#: src/components/AuthForm.tsx:434
|
||||
#: src/components/AuthForm.tsx:420
|
||||
msgid "Sign up with "
|
||||
msgstr "S'inscrire avec "
|
||||
|
||||
@@ -1981,8 +1953,8 @@ msgstr "Forfait d'équipe"
|
||||
msgid "Teams"
|
||||
msgstr "Équipes"
|
||||
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/board/index.tsx:398
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/board/index.tsx:396
|
||||
msgid "Template"
|
||||
msgstr "Modèle"
|
||||
|
||||
@@ -2032,7 +2004,7 @@ msgid "The open source <0/> alternative to Trello"
|
||||
msgstr "L'alternative open source <0/> à Trello"
|
||||
|
||||
#. placeholder {0}: isPublic ? "public" : "private"
|
||||
#: src/views/board/components/VisibilityButton.tsx:47
|
||||
#: src/views/board/components/VisibilityButton.tsx:46
|
||||
msgid "The visibility of your board has been set to {0}."
|
||||
msgstr "La visibilité de votre tableau a été définie sur {0}."
|
||||
|
||||
@@ -2056,11 +2028,11 @@ msgstr "Cette action ne peut pas être annulée."
|
||||
msgid "This API key will only be shown once. Please save it in a secure location."
|
||||
msgstr "Cette clé API ne sera affichée qu'une seule fois. Veuillez la sauvegarder dans un emplacement sécurisé."
|
||||
|
||||
#: src/views/public/board/index.tsx:156
|
||||
#: src/views/public/board/index.tsx:154
|
||||
msgid "This board is private or does not exist"
|
||||
msgstr "Ce tableau est privé ou n'existe pas"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:136
|
||||
#: 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"
|
||||
|
||||
@@ -2130,7 +2102,7 @@ msgstr "Impossible d'ajouter l'élément à la liste de contrôle"
|
||||
msgid "Unable to add comment"
|
||||
msgstr "Impossible d'ajouter un commentaire"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:174
|
||||
#: src/views/board/components/NewCardForm.tsx:173
|
||||
msgid "Unable to create card"
|
||||
msgstr "Impossible de créer la carte"
|
||||
|
||||
@@ -2138,7 +2110,7 @@ msgstr "Impossible de créer la carte"
|
||||
msgid "Unable to create checklist"
|
||||
msgstr "Impossible de créer la liste de contrôle"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/NewListForm.tsx:77
|
||||
msgid "Unable to create list"
|
||||
msgstr "Impossible de créer une liste"
|
||||
|
||||
@@ -2151,10 +2123,6 @@ msgstr "Impossible de créer le modèle"
|
||||
msgid "Unable to create workspace"
|
||||
msgstr "Impossible de créer l'espace de travail"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:72
|
||||
msgid "Unable to delete attachment"
|
||||
msgstr "Impossible de supprimer la pièce jointe"
|
||||
|
||||
#: src/views/card/components/DeleteCardConfirmation.tsx:51
|
||||
msgid "Unable to delete card"
|
||||
msgstr "Impossible de supprimer la carte"
|
||||
@@ -2179,16 +2147,16 @@ msgstr "Impossible de supprimer le membre"
|
||||
msgid "Unable to send feedback"
|
||||
msgstr "Impossible d'envoyer les commentaires"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:71
|
||||
msgid "Unable to update board URL"
|
||||
msgstr "Impossible de mettre à jour l'URL du tableau"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:53
|
||||
#: src/views/board/components/VisibilityButton.tsx:52
|
||||
msgid "Unable to update board visibility"
|
||||
msgstr "Impossible de mettre à jour la visibilité du tableau"
|
||||
|
||||
#: src/views/board/index.tsx:206
|
||||
#: src/views/card/index.tsx:176
|
||||
#: src/views/board/index.tsx:204
|
||||
#: src/views/card/index.tsx:174
|
||||
msgid "Unable to update card"
|
||||
msgstr "Impossible de mettre à jour la carte"
|
||||
|
||||
@@ -2208,7 +2176,7 @@ msgstr "Impossible de mettre à jour le commentaire"
|
||||
msgid "Unable to update labels"
|
||||
msgstr "Impossible de mettre à jour les étiquettes"
|
||||
|
||||
#: src/views/board/index.tsx:150
|
||||
#: src/views/board/index.tsx:148
|
||||
#: src/views/card/components/ListSelector.tsx:51
|
||||
msgid "Unable to update list"
|
||||
msgstr "Impossible de mettre à jour la liste"
|
||||
@@ -2264,7 +2232,7 @@ msgstr "Membres illimités"
|
||||
msgid "Unlimited workspaces"
|
||||
msgstr "Espaces de travail illimités"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:175
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
|
||||
#: src/views/settings/components/UpdateDisplayNameForm.tsx:80
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:91
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:83
|
||||
@@ -2303,11 +2271,6 @@ msgstr "Passer à Pro"
|
||||
msgid "Upgrade to Pro ($29/month)"
|
||||
msgstr "Passer à Pro (29 $/mois)"
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:32
|
||||
#: src/views/card/components/AttachmentUpload.tsx:78
|
||||
msgid "Upload failed"
|
||||
msgstr "Échec du téléversement"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:38
|
||||
#: src/views/boards/components/TemplateBoards.tsx:55
|
||||
msgid "Urgent"
|
||||
@@ -2357,7 +2320,7 @@ msgstr "Consultez et gérez votre facturation et votre abonnement."
|
||||
msgid "View docs"
|
||||
msgstr "Voir la documentation"
|
||||
|
||||
#: src/views/public/board/index.tsx:129
|
||||
#: src/views/public/board/index.tsx:128
|
||||
msgid "View only"
|
||||
msgstr "Affichage uniquement"
|
||||
|
||||
@@ -2365,11 +2328,11 @@ msgstr "Affichage uniquement"
|
||||
msgid "View our roadmap."
|
||||
msgstr "Consultez notre feuille de route."
|
||||
|
||||
#: src/views/public/board/index.tsx:159
|
||||
#: src/views/public/board/index.tsx:157
|
||||
msgid "View workspace"
|
||||
msgstr "Voir l'espace de travail"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:92
|
||||
#: src/views/board/components/VisibilityButton.tsx:91
|
||||
msgid "Visibility"
|
||||
msgstr "Visibilité"
|
||||
|
||||
@@ -2406,10 +2369,10 @@ msgid "Why make an open source Trello?"
|
||||
msgstr "Pourquoi créer un Trello open source ?"
|
||||
|
||||
#: src/components/SettingsLayout.tsx:39
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/boards/index.tsx:22
|
||||
#: src/views/members/index.tsx:173
|
||||
#: src/views/public/board/index.tsx:101
|
||||
#: src/views/public/board/index.tsx:100
|
||||
#: src/views/public/boards/index.tsx:66
|
||||
msgid "Workspace"
|
||||
msgstr "Espace de travail"
|
||||
@@ -2539,10 +2502,6 @@ msgstr "Vos tableaux ont été importés."
|
||||
msgid "Your display name has been updated."
|
||||
msgstr "Votre nom d'affichage a été mis à jour."
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:26
|
||||
msgid "Your file has been uploaded successfully."
|
||||
msgstr "Votre fichier a été téléversé avec succès."
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:70
|
||||
msgid "Your password has been changed."
|
||||
msgstr "Votre mot de passe a été modifié."
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -31,17 +31,17 @@ msgstr "{0}"
|
||||
#. placeholder {1}: board?.name ?? t`Board`
|
||||
#. placeholder {1}: workspace.name ?? t`Workspace`
|
||||
#: src/views/boards/index.tsx:22
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/card/index.tsx:216
|
||||
msgid "{0} | {1}"
|
||||
msgstr "{0} | {1}"
|
||||
|
||||
#. placeholder {0}: labelPublicIds.length
|
||||
#: src/views/board/components/NewCardForm.tsx:443
|
||||
#: src/views/board/components/NewCardForm.tsx:442
|
||||
msgid "{0} labels"
|
||||
msgstr "{0} etichette"
|
||||
|
||||
#. placeholder {0}: isTemplate ? "Template" : "Board"
|
||||
#: src/views/board/index.tsx:389
|
||||
#: src/views/board/index.tsx:387
|
||||
msgid "{0} not found"
|
||||
msgstr "{0} non trovato"
|
||||
|
||||
@@ -79,8 +79,8 @@ msgstr "Account"
|
||||
msgid "Account deleted"
|
||||
msgstr "Account eliminato"
|
||||
|
||||
#: src/views/card/index.tsx:308
|
||||
#: src/views/public/board/CardModal.tsx:157
|
||||
#: src/views/card/index.tsx:291
|
||||
#: src/views/public/board/CardModal.tsx:143
|
||||
msgid "Activity"
|
||||
msgstr "Attività"
|
||||
|
||||
@@ -109,7 +109,7 @@ msgstr "Aggiungi un elemento..."
|
||||
msgid "Add checklist"
|
||||
msgstr "Aggiungi checklist"
|
||||
|
||||
#: src/components/Editor.tsx:451
|
||||
#: src/components/Editor.tsx:442
|
||||
msgid "Add description... (type '/' to open commands or '@' to mention)"
|
||||
msgstr "Aggiungi descrizione... (digita '/' per aprire i comandi o '@' per menzionare)"
|
||||
|
||||
@@ -270,10 +270,6 @@ msgstr "ha assegnato <0>{0}</0> alla scheda"
|
||||
msgid "Assignees"
|
||||
msgstr "Assegnatari"
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:25
|
||||
msgid "Attachment uploaded"
|
||||
msgstr "Allegato caricato"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:47
|
||||
msgid "Awaiting Customer"
|
||||
msgstr "In attesa del cliente"
|
||||
@@ -308,9 +304,9 @@ msgstr "Portale di fatturazione"
|
||||
msgid "Blog Post"
|
||||
msgstr "Post del blog"
|
||||
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/public/board/index.tsx:101
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/card/index.tsx:216
|
||||
#: src/views/public/board/index.tsx:100
|
||||
msgid "Board"
|
||||
msgstr "Bacheca"
|
||||
|
||||
@@ -327,7 +323,7 @@ msgstr "Il nome della bacheca non può superare i 100 caratteri"
|
||||
msgid "Board name is required"
|
||||
msgstr "Il nome della bacheca è obbligatorio"
|
||||
|
||||
#: src/views/public/board/index.tsx:153
|
||||
#: src/views/public/board/index.tsx:151
|
||||
msgid "Board not found"
|
||||
msgstr "Bacheca non trovata"
|
||||
|
||||
@@ -335,19 +331,19 @@ msgstr "Bacheca non trovata"
|
||||
msgid "Board sharing & invites"
|
||||
msgstr "Condivisione bacheca & inviti"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:46
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:45
|
||||
msgid "Board URL can only contain letters, numbers, and hyphens"
|
||||
msgstr "L'URL della bacheca può contenere solo lettere, numeri e trattini"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:44
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:43
|
||||
msgid "Board URL cannot exceed 60 characters"
|
||||
msgstr "L'URL della bacheca non può superare i 60 caratteri"
|
||||
|
||||
#: src/views/public/board/index.tsx:68
|
||||
#: src/views/public/board/index.tsx:67
|
||||
msgid "Board URL copied to clipboard"
|
||||
msgstr "URL della bacheca copiato negli appunti"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:42
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:41
|
||||
msgid "Board URL must be at least 3 characters long"
|
||||
msgstr "L'URL della bacheca deve contenere almeno 3 caratteri"
|
||||
|
||||
@@ -356,7 +352,7 @@ msgstr "L'URL della bacheca deve contenere almeno 3 caratteri"
|
||||
msgid "Board visibility"
|
||||
msgstr "Visibilità bacheca"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:46
|
||||
#: src/views/board/components/VisibilityButton.tsx:45
|
||||
msgid "Board visibility updated"
|
||||
msgstr "Visibilità della bacheca aggiornata"
|
||||
|
||||
@@ -391,15 +387,15 @@ msgstr "Segnalazione bug"
|
||||
msgid "Cancel"
|
||||
msgstr "Annulla"
|
||||
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/card/index.tsx:216
|
||||
msgid "Card"
|
||||
msgstr "Carta"
|
||||
|
||||
#: src/views/card/index.tsx:264
|
||||
#: src/views/card/index.tsx:262
|
||||
msgid "Card not found"
|
||||
msgstr "Carta non trovata"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:310
|
||||
#: src/views/board/components/NewCardForm.tsx:309
|
||||
msgid "Card title"
|
||||
msgstr "Titolo della carta"
|
||||
|
||||
@@ -432,7 +428,7 @@ msgstr "Nome della checklist"
|
||||
msgid "Checklists"
|
||||
msgstr "Checklist"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:180
|
||||
#: src/views/board/components/Filters.tsx:155
|
||||
msgid "Clear filters"
|
||||
msgstr "Cancella filtri"
|
||||
|
||||
@@ -523,7 +519,7 @@ msgstr "Contattaci"
|
||||
msgid "Content Creation"
|
||||
msgstr "Creazione contenuti"
|
||||
|
||||
#: src/components/AuthForm.tsx:434
|
||||
#: src/components/AuthForm.tsx:420
|
||||
msgid "Continue with "
|
||||
msgstr "Continua con "
|
||||
|
||||
@@ -546,8 +542,8 @@ msgid "Create {0}"
|
||||
msgstr "Crea {0}"
|
||||
|
||||
#: src/components/LabelForm.tsx:213
|
||||
#: src/views/board/components/NewCardForm.tsx:469
|
||||
#: src/views/board/components/NewListForm.tsx:141
|
||||
#: src/views/board/components/NewCardForm.tsx:468
|
||||
#: src/views/board/components/NewListForm.tsx:140
|
||||
msgid "Create another"
|
||||
msgstr "Crea un altro"
|
||||
|
||||
@@ -555,7 +551,7 @@ msgstr "Crea un altro"
|
||||
msgid "Create API key"
|
||||
msgstr "Crea chiave API"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:479
|
||||
#: src/views/board/components/NewCardForm.tsx:478
|
||||
msgid "Create card"
|
||||
msgstr "Crea carta"
|
||||
|
||||
@@ -571,7 +567,7 @@ msgstr "Crea link di invito"
|
||||
msgid "Create label"
|
||||
msgstr "Crea etichetta"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:153
|
||||
#: src/views/board/components/NewListForm.tsx:152
|
||||
msgid "Create list"
|
||||
msgstr "Crea lista"
|
||||
|
||||
@@ -584,12 +580,12 @@ msgstr "Crea nuovo {0}"
|
||||
msgid "Create new key"
|
||||
msgstr "Crea nuova chiave"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:405
|
||||
#: src/views/board/components/NewCardForm.tsx:404
|
||||
#: src/views/card/components/LabelSelector.tsx:97
|
||||
msgid "Create new label"
|
||||
msgstr "Crea nuova etichetta"
|
||||
|
||||
#: src/views/board/index.tsx:478
|
||||
#: src/views/board/index.tsx:475
|
||||
msgid "Create new list"
|
||||
msgstr "Crea nuova lista"
|
||||
|
||||
@@ -773,12 +769,8 @@ msgstr "Non hai un account? <0><1>Registrati</1></0>"
|
||||
msgid "Done"
|
||||
msgstr "Fatto"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:141
|
||||
msgid "Download failed"
|
||||
msgstr "Download fallito"
|
||||
|
||||
#: src/views/board/components/BoardDropdown.tsx:41
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:116
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:115
|
||||
msgid "Edit board URL"
|
||||
msgstr "Modifica URL della bacheca"
|
||||
|
||||
@@ -790,7 +782,7 @@ msgstr "Modifica commento"
|
||||
msgid "Edit label"
|
||||
msgstr "Modifica etichetta"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:162
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:161
|
||||
msgid "Edit workspace URL"
|
||||
msgstr "Modifica URL dell'area di lavoro"
|
||||
|
||||
@@ -798,7 +790,7 @@ msgstr "Modifica URL dell'area di lavoro"
|
||||
msgid "Editing"
|
||||
msgstr "Modifica"
|
||||
|
||||
#: src/components/AuthForm.tsx:435
|
||||
#: src/components/AuthForm.tsx:421
|
||||
msgid "email"
|
||||
msgstr "email"
|
||||
|
||||
@@ -818,11 +810,11 @@ msgstr "Inserisci la tua password attuale"
|
||||
msgid "Enter your current password and choose a new secure password."
|
||||
msgstr "Inserisci la tua password attuale e scegli una nuova password sicura."
|
||||
|
||||
#: src/components/AuthForm.tsx:398
|
||||
#: src/components/AuthForm.tsx:387
|
||||
msgid "Enter your email address"
|
||||
msgstr "Inserisci il tuo indirizzo email"
|
||||
|
||||
#: src/components/AuthForm.tsx:384
|
||||
#: src/components/AuthForm.tsx:375
|
||||
msgid "Enter your name"
|
||||
msgstr "Inserisci il tuo nome"
|
||||
|
||||
@@ -830,7 +822,7 @@ msgstr "Inserisci il tuo nome"
|
||||
msgid "Enter your new password"
|
||||
msgstr "Inserisci la tua nuova password"
|
||||
|
||||
#: src/components/AuthForm.tsx:411
|
||||
#: src/components/AuthForm.tsx:400
|
||||
msgid "Enter your password"
|
||||
msgstr "Inserisci la tua password"
|
||||
|
||||
@@ -939,11 +931,6 @@ msgstr "Impossibile creare la bacheca"
|
||||
msgid "Failed to login with {0}. Please try again."
|
||||
msgstr "Accesso con {0} fallito. Riprova."
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:33
|
||||
#: src/views/card/components/AttachmentUpload.tsx:79
|
||||
msgid "Failed to upload attachment. Please try again."
|
||||
msgstr "Impossibile caricare l'allegato. Riprova."
|
||||
|
||||
#: src/views/home/components/Header.tsx:41
|
||||
msgid "FAQ"
|
||||
msgstr "FAQ"
|
||||
@@ -987,7 +974,7 @@ msgstr "Feedback"
|
||||
msgid "Feedback sent"
|
||||
msgstr "Feedback inviato"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:174
|
||||
#: src/views/board/components/Filters.tsx:149
|
||||
msgid "Filter"
|
||||
msgstr "Filtra"
|
||||
|
||||
@@ -1000,8 +987,6 @@ msgid "For long-term sustainability, we recognise all good open source projects
|
||||
msgstr "Per la sostenibilità a lungo termine, riconosciamo che tutti i buoni progetti open source necessitano di una fonte di entrate. La nostra proviene dall'offerta cloud a pagamento per gli spazi di lavoro con più utenti e per gli slug personalizzati degli spazi di lavoro. Non c'è alcun obbligo di utilizzarla, e puoi ospitare autonomamente il software sulla tua infrastruttura gratuitamente."
|
||||
|
||||
#: src/views/pricing/components/Pricing.tsx:32
|
||||
#: src/views/pricing/components/Pricing.tsx:32
|
||||
#: src/views/pricing/components/PricingTiers.tsx:30
|
||||
#: src/views/pricing/components/PricingTiers.tsx:30
|
||||
msgid "Free"
|
||||
msgstr "Gratuito"
|
||||
@@ -1043,7 +1028,7 @@ msgstr "Inizia ora"
|
||||
msgid "Get started by creating a new {0}"
|
||||
msgstr "Inizia creando un nuovo {0}"
|
||||
|
||||
#: src/views/board/index.tsx:470
|
||||
#: src/views/board/index.tsx:467
|
||||
msgid "Get started by creating a new list"
|
||||
msgstr "Inizia creando una nuova lista"
|
||||
|
||||
@@ -1257,9 +1242,9 @@ msgstr "Kanban reinventato"
|
||||
msgid "Keep in mind that this action is irreversible."
|
||||
msgstr "Tieni presente che questa azione è irreversibile."
|
||||
|
||||
#: src/views/board/components/Filters.tsx:115
|
||||
#: src/views/board/components/NewCardForm.tsx:409
|
||||
#: src/views/card/index.tsx:119
|
||||
#: src/views/board/components/Filters.tsx:101
|
||||
#: src/views/board/components/NewCardForm.tsx:408
|
||||
#: src/views/card/index.tsx:117
|
||||
msgid "Labels"
|
||||
msgstr "Etichette"
|
||||
|
||||
@@ -1309,22 +1294,18 @@ msgstr "Licenza"
|
||||
msgid "Light"
|
||||
msgstr "Chiaro"
|
||||
|
||||
#: src/views/public/board/index.tsx:66
|
||||
#: src/views/public/board/index.tsx:65
|
||||
msgid "Link copied"
|
||||
msgstr "Link copiato"
|
||||
|
||||
#: src/views/card/index.tsx:111
|
||||
#: src/views/card/index.tsx:109
|
||||
msgid "List"
|
||||
msgstr "Lista"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:129
|
||||
#: src/views/board/components/NewListForm.tsx:128
|
||||
msgid "List name"
|
||||
msgstr "Nome lista"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:123
|
||||
msgid "Lists"
|
||||
msgstr "Liste"
|
||||
|
||||
#: src/views/auth/login/index.tsx:33
|
||||
msgid "Login | kan.bn"
|
||||
msgstr "Login | kan.bn"
|
||||
@@ -1345,7 +1326,7 @@ msgstr "Amato dai team di tutto il mondo"
|
||||
msgid "Low Priority"
|
||||
msgstr "Bassa priorità"
|
||||
|
||||
#: src/components/AuthForm.tsx:435
|
||||
#: src/components/AuthForm.tsx:421
|
||||
msgid "magic link"
|
||||
msgstr "link magico"
|
||||
|
||||
@@ -1367,9 +1348,9 @@ msgid "Medium Priority"
|
||||
msgstr "Media priorità"
|
||||
|
||||
#: src/components/SideNavigation.tsx:101
|
||||
#: src/views/board/components/Filters.tsx:107
|
||||
#: src/views/board/components/NewCardForm.tsx:367
|
||||
#: src/views/card/index.tsx:128
|
||||
#: src/views/board/components/Filters.tsx:93
|
||||
#: src/views/board/components/NewCardForm.tsx:366
|
||||
#: src/views/card/index.tsx:126
|
||||
#: src/views/members/index.tsx:178
|
||||
msgid "Members"
|
||||
msgstr "Membri"
|
||||
@@ -1422,7 +1403,7 @@ msgstr "Nuovo {0}"
|
||||
msgid "New API key"
|
||||
msgstr "Nuova chiave API"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:293
|
||||
#: src/views/board/components/NewCardForm.tsx:292
|
||||
msgid "New card"
|
||||
msgstr "Nuova carta"
|
||||
|
||||
@@ -1438,8 +1419,8 @@ msgstr "Nuova importazione"
|
||||
msgid "New label"
|
||||
msgstr "Nuova etichetta"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:113
|
||||
#: src/views/board/index.tsx:442
|
||||
#: src/views/board/components/NewListForm.tsx:112
|
||||
#: src/views/board/index.tsx:439
|
||||
msgid "New list"
|
||||
msgstr "Nuova lista"
|
||||
|
||||
@@ -1476,10 +1457,6 @@ msgstr "Prossimi passi"
|
||||
msgid "No {0}"
|
||||
msgstr "Nessun {0}"
|
||||
|
||||
#: src/components/AuthForm.tsx:365
|
||||
msgid "No authentication methods are currently available"
|
||||
msgstr "Nessun metodo di autenticazione è attualmente disponibile"
|
||||
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:242
|
||||
msgid "No boards found"
|
||||
msgstr "Nessuna bacheca trovata"
|
||||
@@ -1488,11 +1465,7 @@ msgstr "Nessuna bacheca trovata"
|
||||
msgid "No credit card required"
|
||||
msgstr "Nessuna carta di credito richiesta"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:142
|
||||
msgid "No download URL available for this attachment."
|
||||
msgstr "Nessun URL di download disponibile per questo allegato."
|
||||
|
||||
#: src/views/board/index.tsx:467
|
||||
#: src/views/board/index.tsx:464
|
||||
msgid "No lists"
|
||||
msgstr "Nessuna lista"
|
||||
|
||||
@@ -1524,7 +1497,7 @@ msgstr "Open source"
|
||||
msgid "Open Source Friends"
|
||||
msgstr "Amici Open Source"
|
||||
|
||||
#: src/components/AuthForm.tsx:374
|
||||
#: src/components/AuthForm.tsx:365
|
||||
msgid "or"
|
||||
msgstr "o"
|
||||
|
||||
@@ -1606,15 +1579,15 @@ msgstr "Piattaforma"
|
||||
msgid "Please confirm your new password"
|
||||
msgstr "Conferma la tua nuova password"
|
||||
|
||||
#: src/components/AuthForm.tsx:402
|
||||
#: src/components/AuthForm.tsx:391
|
||||
msgid "Please enter a valid email address"
|
||||
msgstr "Inserisci un indirizzo email valido"
|
||||
|
||||
#: src/components/AuthForm.tsx:388
|
||||
#: src/components/AuthForm.tsx:379
|
||||
msgid "Please enter a valid name"
|
||||
msgstr "Inserisci un nome valido"
|
||||
|
||||
#: src/components/AuthForm.tsx:416
|
||||
#: src/components/AuthForm.tsx:404
|
||||
msgid "Please enter a valid password"
|
||||
msgstr "Inserisci una password valida"
|
||||
|
||||
@@ -1625,16 +1598,15 @@ msgstr "Seleziona un file da caricare."
|
||||
#: src/components/DeleteLabelConfirmation.tsx:26
|
||||
#: src/components/FeedbackModal.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:158
|
||||
#: src/views/board/components/NewCardForm.tsx:177
|
||||
#: src/views/board/components/NewListForm.tsx:79
|
||||
#: src/views/board/components/NewCardForm.tsx:176
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/NewTemplateForm.tsx:61
|
||||
#: src/views/board/components/NewTemplateForm.tsx:77
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:73
|
||||
#: src/views/board/components/VisibilityButton.tsx:54
|
||||
#: src/views/board/index.tsx:151
|
||||
#: src/views/board/index.tsx:207
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
#: src/views/board/components/VisibilityButton.tsx:53
|
||||
#: src/views/board/index.tsx:149
|
||||
#: src/views/board/index.tsx:205
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:205
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:73
|
||||
#: src/views/card/components/ChecklistItemRow.tsx:60
|
||||
#: src/views/card/components/ChecklistItemRow.tsx:88
|
||||
#: src/views/card/components/ChecklistNameInput.tsx:46
|
||||
@@ -1648,7 +1620,7 @@ msgstr "Seleziona un file da caricare."
|
||||
#: src/views/card/components/NewChecklistForm.tsx:70
|
||||
#: src/views/card/components/NewChecklistItemForm.tsx:89
|
||||
#: src/views/card/components/NewCommentForm.tsx:31
|
||||
#: src/views/card/index.tsx:177
|
||||
#: src/views/card/index.tsx:175
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
#: src/views/members/components/InviteMemberForm.tsx:241
|
||||
@@ -1692,7 +1664,7 @@ msgstr "Supporto email prioritario"
|
||||
msgid "Privacy policy"
|
||||
msgstr "Informativa sulla privacy"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:74
|
||||
#: src/views/board/components/VisibilityButton.tsx:73
|
||||
msgid "Private"
|
||||
msgstr "Privato"
|
||||
|
||||
@@ -1712,7 +1684,7 @@ msgstr "Immagine del profilo aggiornata"
|
||||
msgid "Profile picture"
|
||||
msgstr "Immagine del profilo"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:69
|
||||
#: src/views/board/components/VisibilityButton.tsx:68
|
||||
msgid "Public"
|
||||
msgstr "Pubblico"
|
||||
|
||||
@@ -1914,7 +1886,7 @@ msgstr "Registrazione disabilitata"
|
||||
msgid "Sign up is currently disabled. Please try again later."
|
||||
msgstr "La registrazione è attualmente disabilitata. Riprova più tardi."
|
||||
|
||||
#: src/components/AuthForm.tsx:434
|
||||
#: src/components/AuthForm.tsx:420
|
||||
msgid "Sign up with "
|
||||
msgstr "Registrati con "
|
||||
|
||||
@@ -1981,8 +1953,8 @@ msgstr "Piano Team"
|
||||
msgid "Teams"
|
||||
msgstr "Team"
|
||||
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/board/index.tsx:398
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/board/index.tsx:396
|
||||
msgid "Template"
|
||||
msgstr "Template"
|
||||
|
||||
@@ -2032,7 +2004,7 @@ msgid "The open source <0/> alternative to Trello"
|
||||
msgstr "L'alternativa open source <0/> a Trello"
|
||||
|
||||
#. placeholder {0}: isPublic ? "public" : "private"
|
||||
#: src/views/board/components/VisibilityButton.tsx:47
|
||||
#: src/views/board/components/VisibilityButton.tsx:46
|
||||
msgid "The visibility of your board has been set to {0}."
|
||||
msgstr "La visibilità della tua bacheca è stata impostata su {0}."
|
||||
|
||||
@@ -2056,11 +2028,11 @@ msgstr "Questa azione non può essere annullata."
|
||||
msgid "This API key will only be shown once. Please save it in a secure location."
|
||||
msgstr "Questa chiave API verrà mostrata una sola volta. Salvala in un luogo sicuro."
|
||||
|
||||
#: src/views/public/board/index.tsx:156
|
||||
#: src/views/public/board/index.tsx:154
|
||||
msgid "This board is private or does not exist"
|
||||
msgstr "Questa bacheca è privata o non esiste"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:136
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:135
|
||||
msgid "This board URL has already been taken"
|
||||
msgstr "Questo URL della bacheca è già stato utilizzato"
|
||||
|
||||
@@ -2130,7 +2102,7 @@ msgstr "Impossibile aggiungere l'elemento della checklist"
|
||||
msgid "Unable to add comment"
|
||||
msgstr "Impossibile aggiungere il commento"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:174
|
||||
#: src/views/board/components/NewCardForm.tsx:173
|
||||
msgid "Unable to create card"
|
||||
msgstr "Impossibile creare la scheda"
|
||||
|
||||
@@ -2138,7 +2110,7 @@ msgstr "Impossibile creare la scheda"
|
||||
msgid "Unable to create checklist"
|
||||
msgstr "Impossibile creare la checklist"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/NewListForm.tsx:77
|
||||
msgid "Unable to create list"
|
||||
msgstr "Impossibile creare la lista"
|
||||
|
||||
@@ -2151,10 +2123,6 @@ msgstr "Impossibile creare il template"
|
||||
msgid "Unable to create workspace"
|
||||
msgstr "Impossibile creare lo spazio di lavoro"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:72
|
||||
msgid "Unable to delete attachment"
|
||||
msgstr "Impossibile eliminare l'allegato"
|
||||
|
||||
#: src/views/card/components/DeleteCardConfirmation.tsx:51
|
||||
msgid "Unable to delete card"
|
||||
msgstr "Impossibile eliminare la scheda"
|
||||
@@ -2179,16 +2147,16 @@ msgstr "Impossibile rimuovere il membro"
|
||||
msgid "Unable to send feedback"
|
||||
msgstr "Impossibile inviare feedback"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:71
|
||||
msgid "Unable to update board URL"
|
||||
msgstr "Impossibile aggiornare l'URL della bacheca"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:53
|
||||
#: src/views/board/components/VisibilityButton.tsx:52
|
||||
msgid "Unable to update board visibility"
|
||||
msgstr "Impossibile aggiornare la visibilità della bacheca"
|
||||
|
||||
#: src/views/board/index.tsx:206
|
||||
#: src/views/card/index.tsx:176
|
||||
#: src/views/board/index.tsx:204
|
||||
#: src/views/card/index.tsx:174
|
||||
msgid "Unable to update card"
|
||||
msgstr "Impossibile aggiornare la scheda"
|
||||
|
||||
@@ -2208,7 +2176,7 @@ msgstr "Impossibile aggiornare il commento"
|
||||
msgid "Unable to update labels"
|
||||
msgstr "Impossibile aggiornare le etichette"
|
||||
|
||||
#: src/views/board/index.tsx:150
|
||||
#: src/views/board/index.tsx:148
|
||||
#: src/views/card/components/ListSelector.tsx:51
|
||||
msgid "Unable to update list"
|
||||
msgstr "Impossibile aggiornare la lista"
|
||||
@@ -2264,7 +2232,7 @@ msgstr "Membri illimitati"
|
||||
msgid "Unlimited workspaces"
|
||||
msgstr "Aree di lavoro illimitate"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:175
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
|
||||
#: src/views/settings/components/UpdateDisplayNameForm.tsx:80
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:91
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:83
|
||||
@@ -2303,11 +2271,6 @@ msgstr "Passa a Pro"
|
||||
msgid "Upgrade to Pro ($29/month)"
|
||||
msgstr "Passa a Pro ($29/mese)"
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:32
|
||||
#: src/views/card/components/AttachmentUpload.tsx:78
|
||||
msgid "Upload failed"
|
||||
msgstr "Caricamento fallito"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:38
|
||||
#: src/views/boards/components/TemplateBoards.tsx:55
|
||||
msgid "Urgent"
|
||||
@@ -2357,7 +2320,7 @@ msgstr "Visualizza e gestisci la tua fatturazione e abbonamento."
|
||||
msgid "View docs"
|
||||
msgstr "Visualizza documenti"
|
||||
|
||||
#: src/views/public/board/index.tsx:129
|
||||
#: src/views/public/board/index.tsx:128
|
||||
msgid "View only"
|
||||
msgstr "Solo visualizzazione"
|
||||
|
||||
@@ -2365,11 +2328,11 @@ msgstr "Solo visualizzazione"
|
||||
msgid "View our roadmap."
|
||||
msgstr "Visualizza la nostra roadmap."
|
||||
|
||||
#: src/views/public/board/index.tsx:159
|
||||
#: src/views/public/board/index.tsx:157
|
||||
msgid "View workspace"
|
||||
msgstr "Visualizza spazio di lavoro"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:92
|
||||
#: src/views/board/components/VisibilityButton.tsx:91
|
||||
msgid "Visibility"
|
||||
msgstr "Visibilità"
|
||||
|
||||
@@ -2406,10 +2369,10 @@ msgid "Why make an open source Trello?"
|
||||
msgstr "Perché creare un Trello open source?"
|
||||
|
||||
#: src/components/SettingsLayout.tsx:39
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/boards/index.tsx:22
|
||||
#: src/views/members/index.tsx:173
|
||||
#: src/views/public/board/index.tsx:101
|
||||
#: src/views/public/board/index.tsx:100
|
||||
#: src/views/public/boards/index.tsx:66
|
||||
msgid "Workspace"
|
||||
msgstr "Spazio di lavoro"
|
||||
@@ -2539,10 +2502,6 @@ msgstr "Le tue bacheche sono state importate."
|
||||
msgid "Your display name has been updated."
|
||||
msgstr "Il tuo nome visualizzato è stato aggiornato."
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:26
|
||||
msgid "Your file has been uploaded successfully."
|
||||
msgstr "Il tuo file è stato caricato con successo."
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:70
|
||||
msgid "Your password has been changed."
|
||||
msgstr "La tua password è stata modificata."
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -31,17 +31,17 @@ msgstr "{0}"
|
||||
#. placeholder {1}: board?.name ?? t`Board`
|
||||
#. placeholder {1}: workspace.name ?? t`Workspace`
|
||||
#: src/views/boards/index.tsx:22
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/card/index.tsx:216
|
||||
msgid "{0} | {1}"
|
||||
msgstr "{0} | {1}"
|
||||
|
||||
#. placeholder {0}: labelPublicIds.length
|
||||
#: src/views/board/components/NewCardForm.tsx:443
|
||||
#: src/views/board/components/NewCardForm.tsx:442
|
||||
msgid "{0} labels"
|
||||
msgstr "{0} labels"
|
||||
|
||||
#. placeholder {0}: isTemplate ? "Template" : "Board"
|
||||
#: src/views/board/index.tsx:389
|
||||
#: src/views/board/index.tsx:387
|
||||
msgid "{0} not found"
|
||||
msgstr "{0} niet gevonden"
|
||||
|
||||
@@ -79,8 +79,8 @@ msgstr "Account"
|
||||
msgid "Account deleted"
|
||||
msgstr "Account verwijderd"
|
||||
|
||||
#: src/views/card/index.tsx:308
|
||||
#: src/views/public/board/CardModal.tsx:157
|
||||
#: src/views/card/index.tsx:291
|
||||
#: src/views/public/board/CardModal.tsx:143
|
||||
msgid "Activity"
|
||||
msgstr "Activiteit"
|
||||
|
||||
@@ -109,7 +109,7 @@ msgstr "Voeg een item toe..."
|
||||
msgid "Add checklist"
|
||||
msgstr "Checklist toevoegen"
|
||||
|
||||
#: src/components/Editor.tsx:451
|
||||
#: src/components/Editor.tsx:442
|
||||
msgid "Add description... (type '/' to open commands or '@' to mention)"
|
||||
msgstr "Beschrijving toevoegen... (typ '/' om commando's te openen of '@' om te vermelden)"
|
||||
|
||||
@@ -270,10 +270,6 @@ msgstr "heeft <0>{0}</0> aan de kaart toegewezen"
|
||||
msgid "Assignees"
|
||||
msgstr "Toegewezen personen"
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:25
|
||||
msgid "Attachment uploaded"
|
||||
msgstr "Bijlage geüpload"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:47
|
||||
msgid "Awaiting Customer"
|
||||
msgstr "Wachten op klant"
|
||||
@@ -308,9 +304,9 @@ msgstr "Factureringsportaal"
|
||||
msgid "Blog Post"
|
||||
msgstr "Blogbericht"
|
||||
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/public/board/index.tsx:101
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/card/index.tsx:216
|
||||
#: src/views/public/board/index.tsx:100
|
||||
msgid "Board"
|
||||
msgstr "Bord"
|
||||
|
||||
@@ -327,7 +323,7 @@ msgstr "Bordnaam mag niet langer zijn dan 100 tekens"
|
||||
msgid "Board name is required"
|
||||
msgstr "Bordnaam is verplicht"
|
||||
|
||||
#: src/views/public/board/index.tsx:153
|
||||
#: src/views/public/board/index.tsx:151
|
||||
msgid "Board not found"
|
||||
msgstr "Bord niet gevonden"
|
||||
|
||||
@@ -335,19 +331,19 @@ msgstr "Bord niet gevonden"
|
||||
msgid "Board sharing & invites"
|
||||
msgstr "Bord delen & uitnodigingen"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:46
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:45
|
||||
msgid "Board URL can only contain letters, numbers, and hyphens"
|
||||
msgstr "Board URL kan alleen letters, cijfers en koppeltekens bevatten"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:44
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:43
|
||||
msgid "Board URL cannot exceed 60 characters"
|
||||
msgstr "Board URL mag niet langer zijn dan 60 tekens"
|
||||
|
||||
#: src/views/public/board/index.tsx:68
|
||||
#: src/views/public/board/index.tsx:67
|
||||
msgid "Board URL copied to clipboard"
|
||||
msgstr "Board URL gekopieerd naar klembord"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:42
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:41
|
||||
msgid "Board URL must be at least 3 characters long"
|
||||
msgstr "Board URL moet minimaal 3 tekens lang zijn"
|
||||
|
||||
@@ -356,7 +352,7 @@ msgstr "Board URL moet minimaal 3 tekens lang zijn"
|
||||
msgid "Board visibility"
|
||||
msgstr "Bordzichtbaarheid"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:46
|
||||
#: src/views/board/components/VisibilityButton.tsx:45
|
||||
msgid "Board visibility updated"
|
||||
msgstr "Zichtbaarheid van bord bijgewerkt"
|
||||
|
||||
@@ -391,15 +387,15 @@ msgstr "Bugrapport"
|
||||
msgid "Cancel"
|
||||
msgstr "Annuleren"
|
||||
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/card/index.tsx:216
|
||||
msgid "Card"
|
||||
msgstr "Kaart"
|
||||
|
||||
#: src/views/card/index.tsx:264
|
||||
#: src/views/card/index.tsx:262
|
||||
msgid "Card not found"
|
||||
msgstr "Kaart niet gevonden"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:310
|
||||
#: src/views/board/components/NewCardForm.tsx:309
|
||||
msgid "Card title"
|
||||
msgstr "Kaarttitel"
|
||||
|
||||
@@ -432,7 +428,7 @@ msgstr "Naam checklist"
|
||||
msgid "Checklists"
|
||||
msgstr "Checklists"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:180
|
||||
#: src/views/board/components/Filters.tsx:155
|
||||
msgid "Clear filters"
|
||||
msgstr "Filters wissen"
|
||||
|
||||
@@ -523,7 +519,7 @@ msgstr "Neem contact op"
|
||||
msgid "Content Creation"
|
||||
msgstr "Content creatie"
|
||||
|
||||
#: src/components/AuthForm.tsx:434
|
||||
#: src/components/AuthForm.tsx:420
|
||||
msgid "Continue with "
|
||||
msgstr "Doorgaan met "
|
||||
|
||||
@@ -546,8 +542,8 @@ msgid "Create {0}"
|
||||
msgstr "{0} maken"
|
||||
|
||||
#: src/components/LabelForm.tsx:213
|
||||
#: src/views/board/components/NewCardForm.tsx:469
|
||||
#: src/views/board/components/NewListForm.tsx:141
|
||||
#: src/views/board/components/NewCardForm.tsx:468
|
||||
#: src/views/board/components/NewListForm.tsx:140
|
||||
msgid "Create another"
|
||||
msgstr "Maak nog een"
|
||||
|
||||
@@ -555,7 +551,7 @@ msgstr "Maak nog een"
|
||||
msgid "Create API key"
|
||||
msgstr "API-sleutel aanmaken"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:479
|
||||
#: src/views/board/components/NewCardForm.tsx:478
|
||||
msgid "Create card"
|
||||
msgstr "Maak kaart"
|
||||
|
||||
@@ -571,7 +567,7 @@ msgstr "Uitnodigingslink maken"
|
||||
msgid "Create label"
|
||||
msgstr "Maak label"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:153
|
||||
#: src/views/board/components/NewListForm.tsx:152
|
||||
msgid "Create list"
|
||||
msgstr "Lijst maken"
|
||||
|
||||
@@ -584,12 +580,12 @@ msgstr "Nieuwe {0} maken"
|
||||
msgid "Create new key"
|
||||
msgstr "Nieuwe sleutel aanmaken"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:405
|
||||
#: src/views/board/components/NewCardForm.tsx:404
|
||||
#: src/views/card/components/LabelSelector.tsx:97
|
||||
msgid "Create new label"
|
||||
msgstr "Maak nieuw label"
|
||||
|
||||
#: src/views/board/index.tsx:478
|
||||
#: src/views/board/index.tsx:475
|
||||
msgid "Create new list"
|
||||
msgstr "Maak nieuwe lijst"
|
||||
|
||||
@@ -773,12 +769,8 @@ msgstr "Heb je geen account? <0><1>Registreer je</1></0>"
|
||||
msgid "Done"
|
||||
msgstr "Klaar"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:141
|
||||
msgid "Download failed"
|
||||
msgstr "Download mislukt"
|
||||
|
||||
#: src/views/board/components/BoardDropdown.tsx:41
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:116
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:115
|
||||
msgid "Edit board URL"
|
||||
msgstr "Board URL bewerken"
|
||||
|
||||
@@ -790,7 +782,7 @@ msgstr "Reactie bewerken"
|
||||
msgid "Edit label"
|
||||
msgstr "Label bewerken"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:162
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:161
|
||||
msgid "Edit workspace URL"
|
||||
msgstr "Werkruimte-URL bewerken"
|
||||
|
||||
@@ -798,7 +790,7 @@ msgstr "Werkruimte-URL bewerken"
|
||||
msgid "Editing"
|
||||
msgstr "Bewerken"
|
||||
|
||||
#: src/components/AuthForm.tsx:435
|
||||
#: src/components/AuthForm.tsx:421
|
||||
msgid "email"
|
||||
msgstr "e-mail"
|
||||
|
||||
@@ -818,11 +810,11 @@ msgstr "Voer je huidige wachtwoord in"
|
||||
msgid "Enter your current password and choose a new secure password."
|
||||
msgstr "Voer je huidige wachtwoord in en kies een nieuw veilig wachtwoord."
|
||||
|
||||
#: src/components/AuthForm.tsx:398
|
||||
#: src/components/AuthForm.tsx:387
|
||||
msgid "Enter your email address"
|
||||
msgstr "Voer je e-mailadres in"
|
||||
|
||||
#: src/components/AuthForm.tsx:384
|
||||
#: src/components/AuthForm.tsx:375
|
||||
msgid "Enter your name"
|
||||
msgstr "Voer je naam in"
|
||||
|
||||
@@ -830,7 +822,7 @@ msgstr "Voer je naam in"
|
||||
msgid "Enter your new password"
|
||||
msgstr "Voer je nieuwe wachtwoord in"
|
||||
|
||||
#: src/components/AuthForm.tsx:411
|
||||
#: src/components/AuthForm.tsx:400
|
||||
msgid "Enter your password"
|
||||
msgstr "Voer je wachtwoord in"
|
||||
|
||||
@@ -939,11 +931,6 @@ msgstr "Bord maken mislukt"
|
||||
msgid "Failed to login with {0}. Please try again."
|
||||
msgstr "Inloggen met {0} is mislukt. Probeer het opnieuw."
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:33
|
||||
#: src/views/card/components/AttachmentUpload.tsx:79
|
||||
msgid "Failed to upload attachment. Please try again."
|
||||
msgstr "Bijlage uploaden mislukt. Probeer het opnieuw."
|
||||
|
||||
#: src/views/home/components/Header.tsx:41
|
||||
msgid "FAQ"
|
||||
msgstr "FAQ"
|
||||
@@ -987,7 +974,7 @@ msgstr "Feedback"
|
||||
msgid "Feedback sent"
|
||||
msgstr "Feedback verzonden"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:174
|
||||
#: src/views/board/components/Filters.tsx:149
|
||||
msgid "Filter"
|
||||
msgstr "Filter"
|
||||
|
||||
@@ -1000,8 +987,6 @@ msgid "For long-term sustainability, we recognise all good open source projects
|
||||
msgstr "Voor duurzaamheid op lange termijn erkennen we dat alle goede open source projecten een inkomstenbron nodig hebben. De onze komt van de betaalde cloudoplossing voor werkruimtes met meerdere gebruikers en voor aangepaste werkruimte-slugs. Er is geen verplichting om het te gebruiken, en je kunt de software gratis op je eigen infrastructuur hosten."
|
||||
|
||||
#: src/views/pricing/components/Pricing.tsx:32
|
||||
#: src/views/pricing/components/Pricing.tsx:32
|
||||
#: src/views/pricing/components/PricingTiers.tsx:30
|
||||
#: src/views/pricing/components/PricingTiers.tsx:30
|
||||
msgid "Free"
|
||||
msgstr "Gratis"
|
||||
@@ -1043,7 +1028,7 @@ msgstr "Aan de slag"
|
||||
msgid "Get started by creating a new {0}"
|
||||
msgstr "Begin door een nieuwe {0} te maken"
|
||||
|
||||
#: src/views/board/index.tsx:470
|
||||
#: src/views/board/index.tsx:467
|
||||
msgid "Get started by creating a new list"
|
||||
msgstr "Begin door een nieuwe lijst te maken"
|
||||
|
||||
@@ -1257,9 +1242,9 @@ msgstr "Kanban opnieuw uitgevonden"
|
||||
msgid "Keep in mind that this action is irreversible."
|
||||
msgstr "Houd er rekening mee dat deze actie onomkeerbaar is."
|
||||
|
||||
#: src/views/board/components/Filters.tsx:115
|
||||
#: src/views/board/components/NewCardForm.tsx:409
|
||||
#: src/views/card/index.tsx:119
|
||||
#: src/views/board/components/Filters.tsx:101
|
||||
#: src/views/board/components/NewCardForm.tsx:408
|
||||
#: src/views/card/index.tsx:117
|
||||
msgid "Labels"
|
||||
msgstr "Labels"
|
||||
|
||||
@@ -1309,22 +1294,18 @@ msgstr "Licentie"
|
||||
msgid "Light"
|
||||
msgstr "Licht"
|
||||
|
||||
#: src/views/public/board/index.tsx:66
|
||||
#: src/views/public/board/index.tsx:65
|
||||
msgid "Link copied"
|
||||
msgstr "Link gekopieerd"
|
||||
|
||||
#: src/views/card/index.tsx:111
|
||||
#: src/views/card/index.tsx:109
|
||||
msgid "List"
|
||||
msgstr "Lijst"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:129
|
||||
#: src/views/board/components/NewListForm.tsx:128
|
||||
msgid "List name"
|
||||
msgstr "Lijstnaam"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:123
|
||||
msgid "Lists"
|
||||
msgstr "Lijsten"
|
||||
|
||||
#: src/views/auth/login/index.tsx:33
|
||||
msgid "Login | kan.bn"
|
||||
msgstr "Login | kan.bn"
|
||||
@@ -1345,7 +1326,7 @@ msgstr "Geliefd door teams wereldwijd"
|
||||
msgid "Low Priority"
|
||||
msgstr "Lage prioriteit"
|
||||
|
||||
#: src/components/AuthForm.tsx:435
|
||||
#: src/components/AuthForm.tsx:421
|
||||
msgid "magic link"
|
||||
msgstr "magische link"
|
||||
|
||||
@@ -1367,9 +1348,9 @@ msgid "Medium Priority"
|
||||
msgstr "Gemiddelde prioriteit"
|
||||
|
||||
#: src/components/SideNavigation.tsx:101
|
||||
#: src/views/board/components/Filters.tsx:107
|
||||
#: src/views/board/components/NewCardForm.tsx:367
|
||||
#: src/views/card/index.tsx:128
|
||||
#: src/views/board/components/Filters.tsx:93
|
||||
#: src/views/board/components/NewCardForm.tsx:366
|
||||
#: src/views/card/index.tsx:126
|
||||
#: src/views/members/index.tsx:178
|
||||
msgid "Members"
|
||||
msgstr "Leden"
|
||||
@@ -1422,7 +1403,7 @@ msgstr "Nieuwe {0}"
|
||||
msgid "New API key"
|
||||
msgstr "Nieuwe API-sleutel"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:293
|
||||
#: src/views/board/components/NewCardForm.tsx:292
|
||||
msgid "New card"
|
||||
msgstr "Nieuwe kaart"
|
||||
|
||||
@@ -1438,8 +1419,8 @@ msgstr "Nieuwe import"
|
||||
msgid "New label"
|
||||
msgstr "Nieuw label"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:113
|
||||
#: src/views/board/index.tsx:442
|
||||
#: src/views/board/components/NewListForm.tsx:112
|
||||
#: src/views/board/index.tsx:439
|
||||
msgid "New list"
|
||||
msgstr "Nieuwe lijst"
|
||||
|
||||
@@ -1476,10 +1457,6 @@ msgstr "Volgende stappen"
|
||||
msgid "No {0}"
|
||||
msgstr "Geen {0}"
|
||||
|
||||
#: src/components/AuthForm.tsx:365
|
||||
msgid "No authentication methods are currently available"
|
||||
msgstr "Er zijn momenteel geen authenticatiemethoden beschikbaar"
|
||||
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:242
|
||||
msgid "No boards found"
|
||||
msgstr "Geen borden gevonden"
|
||||
@@ -1488,11 +1465,7 @@ msgstr "Geen borden gevonden"
|
||||
msgid "No credit card required"
|
||||
msgstr "Geen creditcard vereist"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:142
|
||||
msgid "No download URL available for this attachment."
|
||||
msgstr "Geen download-URL beschikbaar voor deze bijlage."
|
||||
|
||||
#: src/views/board/index.tsx:467
|
||||
#: src/views/board/index.tsx:464
|
||||
msgid "No lists"
|
||||
msgstr "Geen lijsten"
|
||||
|
||||
@@ -1524,7 +1497,7 @@ msgstr "Open source"
|
||||
msgid "Open Source Friends"
|
||||
msgstr "Open Source Vrienden"
|
||||
|
||||
#: src/components/AuthForm.tsx:374
|
||||
#: src/components/AuthForm.tsx:365
|
||||
msgid "or"
|
||||
msgstr "of"
|
||||
|
||||
@@ -1606,15 +1579,15 @@ msgstr "Platform"
|
||||
msgid "Please confirm your new password"
|
||||
msgstr "Bevestig je nieuwe wachtwoord"
|
||||
|
||||
#: src/components/AuthForm.tsx:402
|
||||
#: src/components/AuthForm.tsx:391
|
||||
msgid "Please enter a valid email address"
|
||||
msgstr "Voer een geldig e-mailadres in"
|
||||
|
||||
#: src/components/AuthForm.tsx:388
|
||||
#: src/components/AuthForm.tsx:379
|
||||
msgid "Please enter a valid name"
|
||||
msgstr "Voer een geldige naam in"
|
||||
|
||||
#: src/components/AuthForm.tsx:416
|
||||
#: src/components/AuthForm.tsx:404
|
||||
msgid "Please enter a valid password"
|
||||
msgstr "Voer een geldig wachtwoord in"
|
||||
|
||||
@@ -1625,16 +1598,15 @@ msgstr "Selecteer een bestand om te uploaden."
|
||||
#: src/components/DeleteLabelConfirmation.tsx:26
|
||||
#: src/components/FeedbackModal.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:158
|
||||
#: src/views/board/components/NewCardForm.tsx:177
|
||||
#: src/views/board/components/NewListForm.tsx:79
|
||||
#: src/views/board/components/NewCardForm.tsx:176
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/NewTemplateForm.tsx:61
|
||||
#: src/views/board/components/NewTemplateForm.tsx:77
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:73
|
||||
#: src/views/board/components/VisibilityButton.tsx:54
|
||||
#: src/views/board/index.tsx:151
|
||||
#: src/views/board/index.tsx:207
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
#: src/views/board/components/VisibilityButton.tsx:53
|
||||
#: src/views/board/index.tsx:149
|
||||
#: src/views/board/index.tsx:205
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:205
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:73
|
||||
#: src/views/card/components/ChecklistItemRow.tsx:60
|
||||
#: src/views/card/components/ChecklistItemRow.tsx:88
|
||||
#: src/views/card/components/ChecklistNameInput.tsx:46
|
||||
@@ -1648,7 +1620,7 @@ msgstr "Selecteer een bestand om te uploaden."
|
||||
#: src/views/card/components/NewChecklistForm.tsx:70
|
||||
#: src/views/card/components/NewChecklistItemForm.tsx:89
|
||||
#: src/views/card/components/NewCommentForm.tsx:31
|
||||
#: src/views/card/index.tsx:177
|
||||
#: src/views/card/index.tsx:175
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
#: src/views/members/components/InviteMemberForm.tsx:241
|
||||
@@ -1692,7 +1664,7 @@ msgstr "Prioriteit e-mailondersteuning"
|
||||
msgid "Privacy policy"
|
||||
msgstr "Privacybeleid"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:74
|
||||
#: src/views/board/components/VisibilityButton.tsx:73
|
||||
msgid "Private"
|
||||
msgstr "Privé"
|
||||
|
||||
@@ -1712,7 +1684,7 @@ msgstr "Profielafbeelding bijgewerkt"
|
||||
msgid "Profile picture"
|
||||
msgstr "Profielfoto"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:69
|
||||
#: src/views/board/components/VisibilityButton.tsx:68
|
||||
msgid "Public"
|
||||
msgstr "Openbaar"
|
||||
|
||||
@@ -1914,7 +1886,7 @@ msgstr "Registreren uitgeschakeld"
|
||||
msgid "Sign up is currently disabled. Please try again later."
|
||||
msgstr "Registreren is momenteel uitgeschakeld. Probeer het later opnieuw."
|
||||
|
||||
#: src/components/AuthForm.tsx:434
|
||||
#: src/components/AuthForm.tsx:420
|
||||
msgid "Sign up with "
|
||||
msgstr "Registreren met "
|
||||
|
||||
@@ -1981,8 +1953,8 @@ msgstr "Teamplan"
|
||||
msgid "Teams"
|
||||
msgstr "Teams"
|
||||
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/board/index.tsx:398
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/board/index.tsx:396
|
||||
msgid "Template"
|
||||
msgstr "Sjabloon"
|
||||
|
||||
@@ -2032,7 +2004,7 @@ msgid "The open source <0/> alternative to Trello"
|
||||
msgstr "Het open source <0/> alternatief voor Trello"
|
||||
|
||||
#. placeholder {0}: isPublic ? "public" : "private"
|
||||
#: src/views/board/components/VisibilityButton.tsx:47
|
||||
#: src/views/board/components/VisibilityButton.tsx:46
|
||||
msgid "The visibility of your board has been set to {0}."
|
||||
msgstr "De zichtbaarheid van je bord is ingesteld op {0}."
|
||||
|
||||
@@ -2056,11 +2028,11 @@ msgstr "Deze actie kan niet ongedaan worden gemaakt."
|
||||
msgid "This API key will only be shown once. Please save it in a secure location."
|
||||
msgstr "Deze API-sleutel wordt slechts één keer getoond. Bewaar deze op een veilige plaats."
|
||||
|
||||
#: src/views/public/board/index.tsx:156
|
||||
#: src/views/public/board/index.tsx:154
|
||||
msgid "This board is private or does not exist"
|
||||
msgstr "Dit bord is privé of bestaat niet"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:136
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:135
|
||||
msgid "This board URL has already been taken"
|
||||
msgstr "Deze board URL is al in gebruik"
|
||||
|
||||
@@ -2130,7 +2102,7 @@ msgstr "Kan checklistitem niet toevoegen"
|
||||
msgid "Unable to add comment"
|
||||
msgstr "Kan geen reactie toevoegen"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:174
|
||||
#: src/views/board/components/NewCardForm.tsx:173
|
||||
msgid "Unable to create card"
|
||||
msgstr "Kan kaart niet aanmaken"
|
||||
|
||||
@@ -2138,7 +2110,7 @@ msgstr "Kan kaart niet aanmaken"
|
||||
msgid "Unable to create checklist"
|
||||
msgstr "Kan checklist niet maken"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/NewListForm.tsx:77
|
||||
msgid "Unable to create list"
|
||||
msgstr "Kan geen lijst maken"
|
||||
|
||||
@@ -2151,10 +2123,6 @@ msgstr "Kan sjabloon niet maken"
|
||||
msgid "Unable to create workspace"
|
||||
msgstr "Kan werkruimte niet aanmaken"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:72
|
||||
msgid "Unable to delete attachment"
|
||||
msgstr "Kan bijlage niet verwijderen"
|
||||
|
||||
#: src/views/card/components/DeleteCardConfirmation.tsx:51
|
||||
msgid "Unable to delete card"
|
||||
msgstr "Kan kaart niet verwijderen"
|
||||
@@ -2179,16 +2147,16 @@ msgstr "Kan lid niet verwijderen"
|
||||
msgid "Unable to send feedback"
|
||||
msgstr "Feedback kon niet worden verzonden"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:71
|
||||
msgid "Unable to update board URL"
|
||||
msgstr "Kan board URL niet bijwerken"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:53
|
||||
#: src/views/board/components/VisibilityButton.tsx:52
|
||||
msgid "Unable to update board visibility"
|
||||
msgstr "Kan bordzichtbaarheid niet bijwerken"
|
||||
|
||||
#: src/views/board/index.tsx:206
|
||||
#: src/views/card/index.tsx:176
|
||||
#: src/views/board/index.tsx:204
|
||||
#: src/views/card/index.tsx:174
|
||||
msgid "Unable to update card"
|
||||
msgstr "Kan kaart niet bijwerken"
|
||||
|
||||
@@ -2208,7 +2176,7 @@ msgstr "Kan reactie niet bijwerken"
|
||||
msgid "Unable to update labels"
|
||||
msgstr "Kan labels niet bijwerken"
|
||||
|
||||
#: src/views/board/index.tsx:150
|
||||
#: src/views/board/index.tsx:148
|
||||
#: src/views/card/components/ListSelector.tsx:51
|
||||
msgid "Unable to update list"
|
||||
msgstr "Kan lijst niet bijwerken"
|
||||
@@ -2264,7 +2232,7 @@ msgstr "Onbeperkt aantal leden"
|
||||
msgid "Unlimited workspaces"
|
||||
msgstr "Onbeperkte werkruimtes"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:175
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
|
||||
#: src/views/settings/components/UpdateDisplayNameForm.tsx:80
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:91
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:83
|
||||
@@ -2303,11 +2271,6 @@ msgstr "Upgraden naar Pro"
|
||||
msgid "Upgrade to Pro ($29/month)"
|
||||
msgstr "Upgrade naar Pro ($29/maand)"
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:32
|
||||
#: src/views/card/components/AttachmentUpload.tsx:78
|
||||
msgid "Upload failed"
|
||||
msgstr "Uploaden mislukt"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:38
|
||||
#: src/views/boards/components/TemplateBoards.tsx:55
|
||||
msgid "Urgent"
|
||||
@@ -2357,7 +2320,7 @@ msgstr "Bekijk en beheer je facturering en abonnement."
|
||||
msgid "View docs"
|
||||
msgstr "Bekijk documentatie"
|
||||
|
||||
#: src/views/public/board/index.tsx:129
|
||||
#: src/views/public/board/index.tsx:128
|
||||
msgid "View only"
|
||||
msgstr "Alleen bekijken"
|
||||
|
||||
@@ -2365,11 +2328,11 @@ msgstr "Alleen bekijken"
|
||||
msgid "View our roadmap."
|
||||
msgstr "Bekijk onze roadmap."
|
||||
|
||||
#: src/views/public/board/index.tsx:159
|
||||
#: src/views/public/board/index.tsx:157
|
||||
msgid "View workspace"
|
||||
msgstr "Werkruimte bekijken"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:92
|
||||
#: src/views/board/components/VisibilityButton.tsx:91
|
||||
msgid "Visibility"
|
||||
msgstr "Zichtbaarheid"
|
||||
|
||||
@@ -2406,10 +2369,10 @@ msgid "Why make an open source Trello?"
|
||||
msgstr "Waarom een open source Trello maken?"
|
||||
|
||||
#: src/components/SettingsLayout.tsx:39
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/boards/index.tsx:22
|
||||
#: src/views/members/index.tsx:173
|
||||
#: src/views/public/board/index.tsx:101
|
||||
#: src/views/public/board/index.tsx:100
|
||||
#: src/views/public/boards/index.tsx:66
|
||||
msgid "Workspace"
|
||||
msgstr "Werkruimte"
|
||||
@@ -2539,10 +2502,6 @@ msgstr "Je borden zijn geïmporteerd."
|
||||
msgid "Your display name has been updated."
|
||||
msgstr "Je weergavenaam is bijgewerkt."
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:26
|
||||
msgid "Your file has been uploaded successfully."
|
||||
msgstr "Je bestand is succesvol geüpload."
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:70
|
||||
msgid "Your password has been changed."
|
||||
msgstr "Je wachtwoord is gewijzigd."
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -36,17 +36,17 @@ msgstr "{0}"
|
||||
#. placeholder {1}: board?.name ?? t`Board`
|
||||
#. placeholder {1}: workspace.name ?? t`Workspace`
|
||||
#: src/views/boards/index.tsx:22
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/card/index.tsx:216
|
||||
msgid "{0} | {1}"
|
||||
msgstr "{0} | {1}"
|
||||
|
||||
#. placeholder {0}: labelPublicIds.length
|
||||
#: src/views/board/components/NewCardForm.tsx:443
|
||||
#: src/views/board/components/NewCardForm.tsx:442
|
||||
msgid "{0} labels"
|
||||
msgstr "{0} etykiety"
|
||||
|
||||
#. placeholder {0}: isTemplate ? "Template" : "Board"
|
||||
#: src/views/board/index.tsx:389
|
||||
#: src/views/board/index.tsx:387
|
||||
msgid "{0} not found"
|
||||
msgstr "{0} nie znaleziono"
|
||||
|
||||
@@ -84,8 +84,8 @@ msgstr "Konto"
|
||||
msgid "Account deleted"
|
||||
msgstr "Konto zostało usunięte"
|
||||
|
||||
#: src/views/card/index.tsx:308
|
||||
#: src/views/public/board/CardModal.tsx:157
|
||||
#: src/views/card/index.tsx:291
|
||||
#: src/views/public/board/CardModal.tsx:143
|
||||
msgid "Activity"
|
||||
msgstr "Aktywność"
|
||||
|
||||
@@ -114,7 +114,7 @@ msgstr "Dodaj element..."
|
||||
msgid "Add checklist"
|
||||
msgstr "Dodaj listę kontrolną"
|
||||
|
||||
#: src/components/Editor.tsx:451
|
||||
#: src/components/Editor.tsx:442
|
||||
msgid "Add description... (type '/' to open commands or '@' to mention)"
|
||||
msgstr "Dodaj opis... (wpisz '/' aby otworzyć polecenia lub '@' aby wspomnieć)"
|
||||
|
||||
@@ -275,10 +275,6 @@ msgstr "przypisano <0>{0}</0> do karty"
|
||||
msgid "Assignees"
|
||||
msgstr "Osoby przypisane"
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:25
|
||||
msgid "Attachment uploaded"
|
||||
msgstr "Załącznik został przesłany"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:47
|
||||
msgid "Awaiting Customer"
|
||||
msgstr "Oczekuje na klienta"
|
||||
@@ -313,9 +309,9 @@ msgstr "Portal rozliczeniowy"
|
||||
msgid "Blog Post"
|
||||
msgstr "Post na blogu"
|
||||
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/public/board/index.tsx:101
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/card/index.tsx:216
|
||||
#: src/views/public/board/index.tsx:100
|
||||
msgid "Board"
|
||||
msgstr "Tablica"
|
||||
|
||||
@@ -332,7 +328,7 @@ msgstr "Nazwa tablicy nie może przekraczać 100 znaków"
|
||||
msgid "Board name is required"
|
||||
msgstr "Nazwa tablicy jest wymagana"
|
||||
|
||||
#: src/views/public/board/index.tsx:153
|
||||
#: src/views/public/board/index.tsx:151
|
||||
msgid "Board not found"
|
||||
msgstr "Tablica nie została znaleziona"
|
||||
|
||||
@@ -340,19 +336,19 @@ msgstr "Tablica nie została znaleziona"
|
||||
msgid "Board sharing & invites"
|
||||
msgstr "Udostępnianie tablicy i zaproszenia"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:46
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:45
|
||||
msgid "Board URL can only contain letters, numbers, and hyphens"
|
||||
msgstr "Adres URL tablicy może zawierać tylko litery, cyfry i myślniki"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:44
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:43
|
||||
msgid "Board URL cannot exceed 60 characters"
|
||||
msgstr "Adres URL tablicy nie może przekraczać 60 znaków"
|
||||
|
||||
#: src/views/public/board/index.tsx:68
|
||||
#: src/views/public/board/index.tsx:67
|
||||
msgid "Board URL copied to clipboard"
|
||||
msgstr "Adres URL tablicy został skopiowany do schowka"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:42
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:41
|
||||
msgid "Board URL must be at least 3 characters long"
|
||||
msgstr "Adres URL tablicy musi mieć co najmniej 3 znaki"
|
||||
|
||||
@@ -361,7 +357,7 @@ msgstr "Adres URL tablicy musi mieć co najmniej 3 znaki"
|
||||
msgid "Board visibility"
|
||||
msgstr "Widoczność tablicy"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:46
|
||||
#: src/views/board/components/VisibilityButton.tsx:45
|
||||
msgid "Board visibility updated"
|
||||
msgstr "Widoczność tablicy została zaktualizowana"
|
||||
|
||||
@@ -396,15 +392,15 @@ msgstr "Zgłoszenie błędu"
|
||||
msgid "Cancel"
|
||||
msgstr "Anuluj"
|
||||
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/card/index.tsx:216
|
||||
msgid "Card"
|
||||
msgstr "Karta"
|
||||
|
||||
#: src/views/card/index.tsx:264
|
||||
#: src/views/card/index.tsx:262
|
||||
msgid "Card not found"
|
||||
msgstr "Nie można było znaleźć karty"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:310
|
||||
#: src/views/board/components/NewCardForm.tsx:309
|
||||
msgid "Card title"
|
||||
msgstr "Tytuł karty"
|
||||
|
||||
@@ -437,7 +433,7 @@ msgstr "Nazwa listy kontrolnej"
|
||||
msgid "Checklists"
|
||||
msgstr "Listy kontrolne"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:180
|
||||
#: src/views/board/components/Filters.tsx:155
|
||||
msgid "Clear filters"
|
||||
msgstr "Wyczyść filtry"
|
||||
|
||||
@@ -528,7 +524,7 @@ msgstr "Skontaktuj się z nami"
|
||||
msgid "Content Creation"
|
||||
msgstr "Tworzenie treści"
|
||||
|
||||
#: src/components/AuthForm.tsx:434
|
||||
#: src/components/AuthForm.tsx:420
|
||||
msgid "Continue with "
|
||||
msgstr "Kontynuuj z "
|
||||
|
||||
@@ -551,8 +547,8 @@ msgid "Create {0}"
|
||||
msgstr "Utwórz {0}"
|
||||
|
||||
#: src/components/LabelForm.tsx:213
|
||||
#: src/views/board/components/NewCardForm.tsx:469
|
||||
#: src/views/board/components/NewListForm.tsx:141
|
||||
#: src/views/board/components/NewCardForm.tsx:468
|
||||
#: src/views/board/components/NewListForm.tsx:140
|
||||
msgid "Create another"
|
||||
msgstr "Utwórz kolejny"
|
||||
|
||||
@@ -560,7 +556,7 @@ msgstr "Utwórz kolejny"
|
||||
msgid "Create API key"
|
||||
msgstr "Utwórz klucz API"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:479
|
||||
#: src/views/board/components/NewCardForm.tsx:478
|
||||
msgid "Create card"
|
||||
msgstr "Utwórz kartę"
|
||||
|
||||
@@ -576,7 +572,7 @@ msgstr "Utwórz link zaproszenia"
|
||||
msgid "Create label"
|
||||
msgstr "Utwórz etykietę"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:153
|
||||
#: src/views/board/components/NewListForm.tsx:152
|
||||
msgid "Create list"
|
||||
msgstr "Utwórz listę"
|
||||
|
||||
@@ -589,12 +585,12 @@ msgstr "Utwórz nowy {0}"
|
||||
msgid "Create new key"
|
||||
msgstr "Utwórz nowy klucz"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:405
|
||||
#: src/views/board/components/NewCardForm.tsx:404
|
||||
#: src/views/card/components/LabelSelector.tsx:97
|
||||
msgid "Create new label"
|
||||
msgstr "Utwórz nową etykietę"
|
||||
|
||||
#: src/views/board/index.tsx:478
|
||||
#: src/views/board/index.tsx:475
|
||||
msgid "Create new list"
|
||||
msgstr "Utwórz nową listę"
|
||||
|
||||
@@ -778,12 +774,8 @@ msgstr "Nie masz konta? <0><1>Zarejestruj się</1></0>"
|
||||
msgid "Done"
|
||||
msgstr "Gotowe"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:141
|
||||
msgid "Download failed"
|
||||
msgstr "Pobieranie nie powiodło się"
|
||||
|
||||
#: src/views/board/components/BoardDropdown.tsx:41
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:116
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:115
|
||||
msgid "Edit board URL"
|
||||
msgstr "Edytuj URL tablicy"
|
||||
|
||||
@@ -795,7 +787,7 @@ msgstr "Edytuj komentarz"
|
||||
msgid "Edit label"
|
||||
msgstr "Edytuj etykietę"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:162
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:161
|
||||
msgid "Edit workspace URL"
|
||||
msgstr "Edytuj URL przestrzeni roboczej"
|
||||
|
||||
@@ -803,7 +795,7 @@ msgstr "Edytuj URL przestrzeni roboczej"
|
||||
msgid "Editing"
|
||||
msgstr "Edycja"
|
||||
|
||||
#: src/components/AuthForm.tsx:435
|
||||
#: src/components/AuthForm.tsx:421
|
||||
msgid "email"
|
||||
msgstr "email"
|
||||
|
||||
@@ -823,11 +815,11 @@ msgstr "Wprowadź swoje obecne hasło"
|
||||
msgid "Enter your current password and choose a new secure password."
|
||||
msgstr "Wprowadź swoje obecne hasło i wybierz nowe, bezpieczne hasło."
|
||||
|
||||
#: src/components/AuthForm.tsx:398
|
||||
#: src/components/AuthForm.tsx:387
|
||||
msgid "Enter your email address"
|
||||
msgstr "Wprowadź swój adres e-mail"
|
||||
|
||||
#: src/components/AuthForm.tsx:384
|
||||
#: src/components/AuthForm.tsx:375
|
||||
msgid "Enter your name"
|
||||
msgstr "Wprowadź swoje imię"
|
||||
|
||||
@@ -835,7 +827,7 @@ msgstr "Wprowadź swoje imię"
|
||||
msgid "Enter your new password"
|
||||
msgstr "Wprowadź swoje nowe hasło"
|
||||
|
||||
#: src/components/AuthForm.tsx:411
|
||||
#: src/components/AuthForm.tsx:400
|
||||
msgid "Enter your password"
|
||||
msgstr "Wprowadź swoje hasło"
|
||||
|
||||
@@ -944,11 +936,6 @@ msgstr "Nie udało się utworzyć tablicy"
|
||||
msgid "Failed to login with {0}. Please try again."
|
||||
msgstr "Nie udało się zalogować za pomocą {0}. Spróbuj ponownie."
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:33
|
||||
#: src/views/card/components/AttachmentUpload.tsx:79
|
||||
msgid "Failed to upload attachment. Please try again."
|
||||
msgstr "Nie udało się przesłać załącznika. Proszę spróbować ponownie."
|
||||
|
||||
#: src/views/home/components/Header.tsx:41
|
||||
msgid "FAQ"
|
||||
msgstr "FAQ"
|
||||
@@ -992,7 +979,7 @@ msgstr "Opinie"
|
||||
msgid "Feedback sent"
|
||||
msgstr "Opinia wysłana"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:174
|
||||
#: src/views/board/components/Filters.tsx:149
|
||||
msgid "Filter"
|
||||
msgstr "Filtr"
|
||||
|
||||
@@ -1005,8 +992,6 @@ msgid "For long-term sustainability, we recognise all good open source projects
|
||||
msgstr "Dla długoterminowej trwałości uznajemy, że wszystkie dobre projekty open source potrzebują źródła dochodu. Nasze pochodzi z płatnej oferty w chmurze dla przestrzeni roboczych z wieloma użytkownikami oraz dla niestandardowych nazw przestrzeni roboczych. Nie ma obowiązku korzystania z niej, a oprogramowanie można hostować samodzielnie na własnej infrastrukturze bezpłatnie."
|
||||
|
||||
#: src/views/pricing/components/Pricing.tsx:32
|
||||
#: src/views/pricing/components/Pricing.tsx:32
|
||||
#: src/views/pricing/components/PricingTiers.tsx:30
|
||||
#: src/views/pricing/components/PricingTiers.tsx:30
|
||||
msgid "Free"
|
||||
msgstr "Darmowy"
|
||||
@@ -1048,7 +1033,7 @@ msgstr "Rozpocznij"
|
||||
msgid "Get started by creating a new {0}"
|
||||
msgstr "Rozpocznij, tworząc nowy {0}"
|
||||
|
||||
#: src/views/board/index.tsx:470
|
||||
#: src/views/board/index.tsx:467
|
||||
msgid "Get started by creating a new list"
|
||||
msgstr "Rozpocznij, tworząc nową listę"
|
||||
|
||||
@@ -1262,9 +1247,9 @@ msgstr "Kanban wymyślony na nowo"
|
||||
msgid "Keep in mind that this action is irreversible."
|
||||
msgstr "Pamiętaj, że ta akcja jest nieodwracalna."
|
||||
|
||||
#: src/views/board/components/Filters.tsx:115
|
||||
#: src/views/board/components/NewCardForm.tsx:409
|
||||
#: src/views/card/index.tsx:119
|
||||
#: src/views/board/components/Filters.tsx:101
|
||||
#: src/views/board/components/NewCardForm.tsx:408
|
||||
#: src/views/card/index.tsx:117
|
||||
msgid "Labels"
|
||||
msgstr "Etykiety"
|
||||
|
||||
@@ -1314,22 +1299,18 @@ msgstr "Licencja"
|
||||
msgid "Light"
|
||||
msgstr "Jasny"
|
||||
|
||||
#: src/views/public/board/index.tsx:66
|
||||
#: src/views/public/board/index.tsx:65
|
||||
msgid "Link copied"
|
||||
msgstr "Link skopiowany"
|
||||
|
||||
#: src/views/card/index.tsx:111
|
||||
#: src/views/card/index.tsx:109
|
||||
msgid "List"
|
||||
msgstr "Lista"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:129
|
||||
#: src/views/board/components/NewListForm.tsx:128
|
||||
msgid "List name"
|
||||
msgstr "Nazwa listy"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:123
|
||||
msgid "Lists"
|
||||
msgstr "Listy"
|
||||
|
||||
#: src/views/auth/login/index.tsx:33
|
||||
msgid "Login | kan.bn"
|
||||
msgstr "Zaloguj się | kan.bn"
|
||||
@@ -1350,7 +1331,7 @@ msgstr "Uwielbiane przez zespoły na całym świecie"
|
||||
msgid "Low Priority"
|
||||
msgstr "Niski priorytet"
|
||||
|
||||
#: src/components/AuthForm.tsx:435
|
||||
#: src/components/AuthForm.tsx:421
|
||||
msgid "magic link"
|
||||
msgstr "magiczny link"
|
||||
|
||||
@@ -1372,9 +1353,9 @@ msgid "Medium Priority"
|
||||
msgstr "Średni priorytet"
|
||||
|
||||
#: src/components/SideNavigation.tsx:101
|
||||
#: src/views/board/components/Filters.tsx:107
|
||||
#: src/views/board/components/NewCardForm.tsx:367
|
||||
#: src/views/card/index.tsx:128
|
||||
#: src/views/board/components/Filters.tsx:93
|
||||
#: src/views/board/components/NewCardForm.tsx:366
|
||||
#: src/views/card/index.tsx:126
|
||||
#: src/views/members/index.tsx:178
|
||||
msgid "Members"
|
||||
msgstr "Członkowie"
|
||||
@@ -1427,7 +1408,7 @@ msgstr "Nowy {0}"
|
||||
msgid "New API key"
|
||||
msgstr "Nowy klucz API"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:293
|
||||
#: src/views/board/components/NewCardForm.tsx:292
|
||||
msgid "New card"
|
||||
msgstr "Nowa karta"
|
||||
|
||||
@@ -1443,8 +1424,8 @@ msgstr "Nowy import"
|
||||
msgid "New label"
|
||||
msgstr "Nowa etykieta"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:113
|
||||
#: src/views/board/index.tsx:442
|
||||
#: src/views/board/components/NewListForm.tsx:112
|
||||
#: src/views/board/index.tsx:439
|
||||
msgid "New list"
|
||||
msgstr "Nowa lista"
|
||||
|
||||
@@ -1481,10 +1462,6 @@ msgstr "Następne kroki"
|
||||
msgid "No {0}"
|
||||
msgstr "Brak {0}"
|
||||
|
||||
#: src/components/AuthForm.tsx:365
|
||||
msgid "No authentication methods are currently available"
|
||||
msgstr "Obecnie brak dostępnych metod uwierzytelniania"
|
||||
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:242
|
||||
msgid "No boards found"
|
||||
msgstr "Nie znaleziono tablic"
|
||||
@@ -1493,11 +1470,7 @@ msgstr "Nie znaleziono tablic"
|
||||
msgid "No credit card required"
|
||||
msgstr "Nie wymagana karta kredytowa"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:142
|
||||
msgid "No download URL available for this attachment."
|
||||
msgstr "Brak dostępnego URL do pobrania tego załącznika."
|
||||
|
||||
#: src/views/board/index.tsx:467
|
||||
#: src/views/board/index.tsx:464
|
||||
msgid "No lists"
|
||||
msgstr "Brak list"
|
||||
|
||||
@@ -1529,7 +1502,7 @@ msgstr "Otwartoźródłowe"
|
||||
msgid "Open Source Friends"
|
||||
msgstr "Przyjaciele Open Source"
|
||||
|
||||
#: src/components/AuthForm.tsx:374
|
||||
#: src/components/AuthForm.tsx:365
|
||||
msgid "or"
|
||||
msgstr "lub"
|
||||
|
||||
@@ -1611,15 +1584,15 @@ msgstr "Platforma"
|
||||
msgid "Please confirm your new password"
|
||||
msgstr "Proszę potwierdzić nowe hasło"
|
||||
|
||||
#: src/components/AuthForm.tsx:402
|
||||
#: src/components/AuthForm.tsx:391
|
||||
msgid "Please enter a valid email address"
|
||||
msgstr "Proszę wprowadzić prawidłowy adres e-mail"
|
||||
|
||||
#: src/components/AuthForm.tsx:388
|
||||
#: src/components/AuthForm.tsx:379
|
||||
msgid "Please enter a valid name"
|
||||
msgstr "Proszę wprowadzić poprawne imię"
|
||||
|
||||
#: src/components/AuthForm.tsx:416
|
||||
#: src/components/AuthForm.tsx:404
|
||||
msgid "Please enter a valid password"
|
||||
msgstr "Proszę wprowadzić poprawne hasło"
|
||||
|
||||
@@ -1630,16 +1603,15 @@ msgstr "Proszę wybrać plik do przesłania."
|
||||
#: src/components/DeleteLabelConfirmation.tsx:26
|
||||
#: src/components/FeedbackModal.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:158
|
||||
#: src/views/board/components/NewCardForm.tsx:177
|
||||
#: src/views/board/components/NewListForm.tsx:79
|
||||
#: src/views/board/components/NewCardForm.tsx:176
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/NewTemplateForm.tsx:61
|
||||
#: src/views/board/components/NewTemplateForm.tsx:77
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:73
|
||||
#: src/views/board/components/VisibilityButton.tsx:54
|
||||
#: src/views/board/index.tsx:151
|
||||
#: src/views/board/index.tsx:207
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
#: src/views/board/components/VisibilityButton.tsx:53
|
||||
#: src/views/board/index.tsx:149
|
||||
#: src/views/board/index.tsx:205
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:205
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:73
|
||||
#: src/views/card/components/ChecklistItemRow.tsx:60
|
||||
#: src/views/card/components/ChecklistItemRow.tsx:88
|
||||
#: src/views/card/components/ChecklistNameInput.tsx:46
|
||||
@@ -1653,7 +1625,7 @@ msgstr "Proszę wybrać plik do przesłania."
|
||||
#: src/views/card/components/NewChecklistForm.tsx:70
|
||||
#: src/views/card/components/NewChecklistItemForm.tsx:89
|
||||
#: src/views/card/components/NewCommentForm.tsx:31
|
||||
#: src/views/card/index.tsx:177
|
||||
#: src/views/card/index.tsx:175
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
#: src/views/members/components/InviteMemberForm.tsx:241
|
||||
@@ -1697,7 +1669,7 @@ msgstr "Priorytetowe wsparcie e-mail"
|
||||
msgid "Privacy policy"
|
||||
msgstr "Polityka prywatności"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:74
|
||||
#: src/views/board/components/VisibilityButton.tsx:73
|
||||
msgid "Private"
|
||||
msgstr "Prywatne"
|
||||
|
||||
@@ -1717,7 +1689,7 @@ msgstr "Zaktualizowano zdjęcie profilowe"
|
||||
msgid "Profile picture"
|
||||
msgstr "Zdjęcie profilowe"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:69
|
||||
#: src/views/board/components/VisibilityButton.tsx:68
|
||||
msgid "Public"
|
||||
msgstr "Publiczne"
|
||||
|
||||
@@ -1919,7 +1891,7 @@ msgstr "Rejestracja wyłączona"
|
||||
msgid "Sign up is currently disabled. Please try again later."
|
||||
msgstr "Rejestracja jest obecnie wyłączona. Spróbuj ponownie później."
|
||||
|
||||
#: src/components/AuthForm.tsx:434
|
||||
#: src/components/AuthForm.tsx:420
|
||||
msgid "Sign up with "
|
||||
msgstr "Zarejestruj się za pomocą "
|
||||
|
||||
@@ -1986,8 +1958,8 @@ msgstr "Plan zespołowy"
|
||||
msgid "Teams"
|
||||
msgstr "Zespoły"
|
||||
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/board/index.tsx:398
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/board/index.tsx:396
|
||||
msgid "Template"
|
||||
msgstr "Szablon"
|
||||
|
||||
@@ -2037,7 +2009,7 @@ msgid "The open source <0/> alternative to Trello"
|
||||
msgstr "Otwarta alternatywa <0/> dla Trello"
|
||||
|
||||
#. placeholder {0}: isPublic ? "public" : "private"
|
||||
#: src/views/board/components/VisibilityButton.tsx:47
|
||||
#: src/views/board/components/VisibilityButton.tsx:46
|
||||
msgid "The visibility of your board has been set to {0}."
|
||||
msgstr "Widoczność Twojej tablicy została ustawiona na {0}."
|
||||
|
||||
@@ -2061,11 +2033,11 @@ msgstr "Tej akcji nie można cofnąć."
|
||||
msgid "This API key will only be shown once. Please save it in a secure location."
|
||||
msgstr "Ten klucz API zostanie wyświetlony tylko raz. Proszę zapisać go w bezpiecznym miejscu."
|
||||
|
||||
#: src/views/public/board/index.tsx:156
|
||||
#: src/views/public/board/index.tsx:154
|
||||
msgid "This board is private or does not exist"
|
||||
msgstr "Ta tablica jest prywatna lub nie istnieje"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:136
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:135
|
||||
msgid "This board URL has already been taken"
|
||||
msgstr "Ten adres URL tablicy jest już zajęty"
|
||||
|
||||
@@ -2135,7 +2107,7 @@ msgstr "Nie można dodać elementu listy kontrolnej"
|
||||
msgid "Unable to add comment"
|
||||
msgstr "Nie można dodać komentarza"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:174
|
||||
#: src/views/board/components/NewCardForm.tsx:173
|
||||
msgid "Unable to create card"
|
||||
msgstr "Nie można utworzyć karty"
|
||||
|
||||
@@ -2143,7 +2115,7 @@ msgstr "Nie można utworzyć karty"
|
||||
msgid "Unable to create checklist"
|
||||
msgstr "Nie można utworzyć listy kontrolnej"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/NewListForm.tsx:77
|
||||
msgid "Unable to create list"
|
||||
msgstr "Nie można utworzyć listy"
|
||||
|
||||
@@ -2156,10 +2128,6 @@ msgstr "Nie można utworzyć szablonu"
|
||||
msgid "Unable to create workspace"
|
||||
msgstr "Nie można utworzyć przestrzeni roboczej"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:72
|
||||
msgid "Unable to delete attachment"
|
||||
msgstr "Nie można usunąć załącznika"
|
||||
|
||||
#: src/views/card/components/DeleteCardConfirmation.tsx:51
|
||||
msgid "Unable to delete card"
|
||||
msgstr "Nie można usunąć karty"
|
||||
@@ -2184,16 +2152,16 @@ msgstr "Nie można usunąć członka"
|
||||
msgid "Unable to send feedback"
|
||||
msgstr "Nie można wysłać opinii"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:71
|
||||
msgid "Unable to update board URL"
|
||||
msgstr "Nie można zaktualizować adresu URL tablicy"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:53
|
||||
#: src/views/board/components/VisibilityButton.tsx:52
|
||||
msgid "Unable to update board visibility"
|
||||
msgstr "Nie można zaktualizować widoczności tablicy"
|
||||
|
||||
#: src/views/board/index.tsx:206
|
||||
#: src/views/card/index.tsx:176
|
||||
#: src/views/board/index.tsx:204
|
||||
#: src/views/card/index.tsx:174
|
||||
msgid "Unable to update card"
|
||||
msgstr "Nie można zaktualizować karty"
|
||||
|
||||
@@ -2213,7 +2181,7 @@ msgstr "Nie można zaktualizować komentarza"
|
||||
msgid "Unable to update labels"
|
||||
msgstr "Nie można zaktualizować etykiet"
|
||||
|
||||
#: src/views/board/index.tsx:150
|
||||
#: src/views/board/index.tsx:148
|
||||
#: src/views/card/components/ListSelector.tsx:51
|
||||
msgid "Unable to update list"
|
||||
msgstr "Nie można zaktualizować listy"
|
||||
@@ -2269,7 +2237,7 @@ msgstr "Nieograniczona liczba członków"
|
||||
msgid "Unlimited workspaces"
|
||||
msgstr "Nieograniczona liczba przestrzeni roboczych"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:175
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
|
||||
#: src/views/settings/components/UpdateDisplayNameForm.tsx:80
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:91
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:83
|
||||
@@ -2308,11 +2276,6 @@ msgstr "Ulepsz do planu Pro"
|
||||
msgid "Upgrade to Pro ($29/month)"
|
||||
msgstr "Ulepsz do planu Pro (29 USD/miesiąc)"
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:32
|
||||
#: src/views/card/components/AttachmentUpload.tsx:78
|
||||
msgid "Upload failed"
|
||||
msgstr "Przesyłanie nie powiodło się"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:38
|
||||
#: src/views/boards/components/TemplateBoards.tsx:55
|
||||
msgid "Urgent"
|
||||
@@ -2362,7 +2325,7 @@ msgstr "Zobacz i zarządzaj swoimi płatnościami i subskrypcją."
|
||||
msgid "View docs"
|
||||
msgstr "Zobacz dokumentację"
|
||||
|
||||
#: src/views/public/board/index.tsx:129
|
||||
#: src/views/public/board/index.tsx:128
|
||||
msgid "View only"
|
||||
msgstr "Tylko podgląd"
|
||||
|
||||
@@ -2370,11 +2333,11 @@ msgstr "Tylko podgląd"
|
||||
msgid "View our roadmap."
|
||||
msgstr "Zobacz nasz plan ulepszeń."
|
||||
|
||||
#: src/views/public/board/index.tsx:159
|
||||
#: src/views/public/board/index.tsx:157
|
||||
msgid "View workspace"
|
||||
msgstr "Zobacz obszar roboczy"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:92
|
||||
#: src/views/board/components/VisibilityButton.tsx:91
|
||||
msgid "Visibility"
|
||||
msgstr "Widoczność"
|
||||
|
||||
@@ -2411,10 +2374,10 @@ msgid "Why make an open source Trello?"
|
||||
msgstr "Dlaczego próbujecie stworzyć Trello w wersji otwartoźródłowej?"
|
||||
|
||||
#: src/components/SettingsLayout.tsx:39
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/boards/index.tsx:22
|
||||
#: src/views/members/index.tsx:173
|
||||
#: src/views/public/board/index.tsx:101
|
||||
#: src/views/public/board/index.tsx:100
|
||||
#: src/views/public/boards/index.tsx:66
|
||||
msgid "Workspace"
|
||||
msgstr "Obszar roboczy"
|
||||
@@ -2544,10 +2507,6 @@ msgstr "Twoje tablice zostały zaimportowane."
|
||||
msgid "Your display name has been updated."
|
||||
msgstr "Twoja nazwa wyświetlana została zaktualizowana."
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:26
|
||||
msgid "Your file has been uploaded successfully."
|
||||
msgstr "Twój plik został pomyślnie przesłany."
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:70
|
||||
msgid "Your password has been changed."
|
||||
msgstr "Twoje hasło zostało zmienione."
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -31,17 +31,17 @@ msgstr "{0}"
|
||||
#. placeholder {1}: board?.name ?? t`Board`
|
||||
#. placeholder {1}: workspace.name ?? t`Workspace`
|
||||
#: src/views/boards/index.tsx:22
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/card/index.tsx:216
|
||||
msgid "{0} | {1}"
|
||||
msgstr "{0} | {1}"
|
||||
|
||||
#. placeholder {0}: labelPublicIds.length
|
||||
#: src/views/board/components/NewCardForm.tsx:443
|
||||
#: src/views/board/components/NewCardForm.tsx:442
|
||||
msgid "{0} labels"
|
||||
msgstr "{0} метки"
|
||||
|
||||
#. placeholder {0}: isTemplate ? "Template" : "Board"
|
||||
#: src/views/board/index.tsx:389
|
||||
#: src/views/board/index.tsx:387
|
||||
msgid "{0} not found"
|
||||
msgstr "{0} не найден"
|
||||
|
||||
@@ -79,8 +79,8 @@ msgstr "Аккаунт"
|
||||
msgid "Account deleted"
|
||||
msgstr "Аккаунт удалён"
|
||||
|
||||
#: src/views/card/index.tsx:308
|
||||
#: src/views/public/board/CardModal.tsx:157
|
||||
#: src/views/card/index.tsx:291
|
||||
#: src/views/public/board/CardModal.tsx:143
|
||||
msgid "Activity"
|
||||
msgstr "Активность"
|
||||
|
||||
@@ -109,7 +109,7 @@ msgstr "Добавить элемент..."
|
||||
msgid "Add checklist"
|
||||
msgstr "Добавить чек-лист"
|
||||
|
||||
#: src/components/Editor.tsx:451
|
||||
#: src/components/Editor.tsx:442
|
||||
msgid "Add description... (type '/' to open commands or '@' to mention)"
|
||||
msgstr "Добавить описание... (введите '/' для открытия команд или '@' для упоминания)"
|
||||
|
||||
@@ -270,10 +270,6 @@ msgstr "назначено <0>{0}</0> к карточке"
|
||||
msgid "Assignees"
|
||||
msgstr "Исполнители"
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:25
|
||||
msgid "Attachment uploaded"
|
||||
msgstr "Вложение загружено"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:47
|
||||
msgid "Awaiting Customer"
|
||||
msgstr "Ожидание клиента"
|
||||
@@ -308,9 +304,9 @@ msgstr "Портал выставления счетов"
|
||||
msgid "Blog Post"
|
||||
msgstr "Пост в блоге"
|
||||
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/public/board/index.tsx:101
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/card/index.tsx:216
|
||||
#: src/views/public/board/index.tsx:100
|
||||
msgid "Board"
|
||||
msgstr "Доска"
|
||||
|
||||
@@ -327,7 +323,7 @@ msgstr "Название доски не может превышать 100 си
|
||||
msgid "Board name is required"
|
||||
msgstr "Название доски обязательно"
|
||||
|
||||
#: src/views/public/board/index.tsx:153
|
||||
#: src/views/public/board/index.tsx:151
|
||||
msgid "Board not found"
|
||||
msgstr "Доска не найдена"
|
||||
|
||||
@@ -335,19 +331,19 @@ msgstr "Доска не найдена"
|
||||
msgid "Board sharing & invites"
|
||||
msgstr "Общий доступ к доске и приглашения"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:46
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:45
|
||||
msgid "Board URL can only contain letters, numbers, and hyphens"
|
||||
msgstr "URL доски может содержать только буквы, цифры и дефисы"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:44
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:43
|
||||
msgid "Board URL cannot exceed 60 characters"
|
||||
msgstr "URL доски не может превышать 60 символов"
|
||||
|
||||
#: src/views/public/board/index.tsx:68
|
||||
#: src/views/public/board/index.tsx:67
|
||||
msgid "Board URL copied to clipboard"
|
||||
msgstr "URL доски скопирован в буфер обмена"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:42
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:41
|
||||
msgid "Board URL must be at least 3 characters long"
|
||||
msgstr "URL доски должен содержать не менее 3 символов"
|
||||
|
||||
@@ -356,7 +352,7 @@ msgstr "URL доски должен содержать не менее 3 сим
|
||||
msgid "Board visibility"
|
||||
msgstr "Видимость доски"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:46
|
||||
#: src/views/board/components/VisibilityButton.tsx:45
|
||||
msgid "Board visibility updated"
|
||||
msgstr "Видимость доски обновлена"
|
||||
|
||||
@@ -391,15 +387,15 @@ msgstr "Отчет об ошибке"
|
||||
msgid "Cancel"
|
||||
msgstr "Отмена"
|
||||
|
||||
#: src/views/card/index.tsx:218
|
||||
#: src/views/card/index.tsx:216
|
||||
msgid "Card"
|
||||
msgstr "Карточка"
|
||||
|
||||
#: src/views/card/index.tsx:264
|
||||
#: src/views/card/index.tsx:262
|
||||
msgid "Card not found"
|
||||
msgstr "Карточка не найдена"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:310
|
||||
#: src/views/board/components/NewCardForm.tsx:309
|
||||
msgid "Card title"
|
||||
msgstr "Название карточки"
|
||||
|
||||
@@ -432,7 +428,7 @@ msgstr "Название контрольного списка"
|
||||
msgid "Checklists"
|
||||
msgstr "Контрольные списки"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:180
|
||||
#: src/views/board/components/Filters.tsx:155
|
||||
msgid "Clear filters"
|
||||
msgstr "Очистить фильтры"
|
||||
|
||||
@@ -523,7 +519,7 @@ msgstr "Свяжитесь с нами"
|
||||
msgid "Content Creation"
|
||||
msgstr "Создание контента"
|
||||
|
||||
#: src/components/AuthForm.tsx:434
|
||||
#: src/components/AuthForm.tsx:420
|
||||
msgid "Continue with "
|
||||
msgstr "Продолжить с "
|
||||
|
||||
@@ -546,8 +542,8 @@ msgid "Create {0}"
|
||||
msgstr "Создать {0}"
|
||||
|
||||
#: src/components/LabelForm.tsx:213
|
||||
#: src/views/board/components/NewCardForm.tsx:469
|
||||
#: src/views/board/components/NewListForm.tsx:141
|
||||
#: src/views/board/components/NewCardForm.tsx:468
|
||||
#: src/views/board/components/NewListForm.tsx:140
|
||||
msgid "Create another"
|
||||
msgstr "Создать ещё одну"
|
||||
|
||||
@@ -555,7 +551,7 @@ msgstr "Создать ещё одну"
|
||||
msgid "Create API key"
|
||||
msgstr "Создать API-ключ"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:479
|
||||
#: src/views/board/components/NewCardForm.tsx:478
|
||||
msgid "Create card"
|
||||
msgstr "Создать карточку"
|
||||
|
||||
@@ -571,7 +567,7 @@ msgstr "Создать ссылку-приглашение"
|
||||
msgid "Create label"
|
||||
msgstr "Создать метку"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:153
|
||||
#: src/views/board/components/NewListForm.tsx:152
|
||||
msgid "Create list"
|
||||
msgstr "Создать список"
|
||||
|
||||
@@ -584,12 +580,12 @@ msgstr "Создать новый {0}"
|
||||
msgid "Create new key"
|
||||
msgstr "Создать новый ключ"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:405
|
||||
#: src/views/board/components/NewCardForm.tsx:404
|
||||
#: src/views/card/components/LabelSelector.tsx:97
|
||||
msgid "Create new label"
|
||||
msgstr "Создать новую метку"
|
||||
|
||||
#: src/views/board/index.tsx:478
|
||||
#: src/views/board/index.tsx:475
|
||||
msgid "Create new list"
|
||||
msgstr "Создать новый список"
|
||||
|
||||
@@ -773,12 +769,8 @@ msgstr "Нет аккаунта? <0><1>Зарегистрируйтесь</1></0
|
||||
msgid "Done"
|
||||
msgstr "Готово"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:141
|
||||
msgid "Download failed"
|
||||
msgstr "Не удалось загрузить"
|
||||
|
||||
#: src/views/board/components/BoardDropdown.tsx:41
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:116
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:115
|
||||
msgid "Edit board URL"
|
||||
msgstr "Изменить URL доски"
|
||||
|
||||
@@ -790,7 +782,7 @@ msgstr "Редактировать комментарий"
|
||||
msgid "Edit label"
|
||||
msgstr "Редактировать метку"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:162
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:161
|
||||
msgid "Edit workspace URL"
|
||||
msgstr "Редактировать URL рабочей области"
|
||||
|
||||
@@ -798,7 +790,7 @@ msgstr "Редактировать URL рабочей области"
|
||||
msgid "Editing"
|
||||
msgstr "Редактирование"
|
||||
|
||||
#: src/components/AuthForm.tsx:435
|
||||
#: src/components/AuthForm.tsx:421
|
||||
msgid "email"
|
||||
msgstr "email"
|
||||
|
||||
@@ -818,11 +810,11 @@ msgstr "Введите ваш текущий пароль"
|
||||
msgid "Enter your current password and choose a new secure password."
|
||||
msgstr "Введите ваш текущий пароль и выберите новый безопасный пароль."
|
||||
|
||||
#: src/components/AuthForm.tsx:398
|
||||
#: src/components/AuthForm.tsx:387
|
||||
msgid "Enter your email address"
|
||||
msgstr "Введите ваш адрес электронной почты"
|
||||
|
||||
#: src/components/AuthForm.tsx:384
|
||||
#: src/components/AuthForm.tsx:375
|
||||
msgid "Enter your name"
|
||||
msgstr "Введите ваше имя"
|
||||
|
||||
@@ -830,7 +822,7 @@ msgstr "Введите ваше имя"
|
||||
msgid "Enter your new password"
|
||||
msgstr "Введите ваш новый пароль"
|
||||
|
||||
#: src/components/AuthForm.tsx:411
|
||||
#: src/components/AuthForm.tsx:400
|
||||
msgid "Enter your password"
|
||||
msgstr "Введите ваш пароль"
|
||||
|
||||
@@ -939,11 +931,6 @@ msgstr "Не удалось создать доску"
|
||||
msgid "Failed to login with {0}. Please try again."
|
||||
msgstr "Не удалось войти с {0}. Пожалуйста, попробуйте снова."
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:33
|
||||
#: src/views/card/components/AttachmentUpload.tsx:79
|
||||
msgid "Failed to upload attachment. Please try again."
|
||||
msgstr "Не удалось загрузить вложение. Пожалуйста, попробуйте еще раз."
|
||||
|
||||
#: src/views/home/components/Header.tsx:41
|
||||
msgid "FAQ"
|
||||
msgstr "FAQ"
|
||||
@@ -987,7 +974,7 @@ msgstr "Обратная связь"
|
||||
msgid "Feedback sent"
|
||||
msgstr "Обратная связь отправлена"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:174
|
||||
#: src/views/board/components/Filters.tsx:149
|
||||
msgid "Filter"
|
||||
msgstr "Фильтр"
|
||||
|
||||
@@ -1000,8 +987,6 @@ msgid "For long-term sustainability, we recognise all good open source projects
|
||||
msgstr "Для долгосрочной устойчивости мы признаем, что всем хорошим проектам с открытым исходным кодом необходим источник дохода. Наш доход поступает от платного облачного предложения для рабочих пространств с несколькими пользователями и для пользовательских идентификаторов рабочих пространств. Нет обязательства использовать его, и вы можете самостоятельно разместить программное обеспечение на своей инфраструктуре бесплатно."
|
||||
|
||||
#: src/views/pricing/components/Pricing.tsx:32
|
||||
#: src/views/pricing/components/Pricing.tsx:32
|
||||
#: src/views/pricing/components/PricingTiers.tsx:30
|
||||
#: src/views/pricing/components/PricingTiers.tsx:30
|
||||
msgid "Free"
|
||||
msgstr "Бесплатно"
|
||||
@@ -1043,7 +1028,7 @@ msgstr "Начать"
|
||||
msgid "Get started by creating a new {0}"
|
||||
msgstr "Начните с создания нового {0}"
|
||||
|
||||
#: src/views/board/index.tsx:470
|
||||
#: src/views/board/index.tsx:467
|
||||
msgid "Get started by creating a new list"
|
||||
msgstr "Начните с создания нового списка"
|
||||
|
||||
@@ -1257,9 +1242,9 @@ msgstr "Канбан переосмыслен"
|
||||
msgid "Keep in mind that this action is irreversible."
|
||||
msgstr "Имейте в виду, что это действие необратимо."
|
||||
|
||||
#: src/views/board/components/Filters.tsx:115
|
||||
#: src/views/board/components/NewCardForm.tsx:409
|
||||
#: src/views/card/index.tsx:119
|
||||
#: src/views/board/components/Filters.tsx:101
|
||||
#: src/views/board/components/NewCardForm.tsx:408
|
||||
#: src/views/card/index.tsx:117
|
||||
msgid "Labels"
|
||||
msgstr "Метки"
|
||||
|
||||
@@ -1309,22 +1294,18 @@ msgstr "Лицензия"
|
||||
msgid "Light"
|
||||
msgstr "Светлый"
|
||||
|
||||
#: src/views/public/board/index.tsx:66
|
||||
#: src/views/public/board/index.tsx:65
|
||||
msgid "Link copied"
|
||||
msgstr "Ссылка скопирована"
|
||||
|
||||
#: src/views/card/index.tsx:111
|
||||
#: src/views/card/index.tsx:109
|
||||
msgid "List"
|
||||
msgstr "Список"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:129
|
||||
#: src/views/board/components/NewListForm.tsx:128
|
||||
msgid "List name"
|
||||
msgstr "Название списка"
|
||||
|
||||
#: src/views/board/components/Filters.tsx:123
|
||||
msgid "Lists"
|
||||
msgstr "Списки"
|
||||
|
||||
#: src/views/auth/login/index.tsx:33
|
||||
msgid "Login | kan.bn"
|
||||
msgstr "Вход | kan.bn"
|
||||
@@ -1345,7 +1326,7 @@ msgstr "Любим командами по всему миру"
|
||||
msgid "Low Priority"
|
||||
msgstr "Низкий приоритет"
|
||||
|
||||
#: src/components/AuthForm.tsx:435
|
||||
#: src/components/AuthForm.tsx:421
|
||||
msgid "magic link"
|
||||
msgstr "магическая ссылка"
|
||||
|
||||
@@ -1367,9 +1348,9 @@ msgid "Medium Priority"
|
||||
msgstr "Средний приоритет"
|
||||
|
||||
#: src/components/SideNavigation.tsx:101
|
||||
#: src/views/board/components/Filters.tsx:107
|
||||
#: src/views/board/components/NewCardForm.tsx:367
|
||||
#: src/views/card/index.tsx:128
|
||||
#: src/views/board/components/Filters.tsx:93
|
||||
#: src/views/board/components/NewCardForm.tsx:366
|
||||
#: src/views/card/index.tsx:126
|
||||
#: src/views/members/index.tsx:178
|
||||
msgid "Members"
|
||||
msgstr "Участники"
|
||||
@@ -1422,7 +1403,7 @@ msgstr "Новый {0}"
|
||||
msgid "New API key"
|
||||
msgstr "Новый API-ключ"
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:293
|
||||
#: src/views/board/components/NewCardForm.tsx:292
|
||||
msgid "New card"
|
||||
msgstr "Новая карточка"
|
||||
|
||||
@@ -1438,8 +1419,8 @@ msgstr "Новый импорт"
|
||||
msgid "New label"
|
||||
msgstr "Новая метка"
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:113
|
||||
#: src/views/board/index.tsx:442
|
||||
#: src/views/board/components/NewListForm.tsx:112
|
||||
#: src/views/board/index.tsx:439
|
||||
msgid "New list"
|
||||
msgstr "Новый список"
|
||||
|
||||
@@ -1476,10 +1457,6 @@ msgstr "Следующие шаги"
|
||||
msgid "No {0}"
|
||||
msgstr "Нет {0}"
|
||||
|
||||
#: src/components/AuthForm.tsx:365
|
||||
msgid "No authentication methods are currently available"
|
||||
msgstr "В настоящее время нет доступных методов аутентификации"
|
||||
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:242
|
||||
msgid "No boards found"
|
||||
msgstr "Доски не найдены"
|
||||
@@ -1488,11 +1465,7 @@ msgstr "Доски не найдены"
|
||||
msgid "No credit card required"
|
||||
msgstr "Кредитная карта не требуется"
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:142
|
||||
msgid "No download URL available for this attachment."
|
||||
msgstr "URL для загрузки этого вложения недоступен."
|
||||
|
||||
#: src/views/board/index.tsx:467
|
||||
#: src/views/board/index.tsx:464
|
||||
msgid "No lists"
|
||||
msgstr "Нет списков"
|
||||
|
||||
@@ -1524,7 +1497,7 @@ msgstr "С открытым исходным кодом"
|
||||
msgid "Open Source Friends"
|
||||
msgstr "Друзья с открытым исходным кодом"
|
||||
|
||||
#: src/components/AuthForm.tsx:374
|
||||
#: src/components/AuthForm.tsx:365
|
||||
msgid "or"
|
||||
msgstr "или"
|
||||
|
||||
@@ -1606,15 +1579,15 @@ msgstr "Платформа"
|
||||
msgid "Please confirm your new password"
|
||||
msgstr "Пожалуйста, подтвердите новый пароль"
|
||||
|
||||
#: src/components/AuthForm.tsx:402
|
||||
#: src/components/AuthForm.tsx:391
|
||||
msgid "Please enter a valid email address"
|
||||
msgstr "Пожалуйста, введите действительный адрес электронной почты"
|
||||
|
||||
#: src/components/AuthForm.tsx:388
|
||||
#: src/components/AuthForm.tsx:379
|
||||
msgid "Please enter a valid name"
|
||||
msgstr "Пожалуйста, введите действительное имя"
|
||||
|
||||
#: src/components/AuthForm.tsx:416
|
||||
#: src/components/AuthForm.tsx:404
|
||||
msgid "Please enter a valid password"
|
||||
msgstr "Пожалуйста, введите действительный пароль"
|
||||
|
||||
@@ -1625,16 +1598,15 @@ msgstr "Пожалуйста, выберите файл для загрузки.
|
||||
#: src/components/DeleteLabelConfirmation.tsx:26
|
||||
#: src/components/FeedbackModal.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:158
|
||||
#: src/views/board/components/NewCardForm.tsx:177
|
||||
#: src/views/board/components/NewListForm.tsx:79
|
||||
#: src/views/board/components/NewCardForm.tsx:176
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/NewTemplateForm.tsx:61
|
||||
#: src/views/board/components/NewTemplateForm.tsx:77
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:73
|
||||
#: src/views/board/components/VisibilityButton.tsx:54
|
||||
#: src/views/board/index.tsx:151
|
||||
#: src/views/board/index.tsx:207
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
#: src/views/board/components/VisibilityButton.tsx:53
|
||||
#: src/views/board/index.tsx:149
|
||||
#: src/views/board/index.tsx:205
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:205
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:73
|
||||
#: src/views/card/components/ChecklistItemRow.tsx:60
|
||||
#: src/views/card/components/ChecklistItemRow.tsx:88
|
||||
#: src/views/card/components/ChecklistNameInput.tsx:46
|
||||
@@ -1648,7 +1620,7 @@ msgstr "Пожалуйста, выберите файл для загрузки.
|
||||
#: src/views/card/components/NewChecklistForm.tsx:70
|
||||
#: src/views/card/components/NewChecklistItemForm.tsx:89
|
||||
#: src/views/card/components/NewCommentForm.tsx:31
|
||||
#: src/views/card/index.tsx:177
|
||||
#: src/views/card/index.tsx:175
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
#: src/views/members/components/InviteMemberForm.tsx:241
|
||||
@@ -1692,7 +1664,7 @@ msgstr "Приоритетная поддержка по электронной
|
||||
msgid "Privacy policy"
|
||||
msgstr "Политика конфиденциальности"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:74
|
||||
#: src/views/board/components/VisibilityButton.tsx:73
|
||||
msgid "Private"
|
||||
msgstr "Личное"
|
||||
|
||||
@@ -1712,7 +1684,7 @@ msgstr "Изображение профиля обновлено"
|
||||
msgid "Profile picture"
|
||||
msgstr "Фотография профиля"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:69
|
||||
#: src/views/board/components/VisibilityButton.tsx:68
|
||||
msgid "Public"
|
||||
msgstr "Публичное"
|
||||
|
||||
@@ -1914,7 +1886,7 @@ msgstr "Регистрация отключена"
|
||||
msgid "Sign up is currently disabled. Please try again later."
|
||||
msgstr "Регистрация в настоящее время отключена. Пожалуйста, попробуйте позже."
|
||||
|
||||
#: src/components/AuthForm.tsx:434
|
||||
#: src/components/AuthForm.tsx:420
|
||||
msgid "Sign up with "
|
||||
msgstr "Зарегистрироваться с "
|
||||
|
||||
@@ -1981,8 +1953,8 @@ msgstr "Командный план"
|
||||
msgid "Teams"
|
||||
msgstr "Команды"
|
||||
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/board/index.tsx:398
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/board/index.tsx:396
|
||||
msgid "Template"
|
||||
msgstr "Шаблон"
|
||||
|
||||
@@ -2032,7 +2004,7 @@ msgid "The open source <0/> alternative to Trello"
|
||||
msgstr "Альтернатива Trello с открытым исходным кодом <0/>"
|
||||
|
||||
#. placeholder {0}: isPublic ? "public" : "private"
|
||||
#: src/views/board/components/VisibilityButton.tsx:47
|
||||
#: src/views/board/components/VisibilityButton.tsx:46
|
||||
msgid "The visibility of your board has been set to {0}."
|
||||
msgstr "Видимость вашей доски установлена на {0}."
|
||||
|
||||
@@ -2056,11 +2028,11 @@ msgstr "Это действие нельзя будет отменить."
|
||||
msgid "This API key will only be shown once. Please save it in a secure location."
|
||||
msgstr "Этот API-ключ будет показан только один раз. Пожалуйста, сохраните его в безопасном месте."
|
||||
|
||||
#: src/views/public/board/index.tsx:156
|
||||
#: src/views/public/board/index.tsx:154
|
||||
msgid "This board is private or does not exist"
|
||||
msgstr "Эта доска является приватной или не существует."
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:136
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:135
|
||||
msgid "This board URL has already been taken"
|
||||
msgstr "Этот URL доски уже занят."
|
||||
|
||||
@@ -2130,7 +2102,7 @@ msgstr "Не удалось добавить элемент контрольно
|
||||
msgid "Unable to add comment"
|
||||
msgstr "Не удалось добавить комментарий."
|
||||
|
||||
#: src/views/board/components/NewCardForm.tsx:174
|
||||
#: src/views/board/components/NewCardForm.tsx:173
|
||||
msgid "Unable to create card"
|
||||
msgstr "Не удалось создать карточку."
|
||||
|
||||
@@ -2138,7 +2110,7 @@ msgstr "Не удалось создать карточку."
|
||||
msgid "Unable to create checklist"
|
||||
msgstr "Не удалось создать контрольный список."
|
||||
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/NewListForm.tsx:77
|
||||
msgid "Unable to create list"
|
||||
msgstr "Не удалось создать список."
|
||||
|
||||
@@ -2151,10 +2123,6 @@ msgstr "Не удалось создать шаблон"
|
||||
msgid "Unable to create workspace"
|
||||
msgstr "Не удалось создать рабочее пространство."
|
||||
|
||||
#: src/views/card/components/AttachmentThumbnails.tsx:72
|
||||
msgid "Unable to delete attachment"
|
||||
msgstr "Не удалось удалить вложение"
|
||||
|
||||
#: src/views/card/components/DeleteCardConfirmation.tsx:51
|
||||
msgid "Unable to delete card"
|
||||
msgstr "Не удалось удалить карточку."
|
||||
@@ -2179,16 +2147,16 @@ msgstr "Не удалось удалить участника"
|
||||
msgid "Unable to send feedback"
|
||||
msgstr "Не удалось отправить отзыв"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:71
|
||||
msgid "Unable to update board URL"
|
||||
msgstr "Не удалось обновить URL доски"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:53
|
||||
#: src/views/board/components/VisibilityButton.tsx:52
|
||||
msgid "Unable to update board visibility"
|
||||
msgstr "Не удалось обновить видимость доски"
|
||||
|
||||
#: src/views/board/index.tsx:206
|
||||
#: src/views/card/index.tsx:176
|
||||
#: src/views/board/index.tsx:204
|
||||
#: src/views/card/index.tsx:174
|
||||
msgid "Unable to update card"
|
||||
msgstr "Не удалось обновить карточку"
|
||||
|
||||
@@ -2208,7 +2176,7 @@ msgstr "Не удалось обновить комментарий"
|
||||
msgid "Unable to update labels"
|
||||
msgstr "Не удалось обновить метки"
|
||||
|
||||
#: src/views/board/index.tsx:150
|
||||
#: src/views/board/index.tsx:148
|
||||
#: src/views/card/components/ListSelector.tsx:51
|
||||
msgid "Unable to update list"
|
||||
msgstr "Не удалось обновить список"
|
||||
@@ -2264,7 +2232,7 @@ msgstr "Неограниченное количество участников"
|
||||
msgid "Unlimited workspaces"
|
||||
msgstr "Неограниченное количество рабочих пространств"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:175
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
|
||||
#: src/views/settings/components/UpdateDisplayNameForm.tsx:80
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:91
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:83
|
||||
@@ -2303,11 +2271,6 @@ msgstr "Обновить до Pro"
|
||||
msgid "Upgrade to Pro ($29/month)"
|
||||
msgstr "Обновить до Pro ($29/месяц)"
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:32
|
||||
#: src/views/card/components/AttachmentUpload.tsx:78
|
||||
msgid "Upload failed"
|
||||
msgstr "Не удалось загрузить"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:38
|
||||
#: src/views/boards/components/TemplateBoards.tsx:55
|
||||
msgid "Urgent"
|
||||
@@ -2357,7 +2320,7 @@ msgstr "Просмотр и управление вашими счетами и
|
||||
msgid "View docs"
|
||||
msgstr "Просмотреть документацию"
|
||||
|
||||
#: src/views/public/board/index.tsx:129
|
||||
#: src/views/public/board/index.tsx:128
|
||||
msgid "View only"
|
||||
msgstr "Только просмотр"
|
||||
|
||||
@@ -2365,11 +2328,11 @@ msgstr "Только просмотр"
|
||||
msgid "View our roadmap."
|
||||
msgstr "Просмотреть нашу дорожную карту."
|
||||
|
||||
#: src/views/public/board/index.tsx:159
|
||||
#: src/views/public/board/index.tsx:157
|
||||
msgid "View workspace"
|
||||
msgstr "Просмотреть рабочее пространство"
|
||||
|
||||
#: src/views/board/components/VisibilityButton.tsx:92
|
||||
#: src/views/board/components/VisibilityButton.tsx:91
|
||||
msgid "Visibility"
|
||||
msgstr "Видимость"
|
||||
|
||||
@@ -2406,10 +2369,10 @@ msgid "Why make an open source Trello?"
|
||||
msgstr "Зачем создавать Trello с открытым исходным кодом?"
|
||||
|
||||
#: src/components/SettingsLayout.tsx:39
|
||||
#: src/views/board/index.tsx:363
|
||||
#: src/views/board/index.tsx:361
|
||||
#: src/views/boards/index.tsx:22
|
||||
#: src/views/members/index.tsx:173
|
||||
#: src/views/public/board/index.tsx:101
|
||||
#: src/views/public/board/index.tsx:100
|
||||
#: src/views/public/boards/index.tsx:66
|
||||
msgid "Workspace"
|
||||
msgstr "Рабочее пространство"
|
||||
@@ -2539,10 +2502,6 @@ msgstr "Ваши доски были импортированы."
|
||||
msgid "Your display name has been updated."
|
||||
msgstr "Ваше отображаемое имя было обновлено."
|
||||
|
||||
#: src/views/card/components/AttachmentUpload.tsx:26
|
||||
msgid "Your file has been uploaded successfully."
|
||||
msgstr "Ваш файл успешно загружен."
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:70
|
||||
msgid "Your password has been changed."
|
||||
msgstr "Ваш пароль был изменён."
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,48 +0,0 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
) {
|
||||
if (req.method !== "GET") {
|
||||
return res.status(405).json({ message: "Method not allowed" });
|
||||
}
|
||||
|
||||
const { url, filename } = req.query;
|
||||
|
||||
if (!url || typeof url !== "string") {
|
||||
return res.status(400).json({
|
||||
message: "url parameter is required",
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const downloadUrl = decodeURIComponent(url);
|
||||
const downloadFilename =
|
||||
(typeof filename === "string" ? decodeURIComponent(filename) : null) ??
|
||||
"attachment";
|
||||
|
||||
const upstream = await fetch(downloadUrl);
|
||||
|
||||
if (!upstream.ok) {
|
||||
return res.status(upstream.status).json({
|
||||
message: "Failed to fetch attachment",
|
||||
});
|
||||
}
|
||||
|
||||
const contentType =
|
||||
upstream.headers.get("Content-Type") ?? "application/octet-stream";
|
||||
|
||||
res.setHeader("Content-Type", contentType);
|
||||
res.setHeader(
|
||||
"Content-Disposition",
|
||||
`attachment; filename="${downloadFilename}"`,
|
||||
);
|
||||
|
||||
const buffer = await upstream.arrayBuffer();
|
||||
return res.send(Buffer.from(buffer));
|
||||
} catch (error) {
|
||||
console.error("Error downloading attachment:", error);
|
||||
return res.status(500).json({ message: "Failed to download attachment" });
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
import { HiOutlinePaperClip } from "react-icons/hi";
|
||||
import { HiBars3BottomLeft, HiChatBubbleLeft } from "react-icons/hi2";
|
||||
|
||||
import Avatar from "~/components/Avatar";
|
||||
@@ -14,7 +13,6 @@ const Card = ({
|
||||
checklists,
|
||||
description,
|
||||
comments,
|
||||
attachments,
|
||||
}: {
|
||||
title: string;
|
||||
labels: { name: string; colourCode: string | null }[];
|
||||
@@ -35,7 +33,6 @@ const Card = ({
|
||||
}[];
|
||||
description: string | null;
|
||||
comments: { publicId: string }[];
|
||||
attachments?: { publicId: string }[];
|
||||
}) => {
|
||||
const completedItems = checklists.reduce((acc, checklist) => {
|
||||
return acc + checklist.items.filter((item) => item.completed).length;
|
||||
@@ -50,7 +47,6 @@ const Card = ({
|
||||
|
||||
const hasDescription =
|
||||
description && description.replace(/<[^>]*>/g, "").trim().length > 0;
|
||||
const hasAttachments = attachments && attachments.length > 0;
|
||||
|
||||
return (
|
||||
<div className="flex flex-col rounded-md border border-light-200 bg-light-50 px-3 py-2 text-sm text-neutral-900 dark:border-dark-200 dark:bg-dark-200 dark:text-dark-1000 dark:hover:bg-dark-300">
|
||||
@@ -59,8 +55,7 @@ const Card = ({
|
||||
members.length ||
|
||||
checklists.length > 0 ||
|
||||
hasDescription ||
|
||||
comments.length > 0 ||
|
||||
hasAttachments ? (
|
||||
comments.length > 0 ? (
|
||||
<div className="mt-2 flex flex-col justify-end">
|
||||
<div className="space-x-0.5">
|
||||
{labels.map((label) => (
|
||||
@@ -82,11 +77,6 @@ const Card = ({
|
||||
<HiChatBubbleLeft className="h-4 w-4" />
|
||||
</div>
|
||||
)}
|
||||
{hasAttachments && (
|
||||
<div className="flex items-center gap-1 text-light-700 dark:text-dark-800">
|
||||
<HiOutlinePaperClip className="h-4 w-4" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center justify-end gap-1">
|
||||
{checklists.length > 0 && (
|
||||
|
||||
@@ -12,7 +12,6 @@ interface QueryParams {
|
||||
boardPublicId: string;
|
||||
members: string[];
|
||||
labels: string[];
|
||||
lists: string[];
|
||||
}
|
||||
|
||||
export function DeleteListConfirmation({
|
||||
|
||||
@@ -2,7 +2,6 @@ import { useRouter } from "next/router";
|
||||
import { t } from "@lingui/core/macro";
|
||||
import {
|
||||
HiMiniXMark,
|
||||
HiOutlineSquare3Stack3D,
|
||||
HiOutlineTag,
|
||||
HiOutlineUserCircle,
|
||||
} from "react-icons/hi2";
|
||||
@@ -33,22 +32,15 @@ interface Label {
|
||||
colourCode: string | null;
|
||||
}
|
||||
|
||||
interface List {
|
||||
publicId: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
const Filters = ({
|
||||
position = "right",
|
||||
labels,
|
||||
members,
|
||||
lists,
|
||||
isLoading,
|
||||
}: {
|
||||
position?: "left" | "right";
|
||||
labels: Label[];
|
||||
members: Member[];
|
||||
lists: List[];
|
||||
isLoading: boolean;
|
||||
}) => {
|
||||
const router = useRouter();
|
||||
@@ -60,7 +52,7 @@ const Filters = ({
|
||||
try {
|
||||
await router.push({
|
||||
pathname: router.pathname,
|
||||
query: { ...router.query, members: [], labels: [], lists: [] },
|
||||
query: { ...router.query, members: [], labels: [] },
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
@@ -93,12 +85,6 @@ const Filters = ({
|
||||
leftIcon: <LabelIcon colourCode={label.colourCode} />,
|
||||
}));
|
||||
|
||||
const formattedLists = lists.map((list) => ({
|
||||
key: list.publicId,
|
||||
value: list.name,
|
||||
selected: !!router.query.lists?.includes(list.publicId),
|
||||
}));
|
||||
|
||||
const groups = [
|
||||
...(formattedMembers.length
|
||||
? [
|
||||
@@ -116,16 +102,6 @@ const Filters = ({
|
||||
icon: <HiOutlineTag size={16} />,
|
||||
items: formattedLabels,
|
||||
},
|
||||
...(formattedLists.length
|
||||
? [
|
||||
{
|
||||
key: "lists",
|
||||
label: t`Lists`,
|
||||
icon: <HiOutlineSquare3Stack3D size={16} />,
|
||||
items: formattedLists,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
];
|
||||
|
||||
const handleSelect = async (
|
||||
@@ -155,7 +131,6 @@ const Filters = ({
|
||||
const numOfFilters = [
|
||||
...formatToArray(router.query.members),
|
||||
...formatToArray(router.query.labels),
|
||||
...formatToArray(router.query.lists),
|
||||
].length;
|
||||
|
||||
return (
|
||||
|
||||
@@ -33,7 +33,6 @@ interface QueryParams {
|
||||
boardPublicId: string;
|
||||
members: string[];
|
||||
labels: string[];
|
||||
lists: string[];
|
||||
}
|
||||
|
||||
interface NewCardFormProps {
|
||||
|
||||
@@ -21,7 +21,6 @@ interface QueryParams {
|
||||
boardPublicId: string;
|
||||
members: string[];
|
||||
labels: string[];
|
||||
lists: string[];
|
||||
}
|
||||
|
||||
export function NewListForm({
|
||||
|
||||
@@ -17,7 +17,6 @@ interface QueryParams {
|
||||
boardPublicId: string;
|
||||
members: string[];
|
||||
labels: string[];
|
||||
lists: string[];
|
||||
}
|
||||
|
||||
export function UpdateBoardSlugForm({
|
||||
|
||||
@@ -11,7 +11,6 @@ interface QueryParams {
|
||||
boardPublicId: string;
|
||||
members: string[];
|
||||
labels: string[];
|
||||
lists: string[];
|
||||
}
|
||||
|
||||
const VisibilityButton = ({
|
||||
|
||||
@@ -80,13 +80,11 @@ export default function BoardPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
boardPublicId: string;
|
||||
members: string[];
|
||||
labels: string[];
|
||||
lists: string[];
|
||||
type: "regular" | "template";
|
||||
} = {
|
||||
boardPublicId: boardId ?? "",
|
||||
members: formatToArray(router.query.members),
|
||||
labels: formatToArray(router.query.labels),
|
||||
lists: formatToArray(router.query.lists),
|
||||
type: isTemplate ? "template" : "regular",
|
||||
};
|
||||
|
||||
@@ -420,7 +418,6 @@ export default function BoardPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
members={boardData.workspace.members.filter(
|
||||
(member) => member.user !== null,
|
||||
)}
|
||||
lists={boardData.allLists}
|
||||
position="left"
|
||||
isLoading={!boardData}
|
||||
/>
|
||||
@@ -553,7 +550,6 @@ export default function BoardPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
card.description ?? null
|
||||
}
|
||||
comments={card.comments ?? []}
|
||||
attachments={card.attachments}
|
||||
/>
|
||||
</Link>
|
||||
)}
|
||||
|
||||
@@ -1,462 +0,0 @@
|
||||
import Image from "next/image";
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { Fragment, useEffect, useState } from "react";
|
||||
import {
|
||||
HiArrowDownTray,
|
||||
HiChevronLeft,
|
||||
HiChevronRight,
|
||||
HiDocumentText,
|
||||
HiOutlineTrash,
|
||||
HiXMark,
|
||||
} from "react-icons/hi2";
|
||||
|
||||
import { usePopup } from "~/providers/popup";
|
||||
import { api } from "~/utils/api";
|
||||
|
||||
interface Attachment {
|
||||
publicId: string;
|
||||
contentType: string;
|
||||
url: string | null;
|
||||
originalFilename: string | null;
|
||||
s3Key: string;
|
||||
size?: number | null;
|
||||
}
|
||||
|
||||
export function AttachmentThumbnails({
|
||||
attachments,
|
||||
cardPublicId,
|
||||
isReadOnly = false,
|
||||
}: {
|
||||
attachments?: Attachment[];
|
||||
cardPublicId: string;
|
||||
isReadOnly?: boolean;
|
||||
}) {
|
||||
const { showPopup } = usePopup();
|
||||
const utils = api.useUtils();
|
||||
const imageAttachments =
|
||||
attachments?.filter(
|
||||
(attachment) =>
|
||||
attachment.contentType.startsWith("image/") && attachment.url,
|
||||
) ?? [];
|
||||
|
||||
const nonImageAttachments =
|
||||
attachments?.filter(
|
||||
(attachment) =>
|
||||
!attachment.contentType.startsWith("image/") && attachment.url,
|
||||
) ?? [];
|
||||
|
||||
const [selectedIndex, setSelectedIndex] = useState<number | null>(null);
|
||||
|
||||
const deleteAttachment = api.attachment.delete.useMutation({
|
||||
onMutate: async (args) => {
|
||||
if (isReadOnly) return;
|
||||
|
||||
await utils.card.byId.cancel({ cardPublicId });
|
||||
const currentState = utils.card.byId.getData({ cardPublicId });
|
||||
|
||||
utils.card.byId.setData({ cardPublicId }, (oldCard) => {
|
||||
if (!oldCard) return oldCard;
|
||||
const updatedAttachments = oldCard.attachments.filter(
|
||||
(attachment) => attachment.publicId !== args.attachmentPublicId,
|
||||
);
|
||||
return { ...oldCard, attachments: updatedAttachments };
|
||||
});
|
||||
|
||||
return { previousState: currentState };
|
||||
},
|
||||
onError: (_error, _args, context) => {
|
||||
if (isReadOnly) return;
|
||||
utils.card.byId.setData({ cardPublicId }, context?.previousState);
|
||||
showPopup({
|
||||
header: t`Unable to delete attachment`,
|
||||
message: t`Please try again later, or contact customer support.`,
|
||||
icon: "error",
|
||||
});
|
||||
},
|
||||
onSuccess: () => {
|
||||
if (isReadOnly) return;
|
||||
// Close viewer if the deleted image was being viewed
|
||||
setSelectedIndex(null);
|
||||
},
|
||||
onSettled: async () => {
|
||||
if (isReadOnly) return;
|
||||
await utils.card.byId.invalidate({ cardPublicId });
|
||||
},
|
||||
});
|
||||
|
||||
// Keyboard navigation
|
||||
useEffect(() => {
|
||||
if (selectedIndex === null) return;
|
||||
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape") {
|
||||
setSelectedIndex(null);
|
||||
} else if (e.key === "ArrowLeft") {
|
||||
setSelectedIndex((prev) => {
|
||||
if (prev === null) return null;
|
||||
return prev === 0 ? imageAttachments.length - 1 : prev - 1;
|
||||
});
|
||||
} else if (e.key === "ArrowRight") {
|
||||
setSelectedIndex((prev) => {
|
||||
if (prev === null) return null;
|
||||
return prev === imageAttachments.length - 1 ? 0 : prev + 1;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", handleKeyDown);
|
||||
return () => window.removeEventListener("keydown", handleKeyDown);
|
||||
}, [selectedIndex, imageAttachments.length]);
|
||||
|
||||
if (imageAttachments.length === 0 && nonImageAttachments.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const openViewer = (index: number) => {
|
||||
setSelectedIndex(index);
|
||||
};
|
||||
|
||||
const closeViewer = () => {
|
||||
setSelectedIndex(null);
|
||||
};
|
||||
|
||||
const goToPrevious = () => {
|
||||
if (selectedIndex === null) return;
|
||||
const newIndex =
|
||||
selectedIndex === 0 ? imageAttachments.length - 1 : selectedIndex - 1;
|
||||
setSelectedIndex(newIndex);
|
||||
};
|
||||
|
||||
const goToNext = () => {
|
||||
if (selectedIndex === null) return;
|
||||
const newIndex =
|
||||
selectedIndex === imageAttachments.length - 1 ? 0 : selectedIndex + 1;
|
||||
setSelectedIndex(newIndex);
|
||||
};
|
||||
|
||||
const handleDownload = (attachment: Attachment) => {
|
||||
if (!attachment.url) {
|
||||
showPopup({
|
||||
header: t`Download failed`,
|
||||
message: t`No download URL available for this attachment.`,
|
||||
icon: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const downloadUrl = `/api/download/attatchment?url=${encodeURIComponent(attachment.url)}&filename=${encodeURIComponent(attachment.originalFilename ?? "attachment")}`;
|
||||
|
||||
const link = document.createElement("a");
|
||||
link.href = downloadUrl;
|
||||
link.style.display = "none";
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
};
|
||||
|
||||
const selectedAttachment =
|
||||
selectedIndex !== null ? imageAttachments[selectedIndex] : null;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mb-3 flex flex-wrap gap-2 pt-1">
|
||||
{imageAttachments.map((attachment, index) => {
|
||||
if (!attachment.url) return null;
|
||||
return (
|
||||
<AttachmentThumbnail
|
||||
key={attachment.publicId}
|
||||
attachment={{
|
||||
publicId: attachment.publicId,
|
||||
url: attachment.url,
|
||||
originalFilename: attachment.originalFilename ?? "",
|
||||
contentType: attachment.contentType,
|
||||
}}
|
||||
onClick={() => openViewer(index)}
|
||||
isImage={true}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{nonImageAttachments.length > 0 && (
|
||||
<div className="mb-3 flex flex-col gap-2">
|
||||
{nonImageAttachments.map((attachment) => {
|
||||
if (!attachment.url) return null;
|
||||
return (
|
||||
<FileListItem
|
||||
key={attachment.publicId}
|
||||
attachment={attachment}
|
||||
onDownload={() => handleDownload(attachment)}
|
||||
onDelete={
|
||||
isReadOnly
|
||||
? undefined
|
||||
: () => {
|
||||
deleteAttachment.mutate({
|
||||
attachmentPublicId: attachment.publicId,
|
||||
});
|
||||
}
|
||||
}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Transition.Root show={selectedIndex !== null} as={Fragment}>
|
||||
<Dialog
|
||||
as="div"
|
||||
className="relative z-50"
|
||||
onClose={() => {
|
||||
// Dialog closing is handled by the background overlay click
|
||||
}}
|
||||
static
|
||||
>
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0"
|
||||
enterTo="opacity-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<div
|
||||
className="fixed inset-0 bg-light-50 transition-opacity dark:bg-dark-50"
|
||||
onClick={(e) => {
|
||||
// Only close if clicking directly on the background, not on buttons
|
||||
if (e.target === e.currentTarget) {
|
||||
closeViewer();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-10 overflow-y-auto">
|
||||
{selectedIndex !== null && selectedAttachment && (
|
||||
<div
|
||||
className="fixed left-2 top-2 z-20 flex gap-1"
|
||||
onMouseDown={(e) => e.stopPropagation()}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{!isReadOnly && (
|
||||
<button
|
||||
onMouseDown={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
deleteAttachment.mutate({
|
||||
attachmentPublicId: selectedAttachment.publicId,
|
||||
});
|
||||
}}
|
||||
className="rounded-full bg-light-50 p-1.5 text-light-1000 transition-colors hover:bg-light-100 focus:outline-none dark:bg-dark-50 dark:text-dark-1000 dark:hover:bg-dark-100"
|
||||
aria-label="Delete image"
|
||||
disabled={deleteAttachment.isPending}
|
||||
>
|
||||
<HiOutlineTrash className="h-4 w-4" />
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
onMouseDown={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
handleDownload(selectedAttachment);
|
||||
}}
|
||||
className="rounded-full bg-light-50 p-1.5 text-light-1000 transition-colors hover:bg-light-100 focus:outline-none dark:bg-dark-50 dark:text-dark-1000 dark:hover:bg-dark-100"
|
||||
aria-label="Download image"
|
||||
>
|
||||
<HiArrowDownTray className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="fixed right-2 top-2 z-20 flex gap-1">
|
||||
{imageAttachments.length > 1 && selectedIndex !== null && (
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
goToPrevious();
|
||||
}}
|
||||
className="rounded-full bg-light-50 p-1.5 text-light-1000 transition-colors hover:bg-light-100 focus:outline-none dark:bg-dark-50 dark:text-dark-1000 dark:hover:bg-dark-100"
|
||||
aria-label="Previous image"
|
||||
>
|
||||
<HiChevronLeft className="h-4 w-4" />
|
||||
</button>
|
||||
)}
|
||||
|
||||
{imageAttachments.length > 1 && selectedIndex !== null && (
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
goToNext();
|
||||
}}
|
||||
className="rounded-full bg-light-50 p-1.5 text-light-1000 transition-colors hover:bg-light-100 focus:outline-none dark:bg-dark-50 dark:text-dark-1000 dark:hover:bg-dark-100"
|
||||
aria-label="Next image"
|
||||
>
|
||||
<HiChevronRight className="h-4 w-4" />
|
||||
</button>
|
||||
)}
|
||||
|
||||
{selectedIndex !== null && (
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
closeViewer();
|
||||
}}
|
||||
className="rounded-full bg-light-50 p-1.5 text-light-1000 transition-colors hover:bg-light-100 focus:outline-none dark:bg-dark-50 dark:text-dark-1000 dark:hover:bg-dark-100"
|
||||
aria-label="Close"
|
||||
>
|
||||
<HiXMark className="h-4 w-4" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-full items-center justify-center p-4">
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 scale-95"
|
||||
enterTo="opacity-100 scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 scale-100"
|
||||
leaveTo="opacity-0 scale-95"
|
||||
>
|
||||
<Dialog.Panel
|
||||
className="relative w-full max-w-7xl"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{selectedAttachment?.url && (
|
||||
<div className="relative">
|
||||
<div className="relative mx-auto max-h-[90vh] w-full">
|
||||
<Image
|
||||
src={selectedAttachment.url}
|
||||
alt={
|
||||
selectedAttachment.originalFilename ?? "Attachment"
|
||||
}
|
||||
width={1920}
|
||||
height={1080}
|
||||
className="mx-auto max-h-[90vh] w-auto object-contain"
|
||||
unoptimized
|
||||
/>
|
||||
</div>
|
||||
|
||||
{imageAttachments.length > 1 && (
|
||||
<div className="absolute bottom-4 left-1/2 -translate-x-1/2 rounded-full bg-black/50 px-3 py-1.5 text-[10px] text-white">
|
||||
{selectedIndex !== null && selectedIndex + 1} /{" "}
|
||||
{imageAttachments.length}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function AttachmentThumbnail({
|
||||
attachment,
|
||||
onClick,
|
||||
isImage,
|
||||
}: {
|
||||
attachment: {
|
||||
publicId: string;
|
||||
url: string;
|
||||
originalFilename: string;
|
||||
contentType: string;
|
||||
};
|
||||
onClick: () => void;
|
||||
isImage: boolean;
|
||||
}) {
|
||||
return (
|
||||
<button
|
||||
onClick={onClick}
|
||||
className="relative h-16 w-16 overflow-hidden rounded-xl border border-light-300 transition-transform hover:scale-105 dark:border-dark-300"
|
||||
aria-label={`View ${attachment.originalFilename}`}
|
||||
>
|
||||
{isImage ? (
|
||||
<Image
|
||||
src={attachment.url}
|
||||
alt={attachment.originalFilename}
|
||||
fill
|
||||
className="object-cover"
|
||||
sizes="64px"
|
||||
/>
|
||||
) : (
|
||||
<div className="flex h-full w-full items-center justify-center bg-light-100 dark:bg-dark-100">
|
||||
<HiDocumentText className="h-6 w-6 text-light-700 dark:text-dark-700" />
|
||||
</div>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
function formatFileSize(bytes: number | null | undefined): string {
|
||||
if (!bytes || bytes === 0 || isNaN(bytes)) return "0 B";
|
||||
const k = 1024;
|
||||
const sizes = ["B", "KB", "MB", "GB"];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return `${(bytes / Math.pow(k, i)).toFixed(1)} ${sizes[i] ?? "B"}`;
|
||||
}
|
||||
|
||||
function FileListItem({
|
||||
attachment,
|
||||
onDownload,
|
||||
onDelete,
|
||||
}: {
|
||||
attachment: Attachment;
|
||||
onDownload: () => void;
|
||||
onDelete?: () => void;
|
||||
}) {
|
||||
return (
|
||||
<div className="group flex w-full items-center gap-3 rounded-lg border border-light-300 bg-light-50 px-3 py-2 dark:border-dark-200 dark:bg-dark-100">
|
||||
<div className="flex-shrink-0">
|
||||
<HiDocumentText className="h-5 w-5 text-light-700 dark:text-dark-700" />
|
||||
</div>
|
||||
<div className="min-w-0 flex-1 truncate text-sm text-light-1000 dark:text-dark-1000">
|
||||
{attachment.originalFilename ?? "File"}
|
||||
</div>
|
||||
<div className="flex items-center gap-2 opacity-0 transition-opacity group-hover:opacity-100">
|
||||
<div className="text-xs text-light-500 dark:text-dark-900">
|
||||
{attachment.size != null &&
|
||||
!isNaN(attachment.size) &&
|
||||
`${formatFileSize(attachment.size)}`}
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onDownload();
|
||||
}}
|
||||
className="flex-shrink-0 rounded-full bg-light-100 p-1.5 text-light-1000 transition-colors hover:bg-light-200 focus:outline-none dark:bg-dark-100 dark:text-dark-950 dark:hover:bg-dark-300"
|
||||
aria-label={`Download ${attachment.originalFilename}`}
|
||||
>
|
||||
<HiArrowDownTray className="h-4 w-4" />
|
||||
</button>
|
||||
{onDelete && (
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onDelete();
|
||||
}}
|
||||
className="flex-shrink-0 rounded-full bg-light-100 p-1.5 text-light-1000 transition-colors hover:bg-light-200 focus:outline-none dark:bg-dark-100 dark:text-dark-950 dark:hover:bg-dark-300"
|
||||
aria-label={`Delete ${attachment.originalFilename}`}
|
||||
>
|
||||
<HiXMark className="h-4 w-4" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { useRef, useState } from "react";
|
||||
import { HiOutlinePaperClip } from "react-icons/hi";
|
||||
import { HiCheckBadge } from "react-icons/hi2";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import Button from "~/components/Button";
|
||||
import { useModal } from "~/providers/modal";
|
||||
import { usePopup } from "~/providers/popup";
|
||||
import { api } from "~/utils/api";
|
||||
|
||||
export function AttachmentUpload({ cardPublicId }: { cardPublicId: string }) {
|
||||
const { openModal } = useModal();
|
||||
const { showPopup } = usePopup();
|
||||
const utils = api.useUtils();
|
||||
const [uploading, setUploading] = useState(false);
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||
|
||||
const generateUploadUrl = api.attachment.generateUploadUrl.useMutation();
|
||||
const confirmAttachment = api.attachment.confirm.useMutation({
|
||||
onSuccess: async () => {
|
||||
await utils.card.byId.invalidate({ cardPublicId });
|
||||
showPopup({
|
||||
header: t`Attachment uploaded`,
|
||||
message: t`Your file has been uploaded successfully.`,
|
||||
icon: "success",
|
||||
});
|
||||
},
|
||||
onError: () => {
|
||||
showPopup({
|
||||
header: t`Upload failed`,
|
||||
message: t`Failed to upload attachment. Please try again.`,
|
||||
icon: "error",
|
||||
});
|
||||
},
|
||||
onSettled: () => {
|
||||
setUploading(false);
|
||||
},
|
||||
});
|
||||
|
||||
const uploadFile = async (file: File) => {
|
||||
setUploading(true);
|
||||
|
||||
try {
|
||||
// Generate presigned URL
|
||||
const { url, key } = await generateUploadUrl.mutateAsync({
|
||||
cardPublicId,
|
||||
filename: file.name,
|
||||
contentType: file.type,
|
||||
size: file.size,
|
||||
});
|
||||
|
||||
// Upload file to S3
|
||||
const uploadResponse = await fetch(url, {
|
||||
method: "PUT",
|
||||
body: file,
|
||||
headers: {
|
||||
"Content-Type": file.type,
|
||||
},
|
||||
});
|
||||
|
||||
if (!uploadResponse.ok) {
|
||||
throw new Error("Upload failed");
|
||||
}
|
||||
|
||||
// Confirm attachment in database
|
||||
await confirmAttachment.mutateAsync({
|
||||
cardPublicId,
|
||||
s3Key: key,
|
||||
filename: file.name,
|
||||
originalFilename: file.name,
|
||||
contentType: file.type,
|
||||
size: file.size,
|
||||
});
|
||||
} catch {
|
||||
showPopup({
|
||||
header: t`Upload failed`,
|
||||
message: t`Failed to upload attachment. Please try again.`,
|
||||
icon: "error",
|
||||
});
|
||||
setUploading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleFileSelect = async (
|
||||
event: React.ChangeEvent<HTMLInputElement>,
|
||||
) => {
|
||||
const file = event.target.files?.[0];
|
||||
if (!file) return;
|
||||
|
||||
// Reset input
|
||||
event.target.value = "";
|
||||
|
||||
await uploadFile(file);
|
||||
};
|
||||
|
||||
const handleDragOver = (e: React.DragEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (!uploading) {
|
||||
setIsDragging(true);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDragLeave = (e: React.DragEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setIsDragging(false);
|
||||
};
|
||||
|
||||
const handleDrop = async (e: React.DragEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setIsDragging(false);
|
||||
|
||||
if (uploading) return;
|
||||
|
||||
const files = Array.from(e.dataTransfer.files);
|
||||
if (files.length === 0) return;
|
||||
|
||||
// Upload the first file (or could upload all files)
|
||||
await uploadFile(files[0] ?? new File([], ""));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mb-6">
|
||||
<input
|
||||
ref={inputRef}
|
||||
type="file"
|
||||
id="attachment-upload"
|
||||
className="hidden"
|
||||
onChange={handleFileSelect}
|
||||
disabled={uploading}
|
||||
/>
|
||||
<div
|
||||
onDragOver={handleDragOver}
|
||||
onDragLeave={handleDragLeave}
|
||||
onDrop={handleDrop}
|
||||
className={twMerge(
|
||||
"rounded-lg border-2 border-dashed transition-colors",
|
||||
isDragging
|
||||
? "border-light-300 bg-light-100 dark:border-dark-300 dark:bg-dark-100"
|
||||
: "border-transparent",
|
||||
)}
|
||||
>
|
||||
<div className="flex items-center justify-between p-2">
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
iconLeft={
|
||||
<HiCheckBadge className="h-4 w-4 text-light-950 dark:text-dark-950" />
|
||||
}
|
||||
iconOnly
|
||||
size="sm"
|
||||
onClick={() => openModal("ADD_CHECKLIST")}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
iconLeft={
|
||||
<HiOutlinePaperClip className="h-4 w-4 text-light-950 dark:text-dark-950" />
|
||||
}
|
||||
isLoading={uploading}
|
||||
disabled={uploading}
|
||||
iconOnly
|
||||
size="sm"
|
||||
onClick={() => inputRef.current?.click()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -28,7 +28,7 @@ export default function BoardDropdown() {
|
||||
},
|
||||
]}
|
||||
>
|
||||
<HiEllipsisHorizontal className="h-5 w-5 text-dark-900" />
|
||||
<HiEllipsisHorizontal className="h-6 w-6 text-dark-900" />
|
||||
</Dropdown>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -20,8 +20,6 @@ import { api } from "~/utils/api";
|
||||
import { formatMemberDisplayName, getAvatarUrl } from "~/utils/helpers";
|
||||
import { DeleteLabelConfirmation } from "../../components/DeleteLabelConfirmation";
|
||||
import ActivityList from "./components/ActivityList";
|
||||
import { AttachmentThumbnails } from "./components/AttachmentThumbnails";
|
||||
import { AttachmentUpload } from "./components/AttachmentUpload";
|
||||
import Checklists from "./components/Checklists";
|
||||
import { DeleteCardConfirmation } from "./components/DeleteCardConfirmation";
|
||||
import { DeleteChecklistConfirmation } from "./components/DeleteChecklistConfirmation";
|
||||
@@ -107,7 +105,7 @@ export function CardRightPanel({ isTemplate }: { isTemplate?: boolean }) {
|
||||
|
||||
return (
|
||||
<div className="h-full w-[360px] border-l-[1px] border-light-300 bg-light-50 p-8 text-light-900 dark:border-dark-300 dark:bg-dark-50 dark:text-dark-900">
|
||||
<div className="mb-4 flex w-full flex-row pt-[18px]">
|
||||
<div className="mb-4 flex w-full flex-row">
|
||||
<p className="my-2 mb-2 w-[100px] text-sm font-medium">{t`List`}</p>
|
||||
<ListSelector
|
||||
cardPublicId={cardId ?? ""}
|
||||
@@ -210,17 +208,6 @@ export default function CardPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
}
|
||||
}, [card, getModalState, clearModalState]);
|
||||
|
||||
// Auto-resize title textarea
|
||||
useEffect(() => {
|
||||
const titleTextarea = document.getElementById(
|
||||
"title",
|
||||
) as HTMLTextAreaElement;
|
||||
if (titleTextarea) {
|
||||
titleTextarea.style.height = "auto";
|
||||
titleTextarea.style.height = `${titleTextarea.scrollHeight}px`;
|
||||
}
|
||||
}, [card]);
|
||||
|
||||
if (!cardId) return <></>;
|
||||
|
||||
return (
|
||||
@@ -228,71 +215,47 @@ export default function CardPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
<PageHead
|
||||
title={t`${card?.title ?? t`Card`} | ${board?.name ?? t`Board`}`}
|
||||
/>
|
||||
<div className="flex h-full flex-1 flex-col overflow-hidden">
|
||||
{/* Full-width top strip with board link and dropdown */}
|
||||
<div className="flex w-full items-center justify-between border-b-[1px] border-light-300 bg-light-50 px-8 py-2 dark:border-dark-300 dark:bg-dark-50">
|
||||
{!card && isLoading && (
|
||||
<div className="flex space-x-2">
|
||||
<div className="h-[1.5rem] w-[150px] animate-pulse rounded-[5px] bg-light-300 dark:bg-dark-300" />
|
||||
</div>
|
||||
)}
|
||||
{card && (
|
||||
<>
|
||||
<div className="flex items-center gap-1">
|
||||
<Link
|
||||
className="whitespace-nowrapleading-[1.5rem] text-sm font-bold text-light-900 dark:text-dark-950"
|
||||
href={`${isTemplate ? "/templates" : "/boards"}`}
|
||||
>
|
||||
{workspace.name}
|
||||
</Link>
|
||||
<IoChevronForwardSharp className="h-[10px] w-[10px] text-light-900 dark:text-dark-900" />
|
||||
<Link
|
||||
className="whitespace-nowrap text-sm font-bold leading-[1.5rem] text-light-900 dark:text-dark-950"
|
||||
href={`${isTemplate ? "/templates" : "/boards"}/${board?.publicId}`}
|
||||
>
|
||||
{board?.name}
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Dropdown />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{!card && !isLoading && (
|
||||
<p className="block p-0 py-0 font-bold leading-[1.5rem] tracking-tight text-light-900 dark:text-dark-900 sm:text-[1rem]">
|
||||
{t`Card not found`}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex h-full flex-1 flex-row overflow-hidden">
|
||||
<div className="scrollbar-thumb-rounded-[4px] scrollbar-track-rounded-[4px] w-full flex-1 overflow-y-auto scrollbar scrollbar-track-light-200 scrollbar-thumb-light-400 hover:scrollbar-thumb-light-400 dark:scrollbar-track-dark-100 dark:scrollbar-thumb-dark-300 dark:hover:scrollbar-thumb-dark-300">
|
||||
<div className="p-auto mx-auto flex h-full w-full max-w-[800px] flex-col">
|
||||
<div className="p-6 md:p-8">
|
||||
<div className="mb-8 md:mt-4">
|
||||
<div className="mb-8 flex w-full items-center justify-between md:mt-6">
|
||||
{!card && isLoading && (
|
||||
<div className="flex space-x-2">
|
||||
<div className="h-[2.3rem] w-[150px] animate-pulse rounded-[5px] bg-light-300 dark:bg-dark-300" />
|
||||
<div className="h-[2.3rem] w-[300px] animate-pulse rounded-[5px] bg-light-300 dark:bg-dark-300" />
|
||||
</div>
|
||||
)}
|
||||
{card && (
|
||||
<form
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
className="w-full space-y-6"
|
||||
>
|
||||
<div>
|
||||
<textarea
|
||||
id="title"
|
||||
{...register("title")}
|
||||
onBlur={handleSubmit(onSubmit)}
|
||||
rows={1}
|
||||
className="block w-full resize-none overflow-hidden border-0 bg-transparent p-0 py-0 font-bold leading-relaxed text-neutral-900 focus:ring-0 dark:text-dark-1000 sm:text-[1.2rem]"
|
||||
onInput={(e) => {
|
||||
const target = e.target as HTMLTextAreaElement;
|
||||
target.style.height = "auto";
|
||||
target.style.height = `${target.scrollHeight}px`;
|
||||
}}
|
||||
/>
|
||||
<>
|
||||
<Link
|
||||
className="whitespace-nowrap font-bold leading-[2.3rem] tracking-tight text-light-900 dark:text-dark-900 sm:text-[1.2rem]"
|
||||
href={`${isTemplate ? "/templates" : "/boards"}/${board?.publicId}`}
|
||||
>
|
||||
{board?.name}
|
||||
</Link>
|
||||
<IoChevronForwardSharp
|
||||
size={18}
|
||||
className="mx-2 text-light-900 dark:text-dark-900"
|
||||
/>
|
||||
<form
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
className="w-full space-y-6"
|
||||
>
|
||||
<div>
|
||||
<input
|
||||
type="text"
|
||||
id="title"
|
||||
{...register("title")}
|
||||
onBlur={handleSubmit(onSubmit)}
|
||||
className="block w-full border-0 bg-transparent p-0 py-0 font-bold tracking-tight text-neutral-900 focus:ring-0 dark:text-dark-1000 sm:text-[1.2rem]"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
<div className="flex">
|
||||
<Dropdown />
|
||||
</div>
|
||||
</form>
|
||||
</>
|
||||
)}
|
||||
{!card && !isLoading && (
|
||||
<p className="block p-0 py-0 font-bold leading-[2.3rem] tracking-tight text-neutral-900 dark:text-dark-1000 sm:text-[1.2rem]">
|
||||
@@ -323,21 +286,6 @@ export default function CardPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
activeChecklistForm={activeChecklistForm}
|
||||
setActiveChecklistForm={setActiveChecklistForm}
|
||||
/>
|
||||
{!isTemplate && (
|
||||
<>
|
||||
{card?.attachments.length > 0 && (
|
||||
<div className="mt-6">
|
||||
<AttachmentThumbnails
|
||||
attachments={card.attachments}
|
||||
cardPublicId={cardId ?? ""}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="mt-6">
|
||||
<AttachmentUpload cardPublicId={cardId} />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<div className="border-t-[1px] border-light-300 pt-12 dark:border-dark-300">
|
||||
<h2 className="text-md pb-4 font-medium text-light-1000 dark:text-dark-1000">
|
||||
{t`Activity`}
|
||||
|
||||
@@ -9,7 +9,6 @@ import LabelIcon from "~/components/LabelIcon";
|
||||
import { useModal } from "~/providers/modal";
|
||||
import { api } from "~/utils/api";
|
||||
import ActivityList from "~/views/card/components/ActivityList";
|
||||
import { AttachmentThumbnails } from "~/views/card/components/AttachmentThumbnails";
|
||||
import Checklists from "~/views/card/components/Checklists";
|
||||
|
||||
export function CardModal({
|
||||
@@ -127,24 +126,11 @@ export function CardModal({
|
||||
<Editor
|
||||
content={data.description}
|
||||
readOnly
|
||||
workspaceMembers={
|
||||
data?.list.board.workspace.members ?? []
|
||||
}
|
||||
workspaceMembers={data?.list.board.workspace.members ?? []}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{data?.attachments &&
|
||||
data.attachments.length > 0 &&
|
||||
cardPublicId && (
|
||||
<div className="mb-10 max-w-2xl">
|
||||
<AttachmentThumbnails
|
||||
attachments={data.attachments}
|
||||
cardPublicId={cardPublicId}
|
||||
isReadOnly
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{data?.checklists && data.checklists.length > 0 && (
|
||||
<Checklists
|
||||
checklists={data.checklists}
|
||||
|
||||
@@ -44,7 +44,6 @@ export default function PublicBoardView() {
|
||||
workspaceSlug: workspaceSlug ?? "",
|
||||
members: formatToArray(router.query.members),
|
||||
labels: formatToArray(router.query.labels),
|
||||
lists: formatToArray(router.query.lists),
|
||||
},
|
||||
{
|
||||
enabled: router.isReady && !!boardSlug,
|
||||
@@ -131,7 +130,6 @@ export default function PublicBoardView() {
|
||||
<Filters
|
||||
labels={data.labels ?? []}
|
||||
members={[]}
|
||||
lists={data.allLists ?? []}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
</div>
|
||||
@@ -189,7 +187,6 @@ export default function PublicBoardView() {
|
||||
members={[]}
|
||||
description={card.description}
|
||||
comments={card.comments ?? []}
|
||||
attachments={card.attachments}
|
||||
/>
|
||||
</Link>
|
||||
))}
|
||||
|
||||
@@ -35,10 +35,8 @@ services:
|
||||
- SMTP_PASSWORD=${SMTP_PASSWORD}
|
||||
- SMTP_SECURE=${SMTP_SECURE}
|
||||
- EMAIL_FROM=${EMAIL_FROM}
|
||||
|
||||
# Notifications
|
||||
- NOVU_API_KEY=${NOVU_API_KEY}
|
||||
- DISCORD_WEBHOOK_URL=${DISCORD_WEBHOOK_URL}
|
||||
- PLUNK_API_KEY=${PLUNK_API_KEY}
|
||||
- PLUNK_API_URL=${PLUNK_API_URL}
|
||||
|
||||
# S3 storage
|
||||
- S3_ACCESS_KEY_ID=${S3_ACCESS_KEY_ID}
|
||||
@@ -48,7 +46,6 @@ services:
|
||||
- S3_FORCE_PATH_STYLE=${S3_FORCE_PATH_STYLE}
|
||||
- NEXT_PUBLIC_STORAGE_URL=${NEXT_PUBLIC_STORAGE_URL}
|
||||
- NEXT_PUBLIC_AVATAR_BUCKET_NAME=${NEXT_PUBLIC_AVATAR_BUCKET_NAME}
|
||||
- NEXT_PUBLIC_ATTACHMENTS_BUCKET_NAME=${NEXT_PUBLIC_ATTACHMENTS_BUCKET_NAME}
|
||||
- NEXT_PUBLIC_STORAGE_DOMAIN=${NEXT_PUBLIC_STORAGE_DOMAIN}
|
||||
|
||||
# Auth config
|
||||
|
||||
@@ -36,7 +36,6 @@ services:
|
||||
- S3_FORCE_PATH_STYLE=${S3_FORCE_PATH_STYLE}
|
||||
- NEXT_PUBLIC_STORAGE_URL=${NEXT_PUBLIC_STORAGE_URL}
|
||||
- NEXT_PUBLIC_AVATAR_BUCKET_NAME=${NEXT_PUBLIC_AVATAR_BUCKET_NAME}
|
||||
- NEXT_PUBLIC_ATTACHMENTS_BUCKET_NAME=${NEXT_PUBLIC_ATTACHMENTS_BUCKET_NAME}
|
||||
- NEXT_PUBLIC_STORAGE_DOMAIN=${NEXT_PUBLIC_STORAGE_DOMAIN}
|
||||
|
||||
# White label
|
||||
|
||||
@@ -35,8 +35,6 @@
|
||||
"typecheck": "tsc --noEmit --emitDeclarationOnly false"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.802.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.812.0",
|
||||
"@kan/auth": "workspace:*",
|
||||
"@kan/db": "workspace:*",
|
||||
"@kan/email": "workspace:^",
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { attachmentRouter } from "./routers/attachment";
|
||||
import { boardRouter } from "./routers/board";
|
||||
import { cardRouter } from "./routers/card";
|
||||
import { checklistRouter } from "./routers/checklist";
|
||||
@@ -13,7 +12,6 @@ import { workspaceRouter } from "./routers/workspace";
|
||||
import { createTRPCRouter } from "./trpc";
|
||||
|
||||
export const appRouter = createTRPCRouter({
|
||||
attachment: attachmentRouter,
|
||||
board: boardRouter,
|
||||
card: cardRouter,
|
||||
checklist: checklistRouter,
|
||||
|
||||
@@ -1,205 +0,0 @@
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { z } from "zod";
|
||||
|
||||
import * as cardRepo from "@kan/db/repository/card.repo";
|
||||
import * as cardActivityRepo from "@kan/db/repository/cardActivity.repo";
|
||||
import * as cardAttachmentRepo from "@kan/db/repository/cardAttachment.repo";
|
||||
import * as workspaceRepo from "@kan/db/repository/workspace.repo";
|
||||
import { generateUID } from "@kan/shared/utils";
|
||||
|
||||
import { createTRPCRouter, protectedProcedure } from "../trpc";
|
||||
import { assertUserInWorkspace } from "../utils/auth";
|
||||
import { generateUploadUrl } from "../utils/s3";
|
||||
|
||||
export const attachmentRouter = createTRPCRouter({
|
||||
generateUploadUrl: protectedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
summary: "Generate presigned URL for attachment upload",
|
||||
method: "POST",
|
||||
path: "/cards/{cardPublicId}/attachments/upload-url",
|
||||
description:
|
||||
"Generates a presigned URL for uploading an attachment to S3",
|
||||
tags: ["Attachments"],
|
||||
protect: true,
|
||||
},
|
||||
})
|
||||
.input(
|
||||
z.object({
|
||||
cardPublicId: z.string().min(12),
|
||||
filename: z.string().min(1).max(255),
|
||||
contentType: z.string(),
|
||||
size: z
|
||||
.number()
|
||||
.positive()
|
||||
.max(50 * 1024 * 1024), // 50MB max
|
||||
}),
|
||||
)
|
||||
.output(z.object({ url: z.string(), key: z.string() }))
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const userId = ctx.user?.id;
|
||||
|
||||
if (!userId)
|
||||
throw new TRPCError({
|
||||
message: `User not authenticated`,
|
||||
code: "UNAUTHORIZED",
|
||||
});
|
||||
|
||||
const card = await cardRepo.getWorkspaceAndCardIdByCardPublicId(
|
||||
ctx.db,
|
||||
input.cardPublicId,
|
||||
);
|
||||
|
||||
if (!card)
|
||||
throw new TRPCError({
|
||||
message: `Card with public ID ${input.cardPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, card.workspaceId);
|
||||
|
||||
// Get workspace publicId
|
||||
const workspace = await workspaceRepo.getById(ctx.db, card.workspaceId);
|
||||
if (!workspace)
|
||||
throw new TRPCError({
|
||||
message: `Workspace not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
const bucket = process.env.NEXT_PUBLIC_ATTACHMENTS_BUCKET_NAME;
|
||||
if (!bucket)
|
||||
throw new TRPCError({
|
||||
message: `Attachments bucket not configured`,
|
||||
code: "INTERNAL_SERVER_ERROR",
|
||||
});
|
||||
|
||||
// Sanitize filename
|
||||
const sanitizedFilename = input.filename
|
||||
.replace(/[^a-zA-Z0-9._-]/g, "_")
|
||||
.substring(0, 200);
|
||||
|
||||
const s3Key = `${workspace.publicId}/${input.cardPublicId}/${generateUID()}-${sanitizedFilename}`;
|
||||
|
||||
const url = await generateUploadUrl(
|
||||
bucket,
|
||||
s3Key,
|
||||
input.contentType,
|
||||
3600, // 1 hour
|
||||
);
|
||||
|
||||
return { url, key: s3Key };
|
||||
}),
|
||||
confirm: protectedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
summary: "Confirm attachment upload and save to database",
|
||||
method: "POST",
|
||||
path: "/cards/{cardPublicId}/attachments/confirm",
|
||||
description:
|
||||
"Confirms an attachment upload and saves the record to the database",
|
||||
tags: ["Attachments"],
|
||||
protect: true,
|
||||
},
|
||||
})
|
||||
.input(
|
||||
z.object({
|
||||
cardPublicId: z.string().min(12),
|
||||
s3Key: z.string(),
|
||||
filename: z.string(),
|
||||
originalFilename: z.string(),
|
||||
contentType: z.string(),
|
||||
size: z.number().positive(),
|
||||
}),
|
||||
)
|
||||
.output(z.custom<Awaited<ReturnType<typeof cardAttachmentRepo.create>>>())
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const userId = ctx.user?.id;
|
||||
|
||||
if (!userId)
|
||||
throw new TRPCError({
|
||||
message: `User not authenticated`,
|
||||
code: "UNAUTHORIZED",
|
||||
});
|
||||
|
||||
const card = await cardRepo.getWorkspaceAndCardIdByCardPublicId(
|
||||
ctx.db,
|
||||
input.cardPublicId,
|
||||
);
|
||||
|
||||
if (!card)
|
||||
throw new TRPCError({
|
||||
message: `Card with public ID ${input.cardPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, card.workspaceId);
|
||||
|
||||
const attachment = await cardAttachmentRepo.create(ctx.db, {
|
||||
cardId: card.id,
|
||||
filename: input.filename,
|
||||
originalFilename: input.originalFilename,
|
||||
contentType: input.contentType,
|
||||
size: input.size,
|
||||
s3Key: input.s3Key,
|
||||
createdBy: userId,
|
||||
});
|
||||
|
||||
await cardActivityRepo.create(ctx.db, {
|
||||
type: "card.updated.attachment.added",
|
||||
cardId: card.id,
|
||||
createdBy: userId,
|
||||
});
|
||||
|
||||
return attachment;
|
||||
}),
|
||||
delete: protectedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
summary: "Delete an attachment",
|
||||
method: "DELETE",
|
||||
path: "/attachments/{attachmentPublicId}",
|
||||
description: "Soft deletes an attachment",
|
||||
tags: ["Attachments"],
|
||||
protect: true,
|
||||
},
|
||||
})
|
||||
.input(z.object({ attachmentPublicId: z.string().min(12) }))
|
||||
.output(z.object({ success: z.boolean() }))
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const userId = ctx.user?.id;
|
||||
|
||||
if (!userId)
|
||||
throw new TRPCError({
|
||||
message: `User not authenticated`,
|
||||
code: "UNAUTHORIZED",
|
||||
});
|
||||
|
||||
const attachment = await cardAttachmentRepo.getByPublicId(
|
||||
ctx.db,
|
||||
input.attachmentPublicId,
|
||||
);
|
||||
|
||||
if (!attachment || attachment.deletedAt)
|
||||
throw new TRPCError({
|
||||
message: `Attachment with public ID ${input.attachmentPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
const workspaceId = attachment.card.list.board.workspaceId;
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, workspaceId);
|
||||
|
||||
await cardAttachmentRepo.softDelete(ctx.db, {
|
||||
attachmentId: attachment.id,
|
||||
deletedAt: new Date(),
|
||||
});
|
||||
|
||||
await cardActivityRepo.create(ctx.db, {
|
||||
type: "card.updated.attachment.removed",
|
||||
cardId: attachment.cardId,
|
||||
createdBy: userId,
|
||||
});
|
||||
|
||||
return { success: true };
|
||||
}),
|
||||
});
|
||||
@@ -78,7 +78,6 @@ export const boardRouter = createTRPCRouter({
|
||||
boardPublicId: z.string().min(12),
|
||||
members: z.array(z.string().min(12)).optional(),
|
||||
labels: z.array(z.string().min(12)).optional(),
|
||||
lists: z.array(z.string().min(12)).optional(),
|
||||
type: z.enum(["regular", "template"]).optional(),
|
||||
}),
|
||||
)
|
||||
@@ -111,7 +110,6 @@ export const boardRouter = createTRPCRouter({
|
||||
{
|
||||
members: input.members ?? [],
|
||||
labels: input.labels ?? [],
|
||||
lists: input.lists ?? [],
|
||||
type: input.type,
|
||||
},
|
||||
);
|
||||
@@ -144,7 +142,6 @@ export const boardRouter = createTRPCRouter({
|
||||
.regex(/^(?![-]+$)[a-zA-Z0-9-]+$/),
|
||||
members: z.array(z.string().min(12)).optional(),
|
||||
labels: z.array(z.string().min(12)).optional(),
|
||||
lists: z.array(z.string().min(12)).optional(),
|
||||
}),
|
||||
)
|
||||
.output(z.custom<Awaited<ReturnType<typeof boardRepo.getBySlug>>>())
|
||||
@@ -167,7 +164,6 @@ export const boardRouter = createTRPCRouter({
|
||||
{
|
||||
members: input.members ?? [],
|
||||
labels: input.labels ?? [],
|
||||
lists: input.lists ?? [],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -238,7 +234,6 @@ export const boardRouter = createTRPCRouter({
|
||||
{
|
||||
members: [],
|
||||
labels: [],
|
||||
lists: [],
|
||||
type: sourceBoardInfo.type,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -10,7 +10,6 @@ import * as workspaceRepo from "@kan/db/repository/workspace.repo";
|
||||
|
||||
import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc";
|
||||
import { assertUserInWorkspace } from "../utils/auth";
|
||||
import { generateDownloadUrl } from "../utils/s3";
|
||||
|
||||
export const cardRouter = createTRPCRouter({
|
||||
create: protectedProcedure
|
||||
@@ -575,21 +574,7 @@ export const cardRouter = createTRPCRouter({
|
||||
.input(z.object({ cardPublicId: z.string().min(12) }))
|
||||
.output(
|
||||
z.custom<
|
||||
Omit<
|
||||
NonNullable<
|
||||
Awaited<ReturnType<typeof cardRepo.getWithListAndMembersByPublicId>>
|
||||
>,
|
||||
"attachments"
|
||||
> & {
|
||||
attachments: {
|
||||
publicId: string;
|
||||
contentType: string;
|
||||
s3Key: string;
|
||||
originalFilename: string | null;
|
||||
size?: number | null;
|
||||
url: string | null;
|
||||
}[];
|
||||
}
|
||||
Awaited<ReturnType<typeof cardRepo.getWithListAndMembersByPublicId>>
|
||||
>(),
|
||||
)
|
||||
.query(async ({ ctx, input }) => {
|
||||
@@ -627,46 +612,7 @@ export const cardRouter = createTRPCRouter({
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
// Generate URLs for all attachments
|
||||
const bucket = process.env.NEXT_PUBLIC_ATTACHMENTS_BUCKET_NAME;
|
||||
if (result.attachments && Array.isArray(result.attachments)) {
|
||||
const attachments = result.attachments as {
|
||||
publicId: string;
|
||||
contentType: string;
|
||||
s3Key: string;
|
||||
originalFilename: string | null;
|
||||
size?: number | null;
|
||||
}[];
|
||||
|
||||
const attachmentsWithUrls = await Promise.all(
|
||||
attachments.map(async (attachment) => {
|
||||
const base = {
|
||||
publicId: attachment.publicId,
|
||||
contentType: attachment.contentType,
|
||||
s3Key: attachment.s3Key,
|
||||
originalFilename: attachment.originalFilename,
|
||||
size: attachment.size,
|
||||
};
|
||||
if (!bucket || !attachment.s3Key) {
|
||||
return { ...base, url: null };
|
||||
}
|
||||
try {
|
||||
const url = await generateDownloadUrl(
|
||||
bucket,
|
||||
attachment.s3Key,
|
||||
86400, // 24 hours expiration
|
||||
);
|
||||
return { ...base, url };
|
||||
} catch {
|
||||
// If URL generation fails, return attachment with url: null
|
||||
return { ...base, url: null };
|
||||
}
|
||||
}),
|
||||
);
|
||||
return { ...result, attachments: attachmentsWithUrls };
|
||||
}
|
||||
|
||||
return { ...result, attachments: [] };
|
||||
return result;
|
||||
}),
|
||||
update: protectedProcedure
|
||||
.meta({
|
||||
|
||||
@@ -4,7 +4,6 @@ import { z } from "zod";
|
||||
import * as boardRepo from "@kan/db/repository/board.repo";
|
||||
import * as cardRepo from "@kan/db/repository/card.repo";
|
||||
import * as cardActivityRepo from "@kan/db/repository/cardActivity.repo";
|
||||
import * as checklistRepo from "@kan/db/repository/checklist.repo";
|
||||
import * as importRepo from "@kan/db/repository/import.repo";
|
||||
import * as integrationsRepo from "@kan/db/repository/integration.repo";
|
||||
import * as labelRepo from "@kan/db/repository/label.repo";
|
||||
@@ -23,7 +22,6 @@ export interface TrelloBoard {
|
||||
labels: TrelloLabel[];
|
||||
lists: TrelloList[];
|
||||
cards: TrelloCard[];
|
||||
checklists: TrelloChecklist[];
|
||||
}
|
||||
|
||||
interface TrelloLabel {
|
||||
@@ -36,34 +34,12 @@ interface TrelloList {
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface TrelloChecklist {
|
||||
id: string;
|
||||
idCard: string;
|
||||
name: string;
|
||||
checkItems: TrelloCheckItem[];
|
||||
}
|
||||
|
||||
interface TrelloCheckItem {
|
||||
id: string;
|
||||
name: string;
|
||||
state: "complete" | "incomplete";
|
||||
pos: number;
|
||||
}
|
||||
|
||||
interface TrelloCard {
|
||||
id: string;
|
||||
name: string;
|
||||
desc: string;
|
||||
idList: string;
|
||||
labels: TrelloLabel[];
|
||||
idChecklists: string[];
|
||||
checkItemStates: TrelloCheckItemState[];
|
||||
}
|
||||
|
||||
interface TrelloCheckItemState {
|
||||
idChecklist: string;
|
||||
idCheckItem: string;
|
||||
state: "complete" | "incomplete";
|
||||
}
|
||||
|
||||
export const importRouter = createTRPCRouter({
|
||||
@@ -194,7 +170,7 @@ export const importRouter = createTRPCRouter({
|
||||
|
||||
for (const boardId of input.boardIds) {
|
||||
const response = await fetch(
|
||||
`${urls.trello}/boards/${boardId}?key=${apiKey}&token=${integration.accessToken}&lists=open&cards=open&labels=all&checklists=all&checkItemStates=all`,
|
||||
`${urls.trello}/boards/${boardId}?key=${apiKey}&token=${integration.accessToken}&lists=open&cards=open&labels=all`,
|
||||
);
|
||||
const data = (await response.json()) as TrelloBoard;
|
||||
|
||||
@@ -218,18 +194,6 @@ export const importRouter = createTRPCRouter({
|
||||
sourceId: label.id,
|
||||
name: label.name,
|
||||
})),
|
||||
checklists: data.checklists
|
||||
.filter((checklist) => checklist.idCard === _card.id)
|
||||
.map((_checklist) => ({
|
||||
sourceId: _checklist.id,
|
||||
name: _checklist.name,
|
||||
items: _checklist.checkItems.map((_item) => ({
|
||||
sourceId: _item.id,
|
||||
title: _item.name,
|
||||
completed: _item.state === "complete",
|
||||
index: _item.pos,
|
||||
})),
|
||||
})),
|
||||
})),
|
||||
})),
|
||||
};
|
||||
@@ -325,97 +289,6 @@ export const importRouter = createTRPCRouter({
|
||||
await cardActivityRepo.bulkCreate(ctx.db, activities);
|
||||
}
|
||||
|
||||
const checklistsToCreate: {
|
||||
cardId: number;
|
||||
name: string;
|
||||
createdBy: string;
|
||||
index: number;
|
||||
sourceId: string;
|
||||
items: {
|
||||
sourceId: string;
|
||||
title: string;
|
||||
completed: boolean;
|
||||
index: number;
|
||||
}[];
|
||||
}[] = [];
|
||||
|
||||
for (const card of list.cards) {
|
||||
const _card = createdCards.find(
|
||||
(c) => c.sourceId === card.sourceId,
|
||||
);
|
||||
|
||||
if (!_card || !card.checklists.length) continue;
|
||||
|
||||
for (
|
||||
let checklistIndex = 0;
|
||||
checklistIndex < card.checklists.length;
|
||||
checklistIndex++
|
||||
) {
|
||||
const checklist = card.checklists[checklistIndex];
|
||||
if (!checklist) continue;
|
||||
|
||||
checklistsToCreate.push({
|
||||
cardId: _card.id,
|
||||
name: checklist.name,
|
||||
createdBy: userId,
|
||||
index: checklistIndex,
|
||||
sourceId: checklist.sourceId,
|
||||
items: checklist.items.map((item) => ({
|
||||
sourceId: item.sourceId,
|
||||
title: item.title,
|
||||
completed: item.completed,
|
||||
index: item.index,
|
||||
})),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (checklistsToCreate.length > 0) {
|
||||
const newChecklists = await checklistRepo.bulkCreate(
|
||||
ctx.db,
|
||||
checklistsToCreate.map((checklist) => ({
|
||||
cardId: checklist.cardId,
|
||||
name: checklist.name,
|
||||
createdBy: checklist.createdBy,
|
||||
index: checklist.index,
|
||||
})),
|
||||
);
|
||||
|
||||
const itemsToCreate: {
|
||||
checklistId: number;
|
||||
title: string;
|
||||
createdBy: string;
|
||||
index: number;
|
||||
completed: boolean;
|
||||
}[] = [];
|
||||
|
||||
for (let i = 0; i < checklistsToCreate.length; i++) {
|
||||
const checklistData = checklistsToCreate[i];
|
||||
const newChecklist = newChecklists[i];
|
||||
|
||||
if (!newChecklist || !checklistData?.items.length) continue;
|
||||
|
||||
// NOTE: Sorting here to prevent checklist items being out of order
|
||||
const sortedItems = [...checklistData.items].sort(
|
||||
(a, b) => a.index - b.index,
|
||||
);
|
||||
|
||||
for (const item of sortedItems) {
|
||||
itemsToCreate.push({
|
||||
checklistId: newChecklist.id,
|
||||
title: item.title,
|
||||
createdBy: userId,
|
||||
index: item.index,
|
||||
completed: item.completed,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (itemsToCreate.length > 0) {
|
||||
await checklistRepo.bulkCreateItems(ctx.db, itemsToCreate);
|
||||
}
|
||||
}
|
||||
|
||||
if (createdLabels.length && createdCards.length) {
|
||||
const cardLabelRelations: {
|
||||
cardId: number;
|
||||
|
||||
@@ -476,7 +476,7 @@ export const memberRouter = createTRPCRouter({
|
||||
openapi: {
|
||||
summary: "Get invite information by code",
|
||||
method: "GET",
|
||||
path: "/invites/{inviteCode}",
|
||||
path: "/workspaces/{workspacePublicId}/invites/{inviteCode}",
|
||||
description: "Get invite information by invite code",
|
||||
tags: ["Invites"],
|
||||
protect: false,
|
||||
@@ -521,7 +521,7 @@ export const memberRouter = createTRPCRouter({
|
||||
openapi: {
|
||||
summary: "Accept an invite link",
|
||||
method: "POST",
|
||||
path: "/invites/accept",
|
||||
path: "/workspaces/{workspacePublicId}/invites/accept",
|
||||
description: "Accepts an invitation via invite link",
|
||||
tags: ["Invites"],
|
||||
protect: false,
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
import {
|
||||
GetObjectCommand,
|
||||
PutObjectCommand,
|
||||
S3Client,
|
||||
} from "@aws-sdk/client-s3";
|
||||
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
||||
|
||||
export function createS3Client() {
|
||||
return new S3Client({
|
||||
region: process.env.S3_REGION ?? "",
|
||||
endpoint: process.env.S3_ENDPOINT ?? "",
|
||||
forcePathStyle: process.env.S3_FORCE_PATH_STYLE === "true",
|
||||
credentials: {
|
||||
accessKeyId: process.env.S3_ACCESS_KEY_ID ?? "",
|
||||
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY ?? "",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export async function generateUploadUrl(
|
||||
bucket: string,
|
||||
key: string,
|
||||
contentType: string,
|
||||
expiresIn = 3600,
|
||||
) {
|
||||
const client = createS3Client();
|
||||
return getSignedUrl(
|
||||
client,
|
||||
new PutObjectCommand({
|
||||
Bucket: bucket,
|
||||
Key: key,
|
||||
ContentType: contentType,
|
||||
// Don't set ACL for private files
|
||||
}),
|
||||
{ expiresIn },
|
||||
);
|
||||
}
|
||||
|
||||
export async function generateDownloadUrl(
|
||||
bucket: string,
|
||||
key: string,
|
||||
expiresIn = 3600,
|
||||
) {
|
||||
const client = createS3Client();
|
||||
return getSignedUrl(
|
||||
client,
|
||||
new GetObjectCommand({
|
||||
Bucket: bucket,
|
||||
Key: key,
|
||||
}),
|
||||
{ expiresIn },
|
||||
);
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
import type { Subscription } from "@better-auth/stripe";
|
||||
import type Stripe from "stripe";
|
||||
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
|
||||
import { stripe } from "@better-auth/stripe";
|
||||
import { ChatOrPushProviderEnum } from "@novu/api/models/components";
|
||||
import { betterAuth } from "better-auth";
|
||||
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
||||
import { createAuthEndpoint, createAuthMiddleware } from "better-auth/api";
|
||||
@@ -17,7 +14,7 @@ import * as subscriptionRepo from "@kan/db/repository/subscription.repo";
|
||||
import * as userRepo from "@kan/db/repository/user.repo";
|
||||
import * as workspaceRepo from "@kan/db/repository/workspace.repo";
|
||||
import * as schema from "@kan/db/schema";
|
||||
import { notificationClient, sendEmail } from "@kan/email";
|
||||
import { cloudMailerClient, sendEmail } from "@kan/email";
|
||||
import { createStripeClient } from "@kan/stripe";
|
||||
|
||||
export const configuredProviders = socialProviderList.reduce<
|
||||
@@ -132,11 +129,6 @@ export const initAuth = (db: dbClient) => {
|
||||
user: schema.users,
|
||||
},
|
||||
}),
|
||||
session: {
|
||||
expiresIn: 60 * 60 * 24 * 30, // 30 days
|
||||
updateAge: 60 * 60 * 24 * 2, // Update session expiry every 48 hours if user is active
|
||||
freshAge: 0,
|
||||
},
|
||||
emailAndPassword: {
|
||||
enabled: env("NEXT_PUBLIC_ALLOW_CREDENTIALS")?.toLowerCase() === "true",
|
||||
disableSignUp:
|
||||
@@ -181,17 +173,19 @@ export const initAuth = (db: dbClient) => {
|
||||
freeTrial: {
|
||||
days: 14,
|
||||
onTrialStart: async (subscription) => {
|
||||
await triggerWorkflow(db, "trial-start", subscription);
|
||||
// Called when a trial starts
|
||||
// @todo: send trial start email
|
||||
// await sendTrialStartEmail(subscription.referenceId);
|
||||
},
|
||||
onTrialEnd: async ({ subscription }) => {
|
||||
await triggerWorkflow(db, "trial-end", subscription);
|
||||
onTrialEnd: async ({ subscription }, request) => {
|
||||
// Called when a trial ends
|
||||
// @todo: send trial end email
|
||||
// await sendTrialEndEmail(user.email);
|
||||
},
|
||||
onTrialExpired: async (subscription) => {
|
||||
await triggerWorkflow(
|
||||
db,
|
||||
"trial-expired",
|
||||
subscription,
|
||||
);
|
||||
// Called when a trial expires without conversion
|
||||
// @todo: send trial expired email
|
||||
// await sendTrialExpiredEmail(subscription.referenceId);
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -203,17 +197,19 @@ export const initAuth = (db: dbClient) => {
|
||||
freeTrial: {
|
||||
days: 14,
|
||||
onTrialStart: async (subscription) => {
|
||||
await triggerWorkflow(db, "trial-start", subscription);
|
||||
// Called when a trial starts
|
||||
// @todo: send trial start email
|
||||
// await sendTrialStartEmail(subscription.referenceId);
|
||||
},
|
||||
onTrialEnd: async ({ subscription }) => {
|
||||
await triggerWorkflow(db, "trial-end", subscription);
|
||||
onTrialEnd: async ({ subscription }, request) => {
|
||||
// Called when a trial ends
|
||||
// @todo: send trial end email
|
||||
// await sendTrialEndEmail(user.email);
|
||||
},
|
||||
onTrialExpired: async (subscription) => {
|
||||
await triggerWorkflow(
|
||||
db,
|
||||
"trial-expired",
|
||||
subscription,
|
||||
);
|
||||
// Called when a trial expires without conversion
|
||||
// @todo: send trial expired email
|
||||
// await sendTrialExpiredEmail(subscription.referenceId);
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -347,7 +343,17 @@ export const initAuth = (db: dbClient) => {
|
||||
return Promise.resolve(true);
|
||||
},
|
||||
async after(user) {
|
||||
let avatarKey = user.image;
|
||||
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!)
|
||||
@@ -380,9 +386,6 @@ export const initAuth = (db: dbClient) => {
|
||||
ACL: "public-read",
|
||||
}),
|
||||
);
|
||||
|
||||
avatarKey = key;
|
||||
|
||||
await userRepo.update(db, user.id, {
|
||||
image: key,
|
||||
});
|
||||
@@ -390,51 +393,6 @@ export const initAuth = (db: dbClient) => {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
if (notificationClient) {
|
||||
try {
|
||||
const [firstName, ...rest] = user.name
|
||||
.split(" ")
|
||||
.filter(Boolean);
|
||||
const lastName = rest.length ? rest.join(" ") : undefined;
|
||||
const avatarUrl = avatarKey
|
||||
? `${env("NEXT_PUBLIC_STORAGE_URL")}/${env("NEXT_PUBLIC_AVATAR_BUCKET_NAME")}/${avatarKey}`
|
||||
: undefined;
|
||||
|
||||
await notificationClient.trigger({
|
||||
to: {
|
||||
subscriberId: user.id,
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
email: user.email,
|
||||
avatar: avatarUrl,
|
||||
data: {
|
||||
emailVerified: user.emailVerified,
|
||||
stripeCustomerId: user.stripeCustomerId,
|
||||
createdAt: user.createdAt,
|
||||
updatedAt: user.updatedAt,
|
||||
},
|
||||
},
|
||||
workflowId: "user-signup",
|
||||
});
|
||||
|
||||
await notificationClient.subscribers.credentials.update(
|
||||
{
|
||||
providerId: ChatOrPushProviderEnum.Discord,
|
||||
credentials: {
|
||||
webhookUrl: process.env.DISCORD_WEBHOOK_URL!,
|
||||
},
|
||||
integrationIdentifier: "discord",
|
||||
},
|
||||
user.id,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
"Error adding user to notification client",
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -472,34 +430,3 @@ export const initAuth = (db: dbClient) => {
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
async function triggerWorkflow(
|
||||
db: dbClient,
|
||||
workflowId: string,
|
||||
subscription: Subscription,
|
||||
cancellationDetails?: Stripe.Subscription.CancellationDetails | null,
|
||||
) {
|
||||
try {
|
||||
if (!subscription.stripeCustomerId || !notificationClient) return;
|
||||
|
||||
const user = await userRepo.getByStripeCustomerId(
|
||||
db,
|
||||
subscription.stripeCustomerId,
|
||||
);
|
||||
|
||||
if (!user || !notificationClient) return;
|
||||
|
||||
await notificationClient.trigger({
|
||||
to: {
|
||||
subscriberId: user.id,
|
||||
},
|
||||
payload: {
|
||||
...subscription,
|
||||
cancellationDetails,
|
||||
},
|
||||
workflowId,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error triggering workflow", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
ALTER TYPE "public"."card_activity_type" ADD VALUE 'card.updated.attachment.added' BEFORE 'card.archived';--> statement-breakpoint
|
||||
ALTER TYPE "public"."card_activity_type" ADD VALUE 'card.updated.attachment.removed' BEFORE 'card.archived';--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "card_attachment" (
|
||||
"id" bigserial PRIMARY KEY NOT NULL,
|
||||
"publicId" varchar(12) NOT NULL,
|
||||
"cardId" bigint NOT NULL,
|
||||
"filename" varchar(255) NOT NULL,
|
||||
"originalFilename" varchar(255) NOT NULL,
|
||||
"contentType" varchar(100) NOT NULL,
|
||||
"size" bigint NOT NULL,
|
||||
"s3Key" varchar(500) NOT NULL,
|
||||
"createdBy" uuid,
|
||||
"createdAt" timestamp DEFAULT now() NOT NULL,
|
||||
"deletedAt" timestamp,
|
||||
CONSTRAINT "card_attachment_publicId_unique" UNIQUE("publicId")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "card_attachment" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "card_attachment" ADD CONSTRAINT "card_attachment_cardId_card_id_fk" FOREIGN KEY ("cardId") REFERENCES "public"."card"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "card_attachment" ADD CONSTRAINT "card_attachment_createdBy_user_id_fk" FOREIGN KEY ("createdBy") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -134,13 +134,6 @@
|
||||
"when": 1760044396109,
|
||||
"tag": "20251009211316_AddBoardSourceIdToCardActivity",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 19,
|
||||
"version": "7",
|
||||
"when": 1762807463569,
|
||||
"tag": "20251110204423_AddCardAttachments",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import type { BoardVisibilityStatus } from "@kan/db/schema";
|
||||
import {
|
||||
boards,
|
||||
cardActivities,
|
||||
cardAttachments,
|
||||
cards,
|
||||
cardsToLabels,
|
||||
cardToWorkspaceMembers,
|
||||
@@ -71,7 +70,6 @@ export const getByPublicId = async (
|
||||
filters: {
|
||||
members: string[];
|
||||
labels: string[];
|
||||
lists: string[];
|
||||
type: "regular" | "template" | undefined;
|
||||
},
|
||||
) => {
|
||||
@@ -197,13 +195,6 @@ export const getByPublicId = async (
|
||||
},
|
||||
},
|
||||
},
|
||||
attachments: {
|
||||
columns: {
|
||||
publicId: true,
|
||||
},
|
||||
where: isNull(cardAttachments.deletedAt),
|
||||
orderBy: asc(cardAttachments.createdAt),
|
||||
},
|
||||
checklists: {
|
||||
columns: {
|
||||
publicId: true,
|
||||
@@ -240,19 +231,6 @@ export const getByPublicId = async (
|
||||
orderBy: [asc(cards.index)],
|
||||
},
|
||||
},
|
||||
where: and(
|
||||
isNull(lists.deletedAt),
|
||||
filters.lists.length > 0
|
||||
? inArray(lists.publicId, filters.lists)
|
||||
: undefined,
|
||||
),
|
||||
orderBy: [asc(lists.index)],
|
||||
},
|
||||
allLists: {
|
||||
columns: {
|
||||
publicId: true,
|
||||
name: true,
|
||||
},
|
||||
where: isNull(lists.deletedAt),
|
||||
orderBy: [asc(lists.index)],
|
||||
},
|
||||
@@ -290,7 +268,6 @@ export const getBySlug = async (
|
||||
filters: {
|
||||
members: string[];
|
||||
labels: string[];
|
||||
lists: string[];
|
||||
},
|
||||
) => {
|
||||
let cardIds: string[] = [];
|
||||
@@ -366,13 +343,6 @@ export const getBySlug = async (
|
||||
},
|
||||
},
|
||||
},
|
||||
attachments: {
|
||||
columns: {
|
||||
publicId: true,
|
||||
},
|
||||
where: isNull(cardAttachments.deletedAt),
|
||||
orderBy: asc(cardAttachments.createdAt),
|
||||
},
|
||||
comments: {
|
||||
columns: {
|
||||
publicId: true,
|
||||
@@ -409,19 +379,6 @@ export const getBySlug = async (
|
||||
orderBy: [asc(cards.index)],
|
||||
},
|
||||
},
|
||||
where: and(
|
||||
isNull(lists.deletedAt),
|
||||
filters.lists.length > 0
|
||||
? inArray(lists.publicId, filters.lists)
|
||||
: undefined,
|
||||
),
|
||||
orderBy: [asc(lists.index)],
|
||||
},
|
||||
allLists: {
|
||||
columns: {
|
||||
publicId: true,
|
||||
name: true,
|
||||
},
|
||||
where: isNull(lists.deletedAt),
|
||||
orderBy: [asc(lists.index)],
|
||||
},
|
||||
|
||||
@@ -3,7 +3,6 @@ import { and, asc, desc, eq, gt, inArray, isNull, sql } from "drizzle-orm";
|
||||
import type { dbClient } from "@kan/db/client";
|
||||
import {
|
||||
cardActivities,
|
||||
cardAttachments,
|
||||
cards,
|
||||
cardsToLabels,
|
||||
cardToWorkspaceMembers,
|
||||
@@ -410,17 +409,6 @@ export const getWithListAndMembersByPublicId = async (
|
||||
},
|
||||
},
|
||||
},
|
||||
attachments: {
|
||||
columns: {
|
||||
publicId: true,
|
||||
contentType: true,
|
||||
s3Key: true,
|
||||
originalFilename: true,
|
||||
size: true,
|
||||
},
|
||||
where: isNull(cardAttachments.deletedAt),
|
||||
orderBy: asc(cardAttachments.createdAt),
|
||||
},
|
||||
checklists: {
|
||||
columns: {
|
||||
publicId: true,
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
import { and, eq, isNull } from "drizzle-orm";
|
||||
|
||||
import type { dbClient } from "@kan/db/client";
|
||||
import { cardAttachments } from "@kan/db/schema";
|
||||
import { generateUID } from "@kan/shared/utils";
|
||||
|
||||
export const create = async (
|
||||
db: dbClient,
|
||||
attachmentInput: {
|
||||
cardId: number;
|
||||
filename: string;
|
||||
originalFilename: string;
|
||||
contentType: string;
|
||||
size: number;
|
||||
s3Key: string;
|
||||
createdBy: string;
|
||||
},
|
||||
) => {
|
||||
const [result] = await db
|
||||
.insert(cardAttachments)
|
||||
.values({
|
||||
publicId: generateUID(),
|
||||
cardId: attachmentInput.cardId,
|
||||
filename: attachmentInput.filename,
|
||||
originalFilename: attachmentInput.originalFilename,
|
||||
contentType: attachmentInput.contentType,
|
||||
size: attachmentInput.size,
|
||||
s3Key: attachmentInput.s3Key,
|
||||
createdBy: attachmentInput.createdBy,
|
||||
})
|
||||
.returning({
|
||||
id: cardAttachments.id,
|
||||
publicId: cardAttachments.publicId,
|
||||
filename: cardAttachments.filename,
|
||||
originalFilename: cardAttachments.originalFilename,
|
||||
contentType: cardAttachments.contentType,
|
||||
size: cardAttachments.size,
|
||||
s3Key: cardAttachments.s3Key,
|
||||
createdBy: cardAttachments.createdBy,
|
||||
createdAt: cardAttachments.createdAt,
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
export const getByPublicId = (db: dbClient, publicId: string) => {
|
||||
return db.query.cardAttachments.findFirst({
|
||||
where: eq(cardAttachments.publicId, publicId),
|
||||
with: {
|
||||
card: {
|
||||
columns: {
|
||||
id: true,
|
||||
publicId: true,
|
||||
},
|
||||
with: {
|
||||
list: {
|
||||
columns: {
|
||||
id: true,
|
||||
},
|
||||
with: {
|
||||
board: {
|
||||
columns: {
|
||||
id: true,
|
||||
workspaceId: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const getAllByCardId = (db: dbClient, cardId: number) => {
|
||||
return db.query.cardAttachments.findMany({
|
||||
where: and(
|
||||
eq(cardAttachments.cardId, cardId),
|
||||
isNull(cardAttachments.deletedAt),
|
||||
),
|
||||
orderBy: (attachments, { desc }) => [desc(attachments.createdAt)],
|
||||
});
|
||||
};
|
||||
|
||||
export const softDelete = async (
|
||||
db: dbClient,
|
||||
args: {
|
||||
attachmentId: number;
|
||||
deletedAt: Date;
|
||||
},
|
||||
) => {
|
||||
const [result] = await db
|
||||
.update(cardAttachments)
|
||||
.set({ deletedAt: args.deletedAt })
|
||||
.where(eq(cardAttachments.id, args.attachmentId))
|
||||
.returning({ id: cardAttachments.id });
|
||||
|
||||
return result;
|
||||
};
|
||||
@@ -46,7 +46,6 @@ export const createItem = async (
|
||||
checklistId: number;
|
||||
title: string;
|
||||
createdBy: string;
|
||||
completed?: boolean;
|
||||
},
|
||||
) => {
|
||||
return db.transaction(async (tx) => {
|
||||
@@ -66,7 +65,7 @@ export const createItem = async (
|
||||
createdBy: checklistItemInput.createdBy,
|
||||
checklistId: checklistItemInput.checklistId,
|
||||
index: lastItem ? lastItem.index + 1 : 0,
|
||||
completed: checklistItemInput.completed ?? false,
|
||||
completed: false,
|
||||
})
|
||||
.returning({
|
||||
id: checklistItems.id,
|
||||
@@ -215,129 +214,3 @@ export const updateChecklistById = async (
|
||||
.returning({ publicId: checklists.publicId, name: checklists.name });
|
||||
return result;
|
||||
};
|
||||
|
||||
export const bulkCreate = async (
|
||||
db: dbClient,
|
||||
checklistInput: {
|
||||
cardId: number;
|
||||
name: string;
|
||||
createdBy: string;
|
||||
index: number;
|
||||
}[],
|
||||
) => {
|
||||
if (checklistInput.length === 0) return [];
|
||||
|
||||
return db.transaction(async (tx) => {
|
||||
const byCard = groupByKey(checklistInput, "cardId");
|
||||
|
||||
const allValuesToInsert: {
|
||||
publicId: string;
|
||||
cardId: number;
|
||||
name: string;
|
||||
createdBy: string;
|
||||
index: number;
|
||||
}[] = [];
|
||||
|
||||
for (const [cardId, items] of byCard.entries()) {
|
||||
const last = await tx.query.checklists.findFirst({
|
||||
columns: { index: true },
|
||||
where: and(eq(checklists.cardId, cardId), isNull(checklists.deletedAt)),
|
||||
orderBy: [desc(checklists.index)],
|
||||
});
|
||||
|
||||
let nextIndex = last ? last.index + 1 : 0;
|
||||
|
||||
const sorted = [...items].sort((a, b) => a.index - b.index);
|
||||
|
||||
for (const item of sorted) {
|
||||
allValuesToInsert.push({
|
||||
publicId: generateUID(),
|
||||
...item,
|
||||
index: nextIndex++,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const inserted = await tx
|
||||
.insert(checklists)
|
||||
.values(allValuesToInsert)
|
||||
.returning({ id: checklists.id, publicId: checklists.publicId });
|
||||
|
||||
return inserted;
|
||||
});
|
||||
};
|
||||
|
||||
export const bulkCreateItems = async (
|
||||
db: dbClient,
|
||||
checklistItemInput: {
|
||||
checklistId: number;
|
||||
title: string;
|
||||
createdBy: string;
|
||||
index: number;
|
||||
completed: boolean;
|
||||
}[],
|
||||
) => {
|
||||
if (checklistItemInput.length === 0) return [];
|
||||
|
||||
return db.transaction(async (tx) => {
|
||||
const byChecklist = groupByKey(checklistItemInput, "checklistId");
|
||||
|
||||
const allValuesToInsert: {
|
||||
publicId: string;
|
||||
checklistId: number;
|
||||
title: string;
|
||||
createdBy: string;
|
||||
index: number;
|
||||
completed: boolean;
|
||||
}[] = [];
|
||||
|
||||
for (const [checklistId, items] of byChecklist.entries()) {
|
||||
const last = await tx.query.checklistItems.findFirst({
|
||||
columns: { index: true },
|
||||
where: and(
|
||||
eq(checklistItems.checklistId, checklistId),
|
||||
isNull(checklistItems.deletedAt),
|
||||
),
|
||||
orderBy: [desc(checklistItems.index)],
|
||||
});
|
||||
|
||||
let nextIndex = last ? last.index + 1 : 0;
|
||||
|
||||
const sorted = [...items].sort((a, b) => a.index - b.index);
|
||||
|
||||
for (const item of sorted) {
|
||||
allValuesToInsert.push({
|
||||
publicId: generateUID(),
|
||||
...item,
|
||||
index: nextIndex++,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const inserted = await tx
|
||||
.insert(checklistItems)
|
||||
.values(allValuesToInsert)
|
||||
.returning({
|
||||
id: checklistItems.id,
|
||||
publicId: checklistItems.publicId,
|
||||
title: checklistItems.title,
|
||||
completed: checklistItems.completed,
|
||||
});
|
||||
|
||||
return inserted;
|
||||
});
|
||||
};
|
||||
|
||||
const groupByKey = <T extends Record<string, unknown>>(
|
||||
items: T[],
|
||||
keyField: keyof T,
|
||||
): Map<number, T[]> => {
|
||||
const grouped = new Map<number, T[]>();
|
||||
for (const item of items) {
|
||||
const key = item[keyField] as number;
|
||||
const arr = grouped.get(key) ?? [];
|
||||
arr.push(item);
|
||||
grouped.set(key, arr);
|
||||
}
|
||||
return grouped;
|
||||
};
|
||||
|
||||
@@ -28,15 +28,6 @@ export const getById = async (db: dbClient, userId: string) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const getByStripeCustomerId = async (
|
||||
db: dbClient,
|
||||
stripeCustomerId: string,
|
||||
) => {
|
||||
return await db.query.users.findFirst({
|
||||
where: eq(users.stripeCustomerId, stripeCustomerId),
|
||||
});
|
||||
};
|
||||
|
||||
export const getByEmail = (db: dbClient, email: string) => {
|
||||
return db.query.users.findFirst({
|
||||
columns: {
|
||||
|
||||
@@ -73,7 +73,6 @@ export const boardsRelations = relations(boards, ({ one, many }) => ({
|
||||
relationName: "boardCreatedByUser",
|
||||
}),
|
||||
lists: many(lists),
|
||||
allLists: many(lists),
|
||||
labels: many(labels),
|
||||
deletedBy: one(users, {
|
||||
fields: [boards.deletedBy],
|
||||
|
||||
@@ -42,8 +42,6 @@ export const activityTypes = [
|
||||
"card.updated.checklist.item.completed",
|
||||
"card.updated.checklist.item.uncompleted",
|
||||
"card.updated.checklist.item.deleted",
|
||||
"card.updated.attachment.added",
|
||||
"card.updated.attachment.removed",
|
||||
"card.archived",
|
||||
] as const;
|
||||
|
||||
@@ -98,7 +96,6 @@ export const cardsRelations = relations(cards, ({ one, many }) => ({
|
||||
comments: many(comments),
|
||||
activities: many(cardActivities),
|
||||
checklists: many(checklists),
|
||||
attachments: many(cardAttachments),
|
||||
}));
|
||||
|
||||
export const cardActivities = pgTable("card_activity", {
|
||||
@@ -276,37 +273,3 @@ export const commentsRelations = relations(comments, ({ one }) => ({
|
||||
relationName: "commentsDeletedByUser",
|
||||
}),
|
||||
}));
|
||||
|
||||
export const cardAttachments = pgTable("card_attachment", {
|
||||
id: bigserial("id", { mode: "number" }).primaryKey(),
|
||||
publicId: varchar("publicId", { length: 12 }).notNull().unique(),
|
||||
cardId: bigint("cardId", { mode: "number" })
|
||||
.notNull()
|
||||
.references(() => cards.id, { onDelete: "cascade" }),
|
||||
filename: varchar("filename", { length: 255 }).notNull(),
|
||||
originalFilename: varchar("originalFilename", { length: 255 }).notNull(),
|
||||
contentType: varchar("contentType", { length: 100 }).notNull(),
|
||||
size: bigint("size", { mode: "number" }).notNull(),
|
||||
s3Key: varchar("s3Key", { length: 500 }).notNull(),
|
||||
createdBy: uuid("createdBy").references(() => users.id, {
|
||||
onDelete: "set null",
|
||||
}),
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
deletedAt: timestamp("deletedAt"),
|
||||
}).enableRLS();
|
||||
|
||||
export const cardAttachmentsRelations = relations(
|
||||
cardAttachments,
|
||||
({ one }) => ({
|
||||
card: one(cards, {
|
||||
fields: [cardAttachments.cardId],
|
||||
references: [cards.id],
|
||||
relationName: "cardAttachmentsCard",
|
||||
}),
|
||||
createdBy: one(users, {
|
||||
fields: [cardAttachments.createdBy],
|
||||
references: [users.id],
|
||||
relationName: "cardAttachmentsCreatedByUser",
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"typecheck": "tsc --noEmit --emitDeclarationOnly false"
|
||||
},
|
||||
"dependencies": {
|
||||
"@novu/api": "^3.11.0",
|
||||
"@plunk/node": "^3.0.3",
|
||||
"@react-email/components": "^0.0.25",
|
||||
"nodemailer": "^7.0.3",
|
||||
"react-email": "^3.0.1"
|
||||
|
||||
10
packages/email/src/cloudMailerClient.tsx
Normal file
10
packages/email/src/cloudMailerClient.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import Plunk from "@plunk/node";
|
||||
|
||||
export const cloudMailerClient =
|
||||
process.env.NEXT_PUBLIC_KAN_ENV === "cloud" &&
|
||||
process.env.PLUNK_API_KEY &&
|
||||
process.env.PLUNK_API_URL
|
||||
? new Plunk(process.env.PLUNK_API_KEY ?? "", {
|
||||
baseUrl: process.env.PLUNK_API_URL,
|
||||
})
|
||||
: null;
|
||||
@@ -1,4 +1,4 @@
|
||||
export const name = "email";
|
||||
|
||||
export { sendEmail } from "./sendEmail";
|
||||
export { notificationClient } from "./notificationClient";
|
||||
export { cloudMailerClient } from "./cloudMailerClient";
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
import { Novu } from "@novu/api";
|
||||
|
||||
export const notificationClient =
|
||||
process.env.NEXT_PUBLIC_KAN_ENV === "cloud" && process.env.NOVU_API_KEY
|
||||
? new Novu({ secretKey: process.env.NOVU_API_KEY })
|
||||
: null;
|
||||
@@ -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) {
|
||||
|
||||
@@ -71,13 +71,4 @@ export const updateSubscriptionSeats = async (
|
||||
return updatedSubscription;
|
||||
};
|
||||
|
||||
export const getCancellationDetails = async (
|
||||
stripeSubscriptionId: string,
|
||||
): Promise<Stripe.Subscription.CancellationDetails | null> => {
|
||||
const stripe = createStripeClient();
|
||||
const stripeSubscription =
|
||||
await stripe.subscriptions.retrieve(stripeSubscriptionId);
|
||||
return stripeSubscription.cancellation_details ?? null;
|
||||
};
|
||||
|
||||
export { createStripeClient };
|
||||
|
||||
67
pnpm-lock.yaml
generated
67
pnpm-lock.yaml
generated
@@ -223,9 +223,6 @@ importers:
|
||||
tippy.js:
|
||||
specifier: ^6.3.7
|
||||
version: 6.3.7
|
||||
tiptap-markdown:
|
||||
specifier: ^0.8
|
||||
version: 0.8.10(@tiptap/core@2.26.1(@tiptap/pm@2.26.1))
|
||||
zod:
|
||||
specifier: 'catalog:'
|
||||
version: 3.25.76
|
||||
@@ -293,12 +290,6 @@ importers:
|
||||
|
||||
packages/api:
|
||||
dependencies:
|
||||
'@aws-sdk/client-s3':
|
||||
specifier: ^3.802.0
|
||||
version: 3.879.0
|
||||
'@aws-sdk/s3-request-presigner':
|
||||
specifier: ^3.812.0
|
||||
version: 3.879.0
|
||||
'@kan/auth':
|
||||
specifier: workspace:*
|
||||
version: link:../auth
|
||||
@@ -440,9 +431,9 @@ importers:
|
||||
|
||||
packages/email:
|
||||
dependencies:
|
||||
'@novu/api':
|
||||
specifier: ^3.11.0
|
||||
version: 3.11.0
|
||||
'@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)
|
||||
@@ -2683,9 +2674,6 @@ packages:
|
||||
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
'@novu/api@3.11.0':
|
||||
resolution: {integrity: sha512-8u0mB5VThL7MhdxoN0UoA4CS9eu2k3Xa6iulauMhCHENuJNxUNuirJWq5t8jDoH4bFTQTfMN0VRkC0qodKR2qA==}
|
||||
|
||||
'@octokit/auth-token@3.0.4':
|
||||
resolution: {integrity: sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==}
|
||||
engines: {node: '>= 14'}
|
||||
@@ -2765,6 +2753,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==}
|
||||
|
||||
@@ -3584,15 +3575,9 @@ packages:
|
||||
'@types/katex@0.16.7':
|
||||
resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==}
|
||||
|
||||
'@types/linkify-it@3.0.5':
|
||||
resolution: {integrity: sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==}
|
||||
|
||||
'@types/linkify-it@5.0.0':
|
||||
resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==}
|
||||
|
||||
'@types/markdown-it@13.0.9':
|
||||
resolution: {integrity: sha512-1XPwR0+MgXLWfTn9gCsZ55AHOKW1WN+P9vr0PaQh5aerR9LLQXUbjfEAFhjmEmyoYFWAyuN2Mqkn40MZ4ukjBw==}
|
||||
|
||||
'@types/markdown-it@14.1.2':
|
||||
resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==}
|
||||
|
||||
@@ -3602,9 +3587,6 @@ packages:
|
||||
'@types/mdast@4.0.4':
|
||||
resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
|
||||
|
||||
'@types/mdurl@1.0.5':
|
||||
resolution: {integrity: sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==}
|
||||
|
||||
'@types/mdurl@2.0.0':
|
||||
resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==}
|
||||
|
||||
@@ -5748,9 +5730,6 @@ packages:
|
||||
make-error@1.3.6:
|
||||
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
|
||||
|
||||
markdown-it-task-lists@2.1.1:
|
||||
resolution: {integrity: sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA==}
|
||||
|
||||
markdown-it@14.1.0:
|
||||
resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==}
|
||||
hasBin: true
|
||||
@@ -7432,11 +7411,6 @@ packages:
|
||||
tippy.js@6.3.7:
|
||||
resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==}
|
||||
|
||||
tiptap-markdown@0.8.10:
|
||||
resolution: {integrity: sha512-iDVkR2BjAqkTDtFX0h94yVvE2AihCXlF0Q7RIXSJPRSR5I0PA1TMuAg6FHFpmqTn4tPxJ0by0CK7PUMlnFLGEQ==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': ^2.0.3
|
||||
|
||||
title-case@2.1.1:
|
||||
resolution: {integrity: sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q==}
|
||||
|
||||
@@ -10226,10 +10200,6 @@ snapshots:
|
||||
'@nodelib/fs.scandir': 2.1.5
|
||||
fastq: 1.19.1
|
||||
|
||||
'@novu/api@3.11.0':
|
||||
dependencies:
|
||||
zod: 3.25.76
|
||||
|
||||
'@octokit/auth-token@3.0.4': {}
|
||||
|
||||
'@octokit/core@4.2.4':
|
||||
@@ -10349,6 +10319,10 @@ snapshots:
|
||||
'@pkgjs/parseargs@0.11.0':
|
||||
optional: true
|
||||
|
||||
'@plunk/node@3.0.3':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
'@popperjs/core@2.11.8': {}
|
||||
|
||||
'@posthog/core@1.0.2': {}
|
||||
@@ -11347,15 +11321,8 @@ snapshots:
|
||||
|
||||
'@types/katex@0.16.7': {}
|
||||
|
||||
'@types/linkify-it@3.0.5': {}
|
||||
|
||||
'@types/linkify-it@5.0.0': {}
|
||||
|
||||
'@types/markdown-it@13.0.9':
|
||||
dependencies:
|
||||
'@types/linkify-it': 3.0.5
|
||||
'@types/mdurl': 1.0.5
|
||||
|
||||
'@types/markdown-it@14.1.2':
|
||||
dependencies:
|
||||
'@types/linkify-it': 5.0.0
|
||||
@@ -11369,8 +11336,6 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/unist': 3.0.3
|
||||
|
||||
'@types/mdurl@1.0.5': {}
|
||||
|
||||
'@types/mdurl@2.0.0': {}
|
||||
|
||||
'@types/ms@2.1.0': {}
|
||||
@@ -13812,8 +13777,6 @@ snapshots:
|
||||
|
||||
make-error@1.3.6: {}
|
||||
|
||||
markdown-it-task-lists@2.1.1: {}
|
||||
|
||||
markdown-it@14.1.0:
|
||||
dependencies:
|
||||
argparse: 2.0.1
|
||||
@@ -16122,14 +16085,6 @@ snapshots:
|
||||
dependencies:
|
||||
'@popperjs/core': 2.11.8
|
||||
|
||||
tiptap-markdown@0.8.10(@tiptap/core@2.26.1(@tiptap/pm@2.26.1)):
|
||||
dependencies:
|
||||
'@tiptap/core': 2.26.1(@tiptap/pm@2.26.1)
|
||||
'@types/markdown-it': 13.0.9
|
||||
markdown-it: 14.1.0
|
||||
markdown-it-task-lists: 2.1.1
|
||||
prosemirror-markdown: 1.13.2
|
||||
|
||||
title-case@2.1.1:
|
||||
dependencies:
|
||||
no-case: 2.3.2
|
||||
@@ -16511,7 +16466,7 @@ snapshots:
|
||||
'@webassemblyjs/wasm-parser': 1.14.1
|
||||
acorn: 8.15.0
|
||||
acorn-import-phases: 1.0.4(acorn@8.15.0)
|
||||
browserslist: 4.27.0
|
||||
browserslist: 4.25.4
|
||||
chrome-trace-event: 1.0.4
|
||||
enhanced-resolve: 5.18.3
|
||||
es-module-lexer: 1.7.0
|
||||
|
||||
@@ -99,7 +99,6 @@
|
||||
"NEXT_PUBLIC_KAN_ENV",
|
||||
"NEXT_PUBLIC_WHITE_LABEL_HIDE_POWERED_BY",
|
||||
"STRIPE_SECRET_KEY",
|
||||
"DISCORD_WEBHOOK_URL",
|
||||
"STRIPE_WEBHOOK_SECRET",
|
||||
"STRIPE_WEBHOOK_SECRET_LEGACY",
|
||||
"STRIPE_PRO_PLAN_MONTHLY_PRICE_ID",
|
||||
@@ -109,7 +108,6 @@
|
||||
"NEXT_PUBLIC_STORAGE_DOMAIN",
|
||||
"NEXT_PUBLIC_STORAGE_URL",
|
||||
"NEXT_PUBLIC_AVATAR_BUCKET_NAME",
|
||||
"NEXT_PUBLIC_ATTACHMENTS_BUCKET_NAME",
|
||||
"NEXT_PUBLIC_ALLOW_CREDENTIALS",
|
||||
"NEXT_PUBLIC_DISABLE_SIGN_UP",
|
||||
"NEXT_PUBLIC_USE_STANDALONE_OUTPUT",
|
||||
@@ -121,7 +119,8 @@
|
||||
"PORT",
|
||||
"BETTER_AUTH_SECRET",
|
||||
"BETTER_AUTH_TRUSTED_ORIGINS",
|
||||
"NOVU_API_KEY"
|
||||
"PLUNK_API_KEY",
|
||||
"PLUNK_API_URL"
|
||||
],
|
||||
"globalPassThroughEnv": [
|
||||
"NODE_ENV",
|
||||
|
||||
Reference in New Issue
Block a user