Skip to content

Commit

Permalink
TECH - custom server, locales, new module
Browse files Browse the repository at this point in the history
  • Loading branch information
TomaszPilch committed Dec 6, 2020
1 parent 75ef03f commit d0578b2
Show file tree
Hide file tree
Showing 11 changed files with 403 additions and 122 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ COPYRIGHT
CLIENT_SECRET
CLIENT_ID
NODE_ENV
LOCALE_PASS
```

## Created from BHE be v1
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@
"test:watch": "jest --watch"
},
"dependencies": {
"@bheui/components": "^1.0.0-alpha7",
"@bheui/components": "^1.0.0-alpha9",
"@bheui/server-functions": "^0.1.2",
"@fluentui/react": "^7.153.3",
"@uifabric/experiments": "^7.36.19",
"@uifabric/fluent-theme": "^7.3.47",
"@uifabric/icons": "^7.5.17",
"axios": "^0.21.0",
"body-parser": "^1.19.0",
"compression": "^1.7.4",
"express": "^4.17.1",
"i18next-intervalplural-postprocessor": "^2.0.2",
"next": "10.0.3",
"next-i18next": "^7.0.1",
Expand Down
31 changes: 2 additions & 29 deletions pages/api/login.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,3 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import axios from 'axios'
const loginRoute = require('@bheui/server-functions/lib/login/login')

const axiosLoginInstance = axios.create({
baseURL: `${process.env.API_URL}/api/v1`,
timeout: 100000,
headers: {
'Content-Type': 'application/json',
},
})

export default (req, res) => {
const formData = encodeURI(
`username=${req.body.email}&password=${req.body.password}&client_id=${process.env.CLIENT_ID}&client_secret=${process.env.CLIENT_SECRET}&grant_type=password`,
)
axiosLoginInstance
.post('/oauth/token', formData, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
})
.then((response) => {
res.statusCode = 200
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify(response.data))
})
.catch((e) => {
res.statusCode = 400
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify(e.message))
})
}
module.exports = loginRoute
1 change: 1 addition & 0 deletions public/static/defaultLocales/en/common.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"errorCodes":{"SOMETHING_WRONG":"Something went wrong, try it again later.","BAD_EMAIL":"Incorrect email.","BAD_PASSWORD":"Incorrect password.","MISSING_HELPER_ACTIONS":"This input needs helper actions!"},"notifications":{"SUCCESSFULLY_SAVED_MESSAGE":"Successfully saved","SUCCESSFULLY_SAVED_TITLE":"Saved","ITEMS_SUCCESSFULLY_DELETED_MESSAGE":"Items successfully deleted","ITEMS_SUCCESSFULLY_DELETED_TITLE":"Deleted"}}
1 change: 1 addition & 0 deletions public/static/defaultLocales/en/login.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"loginScreen":{"signIn":"Sign In","remember":"Remember","submitButton":"Submit"},"general":{"email":"Email","password":"Password","login":"Login"},"validationErrors":{"required":"This value is required.","badFormat":"Value format is not valid.","tooShort":"This value is to short, min. length is {{length}}.","tooLong":"This value is to long, max. length is {{length}}.","badPhoneFormat":"This phone number is not valid.","email":"Invalid email address format.","cardNumber":"Card number is not valid.","range":"The value must be in range from {{start}} to {{end}}.","numeric":"Value must be numeric.","integer":"Value must be an integer.","badRegExp":"Bad format! Pattern: {{pattern}}","suffix_interval":"(1){ 1 other error };(2-inf){ {{count}} other errors};"}}
1 change: 1 addition & 0 deletions public/static/defaultLocales/en/modules.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"errorCodes":{"SOMETHING_WRONG":"Something went wrong, try it again later.","BAD_EMAIL":"Incorrect email.","BAD_PASSWORD":"Incorrect password.","MISSING_HELPER_ACTIONS":"This input needs helper actions!"},"editScreen":{"submitButton":"Save"},"validationErrors":{"required":"This value is required.","badFormat":"Value format is not valid.","tooShort":"This value is to short, min. length is {{length}}.","tooLong":"This value is to long, max. length is {{length}}.","badPhoneFormat":"This phone number is not valid.","email":"Invalid email address format.","cardNumber":"Card number is not valid.","range":"The value must be in range from {{start}} to {{end}}.","numeric":"Value must be numeric.","integer":"Value must be an integer.","badRegExp":"Bad format! Pattern: {{pattern}}","suffix_interval":"(1){ 1 other error };(2-inf){ {{count}} other errors};"},"navigation":{"users":"Users","settings":"Settings"},"general":{"email":"Email","password":"Password","login":"Login","listNoData":"Nothing to display","yes":"Yes","no":"No","add":"Add","view":"View","edit":"Edit","delete":"Delete","refresh":"Refresh","cancel":"Cancel","confirm":"Confirm","notConfigured":"Forms are not configured for this module!","uploadImage":"Upload","save":"Save","name":"Name","apiKey":"API key","origin":"Origin","active":"Active","groupId":"Group ID","createdAt":"Created at","updatedAt":"Updated at","id":"ID","copyUrl":"Copy URL","showFilter":"Show filter","hideFilter":"Hide filter","hash":"Hash","status":"Status","logCount":"Log count","sourceMap":"Source map","app":"App","version":"Version","stackTrace":"Stack trace","guardGroup":"Group","logLevel":"Log level","removeSelectedRequest":"Delete selected items","module":"Module","action":{"list":"List","view":"View","add":"Add","edit":"Edit","delete":"Delete"},"group":"Group","description":"Description"},"modules":{"dashboard":{"menuTitle":"Dashboard","listTitle":"Dashboard"},"version":{"menuTitle":"Versions","addTitle":"Add version","editTitle":"Edit version","listTitle":"All versions","viewTitle":"Version","tab":{"main":"Main"}},"users":{"menuTitle":"Users","listTitle":"Users","addTitle":"Add user","editTitle":"Edit user","viewTitle":"User","parent":{"menuTitle":"User"},"tab":{"main":"Main"}},"userDevice":{"menuTitle":"User devices","listTitle":"User devices","addTitle":"Add user device","editTitle":"Edit user device","viewTitle":"User devices","tab":{"main":"Main"}},"userRights":{"menuTitle":"Rights","listTitle":"User rights","addTitle":"Add user rights","editTitle":"Edit user rights","viewTitle":"User rights","tab":{"main":"Main"}},"userGroups":{"menuTitle":"Groups","listTitle":"Groups","addTitle":"Add group","editTitle":"Edit group","viewTitle":"Group","tab":{"main":"Main"}},"userInGroups":{"menuTitle":"User in groups","listTitle":"User in groups","addTitle":"Add user to group","editTitle":"Edit user in group","viewTitle":"User in group","tab":{"main":"Main"}},"settings":{"menuTitle":"Settings","addTitle":"Add settings","editTitle":"Edit settings","listTitle":"Settings","viewTitle":"Settings","tab":{"main":"Main"}},"guardX":{"menuTitle":"GuardX"},"guardXApp":{"menuTitle":"GuardX App","addTitle":"Add App","editTitle":"Edit App","listTitle":"All Apps lists","viewTitle":"Apps list","tab":{"main":"Main"}},"guardXLog":{"menuTitle":"GuardX log","listTitle":"All GuardX logs","viewTitle":"GuardX log","tab":{"main":"Main"}},"guardXGroup":{"menuTitle":"GuardX group","listTitle":"All GuardX groups","viewTitle":"GuardX group","tab":{"main":"Main","logs":"Logs"},"form":{"sourceMap":"Stack mapped"}},"guardXSourceMap":{"menuTitle":"GuardX Source Maps","listTitle":"All GuardX Source Maps","viewTitle":"GuardX Source Map","tab":{"main":"Main","logs":"Logs"},"form":{"path":"File"}},"cache":{"menuTitle":"Cache","listTitle":"Cache","viewTitle":"Cache","tab":{"main":"Main"}},"logger":{"menuTitle":"Logs"},"dbLogger":{"menuTitle":"DB logs","addTitle":"Add DB log","editTitle":"Edit DB log","listTitle":"All DB logs","viewTitle":"DB log","tab":{"main":"Main"}},"actionLogger":{"menuTitle":"Action logs","addTitle":"Add action log","editTitle":"Edit action log","listTitle":"All action logs","viewTitle":"Action log","tab":{"main":"Main"}},"client":{"menuTitle":"oAuth clients","addTitle":"Add client","editTitle":"Edit client","listTitle":"All clients","viewTitle":"oAuth client","tab":{"main":"Main"}}},"dataTableColumns":{"actions":"Actions","action":"Action","clientId":"Client ID","clientSecret":"Client secret","clientType":"Client type","grants":"Grants","address":"Address","description":"Description","email":"Email","group":"Group","id":"ID","key":"Key","name":"Name","role":"Role","token":"Token","username":"Username","user":"User","subject":"Subject","to":"To","status":"Status","user_email":"User email","cityId":"City ID","weatherData":"Weather data","updatedAt":"Last update","url":"Url","active":"Active","batteryCapacity":"Battery capacity","fullTrashCan":"Full trash can","softwareVersion":"Software version","ipAddress":"IP address","busStop_name":"Bus stop","feed_name":"Feed","title":"Title","link":"Link","onlineRadio":"Online radio","onlineRadio_name":"Online radio","floor_name":"Floor","domain":"Domain","apiKey":"Api key","monthlyMessageCount":"Actual monthly message count","limit":"Limit","topic_name":"Topic","visiblePublic":"Public visible?","valueFrom":"From","valueTo":"To","type":"Type","value":"Value","enabled":"Enabled","slackId":"Slack ID","error":"Error","version":"Version","logLevel":"Log level","dataset_name":"Dataset","dateTime":"Datetime","unit":"Unit","threshold":"Threshold","message":"Message","texts_name":"Name","app_name":"App name","logCount":"Count","module":"Module","group_name":"Group name","origin":"Origin","distance":"Distance","level":"Level"},"forms":{"active":"Active","action":"Action","code":"Code","content":"Content","createdAt":"CreatedAt","data":"Data","description":"Description","clientId":"Client ID","clientSecret":"Client secret","clientType":"Client type","grants":"Grants","feed":"Feed","guid":"Guid (unique)","id":"ID","image":"Image","lastSync":"Last sync","link":"Link","name":"Name","publicationDate":"Publication date","status":"Status","sourceMap":"Sourcemap","subject":"Subject","title":"Title","to":"To","updatedAt":"UpdatedAt","url":"Url","user":"User","latitude":"Latitude","longitude":"Longitude","ipAddress":"IP address","temperature":"Temperature","info":"Info","type":"Type","weatherData":"Data","position":"Position","floor":"Floor","lastActive":"Last active","favourite":"Favourite","onlineRadio":"Online radio","key":"Key","group":"Group","value":"Value","values":"Values","topic":"Topic","valueFrom":"From","valueTo":"To","visiblePublic":"Public visible","enabled":"Enabled","module":"Module","actions":"Actions","apiKey":"Api key","origin":"Origin","username":"Username","token":"Token","surname":"Surname","email":"Email","phone":"Phone","role":"Role","selectedGroupId":"Selected group ID","activePresentationId":"Active presentation ID","error":"Error","version":"Version","logLevel":"Log level","stackTrace":"Stack trace","app":"App","guardGroup":"Guard group","hash":"Hash","logCount":"Error count","logs":"Logs","ip":"IP","connectionType":"Connection type","macAddress":"Mac address","deviceType":"Device type","threshold":"Threshold","unit":"Unit","dateTime":"Date","dataset":"Dataset","password":"Password","message":"Message","templateName":"Template","moduleName":"Module","identificationId":"Identification id","groupId":"Group ID"},"filter":{"_action":{"search":"Search","reset":"Reset"},"id":"ID","search":"Search","user":"User","status":"Status"},"valueToString":{"typeObject":"_Object_","typeArray":"_Array_"},"paginator":{"description":"Showing {{first}} to {{last}} of {{count}} records."},"confirmationModal":{"deleteTitle":"You want to delete these items?"}}
56 changes: 45 additions & 11 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,57 @@
const { createServer } = require('http')
const { parse } = require('url')
const express = require('express')
const next = require('next')
const compression = require('compression')
const bodyParser = require('body-parser')

const processLocale = require('./src/server/process-locale')
const processLocale = require('@bheui/server-functions/lib/locale/process-locale')

const apiLogin = require('./pages/api/login').default

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

const renderPageOrContinue = (req, res, nextCl) => {
console.log(req.path)
if (req.path.includes('_next') || req.path.includes('api/')) {
return nextCl()
}
const query = { ...req.params }
if (req.params.id) {
query.page = '/[module]/[action]/[id]'
} else if (req.params.action) {
query.page = '/[module]/[action]'
} else if (req.params.module) {
query.page = '/[module]'
}
console.log(query)
return app.render(req, res, req.params.page, query)
}

app.prepare().then(() => {
processLocale()

createServer((req, res) => {
// Be sure to pass `true` as the second argument to `url.parse`.
// This tells it to parse the query portion of the URL.
const parsedUrl = parse(req.url, true)
handle(req, res, parsedUrl)
}).listen(3000, (err) => {
if (err) throw err
console.log('> Ready on http://localhost:3000')
const server = express()
server.use(`/static`, express.static('public'))
server.use(compression())

server.get('/is-ready', (req, res) => {
res.sendStatus(200)
})

server.use('/api/login', bodyParser.json({ limit: '50mb' }))
server.post('/api/login', apiLogin)

server.get('/:module/:action/:id', renderPageOrContinue, (req, res) => handle(req, res))
server.get('/:module/:action', renderPageOrContinue, (req, res) => handle(req, res))

server.get('*', (req, res) => handle(req, res))

server.listen(3000, (err) => {
if (err) {
console.error(err.stack)
process.exit(1)
}
console.log(`> Ready on http://localhost:${3000}`)
})
})
3 changes: 3 additions & 0 deletions src/containers/ListContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import React from 'react'
import TitleWithBreadcrumbs from '@bheui/components/lib/components/TitleWithBreadcrumbs'
import withModule from '@bheui/components/lib/components/WithModule'
import ListComponent from '@bheui/components/lib/components/ListComponent'
import CustomModuleComponents from '@bheui/components/lib/components/modules/CustomModuleComponents'

