Habilidades puntuadas terminado
This commit is contained in:
parent
24a1e18dc3
commit
d96348bbf6
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"tabWidth": 2,
|
|
||||||
"useTabs": false
|
|
||||||
}
|
|
||||||
@ -43,6 +43,7 @@ public function index()
|
|||||||
->orWhereIn('scored_id', $scores)
|
->orWhereIn('scored_id', $scores)
|
||||||
->with([
|
->with([
|
||||||
'mainRole:id,name,department_id',
|
'mainRole:id,name,department_id',
|
||||||
|
'mainRole.department:id,name',
|
||||||
'skill:id,name',
|
'skill:id,name',
|
||||||
'score:id,alias'
|
'score:id,alias'
|
||||||
])
|
])
|
||||||
@ -95,7 +96,6 @@ public function create()
|
|||||||
|
|
||||||
public function store(StoreMainRoleSkills $request)
|
public function store(StoreMainRoleSkills $request)
|
||||||
{
|
{
|
||||||
try {
|
|
||||||
$create = [];
|
$create = [];
|
||||||
foreach ($request['skills'] as $skill) {
|
foreach ($request['skills'] as $skill) {
|
||||||
$create[] = [
|
$create[] = [
|
||||||
@ -110,31 +110,42 @@ public function store(StoreMainRoleSkills $request)
|
|||||||
MainRoleSkills::insert($create);
|
MainRoleSkills::insert($create);
|
||||||
|
|
||||||
return $this->index();
|
return $this->index();
|
||||||
|
|
||||||
} catch (\Illuminate\Database\QueryException $e) {
|
|
||||||
// Si hay error de restricción única
|
|
||||||
if ($e->getCode() === '23000') {
|
|
||||||
return back()->withErrors(['skills' => 'Una o más habilidades ya están asignadas a este rol.']);
|
|
||||||
}
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update(UpdateMainRoleSkills $request, MainRoleSkills $mainRoleSkills)
|
public function edit(MainRoleSkills $mainRoleSkills)
|
||||||
{
|
{
|
||||||
$mainRoleSkills->update($request->all());
|
$mainRoleSkills->load(['mainRole.department', 'skill.department', 'score']);
|
||||||
|
$scores = Score::orderBy('alias', 'ASC')->get();
|
||||||
|
|
||||||
|
return $this->vuew('edit', [
|
||||||
|
'mainRoleSkills' => $mainRoleSkills,
|
||||||
|
'scores' => $scores,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function destroy($mainRoleId)
|
|
||||||
|
public function update(UpdateMainRoleSkills $request, $id)
|
||||||
|
{
|
||||||
|
$mainRoleSkills = MainRoleSkills::findOrFail($id);
|
||||||
|
|
||||||
|
$mainRoleSkills->update([
|
||||||
|
'scored_id' => $request->scored_id,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return redirect()->back();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy($id)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
// Eliminar todas las habilidades asociadas a este rol principal
|
$mainRoleSkills = MainRoleSkills::findOrFail($id);
|
||||||
MainRoleSkills::where('main_role_id', $mainRoleId)->delete();
|
|
||||||
|
$mainRoleSkills->delete();
|
||||||
|
|
||||||
return $this->index();
|
return $this->index();
|
||||||
} catch (\Throwable $th) {
|
} catch (\Throwable $th) {
|
||||||
Log::channel('mainRoleSkills')->error($th->getMessage());
|
Log::error($th->getMessage());
|
||||||
return response()->json(['error' => 'Error al eliminar las habilidades'], 500);
|
return response()->json(['error' => 'Error al eliminar las habilidades']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,8 +32,6 @@ public function authorize()
|
|||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'main_role_id' => ['required', 'integer'],
|
|
||||||
'skill_id' => ['required', 'integer'],
|
|
||||||
'scored_id' => ['required', 'integer'],
|
'scored_id' => ['required', 'integer'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,22 +1,34 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { computed } from "vue";
|
import { computed, ref } from "vue";
|
||||||
import { Link } from "@inertiajs/vue3";
|
import { Link } from "@inertiajs/vue3";
|
||||||
import { can, goTo } from "@/Pages/Admin/MainRoleSkills/Component";
|
import { can, goTo } from "@/Pages/Admin/MainRoleSkills/Component";
|
||||||
|
|
||||||
import GoogleIcon from "@/Components/Shared/GoogleIcon.vue";
|
import GoogleIcon from "@/Components/Shared/GoogleIcon.vue";
|
||||||
|
import ModalController from "@/Controllers/ModalController.js";
|
||||||
|
import DestroyView from "@/Pages/Admin/MainRoleSkills/Destroy.vue";
|
||||||
|
import EditView from '@/Pages/Admin/MainRoleSkills/Edit.vue';
|
||||||
|
|
||||||
const emit = defineEmits(["select"]);
|
const emit = defineEmits(["select"]);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
mainRoleSkills: Array,
|
mainRoleSkills: Array,
|
||||||
selectedRole: Object,
|
selectedRole: Object,
|
||||||
|
scores: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Controlador de modal
|
||||||
|
const Modal = new ModalController();
|
||||||
|
const destroyModal = ref(Modal.destroyModal);
|
||||||
|
const editModal = ref(Modal.editModal);
|
||||||
|
const modelModal = ref(Modal.modelModal);
|
||||||
|
|
||||||
const roleSkills = computed(() => {
|
const roleSkills = computed(() => {
|
||||||
if (!props.mainRoleSkills || !props.selectedRole) {
|
if (!props.mainRoleSkills || !props.selectedRole) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
// Filtrar habilidades por rol seleccionado
|
|
||||||
return props.mainRoleSkills.filter(
|
return props.mainRoleSkills.filter(
|
||||||
(roleSkill) => roleSkill.main_role_id === props.selectedRole.id
|
(roleSkill) => roleSkill.main_role_id === props.selectedRole.id
|
||||||
);
|
);
|
||||||
@ -32,10 +44,13 @@ const roleSkills = computed(() => {
|
|||||||
</h2>
|
</h2>
|
||||||
<Link
|
<Link
|
||||||
v-if="can('create')"
|
v-if="can('create')"
|
||||||
:href="route(goTo('create'), {
|
:href="
|
||||||
|
route(goTo('create'), {
|
||||||
role_id: selectedRole.id,
|
role_id: selectedRole.id,
|
||||||
department_id: selectedRole.department?.id || selectedRole.department_id
|
department_id:
|
||||||
})"
|
selectedRole.department?.id || selectedRole.department_id,
|
||||||
|
})
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<GoogleIcon
|
<GoogleIcon
|
||||||
:title="$t('crud.create')"
|
:title="$t('crud.create')"
|
||||||
@ -75,6 +90,22 @@ const roleSkills = computed(() => {
|
|||||||
>
|
>
|
||||||
{{ roleSkill.skill.description }}
|
{{ roleSkill.skill.description }}
|
||||||
</p>
|
</p>
|
||||||
|
<div class="flex items-center justify-end mt-4 gap-2">
|
||||||
|
<GoogleIcon
|
||||||
|
v-if="can('edit')"
|
||||||
|
:title="$t('crud.edit')"
|
||||||
|
class="btn-icon-danger w-6 h-6 bg-blue-500 text-white rounded hover:bg-blue-600"
|
||||||
|
name="edit"
|
||||||
|
@click.stop="Modal.switchEditModal(roleSkill)"
|
||||||
|
/>
|
||||||
|
<GoogleIcon
|
||||||
|
v-if="can('destroy')"
|
||||||
|
:title="$t('crud.destroy')"
|
||||||
|
class="btn-icon-danger w-6 h-6 bg-red-500 text-white rounded hover:bg-red-600"
|
||||||
|
name="delete"
|
||||||
|
@click.stop="Modal.switchDestroyModal(roleSkill)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -86,5 +117,19 @@ const roleSkills = computed(() => {
|
|||||||
Las habilidades se pueden asignar desde la sección de creación
|
Las habilidades se pueden asignar desde la sección de creación
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<EditView
|
||||||
|
v-if="can('edit')"
|
||||||
|
:show="editModal"
|
||||||
|
:model="modelModal"
|
||||||
|
:scores="scores"
|
||||||
|
@close="Modal.switchEditModal"
|
||||||
|
@switchModal="Modal.switchEditModal"
|
||||||
|
/>
|
||||||
|
<DestroyView
|
||||||
|
v-if="can('destroy')"
|
||||||
|
:show="destroyModal"
|
||||||
|
:model="modelModal"
|
||||||
|
@close="Modal.switchDestroyModal"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -46,7 +46,7 @@ const onRemove = () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col relative">
|
||||||
<label v-if="title" class="block mb-2 text-sm font-medium text-gray-900">
|
<label v-if="title" class="block mb-2 text-sm font-medium text-gray-900">
|
||||||
{{title}} <span class="text-red-500" v-if="required">*</span> <slot name="label-icon" />
|
{{title}} <span class="text-red-500" v-if="required">*</span> <slot name="label-icon" />
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
@ -26,7 +26,7 @@ const props = defineProps({
|
|||||||
</template>
|
</template>
|
||||||
<template #content>
|
<template #content>
|
||||||
<div class="w-full right-0 mt-2">
|
<div class="w-full right-0 mt-2">
|
||||||
<div class="rounded overflow-hidden">
|
<div class="rounded">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -36,8 +36,7 @@ const destroy = (id) => router.delete(route(goTo('destroy'), {id}), {
|
|||||||
@destroy="destroy(model.id)"
|
@destroy="destroy(model.id)"
|
||||||
>
|
>
|
||||||
<Header
|
<Header
|
||||||
:title="model.name"
|
:title="model.skill.name"
|
||||||
:subtitle="model.description"
|
|
||||||
/>
|
/>
|
||||||
</DestroyModal>
|
</DestroyModal>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -1,64 +1,84 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { goTo } from './Component';
|
import { goTo } from "./Component";
|
||||||
import { useForm } from '@inertiajs/vue3';
|
import { router, useForm } from "@inertiajs/vue3";
|
||||||
import { onUpdated } from 'vue';
|
|
||||||
|
|
||||||
import Input from '@/Components/Dashboard/Form/Input.vue';
|
import Selectable from "@/Components/Dashboard/Form/Selectable.vue";
|
||||||
import EditModal from '@/Components/Dashboard/Modal/Edit.vue';
|
import EditModal from "@/Components/Dashboard/Modal/Edit.vue";
|
||||||
import Header from '@/Components/Dashboard/Modal/Elements/Header.vue';
|
import Header from "@/Components/Dashboard/Modal/Elements/Header.vue";
|
||||||
|
|
||||||
const emit = defineEmits([
|
const emit = defineEmits(["close", "switchModal"]);
|
||||||
'close',
|
|
||||||
'switchModal'
|
|
||||||
]);
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
show: Boolean,
|
show: Boolean,
|
||||||
model: Object
|
model: Object,
|
||||||
|
scores: Array,
|
||||||
});
|
});
|
||||||
|
|
||||||
const form = useForm({});
|
const form = useForm({
|
||||||
|
scored_id: "",
|
||||||
|
});
|
||||||
|
|
||||||
const update = (id) => {
|
const update = (id) => {
|
||||||
form.transform(data => ({
|
form
|
||||||
...props.model
|
.transform((data) => ({
|
||||||
})).put(route(goTo('update'), {id}),{
|
scored_id:
|
||||||
|
typeof data.scored_id === "object" ? data.scored_id.id : data.scored_id,
|
||||||
|
}))
|
||||||
|
.put(route(goTo("update"), { id }), {
|
||||||
preserveScroll: true,
|
preserveScroll: true,
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
Notify.success(lang('updated'))
|
Notify.success(lang("updated"));
|
||||||
emit('switchModal')
|
emit("switchModal");
|
||||||
}
|
router.reload();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<EditModal
|
<EditModal :show="show" @close="$emit('close')" @update="update(model.id)">
|
||||||
:show="show"
|
<Header :title="model.main_role?.name" />
|
||||||
@close="$emit('close')"
|
|
||||||
@update="update(model.id)"
|
|
||||||
>
|
|
||||||
<Header
|
|
||||||
:title="model.name"
|
|
||||||
/>
|
|
||||||
<div class="py-2 border-b">
|
<div class="py-2 border-b">
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<form>
|
<form>
|
||||||
<div class="grid gap-6 mb-6 lg:grid-cols-2">
|
<div class="grid gap-6 mb-6 overflow-auto">
|
||||||
<Input
|
<div class="bg-gray-50 p-4 rounded-lg">
|
||||||
id="Nombre"
|
<h4 class="bg-gray-50 text-gray-700 mb-2 font-medium">
|
||||||
placeholder="name"
|
Información:
|
||||||
v-model="model.name"
|
</h4>
|
||||||
:onError="form.errors.name"
|
<div class="text-sm text-gray-600 space-y-1">
|
||||||
required
|
<p>
|
||||||
/>
|
<span class="font-medium">Rol: </span
|
||||||
<Input
|
>{{ model.main_role?.name }}
|
||||||
id="Descripción"
|
</p>
|
||||||
v-model="model.description"
|
<p>
|
||||||
:onError="form.errors.description"
|
<span class="font-medium">Departamento: </span>
|
||||||
|
{{ model.main_role?.department?.name }}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="font-medium">Habilidad: </span
|
||||||
|
>{{ model.skill?.name }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
Cambiar Puntuación
|
||||||
|
</label>
|
||||||
|
<Selectable
|
||||||
|
id="scored_id"
|
||||||
|
v-model="form.scored_id"
|
||||||
|
:options="scores"
|
||||||
|
:onError="form.errors.scored_id"
|
||||||
|
label="alias"
|
||||||
|
track-by="id"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
<p class="text-xs text-gray-500 mt-1">
|
||||||
|
Puntuación actual:
|
||||||
|
<span class="font-medium"> {{ model.score?.alias }}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -85,6 +85,7 @@ const goBack = () => {
|
|||||||
v-if="selectedRole"
|
v-if="selectedRole"
|
||||||
:mainRoleSkills="filteredMainRoleSkills"
|
:mainRoleSkills="filteredMainRoleSkills"
|
||||||
:selectedRole="selectedRole"
|
:selectedRole="selectedRole"
|
||||||
|
:scores="scores"
|
||||||
@select="handleSkillSelect"
|
@select="handleSkillSelect"
|
||||||
/>
|
/>
|
||||||
</DashboardLayout>
|
</DashboardLayout>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user