diff --git a/Data/Engine/Assemblies/Payloads/cf144e3852574bbfbdff04f7209d20d4/payload.json b/Data/Engine/Assemblies/Payloads/cf144e3852574bbfbdff04f7209d20d4/payload.json index 3d681553..2f839e2c 100644 --- a/Data/Engine/Assemblies/Payloads/cf144e3852574bbfbdff04f7209d20d4/payload.json +++ b/Data/Engine/Assemblies/Payloads/cf144e3852574bbfbdff04f7209d20d4/payload.json @@ -3,7 +3,7 @@ "description": "Deletes Agent and Engine Logs from C:\\Borealis.", "files": [], "name": "Borealis - Delete Logs [WIN]", - "script": "UmVtb3ZlLUl0ZW0gLUxpdGVyYWxQYXRoICdDOlxCb3JlYWxpc1xBZ2VudFxMb2dzJywnQzpcQm9yZWFsaXNcRW5naW5lXExvZ3MnIC1SZWN1cnNlIC1Gb3JjZSAtRXJyb3JBY3Rpb24gU2lsZW50bHlDb250aW51ZQ==", + "script": "UmVtb3ZlLUl0ZW0gLUxpdGVyYWxQYXRoICdDOlxCb3JlYWxpc1xBZ2VudFxMb2dzJywnQzpcQm9yZWFsaXNcRW5naW5lXExvZ3MnIC1SZWN1cnNlIC1Gb3JjZSAtRXJyb3JBY3Rpb24gU2lsZW50bHlDb250aW51ZQpSZW1vdmUtSXRlbSAtTGl0ZXJhbFBhdGggJ0U6XEdpdEh1YlxCb3JlYWxpc1xBZ2VudFxMb2dzJywnRTpcR2l0SHViXEJvcmVhbGlzXEVuZ2luZVxMb2dzJyAtUmVjdXJzZSAtRm9yY2UgLUVycm9yQWN0aW9uIFNpbGVudGx5Q29udGludWU=", "script_encoding": "base64", "sites": { "mode": "all", diff --git a/Data/Engine/Assemblies/user_created.db b/Data/Engine/Assemblies/user_created.db index 356056b1..b6a85116 100644 Binary files a/Data/Engine/Assemblies/user_created.db and b/Data/Engine/Assemblies/user_created.db differ diff --git a/Data/Engine/web-interface/src/Admin/Page_Template.jsx b/Data/Engine/web-interface/src/Admin/Page_Template.jsx index d078c160..8fb52d28 100644 --- a/Data/Engine/web-interface/src/Admin/Page_Template.jsx +++ b/Data/Engine/web-interface/src/Admin/Page_Template.jsx @@ -177,13 +177,10 @@ const SAMPLE_ROWS = [ const selectionCol = { headerName: "", field: "__select__", - cellClass: 'ag-selection-centered', - cellStyle: { display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 0 }, width: 52, maxWidth: 52, checkboxSelection: true, headerCheckboxSelection: true, - headerCheckboxSelectionFilteredOnly: false, resizable: false, sortable: false, suppressMenu: true, diff --git a/Data/Engine/web-interface/src/Scheduling/Scheduled_Jobs_List.jsx b/Data/Engine/web-interface/src/Scheduling/Scheduled_Jobs_List.jsx index 6f92ac84..8e8b7803 100644 --- a/Data/Engine/web-interface/src/Scheduling/Scheduled_Jobs_List.jsx +++ b/Data/Engine/web-interface/src/Scheduling/Scheduled_Jobs_List.jsx @@ -1,4 +1,12 @@ -////////// PROJECT FILE SEPARATION LINE ////////// CODE AFTER THIS LINE ARE FROM: /Data/WebUI/src/Scheduled_Jobs_List.jsx +// ///////////////////////////////////////////////////////////////////////////// +// Scheduled_Jobs_List — Borealis MagicUI styling parity with Page Template +// - Aurora gradient shell +// - Small Material icon LEFT of title +// - Subtitle under title +// - Top-right utility buttons (Refresh, Create Job, Settings) +// - AG Grid Quartz theme + square checkboxes, rounded chrome +// - Keeps all original logic + renderers +// ///////////////////////////////////////////////////////////////////////////// import React, { useCallback, @@ -16,34 +24,68 @@ import { Dialog, DialogTitle, DialogActions, - CircularProgress + CircularProgress, + IconButton, + Stack, + Tooltip } from "@mui/material"; +import { + Schedule as HeaderIcon, + Cached as CachedIcon, + Add as AddIcon, + Tune as TuneIcon +} from "@mui/icons-material"; import { AgGridReact } from "ag-grid-react"; import { ModuleRegistry, AllCommunityModule, themeQuartz } from "ag-grid-community"; import { DomainBadge, resolveDomainMeta } from "../Assemblies/Assembly_Badges"; import { buildAssemblyIndex, resolveAssemblyForComponent } from "../Assemblies/assemblyUtils"; +// ----------------------------------------------------------------------------- +// Register AG Grid community modules +// ----------------------------------------------------------------------------- ModuleRegistry.registerModules([AllCommunityModule]); -const myTheme = themeQuartz.withParams({ - accentColor: "#FFA6FF", - backgroundColor: "#1f2836", +// ----------------------------------------------------------------------------- +// MagicUI x Quartz Theme (parity with Page_Template) +// ----------------------------------------------------------------------------- +const gridTheme = themeQuartz.withParams({ + accentColor: "#8b5cf6", + backgroundColor: "#070b1a", browserColorScheme: "dark", - chromeBackgroundColor: { - ref: "foregroundColor", - mix: 0.07, - onto: "backgroundColor" - }, - fontFamily: { - googleFont: "IBM Plex Sans" - }, - foregroundColor: "#FFF", - headerFontSize: 14 + fontFamily: { googleFont: "IBM Plex Sans" }, + foregroundColor: "#f4f7ff", + headerFontSize: 13, }); +const themeClassName = gridTheme.themeName || "ag-theme-quartz"; -const themeClassName = myTheme.themeName || "ag-theme-quartz"; -const gridFontFamily = '"IBM Plex Sans", "Helvetica Neue", Arial, sans-serif'; -const iconFontFamily = '"Quartz Regular"'; +// Typography +const gridFontFamily = "'IBM Plex Sans','Helvetica Neue',Arial,sans-serif"; +const iconFontFamily = "'Quartz Regular'"; + +// Aurora gradient shell colors +const AURORA_SHELL = { + background: + "radial-gradient(120% 120% at 0% 0%, rgba(76, 186, 255, 0.16), transparent 55%), " + + "radial-gradient(120% 120% at 100% 0%, rgba(214, 130, 255, 0.18), transparent 60%), #040711", + text: "#e2e8f0", + subtext: "#9ba3b4", + accent: "#7dd3fc", +}; + +// Gradient button styling +const gradientButtonSx = { + backgroundImage: "linear-gradient(135deg,#7dd3fc,#c084fc)", + color: "#0b1220", + borderRadius: 999, + textTransform: "none", + boxShadow: "0 10px 26px rgba(124,58,237,0.28)", + px: 2.6, + minWidth: 116, + "&:hover": { + backgroundImage: "linear-gradient(135deg,#86e1ff,#d1a6ff)", + boxShadow: "0 12px 34px rgba(124,58,237,0.38)", + }, +}; function ResultsBar({ counts }) { const total = Math.max(1, Number(counts?.total_targets || 0)); @@ -67,24 +109,8 @@ function ResultsBar({ counts }) { .some((section) => Number(counts?.[section.key] || 0) > 0); return ( - - + + {sections.map((section) => { const value = Number(counts?.[section.key] || 0); if (!value) return null; @@ -116,20 +142,8 @@ function ResultsBar({ counts }) { return sections .filter((section) => Number(counts?.[section.key] || 0) > 0) .map((section) => ( - - + + {counts?.[section.key]} {labelFor(section.key)} )); @@ -478,12 +492,8 @@ export default function ScheduledJobsList({ onCreateJob, onEditJob, refreshToken onChange={handleToggle} onClick={(event) => event.stopPropagation()} sx={{ - "& .MuiSwitch-switchBase.Mui-checked": { - color: "#58a6ff" - }, - "& .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track": { - bgcolor: "#58a6ff" - } + "& .MuiSwitch-switchBase.Mui-checked": { color: "#58a6ff" }, + "& .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track": { bgcolor: "#58a6ff" } }} /> ); @@ -491,49 +501,42 @@ export default function ScheduledJobsList({ onCreateJob, onEditJob, refreshToken [] ); + // Selection column parity (square, centered, pinned left) + const selectionCol = { + headerName: "", + field: "__select__", + width: 52, + maxWidth: 52, + checkboxSelection: true, + headerCheckboxSelection: true, + resizable: false, + sortable: false, + suppressMenu: true, + filter: false, + pinned: "left", + lockPosition: true, + }; + const columnDefs = useMemo( () => [ - { - headerName: "", - field: "__checkbox__", - checkboxSelection: true, - headerCheckboxSelection: true, - maxWidth: 60, - minWidth: 60, - sortable: false, - filter: false, - resizable: false, - suppressMenu: true, - pinned: false - }, + selectionCol, { headerName: "Name", field: "name", cellRenderer: nameCellRenderer, - sort: "asc" + sort: "asc", + minWidth: 220, }, { headerName: "Assembly(s)", field: "componentsMeta", - minWidth: 240, + minWidth: 260, cellRenderer: assembliesCellRenderer }, - { - headerName: "Target", - field: "target" - }, - { - headerName: "Recurrence", - field: "occurrence" - }, - { - headerName: "Last Run", - field: "lastRun" - }, - { - headerName: "Next Run", - field: "nextRun" - }, + { headerName: "Target", field: "target", minWidth: 140 }, + { headerName: "Recurrence", field: "occurrence", minWidth: 160 }, + { headerName: "Last Run", field: "lastRun", minWidth: 160 }, + { headerName: "Next Run", field: "nextRun", minWidth: 160 }, { headerName: "Results", field: "resultsCounts", @@ -562,7 +565,6 @@ export default function ScheduledJobsList({ onCreateJob, onEditJob, refreshToken sortable: true, filter: "agTextColumnFilter", resizable: true, - flex: 1, minWidth: 140, cellStyle: { display: "flex", @@ -570,145 +572,181 @@ export default function ScheduledJobsList({ onCreateJob, onEditJob, refreshToken color: "#f5f7fa", fontFamily: gridFontFamily, fontSize: "13px" - }, - headerClass: "scheduled-jobs-grid-header" + } }), [] ); + const handleRefreshClick = useCallback(async () => { + await loadJobs({ showLoading: true }); + }, [loadJobs]); + return ( - - - + {/* Page header (keep padding: top 24px, left/right 24px) */} + + + + Scheduled Jobs - - List of automation jobs with schedules, results, and actions. - - - - - - + + + + + + + + + + + + + + + + + + + + + + + {/* Subtitle directly under title (muted color, small size) */} + + List of automation jobs with schedules, results, and actions. + - {loading && ( - - - Loading scheduled jobs… - - )} - - {error && ( - - {error} - - )} - - + {/* Content area — a bit more top space below subtitle */} + + {/* Action bar for bulk delete stays above grid when needed */} + {anySelected && ( + + + + )} +