Flatten nested repos

This commit is contained in:
sas.fajri
2026-04-27 10:13:31 +07:00
parent 01c2963a43
commit 8347aef8f4
17935 changed files with 5015229 additions and 3 deletions

View File

View File

@@ -0,0 +1,31 @@
// API :
// search bank
// paramater : query , page , rowPerPage
const URL =
"http://lebaran.aplikasi.web.id/smartlab_api/vuex/t02/search_bank";
export async function searchBank(query, page, rowPerPage = 15) {
try {
var resp = await axios.post(URL, {
query: query,
page: page,
rowPerPage: rowPerPage
});
if (resp.status != 200) {
return {
status: "ERR",
query: query,
message: resp.statusText
};
}
let data = resp.data;
data.query = query;
return data;
} catch (e) {
return {
status: "ERR",
query: query,
message: e.message
};
}
}

View File

@@ -0,0 +1,69 @@
var dialogFormComponent = {
template: `
<template>
<v-layout row justify-center>
<v-dialog v-model="dialog" persistent max-width="500px">
<v-btn slot="activator" color="primary" dark>Open Dialog</v-btn>
<v-card>
<v-card-title>
<span class="headline">User Profile</span>
</v-card-title>
<v-card-text>
<v-container grid-list-md>
<v-layout wrap>
<v-flex xs12 sm6 md4>
<v-text-field label="Legal first name" required></v-text-field>
</v-flex>
<v-flex xs12 sm6 md4>
<v-text-field label="Legal middle name" hint="example of helper text only on focus"></v-text-field>
</v-flex>
<v-flex xs12 sm6 md4>
<v-text-field
label="Legal last name"
hint="example of persistent helper text"
persistent-hint
required
></v-text-field>
</v-flex>
<v-flex xs12>
<v-text-field label="Email" required></v-text-field>
</v-flex>
<v-flex xs12>
<v-text-field label="Password" type="password" required></v-text-field>
</v-flex>
<v-flex xs12 sm6>
<v-select
:items="['0-17', '18-29', '30-54', '54+']"
label="Age"
required
></v-select>
</v-flex>
<v-flex xs12 sm6>
<v-autocomplete
:items="['Skiing', 'Ice hockey', 'Soccer', 'Basketball', 'Hockey', 'Reading', 'Writing', 'Coding', 'Basejump']"
label="Interests"
multiple
chips
></v-autocomplete>
</v-flex>
</v-layout>
</v-container>
<small>*indicates required field</small>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" flat @click.native="dialog = false">Close</v-btn>
<v-btn color="blue darken-1" flat @click.native="dialog = false">Save</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-layout>
</template>
`,
data: () => ({
dialog: false
})
};
export { dialogFormComponent };

View File

@@ -0,0 +1,71 @@
var ioAlatComponent = {
template: `
<v-flex md3 xs6 class='p-io-alat'>
<v-card
class="mx-auto io-alat light-green lighten-4"
light
max-width="400"
>
<v-card-title >
<span class="title font-weight-light"> Title </span>
</v-card-title>
<v-card-text>
<div>
<span class="label">Port</span>
<span class="label-sep">:</span>
<span class="label-val">123</span>
</div>
<div>
<span class="label">Glu</span>
<span class="label-sep">:</span>
<span class="label-val">1023</span>
</div>
<div>
<span class="label">DB</span>
<span class="label-sep">:</span>
<span class="label-val">pdb</span>
</div>
<div>
<span class="label">LIS</span>
<span class="label-sep">:</span>
<span class="label-val">Enabled</span>
</div>
</v-card-text>
<v-card-actions class="action light-green lighten-1">
<v-spacer></v-spacer>
<v-icon color="#EFFCED" v-bind:class="true" >get_app</v-icon>
</v-card-actions>
</v-card>
</v-flex>
`,
data: function() {
return {}
},
methods: {},
components: {
SheetFooter: {
functional: true,
render(h, {
children
}) {
return h('v-sheet', {
staticClass: 'mt-auto align-center justify-center d-flex',
props: {
color: 'rgba(0, 0, 0, .36)',
dark: true,
height: 50
}
}, children)
}
}
}
}
export {
ioAlatComponent
};

View File

@@ -0,0 +1,139 @@
var listBankComponent = {
template: `
<v-card class="xs12 md12" >
<v-card-title>
<v-layout>
<v-flex xs12 sm8>
<v-toolbar-title>Bank Listing <v-btn depressed small color="primary">New Data</v-btn></v-toolbar-title>
</v-flex>
<v-flex xs12 sm4>
<v-spacer></v-spacer>
<v-text-field
v-model="query"
append-icon="search"
@click:clear="clearSearch"
@keydown.enter="doSearch"
@click:append="doSearch"
label="Search"
single-line
hide-details
clearable
class="xs12 md3"
></v-text-field>
</v-flex>
</v-layout>
</v-card-title>
<v-data-table :headers="headers" :items="banks"
:loading="isLoading"
hide-actions class="elevation-1">
<template slot="items" slot-scope="props">
<td class="text-xs-center">{{ props.item.M_BankCode }}</td>
<td>{{ props.item.M_BankName }}</td>
<td>{{ props.item.M_BankAddress }}</td>
<td>{{ props.item.M_BankBranch }}</td>
<td><v-btn depressed small color="info">Edit</v-btn> <v-btn depressed small color="error">Delete</v-btn></td>
</template>
<template slot="no-data">
<v-alert :value="isError" color="error" icon="warning">
{{errorMessage}}
</v-alert>
<v-spacer></v-spacer>
</template>
<template slot="footer">
<td colspan="2" class="text-xs-left">
Total Records : {{totalRecord}}, page {{page}} of {{totalPage}}.
</td>
<td colspan="3" class="text-xs-right">
<v-pagination :length="totalPage" :value="page" :total-visible="10"
@next="nextPage" @prev="prevPage"
@input="gotoPage" >
</v-pagination>
</td>
</template>
</v-data-table>
</v-card>
`,
mounted() {
this.doSearch();
},
data() {
return {
query: "",
headers: [{
text: "Code",
align: "left",
sortable: false,
value: "M_BankCode"
},
{
text: "Name",
align: "left",
sortable: false,
value: "M_BankName"
},
{
text: "Address",
value: "M_BankAddress",
sortable: false,
align: "left",
width: "30%"
},
{
text: "Branch",
value: "M_BankBranch",
sortable: false,
align: "left"
},
{
text: "Action",
value: "action",
sortable: false,
align: "center",
width: "20%"
}
]
};
},
methods: {
clearSearch() {
this.query = "";
this.doSearch();
},
doSearch(page = 1, rowPerPage = 8) {
if (this.query == null) this.query = "";
this.$store.dispatch("searchBank", {
query: this.query,
page,
rowPerPage
});
},
prevPage() {
let c_page = this.page - 1;
this.doSearch(c_page);
},
nextPage() {
let c_page = this.page + 1;
this.doSearch(c_page);
},
gotoPage(e) {
let c_page = e;
this.doSearch(c_page);
}
},
computed: {
...Vuex.mapState({
isLoading: state => state.isLoading,
isError: state => state.isError,
errorMessage: state => state.errorMessage,
banks: state => state.rows,
totalRecord: state => state.totalRecord,
page: state => state.page,
totalPage: state => state.totalPage
})
},
updated() {
console.log("Component Updated");
}
};
export { listBankComponent };

View File

@@ -0,0 +1,138 @@
var listPatientComponent = {
template: `
<v-card class="xs12 md12" >
<v-card-title>
<v-layout>
<v-flex xs12 sm8>
<v-toolbar-title>Patient Listing</v-toolbar-title>
</v-flex>
<v-flex xs12 sm4>
<v-spacer></v-spacer>
<v-text-field
v-model="query"
append-icon="search"
@click:clear="clearSearch"
@keydown.enter="doSearch"
@click:append="doSearch"
label="Search"
single-line
hide-details
clearable
class="xs12 md3"
></v-text-field>
</v-flex>
</v-layout>
</v-card-title>
<v-data-table :headers="headers" :items="patients"
:loading="isLoading"
hide-actions class="elevation-1">
<template slot="items" slot-scope="props">
<td>{{ props.item.M_PatientNoReg }}</td>
<td>{{ props.item.M_PatientName }}</td>
<td class="text-xs-center">{{ props.item.M_PatientDOB }}</td>
<td>{{ props.item.M_PatientHP }}</td>
<td>{{ props.item.M_PatientAddress }}</td>
</template>
<template slot="no-data">
<v-alert :value="isError" color="error" icon="warning">
{{errorMessage}}
</v-alert>
<v-spacer></v-spacer>
</template>
<template slot="footer">
<td colspan="2" class="text-xs-left">
Total Records : {{totalRecord}}, page {{page}} of {{totalPage}}.
</td>
<td colspan="3" class="text-xs-right">
<v-pagination :length="totalPage" :value="page" :total-visible="10"
@next="nextPage" @prev="prevPage"
@input="gotoPage" >
</v-pagination>
</td>
</template>
</v-data-table>
</v-card>
`,
mounted() {
this.doSearch();
},
data() {
return {
query: "",
headers: [
{
text: "No. Reg",
align: "left",
sortable: false,
value: "M_PatientNoReg"
},
{
text: "Name",
align: "left",
sortable: false,
value: "M_PatientName"
},
{
text: "DOB",
align: "center",
sortable: false,
value: "M_PatientDOB"
},
{
text: "HP",
value: "M_PatientHP",
sortable: false,
align: "left"
},
{
text: "Address",
value: "M_PatientAddress",
sortable: false,
align: "left"
}
]
};
},
methods: {
clearSearch() {
this.query = "";
this.doSearch();
},
doSearch(page = 1, rowPerPage = 8) {
if (this.query == null) this.query = "";
this.$store.dispatch("searchPatient", {
query: this.query,
page,
rowPerPage
});
},
prevPage() {
let c_page = this.page - 1;
this.doSearch(c_page);
},
nextPage() {
let c_page = this.page + 1;
this.doSearch(c_page);
},
gotoPage(e) {
let c_page = e;
this.doSearch(c_page);
}
},
computed: {
...Vuex.mapState({
isLoading: state => state.isLoading,
isError: state => state.isError,
errorMessage: state => state.errorMessage,
patients: state => state.rows,
totalRecord: state => state.totalRecord,
page: state => state.page,
totalPage: state => state.totalPage
})
},
updated() {
console.log("Component Updated");
}
};
export { listPatientComponent };

View File

@@ -0,0 +1,266 @@
var oneFormPatientComponent= {
template: `
<v-form ref="form" v-model="valid" lazy-validation >
<v-container>
<v-layout>
<v-flex xs12 >
<v-text-field
v-model="Nama"
:rules="namaRules"
label="Nama"
required
></v-text-field>
<v-text-field
v-model="Alamat"
:rules="alamatRules"
label="Alamat"
required
></v-text-field>
<v-text-field
v-model="Umur"
:rules="umurRules"
label="Umur"
required
></v-text-field>
<v-text-field
v-model="Riwayat"
:rules="riwayatRules"
label="Riwayat Pemeriksaan"
></v-text-field>
<v-select
v-model="select"
:items="items"
:rules="[v => !!v || 'Item is required']"
label="Item"
required
></v-select>
<v-checkbox
v-model="checkbox"
:rules="[v => !!v || 'You must agree to continue!']"
label="Do you agree?"
required
></v-checkbox>
<v-btn
:disabled="!valid"
color="success"
@click="validate"
>
Tambah Pasien
</v-btn>
<v-btn
color="error"
@click="reset"
>
Save
</v-btn>
<v-btn
color="warning"
@click="resetValidation"
>
Test
</v-btn>
<v-btn
:disabled="!valid"
color="success"
@click="validate"
>
Test
</v-btn>
<v-btn
color="error"
@click="reset"
>
Test
</v-btn>
<v-btn
color="warning"
@click="resetValidation"
>
Test
</v-btn>
<v-btn
color="warning"
@click="resetValidation"
>
Test
</v-btn>
<v-btn
:disabled="!valid"
color="success"
@click="validate"
>
Test
</v-btn>
<v-btn
color="error"
@click="reset"
>
Test
</v-btn>
<v-btn
color="warning"
@click="resetValidation"
>
Test
</v-btn>
<v-btn
color="warning"
@click="resetValidation"
>
Test
</v-btn>
<v-btn
:disabled="!valid"
color="success"
@click="validate"
>
Test
</v-btn>
<v-btn
color="error"
@click="reset"
>
Test
</v-btn>
<v-btn
color="warning"
@click="resetValidation"
>
Test
</v-btn>
<v-btn
color="warning"
@click="resetValidation"
>
Test
</v-btn>
<v-btn
:disabled="!valid"
color="success"
@click="validate"
>
Test
</v-btn>
<v-btn
color="error"
@click="reset"
>
Test
</v-btn>
<v-btn
color="warning"
@click="resetValidation"
>
Test
</v-btn>
<v-btn
color="warning"
@click="resetValidation"
>
Test
</v-btn>
<v-btn
:disabled="!valid"
color="success"
@click="validate"
>
Test
</v-btn>
<v-btn
color="error"
@click="reset"
>
Test
</v-btn>
<v-btn
color="warning"
@click="resetValidation"
>
Test
</v-btn>
</v-layout>
</v-container>
</v-form>
`,
data: function() {
return {
valid: true,
name: '',
nameRules: [
v => !!v || 'Name is required',
v => (v && v.length <= 10) || 'Name must be less than 10 characters'
],
email: '',
emailRules: [
v => !!v || 'E-mail is required',
v => /.+@.+/.test(v) || 'E-mail must be valid'
],
select: null,
items: [
'Item 1',
'Item 2',
'Item 3',
'Item 4'
],
checkbox: false
};
},
methods: {
validate () {
if (this.$refs.form.validate()) {
this.snackbar = true
}
},
reset () {
this.$refs.form.reset()
},
resetValidation () {
this.$refs.form.resetValidation()
}
}
};
export { oneFormPatientComponent };

View File

@@ -0,0 +1,165 @@
var oneListPatientComponent= {
template: `
<v-container>
<v-layout>
<v-data-table
v-model="selected"
:headers="headers"
:items="desserts"
:pagination.sync="pagination"
select-all
item-key="name"
class="elevation-1"
>
<template slot="headers" slot-scope="props">
<tr>
<th>
<v-checkbox
:input-value="props.all"
:indeterminate="props.indeterminate"
primary
hide-details
@click.stop="toggleAll"
></v-checkbox>
</th>
<th
v-for="header in props.headers"
:key="header.text"
:class="['column sortable', pagination.descending ? 'desc' : 'asc', header.value === pagination.sortBy ? 'active' : '']"
@click="changeSort(header.value)"
>
<v-icon small>arrow_upward</v-icon>
{{ header.text }}
</th>
</tr>
</template>
<template slot="items" slot-scope="props">
<tr :active="props.selected" @click="props.selected = !props.selected">
<td>
<v-checkbox
:input-value="props.selected"
primary
hide-details
></v-checkbox>
</td>
<td>{{ props.item.name }}</td>
<td class="text-xs-right">{{ props.item.calories }}</td>
<td class="text-xs-right">{{ props.item.fat }}</td>
<td class="text-xs-right">{{ props.item.carbs }}</td>
</tr>
</template>
</v-data-table>
</v-layout>
</v-container>
`,
data: function() {
return {
pagination: {
sortBy: 'name'
},
selected: [],
headers: [
{
text: 'Pemeriksaan',
align: 'left',
value: 'name'
},
{ text: 'Harga', value: 'calories' },
{ text: 'Diskon', value: 'fat' },
{ text: 'Total (g)', value: 'carbs' },
],
desserts: [
{
name: 'Frozen Yogurt',
calories: 159,
fat: 6.0,
carbs: 24,
},
{
name: 'Ice cream sandwich',
calories: 237,
fat: 9.0,
carbs: 37,
},
{
name: 'Eclair',
calories: 262,
fat: 16.0,
carbs: 23,
},
{
name: 'Cupcake',
calories: 305,
fat: 3.7,
carbs: 67,
},
{
name: 'Gingerbread',
calories: 356,
fat: 16.0,
carbs: 49,
},
{
name: 'Jelly bean',
calories: 375,
fat: 0.0,
carbs: 94,
},
{
name: 'Lollipop',
calories: 392,
fat: 0.2,
carbs: 98,
},
{
name: 'Honeycomb',
calories: 408,
fat: 3.2,
carbs: 87,
},
{
name: 'Donut',
calories: 452,
fat: 25.0,
carbs: 51,
},
{
name: 'KitKat',
calories: 518,
fat: 26.0,
carbs: 65,
}
]
};
},
methods: {
validate () {
if (this.$refs.form.validate()) {
this.snackbar = true
}
},
reset () {
this.$refs.form.reset()
},
resetValidation () {
this.$refs.form.resetValidation()
}
}
};
export { oneListPatientComponent };

