ui ประวัติการศึกษา

This commit is contained in:
Kittapath 2023-03-16 00:35:08 +07:00
parent 792f30d606
commit 0157bf51b9
46 changed files with 1500 additions and 1642 deletions

View file

@ -0,0 +1,126 @@
<template>
<q-card-actions class="text-primary q-py-sm">
<q-btn
flat
round
icon="mdi-menu-left"
@click="clickPrevious"
v-if="modalEdit == true"
:disable="previous == false"
:color="!previous ? 'grey-7' : 'public'"
/>
<q-btn
flat
round
icon="mdi-menu-right"
@click="clickNext"
v-if="modalEdit == true"
:disable="next == false"
:color="!next ? 'grey-7' : 'public'"
/>
<q-space />
<q-btn
v-if="!editvisible"
flat
round
:disabled="editvisible"
:color="editvisible ? 'grey-7' : 'primary'"
@click="edit"
icon="mdi-pencil-outline"
>
<q-tooltip>แกไขขอม</q-tooltip>
</q-btn>
<div v-else>
<q-btn
flat
round
:disabled="!editvisible"
:outline="!editvisible"
:color="!editvisible ? 'grey-7' : 'red'"
@click="cancel()"
icon="mdi-undo"
v-if="modalEdit == true"
>
<q-tooltip>ยกเล</q-tooltip>
</q-btn>
<q-btn
flat
round
:disabled="!editvisible"
:color="!editvisible ? 'grey-7' : 'public'"
@click="checkSave"
icon="mdi-content-save-outline"
>
<q-tooltip>นท</q-tooltip>
</q-btn>
</div>
</q-card-actions>
</template>
<script setup lang="ts">
import { ref, useAttrs } from "vue";
const props = defineProps({
editvisible: Boolean,
next: Boolean,
previous: Boolean,
modalEdit: Boolean,
clickNext: {
type: Function,
default: () => console.log("not function"),
},
clickPrevious: {
type: Function,
default: () => console.log("not function"),
},
cancel: {
type: Function,
default: () => console.log("not function"),
},
edit: {
type: Function,
default: () => console.log("not function"),
},
save: {
type: Function,
default: () => console.log("not function"),
},
validate: {
type: Function,
default: () => console.log("not function"),
},
});
const emit = defineEmits([
"update:editvisible",
"update:next",
"update:previous",
]);
const updateEdit = (value: Boolean) => {
emit("update:editvisible", value);
};
const cancel = async () => {
props.cancel();
};
const edit = async () => {
updateEdit(!props.editvisible);
props.edit();
};
const checkSave = () => {
props.validate();
props.save();
// if (myForm.value !== null) {
// myForm.value.validate().then((success) => {
// if (success) {
// }
// });
// }
};
const clickNext = async () => {
await props.clickNext();
};
const clickPrevious = async () => {
await props.clickPrevious();
};
</script>

View file

@ -0,0 +1,32 @@
<template>
<q-card-section class="row items-center col-12 q-py-sm">
<div class="row col-11">
<div class="text-bold">{{ tittle }}</div>
</div>
<q-space />
<!-- <div class="row col-1"> -->
<q-btn
icon="close"
unelevated
round
dense
@click="close"
style="color: #ff8080; background-color: #ffdede"
/>
<!-- </div> -->
</q-card-section>
</template>
<script setup lang="ts">
import { ref, useAttrs } from "vue";
const props = defineProps({
tittle: String,
close: {
type: Function,
default: () => console.log("not function"),
},
});
const close = async () => {
props.close();
};
</script>

View file

