Skip to content
Permalink
Browse files

updated wing notifications to use bootstrap toasts

  • Loading branch information...
rizen committed May 10, 2019
1 parent 71d605d commit e72a77fc536d4da461f7a5203e7f7cae8aed2961
@@ -4,6 +4,11 @@ This file tracks the changes to Wing over time. Especially
with respect to new features and compatibility changes.
==========================================================

2019-05-10
* Wing notifications (wing.info, wing.success, etc) have been upgraded to use Bootstrap Toasts. See WingVue.pod for usage notes.
* You must upgrade to bootstrap-vue@2.0.0-rc.19 and bootstrap@4.3.1.
* You can remove noty from wing_ui_css_requirements.tt and wing_ui_js_requirements.tt.

2019-05-08
* Fixed bug with nulls in wing.vue.js.

@@ -987,9 +987,51 @@ The name of the field you want to use as the text label for the option. Often th

=head1 Notifications

Wing gives you an easy way to notify users.
Wing gives you an easy way to notify users. The message can take one of the following formats:

=head2 wing.error(message)
=over

=item String

wing.success('Item added to cart.');

=item Vue Virtual DOM

L<https://vuejs.org/v2/guide/render-function.html#The-Virtual-DOM>

wing.success(
h('div', {}, [
'Item added to cart.',
h('a', { attrs : {href : '/cart'}, class : 'btn btn-primary'}, 'View Cart')
])
);

=back

=item Array of objects

Just a straight Javascript data structure that will be turned into a Vue Virtual DOM.

wing.success([
'div', {}, [
'Item added to cart. ',
['a', {attrs : {href : '/cart'}, class : 'btn btn-primary'}, 'View Cart']
]
]);

=item JSON string

A JSON string that will be turned into a Vue Virtual DOM. Use this when you want to do some fancy formatting, but need to pass a string message around, like through Firebase notifications.

wing.success(`[
"div", {}, [
"Item added to cart. ",
["a", {"attrs" : {"href" : "/cart"}, "class" : "btn btn-primary"}, "View Cart"]
]
]`);


=head2 wing.error(message, options)

A red box in the center of the screen to let the user know something bad has happened.

@@ -999,9 +1041,29 @@ A red box in the center of the screen to let the user know something bad has hap

The message you want to be diplayed.

=item options

An optional object with the following optional parameters:

=over

=item ttl

In milliseconds, how long should the message remain on screen. Default 15000.

=item href

If specified, the message will be linked to this URL.

=item title

Optionally override the title of the message. Defaults to C<Error>.

=back

=head2 wing.info(message)
=back

=head2 wing.info(message, options)

A blue box in the lower left corner of the screen to let the user know something they should be aware of, like an ongoing process.

@@ -1011,9 +1073,29 @@ A blue box in the lower left corner of the screen to let the user know something

The message you want to be diplayed.

=item options

An optional object with the following optional parameters:

=over

=item ttl

In milliseconds, how long should the message remain on screen. Default 8000.

=item href

If specified, the message will be linked to this URL.

=item title

Optionally override the title of the message. Defaults to C<Info>.

=back

=head2 wing.success(message)
=back

=head2 wing.success(message, options)

A green box in the lower left corner of the screen to let the user know something they did worked.

@@ -1023,9 +1105,29 @@ A green box in the lower left corner of the screen to let the user know somethin

The message you want to be diplayed.

=item options

An optional object with the following optional parameters:

=over

=item ttl

In milliseconds, how long should the message remain on screen. Default 8000.

=item href

If specified, the message will be linked to this URL.

=item title

Optionally override the title of the message. Defaults to C<Success>.

=back

=back

=head2 wing.warn(message)
=head2 wing.warn(message, options)

A blue box in the lower left corner of the screen to let the user know something that may be of concern, but isn't an error.

@@ -1035,6 +1137,26 @@ A blue box in the lower left corner of the screen to let the user know something

The message you want to be diplayed.

=item options

An optional object with the following optional parameters:

=over

=item ttl

In milliseconds, how long should the message remain on screen. Default 8000.

=item href

If specified, the message will be linked to this URL.

=item title

Optionally override the title of the message. Defaults to C<Warning>.

=back

=back