View File

@@ -0,0 +1,12 @@
var searchComponent = {
template: `
<div>
<h1>Search Component</h1>
</div>
`,
data() {
return {};
},
methods: {}
};
export { searchComponent };

View File

@@ -0,0 +1,38 @@
var smartNavbarComponent = {
template: `
<span>
<v-navigation-drawer v-model="drawer" fixed app>
<v-list dense>
<v-list-tile>
<v-list-tile-action>
<v-icon>home</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Home</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
<v-list-tile>
<v-list-tile-action>
<v-icon>contact_mail</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Contact</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-navigation-drawer>
<v-toolbar color="blue lighten-2" dark fixed app>
<v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
<img src="/one-ui/libs/image/onetext.png" alt="image" height = 15px>
</v-toolbar>
</span>
`,
data: function() {
return {
drawer: false
};
},
methods: {}
};
export { smartNavbarComponent };

View File

@@ -0,0 +1,76 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>SmartOne</title>
<link rel="stylesheet" href="../../../libs/vendor/css/google-fonts.css">
<link rel="stylesheet" href="../../../libs/vendor/css/vuetify.min.css">
</head>
<body>
<div v-cloak id="app">
<v-app id="smartApp" >
<smart-navbar></smart-navbar>
<v-content class="blue lighten-5" >
<v-container fluid fill-height>
<v-layout fill-height row wrap>
<v-flex xs6 style="background-color:white">
<one-form-pasien></one-form-pasien>
</v-flex>
<v-flex xs6 style="background-color:white">
<one-list-pasien></one-list-pasien>
</v-flex>
</v-layout>
</v-container>
</v-content>
<v-footer color="blue lighten-2" app>
<span class="white--text">&copy; 2017</span>
</v-footer>
</v-app>
</div>
<!-- Vendor -->
<script src="../../../libs/vendor/axios.min.js"></script>
<script src="../../../libs/vendor/vue.js"></script>
<script src="../../../libs/vendor/vuex.js"></script>
<script src="../../../libs/vendor/vuetify.js"></script>
<!-- App Script -->
<?php
$ts = "?ts=" . Date("ymdhis");
?>
<script type="module">
import { store } from './store.js<?php echo $ts ?>';
import { smartNavbarComponent } from './components/smartNavbarComponent.js<?php echo $ts ?>';
import { oneFormPatientComponent } from './components/oneFormPatientComponent.js<?php echo $ts ?>';
import { oneListPatientComponent } from './components/oneListPatientComponent.js<?php echo $ts ?>';
//for testing
// window.store = store;
new Vue({
store,
el: '#app',
components: {
'smart-navbar': smartNavbarComponent,
'one-form-pasien': oneFormPatientComponent,
'one-list-pasien': oneListPatientComponent,
},
data: {
drawer: false,
}
})
</script>
<style>
[v-cloak] {
display: none
}
</style>
</body>
</html>

View File

View File

@@ -0,0 +1,71 @@
// State
// data ...
// Mutations
//
//
// Actions
import * as api from "./api.js";
export const store = new Vuex.Store({
state: {
rows: [],
midPages: [],
isLoading: false,
isError: false,
errorMessage: "",
query: "",
page: 0,
totalPage: 0,
totalRecord: 0
},
mutations: {
updateBank(state, data) {
// console.log(data);
if (data.status == "ERR") {
state.isError = true;
if (data.db_error) {
state.errorMessage = data.db_error.message;
} else {
state.errorMessage = data.message;
}
state.query = data.query;
state.page = 0;
state.totalPage = 0;
state.totalRecord = 0;
state.rows = [];
state.midPages = [];
} else {
state.isError = false;
state.errorMessage = "";
state.query = data.query;
state.page = data.page;
state.totalPage = data.totalPage;
state.totalRecord = data.totalRecord;
state.rows = data.rows;
state.midPages = data.midPages;
}
},
updateLoading(state, flag) {
state.isLoading = flag;
},
resetError(state) {
state.isError = false;
state.errorMessage = "";
}
},
actions: {
async searchBank(context, data) {
context.commit("updateLoading", true);
let resp = await api.searchBank(
data.query,
data.page,
data.rowPerPage
);
context.commit("updateLoading", false);
context.commit("updateBank", resp);
setTimeout(function() {
context.commit("resetError");
}, 5000);
}
}
});

View File

View File

@@ -0,0 +1,31 @@
// API :
// search bank
// paramater : query , page , rowPerPage
const URL =
"http://lebaran.aplikasi.web.id/smartlab_api/vuex/t02/search_bank";
export async function searchBank(query, page, rowPerPage = 15) {
try {
var resp = await axios.post(URL, {
query: query,
page: page,
rowPerPage: rowPerPage
});
if (resp.status != 200) {
return {
status: "ERR",
query: query,
message: resp.statusText
};
}
let data = resp.data;
data.query = query;
return data;
} catch (e) {
return {
status: "ERR",
query: query,
message: e.message
};
}
}

View File

@@ -0,0 +1,69 @@
var dialogFormComponent = {
template: `
<template>
<v-layout row justify-center>
<v-dialog v-model="dialog" persistent max-width="500px">
<v-btn slot="activator" color="primary" dark>Open Dialog</v-btn>
<v-card>
<v-card-title>
<span class="headline">User Profile</span>
</v-card-title>
<v-card-text>
<v-container grid-list-md>
<v-layout wrap>
<v-flex xs12 sm6 md4>
<v-text-field label="Legal first name" required></v-text-field>
</v-flex>
<v-flex xs12 sm6 md4>
<v-text-field label="Legal middle name" hint="example of helper text only on focus"></v-text-field>
</v-flex>
<v-flex xs12 sm6 md4>
<v-text-field
label="Legal last name"
hint="example of persistent helper text"
persistent-hint
required
></v-text-field>
</v-flex>
<v-flex xs12>
<v-text-field label="Email" required></v-text-field>
</v-flex>
<v-flex xs12>
<v-text-field label="Password" type="password" required></v-text-field>
</v-flex>
<v-flex xs12 sm6>
<v-select
:items="['0-17', '18-29', '30-54', '54+']"
label="Age"
required
></v-select>
</v-flex>
<v-flex xs12 sm6>
<v-autocomplete
:items="['Skiing', 'Ice hockey', 'Soccer', 'Basketball', 'Hockey', 'Reading', 'Writing', 'Coding', 'Basejump']"
label="Interests"
multiple
chips
></v-autocomplete>
</v-flex>
</v-layout>
</v-container>
<small>*indicates required field</small>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" flat @click.native="dialog = false">Close</v-btn>
<v-btn color="blue darken-1" flat @click.native="dialog = false">Save</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-layout>
</template>
`,
data: () => ({
dialog: false
})
};
export { dialogFormComponent };

View File

@@ -0,0 +1,139 @@
var listBankComponent = {
template: `
<v-card class="xs12 md12" >
<v-card-title>
<v-layout>
<v-flex xs12 sm8>
<v-toolbar-title>Bank Listing <v-btn depressed small color="primary">New Data</v-btn></v-toolbar-title>
</v-flex>
<v-flex xs12 sm4>
<v-spacer></v-spacer>
<v-text-field
v-model="query"
append-icon="search"
@click:clear="clearSearch"
@keydown.enter="doSearch"
@click:append="doSearch"
label="Search"
single-line
hide-details
clearable
class="xs12 md3"
></v-text-field>
</v-flex>
</v-layout>
</v-card-title>
<v-data-table :headers="headers" :items="banks"
:loading="isLoading"
hide-actions class="elevation-1">
<template slot="items" slot-scope="props">
<td class="text-xs-center">{{ props.item.M_BankCode }}</td>
<td>{{ props.item.M_BankName }}</td>
<td>{{ props.item.M_BankAddress }}</td>
<td>{{ props.item.M_BankBranch }}</td>
<td><v-btn depressed small color="info">Edit</v-btn> <v-btn depressed small color="error">Delete</v-btn></td>
</template>
<template slot="no-data">
<v-alert :value="isError" color="error" icon="warning">
{{errorMessage}}
</v-alert>
<v-spacer></v-spacer>
</template>
<template slot="footer">
<td colspan="2" class="text-xs-left">
Total Records : {{totalRecord}}, page {{page}} of {{totalPage}}.
</td>
<td colspan="3" class="text-xs-right">
<v-pagination :length="totalPage" :value="page" :total-visible="10"
@next="nextPage" @prev="prevPage"
@input="gotoPage" >
</v-pagination>
</td>
</template>
</v-data-table>
</v-card>
`,
mounted() {
this.doSearch();
},
data() {
return {
query: "",
headers: [{
text: "Code",
align: "left",
sortable: false,
value: "M_BankCode"
},
{
text: "Name",
align: "left",
sortable: false,
value: "M_BankName"
},
{
text: "Address",
value: "M_BankAddress",
sortable: false,
align: "left",
width: "30%"
},
{
text: "Branch",
value: "M_BankBranch",
sortable: false,
align: "left"
},
{
text: "Action",
value: "action",
sortable: false,
align: "center",
width: "20%"
}
]
};
},
methods: {
clearSearch() {
this.query = "";
this.doSearch();
},
doSearch(page = 1, rowPerPage = 8) {
if (this.query == null) this.query = "";
this.$store.dispatch("searchBank", {
query: this.query,
page,
rowPerPage
});
},
prevPage() {
let c_page = this.page - 1;
this.doSearch(c_page);
},
nextPage() {
let c_page = this.page + 1;
this.doSearch(c_page);
},
gotoPage(e) {
let c_page = e;
this.doSearch(c_page);
}
},
computed: {
...Vuex.mapState({
isLoading: state => state.isLoading,
isError: state => state.isError,
errorMessage: state => state.errorMessage,
banks: state => state.rows,
totalRecord: state => state.totalRecord,
page: state => state.page,
totalPage: state => state.totalPage
})
},
updated() {
console.log("Component Updated");
}
};
export { listBankComponent };

View File

@@ -0,0 +1,138 @@
var listPatientComponent = {
template: `
<v-card class="xs12 md12" >
<v-card-title>
<v-layout>
<v-flex xs12 sm8>
<v-toolbar-title>Patient Listing</v-toolbar-title>
</v-flex>
<v-flex xs12 sm4>
<v-spacer></v-spacer>
<v-text-field
v-model="query"
append-icon="search"
@click:clear="clearSearch"
@keydown.enter="doSearch"
@click:append="doSearch"
label="Search"
single-line
hide-details
clearable
class="xs12 md3"
></v-text-field>
</v-flex>
</v-layout>
</v-card-title>
<v-data-table :headers="headers" :items="patients"
:loading="isLoading"
hide-actions class="elevation-1">
<template slot="items" slot-scope="props">
<td>{{ props.item.M_PatientNoReg }}</td>
<td>{{ props.item.M_PatientName }}</td>
<td class="text-xs-center">{{ props.item.M_PatientDOB }}</td>
<td>{{ props.item.M_PatientHP }}</td>
<td>{{ props.item.M_PatientAddress }}</td>
</template>
<template slot="no-data">
<v-alert :value="isError" color="error" icon="warning">
{{errorMessage}}
</v-alert>
<v-spacer></v-spacer>
</template>
<template slot="footer">
<td colspan="2" class="text-xs-left">
Total Records : {{totalRecord}}, page {{page}} of {{totalPage}}.
</td>
<td colspan="3" class="text-xs-right">
<v-pagination :length="totalPage" :value="page" :total-visible="10"
@next="nextPage" @prev="prevPage"
@input="gotoPage" >
</v-pagination>
</td>
</template>
</v-data-table>
</v-card>
`,
mounted() {
this.doSearch();
},
data() {
return {
query: "",
headers: [
{
text: "No. Reg",
align: "left",
sortable: false,
value: "M_PatientNoReg"
},
{
text: "Name",
align: "left",
sortable: false,
value: "M_PatientName"
},
{
text: "DOB",
align: "center",
sortable: false,
value: "M_PatientDOB"
},
{
text: "HP",
value: "M_PatientHP",
sortable: false,
align: "left"
},
{
text: "Address",
value: "M_PatientAddress",
sortable: false,
align: "left"
}
]
};
},
methods: {
clearSearch() {
this.query = "";
this.doSearch();
},
doSearch(page = 1, rowPerPage = 8) {
if (this.query == null) this.query = "";
this.$store.dispatch("searchPatient", {
query: this.query,
page,
rowPerPage
});
},
prevPage() {
let c_page = this.page - 1;
this.doSearch(c_page);
},
nextPage() {
let c_page = this.page + 1;
this.doSearch(c_page);
},
gotoPage(e) {
let c_page = e;
this.doSearch(c_page);
}
},
computed: {
...Vuex.mapState({
isLoading: state => state.isLoading,
isError: state => state.isError,
errorMessage: state => state.errorMessage,
patients: state => state.rows,
totalRecord: state => state.totalRecord,
page: state => state.page,
totalPage: state => state.totalPage
})
},
updated() {
console.log("Component Updated");
}
};
export { listPatientComponent };

View File

@@ -0,0 +1,12 @@
var searchComponent = {
template: `
<div>
<h1>Search Component</h1>
</div>
`,
data() {
return {};
},
methods: {}
};
export { searchComponent };

View File

@@ -0,0 +1,44 @@
var smartNavbarComponent = {
template: `
<span>
<v-navigation-drawer class="light-green lighten-4" v-model="drawer" fixed app>
<v-list dense>
<v-list-tile>
<v-list-tile-action>
<v-icon>home</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Home</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
<v-list-tile>
<v-list-tile-action>
<v-icon>contact_mail</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Contact</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-navigation-drawer>
<v-toolbar color="light-green" dark fixed app>
<v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
<v-spacer></v-spacer>
<img src="/one-ui/libs/image/logoone.png" alt="image" height = 50px>
</v-toolbar>
</span>
`,
data: function() {
return {
drawer: false
};
},
methods: {}
};
export { smartNavbarComponent };

View File

@@ -0,0 +1,47 @@
var tabComponent = {
template: `
<v-tabs
centered
color="cyan"
dark
icons-and-text
>
<v-tabs-slider color="yellow"></v-tabs-slider>
<v-tab href="#tab-1">
Recents
<v-icon>phone</v-icon>
</v-tab>
<v-tab href="#tab-2">
Favorites
<v-icon>favorite</v-icon>
</v-tab>
<v-tab href="#tab-3">
Nearby
<v-icon>account_box</v-icon>
</v-tab>
<v-tab-item
v-for="i in 3"
:key="i"
:value="'tab-' + i"
>
<v-card flat>
<v-card-text>{{ text }}</v-card-text>
</v-card>
</v-tab-item>
</v-tabs>
`,
data: function() {
return {
drawer: false
};
},
methods: {}
};
export { tabComponent };

View File