@ -0,0 +1,92 @@
<template>
<q-dialog
:model-value="modalError"
persistent
@update:model-value="updateClose"
>
<q-card class="q-pa-sm">
<q-card-section class="row items-center">
<div class="q-pr-md">
<q-avatar
icon="mdi-alert-circle-outline"
font-size="25px"
size="lg"
color="red-1"
text-color="red"
/>
</div>
<div class="col text-dark">
<span class="text-bold">{{ modalErrorTittle }}</span>
<br />
<span>{{ modalErrorDetail }}</span>
</div>
</q-card-section>
<q-card-actions align="right" class="bg-white text-teal">
<q-btn
label="ตกลง"
color="primary"
@click="updateClose"
v-close-popup
/>
</q-card-actions>
</q-card>
</q-dialog>
</template>
<script setup lang="ts">
import { ref, useAttrs } from "vue";
const props = defineProps({
modalError: Boolean,
modalErrorTittle: String,
modalErrorDetail: String,
close: {
type: Function,
default: () => console.log("not function"),
},
});
const emit = defineEmits([
"update:modalError",
"update:modalErrorTittle",
"update:modalErrorDetail",
]);
const updateClose = () => {
emit("update:modalError", false);
emit("update:modalErrorTittle", "");
emit("update:modalErrorDetail", "");
props.close();
};
</script>
<style lang="scss">
.icon-color {
color: #4154b3;
}
.custom-header-table {
max-height: 64vh;
.q-table tr:nth-child(odd) td {
background: white;
}
.q-table tr:nth-child(even) td {
background: #f6f6f6ae;
}
.q-table thead tr {
background: #ecebeb;
}
.q-table thead tr th {
position: sticky;
z-index: 1;
}
/* this will be the loading indicator */
.q-table thead tr:last-child th {
/* height of all previous header rows */
top: 48px;
}
.q-table thead tr:first-child th {
top: 0;
}
}
</style>

199
src/components/Table.vue Normal file
View file

@ -0,0 +1,199 @@
<template>
<div class="q-pb-sm row">
<!-- -->
<HeaderTop
v-model:edit="editBtn"
:header="name"
:icon="icon"
:add="checkAdd"
:addData="true"
:history="false"
v-if="nameHeader"
/>
<q-btn size="12px" flat round color="add" @click="add" icon="mdi-plus">
<q-tooltip>เพมขอม</q-tooltip>
</q-btn>
<q-space />
<div class="items-center" style="display: flex">
<!-- นหาขอความใน table -->
<q-input
standout
dense
:model-value="inputfilter"
ref="filterRef"
@update:model-value="updateInput"
outlined
debounce="300"
placeholder="ค้นหา"
style="max-width: 200px"
class="q-ml-sm"
>
<template v-slot:append>
<q-icon v-if="inputfilter == ''" name="search" />
<q-icon
v-if="inputfilter !== ''"
name="clear"
class="cursor-pointer"
@click="resetFilter"
/>
</template>
</q-input>
<!-- แสดงคอลมนใน table -->
<q-select
:model-value="inputvisible"
@update:model-value="updateVisible"
:display-value="$q.lang.table.columns"
multiple
outlined
dense
:options="attrs.columns"
options-dense
option-value="name"
map-options
emit-value
style="min-width: 150px"
class="gt-xs q-ml-sm"
/>
</div>
</div>
<q-table
ref="table"
flat
bordered
class="custom-header-table"
v-bind="attrs"
virtual-scroll
:virtual-scroll-sticky-size-start="48"
dense
:pagination-label="paginationLabel"
:pagination="initialPagination"
:rows-per-page-options="[0]"
>
<template v-slot:header="props">
<q-tr :props="props">
<q-th v-for="col in props.cols" :key="col.name" :props="props">
<span class="text-weight-medium">{{ col.label }}</span>
</q-th>
</q-tr>
</template>
<template #body="props">
<slot v-bind="props" name="columns"></slot>
</template>
</q-table>
</template>
<script setup lang="ts">
import { ref, useAttrs } from 'vue'
import HeaderTop from '@/components/top.vue'
import type { Pagination } from '@/modules/01_exam/interface/index/Main'
const attrs = ref<any>(useAttrs())
const table = ref<any>(null)
const filterRef = ref<any>(null)
const editBtn = ref<boolean>(false)
const initialPagination = ref<Pagination>({
// descending: false,
rowsPerPage: 0
})
const props = defineProps({
inputfilter: String,
name: String,
icon: String,
inputvisible: Array,
editvisible: Boolean,
nameHeader: Boolean,
edit: {
type: Function,
default: () => console.log('not function')
},
add: {
type: Function,
default: () => console.log('not function')
},
cancel: {
type: Function,
default: () => console.log('not function')
},
validate: {
type: Function,
default: () => console.log('not function')
}
})
const emit = defineEmits(['update:inputfilter', 'update:inputvisible', 'update:editvisible'])
const updateEdit = (value: Boolean) => {
emit('update:editvisible', value)
}
const updateInput = (value: string | number | null) => {
emit('update:inputfilter', value)
}
const updateVisible = (value: []) => {
emit('update:inputvisible', value)
}
const paginationLabel = (start: string, end: string, total: string) => {
return start + '-' + end + ' ใน ' + total
}
const checkAdd = () => {
// props.validate();
props.add()
}
const edit = async () => {
updateEdit(!props.editvisible)
props.edit()
}
const cancel = async () => {
updateEdit(!props.editvisible)
props.cancel()
}
const resetFilter = () => {
// reset X
emit('update:inputfilter', '')
filterRef.value.focus()
}
const add = () => {
props.add()
}
</script>
<style lang="scss">
.icon-color {
color: #4154b3;
}
.custom-header-table {
max-height: 64vh;
.q-table tr:nth-child(odd) td {
background: white;
}
.q-table tr:nth-child(even) td {
background: #f6f6f6ae;
}
.q-table thead tr {
background: #ecebeb;
}
.q-table thead tr th {
position: sticky;
z-index: 1;
}
/* this will be the loading indicator */
.q-table thead tr:last-child th {
/* height of all previous header rows */
top: 48px;
}
.q-table thead tr:first-child th {
top: 0;
}
}
</style>

