feat:ticketing,eskalasi

This commit is contained in:
Anang Yusman 2025-05-20 03:39:21 +08:00
parent 06fd71122e
commit f78195e0be
10307 changed files with 1974 additions and 1026839 deletions

View File

@ -0,0 +1,619 @@
"use client";
import React, { ChangeEvent, useEffect, useRef, useState } from "react";
import { useForm, Controller } from "react-hook-form";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Card, CardContent } from "@/components/ui/card";
import { zodResolver } from "@hookform/resolvers/zod";
import * as z from "zod";
import Swal from "sweetalert2";
import withReactContent from "sweetalert2-react-content";
import { useParams, useRouter } from "next/navigation";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import Cookies from "js-cookie";
import { postBlog } from "@/service/blog/blog";
import { Textarea } from "@/components/ui/textarea";
import {
DotSquare,
InboxIcon,
PaperclipIcon,
SmileIcon,
TrashIcon,
} from "lucide-react";
import {
deleteMediaCurationMessage,
detailMedia,
getMediaCurationMessage,
saveMediaCurationMessage,
} from "@/service/curated-content/curated-content";
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/css";
import "swiper/css/free-mode";
import "swiper/css/navigation";
import "swiper/css/pagination";
import "swiper/css/thumbs";
import "swiper/css";
import "swiper/css/navigation";
import { FreeMode, Navigation, Pagination, Thumbs } from "swiper/modules";
import { Avatar, AvatarImage } from "@/components/ui/avatar";
import { Badge } from "@/components/ui/badge";
import { listData } from "@/service/landing/landing";
import {
createAssignmentResponse,
deleteAssignmentResponse,
getAssignmentResponseList,
} from "@/service/task";
import { getCookiesDecrypt } from "@/lib/utils";
import { close, loading } from "@/lib/swal";
import { Checkbox } from "@/components/ui/checkbox";
import { formatDateToIndonesian, htmlToString } from "@/utils/globals";
import { Link } from "@/i18n/routing";
import { useTranslations } from "next-intl";
import { Icon } from "@/components/ui/icon";
const detailSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }),
categoryName: z.string().min(1, { message: "Judul diperlukan" }),
meta: z.string().min(1, { message: "Judul diperlukan" }),
description: z
.string()
.min(2, { message: "Narasi Penugasan harus lebih dari 2 karakter." }),
// tags: z.string().min(1, { message: "Judul diperlukan" }),
});
type Category = {
id: string;
categoryName: string;
};
const formatDate = (dateString: string): string => {
const date = new Date(dateString);
// Pastikan validitas tanggal
if (isNaN(date.getTime())) {
throw new Error("Invalid date format");
}
// Format tanggal
const day = date.getDate().toString().padStart(2, "0");
const month = (date.getMonth() + 1).toString().padStart(2, "0");
const year = date.getFullYear();
// const hours = date.getHours().toString().padStart(2, "0");
// Gabungkan hasil format
return `${day}-${month}-${year} `;
};
export type curationDetail = {
id: number;
title: string;
categoryName: string;
htmlDescription: string;
updatedAt: string;
timezone: string;
clickCount: string;
creatorName: string;
uploadedBy: {
id: number;
fullname: string;
username: string | null;
email: string;
isActive: boolean;
isDefault: boolean;
isInternational: boolean;
userLevel: {
id: number;
name: string;
aliasName: string;
userGroupId: number;
};
};
publishedFor: string; // ID for selected radio button
publishedForObject: {
id: number;
name: string;
isInternal: boolean;
code: string;
}[];
tags: string;
provinceId: string;
is_active: string;
};
const initialComments = [
{
id: 1,
username: "Esther Howard",
date: "07-04-2023 20:00 WIB",
text: "Tolong untuk narasinya mengikuti 5W + 1H!",
avatar: "/images/avatar/avatar-3.png", // URL avatar atau path gambar pengguna
replies: [], // Komentar balasan
},
{
id: 2,
username: "Brooklyn Simmons",
date: "07-04-2023 20:00 WIB",
text: "Ok Baik, Saya segera melakukan perbaikan. Terima kasih atas masukannya. 🙏",
avatar: "/images/avatar/avatar-5.png", // URL avatar atau path gambar pengguna
replies: [], // Komentar balasan
},
{
id: 3,
username: "Leslie Alexander",
date: "07-04-2023 20:00 WIB",
text: "Sangat berguna. Terima Kasih!",
avatar: "/images/avatar/avatar-7.png", // URL avatar atau path gambar pengguna
replies: [], // Komentar balasan
},
];
export default function DetailAcceptImage() {
const MySwal = withReactContent(Swal);
const { id } = useParams() as { id: string };
const t = useTranslations("LandingPage");
console.log(id);
const editor = useRef(null);
type DetailSchema = z.infer<typeof detailSchema>;
const userLevelNumber = getCookiesDecrypt("ulne");
const userId = getCookiesDecrypt("uie");
const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
const taskId = Cookies.get("taskId");
const scheduleId = Cookies.get("scheduleId");
const scheduleType = Cookies.get("scheduleType");
const [selectedTarget, setSelectedTarget] = useState("");
const [detail, setDetail] = useState<curationDetail>();
const [refresh] = useState(false);
const [detailThumb, setDetailThumb] = useState<any>([]);
const [thumbsSwiper, setThumbsSwiper] = useState<any>(null);
const [showInput, setShowInput] = useState<boolean>(false);
const [selectedFileId, setSelectedFileId] = useState(null);
const [listData, setListData] = useState([]);
const [message, setMessage] = useState("");
const {
control,
handleSubmit,
setValue,
formState: { errors },
} = useForm<DetailSchema>({
resolver: zodResolver(detailSchema),
});
const [commentsData, setCommentsData] = useState(initialComments);
const [replyText, setReplyText] = useState("");
const [replyingTo, setReplyingTo] = useState<number | null>(null);
const [selectedValue, setSelectedValue] = useState<string>("");
const handleReply = (commentId: number) => {
setReplyingTo(commentId);
};
const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
setMessage(e.target.value);
};
useEffect(() => {
async function initState() {
// loading();
const response = await getMediaCurationMessage(selectedFileId);
console.log("data", response?.data?.data);
console.log("userLvl", userLevelNumber);
setListData(response?.data?.data);
close();
}
initState();
}, [selectedFileId]);
// const postData = () => {
// sendSuggestionParent();
// };
const postData = async () => {
if (message?.length > 1 && selectedFileId) {
try {
const data = {
mediaUploadFileId: selectedFileId,
message,
parentId: null,
};
const response = await saveMediaCurationMessage(data);
console.log("Komentar terkirim:", response);
const responseGet = await getMediaCurationMessage(selectedFileId);
setListData(responseGet?.data?.data);
setMessage("");
} catch (error) {
console.error("Error posting comment:", error);
}
} else {
console.log("Pesan atau file ID tidak valid.");
}
};
const sendReplyData = async (parentId: number) => {
const inputElement = document.querySelector(
`#input-comment-${parentId}`
) as HTMLTextAreaElement;
if (inputElement?.value?.length > 1 && selectedFileId) {
loading();
const data = {
mediaUploadFileId: selectedFileId,
message: inputElement.value,
parentId,
};
console.log("Sending reply:", data);
const response = await saveMediaCurationMessage(data);
console.log(response);
const responseGet = await getMediaCurationMessage(selectedFileId);
console.log("Updated comments:", responseGet?.data?.data);
setListData(responseGet?.data?.data);
inputElement.value = "";
close();
setReplyingTo(null);
}
};
async function deleteDataSuggestion(dataId: any) {
loading();
const response = await deleteMediaCurationMessage(dataId);
console.log(response);
const responseGet = await getMediaCurationMessage(selectedFileId);
console.log(responseGet?.data?.data);
setListData(responseGet?.data?.data);
close();
}
const deleteData = (dataId: any) => {
deleteDataSuggestion(dataId);
console.log(dataId);
};
useEffect(() => {
async function initState() {
if (id) {
const response = await detailMedia(id);
const details = response?.data?.data;
setDetail(details);
setSelectedValue(details?.publishedFor || "");
setSelectedFileId(details?.files[0]?.id);
const filesData = details.files || [];
const fileUrls = filesData.map((file: any) => ({
id: file.id,
thumbnailFileUrl: file.thumbnailFileUrl || "default-image.jpg",
placements: file.placements || "",
}));
setDetailThumb(fileUrls);
}
}
initState();
}, [id, refresh]);
const handleFileClick = async (fileId: any) => {
setSelectedFileId(fileId);
try {
const response = await getMediaCurationMessage(fileId);
console.log("Data komentar:", response?.data?.data);
setListData(response?.data?.data);
} catch (error) {
console.error("Error fetching comments:", error);
}
};
const handleValueChange = (value: string) => {
setSelectedValue(value);
};
return (
<div className="flex gap-10">
{detail !== undefined ? (
<Card className="w-full ">
<div className="px-6 py-6">
<p className="text-lg font-semibold mb-3">Kurasi Detail</p>
<div className="flex flex-col lg:flex-row gap-5">
<div className="w-full px-3 mt-3 rounded-md">
<div className="gap-5 mb-5">
<div className="space-y-2 py-3">
<div className="w-full ">
<Swiper
thumbs={{ swiper: thumbsSwiper }}
modules={[FreeMode, Navigation, Thumbs]}
navigation={false}
className="w-full"
>
{detailThumb?.map((data: any) => (
<SwiperSlide
key={data.id}
onClick={() => handleFileClick(data.id)}
>
<img
className="object-fill h-full w-full rounded-md"
src={data.thumbnailFileUrl}
alt={`File ID: ${data.id}`}
/>
</SwiperSlide>
))}
</Swiper>
<div className=" mt-2 ">
<Swiper
onSwiper={setThumbsSwiper}
slidesPerView={6}
spaceBetween={8}
pagination={{
clickable: true,
}}
modules={[Pagination, Thumbs]}
// className="mySwiper2"
>
{detailThumb?.map((data: any) => (
<SwiperSlide
key={data.id}
onClick={() => handleFileClick(data.id)}
>
<img
className="object-fill h-full w-full rounded-md"
src={data.thumbnailFileUrl}
alt={`File ID: ${data.id}`}
/>
</SwiperSlide>
))}
</Swiper>
</div>
</div>
</div>
</div>
<div className="text-gray-500 flex flex-col lg:flex-row justify-between items-center border-t mt-4">
<div className="flex flex-col lg:flex-row items-center mt-3 lg:justify-between">
<p className="text-xs lg:text-sm">
{t("by")}&nbsp;
<span className="font-semibold text-black dark:text-white">
{detail?.uploadedBy?.userLevel?.name}
</span>
</p>
{/* <p className="text-xs lg:text-sm">
&nbsp;|&nbsp;{t("updatedOn")}
{detail?.updatedAt} WIB &nbsp;|&nbsp;
</p> */}
<p className="text-xs lg:text-sm">
&nbsp;|&nbsp;{t("updatedOn")}&nbsp;
{formatDateToIndonesian(new Date(detail?.updatedAt))}{" "}
{detail?.timezone ? detail?.timezone : "WIB"}
&nbsp;
</p>
<p className="text-xs lg:text-sm flex justify-center items-center">
&nbsp;|&nbsp;
<Icon icon="formkit:eye" width="15" height="15" />
&nbsp; {detail?.clickCount} &nbsp;
</p>
</div>
<div className="mt-3">
<p className="flex text-end text-xs lg:text-sm font-semibold">
{t("creator")}
{detail?.creatorName}
</p>
</div>
</div>
{/* Keterangan */}
<div className="w-full">
<h1 className="flex flex-row font-bold text-lg lg:text-2xl my-8">
{detail?.title}
</h1>
<div
className="font-light text-justify mb-5 space-y-4 lg:mb-0"
dangerouslySetInnerHTML={{
__html: detail?.htmlDescription,
}}
/>
</div>
</div>
</div>
<CardContent className="p-1">
<div className="gap-5 mb-5">
<div className="mt-5">
<Label className="text-xl text-black">Komentar</Label>
<div className="mt-4 border p-4 rounded bg-gray-50">
<Textarea
placeholder="Tulis tanggapan Anda di sini..."
value={message}
onChange={handleInputChange}
/>
<div className="flex justify-end mt-3">
<Button
color="primary"
onClick={() => postData()}
type="button"
>
Kirim Komentar
</Button>
</div>
</div>
{listData?.map((item: any) => (
<div key={item.id} className="flex flex-col gap-3 mt-2 ">
<div className="flex flex-row gap-3">
<Avatar className="mt-2">
<AvatarImage
src={"/assets/avatar-profile.png"}
alt={`@${item.username}`}
/>
</Avatar>
<div className="flex flex-col bg-slate-200 w-full px-2 py-2 rounded-md">
<div className="flex items-center justify-between">
<span className="text-gray-700 font-semibold">
{item.messageFrom.fullname}
</span>
<span className="text-gray-500 text-sm">
{formatDate(item.createdAt)}
</span>
</div>
<p className="text-gray-800 mt-1">{item.message}</p>
<div className="flex flex-row gap-2">
{/* <div
className="flex items-center mt-1 text-blue-500 cursor-pointer"
onClick={() => handleReply(item.id)}
>
<DotSquare className="w-4 h-4" />
<span className="ml-1">Balas</span>
</div> */}
<div
className="flex items-center mt-1 text-red-500 cursor-pointer"
onClick={() => deleteData(item.id)}
>
<TrashIcon className="w-4 h-4" />
<span className="ml-1">Delete</span>
</div>
</div>
</div>
</div>
{replyingTo === item.id && (
<div className="ml-10 mt-2">
<textarea
id={`input-comment-${item.id}`}
className="w-full p-2 border rounded"
placeholder="Masukkan tanggapan anda"
/>
<button
className="mt-2 px-4 py-2 bg-blue-500 text-white rounded"
onClick={() => sendReplyData(item.id)}
>
Kirim
</button>
</div>
)}
{item.children?.length > 0 && (
<div className="ml-10 mt-2 flex flex-col">
{item.children.map((child: any) => (
<div
key={child.id}
className="flex flex-col gap-3 mt-2"
>
<div className="flex flex-row gap-3">
<Avatar className="mt-2">
<AvatarImage
src={"/assets/avatar-profile.png"}
alt={`@${child.username}`}
/>
</Avatar>
<div className="flex flex-col bg-slate-200 w-full px-2 py-2 rounded-md">
<div className="flex items-center justify-between">
<span className="text-gray-700 font-semibold">
{item.messageFrom.fullname}
</span>
<span className="text-gray-500 text-sm">
{formatDate(item.createdAt)}
</span>
</div>
<p className="text-gray-800 mt-1">
{child.message}
</p>
<div className="flex flex-row gap-2">
{/* <div
className="flex items-center mt-1 text-blue-500 cursor-pointer"
onClick={() => handleReply(child.id)}
>
<DotSquare className="w-4 h-4" />
<span className="ml-1">Balas</span>
</div> */}
<div
className="flex items-center mt-1 text-red-500 cursor-pointer"
onClick={() => deleteData(child.id)}
>
<TrashIcon className="w-4 h-4" />
<span className="ml-1">Delete</span>
</div>
</div>
</div>
</div>
{replyingTo === child.id && (
<div className="ml-10 mt-2">
<textarea
id={`input-comment-${child.id}`}
className="w-full p-2 border rounded"
placeholder="Masukkan tanggapan anda"
/>
<button
className="mt-2 px-4 py-2 bg-blue-500 text-white rounded"
onClick={() => sendReplyData(child.id)}
>
Kirim
</button>
</div>
)}
{child.children?.length > 0 && (
<div className="ml-10 mt-2 flex flex-col mb-3">
{child.children.map((child2: any) => (
<div
key={child2.id}
className="flex flex-col gap-3 mt-2"
>
<div className="flex flex-row gap-3 ">
<Avatar className="mt-2">
<AvatarImage
src={"/assets/avatar-profile.png"}
alt={`@${child2.username}`}
/>
</Avatar>
<div className="flex flex-col bg-slate-200 w-full px-2 py-2 rounded-md">
<div className="flex items-center justify-between">
<span className="text-gray-700 font-semibold">
{item.messageFrom.fullname}
</span>
<span className="text-gray-500 text-sm">
{formatDate(item.createdAt)}
</span>
</div>
<p className="text-gray-800 mt-1">
{child2.message}
</p>
<div className="flex flex-row gap-2">
<div
className="flex items-center mt-1 text-red-500 cursor-pointer"
onClick={() =>
deleteData(child2.id)
}
>
<TrashIcon className="w-4 h-4" />
<span className="ml-1">
Delete
</span>
</div>
</div>
</div>
</div>
</div>
))}
</div>
)}
</div>
))}
</div>
)}
</div>
))}
</div>
</div>
</CardContent>
</div>
</Card>
) : (
""
)}
</div>
);
}