@@ -0,0 +1,113 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Adhi</title>
<link rel="stylesheet" href="../../../libs/vendor/css/google-fonts.css">
<link rel="stylesheet" href="../../../libs/vendor/css/vuetify.min.css">
</head>
<body>
<div v-cloak id="app">
<v-app id="smartApp">
<smart-navbar></smart-navbar>
<v-content>
<v-container >
<v-tabs
centered
color="light-green lighten-2
"
dark
icons-and-text
>
<v-tabs-slider color="light-green"></v-tabs-slider>
<v-tab ripple>
Recents
<v-icon>phone</v-icon>
</v-tab>
<v-tab ripple>
Favorites
<v-icon>favorite</v-icon>
</v-tab>
<v-tab ripple>
Nearby
<v-icon>account_box</v-icon>
</v-tab>
<v-tab-item>
<v-card flat>
<v-card-text>Contents for Item 1 go here</v-card-text>
</v-card>
</v-tab-item>
<v-tab-item>
<v-card flat>
<v-card-text>Contents for Item 2 go here</v-card-text>
</v-card>
</v-tab-item>
</v-tabs>
</v-container>
</v-content>
<v-footer color="light-green" app>
<span class="white--text">PT. SAS &copy; 2019</span>
</v-footer>
</v-app>
</div>
<!-- Vendor -->
<script src="../../../libs/vendor/axios.min.js"></script>
<script src="../../../libs/vendor/vue.js"></script>
<script src="../../../libs/vendor/vuex.js"></script>
<script src="../../../libs/vendor/vuetify.js"></script>
<!-- App Script -->
<?php
$ts = "?ts=" . Date("ymdhis");
?>
<script type="module">
import { store } from './store.js<?php echo $ts ?>';
import { smartNavbarComponent } from './components/smartNavbarComponent.js<?php echo $ts ?>';
// import { tabComponent } from './components/tabComponent.js<?php echo $ts ?>';
// import { dialogFormComponent } from './components/dialogFormComponent.js<?php echo $ts ?>';
//for testing
// window.store = store;
new Vue({
store,
el: '#app',
components: {
'smart-navbar': smartNavbarComponent,
// 'tab': tabComponent
// 'dialog-form':dialogFormComponent
},
data: {
drawer: false,
},
data: {
text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed',
}
})
</script>
<style>
[v-cloak] {
display: none
}
</style>
</body>
</html>

View File

View File

@@ -0,0 +1,71 @@
// State
// data ...
// Mutations
//
//
// Actions
import * as api from "./api.js";
export const store = new Vuex.Store({
state: {
rows: [],
midPages: [],
isLoading: false,
isError: false,
errorMessage: "",
query: "",
page: 0,
totalPage: 0,
totalRecord: 0
},
mutations: {
updateBank(state, data) {
// console.log(data);
if (data.status == "ERR") {
state.isError = true;
if (data.db_error) {
state.errorMessage = data.db_error.message;
} else {
state.errorMessage = data.message;
}
state.query = data.query;
state.page = 0;
state.totalPage = 0;
state.totalRecord = 0;
state.rows = [];
state.midPages = [];
} else {
state.isError = false;
state.errorMessage = "";
state.query = data.query;
state.page = data.page;
state.totalPage = data.totalPage;
state.totalRecord = data.totalRecord;
state.rows = data.rows;
state.midPages = data.midPages;
}
},
updateLoading(state, flag) {
state.isLoading = flag;
},
resetError(state) {
state.isError = false;
state.errorMessage = "";
}
},
actions: {
async searchBank(context, data) {
context.commit("updateLoading", true);
let resp = await api.searchBank(
data.query,
data.page,
data.rowPerPage
);
context.commit("updateLoading", false);
context.commit("updateBank", resp);
setTimeout(function() {
context.commit("resetError");
}, 5000);
}
}
});

View File

@@ -0,0 +1,31 @@
// API :
// search patient
// paramater : query , page , rowPerPage
const URL =
"http://lebaran.aplikasi.web.id/smartlab_api/vuex/t01/search_patient";
export async function searchPatient(query, page, rowPerPage = 15) {
try {
var resp = await axios.post(URL, {
query: query,
page: page,
rowPerPage: rowPerPage
});
if (resp.status != 200) {
return {
status: "ERR",
query: query,
message: resp.statusText
};
}
let data = resp.data;
data.query = query;
return data;
} catch (e) {
return {
status: "ERR",
query: query,
message: e.message
};
}
}

View File

@@ -0,0 +1,12 @@
var searchComponent = {
template: `
<div>
<h1>Search Component</h1>
</div>
`,
data() {
return {};
},
methods: {}
};
export { searchComponent };

View File

@@ -0,0 +1,38 @@
var smartNavbarComponent = {
template: `
<span>
<v-navigation-drawer v-model="drawer" fixed app>
<v-list dense>
<v-list-tile>
<v-list-tile-action>
<v-icon>home</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Home</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
<v-list-tile>
<v-list-tile-action>
<v-icon>contact_mail</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Contact</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-navigation-drawer>
<v-toolbar color="indigo" dark fixed app>
<v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
<v-toolbar-title>Application</v-toolbar-title>
</v-toolbar>
</span>
`,
data: function() {
return {
drawer: false
};
},
methods: {}
};
export { smartNavbarComponent };

View File

@@ -0,0 +1,139 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Doctor</title>
<link rel="stylesheet" href="../../../libs/vendor/css/google-fonts.css">
<link rel="stylesheet" href="../../../libs/vendor/css/vuetify.min.css">
</head>
<body>
<div v-cloak id="app">
<v-app id="smartApp">
<v-navigation-drawer v-model="drawer" fixed app>
<v-list dense>
<v-list-tile>
<v-list-tile-action>
<v-icon>home</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Home</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
<v-list-tile>
<v-list-tile-action>
<v-icon>contact_mail</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Contact</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-navigation-drawer>
<v-toolbar color="indigo" dark fixed app>
<v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
<v-toolbar-title>Application</v-toolbar-title>
</v-toolbar>
<v-content>
<v-container fluid fill-height>
<v-layout >
<v-flex text-xs-center>
<v-data-table :headers="headers" :items="doctor" hide-actions class="elevation-1" >
<template slot="items" slot-scope="props">
<td >{{ props.item.M_DoctorName}}</td>
<td >{{ props.item.M_DoctorHomeAddress}}</td>
<td >{{ props.item.M_DoctorHomeAddress}}</td>
<td >{{ props.item.M_DoctorHP}}</td>
<td >{{ props.item.M_DoctorPhone}}</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
</v-container>
</v-content>
<v-footer color="indigo" app>
<span class="white--text">&copy; 2017</span>
</v-footer>
</v-app>
</div>
<!-- Vendor -->
<script src="../../../libs/vendor/axios.min.js"></script>
<script src="../../../libs/vendor/vue.js"></script>
<script src="../../../libs/vendor/vuex.js"></script>
<script src="../../../libs/vendor/vuetify.js"></script>
<!-- App Script -->
<script type="module">
import { store } from './store.js?x=3';
import { smartNavbarComponent } from './components/smartNavbarComponent.js?x=5';
//for testing
// window.store = store;
new Vue({
store,
el: '#app',
components: {
'smart-navbar': smartNavbarComponent
},
data: {
drawer: false,
headers: [
{
text: 'Nama',
align: 'center',
sortable: false,
value: 'M_DoctorName'
},
{
text: 'Home Address',
align: 'center',
sortable: false,
value: 'M_DoctorHomeAddress'
},
{
text: 'Practice Address',
align: 'center',
sortable: false,
value: 'M_DoctorPracticeAddress'
},
{
text: 'HP',
value: 'M_DoctorHP',
sortable: false,
align: 'center',
},
{
text: 'Phone',
value: 'M_DoctorPhone',
sortable: false,
align: 'center',
}
],
doctor: [
{
M_DoctorName : 'Dr. Suzana T,M.Kes',
M_DoctorHomeAddress: "Jl.Kopo No 161",
M_DoctorPracticeAddress: "Jl. Protokol V / 4 Cijerah",
M_DoctorHP: '022-2506337',
M_DoctorPhone: '081321329126'
},
]
}
})
</script>
<style>
[v-cloak] {
display: none
}
</style>
</body>
</html>

View File

@@ -0,0 +1,64 @@
// State
// data ...
// Mutations
//
//
// Actions
import * as api from "./api.js";
export const store = new Vuex.Store({
state: {
rows: [],
midPages: [],
isLoading: false,
isError: false,
errorMessage: "",
query: "",
page: 0,
totalPage: 0,
totalRecord: 0
},
mutations: {
updatePatient(state, data) {
console.log(data);
if (data.status == "ERR") {
state.isError = true;
if (data.dbError) {
state.errorMessage = data.dbError;
} else {
state.errorMessage = data.message;
}
state.query = data.query;
state.page = 0;
state.totalPage = 0;
state.totalRecord = 0;
state.rows = [];
state.midPages = [];
} else {
state.isError = false;
state.errorMessage = "";
state.query = data.query;
state.page = data.page;
state.totalPage = data.totalPage;
state.totalRecord = data.totalRecord;
state.rows = data.rows;
state.midPages = data.midPages;
}
},
updateLoading(state, flag) {
state.isLoading = flag;
}
},
actions: {
async searchPatient(context, data) {
context.commit("updateLoading", true);
let resp = await api.searchPatient(
data.query,
data.page,
data.rowPerPage
);
context.commit("updateLoading", false);
context.commit("updatePatient", resp);
}
}
});

View File

View File

@@ -0,0 +1,31 @@
// API :
// search patient
// paramater : query , page , rowPerPage
const URL =
"http://lebaran.aplikasi.web.id/smartlab_api/vuex/t05/search_patienttype";
export async function searchPatientType(query, page, rowPerPage = 15) {
try {
var resp = await axios.post(URL, {
query: query,
page: page,
rowPerPage: rowPerPage
});
if (resp.status != 200) {
return {
status: "ERR",
query: query,
message: resp.statusText
};
}
let data = resp.data;
data.query = query;
return data;
} catch (e) {
return {
status: "ERR",
query: query,
message: e.message
};
}
}

View File

@@ -0,0 +1,5 @@
var barComponent = {
template: `<div> text bar</div>`
};
export { barComponent };

View File

@@ -0,0 +1,228 @@
var barComponent = {
template: `<v-layout>
<v-flex
md6="md6"
class="mr-2"
>
<v-card
ref="form"
flat="flat"
light="light"
color="amber lighten-2"
>
<v-card-text>
<v-layout row="row">
<v-flex
d-flex="d-flex"
md12="md12"
>
<v-flex
md6="md6"
ma-2="ma-2"
>
<v-text-field
label="Nama Pasien"
outline="outline"
></v-text-field>
</v-flex>
<v-flex
md3="md3"
ma-2="ma-2"
>
<v-text-field
label="DOB"
outline="outline"
></v-text-field>
</v-flex>
<v-flex
md3="md3"
ma-2="ma-2"
>
<v-text-field
label="HP"
outline="outline"
></v-text-field>
</v-flex>
</v-flex>
</v-layout>
<v-layout
fluid="fluid"
wrap="wrap"
row="row"
>
<v-chip>
<v-avatar>
<img src="https://randomuser.me/api/portraits/men/35.jpg" alt="trevor">
</v-avatar>
Trevor Hansen (M)
</v-chip>
<v-chip>
<v-avatar>
<img src="https://randomuser.me/api/portraits/men/35.jpg" alt="trevor">
</v-avatar>
Fajri hardhita M (M)
</v-chip>
<v-chip>
<v-avatar>
<img src="https://randomuser.me/api/portraits/men/35.jpg" alt="trevor">
</v-avatar>
Jhonny Andrean (M)
</v-chip>
<v-chip>
<v-avatar>
<img src="https://randomuser.me/api/portraits/men/35.jpg" alt="trevor">
</v-avatar>
Dave Emanuel (M)
</v-chip>
<v-chip>
<v-avatar>
<img src="https://randomuser.me/api/portraits/men/35.jpg" alt="trevor">
</v-avatar>
Fian Taruna (M)
</v-chip>
<v-chip>
<v-avatar>
<img src="https://randomuser.me/api/portraits/men/35.jpg" alt="trevor">
</v-avatar>
Andik Hermawan (M)
</v-chip>
<v-chip>
<v-avatar>
<img src="https://randomuser.me/api/portraits/men/35.jpg" alt="trevor">
</v-avatar>
Sugeng (M)
</v-chip>
<v-chip>
<v-avatar>
<img src="https://randomuser.me/api/portraits/men/35.jpg" alt="trevor">
</v-avatar>
Kerta Sanjaya (M)
</v-chip>
<v-chip>
<v-avatar>
<img src="https://randomuser.me/api/portraits/men/35.jpg" alt="trevor">
</v-avatar>
Denis Anggara (M)
</v-chip>
<v-chip>
<v-avatar>
<img src="https://randomuser.me/api/portraits/men/35.jpg" alt="trevor">
</v-avatar>
Mustafa (M)
</v-chip>
<v-chip>
<v-avatar>
<img src="https://randomuser.me/api/portraits/men/35.jpg" alt="trevor">
</v-avatar>
Ribut Sentosa Tanuraga (M)
</v-chip>
<v-chip>
<v-avatar>
<img src="https://randomuser.me/api/portraits/men/35.jpg" alt="trevor">
</v-avatar>
Lilipan Anggara (M)
</v-chip>
</v-layout>
</v-card-text>
</v-card>
</v-flex>
<v-flex
md6="md6"
class="mr-2"
>
<v-card
ref="form"
flat="flat"
light="light"
color="amber lighten-2"
>
<v-layout>
<v-flex md5 align-self-center d-flex >
<img
style="text-align:center"
class="white--text"
height="192px"
src="https://cdn.vuetifyjs.com/images/cards/docks.jpg"
></img>
</v-flex>
<v-flex md7>
<v-data-table
:items="patient"
class="elevation-1"
hide-actions
hide-headers
>
<template slot="items" slot-scope="props">
<td>{{ props.item.label }}</td>
<td align="right">{{ props.item.value }}</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
<v-divider light="light"></v-divider>
<v-layout
fluid="fluid"
wrap="wrap"
row="row"
>
<v-flex md6 pa-2
>
<v-text-field
label="DOKTER"
outline="outline"
></v-text-field>
</v-flex>
<v-flex pa-2 md6>
<v-select
v-model="select"
:items="items"
item-text="state"
item-value="abbr"
return-object
label="Alamat Dokter"
outline
></v-select>
</v-flex>
</v-layout>
</v-card-text>
</v-card>
</v-flex>
</v-layout>`,
data: function() {
return {
patient: [
{ label: 'No Reg', value: 'ABT565651551' },
{ label: 'Nama', value: ' Lilipan Anggara' },
{ label: 'DOB', value: '22-01-1995' },
{ label: 'Alamat', value: 'Desa Kauman Tegal' },
],
select: { state: 'Georgia', abbr: 'GA' },
items: [
{ state: 'Florida', abbr: 'FL' },
{ state: 'Georgia', abbr: 'GA' },
{ state: 'Nebraska', abbr: 'NE' },
{ state: 'California', abbr: 'CA' },
{ state: 'New York', abbr: 'NY' }
]
};
},
methods: {}
};
export {
barComponent
};

View File

@@ -0,0 +1,5 @@
var fooComponent = {
template: `<div> text foo</div>`
};
export { fooComponent };

View File

@@ -0,0 +1,138 @@
var listPatientTypeComponent = {
template: `
<v-card class="xs12 md12" >
<v-card-title>
<v-layout>
<v-flex xs12 sm8>
<v-toolbar-title>Patient Type Listing</v-toolbar-title>
</v-flex>
<v-flex xs12 sm4>
<v-spacer></v-spacer>
<v-text-field
v-model="query"
append-icon="search"
@click:clear="clearSearch"
@keydown.enter="doSearch"
@click:append="doSearch"
label="Search"
single-line
hide-details
clearable
class="xs12 md3"
></v-text-field>
</v-flex>
</v-layout>
</v-card-title>
<v-data-table :headers="headers" :items="patienttypes"
:loading="isLoading"
hide-actions class="elevation-1">
<template slot="items" slot-scope="props">
<td>{{ props.item.M_PatientTypeName }}</td>
<td>{{ props.item.M_PatientTypeAddress }}</td>
<td>{{ props.item.M_PatientTypeMOUPIC }}</td>
<td>{{ props.item.M_PatientTypePhone }}</td>
<td>{{ props.item.M_PatientTypeEmail }}</td>
</template>
<template slot="no-data">
<v-alert :value="isError" color="error" icon="warning">
{{errorMessage}}
</v-alert>
<v-spacer></v-spacer>
</template>
<template slot="footer">
<td colspan="2" class="text-xs-left">
Total Records : {{totalRecord}}, page {{page}} of {{totalPage}}.
</td>
<td colspan="3" class="text-xs-right">
<v-pagination :length="totalPage" :value="page" :total-visible="10"
@next="nextPage" @prev="prevPage"
@input="gotoPage" >
</v-pagination>
</td>
</template>
</v-data-table>
</v-card>
`,
mounted() {
this.doSearch();
},
data() {
return {
query: "",
headers: [
{
text: "Name",
align: "left",
sortable: false,
value: "M_PatientTypeName"
},
{
text: "Addres",
align: "left",
sortable: false,
value: "M_PatientTypeAddress"
},
{
text: "PIC",
value: "M_PatientTypeMOUPIC",
sortable: false,
align: "left"
},
{
text: "Phone",
value: "M_PatientTypePhone",
sortable: false,
align: "left"
},
{
text: "Email",
value: "M_PatientTypeEmail",
sortable: false,
align: "left"
}
]
};
},
methods: {
clearSearch() {
this.query = "";
this.doSearch();
},
doSearch(page = 1, rowPerPage = 8) {
if (this.query == null) this.query = "";
this.$store.dispatch("searchPatientType", {
query: this.query,
page,
rowPerPage
});
},
prevPage() {
let c_page = this.page - 1;
this.doSearch(c_page);
},
nextPage() {
let c_page = this.page + 1;
this.doSearch(c_page);
},
gotoPage(e) {
let c_page = e;
this.doSearch(c_page);
}
},
computed: {
...Vuex.mapState({
isLoading: state => state.isLoading,
isError: state => state.isError,
errorMessage: state => state.errorMessage,
patienttypes: state => state.rows,
totalRecord: state => state.totalRecord,
page: state => state.page,
totalPage: state => state.totalPage
})
},
updated() {
console.log("Component Updated");
}
};
export { listPatientTypeComponent };

