This commit is contained in:
glovetleong
2021-06-17 09:53:04 +08:00
commit 8fa80e4a1a
2382 changed files with 196486 additions and 0 deletions
@@ -0,0 +1,45 @@
<template>
<div >
<label v-if="label" for="name">{{ label }}</label>
<div class="form-group" :class="{'has-error': form.errors.has(input_name)}">
<datepicker
:name="input_name"
input-class="form-control"
:placeholder="placeholder"
v-model="form[input_name]"
@input="form.errors.clear(input_name)"
format="dd-MM-yy"
:disabled-dates="state.disabledDates"
></datepicker>
<div class="text-danger text-left" v-if="form.errors.has(input_name)" v-text="form.errors.get(input_name)"></div>
</div>
</div>
</template>
<script type="text/javascript">
import Datepicker from 'vuejs-datepicker';
import moment from 'moment';
export default {
props: ['input_name', 'form', 'placeholder', 'label', 'disable_pass_date'],
components: {
Datepicker
},
data() {
let vm = this;
return {
state : {
disabledDates: {
customPredictor: function(date) {
if (!vm.disable_pass_date) {
if(date < moment().startOf('day') ){
return true
}
}
}
}
}
}
}
}
</script>
@@ -0,0 +1,63 @@
<template>
<div >
<label v-if="label" for="name">{{ label }}</label>
<div class="row">
<div class="col-6">
<div class="form-group" :class="{'has-error': form.errors.has(input_name_1)}">
<datepicker
:name="input_name_1"
input-class="form-control"
:placeholder="placeholder"
v-model="form[input_name_1]"
@input="form.errors.clear(input_name_1)"
format="dd-MM-yy"
:disabled-dates="state.disabledDates"
></datepicker>
<div class="text-danger text-left" v-if="form.errors.has(input_name_1)" v-text="form.errors.get(input_name_1)"></div>
</div>
</div>
<div class="col-6">
<div class="form-group" :class="{'has-error': form.errors.has(input_name_2)}">
<datepicker
:name="input_name_2"
input-class="form-control"
:placeholder="placeholder"
v-model="form[input_name_2]"
@input="form.errors.clear(input_name_2)"
format="dd-MM-yy"
:disabled-dates="state.disabledDates"
></datepicker>
<div class="text-danger text-left" v-if="form.errors.has(input_name_2)" v-text="form.errors.get(input_name_2)"></div>
</div>
</div>
</div>
</div>
</template>
<script type="text/javascript">
import Datepicker from 'vuejs-datepicker';
import moment from 'moment';
export default {
props: ['input_name_1', 'input_name_2', 'form', 'placeholder', 'label', 'disable_pass_date'],
components: {
Datepicker
},
data() {
let vm = this;
return {
state : {
disabledDates: {
customPredictor: function(date) {
if (!vm.disable_pass_date) {
if(date < moment().startOf('day') ){
return true
}
}
}
}
}
}
}
}
</script>
@@ -0,0 +1,32 @@
<template>
<div class="form-group">
<label v-if="label" for="name">{{ label }}</label>
<div class="row">
<div class="col-6">
<div class="form-group">
<input type="text"
class="form-control"
v-model="form[input_name_1]"
:readonly="true"
>
</div>
</div>
<div class="col-6">
<div class="form-group">
<input type="text"
class="form-control"
v-model="form[input_name_2]"
:readonly="true"
>
</div>
</div>
</div>
</div>
</template>
<script type="text/javascript">
export default {
props: ['input_name_1', 'input_name_2', 'form', 'label', 'disable_pass_date'],
}
</script>
@@ -0,0 +1,52 @@
<template>
<div >
<label v-if="label" for="name">{{ label }}</label>
<div class="row">
<div class="col-6">
<div class="form-group" :class="{'has-error': form.errors.has(input_name_1)}">
<datetime
type="datetime"
class="form-control"
v-model="form[input_name_1]"
value-zone="Asia/Singapore"
zone="Asia/Singapore"
@input="form.errors.clear(input_name_1)"
></datetime>
<div class="text-danger text-left" v-if="form.errors.has(input_name_1)" v-text="form.errors.get(input_name_1)"></div>
</div>
</div>
<div class="col-6">
<div class="form-group" :class="{'has-error': form.errors.has(input_name_2)}">
<datetime
type="datetime"
class="form-control"
v-model="form[input_name_2]"
value-zone="Asia/Singapore"
zone="Asia/Singapore"
@input="form.errors.clear(input_name_2)"
></datetime>
<div class="text-danger text-left" v-if="form.errors.has(input_name_2)" v-text="form.errors.get(input_name_2)"></div>
</div>
</div>
</div>
</div>
</template>
<script type="text/javascript">
import { Datetime } from 'vue-datetime';
import 'vue-datetime/dist/vue-datetime.css';
import moment from 'moment';
export default {
props: ['input_name_1', 'input_name_2', 'form', 'placeholder', 'label', 'disable_pass_date'],
components: {
Datetime
},
data() {
let vm = this;
return {
}
}
}
</script>
@@ -0,0 +1,43 @@
<template>
<div class="form-group" :class="{'has-error': form.errors.has(input_name)}">
<label v-if="label" for="name">{{ label }}</label>
<div class="upload-box">
<div class="file-container mb-1">
<i class="fa fa-download"></i>
<input type='file'
:name="input_name"
@change="onChange"
/>
<div>{{ file_name }}</div>
</div>
</div>
<div class="text-danger text-left" v-if="form.errors.has(input_name)" v-text="form.errors.get(input_name)"></div>
</div>
</template>
<script>
export default {
props: ['input_name', 'form', 'placeholder', 'label'],
components: {
},
data() {
return {
file_name: '',
file: []
}
},
methods: {
onChange(e) {
let vm = this;
let files = e.target.files;
General.imageBase64(e.target.files).then(data => {
vm.file = data[0];
vm.file_name = e.target.files[0].name;
vm.form[vm.input_name] = [vm.file];
});
},
}
}
</script>
@@ -0,0 +1,89 @@
<template>
<div class="form-group" :class="{'has-error': form.errors.has(input_name)}">
<label v-if="label" for="name">{{ label }}</label>
<div class="upload-box">
<div class="file-container mb-1">
<i class="fa fa-download"></i>
<input type='file'
:name="input_name"
@change="onChange"
/>
</div>
<div v-if="preview" v-for="(img, $index) in preview" :key="$index">
<a v-if="mime_type == 'application/pdf'" class="btn btn-xs btn-light" :href="img" target="_blank">
<i class="fa fa-file-pdf"></i>
</a>
<div v-if="mime_type != 'application/pdf'">
<img class="img-fluid" alt='' :src="img"/>
</div>
</div>
</div>
<div class="text-danger text-left" v-if="form.errors.has(input_name)" v-text="form.errors.get(input_name)"></div>
<cropper-modal
:img="img"
@clicked="getCropImage"
>
</cropper-modal>
</div>
</template>
<script>
import CropperModal from "../modals/CropperModal";
export default {
props: {
input_name: String,
form: Object,
placeholder: String,
label: String,
exist_img: Array,
},
components: {
CropperModal
},
data() {
return {
preview: [],
img: [],
mime_type: '',
}
},
methods: {
onChange(e) {
let vm = this;
let files = e.target.files;
vm.mime_type = files[0].type;
General.imageBase64(e.target.files).then(data => {
vm.img = data[0];
vm.cropperModalToggle();
});
},
cropperModalToggle() {
let vm = this;
vm.$bvModal.show('cropper-modal');
},
getCropImage(img) {
let vm = this;
vm.form[vm.input_name] = [img];
vm.preview = [img];
},
loadExistingImg() {
let vm = this;
if (vm.exist_img[0]) {
vm.mime_type = vm.exist_img[0].mime_type;
Array.from(vm.exist_img).forEach(file => {
vm.preview.push(file.file_info.original.file);
});
}
}
},
watch: {
'exist_img': 'loadExistingImg',
},
created() {
let vm = this;
vm.loadExistingImg();
}
}
</script>
@@ -0,0 +1,46 @@
<template>
<div class="form-group">
<label v-if="label" for="name">{{ label }}</label>
<div class="upload-box">
<div v-if="preview" v-for="(img, $index) in preview" :key="$index">
<div>
<img class="img-fluid" alt='' :src="img"/>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
label: String,
exist_img: Array,
},
data() {
return {
preview: [],
img: [],
mime_type: '',
}
},
methods: {
loadExistingImg() {
let vm = this;
if (vm.exist_img[0]) {
vm.mime_type = vm.exist_img[0].mime_type;
Array.from(vm.exist_img).forEach(file => {
vm.preview.push(file.file_info.original.file);
});
}
}
},
watch: {
'exist_img': 'loadExistingImg',
},
created() {
let vm = this;
vm.loadExistingImg();
}
}
</script>
@@ -0,0 +1,34 @@
<template>
<div class="form-group" :class="{'has-error': form.errors.has(input_name)}">
<label v-if="label" for="name">{{ label }}</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">{{ icon }}</span>
</div>
<input type="text"
class="form-control"
:placeholder="placeholder"
v-model="form[input_name]"
@keydown="form.errors.clear(input_name)"
@keypress="isNumber($event)"
@input="$emit('clicked')"
:readonly="readonly"
>
</div>
<div class="text-danger text-left" v-if="form.errors.has(input_name)" v-text="form.errors.get(input_name)"></div>
</div>
</template>
<script type="text/javascript">
export default {
props: ['input_name', 'form', 'icon', 'placeholder', 'label', 'readonly'],
methods: {
isNumber($event) {
let keyCode = ($event.keyCode ? $event.keyCode : $event.which);
if ((keyCode < 48 || keyCode > 57) && keyCode !== 46) { // 46 is dot
$event.preventDefault();
}
}
}
}
</script>
@@ -0,0 +1,36 @@
<template>
<div class="form-group" :class="{'has-error': form.errors.has(input_name)}">
<label v-if="label" for="name">{{ label }}</label>
<input type="text"
:name="input_name"
class="form-control"
:placeholder="placeholder"
v-model="form[input_name]"
@keydown="form.errors.clear(input_name)"
@keypress="isNumber($event)"
@keyup="$emit('clicked')"
:readonly="readonly"
>
<div class="text-danger text-left" v-if="form.errors.has(input_name)" v-text="form.errors.get(input_name)"></div>
</div>
</template>
<script type="text/javascript">
export default {
props: {
input_name: String,
form: Object,
placeholder: String,
label: String,
readonly: Boolean,
},
methods: {
isNumber($event) {
let keyCode = ($event.keyCode ? $event.keyCode : $event.which);
if ((keyCode < 48 || keyCode > 57) && keyCode !== 46) { // 46 is dot
$event.preventDefault();
}
}
}
}
</script>
@@ -0,0 +1,44 @@
<template>
<div class="form-group" :class="{'has-error': form.errors.has(input_name)}">
<label v-if="label" for="name">{{ label }}</label>
<div class="input-group">
<input :type="password_type ? 'password' : 'text'"
class="form-control"
:placeholder="placeholder"
v-model="form[input_name]"
@keydown="form.errors.clear(input_name)"
>
<div class="input-group-prepend pointer-cursor" @click="passwordToggle">
<span class="input-group-text">
<i :class="password_type ? 'fa fa-eye-slash' : 'fa fa-eye'" aria-hidden="true"></i>
</span>
</div>
</div>
<div class="text-danger text-left" v-if="form.errors.has(input_name)" v-text="form.errors.get(input_name)"></div>
</div>
</template>
<script type="text/javascript">
export default {
props: {
input_name: String,
form: Object,
placeholder: String,
label: String
},
data() {
let vm = this;
return {
password_type: true
}
},
methods: {
passwordToggle() {
let vm = this;
vm.password_type = !vm.password_type;
}
}
}
</script>
@@ -0,0 +1,27 @@
<template>
<div class="form-group" :class="{'has-error': form.errors.has(input_name)}">
<div>
<label v-if="label" for="name">{{ label }}</label>
</div>
<v-radio-group v-model="form[input_name]" :mandatory="false">
<v-radio
v-if="list" v-for="(item, $index) in list" :key="$index"
color="primary"
:label="item.name"
:value="item.id"
></v-radio>
</v-radio-group>
<div class="text-danger text-left" v-if="form.errors.has(input_name)" v-text="form.errors.get(input_name)"></div>
</div>
</template>
<script type="text/javascript">
export default {
props: {
input_name: String,
form: Object,
list: Array,
label: String,
}
}
</script>
@@ -0,0 +1,140 @@
<template>
<div class="form-group" :class="{'has-error': form.errors.has(input_name)}">
<label v-if="label" for="name">{{ label }}</label>
<vue-tags-input
ref="tags_input"
v-model="tag"
:tags="tags"
:autocomplete-min-length="0"
:add-on-blur="false"
:autocomplete-items="autocompleteItems"
:before-deleting-tag="deleteTag"
:max-tags="limit_tag"
:add-only-from-autocomplete="!can_add_new_tag ? true : false"
:placeholder="''"
@tags-changed="update"
@before-adding-tag="checkTag"
@focus="focus()"
>
</vue-tags-input>
<div class="text-danger text-left" v-if="form.errors.has(input_name)" v-text="form.errors.get(input_name)"></div>
</div>
</template>
<script type="text/javascript">
export default {
props: {
input_name: String,
form: Object,
exist_data: Array,
data_set: Array,
placeholder: String,
label: String,
endpoint: String,
params: Object,
search_field: String,
is_array: Boolean,
limit_tag: Number,
return_key: String,
can_add_new_tag: Boolean
},
data() {
let vm = this;
return {
tag: '',
original_tag: [],
tags: vm.exist_data ? vm.exist_data : [],
autocompleteItems: [],
pervious_item: []
}
},
methods: {
focus() {
let vm = this;
if (vm.pervious_item.length > 0) {
vm.pervious_item = [];
vm.initItems();
}
},
checkTag(obj) {
let vm = this;
if (vm.limit_tag >= vm.tags.length) {
vm.tags = [];
}
obj.addTag();
},
update(newTags = '') {
let vm = this;
vm.tags = newTags;
vm.pervious_item = vm.autocompleteItems;
vm.autocompleteItems = [];
vm.keyConvert();
vm.$emit('clicked', vm.extractRow(vm.tags));
vm.form.errors.clear(vm.input_name);
},
deleteTag() {
vm.$emit('clicked', vm.extractRow(vm.tags));
},
keyConvert() {
let vm = this;
if (!vm.original) {
vm.form[vm.input_name] = General.getKey(vm.tags, (!vm.return_key ? 'id' : vm.return_key));
}
else {
vm.form[vm.input_name] = vm.original_tag;
}
},
initItems() {
let vm = this;
if (vm.pervious_item.length > 0) {
return;
}
if (!vm.data_set) {
let search_field = {};
search_field[vm.search_field] = vm.array ? [vm.tag] : vm.tag;
let form = new Form({...vm.params, ...search_field});
General.getCall(vm.endpoint, form).then(data => {
vm.autocompleteItems = data.data.map(item => {
vm.original_tag.push(vm.tag);
return {
id: item.id,
hash_id: (item.hash_id ? item.hash_id : ''),
row: item,
text: (item.name ? item.name : item.hash_id )
};
});
});
}
else {
vm.autocompleteItems = vm.data_set;
}
},
extractRow() {
let vm = this;
let return_row = [];
vm.tags.forEach(function(element, index) {
return_row.push(element.row);
});
return return_row;
}
},
created() {
let vm = this;
setTimeout(function(){
vm.tags = vm.exist_data ? vm.exist_data : [];
vm.$emit('clicked', vm.extractRow(vm.tags));
}, 1000);
vm.initItems();
},
watch: {
'tag': 'initItems',
}
}
</script>
@@ -0,0 +1,23 @@
<template>
<div class="form-group" :class="{'has-error': form.errors.has(input_name)}">
<label v-if="label">{{ label }}</label>
<select
class="form-control"
v-model="form[input_name]"
@change="$emit('clicked')"
:disabled="readonly"
>
<option disabled value="">Select Option</option>
<option :value="option.id" v-if="list" v-for="(option, $index) in list" :key="$index">
{{ option.name }}
</option>
</select>
<div class="text-danger text-left" v-if="form.errors.has(input_name)" v-text="form.errors.get(input_name)"></div>
</div>
</template>
<script type="text/javascript">
export default {
props: ['input_name', 'form', 'label', 'list', 'readonly']
}
</script>
@@ -0,0 +1,25 @@
<template>
<div class="mb-2">
<label v-if="label">{{ label }}</label>
<v-switch
v-model="form[input_name]"
color="primary"
:value="1"
hide-details
></v-switch>
<div class="text-danger text-left" v-if="form.errors.has(input_name)" v-text="form.errors.get(input_name)"></div>
</div>
</template>
<script type="text/javascript">
import {ToggleButton} from 'vue-js-toggle-button'
export default {
props: {
input_name: String,
form: Object,
label: String
}
}
</script>
@@ -0,0 +1,31 @@
<template>
<div class="form-group" :class="{'has-error': form.errors.has(input_name)}">
<div>
<label v-if="label" for="name">{{ label }}</label>
</div>
<div class="col">
<div class="row">
<div :class="full == true ? 'col-12' : 'col-3'" class="p-0" v-if="list.data" v-for="(item, $index) in list.data" :key="$index">
<div class="float-left mr-3">{{ item.value }}</div>
<div class="float-right">
<v-switch
:name="input_name"
v-model="form[input_name]"
color="primary"
:value="item.key"
hide-details
@keydown="form.errors.clear(input_name)"
></v-switch>
</div>
</div>
</div>
</div>
<div class="text-danger text-left" v-if="form.errors.has(input_name)" v-text="form.errors.get(input_name)"></div>
</div>
</template>
<script type="text/javascript">
export default {
props: ['input_name', 'form', 'list', 'label', 'full']
}
</script>
@@ -0,0 +1,21 @@
<template>
<div class="mb-2">
<label v-if="label">{{ label }}</label>
<v-switch
v-model="form[input_name]"
color="primary"
:value="value"
hide-details
></v-switch>
<div class="text-danger text-left" v-if="form.errors.has(input_name)" v-text="form.errors.get(input_name)"></div>
</div>
</template>
<script type="text/javascript">
import {ToggleButton} from 'vue-js-toggle-button'
export default {
props: ['input_name', 'value', 'form', 'label', 'value']
}
</script>
@@ -0,0 +1,27 @@
<template>
<div class="form-group" :class="{'has-error': form.errors.has(input_name)}">
<label v-if="label" for="name">{{ label }}</label>
<textarea
:name="input_name"
class="form-control"
:placeholder="placeholder"
v-model="form[input_name]"
@keydown="form.errors.clear(input_name)"
:readonly="readonly"
>
</textarea>
<div class="text-danger text-left" v-if="form.errors.has(input_name)" v-text="form.errors.get(input_name)"></div>
</div>
</template>
<script type="text/javascript">
export default {
props: {
input_name: String,
form: Object,
placeholder: String,
label: String,
readonly: Boolean
}
}
</script>
@@ -0,0 +1,18 @@
<template>
<div class="form-group">
<label v-if="label" for="name">{{ label }}</label>
<textarea type="text"
rows="8" cols="50"
class="form-control"
:value="value"
:readonly="true"
>
</textarea>
</div>
</template>
<script type="text/javascript">
export default {
props: ['value', 'label']
}
</script>
@@ -0,0 +1,26 @@
<template>
<div class="form-group" :class="{'has-error': form.errors.has(input_name)}">
<label v-if="label">{{ label }}</label>
<input type="text"
:name="input_name"
class="form-control"
:placeholder="placeholder"
v-model="form[input_name]"
@keydown="form.errors.clear(input_name)"
:readonly="readonly"
>
<div class="text-danger text-left" v-if="form.errors.has(input_name)" v-text="form.errors.get(input_name)"></div>
</div>
</template>
<script type="text/javascript">
export default {
props: {
input_name: String,
form: Object,
placeholder: String,
label: String,
readonly: Boolean
}
}
</script>
@@ -0,0 +1,53 @@
<template>
<div class="form-group" :class="{'has-error': form.errors.has(input_name)}">
<div class="mb-2">
<label v-if="label" for="name">{{ label }}</label>
</div>
<b-row class="mb-2"
v-for="(input, $index) in form[input_name]" :key="$index"
>
<b-col md="10">
<input type="text"
class="form-control mb-1"
v-model="form[input_name][$index]"
@keydown="form.errors.clear(input_name)"
>
</b-col>
<b-col md="2" class="text-right">
<button type="button" class="btn btn-xs btn-danger" @click="removeField($index)">
<i class="fa fa-trash"></i>
</button>
</b-col>
</b-row>
<div>
<button
class="btn btn-xs btn-light"
@click="addField"
>
<i class="fa fa-plus"></i> Add Option
</button>
</div>
<div class="text-danger text-left" v-if="form.errors.has(input_name)" v-text="form.errors.get(input_name)"></div>
</div>
</template>
<script type="text/javascript">
export default {
props: ['input_name', 'form', 'placeholder', 'label', 'readonly'],
methods: {
addField() {
let vm = this;
vm.form[vm.input_name].push([]);
},
removeField(index) {
let vm = this;
vm.form[vm.input_name].splice(index, 1);
}
},
created() {
let vm = this;
}
}
</script>
@@ -0,0 +1,23 @@
<template>
<div class="form-group">
<label v-if="label" for="name">{{ label }}</label>
<b-row class="mb-2"
v-for="(input, $index) in form[input_name]" :key="$index"
>
<b-col md="12">
<input type="text"
class="form-control mb-1"
v-model="form[input_name][$index]"
:readonly="true"
>
</b-col>
</b-row>
</div>
</template>
<script type="text/javascript">
export default {
props: ['input_name', 'form', 'label'],
}
</script>
@@ -0,0 +1,19 @@
<template>
<div class="form-group">
<label v-if="label" for="name">{{ label }}</label>
<input type="text"
class="form-control"
:value="value"
:readonly="true"
>
</div>
</template>
<script type="text/javascript">
export default {
props: {
label: String,
value: String
}
}
</script>
@@ -0,0 +1,56 @@
<template>
<div>
<b-modal :id="'cropper-modal'" size="lg" scrollable>
<template v-slot:modal-title>
<h4 class="modal-title">Crop Image</h4>
</template>
<vue-cropper
ref='cropper'
:guides="true"
:view-mode="2"
drag-mode="crop"
:auto-crop-area="0.5"
:min-container-width="250"
:min-container-height="180"
:background="true"
:rotatable="true"
:src="img"
alt="Source Image"
:img-style="{ 'width': '400px', 'height': '300px' }"
>
</vue-cropper>
<template v-slot:modal-footer>
<form>
<v-btn
:block="true"
type="button"
color="primary"
class="white--text"
@click="cropImage"
>
Crop
</v-btn>
</form>
</template>
</b-modal>
</div>
</template>
<script>
import VueCropper from 'vue-cropperjs';
export default {
props: ['img'],
components: {
VueCropper
},
methods: {
cropImage() {
let vm = this;
let cropImg = '';
cropImg = this.$refs.cropper.getCroppedCanvas().toDataURL();
vm.$bvModal.hide('cropper-modal');
vm.$emit('clicked', cropImg);
}
}
}
</script>
@@ -0,0 +1,48 @@
<template>
<div>
<b-modal :id="'img-pop-modal'" size="lg" scrollable>
<template v-slot:modal-title>
<h4 class="modal-title">{{ label }}</h4>
</template>
<div v-if="img[0]" class="text-center">
<img class="img-fluid"
:src="img[0].file_info.original.file"
width="300px" height="300px"
>
</div>
<template v-slot:modal-footer>
<form>
<v-btn
depressed
small
type="button"
color="warning"
class="m-0"
@click="$bvModal.hide('img-pop-modal')"
>
Close
</v-btn>
</form>
</template>
</b-modal>
</div>
</template>
<script>
import VueCropper from 'vue-cropperjs';
export default {
props: ['label', 'img'],
components: {
VueCropper
},
methods: {
cropImage() {
let vm = this;
let cropImg = '';
cropImg = this.$refs.cropper.getCroppedCanvas().toDataURL();
vm.$bvModal.hide('cropper-modal');
vm.$emit('clicked', cropImg);
}
}
}
</script>
@@ -0,0 +1,31 @@
<template>
<tr>
<td class="pl-0 pr-0" :colspan="colspan">
<ul class="pagination pull-right">
<li v-if="pervious_page" class="page-item">
<span
@click="$emit('clicked', pervious_page)"
class="page-link"
title="left" value="">
«
</span>
</li>
<li v-if="next_page" class="page-item">
<span
@click="$emit('clicked', next_page)"
class="page-link"
title="right" value="">
»
</span>
</li>
</ul>
</td>
</tr>
</template>
<script type="text/javascript">
export default {
props: ['pervious_page', 'next_page', 'colspan']
}
</script>
@@ -0,0 +1,21 @@
<template>
<div class="app-page-title">
<div class="page-title-wrapper">
<div class="page-title-heading">
<div class="page-title-icon">
<i :class="icon"></i>
</div>
<div>
{{heading}}
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['icon', 'heading'],
}
</script>