172
src/components/top.vue Normal file
View file

@ -0,0 +1,172 @@
<template>
<div class="flex items-center">
<div class="flex items-center">
<q-icon :name="icon" size="1.5em" color="grey-5" class="q-mr-md" />
<div
class="text-weight-medium text-dark col-12 row items-center text-header"
>
{{ header }}
</div>
</div>
<div class="q-gutter-sm q-mx-sm" v-if="addData == false">
<!-- <q-btn
dense
outline
label="แก้ไข"
icon="mdi-pencil-outline"
iconsize
v-if="!edit"
@click="ClickEdit"
>
<q-tooltip>แกไขขอม</q-tooltip>
</q-btn> -->
<q-btn
size="12px"
v-if="!edit"
flat
round
:disabled="edit"
:color="edit ? 'grey-7' : 'primary'"
@click="ClickEdit"
icon="mdi-pencil-outline"
>
<q-tooltip>แกไขขอม</q-tooltip>
</q-btn>
<!-- <q-btn
color="primary"
dense
label="บันทึก"
icon="mdi-content-save"
v-if="edit"
@click="save"
>
<q-tooltip>นทกขอม</q-tooltip>
</q-btn> -->
<q-btn
size="12px"
flat
round
v-if="edit"
:disabled="!edit"
:color="!edit ? 'grey-7' : 'public'"
@click="save"
icon="mdi-content-save-outline"
>
<q-tooltip>นทกขอม</q-tooltip>
</q-btn>
<!-- <q-btn
style="background: white; color: red"
dense
label="ยกเลิก"
icon="mdi-close-outline"
v-if="edit"
@click="ClickCancel"
>
<q-tooltip>ยกเล</q-tooltip>
</q-btn> -->
<q-btn
size="12px"
flat
round
v-if="edit"
:disabled="!edit"
:color="!edit ? 'grey-7' : 'red'"
@click="ClickCancel"
icon="mdi-undo"
>
<q-tooltip>ยกเล</q-tooltip>
</q-btn>
</div>
<div class="q-pl-sm" v-else>
<q-btn size="12px" flat round color="add" @click="add" icon="mdi-plus">
<q-tooltip>เพมขอม</q-tooltip>
</q-btn>
</div>
<q-space/>
<q-btn
color="info"
flat
dense
round
size="14px"
icon="mdi-history"
v-if="history"
>
<q-tooltip>ประว{{header}}</q-tooltip>
</q-btn>
</div>
</template>
<script setup lang="ts">
import { ref, useAttrs } from "vue";
const props = defineProps({
header: {
type: String,
default: "ข้อความ",
required: true,
},
icon: {
type: String,
default: "mdi-help",
required: true,
},
edit: {
type: Boolean,
default: true,
required: true,
},
history: {
type: Boolean,
default: true,
required: true,
},
addData: {
type: Boolean,
defualt: false,
},
add: {
type: Function,
default: () => console.log("not function"),
},
save: {
type: Function,
default: () => console.log("not function"),
},
deleted: {
type: Function,
default: () => console.log("not function"),
},
cancel: {
type: Function,
default: () => console.log("not function"),
},
});
const emit = defineEmits(["update:edit"]);
const updateEdit = (value: any) => {
emit("update:edit", value);
};
const ClickEdit = () => {
updateEdit(!props.edit);
};
const ClickCancel = () => {
updateEdit(!props.edit);
props.cancel();
};
const save = () => {
props.save();
};
const add = () => {
props.add();
};
</script>
<style scoped>
/* .q-btn >>> .q-icon {
font-size: 20px;
} */
</style>