View File

@@ -0,0 +1,92 @@
var smartNavbarComponent = {
template: `
<span>
<v-navigation-drawer
v-model="drawer"
fixed
clipped
class="grey lighten-4"
app
>
<v-list
dense
class="grey lighten-4"
>
<template v-for="(item, i) in items">
<v-layout
v-if="item.heading"
:key="i"
row
align-center
>
<v-flex xs6>
<v-subheader v-if="item.heading">
{{ item.heading }}
</v-subheader>
</v-flex>
<v-flex xs6 class="text-xs-right">
<v-btn small flat>edit</v-btn>
</v-flex>
</v-layout>
<v-divider
v-else-if="item.divider"
:key="i"
dark
class="my-3"
></v-divider>
<v-list-tile
v-else
:key="i"
@click=""
>
<v-list-tile-action>
<v-icon>{{ item.icon }}</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title class="grey--text">
{{ item.text }}
</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</template>
</v-list>
</v-navigation-drawer>
<v-toolbar color="amber" app absolute clipped-left>
<v-toolbar-side-icon @click.native="drawer = !drawer"></v-toolbar-side-icon>
<span class="title ml-3 mr-5">Google&nbsp;<span class="font-weight-light">Keep</span></span>
<v-text-field
solo-inverted
flat
hide-details
label="Search"
prepend-inner-icon="search"
></v-text-field>
<v-spacer></v-spacer>
</v-toolbar>
</span>
`,
data: function() {
return {
drawer: false,
items: [
{ icon: 'lightbulb_outline', text: 'Notes' },
{ icon: 'touch_app', text: 'Reminders' },
{ divider: true },
{ heading: 'Labels' },
{ icon: 'add', text: 'Create new label' },
{ divider: true },
{ icon: 'archive', text: 'Archive' },
{ icon: 'delete', text: 'Trash' },
{ divider: true },
{ icon: 'settings', text: 'Settings' },
{ icon: 'chat_bubble', text: 'Trash' },
{ icon: 'help', text: 'Help' },
{ icon: 'phonelink', text: 'App downloads' },
{ icon: 'keyboard', text: 'Keyboard shortcuts' }
]
};
},
methods: {}
};
export { smartNavbarComponent };

View File

@@ -0,0 +1,113 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Test 05 Vuex (Fitri)</title>
<link rel="stylesheet" href="../../../libs/vendor/css/google-fonts.css">
<link rel="stylesheet" href="../../../libs/vendor/css/vuetify.min.css">
</head>
<body>
<div v-cloak id="app">
<v-app id="inspire">
<div>
<v-toolbar color="indigo accent-1" dark>
<v-btn icon class="hidden-xs-only">
<v-icon large>format_indent_increase</v-icon>
</v-btn>
<v-toolbar-title><div class="flex display-3 font-weight-bold">One</div></v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items class="hidden-sm-and-down">
<v-icon large>notifications_none</v-icon>
</v-toolbar-items>
</v-toolbar>
<v-tabs light
v-model="active"
color="green darken-2"
dark
slider-color="amber lighten-2"
fixed-tabs
>
<v-tab
v-for="item in items"
:key="item.id"
ripple
>
{{item.label}}
</v-tab>
<v-tab-item id="1"
>
<v-card color="blue-grey lighten-5" flat>
<v-card-text><bar></bar></v-card-text>
</v-card>
</v-tab-item>
<v-tab-item id="2"
>
<v-card flat>
<v-card-text><foo></foo></v-card-text>
</v-card>
</v-tab-item>
</v-tabs>
<div class="text-xs-center mt-3">
<v-btn @click="next">next tab</v-btn>
</div>
</div>
</v-app>
</div>
<!-- Vendor -->
<script src="../../../libs/vendor/axios.min.js"></script>
<script src="../../../libs/vendor/vue.js"></script>
<script src="../../../libs/vendor/vuex.js"></script>
<script src="../../../libs/vendor/vuetify.js"></script>
<!-- App Script -->
<?php
$ts = "?ts=" . Date("ymdhis");
?>
<script type="module">
import { store } from './store.js<?php echo $ts ?>';
import { barComponent } from './components/barComponent.js<?php echo $ts ?>';
import { fooComponent } from './components/fooComponent.js<?php echo $ts ?>';
//for testing
// window.store = store;
new Vue({
el: '#app',
components: {
'bar': barComponent,
'foo': fooComponent,
},
data () {
return {
active: null,
items: [
{id:1,'label':'PASIEN','url':'#bar'},
{id:2,'label':'foo','url':'#foo'}
],
}
},
methods: {
next () {
const active = parseInt(this.active)
this.active = (active < 2 ? active + 1 : 0)
}
}
})
</script>
<style>
[v-cloak] {
display: none
}
</style>
</body>
</html>

View File

View File

@@ -0,0 +1,71 @@
// State
// data ...
// Mutations
//
//
// Actions
import * as api from "./api.js";
export const store = new Vuex.Store({
state: {
rows: [],
midPages: [],
isLoading: false,
isError: false,
errorMessage: "",
query: "",
page: 0,
totalPage: 0,
totalRecord: 0
},
mutations: {
updatePatientType(state, data) {
// console.log(data);
if (data.status == "ERR") {
state.isError = true;
if (data.db_error) {
state.errorMessage = data.db_error.message;
} else {
state.errorMessage = data.message;
}
state.query = data.query;
state.page = 0;
state.totalPage = 0;
state.totalRecord = 0;
state.rows = [];
state.midPages = [];
} else {
state.isError = false;
state.errorMessage = "";
state.query = data.query;
state.page = data.page;
state.totalPage = data.totalPage;
state.totalRecord = data.totalRecord;
state.rows = data.rows;
state.midPages = data.midPages;
}
},
updateLoading(state, flag) {
state.isLoading = flag;
},
resetError(state) {
state.isError = false;
state.errorMessage = "";
}
},
actions: {
async searchPatientType(context, data) {
context.commit("updateLoading", true);
let resp = await api.searchPatientType(
data.query,
data.page,
data.rowPerPage
);
context.commit("updateLoading", false);
context.commit("updatePatientType", resp);
setTimeout(function() {
context.commit("resetError");
}, 5000);
}
}
});

View File

31
test/vuex/lama/t01/api.js Normal file
View File

@@ -0,0 +1,31 @@
// API :
// search patient
// paramater : query , page , rowPerPage
const URL =
"http://lebaran.aplikasi.web.id/smartlab_api/vuex/t01/search_patient";
export async function searchPatient(query, page, rowPerPage = 15) {
try {
var resp = await axios.post(URL, {
query: query,
page: page,
rowPerPage: rowPerPage
});
if (resp.status != 200) {
return {
status: "ERR",
query: query,
message: resp.statusText
};
}
let data = resp.data;
data.query = query;
return data;
} catch (e) {
return {
status: "ERR",
query: query,
message: e.message
};
}
}

View File

@@ -0,0 +1,138 @@
var listPatientComponent = {
template: `
<v-card class="xs12 md12" >
<v-card-title>
<v-layout>
<v-flex xs12 sm8>
<v-toolbar-title>Patient Listing</v-toolbar-title>
</v-flex>
<v-flex xs12 sm4>
<v-spacer></v-spacer>
<v-text-field
v-model="query"
append-icon="search"
@click:clear="clearSearch"
@keydown.enter="doSearch"
@click:append="doSearch"
label="Search"
single-line
hide-details
clearable
class="xs12 md3"
></v-text-field>
</v-flex>
</v-layout>
</v-card-title>
<v-data-table :headers="headers" :items="patients"
:loading="isLoading"
hide-actions class="elevation-1">
<template slot="items" slot-scope="props">
<td>{{ props.item.M_PatientNoReg }}</td>
<td>{{ props.item.M_PatientName }}</td>
<td class="text-xs-center">{{ props.item.M_PatientDOB }}</td>
<td>{{ props.item.M_PatientHP }}</td>
<td>{{ props.item.M_PatientAddress }}</td>
</template>
<template slot="no-data">
<v-alert :value="isError" color="error" icon="warning">
{{errorMessage}}
</v-alert>
<v-spacer></v-spacer>
</template>
<template slot="footer">
<td colspan="2" class="text-xs-left">
Total Records : {{totalRecord}}, page {{page}} of {{totalPage}}.
</td>
<td colspan="3" class="text-xs-right">
<v-pagination :length="totalPage" :value="page" :total-visible="10"
@next="nextPage" @prev="prevPage"
@input="gotoPage" >
</v-pagination>
</td>
</template>
</v-data-table>
</v-card>
`,
mounted() {
this.doSearch();
},
data() {
return {
query: "",
headers: [
{
text: "No. Reg",
align: "left",
sortable: false,
value: "M_PatientNoReg"
},
{
text: "Name",
align: "left",
sortable: false,
value: "M_PatientName"
},
{
text: "DOB",
align: "center",
sortable: false,
value: "M_PatientDOB"
},
{
text: "HP",
value: "M_PatientHP",
sortable: false,
align: "left"
},
{
text: "Address",
value: "M_PatientAddress",
sortable: false,
align: "left"
}
]
};
},
methods: {
clearSearch() {
this.query = "";
this.doSearch();
},
doSearch(page = 1, rowPerPage = 8) {
if (this.query == null) this.query = "";
this.$store.dispatch("searchPatient", {
query: this.query,
page,
rowPerPage
});
},
prevPage() {
let c_page = this.page - 1;
this.doSearch(c_page);
},
nextPage() {
let c_page = this.page + 1;
this.doSearch(c_page);
},
gotoPage(e) {
let c_page = e;
this.doSearch(c_page);
}
},
computed: {
...Vuex.mapState({
isLoading: state => state.isLoading,
isError: state => state.isError,
errorMessage: state => state.errorMessage,
patients: state => state.rows,
totalRecord: state => state.totalRecord,
page: state => state.page,
totalPage: state => state.totalPage
})
},
updated() {
console.log("Component Updated");
}
};
export { listPatientComponent };

View File

@@ -0,0 +1,38 @@
var smartNavbarComponent = {
template: `
<span>
<v-navigation-drawer v-model="drawer" fixed app>
<v-list dense>
<v-list-tile>
<v-list-tile-action>
<v-icon>home</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Home</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
<v-list-tile>
<v-list-tile-action>
<v-icon>contact_mail</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Contact</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-navigation-drawer>
<v-toolbar color="indigo" dark fixed app>
<v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
<v-toolbar-title>Application</v-toolbar-title>
</v-toolbar>
</span>
`,
data: function() {
return {
drawer: false
};
},
methods: {}
};
export { smartNavbarComponent };

View File

@@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Test 01 Vuex</title>
<link rel="stylesheet" href="../../../libs/vendor/css/google-fonts.css">
<link rel="stylesheet" href="../../../libs/vendor/css/vuetify.min.css">
</head>
<body>
<div v-cloak id="app">
<v-app id="smartApp">
<smart-navbar></smart-navbar>
<v-content>
<v-container fluid fill-height style="height:inherit">
<v-flex size="xs12">
<list-patient fill-height></list-patient>
</v-flex>
</v-container>
</v-content>
<v-footer color="indigo" app>
<span class="white--text">&copy; 2017</span>
</v-footer>
</v-app>
</div>
<!-- Vendor -->
<script src="../../../libs/vendor/axios.min.js"></script>
<script src="../../../libs/vendor/vue.js"></script>
<script src="../../../libs/vendor/vuex.js"></script>
<script src="../../../libs/vendor/vuetify.js"></script>
<!-- App Script -->
<?php
$ts = "?ts=" . Date("ymdhis");
?>
<script type="module">
import { store } from './store.js<?php echo $ts ?>';
import { smartNavbarComponent } from './components/smartNavbarComponent.js<?php echo $ts ?>';
import { listPatientComponent } from './components/listPatientComponent.js<?php echo $ts ?>';
//for testing
// window.store = store;
new Vue({
store,
el: '#app',
components: {
'smart-navbar': smartNavbarComponent,
'list-patient': listPatientComponent,
},
data: {
drawer: false,
}
})
</script>
<style>
[v-cloak] {
display: none
}
</style>
</body>
</html>

View File

View File

@@ -0,0 +1,71 @@
// State
// data ...
// Mutations
//
//
// Actions
import * as api from "./api.js";
export const store = new Vuex.Store({
state: {
rows: [],
midPages: [],
isLoading: false,
isError: false,
errorMessage: "",
query: "",
page: 0,
totalPage: 0,
totalRecord: 0
},
mutations: {
updatePatient(state, data) {
// console.log(data);
if (data.status == "ERR") {
state.isError = true;
if (data.db_error) {
state.errorMessage = data.db_error.message;
} else {
state.errorMessage = data.message;
}
state.query = data.query;
state.page = 0;
state.totalPage = 0;
state.totalRecord = 0;
state.rows = [];
state.midPages = [];
} else {
state.isError = false;
state.errorMessage = "";
state.query = data.query;
state.page = data.page;
state.totalPage = data.totalPage;
state.totalRecord = data.totalRecord;
state.rows = data.rows;
state.midPages = data.midPages;
}
},
updateLoading(state, flag) {
state.isLoading = flag;
},
resetError(state) {
state.isError = false;
state.errorMessage = "";
}
},
actions: {
async searchPatient(context, data) {
context.commit("updateLoading", true);
let resp = await api.searchPatient(
data.query,
data.page,
data.rowPerPage
);
context.commit("updateLoading", false);
context.commit("updatePatient", resp);
setTimeout(function() {
context.commit("resetError");
}, 5000);
}
}
});

View File

31
test/vuex/lama/t02/api.js Normal file
View File

@@ -0,0 +1,31 @@
// API :
// search bank
// paramater : query , page , rowPerPage
const URL =
"http://lebaran.aplikasi.web.id/smartlab_api/vuex/t02/search_bank";
export async function searchBank(query, page, rowPerPage = 15) {
try {
var resp = await axios.post(URL, {
query: query,
page: page,
rowPerPage: rowPerPage
});
if (resp.status != 200) {
return {
status: "ERR",
query: query,
message: resp.statusText
};
}
let data = resp.data;
data.query = query;
return data;
} catch (e) {
return {
status: "ERR",
query: query,
message: e.message
};
}
}

View File

