#49 fix: labels en nodos de gráficos y municipio con departamento en proveedores

This commit is contained in:
2026-08-15 18:33:30 -05:00
parent 79100ef40e
commit 58b42d956b
6 changed files with 52 additions and 7 deletions

View File

@@ -60,6 +60,7 @@
color: '#263238', color: '#263238',
'font-size': 12, 'font-size': 12,
'font-family': 'sans-serif', 'font-family': 'sans-serif',
content: 'data(label)',
'text-valign': 'bottom', 'text-valign': 'bottom',
'text-halign': 'center', 'text-halign': 'center',
'text-wrap': 'wrap', 'text-wrap': 'wrap',
@@ -73,7 +74,7 @@
{ selector: 'node.product', style: { 'background-color': '#26a69a', 'border-color': '#00796b' } }, { selector: 'node.product', style: { 'background-color': '#26a69a', 'border-color': '#00796b' } },
{ selector: 'node.supplier', style: { 'background-color': '#42a5f5', 'border-color': '#1565c0' } }, { selector: 'node.supplier', style: { 'background-color': '#42a5f5', 'border-color': '#1565c0' } },
{ selector: 'node.organization', style: { 'background-color': '#ffb74d', 'border-color': '#e65100' } }, { selector: 'node.organization', style: { 'background-color': '#ffb74d', 'border-color': '#e65100' } },
{ selector: 'node.has-image', style: { 'background-image': 'data(image)', 'background-fit': 'cover', 'background-clip': 'none' } }, { selector: 'node.has-image', style: { 'background-image': 'data(image)', 'background-fit': 'cover', 'background-clip': 'none', 'text-background-color': '#ffffff', 'text-background-opacity': 0.85, 'text-background-padding': 2 } },
{ {
selector: 'edge', selector: 'edge',
style: { style: {

View File

@@ -60,6 +60,7 @@
color: '#263238', color: '#263238',
'font-size': 12, 'font-size': 12,
'font-family': 'sans-serif', 'font-family': 'sans-serif',
content: 'data(label)',
'text-valign': 'bottom', 'text-valign': 'bottom',
'text-halign': 'center', 'text-halign': 'center',
'text-wrap': 'wrap', 'text-wrap': 'wrap',
@@ -75,7 +76,7 @@
{ selector: 'node.municipality', style: { 'background-color': '#66bb6a', 'border-color': '#2e7d32' } }, { selector: 'node.municipality', style: { 'background-color': '#66bb6a', 'border-color': '#2e7d32' } },
{ selector: 'node.department', style: { 'background-color': '#5c6bc0', 'border-color': '#283593' } }, { selector: 'node.department', style: { 'background-color': '#5c6bc0', 'border-color': '#283593' } },
{ selector: 'node.country', style: { 'background-color': '#ab47bc', 'border-color': '#6a1b9a' } }, { selector: 'node.country', style: { 'background-color': '#ab47bc', 'border-color': '#6a1b9a' } },
{ selector: 'node.has-image', style: { 'background-image': 'data(image)', 'background-fit': 'cover', 'background-clip': 'none' } }, { selector: 'node.has-image', style: { 'background-image': 'data(image)', 'background-fit': 'cover', 'background-clip': 'none', 'text-background-color': '#ffffff', 'text-background-opacity': 0.85, 'text-background-padding': 2 } },
{ {
selector: 'edge', selector: 'edge',
style: { style: {

View File

@@ -111,7 +111,7 @@
v-model="formData.municipality" v-model="formData.municipality"
clearable clearable
data-testid="supplier-form-municipality" data-testid="supplier-form-municipality"
item-title="name" :item-title="municipalityItemTitle"
item-value="id" item-value="id"
:items="municipalityItems" :items="municipalityItems"
label="Municipio" label="Municipio"
@@ -189,6 +189,7 @@
const suppliers = ref([]) const suppliers = ref([])
const organizations = ref([]) const organizations = ref([])
const municipalities = ref([]) const municipalities = ref([])
const departments = ref([])
const loading = ref(false) const loading = ref(false)
const saving = ref(false) const saving = ref(false)
const searchQuery = ref('') const searchQuery = ref('')
@@ -226,12 +227,18 @@
}) })
}) })
function municipalityItemTitle (item) {
const department = departments.value.find(department => department.id === item.department)
if (!department) return item.name || ''
return `${item.name} (${department.name})`
}
const municipalityItems = computed(() => { const municipalityItems = computed(() => {
const query = municipalitySearch.value.trim().toLowerCase() const query = municipalitySearch.value.trim().toLowerCase()
let filtered = municipalities.value let filtered = municipalities.value
if (query) { if (query) {
filtered = municipalities.value.filter(municipality => { filtered = municipalities.value.filter(municipality => {
return (municipality.name || '').toLowerCase().includes(query) return municipalityItemTitle(municipality).toLowerCase().includes(query)
}) })
} }
const selectedId = Number(formData.value.municipality) const selectedId = Number(formData.value.municipality)
@@ -246,14 +253,16 @@
async function load () { async function load () {
loading.value = true loading.value = true
try { try {
const [suppliersData, organizationsData, municipalitiesData] = await Promise.all([ const [suppliersData, organizationsData, municipalitiesData, departmentsData] = await Promise.all([
api.getSuppliers(), api.getSuppliers(),
api.getOrganizations(), api.getOrganizations(),
api.getMunicipalities(), api.getMunicipalities(),
api.getDepartments(),
]) ])
suppliers.value = suppliersData suppliers.value = suppliersData
organizations.value = organizationsData organizations.value = organizationsData
municipalities.value = municipalitiesData municipalities.value = municipalitiesData
departments.value = departmentsData
} catch (error) { } catch (error) {
console.error('Error al cargar proveedores:', error) console.error('Error al cargar proveedores:', error)
showSnackbar('Error al cargar proveedores', 'error') showSnackbar('Error al cargar proveedores', 'error')

View File

@@ -60,6 +60,14 @@ describe('ProductSupplierOrganizationChart', () => {
expect(nodeIds).toContain('organization:3') expect(nodeIds).toContain('organization:3')
}) })
it('muestra el nombre de los nodos a través del label', () => {
const wrapper = mountChart()
const styles = wrapper.findComponent(CytoscapeChart).props('styles')
const nodeStyle = styles.find(style => style.selector === 'node').style
expect(nodeStyle.content).toBe('data(label)')
})
it('no muestra mensaje de próximamente cuando existen relaciones', () => { it('no muestra mensaje de próximamente cuando existen relaciones', () => {
const wrapper = mountChart() const wrapper = mountChart()

View File

@@ -58,6 +58,14 @@ describe('ProductTerritoryChart', () => {
expect(nodeIds).toContain('country:1') expect(nodeIds).toContain('country:1')
}) })
it('muestra el nombre de los nodos a través del label', () => {
const wrapper = mountChart()
const styles = wrapper.findComponent(CytoscapeChart).props('styles')
const nodeStyle = styles.find(style => style.selector === 'node').style
expect(nodeStyle.content).toBe('data(label)')
})
it('muestra mensaje de próximamente cuando ningún proveedor tiene territorio', () => { it('muestra mensaje de próximamente cuando ningún proveedor tiene territorio', () => {
const wrapper = mountChart({ const wrapper = mountChart({
provenance: [ provenance: [

View File

@@ -10,8 +10,13 @@ const organizations = [
] ]
const municipalities = [ const municipalities = [
{ id: 7, name: 'La Mesa' }, { id: 7, name: 'La Mesa', department: 2 },
{ id: 8, name: 'San Antonio' }, { id: 8, name: 'San Antonio', department: 3 },
]
const departments = [
{ id: 2, name: 'Cundinamarca' },
{ id: 3, name: 'Antioquia' },
] ]
const suppliers = [ const suppliers = [
@@ -44,6 +49,7 @@ function mockApi () {
getSuppliers: vi.fn().mockResolvedValue(suppliers), getSuppliers: vi.fn().mockResolvedValue(suppliers),
getOrganizations: vi.fn().mockResolvedValue(organizations), getOrganizations: vi.fn().mockResolvedValue(organizations),
getMunicipalities: vi.fn().mockResolvedValue(municipalities), getMunicipalities: vi.fn().mockResolvedValue(municipalities),
getDepartments: vi.fn().mockResolvedValue(departments),
createSupplier: vi.fn().mockResolvedValue({}), createSupplier: vi.fn().mockResolvedValue({}),
updateSupplier: vi.fn().mockResolvedValue({}), updateSupplier: vi.fn().mockResolvedValue({}),
deleteSupplier: vi.fn().mockResolvedValue({}), deleteSupplier: vi.fn().mockResolvedValue({}),
@@ -68,6 +74,18 @@ describe('SuppliersManagement', () => {
expect(wrapper.text()).toContain('La Mesa') expect(wrapper.text()).toContain('La Mesa')
}) })
it('muestra el departamento en el título del municipio', async () => {
const api = mockApi()
const wrapper = mountComponent(api)
await flushPromises()
await wrapper.find('[data-testid="supplier-create"]').trigger('click')
const autocomplete = wrapper.findAllComponents({ name: 'VAutocomplete' })[0]
const itemTitle = autocomplete.props('itemTitle')
expect(itemTitle({ id: 7, name: 'La Mesa', department: 2 })).toBe('La Mesa (Cundinamarca)')
})
it('crea un proveedor con organización y municipio', async () => { it('crea un proveedor con organización y municipio', async () => {
const api = mockApi() const api = mockApi()
const wrapper = mountComponent(api) const wrapper = mountComponent(api)