Compare commits
5 Commits
release/20
...
feature/IO
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
141b05f558 | ||
|
|
8c9ef375be | ||
|
|
8295cb111a | ||
|
|
951d214d49 | ||
|
|
6f19c1dd3f |
@@ -1,20 +1,20 @@
|
||||
import { ApolloProvider } from "@apollo/client";
|
||||
import * as Sentry from "@sentry/react";
|
||||
import { SplitFactoryProvider, useSplitClient } from "@splitsoftware/splitio-react";
|
||||
import { ConfigProvider } from "antd";
|
||||
import enLocale from "antd/es/locale/en_US";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import { CookiesProvider } from "react-cookie";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect, useSelector } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import GlobalLoadingBar from "../components/global-loading-bar/global-loading-bar.component";
|
||||
import { setDarkMode } from "../redux/application/application.actions";
|
||||
import { selectDarkMode } from "../redux/application/application.selectors";
|
||||
import { selectCurrentUser } from "../redux/user/user.selectors.js";
|
||||
import client from "../utils/GraphQLClient";
|
||||
import App from "./App";
|
||||
import * as Sentry from "@sentry/react";
|
||||
import getTheme from "./themeProvider";
|
||||
import { CookiesProvider } from "react-cookie";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectCurrentUser } from "../redux/user/user.selectors.js";
|
||||
import { selectDarkMode } from "../redux/application/application.selectors";
|
||||
import { setDarkMode } from "../redux/application/application.actions";
|
||||
|
||||
// Base Split configuration
|
||||
const config = {
|
||||
@@ -86,7 +86,7 @@ function AppContainer({ currentUser, setDarkMode }) {
|
||||
theme={theme}
|
||||
form={{
|
||||
validateMessages: {
|
||||
required: t("general.validation.required", { label: "{{label}}" })
|
||||
required: t("general.validation.required", { label: "${label}" })
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
--tech-icon-color: orangered; /* Light mode tech icon color */
|
||||
--clone-border-color: #1890ff; /* Light mode clone border color */
|
||||
--event-arrived-bg: rgba(4, 141, 4, 0.4); /* Light mode arrived event background */
|
||||
--event-block-bg: rgba(212, 2, 2, 0.6); /* Light mode block event background */
|
||||
--event-block-bg: tomato; /* Light mode block event background */
|
||||
--event-selected-bg: slategrey; /* Light mode selected event background */
|
||||
--task-bg: #fff; /* Light mode task center background */
|
||||
--task-text: rgba(0, 0, 0, 0.85); /* Light mode task text */
|
||||
@@ -83,7 +83,7 @@
|
||||
--tag-wrapper-text: #000; /* Light mode tag wrapper text */
|
||||
--preview-bg: lightgray; /* Light mode preview background */
|
||||
--preview-border-color: #2196F3; /* Light mode preview border color */
|
||||
--event-bg-fallback: #ffffff; /* Light mode event background fallback */
|
||||
--event-bg-fallback: #c4c4c4; /* Light mode event background fallback */
|
||||
--card-bg-fallback: #ffffff; /* Light mode card background fallback */
|
||||
--card-text-fallback: black; /* Light mode card text fallback */
|
||||
--table-row-even-bg: rgb(236, 236, 236); /* Light mode table row even background */
|
||||
@@ -159,7 +159,7 @@
|
||||
--tech-icon-color: #ff4500; /* Dark mode tech icon color */
|
||||
--clone-border-color: #4da8ff; /* Dark mode clone border color */
|
||||
--event-arrived-bg: rgba(4, 141, 4, 0.6); /* Dark mode arrived event background */
|
||||
--event-block-bg: rgba(212, 2, 2, 0.8); /* Dark mode block event background */
|
||||
--event-block-bg: tomato; /* Dark mode block event background */
|
||||
--event-selected-bg: #4a5e6e; /* Dark mode selected event background */
|
||||
--task-bg: #2a2a2a; /* Dark mode task center background */
|
||||
--task-text: rgba(255, 255, 255, 0.85); /* Dark mode task text */
|
||||
@@ -189,7 +189,7 @@
|
||||
--tag-wrapper-text: #cccccc; /* Dark mode tag wrapper text */
|
||||
--preview-bg: #2a2a2a; /* Dark mode preview background */
|
||||
--preview-border-color: #4da8ff; /* Dark mode preview border color */
|
||||
--event-bg-fallback: #2a2a2a; /* Dark mode event background fallback */
|
||||
--event-bg-fallback: #262626; /* Dark mode event background fallback */
|
||||
--card-bg-fallback: #2a2a2a; /* Dark mode card background fallback */
|
||||
--card-text-fallback: #cccccc; /* Dark mode card text fallback */
|
||||
--table-row-even-bg: #2a2a2a; /* Dark mode table row even background */
|
||||
|
||||
@@ -424,6 +424,9 @@ export function ScheduleEventComponent({
|
||||
|
||||
// Adjust event color for dark mode if needed
|
||||
const getEventBackground = () => {
|
||||
if (event?.block) {
|
||||
return "var(--event-block-bg)"; // Use a specific color for dark mode
|
||||
}
|
||||
const baseColor = event.color && event.color.hex ? event.color.hex : event.color || "var(--event-bg-fallback)";
|
||||
// Optionally adjust color for dark mode (e.g., lighten if too dark)
|
||||
return baseColor;
|
||||
|
||||
@@ -212,6 +212,10 @@ export function ScheduleCalendarHeaderComponent({ bodyshop, label, refetch, date
|
||||
return bodyshop.workingdays[day];
|
||||
};
|
||||
|
||||
const blocked = isDayBlocked.length > 0;
|
||||
const headerStyle = blocked ? { color: "#fff" } : { color: isShopOpen(date) ? "" : "tomato" };
|
||||
const headerClass = `imex-calendar-header-card ${blocked ? "imex-calendar-header-card--blocked" : ""}`.trim();
|
||||
|
||||
return (
|
||||
<div className="imex-calendar-load">
|
||||
<ScheduleBlockDay alreadyBlocked={isDayBlocked.length > 0} date={date} refetch={refetch}>
|
||||
|
||||
@@ -26,6 +26,37 @@
|
||||
background-color: var(--event-block-bg);
|
||||
}
|
||||
|
||||
/* Ensure readable text when fallback background is used */
|
||||
.imex-event-fallback,
|
||||
.imex-event-fallback .rbc-event-content,
|
||||
.imex-event-fallback .rbc-event-label,
|
||||
.imex-event-fallback a {
|
||||
color: var(--card-text-fallback) !important;
|
||||
}
|
||||
|
||||
/* Optional subtle border to distinguish on white backgrounds */
|
||||
.imex-event-fallback {
|
||||
border: 1px solid var(--bar-border-color);
|
||||
}
|
||||
|
||||
/* Header day card styling */
|
||||
.imex-calendar-header-card {
|
||||
display: inline-block;
|
||||
padding: 0.15rem 0.35rem;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.imex-calendar-header-card--blocked {
|
||||
background-color: var(--event-block-bg);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.imex-calendar-header-card--blocked a,
|
||||
.imex-calendar-header-card--blocked span,
|
||||
.imex-calendar-header-card--blocked .ant-typography {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.rbc-month-view {
|
||||
// height: 125rem;
|
||||
}
|
||||
|
||||
@@ -37,17 +37,39 @@ export function ScheduleCalendarWrapperComponent({
|
||||
const history = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
|
||||
// Determine current view to compute styles consistently
|
||||
const currentView = search.view || defaultView || "week";
|
||||
|
||||
const handleEventPropStyles = (event, start, end, isSelected) => {
|
||||
const hasColor = Boolean(event?.color?.hex || event?.color);
|
||||
const useBg = currentView !== "agenda";
|
||||
|
||||
// Prioritize explicit blocked-day background to ensure red in all themes
|
||||
let bg;
|
||||
if (useBg) {
|
||||
if (event?.block) {
|
||||
bg = "var(--event-block-bg)";
|
||||
} else if (hasColor) {
|
||||
bg = event?.color?.hex ?? event?.color;
|
||||
} else {
|
||||
bg = "var(--event-bg-fallback)";
|
||||
}
|
||||
}
|
||||
|
||||
const usedFallback = !hasColor && !event?.block; // only mark as fallback when not blocked
|
||||
|
||||
const classes = [
|
||||
"imex-event",
|
||||
event.arrived && "imex-event-arrived",
|
||||
event.block && "imex-event-block",
|
||||
usedFallback && "imex-event-fallback"
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ");
|
||||
|
||||
return {
|
||||
...(event.color && !((search.view || defaultView) === "agenda")
|
||||
? {
|
||||
style: {
|
||||
backgroundColor:
|
||||
event.color && event.color.hex ? event.color.hex : event.color || "var(--event-bg-fallback)"
|
||||
}
|
||||
}
|
||||
: {}),
|
||||
className: `${event.arrived ? "imex-event-arrived" : ""} ${event.block ? "imex-event-block" : ""}`
|
||||
...(bg ? { style: { backgroundColor: bg } } : {}),
|
||||
className: classes
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -73,37 +73,23 @@ const processCanvasRequest = async (req, res) => {
|
||||
// Default width and height
|
||||
const width = isNumber(w) && w > 0 ? w : 500;
|
||||
const height = isNumber(h) && h > 0 ? h : 275;
|
||||
|
||||
const configuration = getChartConfiguration(keys, values, override);
|
||||
|
||||
let canvas = null;
|
||||
let ctx = null;
|
||||
let chart = null;
|
||||
let chartImage = null;
|
||||
|
||||
try {
|
||||
// Create the canvas
|
||||
canvas = new Canvas(width, height);
|
||||
ctx = canvas.getContext("2d");
|
||||
const canvas = new Canvas(width, height);
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
// Render the chart
|
||||
chart = new Chart(ctx, configuration);
|
||||
|
||||
// Generate and send the image
|
||||
chartImage = (await canvas.toBuffer("image/png")).toString("base64");
|
||||
const chartImage = (await canvas.toBuffer("image/png")).toString("base64");
|
||||
res.status(200).send(`data:image/png;base64,${chartImage}`);
|
||||
} catch (error) {
|
||||
// Log the error and send the response
|
||||
logger.log("canvas-error", "error", "jsr", null, { error: error.message });
|
||||
res.status(500).send("Failed to generate canvas.");
|
||||
res.status(500).send("Error generating canvas");
|
||||
} finally {
|
||||
// Cleanup resources
|
||||
if (chart) {
|
||||
chart.destroy();
|
||||
}
|
||||
ctx = null;
|
||||
canvas = null;
|
||||
chartImage = null;
|
||||
chart?.destroy();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -118,15 +104,18 @@ const enqueueRequest = (req, res) => {
|
||||
};
|
||||
|
||||
const processNextInQueue = async () => {
|
||||
while (requestQueue.length > 0) {
|
||||
const { req, res } = requestQueue.shift();
|
||||
try {
|
||||
await processCanvasRequest(req, res);
|
||||
} catch (err) {
|
||||
console.error("canvas-queue-error", "error", "jsr", null, { error: err.message });
|
||||
try {
|
||||
while (requestQueue.length > 0) {
|
||||
const { req, res } = requestQueue.shift();
|
||||
try {
|
||||
await processCanvasRequest(req, res);
|
||||
} catch (err) {
|
||||
console.error("canvas-queue-error", "error", "jsr", null, { error: err.message });
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
isProcessing = false;
|
||||
}
|
||||
isProcessing = false;
|
||||
};
|
||||
|
||||
exports.canvastest = function (req, res) {
|
||||
@@ -134,7 +123,10 @@ exports.canvastest = function (req, res) {
|
||||
};
|
||||
|
||||
exports.canvas = async (req, res) => {
|
||||
if (isProcessing || !enqueueRequest(req, res)) return;
|
||||
isProcessing = true;
|
||||
processNextInQueue().catch((err) => console.error("canvas-processing-error", { error: err.message }));
|
||||
if (!enqueueRequest(req, res)) return;
|
||||
|
||||
if (!isProcessing) {
|
||||
isProcessing = true;
|
||||
processNextInQueue().catch((err) => console.error("canvas-processing-error", { error: err.message }));
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user