1
0
forked from baron/baron-sso

ci: add code check badges and coverage reports

This commit is contained in:
2026-05-29 12:05:43 +09:00
parent c489c7c38f
commit a830242947
164 changed files with 9059 additions and 2012 deletions

View File

@@ -1,17 +1,8 @@
import { ChevronDown, ChevronUp, Copy } from "lucide-react";
import * as React from "react";
import type { CommonAuditLog } from "../../audit";
import {
formatAuditDateParts,
formatAuditValue,
parseAuditDetails,
resolveAuditAction,
resolveAuditActor,
resolveAuditTarget,
} from "../../audit";
import {
getCommonBadgeClasses,
type CommonBadgeVariant,
getCommonBadgeClasses,
} from "../../../ui/badge";
import { getCommonButtonClasses } from "../../../ui/button";
import {
@@ -26,6 +17,15 @@ import {
commonTableViewportClass,
commonTableWrapperClass,
} from "../../../ui/table";
import type { CommonAuditLog } from "../../audit";
import {
formatAuditDateParts,
formatAuditValue,
parseAuditDetails,
resolveAuditAction,
resolveAuditActor,
resolveAuditTarget,
} from "../../audit";
type AuditTranslate = (
key: string,
@@ -77,7 +77,10 @@ export function AuditLogTable({
<div className={commonTableWrapperClass}>
<table className={cx(commonTableClass, "table-fixed")}>
<thead
className={cx(commonTableHeaderClass, commonStickyTableHeaderClass)}
className={cx(
commonTableHeaderClass,
commonStickyTableHeaderClass,
)}
>
<tr className={commonTableRowClass}>
<th className={cx(commonTableHeadClass, "w-[190px]")}>
@@ -115,7 +118,10 @@ export function AuditLogTable({
<tr className={commonTableRowClass}>
<td
colSpan={6}
className={cx(commonTableCellClass, "text-center text-muted-foreground")}
className={cx(
commonTableCellClass,
"text-center text-muted-foreground",
)}
>
{t("msg.common.audit.empty", "No audit logs found.")}
</td>
@@ -132,7 +138,12 @@ export function AuditLogTable({
return (
<React.Fragment key={rowKey}>
<tr className={cx(commonTableRowClass, "bg-card/40")}>
<td className={cx(commonTableCellClass, "text-xs text-muted-foreground")}>
<td
className={cx(
commonTableCellClass,
"text-xs text-muted-foreground",
)}
>
<div className="space-y-1">
<div>{date}</div>
<div>{time}</div>
@@ -165,14 +176,20 @@ export function AuditLogTable({
</div>
</td>
<td
className={cx(commonTableCellClass, "text-xs text-muted-foreground")}
className={cx(
commonTableCellClass,
"text-xs text-muted-foreground",
)}
>
<div className="font-semibold text-foreground">
{actionLabel}
</div>
</td>
<td
className={cx(commonTableCellClass, "text-xs text-muted-foreground")}
className={cx(
commonTableCellClass,
"text-xs text-muted-foreground",
)}
>
<div className="flex items-center gap-2">
<span className="break-all">{targetLabel}</span>
@@ -230,18 +247,26 @@ export function AuditLogTable({
</tr>
{expanded ? (
<tr className={cx(commonTableRowClass, "bg-card/20")}>
<td colSpan={6} className={cx(commonTableCellClass, "text-xs")}>
<td
colSpan={6}
className={cx(commonTableCellClass, "text-xs")}
>
<div className="grid gap-4 text-muted-foreground md:grid-cols-3">
<div className="space-y-1">
<div className="uppercase tracking-[0.16em]">
{t("ui.common.audit.details.request", "Request")}
{t(
"ui.common.audit.details.request",
"Request",
)}
</div>
<div className="break-all">
{t(
"ui.common.audit.details.request_id",
"Request ID · {{value}}",
{
value: formatAuditValue(details.request_id),
value: formatAuditValue(
details.request_id,
),
},
)}
</div>
@@ -255,9 +280,13 @@ export function AuditLogTable({
)}
</div>
<div>
{t("ui.common.audit.details.ip", "IP · {{value}}", {
value: formatAuditValue(row.ip_address),
})}
{t(
"ui.common.audit.details.ip",
"IP · {{value}}",
{
value: formatAuditValue(row.ip_address),
},
)}
</div>
<div className="break-all">
{t(
@@ -306,7 +335,9 @@ export function AuditLogTable({
"ui.common.audit.details.tenant",
"Tenant · {{value}}",
{
value: formatAuditValue(details.tenant_id),
value: formatAuditValue(
details.tenant_id,
),
},
)}
</div>
@@ -329,7 +360,10 @@ export function AuditLogTable({
</div>
<div className="space-y-1">
<div className="uppercase tracking-[0.16em]">
{t("ui.common.audit.details.result", "Result")}
{t(
"ui.common.audit.details.result",
"Result",
)}
</div>
<div className="break-all">
{t(

View File

@@ -1,3 +1,3 @@
export { OverviewMetric } from "./OverviewMetric";
export { OverviewAxisNotes } from "./OverviewAxisNotes";
export { OverviewMetric } from "./OverviewMetric";
export { OverviewSelectionChips } from "./OverviewSelectionChips";

View File

@@ -35,7 +35,7 @@ export function PageHeader({
className={cx(
"flex flex-wrap items-start justify-between gap-4",
sticky &&
"sticky top-[-2.5rem] z-20 -mt-4 bg-background/95 pt-4 pb-2 backdrop-blur",
"sticky top-[-2.5rem] z-20 -mt-4 bg-background/95 pt-4 pb-2 backdrop-blur",
className,
)}
{...props}

View File

@@ -1,15 +1,13 @@
import type { ReactNode, ThHTMLAttributes } from "react";
import type { SortConfig } from "../../utils";
import {
commonStickyTableHeaderClass,
commonTableHeadClass,
} from "../../../ui/table";
import type { SortConfig } from "../../utils";
export const sortableTableHeadBaseClassName =
commonTableHeadClass;
export const sortableTableHeadBaseClassName = commonTableHeadClass;
export const sortableTableHeaderClassName =
commonStickyTableHeaderClass;
export const sortableTableHeaderClassName = commonStickyTableHeaderClass;
function SortAscendingIcon() {
return (
@@ -126,7 +124,7 @@ export function SortableTableHead<Key extends string>({
...props
}: SortableTableHeadProps<Key>) {
const isActive = sortConfig?.key === sortKey;
const direction = isActive ? sortConfig?.direction ?? null : null;
const direction = isActive ? (sortConfig?.direction ?? null) : null;
return (
<th

View File

@@ -2,8 +2,8 @@ export { createTomlTranslator } from "./loader";
export {
DEFAULT_LOCALE,
LOCALE_STORAGE_KEY,
SUPPORTED_LOCALES,
type Locale,
SUPPORTED_LOCALES,
type TomlObject,
type TomlValue,
type TranslatorInput,

View File

@@ -1,8 +1,8 @@
import {
DEFAULT_LOCALE,
LOCALE_STORAGE_KEY,
SUPPORTED_LOCALES,
type Locale,
SUPPORTED_LOCALES,
type TomlObject,
type TomlValue,
type TranslatorInput,
@@ -155,10 +155,16 @@ export function createTomlTranslator(
const translations: Record<Locale, TomlObject> = {
ko: input.ko
.map((raw) => parseToml(raw))
.reduce<TomlObject>((merged, current) => mergeTomlObjects(merged, current), {}),
.reduce<TomlObject>(
(merged, current) => mergeTomlObjects(merged, current),
{},
),
en: input.en
.map((raw) => parseToml(raw))
.reduce<TomlObject>((merged, current) => mergeTomlObjects(merged, current), {}),
.reduce<TomlObject>(
(merged, current) => mergeTomlObjects(merged, current),
{},
),
};
return function t(

View File

@@ -34,9 +34,12 @@ function shouldUseWorker(useWorker: boolean | undefined) {
async function fetchAllCursorPagesInWorker<TItem>(
request: CursorFetchRequest,
): Promise<CursorPageResponse<TItem>> {
const worker = new Worker(new URL("./cursorFetch.worker.ts", import.meta.url), {
type: "module",
});
const worker = new Worker(
new URL("./cursorFetch.worker.ts", import.meta.url),
{
type: "module",
},
);
const id = createRequestId();
return new Promise((resolve, reject) => {

View File

@@ -1,7 +1,7 @@
import {
fetchAllCursorPagesMainThread,
type CursorFetchRequest,
type CursorPageResponse,
fetchAllCursorPagesMainThread,
} from "./cursorFetchCore";
type CursorWorkerRequestMessage = {
@@ -21,23 +21,24 @@ type CursorWorkerResponseMessage<TItem> =
error: string;
};
self.addEventListener("message", async (event: MessageEvent<CursorWorkerRequestMessage>) => {
const { id, request } = event.data;
self.addEventListener(
"message",
async (event: MessageEvent<CursorWorkerRequestMessage>) => {
const { id, request } = event.data;
try {
const response = await fetchAllCursorPagesMainThread(request);
self.postMessage({
id,
ok: true,
response,
} satisfies CursorWorkerResponseMessage<unknown>);
} catch (error) {
self.postMessage({
id,
ok: false,
error: error instanceof Error ? error.message : String(error),
} satisfies CursorWorkerResponseMessage<unknown>);
}
});
export {};
try {
const response = await fetchAllCursorPagesMainThread(request);
self.postMessage({
id,
ok: true,
response,
} satisfies CursorWorkerResponseMessage<unknown>);
} catch (error) {
self.postMessage({
id,
ok: false,
error: error instanceof Error ? error.message : String(error),
} satisfies CursorWorkerResponseMessage<unknown>);
}
},
);

View File

@@ -74,7 +74,9 @@ export async function fetchAllCursorPagesMainThread<TItem>({
});
if (!response.ok) {
throw new Error(`Cursor page request failed with status ${response.status}`);
throw new Error(
`Cursor page request failed with status ${response.status}`,
);
}
const page = (await response.json()) as CursorPageResponse<TItem>;

View File

@@ -1,6 +1,6 @@
export {
fetchAllCursorPages,
fetchAllCursorPagesMainThread,
type CursorFetchRequest,
type CursorPageResponse,
fetchAllCursorPages,
fetchAllCursorPagesMainThread,
} from "./cursorFetch";