@tensor_1/react 2.32.0 → 2.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -0
- package/dist/SchedulingCalendar-DSLQ6AY5.d.ts +376 -0
- package/dist/components/SchedulingAgenda.d.ts +31 -0
- package/dist/components/SchedulingAgenda.js +161 -0
- package/dist/components/SchedulingCalendar.d.ts +4 -241
- package/dist/components/SchedulingCalendar.js +116 -24
- package/dist/components/SchedulingTimeGrid.d.ts +4 -0
- package/dist/components/SchedulingTimeGrid.js +521 -0
- package/dist/components/SchedulingTimeline.d.ts +1 -1
- package/dist/index.cjs +1349 -490
- package/dist/index.d.cts +211 -7
- package/dist/index.d.ts +2 -2
- package/dist/index.js +15 -1
- package/dist/labels-context.d.ts +1 -1
- package/dist/scheduling-calendar-model.d.ts +104 -1
- package/dist/scheduling-calendar-model.js +95 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -190,6 +190,7 @@ __export(src_exports, {
|
|
|
190
190
|
Switch: () => Switch,
|
|
191
191
|
TEXT_FILTER_OPERATORS: () => TEXT_FILTER_OPERATORS,
|
|
192
192
|
TOAST_LEAVE_MS: () => TOAST_LEAVE_MS,
|
|
193
|
+
TOP_LANE_CROSS_MIDNIGHT_MINUTES: () => TOP_LANE_CROSS_MIDNIGHT_MINUTES,
|
|
193
194
|
Tab: () => Tab,
|
|
194
195
|
TabPanel: () => TabPanel,
|
|
195
196
|
Table: () => Table,
|
|
@@ -254,10 +255,12 @@ __export(src_exports, {
|
|
|
254
255
|
isRuleGroup: () => isRuleGroup,
|
|
255
256
|
itemDaySpan: () => itemDaySpan,
|
|
256
257
|
layeredNeighbor: () => layeredNeighbor,
|
|
258
|
+
layoutDaySpans: () => layoutDaySpans,
|
|
257
259
|
layoutLane: () => layoutLane,
|
|
258
260
|
layoutLayeredGraph: () => layoutLayeredGraph,
|
|
259
261
|
layoutMonthSpans: () => layoutMonthSpans,
|
|
260
262
|
layoutRelationshipGraph: () => layoutRelationshipGraph,
|
|
263
|
+
layoutTimeGridDay: () => layoutTimeGridDay,
|
|
261
264
|
mapRuleGroup: () => mapRuleGroup,
|
|
262
265
|
matchFilter: () => matchFilter,
|
|
263
266
|
matchFilterPreset: () => matchFilterPreset,
|
|
@@ -274,6 +277,8 @@ __export(src_exports, {
|
|
|
274
277
|
partitionFiles: () => partitionFiles,
|
|
275
278
|
pixelsToMs: () => pixelsToMs,
|
|
276
279
|
placeSpan: () => placeSpan,
|
|
280
|
+
placesInTopLane: () => placesInTopLane,
|
|
281
|
+
proposeMove: () => proposeMove,
|
|
277
282
|
rankOverflow: () => rankOverflow,
|
|
278
283
|
relationshipNeighbors: () => relationshipNeighbors,
|
|
279
284
|
relativeTimeValue: () => relativeTimeValue,
|
|
@@ -8930,7 +8935,7 @@ function BuilderCanvas({
|
|
|
8930
8935
|
}
|
|
8931
8936
|
|
|
8932
8937
|
// src/components/SchedulingCalendar.tsx
|
|
8933
|
-
var
|
|
8938
|
+
var import_react60 = require("react");
|
|
8934
8939
|
|
|
8935
8940
|
// src/calendar-model.ts
|
|
8936
8941
|
function fromDateKey(value) {
|
|
@@ -9267,9 +9272,768 @@ function layoutMonthSpans(spans, days, options) {
|
|
|
9267
9272
|
}
|
|
9268
9273
|
return { placed, hiddenByRow, firstHiddenDayByRow };
|
|
9269
9274
|
}
|
|
9275
|
+
var MINUTE_MS = 6e4;
|
|
9276
|
+
var HOUR_MS = 36e5;
|
|
9277
|
+
var instantMs = (value) => new Date(value).getTime();
|
|
9278
|
+
var TOP_LANE_CROSS_MIDNIGHT_MINUTES = 360;
|
|
9279
|
+
function placesInTopLane(entry, timeZone, options = {}) {
|
|
9280
|
+
if (entry.allDay) return true;
|
|
9281
|
+
const start = instantMs(entry.start);
|
|
9282
|
+
const end = instantMs(entry.end);
|
|
9283
|
+
if (!(end > start)) return false;
|
|
9284
|
+
if (end > addZonedDays(new Date(start), 1, timeZone).instant.getTime()) return true;
|
|
9285
|
+
const firstMidnight = zonedDayBounds(zonedDateKey(new Date(start), timeZone), timeZone).end.getTime();
|
|
9286
|
+
return end > firstMidnight + (options.crossMidnightMinutes ?? TOP_LANE_CROSS_MIDNIGHT_MINUTES) * MINUTE_MS;
|
|
9287
|
+
}
|
|
9288
|
+
function layoutTimeGridDay(entries, date, timeZone, options = {}) {
|
|
9289
|
+
const bounds = zonedDayBounds(date, timeZone);
|
|
9290
|
+
const dayStart = bounds.start.getTime();
|
|
9291
|
+
const dayEnd = bounds.end.getTime();
|
|
9292
|
+
const parts = /* @__PURE__ */ new Map();
|
|
9293
|
+
for (const entry of entries) {
|
|
9294
|
+
const start = instantMs(entry.start);
|
|
9295
|
+
const end = Math.max(instantMs(entry.end), start);
|
|
9296
|
+
const touches = end > start ? start < dayEnd && end > dayStart : start >= dayStart && start < dayEnd;
|
|
9297
|
+
if (!touches || placesInTopLane(entry, timeZone, options)) continue;
|
|
9298
|
+
parts.set(entry.id, {
|
|
9299
|
+
start: Math.max(start, dayStart),
|
|
9300
|
+
end: Math.min(end, dayEnd),
|
|
9301
|
+
part: start < dayStart ? "continuation" : end > dayEnd ? "start" : "whole"
|
|
9302
|
+
});
|
|
9303
|
+
}
|
|
9304
|
+
const packed = packLanes([...parts].map(([id, part]) => ({ id, start: part.start, end: part.end })), options.maxLanes ?? Infinity);
|
|
9305
|
+
const segments = [];
|
|
9306
|
+
const hidden = [];
|
|
9307
|
+
for (const cluster of packed.clusters) {
|
|
9308
|
+
for (const id of cluster.ids) {
|
|
9309
|
+
const part = parts.get(id);
|
|
9310
|
+
const lane = packed.lanes[id].lane;
|
|
9311
|
+
if (lane === null) {
|
|
9312
|
+
hidden.push(id);
|
|
9313
|
+
continue;
|
|
9314
|
+
}
|
|
9315
|
+
segments.push({
|
|
9316
|
+
id,
|
|
9317
|
+
part: part.part,
|
|
9318
|
+
start: part.start,
|
|
9319
|
+
end: part.end,
|
|
9320
|
+
offsetHours: (part.start - dayStart) / HOUR_MS,
|
|
9321
|
+
lengthHours: (part.end - part.start) / HOUR_MS,
|
|
9322
|
+
lane,
|
|
9323
|
+
laneCount: Math.max(cluster.laneCount, 1)
|
|
9324
|
+
});
|
|
9325
|
+
}
|
|
9326
|
+
}
|
|
9327
|
+
return { date, dayStart, dayHours: (dayEnd - dayStart) / HOUR_MS, segments, hidden };
|
|
9328
|
+
}
|
|
9329
|
+
function layoutDaySpans(spans, days, options) {
|
|
9330
|
+
if (days.length === 0) throw new RangeError("layoutDaySpans: days is empty");
|
|
9331
|
+
const rowStart = days[0];
|
|
9332
|
+
const rowEnd = addCalendarDays(days[days.length - 1], 1);
|
|
9333
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9334
|
+
const inRow = spans.filter((span) => seen.has(span.id) ? false : (seen.add(span.id), true)).map((span) => ({ id: span.id, days: itemDaySpan(span.start, instantMs(span.end) < instantMs(span.start) ? span.start : span.end, options.timeZone) })).filter((span) => span.days.start < rowEnd && span.days.end > rowStart).map((span) => {
|
|
9335
|
+
const from = span.days.start > rowStart ? span.days.start : rowStart;
|
|
9336
|
+
const to = span.days.end < rowEnd ? span.days.end : rowEnd;
|
|
9337
|
+
return { span, from, startCol: days.indexOf(from), endCol: days.indexOf(addCalendarDays(to, -1)) };
|
|
9338
|
+
});
|
|
9339
|
+
const packed = packLanes(inRow.map(({ span, startCol, endCol }) => ({ id: span.id, start: startCol, end: endCol + 1 })), options.laneCap ?? Infinity, { order: "given" });
|
|
9340
|
+
const layout = { placed: [], hidden: [] };
|
|
9341
|
+
for (const { span, from, startCol, endCol } of inRow) {
|
|
9342
|
+
const lane = packed.lanes[span.id].lane;
|
|
9343
|
+
if (lane === null) {
|
|
9344
|
+
layout.hidden.push(span.id);
|
|
9345
|
+
if (layout.firstHiddenDay === void 0 || from < layout.firstHiddenDay) layout.firstHiddenDay = from;
|
|
9346
|
+
continue;
|
|
9347
|
+
}
|
|
9348
|
+
layout.placed.push({ id: span.id, lane, startCol, endCol, continuesBefore: span.days.start < rowStart, continuesAfter: span.days.end > rowEnd });
|
|
9349
|
+
}
|
|
9350
|
+
return layout;
|
|
9351
|
+
}
|
|
9352
|
+
function proposeMove(span, delta, timeZone) {
|
|
9353
|
+
const shift = (delta.minutes ?? 0) * MINUTE_MS;
|
|
9354
|
+
const start = new Date(instantMs(span.start) + shift);
|
|
9355
|
+
const end = new Date(instantMs(span.end) + shift);
|
|
9356
|
+
if (!delta.days) return { start: start.toISOString(), end: end.toISOString(), adjusted: null };
|
|
9357
|
+
const movedStart = addZonedDays(start, delta.days, timeZone);
|
|
9358
|
+
const movedEnd = addZonedDays(end, delta.days, timeZone);
|
|
9359
|
+
const length = end.getTime() - start.getTime();
|
|
9360
|
+
const collapsed = length > 0 && movedEnd.instant.getTime() <= movedStart.instant.getTime();
|
|
9361
|
+
const proposedEnd = collapsed ? new Date(movedStart.instant.getTime() + length) : movedEnd.instant;
|
|
9362
|
+
return { start: movedStart.instant.toISOString(), end: proposedEnd.toISOString(), adjusted: movedStart.adjusted ?? movedEnd.adjusted };
|
|
9363
|
+
}
|
|
9364
|
+
|
|
9365
|
+
// src/components/SchedulingAgenda.tsx
|
|
9366
|
+
var import_react58 = require("react");
|
|
9367
|
+
var import_jsx_runtime84 = require("react/jsx-runtime");
|
|
9368
|
+
var AGENDA_VIRTUAL_ROW = 44;
|
|
9369
|
+
var AGENDA_NARROW_WIDTH = 576;
|
|
9370
|
+
var AGENDA_NARROW_ROW = 64;
|
|
9371
|
+
var AGENDA_VIRTUAL_VIEWPORT = 640;
|
|
9372
|
+
function uniqueKeys(ids) {
|
|
9373
|
+
const used = /* @__PURE__ */ new Set();
|
|
9374
|
+
return ids.map((id) => {
|
|
9375
|
+
let key = id;
|
|
9376
|
+
for (let times = 1; used.has(key); times++) key = `${id}#${times}`;
|
|
9377
|
+
used.add(key);
|
|
9378
|
+
return key;
|
|
9379
|
+
});
|
|
9380
|
+
}
|
|
9381
|
+
function SchedulingAgenda(props) {
|
|
9382
|
+
const rowCount = props.groups.reduce((sum, group) => sum + group.rows.length, 0);
|
|
9383
|
+
const flat = rowCount > props.virtualizeAbove;
|
|
9384
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(AgendaBody, { ...props, flat }, flat ? "flat" : "grouped");
|
|
9385
|
+
}
|
|
9386
|
+
function AgendaBody({
|
|
9387
|
+
groups,
|
|
9388
|
+
flat,
|
|
9389
|
+
timeZone,
|
|
9390
|
+
labels,
|
|
9391
|
+
headingLevel,
|
|
9392
|
+
dateText,
|
|
9393
|
+
formatInstant,
|
|
9394
|
+
entryName,
|
|
9395
|
+
entryStatus,
|
|
9396
|
+
entryStatusText,
|
|
9397
|
+
entryMarkers,
|
|
9398
|
+
overlayName,
|
|
9399
|
+
renderEntry,
|
|
9400
|
+
renderMarker: renderMarker2,
|
|
9401
|
+
onSelectEntry,
|
|
9402
|
+
onSelectOverlay,
|
|
9403
|
+
onShowMore
|
|
9404
|
+
}) {
|
|
9405
|
+
const groupKeys = uniqueKeys(groups.map((group) => group.date));
|
|
9406
|
+
const flatRows = [];
|
|
9407
|
+
if (flat) {
|
|
9408
|
+
groups.forEach((group, index) => {
|
|
9409
|
+
const groupKey = groupKeys[index];
|
|
9410
|
+
flatRows.push({ kind: "heading", key: `h-${groupKey}`, group });
|
|
9411
|
+
const noteKeys = uniqueKeys((group.annotations ?? []).map((overlay) => overlay.id));
|
|
9412
|
+
(group.annotations ?? []).forEach((overlay, at) => flatRows.push({ kind: "note", key: `n-${groupKey}-${noteKeys[at]}`, group, overlay }));
|
|
9413
|
+
const rowKeys = uniqueKeys(group.rows.map((entry) => entry.id));
|
|
9414
|
+
group.rows.forEach((entry, at) => flatRows.push({ kind: "entry", key: `e-${groupKey}-${rowKeys[at]}`, group, entry }));
|
|
9415
|
+
if ((group.hiddenCount ?? 0) > 0) flatRows.push({ kind: "hidden", key: `m-${groupKey}`, group });
|
|
9416
|
+
if ((group.continuesCount ?? 0) > 0) flatRows.push({ kind: "continues", key: `c-${groupKey}`, group });
|
|
9417
|
+
});
|
|
9418
|
+
}
|
|
9419
|
+
const [narrow, setNarrow] = (0, import_react58.useState)(false);
|
|
9420
|
+
const virtual = useVirtualRows(flatRows, { rowHeight: narrow ? AGENDA_NARROW_ROW : AGENDA_VIRTUAL_ROW, threshold: 0, estimatedViewportHeight: AGENDA_VIRTUAL_VIEWPORT });
|
|
9421
|
+
const scroller = virtual.containerRef;
|
|
9422
|
+
(0, import_react58.useLayoutEffect)(() => {
|
|
9423
|
+
const box = scroller.current;
|
|
9424
|
+
if (!box) return;
|
|
9425
|
+
const measure = () => setNarrow(box.clientWidth > 0 && box.clientWidth <= AGENDA_NARROW_WIDTH);
|
|
9426
|
+
measure();
|
|
9427
|
+
const observer = new ResizeObserver(measure);
|
|
9428
|
+
observer.observe(box);
|
|
9429
|
+
return () => observer.disconnect();
|
|
9430
|
+
}, [scroller]);
|
|
9431
|
+
const grouped = (0, import_react58.useRef)(null);
|
|
9432
|
+
(0, import_react58.useLayoutEffect)(() => {
|
|
9433
|
+
const box = grouped.current;
|
|
9434
|
+
if (!box) return;
|
|
9435
|
+
const observer = new ResizeObserver((entries) => {
|
|
9436
|
+
for (const entry of entries) {
|
|
9437
|
+
const head = entry.target;
|
|
9438
|
+
head.parentElement?.style.setProperty("--uix-scheduling-calendar-agenda-head", `${Math.ceil(head.getBoundingClientRect().height)}px`);
|
|
9439
|
+
}
|
|
9440
|
+
});
|
|
9441
|
+
box.querySelectorAll(":scope > section > .uix-scheduling-calendar__agenda-head").forEach((head) => observer.observe(head));
|
|
9442
|
+
return () => observer.disconnect();
|
|
9443
|
+
}, [groups]);
|
|
9444
|
+
const note = (overlay) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("button", { type: "button", className: "uix-scheduling-calendar__window", "data-overlay-id": overlay.id, "data-pattern": overlay.pattern ?? "solid", "data-global": overlay.global || void 0, onClick: () => onSelectOverlay?.(overlay), "aria-label": overlayName(overlay), children: /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("span", { className: "uix-scheduling-calendar__window-text", children: [
|
|
9445
|
+
overlay.kindLabel && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__window-kind", children: overlay.kindLabel }),
|
|
9446
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__window-name", children: overlay.label }),
|
|
9447
|
+
overlay.scopeLabel && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__window-scope", children: overlay.scopeLabel })
|
|
9448
|
+
] }) });
|
|
9449
|
+
const heading = (group, withNotes) => /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "uix-scheduling-calendar__agenda-head", children: [
|
|
9450
|
+
(0, import_react58.createElement)(`h${headingLevel}`, { className: "uix-scheduling-calendar__agenda-heading" }, group.heading ?? dateText(group.date, "day")),
|
|
9451
|
+
withNotes && group.annotations && group.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("ul", { className: "uix-scheduling-calendar__agenda-notes", children: uniqueKeys(group.annotations.map((overlay) => overlay.id)).map((key, at) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("li", { children: note(group.annotations[at]) }, key)) })
|
|
9452
|
+
] });
|
|
9453
|
+
const timeText = (entry, date) => {
|
|
9454
|
+
const part = (text) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__agenda-time-part", children: text });
|
|
9455
|
+
const dash = /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { "aria-hidden": "true", children: " \u2013 " });
|
|
9456
|
+
if (entry.allDay) {
|
|
9457
|
+
let span;
|
|
9458
|
+
try {
|
|
9459
|
+
span = itemDaySpan(entry.start, entry.end, timeZone);
|
|
9460
|
+
} catch {
|
|
9461
|
+
span = itemDaySpan(entry.start, entry.start, timeZone);
|
|
9462
|
+
}
|
|
9463
|
+
const last = addCalendarDays(span.end, -1);
|
|
9464
|
+
if (span.start === date && last === date) return labels.allDay;
|
|
9465
|
+
return span.start === last ? part(dateText(last, "day")) : /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(import_jsx_runtime84.Fragment, { children: [
|
|
9466
|
+
part(dateText(span.start, "day")),
|
|
9467
|
+
dash,
|
|
9468
|
+
part(dateText(last, "day"))
|
|
9469
|
+
] });
|
|
9470
|
+
}
|
|
9471
|
+
const startTime = zonedTimeOfDay(entry.start, timeZone);
|
|
9472
|
+
const endTime = zonedTimeOfDay(entry.end, timeZone);
|
|
9473
|
+
const endDay = zonedDateKey(entry.end, timeZone);
|
|
9474
|
+
const underItsDay = zonedDateKey(entry.start, timeZone) === date && (endDay === date || endDay === addCalendarDays(date, 1) && endTime < startTime);
|
|
9475
|
+
return underItsDay ? /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(import_jsx_runtime84.Fragment, { children: [
|
|
9476
|
+
startTime,
|
|
9477
|
+
dash,
|
|
9478
|
+
endTime
|
|
9479
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(import_jsx_runtime84.Fragment, { children: [
|
|
9480
|
+
part(formatInstant(entry.start)),
|
|
9481
|
+
dash,
|
|
9482
|
+
part(formatInstant(entry.end))
|
|
9483
|
+
] });
|
|
9484
|
+
};
|
|
9485
|
+
const row = (entry, date) => {
|
|
9486
|
+
const markers = entryMarkers(entry);
|
|
9487
|
+
const name = entry.accessibleName ?? (entry.meta ? `${entryName(entry)}, ${entry.meta}` : entryName(entry));
|
|
9488
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("button", { type: "button", className: "uix-scheduling-calendar__agenda-row", "data-item-id": entry.id, "data-band": entry.band ?? "none", "data-status": entryStatus(entry), "data-state": entry.state, onClick: () => onSelectEntry?.(entry), "aria-label": name, children: [
|
|
9489
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__swatch", "aria-hidden": "true", "data-band": entry.band ?? "none", "data-status": entryStatus(entry) }),
|
|
9490
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__agenda-time", children: timeText(entry, date) }),
|
|
9491
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("span", { className: "uix-scheduling-calendar__agenda-main", children: [
|
|
9492
|
+
renderEntry?.(entry) ?? /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__title", children: entry.title }),
|
|
9493
|
+
entry.meta && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__agenda-meta", children: entry.meta })
|
|
9494
|
+
] }),
|
|
9495
|
+
markers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__markers", children: markers.map((marker) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { children: renderMarker2(marker, true) }, marker.id)) }),
|
|
9496
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__status", children: entryStatusText(entry) })
|
|
9497
|
+
] });
|
|
9498
|
+
};
|
|
9499
|
+
const hidden = (group) => {
|
|
9500
|
+
const text = fillLabel(labels.hiddenInDay, { count: group.hiddenCount ?? 0 });
|
|
9501
|
+
return onShowMore ? /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("button", { type: "button", className: "uix-scheduling-calendar__agenda-more", onClick: () => onShowMore(group.date, group.rows), children: text }) : /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("p", { className: "uix-scheduling-calendar__agenda-more", children: text });
|
|
9502
|
+
};
|
|
9503
|
+
const continues = (group) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("p", { className: "uix-scheduling-calendar__agenda-continues", children: fillLabel(labels.continuesInDay, { count: group.continuesCount ?? 0 }) });
|
|
9504
|
+
if (groups.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "uix-scheduling-calendar__agenda", role: "region", "aria-label": labels.agenda, children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("p", { children: labels.agendaEmpty }) });
|
|
9505
|
+
if (flat) {
|
|
9506
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { ref: virtual.containerRef, className: "uix-scheduling-calendar__agenda uix-scheduling-calendar__agenda--virtual", "data-narrow": narrow || void 0, role: "region", "aria-label": labels.agenda, children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "uix-scheduling-calendar__agenda-window", style: { paddingTop: virtual.padTop, paddingBottom: virtual.padBottom }, children: virtual.rows.map((item) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "uix-scheduling-calendar__agenda-vrow", "data-kind": item.kind, children: item.kind === "heading" ? heading(item.group, false) : item.kind === "note" ? note(item.overlay) : item.kind === "entry" ? row(item.entry, item.group.date) : item.kind === "hidden" ? hidden(item.group) : continues(item.group) }, item.key)) }) });
|
|
9507
|
+
}
|
|
9508
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { ref: grouped, className: "uix-scheduling-calendar__agenda", role: "region", "aria-label": labels.agenda, children: groups.map((group, index) => {
|
|
9509
|
+
const rowKeys = uniqueKeys(group.rows.map((entry) => entry.id));
|
|
9510
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("section", { className: "uix-scheduling-calendar__agenda-group", "data-date": group.date, children: [
|
|
9511
|
+
heading(group, true),
|
|
9512
|
+
group.rows.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("ol", { className: "uix-scheduling-calendar__agenda-rows", children: group.rows.map((entry, at) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("li", { children: row(entry, group.date) }, rowKeys[at])) }),
|
|
9513
|
+
(group.hiddenCount ?? 0) > 0 && hidden(group),
|
|
9514
|
+
(group.continuesCount ?? 0) > 0 && continues(group)
|
|
9515
|
+
] }, groupKeys[index]);
|
|
9516
|
+
}) });
|
|
9517
|
+
}
|
|
9518
|
+
|
|
9519
|
+
// src/components/SchedulingTimeGrid.tsx
|
|
9520
|
+
var import_react59 = require("react");
|
|
9521
|
+
var import_jsx_runtime85 = require("react/jsx-runtime");
|
|
9522
|
+
var HOUR_MS2 = 36e5;
|
|
9523
|
+
var MINUTES_PER_HOUR = 60;
|
|
9524
|
+
var LINES_PER_HOUR = 3;
|
|
9525
|
+
var DRAG_THRESHOLD = 4;
|
|
9526
|
+
var DEFAULT_STEP = 15;
|
|
9527
|
+
var vars = (values) => values;
|
|
9528
|
+
var linesFor = (segment) => Math.max(0, Math.floor(segment.lengthHours * LINES_PER_HOUR - 0.25));
|
|
9529
|
+
var slotSignature = (slots) => slots.map((slot) => `${slot.label}${slot.offsetLabel ?? ""}`).join(" ");
|
|
9530
|
+
function uniqueById(items) {
|
|
9531
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9532
|
+
return items.filter((item) => seen.has(item.id) ? false : (seen.add(item.id), true));
|
|
9533
|
+
}
|
|
9534
|
+
var GridItem = (0, import_react59.memo)(function GridItem2({ entry, segment, column, alone, name, status, movable, hintId, timeZone, continuesFrom, markers, renderEntry, renderMarker: renderMarker2, handlers }) {
|
|
9535
|
+
const lines = linesFor(segment);
|
|
9536
|
+
const continuation = segment.part === "continuation";
|
|
9537
|
+
const style = vars({
|
|
9538
|
+
"--uix-scheduling-calendar-offset": segment.offsetHours,
|
|
9539
|
+
"--uix-scheduling-calendar-length": segment.lengthHours,
|
|
9540
|
+
"--uix-scheduling-calendar-lane": segment.lane,
|
|
9541
|
+
"--uix-scheduling-calendar-lanes": segment.laneCount
|
|
9542
|
+
});
|
|
9543
|
+
const text = renderEntry?.(entry, { availableLines: lines }) ?? (lines > 0 ? /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(import_jsx_runtime85.Fragment, { children: [
|
|
9544
|
+
!continuation && /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(import_jsx_runtime85.Fragment, { children: [
|
|
9545
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__time", children: zonedTimeOfDay(entry.start, timeZone) }),
|
|
9546
|
+
" "
|
|
9547
|
+
] }),
|
|
9548
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__title", children: entry.title })
|
|
9549
|
+
] }) : null);
|
|
9550
|
+
const body = /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(import_jsx_runtime85.Fragment, { children: [
|
|
9551
|
+
continuation && lines > 0 && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__tg-from", children: continuesFrom }),
|
|
9552
|
+
(!continuation || alone) && text != null && text !== false && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__entry-text", children: text }),
|
|
9553
|
+
markers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__markers", children: markers.map((marker) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { children: renderMarker2(marker) }, marker.id)) })
|
|
9554
|
+
] });
|
|
9555
|
+
const shared = {
|
|
9556
|
+
className: "uix-scheduling-calendar__entry uix-scheduling-calendar__tg-item",
|
|
9557
|
+
"data-band": entry.band ?? "none",
|
|
9558
|
+
"data-status": status,
|
|
9559
|
+
"data-state": entry.state,
|
|
9560
|
+
"data-part": segment.part,
|
|
9561
|
+
"data-lines": Math.min(lines, 3),
|
|
9562
|
+
"data-movable": movable || void 0,
|
|
9563
|
+
style,
|
|
9564
|
+
onClick: () => handlers.click(entry),
|
|
9565
|
+
onPointerDown: movable ? (event) => handlers.pointerDown(event, entry, column, false) : void 0
|
|
9566
|
+
};
|
|
9567
|
+
if (continuation && !alone) return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { ...shared, "data-continuation-of": entry.id, "aria-hidden": "true", children: body });
|
|
9568
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
9569
|
+
"button",
|
|
9570
|
+
{
|
|
9571
|
+
type: "button",
|
|
9572
|
+
...shared,
|
|
9573
|
+
"data-item-id": entry.id,
|
|
9574
|
+
"aria-label": name,
|
|
9575
|
+
"aria-describedby": movable ? hintId : void 0,
|
|
9576
|
+
onKeyDown: movable ? (event) => handlers.keyDown(event, entry) : void 0,
|
|
9577
|
+
onBlur: movable ? () => handlers.blur(entry) : void 0,
|
|
9578
|
+
children: body
|
|
9579
|
+
}
|
|
9580
|
+
);
|
|
9581
|
+
}, (previous, next) => previous.entry === next.entry && previous.column === next.column && previous.alone === next.alone && previous.name === next.name && previous.status === next.status && previous.movable === next.movable && previous.hintId === next.hintId && previous.timeZone === next.timeZone && previous.continuesFrom === next.continuesFrom && previous.renderEntry === next.renderEntry && previous.segment.part === next.segment.part && previous.segment.offsetHours === next.segment.offsetHours && previous.segment.lengthHours === next.segment.lengthHours && previous.segment.lane === next.segment.lane && previous.segment.laneCount === next.segment.laneCount);
|
|
9582
|
+
function SchedulingTimeGrid({
|
|
9583
|
+
view,
|
|
9584
|
+
days,
|
|
9585
|
+
timeZone,
|
|
9586
|
+
entries: givenEntries,
|
|
9587
|
+
overlays: givenOverlays,
|
|
9588
|
+
dayInfo,
|
|
9589
|
+
labels,
|
|
9590
|
+
gridLabel,
|
|
9591
|
+
dateText,
|
|
9592
|
+
formatInstant,
|
|
9593
|
+
entryName,
|
|
9594
|
+
entryStatus,
|
|
9595
|
+
entryMarkers,
|
|
9596
|
+
overlayName,
|
|
9597
|
+
renderEntry,
|
|
9598
|
+
renderMarker: renderMarker2,
|
|
9599
|
+
onSelectEntry,
|
|
9600
|
+
onSelectOverlay,
|
|
9601
|
+
onSelectDate,
|
|
9602
|
+
onShowMore,
|
|
9603
|
+
now,
|
|
9604
|
+
canMove,
|
|
9605
|
+
step: givenStep,
|
|
9606
|
+
onProposeMove,
|
|
9607
|
+
topLaneCrossMidnightMinutes,
|
|
9608
|
+
topLaneCap,
|
|
9609
|
+
windowLaneCap,
|
|
9610
|
+
maxLanes,
|
|
9611
|
+
emptyNote,
|
|
9612
|
+
nothingToShow
|
|
9613
|
+
}) {
|
|
9614
|
+
const rootRef = (0, import_react59.useRef)(null);
|
|
9615
|
+
const hintId = (0, import_react59.useId)();
|
|
9616
|
+
const [widthCap, setWidthCap] = (0, import_react59.useState)(Infinity);
|
|
9617
|
+
const [ghost, setGhost] = (0, import_react59.useState)(null);
|
|
9618
|
+
const [announcement, setAnnouncement] = (0, import_react59.useState)("");
|
|
9619
|
+
const moving = canMove && onProposeMove !== void 0;
|
|
9620
|
+
const step = Number.isFinite(givenStep) && givenStep > 0 ? givenStep : DEFAULT_STEP;
|
|
9621
|
+
const laneOptions = (0, import_react59.useMemo)(() => ({ crossMidnightMinutes: topLaneCrossMidnightMinutes }), [topLaneCrossMidnightMinutes]);
|
|
9622
|
+
const entries = (0, import_react59.useMemo)(() => uniqueById(givenEntries), [givenEntries]);
|
|
9623
|
+
const overlays = (0, import_react59.useMemo)(() => uniqueById(givenOverlays), [givenOverlays]);
|
|
9624
|
+
(0, import_react59.useEffect)(() => {
|
|
9625
|
+
const root = rootRef.current;
|
|
9626
|
+
if (!root || typeof ResizeObserver === "undefined") return void 0;
|
|
9627
|
+
const column = root.querySelector("[data-tg-column]");
|
|
9628
|
+
const probe = root.querySelector(".uix-scheduling-calendar__tg-probe");
|
|
9629
|
+
if (!column || !probe) return void 0;
|
|
9630
|
+
let frame = 0;
|
|
9631
|
+
const measure = () => {
|
|
9632
|
+
frame = 0;
|
|
9633
|
+
if (!column.isConnected) return;
|
|
9634
|
+
const lane = probe.getBoundingClientRect().width;
|
|
9635
|
+
const width = column.getBoundingClientRect().width;
|
|
9636
|
+
setWidthCap(lane > 0 && width > 0 ? Math.max(1, Math.floor(width / lane)) : Infinity);
|
|
9637
|
+
};
|
|
9638
|
+
const observer = new ResizeObserver(() => {
|
|
9639
|
+
if (!frame) frame = requestAnimationFrame(measure);
|
|
9640
|
+
});
|
|
9641
|
+
observer.observe(column);
|
|
9642
|
+
measure();
|
|
9643
|
+
return () => {
|
|
9644
|
+
observer.disconnect();
|
|
9645
|
+
if (frame) cancelAnimationFrame(frame);
|
|
9646
|
+
};
|
|
9647
|
+
}, [days]);
|
|
9648
|
+
const lanes = Math.max(1, Math.min(maxLanes, widthCap));
|
|
9649
|
+
const entryById = (0, import_react59.useMemo)(() => new Map(entries.map((entry) => [entry.id, entry])), [entries]);
|
|
9650
|
+
const overlayById = (0, import_react59.useMemo)(() => new Map(overlays.map((overlay) => [overlay.id, overlay])), [overlays]);
|
|
9651
|
+
const columns = (0, import_react59.useMemo)(() => days.map((date) => layoutTimeGridDay(entries, date, timeZone, { ...laneOptions, maxLanes: lanes })), [days, entries, timeZone, laneOptions, lanes]);
|
|
9652
|
+
const slots = (0, import_react59.useMemo)(() => days.map((date) => zonedHourSlots(date, timeZone)), [days, timeZone]);
|
|
9653
|
+
const top = (0, import_react59.useMemo)(() => layoutDaySpans(entries.filter((entry) => placesInTopLane(entry, timeZone, laneOptions)), days, { timeZone, laneCap: Math.max(0, topLaneCap) }), [entries, days, timeZone, laneOptions, topLaneCap]);
|
|
9654
|
+
const drawable = (0, import_react59.useMemo)(() => overlays.filter((overlay) => new Date(overlay.end).getTime() >= new Date(overlay.start).getTime()), [overlays]);
|
|
9655
|
+
const strip = (0, import_react59.useMemo)(() => layoutDaySpans(drawable, days, { timeZone, laneCap: Math.max(0, windowLaneCap) }), [drawable, days, timeZone, windowLaneCap]);
|
|
9656
|
+
const shades = (0, import_react59.useMemo)(() => layoutDaySpans(drawable.filter((overlay) => overlay.global), days, { timeZone }).placed, [drawable, days, timeZone]);
|
|
9657
|
+
const lanesIn = (placed) => placed.reduce((max, span) => Math.max(max, span.lane + 1), 0);
|
|
9658
|
+
const maxHours = Math.max(...columns.map((column) => column.dayHours));
|
|
9659
|
+
const gutterIndex = (0, import_react59.useMemo)(() => {
|
|
9660
|
+
const signatures = slots.map(slotSignature);
|
|
9661
|
+
const count2 = /* @__PURE__ */ new Map();
|
|
9662
|
+
for (const signature of signatures) count2.set(signature, (count2.get(signature) ?? 0) + 1);
|
|
9663
|
+
let best = 0;
|
|
9664
|
+
signatures.forEach((signature, index) => {
|
|
9665
|
+
if ((count2.get(signature) ?? 0) > (count2.get(signatures[best]) ?? 0)) best = index;
|
|
9666
|
+
});
|
|
9667
|
+
return best;
|
|
9668
|
+
}, [slots]);
|
|
9669
|
+
const gutterSignature = slotSignature(slots[gutterIndex]);
|
|
9670
|
+
const hourLabels = (index, inline) => slots[index].map((slot) => /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(
|
|
9671
|
+
"div",
|
|
9672
|
+
{
|
|
9673
|
+
className: inline ? "uix-scheduling-calendar__tg-hour uix-scheduling-calendar__tg-hour--inline" : "uix-scheduling-calendar__tg-hour",
|
|
9674
|
+
"data-hour": slot.label,
|
|
9675
|
+
style: vars({ "--uix-scheduling-calendar-offset": (slot.instant.getTime() - columns[index].dayStart) / HOUR_MS2 }),
|
|
9676
|
+
children: [
|
|
9677
|
+
slot.label,
|
|
9678
|
+
slot.offsetLabel && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__tg-offset", children: slot.offsetLabel })
|
|
9679
|
+
]
|
|
9680
|
+
},
|
|
9681
|
+
slot.instant.getTime()
|
|
9682
|
+
));
|
|
9683
|
+
const movable = (entry) => moving && entry.movable !== false;
|
|
9684
|
+
const live = (0, import_react59.useRef)({ ghost, entryById, timeZone, step, onProposeMove, onSelectEntry, labels, formatInstant, days, columns, movable });
|
|
9685
|
+
live.current = { ghost, entryById, timeZone, step, onProposeMove, onSelectEntry, labels, formatInstant, days, columns, movable };
|
|
9686
|
+
const dragRef = (0, import_react59.useRef)(null);
|
|
9687
|
+
const suppressClick = (0, import_react59.useRef)(false);
|
|
9688
|
+
const refocus = (0, import_react59.useRef)(null);
|
|
9689
|
+
(0, import_react59.useEffect)(() => {
|
|
9690
|
+
if (ghost && !entryById.has(ghost.id)) setGhost(null);
|
|
9691
|
+
}, [ghost, entryById]);
|
|
9692
|
+
(0, import_react59.useEffect)(() => {
|
|
9693
|
+
const id = refocus.current;
|
|
9694
|
+
const root = rootRef.current;
|
|
9695
|
+
if (!id || !root) return;
|
|
9696
|
+
const active = document.activeElement;
|
|
9697
|
+
const lost = !active || active === document.body;
|
|
9698
|
+
if (!lost) {
|
|
9699
|
+
if (active.getAttribute("data-item-id") !== id) refocus.current = null;
|
|
9700
|
+
return;
|
|
9701
|
+
}
|
|
9702
|
+
for (const candidate of Array.from(root.querySelectorAll("[data-item-id]"))) {
|
|
9703
|
+
if (candidate.getAttribute("data-item-id") === id) {
|
|
9704
|
+
candidate.focus();
|
|
9705
|
+
break;
|
|
9706
|
+
}
|
|
9707
|
+
}
|
|
9708
|
+
});
|
|
9709
|
+
const send = (0, import_react59.useCallback)((id, delta) => {
|
|
9710
|
+
const state = live.current;
|
|
9711
|
+
const entry = state.entryById.get(id);
|
|
9712
|
+
if (!entry || !state.onProposeMove || !state.movable(entry) || delta.days === 0 && delta.minutes === 0) {
|
|
9713
|
+
setGhost(null);
|
|
9714
|
+
return;
|
|
9715
|
+
}
|
|
9716
|
+
const proposal = proposeMove(entry, delta, state.timeZone);
|
|
9717
|
+
const result = state.onProposeMove(id, proposal);
|
|
9718
|
+
if (result && typeof result.then === "function") {
|
|
9719
|
+
setGhost({ id, delta, source: "sent", proposal });
|
|
9720
|
+
const clear = () => setGhost((current) => current && current.source === "sent" && current.proposal === proposal ? null : current);
|
|
9721
|
+
result.then(clear, clear);
|
|
9722
|
+
} else setGhost(null);
|
|
9723
|
+
}, []);
|
|
9724
|
+
const handlers = (0, import_react59.useMemo)(() => ({
|
|
9725
|
+
click: (entry) => {
|
|
9726
|
+
live.current.onSelectEntry?.(entry);
|
|
9727
|
+
},
|
|
9728
|
+
keyDown: (event, entry) => {
|
|
9729
|
+
const state = live.current;
|
|
9730
|
+
const pending = state.ghost && state.ghost.id === entry.id && state.ghost.source === "keys" ? state.ghost.delta : null;
|
|
9731
|
+
if (event.key === "Enter" && pending) {
|
|
9732
|
+
event.preventDefault();
|
|
9733
|
+
refocus.current = entry.id;
|
|
9734
|
+
send(entry.id, pending);
|
|
9735
|
+
return;
|
|
9736
|
+
}
|
|
9737
|
+
if (event.key === "Escape" && pending) {
|
|
9738
|
+
event.preventDefault();
|
|
9739
|
+
event.stopPropagation();
|
|
9740
|
+
setGhost(null);
|
|
9741
|
+
setAnnouncement(state.labels.moveCancelled);
|
|
9742
|
+
return;
|
|
9743
|
+
}
|
|
9744
|
+
if (!event.shiftKey) return;
|
|
9745
|
+
const base = pending ?? { days: 0, minutes: 0 };
|
|
9746
|
+
const next = event.key === "ArrowUp" ? { ...base, minutes: base.minutes - state.step } : event.key === "ArrowDown" ? { ...base, minutes: base.minutes + state.step } : event.key === "ArrowLeft" ? { ...base, days: base.days - 1 } : event.key === "ArrowRight" ? { ...base, days: base.days + 1 } : null;
|
|
9747
|
+
if (!next) return;
|
|
9748
|
+
event.preventDefault();
|
|
9749
|
+
if (next.days === 0 && next.minutes === 0) {
|
|
9750
|
+
setGhost(null);
|
|
9751
|
+
setAnnouncement(state.labels.moveCancelled);
|
|
9752
|
+
return;
|
|
9753
|
+
}
|
|
9754
|
+
const proposal = proposeMove(entry, next, state.timeZone);
|
|
9755
|
+
setGhost({ id: entry.id, delta: next, source: "keys", proposal });
|
|
9756
|
+
const proposed = fillLabel(state.labels.moveProposed, { start: state.formatInstant(proposal.start), end: state.formatInstant(proposal.end) });
|
|
9757
|
+
setAnnouncement(proposal.adjusted ? `${fillLabel(state.labels.gapForward, { time: zonedTimeOfDay(proposal.start, state.timeZone) })} ${proposed}` : proposed);
|
|
9758
|
+
},
|
|
9759
|
+
blur: (entry) => {
|
|
9760
|
+
refocus.current = null;
|
|
9761
|
+
setGhost((current) => current && current.id === entry.id && current.source === "keys" ? null : current);
|
|
9762
|
+
},
|
|
9763
|
+
pointerDown: (event, entry, column, top2) => {
|
|
9764
|
+
if (event.button !== 0 || dragRef.current) return;
|
|
9765
|
+
const root = rootRef.current;
|
|
9766
|
+
if (!root) return;
|
|
9767
|
+
const elements = Array.from(root.querySelectorAll("[data-tg-column]"));
|
|
9768
|
+
const rects = elements.map((element) => element.getBoundingClientRect());
|
|
9769
|
+
const under = rects.findIndex((rect) => event.clientX >= rect.left && event.clientX < rect.right);
|
|
9770
|
+
const from = under === -1 ? column : under;
|
|
9771
|
+
const hours = live.current.columns[from]?.dayHours ?? 1;
|
|
9772
|
+
const finish = (commit) => {
|
|
9773
|
+
const drag = dragRef.current;
|
|
9774
|
+
if (!drag) return;
|
|
9775
|
+
drag.stop();
|
|
9776
|
+
dragRef.current = null;
|
|
9777
|
+
if (!drag.moved) return;
|
|
9778
|
+
suppressClick.current = true;
|
|
9779
|
+
setTimeout(() => {
|
|
9780
|
+
suppressClick.current = false;
|
|
9781
|
+
}, 0);
|
|
9782
|
+
if (commit && !drag.dropped) send(drag.id, drag.delta);
|
|
9783
|
+
else setGhost(null);
|
|
9784
|
+
};
|
|
9785
|
+
const onMove = (move) => {
|
|
9786
|
+
const drag = dragRef.current;
|
|
9787
|
+
if (!drag || move.pointerId !== drag.pointerId) return;
|
|
9788
|
+
if (move.buttons === 0 && move.pointerType === "mouse") {
|
|
9789
|
+
finish(false);
|
|
9790
|
+
return;
|
|
9791
|
+
}
|
|
9792
|
+
if (drag.dropped) return;
|
|
9793
|
+
const dx = move.clientX - drag.x;
|
|
9794
|
+
const dy = move.clientY - drag.y;
|
|
9795
|
+
if (!drag.moved && Math.hypot(dx, dy) < DRAG_THRESHOLD) return;
|
|
9796
|
+
drag.moved = true;
|
|
9797
|
+
const target = drag.rects.findIndex((rect) => move.clientX >= rect.left && move.clientX < rect.right);
|
|
9798
|
+
const stepMinutes = live.current.step;
|
|
9799
|
+
const delta = {
|
|
9800
|
+
days: target === -1 ? drag.delta.days : target - drag.column,
|
|
9801
|
+
minutes: drag.top || drag.hourPx <= 0 ? 0 : Math.round(dy / drag.hourPx * MINUTES_PER_HOUR / stepMinutes) * stepMinutes
|
|
9802
|
+
};
|
|
9803
|
+
if (delta.days === drag.delta.days && delta.minutes === drag.delta.minutes) return;
|
|
9804
|
+
drag.delta = delta;
|
|
9805
|
+
const dragged = live.current.entryById.get(drag.id);
|
|
9806
|
+
if (dragged) setGhost({ id: drag.id, delta, source: "pointer", proposal: proposeMove(dragged, delta, live.current.timeZone) });
|
|
9807
|
+
};
|
|
9808
|
+
const onUp = (up) => {
|
|
9809
|
+
if (up.pointerId === dragRef.current?.pointerId) finish(true);
|
|
9810
|
+
};
|
|
9811
|
+
const onCancel = (cancel) => {
|
|
9812
|
+
if (cancel.pointerId === dragRef.current?.pointerId) finish(false);
|
|
9813
|
+
};
|
|
9814
|
+
const onKey = (key) => {
|
|
9815
|
+
const drag = dragRef.current;
|
|
9816
|
+
if (key.key !== "Escape" || !drag?.moved || drag.dropped) return;
|
|
9817
|
+
key.preventDefault();
|
|
9818
|
+
key.stopPropagation();
|
|
9819
|
+
drag.dropped = true;
|
|
9820
|
+
setGhost(null);
|
|
9821
|
+
};
|
|
9822
|
+
window.addEventListener("pointermove", onMove);
|
|
9823
|
+
window.addEventListener("pointerup", onUp);
|
|
9824
|
+
window.addEventListener("pointercancel", onCancel);
|
|
9825
|
+
window.addEventListener("keydown", onKey, true);
|
|
9826
|
+
dragRef.current = {
|
|
9827
|
+
id: entry.id,
|
|
9828
|
+
pointerId: event.pointerId,
|
|
9829
|
+
x: event.clientX,
|
|
9830
|
+
y: event.clientY,
|
|
9831
|
+
column: from,
|
|
9832
|
+
top: top2,
|
|
9833
|
+
moved: false,
|
|
9834
|
+
dropped: false,
|
|
9835
|
+
rects,
|
|
9836
|
+
hourPx: (rects[from]?.height ?? 0) / hours,
|
|
9837
|
+
delta: { days: 0, minutes: 0 },
|
|
9838
|
+
stop: () => {
|
|
9839
|
+
window.removeEventListener("pointermove", onMove);
|
|
9840
|
+
window.removeEventListener("pointerup", onUp);
|
|
9841
|
+
window.removeEventListener("pointercancel", onCancel);
|
|
9842
|
+
window.removeEventListener("keydown", onKey, true);
|
|
9843
|
+
}
|
|
9844
|
+
};
|
|
9845
|
+
}
|
|
9846
|
+
}), [send]);
|
|
9847
|
+
(0, import_react59.useEffect)(() => () => {
|
|
9848
|
+
dragRef.current?.stop();
|
|
9849
|
+
dragRef.current = null;
|
|
9850
|
+
}, []);
|
|
9851
|
+
const gridColumns = (span) => `${span.startCol + 2} / ${span.endCol + 3}`;
|
|
9852
|
+
const nowAt = now === void 0 ? null : new Date(now).getTime();
|
|
9853
|
+
const nowColumn = nowAt === null || Number.isNaN(nowAt) ? -1 : days.indexOf(zonedDateKey(new Date(nowAt), timeZone));
|
|
9854
|
+
const topHiddenOn = (date) => top.hidden.filter((id) => {
|
|
9855
|
+
const entry = entryById.get(id);
|
|
9856
|
+
return entry ? layoutDaySpans([entry], [date], { timeZone }).placed.length > 0 : false;
|
|
9857
|
+
});
|
|
9858
|
+
const windowLanes = lanesIn(strip.placed);
|
|
9859
|
+
const topLanes = lanesIn(top.placed);
|
|
9860
|
+
const moreWindows = strip.hidden.length;
|
|
9861
|
+
const firstHiddenWindowDay = strip.firstHiddenDay ?? days[0];
|
|
9862
|
+
const ghostEntry = ghost ? entryById.get(ghost.id) : void 0;
|
|
9863
|
+
const ghostTop = ghostEntry ? placesInTopLane(ghostEntry, timeZone, laneOptions) : false;
|
|
9864
|
+
const ghostParts = ghost && ghostEntry && !ghostTop ? days.map((date) => layoutTimeGridDay([{ id: "ghost", start: ghost.proposal.start, end: ghost.proposal.end }], date, timeZone, { crossMidnightMinutes: Infinity }).segments) : null;
|
|
9865
|
+
const ghostSpan = ghost && ghostEntry && ghostTop ? layoutDaySpans([{ id: "ghost", start: ghost.proposal.start, end: ghost.proposal.end }], days, { timeZone }).placed[0] : void 0;
|
|
9866
|
+
const ghostLane = ghost ? top.placed.find((span) => span.id === ghost.id)?.lane ?? 0 : 0;
|
|
9867
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(
|
|
9868
|
+
"div",
|
|
9869
|
+
{
|
|
9870
|
+
ref: rootRef,
|
|
9871
|
+
className: "uix-scheduling-calendar__timegrid",
|
|
9872
|
+
"data-view": view,
|
|
9873
|
+
role: "group",
|
|
9874
|
+
"aria-label": gridLabel,
|
|
9875
|
+
style: vars({ "--uix-scheduling-calendar-days": days.length, "--uix-scheduling-calendar-hours": maxHours }),
|
|
9876
|
+
onClickCapture: (event) => {
|
|
9877
|
+
if (suppressClick.current) {
|
|
9878
|
+
suppressClick.current = false;
|
|
9879
|
+
event.preventDefault();
|
|
9880
|
+
event.stopPropagation();
|
|
9881
|
+
}
|
|
9882
|
+
},
|
|
9883
|
+
children: [
|
|
9884
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "uix-scheduling-calendar__tg-head", children: [
|
|
9885
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "uix-scheduling-calendar__tg-zone", children: fillLabel(labels.timeZone, { timeZone }) }),
|
|
9886
|
+
days.map((date, index) => {
|
|
9887
|
+
const info = dayInfo?.[date];
|
|
9888
|
+
const hiddenIds = dayInfo ? [] : [...columns[index].hidden, ...topHiddenOn(date)];
|
|
9889
|
+
const more = info ? info.overflowCount : hiddenIds.length;
|
|
9890
|
+
const moreText = fillLabel(labels.moreSpans, { count: more });
|
|
9891
|
+
const moreName = fillLabel(labels.moreEntriesLabel, { count: more, date: dateText(date, "day") });
|
|
9892
|
+
const headName = info ? info.label ?? `${dateText(date, "day")}, ${fillLabel(labels.dayCount, { count: info.count })}` : dateText(date, "day");
|
|
9893
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "uix-scheduling-calendar__tg-dayhead", role: "group", "aria-label": headName, "data-date": date, children: [
|
|
9894
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("button", { type: "button", className: "uix-scheduling-calendar__date", "data-calendar-date": date, "aria-label": dateText(date, "day"), onClick: onSelectDate ? () => onSelectDate(date) : void 0, children: dateText(date, "column") }),
|
|
9895
|
+
info && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__count", "aria-hidden": "true", children: info.count }),
|
|
9896
|
+
info?.markers && info.markers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__markers", children: info.markers.map((marker) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { children: renderMarker2(marker, true) }, marker.id)) }),
|
|
9897
|
+
more > 0 && (onShowMore ? /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("button", { type: "button", className: "uix-scheduling-calendar__more", "aria-label": moreName, onClick: () => onShowMore(date, hiddenIds.map((id) => entryById.get(id)).filter(Boolean)), children: moreText }) : /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("span", { className: "uix-scheduling-calendar__more", children: [
|
|
9898
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { "aria-hidden": "true", children: moreText }),
|
|
9899
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-visually-hidden", children: moreName })
|
|
9900
|
+
] }))
|
|
9901
|
+
] }, date);
|
|
9902
|
+
})
|
|
9903
|
+
] }),
|
|
9904
|
+
(windowLanes > 0 || moreWindows > 0) && /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "uix-scheduling-calendar__tg-strip", role: "group", "aria-label": labels.windows, style: vars({ "--uix-scheduling-calendar-lanes": Math.max(windowLanes, 1) }), children: [
|
|
9905
|
+
strip.placed.map((placed) => {
|
|
9906
|
+
const overlay = overlayById.get(placed.id);
|
|
9907
|
+
if (!overlay) return null;
|
|
9908
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
9909
|
+
"button",
|
|
9910
|
+
{
|
|
9911
|
+
type: "button",
|
|
9912
|
+
className: "uix-scheduling-calendar__window",
|
|
9913
|
+
"data-overlay-id": overlay.id,
|
|
9914
|
+
"data-pattern": overlay.pattern ?? "solid",
|
|
9915
|
+
"data-global": overlay.global || void 0,
|
|
9916
|
+
"data-kind": overlay.kind,
|
|
9917
|
+
"data-continues-before": placed.continuesBefore || void 0,
|
|
9918
|
+
"data-continues-after": placed.continuesAfter || void 0,
|
|
9919
|
+
style: { gridColumn: gridColumns(placed), ...vars({ "--uix-scheduling-calendar-lane": placed.lane }) },
|
|
9920
|
+
onClick: () => onSelectOverlay?.(overlay),
|
|
9921
|
+
"aria-label": overlayName(overlay),
|
|
9922
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("span", { className: "uix-scheduling-calendar__window-text", children: [
|
|
9923
|
+
overlay.kindLabel && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__window-kind", children: overlay.kindLabel }),
|
|
9924
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__window-name", children: overlay.label }),
|
|
9925
|
+
overlay.scopeLabel && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__window-scope", children: overlay.scopeLabel })
|
|
9926
|
+
] })
|
|
9927
|
+
},
|
|
9928
|
+
placed.id
|
|
9929
|
+
);
|
|
9930
|
+
}),
|
|
9931
|
+
moreWindows > 0 && (onShowMore ? /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("button", { type: "button", className: "uix-scheduling-calendar__rowmore", "aria-label": fillLabel(labels.moreWindowsLabel, { count: moreWindows, date: dateText(firstHiddenWindowDay, "day") }), onClick: () => onShowMore(firstHiddenWindowDay, []), children: fillLabel(labels.moreWindows, { count: moreWindows }) }) : /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__rowmore", children: fillLabel(labels.moreWindows, { count: moreWindows }) }))
|
|
9932
|
+
] }),
|
|
9933
|
+
(topLanes > 0 || ghostSpan) && /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "uix-scheduling-calendar__tg-strip uix-scheduling-calendar__tg-top", role: "group", "aria-label": labels.topLane, style: vars({ "--uix-scheduling-calendar-lanes": Math.max(topLanes, 1) }), children: [
|
|
9934
|
+
top.placed.map((placed) => {
|
|
9935
|
+
const entry = entryById.get(placed.id);
|
|
9936
|
+
if (!entry) return null;
|
|
9937
|
+
const canDrag = movable(entry);
|
|
9938
|
+
const markers = entryMarkers(entry);
|
|
9939
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(
|
|
9940
|
+
"button",
|
|
9941
|
+
{
|
|
9942
|
+
type: "button",
|
|
9943
|
+
className: "uix-scheduling-calendar__entry uix-scheduling-calendar__tg-span",
|
|
9944
|
+
"data-item-id": entry.id,
|
|
9945
|
+
"data-band": entry.band ?? "none",
|
|
9946
|
+
"data-status": entryStatus(entry),
|
|
9947
|
+
"data-state": entry.state,
|
|
9948
|
+
"data-movable": canDrag || void 0,
|
|
9949
|
+
"data-continues-before": placed.continuesBefore || void 0,
|
|
9950
|
+
"data-continues-after": placed.continuesAfter || void 0,
|
|
9951
|
+
style: { gridColumn: gridColumns(placed), ...vars({ "--uix-scheduling-calendar-lane": placed.lane }) },
|
|
9952
|
+
"aria-label": entryName(entry),
|
|
9953
|
+
"aria-describedby": canDrag ? hintId : void 0,
|
|
9954
|
+
onClick: () => handlers.click(entry),
|
|
9955
|
+
onKeyDown: canDrag ? (event) => handlers.keyDown(event, entry) : void 0,
|
|
9956
|
+
onBlur: canDrag ? () => handlers.blur(entry) : void 0,
|
|
9957
|
+
onPointerDown: canDrag ? (event) => handlers.pointerDown(event, entry, placed.startCol, true) : void 0,
|
|
9958
|
+
children: [
|
|
9959
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__entry-text", children: renderEntry?.(entry, { availableLines: 1 }) ?? /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(import_jsx_runtime85.Fragment, { children: [
|
|
9960
|
+
!placed.continuesBefore && !entry.allDay && /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(import_jsx_runtime85.Fragment, { children: [
|
|
9961
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__time", children: zonedTimeOfDay(entry.start, timeZone) }),
|
|
9962
|
+
" "
|
|
9963
|
+
] }),
|
|
9964
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__title", children: entry.title })
|
|
9965
|
+
] }) }),
|
|
9966
|
+
markers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__markers", children: markers.map((marker) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { children: renderMarker2(marker) }, marker.id)) })
|
|
9967
|
+
]
|
|
9968
|
+
},
|
|
9969
|
+
placed.id
|
|
9970
|
+
);
|
|
9971
|
+
}),
|
|
9972
|
+
ghostSpan && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "uix-scheduling-calendar__tg-ghost", "aria-hidden": "true", "data-sent": ghost?.source === "sent" || void 0, style: { gridColumn: gridColumns(ghostSpan), ...vars({ "--uix-scheduling-calendar-lane": ghostLane }) } })
|
|
9973
|
+
] }),
|
|
9974
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "uix-scheduling-calendar__tg-body", children: [
|
|
9975
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "uix-scheduling-calendar__tg-gutter", "aria-hidden": "true", children: hourLabels(gutterIndex, false) }),
|
|
9976
|
+
shades.map((placed) => {
|
|
9977
|
+
const overlay = overlayById.get(placed.id);
|
|
9978
|
+
const first = columns[placed.startCol];
|
|
9979
|
+
const last = columns[placed.endCol];
|
|
9980
|
+
const from = placed.continuesBefore ? 0 : Math.max(0, (new Date(overlay.start).getTime() - first.dayStart) / HOUR_MS2) / maxHours;
|
|
9981
|
+
const to = (placed.continuesAfter ? last.dayHours : Math.min(last.dayHours, (new Date(overlay.end).getTime() - last.dayStart) / HOUR_MS2)) / maxHours;
|
|
9982
|
+
const width = 100 / (placed.endCol - placed.startCol + 1);
|
|
9983
|
+
const percent = (value) => `${Math.round(value * 1e4) / 100}%`;
|
|
9984
|
+
const clipPath = placed.startCol === placed.endCol ? `polygon(0 ${percent(from)}, 100% ${percent(from)}, 100% ${percent(to)}, 0 ${percent(to)})` : `polygon(0 ${percent(from)}, ${width}% ${percent(from)}, ${width}% 0, 100% 0, 100% ${percent(to)}, ${100 - width}% ${percent(to)}, ${100 - width}% 100%, 0 100%)`;
|
|
9985
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "uix-scheduling-calendar__tg-shade", "aria-hidden": "true", "data-pattern": overlay.pattern ?? "solid", style: { gridColumn: gridColumns(placed), clipPath } }, `shade-${placed.id}`);
|
|
9986
|
+
}),
|
|
9987
|
+
columns.map((column, index) => /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "uix-scheduling-calendar__tg-column", "data-tg-column": column.date, style: { gridColumn: `${index + 2}`, ...vars({ "--uix-scheduling-calendar-hours": column.dayHours }) }, children: [
|
|
9988
|
+
slotSignature(slots[index]) !== gutterSignature && hourLabels(index, true),
|
|
9989
|
+
column.segments.map((segment) => {
|
|
9990
|
+
const entry = entryById.get(segment.id);
|
|
9991
|
+
const alone = segment.part === "continuation" && index === 0;
|
|
9992
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
9993
|
+
GridItem,
|
|
9994
|
+
{
|
|
9995
|
+
entry,
|
|
9996
|
+
segment,
|
|
9997
|
+
column: index,
|
|
9998
|
+
alone,
|
|
9999
|
+
name: entryName(entry),
|
|
10000
|
+
status: entryStatus(entry),
|
|
10001
|
+
movable: movable(entry),
|
|
10002
|
+
hintId,
|
|
10003
|
+
timeZone,
|
|
10004
|
+
continuesFrom: fillLabel(labels.continuesFrom, { time: zonedTimeOfDay(entry.start, timeZone) }),
|
|
10005
|
+
markers: entryMarkers(entry),
|
|
10006
|
+
renderEntry,
|
|
10007
|
+
renderMarker: renderMarker2,
|
|
10008
|
+
handlers
|
|
10009
|
+
},
|
|
10010
|
+
`${segment.id}-${segment.part}`
|
|
10011
|
+
);
|
|
10012
|
+
}),
|
|
10013
|
+
ghostParts?.[index].map((segment) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
10014
|
+
"div",
|
|
10015
|
+
{
|
|
10016
|
+
className: "uix-scheduling-calendar__tg-ghost",
|
|
10017
|
+
"aria-hidden": "true",
|
|
10018
|
+
"data-sent": ghost?.source === "sent" || void 0,
|
|
10019
|
+
style: vars({ "--uix-scheduling-calendar-offset": segment.offsetHours, "--uix-scheduling-calendar-length": segment.lengthHours })
|
|
10020
|
+
},
|
|
10021
|
+
`ghost-${segment.part}`
|
|
10022
|
+
)),
|
|
10023
|
+
index === nowColumn && nowAt !== null && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "uix-scheduling-calendar__tg-now", "aria-hidden": "true", style: vars({ "--uix-scheduling-calendar-offset": (nowAt - column.dayStart) / HOUR_MS2 }) })
|
|
10024
|
+
] }, column.date))
|
|
10025
|
+
] }),
|
|
10026
|
+
emptyNote != null && emptyNote !== false && nothingToShow && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "uix-scheduling-calendar__empty", children: emptyNote }),
|
|
10027
|
+
moving && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("p", { id: hintId, className: "uix-visually-hidden", children: labels.moveHint }),
|
|
10028
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__tg-probe", "aria-hidden": "true", children: "00:00 abcdef" }),
|
|
10029
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "uix-visually-hidden", "aria-live": "polite", children: announcement })
|
|
10030
|
+
]
|
|
10031
|
+
}
|
|
10032
|
+
);
|
|
10033
|
+
}
|
|
9270
10034
|
|
|
9271
10035
|
// src/components/SchedulingCalendar.tsx
|
|
9272
|
-
var
|
|
10036
|
+
var import_jsx_runtime86 = require("react/jsx-runtime");
|
|
9273
10037
|
var DEFAULT_SCHEDULING_CALENDAR_LABELS = {
|
|
9274
10038
|
region: "Scheduling calendar in {timeZone}",
|
|
9275
10039
|
previous: "Previous",
|
|
@@ -9278,9 +10042,12 @@ var DEFAULT_SCHEDULING_CALENDAR_LABELS = {
|
|
|
9278
10042
|
nextMonth: "Next month",
|
|
9279
10043
|
previousWeek: "Previous week",
|
|
9280
10044
|
nextWeek: "Next week",
|
|
10045
|
+
previousDay: "Previous day",
|
|
10046
|
+
nextDay: "Next day",
|
|
9281
10047
|
viewGroup: "Calendar view",
|
|
9282
10048
|
viewMonth: "Month",
|
|
9283
10049
|
viewWeek: "Week",
|
|
10050
|
+
viewDay: "Day",
|
|
9284
10051
|
viewAgenda: "Agenda",
|
|
9285
10052
|
loading: "Loading schedule\u2026",
|
|
9286
10053
|
retry: "Try again",
|
|
@@ -9297,17 +10064,32 @@ var DEFAULT_SCHEDULING_CALENDAR_LABELS = {
|
|
|
9297
10064
|
moreSpansLabel: "{count} more spanning this week, from {date}",
|
|
9298
10065
|
dayCount: "{count} entries",
|
|
9299
10066
|
states: { scheduled: "Scheduled", conflicted: "Conflicted", "in-progress": "In progress", "blackout-violation": "Blackout violation" },
|
|
9300
|
-
statuses: { tentative: "Tentative", committed: "Scheduled", live: "In progress", done: "Done", dead: "Cancelled" }
|
|
10067
|
+
statuses: { tentative: "Tentative", committed: "Scheduled", live: "In progress", done: "Done", dead: "Cancelled" },
|
|
10068
|
+
timeZone: "{timeZone}",
|
|
10069
|
+
windows: "Windows",
|
|
10070
|
+
moreWindows: "+{count} windows",
|
|
10071
|
+
moreWindowsLabel: "{count} more windows, from {date}",
|
|
10072
|
+
topLane: "All-day and longer entries",
|
|
10073
|
+
continuesFrom: "from {time}",
|
|
10074
|
+
allDay: "All day",
|
|
10075
|
+
hiddenInDay: "{count} not shown \u2014 open day",
|
|
10076
|
+
continuesInDay: "Continues: {count} listed under an earlier day",
|
|
10077
|
+
moveHint: "Hold Shift and press an arrow key to move it. Enter confirms, Escape cancels.",
|
|
10078
|
+
moveProposed: "Move to {start} \u2013 {end}. Enter confirms, Escape cancels.",
|
|
10079
|
+
moveCancelled: "Move cancelled.",
|
|
10080
|
+
gapForward: "That time does not exist on this day. Moved forward to {time}."
|
|
9301
10081
|
};
|
|
9302
10082
|
var stateTone = (state) => state === "scheduled" ? "info" : state === "in-progress" ? "success" : "danger";
|
|
9303
10083
|
var utcDate = (date) => /* @__PURE__ */ new Date(`${date}T00:00:00Z`);
|
|
9304
10084
|
var INTL_PARTS = {
|
|
9305
10085
|
day: { dateStyle: "full", timeZone: "UTC" },
|
|
9306
10086
|
weekday: { weekday: "short", timeZone: "UTC" },
|
|
9307
|
-
month: { month: "long", year: "numeric", timeZone: "UTC" }
|
|
10087
|
+
month: { month: "long", year: "numeric", timeZone: "UTC" },
|
|
10088
|
+
column: { weekday: "short", day: "2-digit", month: "2-digit", timeZone: "UTC" }
|
|
9308
10089
|
};
|
|
9309
10090
|
var EMPTY_OVERLAYS = [];
|
|
9310
10091
|
var EMPTY_ENTRIES = [];
|
|
10092
|
+
var EMPTY_IDS = [];
|
|
9311
10093
|
var DEFAULT_LANE_CAP2 = 2;
|
|
9312
10094
|
var DEFAULT_CHIP_ROWS = 3;
|
|
9313
10095
|
function coveredDays(start, end, timeZone) {
|
|
@@ -9317,13 +10099,14 @@ function coveredDays(start, end, timeZone) {
|
|
|
9317
10099
|
return itemDaySpan(start, start, timeZone);
|
|
9318
10100
|
}
|
|
9319
10101
|
}
|
|
9320
|
-
function Marker({ marker }) {
|
|
10102
|
+
function Marker({ marker, showLabel }) {
|
|
9321
10103
|
const emphasis = marker.emphasis ?? "neutral";
|
|
9322
|
-
return /* @__PURE__ */ (0,
|
|
9323
|
-
marker.icon != null && /* @__PURE__ */ (0,
|
|
9324
|
-
/* @__PURE__ */ (0,
|
|
10104
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("span", { className: "uix-scheduling-calendar__marker", "data-emphasis": emphasis, "data-glyph": marker.icon == null ? emphasis : void 0, children: [
|
|
10105
|
+
marker.icon != null && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-calendar__marker-icon", "aria-hidden": "true", children: marker.icon }),
|
|
10106
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: showLabel ? "uix-scheduling-calendar__marker-label" : "uix-visually-hidden", children: marker.label })
|
|
9325
10107
|
] });
|
|
9326
10108
|
}
|
|
10109
|
+
var renderMarker = (marker, showLabel) => /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(Marker, { marker, showLabel });
|
|
9327
10110
|
function SchedulingCalendar({
|
|
9328
10111
|
entries,
|
|
9329
10112
|
anchorDate,
|
|
@@ -9354,6 +10137,18 @@ function SchedulingCalendar({
|
|
|
9354
10137
|
notice,
|
|
9355
10138
|
emptyNote,
|
|
9356
10139
|
onSelectDate,
|
|
10140
|
+
agendaGroups,
|
|
10141
|
+
agendaHeadingLevel = 3,
|
|
10142
|
+
virtualizeAbove = 200,
|
|
10143
|
+
monthDensity = "full",
|
|
10144
|
+
timeGrid = false,
|
|
10145
|
+
now,
|
|
10146
|
+
canMove = false,
|
|
10147
|
+
step = 15,
|
|
10148
|
+
onProposeMove,
|
|
10149
|
+
topLaneCrossMidnightMinutes = TOP_LANE_CROSS_MIDNIGHT_MINUTES,
|
|
10150
|
+
topLaneCap = 3,
|
|
10151
|
+
maxLanes = 4,
|
|
9357
10152
|
loading,
|
|
9358
10153
|
error,
|
|
9359
10154
|
onRetry,
|
|
@@ -9369,26 +10164,28 @@ function SchedulingCalendar({
|
|
|
9369
10164
|
statuses: { ...DEFAULT_SCHEDULING_CALENDAR_LABELS.statuses, ...uixLabels.schedulingCalendar?.statuses, ...labelOverrides?.statuses }
|
|
9370
10165
|
};
|
|
9371
10166
|
const stateLabel = labels.states;
|
|
9372
|
-
const viewLabel = { month: labels.viewMonth, week: labels.viewWeek, agenda: labels.viewAgenda };
|
|
9373
|
-
const [internalView, setInternalView] = (0,
|
|
10167
|
+
const viewLabel = { month: labels.viewMonth, week: labels.viewWeek, day: labels.viewDay, agenda: labels.viewAgenda };
|
|
10168
|
+
const [internalView, setInternalView] = (0, import_react60.useState)("month");
|
|
9374
10169
|
const view = controlledView ?? internalView;
|
|
9375
|
-
const [activeDate, setActiveDate] = (0,
|
|
9376
|
-
const [expandedDates, setExpandedDates] = (0,
|
|
10170
|
+
const [activeDate, setActiveDate] = (0, import_react60.useState)(anchorDate);
|
|
10171
|
+
const [expandedDates, setExpandedDates] = (0, import_react60.useState)(() => /* @__PURE__ */ new Set());
|
|
9377
10172
|
const dateText = (date, part) => formatDate?.(date, part) ?? cachedDateTimeFormat(locale, INTL_PARTS[part]).format(utcDate(date));
|
|
9378
10173
|
const formatInstant = (instant) => formatInstantProp?.(instant) ?? `${dateText(zonedDateKey(instant, timeZone), "day")} ${zonedTimeOfDay(instant, timeZone)}`;
|
|
9379
|
-
const gridRef = (0,
|
|
10174
|
+
const gridRef = (0, import_react60.useRef)(null);
|
|
9380
10175
|
const picksGiven = dayEntries !== void 0;
|
|
9381
10176
|
const controlled = picksGiven || dayInfo !== void 0;
|
|
9382
|
-
const
|
|
10177
|
+
const countsOnly = monthDensity === "counts" && view === "month";
|
|
10178
|
+
const fixed = controlled || maxEntriesPerDay !== void 0 && onShowMore !== void 0 || countsOnly;
|
|
9383
10179
|
const windowCap = Math.max(0, windowLaneCap ?? (fixed ? DEFAULT_LANE_CAP2 : Infinity));
|
|
9384
10180
|
const spanCap = Math.max(0, spanLaneCap ?? (fixed ? DEFAULT_LANE_CAP2 : Infinity));
|
|
9385
|
-
const visibleEntries = (0,
|
|
9386
|
-
const monthDays = (0,
|
|
10181
|
+
const visibleEntries = (0, import_react60.useMemo)(() => entries.filter((entry) => filter?.(entry) ?? true), [entries, filter]);
|
|
10182
|
+
const monthDays = (0, import_react60.useMemo)(() => buildMonthGrid(startOfMonth(anchorDate), weekStartsOn), [anchorDate, weekStartsOn]);
|
|
9387
10183
|
const weekday = (utcDate(anchorDate).getUTCDay() - weekStartsOn + 7) % 7;
|
|
9388
10184
|
const weekStart = addCalendarDays(anchorDate, -weekday);
|
|
9389
|
-
const weekDays = (0,
|
|
9390
|
-
const days = (0,
|
|
9391
|
-
const
|
|
10185
|
+
const weekDays = (0, import_react60.useMemo)(() => Array.from({ length: 7 }, (_, index) => addCalendarDays(weekStart, index)), [weekStart]);
|
|
10186
|
+
const days = (0, import_react60.useMemo)(() => view === "month" ? monthDays.map((day) => day.date) : view === "day" ? [anchorDate] : weekDays, [view, monthDays, weekDays, anchorDate]);
|
|
10187
|
+
const timeGridView = view === "day" || view === "week" && timeGrid;
|
|
10188
|
+
const { singles, multiDay, coverage } = (0, import_react60.useMemo)(() => {
|
|
9392
10189
|
const byDay = /* @__PURE__ */ new Map();
|
|
9393
10190
|
const spans = [];
|
|
9394
10191
|
const every = [];
|
|
@@ -9403,11 +10200,11 @@ function SchedulingCalendar({
|
|
|
9403
10200
|
}
|
|
9404
10201
|
return { singles: byDay, multiDay: spans, coverage: every };
|
|
9405
10202
|
}, [visibleEntries, timeZone]);
|
|
9406
|
-
const entryById = (0,
|
|
9407
|
-
const overlayById = (0,
|
|
9408
|
-
const layout = (0,
|
|
10203
|
+
const entryById = (0, import_react60.useMemo)(() => new Map([...multiDay].reverse().map(({ entry }) => [entry.id, entry])), [multiDay]);
|
|
10204
|
+
const overlayById = (0, import_react60.useMemo)(() => new Map([...overlays].reverse().map((overlay) => [overlay.id, overlay])), [overlays]);
|
|
10205
|
+
const layout = (0, import_react60.useMemo)(() => {
|
|
9409
10206
|
if (spanLayout) return spanLayout;
|
|
9410
|
-
if (view === "agenda") return { placed: [], hiddenByRow: {}, firstHiddenDayByRow: {} };
|
|
10207
|
+
if (view === "agenda" || timeGridView) return { placed: [], hiddenByRow: {}, firstHiddenDayByRow: {} };
|
|
9411
10208
|
const inputs = [];
|
|
9412
10209
|
const windowIds = /* @__PURE__ */ new Set();
|
|
9413
10210
|
const itemIds = /* @__PURE__ */ new Set();
|
|
@@ -9416,14 +10213,14 @@ function SchedulingCalendar({
|
|
|
9416
10213
|
windowIds.add(overlay.id);
|
|
9417
10214
|
inputs.push({ id: overlay.id, start: overlay.start, end: overlay.end, group: "window" });
|
|
9418
10215
|
}
|
|
9419
|
-
for (const { entry } of multiDay) {
|
|
10216
|
+
for (const { entry } of countsOnly ? [] : multiDay) {
|
|
9420
10217
|
if (itemIds.has(entry.id)) continue;
|
|
9421
10218
|
itemIds.add(entry.id);
|
|
9422
10219
|
inputs.push({ id: entry.id, start: entry.start, end: entry.end, group: "item" });
|
|
9423
10220
|
}
|
|
9424
10221
|
return layoutMonthSpans(inputs, days, { timeZone, laneCap: { window: windowCap, item: spanCap } });
|
|
9425
|
-
}, [spanLayout, view, overlays, multiDay, days, timeZone, windowCap, spanCap]);
|
|
9426
|
-
const placedByRow = (0,
|
|
10222
|
+
}, [spanLayout, view, timeGridView, overlays, multiDay, days, timeZone, windowCap, spanCap, countsOnly]);
|
|
10223
|
+
const placedByRow = (0, import_react60.useMemo)(() => {
|
|
9427
10224
|
const rows = /* @__PURE__ */ new Map();
|
|
9428
10225
|
for (const placed of layout.placed) {
|
|
9429
10226
|
const row = rows.get(placed.weekRow);
|
|
@@ -9434,16 +10231,16 @@ function SchedulingCalendar({
|
|
|
9434
10231
|
}, [layout]);
|
|
9435
10232
|
const lanesUsed = (row, group) => (placedByRow.get(row) ?? []).reduce((max, placed) => placed.group === group ? Math.max(max, placed.lane + 1) : max, 0);
|
|
9436
10233
|
const lanesUsedAnywhere = (group) => layout.placed.reduce((max, placed) => placed.group === group ? Math.max(max, placed.lane + 1) : max, 0);
|
|
9437
|
-
(0,
|
|
10234
|
+
(0, import_react60.useEffect)(() => {
|
|
9438
10235
|
if (view !== "agenda" && !days.includes(activeDate)) setActiveDate(days[0]);
|
|
9439
10236
|
}, [activeDate, days, view]);
|
|
9440
10237
|
const setView = (next) => {
|
|
9441
10238
|
if (controlledView === void 0) setInternalView(next);
|
|
9442
10239
|
onViewChange?.(next);
|
|
9443
10240
|
};
|
|
9444
|
-
const movePeriod = (direction) => onAnchorDateChange?.(view === "month" ? addCalendarMonths(anchorDate, direction) : addCalendarDays(anchorDate, direction * 7));
|
|
10241
|
+
const movePeriod = (direction) => onAnchorDateChange?.(view === "month" ? addCalendarMonths(anchorDate, direction) : addCalendarDays(anchorDate, view === "day" ? direction : direction * 7));
|
|
9445
10242
|
const periodLabel = (direction) => {
|
|
9446
|
-
const key = `${direction}${view === "month" ? "Month" : "Week"}`;
|
|
10243
|
+
const key = `${direction}${view === "month" ? "Month" : view === "day" ? "Day" : "Week"}`;
|
|
9447
10244
|
return overrides[key] ?? overrides[direction] ?? labels[key];
|
|
9448
10245
|
};
|
|
9449
10246
|
const focusDate = (date) => {
|
|
@@ -9495,15 +10292,15 @@ function SchedulingCalendar({
|
|
|
9495
10292
|
});
|
|
9496
10293
|
const entryContent = (entry, withTime = true) => {
|
|
9497
10294
|
const markers = markersOf(entry);
|
|
9498
|
-
return /* @__PURE__ */ (0,
|
|
9499
|
-
/* @__PURE__ */ (0,
|
|
9500
|
-
withTime && /* @__PURE__ */ (0,
|
|
9501
|
-
/* @__PURE__ */ (0,
|
|
10295
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(import_jsx_runtime86.Fragment, { children: [
|
|
10296
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-calendar__entry-text", children: renderEntry?.(entry) ?? /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(import_jsx_runtime86.Fragment, { children: [
|
|
10297
|
+
withTime && /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(import_jsx_runtime86.Fragment, { children: [
|
|
10298
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-calendar__time", children: zonedTimeOfDay(entry.start, timeZone) }),
|
|
9502
10299
|
" "
|
|
9503
10300
|
] }),
|
|
9504
|
-
/* @__PURE__ */ (0,
|
|
10301
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-calendar__title", children: entry.title })
|
|
9505
10302
|
] }) }),
|
|
9506
|
-
markers.length > 0 && /* @__PURE__ */ (0,
|
|
10303
|
+
markers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-calendar__markers", children: markers.map((marker) => /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(Marker, { marker }, marker.id)) })
|
|
9507
10304
|
] });
|
|
9508
10305
|
};
|
|
9509
10306
|
const laneStyle = (placed, windowLanes) => ({
|
|
@@ -9511,126 +10308,183 @@ function SchedulingCalendar({
|
|
|
9511
10308
|
["--uix-scheduling-calendar-lane"]: placed.group === "window" ? placed.lane : windowLanes + placed.lane
|
|
9512
10309
|
});
|
|
9513
10310
|
const nothingToShow = visibleEntries.length === 0 && !Object.values(dayEntries ?? {}).some((list) => list.length > 0) && !Object.values(dayInfo ?? {}).some((day) => day.count > 0);
|
|
9514
|
-
const chipRows = Math.max(0, maxEntriesPerDay ?? DEFAULT_CHIP_ROWS, ...Object.values(dayEntries ?? {}).map((list) => list.length));
|
|
10311
|
+
const chipRows = countsOnly ? -1 : Math.max(0, maxEntriesPerDay ?? DEFAULT_CHIP_ROWS, ...Object.values(dayEntries ?? {}).map((list) => list.length));
|
|
9515
10312
|
const renderDay = (date, index) => {
|
|
9516
10313
|
const info = dayInfo?.[date];
|
|
9517
10314
|
const all = picksGiven ? dayEntries[date] ?? EMPTY_ENTRIES : singles.get(date) ?? EMPTY_ENTRIES;
|
|
9518
10315
|
const overflowing = !picksGiven && maxEntriesPerDay !== void 0 && all.length > maxEntriesPerDay;
|
|
9519
10316
|
const collapsed = overflowing && (controlled || onShowMore !== void 0 || !expandedDates.has(date));
|
|
9520
|
-
const shown = collapsed ? all.slice(0, Math.max(0, maxEntriesPerDay)) : all;
|
|
10317
|
+
const shown = countsOnly ? EMPTY_ENTRIES : collapsed ? all.slice(0, Math.max(0, maxEntriesPerDay)) : all;
|
|
9521
10318
|
const hiddenCount = info ? info.overflowCount : picksGiven ? 0 : all.length - shown.length;
|
|
9522
10319
|
const onDay = picksGiven ? all : entriesOn(date);
|
|
9523
10320
|
const badge = renderDayBadge?.(date, onDay);
|
|
9524
10321
|
const hasBadge = badge != null && badge !== false;
|
|
9525
|
-
const dateButton = /* @__PURE__ */ (0,
|
|
10322
|
+
const dateButton = /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("button", { type: "button", className: "uix-scheduling-calendar__date", "data-calendar-date": date, tabIndex: activeDate === date ? 0 : -1, onFocus: () => setActiveDate(date), onKeyDown: (event) => onDayKeyDown(event, date), onClick: onSelectDate ? () => onSelectDate(date) : void 0, "aria-label": dateText(date, "day"), children: Number(date.slice(-2)) });
|
|
9526
10323
|
const moreText = fillLabel(labels.moreEntries, { count: hiddenCount });
|
|
9527
10324
|
const moreName = fillLabel(labels.moreEntriesLabel, { count: hiddenCount, date: dateText(date, "day") });
|
|
9528
|
-
return /* @__PURE__ */ (0,
|
|
9529
|
-
hasBadge || info ? /* @__PURE__ */ (0,
|
|
9530
|
-
hasBadge && /* @__PURE__ */ (0,
|
|
9531
|
-
info && /* @__PURE__ */ (0,
|
|
9532
|
-
/* @__PURE__ */ (0,
|
|
9533
|
-
/* @__PURE__ */ (0,
|
|
10325
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "uix-scheduling-calendar__day", "data-outside": view === "month" && !monthDays[index].inMonth || void 0, children: [
|
|
10326
|
+
hasBadge || info ? /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "uix-scheduling-calendar__dayhead", children: [
|
|
10327
|
+
hasBadge && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-calendar__badge", children: badge }),
|
|
10328
|
+
info && /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("span", { className: "uix-scheduling-calendar__count", children: [
|
|
10329
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { "aria-hidden": "true", children: info.count }),
|
|
10330
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-visually-hidden", children: info.label ?? fillLabel(labels.dayCount, { count: info.count }) })
|
|
9534
10331
|
] }),
|
|
9535
|
-
info?.markers && info.markers.length > 0 && /* @__PURE__ */ (0,
|
|
10332
|
+
info?.markers && info.markers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-calendar__markers", children: info.markers.map((marker) => /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(Marker, { marker }, marker.id)) }),
|
|
9536
10333
|
dateButton
|
|
9537
10334
|
] }) : dateButton,
|
|
9538
|
-
/* @__PURE__ */ (0,
|
|
9539
|
-
shown.map((entry) => /* @__PURE__ */ (0,
|
|
9540
|
-
controlled ? hiddenCount > 0 && (onShowMore ? /* @__PURE__ */ (0,
|
|
9541
|
-
/* @__PURE__ */ (0,
|
|
9542
|
-
/* @__PURE__ */ (0,
|
|
9543
|
-
] })) : overflowing && /* @__PURE__ */ (0,
|
|
10335
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "uix-scheduling-calendar__entries", children: [
|
|
10336
|
+
shown.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("button", { className: "uix-scheduling-calendar__entry", ...entryProps(entry), children: entryContent(entry) }, entry.id)),
|
|
10337
|
+
countsOnly ? null : controlled ? hiddenCount > 0 && (onShowMore ? /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("button", { type: "button", className: "uix-scheduling-calendar__more", "aria-label": moreName, onClick: () => onShowMore(date, onDay), children: moreText }) : /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("span", { className: "uix-scheduling-calendar__more", children: [
|
|
10338
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { "aria-hidden": "true", children: moreText }),
|
|
10339
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-visually-hidden", children: moreName })
|
|
10340
|
+
] })) : overflowing && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("button", { type: "button", className: "uix-scheduling-calendar__more", "aria-expanded": onShowMore ? void 0 : !collapsed, "aria-label": collapsed ? moreName : void 0, onClick: () => toggleMore(date, onDay), children: collapsed ? moreText : labels.fewerEntries })
|
|
9544
10341
|
] })
|
|
9545
10342
|
] }, date);
|
|
9546
10343
|
};
|
|
9547
10344
|
const renderWeek = (row) => {
|
|
9548
10345
|
const rowDays = days.slice(row * 7, row * 7 + 7);
|
|
9549
10346
|
const windowLanes = lanesUsed(row, "window");
|
|
9550
|
-
const spanLanes = lanesUsed(row, "item");
|
|
9551
|
-
const
|
|
10347
|
+
const spanLanes = countsOnly ? 0 : lanesUsed(row, "item");
|
|
10348
|
+
const hiddenIds = layout.hiddenByRow?.[row] ?? EMPTY_IDS;
|
|
10349
|
+
const drawnWindows = countsOnly ? new Set((placedByRow.get(row) ?? []).filter((placed) => placed.group === "window").map((placed) => placed.id)) : void 0;
|
|
10350
|
+
const hidden = countsOnly ? hiddenIds.filter((id) => overlayById.has(id) && !drawnWindows.has(id)).length : hiddenIds.length;
|
|
9552
10351
|
const firstHiddenDay = layout.firstHiddenDayByRow?.[row] ?? rowDays[0];
|
|
9553
10352
|
const moreText = fillLabel(labels.moreSpans, { count: hidden });
|
|
9554
10353
|
const moreName = fillLabel(labels.moreSpansLabel, { count: hidden, date: dateText(firstHiddenDay, "day") });
|
|
9555
10354
|
const style = { ["--uix-scheduling-calendar-lanes"]: Math.max(windowLanes + spanLanes, hidden > 0 ? 1 : 0) };
|
|
9556
|
-
return /* @__PURE__ */ (0,
|
|
10355
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "uix-scheduling-calendar__week", style, children: [
|
|
9557
10356
|
rowDays.map((date, column) => renderDay(date, row * 7 + column)),
|
|
9558
10357
|
(placedByRow.get(row) ?? []).map((placed) => {
|
|
9559
10358
|
const continues = { "data-continues-before": placed.continuesBefore || void 0, "data-continues-after": placed.continuesAfter || void 0 };
|
|
9560
10359
|
if (placed.group === "window") {
|
|
9561
10360
|
const overlay = overlayById.get(placed.id);
|
|
9562
10361
|
if (!overlay) return null;
|
|
9563
|
-
return /* @__PURE__ */ (0,
|
|
9564
|
-
overlay.kindLabel && /* @__PURE__ */ (0,
|
|
9565
|
-
/* @__PURE__ */ (0,
|
|
9566
|
-
overlay.scopeLabel && /* @__PURE__ */ (0,
|
|
10362
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("button", { type: "button", className: "uix-scheduling-calendar__window", "data-overlay-id": overlay.id, "data-pattern": overlay.pattern ?? "solid", "data-global": overlay.global || void 0, "data-kind": overlay.kind, ...continues, style: laneStyle(placed, windowLanes), onClick: () => onSelectOverlay?.(overlay), "aria-label": overlayName(overlay), children: /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("span", { className: "uix-scheduling-calendar__window-text", children: [
|
|
10363
|
+
overlay.kindLabel && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-calendar__window-kind", children: overlay.kindLabel }),
|
|
10364
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-calendar__window-name", children: overlay.label }),
|
|
10365
|
+
overlay.scopeLabel && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-calendar__window-scope", children: overlay.scopeLabel })
|
|
9567
10366
|
] }) }, `window-${placed.id}`);
|
|
9568
10367
|
}
|
|
9569
10368
|
const entry = entryById.get(placed.id);
|
|
9570
|
-
if (!entry) return null;
|
|
9571
|
-
return /* @__PURE__ */ (0,
|
|
10369
|
+
if (!entry || countsOnly) return null;
|
|
10370
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("button", { className: "uix-scheduling-calendar__entry uix-scheduling-calendar__span", ...entryProps(entry), ...continues, style: laneStyle(placed, windowLanes), children: entryContent(entry, !placed.continuesBefore) }, `span-${placed.id}`);
|
|
9572
10371
|
}),
|
|
9573
|
-
hidden > 0 && (onShowMore ? /* @__PURE__ */ (0,
|
|
9574
|
-
/* @__PURE__ */ (0,
|
|
9575
|
-
/* @__PURE__ */ (0,
|
|
10372
|
+
hidden > 0 && (onShowMore ? /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("button", { type: "button", className: "uix-scheduling-calendar__rowmore", "aria-label": moreName, onClick: () => onShowMore(firstHiddenDay, picksGiven ? dayEntries[firstHiddenDay] ?? EMPTY_ENTRIES : entriesOn(firstHiddenDay)), children: moreText }) : /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("span", { className: "uix-scheduling-calendar__rowmore", children: [
|
|
10373
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { "aria-hidden": "true", children: moreText }),
|
|
10374
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-visually-hidden", children: moreName })
|
|
9576
10375
|
] }))
|
|
9577
10376
|
] }, rowDays[0]);
|
|
9578
10377
|
};
|
|
9579
10378
|
const gridStyle = fixed ? {
|
|
9580
10379
|
["--uix-scheduling-calendar-chips"]: chipRows,
|
|
9581
10380
|
["--uix-scheduling-calendar-lane-cap"]: Math.max(
|
|
9582
|
-
Math.max(Number.isFinite(windowCap) ? windowCap : 0, lanesUsedAnywhere("window")) + Math.max(Number.isFinite(spanCap) ? spanCap : 0, lanesUsedAnywhere("item")),
|
|
10381
|
+
Math.max(Number.isFinite(windowCap) ? windowCap : 0, lanesUsedAnywhere("window")) + (countsOnly ? 0 : Math.max(Number.isFinite(spanCap) ? spanCap : 0, lanesUsedAnywhere("item"))),
|
|
9583
10382
|
Object.keys(layout.hiddenByRow ?? {}).length > 0 ? 1 : 0
|
|
9584
10383
|
)
|
|
9585
10384
|
} : void 0;
|
|
9586
|
-
return /* @__PURE__ */ (0,
|
|
9587
|
-
showHeader && /* @__PURE__ */ (0,
|
|
9588
|
-
/* @__PURE__ */ (0,
|
|
9589
|
-
/* @__PURE__ */ (0,
|
|
9590
|
-
/* @__PURE__ */ (0,
|
|
10385
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("section", { className: cx("uix-scheduling-calendar", className), "aria-label": fillLabel(labels.region, { timeZone }), children: [
|
|
10386
|
+
showHeader && /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "uix-scheduling-calendar__header", children: [
|
|
10387
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { children: [
|
|
10388
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: () => movePeriod(-1), disabled: !onAnchorDateChange, children: periodLabel("previous") }),
|
|
10389
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: () => movePeriod(1), disabled: !onAnchorDateChange, children: periodLabel("next") })
|
|
9591
10390
|
] }),
|
|
9592
|
-
/* @__PURE__ */ (0,
|
|
9593
|
-
/* @__PURE__ */ (0,
|
|
10391
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("strong", { children: view === "month" ? dateText(startOfMonth(anchorDate), "month") : view === "day" ? dateText(anchorDate, "day") : `${dateText(weekStart, "day")} \u2013 ${dateText(weekDays[weekDays.length - 1], "day")}` }),
|
|
10392
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: "uix-segmented", role: "group", "aria-label": labels.viewGroup, children: (timeGrid || view === "day" ? ["month", "week", "day", "agenda"] : ["month", "week", "agenda"]).map((option) => /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("button", { type: "button", className: "uix-segmented__option", "aria-pressed": view === option, "data-selected": view === option || void 0, onClick: () => setView(option), children: viewLabel[option] }, option)) })
|
|
9594
10393
|
] }),
|
|
9595
|
-
notice != null && notice !== false && /* @__PURE__ */ (0,
|
|
9596
|
-
loading ? /* @__PURE__ */ (0,
|
|
9597
|
-
/* @__PURE__ */ (0,
|
|
9598
|
-
onRetry && /* @__PURE__ */ (0,
|
|
9599
|
-
] }) : view === "agenda"
|
|
10394
|
+
notice != null && notice !== false && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: "uix-scheduling-calendar__notice", children: notice }),
|
|
10395
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: "uix-scheduling-calendar__state", role: "status", children: labels.loading }) : error ? /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "uix-scheduling-calendar__state", role: "alert", children: [
|
|
10396
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("p", { children: error }),
|
|
10397
|
+
onRetry && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: onRetry, children: labels.retry })
|
|
10398
|
+
] }) : view === "agenda" && agendaGroups ? /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
10399
|
+
SchedulingAgenda,
|
|
10400
|
+
{
|
|
10401
|
+
groups: agendaGroups,
|
|
10402
|
+
timeZone,
|
|
10403
|
+
labels,
|
|
10404
|
+
headingLevel: agendaHeadingLevel,
|
|
10405
|
+
virtualizeAbove,
|
|
10406
|
+
dateText,
|
|
10407
|
+
formatInstant,
|
|
10408
|
+
entryName,
|
|
10409
|
+
entryStatus: statusOf,
|
|
10410
|
+
entryStatusText: stateText,
|
|
10411
|
+
entryMarkers: markersOf,
|
|
10412
|
+
overlayName,
|
|
10413
|
+
renderEntry,
|
|
10414
|
+
renderMarker,
|
|
10415
|
+
onSelectEntry,
|
|
10416
|
+
onSelectOverlay,
|
|
10417
|
+
onShowMore
|
|
10418
|
+
}
|
|
10419
|
+
) : view === "agenda" ? /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: "uix-scheduling-calendar__agenda", role: "region", "aria-label": labels.agenda, children: visibleEntries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("p", { children: labels.agendaEmpty }) : /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("ol", { children: [...visibleEntries].sort((a, b) => a.start.localeCompare(b.start)).map((entry) => {
|
|
9600
10420
|
const markers = markersOf(entry);
|
|
9601
|
-
return /* @__PURE__ */ (0,
|
|
9602
|
-
/* @__PURE__ */ (0,
|
|
9603
|
-
/* @__PURE__ */ (0,
|
|
9604
|
-
/* @__PURE__ */ (0,
|
|
10421
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("button", { type: "button", "data-item-id": entry.id, "data-band": entry.band ?? "none", "data-status": statusOf(entry), "data-state": entry.state, onClick: () => onSelectEntry?.(entry), children: [
|
|
10422
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("span", { children: [
|
|
10423
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("strong", { children: renderEntry?.(entry) ?? entry.title }),
|
|
10424
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("span", { children: [
|
|
9605
10425
|
formatInstant(entry.start),
|
|
9606
10426
|
" \u2013 ",
|
|
9607
10427
|
formatInstant(entry.end)
|
|
9608
10428
|
] }),
|
|
9609
|
-
entry.meta && /* @__PURE__ */ (0,
|
|
10429
|
+
entry.meta && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { children: entry.meta })
|
|
9610
10430
|
] }),
|
|
9611
|
-
markers.length > 0 && /* @__PURE__ */ (0,
|
|
9612
|
-
entry.state ? /* @__PURE__ */ (0,
|
|
10431
|
+
markers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-calendar__markers", children: markers.map((marker) => /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(Marker, { marker }, marker.id)) }),
|
|
10432
|
+
entry.state ? /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(StatusPill, { tone: stateTone(entry.state), children: stateLabel[entry.state] }) : /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-calendar__status", children: stateText(entry) })
|
|
9613
10433
|
] }) }, entry.id);
|
|
9614
|
-
}) }) }) : /* @__PURE__ */ (0,
|
|
9615
|
-
|
|
10434
|
+
}) }) }) : timeGridView ? /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
10435
|
+
SchedulingTimeGrid,
|
|
10436
|
+
{
|
|
10437
|
+
view: view === "day" ? "day" : "week",
|
|
10438
|
+
days,
|
|
10439
|
+
timeZone,
|
|
10440
|
+
entries: visibleEntries,
|
|
10441
|
+
overlays,
|
|
10442
|
+
dayInfo,
|
|
10443
|
+
labels,
|
|
10444
|
+
gridLabel: fillLabel(labels.grid, { view: viewLabel[view] }),
|
|
10445
|
+
dateText,
|
|
10446
|
+
formatInstant,
|
|
10447
|
+
entryName,
|
|
10448
|
+
entryStatus: statusOf,
|
|
10449
|
+
entryMarkers: markersOf,
|
|
10450
|
+
overlayName,
|
|
10451
|
+
renderEntry,
|
|
10452
|
+
renderMarker,
|
|
10453
|
+
onSelectEntry,
|
|
10454
|
+
onSelectOverlay,
|
|
10455
|
+
onSelectDate,
|
|
10456
|
+
onShowMore,
|
|
10457
|
+
now,
|
|
10458
|
+
canMove,
|
|
10459
|
+
step,
|
|
10460
|
+
onProposeMove,
|
|
10461
|
+
topLaneCrossMidnightMinutes,
|
|
10462
|
+
topLaneCap,
|
|
10463
|
+
windowLaneCap: windowLaneCap ?? DEFAULT_LANE_CAP2,
|
|
10464
|
+
maxLanes,
|
|
10465
|
+
emptyNote,
|
|
10466
|
+
nothingToShow
|
|
10467
|
+
}
|
|
10468
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { ref: gridRef, className: cx("uix-scheduling-calendar__grid", view === "week" && "uix-scheduling-calendar__grid--week"), "data-fixed": fixed || void 0, "data-density": countsOnly ? "counts" : void 0, style: gridStyle, role: "group", "aria-label": fillLabel(labels.grid, { view: viewLabel[view] }), children: [
|
|
10469
|
+
days.slice(0, 7).map((date) => /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: "uix-scheduling-calendar__weekday", "aria-hidden": "true", children: dateText(date, "weekday") }, `weekday-${date}`)),
|
|
9616
10470
|
Array.from({ length: days.length / 7 }, (_, row) => renderWeek(row)),
|
|
9617
|
-
emptyNote != null && emptyNote !== false && nothingToShow && /* @__PURE__ */ (0,
|
|
10471
|
+
emptyNote != null && emptyNote !== false && nothingToShow && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: "uix-scheduling-calendar__empty", children: emptyNote })
|
|
9618
10472
|
] }),
|
|
9619
|
-
legend ? (legend.length > 0 || legendCaption != null && legendCaption !== false) && /* @__PURE__ */ (0,
|
|
9620
|
-
legend.length > 0 && /* @__PURE__ */ (0,
|
|
9621
|
-
/* @__PURE__ */ (0,
|
|
10473
|
+
legend ? (legend.length > 0 || legendCaption != null && legendCaption !== false) && /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "uix-scheduling-calendar__legend", role: "group", "aria-label": labels.legend, children: [
|
|
10474
|
+
legend.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("ul", { className: "uix-scheduling-calendar__legend-list", children: legend.map((item) => /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("li", { "data-legend-id": item.id, children: [
|
|
10475
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-calendar__swatch", "aria-hidden": "true", "data-band": item.swatch.band, "data-status": item.swatch.status, "data-pattern": item.swatch.pattern, children: item.swatch.icon }),
|
|
9622
10476
|
item.label
|
|
9623
10477
|
] }, item.id)) }),
|
|
9624
|
-
legendCaption != null && legendCaption !== false && /* @__PURE__ */ (0,
|
|
9625
|
-
] }) : /* @__PURE__ */ (0,
|
|
9626
|
-
["scheduled", "conflicted", "in-progress", "blackout-violation"].map((state) => /* @__PURE__ */ (0,
|
|
9627
|
-
legendCaption != null && legendCaption !== false && /* @__PURE__ */ (0,
|
|
10478
|
+
legendCaption != null && legendCaption !== false && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("p", { className: "uix-scheduling-calendar__legend-caption", children: legendCaption })
|
|
10479
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "uix-scheduling-calendar__legend", role: "group", "aria-label": labels.legend, children: [
|
|
10480
|
+
["scheduled", "conflicted", "in-progress", "blackout-violation"].map((state) => /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { "data-state": state, children: stateLabel[state] }, state)),
|
|
10481
|
+
legendCaption != null && legendCaption !== false && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("p", { className: "uix-scheduling-calendar__legend-caption", children: legendCaption })
|
|
9628
10482
|
] })
|
|
9629
10483
|
] });
|
|
9630
10484
|
}
|
|
9631
10485
|
|
|
9632
10486
|
// src/components/SchedulingTimeline.tsx
|
|
9633
|
-
var
|
|
10487
|
+
var import_react61 = require("react");
|
|
9634
10488
|
|
|
9635
10489
|
// src/scheduling-timeline-model.ts
|
|
9636
10490
|
var HOUR = 36e5;
|
|
@@ -9732,7 +10586,7 @@ function pixelsToMs(px, trackWidth, range, step) {
|
|
|
9732
10586
|
}
|
|
9733
10587
|
|
|
9734
10588
|
// src/components/SchedulingTimeline.tsx
|
|
9735
|
-
var
|
|
10589
|
+
var import_jsx_runtime87 = require("react/jsx-runtime");
|
|
9736
10590
|
var DEFAULT_SCHEDULING_TIMELINE_LABELS = {
|
|
9737
10591
|
region: "Schedule timeline in {timeZone}",
|
|
9738
10592
|
lanes: "Lanes",
|
|
@@ -9788,20 +10642,20 @@ function SchedulingTimeline({
|
|
|
9788
10642
|
states: { ...DEFAULT_SCHEDULING_TIMELINE_LABELS.states, ...uixLabels.schedulingTimeline?.states, ...labelOverrides?.states },
|
|
9789
10643
|
overlays: { ...DEFAULT_SCHEDULING_TIMELINE_LABELS.overlays, ...uixLabels.schedulingTimeline?.overlays, ...labelOverrides?.overlays }
|
|
9790
10644
|
};
|
|
9791
|
-
const id = (0,
|
|
10645
|
+
const id = (0, import_react61.useId)();
|
|
9792
10646
|
const step = stepProp ?? defaultTimelineStep(scale);
|
|
9793
|
-
const ticks = (0,
|
|
9794
|
-
const laneLayouts = (0,
|
|
10647
|
+
const ticks = (0, import_react61.useMemo)(() => timelineTicks(range, scale, timeZone, weekStartsOn), [range.start, range.end, scale, timeZone, weekStartsOn]);
|
|
10648
|
+
const laneLayouts = (0, import_react61.useMemo)(
|
|
9795
10649
|
() => lanes.map((lane) => ({ lane, placed: layoutLane(items.filter((item) => item.laneId === lane.id), range) })),
|
|
9796
10650
|
[lanes, items, range.start, range.end]
|
|
9797
10651
|
// eslint-disable-line react-hooks/exhaustive-deps
|
|
9798
10652
|
);
|
|
9799
|
-
const ordered = (0,
|
|
9800
|
-
const [activeId, setActiveId] = (0,
|
|
10653
|
+
const ordered = (0, import_react61.useMemo)(() => laneLayouts.flatMap((l) => l.placed.map((p) => p.item.id)), [laneLayouts]);
|
|
10654
|
+
const [activeId, setActiveId] = (0, import_react61.useState)();
|
|
9801
10655
|
const focusId = activeId && ordered.includes(activeId) ? activeId : ordered[0];
|
|
9802
|
-
const [drag, setDrag] = (0,
|
|
9803
|
-
const [announcement, setAnnouncement] = (0,
|
|
9804
|
-
const rootRef = (0,
|
|
10656
|
+
const [drag, setDrag] = (0, import_react61.useState)(null);
|
|
10657
|
+
const [announcement, setAnnouncement] = (0, import_react61.useState)("");
|
|
10658
|
+
const rootRef = (0, import_react61.useRef)(null);
|
|
9805
10659
|
const fmtInstant = (instant) => formatInstantProp?.(instant) ?? new Intl.DateTimeFormat(locale, { timeZone, dateStyle: "medium", timeStyle: "short" }).format(new Date(instant));
|
|
9806
10660
|
const fmtTick = (at) => formatTick?.(new Date(at), scale) ?? new Intl.DateTimeFormat(locale, { timeZone, ...TICK_FORMAT[scale] }).format(new Date(at));
|
|
9807
10661
|
const movable = (item) => !!onMoveItem && item.movable !== false;
|
|
@@ -9872,17 +10726,17 @@ function SchedulingTimeline({
|
|
|
9872
10726
|
const trackStyle = { minWidth: `calc(${Math.max(ticks.length - 1, 1)} * ${tickWidth ?? TICK_WIDTH[scale]})` };
|
|
9873
10727
|
const band = (o, showLabel) => {
|
|
9874
10728
|
const pos = placeSpan(o, range);
|
|
9875
|
-
return pos && /* @__PURE__ */ (0,
|
|
9876
|
-
};
|
|
9877
|
-
return /* @__PURE__ */ (0,
|
|
9878
|
-
loading ? /* @__PURE__ */ (0,
|
|
9879
|
-
/* @__PURE__ */ (0,
|
|
9880
|
-
onRetry && /* @__PURE__ */ (0,
|
|
9881
|
-
] }) : /* @__PURE__ */ (0,
|
|
9882
|
-
(overlays.length > 0 || markers.length > 0) && /* @__PURE__ */ (0,
|
|
9883
|
-
/* @__PURE__ */ (0,
|
|
9884
|
-
/* @__PURE__ */ (0,
|
|
9885
|
-
overlays.map((o) => /* @__PURE__ */ (0,
|
|
10729
|
+
return pos && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "uix-scheduling-timeline__overlay", "data-kind": o.kind, style: { left: `${pos.left}%`, width: `${pos.width}%` }, children: showLabel && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "uix-scheduling-timeline__overlay-label", children: o.label }) }, o.id);
|
|
10730
|
+
};
|
|
10731
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("section", { ref: rootRef, className: cx("uix-scheduling-timeline", className), "aria-label": fillLabel(labels.region, { timeZone }), children: [
|
|
10732
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", { className: "uix-scheduling-timeline__state", role: "status", children: labels.loading }) : error ? /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "uix-scheduling-timeline__state", role: "alert", children: [
|
|
10733
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("p", { children: error }),
|
|
10734
|
+
onRetry && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: onRetry, children: labels.retry })
|
|
10735
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)(import_jsx_runtime87.Fragment, { children: [
|
|
10736
|
+
(overlays.length > 0 || markers.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "uix-visually-hidden", children: [
|
|
10737
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("p", { id: `${id}-windows`, children: labels.windows }),
|
|
10738
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("ul", { "aria-labelledby": `${id}-windows`, children: [
|
|
10739
|
+
overlays.map((o) => /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("li", { children: [
|
|
9886
10740
|
labels.overlays[o.kind],
|
|
9887
10741
|
": ",
|
|
9888
10742
|
o.label,
|
|
@@ -9891,40 +10745,40 @@ function SchedulingTimeline({
|
|
|
9891
10745
|
" \u2013 ",
|
|
9892
10746
|
fmtInstant(o.end)
|
|
9893
10747
|
] }, o.id)),
|
|
9894
|
-
markers.map((m) => /* @__PURE__ */ (0,
|
|
10748
|
+
markers.map((m) => /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("li", { children: [
|
|
9895
10749
|
m.label,
|
|
9896
10750
|
", ",
|
|
9897
10751
|
fmtInstant(m.at)
|
|
9898
10752
|
] }, m.id))
|
|
9899
10753
|
] })
|
|
9900
10754
|
] }),
|
|
9901
|
-
/* @__PURE__ */ (0,
|
|
9902
|
-
/* @__PURE__ */ (0,
|
|
9903
|
-
/* @__PURE__ */ (0,
|
|
9904
|
-
/* @__PURE__ */ (0,
|
|
10755
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", { className: "uix-scheduling-timeline__scroller", children: /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "uix-scheduling-timeline__grid", children: [
|
|
10756
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "uix-scheduling-timeline__row uix-scheduling-timeline__row--axis", "aria-hidden": "true", children: [
|
|
10757
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", { className: "uix-scheduling-timeline__lane-label", children: labels.lanes }),
|
|
10758
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", { className: "uix-scheduling-timeline__track uix-scheduling-timeline__axis", style: trackStyle, children: ticks.map((tick) => /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "uix-scheduling-timeline__tick", "data-major": tick.major || void 0, style: { left: `${tick.offset}%` }, children: tick.offset < 100 && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "uix-scheduling-timeline__tick-label", children: fmtTick(tick.at) }) }, tick.at)) })
|
|
9905
10759
|
] }),
|
|
9906
10760
|
laneLayouts.map(({ lane, placed }, laneIndex) => {
|
|
9907
10761
|
const rows = placed.reduce((max, p) => Math.max(max, p.row + 1), 1);
|
|
9908
10762
|
const laneLabelId = `${id}-lane-${laneIndex}`;
|
|
9909
|
-
return /* @__PURE__ */ (0,
|
|
9910
|
-
/* @__PURE__ */ (0,
|
|
9911
|
-
/* @__PURE__ */ (0,
|
|
9912
|
-
lane.meta != null && /* @__PURE__ */ (0,
|
|
10763
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "uix-scheduling-timeline__row", style: { "--uix-timeline-rows": rows }, children: [
|
|
10764
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "uix-scheduling-timeline__lane-label", id: laneLabelId, children: [
|
|
10765
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "uix-scheduling-timeline__lane-name", children: lane.label }),
|
|
10766
|
+
lane.meta != null && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "uix-scheduling-timeline__lane-meta", children: lane.meta })
|
|
9913
10767
|
] }),
|
|
9914
|
-
/* @__PURE__ */ (0,
|
|
9915
|
-
ticks.map((tick) => /* @__PURE__ */ (0,
|
|
9916
|
-
/* @__PURE__ */ (0,
|
|
9917
|
-
nowPos && /* @__PURE__ */ (0,
|
|
10768
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "uix-scheduling-timeline__track", style: trackStyle, children: [
|
|
10769
|
+
ticks.map((tick) => /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "uix-scheduling-timeline__gridline", "data-major": tick.major || void 0, style: { left: `${tick.offset}%` }, "aria-hidden": "true" }, tick.at)),
|
|
10770
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { "aria-hidden": "true", children: overlaysFor(lane.id).map((o) => band(o, laneIndex === 0 || !!o.laneId)) }),
|
|
10771
|
+
nowPos && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "uix-scheduling-timeline__now", style: { left: `${nowPos.left}%` }, "aria-hidden": "true", children: laneIndex === 0 && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "uix-scheduling-timeline__now-label", children: labels.now }) }),
|
|
9918
10772
|
markersFor(lane.id).map((m) => {
|
|
9919
10773
|
const pos = placeSpan({ start: m.at, end: m.at }, range);
|
|
9920
|
-
return pos && /* @__PURE__ */ (0,
|
|
10774
|
+
return pos && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "uix-scheduling-timeline__marker", style: { left: `${pos.left}%` }, title: m.label, "aria-hidden": "true" }, m.id);
|
|
9921
10775
|
}),
|
|
9922
|
-
/* @__PURE__ */ (0,
|
|
10776
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("ul", { className: "uix-scheduling-timeline__items", "aria-labelledby": laneLabelId, children: placed.map((p, index) => {
|
|
9923
10777
|
const item = p.item;
|
|
9924
10778
|
const state = item.state ?? "scheduled";
|
|
9925
10779
|
const dragging = drag?.id === item.id && drag.moved;
|
|
9926
10780
|
const shown = dragging && drag ? placeSpan(shiftSpan(item, drag.delta, "move", step), range) ?? p : p;
|
|
9927
|
-
return /* @__PURE__ */ (0,
|
|
10781
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("li", { className: "uix-scheduling-timeline__slot", style: { left: `${shown.left}%`, width: `${shown.width}%`, "--uix-timeline-row": p.row }, children: /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)(
|
|
9928
10782
|
"button",
|
|
9929
10783
|
{
|
|
9930
10784
|
type: "button",
|
|
@@ -9951,8 +10805,8 @@ function SchedulingTimeline({
|
|
|
9951
10805
|
onSelectItem?.(item);
|
|
9952
10806
|
},
|
|
9953
10807
|
children: [
|
|
9954
|
-
/* @__PURE__ */ (0,
|
|
9955
|
-
item.meta && /* @__PURE__ */ (0,
|
|
10808
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "uix-scheduling-timeline__item-title", children: renderItem?.(item) ?? item.title }),
|
|
10809
|
+
item.meta && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "uix-scheduling-timeline__item-meta", children: item.meta })
|
|
9956
10810
|
]
|
|
9957
10811
|
}
|
|
9958
10812
|
) }, item.id);
|
|
@@ -9961,16 +10815,16 @@ function SchedulingTimeline({
|
|
|
9961
10815
|
] }, lane.id);
|
|
9962
10816
|
})
|
|
9963
10817
|
] }) }),
|
|
9964
|
-
ordered.length === 0 && /* @__PURE__ */ (0,
|
|
10818
|
+
ordered.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("p", { className: "uix-scheduling-timeline__empty", children: labels.empty })
|
|
9965
10819
|
] }),
|
|
9966
|
-
onMoveItem && /* @__PURE__ */ (0,
|
|
9967
|
-
/* @__PURE__ */ (0,
|
|
10820
|
+
onMoveItem && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { id: `${id}-hint`, className: "uix-visually-hidden", children: labels.moveHint }),
|
|
10821
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "uix-visually-hidden", role: "status", "aria-live": "polite", children: announcement })
|
|
9968
10822
|
] });
|
|
9969
10823
|
}
|
|
9970
10824
|
|
|
9971
10825
|
// src/components/DateRangePicker.tsx
|
|
9972
|
-
var
|
|
9973
|
-
var
|
|
10826
|
+
var import_react62 = require("react");
|
|
10827
|
+
var import_jsx_runtime88 = require("react/jsx-runtime");
|
|
9974
10828
|
var DEFAULT_DATE_RANGE_PICKER_LABELS = {
|
|
9975
10829
|
previous: "Previous",
|
|
9976
10830
|
previousMonth: "Show previous month",
|
|
@@ -10008,29 +10862,29 @@ function DateRangePicker({
|
|
|
10008
10862
|
labels: labelOverrides,
|
|
10009
10863
|
today
|
|
10010
10864
|
}) {
|
|
10011
|
-
const id = (0,
|
|
10865
|
+
const id = (0, import_react62.useId)();
|
|
10012
10866
|
const uixLabels = useUixLabels();
|
|
10013
10867
|
const labels = { ...DEFAULT_DATE_RANGE_PICKER_LABELS, ...uixLabels.dateRangePicker, ...labelOverrides };
|
|
10014
|
-
const weekdays = (0,
|
|
10015
|
-
const [internalMonth, setInternalMonth] = (0,
|
|
10868
|
+
const weekdays = (0, import_react62.useMemo)(() => weekdayNames(locale), [locale]);
|
|
10869
|
+
const [internalMonth, setInternalMonth] = (0, import_react62.useState)(() => startOfMonth(controlledMonth ?? value.start ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)));
|
|
10016
10870
|
const visibleMonth = startOfMonth(controlledMonth ?? internalMonth);
|
|
10017
|
-
const [activeDate, setActiveDate] = (0,
|
|
10018
|
-
const rootRef = (0,
|
|
10019
|
-
const pendingFocus = (0,
|
|
10871
|
+
const [activeDate, setActiveDate] = (0, import_react62.useState)(value.end ?? value.start ?? visibleMonth);
|
|
10872
|
+
const rootRef = (0, import_react62.useRef)(null);
|
|
10873
|
+
const pendingFocus = (0, import_react62.useRef)(false);
|
|
10020
10874
|
const count2 = Math.max(1, Math.min(3, months));
|
|
10021
|
-
const calendars = (0,
|
|
10875
|
+
const calendars = (0, import_react62.useMemo)(() => Array.from({ length: count2 }, (_, index) => {
|
|
10022
10876
|
const month = startOfMonth(addCalendarMonths(visibleMonth, index));
|
|
10023
10877
|
return { month, days: buildMonthGrid(month).filter((day) => day.inMonth) };
|
|
10024
10878
|
}), [visibleMonth, count2]);
|
|
10025
10879
|
const todayDate = today === void 0 ? localDateKey() : today;
|
|
10026
10880
|
const rangeInvalid = invalid || !!value.start && !!value.end && value.start > value.end;
|
|
10027
|
-
(0,
|
|
10881
|
+
(0, import_react62.useEffect)(() => {
|
|
10028
10882
|
const first = calendars[0]?.days[0]?.date;
|
|
10029
10883
|
const finalDays = calendars[calendars.length - 1]?.days;
|
|
10030
10884
|
const last = finalDays?.[finalDays.length - 1]?.date;
|
|
10031
10885
|
if (first && last && (activeDate < first || activeDate > last)) setActiveDate(first);
|
|
10032
10886
|
}, [activeDate, calendars]);
|
|
10033
|
-
(0,
|
|
10887
|
+
(0, import_react62.useEffect)(() => {
|
|
10034
10888
|
if (!pendingFocus.current) return;
|
|
10035
10889
|
rootRef.current?.querySelector(`[data-date="${activeDate}"]`)?.focus();
|
|
10036
10890
|
pendingFocus.current = false;
|
|
@@ -10068,23 +10922,23 @@ function DateRangePicker({
|
|
|
10068
10922
|
}
|
|
10069
10923
|
};
|
|
10070
10924
|
const announcement = !value.start ? labels.noneSelected : !value.end ? labels.startSelected.replace("{start}", dateLabel(value.start, locale)) : labels.rangeSelected.replace("{start}", dateLabel(value.start, locale)).replace("{end}", dateLabel(value.end, locale));
|
|
10071
|
-
return /* @__PURE__ */ (0,
|
|
10072
|
-
/* @__PURE__ */ (0,
|
|
10073
|
-
/* @__PURE__ */ (0,
|
|
10074
|
-
/* @__PURE__ */ (0,
|
|
10075
|
-
/* @__PURE__ */ (0,
|
|
10076
|
-
/* @__PURE__ */ (0,
|
|
10925
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("section", { className: cx("uix-date-range-picker", rangeInvalid && "uix-date-range-picker--invalid", className), "aria-labelledby": `${id}-label`, children: [
|
|
10926
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", { className: "uix-date-range-picker__header", children: [
|
|
10927
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)("h3", { id: `${id}-label`, children: label }),
|
|
10928
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", { children: [
|
|
10929
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: () => setMonth(addCalendarMonths(visibleMonth, -1)), "aria-label": labels.previousMonth, children: labels.previous }),
|
|
10930
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: () => setMonth(addCalendarMonths(visibleMonth, 1)), "aria-label": labels.nextMonth, children: labels.next })
|
|
10077
10931
|
] })
|
|
10078
10932
|
] }),
|
|
10079
|
-
/* @__PURE__ */ (0,
|
|
10080
|
-
/* @__PURE__ */ (0,
|
|
10081
|
-
/* @__PURE__ */ (0,
|
|
10082
|
-
/* @__PURE__ */ (0,
|
|
10083
|
-
Array.from({ length: ((/* @__PURE__ */ new Date(`${month}T00:00:00Z`)).getUTCDay() + 6) % 7 }, (_, index) => /* @__PURE__ */ (0,
|
|
10933
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)("div", { ref: rootRef, className: "uix-date-range-picker__months", children: calendars.map(({ month, days }) => /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", { className: "uix-date-range-picker__month", children: [
|
|
10934
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)("h4", { children: monthLabel(month, locale) }),
|
|
10935
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)("div", { className: "uix-date-range-picker__weekdays", "aria-hidden": "true", children: weekdays.map((day, index) => /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", { children: day }, index)) }),
|
|
10936
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", { className: "uix-date-range-picker__grid", role: "group", "aria-label": monthLabel(month, locale), children: [
|
|
10937
|
+
Array.from({ length: ((/* @__PURE__ */ new Date(`${month}T00:00:00Z`)).getUTCDay() + 6) % 7 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", { "aria-hidden": "true" }, `blank-${index}`)),
|
|
10084
10938
|
days.map((day) => {
|
|
10085
10939
|
const unavailable = disabled || isDateUnavailable(day.date, { min, max, isDisabled: isDateDisabled });
|
|
10086
10940
|
const edge = day.date === value.start ? "start" : day.date === value.end ? "end" : void 0;
|
|
10087
|
-
return /* @__PURE__ */ (0,
|
|
10941
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
10088
10942
|
"button",
|
|
10089
10943
|
{
|
|
10090
10944
|
type: "button",
|
|
@@ -10106,13 +10960,13 @@ function DateRangePicker({
|
|
|
10106
10960
|
})
|
|
10107
10961
|
] })
|
|
10108
10962
|
] }, month)) }),
|
|
10109
|
-
/* @__PURE__ */ (0,
|
|
10110
|
-
rangeInvalid && /* @__PURE__ */ (0,
|
|
10963
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)("p", { className: "uix-date-range-picker__selection", "aria-live": "polite", children: announcement }),
|
|
10964
|
+
rangeInvalid && /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("p", { className: "uix-field__error", role: "alert", children: invalidMessage })
|
|
10111
10965
|
] });
|
|
10112
10966
|
}
|
|
10113
10967
|
|
|
10114
10968
|
// src/components/RelationshipGraph.tsx
|
|
10115
|
-
var
|
|
10969
|
+
var import_react64 = require("react");
|
|
10116
10970
|
|
|
10117
10971
|
// src/relationship-graph-model.ts
|
|
10118
10972
|
function boundRelationshipGraph(nodes, edges, maxNodes = 40) {
|
|
@@ -10593,10 +11447,10 @@ function layeredNeighbor(layout, currentId, key) {
|
|
|
10593
11447
|
}
|
|
10594
11448
|
|
|
10595
11449
|
// src/components/RelationshipGraphLayered.tsx
|
|
10596
|
-
var
|
|
11450
|
+
var import_react63 = require("react");
|
|
10597
11451
|
|
|
10598
11452
|
// src/components/RelationshipGraphList.tsx
|
|
10599
|
-
var
|
|
11453
|
+
var import_jsx_runtime89 = require("react/jsx-runtime");
|
|
10600
11454
|
function EquivalentRelationshipList({
|
|
10601
11455
|
nodes,
|
|
10602
11456
|
edges,
|
|
@@ -10607,19 +11461,19 @@ function EquivalentRelationshipList({
|
|
|
10607
11461
|
onOpenDetails
|
|
10608
11462
|
}) {
|
|
10609
11463
|
const labelById = new Map(nodes.map((node) => [node.id, node.label]));
|
|
10610
|
-
return /* @__PURE__ */ (0,
|
|
10611
|
-
/* @__PURE__ */ (0,
|
|
10612
|
-
/* @__PURE__ */ (0,
|
|
11464
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "uix-relationship-graph__list", role: "region", "aria-label": labels.list, children: [
|
|
11465
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("h3", { children: labels.listHeading }),
|
|
11466
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("ul", { children: nodes.map((node) => {
|
|
10613
11467
|
const neighbors = relationshipNeighbors(node.id, edges).map((id) => labelById.get(id) ?? id);
|
|
10614
|
-
return /* @__PURE__ */ (0,
|
|
10615
|
-
/* @__PURE__ */ (0,
|
|
10616
|
-
/* @__PURE__ */ (0,
|
|
10617
|
-
node.type && /* @__PURE__ */ (0,
|
|
10618
|
-
/* @__PURE__ */ (0,
|
|
11468
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("li", { "data-selected": selectedId === node.id || void 0, children: [
|
|
11469
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("button", { type: "button", onClick: () => onSelect(node.id), "aria-pressed": selectedId === node.id, children: [
|
|
11470
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("strong", { children: node.label }),
|
|
11471
|
+
node.type && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { children: node.type }),
|
|
11472
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { children: neighbors.length ? labels.connectedTo(neighbors.join(", ")) : labels.noConnections })
|
|
10619
11473
|
] }),
|
|
10620
|
-
/* @__PURE__ */ (0,
|
|
10621
|
-
onExpandNeighbors && /* @__PURE__ */ (0,
|
|
10622
|
-
onOpenDetails && /* @__PURE__ */ (0,
|
|
11474
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("span", { className: "uix-relationship-graph__list-actions", children: [
|
|
11475
|
+
onExpandNeighbors && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("button", { type: "button", onClick: () => onExpandNeighbors(node), children: labels.expandNeighbors }),
|
|
11476
|
+
onOpenDetails && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("button", { type: "button", onClick: () => onOpenDetails(node), children: labels.openDetails })
|
|
10623
11477
|
] })
|
|
10624
11478
|
] }, node.id);
|
|
10625
11479
|
}) })
|
|
@@ -10627,8 +11481,8 @@ function EquivalentRelationshipList({
|
|
|
10627
11481
|
}
|
|
10628
11482
|
|
|
10629
11483
|
// src/components/RelationshipGraphLayered.tsx
|
|
10630
|
-
var
|
|
10631
|
-
var
|
|
11484
|
+
var import_jsx_runtime90 = require("react/jsx-runtime");
|
|
11485
|
+
var EMPTY_IDS2 = /* @__PURE__ */ new Set();
|
|
10632
11486
|
var MIN_ZOOM = 0.4;
|
|
10633
11487
|
var MAX_ZOOM = 1.5;
|
|
10634
11488
|
var READABLE_ZOOM = 0.75;
|
|
@@ -10659,10 +11513,10 @@ function LayeredRelationshipGraph({
|
|
|
10659
11513
|
onOpenDetails,
|
|
10660
11514
|
maxNodes = 400,
|
|
10661
11515
|
density = "standard",
|
|
10662
|
-
highlightedNodeIds =
|
|
10663
|
-
conflictedNodeIds =
|
|
10664
|
-
highlightedEdgeIds =
|
|
10665
|
-
conflictedEdgeIds =
|
|
11516
|
+
highlightedNodeIds = EMPTY_IDS2,
|
|
11517
|
+
conflictedNodeIds = EMPTY_IDS2,
|
|
11518
|
+
highlightedEdgeIds = EMPTY_IDS2,
|
|
11519
|
+
conflictedEdgeIds = EMPTY_IDS2,
|
|
10666
11520
|
legend = [],
|
|
10667
11521
|
className,
|
|
10668
11522
|
labels,
|
|
@@ -10673,18 +11527,18 @@ function LayeredRelationshipGraph({
|
|
|
10673
11527
|
clusterThreshold,
|
|
10674
11528
|
expandedClusterIds,
|
|
10675
11529
|
onToggleCluster,
|
|
10676
|
-
dimmedNodeIds =
|
|
11530
|
+
dimmedNodeIds = EMPTY_IDS2,
|
|
10677
11531
|
edgeLabels = "auto",
|
|
10678
11532
|
showList = true,
|
|
10679
11533
|
height,
|
|
10680
11534
|
focusId,
|
|
10681
11535
|
onFocusChange
|
|
10682
11536
|
}) {
|
|
10683
|
-
const hintId = (0,
|
|
10684
|
-
const bounded = (0,
|
|
10685
|
-
const [localExpanded, setLocalExpanded] = (0,
|
|
11537
|
+
const hintId = (0, import_react63.useId)();
|
|
11538
|
+
const bounded = (0, import_react63.useMemo)(() => boundRelationshipGraph(nodes, edges, maxNodes), [nodes, edges, maxNodes]);
|
|
11539
|
+
const [localExpanded, setLocalExpanded] = (0, import_react63.useState)(EMPTY_IDS2);
|
|
10686
11540
|
const expanded = expandedClusterIds ?? localExpanded;
|
|
10687
|
-
const layout = (0,
|
|
11541
|
+
const layout = (0, import_react63.useMemo)(
|
|
10688
11542
|
() => layoutLayeredGraph(bounded.nodes, bounded.edges, {
|
|
10689
11543
|
...rootId !== void 0 ? { rootId } : {},
|
|
10690
11544
|
...clusterThreshold !== void 0 ? { clusterThreshold } : {},
|
|
@@ -10693,29 +11547,29 @@ function LayeredRelationshipGraph({
|
|
|
10693
11547
|
}),
|
|
10694
11548
|
[bounded, rootId, clusterThreshold, expanded, density]
|
|
10695
11549
|
);
|
|
10696
|
-
const itemById = (0,
|
|
10697
|
-
const viewportRef = (0,
|
|
10698
|
-
const itemRefs = (0,
|
|
10699
|
-
const [size, setSize] = (0,
|
|
10700
|
-
const [view, setView] = (0,
|
|
10701
|
-
const [animate, setAnimate] = (0,
|
|
10702
|
-
const [localFocus, setLocalFocus] = (0,
|
|
10703
|
-
const [hoverId, setHoverId] = (0,
|
|
10704
|
-
const viewRef = (0,
|
|
11550
|
+
const itemById = (0, import_react63.useMemo)(() => new Map(layout.items.map((item) => [item.id, item])), [layout]);
|
|
11551
|
+
const viewportRef = (0, import_react63.useRef)(null);
|
|
11552
|
+
const itemRefs = (0, import_react63.useRef)(/* @__PURE__ */ new Map());
|
|
11553
|
+
const [size, setSize] = (0, import_react63.useState)({ width: 0, height: 0 });
|
|
11554
|
+
const [view, setView] = (0, import_react63.useState)({ x: 0, y: 0, zoom: 1 });
|
|
11555
|
+
const [animate, setAnimate] = (0, import_react63.useState)(false);
|
|
11556
|
+
const [localFocus, setLocalFocus] = (0, import_react63.useState)(void 0);
|
|
11557
|
+
const [hoverId, setHoverId] = (0, import_react63.useState)(void 0);
|
|
11558
|
+
const viewRef = (0, import_react63.useRef)(view);
|
|
10705
11559
|
viewRef.current = view;
|
|
10706
|
-
const layoutRef = (0,
|
|
11560
|
+
const layoutRef = (0, import_react63.useRef)(layout);
|
|
10707
11561
|
layoutRef.current = layout;
|
|
10708
|
-
const pendingFocus = (0,
|
|
10709
|
-
const initialisedFor = (0,
|
|
11562
|
+
const pendingFocus = (0, import_react63.useRef)(void 0);
|
|
11563
|
+
const initialisedFor = (0, import_react63.useRef)(void 0);
|
|
10710
11564
|
const rootItemId = layout.rootId !== void 0 ? layout.itemOf[layout.rootId] : layout.items[0]?.id;
|
|
10711
11565
|
const requestedFocus = focusId !== void 0 ? layout.itemOf[focusId] ?? focusId : localFocus;
|
|
10712
11566
|
const focusedId = requestedFocus !== void 0 && itemById.has(requestedFocus) ? requestedFocus : rootItemId;
|
|
10713
11567
|
const selectedItemId = selectedId !== void 0 ? layout.itemOf[selectedId] : void 0;
|
|
10714
|
-
const activeIds = (0,
|
|
11568
|
+
const activeIds = (0, import_react63.useMemo)(
|
|
10715
11569
|
() => new Set([hoverId, selectedItemId].filter((id) => id !== void 0)),
|
|
10716
11570
|
[hoverId, selectedItemId]
|
|
10717
11571
|
);
|
|
10718
|
-
(0,
|
|
11572
|
+
(0, import_react63.useEffect)(() => {
|
|
10719
11573
|
const element = viewportRef.current;
|
|
10720
11574
|
if (!element) return;
|
|
10721
11575
|
const measure = () => setSize({ width: element.clientWidth, height: element.clientHeight });
|
|
@@ -10725,18 +11579,18 @@ function LayeredRelationshipGraph({
|
|
|
10725
11579
|
observer.observe(element);
|
|
10726
11580
|
return () => observer.disconnect();
|
|
10727
11581
|
}, []);
|
|
10728
|
-
(0,
|
|
11582
|
+
(0, import_react63.useEffect)(() => {
|
|
10729
11583
|
if (size.width === 0) return;
|
|
10730
11584
|
const key = `${layout.rootId ?? ""}`;
|
|
10731
11585
|
if (initialisedFor.current === key) return;
|
|
10732
11586
|
initialisedFor.current = key;
|
|
10733
11587
|
setView(initialView(layout, size));
|
|
10734
11588
|
}, [layout, size]);
|
|
10735
|
-
const moveView = (0,
|
|
11589
|
+
const moveView = (0, import_react63.useCallback)((next, smooth) => {
|
|
10736
11590
|
setAnimate(smooth);
|
|
10737
11591
|
setView(next);
|
|
10738
11592
|
}, []);
|
|
10739
|
-
const ensureVisible = (0,
|
|
11593
|
+
const ensureVisible = (0, import_react63.useCallback)((id, smooth) => {
|
|
10740
11594
|
const element = viewportRef.current;
|
|
10741
11595
|
const item = layoutRef.current.items.find((candidate) => candidate.id === id);
|
|
10742
11596
|
if (!element || !item) return;
|
|
@@ -10755,7 +11609,7 @@ function LayeredRelationshipGraph({
|
|
|
10755
11609
|
else if (bottom > heightPx - FOCUS_MARGIN) nextY -= bottom - (heightPx - FOCUS_MARGIN);
|
|
10756
11610
|
if (nextX !== x || nextY !== y) moveView({ x: nextX, y: nextY, zoom }, smooth);
|
|
10757
11611
|
}, [moveView]);
|
|
10758
|
-
const focusItem = (0,
|
|
11612
|
+
const focusItem = (0, import_react63.useCallback)((id) => {
|
|
10759
11613
|
setLocalFocus(id);
|
|
10760
11614
|
onFocusChange?.(id);
|
|
10761
11615
|
requestAnimationFrame(() => {
|
|
@@ -10763,7 +11617,7 @@ function LayeredRelationshipGraph({
|
|
|
10763
11617
|
ensureVisible(id, true);
|
|
10764
11618
|
});
|
|
10765
11619
|
}, [ensureVisible, onFocusChange]);
|
|
10766
|
-
(0,
|
|
11620
|
+
(0, import_react63.useEffect)(() => {
|
|
10767
11621
|
const wanted = pendingFocus.current;
|
|
10768
11622
|
if (wanted !== void 0 && itemById.has(wanted)) {
|
|
10769
11623
|
pendingFocus.current = void 0;
|
|
@@ -10773,8 +11627,8 @@ function LayeredRelationshipGraph({
|
|
|
10773
11627
|
const controlledTarget = focusId !== void 0 ? layout.itemOf[focusId] ?? focusId : void 0;
|
|
10774
11628
|
const controlledPresent = controlledTarget !== void 0 && itemById.has(controlledTarget);
|
|
10775
11629
|
const controlledKey = `${controlledTarget ?? ""}|${controlledPresent}`;
|
|
10776
|
-
const lastControlledKey = (0,
|
|
10777
|
-
(0,
|
|
11630
|
+
const lastControlledKey = (0, import_react63.useRef)(controlledKey);
|
|
11631
|
+
(0, import_react63.useEffect)(() => {
|
|
10778
11632
|
if (lastControlledKey.current === controlledKey) return;
|
|
10779
11633
|
lastControlledKey.current = controlledKey;
|
|
10780
11634
|
if (!controlledPresent || controlledTarget === void 0) return;
|
|
@@ -10783,7 +11637,7 @@ function LayeredRelationshipGraph({
|
|
|
10783
11637
|
ensureVisible(controlledTarget, true);
|
|
10784
11638
|
});
|
|
10785
11639
|
}, [controlledKey, controlledTarget, controlledPresent, ensureVisible]);
|
|
10786
|
-
(0,
|
|
11640
|
+
(0, import_react63.useEffect)(() => {
|
|
10787
11641
|
const element = viewportRef.current;
|
|
10788
11642
|
if (!element) return;
|
|
10789
11643
|
const onWheel = (event) => {
|
|
@@ -10801,8 +11655,8 @@ function LayeredRelationshipGraph({
|
|
|
10801
11655
|
element.addEventListener("wheel", onWheel, { passive: false });
|
|
10802
11656
|
return () => element.removeEventListener("wheel", onWheel);
|
|
10803
11657
|
}, []);
|
|
10804
|
-
const pointers = (0,
|
|
10805
|
-
const pinchDistance = (0,
|
|
11658
|
+
const pointers = (0, import_react63.useRef)(/* @__PURE__ */ new Map());
|
|
11659
|
+
const pinchDistance = (0, import_react63.useRef)(void 0);
|
|
10806
11660
|
const onPointerDown = (event) => {
|
|
10807
11661
|
if (event.target.closest("button")) return;
|
|
10808
11662
|
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
@@ -10900,21 +11754,21 @@ function LayeredRelationshipGraph({
|
|
|
10900
11754
|
height: layout.height,
|
|
10901
11755
|
transform: `translate(${view.x}px, ${view.y}px) scale(${view.zoom})`
|
|
10902
11756
|
};
|
|
10903
|
-
return /* @__PURE__ */ (0,
|
|
10904
|
-
/* @__PURE__ */ (0,
|
|
10905
|
-
/* @__PURE__ */ (0,
|
|
10906
|
-
/* @__PURE__ */ (0,
|
|
10907
|
-
/* @__PURE__ */ (0,
|
|
10908
|
-
/* @__PURE__ */ (0,
|
|
10909
|
-
/* @__PURE__ */ (0,
|
|
10910
|
-
/* @__PURE__ */ (0,
|
|
10911
|
-
/* @__PURE__ */ (0,
|
|
10912
|
-
/* @__PURE__ */ (0,
|
|
10913
|
-
/* @__PURE__ */ (0,
|
|
11757
|
+
return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("section", { className: cx("uix-relationship-graph", "uix-relationship-graph--layered", density === "compact" && "uix-relationship-graph--compact", className), "aria-label": labels.graph, children: [
|
|
11758
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: "uix-relationship-graph__toolbar", role: "group", "aria-label": labels.controls, children: [
|
|
11759
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("button", { type: "button", onClick: () => zoomBy(ZOOM_STEP), disabled: view.zoom >= MAX_ZOOM, children: labels.zoomIn }),
|
|
11760
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("button", { type: "button", onClick: () => zoomBy(1 / ZOOM_STEP), disabled: view.zoom <= MIN_ZOOM, children: labels.zoomOut }),
|
|
11761
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("button", { type: "button", onClick: () => moveView(fitView(layout, size), true), children: labels.fit }),
|
|
11762
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("button", { type: "button", onClick: () => moveView(initialView(layout, size), true), children: labels.reset }),
|
|
11763
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("button", { type: "button", onClick: () => panBy(PAN_STEP, 0), "aria-label": labels.panLeft, children: labels.left }),
|
|
11764
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("button", { type: "button", onClick: () => panBy(0, PAN_STEP), "aria-label": labels.panUp, children: labels.up }),
|
|
11765
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("button", { type: "button", onClick: () => panBy(0, -PAN_STEP), "aria-label": labels.panDown, children: labels.down }),
|
|
11766
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("button", { type: "button", onClick: () => panBy(-PAN_STEP, 0), "aria-label": labels.panRight, children: labels.right }),
|
|
11767
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { "aria-live": "polite", children: labels.zoomLevel(Math.round(view.zoom * 100)) })
|
|
10914
11768
|
] }),
|
|
10915
|
-
bounded.omittedNodeCount > 0 && /* @__PURE__ */ (0,
|
|
10916
|
-
/* @__PURE__ */ (0,
|
|
10917
|
-
/* @__PURE__ */ (0,
|
|
11769
|
+
bounded.omittedNodeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("p", { className: "uix-relationship-graph__bounded", role: "status", children: labels.bounded(bounded.nodes.length, bounded.omittedNodeCount) }),
|
|
11770
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("p", { id: hintId, className: "uix-visually-hidden", children: labels.keyboardHint }),
|
|
11771
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
10918
11772
|
"div",
|
|
10919
11773
|
{
|
|
10920
11774
|
ref: viewportRef,
|
|
@@ -10924,11 +11778,11 @@ function LayeredRelationshipGraph({
|
|
|
10924
11778
|
onPointerMove,
|
|
10925
11779
|
onPointerUp: onPointerEnd,
|
|
10926
11780
|
onPointerCancel: onPointerEnd,
|
|
10927
|
-
children: /* @__PURE__ */ (0,
|
|
10928
|
-
/* @__PURE__ */ (0,
|
|
11781
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: "uix-relationship-graph__stage", style: stageStyle, "data-animate": animate || void 0, onTransitionEnd: () => setAnimate(false), children: [
|
|
11782
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("svg", { className: "uix-relationship-graph__edges", width: layout.width, height: layout.height, "aria-hidden": "true", focusable: "false", children: layout.edges.map((edge) => {
|
|
10929
11783
|
const active = activeIds.has(edge.source) || activeIds.has(edge.target) || edge.edgeIds.some((id) => highlightedEdgeIds.has(id));
|
|
10930
11784
|
const angle = edge.arrowAngle * 180 / Math.PI;
|
|
10931
|
-
return /* @__PURE__ */ (0,
|
|
11785
|
+
return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(
|
|
10932
11786
|
"g",
|
|
10933
11787
|
{
|
|
10934
11788
|
className: "uix-relationship-graph__link",
|
|
@@ -10938,15 +11792,15 @@ function LayeredRelationshipGraph({
|
|
|
10938
11792
|
"data-conflicted": edge.edgeIds.some((id) => conflictedEdgeIds.has(id)) || void 0,
|
|
10939
11793
|
"data-dimmed": dimmedNodeIds.has(edge.source) && dimmedNodeIds.has(edge.target) || void 0,
|
|
10940
11794
|
children: [
|
|
10941
|
-
/* @__PURE__ */ (0,
|
|
10942
|
-
edge.arrow !== "none" && /* @__PURE__ */ (0,
|
|
10943
|
-
showLabel(edge) && /* @__PURE__ */ (0,
|
|
11795
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("path", { d: edge.path }),
|
|
11796
|
+
edge.arrow !== "none" && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("polygon", { points: arrowPoints, transform: `translate(${edge.arrowX} ${edge.arrowY}) rotate(${angle})` }),
|
|
11797
|
+
showLabel(edge) && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("text", { x: edge.labelX, y: edge.labelY, textAnchor: "middle", dominantBaseline: "middle", children: (edge.kind === "cycle" ? [...edge.labelLines, labels.cycle] : edge.labelLines).map((line, index, lines) => /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("tspan", { x: edge.labelX, dy: index === 0 ? `${-(lines.length - 1) * 0.55}em` : "1.1em", children: line }, index)) })
|
|
10944
11798
|
]
|
|
10945
11799
|
},
|
|
10946
11800
|
edge.id
|
|
10947
11801
|
);
|
|
10948
11802
|
}) }),
|
|
10949
|
-
layout.columns.map((column) => /* @__PURE__ */ (0,
|
|
11803
|
+
layout.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
10950
11804
|
"div",
|
|
10951
11805
|
{
|
|
10952
11806
|
className: "uix-relationship-graph__column",
|
|
@@ -10956,17 +11810,17 @@ function LayeredRelationshipGraph({
|
|
|
10956
11810
|
},
|
|
10957
11811
|
column.depth
|
|
10958
11812
|
)),
|
|
10959
|
-
/* @__PURE__ */ (0,
|
|
11813
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("div", { role: "group", "aria-roledescription": labels.roleDescription, "aria-label": labels.graphSummary(bounded.nodes.length, bounded.edges.length), "aria-describedby": hintId, children: layout.items.map((item) => {
|
|
10960
11814
|
const selected = item.id === selectedItemId;
|
|
10961
11815
|
const dimmed = item.node ? dimmedNodeIds.has(item.node.id) : item.cluster.members.every((member) => dimmedNodeIds.has(member.id));
|
|
10962
|
-
const body = item.cluster ? renderCluster?.(item.cluster) ?? /* @__PURE__ */ (0,
|
|
10963
|
-
/* @__PURE__ */ (0,
|
|
10964
|
-
/* @__PURE__ */ (0,
|
|
10965
|
-
] }) : renderNode?.(item.node, { selected, dimmed }) ?? /* @__PURE__ */ (0,
|
|
10966
|
-
/* @__PURE__ */ (0,
|
|
10967
|
-
(item.node.type || item.node.description) && /* @__PURE__ */ (0,
|
|
11816
|
+
const body = item.cluster ? renderCluster?.(item.cluster) ?? /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(import_jsx_runtime90.Fragment, { children: [
|
|
11817
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { className: "uix-relationship-graph__item-label", children: labels.cluster(item.cluster.members.length, item.cluster.type, item.cluster.edgeLabel) }),
|
|
11818
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { className: "uix-relationship-graph__item-meta", children: labels.expandCluster })
|
|
11819
|
+
] }) : renderNode?.(item.node, { selected, dimmed }) ?? /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(import_jsx_runtime90.Fragment, { children: [
|
|
11820
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { className: "uix-relationship-graph__item-label", children: item.node.label }),
|
|
11821
|
+
(item.node.type || item.node.description) && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { className: "uix-relationship-graph__item-meta", children: [item.node.type, item.node.description].filter(Boolean).join(" \xB7 ") })
|
|
10968
11822
|
] });
|
|
10969
|
-
return /* @__PURE__ */ (0,
|
|
11823
|
+
return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(
|
|
10970
11824
|
"button",
|
|
10971
11825
|
{
|
|
10972
11826
|
ref: (element) => {
|
|
@@ -10997,7 +11851,7 @@ function LayeredRelationshipGraph({
|
|
|
10997
11851
|
onPointerLeave: () => setHoverId((current) => current === item.id ? void 0 : current),
|
|
10998
11852
|
children: [
|
|
10999
11853
|
body,
|
|
11000
|
-
item.inCycle && /* @__PURE__ */ (0,
|
|
11854
|
+
item.inCycle && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { className: "uix-relationship-graph__item-flag", "aria-hidden": "true", children: labels.cycle })
|
|
11001
11855
|
]
|
|
11002
11856
|
},
|
|
11003
11857
|
item.id
|
|
@@ -11005,7 +11859,7 @@ function LayeredRelationshipGraph({
|
|
|
11005
11859
|
}) }),
|
|
11006
11860
|
layout.items.filter((item) => item.expandedGroup).map((item) => {
|
|
11007
11861
|
const group = item.expandedGroup;
|
|
11008
|
-
return /* @__PURE__ */ (0,
|
|
11862
|
+
return /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
11009
11863
|
"button",
|
|
11010
11864
|
{
|
|
11011
11865
|
type: "button",
|
|
@@ -11021,8 +11875,8 @@ function LayeredRelationshipGraph({
|
|
|
11021
11875
|
] })
|
|
11022
11876
|
}
|
|
11023
11877
|
),
|
|
11024
|
-
legend.length > 0 && /* @__PURE__ */ (0,
|
|
11025
|
-
showList && /* @__PURE__ */ (0,
|
|
11878
|
+
legend.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("ul", { className: "uix-relationship-graph__legend", "aria-label": labels.legend, children: legend.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("li", { "data-type": entry.id, children: entry.label }, entry.id)) }),
|
|
11879
|
+
showList && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
11026
11880
|
EquivalentRelationshipList,
|
|
11027
11881
|
{
|
|
11028
11882
|
nodes: bounded.nodes,
|
|
@@ -11041,7 +11895,7 @@ function LayeredRelationshipGraph({
|
|
|
11041
11895
|
}
|
|
11042
11896
|
|
|
11043
11897
|
// src/components/RelationshipGraph.tsx
|
|
11044
|
-
var
|
|
11898
|
+
var import_jsx_runtime91 = require("react/jsx-runtime");
|
|
11045
11899
|
var DEFAULT_RELATIONSHIP_GRAPH_LABELS = {
|
|
11046
11900
|
graph: "Relationship graph",
|
|
11047
11901
|
controls: "Graph view controls",
|
|
@@ -11082,7 +11936,7 @@ var DEFAULT_RELATIONSHIP_GRAPH_LABELS = {
|
|
|
11082
11936
|
emptyTitle: "No relationships to display.",
|
|
11083
11937
|
emptyHint: "Adjust the neighborhood or filters to include a node."
|
|
11084
11938
|
};
|
|
11085
|
-
var
|
|
11939
|
+
var EMPTY_IDS3 = /* @__PURE__ */ new Set();
|
|
11086
11940
|
var EMPTY_LEGEND = [];
|
|
11087
11941
|
var RADIAL_SCALE_X = 6;
|
|
11088
11942
|
var RADIAL_SCALE_Y = 4;
|
|
@@ -11103,21 +11957,21 @@ function radialViewBox(nodes) {
|
|
|
11103
11957
|
return `${round(minX)} ${round(minY)} ${width} ${height}`;
|
|
11104
11958
|
}
|
|
11105
11959
|
function RelationshipGraph(props) {
|
|
11106
|
-
const labels = (0,
|
|
11960
|
+
const labels = (0, import_react64.useMemo)(() => ({ ...DEFAULT_RELATIONSHIP_GRAPH_LABELS, ...props.labels }), [props.labels]);
|
|
11107
11961
|
const stateClass = cx("uix-relationship-graph uix-relationship-graph--state", props.className);
|
|
11108
|
-
if (props.loading) return /* @__PURE__ */ (0,
|
|
11962
|
+
if (props.loading) return /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("div", { className: stateClass, role: "status", children: labels.loading });
|
|
11109
11963
|
if (props.error) {
|
|
11110
|
-
return /* @__PURE__ */ (0,
|
|
11111
|
-
/* @__PURE__ */ (0,
|
|
11112
|
-
props.onRetry && /* @__PURE__ */ (0,
|
|
11964
|
+
return /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: stateClass, role: "alert", children: [
|
|
11965
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("p", { children: props.error }),
|
|
11966
|
+
props.onRetry && /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: props.onRetry, children: labels.retry })
|
|
11113
11967
|
] });
|
|
11114
11968
|
}
|
|
11115
|
-
if (props.nodes.length === 0) return /* @__PURE__ */ (0,
|
|
11116
|
-
/* @__PURE__ */ (0,
|
|
11117
|
-
/* @__PURE__ */ (0,
|
|
11969
|
+
if (props.nodes.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: stateClass, children: [
|
|
11970
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("p", { children: labels.emptyTitle }),
|
|
11971
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("p", { children: labels.emptyHint })
|
|
11118
11972
|
] });
|
|
11119
|
-
if (props.layout === "layered") return /* @__PURE__ */ (0,
|
|
11120
|
-
return /* @__PURE__ */ (0,
|
|
11973
|
+
if (props.layout === "layered") return /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(LayeredRelationshipGraph, { ...props, labels });
|
|
11974
|
+
return /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(RadialRelationshipGraph, { ...props, labels });
|
|
11121
11975
|
}
|
|
11122
11976
|
function RadialRelationshipGraph({
|
|
11123
11977
|
nodes,
|
|
@@ -11128,26 +11982,26 @@ function RadialRelationshipGraph({
|
|
|
11128
11982
|
onOpenDetails,
|
|
11129
11983
|
maxNodes = 40,
|
|
11130
11984
|
density = "standard",
|
|
11131
|
-
highlightedNodeIds =
|
|
11132
|
-
conflictedNodeIds =
|
|
11133
|
-
highlightedEdgeIds =
|
|
11134
|
-
conflictedEdgeIds =
|
|
11985
|
+
highlightedNodeIds = EMPTY_IDS3,
|
|
11986
|
+
conflictedNodeIds = EMPTY_IDS3,
|
|
11987
|
+
highlightedEdgeIds = EMPTY_IDS3,
|
|
11988
|
+
conflictedEdgeIds = EMPTY_IDS3,
|
|
11135
11989
|
legend = EMPTY_LEGEND,
|
|
11136
11990
|
className,
|
|
11137
11991
|
labels,
|
|
11138
11992
|
showList = true
|
|
11139
11993
|
}) {
|
|
11140
|
-
const bounded = (0,
|
|
11141
|
-
const positioned = (0,
|
|
11142
|
-
const typeColor = (0,
|
|
11994
|
+
const bounded = (0, import_react64.useMemo)(() => boundRelationshipGraph(nodes, edges, maxNodes), [nodes, edges, maxNodes]);
|
|
11995
|
+
const positioned = (0, import_react64.useMemo)(() => layoutRelationshipGraph(bounded.nodes, bounded.edges, selectedId), [bounded, selectedId]);
|
|
11996
|
+
const typeColor = (0, import_react64.useMemo)(
|
|
11143
11997
|
() => new Map(legend.map((item, index) => [item.id, `var(--uix-chart-${index % 8 + 1})`])),
|
|
11144
11998
|
[legend]
|
|
11145
11999
|
);
|
|
11146
|
-
const positionedById = (0,
|
|
11147
|
-
const [zoom, setZoom] = (0,
|
|
11148
|
-
const [pan, setPan] = (0,
|
|
11149
|
-
const [focusedId, setFocusedId] = (0,
|
|
11150
|
-
const svgRef = (0,
|
|
12000
|
+
const positionedById = (0, import_react64.useMemo)(() => new Map(positioned.map((node) => [node.id, node])), [positioned]);
|
|
12001
|
+
const [zoom, setZoom] = (0, import_react64.useState)(1);
|
|
12002
|
+
const [pan, setPan] = (0, import_react64.useState)({ x: 0, y: 0 });
|
|
12003
|
+
const [focusedId, setFocusedId] = (0, import_react64.useState)(selectedId ?? positioned[0]?.id);
|
|
12004
|
+
const svgRef = (0, import_react64.useRef)(null);
|
|
11151
12005
|
const select = (id) => {
|
|
11152
12006
|
const node = bounded.nodes.find((item) => item.id === id);
|
|
11153
12007
|
if (node) onSelect?.(node);
|
|
@@ -11170,25 +12024,25 @@ function RadialRelationshipGraph({
|
|
|
11170
12024
|
setZoom(1);
|
|
11171
12025
|
setPan({ x: 0, y: 0 });
|
|
11172
12026
|
};
|
|
11173
|
-
return /* @__PURE__ */ (0,
|
|
11174
|
-
/* @__PURE__ */ (0,
|
|
11175
|
-
/* @__PURE__ */ (0,
|
|
11176
|
-
/* @__PURE__ */ (0,
|
|
11177
|
-
/* @__PURE__ */ (0,
|
|
11178
|
-
/* @__PURE__ */ (0,
|
|
11179
|
-
/* @__PURE__ */ (0,
|
|
11180
|
-
/* @__PURE__ */ (0,
|
|
11181
|
-
/* @__PURE__ */ (0,
|
|
11182
|
-
/* @__PURE__ */ (0,
|
|
12027
|
+
return /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("section", { className: cx("uix-relationship-graph", `uix-relationship-graph--${density}`, className), "aria-label": labels.graph, children: [
|
|
12028
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: "uix-relationship-graph__toolbar", "aria-label": labels.controls, children: [
|
|
12029
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, x: value.x - 24 })), "aria-label": labels.panLeft, children: labels.left }),
|
|
12030
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, y: value.y - 24 })), "aria-label": labels.panUp, children: labels.up }),
|
|
12031
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, y: value.y + 24 })), "aria-label": labels.panDown, children: labels.down }),
|
|
12032
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, x: value.x + 24 })), "aria-label": labels.panRight, children: labels.right }),
|
|
12033
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("button", { type: "button", onClick: () => setZoom((value) => Math.min(2, Number((value + 0.2).toFixed(1)))), "aria-label": labels.zoomIn, children: labels.zoomIn }),
|
|
12034
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("button", { type: "button", onClick: () => setZoom((value) => Math.max(0.5, Number((value - 0.2).toFixed(1)))), "aria-label": labels.zoomOut, children: labels.zoomOut }),
|
|
12035
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("button", { type: "button", onClick: reset, children: labels.reset }),
|
|
12036
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("span", { "aria-live": "polite", children: labels.zoomLevel(Math.round(zoom * 100)) })
|
|
11183
12037
|
] }),
|
|
11184
|
-
bounded.omittedNodeCount > 0 && /* @__PURE__ */ (0,
|
|
11185
|
-
/* @__PURE__ */ (0,
|
|
12038
|
+
bounded.omittedNodeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("p", { className: "uix-relationship-graph__bounded", role: "status", children: labels.bounded(bounded.nodes.length, bounded.omittedNodeCount) }),
|
|
12039
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("div", { className: "uix-relationship-graph__visual", children: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("svg", { ref: svgRef, viewBox: radialViewBox(positioned), role: "group", "aria-label": labels.graphSummary(bounded.nodes.length, bounded.edges.length), children: /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("g", { transform: `translate(${pan.x} ${pan.y}) scale(${zoom})`, children: [
|
|
11186
12040
|
bounded.edges.map((edge) => {
|
|
11187
12041
|
const source = positionedById.get(edge.source);
|
|
11188
12042
|
const target = positionedById.get(edge.target);
|
|
11189
|
-
return /* @__PURE__ */ (0,
|
|
12043
|
+
return /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("line", { x1: source.x * RADIAL_SCALE_X, y1: source.y * RADIAL_SCALE_Y, x2: target.x * RADIAL_SCALE_X, y2: target.y * RADIAL_SCALE_Y, className: "uix-relationship-graph__edge", "data-typed": edge.type != null && typeColor.has(edge.type) || void 0, style: edge.type != null && typeColor.has(edge.type) ? { "--uix-graph-type-color": typeColor.get(edge.type) } : void 0, "data-highlighted": highlightedEdgeIds.has(edge.id) || void 0, "data-conflicted": conflictedEdgeIds.has(edge.id) || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("title", { children: edge.label ?? edge.type ?? labels.relationship }) }, edge.id);
|
|
11190
12044
|
}),
|
|
11191
|
-
positioned.map((node) => /* @__PURE__ */ (0,
|
|
12045
|
+
positioned.map((node) => /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(
|
|
11192
12046
|
"g",
|
|
11193
12047
|
{
|
|
11194
12048
|
transform: `translate(${node.x * RADIAL_SCALE_X} ${node.y * RADIAL_SCALE_Y})`,
|
|
@@ -11204,22 +12058,22 @@ function RadialRelationshipGraph({
|
|
|
11204
12058
|
onKeyDown: (event) => onNodeKeyDown(event, node.id),
|
|
11205
12059
|
onClick: () => select(node.id),
|
|
11206
12060
|
children: [
|
|
11207
|
-
/* @__PURE__ */ (0,
|
|
11208
|
-
/* @__PURE__ */ (0,
|
|
11209
|
-
/* @__PURE__ */ (0,
|
|
12061
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("title", { children: node.label }),
|
|
12062
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("rect", { x: -RADIAL_NODE_HALF_W, y: -RADIAL_NODE_HALF_H, width: RADIAL_NODE_HALF_W * 2, height: RADIAL_NODE_HALF_H * 2, rx: "8" }),
|
|
12063
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("text", { textAnchor: "middle", dominantBaseline: "middle", children: node.label.length > 16 ? `${node.label.slice(0, 15)}\u2026` : node.label })
|
|
11210
12064
|
]
|
|
11211
12065
|
},
|
|
11212
12066
|
node.id
|
|
11213
12067
|
))
|
|
11214
12068
|
] }) }) }),
|
|
11215
|
-
legend.length > 0 && /* @__PURE__ */ (0,
|
|
11216
|
-
showList && /* @__PURE__ */ (0,
|
|
12069
|
+
legend.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("ul", { className: "uix-relationship-graph__legend", "aria-label": labels.legend, children: legend.map((item) => /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("li", { "data-type": item.id, style: { "--uix-graph-type-color": typeColor.get(item.id) }, children: item.label }, item.id)) }),
|
|
12070
|
+
showList && /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(EquivalentRelationshipList, { nodes: bounded.nodes, edges: bounded.edges, selectedId, labels, onSelect: select, onExpandNeighbors, onOpenDetails })
|
|
11217
12071
|
] });
|
|
11218
12072
|
}
|
|
11219
12073
|
|
|
11220
12074
|
// src/components/MatchReview.tsx
|
|
11221
|
-
var
|
|
11222
|
-
var
|
|
12075
|
+
var import_react65 = require("react");
|
|
12076
|
+
var import_jsx_runtime92 = require("react/jsx-runtime");
|
|
11223
12077
|
var DEFAULT_MATCH_REVIEW_LABELS = {
|
|
11224
12078
|
region: "Match review",
|
|
11225
12079
|
loading: "Loading match candidates\u2026",
|
|
@@ -11281,11 +12135,11 @@ function MatchReview({
|
|
|
11281
12135
|
const plural = (n, one, many) => fillLabel(n === 1 ? one : many, { count: n });
|
|
11282
12136
|
const decisionLabel = { accepted: labels.decisionAccepted, dismissed: labels.decisionDismissed, split: labels.decisionSplit, other: labels.decisionOther };
|
|
11283
12137
|
const actionLabel = { accept: labels.accept, dismiss: labels.dismiss, split: labels.split, "pick-other": labels.pickOther };
|
|
11284
|
-
const [internalSelection, setInternalSelection] = (0,
|
|
11285
|
-
const [announcement, setAnnouncement] = (0,
|
|
11286
|
-
const [bulkPending, setBulkPending] = (0,
|
|
12138
|
+
const [internalSelection, setInternalSelection] = (0, import_react65.useState)(/* @__PURE__ */ new Set());
|
|
12139
|
+
const [announcement, setAnnouncement] = (0, import_react65.useState)("");
|
|
12140
|
+
const [bulkPending, setBulkPending] = (0, import_react65.useState)(false);
|
|
11287
12141
|
const selection = selectedIds ?? internalSelection;
|
|
11288
|
-
const pending = (0,
|
|
12142
|
+
const pending = (0, import_react65.useMemo)(() => candidates.filter((candidate) => candidate.status !== "resolved"), [candidates]);
|
|
11289
12143
|
const setSelection = (next) => {
|
|
11290
12144
|
if (selectedIds === void 0) setInternalSelection(next);
|
|
11291
12145
|
onSelectionChange?.(next);
|
|
@@ -11314,48 +12168,48 @@ function MatchReview({
|
|
|
11314
12168
|
setBulkPending(false);
|
|
11315
12169
|
}
|
|
11316
12170
|
};
|
|
11317
|
-
if (loading) return /* @__PURE__ */ (0,
|
|
11318
|
-
if (error) return /* @__PURE__ */ (0,
|
|
11319
|
-
/* @__PURE__ */ (0,
|
|
11320
|
-
onRetry && /* @__PURE__ */ (0,
|
|
12171
|
+
if (loading) return /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { className: cx("uix-match-review uix-match-review--state", className), role: "status", children: labels.loading });
|
|
12172
|
+
if (error) return /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("div", { className: cx("uix-match-review uix-match-review--state", className), role: "alert", children: [
|
|
12173
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("p", { children: error }),
|
|
12174
|
+
onRetry && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: onRetry, children: labels.retry })
|
|
11321
12175
|
] });
|
|
11322
|
-
if (candidates.length === 0) return /* @__PURE__ */ (0,
|
|
11323
|
-
/* @__PURE__ */ (0,
|
|
11324
|
-
/* @__PURE__ */ (0,
|
|
12176
|
+
if (candidates.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("div", { className: cx("uix-match-review uix-match-review--state", className), children: [
|
|
12177
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("p", { children: labels.empty }),
|
|
12178
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("p", { children: labels.emptyDetail })
|
|
11325
12179
|
] });
|
|
11326
|
-
return /* @__PURE__ */ (0,
|
|
11327
|
-
/* @__PURE__ */ (0,
|
|
11328
|
-
/* @__PURE__ */ (0,
|
|
11329
|
-
/* @__PURE__ */ (0,
|
|
11330
|
-
/* @__PURE__ */ (0,
|
|
12180
|
+
return /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("section", { className: cx("uix-match-review", className), "aria-label": labels.region, children: [
|
|
12181
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("div", { className: "uix-match-review__summary", children: [
|
|
12182
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("div", { children: [
|
|
12183
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("strong", { children: incomingLabel }),
|
|
12184
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("span", { children: fillLabel(labels.pendingOf, { pending: pending.length, total: candidates.length }) })
|
|
11331
12185
|
] }),
|
|
11332
|
-
/* @__PURE__ */ (0,
|
|
11333
|
-
/* @__PURE__ */ (0,
|
|
12186
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { className: "uix-match-review__incoming", children: fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("span", { children: [
|
|
12187
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("b", { children: field.label }),
|
|
11334
12188
|
field.render?.(incoming[field.id], incoming) ?? valueText(incoming[field.id])
|
|
11335
12189
|
] }, field.id)) })
|
|
11336
12190
|
] }),
|
|
11337
|
-
onBulkDecision && /* @__PURE__ */ (0,
|
|
11338
|
-
/* @__PURE__ */ (0,
|
|
11339
|
-
/* @__PURE__ */ (0,
|
|
11340
|
-
/* @__PURE__ */ (0,
|
|
12191
|
+
onBulkDecision && /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("div", { className: "uix-match-review__bulk", "aria-label": labels.bulk, children: [
|
|
12192
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("span", { children: fillLabel(labels.selectedCount, { count: selection.size }) }),
|
|
12193
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", disabled: selection.size === 0 || bulkPending, onClick: () => void runBulk("accept"), children: bulkPending ? labels.applying : labels.acceptSelected }),
|
|
12194
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", disabled: selection.size === 0 || bulkPending, onClick: () => void runBulk("dismiss"), children: bulkPending ? labels.applying : labels.dismissSelected })
|
|
11341
12195
|
] }),
|
|
11342
|
-
/* @__PURE__ */ (0,
|
|
11343
|
-
/* @__PURE__ */ (0,
|
|
11344
|
-
/* @__PURE__ */ (0,
|
|
11345
|
-
/* @__PURE__ */ (0,
|
|
11346
|
-
/* @__PURE__ */ (0,
|
|
11347
|
-
fields.map((field) => /* @__PURE__ */ (0,
|
|
11348
|
-
/* @__PURE__ */ (0,
|
|
11349
|
-
/* @__PURE__ */ (0,
|
|
12196
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { className: "uix-match-review__table-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("table", { className: "uix-table uix-match-review__table", children: [
|
|
12197
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("caption", { className: "uix-visually-hidden", children: labels.caption }),
|
|
12198
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("tr", { children: [
|
|
12199
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("th", { scope: "col", children: /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("span", { className: "uix-visually-hidden", children: labels.select }) }),
|
|
12200
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("th", { scope: "col", children: labels.confidence }),
|
|
12201
|
+
fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("th", { scope: "col", children: field.label }, field.id)),
|
|
12202
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("th", { scope: "col", children: labels.status }),
|
|
12203
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("th", { scope: "col", children: labels.actions })
|
|
11350
12204
|
] }) }),
|
|
11351
|
-
/* @__PURE__ */ (0,
|
|
12205
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("tbody", { children: candidates.map((candidate) => {
|
|
11352
12206
|
const resolved = candidate.status === "resolved";
|
|
11353
|
-
return /* @__PURE__ */ (0,
|
|
11354
|
-
/* @__PURE__ */ (0,
|
|
11355
|
-
/* @__PURE__ */ (0,
|
|
11356
|
-
fields.map((field) => /* @__PURE__ */ (0,
|
|
11357
|
-
/* @__PURE__ */ (0,
|
|
11358
|
-
/* @__PURE__ */ (0,
|
|
12207
|
+
return /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("tr", { "data-status": candidate.status ?? "pending", children: [
|
|
12208
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("input", { type: "checkbox", checked: selection.has(candidate.id), onChange: () => toggle(candidate.id), "aria-label": fillLabel(labels.selectCandidate, { id: candidate.id }) }) }),
|
|
12209
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("span", { className: "uix-match-review__confidence", children: candidate.confidence == null ? labels.notScored : `${Math.round(candidate.confidence * 100)}%` }) }),
|
|
12210
|
+
fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("td", { children: field.render?.(candidate.record[field.id], candidate.record) ?? valueText(candidate.record[field.id]) }, field.id)),
|
|
12211
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(StatusPill, { tone: resolved ? "success" : "warning", children: resolved ? candidate.decision ? decisionLabel[candidate.decision] : labels.resolved : labels.pending }) }),
|
|
12212
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { className: "uix-match-review__actions", children: ["accept", "dismiss", "split", "pick-other"].map((action) => /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
11359
12213
|
"button",
|
|
11360
12214
|
{
|
|
11361
12215
|
type: "button",
|
|
@@ -11369,12 +12223,12 @@ function MatchReview({
|
|
|
11369
12223
|
] }, candidate.id);
|
|
11370
12224
|
}) })
|
|
11371
12225
|
] }) }),
|
|
11372
|
-
/* @__PURE__ */ (0,
|
|
12226
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("p", { className: "uix-visually-hidden", "aria-live": "polite", children: announcement })
|
|
11373
12227
|
] });
|
|
11374
12228
|
}
|
|
11375
12229
|
|
|
11376
12230
|
// src/components/MetricInput.tsx
|
|
11377
|
-
var
|
|
12231
|
+
var import_react66 = require("react");
|
|
11378
12232
|
|
|
11379
12233
|
// src/metric-model.ts
|
|
11380
12234
|
function decimals(value) {
|
|
@@ -11399,7 +12253,7 @@ function parseMetricValue(value) {
|
|
|
11399
12253
|
}
|
|
11400
12254
|
|
|
11401
12255
|
// src/components/MetricInput.tsx
|
|
11402
|
-
var
|
|
12256
|
+
var import_jsx_runtime93 = require("react/jsx-runtime");
|
|
11403
12257
|
var defaultMetricFormat = (input) => input == null ? "" : String(input);
|
|
11404
12258
|
function MetricInput({
|
|
11405
12259
|
value,
|
|
@@ -11418,11 +12272,11 @@ function MetricInput({
|
|
|
11418
12272
|
className,
|
|
11419
12273
|
id: providedId
|
|
11420
12274
|
}) {
|
|
11421
|
-
const generatedId = (0,
|
|
12275
|
+
const generatedId = (0, import_react66.useId)();
|
|
11422
12276
|
const id = providedId ?? generatedId;
|
|
11423
12277
|
const errorId = `${id}-error`;
|
|
11424
|
-
const [text, setText] = (0,
|
|
11425
|
-
(0,
|
|
12278
|
+
const [text, setText] = (0, import_react66.useState)(() => format(value));
|
|
12279
|
+
(0, import_react66.useEffect)(() => setText(format(value)), [value, format]);
|
|
11426
12280
|
const commit = (input) => {
|
|
11427
12281
|
const parsed = parse(input);
|
|
11428
12282
|
if (input.trim() === "" || parsed !== null) {
|
|
@@ -11448,10 +12302,10 @@ function MetricInput({
|
|
|
11448
12302
|
const parsed = parse(event.currentTarget.value);
|
|
11449
12303
|
setText(parsed === null && event.currentTarget.value.trim() !== "" ? format(value) : format(parsed));
|
|
11450
12304
|
};
|
|
11451
|
-
return /* @__PURE__ */ (0,
|
|
11452
|
-
/* @__PURE__ */ (0,
|
|
11453
|
-
/* @__PURE__ */ (0,
|
|
11454
|
-
/* @__PURE__ */ (0,
|
|
12305
|
+
return /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { className: cx("uix-metric-input", invalid && "uix-metric-input--invalid", className), children: [
|
|
12306
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)("label", { className: "uix-field__label", htmlFor: id, children: label }),
|
|
12307
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { className: "uix-metric-input__control", children: [
|
|
12308
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
|
|
11455
12309
|
Input,
|
|
11456
12310
|
{
|
|
11457
12311
|
id,
|
|
@@ -11470,22 +12324,22 @@ function MetricInput({
|
|
|
11470
12324
|
readOnly
|
|
11471
12325
|
}
|
|
11472
12326
|
),
|
|
11473
|
-
unit && /* @__PURE__ */ (0,
|
|
11474
|
-
/* @__PURE__ */ (0,
|
|
11475
|
-
/* @__PURE__ */ (0,
|
|
11476
|
-
/* @__PURE__ */ (0,
|
|
12327
|
+
unit && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("span", { className: "uix-metric-input__unit", "aria-hidden": "true", children: unit }),
|
|
12328
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("span", { className: "uix-metric-input__steps", children: [
|
|
12329
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)("button", { type: "button", className: "uix-metric-input__step", onClick: () => stepBy(1), disabled: disabled || readOnly, "aria-label": `Increase ${label}`, children: "+" }),
|
|
12330
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)("button", { type: "button", className: "uix-metric-input__step", onClick: () => stepBy(-1), disabled: disabled || readOnly, "aria-label": `Decrease ${label}`, children: "\u2212" })
|
|
11477
12331
|
] })
|
|
11478
12332
|
] }),
|
|
11479
|
-
unit && /* @__PURE__ */ (0,
|
|
12333
|
+
unit && /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("span", { className: "uix-visually-hidden", children: [
|
|
11480
12334
|
"Unit: ",
|
|
11481
12335
|
unit
|
|
11482
12336
|
] }),
|
|
11483
|
-
invalid && errorMessage && /* @__PURE__ */ (0,
|
|
12337
|
+
invalid && errorMessage && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("span", { id: errorId, className: "uix-field__error", children: errorMessage })
|
|
11484
12338
|
] });
|
|
11485
12339
|
}
|
|
11486
12340
|
|
|
11487
12341
|
// src/components/LicensePositionBar.tsx
|
|
11488
|
-
var
|
|
12342
|
+
var import_jsx_runtime94 = require("react/jsx-runtime");
|
|
11489
12343
|
var defaultCapacityFormat = (value) => new Intl.NumberFormat().format(value);
|
|
11490
12344
|
function LicensePositionBar({
|
|
11491
12345
|
consumed,
|
|
@@ -11506,18 +12360,18 @@ function LicensePositionBar({
|
|
|
11506
12360
|
const percent = safeEntitled === 0 ? safeConsumed > 0 ? 100 : 0 : safeConsumed / safeEntitled * 100;
|
|
11507
12361
|
const format = (value) => `${formatValue(value)}${unit ? ` ${unit}` : ""}`;
|
|
11508
12362
|
const summary = `${consumedLabel}: ${format(safeConsumed)}. ${entitledLabel}: ${format(safeEntitled)}. ${over > 0 ? `${format(over)} ${overLabel}` : `${format(available)} ${availableLabel}`}.`;
|
|
11509
|
-
return /* @__PURE__ */ (0,
|
|
11510
|
-
/* @__PURE__ */ (0,
|
|
11511
|
-
/* @__PURE__ */ (0,
|
|
12363
|
+
return /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { className: cx("uix-license-position", over > 0 && "uix-license-position--over", className), ...props, children: [
|
|
12364
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { className: "uix-license-position__header", children: [
|
|
12365
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("span", { className: "uix-license-position__value", children: [
|
|
11512
12366
|
format(safeConsumed),
|
|
11513
12367
|
" / ",
|
|
11514
12368
|
format(safeEntitled)
|
|
11515
12369
|
] }),
|
|
11516
|
-
/* @__PURE__ */ (0,
|
|
12370
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)(StatusPill, { tone: over > 0 ? "danger" : percent >= 80 ? "warning" : "success", children: over > 0 ? `${format(over)} ${overLabel}` : `${format(available)} ${availableLabel}` })
|
|
11517
12371
|
] }),
|
|
11518
|
-
/* @__PURE__ */ (0,
|
|
11519
|
-
/* @__PURE__ */ (0,
|
|
11520
|
-
over > 0 && /* @__PURE__ */ (0,
|
|
12372
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { className: "uix-license-position__track", children: [
|
|
12373
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)(Meter, { value: Math.min(100, percent), tone: over > 0 ? "danger" : percent >= 80 ? "warning" : "success", "aria-label": summary, "aria-valuetext": summary }),
|
|
12374
|
+
over > 0 && /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(
|
|
11521
12375
|
"span",
|
|
11522
12376
|
{
|
|
11523
12377
|
className: "uix-license-position__overflow",
|
|
@@ -11526,12 +12380,12 @@ function LicensePositionBar({
|
|
|
11526
12380
|
}
|
|
11527
12381
|
)
|
|
11528
12382
|
] }),
|
|
11529
|
-
/* @__PURE__ */ (0,
|
|
12383
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("span", { className: "uix-visually-hidden", children: summary })
|
|
11530
12384
|
] });
|
|
11531
12385
|
}
|
|
11532
12386
|
|
|
11533
12387
|
// src/components/BrandProfiles.tsx
|
|
11534
|
-
var
|
|
12388
|
+
var import_react68 = require("react");
|
|
11535
12389
|
|
|
11536
12390
|
// src/color-model.ts
|
|
11537
12391
|
var clamp2 = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
@@ -11600,8 +12454,8 @@ function meetsContrast(background, foreground, minimum = 4.5) {
|
|
|
11600
12454
|
}
|
|
11601
12455
|
|
|
11602
12456
|
// src/components/ColorPicker.tsx
|
|
11603
|
-
var
|
|
11604
|
-
var
|
|
12457
|
+
var import_react67 = require("react");
|
|
12458
|
+
var import_jsx_runtime95 = require("react/jsx-runtime");
|
|
11605
12459
|
var DEFAULT_COLOR_PICKER_LABELS = {
|
|
11606
12460
|
trigger: "{label}: {color}",
|
|
11607
12461
|
sample: "Aa",
|
|
@@ -11632,17 +12486,17 @@ function ColorPicker({
|
|
|
11632
12486
|
labels: labelOverrides
|
|
11633
12487
|
}) {
|
|
11634
12488
|
const labels = { ...DEFAULT_COLOR_PICKER_LABELS, ...labelOverrides };
|
|
11635
|
-
const id = (0,
|
|
11636
|
-
const triggerRef = (0,
|
|
11637
|
-
const dialogRef = (0,
|
|
11638
|
-
const [open, setOpen] = (0,
|
|
12489
|
+
const id = (0, import_react67.useId)();
|
|
12490
|
+
const triggerRef = (0, import_react67.useRef)(null);
|
|
12491
|
+
const dialogRef = (0, import_react67.useRef)(null);
|
|
12492
|
+
const [open, setOpen] = (0, import_react67.useState)(false);
|
|
11639
12493
|
const normalized = normalizeHex(value) ?? "#000000";
|
|
11640
|
-
const [hexText, setHexText] = (0,
|
|
11641
|
-
const hsv = (0,
|
|
12494
|
+
const [hexText, setHexText] = (0, import_react67.useState)(normalized);
|
|
12495
|
+
const hsv = (0, import_react67.useMemo)(() => rgbToHsv(hexToRgb(normalized)), [normalized]);
|
|
11642
12496
|
const ratio = contrastRatio(normalized, foreground) ?? 0;
|
|
11643
12497
|
const passes = ratio >= minimumContrast;
|
|
11644
|
-
(0,
|
|
11645
|
-
(0,
|
|
12498
|
+
(0, import_react67.useEffect)(() => setHexText(normalized), [normalized]);
|
|
12499
|
+
(0, import_react67.useEffect)(() => {
|
|
11646
12500
|
if (!open) return;
|
|
11647
12501
|
const dialog = dialogRef.current;
|
|
11648
12502
|
dialog?.querySelector("input,button")?.focus();
|
|
@@ -11685,8 +12539,8 @@ function ColorPicker({
|
|
|
11685
12539
|
if (next) onChange(next);
|
|
11686
12540
|
};
|
|
11687
12541
|
const sampleStyle = { backgroundColor: normalized };
|
|
11688
|
-
return /* @__PURE__ */ (0,
|
|
11689
|
-
/* @__PURE__ */ (0,
|
|
12542
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: cx("uix-color-picker", className), children: [
|
|
12543
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(
|
|
11690
12544
|
"button",
|
|
11691
12545
|
{
|
|
11692
12546
|
ref: triggerRef,
|
|
@@ -11698,12 +12552,12 @@ function ColorPicker({
|
|
|
11698
12552
|
onClick: () => setOpen((current) => !current),
|
|
11699
12553
|
disabled,
|
|
11700
12554
|
children: [
|
|
11701
|
-
/* @__PURE__ */ (0,
|
|
11702
|
-
/* @__PURE__ */ (0,
|
|
12555
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { className: "uix-color-picker__swatch", style: sampleStyle, "aria-hidden": "true" }),
|
|
12556
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { children: normalized })
|
|
11703
12557
|
]
|
|
11704
12558
|
}
|
|
11705
12559
|
),
|
|
11706
|
-
open && /* @__PURE__ */ (0,
|
|
12560
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(
|
|
11707
12561
|
"div",
|
|
11708
12562
|
{
|
|
11709
12563
|
ref: dialogRef,
|
|
@@ -11714,55 +12568,55 @@ function ColorPicker({
|
|
|
11714
12568
|
className: "uix-color-picker__popover",
|
|
11715
12569
|
onKeyDown: onDialogKeyDown,
|
|
11716
12570
|
children: [
|
|
11717
|
-
/* @__PURE__ */ (0,
|
|
11718
|
-
/* @__PURE__ */ (0,
|
|
12571
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("div", { className: "uix-color-picker__preview", style: sampleStyle, children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { style: { color: foreground }, children: labels.sample }) }),
|
|
12572
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("label", { className: "uix-color-picker__range", children: [
|
|
11719
12573
|
labels.hue,
|
|
11720
12574
|
" ",
|
|
11721
|
-
/* @__PURE__ */ (0,
|
|
12575
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("span", { children: [
|
|
11722
12576
|
Math.round(hsv.h),
|
|
11723
12577
|
"\xB0"
|
|
11724
12578
|
] }),
|
|
11725
|
-
/* @__PURE__ */ (0,
|
|
12579
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("input", { type: "range", min: "0", max: "359", value: Math.round(hsv.h), onChange: (event) => updateHsv({ h: Number(event.currentTarget.value) }) })
|
|
11726
12580
|
] }),
|
|
11727
|
-
/* @__PURE__ */ (0,
|
|
12581
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("label", { className: "uix-color-picker__range", children: [
|
|
11728
12582
|
labels.saturation,
|
|
11729
12583
|
" ",
|
|
11730
|
-
/* @__PURE__ */ (0,
|
|
12584
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("span", { children: [
|
|
11731
12585
|
Math.round(hsv.s * 100),
|
|
11732
12586
|
"%"
|
|
11733
12587
|
] }),
|
|
11734
|
-
/* @__PURE__ */ (0,
|
|
12588
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("input", { type: "range", min: "0", max: "100", value: Math.round(hsv.s * 100), onChange: (event) => updateHsv({ s: Number(event.currentTarget.value) / 100 }) })
|
|
11735
12589
|
] }),
|
|
11736
|
-
/* @__PURE__ */ (0,
|
|
12590
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("label", { className: "uix-color-picker__range", children: [
|
|
11737
12591
|
labels.brightness,
|
|
11738
12592
|
" ",
|
|
11739
|
-
/* @__PURE__ */ (0,
|
|
12593
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("span", { children: [
|
|
11740
12594
|
Math.round(hsv.v * 100),
|
|
11741
12595
|
"%"
|
|
11742
12596
|
] }),
|
|
11743
|
-
/* @__PURE__ */ (0,
|
|
12597
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("input", { type: "range", min: "0", max: "100", value: Math.round(hsv.v * 100), onChange: (event) => updateHsv({ v: Number(event.currentTarget.value) / 100 }) })
|
|
11744
12598
|
] }),
|
|
11745
|
-
/* @__PURE__ */ (0,
|
|
12599
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("label", { className: "uix-color-picker__hex", children: [
|
|
11746
12600
|
labels.hex,
|
|
11747
|
-
/* @__PURE__ */ (0,
|
|
11748
|
-
/* @__PURE__ */ (0,
|
|
12601
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("span", { className: "uix-color-picker__hex-row", children: [
|
|
12602
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("input", { className: "uix-input", value: hexText, onChange: (event) => setHexText(event.currentTarget.value), onBlur: commitHex, onKeyDown: (event) => {
|
|
11749
12603
|
if (event.key === "Enter") commitHex();
|
|
11750
12604
|
}, "aria-invalid": !normalizeHex(hexText) }),
|
|
11751
|
-
/* @__PURE__ */ (0,
|
|
12605
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", onClick: commitHex, disabled: !normalizeHex(hexText), children: labels.set })
|
|
11752
12606
|
] })
|
|
11753
12607
|
] }),
|
|
11754
|
-
(presets.length > 0 || recent.length > 0) && /* @__PURE__ */ (0,
|
|
11755
|
-
presets.length > 0 && /* @__PURE__ */ (0,
|
|
11756
|
-
/* @__PURE__ */ (0,
|
|
11757
|
-
/* @__PURE__ */ (0,
|
|
12608
|
+
(presets.length > 0 || recent.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "uix-color-picker__palettes", children: [
|
|
12609
|
+
presets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("fieldset", { children: [
|
|
12610
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("legend", { children: labels.presets }),
|
|
12611
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("div", { children: presets.map((color) => /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("button", { type: "button", className: "uix-color-picker__preset", style: { backgroundColor: normalizeHex(color) ?? color }, onClick: () => choose(color), "aria-label": fillLabel(labels.usePreset, { color }) }, color)) })
|
|
11758
12612
|
] }),
|
|
11759
|
-
recent.length > 0 && /* @__PURE__ */ (0,
|
|
11760
|
-
/* @__PURE__ */ (0,
|
|
11761
|
-
/* @__PURE__ */ (0,
|
|
12613
|
+
recent.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("fieldset", { children: [
|
|
12614
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("legend", { children: labels.recent }),
|
|
12615
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("div", { children: recent.map((color) => /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("button", { type: "button", className: "uix-color-picker__preset", style: { backgroundColor: normalizeHex(color) ?? color }, onClick: () => choose(color), "aria-label": fillLabel(labels.useRecent, { color }) }, color)) })
|
|
11762
12616
|
] })
|
|
11763
12617
|
] }),
|
|
11764
|
-
/* @__PURE__ */ (0,
|
|
11765
|
-
/* @__PURE__ */ (0,
|
|
12618
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("p", { className: cx("uix-color-picker__contrast", passes ? "uix-color-picker__contrast--pass" : "uix-color-picker__contrast--fail"), role: "status", "aria-live": "polite", children: fillLabel(passes ? labels.contrastPasses : labels.contrastFails, { ratio: ratio.toFixed(2), minimum: minimumContrast }) }),
|
|
12619
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary uix-btn--sm", onClick: close, children: labels.done })
|
|
11766
12620
|
]
|
|
11767
12621
|
}
|
|
11768
12622
|
)
|
|
@@ -11770,7 +12624,7 @@ function ColorPicker({
|
|
|
11770
12624
|
}
|
|
11771
12625
|
|
|
11772
12626
|
// src/components/BrandProfiles.tsx
|
|
11773
|
-
var
|
|
12627
|
+
var import_jsx_runtime96 = require("react/jsx-runtime");
|
|
11774
12628
|
var PROFILE_PROPERTIES = {
|
|
11775
12629
|
brand: "--uix-brand",
|
|
11776
12630
|
brandForeground: "--uix-brand-fg",
|
|
@@ -11862,7 +12716,7 @@ function BrandProfileEditor({
|
|
|
11862
12716
|
labels: labelOverrides
|
|
11863
12717
|
}) {
|
|
11864
12718
|
const labels = { ...DEFAULT_BRAND_PROFILE_EDITOR_LABELS, ...labelOverrides };
|
|
11865
|
-
const [announcement, setAnnouncement] = (0,
|
|
12719
|
+
const [announcement, setAnnouncement] = (0, import_react68.useState)("");
|
|
11866
12720
|
const update = (patch) => onChange({ ...value, ...patch });
|
|
11867
12721
|
const apply = () => {
|
|
11868
12722
|
if (applyTarget !== null) applyBrandProfile(value, applyTarget);
|
|
@@ -11879,54 +12733,54 @@ function BrandProfileEditor({
|
|
|
11879
12733
|
...value.typography?.sans ? { "--uix-font-sans": value.typography.sans } : {},
|
|
11880
12734
|
...value.typography?.heading ? { "--uix-font-heading": value.typography.heading } : {}
|
|
11881
12735
|
};
|
|
11882
|
-
return /* @__PURE__ */ (0,
|
|
11883
|
-
/* @__PURE__ */ (0,
|
|
11884
|
-
profiles.length > 0 && /* @__PURE__ */ (0,
|
|
12736
|
+
return /* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("section", { className: cx("uix-brand-profiles", className), "aria-label": labels.region, children: [
|
|
12737
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("div", { className: "uix-brand-profiles__form", children: [
|
|
12738
|
+
profiles.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("label", { className: "uix-field__label", children: [
|
|
11885
12739
|
labels.profile,
|
|
11886
|
-
/* @__PURE__ */ (0,
|
|
12740
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("select", { className: "uix-select", value: value.id, onChange: (event) => {
|
|
11887
12741
|
const selected = profiles.find((profile) => profile.id === event.currentTarget.value);
|
|
11888
12742
|
if (selected) onSelectProfile?.(selected);
|
|
11889
|
-
}, children: profiles.map((profile) => /* @__PURE__ */ (0,
|
|
12743
|
+
}, children: profiles.map((profile) => /* @__PURE__ */ (0, import_jsx_runtime96.jsx)("option", { value: profile.id, children: profile.name }, profile.id)) })
|
|
11890
12744
|
] }),
|
|
11891
|
-
/* @__PURE__ */ (0,
|
|
12745
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("label", { className: "uix-field__label", children: [
|
|
11892
12746
|
labels.name,
|
|
11893
|
-
/* @__PURE__ */ (0,
|
|
12747
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("input", { className: "uix-input", value: value.name, onChange: (event) => update({ name: event.currentTarget.value }) })
|
|
11894
12748
|
] }),
|
|
11895
|
-
/* @__PURE__ */ (0,
|
|
11896
|
-
/* @__PURE__ */ (0,
|
|
12749
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("div", { className: "uix-brand-profiles__colors", children: [
|
|
12750
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("label", { children: [
|
|
11897
12751
|
labels.brand,
|
|
11898
|
-
/* @__PURE__ */ (0,
|
|
12752
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)(ColorPicker, { label: labels.brandColor, value: value.brand, foreground: value.brandForeground, presets: colorPresets, onChange: (brand) => update({ brand }) })
|
|
11899
12753
|
] }),
|
|
11900
|
-
/* @__PURE__ */ (0,
|
|
12754
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("label", { children: [
|
|
11901
12755
|
labels.onBrand,
|
|
11902
|
-
/* @__PURE__ */ (0,
|
|
12756
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)(ColorPicker, { label: labels.onBrandColor, value: value.brandForeground, foreground: value.brand, presets: colorPresets, onChange: (brandForeground) => update({ brandForeground }) })
|
|
11903
12757
|
] })
|
|
11904
12758
|
] }),
|
|
11905
|
-
/* @__PURE__ */ (0,
|
|
12759
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("label", { className: "uix-field__label", children: [
|
|
11906
12760
|
labels.bodyFont,
|
|
11907
|
-
/* @__PURE__ */ (0,
|
|
12761
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("input", { className: "uix-input", value: value.typography?.sans ?? "", onChange: (event) => update({ typography: { ...value.typography, sans: event.currentTarget.value || void 0 } }) })
|
|
11908
12762
|
] }),
|
|
11909
|
-
/* @__PURE__ */ (0,
|
|
12763
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("label", { className: "uix-field__label", children: [
|
|
11910
12764
|
labels.headingFont,
|
|
11911
|
-
/* @__PURE__ */ (0,
|
|
12765
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("input", { className: "uix-input", value: value.typography?.heading ?? "", onChange: (event) => update({ typography: { ...value.typography, heading: event.currentTarget.value || void 0 } }) })
|
|
11912
12766
|
] }),
|
|
11913
|
-
/* @__PURE__ */ (0,
|
|
12767
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("label", { className: "uix-file-upload uix-brand-profiles__upload", children: [
|
|
11914
12768
|
labels.logoFile,
|
|
11915
|
-
/* @__PURE__ */ (0,
|
|
12769
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("input", { type: "file", accept: "image/*", onChange: onFile })
|
|
11916
12770
|
] }),
|
|
11917
|
-
/* @__PURE__ */ (0,
|
|
11918
|
-
/* @__PURE__ */ (0,
|
|
12771
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary", onClick: apply, children: labels.apply }),
|
|
12772
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("span", { className: "uix-visually-hidden", "aria-live": "polite", children: announcement })
|
|
11919
12773
|
] }),
|
|
11920
|
-
/* @__PURE__ */ (0,
|
|
11921
|
-
/* @__PURE__ */ (0,
|
|
11922
|
-
value.logo ? /* @__PURE__ */ (0,
|
|
11923
|
-
/* @__PURE__ */ (0,
|
|
12774
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("div", { className: "uix-brand-profiles__preview", style: previewStyle, "aria-label": fillLabel(labels.preview, { name: value.name }), children: [
|
|
12775
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("div", { className: "uix-brand-profiles__preview-header", children: [
|
|
12776
|
+
value.logo ? /* @__PURE__ */ (0, import_jsx_runtime96.jsx)("img", { src: value.logo.src, alt: value.logo.alt }) : /* @__PURE__ */ (0, import_jsx_runtime96.jsx)("span", { className: "uix-brand-profiles__logo-placeholder", children: labels.logoPlaceholder }),
|
|
12777
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("strong", { children: value.name || labels.previewTitleFallback })
|
|
11924
12778
|
] }),
|
|
11925
|
-
/* @__PURE__ */ (0,
|
|
11926
|
-
/* @__PURE__ */ (0,
|
|
11927
|
-
/* @__PURE__ */ (0,
|
|
11928
|
-
/* @__PURE__ */ (0,
|
|
11929
|
-
/* @__PURE__ */ (0,
|
|
12779
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("div", { className: "uix-brand-profiles__preview-body", children: [
|
|
12780
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("h3", { children: labels.previewHeading }),
|
|
12781
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("p", { children: labels.previewBody }),
|
|
12782
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary", children: labels.previewPrimary }),
|
|
12783
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("a", { href: "#brand-profile-preview", children: labels.previewLink })
|
|
11930
12784
|
] })
|
|
11931
12785
|
] })
|
|
11932
12786
|
] });
|
|
@@ -11934,7 +12788,7 @@ function BrandProfileEditor({
|
|
|
11934
12788
|
var BrandProfiles = BrandProfileEditor;
|
|
11935
12789
|
|
|
11936
12790
|
// src/components/DiffViewer.tsx
|
|
11937
|
-
var
|
|
12791
|
+
var import_react69 = require("react");
|
|
11938
12792
|
|
|
11939
12793
|
// src/diff-model.ts
|
|
11940
12794
|
function isJsonObject(value) {
|
|
@@ -11985,7 +12839,7 @@ function summarizeDiff(entries, resolutions = {}) {
|
|
|
11985
12839
|
}
|
|
11986
12840
|
|
|
11987
12841
|
// src/components/DiffViewer.tsx
|
|
11988
|
-
var
|
|
12842
|
+
var import_jsx_runtime97 = require("react/jsx-runtime");
|
|
11989
12843
|
var DEFAULT_DIFF_VIEWER_LABELS = {
|
|
11990
12844
|
base: "Base",
|
|
11991
12845
|
current: "Current",
|
|
@@ -12030,33 +12884,33 @@ function DiffViewer({
|
|
|
12030
12884
|
const labels = { ...DEFAULT_DIFF_VIEWER_LABELS, ...labelOverrides };
|
|
12031
12885
|
const resolutionLabel = { accept: labels.resolutionAccept, skip: labels.resolutionSkip, pending: labels.resolutionPending };
|
|
12032
12886
|
const buttonSize = controlSize === "md" ? void 0 : `uix-btn--${controlSize}`;
|
|
12033
|
-
const id = (0,
|
|
12034
|
-
const entries = (0,
|
|
12035
|
-
const [internalResolutions, setInternalResolutions] = (0,
|
|
12887
|
+
const id = (0, import_react69.useId)();
|
|
12888
|
+
const entries = (0, import_react69.useMemo)(() => providedEntries ?? buildThreeWayDiff(base, current, incoming), [providedEntries, base, current, incoming]);
|
|
12889
|
+
const [internalResolutions, setInternalResolutions] = (0, import_react69.useState)({});
|
|
12036
12890
|
const resolutions = controlledResolutions ?? internalResolutions;
|
|
12037
12891
|
const summary = summarizeDiff(entries, resolutions);
|
|
12038
12892
|
const resolve = (path, resolution) => {
|
|
12039
12893
|
if (controlledResolutions === void 0) setInternalResolutions((currentState) => ({ ...currentState, [path]: resolution }));
|
|
12040
12894
|
onResolutionChange?.(path, resolution);
|
|
12041
12895
|
};
|
|
12042
|
-
if (entries.length === 0) return /* @__PURE__ */ (0,
|
|
12043
|
-
/* @__PURE__ */ (0,
|
|
12044
|
-
/* @__PURE__ */ (0,
|
|
12896
|
+
if (entries.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("section", { className: cx("uix-diff-viewer uix-diff-viewer--empty", className), "aria-label": labels.region, children: [
|
|
12897
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("h3", { children: labels.noDifferences }),
|
|
12898
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("p", { children: labels.noDifferencesDetail })
|
|
12045
12899
|
] });
|
|
12046
|
-
return /* @__PURE__ */ (0,
|
|
12047
|
-
/* @__PURE__ */ (0,
|
|
12048
|
-
GROUPS.map((kind) => /* @__PURE__ */ (0,
|
|
12049
|
-
/* @__PURE__ */ (0,
|
|
12900
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("section", { className: cx("uix-diff-viewer", className), "aria-label": labels.region, "data-control-size": controlSize, children: [
|
|
12901
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: "uix-diff-viewer__summary", role: "group", "aria-label": labels.summary, children: [
|
|
12902
|
+
GROUPS.map((kind) => /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("span", { children: [
|
|
12903
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("b", { children: summary[kind] }),
|
|
12050
12904
|
" ",
|
|
12051
12905
|
labels[kind].toLowerCase()
|
|
12052
12906
|
] }, kind)),
|
|
12053
|
-
/* @__PURE__ */ (0,
|
|
12054
|
-
/* @__PURE__ */ (0,
|
|
12907
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("span", { children: [
|
|
12908
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("b", { children: summary.resolved }),
|
|
12055
12909
|
" ",
|
|
12056
12910
|
labels.resolved
|
|
12057
12911
|
] }),
|
|
12058
|
-
/* @__PURE__ */ (0,
|
|
12059
|
-
/* @__PURE__ */ (0,
|
|
12912
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("span", { children: [
|
|
12913
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("b", { children: summary.pending }),
|
|
12060
12914
|
" ",
|
|
12061
12915
|
labels.pending
|
|
12062
12916
|
] })
|
|
@@ -12064,38 +12918,38 @@ function DiffViewer({
|
|
|
12064
12918
|
GROUPS.map((kind) => {
|
|
12065
12919
|
const grouped = entries.filter((entry) => entry.kind === kind);
|
|
12066
12920
|
if (!grouped.length) return null;
|
|
12067
|
-
return /* @__PURE__ */ (0,
|
|
12068
|
-
/* @__PURE__ */ (0,
|
|
12921
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("section", { className: "uix-diff-viewer__group", "aria-labelledby": `${id}-${kind}`, children: [
|
|
12922
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("h3", { id: `${id}-${kind}`, children: [
|
|
12069
12923
|
labels[kind],
|
|
12070
12924
|
" ",
|
|
12071
|
-
/* @__PURE__ */ (0,
|
|
12925
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { children: grouped.length })
|
|
12072
12926
|
] }),
|
|
12073
12927
|
grouped.map((entry) => {
|
|
12074
12928
|
const resolution = resolutions[entry.path] ?? "pending";
|
|
12075
|
-
return /* @__PURE__ */ (0,
|
|
12076
|
-
/* @__PURE__ */ (0,
|
|
12077
|
-
/* @__PURE__ */ (0,
|
|
12078
|
-
/* @__PURE__ */ (0,
|
|
12929
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("details", { className: "uix-diff-viewer__entry", "data-kind": entry.kind, open: entry.kind === "conflicted", children: [
|
|
12930
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("summary", { children: [
|
|
12931
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("code", { children: entry.path }),
|
|
12932
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(StatusPill, { tone: resolution === "pending" ? "warning" : "success", children: resolutionLabel[resolution] })
|
|
12079
12933
|
] }),
|
|
12080
|
-
/* @__PURE__ */ (0,
|
|
12081
|
-
/* @__PURE__ */ (0,
|
|
12082
|
-
/* @__PURE__ */ (0,
|
|
12934
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: "uix-diff-viewer__versions", children: ["base", "current", "incoming"].map((version) => /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { role: "region", "aria-label": fillLabel(labels.valueFor, { version: labels[version], path: entry.path }), children: [
|
|
12935
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("strong", { children: labels[version] }),
|
|
12936
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("pre", { children: renderValue(entry[version], labels.notPresent) })
|
|
12083
12937
|
] }, version)) }),
|
|
12084
|
-
/* @__PURE__ */ (0,
|
|
12085
|
-
/* @__PURE__ */ (0,
|
|
12086
|
-
/* @__PURE__ */ (0,
|
|
12087
|
-
/* @__PURE__ */ (0,
|
|
12938
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: "uix-diff-viewer__actions", role: "group", "aria-label": fillLabel(labels.resolve, { path: entry.path }), children: [
|
|
12939
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("button", { type: "button", className: cx("uix-btn uix-btn--primary", buttonSize), "aria-label": fillLabel(labels.acceptIncomingFor, { path: entry.path }), "aria-pressed": resolution === "accept", onClick: () => resolve(entry.path, "accept"), children: labels.acceptIncoming }),
|
|
12940
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("button", { type: "button", className: cx("uix-btn uix-btn--secondary", buttonSize), "aria-label": fillLabel(labels.keepCurrentFor, { path: entry.path }), "aria-pressed": resolution === "skip", onClick: () => resolve(entry.path, "skip"), children: labels.keepCurrent }),
|
|
12941
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("button", { type: "button", className: cx("uix-btn uix-btn--ghost", buttonSize), "aria-label": fillLabel(labels.markPendingFor, { path: entry.path }), "aria-pressed": resolution === "pending", onClick: () => resolve(entry.path, "pending"), children: labels.markPending })
|
|
12088
12942
|
] })
|
|
12089
12943
|
] }, entry.path);
|
|
12090
12944
|
})
|
|
12091
12945
|
] }, kind);
|
|
12092
12946
|
}),
|
|
12093
|
-
/* @__PURE__ */ (0,
|
|
12947
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("p", { className: "uix-visually-hidden", "aria-live": "polite", children: fillLabel(labels.progress, { resolved: summary.resolved, total: entries.length }) })
|
|
12094
12948
|
] });
|
|
12095
12949
|
}
|
|
12096
12950
|
|
|
12097
12951
|
// src/components/TextDiff.tsx
|
|
12098
|
-
var
|
|
12952
|
+
var import_react70 = require("react");
|
|
12099
12953
|
|
|
12100
12954
|
// src/text-diff-model.ts
|
|
12101
12955
|
var WORD_TOKENS = /\s+|[\p{L}\p{M}\p{N}_]+|[^\s\p{L}\p{M}\p{N}_]/gu;
|
|
@@ -12355,7 +13209,7 @@ function textDiffRows(result, { context } = {}) {
|
|
|
12355
13209
|
}
|
|
12356
13210
|
|
|
12357
13211
|
// src/components/TextDiff.tsx
|
|
12358
|
-
var
|
|
13212
|
+
var import_jsx_runtime98 = require("react/jsx-runtime");
|
|
12359
13213
|
var DEFAULT_TEXT_DIFF_LABELS = {
|
|
12360
13214
|
before: "Before",
|
|
12361
13215
|
after: "After",
|
|
@@ -12368,47 +13222,47 @@ var DEFAULT_TEXT_DIFF_LABELS = {
|
|
|
12368
13222
|
};
|
|
12369
13223
|
function Marked({ segments, side, labels, whole }) {
|
|
12370
13224
|
const Tag = side === "before" ? "del" : "ins";
|
|
12371
|
-
return /* @__PURE__ */ (0,
|
|
12372
|
-
/* @__PURE__ */ (0,
|
|
13225
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_jsx_runtime98.Fragment, { children: segments.map((segment, i) => segment.changed ? /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)(Tag, { "data-whole": whole || void 0, children: [
|
|
13226
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("span", { className: "uix-visually-hidden", children: [
|
|
12373
13227
|
side === "before" ? labels.removed : labels.added,
|
|
12374
13228
|
": "
|
|
12375
13229
|
] }),
|
|
12376
13230
|
segment.text
|
|
12377
|
-
] }, i) : /* @__PURE__ */ (0,
|
|
13231
|
+
] }, i) : /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_react70.Fragment, { children: segment.text }, i)) });
|
|
12378
13232
|
}
|
|
12379
13233
|
function Cell({ line, side, kind, labels }) {
|
|
12380
|
-
if (!line) return /* @__PURE__ */ (0,
|
|
13234
|
+
if (!line) return /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { className: "uix-text-diff__cell", "data-side": side, "data-empty": "", "aria-hidden": "true" });
|
|
12381
13235
|
const changed = kind !== "equal";
|
|
12382
|
-
return /* @__PURE__ */ (0,
|
|
12383
|
-
/* @__PURE__ */ (0,
|
|
12384
|
-
/* @__PURE__ */ (0,
|
|
12385
|
-
/* @__PURE__ */ (0,
|
|
13236
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("div", { className: "uix-text-diff__cell", "data-side": side, "data-kind": changed ? side === "before" ? "delete" : "insert" : "equal", children: [
|
|
13237
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("span", { className: "uix-text-diff__num", "aria-hidden": "true", children: line.number }),
|
|
13238
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("span", { className: "uix-text-diff__sign", "aria-hidden": "true", children: changed ? side === "before" ? "\u2212" : "+" : "" }),
|
|
13239
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("span", { className: "uix-text-diff__text", children: line.segments.length === 1 && line.segments[0].text === "" ? "\u200B" : /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(Marked, { segments: line.segments, side, labels, whole: line.segments.length === 1 }) })
|
|
12386
13240
|
] });
|
|
12387
13241
|
}
|
|
12388
13242
|
function Rows({ rows, view, labels, focusFirst }) {
|
|
12389
|
-
const [open, setOpen] = (0,
|
|
12390
|
-
const first = (0,
|
|
12391
|
-
(0,
|
|
13243
|
+
const [open, setOpen] = (0, import_react70.useState)(() => /* @__PURE__ */ new Set());
|
|
13244
|
+
const first = (0, import_react70.useRef)(null);
|
|
13245
|
+
(0, import_react70.useEffect)(() => {
|
|
12392
13246
|
if (focusFirst) first.current?.focus();
|
|
12393
13247
|
}, [focusFirst]);
|
|
12394
13248
|
const firstProps = (index) => focusFirst && index === 0 ? { ref: first, tabIndex: -1 } : {};
|
|
12395
|
-
return /* @__PURE__ */ (0,
|
|
13249
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_jsx_runtime98.Fragment, { children: rows.map((row, index) => {
|
|
12396
13250
|
if (row.kind === "fold") {
|
|
12397
|
-
if (open.has(index)) return /* @__PURE__ */ (0,
|
|
12398
|
-
return /* @__PURE__ */ (0,
|
|
13251
|
+
if (open.has(index)) return /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(Rows, { rows: row.rows, view, labels, focusFirst: true }, index);
|
|
13252
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { className: "uix-text-diff__row", "data-kind": "fold", children: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("button", { type: "button", className: "uix-text-diff__fold", onClick: () => setOpen((s) => new Set(s).add(index)), children: fillLabel(labels.showUnchanged, { count: row.count }) }) }, index);
|
|
12399
13253
|
}
|
|
12400
13254
|
const before = row.kind === "insert" ? void 0 : row.before;
|
|
12401
13255
|
const after = row.kind === "delete" ? void 0 : row.after;
|
|
12402
13256
|
if (view === "unified") {
|
|
12403
|
-
if (row.kind === "equal") return /* @__PURE__ */ (0,
|
|
12404
|
-
return /* @__PURE__ */ (0,
|
|
12405
|
-
before && /* @__PURE__ */ (0,
|
|
12406
|
-
after && /* @__PURE__ */ (0,
|
|
13257
|
+
if (row.kind === "equal") return /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { className: "uix-text-diff__row", "data-kind": "equal", ...firstProps(index), children: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(Cell, { line: after, side: "after", kind: "equal", labels }) }, index);
|
|
13258
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)(import_react70.Fragment, { children: [
|
|
13259
|
+
before && /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { className: "uix-text-diff__row", "data-kind": "delete", children: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(Cell, { line: before, side: "before", kind: row.kind, labels }) }),
|
|
13260
|
+
after && /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { className: "uix-text-diff__row", "data-kind": "insert", children: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(Cell, { line: after, side: "after", kind: row.kind, labels }) })
|
|
12407
13261
|
] }, index);
|
|
12408
13262
|
}
|
|
12409
|
-
return /* @__PURE__ */ (0,
|
|
12410
|
-
/* @__PURE__ */ (0,
|
|
12411
|
-
/* @__PURE__ */ (0,
|
|
13263
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("div", { className: "uix-text-diff__row", "data-kind": row.kind, ...firstProps(index), children: [
|
|
13264
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)(Cell, { line: before, side: "before", kind: row.kind, labels }),
|
|
13265
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)(Cell, { line: after, side: "after", kind: row.kind, labels })
|
|
12412
13266
|
] }, index);
|
|
12413
13267
|
}) });
|
|
12414
13268
|
}
|
|
@@ -12430,41 +13284,41 @@ function TextDiff({
|
|
|
12430
13284
|
}) {
|
|
12431
13285
|
const uixLabels = useUixLabels();
|
|
12432
13286
|
const labels = { ...DEFAULT_TEXT_DIFF_LABELS, ...uixLabels.textDiff, ...labelOverrides };
|
|
12433
|
-
const result = (0,
|
|
12434
|
-
const rows = (0,
|
|
12435
|
-
const heads = /* @__PURE__ */ (0,
|
|
12436
|
-
/* @__PURE__ */ (0,
|
|
12437
|
-
view === "unified" && /* @__PURE__ */ (0,
|
|
13287
|
+
const result = (0, import_react70.useMemo)(() => diffText(before, after, { granularity, maxTokens, maxEdits }), [before, after, granularity, maxTokens, maxEdits]);
|
|
13288
|
+
const rows = (0, import_react70.useMemo)(() => granularity === "line" && result.status === "ok" ? textDiffRows(result, { context }) : [], [result, granularity, context]);
|
|
13289
|
+
const heads = /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("div", { className: "uix-text-diff__heads", "aria-hidden": view === "unified" || void 0, children: [
|
|
13290
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("span", { className: "uix-text-diff__head", "data-side": "before", children: [
|
|
13291
|
+
view === "unified" && /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("span", { "aria-hidden": "true", children: "\u2212 " }),
|
|
12438
13292
|
beforeLabel ?? labels.before
|
|
12439
13293
|
] }),
|
|
12440
|
-
/* @__PURE__ */ (0,
|
|
12441
|
-
view === "unified" && /* @__PURE__ */ (0,
|
|
13294
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("span", { className: "uix-text-diff__head", "data-side": "after", children: [
|
|
13295
|
+
view === "unified" && /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("span", { "aria-hidden": "true", children: "+ " }),
|
|
12442
13296
|
afterLabel ?? labels.after
|
|
12443
13297
|
] })
|
|
12444
13298
|
] });
|
|
12445
13299
|
const unchanged = result.status === "ok" && result.added === 0 && result.removed === 0 && result.ops.every((op) => op.type === "equal");
|
|
12446
13300
|
let body;
|
|
12447
|
-
if (result.status === "too-large") body = /* @__PURE__ */ (0,
|
|
12448
|
-
else if (granularity === "line") body = /* @__PURE__ */ (0,
|
|
13301
|
+
if (result.status === "too-large") body = /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { className: "uix-text-diff__note", children: labels.tooLarge });
|
|
13302
|
+
else if (granularity === "line") body = /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { className: "uix-text-diff__body", children: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(Rows, { rows, view, labels }) });
|
|
12449
13303
|
else {
|
|
12450
|
-
const prose = (side2) => /* @__PURE__ */ (0,
|
|
13304
|
+
const prose = (side2) => /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { className: "uix-text-diff__prose", "data-side": side2, children: result.ops.map((op, i) => {
|
|
12451
13305
|
const text = op.tokens.join("");
|
|
12452
|
-
if (op.type === "equal") return /* @__PURE__ */ (0,
|
|
13306
|
+
if (op.type === "equal") return /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(import_react70.Fragment, { children: text }, i);
|
|
12453
13307
|
if (op.type === "delete" && side2 === "after") return null;
|
|
12454
13308
|
if (op.type === "insert" && side2 === "before") return null;
|
|
12455
|
-
return /* @__PURE__ */ (0,
|
|
13309
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(Marked, { segments: [{ text, changed: true }], side: op.type === "delete" ? "before" : "after", labels }, i);
|
|
12456
13310
|
}) });
|
|
12457
|
-
const side = (which) => /* @__PURE__ */ (0,
|
|
12458
|
-
/* @__PURE__ */ (0,
|
|
13311
|
+
const side = (which) => /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("div", { className: "uix-text-diff__side", children: [
|
|
13312
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { className: "uix-text-diff__head", children: which === "before" ? beforeLabel ?? labels.before : afterLabel ?? labels.after }),
|
|
12459
13313
|
prose(which)
|
|
12460
13314
|
] });
|
|
12461
|
-
body = /* @__PURE__ */ (0,
|
|
13315
|
+
body = /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { className: "uix-text-diff__body", children: view === "unified" ? prose("both") : /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("div", { className: "uix-text-diff__row", "data-kind": "prose", children: [
|
|
12462
13316
|
side("before"),
|
|
12463
13317
|
side("after")
|
|
12464
13318
|
] }) });
|
|
12465
13319
|
}
|
|
12466
|
-
return /* @__PURE__ */ (0,
|
|
12467
|
-
!hideSummary && result.status === "ok" && /* @__PURE__ */ (0,
|
|
13320
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("div", { role: "group", "aria-label": label, className: cx("uix-text-diff", className), "data-view": view, "data-granularity": granularity, ...props, children: [
|
|
13321
|
+
!hideSummary && result.status === "ok" && /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { className: "uix-text-diff__summary", children: unchanged ? labels.noChanges : fillLabel(labels.summary, { added: result.added, removed: result.removed }) }),
|
|
12468
13322
|
!(granularity === "word" && view === "split" && result.status === "ok") && heads,
|
|
12469
13323
|
body
|
|
12470
13324
|
] });
|
|
@@ -12641,6 +13495,7 @@ function TextDiff({
|
|
|
12641
13495
|
Switch,
|
|
12642
13496
|
TEXT_FILTER_OPERATORS,
|
|
12643
13497
|
TOAST_LEAVE_MS,
|
|
13498
|
+
TOP_LANE_CROSS_MIDNIGHT_MINUTES,
|
|
12644
13499
|
Tab,
|
|
12645
13500
|
TabPanel,
|
|
12646
13501
|
Table,
|
|
@@ -12705,10 +13560,12 @@ function TextDiff({
|
|
|
12705
13560
|
isRuleGroup,
|
|
12706
13561
|
itemDaySpan,
|
|
12707
13562
|
layeredNeighbor,
|
|
13563
|
+
layoutDaySpans,
|
|
12708
13564
|
layoutLane,
|
|
12709
13565
|
layoutLayeredGraph,
|
|
12710
13566
|
layoutMonthSpans,
|
|
12711
13567
|
layoutRelationshipGraph,
|
|
13568
|
+
layoutTimeGridDay,
|
|
12712
13569
|
mapRuleGroup,
|
|
12713
13570
|
matchFilter,
|
|
12714
13571
|
matchFilterPreset,
|
|
@@ -12725,6 +13582,8 @@ function TextDiff({
|
|
|
12725
13582
|
partitionFiles,
|
|
12726
13583
|
pixelsToMs,
|
|
12727
13584
|
placeSpan,
|
|
13585
|
+
placesInTopLane,
|
|
13586
|
+
proposeMove,
|
|
12728
13587
|
rankOverflow,
|
|
12729
13588
|
relationshipNeighbors,
|
|
12730
13589
|
relativeTimeValue,
|