mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
remove components Charts, Notification, SearchUser, ButtonCheckbox, Button RadioGroup, Breadcrumb
This commit is contained in:
parent
2057cdcae3
commit
159bff71df
@ -1,25 +0,0 @@
|
||||
<template>
|
||||
<nav aria-label="breadcrumb">
|
||||
<b-breadcrumb :class="[{ [`bg-${type}`]: type }, listClasses]">
|
||||
<slot></slot>
|
||||
</b-breadcrumb>
|
||||
</nav>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'breadcrumb',
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: '',
|
||||
description: 'Breadcrumb background type',
|
||||
},
|
||||
listClasses: {
|
||||
type: [String, Object],
|
||||
default: '',
|
||||
description: 'Breadcrumb list classes',
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
||||
@ -1,18 +0,0 @@
|
||||
<template>
|
||||
<b-breadcrumb-item :active="active">
|
||||
<slot></slot>
|
||||
</b-breadcrumb-item>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'breadcrumb-item',
|
||||
props: {
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
description: 'Whether breadcrumb item is active',
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
||||
@ -1,40 +0,0 @@
|
||||
<template>
|
||||
<bread-crumb list-classes="breadcrumb-links breadcrumb-dark">
|
||||
<bread-crumb-item>
|
||||
<router-link to="/overview">
|
||||
<i class="fas fa-home"></i>
|
||||
</router-link>
|
||||
</bread-crumb-item>
|
||||
<bread-crumb-item
|
||||
v-for="(route, index) in $route.matched.slice()"
|
||||
:key="route.name"
|
||||
:active="index === $route.matched.length - 1"
|
||||
style="display: inline-block"
|
||||
>
|
||||
<router-link :to="{ name: route.name }" v-if="index < $route.matched.length - 1">
|
||||
{{ route.name }}
|
||||
</router-link>
|
||||
<span v-else>{{ route.name }}</span>
|
||||
</bread-crumb-item>
|
||||
</bread-crumb>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BreadCrumb from './Breadcrumb'
|
||||
import BreadCrumbItem from './BreadcrumbItem'
|
||||
|
||||
export default {
|
||||
name: 'route-breadcrumb',
|
||||
components: {
|
||||
BreadCrumb,
|
||||
BreadCrumbItem,
|
||||
},
|
||||
methods: {
|
||||
getBreadName(route) {
|
||||
return route.name
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@ -1,38 +0,0 @@
|
||||
<template>
|
||||
<div class="btn-group-toggle" data-toggle="buttons">
|
||||
<label class="btn" :class="[{ active: value }, buttonClasses]">
|
||||
<input v-model="model" type="checkbox" checked="" autocomplete="off" />
|
||||
<slot></slot>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'button-checkbox',
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
description: 'Checked value',
|
||||
},
|
||||
buttonClasses: {
|
||||
type: [String, Object],
|
||||
description: 'Inner button css classes',
|
||||
},
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change',
|
||||
},
|
||||
computed: {
|
||||
model: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('change', val)
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
||||
@ -1,55 +0,0 @@
|
||||
<template>
|
||||
<div class="btn-group-toggle" data-toggle="buttons">
|
||||
<label
|
||||
v-for="(option, index) in options"
|
||||
:key="index"
|
||||
class="btn"
|
||||
:class="[{ active: value === option.value }, buttonClasses]"
|
||||
>
|
||||
<input
|
||||
:value="option.value"
|
||||
v-model="model"
|
||||
type="radio"
|
||||
id="option1"
|
||||
autocomplete="off"
|
||||
checked=""
|
||||
/>
|
||||
{{ option.label }}
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'button-radio-group',
|
||||
props: {
|
||||
options: {
|
||||
type: Array,
|
||||
description: 'Radio options. Should be an array of objects {value: "", label: ""}',
|
||||
default: () => [],
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
description: 'Radio value',
|
||||
},
|
||||
buttonClasses: {
|
||||
type: [String, Object],
|
||||
description: 'Inner button css classes',
|
||||
},
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change',
|
||||
},
|
||||
computed: {
|
||||
model: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('change', val)
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
||||
@ -1,30 +0,0 @@
|
||||
import { Bar, mixins } from 'vue-chartjs'
|
||||
import globalOptionsMixin from '@/components/Charts/globalOptionsMixin'
|
||||
|
||||
export default {
|
||||
name: 'bar-chart',
|
||||
extends: Bar,
|
||||
mixins: [mixins.reactiveProp, globalOptionsMixin],
|
||||
props: {
|
||||
extraOptions: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ctx: null,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$watch(
|
||||
'chartData',
|
||||
(newVal, oldVal) => {
|
||||
if (!oldVal) {
|
||||
this.renderChart(this.chartData, this.extraOptions)
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
},
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
import { Line, mixins } from 'vue-chartjs'
|
||||
import globalOptionsMixin from '@/components/Charts/globalOptionsMixin'
|
||||
export default {
|
||||
name: 'line-chart',
|
||||
extends: Line,
|
||||
mixins: [mixins.reactiveProp, globalOptionsMixin],
|
||||
props: {
|
||||
extraOptions: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ctx: null,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$watch(
|
||||
'chartData',
|
||||
(newVal, oldVal) => {
|
||||
if (!oldVal) {
|
||||
this.renderChart(this.chartData, this.extraOptions)
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
},
|
||||
}
|
||||
@ -1,234 +0,0 @@
|
||||
import { parseOptions } from '@/components/Charts/optionHelpers'
|
||||
import Chart from 'chart.js'
|
||||
|
||||
export const Charts = {
|
||||
mode: 'light', // (themeMode) ? themeMode : 'light';
|
||||
fonts: {
|
||||
base: 'Open Sans',
|
||||
},
|
||||
colors: {
|
||||
gray: {
|
||||
100: '#f6f9fc',
|
||||
200: '#e9ecef',
|
||||
300: '#dee2e6',
|
||||
400: '#ced4da',
|
||||
500: '#adb5bd',
|
||||
600: '#8898aa',
|
||||
700: '#525f7f',
|
||||
800: '#32325d',
|
||||
900: '#212529',
|
||||
},
|
||||
theme: {
|
||||
default: '#172b4d',
|
||||
primary: '#5e72e4',
|
||||
secondary: '#f4f5f7',
|
||||
info: '#11cdef',
|
||||
success: '#2dce89',
|
||||
danger: '#f5365c',
|
||||
warning: '#fb6340',
|
||||
},
|
||||
black: '#12263F',
|
||||
white: '#FFFFFF',
|
||||
transparent: 'transparent',
|
||||
},
|
||||
}
|
||||
|
||||
function chartOptions() {
|
||||
const { colors, mode, fonts } = Charts
|
||||
// Options
|
||||
const options = {
|
||||
defaults: {
|
||||
global: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
defaultColor: mode === 'dark' ? colors.gray[700] : colors.gray[600],
|
||||
defaultFontColor: mode === 'dark' ? colors.gray[700] : colors.gray[600],
|
||||
defaultFontFamily: fonts.base,
|
||||
defaultFontSize: 13,
|
||||
layout: {
|
||||
padding: 0,
|
||||
},
|
||||
legend: {
|
||||
display: false,
|
||||
position: 'bottom',
|
||||
labels: {
|
||||
usePointStyle: true,
|
||||
padding: 16,
|
||||
},
|
||||
},
|
||||
elements: {
|
||||
point: {
|
||||
radius: 0,
|
||||
backgroundColor: colors.theme.primary,
|
||||
},
|
||||
line: {
|
||||
tension: 0.4,
|
||||
borderWidth: 4,
|
||||
borderColor: colors.theme.primary,
|
||||
backgroundColor: colors.transparent,
|
||||
borderCapStyle: 'rounded',
|
||||
},
|
||||
rectangle: {
|
||||
backgroundColor: colors.theme.warning,
|
||||
},
|
||||
arc: {
|
||||
backgroundColor: colors.theme.primary,
|
||||
borderColor: mode === 'dark' ? colors.gray[800] : colors.white,
|
||||
borderWidth: 4,
|
||||
},
|
||||
},
|
||||
tooltips: {
|
||||
enabled: true,
|
||||
mode: 'index',
|
||||
intersect: false,
|
||||
},
|
||||
},
|
||||
pie: {
|
||||
tooltips: {
|
||||
mode: 'point',
|
||||
},
|
||||
},
|
||||
doughnut: {
|
||||
tooltips: {
|
||||
mode: 'point',
|
||||
},
|
||||
cutoutPercentage: 83,
|
||||
legendCallback: function (chart) {
|
||||
const data = chart.data
|
||||
let content = ''
|
||||
|
||||
data.labels.forEach(function (label, index) {
|
||||
const bgColor = data.datasets[0].backgroundColor[index]
|
||||
|
||||
content += '<span class="chart-legend-item">'
|
||||
content +=
|
||||
'<i class="chart-legend-indicator" style="background-color: ' + bgColor + '"></i>'
|
||||
content += label
|
||||
content += '</span>'
|
||||
})
|
||||
|
||||
return content
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// yAxes
|
||||
Chart.scaleService.updateScaleDefaults('linear', {
|
||||
gridLines: {
|
||||
borderDash: [2],
|
||||
borderDashOffset: [2],
|
||||
color: mode === 'dark' ? colors.gray[900] : colors.gray[200],
|
||||
drawBorder: false,
|
||||
drawTicks: true,
|
||||
zeroLineWidth: 1,
|
||||
zeroLineColor: mode === 'dark' ? colors.gray[900] : colors.gray[200],
|
||||
zeroLineBorderDash: [2],
|
||||
zeroLineBorderDashOffset: [2],
|
||||
},
|
||||
ticks: {
|
||||
beginAtZero: true,
|
||||
padding: 10,
|
||||
callback: function (value) {
|
||||
if (!(value % 10)) {
|
||||
return value
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// xAxes
|
||||
Chart.scaleService.updateScaleDefaults('category', {
|
||||
gridLines: {
|
||||
drawBorder: false,
|
||||
drawOnChartArea: false,
|
||||
drawTicks: false,
|
||||
lineWidth: 1,
|
||||
zeroLineWidth: 1,
|
||||
},
|
||||
ticks: {
|
||||
padding: 20,
|
||||
},
|
||||
maxBarThickness: 10,
|
||||
})
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
let initialized = false
|
||||
|
||||
export function initGlobalOptions() {
|
||||
if (initialized) {
|
||||
return
|
||||
}
|
||||
parseOptions(Chart, chartOptions())
|
||||
initialized = true
|
||||
}
|
||||
|
||||
export const basicOptions = {
|
||||
maintainAspectRatio: false,
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
responsive: true,
|
||||
}
|
||||
export const blueChartOptions = {
|
||||
scales: {
|
||||
yAxes: [
|
||||
{
|
||||
gridLines: {
|
||||
color: Charts.colors.gray[700],
|
||||
zeroLineColor: Charts.colors.gray[700],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
export const lineChartOptionsBlue = {
|
||||
...basicOptions,
|
||||
tooltips: {
|
||||
backgroundColor: '#f5f5f5',
|
||||
titleFontColor: '#333',
|
||||
bodyFontColor: '#666',
|
||||
bodySpacing: 4,
|
||||
xPadding: 12,
|
||||
mode: 'nearest',
|
||||
intersect: 0,
|
||||
position: 'nearest',
|
||||
},
|
||||
responsive: true,
|
||||
scales: {
|
||||
yAxes: [
|
||||
{
|
||||
barPercentage: 1.6,
|
||||
gridLines: {
|
||||
drawBorder: false,
|
||||
color: 'rgba(29,140,248,0.0)',
|
||||
zeroLineColor: 'transparent',
|
||||
},
|
||||
ticks: {
|
||||
suggestedMin: 60,
|
||||
suggestedMax: 125,
|
||||
padding: 20,
|
||||
fontColor: '#9e9e9e',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
xAxes: [
|
||||
{
|
||||
barPercentage: 1.6,
|
||||
gridLines: {
|
||||
drawBorder: false,
|
||||
color: 'rgba(29,140,248,0.1)',
|
||||
zeroLineColor: 'transparent',
|
||||
},
|
||||
ticks: {
|
||||
padding: 20,
|
||||
fontColor: '#9e9e9e',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
import { initGlobalOptions } from '@/components/Charts/config'
|
||||
import './roundedCornersExtension'
|
||||
export default {
|
||||
mounted() {
|
||||
initGlobalOptions()
|
||||
},
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
// Parse global options
|
||||
export function parseOptions(parent, options) {
|
||||
for (const item in options) {
|
||||
if (typeof options[item] !== 'object') {
|
||||
parent[item] = options[item]
|
||||
} else {
|
||||
parseOptions(parent[item], options[item])
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,126 +0,0 @@
|
||||
//
|
||||
// Chart extension for making the bars rounded
|
||||
// Code from: https://codepen.io/jedtrow/full/ygRYgo
|
||||
//
|
||||
import Chart from 'chart.js'
|
||||
Chart.elements.Rectangle.prototype.draw = function () {
|
||||
const ctx = this._chart.ctx
|
||||
const vm = this._view
|
||||
let left, right, top, bottom, signX, signY, borderSkipped
|
||||
let borderWidth = vm.borderWidth
|
||||
// Set Radius Here
|
||||
// If radius is large enough to cause drawing errors a max radius is imposed
|
||||
const cornerRadius = 6
|
||||
|
||||
if (!vm.horizontal) {
|
||||
// bar
|
||||
left = vm.x - vm.width / 2
|
||||
right = vm.x + vm.width / 2
|
||||
top = vm.y
|
||||
bottom = vm.base
|
||||
signX = 1
|
||||
signY = bottom > top ? 1 : -1
|
||||
borderSkipped = vm.borderSkipped || 'bottom'
|
||||
} else {
|
||||
// horizontal bar
|
||||
left = vm.base
|
||||
right = vm.x
|
||||
top = vm.y - vm.height / 2
|
||||
bottom = vm.y + vm.height / 2
|
||||
signX = right > left ? 1 : -1
|
||||
signY = 1
|
||||
borderSkipped = vm.borderSkipped || 'left'
|
||||
}
|
||||
|
||||
// Canvas doesn't allow us to stroke inside the width so we can
|
||||
// adjust the sizes to fit if we're setting a stroke on the line
|
||||
if (borderWidth) {
|
||||
// borderWidth shold be less than bar width and bar height.
|
||||
const barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom))
|
||||
borderWidth = borderWidth > barSize ? barSize : borderWidth
|
||||
const halfStroke = borderWidth / 2
|
||||
// Adjust borderWidth when bar top position is near vm.base(zero).
|
||||
const borderLeft = left + (borderSkipped !== 'left' ? halfStroke * signX : 0)
|
||||
const borderRight = right + (borderSkipped !== 'right' ? -halfStroke * signX : 0)
|
||||
const borderTop = top + (borderSkipped !== 'top' ? halfStroke * signY : 0)
|
||||
const borderBottom = bottom + (borderSkipped !== 'bottom' ? -halfStroke * signY : 0)
|
||||
// not become a vertical line?
|
||||
if (borderLeft !== borderRight) {
|
||||
top = borderTop
|
||||
bottom = borderBottom
|
||||
}
|
||||
// not become a horizontal line?
|
||||
if (borderTop !== borderBottom) {
|
||||
left = borderLeft
|
||||
right = borderRight
|
||||
}
|
||||
}
|
||||
|
||||
ctx.beginPath()
|
||||
ctx.fillStyle = vm.backgroundColor
|
||||
ctx.strokeStyle = vm.borderColor
|
||||
ctx.lineWidth = borderWidth
|
||||
|
||||
// Corner points, from bottom-left to bottom-right clockwise
|
||||
// | 1 2 |
|
||||
// | 0 3 |
|
||||
const corners = [
|
||||
[left, bottom],
|
||||
[left, top],
|
||||
[right, top],
|
||||
[right, bottom],
|
||||
]
|
||||
|
||||
// Find first (starting) corner with fallback to 'bottom'
|
||||
const borders = ['bottom', 'left', 'top', 'right']
|
||||
let startCorner = borders.indexOf(borderSkipped, 0)
|
||||
if (startCorner === -1) {
|
||||
startCorner = 0
|
||||
}
|
||||
|
||||
function cornerAt(index) {
|
||||
return corners[(startCorner + index) % 4]
|
||||
}
|
||||
|
||||
// Draw rectangle from 'startCorner'
|
||||
let corner = cornerAt(0)
|
||||
ctx.moveTo(corner[0], corner[1])
|
||||
|
||||
for (let i = 1; i < 4; i++) {
|
||||
corner = cornerAt(i)
|
||||
let nextCornerId = i + 1
|
||||
if (nextCornerId === 4) {
|
||||
nextCornerId = 0
|
||||
}
|
||||
|
||||
const width = corners[2][0] - corners[1][0]
|
||||
const height = corners[0][1] - corners[1][1]
|
||||
const x = corners[1][0]
|
||||
const y = corners[1][1]
|
||||
|
||||
let radius = cornerRadius
|
||||
|
||||
// Fix radius being too large
|
||||
if (radius > height / 2) {
|
||||
radius = height / 2
|
||||
}
|
||||
if (radius > width / 2) {
|
||||
radius = width / 2
|
||||
}
|
||||
|
||||
ctx.moveTo(x + radius, y)
|
||||
ctx.lineTo(x + width - radius, y)
|
||||
ctx.quadraticCurveTo(x + width, y, x + width, y + radius)
|
||||
ctx.lineTo(x + width, y + height - radius)
|
||||
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height)
|
||||
ctx.lineTo(x + radius, y + height)
|
||||
ctx.quadraticCurveTo(x, y + height, x, y + height - radius)
|
||||
ctx.lineTo(x, y + radius)
|
||||
ctx.quadraticCurveTo(x, y, x + radius, y)
|
||||
}
|
||||
|
||||
ctx.fill()
|
||||
if (borderWidth) {
|
||||
ctx.stroke()
|
||||
}
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
|
||||
import CloseButton from './CloseButton'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
describe('CloseButton', () => {
|
||||
let wrapper
|
||||
const propsData = {
|
||||
target: 'Target',
|
||||
expanded: false,
|
||||
}
|
||||
|
||||
const Wrapper = () => {
|
||||
return mount(CloseButton, { localVue, propsData })
|
||||
}
|
||||
|
||||
describe('mount', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('emmits click event', () => {
|
||||
wrapper.find('.navbar-toggler').trigger('click')
|
||||
expect(wrapper.emitted('click')).toBeTruthy()
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -1,36 +0,0 @@
|
||||
<template>
|
||||
<button
|
||||
type="button"
|
||||
class="navbar-toggler"
|
||||
data-toggle="collapse"
|
||||
@click="handleClick"
|
||||
:data-target="`#${target}`"
|
||||
:aria-controls="target"
|
||||
:aria-expanded="expanded"
|
||||
aria-label="Toggle navigation"
|
||||
>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</button>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'close-button',
|
||||
props: {
|
||||
target: {
|
||||
type: [String, Number],
|
||||
description: 'Close button target element',
|
||||
},
|
||||
expanded: {
|
||||
type: Boolean,
|
||||
description: 'Whether button is expanded (aria-expanded attribute)',
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleClick(evt) {
|
||||
this.$emit('click', evt)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
||||
@ -1,194 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
@click="tryClose"
|
||||
data-notify="container"
|
||||
class="alert alert-notify alert-dismissible"
|
||||
:class="[{ 'alert-with-icon': icon }, verticalAlign, horizontalAlign, alertType]"
|
||||
role="alert"
|
||||
:style="customPosition"
|
||||
data-notify-position="top-center"
|
||||
>
|
||||
<template v-if="icon || $slots.icon">
|
||||
<slot name="icon">
|
||||
<span class="alert-icon" data-notify="icon">
|
||||
<i :class="icon"></i>
|
||||
</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 name="dismiss-icon">
|
||||
<button type="button" class="close" 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: function (createElement) {
|
||||
return createElement(this.component)
|
||||
},
|
||||
},
|
||||
},
|
||||
props: {
|
||||
message: String,
|
||||
title: {
|
||||
type: String,
|
||||
description: 'Notification title',
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
description: 'Notification icon',
|
||||
},
|
||||
verticalAlign: {
|
||||
type: String,
|
||||
default: 'top',
|
||||
validator: (value) => {
|
||||
const acceptedValues = ['top', 'bottom']
|
||||
return acceptedValues.indexOf(value) !== -1
|
||||
},
|
||||
description: 'Vertical alignment of notification (top|bottom)',
|
||||
},
|
||||
horizontalAlign: {
|
||||
type: String,
|
||||
default: 'right',
|
||||
validator: (value) => {
|
||||
const acceptedValues = ['left', 'center', 'right']
|
||||
return acceptedValues.indexOf(value) !== -1
|
||||
},
|
||||
description: 'Horizontal alignment of notification (left|center|right)',
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'info',
|
||||
validator: (value) => {
|
||||
const acceptedValues = ['default', 'info', 'primary', 'danger', 'warning', 'success']
|
||||
return acceptedValues.indexOf(value) !== -1
|
||||
},
|
||||
description:
|
||||
'Notification type of notification (default|info|primary|danger|warning|success)',
|
||||
},
|
||||
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',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
elmHeight: 0,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hasIcon() {
|
||||
return this.icon && this.icon.length > 0
|
||||
},
|
||||
alertType() {
|
||||
return `alert-${this.type}`
|
||||
},
|
||||
customPosition() {
|
||||
const initialMargin = 20
|
||||
const 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
|
||||
}
|
||||
const pixels = (sameAlertsCount - 1) * alertHeight + initialMargin
|
||||
const 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>
|
||||
<style lang="scss">
|
||||
.notifications .alert {
|
||||
position: fixed;
|
||||
z-index: 10000;
|
||||
|
||||
&[data-notify='container'] {
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
&.center {
|
||||
margin: 0 auto;
|
||||
}
|
||||
&.left {
|
||||
left: 20px;
|
||||
}
|
||||
&.right {
|
||||
right: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,52 +0,0 @@
|
||||
<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>
|
||||
</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>
|
||||
@ -1,66 +0,0 @@
|
||||
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)
|
||||
}
|
||||
},
|
||||
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) {
|
||||
const 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)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default NotificationsPlugin
|
||||
@ -1,81 +0,0 @@
|
||||
<template>
|
||||
<vue-bootstrap-typeahead v-model="query" :data="users" @change="getUser" />
|
||||
</template>
|
||||
<script>
|
||||
import VueBootstrapTypeahead from 'vue-bootstrap-typeahead'
|
||||
|
||||
// Global registration
|
||||
// Vue.component('vue-bootstrap-typeahead', VueBootstrapTypeahead)
|
||||
|
||||
// OR
|
||||
|
||||
// Local registration
|
||||
export default {
|
||||
name: 'SearchUser',
|
||||
components: {
|
||||
VueBootstrapTypeahead,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
user: '',
|
||||
users: [
|
||||
'Bob',
|
||||
'Alice',
|
||||
'Bernd',
|
||||
'Dario',
|
||||
'Alex',
|
||||
'Pauls',
|
||||
'Ulf',
|
||||
'Delaware',
|
||||
'Florida',
|
||||
'Georgia',
|
||||
'Hawaii',
|
||||
'Idaho',
|
||||
'Illnois',
|
||||
'Indiana',
|
||||
'Iowa',
|
||||
'Kansas',
|
||||
'Kentucky',
|
||||
'Louisiana',
|
||||
'Maine',
|
||||
'Maryland',
|
||||
'Massachusetts',
|
||||
'Michigan',
|
||||
'Minnesota',
|
||||
'Mississippi',
|
||||
'Missouri',
|
||||
'Montana',
|
||||
'Nebraska',
|
||||
'Nevada',
|
||||
'New Hampshire',
|
||||
'New Jersey',
|
||||
'New Mexico',
|
||||
'New York',
|
||||
'North Carolina',
|
||||
'North Dakota',
|
||||
'Ohio',
|
||||
'Oklahoma',
|
||||
'Oregon',
|
||||
'Pennsylvania',
|
||||
'Rhode Island',
|
||||
'South Carolina',
|
||||
'South Dakota',
|
||||
'Tennessee',
|
||||
'Texas',
|
||||
'Utah',
|
||||
'Vermont',
|
||||
'Virginia',
|
||||
'Washington',
|
||||
'West Virginia',
|
||||
'Wisconsin',
|
||||
'Wyoming',
|
||||
],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getUser() {
|
||||
alert(this.data.user)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@ -10,12 +10,10 @@ const SidebarStore = {
|
||||
},
|
||||
toggleMinimize() {
|
||||
document.body.classList.toggle('sidebar-mini')
|
||||
// we simulate the window Resize so the charts will get updated in realtime.
|
||||
const simulateWindowResize = setInterval(() => {
|
||||
window.dispatchEvent(new Event('resize'))
|
||||
}, 180)
|
||||
|
||||
// we stop the simulation of Window Resize after the animations are completed
|
||||
setTimeout(() => {
|
||||
clearInterval(simulateWindowResize)
|
||||
}, 1000)
|
||||
|
||||
@ -106,7 +106,6 @@
|
||||
},
|
||||
"profil": {
|
||||
"activity": {
|
||||
"chart":"Gemeinschaftsstunden Chart",
|
||||
"new":"Neue Gemeinschaftsstunden eintragen",
|
||||
"list":"Meine Gemeinschaftsstunden Liste"
|
||||
}
|
||||
|
||||
@ -107,7 +107,6 @@
|
||||
"profil": {
|
||||
"transactions":"transactions",
|
||||
"activity": {
|
||||
"chart":"Community Hours Chart",
|
||||
"new":"Register new community hours",
|
||||
"list":"My Community Hours List"
|
||||
}
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
// Polyfills for js features used in the Dashboard but not supported in some browsers (mainly IE)
|
||||
import '@/polyfills'
|
||||
// Notifications plugin. Used on Notifications page
|
||||
import Notifications from '@/components/NotificationPlugin'
|
||||
// Validation plugin used to validate forms
|
||||
import { configure, extend, localize } from 'vee-validate'
|
||||
// A plugin file where you could register global components used across the app
|
||||
@ -48,7 +46,6 @@ export default {
|
||||
Vue.use(GlobalComponents)
|
||||
Vue.use(GlobalDirectives)
|
||||
Vue.use(SideBar)
|
||||
Vue.use(Notifications)
|
||||
Vue.use(BootstrapVue)
|
||||
Vue.use(IconsPlugin)
|
||||
Vue.use(VueGoodTablePlugin)
|
||||
|
||||
@ -6,7 +6,6 @@ import * as rules from 'vee-validate/dist/rules'
|
||||
|
||||
import { messages } from 'vee-validate/dist/locale/en.json'
|
||||
import RegeneratorRuntime from 'regenerator-runtime'
|
||||
import Notifications from '@/components/NotificationPlugin'
|
||||
import SideBar from '@/components/SidebarPlugin'
|
||||
import VueRouter from 'vue-router'
|
||||
import VueQrcode from 'vue-qrcode'
|
||||
@ -29,7 +28,6 @@ global.localVue.use(BootstrapVue)
|
||||
global.localVue.use(Vuex)
|
||||
global.localVue.use(IconsPlugin)
|
||||
global.localVue.use(RegeneratorRuntime)
|
||||
global.localVue.use(Notifications)
|
||||
global.localVue.use(SideBar)
|
||||
global.localVue.use(VueRouter)
|
||||
global.localVue.use(VueQrcode)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user