@fayz-ai/plugin-workforce 0.2.17 → 0.3.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/dist/index.d.ts.map +1 -1
- package/dist/index.js +163 -123
- package/dist/index.js.map +1 -1
- package/dist/settings/v1-settings.d.ts +2 -0
- package/dist/settings/v1-settings.d.ts.map +1 -0
- package/dist/views/HrView.d.ts.map +1 -1
- package/dist/views/SchedulesView.d.ts.map +1 -1
- package/dist/views/TimeEntriesView.d.ts.map +1 -1
- package/package.json +4 -4
- package/dist/data/index.d.ts +0 -4
- package/dist/data/index.d.ts.map +0 -1
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,SAAS,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAEvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAIlD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAMzD;;;;GAIG;AACH,wBAAgB,2BAA2B,IAAI,qBAAqB,CAKnE;AAMD,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IACvC,OAAO,CAAC,EAAE;QACR,SAAS,CAAC,EAAE,OAAO,CAAA;QACnB,SAAS,CAAC,EAAE,OAAO,CAAA;QACnB,WAAW,CAAC,EAAE,OAAO,CAAA;QACrB,EAAE,CAAC,EAAE,OAAO,CAAA;QACZ,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,MAAM,CAAC,EAAE,OAAO,CAAA;QAChB,YAAY,CAAC,EAAE,OAAO,CAAA;KACvB,CAAA;IACD,MAAM,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAA;IACvC,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;IACjC,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,UAAU,CAAC,EAAE,UAAU,CAAA;IAEvB,sDAAsD;IACtD,YAAY,CAAC,EAAE,qBAAqB,CAAA;IAEpC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;0EACsE;IACtE,WAAW,CAAC,EAAE,SAAS,CAAA;IAEvB,sEAAsE;IACtE,WAAW,CAAC,EAAE,YAAY,CAAA;IAE1B;;;;;;;;;;;;OAYG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACvC;AAoBD;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;CAQQ,CAAA;AA4B3C,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAEvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAIlD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAMzD;;;;GAIG;AACH,wBAAgB,2BAA2B,IAAI,qBAAqB,CAKnE;AAMD,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IACvC,OAAO,CAAC,EAAE;QACR,SAAS,CAAC,EAAE,OAAO,CAAA;QACnB,SAAS,CAAC,EAAE,OAAO,CAAA;QACnB,WAAW,CAAC,EAAE,OAAO,CAAA;QACrB,EAAE,CAAC,EAAE,OAAO,CAAA;QACZ,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,MAAM,CAAC,EAAE,OAAO,CAAA;QAChB,YAAY,CAAC,EAAE,OAAO,CAAA;KACvB,CAAA;IACD,MAAM,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAA;IACvC,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;IACjC,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,UAAU,CAAC,EAAE,UAAU,CAAA;IAEvB,sDAAsD;IACtD,YAAY,CAAC,EAAE,qBAAqB,CAAA;IAEpC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;0EACsE;IACtE,WAAW,CAAC,EAAE,SAAS,CAAA;IAEvB,sEAAsE;IACtE,WAAW,CAAC,EAAE,YAAY,CAAA;IAE1B;;;;;;;;;;;;OAYG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACvC;AAoBD;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;CAQQ,CAAA;AA4B3C,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,cAAc,CAiItF;AAMD,YAAY,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AACzD,YAAY,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAA;AACxD,YAAY,EACV,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,oBAAoB,EAAE,mBAAmB,EACnF,OAAO,EAAE,eAAe,EACxB,gBAAgB,EAAE,aAAa,EAAE,mBAAmB,EACpD,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,mBAAmB,EACnE,eAAe,EAAE,cAAc,EAAE,gBAAgB,GAClD,MAAM,SAAS,CAAA;AAEhB,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EAAE,+BAA+B,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React3 from 'react';
|
|
2
|
-
import { recordRailFields, RECORD_GROUP, activeFacet, createSafeDataProvider, getSupabaseClientOptional, getActiveTenantId } from '@fayz-ai/core';
|
|
3
|
-
import { createPluginContext, saveSchedule, registerEntityPath, useModuleNavigation, useModuleNavAccess, parseViewId, EntitlementGate, UpgradePrompt, ScheduleEditor, usePermissionOptional, adminNavigateTo, formatCurrency, PersonLink, createCrudPage, WidgetSlot } from '@fayz-ai/admin';
|
|
4
|
-
import { ModulePage, FilterRail, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, MiniCalendar, toLocalISODate,
|
|
5
|
-
import { Send, CalendarDays, Plus, ExternalLink, HandCoins, AlertTriangle, Users, CalendarCheck, Unlock, Lock, Clock, LayoutTemplate, ListTree, UserPlus, UserMinus, CakeSlice, Plane, CalendarClock, ShieldAlert, Stethoscope, ClipboardList, FileText,
|
|
2
|
+
import { recordRailFields, RECORD_GROUP, activeFacet, tl, createSafeDataProvider, getSupabaseClientOptional, getActiveTenantId } from '@fayz-ai/core';
|
|
3
|
+
import { createPluginContext, defineSettingsTab, saveSchedule, registerEntityPath, useModuleNavigation, useModuleNavAccess, parseViewId, EntitlementGate, UpgradePrompt, ScheduleEditor, usePermissionOptional, adminNavigateTo, formatCurrency, PersonLink, createCrudPage, WidgetSlot } from '@fayz-ai/admin';
|
|
4
|
+
import { ModulePage, FilterRail, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, MiniCalendar, toLocalISODate, Badge, Button, Skeleton, resolveRangePreset, compareCodes, PageToolbar, DateRangeControl, StatTiles, StatementTable, PageSubNav, Modal, ModalContent, ModalHeader, ModalTitle, ModalBody, Input, ModalFooter, toast, Popover, PopoverTrigger, PopoverContent, Checkbox, Avatar, AvatarFallback, DataTable, AvatarImage } from '@fayz-ai/ui';
|
|
5
|
+
import { Send, CalendarDays, Plus, ExternalLink, HandCoins, AlertTriangle, Users, CalendarCheck, Unlock, Lock, Clock, LayoutTemplate, ListTree, UserPlus, UserMinus, CakeSlice, Plane, CalendarClock, ShieldAlert, Stethoscope, ClipboardList, FileText, Pencil, Eye, ChevronRight, Trash2, ImageOff, MapPin, ScanFace } from 'lucide-react';
|
|
6
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
7
|
import { createStore } from 'zustand/vanilla';
|
|
8
8
|
|
|
@@ -136,51 +136,54 @@ function SchedulesView() {
|
|
|
136
136
|
]
|
|
137
137
|
}
|
|
138
138
|
);
|
|
139
|
-
return /* @__PURE__ */
|
|
140
|
-
/* @__PURE__ */
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
/* @__PURE__ */ jsxs("
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
139
|
+
return /* @__PURE__ */ jsxs("div", { className: "grid gap-6 p-6 lg:grid-cols-[260px_minmax(0,1fr)]", children: [
|
|
140
|
+
/* @__PURE__ */ jsx("aside", { className: "self-start rounded-xl border border-border bg-card p-4", children: rail }),
|
|
141
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-4", children: [
|
|
142
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [
|
|
143
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
144
|
+
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: (/* @__PURE__ */ new Date(`${selectedDate}T12:00:00`)).toLocaleDateString("pt-BR", {
|
|
145
|
+
weekday: "long",
|
|
146
|
+
day: "2-digit",
|
|
147
|
+
month: "long"
|
|
148
|
+
}) }),
|
|
149
|
+
day && /* @__PURE__ */ jsxs("div", { className: "mt-1 flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
150
|
+
/* @__PURE__ */ jsx(Badge, { variant: day.status === "published" ? "success" : "warning", children: STATUS_LABEL[day.status] ?? day.status }),
|
|
151
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
152
|
+
titulares.length,
|
|
153
|
+
" titular(es) \xB7 ",
|
|
154
|
+
pendentes.length,
|
|
155
|
+
" pendente(s)"
|
|
156
|
+
] })
|
|
154
157
|
] })
|
|
158
|
+
] }),
|
|
159
|
+
day && day.status === "draft" && /* @__PURE__ */ jsxs(Button, { onClick: publish, disabled: busy, children: [
|
|
160
|
+
/* @__PURE__ */ jsx(Send, { className: "mr-2 h-4 w-4", "aria-hidden": true }),
|
|
161
|
+
"Publicar escala"
|
|
155
162
|
] })
|
|
156
163
|
] }),
|
|
157
|
-
|
|
158
|
-
/* @__PURE__ */ jsx(
|
|
159
|
-
"
|
|
160
|
-
] })
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
] }),
|
|
176
|
-
/* @__PURE__ */ jsxs(Button, { onClick: createFromTemplate, disabled: !templateId || busy, children: [
|
|
177
|
-
/* @__PURE__ */ jsx(Plus, { className: "mr-2 h-4 w-4", "aria-hidden": true }),
|
|
178
|
-
"Criar"
|
|
164
|
+
loading ? /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
165
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-12 w-full" }),
|
|
166
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-12 w-full" })
|
|
167
|
+
] }) : day ? /* @__PURE__ */ jsx("div", { className: "space-y-2", children: day.assignments.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Nenhuma vaga preenchida neste dia." }) : day.assignments.map((a) => /* @__PURE__ */ jsx(AssignmentRow, { assignment: a }, a.id)) }) : (
|
|
168
|
+
// O pré-requisito duro do V1, dito na tela em vez de escondido: sem
|
|
169
|
+
// molde não existe escala.
|
|
170
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-dashed border-border p-8 text-center", children: [
|
|
171
|
+
/* @__PURE__ */ jsx(CalendarDays, { className: "mx-auto mb-3 h-8 w-8 text-muted-foreground", "aria-hidden": true }),
|
|
172
|
+
/* @__PURE__ */ jsx("p", { className: "mb-4 text-sm text-muted-foreground", children: templates.length === 0 ? "Nenhum molde de escala cadastrado. Crie um em Templates para come\xE7ar." : "Ainda n\xE3o h\xE1 escala neste dia. Escolha um molde para mont\xE1-la." }),
|
|
173
|
+
templates.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mx-auto flex max-w-sm items-center gap-2", children: [
|
|
174
|
+
/* @__PURE__ */ jsxs(Select, { value: templateId, onValueChange: setTemplateId, children: [
|
|
175
|
+
/* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Molde de escala" }) }),
|
|
176
|
+
/* @__PURE__ */ jsx(SelectContent, { children: templates.map((t) => /* @__PURE__ */ jsx(SelectItem, { value: t.id, children: t.name }, t.id)) })
|
|
177
|
+
] }),
|
|
178
|
+
/* @__PURE__ */ jsxs(Button, { onClick: createFromTemplate, disabled: !templateId || busy, children: [
|
|
179
|
+
/* @__PURE__ */ jsx(Plus, { className: "mr-2 h-4 w-4", "aria-hidden": true }),
|
|
180
|
+
"Criar"
|
|
181
|
+
] })
|
|
179
182
|
] })
|
|
180
183
|
] })
|
|
181
|
-
|
|
182
|
-
)
|
|
183
|
-
] })
|
|
184
|
+
)
|
|
185
|
+
] })
|
|
186
|
+
] });
|
|
184
187
|
}
|
|
185
188
|
var WEEKDAYS = ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "S\xE1b"];
|
|
186
189
|
var WEEKDAY_NAMES = ["Domingo", "Segunda", "Ter\xE7a", "Quarta", "Quinta", "Sexta", "S\xE1bado"];
|
|
@@ -251,7 +254,7 @@ function ShiftCard({ shift, onChanged }) {
|
|
|
251
254
|
" (",
|
|
252
255
|
r.requiredCount,
|
|
253
256
|
")",
|
|
254
|
-
/* @__PURE__ */ jsx("
|
|
257
|
+
/* @__PURE__ */ jsx(Button, { variant: "bare", size: "bare", onClick: () => removeRequirement(r.id), "aria-label": `Remover ${r.professionName}`, children: /* @__PURE__ */ jsx(Trash2, { className: "h-3 w-3", "aria-hidden": true }) })
|
|
255
258
|
] }, r.id)) }),
|
|
256
259
|
/* @__PURE__ */ jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [
|
|
257
260
|
/* @__PURE__ */ jsx("div", { className: "w-full sm:w-56", children: /* @__PURE__ */ jsx(
|
|
@@ -314,11 +317,13 @@ function NewShiftModal({ template, open, onOpenChange, onChanged }) {
|
|
|
314
317
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
315
318
|
/* @__PURE__ */ jsx("div", { className: "mb-1 text-xs text-muted-foreground", children: "Dias da semana" }),
|
|
316
319
|
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: WEEKDAYS.map((d, i) => /* @__PURE__ */ jsx(
|
|
317
|
-
|
|
320
|
+
Button,
|
|
318
321
|
{
|
|
322
|
+
variant: "bare",
|
|
323
|
+
size: "bare",
|
|
319
324
|
type: "button",
|
|
320
325
|
onClick: () => setWeekdays((w) => w.includes(i) ? w.filter((x) => x !== i) : [...w, i]),
|
|
321
|
-
className: `h-8 rounded px-2 text-xs ${weekdays.includes(i) ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"}`,
|
|
326
|
+
className: `font-normal h-8 rounded px-2 text-xs ${weekdays.includes(i) ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"}`,
|
|
322
327
|
children: d
|
|
323
328
|
},
|
|
324
329
|
i
|
|
@@ -360,13 +365,15 @@ function TemplateBlock({ template, shifts, onChanged }) {
|
|
|
360
365
|
function DayRow({ title, summary, empty, open, onToggle, children }) {
|
|
361
366
|
return /* @__PURE__ */ jsxs("div", { className: "border-b border-border last:border-b-0", children: [
|
|
362
367
|
/* @__PURE__ */ jsxs(
|
|
363
|
-
|
|
368
|
+
Button,
|
|
364
369
|
{
|
|
370
|
+
variant: "bare",
|
|
371
|
+
size: "bare",
|
|
365
372
|
type: "button",
|
|
366
373
|
onClick: onToggle,
|
|
367
374
|
"aria-expanded": open,
|
|
368
375
|
disabled: empty,
|
|
369
|
-
className: "flex w-full items-center gap-3 px-3 py-2.5 text-left transition-colors hover:bg-muted/50 disabled:cursor-default disabled:hover:bg-transparent",
|
|
376
|
+
className: "flex w-full items-center justify-start gap-3 rounded-none px-3 py-2.5 text-left font-normal transition-colors hover:bg-muted/50 disabled:cursor-default disabled:opacity-100 disabled:hover:bg-transparent",
|
|
370
377
|
children: [
|
|
371
378
|
/* @__PURE__ */ jsx(
|
|
372
379
|
ChevronRight,
|
|
@@ -754,54 +761,12 @@ function SeloEscala({ day }) {
|
|
|
754
761
|
if (day.outsideSchedule) return /* @__PURE__ */ jsx(Badge, { variant: "destructive", children: "Fora da escala" });
|
|
755
762
|
return /* @__PURE__ */ jsx(Badge, { variant: "success", children: "Na escala" });
|
|
756
763
|
}
|
|
757
|
-
function
|
|
758
|
-
const { currency, hourlyRate, staffLookup } = useWorkforceConfig();
|
|
764
|
+
function dayFacts(day, entries, hourlyRate) {
|
|
759
765
|
const value = hourlyRate != null && day.workedMinutes != null && !day.reviewReason ? day.workedMinutes / 60 * hourlyRate : null;
|
|
760
766
|
const alvo = entries.length ? entries[entries.length - 1] : null;
|
|
761
767
|
const travado = entries.some((e) => e.payableInvoiceId);
|
|
762
768
|
const retrato = entries.find((e) => e.kind === "clock_in" && e.photo) ?? entries.find((e) => e.photo) ?? null;
|
|
763
|
-
return
|
|
764
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
765
|
-
retrato ? /* @__PURE__ */ jsx(FotoDaBatida, { entry: retrato }) : /* @__PURE__ */ jsx(Avatar, { className: "h-8 w-8 shrink-0", children: /* @__PURE__ */ jsx(AvatarFallback, { children: iniciais(day.personName) }) }),
|
|
766
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
767
|
-
/* @__PURE__ */ jsx(
|
|
768
|
-
PersonLink,
|
|
769
|
-
{
|
|
770
|
-
personId: day.personId,
|
|
771
|
-
name: day.personName ?? "Sem nome",
|
|
772
|
-
kind: "staff",
|
|
773
|
-
lookup: staffLookup,
|
|
774
|
-
size: "sm",
|
|
775
|
-
className: "text-sm"
|
|
776
|
-
}
|
|
777
|
-
),
|
|
778
|
-
/* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: "Profissional" })
|
|
779
|
-
] })
|
|
780
|
-
] }) }),
|
|
781
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-3 text-sm text-muted-foreground", children: unitName }),
|
|
782
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-3 text-sm tabular-nums", children: hhmm(day.firstIn) }),
|
|
783
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-3 text-sm tabular-nums", children: day.isOpen ? /* @__PURE__ */ jsx(Badge, { variant: "outline", children: "Em aberto" }) : hhmm(day.lastOut) }),
|
|
784
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-3 text-sm tabular-nums", children: /* @__PURE__ */ jsx(Duracao, { day, agora }) }),
|
|
785
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-3 text-sm tabular-nums", children: value != null ? formatCurrency(value, currency) : "\u2014" }),
|
|
786
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx(SeloEscala, { day }) }),
|
|
787
|
-
/* @__PURE__ */ jsx("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
788
|
-
travado ? (
|
|
789
|
-
// A trava do banco, dita na tela: hora já paga não se corrige sem
|
|
790
|
-
// reabrir a competência.
|
|
791
|
-
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 px-2 text-xs text-muted-foreground", children: [
|
|
792
|
-
/* @__PURE__ */ jsx(Lock, { className: "h-3.5 w-3.5", "aria-hidden": true }),
|
|
793
|
-
" j\xE1 paga"
|
|
794
|
-
] })
|
|
795
|
-
) : alvo ? /* @__PURE__ */ jsxs(Button, { size: "sm", variant: "ghost", onClick: () => onAdjust(alvo), children: [
|
|
796
|
-
/* @__PURE__ */ jsx(Pencil, { className: "mr-1 h-3.5 w-3.5", "aria-hidden": true }),
|
|
797
|
-
" Ajustar"
|
|
798
|
-
] }) : null,
|
|
799
|
-
/* @__PURE__ */ jsxs(Button, { size: "sm", variant: "ghost", onClick: () => onDetails(day), children: [
|
|
800
|
-
/* @__PURE__ */ jsx(Eye, { className: "mr-1 h-3.5 w-3.5", "aria-hidden": true }),
|
|
801
|
-
" Detalhes"
|
|
802
|
-
] })
|
|
803
|
-
] }) })
|
|
804
|
-
] });
|
|
769
|
+
return { value, alvo, travado, retrato };
|
|
805
770
|
}
|
|
806
771
|
function tituloDoDia(workDate) {
|
|
807
772
|
const d = /* @__PURE__ */ new Date(`${workDate}T12:00:00`);
|
|
@@ -814,12 +779,87 @@ function tituloDoDia(workDate) {
|
|
|
814
779
|
return extenso.charAt(0).toUpperCase() + extenso.slice(1);
|
|
815
780
|
}
|
|
816
781
|
function GrupoDoDia({ workDate, days, entriesByPerson, unitNames, agora, onAdjust, onDetails }) {
|
|
817
|
-
const { currency, hourlyRate } = useWorkforceConfig();
|
|
782
|
+
const { currency, hourlyRate, staffLookup } = useWorkforceConfig();
|
|
818
783
|
const pessoas = new Set(days.map((d) => d.personId)).size;
|
|
819
784
|
const abertos = days.filter((d) => d.isOpen).length;
|
|
820
785
|
const revisar = days.filter((d) => d.reviewReason === "span_too_long").length;
|
|
821
786
|
const minutos = days.reduce((sum, d) => sum + (d.reviewReason ? 0 : d.workedMinutes ?? 0), 0);
|
|
822
787
|
const valor = hourlyRate != null ? minutos / 60 * hourlyRate : null;
|
|
788
|
+
const columns = React3.useMemo(() => {
|
|
789
|
+
const head = (label) => () => /* @__PURE__ */ jsx("span", { className: "text-xs", children: label });
|
|
790
|
+
const facts = (day) => dayFacts(day, entriesByPerson.get(`${day.personId}|${day.workDate}`) ?? [], hourlyRate);
|
|
791
|
+
return [
|
|
792
|
+
{
|
|
793
|
+
id: "name",
|
|
794
|
+
header: head("Nome"),
|
|
795
|
+
cell: ({ row: { original: day } }) => {
|
|
796
|
+
const { retrato } = facts(day);
|
|
797
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
798
|
+
retrato ? /* @__PURE__ */ jsx(FotoDaBatida, { entry: retrato }) : /* @__PURE__ */ jsx(Avatar, { className: "h-8 w-8 shrink-0", children: /* @__PURE__ */ jsx(AvatarFallback, { children: iniciais(day.personName) }) }),
|
|
799
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
800
|
+
/* @__PURE__ */ jsx(
|
|
801
|
+
PersonLink,
|
|
802
|
+
{
|
|
803
|
+
personId: day.personId,
|
|
804
|
+
name: day.personName ?? "Sem nome",
|
|
805
|
+
kind: "staff",
|
|
806
|
+
lookup: staffLookup,
|
|
807
|
+
size: "sm",
|
|
808
|
+
className: "text-sm"
|
|
809
|
+
}
|
|
810
|
+
),
|
|
811
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: "Profissional" })
|
|
812
|
+
] })
|
|
813
|
+
] });
|
|
814
|
+
}
|
|
815
|
+
},
|
|
816
|
+
{
|
|
817
|
+
id: "unit",
|
|
818
|
+
header: head("Unidade"),
|
|
819
|
+
cell: ({ row: { original: day } }) => /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: day.unitId && unitNames.get(day.unitId) || "\u2014" })
|
|
820
|
+
},
|
|
821
|
+
{ id: "in", header: head("Entrada"), cell: ({ row }) => /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: hhmm(row.original.firstIn) }) },
|
|
822
|
+
{
|
|
823
|
+
id: "out",
|
|
824
|
+
header: head("Sa\xEDda"),
|
|
825
|
+
cell: ({ row: { original: day } }) => /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: day.isOpen ? /* @__PURE__ */ jsx(Badge, { variant: "outline", children: "Em aberto" }) : hhmm(day.lastOut) })
|
|
826
|
+
},
|
|
827
|
+
{ id: "duration", header: head("Dura\xE7\xE3o"), cell: ({ row }) => /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: /* @__PURE__ */ jsx(Duracao, { day: row.original, agora }) }) },
|
|
828
|
+
{
|
|
829
|
+
id: "value",
|
|
830
|
+
header: head("Valor"),
|
|
831
|
+
cell: ({ row: { original: day } }) => {
|
|
832
|
+
const { value } = facts(day);
|
|
833
|
+
return /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: value != null ? formatCurrency(value, currency) : "\u2014" });
|
|
834
|
+
}
|
|
835
|
+
},
|
|
836
|
+
{ id: "schedule", header: head("Escala"), cell: ({ row }) => /* @__PURE__ */ jsx(SeloEscala, { day: row.original }) },
|
|
837
|
+
{
|
|
838
|
+
id: "actions",
|
|
839
|
+
header: head("A\xE7\xF5es"),
|
|
840
|
+
cell: ({ row: { original: day } }) => {
|
|
841
|
+
const { alvo, travado } = facts(day);
|
|
842
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
843
|
+
travado ? (
|
|
844
|
+
// A trava do banco, dita na tela: hora já paga não se corrige sem
|
|
845
|
+
// reabrir a competência.
|
|
846
|
+
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 px-2 text-xs text-muted-foreground", children: [
|
|
847
|
+
/* @__PURE__ */ jsx(Lock, { className: "h-3.5 w-3.5", "aria-hidden": true }),
|
|
848
|
+
" j\xE1 paga"
|
|
849
|
+
] })
|
|
850
|
+
) : alvo ? /* @__PURE__ */ jsxs(Button, { size: "sm", variant: "ghost", onClick: () => onAdjust(alvo), children: [
|
|
851
|
+
/* @__PURE__ */ jsx(Pencil, { className: "mr-1 h-3.5 w-3.5", "aria-hidden": true }),
|
|
852
|
+
" Ajustar"
|
|
853
|
+
] }) : null,
|
|
854
|
+
/* @__PURE__ */ jsxs(Button, { size: "sm", variant: "ghost", onClick: () => onDetails(day), children: [
|
|
855
|
+
/* @__PURE__ */ jsx(Eye, { className: "mr-1 h-3.5 w-3.5", "aria-hidden": true }),
|
|
856
|
+
" Detalhes"
|
|
857
|
+
] })
|
|
858
|
+
] });
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
];
|
|
862
|
+
}, [entriesByPerson, unitNames, agora, onAdjust, onDetails, currency, hourlyRate, staffLookup]);
|
|
823
863
|
return /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-xl border border-border", children: [
|
|
824
864
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-4 border-l-2 border-l-primary bg-muted/40 px-4 py-3", children: [
|
|
825
865
|
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: tituloDoDia(workDate) }),
|
|
@@ -856,30 +896,7 @@ function GrupoDoDia({ workDate, days, entriesByPerson, unitNames, agora, onAdjus
|
|
|
856
896
|
] }),
|
|
857
897
|
valor != null && valor > 0 && /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-success", children: formatCurrency(valor, currency) })
|
|
858
898
|
] }),
|
|
859
|
-
/* @__PURE__ */ jsx(
|
|
860
|
-
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b border-border text-xs font-medium text-muted-foreground", children: [
|
|
861
|
-
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2", children: "Nome" }),
|
|
862
|
-
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2", children: "Unidade" }),
|
|
863
|
-
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2", children: "Entrada" }),
|
|
864
|
-
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2", children: "Sa\xEDda" }),
|
|
865
|
-
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2", children: "Dura\xE7\xE3o" }),
|
|
866
|
-
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2", children: "Valor" }),
|
|
867
|
-
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2", children: "Escala" }),
|
|
868
|
-
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2", children: "A\xE7\xF5es" })
|
|
869
|
-
] }) }),
|
|
870
|
-
/* @__PURE__ */ jsx("tbody", { children: days.map((d) => /* @__PURE__ */ jsx(
|
|
871
|
-
LinhaPessoa,
|
|
872
|
-
{
|
|
873
|
-
day: d,
|
|
874
|
-
entries: entriesByPerson.get(`${d.personId}|${d.workDate}`) ?? [],
|
|
875
|
-
unitName: d.unitId && unitNames.get(d.unitId) || "\u2014",
|
|
876
|
-
agora,
|
|
877
|
-
onAdjust,
|
|
878
|
-
onDetails
|
|
879
|
-
},
|
|
880
|
-
`${d.personId}|${d.workDate}`
|
|
881
|
-
)) })
|
|
882
|
-
] }) })
|
|
899
|
+
/* @__PURE__ */ jsx(DataTable, { variant: "bare", columns, data: days, getRowId: (d) => `${d.personId}|${d.workDate}` })
|
|
883
900
|
] });
|
|
884
901
|
}
|
|
885
902
|
function TimeEntriesView() {
|
|
@@ -1778,11 +1795,13 @@ function Painel({ overview, upcoming, onPessoa }) {
|
|
|
1778
1795
|
/* @__PURE__ */ jsx("div", { className: "border-b border-border bg-muted/40 px-4 py-2 text-sm font-medium", children: titulo }),
|
|
1779
1796
|
itens.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-4 py-3 text-sm text-muted-foreground", children: vazio }) : /* @__PURE__ */ jsx("ul", { className: "divide-y divide-border", children: itens.map((u, i) => /* @__PURE__ */ jsxs("li", { className: "flex items-center justify-between gap-2 px-4 py-2 text-sm", children: [
|
|
1780
1797
|
/* @__PURE__ */ jsx(
|
|
1781
|
-
|
|
1798
|
+
Button,
|
|
1782
1799
|
{
|
|
1800
|
+
variant: "bare",
|
|
1801
|
+
size: "bare",
|
|
1783
1802
|
type: "button",
|
|
1784
1803
|
onClick: () => onPessoa(u.personId),
|
|
1785
|
-
className: "truncate text-left underline decoration-dashed decoration-muted-foreground/40 underline-offset-2 hover:text-primary",
|
|
1804
|
+
className: "truncate text-left underline decoration-dashed decoration-muted-foreground/40 underline-offset-2 hover:text-primary block font-normal",
|
|
1786
1805
|
children: u.personName ?? "Sem nome"
|
|
1787
1806
|
}
|
|
1788
1807
|
),
|
|
@@ -1971,11 +1990,10 @@ function Ficha({ personId, personName }) {
|
|
|
1971
1990
|
children: pendencias.map((p) => /* @__PURE__ */ jsxs("li", { className: "flex items-center justify-between gap-2 px-4 py-2 text-sm", children: [
|
|
1972
1991
|
/* @__PURE__ */ jsxs("label", { className: "flex min-w-0 items-center gap-2", children: [
|
|
1973
1992
|
/* @__PURE__ */ jsx(
|
|
1974
|
-
|
|
1993
|
+
Checkbox,
|
|
1975
1994
|
{
|
|
1976
|
-
type: "checkbox",
|
|
1977
1995
|
checked: !!p.resolvedAt,
|
|
1978
|
-
onChange: (
|
|
1996
|
+
onChange: (checked) => void provider.resolvePendingItem(p.id, checked).then(recarregar)
|
|
1979
1997
|
}
|
|
1980
1998
|
),
|
|
1981
1999
|
/* @__PURE__ */ jsx("span", { className: `truncate ${p.resolvedAt ? "text-muted-foreground line-through" : ""}`, children: p.title })
|
|
@@ -6500,6 +6518,23 @@ var MIGRATIONS = [
|
|
|
6500
6518
|
{ id: "006_o_custo_de_pessoal_e_um_ramo_do_plano", sql: MIGRATION_006_O_CUSTO_DE_PESSOAL_E_UM_RAMO_DO_PLANO },
|
|
6501
6519
|
{ id: "007_a_porta_de_servico_do_ponto_fecha_tambem", sql: MIGRATION_007_A_PORTA_DE_SERVICO_DO_PONTO_FECHA_TAMBEM }
|
|
6502
6520
|
];
|
|
6521
|
+
var workforceV1SettingsTabs = [
|
|
6522
|
+
defineSettingsTab({
|
|
6523
|
+
id: "workforce-time-clock",
|
|
6524
|
+
label: tl("Time clock", "Ponto eletr\xF4nico"),
|
|
6525
|
+
icon: "Clock",
|
|
6526
|
+
section: "company",
|
|
6527
|
+
requiresFacet: "time_clock",
|
|
6528
|
+
pending: true,
|
|
6529
|
+
defaults: { "time_clock.unit_active": false },
|
|
6530
|
+
sections: [{
|
|
6531
|
+
description: tl("The unit password unlocks the clock-in totem for 24 hours.", "A senha da unidade libera o totem de ponto por 24 horas."),
|
|
6532
|
+
fields: [
|
|
6533
|
+
{ key: "time_clock.unit_active", type: "boolean", scope: "unit", label: tl("Totem active in this unit", "Totem ativo nesta unidade") }
|
|
6534
|
+
]
|
|
6535
|
+
}]
|
|
6536
|
+
})
|
|
6537
|
+
];
|
|
6503
6538
|
|
|
6504
6539
|
// src/index.ts
|
|
6505
6540
|
function createSafeWorkforceProvider() {
|
|
@@ -6580,6 +6615,11 @@ function createWorkforcePlugin(options) {
|
|
|
6580
6615
|
sql: m.sql,
|
|
6581
6616
|
description: m.id
|
|
6582
6617
|
})),
|
|
6618
|
+
// Paid parts a plan sells apart; their settings appear once turned on.
|
|
6619
|
+
facets: [
|
|
6620
|
+
{ id: "time_clock", label: "Ponto eletr\xF4nico", description: "Registro de ponto no totem da unidade." }
|
|
6621
|
+
],
|
|
6622
|
+
settings: workforceV1SettingsTabs,
|
|
6583
6623
|
declaredFeatures: [
|
|
6584
6624
|
{ id: "workforce", label: config.labels.pageTitle, group: config.labels.pageTitle }
|
|
6585
6625
|
],
|