@@ -0,0 +1,69 @@
var dialogFormComponent = {
template: `
<template>
<v-layout row justify-center>
<v-dialog v-model="dialog" persistent max-width="500px">
<v-btn slot="activator" color="primary" dark>Open Dialog</v-btn>
<v-card>
<v-card-title>
<span class="headline">User Profile</span>
</v-card-title>
<v-card-text>
<v-container grid-list-md>
<v-layout wrap>
<v-flex xs12 sm6 md4>
<v-text-field label="Legal first name" required></v-text-field>
</v-flex>
<v-flex xs12 sm6 md4>
<v-text-field label="Legal middle name" hint="example of helper text only on focus"></v-text-field>
</v-flex>
<v-flex xs12 sm6 md4>
<v-text-field
label="Legal last name"
hint="example of persistent helper text"
persistent-hint
required
></v-text-field>
</v-flex>
<v-flex xs12>
<v-text-field label="Email" required></v-text-field>
</v-flex>
<v-flex xs12>
<v-text-field label="Password" type="password" required></v-text-field>
</v-flex>
<v-flex xs12 sm6>
<v-select
:items="['0-17', '18-29', '30-54', '54+']"
label="Age"
required
></v-select>
</v-flex>
<v-flex xs12 sm6>
<v-autocomplete
:items="['Skiing', 'Ice hockey', 'Soccer', 'Basketball', 'Hockey', 'Reading', 'Writing', 'Coding', 'Basejump']"
label="Interests"
multiple
chips
></v-autocomplete>
</v-flex>
</v-layout>
</v-container>
<small>*indicates required field</small>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" flat @click.native="dialog = false">Close</v-btn>
<v-btn color="blue darken-1" flat @click.native="dialog = false">Save</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-layout>
</template>
`,
data: () => ({
dialog: false
})
};
export { dialogFormComponent };

View File

@@ -0,0 +1,139 @@
var listBankComponent = {
template: `
<v-card class="xs12 md12" >
<v-card-title>
<v-layout>
<v-flex xs12 sm8>
<v-toolbar-title>Bank Listing <v-btn depressed small color="primary">New Data</v-btn></v-toolbar-title>
</v-flex>
<v-flex xs12 sm4>
<v-spacer></v-spacer>
<v-text-field
v-model="query"
append-icon="search"
@click:clear="clearSearch"
@keydown.enter="doSearch"
@click:append="doSearch"
label="Search"
single-line
hide-details
clearable
class="xs12 md3"
></v-text-field>
</v-flex>
</v-layout>
</v-card-title>
<v-data-table :headers="headers" :items="banks"
:loading="isLoading"
hide-actions class="elevation-1">
<template slot="items" slot-scope="props">
<td class="text-xs-center">{{ props.item.M_BankCode }}</td>
<td>{{ props.item.M_BankName }}</td>
<td>{{ props.item.M_BankAddress }}</td>
<td>{{ props.item.M_BankBranch }}</td>
<td><v-btn depressed small color="info">Edit</v-btn> <v-btn depressed small color="error">Delete</v-btn></td>
</template>
<template slot="no-data">
<v-alert :value="isError" color="error" icon="warning">
{{errorMessage}}
</v-alert>
<v-spacer></v-spacer>
</template>
<template slot="footer">
<td colspan="2" class="text-xs-left">
Total Records : {{totalRecord}}, page {{page}} of {{totalPage}}.
</td>
<td colspan="3" class="text-xs-right">
<v-pagination :length="totalPage" :value="page" :total-visible="10"
@next="nextPage" @prev="prevPage"
@input="gotoPage" >
</v-pagination>
</td>
</template>
</v-data-table>
</v-card>
`,
mounted() {
this.doSearch();
},
data() {
return {
query: "",
headers: [{
text: "Code",
align: "left",
sortable: false,
value: "M_BankCode"
},
{
text: "Name",
align: "left",
sortable: false,
value: "M_BankName"
},
{
text: "Address",
value: "M_BankAddress",
sortable: false,
align: "left",
width: "30%"
},
{
text: "Branch",
value: "M_BankBranch",
sortable: false,
align: "left"
},
{
text: "Action",
value: "action",
sortable: false,
align: "center",
width: "20%"
}
]
};
},
methods: {
clearSearch() {
this.query = "";
this.doSearch();
},
doSearch(page = 1, rowPerPage = 8) {
if (this.query == null) this.query = "";
this.$store.dispatch("searchBank", {
query: this.query,
page,
rowPerPage
});
},
prevPage() {
let c_page = this.page - 1;
this.doSearch(c_page);
},
nextPage() {
let c_page = this.page + 1;
this.doSearch(c_page);
},
gotoPage(e) {
let c_page = e;
this.doSearch(c_page);
}
},
computed: {
...Vuex.mapState({
isLoading: state => state.isLoading,
isError: state => state.isError,
errorMessage: state => state.errorMessage,
banks: state => state.rows,
totalRecord: state => state.totalRecord,
page: state => state.page,
totalPage: state => state.totalPage
})
},
updated() {
console.log("Component Updated");
}
};
export { listBankComponent };

View File

@@ -0,0 +1,138 @@
var listPatientComponent = {
template: `
<v-card class="xs12 md12" >
<v-card-title>
<v-layout>
<v-flex xs12 sm8>
<v-toolbar-title>Patient Listing</v-toolbar-title>
</v-flex>
<v-flex xs12 sm4>
<v-spacer></v-spacer>
<v-text-field
v-model="query"
append-icon="search"
@click:clear="clearSearch"
@keydown.enter="doSearch"
@click:append="doSearch"
label="Search"
single-line
hide-details
clearable
class="xs12 md3"
></v-text-field>
</v-flex>
</v-layout>
</v-card-title>
<v-data-table :headers="headers" :items="patients"
:loading="isLoading"
hide-actions class="elevation-1">
<template slot="items" slot-scope="props">
<td>{{ props.item.M_PatientNoReg }}</td>
<td>{{ props.item.M_PatientName }}</td>
<td class="text-xs-center">{{ props.item.M_PatientDOB }}</td>
<td>{{ props.item.M_PatientHP }}</td>
<td>{{ props.item.M_PatientAddress }}</td>
</template>
<template slot="no-data">
<v-alert :value="isError" color="error" icon="warning">
{{errorMessage}}
</v-alert>
<v-spacer></v-spacer>
</template>
<template slot="footer">
<td colspan="2" class="text-xs-left">
Total Records : {{totalRecord}}, page {{page}} of {{totalPage}}.
</td>
<td colspan="3" class="text-xs-right">
<v-pagination :length="totalPage" :value="page" :total-visible="10"
@next="nextPage" @prev="prevPage"
@input="gotoPage" >
</v-pagination>
</td>
</template>
</v-data-table>
</v-card>
`,
mounted() {
this.doSearch();
},
data() {
return {
query: "",
headers: [
{
text: "No. Reg",
align: "left",
sortable: false,
value: "M_PatientNoReg"
},
{
text: "Name",
align: "left",
sortable: false,
value: "M_PatientName"
},
{
text: "DOB",
align: "center",
sortable: false,
value: "M_PatientDOB"
},
{
text: "HP",
value: "M_PatientHP",
sortable: false,
align: "left"
},
{
text: "Address",
value: "M_PatientAddress",
sortable: false,
align: "left"
}
]
};
},
methods: {
clearSearch() {
this.query = "";
this.doSearch();
},
doSearch(page = 1, rowPerPage = 8) {
if (this.query == null) this.query = "";
this.$store.dispatch("searchPatient", {
query: this.query,
page,
rowPerPage
});
},
prevPage() {
let c_page = this.page - 1;
this.doSearch(c_page);
},
nextPage() {
let c_page = this.page + 1;
this.doSearch(c_page);
},
gotoPage(e) {
let c_page = e;
this.doSearch(c_page);
}
},
computed: {
...Vuex.mapState({
isLoading: state => state.isLoading,
isError: state => state.isError,
errorMessage: state => state.errorMessage,
patients: state => state.rows,
totalRecord: state => state.totalRecord,
page: state => state.page,
totalPage: state => state.totalPage
})
},
updated() {
console.log("Component Updated");
}
};
export { listPatientComponent };

View File

@@ -0,0 +1,12 @@
var searchComponent = {
template: `
<div>
<h1>Search Component</h1>
</div>
`,
data() {
return {};
},
methods: {}
};
export { searchComponent };

View File

@@ -0,0 +1,38 @@
var smartNavbarComponent = {
template: `
<span>
<v-navigation-drawer v-model="drawer" fixed app>
<v-list dense>
<v-list-tile>
<v-list-tile-action>
<v-icon>home</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Home</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
<v-list-tile>
<v-list-tile-action>
<v-icon>contact_mail</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Contact</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-navigation-drawer>
<v-toolbar color="blue lighten-2" dark fixed app>
<v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
<v-toolbar-title>Application</v-toolbar-title>
</v-toolbar>
</span>
`,
data: function() {
return {
drawer: false
};
},
methods: {}
};
export { smartNavbarComponent };

View File

@@ -0,0 +1,68 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Test 02 Vuex</title>
<link rel="stylesheet" href="../../../libs/vendor/css/google-fonts.css">
<link rel="stylesheet" href="../../../libs/vendor/css/vuetify.min.css">
</head>
<body>
<div v-cloak id="app">
<v-app id="smartApp" >
<smart-navbar></smart-navbar>
<v-content class="blue lighten-5" >
<v-container fluid fill-height style="height:inherit">
<v-flex size="xs12">
<list-bank fill-height></list-bank>
</v-flex>
</v-container>
</v-content>
<v-footer color="blue lighten-2" app>
<span class="white--text">&copy; 2017</span>
</v-footer>
</v-app>
</div>
<!-- Vendor -->
<script src="../../../libs/vendor/axios.min.js"></script>
<script src="../../../libs/vendor/vue.js"></script>
<script src="../../../libs/vendor/vuex.js"></script>
<script src="../../../libs/vendor/vuetify.js"></script>
<!-- App Script -->
<?php
$ts = "?ts=" . Date("ymdhis");
?>
<script type="module">
import { store } from './store.js<?php echo $ts ?>';
import { smartNavbarComponent } from './components/smartNavbarComponent.js<?php echo $ts ?>';
import { listBankComponent } from './components/listBankComponent.js<?php echo $ts ?>';
import { dialogFormComponent } from './components/dialogFormComponent.js<?php echo $ts ?>';
//for testing
// window.store = store;
new Vue({
store,
el: '#app',
components: {
'smart-navbar': smartNavbarComponent,
'list-bank': listBankComponent,
'dialog-form':dialogFormComponent
},
data: {
drawer: false,
}
})
</script>
<style>
[v-cloak] {
display: none
}
</style>
</body>
</html>

View File

View File

@@ -0,0 +1,71 @@
// State
// data ...
// Mutations
//
//
// Actions
import * as api from "./api.js";
export const store = new Vuex.Store({
state: {
rows: [],
midPages: [],
isLoading: false,
isError: false,
errorMessage: "",
query: "",
page: 0,
totalPage: 0,
totalRecord: 0
},
mutations: {
updateBank(state, data) {
// console.log(data);
if (data.status == "ERR") {
state.isError = true;
if (data.db_error) {
state.errorMessage = data.db_error.message;
} else {
state.errorMessage = data.message;
}
state.query = data.query;
state.page = 0;
state.totalPage = 0;
state.totalRecord = 0;
state.rows = [];
state.midPages = [];
} else {
state.isError = false;
state.errorMessage = "";
state.query = data.query;
state.page = data.page;
state.totalPage = data.totalPage;
state.totalRecord = data.totalRecord;
state.rows = data.rows;
state.midPages = data.midPages;
}
},
updateLoading(state, flag) {
state.isLoading = flag;
},
resetError(state) {
state.isError = false;
state.errorMessage = "";
}
},
actions: {
async searchBank(context, data) {
context.commit("updateLoading", true);
let resp = await api.searchBank(
data.query,
data.page,
data.rowPerPage
);
context.commit("updateLoading", false);
context.commit("updateBank", resp);
setTimeout(function() {
context.commit("resetError");
}, 5000);
}
}
});

View File

31
test/vuex/lama/t03/api.js Normal file
View File

@@ -0,0 +1,31 @@
// API :
// search doctor
// paramater : query , page , rowPerPage
const URL =
"http://lebaran.aplikasi.web.id/smartlab_api/vuex/t03/search_doctor";
export async function searchDoctor(query, page, rowPerPage = 15) {
try {
var resp = await axios.post(URL, {
query: query,
page: page,
rowPerPage: rowPerPage
});
if (resp.status != 200) {
return {
status: "ERR",
query: query,
message: resp.statusText
};
}
let data = resp.data;
data.query = query;
return data;
} catch (e) {
return {
status: "ERR",
query: query,
message: e.message
};
}
}

View File

@@ -0,0 +1,69 @@
var dialogFormComponent = {
template: `
<template>
<v-layout row justify-center>
<v-dialog v-model="dialog" persistent max-width="500px">
<v-btn slot="activator" color="primary" dark>Open Dialog</v-btn>
<v-card>
<v-card-title>
<span class="headline">User Profile</span>
</v-card-title>
<v-card-text>
<v-container grid-list-md>
<v-layout wrap>
<v-flex xs12 sm6 md4>
<v-text-field label="Legal first name" required></v-text-field>
</v-flex>
<v-flex xs12 sm6 md4>
<v-text-field label="Legal middle name" hint="example of helper text only on focus"></v-text-field>
</v-flex>
<v-flex xs12 sm6 md4>
<v-text-field
label="Legal last name"
hint="example of persistent helper text"
persistent-hint
required
></v-text-field>
</v-flex>
<v-flex xs12>
<v-text-field label="Email" required></v-text-field>
</v-flex>
<v-flex xs12>
<v-text-field label="Password" type="password" required></v-text-field>
</v-flex>
<v-flex xs12 sm6>
<v-select
:items="['0-17', '18-29', '30-54', '54+']"
label="Age"
required
></v-select>
</v-flex>
<v-flex xs12 sm6>
<v-autocomplete
:items="['Skiing', 'Ice hockey', 'Soccer', 'Basketball', 'Hockey', 'Reading', 'Writing', 'Coding', 'Basejump']"
label="Interests"
multiple
chips
></v-autocomplete>
</v-flex>
</v-layout>
</v-container>
<small>*indicates required field</small>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" flat @click.native="dialog = false">Close</v-btn>
<v-btn color="blue darken-1" flat @click.native="dialog = false">Save</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-layout>
</template>
`,
data: () => ({
dialog: false
})
};
export { dialogFormComponent };

View File

@@ -0,0 +1,139 @@
var listBankComponent = {
template: `
<v-card class="xs12 md12" >
<v-card-title>
<v-layout>
<v-flex xs12 sm8>
<v-toolbar-title>Bank Listing <v-btn depressed small color="primary">New Data</v-btn></v-toolbar-title>
</v-flex>
<v-flex xs12 sm4>
<v-spacer></v-spacer>
<v-text-field
v-model="query"
append-icon="search"
@click:clear="clearSearch"
@keydown.enter="doSearch"
@click:append="doSearch"
label="Search"
single-line
hide-details
clearable
class="xs12 md3"
></v-text-field>
</v-flex>
</v-layout>
</v-card-title>
<v-data-table :headers="headers" :items="banks"
:loading="isLoading"
hide-actions class="elevation-1">
<template slot="items" slot-scope="props">
<td class="text-xs-center">{{ props.item.M_BankCode }}</td>
<td>{{ props.item.M_BankName }}</td>
<td>{{ props.item.M_BankAddress }}</td>
<td>{{ props.item.M_BankBranch }}</td>
<td><v-btn depressed small color="info">Edit</v-btn> <v-btn depressed small color="error">Delete</v-btn></td>
</template>
<template slot="no-data">
<v-alert :value="isError" color="error" icon="warning">
{{errorMessage}}
</v-alert>
<v-spacer></v-spacer>
</template>
<template slot="footer">
<td colspan="2" class="text-xs-left">
Total Records : {{totalRecord}}, page {{page}} of {{totalPage}}.
</td>
<td colspan="3" class="text-xs-right">
<v-pagination :length="totalPage" :value="page" :total-visible="10"
@next="nextPage" @prev="prevPage"
@input="gotoPage" >
</v-pagination>
</td>
</template>
</v-data-table>
</v-card>
`,
mounted() {
this.doSearch();
},
data() {
return {
query: "",
headers: [
{
text: "Code",
align: "left",
sortable: false,
value: "M_BankCode"
},
{
text: "Name",
align: "left",
sortable: false,
value: "M_BankName"
},
{
text: "Address",
value: "M_BankAddress",
sortable: false,
align: "left"
},
{
text: "Branch",
value: "M_BankBranch",
sortable: false,
align: "left"
},
{
text: "Action",
value: "action",
sortable: false,
align: "center",
width:"18%"
}
]
};
},
methods: {
clearSearch() {
this.query = "";
this.doSearch();
},
doSearch(page = 1, rowPerPage = 8) {
if (this.query == null) this.query = "";
this.$store.dispatch("searchBank", {
query: this.query,
page,
rowPerPage
});
},
prevPage() {
let c_page = this.page - 1;
this.doSearch(c_page);
},
nextPage() {
let c_page = this.page + 1;
this.doSearch(c_page);
},
gotoPage(e) {
let c_page = e;
this.doSearch(c_page);
}
},
computed: {
...Vuex.mapState({
isLoading: state => state.isLoading,
isError: state => state.isError,
errorMessage: state => state.errorMessage,
banks: state => state.rows,
totalRecord: state => state.totalRecord,
page: state => state.page,
totalPage: state => state.totalPage
})
},
updated() {
console.log("Component Updated");
}
};
export { listBankComponent };