// types

Expand All @@ -21,6 +22,7 @@ type Props = {
class ListContainer extends React.Component<Props, State> {
render() {
const { changeRedirectUrl, module, navigationItem, rights, settings, t } = this.props
console.log(this.props)
return (
<div className="list-container-wrapper">
<div className="container">
Expand All @@ -35,6 +37,7 @@ class ListContainer extends React.Component<Props, State> {
<div className="container ms-bgColor-white list-container">
<ListComponent
changeRedirectUrl={changeRedirectUrl}
customComponents={CustomModuleComponents}
module={module}
navigationItem={navigationItem}
rights={rights}
Expand Down
17 changes: 11 additions & 6 deletions src/containers/RootContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,19 @@ class RootScreen extends React.Component<Props, null> {

checkNotificationsToShow = () => {
const { notificationToShow, clearNotifications, t } = this.props
if (notificationToShow.length > 0) {
if (notificationToShow.length > 0 && this.toastrContainer && this.toastrContainer.current) {
const notifications = [...notificationToShow]
clearNotifications()
notifications.map((notification: NotificationType) => {
this.toastrContainer.current[notification.type](
notification.translate ? t(`notifications.${notification.message}`) : notification.message,
notification.translate ? t(`notifications.${notification.title}`) : notification.title,
{ closeButton: true },
)
if (typeof this.toastrContainer.current[notification.type] === 'function') {
this.toastrContainer.current[notification.type](
notification.translate ? t(`notifications.${notification.message}`) : notification.message,
notification.translate ? t(`notifications.${notification.title}`) : notification.title,
{ closeButton: true },
)
} else {
console.error(notification)
}
return true
})
}
Expand All @@ -111,6 +115,7 @@ class RootScreen extends React.Component<Props, null> {

render() {
const { children, navigation, presentationId, presentationIds, router, selectedGroup, t, userGroups } = this.props
console.log(this.props)
return (
<div className="app-body">
<ToastContainer ref={this.toastrContainer} className="toast-top-right" />
Expand Down
53 changes: 0 additions & 53 deletions src/server/process-locale.js

This file was deleted.

Loading

0 comments on commit d0578b2

Please sign in to comment.