forlogic-core 3.0.8 → 3.0.9

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.
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Fonte de dados plugável do módulo de liderança.
3
+ *
4
+ * Por padrão os hooks leem/escrevem em `common.leaders` no Supabase. Apps que migraram
5
+ * a hierarquia para outra API (ex.: Qualiex Trainings → TeamController/dbo.leaders)
6
+ * registram um adapter aqui — os hooks passam a usá-lo sem mudança de comportamento
7
+ * na UI (mesmo shape de linha da tabela legada).
8
+ *
9
+ * Limitação conhecida do modelo de arestas (dbo.leaders): linha com `id_leader = null`
10
+ * ("líder virtual" promovido sem liderados) não é persistível — o adapter pode tratá-la
11
+ * como no-op; a árvore já sintetiza raízes virtuais no cliente a partir das arestas.
12
+ */
13
+ /** Linha crua no shape da tabela legada common.leaders. */
14
+ export interface LeadershipRelationRow {
15
+ id: string;
16
+ alias: string;
17
+ /** O LIDERADO (vocabulário da tabela legada). */
18
+ id_user: string;
19
+ /** O líder (null = raiz/líder virtual). */
20
+ id_leader: string | null;
21
+ is_active: boolean;
22
+ is_removed: boolean;
23
+ created_at: string;
24
+ updated_at: string;
25
+ }
26
+ export interface LeadershipDataAdapter {
27
+ /** Todas as relações ativas da unidade corrente. */
28
+ list(): Promise<LeadershipRelationRow[]>;
29
+ /** Cria vínculos liderado→líder. Linhas com id_leader null podem ser no-op. */
30
+ create(rows: Array<{
31
+ id_user: string;
32
+ id_leader: string | null;
33
+ }>): Promise<void>;
34
+ /** Troca o líder do vínculo (null = liderado fica sem líder). */
35
+ updateLeader(rowId: string, newLeaderId: string | null): Promise<void>;
36
+ /** Desfaz o vínculo (soft delete no modelo legado). */
37
+ remove(rowId: string): Promise<void>;
38
+ }
39
+ export declare function setLeadershipDataSource(next: LeadershipDataAdapter | null): void;
40
+ export declare function getLeadershipDataSource(): LeadershipDataAdapter | null;
@@ -5,6 +5,7 @@
5
5
  * relações de liderança entre usuários do Qualiex.
6
6
  */
7
7
  export * from './types';
8
+ export * from './dataSource';
8
9
  export * from './utils/leadershipUtils';
9
10
  export * from './hooks/useLeadershipApi';
10
11
  export * from './hooks/useLeadershipMutations';
