Feat: add clear all button, stripe overlay on invalid notification

Fix: rework notification styles
This commit is contained in:
Cesar 2020-12-28 20:45:45 +00:00 committed by Josh Harvey
parent 7459700986
commit 55dc3aab94
4 changed files with 44 additions and 67 deletions

View file

@ -15,70 +15,29 @@ error - notifications related to errors
*/ */
const addNotification = (type, message, detail) => { const addNotification = (type, message, detail) => {
const sql = `INSERT INTO notifications (id, type, message, detail) VALUES ($1, $2, $3, $4)` const sql = `INSERT INTO notifications (id, type, message, detail) values ($1, $2, $3, $4)`
return db.oneOrNone(sql, [uuidv4(), type, message, detail]) return db.oneOrNone(sql, [uuidv4(), type, message, detail])
} }
const getAllValidNotifications = (type) => { const getAllValidNotifications = (type) => {
const sql = `SELECT * FROM notifications WHERE type = $1 AND valid = 't'` const sql = `SELECT * FROM notifications WHERE type = $1 AND valid = 't'`
return db.any(sql, [type]) return db.any(sql, [type])
} }
const invalidateNotification = (detail, type) => { const invalidateNotification = (detail, type) => {
detail = _.omitBy(_.isEmpty, detail) detail = _.omitBy(_.isEmpty, detail)
const sql = `UPDATE notifications SET valid = 'f', read = 't', modified = CURRENT_TIMESTAMP WHERE valid = 't' AND type = $1 AND detail::jsonb @> $2::jsonb` const sql = `UPDATE notifications SET valid = 'f', read = 't' WHERE valid = 't' AND type = $1 AND detail::jsonb @> $2::jsonb`
return db.none(sql, [type, detail]) return db.none(sql, [type, detail])
}
const batchInvalidate = (ids) => {
const formattedIds = _.map(pgp.as.text, ids).join(',')
const sql = `UPDATE notifications SET valid = 'f', read = 't', modified = CURRENT_TIMESTAMP WHERE id IN ($1^)`
return db.none(sql, [formattedIds])
}
const clearBlacklistNotification = (cryptoCode, cryptoAddress) => {
const sql = `UPDATE notifications SET valid = 'f', read = 't', modified = CURRENT_TIMESTAMP WHERE type = 'compliance' AND detail->>'cryptoCode' = $1 AND detail->>'cryptoAddress' = $2 AND (detail->>'code' = 'BLOCKED' OR detail->>'code' = 'REUSED')`
return db.none(sql, [cryptoCode, cryptoAddress])
}
const getValidNotifications = (type, detail) => {
const sql = `SELECT * FROM notifications WHERE type = $1 AND valid = 't' AND detail @> $2`
return db.any(sql, [type, detail])
}
const getNotifications = () => {
const sql = `SELECT * FROM notifications ORDER BY created DESC`
return db.any(sql)
}
const markAsRead = (id) => {
const sql = `UPDATE notifications SET read = 't', modified = CURRENT_TIMESTAMP WHERE id = $1`
return db.none(sql, [id])
}
const markAllAsRead = () => {
const sql = `UPDATE notifications SET read = 't'`
return db.none(sql)
}
const hasUnreadNotifications = () => {
const sql = `SELECT EXISTS (SELECT 1 FROM notifications WHERE read = 'f' LIMIT 1)`
return db.oneOrNone(sql).then(res => res.exists)
}
const addComplianceNotification = (deviceId, detail, message) => {
const sql = `INSERT INTO notifications (id, type, detail, device_id, message, created) values ($1, 'compliance', $2, $3, $4, CURRENT_TIMESTAMP)`
return db.oneOrNone(sql, [uuidv4(), detail, deviceId, message])
} }
const batchInvalidate = (ids) => { const batchInvalidate = (ids) => {
const formattedIds = _.map(pgp.as.text, ids).join(',') const formattedIds = _.map(pgp.as.text, ids).join(',')
const sql = `UPDATE notifications SET valid = 'f', read = 't', modified = CURRENT_TIMESTAMP WHERE id IN ($1^)` const sql = `UPDATE notifications SET valid = 'f', read = 't' WHERE id IN ($1^)`
return db.none(sql, [formattedIds]) return db.none(sql, [formattedIds])
} }
const clearBlacklistNotification = (cryptoCode, cryptoAddress) => { const clearBlacklistNotification = (cryptoCode, cryptoAddress) => {
const sql = `UPDATE notifications SET valid = 'f', read = 't', modified = CURRENT_TIMESTAMP WHERE type = 'compliance' AND detail->>'cryptoCode' = $1 AND detail->>'cryptoAddress' = $2 AND (detail->>'code' = 'BLOCKED' OR detail->>'code' = 'REUSED')` const sql = `UPDATE notifications SET valid = 'f', read = 't' WHERE type = 'compliance' AND detail->>'cryptoCode' = $1 AND detail->>'cryptoAddress' = $2 AND (detail->>'code' = 'BLOCKED' OR detail->>'code' = 'REUSED')`
return db.none(sql, [cryptoCode, cryptoAddress]) return db.none(sql, [cryptoCode, cryptoAddress])
} }
@ -88,27 +47,42 @@ const getValidNotifications = (type, detail) => {
} }
const getNotificationsGql = () => { const getNotificationsGql = () => {
const sql = `(SELECT * from notifications WHERE read = 'f' AND valid = 't' ORDER BY created DESC) const sql = `SELECT * FROM notifications ORDER BY created DESC`
UNION ALL (SELECT * from notifications WHERE read = 't' OR valid = 'f' ORDER BY modified DESC LIMIT 50)
`
return db.any(sql) return db.any(sql)
} }
const markAsReadGql = (id) => { const markAsReadGql = (id) => {
const sql = `UPDATE notifications SET read = 't', modified = CURRENT_TIMESTAMP WHERE id = $1` const sql = `UPDATE notifications SET read = 't' WHERE id = $1`
return db.none(sql, [id]) return db.none(sql, [id])
} }
module.exports = { const markAllAsReadGql = () => {
machineEvents: dbm.machineEvents, const sql = `UPDATE notifications SET read = 't'`
addNotification, return db.none(sql)
getAllValidNotifications, }
invalidateNotification,
batchInvalidate, const hasUnreadNotificationsGql = () => {
clearBlacklistNotification, const sql = `SELECT EXISTS (SELECT 1 FROM notifications WHERE read = 'f' LIMIT 1)`
getValidNotifications, return db.oneOrNone(sql).then(res => res.exists)
getNotifications, }
markAsRead,
markAllAsRead, const getAlertsGql = () => {
hasUnreadNotifications const types = ['fiatBalance', 'cryptoBalance', 'error']
const sql = `SELECT * FROM notifications WHERE valid = 't' AND type IN ($1:list) ORDER BY created DESC`
return db.any(sql, [types])
}
module.exports = {
machineEvents: dbm.machineEvents,
addNotification,
getAllValidNotifications,
invalidateNotification,
batchInvalidate,
clearBlacklistNotification,
getValidNotifications,
getNotificationsGql,
markAsReadGql,
markAllAsReadGql,
hasUnreadNotificationsGql,
getAlertsGql
} }

