@wgalleti/primevue-components 0.7.1 → 0.8.2

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.
Files changed (59) hide show
  1. package/README.md +17 -0
  2. package/bin/wpvc.mjs +209 -0
  3. package/dist/WProgressFlow.vue_vue_type_script_setup_true_lang-C9YG4BXB.cjs +12 -0
  4. package/dist/WProgressFlow.vue_vue_type_script_setup_true_lang-C9YG4BXB.cjs.map +1 -0
  5. package/dist/WProgressFlow.vue_vue_type_script_setup_true_lang-CoGaRckJ.js +3348 -0
  6. package/dist/WProgressFlow.vue_vue_type_script_setup_true_lang-CoGaRckJ.js.map +1 -0
  7. package/dist/components/crud/WCrudFormDialog.vue.d.ts +2 -215
  8. package/dist/components/crud/WCrudView.vue.d.ts +16 -8
  9. package/dist/components/form/WAutoCompleteFK.vue.d.ts +1 -1
  10. package/dist/components/form/WDatePicker.vue.d.ts +44 -0
  11. package/dist/components/form/WDateRange.vue.d.ts +23 -0
  12. package/dist/components/form/WFileUpload.vue.d.ts +48 -0
  13. package/dist/components/form/WFormRenderer.vue.d.ts +2 -37
  14. package/dist/components/index.d.ts +3 -0
  15. package/dist/components.cjs +1 -1
  16. package/dist/components.cjs.map +1 -1
  17. package/dist/components.js +124 -20
  18. package/dist/components.js.map +1 -1
  19. package/dist/composables/defineCrudConfig.d.ts +18 -0
  20. package/dist/composables/index.d.ts +4 -0
  21. package/dist/composables/useDateInput.d.ts +29 -0
  22. package/dist/composables/useFormKeyboardNav.d.ts +11 -0
  23. package/dist/composables.cjs +1 -1
  24. package/dist/composables.cjs.map +1 -1
  25. package/dist/composables.js +14 -8
  26. package/dist/composables.js.map +1 -1
  27. package/dist/index.cjs +1 -1
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.ts +3 -2
  30. package/dist/index.js +53 -50
  31. package/dist/primevue-components.css +1 -1
  32. package/dist/types/field.d.ts +5 -0
  33. package/dist/types/manager.d.ts +8 -0
  34. package/dist/useApi-BDjRqSFt.cjs +2 -0
  35. package/dist/useApi-BDjRqSFt.cjs.map +1 -0
  36. package/dist/useApi-CzOJADZw.js +395 -0
  37. package/dist/useApi-CzOJADZw.js.map +1 -0
  38. package/dist/useFormKeyboardNav-D4Irq5RE.js +461 -0
  39. package/dist/useFormKeyboardNav-D4Irq5RE.js.map +1 -0
  40. package/dist/useFormKeyboardNav-D4Ow3k4Y.cjs +3 -0
  41. package/dist/useFormKeyboardNav-D4Ow3k4Y.cjs.map +1 -0
  42. package/package.json +8 -3
  43. package/skill/SKILL.md +67 -0
  44. package/skill/references/components.md +51 -0
  45. package/skill/references/crud.md +83 -0
  46. package/skill/references/migration.md +58 -0
  47. package/skill/references/setup.md +74 -0
  48. package/dist/WProgressFlow.vue_vue_type_script_setup_true_lang-B70Uk-1x.cjs +0 -12
  49. package/dist/WProgressFlow.vue_vue_type_script_setup_true_lang-B70Uk-1x.cjs.map +0 -1
  50. package/dist/WProgressFlow.vue_vue_type_script_setup_true_lang-BVlG1in1.js +0 -3024
  51. package/dist/WProgressFlow.vue_vue_type_script_setup_true_lang-BVlG1in1.js.map +0 -1
  52. package/dist/useApi-B692TOWz.js +0 -383
  53. package/dist/useApi-B692TOWz.js.map +0 -1
  54. package/dist/useApi-BIlKLud-.cjs +0 -2
  55. package/dist/useApi-BIlKLud-.cjs.map +0 -1
  56. package/dist/useApiError-BEbEk2Kq.cjs +0 -3
  57. package/dist/useApiError-BEbEk2Kq.cjs.map +0 -1
  58. package/dist/useApiError-C7rPzGrF.js +0 -375
  59. package/dist/useApiError-C7rPzGrF.js.map +0 -1