View File

@ -63,7 +63,11 @@ const ImageSliderPage = () => {
<div className="p-2"> <div className="p-2">
<Card className="shadow-md rounded-lg overflow-hidden"> <Card className="shadow-md rounded-lg overflow-hidden">
<Link <Link
href={`/shared/curated-content/giat-routine/image/detail/${image.id}`} href={
roleId === 12
? `/shared/curated-content/giat-routine/image/accept-assignment/detail/${image.id}`
: `/shared/curated-content/giat-routine/image/detail/${image.id}`
}
> >
<CardContent className="p-0"> <CardContent className="p-0">
<img <img

View File

@ -0,0 +1,20 @@
import { Card, CardContent } from "@/components/ui/card";
import SiteBreadcrumb from "@/components/site-breadcrumb";
import FormTask from "@/components/form/task/task-form";
import FormTaskDetail from "@/components/form/task/task-detail-form";
import FormDetailInternal from "@/components/form/communication/internal-detail-form";
import FormDetailEscalation from "@/components/form/communication/escalation-detail-form";
import FormQuestionsForward from "@/components/form/communication/escalation-forward-form";
const EscalationDetailPage = async () => {
return (
<div>
<SiteBreadcrumb />
<div className="space-y-4">
<FormQuestionsForward />
</div>
</div>
);
};
export default EscalationDetailPage;

View File

@ -136,7 +136,7 @@ const columns: ColumnDef<any>[] = [
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent className="p-0" align="end"> <DropdownMenuContent className="p-0" align="end">
<Link <Link
href={`/supervisor/communications/internal/update/${row?.original?.id}`} href={`/supervisor/communications/questions/reply/${row?.original?.id}`}
> >
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none items-center"> <DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none items-center">
Jawab Jawab

View File

@ -0,0 +1,20 @@
import { Card, CardContent } from "@/components/ui/card";
import SiteBreadcrumb from "@/components/site-breadcrumb";
import FormTask from "@/components/form/task/task-form";
import FormTaskDetail from "@/components/form/task/task-detail-form";
import FormDetailInternal from "@/components/form/communication/internal-detail-form";
import FormDetailTicketing from "@/components/form/ticketing/ticketing-detail-form";
import FormQuestionsReply from "@/components/form/communication/questions-reply-form";
const QuestionsReplyPage = async () => {
return (
<div>
<SiteBreadcrumb />
<div className="space-y-4">
<FormQuestionsReply />
</div>
</div>
);
};
export default QuestionsReplyPage;

View File

@ -1,7 +1,13 @@
import * as React from "react"; import * as React from "react";
import { ColumnDef } from "@tanstack/react-table"; import { ColumnDef } from "@tanstack/react-table";
import { Eye, MoreVertical, SquarePen, Trash2 } from "lucide-react"; import {
CheckSquare2,
Eye,
MoreVertical,
SquarePen,
Trash2,
} from "lucide-react";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { import {
DropdownMenu, DropdownMenu,
@ -13,7 +19,10 @@ import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { formatDateToIndonesian } from "@/utils/globals"; import { formatDateToIndonesian } from "@/utils/globals";
import { Link } from "@/i18n/routing"; import { Link } from "@/i18n/routing";
import { deleteTicket } from "@/service/communication/communication"; import {
closeTicket,
deleteTicket,
} from "@/service/communication/communication";
import withReactContent from "sweetalert2-react-content"; import withReactContent from "sweetalert2-react-content";
import { error } from "@/lib/swal"; import { error } from "@/lib/swal";
import Swal from "sweetalert2"; import Swal from "sweetalert2";
@ -135,6 +144,33 @@ const columns: ColumnDef<any>[] = [
} }
}); });
}; };
async function doClose(id: any) {
const response = await closeTicket(id);
if (response?.error) {
error(response.message);
return false;
}
success();
}
const handleClose = (id: any) => {
MySwal.fire({
title: "Ubah status menjadi close?",
text: "",
icon: "warning",
showCancelButton: true,
cancelButtonColor: "#3085d6",
confirmButtonColor: "#d33",
confirmButtonText: "Iya",
}).then((result) => {
if (result.isConfirmed) {
doClose(id);
}
});
};
return ( return (
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild>
@ -159,6 +195,13 @@ const columns: ColumnDef<any>[] = [
Edit Edit
</DropdownMenuItem> </DropdownMenuItem>
</Link> </Link>
<DropdownMenuItem
onClick={() => handleClose(row.original.id)}
className="p-2 border-b text-green-600 bg-green-200 focus:bg-green-400 focus:text-destructive-foreground rounded-none"
>
<CheckSquare2 className="w-4 h-4 me-1.5" />
Close
</DropdownMenuItem>
<DropdownMenuItem <DropdownMenuItem
onClick={() => handleDelete(row.original.id)} onClick={() => handleDelete(row.original.id)}
className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none" className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none"

View File

@ -0,0 +1,291 @@
"use client";
"use client";
import React, { useEffect, useState } from "react";
import { useForm, Controller } from "react-hook-form";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Card } from "@/components/ui/card";
import { zodResolver } from "@hookform/resolvers/zod";
import * as z from "zod";
import Swal from "sweetalert2";
import withReactContent from "sweetalert2-react-content";
import { useParams } from "next/navigation";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Avatar, AvatarImage } from "@/components/ui/avatar";
import {
getEscalationDiscussion,
getQuestionTicket,
getTicketingDetail,
getTicketingInternalDetail,
getTicketingInternalDiscussion,
saveTicketInternalReply,
saveTicketsQuestion,
} from "@/service/communication/communication";
import { Textarea } from "@/components/ui/textarea";
import { Icon } from "@iconify/react/dist/iconify.js";
import { Link } from "@/i18n/routing";
import { loading } from "@/lib/swal";
import { id } from "date-fns/locale";
import { DetailTicket } from "../ticketing/info-lainnya-types";
import { Description } from "@radix-ui/react-toast";
const taskSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }),
description: z.string().min(2, {
message: "Narasi Penugasan harus lebih dari 2 karakter.",
}),
});
export type replyDetail = {
id: number;
message: string;
createdAt: string;
messageFrom: {
id: number;
fullname: string;
};
messageTo: {
id: number;
fullname: string;
};
};
export default function FormQuestionsForward() {
const MySwal = withReactContent(Swal);
const { id } = useParams() as { id: string };
const [detail, setDetail] = useState<any>();
const [ticketReply, setTicketReply] = useState<replyDetail[]>([]);
const [replyVisible, setReplyVisible] = useState(false);
const [listDiscussion, setListDiscussion] = useState();
const [message, setMessage] = useState("");
const [detailTickets, setDetailTickets] = useState<DetailTicket | null>(null);
const [selectedPriority, setSelectedPriority] = useState("");
const [replyMessage, setReplyMessage] = useState("");
const [selectedStatus, setSelectedStatus] = useState("");
const [replies, setReplies] = useState([
{
id: 1,
name: "Mabes Polri - Approver",
message: "test",
timestamp: "2024-12-20 00:56:10",
},
{
id: 2,
name: "Mabes Polri - Approver",
message: "balas",
timestamp: "2025-01-18 17:42:48",
},
]);
const {
control,
handleSubmit,
reset,
formState: { errors },
} = useForm({
resolver: zodResolver(taskSchema),
});
useEffect(() => {
async function initState() {
const response = await getQuestionTicket(id);
setDetail(response?.data?.data);
if (response?.data !== null) {
setDetailTickets(response?.data?.data);
}
if (detailTickets?.emergencyIssue) {
reset({
title: detailTickets.emergencyIssue.title || "",
description: detailTickets.emergencyIssue.description || "",
});
// setSelectedPriority(String(detailTickets.emergencyIssue.urgencyId));
// setSelectedStatus(String(detailTickets.statusId)); // jika ada
}
}
initState();
getTicketReply();
}, [id, reset]);
async function getTicketReply() {
const res = await getTicketingInternalDiscussion(id);
if (res?.data !== null) {
setTicketReply(res?.data?.data);
}
}
const onSubmit = async (data: any) => {
try {
const payload = {
id,
title: data.title,
description: data.description,
priorityId: selectedPriority,
statusId: selectedStatus,
typeId: detailTickets?.typeId,
parentCommentId: detailTickets?.feedId,
};
const response = await saveTicketsQuestion(payload);
MySwal.fire({
title: "Sukses",
text: "Data berhasil diperbarui.",
icon: "success",
});
// Refresh data jika perlu
getTicketReply();
} catch (error) {
console.error("Gagal update:", error);
MySwal.fire({
title: "Error",
text: "Terjadi kesalahan saat memperbarui.",
icon: "error",
});
}
};
const handleSendReply = () => {
if (replyMessage.trim() === "") return;
const newReply = {
id: replies.length + 1,
name: "Mabes Polri - Approver", // Sesuaikan dengan data dinamis jika ada
message: replyMessage,
timestamp: new Date().toISOString().slice(0, 19).replace("T", " "),
};
setReplies([...replies, newReply]);
setReplyMessage("");
};
return (
<div>
<div className="flex">
<div className="flex flex-col mt-6 w-full mb-3">
{detail !== undefined && (
<div key={detail?.id} className="bg-slate-300 rounded-md">
<p className="p-5 bg-slate-300 rounded-md text-lg font-semibold">
Ticket #{detail.id}
</p>
<div className="flex flex-row gap-3 bg-sky-100 p-5 items-center">
<Icon icon="qlementine-icons:user-16" width={36} />
<div>
<p>
<span className="font-bold">
{detail?.commentFromUserName}
</span>
{` `}
mengirimkan pesan untuk{` `}
<Link
href={
detail?.feed
? detail?.feed?.permalink_url == undefined
? detail?.feedUrl
: detail?.feed?.permalink_url
: ""
}
target="_blank"
className="font-bold"
>
{detail?.message}
</Link>
</p>
<p className="text-xs">
{`${new Date(detail?.createdAt).getDate()}-${
new Date(detail?.createdAt).getMonth() + 1
}-${new Date(detail?.createdAt).getFullYear()} ${new Date(
detail?.createdAt
).getHours()}:${new Date(detail?.createdAt).getMinutes()}`}
</p>
</div>
</div>
<p className="p-5 bg-white">{detail.message}</p>
</div>
)}
</div>
</div>
{detailTickets && (
<form onSubmit={handleSubmit(onSubmit)}>
<div className="gap-5 mb-5 w-[100%] lg:w-auto border bg-white rounded-md">
<p className="mx-3 mt-3">Properties</p>
<div className="space-y-2 px-3">
<Label>Judul</Label>
<Controller
control={control}
name="title"
render={({ field }) => (
<Input
size="md"
type="text"
{...field}
placeholder="Masukkan judul"
/>
)}
/>
</div>
<div className="mt-5 px-3">
<Label>Prioritas</Label>
<Select
onValueChange={setSelectedPriority}
value={selectedPriority}
>
<SelectTrigger size="md">
<SelectValue placeholder="Pilih Prioritas" />
</SelectTrigger>
<SelectContent>
<SelectItem value="1">Low</SelectItem>
<SelectItem value="2">Medium</SelectItem>
<SelectItem value="3">High</SelectItem>
</SelectContent>
</Select>
</div>
<div className="mt-5 px-3 mb-3">
<Label>Status</Label>
<Select onValueChange={setSelectedStatus} value={selectedStatus}>
<SelectTrigger size="md">
<SelectValue placeholder="Pilih Status" />
</SelectTrigger>
<SelectContent>
<SelectItem value="1">Open</SelectItem>
<SelectItem value="2">Close</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-2 px-3 py-3">
<Label>Deskripsi</Label>
<Controller
control={control}
name="description"
render={({ field }) => (
<Textarea {...field} placeholder="Masukkan description" />
)}
/>
</div>
<div className="flex justify-end mt-3 mr-3 py-3">
<Button type="submit" color="primary">
Simpan
</Button>
</div>
</div>
</form>
)}
</div>
);
}

View File

