feat(timeline): add pulse animation for in-flight drag mutations
Allocation bars that have active optimistic overrides (post-drag, awaiting server confirmation) now pulse subtly via animate-pulse. The pending set is derived from the existing optimisticAllocations map keys, requiring no additional state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { WeekdayAvailability } from "@capakraken/shared";
|
||||
import { DAY_KEYS, type WeekdayAvailability } from "@capakraken/shared";
|
||||
|
||||
export interface ChargeabilityAllocation {
|
||||
startDate: Date;
|
||||
@@ -12,11 +12,6 @@ export interface ChargeabilityResult {
|
||||
chargeability: number; // 0-100, rounded
|
||||
}
|
||||
|
||||
// Maps JS getDay() (0=Sun..6=Sat) to WeekdayAvailability keys
|
||||
const DAY_KEYS: (keyof WeekdayAvailability)[] = [
|
||||
"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday",
|
||||
];
|
||||
|
||||
/** Count working hours a resource has available in [start, end] based on their schedule. */
|
||||
export function computeAvailableHours(
|
||||
availability: WeekdayAvailability,
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
* - Aggregation by chapter for 4Dispo view
|
||||
*/
|
||||
|
||||
import { MILLISECONDS_PER_DAY } from "@capakraken/shared";
|
||||
|
||||
export interface WeekDefinition {
|
||||
weekNumber: number;
|
||||
year: number;
|
||||
@@ -42,7 +44,7 @@ function getISOWeekData(date: Date): { year: number; week: number } {
|
||||
const dayNum = d.getUTCDay() || 7;
|
||||
d.setUTCDate(d.getUTCDate() + 4 - dayNum);
|
||||
const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
|
||||
const week = Math.ceil(((d.getTime() - yearStart.getTime()) / 86_400_000 + 1) / 7);
|
||||
const week = Math.ceil(((d.getTime() - yearStart.getTime()) / MILLISECONDS_PER_DAY + 1) / 7);
|
||||
return { year: d.getUTCFullYear(), week };
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* It is the denominator for chargeability calculations.
|
||||
*/
|
||||
|
||||
import { toIsoDate } from "@capakraken/shared";
|
||||
import type { SpainScheduleRule } from "@capakraken/shared";
|
||||
|
||||
// ─── Types ──────────────────────────────────────────────────────────────────
|
||||
@@ -47,11 +48,6 @@ export interface SAHResult {
|
||||
|
||||
// ─── Helpers ────────────────────────────────────────────────────────────────
|
||||
|
||||
function toISODate(d: Date | string): string {
|
||||
if (typeof d === "string") return d.slice(0, 10);
|
||||
return d.toISOString().slice(0, 10);
|
||||
}
|
||||
|
||||
function isWeekend(date: Date): boolean {
|
||||
const day = date.getUTCDay();
|
||||
return day === 0 || day === 6;
|
||||
@@ -93,8 +89,8 @@ export function getDailyHours(
|
||||
export function calculateSAH(input: SAHInput): SAHResult {
|
||||
const { dailyWorkingHours, scheduleRules, fte, periodStart, periodEnd, publicHolidays, absenceDays } = input;
|
||||
|
||||
const holidaySet = new Set(publicHolidays.map(toISODate));
|
||||
const absenceSet = new Set(absenceDays.map(toISODate));
|
||||
const holidaySet = new Set(publicHolidays.map(toIsoDate));
|
||||
const absenceSet = new Set(absenceDays.map(toIsoDate));
|
||||
|
||||
let calendarDays = 0;
|
||||
let weekendDays = 0;
|
||||
|
||||
Reference in New Issue
Block a user