=head1 Utilities
@@ -962,26 +962,50 @@ const wing = {
toast : new Vue({
el : '#wingtoast',
methods : {
success : function (message, options) {
format_options (options) {
if (typeof(options) != 'object') {
options = {};
}
return options;
},
build_dom(message) {
const self = this;
const h = this.$createElement;
if (Array.isArray(message[2])) {
for (const i in message[2]) {
message[2][i] = Array.isArray(message[2][i]) ? self.build_dom(message[2][i]) : message[2][i];
}
}
return h(message[0], message[1], message[2]);
},
format_message (message) {
if (Array.isArray(message)) { // an array of objects to make into a tree
return this.build_dom(message);
}
else if (typeof(message) == 'string' && message.charAt(0) == '[') { // looks like json
return this.build_dom(JSON.parse(message));
}
else { // just a string
return message;
}
},
success (message, options) {
options = this.format_options(options);
this.$bvToast.toast(
message,
this.format_message(message),
{
autoHideDelay : options.ttl || 80000000,
autoHideDelay : options.ttl || 8000,
variant : 'success',
toaster: 'b-toaster-bottom-left',
title : options.title || 'Success',
href : options.href,
}
);
},
error : function (message) {
if (typeof(options) != 'object') {
options = {};
}
error (message, options) {
options = this.format_options(options);
this.$bvToast.toast(
message,
this.format_message(message),
{
autoHideDelay : options.ttl || 15000,
variant : 'danger',
@@ -990,12 +1014,10 @@ const wing = {
}
);
},
warn : function (message) {
if (typeof(options) != 'object') {
options = {};
}
warn (message, options) {
options = this.format_options(options);
this.$bvToast.toast(
message,
this.format_message(message),
{
autoHideDelay : options.ttl || 8000,
variant : 'warning',
@@ -1004,12 +1026,10 @@ const wing = {
}
);
},
info : function (message) {
if (typeof(options) != 'object') {
options = {};
}
info (message, options) {
options = this.format_options(options);
this.$bvToast.toast(
message,
this.format_message(message),
{
autoHideDelay : options.ttl || 8000,
variant : 'info',
@@ -1025,31 +1045,31 @@ const wing = {
* display an error message
*/

error : (message) => {
error : (message, options) => {
wing.toast.error(message);
},

/*
* display a success message
*/

success : (message) => {
wing.toast.success(message);
success : (message, options) => {
wing.toast.success(message, options);
},

/*
* display a warning
*/

warn : (message) => {
warn : (message, options) => {
wing.toast.warn(message);
},

/*
* display some info
*/

info : (message) => {
info : (message, options) => {
wing.toast.info(message);
},

@@ -41,13 +41,6 @@
</table>
</div>

<button class="btn btn-success" @click="success()">Success</button>
<button class="btn btn-warning" @click="wing.warn('test')">warn</button>
<button class="btn btn-info" @click="wing.info('test')">info</button>
<button class="btn btn-danger" @click="wing.error('test')">error</button>



<br>
<a href="/admin/trends/reports/manage" class="btn btn-primary">Manage Reports</a>
</div>
@@ -99,20 +92,6 @@ new Vue({
}});
},
methods : {
success() {
wing.success('Item added to cart. <a href="/cart" class="btn btn-primary">View Cart</a>');

const h = this.$createElement;

wing.success('Some message.', { href : 'http://www.google.com' });

wing.success(
h('div', {}, [
'Item added to cart.',
h('a', { attrs : {href : '/cart'}, class : 'btn btn-primary'}, 'View Cart')
])
);
},
fetch_report_data : _.debounce(function() { // some browsers fire events before updating the model, this gets around that
const self = this;
axios.get('/api/trends/'+self.filters.granularity+'/'+self.filters.report_id, { params: { start : self.filters.start, range : self.filters.range }})
@@ -1,5 +1,3 @@
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap@4.3.1/dist/css/bootstrap.min.css">
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue@2.0.0-rc.19/dist/bootstrap-vue.min.css">
<link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/noty@3.2.0-beta/lib/noty.css">
<link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/noty@3.2.0-beta/lib/themes/bootstrap-v4.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/all.css" integrity="sha384-3AB7yXWz4OeoZcPbieVW64vVXEwADiYyAEhwilzWsLw+9FgqpyjjStpPnpBO8o8S" crossorigin="anonymous">
@@ -2,7 +2,6 @@
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue@2.0.0-rc.19/dist/bootstrap-vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue2-filters@0.3.0/dist/vue2-filters.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/noty@3.2.0-beta/lib/noty.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.5/lodash.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/qs@6.5.2/dist/qs.js"></script>
<script src="https://unpkg.com/axios@0.18.0/dist/axios.min.js"></script>

0 comments on commit e72a77f

Please sign in to comment.
You can’t perform that action at this time.