mirror of
https://github.com/its-a-feature/Mythic
synced 2026-06-08 14:55:38 +00:00
"modernizing" of the UI components
This commit is contained in:
+48
-49
@@ -25,9 +25,9 @@ export const defaultShortcuts = [
|
||||
"CreatePayload", "Eventing",
|
||||
].sort();
|
||||
export const operatorSettingDefaults = {
|
||||
fontSize: 12,
|
||||
fontSize: 13,
|
||||
navBarOpen: false,
|
||||
fontFamily: "Verdana, Arial, sans-serif",
|
||||
fontFamily: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
|
||||
showMedia: true,
|
||||
hideUsernames: false,
|
||||
showIP: false,
|
||||
@@ -47,36 +47,36 @@ export const operatorSettingDefaults = {
|
||||
sideShortcuts: defaultShortcuts,
|
||||
palette: {
|
||||
primary: {
|
||||
dark: "#75859b",
|
||||
light: "#75859b",
|
||||
dark: "#8ab4f8",
|
||||
light: "#2563eb",
|
||||
},
|
||||
error: {
|
||||
dark: '#bd5142',
|
||||
light: '#c42c32'
|
||||
dark: '#f87171',
|
||||
light: '#dc2626'
|
||||
},
|
||||
success: {
|
||||
dark: '#85b089',
|
||||
light: '#0e7004',
|
||||
dark: '#4ade80',
|
||||
light: '#15803d',
|
||||
},
|
||||
secondary: {
|
||||
dark: '#bebebe',
|
||||
light: '#a6a5a5'
|
||||
dark: '#94a3b8',
|
||||
light: '#64748b'
|
||||
},
|
||||
info: {
|
||||
dark: '#84b4dc',
|
||||
light: '#4990b2'
|
||||
dark: '#38bdf8',
|
||||
light: '#0284c7'
|
||||
},
|
||||
warning: {
|
||||
dark: "#dc8455",
|
||||
light: "#ffb74d",
|
||||
dark: "#fbbf24",
|
||||
light: "#d97706",
|
||||
},
|
||||
background: {
|
||||
dark: '#282828',
|
||||
light: '#f6f6f6'
|
||||
dark: '#0f141b',
|
||||
light: '#f4f6f8'
|
||||
},
|
||||
paper: {
|
||||
dark: '#282828',
|
||||
light: '#ececec'
|
||||
dark: '#161b22',
|
||||
light: '#ffffff'
|
||||
},
|
||||
tableHeader: {
|
||||
dark: '#484848',
|
||||
@@ -87,20 +87,20 @@ export const operatorSettingDefaults = {
|
||||
light: "#e8e8e8",
|
||||
},
|
||||
pageHeader: {
|
||||
dark: '#1b2025',
|
||||
light: '#706c6e'
|
||||
dark: '#171d25',
|
||||
light: '#ffffff'
|
||||
},
|
||||
text: {
|
||||
dark: "#e4e4e4",
|
||||
light: "#000000",
|
||||
dark: "#e5e7eb",
|
||||
light: "#111827",
|
||||
},
|
||||
selectedCallbackColor: {
|
||||
dark: '#26456e',
|
||||
light: '#c6e5f6',
|
||||
dark: '#1e3a5f',
|
||||
light: '#dbeafe',
|
||||
},
|
||||
selectedCallbackHierarchyColor: {
|
||||
dark: '#273e5d',
|
||||
light: '#deeff8',
|
||||
dark: '#22324c',
|
||||
light: '#eef4ff',
|
||||
},
|
||||
backgroundImage: {
|
||||
dark: null,
|
||||
@@ -115,48 +115,48 @@ export const operatorSettingDefaults = {
|
||||
light: '#ffffff'
|
||||
},
|
||||
navBarColor: {
|
||||
dark: "#194573",
|
||||
light: "#3b606d",
|
||||
dark: "#111827",
|
||||
light: "#111827",
|
||||
},
|
||||
navBarBottomColor: {
|
||||
dark: "#330814",
|
||||
light: "#283581",
|
||||
dark: "#1f2937",
|
||||
light: "#1f2937",
|
||||
},
|
||||
taskPromptTextColor: {
|
||||
dark: '#bebebe',
|
||||
light: '#a6a5a5'
|
||||
dark: '#9ca3af',
|
||||
light: '#64748b'
|
||||
},
|
||||
taskPromptCommandTextColor: {
|
||||
dark: "#e4e4e4",
|
||||
light: "#000000",
|
||||
dark: "#f8fafc",
|
||||
light: "#111827",
|
||||
},
|
||||
taskContextColor: {
|
||||
dark: "#122848",
|
||||
light: "#acc0da",
|
||||
dark: "#14253d",
|
||||
light: "#dbeafe",
|
||||
},
|
||||
taskContextImpersonationColor: {
|
||||
dark: "#641616",
|
||||
light: "#dec0c0",
|
||||
dark: "#4c1d20",
|
||||
light: "#fee2e2",
|
||||
},
|
||||
taskContextExtraColor: {
|
||||
dark: "#2a5953",
|
||||
light: "#a7ce9d",
|
||||
dark: "#123d39",
|
||||
light: "#dcfce7",
|
||||
},
|
||||
emptyFolderColor: {
|
||||
dark: '#bebebe',
|
||||
light: '#a6a5a5'
|
||||
dark: '#94a3b8',
|
||||
light: '#64748b'
|
||||
},
|
||||
outputBackgroundColor: {
|
||||
dark: '#282828',
|
||||
light: '#f6f6f6'
|
||||
dark: '#0b1017',
|
||||
light: '#f8fafc'
|
||||
},
|
||||
outputTextColor: {
|
||||
dark: '#f6f6f6',
|
||||
light: '#282828',
|
||||
dark: '#e5e7eb',
|
||||
light: '#111827',
|
||||
},
|
||||
borderColor: {
|
||||
dark: "#595858",
|
||||
light: "#c5c5c5"
|
||||
dark: "#2f3742",
|
||||
light: "#d9dee7"
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -227,4 +227,3 @@ export const FailedRefresh = (restart_websockets) =>{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,438 @@ query getUserSettings {
|
||||
}
|
||||
`;
|
||||
|
||||
const getModernThemeAdditions = (themeMode, preferences = operatorSettingDefaults) => {
|
||||
const isDark = themeMode === "dark";
|
||||
const mode = isDark ? "dark" : "light";
|
||||
const safePreferences = preferences || operatorSettingDefaults;
|
||||
const getColor = (key) => {
|
||||
return safePreferences?.palette?.[key]?.[mode] || operatorSettingDefaults.palette[key][mode];
|
||||
};
|
||||
const withAlpha = (color, alphaHex) => {
|
||||
if(typeof color === "string" && color.startsWith("#") && color.length === 7){
|
||||
return `${color}${alphaHex}`;
|
||||
}
|
||||
return color;
|
||||
};
|
||||
const textPrimary = getColor("text");
|
||||
const textSecondary = isDark ? "#9ca3af" : "#475569";
|
||||
const borderColor = getColor("borderColor");
|
||||
const backgroundDefault = getColor("background");
|
||||
const backgroundPaper = getColor("paper");
|
||||
const navBackground = getColor("navBarColor");
|
||||
const navAccent = getColor("navBarBottomColor");
|
||||
const navText = getColor("navBarText");
|
||||
const navIcon = getColor("navBarIcons");
|
||||
const primary = getColor("primary");
|
||||
const tableHeaderColor = getColor("tableHeader");
|
||||
const tableHoverColor = getColor("tableHover");
|
||||
const tableRowStripeColor = withAlpha(tableHoverColor, isDark ? "55" : "66");
|
||||
const tableRowHoverColor = withAlpha(tableHoverColor, "CC");
|
||||
const hoverColor = tableRowHoverColor;
|
||||
const tableSelectedColor = withAlpha(getColor("selectedCallbackColor"), "CC");
|
||||
const tableSelectedHierarchyColor = withAlpha(getColor("selectedCallbackHierarchyColor"), "CC");
|
||||
const tableBorderSoft = withAlpha(borderColor, isDark ? "AA" : "CC");
|
||||
|
||||
return {
|
||||
shape: {
|
||||
borderRadius: 6,
|
||||
},
|
||||
pageHeaderText: {
|
||||
main: textPrimary,
|
||||
},
|
||||
navigation: {
|
||||
background: `linear-gradient(180deg, ${navBackground}, ${navAccent})`,
|
||||
backgroundColor: navBackground,
|
||||
border: borderColor,
|
||||
hover: withAlpha(getColor("tableHover"), "66"),
|
||||
selected: withAlpha(getColor("selectedCallbackColor"), "99"),
|
||||
text: navText,
|
||||
icon: navIcon,
|
||||
muted: withAlpha(navText, "B3"),
|
||||
accent: navAccent,
|
||||
},
|
||||
surfaces: {
|
||||
app: backgroundDefault,
|
||||
paper: backgroundPaper,
|
||||
raised: isDark ? "#1b222c" : "#ffffff",
|
||||
muted: isDark ? withAlpha(backgroundDefault, "DD") : withAlpha(backgroundDefault, "EE"),
|
||||
hover: tableRowHoverColor,
|
||||
selected: tableSelectedColor,
|
||||
},
|
||||
table: {
|
||||
header: tableHeaderColor,
|
||||
headerHover: tableRowHoverColor,
|
||||
rowStripe: tableRowStripeColor,
|
||||
rowHover: tableRowHoverColor,
|
||||
selected: tableSelectedColor,
|
||||
selectedHierarchy: tableSelectedHierarchyColor,
|
||||
border: borderColor,
|
||||
borderSoft: tableBorderSoft,
|
||||
},
|
||||
typography: {
|
||||
fontSize: safePreferences?.fontSize || operatorSettingDefaults.fontSize,
|
||||
fontFamily: safePreferences?.fontFamily || operatorSettingDefaults.fontFamily,
|
||||
h5: {
|
||||
fontWeight: 650,
|
||||
letterSpacing: 0,
|
||||
},
|
||||
h6: {
|
||||
fontWeight: 650,
|
||||
letterSpacing: 0,
|
||||
},
|
||||
subtitle1: {
|
||||
fontWeight: 650,
|
||||
},
|
||||
button: {
|
||||
textTransform: "none",
|
||||
fontWeight: 650,
|
||||
letterSpacing: 0,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
MuiCssBaseline: {
|
||||
styleOverrides: {
|
||||
body: {
|
||||
backgroundColor: backgroundDefault,
|
||||
color: textPrimary,
|
||||
WebkitFontSmoothing: "antialiased",
|
||||
MozOsxFontSmoothing: "grayscale",
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiPaper: {
|
||||
defaultProps: {
|
||||
elevation: 0,
|
||||
},
|
||||
styleOverrides: {
|
||||
root: {
|
||||
backgroundImage: "none",
|
||||
boxShadow: "none",
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiButton: {
|
||||
defaultProps: {
|
||||
disableElevation: true,
|
||||
size: "small",
|
||||
},
|
||||
styleOverrides: {
|
||||
root: {
|
||||
minHeight: 30,
|
||||
borderRadius: 6,
|
||||
textTransform: "none",
|
||||
fontWeight: 650,
|
||||
},
|
||||
contained: {
|
||||
boxShadow: "none",
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiIconButton: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
borderRadius: 6,
|
||||
padding: 5,
|
||||
color: textSecondary,
|
||||
"&:hover": {
|
||||
backgroundColor: hoverColor,
|
||||
color: textPrimary,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiAppBar: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
backgroundImage: "none",
|
||||
boxShadow: "none",
|
||||
borderBottom: `1px solid ${borderColor}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiDialog: {
|
||||
styleOverrides: {
|
||||
paper: {
|
||||
borderRadius: 8,
|
||||
border: `1px solid ${borderColor}`,
|
||||
backgroundImage: "none",
|
||||
boxShadow: isDark ? "0 24px 80px rgba(0, 0, 0, 0.45)" : "0 24px 80px rgba(15, 23, 42, 0.14)",
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiDialogTitle: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: "10px 14px",
|
||||
fontSize: "1rem",
|
||||
fontWeight: 650,
|
||||
borderBottom: `1px solid ${borderColor}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiDialogContent: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
padding: "12px 14px",
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiDialogActions: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
gap: 8,
|
||||
padding: "10px 14px",
|
||||
borderTop: `1px solid ${borderColor}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiOutlinedInput: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
borderRadius: 6,
|
||||
backgroundColor: backgroundPaper,
|
||||
"&:hover .MuiOutlinedInput-notchedOutline": {
|
||||
borderColor: textSecondary,
|
||||
},
|
||||
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
|
||||
borderColor: primary,
|
||||
borderWidth: 1,
|
||||
},
|
||||
},
|
||||
notchedOutline: {
|
||||
borderColor,
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiInput: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
"&:before": {
|
||||
borderBottomColor: borderColor,
|
||||
},
|
||||
"&:after": {
|
||||
borderBottomColor: primary,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiInputBase: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
fontSize: "0.92rem",
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiInputLabel: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
color: textSecondary,
|
||||
"&.Mui-focused": {
|
||||
color: primary,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiTabs: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
minHeight: 34,
|
||||
},
|
||||
indicator: {
|
||||
height: 2,
|
||||
borderRadius: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiTab: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
minHeight: 34,
|
||||
padding: "6px 10px",
|
||||
textTransform: "none",
|
||||
fontSize: "0.82rem",
|
||||
fontWeight: 650,
|
||||
letterSpacing: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiMenu: {
|
||||
styleOverrides: {
|
||||
paper: {
|
||||
border: `1px solid ${borderColor}`,
|
||||
borderRadius: 8,
|
||||
boxShadow: isDark ? "0 18px 48px rgba(0, 0, 0, 0.40)" : "0 18px 48px rgba(15, 23, 42, 0.12)",
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiList: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
backgroundImage: "none",
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiTooltip: {
|
||||
styleOverrides: {
|
||||
tooltip: {
|
||||
borderRadius: 6,
|
||||
fontSize: 12,
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiAccordion: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
boxShadow: "none",
|
||||
"&:before": {
|
||||
display: "none",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiChip: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
borderRadius: 5,
|
||||
fontWeight: 650,
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiTableContainer: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
backgroundColor: backgroundPaper,
|
||||
borderRadius: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiTable: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
backgroundColor: backgroundPaper,
|
||||
borderCollapse: "separate",
|
||||
borderSpacing: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiTableCell: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
borderBottom: `1px solid ${tableBorderSoft}`,
|
||||
color: textPrimary,
|
||||
fontSize: "0.86rem",
|
||||
lineHeight: 1.35,
|
||||
padding: "6px 10px",
|
||||
verticalAlign: "middle",
|
||||
},
|
||||
head: {
|
||||
backgroundColor: tableHeaderColor,
|
||||
borderBottom: `1px solid ${borderColor}`,
|
||||
borderTop: 0,
|
||||
color: textPrimary,
|
||||
fontSize: "0.76rem",
|
||||
fontWeight: 700,
|
||||
letterSpacing: 0,
|
||||
textTransform: "uppercase",
|
||||
whiteSpace: "nowrap",
|
||||
},
|
||||
stickyHeader: {
|
||||
backgroundColor: tableHeaderColor,
|
||||
zIndex: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiTableRow: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
"&:last-child .MuiTableCell-root": {
|
||||
borderBottom: 0,
|
||||
},
|
||||
"&.Mui-selected": {
|
||||
backgroundColor: tableSelectedColor,
|
||||
"&:hover": {
|
||||
backgroundColor: tableSelectedColor,
|
||||
},
|
||||
},
|
||||
"&.MuiTableRow-hover:hover": {
|
||||
backgroundColor: tableRowHoverColor,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiTableSortLabel: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
color: textSecondary,
|
||||
"&.Mui-active": {
|
||||
color: textPrimary,
|
||||
},
|
||||
"&:hover": {
|
||||
color: textPrimary,
|
||||
},
|
||||
},
|
||||
icon: {
|
||||
color: `${textSecondary} !important`,
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiDataGrid: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
backgroundColor: backgroundPaper,
|
||||
border: `1px solid ${borderColor}`,
|
||||
borderRadius: 6,
|
||||
color: textPrimary,
|
||||
fontSize: "0.86rem",
|
||||
"--DataGrid-rowBorderColor": tableBorderSoft,
|
||||
"--DataGrid-containerBackground": tableHeaderColor,
|
||||
"& .MuiDataGrid-columnHeaders": {
|
||||
backgroundColor: tableHeaderColor,
|
||||
borderBottom: `1px solid ${borderColor}`,
|
||||
minHeight: 34,
|
||||
},
|
||||
"& .MuiDataGrid-columnHeader": {
|
||||
backgroundColor: tableHeaderColor,
|
||||
color: textPrimary,
|
||||
fontWeight: 700,
|
||||
},
|
||||
"& .MuiDataGrid-columnHeaderTitle": {
|
||||
fontSize: "0.76rem",
|
||||
fontWeight: 700,
|
||||
letterSpacing: 0,
|
||||
textTransform: "uppercase",
|
||||
},
|
||||
"& .MuiDataGrid-cell": {
|
||||
borderBottom: `1px solid ${tableBorderSoft}`,
|
||||
outline: "none",
|
||||
},
|
||||
"& .MuiDataGrid-row:nth-of-type(even)": {
|
||||
backgroundColor: tableRowStripeColor,
|
||||
},
|
||||
"& .MuiDataGrid-row:hover": {
|
||||
backgroundColor: tableRowHoverColor,
|
||||
},
|
||||
"& .MuiDataGrid-row.Mui-selected": {
|
||||
backgroundColor: tableSelectedColor,
|
||||
"&:hover": {
|
||||
backgroundColor: tableSelectedColor,
|
||||
},
|
||||
},
|
||||
"& .MuiDataGrid-footerContainer": {
|
||||
borderTop: `1px solid ${borderColor}`,
|
||||
minHeight: 34,
|
||||
},
|
||||
"& .MuiDataGrid-toolbarContainer": {
|
||||
borderBottom: `1px solid ${tableBorderSoft}`,
|
||||
minHeight: 34,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
export function App(props) {
|
||||
const me = useReactiveVar(meState);
|
||||
@@ -117,8 +549,17 @@ export function App(props) {
|
||||
text: {
|
||||
primary: themeMode === 'dark' ? preferences?.palette?.text?.dark || operatorSettingDefaults.palette.text.dark :
|
||||
preferences?.palette?.text?.light || operatorSettingDefaults.palette.text.light,
|
||||
secondary: themeMode === 'dark' ? '#9ca3af' : '#475569',
|
||||
disabled: themeMode === 'dark' ? '#6b7280' : '#94a3b8',
|
||||
contrast: themeMode === 'dark' ? '#000' : '#fff',
|
||||
},
|
||||
action: {
|
||||
hover: themeMode === 'dark' ? 'rgba(255, 255, 255, 0.07)' : 'rgba(15, 23, 42, 0.06)',
|
||||
selected: themeMode === 'dark' ? 'rgba(255, 255, 255, 0.11)' : 'rgba(37, 99, 235, 0.10)',
|
||||
focus: themeMode === 'dark' ? 'rgba(138, 180, 248, 0.20)' : 'rgba(37, 99, 235, 0.18)',
|
||||
},
|
||||
divider: themeMode === 'dark' ? preferences?.palette?.borderColor?.dark || operatorSettingDefaults.palette.borderColor.dark :
|
||||
preferences?.palette?.borderColor?.light || operatorSettingDefaults.palette.borderColor.light,
|
||||
graphGroupRGBA: themeMode === 'dark' ? 'rgba(57, 76, 93, 0.5)' : 'rgba(211, 215, 232, 0.5)',
|
||||
speedDialAction: themeMode === 'dark' ? '#495054' : '#ffffff',
|
||||
},
|
||||
@@ -168,6 +609,7 @@ export function App(props) {
|
||||
preferences?.palette?.outputTextColor?.light || operatorSettingDefaults.palette.outputTextColor.light,
|
||||
borderColor: themeMode === 'dark' ? preferences?.palette?.borderColor?.dark || operatorSettingDefaults.palette.borderColor.dark :
|
||||
preferences?.palette?.borderColor?.light || operatorSettingDefaults.palette.borderColor.light,
|
||||
...getModernThemeAdditions(themeMode, preferences),
|
||||
})
|
||||
}catch(error){
|
||||
console.log(error);
|
||||
@@ -218,8 +660,17 @@ export function App(props) {
|
||||
text: {
|
||||
primary: themeMode === 'dark' ? operatorSettingDefaults.palette.text.dark :
|
||||
operatorSettingDefaults.palette.text.light,
|
||||
secondary: themeMode === 'dark' ? '#9ca3af' : '#475569',
|
||||
disabled: themeMode === 'dark' ? '#6b7280' : '#94a3b8',
|
||||
contrast: themeMode === 'dark' ? '#000' : '#fff',
|
||||
},
|
||||
action: {
|
||||
hover: themeMode === 'dark' ? 'rgba(255, 255, 255, 0.07)' : 'rgba(15, 23, 42, 0.06)',
|
||||
selected: themeMode === 'dark' ? 'rgba(255, 255, 255, 0.11)' : 'rgba(37, 99, 235, 0.10)',
|
||||
focus: themeMode === 'dark' ? 'rgba(138, 180, 248, 0.20)' : 'rgba(37, 99, 235, 0.18)',
|
||||
},
|
||||
divider: themeMode === 'dark' ? operatorSettingDefaults.palette.borderColor.dark :
|
||||
operatorSettingDefaults.palette.borderColor.light,
|
||||
graphGroupRGBA: themeMode === 'dark' ? 'rgba(57, 76, 93, 0.5)' : 'rgba(211, 215, 232, 0.5)',
|
||||
speedDialAction: themeMode === 'dark' ? '#495054' : '#ffffff',
|
||||
},
|
||||
@@ -259,9 +710,10 @@ export function App(props) {
|
||||
fontSize: 12,//operatorSettingDefaults?.fontSize,
|
||||
fontFamily: operatorSettingDefaults?.fontFamily
|
||||
},
|
||||
...getModernThemeAdditions(themeMode, operatorSettingDefaults),
|
||||
})
|
||||
}
|
||||
},[themeMode, loadingPreference, preferences.fontSize, preferences.fontFamily, preferences.palette]
|
||||
},[themeMode, preferences]
|
||||
);
|
||||
const mountedRef = React.useRef(true);
|
||||
const [openRefreshDialog, setOpenRefreshDialog] = React.useState(false);
|
||||
@@ -358,7 +810,7 @@ export function App(props) {
|
||||
flexDirection: 'column',
|
||||
overflow: "hidden",
|
||||
}}>
|
||||
<div style={{height: "5px", width: "100%", background: me.loggedIn ? `linear-gradient(25deg, ${theme.topAppBarColor}, ${theme.topAppBarBottomColor})` : ""}}/>
|
||||
<div style={{height: me.loggedIn ? "2px" : 0, width: "100%", background: me.loggedIn ? `linear-gradient(90deg, ${theme.topAppBarColor}, ${theme.topAppBarBottomColor})` : ""}}/>
|
||||
{me.loggedIn && me?.user?.current_operation_banner_text !== "" &&
|
||||
<Typography style={{
|
||||
backgroundColor: me?.user?.current_operation_banner_color,
|
||||
@@ -366,7 +818,9 @@ export function App(props) {
|
||||
textAlign: "center",
|
||||
fontWeight: "600",
|
||||
color: "white",
|
||||
border: `1px solid ${theme.topAppBarColor || "grey"}`
|
||||
borderBottom: `1px solid ${theme.borderColor}`,
|
||||
fontSize: theme.typography.pxToRem(12),
|
||||
lineHeight: "24px",
|
||||
}}>
|
||||
{me?.user?.current_operation_banner_text}
|
||||
</Typography>
|
||||
@@ -379,7 +833,9 @@ export function App(props) {
|
||||
textAlign: "center",
|
||||
fontWeight: "600",
|
||||
color: "white",
|
||||
border: `1px solid ${theme.topAppBarColor || "grey"}`
|
||||
borderBottom: `1px solid ${theme.borderColor}`,
|
||||
fontSize: theme.typography.pxToRem(12),
|
||||
lineHeight: "24px",
|
||||
}}>
|
||||
{"Can't connect to Mythic. Please check connection and refresh"}
|
||||
</Typography>
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
import React from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import {HexColorInput} from 'react-colorful';
|
||||
|
||||
export const isValidHexColor = (color) => {
|
||||
if(typeof color !== "string"){
|
||||
return false;
|
||||
}
|
||||
if(color.length !== 7){
|
||||
return false;
|
||||
}
|
||||
if(color[0] !== "#"){
|
||||
return false;
|
||||
}
|
||||
return /^#[0-9a-fA-F]{6}$/.test(color);
|
||||
}
|
||||
|
||||
export const getReadableTextColor = (backgroundColor) => {
|
||||
if(!isValidHexColor(backgroundColor)){
|
||||
return "#ffffff";
|
||||
}
|
||||
const red = parseInt(backgroundColor.slice(1, 3), 16);
|
||||
const green = parseInt(backgroundColor.slice(3, 5), 16);
|
||||
const blue = parseInt(backgroundColor.slice(5, 7), 16);
|
||||
const brightness = (red * 299 + green * 587 + blue * 114) / 1000;
|
||||
return brightness >= 140 ? "#111827" : "#ffffff";
|
||||
}
|
||||
|
||||
export const MythicColorSwatchInput = ({color, label, onChange, inputWidth = "96px", sx = {}}) => {
|
||||
const safeColor = isValidHexColor(color) ? color : "#000000";
|
||||
return (
|
||||
<Box sx={{display: "flex", alignItems: "center", gap: 1, minWidth: 0, ...sx}}>
|
||||
<Box
|
||||
component="input"
|
||||
type="color"
|
||||
value={safeColor}
|
||||
onChange={(evt) => onChange(evt.target.value)}
|
||||
aria-label={label}
|
||||
sx={{
|
||||
width: 34,
|
||||
height: 30,
|
||||
flex: "0 0 auto",
|
||||
p: 0,
|
||||
border: "none",
|
||||
backgroundColor: "transparent",
|
||||
cursor: "pointer",
|
||||
"&::-webkit-color-swatch-wrapper": {p: 0},
|
||||
"&::-webkit-color-swatch": {
|
||||
border: "1px solid",
|
||||
borderColor: "divider",
|
||||
borderRadius: "4px",
|
||||
},
|
||||
"&::-moz-color-swatch": {
|
||||
border: "1px solid",
|
||||
borderColor: "divider",
|
||||
borderRadius: "4px",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<HexColorInput
|
||||
color={color}
|
||||
onChange={onChange}
|
||||
prefixed={true}
|
||||
style={{
|
||||
width: inputWidth,
|
||||
minWidth: 0,
|
||||
height: "30px",
|
||||
boxSizing: "border-box",
|
||||
borderRadius: "4px",
|
||||
border: "1px solid rgba(128,128,128,0.45)",
|
||||
background: "transparent",
|
||||
color: "inherit",
|
||||
padding: "0 8px",
|
||||
fontFamily: "inherit",
|
||||
fontSize: "0.85rem",
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import Draggable from 'react-draggable';
|
||||
import {MythicDraggableDialogTitle} from "./MythicDraggableDialogTitle";
|
||||
|
||||
export function MythicDialog(props) {
|
||||
const theme = useTheme();
|
||||
const [draggedState, setDraggedState] = React.useState({
|
||||
style: {},
|
||||
paperStyle: {
|
||||
@@ -121,10 +122,13 @@ export function MythicDialog(props) {
|
||||
aria-labelledby="scroll-dialog-title"
|
||||
aria-describedby="scroll-dialog-description"
|
||||
sx={{
|
||||
[".MuiPaper-root"]: {
|
||||
".MuiPaper-root": {
|
||||
borderRadius: "8px",
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
border: `1px solid ${theme.borderColor}`,
|
||||
...draggedState.paperStyle
|
||||
},
|
||||
[".MuiDialog-container"]: {
|
||||
".MuiDialog-container": {
|
||||
...draggedState.containerStyle
|
||||
}
|
||||
}}
|
||||
@@ -480,4 +484,4 @@ export const TableRowSizeCell = ({ cellData, rowData }) => {
|
||||
}
|
||||
};
|
||||
return getStringSize(cellData);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
import DialogTitle from '@mui/material/DialogTitle';
|
||||
import {useTheme} from '@mui/material/styles';
|
||||
|
||||
|
||||
export const MythicDraggableDialogTitle = ({children}) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<DialogTitle id="mythic-draggable-title" style={{ cursor: 'move', width: "100%" }}>
|
||||
<DialogTitle id="mythic-draggable-title" style={{
|
||||
cursor: 'move',
|
||||
width: "100%",
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
color: theme.palette.text.primary,
|
||||
}}>
|
||||
{children}
|
||||
</DialogTitle>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,12 @@ export const MythicPageBody = ({children}) => {
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
margin: "0.5rem",
|
||||
padding: "0.75rem",
|
||||
gap: "0.5rem",
|
||||
minWidth: 0,
|
||||
minHeight: 0,
|
||||
}}>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,31 +2,41 @@ import {useTheme} from '@mui/material/styles';
|
||||
import Paper from '@mui/material/Paper';
|
||||
import {Typography} from "@mui/material";
|
||||
|
||||
export const MythicPageHeader = ({children, title, style={}, headerVariant="h5"}) => {
|
||||
export const MythicPageHeader = ({children, title, style={}, headerVariant="h6"}) => {
|
||||
const theme = useTheme();
|
||||
const headerTextColor = theme.palette.getContrastText(theme.pageHeader.main);
|
||||
return (
|
||||
<Paper elevation={2}
|
||||
variant={"elevation"}
|
||||
<Paper elevation={0}
|
||||
style={{
|
||||
backgroundColor: theme.pageHeader.main,
|
||||
color: theme.pageHeaderText.main,
|
||||
color: headerTextColor,
|
||||
border: `1px solid ${theme.borderColor}`,
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
marginBottom: "0.5rem",
|
||||
padding: "0.5rem",
|
||||
borderRadius: "5px",
|
||||
gap: "0.75rem",
|
||||
minHeight: "44px",
|
||||
marginBottom: "0rem",
|
||||
padding: "0.5rem 0.75rem",
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
...style
|
||||
}}
|
||||
>
|
||||
<Typography variant={headerVariant} style={{textAlign: "left", display: "inline-block", marginLeft: "1rem", width: "100%"}}>
|
||||
<Typography variant={headerVariant} style={{
|
||||
textAlign: "left",
|
||||
display: "inline-block",
|
||||
marginLeft: "0.25rem",
|
||||
width: "100%",
|
||||
fontWeight: 650,
|
||||
letterSpacing: 0,
|
||||
color: headerTextColor,
|
||||
}}>
|
||||
{title}
|
||||
</Typography>
|
||||
<div style={{display: "flex", marginRight: "1rem", alignItems: "center"}}>
|
||||
<div style={{display: "flex", marginRight: "0.25rem", alignItems: "center", gap: "0.35rem", color: headerTextColor}}>
|
||||
{children}
|
||||
</div>
|
||||
</Paper>
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import MenuList from '@mui/material/MenuList';
|
||||
import ClickAwayListener from '@mui/material/ClickAwayListener';
|
||||
import Paper from '@mui/material/Paper';
|
||||
import Badge from '@mui/material/Badge';
|
||||
import {useTheme} from '@mui/material/styles';
|
||||
import {
|
||||
Draggable,
|
||||
} from "@hello-pangea/dnd";
|
||||
@@ -72,6 +73,7 @@ export function MythicTabLabel(props) {
|
||||
};
|
||||
const [openContextMenu, setOpenContextMenu] = React.useState(false);
|
||||
const dropdownAnchorRef = React.useRef(null);
|
||||
const theme = useTheme();
|
||||
const handleContextClick = (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
@@ -94,8 +96,11 @@ export function MythicTabLabel(props) {
|
||||
{(provided, snapshot) => (
|
||||
<div ref={provided.innerRef}
|
||||
{...provided.draggableProps}>
|
||||
{(() => {
|
||||
const selected = selectedIndex === index || snapshot.isDragging;
|
||||
const tabAccent = tabInfo?.color || theme.palette.primary.main;
|
||||
return (
|
||||
<Tab
|
||||
className={selectedIndex === index || snapshot.isDragging ? "selectedCallback" : "" }
|
||||
label={
|
||||
<span onContextMenu={handleContextClick} style={{}} ref={dropdownAnchorRef}>
|
||||
<Badge color="success" variant="dot" invisible={!highlight} >
|
||||
@@ -109,10 +114,20 @@ export function MythicTabLabel(props) {
|
||||
{...a11yProps(index)}
|
||||
{...other}
|
||||
{...provided.dragHandleProps}
|
||||
style={{padding: "0px 5px 0px 5px", borderRadius: "4px", margin: 0,
|
||||
borderBottom: selectedIndex === index ? `2px solid grey` : '',
|
||||
backgroundColor: selectedIndex === index ? tabInfo.color : snapshot.isDragging ? tabInfo.color : ""}}
|
||||
style={{
|
||||
padding: "0px 6px",
|
||||
margin: "0 3px 0 0",
|
||||
minHeight: "32px",
|
||||
borderRadius: `${theme.shape.borderRadius}px ${theme.shape.borderRadius}px 0 0`,
|
||||
border: `1px solid ${theme.borderColor}`,
|
||||
borderTop: `2px solid ${selected ? tabAccent : "transparent"}`,
|
||||
borderBottom: selected ? `1px solid ${theme.palette.background.paper}` : `1px solid ${theme.borderColor}`,
|
||||
backgroundColor: selected ? theme.palette.background.paper : theme.surfaces?.muted,
|
||||
color: theme.palette.text.primary,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})()}
|
||||
<Popper open={openContextMenu} anchorEl={dropdownAnchorRef.current} role={undefined} transition style={{zIndex: 40}}>
|
||||
{({ TransitionProps, placement }) => (
|
||||
<Grow
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
import {styled} from '@mui/material/styles';
|
||||
import TableCell from '@mui/material/TableCell';
|
||||
const MythicStyledTableCell = styled(TableCell, {})({
|
||||
padding: "2px 0 2px 10px !important",
|
||||
});
|
||||
const MythicStyledTableCell = styled(TableCell, {})(({theme}) => ({
|
||||
borderBottom: `1px solid ${theme.table?.borderSoft || theme.borderColor}`,
|
||||
lineHeight: 1.35,
|
||||
padding: "6px 10px !important",
|
||||
verticalAlign: "middle",
|
||||
"&.MuiTableCell-head": {
|
||||
borderBottom: `1px solid ${theme.table?.border || theme.borderColor}`,
|
||||
padding: "6px 10px !important",
|
||||
},
|
||||
"&:first-of-type": {
|
||||
paddingLeft: "12px !important",
|
||||
},
|
||||
"&:last-of-type": {
|
||||
paddingRight: "12px !important",
|
||||
},
|
||||
}));
|
||||
export default MythicStyledTableCell;
|
||||
|
||||
@@ -17,20 +17,31 @@ const Root = styled('div')(({theme}) => ({
|
||||
|
||||
const ValidationTextField = styled(TextField)(({theme}) => ({
|
||||
[`&.${classes.textFieldRoot}`]: {
|
||||
'& .MuiInputBase-root': {
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
},
|
||||
'& fieldset': {
|
||||
borderColor: 'grey',
|
||||
borderColor: theme.borderColor,
|
||||
borderWidth: 1,
|
||||
},
|
||||
'&:hover fieldset': {
|
||||
borderColor: theme.palette.text.secondary,
|
||||
},
|
||||
'& .Mui-focused fieldset': {
|
||||
borderColor: `${theme.palette.primary.main} !important`,
|
||||
borderWidth: '1px !important',
|
||||
},
|
||||
'& input:invalid + fieldset': {
|
||||
borderColor: 'red',
|
||||
borderColor: theme.palette.error.main,
|
||||
borderWidth: 2,
|
||||
},
|
||||
'& input:valid:focus + fieldset': {
|
||||
borderLeftWidth: 6,
|
||||
borderLeftWidth: 2,
|
||||
padding: '4px !important', // override inline-style
|
||||
},
|
||||
'& textarea:focus + textarea + fieldset': {
|
||||
borderLeftWidth: 6,
|
||||
borderLeftWidth: 2,
|
||||
//padding: '4px !important', // override inline-style
|
||||
},
|
||||
},
|
||||
|
||||
@@ -92,14 +92,16 @@ const openedMixin = (theme) => ({
|
||||
overflowX: 'hidden',
|
||||
borderRadius: "0 !important",
|
||||
border: "0px !important",
|
||||
backgroundColor: "unset !important",
|
||||
background: `${theme.navigation.background} !important`,
|
||||
backgroundColor: `${theme.navigation.backgroundColor} !important`,
|
||||
});
|
||||
const closedMixin = (theme) => ({
|
||||
overflowX: 'hidden',
|
||||
width: `calc(${theme.spacing(4)} + 1px)`,
|
||||
borderRadius: "0 !important",
|
||||
border: "0px !important",
|
||||
backgroundColor: "unset !important",
|
||||
background: `${theme.navigation.background} !important`,
|
||||
backgroundColor: `${theme.navigation.backgroundColor} !important`,
|
||||
[theme.breakpoints.up('sm')]: {
|
||||
width: `calc(${theme.spacing(5)} + 1px)`,
|
||||
borderRadius: "0 !important",
|
||||
@@ -112,18 +114,25 @@ const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== 'open'
|
||||
flexShrink: 0,
|
||||
whiteSpace: 'nowrap',
|
||||
boxSizing: 'border-box',
|
||||
background: `linear-gradient(180deg, ${theme.topAppBarColor}, ${theme.topAppBarBottomColor}) !important`,
|
||||
backgroundColor: `unset !important`,
|
||||
background: `${theme.navigation.background} !important`,
|
||||
backgroundColor: `${theme.navigation.backgroundColor} !important`,
|
||||
color: theme.navigation.text,
|
||||
'& .MuiDrawer-paper': {
|
||||
border: "0 !important",
|
||||
borderRight: "0 !important",
|
||||
borderRadius: "0 !important",
|
||||
boxShadow: "none !important",
|
||||
},
|
||||
'& .MuiList-root': {
|
||||
border: "0 !important",
|
||||
borderRadius: "0 !important",
|
||||
},
|
||||
[`& .${classes.listSubHeader}`]: {
|
||||
//color: ` ${theme.navBarTextIconColor} !important`,
|
||||
//backgroundColor: `${theme.topAppBarColor} !important`,
|
||||
backgroundColor: "unset !important",
|
||||
backgroundColor: "transparent !important",
|
||||
},
|
||||
[`& .${classes.listSubHeader}:hover`]: {
|
||||
//backgroundColor: `${theme.topAppBarColor} !important`,
|
||||
filter: `brightness(90%)`,
|
||||
color: `${theme.navBarTextIconColor} !important`,
|
||||
backgroundColor: "unset !important",
|
||||
color: `${theme.navigation.text} !important`,
|
||||
backgroundColor: `${theme.navigation.hover} !important`,
|
||||
},
|
||||
variants: [
|
||||
{
|
||||
@@ -132,9 +141,16 @@ const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== 'open'
|
||||
...openedMixin(theme),
|
||||
'& .MuiDrawer-paper': {
|
||||
...openedMixin(theme),
|
||||
backgroundColor: "unset !important",
|
||||
background: `${theme.navigation.background} !important`,
|
||||
backgroundColor: `${theme.navigation.backgroundColor} !important`,
|
||||
border: "0 !important",
|
||||
borderRight: "0 !important",
|
||||
borderRadius: "0 !important",
|
||||
boxShadow: "none !important",
|
||||
'& .MuiList-root': {
|
||||
backgroundColor: "unset !important",
|
||||
backgroundColor: "transparent !important",
|
||||
border: "0 !important",
|
||||
borderRadius: "0 !important",
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -145,9 +161,16 @@ const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== 'open'
|
||||
...closedMixin(theme),
|
||||
'& .MuiDrawer-paper': {
|
||||
...closedMixin(theme),
|
||||
backgroundColor: "unset !important",
|
||||
background: `${theme.navigation.background} !important`,
|
||||
backgroundColor: `${theme.navigation.backgroundColor} !important`,
|
||||
border: "0 !important",
|
||||
borderRight: "0 !important",
|
||||
borderRadius: "0 !important",
|
||||
boxShadow: "none !important",
|
||||
'& .MuiList-root': {
|
||||
backgroundColor: "unset !important",
|
||||
backgroundColor: "transparent !important",
|
||||
border: "0 !important",
|
||||
borderRadius: "0 !important",
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -157,13 +180,22 @@ const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== 'open'
|
||||
);
|
||||
export const StyledListItem = styled(ListItem)(
|
||||
({ theme }) => ({
|
||||
paddingTop: "2px",
|
||||
paddingLeft: "10px",
|
||||
paddingRight: "10px",
|
||||
marginTop: 0,
|
||||
paddingBottom: "2px",
|
||||
color: theme.navBarTextColor,
|
||||
backgroundColor: "unset !important",
|
||||
minHeight: "34px",
|
||||
paddingTop: "4px",
|
||||
paddingLeft: "8px",
|
||||
paddingRight: "8px",
|
||||
margin: "2px 4px",
|
||||
paddingBottom: "4px",
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
color: theme.navigation.text,
|
||||
backgroundColor: "transparent !important",
|
||||
"& .MuiListItemText-primary": {
|
||||
fontSize: theme.typography.pxToRem(12.5),
|
||||
fontWeight: 600,
|
||||
},
|
||||
"&:hover": {
|
||||
backgroundColor: `${theme.navigation.hover} !important`,
|
||||
},
|
||||
}),
|
||||
);
|
||||
export const StyledListItemIcon = styled(ListItemIcon)(
|
||||
@@ -171,9 +203,10 @@ export const StyledListItemIcon = styled(ListItemIcon)(
|
||||
paddingTop:0,
|
||||
marginTop: 0,
|
||||
paddingBottom: 0,
|
||||
minWidth: "45px",
|
||||
//color: theme.navBarTextIconColor,
|
||||
backgroundColor: "unset !important",
|
||||
minWidth: "32px",
|
||||
justifyContent: "center",
|
||||
color: theme.navigation.icon,
|
||||
backgroundColor: "transparent !important",
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -758,33 +791,33 @@ export function TopAppBarVertical(props) {
|
||||
<>
|
||||
{me?.user?.current_operation_id ? (<EventFeedNotifications me={me} />) : null }
|
||||
<Drawer anchor="left" variant="permanent" open={menuOpen} onClose={handleDrawerClose}
|
||||
style={{borderRight: "1px solid grey !important", backgroundColor: "unset !important"
|
||||
}}>
|
||||
PaperProps={{sx: {border: "0 !important", borderRight: "0 !important", borderRadius: "0 !important", boxShadow: "none !important"}}}
|
||||
style={{background: theme.navigation.background, backgroundColor: theme.navigation.backgroundColor}}>
|
||||
<List style={{paddingTop: 0, marginTop: 0, height: "100%", display: "flex", flexDirection: "column",
|
||||
backgroundColor: "unset !important",
|
||||
borderBottom: "unset !important", borderLeft: "unset !important", borderTop: "unset !important"}}>
|
||||
<ListItem className={classes.listSubHeader} style={{marginTop:0, paddingTop: 0, paddingLeft: "2px", paddingBottom: 0}}>
|
||||
backgroundColor: "transparent !important",
|
||||
border: "0 !important", borderRadius: 0}}>
|
||||
<ListItem className={classes.listSubHeader} style={{margin: "4px 4px 6px", paddingTop: "5px", paddingLeft: "4px", paddingBottom: "5px", borderRadius: theme.shape.borderRadius}}>
|
||||
<ListItemIcon >
|
||||
<img src={ReactLogo} onClick={()=>navigate('/new')} width={"40px"} height={"35px"}/>
|
||||
<img src={ReactLogo} onClick={()=>navigate('/new')} width={"40px"} height={"35px"} alt="Mythic" style={{cursor: "pointer"}}/>
|
||||
</ListItemIcon>
|
||||
<ListItemText style={{margin: 0}} primary={
|
||||
<>
|
||||
<Typography style={{ fontSize: 12, color: theme.navBarTextColor, display: "inline-block"}}>
|
||||
<Typography style={{ fontSize: 12, color: theme.navigation.muted, display: "inline-block", lineHeight: 1.35}}>
|
||||
<b>Mythic:</b> v{serverVersion}<br/>
|
||||
<b>UI:</b> v{mythicUIVersion}<br/>
|
||||
</Typography>
|
||||
<IconButton onClick={props.toggleTheme} style={{float:"right", display: menuOpen ? "" : "none"}} >
|
||||
<IconButton onClick={props.toggleTheme} style={{float:"right", display: menuOpen ? "" : "none", color: theme.navigation.icon}} >
|
||||
{theme.palette.mode === 'light' &&
|
||||
<DarkModeTwoToneIcon style={{color: "#2f0e67"}} fontSize={"medium"} className="mythicElement" />
|
||||
<DarkModeTwoToneIcon style={{color: theme.navigation.icon}} fontSize={"medium"} className="mythicElement" />
|
||||
}
|
||||
{theme.palette.mode === 'dark' &&
|
||||
<LightModeTwoToneIcon style={{color: '#eacc1b'}} fontSize={"medium"} className="mythicElement" />
|
||||
<LightModeTwoToneIcon style={{color: theme.palette.warning.main}} fontSize={"medium"} className="mythicElement" />
|
||||
}
|
||||
</IconButton>
|
||||
</>
|
||||
} />
|
||||
</ListItem>
|
||||
<StyledListItem className={classes.listSubHeader} onClick={toggleDrawerOpen} style={{height: "30px"}} >
|
||||
<StyledListItem className={classes.listSubHeader} onClick={toggleDrawerOpen} style={{height: "32px"}} >
|
||||
<StyledListItemIcon ><MenuIcon style={{color: theme.navBarTextIconColor}} onClick={toggleDrawerOpen} fontSize={"medium"} className="mythicElement" /></StyledListItemIcon>
|
||||
<ListItemText primary={
|
||||
<>
|
||||
@@ -815,10 +848,10 @@ export function TopAppBarVertical(props) {
|
||||
|
||||
} />
|
||||
</StyledListItem>
|
||||
<Divider style={{borderColor: "white"}} />
|
||||
<Divider style={{borderColor: theme.navigation.muted, margin: "4px 8px"}} />
|
||||
<div style={{flexGrow: 1, overflowY: "auto", overflowX: "hidden"}}>
|
||||
{getShortcuts({shortcuts: sideShortcuts})}
|
||||
<Divider style={{borderColor: "white"}} />
|
||||
<Divider style={{borderColor: theme.navigation.muted, margin: "4px 8px"}} />
|
||||
<StyledListItem className={classes.listSubHeader} onClick={handleToggleExtra}>
|
||||
<StyledListItemIcon>
|
||||
<MoreHorizIcon style={{color: theme.navBarTextIconColor}} fontSize={"medium"} />
|
||||
@@ -827,7 +860,7 @@ export function TopAppBarVertical(props) {
|
||||
{openExtra ? <ExpandLess /> : <ExpandMore />}
|
||||
</StyledListItem>
|
||||
{openExtra && getExtraShortcuts()}
|
||||
<Divider style={{borderColor: "white"}} />
|
||||
<Divider style={{borderColor: theme.navigation.muted, margin: "4px 8px"}} />
|
||||
<div className={classes.listSubHeader} style={{ flexGrow: 1}}></div>
|
||||
</div>
|
||||
<TopBarRightShortcutsVertical me={me} menuOpen={menuOpen} serverName={serverName} />
|
||||
@@ -1044,4 +1077,4 @@ function TopBarRightShortcutsVertical({me, menuOpen, serverName}){
|
||||
</StyledListItem>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import {reorder} from "../../MythicComponents/MythicDraggableList";
|
||||
import Paper from '@mui/material/Paper';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import {MythicStyledTooltip} from "../../MythicComponents/MythicStyledTooltip";
|
||||
import {useTheme} from '@mui/material/styles';
|
||||
|
||||
export const getCallbackIdFromClickedTab = (tabId) => {
|
||||
if(tabId === null || tabId === undefined){return 0}
|
||||
@@ -32,6 +33,7 @@ export const getCallbackIdFromClickedTab = (tabId) => {
|
||||
}
|
||||
|
||||
export function Callbacks({me}) {
|
||||
const theme = useTheme();
|
||||
const [openCallbackImport, setOpenCallbackImport] = React.useState(false);
|
||||
const [topDisplay, setTopDisplay] = React.useState('table');
|
||||
const [newDataForTab, setNewDataForTab] = React.useState({});
|
||||
@@ -216,8 +218,18 @@ export function Callbacks({me}) {
|
||||
onDragEnd={(sizes) => localStorage.setItem('callbackTableSplitSizes', JSON.stringify(sizes))}
|
||||
style={{ height: "100%" }}>
|
||||
<div style={{display: "flex", flexDirection: "row-reverse"}}>
|
||||
<Paper elevation={5} style={{width: "30px", display: "flex", flexDirection: "column", alignItems: "center", overflow: "hidden",
|
||||
backgroundColor: "transparent"}}>
|
||||
<Paper elevation={0} style={{
|
||||
width: "34px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
overflow: "hidden",
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
border: `1px solid ${theme.borderColor}`,
|
||||
borderRight: 0,
|
||||
borderRadius: `${theme.shape.borderRadius}px 0 0 ${theme.shape.borderRadius}px`,
|
||||
paddingTop: "3px",
|
||||
}}>
|
||||
{topDisplay !== 'table' &&
|
||||
<MythicStyledTooltip title={"Table View"}>
|
||||
<IconButton onClick={() =>setTopDisplay("table")}>
|
||||
@@ -270,4 +282,4 @@ export function Callbacks({me}) {
|
||||
</Split>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+63
-11
@@ -10,15 +10,17 @@ import "ace-builds/src-noconflict/theme-github";
|
||||
import "ace-builds/src-noconflict/theme-monokai";
|
||||
import "ace-builds/src-noconflict/ext-searchbox";
|
||||
import {useTheme} from '@mui/material/styles';
|
||||
import {HexColorInput, HexColorPicker} from 'react-colorful';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import {isValidHexColor, MythicColorSwatchInput} from '../../MythicComponents/MythicColorInput';
|
||||
|
||||
export function CallbacksTableEditDescriptionColorDialog(props) {
|
||||
const [comment, setComment] = React.useState("");
|
||||
const [color, setColor] = React.useState("");
|
||||
const theme = useTheme();
|
||||
const onCommitSubmit = () => {
|
||||
if(color === "ffffff" || color === "000000"){
|
||||
const normalizedColor = color?.toLowerCase() || "";
|
||||
if(normalizedColor === "" || normalizedColor === "ffffff" || normalizedColor === "#ffffff" ||
|
||||
normalizedColor === "000000" || normalizedColor === "#000000"){
|
||||
props.onSubmit(comment, "");
|
||||
} else {
|
||||
props.onSubmit(comment, color);
|
||||
@@ -39,6 +41,8 @@ export function CallbacksTableEditDescriptionColorDialog(props) {
|
||||
}
|
||||
setColor(props.color);
|
||||
}, [props.description, props.color]);
|
||||
const previewColor = isValidHexColor(color) ? color : "";
|
||||
const previewBorder = previewColor === "" ? "1px dashed" : `2px solid ${previewColor}`;
|
||||
return (
|
||||
<React.Fragment>
|
||||
<DialogTitle id="form-dialog-title">{props.title}</DialogTitle>
|
||||
@@ -61,14 +65,62 @@ export function CallbacksTableEditDescriptionColorDialog(props) {
|
||||
showInvisibles: false,
|
||||
}}
|
||||
/>
|
||||
<HexColorPicker color={color} onChange={setColor} style={{width: "100%"}} />
|
||||
<HexColorInput color={color} onChange={setColor} style={{width: "80%"}} />
|
||||
<Button onClick={()=>setColor("ffffff")} color={"success"}>
|
||||
Clear
|
||||
</Button>
|
||||
<Box sx={{width: "100%", height: 25, backgroundColor: color}} >
|
||||
<Typography style={{color: "white", display: "inline-block", marginRight: "10px"}}>DarkMode Text With Color Background</Typography>
|
||||
<Typography style={{color: "black", display: "inline-block"}}>LightMode Text With Color Background</Typography>
|
||||
<Box sx={{p: 1.5, borderTop: "1px solid", borderColor: "divider", backgroundColor: "background.paper"}}>
|
||||
<Box
|
||||
sx={{
|
||||
p: 1.5,
|
||||
border: "1px solid",
|
||||
borderColor: "divider",
|
||||
borderRadius: "8px",
|
||||
}}
|
||||
>
|
||||
<Box sx={{display: "flex", alignItems: "center", justifyContent: "space-between", gap: 2, mb: 1}}>
|
||||
<Box sx={{minWidth: 0}}>
|
||||
<Typography variant="body2" sx={{fontWeight: 700}}>Callback Color</Typography>
|
||||
<Typography variant="caption" sx={{color: "text.secondary"}}>Callback row and tasking accent</Typography>
|
||||
</Box>
|
||||
<Box sx={{display: "flex", alignItems: "center", gap: 1, flexWrap: "wrap", justifyContent: "flex-end"}}>
|
||||
<MythicColorSwatchInput
|
||||
color={isValidHexColor(color) ? color : "#000000"}
|
||||
label="Callback color"
|
||||
onChange={setColor}
|
||||
/>
|
||||
<Button onClick={() => setColor("")} color="success" variant="outlined" size="small">
|
||||
Clear
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box sx={{display: "grid", gridTemplateColumns: {xs: "1fr", sm: "1fr 1fr"}, gap: 1}}>
|
||||
<Box
|
||||
sx={{
|
||||
minHeight: 40,
|
||||
px: 1.5,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
borderRadius: "6px",
|
||||
border: previewBorder,
|
||||
borderColor: previewColor === "" ? "divider" : previewColor,
|
||||
backgroundColor: "#1f2937",
|
||||
}}
|
||||
>
|
||||
<Typography sx={{color: "#ffffff", fontWeight: 700}}>Dark callback row</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
minHeight: 40,
|
||||
px: 1.5,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
borderRadius: "6px",
|
||||
border: previewBorder,
|
||||
borderColor: previewColor === "" ? "divider" : previewColor,
|
||||
backgroundColor: "#f8fafc",
|
||||
}}
|
||||
>
|
||||
<Typography sx={{color: "#111827", fontWeight: 700}}>Light callback row</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
@@ -83,4 +135,4 @@ export function CallbacksTableEditDescriptionColorDialog(props) {
|
||||
</DialogActions>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import TableCell from '@mui/material/TableCell';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import {useQuery, gql, useMutation} from '@apollo/client';
|
||||
@@ -346,6 +347,7 @@ export function DetailedCallbackTable(props){
|
||||
Payload Information
|
||||
</Typography>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" aria-label="details" style={{ "overflowWrap": "break-word"}}>
|
||||
<TableHead>
|
||||
<TableRow hover>
|
||||
@@ -451,11 +453,13 @@ export function DetailedCallbackTable(props){
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<Paper elevation={5} style={{backgroundColor: theme.pageHeader.main, color: theme.pageHeaderText.main,marginBottom: "5px", marginTop: "10px"}} variant={"elevation"}>
|
||||
<Typography variant="h6" style={{textAlign: "left", display: "inline-block", marginLeft: "20px", color: theme.pageHeaderColor}}>
|
||||
Build Parameters
|
||||
</Typography>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" aria-label="details" style={{ "overflowWrap": "break-word"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -491,11 +495,13 @@ export function DetailedCallbackTable(props){
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<Paper elevation={5} style={{backgroundColor: theme.pageHeader.main, color: theme.pageHeaderText.main,marginBottom: "5px", marginTop: "10px"}} variant={"elevation"}>
|
||||
<Typography variant="h6" style={{textAlign: "left", display: "inline-block", marginLeft: "20px", color: theme.pageHeaderColor}}>
|
||||
Build Steps
|
||||
</Typography>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" aria-label="details" style={{ "overflowWrap": "break-word"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -521,6 +527,7 @@ export function DetailedCallbackTable(props){
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
{ c2Profiles.map( (c2) => (
|
||||
<React.Fragment key={"c2frag" + data.callback_by_pk.payload.id + c2.c2_profile}>
|
||||
<Paper elevation={5} style={{backgroundColor: theme.pageHeader.main, color: theme.pageHeaderText.main,marginBottom: "5px", marginTop: "10px"}} variant={"elevation"}>
|
||||
@@ -528,6 +535,7 @@ export function DetailedCallbackTable(props){
|
||||
{c2.c2_profile}
|
||||
</Typography>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" aria-label="details" style={{"overflowWrap": "break-word"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -554,6 +562,7 @@ export function DetailedCallbackTable(props){
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</React.Fragment>
|
||||
))}
|
||||
<Paper elevation={5} style={{backgroundColor: theme.pageHeader.main, color: theme.pageHeaderText.main,marginBottom: "5px", marginTop: "10px"}} variant={"elevation"}>
|
||||
@@ -563,6 +572,7 @@ export function DetailedCallbackTable(props){
|
||||
</Typography>
|
||||
<Button style={{float: "right"}} variant="contained" size="small" onClick={()=>{setOpenAddRemoveCommandsDialog(true)}} >Add/Remove Commands</Button>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" aria-label="details" style={{"overflowWrap": "break-word"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -638,6 +648,7 @@ export function DetailedCallbackTable(props){
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={props.onClose} variant="contained" color="primary">
|
||||
@@ -647,4 +658,3 @@ export function DetailedCallbackTable(props){
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -2,6 +2,7 @@ import React from 'react';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import {useQuery, gql, useMutation} from '@apollo/client';
|
||||
import FormControl from '@mui/material/FormControl';
|
||||
@@ -122,6 +123,7 @@ export function ModifyCallbackMythicTreeGroupsDialog(props){
|
||||
<b>Note:</b> Having <b>no</b> group entries will hide all information from this callback from your FileBrowser and ProcessBrowser views.
|
||||
</div>
|
||||
<DialogContent dividers={true}>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" aria-label="details" style={{ "overflowWrap": "break-word"}}>
|
||||
<TableHead>
|
||||
</TableHead>
|
||||
@@ -167,6 +169,7 @@ export function ModifyCallbackMythicTreeGroupsDialog(props){
|
||||
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={props.onClose} variant="contained" color="primary">
|
||||
@@ -190,4 +193,3 @@ export function ModifyCallbackMythicTreeGroupsDialog(props){
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ import CodeIcon from '@mui/icons-material/Code';
|
||||
import DownloadIcon from '@mui/icons-material/Download';
|
||||
import {b64DecodeUnicode} from "./ResponseDisplay";
|
||||
import {MythicDialog, TableRowSizeCell} from "../../MythicComponents/MythicDialog";
|
||||
import {Table, TableHead, TableRow, TableBody, TableCell, Paper} from '@mui/material';
|
||||
import {Table, TableContainer, TableHead, TableRow, TableBody, TableCell, Paper} from '@mui/material';
|
||||
import MythicStyledTableCell from "../../MythicComponents/MythicTableCell";
|
||||
import WarningOutlinedIcon from '@mui/icons-material/WarningOutlined';
|
||||
import {TagsDisplay, ViewEditTags} from "../../MythicComponents/MythicTag";
|
||||
@@ -376,6 +376,7 @@ export const DisplayMedia = ({agent_file_id, filename, expand, task, fileMetaDat
|
||||
const MaxRenderSize = 2000000; // 2MB
|
||||
const DisplayFileMetaData = ({fileMetaData}) => {
|
||||
return (
|
||||
<TableContainer className="mythicElement">
|
||||
<Table style={{marginLeft: "0px", width: "100%", tableLayout: "fixed"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -423,6 +424,7 @@ const DisplayFileMetaData = ({fileMetaData}) => {
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
)
|
||||
}
|
||||
const DisplayText = ({agent_file_id, expand, filename, preview, fileMetaData}) => {
|
||||
@@ -895,6 +897,7 @@ const DisplayDatabaseResult = ({result}) => {
|
||||
const [columns, setColumns] = React.useState(result.columns);
|
||||
const [rows, setRows] = React.useState(result.values?.slice(0, MAX_ROWS));
|
||||
return (
|
||||
<TableContainer className="mythicElement" style={{height: "100%", position: "relative"}}>
|
||||
<Table stickyHeader style={{width: "100%", height: "100%", position: "absolute"}}>
|
||||
<TableHead >
|
||||
<TableRow>
|
||||
@@ -915,5 +918,6 @@ const DisplayDatabaseResult = ({result}) => {
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,12 +60,14 @@ export const StyledPaper = styled(Paper)((
|
||||
}
|
||||
) => ({
|
||||
[`&.${classes.root}`]: {
|
||||
marginTop: "3px",
|
||||
marginTop: "4px",
|
||||
marginRight: "0px",
|
||||
height: "auto",
|
||||
width: "100%",
|
||||
boxShadow: "unset",
|
||||
backgroundColor: theme.palette.background.default + "CC",
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
border: `1px solid ${theme.borderColor}`,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
},
|
||||
|
||||
[`& .${classes.heading}`]: {
|
||||
@@ -235,8 +237,8 @@ const ColoredTaskDisplay = ({task, theme, children, expanded}) => {
|
||||
}, [task.status, task.completed])
|
||||
return(
|
||||
<span style={{display: "flex", margin: 0, borderWidth: 0, padding: 0, minHeight: "48px", alignItems: "center",
|
||||
height: "100%", borderLeft: "6px solid " + themeColor, paddingLeft: "5px", width: "100%", maxWidth: "100%",
|
||||
borderTopLeftRadius: "4px", borderBottomLeftRadius: expanded ? 0 : "4px"}}>
|
||||
height: "100%", borderLeft: "4px solid " + themeColor, paddingLeft: "7px", width: "100%", maxWidth: "100%",
|
||||
borderTopLeftRadius: theme.shape.borderRadius, borderBottomLeftRadius: expanded ? 0 : theme.shape.borderRadius}}>
|
||||
{children}
|
||||
</span>
|
||||
)
|
||||
|
||||
@@ -1008,7 +1008,7 @@ export function TaskParametersDialog(props) {
|
||||
|
||||
}
|
||||
</Typography>
|
||||
<TableContainer>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" style={{"tableLayout": "fixed", "maxWidth": "100%", "overflow": "scroll"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -1044,4 +1044,3 @@ export function TaskParametersDialog(props) {
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -801,7 +801,7 @@ export function TaskParametersDialogRow(props){
|
||||
)
|
||||
case "Array":
|
||||
return (
|
||||
<TableContainer >
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" style={{tableLayout: "fixed", maxWidth: "100%", "overflow": "auto"}}>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
@@ -846,7 +846,7 @@ export function TaskParametersDialogRow(props){
|
||||
)
|
||||
case "TypedArray":
|
||||
return (
|
||||
<TableContainer >
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" style={{tableLayout: "fixed", maxWidth: "100%", "overflow": "auto"}}>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
|
||||
@@ -3,6 +3,7 @@ import TableRow from '@mui/material/TableRow';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableCell from '@mui/material/TableCell';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import {useQuery, gql} from '@apollo/client';
|
||||
import DialogActions from '@mui/material/DialogActions';
|
||||
@@ -111,6 +112,7 @@ export function ViewCallbackMythicTreeGroupsDialog(props){
|
||||
<Backdrop open={backdropOpen} style={{zIndex: 2, position: "absolute"}} invisible={false}>
|
||||
<CircularProgress color="inherit" />
|
||||
</Backdrop>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table stickyHeader={true} size="small" style={{ "overflowWrap": "break-word", width: "100%"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -154,6 +156,7 @@ export function ViewCallbackMythicTreeGroupsDialog(props){
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={props.onClose} variant="contained" color="primary">
|
||||
@@ -240,6 +243,7 @@ export function ViewAllCallbackMythicTreeGroupsDialog(props){
|
||||
{g.group}
|
||||
</Typography>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" aria-label="details" style={{ "overflowWrap": "break-word", width: "100%"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -283,6 +287,7 @@ export function ViewAllCallbackMythicTreeGroupsDialog(props){
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</div>
|
||||
|
||||
))}
|
||||
|
||||
+3
@@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import { CreatePayloadParameter } from './CreatePayloadParameter';
|
||||
@@ -13,6 +14,7 @@ export function CreatePayloadC2ProfileParametersTable(props){
|
||||
props.onChange(props.name, paramName, value, error);
|
||||
}
|
||||
return (
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" style={{"tableLayout": "fixed", "maxWidth": "calc(100vw)", "overflow": "auto"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -26,5 +28,6 @@ export function CreatePayloadC2ProfileParametersTable(props){
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -586,7 +586,7 @@ export function CreatePayloadParameter({onChange, parameter_type, default_value,
|
||||
);
|
||||
case "Array":
|
||||
return (
|
||||
<TableContainer >
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" style={{tableLayout: "fixed", maxWidth: "100%", "overflow": "auto"}}>
|
||||
<TableBody>
|
||||
{arrayValue.map( (a, i) => (
|
||||
@@ -616,7 +616,7 @@ export function CreatePayloadParameter({onChange, parameter_type, default_value,
|
||||
);
|
||||
case "TypedArray":
|
||||
return (
|
||||
<TableContainer >
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" style={{tableLayout: "fixed", maxWidth: "100%", "overflow": "auto"}}>
|
||||
<TableBody>
|
||||
{typedArrayValue.map( (a, i) => (
|
||||
@@ -819,4 +819,3 @@ export function CreatePayloadParameter({onChange, parameter_type, default_value,
|
||||
</TableRow>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import { snackActions } from '../../utilities/Snackbar';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableCell from '@mui/material/TableCell';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import { meState } from '../../../cache';
|
||||
@@ -199,7 +200,7 @@ export function PayloadSelect(props) {
|
||||
props.finished(payload);
|
||||
}
|
||||
return (
|
||||
<div style={{height: "100%", overflow: "auto"}}>
|
||||
<TableContainer className="mythicElement" style={{height: "100%", overflow: "auto"}}>
|
||||
<Table stickyHeader size="small" style={{tableLayout:"fixed", maxWidth: "100%",}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -222,7 +223,7 @@ export function PayloadSelect(props) {
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</TableContainer>
|
||||
|
||||
);
|
||||
}
|
||||
@@ -262,4 +263,4 @@ export function PayloadsTableRow(props){
|
||||
</TableRow>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import DialogContent from '@mui/material/DialogContent';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import { useReactiveVar } from '@apollo/client';
|
||||
import {meState} from "../../../cache";
|
||||
import {Table, TableBody, TableHead, TableRow, Typography, IconButton, Paper, Switch} from '@mui/material';
|
||||
import {Table, TableBody, TableContainer, TableHead, TableRow, Typography, IconButton, Paper, Switch} from '@mui/material';
|
||||
import FormControl from '@mui/material/FormControl';
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import TextField from '@mui/material/TextField';
|
||||
@@ -632,7 +632,7 @@ const CreateEventingStep1 = ({finished, back, first, last, cancel, prevData}) =>
|
||||
}, [prevData]);
|
||||
return (
|
||||
<>
|
||||
<div style={{flexGrow: 1, width: "100%", display: "flex", flexDirection: "column", overflowY: "auto"}}>
|
||||
<TableContainer className="mythicElement" style={{flexGrow: 1, width: "100%", display: "flex", flexDirection: "column", overflowY: "auto"}}>
|
||||
<Table style={{tableLayout: "fixed", width: "100%",}}>
|
||||
<TableHead >
|
||||
<TableRow>
|
||||
@@ -742,7 +742,7 @@ const CreateEventingStep1 = ({finished, back, first, last, cancel, prevData}) =>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</TableContainer>
|
||||
<CreateEventingStepperNavigationButtons first={first} last={last} finished={finishedStep1} back={back} cancel={cancel} />
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -8,6 +8,7 @@ import {useMutation, gql} from '@apollo/client';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableCell from '@mui/material/TableCell';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
|
||||
@@ -64,6 +65,7 @@ export function EventGroupTableRunAsDialog({eventgroupapprovals, me, onClose, se
|
||||
<b>Run As: </b>{selectedEventGroup.run_as} <br/>
|
||||
{getRunAsHelp(selectedEventGroup.run_as)}
|
||||
</DialogContentText>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -126,6 +128,7 @@ export function EventGroupTableRunAsDialog({eventgroupapprovals, me, onClose, se
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
@@ -136,4 +139,3 @@ export function EventGroupTableRunAsDialog({eventgroupapprovals, me, onClose, se
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import DialogTitle from '@mui/material/DialogTitle';
|
||||
import {useMutation, gql} from '@apollo/client';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
|
||||
import {snackActions} from "../../utilities/Snackbar";
|
||||
@@ -52,6 +53,7 @@ export function EventFileManageDialog({onClose, selectedEventGroup}) {
|
||||
<DialogContentText>
|
||||
These files can be accessed via `workflow.filename` in a step's inputs.
|
||||
</DialogContentText>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table>
|
||||
<TableBody>
|
||||
{selectedEventGroup.filemeta.map( e => (
|
||||
@@ -59,6 +61,7 @@ export function EventFileManageDialog({onClose, selectedEventGroup}) {
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose} variant="contained" color="primary">
|
||||
@@ -127,4 +130,4 @@ function EventFileManageDialogTableRow({eventFile}) {
|
||||
</MythicStyledTableCell>
|
||||
</TableRow>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import DialogTitle from '@mui/material/DialogTitle';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableCell from '@mui/material/TableCell';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
|
||||
@@ -22,6 +23,7 @@ export function EventGroupConsumingContainersDialog({onClose, selectedEventGroup
|
||||
</DialogTitle>
|
||||
|
||||
<DialogContent dividers={true} style={{maxHeight: "calc(70vh)"}}>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -37,6 +39,7 @@ export function EventGroupConsumingContainersDialog({onClose, selectedEventGroup
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose} variant="contained" color="primary">
|
||||
@@ -84,4 +87,4 @@ function EventGroupConsumingContainersDialogTableRow({container}) {
|
||||
</MythicStyledTableCell>
|
||||
</TableRow>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import AddCircleIcon from '@mui/icons-material/AddCircle';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableCell from '@mui/material/TableCell';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
@@ -210,6 +211,7 @@ export function EventGroupTable({selectedEventGroup, me, showInstances, showGrap
|
||||
)
|
||||
}
|
||||
<br/><Typography variant={"h8"}>{selectedEventGroup?.description}</Typography>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -343,6 +345,7 @@ export function EventGroupTable({selectedEventGroup, me, showInstances, showGrap
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
|
||||
</div>
|
||||
}
|
||||
@@ -474,4 +477,4 @@ function RenderSteps({selectedEventGroup, selectedInstanceID}){
|
||||
{getRenderer()}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import MythicTableCell from "../../MythicComponents/MythicTableCell";
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableCell from '@mui/material/TableCell';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import MythicStyledTableCell from "../../MythicComponents/MythicTableCell";
|
||||
@@ -1106,6 +1107,7 @@ function EventStepInstanceDetailDialog({selectedEventStepInstance, onClose}) {
|
||||
Original and Instance Metadata
|
||||
</AccordionSummary>
|
||||
<AccordionDetails style={{cursor: "default"}}>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table style={{width: "100%", overflow: "auto", tableLayout: "fixed", }}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -1167,6 +1169,7 @@ function EventStepInstanceDetailDialog({selectedEventStepInstance, onClose}) {
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</Paper>
|
||||
@@ -1241,6 +1244,7 @@ function EventStepInstanceDetailDialog({selectedEventStepInstance, onClose}) {
|
||||
Callbacks Generated
|
||||
</Typography>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table>
|
||||
<TableBody>
|
||||
{data.eventstepinstance_by_pk.callbacks.map(trackedData => (
|
||||
@@ -1253,6 +1257,7 @@ function EventStepInstanceDetailDialog({selectedEventStepInstance, onClose}) {
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</>
|
||||
}
|
||||
<EventDetailsFilesTable files={data.eventstepinstance_by_pk.filemeta} />
|
||||
@@ -1265,6 +1270,7 @@ function EventStepInstanceDetailDialog({selectedEventStepInstance, onClose}) {
|
||||
API Tokens generated
|
||||
</Typography>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -1287,6 +1293,7 @@ function EventStepInstanceDetailDialog({selectedEventStepInstance, onClose}) {
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</>
|
||||
}
|
||||
</DialogContent>
|
||||
@@ -1395,6 +1402,7 @@ function EventGroupInstanceDetailDialog({selectedEventGroupInstance, onClose}) {
|
||||
Callbacks Generated
|
||||
</Typography>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table>
|
||||
<TableBody>
|
||||
{data.callback.map(trackedData => (
|
||||
@@ -1410,6 +1418,7 @@ function EventGroupInstanceDetailDialog({selectedEventGroupInstance, onClose}) {
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</>
|
||||
}
|
||||
<EventDetailsFilesTable files={data?.filemeta} />
|
||||
@@ -1422,6 +1431,7 @@ function EventGroupInstanceDetailDialog({selectedEventGroupInstance, onClose}) {
|
||||
API Tokens generated
|
||||
</Typography>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -1444,6 +1454,7 @@ function EventGroupInstanceDetailDialog({selectedEventGroupInstance, onClose}) {
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</>
|
||||
}
|
||||
|
||||
@@ -1518,6 +1529,7 @@ function EventStepDetailDialog({selectedEventStep, onClose}) {
|
||||
variant={'h5'} component={Paper} >
|
||||
Action: <b>{data.eventstep_by_pk.action}</b>
|
||||
</Typography>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table style={{width: "100%", overflow: "auto", tableLayout: "fixed"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -1564,6 +1576,7 @@ function EventStepDetailDialog({selectedEventStep, onClose}) {
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose} variant="contained" color="primary">
|
||||
@@ -1630,6 +1643,7 @@ function EventDetailsPayloadsTable({payloads, deletePayload}){
|
||||
<ArchiveIcon/>Zip & Download All Available Payloads
|
||||
</Button>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table>
|
||||
<TableBody>
|
||||
{openDelete &&
|
||||
@@ -1674,6 +1688,7 @@ function EventDetailsPayloadsTable({payloads, deletePayload}){
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1687,6 +1702,7 @@ function EventDetailsTaskTable({tasks}){
|
||||
Tasks Issued
|
||||
</Typography>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table>
|
||||
<TableBody>
|
||||
{tasks.map(trackedData => (
|
||||
@@ -1713,6 +1729,7 @@ function EventDetailsTaskTable({tasks}){
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1757,6 +1774,7 @@ function EventDetailsFilesTable({files}){
|
||||
<ArchiveIcon/>Zip & Download All Files
|
||||
</Button>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -1794,6 +1812,7 @@ function EventDetailsFilesTable({files}){
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import {useMutation,useQuery, gql} from '@apollo/client';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableCell from '@mui/material/TableCell';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import {IconButton} from '@mui/material';
|
||||
@@ -223,6 +224,7 @@ export function EventTriggerContextSelectDialog({onClose, triggerContext}) {
|
||||
{selectedEventGroup.id !== 0 &&
|
||||
<EventGroupTable me={me} selectedEventGroup={selectedEventGroup} showInstances={false} showGraph={false} height={"unset"}/>
|
||||
}
|
||||
<TableContainer className="mythicElement">
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -269,6 +271,7 @@ export function EventTriggerContextSelectDialog({onClose, triggerContext}) {
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
@@ -281,4 +284,4 @@ export function EventTriggerContextSelectDialog({onClose, triggerContext}) {
|
||||
</DialogActions>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import {useMutation, gql} from '@apollo/client';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableCell from '@mui/material/TableCell';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import {IconButton} from '@mui/material';
|
||||
@@ -120,6 +121,7 @@ export function EventTriggerKeywordDialog({onClose, selectedEventGroup}) {
|
||||
))
|
||||
}
|
||||
</Select>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -166,6 +168,7 @@ export function EventTriggerKeywordDialog({onClose, selectedEventGroup}) {
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
@@ -178,4 +181,4 @@ export function EventTriggerKeywordDialog({onClose, selectedEventGroup}) {
|
||||
</DialogActions>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, {useEffect} from 'react';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableCell from '@mui/material/TableCell';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import Paper from '@mui/material/Paper';
|
||||
@@ -56,6 +57,7 @@ export function ExpandedCallbackSideDetailsTable(props){
|
||||
updateSleep({variables: {callback_display_id: callback_display_id, sleep_info}})
|
||||
}, [])
|
||||
return (
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" style={{tableLayout: "fixed"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -220,5 +222,6 @@ export function ExpandedCallbackSideDetailsTable(props){
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import {Gauge, GaugeContainer,
|
||||
GaugeReferenceArc,
|
||||
useGaugeState} from '@mui/x-charts/Gauge';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import { BarChart } from '@mui/x-charts/BarChart';
|
||||
import {MythicStyledTooltip} from "../../MythicComponents/MythicStyledTooltip";
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
@@ -53,7 +54,7 @@ export const PieChartCard = ({
|
||||
width: width,
|
||||
height: "100%",
|
||||
border: `1px solid ${theme.borderColor}`,
|
||||
borderRadius: "5px",
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
overflow: "hidden",
|
||||
}}>
|
||||
<h3 style={{marginTop: 0, marginLeft: "0.5rem", marginBottom: 0, paddingBottom: 0,}}>
|
||||
@@ -172,7 +173,7 @@ export const GaugeCard = ({data, width = "100%", additionalStyles, innerElement,
|
||||
width: width,
|
||||
height: "100%",
|
||||
border: `1px solid ${theme.borderColor}`,
|
||||
borderRadius: "5px",
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
overflow: "hidden",
|
||||
}}>
|
||||
<h3 style={{marginTop: 0, marginLeft: "0.5rem", marginBottom: 0, paddingBottom: 0,}}>
|
||||
@@ -221,7 +222,7 @@ export const CallbackDataCard = ({mainTitle, secondTitle, mainElement, secondary
|
||||
width: width,
|
||||
height: "100%",
|
||||
border: `1px solid ${theme.borderColor}`,
|
||||
borderRadius: "5px",
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
overflow: "hidden",
|
||||
}} >
|
||||
<h2 style={{marginTop: 0, marginLeft: "0.5rem", marginBottom: 0, paddingBottom: 0}}>
|
||||
@@ -256,7 +257,7 @@ export const TableDataCard = ({title, width = "100%", tableHead, tableBody, edit
|
||||
width: width,
|
||||
height: "100%",
|
||||
border: `1px solid ${theme.borderColor}`,
|
||||
borderRadius: "5px",
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
overflow: "hidden",
|
||||
}}>
|
||||
<h3 style={{marginTop: 0, marginLeft: "0.5rem", marginBottom: 0, paddingBottom: 0}}>
|
||||
@@ -274,12 +275,12 @@ export const TableDataCard = ({title, width = "100%", tableHead, tableBody, edit
|
||||
{customizeElement}
|
||||
</span>
|
||||
</h3>
|
||||
<div style={{height: 200, overflowY: "auto", width: "100%"}}>
|
||||
<TableContainer className="mythicElement" style={{height: 200, overflowY: "auto", width: "100%"}}>
|
||||
<Table style={{ maxWidth: "100%", overflow: "auto"}} stickyHeader size="small">
|
||||
{tableHead}
|
||||
{tableBody}
|
||||
</Table>
|
||||
</div>
|
||||
</TableContainer>
|
||||
</Paper>
|
||||
)
|
||||
}
|
||||
@@ -319,7 +320,7 @@ export const LineTimeChartCard = ({data, additionalStyles}) => {
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
border: `1px solid ${theme.borderColor}`,
|
||||
borderRadius: "5px",
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
overflow: "hidden",
|
||||
}} >
|
||||
<Typography variant={"h3"} style={{margin: 0, padding: 0, position: "relative", left: "30%"}}>
|
||||
@@ -434,7 +435,7 @@ export const LineTimeMultiChartCard = ({data, additionalStyles, colors=normalCol
|
||||
marginRight: "0.5rem",
|
||||
height: "100%",
|
||||
border: `1px solid ${theme.borderColor}`,
|
||||
borderRadius: "5px",
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
overflow: "hidden",
|
||||
}} >
|
||||
<Typography variant={"h3"} style={{margin: 0, padding: 0, position: "relative", left: "30%"}}>
|
||||
@@ -522,7 +523,7 @@ export const StackedBarChartCard = ({data, labels, title, width="100%", hidden,
|
||||
width: width,
|
||||
height: "100%",
|
||||
border: `1px solid ${theme.borderColor}`,
|
||||
borderRadius: "5px",
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
overflow: "hidden",
|
||||
}} >
|
||||
<h3 style={{marginTop: 0, marginLeft: "5px", marginBottom: 0, paddingBottom: 0, position: "absolute"}}>
|
||||
@@ -554,4 +555,4 @@ export const StackedBarChartCard = ({data, labels, title, width="100%", hidden,
|
||||
}} />
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import TableCell from '@mui/material/TableCell';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { meState } from '../../../cache';
|
||||
@@ -89,6 +90,7 @@ function DetailedCommandMappingTables({commands}){
|
||||
{c[0]}
|
||||
</Typography>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" aria-label="details" style={{ "overflowWrap": "break-word"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -108,6 +110,7 @@ function DetailedCommandMappingTables({commands}){
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</div>
|
||||
))}
|
||||
</React.Fragment>
|
||||
@@ -126,6 +129,7 @@ function DetailedTaskMappingTables({tasks}){
|
||||
{c[0]}
|
||||
</Typography>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" aria-label="details" style={{ "overflowWrap": "break-word"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -150,8 +154,9 @@ function DetailedTaskMappingTables({tasks}){
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+38
-6
@@ -8,9 +8,9 @@ import MythicTextField from '../../MythicComponents/MythicTextField';
|
||||
import {useQuery, gql} from '@apollo/client';
|
||||
import {snackActions} from '../../utilities/Snackbar';
|
||||
import Switch from '@mui/material/Switch';
|
||||
import {HexColorInput, HexColorPicker} from 'react-colorful';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import Box from '@mui/material/Box';
|
||||
import {getReadableTextColor, MythicColorSwatchInput} from '../../MythicComponents/MythicColorInput';
|
||||
|
||||
const GET_OperationData = gql`
|
||||
query GetOperations($operation_id: Int!) {
|
||||
@@ -118,10 +118,43 @@ export function OperationTableRowNotificationsDialog(props) {
|
||||
onChange={onTextChange}
|
||||
name="Banner Text"
|
||||
/>
|
||||
<HexColorPicker color={bannerColor} onChange={setBannerColor} />
|
||||
<HexColorInput color={bannerColor} onChange={setBannerColor} />
|
||||
<Box sx={{width: "100%", height: 25, backgroundColor: bannerColor}} >
|
||||
<Typography style={{color: "white"}}>{bannerText}</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
mt: 2,
|
||||
p: 1.5,
|
||||
border: "1px solid",
|
||||
borderColor: "divider",
|
||||
borderRadius: "8px",
|
||||
backgroundColor: "background.paper",
|
||||
}}
|
||||
>
|
||||
<Box sx={{display: "flex", alignItems: "center", justifyContent: "space-between", gap: 2, mb: 1}}>
|
||||
<Box sx={{minWidth: 0}}>
|
||||
<Typography variant="body2" sx={{fontWeight: 700}}>Banner Color</Typography>
|
||||
<Typography variant="caption" sx={{color: "text.secondary"}}>Operation banner background</Typography>
|
||||
</Box>
|
||||
<MythicColorSwatchInput
|
||||
color={bannerColor}
|
||||
label="Operation banner color"
|
||||
onChange={setBannerColor}
|
||||
/>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
minHeight: 38,
|
||||
px: 1.5,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
borderRadius: "6px",
|
||||
backgroundColor: bannerColor,
|
||||
border: "1px solid",
|
||||
borderColor: "divider",
|
||||
}}
|
||||
>
|
||||
<Typography sx={{color: getReadableTextColor(bannerColor), fontWeight: 700}}>
|
||||
{bannerText || "Operation Banner"}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
@@ -135,4 +168,3 @@ export function OperationTableRowNotificationsDialog(props) {
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import TableCell from '@mui/material/TableCell';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import LinearProgress from '@mui/material/LinearProgress';
|
||||
import { getDefaultChoices } from '../CreatePayload/Step2SelectPayloadType';
|
||||
@@ -91,6 +92,7 @@ export function C2ProfileBuildDialog(props) {
|
||||
<DialogContentText>
|
||||
These are the build parameters associated with this payload
|
||||
</DialogContentText>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" aria-label="details" style={{"tableLayout": "fixed", "overflowWrap": "break-word"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -127,6 +129,7 @@ export function C2ProfileBuildDialog(props) {
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button variant="contained" onClick={props.onClose} color="primary">
|
||||
@@ -136,4 +139,3 @@ export function C2ProfileBuildDialog(props) {
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -111,7 +111,7 @@ export function C2ProfileListFilesDialog(props) {
|
||||
<input onChange={onFileChange} type="file" multiple hidden />
|
||||
</Button>
|
||||
</DialogTitle>
|
||||
<TableContainer >
|
||||
<TableContainer className="mythicElement">
|
||||
<Table stickyHeader size="small" style={{ "maxWidth": "100%", "overflow": "scroll"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -225,4 +225,3 @@ const C2ProfileListFilesDialogTableRow = ({container_name, id, filename}) => {
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import {MythicDialog} from "../../MythicComponents/MythicDialog";
|
||||
import {C2ProfileListFilesDialog} from "./C2ProfileListFilesDialog";
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
|
||||
const toggleDeleteStatus = gql`
|
||||
@@ -103,6 +104,7 @@ export function CustomBrowserRow({service, showDeleted}) {
|
||||
</MythicStyledTooltip>
|
||||
</MythicTableCell>
|
||||
<MythicTableCell style={{padding: 0}}>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow hover>
|
||||
@@ -119,6 +121,8 @@ export function CustomBrowserRow({service, showDeleted}) {
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow hover>
|
||||
@@ -135,6 +139,8 @@ export function CustomBrowserRow({service, showDeleted}) {
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow hover>
|
||||
@@ -155,6 +161,7 @@ export function CustomBrowserRow({service, showDeleted}) {
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</MythicTableCell>
|
||||
|
||||
{openListFilesDialog &&
|
||||
|
||||
@@ -9,6 +9,7 @@ import TableCell from '@mui/material/TableCell';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import LinearProgress from '@mui/material/LinearProgress';
|
||||
import { getDefaultChoices } from '../CreatePayload/Step2SelectPayloadType';
|
||||
@@ -99,6 +100,7 @@ export function PayloadTypeBuildDialog(props) {
|
||||
<DialogContentText>
|
||||
These are the build parameters associated with this payload
|
||||
</DialogContentText>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" aria-label="details" style={{"tableLayout": "fixed", "overflowWrap": "break-word"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -135,6 +137,7 @@ export function PayloadTypeBuildDialog(props) {
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button variant="contained" onClick={props.onClose} color="primary">
|
||||
@@ -144,4 +147,3 @@ export function PayloadTypeBuildDialog(props) {
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -10,6 +10,7 @@ import TableCell from '@mui/material/TableCell';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import LinearProgress from '@mui/material/LinearProgress';
|
||||
import MenuBookIcon from '@mui/icons-material/MenuBook';
|
||||
@@ -93,6 +94,7 @@ export function PayloadTypeCommandDialog({service, payload_name, onClose}) {
|
||||
<React.Fragment>
|
||||
<DialogTitle id="form-dialog-title">{payload_name}'s Commands</DialogTitle>
|
||||
<DialogContent dividers={true} style={{padding: 0}}>
|
||||
<TableContainer className="mythicElement" style={{height: "100%"}}>
|
||||
<Table size="small" stickyHeader={true} aria-label="details"
|
||||
style={{"tableLayout": "fixed", "overflowWrap": "break-word", overflowY:"auto", width: "100%", height: "100%"}}>
|
||||
<TableHead>
|
||||
@@ -136,6 +138,7 @@ export function PayloadTypeCommandDialog({service, payload_name, onClose}) {
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
{openScriptDialog.open &&
|
||||
<MythicDialog fullWidth={true} maxWidth="lg" open={openScriptDialog.open}
|
||||
onClose={()=>{setOpenScriptDialog({open: false, command_id: 0});}}
|
||||
@@ -226,6 +229,7 @@ export function ScriptingCommandDialog({command_id, command_name, onClose}){
|
||||
Parameter Group: {paramGroup[0].parameter_group_name}
|
||||
</Typography>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table style={{tableLayout: "fixed"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -373,6 +377,7 @@ export function ScriptingCommandDialog({command_id, command_name, onClose}){
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
|
||||
</div>
|
||||
))}
|
||||
@@ -385,4 +390,3 @@ export function ScriptingCommandDialog({command_id, command_name, onClose}){
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -423,7 +423,7 @@ A few examples are github.com/MythicAgents/bloodhound and github.com/MythicAgent
|
||||
return (
|
||||
<MythicTabPanel {...props} >
|
||||
<div style={{display: "flex", flexGrow: 1, overflowY: "auto"}}>
|
||||
<TableContainer>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table stickyHeader size="small" style={{"maxWidth": "100%", "overflow": "scroll"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -492,7 +492,7 @@ You can extend this auth capability to support your own LDAP, SSO, or otherwise
|
||||
return (
|
||||
<MythicTabPanel {...props} >
|
||||
<div style={{display: "flex", flexGrow: 1, overflowY: "auto"}}>
|
||||
<TableContainer>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table stickyHeader size="small" style={{"maxWidth": "100%", "overflow": "scroll"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -542,7 +542,7 @@ const ContainersTabCustomBrowsersPanel = (props) => {
|
||||
return (
|
||||
<MythicTabPanel {...props} >
|
||||
<div style={{display: "flex", flexGrow: 1, overflowY: "auto"}}>
|
||||
<TableContainer>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table stickyHeader size="small" style={{"maxWidth": "100%", "overflow": "scroll"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
|
||||
@@ -3,6 +3,7 @@ import TableCell from '@mui/material/TableCell';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import {useQuery, gql, useMutation} from '@apollo/client';
|
||||
@@ -551,6 +552,7 @@ function DetailedPayloadInnerTable(props){
|
||||
Payload Information
|
||||
</Typography>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" aria-label="details" style={{ "overflowWrap": "break-word"}}>
|
||||
<TableHead>
|
||||
<TableRow hover>
|
||||
@@ -656,11 +658,13 @@ function DetailedPayloadInnerTable(props){
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<Paper elevation={5} style={{backgroundColor: theme.pageHeader.main, color: theme.pageHeaderText.main,marginBottom: "5px", marginTop: "10px"}} variant={"elevation"}>
|
||||
<Typography variant="h6" style={{textAlign: "left", display: "inline-block", marginLeft: "20px", color: theme.pageHeaderColor}}>
|
||||
Build Parameters
|
||||
</Typography>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" aria-label="details" style={{ "overflowWrap": "break-word"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -695,11 +699,13 @@ function DetailedPayloadInnerTable(props){
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<Paper elevation={5} style={{backgroundColor: theme.pageHeader.main, color: theme.pageHeaderText.main,marginBottom: "5px", marginTop: "10px"}} variant={"elevation"}>
|
||||
<Typography variant="h6" style={{textAlign: "left", display: "inline-block", marginLeft: "20px", color: theme.pageHeaderColor}}>
|
||||
Build Steps
|
||||
</Typography>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" aria-label="details" style={{ "overflowWrap": "break-word"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -723,6 +729,7 @@ function DetailedPayloadInnerTable(props){
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
{ c2Profiles.map( (c2) => (
|
||||
<React.Fragment key={"c2frag" + props.payload_id + c2.c2_profile}>
|
||||
<Paper elevation={5} style={{backgroundColor: theme.pageHeader.main, color: theme.pageHeaderText.main,marginBottom: "5px", marginTop: "10px"}} variant={"elevation"}>
|
||||
@@ -730,6 +737,7 @@ function DetailedPayloadInnerTable(props){
|
||||
{c2.c2_profile}
|
||||
</Typography>
|
||||
</Paper>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" aria-label="details" style={{"overflowWrap": "break-word"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -764,6 +772,7 @@ function DetailedPayloadInnerTable(props){
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</React.Fragment>
|
||||
))}
|
||||
|
||||
@@ -775,6 +784,7 @@ function DetailedPayloadInnerTable(props){
|
||||
<Button style={{float: "right"}} variant="contained" size="small" onClick={()=>{setOpenAddRemoveCommandsDialog(true)}} >Add/Remove Commands</Button>
|
||||
</Paper>
|
||||
{commands.length > 0 &&
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" aria-label="details" style={{"overflowWrap": "break-word"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -803,6 +813,7 @@ function DetailedPayloadInnerTable(props){
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
}
|
||||
</React.Fragment>
|
||||
|
||||
@@ -860,4 +871,4 @@ function DetailedPayloadInnerTable(props){
|
||||
}
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import MythicTableCell from "../../MythicComponents/MythicTableCell";
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import MythicTextField from "../../MythicComponents/MythicTextField";
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import FormControl from '@mui/material/FormControl';
|
||||
@@ -101,6 +102,7 @@ export function HostFileDialog(props) {
|
||||
<React.Fragment>
|
||||
<DialogTitle id="form-dialog-title">Host File via C2 Profile</DialogTitle>
|
||||
<DialogContent dividers={true}>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" aria-label="details" style={{ "overflowWrap": "break-word"}}>
|
||||
<TableBody>
|
||||
<TableRow hover>
|
||||
@@ -140,6 +142,7 @@ export function HostFileDialog(props) {
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button variant="contained" onClick={props.onClose} color="primary">
|
||||
@@ -155,4 +158,3 @@ export function HostFileDialog(props) {
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,13 @@ import React from 'react';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableCell from '@mui/material/TableCell';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import Paper from '@mui/material/Paper';
|
||||
import Button from '@mui/material/Button';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { PayloadsTableRow } from './PayloadsTableRow';
|
||||
import {useTheme} from '@mui/material/styles';
|
||||
import {ImportPayloadConfigDialog} from './ImportPayloadConfigDialog';
|
||||
import { MythicDialog } from '../../MythicComponents/MythicDialog';
|
||||
import ButtonGroup from '@mui/material/ButtonGroup';
|
||||
@@ -27,7 +27,6 @@ import {MythicPageHeader} from "../../MythicComponents/MythicPageHeader";
|
||||
export function PayloadsTable({payload, onDeletePayload, onUpdateCallbackAlert, onRestorePayload, me,
|
||||
pageData, onChangePage, onChangeShowDeleted, onChangeShowAutogenerated,
|
||||
onCallbacksAllowedChanged, openBackdrop}){
|
||||
const theme = useTheme();
|
||||
const [showDeleted, setShowDeleted] = React.useState(false);
|
||||
const [showAutogenerated, setShowAutogenerated] = React.useState(false);
|
||||
const [openPayloadImport, setOpenPayloadImport] = React.useState(false);
|
||||
@@ -118,13 +117,13 @@ export function PayloadsTable({payload, onDeletePayload, onUpdateCallbackAlert,
|
||||
/>
|
||||
}
|
||||
</MythicPageHeader>
|
||||
<div style={{flexGrow: 1, overflowY: "auto", height: "100%", position: "relative"}}>
|
||||
<TableContainer className="mythicElement" style={{flexGrow: 1, overflowY: "auto", height: "100%", position: "relative"}}>
|
||||
{openBackdrop &&
|
||||
<Backdrop open={openBackdrop} style={{zIndex: 2000, position: "absolute"}}>
|
||||
<CircularProgress color="inherit" disableShrink />
|
||||
</Backdrop>
|
||||
}
|
||||
<Table stickyHeader size="small" style={{ "maxWidth": "100%", "overflow": "auto", tableLayout: "fixed"}}>
|
||||
<Table stickyHeader size="small" style={{maxWidth: "100%", tableLayout: "fixed"}}>
|
||||
<TableHead >
|
||||
<TableRow>
|
||||
<TableCell style={{width: "6rem"}}></TableCell>
|
||||
@@ -151,7 +150,7 @@ export function PayloadsTable({payload, onDeletePayload, onUpdateCallbackAlert,
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</TableContainer>
|
||||
<div style={{background: "transparent", display: "flex", justifyContent: "center", alignItems: "center", paddingTop: "5px", paddingBottom: "10px"}}>
|
||||
<Pagination count={Math.ceil(pageData.totalCount / pageData.fetchLimit)} variant="outlined" color="primary" boundaryCount={1}
|
||||
siblingCount={1} onChange={onChangePage} showFirstButton={true} showLastButton={true} style={{padding: "20px"}}/>
|
||||
@@ -161,4 +160,3 @@ export function PayloadsTable({payload, onDeletePayload, onUpdateCallbackAlert,
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import TableCell from '@mui/material/TableCell';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import DialogContent from '@mui/material/DialogContent';
|
||||
|
||||
@@ -171,6 +172,7 @@ export function PayloadBuildStepStatusDialog(props) {
|
||||
<React.Fragment>
|
||||
<DialogTitle id="form-dialog-title">Step {props.step.step_number + 1} - {props.step.step_name}</DialogTitle>
|
||||
<DialogContent>
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" style={{ maxWidth: "100%", overflow: "scroll"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -206,6 +208,7 @@ export function PayloadBuildStepStatusDialog(props) {
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button variant="contained" onClick={props.onClose} color="primary">
|
||||
|
||||
@@ -252,7 +252,7 @@ export function FileMetaDownloadTable(props){
|
||||
<DeleteIcon />Delete Selected
|
||||
</Button>
|
||||
</span>
|
||||
<div style={{height: "100%", overflowY: "auto"}}>
|
||||
<TableContainer className="mythicElement" style={{height: "100%", overflowY: "auto"}}>
|
||||
<Table stickyHeader size="small" style={{"tableLayout": "fixed", "maxWidth": "100%", "overflow": "scroll"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -284,7 +284,7 @@ export function FileMetaDownloadTable(props){
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</TableContainer>
|
||||
</TableContainer>
|
||||
)
|
||||
}
|
||||
@@ -639,7 +639,7 @@ export function FileMetaUploadTable(props){
|
||||
<DeleteIcon />Delete Selected
|
||||
</Button>
|
||||
</span>
|
||||
<div style={{height: "100%", overflowY: "auto"}}>
|
||||
<TableContainer className="mythicElement" style={{height: "100%", overflowY: "auto"}}>
|
||||
<Table stickyHeader size="small"
|
||||
style={{"tableLayout": "fixed", "maxWidth": "100%", "overflow": "scroll"}}>
|
||||
<TableHead>
|
||||
@@ -673,7 +673,7 @@ export function FileMetaUploadTable(props){
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</TableContainer>
|
||||
</TableContainer>
|
||||
)
|
||||
}
|
||||
@@ -1283,7 +1283,7 @@ export function FileMetaEventingWorkflowsTable(props){
|
||||
<DeleteIcon />Delete Selected
|
||||
</Button>
|
||||
</span>
|
||||
<div style={{height: "100%", overflowY: "auto"}}>
|
||||
<TableContainer className="mythicElement" style={{height: "100%", overflowY: "auto"}}>
|
||||
<Table stickyHeader size="small"
|
||||
style={{"tableLayout": "fixed", "maxWidth": "100%", "overflow": "scroll"}}>
|
||||
<TableHead>
|
||||
@@ -1316,7 +1316,7 @@ export function FileMetaEventingWorkflowsTable(props){
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</TableContainer>
|
||||
</TableContainer>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ export function SearchPayloadsTable({payloads, setPayloads, showDeleted, me}){
|
||||
}
|
||||
return (
|
||||
<div style={{display: "flex", flexGrow: 1, overflowY: "auto"}}>
|
||||
<TableContainer style={{height: "100%", overflowY: "auto"}}>
|
||||
<TableContainer className="mythicElement" style={{height: "100%", overflowY: "auto"}}>
|
||||
<Table stickyHeader size="small" style={{ "maxWidth": "100%", "overflow": "scroll", tableLayout: "fixed"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -153,4 +153,3 @@ export function SearchPayloadsTable({payloads, setPayloads, showDeleted, me}){
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ export function ProxySearchTable(props){
|
||||
}
|
||||
|
||||
return (
|
||||
<TableContainer style={{overflowY: "auto", flexGrow: 1, marginTop: "5px"}}>
|
||||
<TableContainer className="mythicElement" style={{overflowY: "auto", flexGrow: 1, marginTop: "5px"}}>
|
||||
<Table stickyHeader size="small" style={{tableLayout: "fixed"}}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
@@ -222,4 +222,3 @@ function ProxySearchTableRow(props){
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -293,7 +293,7 @@ export function CreateInviteLinksDialog(props) {
|
||||
<DialogContentText>
|
||||
<b style={{marginLeft: "10px"}}>{"Note:"}</b> Invite links are deleted if Mythic restarts
|
||||
</DialogContentText>
|
||||
<TableContainer >
|
||||
<TableContainer className="mythicElement">
|
||||
<Table size="small" style={{ "maxWidth": "100%", "overflow": "scroll", marginRight: "10px"}}>
|
||||
<TableBody>
|
||||
<TableRow hover>
|
||||
@@ -367,4 +367,3 @@ export function CreateInviteLinksDialog(props) {
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import React from 'react';
|
||||
import Table from '@mui/material/Table';
|
||||
import TableBody from '@mui/material/TableBody';
|
||||
import TableCell from '@mui/material/TableCell';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import TableHead from '@mui/material/TableHead';
|
||||
import TableRow from '@mui/material/TableRow';
|
||||
import {
|
||||
@@ -129,7 +130,7 @@ export function SettingsOperatorTable(props){
|
||||
/>
|
||||
}
|
||||
</MythicPageHeader>
|
||||
<div style={{display: "flex", flexGrow: 1, overflowY: "auto", alignItems: "flex-start"}}>
|
||||
<TableContainer className="mythicElement" style={{display: "flex", flexGrow: 1, overflowY: "auto", alignItems: "flex-start"}}>
|
||||
<Table stickyHeader size="small" style={{"tableLayout": "fixed",}}>
|
||||
<TableHead >
|
||||
<TableRow>
|
||||
@@ -163,8 +164,7 @@ export function SettingsOperatorTable(props){
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</TableContainer>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import TableBody from '@mui/material/TableBody';
|
||||
import Link from '@mui/material/Link';
|
||||
import TableContainer from '@mui/material/TableContainer';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import {HexColorInput, HexColorPicker} from 'react-colorful';
|
||||
import {GetMythicSetting, useSetMythicSetting} from "../../MythicComponents/MythicSavedUserSetting";
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import Select from '@mui/material/Select';
|
||||
@@ -28,6 +27,7 @@ import {copyStringToClipboard} from "../../utilities/Clipboard";
|
||||
import {useLazyQuery } from '@apollo/client';
|
||||
import PhoneCallbackIcon from '@mui/icons-material/PhoneCallback';
|
||||
import ColorLensIcon from '@mui/icons-material/ColorLens';
|
||||
import {MythicColorSwatchInput} from "../../MythicComponents/MythicColorInput";
|
||||
|
||||
const interactTypeOptions = [
|
||||
{value: "interact", display: "Accordions"},
|
||||
@@ -51,6 +51,406 @@ const isValidColor = (color) =>{
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const COLOR_EDITOR_SECTIONS = [
|
||||
{
|
||||
title: "Application Shell",
|
||||
description: "Page chrome, surfaces, typography, and borders.",
|
||||
colors: [
|
||||
{name: "background", display: "App Background", description: "Main page background behind views and dialogs.", preview: "surface"},
|
||||
{name: "paper", display: "Panel Background", description: "Menus, dialogs, and content surfaces.", preview: "surface"},
|
||||
{name: "pageHeader", display: "Page Headers", description: "Header bars at the top of major pages.", preview: "surface"},
|
||||
{name: "text", display: "Text", description: "Primary readable text throughout the UI.", preview: "surface"},
|
||||
{name: "borderColor", display: "Borders", description: "Outlines around panels, tables, and controls.", preview: "surface"},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Navigation",
|
||||
description: "Left navigation gradient, labels, and icons.",
|
||||
colors: [
|
||||
{name: "navBarColor", display: "Navigation Top", description: "Start color for the navigation background.", preview: "navigation"},
|
||||
{name: "navBarBottomColor", display: "Navigation Bottom", description: "End color for the navigation background.", preview: "navigation"},
|
||||
{name: "navBarIcons", display: "Navigation Icons", description: "Icon color in the navigation bar.", preview: "navigation"},
|
||||
{name: "navBarText", display: "Navigation Text", description: "Text color in the navigation bar.", preview: "navigation"},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Tables and Selection",
|
||||
description: "Table headers, hover states, and selected callback emphasis.",
|
||||
colors: [
|
||||
{name: "tableHeader", display: "Table Header", description: "Sticky header rows in tables and data grids.", preview: "table"},
|
||||
{name: "tableHover", display: "Table Hover", description: "Rows when hovered or softly emphasized.", preview: "table"},
|
||||
{name: "selectedCallbackColor", display: "Active Callback", description: "Currently active callback row highlight.", preview: "table"},
|
||||
{name: "selectedCallbackHierarchyColor", display: "Tree Host Highlight", description: "Current host highlight in tree views.", preview: "table"},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Status Colors",
|
||||
description: "Button, alert, tag, and status accents.",
|
||||
colors: [
|
||||
{name: "primary", display: "Primary", description: "Primary actions and key affordances.", preview: "status"},
|
||||
{name: "secondary", display: "Secondary", description: "Secondary actions and supporting accents.", preview: "status"},
|
||||
{name: "info", display: "Info", description: "Informational actions and notices.", preview: "status"},
|
||||
{name: "success", display: "Success", description: "Success actions, healthy states, and confirmations.", preview: "status"},
|
||||
{name: "warning", display: "Warning", description: "Warning actions and caution states.", preview: "status"},
|
||||
{name: "error", display: "Error", description: "Danger actions, failed states, and errors.", preview: "status"},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Tasking",
|
||||
description: "Task prompt, context badges, and command output.",
|
||||
colors: [
|
||||
{name: "taskPromptTextColor", display: "Prompt Text", description: "Tasking prompt text.", preview: "task"},
|
||||
{name: "taskPromptCommandTextColor", display: "Command Text", description: "Command and parameter text in tasking.", preview: "task"},
|
||||
{name: "taskContextColor", display: "Context", description: "Generic tasking context labels.", preview: "task"},
|
||||
{name: "taskContextImpersonationColor", display: "Impersonation Context", description: "User or impersonation tasking context labels.", preview: "task"},
|
||||
{name: "taskContextExtraColor", display: "Extra Context", description: "Additional tasking context labels.", preview: "task"},
|
||||
{name: "outputBackgroundColor", display: "Output Background", description: "Task output and terminal-style response background.", preview: "output"},
|
||||
{name: "outputTextColor", display: "Output Text", description: "Task output and terminal-style response text.", preview: "output"},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "File Browsing",
|
||||
description: "File browser empty-folder treatment.",
|
||||
colors: [
|
||||
{name: "emptyFolderColor", display: "Empty Folder", description: "Empty folder icon and text in file-based browsers.", preview: "file"},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const clonePalette = (sourcePalette) => {
|
||||
const clonedPalette = {};
|
||||
Object.entries(sourcePalette || {}).forEach(([key, value]) => {
|
||||
clonedPalette[key] = typeof value === "object" && value !== null ? {...value} : value;
|
||||
});
|
||||
return clonedPalette;
|
||||
}
|
||||
|
||||
const addAlpha = (color, alphaHex) => {
|
||||
if(isValidColor(color)){
|
||||
return `${color}${alphaHex}`;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
const getPaletteValue = (palette, name, mode) => {
|
||||
const color = palette?.[name]?.[mode];
|
||||
if(isValidColor(color)){
|
||||
return color;
|
||||
}
|
||||
const defaultColor = operatorSettingDefaults.palette?.[name]?.[mode];
|
||||
if(isValidColor(defaultColor)){
|
||||
return defaultColor;
|
||||
}
|
||||
return mode === "dark" ? "#1f2937" : "#f8fafc";
|
||||
}
|
||||
|
||||
const getReadableTextColor = (backgroundColor) => {
|
||||
if(!isValidColor(backgroundColor)){
|
||||
return "#ffffff";
|
||||
}
|
||||
const red = parseInt(backgroundColor.slice(1, 3), 16);
|
||||
const green = parseInt(backgroundColor.slice(3, 5), 16);
|
||||
const blue = parseInt(backgroundColor.slice(5, 7), 16);
|
||||
const brightness = (red * 299 + green * 587 + blue * 114) / 1000;
|
||||
return brightness >= 140 ? "#111827" : "#ffffff";
|
||||
}
|
||||
|
||||
const ModeColorControl = ({mode, name, color, onChange}) => (
|
||||
<Box sx={{minWidth: 0}}>
|
||||
<Typography variant="caption" sx={{display: "block", color: "text.secondary", mb: 0.5}}>
|
||||
{mode === "dark" ? "Dark" : "Light"}
|
||||
</Typography>
|
||||
<MythicColorSwatchInput
|
||||
color={color}
|
||||
label={`${name} ${mode} color`}
|
||||
onChange={(value) => onChange(name, mode, value)}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
|
||||
const PreviewLabel = ({children, color}) => (
|
||||
<Typography
|
||||
variant="caption"
|
||||
sx={{
|
||||
color,
|
||||
display: "block",
|
||||
lineHeight: 1.2,
|
||||
whiteSpace: "nowrap",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Typography>
|
||||
);
|
||||
|
||||
const ColorUsagePreview = ({option, palette, mode}) => {
|
||||
const background = getPaletteValue(palette, "background", mode);
|
||||
const paper = getPaletteValue(palette, "paper", mode);
|
||||
const text = getPaletteValue(palette, "text", mode);
|
||||
const border = getPaletteValue(palette, "borderColor", mode);
|
||||
const navTop = getPaletteValue(palette, "navBarColor", mode);
|
||||
const navBottom = getPaletteValue(palette, "navBarBottomColor", mode);
|
||||
const navIcon = getPaletteValue(palette, "navBarIcons", mode);
|
||||
const navText = getPaletteValue(palette, "navBarText", mode);
|
||||
const tableHeader = getPaletteValue(palette, "tableHeader", mode);
|
||||
const tableHover = getPaletteValue(palette, "tableHover", mode);
|
||||
const selectedCallback = getPaletteValue(palette, "selectedCallbackColor", mode);
|
||||
const selectedHierarchy = getPaletteValue(palette, "selectedCallbackHierarchyColor", mode);
|
||||
const outputBackground = getPaletteValue(palette, "outputBackgroundColor", mode);
|
||||
const outputText = getPaletteValue(palette, "outputTextColor", mode);
|
||||
const promptText = getPaletteValue(palette, "taskPromptTextColor", mode);
|
||||
const commandText = getPaletteValue(palette, "taskPromptCommandTextColor", mode);
|
||||
const context = getPaletteValue(palette, "taskContextColor", mode);
|
||||
const impersonation = getPaletteValue(palette, "taskContextImpersonationColor", mode);
|
||||
const extra = getPaletteValue(palette, "taskContextExtraColor", mode);
|
||||
const previewColor = getPaletteValue(palette, option.name, mode);
|
||||
const shellSx = {
|
||||
border: `1px solid ${addAlpha(border, "99")}`,
|
||||
borderRadius: "6px",
|
||||
overflow: "hidden",
|
||||
minHeight: 74,
|
||||
backgroundColor: background,
|
||||
};
|
||||
switch(option.preview){
|
||||
case "navigation":
|
||||
return (
|
||||
<Box sx={{...shellSx, display: "flex"}}>
|
||||
<Box sx={{width: 58, background: `linear-gradient(180deg, ${navTop}, ${navBottom})`, p: 1}}>
|
||||
<PhoneCallbackIcon style={{color: navIcon, fontSize: 18}}/>
|
||||
<PreviewLabel color={navText}>Tasks</PreviewLabel>
|
||||
</Box>
|
||||
<Box sx={{flex: 1, backgroundColor: paper, p: 1}}>
|
||||
<PreviewLabel color={text}>{mode} navigation</PreviewLabel>
|
||||
<Box sx={{height: 7, mt: 1, borderRadius: "4px", backgroundColor: previewColor}} />
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
case "table":
|
||||
return (
|
||||
<Box sx={shellSx}>
|
||||
<Box sx={{height: 22, px: 1, display: "flex", alignItems: "center", backgroundColor: tableHeader}}>
|
||||
<PreviewLabel color={text}>Table header</PreviewLabel>
|
||||
</Box>
|
||||
<Box sx={{height: 18, px: 1, display: "flex", alignItems: "center", borderTop: `1px solid ${addAlpha(border, "99")}`, backgroundColor: paper}}>
|
||||
<PreviewLabel color={text}>Normal row</PreviewLabel>
|
||||
</Box>
|
||||
<Box sx={{height: 18, px: 1, display: "flex", alignItems: "center", backgroundColor: addAlpha(tableHover, "CC")}}>
|
||||
<PreviewLabel color={text}>Hover row</PreviewLabel>
|
||||
</Box>
|
||||
<Box sx={{height: 18, display: "grid", gridTemplateColumns: "1fr 1fr"}}>
|
||||
<Box sx={{px: 1, backgroundColor: addAlpha(selectedCallback, "CC")}}>
|
||||
<PreviewLabel color={text}>Active</PreviewLabel>
|
||||
</Box>
|
||||
<Box sx={{px: 1, backgroundColor: addAlpha(selectedHierarchy, "CC")}}>
|
||||
<PreviewLabel color={text}>Tree</PreviewLabel>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
case "status":
|
||||
return (
|
||||
<Box sx={{...shellSx, p: 1, backgroundColor: paper}}>
|
||||
<Box sx={{display: "inline-flex", alignItems: "center", px: 1, py: 0.5, borderRadius: "4px", backgroundColor: previewColor, color: getReadableTextColor(previewColor), fontSize: "0.75rem", fontWeight: 700}}>
|
||||
{option.display}
|
||||
</Box>
|
||||
<Box sx={{mt: 1, height: 10, borderRadius: "4px", backgroundColor: addAlpha(previewColor, "66")}} />
|
||||
<PreviewLabel color={text}>{mode} accent</PreviewLabel>
|
||||
</Box>
|
||||
);
|
||||
case "task":
|
||||
return (
|
||||
<Box sx={{...shellSx, p: 1, backgroundColor: paper}}>
|
||||
<PreviewLabel color={promptText}>operator@host</PreviewLabel>
|
||||
<Typography variant="caption" sx={{color: commandText, display: "block", lineHeight: 1.2}}>
|
||||
shell whoami
|
||||
</Typography>
|
||||
<Box sx={{display: "flex", gap: 0.5, mt: 0.75, minWidth: 0}}>
|
||||
{[context, impersonation, extra].map((color, index) => (
|
||||
<Box key={`${mode}-${color}-${index}`} sx={{height: 12, flex: 1, borderRadius: "3px", backgroundColor: color}} />
|
||||
))}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
case "output":
|
||||
return (
|
||||
<Box sx={{...shellSx, p: 1, backgroundColor: outputBackground}}>
|
||||
<Typography variant="caption" sx={{color: outputText, display: "block", fontFamily: "monospace", lineHeight: 1.25}}>
|
||||
user\host
|
||||
</Typography>
|
||||
<Typography variant="caption" sx={{color: outputText, display: "block", fontFamily: "monospace", lineHeight: 1.25}}>
|
||||
completed
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
case "file":
|
||||
return (
|
||||
<Box sx={{...shellSx, p: 1, backgroundColor: paper}}>
|
||||
<Box sx={{height: 24, borderRadius: "4px", backgroundColor: addAlpha(previewColor, "33"), border: `1px solid ${addAlpha(previewColor, "99")}`}} />
|
||||
<Typography variant="caption" sx={{color: previewColor, display: "block", mt: 0.75, fontWeight: 700}}>
|
||||
Empty folder
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
case "surface":
|
||||
default:
|
||||
return (
|
||||
<Box sx={{...shellSx, p: 0.75}}>
|
||||
<Box sx={{height: 16, borderRadius: "4px 4px 0 0", backgroundColor: getPaletteValue(palette, "pageHeader", mode)}} />
|
||||
<Box sx={{p: 0.75, backgroundColor: paper, border: `1px solid ${addAlpha(border, "99")}`, borderTop: 0, borderRadius: "0 0 4px 4px"}}>
|
||||
<PreviewLabel color={text}>{mode} surface</PreviewLabel>
|
||||
<Box sx={{height: 7, mt: 0.75, borderRadius: "4px", backgroundColor: previewColor}} />
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const ColorTokenEditor = ({option, palette, onChange}) => (
|
||||
<Box
|
||||
sx={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: {xs: "1fr", md: "minmax(170px, 0.8fr) minmax(250px, 1fr) minmax(260px, 1.1fr)"},
|
||||
gap: 1.5,
|
||||
alignItems: "center",
|
||||
p: 1.5,
|
||||
borderTop: "1px solid",
|
||||
borderColor: "divider",
|
||||
"&:first-of-type": {borderTop: 0},
|
||||
}}
|
||||
>
|
||||
<Box sx={{minWidth: 0}}>
|
||||
<Typography variant="body2" sx={{fontWeight: 700}}>
|
||||
{option.display}
|
||||
</Typography>
|
||||
<Typography variant="caption" sx={{color: "text.secondary", display: "block", lineHeight: 1.3}}>
|
||||
{option.description}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 1.5, minWidth: 0}}>
|
||||
<ModeColorControl
|
||||
mode="dark"
|
||||
name={option.name}
|
||||
color={palette?.[option.name]?.dark}
|
||||
onChange={onChange}
|
||||
/>
|
||||
<ModeColorControl
|
||||
mode="light"
|
||||
name={option.name}
|
||||
color={palette?.[option.name]?.light}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</Box>
|
||||
<Box sx={{display: "grid", gridTemplateColumns: "1fr 1fr", gap: 1, minWidth: 0}}>
|
||||
<ColorUsagePreview option={option} palette={palette} mode="dark" />
|
||||
<ColorUsagePreview option={option} palette={palette} mode="light" />
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
||||
const BackgroundImageEditor = ({palette, backgroundFileImageDarkRef, backgroundFileImageLightRef, onChangePaletteColor, onFileBackgroundImageChangeDark, onFileBackgroundImageChangeLight}) => (
|
||||
<Box sx={{mt: 2}}>
|
||||
<Box sx={{mb: 1}}>
|
||||
<Typography variant="h6" sx={{fontWeight: 700}}>Background Images</Typography>
|
||||
<Typography variant="caption" sx={{color: "text.secondary"}}>
|
||||
Optional page background images for each theme mode.
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: {xs: "1fr", md: "1fr 1fr"},
|
||||
gap: 1.5,
|
||||
}}
|
||||
>
|
||||
{[
|
||||
{mode: "dark", label: "Dark", ref: backgroundFileImageDarkRef, onChange: onFileBackgroundImageChangeDark},
|
||||
{mode: "light", label: "Light", ref: backgroundFileImageLightRef, onChange: onFileBackgroundImageChangeLight},
|
||||
].map((imageOption) => (
|
||||
<Box
|
||||
key={imageOption.mode}
|
||||
sx={{
|
||||
border: "1px solid",
|
||||
borderColor: "divider",
|
||||
borderRadius: "8px",
|
||||
overflow: "hidden",
|
||||
backgroundColor: imageOption.mode === "dark" ? "#111827" : "#f8fafc",
|
||||
}}
|
||||
>
|
||||
<Box sx={{display: "flex", alignItems: "center", gap: 1, p: 1}}>
|
||||
<Typography variant="body2" sx={{fontWeight: 700, flexGrow: 1, color: imageOption.mode === "dark" ? "#ffffff" : "#111827"}}>
|
||||
{imageOption.label}
|
||||
</Typography>
|
||||
<Button size="small" color="info" variant="contained" onClick={() => imageOption.ref.current.click()}>
|
||||
Upload
|
||||
<input ref={imageOption.ref} onChange={imageOption.onChange} type="file" hidden />
|
||||
</Button>
|
||||
<Button size="small" color="warning" variant="contained" onClick={() => onChangePaletteColor("backgroundImage", imageOption.mode, null)}>
|
||||
Remove
|
||||
</Button>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
height: 120,
|
||||
backgroundImage: palette.backgroundImage?.[imageOption.mode],
|
||||
backgroundSize: "cover",
|
||||
backgroundPosition: "center",
|
||||
borderTop: "1px solid",
|
||||
borderColor: "divider",
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
||||
const ColorPaletteEditor = ({palette, onChangePaletteColor, backgroundFileImageDarkRef, backgroundFileImageLightRef, onFileBackgroundImageChangeDark, onFileBackgroundImageChangeLight}) => (
|
||||
<Box sx={{width: "100%", py: 1}}>
|
||||
<Typography variant="h4" sx={{mb: 0.5}}>
|
||||
Theme Colors
|
||||
</Typography>
|
||||
<Typography variant="body2" sx={{color: "text.secondary", mb: 2}}>
|
||||
Colors are grouped by where operators will see them, with dark and light previews shown side by side.
|
||||
</Typography>
|
||||
{COLOR_EDITOR_SECTIONS.map((section) => (
|
||||
<Box key={section.title} sx={{mb: 2.5}}>
|
||||
<Box sx={{mb: 1}}>
|
||||
<Typography variant="h6" sx={{fontWeight: 700}}>{section.title}</Typography>
|
||||
<Typography variant="caption" sx={{color: "text.secondary"}}>{section.description}</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
border: "1px solid",
|
||||
borderColor: "divider",
|
||||
borderRadius: "8px",
|
||||
overflow: "hidden",
|
||||
backgroundColor: "background.paper",
|
||||
}}
|
||||
>
|
||||
{section.colors.map((option) => (
|
||||
<ColorTokenEditor
|
||||
key={option.name}
|
||||
option={option}
|
||||
palette={palette}
|
||||
onChange={onChangePaletteColor}
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
</Box>
|
||||
))}
|
||||
<BackgroundImageEditor
|
||||
palette={palette}
|
||||
backgroundFileImageDarkRef={backgroundFileImageDarkRef}
|
||||
backgroundFileImageLightRef={backgroundFileImageLightRef}
|
||||
onChangePaletteColor={onChangePaletteColor}
|
||||
onFileBackgroundImageChangeDark={onFileBackgroundImageChangeDark}
|
||||
onFileBackgroundImageChangeLight={onFileBackgroundImageChangeLight}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
|
||||
export function SettingsOperatorUIConfigDialog(props) {
|
||||
const fileInputRef = React.useRef(null);
|
||||
const backgroundFileImageLightRef = React.useRef(null);
|
||||
@@ -247,35 +647,8 @@ export function SettingsOperatorUIConfigDialog(props) {
|
||||
light: isValidColor(initialPalette?.borderColor?.light) ? initialPalette?.borderColor?.light : operatorSettingDefaults.palette.borderColor.light,
|
||||
},
|
||||
});
|
||||
const paletteOptionsSolidColor = [
|
||||
{name: "primary", display: "Primary"},
|
||||
{name: "error", display: "Error"},
|
||||
{name: "warning", display: "Warning"},
|
||||
{name: "info", display: "Informational"},
|
||||
{name: "success", display: "Success"},
|
||||
{name: "secondary", display: "Secondary"},
|
||||
{name: "pageHeader", display: "Page Headers"},
|
||||
{name: "taskPromptTextColor", display: "Tasking Prompt Text"},
|
||||
{name: "taskPromptCommandTextColor", display: "Tasking Command and Parameter Text"}
|
||||
];
|
||||
const paletteOptionsTextColor = [
|
||||
{name: "tableHeader", display: "Table Headers"},
|
||||
{name: "tableHover", display: "Table Hover"},
|
||||
{name: "selectedCallbackColor", display: "Currently active callback row highlight"},
|
||||
{name: "selectedCallbackHierarchyColor", display: "Current Host highlight in tree views"},
|
||||
{name: "paper", display: "Menu and Modals Background"},
|
||||
{name: "background", display: "Background"},
|
||||
{name: "taskContextColor", display: "Tasking Context Generic Background Color"},
|
||||
{name: "taskContextImpersonationColor", display: "Tasking Context User Background Color"},
|
||||
{name: "taskContextExtraColor", display: "Tasking Context Extra Info Background Color"},
|
||||
{name: "emptyFolderColor", display: "Color of the empty folder icon and text in file-based browsers"},
|
||||
{name: "borderColor", display: "Color of borders around elements"}
|
||||
]
|
||||
const [resumeNotifications, setResumeNotifications] = React.useState(false);
|
||||
const [_, updateSettings, clearSettings] = useSetMythicSetting();
|
||||
const onChangeFontSize = (name, value, error) => {
|
||||
setFontSize(value);
|
||||
}
|
||||
const [, updateSettings, clearSettings] = useSetMythicSetting();
|
||||
const onChangeFontFamily = (name, value, error) => {
|
||||
setFontFamily(value);
|
||||
}
|
||||
@@ -365,7 +738,7 @@ export function SettingsOperatorUIConfigDialog(props) {
|
||||
setInteractType(operatorSettingDefaults.interactType);
|
||||
setUseDisplayParamsForCLIHistory(operatorSettingDefaults.useDisplayParamsForCLIHistory);
|
||||
setResumeNotifications(false);
|
||||
setPalette(operatorSettingDefaults.palette);
|
||||
setPalette(clonePalette(operatorSettingDefaults.palette));
|
||||
setTaskTimestampDisplayField(operatorSettingDefaults.taskTimestampDisplayField);
|
||||
setHideTaskingContext(operatorSettingDefaults.hideTaskingContext);
|
||||
setTaskingContextFields(operatorSettingDefaults.taskingContextFields);
|
||||
@@ -376,9 +749,9 @@ export function SettingsOperatorUIConfigDialog(props) {
|
||||
props.onClose();
|
||||
}
|
||||
const setColorDefaults = (mode) => {
|
||||
let newPaletteOptions = {...palette};
|
||||
let newPaletteOptions = clonePalette(palette);
|
||||
for(const [key, value] of Object.entries(operatorSettingDefaults.palette)){
|
||||
newPaletteOptions[key][mode] = value[mode];
|
||||
newPaletteOptions[key] = {...newPaletteOptions[key], [mode]: value[mode]};
|
||||
}
|
||||
setPalette(newPaletteOptions);
|
||||
}
|
||||
@@ -661,242 +1034,15 @@ export function SettingsOperatorUIConfigDialog(props) {
|
||||
</MythicStyledTableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<MythicStyledTableCell></MythicStyledTableCell>
|
||||
<MythicStyledTableCell>
|
||||
<Typography variant={"h4"}>
|
||||
Global Palette Colors
|
||||
</Typography>
|
||||
</MythicStyledTableCell>
|
||||
</TableRow>
|
||||
<TableRow hover>
|
||||
<MythicStyledTableCell>Navigation Bar Color</MythicStyledTableCell>
|
||||
<MythicStyledTableCell>
|
||||
<div style={{display: "flex", width: "100%", paddingRight: "15px"}}>
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<HexColorPicker style={{width: "100%"}} color={palette?.navBarColor?.dark} onChange={(v) => onChangePaletteColor("navBarColor", "dark", v)}/>
|
||||
<HexColorInput color={palette?.navBarColor?.dark} onChange={(v) => onChangePaletteColor("navBarColor", "dark", v)}/>
|
||||
<Box sx={{width: "100%", height: 25, backgroundColor: palette?.navBarColor?.dark, display: "flex", alignItems: "center"}}>
|
||||
<PhoneCallbackIcon style={{color: palette.navBarIcons.dark, marginRight: "5px"}}/>
|
||||
<Typography style={{color: palette.navBarText.dark, display: "inline-block"}}>Dark Mode Color</Typography>
|
||||
</Box>
|
||||
</div>
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<HexColorPicker style={{width: "100%"}} color={palette?.navBarColor?.light} onChange={(v) => onChangePaletteColor("navBarColor", "light", v)}/>
|
||||
<HexColorInput color={palette?.navBarColor?.light} onChange={(v) => onChangePaletteColor("navBarColor", "light", v)}/>
|
||||
<Box sx={{width: "100%", height: 25, backgroundColor: palette?.navBarColor?.light, display: "flex", alignItems: "center"}}>
|
||||
<PhoneCallbackIcon style={{color: palette.navBarIcons.light, marginRight: "5px"}}/>
|
||||
<Typography style={{color: palette.navBarText.light, display: "inline-block"}}>Light Mode Color</Typography>
|
||||
</Box>
|
||||
</div>
|
||||
</div>
|
||||
</MythicStyledTableCell>
|
||||
</TableRow>
|
||||
<TableRow hover>
|
||||
<MythicStyledTableCell>Navigation Bar Bottom Color</MythicStyledTableCell>
|
||||
<MythicStyledTableCell>
|
||||
<div style={{display: "flex", width: "100%", paddingRight: "15px"}}>
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<HexColorPicker style={{width: "100%"}} color={palette?.navBarBottomColor?.dark} onChange={(v) => onChangePaletteColor("navBarBottomColor", "dark", v)}/>
|
||||
<HexColorInput color={palette?.navBarBottomColor?.dark} onChange={(v) => onChangePaletteColor("navBarBottomColor", "dark", v)}/>
|
||||
<Box sx={{width: "100%", height: 25, backgroundColor: palette?.navBarBottomColor?.dark, display: "flex", alignItems: "center"}}>
|
||||
<PhoneCallbackIcon style={{color: palette.navBarIcons.dark, marginRight: "5px"}}/>
|
||||
<Typography style={{color: palette.navBarText.dark, display: "inline-block"}}>Dark Mode Color</Typography>
|
||||
</Box>
|
||||
</div>
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<HexColorPicker style={{width: "100%"}} color={palette?.navBarBottomColor?.light} onChange={(v) => onChangePaletteColor("navBarBottomColor", "light", v)}/>
|
||||
<HexColorInput color={palette?.navBarBottomColor?.light} onChange={(v) => onChangePaletteColor("navBarBottomColor", "light", v)}/>
|
||||
<Box sx={{width: "100%", height: 25, backgroundColor: palette?.navBarBottomColor?.light, display: "flex", alignItems: "center"}}>
|
||||
<PhoneCallbackIcon style={{color: palette.navBarIcons.light, marginRight: "5px"}}/>
|
||||
<Typography style={{color: palette.navBarText.light, display: "inline-block"}}>Light Mode Color</Typography>
|
||||
</Box>
|
||||
</div>
|
||||
</div>
|
||||
</MythicStyledTableCell>
|
||||
</TableRow>
|
||||
<TableRow hover>
|
||||
<MythicStyledTableCell>Navigation Bar Icon Colors</MythicStyledTableCell>
|
||||
<MythicStyledTableCell>
|
||||
<div style={{display: "flex", width: "100%", paddingRight: "15px"}}>
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<HexColorPicker style={{width: "100%"}} color={palette?.navBarIcons?.dark} onChange={(v) => onChangePaletteColor("navBarIcons", "dark", v)}/>
|
||||
<HexColorInput color={palette?.navBarIcons?.dark} onChange={(v) => onChangePaletteColor("navBarIcons", "dark", v)}/>
|
||||
<Box sx={{width: "100%", height: 25, background: `linear-gradient(.25turn, ${palette?.navBarColor?.dark}, ${palette?.navBarBottomColor?.dark})`, display: "flex", alignItems: "center"}}>
|
||||
<PhoneCallbackIcon style={{color: palette.navBarIcons.dark, marginRight: "5px"}}/>
|
||||
<Typography style={{color: palette.navBarText.dark, display: "inline-block"}}>Dark Mode Color</Typography>
|
||||
</Box>
|
||||
</div>
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<HexColorPicker style={{width: "100%"}} color={palette?.navBarIcons?.light} onChange={(v) => onChangePaletteColor("navBarIcons", "light", v)}/>
|
||||
<HexColorInput color={palette?.navBarIcons?.light} onChange={(v) => onChangePaletteColor("navBarIcons", "light", v)}/>
|
||||
<Box sx={{width: "100%", height: 25, background: `linear-gradient(.25turn, ${palette?.navBarColor?.light}, ${palette?.navBarBottomColor?.light})`, display: "flex", alignItems: "center"}}>
|
||||
<PhoneCallbackIcon style={{color: palette.navBarIcons.light, marginRight: "5px"}}/>
|
||||
<Typography style={{color: palette.navBarText.light, display: "inline-block"}}>Light Mode Color</Typography>
|
||||
</Box>
|
||||
</div>
|
||||
</div>
|
||||
</MythicStyledTableCell>
|
||||
</TableRow>
|
||||
<TableRow hover>
|
||||
<MythicStyledTableCell>Navigation Bar Text Color</MythicStyledTableCell>
|
||||
<MythicStyledTableCell>
|
||||
<div style={{display: "flex", width: "100%", paddingRight: "15px"}}>
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<HexColorPicker style={{width: "100%"}} color={palette?.navBarText?.dark} onChange={(v) => onChangePaletteColor("navBarText", "dark", v)}/>
|
||||
<HexColorInput color={palette?.navBarText?.dark} onChange={(v) => onChangePaletteColor("navBarText", "dark", v)}/>
|
||||
<Box sx={{width: "100%", height: 25, background: `linear-gradient(.25turn, ${palette?.navBarColor?.dark}, ${palette?.navBarBottomColor?.dark})`, display: "flex", alignItems: "center"}}>
|
||||
<PhoneCallbackIcon style={{color: palette.navBarIcons.dark, marginRight: "5px"}}/>
|
||||
<Typography style={{color: palette.navBarText.dark, display: "inline-block"}}>Dark Mode Color</Typography>
|
||||
</Box>
|
||||
</div>
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<HexColorPicker style={{width: "100%"}} color={palette?.navBarText?.light} onChange={(v) => onChangePaletteColor("navBarText", "light", v)}/>
|
||||
<HexColorInput color={palette?.navBarText?.light} onChange={(v) => onChangePaletteColor("navBarText", "light", v)}/>
|
||||
<Box sx={{width: "100%", height: 25, background: `linear-gradient(.25turn, ${palette?.navBarColor?.light}, ${palette?.navBarBottomColor?.light})`, display: "flex", alignItems: "center"}}>
|
||||
<PhoneCallbackIcon style={{color: palette.navBarIcons.light, marginRight: "5px"}}/>
|
||||
<Typography style={{color: palette.navBarText.light, display: "inline-block"}}>Light Mode Color</Typography>
|
||||
</Box>
|
||||
</div>
|
||||
</div>
|
||||
</MythicStyledTableCell>
|
||||
</TableRow>
|
||||
<TableRow hover>
|
||||
<MythicStyledTableCell>Background Images</MythicStyledTableCell>
|
||||
<MythicStyledTableCell>
|
||||
<div style={{display: "flex", width: "100%", justifyContent: "space-between"}}>
|
||||
<div style={{width: "100%"}}>
|
||||
<Button color={"info"} variant={"contained"} onClick={()=>backgroundFileImageDarkRef.current.click()} >
|
||||
Upload Dark
|
||||
<input ref={backgroundFileImageDarkRef} onChange={onFileBackgroundImageChangeDark} type="file" hidden />
|
||||
</Button>
|
||||
<Button color={"warning"} variant={"contained"} onClick={() => onChangePaletteColor("backgroundImage", "dark", null)} >
|
||||
Remove Dark
|
||||
</Button>
|
||||
<div style={{backgroundImage: palette.backgroundImage.dark, width: "100%", height: "300px", backgroundSize: "contain"}}>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{width: "100%"}}>
|
||||
<Button color={"info"} variant={"contained"} onClick={()=>backgroundFileImageLightRef.current.click()} >
|
||||
Upload Light
|
||||
<input ref={backgroundFileImageLightRef} onChange={onFileBackgroundImageChangeLight} type="file" hidden />
|
||||
</Button>
|
||||
<Button color={"warning"} variant={"contained"} onClick={() => onChangePaletteColor("backgroundImage", "light", null)} >
|
||||
Remove Light
|
||||
</Button>
|
||||
<div style={{backgroundImage: palette.backgroundImage.light, width: "100%", height: "300px", backgroundSize: "contain"}}>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</MythicStyledTableCell>
|
||||
</TableRow>
|
||||
{paletteOptionsSolidColor.map(p => (
|
||||
<TableRow hover key={p.display}>
|
||||
<MythicStyledTableCell>{p.display}</MythicStyledTableCell>
|
||||
<MythicStyledTableCell>
|
||||
<div style={{display: "flex", width: "100%", paddingRight: "15px"}}>
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<HexColorPicker style={{width: "100%"}} color={palette?.[p.name]?.dark} onChange={(v) => onChangePaletteColor(p.name, "dark", v)}/>
|
||||
<HexColorInput color={palette?.[p.name]?.dark} onChange={(v) => onChangePaletteColor(p.name, "dark", v)}/>
|
||||
<Box sx={{width: "100%", height: 25, backgroundColor: palette?.[p.name]?.dark}}>
|
||||
<Typography style={{color: "white"}}>Dark Mode Color</Typography>
|
||||
</Box>
|
||||
</div>
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<HexColorPicker style={{width: "100%"}} color={palette?.[p.name]?.light} onChange={(v) => onChangePaletteColor(p.name, "light", v)}/>
|
||||
<HexColorInput color={palette?.[p.name]?.light} onChange={(v) => onChangePaletteColor(p.name, "light", v)}/>
|
||||
<Box sx={{width: "100%", height: 25, backgroundColor: palette?.[p.name]?.light}}>
|
||||
<Typography style={{color: "black"}}>Light Mode Color</Typography>
|
||||
</Box>
|
||||
</div>
|
||||
</div>
|
||||
</MythicStyledTableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
{paletteOptionsTextColor.map(p => (
|
||||
<TableRow hover key={p.display}>
|
||||
<MythicStyledTableCell>{p.display}</MythicStyledTableCell>
|
||||
<MythicStyledTableCell>
|
||||
<div style={{display: "flex", width: "100%", paddingRight: "15px"}}>
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<HexColorPicker style={{width: "100%"}} color={palette?.[p.name]?.dark} onChange={(v) => onChangePaletteColor(p.name, "dark", v)}/>
|
||||
<HexColorInput color={palette?.[p.name]?.dark} onChange={(v) => onChangePaletteColor(p.name, "dark", v)}/>
|
||||
<Box sx={{width: "100%", height: 25, backgroundColor: palette?.[p.name]?.dark}}>
|
||||
<Typography style={{color: palette.text.dark}}>Dark Mode Color</Typography>
|
||||
</Box>
|
||||
</div>
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<HexColorPicker style={{width: "100%"}} color={palette?.[p.name]?.light} onChange={(v) => onChangePaletteColor(p.name, "light", v)}/>
|
||||
<HexColorInput color={palette?.[p.name]?.light} onChange={(v) => onChangePaletteColor(p.name, "light", v)}/>
|
||||
<Box sx={{width: "100%", height: 25, backgroundColor: palette?.[p.name]?.light}}>
|
||||
<Typography style={{color: palette.text.light}}>Light Mode Color</Typography>
|
||||
</Box>
|
||||
</div>
|
||||
</div>
|
||||
</MythicStyledTableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
<TableRow hover>
|
||||
<MythicStyledTableCell>Text Color</MythicStyledTableCell>
|
||||
<MythicStyledTableCell>
|
||||
<div style={{display: "flex", width: "100%", paddingRight: "15px"}}>
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<HexColorPicker style={{width: "100%"}} color={palette?.text?.dark} onChange={(v) => onChangePaletteColor("text", "dark", v)}/>
|
||||
<HexColorInput color={palette?.text?.dark} onChange={(v) => onChangePaletteColor("text", "dark", v)}/>
|
||||
<Box sx={{width: "100%", height: 25, backgroundColor: palette?.background?.dark, display: "flex", alignItems: "center"}}>
|
||||
<Typography style={{color: palette.text.dark, display: "inline-block"}}>Dark Mode Color</Typography>
|
||||
</Box>
|
||||
</div>
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<HexColorPicker style={{width: "100%"}} color={palette?.text?.light} onChange={(v) => onChangePaletteColor("text", "light", v)}/>
|
||||
<HexColorInput color={palette?.text?.light} onChange={(v) => onChangePaletteColor("text", "light", v)}/>
|
||||
<Box sx={{width: "100%", height: 25, backgroundColor: palette?.background?.light, display: "flex", alignItems: "center"}}>
|
||||
<Typography style={{color: palette.text.light, display: "inline-block"}}>Light Mode Color</Typography>
|
||||
</Box>
|
||||
</div>
|
||||
</div>
|
||||
</MythicStyledTableCell>
|
||||
</TableRow>
|
||||
<TableRow hover>
|
||||
<MythicStyledTableCell>Task Output Text Color</MythicStyledTableCell>
|
||||
<MythicStyledTableCell>
|
||||
<div style={{display: "flex", width: "100%", paddingRight: "15px"}}>
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<HexColorPicker style={{width: "100%"}} color={palette?.outputTextColor?.dark} onChange={(v) => onChangePaletteColor("outputTextColor", "dark", v)}/>
|
||||
<HexColorInput color={palette?.outputTextColor?.dark} onChange={(v) => onChangePaletteColor("outputTextColor", "dark", v)}/>
|
||||
<Box sx={{width: "100%", height: 25, backgroundColor: palette?.outputBackgroundColor?.dark, display: "flex", alignItems: "center"}}>
|
||||
<Typography style={{color: palette.outputTextColor.dark, display: "inline-block"}}>Dark Mode Output Text Color</Typography>
|
||||
</Box>
|
||||
</div>
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<HexColorPicker style={{width: "100%"}} color={palette?.outputTextColor?.light} onChange={(v) => onChangePaletteColor("outputTextColor", "light", v)}/>
|
||||
<HexColorInput color={palette?.outputTextColor?.light} onChange={(v) => onChangePaletteColor("outputTextColor", "light", v)}/>
|
||||
<Box sx={{width: "100%", height: 25, backgroundColor: palette?.outputBackgroundColor?.light, display: "flex", alignItems: "center"}}>
|
||||
<Typography style={{color: palette.outputTextColor.light, display: "inline-block"}}>Light Mode Output Text Color</Typography>
|
||||
</Box>
|
||||
</div>
|
||||
</div>
|
||||
</MythicStyledTableCell>
|
||||
</TableRow>
|
||||
<TableRow hover>
|
||||
<MythicStyledTableCell>Task Output Background Color</MythicStyledTableCell>
|
||||
<MythicStyledTableCell>
|
||||
<div style={{display: "flex", width: "100%", paddingRight: "15px"}}>
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<HexColorPicker style={{width: "100%"}} color={palette?.outputBackgroundColor?.dark} onChange={(v) => onChangePaletteColor("outputBackgroundColor", "dark", v)}/>
|
||||
<HexColorInput color={palette?.outputBackgroundColor?.dark} onChange={(v) => onChangePaletteColor("outputBackgroundColor", "dark", v)}/>
|
||||
<Box sx={{width: "100%", height: 25, backgroundColor: palette?.outputBackgroundColor?.dark, display: "flex", alignItems: "center"}}>
|
||||
<Typography style={{color: palette.outputTextColor.dark, display: "inline-block"}}>Dark Mode Output Text Color</Typography>
|
||||
</Box>
|
||||
</div>
|
||||
<div style={{display: "inline-block", width: "100%"}}>
|
||||
<HexColorPicker style={{width: "100%"}} color={palette?.outputBackgroundColor?.light} onChange={(v) => onChangePaletteColor("outputBackgroundColor", "light", v)}/>
|
||||
<HexColorInput color={palette?.outputBackgroundColor?.light} onChange={(v) => onChangePaletteColor("outputBackgroundColor", "light", v)}/>
|
||||
<Box sx={{width: "100%", height: 25, backgroundColor: palette?.outputBackgroundColor?.light, display: "flex", alignItems: "center"}}>
|
||||
<Typography style={{color: palette.outputTextColor.light, display: "inline-block"}}>Light Mode Output Text Color</Typography>
|
||||
</Box>
|
||||
</div>
|
||||
</div>
|
||||
<MythicStyledTableCell colSpan={2} style={{paddingTop: "16px", paddingBottom: "16px"}}>
|
||||
<ColorPaletteEditor
|
||||
palette={palette}
|
||||
onChangePaletteColor={onChangePaletteColor}
|
||||
backgroundFileImageDarkRef={backgroundFileImageDarkRef}
|
||||
backgroundFileImageLightRef={backgroundFileImageLightRef}
|
||||
onFileBackgroundImageChangeDark={onFileBackgroundImageChangeDark}
|
||||
onFileBackgroundImageChangeLight={onFileBackgroundImageChangeLight}
|
||||
/>
|
||||
</MythicStyledTableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
@@ -921,4 +1067,3 @@ export function SettingsOperatorUIConfigDialog(props) {
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,14 +2,39 @@ import { createGlobalStyle} from "styled-components"
|
||||
// hex transparencies https://gist.github.com/lopspower/03fb1cc0ac9f32ef38f4
|
||||
export const GlobalStyles = createGlobalStyle`
|
||||
body {
|
||||
margin: 0
|
||||
|
||||
margin: 0;
|
||||
background-color: ${(props) => props.theme.palette.background.default};
|
||||
color: ${(props) => props.theme.palette.text.primary};
|
||||
font-family: ${(props) => props.theme.typography.fontFamily};
|
||||
}
|
||||
html, body, #root {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
color-scheme: light dark;
|
||||
}
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
::selection {
|
||||
background-color: ${(props) => props.theme.palette.primary.main + "40"};
|
||||
}
|
||||
* {
|
||||
scrollbar-color: ${(props) => props.theme.borderColor} transparent;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
*::-webkit-scrollbar {
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
}
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background-color: ${(props) => props.theme.borderColor};
|
||||
border: 3px solid transparent;
|
||||
border-radius: 999px;
|
||||
background-clip: padding-box;
|
||||
}
|
||||
*::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
@media screen and (max-width: 1100px) {
|
||||
.hideOnSmallWidth {
|
||||
display: none;
|
||||
@@ -35,23 +60,27 @@ html, body, #root {
|
||||
}
|
||||
.MuiTableCell-head {
|
||||
background-color: ${(props) => props.theme.tableHeader} !important;
|
||||
font-weight: bold;
|
||||
border-top: 2px solid ${(props) => props.theme.borderColor};
|
||||
border-bottom: 2px solid ${(props) => props.theme.borderColor};
|
||||
color: ${(props) => props.theme.palette.text.primary};
|
||||
font-size: 0.76rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0;
|
||||
text-transform: uppercase;
|
||||
border-top: 0;
|
||||
border-bottom: 1px solid ${(props) => props.theme.table?.border || props.theme.borderColor};
|
||||
}
|
||||
tr:nth-child(even) {
|
||||
background-color: ${(props) => props.theme.palette.mode === 'dark' ? props.theme.tableHover + "80" : props.theme.tableHover + "80"};
|
||||
background-color: ${(props) => props.theme.table?.rowStripe || props.theme.tableHover + "66"};
|
||||
}
|
||||
.alternateRow {
|
||||
background-color: ${(props) => props.theme.palette.mode === 'dark' ? props.theme.tableHover + "0D" : props.theme.tableHover + "80"};
|
||||
background-color: ${(props) => props.theme.table?.rowStripe || props.theme.tableHover + "66"};
|
||||
}
|
||||
.MythicResizableGridRowHighlight {
|
||||
background-color: ${(props) => props.theme.palette.mode === 'dark' ? props.theme.tableHover + "60" : props.theme.tableHover + "10"};
|
||||
background-color: ${(props) => props.theme.table?.rowStripe || props.theme.tableHover + "66"};
|
||||
}
|
||||
.MuiTableRow-hover {
|
||||
&:hover,
|
||||
&--hovered {
|
||||
background-color: ${(props) => props.theme.tableHover + "CC"} !important;
|
||||
background-color: ${(props) => props.theme.table?.rowHover || props.theme.tableHover + "CC"} !important;
|
||||
color: ${(props) => props.theme.palette.text.primary} !important;
|
||||
}
|
||||
}
|
||||
@@ -62,7 +91,7 @@ tr:nth-child(even) {
|
||||
.MuiListItem-root {
|
||||
&:hover,
|
||||
&--hovered {
|
||||
background-color: ${(props) => props.theme.tableHover + "CC"} !important;
|
||||
background-color: ${(props) => props.theme.surfaces?.hover || props.theme.palette.action.hover} !important;
|
||||
color: ${(props) => props.theme.palette.text.primary} !important;
|
||||
}
|
||||
}
|
||||
@@ -115,7 +144,7 @@ tspan {
|
||||
z-index: 0 !important
|
||||
}
|
||||
.gutter {
|
||||
background-color: ${(props) => props.theme.topAppBarColor};
|
||||
background-color: ${(props) => props.theme.borderColor};
|
||||
background-repeat: no-repeat;
|
||||
background-position: 50%;
|
||||
}
|
||||
@@ -170,8 +199,8 @@ tspan {
|
||||
.context-menu {
|
||||
background-color: ${(props) => props.theme.palette.background.paper};
|
||||
border: 1px solid ${(props) => props.theme.borderColor};
|
||||
border-radius: 5px;
|
||||
box-shadow: 10px 19px 20px rgba(0, 0, 0, 10%);
|
||||
border-radius: ${(props) => props.theme.shape.borderRadius + 2}px;
|
||||
box-shadow: ${(props) => props.theme.palette.mode === 'dark' ? "0 18px 48px rgba(0, 0, 0, 40%)" : "0 18px 48px rgba(15, 23, 42, 12%)"};
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
@@ -201,21 +230,30 @@ tspan {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding: 0 0.5em;
|
||||
padding: 0 8px;
|
||||
box-sizing: border-box;
|
||||
justify-content: space-between;
|
||||
user-select: none;
|
||||
border-top: 2px solid ${(props) => props.theme.borderColor};
|
||||
border-bottom: 2px solid ${(props) => props.theme.borderColor};
|
||||
border-right: 1px solid ${(props) => props.theme.table?.borderSoft || props.theme.borderColor};
|
||||
border-bottom: 1px solid ${(props) => props.theme.table?.border || props.theme.borderColor};
|
||||
background-color: ${(props) => props.theme.tableHeader} !important;
|
||||
color: ${(props) => props.theme.palette.text.primary};
|
||||
font-size: 0.76rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0;
|
||||
&:first-child-of-type {
|
||||
border-left: 2px solid ${(props) => props.theme.borderColor};
|
||||
border-left: 0;
|
||||
}
|
||||
&:hover {
|
||||
background-color: ${(props) => props.theme.tableHover};
|
||||
background-color: ${(props) => props.theme.table?.headerHover || props.theme.tableHover};
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.MythicResizableGrid-headerCell .MythicResizableGrid-cellInner {
|
||||
font-size: 0.76rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
}
|
||||
.MythicResizableGrid-headerResizeHandle {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -233,9 +271,9 @@ tspan {
|
||||
right: 2px;
|
||||
width: 0px;
|
||||
height: 100%;
|
||||
border-left: 1px solid ${(props) => props.theme.palette.text.main};
|
||||
border-right: 1px solid ${(props) => props.theme.palette.text.main};
|
||||
opacity: 0.85;
|
||||
border-left: 1px solid ${(props) => props.theme.palette.text.secondary};
|
||||
border-right: 1px solid ${(props) => props.theme.palette.text.secondary};
|
||||
opacity: 0.55;
|
||||
}
|
||||
.MythicResizableGrid-headerResizeHandle:hover,
|
||||
.MythicResizableGrid-headerResizeHandleActive {
|
||||
@@ -252,15 +290,19 @@ tspan {
|
||||
opacity: 1;
|
||||
}
|
||||
.MythicResizableGrid-hoveredRow {
|
||||
background-color: ${(props) => props.theme.tableHover + "CC"};
|
||||
background-color: ${(props) => props.theme.table?.rowHover || props.theme.tableHover + "CC"};
|
||||
}
|
||||
.MythicResizableGrid-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 0.5em;
|
||||
padding: 0 8px;
|
||||
box-sizing: border-box;
|
||||
font-family: monospace;
|
||||
border-bottom: 1px solid ${(props) => props.theme.borderColor};
|
||||
color: ${(props) => props.theme.palette.text.primary};
|
||||
font-family: ${(props) => props.theme.typography.fontFamily};
|
||||
font-size: 0.86rem;
|
||||
font-variant-numeric: tabular-nums;
|
||||
border-right: 1px solid ${(props) => props.theme.table?.borderSoft || props.theme.borderColor};
|
||||
border-bottom: 1px solid ${(props) => props.theme.table?.borderSoft || props.theme.borderColor};
|
||||
cursor: default !important;
|
||||
}
|
||||
.MythicResizableGrid-cellInner {
|
||||
@@ -289,7 +331,7 @@ tspan {
|
||||
}
|
||||
.MuiPaper-root {
|
||||
border: 1px solid ${(props) => props.theme.borderColor};
|
||||
border-radius: 5px;
|
||||
border-radius: ${(props) => props.theme.shape.borderRadius}px;
|
||||
background-color: ${(props) => props.theme.palette.background.paper};
|
||||
background-image: unset;
|
||||
}
|
||||
@@ -303,13 +345,13 @@ tspan {
|
||||
.MuiList-root {
|
||||
background-color: ${(props) => props.theme.palette.background.paper};
|
||||
border: 1px solid ${(props) => props.theme.borderColor};
|
||||
border-radius: 3px;
|
||||
line-height: 30px;
|
||||
border-radius: ${(props) => props.theme.shape.borderRadius}px;
|
||||
line-height: 28px;
|
||||
}
|
||||
.dropdownMenuColored {
|
||||
background-color: ${(props) => props.theme.palette.background.paper} !important;
|
||||
border: 1px solid ${(props) => props.theme.borderColor};
|
||||
border-radius: 5px;
|
||||
border-radius: ${(props) => props.theme.shape.borderRadius}px;
|
||||
//color: white;
|
||||
}
|
||||
// gets the title of the table
|
||||
@@ -329,21 +371,21 @@ tspan {
|
||||
min-height: 2rem;
|
||||
}
|
||||
.selectedCallback {
|
||||
background-color: ${(props) => props.theme.selectedCallbackColor + "CC"};
|
||||
background-color: ${(props) => props.theme.table?.selected || props.theme.selectedCallbackColor + "CC"};
|
||||
}
|
||||
.selectedCallbackHierarchy {
|
||||
background-color: ${(props) => props.theme.selectedCallbackHierarchyColor + "CC"};
|
||||
background-color: ${(props) => props.theme.table?.selectedHierarchy || props.theme.selectedCallbackHierarchyColor + "CC"};
|
||||
}
|
||||
|
||||
.MuiDataGrid-row.Mui-selected {
|
||||
background-color: ${(props) => props.theme.selectedCallbackColor} !important;
|
||||
background-color: ${(props) => props.theme.table?.selected || props.theme.selectedCallbackColor + "CC"} !important;
|
||||
}
|
||||
.roundedBottomCorners {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
.MuiInputLabel-root {
|
||||
color: ${(props) => props.theme.borderColor} !important;
|
||||
color: ${(props) => props.theme.palette.text.secondary} !important;
|
||||
}
|
||||
.MuiOutlinedInput-notchedOutline {
|
||||
border-color: ${(props) => props.theme.borderColor} !important;
|
||||
@@ -355,19 +397,22 @@ tspan {
|
||||
border-color: ${(props) => props.theme.borderColor} !important;
|
||||
}
|
||||
.Mui-focused {
|
||||
border-color: ${(props) => props.theme.borderColor} !important;
|
||||
border-color: ${(props) => props.theme.palette.primary.main} !important;
|
||||
}
|
||||
.MuiInputBase-input {
|
||||
border-color: ${(props) => props.theme.borderColor} !important;
|
||||
}
|
||||
.MuiInput-root::after {
|
||||
border-color: ${(props) => props.theme.borderColor} !important;
|
||||
border-color: ${(props) => props.theme.palette.primary.main} !important;
|
||||
}
|
||||
.MuiTableCell-root {
|
||||
padding: 0 16px 0 16px;
|
||||
padding: 6px 10px;
|
||||
border-bottom: 1px solid ${(props) => props.theme.table?.borderSoft || props.theme.borderColor};
|
||||
line-height: 1.35;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.MuiTabs-root {
|
||||
min-height: 30px;
|
||||
min-height: 34px;
|
||||
}
|
||||
.MuiTab-root {
|
||||
min-width: unset !important;
|
||||
@@ -395,11 +440,11 @@ tspan {
|
||||
color: ${(props) => props.theme.outputTextColor};
|
||||
}
|
||||
.rounded-tab {
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
padding: 0 10px 0 10px;
|
||||
border-top-left-radius: ${(props) => props.theme.shape.borderRadius}px;
|
||||
border-top-right-radius: ${(props) => props.theme.shape.borderRadius}px;
|
||||
padding: 2px 10px 0 10px;
|
||||
border-top: 1px solid ${(props) => props.theme.borderColor};
|
||||
border-left: 2px solid ${(props) => props.theme.borderColor};
|
||||
border-left: 1px solid ${(props) => props.theme.borderColor};
|
||||
border-right: 1px solid ${(props) => props.theme.borderColor};
|
||||
border-bottom: 1px solid ${(props) => props.theme.borderColor};
|
||||
position: relative;
|
||||
|
||||
Reference in New Issue
Block a user