View File

@@ -0,0 +1,140 @@
var listDoctorComponent = {
template: `
<v-card class="xs12 md12" >
<v-card-title>
<v-layout>
<v-flex xs12 sm8>
<v-toolbar-title>Doctor Listing <v-btn depressed small color="primary">New Data</v-btn></v-toolbar-title>
</v-flex>
<v-flex xs12 sm4>
<v-spacer></v-spacer>
<v-text-field
v-model="query"
append-icon="search"
@click:clear="clearSearch"
@keydown.enter="doSearch"
@click:append="doSearch"
label="Search"
single-line
hide-details
clearable
class="xs12 md3"
></v-text-field>
</v-flex>
</v-layout>
</v-card-title>
<v-data-table :headers="headers" :items="doctor"
:loading="isLoading"
hide-actions class="elevation-1">
<template slot="items" slot-scope="props">
<td>{{ props.item.M_DoctorName}}</td>
<td>{{ props.item.M_DoctorPracticeAddress}}</td>
<td>{{ props.item.M_DoctorHP}}</td>
<td>{{ props.item.M_DoctorPhone}}</td>
<td><v-btn depressed small color="info">Edit</v-btn> <v-btn depressed small color="error">Delete</v-btn></td>
</template>
<template slot="no-data">
<v-alert :value="isError" color="error" icon="warning">
{{errorMessage}}
</v-alert>
<v-spacer></v-spacer>
</template>
<template slot="footer">
<td colspan="2" class="text-xs-left">
Total Records : {{totalRecord}}, page {{page}} of {{totalPage}}.
</td>
<td colspan="3" class="text-xs-right">
<v-pagination :length="totalPage" :value="page" :total-visible="10"
@next="nextPage" @prev="prevPage"
@input="gotoPage" >
</v-pagination>
</td>
</template>
</v-data-table>
</v-card>
`,
mounted() {
this.doSearch();
},
data() {
return {
query: "",
headers: [
{
text: "Name",
align: "center",
sortable: true,
value: "M_DoctorName"
},
{
text: "Address",
align: "center",
sortable: true,
value: "M_DoctorPracticeAddress"
},
{
text: "HP",
value: "M_DoctorHP",
sortable: false,
align: "center"
},
{
text: "Phone",
value: "M_DoctorPhone",
sortable: false,
align: "center"
},
{
text: "Action",
value: "action",
sortable: false,
align: "center",
width:"10%"
}
]
};
},
methods: {
clearSearch() {
this.query = "";
this.doSearch();
},
doSearch(page = 1, rowPerPage = 8) {
if (this.query == null) this.query = "";
this.$store.dispatch("searchDoctor", {
query: this.query,
page,
rowPerPage
});
},
prevPage() {
let c_page = this.page - 1;
this.doSearch(c_page);
},
nextPage() {
let c_page = this.page + 1;
this.doSearch(c_page);
},
gotoPage(e) {
let c_page = e;
this.doSearch(c_page);
}
},
computed: {
...Vuex.mapState({
isLoading: state => state.isLoading,
isError: state => state.isError,
errorMessage: state => state.errorMessage,
doctor: state => state.rows,
totalRecord: state => state.totalRecord,
page: state => state.page,
totalPage: state => state.totalPage
})
},
updated() {
console.log("Component Updated");
}
};
export { listDoctorComponent };

View File

@@ -0,0 +1,138 @@
var listPatientComponent = {
template: `
<v-card class="xs12 md12" >
<v-card-title>
<v-layout>
<v-flex xs12 sm8>
<v-toolbar-title>Patient Listing</v-toolbar-title>
</v-flex>
<v-flex xs12 sm4>
<v-spacer></v-spacer>
<v-text-field
v-model="query"
append-icon="search"
@click:clear="clearSearch"
@keydown.enter="doSearch"
@click:append="doSearch"
label="Search"
single-line
hide-details
clearable
class="xs12 md3"
></v-text-field>
</v-flex>
</v-layout>
</v-card-title>
<v-data-table :headers="headers" :items="patients"
:loading="isLoading"
hide-actions class="elevation-1">
<template slot="items" slot-scope="props">
<td>{{ props.item.M_PatientNoReg }}</td>
<td>{{ props.item.M_PatientName }}</td>
<td class="text-xs-center">{{ props.item.M_PatientDOB }}</td>
<td>{{ props.item.M_PatientHP }}</td>
<td>{{ props.item.M_PatientAddress }}</td>
</template>
<template slot="no-data">
<v-alert :value="isError" color="error" icon="warning">
{{errorMessage}}
</v-alert>
<v-spacer></v-spacer>
</template>
<template slot="footer">
<td colspan="2" class="text-xs-left">
Total Records : {{totalRecord}}, page {{page}} of {{totalPage}}.
</td>
<td colspan="3" class="text-xs-right">
<v-pagination :length="totalPage" :value="page" :total-visible="10"
@next="nextPage" @prev="prevPage"
@input="gotoPage" >
</v-pagination>
</td>
</template>
</v-data-table>
</v-card>
`,
mounted() {
this.doSearch();
},
data() {
return {
query: "",
headers: [
{
text: "No. Reg",
align: "left",
sortable: false,
value: "M_PatientNoReg"
},
{
text: "Name",
align: "left",
sortable: false,
value: "M_PatientName"
},
{
text: "DOB",
align: "center",
sortable: false,
value: "M_PatientDOB"
},
{
text: "HP",
value: "M_PatientHP",
sortable: false,
align: "left"
},
{
text: "Address",
value: "M_PatientAddress",
sortable: false,
align: "left"
}
]
};
},
methods: {
clearSearch() {
this.query = "";
this.doSearch();
},
doSearch(page = 1, rowPerPage = 8) {
if (this.query == null) this.query = "";
this.$store.dispatch("searchPatient", {
query: this.query,
page,
rowPerPage
});
},
prevPage() {
let c_page = this.page - 1;
this.doSearch(c_page);
},
nextPage() {
let c_page = this.page + 1;
this.doSearch(c_page);
},
gotoPage(e) {
let c_page = e;
this.doSearch(c_page);
}
},
computed: {
...Vuex.mapState({
isLoading: state => state.isLoading,
isError: state => state.isError,
errorMessage: state => state.errorMessage,
patients: state => state.rows,
totalRecord: state => state.totalRecord,
page: state => state.page,
totalPage: state => state.totalPage
})
},
updated() {
console.log("Component Updated");
}
};
export { listPatientComponent };

View File

@@ -0,0 +1,12 @@
var searchComponent = {
template: `
<div>
<h1>Search Component</h1>
</div>
`,
data() {
return {};
},
methods: {}
};
export { searchComponent };

View File

@@ -0,0 +1,38 @@
var smartNavbarComponent = {
template: `
<span>
<v-navigation-drawer v-model="drawer" fixed app>
<v-list dense>
<v-list-tile>
<v-list-tile-action>
<v-icon>home</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Home</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
<v-list-tile>
<v-list-tile-action>
<v-icon>contact_mail</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Contact</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-navigation-drawer>
<v-toolbar color="indigo" dark fixed app>
<v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
<v-toolbar-title>Application</v-toolbar-title>
</v-toolbar>
</span>
`,
data: function() {
return {
drawer: false
};
},
methods: {}
};
export { smartNavbarComponent };

View File

@@ -0,0 +1,68 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Test 03</title>
<link rel="stylesheet" href="../../../libs/vendor/css/google-fonts.css">
<link rel="stylesheet" href="../../../libs/vendor/css/vuetify.min.css">
</head>
<body>
<div v-cloak id="app">
<v-app id="smartApp">
<smart-navbar></smart-navbar>
<v-content>
<v-container fluid fill-height style="height:inherit">
<v-flex size="xs12">
<list-doctor fill-height></list-doctor>
</v-flex>
</v-container>
</v-content>
<v-footer color="indigo" app>
<span class="white--text">&copy; 2017</span>
</v-footer>
</v-app>
</div>
<!-- Vendor -->
<script src="../../../libs/vendor/axios.min.js"></script>
<script src="../../../libs/vendor/vue.js"></script>
<script src="../../../libs/vendor/vuex.js"></script>
<script src="../../../libs/vendor/vuetify.js"></script>
<!-- App Script -->
<?php
$ts = "?ts=" . Date("ymdhis");
?>
<script type="module">
import { store } from './store.js<?php echo $ts ?>';
import { smartNavbarComponent } from './components/smartNavbarComponent.js<?php echo $ts ?>';
import { listDoctorComponent } from './components/listDoctorComponent.js<?php echo $ts ?>';
import { dialogFormComponent } from './components/dialogFormComponent.js<?php echo $ts ?>';
//for testing
// window.store = store;
new Vue({
store,
el: '#app',
components: {
'smart-navbar': smartNavbarComponent,
'list-doctor': listDoctorComponent,
'dialog-form':dialogFormComponent
},
data: {
drawer: false,
}
})
</script>
<style>
[v-cloak] {
display: none
}
</style>
</body>
</html>

View File

View File

@@ -0,0 +1,71 @@
// State
// data ...
// Mutations
//
//
// Actions
import * as api from "./api.js";
export const store = new Vuex.Store({
state: {
rows: [],
midPages: [],
isLoading: false,
isError: false,
errorMessage: "",
query: "",
page: 0,
totalPage: 0,
totalRecord: 0
},
mutations: {
updateDoctor(state, data) {
// console.log(data);
if (data.status == "ERR") {
state.isError = true;
if (data.db_error) {
state.errorMessage = data.db_error.message;
} else {
state.errorMessage = data.message;
}
state.query = data.query;
state.page = 0;
state.totalPage = 0;
state.totalRecord = 0;
state.rows = [];
state.midPages = [];
} else {
state.isError = false;
state.errorMessage = "";
state.query = data.query;
state.page = data.page;
state.totalPage = data.totalPage;
state.totalRecord = data.totalRecord;
state.rows = data.rows;
state.midPages = data.midPages;
}
},
updateLoading(state, flag) {
state.isLoading = flag;
},
resetError(state) {
state.isError = false;
state.errorMessage = "";
}
},
actions: {
async searchDoctor(context, data) {
context.commit("updateLoading", true);
let resp = await api.searchDoctor(
data.query,
data.page,
data.rowPerPage
);
context.commit("updateLoading", false);
context.commit("updateDoctor", resp);
setTimeout(function() {
context.commit("resetError");
}, 5000);
}
}
});

31
test/vuex/lama/t04/api.js Normal file
View File

@@ -0,0 +1,31 @@
// API :
// search patient
// paramater : query , page , rowPerPage
const URL =
"http://lebaran.aplikasi.web.id/smartlab_api/vuex/t04/search_test";
export async function searchPatient(query, page, rowPerPage = 15) {
try {
var resp = await axios.post(URL, {
query: query,
page: page,
rowPerPage: rowPerPage
});
if (resp.status != 200) {
return {
status: "ERR",
query: query,
message: resp.statusText
};
}
let data = resp.data;
data.query = query;
return data;
} catch (e) {
return {
status: "ERR",
query: query,
message: e.message
};
}
}

View File

@@ -0,0 +1,124 @@
var listPatientComponent = {
template: `
<v-card class="xs12 md12" >
<v-card-title>
<v-layout>
<v-flex xs12 sm8>
<v-toolbar-title>Test Listing</v-toolbar-title>
</v-flex>
<v-flex xs12 sm4>
<v-spacer></v-spacer>
<v-text-field
v-model="query"
append-icon="search"
@click:clear="clearSearch"
@keydown.enter="doSearch"
@click:append="doSearch"
label="Search"
single-line
hide-details
clearable
class="xs12 md3"
></v-text-field>
</v-flex>
</v-layout>
</v-card-title>
<v-data-table :headers="headers" :items="patients"
:loading="isLoading"
hide-actions class="elevation-1">
<template slot="items" slot-scope="props">
<td width="10%">{{ props.item.T_TestCode }}</td>
<td width="20%">{{ props.item.T_TestName }}</td>
<td>{{ props.item.T_RefTestName }}</td>
</template>
<template slot="no-data">
<v-alert :value="isError" color="error" icon="warning">
{{errorMessage}}
</v-alert>
<v-spacer></v-spacer>
</template>
<template slot="footer">
<td colspan="2" class="text-xs-left">
Total Records : {{totalRecord}}, page {{page}} of {{totalPage}}.
</td>
<td colspan="3" class="text-xs-right">
<v-pagination :length="totalPage" :value="page" :total-visible="10"
@next="nextPage" @prev="prevPage"
@input="gotoPage" >
</v-pagination>
</td>
</template>
</v-data-table>
</v-card>
`,
mounted() {
this.doSearch();
},
data() {
return {
query: "",
headers: [
{
text: "CODE",
align: "left",
sortable: false,
value: "T_TestCode"
},
{
text: "NAME",
align: "left",
sortable: false,
value: "T_TestName"
},
{
text: "REF TEST",
align: "left",
sortable: false,
value: "T_RefTestName"
}
]
};
},
methods: {
clearSearch() {
this.query = "";
this.doSearch();
},
doSearch(page = 1, rowPerPage = 8) {
if (this.query == null) this.query = "";
this.$store.dispatch("searchPatient", {
query: this.query,
page,
rowPerPage
});
},
prevPage() {
let c_page = this.page - 1;
this.doSearch(c_page);
},
nextPage() {
let c_page = this.page + 1;
this.doSearch(c_page);
},
gotoPage(e) {
let c_page = e;
this.doSearch(c_page);
}
},
computed: {
...Vuex.mapState({
isLoading: state => state.isLoading,
isError: state => state.isError,
errorMessage: state => state.errorMessage,
patients: state => state.rows,
totalRecord: state => state.totalRecord,
page: state => state.page,
totalPage: state => state.totalPage
})
},
updated() {
console.log("Component Updated");
}
};
export { listPatientComponent };

View File

@@ -0,0 +1,38 @@
var smartNavbarComponent = {
template: `
<span>
<v-navigation-drawer v-model="drawer" fixed app>
<v-list dense>
<v-list-tile>
<v-list-tile-action>
<v-icon>home</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Home</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
<v-list-tile>
<v-list-tile-action>
<v-icon>contact_mail</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Contact</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-navigation-drawer>
<v-toolbar color="indigo" dark fixed app>
<v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
<v-toolbar-title>Application</v-toolbar-title>
</v-toolbar>
</span>
`,
data: function() {
return {
drawer: false
};
},
methods: {}
};
export { smartNavbarComponent };

View File

