Terminar Habilidades puntuadas

This commit is contained in:
Juan Felipe Zapata Moreno 2025-07-11 16:29:49 -06:00
parent d54c017d40
commit 776ef80b93
12 changed files with 384 additions and 342 deletions

View File

@ -8,6 +8,7 @@
use App\Http\Requests\StoreMainRoleSkills;
use App\Http\Requests\UpdateMainRoleSkills;
use App\Models\department;
use App\Models\mainRole;
use App\Models\MainRoleSkills;
use App\Models\Score;
@ -42,19 +43,43 @@ public function index()
->orWhereIn('scored_id', $scores)
->with([
'mainRole:id,name,department_id',
'mainRole.department:id,name,description',
'skill:id,name,department_id',
'skill:id,name',
'score:id,alias'
])
->paginate(config('app.pagination'));
$departments = department::select(['id', 'name', 'description'])->orderBy('name', 'ASC')->get();
$mainRoles = mainRole::with(['department:id,name'])->orderBy('name', 'ASC')->get();
$skills = Skill::with(['department:id,name'])->orderBy('name', 'ASC')->get();
$scores = Score::orderBy('alias', 'ASC')->get();
return $this->vuew('index', [
'mainRoleSkills' => $mainRoleSkills
'mainRoleSkills' => $mainRoleSkills,
'departments' => $departments,
'mainRoles' => $mainRoles,
'skills' => $skills,
'scores' => $scores,
]);
}
public function create()
{
$roleId = request()->get('role_id');
$departmentId = request()->get('department_id');
// Obtener el rol seleccionado y su departamento
$selectedRole = null;
$selectedDepartment = null;
if ($roleId) {
$selectedRole = mainRole::with('department:id,name')->find($roleId);
if ($selectedRole && $selectedRole->department) {
$selectedDepartment = $selectedRole->department;
}
} elseif ($departmentId) {
$selectedDepartment = department::find($departmentId);
}
$mainRoles = mainRole::with('department:id,name')->orderBy('name', 'ASC')->get();
$skills = Skill::with('department:id,name')->orderBy('name', 'ASC')->get();
$scores = Score::orderBy('alias', 'ASC')->get();
@ -62,7 +87,9 @@ public function create()
return $this->vuew('create', [
'mainRoles' => $mainRoles,
'skills' => $skills,
'scores' => $scores
'scores' => $scores,
'selectedRole' => $selectedRole,
'selectedDepartment' => $selectedDepartment
]);
}
@ -89,10 +116,16 @@ public function update(UpdateMainRoleSkills $request, MainRoleSkills $mainRoleSk
$mainRoleSkills->update($request->all());
}
public function destroy($id)
public function destroy($mainRoleId)
{
$mainRoleSkill = MainRoleSkills::findOrFail($id);
$mainRoleSkill->delete();
}
try {
// Eliminar todas las habilidades asociadas a este rol principal
MainRoleSkills::where('main_role_id', $mainRoleId)->delete();
return $this->index();
} catch (\Throwable $th) {
Log::channel('mainRoleSkills')->error($th->getMessage());
return response()->json(['error' => 'Error al eliminar las habilidades'], 500);
}
}
}

View File

@ -4,13 +4,11 @@ defineEmits(['select']);
const props = defineProps({
departments: Object,
});
console.log('Department props:', props.departments);
</script>
<template>
<div class="w-full">
<div class="mb-6">
<div class="mb-6 mt-12">
<h2 class="text-xl font-semibold mb-2">{{ $t('department.select.title') }}</h2>
<p class="text-gray-600">{{ $t('department.select.description') }}</p>
</div>

View File