@@ -22,6 +22,12 @@ export interface CrudManagerConfig<T> {
22
22
  * search or filter position. Defaults to `true`. Set `false` to keep the
23
23
  * optimistic in-place update instead. */
24
24
  refetchOnSave?: boolean;
25
+ /** Modo de edição: 'dialog' (default — abre o form dialog) ou 'cell' (edição
26
+ * inline por célula, com PATCH só do campo alterado). */
27
+ editMode?: 'cell' | 'dialog';
28
+ /** Navegação por teclado no form dialog: foca o 1º campo ao abrir e o Enter
29
+ * pula para o próximo campo até o botão salvar (F2 abre a busca em FKs). */
30
+ keyboardNav?: boolean;
25
31
  canCreate?: boolean;
26
32
  canEdit?: boolean;
27
33
  canDelete?: boolean;
@@ -77,6 +83,8 @@ export interface CrudManagerReturn<T> {
77
83
  openViewDialog(item: T): void;
78
84
  openDuplicateDialog(item: T): void;
79
85
  save(): Promise<T | null>;
86
+ /** Salva um único campo de um item (edição inline por célula) via PATCH. */
87
+ updateField(item: T, field: string, value: unknown): Promise<void>;
80
88
  confirmDelete(item: T): void;
81
89
  setFormField(field: string, value: unknown): void;
82
90
  resetForm(): void;
@@ -0,0 +1,2 @@
1
+ "use strict";const o=require("vue"),Y=require("./plugin-D1YvyKXX.cjs"),Oe=require("./types.cjs"),b=require("./useFormKeyboardNav-D4Ow3k4Y.cjs");function ze(j,P){const v={};for(const g of Object.keys(P))JSON.stringify(j[g])!==JSON.stringify(P[g])&&(v[g]=P[g]);return v}function Fe(j){const{endpoint:P,form:v,pk:g="id",searchDebounce:U=300,partialUpdate:$=!0,refetchOnSave:E=!0,filterParams:R=void 0,createDefaults:_=void 0,transformPayload:T=void 0,onAfterSave:x=void 0,onAfterDelete:q=void 0}=j,A=o.inject(Y.W_DATA_PROVIDER_KEY);if(!A)throw new Error("[wPrimeVueComponents] dataProvider não encontrado. Registre o WPrimeVuePlugin antes de usar useCrudManager.");const n=A,w=o.inject(Y.W_CONFIG_KEY),M=j.pageSize??(w==null?void 0:w.defaultPageSize)??20,f={...Oe.DEFAULT_CRUD_LABELS,...j.labels},k=b.useAppToast(),{confirmDelete:G}=b.useAppConfirm(),h=o.ref([]),W=o.ref([]),L=o.ref({}),K=o.ref(!1),u=o.ref(!1),y=o.ref(""),p=o.ref(!1),z=o.ref(!1),d=o.ref(null),D=o.reactive({});let C=null;const s=o.reactive({page:1,pageSize:M,rows:0,totalPages:0}),m=o.reactive({field:null,order:0}),V=o.reactive({});function Q(){const e={};for(const t of v)e[t.field]=t.defaultValue!==void 0?typeof t.defaultValue=="function"?t.defaultValue():t.defaultValue:null;return e}const X=Q();for(const e of Object.keys(X))D[e]=X[e];const I=o.computed(()=>d.value!==null&&!z.value),ae=o.computed(()=>z.value),ie=o.computed(()=>z.value?f.viewTitle??"Visualizar Registro":I.value?f.editTitle:f.createTitle),oe=o.computed(()=>s.page<=1),ne=o.computed(()=>s.page>=s.totalPages);let J=null;async function F(e={}){K.value=!0;try{const t={page:s.page,page_size:s.pageSize,...e};y.value&&(t.search=y.value),m.field&&m.order!==0&&(t.ordering=m.order===-1?`-${m.field}`:m.field),R&&Object.assign(t,R());for(const[i,c]of Object.entries(V))c!=null&&c!==""&&(t[i]=c);const a=await n.list(P,t);h.value=a.data,W.value=[],s.rows=a.rows,L.value=a.extras??{},a.page&&(s.page=a.page),a.page_size&&(s.pageSize=a.page_size),s.totalPages=Math.ceil(s.rows/s.pageSize)||0}finally{K.value=!1}}async function se(){await F()}async function re(){await F()}async function le(e=200){const t={};y.value&&(t.search=y.value),m.field&&m.order!==0&&(t.ordering=m.order===-1?`-${m.field}`:m.field),R&&Object.assign(t,R());for(const[l,r]of Object.entries(V))r!=null&&r!==""&&(t[l]=r);const a=[];let i=1;const c=1e4;for(;i<=c;){const l=await n.list(P,{...t,page:i,page_size:e});a.push(...l.data);const r=l.rows??a.length;if(l.data.length===0||a.length>=r)break;i++}return a}function Z(e){y.value=e,J&&clearTimeout(J),J=setTimeout(()=>{s.page=1,F()},U)}function ce(e){const t=e.target;Z(t.value)}function B(e){s.page=e,F()}function fe(){B(1)}function ue(){B(s.totalPages)}function de(e){s.page=e.page+1,s.pageSize=e.rows,F()}function pe(e){m.field=e.sortField??null,m.order=e.sortOrder??0,s.page=1,F()}function H(){const e=Q();for(const t of Object.keys(e))D[t]=e[t]}function ge(e,t){D[e]=t}function ve(){if(z.value=!1,d.value=null,C=null,H(),_){const e=_();for(const[t,a]of Object.entries(e))D[t]=a}p.value=!0}function ee(e){const t={};for(const a of v){let i=e[a.field]!==void 0?e[a.field]:null;i&&(a.type==="date"||a.type==="datetime")&&typeof i=="string"&&(i=b.parseDate(i)),D[a.field]=i,t[a.field]=i}C=t}function ye(e){z.value=!1,d.value=e,ee(e),p.value=!0}function me(e){z.value=!0,d.value=e,ee(e),p.value=!0}function Pe(e){z.value=!1,d.value=null,C=null,H();for(const t of v){if(t.field===g)continue;let a=e[t.field]!==void 0?e[t.field]:D[t.field];a&&(t.type==="date"||t.type==="datetime")&&typeof a=="string"&&(a=b.parseDate(a)),D[t.field]=a}if(_){const t=_();for(const[a,i]of Object.entries(t))D[a]=i}p.value=!0}function te(e){const t={...e};for(const a of v){const i=t[a.field];if(a.type==="date"&&i instanceof Date?t[a.field]=b.toDateString(i):a.type==="datetime"&&i instanceof Date&&(t[a.field]=b.toDateTimeString(i)),a.type==="fk"&&i!==null&&typeof i=="object"){const c=a.optionValue||"id";t[a.field]=i[c]??i}(a.type==="mask"||a.type==="cpf_cnpj")&&typeof i=="string"&&(t[a.field]=b.stripMask(i))}return t}async function we(){for(const e of v){if(e.validate){const t=e.validate(D[e.field]);if(t)return k.error(t),null}if(e.required){const t=D[e.field];if(t==null||t==="")return k.error(`${e.label} é obrigatório`),null}}u.value=!0;try{let e=te(D);if(!I.value&&_&&Object.assign(e,_()),I.value&&$&&C){const r=te(C);if(e=ze(r,e),Object.keys(e).length===0&&!T){p.value=!1;const S=d.value;return d.value=null,C=null,S}}T&&(e=T(e,I.value));const t=v.some(r=>r.type==="image"&&e[r.field]instanceof File);let a=e,i;if(t){const r=new Set(v.filter(O=>O.type==="image").map(O=>O.field)),S=new FormData;for(const[O,N]of Object.entries(e))if(N!=null)if(N instanceof File)S.append(O,N);else{if(r.has(O))continue;S.append(O,String(N))}a=S,i={"Content-Type":"multipart/form-data"}}const c=i?{headers:i}:void 0;let l;if(I.value&&d.value){const r=d.value[g];if(l=await n.update(P,r,a,c),!E){const S=h.value.findIndex(O=>O[g]===r);S!==-1&&(h.value[S]=l.data)}k.success(f.successUpdate)}else l=await n.create(P,a,c),E||(h.value.unshift(l.data),s.rows++),k.success(f.successCreate);return p.value=!1,d.value=null,C=null,E&&await F(),x&&x(l.data,I.value),l.data}catch(e){return k.error(b.extractApiError(e,"Erro ao salvar registro")),null}finally{u.value=!1}}async function he(e,t,a){const i=e[g],c=v.find(r=>r.field===t);let l=a;(c==null?void 0:c.type)==="date"&&l instanceof Date?l=b.toDateString(l):(c==null?void 0:c.type)==="datetime"&&l instanceof Date&&(l=b.toDateTimeString(l));try{const r=await n.update(P,i,{[t]:l}),S=h.value.findIndex(O=>O[g]===i);S!==-1&&(h.value[S]={...h.value[S],...r.data}),k.success(f.successUpdate)}catch(r){k.error(b.extractApiError(r,"Erro ao salvar o campo"))}}function De(e){G(async()=>{try{const t=e[g];await n.delete(P,t);const a=h.value.findIndex(i=>i[g]===t);a!==-1&&(h.value.splice(a,1),s.rows--),k.success(f.successDelete),q&&q(e)}catch(t){k.error(b.extractApiError(t,"Erro ao excluir registro"))}},f.deleteConfirmMessage)}function Se(){W.value=[]}function be(e,t){t==null||t===""?delete V[e]:V[e]=t,s.page=1,F()}function ke(){for(const e of Object.keys(V))delete V[e];s.page=1,F()}return{items:h,selectedItems:W,columnFilters:V,extras:L,loading:K,saving:u,search:y,dialogVisible:p,editingItem:d,formData:D,pagination:s,sort:m,isEditing:I,isViewing:ae,viewMode:z,dialogTitle:ie,isFirstPage:oe,isLastPage:ne,init:se,fetchItems:F,fetchAll:le,refresh:re,setSearch:Z,onSearch:ce,onPage:de,onSort:pe,openCreateDialog:ve,openEditDialog:ye,openViewDialog:me,openDuplicateDialog:Pe,save:we,updateField:he,confirmDelete:De,setFormField:ge,resetForm:H,goToPage:B,firstPage:fe,lastPage:ue,clearSelection:Se,setColumnFilter:be,clearColumnFilters:ke,config:j}}function je(j){const{endpoint:P,searchDebounce:v=300,immediate:g=!1}=j,U=o.inject(Y.W_DATA_PROVIDER_KEY);if(!U)throw new Error("[wPrimeVueComponents] dataProvider não encontrado. Registre o WPrimeVuePlugin antes de usar useApi.");const $=U,E=o.inject(Y.W_CONFIG_KEY),R=j.pageSize??(E==null?void 0:E.defaultPageSize)??20,_=o.ref([]),T=o.ref(!1),x=o.ref(""),q=o.ref({}),A=o.reactive({}),n=o.reactive({page:1,pageSize:R,rows:0,totalPages:0}),w=o.reactive({field:null,order:0});let M=null;async function f(u={}){T.value=!0;try{const y={page:n.page,page_size:n.pageSize,...u};x.value&&(y.search=x.value),w.field&&w.order!==0&&(y.ordering=w.order===-1?`-${w.field}`:w.field);for(const[z,d]of Object.entries(A))d!=null&&d!==""&&(y[z]=d);const p=await $.list(P,y);_.value=p.data,n.rows=p.rows,p.page&&(n.page=p.page),p.page_size&&(n.pageSize=p.page_size),n.totalPages=Math.ceil(n.rows/n.pageSize)||0,q.value=p.extras??{}}finally{T.value=!1}}async function k(){await f()}function G(u){x.value=u,M&&clearTimeout(M),M=setTimeout(()=>{n.page=1,f()},v)}function h(u,y){A[u]=y,n.page=1,f()}function W(){for(const u of Object.keys(A))delete A[u];n.page=1,f()}function L(u){n.page=u.page+1,n.pageSize=u.rows,f()}function K(u){w.field=u.sortField??null,w.order=u.sortOrder??0,n.page=1,f()}return g&&f(),{items:_,loading:T,search:x,pagination:n,sort:w,extras:q,fetchItems:f,refresh:k,setSearch:G,setFilter:h,clearFilters:W,onPage:L,onSort:K}}exports.useApi=je;exports.useCrudManager=Fe;
2
+ //# sourceMappingURL=useApi-BDjRqSFt.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useApi-BDjRqSFt.cjs","sources":["../src/composables/useCrudManager.ts","../src/composables/useApi.ts"],"sourcesContent":["import { ref, reactive, computed, inject } from 'vue'\nimport { W_CONFIG_KEY, W_DATA_PROVIDER_KEY } from '@/types/plugin'\nimport type { WPluginConfig } from '@/types/plugin'\nimport type { DataProvider } from '@/types/dataProvider'\nimport type { PaginationState, SortState } from '@/types/api'\nimport type { CrudManagerConfig, CrudManagerReturn } from '@/types/manager'\nimport type { CrudLabels } from '@/types/labels'\nimport { DEFAULT_CRUD_LABELS } from '@/types/labels'\nimport { useAppToast } from './useAppToast'\nimport { useAppConfirm } from './useAppConfirm'\nimport { extractApiError } from './useApiError'\nimport { parseDate, toDateString, toDateTimeString } from '@/utils/dates'\nimport { stripMask } from '@/utils/masks'\n\n/** Shallow diff: returns only the keys whose value changed between two records. */\nfunction diffRecord(\n original: Record<string, unknown>,\n current: Record<string, unknown>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const key of Object.keys(current)) {\n if (JSON.stringify(original[key]) !== JSON.stringify(current[key])) {\n out[key] = current[key]\n }\n }\n return out\n}\n\nexport function useCrudManager<T extends Record<string, unknown> = Record<string, unknown>>(\n config: CrudManagerConfig<T>,\n): CrudManagerReturn<T> {\n const {\n endpoint,\n form: formFields,\n pk = 'id',\n searchDebounce = 300,\n partialUpdate = true,\n refetchOnSave = true,\n filterParams = undefined,\n createDefaults = undefined,\n transformPayload = undefined,\n onAfterSave = undefined,\n onAfterDelete = undefined,\n } = config\n\n const dataProvider = inject<DataProvider>(W_DATA_PROVIDER_KEY)\n if (!dataProvider) {\n throw new Error(\n '[wPrimeVueComponents] dataProvider não encontrado. Registre o WPrimeVuePlugin antes de usar useCrudManager.',\n )\n }\n const provider = dataProvider\n\n const pluginConfig = inject<WPluginConfig>(W_CONFIG_KEY)\n const defaultPageSize = config.pageSize ?? pluginConfig?.defaultPageSize ?? 20\n\n const labels: CrudLabels = { ...DEFAULT_CRUD_LABELS, ...config.labels }\n const toast = useAppToast()\n const { confirmDelete: confirmDeleteDialog } = useAppConfirm()\n\n // ---------------------------------------------------------------------------\n // State\n // ---------------------------------------------------------------------------\n\n const items = ref<T[]>([]) as import('vue').Ref<T[]>\n const selectedItems = ref<T[]>([]) as import('vue').Ref<T[]>\n const extras = ref<Record<string, unknown>>({})\n const loading = ref(false)\n const saving = ref(false)\n const search = ref('')\n const dialogVisible = ref(false)\n const viewMode = ref(false)\n const editingItem = ref<T | null>(null) as import('vue').Ref<T | null>\n const formData = reactive<Record<string, unknown>>({})\n // Snapshot of the form values when an edit dialog opens — used for diff-based PATCH.\n let editingOriginal: Record<string, unknown> | null = null\n\n const pagination: PaginationState = reactive({\n page: 1,\n pageSize: defaultPageSize,\n rows: 0,\n totalPages: 0,\n })\n\n const sort: SortState = reactive({\n field: null,\n order: 0,\n })\n\n // Filtros de coluna ativos (param → valor). Persistem entre páginas/ordenação.\n const columnFilters = reactive<Record<string, unknown>>({})\n\n // ---------------------------------------------------------------------------\n // Defaults\n // ---------------------------------------------------------------------------\n\n function getDefaults(): Record<string, unknown> {\n const defaults: Record<string, unknown> = {}\n for (const f of formFields) {\n defaults[f.field] =\n f.defaultValue !== undefined\n ? typeof f.defaultValue === 'function'\n ? (f.defaultValue as () => unknown)()\n : f.defaultValue\n : null\n }\n return defaults\n }\n\n // Initialize\n const defaults = getDefaults()\n for (const key of Object.keys(defaults)) {\n formData[key] = defaults[key]\n }\n\n // ---------------------------------------------------------------------------\n // Computed\n // ---------------------------------------------------------------------------\n\n const isEditing = computed(() => editingItem.value !== null && !viewMode.value)\n const isViewing = computed(() => viewMode.value)\n const dialogTitle = computed(() =>\n viewMode.value\n ? (labels.viewTitle ?? 'Visualizar Registro')\n : isEditing.value\n ? labels.editTitle\n : labels.createTitle,\n )\n const isFirstPage = computed(() => pagination.page <= 1)\n const isLastPage = computed(() => pagination.page >= pagination.totalPages)\n\n // ---------------------------------------------------------------------------\n // Fetch\n // ---------------------------------------------------------------------------\n\n let searchTimeout: ReturnType<typeof setTimeout> | null = null\n\n async function fetchItems(params: Record<string, unknown> = {}): Promise<void> {\n loading.value = true\n try {\n const queryParams: Record<string, unknown> = {\n page: pagination.page,\n page_size: pagination.pageSize,\n ...params,\n }\n\n if (search.value) {\n queryParams.search = search.value\n }\n\n if (sort.field && sort.order !== 0) {\n queryParams.ordering = sort.order === -1 ? `-${sort.field}` : sort.field\n }\n\n if (filterParams) {\n Object.assign(queryParams, filterParams())\n }\n\n // Filtros de coluna ativos (ignora vazios).\n for (const [key, val] of Object.entries(columnFilters)) {\n if (val !== null && val !== undefined && val !== '') queryParams[key] = val\n }\n\n const responseData = await provider.list<T>(endpoint, queryParams)\n items.value = responseData.data\n selectedItems.value = [] // seleção anterior fica obsoleta ao recarregar\n pagination.rows = responseData.rows\n extras.value = responseData.extras ?? {}\n if (responseData.page) pagination.page = responseData.page\n if (responseData.page_size) pagination.pageSize = responseData.page_size\n pagination.totalPages = Math.ceil(pagination.rows / pagination.pageSize) || 0\n } finally {\n loading.value = false\n }\n }\n\n async function init(): Promise<void> {\n await fetchItems()\n }\n\n async function refresh(): Promise<void> {\n await fetchItems()\n }\n\n /**\n * Fetch every record across all pages (respeitando search, sort e\n * filterParams atuais) sem alterar o estado da lista. Útil para exportações.\n */\n async function fetchAll(pageSize = 200): Promise<T[]> {\n const base: Record<string, unknown> = {}\n if (search.value) base.search = search.value\n if (sort.field && sort.order !== 0) {\n base.ordering = sort.order === -1 ? `-${sort.field}` : sort.field\n }\n if (filterParams) Object.assign(base, filterParams())\n for (const [key, val] of Object.entries(columnFilters)) {\n if (val !== null && val !== undefined && val !== '') base[key] = val\n }\n\n const all: T[] = []\n let page = 1\n // Hard cap para evitar loop infinito caso o backend não pagine corretamente.\n const maxPages = 10000\n while (page <= maxPages) {\n const res = await provider.list<T>(endpoint, {\n ...base,\n page,\n page_size: pageSize,\n })\n all.push(...res.data)\n const total = res.rows ?? all.length\n if (res.data.length === 0 || all.length >= total) break\n page++\n }\n return all\n }\n\n // ---------------------------------------------------------------------------\n // Search\n // ---------------------------------------------------------------------------\n\n function setSearch(value: string): void {\n search.value = value\n if (searchTimeout) clearTimeout(searchTimeout)\n searchTimeout = setTimeout(() => {\n pagination.page = 1\n fetchItems()\n }, searchDebounce)\n }\n\n function onSearch(event: Event): void {\n const target = event.target as HTMLInputElement\n setSearch(target.value)\n }\n\n // ---------------------------------------------------------------------------\n // Pagination\n // ---------------------------------------------------------------------------\n\n function goToPage(page: number): void {\n pagination.page = page\n fetchItems()\n }\n\n function firstPage(): void {\n goToPage(1)\n }\n\n function lastPage(): void {\n goToPage(pagination.totalPages)\n }\n\n function onPage(event: { page: number; rows: number }): void {\n pagination.page = event.page + 1\n pagination.pageSize = event.rows\n fetchItems()\n }\n\n function onSort(event: { sortField?: string | null; sortOrder?: 1 | -1 | 0 | null }): void {\n sort.field = event.sortField ?? null\n sort.order = event.sortOrder ?? 0\n pagination.page = 1\n fetchItems()\n }\n\n // ---------------------------------------------------------------------------\n // Form\n // ---------------------------------------------------------------------------\n\n function resetForm(): void {\n const defs = getDefaults()\n for (const key of Object.keys(defs)) {\n formData[key] = defs[key]\n }\n }\n\n function setFormField(field: string, value: unknown): void {\n formData[field] = value\n }\n\n function openCreateDialog(): void {\n viewMode.value = false\n editingItem.value = null\n editingOriginal = null\n resetForm()\n // Apply createDefaults (e.g. parent FK) on top of field defaults\n if (createDefaults) {\n const extra = createDefaults()\n for (const [key, val] of Object.entries(extra)) {\n formData[key] = val\n }\n }\n dialogVisible.value = true\n }\n\n function loadItemIntoForm(item: T): void {\n const snapshot: Record<string, unknown> = {}\n for (const f of formFields) {\n let value = item[f.field] !== undefined ? item[f.field] : null\n if (value && (f.type === 'date' || f.type === 'datetime') && typeof value === 'string') {\n value = parseDate(value)\n }\n formData[f.field] = value\n snapshot[f.field] = value\n }\n editingOriginal = snapshot\n }\n\n function openEditDialog(item: T): void {\n viewMode.value = false\n editingItem.value = item\n loadItemIntoForm(item)\n dialogVisible.value = true\n }\n\n function openViewDialog(item: T): void {\n viewMode.value = true\n editingItem.value = item\n loadItemIntoForm(item)\n dialogVisible.value = true\n }\n\n function openDuplicateDialog(item: T): void {\n // Abre o diálogo em modo criação, pré-preenchido com os dados do registro\n // (exceto a chave primária).\n viewMode.value = false\n editingItem.value = null\n editingOriginal = null\n resetForm()\n for (const f of formFields) {\n if (f.field === pk) continue\n let value = item[f.field] !== undefined ? item[f.field] : formData[f.field]\n if (value && (f.type === 'date' || f.type === 'datetime') && typeof value === 'string') {\n value = parseDate(value)\n }\n formData[f.field] = value\n }\n // createDefaults (ex: FK do pai) sobrepõe os valores duplicados.\n if (createDefaults) {\n const extra = createDefaults()\n for (const [key, val] of Object.entries(extra)) {\n formData[key] = val\n }\n }\n dialogVisible.value = true\n }\n\n // ---------------------------------------------------------------------------\n // Save\n // ---------------------------------------------------------------------------\n\n // Apply automatic conversions (dates, FK objects, masks) to a record,\n // returning a fresh plain object suitable for the API payload.\n function convertRecord(record: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = { ...record }\n for (const f of formFields) {\n const val = out[f.field]\n\n // Datas\n if (f.type === 'date' && val instanceof Date) {\n out[f.field] = toDateString(val)\n } else if (f.type === 'datetime' && val instanceof Date) {\n out[f.field] = toDateTimeString(val)\n }\n\n // FK — extrair o ID do objeto selecionado\n if (f.type === 'fk' && val !== null && typeof val === 'object') {\n const key = f.optionValue || 'id'\n out[f.field] = (val as Record<string, unknown>)[key] ?? val\n }\n\n // Máscaras — strip para enviar só dígitos\n if ((f.type === 'mask' || f.type === 'cpf_cnpj') && typeof val === 'string') {\n out[f.field] = stripMask(val)\n }\n }\n return out\n }\n\n async function save(): Promise<T | null> {\n // Validação\n for (const f of formFields) {\n if (f.validate) {\n const result = f.validate(formData[f.field])\n if (result) {\n toast.error(result)\n return null\n }\n }\n if (f.required) {\n const val = formData[f.field]\n if (val === null || val === undefined || val === '') {\n toast.error(`${f.label} é obrigatório`)\n return null\n }\n }\n }\n\n saving.value = true\n try {\n let payload: Record<string, unknown> = convertRecord(formData)\n\n // Merge createDefaults into payload for new records (hidden parent FKs, etc.)\n if (!isEditing.value && createDefaults) {\n Object.assign(payload, createDefaults())\n }\n\n // Edição: enviar apenas os campos alterados (diff) quando partialUpdate.\n if (isEditing.value && partialUpdate && editingOriginal) {\n const originalPayload = convertRecord(editingOriginal)\n payload = diffRecord(originalPayload, payload)\n\n // Nada mudou — fecha sem chamar a API.\n if (Object.keys(payload).length === 0 && !transformPayload) {\n dialogVisible.value = false\n const current = editingItem.value\n editingItem.value = null\n editingOriginal = null\n return current\n }\n }\n\n if (transformPayload) {\n payload = transformPayload(payload, isEditing.value)\n }\n\n // Detecta se tem arquivo (image) → FormData\n const hasFile = formFields.some((f) => f.type === 'image' && payload[f.field] instanceof File)\n\n let body: Record<string, unknown> | FormData = payload\n let headers: Record<string, string> | undefined\n\n if (hasFile) {\n const imageFields = new Set(\n formFields.filter((f) => f.type === 'image').map((f) => f.field),\n )\n const fd = new FormData()\n for (const [key, val] of Object.entries(payload)) {\n if (val === null || val === undefined) continue\n if (val instanceof File) {\n fd.append(key, val)\n } else if (imageFields.has(key)) {\n // URL string de imagem inalterada — pula\n continue\n } else {\n fd.append(key, String(val))\n }\n }\n body = fd\n headers = { 'Content-Type': 'multipart/form-data' }\n }\n\n const requestConfig = headers ? { headers } : undefined\n let response\n\n if (isEditing.value && editingItem.value) {\n const itemPk = editingItem.value[pk as keyof T]\n response = await provider.update<T>(\n endpoint,\n itemPk as string | number,\n body,\n requestConfig,\n )\n if (!refetchOnSave) {\n const index = items.value.findIndex((i) => i[pk as keyof T] === itemPk)\n if (index !== -1) {\n items.value[index] = response.data\n }\n }\n toast.success(labels.successUpdate)\n } else {\n response = await provider.create<T>(endpoint, body, requestConfig)\n if (!refetchOnSave) {\n items.value.unshift(response.data)\n pagination.rows++\n }\n toast.success(labels.successCreate)\n }\n\n dialogVisible.value = false\n editingItem.value = null\n editingOriginal = null\n\n // Re-busca a página atual para refletir o estado real do backend\n // (campos derivados, ordenação, etc.) sem perder a posição da paginação,\n // busca ou filtros — todos preservados em `pagination`/`search`/`sort`.\n if (refetchOnSave) {\n await fetchItems()\n }\n\n if (onAfterSave) onAfterSave(response.data, isEditing.value)\n return response.data\n } catch (err) {\n toast.error(extractApiError(err, 'Erro ao salvar registro'))\n return null\n } finally {\n saving.value = false\n }\n }\n\n // ---------------------------------------------------------------------------\n // Inline (cell) edit\n // ---------------------------------------------------------------------------\n\n async function updateField(item: T, field: string, value: unknown): Promise<void> {\n const itemPk = item[pk as keyof T]\n const fdef = formFields.find((f) => f.field === field)\n let v = value\n if (fdef?.type === 'date' && v instanceof Date) v = toDateString(v)\n else if (fdef?.type === 'datetime' && v instanceof Date) v = toDateTimeString(v)\n try {\n const response = await provider.update<T>(endpoint, itemPk as string | number, { [field]: v })\n const index = items.value.findIndex((i) => i[pk as keyof T] === itemPk)\n if (index !== -1) items.value[index] = { ...items.value[index], ...response.data }\n toast.success(labels.successUpdate)\n } catch (err) {\n toast.error(extractApiError(err, 'Erro ao salvar o campo'))\n }\n }\n\n // ---------------------------------------------------------------------------\n // Delete\n // ---------------------------------------------------------------------------\n\n function confirmDelete(item: T): void {\n confirmDeleteDialog(async () => {\n try {\n const itemPk = item[pk as keyof T]\n await provider.delete(endpoint, itemPk as string | number)\n const index = items.value.findIndex((i) => i[pk as keyof T] === itemPk)\n if (index !== -1) {\n items.value.splice(index, 1)\n pagination.rows--\n }\n toast.success(labels.successDelete)\n if (onAfterDelete) onAfterDelete(item)\n } catch (err) {\n toast.error(extractApiError(err, 'Erro ao excluir registro'))\n }\n }, labels.deleteConfirmMessage)\n }\n\n function clearSelection(): void {\n selectedItems.value = []\n }\n\n function setColumnFilter(param: string, value: unknown): void {\n if (value === null || value === undefined || value === '') {\n delete columnFilters[param]\n } else {\n columnFilters[param] = value\n }\n pagination.page = 1\n fetchItems()\n }\n\n function clearColumnFilters(): void {\n for (const key of Object.keys(columnFilters)) delete columnFilters[key]\n pagination.page = 1\n fetchItems()\n }\n\n // ---------------------------------------------------------------------------\n // Return\n // ---------------------------------------------------------------------------\n\n return {\n items,\n selectedItems,\n columnFilters,\n extras,\n loading,\n saving,\n search,\n dialogVisible,\n editingItem,\n formData,\n pagination,\n sort,\n isEditing,\n isViewing,\n viewMode,\n dialogTitle,\n isFirstPage,\n isLastPage,\n init,\n fetchItems,\n fetchAll,\n refresh,\n setSearch,\n onSearch,\n onPage,\n onSort,\n openCreateDialog,\n openEditDialog,\n openViewDialog,\n openDuplicateDialog,\n save,\n updateField,\n confirmDelete,\n setFormField,\n resetForm,\n goToPage,\n firstPage,\n lastPage,\n clearSelection,\n setColumnFilter,\n clearColumnFilters,\n config,\n }\n}\n","import { ref, reactive, inject } from 'vue'\nimport type { PaginationState, SortState, UseApiOptions, UseApiReturn } from '@/types/api'\nimport { W_CONFIG_KEY, W_DATA_PROVIDER_KEY } from '@/types/plugin'\nimport type { WPluginConfig } from '@/types/plugin'\nimport type { DataProvider } from '@/types/dataProvider'\n\nexport function useApi<T = Record<string, unknown>>(options: UseApiOptions): UseApiReturn<T> {\n const { endpoint, searchDebounce = 300, immediate = false } = options\n\n const dataProvider = inject<DataProvider>(W_DATA_PROVIDER_KEY)\n if (!dataProvider) {\n throw new Error(\n '[wPrimeVueComponents] dataProvider não encontrado. Registre o WPrimeVuePlugin antes de usar useApi.',\n )\n }\n const provider = dataProvider\n\n const config = inject<WPluginConfig>(W_CONFIG_KEY)\n const defaultPageSize = options.pageSize ?? config?.defaultPageSize ?? 20\n\n // State\n const items = ref<T[]>([]) as import('vue').Ref<T[]>\n const loading = ref(false)\n const search = ref('')\n const extras = ref<Record<string, unknown>>({})\n const filters = reactive<Record<string, unknown>>({})\n\n const pagination: PaginationState = reactive({\n page: 1,\n pageSize: defaultPageSize,\n rows: 0,\n totalPages: 0,\n })\n\n const sort: SortState = reactive({\n field: null,\n order: 0,\n })\n\n // Debounce\n let searchTimeout: ReturnType<typeof setTimeout> | null = null\n\n async function fetchItems(params: Record<string, unknown> = {}): Promise<void> {\n loading.value = true\n try {\n const queryParams: Record<string, unknown> = {\n page: pagination.page,\n page_size: pagination.pageSize,\n ...params,\n }\n\n if (search.value) {\n queryParams.search = search.value\n }\n\n if (sort.field && sort.order !== 0) {\n queryParams.ordering = sort.order === -1 ? `-${sort.field}` : sort.field\n }\n\n for (const [key, value] of Object.entries(filters)) {\n if (value !== null && value !== undefined && value !== '') {\n queryParams[key] = value\n }\n }\n\n const responseData = await provider.list<T>(endpoint, queryParams)\n\n items.value = responseData.data\n pagination.rows = responseData.rows\n if (responseData.page) pagination.page = responseData.page\n if (responseData.page_size) pagination.pageSize = responseData.page_size\n pagination.totalPages = Math.ceil(pagination.rows / pagination.pageSize) || 0\n extras.value = responseData.extras ?? {}\n } finally {\n loading.value = false\n }\n }\n\n async function refresh(): Promise<void> {\n await fetchItems()\n }\n\n function setSearch(value: string): void {\n search.value = value\n if (searchTimeout) clearTimeout(searchTimeout)\n searchTimeout = setTimeout(() => {\n pagination.page = 1\n fetchItems()\n }, searchDebounce)\n }\n\n function setFilter(key: string, value: unknown): void {\n filters[key] = value\n pagination.page = 1\n fetchItems()\n }\n\n function clearFilters(): void {\n for (const key of Object.keys(filters)) {\n delete filters[key]\n }\n pagination.page = 1\n fetchItems()\n }\n\n function onPage(event: { page: number; rows: number }): void {\n pagination.page = event.page + 1\n pagination.pageSize = event.rows\n fetchItems()\n }\n\n function onSort(event: { sortField: string; sortOrder: 1 | -1 | 0 }): void {\n sort.field = event.sortField ?? null\n sort.order = event.sortOrder ?? 0\n pagination.page = 1\n fetchItems()\n }\n\n if (immediate) {\n fetchItems()\n }\n\n return {\n items,\n loading,\n search,\n pagination,\n sort,\n extras,\n fetchItems,\n refresh,\n setSearch,\n setFilter,\n clearFilters,\n onPage,\n onSort,\n }\n}\n"],"names":["diffRecord","original","current","out","key","useCrudManager","config","endpoint","formFields","pk","searchDebounce","partialUpdate","refetchOnSave","filterParams","createDefaults","transformPayload","onAfterSave","onAfterDelete","dataProvider","inject","W_DATA_PROVIDER_KEY","provider","pluginConfig","W_CONFIG_KEY","defaultPageSize","labels","DEFAULT_CRUD_LABELS","toast","useAppToast","confirmDeleteDialog","useAppConfirm","items","ref","selectedItems","extras","loading","saving","search","dialogVisible","viewMode","editingItem","formData","reactive","editingOriginal","pagination","sort","columnFilters","getDefaults","defaults","f","isEditing","computed","isViewing","dialogTitle","isFirstPage","isLastPage","searchTimeout","fetchItems","params","queryParams","val","responseData","init","refresh","fetchAll","pageSize","base","all","page","maxPages","res","total","setSearch","value","onSearch","event","target","goToPage","firstPage","lastPage","onPage","onSort","resetForm","defs","setFormField","field","openCreateDialog","extra","loadItemIntoForm","item","snapshot","parseDate","openEditDialog","openViewDialog","openDuplicateDialog","convertRecord","record","toDateString","toDateTimeString","stripMask","save","result","payload","originalPayload","hasFile","body","headers","imageFields","fd","requestConfig","response","itemPk","index","i","err","extractApiError","updateField","fdef","v","confirmDelete","clearSelection","setColumnFilter","param","clearColumnFilters","useApi","options","immediate","filters","setFilter","clearFilters"],"mappings":"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"}
@@ -0,0 +1,395 @@
1
+ import { inject as K, ref as m, reactive as I, computed as $ } from "vue";
2
+ import { W as le, a as re } from "./plugin-BKa0eSEM.js";
3
+ import { DEFAULT_CRUD_LABELS as Ve } from "./types.js";
4
+ import { b as Ce, a as Ee, e as X, t as ie, g as ne, p as se, s as Ae } from "./useFormKeyboardNav-D4Irq5RE.js";
5
+ function Ie(F, w) {
6
+ const g = {};
7
+ for (const p of Object.keys(w))
8
+ JSON.stringify(F[p]) !== JSON.stringify(w[p]) && (g[p] = w[p]);
9
+ return g;
10
+ }
11
+ function qe(F) {
12
+ const {
13
+ endpoint: w,
14
+ form: g,
15
+ pk: p = "id",
16
+ searchDebounce: N = 300,
17
+ partialUpdate: Y = !0,
18
+ refetchOnSave: x = !0,
19
+ filterParams: R = void 0,
20
+ createDefaults: j = void 0,
21
+ transformPayload: T = void 0,
22
+ onAfterSave: _ = void 0,
23
+ onAfterDelete: M = void 0
24
+ } = F, V = K(le);
25
+ if (!V)
26
+ throw new Error(
27
+ "[wPrimeVueComponents] dataProvider não encontrado. Registre o WPrimeVuePlugin antes de usar useCrudManager."
28
+ );
29
+ const i = V, P = K(re), U = F.pageSize ?? (P == null ? void 0 : P.defaultPageSize) ?? 20, f = { ...Ve, ...F.labels }, b = Ce(), { confirmDelete: B } = Ee(), h = m([]), W = m([]), J = m({}), q = m(!1), c = m(!1), v = m(""), d = m(!1), z = m(!1), u = m(null), S = I({});
30
+ let C = null;
31
+ const n = I({
32
+ page: 1,
33
+ pageSize: U,
34
+ rows: 0,
35
+ totalPages: 0
36
+ }), y = I({
37
+ field: null,
38
+ order: 0
39
+ }), E = I({});
40
+ function Z() {
41
+ const e = {};
42
+ for (const t of g)
43
+ e[t.field] = t.defaultValue !== void 0 ? typeof t.defaultValue == "function" ? t.defaultValue() : t.defaultValue : null;
44
+ return e;
45
+ }
46
+ const ee = Z();
47
+ for (const e of Object.keys(ee))
48
+ S[e] = ee[e];
49
+ const A = $(() => u.value !== null && !z.value), fe = $(() => z.value), ce = $(
50
+ () => z.value ? f.viewTitle ?? "Visualizar Registro" : A.value ? f.editTitle : f.createTitle
51
+ ), ue = $(() => n.page <= 1), de = $(() => n.page >= n.totalPages);
52
+ let G = null;
53
+ async function O(e = {}) {
54
+ q.value = !0;
55
+ try {
56
+ const t = {
57
+ page: n.page,
58
+ page_size: n.pageSize,
59
+ ...e
60
+ };
61
+ v.value && (t.search = v.value), y.field && y.order !== 0 && (t.ordering = y.order === -1 ? `-${y.field}` : y.field), R && Object.assign(t, R());
62
+ for (const [o, r] of Object.entries(E))
63
+ r != null && r !== "" && (t[o] = r);
64
+ const a = await i.list(w, t);
65
+ h.value = a.data, W.value = [], n.rows = a.rows, J.value = a.extras ?? {}, a.page && (n.page = a.page), a.page_size && (n.pageSize = a.page_size), n.totalPages = Math.ceil(n.rows / n.pageSize) || 0;
66
+ } finally {
67
+ q.value = !1;
68
+ }
69
+ }
70
+ async function pe() {
71
+ await O();
72
+ }
73
+ async function ge() {
74
+ await O();
75
+ }
76
+ async function ve(e = 200) {
77
+ const t = {};
78
+ v.value && (t.search = v.value), y.field && y.order !== 0 && (t.ordering = y.order === -1 ? `-${y.field}` : y.field), R && Object.assign(t, R());
79
+ for (const [l, s] of Object.entries(E))
80
+ s != null && s !== "" && (t[l] = s);
81
+ const a = [];
82
+ let o = 1;
83
+ const r = 1e4;
84
+ for (; o <= r; ) {
85
+ const l = await i.list(w, {
86
+ ...t,
87
+ page: o,
88
+ page_size: e
89
+ });
90
+ a.push(...l.data);
91
+ const s = l.rows ?? a.length;
92
+ if (l.data.length === 0 || a.length >= s) break;
93
+ o++;
94
+ }
95
+ return a;
96
+ }
97
+ function te(e) {
98
+ v.value = e, G && clearTimeout(G), G = setTimeout(() => {
99
+ n.page = 1, O();
100
+ }, N);
101
+ }
102
+ function ye(e) {
103
+ const t = e.target;
104
+ te(t.value);
105
+ }
106
+ function H(e) {
107
+ n.page = e, O();
108
+ }
109
+ function me() {
110
+ H(1);
111
+ }
112
+ function we() {
113
+ H(n.totalPages);
114
+ }
115
+ function Pe(e) {
116
+ n.page = e.page + 1, n.pageSize = e.rows, O();
117
+ }
118
+ function he(e) {
119
+ y.field = e.sortField ?? null, y.order = e.sortOrder ?? 0, n.page = 1, O();
120
+ }
121
+ function Q() {
122
+ const e = Z();
123
+ for (const t of Object.keys(e))
124
+ S[t] = e[t];
125
+ }
126
+ function Se(e, t) {
127
+ S[e] = t;
128
+ }
129
+ function De() {
130
+ if (z.value = !1, u.value = null, C = null, Q(), j) {
131
+ const e = j();
132
+ for (const [t, a] of Object.entries(e))
133
+ S[t] = a;
134
+ }
135
+ d.value = !0;
136
+ }
137
+ function ae(e) {
138
+ const t = {};
139
+ for (const a of g) {
140
+ let o = e[a.field] !== void 0 ? e[a.field] : null;
141
+ o && (a.type === "date" || a.type === "datetime") && typeof o == "string" && (o = se(o)), S[a.field] = o, t[a.field] = o;
142
+ }
143
+ C = t;
144
+ }
145
+ function be(e) {
146
+ z.value = !1, u.value = e, ae(e), d.value = !0;
147
+ }
148
+ function ke(e) {
149
+ z.value = !0, u.value = e, ae(e), d.value = !0;
150
+ }
151
+ function ze(e) {
152
+ z.value = !1, u.value = null, C = null, Q();
153
+ for (const t of g) {
154
+ if (t.field === p) continue;
155
+ let a = e[t.field] !== void 0 ? e[t.field] : S[t.field];
156
+ a && (t.type === "date" || t.type === "datetime") && typeof a == "string" && (a = se(a)), S[t.field] = a;
157
+ }
158
+ if (j) {
159
+ const t = j();
160
+ for (const [a, o] of Object.entries(t))
161
+ S[a] = o;
162
+ }
163
+ d.value = !0;
164
+ }
165
+ function oe(e) {
166
+ const t = { ...e };
167
+ for (const a of g) {
168
+ const o = t[a.field];
169
+ if (a.type === "date" && o instanceof Date ? t[a.field] = ie(o) : a.type === "datetime" && o instanceof Date && (t[a.field] = ne(o)), a.type === "fk" && o !== null && typeof o == "object") {
170
+ const r = a.optionValue || "id";
171
+ t[a.field] = o[r] ?? o;
172
+ }
173
+ (a.type === "mask" || a.type === "cpf_cnpj") && typeof o == "string" && (t[a.field] = Ae(o));
174
+ }
175
+ return t;
176
+ }
177
+ async function Oe() {
178
+ for (const e of g) {
179
+ if (e.validate) {
180
+ const t = e.validate(S[e.field]);
181
+ if (t)
182
+ return b.error(t), null;
183
+ }
184
+ if (e.required) {
185
+ const t = S[e.field];
186
+ if (t == null || t === "")
187
+ return b.error(`${e.label} é obrigatório`), null;
188
+ }
189
+ }
190
+ c.value = !0;
191
+ try {
192
+ let e = oe(S);
193
+ if (!A.value && j && Object.assign(e, j()), A.value && Y && C) {
194
+ const s = oe(C);
195
+ if (e = Ie(s, e), Object.keys(e).length === 0 && !T) {
196
+ d.value = !1;
197
+ const D = u.value;
198
+ return u.value = null, C = null, D;
199
+ }
200
+ }
201
+ T && (e = T(e, A.value));
202
+ const t = g.some((s) => s.type === "image" && e[s.field] instanceof File);
203
+ let a = e, o;
204
+ if (t) {
205
+ const s = new Set(
206
+ g.filter((k) => k.type === "image").map((k) => k.field)
207
+ ), D = new FormData();
208
+ for (const [k, L] of Object.entries(e))
209
+ if (L != null)
210
+ if (L instanceof File)
211
+ D.append(k, L);
212
+ else {
213
+ if (s.has(k))
214
+ continue;
215
+ D.append(k, String(L));
216
+ }
217
+ a = D, o = { "Content-Type": "multipart/form-data" };
218
+ }
219
+ const r = o ? { headers: o } : void 0;
220
+ let l;
221
+ if (A.value && u.value) {
222
+ const s = u.value[p];
223
+ if (l = await i.update(
224
+ w,
225
+ s,
226
+ a,
227
+ r
228
+ ), !x) {
229
+ const D = h.value.findIndex((k) => k[p] === s);
230
+ D !== -1 && (h.value[D] = l.data);
231
+ }
232
+ b.success(f.successUpdate);
233
+ } else
234
+ l = await i.create(w, a, r), x || (h.value.unshift(l.data), n.rows++), b.success(f.successCreate);
235
+ return d.value = !1, u.value = null, C = null, x && await O(), _ && _(l.data, A.value), l.data;
236
+ } catch (e) {
237
+ return b.error(X(e, "Erro ao salvar registro")), null;
238
+ } finally {
239
+ c.value = !1;
240
+ }
241
+ }
242
+ async function Fe(e, t, a) {
243
+ const o = e[p], r = g.find((s) => s.field === t);
244
+ let l = a;
245
+ (r == null ? void 0 : r.type) === "date" && l instanceof Date ? l = ie(l) : (r == null ? void 0 : r.type) === "datetime" && l instanceof Date && (l = ne(l));
246
+ try {
247
+ const s = await i.update(w, o, { [t]: l }), D = h.value.findIndex((k) => k[p] === o);
248
+ D !== -1 && (h.value[D] = { ...h.value[D], ...s.data }), b.success(f.successUpdate);
249
+ } catch (s) {
250
+ b.error(X(s, "Erro ao salvar o campo"));
251
+ }
252
+ }
253
+ function je(e) {
254
+ B(async () => {
255
+ try {
256
+ const t = e[p];
257
+ await i.delete(w, t);
258
+ const a = h.value.findIndex((o) => o[p] === t);
259
+ a !== -1 && (h.value.splice(a, 1), n.rows--), b.success(f.successDelete), M && M(e);
260
+ } catch (t) {
261
+ b.error(X(t, "Erro ao excluir registro"));
262
+ }
263
+ }, f.deleteConfirmMessage);
264
+ }
265
+ function xe() {
266
+ W.value = [];
267
+ }
268
+ function Te(e, t) {
269
+ t == null || t === "" ? delete E[e] : E[e] = t, n.page = 1, O();
270
+ }
271
+ function _e() {
272
+ for (const e of Object.keys(E)) delete E[e];
273
+ n.page = 1, O();
274
+ }
275
+ return {
276
+ items: h,
277
+ selectedItems: W,
278
+ columnFilters: E,
279
+ extras: J,
280
+ loading: q,
281
+ saving: c,
282
+ search: v,
283
+ dialogVisible: d,
284
+ editingItem: u,
285
+ formData: S,
286
+ pagination: n,
287
+ sort: y,
288
+ isEditing: A,
289
+ isViewing: fe,
290
+ viewMode: z,
291
+ dialogTitle: ce,
292
+ isFirstPage: ue,
293
+ isLastPage: de,
294
+ init: pe,
295
+ fetchItems: O,
296
+ fetchAll: ve,
297
+ refresh: ge,
298
+ setSearch: te,
299
+ onSearch: ye,
300
+ onPage: Pe,
301
+ onSort: he,
302
+ openCreateDialog: De,
303
+ openEditDialog: be,
304
+ openViewDialog: ke,
305
+ openDuplicateDialog: ze,
306
+ save: Oe,
307
+ updateField: Fe,
308
+ confirmDelete: je,
309
+ setFormField: Se,
310
+ resetForm: Q,
311
+ goToPage: H,
312
+ firstPage: me,
313
+ lastPage: we,
314
+ clearSelection: xe,
315
+ setColumnFilter: Te,
316
+ clearColumnFilters: _e,
317
+ config: F
318
+ };
319
+ }
320
+ function Le(F) {
321
+ const { endpoint: w, searchDebounce: g = 300, immediate: p = !1 } = F, N = K(le);
322
+ if (!N)
323
+ throw new Error(
324
+ "[wPrimeVueComponents] dataProvider não encontrado. Registre o WPrimeVuePlugin antes de usar useApi."
325
+ );
326
+ const Y = N, x = K(re), R = F.pageSize ?? (x == null ? void 0 : x.defaultPageSize) ?? 20, j = m([]), T = m(!1), _ = m(""), M = m({}), V = I({}), i = I({
327
+ page: 1,
328
+ pageSize: R,
329
+ rows: 0,
330
+ totalPages: 0
331
+ }), P = I({
332
+ field: null,
333
+ order: 0
334
+ });
335
+ let U = null;
336
+ async function f(c = {}) {
337
+ T.value = !0;
338
+ try {
339
+ const v = {
340
+ page: i.page,
341
+ page_size: i.pageSize,
342
+ ...c
343
+ };
344
+ _.value && (v.search = _.value), P.field && P.order !== 0 && (v.ordering = P.order === -1 ? `-${P.field}` : P.field);
345
+ for (const [z, u] of Object.entries(V))
346
+ u != null && u !== "" && (v[z] = u);
347
+ const d = await Y.list(w, v);
348
+ j.value = d.data, i.rows = d.rows, d.page && (i.page = d.page), d.page_size && (i.pageSize = d.page_size), i.totalPages = Math.ceil(i.rows / i.pageSize) || 0, M.value = d.extras ?? {};
349
+ } finally {
350
+ T.value = !1;
351
+ }
352
+ }
353
+ async function b() {
354
+ await f();
355
+ }
356
+ function B(c) {
357
+ _.value = c, U && clearTimeout(U), U = setTimeout(() => {
358
+ i.page = 1, f();
359
+ }, g);
360
+ }
361
+ function h(c, v) {
362
+ V[c] = v, i.page = 1, f();
363
+ }
364
+ function W() {
365
+ for (const c of Object.keys(V))
366
+ delete V[c];
367
+ i.page = 1, f();
368
+ }
369
+ function J(c) {
370
+ i.page = c.page + 1, i.pageSize = c.rows, f();
371
+ }
372
+ function q(c) {
373
+ P.field = c.sortField ?? null, P.order = c.sortOrder ?? 0, i.page = 1, f();
374
+ }
375
+ return p && f(), {
376
+ items: j,
377
+ loading: T,
378
+ search: _,
379
+ pagination: i,
380
+ sort: P,
381
+ extras: M,
382
+ fetchItems: f,
383
+ refresh: b,
384
+ setSearch: B,
385
+ setFilter: h,
386
+ clearFilters: W,
387
+ onPage: J,
388
+ onSort: q
389
+ };
390
+ }
391
+ export {
392
+ qe as a,
393
+ Le as u
394
+ };
395
+ //# sourceMappingURL=useApi-CzOJADZw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useApi-CzOJADZw.js","sources":["../src/composables/useCrudManager.ts","../src/composables/useApi.ts"],"sourcesContent":["import { ref, reactive, computed, inject } from 'vue'\nimport { W_CONFIG_KEY, W_DATA_PROVIDER_KEY } from '@/types/plugin'\nimport type { WPluginConfig } from '@/types/plugin'\nimport type { DataProvider } from '@/types/dataProvider'\nimport type { PaginationState, SortState } from '@/types/api'\nimport type { CrudManagerConfig, CrudManagerReturn } from '@/types/manager'\nimport type { CrudLabels } from '@/types/labels'\nimport { DEFAULT_CRUD_LABELS } from '@/types/labels'\nimport { useAppToast } from './useAppToast'\nimport { useAppConfirm } from './useAppConfirm'\nimport { extractApiError } from './useApiError'\nimport { parseDate, toDateString, toDateTimeString } from '@/utils/dates'\nimport { stripMask } from '@/utils/masks'\n\n/** Shallow diff: returns only the keys whose value changed between two records. */\nfunction diffRecord(\n original: Record<string, unknown>,\n current: Record<string, unknown>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const key of Object.keys(current)) {\n if (JSON.stringify(original[key]) !== JSON.stringify(current[key])) {\n out[key] = current[key]\n }\n }\n return out\n}\n\nexport function useCrudManager<T extends Record<string, unknown> = Record<string, unknown>>(\n config: CrudManagerConfig<T>,\n): CrudManagerReturn<T> {\n const {\n endpoint,\n form: formFields,\n pk = 'id',\n searchDebounce = 300,\n partialUpdate = true,\n refetchOnSave = true,\n filterParams = undefined,\n createDefaults = undefined,\n transformPayload = undefined,\n onAfterSave = undefined,\n onAfterDelete = undefined,\n } = config\n\n const dataProvider = inject<DataProvider>(W_DATA_PROVIDER_KEY)\n if (!dataProvider) {\n throw new Error(\n '[wPrimeVueComponents] dataProvider não encontrado. Registre o WPrimeVuePlugin antes de usar useCrudManager.',\n )\n }\n const provider = dataProvider\n\n const pluginConfig = inject<WPluginConfig>(W_CONFIG_KEY)\n const defaultPageSize = config.pageSize ?? pluginConfig?.defaultPageSize ?? 20\n\n const labels: CrudLabels = { ...DEFAULT_CRUD_LABELS, ...config.labels }\n const toast = useAppToast()\n const { confirmDelete: confirmDeleteDialog } = useAppConfirm()\n\n // ---------------------------------------------------------------------------\n // State\n // ---------------------------------------------------------------------------\n\n const items = ref<T[]>([]) as import('vue').Ref<T[]>\n const selectedItems = ref<T[]>([]) as import('vue').Ref<T[]>\n const extras = ref<Record<string, unknown>>({})\n const loading = ref(false)\n const saving = ref(false)\n const search = ref('')\n const dialogVisible = ref(false)\n const viewMode = ref(false)\n const editingItem = ref<T | null>(null) as import('vue').Ref<T | null>\n const formData = reactive<Record<string, unknown>>({})\n // Snapshot of the form values when an edit dialog opens — used for diff-based PATCH.\n let editingOriginal: Record<string, unknown> | null = null\n\n const pagination: PaginationState = reactive({\n page: 1,\n pageSize: defaultPageSize,\n rows: 0,\n totalPages: 0,\n })\n\n const sort: SortState = reactive({\n field: null,\n order: 0,\n })\n\n // Filtros de coluna ativos (param → valor). Persistem entre páginas/ordenação.\n const columnFilters = reactive<Record<string, unknown>>({})\n\n // ---------------------------------------------------------------------------\n // Defaults\n // ---------------------------------------------------------------------------\n\n function getDefaults(): Record<string, unknown> {\n const defaults: Record<string, unknown> = {}\n for (const f of formFields) {\n defaults[f.field] =\n f.defaultValue !== undefined\n ? typeof f.defaultValue === 'function'\n ? (f.defaultValue as () => unknown)()\n : f.defaultValue\n : null\n }\n return defaults\n }\n\n // Initialize\n const defaults = getDefaults()\n for (const key of Object.keys(defaults)) {\n formData[key] = defaults[key]\n }\n\n // ---------------------------------------------------------------------------\n // Computed\n // ---------------------------------------------------------------------------\n\n const isEditing = computed(() => editingItem.value !== null && !viewMode.value)\n const isViewing = computed(() => viewMode.value)\n const dialogTitle = computed(() =>\n viewMode.value\n ? (labels.viewTitle ?? 'Visualizar Registro')\n : isEditing.value\n ? labels.editTitle\n : labels.createTitle,\n )\n const isFirstPage = computed(() => pagination.page <= 1)\n const isLastPage = computed(() => pagination.page >= pagination.totalPages)\n\n // ---------------------------------------------------------------------------\n // Fetch\n // ---------------------------------------------------------------------------\n\n let searchTimeout: ReturnType<typeof setTimeout> | null = null\n\n async function fetchItems(params: Record<string, unknown> = {}): Promise<void> {\n loading.value = true\n try {\n const queryParams: Record<string, unknown> = {\n page: pagination.page,\n page_size: pagination.pageSize,\n ...params,\n }\n\n if (search.value) {\n queryParams.search = search.value\n }\n\n if (sort.field && sort.order !== 0) {\n queryParams.ordering = sort.order === -1 ? `-${sort.field}` : sort.field\n }\n\n if (filterParams) {\n Object.assign(queryParams, filterParams())\n }\n\n // Filtros de coluna ativos (ignora vazios).\n for (const [key, val] of Object.entries(columnFilters)) {\n if (val !== null && val !== undefined && val !== '') queryParams[key] = val\n }\n\n const responseData = await provider.list<T>(endpoint, queryParams)\n items.value = responseData.data\n selectedItems.value = [] // seleção anterior fica obsoleta ao recarregar\n pagination.rows = responseData.rows\n extras.value = responseData.extras ?? {}\n if (responseData.page) pagination.page = responseData.page\n if (responseData.page_size) pagination.pageSize = responseData.page_size\n pagination.totalPages = Math.ceil(pagination.rows / pagination.pageSize) || 0\n } finally {\n loading.value = false\n }\n }\n\n async function init(): Promise<void> {\n await fetchItems()\n }\n\n async function refresh(): Promise<void> {\n await fetchItems()\n }\n\n /**\n * Fetch every record across all pages (respeitando search, sort e\n * filterParams atuais) sem alterar o estado da lista. Útil para exportações.\n */\n async function fetchAll(pageSize = 200): Promise<T[]> {\n const base: Record<string, unknown> = {}\n if (search.value) base.search = search.value\n if (sort.field && sort.order !== 0) {\n base.ordering = sort.order === -1 ? `-${sort.field}` : sort.field\n }\n if (filterParams) Object.assign(base, filterParams())\n for (const [key, val] of Object.entries(columnFilters)) {\n if (val !== null && val !== undefined && val !== '') base[key] = val\n }\n\n const all: T[] = []\n let page = 1\n // Hard cap para evitar loop infinito caso o backend não pagine corretamente.\n const maxPages = 10000\n while (page <= maxPages) {\n const res = await provider.list<T>(endpoint, {\n ...base,\n page,\n page_size: pageSize,\n })\n all.push(...res.data)\n const total = res.rows ?? all.length\n if (res.data.length === 0 || all.length >= total) break\n page++\n }\n return all\n }\n\n // ---------------------------------------------------------------------------\n // Search\n // ---------------------------------------------------------------------------\n\n function setSearch(value: string): void {\n search.value = value\n if (searchTimeout) clearTimeout(searchTimeout)\n searchTimeout = setTimeout(() => {\n pagination.page = 1\n fetchItems()\n }, searchDebounce)\n }\n\n function onSearch(event: Event): void {\n const target = event.target as HTMLInputElement\n setSearch(target.value)\n }\n\n // ---------------------------------------------------------------------------\n // Pagination\n // ---------------------------------------------------------------------------\n\n function goToPage(page: number): void {\n pagination.page = page\n fetchItems()\n }\n\n function firstPage(): void {\n goToPage(1)\n }\n\n function lastPage(): void {\n goToPage(pagination.totalPages)\n }\n\n function onPage(event: { page: number; rows: number }): void {\n pagination.page = event.page + 1\n pagination.pageSize = event.rows\n fetchItems()\n }\n\n function onSort(event: { sortField?: string | null; sortOrder?: 1 | -1 | 0 | null }): void {\n sort.field = event.sortField ?? null\n sort.order = event.sortOrder ?? 0\n pagination.page = 1\n fetchItems()\n }\n\n // ---------------------------------------------------------------------------\n // Form\n // ---------------------------------------------------------------------------\n\n function resetForm(): void {\n const defs = getDefaults()\n for (const key of Object.keys(defs)) {\n formData[key] = defs[key]\n }\n }\n\n function setFormField(field: string, value: unknown): void {\n formData[field] = value\n }\n\n function openCreateDialog(): void {\n viewMode.value = false\n editingItem.value = null\n editingOriginal = null\n resetForm()\n // Apply createDefaults (e.g. parent FK) on top of field defaults\n if (createDefaults) {\n const extra = createDefaults()\n for (const [key, val] of Object.entries(extra)) {\n formData[key] = val\n }\n }\n dialogVisible.value = true\n }\n\n function loadItemIntoForm(item: T): void {\n const snapshot: Record<string, unknown> = {}\n for (const f of formFields) {\n let value = item[f.field] !== undefined ? item[f.field] : null\n if (value && (f.type === 'date' || f.type === 'datetime') && typeof value === 'string') {\n value = parseDate(value)\n }\n formData[f.field] = value\n snapshot[f.field] = value\n }\n editingOriginal = snapshot\n }\n\n function openEditDialog(item: T): void {\n viewMode.value = false\n editingItem.value = item\n loadItemIntoForm(item)\n dialogVisible.value = true\n }\n\n function openViewDialog(item: T): void {\n viewMode.value = true\n editingItem.value = item\n loadItemIntoForm(item)\n dialogVisible.value = true\n }\n\n function openDuplicateDialog(item: T): void {\n // Abre o diálogo em modo criação, pré-preenchido com os dados do registro\n // (exceto a chave primária).\n viewMode.value = false\n editingItem.value = null\n editingOriginal = null\n resetForm()\n for (const f of formFields) {\n if (f.field === pk) continue\n let value = item[f.field] !== undefined ? item[f.field] : formData[f.field]\n if (value && (f.type === 'date' || f.type === 'datetime') && typeof value === 'string') {\n value = parseDate(value)\n }\n formData[f.field] = value\n }\n // createDefaults (ex: FK do pai) sobrepõe os valores duplicados.\n if (createDefaults) {\n const extra = createDefaults()\n for (const [key, val] of Object.entries(extra)) {\n formData[key] = val\n }\n }\n dialogVisible.value = true\n }\n\n // ---------------------------------------------------------------------------\n // Save\n // ---------------------------------------------------------------------------\n\n // Apply automatic conversions (dates, FK objects, masks) to a record,\n // returning a fresh plain object suitable for the API payload.\n function convertRecord(record: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = { ...record }\n for (const f of formFields) {\n const val = out[f.field]\n\n // Datas\n if (f.type === 'date' && val instanceof Date) {\n out[f.field] = toDateString(val)\n } else if (f.type === 'datetime' && val instanceof Date) {\n out[f.field] = toDateTimeString(val)\n }\n\n // FK — extrair o ID do objeto selecionado\n if (f.type === 'fk' && val !== null && typeof val === 'object') {\n const key = f.optionValue || 'id'\n out[f.field] = (val as Record<string, unknown>)[key] ?? val\n }\n\n // Máscaras — strip para enviar só dígitos\n if ((f.type === 'mask' || f.type === 'cpf_cnpj') && typeof val === 'string') {\n out[f.field] = stripMask(val)\n }\n }\n return out\n }\n\n async function save(): Promise<T | null> {\n // Validação\n for (const f of formFields) {\n if (f.validate) {\n const result = f.validate(formData[f.field])\n if (result) {\n toast.error(result)\n return null\n }\n }\n if (f.required) {\n const val = formData[f.field]\n if (val === null || val === undefined || val === '') {\n toast.error(`${f.label} é obrigatório`)\n return null\n }\n }\n }\n\n saving.value = true\n try {\n let payload: Record<string, unknown> = convertRecord(formData)\n\n // Merge createDefaults into payload for new records (hidden parent FKs, etc.)\n if (!isEditing.value && createDefaults) {\n Object.assign(payload, createDefaults())\n }\n\n // Edição: enviar apenas os campos alterados (diff) quando partialUpdate.\n if (isEditing.value && partialUpdate && editingOriginal) {\n const originalPayload = convertRecord(editingOriginal)\n payload = diffRecord(originalPayload, payload)\n\n // Nada mudou — fecha sem chamar a API.\n if (Object.keys(payload).length === 0 && !transformPayload) {\n dialogVisible.value = false\n const current = editingItem.value\n editingItem.value = null\n editingOriginal = null\n return current\n }\n }\n\n if (transformPayload) {\n payload = transformPayload(payload, isEditing.value)\n }\n\n // Detecta se tem arquivo (image) → FormData\n const hasFile = formFields.some((f) => f.type === 'image' && payload[f.field] instanceof File)\n\n let body: Record<string, unknown> | FormData = payload\n let headers: Record<string, string> | undefined\n\n if (hasFile) {\n const imageFields = new Set(\n formFields.filter((f) => f.type === 'image').map((f) => f.field),\n )\n const fd = new FormData()\n for (const [key, val] of Object.entries(payload)) {\n if (val === null || val === undefined) continue\n if (val instanceof File) {\n fd.append(key, val)\n } else if (imageFields.has(key)) {\n // URL string de imagem inalterada — pula\n continue\n } else {\n fd.append(key, String(val))\n }\n }\n body = fd\n headers = { 'Content-Type': 'multipart/form-data' }\n }\n\n const requestConfig = headers ? { headers } : undefined\n let response\n\n if (isEditing.value && editingItem.value) {\n const itemPk = editingItem.value[pk as keyof T]\n response = await provider.update<T>(\n endpoint,\n itemPk as string | number,\n body,\n requestConfig,\n )\n if (!refetchOnSave) {\n const index = items.value.findIndex((i) => i[pk as keyof T] === itemPk)\n if (index !== -1) {\n items.value[index] = response.data\n }\n }\n toast.success(labels.successUpdate)\n } else {\n response = await provider.create<T>(endpoint, body, requestConfig)\n if (!refetchOnSave) {\n items.value.unshift(response.data)\n pagination.rows++\n }\n toast.success(labels.successCreate)\n }\n\n dialogVisible.value = false\n editingItem.value = null\n editingOriginal = null\n\n // Re-busca a página atual para refletir o estado real do backend\n // (campos derivados, ordenação, etc.) sem perder a posição da paginação,\n // busca ou filtros — todos preservados em `pagination`/`search`/`sort`.\n if (refetchOnSave) {\n await fetchItems()\n }\n\n if (onAfterSave) onAfterSave(response.data, isEditing.value)\n return response.data\n } catch (err) {\n toast.error(extractApiError(err, 'Erro ao salvar registro'))\n return null\n } finally {\n saving.value = false\n }\n }\n\n // ---------------------------------------------------------------------------\n // Inline (cell) edit\n // ---------------------------------------------------------------------------\n\n async function updateField(item: T, field: string, value: unknown): Promise<void> {\n const itemPk = item[pk as keyof T]\n const fdef = formFields.find((f) => f.field === field)\n let v = value\n if (fdef?.type === 'date' && v instanceof Date) v = toDateString(v)\n else if (fdef?.type === 'datetime' && v instanceof Date) v = toDateTimeString(v)\n try {\n const response = await provider.update<T>(endpoint, itemPk as string | number, { [field]: v })\n const index = items.value.findIndex((i) => i[pk as keyof T] === itemPk)\n if (index !== -1) items.value[index] = { ...items.value[index], ...response.data }\n toast.success(labels.successUpdate)\n } catch (err) {\n toast.error(extractApiError(err, 'Erro ao salvar o campo'))\n }\n }\n\n // ---------------------------------------------------------------------------\n // Delete\n // ---------------------------------------------------------------------------\n\n function confirmDelete(item: T): void {\n confirmDeleteDialog(async () => {\n try {\n const itemPk = item[pk as keyof T]\n await provider.delete(endpoint, itemPk as string | number)\n const index = items.value.findIndex((i) => i[pk as keyof T] === itemPk)\n if (index !== -1) {\n items.value.splice(index, 1)\n pagination.rows--\n }\n toast.success(labels.successDelete)\n if (onAfterDelete) onAfterDelete(item)\n } catch (err) {\n toast.error(extractApiError(err, 'Erro ao excluir registro'))\n }\n }, labels.deleteConfirmMessage)\n }\n\n function clearSelection(): void {\n selectedItems.value = []\n }\n\n function setColumnFilter(param: string, value: unknown): void {\n if (value === null || value === undefined || value === '') {\n delete columnFilters[param]\n } else {\n columnFilters[param] = value\n }\n pagination.page = 1\n fetchItems()\n }\n\n function clearColumnFilters(): void {\n for (const key of Object.keys(columnFilters)) delete columnFilters[key]\n pagination.page = 1\n fetchItems()\n }\n\n // ---------------------------------------------------------------------------\n // Return\n // ---------------------------------------------------------------------------\n\n return {\n items,\n selectedItems,\n columnFilters,\n extras,\n loading,\n saving,\n search,\n dialogVisible,\n editingItem,\n formData,\n pagination,\n sort,\n isEditing,\n isViewing,\n viewMode,\n dialogTitle,\n isFirstPage,\n isLastPage,\n init,\n fetchItems,\n fetchAll,\n refresh,\n setSearch,\n onSearch,\n onPage,\n onSort,\n openCreateDialog,\n openEditDialog,\n openViewDialog,\n openDuplicateDialog,\n save,\n updateField,\n confirmDelete,\n setFormField,\n resetForm,\n goToPage,\n firstPage,\n lastPage,\n clearSelection,\n setColumnFilter,\n clearColumnFilters,\n config,\n }\n}\n","import { ref, reactive, inject } from 'vue'\nimport type { PaginationState, SortState, UseApiOptions, UseApiReturn } from '@/types/api'\nimport { W_CONFIG_KEY, W_DATA_PROVIDER_KEY } from '@/types/plugin'\nimport type { WPluginConfig } from '@/types/plugin'\nimport type { DataProvider } from '@/types/dataProvider'\n\nexport function useApi<T = Record<string, unknown>>(options: UseApiOptions): UseApiReturn<T> {\n const { endpoint, searchDebounce = 300, immediate = false } = options\n\n const dataProvider = inject<DataProvider>(W_DATA_PROVIDER_KEY)\n if (!dataProvider) {\n throw new Error(\n '[wPrimeVueComponents] dataProvider não encontrado. Registre o WPrimeVuePlugin antes de usar useApi.',\n )\n }\n const provider = dataProvider\n\n const config = inject<WPluginConfig>(W_CONFIG_KEY)\n const defaultPageSize = options.pageSize ?? config?.defaultPageSize ?? 20\n\n // State\n const items = ref<T[]>([]) as import('vue').Ref<T[]>\n const loading = ref(false)\n const search = ref('')\n const extras = ref<Record<string, unknown>>({})\n const filters = reactive<Record<string, unknown>>({})\n\n const pagination: PaginationState = reactive({\n page: 1,\n pageSize: defaultPageSize,\n rows: 0,\n totalPages: 0,\n })\n\n const sort: SortState = reactive({\n field: null,\n order: 0,\n })\n\n // Debounce\n let searchTimeout: ReturnType<typeof setTimeout> | null = null\n\n async function fetchItems(params: Record<string, unknown> = {}): Promise<void> {\n loading.value = true\n try {\n const queryParams: Record<string, unknown> = {\n page: pagination.page,\n page_size: pagination.pageSize,\n ...params,\n }\n\n if (search.value) {\n queryParams.search = search.value\n }\n\n if (sort.field && sort.order !== 0) {\n queryParams.ordering = sort.order === -1 ? `-${sort.field}` : sort.field\n }\n\n for (const [key, value] of Object.entries(filters)) {\n if (value !== null && value !== undefined && value !== '') {\n queryParams[key] = value\n }\n }\n\n const responseData = await provider.list<T>(endpoint, queryParams)\n\n items.value = responseData.data\n pagination.rows = responseData.rows\n if (responseData.page) pagination.page = responseData.page\n if (responseData.page_size) pagination.pageSize = responseData.page_size\n pagination.totalPages = Math.ceil(pagination.rows / pagination.pageSize) || 0\n extras.value = responseData.extras ?? {}\n } finally {\n loading.value = false\n }\n }\n\n async function refresh(): Promise<void> {\n await fetchItems()\n }\n\n function setSearch(value: string): void {\n search.value = value\n if (searchTimeout) clearTimeout(searchTimeout)\n searchTimeout = setTimeout(() => {\n pagination.page = 1\n fetchItems()\n }, searchDebounce)\n }\n\n function setFilter(key: string, value: unknown): void {\n filters[key] = value\n pagination.page = 1\n fetchItems()\n }\n\n function clearFilters(): void {\n for (const key of Object.keys(filters)) {\n delete filters[key]\n }\n pagination.page = 1\n fetchItems()\n }\n\n function onPage(event: { page: number; rows: number }): void {\n pagination.page = event.page + 1\n pagination.pageSize = event.rows\n fetchItems()\n }\n\n function onSort(event: { sortField: string; sortOrder: 1 | -1 | 0 }): void {\n sort.field = event.sortField ?? null\n sort.order = event.sortOrder ?? 0\n pagination.page = 1\n fetchItems()\n }\n\n if (immediate) {\n fetchItems()\n }\n\n return {\n items,\n loading,\n search,\n pagination,\n sort,\n extras,\n fetchItems,\n refresh,\n setSearch,\n setFilter,\n clearFilters,\n onPage,\n onSort,\n }\n}\n"],"names":["diffRecord","original","current","out","key","useCrudManager","config","endpoint","formFields","pk","searchDebounce","partialUpdate","refetchOnSave","filterParams","createDefaults","transformPayload","onAfterSave","onAfterDelete","dataProvider","inject","W_DATA_PROVIDER_KEY","provider","pluginConfig","W_CONFIG_KEY","defaultPageSize","labels","DEFAULT_CRUD_LABELS","toast","useAppToast","confirmDeleteDialog","useAppConfirm","items","ref","selectedItems","extras","loading","saving","search","dialogVisible","viewMode","editingItem","formData","reactive","editingOriginal","pagination","sort","columnFilters","getDefaults","defaults","f","isEditing","computed","isViewing","dialogTitle","isFirstPage","isLastPage","searchTimeout","fetchItems","params","queryParams","val","responseData","init","refresh","fetchAll","pageSize","base","all","page","maxPages","res","total","setSearch","value","onSearch","event","target","goToPage","firstPage","lastPage","onPage","onSort","resetForm","defs","setFormField","field","openCreateDialog","extra","loadItemIntoForm","item","snapshot","parseDate","openEditDialog","openViewDialog","openDuplicateDialog","convertRecord","record","toDateString","toDateTimeString","stripMask","save","result","payload","originalPayload","hasFile","body","headers","imageFields","fd","requestConfig","response","itemPk","index","i","err","extractApiError","updateField","fdef","v","confirmDelete","clearSelection","setColumnFilter","param","clearColumnFilters","useApi","options","immediate","filters","setFilter","clearFilters"],"mappings":"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"}