diff --git a/public/locales/en/components.json b/public/locales/en/components.json index 37346f1..3516076 100644 --- a/public/locales/en/components.json +++ b/public/locales/en/components.json @@ -1,42 +1,47 @@ { - "table": { - "no_records": "No records", - "pagination": { - "selected": "selected.", - "page_size": "Page size", - "page": "Page", - "total": "Total", - "records": "records" - }, - "toolbar": { - "clear_filters": "Clear Filters", - "view": "View", - "columns": "Columns", - "search_placeholder": "Search..." - }, - "column": { - "asc": "Ascending", - "desc": "Descending", - "hide": "Hide" - } + "table": { + "no_records": "No records", + "pagination": { + "selected": "selected.", + "page_size": "Page size", + "page": "Page", + "total": "Total", + "records": "records" }, - "select": { - "user": { - "search_placeholder": "Search user...", - "not_found": "User not found", - "select_placeholder": "Select user" - }, - "server": { - "search_placeholder": "Search server...", - "not_found": "Server not found", - "select_placeholder": "Select server" - } + "toolbar": { + "clear_filters": "Clear Filters", + "view": "View", + "columns": "Columns", + "search_placeholder": "Search..." }, - "transfer": { - "select_all": "Select all", - "search": "Search...", - "selected": "({{selected}}/{{total}} selected)", - "no_records": "No data", - "save": "Save" + "column": { + "asc": "Ascending", + "desc": "Descending", + "hide": "Hide" } + }, + "select": { + "user": { + "search_placeholder": "Search user...", + "not_found": "User not found", + "select_placeholder": "Select user" + }, + "server": { + "search_placeholder": "Search server...", + "not_found": "Server not found", + "select_placeholder": "Select server" + }, + "role": { + "select_placeholder": "Select a role...", + "search_placeholder": "Search a role...", + "not_found": "No roles found." + } + }, + "transfer": { + "select_all": "Select all", + "search": "Search...", + "selected": "({{selected}}/{{total}} selected)", + "no_records": "No data", + "save": "Save" + } } \ No newline at end of file diff --git a/public/locales/tr/components.json b/public/locales/tr/components.json index a4292e7..83a670c 100644 --- a/public/locales/tr/components.json +++ b/public/locales/tr/components.json @@ -1,42 +1,47 @@ { - "table": { - "no_records": "Kayıt yok", - "pagination": { - "selected": "seçildi.", - "page_size": "Sayfa boyutu", - "page": "Sayfa", - "total": "Toplam", - "records": "kayıt" - }, - "toolbar": { - "clear_filters": "Filtreleri Temizle", - "view": "Görüntüleme", - "columns": "Sütunlar", - "search_placeholder": "Arama..." - }, - "column": { - "asc": "Artan", - "desc": "Azalan", - "hide": "Gizle" - } + "table": { + "no_records": "Kayıt yok", + "pagination": { + "selected": "seçildi.", + "page_size": "Sayfa boyutu", + "page": "Sayfa", + "total": "Toplam", + "records": "kayıt" }, - "select": { - "user": { - "search_placeholder": "Kullanıcı ara...", - "not_found": "Kullanıcı bulunamadı", - "select_placeholder": "Kullanıcı seçiniz" - }, - "server": { - "search_placeholder": "Sunucu ara...", - "not_found": "Sunucu bulunamadı", - "select_placeholder": "Sunucu seçiniz" - } + "toolbar": { + "clear_filters": "Filtreleri Temizle", + "view": "Görüntüleme", + "columns": "Sütunlar", + "search_placeholder": "Arama..." }, - "transfer": { - "select_all": "Tümünü seç", - "search": "Arama...", - "selected": "({{selected}}/{{total}} seçili)", - "no_records": "Veri yok", - "save": "Kaydet" + "column": { + "asc": "Artan", + "desc": "Azalan", + "hide": "Gizle" } + }, + "select": { + "user": { + "search_placeholder": "Kullanıcı ara...", + "not_found": "Kullanıcı bulunamadı", + "select_placeholder": "Kullanıcı seçiniz" + }, + "server": { + "search_placeholder": "Sunucu ara...", + "not_found": "Sunucu bulunamadı", + "select_placeholder": "Sunucu seçiniz" + }, + "role": { + "select_placeholder": "Rol seçimi yapınız...", + "search_placeholder": "Rol arayın...", + "not_found": "Rol bulunamadı." + } + }, + "transfer": { + "select_all": "Tümünü seç", + "search": "Arama...", + "selected": "({{selected}}/{{total}} seçili)", + "no_records": "Veri yok", + "save": "Kaydet" + } } \ No newline at end of file diff --git a/src/components/selectbox/role-select.tsx b/src/components/selectbox/role-select.tsx new file mode 100644 index 0000000..33a6d04 --- /dev/null +++ b/src/components/selectbox/role-select.tsx @@ -0,0 +1,122 @@ +import * as React from "react" +import { apiService } from "@/services" +import { Check, ChevronsUpDown, FileInput } from "lucide-react" +import { useTranslation } from "react-i18next" + +import { IRole } from "@/types/role" +import { cn } from "@/lib/utils" +import { Button } from "@/components/ui/button" +import { + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, +} from "@/components/ui/command" +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover" + +import { Icons } from "../ui/icons" +import { ScrollArea } from "../ui/scroll-area" + +export function SelectRole({ + defaultValue, + onValueChange, +}: { + defaultValue: string + onValueChange: (value: string) => void +}) { + const { t } = useTranslation("components") + + const [open, setOpen] = React.useState(false) + const [value, setValue] = React.useState("") + + const [roles, setRoles] = React.useState([]) + const [loading, setLoading] = React.useState(true) + + React.useEffect(() => { + apiService + .getInstance() + .get("/settings/roles") + .then((res) => { + setRoles(res.data) + }) + .finally(() => { + setLoading(false) + }) + }, []) + + React.useEffect(() => { + if (!defaultValue) return + setValue(defaultValue) + }, [defaultValue]) + + React.useEffect(() => { + onValueChange(value) + }, [value]) + + return ( + + + + + + + + {t("select.role.not_found")} + + + + {roles.map((role) => ( + { + setValue(role.id === value ? "" : role.id) + setOpen(false) + }} + > + + {role.name} + + ))} + + + + + + + ) +} diff --git a/src/components/settings/ldap-role-mapping.tsx b/src/components/settings/ldap-role-mapping.tsx new file mode 100644 index 0000000..87b4843 --- /dev/null +++ b/src/components/settings/ldap-role-mapping.tsx @@ -0,0 +1,112 @@ +import { useEffect, useState } from "react" +import { apiService } from "@/services" +import { useTranslation } from "react-i18next" + +import { SelectRole } from "../selectbox/role-select" +import { Card } from "../ui/card" +import { useToast } from "../ui/use-toast" +import AsyncTransferList from "./async-transfer-list" + +export default function LdapRoleMapping(props: { + username: string + password: string +}) { + const { t } = useTranslation("settings") + const { toast } = useToast() + + const { username, password } = props + + const [roleListLoading, setRoleListLoading] = useState(true) + const [roleList, setRoleList] = useState([]) + const [selectedRoleList, setSelectedRoleList] = useState([]) + const [selectedRole, setSelectedRole] = useState("") + + const fetchRoleMappingList = (param?: string) => { + setRoleListLoading(true) + apiService + .getInstance() + .get("settings/access/ldap/permissions/role_mappings", { + params: { + username: username, + password: password, + search_query: param, + role_id: selectedRole, + }, + }) + .then((res) => { + setRoleList( + res.data.items.map((it: string) => { + return { + id: it, + name: it, + } + }) + ) + setSelectedRoleList( + res.data.selected.map((it: string) => { + return { + id: it, + name: it, + } + }) + ) + }) + .finally(() => { + setRoleListLoading(false) + setKey((prev) => prev + 1) + }) + } + + const [key, setKey] = useState(0) + + useEffect(() => { + if (!username || !password) return + if (!selectedRole) return + fetchRoleMappingList() + }, [selectedRole, username, password]) + + const handleRoleMappingSave = (groups: any[]) => { + apiService + .getInstance() + .post("settings/access/ldap/permissions/role_mappings", { + role_id: selectedRole, + groups: groups.map((it) => it.id), + }) + .then(() => { + toast({ + title: t("success"), + description: t("access.permissions.group_success"), + }) + }) + .catch(() => { + toast({ + title: t("error"), + description: t("access.permissions.group_error"), + variant: "destructive", + }) + }) + } + + return ( +
+ + {!selectedRole && ( + + İşlem yapabilmek için üst kısımdan bir rol seçiniz. + + )} + {selectedRole && ( + fetchRoleMappingList(v)} + key={key} + /> + )} +
+ ) +} diff --git a/src/pages/settings/access/permissions_ldap.tsx b/src/pages/settings/access/permissions_ldap.tsx index 5447188..97ab0c8 100644 --- a/src/pages/settings/access/permissions_ldap.tsx +++ b/src/pages/settings/access/permissions_ldap.tsx @@ -2,7 +2,7 @@ import { ReactElement, useEffect, useState } from "react" import { NextPageWithLayout } from "@/pages/_app" import { apiService } from "@/services" import { zodResolver } from "@hookform/resolvers/zod" -import { KeyRound, LogIn, User2, Users2 } from "lucide-react" +import { KeyRound, LinkIcon, LogIn, User2, Users2 } from "lucide-react" import { useForm } from "react-hook-form" import { useTranslation } from "react-i18next" import * as z from "zod" @@ -17,6 +17,7 @@ import { useToast } from "@/components/ui/use-toast" import AccessLayout from "@/components/_layout/access_layout" import { Form, FormField, FormMessage } from "@/components/form/form" import AsyncTransferList from "@/components/settings/async-transfer-list" +import LdapRoleMapping from "@/components/settings/ldap-role-mapping" const AccessLdapPermissionsPage: NextPageWithLayout = () => { const { t } = useTranslation("settings") @@ -291,6 +292,10 @@ const AccessLdapPermissionsPage: NextPageWithLayout = () => { {t("access.permissions.group.title")} + + + Rol Bağlama + { onSearch={(v: string) => fetchGroupsList(v)} /> + + + )}