@ -4,14 +4,8 @@ import { computed } from 'vue';
const emit = defineEmits(['select']);
const props = defineProps({
mainRoles: {
type: Object,
required: true
},
selectedDepartment: {
type: Object,
required: true
}
mainRoles: Object,
selectedDepartment: Object,
});
const departmentMainRoles = computed(() => {
@ -23,9 +17,9 @@ const departmentMainRoles = computed(() => {
<template>
<div class="w-full">
<div class="mb-6">
<div class="mb-6 mt-12">
<h2 class="text-xl font-semibold mb-2">
{{ $t('mainRole.inDepartment', { department: selectedDepartment.name }) }}
{{ $t('mainRole.inDepartment') }}
</h2>
<p class="text-gray-600">{{ $t('mainRole.select.description') }}</p>
</div>

View File

@ -1,9 +1,9 @@
<script setup>
import { ref, computed, onMounted, watch } from "vue";
import { ref, computed } from "vue";
import PrimaryButton from "@/Components/Dashboard/Button/Primary.vue";
import Selectable from "@/Components/Dashboard/Form/Selectable.vue";
const emit = defineEmits(["submit", "update:modelValue"]);
const emit = defineEmits(["submit"]);
const props = defineProps({
form: {
@ -11,11 +11,11 @@ const props = defineProps({
required: true,
},
skills: {
type: Object,
type: Array, // Ya filtradas por departamento
required: true,
},
scores: {
type: Object,
type: Array,
required: true,
},
selectedDepartment: {
@ -26,26 +26,28 @@ const props = defineProps({
type: Object,
required: true,
},
modelValue: {
type: Array,
default: () => [],
},
});
const skillId = ref("");
const scoredId = ref("");
const todos = ref([]);
function addTodo() {
if (skillId.value && scoredId.value) {
// Buscar los objetos completos
const selectedSkill = departmentSkills.value.find(
(skill) => skill.id === skillId.value.id || skill.id === skillId.value
const selectedSkill = props.skills.find(
skill => skill.id === (skillId.value.id || skillId.value)
);
const selectedScore = props.scores.find(
(score) => score.id === scoredId.value.id || score.id === scoredId.value
score => score.id === (scoredId.value.id || scoredId.value)
);
if (selectedSkill && selectedScore) {
// Verificar que no esté duplicada
const isDuplicate = todos.value.some(
todo => todo.skill_id === selectedSkill.id
);
if (!isDuplicate) {
const newItem = {
skill_id: selectedSkill.id,
scored_id: selectedScore.id,
@ -55,27 +57,18 @@ function addTodo() {
todos.value.push(newItem);
// Limpiar los campos
// Limpiar campos
skillId.value = "";
scoredId.value = "";
// Emitir el arreglo actualizado
emit("update:modelValue", todos.value);
}
}
}
}
function removeTodo(index) {
todos.value.splice(index, 1);
emit("update:modelValue", todos.value);
}
const departmentSkills = computed(() => {
return props.skills.filter(
(skill) => skill.department_id === props.selectedDepartment.id
);
});
const isFormValid = computed(() => {
return todos.value.length > 0;
});
@ -85,35 +78,16 @@ const submitForm = () => {
emit("submit", todos.value);
}
};
onMounted(() => {
if (Array.isArray(props.modelValue) && props.modelValue.length > 0) {
todos.value = [...props.modelValue];
}
});
watch(
() => props.modelValue,
(newValue) => {
if (Array.isArray(newValue)) {
todos.value = [...newValue];
}
}
);
</script>
<template>
<div class="w-full">
<div class="mb-6">
<h2 class="text-xl font-semibold mb-2">
{{ $t("skill.assignTo", { role: selectedMainRole.name }) }}
Asignar Habilidades al Rol: {{ selectedMainRole.name }}
</h2>
<p class="text-gray-600">
{{
$t("skill.assignment.description", {
department: selectedDepartment.name,
})
}}
Departamento: {{ selectedDepartment.name }}
</p>
</div>
@ -123,7 +97,7 @@ watch(
<Selectable
id="skill_id"
v-model="skillId"
:options="departmentSkills"
:options="skills"
:title="$t('skill.title')"
placeholder="Selecciona una habilidad..."
label="name"
@ -147,7 +121,8 @@ watch(
<button
@click="addTodo"
type="button"
class="rounded-lg px-4 py-2 bg-primary text-white border dark:bg-primary-dark dark:border-primary-dark-on"
:disabled="!skillId || !scoredId"
class="rounded-lg px-4 py-2 bg-primary text-white border disabled:opacity-50 disabled:cursor-not-allowed"
>
Agregar Habilidad
</button>
@ -159,15 +134,15 @@ watch(
<template v-for="(todo, index) in todos" :key="index">
<div class="flex bg-white items-center justify-between rounded-lg px-4 py-3 border shadow-sm">
<div class="flex-1">
<div class="font-bold text-black">Habilidad: {{ todo.skill_name }}</div>
<div class="font-bold text-black">Puntuación: {{ todo.score_alias }}</div>
<div class="font-bold text-black">{{ todo.skill_name }}</div>
<div class="text-sm text-gray-600">Puntuación: {{ todo.score_alias }}</div>
</div>
<div
<button
@click="removeTodo(index)"
class="rounded-lg px-4 py-2 bg-red-600 text-white cursor-pointer hover:bg-red-700 transition-colors"
class="rounded-lg px-4 py-2 bg-red-600 text-white hover:bg-red-700 transition-colors"
>
Quitar
</div>
</button>
</div>
</template>
@ -184,7 +159,7 @@ watch(
type="button"
@click="submitForm"
>
<span>{{ $t("Crear") }}</span>
<span>Crear Asignación</span>
</PrimaryButton>
</div>
</div>

View File

@ -0,0 +1,90 @@
<script setup>
import { computed } from "vue";
import { Link } from "@inertiajs/vue3";
import { can, goTo } from "@/Pages/Admin/MainRoleSkills/Component";
import GoogleIcon from "@/Components/Shared/GoogleIcon.vue";
const emit = defineEmits(["select"]);
const props = defineProps({
mainRoleSkills: Array,
selectedRole: Object,
});
const roleSkills = computed(() => {
if (!props.mainRoleSkills || !props.selectedRole) {
return [];
}
// Filtrar habilidades por rol seleccionado
return props.mainRoleSkills.filter(
(roleSkill) => roleSkill.main_role_id === props.selectedRole.id
);
});
</script>
<template>
<div class="w-full">
<div class="mb-6 mt-12">
<div class="flex gap-6">
<h2 class="text-xl font-semibold mb-2">
{{ $t("skill.assignment.title") }}
</h2>
<Link
v-if="can('create')"
:href="route(goTo('create'), {
role_id: selectedRole.id,
department_id: selectedRole.department?.id || selectedRole.department_id
})"
>
<GoogleIcon
:title="$t('crud.create')"
class="btn-icon-primary"
name="add"
outline
/>
</Link>
</div>
<p class="text-gray-600">
Habilidades asignadas al rol: {{ selectedRole.name }}
</p>
</div>
<div
v-if="roleSkills.length > 0"
class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4"
>
<div
v-for="roleSkill in roleSkills"
:key="roleSkill.id"
class="bg-white p-4 rounded-lg shadow hover:shadow-lg transition-shadow duration-200 cursor-pointer border"
@click="emit('select', roleSkill)"
>
<h3 class="text-lg font-medium mb-2 text-blue-600">
{{ roleSkill.skill.name }}
</h3>
<div class="text-sm text-gray-600">
<span class="font-semibold">Puntuación:</span>
{{ roleSkill.score.alias }}
</div>
<p
v-if="roleSkill.skill.description"
class="text-xs text-gray-500 mt-2"
>
{{ roleSkill.skill.description }}
</p>
</div>
</div>
<div v-else class="text-center py-12">
<p class="text-gray-500 text-lg">
No hay habilidades asignadas a este rol
</p>
<p class="text-gray-400 text-sm mt-2">
Las habilidades se pueden asignar desde la sección de creación
</p>
</div>
</div>
</template>

View File

@ -292,6 +292,7 @@ export default {
assignTo: "Asignar a rol principal",
system: "Sistema de habilidades",
assignment: {
title: "Habilidades del Rol",
description: "Asigna una habilidad a un rol principal.",
},
create: {

View File

@ -65,7 +65,7 @@ const submit = () => form.post(route(goTo('store')), {
required
/>
<Input
id="Descrición"
id="Descripción"
class="col-span-2"
v-model="form.description"
:onError="form.errors.description"

View File

@ -54,7 +54,7 @@ const submit = () => form.post(route(goTo('store')), {
required
/>
<Input
id="Descrición"
id="Descripción"
class="col-span-2"
v-model="form.description"
:onError="form.errors.description"

View File

@ -59,7 +59,7 @@ const submit = () =>
required
/>
<Input
id="Descrición"
id="Descripción"
class="col-span-2"
v-model="form.description"
:onError="form.errors.description"

View File

@ -1,110 +1,115 @@
<script setup>
import { goTo, transl } from "./Component";
import { Link, useForm } from "@inertiajs/vue3";
import { ref, computed } from "vue";
import { ref, computed, onMounted } from "vue";
import PrimaryButton from "@/Components/Dashboard/Button/Primary.vue";
import SecondaryButton from "@/Components/Dashboard/Button/Secondary.vue";
import PageHeader from "@/Components/Dashboard/PageHeader.vue";
import GoogleIcon from "@/Components/Shared/GoogleIcon.vue";
import DashboardLayout from "@/Layouts/DashboardLayout.vue";
// Componentes específicos para el flujo
import StepIndicator from "@/Components/App/StepIndicator.vue";
import DepartmentSelector from "@/Components/App/DepartmentSelector.vue";
import MainRoleSelector from "@/Components/App/MainRoleSelector.vue";
import SkillAssignment from "@/Components/App/SkillAssignment.vue";
const props = defineProps({
mainRoles: Object,
skills: Object,
scores: Object,
});
// Estado del flujo
const currentStep = ref(1);
const selectedDepartment = ref(null);
const selectedMainRole = ref(null);
const form = useForm({
main_role_id: "",
skill_id: "",
scored_id: "",
});
// Datos computados
const uniqueDepartments = computed(() => {
const deps = [];
const seen = new Set();
props.mainRoles.forEach((role) => {
if (role.department && !seen.has(role.department.id)) {
seen.add(role.department.id);
deps.push(role.department);
mainRoles: {
type: Array,
default: () => []
},
skills: {
type: Array,
default: () => []
},
scores: {
type: Array,
default: () => []
},
selectedRole: {
type: Object,
default: null
},
selectedDepartment: {
type: Object,
default: null
}
});
return deps;
const selectedDepartment = ref(props.selectedDepartment);
const selectedMainRole = ref(props.selectedRole);
const form = useForm({
main_role_id: props.selectedRole?.id || '',
skills: []
});
// Obtener departamentos únicos
const departments = computed(() => {
const uniqueDepartments = [];
const seenIds = new Set();
props.mainRoles.forEach(role => {
if (role.department && !seenIds.has(role.department.id)) {
seenIds.add(role.department.id);
uniqueDepartments.push(role.department);
}
});
return uniqueDepartments;
});
// Filtrar habilidades por departamento seleccionado
const departmentSkills = computed(() => {
if (!selectedDepartment.value) return [];
return props.skills.filter(skill =>
skill.department_id === selectedDepartment.value.id
);
});
// Métodos de navegación
const handleDepartmentSelect = (department) => {
selectedDepartment.value = department;
currentStep.value = 2;
selectedMainRole.value = null;
form.main_role_id = '';
};
const handleMainRoleSelect = (mainRole) => {
selectedMainRole.value = mainRole;
form.main_role_id = mainRole.id;
currentStep.value = 3;
const handleRoleSelect = (role) => {
selectedMainRole.value = role;
form.main_role_id = role.id;
};
const submit = (skillsData) => {
form.skills = skillsData;
form.post(route(goTo("store")), {
onSuccess: () => {
// Redireccionar al index
},
onError: () => {
// Mostrar mensaje de error
},
});
};
const goBack = () => {
if (currentStep.value === 3) {
if (selectedMainRole.value) {
selectedMainRole.value = null;
form.main_role_id = "";
form.skill_id = "";
form.scored_id = "";
currentStep.value = 2;
} else if (currentStep.value === 2) {
form.main_role_id = '';
} else if (selectedDepartment.value) {
selectedDepartment.value = null;
selectedMainRole.value = null;
form.reset();
currentStep.value = 1;
}
};
const resetFlow = () => {
selectedDepartment.value = null;
selectedMainRole.value = null;
form.reset();
currentStep.value = 1;
};
const submit = (skillArray) => {
const skillsData = skillArray.map(skill => ({
skill_id: skill.skill_id,
scored_id: skill.scored_id,
}));
form
.transform((data) => ({
main_role_id: data.main_role_id,
skills: skillsData
}))
.post(route(goTo("store")), {
onSuccess: () => {
Notify.success(transl("create.onSuccess"));
resetFlow();
},
onError: () => Notify.error(transl("create.onError")),
onMounted(() => {
// Si tenemos rol seleccionado, asegurar que el departamento también esté seleccionado
if (props.selectedRole && props.selectedRole.department) {
selectedDepartment.value = props.selectedRole.department;
selectedMainRole.value = props.selectedRole;
form.main_role_id = props.selectedRole.id;
}
});
};
</script>
<template>
<DashboardLayout :title="transl('create.title')">
<PageHeader>
<div class="flex items-center space-x-2">
<Link :href="route(goTo('index'))">
<GoogleIcon
:title="$t('return')"
@ -113,51 +118,52 @@ const submit = (skillArray) => {
outline
/>
</Link>
</div>
</PageHeader>
<!-- Indicador de progreso componentizado -->
<div class="mt-6">
<StepIndicator :current-step="currentStep" />
<div class="flex justify-center gap-2">
<SecondaryButton v-if="currentStep > 1" @click="goBack" type="button">
<GoogleIcon name="keyboard_backspace" class="mr-2" />
{{ $t("Regresar") }}
</SecondaryButton>
<div class="w-full pb-8">
<div class="mt-8">
<p v-text="transl('create.description')" />
</div>
</div>
<SecondaryButton
v-if="currentStep > 1"
@click="resetFlow"
type="button"
<div class="w-full">
<!-- Navegación hacia atrás -->
<div v-if="selectedDepartment || selectedMainRole" class="mb-6">
<button
@click="goBack"
class="text-primary hover:underline flex items-center gap-2"
>
<GoogleIcon name="refresh" class="mr-2" />
{{ $t("Inicio") }}
</SecondaryButton>
</div>
<GoogleIcon name="arrow_back" class="w-4 h-4" />
<span v-if="selectedMainRole">Cambiar rol principal</span>
<span v-else-if="selectedDepartment">Cambiar departamento</span>
</button>
</div>
<!-- Componentes de pasos -->
<!-- Paso 1: Selector de Departamento -->
<DepartmentSelector
v-if="currentStep === 1"
:departments="uniqueDepartments"
v-if="!selectedDepartment"
:departments="departments"
@select="handleDepartmentSelect"
/>
<!-- Paso 2: Selector de Rol Principal -->
<MainRoleSelector
v-if="currentStep === 2"
:main-roles="mainRoles"
:selected-department="selectedDepartment"
@select="handleMainRoleSelect"
v-else-if="selectedDepartment && !selectedMainRole"
:selectedDepartment="selectedDepartment"
:mainRoles="mainRoles"
@select="handleRoleSelect"
/>
<!-- Paso 3: Asignación de Habilidades -->
<SkillAssignment
v-if="currentStep === 3"
v-else-if="selectedDepartment && selectedMainRole"
:form="form"
:skills="skills"
:skills="departmentSkills"
:scores="scores"
:selected-department="selectedDepartment"
:selected-main-role="selectedMainRole"
:selectedDepartment="selectedDepartment"
:selectedMainRole="selectedMainRole"
@submit="submit"
/>
</div>
</DashboardLayout>
</template>

View File

@ -1,146 +1,91 @@
<script setup>
import { transl, can, goTo } from "./Component";
import { transl } from "./Component";
import { ref, computed } from "vue";
import { Link } from "@inertiajs/vue3";
import ModalController from "@/Controllers/ModalController.js";
import SearcherController from "@/Controllers/SearcherController.js";
import SearcherHead from "@/Components/Dashboard/Searcher.vue";
import Table from "@/Components/Dashboard/Table.vue";
import GoogleIcon from "@/Components/Shared/GoogleIcon.vue";
import DashboardLayout from "@/Layouts/DashboardLayout.vue";
import DestroyView from "./Destroy.vue";
import EditView from "./Edit.vue";
import DepartmentSelector from "@/Components/App/DepartmentSelector.vue";
import MainRoleSelector from "@/Components/App/MainRoleSelector.vue";
import SkillRole from "@/Components/App/SkillsRole.vue";
import PageHeader from "@/Components/Dashboard/PageHeader.vue";
import GoogleIcon from "@/Components/Shared/GoogleIcon.vue";
defineEmits(["select"]);
const props = defineProps({
mainRoleSkills: Object,
departments: Object,
mainRoles: Object,
skills: Object,
scores: Object,
});
// Controladores
const Modal = new ModalController();
const Searcher = new SearcherController(goTo("index"));
const selectedDepartment = ref(null);
const selectedRole = ref(null);
// Variables de controladores
const destroyModal = ref(Modal.destroyModal);
const editModal = ref(Modal.editModal);
const modelModal = ref(Modal.modelModal);
const query = ref(Searcher.query);
const filteredMainRoleSkills = computed(() => {
if (!props.mainRoleSkills?.data || !selectedRole.value) {
return [];
}
const groupedRoles = computed(() => {
const groups = {};
props.mainRoleSkills.data?.forEach(item => {
const key = item.main_role?.id;
if(!groups[key]) groups[key] = { ...item, skills: []};
groups[key].skills.push(item);
})
return Object.values(groups);
return props.mainRoleSkills.data.filter(roleSkill =>
roleSkill.main_role_id === selectedRole.value.id
);
});
const handleDepartmentSelect = (department) => {
selectedDepartment.value = department;
selectedRole.value= null;
};
const handleRoleSelect = (role) => {
selectedRole.value = role;
};
const handleSkillSelect = (roleSkill) => {
console.log('Habilidad de rol seleccionada:', roleSkill);
}
const goBack = () => {
if (selectedRole.value) {
selectedRole.value = null;
} else if (selectedDepartment.value) {
selectedDepartment.value = null;
}
};
</script>
<template>
<DashboardLayout :title="transl('system')">
<SearcherHead @search="Searcher.search">
<Link v-if="can('create')" :href="route(goTo('create'))">
<PageHeader>
<button @click="goBack">
<GoogleIcon
:title="$t('crud.create')"
:title="$t('return')"
class="btn-icon-primary"
name="add"
name="arrow_back"
outline
/>
</Link>
</SearcherHead>
<div class="pt-2 w-full">
<Table
:items="mainRoleSkills"
@send-pagination="Searcher.searchWithPagination"
>
<template #head>
<th class="table-item" v-text="$t('Departamento')" />
<th class="table-item" v-text="$t('Rol Principal')" />
<th class="table-item" v-text="$t('Habilidades Puntuadas')" />
<th class="table-item w-44" v-text="$t('actions')" />
</template>
<template #body="{ items }">
<tr v-for="group in groupedRoles" :key="group.main_role.id">
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ group.main_role?.department?.name }}
</p>
</div>
</div>
</td>
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ group.main_role?.name }}
</p>
</div>
</div>
</td>
<div>
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p v-for="skill in group.skills" :key="skill.id" class="font-semibold">
{{ skill.skill?.name }} - {{ skill.score?.alias }}
</p>
</div>
</div>
</td>
</div>
<td class="table-item border">
<div class="flex justify-center space-x-2">
<GoogleIcon
v-if="can('edit')"
:title="$t('crud.edit')"
class="btn-icon-primary"
name="edit"
outline
@click="Modal.switchEditModal(model)"
</button>
</PageHeader>
<!-- Selector de Departamento -->
<DepartmentSelector
v-if="!selectedDepartment"
:departments="departments"
@select="handleDepartmentSelect"
/>
<GoogleIcon
v-if="can('destroy')"
:title="$t('crud.destroy')"
class="btn-icon-primary"
name="delete"
outline
@click="Modal.switchDestroyModal(model)"
<!-- Selector de Roles Principales -->
<MainRoleSelector
v-if="selectedDepartment"
:selectedDepartment="selectedDepartment"
:mainRoles="mainRoles"
@select="handleRoleSelect"
/>
</div>
</td>
</tr>
</template>
<template #empty>
<td class="table-item border">
<div class="flex items-center text-sm">
<div>
<p class="font-semibold">
{{ $t("registers.empty") }}
</p>
</div>
</div>
</td>
<td class="table-item border">-</td>
<td class="table-item border">-</td>
</template>
</Table>
</div>
<EditView
v-if="can('edit')"
:show="editModal"
:model="modelModal"
@switchModal="Modal.switchShowEditModal"
@close="Modal.switchEditModal"
/>
<DestroyView
v-if="can('create')"
:show="destroyModal"
:model="modelModal"
@close="Modal.switchDestroyModal"
<SkillRole
v-if="selectedRole"
:mainRoleSkills="filteredMainRoleSkills"
:selectedRole="selectedRole"
@select="handleSkillSelect"
/>
</DashboardLayout>
</template>

View File

@ -59,7 +59,7 @@ const submit = () =>
required
/>
<Input
id="Descrición"
id="Descripción"
class="col-span-2"
v-model="form.description"
:onError="form.errors.description"