forked from baron/baron-sso
조직도 줌 레벨 상향
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
{
|
{
|
||||||
"extends": ["../common/config/biome.base.json"]
|
"extends": ["../common/config/biome.base.json"],
|
||||||
|
"files": {
|
||||||
|
"ignore": [".vite"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,13 +22,13 @@ import { useAuth } from "react-oidc-context";
|
|||||||
import { NavLink, Outlet, useLocation, useNavigate } from "react-router-dom";
|
import { NavLink, Outlet, useLocation, useNavigate } from "react-router-dom";
|
||||||
import {
|
import {
|
||||||
AppSidebar,
|
AppSidebar,
|
||||||
|
type ShellSidebarNavItem,
|
||||||
type ShellTranslator,
|
type ShellTranslator,
|
||||||
applyShellTheme,
|
applyShellTheme,
|
||||||
buildShellProfileSummary,
|
buildShellProfileSummary,
|
||||||
buildShellSessionStatus,
|
buildShellSessionStatus,
|
||||||
readShellSessionExpiryEnabled,
|
readShellSessionExpiryEnabled,
|
||||||
readShellTheme,
|
readShellTheme,
|
||||||
type ShellSidebarNavItem,
|
|
||||||
shellLayoutClasses,
|
shellLayoutClasses,
|
||||||
writeShellSessionExpiryEnabled,
|
writeShellSessionExpiryEnabled,
|
||||||
} from "../../../../common/shell";
|
} from "../../../../common/shell";
|
||||||
|
|||||||
@@ -111,37 +111,36 @@ const DialogPortal = ({ children }: { children?: React.ReactNode }) => {
|
|||||||
};
|
};
|
||||||
DialogPortal.displayName = "DialogPortal";
|
DialogPortal.displayName = "DialogPortal";
|
||||||
|
|
||||||
const DialogClose = React.forwardRef<
|
const DialogClose = React.forwardRef<HTMLButtonElement, DialogTriggerProps>(
|
||||||
HTMLButtonElement,
|
({ asChild = false, children, onClick, ...props }, ref) => {
|
||||||
DialogTriggerProps
|
const { setOpen } = useDialogContext("DialogClose");
|
||||||
>(({ asChild = false, children, onClick, ...props }, ref) => {
|
const handleClose = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
const { setOpen } = useDialogContext("DialogClose");
|
onClick?.(event);
|
||||||
const handleClose = (event: React.MouseEvent<HTMLButtonElement>) => {
|
if (!event.defaultPrevented) {
|
||||||
onClick?.(event);
|
setOpen(false);
|
||||||
if (!event.defaultPrevented) {
|
}
|
||||||
setOpen(false);
|
};
|
||||||
|
|
||||||
|
if (asChild && React.isValidElement(children)) {
|
||||||
|
const child = children as React.ReactElement<{
|
||||||
|
onClick?: React.MouseEventHandler<HTMLElement>;
|
||||||
|
}>;
|
||||||
|
return React.cloneElement(child, {
|
||||||
|
...props,
|
||||||
|
onClick: composeEventHandlers(
|
||||||
|
child.props.onClick as React.MouseEventHandler<HTMLButtonElement>,
|
||||||
|
() => setOpen(false),
|
||||||
|
),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
if (asChild && React.isValidElement(children)) {
|
return (
|
||||||
const child = children as React.ReactElement<{
|
<button type="button" ref={ref} onClick={handleClose} {...props}>
|
||||||
onClick?: React.MouseEventHandler<HTMLElement>;
|
{children}
|
||||||
}>;
|
</button>
|
||||||
return React.cloneElement(child, {
|
);
|
||||||
...props,
|
},
|
||||||
onClick: composeEventHandlers(
|
);
|
||||||
child.props.onClick as React.MouseEventHandler<HTMLButtonElement>,
|
|
||||||
() => setOpen(false),
|
|
||||||
),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<button type="button" ref={ref} onClick={handleClose} {...props}>
|
|
||||||
{children}
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
DialogClose.displayName = "DialogClose";
|
DialogClose.displayName = "DialogClose";
|
||||||
|
|
||||||
const DialogOverlay = React.forwardRef<
|
const DialogOverlay = React.forwardRef<
|
||||||
@@ -169,8 +168,8 @@ const DialogOverlay = React.forwardRef<
|
|||||||
DialogOverlay.displayName = "DialogOverlay";
|
DialogOverlay.displayName = "DialogOverlay";
|
||||||
|
|
||||||
const DialogContent = React.forwardRef<
|
const DialogContent = React.forwardRef<
|
||||||
HTMLDivElement,
|
HTMLDialogElement,
|
||||||
React.HTMLAttributes<HTMLDivElement>
|
React.HTMLAttributes<HTMLDialogElement>
|
||||||
>(({ className, children, onKeyDown, ...props }, ref) => {
|
>(({ className, children, onKeyDown, ...props }, ref) => {
|
||||||
const { open, setOpen } = useDialogContext("DialogContent");
|
const { open, setOpen } = useDialogContext("DialogContent");
|
||||||
|
|
||||||
@@ -194,13 +193,13 @@ const DialogContent = React.forwardRef<
|
|||||||
return (
|
return (
|
||||||
<DialogPortal>
|
<DialogPortal>
|
||||||
<DialogOverlay />
|
<DialogOverlay />
|
||||||
<div
|
<dialog
|
||||||
ref={ref}
|
ref={ref}
|
||||||
role="dialog"
|
open
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
data-state="open"
|
data-state="open"
|
||||||
className={cn(
|
className={cn(
|
||||||
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
|
"fixed left-[50%] top-[50%] z-50 m-0 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 backdrop:bg-transparent data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
onKeyDown={onKeyDown}
|
onKeyDown={onKeyDown}
|
||||||
@@ -211,7 +210,7 @@ const DialogContent = React.forwardRef<
|
|||||||
<X className="h-4 w-4" />
|
<X className="h-4 w-4" />
|
||||||
<span className="sr-only">Close</span>
|
<span className="sr-only">Close</span>
|
||||||
</DialogClose>
|
</DialogClose>
|
||||||
</div>
|
</dialog>
|
||||||
</DialogPortal>
|
</DialogPortal>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import {
|
|||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
import { PageHeader } from "../../../../common/core/components/page";
|
||||||
|
import { commonStickyTableHeaderClass } from "../../../../common/ui/table";
|
||||||
import { Badge } from "../../components/ui/badge";
|
import { Badge } from "../../components/ui/badge";
|
||||||
import { Button } from "../../components/ui/button";
|
import { Button } from "../../components/ui/button";
|
||||||
import {
|
import {
|
||||||
@@ -38,8 +40,6 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "../../components/ui/table";
|
} from "../../components/ui/table";
|
||||||
import { PageHeader } from "../../../../common/core/components/page";
|
|
||||||
import { commonStickyTableHeaderClass } from "../../../../common/ui/table";
|
|
||||||
import {
|
import {
|
||||||
type ApiKeySummary,
|
type ApiKeySummary,
|
||||||
deleteApiKey,
|
deleteApiKey,
|
||||||
|
|||||||
@@ -13,7 +13,12 @@ import { PageHeader } from "../../../../common/core/components/page";
|
|||||||
import { SearchFilterBar } from "../../../../common/ui/search-filter-bar";
|
import { SearchFilterBar } from "../../../../common/ui/search-filter-bar";
|
||||||
import { Badge } from "../../components/ui/badge";
|
import { Badge } from "../../components/ui/badge";
|
||||||
import { Button } from "../../components/ui/button";
|
import { Button } from "../../components/ui/button";
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "../../components/ui/card";
|
import {
|
||||||
|
Card,
|
||||||
|
CardContent,
|
||||||
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
|
} from "../../components/ui/card";
|
||||||
import { Input } from "../../components/ui/input";
|
import { Input } from "../../components/ui/input";
|
||||||
import type { AuditLog } from "../../lib/adminApi";
|
import type { AuditLog } from "../../lib/adminApi";
|
||||||
import { fetchAuditLogs } from "../../lib/adminApi";
|
import { fetchAuditLogs } from "../../lib/adminApi";
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useAuth } from "react-oidc-context";
|
import { useAuth } from "react-oidc-context";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
|
import { commonStickyTableHeaderClass } from "../../../../../common/ui/table";
|
||||||
import { Badge } from "../../../components/ui/badge";
|
import { Badge } from "../../../components/ui/badge";
|
||||||
import { Button } from "../../../components/ui/button";
|
import { Button } from "../../../components/ui/button";
|
||||||
import {
|
import {
|
||||||
@@ -38,7 +39,6 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "../../../components/ui/table";
|
} from "../../../components/ui/table";
|
||||||
import { commonStickyTableHeaderClass } from "../../../../../common/ui/table";
|
|
||||||
import { toast } from "../../../components/ui/use-toast";
|
import { toast } from "../../../components/ui/use-toast";
|
||||||
import {
|
import {
|
||||||
type TenantAdmin,
|
type TenantAdmin,
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
import type React from "react";
|
import type React from "react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
|
import { commonStickyTableHeaderClass } from "../../../../../common/ui/table";
|
||||||
import { Badge } from "../../../components/ui/badge";
|
import { Badge } from "../../../components/ui/badge";
|
||||||
import { Button } from "../../../components/ui/button";
|
import { Button } from "../../../components/ui/button";
|
||||||
import {
|
import {
|
||||||
@@ -50,7 +51,6 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "../../../components/ui/table";
|
} from "../../../components/ui/table";
|
||||||
import { commonStickyTableHeaderClass } from "../../../../../common/ui/table";
|
|
||||||
import { toast } from "../../../components/ui/use-toast";
|
import { toast } from "../../../components/ui/use-toast";
|
||||||
import {
|
import {
|
||||||
type GroupSummary,
|
type GroupSummary,
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { ArrowRight, Building2, Plus } from "lucide-react";
|
import { ArrowRight, Building2, Plus } from "lucide-react";
|
||||||
import { Link, useNavigate, useParams } from "react-router-dom";
|
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||||
|
import {
|
||||||
|
commonStickyTableHeaderClass,
|
||||||
|
commonTableShellClass,
|
||||||
|
commonTableViewportClass,
|
||||||
|
} from "../../../../../common/ui/table";
|
||||||
import { Badge } from "../../../components/ui/badge";
|
import { Badge } from "../../../components/ui/badge";
|
||||||
import { Button } from "../../../components/ui/button";
|
import { Button } from "../../../components/ui/button";
|
||||||
import {
|
import {
|
||||||
@@ -18,11 +23,6 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "../../../components/ui/table";
|
} from "../../../components/ui/table";
|
||||||
import {
|
|
||||||
commonStickyTableHeaderClass,
|
|
||||||
commonTableShellClass,
|
|
||||||
commonTableViewportClass,
|
|
||||||
} from "../../../../../common/ui/table";
|
|
||||||
import { fetchAllTenants } from "../../../lib/adminApi";
|
import { fetchAllTenants } from "../../../lib/adminApi";
|
||||||
import { t } from "../../../lib/i18n";
|
import { t } from "../../../lib/i18n";
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
UserPlus,
|
UserPlus,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { Link, useNavigate, useParams } from "react-router-dom";
|
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||||
|
import { commonStickyTableHeaderClass } from "../../../../../common/ui/table";
|
||||||
import { Badge } from "../../../components/ui/badge";
|
import { Badge } from "../../../components/ui/badge";
|
||||||
import { Button } from "../../../components/ui/button";
|
import { Button } from "../../../components/ui/button";
|
||||||
import {
|
import {
|
||||||
@@ -32,7 +33,6 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "../../../components/ui/table";
|
} from "../../../components/ui/table";
|
||||||
import { commonStickyTableHeaderClass } from "../../../../../common/ui/table";
|
|
||||||
import { toast } from "../../../components/ui/use-toast";
|
import { toast } from "../../../components/ui/use-toast";
|
||||||
import { fetchTenant, fetchUsers, updateUser } from "../../../lib/adminApi";
|
import { fetchTenant, fetchUsers, updateUser } from "../../../lib/adminApi";
|
||||||
import { t } from "../../../lib/i18n";
|
import { t } from "../../../lib/i18n";
|
||||||
|
|||||||
@@ -681,11 +681,7 @@ function ComparisonFilterButtons<T extends string>({
|
|||||||
aria-pressed={isSelected}
|
aria-pressed={isSelected}
|
||||||
aria-expanded={hasDetail && openDetailFor === option.value}
|
aria-expanded={hasDetail && openDetailFor === option.value}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (
|
if (hasDetail && isSelected && openDetailFor !== option.value) {
|
||||||
hasDetail &&
|
|
||||||
isSelected &&
|
|
||||||
openDetailFor !== option.value
|
|
||||||
) {
|
|
||||||
setOpenDetailFor(option.value);
|
setOpenDetailFor(option.value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { useQuery } from "@tanstack/react-query";
|
|||||||
import { Building2, Plus, Users } from "lucide-react";
|
import { Building2, Plus, Users } from "lucide-react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
import { commonStickyTableHeaderClass } from "../../../../../common/ui/table";
|
||||||
import { Badge } from "../../../components/ui/badge";
|
import { Badge } from "../../../components/ui/badge";
|
||||||
import { Button } from "../../../components/ui/button";
|
import { Button } from "../../../components/ui/button";
|
||||||
import {
|
import {
|
||||||
@@ -19,7 +20,6 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "../../../components/ui/table";
|
} from "../../../components/ui/table";
|
||||||
import { commonStickyTableHeaderClass } from "../../../../../common/ui/table";
|
|
||||||
import {
|
import {
|
||||||
type TenantSummary,
|
type TenantSummary,
|
||||||
fetchAllTenants,
|
fetchAllTenants,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import type { AxiosError } from "axios";
|
|||||||
import { ArrowLeft, Shield, Trash2, UserPlus, Users } from "lucide-react";
|
import { ArrowLeft, Shield, Trash2, UserPlus, Users } from "lucide-react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Link, useParams } from "react-router-dom";
|
import { Link, useParams } from "react-router-dom";
|
||||||
|
import { commonStickyTableHeaderClass } from "../../../../../common/ui/table";
|
||||||
import { Badge } from "../../../components/ui/badge";
|
import { Badge } from "../../../components/ui/badge";
|
||||||
import { Button } from "../../../components/ui/button";
|
import { Button } from "../../../components/ui/button";
|
||||||
import {
|
import {
|
||||||
@@ -38,7 +39,6 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "../../../components/ui/table";
|
} from "../../../components/ui/table";
|
||||||
import { commonStickyTableHeaderClass } from "../../../../../common/ui/table";
|
|
||||||
import { toast } from "../../../components/ui/use-toast";
|
import { toast } from "../../../components/ui/use-toast";
|
||||||
import {
|
import {
|
||||||
addGroupMember,
|
addGroupMember,
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import {
|
|||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
|
import { PageHeader } from "../../../../common/core/components/page";
|
||||||
import {
|
import {
|
||||||
SortableTableHead,
|
SortableTableHead,
|
||||||
sortableTableHeadBaseClassName,
|
sortableTableHeadBaseClassName,
|
||||||
@@ -29,12 +30,11 @@ import {
|
|||||||
sortItems,
|
sortItems,
|
||||||
toggleSort,
|
toggleSort,
|
||||||
} from "../../../../common/core/utils";
|
} from "../../../../common/core/utils";
|
||||||
import { PageHeader } from "../../../../common/core/components/page";
|
import { SearchFilterBar } from "../../../../common/ui/search-filter-bar";
|
||||||
import {
|
import {
|
||||||
commonTableShellClass,
|
commonTableShellClass,
|
||||||
commonTableViewportClass,
|
commonTableViewportClass,
|
||||||
} from "../../../../common/ui/table";
|
} from "../../../../common/ui/table";
|
||||||
import { SearchFilterBar } from "../../../../common/ui/search-filter-bar";
|
|
||||||
import { Button } from "../../components/ui/button";
|
import { Button } from "../../components/ui/button";
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
@@ -545,7 +545,9 @@ function UserListPage() {
|
|||||||
onChange={() => toggleColumn(field.key)}
|
onChange={() => toggleColumn(field.key)}
|
||||||
/>
|
/>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<span className="text-sm font-medium">{field.label}</span>
|
<span className="text-sm font-medium">
|
||||||
|
{field.label}
|
||||||
|
</span>
|
||||||
<span className="font-mono text-xs text-muted-foreground">
|
<span className="font-mono text-xs text-muted-foreground">
|
||||||
{field.key}
|
{field.key}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -19,9 +19,7 @@ createRoot(rootElement).render(
|
|||||||
<StrictMode>
|
<StrictMode>
|
||||||
<AuthProvider {...oidcConfig}>
|
<AuthProvider {...oidcConfig}>
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<RouterProvider
|
<RouterProvider router={router} />
|
||||||
router={router}
|
|
||||||
/>
|
|
||||||
<Toaster />
|
<Toaster />
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
</AuthProvider>
|
</AuthProvider>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const buildOutDir =
|
|||||||
const allowedHosts = getAllowedHosts(
|
const allowedHosts = getAllowedHosts(
|
||||||
["sadmin.hmac.kr", "localhost", "172.16.10.176", "127.0.0.1"],
|
["sadmin.hmac.kr", "localhost", "172.16.10.176", "127.0.0.1"],
|
||||||
undefined,
|
undefined,
|
||||||
undefined
|
undefined,
|
||||||
);
|
);
|
||||||
|
|
||||||
export default defineConfig(
|
export default defineConfig(
|
||||||
@@ -40,5 +40,5 @@ export default defineConfig(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module baron-sso-backend
|
module baron-sso-backend
|
||||||
|
|
||||||
go 1.24.0
|
go 1.26.2
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/ClickHouse/clickhouse-go/v2 v2.42.0
|
github.com/ClickHouse/clickhouse-go/v2 v2.42.0
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ back = "Back"
|
|||||||
back_to_login = "Back to login"
|
back_to_login = "Back to login"
|
||||||
cancel = "Cancel"
|
cancel = "Cancel"
|
||||||
change_file = "Change File"
|
change_file = "Change File"
|
||||||
|
clear = "Clear"
|
||||||
clear_search = "Clear Search"
|
clear_search = "Clear Search"
|
||||||
close = "Close"
|
close = "Close"
|
||||||
collapse = "Collapse"
|
collapse = "Collapse"
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ back = "돌아가기"
|
|||||||
back_to_login = "로그인으로 돌아가기"
|
back_to_login = "로그인으로 돌아가기"
|
||||||
cancel = "취소"
|
cancel = "취소"
|
||||||
change_file = "파일 변경"
|
change_file = "파일 변경"
|
||||||
|
clear = "초기화"
|
||||||
clear_search = "검색 초기화"
|
clear_search = "검색 초기화"
|
||||||
close = "닫기"
|
close = "닫기"
|
||||||
collapse = "접기"
|
collapse = "접기"
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ back = ""
|
|||||||
back_to_login = ""
|
back_to_login = ""
|
||||||
cancel = ""
|
cancel = ""
|
||||||
change_file = ""
|
change_file = ""
|
||||||
|
clear = ""
|
||||||
clear_search = ""
|
clear_search = ""
|
||||||
close = ""
|
close = ""
|
||||||
collapse = ""
|
collapse = ""
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
{
|
{
|
||||||
"extends": ["../common/config/biome.base.json"]
|
"extends": ["../common/config/biome.base.json"],
|
||||||
|
"files": {
|
||||||
|
"ignore": [".vite"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
785
devfront/package-lock.json
generated
785
devfront/package-lock.json
generated
@@ -48,13 +48,6 @@
|
|||||||
"node": ">=24.0.0"
|
"node": ">=24.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@acemir/cssom": {
|
|
||||||
"version": "0.9.31",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true
|
|
||||||
},
|
|
||||||
"node_modules/@alloc/quick-lru": {
|
"node_modules/@alloc/quick-lru": {
|
||||||
"version": "5.2.0",
|
"version": "5.2.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -66,207 +59,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@asamuzakjp/css-color": {
|
|
||||||
"version": "5.1.11",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@asamuzakjp/generational-cache": "^1.0.1",
|
|
||||||
"@csstools/css-calc": "^3.2.0",
|
|
||||||
"@csstools/css-color-parser": "^4.1.0",
|
|
||||||
"@csstools/css-parser-algorithms": "^4.0.0",
|
|
||||||
"@csstools/css-tokenizer": "^4.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@asamuzakjp/dom-selector": {
|
|
||||||
"version": "6.8.1",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@asamuzakjp/nwsapi": "^2.3.9",
|
|
||||||
"bidi-js": "^1.0.3",
|
|
||||||
"css-tree": "^3.1.0",
|
|
||||||
"is-potential-custom-element-name": "^1.0.1",
|
|
||||||
"lru-cache": "^11.2.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@asamuzakjp/generational-cache": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@asamuzakjp/nwsapi": {
|
|
||||||
"version": "2.3.9",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true
|
|
||||||
},
|
|
||||||
"node_modules/@bramus/specificity": {
|
|
||||||
"version": "2.4.2",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"css-tree": "^3.0.0"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"specificity": "bin/cli.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@csstools/color-helpers": {
|
|
||||||
"version": "6.0.2",
|
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/csstools"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/csstools"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT-0",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=20.19.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@csstools/css-calc": {
|
|
||||||
"version": "3.2.0",
|
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/csstools"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/csstools"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=20.19.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@csstools/css-parser-algorithms": "^4.0.0",
|
|
||||||
"@csstools/css-tokenizer": "^4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@csstools/css-color-parser": {
|
|
||||||
"version": "4.1.0",
|
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/csstools"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/csstools"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@csstools/color-helpers": "^6.0.2",
|
|
||||||
"@csstools/css-calc": "^3.2.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=20.19.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@csstools/css-parser-algorithms": "^4.0.0",
|
|
||||||
"@csstools/css-tokenizer": "^4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@csstools/css-parser-algorithms": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/csstools"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/csstools"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=20.19.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@csstools/css-tokenizer": "^4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@csstools/css-syntax-patches-for-csstree": {
|
|
||||||
"version": "1.1.3",
|
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/csstools"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/csstools"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT-0",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"peerDependencies": {
|
|
||||||
"css-tree": "^3.2.1"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"css-tree": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@csstools/css-tokenizer": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/csstools"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/csstools"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=20.19.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@emnapi/core": {
|
"node_modules/@emnapi/core": {
|
||||||
"version": "1.10.0",
|
"version": "1.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
|
||||||
@@ -301,24 +93,6 @@
|
|||||||
"tslib": "^2.4.0"
|
"tslib": "^2.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@exodus/bytes": {
|
|
||||||
"version": "1.15.0",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@noble/hashes": "^1.8.0 || ^2.0.0"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"@noble/hashes": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@floating-ui/core": {
|
"node_modules/@floating-ui/core": {
|
||||||
"version": "1.7.5",
|
"version": "1.7.5",
|
||||||
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz",
|
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz",
|
||||||
@@ -2408,16 +2182,6 @@
|
|||||||
"url": "https://opencollective.com/vitest"
|
"url": "https://opencollective.com/vitest"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/agent-base": {
|
|
||||||
"version": "7.1.4",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/any-promise": {
|
"node_modules/any-promise": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -2553,16 +2317,6 @@
|
|||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/bidi-js": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"require-from-string": "^2.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/binary-extensions": {
|
"node_modules/binary-extensions": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -2758,20 +2512,6 @@
|
|||||||
"url": "https://opencollective.com/express"
|
"url": "https://opencollective.com/express"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/css-tree": {
|
|
||||||
"version": "3.2.1",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"mdn-data": "2.27.1",
|
|
||||||
"source-map-js": "^1.2.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/cssesc": {
|
"node_modules/cssesc": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -2783,41 +2523,11 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cssstyle": {
|
|
||||||
"version": "6.2.0",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@asamuzakjp/css-color": "^5.0.1",
|
|
||||||
"@csstools/css-syntax-patches-for-csstree": "^1.0.28",
|
|
||||||
"css-tree": "^3.1.0",
|
|
||||||
"lru-cache": "^11.2.6"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=20"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/csstype": {
|
"node_modules/csstype": {
|
||||||
"version": "3.2.3",
|
"version": "3.2.3",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/data-urls": {
|
|
||||||
"version": "7.0.0",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"whatwg-mimetype": "^5.0.0",
|
|
||||||
"whatwg-url": "^16.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.4.3",
|
"version": "4.4.3",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -2833,13 +2543,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/decimal.js": {
|
|
||||||
"version": "10.6.0",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true
|
|
||||||
},
|
|
||||||
"node_modules/delayed-stream": {
|
"node_modules/delayed-stream": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -2890,19 +2593,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/entities": {
|
|
||||||
"version": "8.0.0",
|
|
||||||
"dev": true,
|
|
||||||
"license": "BSD-2-Clause",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=20.19.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/es-define-property": {
|
"node_modules/es-define-property": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -3182,47 +2872,6 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/html-encoding-sniffer": {
|
|
||||||
"version": "6.0.0",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@exodus/bytes": "^1.6.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/http-proxy-agent": {
|
|
||||||
"version": "7.0.2",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"agent-base": "^7.1.0",
|
|
||||||
"debug": "^4.3.4"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/https-proxy-agent": {
|
|
||||||
"version": "7.0.6",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"agent-base": "^7.1.2",
|
|
||||||
"debug": "4"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/is-binary-path": {
|
"node_modules/is-binary-path": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -3275,13 +2924,6 @@
|
|||||||
"node": ">=0.12.0"
|
"node": ">=0.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/is-potential-custom-element-name": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true
|
|
||||||
},
|
|
||||||
"node_modules/jiti": {
|
"node_modules/jiti": {
|
||||||
"version": "1.21.7",
|
"version": "1.21.7",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -3290,47 +2932,6 @@
|
|||||||
"jiti": "bin/jiti.js"
|
"jiti": "bin/jiti.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jsdom": {
|
|
||||||
"version": "28.1.0",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@acemir/cssom": "^0.9.31",
|
|
||||||
"@asamuzakjp/dom-selector": "^6.8.1",
|
|
||||||
"@bramus/specificity": "^2.4.2",
|
|
||||||
"@exodus/bytes": "^1.11.0",
|
|
||||||
"cssstyle": "^6.0.1",
|
|
||||||
"data-urls": "^7.0.0",
|
|
||||||
"decimal.js": "^10.6.0",
|
|
||||||
"html-encoding-sniffer": "^6.0.0",
|
|
||||||
"http-proxy-agent": "^7.0.2",
|
|
||||||
"https-proxy-agent": "^7.0.6",
|
|
||||||
"is-potential-custom-element-name": "^1.0.1",
|
|
||||||
"parse5": "^8.0.0",
|
|
||||||
"saxes": "^6.0.0",
|
|
||||||
"symbol-tree": "^3.2.4",
|
|
||||||
"tough-cookie": "^6.0.0",
|
|
||||||
"undici": "^7.21.0",
|
|
||||||
"w3c-xmlserializer": "^5.0.0",
|
|
||||||
"webidl-conversions": "^8.0.1",
|
|
||||||
"whatwg-mimetype": "^5.0.0",
|
|
||||||
"whatwg-url": "^16.0.0",
|
|
||||||
"xml-name-validator": "^5.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"canvas": "^3.0.0"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"canvas": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/jwt-decode": {
|
"node_modules/jwt-decode": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -3366,6 +2967,159 @@
|
|||||||
"lightningcss-win32-x64-msvc": "1.32.0"
|
"lightningcss-win32-x64-msvc": "1.32.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lightningcss-android-arm64": {
|
||||||
|
"version": "1.32.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",
|
||||||
|
"integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MPL-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lightningcss-darwin-arm64": {
|
||||||
|
"version": "1.32.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
|
||||||
|
"integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MPL-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lightningcss-darwin-x64": {
|
||||||
|
"version": "1.32.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",
|
||||||
|
"integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MPL-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lightningcss-freebsd-x64": {
|
||||||
|
"version": "1.32.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",
|
||||||
|
"integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MPL-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"freebsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lightningcss-linux-arm-gnueabihf": {
|
||||||
|
"version": "1.32.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",
|
||||||
|
"integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MPL-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lightningcss-linux-arm64-gnu": {
|
||||||
|
"version": "1.32.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",
|
||||||
|
"integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"libc": [
|
||||||
|
"glibc"
|
||||||
|
],
|
||||||
|
"license": "MPL-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lightningcss-linux-arm64-musl": {
|
||||||
|
"version": "1.32.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",
|
||||||
|
"integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"libc": [
|
||||||
|
"musl"
|
||||||
|
],
|
||||||
|
"license": "MPL-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/lightningcss-linux-x64-gnu": {
|
"node_modules/lightningcss-linux-x64-gnu": {
|
||||||
"version": "1.32.0",
|
"version": "1.32.0",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
@@ -3404,6 +3158,48 @@
|
|||||||
"url": "https://opencollective.com/parcel"
|
"url": "https://opencollective.com/parcel"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lightningcss-win32-arm64-msvc": {
|
||||||
|
"version": "1.32.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",
|
||||||
|
"integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MPL-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lightningcss-win32-x64-msvc": {
|
||||||
|
"version": "1.32.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
|
||||||
|
"integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MPL-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/lilconfig": {
|
"node_modules/lilconfig": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -3420,16 +3216,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/lru-cache": {
|
|
||||||
"version": "11.3.6",
|
|
||||||
"dev": true,
|
|
||||||
"license": "BlueOak-1.0.0",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": "20 || >=22"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/lucide-react": {
|
"node_modules/lucide-react": {
|
||||||
"version": "1.16.0",
|
"version": "1.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.16.0.tgz",
|
||||||
@@ -3456,13 +3242,6 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mdn-data": {
|
|
||||||
"version": "2.27.1",
|
|
||||||
"dev": true,
|
|
||||||
"license": "CC0-1.0",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true
|
|
||||||
},
|
|
||||||
"node_modules/merge2": {
|
"node_modules/merge2": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -3583,19 +3362,6 @@
|
|||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/parse5": {
|
|
||||||
"version": "8.0.1",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"entities": "^8.0.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/inikulin/parse5?sponsor=1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/path-parse": {
|
"node_modules/path-parse": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -3832,16 +3598,6 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/punycode": {
|
|
||||||
"version": "2.3.1",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/queue-microtask": {
|
"node_modules/queue-microtask": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -4037,16 +3793,6 @@
|
|||||||
"node": ">=8.10.0"
|
"node": ">=8.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/require-from-string": {
|
|
||||||
"version": "2.0.2",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/resolve": {
|
"node_modules/resolve": {
|
||||||
"version": "1.22.11",
|
"version": "1.22.11",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -4138,19 +3884,6 @@
|
|||||||
"queue-microtask": "^1.2.2"
|
"queue-microtask": "^1.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/saxes": {
|
|
||||||
"version": "6.0.0",
|
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"xmlchars": "^2.2.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=v12.22.7"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/scheduler": {
|
"node_modules/scheduler": {
|
||||||
"version": "0.27.0",
|
"version": "0.27.0",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
@@ -4216,13 +3949,6 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/symbol-tree": {
|
|
||||||
"version": "3.2.4",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true
|
|
||||||
},
|
|
||||||
"node_modules/tailwind-merge": {
|
"node_modules/tailwind-merge": {
|
||||||
"version": "3.6.0",
|
"version": "3.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz",
|
||||||
@@ -4365,26 +4091,6 @@
|
|||||||
"node": ">=14.0.0"
|
"node": ">=14.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tldts": {
|
|
||||||
"version": "7.0.30",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"tldts-core": "^7.0.30"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"tldts": "bin/cli.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/tldts-core": {
|
|
||||||
"version": "7.0.30",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true
|
|
||||||
},
|
|
||||||
"node_modules/to-regex-range": {
|
"node_modules/to-regex-range": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -4396,32 +4102,6 @@
|
|||||||
"node": ">=8.0"
|
"node": ">=8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tough-cookie": {
|
|
||||||
"version": "6.0.1",
|
|
||||||
"dev": true,
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"tldts": "^7.0.5"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=16"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/tr46": {
|
|
||||||
"version": "6.0.0",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"punycode": "^2.3.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=20"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/ts-interface-checker": {
|
"node_modules/ts-interface-checker": {
|
||||||
"version": "0.1.13",
|
"version": "0.1.13",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -4447,16 +4127,6 @@
|
|||||||
"node": ">=14.17"
|
"node": ">=14.17"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici": {
|
|
||||||
"version": "7.25.0",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=20.18.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "7.24.6",
|
"version": "7.24.6",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
|
||||||
@@ -4755,54 +4425,6 @@
|
|||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/w3c-xmlserializer": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"xml-name-validator": "^5.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/webidl-conversions": {
|
|
||||||
"version": "8.0.1",
|
|
||||||
"dev": true,
|
|
||||||
"license": "BSD-2-Clause",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=20"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/whatwg-mimetype": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=20"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/whatwg-url": {
|
|
||||||
"version": "16.0.1",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@exodus/bytes": "^1.11.0",
|
|
||||||
"tr46": "^6.0.0",
|
|
||||||
"webidl-conversions": "^8.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/why-is-node-running": {
|
"node_modules/why-is-node-running": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -4818,23 +4440,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/xml-name-validator": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"dev": true,
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/xmlchars": {
|
|
||||||
"version": "2.2.0",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true
|
|
||||||
},
|
|
||||||
"node_modules/zod": {
|
"node_modules/zod": {
|
||||||
"version": "4.4.3",
|
"version": "4.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import ClientDetailsPage from "../features/clients/ClientDetailsPage";
|
|||||||
import ClientGeneralPage from "../features/clients/ClientGeneralPage";
|
import ClientGeneralPage from "../features/clients/ClientGeneralPage";
|
||||||
import ClientRelationsPage from "../features/clients/ClientRelationsPage";
|
import ClientRelationsPage from "../features/clients/ClientRelationsPage";
|
||||||
import ClientsPage from "../features/clients/ClientsPage";
|
import ClientsPage from "../features/clients/ClientsPage";
|
||||||
import GlobalOverviewPage from "../features/overview/GlobalOverviewPage";
|
|
||||||
import DeveloperRequestPage from "../features/developer-request/DeveloperRequestPage";
|
import DeveloperRequestPage from "../features/developer-request/DeveloperRequestPage";
|
||||||
|
import GlobalOverviewPage from "../features/overview/GlobalOverviewPage";
|
||||||
import ProfilePage from "../features/profile/ProfilePage";
|
import ProfilePage from "../features/profile/ProfilePage";
|
||||||
import { DEVFRONT_AUTH_CALLBACK_PATH } from "../lib/authConfig";
|
import { DEVFRONT_AUTH_CALLBACK_PATH } from "../lib/authConfig";
|
||||||
|
|
||||||
|
|||||||
@@ -15,13 +15,13 @@ import { useAuth } from "react-oidc-context";
|
|||||||
import { NavLink, Outlet, useLocation, useNavigate } from "react-router-dom";
|
import { NavLink, Outlet, useLocation, useNavigate } from "react-router-dom";
|
||||||
import {
|
import {
|
||||||
AppSidebar,
|
AppSidebar,
|
||||||
|
type ShellSidebarNavItem,
|
||||||
type ShellTranslator,
|
type ShellTranslator,
|
||||||
applyShellTheme,
|
applyShellTheme,
|
||||||
buildShellProfileSummary,
|
buildShellProfileSummary,
|
||||||
buildShellSessionStatus,
|
buildShellSessionStatus,
|
||||||
readShellSessionExpiryEnabled,
|
readShellSessionExpiryEnabled,
|
||||||
readShellTheme,
|
readShellTheme,
|
||||||
type ShellSidebarNavItem,
|
|
||||||
shellLayoutClasses,
|
shellLayoutClasses,
|
||||||
writeShellSessionExpiryEnabled,
|
writeShellSessionExpiryEnabled,
|
||||||
} from "../../../../common/shell";
|
} from "../../../../common/shell";
|
||||||
|
|||||||
@@ -2,17 +2,20 @@ import { useInfiniteQuery } from "@tanstack/react-query";
|
|||||||
import type { AxiosError } from "axios";
|
import type { AxiosError } from "axios";
|
||||||
import { Download, RefreshCw, Search } from "lucide-react";
|
import { Download, RefreshCw, Search } from "lucide-react";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
import { parseAuditDetails } from "../../../../common/core/audit";
|
||||||
|
import { AuditLogTable } from "../../../../common/core/components/audit";
|
||||||
|
import { PageHeader } from "../../../../common/core/components/page";
|
||||||
|
import { SearchFilterBar } from "../../../../common/ui/search-filter-bar";
|
||||||
import { ForbiddenMessage } from "../../components/common/ForbiddenMessage";
|
import { ForbiddenMessage } from "../../components/common/ForbiddenMessage";
|
||||||
import { Badge } from "../../components/ui/badge";
|
import { Badge } from "../../components/ui/badge";
|
||||||
import { Button } from "../../components/ui/button";
|
import { Button } from "../../components/ui/button";
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "../../components/ui/card";
|
|
||||||
import { Input } from "../../components/ui/input";
|
|
||||||
import {
|
import {
|
||||||
parseAuditDetails,
|
Card,
|
||||||
} from "../../../../common/core/audit";
|
CardContent,
|
||||||
import { AuditLogTable } from "../../../../common/core/components/audit";
|
CardHeader,
|
||||||
import { SearchFilterBar } from "../../../../common/ui/search-filter-bar";
|
CardTitle,
|
||||||
import { PageHeader } from "../../../../common/core/components/page";
|
} from "../../components/ui/card";
|
||||||
|
import { Input } from "../../components/ui/input";
|
||||||
import type { DevAuditLog } from "../../lib/devApi";
|
import type { DevAuditLog } from "../../lib/devApi";
|
||||||
import { fetchDevAuditLogs } from "../../lib/devApi";
|
import { fetchDevAuditLogs } from "../../lib/devApi";
|
||||||
import { t } from "../../lib/i18n";
|
import { t } from "../../lib/i18n";
|
||||||
|
|||||||
@@ -4,19 +4,19 @@ import { BookOpenText, Filter, Plus, Search, X } from "lucide-react";
|
|||||||
import { useEffect, useMemo, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { useAuth } from "react-oidc-context";
|
import { useAuth } from "react-oidc-context";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
|
import { PageHeader } from "../../../../common/core/components/page";
|
||||||
import {
|
import {
|
||||||
SortableTableHead,
|
SortableTableHead,
|
||||||
sortableTableHeadBaseClassName,
|
sortableTableHeadBaseClassName,
|
||||||
sortableTableHeaderClassName,
|
sortableTableHeaderClassName,
|
||||||
} from "../../../../common/core/components/sort";
|
} from "../../../../common/core/components/sort";
|
||||||
import { SearchFilterBar } from "../../../../common/ui/search-filter-bar";
|
|
||||||
import { PageHeader } from "../../../../common/core/components/page";
|
|
||||||
import {
|
import {
|
||||||
type SortConfig,
|
type SortConfig,
|
||||||
type SortResolverMap,
|
type SortResolverMap,
|
||||||
sortItems,
|
sortItems,
|
||||||
toggleSort,
|
toggleSort,
|
||||||
} from "../../../../common/core/utils";
|
} from "../../../../common/core/utils";
|
||||||
|
import { SearchFilterBar } from "../../../../common/ui/search-filter-bar";
|
||||||
import {
|
import {
|
||||||
commonTableShellClass,
|
commonTableShellClass,
|
||||||
commonTableViewportClass,
|
commonTableViewportClass,
|
||||||
@@ -330,61 +330,59 @@ function ClientsPage() {
|
|||||||
}
|
}
|
||||||
advancedOpen={isAdvancedFilterOpen}
|
advancedOpen={isAdvancedFilterOpen}
|
||||||
advanced={
|
advanced={
|
||||||
<>
|
<div className="flex flex-wrap items-center gap-6">
|
||||||
<div className="flex flex-wrap items-center gap-6">
|
<div className="flex items-center gap-2">
|
||||||
<div className="flex items-center gap-2">
|
<span className="text-xs font-bold uppercase tracking-wider text-muted-foreground whitespace-nowrap">
|
||||||
<span className="text-xs font-bold uppercase tracking-wider text-muted-foreground whitespace-nowrap">
|
{t("ui.dev.clients.filter.type_label", "Type:")}
|
||||||
{t("ui.dev.clients.filter.type_label", "Type:")}
|
</span>
|
||||||
</span>
|
<select
|
||||||
<select
|
className="h-9 min-w-[140px] rounded-md border border-input bg-background px-3 text-sm focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary/30"
|
||||||
className="h-9 min-w-[140px] rounded-md border border-input bg-background px-3 text-sm focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary/30"
|
value={typeFilter}
|
||||||
value={typeFilter}
|
onChange={(e) => setTypeFilter(e.target.value)}
|
||||||
onChange={(e) => setTypeFilter(e.target.value)}
|
|
||||||
>
|
|
||||||
<option value="all">
|
|
||||||
{t("ui.dev.clients.filter.type_all", "모든 유형")}
|
|
||||||
</option>
|
|
||||||
<option value="private">
|
|
||||||
{t("ui.dev.clients.type.private", "Server side App")}
|
|
||||||
</option>
|
|
||||||
<option value="pkce">
|
|
||||||
{t("ui.dev.clients.type.pkce", "PKCE")}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<span className="text-xs font-bold uppercase tracking-wider text-muted-foreground whitespace-nowrap">
|
|
||||||
{t("ui.dev.clients.consents.status_label", "Status:")}
|
|
||||||
</span>
|
|
||||||
<select
|
|
||||||
className="h-9 min-w-[140px] rounded-md border border-input bg-background px-3 text-sm focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary/30"
|
|
||||||
value={statusFilter}
|
|
||||||
onChange={(e) => setStatusFilter(e.target.value)}
|
|
||||||
>
|
|
||||||
<option value="all">
|
|
||||||
{t("ui.dev.clients.filter.status_all", "모든 상태")}
|
|
||||||
</option>
|
|
||||||
<option value="active">
|
|
||||||
{t("ui.common.status.active", "Active")}
|
|
||||||
</option>
|
|
||||||
<option value="inactive">
|
|
||||||
{t("ui.common.status.inactive", "Inactive")}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="sm"
|
|
||||||
className="ml-auto text-xs text-muted-foreground"
|
|
||||||
onClick={() => {
|
|
||||||
setTypeFilter("all");
|
|
||||||
setStatusFilter("all");
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{t("ui.common.reset", "초기화")}
|
<option value="all">
|
||||||
</Button>
|
{t("ui.dev.clients.filter.type_all", "모든 유형")}
|
||||||
|
</option>
|
||||||
|
<option value="private">
|
||||||
|
{t("ui.dev.clients.type.private", "Server side App")}
|
||||||
|
</option>
|
||||||
|
<option value="pkce">
|
||||||
|
{t("ui.dev.clients.type.pkce", "PKCE")}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</>
|
<div className="flex items-center gap-2">
|
||||||
|
<span className="text-xs font-bold uppercase tracking-wider text-muted-foreground whitespace-nowrap">
|
||||||
|
{t("ui.dev.clients.consents.status_label", "Status:")}
|
||||||
|
</span>
|
||||||
|
<select
|
||||||
|
className="h-9 min-w-[140px] rounded-md border border-input bg-background px-3 text-sm focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary/30"
|
||||||
|
value={statusFilter}
|
||||||
|
onChange={(e) => setStatusFilter(e.target.value)}
|
||||||
|
>
|
||||||
|
<option value="all">
|
||||||
|
{t("ui.dev.clients.filter.status_all", "모든 상태")}
|
||||||
|
</option>
|
||||||
|
<option value="active">
|
||||||
|
{t("ui.common.status.active", "Active")}
|
||||||
|
</option>
|
||||||
|
<option value="inactive">
|
||||||
|
{t("ui.common.status.inactive", "Inactive")}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
className="ml-auto text-xs text-muted-foreground"
|
||||||
|
onClick={() => {
|
||||||
|
setTypeFilter("all");
|
||||||
|
setStatusFilter("all");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t("ui.common.reset", "초기화")}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|||||||
@@ -9,6 +9,12 @@ import {
|
|||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useAuth } from "react-oidc-context";
|
import { useAuth } from "react-oidc-context";
|
||||||
|
import { PageHeader } from "../../../../common/core/components/page";
|
||||||
|
import {
|
||||||
|
commonStickyTableHeaderClass,
|
||||||
|
commonTableShellClass,
|
||||||
|
commonTableViewportClass,
|
||||||
|
} from "../../../../common/ui/table";
|
||||||
import { Badge } from "../../components/ui/badge";
|
import { Badge } from "../../components/ui/badge";
|
||||||
import { Button } from "../../components/ui/button";
|
import { Button } from "../../components/ui/button";
|
||||||
import {
|
import {
|
||||||
@@ -27,12 +33,6 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "../../components/ui/table";
|
} from "../../components/ui/table";
|
||||||
import {
|
|
||||||
commonStickyTableHeaderClass,
|
|
||||||
commonTableShellClass,
|
|
||||||
commonTableViewportClass,
|
|
||||||
} from "../../../../common/ui/table";
|
|
||||||
import { PageHeader } from "../../../../common/core/components/page";
|
|
||||||
import { Textarea } from "../../components/ui/textarea";
|
import { Textarea } from "../../components/ui/textarea";
|
||||||
import {
|
import {
|
||||||
approveDeveloperRequest,
|
approveDeveloperRequest,
|
||||||
@@ -199,7 +199,9 @@ export default function DeveloperRequestPage() {
|
|||||||
{t("ui.dev.request.table.user", "사용자")}
|
{t("ui.dev.request.table.user", "사용자")}
|
||||||
</TableHead>
|
</TableHead>
|
||||||
)}
|
)}
|
||||||
<TableHead>{t("ui.dev.request.table.org", "소속")}</TableHead>
|
<TableHead>
|
||||||
|
{t("ui.dev.request.table.org", "소속")}
|
||||||
|
</TableHead>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
{t("ui.dev.request.table.reason", "신청 사유")}
|
{t("ui.dev.request.table.reason", "신청 사유")}
|
||||||
</TableHead>
|
</TableHead>
|
||||||
@@ -237,7 +239,9 @@ export default function DeveloperRequestPage() {
|
|||||||
</div>
|
</div>
|
||||||
{(req.phone || req.role) && (
|
{(req.phone || req.role) && (
|
||||||
<div className="mt-1 text-xs text-muted-foreground">
|
<div className="mt-1 text-xs text-muted-foreground">
|
||||||
{[req.phone, req.role].filter(Boolean).join(" / ")}
|
{[req.phone, req.role]
|
||||||
|
.filter(Boolean)
|
||||||
|
.join(" / ")}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
@@ -323,7 +327,10 @@ export default function DeveloperRequestPage() {
|
|||||||
disabled={isActionPending}
|
disabled={isActionPending}
|
||||||
>
|
>
|
||||||
<XCircle className="mr-1 h-3 w-3" />
|
<XCircle className="mr-1 h-3 w-3" />
|
||||||
{t("ui.dev.request.cancel_approval", "승인 취소")}
|
{t(
|
||||||
|
"ui.dev.request.cancel_approval",
|
||||||
|
"승인 취소",
|
||||||
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ import {
|
|||||||
import { useMemo, useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
import { useAuth } from "react-oidc-context";
|
import { useAuth } from "react-oidc-context";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import {
|
||||||
|
OverviewAxisNotes,
|
||||||
|
OverviewMetric,
|
||||||
|
OverviewSelectionChips,
|
||||||
|
} from "../../../../common/core/components/overview";
|
||||||
import {
|
import {
|
||||||
type ClientSummary,
|
type ClientSummary,
|
||||||
type RPUsageDailyMetric,
|
type RPUsageDailyMetric,
|
||||||
@@ -22,11 +27,6 @@ import {
|
|||||||
} from "../../lib/devApi";
|
} from "../../lib/devApi";
|
||||||
import { t } from "../../lib/i18n";
|
import { t } from "../../lib/i18n";
|
||||||
import { resolveProfileRole } from "../../lib/role";
|
import { resolveProfileRole } from "../../lib/role";
|
||||||
import {
|
|
||||||
OverviewAxisNotes,
|
|
||||||
OverviewMetric,
|
|
||||||
OverviewSelectionChips,
|
|
||||||
} from "../../../../common/core/components/overview";
|
|
||||||
|
|
||||||
type ClientDistribution = {
|
type ClientDistribution = {
|
||||||
activeClients: number;
|
activeClients: number;
|
||||||
|
|||||||
@@ -1,13 +1,18 @@
|
|||||||
import { defineConfig, mergeConfig } from "vite";
|
import { defineConfig, mergeConfig } from "vite";
|
||||||
import { commonViteConfig, getAllowedHosts } from "../common/config/vite.base";
|
import {
|
||||||
|
commonViteConfig,
|
||||||
|
getAllowedHosts,
|
||||||
|
hostFromUrl,
|
||||||
|
} from "../common/config/vite.base";
|
||||||
|
|
||||||
const buildOutDir =
|
const buildOutDir =
|
||||||
process.env.DEVFRONT_BUILD_OUT_DIR ?? "/tmp/baron-sso-devfront-dist";
|
process.env.DEVFRONT_BUILD_OUT_DIR ?? "/tmp/baron-sso-devfront-dist";
|
||||||
|
const devfrontHost = hostFromUrl(process.env.DEVFRONT_URL);
|
||||||
|
|
||||||
const allowedHosts = getAllowedHosts(
|
const allowedHosts = getAllowedHosts(
|
||||||
["sdev.hmac.kr", "localhost", "172.16.10.176", "127.0.0.1"],
|
["sdev.hmac.kr", "localhost", "172.16.10.176", "127.0.0.1"],
|
||||||
process.env.DEVFRONT_URL,
|
devfrontHost,
|
||||||
process.env.DEVFRONT_ALLOWED_HOSTS
|
process.env.DEVFRONT_ALLOWED_HOSTS,
|
||||||
);
|
);
|
||||||
|
|
||||||
export default defineConfig(
|
export default defineConfig(
|
||||||
@@ -39,5 +44,5 @@ export default defineConfig(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,8 +1,18 @@
|
|||||||
|
import { fileURLToPath } from "node:url";
|
||||||
import react from "@vitejs/plugin-react";
|
import react from "@vitejs/plugin-react";
|
||||||
import { defineConfig } from "vitest/config";
|
import { defineConfig } from "vitest/config";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
|
server: {
|
||||||
|
fs: {
|
||||||
|
allow: [
|
||||||
|
fileURLToPath(new URL(".", import.meta.url)),
|
||||||
|
fileURLToPath(new URL("../common", import.meta.url)),
|
||||||
|
"/workspace/common",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
test: {
|
test: {
|
||||||
globals: true,
|
globals: true,
|
||||||
environment: "jsdom",
|
environment: "jsdom",
|
||||||
|
|||||||
@@ -218,6 +218,9 @@ local_picker_description = "Select the tenant to use as the parent from the tena
|
|||||||
local_picker_empty = "No selectable tenants are available."
|
local_picker_empty = "No selectable tenants are available."
|
||||||
picker_description = "Select a tenant in org-chart to apply it as the parent tenant."
|
picker_description = "Select a tenant in org-chart to apply it as the parent tenant."
|
||||||
|
|
||||||
|
[msg.admin.tenants.scope]
|
||||||
|
description = "Select a parent tenant to filter the list to its descendants."
|
||||||
|
|
||||||
[msg.admin.tenants.admins]
|
[msg.admin.tenants.admins]
|
||||||
add_success = "Tenant admin added successfully."
|
add_success = "Tenant admin added successfully."
|
||||||
empty = "No tenant admins are assigned yet."
|
empty = "No tenant admins are assigned yet."
|
||||||
@@ -1153,6 +1156,12 @@ view_org_chart = "View Full Org Chart"
|
|||||||
[ui.admin.tenants.view]
|
[ui.admin.tenants.view]
|
||||||
hierarchy = "Hierarchy"
|
hierarchy = "Hierarchy"
|
||||||
list = "List"
|
list = "List"
|
||||||
|
table = "Table"
|
||||||
|
tree = "Tree"
|
||||||
|
|
||||||
|
[ui.admin.tenants.scope]
|
||||||
|
active = "{{name}} descendants"
|
||||||
|
pick = "Select parent scope"
|
||||||
|
|
||||||
[ui.admin.tenants.domain_conflict]
|
[ui.admin.tenants.domain_conflict]
|
||||||
description = ""
|
description = ""
|
||||||
|
|||||||
@@ -125,6 +125,9 @@ local_picker_description = "테넌트 목록에서 상위 테넌트로 사용할
|
|||||||
local_picker_empty = "선택할 수 있는 테넌트가 없습니다."
|
local_picker_empty = "선택할 수 있는 테넌트가 없습니다."
|
||||||
picker_description = "org-chart에서 테넌트를 선택하면 상위 테넌트에 반영됩니다."
|
picker_description = "org-chart에서 테넌트를 선택하면 상위 테넌트에 반영됩니다."
|
||||||
|
|
||||||
|
[msg.admin.tenants.scope]
|
||||||
|
description = "상위 테넌트를 선택하면 해당 하위 테넌트만 목록에 표시합니다."
|
||||||
|
|
||||||
[msg.dev.auth]
|
[msg.dev.auth]
|
||||||
access_denied_description = "DevFront는 관리자 전용 화면입니다. 권한이 필요하면 관리자에게 요청해 주세요."
|
access_denied_description = "DevFront는 관리자 전용 화면입니다. 권한이 필요하면 관리자에게 요청해 주세요."
|
||||||
access_denied_title = "접근 권한이 없습니다."
|
access_denied_title = "접근 권한이 없습니다."
|
||||||
@@ -1639,6 +1642,12 @@ view_org_chart = "전체 조직도 보기"
|
|||||||
[ui.admin.tenants.view]
|
[ui.admin.tenants.view]
|
||||||
hierarchy = "계층 구조"
|
hierarchy = "계층 구조"
|
||||||
list = "평면 목록"
|
list = "평면 목록"
|
||||||
|
table = "평면"
|
||||||
|
tree = "트리"
|
||||||
|
|
||||||
|
[ui.admin.tenants.scope]
|
||||||
|
active = "{{name}} 하위"
|
||||||
|
pick = "상위 범위 선택"
|
||||||
|
|
||||||
[ui.admin.tenants.admins]
|
[ui.admin.tenants.admins]
|
||||||
add_button = "관리자 추가"
|
add_button = "관리자 추가"
|
||||||
|
|||||||
@@ -1505,6 +1505,12 @@ export = ""
|
|||||||
[ui.admin.tenants.view]
|
[ui.admin.tenants.view]
|
||||||
hierarchy = ""
|
hierarchy = ""
|
||||||
list = ""
|
list = ""
|
||||||
|
table = ""
|
||||||
|
tree = ""
|
||||||
|
|
||||||
|
[ui.admin.tenants.scope]
|
||||||
|
active = ""
|
||||||
|
pick = ""
|
||||||
|
|
||||||
[ui.admin.tenants.admins]
|
[ui.admin.tenants.admins]
|
||||||
add_button = ""
|
add_button = ""
|
||||||
@@ -1625,6 +1631,9 @@ local_picker_description = ""
|
|||||||
local_picker_empty = ""
|
local_picker_empty = ""
|
||||||
picker_description = ""
|
picker_description = ""
|
||||||
|
|
||||||
|
[msg.admin.tenants.scope]
|
||||||
|
description = ""
|
||||||
|
|
||||||
[msg.admin.users]
|
[msg.admin.users]
|
||||||
self_delete_blocked = ""
|
self_delete_blocked = ""
|
||||||
export_error = ""
|
export_error = ""
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
{
|
{
|
||||||
"extends": ["../common/config/biome.base.json"]
|
"extends": ["../common/config/biome.base.json"],
|
||||||
|
"files": {
|
||||||
|
"ignore": [".vite"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1068
orgfront/package-lock.json
generated
1068
orgfront/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,7 @@ import {
|
|||||||
Search,
|
Search,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
import { SearchFilterBar } from "../../../../common/ui/search-filter-bar";
|
||||||
import { ForbiddenMessage } from "../../components/common/ForbiddenMessage";
|
import { ForbiddenMessage } from "../../components/common/ForbiddenMessage";
|
||||||
import { Badge } from "../../components/ui/badge";
|
import { Badge } from "../../components/ui/badge";
|
||||||
import { Button } from "../../components/ui/button";
|
import { Button } from "../../components/ui/button";
|
||||||
@@ -28,7 +29,6 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "../../components/ui/table";
|
} from "../../components/ui/table";
|
||||||
import { SearchFilterBar } from "../../../../common/ui/search-filter-bar";
|
|
||||||
import type { DevAuditLog } from "../../lib/devApi";
|
import type { DevAuditLog } from "../../lib/devApi";
|
||||||
import { fetchDevAuditLogs } from "../../lib/devApi";
|
import { fetchDevAuditLogs } from "../../lib/devApi";
|
||||||
import { t } from "../../lib/i18n";
|
import { t } from "../../lib/i18n";
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Link, useParams } from "react-router-dom";
|
import { Link, useParams } from "react-router-dom";
|
||||||
|
import { SearchFilterBar } from "../../../../common/ui/search-filter-bar";
|
||||||
import { Badge } from "../../components/ui/badge";
|
import { Badge } from "../../components/ui/badge";
|
||||||
import { Button } from "../../components/ui/button";
|
import { Button } from "../../components/ui/button";
|
||||||
import {
|
import {
|
||||||
@@ -26,7 +27,6 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "../../components/ui/table";
|
} from "../../components/ui/table";
|
||||||
import { SearchFilterBar } from "../../../../common/ui/search-filter-bar";
|
|
||||||
import { fetchClient, fetchConsents, revokeConsent } from "../../lib/devApi";
|
import { fetchClient, fetchConsents, revokeConsent } from "../../lib/devApi";
|
||||||
import { t } from "../../lib/i18n";
|
import { t } from "../../lib/i18n";
|
||||||
import { cn } from "../../lib/utils";
|
import { cn } from "../../lib/utils";
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useAuth } from "react-oidc-context";
|
import { useAuth } from "react-oidc-context";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
|
import { SearchFilterBar } from "../../../../common/ui/search-filter-bar";
|
||||||
import { ForbiddenMessage } from "../../components/common/ForbiddenMessage";
|
import { ForbiddenMessage } from "../../components/common/ForbiddenMessage";
|
||||||
import {
|
import {
|
||||||
Avatar,
|
Avatar,
|
||||||
@@ -36,7 +37,6 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "../../components/ui/table";
|
} from "../../components/ui/table";
|
||||||
import { SearchFilterBar } from "../../../../common/ui/search-filter-bar";
|
|
||||||
import { fetchClients, fetchDevStats } from "../../lib/devApi";
|
import { fetchClients, fetchDevStats } from "../../lib/devApi";
|
||||||
import { t } from "../../lib/i18n";
|
import { t } from "../../lib/i18n";
|
||||||
import { cn } from "../../lib/utils";
|
import { cn } from "../../lib/utils";
|
||||||
@@ -228,61 +228,59 @@ function ClientsPage() {
|
|||||||
}
|
}
|
||||||
advancedOpen={isAdvancedFilterOpen}
|
advancedOpen={isAdvancedFilterOpen}
|
||||||
advanced={
|
advanced={
|
||||||
<>
|
<div className="flex flex-wrap items-center gap-6">
|
||||||
<div className="flex flex-wrap items-center gap-6">
|
<div className="flex items-center gap-2">
|
||||||
<div className="flex items-center gap-2">
|
<span className="text-xs font-bold uppercase tracking-wider text-muted-foreground whitespace-nowrap">
|
||||||
<span className="text-xs font-bold uppercase tracking-wider text-muted-foreground whitespace-nowrap">
|
{t("ui.dev.clients.filter.type_label", "Type:")}
|
||||||
{t("ui.dev.clients.filter.type_label", "Type:")}
|
</span>
|
||||||
</span>
|
<select
|
||||||
<select
|
className="h-9 min-w-[140px] rounded-md border border-input bg-background px-3 text-sm focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary/30"
|
||||||
className="h-9 min-w-[140px] rounded-md border border-input bg-background px-3 text-sm focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary/30"
|
value={typeFilter}
|
||||||
value={typeFilter}
|
onChange={(e) => setTypeFilter(e.target.value)}
|
||||||
onChange={(e) => setTypeFilter(e.target.value)}
|
|
||||||
>
|
|
||||||
<option value="all">
|
|
||||||
{t("ui.dev.clients.filter.type_all", "모든 유형")}
|
|
||||||
</option>
|
|
||||||
<option value="private">
|
|
||||||
{t("ui.dev.clients.type.private", "Server side App")}
|
|
||||||
</option>
|
|
||||||
<option value="pkce">
|
|
||||||
{t("ui.dev.clients.type.pkce", "PKCE")}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<span className="text-xs font-bold uppercase tracking-wider text-muted-foreground whitespace-nowrap">
|
|
||||||
{t("ui.dev.clients.consents.status_label", "Status:")}
|
|
||||||
</span>
|
|
||||||
<select
|
|
||||||
className="h-9 min-w-[140px] rounded-md border border-input bg-background px-3 text-sm focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary/30"
|
|
||||||
value={statusFilter}
|
|
||||||
onChange={(e) => setStatusFilter(e.target.value)}
|
|
||||||
>
|
|
||||||
<option value="all">
|
|
||||||
{t("ui.dev.clients.filter.status_all", "모든 상태")}
|
|
||||||
</option>
|
|
||||||
<option value="active">
|
|
||||||
{t("ui.common.status.active", "Active")}
|
|
||||||
</option>
|
|
||||||
<option value="inactive">
|
|
||||||
{t("ui.common.status.inactive", "Inactive")}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="sm"
|
|
||||||
className="ml-auto text-xs text-muted-foreground"
|
|
||||||
onClick={() => {
|
|
||||||
setTypeFilter("all");
|
|
||||||
setStatusFilter("all");
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{t("ui.common.reset", "초기화")}
|
<option value="all">
|
||||||
</Button>
|
{t("ui.dev.clients.filter.type_all", "모든 유형")}
|
||||||
|
</option>
|
||||||
|
<option value="private">
|
||||||
|
{t("ui.dev.clients.type.private", "Server side App")}
|
||||||
|
</option>
|
||||||
|
<option value="pkce">
|
||||||
|
{t("ui.dev.clients.type.pkce", "PKCE")}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</>
|
<div className="flex items-center gap-2">
|
||||||
|
<span className="text-xs font-bold uppercase tracking-wider text-muted-foreground whitespace-nowrap">
|
||||||
|
{t("ui.dev.clients.consents.status_label", "Status:")}
|
||||||
|
</span>
|
||||||
|
<select
|
||||||
|
className="h-9 min-w-[140px] rounded-md border border-input bg-background px-3 text-sm focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary/30"
|
||||||
|
value={statusFilter}
|
||||||
|
onChange={(e) => setStatusFilter(e.target.value)}
|
||||||
|
>
|
||||||
|
<option value="all">
|
||||||
|
{t("ui.dev.clients.filter.status_all", "모든 상태")}
|
||||||
|
</option>
|
||||||
|
<option value="active">
|
||||||
|
{t("ui.common.status.active", "Active")}
|
||||||
|
</option>
|
||||||
|
<option value="inactive">
|
||||||
|
{t("ui.common.status.inactive", "Inactive")}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
className="ml-auto text-xs text-muted-foreground"
|
||||||
|
onClick={() => {
|
||||||
|
setTypeFilter("all");
|
||||||
|
setStatusFilter("all");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t("ui.common.reset", "초기화")}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|||||||
@@ -345,7 +345,8 @@ describe("org chart layout", () => {
|
|||||||
|
|
||||||
it("keeps zoom limits wide enough for large SVG organization charts", () => {
|
it("keeps zoom limits wide enough for large SVG organization charts", () => {
|
||||||
expect(clampScale(0.08)).toBe(0.08);
|
expect(clampScale(0.08)).toBe(0.08);
|
||||||
expect(clampScale(5)).toBe(5);
|
expect(clampScale(32)).toBe(32);
|
||||||
|
expect(clampScale(64)).toBe(32);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("switches semantic zoom modes from overview to detail", () => {
|
it("switches semantic zoom modes from overview to detail", () => {
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ const WIDE_ASPECT_RATIO = MAX_TARGET_ASPECT_RATIO;
|
|||||||
const TALL_ASPECT_RATIO = 0.5;
|
const TALL_ASPECT_RATIO = 0.5;
|
||||||
const CHART_MARGIN = 72;
|
const CHART_MARGIN = 72;
|
||||||
const MIN_SCALE = 0.08;
|
const MIN_SCALE = 0.08;
|
||||||
const MAX_SCALE = 5;
|
const MAX_SCALE = 32;
|
||||||
const ZOOM_SENSITIVITY = 0.0015;
|
const ZOOM_SENSITIVITY = 0.0015;
|
||||||
const FAMILY_FILTER_ID = "hanmac-family";
|
const FAMILY_FILTER_ID = "hanmac-family";
|
||||||
const DEFAULT_LAYOUT_OPTIONS: OrgChartLayoutOptions = {
|
const DEFAULT_LAYOUT_OPTIONS: OrgChartLayoutOptions = {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ const allowedHosts = getAllowedHosts(
|
|||||||
"127.0.0.1",
|
"127.0.0.1",
|
||||||
],
|
],
|
||||||
process.env.ORGFRONT_URL,
|
process.env.ORGFRONT_URL,
|
||||||
process.env.ORGFRONT_ALLOWED_HOSTS
|
process.env.ORGFRONT_ALLOWED_HOSTS,
|
||||||
);
|
);
|
||||||
|
|
||||||
export default defineConfig(
|
export default defineConfig(
|
||||||
@@ -47,5 +47,5 @@ export default defineConfig(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ function resolvePerformanceBudget(projectName: string): {
|
|||||||
if (projectName.includes('mobile')) {
|
if (projectName.includes('mobile')) {
|
||||||
return { coldMs: 3000, warmMs: 1500 };
|
return { coldMs: 3000, warmMs: 1500 };
|
||||||
}
|
}
|
||||||
return { coldMs: 1700, warmMs: 1200 };
|
return { coldMs: 2300, warmMs: 1500 };
|
||||||
}
|
}
|
||||||
|
|
||||||
test.describe('UserFront login performance budget', () => {
|
test.describe('UserFront login performance budget', () => {
|
||||||
|
|||||||
@@ -70,15 +70,17 @@ async function fillAt(page: Page, x: number, y: number, value: string): Promise<
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function openDepartmentEditor(page: Page): Promise<void> {
|
async function openDepartmentEditor(page: Page): Promise<void> {
|
||||||
if (isMobileProject(page)) {
|
const accessibleEditor = page
|
||||||
await enableFlutterAccessibility(page);
|
.getByRole('group', { name: '소속 QA' })
|
||||||
await page
|
.getByRole('button', { name: '편집' });
|
||||||
.getByRole('group', { name: '소속 QA' })
|
if ((await accessibleEditor.count()) > 0) {
|
||||||
.getByRole('button', { name: '편집' })
|
await accessibleEditor.click({ force: true });
|
||||||
.click({ force: true });
|
|
||||||
await page.waitForTimeout(200);
|
await page.waitForTimeout(200);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (isMobileProject(page)) {
|
||||||
|
throw new Error('Department editor accessibility button was not found.');
|
||||||
|
}
|
||||||
const coords = coordsFor(page);
|
const coords = coordsFor(page);
|
||||||
await page.locator('flt-glass-pane').click({
|
await page.locator('flt-glass-pane').click({
|
||||||
position: { x: coords.departmentEditX, y: coords.departmentEditY },
|
position: { x: coords.departmentEditX, y: coords.departmentEditY },
|
||||||
@@ -88,11 +90,15 @@ async function openDepartmentEditor(page: Page): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function blurDepartmentEditor(page: Page): Promise<void> {
|
async function blurDepartmentEditor(page: Page): Promise<void> {
|
||||||
if (isMobileProject(page)) {
|
const textbox = page.getByRole('textbox', { name: '소속' });
|
||||||
await page.getByRole('textbox', { name: '소속' }).blur();
|
if ((await textbox.count()) > 0) {
|
||||||
|
await textbox.blur();
|
||||||
await page.waitForTimeout(250);
|
await page.waitForTimeout(250);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (isMobileProject(page)) {
|
||||||
|
throw new Error('Department textbox was not found.');
|
||||||
|
}
|
||||||
const coords = coordsFor(page);
|
const coords = coordsFor(page);
|
||||||
await page.locator('flt-glass-pane').click({
|
await page.locator('flt-glass-pane').click({
|
||||||
position: { x: coords.blurX, y: coords.blurY },
|
position: { x: coords.blurX, y: coords.blurY },
|
||||||
@@ -102,20 +108,28 @@ async function blurDepartmentEditor(page: Page): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function submitDepartmentEditor(page: Page): Promise<void> {
|
async function submitDepartmentEditor(page: Page): Promise<void> {
|
||||||
if (isMobileProject(page)) {
|
const textbox = page.getByRole('textbox', { name: '소속' });
|
||||||
await page.getByRole('textbox', { name: '소속' }).press('Enter');
|
if ((await textbox.count()) > 0) {
|
||||||
|
await textbox.press('Enter');
|
||||||
await page.waitForTimeout(250);
|
await page.waitForTimeout(250);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (isMobileProject(page)) {
|
||||||
|
throw new Error('Department textbox was not found.');
|
||||||
|
}
|
||||||
await page.keyboard.press('Enter');
|
await page.keyboard.press('Enter');
|
||||||
await page.waitForTimeout(250);
|
await page.waitForTimeout(250);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fillDepartmentField(page: Page, value: string): Promise<void> {
|
async function fillDepartmentField(page: Page, value: string): Promise<void> {
|
||||||
if (isMobileProject(page)) {
|
const textbox = page.getByRole('textbox', { name: '소속' });
|
||||||
await page.getByRole('textbox', { name: '소속' }).fill(value);
|
if ((await textbox.count()) > 0) {
|
||||||
|
await textbox.fill(value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (isMobileProject(page)) {
|
||||||
|
throw new Error('Department textbox was not found.');
|
||||||
|
}
|
||||||
const coords = coordsFor(page);
|
const coords = coordsFor(page);
|
||||||
await fillAt(page, coords.departmentInputX, coords.departmentInputY, value);
|
await fillAt(page, coords.departmentInputX, coords.departmentInputY, value);
|
||||||
}
|
}
|
||||||
@@ -216,6 +230,7 @@ async function mockProfileApis(page: Page, state: ProfileState): Promise<void> {
|
|||||||
async function openProfilePage(page: Page): Promise<void> {
|
async function openProfilePage(page: Page): Promise<void> {
|
||||||
await page.goto('/ko/profile');
|
await page.goto('/ko/profile');
|
||||||
await expect(page).toHaveURL(/\/ko\/profile$/);
|
await expect(page).toHaveURL(/\/ko\/profile$/);
|
||||||
|
await enableFlutterAccessibility(page);
|
||||||
await page.waitForTimeout(1200);
|
await page.waitForTimeout(1200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import 'dart:async';
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart' hide tr;
|
import 'package:easy_localization/easy_localization.dart' hide tr;
|
||||||
@@ -162,20 +161,10 @@ bool _shouldRunStartupSessionRecovery(Uri uri) {
|
|||||||
return !isPublicAuthPath(path, uri);
|
return !isPublicAuthPath(path, uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadRuntimeEnv() async {
|
|
||||||
for (final fileName in const ['assets/.env', '.env']) {
|
|
||||||
try {
|
|
||||||
await dotenv.load(fileName: fileName);
|
|
||||||
return;
|
|
||||||
} catch (_) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
usePathUrlStrategy();
|
usePathUrlStrategy();
|
||||||
await EasyLocalization.ensureInitialized();
|
await EasyLocalization.ensureInitialized();
|
||||||
await _loadRuntimeEnv();
|
|
||||||
LocaleRegistry.primeWithDefaults();
|
LocaleRegistry.primeWithDefaults();
|
||||||
|
|
||||||
// 1. Global Error Handling
|
// 1. Global Error Handling
|
||||||
|
|||||||
@@ -45,10 +45,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: characters
|
name: characters
|
||||||
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.0"
|
version: "1.4.1"
|
||||||
cli_config:
|
cli_config:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -276,14 +276,6 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.5"
|
version: "1.0.5"
|
||||||
js:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: js
|
|
||||||
sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.7.2"
|
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -336,18 +328,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.17"
|
version: "0.12.19"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.11.1"
|
version: "0.13.0"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -669,26 +661,26 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test
|
name: test
|
||||||
sha256: "75906bf273541b676716d1ca7627a17e4c4070a3a16272b7a3dc7da3b9f3f6b7"
|
sha256: "280d6d890011ca966ad08df7e8a4ddfab0fb3aa49f96ed6de56e3521347a9ae7"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.26.3"
|
version: "1.30.0"
|
||||||
test_api:
|
test_api:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
|
sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.7"
|
version: "0.7.10"
|
||||||
test_core:
|
test_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_core
|
name: test_core
|
||||||
sha256: "0cc24b5ff94b38d2ae73e1eb43cc302b77964fbf67abad1e296025b78deb53d0"
|
sha256: "0381bd1585d1a924763c308100f2138205252fb90c9d4eeaf28489ee65ccde51"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.12"
|
version: "0.6.16"
|
||||||
toml:
|
toml:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|||||||
Reference in New Issue
Block a user