@@ -1 +1 @@
1
- import e from"i18next";import{useMemo as r,useState as a,useEffect as s,useRef as i,useCallback as t}from"react";import{useQuery as n,useQueryClient as d,useMutation as o}from"@tanstack/react-query";import{useAuth as l,TokenManager as c,useQualiexUsers as u,getSupabaseClient as m,Label as h,Input as _,Select as f,SelectTrigger as p,SelectValue as g,SelectContent as w,ScrollArea as v,SelectItem as x,Button as N,AlertDialog as y,AlertDialogTrigger as b,AlertDialogContent as E,AlertDialogHeader as S,AlertDialogTitle as I,AlertDialogDescription as C,AlertDialogFooter as k,AlertDialogCancel as q,AlertDialogAction as U,Checkbox as A,Dialog as L,DialogContent as P,DialogHeader as $,DialogTitle as j,DialogBody as z,TreeTable as D,cn as T}from"forlogic-core";import{toast as K}from"sonner";import{useTranslation as M}from"react-i18next";import{jsxs as O,jsx as F,Fragment as V}from"react/jsx-runtime";import{Loader2 as Q,Trash2 as J,User as H,Mail as B,Plus as R,ChevronDown as W,ChevronRight as G,Users as X,Pencil as Y,UserPlus as Z}from"lucide-react";import{z as ee}from"zod";import{appendErrors as re,useForm as ae}from"react-hook-form";import{validateFieldsNatively as se,toNestErrors as ie}from"@hookform/resolvers";function te(e,r){const a=e.map(e=>({...e})),s=new Set(a.filter(e=>!r.has(e.id_user)).map(e=>e.id_user));return a.forEach(e=>{if(e.id_leader&&s.has(e.id_leader)){let r=e.id_leader;for(;r&&s.has(r);){const e=a.find(e=>e.id_user===r);r=e?.id_leader||null}e.id_leader=r}}),a.filter(e=>r.has(e.id_user))}function ne(e){const r=new Map,a=new Map,s=[];e.forEach(e=>{const s={...e,children:[],level:0};r.set(e.id,s),a.set(e.id_user,s)}),e.forEach(e=>{const i=r.get(e.id);if(e.id_leader){const r=a.get(e.id_leader);if(r)return void r.children.push(i)}s.push(i)});const i=(e,r)=>{e.level=r,e.children.forEach(e=>i(e,r+1))};s.forEach(e=>i(e,0));const t=e=>{e.sort((e,r)=>{const a=e.name||e.id_user||e.email||"",s=r.name||r.id_user||r.email||"";return a.localeCompare(s)}),e.forEach(e=>e.children.length>0&&t(e.children))};return t(s),s}function de(e){const r=[],a=e=>{r.push(e),e.children.forEach(a)};return e.forEach(a),r}function oe(){const{alias:a,isAuthenticated:s}=l(),i=c.getAccessToken(),{data:t=[]}=u(),d=n({queryKey:["leadership-raw",a],queryFn:async()=>{if(!i||!a)throw new Error("Usuário não autenticado ou unidade não selecionada");const e=m(),{data:r,error:s}=await e.schema("common").from("leaders").select("*").eq("is_removed",!1).eq("alias",a);if(s)throw new Error("Erro ao buscar hierarquia de liderança");return r??[]},enabled:!!i&&!!a&&s}),o=r(()=>{const r=d.data;if(!r)return;if(0===r.length)return[];const a={};t.forEach(e=>{a[e.userId]={name:e.userName||e.userEmail,email:e.userEmail||""}});const s=r.map(s=>{const i=r.filter(e=>e.id_leader===s.id_user);return{...s,name:a[s.id_user]?.name||e.t("inactive_user"),email:a[s.id_user]?.email||"",subordinatesCount:i.length,subordinateNames:i.map(e=>a[e.id_user]?.name||"[Usuário inativo]").sort((e,r)=>e.localeCompare(r))}}),i=new Set(r.map(e=>e.id_user));return new Set(r.filter(e=>e.id_leader&&!i.has(e.id_leader)).map(e=>e.id_leader)).forEach(i=>{const t=a[i],n=r.filter(e=>e.id_leader===i);s.push({id:`virtual-${i}`,alias:r[0]?.alias||"",id_user:i,id_leader:null,is_removed:!1,is_active:!0,created_at:(new Date).toISOString(),updated_at:(new Date).toISOString(),name:t?.name||e.t("inactive_user"),email:t?.email||"",subordinatesCount:n.length,subordinateNames:n.map(e=>a[e.id_user]?.name||"[Usuário inativo]").sort((e,r)=>e.localeCompare(r))})}),ne(s)},[d.data,t]);return{...d,data:o}}const le="common";function ce(){const{alias:e}=l(),r=d(),a=m(),{t:s}=M();return o({mutationFn:async r=>{if(!e)throw new Error(s("unit_not_selected","Unidade não selecionada"));if(r.id_user===r.id_leader)throw new Error(s("cannot_be_own_leader","Usuário não pode ser seu próprio líder"));r.id_leader&&await fe(a,e,r.id_user,r.id_leader);const{data:i,error:t}=await a.schema(le).from("leaders").insert({alias:e,id_user:r.id_user,id_leader:r.id_leader,is_active:!0,is_removed:!1}).select().single();if(t)throw t;return i},onSuccess:()=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),K.success(s("leader_promoted_success","Líder virtual promovido com sucesso"))},onError:e=>{K.error(e.message||s("leader_create_error","Erro ao criar líder"))}})}function ue(){const{alias:e}=l(),r=d(),a=m(),{t:s}=M();return o({mutationFn:async r=>{if(!e)throw new Error(s("unit_not_selected","Unidade não selecionada"));if(!r.users.length)throw new Error(s("select_at_least_one",s("leadership_select_subordinates")));const i=r.users.map(e=>e.id_user),{data:t}=await a.schema(le).from("leaders").select("id_user").eq("alias",e).in("id_user",i).eq("is_removed",!1);if(t&&t.length>0){const e=t.map(e=>e.id_user);throw new Error(s("users_already_leaders",`Alguns usuários já estão cadastrados como líderes: ${e.join(", ")}`))}for(const l of r.users){if(r.id_leader&&l.id_user===r.id_leader)throw new Error(s("cannot_be_own_leader","Usuário não pode ser seu próprio líder"));r.id_leader&&await fe(a,e,l.id_user,r.id_leader)}const n=r.users.map(a=>({alias:e,id_user:a.id_user,id_leader:r.id_leader,is_active:!0,is_removed:!1})),{data:d,error:o}=await a.schema(le).from("leaders").insert(n).select();if(o)throw o;return d},onSuccess:a=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),K.success(s("subordinates_added_success",`${a?.length||0} liderado(s) adicionado(s) com sucesso`))},onError:e=>{K.error(e.message||s("subordinates_add_error","Erro ao adicionar liderados"))}})}function me(){const{alias:e}=l(),r=d(),a=m(),{t:s}=M();return o({mutationFn:async r=>{if(!e)throw new Error(s("unit_not_selected","Unidade não selecionada"));const{data:i}=await a.schema(le).from("leaders").select("id_user").eq("id",r.id).eq("alias",e).single();if(!i)throw new Error(s("leader_not_found","Líder não encontrado"));if(i.id_user===r.id_leader)throw new Error(s("cannot_be_own_leader","Usuário não pode ser seu próprio líder"));r.id_leader&&await fe(a,e,i.id_user,r.id_leader,r.id);const{data:t,error:n}=await a.schema(le).from("leaders").update({id_leader:r.id_leader}).eq("id",r.id).eq("alias",e).select().single();if(n)throw n;return t},onSuccess:()=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),K.success(s("leader_updated_success","Líder atualizado com sucesso"))},onError:e=>{K.error(e.message||s("leader_update_error","Erro ao atualizar líder"))}})}function he(){const{alias:e}=l(),r=d(),a=m(),{t:s}=M();return o({mutationFn:async r=>{if(!e)throw new Error(s("unit_not_selected","Unidade não selecionada"));const{error:i}=await a.schema(le).from("leaders").update({is_removed:!0}).eq("id",r).eq("alias",e);if(i)throw i},onSuccess:()=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),K.success(s("leader_removed_success","Líder removido com sucesso"))},onError:e=>{K.error(e.message||s("leader_remove_error","Erro ao remover líder"))}})}function _e(){const{alias:e}=l(),r=d(),a=m(),{t:s}=M();return o({mutationFn:async({leaderUserId:r,selectedUsers:i})=>{if(!e)throw new Error(s("unit_not_selected","Unidade não selecionada"));const t=i.map(e=>e.id_user),n=await Promise.all([a.schema(le).from("leaders").select("id, id_user, id_leader").eq("alias",e).eq("is_removed",!1).eq("id_leader",r),a.schema(le).from("leaders").select("id, id_user, id_leader").eq("alias",e).eq("is_removed",!1).in("id_user",t.length?t:["__none__"])]),[{data:d,error:o},{data:l,error:c}]=n;if(o)throw o;if(c)throw c;const u=d||[],m=l||[],h=new Set(t),_=u.filter(e=>!h.has(e.id_user)),f=m.filter(e=>e.id_leader!==r),p=new Set(m.map(e=>e.id_user)),g=i.filter(e=>!p.has(e.id_user));for(const s of f)await fe(a,e,s.id_user,r,s.id);for(const x of g){if(x.id_user===r)throw new Error(s("cannot_be_own_leader","Usuário não pode ser seu próprio líder"));await fe(a,e,x.id_user,r)}const w=[];if(_.length){const r=_.map(e=>e.id);w.push(a.schema(le).from("leaders").update({is_removed:!0}).in("id",r).eq("alias",e))}if(f.length){const s=f.map(e=>e.id);w.push(a.schema(le).from("leaders").update({id_leader:r}).in("id",s).eq("alias",e))}if(g.length){const s=g.map(a=>({alias:e,id_user:a.id_user,id_leader:r,is_active:!0,is_removed:!1}));w.push(a.schema(le).from("leaders").insert(s))}const v=(await Promise.all(w)).find(e=>e?.error);if(v?.error)throw v.error;return{unlinked:_.length,updated:f.length,created:g.length}},onSuccess:a=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),K.success(s("subordinates_synced_success",`Subordinados sincronizados (${a.created} adicionados, ${a.updated} atualizados, ${a.unlinked} removidos)`))},onError:e=>{K.error(e.message||s("subordinates_sync_error","Erro ao sincronizar subordinados"))}})}async function fe(r,a,s,i,t){const{data:n,error:d}=await r.schema(le).from("leaders").select("id, id_user, id_leader").eq("alias",a).eq("is_removed",!1);if(d)throw d;const o=t?n.filter(e=>e.id!==t):n,l=new Set;let c=i;for(;c;){if(l.has(c))throw new Error(e.t("leadership_cycle_error"));if(c===s)throw new Error("Esta associação criaria um ciclo na hierarquia");l.add(c);const r=o.find(e=>e.id_user===c);c=r?.id_leader||null}}var pe=function(e,r){for(var a={};e.length;){var s=e[0],i=s.code,t=s.message,n=s.path.join(".");if(!a[n])if("unionErrors"in s){var d=s.unionErrors[0].errors[0];a[n]={message:d.message,type:d.code}}else a[n]={message:t,type:i};if("unionErrors"in s&&s.unionErrors.forEach(function(r){return r.errors.forEach(function(r){return e.push(r)})}),r){var o=a[n].types,l=o&&o[s.code];a[n]=re(n,r,a,i,l?[].concat(l,s.message):s.message)}e.shift()}return a},ge=function(e,r,a){return void 0===a&&(a={}),function(s,i,t){try{return Promise.resolve(function(i,n){try{var d=Promise.resolve(e["sync"===a.mode?"parse":"parseAsync"](s,r)).then(function(e){return t.shouldUseNativeValidation&&se({},t),{errors:{},values:a.raw?s:e}})}catch(o){return n(o)}return d&&d.then?d.then(void 0,n):d}(0,function(e){if(function(e){return Array.isArray(null==e?void 0:e.errors)}(e))return{values:{},errors:ie(pe(e.errors,!t.shouldUseNativeValidation&&"all"===t.criteriaMode),t)};throw e}))}catch(n){return Promise.reject(n)}}};const we=ee.object({id_leader:ee.string().nullable(),id_users:ee.array(ee.string()).min(1,e.t("leadership_select_subordinates"))}),ve=ee.object({id_leader:ee.string().nullable(),id_users:ee.array(ee.string())});function xe({value:e,onChange:r,excludeUserIds:t=[],error:n}){const{t:d}=M(),{data:o=[],isLoading:l}=u(),[c,m]=a(""),f=i(null),p=i(0),g=o.filter(e=>!t.includes(e.userId||"")).filter(e=>{const r=c.toLowerCase(),a=e.userName?.toLowerCase().includes(r);return a}).sort((r,a)=>{const s=e.includes(r.userId),i=e.includes(a.userId);if(s&&!i)return-1;if(!s&&i)return 1;const t=r.userName||r.userEmail||"",n=a.userName||a.userEmail||"";return t.localeCompare(n)});return s(()=>{f.current&&p.current>0&&(f.current.scrollTop=p.current)},[g]),O("div",l?{className:"flex items-center justify-center p-4",children:[F(Q,{className:"h-6 w-6 animate-spin"}),F("span",{className:"ml-2",children:d("loading")})]}:{className:"space-y-2",children:[F(_,{placeholder:d("search_user_placeholder"),value:c,onChange:e=>m(e.target.value)}),F("div",{ref:f,className:"border rounded-md p-4 max-h-[300px] overflow-y-auto",children:0===g.length?F("p",{className:"text-sm text-muted-foreground",children:d("search_user_placeholder")}):F("div",{className:"space-y-2",children:g.map(a=>O("div",{className:"flex items-center space-x-2",children:[F(A,{id:a.userId,checked:e.includes(a.userId),onCheckedChange:()=>{return s=a.userId,f.current&&(p.current=f.current.scrollTop),void(e.includes(s)?r(e.filter(e=>e!==s)):r([...e,s]));var s}}),F(h,{htmlFor:a.userId,className:"flex-1 cursor-pointer",children:a.userName||a.userEmail})]},a.userId))})}),e.length>0&&F("p",{className:"text-sm text-muted-foreground",children:d("selected_count",{count:e.length})}),n&&F("p",{className:"text-sm text-destructive",children:n})]})}function Ne({leader:e,prefilledLeaderId:r,onSuccess:i}){const{t:t}=M(),{alias:n}=l(),d=!!e,o=e?.id.startsWith("virtual-"),c=ue(),m=ce(),A=me(),L=_e(),P=he(),{data:$=[]}=oe(),{data:j=[]}=u(),[z,D]=a(""),T=de($).map(e=>e.id_user),K=d?de($).filter(r=>r.id_leader===e.id_user).map(e=>e.id_user):[],H=ae({resolver:ge(d?ve:we),defaultValues:{id_leader:r||(d?e?.id_leader:null)||null,id_users:d?K:[]}});s(()=>{if(e){const r=de($).filter(r=>r.id_leader===e.id_user).map(e=>e.id_user);H.reset({id_leader:e.id_leader||null,id_users:r})}else r?H.reset({id_leader:r,id_users:[]}):H.reset({id_leader:null,id_users:[]})},[n,e?.id,e?.id_user,e?.id_leader,r,$]);const B=c.isPending||m.isPending||A.isPending||L.isPending||P.isPending,R=H.watch("id_leader"),W=H.watch("id_users"),G=d?[e.id_user,...T.filter(r=>r!==e.id_user&&!W.includes(r)&&!K.includes(r))]:[R,...T.filter(e=>!W.includes(e))].filter(Boolean);return O("form",{onSubmit:H.handleSubmit(async r=>{try{if(d)if(o){await m.mutateAsync({id_user:e.id_user,id_leader:r.id_leader});const a=j.filter(e=>r.id_users.includes(e.userId)).map(e=>({id_user:e.userId}));await L.mutateAsync({leaderUserId:e.id_user,selectedUsers:a})}else{await A.mutateAsync({id:e.id,id_leader:r.id_leader});const a=j.filter(e=>r.id_users.includes(e.userId)).map(e=>({id_user:e.userId}));await L.mutateAsync({leaderUserId:e.id_user,selectedUsers:a})}else{const e=j.filter(e=>r.id_users.includes(e.userId)).map(e=>({id_user:e.userId}));await c.mutateAsync({id_leader:r.id_leader,users:e})}i?.()}catch(a){}}),className:"space-y-4",children:[d&&O("div",{children:[F(h,{children:t("leader")}),F(_,{value:j.find(r=>r.userId===e.id_user)?.userName||e.name||t("inactive_user"),disabled:!0,className:"bg-muted"})]}),O("div",{children:[F(h,{children:t("leadership_immediate_superior")}),O(f,{value:R||"none",onValueChange:e=>H.setValue("id_leader","none"===e?null:e),children:[F(p,{children:F(g,{placeholder:t("select_placeholder")})}),O(w,{children:[F("div",{className:"sticky top-0 z-10 bg-background p-2 border-b",children:F(_,{placeholder:t("leadership_search_superior"),value:z,onChange:e=>D(e.target.value),onKeyDown:e=>e.stopPropagation(),onClick:e=>e.stopPropagation(),className:"h-8"})}),O(v,{className:"h-[200px]",children:[F(x,{value:"none",children:t("none_bracketed")}),j.filter(r=>{const a=d?r.userId!==e.id_user:!W.includes(r.userId),s=!z||r.userName?.toLowerCase().includes(z.toLowerCase());return a&&s}).sort((e,r)=>{const a=e.userName||e.userEmail||"",s=r.userName||r.userEmail||"";return a.localeCompare(s)}).map(e=>F(x,{value:e.userId,children:e.userName},e.userId))]})]})]},`superior-select-${n}`),H.formState.errors.id_leader&&F("p",{className:"text-sm text-destructive mt-1",children:H.formState.errors.id_leader.message})]}),O("div",{children:[O(h,{children:[t("subordinates")," *"]}),F(xe,{value:W,onChange:e=>H.setValue("id_users",e),excludeUserIds:G,error:H.formState.errors.id_users?.message},`users-multiselect-${n}`)]}),O("div",{className:"flex items-center justify-between gap-2",children:[F(N,{type:"submit",disabled:B||!d&&0===W.length,children:B&&!P.isPending?O(V,{children:[F(Q,{className:"mr-2 h-4 w-4 animate-spin"}),t(d?"updating":"saving")]}):t(d?"update":"create")}),d&&!R&&0===W.length&&O(y,{children:[F(b,{asChild:!0,children:F(N,{type:"button",variant:"destructive",disabled:B,className:"ml-auto",children:P.isPending?O(V,{children:[F(Q,{className:"mr-2 h-4 w-4 animate-spin"}),t("removing")]}):O(V,{children:[F(J,{className:"mr-2 h-4 w-4"}),t("remove")]})})}),O(E,{children:[O(S,{children:[F(I,{children:t("confirm_removal")}),F(C,{children:t("leadership_remove_confirmation")})]}),O(k,{children:[F(q,{children:t("cancel")}),F(U,{onClick:async()=>{if(e)try{await P.mutateAsync(e.id),i?.()}catch(r){}},children:t("remove")})]})]})]})]})]})}function ye({open:e,onOpenChange:r,leader:a,prefilledLeaderId:s,title:i}){return F(L,{open:e,onOpenChange:r,children:O(P,{variant:"form",className:"sm:max-w-[500px]",children:[F($,{showSeparator:!0,children:F(j,{children:i})}),F(z,{children:F(Ne,{leader:a,prefilledLeaderId:s,onSuccess:()=>r(!1)})})]})})}const be="leadership-expanded-nodes",Ee=(e,r)=>{try{localStorage.setItem(`${be}-${e}`,JSON.stringify(Array.from(r)))}catch{}};function Se({unassociatedUsers:e=[],onAssociateUser:i,onMoveNode:n,onMoveNodes:d,columns:o,nameHeader:c,rootDropLabel:u}={}){const{t:m}=M(),{alias:h}=l(),{data:_,isLoading:f,error:p,refetch:g}=oe(),w=me(),v=ce(),[x,y]=a(()=>h?(e=>{try{const r=localStorage.getItem(`${be}-${e}`);if(r)return new Set(JSON.parse(r))}catch{}return new Set})(h):new Set),[b,E]=a([]),[S,I]=a(new Set),[C,k]=a(!0),[q,U]=a(!1),[L,P]=a(),[$,j]=a(null),z=r(()=>_?de(_):[],[_]),K=r(()=>z.map(e=>e.id),[z]),Q=K.length>0&&b.length===K.length,J=z.filter(e=>e.children.length>0).every(e=>x.has(e.id));s(()=>{if(_&&_.length>0&&h){if(!localStorage.getItem(`${be}-${h}`)){const e=_.map(e=>e.id),r=new Set(e);y(r),Ee(h,r)}}},[_,h]);const ee=t(e=>{y(r=>{const a=new Set(r);return a.has(e)?a.delete(e):a.add(e),h&&Ee(h,a),a})},[h]),re=t(()=>{if(J){const e=new Set;y(e),h&&Ee(h,e)}else{const e=new Set(z.filter(e=>e.children.length>0).map(e=>e.id));y(e),h&&Ee(h,e)}},[J,z,h]),ae=t(e=>{E(r=>r.includes(e)?r.filter(r=>r!==e):[...r,e])},[]),se=t(()=>{E(Q?[]:K)},[Q,K]),ie=t(e=>{I(r=>{const a=new Set(r);return a.has(e)?a.delete(e):a.add(e),a})},[]),te=t(e=>z.find(r=>r.id===e),[z]),ne=t((r,a)=>{if(n)return void n(r,a);const s=e.find(e=>e.id===r);if(s){if(i){const e=a?te(a):null;i(s.id,e?.id_user||null)}else v.mutate({id_user:s.id,id_leader:a&&te(a)?.id_user||null});return}const t=te(r);if(!t)return;const d=a?te(a):null;w.mutate({id:t.id,id_leader:d?.id_user||null})},[n,e,i,te,w,v]),le=t((e,r)=>{d?d(e,r):(e.forEach(e=>ne(e,r)),E([]))},[d,ne]),ue=t(e=>{P(e),j(null),U(!0)},[]),he=t(()=>{P(void 0),j(null),U(!0)},[]),_e=t(()=>{U(!1),P(void 0),j(null)},[]),fe=t((e,r)=>{const a=S.has(e)&&S.size>1?Array.from(S):[e];r.dataTransfer.effectAllowed="move",r.dataTransfer.setData("text/plain",e),r.dataTransfer.setData("application/x-tree-ids",JSON.stringify(a)),r.currentTarget.style.opacity="0.4"},[S]),pe=r(()=>[{key:"subordinatesCount",header:m("subordinates"),hoverContent:e=>e.subordinateNames&&e.subordinateNames.length>0?O("div",{className:"space-y-1.5",children:[F("p",{className:"text-xs font-medium text-muted-foreground mb-1",children:m("leadership_direct_subordinates")}),[...e.subordinateNames].sort((e,r)=>e.localeCompare(r)).map(e=>O("div",{className:"flex items-center gap-2 text-sm",children:[F(H,{className:"h-3 w-3 text-muted-foreground"}),F("span",{children:e})]},e))]}):F("p",{className:"text-xs text-muted-foreground",children:m("leadership_no_direct_subordinates")})},{key:"email",header:m("email"),className:"text-left",width:180,render:e=>O("span",{className:"flex items-center gap-1.5 text-muted-foreground text-sm",children:[F(B,{className:"h-3.5 w-3.5"}),e.email||"—"]})}],[m]),ge=o??pe;if(f)return F("div",{className:"flex items-center justify-center h-full",children:O("div",{className:"text-center space-y-2",children:[F("div",{className:"animate-spin h-8 w-8 border-4 border-primary border-t-transparent rounded-full mx-auto"}),F("p",{className:"text-sm text-muted-foreground",children:m("loading")})]})});if(p)return F("div",{className:"flex items-center justify-center h-full",children:O("div",{className:"text-center",children:[F("p",{className:"text-destructive mb-4",children:m("leadership_load_error")}),F(N,{onClick:()=>g(),children:m("try_again")})]})});const we=z.filter(e=>e.name!==m("inactive_user")).length;return O("div",{className:"flex flex-col h-full gap-3 p-4",children:[O("div",{className:"flex items-center justify-between",children:[O("div",{className:"flex gap-2 items-center",children:[O(N,{size:"sm",onClick:he,children:[F(R,{className:"h-4 w-4 mr-2"}),m("leadership_define_leader")]}),F(N,{size:"sm",variant:"outline",onClick:re,children:O(V,J?{children:[F(W,{className:"h-4 w-4 mr-1"}),m("collapse")]}:{children:[F(G,{className:"h-4 w-4 mr-1"}),m("expand")]})}),F("div",{className:"flex items-center gap-2 ml-4",children:O("div",{className:"flex items-center gap-2 px-3 py-1.5 bg-muted rounded-md",children:[F(X,{className:"h-4 w-4 text-muted-foreground"}),F("span",{className:"text-sm font-medium",children:m("leadership_users_associated",{count:we})})]})})]}),F("p",{className:"text-xs text-muted-foreground",children:m("leadership_drag_hint")})]}),F(D,{data:_||[],columns:ge,nameKey:"name",nameHeader:c??m("leader"),expandedIds:x,onToggleExpand:ee,iconComponent:F(X,{className:"h-4 w-4 text-muted-foreground shrink-0"}),rowActionsVariant:"inline",enableRowDrag:!0,enableSelection:!0,selectedIds:b,onSelectItem:ae,onSelectAll:se,isAllSelected:Q,onMoveNode:ne,onMoveNodes:le,rootDropLabel:u??m("leadership_make_root"),emptyMessage:m("leadership_no_hierarchy"),renderActions:e=>F(N,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>ue(e),children:F(Y,{className:"h-4 w-4"})})}),e.length>0&&O("div",{className:"border rounded-lg overflow-hidden",children:[O("button",{type:"button",onClick:()=>k(e=>!e),className:"w-full px-4 py-2.5 bg-muted/50 border-b flex items-center gap-2 hover:bg-muted/70 transition-colors cursor-pointer",children:[F(C?W:G,{className:"h-4 w-4 text-muted-foreground shrink-0"}),F(Z,{className:"h-4 w-4 text-muted-foreground"}),F("span",{className:"text-sm font-medium",children:m("leadership_unassociated_users")}),O("span",{className:"text-xs text-muted-foreground ml-1",children:["(",e.length,")"]}),S.size>0&&O("span",{className:"text-xs text-primary ml-1",children:["(",m("selected_count",{count:S.size}),")"]}),F("span",{className:"text-xs text-muted-foreground ml-auto",children:m("leadership_drag_to_hierarchy")})]}),C&&F("div",{className:"divide-y",children:e.map(e=>O("div",{draggable:!0,onDragStart:r=>fe(e.id,r),onDragEnd:e=>{e.currentTarget.style.opacity="1"},className:T("flex items-center gap-3 px-4 py-2.5 hover:bg-accent/50 cursor-grab active:cursor-grabbing transition-colors",S.has(e.id)&&"bg-primary/5"),children:[F(A,{checked:S.has(e.id),onCheckedChange:()=>ie(e.id),onClick:e=>e.stopPropagation(),className:"shrink-0"}),F("span",{className:"text-muted-foreground shrink-0 select-none",children:"⠿"}),F(H,{className:"h-4 w-4 text-muted-foreground shrink-0"}),O("div",{className:"flex flex-col min-w-0",children:[F("span",{className:"text-sm truncate",children:e.name}),F("span",{className:"text-xs text-muted-foreground truncate",children:e.email})]})]},e.id))})]}),O("div",{className:"px-3 py-2 bg-muted/20 border rounded-lg text-xs text-muted-foreground flex justify-between",children:[F("span",{children:m("leadership_users_associated_count",{count:we})}),e.length>0&&F("span",{children:m("leadership_users_unassociated_count",{count:e.length})})]}),F(ye,{open:q,onOpenChange:_e,leader:L,prefilledLeaderId:$,title:m(L?"edit_name":$?"leadership_add_subordinate":"leadership_add_root")},`leadership-dialog-${h}`)]})}export{ye as LeadershipDialog,Ne as LeadershipForm,Se as LeadershipPage,ne as buildHierarchy,te as filterAndPromoteOrphans,de as flattenTree,ue as useCreateMultipleLeadersMutation,ce as useCreateSingleLeaderMutation,oe as useLeadershipApi,he as useRemoveLeaderMutation,_e as useSyncSubordinatesMutation,me as useUpdateLeaderMutation};
1
+ import e from"i18next";import{useMemo as r,useState as a,useEffect as s,useRef as i,useCallback as t}from"react";import{useQuery as n,useQueryClient as d,useMutation as o}from"@tanstack/react-query";import{useAuth as l,TokenManager as c,useQualiexUsers as u,getSupabaseClient as m,Label as h,Input as _,Select as f,SelectTrigger as p,SelectValue as g,SelectContent as w,ScrollArea as v,SelectItem as x,Button as N,AlertDialog as y,AlertDialogTrigger as b,AlertDialogContent as E,AlertDialogHeader as S,AlertDialogTitle as I,AlertDialogDescription as C,AlertDialogFooter as k,AlertDialogCancel as U,AlertDialogAction as q,Checkbox as A,Dialog as L,DialogContent as $,DialogHeader as P,DialogTitle as j,DialogBody as z,TreeTable as D,cn as T}from"forlogic-core";import{toast as K}from"sonner";import{useTranslation as M}from"react-i18next";import{jsxs as O,jsx as F,Fragment as V}from"react/jsx-runtime";import{Loader2 as Q,Trash2 as J,User as H,Mail as B,Plus as R,ChevronDown as W,ChevronRight as G,Users as X,Pencil as Y,UserPlus as Z}from"lucide-react";import{z as ee}from"zod";import{appendErrors as re,useForm as ae}from"react-hook-form";import{validateFieldsNatively as se,toNestErrors as ie}from"@hookform/resolvers";let te=null;function ne(e){te=e}function de(){return te}function oe(e,r){const a=e.map(e=>({...e})),s=new Set(a.filter(e=>!r.has(e.id_user)).map(e=>e.id_user));return a.forEach(e=>{if(e.id_leader&&s.has(e.id_leader)){let r=e.id_leader;for(;r&&s.has(r);){const e=a.find(e=>e.id_user===r);r=e?.id_leader||null}e.id_leader=r}}),a.filter(e=>r.has(e.id_user))}function le(e){const r=new Map,a=new Map,s=[];e.forEach(e=>{const s={...e,children:[],level:0};r.set(e.id,s),a.set(e.id_user,s)}),e.forEach(e=>{const i=r.get(e.id);if(e.id_leader){const r=a.get(e.id_leader);if(r)return void r.children.push(i)}s.push(i)});const i=(e,r)=>{e.level=r,e.children.forEach(e=>i(e,r+1))};s.forEach(e=>i(e,0));const t=e=>{e.sort((e,r)=>{const a=e.name||e.id_user||e.email||"",s=r.name||r.id_user||r.email||"";return a.localeCompare(s)}),e.forEach(e=>e.children.length>0&&t(e.children))};return t(s),s}function ce(e){const r=[],a=e=>{r.push(e),e.children.forEach(a)};return e.forEach(a),r}function ue(){const{alias:a,isAuthenticated:s}=l(),i=c.getAccessToken(),{data:t=[]}=u(),d=n({queryKey:["leadership-raw",a],queryFn:async()=>{if(!i||!a)throw new Error("Usuário não autenticado ou unidade não selecionada");const e=de();if(e)return e.list();const r=m(),{data:s,error:t}=await r.schema("common").from("leaders").select("*").eq("is_removed",!1).eq("alias",a);if(t)throw new Error("Erro ao buscar hierarquia de liderança");return s??[]},enabled:!!i&&!!a&&s}),o=r(()=>{const r=d.data;if(!r)return;if(0===r.length)return[];const a={};t.forEach(e=>{a[e.userId]={name:e.userName||e.userEmail,email:e.userEmail||""}});const s=r.map(s=>{const i=r.filter(e=>e.id_leader===s.id_user);return{...s,name:a[s.id_user]?.name||e.t("inactive_user"),email:a[s.id_user]?.email||"",subordinatesCount:i.length,subordinateNames:i.map(e=>a[e.id_user]?.name||"[Usuário inativo]").sort((e,r)=>e.localeCompare(r))}}),i=new Set(r.map(e=>e.id_user));return new Set(r.filter(e=>e.id_leader&&!i.has(e.id_leader)).map(e=>e.id_leader)).forEach(i=>{const t=a[i],n=r.filter(e=>e.id_leader===i);s.push({id:`virtual-${i}`,alias:r[0]?.alias||"",id_user:i,id_leader:null,is_removed:!1,is_active:!0,created_at:(new Date).toISOString(),updated_at:(new Date).toISOString(),name:t?.name||e.t("inactive_user"),email:t?.email||"",subordinatesCount:n.length,subordinateNames:n.map(e=>a[e.id_user]?.name||"[Usuário inativo]").sort((e,r)=>e.localeCompare(r))})}),le(s)},[d.data,t]);return{...d,data:o}}const me="common";async function he(e){const r=de();if(r){return(await r.list()).map(e=>({id:e.id,id_user:e.id_user,id_leader:e.id_leader}))}const a=m(),{data:s,error:i}=await a.schema(me).from("leaders").select("id, id_user, id_leader").eq("alias",e).eq("is_removed",!1);if(i)throw i;return s??[]}function _e(){const{alias:e}=l(),r=d(),a=m(),{t:s}=M();return o({mutationFn:async r=>{if(!e)throw new Error(s("unit_not_selected","Unidade não selecionada"));if(r.id_user===r.id_leader)throw new Error(s("cannot_be_own_leader","Usuário não pode ser seu próprio líder"));r.id_leader&&await ve(e,r.id_user,r.id_leader);const i=de();if(i)return await i.create([{id_user:r.id_user,id_leader:r.id_leader}]),{id_user:r.id_user,id_leader:r.id_leader};const{data:t,error:n}=await a.schema(me).from("leaders").insert({alias:e,id_user:r.id_user,id_leader:r.id_leader,is_active:!0,is_removed:!1}).select().single();if(n)throw n;return t},onSuccess:()=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),K.success(s("leader_promoted_success","Líder virtual promovido com sucesso"))},onError:e=>{K.error(e.message||s("leader_create_error","Erro ao criar líder"))}})}function fe(){const{alias:e}=l(),r=d(),a=m(),{t:s}=M();return o({mutationFn:async r=>{if(!e)throw new Error(s("unit_not_selected","Unidade não selecionada"));if(!r.users.length)throw new Error(s("select_at_least_one",s("leadership_select_subordinates")));const i=r.users.map(e=>e.id_user),t=(await he(e)).filter(e=>i.includes(e.id_user)).map(e=>e.id_user);if(t.length>0)throw new Error(s("users_already_leaders",`Alguns usuários já estão cadastrados como líderes: ${t.join(", ")}`));for(const a of r.users){if(r.id_leader&&a.id_user===r.id_leader)throw new Error(s("cannot_be_own_leader","Usuário não pode ser seu próprio líder"));r.id_leader&&await ve(e,a.id_user,r.id_leader)}const n=de();if(n){const e=r.users.map(e=>({id_user:e.id_user,id_leader:r.id_leader}));return await n.create(e),e}const d=r.users.map(a=>({alias:e,id_user:a.id_user,id_leader:r.id_leader,is_active:!0,is_removed:!1})),{data:o,error:l}=await a.schema(me).from("leaders").insert(d).select();if(l)throw l;return o},onSuccess:a=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),K.success(s("subordinates_added_success",`${a?.length||0} liderado(s) adicionado(s) com sucesso`))},onError:e=>{K.error(e.message||s("subordinates_add_error","Erro ao adicionar liderados"))}})}function pe(){const{alias:e}=l(),r=d(),a=m(),{t:s}=M();return o({mutationFn:async r=>{if(!e)throw new Error(s("unit_not_selected","Unidade não selecionada"));const i=(await he(e)).find(e=>e.id===r.id);if(!i)throw new Error(s("leader_not_found","Líder não encontrado"));if(i.id_user===r.id_leader)throw new Error(s("cannot_be_own_leader","Usuário não pode ser seu próprio líder"));r.id_leader&&await ve(e,i.id_user,r.id_leader,r.id);const t=de();if(t)return await t.updateLeader(r.id,r.id_leader),{...i,id_leader:r.id_leader};const{data:n,error:d}=await a.schema(me).from("leaders").update({id_leader:r.id_leader}).eq("id",r.id).eq("alias",e).select().single();if(d)throw d;return n},onSuccess:()=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),K.success(s("leader_updated_success","Líder atualizado com sucesso"))},onError:e=>{K.error(e.message||s("leader_update_error","Erro ao atualizar líder"))}})}function ge(){const{alias:e}=l(),r=d(),a=m(),{t:s}=M();return o({mutationFn:async r=>{if(!e)throw new Error(s("unit_not_selected","Unidade não selecionada"));const i=de();if(i)return void await i.remove(r);const{error:t}=await a.schema(me).from("leaders").update({is_removed:!0}).eq("id",r).eq("alias",e);if(t)throw t},onSuccess:()=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),K.success(s("leader_removed_success","Líder removido com sucesso"))},onError:e=>{K.error(e.message||s("leader_remove_error","Erro ao remover líder"))}})}function we(){const{alias:e}=l(),r=d(),a=m(),{t:s}=M();return o({mutationFn:async({leaderUserId:r,selectedUsers:i})=>{if(!e)throw new Error(s("unit_not_selected","Unidade não selecionada"));const t=i.map(e=>e.id_user),n=await he(e),d=n.filter(e=>e.id_leader===r),o=n.filter(e=>t.includes(e.id_user)),l=new Set(t),c=d.filter(e=>!l.has(e.id_user)),u=o.filter(e=>e.id_leader!==r),m=new Set(o.map(e=>e.id_user)),h=i.filter(e=>!m.has(e.id_user));for(const a of u)await ve(e,a.id_user,r,a.id);for(const a of h){if(a.id_user===r)throw new Error(s("cannot_be_own_leader","Usuário não pode ser seu próprio líder"));await ve(e,a.id_user,r)}const _=de();if(_){for(const e of c)await _.remove(e.id);for(const e of u)await _.updateLeader(e.id,r);return h.length&&await _.create(h.map(e=>({id_user:e.id_user,id_leader:r}))),{unlinked:c.length,updated:u.length,created:h.length}}const f=[];if(c.length){const r=c.map(e=>e.id);f.push(a.schema(me).from("leaders").update({is_removed:!0}).in("id",r).eq("alias",e))}if(u.length){const s=u.map(e=>e.id);f.push(a.schema(me).from("leaders").update({id_leader:r}).in("id",s).eq("alias",e))}if(h.length){const s=h.map(a=>({alias:e,id_user:a.id_user,id_leader:r,is_active:!0,is_removed:!1}));f.push(a.schema(me).from("leaders").insert(s))}const p=(await Promise.all(f)).find(e=>e?.error);if(p?.error)throw p.error;return{unlinked:c.length,updated:u.length,created:h.length}},onSuccess:a=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),K.success(s("subordinates_synced_success",`Subordinados sincronizados (${a.created} adicionados, ${a.updated} atualizados, ${a.unlinked} removidos)`))},onError:e=>{K.error(e.message||s("subordinates_sync_error","Erro ao sincronizar subordinados"))}})}async function ve(r,a,s,i){const t=await he(r),n=i?t.filter(e=>e.id!==i):t,d=new Set;let o=s;for(;o;){if(d.has(o))throw new Error(e.t("leadership_cycle_error"));if(o===a)throw new Error("Esta associação criaria um ciclo na hierarquia");d.add(o);const r=n.find(e=>e.id_user===o);o=r?.id_leader||null}}var xe=function(e,r){for(var a={};e.length;){var s=e[0],i=s.code,t=s.message,n=s.path.join(".");if(!a[n])if("unionErrors"in s){var d=s.unionErrors[0].errors[0];a[n]={message:d.message,type:d.code}}else a[n]={message:t,type:i};if("unionErrors"in s&&s.unionErrors.forEach(function(r){return r.errors.forEach(function(r){return e.push(r)})}),r){var o=a[n].types,l=o&&o[s.code];a[n]=re(n,r,a,i,l?[].concat(l,s.message):s.message)}e.shift()}return a},Ne=function(e,r,a){return void 0===a&&(a={}),function(s,i,t){try{return Promise.resolve(function(i,n){try{var d=Promise.resolve(e["sync"===a.mode?"parse":"parseAsync"](s,r)).then(function(e){return t.shouldUseNativeValidation&&se({},t),{errors:{},values:a.raw?s:e}})}catch(o){return n(o)}return d&&d.then?d.then(void 0,n):d}(0,function(e){if(function(e){return Array.isArray(null==e?void 0:e.errors)}(e))return{values:{},errors:ie(xe(e.errors,!t.shouldUseNativeValidation&&"all"===t.criteriaMode),t)};throw e}))}catch(n){return Promise.reject(n)}}};const ye=ee.object({id_leader:ee.string().nullable(),id_users:ee.array(ee.string()).min(1,e.t("leadership_select_subordinates"))}),be=ee.object({id_leader:ee.string().nullable(),id_users:ee.array(ee.string())});function Ee({value:e,onChange:r,excludeUserIds:t=[],error:n}){const{t:d}=M(),{data:o=[],isLoading:l}=u(),[c,m]=a(""),f=i(null),p=i(0),g=o.filter(e=>!t.includes(e.userId||"")).filter(e=>{const r=c.toLowerCase(),a=e.userName?.toLowerCase().includes(r);return a}).sort((r,a)=>{const s=e.includes(r.userId),i=e.includes(a.userId);if(s&&!i)return-1;if(!s&&i)return 1;const t=r.userName||r.userEmail||"",n=a.userName||a.userEmail||"";return t.localeCompare(n)});return s(()=>{f.current&&p.current>0&&(f.current.scrollTop=p.current)},[g]),O("div",l?{className:"flex items-center justify-center p-4",children:[F(Q,{className:"h-6 w-6 animate-spin"}),F("span",{className:"ml-2",children:d("loading")})]}:{className:"space-y-2",children:[F(_,{placeholder:d("search_user_placeholder"),value:c,onChange:e=>m(e.target.value)}),F("div",{ref:f,className:"border rounded-md p-4 max-h-[300px] overflow-y-auto",children:0===g.length?F("p",{className:"text-sm text-muted-foreground",children:d("search_user_placeholder")}):F("div",{className:"space-y-2",children:g.map(a=>O("div",{className:"flex items-center space-x-2",children:[F(A,{id:a.userId,checked:e.includes(a.userId),onCheckedChange:()=>{return s=a.userId,f.current&&(p.current=f.current.scrollTop),void(e.includes(s)?r(e.filter(e=>e!==s)):r([...e,s]));var s}}),F(h,{htmlFor:a.userId,className:"flex-1 cursor-pointer",children:a.userName||a.userEmail})]},a.userId))})}),e.length>0&&F("p",{className:"text-sm text-muted-foreground",children:d("selected_count",{count:e.length})}),n&&F("p",{className:"text-sm text-destructive",children:n})]})}function Se({leader:e,prefilledLeaderId:r,onSuccess:i}){const{t:t}=M(),{alias:n}=l(),d=!!e,o=e?.id.startsWith("virtual-"),c=fe(),m=_e(),A=pe(),L=we(),$=ge(),{data:P=[]}=ue(),{data:j=[]}=u(),[z,D]=a(""),T=ce(P).map(e=>e.id_user),K=d?ce(P).filter(r=>r.id_leader===e.id_user).map(e=>e.id_user):[],H=ae({resolver:Ne(d?be:ye),defaultValues:{id_leader:r||(d?e?.id_leader:null)||null,id_users:d?K:[]}});s(()=>{if(e){const r=ce(P).filter(r=>r.id_leader===e.id_user).map(e=>e.id_user);H.reset({id_leader:e.id_leader||null,id_users:r})}else r?H.reset({id_leader:r,id_users:[]}):H.reset({id_leader:null,id_users:[]})},[n,e?.id,e?.id_user,e?.id_leader,r,P]);const B=c.isPending||m.isPending||A.isPending||L.isPending||$.isPending,R=H.watch("id_leader"),W=H.watch("id_users"),G=d?[e.id_user,...T.filter(r=>r!==e.id_user&&!W.includes(r)&&!K.includes(r))]:[R,...T.filter(e=>!W.includes(e))].filter(Boolean);return O("form",{onSubmit:H.handleSubmit(async r=>{try{if(d)if(o){await m.mutateAsync({id_user:e.id_user,id_leader:r.id_leader});const a=j.filter(e=>r.id_users.includes(e.userId)).map(e=>({id_user:e.userId}));await L.mutateAsync({leaderUserId:e.id_user,selectedUsers:a})}else{await A.mutateAsync({id:e.id,id_leader:r.id_leader});const a=j.filter(e=>r.id_users.includes(e.userId)).map(e=>({id_user:e.userId}));await L.mutateAsync({leaderUserId:e.id_user,selectedUsers:a})}else{const e=j.filter(e=>r.id_users.includes(e.userId)).map(e=>({id_user:e.userId}));await c.mutateAsync({id_leader:r.id_leader,users:e})}i?.()}catch(a){}}),className:"space-y-4",children:[d&&O("div",{children:[F(h,{children:t("leader")}),F(_,{value:j.find(r=>r.userId===e.id_user)?.userName||e.name||t("inactive_user"),disabled:!0,className:"bg-muted"})]}),O("div",{children:[F(h,{children:t("leadership_immediate_superior")}),O(f,{value:R||"none",onValueChange:e=>H.setValue("id_leader","none"===e?null:e),children:[F(p,{children:F(g,{placeholder:t("select_placeholder")})}),O(w,{children:[F("div",{className:"sticky top-0 z-10 bg-background p-2 border-b",children:F(_,{placeholder:t("leadership_search_superior"),value:z,onChange:e=>D(e.target.value),onKeyDown:e=>e.stopPropagation(),onClick:e=>e.stopPropagation(),className:"h-8"})}),O(v,{className:"h-[200px]",children:[F(x,{value:"none",children:t("none_bracketed")}),j.filter(r=>{const a=d?r.userId!==e.id_user:!W.includes(r.userId),s=!z||r.userName?.toLowerCase().includes(z.toLowerCase());return a&&s}).sort((e,r)=>{const a=e.userName||e.userEmail||"",s=r.userName||r.userEmail||"";return a.localeCompare(s)}).map(e=>F(x,{value:e.userId,children:e.userName},e.userId))]})]})]},`superior-select-${n}`),H.formState.errors.id_leader&&F("p",{className:"text-sm text-destructive mt-1",children:H.formState.errors.id_leader.message})]}),O("div",{children:[O(h,{children:[t("subordinates")," *"]}),F(Ee,{value:W,onChange:e=>H.setValue("id_users",e),excludeUserIds:G,error:H.formState.errors.id_users?.message},`users-multiselect-${n}`)]}),O("div",{className:"flex items-center justify-between gap-2",children:[F(N,{type:"submit",disabled:B||!d&&0===W.length,children:B&&!$.isPending?O(V,{children:[F(Q,{className:"mr-2 h-4 w-4 animate-spin"}),t(d?"updating":"saving")]}):t(d?"update":"create")}),d&&!R&&0===W.length&&O(y,{children:[F(b,{asChild:!0,children:F(N,{type:"button",variant:"destructive",disabled:B,className:"ml-auto",children:$.isPending?O(V,{children:[F(Q,{className:"mr-2 h-4 w-4 animate-spin"}),t("removing")]}):O(V,{children:[F(J,{className:"mr-2 h-4 w-4"}),t("remove")]})})}),O(E,{children:[O(S,{children:[F(I,{children:t("confirm_removal")}),F(C,{children:t("leadership_remove_confirmation")})]}),O(k,{children:[F(U,{children:t("cancel")}),F(q,{onClick:async()=>{if(e)try{await $.mutateAsync(e.id),i?.()}catch(r){}},children:t("remove")})]})]})]})]})]})}function Ie({open:e,onOpenChange:r,leader:a,prefilledLeaderId:s,title:i}){return F(L,{open:e,onOpenChange:r,children:O($,{variant:"form",className:"sm:max-w-[500px]",children:[F(P,{showSeparator:!0,children:F(j,{children:i})}),F(z,{children:F(Se,{leader:a,prefilledLeaderId:s,onSuccess:()=>r(!1)})})]})})}const Ce="leadership-expanded-nodes",ke=(e,r)=>{try{localStorage.setItem(`${Ce}-${e}`,JSON.stringify(Array.from(r)))}catch{}};function Ue({unassociatedUsers:e=[],onAssociateUser:i,onMoveNode:n,onMoveNodes:d,columns:o,nameHeader:c,rootDropLabel:u}={}){const{t:m}=M(),{alias:h}=l(),{data:_,isLoading:f,error:p,refetch:g}=ue(),w=pe(),v=_e(),[x,y]=a(()=>h?(e=>{try{const r=localStorage.getItem(`${Ce}-${e}`);if(r)return new Set(JSON.parse(r))}catch{}return new Set})(h):new Set),[b,E]=a([]),[S,I]=a(new Set),[C,k]=a(!0),[U,q]=a(!1),[L,$]=a(),[P,j]=a(null),z=r(()=>_?ce(_):[],[_]),K=r(()=>z.map(e=>e.id),[z]),Q=K.length>0&&b.length===K.length,J=z.filter(e=>e.children.length>0).every(e=>x.has(e.id));s(()=>{if(_&&_.length>0&&h){if(!localStorage.getItem(`${Ce}-${h}`)){const e=_.map(e=>e.id),r=new Set(e);y(r),ke(h,r)}}},[_,h]);const ee=t(e=>{y(r=>{const a=new Set(r);return a.has(e)?a.delete(e):a.add(e),h&&ke(h,a),a})},[h]),re=t(()=>{if(J){const e=new Set;y(e),h&&ke(h,e)}else{const e=new Set(z.filter(e=>e.children.length>0).map(e=>e.id));y(e),h&&ke(h,e)}},[J,z,h]),ae=t(e=>{E(r=>r.includes(e)?r.filter(r=>r!==e):[...r,e])},[]),se=t(()=>{E(Q?[]:K)},[Q,K]),ie=t(e=>{I(r=>{const a=new Set(r);return a.has(e)?a.delete(e):a.add(e),a})},[]),te=t(e=>z.find(r=>r.id===e),[z]),ne=t((r,a)=>{if(n)return void n(r,a);const s=e.find(e=>e.id===r);if(s){if(i){const e=a?te(a):null;i(s.id,e?.id_user||null)}else v.mutate({id_user:s.id,id_leader:a&&te(a)?.id_user||null});return}const t=te(r);if(!t)return;const d=a?te(a):null;w.mutate({id:t.id,id_leader:d?.id_user||null})},[n,e,i,te,w,v]),de=t((e,r)=>{d?d(e,r):(e.forEach(e=>ne(e,r)),E([]))},[d,ne]),oe=t(e=>{$(e),j(null),q(!0)},[]),le=t(()=>{$(void 0),j(null),q(!0)},[]),me=t(()=>{q(!1),$(void 0),j(null)},[]),he=t((e,r)=>{const a=S.has(e)&&S.size>1?Array.from(S):[e];r.dataTransfer.effectAllowed="move",r.dataTransfer.setData("text/plain",e),r.dataTransfer.setData("application/x-tree-ids",JSON.stringify(a)),r.currentTarget.style.opacity="0.4"},[S]),fe=r(()=>[{key:"subordinatesCount",header:m("subordinates"),hoverContent:e=>e.subordinateNames&&e.subordinateNames.length>0?O("div",{className:"space-y-1.5",children:[F("p",{className:"text-xs font-medium text-muted-foreground mb-1",children:m("leadership_direct_subordinates")}),[...e.subordinateNames].sort((e,r)=>e.localeCompare(r)).map(e=>O("div",{className:"flex items-center gap-2 text-sm",children:[F(H,{className:"h-3 w-3 text-muted-foreground"}),F("span",{children:e})]},e))]}):F("p",{className:"text-xs text-muted-foreground",children:m("leadership_no_direct_subordinates")})},{key:"email",header:m("email"),className:"text-left",width:180,render:e=>O("span",{className:"flex items-center gap-1.5 text-muted-foreground text-sm",children:[F(B,{className:"h-3.5 w-3.5"}),e.email||"—"]})}],[m]),ge=o??fe;if(f)return F("div",{className:"flex items-center justify-center h-full",children:O("div",{className:"text-center space-y-2",children:[F("div",{className:"animate-spin h-8 w-8 border-4 border-primary border-t-transparent rounded-full mx-auto"}),F("p",{className:"text-sm text-muted-foreground",children:m("loading")})]})});if(p)return F("div",{className:"flex items-center justify-center h-full",children:O("div",{className:"text-center",children:[F("p",{className:"text-destructive mb-4",children:m("leadership_load_error")}),F(N,{onClick:()=>g(),children:m("try_again")})]})});const we=z.filter(e=>e.name!==m("inactive_user")).length;return O("div",{className:"flex flex-col h-full gap-3 p-4",children:[O("div",{className:"flex items-center justify-between",children:[O("div",{className:"flex gap-2 items-center",children:[O(N,{size:"sm",onClick:le,children:[F(R,{className:"h-4 w-4 mr-2"}),m("leadership_define_leader")]}),F(N,{size:"sm",variant:"outline",onClick:re,children:O(V,J?{children:[F(W,{className:"h-4 w-4 mr-1"}),m("collapse")]}:{children:[F(G,{className:"h-4 w-4 mr-1"}),m("expand")]})}),F("div",{className:"flex items-center gap-2 ml-4",children:O("div",{className:"flex items-center gap-2 px-3 py-1.5 bg-muted rounded-md",children:[F(X,{className:"h-4 w-4 text-muted-foreground"}),F("span",{className:"text-sm font-medium",children:m("leadership_users_associated",{count:we})})]})})]}),F("p",{className:"text-xs text-muted-foreground",children:m("leadership_drag_hint")})]}),F(D,{data:_||[],columns:ge,nameKey:"name",nameHeader:c??m("leader"),expandedIds:x,onToggleExpand:ee,iconComponent:F(X,{className:"h-4 w-4 text-muted-foreground shrink-0"}),rowActionsVariant:"inline",enableRowDrag:!0,enableSelection:!0,selectedIds:b,onSelectItem:ae,onSelectAll:se,isAllSelected:Q,onMoveNode:ne,onMoveNodes:de,rootDropLabel:u??m("leadership_make_root"),emptyMessage:m("leadership_no_hierarchy"),renderActions:e=>F(N,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>oe(e),children:F(Y,{className:"h-4 w-4"})})}),e.length>0&&O("div",{className:"border rounded-lg overflow-hidden",children:[O("button",{type:"button",onClick:()=>k(e=>!e),className:"w-full px-4 py-2.5 bg-muted/50 border-b flex items-center gap-2 hover:bg-muted/70 transition-colors cursor-pointer",children:[F(C?W:G,{className:"h-4 w-4 text-muted-foreground shrink-0"}),F(Z,{className:"h-4 w-4 text-muted-foreground"}),F("span",{className:"text-sm font-medium",children:m("leadership_unassociated_users")}),O("span",{className:"text-xs text-muted-foreground ml-1",children:["(",e.length,")"]}),S.size>0&&O("span",{className:"text-xs text-primary ml-1",children:["(",m("selected_count",{count:S.size}),")"]}),F("span",{className:"text-xs text-muted-foreground ml-auto",children:m("leadership_drag_to_hierarchy")})]}),C&&F("div",{className:"divide-y",children:e.map(e=>O("div",{draggable:!0,onDragStart:r=>he(e.id,r),onDragEnd:e=>{e.currentTarget.style.opacity="1"},className:T("flex items-center gap-3 px-4 py-2.5 hover:bg-accent/50 cursor-grab active:cursor-grabbing transition-colors",S.has(e.id)&&"bg-primary/5"),children:[F(A,{checked:S.has(e.id),onCheckedChange:()=>ie(e.id),onClick:e=>e.stopPropagation(),className:"shrink-0"}),F("span",{className:"text-muted-foreground shrink-0 select-none",children:"⠿"}),F(H,{className:"h-4 w-4 text-muted-foreground shrink-0"}),O("div",{className:"flex flex-col min-w-0",children:[F("span",{className:"text-sm truncate",children:e.name}),F("span",{className:"text-xs text-muted-foreground truncate",children:e.email})]})]},e.id))})]}),O("div",{className:"px-3 py-2 bg-muted/20 border rounded-lg text-xs text-muted-foreground flex justify-between",children:[F("span",{children:m("leadership_users_associated_count",{count:we})}),e.length>0&&F("span",{children:m("leadership_users_unassociated_count",{count:e.length})})]}),F(Ie,{open:U,onOpenChange:me,leader:L,prefilledLeaderId:P,title:m(L?"edit_name":P?"leadership_add_subordinate":"leadership_add_root")},`leadership-dialog-${h}`)]})}export{Ie as LeadershipDialog,Se as LeadershipForm,Ue as LeadershipPage,le as buildHierarchy,oe as filterAndPromoteOrphans,ce as flattenTree,de as getLeadershipDataSource,ne as setLeadershipDataSource,fe as useCreateMultipleLeadersMutation,_e as useCreateSingleLeaderMutation,ue as useLeadershipApi,ge as useRemoveLeaderMutation,we as useSyncSubordinatesMutation,pe as useUpdateLeaderMutation};
@@ -1 +1 @@
1
- "use strict";var e=require("i18next"),r=require("react"),s=require("@tanstack/react-query"),a=require("forlogic-core"),t=require("sonner"),i=require("react-i18next"),n=require("react/jsx-runtime"),d=require("lucide-react"),l=require("zod"),o=require("react-hook-form"),u=require("@hookform/resolvers");function c(e){const r=new Map,s=new Map,a=[];e.forEach(e=>{const a={...e,children:[],level:0};r.set(e.id,a),s.set(e.id_user,a)}),e.forEach(e=>{const t=r.get(e.id);if(e.id_leader){const r=s.get(e.id_leader);if(r)return void r.children.push(t)}a.push(t)});const t=(e,r)=>{e.level=r,e.children.forEach(e=>t(e,r+1))};a.forEach(e=>t(e,0));const i=e=>{e.sort((e,r)=>{const s=e.name||e.id_user||e.email||"",a=r.name||r.id_user||r.email||"";return s.localeCompare(a)}),e.forEach(e=>e.children.length>0&&i(e.children))};return i(a),a}function m(e){const r=[],s=e=>{r.push(e),e.children.forEach(s)};return e.forEach(s),r}function h(){const{alias:t,isAuthenticated:i}=a.useAuth(),n=a.TokenManager.getAccessToken(),{data:d=[]}=a.useQualiexUsers(),l=s.useQuery({queryKey:["leadership-raw",t],queryFn:async()=>{if(!n||!t)throw new Error("Usuário não autenticado ou unidade não selecionada");const e=a.getSupabaseClient(),{data:r,error:s}=await e.schema("common").from("leaders").select("*").eq("is_removed",!1).eq("alias",t);if(s)throw new Error("Erro ao buscar hierarquia de liderança");return r??[]},enabled:!!n&&!!t&&i}),o=r.useMemo(()=>{const r=l.data;if(!r)return;if(0===r.length)return[];const s={};d.forEach(e=>{s[e.userId]={name:e.userName||e.userEmail,email:e.userEmail||""}});const a=r.map(a=>{const t=r.filter(e=>e.id_leader===a.id_user);return{...a,name:s[a.id_user]?.name||e.t("inactive_user"),email:s[a.id_user]?.email||"",subordinatesCount:t.length,subordinateNames:t.map(e=>s[e.id_user]?.name||"[Usuário inativo]").sort((e,r)=>e.localeCompare(r))}}),t=new Set(r.map(e=>e.id_user));return new Set(r.filter(e=>e.id_leader&&!t.has(e.id_leader)).map(e=>e.id_leader)).forEach(t=>{const i=s[t],n=r.filter(e=>e.id_leader===t);a.push({id:`virtual-${t}`,alias:r[0]?.alias||"",id_user:t,id_leader:null,is_removed:!1,is_active:!0,created_at:(new Date).toISOString(),updated_at:(new Date).toISOString(),name:i?.name||e.t("inactive_user"),email:i?.email||"",subordinatesCount:n.length,subordinateNames:n.map(e=>s[e.id_user]?.name||"[Usuário inativo]").sort((e,r)=>e.localeCompare(r))})}),c(a)},[l.data,d]);return{...l,data:o}}const _="common";function p(){const{alias:e}=a.useAuth(),r=s.useQueryClient(),n=a.getSupabaseClient(),{t:d}=i.useTranslation();return s.useMutation({mutationFn:async r=>{if(!e)throw new Error(d("unit_not_selected","Unidade não selecionada"));if(r.id_user===r.id_leader)throw new Error(d("cannot_be_own_leader","Usuário não pode ser seu próprio líder"));r.id_leader&&await w(n,e,r.id_user,r.id_leader);const{data:s,error:a}=await n.schema(_).from("leaders").insert({alias:e,id_user:r.id_user,id_leader:r.id_leader,is_active:!0,is_removed:!1}).select().single();if(a)throw a;return s},onSuccess:()=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),t.toast.success(d("leader_promoted_success","Líder virtual promovido com sucesso"))},onError:e=>{t.toast.error(e.message||d("leader_create_error","Erro ao criar líder"))}})}function f(){const{alias:e}=a.useAuth(),r=s.useQueryClient(),n=a.getSupabaseClient(),{t:d}=i.useTranslation();return s.useMutation({mutationFn:async r=>{if(!e)throw new Error(d("unit_not_selected","Unidade não selecionada"));if(!r.users.length)throw new Error(d("select_at_least_one",d("leadership_select_subordinates")));const s=r.users.map(e=>e.id_user),{data:a}=await n.schema(_).from("leaders").select("id_user").eq("alias",e).in("id_user",s).eq("is_removed",!1);if(a&&a.length>0){const e=a.map(e=>e.id_user);throw new Error(d("users_already_leaders",`Alguns usuários já estão cadastrados como líderes: ${e.join(", ")}`))}for(const o of r.users){if(r.id_leader&&o.id_user===r.id_leader)throw new Error(d("cannot_be_own_leader","Usuário não pode ser seu próprio líder"));r.id_leader&&await w(n,e,o.id_user,r.id_leader)}const t=r.users.map(s=>({alias:e,id_user:s.id_user,id_leader:r.id_leader,is_active:!0,is_removed:!1})),{data:i,error:l}=await n.schema(_).from("leaders").insert(t).select();if(l)throw l;return i},onSuccess:s=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),t.toast.success(d("subordinates_added_success",`${s?.length||0} liderado(s) adicionado(s) com sucesso`))},onError:e=>{t.toast.error(e.message||d("subordinates_add_error","Erro ao adicionar liderados"))}})}function x(){const{alias:e}=a.useAuth(),r=s.useQueryClient(),n=a.getSupabaseClient(),{t:d}=i.useTranslation();return s.useMutation({mutationFn:async r=>{if(!e)throw new Error(d("unit_not_selected","Unidade não selecionada"));const{data:s}=await n.schema(_).from("leaders").select("id_user").eq("id",r.id).eq("alias",e).single();if(!s)throw new Error(d("leader_not_found","Líder não encontrado"));if(s.id_user===r.id_leader)throw new Error(d("cannot_be_own_leader","Usuário não pode ser seu próprio líder"));r.id_leader&&await w(n,e,s.id_user,r.id_leader,r.id);const{data:a,error:t}=await n.schema(_).from("leaders").update({id_leader:r.id_leader}).eq("id",r.id).eq("alias",e).select().single();if(t)throw t;return a},onSuccess:()=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),t.toast.success(d("leader_updated_success","Líder atualizado com sucesso"))},onError:e=>{t.toast.error(e.message||d("leader_update_error","Erro ao atualizar líder"))}})}function g(){const{alias:e}=a.useAuth(),r=s.useQueryClient(),n=a.getSupabaseClient(),{t:d}=i.useTranslation();return s.useMutation({mutationFn:async r=>{if(!e)throw new Error(d("unit_not_selected","Unidade não selecionada"));const{error:s}=await n.schema(_).from("leaders").update({is_removed:!0}).eq("id",r).eq("alias",e);if(s)throw s},onSuccess:()=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),t.toast.success(d("leader_removed_success","Líder removido com sucesso"))},onError:e=>{t.toast.error(e.message||d("leader_remove_error","Erro ao remover líder"))}})}function v(){const{alias:e}=a.useAuth(),r=s.useQueryClient(),n=a.getSupabaseClient(),{t:d}=i.useTranslation();return s.useMutation({mutationFn:async({leaderUserId:r,selectedUsers:s})=>{if(!e)throw new Error(d("unit_not_selected","Unidade não selecionada"));const a=s.map(e=>e.id_user),t=await Promise.all([n.schema(_).from("leaders").select("id, id_user, id_leader").eq("alias",e).eq("is_removed",!1).eq("id_leader",r),n.schema(_).from("leaders").select("id, id_user, id_leader").eq("alias",e).eq("is_removed",!1).in("id_user",a.length?a:["__none__"])]),[{data:i,error:l},{data:o,error:u}]=t;if(l)throw l;if(u)throw u;const c=i||[],m=o||[],h=new Set(a),p=c.filter(e=>!h.has(e.id_user)),f=m.filter(e=>e.id_leader!==r),x=new Set(m.map(e=>e.id_user)),g=s.filter(e=>!x.has(e.id_user));for(const d of f)await w(n,e,d.id_user,r,d.id);for(const _ of g){if(_.id_user===r)throw new Error(d("cannot_be_own_leader","Usuário não pode ser seu próprio líder"));await w(n,e,_.id_user,r)}const v=[];if(p.length){const r=p.map(e=>e.id);v.push(n.schema(_).from("leaders").update({is_removed:!0}).in("id",r).eq("alias",e))}if(f.length){const s=f.map(e=>e.id);v.push(n.schema(_).from("leaders").update({id_leader:r}).in("id",s).eq("alias",e))}if(g.length){const s=g.map(s=>({alias:e,id_user:s.id_user,id_leader:r,is_active:!0,is_removed:!1}));v.push(n.schema(_).from("leaders").insert(s))}const j=(await Promise.all(v)).find(e=>e?.error);if(j?.error)throw j.error;return{unlinked:p.length,updated:f.length,created:g.length}},onSuccess:s=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),t.toast.success(d("subordinates_synced_success",`Subordinados sincronizados (${s.created} adicionados, ${s.updated} atualizados, ${s.unlinked} removidos)`))},onError:e=>{t.toast.error(e.message||d("subordinates_sync_error","Erro ao sincronizar subordinados"))}})}async function w(r,s,a,t,i){const{data:n,error:d}=await r.schema(_).from("leaders").select("id, id_user, id_leader").eq("alias",s).eq("is_removed",!1);if(d)throw d;const l=i?n.filter(e=>e.id!==i):n,o=new Set;let u=t;for(;u;){if(o.has(u))throw new Error(e.t("leadership_cycle_error"));if(u===a)throw new Error("Esta associação criaria um ciclo na hierarquia");o.add(u);const r=l.find(e=>e.id_user===u);u=r?.id_leader||null}}var j=function(e,r){for(var s={};e.length;){var a=e[0],t=a.code,i=a.message,n=a.path.join(".");if(!s[n])if("unionErrors"in a){var d=a.unionErrors[0].errors[0];s[n]={message:d.message,type:d.code}}else s[n]={message:i,type:t};if("unionErrors"in a&&a.unionErrors.forEach(function(r){return r.errors.forEach(function(r){return e.push(r)})}),r){var l=s[n].types,u=l&&l[a.code];s[n]=o.appendErrors(n,r,s,t,u?[].concat(u,a.message):a.message)}e.shift()}return s},b=function(e,r,s){return void 0===s&&(s={}),function(a,t,i){try{return Promise.resolve(function(t,n){try{var d=Promise.resolve(e["sync"===s.mode?"parse":"parseAsync"](a,r)).then(function(e){return i.shouldUseNativeValidation&&u.validateFieldsNatively({},i),{errors:{},values:s.raw?a:e}})}catch(l){return n(l)}return d&&d.then?d.then(void 0,n):d}(0,function(e){if(function(e){return Array.isArray(null==e?void 0:e.errors)}(e))return{values:{},errors:u.toNestErrors(j(e.errors,!i.shouldUseNativeValidation&&"all"===i.criteriaMode),i)};throw e}))}catch(n){return Promise.reject(n)}}};const y=l.z.object({id_leader:l.z.string().nullable(),id_users:l.z.array(l.z.string()).min(1,e.t("leadership_select_subordinates"))}),N=l.z.object({id_leader:l.z.string().nullable(),id_users:l.z.array(l.z.string())});function C({value:e,onChange:s,excludeUserIds:t=[],error:l}){const{t:o}=i.useTranslation(),{data:u=[],isLoading:c}=a.useQualiexUsers(),[m,h]=r.useState(""),_=r.useRef(null),p=r.useRef(0),f=u.filter(e=>!t.includes(e.userId||"")).filter(e=>{const r=m.toLowerCase(),s=e.userName?.toLowerCase().includes(r);return s}).sort((r,s)=>{const a=e.includes(r.userId),t=e.includes(s.userId);if(a&&!t)return-1;if(!a&&t)return 1;const i=r.userName||r.userEmail||"",n=s.userName||s.userEmail||"";return i.localeCompare(n)});return r.useEffect(()=>{_.current&&p.current>0&&(_.current.scrollTop=p.current)},[f]),c?n.jsxs("div",{className:"flex items-center justify-center p-4",children:[n.jsx(d.Loader2,{className:"h-6 w-6 animate-spin"}),n.jsx("span",{className:"ml-2",children:o("loading")})]}):n.jsxs("div",{className:"space-y-2",children:[n.jsx(a.Input,{placeholder:o("search_user_placeholder"),value:m,onChange:e=>h(e.target.value)}),n.jsx("div",{ref:_,className:"border rounded-md p-4 max-h-[300px] overflow-y-auto",children:0===f.length?n.jsx("p",{className:"text-sm text-muted-foreground",children:o("search_user_placeholder")}):n.jsx("div",{className:"space-y-2",children:f.map(r=>n.jsxs("div",{className:"flex items-center space-x-2",children:[n.jsx(a.Checkbox,{id:r.userId,checked:e.includes(r.userId),onCheckedChange:()=>{return a=r.userId,_.current&&(p.current=_.current.scrollTop),void(e.includes(a)?s(e.filter(e=>e!==a)):s([...e,a]));var a}}),n.jsx(a.Label,{htmlFor:r.userId,className:"flex-1 cursor-pointer",children:r.userName||r.userEmail})]},r.userId))})}),e.length>0&&n.jsx("p",{className:"text-sm text-muted-foreground",children:o("selected_count",{count:e.length})}),l&&n.jsx("p",{className:"text-sm text-destructive",children:l})]})}function S({leader:e,prefilledLeaderId:s,onSuccess:t}){const{t:l}=i.useTranslation(),{alias:u}=a.useAuth(),c=!!e,_=e?.id.startsWith("virtual-"),w=f(),j=p(),S=x(),E=v(),k=g(),{data:I=[]}=h(),{data:A=[]}=a.useQualiexUsers(),[q,U]=r.useState(""),L=m(I).map(e=>e.id_user),D=c?m(I).filter(r=>r.id_leader===e.id_user).map(e=>e.id_user):[],T=o.useForm({resolver:b(c?N:y),defaultValues:{id_leader:s||(c?e?.id_leader:null)||null,id_users:c?D:[]}});r.useEffect(()=>{if(e){const r=m(I).filter(r=>r.id_leader===e.id_user).map(e=>e.id_user);T.reset({id_leader:e.id_leader||null,id_users:r})}else s?T.reset({id_leader:s,id_users:[]}):T.reset({id_leader:null,id_users:[]})},[u,e?.id,e?.id_user,e?.id_leader,s,I]);const M=w.isPending||j.isPending||S.isPending||E.isPending||k.isPending,z=T.watch("id_leader"),P=T.watch("id_users"),F=c?[e.id_user,...L.filter(r=>r!==e.id_user&&!P.includes(r)&&!D.includes(r))]:[z,...L.filter(e=>!P.includes(e))].filter(Boolean);return n.jsxs("form",{onSubmit:T.handleSubmit(async r=>{try{if(c)if(_){await j.mutateAsync({id_user:e.id_user,id_leader:r.id_leader});const s=A.filter(e=>r.id_users.includes(e.userId)).map(e=>({id_user:e.userId}));await E.mutateAsync({leaderUserId:e.id_user,selectedUsers:s})}else{await S.mutateAsync({id:e.id,id_leader:r.id_leader});const s=A.filter(e=>r.id_users.includes(e.userId)).map(e=>({id_user:e.userId}));await E.mutateAsync({leaderUserId:e.id_user,selectedUsers:s})}else{const e=A.filter(e=>r.id_users.includes(e.userId)).map(e=>({id_user:e.userId}));await w.mutateAsync({id_leader:r.id_leader,users:e})}t?.()}catch(s){}}),className:"space-y-4",children:[c&&n.jsxs("div",{children:[n.jsx(a.Label,{children:l("leader")}),n.jsx(a.Input,{value:A.find(r=>r.userId===e.id_user)?.userName||e.name||l("inactive_user"),disabled:!0,className:"bg-muted"})]}),n.jsxs("div",{children:[n.jsx(a.Label,{children:l("leadership_immediate_superior")}),n.jsxs(a.Select,{value:z||"none",onValueChange:e=>T.setValue("id_leader","none"===e?null:e),children:[n.jsx(a.SelectTrigger,{children:n.jsx(a.SelectValue,{placeholder:l("select_placeholder")})}),n.jsxs(a.SelectContent,{children:[n.jsx("div",{className:"sticky top-0 z-10 bg-background p-2 border-b",children:n.jsx(a.Input,{placeholder:l("leadership_search_superior"),value:q,onChange:e=>U(e.target.value),onKeyDown:e=>e.stopPropagation(),onClick:e=>e.stopPropagation(),className:"h-8"})}),n.jsxs(a.ScrollArea,{className:"h-[200px]",children:[n.jsx(a.SelectItem,{value:"none",children:l("none_bracketed")}),A.filter(r=>{const s=c?r.userId!==e.id_user:!P.includes(r.userId),a=!q||r.userName?.toLowerCase().includes(q.toLowerCase());return s&&a}).sort((e,r)=>{const s=e.userName||e.userEmail||"",a=r.userName||r.userEmail||"";return s.localeCompare(a)}).map(e=>n.jsx(a.SelectItem,{value:e.userId,children:e.userName},e.userId))]})]})]},`superior-select-${u}`),T.formState.errors.id_leader&&n.jsx("p",{className:"text-sm text-destructive mt-1",children:T.formState.errors.id_leader.message})]}),n.jsxs("div",{children:[n.jsxs(a.Label,{children:[l("subordinates")," *"]}),n.jsx(C,{value:P,onChange:e=>T.setValue("id_users",e),excludeUserIds:F,error:T.formState.errors.id_users?.message},`users-multiselect-${u}`)]}),n.jsxs("div",{className:"flex items-center justify-between gap-2",children:[n.jsx(a.Button,{type:"submit",disabled:M||!c&&0===P.length,children:M&&!k.isPending?n.jsxs(n.Fragment,{children:[n.jsx(d.Loader2,{className:"mr-2 h-4 w-4 animate-spin"}),l(c?"updating":"saving")]}):l(c?"update":"create")}),c&&!z&&0===P.length&&n.jsxs(a.AlertDialog,{children:[n.jsx(a.AlertDialogTrigger,{asChild:!0,children:n.jsx(a.Button,{type:"button",variant:"destructive",disabled:M,className:"ml-auto",children:k.isPending?n.jsxs(n.Fragment,{children:[n.jsx(d.Loader2,{className:"mr-2 h-4 w-4 animate-spin"}),l("removing")]}):n.jsxs(n.Fragment,{children:[n.jsx(d.Trash2,{className:"mr-2 h-4 w-4"}),l("remove")]})})}),n.jsxs(a.AlertDialogContent,{children:[n.jsxs(a.AlertDialogHeader,{children:[n.jsx(a.AlertDialogTitle,{children:l("confirm_removal")}),n.jsx(a.AlertDialogDescription,{children:l("leadership_remove_confirmation")})]}),n.jsxs(a.AlertDialogFooter,{children:[n.jsx(a.AlertDialogCancel,{children:l("cancel")}),n.jsx(a.AlertDialogAction,{onClick:async()=>{if(e)try{await k.mutateAsync(e.id),t?.()}catch(r){}},children:l("remove")})]})]})]})]})]})}function E({open:e,onOpenChange:r,leader:s,prefilledLeaderId:t,title:i}){return n.jsx(a.Dialog,{open:e,onOpenChange:r,children:n.jsxs(a.DialogContent,{variant:"form",className:"sm:max-w-[500px]",children:[n.jsx(a.DialogHeader,{showSeparator:!0,children:n.jsx(a.DialogTitle,{children:i})}),n.jsx(a.DialogBody,{children:n.jsx(S,{leader:s,prefilledLeaderId:t,onSuccess:()=>r(!1)})})]})})}const k="leadership-expanded-nodes",I=(e,r)=>{try{localStorage.setItem(`${k}-${e}`,JSON.stringify(Array.from(r)))}catch{}};exports.LeadershipDialog=E,exports.LeadershipForm=S,exports.LeadershipPage=function({unassociatedUsers:e=[],onAssociateUser:s,onMoveNode:t,onMoveNodes:l,columns:o,nameHeader:u,rootDropLabel:c}={}){const{t:_}=i.useTranslation(),{alias:f}=a.useAuth(),{data:g,isLoading:v,error:w,refetch:j}=h(),b=x(),y=p(),[N,C]=r.useState(()=>f?(e=>{try{const r=localStorage.getItem(`${k}-${e}`);if(r)return new Set(JSON.parse(r))}catch{}return new Set})(f):new Set),[S,A]=r.useState([]),[q,U]=r.useState(new Set),[L,D]=r.useState(!0),[T,M]=r.useState(!1),[z,P]=r.useState(),[F,$]=r.useState(null),Q=r.useMemo(()=>g?m(g):[],[g]),O=r.useMemo(()=>Q.map(e=>e.id),[Q]),B=O.length>0&&S.length===O.length,K=Q.filter(e=>e.children.length>0).every(e=>N.has(e.id));r.useEffect(()=>{if(g&&g.length>0&&f){if(!localStorage.getItem(`${k}-${f}`)){const e=g.map(e=>e.id),r=new Set(e);C(r),I(f,r)}}},[g,f]);const V=r.useCallback(e=>{C(r=>{const s=new Set(r);return s.has(e)?s.delete(e):s.add(e),f&&I(f,s),s})},[f]),R=r.useCallback(()=>{if(K){const e=new Set;C(e),f&&I(f,e)}else{const e=new Set(Q.filter(e=>e.children.length>0).map(e=>e.id));C(e),f&&I(f,e)}},[K,Q,f]),H=r.useCallback(e=>{A(r=>r.includes(e)?r.filter(r=>r!==e):[...r,e])},[]),J=r.useCallback(()=>{A(B?[]:O)},[B,O]),W=r.useCallback(e=>{U(r=>{const s=new Set(r);return s.has(e)?s.delete(e):s.add(e),s})},[]),G=r.useCallback(e=>Q.find(r=>r.id===e),[Q]),X=r.useCallback((r,a)=>{if(t)return void t(r,a);const i=e.find(e=>e.id===r);if(i){if(s){const e=a?G(a):null;s(i.id,e?.id_user||null)}else y.mutate({id_user:i.id,id_leader:a&&G(a)?.id_user||null});return}const n=G(r);if(!n)return;const d=a?G(a):null;b.mutate({id:n.id,id_leader:d?.id_user||null})},[t,e,s,G,b,y]),Y=r.useCallback((e,r)=>{l?l(e,r):(e.forEach(e=>X(e,r)),A([]))},[l,X]),Z=r.useCallback(e=>{P(e),$(null),M(!0)},[]),ee=r.useCallback(()=>{P(void 0),$(null),M(!0)},[]),re=r.useCallback(()=>{M(!1),P(void 0),$(null)},[]),se=r.useCallback((e,r)=>{const s=q.has(e)&&q.size>1?Array.from(q):[e];r.dataTransfer.effectAllowed="move",r.dataTransfer.setData("text/plain",e),r.dataTransfer.setData("application/x-tree-ids",JSON.stringify(s)),r.currentTarget.style.opacity="0.4"},[q]),ae=r.useMemo(()=>[{key:"subordinatesCount",header:_("subordinates"),hoverContent:e=>e.subordinateNames&&e.subordinateNames.length>0?n.jsxs("div",{className:"space-y-1.5",children:[n.jsx("p",{className:"text-xs font-medium text-muted-foreground mb-1",children:_("leadership_direct_subordinates")}),[...e.subordinateNames].sort((e,r)=>e.localeCompare(r)).map(e=>n.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[n.jsx(d.User,{className:"h-3 w-3 text-muted-foreground"}),n.jsx("span",{children:e})]},e))]}):n.jsx("p",{className:"text-xs text-muted-foreground",children:_("leadership_no_direct_subordinates")})},{key:"email",header:_("email"),className:"text-left",width:180,render:e=>n.jsxs("span",{className:"flex items-center gap-1.5 text-muted-foreground text-sm",children:[n.jsx(d.Mail,{className:"h-3.5 w-3.5"}),e.email||"—"]})}],[_]),te=o??ae;if(v)return n.jsx("div",{className:"flex items-center justify-center h-full",children:n.jsxs("div",{className:"text-center space-y-2",children:[n.jsx("div",{className:"animate-spin h-8 w-8 border-4 border-primary border-t-transparent rounded-full mx-auto"}),n.jsx("p",{className:"text-sm text-muted-foreground",children:_("loading")})]})});if(w)return n.jsx("div",{className:"flex items-center justify-center h-full",children:n.jsxs("div",{className:"text-center",children:[n.jsx("p",{className:"text-destructive mb-4",children:_("leadership_load_error")}),n.jsx(a.Button,{onClick:()=>j(),children:_("try_again")})]})});const ie=Q.filter(e=>e.name!==_("inactive_user")).length;return n.jsxs("div",{className:"flex flex-col h-full gap-3 p-4",children:[n.jsxs("div",{className:"flex items-center justify-between",children:[n.jsxs("div",{className:"flex gap-2 items-center",children:[n.jsxs(a.Button,{size:"sm",onClick:ee,children:[n.jsx(d.Plus,{className:"h-4 w-4 mr-2"}),_("leadership_define_leader")]}),n.jsx(a.Button,{size:"sm",variant:"outline",onClick:R,children:K?n.jsxs(n.Fragment,{children:[n.jsx(d.ChevronDown,{className:"h-4 w-4 mr-1"}),_("collapse")]}):n.jsxs(n.Fragment,{children:[n.jsx(d.ChevronRight,{className:"h-4 w-4 mr-1"}),_("expand")]})}),n.jsx("div",{className:"flex items-center gap-2 ml-4",children:n.jsxs("div",{className:"flex items-center gap-2 px-3 py-1.5 bg-muted rounded-md",children:[n.jsx(d.Users,{className:"h-4 w-4 text-muted-foreground"}),n.jsx("span",{className:"text-sm font-medium",children:_("leadership_users_associated",{count:ie})})]})})]}),n.jsx("p",{className:"text-xs text-muted-foreground",children:_("leadership_drag_hint")})]}),n.jsx(a.TreeTable,{data:g||[],columns:te,nameKey:"name",nameHeader:u??_("leader"),expandedIds:N,onToggleExpand:V,iconComponent:n.jsx(d.Users,{className:"h-4 w-4 text-muted-foreground shrink-0"}),rowActionsVariant:"inline",enableRowDrag:!0,enableSelection:!0,selectedIds:S,onSelectItem:H,onSelectAll:J,isAllSelected:B,onMoveNode:X,onMoveNodes:Y,rootDropLabel:c??_("leadership_make_root"),emptyMessage:_("leadership_no_hierarchy"),renderActions:e=>n.jsx(a.Button,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>Z(e),children:n.jsx(d.Pencil,{className:"h-4 w-4"})})}),e.length>0&&n.jsxs("div",{className:"border rounded-lg overflow-hidden",children:[n.jsxs("button",{type:"button",onClick:()=>D(e=>!e),className:"w-full px-4 py-2.5 bg-muted/50 border-b flex items-center gap-2 hover:bg-muted/70 transition-colors cursor-pointer",children:[L?n.jsx(d.ChevronDown,{className:"h-4 w-4 text-muted-foreground shrink-0"}):n.jsx(d.ChevronRight,{className:"h-4 w-4 text-muted-foreground shrink-0"}),n.jsx(d.UserPlus,{className:"h-4 w-4 text-muted-foreground"}),n.jsx("span",{className:"text-sm font-medium",children:_("leadership_unassociated_users")}),n.jsxs("span",{className:"text-xs text-muted-foreground ml-1",children:["(",e.length,")"]}),q.size>0&&n.jsxs("span",{className:"text-xs text-primary ml-1",children:["(",_("selected_count",{count:q.size}),")"]}),n.jsx("span",{className:"text-xs text-muted-foreground ml-auto",children:_("leadership_drag_to_hierarchy")})]}),L&&n.jsx("div",{className:"divide-y",children:e.map(e=>n.jsxs("div",{draggable:!0,onDragStart:r=>se(e.id,r),onDragEnd:e=>{e.currentTarget.style.opacity="1"},className:a.cn("flex items-center gap-3 px-4 py-2.5 hover:bg-accent/50 cursor-grab active:cursor-grabbing transition-colors",q.has(e.id)&&"bg-primary/5"),children:[n.jsx(a.Checkbox,{checked:q.has(e.id),onCheckedChange:()=>W(e.id),onClick:e=>e.stopPropagation(),className:"shrink-0"}),n.jsx("span",{className:"text-muted-foreground shrink-0 select-none",children:"⠿"}),n.jsx(d.User,{className:"h-4 w-4 text-muted-foreground shrink-0"}),n.jsxs("div",{className:"flex flex-col min-w-0",children:[n.jsx("span",{className:"text-sm truncate",children:e.name}),n.jsx("span",{className:"text-xs text-muted-foreground truncate",children:e.email})]})]},e.id))})]}),n.jsxs("div",{className:"px-3 py-2 bg-muted/20 border rounded-lg text-xs text-muted-foreground flex justify-between",children:[n.jsx("span",{children:_("leadership_users_associated_count",{count:ie})}),e.length>0&&n.jsx("span",{children:_("leadership_users_unassociated_count",{count:e.length})})]}),n.jsx(E,{open:T,onOpenChange:re,leader:z,prefilledLeaderId:F,title:_(z?"edit_name":F?"leadership_add_subordinate":"leadership_add_root")},`leadership-dialog-${f}`)]})},exports.buildHierarchy=c,exports.filterAndPromoteOrphans=function(e,r){const s=e.map(e=>({...e})),a=new Set(s.filter(e=>!r.has(e.id_user)).map(e=>e.id_user));return s.forEach(e=>{if(e.id_leader&&a.has(e.id_leader)){let r=e.id_leader;for(;r&&a.has(r);){const e=s.find(e=>e.id_user===r);r=e?.id_leader||null}e.id_leader=r}}),s.filter(e=>r.has(e.id_user))},exports.flattenTree=m,exports.useCreateMultipleLeadersMutation=f,exports.useCreateSingleLeaderMutation=p,exports.useLeadershipApi=h,exports.useRemoveLeaderMutation=g,exports.useSyncSubordinatesMutation=v,exports.useUpdateLeaderMutation=x;
1
+ "use strict";var e=require("i18next"),r=require("react"),s=require("@tanstack/react-query"),a=require("forlogic-core"),t=require("sonner"),i=require("react-i18next"),n=require("react/jsx-runtime"),d=require("lucide-react"),l=require("zod"),o=require("react-hook-form"),u=require("@hookform/resolvers");let c=null;function m(){return c}function h(e){const r=new Map,s=new Map,a=[];e.forEach(e=>{const a={...e,children:[],level:0};r.set(e.id,a),s.set(e.id_user,a)}),e.forEach(e=>{const t=r.get(e.id);if(e.id_leader){const r=s.get(e.id_leader);if(r)return void r.children.push(t)}a.push(t)});const t=(e,r)=>{e.level=r,e.children.forEach(e=>t(e,r+1))};a.forEach(e=>t(e,0));const i=e=>{e.sort((e,r)=>{const s=e.name||e.id_user||e.email||"",a=r.name||r.id_user||r.email||"";return s.localeCompare(a)}),e.forEach(e=>e.children.length>0&&i(e.children))};return i(a),a}function _(e){const r=[],s=e=>{r.push(e),e.children.forEach(s)};return e.forEach(s),r}function p(){const{alias:t,isAuthenticated:i}=a.useAuth(),n=a.TokenManager.getAccessToken(),{data:d=[]}=a.useQualiexUsers(),l=s.useQuery({queryKey:["leadership-raw",t],queryFn:async()=>{if(!n||!t)throw new Error("Usuário não autenticado ou unidade não selecionada");const e=m();if(e)return e.list();const r=a.getSupabaseClient(),{data:s,error:i}=await r.schema("common").from("leaders").select("*").eq("is_removed",!1).eq("alias",t);if(i)throw new Error("Erro ao buscar hierarquia de liderança");return s??[]},enabled:!!n&&!!t&&i}),o=r.useMemo(()=>{const r=l.data;if(!r)return;if(0===r.length)return[];const s={};d.forEach(e=>{s[e.userId]={name:e.userName||e.userEmail,email:e.userEmail||""}});const a=r.map(a=>{const t=r.filter(e=>e.id_leader===a.id_user);return{...a,name:s[a.id_user]?.name||e.t("inactive_user"),email:s[a.id_user]?.email||"",subordinatesCount:t.length,subordinateNames:t.map(e=>s[e.id_user]?.name||"[Usuário inativo]").sort((e,r)=>e.localeCompare(r))}}),t=new Set(r.map(e=>e.id_user));return new Set(r.filter(e=>e.id_leader&&!t.has(e.id_leader)).map(e=>e.id_leader)).forEach(t=>{const i=s[t],n=r.filter(e=>e.id_leader===t);a.push({id:`virtual-${t}`,alias:r[0]?.alias||"",id_user:t,id_leader:null,is_removed:!1,is_active:!0,created_at:(new Date).toISOString(),updated_at:(new Date).toISOString(),name:i?.name||e.t("inactive_user"),email:i?.email||"",subordinatesCount:n.length,subordinateNames:n.map(e=>s[e.id_user]?.name||"[Usuário inativo]").sort((e,r)=>e.localeCompare(r))})}),h(a)},[l.data,d]);return{...l,data:o}}const f="common";async function x(e){const r=m();if(r){return(await r.list()).map(e=>({id:e.id,id_user:e.id_user,id_leader:e.id_leader}))}const s=a.getSupabaseClient(),{data:t,error:i}=await s.schema(f).from("leaders").select("id, id_user, id_leader").eq("alias",e).eq("is_removed",!1);if(i)throw i;return t??[]}function g(){const{alias:e}=a.useAuth(),r=s.useQueryClient(),n=a.getSupabaseClient(),{t:d}=i.useTranslation();return s.useMutation({mutationFn:async r=>{if(!e)throw new Error(d("unit_not_selected","Unidade não selecionada"));if(r.id_user===r.id_leader)throw new Error(d("cannot_be_own_leader","Usuário não pode ser seu próprio líder"));r.id_leader&&await y(e,r.id_user,r.id_leader);const s=m();if(s)return await s.create([{id_user:r.id_user,id_leader:r.id_leader}]),{id_user:r.id_user,id_leader:r.id_leader};const{data:a,error:t}=await n.schema(f).from("leaders").insert({alias:e,id_user:r.id_user,id_leader:r.id_leader,is_active:!0,is_removed:!1}).select().single();if(t)throw t;return a},onSuccess:()=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),t.toast.success(d("leader_promoted_success","Líder virtual promovido com sucesso"))},onError:e=>{t.toast.error(e.message||d("leader_create_error","Erro ao criar líder"))}})}function w(){const{alias:e}=a.useAuth(),r=s.useQueryClient(),n=a.getSupabaseClient(),{t:d}=i.useTranslation();return s.useMutation({mutationFn:async r=>{if(!e)throw new Error(d("unit_not_selected","Unidade não selecionada"));if(!r.users.length)throw new Error(d("select_at_least_one",d("leadership_select_subordinates")));const s=r.users.map(e=>e.id_user),a=(await x(e)).filter(e=>s.includes(e.id_user)).map(e=>e.id_user);if(a.length>0)throw new Error(d("users_already_leaders",`Alguns usuários já estão cadastrados como líderes: ${a.join(", ")}`));for(const n of r.users){if(r.id_leader&&n.id_user===r.id_leader)throw new Error(d("cannot_be_own_leader","Usuário não pode ser seu próprio líder"));r.id_leader&&await y(e,n.id_user,r.id_leader)}const t=m();if(t){const e=r.users.map(e=>({id_user:e.id_user,id_leader:r.id_leader}));return await t.create(e),e}const i=r.users.map(s=>({alias:e,id_user:s.id_user,id_leader:r.id_leader,is_active:!0,is_removed:!1})),{data:l,error:o}=await n.schema(f).from("leaders").insert(i).select();if(o)throw o;return l},onSuccess:s=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),t.toast.success(d("subordinates_added_success",`${s?.length||0} liderado(s) adicionado(s) com sucesso`))},onError:e=>{t.toast.error(e.message||d("subordinates_add_error","Erro ao adicionar liderados"))}})}function v(){const{alias:e}=a.useAuth(),r=s.useQueryClient(),n=a.getSupabaseClient(),{t:d}=i.useTranslation();return s.useMutation({mutationFn:async r=>{if(!e)throw new Error(d("unit_not_selected","Unidade não selecionada"));const s=(await x(e)).find(e=>e.id===r.id);if(!s)throw new Error(d("leader_not_found","Líder não encontrado"));if(s.id_user===r.id_leader)throw new Error(d("cannot_be_own_leader","Usuário não pode ser seu próprio líder"));r.id_leader&&await y(e,s.id_user,r.id_leader,r.id);const a=m();if(a)return await a.updateLeader(r.id,r.id_leader),{...s,id_leader:r.id_leader};const{data:t,error:i}=await n.schema(f).from("leaders").update({id_leader:r.id_leader}).eq("id",r.id).eq("alias",e).select().single();if(i)throw i;return t},onSuccess:()=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),t.toast.success(d("leader_updated_success","Líder atualizado com sucesso"))},onError:e=>{t.toast.error(e.message||d("leader_update_error","Erro ao atualizar líder"))}})}function j(){const{alias:e}=a.useAuth(),r=s.useQueryClient(),n=a.getSupabaseClient(),{t:d}=i.useTranslation();return s.useMutation({mutationFn:async r=>{if(!e)throw new Error(d("unit_not_selected","Unidade não selecionada"));const s=m();if(s)return void await s.remove(r);const{error:a}=await n.schema(f).from("leaders").update({is_removed:!0}).eq("id",r).eq("alias",e);if(a)throw a},onSuccess:()=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),t.toast.success(d("leader_removed_success","Líder removido com sucesso"))},onError:e=>{t.toast.error(e.message||d("leader_remove_error","Erro ao remover líder"))}})}function b(){const{alias:e}=a.useAuth(),r=s.useQueryClient(),n=a.getSupabaseClient(),{t:d}=i.useTranslation();return s.useMutation({mutationFn:async({leaderUserId:r,selectedUsers:s})=>{if(!e)throw new Error(d("unit_not_selected","Unidade não selecionada"));const a=s.map(e=>e.id_user),t=await x(e),i=t.filter(e=>e.id_leader===r),l=t.filter(e=>a.includes(e.id_user)),o=new Set(a),u=i.filter(e=>!o.has(e.id_user)),c=l.filter(e=>e.id_leader!==r),h=new Set(l.map(e=>e.id_user)),_=s.filter(e=>!h.has(e.id_user));for(const n of c)await y(e,n.id_user,r,n.id);for(const n of _){if(n.id_user===r)throw new Error(d("cannot_be_own_leader","Usuário não pode ser seu próprio líder"));await y(e,n.id_user,r)}const p=m();if(p){for(const e of u)await p.remove(e.id);for(const e of c)await p.updateLeader(e.id,r);return _.length&&await p.create(_.map(e=>({id_user:e.id_user,id_leader:r}))),{unlinked:u.length,updated:c.length,created:_.length}}const g=[];if(u.length){const r=u.map(e=>e.id);g.push(n.schema(f).from("leaders").update({is_removed:!0}).in("id",r).eq("alias",e))}if(c.length){const s=c.map(e=>e.id);g.push(n.schema(f).from("leaders").update({id_leader:r}).in("id",s).eq("alias",e))}if(_.length){const s=_.map(s=>({alias:e,id_user:s.id_user,id_leader:r,is_active:!0,is_removed:!1}));g.push(n.schema(f).from("leaders").insert(s))}const w=(await Promise.all(g)).find(e=>e?.error);if(w?.error)throw w.error;return{unlinked:u.length,updated:c.length,created:_.length}},onSuccess:s=>{r.invalidateQueries({queryKey:["leadership-raw",e]}),t.toast.success(d("subordinates_synced_success",`Subordinados sincronizados (${s.created} adicionados, ${s.updated} atualizados, ${s.unlinked} removidos)`))},onError:e=>{t.toast.error(e.message||d("subordinates_sync_error","Erro ao sincronizar subordinados"))}})}async function y(r,s,a,t){const i=await x(r),n=t?i.filter(e=>e.id!==t):i,d=new Set;let l=a;for(;l;){if(d.has(l))throw new Error(e.t("leadership_cycle_error"));if(l===s)throw new Error("Esta associação criaria um ciclo na hierarquia");d.add(l);const r=n.find(e=>e.id_user===l);l=r?.id_leader||null}}var N=function(e,r){for(var s={};e.length;){var a=e[0],t=a.code,i=a.message,n=a.path.join(".");if(!s[n])if("unionErrors"in a){var d=a.unionErrors[0].errors[0];s[n]={message:d.message,type:d.code}}else s[n]={message:i,type:t};if("unionErrors"in a&&a.unionErrors.forEach(function(r){return r.errors.forEach(function(r){return e.push(r)})}),r){var l=s[n].types,u=l&&l[a.code];s[n]=o.appendErrors(n,r,s,t,u?[].concat(u,a.message):a.message)}e.shift()}return s},C=function(e,r,s){return void 0===s&&(s={}),function(a,t,i){try{return Promise.resolve(function(t,n){try{var d=Promise.resolve(e["sync"===s.mode?"parse":"parseAsync"](a,r)).then(function(e){return i.shouldUseNativeValidation&&u.validateFieldsNatively({},i),{errors:{},values:s.raw?a:e}})}catch(l){return n(l)}return d&&d.then?d.then(void 0,n):d}(0,function(e){if(function(e){return Array.isArray(null==e?void 0:e.errors)}(e))return{values:{},errors:u.toNestErrors(N(e.errors,!i.shouldUseNativeValidation&&"all"===i.criteriaMode),i)};throw e}))}catch(n){return Promise.reject(n)}}};const S=l.z.object({id_leader:l.z.string().nullable(),id_users:l.z.array(l.z.string()).min(1,e.t("leadership_select_subordinates"))}),E=l.z.object({id_leader:l.z.string().nullable(),id_users:l.z.array(l.z.string())});function k({value:e,onChange:s,excludeUserIds:t=[],error:l}){const{t:o}=i.useTranslation(),{data:u=[],isLoading:c}=a.useQualiexUsers(),[m,h]=r.useState(""),_=r.useRef(null),p=r.useRef(0),f=u.filter(e=>!t.includes(e.userId||"")).filter(e=>{const r=m.toLowerCase(),s=e.userName?.toLowerCase().includes(r);return s}).sort((r,s)=>{const a=e.includes(r.userId),t=e.includes(s.userId);if(a&&!t)return-1;if(!a&&t)return 1;const i=r.userName||r.userEmail||"",n=s.userName||s.userEmail||"";return i.localeCompare(n)});return r.useEffect(()=>{_.current&&p.current>0&&(_.current.scrollTop=p.current)},[f]),c?n.jsxs("div",{className:"flex items-center justify-center p-4",children:[n.jsx(d.Loader2,{className:"h-6 w-6 animate-spin"}),n.jsx("span",{className:"ml-2",children:o("loading")})]}):n.jsxs("div",{className:"space-y-2",children:[n.jsx(a.Input,{placeholder:o("search_user_placeholder"),value:m,onChange:e=>h(e.target.value)}),n.jsx("div",{ref:_,className:"border rounded-md p-4 max-h-[300px] overflow-y-auto",children:0===f.length?n.jsx("p",{className:"text-sm text-muted-foreground",children:o("search_user_placeholder")}):n.jsx("div",{className:"space-y-2",children:f.map(r=>n.jsxs("div",{className:"flex items-center space-x-2",children:[n.jsx(a.Checkbox,{id:r.userId,checked:e.includes(r.userId),onCheckedChange:()=>{return a=r.userId,_.current&&(p.current=_.current.scrollTop),void(e.includes(a)?s(e.filter(e=>e!==a)):s([...e,a]));var a}}),n.jsx(a.Label,{htmlFor:r.userId,className:"flex-1 cursor-pointer",children:r.userName||r.userEmail})]},r.userId))})}),e.length>0&&n.jsx("p",{className:"text-sm text-muted-foreground",children:o("selected_count",{count:e.length})}),l&&n.jsx("p",{className:"text-sm text-destructive",children:l})]})}function I({leader:e,prefilledLeaderId:s,onSuccess:t}){const{t:l}=i.useTranslation(),{alias:u}=a.useAuth(),c=!!e,m=e?.id.startsWith("virtual-"),h=w(),f=g(),x=v(),y=b(),N=j(),{data:I=[]}=p(),{data:A=[]}=a.useQualiexUsers(),[L,U]=r.useState(""),q=_(I).map(e=>e.id_user),D=c?_(I).filter(r=>r.id_leader===e.id_user).map(e=>e.id_user):[],T=o.useForm({resolver:C(c?E:S),defaultValues:{id_leader:s||(c?e?.id_leader:null)||null,id_users:c?D:[]}});r.useEffect(()=>{if(e){const r=_(I).filter(r=>r.id_leader===e.id_user).map(e=>e.id_user);T.reset({id_leader:e.id_leader||null,id_users:r})}else s?T.reset({id_leader:s,id_users:[]}):T.reset({id_leader:null,id_users:[]})},[u,e?.id,e?.id_user,e?.id_leader,s,I]);const M=h.isPending||f.isPending||x.isPending||y.isPending||N.isPending,z=T.watch("id_leader"),P=T.watch("id_users"),F=c?[e.id_user,...q.filter(r=>r!==e.id_user&&!P.includes(r)&&!D.includes(r))]:[z,...q.filter(e=>!P.includes(e))].filter(Boolean);return n.jsxs("form",{onSubmit:T.handleSubmit(async r=>{try{if(c)if(m){await f.mutateAsync({id_user:e.id_user,id_leader:r.id_leader});const s=A.filter(e=>r.id_users.includes(e.userId)).map(e=>({id_user:e.userId}));await y.mutateAsync({leaderUserId:e.id_user,selectedUsers:s})}else{await x.mutateAsync({id:e.id,id_leader:r.id_leader});const s=A.filter(e=>r.id_users.includes(e.userId)).map(e=>({id_user:e.userId}));await y.mutateAsync({leaderUserId:e.id_user,selectedUsers:s})}else{const e=A.filter(e=>r.id_users.includes(e.userId)).map(e=>({id_user:e.userId}));await h.mutateAsync({id_leader:r.id_leader,users:e})}t?.()}catch(s){}}),className:"space-y-4",children:[c&&n.jsxs("div",{children:[n.jsx(a.Label,{children:l("leader")}),n.jsx(a.Input,{value:A.find(r=>r.userId===e.id_user)?.userName||e.name||l("inactive_user"),disabled:!0,className:"bg-muted"})]}),n.jsxs("div",{children:[n.jsx(a.Label,{children:l("leadership_immediate_superior")}),n.jsxs(a.Select,{value:z||"none",onValueChange:e=>T.setValue("id_leader","none"===e?null:e),children:[n.jsx(a.SelectTrigger,{children:n.jsx(a.SelectValue,{placeholder:l("select_placeholder")})}),n.jsxs(a.SelectContent,{children:[n.jsx("div",{className:"sticky top-0 z-10 bg-background p-2 border-b",children:n.jsx(a.Input,{placeholder:l("leadership_search_superior"),value:L,onChange:e=>U(e.target.value),onKeyDown:e=>e.stopPropagation(),onClick:e=>e.stopPropagation(),className:"h-8"})}),n.jsxs(a.ScrollArea,{className:"h-[200px]",children:[n.jsx(a.SelectItem,{value:"none",children:l("none_bracketed")}),A.filter(r=>{const s=c?r.userId!==e.id_user:!P.includes(r.userId),a=!L||r.userName?.toLowerCase().includes(L.toLowerCase());return s&&a}).sort((e,r)=>{const s=e.userName||e.userEmail||"",a=r.userName||r.userEmail||"";return s.localeCompare(a)}).map(e=>n.jsx(a.SelectItem,{value:e.userId,children:e.userName},e.userId))]})]})]},`superior-select-${u}`),T.formState.errors.id_leader&&n.jsx("p",{className:"text-sm text-destructive mt-1",children:T.formState.errors.id_leader.message})]}),n.jsxs("div",{children:[n.jsxs(a.Label,{children:[l("subordinates")," *"]}),n.jsx(k,{value:P,onChange:e=>T.setValue("id_users",e),excludeUserIds:F,error:T.formState.errors.id_users?.message},`users-multiselect-${u}`)]}),n.jsxs("div",{className:"flex items-center justify-between gap-2",children:[n.jsx(a.Button,{type:"submit",disabled:M||!c&&0===P.length,children:M&&!N.isPending?n.jsxs(n.Fragment,{children:[n.jsx(d.Loader2,{className:"mr-2 h-4 w-4 animate-spin"}),l(c?"updating":"saving")]}):l(c?"update":"create")}),c&&!z&&0===P.length&&n.jsxs(a.AlertDialog,{children:[n.jsx(a.AlertDialogTrigger,{asChild:!0,children:n.jsx(a.Button,{type:"button",variant:"destructive",disabled:M,className:"ml-auto",children:N.isPending?n.jsxs(n.Fragment,{children:[n.jsx(d.Loader2,{className:"mr-2 h-4 w-4 animate-spin"}),l("removing")]}):n.jsxs(n.Fragment,{children:[n.jsx(d.Trash2,{className:"mr-2 h-4 w-4"}),l("remove")]})})}),n.jsxs(a.AlertDialogContent,{children:[n.jsxs(a.AlertDialogHeader,{children:[n.jsx(a.AlertDialogTitle,{children:l("confirm_removal")}),n.jsx(a.AlertDialogDescription,{children:l("leadership_remove_confirmation")})]}),n.jsxs(a.AlertDialogFooter,{children:[n.jsx(a.AlertDialogCancel,{children:l("cancel")}),n.jsx(a.AlertDialogAction,{onClick:async()=>{if(e)try{await N.mutateAsync(e.id),t?.()}catch(r){}},children:l("remove")})]})]})]})]})]})}function A({open:e,onOpenChange:r,leader:s,prefilledLeaderId:t,title:i}){return n.jsx(a.Dialog,{open:e,onOpenChange:r,children:n.jsxs(a.DialogContent,{variant:"form",className:"sm:max-w-[500px]",children:[n.jsx(a.DialogHeader,{showSeparator:!0,children:n.jsx(a.DialogTitle,{children:i})}),n.jsx(a.DialogBody,{children:n.jsx(I,{leader:s,prefilledLeaderId:t,onSuccess:()=>r(!1)})})]})})}const L="leadership-expanded-nodes",U=(e,r)=>{try{localStorage.setItem(`${L}-${e}`,JSON.stringify(Array.from(r)))}catch{}};exports.LeadershipDialog=A,exports.LeadershipForm=I,exports.LeadershipPage=function({unassociatedUsers:e=[],onAssociateUser:s,onMoveNode:t,onMoveNodes:l,columns:o,nameHeader:u,rootDropLabel:c}={}){const{t:m}=i.useTranslation(),{alias:h}=a.useAuth(),{data:f,isLoading:x,error:w,refetch:j}=p(),b=v(),y=g(),[N,C]=r.useState(()=>h?(e=>{try{const r=localStorage.getItem(`${L}-${e}`);if(r)return new Set(JSON.parse(r))}catch{}return new Set})(h):new Set),[S,E]=r.useState([]),[k,I]=r.useState(new Set),[q,D]=r.useState(!0),[T,M]=r.useState(!1),[z,P]=r.useState(),[F,$]=r.useState(null),Q=r.useMemo(()=>f?_(f):[],[f]),O=r.useMemo(()=>Q.map(e=>e.id),[Q]),B=O.length>0&&S.length===O.length,K=Q.filter(e=>e.children.length>0).every(e=>N.has(e.id));r.useEffect(()=>{if(f&&f.length>0&&h){if(!localStorage.getItem(`${L}-${h}`)){const e=f.map(e=>e.id),r=new Set(e);C(r),U(h,r)}}},[f,h]);const V=r.useCallback(e=>{C(r=>{const s=new Set(r);return s.has(e)?s.delete(e):s.add(e),h&&U(h,s),s})},[h]),R=r.useCallback(()=>{if(K){const e=new Set;C(e),h&&U(h,e)}else{const e=new Set(Q.filter(e=>e.children.length>0).map(e=>e.id));C(e),h&&U(h,e)}},[K,Q,h]),H=r.useCallback(e=>{E(r=>r.includes(e)?r.filter(r=>r!==e):[...r,e])},[]),J=r.useCallback(()=>{E(B?[]:O)},[B,O]),W=r.useCallback(e=>{I(r=>{const s=new Set(r);return s.has(e)?s.delete(e):s.add(e),s})},[]),G=r.useCallback(e=>Q.find(r=>r.id===e),[Q]),X=r.useCallback((r,a)=>{if(t)return void t(r,a);const i=e.find(e=>e.id===r);if(i){if(s){const e=a?G(a):null;s(i.id,e?.id_user||null)}else y.mutate({id_user:i.id,id_leader:a&&G(a)?.id_user||null});return}const n=G(r);if(!n)return;const d=a?G(a):null;b.mutate({id:n.id,id_leader:d?.id_user||null})},[t,e,s,G,b,y]),Y=r.useCallback((e,r)=>{l?l(e,r):(e.forEach(e=>X(e,r)),E([]))},[l,X]),Z=r.useCallback(e=>{P(e),$(null),M(!0)},[]),ee=r.useCallback(()=>{P(void 0),$(null),M(!0)},[]),re=r.useCallback(()=>{M(!1),P(void 0),$(null)},[]),se=r.useCallback((e,r)=>{const s=k.has(e)&&k.size>1?Array.from(k):[e];r.dataTransfer.effectAllowed="move",r.dataTransfer.setData("text/plain",e),r.dataTransfer.setData("application/x-tree-ids",JSON.stringify(s)),r.currentTarget.style.opacity="0.4"},[k]),ae=r.useMemo(()=>[{key:"subordinatesCount",header:m("subordinates"),hoverContent:e=>e.subordinateNames&&e.subordinateNames.length>0?n.jsxs("div",{className:"space-y-1.5",children:[n.jsx("p",{className:"text-xs font-medium text-muted-foreground mb-1",children:m("leadership_direct_subordinates")}),[...e.subordinateNames].sort((e,r)=>e.localeCompare(r)).map(e=>n.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[n.jsx(d.User,{className:"h-3 w-3 text-muted-foreground"}),n.jsx("span",{children:e})]},e))]}):n.jsx("p",{className:"text-xs text-muted-foreground",children:m("leadership_no_direct_subordinates")})},{key:"email",header:m("email"),className:"text-left",width:180,render:e=>n.jsxs("span",{className:"flex items-center gap-1.5 text-muted-foreground text-sm",children:[n.jsx(d.Mail,{className:"h-3.5 w-3.5"}),e.email||"—"]})}],[m]),te=o??ae;if(x)return n.jsx("div",{className:"flex items-center justify-center h-full",children:n.jsxs("div",{className:"text-center space-y-2",children:[n.jsx("div",{className:"animate-spin h-8 w-8 border-4 border-primary border-t-transparent rounded-full mx-auto"}),n.jsx("p",{className:"text-sm text-muted-foreground",children:m("loading")})]})});if(w)return n.jsx("div",{className:"flex items-center justify-center h-full",children:n.jsxs("div",{className:"text-center",children:[n.jsx("p",{className:"text-destructive mb-4",children:m("leadership_load_error")}),n.jsx(a.Button,{onClick:()=>j(),children:m("try_again")})]})});const ie=Q.filter(e=>e.name!==m("inactive_user")).length;return n.jsxs("div",{className:"flex flex-col h-full gap-3 p-4",children:[n.jsxs("div",{className:"flex items-center justify-between",children:[n.jsxs("div",{className:"flex gap-2 items-center",children:[n.jsxs(a.Button,{size:"sm",onClick:ee,children:[n.jsx(d.Plus,{className:"h-4 w-4 mr-2"}),m("leadership_define_leader")]}),n.jsx(a.Button,{size:"sm",variant:"outline",onClick:R,children:K?n.jsxs(n.Fragment,{children:[n.jsx(d.ChevronDown,{className:"h-4 w-4 mr-1"}),m("collapse")]}):n.jsxs(n.Fragment,{children:[n.jsx(d.ChevronRight,{className:"h-4 w-4 mr-1"}),m("expand")]})}),n.jsx("div",{className:"flex items-center gap-2 ml-4",children:n.jsxs("div",{className:"flex items-center gap-2 px-3 py-1.5 bg-muted rounded-md",children:[n.jsx(d.Users,{className:"h-4 w-4 text-muted-foreground"}),n.jsx("span",{className:"text-sm font-medium",children:m("leadership_users_associated",{count:ie})})]})})]}),n.jsx("p",{className:"text-xs text-muted-foreground",children:m("leadership_drag_hint")})]}),n.jsx(a.TreeTable,{data:f||[],columns:te,nameKey:"name",nameHeader:u??m("leader"),expandedIds:N,onToggleExpand:V,iconComponent:n.jsx(d.Users,{className:"h-4 w-4 text-muted-foreground shrink-0"}),rowActionsVariant:"inline",enableRowDrag:!0,enableSelection:!0,selectedIds:S,onSelectItem:H,onSelectAll:J,isAllSelected:B,onMoveNode:X,onMoveNodes:Y,rootDropLabel:c??m("leadership_make_root"),emptyMessage:m("leadership_no_hierarchy"),renderActions:e=>n.jsx(a.Button,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>Z(e),children:n.jsx(d.Pencil,{className:"h-4 w-4"})})}),e.length>0&&n.jsxs("div",{className:"border rounded-lg overflow-hidden",children:[n.jsxs("button",{type:"button",onClick:()=>D(e=>!e),className:"w-full px-4 py-2.5 bg-muted/50 border-b flex items-center gap-2 hover:bg-muted/70 transition-colors cursor-pointer",children:[q?n.jsx(d.ChevronDown,{className:"h-4 w-4 text-muted-foreground shrink-0"}):n.jsx(d.ChevronRight,{className:"h-4 w-4 text-muted-foreground shrink-0"}),n.jsx(d.UserPlus,{className:"h-4 w-4 text-muted-foreground"}),n.jsx("span",{className:"text-sm font-medium",children:m("leadership_unassociated_users")}),n.jsxs("span",{className:"text-xs text-muted-foreground ml-1",children:["(",e.length,")"]}),k.size>0&&n.jsxs("span",{className:"text-xs text-primary ml-1",children:["(",m("selected_count",{count:k.size}),")"]}),n.jsx("span",{className:"text-xs text-muted-foreground ml-auto",children:m("leadership_drag_to_hierarchy")})]}),q&&n.jsx("div",{className:"divide-y",children:e.map(e=>n.jsxs("div",{draggable:!0,onDragStart:r=>se(e.id,r),onDragEnd:e=>{e.currentTarget.style.opacity="1"},className:a.cn("flex items-center gap-3 px-4 py-2.5 hover:bg-accent/50 cursor-grab active:cursor-grabbing transition-colors",k.has(e.id)&&"bg-primary/5"),children:[n.jsx(a.Checkbox,{checked:k.has(e.id),onCheckedChange:()=>W(e.id),onClick:e=>e.stopPropagation(),className:"shrink-0"}),n.jsx("span",{className:"text-muted-foreground shrink-0 select-none",children:"⠿"}),n.jsx(d.User,{className:"h-4 w-4 text-muted-foreground shrink-0"}),n.jsxs("div",{className:"flex flex-col min-w-0",children:[n.jsx("span",{className:"text-sm truncate",children:e.name}),n.jsx("span",{className:"text-xs text-muted-foreground truncate",children:e.email})]})]},e.id))})]}),n.jsxs("div",{className:"px-3 py-2 bg-muted/20 border rounded-lg text-xs text-muted-foreground flex justify-between",children:[n.jsx("span",{children:m("leadership_users_associated_count",{count:ie})}),e.length>0&&n.jsx("span",{children:m("leadership_users_unassociated_count",{count:e.length})})]}),n.jsx(A,{open:T,onOpenChange:re,leader:z,prefilledLeaderId:F,title:m(z?"edit_name":F?"leadership_add_subordinate":"leadership_add_root")},`leadership-dialog-${h}`)]})},exports.buildHierarchy=h,exports.filterAndPromoteOrphans=function(e,r){const s=e.map(e=>({...e})),a=new Set(s.filter(e=>!r.has(e.id_user)).map(e=>e.id_user));return s.forEach(e=>{if(e.id_leader&&a.has(e.id_leader)){let r=e.id_leader;for(;r&&a.has(r);){const e=s.find(e=>e.id_user===r);r=e?.id_leader||null}e.id_leader=r}}),s.filter(e=>r.has(e.id_user))},exports.flattenTree=_,exports.getLeadershipDataSource=m,exports.setLeadershipDataSource=function(e){c=e},exports.useCreateMultipleLeadersMutation=w,exports.useCreateSingleLeaderMutation=g,exports.useLeadershipApi=p,exports.useRemoveLeaderMutation=j,exports.useSyncSubordinatesMutation=b,exports.useUpdateLeaderMutation=v;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forlogic-core",
3
- "version": "3.0.8",
3
+ "version": "3.0.9",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",