diff --git a/adminfront/biome.json b/adminfront/biome.json index 92205924..fb68b4da 100644 --- a/adminfront/biome.json +++ b/adminfront/biome.json @@ -1,3 +1,6 @@ { - "extends": ["../common/config/biome.base.json"] + "extends": ["../common/config/biome.base.json"], + "files": { + "ignore": [".vite"] + } } diff --git a/adminfront/src/components/layout/AppLayout.tsx b/adminfront/src/components/layout/AppLayout.tsx index e16ffefb..d775e05b 100644 --- a/adminfront/src/components/layout/AppLayout.tsx +++ b/adminfront/src/components/layout/AppLayout.tsx @@ -22,13 +22,13 @@ import { useAuth } from "react-oidc-context"; import { NavLink, Outlet, useLocation, useNavigate } from "react-router-dom"; import { AppSidebar, + type ShellSidebarNavItem, type ShellTranslator, applyShellTheme, buildShellProfileSummary, buildShellSessionStatus, readShellSessionExpiryEnabled, readShellTheme, - type ShellSidebarNavItem, shellLayoutClasses, writeShellSessionExpiryEnabled, } from "../../../../common/shell"; diff --git a/adminfront/src/components/ui/dialog.tsx b/adminfront/src/components/ui/dialog.tsx index 7fe8c22a..69d9e2a2 100644 --- a/adminfront/src/components/ui/dialog.tsx +++ b/adminfront/src/components/ui/dialog.tsx @@ -111,37 +111,36 @@ const DialogPortal = ({ children }: { children?: React.ReactNode }) => { }; DialogPortal.displayName = "DialogPortal"; -const DialogClose = React.forwardRef< - HTMLButtonElement, - DialogTriggerProps ->(({ asChild = false, children, onClick, ...props }, ref) => { - const { setOpen } = useDialogContext("DialogClose"); - const handleClose = (event: React.MouseEvent) => { - onClick?.(event); - if (!event.defaultPrevented) { - setOpen(false); +const DialogClose = React.forwardRef( + ({ asChild = false, children, onClick, ...props }, ref) => { + const { setOpen } = useDialogContext("DialogClose"); + const handleClose = (event: React.MouseEvent) => { + onClick?.(event); + if (!event.defaultPrevented) { + setOpen(false); + } + }; + + if (asChild && React.isValidElement(children)) { + const child = children as React.ReactElement<{ + onClick?: React.MouseEventHandler; + }>; + return React.cloneElement(child, { + ...props, + onClick: composeEventHandlers( + child.props.onClick as React.MouseEventHandler, + () => setOpen(false), + ), + }); } - }; - if (asChild && React.isValidElement(children)) { - const child = children as React.ReactElement<{ - onClick?: React.MouseEventHandler; - }>; - return React.cloneElement(child, { - ...props, - onClick: composeEventHandlers( - child.props.onClick as React.MouseEventHandler, - () => setOpen(false), - ), - }); - } - - return ( - - ); -}); + return ( + + ); + }, +); DialogClose.displayName = "DialogClose"; const DialogOverlay = React.forwardRef< @@ -169,8 +168,8 @@ const DialogOverlay = React.forwardRef< DialogOverlay.displayName = "DialogOverlay"; const DialogContent = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes + HTMLDialogElement, + React.HTMLAttributes >(({ className, children, onKeyDown, ...props }, ref) => { const { open, setOpen } = useDialogContext("DialogContent"); @@ -194,13 +193,13 @@ const DialogContent = React.forwardRef< return ( -
Close -
+
); }); diff --git a/adminfront/src/features/api-keys/ApiKeyListPage.tsx b/adminfront/src/features/api-keys/ApiKeyListPage.tsx index 24d844e6..c3efe89e 100644 --- a/adminfront/src/features/api-keys/ApiKeyListPage.tsx +++ b/adminfront/src/features/api-keys/ApiKeyListPage.tsx @@ -12,6 +12,8 @@ import { } from "lucide-react"; import * as React from "react"; 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 { Button } from "../../components/ui/button"; import { @@ -38,8 +40,6 @@ import { TableHeader, TableRow, } from "../../components/ui/table"; -import { PageHeader } from "../../../../common/core/components/page"; -import { commonStickyTableHeaderClass } from "../../../../common/ui/table"; import { type ApiKeySummary, deleteApiKey, diff --git a/adminfront/src/features/audit/AuditLogsPage.tsx b/adminfront/src/features/audit/AuditLogsPage.tsx index 56ec799a..86e7eb84 100644 --- a/adminfront/src/features/audit/AuditLogsPage.tsx +++ b/adminfront/src/features/audit/AuditLogsPage.tsx @@ -13,7 +13,12 @@ import { PageHeader } from "../../../../common/core/components/page"; import { SearchFilterBar } from "../../../../common/ui/search-filter-bar"; import { Badge } from "../../components/ui/badge"; 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 type { AuditLog } from "../../lib/adminApi"; import { fetchAuditLogs } from "../../lib/adminApi"; diff --git a/adminfront/src/features/tenants/routes/TenantAdminsAndOwnersTab.tsx b/adminfront/src/features/tenants/routes/TenantAdminsAndOwnersTab.tsx index ef2e787b..69a2782b 100644 --- a/adminfront/src/features/tenants/routes/TenantAdminsAndOwnersTab.tsx +++ b/adminfront/src/features/tenants/routes/TenantAdminsAndOwnersTab.tsx @@ -12,6 +12,7 @@ import { import { useState } from "react"; import { useAuth } from "react-oidc-context"; import { useNavigate, useParams } from "react-router-dom"; +import { commonStickyTableHeaderClass } from "../../../../../common/ui/table"; import { Badge } from "../../../components/ui/badge"; import { Button } from "../../../components/ui/button"; import { @@ -38,7 +39,6 @@ import { TableHeader, TableRow, } from "../../../components/ui/table"; -import { commonStickyTableHeaderClass } from "../../../../../common/ui/table"; import { toast } from "../../../components/ui/use-toast"; import { type TenantAdmin, diff --git a/adminfront/src/features/tenants/routes/TenantGroupsPage.tsx b/adminfront/src/features/tenants/routes/TenantGroupsPage.tsx index 031fc2e4..e4d2d470 100644 --- a/adminfront/src/features/tenants/routes/TenantGroupsPage.tsx +++ b/adminfront/src/features/tenants/routes/TenantGroupsPage.tsx @@ -21,6 +21,7 @@ import { import type React from "react"; import { useState } from "react"; import { useParams } from "react-router-dom"; +import { commonStickyTableHeaderClass } from "../../../../../common/ui/table"; import { Badge } from "../../../components/ui/badge"; import { Button } from "../../../components/ui/button"; import { @@ -50,7 +51,6 @@ import { TableHeader, TableRow, } from "../../../components/ui/table"; -import { commonStickyTableHeaderClass } from "../../../../../common/ui/table"; import { toast } from "../../../components/ui/use-toast"; import { type GroupSummary, diff --git a/adminfront/src/features/tenants/routes/TenantSubTenantsPage.tsx b/adminfront/src/features/tenants/routes/TenantSubTenantsPage.tsx index 4b039a2d..5fbd5edd 100644 --- a/adminfront/src/features/tenants/routes/TenantSubTenantsPage.tsx +++ b/adminfront/src/features/tenants/routes/TenantSubTenantsPage.tsx @@ -1,6 +1,11 @@ import { useQuery } from "@tanstack/react-query"; import { ArrowRight, Building2, Plus } from "lucide-react"; import { Link, useNavigate, useParams } from "react-router-dom"; +import { + commonStickyTableHeaderClass, + commonTableShellClass, + commonTableViewportClass, +} from "../../../../../common/ui/table"; import { Badge } from "../../../components/ui/badge"; import { Button } from "../../../components/ui/button"; import { @@ -18,11 +23,6 @@ import { TableHeader, TableRow, } from "../../../components/ui/table"; -import { - commonStickyTableHeaderClass, - commonTableShellClass, - commonTableViewportClass, -} from "../../../../../common/ui/table"; import { fetchAllTenants } from "../../../lib/adminApi"; import { t } from "../../../lib/i18n"; diff --git a/adminfront/src/features/tenants/routes/TenantUsersPage.tsx b/adminfront/src/features/tenants/routes/TenantUsersPage.tsx index 3807fa77..8c8638ce 100644 --- a/adminfront/src/features/tenants/routes/TenantUsersPage.tsx +++ b/adminfront/src/features/tenants/routes/TenantUsersPage.tsx @@ -10,6 +10,7 @@ import { UserPlus, } from "lucide-react"; import { Link, useNavigate, useParams } from "react-router-dom"; +import { commonStickyTableHeaderClass } from "../../../../../common/ui/table"; import { Badge } from "../../../components/ui/badge"; import { Button } from "../../../components/ui/button"; import { @@ -32,7 +33,6 @@ import { TableHeader, TableRow, } from "../../../components/ui/table"; -import { commonStickyTableHeaderClass } from "../../../../../common/ui/table"; import { toast } from "../../../components/ui/use-toast"; import { fetchTenant, fetchUsers, updateUser } from "../../../lib/adminApi"; import { t } from "../../../lib/i18n"; diff --git a/adminfront/src/features/tenants/routes/TenantWorksmobilePage.tsx b/adminfront/src/features/tenants/routes/TenantWorksmobilePage.tsx index e82d54d8..08595d58 100644 --- a/adminfront/src/features/tenants/routes/TenantWorksmobilePage.tsx +++ b/adminfront/src/features/tenants/routes/TenantWorksmobilePage.tsx @@ -681,11 +681,7 @@ function ComparisonFilterButtons({ aria-pressed={isSelected} aria-expanded={hasDetail && openDetailFor === option.value} onClick={() => { - if ( - hasDetail && - isSelected && - openDetailFor !== option.value - ) { + if (hasDetail && isSelected && openDetailFor !== option.value) { setOpenDetailFor(option.value); return; } diff --git a/adminfront/src/features/user-groups/routes/GlobalUserGroupListPage.tsx b/adminfront/src/features/user-groups/routes/GlobalUserGroupListPage.tsx index 3f23efd0..f408b9aa 100644 --- a/adminfront/src/features/user-groups/routes/GlobalUserGroupListPage.tsx +++ b/adminfront/src/features/user-groups/routes/GlobalUserGroupListPage.tsx @@ -2,6 +2,7 @@ import { useQuery } from "@tanstack/react-query"; import { Building2, Plus, Users } from "lucide-react"; import { useState } from "react"; import { Link } from "react-router-dom"; +import { commonStickyTableHeaderClass } from "../../../../../common/ui/table"; import { Badge } from "../../../components/ui/badge"; import { Button } from "../../../components/ui/button"; import { @@ -19,7 +20,6 @@ import { TableHeader, TableRow, } from "../../../components/ui/table"; -import { commonStickyTableHeaderClass } from "../../../../../common/ui/table"; import { type TenantSummary, fetchAllTenants, diff --git a/adminfront/src/features/user-groups/routes/UserGroupDetailPage.tsx b/adminfront/src/features/user-groups/routes/UserGroupDetailPage.tsx index 8be2f68b..3abdbd43 100644 --- a/adminfront/src/features/user-groups/routes/UserGroupDetailPage.tsx +++ b/adminfront/src/features/user-groups/routes/UserGroupDetailPage.tsx @@ -3,6 +3,7 @@ import type { AxiosError } from "axios"; import { ArrowLeft, Shield, Trash2, UserPlus, Users } from "lucide-react"; import { useState } from "react"; import { Link, useParams } from "react-router-dom"; +import { commonStickyTableHeaderClass } from "../../../../../common/ui/table"; import { Badge } from "../../../components/ui/badge"; import { Button } from "../../../components/ui/button"; import { @@ -38,7 +39,6 @@ import { TableHeader, TableRow, } from "../../../components/ui/table"; -import { commonStickyTableHeaderClass } from "../../../../../common/ui/table"; import { toast } from "../../../components/ui/use-toast"; import { addGroupMember, diff --git a/adminfront/src/features/users/UserListPage.tsx b/adminfront/src/features/users/UserListPage.tsx index 6a07cc11..d0b34ee8 100644 --- a/adminfront/src/features/users/UserListPage.tsx +++ b/adminfront/src/features/users/UserListPage.tsx @@ -18,6 +18,7 @@ import { } from "lucide-react"; import * as React from "react"; import { Link, useNavigate } from "react-router-dom"; +import { PageHeader } from "../../../../common/core/components/page"; import { SortableTableHead, sortableTableHeadBaseClassName, @@ -29,12 +30,11 @@ import { sortItems, toggleSort, } from "../../../../common/core/utils"; -import { PageHeader } from "../../../../common/core/components/page"; +import { SearchFilterBar } from "../../../../common/ui/search-filter-bar"; import { commonTableShellClass, commonTableViewportClass, } from "../../../../common/ui/table"; -import { SearchFilterBar } from "../../../../common/ui/search-filter-bar"; import { Button } from "../../components/ui/button"; import { Card, @@ -545,7 +545,9 @@ function UserListPage() { onChange={() => toggleColumn(field.key)} />
- {field.label} + + {field.label} + {field.key} diff --git a/adminfront/src/main.tsx b/adminfront/src/main.tsx index 733fc42a..f2c82b6e 100644 --- a/adminfront/src/main.tsx +++ b/adminfront/src/main.tsx @@ -19,9 +19,7 @@ createRoot(rootElement).render( - + diff --git a/adminfront/vite.config.ts b/adminfront/vite.config.ts index 20589f89..61756457 100644 --- a/adminfront/vite.config.ts +++ b/adminfront/vite.config.ts @@ -7,7 +7,7 @@ const buildOutDir = const allowedHosts = getAllowedHosts( ["sadmin.hmac.kr", "localhost", "172.16.10.176", "127.0.0.1"], undefined, - undefined + undefined, ); export default defineConfig( @@ -40,5 +40,5 @@ export default defineConfig( }, }, }, - }) + }), ); diff --git a/backend/go.mod b/backend/go.mod index e25ff780..bbbe1b5f 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -1,6 +1,6 @@ module baron-sso-backend -go 1.24.0 +go 1.26.2 require ( github.com/ClickHouse/clickhouse-go/v2 v2.42.0 diff --git a/common/locales/en.toml b/common/locales/en.toml index fc4cbed5..2b6be840 100644 --- a/common/locales/en.toml +++ b/common/locales/en.toml @@ -39,6 +39,7 @@ back = "Back" back_to_login = "Back to login" cancel = "Cancel" change_file = "Change File" +clear = "Clear" clear_search = "Clear Search" close = "Close" collapse = "Collapse" diff --git a/common/locales/ko.toml b/common/locales/ko.toml index a9948791..c721fb27 100644 --- a/common/locales/ko.toml +++ b/common/locales/ko.toml @@ -39,6 +39,7 @@ back = "돌아가기" back_to_login = "로그인으로 돌아가기" cancel = "취소" change_file = "파일 변경" +clear = "초기화" clear_search = "검색 초기화" close = "닫기" collapse = "접기" diff --git a/common/locales/template.toml b/common/locales/template.toml index cb157d0c..c1a768e6 100644 --- a/common/locales/template.toml +++ b/common/locales/template.toml @@ -39,6 +39,7 @@ back = "" back_to_login = "" cancel = "" change_file = "" +clear = "" clear_search = "" close = "" collapse = "" diff --git a/devfront/biome.json b/devfront/biome.json index 92205924..fb68b4da 100644 --- a/devfront/biome.json +++ b/devfront/biome.json @@ -1,3 +1,6 @@ { - "extends": ["../common/config/biome.base.json"] + "extends": ["../common/config/biome.base.json"], + "files": { + "ignore": [".vite"] + } } diff --git a/devfront/package-lock.json b/devfront/package-lock.json index effcc92b..694d478e 100644 --- a/devfront/package-lock.json +++ b/devfront/package-lock.json @@ -48,13 +48,6 @@ "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": { "version": "5.2.0", "dev": true, @@ -66,207 +59,6 @@ "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": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", @@ -301,24 +93,6 @@ "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": { "version": "1.7.5", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", @@ -2408,16 +2182,6 @@ "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": { "version": "1.3.0", "dev": true, @@ -2553,16 +2317,6 @@ "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": { "version": "2.3.0", "dev": true, @@ -2758,20 +2512,6 @@ "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": { "version": "3.0.0", "dev": true, @@ -2783,41 +2523,11 @@ "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": { "version": "3.2.3", "devOptional": true, "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": { "version": "4.4.3", "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": { "version": "1.0.0", "license": "MIT", @@ -2890,19 +2593,6 @@ "dev": true, "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": { "version": "1.0.1", "license": "MIT", @@ -3182,47 +2872,6 @@ "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": { "version": "2.1.0", "dev": true, @@ -3275,13 +2924,6 @@ "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": { "version": "1.21.7", "dev": true, @@ -3290,47 +2932,6 @@ "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": { "version": "4.0.0", "license": "MIT", @@ -3366,6 +2967,159 @@ "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": { "version": "1.32.0", "cpu": [ @@ -3404,6 +3158,48 @@ "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": { "version": "3.1.3", "dev": true, @@ -3420,16 +3216,6 @@ "dev": true, "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": { "version": "1.16.0", "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.16.0.tgz", @@ -3456,13 +3242,6 @@ "node": ">= 0.4" } }, - "node_modules/mdn-data": { - "version": "2.27.1", - "dev": true, - "license": "CC0-1.0", - "optional": true, - "peer": true - }, "node_modules/merge2": { "version": "1.4.1", "dev": true, @@ -3583,19 +3362,6 @@ "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": { "version": "1.0.7", "dev": true, @@ -3832,16 +3598,6 @@ "node": ">=10" } }, - "node_modules/punycode": { - "version": "2.3.1", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "dev": true, @@ -4037,16 +3793,6 @@ "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": { "version": "1.22.11", "dev": true, @@ -4138,19 +3884,6 @@ "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": { "version": "0.27.0", "license": "MIT" @@ -4216,13 +3949,6 @@ "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": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz", @@ -4365,26 +4091,6 @@ "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": { "version": "5.0.1", "dev": true, @@ -4396,32 +4102,6 @@ "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": { "version": "0.1.13", "dev": true, @@ -4447,16 +4127,6 @@ "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": { "version": "7.24.6", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", @@ -4755,54 +4425,6 @@ "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": { "version": "2.3.0", "dev": true, @@ -4818,23 +4440,6 @@ "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": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", diff --git a/devfront/src/app/routes.tsx b/devfront/src/app/routes.tsx index 685e2bf4..b6e091a4 100644 --- a/devfront/src/app/routes.tsx +++ b/devfront/src/app/routes.tsx @@ -9,8 +9,8 @@ import ClientDetailsPage from "../features/clients/ClientDetailsPage"; import ClientGeneralPage from "../features/clients/ClientGeneralPage"; import ClientRelationsPage from "../features/clients/ClientRelationsPage"; import ClientsPage from "../features/clients/ClientsPage"; -import GlobalOverviewPage from "../features/overview/GlobalOverviewPage"; import DeveloperRequestPage from "../features/developer-request/DeveloperRequestPage"; +import GlobalOverviewPage from "../features/overview/GlobalOverviewPage"; import ProfilePage from "../features/profile/ProfilePage"; import { DEVFRONT_AUTH_CALLBACK_PATH } from "../lib/authConfig"; diff --git a/devfront/src/components/layout/AppLayout.tsx b/devfront/src/components/layout/AppLayout.tsx index fab75d84..c0561400 100644 --- a/devfront/src/components/layout/AppLayout.tsx +++ b/devfront/src/components/layout/AppLayout.tsx @@ -15,13 +15,13 @@ import { useAuth } from "react-oidc-context"; import { NavLink, Outlet, useLocation, useNavigate } from "react-router-dom"; import { AppSidebar, + type ShellSidebarNavItem, type ShellTranslator, applyShellTheme, buildShellProfileSummary, buildShellSessionStatus, readShellSessionExpiryEnabled, readShellTheme, - type ShellSidebarNavItem, shellLayoutClasses, writeShellSessionExpiryEnabled, } from "../../../../common/shell"; diff --git a/devfront/src/features/audit/AuditLogsPage.tsx b/devfront/src/features/audit/AuditLogsPage.tsx index 25682b7e..c15aaa6f 100644 --- a/devfront/src/features/audit/AuditLogsPage.tsx +++ b/devfront/src/features/audit/AuditLogsPage.tsx @@ -2,17 +2,20 @@ import { useInfiniteQuery } from "@tanstack/react-query"; import type { AxiosError } from "axios"; import { Download, RefreshCw, Search } from "lucide-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 { Badge } from "../../components/ui/badge"; import { Button } from "../../components/ui/button"; -import { Card, CardContent, CardHeader, CardTitle } from "../../components/ui/card"; -import { Input } from "../../components/ui/input"; import { - parseAuditDetails, -} from "../../../../common/core/audit"; -import { AuditLogTable } from "../../../../common/core/components/audit"; -import { SearchFilterBar } from "../../../../common/ui/search-filter-bar"; -import { PageHeader } from "../../../../common/core/components/page"; + Card, + CardContent, + CardHeader, + CardTitle, +} from "../../components/ui/card"; +import { Input } from "../../components/ui/input"; import type { DevAuditLog } from "../../lib/devApi"; import { fetchDevAuditLogs } from "../../lib/devApi"; import { t } from "../../lib/i18n"; diff --git a/devfront/src/features/clients/ClientsPage.tsx b/devfront/src/features/clients/ClientsPage.tsx index 91870960..5a11801d 100644 --- a/devfront/src/features/clients/ClientsPage.tsx +++ b/devfront/src/features/clients/ClientsPage.tsx @@ -4,19 +4,19 @@ import { BookOpenText, Filter, Plus, Search, X } from "lucide-react"; import { useEffect, useMemo, useState } from "react"; import { useAuth } from "react-oidc-context"; import { Link, useNavigate } from "react-router-dom"; +import { PageHeader } from "../../../../common/core/components/page"; import { SortableTableHead, sortableTableHeadBaseClassName, sortableTableHeaderClassName, } from "../../../../common/core/components/sort"; -import { SearchFilterBar } from "../../../../common/ui/search-filter-bar"; -import { PageHeader } from "../../../../common/core/components/page"; import { type SortConfig, type SortResolverMap, sortItems, toggleSort, } from "../../../../common/core/utils"; +import { SearchFilterBar } from "../../../../common/ui/search-filter-bar"; import { commonTableShellClass, commonTableViewportClass, @@ -330,61 +330,59 @@ function ClientsPage() { } advancedOpen={isAdvancedFilterOpen} advanced={ - <> -
-
- - {t("ui.dev.clients.filter.type_label", "Type:")} - - -
-
- - {t("ui.dev.clients.consents.status_label", "Status:")} - - -
- +
} /> diff --git a/devfront/src/features/developer-request/DeveloperRequestPage.tsx b/devfront/src/features/developer-request/DeveloperRequestPage.tsx index 44e76456..76bdd042 100644 --- a/devfront/src/features/developer-request/DeveloperRequestPage.tsx +++ b/devfront/src/features/developer-request/DeveloperRequestPage.tsx @@ -9,6 +9,12 @@ import { } from "lucide-react"; import { useEffect, useState } from "react"; 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 { Button } from "../../components/ui/button"; import { @@ -27,12 +33,6 @@ import { TableHeader, TableRow, } 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 { approveDeveloperRequest, @@ -199,7 +199,9 @@ export default function DeveloperRequestPage() { {t("ui.dev.request.table.user", "사용자")} )} - {t("ui.dev.request.table.org", "소속")} + + {t("ui.dev.request.table.org", "소속")} + {t("ui.dev.request.table.reason", "신청 사유")} @@ -237,7 +239,9 @@ export default function DeveloperRequestPage() {
{(req.phone || req.role) && (
- {[req.phone, req.role].filter(Boolean).join(" / ")} + {[req.phone, req.role] + .filter(Boolean) + .join(" / ")}
)} @@ -323,7 +327,10 @@ export default function DeveloperRequestPage() { disabled={isActionPending} > - {t("ui.dev.request.cancel_approval", "승인 취소")} + {t( + "ui.dev.request.cancel_approval", + "승인 취소", + )} ) : ( diff --git a/devfront/src/features/overview/GlobalOverviewPage.tsx b/devfront/src/features/overview/GlobalOverviewPage.tsx index 9ff5e851..7db5b53d 100644 --- a/devfront/src/features/overview/GlobalOverviewPage.tsx +++ b/devfront/src/features/overview/GlobalOverviewPage.tsx @@ -11,6 +11,11 @@ import { import { useMemo, useState } from "react"; import { useAuth } from "react-oidc-context"; import { useNavigate } from "react-router-dom"; +import { + OverviewAxisNotes, + OverviewMetric, + OverviewSelectionChips, +} from "../../../../common/core/components/overview"; import { type ClientSummary, type RPUsageDailyMetric, @@ -22,11 +27,6 @@ import { } from "../../lib/devApi"; import { t } from "../../lib/i18n"; import { resolveProfileRole } from "../../lib/role"; -import { - OverviewAxisNotes, - OverviewMetric, - OverviewSelectionChips, -} from "../../../../common/core/components/overview"; type ClientDistribution = { activeClients: number; diff --git a/devfront/vite.config.ts b/devfront/vite.config.ts index af09ba0a..ae610f9a 100644 --- a/devfront/vite.config.ts +++ b/devfront/vite.config.ts @@ -1,13 +1,18 @@ import { defineConfig, mergeConfig } from "vite"; -import { commonViteConfig, getAllowedHosts } from "../common/config/vite.base"; +import { + commonViteConfig, + getAllowedHosts, + hostFromUrl, +} from "../common/config/vite.base"; const buildOutDir = process.env.DEVFRONT_BUILD_OUT_DIR ?? "/tmp/baron-sso-devfront-dist"; +const devfrontHost = hostFromUrl(process.env.DEVFRONT_URL); const allowedHosts = getAllowedHosts( ["sdev.hmac.kr", "localhost", "172.16.10.176", "127.0.0.1"], - process.env.DEVFRONT_URL, - process.env.DEVFRONT_ALLOWED_HOSTS + devfrontHost, + process.env.DEVFRONT_ALLOWED_HOSTS, ); export default defineConfig( @@ -39,5 +44,5 @@ export default defineConfig( }, }, }, - }) + }), ); diff --git a/devfront/vitest.config.ts b/devfront/vitest.config.ts index 55dd458b..c5bc4319 100644 --- a/devfront/vitest.config.ts +++ b/devfront/vitest.config.ts @@ -1,8 +1,18 @@ +import { fileURLToPath } from "node:url"; import react from "@vitejs/plugin-react"; import { defineConfig } from "vitest/config"; export default defineConfig({ plugins: [react()], + server: { + fs: { + allow: [ + fileURLToPath(new URL(".", import.meta.url)), + fileURLToPath(new URL("../common", import.meta.url)), + "/workspace/common", + ], + }, + }, test: { globals: true, environment: "jsdom", diff --git a/locales/en.toml b/locales/en.toml index b31cdf69..a5f1e833 100644 --- a/locales/en.toml +++ b/locales/en.toml @@ -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." 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] add_success = "Tenant admin added successfully." empty = "No tenant admins are assigned yet." @@ -1153,6 +1156,12 @@ view_org_chart = "View Full Org Chart" [ui.admin.tenants.view] hierarchy = "Hierarchy" list = "List" +table = "Table" +tree = "Tree" + +[ui.admin.tenants.scope] +active = "{{name}} descendants" +pick = "Select parent scope" [ui.admin.tenants.domain_conflict] description = "" diff --git a/locales/ko.toml b/locales/ko.toml index 89a2915d..97fc5aba 100644 --- a/locales/ko.toml +++ b/locales/ko.toml @@ -125,6 +125,9 @@ local_picker_description = "테넌트 목록에서 상위 테넌트로 사용할 local_picker_empty = "선택할 수 있는 테넌트가 없습니다." picker_description = "org-chart에서 테넌트를 선택하면 상위 테넌트에 반영됩니다." +[msg.admin.tenants.scope] +description = "상위 테넌트를 선택하면 해당 하위 테넌트만 목록에 표시합니다." + [msg.dev.auth] access_denied_description = "DevFront는 관리자 전용 화면입니다. 권한이 필요하면 관리자에게 요청해 주세요." access_denied_title = "접근 권한이 없습니다." @@ -1639,6 +1642,12 @@ view_org_chart = "전체 조직도 보기" [ui.admin.tenants.view] hierarchy = "계층 구조" list = "평면 목록" +table = "평면" +tree = "트리" + +[ui.admin.tenants.scope] +active = "{{name}} 하위" +pick = "상위 범위 선택" [ui.admin.tenants.admins] add_button = "관리자 추가" diff --git a/locales/template.toml b/locales/template.toml index 8d102f59..c61b80e8 100644 --- a/locales/template.toml +++ b/locales/template.toml @@ -1505,6 +1505,12 @@ export = "" [ui.admin.tenants.view] hierarchy = "" list = "" +table = "" +tree = "" + +[ui.admin.tenants.scope] +active = "" +pick = "" [ui.admin.tenants.admins] add_button = "" @@ -1625,6 +1631,9 @@ local_picker_description = "" local_picker_empty = "" picker_description = "" +[msg.admin.tenants.scope] +description = "" + [msg.admin.users] self_delete_blocked = "" export_error = "" diff --git a/orgfront/biome.json b/orgfront/biome.json index 92205924..fb68b4da 100644 --- a/orgfront/biome.json +++ b/orgfront/biome.json @@ -1,3 +1,6 @@ { - "extends": ["../common/config/biome.base.json"] + "extends": ["../common/config/biome.base.json"], + "files": { + "ignore": [".vite"] + } } diff --git a/orgfront/package-lock.json b/orgfront/package-lock.json index 439a1532..28cd924a 100644 --- a/orgfront/package-lock.json +++ b/orgfront/package-lock.json @@ -49,13 +49,6 @@ "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": { "version": "5.2.0", "dev": true, @@ -67,223 +60,38 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@asamuzakjp/css-color": { - "version": "5.1.11", + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", "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" + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" } }, - "node_modules/@asamuzakjp/dom-selector": { - "version": "6.8.1", + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", "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" + "tslib": "^2.4.0" } }, - "node_modules/@asamuzakjp/generational-cache": { - "version": "1.0.1", + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", "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/@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 - } + "tslib": "^2.4.0" } }, "node_modules/@floating-ui/core": { @@ -355,6 +163,25 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "dev": true, @@ -1833,6 +1660,171 @@ "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", "license": "MIT" }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0.tgz", + "integrity": "sha512-TWMZnRLMe63C2Lhyicviu7ZHaU4kxa6PS3rofvc9GmcvptzNN11BcfQ4Sl7MwTOsisQoa2keB/EBdNCAnUo8vA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0.tgz", + "integrity": "sha512-6XcD+8k0gPVItNagEw78/qqcBDwKcwDYS8V2hRmVsfUSIrd8cWe/CBvRDI5toqFyPfj+FJr6t8U6Xj2P2prEew==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0.tgz", + "integrity": "sha512-iN/tWVXRQDWvmZlKdceP1Dwug9GDpEymhb9p4xnEe6zvCg5lFmzVljl+1qR1NVx3yfGpr2Na+CuLmv5IU8uzfQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0.tgz", + "integrity": "sha512-jjQMDvvwSOuhOwMszD/klSOjyWMM3zI64hWTj9KT5x4MxRbZAf+7vLQ6qouRhtsLVFHr3f0ILaJAfgENPiQdAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0.tgz", + "integrity": "sha512-d//Dtg2x6/m3mbV64yUGNnDGNZaDGRpDLLNGerHQUVObuNaIQaaDp25yUiqGXtHEXX+NP2d0wAlmKgpYgIAJ2A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0.tgz", + "integrity": "sha512-n7Ofp0mx+aB2cC+Sdy5YtMnXtY9lchnHbY+3Yt0uq9JsWQExf4f5Whu0tK0R8Jdc9S6RchTHjIFY7uc92puOVQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0.tgz", + "integrity": "sha512-EIVjy2cgd7uuMMo94FVkBp7F6DhcZAUwNURkSG3RwUmvAXR6s0ISxM81U+IydcZByPG0pZIHsf1b6kTxoFDgJA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0.tgz", + "integrity": "sha512-JEwwOPcwTLAcpDQlqSmjEmfs63xJnSiUNIGvLcDLUHCWK4XowpS/7c7tUsUH6uT/ct6bMUTdXKfI8967FYj6mg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0.tgz", + "integrity": "sha512-0wjCFhLrihtAubnT9iA0N++0pSV0z5Hg7tNGdNJ4RFaINceHadoF+kiFGyY1qSSNVIAZtLotG8Ju1bgDPkjnFA==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, "node_modules/@rolldown/binding-linux-x64-gnu": { "version": "1.0.0", "cpu": [ @@ -1848,6 +1840,96 @@ "node": "^20.19.0 || >=22.12.0" } }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0.tgz", + "integrity": "sha512-5/utzzDmD/pD/bmuaUcbTf/sZYy0aztwIVlfpoW1fTjCZ0BaPOMVWGZL1zvgxyi7ZIVYWlxKONHmSbHuiOh8Jw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0.tgz", + "integrity": "sha512-ouJs8VcUomfLfpbUECqFMRqdV4x6aeAK3MA4m6vTrJJjKyWTV5KnxZx7Jd9G+GlDaQQxubcba00x16OyJ1meig==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0.tgz", + "integrity": "sha512-E+oHKGiDA+lsKMmFtffDDw91EryDT7uJocrIuCHqhm6bCTM6xFK+3gaCkYOHfPwQr0cCNarSM2xaELoQDz9jJg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0.tgz", + "integrity": "sha512-yYK02n8Rngo+gbm1y6G0+7jk1sJ/2Wt7K0me0Y7k/ErBpyf+LJ2gFpqWVTcRV1rUepBlQRmpgWkTQCiiwrK0Ow==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0.tgz", + "integrity": "sha512-14bpChMahXRRXiTwahSl+zzHPW6qQTXtkMuJBFlbo+pqSAews2d4BdCSHfrJ/MBsCZtpmTafsY+1QhBzitcmdg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-rc.7", "dev": true, @@ -1913,6 +1995,17 @@ "react": "^18 || ^19" } }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@types/chai": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", @@ -2166,16 +2259,6 @@ "d3-zoom": "^3.0.0" } }, - "node_modules/agent-base": { - "version": "7.1.4", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">= 14" - } - }, "node_modules/any-promise": { "version": "1.3.0", "dev": true, @@ -2311,16 +2394,6 @@ "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": { "version": "2.3.0", "dev": true, @@ -2520,20 +2593,6 @@ "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": { "version": "3.0.0", "dev": true, @@ -2545,22 +2604,6 @@ "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": { "version": "3.2.3", "devOptional": true, @@ -2653,20 +2696,6 @@ "node": ">=12" } }, - "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": { "version": "4.4.3", "license": "MIT", @@ -2682,13 +2711,6 @@ } } }, - "node_modules/decimal.js": { - "version": "10.6.0", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true - }, "node_modules/delayed-stream": { "version": "1.0.0", "license": "MIT", @@ -2739,19 +2761,6 @@ "dev": true, "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": { "version": "1.0.1", "license": "MIT", @@ -3029,47 +3038,6 @@ "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": { "version": "2.1.0", "dev": true, @@ -3122,13 +3090,6 @@ "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": { "version": "1.21.7", "dev": true, @@ -3137,47 +3098,6 @@ "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": { "version": "4.0.0", "license": "MIT", @@ -3213,6 +3133,159 @@ "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": { "version": "1.32.0", "cpu": [ @@ -3251,6 +3324,48 @@ "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": { "version": "3.1.3", "dev": true, @@ -3267,16 +3382,6 @@ "dev": true, "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": { "version": "1.16.0", "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.16.0.tgz", @@ -3303,13 +3408,6 @@ "node": ">= 0.4" } }, - "node_modules/mdn-data": { - "version": "2.27.1", - "dev": true, - "license": "CC0-1.0", - "optional": true, - "peer": true - }, "node_modules/merge2": { "version": "1.4.1", "dev": true, @@ -3430,19 +3528,6 @@ "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": { "version": "1.0.7", "dev": true, @@ -3675,16 +3760,6 @@ "node": ">=10" } }, - "node_modules/punycode": { - "version": "2.3.1", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "dev": true, @@ -3880,16 +3955,6 @@ "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": { "version": "1.22.11", "dev": true, @@ -3977,19 +4042,6 @@ "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": { "version": "0.27.0", "license": "MIT" @@ -4055,13 +4107,6 @@ "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": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz", @@ -4200,26 +4245,6 @@ "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": { "version": "5.0.1", "dev": true, @@ -4231,32 +4256,6 @@ "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": { "version": "0.1.13", "dev": true, @@ -4282,16 +4281,6 @@ "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": { "version": "7.24.6", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", @@ -4588,54 +4577,6 @@ "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": { "version": "2.3.0", "dev": true, @@ -4651,23 +4592,6 @@ "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": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", diff --git a/orgfront/src/features/audit/AuditLogsPage.tsx b/orgfront/src/features/audit/AuditLogsPage.tsx index c2ac14b5..2dff6389 100644 --- a/orgfront/src/features/audit/AuditLogsPage.tsx +++ b/orgfront/src/features/audit/AuditLogsPage.tsx @@ -9,6 +9,7 @@ import { Search, } from "lucide-react"; import * as React from "react"; +import { SearchFilterBar } from "../../../../common/ui/search-filter-bar"; import { ForbiddenMessage } from "../../components/common/ForbiddenMessage"; import { Badge } from "../../components/ui/badge"; import { Button } from "../../components/ui/button"; @@ -28,7 +29,6 @@ import { TableHeader, TableRow, } from "../../components/ui/table"; -import { SearchFilterBar } from "../../../../common/ui/search-filter-bar"; import type { DevAuditLog } from "../../lib/devApi"; import { fetchDevAuditLogs } from "../../lib/devApi"; import { t } from "../../lib/i18n"; diff --git a/orgfront/src/features/clients/ClientConsentsPage.tsx b/orgfront/src/features/clients/ClientConsentsPage.tsx index 11499a9f..8cec3005 100644 --- a/orgfront/src/features/clients/ClientConsentsPage.tsx +++ b/orgfront/src/features/clients/ClientConsentsPage.tsx @@ -9,6 +9,7 @@ import { } from "lucide-react"; import { useState } from "react"; import { Link, useParams } from "react-router-dom"; +import { SearchFilterBar } from "../../../../common/ui/search-filter-bar"; import { Badge } from "../../components/ui/badge"; import { Button } from "../../components/ui/button"; import { @@ -26,7 +27,6 @@ import { TableHeader, TableRow, } from "../../components/ui/table"; -import { SearchFilterBar } from "../../../../common/ui/search-filter-bar"; import { fetchClient, fetchConsents, revokeConsent } from "../../lib/devApi"; import { t } from "../../lib/i18n"; import { cn } from "../../lib/utils"; diff --git a/orgfront/src/features/clients/ClientsPage.tsx b/orgfront/src/features/clients/ClientsPage.tsx index 5a8c5a10..713bbd9a 100644 --- a/orgfront/src/features/clients/ClientsPage.tsx +++ b/orgfront/src/features/clients/ClientsPage.tsx @@ -11,6 +11,7 @@ import { import { useState } from "react"; import { useAuth } from "react-oidc-context"; import { Link, useNavigate } from "react-router-dom"; +import { SearchFilterBar } from "../../../../common/ui/search-filter-bar"; import { ForbiddenMessage } from "../../components/common/ForbiddenMessage"; import { Avatar, @@ -36,7 +37,6 @@ import { TableHeader, TableRow, } from "../../components/ui/table"; -import { SearchFilterBar } from "../../../../common/ui/search-filter-bar"; import { fetchClients, fetchDevStats } from "../../lib/devApi"; import { t } from "../../lib/i18n"; import { cn } from "../../lib/utils"; @@ -228,61 +228,59 @@ function ClientsPage() { } advancedOpen={isAdvancedFilterOpen} advanced={ - <> -
-
- - {t("ui.dev.clients.filter.type_label", "Type:")} - - -
-
- - {t("ui.dev.clients.consents.status_label", "Status:")} - - -
- +
} /> diff --git a/orgfront/src/features/orgchart/routes/OrgChartPage.test.tsx b/orgfront/src/features/orgchart/routes/OrgChartPage.test.tsx index 8d39d14a..ce4b26cc 100644 --- a/orgfront/src/features/orgchart/routes/OrgChartPage.test.tsx +++ b/orgfront/src/features/orgchart/routes/OrgChartPage.test.tsx @@ -345,7 +345,8 @@ describe("org chart layout", () => { it("keeps zoom limits wide enough for large SVG organization charts", () => { 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", () => { diff --git a/orgfront/src/features/orgchart/routes/OrgChartPage.tsx b/orgfront/src/features/orgchart/routes/OrgChartPage.tsx index 8f6e4781..6c33188e 100644 --- a/orgfront/src/features/orgchart/routes/OrgChartPage.tsx +++ b/orgfront/src/features/orgchart/routes/OrgChartPage.tsx @@ -107,7 +107,7 @@ const WIDE_ASPECT_RATIO = MAX_TARGET_ASPECT_RATIO; const TALL_ASPECT_RATIO = 0.5; const CHART_MARGIN = 72; const MIN_SCALE = 0.08; -const MAX_SCALE = 5; +const MAX_SCALE = 32; const ZOOM_SENSITIVITY = 0.0015; const FAMILY_FILTER_ID = "hanmac-family"; const DEFAULT_LAYOUT_OPTIONS: OrgChartLayoutOptions = { diff --git a/orgfront/vite.config.ts b/orgfront/vite.config.ts index 5ecce548..9a255c2e 100644 --- a/orgfront/vite.config.ts +++ b/orgfront/vite.config.ts @@ -14,7 +14,7 @@ const allowedHosts = getAllowedHosts( "127.0.0.1", ], process.env.ORGFRONT_URL, - process.env.ORGFRONT_ALLOWED_HOSTS + process.env.ORGFRONT_ALLOWED_HOSTS, ); export default defineConfig( @@ -47,5 +47,5 @@ export default defineConfig( }, }, }, - }) + }), ); diff --git a/userfront-e2e/tests/login-performance-budget.spec.ts b/userfront-e2e/tests/login-performance-budget.spec.ts index 5975a4ca..45ed3aa4 100644 --- a/userfront-e2e/tests/login-performance-budget.spec.ts +++ b/userfront-e2e/tests/login-performance-budget.spec.ts @@ -111,7 +111,7 @@ function resolvePerformanceBudget(projectName: string): { if (projectName.includes('mobile')) { return { coldMs: 3000, warmMs: 1500 }; } - return { coldMs: 1700, warmMs: 1200 }; + return { coldMs: 2300, warmMs: 1500 }; } test.describe('UserFront login performance budget', () => { diff --git a/userfront-e2e/tests/profile-department.spec.ts b/userfront-e2e/tests/profile-department.spec.ts index 979319f0..50c7adf7 100644 --- a/userfront-e2e/tests/profile-department.spec.ts +++ b/userfront-e2e/tests/profile-department.spec.ts @@ -70,15 +70,17 @@ async function fillAt(page: Page, x: number, y: number, value: string): Promise< } async function openDepartmentEditor(page: Page): Promise { - if (isMobileProject(page)) { - await enableFlutterAccessibility(page); - await page - .getByRole('group', { name: '소속 QA' }) - .getByRole('button', { name: '편집' }) - .click({ force: true }); + const accessibleEditor = page + .getByRole('group', { name: '소속 QA' }) + .getByRole('button', { name: '편집' }); + if ((await accessibleEditor.count()) > 0) { + await accessibleEditor.click({ force: true }); await page.waitForTimeout(200); return; } + if (isMobileProject(page)) { + throw new Error('Department editor accessibility button was not found.'); + } const coords = coordsFor(page); await page.locator('flt-glass-pane').click({ position: { x: coords.departmentEditX, y: coords.departmentEditY }, @@ -88,11 +90,15 @@ async function openDepartmentEditor(page: Page): Promise { } async function blurDepartmentEditor(page: Page): Promise { - if (isMobileProject(page)) { - await page.getByRole('textbox', { name: '소속' }).blur(); + const textbox = page.getByRole('textbox', { name: '소속' }); + if ((await textbox.count()) > 0) { + await textbox.blur(); await page.waitForTimeout(250); return; } + if (isMobileProject(page)) { + throw new Error('Department textbox was not found.'); + } const coords = coordsFor(page); await page.locator('flt-glass-pane').click({ position: { x: coords.blurX, y: coords.blurY }, @@ -102,20 +108,28 @@ async function blurDepartmentEditor(page: Page): Promise { } async function submitDepartmentEditor(page: Page): Promise { - if (isMobileProject(page)) { - await page.getByRole('textbox', { name: '소속' }).press('Enter'); + const textbox = page.getByRole('textbox', { name: '소속' }); + if ((await textbox.count()) > 0) { + await textbox.press('Enter'); await page.waitForTimeout(250); return; } + if (isMobileProject(page)) { + throw new Error('Department textbox was not found.'); + } await page.keyboard.press('Enter'); await page.waitForTimeout(250); } async function fillDepartmentField(page: Page, value: string): Promise { - if (isMobileProject(page)) { - await page.getByRole('textbox', { name: '소속' }).fill(value); + const textbox = page.getByRole('textbox', { name: '소속' }); + if ((await textbox.count()) > 0) { + await textbox.fill(value); return; } + if (isMobileProject(page)) { + throw new Error('Department textbox was not found.'); + } const coords = coordsFor(page); await fillAt(page, coords.departmentInputX, coords.departmentInputY, value); } @@ -216,6 +230,7 @@ async function mockProfileApis(page: Page, state: ProfileState): Promise { async function openProfilePage(page: Page): Promise { await page.goto('/ko/profile'); await expect(page).toHaveURL(/\/ko\/profile$/); + await enableFlutterAccessibility(page); await page.waitForTimeout(1200); } diff --git a/userfront/lib/main.dart b/userfront/lib/main.dart index d3093393..c35f45f6 100644 --- a/userfront/lib/main.dart +++ b/userfront/lib/main.dart @@ -3,7 +3,6 @@ import 'dart:async'; import 'dart:convert'; import 'package:flutter/foundation.dart'; -import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:easy_localization/easy_localization.dart' hide tr; @@ -162,20 +161,10 @@ bool _shouldRunStartupSessionRecovery(Uri uri) { return !isPublicAuthPath(path, uri); } -Future _loadRuntimeEnv() async { - for (final fileName in const ['assets/.env', '.env']) { - try { - await dotenv.load(fileName: fileName); - return; - } catch (_) {} - } -} - void main() async { WidgetsFlutterBinding.ensureInitialized(); usePathUrlStrategy(); await EasyLocalization.ensureInitialized(); - await _loadRuntimeEnv(); LocaleRegistry.primeWithDefaults(); // 1. Global Error Handling diff --git a/userfront/pubspec.lock b/userfront/pubspec.lock index 238c821f..5a7fb7b9 100644 --- a/userfront/pubspec.lock +++ b/userfront/pubspec.lock @@ -45,10 +45,10 @@ packages: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" cli_config: dependency: transitive description: @@ -276,14 +276,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.5" - js: - dependency: transitive - description: - name: js - sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" - url: "https://pub.dev" - source: hosted - version: "0.7.2" leak_tracker: dependency: transitive description: @@ -336,18 +328,18 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.19" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" url: "https://pub.dev" source: hosted - version: "0.11.1" + version: "0.13.0" meta: dependency: transitive description: @@ -669,26 +661,26 @@ packages: dependency: transitive description: name: test - sha256: "75906bf273541b676716d1ca7627a17e4c4070a3a16272b7a3dc7da3b9f3f6b7" + sha256: "280d6d890011ca966ad08df7e8a4ddfab0fb3aa49f96ed6de56e3521347a9ae7" url: "https://pub.dev" source: hosted - version: "1.26.3" + version: "1.30.0" test_api: dependency: transitive description: name: test_api - sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 + sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" url: "https://pub.dev" source: hosted - version: "0.7.7" + version: "0.7.10" test_core: dependency: transitive description: name: test_core - sha256: "0cc24b5ff94b38d2ae73e1eb43cc302b77964fbf67abad1e296025b78deb53d0" + sha256: "0381bd1585d1a924763c308100f2138205252fb90c9d4eeaf28489ee65ccde51" url: "https://pub.dev" source: hosted - version: "0.6.12" + version: "0.6.16" toml: dependency: "direct main" description: