Files
FE_CPONE/test/vuex/one-md-counter-service/components/oneMdCounterService.vue
2026-04-27 10:13:31 +07:00

844 lines
26 KiB
Vue

<template>
<v-layout>
<!-- Alert Delete -->
<v-dialog v-model="dialogdeletealert" max-width="30%">
<v-card>
<v-card-title class="headline grey lighten-2 pt-2 pb-2" primary-title>
Peringatan !
</v-card-title>
<v-card-text class="pt-2 pb-2">
<v-layout row>
<v-flex xs12 d-flex>
<v-layout row>
<v-flex pb-1 xs12>
<v-layout row>
<v-flex pt-2 pr-2 xs12>
{{ msgalert }}
</v-flex>
</v-layout>
</v-flex>
</v-layout>
</v-flex>
</v-layout>
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary" flat @click="dialogdeletealert = false">
Tutup
</v-btn>
<v-btn color="primary" flat @click="deleteCounter()">
Yakin lah
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<!-- End alert delete -->
<!-- ERROR DIALOG -->
<v-dialog v-model="dialog_error" max-width="500px">
<v-card>
<v-card-title>
<span>ERROR !</span>
<v-spacer></v-spacer>
</v-card-title>
<v-divider></v-divider>
<div class="ma-3 red--text">{{ error_message }}</div>
<v-divider></v-divider>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary" flat @click="dialog_error = false"
>Close</v-btn
>
</v-card-actions>
</v-card>
</v-dialog>
<!-- END ERROR DIALOG -->
<!-- Snackbar -->
<v-snackbar
v-model="snackbar"
:timeout="5000"
:multi-line="false"
:vertical="false"
:top="true"
:color="clr"
:value="snackbar"
>
{{ success_message }}
<v-btn flat @click="snackbar = false"> Tutup </v-btn>
</v-snackbar>
<!-- End Snackbar -->
<!-- Dialog Form-->
<v-dialog v-model="dialog_form" persistent width="40%">
<v-card>
<v-card-title class="headline lighten-2 pt-2 pb-2" primary-title>
<div>Form Data Counter Service</div>
</v-card-title>
<v-divider v-if="!saveStatus"></v-divider>
<v-progress-linear
:indeterminate="true"
v-if="saveStatus"
></v-progress-linear>
<v-card-text class="pt-2 pb-2">
<v-text-field
outline
v-model="code"
label="Kode*"
required
:error="codeErrorMessage !== ''"
:error-messages="codeErrorMessage"
@blur="codeValidation"
></v-text-field>
<v-text-field
outline
v-model="ipAddress"
label="Alamat IP*"
required
:error="ipErrorMessage !== ''"
:error-messages="ipErrorMessage"
@blur="ipValidation"
></v-text-field>
<v-select
outline
v-model="selectedLocation"
label="Lokasi"
:items="location"
return-object
autocomplete
clearable="clearable"
item-text="locationName"
:error="locationErrorMessage !== ''"
:error-messages="locationErrorMessage"
@blur="locationValidation"
></v-select>
<v-text-field
outline
v-model="maxQueue"
label="Maksimal Antrian*"
required
:error="maxQueueErrorMessage !== ''"
:error-messages="maxQueueErrorMessage"
type="number"
@blur="maxQueueValidation"
></v-text-field>
<v-radio-group v-model="isDedicated" class="mt-0">
<template v-slot:label>
<div>Counter dikhususkan untuk layanan</div>
</template>
<v-radio value="Y">
<template v-slot:label>
<div>Ya</div>
</template>
</v-radio>
<v-radio value="N">
<template v-slot:label>
<div>Tidak</div>
</template>
</v-radio>
</v-radio-group>
<div v-if="isDedicated === 'Y'">
<v-select
v-model="selectedService"
:items="service"
item-text="serviceID"
return-object
chips
autocomplete
label="Pilih Layanan"
multiple
outline
clearable="clearable"
:error="ServiceErrorMessage !== ''"
:error-messages="ServiceErrorMessage"
@blur="serviceValidation"
>
<template slot="item" slot-scope="data">
{{ data.item.serviceName }} {{ data.item.serviceDoctorName }}
</template>
<template slot="selection" slot-scope="data">
<v-chip
>{{ data.item.serviceName }}
{{ data.item.serviceDoctorName }}</v-chip
>
</template>
</v-select>
</div>
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="primary"
flat
@click="closeDialog()"
:disabled="buttonDisable"
>
Tutup
</v-btn>
<v-btn
v-if="act === 'add'"
color="primary"
flat
:disabled="buttonDisable"
@click="addCounterService()"
>
Simpan
</v-btn>
<v-btn
v-if="act === 'edit'"
color="primary"
@click="saveEditCounter"
flat
:disabled="buttonDisable"
>
Simpan Perubahan
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<!-- End dialog form -->
<v-flex xs12>
<v-card>
<!-- Toolbar -->
<v-toolbar
color="blue darken-1"
dark
scroll-off-screen
scroll-target="#scrolling-techniques"
>
<v-toolbar-title class="headline font-weight-bold"
>COUNTER LAYANAN [IP anda : {{ own_ip }}]</v-toolbar-title
>
<v-spacer></v-spacer>
<div>
<v-btn icon @click="openFormAdd()"
><v-icon>library_add</v-icon></v-btn
>
</div>
</v-toolbar>
<!-- End Toolbar -->
<!-- Search area -->
<v-card elevation="0" style="height: 100px !important">
<v-card-text>
<v-flex xs3>
<v-text-field
v-model="xsearch"
label="Cari"
placeholder="Ketikkan Kode atau IP atau lokasi "
outline
hide-details
></v-text-field>
</v-flex>
</v-card-text>
</v-card>
<v-divider></v-divider>
<!-- End Search Area -->
<v-layout row>
<!-- DATA TABEL -->
<v-flex xs8>
<div
id="scrolling-techniques"
class="scroll-y"
:style="{ height: windowHeight }"
>
<v-data-table
:headers="headers"
:loading="isLoading"
:items="getCounterService"
hide-actions
>
<template v-slot:headers="props">
<tr style="height: 48px !important">
<th
v-for="header in props.headers"
:key="header.text"
:width="header.width"
@click="changeSort(header.value, sorting.type, header)"
>
<v-icon
color="blue darken-2"
v-if="
sorting.sortBy === header.value &&
header.sort &&
sorting.type == 'desc'
"
small
>arrow_upward</v-icon
>
<v-icon
color="blue darken-2"
v-if="
sorting.sortBy === header.value &&
header.sort &&
sorting.type == 'asc'
"
small
>arrow_downward</v-icon
>
<v-icon
color="grey lighten-2"
v-if="sorting.sortBy !== header.value && header.sort"
small
>arrow_downward</v-icon
>
{{ header.text }}
</th>
</tr>
</template>
<v-progress-linear
v-slot:progress
color="blue"
indeterminate
></v-progress-linear>
<template v-slot:no-data>
<v-alert :value="true" color="error" icon="warning">
Belum ditemukan data
</v-alert>
</template>
<template v-slot:items="props">
<td
class="text-xs-center pa-2 pl-3"
@click="selectMe(props.item)"
v-bind:class="{ 'blue lighten-5': isSelected(props.item) }"
>
{{ props.item.code }}
</td>
<td
class="text-xs-left pa-2 pl-3"
@click="selectMe(props.item)"
v-bind:class="{ 'blue lighten-5': isSelected(props.item) }"
>
{{ props.item.IP }}
</td>
<td
class="text-xs-center pa-2 pl-3"
@click="selectMe(props.item)"
v-bind:class="{ 'blue lighten-5': isSelected(props.item) }"
>
{{ props.item.isDedicated }}
</td>
<td
class="text-xs-center pa-2 pl-3"
@click="selectMe(props.item)"
v-bind:class="{ 'blue lighten-5': isSelected(props.item) }"
>
{{ props.item.maxQueue }}
</td>
<td
class="text-xs-left pa-2 pl-3"
@click="selectMe(props.item)"
v-bind:class="{ 'blue lighten-5': isSelected(props.item) }"
>
{{ props.item.locationName }}
</td>
<td
class="text-xs-left pa-2"
@click="selectMe(props.item)"
v-bind:class="{ 'blue lighten-5': isSelected(props.item) }"
>
<v-toolbar flat dense>
<v-btn
small
color="primary"
dark
@click="openEditForm(props.item)"
>ubah<v-icon small right dark>edit</v-icon></v-btn
>
<v-divider vertical></v-divider>
<v-btn
small
color="danger"
dark
@click="confirmDelete(props.item)"
>hapus <v-icon small right dark>clear</v-icon></v-btn
>
</v-toolbar>
</td>
</template>
</v-data-table>
</div>
</v-flex>
<!-- END DATA TABEL -->
<v-divider vertical></v-divider>
<!-- BAGIAN LAYANAN -->
<v-flex xs5>
<div style="overflow-y: auto" :style="{ height: windowHeight }">
<v-tabs grow :hide-slider="true" class="white--text">
<V-tab
style="height: 47px !important"
v-if="
Object.keys(selected_item).length === 0 &&
selected_item.constructor === Object
"
>COUNTER : [BELUM MEMILIH COUNTER]</V-tab
>
<V-tab
style="height: 47px !important"
v-if="
!(
Object.keys(selected_item).length === 0 &&
selected_item.constructor === Object
)
"
>COUNTER : {{ selected_item.code }}</V-tab
>
</v-tabs>
<v-divider></v-divider>
<v-tabs-items>
<v-tab-item>
<v-card-text>
<v-alert
:value="true"
color="info"
icon="info"
outline
v-if="selected_item.details?.length === 0"
>
melayani semua layanan yang ada
</v-alert>
<v-card
class="mb-2"
v-if="selected_item.details?.length > 0"
v-for="(details, kr) in selected_item.details"
:key="kr"
>
<v-alert
:value="true"
color="success"
icon="check_circle"
outline
>
{{ details.serviceName }}
{{ details.serviceDoctorName }}
</v-alert>
</v-card>
</v-card-text>
</v-tab-item>
</v-tabs-items>
</div>
</v-flex>
<!-- END BAGIAN LAYANAN -->
</v-layout>
<!-- PAGINATION -->
<v-divider></v-divider>
<v-flex xs12 class="text-xs-left pt-3 pb-3">
<v-pagination
v-model="curr_page"
:length="xtotal_page"
></v-pagination>
</v-flex>
<!-- End Pagination -->
</v-card>
</v-flex>
</v-layout>
</template>
<script>
module.exports = {
data() {
return {
windowHeight: window.innerHeight - 360 + "px",
clr: "success",
code: "",
ipAddress: "",
selectedLocation: {},
isDedicated: "N",
selectedService: [],
act: "",
serviceError: false,
codeErrorMessage: "",
ipErrorMessage: "",
locationErrorMessage: "",
ServiceErrorMessage: "",
buttonDisable: false,
counterServiceID: 0,
isDetectedBefore: "N",
dialogdeletealert: false,
msgalert: "",
maxQueue: "",
maxQueueErrorMessage: "",
headers: [
{
text: "KODE",
align: "center",
sortable: false,
sort: true,
value: "counterCode",
width: "15%",
class: "pa-2 blue darken-3 white--text",
},
{
text: "IP",
align: "center",
sortable: false,
sort: true,
value: "counterIP",
width: "30%",
class: "pa-2 blue darken-3 white--text",
},
{
text: "LAYANAN",
align: "center",
sortable: false,
sort: true,
value: "counterIsDedicated",
width: "5%",
class: "pa-2 blue darken-3 white--text",
},
{
text: "MAKSIMAL ANTRIAN",
align: "center",
sortable: false,
sort: true,
value: "counterMaxQueue",
width: "10%",
class: "pa-2 blue darken-3 white--text",
},
{
text: "LOKASI",
align: "center",
sortable: false,
sort: true,
value: "locationName",
width: "30%",
class: "pa-2 blue darken-3 white--text",
},
{
text: "AKSI",
align: "center",
sortable: false,
sort: false,
value: "r",
width: "10%",
class: "pa-2 blue darken-3 white--text",
},
],
};
},
mounted() {
this.$store.dispatch("counterService/lookup");
},
computed: {
getCounterService() {
return this.$store.state.counterService.counter_service;
},
isLoading() {
return this.$store.state.counterService.search_status;
},
sorting: {
get() {
return this.$store.state.counterService.sorting;
},
set(val) {
this.$store.commit("counterService/update_sorting", val);
},
},
selected_item: {
get() {
return this.$store.state.counterService.selected_item;
},
},
curr_page: {
get() {
return this.$store.state.counterService.current_page;
},
set(val) {
this.$store.commit("counterService/update_current_page", val);
this.$store.dispatch("counterService/lookup");
},
},
xtotal_page: {
get() {
return this.$store.state.counterService.total;
},
// set(val) {
// this.$store.commit("counterService/update_total_page", val);
// },
},
xsearch: {
get() {
return this.$store.state.counterService.x_search;
},
set(val) {
this.$store.commit("counterService/update_x_search", val);
},
},
snackbar: {
get() {
return this.$store.state.counterService.snackbar;
},
set(val) {
this.$store.commit("counterService/update_snackbar", val);
},
},
dialog_form: {
get() {
return this.$store.state.counterService.dialog_form;
},
set(val) {
this.$store.commit("counterService/update_dialog_form", val);
},
},
dialog_error: {
get() {
return this.$store.state.counterService.dialog_error;
},
set(val) {
this.$store.commit("counterService/update_dialog_error", val);
},
},
error_message() {
return this.$store.state.counterService.error_message;
},
success_message() {
return this.$store.state.counterService.success_message;
},
location() {
return this.$store.state.counterService.location;
},
service() {
return this.$store.state.counterService.service;
},
saveStatus() {
return this.$store.state.counterService.save_status;
},
own_ip() {
return this.$store.state.counterService.ip_address;
},
last_id: {
get() {
return this.$store.state.counterService.last_id;
},
set(val) {
this.$store.commit("counterService/update_last_id", val);
},
},
},
methods: {
changeSort(value, sort, header) {
if (header.sort) {
var newVal = value;
var newSort = sort == "asc" ? "desc" : "asc";
if (newVal !== this.sorting.sortBy) newSort = "asc";
this.sorting = { type: newSort, sortBy: newVal };
this.$store.dispatch("counterService/lookup");
}
},
selectMe(sc) {
this.$store.commit("counterService/update_selected_item", sc);
},
isSelected(p) {
return p.id == this.selected_item.id;
},
thr_search: _.debounce(function () {
this.$store.dispatch("counterService/lookup");
}, 1000),
openFormAdd() {
this.resetForm();
this.$store.dispatch("counterService/getLocation");
this.$store.dispatch("counterService/getService");
this.act = "add";
this.dialog_form = true;
},
addCounterService() {
this.codeValidation();
this.ipValidation();
this.locationValidation();
this.serviceValidation();
this.maxQueueValidation();
let arrService = [];
this.selectedService.forEach((element) => {
arrService.push(element.serviceID);
});
prm = {
code: this.code,
ip: this.ipAddress,
isDedicated: this.isDedicated,
locationId: this.selectedLocation.locationID,
service: arrService,
maxQueue: this.maxQueue,
};
console.log(prm);
if (
this.codeErrorMessage === "" &&
this.ipErrorMessage === "" &&
this.locationErrorMessage === "" &&
this.isDedicated === "N" &&
this.maxQueueErrorMessage === ""
) {
this.buttonDisable = true;
this.$store.dispatch("counterService/addData", prm);
} else if (
this.codeErrorMessage === "" &&
this.ipErrorMessage === "" &&
this.locationErrorMessage === "" &&
this.ServiceErrorMessage === "" &&
this.isDedicated === "Y" &&
this.maxQueueErrorMessage === ""
) {
this.buttonDisable = true;
this.$store.dispatch("counterService/addData", prm);
}
},
codeValidation() {
if (!this.code) {
this.codeErrorMessage = "Kode harus diisi";
}
if (this.code) {
this.codeErrorMessage = "";
}
},
ipValidation() {
if (!this.ipAddress) {
this.ipErrorMessage = "Alamat IP harus diisi";
}
if (this.ipAddress) {
this.ipErrorMessage = "";
}
},
maxQueueValidation() {
if (!this.maxQueue) {
this.maxQueueErrorMessage = "Maksimal antrian harus diisi";
}
if (this.maxQueue) {
this.maxQueueErrorMessage = "";
}
},
locationValidation() {
if (!this.selectedLocation) {
this.locationErrorMessage = "Pilih salah satu lokasi*";
}
if (this.selectedLocation) {
this.locationErrorMessage = "";
}
},
serviceValidation() {
if (!this.selectedService || this.selectedLocation === undefined) {
this.serviceError = true;
this.ServiceErrorMessage = "Pilih salah satu Layanan";
}
if (
this.selectedService.length === 0 ||
this.selectedLocation === undefined
) {
this.ServiceErrorMessage = "Pilih salah satu layanan";
this.serviceError = true;
}
if (this.selectedService.length > 0) {
this.serviceError = false;
this.ServiceErrorMessage = "";
}
},
resetForm() {
this.buttonDisable = false;
this.codeErrorMessage = "";
this.ipErrorMessage = "";
this.locationErrorMessage = "";
this.ServiceErrorMessage = "";
this.maxQueueErrorMessage = "";
this.maxQueue = "";
this.code = "";
this.ipAddress = "";
this.selectedLocation = {};
this.selectedService = [];
},
openEditForm(data) {
this.$store.dispatch("counterService/getLocation");
this.$store.dispatch("counterService/getService");
this.act = "edit";
this.selectMe(data);
this.resetForm();
this.buttonDisable = false;
this.counterServiceID = data.id;
this.code = data.code;
this.ipAddress = data.IP;
this.isDedicated = data.isDedicated;
this.isDetectedBefore = data.isDedicated;
this.maxQueue = data.maxQueue;
this.selectedLocation = {
locationID: data.locationId,
locationName: data.locationName,
};
this.selectedService = data.details;
this.dialog_form = true;
},
saveEditCounter() {
this.codeValidation();
this.ipValidation();
this.locationValidation();
this.serviceValidation();
this.maxQueueValidation();
prm = {
id: this.counterServiceID,
code: this.code,
ip: this.ipAddress,
isDedicated: this.isDedicated,
isDedicatedBefore: this.isDetectedBefore,
locationId: this.selectedLocation.locationID,
service: this.selectedService,
maxQueue: this.maxQueue,
};
if (
this.codeErrorMessage === "" &&
this.ipErrorMessage === "" &&
this.locationErrorMessage === "" &&
this.isDedicated === "N" &&
this.maxQueueErrorMessage === ""
) {
this.last_id = this.counterServiceID;
this.buttonDisable = true;
this.$store.dispatch("counterService/editData", prm);
} else if (
this.codeErrorMessage === "" &&
this.ipErrorMessage === "" &&
this.locationErrorMessage === "" &&
this.ServiceErrorMessage === "" &&
this.isDedicated === "Y" &&
this.maxQueueErrorMessage === ""
) {
this.last_id = this.counterServiceID;
this.buttonDisable = true;
this.$store.dispatch("counterService/editData", prm);
}
},
confirmDelete(data) {
this.selectMe(data);
this.msgalert = "Yakin, mau hapus counter " + data.code + " ?";
this.dialogdeletealert = true;
},
deleteCounter() {
prm = {
id: this.selected_item.id,
isDedicated: this.selected_item.isDedicated,
code: this.selected_item.code,
};
this.$store.dispatch("counterService/deleteData", prm);
this.dialogdeletealert = false;
},
closeDialog() {
this.codeErrorMessage = "";
this.ipErrorMessage = "";
this.locationErrorMessage = "";
this.ServiceErrorMessage = "";
this.maxQueueErrorMessage = "";
this.isDedicated = "N";
this.dialog_form = false;
},
},
watch: {
xsearch(val, old) {
this.xsearch = val;
this.thr_search();
},
},
};
</script>