mirror of
https://github.com/moghtech/komodo.git
synced 2025-12-05 19:17:36 -06:00
* start 1.19.4 * deploy 1.19.4-dev-1 * try smaller binaries with cargo strip * deploy 1.19.4-dev-2 * smaller binaries with cargo strip * Fix Submit Dialog Button Behavior with 500 Errors on Duplicate Names (#819) * Implement enhanced error handling and messaging for resource creation * Implement improved error handling for resource creation across alerter, build, and sync * Implement error handling improvements for resource copying and validation feedback * Adjust error handling for resource creation to distinguish validation errors from unexpected system errors * Refactor resource creation error handling by removing redundant match statements and simplifying the error propagation in multiple API modules. * fmt * bump indexmap * fix account selector showing empty when account no longer found * clean up theme logic, ensure monaco and others get up to date current theme * enforce disable_non_admin_create for tags. Clean up status code responses * update server cache concurrency controller * deploy 1.19.4-dev-3 * Allow signing in by pressing enter (#830) * Improve dialog overflow handling to prevent clipping of content (#828) * Add Email notification entry to community.md (#824) * Add clickable file path to show/hide file contents in StackInfo (#827) * add clickable file path to show/hide file contents in StackInfo Also added CopyButton due to the new functionality making the file path not selectable. * Move clicking interaction to CardHeader * Avoid sync edge cases of having toggle show function capturing showContents from outside Co-authored-by: Maxwell Becker <49575486+mbecker20@users.noreply.github.com> * Format previous change * Add `default_show_contents` to `handleToggleShow` --------- Co-authored-by: Maxwell Becker <49575486+mbecker20@users.noreply.github.com> * deploy 1.19.4-dev-4 * avoid stake info ShowHideButton double toggle * Allow multiple simultaneous Action runs for use with Args * deploy 1.19.4-dev-5 * feat: persist all table sorting states including unsorted (#832) - Always save sorting state to localStorage, even when empty/unsorted - Fixes issue where 'unsorted' state was not persisted across page reloads - Ensures consistent and predictable sorting behavior for all DataTable components * autofocus on login username field (#837) * Fix unnecessary auth queries flooding console on login page (#842) * Refactor authentication error handling to use serror::Result and status codes * Enable user query only when JWT is present * Enable query execution in useRead only if JWT is present * Revert backend auth changes - keep PR focused on frontend only * Fix unnecessary API queries to unreachable servers flooding console (#843) * Implement server availability checks in various components * Refactor server availability check to ensure only healthy servers are identified * cargo fmt * fmt * Auth error handling with status codes (#841) * Refactor authentication error handling to use serror::Result and status codes * Refactor error messages * Refactor authentication error handling to include status codes and improve error messages * clean up * clean * fmt * invalid user id also UNAUTHORIZED * deploy 1.19.4-dev-6 * deploy 1.19.4-dev-7 --------- Co-authored-by: Marcel Pfennig <82059270+MP-Tool@users.noreply.github.com> Co-authored-by: jack <45038833+jackra1n@users.noreply.github.com> Co-authored-by: Guten <ywzhaifei@gmail.com> Co-authored-by: Paulo Roberto Albuquerque <paulora2405@gmail.com> Co-authored-by: Lorenzo Farnararo <2814802+baldarn@users.noreply.github.com>
165 lines
4.8 KiB
TypeScript
165 lines
4.8 KiB
TypeScript
import { ActionWithDialog, StatusBadge } from "@components/util";
|
|
import { useExecute, useRead } from "@lib/hooks";
|
|
import { RequiredResourceComponents } from "@types";
|
|
import { Clapperboard, Clock } from "lucide-react";
|
|
import { ActionConfig } from "./config";
|
|
import { ActionTable } from "./table";
|
|
import { DeleteResource, NewResource, ResourcePageHeader } from "../common";
|
|
import {
|
|
action_state_intention,
|
|
stroke_color_class_by_intention,
|
|
} from "@lib/color";
|
|
import { cn, updateLogToHtml } from "@lib/utils";
|
|
import { Types } from "komodo_client";
|
|
import { DashboardPieChart } from "@pages/home/dashboard";
|
|
import { GroupActions } from "@components/group-actions";
|
|
import { Tooltip, TooltipContent, TooltipTrigger } from "@ui/tooltip";
|
|
import { Card } from "@ui/card";
|
|
|
|
const useAction = (id?: string) =>
|
|
useRead("ListActions", {}).data?.find((d) => d.id === id);
|
|
|
|
const ActionIcon = ({ id, size }: { id?: string; size: number }) => {
|
|
const state = useAction(id)?.info.state;
|
|
const color = stroke_color_class_by_intention(action_state_intention(state));
|
|
return <Clapperboard className={cn(`w-${size} h-${size}`, state && color)} />;
|
|
};
|
|
|
|
export const ActionComponents: RequiredResourceComponents = {
|
|
list_item: (id) => useAction(id),
|
|
resource_links: () => undefined,
|
|
|
|
Description: () => <>Custom scripts using the Komodo client.</>,
|
|
|
|
Dashboard: () => {
|
|
const summary = useRead("GetActionsSummary", {}).data;
|
|
return (
|
|
<DashboardPieChart
|
|
data={[
|
|
{ title: "Ok", intention: "Good", value: summary?.ok ?? 0 },
|
|
{
|
|
title: "Running",
|
|
intention: "Warning",
|
|
value: summary?.running ?? 0,
|
|
},
|
|
{
|
|
title: "Failed",
|
|
intention: "Critical",
|
|
value: summary?.failed ?? 0,
|
|
},
|
|
{
|
|
title: "Unknown",
|
|
intention: "Unknown",
|
|
value: summary?.unknown ?? 0,
|
|
},
|
|
]}
|
|
/>
|
|
);
|
|
},
|
|
|
|
New: () => <NewResource type="Action" />,
|
|
|
|
GroupActions: () => <GroupActions type="Action" actions={["RunAction"]} />,
|
|
|
|
Table: ({ resources }) => (
|
|
<ActionTable actions={resources as Types.ActionListItem[]} />
|
|
),
|
|
|
|
Icon: ({ id }) => <ActionIcon id={id} size={4} />,
|
|
BigIcon: ({ id }) => <ActionIcon id={id} size={8} />,
|
|
|
|
State: ({ id }) => {
|
|
let state = useAction(id)?.info.state;
|
|
return <StatusBadge text={state} intent={action_state_intention(state)} />;
|
|
},
|
|
|
|
Status: {},
|
|
|
|
Info: {
|
|
Schedule: ({ id }) => {
|
|
const next_scheduled_run = useAction(id)?.info.next_scheduled_run;
|
|
return (
|
|
<div className="flex gap-2 items-center">
|
|
<Clock className="w-4 h-4" />
|
|
Next Run:
|
|
<div className="font-bold">
|
|
{next_scheduled_run
|
|
? new Date(next_scheduled_run).toLocaleString()
|
|
: "Not Scheduled"}
|
|
</div>
|
|
</div>
|
|
);
|
|
},
|
|
ScheduleErrors: ({ id }) => {
|
|
const error = useAction(id)?.info.schedule_error;
|
|
if (!error) {
|
|
return null;
|
|
}
|
|
return (
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Card className="px-3 py-2 bg-destructive/75 hover:bg-destructive transition-colors cursor-pointer">
|
|
<div className="text-sm text-nowrap overflow-hidden overflow-ellipsis">
|
|
Schedule Error
|
|
</div>
|
|
</Card>
|
|
</TooltipTrigger>
|
|
<TooltipContent className="w-[400px]">
|
|
<pre
|
|
dangerouslySetInnerHTML={{
|
|
__html: updateLogToHtml(error),
|
|
}}
|
|
className="max-h-[500px] overflow-y-auto"
|
|
/>
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
);
|
|
},
|
|
},
|
|
|
|
Actions: {
|
|
RunAction: ({ id }) => {
|
|
const running =
|
|
(useRead(
|
|
"GetActionActionState",
|
|
{ action: id },
|
|
{ refetchInterval: 5000 }
|
|
).data?.running ?? 0) > 0;
|
|
const { mutate, isPending } = useExecute("RunAction");
|
|
const action = useAction(id);
|
|
if (!action) return null;
|
|
return (
|
|
<ActionWithDialog
|
|
name={action.name}
|
|
title={running ? "Running" : "Run Action"}
|
|
icon={<Clapperboard className="h-4 w-4" />}
|
|
onClick={() => mutate({ action: id, args: {} })}
|
|
disabled={running || isPending}
|
|
loading={running}
|
|
/>
|
|
);
|
|
},
|
|
},
|
|
|
|
Page: {},
|
|
|
|
Config: ActionConfig,
|
|
|
|
DangerZone: ({ id }) => <DeleteResource type="Action" id={id} />,
|
|
|
|
ResourcePageHeader: ({ id }) => {
|
|
const action = useAction(id);
|
|
return (
|
|
<ResourcePageHeader
|
|
intent={action_state_intention(action?.info.state)}
|
|
icon={<ActionIcon id={id} size={8} />}
|
|
type="Action"
|
|
id={id}
|
|
resource={action}
|
|
state={action?.info.state}
|
|
status={undefined}
|
|
/>
|
|
);
|
|
},
|
|
};
|