@fayz-ai/plugin-agenda 0.23.4 → 0.24.1
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/dist/data/supabase.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +221 -10
- package/dist/index.js.map +1 -1
- package/dist/lib/agenda-url.d.ts +14 -0
- package/dist/lib/agenda-url.d.ts.map +1 -0
- package/dist/styles/calendar-styles.d.ts.map +1 -1
- package/dist/views/CalendarView.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../src/data/supabase.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAM/B,MAAM,SAAS,CAAA;AAubhB,MAAM,WAAW,6BAA6B;IAC5C,uGAAuG;IACvG,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AA8ED,wBAAgB,4BAA4B,CAAC,eAAe,CAAC,EAAE,6BAA6B,GAAG,kBAAkB,
|
|
1
|
+
{"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../src/data/supabase.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAM/B,MAAM,SAAS,CAAA;AAubhB,MAAM,WAAW,6BAA6B;IAC5C,uGAAuG;IACvG,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AA8ED,wBAAgB,4BAA4B,CAAC,eAAe,CAAC,EAAE,6BAA6B,GAAG,kBAAkB,CA6pDhH"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAInD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAoBnD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAA;AACrE,OAAO,EAAE,2BAA2B,EAAE,+BAA+B,EAAE,MAAM,mBAAmB,CAAA;AAChG,YAAY,EACV,4BAA4B,EAC5B,0BAA0B,EAC1B,2BAA2B,EAC3B,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,eAAe,GAChB,MAAM,yBAAyB,CAAA;AAMhC,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAInD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAoBnD,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAA;AACrE,OAAO,EAAE,2BAA2B,EAAE,+BAA+B,EAAE,MAAM,mBAAmB,CAAA;AAChG,YAAY,EACV,4BAA4B,EAC5B,0BAA0B,EAC1B,2BAA2B,EAC3B,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,eAAe,GAChB,MAAM,yBAAyB,CAAA;AAMhC,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,cAAc,CAgfhF;AAGD,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AACnD,YAAY,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AACpD,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAGtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AACtD,YAAY,EAAE,cAAc,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAC5E,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAA;AAC1I,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAA;AAGlG,OAAO,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,uBAAuB,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;AAIvK,OAAO,EAAE,uBAAuB,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { createMockAgendaProvider, createSupabasePublicBookingProvider } from '.
|
|
|
2
2
|
export { createMockAgendaProvider } from './chunk-A77PUFY5.js';
|
|
3
3
|
import React23, { useState, useEffect, useRef, useMemo, useCallback, useLayoutEffect } from 'react';
|
|
4
4
|
import { tl, recordRailFields, RECORD_GROUP, activeFacet, connectionStatus, createConnectionStore, getActiveTenantId, createSafeDataProvider, todayLocal, getSupabaseClientOptional, registerTranslations, registerMessageDefaults, connectorRuntimeToken, CONNECTOR_RUNTIME_TOKEN_HEADER, getActiveUnitId, assertWrote, emitDataChanged, globalCache, usePluginRuntimeOptional, useTranslation, useActiveUnitId, emitDomainEvent, getCurrentLocale, localDateKey, useDataChanged, describeError, formatCurrency, resolveDataProvider } from '@fayz-ai/core';
|
|
5
|
-
import { createPluginContext, fayzConnectorOAuth, UNIT_DETAIL_ZONES, setScheduleBlockConfig, getScheduleBlockConfig, registerPersonActions, PluginSettingsPanel, adminNavigateTo, createArchetypeLookup, dedup, usePluginPrefs, PersonLink, useTenantPluginSettings, SettingsGroup, ToggleRow, SelectRow, usePermissionOptional, PageActions, useRightRailStore, useFieldRules, deriveEntityKey, openEntity, ScheduleEditor, useLimitGuard, useLookupCreate, CrudFormPage, CrudDetailPage, ContactPicker, PaymentStatusBadge as PaymentStatusBadge$1, RightRailPage, invalidateLimit } from '@fayz-ai/admin';
|
|
5
|
+
import { createPluginContext, fayzConnectorOAuth, UNIT_DETAIL_ZONES, setScheduleBlockConfig, getScheduleBlockConfig, registerPersonActions, PluginSettingsPanel, adminNavigateTo, createArchetypeLookup, dedup, usePluginPrefs, PersonLink, useTenantPluginSettings, SettingsGroup, ToggleRow, SelectRow, usePermissionOptional, useAdminPath, PageActions, useRightRailStore, useFieldRules, deriveEntityKey, openEntity, ScheduleEditor, useLimitGuard, useLookupCreate, CrudFormPage, CrudDetailPage, ContactPicker, PaymentStatusBadge as PaymentStatusBadge$1, RightRailPage, invalidateLimit } from '@fayz-ai/admin';
|
|
6
6
|
import FullCalendar from '@fullcalendar/react';
|
|
7
7
|
import dayGridPlugin from '@fullcalendar/daygrid';
|
|
8
8
|
import timeGridPlugin from '@fullcalendar/timegrid';
|
|
@@ -677,6 +677,42 @@ var css = (
|
|
|
677
677
|
text-transform: none;
|
|
678
678
|
letter-spacing: 0;
|
|
679
679
|
}
|
|
680
|
+
|
|
681
|
+
/* The day header fills its column, so a holiday name ellipses inside it
|
|
682
|
+
instead of pushing the day out. */
|
|
683
|
+
.agenda-calendar .fc-col-header-cell[data-date] .fc-col-header-cell-cushion {
|
|
684
|
+
display: block;
|
|
685
|
+
max-width: 100%;
|
|
686
|
+
overflow: hidden;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
/* A day of the week opens that day. */
|
|
690
|
+
.agenda-calendar .agenda-day-link {
|
|
691
|
+
cursor: pointer;
|
|
692
|
+
border-radius: 0.5rem;
|
|
693
|
+
padding: 2px 4px;
|
|
694
|
+
transition: background-color 120ms ease-out;
|
|
695
|
+
}
|
|
696
|
+
.agenda-calendar .agenda-day-link:hover,
|
|
697
|
+
.agenda-calendar .agenda-day-link:focus-visible {
|
|
698
|
+
background: hsl(var(--foreground) / 0.07);
|
|
699
|
+
outline: none;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
/* No schedule in the period: the whole grid reads as closed, in the same
|
|
703
|
+
hatch as time outside a schedule \u2014 a blank grid looks bookable. On the slot
|
|
704
|
+
rows, because with no schedule there may be no column to paint. */
|
|
705
|
+
.agenda-calendar.agenda-unscheduled .fc-timegrid-slots td.fc-timegrid-slot-lane {
|
|
706
|
+
background-color: hsl(var(--muted-foreground) / 0.2);
|
|
707
|
+
background-image: repeating-linear-gradient(
|
|
708
|
+
45deg,
|
|
709
|
+
transparent,
|
|
710
|
+
transparent 4px,
|
|
711
|
+
hsl(var(--muted-foreground) / 0.12) 4px,
|
|
712
|
+
hsl(var(--muted-foreground) / 0.12) 8px
|
|
713
|
+
);
|
|
714
|
+
background-attachment: fixed;
|
|
715
|
+
}
|
|
680
716
|
`
|
|
681
717
|
);
|
|
682
718
|
var injected = false;
|
|
@@ -695,6 +731,38 @@ function injectCalendarStyles() {
|
|
|
695
731
|
document.head.appendChild(style);
|
|
696
732
|
injected = true;
|
|
697
733
|
}
|
|
734
|
+
|
|
735
|
+
// src/lib/agenda-url.ts
|
|
736
|
+
var VIEWS = ["day", "week", "month", "list"];
|
|
737
|
+
function parseAgendaPath(path) {
|
|
738
|
+
const parts = (path.split("?")[0] ?? "").split("/").filter(Boolean);
|
|
739
|
+
if (parts[0] !== "agenda") return null;
|
|
740
|
+
const view = parts[1];
|
|
741
|
+
if (!view || !VIEWS.includes(view)) return null;
|
|
742
|
+
if (parts.length === 2) return { view };
|
|
743
|
+
if (parts.length !== 5) return null;
|
|
744
|
+
const [y, m, d] = parts.slice(2).map(Number);
|
|
745
|
+
const date = new Date(y, m - 1, d);
|
|
746
|
+
if (date.getFullYear() !== y || date.getMonth() !== m - 1 || date.getDate() !== d) return null;
|
|
747
|
+
return { view, date };
|
|
748
|
+
}
|
|
749
|
+
function agendaPath(view, date) {
|
|
750
|
+
if (!date) return `/agenda/${view}`;
|
|
751
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
752
|
+
return `/agenda/${view}/${date.getFullYear()}/${pad(date.getMonth() + 1)}/${pad(date.getDate())}`;
|
|
753
|
+
}
|
|
754
|
+
function urlViewOf(viewType) {
|
|
755
|
+
if (viewType.startsWith("list")) return "list";
|
|
756
|
+
if (viewType.endsWith("Day")) return "day";
|
|
757
|
+
if (viewType.endsWith("Week")) return "week";
|
|
758
|
+
return "month";
|
|
759
|
+
}
|
|
760
|
+
function calendarViewFor(view, resourceCapable) {
|
|
761
|
+
if (view === "day") return resourceCapable ? "resourceTimeGridDay" : "timeGridDay";
|
|
762
|
+
if (view === "week") return resourceCapable ? "resourceTimeGridWeek" : "timeGridWeek";
|
|
763
|
+
if (view === "list") return resourceCapable ? "listWeek" : "listMonth";
|
|
764
|
+
return "dayGridMonth";
|
|
765
|
+
}
|
|
698
766
|
var DEFAULTS = {
|
|
699
767
|
startTime: "07:00",
|
|
700
768
|
endTime: "21:00"
|
|
@@ -4428,7 +4496,9 @@ function CalendarView() {
|
|
|
4428
4496
|
// Como a SEMANA se agrupa: 'day' põe o dia em cima e as pessoas dentro
|
|
4429
4497
|
// dele; 'professional' inverte. 'auto' é o padrão e deixa a agenda decidir
|
|
4430
4498
|
// pelo tamanho da equipe — ver `weekGrouping` mais abaixo.
|
|
4431
|
-
weekGrouping: "auto"
|
|
4499
|
+
weekGrouping: "auto",
|
|
4500
|
+
// Which weekdays the WEEK draws: 'auto', or the shown days (0 = Sunday) — see `shownWeekDays`.
|
|
4501
|
+
weekDays: "auto"
|
|
4432
4502
|
});
|
|
4433
4503
|
const weekGroupingPref = prefs.get("weekGrouping") ?? "auto";
|
|
4434
4504
|
const agendaSettings = useAgendaSettings();
|
|
@@ -4549,6 +4619,16 @@ function CalendarView() {
|
|
|
4549
4619
|
const days2 = /* @__PURE__ */ new Set();
|
|
4550
4620
|
const cursor = new Date(visibleRange.start);
|
|
4551
4621
|
const end = new Date(visibleRange.end);
|
|
4622
|
+
if (currentView.endsWith("Week")) {
|
|
4623
|
+
cursor.setDate(cursor.getDate() - cursor.getDay());
|
|
4624
|
+
end.setTime(cursor.getTime());
|
|
4625
|
+
end.setDate(end.getDate() + 7);
|
|
4626
|
+
return {
|
|
4627
|
+
daysOfWeek: [0, 1, 2, 3, 4, 5, 6],
|
|
4628
|
+
from: localDateKey(cursor),
|
|
4629
|
+
to: localDateKey(end)
|
|
4630
|
+
};
|
|
4631
|
+
}
|
|
4552
4632
|
for (let i = 0; cursor < end && i < 62; i++) {
|
|
4553
4633
|
days2.add(cursor.getDay());
|
|
4554
4634
|
cursor.setDate(cursor.getDate() + 1);
|
|
@@ -4558,7 +4638,7 @@ function CalendarView() {
|
|
|
4558
4638
|
from: visibleRange.start.slice(0, 10),
|
|
4559
4639
|
to: visibleRange.end.slice(0, 10)
|
|
4560
4640
|
};
|
|
4561
|
-
}, [visibleRange]);
|
|
4641
|
+
}, [visibleRange, currentView]);
|
|
4562
4642
|
const wantedSchedulesKey = useMemo(
|
|
4563
4643
|
() => scheduleQuery ? "agenda:schedules:" + JSON.stringify(scheduleQuery) : null,
|
|
4564
4644
|
[scheduleQuery]
|
|
@@ -4633,6 +4713,37 @@ function CalendarView() {
|
|
|
4633
4713
|
const rows = scheduleIndex.get(profId);
|
|
4634
4714
|
return !!rows && opensOnDate(rows, iso);
|
|
4635
4715
|
}, [scheduleIndex]);
|
|
4716
|
+
const weekDaysPref = prefs.get("weekDays");
|
|
4717
|
+
const lastAutoWeekDays = useRef("0123456");
|
|
4718
|
+
const shownWeekDaysKey = useMemo(() => {
|
|
4719
|
+
const all = [0, 1, 2, 3, 4, 5, 6];
|
|
4720
|
+
if (Array.isArray(weekDaysPref)) {
|
|
4721
|
+
const chosen = all.filter((d) => weekDaysPref.includes(d));
|
|
4722
|
+
return (chosen.length > 0 ? chosen : all).join("");
|
|
4723
|
+
}
|
|
4724
|
+
const settled = currentView.endsWith("Week") && !schedulesLoading && schedulesKey === wantedSchedulesKey;
|
|
4725
|
+
if (!settled) return lastAutoWeekDays.current;
|
|
4726
|
+
if (!visibleRange || scheduleIndex.size === 0) return lastAutoWeekDays.current = all.join("");
|
|
4727
|
+
const sunday = new Date(visibleRange.start);
|
|
4728
|
+
sunday.setDate(sunday.getDate() - sunday.getDay());
|
|
4729
|
+
const works = (dow2) => {
|
|
4730
|
+
const day = new Date(sunday);
|
|
4731
|
+
day.setDate(day.getDate() + dow2);
|
|
4732
|
+
const iso = localDateKey(day);
|
|
4733
|
+
for (const [profId] of scheduleIndex) if (opensOn(profId, iso, dow2)) return true;
|
|
4734
|
+
return false;
|
|
4735
|
+
};
|
|
4736
|
+
return lastAutoWeekDays.current = all.filter((d) => d !== 0 && d !== 6 || works(d)).join("");
|
|
4737
|
+
}, [weekDaysPref, visibleRange, scheduleIndex, opensOn, currentView, schedulesLoading, schedulesKey, wantedSchedulesKey]);
|
|
4738
|
+
const shownWeekDays = useMemo(() => shownWeekDaysKey.split("").map(Number), [shownWeekDaysKey]);
|
|
4739
|
+
const weekViewOptions = useMemo(() => {
|
|
4740
|
+
const hiddenDays = [0, 1, 2, 3, 4, 5, 6].filter((d) => !shownWeekDays.includes(d));
|
|
4741
|
+
return { resourceTimeGridWeek: { hiddenDays }, timeGridWeek: { hiddenDays } };
|
|
4742
|
+
}, [shownWeekDays]);
|
|
4743
|
+
const toggleWeekDay = useCallback((dow2) => {
|
|
4744
|
+
const next = shownWeekDays.includes(dow2) ? shownWeekDays.filter((d) => d !== dow2) : [...shownWeekDays, dow2].sort();
|
|
4745
|
+
if (next.length > 0) prefs.set("weekDays", next);
|
|
4746
|
+
}, [shownWeekDays, prefs]);
|
|
4636
4747
|
const relevantProfIds = useMemo(() => {
|
|
4637
4748
|
const ids = /* @__PURE__ */ new Set();
|
|
4638
4749
|
for (const [profId] of scheduleIndex) {
|
|
@@ -4911,13 +5022,49 @@ function CalendarView() {
|
|
|
4911
5022
|
return [...bookingEvents, ...disponibilidade, ...blockEvents];
|
|
4912
5023
|
}, [bookingEvents, availabilityEvents, blockEvents, currentView]);
|
|
4913
5024
|
const storedView = prefs.get("calendarView");
|
|
4914
|
-
const
|
|
5025
|
+
const adminPath = useAdminPath();
|
|
5026
|
+
const urlTarget = useMemo(() => parseAgendaPath(adminPath), [adminPath]);
|
|
5027
|
+
const effectiveInitialView = urlTarget ? calendarViewFor(urlTarget.view, resourceCapable) : resourceCapable ? viewForResources(storedView) : viewForNoResources(storedView);
|
|
4915
5028
|
const handleDatesSet = useCallback((arg) => {
|
|
4916
5029
|
setCalendarTitle(arg.view.title);
|
|
4917
5030
|
setView(arg.view.type);
|
|
4918
5031
|
setVisibleRange({ start: arg.startStr, end: arg.endStr });
|
|
4919
5032
|
fetchBookings({ start: arg.startStr, end: arg.endStr });
|
|
5033
|
+
const here = window.location.hash.replace(/^#/, "");
|
|
5034
|
+
if (parseAgendaPath(here)) {
|
|
5035
|
+
const api = calendarRef.current?.getApi();
|
|
5036
|
+
const next = agendaPath(urlViewOf(arg.view.type), api?.getDate());
|
|
5037
|
+
if (next !== here) {
|
|
5038
|
+
try {
|
|
5039
|
+
window.history.replaceState(null, "", `#${next}`);
|
|
5040
|
+
} catch {
|
|
5041
|
+
}
|
|
5042
|
+
}
|
|
5043
|
+
}
|
|
4920
5044
|
}, [fetchBookings, setView]);
|
|
5045
|
+
useEffect(() => {
|
|
5046
|
+
if (!urlTarget) return;
|
|
5047
|
+
const api = calendarRef.current?.getApi();
|
|
5048
|
+
if (!api) return;
|
|
5049
|
+
const view = calendarViewFor(urlTarget.view, resourceCapable);
|
|
5050
|
+
const sameDay = !urlTarget.date || api.getDate().toDateString() === urlTarget.date.toDateString();
|
|
5051
|
+
if (api.view.type === view && sameDay) return;
|
|
5052
|
+
api.changeView(view);
|
|
5053
|
+
if (urlTarget.date) {
|
|
5054
|
+
api.gotoDate(urlTarget.date);
|
|
5055
|
+
setSelectedDate(urlTarget.date);
|
|
5056
|
+
}
|
|
5057
|
+
}, [urlTarget, resourceCapable]);
|
|
5058
|
+
const openDay = useCallback((date) => {
|
|
5059
|
+
const api = calendarRef.current?.getApi();
|
|
5060
|
+
if (api && !parseAgendaPath(window.location.hash.replace(/^#/, ""))) {
|
|
5061
|
+
try {
|
|
5062
|
+
window.history.replaceState(null, "", `#${agendaPath(urlViewOf(api.view.type), api.getDate())}`);
|
|
5063
|
+
} catch {
|
|
5064
|
+
}
|
|
5065
|
+
}
|
|
5066
|
+
adminNavigateTo(agendaPath("day", date));
|
|
5067
|
+
}, []);
|
|
4921
5068
|
const handleEventDidMount = useCallback((arg) => {
|
|
4922
5069
|
const booking = arg.event.extendedProps?.booking;
|
|
4923
5070
|
if (booking) arg.el.setAttribute("data-booking-id", booking.id);
|
|
@@ -5266,11 +5413,23 @@ function CalendarView() {
|
|
|
5266
5413
|
const iso = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
|
|
5267
5414
|
const noMes = arg.view?.type === "dayGridMonth";
|
|
5268
5415
|
const feriado = noMes ? void 0 : holidayByDate.get(iso);
|
|
5269
|
-
const wrapStyle = { display: "flex", flexDirection: "column", alignItems: "center", lineHeight: 1.15, maxWidth: "100%", minWidth: 0 };
|
|
5416
|
+
const wrapStyle = { display: "flex", flexDirection: "column", alignItems: "center", lineHeight: 1.15, width: "fit-content", maxWidth: "100%", minWidth: 0, margin: "0 auto", boxSizing: "border-box" };
|
|
5417
|
+
const dayLink = String(arg.view?.type ?? "").endsWith("Week") ? {
|
|
5418
|
+
role: "link",
|
|
5419
|
+
tabIndex: 0,
|
|
5420
|
+
className: "agenda-day-link",
|
|
5421
|
+
onClick: () => openDay(date),
|
|
5422
|
+
onKeyDown: (e) => {
|
|
5423
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
5424
|
+
e.preventDefault();
|
|
5425
|
+
openDay(date);
|
|
5426
|
+
}
|
|
5427
|
+
}
|
|
5428
|
+
} : {};
|
|
5270
5429
|
const dateStyle = { fontSize: "0.65rem", opacity: 0.75 };
|
|
5271
5430
|
if (dayHeaderCompact) {
|
|
5272
5431
|
const letter = date.toLocaleDateString(dateLocale, { weekday: "narrow" });
|
|
5273
|
-
return /* @__PURE__ */ jsxs("div", { style: wrapStyle, title: feriado ? feriado.names.join(" \xB7 ") : void 0, children: [
|
|
5432
|
+
return /* @__PURE__ */ jsxs("div", { style: wrapStyle, title: feriado ? feriado.names.join(" \xB7 ") : void 0, ...dayLink, children: [
|
|
5274
5433
|
/* @__PURE__ */ jsx("span", { style: { fontWeight: 600 }, children: letter }),
|
|
5275
5434
|
/* @__PURE__ */ jsx("span", { style: dateStyle, children: date.getDate() }),
|
|
5276
5435
|
feriado && /* @__PURE__ */ jsx(
|
|
@@ -5291,7 +5450,7 @@ function CalendarView() {
|
|
|
5291
5450
|
const weekday = date.toLocaleDateString(dateLocale, { weekday: "short" });
|
|
5292
5451
|
if (noMes) return /* @__PURE__ */ jsx("div", { style: wrapStyle, children: /* @__PURE__ */ jsx("span", { children: arg.text }) });
|
|
5293
5452
|
const diaMes = date.toLocaleDateString(dateLocale, { day: "numeric", month: "numeric" });
|
|
5294
|
-
return /* @__PURE__ */ jsxs("div", { style: wrapStyle, children: [
|
|
5453
|
+
return /* @__PURE__ */ jsxs("div", { style: wrapStyle, ...dayLink, children: [
|
|
5295
5454
|
/* @__PURE__ */ jsx("span", { children: weekday }),
|
|
5296
5455
|
/* @__PURE__ */ jsx("span", { style: dateStyle, children: diaMes }),
|
|
5297
5456
|
feriado && /* @__PURE__ */ jsxs(
|
|
@@ -5316,7 +5475,7 @@ function CalendarView() {
|
|
|
5316
5475
|
}
|
|
5317
5476
|
)
|
|
5318
5477
|
] });
|
|
5319
|
-
}, [dayHeaderCompact, currentLocale, holidayByDate]);
|
|
5478
|
+
}, [dayHeaderCompact, currentLocale, holidayByDate, openDay]);
|
|
5320
5479
|
const dayCellContent = useCallback((arg) => {
|
|
5321
5480
|
const date = arg.date;
|
|
5322
5481
|
const pad = (n) => String(n).padStart(2, "0");
|
|
@@ -5524,6 +5683,43 @@ function CalendarView() {
|
|
|
5524
5683
|
}
|
|
5525
5684
|
)
|
|
5526
5685
|
},
|
|
5686
|
+
{
|
|
5687
|
+
id: "week-days",
|
|
5688
|
+
title: "Dias da semana",
|
|
5689
|
+
// A choice away from the automatic one is something in force.
|
|
5690
|
+
count: Array.isArray(weekDaysPref) ? 1 : 0,
|
|
5691
|
+
hidden: !currentView.endsWith("Week") || currentView.startsWith("list"),
|
|
5692
|
+
defaultOpen: true,
|
|
5693
|
+
content: /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
5694
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-1", role: "group", "aria-label": "Dias que a semana mostra", children: [1, 2, 3, 4, 5, 6, 0].map((dow2) => {
|
|
5695
|
+
const on = shownWeekDays.includes(dow2);
|
|
5696
|
+
const name = new Date(2024, 0, 7 + dow2).toLocaleDateString(currentLocale === "pt-BR" ? "pt-BR" : "en", { weekday: "long" });
|
|
5697
|
+
return /* @__PURE__ */ jsx(
|
|
5698
|
+
"button",
|
|
5699
|
+
{
|
|
5700
|
+
type: "button",
|
|
5701
|
+
"aria-pressed": on,
|
|
5702
|
+
title: name,
|
|
5703
|
+
"aria-label": name,
|
|
5704
|
+
"data-testid": `week-day-${dow2}`,
|
|
5705
|
+
onClick: () => toggleWeekDay(dow2),
|
|
5706
|
+
className: `flex h-7 w-7 items-center justify-center rounded-full text-xs font-medium uppercase transition-colors ${on ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground hover:text-foreground"}`,
|
|
5707
|
+
children: name.charAt(0)
|
|
5708
|
+
},
|
|
5709
|
+
dow2
|
|
5710
|
+
);
|
|
5711
|
+
}) }),
|
|
5712
|
+
Array.isArray(weekDaysPref) && /* @__PURE__ */ jsx(
|
|
5713
|
+
"button",
|
|
5714
|
+
{
|
|
5715
|
+
type: "button",
|
|
5716
|
+
onClick: () => prefs.set("weekDays", "auto"),
|
|
5717
|
+
className: "text-xs text-muted-foreground underline-offset-2 hover:text-foreground hover:underline",
|
|
5718
|
+
children: "Voltar ao autom\xE1tico"
|
|
5719
|
+
}
|
|
5720
|
+
)
|
|
5721
|
+
] })
|
|
5722
|
+
},
|
|
5527
5723
|
{
|
|
5528
5724
|
id: "hide-empty",
|
|
5529
5725
|
title: t2("agenda.sidebar.hideEmptyGrids"),
|
|
@@ -5665,13 +5861,15 @@ function CalendarView() {
|
|
|
5665
5861
|
}
|
|
5666
5862
|
)
|
|
5667
5863
|
] }),
|
|
5668
|
-
/* @__PURE__ */ jsx("div", { ref: wrapperRef, className:
|
|
5864
|
+
/* @__PURE__ */ jsx("div", { ref: wrapperRef, className: `min-h-0 min-w-0 flex-1 overflow-x-auto overflow-y-hidden agenda-calendar${semGradeNoPeriodo ? " agenda-unscheduled" : ""}`, children: /* @__PURE__ */ jsx("div", { className: "h-full", style: gridMinWidth ? { minWidth: gridMinWidth } : void 0, children: /* @__PURE__ */ jsx(
|
|
5669
5865
|
FullCalendar,
|
|
5670
5866
|
{
|
|
5671
5867
|
ref: calendarRef,
|
|
5672
5868
|
plugins: [dayGridPlugin, timeGridPlugin, resourceTimeGridPlugin, interactionPlugin, listPlugin],
|
|
5673
5869
|
initialView: mobileGridActive ? mobileView : effectiveInitialView,
|
|
5870
|
+
initialDate: urlTarget?.date,
|
|
5674
5871
|
schedulerLicenseKey: "CC-Attribution-NonCommercial-NoDerivatives",
|
|
5872
|
+
views: weekViewOptions,
|
|
5675
5873
|
resources: resourceCapable ? columnsSettled ? resources : [] : void 0,
|
|
5676
5874
|
events,
|
|
5677
5875
|
headerToolbar: false,
|
|
@@ -7678,7 +7876,7 @@ function createSupabaseAgendaProvider(providerOptions) {
|
|
|
7678
7876
|
return { busyStarts, closedDates: Array.from(new Set(closedDates)) };
|
|
7679
7877
|
},
|
|
7680
7878
|
async updateBooking(id, data) {
|
|
7681
|
-
const { core } = getClients();
|
|
7879
|
+
const { core, pub } = getClients();
|
|
7682
7880
|
const { data: existing, error: existingErr } = await core.from("appointments").select("id, order_id, starts_at, assignee_id, unit_id, metadata").eq("id", id).single();
|
|
7683
7881
|
if (existingErr) throw existingErr;
|
|
7684
7882
|
const updates = {};
|
|
@@ -7746,6 +7944,10 @@ function createSupabaseAgendaProvider(providerOptions) {
|
|
|
7746
7944
|
const { error: itemErr } = await core.from("items").insert(items);
|
|
7747
7945
|
if (itemErr) throw itemErr;
|
|
7748
7946
|
}
|
|
7947
|
+
try {
|
|
7948
|
+
await pub.rpc("order_reconcile_receivable", { p_order_id: orderId });
|
|
7949
|
+
} catch {
|
|
7950
|
+
}
|
|
7749
7951
|
}
|
|
7750
7952
|
} else if (data.services) {
|
|
7751
7953
|
const tenantId = getTenantId();
|
|
@@ -22532,6 +22734,15 @@ function createAgendaPlugin(options) {
|
|
|
22532
22734
|
}
|
|
22533
22735
|
],
|
|
22534
22736
|
routes: [
|
|
22737
|
+
// The calendar's own links (/agenda/day/2026/10/15). Same screen and,
|
|
22738
|
+
// with the wildcard stripped, the same page key as /agenda — so moving
|
|
22739
|
+
// between a week and a day never remounts it.
|
|
22740
|
+
{
|
|
22741
|
+
path: "/agenda/*",
|
|
22742
|
+
component: PageComponent,
|
|
22743
|
+
fullBleed: true,
|
|
22744
|
+
permission: { feature: "agenda", action: "read" }
|
|
22745
|
+
},
|
|
22535
22746
|
{
|
|
22536
22747
|
path: "/agenda",
|
|
22537
22748
|
component: PageComponent,
|