Merge branch 'akaunting:master' into master
This commit is contained in:
@ -264,8 +264,8 @@ export default {
|
||||
},
|
||||
|
||||
sendEmailShow: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
type: [String, Number, Array, Object, Boolean],
|
||||
default: '1',
|
||||
description: "Created recurring model send automatically option"
|
||||
},
|
||||
sendEmailText: {
|
||||
|
@ -15,33 +15,34 @@
|
||||
<span v-if="filter.operator" class="flex items-center bg-purple-lighter text-black border-2 border-body border-l border-r border-t-0 border-b-0 mt-3 px-3 py-4 text-sm cursor-pointer el-tag el-tag--small el-tag-operator" style="margin-left:0; margin-right:0;">
|
||||
<span v-if="filter.operator == '='" class="material-icons text-2xl">drag_handle</span>
|
||||
<span v-else-if="filter.operator == '><'" class="material-icons text-2xl transform rotate-90">height</span>
|
||||
<span v-else class="w-5">
|
||||
<img :src="not_equal_image" class="w-5 h-5 object-cover block" />
|
||||
</span>
|
||||
|
||||
<img v-else :src="not_equal_image" class="w-5 h-5 object-cover block" />
|
||||
|
||||
<i v-if="!filter.value" class="mt-1 ltr:-right-2 rtl:left-0 rtl:right-0 el-tag__close el-icon-close " style="font-size: 16px;" @click="onFilterDelete(index)"></i>
|
||||
<i v-if="!filter.value" class="mt-1 ltr:-right-2 rtl:left-0 rtl:right-0 el-tag__close el-icon-close" style="font-size: 16px;" @click="onFilterDelete(index)"></i>
|
||||
</span>
|
||||
|
||||
<span v-if="filter.value" class="flex items-center bg-purple-lighter text-black border-0 mt-3 px-3 py-4 text-sm cursor-pointer el-tag el-tag--small el-tag-value">
|
||||
<span v-if="filter.value" class="flex items-center bg-purple-lighter text-black border-0 mt-3 px-3 py-4 text-sm cursor-pointer el-tag el-tag--small el-tag-value">
|
||||
{{ filter.value }}
|
||||
|
||||
<i class="mt-1 ltr:-right-2 rtl:left-0 rtl:right-0 el-tag__close el-icon-close " style="font-size: 16px;" @click="onFilterDelete(index)"></i>
|
||||
<i class="mt-1 ltr:-right-2 rtl:left-0 rtl:right-0 el-tag__close el-icon-close" style="font-size: 16px;" @click="onFilterDelete(index)"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative w-full h-full flex">
|
||||
<input
|
||||
v-if="!show_date"
|
||||
type="text"
|
||||
class="w-full h-12 lg:h-auto bg-transparent text-black text-sm border-0 pb-0 focus:outline-none focus:ring-transparent focus:border-purple-100"
|
||||
:class="!show_icon ? 'ltr:pr-4 rtl:pl-4' : 'ltr:pr-10 rtl:pl-10'"
|
||||
:placeholder="dynamicPlaceholder"
|
||||
:ref="'input-search-field-' + _uid"
|
||||
v-model="search"
|
||||
@focus="onInputFocus"
|
||||
@input="onInput"
|
||||
@blur="onBlur"
|
||||
@keyup.enter="onInputConfirm"
|
||||
v-if="!show_date"
|
||||
type="text"
|
||||
class="w-full h-12 lg:h-auto bg-transparent text-black text-sm border-0 pb-0 focus:outline-none focus:ring-transparent focus:border-purple-100"
|
||||
:class="!show_icon ? 'ltr:pr-4 rtl:pl-4' : 'ltr:pr-10 rtl:pl-10'"
|
||||
:placeholder="dynamicPlaceholder"
|
||||
:ref="'input-search-field-' + _uid"
|
||||
v-model="search"
|
||||
@focus="onInputFocus"
|
||||
@input="onInput"
|
||||
@blur="onBlur"
|
||||
@keyup.enter="onInputConfirm"
|
||||
/>
|
||||
|
||||
<flat-picker
|
||||
@ -148,47 +149,57 @@ export default {
|
||||
default: 'Search or filter results...',
|
||||
description: 'Input placeholder'
|
||||
},
|
||||
|
||||
selectPlaceholder: {
|
||||
type: String,
|
||||
},
|
||||
|
||||
enterPlaceholder: {
|
||||
type: String,
|
||||
},
|
||||
|
||||
searchText: {
|
||||
type: String,
|
||||
default: 'Search for this text',
|
||||
description: 'Input placeholder'
|
||||
},
|
||||
|
||||
operatorIsText: {
|
||||
type: String,
|
||||
default: 'is',
|
||||
description: 'Operator is "="'
|
||||
},
|
||||
|
||||
operatorIsNotText: {
|
||||
type: String,
|
||||
default: 'is not',
|
||||
description: 'Operator is not "!="'
|
||||
},
|
||||
|
||||
noDataText: {
|
||||
type: String,
|
||||
default: 'No Data',
|
||||
description: "Selectbox empty options message"
|
||||
},
|
||||
|
||||
noMatchingDataText: {
|
||||
type: String,
|
||||
default: 'No Matchign Data',
|
||||
description: "Selectbox search option not found item message"
|
||||
},
|
||||
|
||||
value: {
|
||||
type: String,
|
||||
default: null,
|
||||
description: 'Search attribute value'
|
||||
},
|
||||
|
||||
filters: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
description: 'List of filters'
|
||||
},
|
||||
|
||||
defaultFiltered: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
@ -196,7 +207,6 @@ export default {
|
||||
},
|
||||
|
||||
dateConfig: null
|
||||
|
||||
},
|
||||
|
||||
model: {
|
||||
@ -317,7 +327,7 @@ export default {
|
||||
onInput(evt) {
|
||||
this.search = evt.target.value;
|
||||
this.show_button = true;
|
||||
|
||||
|
||||
let option_url = this.selected_options.length > 0 && this.selected_options[this.filter_index] !== undefined ? this.selected_options[this.filter_index].url : '';
|
||||
|
||||
if (this.search) {
|
||||
@ -423,10 +433,12 @@ export default {
|
||||
|
||||
let option = false;
|
||||
let option_url = false;
|
||||
let option_fields = {};
|
||||
|
||||
for (let i = 0; i < this.filter_list.length; i++) {
|
||||
if (this.filter_list[i].key == value) {
|
||||
option = this.filter_list[i].value;
|
||||
option_fields = (this.filter_list[i]['value_option_fields']) ? this.filter_list[i].value_option_fields : {};
|
||||
|
||||
if (this.filter_list[i].values !== 'undefined' && Object.keys(this.filter_list[i].values).length) {
|
||||
this.option_values[value] = this.convertOption(this.filter_list[i].values);
|
||||
@ -475,7 +487,7 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.option_values[value] && option_url) {
|
||||
if (! this.option_values[value] && option_url) {
|
||||
if (option_url.indexOf('limit') === -1) {
|
||||
option_url += ' limit:10';
|
||||
}
|
||||
@ -487,11 +499,19 @@ export default {
|
||||
this.values = [];
|
||||
|
||||
data.forEach(function (item) {
|
||||
this.values.push({
|
||||
key: (item.code) ? item.code : item.id,
|
||||
value: (item.title) ? item.title : (item.display_name) ? item.display_name : item.name,
|
||||
level: (item.level) ? item.level : null,
|
||||
});
|
||||
if (Object.keys(option_fields).length) {
|
||||
this.values.push({
|
||||
key: (option_fields['key']) ? item[option_fields['key']] : (item.code) ? item.code : item.id,
|
||||
value: (option_fields['value']) ? item[option_fields['value']] : (item.title) ? item.title : (item.display_name) ? item.display_name : item.name,
|
||||
level: (option_fields['level']) ? item[option_fields['level']] : (item.level) ? item.level : null,
|
||||
});
|
||||
} else {
|
||||
this.values.push({
|
||||
key: (item.code) ? item.code : item.id,
|
||||
value: (item.title) ? item.title : (item.display_name) ? item.display_name : item.name,
|
||||
level: (item.level) ? item.level : null,
|
||||
});
|
||||
}
|
||||
}, this);
|
||||
|
||||
this.option_values[value] = this.values;
|
||||
@ -617,7 +637,7 @@ export default {
|
||||
this.selected_values.splice(index, 1);
|
||||
|
||||
this.show_date = false;
|
||||
|
||||
|
||||
if (this.filter_index == 0) {
|
||||
this.onChangeSearchAndFilterText(this.defaultPlaceholder, true);
|
||||
this.show_close_icon = false;
|
||||
@ -647,7 +667,7 @@ export default {
|
||||
let values = [];
|
||||
|
||||
// Option set sort_option data
|
||||
if (!Array.isArray(options)) {
|
||||
if (! Array.isArray(options)) {
|
||||
for (const [key, value] of Object.entries(options)) {
|
||||
values.push({
|
||||
key: (key).toString(),
|
||||
@ -850,6 +870,7 @@ export default {
|
||||
this.values.sort(function (a, b) {
|
||||
var nameA = a.value.toUpperCase(); // ignore upper and lowercase
|
||||
var nameB = b.value.toUpperCase(); // ignore upper and lowercase
|
||||
|
||||
if (nameA < nameB) {
|
||||
return -1;
|
||||
}
|
||||
@ -857,6 +878,7 @@ export default {
|
||||
if (nameA > nameB) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// names must be equal
|
||||
return 0;
|
||||
});
|
||||
@ -936,7 +958,7 @@ export default {
|
||||
|
||||
.searh-field .btn:not(:disabled):not(.disabled):active:focus,
|
||||
.searh-field .btn:not(:disabled):not(.disabled).active:focus {
|
||||
-webkit-box-shadow: none !important;
|
||||
-webkit-box-shadow: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="card-item relative w-2/4 lg:w-3/4 h-48 m-auto" :class="{ '-active' : isCardFlipped }">
|
||||
<div class="card-item relative w-2/4 lg:w-3/4 h-48 m-auto my-5" :class="{ '-active' : isCardFlipped }">
|
||||
<div class="card-item__side h-full rounded-lg shadow-lg overflow-hidden" style="transform: perspective(2000px) rotateY(0deg) rotateX(0deg) rotate(0deg);
|
||||
transform-style: preserve-3d;
|
||||
transition: all 0.8s cubic-bezier(0.71, 0.03, 0.56, 0.85);
|
||||
|
@ -1,204 +1,257 @@
|
||||
<template>
|
||||
<div
|
||||
@click="tryClose"
|
||||
data-notify="container"
|
||||
class="alert alert-notify fixed w-full sm:w-500 flex items-center justify-between ltr:right-0 rtl:left-0 sm:ltr:right-4 sm:rtl:left-4 p-4 text-black font-bold rounded-lg z-30"
|
||||
:class="[
|
||||
{ 'alert-with-icon': icon },
|
||||
verticalAlign,
|
||||
horizontalAlign,
|
||||
alertType
|
||||
]"
|
||||
role="alert"
|
||||
:style="customPosition"
|
||||
data-notify-position="top-center"
|
||||
>
|
||||
<div class="flex items-center ltr:pr-3 rtl:pl-3">
|
||||
<template v-if="icon || $slots.icon">
|
||||
<slot name="icon">
|
||||
<span class="alert-icon flex items-center ltr:mr-2 rtl:ml-2" data-notify="icon">
|
||||
<span class="material-icons text-2xl">{{ icon }}</span>
|
||||
<div
|
||||
@click="tryClose"
|
||||
data-notify="container"
|
||||
:class="[
|
||||
'alert alert-notify',
|
||||
'fixed w-full sm:w-500 flex items-center justify-between',
|
||||
{
|
||||
'rtl:right-0 ltr:left-0' : horizontalAlign == 'left',
|
||||
'sm:rtl:right-4 sm:ltr:left-4' : horizontalAlign == 'left',
|
||||
},
|
||||
{
|
||||
'ltr:right-0 rtl:left-0' : horizontalAlign == 'right',
|
||||
'sm:ltr:right-4 sm:rtl:left-4' : horizontalAlign == 'right',
|
||||
},
|
||||
'p-4',
|
||||
'text-black font-bold',
|
||||
'rounded-lg',
|
||||
'z-30',
|
||||
{
|
||||
'alert-with-icon': icon
|
||||
},
|
||||
verticalAlign,
|
||||
horizontalAlign,
|
||||
alertType
|
||||
]"
|
||||
role="alert"
|
||||
:style="customPosition"
|
||||
data-notify-position="top-center"
|
||||
>
|
||||
<div class="flex items-center ltr:pr-3 rtl:pl-3">
|
||||
<template v-if="icon || $slots.icon">
|
||||
<slot name="icon">
|
||||
<span class="alert-icon flex items-center ltr:mr-2 rtl:ml-2" data-notify="icon">
|
||||
<span class="material-icons text-2xl">{{ icon }}</span>
|
||||
</span>
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
<span class="alert-text">
|
||||
<span v-if="title" class="title">
|
||||
<b>{{ title }}<br/></b>
|
||||
</span>
|
||||
|
||||
<span v-if="message" v-html="message"></span>
|
||||
|
||||
<content-render v-if="!message && component" :component="component"></content-render>
|
||||
</span>
|
||||
</slot>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<span class="alert-text">
|
||||
<span v-if="title" class="title">
|
||||
<b>{{ title }}<br/></b>
|
||||
</span>
|
||||
<span v-if="message" v-html="message"></span>
|
||||
<content-render
|
||||
v-if="!message && component"
|
||||
:component="component"
|
||||
></content-render>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<slot name="dismiss-icon">
|
||||
<button type="button"
|
||||
class="close text-2xl"
|
||||
data-dismiss="alert"
|
||||
aria-label="Close"
|
||||
@click="close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</slot>
|
||||
</div>
|
||||
<slot name="dismiss-icon">
|
||||
<button type="button"
|
||||
class="close text-2xl"
|
||||
data-dismiss="alert"
|
||||
aria-label="Close"
|
||||
@click="close"
|
||||
>
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'notification',
|
||||
components: {
|
||||
contentRender: {
|
||||
props: ['component'],
|
||||
render: h => h(this.component)
|
||||
}
|
||||
},
|
||||
props: {
|
||||
message: String,
|
||||
title: {
|
||||
type: String,
|
||||
description: 'Notification title'
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
description: 'Notification icon'
|
||||
},
|
||||
verticalAlign: {
|
||||
type: String,
|
||||
default: 'top',
|
||||
validator: value => {
|
||||
let acceptedValues = ['top', 'bottom'];
|
||||
return acceptedValues.indexOf(value) !== -1;
|
||||
export default {
|
||||
name: 'notification',
|
||||
|
||||
components: {
|
||||
contentRender: {
|
||||
props: ['component'],
|
||||
render: h => h(this.component)
|
||||
}
|
||||
},
|
||||
description: 'Vertical alignment of notification (top|bottom)'
|
||||
},
|
||||
horizontalAlign: {
|
||||
type: String,
|
||||
default: 'right',
|
||||
validator: value => {
|
||||
let acceptedValues = ['left', 'center', 'right'];
|
||||
return acceptedValues.indexOf(value) !== -1;
|
||||
|
||||
props: {
|
||||
message: String,
|
||||
|
||||
title: {
|
||||
type: String,
|
||||
description: 'Notification title'
|
||||
},
|
||||
|
||||
icon: {
|
||||
type: String,
|
||||
description: 'Notification icon'
|
||||
},
|
||||
|
||||
verticalAlign: {
|
||||
type: String,
|
||||
default: 'top',
|
||||
validator: value => {
|
||||
let acceptedValues = ['top', 'bottom'];
|
||||
|
||||
return acceptedValues.indexOf(value) !== -1;
|
||||
},
|
||||
description: 'Vertical alignment of notification (top|bottom)'
|
||||
},
|
||||
|
||||
horizontalAlign: {
|
||||
type: String,
|
||||
default: 'right',
|
||||
validator: value => {
|
||||
let acceptedValues = ['left', 'center', 'right'];
|
||||
|
||||
return acceptedValues.indexOf(value) !== -1;
|
||||
},
|
||||
description: 'Horizontal alignment of notification (left|center|right)'
|
||||
},
|
||||
|
||||
type: {
|
||||
type: String,
|
||||
default: 'info',
|
||||
validator: value => {
|
||||
let acceptedValues = [
|
||||
'default',
|
||||
'info',
|
||||
'primary',
|
||||
'danger',
|
||||
'warning',
|
||||
'success'
|
||||
];
|
||||
|
||||
return acceptedValues.indexOf(value) !== -1;
|
||||
},
|
||||
description: 'Notification type of notification (gray-300|blue-300|gray-300|red-300|orange-300|green-300)'
|
||||
},
|
||||
|
||||
timeout: {
|
||||
type: Number,
|
||||
default: 5000,
|
||||
validator: value => {
|
||||
return value >= 0;
|
||||
},
|
||||
description: 'Notification timeout (closes after X milliseconds). Default is 5000 (5s)'
|
||||
},
|
||||
|
||||
timestamp: {
|
||||
type: Date,
|
||||
default: () => new Date(),
|
||||
description: 'Notification timestamp (used internally to handle notification removal correctly)'
|
||||
},
|
||||
|
||||
component: {
|
||||
type: [Object, Function],
|
||||
description: 'Custom content component. Cane be a `.vue` component or render function'
|
||||
},
|
||||
|
||||
showClose: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
description: 'Whether to show close button'
|
||||
},
|
||||
|
||||
closeOnClick: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
description: 'Whether to close notification when clicking it\' body'
|
||||
},
|
||||
|
||||
clickHandler: {
|
||||
type: Function,
|
||||
description: 'Custom notification click handler'
|
||||
}
|
||||
},
|
||||
description: 'Horizontal alignment of notification (left|center|right)'
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'info',
|
||||
validator: value => {
|
||||
let acceptedValues = [
|
||||
'default',
|
||||
'info',
|
||||
'primary',
|
||||
'danger',
|
||||
'warning',
|
||||
'success'
|
||||
];
|
||||
return acceptedValues.indexOf(value) !== -1;
|
||||
|
||||
data() {
|
||||
return {
|
||||
elmHeight: 0,
|
||||
|
||||
typeByClass: {
|
||||
'default': 'black-100',
|
||||
'info': 'blue-100',
|
||||
'primary': 'black-100',
|
||||
'danger': 'red-100',
|
||||
'warning': 'orange-100',
|
||||
'success': 'green-100',
|
||||
},
|
||||
|
||||
textByClass: {
|
||||
'default': 'black-600',
|
||||
'info': 'blue-600',
|
||||
'primary': 'black-600',
|
||||
'danger': 'red-600',
|
||||
'warning': 'orange-600',
|
||||
'success': 'green-600',
|
||||
}
|
||||
};
|
||||
},
|
||||
description: 'Notification type of notification (gray-300|blue-300|gray-300|red-300|orange-300|green-300)'
|
||||
},
|
||||
timeout: {
|
||||
type: Number,
|
||||
default: 5000,
|
||||
validator: value => {
|
||||
return value >= 0;
|
||||
|
||||
computed: {
|
||||
hasIcon() {
|
||||
return this.icon && this.icon.length > 0;
|
||||
},
|
||||
|
||||
alertType() {
|
||||
return `bg-${this.typeByClass[this.type]} text-${this.textByClass[this.type]}`;
|
||||
},
|
||||
|
||||
customPosition() {
|
||||
let initialMargin = 20;
|
||||
let alertHeight = this.elmHeight + 10;
|
||||
|
||||
let sameAlertsCount = this.$notifications.state.filter(alert => {
|
||||
return (
|
||||
alert.horizontalAlign === this.horizontalAlign &&
|
||||
alert.verticalAlign === this.verticalAlign &&
|
||||
alert.timestamp <= this.timestamp
|
||||
);
|
||||
}).length;
|
||||
|
||||
if (this.$notifications.settings.overlap) {
|
||||
sameAlertsCount = 1;
|
||||
}
|
||||
|
||||
let pixels = (sameAlertsCount - 1) * alertHeight + initialMargin;
|
||||
|
||||
if (sameAlertsCount > 1) {
|
||||
pixels = 30 + this.$parent.children[sameAlertsCount - 2].elm.offsetHeight;
|
||||
}
|
||||
|
||||
let styles = {};
|
||||
|
||||
if (this.verticalAlign === 'top') {
|
||||
styles.top = `${pixels}px`;
|
||||
} else {
|
||||
styles.bottom = `${pixels}px`;
|
||||
}
|
||||
|
||||
return styles;
|
||||
}
|
||||
},
|
||||
description: 'Notification timeout (closes after X milliseconds). Default is 5000 (5s)'
|
||||
},
|
||||
timestamp: {
|
||||
type: Date,
|
||||
default: () => new Date(),
|
||||
description: 'Notification timestamp (used internally to handle notification removal correctly)'
|
||||
},
|
||||
component: {
|
||||
type: [Object, Function],
|
||||
description: 'Custom content component. Cane be a `.vue` component or render function'
|
||||
},
|
||||
showClose: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
description: 'Whether to show close button'
|
||||
},
|
||||
closeOnClick: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
description: 'Whether to close notification when clicking it\' body'
|
||||
},
|
||||
clickHandler: {
|
||||
type: Function,
|
||||
description: 'Custom notification click handler'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
elmHeight: 0,
|
||||
typeByClass: {
|
||||
'default': 'black-100',
|
||||
'info': 'blue-100',
|
||||
'primary': 'black-100',
|
||||
'danger': 'red-100',
|
||||
'warning': 'orange-100',
|
||||
'success': 'green-100',
|
||||
|
||||
methods: {
|
||||
close() {
|
||||
this.$emit('close', this.timestamp);
|
||||
},
|
||||
|
||||
tryClose(evt) {
|
||||
if (this.clickHandler) {
|
||||
this.clickHandler(evt, this);
|
||||
}
|
||||
|
||||
if (this.closeOnClick) {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
},
|
||||
textByClass: {
|
||||
'default': 'black-600',
|
||||
'info': 'blue-600',
|
||||
'primary': 'black-600',
|
||||
'danger': 'red-600',
|
||||
'warning': 'orange-600',
|
||||
'success': 'green-600',
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
hasIcon() {
|
||||
return this.icon && this.icon.length > 0;
|
||||
},
|
||||
alertType() {
|
||||
return `bg-${this.typeByClass[this.type]} text-${this.textByClass[this.type]}`;
|
||||
},
|
||||
customPosition() {
|
||||
let initialMargin = 20;
|
||||
let alertHeight = this.elmHeight + 10;
|
||||
let sameAlertsCount = this.$notifications.state.filter(alert => {
|
||||
return (
|
||||
alert.horizontalAlign === this.horizontalAlign &&
|
||||
alert.verticalAlign === this.verticalAlign &&
|
||||
alert.timestamp <= this.timestamp
|
||||
);
|
||||
}).length;
|
||||
if (this.$notifications.settings.overlap) {
|
||||
sameAlertsCount = 1;
|
||||
}
|
||||
let pixels = (sameAlertsCount - 1) * alertHeight + initialMargin;
|
||||
let styles = {};
|
||||
if (this.verticalAlign === 'top') {
|
||||
styles.top = `${pixels}px`;
|
||||
} else {
|
||||
styles.bottom = `${pixels}px`;
|
||||
}
|
||||
return styles;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
close() {
|
||||
this.$emit('close', this.timestamp);
|
||||
},
|
||||
tryClose(evt) {
|
||||
if (this.clickHandler) {
|
||||
this.clickHandler(evt, this);
|
||||
}
|
||||
if (this.closeOnClick) {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.elmHeight = this.$el.clientHeight;
|
||||
if (this.timeout) {
|
||||
setTimeout(this.close, this.timeout);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
mounted() {
|
||||
this.elmHeight = this.$el.clientHeight;
|
||||
|
||||
if (this.timeout) {
|
||||
setTimeout(this.close, this.timeout);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -1,55 +1,63 @@
|
||||
<template>
|
||||
<div class="notifications">
|
||||
<slide-y-up-transition :duration="transitionDuration"
|
||||
group
|
||||
mode="out-in">
|
||||
<notification
|
||||
v-for="notification in notifications"
|
||||
v-bind="notification"
|
||||
:clickHandler="notification.onClick"
|
||||
:key="notification.timestamp.getTime()"
|
||||
@close="removeNotification"
|
||||
>
|
||||
</notification>
|
||||
</slide-y-up-transition>
|
||||
</div>
|
||||
<div class="notifications">
|
||||
<slide-y-up-transition :duration="transitionDuration"
|
||||
group
|
||||
mode="out-in"
|
||||
>
|
||||
<notification
|
||||
v-for="notification in notifications"
|
||||
v-bind="notification"
|
||||
:clickHandler="notification.onClick"
|
||||
:key="notification.timestamp.getTime()"
|
||||
@close="removeNotification"
|
||||
>
|
||||
</notification>
|
||||
</slide-y-up-transition>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Notification from './Notification.vue';
|
||||
import { SlideYUpTransition } from 'vue2-transitions';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SlideYUpTransition,
|
||||
Notification
|
||||
},
|
||||
props: {
|
||||
transitionDuration: {
|
||||
type: Number,
|
||||
default: 200
|
||||
},
|
||||
overlap: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
notifications: this.$notifications.state
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
removeNotification(timestamp) {
|
||||
this.$notifications.removeNotification(timestamp);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$notifications.settings.overlap = this.overlap;
|
||||
},
|
||||
watch: {
|
||||
overlap: function (newVal) {
|
||||
this.$notifications.settings.overlap = newVal;
|
||||
}
|
||||
}
|
||||
};
|
||||
<script>
|
||||
import Notification from './Notification.vue';
|
||||
import { SlideYUpTransition } from 'vue2-transitions';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SlideYUpTransition,
|
||||
Notification
|
||||
},
|
||||
|
||||
props: {
|
||||
transitionDuration: {
|
||||
type: Number,
|
||||
default: 200
|
||||
},
|
||||
|
||||
overlap: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
notifications: this.$notifications.state
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
removeNotification(timestamp) {
|
||||
this.$notifications.removeNotification(timestamp);
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.$notifications.settings.overlap = this.overlap;
|
||||
},
|
||||
|
||||
watch: {
|
||||
overlap: function (newVal) {
|
||||
this.$notifications.settings.overlap = newVal;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -1,66 +1,81 @@
|
||||
import Notifications from './Notifications.vue';
|
||||
|
||||
const NotificationStore = {
|
||||
state: [], // here the notifications will be added
|
||||
settings: {
|
||||
overlap: false,
|
||||
verticalAlign: 'top',
|
||||
horizontalAlign: 'right',
|
||||
type: 'info',
|
||||
timeout: 5000,
|
||||
closeOnClick: true,
|
||||
showClose: true
|
||||
},
|
||||
setOptions(options) {
|
||||
this.settings = Object.assign(this.settings, options);
|
||||
},
|
||||
removeNotification(timestamp) {
|
||||
const indexToDelete = this.state.findIndex(n => n.timestamp === timestamp);
|
||||
if (indexToDelete !== -1) {
|
||||
this.state.splice(indexToDelete, 1);
|
||||
state: [], // here the notifications will be added
|
||||
|
||||
settings: {
|
||||
overlap: false,
|
||||
verticalAlign: 'top',
|
||||
horizontalAlign: 'right',
|
||||
type: 'info',
|
||||
timeout: 5000,
|
||||
closeOnClick: true,
|
||||
showClose: true
|
||||
},
|
||||
|
||||
setOptions(options) {
|
||||
this.settings = Object.assign(this.settings, options);
|
||||
},
|
||||
|
||||
removeNotification(timestamp) {
|
||||
const indexToDelete = this.state.findIndex(n => n.timestamp === timestamp);
|
||||
|
||||
if (indexToDelete !== -1) {
|
||||
this.state.splice(indexToDelete, 1);
|
||||
}
|
||||
},
|
||||
|
||||
addNotification(notification) {
|
||||
if (typeof notification === 'string' || notification instanceof String) {
|
||||
notification = {
|
||||
message: notification
|
||||
};
|
||||
}
|
||||
|
||||
notification.timestamp = new Date();
|
||||
|
||||
notification.timestamp.setMilliseconds(
|
||||
notification.timestamp.getMilliseconds() + this.state.length
|
||||
);
|
||||
|
||||
notification = Object.assign({}, this.settings, notification);
|
||||
|
||||
this.state.push(notification);
|
||||
},
|
||||
|
||||
notify(notification) {
|
||||
if (Array.isArray(notification)) {
|
||||
notification.forEach(notificationInstance => {
|
||||
this.addNotification(notificationInstance);
|
||||
});
|
||||
} else {
|
||||
this.addNotification(notification);
|
||||
}
|
||||
}
|
||||
},
|
||||
addNotification(notification) {
|
||||
if (typeof notification === 'string' || notification instanceof String) {
|
||||
notification = { message: notification };
|
||||
}
|
||||
notification.timestamp = new Date();
|
||||
notification.timestamp.setMilliseconds(
|
||||
notification.timestamp.getMilliseconds() + this.state.length
|
||||
);
|
||||
notification = Object.assign({}, this.settings, notification);
|
||||
this.state.push(notification);
|
||||
},
|
||||
notify(notification) {
|
||||
if (Array.isArray(notification)) {
|
||||
notification.forEach(notificationInstance => {
|
||||
this.addNotification(notificationInstance);
|
||||
});
|
||||
} else {
|
||||
this.addNotification(notification);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const NotificationsPlugin = {
|
||||
install(Vue, options) {
|
||||
let app = new Vue({
|
||||
data: {
|
||||
notificationStore: NotificationStore
|
||||
},
|
||||
methods: {
|
||||
notify(notification) {
|
||||
this.notificationStore.notify(notification);
|
||||
install(Vue, options) {
|
||||
let app = new Vue({
|
||||
data: {
|
||||
notificationStore: NotificationStore
|
||||
},
|
||||
|
||||
methods: {
|
||||
notify(notification) {
|
||||
this.notificationStore.notify(notification);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Vue.prototype.$notify = app.notify;
|
||||
Vue.prototype.$notifications = app.notificationStore;
|
||||
Vue.component('Notifications', Notifications);
|
||||
|
||||
if (options) {
|
||||
NotificationStore.setOptions(options);
|
||||
}
|
||||
}
|
||||
});
|
||||
Vue.prototype.$notify = app.notify;
|
||||
Vue.prototype.$notifications = app.notificationStore;
|
||||
Vue.component('Notifications', Notifications);
|
||||
if (options) {
|
||||
NotificationStore.setOptions(options);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default NotificationsPlugin;
|
||||
|
25
resources/assets/js/mixins/global.js
vendored
25
resources/assets/js/mixins/global.js
vendored
@ -271,6 +271,8 @@ export default {
|
||||
}
|
||||
|
||||
this.$notify({
|
||||
verticalAlign: 'bottom',
|
||||
horizontalAlign: 'left',
|
||||
message: notify.message,
|
||||
timeout: timeout,
|
||||
icon: 'error_outline',
|
||||
@ -467,6 +469,9 @@ export default {
|
||||
onChangePaginationLimit(event) {
|
||||
let path = '';
|
||||
|
||||
let split_href = window.location.href.split('#');
|
||||
let href = split_href[0];
|
||||
|
||||
if (window.location.search.length) {
|
||||
if (window.location.search.includes('limit')) {
|
||||
let queries = [];
|
||||
@ -494,10 +499,14 @@ export default {
|
||||
});
|
||||
|
||||
} else {
|
||||
path = window.location.href + '&limit=' + event.target.getAttribute("value");
|
||||
path = href + '&limit=' + event.target.getAttribute("value");
|
||||
}
|
||||
} else {
|
||||
path = window.location.href + '?limit=' + event.target.getAttribute("value");
|
||||
path = href + '?limit=' + event.target.getAttribute("value");
|
||||
}
|
||||
|
||||
if (split_href[1]) {
|
||||
path += '#' + split_href[1];
|
||||
}
|
||||
|
||||
window.location.href = path;
|
||||
@ -505,6 +514,10 @@ export default {
|
||||
|
||||
// Dynamic component get path view and show it.
|
||||
onDynamicComponent(path) {
|
||||
if (! path) {
|
||||
return;
|
||||
}
|
||||
|
||||
axios.get(path)
|
||||
.then(response => {
|
||||
let html = response.data.html;
|
||||
@ -562,6 +575,10 @@ export default {
|
||||
},
|
||||
|
||||
onDynamicFormParams(path, params) {
|
||||
if (! path) {
|
||||
return;
|
||||
}
|
||||
|
||||
let data = {};
|
||||
|
||||
for (const [key, value] of Object.entries(params)) {
|
||||
@ -1001,7 +1018,7 @@ export default {
|
||||
|
||||
this.component = Vue.component('add-new-component', (resolve, reject) => {
|
||||
resolve({
|
||||
template: '<div id="dynamic-email-component"><akaunting-modal-add-new modal-dialog-class="max-w-screen-md" :show="email.modal" @submit="onSubmit" @cancel="onCancel" :buttons="email.buttons" :title="email.title" :is_component=true :message="email.html"></akaunting-modal-add-new></div>',
|
||||
template: '<div id="dynamic-email-component"><akaunting-modal-add-new modal-dialog-class="max-w-screen-md" modal-position-top :show="email.modal" @submit="onSubmit" @cancel="onCancel" :buttons="email.buttons" :title="email.title" :is_component=true :message="email.html"></akaunting-modal-add-new></div>',
|
||||
|
||||
components: {
|
||||
AkauntingDropzoneFileUpload,
|
||||
@ -1112,6 +1129,8 @@ export default {
|
||||
document.execCommand('copy');
|
||||
|
||||
this.$notify({
|
||||
verticalAlign: 'bottom',
|
||||
horizontalAlign: 'left',
|
||||
message: this.share.success_message,
|
||||
timeout: 5000,
|
||||
icon: 'error_outline',
|
||||
|
4
resources/assets/js/mixins/wizardAction.js
vendored
4
resources/assets/js/mixins/wizardAction.js
vendored
@ -72,6 +72,8 @@ export default {
|
||||
}
|
||||
|
||||
this.$notify({
|
||||
verticalAlign: 'bottom',
|
||||
horizontalAlign: 'left',
|
||||
message: response.data.message,
|
||||
timeout: timeout,
|
||||
icon: "error_outline",
|
||||
@ -92,6 +94,8 @@ export default {
|
||||
}
|
||||
|
||||
this.$notify({
|
||||
verticalAlign: 'bottom',
|
||||
horizontalAlign: 'left',
|
||||
message: event.message,
|
||||
timeout: timeout,
|
||||
icon: "error_outline",
|
||||
|
2
resources/assets/js/views/auth/common.js
vendored
2
resources/assets/js/views/auth/common.js
vendored
@ -54,6 +54,8 @@ const login = new Vue({
|
||||
let type = notify.level;
|
||||
|
||||
this.$notify({
|
||||
verticalAlign: 'bottom',
|
||||
horizontalAlign: 'left',
|
||||
message: notify.message,
|
||||
timeout: 5000,
|
||||
icon: '',
|
||||
|
25
resources/assets/js/views/banking/accounts.js
vendored
25
resources/assets/js/views/banking/accounts.js
vendored
@ -31,29 +31,4 @@ const app = new Vue({
|
||||
bulk_action: new BulkAction('accounts'),
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onType(event) {
|
||||
return;
|
||||
let type = event.target.value;
|
||||
|
||||
switch(type) {
|
||||
case 'credit_card':
|
||||
this.onCreditCard();
|
||||
break;
|
||||
case 'bank':
|
||||
default:
|
||||
this.onBank();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
onCreditCard() {
|
||||
|
||||
},
|
||||
|
||||
onBank() {
|
||||
|
||||
},
|
||||
}
|
||||
});
|
||||
|
2
resources/assets/js/views/common/contacts.js
vendored
2
resources/assets/js/views/common/contacts.js
vendored
@ -69,6 +69,8 @@ const app = new Vue({
|
||||
|
||||
if (response.data.error) {
|
||||
this.$notify({
|
||||
verticalAlign: 'bottom',
|
||||
horizontalAlign: 'left',
|
||||
message: response.data.message,
|
||||
timeout: 0,
|
||||
icon: 'fas fa-bell',
|
||||
|
@ -621,6 +621,7 @@ const app = new Vue({
|
||||
onChangeCurrency(currency_code) {
|
||||
if (this.edit.status && this.edit.currency <= 2) {
|
||||
this.edit.currency++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
2
resources/assets/js/views/modules/apps.js
vendored
2
resources/assets/js/views/modules/apps.js
vendored
@ -106,6 +106,8 @@ const app = new Vue({
|
||||
add_to_cart_promise.then(response => {
|
||||
if (response.data.success) {
|
||||
this.$notify({
|
||||
verticalAlign: 'bottom',
|
||||
horizontalAlign: 'left',
|
||||
message: response.data.message,
|
||||
timeout: 0,
|
||||
icon: "shopping_cart_checkout",
|
||||
|
@ -141,7 +141,7 @@ const app = new Vue({
|
||||
});
|
||||
},
|
||||
|
||||
// Change currency get money
|
||||
// Change currency get money override because remove form currency_code and currency_rate column
|
||||
onChangeCurrency(currency_code) {
|
||||
if (! currency_code) {
|
||||
return;
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="relative bg-body z-10 rounded-lg shadow-2xl p-5 ltr:pr-0 rtl:pl-0 sm:py-10 sm:ltr:pl-10 sm:rtl:pr-10 overflow-hidden">
|
||||
<div class="relative bg-body z-10 rounded-lg shadow-2xl p-5 sm:p-10 full-height-mobile overflow-hidden">
|
||||
<WizardSteps :active_state="active"></WizardSteps>
|
||||
|
||||
<div class="flex flex-col justify-between -mt-5 sm:mt-0" style="height:565px;">
|
||||
@ -42,7 +42,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative w-1/2 right-0 ltr:pl-10 rtl:pr-10 mt-3 hidden lg:flex lg:flex-col">
|
||||
<div class="absolute w-1/2 right-0 ltr:pl-10 rtl:pr-10 mt-3 hidden lg:flex lg:flex-col">
|
||||
<div class="flex flex-col ltr:items-start rtl:items-end bg-purple ltr:rounded-tl-lg ltr:rounded-bl-lg rtl:rounded-tr-lg rtl:rounded-br-lg p-6">
|
||||
<div class="w-48 text-white text-left text-2xl font-semibold leading-9">
|
||||
{{ translations.finish.apps_managing }}
|
||||
@ -50,7 +50,7 @@
|
||||
|
||||
<div style="width:372px; height:372px;"></div>
|
||||
|
||||
<img :src="image_src" class="absolute top-3 right-2" alt="" />
|
||||
<img :src="image_src" class="absolute top-3 right-2" alt="Akaunting" />
|
||||
</div>
|
||||
|
||||
<base-button
|
||||
@ -59,7 +59,7 @@
|
||||
@click="finish()"
|
||||
>
|
||||
<i v-if="anchor_loading" class="animate-submit_second delay-[0.28s] absolute w-2 h-2 rounded-full left-0 right-0 -top-2.5 m-auto before:absolute before:w-2 before:h-2 before:rounded-full before:animate-submit_second before:delay-[0.14s] after:absolute after:w-2 after:h-2 after:rounded-full after:animate-submit_second before:-left-3.5 after:-right-3.5 after:delay-[0.42s]"></i>
|
||||
|
||||
|
||||
<span :class="[{'opacity-0': anchor_loading}]">
|
||||
{{ translations.finish.create_first_invoice }}
|
||||
</span>
|
||||
@ -112,6 +112,8 @@ export default {
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$notify({
|
||||
verticalAlign: 'bottom',
|
||||
horizontalAlign: 'left',
|
||||
message: this.translations.finish.error_message,
|
||||
timeout: 1000,
|
||||
icon: "",
|
||||
|
Reference in New Issue
Block a user