Bladeren bron

Added alerts functionality + modal UI

NGPixel 8 jaren geleden
bovenliggende
commit
52c9821189

File diff suppressed because it is too large
+ 0 - 0
assets/css/app.css


+ 1 - 1
assets/js/app.js

@@ -1 +1 @@
-"use strict";jQuery(document).ready(function(e){e("a").smoothScroll({speed:400,offset:-20});new Sticky(".stickyscroll")});
+"use strict";function _classCallCheck(e,s){if(!(e instanceof s))throw new TypeError("Cannot call a class as a function")}var _createClass=function(){function e(e,s){for(var t=0;t<s.length;t++){var n=s[t];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(s,t,n){return t&&e(s.prototype,t),n&&e(s,n),s}}(),Alerts=function(){function e(){_classCallCheck(this,e);var s=this;s.mdl=new Vue({el:"#alerts",data:{children:[]},methods:{acknowledge:function(e){s.close(e)}}}),s.uidNext=1}return _createClass(e,[{key:"push",value:function(e){var s=this,t=_.defaults(e,{_uid:s.uidNext,class:"is-info",message:"---",sticky:!1,title:"---"});s.mdl.children.push(t),t.sticky||_.delay(function(){s.close(t._uid)},5e3),s.uidNext++}},{key:"pushError",value:function(e,s){this.push({class:"is-danger",message:s,sticky:!1,title:e})}},{key:"pushSuccess",value:function(e,s){this.push({class:"is-success",message:s,sticky:!1,title:e})}},{key:"close",value:function(e){var s=this,t=_.findIndex(s.mdl.children,["_uid",e]),n=_.nth(s.mdl.children,t);t>=0&&n&&(n.class+=" exit",s.mdl.children.$set(t,n),_.delay(function(){s.mdl.children.$remove(n)},500))}}]),e}();jQuery(document).ready(function(e){e("a").smoothScroll({speed:400,offset:-20});var s=(new Sticky(".stickyscroll"),new Alerts);alertsData&&_.forEach(alertsData,function(e){s.push(e)})});

+ 7 - 0
client/js/app.js

@@ -9,4 +9,11 @@ jQuery( document ).ready(function( $ ) {
 
 	var sticky = new Sticky('.stickyscroll');
 
+	var alerts = new Alerts();
+	if(alertsData) {
+		_.forEach(alertsData, (alertRow) => {
+			alerts.push(alertRow);
+		});
+	}
+
 });

+ 115 - 0
client/js/components/alerts.js

@@ -0,0 +1,115 @@
+"use strict";
+
+/**
+ * Alerts
+ */
+class Alerts {
+
+	/**
+	 * Constructor
+	 *
+	 * @class
+	 */
+	constructor() {
+
+		let self = this;
+
+		self.mdl = new Vue({
+			el: '#alerts',
+			data: {
+				children: []
+			},
+			methods: {
+				acknowledge: (uid) => {
+					self.close(uid);
+				}
+			}
+		});
+
+		self.uidNext = 1;
+
+	}
+
+	/**
+	 * Show a new Alert
+	 *
+	 * @param      {Object}  options  Alert properties
+	 * @return     {null}  Void
+	 */
+	push(options) {
+
+		let self = this;
+
+		let nAlert = _.defaults(options, {
+			_uid: self.uidNext,
+			class: 'is-info',
+			message: '---',
+			sticky: false,
+			title: '---'
+		});
+
+		self.mdl.children.push(nAlert);
+
+		if(!nAlert.sticky) {
+			_.delay(() => {
+				self.close(nAlert._uid);
+			}, 5000);
+		}
+
+		self.uidNext++;
+
+	}
+
+	/**
+	 * Shorthand method for pushing errors
+	 *
+	 * @param      {String}  title    The title
+	 * @param      {String}  message  The message
+	 */
+	pushError(title, message) {
+		this.push({
+			class: 'is-danger',
+			message,
+			sticky: false,
+			title
+		});
+	}
+
+	/**
+	 * Shorthand method for pushing success messages
+	 *
+	 * @param      {String}  title    The title
+	 * @param      {String}  message  The message
+	 */
+	pushSuccess(title, message) {
+		this.push({
+			class: 'is-success',
+			message,
+			sticky: false,
+			title
+		});
+	}
+
+	/**
+	 * Close an alert
+	 *
+	 * @param      {Integer}  uid     The unique ID of the alert
+	 */
+	close(uid) {
+
+		let self = this;
+
+		let nAlertIdx = _.findIndex(self.mdl.children, ['_uid', uid]);
+		let nAlert = _.nth(self.mdl.children, nAlertIdx);
+
+		if(nAlertIdx >= 0 && nAlert) {
+			nAlert.class += ' exit';
+			self.mdl.children.$set(nAlertIdx, nAlert);
+			_.delay(() => {
+				self.mdl.children.$remove(nAlert);
+			}, 500);
+		}
+
+	}
+
+}

+ 3 - 0
client/scss/app.scss

@@ -5,6 +5,9 @@ $warning: #f68b39;
 
 @import 'bulma';
 @import './libs/twemoji-awesome';
+@import './libs/animate.min.css';
+
+@import './components/_alerts';
 
 @import './layout/_header';
 @import './layout/_footer';

+ 24 - 0
client/scss/components/_alerts.scss

@@ -0,0 +1,24 @@
+#alerts {
+	position: fixed;
+	top: 60px;
+	right: 10px;
+	width: 350px;
+	z-index: 2;
+	text-shadow: 1px 1px 0 rgba(0,0,0,0.1);
+
+	.notification {
+		animation: 0.5s ease slideInRight;
+		margin-top: 5px;
+
+		&.exit {
+			animation: 0.5s ease fadeOutRight;
+		}
+
+	}
+
+	h3 {
+		font-size: 16px;
+		font-size: 500;
+	}
+
+}

+ 14 - 0
client/scss/layout/_content.scss

@@ -71,6 +71,16 @@ p code {
 	border-radius: 4px;
 }
 
+.modal {
+	align-items: flex-start;
+}
+.modal-background {
+	animation: 0.4s ease fadeIn;
+}
+.modal-content {
+	animation: 0.4s ease slideInDown;	
+}
+
 .card-header {
 	background-color: $turquoise;
 }
@@ -80,4 +90,8 @@ p code {
 	font-weight: 400;
 	font-size: 16px;
 	padding: 10px 20px;
+}
+
+.modal-content .card-footer-item {
+	font-weight: 500;
 }

File diff suppressed because it is too large
+ 10 - 0
client/scss/libs/animate.min.css


+ 1 - 1
controllers/pages.js

@@ -15,7 +15,7 @@ router.get('/', (req, res) => {
 		let pageData = mark.parse(contents);
 		if(!pageData.title) {
 			pageData.title = 'Redis';
-			pageData.subtitle = 'An open source, in-memory data structure store, used as database, cache and message broker.'
+			pageData.subtitle = 'An open source, in-memory data structure store, used as database, cache and message broker.';
 		}
 		res.render('pages/view', { pageData });
  	});

+ 1 - 1
gulpfile.js

@@ -103,7 +103,7 @@ gulp.task("scripts-app", function () {
 	.pipe(babel())
 	.pipe(uglify())
 	.pipe(plumber.stop())
-	.pipe(gulp.dest("./assets/js"))
+	.pipe(gulp.dest("./assets/js"));
 
 });
 

+ 9 - 7
models/markdown.js

@@ -21,11 +21,13 @@ var mkdown = md({
 		html: true,
 		linkify: true,
 		typography: true,
-		highlight: function (str, lang) {
+		highlight(str, lang) {
 			if (lang && hljs.getLanguage(lang)) {
 				try {
 					return '<pre class="hljs"><code>' + hljs.highlight(lang, str, true).value + '</code></pre>';
-				} catch (__) {}
+				} catch (err) {
+					return '<pre><code>' + str + '</code></pre>';
+				}
 			}
 			return '<pre class="hljs"><code>' + hljs.highlightAuto(str).value + '</code></pre>';
 		}
@@ -72,17 +74,17 @@ const parseTree = (content) => {
 
 	for (let i = 0; i < tokens.length; i++) {
 		if (tokens[i].type !== "heading_close") {
-		  continue
+		  continue;
 		}
 
-		const heading = tokens[i - 1]
-		const heading_close = tokens[i]
+		const heading = tokens[i - 1];
+		const heading_close = tokens[i];
 
 		if (heading.type === "inline") {
 		  let content = "";
 		  let anchor = "";
 		  if (heading.children && heading.children[0].type === "link_open") {
-			 content = heading.children[1].content
+			 content = heading.children[1].content;
 			 anchor = slug(content, {lower: true});
 		  } else {
 			 content = heading.content
@@ -93,7 +95,7 @@ const parseTree = (content) => {
 			 content,
 			 anchor,
 			 level: +heading_close.tag.substr(1, 1)
-		  })
+		  });
 		}
 	 }
 

+ 3 - 3
package.json

@@ -35,14 +35,14 @@
     "bluebird": "^3.4.1",
     "body-parser": "^1.15.2",
     "bulma": "^0.1.2",
-    "cheerio": "^0.20.0",
+    "cheerio": "^0.22.0",
     "compression": "^1.6.2",
     "connect-flash": "^0.1.1",
-    "connect-loki": "^1.0.5",
+    "connect-loki": "^1.0.6",
     "connect-redis": "^3.1.0",
     "cookie-parser": "^1.4.3",
     "express": "^4.14.0",
-    "express-brute": "^0.7.0-beta.0",
+    "express-brute": "^1.0.0",
     "express-session": "^1.14.0",
     "express-validator": "^2.20.8",
     "highlight.js": "^9.6.0",

+ 16 - 0
views/common/alerts.pug

@@ -0,0 +1,16 @@
+#alerts
+	ul
+		template(v-for="aItem in children", track-by='_uid')
+			.notification(v-bind:class='aItem.class')
+				button.delete(v-on:click='acknowledge(aItem._uid)')
+				h3 {{ aItem.title }}
+				span {{ aItem.message }}
+
+if appflash.length > 0
+	script(type='text/javascript')
+		| var alertsData = 
+		!= JSON.stringify(appflash)
+		| ;
+else
+	script(type='text/javascript')
+		| var alertsData = [];

Some files were not shown because too many files changed in this diff