@@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Test 04 Vuex</title>
<link rel="stylesheet" href="../../../libs/vendor/css/google-fonts.css">
<link rel="stylesheet" href="../../../libs/vendor/css/vuetify.min.css">
</head>
<body>
<div v-cloak id="app">
<v-app id="smartApp">
<smart-navbar></smart-navbar>
<v-content>
<v-container fluid fill-height style="height:inherit">
<v-flex size="xs12">
<list-patient fill-height></list-patient>
</v-flex>
</v-container>
</v-content>
<v-footer color="indigo" app>
<span class="white--text">&copy; 2017</span>
</v-footer>
</v-app>
</div>
<!-- Vendor -->
<script src="../../../libs/vendor/axios.min.js"></script>
<script src="../../../libs/vendor/vue.js"></script>
<script src="../../../libs/vendor/vuex.js"></script>
<script src="../../../libs/vendor/vuetify.js"></script>
<!-- App Script -->
<?php
$ts = "?ts=" . Date("ymdhis");
?>
<script type="module">
import { store } from './store.js<?php echo $ts ?>';
import { smartNavbarComponent } from './components/smartNavbarComponent.js<?php echo $ts ?>';
import { listPatientComponent } from './components/listPatientComponent.js<?php echo $ts ?>';
//for testing
// window.store = store;
new Vue({
store,
el: '#app',
components: {
'smart-navbar': smartNavbarComponent,
'list-patient': listPatientComponent,
},
data: {
drawer: false,
}
})
</script>
<style>
[v-cloak] {
display: none
}
</style>
</body>
</html>

View File

@@ -0,0 +1,71 @@
// State
// data ...
// Mutations
//
//
// Actions
import * as api from "./api.js";
export const store = new Vuex.Store({
state: {
rows: [],
midPages: [],
isLoading: false,
isError: false,
errorMessage: "",
query: "",
page: 0,
totalPage: 0,
totalRecord: 0
},
mutations: {
updatePatient(state, data) {
// console.log(data);
if (data.status == "ERR") {
state.isError = true;
if (data.db_error) {
state.errorMessage = data.db_error.message;
} else {
state.errorMessage = data.message;
}
state.query = data.query;
state.page = 0;
state.totalPage = 0;
state.totalRecord = 0;
state.rows = [];
state.midPages = [];
} else {
state.isError = false;
state.errorMessage = "";
state.query = data.query;
state.page = data.page;
state.totalPage = data.totalPage;
state.totalRecord = data.totalRecord;
state.rows = data.rows;
state.midPages = data.midPages;
}
},
updateLoading(state, flag) {
state.isLoading = flag;
},
resetError(state) {
state.isError = false;
state.errorMessage = "";
}
},
actions: {
async searchPatient(context, data) {
context.commit("updateLoading", true);
let resp = await api.searchPatient(
data.query,
data.page,
data.rowPerPage
);
context.commit("updateLoading", false);
context.commit("updatePatient", resp);
setTimeout(function() {
context.commit("resetError");
}, 5000);
}
}
});

View File

31
test/vuex/lama/t05/api.js Normal file
View File

@@ -0,0 +1,31 @@
// API :
// search patient
// paramater : query , page , rowPerPage
const URL =
"http://lebaran.aplikasi.web.id/smartlab_api/vuex/t05/search_patienttype";
export async function searchPatientType(query, page, rowPerPage = 15) {
try {
var resp = await axios.post(URL, {
query: query,
page: page,
rowPerPage: rowPerPage
});
if (resp.status != 200) {
return {
status: "ERR",
query: query,
message: resp.statusText
};
}
let data = resp.data;
data.query = query;
return data;
} catch (e) {
return {
status: "ERR",
query: query,
message: e.message
};
}
}

View File

@@ -0,0 +1,138 @@
var listPatientTypeComponent = {
template: `
<v-card class="xs12 md12" >
<v-card-title>
<v-layout>
<v-flex xs12 sm8>
<v-toolbar-title>Patient Type Listing</v-toolbar-title>
</v-flex>
<v-flex xs12 sm4>
<v-spacer></v-spacer>
<v-text-field
v-model="query"
append-icon="search"
@click:clear="clearSearch"
@keydown.enter="doSearch"
@click:append="doSearch"
label="Search"
single-line
hide-details
clearable
class="xs12 md3"
></v-text-field>
</v-flex>
</v-layout>
</v-card-title>
<v-data-table :headers="headers" :items="patienttypes"
:loading="isLoading"
hide-actions class="elevation-1">
<template slot="items" slot-scope="props">
<td>{{ props.item.M_PatientTypeName }}</td>
<td>{{ props.item.M_PatientTypeAddress }}</td>
<td>{{ props.item.M_PatientTypeMOUPIC }}</td>
<td>{{ props.item.M_PatientTypePhone }}</td>
<td>{{ props.item.M_PatientTypeEmail }}</td>
</template>
<template slot="no-data">
<v-alert :value="isError" color="error" icon="warning">
{{errorMessage}}
</v-alert>
<v-spacer></v-spacer>
</template>
<template slot="footer">
<td colspan="2" class="text-xs-left">
Total Records : {{totalRecord}}, page {{page}} of {{totalPage}}.
</td>
<td colspan="3" class="text-xs-right">
<v-pagination :length="totalPage" :value="page" :total-visible="10"
@next="nextPage" @prev="prevPage"
@input="gotoPage" >
</v-pagination>
</td>
</template>
</v-data-table>
</v-card>
`,
mounted() {
this.doSearch();
},
data() {
return {
query: "",
headers: [
{
text: "Name",
align: "left",
sortable: false,
value: "M_PatientTypeName"
},
{
text: "Addres",
align: "left",
sortable: false,
value: "M_PatientTypeAddress"
},
{
text: "PIC",
value: "M_PatientTypeMOUPIC",
sortable: false,
align: "left"
},
{
text: "Phone",
value: "M_PatientTypePhone",
sortable: false,
align: "left"
},
{
text: "Email",
value: "M_PatientTypeEmail",
sortable: false,
align: "left"
}
]
};
},
methods: {
clearSearch() {
this.query = "";
this.doSearch();
},
doSearch(page = 1, rowPerPage = 8) {
if (this.query == null) this.query = "";
this.$store.dispatch("searchPatientType", {
query: this.query,
page,
rowPerPage
});
},
prevPage() {
let c_page = this.page - 1;
this.doSearch(c_page);
},
nextPage() {
let c_page = this.page + 1;
this.doSearch(c_page);
},
gotoPage(e) {
let c_page = e;
this.doSearch(c_page);
}
},
computed: {
...Vuex.mapState({
isLoading: state => state.isLoading,
isError: state => state.isError,
errorMessage: state => state.errorMessage,
patienttypes: state => state.rows,
totalRecord: state => state.totalRecord,
page: state => state.page,
totalPage: state => state.totalPage
})
},
updated() {
console.log("Component Updated");
}
};
export { listPatientTypeComponent };

View File

@@ -0,0 +1,92 @@
var smartNavbarComponent = {
template: `
<span>
<v-navigation-drawer
v-model="drawer"
fixed
clipped
class="grey lighten-4"
app
>
<v-list
dense
class="grey lighten-4"
>
<template v-for="(item, i) in items">
<v-layout
v-if="item.heading"
:key="i"
row
align-center
>
<v-flex xs6>
<v-subheader v-if="item.heading">
{{ item.heading }}
</v-subheader>
</v-flex>
<v-flex xs6 class="text-xs-right">
<v-btn small flat>edit</v-btn>
</v-flex>
</v-layout>
<v-divider
v-else-if="item.divider"
:key="i"
dark
class="my-3"
></v-divider>
<v-list-tile
v-else
:key="i"
@click=""
>
<v-list-tile-action>
<v-icon>{{ item.icon }}</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title class="grey--text">
{{ item.text }}
</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</template>
</v-list>
</v-navigation-drawer>
<v-toolbar color="amber" app absolute clipped-left>
<v-toolbar-side-icon @click.native="drawer = !drawer"></v-toolbar-side-icon>
<span class="title ml-3 mr-5">Google&nbsp;<span class="font-weight-light">Keep</span></span>
<v-text-field
solo-inverted
flat
hide-details
label="Search"
prepend-inner-icon="search"
></v-text-field>
<v-spacer></v-spacer>
</v-toolbar>
</span>
`,
data: function() {
return {
drawer: false,
items: [
{ icon: 'lightbulb_outline', text: 'Notes' },
{ icon: 'touch_app', text: 'Reminders' },
{ divider: true },
{ heading: 'Labels' },
{ icon: 'add', text: 'Create new label' },
{ divider: true },
{ icon: 'archive', text: 'Archive' },
{ icon: 'delete', text: 'Trash' },
{ divider: true },
{ icon: 'settings', text: 'Settings' },
{ icon: 'chat_bubble', text: 'Trash' },
{ icon: 'help', text: 'Help' },
{ icon: 'phonelink', text: 'App downloads' },
{ icon: 'keyboard', text: 'Keyboard shortcuts' }
]
};
},
methods: {}
};
export { smartNavbarComponent };

View File

@@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Test 05 Vuex (Fitri)</title>
<link rel="stylesheet" href="../../../libs/vendor/css/google-fonts.css">
<link rel="stylesheet" href="../../../libs/vendor/css/vuetify.min.css">
</head>
<body>
<div v-cloak id="app">
<v-app id="smartApp">
<smart-navbar></smart-navbar>
<v-content>
<v-container fluid fill-height style="height:inherit">
<v-flex size="xs12">
<list-patienttype fill-height></list-patienttype>
</v-flex>
</v-container>
</v-content>
<v-footer color="amber" app>
<span class="white--text">&copy; 2017</span>
</v-footer>
</v-app>
</div>
<!-- Vendor -->
<script src="../../../libs/vendor/axios.min.js"></script>
<script src="../../../libs/vendor/vue.js"></script>
<script src="../../../libs/vendor/vuex.js"></script>
<script src="../../../libs/vendor/vuetify.js"></script>
<!-- App Script -->
<?php
$ts = "?ts=" . Date("ymdhis");
?>
<script type="module">
import { store } from './store.js<?php echo $ts ?>';
import { smartNavbarComponent } from './components/smartNavbarComponent.js<?php echo $ts ?>';
import { listPatientTypeComponent } from './components/listPatientTypeComponent.js<?php echo $ts ?>';
//for testing
// window.store = store;
new Vue({
store,
el: '#app',
components: {
'smart-navbar': smartNavbarComponent,
'list-patienttype': listPatientTypeComponent,
},
data: {
drawer: false,
}
})
</script>
<style>
[v-cloak] {
display: none
}
</style>
</body>
</html>

View File

View File

@@ -0,0 +1,71 @@
// State
// data ...
// Mutations
//
//
// Actions
import * as api from "./api.js";
export const store = new Vuex.Store({
state: {
rows: [],
midPages: [],
isLoading: false,
isError: false,
errorMessage: "",
query: "",
page: 0,
totalPage: 0,
totalRecord: 0
},
mutations: {
updatePatientType(state, data) {
// console.log(data);
if (data.status == "ERR") {
state.isError = true;
if (data.db_error) {
state.errorMessage = data.db_error.message;
} else {
state.errorMessage = data.message;
}
state.query = data.query;
state.page = 0;
state.totalPage = 0;
state.totalRecord = 0;
state.rows = [];
state.midPages = [];
} else {
state.isError = false;
state.errorMessage = "";
state.query = data.query;
state.page = data.page;
state.totalPage = data.totalPage;
state.totalRecord = data.totalRecord;
state.rows = data.rows;
state.midPages = data.midPages;
}
},
updateLoading(state, flag) {
state.isLoading = flag;
},
resetError(state) {
state.isError = false;
state.errorMessage = "";
}
},
actions: {
async searchPatientType(context, data) {
context.commit("updateLoading", true);
let resp = await api.searchPatientType(
data.query,
data.page,
data.rowPerPage
);
context.commit("updateLoading", false);
context.commit("updatePatientType", resp);
setTimeout(function() {
context.commit("resetError");
}, 5000);
}
}
});

View File

View File

@@ -0,0 +1,31 @@
// API :
// search bank
// paramater : query , page , rowPerPage
const URL =
"http://lebaran.aplikasi.web.id/smartlab_api/vuex/t02/search_bank";
export async function searchBank(query, page, rowPerPage = 15) {
try {
var resp = await axios.post(URL, {
query: query,
page: page,
rowPerPage: rowPerPage
});
if (resp.status != 200) {
return {
status: "ERR",
query: query,
message: resp.statusText
};
}
let data = resp.data;
data.query = query;
return data;
} catch (e) {
return {
status: "ERR",
query: query,
message: e.message
};
}
}

View File

@@ -0,0 +1,32 @@
<template>
<v-layout column>
<v-card>
<v-flex xs12 sm6>
<v-text-field
label="Outline"
single-line
outline
></v-text-field>
</v-flex>
</v-card>
<v-card >
<v-card-text>
test kiri bawah
</v-card>
</v-card>
</v-layout>
</template>
<style scoped>
</style>
<script>
module.exports = {
components : {
}
}
</script>

View File

@@ -0,0 +1,43 @@
<template>
<div>
<v-card>
<v-btn class= "button parallelogram" color="success">Pasien Dokter</v-btn>
<v-btn class= "button parallelogram" color="warning">MOU </v-btn>
<v-btn class= "button parallelogram" color="error">Kirim Hasil </v-btn>
<v-btn class= "button parallelogram" color="info"> Barcode</v-btn>
</v-card>
</div>
</template>
<style scoped>
.v-card{
text-align: center;
}
.v-btn__content{
margin-top : -10px;
}
.button {
padding: 30px 16px;
width : 20%;
text-decoration:none;
}
.parallelogram{
transform: skew(-20deg);
}
.v-btn {
word-break: break-all;
}
</style>
<script>
module.exports = {
}
</script>

View File

@@ -0,0 +1,132 @@
<template>
<div>
<v-layout row>
<v-flex pl-2 pr-2 pt-2 pb-3 md12>
<v-card class="persyaratan">
<v-layout pl-2 pr-2 row>
<v-flex md12>
<v-list
subheader
three-line
>
<v-subheader red--text text--lighten-1> PERSYARATAN</v-subheader>
<v-divider></v-divider>
<v-list-tile @click="">
<v-list-tile-action>
<v-checkbox
v-model="notifications"
></v-checkbox>
</v-list-tile-action>
<v-list-tile-content @click.prevent="notifications = !notifications">
<v-list-tile-sub-title class="pt-3">
<v-flex justify-center md12 style="width:100%">
<v-text-field
label="Tidak bab satu minggu"
placeholder = "ketikkan alasan di sini ..."
outline
class="text-list-fhm"
></v-text-field>
</v-flex>
</v-list-tile-sub-title>
</v-list-tile-content>
</v-list-tile>
<v-list-tile @click="">
<v-list-tile-action>
<v-checkbox
v-model="notifications"
></v-checkbox>
</v-list-tile-action>
<v-list-tile-content @click.prevent="notifications = !notifications">
<v-list-tile-sub-title class="pt-3">
<v-flex justify-center md12 style="width:100%">
<v-text-field
label="Puasa 2 jam sebelum pemeriksaaan"
placeholder = "ketikkan alasan di sini ..."
outline
class="text-list-fhm"
></v-text-field>
</v-flex>
</v-list-tile-sub-title>
</v-list-tile-content>
</v-list-tile>
<v-list-tile @click="">
<v-list-tile-action>
<v-checkbox
v-model="notifications"
></v-checkbox>
</v-list-tile-action>
<v-list-tile-content @click.prevent="notifications = !notifications">
<v-list-tile-sub-title class="pt-3">
<v-flex justify-center md12 style="width:100%">
<v-text-field
label="Puasa 1 hari sebelum pemeriksaan"
placeholder = "ketikkan alasan di sini ..."
outline
class="text-list-fhm"
></v-text-field>
</v-flex>
</v-list-tile-sub-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-flex>
</v-layout>
</v-card>
</v-flex>
</v-layout>
<v-layout row wrap>
<v-flex xs12 pt-2>
<v-card>
<v-btn class= "button parallelogram" color="success">Pasien Dokter</v-btn>
<v-btn class= "button parallelogram" color="warning">MOU </v-btn>
<v-btn class= "button parallelogram" color="error">Kirim Hasil </v-btn>
<v-btn class= "button parallelogram" color="info"> Barcode</v-btn>
</v-card>
</v-flex>
</v-layout>
</div>
</template>
<style scoped>
.v-card{
text-align: center;
}
.v-btn__content{
margin-top : -10px;
}
.button {
padding: 30px 16px;
width : 20%;
text-decoration:none;
}
.parallelogram{
transform: skew(-20deg);
}
.v-btn {
word-break: break-all;
}
</style>
<script>
module.exports = {
}
</script>

View File