@ -0,0 +1,553 @@
"use client";
"use client";
import React, { useEffect, useState } from "react";
import { useForm, Controller } from "react-hook-form";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Card } from "@/components/ui/card";
import { zodResolver } from "@hookform/resolvers/zod";
import * as z from "zod";
import Swal from "sweetalert2";
import withReactContent from "sweetalert2-react-content";
import { useParams } from "next/navigation";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Avatar, AvatarImage } from "@/components/ui/avatar";
import {
deleteTicket,
getQuestionTicket,
getTicketingDetail,
getTicketingInternalDetail,
getTicketingInternalDiscussion,
getTicketingReply,
saveTicketing,
saveTicketInternalReply,
saveTicketReply,
saveTicketsQuestion,
} from "@/service/communication/communication";
import { Icon } from "@iconify/react/dist/iconify.js";
import { list, parse } from "postcss";
import { htmlToString } from "@/utils/globals";
import { Textarea } from "@/components/ui/textarea";
import { error } from "@/lib/swal";
import { useRouter } from "next/navigation";
import { useMediaQuery } from "react-responsive";
import { DetailTicket } from "../ticketing/info-lainnya-types";
import InfoLainnyaModal from "../ticketing/info-lainnya";
import { Description } from "@radix-ui/react-toast";
import { Link } from "@/i18n/routing";
const taskSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }),
description: z.string().min(2, {
message: "Narasi Penugasan harus lebih dari 2 karakter.",
}),
});
export type taskDetail = {
id: number;
title: string;
createdAt: string;
referenceNumber: string | number;
createdBy: {
id: number;
fullname: string;
};
sendTo: {
id: number;
fullname: string;
};
status: {
id: number;
name: string;
};
priority: {
id: number;
name: string;
};
broadcastType: string;
description: string;
is_active: string;
};
export type replyDetail = {
id: number;
comments: string;
createdAt: string;
user: {
id: number;
fullname: string;
};
messageTo: {
id: number;
fullname: string;
};
};
export type internalDetail = {
id: number;
message: string;
createdAt: string;
commentFromUserName: string;
feedTitle: string;
createdBy: {
id: number;
fullname: string;
};
sendTo: {
id: number;
fullname: string;
};
};
export default function FormQuestionsReply() {
const MySwal = withReactContent(Swal);
const { id } = useParams() as { id: string };
const router = useRouter();
const isMobile = useMediaQuery({
maxWidth: 768,
});
const [detail, setDetail] = useState<taskDetail>();
const [ticketReply, setTicketReply] = useState<replyDetail[]>([]);
const [ticketInternal, setTicketInternal] = useState<internalDetail | null>(
null
);
const [detailTicketsQuestions, setDetailTicketsQuestions] =
useState<internalDetail | null>(null);
const [detailTickets, setDetailTickets] = useState<DetailTicket | null>(null);
const [replyVisible, setReplyVisible] = useState(false);
const [replyMessage, setReplyMessage] = useState("");
const [selectedPriority, setSelectedPriority] = useState("");
const [selectedStatus, setSelectedStatus] = useState("");
const [openEmergencyModal, setOpenEmergencyModal] = useState(false);
const [replyValue, setReplyValue] = useState<number>(0); // beri tipe number
const [replyText, setReplyText] = useState<string>(""); // untuk isi balasan
const {
control,
handleSubmit,
reset,
formState: { errors },
} = useForm({
resolver: zodResolver(taskSchema),
});
useEffect(() => {
async function initState() {
setReplyValue(0);
const response = await getQuestionTicket(id);
setDetailTicketsQuestions(response?.data?.data || null);
setTicketInternal(response?.data?.data || null);
setDetail(response?.data?.data);
if (response?.data !== null) {
setDetailTickets(response?.data?.data);
}
if (detailTickets?.emergencyIssue) {
reset({
title: detailTickets?.emergencyIssue.title || "",
description: detailTickets?.emergencyIssue.description || "",
});
// setSelectedPriority(String(detailTickets.emergencyIssue.urgencyId));
// setSelectedStatus(String(detailTickets.statusId)); // jika ada
}
}
initState();
getTicketReply();
}, [id, reset]);
const handleReply = () => {
setReplyValue((prev) => (prev === 1 ? 0 : 1));
};
const handleSendReplyData = async () => {
if (!replyText.trim()) {
console.warn("Balasan kosong!");
return;
}
try {
const res = await saveTicketReply({
ticketId: id,
comment: replyText,
parentCommentId: detailTickets?.commentId,
isFromInternal: true,
});
console.log("Berhasil kirim balasan:", res?.data);
setReplyText("");
setReplyValue(0); // tutup form setelah kirim
getTicketReply(); // refresh balasan
} catch (err) {
console.error("Gagal kirim balasan:", err);
}
};
async function getTicketReply() {
const res = await getTicketingReply(id);
if (res?.data !== null) {
setTicketReply(res?.data?.data);
}
}
const handleSendReply = async () => {
if (replyMessage.trim() === "") {
MySwal.fire({
title: "Error",
text: "Pesan tidak boleh kosong!",
icon: "error",
});
return;
}
const data = {
ticketId: id,
comment: replyMessage,
};
try {
const response = await saveTicketReply(data);
// Tambahkan balasan baru ke daftar balasan
const newReply: replyDetail = {
id: response?.data?.id,
comments: replyMessage,
createdAt: response?.data?.createdAt,
user: response?.data?.messageFrom,
messageTo: response?.data?.messageTo,
};
setTicketReply((prevReplies) => [newReply, ...prevReplies]);
MySwal.fire({
title: "Sukses",
text: "Pesan berhasil dikirim.",
icon: "success",
});
// Reset input dan sembunyikan form balasan
setReplyMessage("");
setReplyVisible(false);
} catch (error) {
MySwal.fire({
title: "Error",
text: "Gagal mengirim balasan.",
icon: "error",
});
console.error("Error sending reply:", error);
}
};
const onSubmit = async (data: any) => {
try {
const payload = {
id,
title: data.title,
description: data.description,
priorityId: selectedPriority,
statusId: selectedStatus,
typeId: detailTickets?.typeId,
parentCommentId: detailTickets?.feedId,
};
const response = await saveTicketsQuestion(payload);
MySwal.fire({
title: "Sukses",
text: "Data berhasil diperbarui.",
icon: "success",
});
// Refresh data jika perlu
getTicketReply();
} catch (error) {
console.error("Gagal update:", error);
MySwal.fire({
title: "Error",
text: "Terjadi kesalahan saat memperbarui.",
icon: "error",
});
}
};
async function doDelete(id: any) {
const response = await deleteTicket(id);
if (response?.error) {
error(response.message);
return false;
}
success("/in/supervisor/ticketing");
}
function success(redirect: string) {
MySwal.fire({
title: "Sukses",
icon: "success",
confirmButtonColor: "#3085d6",
confirmButtonText: "OK",
}).then(() => {
router.push(redirect);
});
}
const handleDelete = (id: any) => {
MySwal.fire({
title: "Hapus Data",
text: "",
icon: "warning",
showCancelButton: true,
cancelButtonColor: "#3085d6",
confirmButtonColor: "#d33",
confirmButtonText: "Hapus",
}).then((result) => {
if (result.isConfirmed) {
doDelete(id);
}
});
};
const openEmergencyIssueDetail = () => {
setOpenEmergencyModal(true);
};
return (
<div className="py-5">
<div className="mt-4 flex flex-row items-center gap-3">
<div className="mt-4 flex flex-row items-center gap-3">
<Link href={`/supervisor/communications/escalation/forward/${id}`}>
<Button color="default" variant={"outline"}>
Eskalasi
</Button>
</Link>
</div>
</div>
<div className="flex flex-col md:flex-row lg:flex-row gap-5 mt-5">
<div className="flex flex-col w-[100%] lg:w-[70%]">
{replyVisible && (
<div className="">
<textarea
id="replyMessage"
className="w-full h-24 border rounded-md p-2"
value={replyMessage}
onChange={(e) => setReplyMessage(e.target.value)}
placeholder="Tulis pesan di sini..."
/>
<div className="flex justify-end gap-3 my-2">
<Button
onClick={() => setReplyVisible(false)}
color="default"
variant="outline"
>
Batal
</Button>
<Button onClick={handleSendReply} color="primary">
Kirim
</Button>
</div>
</div>
)}
<div className="border rounded-t-xl">
<p className="p-4 bg-slate-300 rounded-t-xl text-lg font-semibold">
Ticket #{detail?.referenceNumber}
</p>
{ticketReply?.map((list) => (
<div key={list.id} className="flex flex-col mb-4">
{isMobile ? (
<div className="flex gap-3 bg-sky-100 p-3 items-center">
<Icon icon="qlementine-icons:user-16" width={36} />
<div>
<p className="text-sm">
<span className="font-bold">
{list?.user?.fullname}
</span>{" "}
mengirimkan balasan{" "}
<span className="font-bold">
{list?.messageTo?.fullname}
</span>
</p>
<p className="text-xs">
{new Date(list.createdAt).toLocaleString("id-ID", {
day: "2-digit",
month: "2-digit",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
})}
</p>
</div>
</div>
) : (
<div className="flex gap-4 bg-sky-100 p-4 items-center">
<div className="text-center">
<Icon icon="qlementine-icons:user-16" width={50} />
</div>
<div>
<p className="text-sm">
<span className="font-bold">
{list?.user?.fullname}
</span>{" "}
mengirimkan balasan{" "}
<span className="font-bold">
{list?.messageTo?.fullname}
</span>
</p>
<p className="text-xs">
{new Date(list.createdAt).toLocaleString("id-ID", {
day: "2-digit",
month: "2-digit",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
})}
</p>
</div>
</div>
)}
<div className="bg-white text-sm p-4">{list.comments}</div>
</div>
))}
{detailTicketsQuestions && (
<div key={detailTicketsQuestions.id} className="flex flex-col">
<div className="flex flex-row gap-3 bg-sky-100 p-4 items-center">
<Icon icon="qlementine-icons:user-16" width={36} />
<div>
<p>
<span className="font-bold text-sm">
{detailTicketsQuestions?.commentFromUserName}
</span>{" "}
mengirimkan komentar untuk{" "}
<span className="font-bold text-sm">
{detailTicketsQuestions?.feedTitle}
</span>
</p>
<p className="text-xs">
{`${new Date(
detailTicketsQuestions?.createdAt
).getDate()}-${
new Date(detailTicketsQuestions?.createdAt).getMonth() +
1
}-${new Date(
detailTicketsQuestions?.createdAt
).getFullYear()} ${new Date(
detailTicketsQuestions?.createdAt
).getHours()}:${new Date(
detailTicketsQuestions?.createdAt
).getMinutes()}`}
</p>
</div>
</div>
<div className="p-4 bg-white text-sm">
<p>{htmlToString(detailTicketsQuestions.message)}</p>
{detailTickets?.typeId === 6 &&
detailTickets?.emergencyIssue ? (
<div className="row mx-0 mb-3 emergency-attachments">
<div className="mt-3 mr-4">
<Button
color="primary"
size="md"
onClick={openEmergencyIssueDetail}
>
Info Lainnya
</Button>
</div>
</div>
) : null}
{detailTickets?.emergencyIssue && (
<InfoLainnyaModal
open={openEmergencyModal}
onClose={() => setOpenEmergencyModal(false)}
data={detailTickets.emergencyIssue}
/>
)}
</div>
</div>
)}
</div>
</div>
{detailTickets && (
<form onSubmit={handleSubmit(onSubmit)}>
<div className="gap-5 mb-5 w-[100%] lg:w-auto border bg-white rounded-md">
<p className="mx-3 mt-3">Properties</p>
<div className="space-y-2 px-3">
<Label>Judul</Label>
<Controller
control={control}
name="title"
render={({ field }) => (
<Input
size="md"
type="text"
{...field}
placeholder="Masukkan judul"
/>
)}
/>
</div>
<div className="mt-5 px-3">
<Label>Prioritas</Label>
<Select
onValueChange={setSelectedPriority}
value={selectedPriority}
>
<SelectTrigger size="md">
<SelectValue placeholder="Pilih Prioritas" />
</SelectTrigger>
<SelectContent>
<SelectItem value="1">Low</SelectItem>
<SelectItem value="2">Medium</SelectItem>
<SelectItem value="3">High</SelectItem>
</SelectContent>
</Select>
</div>
<div className="mt-5 px-3 mb-3">
<Label>Status</Label>
<Select
onValueChange={setSelectedStatus}
value={selectedStatus}
>
<SelectTrigger size="md">
<SelectValue placeholder="Pilih Status" />
</SelectTrigger>
<SelectContent>
<SelectItem value="1">Open</SelectItem>
<SelectItem value="2">Close</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-2 px-3 py-3">
<Label>Deskripsi</Label>
<Controller
control={control}
name="description"
render={({ field }) => (
<Textarea {...field} placeholder="Masukkan description" />
)}
/>
</div>
<div className="flex justify-end mt-3 mr-3 py-3">
<Button type="submit" color="primary">
Buat Tiket
</Button>
</div>
</div>
</form>
)}
</div>
</div>
);
}

View File

