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)
|
||||
->with([
|
||||
'mainRole:id,name,department_id',
|
||||
'mainRole.department:id,name',
|
||||
'skill:id,name',
|
||||
'score:id,alias'
|
||||
])
|
||||
@ -95,46 +96,56 @@ public function create()
|
||||
|
||||
public function store(StoreMainRoleSkills $request)
|
||||
{
|
||||
try {
|
||||
$create = [];
|
||||
foreach ($request['skills'] as $skill) {
|
||||
$create[] = [
|
||||
'main_role_id' => $request['main_role_id'],
|
||||
'skill_id' => $skill['skill_id'],
|
||||
'scored_id' => $skill['scored_id'],
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
];
|
||||
}
|
||||
$create = [];
|
||||
foreach ($request['skills'] as $skill) {
|
||||
$create[] = [
|
||||
'main_role_id' => $request['main_role_id'],
|
||||
'skill_id' => $skill['skill_id'],
|
||||
'scored_id' => $skill['scored_id'],
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
];
|
||||
}
|
||||
|
||||
MainRoleSkills::insert($create);
|
||||
MainRoleSkills::insert($create);
|
||||
|
||||
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;
|
||||
}
|
||||
return $this->index();
|
||||
}
|
||||
|
||||
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 {
|
||||
// Eliminar todas las habilidades asociadas a este rol principal
|
||||
MainRoleSkills::where('main_role_id', $mainRoleId)->delete();
|
||||
$mainRoleSkills = MainRoleSkills::findOrFail($id);
|
||||
|
||||
$mainRoleSkills->delete();
|
||||
|
||||
return $this->index();
|
||||
} catch (\Throwable $th) {
|
||||
Log::channel('mainRoleSkills')->error($th->getMessage());
|
||||
return response()->json(['error' => 'Error al eliminar las habilidades'], 500);
|
||||
Log::error($th->getMessage());
|
||||
return response()->json(['error' => 'Error al eliminar las habilidades']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,8 +32,6 @@ public function authorize()
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'main_role_id' => ['required', 'integer'],
|
||||
'skill_id' => ['required', 'integer'],
|
||||
'scored_id' => ['required', 'integer'],
|
||||
];
|
||||
}
|
||||
|
||||
@ -1,22 +1,34 @@
|
||||
<script setup>
|
||||
import { computed } from "vue";
|
||||
import { computed, ref } from "vue";
|
||||
import { Link } from "@inertiajs/vue3";
|
||||
import { can, goTo } from "@/Pages/Admin/MainRoleSkills/Component";
|
||||
|
||||
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 props = defineProps({
|
||||
mainRoleSkills: Array,
|
||||
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(() => {
|
||||
if (!props.mainRoleSkills || !props.selectedRole) {
|
||||
return [];
|
||||
}
|
||||
// Filtrar habilidades por rol seleccionado
|
||||
return props.mainRoleSkills.filter(
|
||||
(roleSkill) => roleSkill.main_role_id === props.selectedRole.id
|
||||
);
|
||||
@ -32,10 +44,13 @@ const roleSkills = computed(() => {
|
||||
</h2>
|
||||
<Link
|
||||
v-if="can('create')"
|
||||
:href="route(goTo('create'), {
|
||||
role_id: selectedRole.id,
|
||||
department_id: selectedRole.department?.id || selectedRole.department_id
|
||||
})"
|
||||
:href="
|
||||
route(goTo('create'), {
|
||||
role_id: selectedRole.id,
|
||||
department_id:
|
||||
selectedRole.department?.id || selectedRole.department_id,
|
||||
})
|
||||
"
|
||||
>
|
||||
<GoogleIcon
|
||||
:title="$t('crud.create')"
|
||||
@ -75,6 +90,22 @@ const roleSkills = computed(() => {
|
||||
>
|
||||
{{ roleSkill.skill.description }}
|
||||
</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>
|
||||
|
||||
@ -86,5 +117,19 @@ const roleSkills = computed(() => {
|
||||
Las habilidades se pueden asignar desde la sección de creación
|
||||
</p>
|
||||
</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>
|
||||
</template>
|
||||
|
||||
@ -46,31 +46,31 @@ const onRemove = () => {
|
||||
</script>
|
||||
|
||||
<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">
|
||||
{{title}} <span class="text-red-500" v-if="required">*</span> <slot name="label-icon" />
|
||||
</label>
|
||||
<VueMultiselect
|
||||
v-model="value"
|
||||
ref="multiselect"
|
||||
:options="options"
|
||||
:mode="mode"
|
||||
:close-on-select="true"
|
||||
:clear-on-select="false"
|
||||
:preserve-search="true"
|
||||
selectedLabel="Seleccionado"
|
||||
selectLabel="Seleccionar"
|
||||
deselectLabel="Remover"
|
||||
:placeholder="placeholder"
|
||||
:label="label"
|
||||
:track-by="trackBy"
|
||||
:required="required"
|
||||
@select="onChange"
|
||||
@remove="onRemove"
|
||||
>
|
||||
<template #noOptions>
|
||||
{{ $t('noRecords') }}
|
||||
</template>
|
||||
<VueMultiselect
|
||||
v-model="value"
|
||||
ref="multiselect"
|
||||
:options="options"
|
||||
:mode="mode"
|
||||
:close-on-select="true"
|
||||
:clear-on-select="false"
|
||||
:preserve-search="true"
|
||||
selectedLabel="Seleccionado"
|
||||
selectLabel="Seleccionar"
|
||||
deselectLabel="Remover"
|
||||
:placeholder="placeholder"
|
||||
:label="label"
|
||||
:track-by="trackBy"
|
||||
:required="required"
|
||||
@select="onChange"
|
||||
@remove="onRemove"
|
||||
>
|
||||
<template #noOptions>
|
||||
{{ $t('noRecords') }}
|
||||
</template>
|
||||
</VueMultiselect>
|
||||
<p v-show="onError" class="text-sm text-red-600">
|
||||
{{ onError }}
|
||||
|
||||
@ -26,7 +26,7 @@ const props = defineProps({
|
||||
</template>
|
||||
<template #content>
|
||||
<div class="w-full right-0 mt-2">
|
||||
<div class="rounded overflow-hidden">
|
||||
<div class="rounded">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -36,8 +36,7 @@ const destroy = (id) => router.delete(route(goTo('destroy'), {id}), {
|
||||
@destroy="destroy(model.id)"
|
||||
>
|
||||
<Header
|
||||
:title="model.name"
|
||||
:subtitle="model.description"
|
||||
:title="model.skill.name"
|
||||
/>
|
||||
</DestroyModal>
|
||||
</template>
|
||||
|
||||
@ -1,67 +1,87 @@
|
||||
<script setup>
|
||||
import { goTo } from './Component';
|
||||
import { useForm } from '@inertiajs/vue3';
|
||||
import { onUpdated } from 'vue';
|
||||
import { goTo } from "./Component";
|
||||
import { router, useForm } from "@inertiajs/vue3";
|
||||
|
||||
import Input from '@/Components/Dashboard/Form/Input.vue';
|
||||
import EditModal from '@/Components/Dashboard/Modal/Edit.vue';
|
||||
import Header from '@/Components/Dashboard/Modal/Elements/Header.vue';
|
||||
import Selectable from "@/Components/Dashboard/Form/Selectable.vue";
|
||||
import EditModal from "@/Components/Dashboard/Modal/Edit.vue";
|
||||
import Header from "@/Components/Dashboard/Modal/Elements/Header.vue";
|
||||
|
||||
const emit = defineEmits([
|
||||
'close',
|
||||
'switchModal'
|
||||
]);
|
||||
const emit = defineEmits(["close", "switchModal"]);
|
||||
|
||||
const props = defineProps({
|
||||
show: Boolean,
|
||||
model: Object
|
||||
show: Boolean,
|
||||
model: Object,
|
||||
scores: Array,
|
||||
});
|
||||
|
||||
const form = useForm({});
|
||||
const form = useForm({
|
||||
scored_id: "",
|
||||
});
|
||||
|
||||
const update = (id) => {
|
||||
form.transform(data => ({
|
||||
...props.model
|
||||
})).put(route(goTo('update'), {id}),{
|
||||
preserveScroll: true,
|
||||
onSuccess: () => {
|
||||
Notify.success(lang('updated'))
|
||||
emit('switchModal')
|
||||
}
|
||||
form
|
||||
.transform((data) => ({
|
||||
scored_id:
|
||||
typeof data.scored_id === "object" ? data.scored_id.id : data.scored_id,
|
||||
}))
|
||||
.put(route(goTo("update"), { id }), {
|
||||
preserveScroll: true,
|
||||
onSuccess: () => {
|
||||
Notify.success(lang("updated"));
|
||||
emit("switchModal");
|
||||
router.reload();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<EditModal
|
||||
:show="show"
|
||||
@close="$emit('close')"
|
||||
@update="update(model.id)"
|
||||
>
|
||||
<Header
|
||||
:title="model.name"
|
||||
/>
|
||||
<div class="py-2 border-b">
|
||||
<div class="p-4">
|
||||
<form>
|
||||
<div class="grid gap-6 mb-6 lg:grid-cols-2">
|
||||
<Input
|
||||
id="Nombre"
|
||||
placeholder="name"
|
||||
v-model="model.name"
|
||||
:onError="form.errors.name"
|
||||
required
|
||||
/>
|
||||
<Input
|
||||
id="Descripción"
|
||||
v-model="model.description"
|
||||
:onError="form.errors.description"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
<EditModal :show="show" @close="$emit('close')" @update="update(model.id)">
|
||||
<Header :title="model.main_role?.name" />
|
||||
<div class="py-2 border-b">
|
||||
<div class="p-4">
|
||||
<form>
|
||||
<div class="grid gap-6 mb-6 overflow-auto">
|
||||
<div class="bg-gray-50 p-4 rounded-lg">
|
||||
<h4 class="bg-gray-50 text-gray-700 mb-2 font-medium">
|
||||
Información:
|
||||
</h4>
|
||||
<div class="text-sm text-gray-600 space-y-1">
|
||||
<p>
|
||||
<span class="font-medium">Rol: </span
|
||||
>{{ model.main_role?.name }}
|
||||
</p>
|
||||
<p>
|
||||
<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>
|
||||
</EditModal>
|
||||
|
||||
<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
|
||||
/>
|
||||
<p class="text-xs text-gray-500 mt-1">
|
||||
Puntuación actual:
|
||||
<span class="font-medium"> {{ model.score?.alias }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</EditModal>
|
||||
</template>
|
||||
|
||||
@ -85,6 +85,7 @@ const goBack = () => {
|
||||
v-if="selectedRole"
|
||||
:mainRoleSkills="filteredMainRoleSkills"
|
||||
:selectedRole="selectedRole"
|
||||
:scores="scores"
|
||||
@select="handleSkillSelect"
|
||||
/>
|
||||
</DashboardLayout>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user