-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Simple pagination for DataTable (#98)
* Load more button and event for tables * Rework loading and add async button
- Loading branch information
Showing
8 changed files
with
234 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
<template> | ||
<button type="button" v-show="fn" :title="title" :disabled="disabled" class="async-button" :class="{awesome: fa}" @click="update"> | ||
<span class="button-content"> | ||
<span v-if="loading" class="icon loading"> | ||
<i v-if="fa" :class="loadingClasses"></i> | ||
<LoadingIcon rotate v-else /> | ||
</span> | ||
<span v-else-if="asyncState === true" class="icon success"> | ||
<i v-if="fa" class="fas fa-check"></i> | ||
<span v-else>✔️</span> | ||
</span> | ||
<span v-else-if="asyncState === false" class="icon error"> | ||
<i v-if="fa" class="fas fa-times"></i> | ||
<span v-else>❌</span> | ||
</span> | ||
<span v-else class="icon default"> | ||
<i v-if="fa" :class="icon"></i> | ||
<span v-else-if="icon">{{ icon }}</span> | ||
<LoadingIcon v-else /> | ||
</span> | ||
<span class="text"><slot></slot></span> | ||
</span> | ||
</button> | ||
</template> | ||
|
||
<script> | ||
import LoadingIcon from './LoadingIcon.vue'; | ||
export default { | ||
components: { LoadingIcon }, | ||
name: "AsyncButton", | ||
props: { | ||
fn: { | ||
// Asynchronous function to execute when the button is clicked | ||
type: Function, | ||
required: true | ||
}, | ||
fa: { | ||
// Whether to use Font Awesome icons or not | ||
type: Boolean, | ||
default: false | ||
}, | ||
confirm: { | ||
// Show a confirmation checkmark once the async action has succeeded | ||
type: Boolean, | ||
default: false | ||
}, | ||
icon: { | ||
// fa=true: The Font Awesome icon class | ||
// fa=false: A unicode symbol | ||
type: String, | ||
default: '' | ||
}, | ||
title: { | ||
// Tooltip text | ||
type: String, | ||
default: null | ||
}, | ||
disabled: { | ||
// Disable the button | ||
type: Boolean, | ||
default: false | ||
}, | ||
consistent: { | ||
// Whether the button should show the same icon for the loading animation | ||
type: Boolean, | ||
default: false | ||
} | ||
}, | ||
data() { | ||
return { | ||
loading: false, | ||
asyncState: null | ||
}; | ||
}, | ||
computed: { | ||
loadingClasses() { | ||
let classes = this.consistent ? this.icon.split(' ') : ['fas', 'fa-spinner']; | ||
classes.push('fa-spin'); | ||
return classes; | ||
} | ||
}, | ||
methods: { | ||
async update(event) { | ||
if (this.asyncState !== null || this.disabled) { | ||
return; | ||
} | ||
try { | ||
this.$emit('before', event); | ||
this.loading = true; | ||
this.asyncState = await this.fn(event); | ||
if (!this.confirm) { | ||
this.asyncState = null | ||
} | ||
else if (typeof this.asyncState !== 'boolean') { | ||
this.asyncState = true; | ||
} | ||
} catch(e) { | ||
this.asyncState = false; | ||
} finally { | ||
this.loading = false; | ||
this.$emit('after', this.asyncState); | ||
if (this.confirm) { | ||
setTimeout(() => this.asyncState = null, 3000); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
</script> | ||
|
||
<style scoped lang="scss"> | ||
.async-button { | ||
min-width: 2em; | ||
&:not(.awesome) { | ||
.icon, .icon > svg, .icon > span { | ||
display: inline-block; | ||
width: 1em; | ||
height: 1em; | ||
font-size: 1em; | ||
line-height: 1em; | ||
} | ||
.button-content { | ||
display: flex; | ||
align-items: center; | ||
} | ||
} | ||
.success { | ||
color: green; | ||
} | ||
.error { | ||
color: maroon; | ||
} | ||
.text { | ||
display: inline-block; | ||
margin-left: 0.5em; | ||
} | ||
.text:empty { | ||
display: none; | ||
} | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,13 @@ | ||
<template> | ||
<div class="vue-component loading-notice"> | ||
<span class="loading">Loading</span> | ||
<span class="loading"><LoadingIcon rotate /> Loading...</span> | ||
</div> | ||
</template> | ||
|
||
<script> | ||
import LoadingIcon from './LoadingIcon.vue' | ||
export default { | ||
components: { LoadingIcon }, | ||
name: 'Loading' | ||
} | ||
</script> | ||
|
||
<style lang="scss"> | ||
.vue-component.loading-notice { | ||
.loading:after { | ||
content: '.'; | ||
animation: dots 1.25s steps(5, end) infinite; | ||
font-size: 1.5em; | ||
line-height: 1em; | ||
font-weight: bold; | ||
} | ||
} | ||
@keyframes dots { | ||
0%, 20% { | ||
color: rgba(0,0,0,0); | ||
text-shadow: | ||
.25em 0 0 rgba(0,0,0,0), | ||
.5em 0 0 rgba(0,0,0,0); | ||
} | ||
40% { | ||
color: black; | ||
text-shadow: | ||
.25em 0 0 rgba(0,0,0,0), | ||
.5em 0 0 rgba(0,0,0,0); | ||
} | ||
60% { | ||
text-shadow: | ||
.25em 0 0 black, | ||
.5em 0 0 rgba(0,0,0,0); | ||
} | ||
80%, 100% { | ||
text-shadow: | ||
.25em 0 0 black, | ||
.5em 0 0 black; | ||
} | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<template> | ||
<svg class="loading-icon" :class="{rotate}" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" version="1.1" x="0px" y="0px" viewBox="0 0 100 100" width="400px" height="400px"> | ||
<path d="M78.271,21.729C71.028,14.486,61.028,10,50,10C27.944,10,10,27.944,10,50S27.944,90,50,90S90,72.056,90,50L80,50C80,66.542,66.542,80,50,80S20,66.542,20,50S33.458,20,50,20C58.271,20,65.771,23.365,71.203,28.797L60,40L90,40L90,10L78.271,21.729Z" stroke="none"></path> | ||
</svg> | ||
</template> | ||
|
||
<script> | ||
export default { | ||
name: "LoadingIcon", | ||
props: { | ||
rotate: { | ||
type: Boolean, | ||
default: false | ||
} | ||
} | ||
} | ||
</script> | ||
|
||
<style lang="scss" scoped> | ||
.loading-icon { | ||
display: inline-block; | ||
width: 1em; | ||
height: 1em; | ||
font-size: 1em; | ||
line-height: 1em; | ||
&.rotate { | ||
animation: loading-icon-rotate 1s infinite linear; | ||
} | ||
} | ||
@keyframes loading-icon-rotate { | ||
from { | ||
transform: rotate(0deg); | ||
} | ||
to { | ||
transform: rotate(359deg); | ||
} | ||
} | ||
</style> |
Oops, something went wrong.