forlogic-core 2.4.11 → 2.4.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/modules/ModulesContent.d.ts +1 -1
- package/dist/components/modules/types.d.ts +1 -1
- package/dist/crud/components/CrudTable.d.ts +3 -1
- package/dist/crud/createCrudPage.d.ts +4 -1
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.js +1 -1
- package/dist/leadership/index.esm.js +1 -1
- package/dist/leadership/index.js +1 -1
- package/dist/updates/utils/interpolate.d.ts +6 -0
- package/docs/sql/import/validate_materials_services.sql +216 -0
- package/docs/sql/import/validate_occurrences_categories.sql +172 -0
- package/docs/sql/import/validate_risks.sql +236 -0
- package/docs/sql/import/validate_risks_categories.sql +221 -0
- package/docs/sql/import/validate_risks_groups.sql +200 -0
- package/docs/sql/import/validate_supplier_categories.sql +173 -0
- package/docs/sql/import/validate_suppliers.sql +171 -0
- package/docs/sql/import/validate_supply_types.sql +219 -0
- package/package.json +1 -1
|
@@ -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 f,Select as _,SelectTrigger as p,SelectValue as g,SelectContent as w,ScrollArea as v,SelectItem as N,Button as x,AlertDialog as y,AlertDialogTrigger as b,AlertDialogContent as E,AlertDialogHeader as S,AlertDialogTitle as C,AlertDialogDescription as I,AlertDialogFooter as q,AlertDialogCancel as k,AlertDialogAction as U,Checkbox as A,Dialog as z,DialogContent as L,DialogHeader as P,DialogTitle as $,DialogBody as j,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 R,Mail as B,Plus as H,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 _e(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 _e(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 _e(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 fe(){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),f=u.filter(e=>!h.has(e.id_user)),_=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 _)await _e(a,e,s.id_user,r,s.id);for(const N of g){if(N.id_user===r)throw new Error(s("cannot_be_own_leader","Usuário não pode ser seu próprio líder"));await _e(a,e,N.id_user,r)}const w=[];if(f.length){const r=f.map(e=>e.id);w.push(a.schema(le).from("leaders").update({is_removed:!0}).in("id",r).eq("alias",e))}if(_.length){const s=_.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:f.length,updated:_.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 _e(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 Ne({value:r,onChange:t,excludeUserIds:n=[],error:d}){const{data:o=[],isLoading:l}=u(),[c,m]=a(""),_=i(null),p=i(0),g=o.filter(e=>!n.includes(e.userId||"")).filter(e=>{const r=c.toLowerCase(),a=e.userName?.toLowerCase().includes(r);return a}).sort((e,a)=>{const s=r.includes(e.userId),i=r.includes(a.userId);if(s&&!i)return-1;if(!s&&i)return 1;const t=e.userName||e.userEmail||"",n=a.userName||a.userEmail||"";return t.localeCompare(n)});return s(()=>{_.current&&p.current>0&&(_.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:"Carregando dados..."})]}:{className:"space-y-2",children:[F(f,{placeholder:e.t("search_user_placeholder"),value:c,onChange:e=>m(e.target.value)}),F("div",{ref:_,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:e.t("search_user_placeholder")}):F("div",{className:"space-y-2",children:g.map(e=>O("div",{className:"flex items-center space-x-2",children:[F(A,{id:e.userId,checked:r.includes(e.userId),onCheckedChange:()=>{return a=e.userId,_.current&&(p.current=_.current.scrollTop),void(r.includes(a)?t(r.filter(e=>e!==a)):t([...r,a]));var a}}),F(h,{htmlFor:e.userId,className:"flex-1 cursor-pointer",children:e.userName||e.userEmail})]},e.userId))})}),r.length>0&&O("p",{className:"text-sm text-muted-foreground",children:[r.length," selecionado(s)"]}),d&&F("p",{className:"text-sm text-destructive",children:d})]})}function xe({leader:r,prefilledLeaderId:i,onSuccess:t}){const{t:n}=M(),{alias:d}=l(),o=!!r,c=r?.id.startsWith("virtual-"),m=ue(),A=ce(),z=me(),L=fe(),P=he(),{data:$=[]}=oe(),{data:j=[]}=u(),[D,T]=a(""),K=de($).map(e=>e.id_user),R=o?de($).filter(e=>e.id_leader===r.id_user).map(e=>e.id_user):[],B=ae({resolver:ge(o?ve:we),defaultValues:{id_leader:i||(o?r?.id_leader:null)||null,id_users:o?R:[]}});s(()=>{if(r){const e=de($).filter(e=>e.id_leader===r.id_user).map(e=>e.id_user);B.reset({id_leader:r.id_leader||null,id_users:e})}else i?B.reset({id_leader:i,id_users:[]}):B.reset({id_leader:null,id_users:[]})},[d,r?.id,r?.id_user,r?.id_leader,i,$]);const H=m.isPending||A.isPending||z.isPending||L.isPending||P.isPending,W=B.watch("id_leader"),G=B.watch("id_users"),X=o?[r.id_user,...K.filter(e=>e!==r.id_user&&!G.includes(e)&&!R.includes(e))]:[W,...K.filter(e=>!G.includes(e))].filter(Boolean);return O("form",{onSubmit:B.handleSubmit(async e=>{try{if(o)if(c){await A.mutateAsync({id_user:r.id_user,id_leader:e.id_leader});const a=j.filter(r=>e.id_users.includes(r.userId)).map(e=>({id_user:e.userId}));await L.mutateAsync({leaderUserId:r.id_user,selectedUsers:a})}else{await z.mutateAsync({id:r.id,id_leader:e.id_leader});const a=j.filter(r=>e.id_users.includes(r.userId)).map(e=>({id_user:e.userId}));await L.mutateAsync({leaderUserId:r.id_user,selectedUsers:a})}else{const r=j.filter(r=>e.id_users.includes(r.userId)).map(e=>({id_user:e.userId}));await m.mutateAsync({id_leader:e.id_leader,users:r})}t?.()}catch(a){}}),className:"space-y-4",children:[o&&O("div",{children:[F(h,{children:e.t("leader")}),F(f,{value:j.find(e=>e.userId===r.id_user)?.userName||r.name||e.t("inactive_user"),disabled:!0,className:"bg-muted"})]}),O("div",{children:[F(h,{children:n("leadership_immediate_superior")}),O(_,{value:W||"none",onValueChange:e=>B.setValue("id_leader","none"===e?null:e),children:[F(p,{children:F(g,{placeholder:"Selecione..."})}),O(w,{children:[F("div",{className:"sticky top-0 z-10 bg-background p-2 border-b",children:F(f,{placeholder:"Buscar superior...",value:D,onChange:e=>T(e.target.value),onKeyDown:e=>e.stopPropagation(),onClick:e=>e.stopPropagation(),className:"h-8"})}),O(v,{className:"h-[200px]",children:[F(N,{value:"none",children:"[Nenhum]"}),j.filter(e=>{const a=o?e.userId!==r.id_user:!G.includes(e.userId),s=!D||e.userName?.toLowerCase().includes(D.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(N,{value:e.userId,children:e.userName},e.userId))]})]})]},`superior-select-${d}`),B.formState.errors.id_leader&&F("p",{className:"text-sm text-destructive mt-1",children:B.formState.errors.id_leader.message})]}),O("div",{children:[F(h,{children:"Subordinados *"}),F(Ne,{value:G,onChange:e=>B.setValue("id_users",e),excludeUserIds:X,error:B.formState.errors.id_users?.message},`users-multiselect-${d}`)]}),O("div",{className:"flex items-center justify-between gap-2",children:[F(x,{type:"submit",disabled:H||!o&&0===G.length,children:H&&!P.isPending?O(V,{children:[F(Q,{className:"mr-2 h-4 w-4 animate-spin"}),o?"Atualizando...":"Salvando..."]}):o?"Atualizar":"Criar"}),o&&!W&&0===G.length&&O(y,{children:[F(b,{asChild:!0,children:F(x,{type:"button",variant:"destructive",disabled:H,className:"ml-auto",children:P.isPending?O(V,{children:[F(Q,{className:"mr-2 h-4 w-4 animate-spin"}),"Removendo..."]}):O(V,{children:[F(J,{className:"mr-2 h-4 w-4"}),"Remover"]})})}),O(E,{children:[O(S,{children:[F(C,{children:n("confirm_removal")}),F(I,{children:"Tem certeza que deseja remover este líder? Esta ação não pode ser desfeita."})]}),O(q,{children:[F(k,{children:n("cancel")}),F(U,{onClick:async()=>{if(r)try{await P.mutateAsync(r.id),t?.()}catch(e){}},children:n("remove")})]})]})]})]})]})}function ye({open:e,onOpenChange:r,leader:a,prefilledLeaderId:s,title:i}){return F(z,{open:e,onOpenChange:r,children:O(L,{variant:"form",className:"sm:max-w-[500px]",children:[F(P,{showSeparator:!0,children:F($,{children:i})}),F(j,{children:F(xe,{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:i=[],onAssociateUser:n,onMoveNode:d,onMoveNodes:o,columns:c,nameHeader:u=e.t("leader"),rootDropLabel:m=e.t("leadership_make_root")}={}){const{alias:h}=l(),{data:f,isLoading:_,error:p,refetch:g}=oe(),w=me(),v=ce(),[N,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,C]=a(new Set),[I,q]=a(!0),[k,U]=a(!1),[z,L]=a(),[P,$]=a(null),j=r(()=>f?de(f):[],[f]),K=r(()=>j.map(e=>e.id),[j]),M=K.length>0&&b.length===K.length,Q=j.filter(e=>e.children.length>0).every(e=>N.has(e.id));s(()=>{if(f&&f.length>0&&h){if(!localStorage.getItem(`${be}-${h}`)){const e=f.map(e=>e.id),r=new Set(e);y(r),Ee(h,r)}}},[f,h]);const J=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]),ee=t(()=>{if(Q){const e=new Set;y(e),h&&Ee(h,e)}else{const e=new Set(j.filter(e=>e.children.length>0).map(e=>e.id));y(e),h&&Ee(h,e)}},[Q,j,h]),re=t(e=>{E(r=>r.includes(e)?r.filter(r=>r!==e):[...r,e])},[]),ae=t(()=>{E(M?[]:K)},[M,K]),se=t(e=>{C(r=>{const a=new Set(r);return a.has(e)?a.delete(e):a.add(e),a})},[]),ie=t(e=>j.find(r=>r.id===e),[j]),te=t((e,r)=>{if(d)return void d(e,r);const a=i.find(r=>r.id===e);if(a){if(n){const e=r?ie(r):null;n(a.id,e?.id_user||null)}else v.mutate({id_user:a.id,id_leader:r&&ie(r)?.id_user||null});return}const s=ie(e);if(!s)return;const t=r?ie(r):null;w.mutate({id:s.id,id_leader:t?.id_user||null})},[d,i,n,ie,w,v]),ne=t((e,r)=>{o?o(e,r):(e.forEach(e=>te(e,r)),E([]))},[o,te]),le=t(e=>{L(e),$(null),U(!0)},[]),ue=t(()=>{L(void 0),$(null),U(!0)},[]),he=t(()=>{U(!1),L(void 0),$(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]),_e=r(()=>[{key:"subordinatesCount",header:"Subordinados",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:"Subordinados diretos:"}),[...e.subordinateNames].sort((e,r)=>e.localeCompare(r)).map(e=>O("div",{className:"flex items-center gap-2 text-sm",children:[F(R,{className:"h-3 w-3 text-muted-foreground"}),F("span",{children:e})]},e))]}):F("p",{className:"text-xs text-muted-foreground",children:"Sem subordinados diretos"})},{key:"email",header:"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||"—"]})}],[]),pe=c??_e;if(_)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:"Carregando..."})]})});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:"Erro ao carregar hierarquia de liderança"}),F(x,{onClick:()=>g(),children:e.t("try_again")})]})});const ge=j.filter(r=>r.name!==e.t("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(x,{size:"sm",onClick:ue,children:[F(H,{className:"h-4 w-4 mr-2"}),"Definir Líder"]}),F(x,{size:"sm",variant:"outline",onClick:ee,children:O(V,Q?{children:[F(W,{className:"h-4 w-4 mr-1"}),"Colapsar"]}:{children:[F(G,{className:"h-4 w-4 mr-1"}),"Expandir"]})}),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"}),O("span",{className:"text-sm font-medium",children:[ge," usuário",1!==ge?"s":""," associado",1!==ge?"s":""]})]})})]}),F("p",{className:"text-xs text-muted-foreground",children:"Arraste as linhas para reorganizar • Selecione múltiplos para mover em lote"})]}),F(D,{data:f||[],columns:pe,nameKey:"name",nameHeader:u,expandedIds:N,onToggleExpand:J,iconComponent:F(X,{className:"h-4 w-4 text-muted-foreground shrink-0"}),rowActionsVariant:"inline",enableRowDrag:!0,enableSelection:!0,selectedIds:b,onSelectItem:re,onSelectAll:ae,isAllSelected:M,onMoveNode:te,onMoveNodes:ne,rootDropLabel:m,emptyMessage:e.t("leadership_no_hierarchy"),renderActions:e=>F(x,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>le(e),children:F(Y,{className:"h-4 w-4"})})}),i.length>0&&O("div",{className:"border rounded-lg overflow-hidden",children:[O("button",{type:"button",onClick:()=>q(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(I?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:"Usuários não associados"}),O("span",{className:"text-xs text-muted-foreground ml-1",children:["(",i.length,")"]}),S.size>0&&O("span",{className:"text-xs text-primary ml-1",children:["(",S.size," selecionado",S.size>1?"s":"",")"]}),F("span",{className:"text-xs text-muted-foreground ml-auto",children:"Arraste para a hierarquia acima"})]}),I&&F("div",{className:"divide-y",children:i.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:()=>se(e.id),onClick:e=>e.stopPropagation(),className:"shrink-0"}),F("span",{className:"text-muted-foreground shrink-0 select-none",children:"⠿"}),F(R,{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:[O("span",{children:["Usuários associados: ",ge]}),i.length>0&&O("span",{children:["Usuários não associados: ",i.length]})]}),F(ye,{open:k,onOpenChange:he,leader:z,prefilledLeaderId:P,title:z?e.t("edit_name"):P?e.t("leadership_add_subordinate"):e.t("leadership_add_root")},`leadership-dialog-${h}`)]})}export{ye as LeadershipDialog,xe 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,fe 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 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};
|
package/dist/leadership/index.js
CHANGED
|
@@ -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"),o=require("zod"),l=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(),o=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}),l=r.useMemo(()=>{const r=o.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)},[o.data,d]);return{...o,data:l}}const f="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(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(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 _(){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(f).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 l of r.users){if(r.id_leader&&l.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,l.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:o}=await n.schema(f).from("leaders").insert(t).select();if(o)throw o;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(f).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(f).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(f).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(f).from("leaders").select("id, id_user, id_leader").eq("alias",e).eq("is_removed",!1).eq("id_leader",r),n.schema(f).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:o},{data:l,error:u}]=t;if(o)throw o;if(u)throw u;const c=i||[],m=l||[],h=new Set(a),p=c.filter(e=>!h.has(e.id_user)),_=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 _)await w(n,e,d.id_user,r,d.id);for(const f of g){if(f.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,f.id_user,r)}const v=[];if(p.length){const r=p.map(e=>e.id);v.push(n.schema(f).from("leaders").update({is_removed:!0}).in("id",r).eq("alias",e))}if(_.length){const s=_.map(e=>e.id);v.push(n.schema(f).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(f).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:_.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(f).from("leaders").select("id, id_user, id_leader").eq("alias",s).eq("is_removed",!1);if(d)throw d;const o=i?n.filter(e=>e.id!==i):n,l=new Set;let u=t;for(;u;){if(l.has(u))throw new Error(e.t("leadership_cycle_error"));if(u===a)throw new Error("Esta associação criaria um ciclo na hierarquia");l.add(u);const r=o.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 o=s[n].types,u=o&&o[a.code];s[n]=l.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(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:u.toNestErrors(j(e.errors,!i.shouldUseNativeValidation&&"all"===i.criteriaMode),i)};throw e}))}catch(n){return Promise.reject(n)}}};const y=o.z.object({id_leader:o.z.string().nullable(),id_users:o.z.array(o.z.string()).min(1,e.t("leadership_select_subordinates"))}),N=o.z.object({id_leader:o.z.string().nullable(),id_users:o.z.array(o.z.string())});function S({value:s,onChange:t,excludeUserIds:i=[],error:o}){const{data:l=[],isLoading:u}=a.useQualiexUsers(),[c,m]=r.useState(""),h=r.useRef(null),f=r.useRef(0),p=l.filter(e=>!i.includes(e.userId||"")).filter(e=>{const r=c.toLowerCase(),s=e.userName?.toLowerCase().includes(r);return s}).sort((e,r)=>{const a=s.includes(e.userId),t=s.includes(r.userId);if(a&&!t)return-1;if(!a&&t)return 1;const i=e.userName||e.userEmail||"",n=r.userName||r.userEmail||"";return i.localeCompare(n)});return r.useEffect(()=>{h.current&&f.current>0&&(h.current.scrollTop=f.current)},[p]),u?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:"Carregando dados..."})]}):n.jsxs("div",{className:"space-y-2",children:[n.jsx(a.Input,{placeholder:e.t("search_user_placeholder"),value:c,onChange:e=>m(e.target.value)}),n.jsx("div",{ref:h,className:"border rounded-md p-4 max-h-[300px] overflow-y-auto",children:0===p.length?n.jsx("p",{className:"text-sm text-muted-foreground",children:e.t("search_user_placeholder")}):n.jsx("div",{className:"space-y-2",children:p.map(e=>n.jsxs("div",{className:"flex items-center space-x-2",children:[n.jsx(a.Checkbox,{id:e.userId,checked:s.includes(e.userId),onCheckedChange:()=>{return r=e.userId,h.current&&(f.current=h.current.scrollTop),void(s.includes(r)?t(s.filter(e=>e!==r)):t([...s,r]));var r}}),n.jsx(a.Label,{htmlFor:e.userId,className:"flex-1 cursor-pointer",children:e.userName||e.userEmail})]},e.userId))})}),s.length>0&&n.jsxs("p",{className:"text-sm text-muted-foreground",children:[s.length," selecionado(s)"]}),o&&n.jsx("p",{className:"text-sm text-destructive",children:o})]})}function C({leader:s,prefilledLeaderId:t,onSuccess:o}){const{t:u}=i.useTranslation(),{alias:c}=a.useAuth(),f=!!s,w=s?.id.startsWith("virtual-"),j=_(),C=p(),E=x(),A=v(),k=g(),{data:q=[]}=h(),{data:I=[]}=a.useQualiexUsers(),[U,L]=r.useState(""),D=m(q).map(e=>e.id_user),z=f?m(q).filter(e=>e.id_leader===s.id_user).map(e=>e.id_user):[],M=l.useForm({resolver:b(f?N:y),defaultValues:{id_leader:t||(f?s?.id_leader:null)||null,id_users:f?z:[]}});r.useEffect(()=>{if(s){const e=m(q).filter(e=>e.id_leader===s.id_user).map(e=>e.id_user);M.reset({id_leader:s.id_leader||null,id_users:e})}else t?M.reset({id_leader:t,id_users:[]}):M.reset({id_leader:null,id_users:[]})},[c,s?.id,s?.id_user,s?.id_leader,t,q]);const T=j.isPending||C.isPending||E.isPending||A.isPending||k.isPending,P=M.watch("id_leader"),F=M.watch("id_users"),$=f?[s.id_user,...D.filter(e=>e!==s.id_user&&!F.includes(e)&&!z.includes(e))]:[P,...D.filter(e=>!F.includes(e))].filter(Boolean);return n.jsxs("form",{onSubmit:M.handleSubmit(async e=>{try{if(f)if(w){await C.mutateAsync({id_user:s.id_user,id_leader:e.id_leader});const r=I.filter(r=>e.id_users.includes(r.userId)).map(e=>({id_user:e.userId}));await A.mutateAsync({leaderUserId:s.id_user,selectedUsers:r})}else{await E.mutateAsync({id:s.id,id_leader:e.id_leader});const r=I.filter(r=>e.id_users.includes(r.userId)).map(e=>({id_user:e.userId}));await A.mutateAsync({leaderUserId:s.id_user,selectedUsers:r})}else{const r=I.filter(r=>e.id_users.includes(r.userId)).map(e=>({id_user:e.userId}));await j.mutateAsync({id_leader:e.id_leader,users:r})}o?.()}catch(r){}}),className:"space-y-4",children:[f&&n.jsxs("div",{children:[n.jsx(a.Label,{children:e.t("leader")}),n.jsx(a.Input,{value:I.find(e=>e.userId===s.id_user)?.userName||s.name||e.t("inactive_user"),disabled:!0,className:"bg-muted"})]}),n.jsxs("div",{children:[n.jsx(a.Label,{children:u("leadership_immediate_superior")}),n.jsxs(a.Select,{value:P||"none",onValueChange:e=>M.setValue("id_leader","none"===e?null:e),children:[n.jsx(a.SelectTrigger,{children:n.jsx(a.SelectValue,{placeholder:"Selecione..."})}),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:"Buscar superior...",value:U,onChange:e=>L(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:"[Nenhum]"}),I.filter(e=>{const r=f?e.userId!==s.id_user:!F.includes(e.userId),a=!U||e.userName?.toLowerCase().includes(U.toLowerCase());return r&&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-${c}`),M.formState.errors.id_leader&&n.jsx("p",{className:"text-sm text-destructive mt-1",children:M.formState.errors.id_leader.message})]}),n.jsxs("div",{children:[n.jsx(a.Label,{children:"Subordinados *"}),n.jsx(S,{value:F,onChange:e=>M.setValue("id_users",e),excludeUserIds:$,error:M.formState.errors.id_users?.message},`users-multiselect-${c}`)]}),n.jsxs("div",{className:"flex items-center justify-between gap-2",children:[n.jsx(a.Button,{type:"submit",disabled:T||!f&&0===F.length,children:T&&!k.isPending?n.jsxs(n.Fragment,{children:[n.jsx(d.Loader2,{className:"mr-2 h-4 w-4 animate-spin"}),f?"Atualizando...":"Salvando..."]}):f?"Atualizar":"Criar"}),f&&!P&&0===F.length&&n.jsxs(a.AlertDialog,{children:[n.jsx(a.AlertDialogTrigger,{asChild:!0,children:n.jsx(a.Button,{type:"button",variant:"destructive",disabled:T,className:"ml-auto",children:k.isPending?n.jsxs(n.Fragment,{children:[n.jsx(d.Loader2,{className:"mr-2 h-4 w-4 animate-spin"}),"Removendo..."]}):n.jsxs(n.Fragment,{children:[n.jsx(d.Trash2,{className:"mr-2 h-4 w-4"}),"Remover"]})})}),n.jsxs(a.AlertDialogContent,{children:[n.jsxs(a.AlertDialogHeader,{children:[n.jsx(a.AlertDialogTitle,{children:u("confirm_removal")}),n.jsx(a.AlertDialogDescription,{children:"Tem certeza que deseja remover este líder? Esta ação não pode ser desfeita."})]}),n.jsxs(a.AlertDialogFooter,{children:[n.jsx(a.AlertDialogCancel,{children:u("cancel")}),n.jsx(a.AlertDialogAction,{onClick:async()=>{if(s)try{await k.mutateAsync(s.id),o?.()}catch(e){}},children:u("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(C,{leader:s,prefilledLeaderId:t,onSuccess:()=>r(!1)})})]})})}const A="leadership-expanded-nodes",k=(e,r)=>{try{localStorage.setItem(`${A}-${e}`,JSON.stringify(Array.from(r)))}catch{}};exports.LeadershipDialog=E,exports.LeadershipForm=C,exports.LeadershipPage=function({unassociatedUsers:s=[],onAssociateUser:t,onMoveNode:i,onMoveNodes:o,columns:l,nameHeader:u=e.t("leader"),rootDropLabel:c=e.t("leadership_make_root")}={}){const{alias:f}=a.useAuth(),{data:_,isLoading:g,error:v,refetch:w}=h(),j=x(),b=p(),[y,N]=r.useState(()=>f?(e=>{try{const r=localStorage.getItem(`${A}-${e}`);if(r)return new Set(JSON.parse(r))}catch{}return new Set})(f):new Set),[S,C]=r.useState([]),[q,I]=r.useState(new Set),[U,L]=r.useState(!0),[D,z]=r.useState(!1),[M,T]=r.useState(),[P,F]=r.useState(null),$=r.useMemo(()=>_?m(_):[],[_]),Q=r.useMemo(()=>$.map(e=>e.id),[$]),B=Q.length>0&&S.length===Q.length,O=$.filter(e=>e.children.length>0).every(e=>y.has(e.id));r.useEffect(()=>{if(_&&_.length>0&&f){if(!localStorage.getItem(`${A}-${f}`)){const e=_.map(e=>e.id),r=new Set(e);N(r),k(f,r)}}},[_,f]);const K=r.useCallback(e=>{N(r=>{const s=new Set(r);return s.has(e)?s.delete(e):s.add(e),f&&k(f,s),s})},[f]),R=r.useCallback(()=>{if(O){const e=new Set;N(e),f&&k(f,e)}else{const e=new Set($.filter(e=>e.children.length>0).map(e=>e.id));N(e),f&&k(f,e)}},[O,$,f]),V=r.useCallback(e=>{C(r=>r.includes(e)?r.filter(r=>r!==e):[...r,e])},[]),H=r.useCallback(()=>{C(B?[]:Q)},[B,Q]),J=r.useCallback(e=>{I(r=>{const s=new Set(r);return s.has(e)?s.delete(e):s.add(e),s})},[]),W=r.useCallback(e=>$.find(r=>r.id===e),[$]),G=r.useCallback((e,r)=>{if(i)return void i(e,r);const a=s.find(r=>r.id===e);if(a){if(t){const e=r?W(r):null;t(a.id,e?.id_user||null)}else b.mutate({id_user:a.id,id_leader:r&&W(r)?.id_user||null});return}const n=W(e);if(!n)return;const d=r?W(r):null;j.mutate({id:n.id,id_leader:d?.id_user||null})},[i,s,t,W,j,b]),X=r.useCallback((e,r)=>{o?o(e,r):(e.forEach(e=>G(e,r)),C([]))},[o,G]),Y=r.useCallback(e=>{T(e),F(null),z(!0)},[]),Z=r.useCallback(()=>{T(void 0),F(null),z(!0)},[]),ee=r.useCallback(()=>{z(!1),T(void 0),F(null)},[]),re=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]),se=r.useMemo(()=>[{key:"subordinatesCount",header:"Subordinados",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:"Subordinados diretos:"}),[...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:"Sem subordinados diretos"})},{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||"—"]})}],[]),ae=l??se;if(g)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:"Carregando..."})]})});if(v)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:"Erro ao carregar hierarquia de liderança"}),n.jsx(a.Button,{onClick:()=>w(),children:e.t("try_again")})]})});const te=$.filter(r=>r.name!==e.t("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:Z,children:[n.jsx(d.Plus,{className:"h-4 w-4 mr-2"}),"Definir Líder"]}),n.jsx(a.Button,{size:"sm",variant:"outline",onClick:R,children:O?n.jsxs(n.Fragment,{children:[n.jsx(d.ChevronDown,{className:"h-4 w-4 mr-1"}),"Colapsar"]}):n.jsxs(n.Fragment,{children:[n.jsx(d.ChevronRight,{className:"h-4 w-4 mr-1"}),"Expandir"]})}),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.jsxs("span",{className:"text-sm font-medium",children:[te," usuário",1!==te?"s":""," associado",1!==te?"s":""]})]})})]}),n.jsx("p",{className:"text-xs text-muted-foreground",children:"Arraste as linhas para reorganizar • Selecione múltiplos para mover em lote"})]}),n.jsx(a.TreeTable,{data:_||[],columns:ae,nameKey:"name",nameHeader:u,expandedIds:y,onToggleExpand:K,iconComponent:n.jsx(d.Users,{className:"h-4 w-4 text-muted-foreground shrink-0"}),rowActionsVariant:"inline",enableRowDrag:!0,enableSelection:!0,selectedIds:S,onSelectItem:V,onSelectAll:H,isAllSelected:B,onMoveNode:G,onMoveNodes:X,rootDropLabel:c,emptyMessage:e.t("leadership_no_hierarchy"),renderActions:e=>n.jsx(a.Button,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>Y(e),children:n.jsx(d.Pencil,{className:"h-4 w-4"})})}),s.length>0&&n.jsxs("div",{className:"border rounded-lg overflow-hidden",children:[n.jsxs("button",{type:"button",onClick:()=>L(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:[U?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:"Usuários não associados"}),n.jsxs("span",{className:"text-xs text-muted-foreground ml-1",children:["(",s.length,")"]}),q.size>0&&n.jsxs("span",{className:"text-xs text-primary ml-1",children:["(",q.size," selecionado",q.size>1?"s":"",")"]}),n.jsx("span",{className:"text-xs text-muted-foreground ml-auto",children:"Arraste para a hierarquia acima"})]}),U&&n.jsx("div",{className:"divide-y",children:s.map(e=>n.jsxs("div",{draggable:!0,onDragStart:r=>re(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:()=>J(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.jsxs("span",{children:["Usuários associados: ",te]}),s.length>0&&n.jsxs("span",{children:["Usuários não associados: ",s.length]})]}),n.jsx(E,{open:D,onOpenChange:ee,leader:M,prefilledLeaderId:P,title:M?e.t("edit_name"):P?e.t("leadership_add_subordinate"):e.t("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=_,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");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;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Substitui o token `@nome_usuario`/`@nome_usuário` no conteúdo das novidades pelo
|
|
3
|
+
* primeiro nome do usuário logado (fallback "Colaborador"). Paridade com o projeto
|
|
4
|
+
* antigo (@forlogic/qex), que fazia o mesmo replace ao renderizar as novidades.
|
|
5
|
+
*/
|
|
6
|
+
export declare function replaceUserNameToken<T extends string | null | undefined>(content: T, userName?: string | null): T;
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
USE [qualiex_common]
|
|
2
|
+
GO
|
|
3
|
+
|
|
4
|
+
begin tran
|
|
5
|
+
|
|
6
|
+
-- criaçao da tabela staging
|
|
7
|
+
IF EXISTS (SELECT * FROM sys.objects
|
|
8
|
+
WHERE object_id = OBJECT_ID(N'[import].[materials_services_staging]')
|
|
9
|
+
AND type IN (N'U'))
|
|
10
|
+
DROP TABLE [import].[materials_services_staging]
|
|
11
|
+
GO
|
|
12
|
+
|
|
13
|
+
SET ANSI_NULLS ON
|
|
14
|
+
GO
|
|
15
|
+
SET QUOTED_IDENTIFIER ON
|
|
16
|
+
GO
|
|
17
|
+
|
|
18
|
+
CREATE TABLE [import].[materials_services_staging](
|
|
19
|
+
[id_batch] [uniqueidentifier] NOT NULL,
|
|
20
|
+
[row_num] [int] NOT NULL,
|
|
21
|
+
[code] [varchar](20) NULL,
|
|
22
|
+
[title] [varchar](200) NOT NULL,
|
|
23
|
+
[supply_type_title] [varchar](200) NOT NULL,
|
|
24
|
+
[description] [nvarchar](max) NULL,
|
|
25
|
+
[is_active] [varchar](20) NULL,
|
|
26
|
+
[id_creation_user] [char](8) NOT NULL,
|
|
27
|
+
[id_company] [char](8) NOT NULL,
|
|
28
|
+
CONSTRAINT [pk_materials_services_staging] PRIMARY KEY CLUSTERED
|
|
29
|
+
(
|
|
30
|
+
[id_batch] ASC,
|
|
31
|
+
[row_num] ASC
|
|
32
|
+
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
|
|
33
|
+
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON,
|
|
34
|
+
OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
|
|
35
|
+
) ON [PRIMARY]
|
|
36
|
+
GO
|
|
37
|
+
|
|
38
|
+
-- criaçao da procedure de validaçao
|
|
39
|
+
CREATE OR ALTER PROCEDURE [import].[validate_materials_services]
|
|
40
|
+
@id_batch UNIQUEIDENTIFIER
|
|
41
|
+
AS
|
|
42
|
+
BEGIN
|
|
43
|
+
SET NOCOUNT ON;
|
|
44
|
+
|
|
45
|
+
DECLARE @Company CHAR(8);
|
|
46
|
+
SELECT TOP 1 @Company = id_company FROM import.materials_services_staging WITH (NOLOCK) WHERE id_batch = @id_batch;
|
|
47
|
+
|
|
48
|
+
DECLARE @IsCustomCodeEnabled BIT = 0;
|
|
49
|
+
|
|
50
|
+
-- Validação 1: Código obrigatório (já que não é mais gerado automaticamente pelo banco)
|
|
51
|
+
INSERT INTO import.errors (id_batch, row_num, error_msg)
|
|
52
|
+
SELECT @id_batch, s.row_num, 'O código é obrigatório'
|
|
53
|
+
FROM import.materials_services_staging s WITH (NOLOCK)
|
|
54
|
+
WHERE s.id_batch = @id_batch
|
|
55
|
+
AND NULLIF(RTRIM(LTRIM(s.code)), '') IS NULL;
|
|
56
|
+
|
|
57
|
+
-- Validação 2: Título duplicado dentro do próprio lote
|
|
58
|
+
INSERT INTO import.errors (id_batch, row_num, error_msg)
|
|
59
|
+
SELECT @id_batch, s.row_num, 'Título duplicado no arquivo'
|
|
60
|
+
FROM (
|
|
61
|
+
SELECT *, COUNT(*) OVER (PARTITION BY title) AS cnt
|
|
62
|
+
FROM import.materials_services_staging WITH (NOLOCK)
|
|
63
|
+
WHERE id_batch = @id_batch
|
|
64
|
+
) s
|
|
65
|
+
WHERE s.cnt > 1;
|
|
66
|
+
|
|
67
|
+
-- Validação 3: Título já existente na produção (mesma unidade)
|
|
68
|
+
INSERT INTO import.errors (id_batch, row_num, error_msg)
|
|
69
|
+
SELECT @id_batch, s.row_num, 'Título já existe na base'
|
|
70
|
+
FROM import.materials_services_staging s WITH (NOLOCK)
|
|
71
|
+
INNER JOIN suppliers.materials_services t WITH (NOLOCK)
|
|
72
|
+
ON t.title = s.title COLLATE Latin1_General_CS_AS
|
|
73
|
+
AND t.removed = 0
|
|
74
|
+
AND t.id_company = s.id_company COLLATE Latin1_General_CS_AS
|
|
75
|
+
WHERE s.id_batch = @id_batch;
|
|
76
|
+
|
|
77
|
+
-- Validação 4: Código duplicado no próprio lote
|
|
78
|
+
INSERT INTO import.errors (id_batch, row_num, error_msg)
|
|
79
|
+
SELECT @id_batch, s.row_num, 'Código duplicado no arquivo'
|
|
80
|
+
FROM (
|
|
81
|
+
SELECT *, COUNT(*) OVER (PARTITION BY code) AS cnt
|
|
82
|
+
FROM import.materials_services_staging WITH (NOLOCK)
|
|
83
|
+
WHERE id_batch = @id_batch
|
|
84
|
+
AND NULLIF(RTRIM(LTRIM(code)), '') IS NOT NULL
|
|
85
|
+
) s
|
|
86
|
+
WHERE s.cnt > 1;
|
|
87
|
+
|
|
88
|
+
-- Validação 5: Código já existente na produção
|
|
89
|
+
INSERT INTO import.errors (id_batch, row_num, error_msg)
|
|
90
|
+
SELECT @id_batch, s.row_num, 'Código já existe na base'
|
|
91
|
+
FROM import.materials_services_staging s WITH (NOLOCK)
|
|
92
|
+
INNER JOIN suppliers.materials_services t WITH (NOLOCK)
|
|
93
|
+
ON t.code = s.code COLLATE Latin1_General_CS_AS
|
|
94
|
+
AND t.removed = 0
|
|
95
|
+
AND t.id_company = s.id_company COLLATE Latin1_General_CS_AS
|
|
96
|
+
WHERE s.id_batch = @id_batch
|
|
97
|
+
AND NULLIF(RTRIM(LTRIM(s.code)), '') IS NOT NULL;
|
|
98
|
+
|
|
99
|
+
-- Validação 6: VALIDAÇÃO DO FORMATO PADRÃO DO SISTEMA (YY-00000)
|
|
100
|
+
-- Só é executada se a configuração da empresa exigir o código padrão (@IsCustomCodeEnabled = 0)
|
|
101
|
+
INSERT INTO import.errors (id_batch, row_num, error_msg)
|
|
102
|
+
SELECT @id_batch, s.row_num, 'Código inválido. Para o padrão do sistema, use o formato YY-00000 (ex: 25-00001)'
|
|
103
|
+
FROM import.materials_services_staging s WITH (NOLOCK)
|
|
104
|
+
WHERE s.id_batch = @id_batch
|
|
105
|
+
AND @IsCustomCodeEnabled = 0
|
|
106
|
+
AND NULLIF(RTRIM(LTRIM(s.code)), '') IS NOT NULL
|
|
107
|
+
-- O operador LIKE abaixo garante: 2 números, hífen, e exatamente 5 números (Formato: YY-00000)
|
|
108
|
+
AND s.code NOT LIKE '[0-9][0-9]-[0-9][0-9][0-9][0-9][0-9]';
|
|
109
|
+
|
|
110
|
+
-- Validação 7: Tipo de Fornecimento não encontrado
|
|
111
|
+
INSERT INTO import.errors (id_batch, row_num, error_msg)
|
|
112
|
+
SELECT @id_batch, s.row_num, 'Tipo de Fornecimento não encontrado ou inativo'
|
|
113
|
+
FROM import.materials_services_staging s WITH (NOLOCK)
|
|
114
|
+
LEFT JOIN suppliers.supply_types st WITH (NOLOCK)
|
|
115
|
+
ON st.title = s.supply_type_title COLLATE Latin1_General_CS_AS
|
|
116
|
+
AND st.id_company = s.id_company COLLATE Latin1_General_CS_AS
|
|
117
|
+
AND st.removed = 0
|
|
118
|
+
WHERE s.id_batch = @id_batch
|
|
119
|
+
AND st.id IS NULL;
|
|
120
|
+
|
|
121
|
+
-- Validação 8: Situação inválida
|
|
122
|
+
INSERT INTO import.errors (id_batch, row_num, error_msg)
|
|
123
|
+
SELECT @id_batch, s.row_num, 'Situação inválida (use Ativo ou Inativo)'
|
|
124
|
+
FROM import.materials_services_staging s WITH (NOLOCK)
|
|
125
|
+
WHERE s.id_batch = @id_batch
|
|
126
|
+
AND LTRIM(RTRIM(ISNULL(s.is_active, ''))) COLLATE Latin1_General_CI_AI
|
|
127
|
+
NOT IN ('ativo','inativo');
|
|
128
|
+
|
|
129
|
+
-- Inserção dos dados validados
|
|
130
|
+
INSERT INTO suppliers.materials_services
|
|
131
|
+
(
|
|
132
|
+
id_company,
|
|
133
|
+
id_supply_type,
|
|
134
|
+
code,
|
|
135
|
+
title,
|
|
136
|
+
description,
|
|
137
|
+
description_text,
|
|
138
|
+
is_active,
|
|
139
|
+
is_custom_code,
|
|
140
|
+
id_creation_user,
|
|
141
|
+
id_last_modified_user,
|
|
142
|
+
creation_date,
|
|
143
|
+
last_modified,
|
|
144
|
+
removed
|
|
145
|
+
)
|
|
146
|
+
SELECT
|
|
147
|
+
s.id_company,
|
|
148
|
+
st.id AS id_supply_type,
|
|
149
|
+
LTRIM(RTRIM(s.code)) AS code,
|
|
150
|
+
s.title,
|
|
151
|
+
NULLIF(s.description, '') AS description,
|
|
152
|
+
NULLIF(s.description, '') AS description_text,
|
|
153
|
+
|
|
154
|
+
CASE
|
|
155
|
+
WHEN LTRIM(RTRIM(ISNULL(s.is_active, ''))) COLLATE Latin1_General_CI_AI = 'inativo' THEN 0
|
|
156
|
+
ELSE 1
|
|
157
|
+
END AS is_active,
|
|
158
|
+
|
|
159
|
+
@IsCustomCodeEnabled AS is_custom_code,
|
|
160
|
+
s.id_creation_user,
|
|
161
|
+
s.id_creation_user AS id_last_modified_user,
|
|
162
|
+
SYSDATETIMEOFFSET() AS creation_date,
|
|
163
|
+
SYSDATETIMEOFFSET() AS last_modified,
|
|
164
|
+
0 AS removed
|
|
165
|
+
FROM import.materials_services_staging s WITH (NOLOCK)
|
|
166
|
+
INNER JOIN suppliers.supply_types st WITH (NOLOCK)
|
|
167
|
+
ON st.title = s.supply_type_title COLLATE Latin1_General_CS_AS
|
|
168
|
+
AND st.id_company = s.id_company COLLATE Latin1_General_CS_AS
|
|
169
|
+
AND st.removed = 0
|
|
170
|
+
WHERE s.id_batch = @id_batch
|
|
171
|
+
AND NOT EXISTS (
|
|
172
|
+
SELECT 1
|
|
173
|
+
FROM import.errors e
|
|
174
|
+
WHERE e.id_batch = s.id_batch
|
|
175
|
+
AND e.row_num = s.row_num
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
END
|
|
179
|
+
GO
|
|
180
|
+
|
|
181
|
+
-- criaçao da procedure de retornar erros
|
|
182
|
+
CREATE OR ALTER PROCEDURE [import].[get_errors_materials_services]
|
|
183
|
+
(
|
|
184
|
+
@id_batch UNIQUEIDENTIFIER
|
|
185
|
+
)
|
|
186
|
+
AS
|
|
187
|
+
BEGIN
|
|
188
|
+
SET NOCOUNT ON;
|
|
189
|
+
|
|
190
|
+
SELECT
|
|
191
|
+
STRING_AGG(
|
|
192
|
+
CAST(e.error_msg AS NVARCHAR(MAX)),
|
|
193
|
+
'; '
|
|
194
|
+
) WITHIN GROUP (ORDER BY e.error_msg) AS error_msg,
|
|
195
|
+
|
|
196
|
+
e.row_num,
|
|
197
|
+
s.title,
|
|
198
|
+
s.code,
|
|
199
|
+
s.id_creation_user
|
|
200
|
+
|
|
201
|
+
FROM import.errors e WITH (NOLOCK)
|
|
202
|
+
JOIN import.materials_services_staging s WITH (NOLOCK)
|
|
203
|
+
ON s.row_num = e.row_num
|
|
204
|
+
AND s.id_batch = e.id_batch
|
|
205
|
+
WHERE e.id_batch = @id_batch
|
|
206
|
+
GROUP BY
|
|
207
|
+
e.row_num,
|
|
208
|
+
s.title,
|
|
209
|
+
s.code,
|
|
210
|
+
s.id_creation_user
|
|
211
|
+
ORDER BY e.row_num;
|
|
212
|
+
END
|
|
213
|
+
GO
|
|
214
|
+
|
|
215
|
+
-- commit
|
|
216
|
+
-- rollback
|