@ -130,7 +130,7 @@ export default function FormAudioUpdate() {
const [publishedFor, setPublishedFor] = useState<string[]>([]); const [publishedFor, setPublishedFor] = useState<string[]>([]);
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
const [selectedOptions, setSelectedOptions] = useState<{ const [selectedOptions, setSelectedOptions] = useState<{
[fileId: number]: string; [fileId: number]: string[];
}>({}); }>({});
const options: Option[] = [ const options: Option[] = [
@ -243,6 +243,13 @@ export default function FormAudioUpdate() {
if (details?.files) { if (details?.files) {
setFiles(details.files); setFiles(details.files);
const initialOptions: { [key: number]: string[] } = {};
details.files.forEach((file: any) => {
if (file.placements) {
initialOptions[file.id] = mapPlacementsToOptions(file.placements);
}
});
setSelectedOptions(initialOptions);
} }
if (details?.publishedFor) { if (details?.publishedFor) {
@ -274,6 +281,31 @@ export default function FormAudioUpdate() {
initState(); initState();
}, [refresh, setValue]); }, [refresh, setValue]);
const mapPlacementsToOptions = (placements: string): string[] => {
const mapping: Record<string, string> = {
all: "all",
mabes: "nasional",
polda: "wilayah",
polres: "internasional",
};
// Jika placements hanya "all", langsung aktifkan semua checkbox
if (placements.trim() === "all") {
return ["all", "nasional", "wilayah", "internasional"];
}
const options = placements
.split(",")
.map((p) => mapping[p.trim()])
.filter(Boolean);
const allSelected = ["nasional", "wilayah", "internasional"].every((opt) =>
options.includes(opt)
);
return allSelected ? ["all", ...options] : options;
};
const handleCheckboxChange = (id: string) => { const handleCheckboxChange = (id: string) => {
if (id === "all") { if (id === "all") {
// Select all options except "all" // Select all options except "all"

View File

@ -133,7 +133,7 @@ export default function FormImageUpdate() {
const [publishedFor, setPublishedFor] = useState<string[]>([]); const [publishedFor, setPublishedFor] = useState<string[]>([]);
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
const [selectedOptions, setSelectedOptions] = useState<{ const [selectedOptions, setSelectedOptions] = useState<{
[fileId: number]: string; [fileId: number]: string[];
}>({}); }>({});
const options: Option[] = [ const options: Option[] = [
@ -266,6 +266,14 @@ export default function FormImageUpdate() {
if (details?.files) { if (details?.files) {
setFiles(details.files); setFiles(details.files);
const initialOptions: { [key: number]: string[] } = {};
details.files.forEach((file: any) => {
if (file.placements) {
initialOptions[file.id] = mapPlacementsToOptions(file.placements);
}
});
setSelectedOptions(initialOptions);
} }
if (details?.publishedFor) { if (details?.publishedFor) {
@ -291,11 +299,30 @@ export default function FormImageUpdate() {
initState(); initState();
}, [refresh, setValue]); }, [refresh, setValue]);
// const handleCheckboxChange = (id: number) => { const mapPlacementsToOptions = (placements: string): string[] => {
// setSelectedPublishers((prev) => const mapping: Record<string, string> = {
// prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id] all: "all",
// ); mabes: "nasional",
// }; polda: "wilayah",
polres: "internasional",
};
// Jika placements hanya "all", langsung aktifkan semua checkbox
if (placements.trim() === "all") {
return ["all", "nasional", "wilayah", "internasional"];
}
const options = placements
.split(",")
.map((p) => mapping[p.trim()])
.filter(Boolean);
const allSelected = ["nasional", "wilayah", "internasional"].every((opt) =>
options.includes(opt)
);
return allSelected ? ["all", ...options] : options;
};
const handleCheckboxChange = (id: string) => { const handleCheckboxChange = (id: string) => {
if (id === "all") { if (id === "all") {

View File

@ -127,7 +127,7 @@ export default function FormTeksUpdate() {
const [files, setFiles] = useState<FileWithPreview[]>([]); const [files, setFiles] = useState<FileWithPreview[]>([]);
const [selectedOptions, setSelectedOptions] = useState<{ const [selectedOptions, setSelectedOptions] = useState<{
[fileId: number]: string; [fileId: number]: string[];
}>({}); }>({});
const [selectedTarget, setSelectedTarget] = useState(""); const [selectedTarget, setSelectedTarget] = useState("");
const [unitSelection, setUnitSelection] = useState({ const [unitSelection, setUnitSelection] = useState({
@ -236,6 +236,13 @@ export default function FormTeksUpdate() {
if (details?.files) { if (details?.files) {
setFiles(details.files); setFiles(details.files);
const initialOptions: { [key: number]: string[] } = {};
details.files.forEach((file: any) => {
if (file.placements) {
initialOptions[file.id] = mapPlacementsToOptions(file.placements);
}
});
setSelectedOptions(initialOptions);
} }
if (details?.publishedFor) { if (details?.publishedFor) {
@ -261,6 +268,31 @@ export default function FormTeksUpdate() {
initState(); initState();
}, [refresh, setValue]); }, [refresh, setValue]);
const mapPlacementsToOptions = (placements: string): string[] => {
const mapping: Record<string, string> = {
all: "all",
mabes: "nasional",
polda: "wilayah",
polres: "internasional",
};
// Jika placements hanya "all", langsung aktifkan semua checkbox
if (placements.trim() === "all") {
return ["all", "nasional", "wilayah", "internasional"];
}
const options = placements
.split(",")
.map((p) => mapping[p.trim()])
.filter(Boolean);
const allSelected = ["nasional", "wilayah", "internasional"].every((opt) =>
options.includes(opt)
);
return allSelected ? ["all", ...options] : options;
};
const handleCheckboxChange = (id: string) => { const handleCheckboxChange = (id: string) => {
if (id === "all") { if (id === "all") {
// Select all options except "all" // Select all options except "all"

View File

@ -145,7 +145,7 @@ export default function FormVideoUpdate() {
const [publishedFor, setPublishedFor] = useState<string[]>([]); const [publishedFor, setPublishedFor] = useState<string[]>([]);
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
const [selectedOptions, setSelectedOptions] = useState<{ const [selectedOptions, setSelectedOptions] = useState<{
[fileId: number]: string; [fileId: number]: string[];
}>({}); }>({});
const options: Option[] = [ const options: Option[] = [
@ -262,6 +262,13 @@ export default function FormVideoUpdate() {
if (details?.files) { if (details?.files) {
setFiles(details.files); setFiles(details.files);
const initialOptions: { [key: number]: string[] } = {};
details.files.forEach((file: any) => {
if (file.placements) {
initialOptions[file.id] = mapPlacementsToOptions(file.placements);
}
});
setSelectedOptions(initialOptions);
} }
if (details?.publishedFor) { if (details?.publishedFor) {
@ -293,6 +300,31 @@ export default function FormVideoUpdate() {
initState(); initState();
}, [refresh, setValue]); }, [refresh, setValue]);
const mapPlacementsToOptions = (placements: string): string[] => {
const mapping: Record<string, string> = {
all: "all",
mabes: "nasional",
polda: "wilayah",
polres: "internasional",
};
// Jika placements hanya "all", langsung aktifkan semua checkbox
if (placements.trim() === "all") {
return ["all", "nasional", "wilayah", "internasional"];
}
const options = placements
.split(",")
.map((p) => mapping[p.trim()])
.filter(Boolean);
const allSelected = ["nasional", "wilayah", "internasional"].every((opt) =>
options.includes(opt)
);
return allSelected ? ["all", ...options] : options;
};
const handleCheckboxChange = (id: string) => { const handleCheckboxChange = (id: string) => {
if (id === "all") { if (id === "all") {
// Select all options except "all" // Select all options except "all"

View File

@ -0,0 +1,22 @@
export type DetailTicket = {
typeId: number;
feedId: any;
commentId: string;
priority: {
name: string;
};
status: {
name: string;
};
emergencyIssue: {
date: string;
location: string;
title: string;
urgencyName: string;
feedUrl: string;
recommendationName: string;
link: string;
uploadFiles?: string;
description: string;
};
};

View File

@ -0,0 +1,72 @@
// InfoLainnyaModal.tsx
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { DetailTicket } from "./info-lainnya-types";
interface InfoLainnyaModalProps {
open: boolean;
onClose: () => void;
data: DetailTicket["emergencyIssue"];
}
export default function InfoLainnyaModal({
open,
onClose,
data,
}: InfoLainnyaModalProps) {
return (
<Dialog open={open} onOpenChange={onClose}>
<DialogContent size="md">
<DialogHeader>
<DialogTitle>Info Lainnya</DialogTitle>
</DialogHeader>
<div className="grid grid-cols-2 gap-4 text-sm">
<div className="font-medium">Tanggal</div>
<div>:{data?.date}</div>
<div className="font-medium">Lokasi Kejadian</div>
<div>:{data?.location}</div>
<div className="font-medium">Isu Menonjol</div>
<div>:{data?.title}</div>
<div className="font-medium">Urgensi</div>
<div>:{data?.urgencyName}</div>
<div className="font-medium">Rekomendasi Tindak Lanjut</div>
<div>:{data?.recommendationName}</div>
<div className="font-medium">Link Pendukung</div>
<div>
:
<a
href={data?.link}
className="text-blue-600"
target="_blank"
rel="noopener noreferrer"
>
{data?.link}
</a>
</div>
{data?.uploadFiles && (
<>
<div className="font-medium">Lampiran</div>
<div>
<img
src={data?.uploadFiles}
alt="Lampiran"
className="max-w-xs"
/>
</div>
</>
)}
</div>
</DialogContent>
</Dialog>
);
}

View File

@ -30,11 +30,15 @@ import {
saveTicketReply, saveTicketReply,
} from "@/service/communication/communication"; } from "@/service/communication/communication";
import { Icon } from "@iconify/react/dist/iconify.js"; import { Icon } from "@iconify/react/dist/iconify.js";
import { list } from "postcss"; import { list, parse } from "postcss";
import { htmlToString } from "@/utils/globals"; import { htmlToString } from "@/utils/globals";
import { Textarea } from "@/components/ui/textarea"; import { Textarea } from "@/components/ui/textarea";
import { error } from "@/lib/swal"; import { error } from "@/lib/swal";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import InfoLainnyaModal from "./info-lainnya";
import { DetailTicket } from "./info-lainnya-types";
import { useMediaQuery } from "react-responsive";
import { ArrowLeft } from "lucide-react";
const taskSchema = z.object({ const taskSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }), title: z.string().min(1, { message: "Judul diperlukan" }),
@ -65,7 +69,7 @@ export type taskDetail = {
name: string; name: string;
}; };
broadcastType: string; broadcastType: string;
narration: string; description: string;
is_active: string; is_active: string;
}; };
@ -86,6 +90,8 @@ export type internalDetail = {
id: number; id: number;
message: string; message: string;
createdAt: string; createdAt: string;
commentFromUserName: string;
feedTitle: string;
createdBy: { createdBy: {
id: number; id: number;
fullname: string; fullname: string;
@ -100,17 +106,22 @@ export default function FormDetailTicketing() {
const MySwal = withReactContent(Swal); const MySwal = withReactContent(Swal);
const { id } = useParams() as { id: string }; const { id } = useParams() as { id: string };
const router = useRouter(); const router = useRouter();
const isMobile = useMediaQuery({
maxWidth: 768,
});
const [detail, setDetail] = useState<taskDetail>(); const [detail, setDetail] = useState<taskDetail>();
const [ticketReply, setTicketReply] = useState<replyDetail[]>([]); const [ticketReply, setTicketReply] = useState<replyDetail[]>([]);
const [ticketInternal, setTicketInternal] = useState<internalDetail | null>( const [ticketInternal, setTicketInternal] = useState<internalDetail | null>(
null null
); );
const [detailTickets, setDetailTickets] = useState<DetailTicket | null>(null);
const [replyVisible, setReplyVisible] = useState(false); const [replyVisible, setReplyVisible] = useState(false);
const [replyMessage, setReplyMessage] = useState(""); const [replyMessage, setReplyMessage] = useState("");
const [selectedPriority, setSelectedPriority] = useState(""); const [selectedPriority, setSelectedPriority] = useState("");
const [selectedStatus, setSelectedStatus] = useState(""); const [selectedStatus, setSelectedStatus] = useState("");
const [openEmergencyModal, setOpenEmergencyModal] = useState(false);
const [replyValue, setReplyValue] = useState<number>(0); // beri tipe number
const [replyText, setReplyText] = useState<string>(""); // untuk isi balasan
const { const {
control, control,
handleSubmit, handleSubmit,
@ -121,16 +132,47 @@ export default function FormDetailTicketing() {
useEffect(() => { useEffect(() => {
async function initState() { async function initState() {
if (id) { setReplyValue(0);
const response = await getTicketingDetail(id); const response = await getTicketingDetail(id);
setTicketInternal(response?.data?.data || null); setTicketInternal(response?.data?.data || null);
setDetail(response?.data?.data); setDetail(response?.data?.data);
if (response?.data !== null) {
setDetailTickets(response?.data?.data);
} }
} }
initState(); initState();
getTicketReply(); getTicketReply();
}, [id]); }, [id]);
const handleReply = () => {
setReplyValue((prev) => (prev === 1 ? 0 : 1));
};
const handleSendReplyData = async () => {
if (!replyText.trim()) {
console.warn("Balasan kosong!");
return;
}
try {
const res = await saveTicketReply({
ticketId: id,
comment: replyText,
parentCommentId: detailTickets?.commentId,
isFromInternal: true,
});
console.log("Berhasil kirim balasan:", res?.data);
setReplyText("");
setReplyValue(0); // tutup form setelah kirim
getTicketReply(); // refresh balasan
} catch (err) {
console.error("Gagal kirim balasan:", err);
}
};
async function getTicketReply() { async function getTicketReply() {
const res = await getTicketingReply(id); const res = await getTicketingReply(id);
if (res?.data !== null) { if (res?.data !== null) {
@ -138,10 +180,6 @@ export default function FormDetailTicketing() {
} }
} }
const handleReply = () => {
setReplyVisible((prev) => !prev); // Toggle visibility
};
const handleSendReply = async () => { const handleSendReply = async () => {
if (replyMessage.trim() === "") { if (replyMessage.trim() === "") {
MySwal.fire({ MySwal.fire({
@ -154,7 +192,7 @@ export default function FormDetailTicketing() {
const data = { const data = {
ticketId: id, ticketId: id,
message: replyMessage, comment: replyMessage,
}; };
try { try {
@ -227,16 +265,46 @@ export default function FormDetailTicketing() {
}); });
}; };
const openEmergencyIssueDetail = () => {
setOpenEmergencyModal(true);
};
return ( return (
<div className="py-5"> <div className="py-5">
<div className="mt-4 flex flex-row items-center gap-3"> <div className="mt-4">
<Button onClick={handleReply} color="default" variant={"outline"}> <div className="flex gap-3">
Balas <Button onClick={handleReply} variant="outline">
<ArrowLeft className="mr-2 h-4 w-4" />
{replyValue === 1 ? "Tutup Balasan" : "Balas"}
</Button> </Button>
</div>
{/* <Button onClick={handleDelete} color="default" variant={"outline"}> {replyValue === 1 && (
Hapus <div className="mt-4 rounded-xl bg-gray-100 p-4">
</Button> */} <textarea
value={replyText}
onChange={(e) => setReplyText(e.target.value)}
placeholder="Tulis Pesan"
className="w-full resize-none rounded-md border border-gray-300 bg-white p-4 text-sm text-gray-700 focus:outline-none"
rows={5}
/>
<div className="mt-4 flex justify-end gap-3">
<Button
onClick={() => setReplyValue(0)}
variant="outline"
className="text-blue-600 border-blue-600"
>
Batal
</Button>
<Button
onClick={handleSendReplyData}
className="bg-blue-600 text-white hover:bg-blue-700"
>
Kirim
</Button>
</div>
</div>
)}
</div> </div>
<div className="flex flex-col md:flex-row lg:flex-row gap-5 mt-5"> <div className="flex flex-col md:flex-row lg:flex-row gap-5 mt-5">
@ -270,29 +338,60 @@ export default function FormDetailTicketing() {
</p> </p>
{ticketReply?.map((list) => ( {ticketReply?.map((list) => (
<div key={list.id} className="flex flex-col"> <div key={list.id} className="flex flex-col mb-4">
<div className="flex flex-row gap-3 bg-sky-100 p-4 items-center"> {isMobile ? (
<div className="flex gap-3 bg-sky-100 p-3 items-center">
<Icon icon="qlementine-icons:user-16" width={36} /> <Icon icon="qlementine-icons:user-16" width={36} />
<div> <div>
<p> <p className="text-sm">
<span className="font-bold text-sm"> <span className="font-bold">
{list?.user?.fullname} {list?.user?.fullname}
</span>{" "} </span>{" "}
mengirimkan pesan untuk{" "} mengirimkan balasan{" "}
<span className="font-bold text-sm"> <span className="font-bold">
{list?.messageTo?.fullname} {list?.messageTo?.fullname}
</span> </span>
</p> </p>
<p className="text-xs"> <p className="text-xs">
{`${new Date(list?.createdAt).getDate()}-${ {new Date(list.createdAt).toLocaleString("id-ID", {
new Date(list?.createdAt).getMonth() + 1 day: "2-digit",
}-${new Date(list?.createdAt).getFullYear()} ${new Date( month: "2-digit",
list?.createdAt year: "numeric",
).getHours()}:${new Date(list?.createdAt).getMinutes()}`} hour: "2-digit",
minute: "2-digit",
})}
</p> </p>
</div> </div>
</div> </div>
<p className="p-4 bg-white text-sm">{list.comments}</p> ) : (
<div className="flex gap-4 bg-sky-100 p-4 items-center">
<div className="text-center">
<Icon icon="qlementine-icons:user-16" width={50} />
</div>
<div>
<p className="text-sm">
<span className="font-bold">
{list?.user?.fullname}
</span>{" "}
mengirimkan balasan{" "}
<span className="font-bold">
{list?.messageTo?.fullname}
</span>
</p>
<p className="text-xs">
{new Date(list.createdAt).toLocaleString("id-ID", {
day: "2-digit",
month: "2-digit",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
})}
</p>
</div>
</div>
)}
<div className="bg-white text-sm p-4">{list.comments}</div>
</div> </div>
))} ))}
{ticketInternal && ( {ticketInternal && (
@ -302,11 +401,11 @@ export default function FormDetailTicketing() {
<div> <div>
<p> <p>
<span className="font-bold text-sm"> <span className="font-bold text-sm">
{ticketInternal?.createdBy?.fullname} {ticketInternal?.commentFromUserName}
</span>{" "} </span>{" "}
mengirimkan pesan untuk{" "} mengirimkan komentar untuk{" "}
<span className="font-bold text-sm"> <span className="font-bold text-sm">
{ticketInternal?.sendTo?.fullname} {ticketInternal?.feedTitle}
</span> </span>
</p> </p>
<p className="text-xs"> <p className="text-xs">
@ -322,9 +421,31 @@ export default function FormDetailTicketing() {
</p> </p>
</div> </div>
</div> </div>
<p className="p-4 bg-white text-sm"> <div className="p-4 bg-white text-sm">
{htmlToString(ticketInternal.message)} <p>{htmlToString(ticketInternal.message)}</p>
</p> {detailTickets?.typeId === 6 &&
detailTickets?.emergencyIssue ? (
<div className="row mx-0 mb-3 emergency-attachments">
<div className="mt-3 mr-4">
<Button
color="primary"
size="md"
onClick={openEmergencyIssueDetail}
>
Info Lainnya
</Button>
</div>
</div>
) : null}
{detailTickets?.emergencyIssue && (
<InfoLainnyaModal
open={openEmergencyModal}
onClose={() => setOpenEmergencyModal(false)}
data={detailTickets.emergencyIssue}
/>
)}
</div>
</div> </div>
)} )}
</div> </div>
@ -391,7 +512,7 @@ export default function FormDetailTicketing() {
name="title" name="title"
render={({ field }) => ( render={({ field }) => (
<Textarea <Textarea
value={detail?.narration} value={detail?.description}
onChange={field.onChange} onChange={field.onChange}
placeholder="Enter Title" placeholder="Enter Title"
/> />

View File

@ -82,7 +82,7 @@ export function getMenuList(pathname: string, t: any): Group[] {
{ {
href: "/contributor/content/teks", href: "/contributor/content/teks",
label: t("text"), label: t("text"),
active: pathname.includes("/content/text"), active: pathname.includes("/content/teks"),
icon: "heroicons:document", icon: "heroicons:document",
children: [], children: [],
}, },
@ -1492,7 +1492,7 @@ export function getMenuList(pathname: string, t: any): Group[] {
{ {
href: "/contributor/content/teks", href: "/contributor/content/teks",
label: t("text"), label: t("text"),
active: pathname.includes("/content/text"), active: pathname.includes("/content/teks"),
icon: "heroicons:document", icon: "heroicons:document",
children: [], children: [],
}, },
@ -1719,7 +1719,7 @@ export function getMenuList(pathname: string, t: any): Group[] {
{ {
href: "/contributor/content/teks", href: "/contributor/content/teks",
label: t("text"), label: t("text"),
active: pathname.includes("/content/text"), active: pathname.includes("/content/teks"),
icon: "heroicons:document", icon: "heroicons:document",
children: [], children: [],
}, },
@ -2421,7 +2421,7 @@ export function getMenuList(pathname: string, t: any): Group[] {
{ {
href: "/contributor/content/teks", href: "/contributor/content/teks",
label: t("text"), label: t("text"),
active: pathname.includes("/content/text"), active: pathname.includes("/content/teks"),
icon: "heroicons:document", icon: "heroicons:document",
children: [], children: [],
}, },

8
package-lock.json generated
View File

@ -127,7 +127,7 @@
"react-player": "^2.16.0", "react-player": "^2.16.0",
"react-quill": "^0.0.2", "react-quill": "^0.0.2",
"react-resizable-panels": "^2.0.19", "react-resizable-panels": "^2.0.19",
"react-responsive": "^10.0.0", "react-responsive": "^10.0.1",
"react-select": "^5.8.3", "react-select": "^5.8.3",
"react-slick": "^0.30.2", "react-slick": "^0.30.2",
"react-syntax-highlighter": "^15.5.0", "react-syntax-highlighter": "^15.5.0",
@ -15275,9 +15275,9 @@
} }
}, },
"node_modules/react-responsive": { "node_modules/react-responsive": {
"version": "10.0.0", "version": "10.0.1",
"resolved": "https://registry.npmjs.org/react-responsive/-/react-responsive-10.0.0.tgz", "resolved": "https://registry.npmjs.org/react-responsive/-/react-responsive-10.0.1.tgz",
"integrity": "sha512-N6/UiRLGQyGUqrarhBZmrSmHi2FXSD++N5VbSKsBBvWfG0ZV7asvUBluSv5lSzdMyEVjzZ6Y8DL4OHABiztDOg==", "integrity": "sha512-OM5/cRvbtUWEX8le8RCT8scA8y2OPtb0Q/IViEyCEM5FBN8lRrkUOZnu87I88A6njxDldvxG+rLBxWiA7/UM9g==",
"dependencies": { "dependencies": {
"hyphenate-style-name": "^1.0.0", "hyphenate-style-name": "^1.0.0",
"matchmediaquery": "^0.4.2", "matchmediaquery": "^0.4.2",

View File

@ -128,7 +128,7 @@
"react-player": "^2.16.0", "react-player": "^2.16.0",
"react-quill": "^0.0.2", "react-quill": "^0.0.2",
"react-resizable-panels": "^2.0.19", "react-resizable-panels": "^2.0.19",
"react-responsive": "^10.0.0", "react-responsive": "^10.0.1",
"react-select": "^5.8.3", "react-select": "^5.8.3",
"react-slick": "^0.30.2", "react-slick": "^0.30.2",
"react-syntax-highlighter": "^15.5.0", "react-syntax-highlighter": "^15.5.0",

View File

@ -64,6 +64,11 @@ export async function deleteTicket(id: any) {
return httpDeleteInterceptor(url, id); return httpDeleteInterceptor(url, id);
} }
export async function closeTicket(id: any) {
const url = `ticketing/close?id=${id}`;
return httpPostInterceptor(url, id);
}
export async function getTicketingInternalDetail(id: any) { export async function getTicketingInternalDetail(id: any) {
const url = `ticketing/internal?id=${id}`; const url = `ticketing/internal?id=${id}`;
return httpGetInterceptor(url); return httpGetInterceptor(url);
@ -136,3 +141,13 @@ export async function getEscalationDiscussion(id: any) {
const url = `ticketing/escalation/discussion?ticketId=${id}`; const url = `ticketing/escalation/discussion?ticketId=${id}`;
return httpGetInterceptor(url); return httpGetInterceptor(url);
} }
export async function getQuestionTicket(id: any) {
const url = `question?id=${id}`;
return httpGetInterceptor(url);
}
export async function saveTicketsQuestion(data: any) {
const url = "ticketing/convert-question";
return httpPostInterceptor(url, data);
}

View File

@ -1,162 +0,0 @@
Changelog
=========
All changes in the package are documented in the main repository. See: https://github.com/ckeditor/ckeditor5/blob/master/CHANGELOG.md.
Changes for the past releases are available below.
## [19.0.0](https://github.com/ckeditor/ckeditor5-alignment/compare/v18.0.0...v19.0.0) (April 29, 2020)
Internal changes only (updated dependencies, documentation, etc.).
## [18.0.0](https://github.com/ckeditor/ckeditor5-alignment/compare/v17.0.0...v18.0.0) (March 19, 2020)
### Other changes
* Updated translations. ([f1beaaa](https://github.com/ckeditor/ckeditor5-alignment/commit/f1beaaa))
## [17.0.0](https://github.com/ckeditor/ckeditor5-alignment/compare/v16.0.0...v17.0.0) (February 18, 2020)
### MAJOR BREAKING CHANGES
* The `align-left`, `align-right`, `align-center`, and `align-justify` icons have been moved to `@ckeditor/ckeditor5-core`.
### Other changes
* Moved alignment icons to `@ckeditor/ckeditor5-core` (see [ckeditor/ckeditor5-table#227](https://github.com/ckeditor/ckeditor5-table/issues/227)). ([410e279](https://github.com/ckeditor/ckeditor5-alignment/commit/410e279))
* Updated translations. ([288672f](https://github.com/ckeditor/ckeditor5-alignment/commit/288672f))
## [16.0.0](https://github.com/ckeditor/ckeditor5-alignment/compare/v15.0.0...v16.0.0) (December 4, 2019)
### Other changes
* Updated translations. ([9085f7b](https://github.com/ckeditor/ckeditor5-alignment/commit/9085f7b))
## [15.0.0](https://github.com/ckeditor/ckeditor5-alignment/compare/v11.2.0...v15.0.0) (October 23, 2019)
### Other changes
* Updated translations. ([a719974](https://github.com/ckeditor/ckeditor5-alignment/commit/a719974)) ([2fed077](https://github.com/ckeditor/ckeditor5-alignment/commit/2fed077))
* Added `pluginName` to the editor plugin part of the feature. ([3b42798](https://github.com/ckeditor/ckeditor5-alignment/commit/3b42798))
## [11.2.0](https://github.com/ckeditor/ckeditor5-alignment/compare/v11.1.3...v11.2.0) (August 26, 2019)
### Features
* Integrated the text alignment feature with different editor content directions (LTR and RTL). See [ckeditor/ckeditor5#1151](https://github.com/ckeditor/ckeditor5/issues/1151). ([edc7d8b](https://github.com/ckeditor/ckeditor5-alignment/commit/edc7d8b))
### Bug fixes
* The UI buttons should be marked as toggleable for better assistive technologies support (see [ckeditor/ckeditor5#1403](https://github.com/ckeditor/ckeditor5/issues/1403)). ([599ea01](https://github.com/ckeditor/ckeditor5-alignment/commit/599ea01))
### Other changes
* The issue tracker for this package was moved to https://github.com/ckeditor/ckeditor5/issues. See [ckeditor/ckeditor5#1988](https://github.com/ckeditor/ckeditor5/issues/1988). ([54f81b3](https://github.com/ckeditor/ckeditor5-alignment/commit/54f81b3))
* The text alignment toolbar should have a proper `aria-label` attribute (see [ckeditor/ckeditor5#1404](https://github.com/ckeditor/ckeditor5/issues/1404)). ([3ed81de](https://github.com/ckeditor/ckeditor5-alignment/commit/3ed81de))
* Updated translations. ([feb4ab3](https://github.com/ckeditor/ckeditor5-alignment/commit/feb4ab3))
## [11.1.3](https://github.com/ckeditor/ckeditor5-alignment/compare/v11.1.2...v11.1.3) (July 10, 2019)
Internal changes only (updated dependencies, documentation, etc.).
## [11.1.2](https://github.com/ckeditor/ckeditor5-alignment/compare/v11.1.1...v11.1.2) (July 4, 2019)
### Other changes
* Updated translations. ([bb7f494](https://github.com/ckeditor/ckeditor5-alignment/commit/bb7f494))
## [11.1.1](https://github.com/ckeditor/ckeditor5-alignment/compare/v11.1.0...v11.1.1) (June 6, 2019)
### Other changes
* Updated translations. ([32c32c1](https://github.com/ckeditor/ckeditor5-alignment/commit/32c32c1))
## [11.1.0](https://github.com/ckeditor/ckeditor5-alignment/compare/v11.0.0...v11.1.0) (April 4, 2019)
### Features
* Marked alignment as a formatting attribute using the `AttributeProperties#isFormatting` property. Closes [ckeditor/ckeditor5#1664](https://github.com/ckeditor/ckeditor5/issues/1664). ([6358e08](https://github.com/ckeditor/ckeditor5-alignment/commit/6358e08))
### Other changes
* Updated translations. ([78bfc40](https://github.com/ckeditor/ckeditor5-alignment/commit/78bfc40))
## [11.0.0](https://github.com/ckeditor/ckeditor5-alignment/compare/v10.0.4...v11.0.0) (February 28, 2019)
### Other changes
* Updated translations. ([45e8dd5](https://github.com/ckeditor/ckeditor5-alignment/commit/45e8dd5)) ([a92c37b](https://github.com/ckeditor/ckeditor5-alignment/commit/a92c37b)) ([ef68e54](https://github.com/ckeditor/ckeditor5-alignment/commit/ef68e54))
### BREAKING CHANGES
* Upgraded minimal versions of Node to `8.0.0` and npm to `5.7.1`. See: [ckeditor/ckeditor5#1507](https://github.com/ckeditor/ckeditor5/issues/1507). ([612ea3c](https://github.com/ckeditor/ckeditor5-cloud-services/commit/612ea3c))
## [10.0.4](https://github.com/ckeditor/ckeditor5-alignment/compare/v10.0.3...v10.0.4) (December 5, 2018)
### Other changes
* Improved SVG icons size. See [ckeditor/ckeditor5-theme-lark#206](https://github.com/ckeditor/ckeditor5-theme-lark/issues/206). ([1d71d33](https://github.com/ckeditor/ckeditor5-alignment/commit/1d71d33))
* Updated translations. ([547f8d8](https://github.com/ckeditor/ckeditor5-alignment/commit/547f8d8)) ([43d8225](https://github.com/ckeditor/ckeditor5-alignment/commit/43d8225))
## [10.0.3](https://github.com/ckeditor/ckeditor5-alignment/compare/v10.0.2...v10.0.3) (October 8, 2018)
### Other changes
* Updated translations. ([5b30202](https://github.com/ckeditor/ckeditor5-alignment/commit/5b30202))
## [10.0.2](https://github.com/ckeditor/ckeditor5-alignment/compare/v10.0.1...v10.0.2) (July 18, 2018)
### Other changes
* Updated translations. ([33c281c](https://github.com/ckeditor/ckeditor5-alignment/commit/33c281c))
## [10.0.1](https://github.com/ckeditor/ckeditor5-alignment/compare/v10.0.0...v10.0.1) (June 21, 2018)
### Other changes
* Updated translations.
## [10.0.0](https://github.com/ckeditor/ckeditor5-alignment/compare/v1.0.0-beta.4...v10.0.0) (April 25, 2018)
### Other changes
* Changed the license to GPL2+ only. See [ckeditor/ckeditor5#991](https://github.com/ckeditor/ckeditor5/issues/991). ([eed1029](https://github.com/ckeditor/ckeditor5-alignment/commit/eed1029))
* Updated translations. ([baa1fbe](https://github.com/ckeditor/ckeditor5-alignment/commit/baa1fbe))
### BREAKING CHANGES
* The license under which CKEditor&nbsp;5 is released has been changed from a triple GPL, LGPL and MPL license to a GPL2+ only. See [ckeditor/ckeditor5#991](https://github.com/ckeditor/ckeditor5/issues/991) for more information.
## [1.0.0-beta.4](https://github.com/ckeditor/ckeditor5-alignment/compare/v1.0.0-beta.2...v1.0.0-beta.4) (April 19, 2018)
### Other changes
* Updated translations. ([586ae62](https://github.com/ckeditor/ckeditor5-alignment/commit/586ae62))
## [1.0.0-beta.2](https://github.com/ckeditor/ckeditor5-alignment/compare/v1.0.0-beta.1...v1.0.0-beta.2) (April 10, 2018)
Internal changes only (updated dependencies, documentation, etc.).
## [1.0.0-beta.1](https://github.com/ckeditor/ckeditor5-alignment/compare/v0.0.1...v1.0.0-beta.1) (March 15, 2018)
### Features
* Initial implementation. Closes [#2](https://github.com/ckeditor/ckeditor5-alignment/issues/2).

View File

@ -1,17 +0,0 @@
Software License Agreement
==========================
**CKEditor&nbsp;5 text alignment feature** https://github.com/ckeditor/ckeditor5-alignment <br>
Copyright (c) 20032024, [CKSource Holding sp. z o.o.](https://cksource.com) All rights reserved.
Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html).
Sources of Intellectual Property Included in CKEditor
-----------------------------------------------------
Where not otherwise indicated, all CKEditor content is authored by CKSource engineers and consists of CKSource-owned intellectual property. In some specific instances, CKEditor will incorporate work done by developers outside of CKSource with their express permission.
Trademarks
----------
**CKEditor** is a trademark of [CKSource Holding sp. z o.o.](https://cksource.com) All other brand and product names are trademarks, registered trademarks, or service marks of their respective holders.

View File

@ -1,20 +0,0 @@
CKEditor&nbsp;5 text alignment feature
========================================
[![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-alignment.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-alignment)
[![Coverage Status](https://coveralls.io/repos/github/ckeditor/ckeditor5/badge.svg?branch=master)](https://coveralls.io/github/ckeditor/ckeditor5?branch=master)
[![Build Status](https://travis-ci.com/ckeditor/ckeditor5.svg?branch=master)](https://app.travis-ci.com/github/ckeditor/ckeditor5)
This package implements text alignment support for CKEditor&nbsp;5.
## Demo
Check out the [demo in the text alignment feature guide](https://ckeditor.com/docs/ckeditor5/latest/features/text-alignment.html#demo).
## Documentation
See the [`@ckeditor/ckeditor5-alignment` package](https://ckeditor.com/docs/ckeditor5/latest/api/alignment.html) page in [CKEditor&nbsp;5 documentation](https://ckeditor.com/docs/ckeditor5/latest/).
## License
Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html). For full details about the license, please check the `LICENSE.md` file or [https://ckeditor.com/legal/ckeditor-oss-license](https://ckeditor.com/legal/ckeditor-oss-license).

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
!function(n){const e=n.af=n.af||{};e.dictionary=Object.assign(e.dictionary||{},{"Align center":"Belyn in die middel","Align left":"Belyn links","Align right":"Belyn regs",Justify:"Belyn beide kante","Text alignment":"Teksbelyning","Text alignment toolbar":"Teksbelyning nutsbank"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.ar=n.ar||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"محاذاة في المنتصف","Align left":"محاذاة لليسار","Align right":"محاذاة لليمين",Justify:"ضبط","Text alignment":"محاذاة النص","Text alignment toolbar":"شريط أدوات محاذاة النص"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.az=n.az||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"Mərkəzə düzləndir","Align left":"Soldan düzləndir","Align right":"Sağdan düzləndir",Justify:"Eninə görə","Text alignment":"Mətn düzləndirməsi","Text alignment toolbar":"Mətnin düzləndirmə paneli"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.bg=n.bg||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"Централно подравняване","Align left":"Ляво подравняване","Align right":"Дясно подравняване",Justify:"Разпредели по равно","Text alignment":"Подравняване на текста","Text alignment toolbar":"Лента за подравняване на текст"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.bn=n.bn||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"কেন্দ্র সারিবদ্ধ করুন","Align left":"বামে সারিবদ্ধ করুন","Align right":"ডানদিকে সারিবদ্ধ করুন",Justify:"জাস্টিফাই","Text alignment":"টেক্সট সারিবদ্ধকরণ","Text alignment toolbar":"টেক্সট শ্রেণীবিন্যাস টুলবার"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const a=n.bs=n.bs||{};a.dictionary=Object.assign(a.dictionary||{},{"Align center":"Centrirati","Align left":"Lijevo poravnanje","Align right":"Desno poravnanje",Justify:"","Text alignment":"Poravnanje teksta","Text alignment toolbar":"Traka za poravnanje teksta"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(i){const e=i.ca=i.ca||{};e.dictionary=Object.assign(e.dictionary||{},{"Align center":"Alineació centre","Align left":"Alineació esquerra","Align right":"Alineació dreta",Justify:"Justificar","Text alignment":"Alineació text","Text alignment toolbar":"Barra d'eines d'alineació de text"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const t=n.cs=n.cs||{};t.dictionary=Object.assign(t.dictionary||{},{"Align center":"Zarovnat na střed","Align left":"Zarovnat vlevo","Align right":"Zarovnat vpravo",Justify:"Zarovnat do bloku","Text alignment":"Zarovnání textu","Text alignment toolbar":"Panel nástrojů zarovnání textu"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(t){const n=t.da=t.da||{};n.dictionary=Object.assign(n.dictionary||{},{"Align center":"Justér center","Align left":"Justér venstre","Align right":"Justér højre",Justify:"Justér","Text alignment":"Tekstjustering","Text alignment toolbar":"Tekstjustering værktøjslinje"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(t){const i=t["de-ch"]=t["de-ch"]||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"Zentriert","Align left":"Linksbündig","Align right":"Rechtsbündig",Justify:"Blocksatz","Text alignment":"Textausrichtung","Text alignment toolbar":"Textausrichtung Werkzeugleiste"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const t=n.de=n.de||{};t.dictionary=Object.assign(t.dictionary||{},{"Align center":"Zentriert","Align left":"Linksbündig","Align right":"Rechtsbündig",Justify:"Blocksatz","Text alignment":"Textausrichtung","Text alignment toolbar":"Text-Ausrichtung Toolbar"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.el=n.el||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"Στοίχιση στο κέντρο","Align left":"Στοίχιση αριστερά","Align right":"Στοίχιση δεξιά",Justify:"Πλήρης στοίχηση","Text alignment":"Στοίχιση κειμένου","Text alignment toolbar":"Γραμμή εργαλείων στοίχισης κειμένου"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const t=n["en-au"]=n["en-au"]||{};t.dictionary=Object.assign(t.dictionary||{},{"Align center":"Align centre","Align left":"Align left","Align right":"Align right",Justify:"Justify","Text alignment":"Text alignment","Text alignment toolbar":"Text alignment toolbar"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n["en-gb"]=n["en-gb"]||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"Align center","Align left":"Align left","Align right":"Align right",Justify:"Justify","Text alignment":"Text alignment","Text alignment toolbar":""})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(i){const e=i["es-co"]=i["es-co"]||{};e.dictionary=Object.assign(e.dictionary||{},{"Align center":"Centrar","Align left":"Alinear a la izquierda","Align right":"Alinear a la derecha",Justify:"Justificar","Text alignment":"Alineación de texto","Text alignment toolbar":"Herramientas de alineación de texto"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(e){const i=e.es=e.es||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"Centrar","Align left":"Alinear a la izquierda","Align right":"Alinear a la derecha",Justify:"Justificar","Text alignment":"Alineación del texto","Text alignment toolbar":"Barra de herramientas de alineación del texto"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.et=n.et||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"Keskjoondus","Align left":"Vasakjoondus","Align right":"Paremjoondus",Justify:"Rööpjoondus","Text alignment":"Teksti joondamine","Text alignment toolbar":"Teksti joonduse tööriistariba"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.fa=n.fa||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"تراز وسط","Align left":"تراز چپ","Align right":"تراز راست",Justify:"هم تراز کردن","Text alignment":"تراز متن","Text alignment toolbar":"نوار ابزار ترازبندی متن"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(a){const i=a.fi=a.fi||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"Tasaa keskelle","Align left":"Tasaa vasemmalle","Align right":"Tasaa oikealle",Justify:"Tasaa molemmat reunat","Text alignment":"Tekstin tasaus","Text alignment toolbar":"Tekstin suuntauksen työkalupalkki"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(e){const t=e.fr=e.fr||{};t.dictionary=Object.assign(t.dictionary||{},{"Align center":"Centrer","Align left":"Aligner à gauche","Align right":"Aligner à droite",Justify:"Justifier","Text alignment":"Alignement du texte","Text alignment toolbar":"Barre d'outils d'alignement du texte"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(t){const e=t.gl=t.gl||{};e.dictionary=Object.assign(e.dictionary||{},{"Align center":"Centrar horizontalmente","Align left":"Aliñar á esquerda","Align right":"Aliñar á dereita",Justify:"Xustificado","Text alignment":"Aliñamento do texto","Text alignment toolbar":"Barra de ferramentas de aliñamento de textos"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.he=n.he||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"יישור באמצע","Align left":"יישור לשמאל","Align right":"יישור לימין",Justify:"מרכוז גבולות","Text alignment":"יישור טקסט","Text alignment toolbar":"סרגל כלים יישור טקסט"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(i){const n=i.hi=i.hi||{};n.dictionary=Object.assign(n.dictionary||{},{"Align center":"Align center","Align left":"Align left","Align right":"Align right",Justify:"Justify","Text alignment":"Text alignment","Text alignment toolbar":"Text alignment toolbar"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const a=n.hr=n.hr||{};a.dictionary=Object.assign(a.dictionary||{},{"Align center":"Poravnaj po sredini","Align left":"Poravnaj ulijevo","Align right":"Poravnaj udesno",Justify:"Razvuci","Text alignment":"Poravnanje teksta","Text alignment toolbar":"Traka za poravnanje"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(i){const t=i.hu=i.hu||{};t.dictionary=Object.assign(t.dictionary||{},{"Align center":"Középre igazítás","Align left":"Balra igazítás","Align right":"Jobbra igazítás",Justify:"Sorkizárt","Text alignment":"Szöveg igazítása","Text alignment toolbar":"Szöveg igazítás eszköztár"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(a){const t=a.id=a.id||{};t.dictionary=Object.assign(t.dictionary||{},{"Align center":"Rata tengah","Align left":"Rata kiri","Align right":"Rata kanan",Justify:"Rata kanan-kiri","Text alignment":"Perataan teks","Text alignment toolbar":"Alat perataan teks"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(i){const n=i.it=i.it||{};n.dictionary=Object.assign(n.dictionary||{},{"Align center":"Allinea al centro","Align left":"Allinea a sinistra","Align right":"Allinea a destra",Justify:"Giustifica","Text alignment":"Allineamento del testo","Text alignment toolbar":"Barra degli strumenti dell'allineamento"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.ja=n.ja||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"中央揃え","Align left":"左揃え","Align right":"右揃え",Justify:"両端揃え","Text alignment":"文字揃え","Text alignment toolbar":"テキストの整列"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const t=n.jv=n.jv||{};t.dictionary=Object.assign(t.dictionary||{},{"Align center":"Rata tengah","Align left":"Rata kiwa","Align right":"Rata tengen",Justify:"Rata kiwa tengen","Text alignment":"Perataan seratan","Text alignment toolbar":""})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.kk=n.kk||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"Ортадан туралау","Align left":"Солға туралау","Align right":"Оңға туралау",Justify:"","Text alignment":"Мәтінді туралау","Text alignment toolbar":"Мәтінді туралау құралдар тақтасы"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.km=n.km||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"តម្រឹម​កណ្ដាល","Align left":"តម្រឹម​ឆ្វេង","Align right":"តម្រឹម​ស្ដាំ",Justify:"តម្រឹម​សងខាង","Text alignment":"ការ​តម្រឹម​អក្សរ","Text alignment toolbar":"របារ​ឧបករណ៍​តម្រឹម​អក្សរ"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.ko=n.ko||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"가운데 정렬","Align left":"왼쪽 정렬","Align right":"오른쪽 정렬",Justify:"양쪽 정렬","Text alignment":"텍스트 정렬","Text alignment toolbar":"텍스트 정렬 툴바"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.ku=n.ku||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"بەهێڵکردنی ناورەڕاست","Align left":"بەهێڵکردنی چەپ","Align right":"بەهێڵکردنی ڕاست",Justify:"هاوستوونی","Text alignment":"ڕیززکردنی تێکست","Text alignment toolbar":"تووڵامرازی ڕیززکردنی تێکست"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(i){const t=i.lt=i.lt||{};t.dictionary=Object.assign(t.dictionary||{},{"Align center":"Centruoti","Align left":"Lygiuoti į kairę","Align right":"Lygiuoti į dešinę",Justify:"Lygiuoti per visą plotį","Text alignment":"Teksto lygiavimas","Text alignment toolbar":"Teksto lygiavimo įrankių juosta"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(i){const n=i.lv=i.lv||{};n.dictionary=Object.assign(n.dictionary||{},{"Align center":"Centrēt","Align left":"Pa kreisi","Align right":"Pa labi",Justify:"Izlīdzināt abas malas","Text alignment":"Teksta izlīdzināšana","Text alignment toolbar":"Teksta līdzināšanas rīkjosla"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(a){const n=a.ms=a.ms||{};n.dictionary=Object.assign(n.dictionary||{},{"Align center":"Jajarkan tengah","Align left":"Jajarkan kiri","Align right":"Jajarkan kiri",Justify:"Imbang","Text alignment":"Jajaran teks","Text alignment toolbar":"Bar alat capaian jajaran teks"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(t){const n=t.nb=t.nb||{};n.dictionary=Object.assign(n.dictionary||{},{"Align center":"Midstill","Align left":"Venstrejuster","Align right":"Høyrejuster",Justify:"Blokkjuster","Text alignment":"Tekstjustering","Text alignment toolbar":""})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.ne=n.ne||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"केन्द्र पङ्क्तिबद्ध गर्नुहोस्","Align left":"बायाँ पङ्क्तिबद्ध गर्नुहोस्","Align right":"दायाँ पङ्क्तिबद्ध गर्नुहोस्",Justify:"जस्टिफाइ गर्नुहोस्","Text alignment":"पाठ संरेखण","Text alignment toolbar":""})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(i){const n=i.nl=i.nl||{};n.dictionary=Object.assign(n.dictionary||{},{"Align center":"Midden uitlijnen","Align left":"Links uitlijnen","Align right":"Rechts uitlijnen",Justify:"Volledig uitlijnen","Text alignment":"Tekst uitlijning","Text alignment toolbar":"Tekst uitlijning werkbalk"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(t){const n=t.no=t.no||{};n.dictionary=Object.assign(n.dictionary||{},{"Align center":"Midtstill","Align left":"Venstrejuster","Align right":"Høyrejuster",Justify:"Blokkjuster","Text alignment":"Tekstjustering","Text alignment toolbar":"Verktøylinje for tekstjustering"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.pl=n.pl||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"Wyrównaj do środka","Align left":"Wyrównaj do lewej","Align right":"Wyrównaj do prawej",Justify:"Wyrównaj obustronnie","Text alignment":"Wyrównanie tekstu","Text alignment toolbar":"Pasek narzędzi wyrównania tekstu"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(t){const i=t["pt-br"]=t["pt-br"]||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"Centralizar","Align left":"Alinhar à esquerda","Align right":"Alinhar à direita",Justify:"Justificar","Text alignment":"Alinhamento do texto","Text alignment toolbar":"Ferramentas de alinhamento de texto"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(t){const i=t.pt=t.pt||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"Alinhar ao centro","Align left":"Alinhar à esquerda","Align right":"Alinhar à direita",Justify:"Justificar","Text alignment":"Alinhamento de texto","Text alignment toolbar":"Barra de alinhamento de texto"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(i){const n=i.ro=i.ro||{};n.dictionary=Object.assign(n.dictionary||{},{"Align center":"Aliniază la centru","Align left":"Aliniază la stânga","Align right":"Aliniază la dreapta",Justify:"Aliniază stânga-dreapta","Text alignment":"Aliniere text","Text alignment toolbar":"Bara aliniere text"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.ru=n.ru||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"Выравнивание по центру","Align left":"Выравнивание по левому краю","Align right":"Выравнивание по правому краю",Justify:"Выравнивание по ширине","Text alignment":"Выравнивание текста","Text alignment toolbar":"Выравнивание"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const a=n.sk=n.sk||{};a.dictionary=Object.assign(a.dictionary||{},{"Align center":"Zarovnať na stred","Align left":"Zarovnať vľavo","Align right":"Zarovnať vpravo",Justify:"Do bloku","Text alignment":"Zarovnanie textu","Text alignment toolbar":"Panel nástrojov zarovnania textu"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(a){const n=a.sl=a.sl||{};n.dictionary=Object.assign(n.dictionary||{},{"Align center":"Sredinska poravnava","Align left":"Poravnava levo","Align right":"Poravnava desno",Justify:"Postavi na sredino","Text alignment":"Poravnava besedila","Text alignment toolbar":"Orodna vrstica besedila"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(t){const i=t.sq=t.sq||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"Radhit në mes","Align left":"Radhit majtas","Align right":"Radhit djathtas",Justify:"Plotësim","Text alignment":"Radhitja e tekstit","Text alignment toolbar":"Shiriti i rradhitjes së tekstit"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const a=n["sr-latn"]=n["sr-latn"]||{};a.dictionary=Object.assign(a.dictionary||{},{"Align center":"Centralno ravnanje","Align left":"Levo ravnanje","Align right":"Desno ravnanje",Justify:"Obostrano ravnanje","Text alignment":"Ravnanje teksta","Text alignment toolbar":"Alatke za ravnanje teksta"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.sr=n.sr||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"Централно равнанје","Align left":"Лево равнање","Align right":"Десно равнање",Justify:"Обострано равнање","Text alignment":"Равнање текста","Text alignment toolbar":"Алатке за равнање текста"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(t){const e=t.sv=t.sv||{};e.dictionary=Object.assign(e.dictionary||{},{"Align center":"Centrera","Align left":"Vänsterjustera","Align right":"Högerjustera",Justify:"Justera till marginaler","Text alignment":"Textjustering","Text alignment toolbar":"Verktygsfält för textjustering"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const t=n.th=n.th||{};t.dictionary=Object.assign(t.dictionary||{},{"Align center":"จัดกึ่งกลาง","Align left":"จัดชิดซ้าย","Align right":"จัดชิดขวา",Justify:"จัด(ขอบ)","Text alignment":"จัดตำแหน่งข้อความ","Text alignment toolbar":"แถบเครื่องมือจัดตำแหน่งข้อความ"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(e){const i=e.tk=e.tk||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"Merkeze deňleşdir","Align left":"Çepe deňleşdiriň","Align right":"Saga deňleşdiriň",Justify:"Akla","Text alignment":"Tekstiň deňleşdirilmegi","Text alignment toolbar":"Teksti deňleşdirmek gurallar paneli"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(a){const i=a.tr=a.tr||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"Ortala","Align left":"Sola hizala","Align right":"Sağa hizala",Justify:"İki yana yasla","Text alignment":"Yazı hizalama","Text alignment toolbar":"Yazı Hizlama Araç Çubuğu"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.ug=n.ug||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"ئوتتۇرىغا توغرىلاش","Align left":"سولغا توغرىلاش","Align right":"ئوڭغا توغرىلاش",Justify:"ئوڭ سولدىن توغرىلا","Text alignment":"تېكىست توغرىلاش","Text alignment toolbar":"تېكىست توغرىلاش قورالبالدىقى"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.uk=n.uk||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"По центру","Align left":"По лівому краю","Align right":"По правому краю",Justify:"По ширині","Text alignment":"Вирівнювання тексту","Text alignment toolbar":"Панель інструментів вирівнювання тексту"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.ur=n.ur||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"درمیانی سیدھ","Align left":"بائیں سیدھ","Align right":"دائیں سیدھ",Justify:"برابر سیدھ","Text alignment":"متن کی سیدھ","Text alignment toolbar":"خانہ آلات برائے سیدھ"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(i){const t=i.uz=i.uz||{};t.dictionary=Object.assign(t.dictionary||{},{"Align center":"O'rtada tekislash","Align left":"Chap tomonda tekislash","Align right":"O'ng tomonda tekislash",Justify:"Kengligi bo'yicha tekislash","Text alignment":"Matnni tekislash","Text alignment toolbar":"Tekislash"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.vi=n.vi||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"Canh giữa","Align left":"Canh trái","Align right":"Canh phải",Justify:"Canh đều","Text alignment":"Căn chỉnh văn bản","Text alignment toolbar":"Thanh công cụ canh chữ"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n["zh-cn"]=n["zh-cn"]||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"居中对齐","Align left":"左对齐","Align right":"右对齐",Justify:"两端对齐","Text alignment":"对齐","Text alignment toolbar":"对齐工具栏"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1 +0,0 @@
!function(n){const i=n.zh=n.zh||{};i.dictionary=Object.assign(i.dictionary||{},{"Align center":"置中對齊","Align left":"靠左對齊","Align right":"靠右對齊",Justify:"左右對齊","Text alignment":"文字對齊","Text alignment toolbar":"文字對齊"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

View File

@ -1,31 +0,0 @@
{
"plugins": [
{
"name": "Alignment",
"className": "Alignment",
"path": "src/alignment.js",
"description": "Enables support for text alignment. You can use it to align your content to left, right and center or to justify it.",
"docs": "features/text-alignment.html",
"uiComponents": [
{
"type": "SplitButton",
"name": "alignment",
"iconPath": "@ckeditor/ckeditor5-core/theme/icons/align-left.svg"
}
],
"htmlOutput": [
{
"elements": "$block",
"styles": "text-align",
"_comment": "By default, the alignment feature uses the `text-align` inline style."
},
{
"elements": "$block",
"classes": "*",
"isAlternative": true,
"_comment": "If `config.alignment.options` is set, these classes are used for alignment instead of inline styles."
}
]
}
]
}

View File

@ -1,8 +0,0 @@
{
"Align left": "Toolbar button tooltip for aligning the text to the left.",
"Align right": "Toolbar button tooltip for aligning the text to the right.",
"Align center": "Toolbar button tooltip for aligning the text to center.",
"Justify": "Toolbar button tooltip for making the text justified.",
"Text alignment": "Dropdown button tooltip for the text alignment feature.",
"Text alignment toolbar": "Label used by assistive technologies describing the text alignment feature toolbar."
}

View File

@ -1,42 +0,0 @@
# Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
#
# !!! IMPORTANT !!!
#
# Before you edit this file, please keep in mind that contributing to the project
# translations is possible ONLY via the Transifex online service.
#
# To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
#
# To learn more, check out the official contributor's guide:
# https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
#
msgid ""
msgstr ""
"Language-Team: Afrikaans (https://app.transifex.com/ckeditor/teams/11143/af/)\n"
"Language: af\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Content-Type: text/plain; charset=UTF-8\n"
msgctxt "Toolbar button tooltip for aligning the text to the left."
msgid "Align left"
msgstr "Belyn links"
msgctxt "Toolbar button tooltip for aligning the text to the right."
msgid "Align right"
msgstr "Belyn regs"
msgctxt "Toolbar button tooltip for aligning the text to center."
msgid "Align center"
msgstr "Belyn in die middel"
msgctxt "Toolbar button tooltip for making the text justified."
msgid "Justify"
msgstr "Belyn beide kante"
msgctxt "Dropdown button tooltip for the text alignment feature."
msgid "Text alignment"
msgstr "Teksbelyning"
msgctxt "Label used by assistive technologies describing the text alignment feature toolbar."
msgid "Text alignment toolbar"
msgstr "Teksbelyning nutsbank"

View File

@ -1,42 +0,0 @@
# Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
#
# !!! IMPORTANT !!!
#
# Before you edit this file, please keep in mind that contributing to the project
# translations is possible ONLY via the Transifex online service.
#
# To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
#
# To learn more, check out the official contributor's guide:
# https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
#
msgid ""
msgstr ""
"Language-Team: Arabic (https://app.transifex.com/ckeditor/teams/11143/ar/)\n"
"Language: ar\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
"Content-Type: text/plain; charset=UTF-8\n"
msgctxt "Toolbar button tooltip for aligning the text to the left."
msgid "Align left"
msgstr "محاذاة لليسار"
msgctxt "Toolbar button tooltip for aligning the text to the right."
msgid "Align right"
msgstr "محاذاة لليمين"
msgctxt "Toolbar button tooltip for aligning the text to center."
msgid "Align center"
msgstr "محاذاة في المنتصف"
msgctxt "Toolbar button tooltip for making the text justified."
msgid "Justify"
msgstr "ضبط"
msgctxt "Dropdown button tooltip for the text alignment feature."
msgid "Text alignment"
msgstr "محاذاة النص"
msgctxt "Label used by assistive technologies describing the text alignment feature toolbar."
msgid "Text alignment toolbar"
msgstr "شريط أدوات محاذاة النص"

View File

@ -1,42 +0,0 @@
# Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
#
# !!! IMPORTANT !!!
#
# Before you edit this file, please keep in mind that contributing to the project
# translations is possible ONLY via the Transifex online service.
#
# To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
#
# To learn more, check out the official contributor's guide:
# https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
#
msgid ""
msgstr ""
"Language-Team: Azerbaijani (https://app.transifex.com/ckeditor/teams/11143/az/)\n"
"Language: az\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Content-Type: text/plain; charset=UTF-8\n"
msgctxt "Toolbar button tooltip for aligning the text to the left."
msgid "Align left"
msgstr "Soldan düzləndir"
msgctxt "Toolbar button tooltip for aligning the text to the right."
msgid "Align right"
msgstr "Sağdan düzləndir"
msgctxt "Toolbar button tooltip for aligning the text to center."
msgid "Align center"
msgstr "Mərkəzə düzləndir"
msgctxt "Toolbar button tooltip for making the text justified."
msgid "Justify"
msgstr "Eninə görə"
msgctxt "Dropdown button tooltip for the text alignment feature."
msgid "Text alignment"
msgstr "Mətn düzləndirməsi"
msgctxt "Label used by assistive technologies describing the text alignment feature toolbar."
msgid "Text alignment toolbar"
msgstr "Mətnin düzləndirmə paneli"

View File

@ -1,42 +0,0 @@
# Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
#
# !!! IMPORTANT !!!
#
# Before you edit this file, please keep in mind that contributing to the project
# translations is possible ONLY via the Transifex online service.
#
# To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
#
# To learn more, check out the official contributor's guide:
# https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
#
msgid ""
msgstr ""
"Language-Team: Bulgarian (https://app.transifex.com/ckeditor/teams/11143/bg/)\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Content-Type: text/plain; charset=UTF-8\n"
msgctxt "Toolbar button tooltip for aligning the text to the left."
msgid "Align left"
msgstr "Ляво подравняване"
msgctxt "Toolbar button tooltip for aligning the text to the right."
msgid "Align right"
msgstr "Дясно подравняване"
msgctxt "Toolbar button tooltip for aligning the text to center."
msgid "Align center"
msgstr "Централно подравняване"
msgctxt "Toolbar button tooltip for making the text justified."
msgid "Justify"
msgstr "Разпредели по равно"
msgctxt "Dropdown button tooltip for the text alignment feature."
msgid "Text alignment"
msgstr "Подравняване на текста"
msgctxt "Label used by assistive technologies describing the text alignment feature toolbar."
msgid "Text alignment toolbar"
msgstr "Лента за подравняване на текст"

View File

@ -1,42 +0,0 @@
# Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
#
# !!! IMPORTANT !!!
#
# Before you edit this file, please keep in mind that contributing to the project
# translations is possible ONLY via the Transifex online service.
#
# To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
#
# To learn more, check out the official contributor's guide:
# https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
#
msgid ""
msgstr ""
"Language-Team: Bengali (https://app.transifex.com/ckeditor/teams/11143/bn/)\n"
"Language: bn\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Content-Type: text/plain; charset=UTF-8\n"
msgctxt "Toolbar button tooltip for aligning the text to the left."
msgid "Align left"
msgstr "বামে সারিবদ্ধ করুন"
msgctxt "Toolbar button tooltip for aligning the text to the right."
msgid "Align right"
msgstr "ডানদিকে সারিবদ্ধ করুন"
msgctxt "Toolbar button tooltip for aligning the text to center."
msgid "Align center"
msgstr "কেন্দ্র সারিবদ্ধ করুন"
msgctxt "Toolbar button tooltip for making the text justified."
msgid "Justify"
msgstr "জাস্টিফাই"
msgctxt "Dropdown button tooltip for the text alignment feature."
msgid "Text alignment"
msgstr "টেক্সট সারিবদ্ধকরণ"
msgctxt "Label used by assistive technologies describing the text alignment feature toolbar."
msgid "Text alignment toolbar"
msgstr "টেক্সট শ্রেণীবিন্যাস টুলবার"

View File

@ -1,42 +0,0 @@
# Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
#
# !!! IMPORTANT !!!
#
# Before you edit this file, please keep in mind that contributing to the project
# translations is possible ONLY via the Transifex online service.
#
# To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
#
# To learn more, check out the official contributor's guide:
# https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
#
msgid ""
msgstr ""
"Language-Team: Bosnian (https://app.transifex.com/ckeditor/teams/11143/bs/)\n"
"Language: bs\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"Content-Type: text/plain; charset=UTF-8\n"
msgctxt "Toolbar button tooltip for aligning the text to the left."
msgid "Align left"
msgstr "Lijevo poravnanje"
msgctxt "Toolbar button tooltip for aligning the text to the right."
msgid "Align right"
msgstr "Desno poravnanje"
msgctxt "Toolbar button tooltip for aligning the text to center."
msgid "Align center"
msgstr "Centrirati"
msgctxt "Toolbar button tooltip for making the text justified."
msgid "Justify"
msgstr ""
msgctxt "Dropdown button tooltip for the text alignment feature."
msgid "Text alignment"
msgstr "Poravnanje teksta"
msgctxt "Label used by assistive technologies describing the text alignment feature toolbar."
msgid "Text alignment toolbar"
msgstr "Traka za poravnanje teksta"

View File

@ -1,42 +0,0 @@
# Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
#
# !!! IMPORTANT !!!
#
# Before you edit this file, please keep in mind that contributing to the project
# translations is possible ONLY via the Transifex online service.
#
# To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
#
# To learn more, check out the official contributor's guide:
# https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
#
msgid ""
msgstr ""
"Language-Team: Catalan (https://app.transifex.com/ckeditor/teams/11143/ca/)\n"
"Language: ca\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Content-Type: text/plain; charset=UTF-8\n"
msgctxt "Toolbar button tooltip for aligning the text to the left."
msgid "Align left"
msgstr "Alineació esquerra"
msgctxt "Toolbar button tooltip for aligning the text to the right."
msgid "Align right"
msgstr "Alineació dreta"
msgctxt "Toolbar button tooltip for aligning the text to center."
msgid "Align center"
msgstr "Alineació centre"
msgctxt "Toolbar button tooltip for making the text justified."
msgid "Justify"
msgstr "Justificar"
msgctxt "Dropdown button tooltip for the text alignment feature."
msgid "Text alignment"
msgstr "Alineació text"
msgctxt "Label used by assistive technologies describing the text alignment feature toolbar."
msgid "Text alignment toolbar"
msgstr "Barra d'eines d'alineació de text"

View File

@ -1,42 +0,0 @@
# Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
#
# !!! IMPORTANT !!!
#
# Before you edit this file, please keep in mind that contributing to the project
# translations is possible ONLY via the Transifex online service.
#
# To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
#
# To learn more, check out the official contributor's guide:
# https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
#
msgid ""
msgstr ""
"Language-Team: Czech (https://app.transifex.com/ckeditor/teams/11143/cs/)\n"
"Language: cs\n"
"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n"
"Content-Type: text/plain; charset=UTF-8\n"
msgctxt "Toolbar button tooltip for aligning the text to the left."
msgid "Align left"
msgstr "Zarovnat vlevo"
msgctxt "Toolbar button tooltip for aligning the text to the right."
msgid "Align right"
msgstr "Zarovnat vpravo"
msgctxt "Toolbar button tooltip for aligning the text to center."
msgid "Align center"
msgstr "Zarovnat na střed"
msgctxt "Toolbar button tooltip for making the text justified."
msgid "Justify"
msgstr "Zarovnat do bloku"
msgctxt "Dropdown button tooltip for the text alignment feature."
msgid "Text alignment"
msgstr "Zarovnání textu"
msgctxt "Label used by assistive technologies describing the text alignment feature toolbar."
msgid "Text alignment toolbar"
msgstr "Panel nástrojů zarovnání textu"

View File

@ -1,42 +0,0 @@
# Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
#
# !!! IMPORTANT !!!
#
# Before you edit this file, please keep in mind that contributing to the project
# translations is possible ONLY via the Transifex online service.
#
# To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
#
# To learn more, check out the official contributor's guide:
# https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
#
msgid ""
msgstr ""
"Language-Team: Danish (https://app.transifex.com/ckeditor/teams/11143/da/)\n"
"Language: da\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Content-Type: text/plain; charset=UTF-8\n"
msgctxt "Toolbar button tooltip for aligning the text to the left."
msgid "Align left"
msgstr "Justér venstre"
msgctxt "Toolbar button tooltip for aligning the text to the right."
msgid "Align right"
msgstr "Justér højre"
msgctxt "Toolbar button tooltip for aligning the text to center."
msgid "Align center"
msgstr "Justér center"
msgctxt "Toolbar button tooltip for making the text justified."
msgid "Justify"
msgstr "Justér"
msgctxt "Dropdown button tooltip for the text alignment feature."
msgid "Text alignment"
msgstr "Tekstjustering"
msgctxt "Label used by assistive technologies describing the text alignment feature toolbar."
msgid "Text alignment toolbar"
msgstr "Tekstjustering værktøjslinje"

View File

@ -1,42 +0,0 @@
# Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
#
# !!! IMPORTANT !!!
#
# Before you edit this file, please keep in mind that contributing to the project
# translations is possible ONLY via the Transifex online service.
#
# To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
#
# To learn more, check out the official contributor's guide:
# https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
#
msgid ""
msgstr ""
"Language-Team: German (Switzerland) (https://app.transifex.com/ckeditor/teams/11143/de_CH/)\n"
"Language: de_CH\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Content-Type: text/plain; charset=UTF-8\n"
msgctxt "Toolbar button tooltip for aligning the text to the left."
msgid "Align left"
msgstr "Linksbündig"
msgctxt "Toolbar button tooltip for aligning the text to the right."
msgid "Align right"
msgstr "Rechtsbündig"
msgctxt "Toolbar button tooltip for aligning the text to center."
msgid "Align center"
msgstr "Zentriert"
msgctxt "Toolbar button tooltip for making the text justified."
msgid "Justify"
msgstr "Blocksatz"
msgctxt "Dropdown button tooltip for the text alignment feature."
msgid "Text alignment"
msgstr "Textausrichtung"
msgctxt "Label used by assistive technologies describing the text alignment feature toolbar."
msgid "Text alignment toolbar"
msgstr "Textausrichtung Werkzeugleiste"

View File

@ -1,42 +0,0 @@
# Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
#
# !!! IMPORTANT !!!
#
# Before you edit this file, please keep in mind that contributing to the project
# translations is possible ONLY via the Transifex online service.
#
# To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
#
# To learn more, check out the official contributor's guide:
# https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
#
msgid ""
msgstr ""
"Language-Team: German (https://app.transifex.com/ckeditor/teams/11143/de/)\n"
"Language: de\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Content-Type: text/plain; charset=UTF-8\n"
msgctxt "Toolbar button tooltip for aligning the text to the left."
msgid "Align left"
msgstr "Linksbündig"
msgctxt "Toolbar button tooltip for aligning the text to the right."
msgid "Align right"
msgstr "Rechtsbündig"
msgctxt "Toolbar button tooltip for aligning the text to center."
msgid "Align center"
msgstr "Zentriert"
msgctxt "Toolbar button tooltip for making the text justified."
msgid "Justify"
msgstr "Blocksatz"
msgctxt "Dropdown button tooltip for the text alignment feature."
msgid "Text alignment"
msgstr "Textausrichtung"
msgctxt "Label used by assistive technologies describing the text alignment feature toolbar."
msgid "Text alignment toolbar"
msgstr "Text-Ausrichtung Toolbar"

View File

@ -1,42 +0,0 @@
# Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
#
# !!! IMPORTANT !!!
#
# Before you edit this file, please keep in mind that contributing to the project
# translations is possible ONLY via the Transifex online service.
#
# To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
#
# To learn more, check out the official contributor's guide:
# https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
#
msgid ""
msgstr ""
"Language-Team: Greek (https://app.transifex.com/ckeditor/teams/11143/el/)\n"
"Language: el\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Content-Type: text/plain; charset=UTF-8\n"
msgctxt "Toolbar button tooltip for aligning the text to the left."
msgid "Align left"
msgstr "Στοίχιση αριστερά"
msgctxt "Toolbar button tooltip for aligning the text to the right."
msgid "Align right"
msgstr "Στοίχιση δεξιά"
msgctxt "Toolbar button tooltip for aligning the text to center."
msgid "Align center"
msgstr "Στοίχιση στο κέντρο"
msgctxt "Toolbar button tooltip for making the text justified."
msgid "Justify"
msgstr "Πλήρης στοίχηση"
msgctxt "Dropdown button tooltip for the text alignment feature."
msgid "Text alignment"
msgstr "Στοίχιση κειμένου"
msgctxt "Label used by assistive technologies describing the text alignment feature toolbar."
msgid "Text alignment toolbar"
msgstr "Γραμμή εργαλείων στοίχισης κειμένου"

View File

@ -1,42 +0,0 @@
# Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
#
# !!! IMPORTANT !!!
#
# Before you edit this file, please keep in mind that contributing to the project
# translations is possible ONLY via the Transifex online service.
#
# To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
#
# To learn more, check out the official contributor's guide:
# https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
#
msgid ""
msgstr ""
"Language-Team: English (Australia) (https://app.transifex.com/ckeditor/teams/11143/en_AU/)\n"
"Language: en_AU\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Content-Type: text/plain; charset=UTF-8\n"
msgctxt "Toolbar button tooltip for aligning the text to the left."
msgid "Align left"
msgstr "Align left"
msgctxt "Toolbar button tooltip for aligning the text to the right."
msgid "Align right"
msgstr "Align right"
msgctxt "Toolbar button tooltip for aligning the text to center."
msgid "Align center"
msgstr "Align centre"
msgctxt "Toolbar button tooltip for making the text justified."
msgid "Justify"
msgstr "Justify"
msgctxt "Dropdown button tooltip for the text alignment feature."
msgid "Text alignment"
msgstr "Text alignment"
msgctxt "Label used by assistive technologies describing the text alignment feature toolbar."
msgid "Text alignment toolbar"
msgstr "Text alignment toolbar"

View File

@ -1,42 +0,0 @@
# Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
#
# !!! IMPORTANT !!!
#
# Before you edit this file, please keep in mind that contributing to the project
# translations is possible ONLY via the Transifex online service.
#
# To submit your translations, visit https://www.transifex.com/ckeditor/ckeditor5.
#
# To learn more, check out the official contributor's guide:
# https://ckeditor.com/docs/ckeditor5/latest/framework/guides/contributing/contributing.html
#
msgid ""
msgstr ""
"Language-Team: English (United Kingdom) (https://app.transifex.com/ckeditor/teams/11143/en_GB/)\n"
"Language: en_GB\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Content-Type: text/plain; charset=UTF-8\n"
msgctxt "Toolbar button tooltip for aligning the text to the left."
msgid "Align left"
msgstr "Align left"
msgctxt "Toolbar button tooltip for aligning the text to the right."
msgid "Align right"
msgstr "Align right"
msgctxt "Toolbar button tooltip for aligning the text to center."
msgid "Align center"
msgstr "Align center"
msgctxt "Toolbar button tooltip for making the text justified."
msgid "Justify"
msgstr "Justify"
msgctxt "Dropdown button tooltip for the text alignment feature."
msgid "Text alignment"
msgstr "Text alignment"
msgctxt "Label used by assistive technologies describing the text alignment feature toolbar."
msgid "Text alignment toolbar"
msgstr ""

Some files were not shown because too many files have changed in this diff Show More