forked from baron/baron-sso
정렬 헤더 UI 공통화 및 devfront secret 표시 수정
This commit is contained in:
@@ -2,9 +2,6 @@ import { useInfiniteQuery, useMutation, useQuery } from "@tanstack/react-query";
|
|||||||
import { useVirtualizer } from "@tanstack/react-virtual";
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
||||||
import type { AxiosError } from "axios";
|
import type { AxiosError } from "axios";
|
||||||
import {
|
import {
|
||||||
ArrowDown,
|
|
||||||
ArrowUp,
|
|
||||||
ArrowUpDown,
|
|
||||||
Building2,
|
Building2,
|
||||||
ChevronDown,
|
ChevronDown,
|
||||||
ChevronRight,
|
ChevronRight,
|
||||||
@@ -22,6 +19,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 { SortableTableHead } from "../../../../../common/core/components/sort";
|
||||||
import {
|
import {
|
||||||
type SortConfig,
|
type SortConfig,
|
||||||
type SortResolverMap,
|
type SortResolverMap,
|
||||||
@@ -513,17 +511,6 @@ function TenantListPage() {
|
|||||||
setSortConfig((current) => toggleSort(current, key));
|
setSortConfig((current) => toggleSort(current, key));
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSortIcon = (key: TenantSortKey) => {
|
|
||||||
if (!sortConfig || sortConfig.key !== key) {
|
|
||||||
return <ArrowUpDown size={14} className="ml-1 opacity-50" />;
|
|
||||||
}
|
|
||||||
return sortConfig.direction === "asc" ? (
|
|
||||||
<ArrowUp size={14} className="ml-1" />
|
|
||||||
) : (
|
|
||||||
<ArrowDown size={14} className="ml-1" />
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const deletableTenants = React.useMemo(
|
const deletableTenants = React.useMemo(
|
||||||
() => tenants.filter((tenant) => !isSeedTenant(tenant)),
|
() => tenants.filter((tenant) => !isSeedTenant(tenant)),
|
||||||
[tenants],
|
[tenants],
|
||||||
@@ -977,69 +964,55 @@ function TenantListPage() {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableHead
|
<SortableTableHead
|
||||||
className="min-w-[220px] cursor-pointer hover:bg-muted/50 transition-colors whitespace-nowrap"
|
className="min-w-[220px] whitespace-nowrap text-foreground sticky top-0 bg-inherit"
|
||||||
onClick={() => requestSort("id")}
|
label={t("ui.admin.tenants.table.id", "ID")}
|
||||||
>
|
onSort={requestSort}
|
||||||
<div className="flex items-center">
|
sortConfig={sortConfig}
|
||||||
{t("ui.admin.tenants.table.id", "ID")}
|
sortKey="id"
|
||||||
{getSortIcon("id")}
|
/>
|
||||||
</div>
|
<SortableTableHead
|
||||||
</TableHead>
|
className="whitespace-nowrap text-foreground sticky top-0 bg-inherit"
|
||||||
<TableHead
|
label={t("ui.admin.tenants.table.name", "NAME")}
|
||||||
className="cursor-pointer hover:bg-muted/50 transition-colors whitespace-nowrap"
|
onSort={requestSort}
|
||||||
onClick={() => requestSort("name")}
|
sortConfig={sortConfig}
|
||||||
>
|
sortKey="name"
|
||||||
<div className="flex items-center">
|
/>
|
||||||
{t("ui.admin.tenants.table.name", "NAME")}
|
<SortableTableHead
|
||||||
{getSortIcon("name")}
|
className="whitespace-nowrap text-foreground sticky top-0 bg-inherit"
|
||||||
</div>
|
label={t("ui.admin.tenants.table.type", "TYPE")}
|
||||||
</TableHead>
|
onSort={requestSort}
|
||||||
<TableHead
|
sortConfig={sortConfig}
|
||||||
className="cursor-pointer hover:bg-muted/50 transition-colors whitespace-nowrap"
|
sortKey="type"
|
||||||
onClick={() => requestSort("type")}
|
/>
|
||||||
>
|
<SortableTableHead
|
||||||
<div className="flex items-center">
|
className="whitespace-nowrap text-foreground sticky top-0 bg-inherit"
|
||||||
{t("ui.admin.tenants.table.type", "TYPE")}
|
label={t("ui.admin.tenants.table.slug", "SLUG")}
|
||||||
{getSortIcon("type")}
|
onSort={requestSort}
|
||||||
</div>
|
sortConfig={sortConfig}
|
||||||
</TableHead>
|
sortKey="slug"
|
||||||
<TableHead
|
/>
|
||||||
className="cursor-pointer hover:bg-muted/50 transition-colors whitespace-nowrap"
|
<SortableTableHead
|
||||||
onClick={() => requestSort("slug")}
|
className="whitespace-nowrap text-foreground sticky top-0 bg-inherit"
|
||||||
>
|
label={t("ui.admin.tenants.table.status", "STATUS")}
|
||||||
<div className="flex items-center">
|
onSort={requestSort}
|
||||||
{t("ui.admin.tenants.table.slug", "SLUG")}
|
sortConfig={sortConfig}
|
||||||
{getSortIcon("slug")}
|
sortKey="status"
|
||||||
</div>
|
/>
|
||||||
</TableHead>
|
<SortableTableHead
|
||||||
<TableHead
|
className="whitespace-nowrap text-foreground sticky top-0 bg-inherit"
|
||||||
className="cursor-pointer hover:bg-muted/50 transition-colors whitespace-nowrap"
|
label={t("ui.admin.tenants.table.members", "MEMBERS")}
|
||||||
onClick={() => requestSort("status")}
|
onSort={requestSort}
|
||||||
>
|
sortConfig={sortConfig}
|
||||||
<div className="flex items-center">
|
sortKey="recursiveMemberCount"
|
||||||
{t("ui.admin.tenants.table.status", "STATUS")}
|
/>
|
||||||
{getSortIcon("status")}
|
<SortableTableHead
|
||||||
</div>
|
className="whitespace-nowrap text-foreground sticky top-0 bg-inherit"
|
||||||
</TableHead>
|
label={t("ui.admin.tenants.table.updated", "UPDATED")}
|
||||||
<TableHead
|
onSort={requestSort}
|
||||||
className="cursor-pointer hover:bg-muted/50 transition-colors whitespace-nowrap"
|
sortConfig={sortConfig}
|
||||||
onClick={() => requestSort("recursiveMemberCount")}
|
sortKey="updatedAt"
|
||||||
>
|
/>
|
||||||
<div className="flex items-center">
|
|
||||||
{t("ui.admin.tenants.table.members", "MEMBERS")}
|
|
||||||
{getSortIcon("recursiveMemberCount")}
|
|
||||||
</div>
|
|
||||||
</TableHead>
|
|
||||||
<TableHead
|
|
||||||
className="cursor-pointer hover:bg-muted/50 transition-colors whitespace-nowrap"
|
|
||||||
onClick={() => requestSort("updatedAt")}
|
|
||||||
>
|
|
||||||
<div className="flex items-center">
|
|
||||||
{t("ui.admin.tenants.table.updated", "UPDATED")}
|
|
||||||
{getSortIcon("updatedAt")}
|
|
||||||
</div>
|
|
||||||
</TableHead>
|
|
||||||
<TableHead className="whitespace-nowrap">
|
<TableHead className="whitespace-nowrap">
|
||||||
{t("ui.common.actions", "액션")}
|
{t("ui.common.actions", "액션")}
|
||||||
</TableHead>
|
</TableHead>
|
||||||
|
|||||||
@@ -15,6 +15,13 @@
|
|||||||
"moduleDetection": "force",
|
"moduleDetection": "force",
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"jsx": "react-jsx",
|
"jsx": "react-jsx",
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"lucide-react": ["./node_modules/lucide-react"],
|
||||||
|
"react": ["./node_modules/@types/react/index.d.ts"],
|
||||||
|
"react/jsx-dev-runtime": ["./node_modules/@types/react/jsx-dev-runtime.d.ts"],
|
||||||
|
"react/jsx-runtime": ["./node_modules/@types/react/jsx-runtime.d.ts"]
|
||||||
|
},
|
||||||
|
|
||||||
/* Linting */
|
/* Linting */
|
||||||
"strict": true,
|
"strict": true,
|
||||||
@@ -24,6 +31,6 @@
|
|||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
"noUncheckedSideEffectImports": true
|
"noUncheckedSideEffectImports": true
|
||||||
},
|
},
|
||||||
"include": ["src"],
|
"include": ["src", "../common/**/*.ts", "../common/**/*.tsx"],
|
||||||
"exclude": ["src/**/*.test.ts", "src/**/*.test.tsx"]
|
"exclude": ["src/**/*.test.ts", "src/**/*.test.tsx"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import react from "@vitejs/plugin-react";
|
import react from "@vitejs/plugin-react";
|
||||||
|
import path from "node:path";
|
||||||
import { defineConfig } from "vite";
|
import { defineConfig } from "vite";
|
||||||
|
|
||||||
const buildOutDir =
|
const buildOutDir =
|
||||||
@@ -6,6 +7,20 @@ const buildOutDir =
|
|||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
"lucide-react": path.resolve(__dirname, "node_modules/lucide-react"),
|
||||||
|
react: path.resolve(__dirname, "node_modules/react"),
|
||||||
|
"react/jsx-dev-runtime": path.resolve(
|
||||||
|
__dirname,
|
||||||
|
"node_modules/react/jsx-dev-runtime.js",
|
||||||
|
),
|
||||||
|
"react/jsx-runtime": path.resolve(
|
||||||
|
__dirname,
|
||||||
|
"node_modules/react/jsx-runtime.js",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
envPrefix: ["VITE_", "USERFRONT_", "ORGFRONT_"],
|
envPrefix: ["VITE_", "USERFRONT_", "ORGFRONT_"],
|
||||||
cacheDir:
|
cacheDir:
|
||||||
process.env.ADMINFRONT_VITE_CACHE_DIR ??
|
process.env.ADMINFRONT_VITE_CACHE_DIR ??
|
||||||
|
|||||||
158
common/core/components/sort/SortableTableHead.tsx
Normal file
158
common/core/components/sort/SortableTableHead.tsx
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
import type { ReactNode, ThHTMLAttributes } from "react";
|
||||||
|
import type { SortConfig } from "../../utils";
|
||||||
|
|
||||||
|
function SortAscendingIcon() {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
className="h-4 w-4"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
>
|
||||||
|
<path d="m12 5-5 5" />
|
||||||
|
<path d="m12 5 5 5" />
|
||||||
|
<path d="M12 19V5" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SortDescendingIcon() {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
className="h-4 w-4"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
>
|
||||||
|
<path d="m12 19-5-5" />
|
||||||
|
<path d="m12 19 5-5" />
|
||||||
|
<path d="M12 5v14" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SortIdleIcon() {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
className="h-4 w-4 opacity-50"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="2"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
>
|
||||||
|
<path d="m7 15 5 5 5-5" />
|
||||||
|
<path d="m7 9 5-5 5 5" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
type SortableTableHeadAlign = "left" | "center" | "right";
|
||||||
|
|
||||||
|
function alignClassName(align: SortableTableHeadAlign) {
|
||||||
|
switch (align) {
|
||||||
|
case "center":
|
||||||
|
return "text-center";
|
||||||
|
case "right":
|
||||||
|
return "text-right";
|
||||||
|
default:
|
||||||
|
return "text-left";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function buttonAlignClassName(align: SortableTableHeadAlign) {
|
||||||
|
switch (align) {
|
||||||
|
case "center":
|
||||||
|
return "justify-center";
|
||||||
|
case "right":
|
||||||
|
return "justify-end";
|
||||||
|
default:
|
||||||
|
return "justify-start";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortAriaValue(
|
||||||
|
isActive: boolean,
|
||||||
|
direction: "asc" | "desc" | null,
|
||||||
|
): ThHTMLAttributes<HTMLTableCellElement>["aria-sort"] {
|
||||||
|
if (!isActive || direction === null) {
|
||||||
|
return "none";
|
||||||
|
}
|
||||||
|
return direction === "asc" ? "ascending" : "descending";
|
||||||
|
}
|
||||||
|
|
||||||
|
type SortableTableHeadProps<Key extends string> = Omit<
|
||||||
|
ThHTMLAttributes<HTMLTableCellElement>,
|
||||||
|
"children"
|
||||||
|
> & {
|
||||||
|
align?: SortableTableHeadAlign;
|
||||||
|
contentClassName?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
label: ReactNode;
|
||||||
|
onSort: (key: Key) => void;
|
||||||
|
sortConfig: SortConfig<Key> | null;
|
||||||
|
sortKey: Key;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function SortableTableHead<Key extends string>({
|
||||||
|
align = "left",
|
||||||
|
className = "",
|
||||||
|
contentClassName = "",
|
||||||
|
disabled = false,
|
||||||
|
label,
|
||||||
|
onSort,
|
||||||
|
sortConfig,
|
||||||
|
sortKey,
|
||||||
|
...props
|
||||||
|
}: SortableTableHeadProps<Key>) {
|
||||||
|
const isActive = sortConfig?.key === sortKey;
|
||||||
|
const direction = isActive ? sortConfig?.direction ?? null : null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<th
|
||||||
|
aria-sort={sortAriaValue(isActive, direction)}
|
||||||
|
className={[
|
||||||
|
"h-12 px-6 text-xs font-bold uppercase tracking-[0.08em] align-middle",
|
||||||
|
alignClassName(align),
|
||||||
|
disabled ? "" : "transition-colors hover:bg-muted/50",
|
||||||
|
className,
|
||||||
|
]
|
||||||
|
.filter(Boolean)
|
||||||
|
.join(" ")}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => onSort(sortKey)}
|
||||||
|
disabled={disabled}
|
||||||
|
className={[
|
||||||
|
"flex w-full items-center gap-1",
|
||||||
|
buttonAlignClassName(align),
|
||||||
|
disabled ? "cursor-default opacity-70" : "cursor-pointer",
|
||||||
|
contentClassName,
|
||||||
|
]
|
||||||
|
.filter(Boolean)
|
||||||
|
.join(" ")}
|
||||||
|
>
|
||||||
|
<span>{label}</span>
|
||||||
|
{direction === "asc" ? (
|
||||||
|
<SortAscendingIcon />
|
||||||
|
) : direction === "desc" ? (
|
||||||
|
<SortDescendingIcon />
|
||||||
|
) : (
|
||||||
|
<SortIdleIcon />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</th>
|
||||||
|
);
|
||||||
|
}
|
||||||
1
common/core/components/sort/index.ts
Normal file
1
common/core/components/sort/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from "./SortableTableHead";
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
import type { AxiosError } from "axios";
|
import type { AxiosError } from "axios";
|
||||||
import {
|
import {
|
||||||
ArrowDown,
|
|
||||||
ArrowUp,
|
|
||||||
ArrowUpDown,
|
|
||||||
BookOpenText,
|
BookOpenText,
|
||||||
Filter,
|
Filter,
|
||||||
Plus,
|
Plus,
|
||||||
@@ -13,6 +10,7 @@ import {
|
|||||||
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 { SortableTableHead } from "../../../../common/core/components/sort";
|
||||||
import {
|
import {
|
||||||
type SortConfig,
|
type SortConfig,
|
||||||
type SortResolverMap,
|
type SortResolverMap,
|
||||||
@@ -230,18 +228,6 @@ function ClientsPage() {
|
|||||||
setSortConfig((current) => toggleSort(current, key));
|
setSortConfig((current) => toggleSort(current, key));
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSortIcon = (key: ClientSortKey) => {
|
|
||||||
if (!sortConfig || sortConfig.key !== key) {
|
|
||||||
return <ArrowUpDown className="ml-1 h-4 w-4 opacity-50" />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sortConfig.direction === "asc" ? (
|
|
||||||
<ArrowUp className="ml-1 h-4 w-4" />
|
|
||||||
) : (
|
|
||||||
<ArrowDown className="ml-1 h-4 w-4" />
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (auth.isLoading || !hasAccessToken || isLoading) {
|
if (auth.isLoading || !hasAccessToken || isLoading) {
|
||||||
return (
|
return (
|
||||||
<div className="p-8 text-center">
|
<div className="p-8 text-center">
|
||||||
@@ -452,51 +438,41 @@ function ClientsPage() {
|
|||||||
<Table>
|
<Table>
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableHead
|
<SortableTableHead
|
||||||
className="cursor-pointer hover:bg-muted/50 transition-colors"
|
className="text-muted-foreground"
|
||||||
onClick={() => requestSort("application")}
|
label={t("ui.dev.clients.table.application", "애플리케이션")}
|
||||||
>
|
onSort={requestSort}
|
||||||
<div className="flex items-center">
|
sortConfig={sortConfig}
|
||||||
{t("ui.dev.clients.table.application", "애플리케이션")}
|
sortKey="application"
|
||||||
{getSortIcon("application")}
|
/>
|
||||||
</div>
|
<SortableTableHead
|
||||||
</TableHead>
|
className="text-muted-foreground"
|
||||||
<TableHead
|
label={t("ui.dev.clients.table.client_id", "Client ID")}
|
||||||
className="cursor-pointer hover:bg-muted/50 transition-colors"
|
onSort={requestSort}
|
||||||
onClick={() => requestSort("id")}
|
sortConfig={sortConfig}
|
||||||
>
|
sortKey="id"
|
||||||
<div className="flex items-center">
|
/>
|
||||||
{t("ui.dev.clients.table.client_id", "Client ID")}
|
<SortableTableHead
|
||||||
{getSortIcon("id")}
|
className="text-muted-foreground"
|
||||||
</div>
|
label={t("ui.dev.clients.table.type", "유형")}
|
||||||
</TableHead>
|
onSort={requestSort}
|
||||||
<TableHead
|
sortConfig={sortConfig}
|
||||||
className="cursor-pointer hover:bg-muted/50 transition-colors"
|
sortKey="type"
|
||||||
onClick={() => requestSort("type")}
|
/>
|
||||||
>
|
<SortableTableHead
|
||||||
<div className="flex items-center">
|
className="text-muted-foreground"
|
||||||
{t("ui.dev.clients.table.type", "유형")}
|
label={t("ui.dev.clients.table.status", "상태")}
|
||||||
{getSortIcon("type")}
|
onSort={requestSort}
|
||||||
</div>
|
sortConfig={sortConfig}
|
||||||
</TableHead>
|
sortKey="status"
|
||||||
<TableHead
|
/>
|
||||||
className="cursor-pointer hover:bg-muted/50 transition-colors"
|
<SortableTableHead
|
||||||
onClick={() => requestSort("status")}
|
className="text-muted-foreground"
|
||||||
>
|
label={t("ui.dev.clients.table.created_at", "생성일")}
|
||||||
<div className="flex items-center">
|
onSort={requestSort}
|
||||||
{t("ui.dev.clients.table.status", "상태")}
|
sortConfig={sortConfig}
|
||||||
{getSortIcon("status")}
|
sortKey="createdAt"
|
||||||
</div>
|
/>
|
||||||
</TableHead>
|
|
||||||
<TableHead
|
|
||||||
className="cursor-pointer hover:bg-muted/50 transition-colors"
|
|
||||||
onClick={() => requestSort("createdAt")}
|
|
||||||
>
|
|
||||||
<div className="flex items-center">
|
|
||||||
{t("ui.dev.clients.table.created_at", "생성일")}
|
|
||||||
{getSortIcon("createdAt")}
|
|
||||||
</div>
|
|
||||||
</TableHead>
|
|
||||||
<TableHead className="text-right">
|
<TableHead className="text-right">
|
||||||
{t("ui.dev.clients.table.actions", "액션")}
|
{t("ui.dev.clients.table.actions", "액션")}
|
||||||
</TableHead>
|
</TableHead>
|
||||||
|
|||||||
@@ -15,6 +15,13 @@
|
|||||||
"moduleDetection": "force",
|
"moduleDetection": "force",
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"jsx": "react-jsx",
|
"jsx": "react-jsx",
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"lucide-react": ["./node_modules/lucide-react"],
|
||||||
|
"react": ["./node_modules/@types/react/index.d.ts"],
|
||||||
|
"react/jsx-dev-runtime": ["./node_modules/@types/react/jsx-dev-runtime.d.ts"],
|
||||||
|
"react/jsx-runtime": ["./node_modules/@types/react/jsx-runtime.d.ts"]
|
||||||
|
},
|
||||||
|
|
||||||
/* Linting */
|
/* Linting */
|
||||||
"strict": true,
|
"strict": true,
|
||||||
@@ -24,6 +31,6 @@
|
|||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
"noUncheckedSideEffectImports": true
|
"noUncheckedSideEffectImports": true
|
||||||
},
|
},
|
||||||
"include": ["src"],
|
"include": ["src", "../common/**/*.ts", "../common/**/*.tsx"],
|
||||||
"exclude": ["src/**/*.test.ts", "src/**/*.test.tsx"]
|
"exclude": ["src/**/*.test.ts", "src/**/*.test.tsx"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import react from "@vitejs/plugin-react";
|
import react from "@vitejs/plugin-react";
|
||||||
|
import path from "node:path";
|
||||||
import { defineConfig } from "vite";
|
import { defineConfig } from "vite";
|
||||||
|
|
||||||
const buildOutDir =
|
const buildOutDir =
|
||||||
@@ -35,6 +36,20 @@ const allowedHosts = Array.from(
|
|||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
"lucide-react": path.resolve(__dirname, "node_modules/lucide-react"),
|
||||||
|
react: path.resolve(__dirname, "node_modules/react"),
|
||||||
|
"react/jsx-dev-runtime": path.resolve(
|
||||||
|
__dirname,
|
||||||
|
"node_modules/react/jsx-dev-runtime.js",
|
||||||
|
),
|
||||||
|
"react/jsx-runtime": path.resolve(
|
||||||
|
__dirname,
|
||||||
|
"node_modules/react/jsx-runtime.js",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
cacheDir:
|
cacheDir:
|
||||||
process.env.DEVFRONT_VITE_CACHE_DIR ?? "/tmp/baron-sso-devfront-vite-cache",
|
process.env.DEVFRONT_VITE_CACHE_DIR ?? "/tmp/baron-sso-devfront-vite-cache",
|
||||||
build: {
|
build: {
|
||||||
|
|||||||
Reference in New Issue
Block a user