{"_id":"@aprendomx/sinpapel-vue","_rev":"3-d6fe63edf2c1576f72848fd343f48e36","name":"@aprendomx/sinpapel-vue","dist-tags":{"latest":"0.4.2"},"versions":{"0.4.0":{"name":"@aprendomx/sinpapel-vue","version":"0.4.0","license":"GPL-3.0","_id":"@aprendomx/sinpapel-vue@0.4.0","maintainers":[{"name":"aprendomx","email":"hola@aprendo.mx"}],"dist":{"shasum":"4d2f9b81f6fa0b97a7d6bd566e319e7a8b5af272","tarball":"https://registry.npmjs.org/@aprendomx/sinpapel-vue/-/sinpapel-vue-0.4.0.tgz","fileCount":8,"integrity":"sha512-hmjVO8nx1M43YsBjyO5Lf5M35kQqoWtq6mT7bGGnmo6h4MqdiuJF08l3BByEQ1PfK5Jq/zaDyC6o6Jz8Xv21hg==","signatures":[{"sig":"MEQCIHEKlxz8N9LftWpVhRjdGDgshK4glhV26l4ugiTUSow0AiBV6sH3Qo5nhVim7rJPN6yzxGBLniSS13tXuIry77W2nw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":139402},"main":"./dist/sinpapel-vue.umd.cjs","type":"module","module":"./dist/sinpapel-vue.js","exports":{".":{"types":"./types/index.d.ts","import":"./dist/sinpapel-vue.js","require":"./dist/sinpapel-vue.umd.cjs"},"./style.css":"./dist/sinpapel-vue.css"},"gitHead":"dac6ee0d647796b19edcf8f61b7344571878d8da","scripts":{"dev":"vite","lint":"eslint \"{src,demo,tests}/**/*.{js,vue}\"","test":"vitest run","build":"vite build","test:watch":"vitest","prepublishOnly":"npm run lint && npm test && npm run build"},"_npmUser":{"name":"aprendomx","email":"hola@aprendo.mx"},"_npmVersion":"11.12.1","description":"Vue 3 workflow-tracking widgets for the sinpapel-drf API","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.22","sass":"^1.101.0","vite":"^6.0.0","axios":"^1.7.0","jsdom":"^25.0.0","pinia":"^3.0.1","eslint":"^9.14.0","quasar":"^2.16.0","vitest":"^2.1.0","globals":"^16.4.0","@eslint/js":"^9.14.0","@quasar/extras":"^2.0.1","@vue/test-utils":"^2.4.6","eslint-plugin-vue":"^10.4.0","@vitejs/plugin-vue":"^5.2.0"},"peerDependencies":{"vue":"^3.5.0","pinia":"^3.0.0","quasar":"^2.16.0"},"_npmOperationalInternal":{"tmp":"tmp/sinpapel-vue_0.4.0_1787952477247_0.09870288226986679","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@aprendomx/sinpapel-vue","version":"0.4.1","license":"GPL-3.0","_id":"@aprendomx/sinpapel-vue@0.4.1","maintainers":[{"name":"aprendomx","email":"hola@aprendo.mx"}],"dist":{"shasum":"d0ebdfeb1efc5e223a6710c1733a8390e171394c","tarball":"https://registry.npmjs.org/@aprendomx/sinpapel-vue/-/sinpapel-vue-0.4.1.tgz","fileCount":8,"integrity":"sha512-AlbbrDfh1dkorI2HTKJXoiIyZTfZN6dTcfxU3IN0RNm9kwDpOigYNMSBid4/oGLh8W+tXVHy9lg7xr9vGT9AZQ==","signatures":[{"sig":"MEYCIQDXEJQL8nilRcPc7AfJlgzxxeJfsFcag08VBwG4ycS4pQIhANlsmxBTokw85ExuwzCus6tl0LraOiTZQqcfUbjTOS96","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":173537},"main":"./dist/sinpapel-vue.umd.cjs","type":"module","module":"./dist/sinpapel-vue.js","exports":{".":{"types":"./types/index.d.ts","import":"./dist/sinpapel-vue.js","require":"./dist/sinpapel-vue.umd.cjs"},"./style.css":"./dist/sinpapel-vue.css"},"scripts":{"dev":"vite","lint":"eslint \"{src,demo,tests}/**/*.{js,vue}\"","test":"vitest run","build":"vite build","test:watch":"vitest","prepublishOnly":"npm run lint && npm test && npm run build"},"_npmUser":{"name":"aprendomx","email":"hola@aprendo.mx"},"_npmVersion":"11.12.1","description":"Vue 3 workflow-tracking widgets for the sinpapel-drf API","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.22","sass":"^1.101.0","vite":"^6.0.0","axios":"^1.7.0","jsdom":"^25.0.0","pinia":"^3.0.1","eslint":"^9.14.0","quasar":"^2.16.0","vitest":"^2.1.0","globals":"^16.4.0","@eslint/js":"^9.14.0","@quasar/extras":"^2.0.1","@vue/test-utils":"^2.4.6","eslint-plugin-vue":"^10.4.0","@vitejs/plugin-vue":"^5.2.0"},"peerDependencies":{"vue":"^3.5.0","pinia":"^3.0.0","quasar":"^2.16.0"},"_npmOperationalInternal":{"tmp":"tmp/sinpapel-vue_0.4.1_1788153063798_0.7707763054470869","host":"s3://npm-registry-packages-npm-production"}},"0.4.2":{"name":"@aprendomx/sinpapel-vue","version":"0.4.2","description":"Vue 3 workflow-tracking widgets for the sinpapel-drf API","keywords":["sinpapel","workflow","vue3","quasar","pinia","django","drf","audit-trail","electronic-signature","fiel"],"homepage":"https://github.com/aprendomx/sinpapel-vue#readme","repository":{"type":"git","url":"git+https://github.com/aprendomx/sinpapel-vue.git"},"bugs":{"url":"https://github.com/aprendomx/sinpapel-vue/issues"},"author":{"name":"AprendoMX"},"license":"GPL-3.0-or-later","type":"module","main":"./dist/sinpapel-vue.umd.cjs","module":"./dist/sinpapel-vue.js","exports":{".":{"types":"./types/index.d.ts","import":"./dist/sinpapel-vue.js","require":"./dist/sinpapel-vue.umd.cjs"},"./style.css":"./dist/sinpapel-vue.css"},"scripts":{"dev":"vite","build":"vite build","test":"vitest run","test:watch":"vitest","lint":"eslint \"{src,demo,tests}/**/*.{js,vue}\"","prepublishOnly":"npm run lint && npm test && npm run build"},"peerDependencies":{"pinia":"^3.0.0","quasar":"^2.16.0","vue":"^3.5.0"},"devDependencies":{"@eslint/js":"^9.14.0","@quasar/extras":"^2.0.1","@vitejs/plugin-vue":"^5.2.0","@vue/test-utils":"^2.4.6","axios":"^1.7.0","eslint":"^9.14.0","eslint-plugin-vue":"^10.4.0","globals":"^16.4.0","jsdom":"^25.0.0","pinia":"^3.0.1","quasar":"^2.16.0","sass":"^1.101.0","vite":"^6.0.0","vitest":"^2.1.0","vue":"^3.5.22"},"gitHead":"3f36f5d4dd0f6b7558fa7c98db3cc16c83705a01","_id":"@aprendomx/sinpapel-vue@0.4.2","_nodeVersion":"25.9.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-cHBIN7DeIgp/fUbIakWWBz2bFmYqhwLhMdmDOix1ikB3uKhjk4AbTkneZxjJEIcR0lWULmZNgxJOn53UVqoA3w==","shasum":"2c82811d56553fe954c7b6733b15a2c9231df38e","tarball":"https://registry.npmjs.org/@aprendomx/sinpapel-vue/-/sinpapel-vue-0.4.2.tgz","fileCount":9,"unpackedSize":197686,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDFB70/pwqGhVSJR97hgBQ+PV+x53ItsbUXfEe2PMW4wgIgJjmlmbkohgRFSk9EIh3RXY3yMDTk1Phg11u9ojGGOQ4="}]},"_npmUser":{"name":"aprendomx","email":"hola@aprendo.mx"},"directories":{},"maintainers":[{"name":"aprendomx","email":"hola@aprendo.mx"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sinpapel-vue_0.4.2_1788155097808_0.14968354438153364"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-28T21:27:57.038Z","modified":"2026-08-31T05:44:58.128Z","0.4.0":"2026-08-28T21:27:57.380Z","0.4.1":"2026-08-31T05:11:03.925Z","0.4.2":"2026-08-31T05:44:57.981Z"},"license":"GPL-3.0-or-later","description":"Vue 3 workflow-tracking widgets for the sinpapel-drf API","maintainers":[{"name":"aprendomx","email":"hola@aprendo.mx"}],"readme":"# @aprendomx/sinpapel-vue\n\n> **v0.4.1** — Vue 3 UI layer for [sinpapel](https://github.com/aprendomx/sinpapel).\n>\n> Workflow-tracking widgets on top of the [sinpapel-drf](https://github.com/aprendomx/sinpapel-drf) REST API: audit history, document requirements + uploads, structured metadata, transition preview, SLA status, and polymorphic electronic signature — **without hand-writing a single request, store, or form**.\n>\n> [🇪🇸 Leer en Español](https://github.com/aprendomx/sinpapel-vue/blob/main/README.es.md)\n\n[![npm](https://img.shields.io/npm/v/@aprendomx/sinpapel-vue.svg)](https://www.npmjs.com/package/@aprendomx/sinpapel-vue)\n[![Vue](https://img.shields.io/badge/vue-3.5%2B-42b883)](https://vuejs.org/)\n[![Quasar](https://img.shields.io/badge/quasar-2.16%2B-1976d2)](https://quasar.dev/)\n[![Node](https://img.shields.io/badge/node-20%20%7C%2022-339933)](https://nodejs.org/)\n[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://github.com/aprendomx/sinpapel-vue/blob/main/LICENSE)\n[![Tests](https://img.shields.io/badge/tests-77%20passing-brightgreen)](#11-development--testing)\n\n---\n\n## Table of Contents\n\n1. [What is sinpapel-vue?](#1-what-is-sinpapel-vue)\n2. [Installation](#2-installation)\n3. [Quick start](#3-quick-start)\n4. [Components](#4-components)\n5. [Client API](#5-client-api)\n6. [Store & composables](#6-store--composables)\n7. [Internationalization (i18n)](#7-internationalization-i18n)\n8. [Theming](#8-theming)\n9. [TypeScript](#9-typescript)\n10. [Compatibility](#10-compatibility)\n11. [Development & testing](#11-development--testing)\n12. [Known limitations & Roadmap](#12-known-limitations--roadmap)\n13. [Versioning & Stability](#13-versioning--stability)\n14. [Documentation & agent skills](#14-documentation--agent-skills)\n15. [License & Contributing](#15-license--contributing)\n\n---\n\n## 1. What is sinpapel-vue?\n\n`@aprendomx/sinpapel-vue` is the **front-end layer** of the sinpapel ecosystem. Where `sinpapel-drf` auto-publishes REST endpoints for every `@workflow_enabled` Django model, this library auto-renders the UI that drives them: one `<SeguimientoPanel>` gives an end user the full case-tracking experience.\n\n### Where it fits\n\n| Package | Runtime | Role |\n|---|---|---|\n| [sinpapel](https://github.com/aprendomx/sinpapel) | Django | Engine — versioned state machines, immutable audit, signing backends, predicates, SLA, metadata |\n| [sinpapel-drf](https://github.com/aprendomx/sinpapel-drf) | Django + DRF | HTTP layer — the API **this package consumes** |\n| [sinpapel-webhooks](https://github.com/aprendomx/sinpapel-webhooks) | Django | Event-driven outbound/inbound HTTP communication |\n| [sinpapel-reports](https://github.com/aprendomx/sinpapel-reports) | Django | Template-driven document generation (PDF overlay + DOCX) |\n| **@aprendomx/sinpapel-vue** | **Vue 3** | **Runtime UI — case tracking for end users (this package)** |\n| [sinpapel-designer](https://github.com/aprendomx/sinpapel-designer) | Vue 3 SPA | Design-time UI — visual flow editor, schema v0.2 import/export |\n\nRule of thumb: **`sinpapel-designer` models the flow, `sinpapel-vue` runs it.** The designer is a standalone SPA for authoring flows; this package is an embeddable component library for the people who move cases through those flows.\n\n### Endpoint coverage\n\nEvery `sinpapel-drf` instance endpoint has a client method and a component behind it:\n\n| `sinpapel-drf` endpoint | Verb | Client method | Component |\n|---|---|---|---|\n| `available-transitions/` | GET | `availableTransitions()` | `TransitionDialog` (target selector) |\n| `transition/` | POST | `transition(payload)` | `TransitionDialog` |\n| `history/` | GET | `history({page, pageSize})` | `HistoryTimeline` |\n| `preview-transition/` | POST | `previewTransition(targetState)` | `PreviewTransitionPanel` |\n| `metadatos/` | GET / PATCH | `getMetadatos()` / `patchMetadatos(values)` | `MetadatosForm` |\n| `sla-status/` | POST | `slaStatus()` | `SlaStatusPanel` |\n| `requisitos/` | GET | `requisitos()` | `RequisitosPanel`, `DocumentosPanel` |\n| `documentos/` | GET / POST | `listDocumentos()` / `uploadDocumento(payload)` | `DocumentosPanel` |\n| `documentos/<id>/` | DELETE | `deleteDocumento(id)` | `DocumentosPanel` |\n\n### Design pillars\n\n- **Zero boilerplate in the consumer.** No stores, no serializers, no fetch code. Mount one component with a resource slug and a pk.\n- **Bring your own transport.** You inject a configured `axios` instance (auth, CSRF, `baseURL`, interceptors). The library ships **no HTTP dependency** of its own.\n- **Polymorphic signature UI.** `TransitionDialog` mirrors the backend's `SignatureRequestSerializer` dispatch: FIEL client-side (recommended), FIEL server-side (gated), manual, or fake.\n- **Backend drives enforcement.** Whether a transition requires a signature comes from `preview-transition`'s `firma_requerida`, not from client-side config.\n- **Graceful degradation.** Features that need a newer `sinpapel-drf` detect their absence and fall back (e.g. without `firma_requerida` the signature stays optional).\n- **Headless-friendly.** The client, the Pinia store and the composables are exported, so you can keep the logic and render your own UI.\n\n---\n\n## 2. Installation\n\n```bash\nnpm install @aprendomx/sinpapel-vue\n# required peer dependencies:\nnpm install vue pinia quasar\n```\n\n> **Note:** Quasar is a **hard peer dependency**. Widgets reuse `q-*` components (e.g., `q-dialog`, `q-icon`).\n\n`axios` is *not* a dependency: you pass your own instance (see below).\n\n---\n\n## 3. Quick start\n\n```vue\n<script setup>\nimport axios from 'axios'\nimport { SeguimientoPanel } from '@aprendomx/sinpapel-vue'\nimport '@aprendomx/sinpapel-vue/style.css'\n\nconst http = axios.create({ withCredentials: true })\n</script>\n\n<template>\n  <SeguimientoPanel\n    :axios=\"http\"\n    base-path=\"/sinpapel/api\"\n    resource=\"solicitudes\"\n    :pk=\"42\"\n    current-state=\"EN_REVISION\"\n  />\n</template>\n```\n\n`base-path` must match where you mounted the `SinpapelRouter` in `urls.py`. The `resource` prop must be the `effective_slug` of the model decorated with `@workflow_enabled` (i.e. `endpoint_slug` if declared, otherwise `workflow_key` + `\"s\"`). There is no auto-discovery.\n\n> **Important:** `SeguimientoPanel` creates its store from the initial props. If `pk` or `resource` change dynamically, pass `:key=\"pk\"` to force a remount.\n\n---\n\n## 4. Components\n\n### SeguimientoPanel\n\nMain composed widget. Renders the current state badge, the tab bar (History / Requirements / Documents / Preview / Metadata / SLA) and the transition dialog.\n\n**Props:**\n\n| Prop | Type | Required | Default | Description |\n|------|------|----------|---------|-------------|\n| `axios` | `Object` | Yes | — | Axios instance (auth, baseURL, interceptors) |\n| `basePath` | `string` | No | `/sinpapel/api` | Base path where the API is mounted |\n| `resource` | `string` | Yes | — | Resource slug (effective_slug) |\n| `pk` | `number \\| string` | Yes | — | Instance ID |\n| `currentState` | `string` | No | `''` | Current state to show in the badge |\n| `canEvaluateSla` | `boolean` | No | `false` | Show the SLA tab |\n| `locale` | `string` | No | `'es'` | Language (`es` or `en`) |\n\n**Emits:** none (everything handled internally via the store).\n\n### StateBadge\n\nState pill with a color dot.\n\n**Props:**\n\n| Prop | Type | Required | Default |\n|------|------|----------|---------|\n| `estado` | `string` | Yes | — |\n| `color` | `string` | No | `''` |\n| `label` | `string` | No | `''` |\n\nThe default label humanizes the state name (`EN_REVISION` → `EN REVISION`). If `color` is passed, `color-mix` is used for the background.\n\n### HistoryTimeline\n\nVertical timeline over history entries.\n\n**Props:**\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `entries` | `Array` | `[]` | History rows |\n| `page` | `number` | `1` | Current page |\n| `pageSize` | `number` | `0` | Page size (0 = no pagination) |\n| `count` | `number` | `0` | Total records |\n\n**Emits:** `prev`, `next`.\n\n### TransitionDialog\n\nModal dialog to execute a state transition. Includes target state selector, comments, conditions and polymorphic signature (FIEL client-side/server-side, manual, fake).\n\n**Props:**\n\n| Prop | Type | Required | Default |\n|------|------|----------|---------|\n| `modelValue` | `boolean` | No | `false` |\n| `client` | `Object` | Yes | — |\n| `currentState` | `string` | No | `''` |\n| `estados` | `Array` | No | `[]` |\n\n**Emits:** `update:modelValue`, `transitioned(result)`.\n\n**Validation:**\n- Target state is required\n- A signature backend is required when the backend reports `firma_requerida` for the chosen target (the \"no signature\" option is disabled and the fieldset is marked as required)\n- `.cer`, `.key` files and password required for FIEL server-side\n\n### PreviewTransitionPanel\n\nRead-only panel that previews the impact of a transition before executing it: blocking reasons, missing documents, failed predicates, and a **\"requires signature\"** indicator when the report carries `firma_requerida`.\n\n**Props:**\n\n| Prop | Type | Required | Default |\n|------|------|----------|---------|\n| `client` | `Object` | Yes | — |\n| `targetState` | `string` | No | `''` |\n\nDebounced by 300ms on `targetState` changes.\n\n### MetadatosForm\n\nForm generated from the backend metadata schema (`SCHEMA_METADATOS` exposed by `GET .../metadatos/`).\n\n**Props:**\n\n| Prop | Type | Required |\n|------|------|----------|\n| `client` | `Object` | Yes |\n\n**Emits:** `saved(values)`.\n\n### SlaStatusPanel\n\nPanel to evaluate SLA status (admin only — the endpoint is permission-gated server-side).\n\n**Props:**\n\n| Prop | Type | Required |\n|------|------|----------|\n| `client` | `Object` | Yes |\n\n### RequisitosPanel\n\nRead-only checklist of documentary requirements for the current state\n(`RequisitoEstadoDocumento` fulfillment). Consumes `GET …/requisitos/`.\n\n**Props:**\n\n| Prop | Type | Required |\n|------|------|----------|\n| `client` | `Object` | Yes |\n\n### DocumentosPanel\n\nLists, uploads (multipart) and deletes documents for the case. Consumes\n`GET/POST …/documentos/`, `DELETE …/documentos/{id}/` and `GET …/requisitos/`.\nThe upload form uses **selects**: the **document type** comes from the current\nstate's requirements and the **document** is a dependent select of the type\n(e.g. \"Identificación\" → \"Pasaporte\" / \"INE\"). No percentage is asked — it is\nset by the requirement config (`RequisitoEstadoDocumento.porcentaje`).\nRequires `sinpapel-drf >= 0.4.0`.\n\n**Props:**\n\n| Prop | Type | Required |\n|------|------|----------|\n| `client` | `Object` | Yes |\n\n**Emits:** `changed` (after upload or delete).\n\n---\n\n## 5. Client API\n\n```js\nimport { createSinpapelClient } from '@aprendomx/sinpapel-vue'\n\nconst client = createSinpapelClient({\n  axios: myAxiosInstance,     // required\n  basePath: '/sinpapel/api',  // default\n  resource: 'solicitudes',    // required\n  pk: 42,                     // can be changed later via client.pk = ...\n})\n```\n\n**Methods:**\n\n| Method | HTTP | Path | Returns |\n|--------|------|------|---------|\n| `availableTransitions()` | GET | `/{resource}/{pk}/available-transitions/` | `Estado[]` |\n| `history({page, pageSize})` | GET | `/{resource}/{pk}/history/` | `HistoryResponse \\| HistoryEntry[]` |\n| `previewTransition(targetState)` | POST | `/{resource}/{pk}/preview-transition/` | `PreviewReport` |\n| `getMetadatos()` | GET | `/{resource}/{pk}/metadatos/` | `{schema, values}` |\n| `patchMetadatos(values)` | PATCH | `/{resource}/{pk}/metadatos/` | updated `values` |\n| `slaStatus()` | POST | `/{resource}/{pk}/sla-status/` | `SlaAction[]` |\n| `transition(payload)` | POST | `/{resource}/{pk}/transition/` | `TransitionResult` |\n| `requisitos()` | GET | `/{resource}/{pk}/requisitos/` | `RequisitoStatus[]` |\n| `listDocumentos()` | GET | `/{resource}/{pk}/documentos/` | `InstanciaDocumento[]` |\n| `uploadDocumento(payload)` | POST | `/{resource}/{pk}/documentos/` | `InstanciaDocumento` |\n| `deleteDocumento(id)` | DELETE | `/{resource}/{pk}/documentos/{id}/` | — |\n\n`transition(payload)` accepts `{ target_state, comentarios?, condiciones?, signature? }`. The exported helper `buildTransitionRequest(payload)` picks the wire format: plain JSON, or `multipart/form-data` when the signature block carries FIEL server-side files.\n\n`uploadDocumento({ archivo, documento?, tipo_documento?, porcentaje?, metadatos? })` is sent as `multipart/form-data` and must include `documento` **or** `tipo_documento`. The `buildDocumentoUpload(payload)` helper builds the `FormData` (encoding `metadatos` as JSON).\n\nAll calls support `AbortController` for cancellation. The store creates an `AbortController` per action and exposes `cancel()`.\n\n**Error mapping** follows `sinpapel-drf`: `403` for permission/predicate failures, `400` for validation and signature errors. Responses surface untouched in `store.error` / `tx.error`.\n\n---\n\n## 6. Store & composables\n\n### useSeguimientoStore\n\n```js\nimport { useSeguimientoStore } from '@aprendomx/sinpapel-vue'\n\nconst store = useSeguimientoStore({ axios, resource: 'solicitudes', pk: 42 })\n```\n\n**Reactive state:**\n- `estados`, `historial`, `historialCount`, `metadatos`, `preview`, `slaActions`, `documentos`, `requisitos`\n- `loading`: `{ estados, historial, metadatos, transicion, documentos, requisitos }` (booleans)\n- `error`: last API error\n\n**Actions:**\n- `cargarEstados()`, `cargarHistorial(page?)`, `ejecutarTransicion(payload)`, `cargarMetadatos()`, `guardarMetadatos(values)`, `cargarPreview(targetState)`, `evaluarSla()`\n- `cargarRequisitos()`, `cargarDocumentos()`, `subirDocumento(payload)`, `eliminarDocumento(id)` (the last two refresh list + requirements)\n- `cancel()`: aborts all in-flight requests\n\n### useTransition(client)\n\nManages the state and logic of a transition.\n\n```js\nconst tx = useTransition(client)\ntx.targetState.value = 'APROBADA'\nawait tx.checkFirmaRequerida()   // asks preview-transition whether a signature is mandatory\ntx.comentarios.value = 'Approved by committee'\nawait tx.submit()                // validates, builds payload, sends, resets on success\n```\n\n**Returns:** `{ targetState, comentarios, condiciones, signatureBackend, signatureMode, signatureFields, signaturePayload, firmaRequerida, checkFirmaRequerida, loading, error, errors, buildPayload, submit, reset, validate }`\n\n`checkFirmaRequerida()` is tolerant: clients without `previewTransition`, older backends, or network errors all resolve to `false` (signature optional).\n\n### useSpLabels()\n\nGets localized labels. Used automatically inside child components of `SeguimientoPanel`.\n\n### buildSignaturePayload(backend, mode, fields)\n\nPure helper that shapes the `signature` block per backend × mode, mirroring `SignatureRequestSerializer`. Exported for custom transition UIs.\n\n---\n\n## 7. Internationalization (i18n)\n\nSupports `es` (Spanish) and `en` (English) with no external dependencies.\n\n```vue\n<SeguimientoPanel ... locale=\"en\" />\n```\n\nTo add a new language, create a file in `src/locales/` and register it in `useSpLabels.js`.\n\n---\n\n## 8. Theming\n\nCSS variables `--sp-*` can be overridden in your scope:\n\n```css\n:root {\n  --sp-color-primary: #3a4a5c;\n  --sp-surface: #ffffff;\n  --sp-border: #dfe3e8;\n  /* ...see src/styles/tokens.css */\n}\n```\n\nRemember to import the stylesheet once: `import '@aprendomx/sinpapel-vue/style.css'`.\n\n---\n\n## 9. TypeScript\n\nType definitions are in `types/index.d.ts` and resolve automatically:\n\n```ts\nimport { createSinpapelClient, SeguimientoPanel, useTransition } from '@aprendomx/sinpapel-vue'\nimport type { SinpapelClient, TransitionPayload, Estado, PreviewReport } from '@aprendomx/sinpapel-vue'\n```\n\n---\n\n## 10. Compatibility\n\n| Vue | Pinia | Quasar | Node (CI) |\n|---|---|---|---|\n| 3.5+ | 3.0+ | 2.16+ | 20, 22 |\n\nBackend matrix:\n\n| Backend package | Minimum | Notes |\n|---|---|---|\n| `sinpapel` | 0.8.x | Engine behind the API |\n| `sinpapel-drf` | 0.3.x | Baseline: transitions, history, preview, metadata, SLA |\n| `sinpapel-drf` | **0.4.0** | Required by `DocumentosPanel` (dependent selects: `tipo_documento_id`, `documentos_disponibles`) |\n| `sinpapel-drf` | **0.4.4** | Required for mandatory-signature enforcement (`firma_requerida` in the preview report) |\n\nNewer features degrade to their previous behavior on older backends rather than breaking.\n\n---\n\n## 11. Development & testing\n\n```bash\nnpm install\nnpm run dev        # development server (demo/)\nnpm test           # full vitest suite (77 tests)\nnpm run test:watch # watch mode\nnpm run build      # library build → dist/\nnpm run lint       # eslint\n```\n\nCI (`.github/workflows/ci.yml`) runs lint, tests and build on Node 20 and 22 for every push and pull request to `main`/`master`.\n\nPublishing: `npm publish`. The `prepublishOnly` script guarantees only code that passes lint + tests + build ships.\n\n---\n\n## 12. Known limitations & Roadmap\n\n**Limitations:**\n\n- `GET …/history/` returns thin django-simple-history records. Comments and signatures are not shown unless the backend exposes them.\n- No auto-discovery of the `resource` slug; the consumer must pass it explicitly.\n- `SeguimientoPanel` builds its store from the initial props — dynamic `pk`/`resource` need a `:key` remount.\n- Quasar is required even if you only use a subset of the widgets.\n\n**Roadmap:**\n\n- Slot-based customization of the panel tabs.\n- Optional Quasar-free build.\n- Richer history rows once `sinpapel-drf` exposes them.\n\n---\n\n## 13. Versioning & Stability\n\nThis package follows [Semantic Versioning](https://semver.org/). The current release is **v0.4.0 (Beta)**. Pre-1.0 contract: **minor releases may include breaking changes** (documented in the [changelog](https://github.com/aprendomx/sinpapel-vue/blob/main/CHANGELOG.md)); patch releases are fixes only. Pin the minor (`\"@aprendomx/sinpapel-vue\": \"~0.4.0\"`) until 1.0.0.\n\nThe public surface is what `src/index.js` exports: components, `createSinpapelClient`, `buildTransitionRequest`, `buildDocumentoUpload`, `useSeguimientoStore`, `useTransition`, `buildSignaturePayload`.\n\n---\n\n## 14. Documentation & agent skills\n\n- [Changelog](https://github.com/aprendomx/sinpapel-vue/blob/main/CHANGELOG.md)\n- [sinpapel usage guide](https://github.com/aprendomx/sinpapel/blob/main/docs/usage/en.md) — engine concepts (states, transitions, predicates, requirements, signing)\n- [sinpapel-drf README](https://github.com/aprendomx/sinpapel-drf/blob/main/README.md) — the API contract this library consumes\n- [sinpapel-boilerplate](https://github.com/aprendomx/sinpapel-boilerplate) — Django + Vue project skeleton with the ecosystem versions pinned\n\n**For AI agents:** [sinpapel-skills](https://github.com/aprendomx/sinpapel-skills) publishes multi-provider skills (Claude, Cursor, OpenCode) for the whole ecosystem. Four of them cover this package: `sinpapel-vue-setup`, `sinpapel-vue-client`, `sinpapel-vue-components` and `sinpapel-vue-store`.\n\n---\n\n## 15. License & Contributing\n\nGPL-3.0-or-later — see [LICENSE](https://github.com/aprendomx/sinpapel-vue/blob/main/LICENSE).\n\nCopyright (C) 2024-2026 AprendoMX. This software is free: you can redistribute it and/or modify it under the terms of the GNU GPL v3. It is distributed in the hope that it will be useful, but **WITHOUT ANY WARRANTY**.\n\nIssues + PRs at https://github.com/aprendomx/sinpapel-vue/issues. Tag with `area/sinpapel-vue`.\n\n**Related projects:**\n\n- [sinpapel](https://github.com/aprendomx/sinpapel) — engine core (workflow + signature + audit + predicates + SLA + metadata)\n- [sinpapel-drf](https://github.com/aprendomx/sinpapel-drf) — REST layer consumed by this library\n- [sinpapel-webhooks](https://github.com/aprendomx/sinpapel-webhooks) — event-driven HTTP communication\n- [sinpapel-reports](https://github.com/aprendomx/sinpapel-reports) — template-driven document generation\n- [sinpapel-designer](https://github.com/aprendomx/sinpapel-designer) — visual workflow editor\n","readmeFilename":"README.md","homepage":"https://github.com/aprendomx/sinpapel-vue#readme","keywords":["sinpapel","workflow","vue3","quasar","pinia","django","drf","audit-trail","electronic-signature","fiel"],"repository":{"type":"git","url":"git+https://github.com/aprendomx/sinpapel-vue.git"},"author":{"name":"AprendoMX"},"bugs":{"url":"https://github.com/aprendomx/sinpapel-vue/issues"}}