View file

@ -27,6 +27,7 @@
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root" class="root"></div> <div id="root" class="root"></div>
<div id="modal-root"></div>
<!-- <!--
This HTML file is a template. This HTML file is a template.
If you open it directly in the browser, you will see an empty page. If you open it directly in the browser, you will see an empty page.

View file

@ -16,7 +16,7 @@ const styles = {
top: 0, top: 0,
zIndex: -1, zIndex: -1,
backgroundColor: white, backgroundColor: white,
boxShadow: '0 0 14px 0 rgba(0, 0, 0, 0.24)' height: '100vh'
}, },
container: { container: {
left: -200, left: -200,
@ -53,6 +53,7 @@ const styles = {
backgroundColor: zircon backgroundColor: zircon
}, },
notificationsList: { notificationsList: {
zIndex: 10,
width: 440, width: 440,
height: '90vh', height: '90vh',
maxHeight: '100vh', maxHeight: '100vh',

View file

@ -13,6 +13,7 @@ import AddMachine from 'src/pages/AddMachine'
import { ReactComponent as AddIconReverse } from 'src/styling/icons/button/add/white.svg' import { ReactComponent as AddIconReverse } from 'src/styling/icons/button/add/white.svg'
import { ReactComponent as AddIcon } from 'src/styling/icons/button/add/zodiac.svg' import { ReactComponent as AddIcon } from 'src/styling/icons/button/add/zodiac.svg'
import { ReactComponent as Logo } from 'src/styling/icons/menu/logo.svg' import { ReactComponent as Logo } from 'src/styling/icons/menu/logo.svg'
import { ReactComponent as NotificationIconZodiac } from 'src/styling/icons/menu/notification-zodiac.svg'
import { ReactComponent as NotificationIcon } from 'src/styling/icons/menu/notification.svg' import { ReactComponent as NotificationIcon } from 'src/styling/icons/menu/notification.svg'
import styles from './Header.styles' import styles from './Header.styles'