@@ -0,0 +1,122 @@
<template>
<v-layout row wrap>
<v-flex xs12>
<v-layout>
<v-flex xs3 pa-2>
<v-layout row wrap>
<v-flex xs12>
<v-img
src="https://www.sgm-inc.com/wp-content/uploads/2014/06/no-profile-male-img.gif"
aspect-ratio="1"
class="grey lighten-2 elevation-2"
>
</v-flex>
<v-flex xs12>
<patient-history-dialog></patient-history-dialog>
</v-flex>
</v-layout>
</v-flex>
<v-flex xs9>
<v-flex xs12 pa-1>
<v-text-field
label="Nama"
placeholder=""
:value="p_name"
readonly
></v-text-field>
</v-flex>
<v-flex xs12 pa-1>
<v-text-field
label="Jenis Kelamin"
placeholder=""
:value="p_kelamin"
readonly
></v-text-field>
</v-flex>
<v-flex xs12 pa-1>
<v-text-field
label="Telepon / HP"
placeholder=""
:value="p_phone"
readonly
></v-text-field>
</v-flex>
<v-flex xs12>
<v-layout>
<v-flex xs6 pa-1>
<v-text-field
label="Tanggal Lahir"
placeholder=""
:value="p_dob"
readonly
></v-text-field>
</v-flex>
<v-flex xs6 pa-1>
<v-text-field
label="Umur"
placeholder=""
:value="p_age"
readonly
></v-text-field>
</v-flex>
</v-layout>
</v-flex>
<v-flex xs12 class="pt-3 pl-2">
<v-text-field
label="Umur"
placeholder=""
:value="p_address"
readonly
></v-text-field>
</v-flex>
</v-flex>
</v-layout>
</v-flex>
</v-layout>
</template>
<style scoped>
.v-messages { display:none; }
.v-input__slot {
margin-bottom: 0px;
}
</style>
<script>
module.exports = {
components : {
'patient-search-dialog': httpVueLoader('./patientSearchDialog.vue'),
'patient-history-dialog': httpVueLoader('./patientHistoryDialog.vue')
},
data() {
return {
p_name : 'HERI SURYAWAN ST.',
p_address : `KPA Regency 221 Klipang\nSendangmulyo `,
p_phone : '0898-5945-837',
p_note : `Pasien ini agak bawel, tidak usah ditanggapi kalau sedang ngomel - ngomel`,
p_dob : '19-09-1999',
p_age : '20th 3bl 2hr',
p_kelamin : 'Laki-Laki'
}
}
}
</script>

View File

@@ -0,0 +1,24 @@
<template>
<v-layout row wrap>
<v-flex xs6 class="left">
Left
</v-flex>
<v-flex xs6 class="right">
Right
</v-flex>
</v-layout>
</template>
<style scoped>
.left {
background-color:red;
}
.right {
background-color:blue;
}
</style>
<script>
module.exports = {
}
</script>

View File

@@ -0,0 +1,28 @@
<template>
<v-layout row wrap>
<v-flex xs6 class="left">
<v-layout column fill-height>
<v-flex shrink class="searchbox">
searchbox
</v-flex>
<v-flex grow class="searchresult">
search result
</v-flex>
</v-layout>
</v-flex>
</v-layout>
</template>
<style scoped>
.searchbox {
background-color:blue;
}
.searchresult {
background-color:red;
}
</style>
<script>
module.exports = {
}
</script>

View File

@@ -0,0 +1,11 @@
<template>
<pasien-search> </pasien-search>
</template>
<script>
module.exports = {
components : {
'pasien-search' : httpVueLoader('./pasienSearch.vue')
}
}
</script>

View File

@@ -0,0 +1,26 @@
<template>
<v-layout row wrap>
<v-flex xs6 class="left">
<v-layout column wrap fill-height>
<search-box></search-box>
<v-flex grow class="searchresult">
search result
</v-flex>
</v-layout>
</v-flex>
</v-layout>
</template>
<style scoped>
.searchresult {
background-color:white;
}
</style>
<script>
module.exports = {
components : {
'search-box' : httpVueLoader('./searchBoxV3.vue')
}
}
</script>

View File

@@ -0,0 +1,23 @@
<template>
<patient-left-side></patient-left-side>
</template>
<style scoped>
.judul {
font-size: 2em;
font-weight: bold;
text-align: left;
}
</style>
<script>
module.exports = {
components : {
'patient-left-side' : httpVueLoader('./patientLeftSide.vue'),
}
}
</script>

View File

@@ -0,0 +1,43 @@
<template>
<div>
<v-card>
<v-btn class= "button parallelogram" color="success">Pasien Dokter</v-btn>
<v-btn class= "button parallelogram" color="warning">MOU </v-btn>
<v-btn class= "button parallelogram" color="error">Kirim Hasil </v-btn>
<v-btn class= "button parallelogram" color="info"> Barcode</v-btn>
</v-card>
</div>
</template>
<style scoped>
.v-card{
text-align: center;
}
.v-btn__content{
margin-top : -10px;
}
.button {
padding: 30px 16px;
width : 20%;
text-decoration:none;
}
.parallelogram{
transform: skew(-20deg);
}
.v-btn {
word-break: break-all;
}
</style>
<script>
module.exports = {
}
</script>

View File

@@ -0,0 +1,13 @@
<template>
<v-card class="fill-height">
<v-card-text>test kanan</v-card>
</v-card>
</template>
<style scoped>
</style>
<script>
module.exports = {
}
</script>

View File

@@ -0,0 +1,23 @@
<template>
<div>
<v-layout class="fill-height" column>
<v-card class="" >
<v-card-text>test kiri atas </v-card-text>
</v-card>
<v-card class="grow">
<v-card-text>
test kiri bawah
</v-card-text>
</v-card>
</v-layout>
</div>
</template>
<style scoped>
</style>
<script>
module.exports = {
}
</script>

View File

@@ -0,0 +1,28 @@
<template>
<v-layout row wrap>
<v-flex xs6 class="left">
<v-layout column wrap fill-height>
<search-box></search-box>
<v-flex grow class="searchresult">
search result
</v-flex>
</v-layout>
</v-flex>
</v-layout>
</template>
<style scoped>
.searchresult {
background-color:red;
}
</style>
<script>
module.exports = {
components : {
'search-box' : httpVueLoader('./searchBoxV3.vue')
}
}
</script>

View File

@@ -0,0 +1,21 @@
<template>
<v-card class="fill-height ma-1">
<v-layout row wrap>
<v-flex xs12>
<patient-search-box></patient-search-box>
</v-flex>
<v-flex xs12>
<patient-search-result></patient-search-result>
</v-flex>
</v-layout>
</v-card>
</template>
<script>
module.exports = {
components : {
'patient-search-box' : httpVueLoader('./patientSearchBox.vue'),
'patient-search-result' : httpVueLoader('./patientSearchResult.vue')
}
}
</script>

View File

@@ -0,0 +1,25 @@
<template>
<v-card class="fill-height">
<v-layout row wrap>
<v-flex xs12>
<header-box></header-box>
</v-flex>
<v-flex xs12>
<one-fo-verification-pasien-dokter></one-fo-verification-pasien-dokter>
</v-flex>
</v-layout>
</v-card>
</template>
<script>
module.exports = {
components : {
'header-box' : httpVueLoader('./headerBox.vue'),
'one-fo-verification-pasien-dokter' : httpVueLoader('./oneFOVerificationPasienDokter.vue'),
}
}
</script>

View File

@@ -0,0 +1,70 @@
<template>
<v-card class="fill-height ">
<v-layout>
<v-flex xs3 pa-1>
<v-text-field
label="Search"
placeholder="No Lab"
single-line
outline
></v-text-field>
</v-flex>
<v-flex xs6 pa-1>
<v-text-field
label=""
placeholder="Nama"
single-line
outline
></v-text-field>
</v-flex>
<v-flex xs6 pa-1>
<v-select
:items="items"
label="Status"
outline
></v-select>
</v-flex>
<v-flex xs3>
<v-btn color="success" class="mr-1 ml-1">Search</v-btn>
</v-flex>
</v-layout>
</v-card>
</template>
<style scoped>
.v-btn {
min-width: auto;
}
.v-input__slot {
margin-bottom: 0px !important;
}
.v-messages {
display: none;
}
.v-text-field--box>.v-input__control>.v-input__slot,.v-text-field--full-width>.v-input__control>.v-input__slot,.v-text-field--outline>.v-input__control>.v-input__slot {
min-height: 44px;
}
.v-text-field--box.v-text-field--single-line input,.v-text-field--full-width.v-text-field--single-line input,.v-text-field--outline.v-text-field--single-line input {
margin-top: 6px;
}
.v-input__control{
height: 10px;
}
.v-btn {
margin : 10px
}
</style>
<script>
module.exports = {
}
</script>

View File

@@ -0,0 +1,86 @@
<template>
<v-card class="fill-height " >
<v-data-table :headers="headers" :items="patients"
:loading="isLoading"
hide-actions class="elevation-1">
<template slot="items" slot-scope="props">
<td class="text-xs-left pa-2" v-bind:class="{'amber lighten-4':props.item.selected}" @click="selectMe(props.item)">{{ props.item.mr }}</td>
<td class="pa-2" v-bind:class="{'amber lighten-4':props.item.selected}" @click="selectMe(props.item)">{{ props.item.lab}}</td>
<td class="text-xs-left pa-2" v-bind:class="{'amber lighten-4':props.item.selected}" @click="selectMe(props.item)">{{ props.item.name }}</td>
<td class="text-xs-left pa-2" v-bind:class="{'amber lighten-4':props.item.selected}" @click="selectMe(props.item)">{{ props.item.status }}</td>
</template>
</v-data-table>
</v-card>
</template>
<style scoped>
table.v-table tbody td,table.v-table tbody th {
height: 40px;
}
table.v-table thead tr {
height: 40px;
}
</style>
<script>
module.exports = {
data() {
return {
query: "",
headers: [
{
text: "NO REG",
align: "left",
sortable: false,
value: "mr",
width: "15%",
class: "pa-2 blue lighten-3 white--text"
},
{
text: "NO LAB",
align: "left",
sortable: false,
value: "lab",
width: "15%",
class: "pa-2 blue lighten-3 white--text"
},
{
text: "NAMA",
align: "left",
sortable: false,
value: "name",
width: "25%",
class: "pa-2 blue lighten-3 white--text"
},
{
text: "STATUS",
align: "left",
sortable: false,
value: "status",
width: "15%",
class: "pa-2 blue lighten-3 white--text"
}
],
isLoading: true,
patients: [
{"status":"Data Verified","lab":"08000198909", "mr": "MR-18107237", "name": "Pasien Umum", "sex": "Perempuan", "address": "Klero\r\nKabupaten Semarang", "action":"", "dob":"19-09-1992", "selected":false},
{"status":"Payment Verified","lab":"08000198111", "mr": "MR-18107238", "name": "Heri Suryawan", "sex": "Laki - laki", "address": "Ampel", "action":"", "dob":"19-09-1992", "selected":false},
{"status":"Payment Verified","lab":"08000198222", "mr": "MR-18107239", "name": "LUKA MODRIC", "sex": "Laki - laki", "address": "Jl. Raya No 1", "action":"", "dob":"19-09-1992", "selected":true},
{"status":"Data Verified","lab":"08000198121", "mr": "MR-18107247", "name": "Tyas Medika Pranandita", "sex": "Laki - laki", "address": "KP. Karangpanas", "action":"", "dob":"19-09-1992", "selected":false},
{"status":"Data & Payment Verified","lab":"08000198131", "mr": "MR-18107248", "name": "Astrid", "sex": "Perempuan", "address": "Jl. Ketintang Raya No.81", "action":"", "dob":"19-09-1992", "selected":false},
{"status":"Data & Payment Verified","lab":"08000198123", "mr": "MR-18107249", "name": "Happy", "sex": "Perempuan", "address": "Karangpanas", "action":"", "dob":"19-09-1992", "selected":false},
{"status":"Data Verified","lab":"08000198111", "mr": "MR-18107251", "name": "Juan Alexis Sukir", "sex": "Laki - laki", "address": "Jl. Sawi", "action":"", "dob":"19-09-1992", "selected":false},
{"status":"Data & Payment Verified","lab":"08000198555", "mr": "MR-18107252", "name": "Alexander Wang", "sex": "Laki - laki", "address": "Jl. Mangga Muda No. 7", "action":"", "dob":"19-09-1992", "selected":false},
{"status":"Payment Verified","lab":"08000198444", "mr": "MR-18107253", "name": "CILA CILANI", "sex": "Perempuan", "address": "Jl. Duren PInang No. 67", "action":"", "dob":"19-09-1992", "selected":false},
{"status":"Data & Payment Verified","lab":"08000198123", "mr": "MR-18107254", "name": "Untung Suropati", "sex": "Laki - laki", "address": "Pasar Kapling Semarang", "action":"", "dob":"19-09-1992", "selected":false}
]
};
}
}
</script>

View File

@@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>One</title>
<link rel="stylesheet" href="../../../libs/vendor/css/google-fonts.css">
<link rel="stylesheet" href="../../../libs/vendor/css/vuetify.min.css">
</head>
<body>
<div v-cloak id="app">
<v-app id="smartApp" >
<one-navbar>
</one-navbar>
<v-content class="blue lighten-5" >
<v-container fluid fill-height class="pl-1 pr-1 pt-2 pb-2">
<v-layout wrap >
<v-flex xs6 class="left" fill-height pa-1>
<!-- komponen kiri -->
<one-kiri></one-kiri>
</v-flex>
<v-flex xs6 class="right" fill-height pa-1>
<!-- komponen kanan -->
<one-kanan></one-kanan>
</v-flex>
</v-layout>
</v-container>
</v-content>
<one-footer>
</one-footer>
</v-app>
</div>
<!-- Vendor -->
<script src="../../../libs/vendor/axios.min.js"></script>
<script src="../../../libs/vendor/vue.js"></script>
<script src="../../../libs/vendor/vuex.js"></script>
<script src="../../../libs/vendor/vuetify.js"></script>
<script src="../../../libs/vendor/httpVueLoader.js"></script>
<!-- App Script -->
<?php
$ts = "?ts=" . Date("ymdhis");
?>
<script type="module">
import { store } from './store.js<?php echo $ts ?>';
//for testing
// window.store = store;
new Vue({
store,
el: '#app',
components: {
'one-navbar': httpVueLoader('../../../apps/components/oneNavbarComponent.vue'),
'one-footer': httpVueLoader('../../../apps/components/oneFooter.vue'),
'one-kiri' : httpVueLoader('./components/oneKiri.vue'),
'one-kanan' : httpVueLoader('./components/oneKanan.vue')
}
})
</script>
<style>
[v-cloak] {
display: none
}
.left {
}
.right {
}
</style>
</body>
</html>

View File

@@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>One</title>
<link rel="stylesheet" href="../../../libs/vendor/css/google-fonts.css">
<link rel="stylesheet" href="../../../libs/vendor/css/vuetify.min.css">
</head>
<body>
<div v-cloak id="app">
<v-app id="smartApp" >
<one-navbar></one-navbar>
<v-content class="blue lighten-5" >
<v-container fluid fill-height>
<one-fo-verification-list> <one-fo-verification-list>
</v-container>
</v-content>
<one-footer> </one-footer>
</v-app>
</div>
<!-- Vendor -->
<script src="../../../libs/vendor/axios.min.js"></script>
<script src="../../../libs/vendor/vue.js"></script>
<script src="../../../libs/vendor/vuex.js"></script>
<script src="../../../libs/vendor/vuetify.js"></script>
<script src="../../../libs/vendor/httpVueLoader.js"></script>
<!-- App Script -->
<?php
$ts = "?ts=" . Date("ymdhis");
?>
<script type="module">
import { store } from './store.js<?php echo $ts ?>';
//for testing
// window.store = store;
new Vue({
store,
el: '#app',
components: {
'one-navbar': httpVueLoader('../../../apps/components/oneNavbarComponent.vue'),
'one-footer': httpVueLoader('../../../apps/components/oneFooter.vue'),
'one-fo-verification-list': httpVueLoader('./components/foVerificationList.vue'),
}
})
</script>
<style>
[v-cloak] {
display: none
}
</style>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More