Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
concept-front-mojsprat-v2
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Djordje Mutavdzic
concept-front-mojsprat-v2
Commits
4a8a1a6c
Commit
4a8a1a6c
authored
Jun 30, 2022
by
Djordje
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add action handlers
parent
f9fc9f48
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
650 additions
and
1 deletion
+650
-1
package.json
package.json
+2
-1
data-manager.js
src/actions/data-manager.js
+455
-0
index.js
src/actions/index.js
+101
-0
network-manager.js
src/actions/network-manager.js
+92
-0
No files found.
package.json
View file @
4a8a1a6c
...
@@ -43,5 +43,6 @@
...
@@ -43,5 +43,6 @@
"last 1 firefox version"
,
"last 1 firefox version"
,
"last 1 safari version"
"last 1 safari version"
]
]
}
},
"proxy"
:
"http://localhost:3001"
}
}
src/actions/data-manager.js
0 → 100644
View file @
4a8a1a6c
import
{
fetchRequestManager
,
fetchRequestTenant
}
from
'./network-manager'
import
{
fetchBuildingsSuccess
,
genericAction
,
TENANT_BUILDING_RECEIVED
,
UNAUTHENTICATED
,
TENANT_VOTING_RECEIVED
}
from
'./index'
export
function
fetchBuildings
()
{
return
dispatch
=>
{
fetchRequestManager
(
"/buildings"
,
(
err
,
data
,
dispatch
)
=>
{
if
(
err
)
{
if
(
err
.
status
===
401
)
{
dispatch
(
genericAction
(
UNAUTHENTICATED
))
}
return
;
}
else
{
dispatch
(
fetchBuildingsSuccess
(
data
));
}
}
,
dispatch
,
"GET"
//,null, false
)
}
}
////////////////////////////////////////
//TODO: handle this, it should not go over reducer
export
function
postNewBuilding
(
data
)
{
fetchRequestManager
(
"/buildings"
,
null
,
null
,
"POST"
,
data
)
//TODO: !!! Add callback that will ADD_BUILDING, not vice versa as it is now
}
export
function
fetchTemplate
(
buildingId
)
{
fetchRequestManager
(
"/b/"
+
buildingId
+
"/templating/engine"
,
null
,
null
,
'POST'
,
'pojedinacno glasanje.pdf'
,
true
)
//TODO: !!! Add callback that will CREATE_DOCUMENTS, not vice versa as it is now
}
export
function
fetchTemplateMeetingVoting
(
buildingId
)
{
fetchRequestManager
(
"/b/"
+
buildingId
+
"/templating/meeting-voting"
,
null
,
null
,
'POST'
,
'grupno glasanje.pdf'
,
true
)
//TODO: !!! Add callback that will CREATE_DOCUMENTS, not vice versa as it is now
}
export
function
fetchTemplateLatestVoting
(
buildingId
)
{
fetchRequestManager
(
"/b/"
+
buildingId
+
"/templating/latest-voting"
,
null
,
null
,
'POST'
,
'Izvestaj.pdf'
,
true
)
//TODO: !!! Add callback that will CREATE_DOCUMENTS, not vice versa as it is now
}
////////////////////////
export
function
downloadLatestInvoice
(
buildingId
)
{
//TODO: consider pros/cons over reducer actions
return
dispatch
=>
{
fetchRequestManager
(
"/b/"
+
buildingId
+
"/templating/invoice/print-latest"
,
null
,
null
,
'GET'
,
'invoice.pdf'
,
true
)
// return downloadRequest('GET', API_ADDRESS + "/finance/invoice/print-latest/" + buildingId, 'invoice.docx')
}
}
export
function
postObligation
(
buildingId
,
name
,
link
,
price
,
accounting
,
callback
)
{
return
dispatch
=>
{
fetchRequestManager
(
"/finance/obligation"
,
(
err
,
data
,
dispatch
)
=>
{
if
(
callback
)
{
callback
()
}
//TODO: consider this
fetchBuildings
()(
dispatch
);
},
dispatch
,
"POST"
,
{
"buildingId"
:
buildingId
,
"name"
:
name
,
"price"
:
price
,
"link"
:
link
,
accounting
}
)
};
}
export
function
postInvoiceConfirmation
(
buildingId
,
periodStart
,
periodEnd
)
{
return
dispatch
=>
{
fetchRequestManager
(
"/finance/invoice-confirmation/"
+
periodStart
+
"/"
+
periodEnd
,
(
err
,
data
,
dispatch
)
=>
{
//TODO: add callback
// if (callback) { callback() }
//TODO: consider this
fetchBuildings
()(
dispatch
);
},
dispatch
,
"POST"
,
{
buildingId
}
)
};
}
//////////////////////////////
//Thunks
function
thunkRequestBase
(
fetchFN
,
address
,
object
,
callback
,
method
=
"POST"
,
getBuildings
=
true
)
{
return
dispatch
=>
{
fetchFN
(
address
,
(
err
,
data
,
dsp
)
=>
{
if
(
callback
)
{
callback
(
err
,
data
,
dsp
)
};
if
(
getBuildings
)
{
fetchBuildings
()(
dsp
);
}
},
dispatch
,
method
,
object
)
}
}
export
function
thunkRequestTenant
(
address
,
object
,
callback
,
method
=
"POST"
,
getBuildings
=
false
)
{
return
thunkRequestBase
(
fetchRequestTenant
,
address
,
object
,
callback
,
method
,
getBuildings
)
}
export
function
thunkRequestManager
(
address
,
object
,
callback
,
method
=
"POST"
,
getBuildings
=
true
)
{
return
thunkRequestBase
(
fetchRequestManager
,
address
,
object
,
callback
,
method
,
getBuildings
)
}
/////////////////////////////
export
function
postNewNotification
(
buildingId
,
title
,
description
,
callback
)
{
return
thunkRequestManager
(
'/notifications'
,
{
buildingId
,
title
,
description
},
callback
)
}
export
function
putNotification
(
buildingId
,
notificationId
,
title
,
description
,
callback
)
{
return
thunkRequestManager
(
'/notifications'
,
{
buildingId
,
notificationId
,
title
,
description
},
callback
,
"PUT"
)
}
export
function
deleteNotification
(
buildingId
,
notificationId
)
{
return
thunkRequestManager
(
'/notifications'
,
{
buildingId
,
notificationId
},
null
,
"DELETE"
)
}
export
function
postNewIsssue
(
buildingId
,
title
,
description
,
callback
)
{
return
thunkRequestManager
(
`/b/
${
buildingId
}
/issues`
,
{
title
,
description
},
callback
)
}
export
function
postNewSolution
(
buildingId
,
issueIndex
,
name
,
description
,
price
,
callback
)
{
return
thunkRequestManager
(
`/b/
${
buildingId
}
/issue/solution`
,
{
issueIndex
,
name
,
description
,
price
},
callback
)
}
export
function
postNewVoting
(
buildingId
,
voting
,
callback
)
{
return
thunkRequestManager
(
`/b/
${
buildingId
}
/voting`
,
voting
,
callback
)
}
export
function
postManualVoting
(
buildingId
,
unitId
,
votedFor
,
callback
)
{
return
thunkRequestManager
(
`/b/
${
buildingId
}
/voting/manual-submit/
${
unitId
}
/
${
votedFor
}
`
,
null
,
callback
)
}
export
function
postVote
(
buildingId
,
vote
,
callback
)
{
return
thunkRequestTenant
(
`/
${
buildingId
}
/voting/submit`
,
vote
,
callback
,
"POST"
)
}
export
function
postVotingKey
(
publicKey
,
callback
)
{
return
thunkRequestTenant
(
'/info/public-key'
,
{
publicKey
},
callback
,
"POST"
)
}
export
function
postNewDocument
(
buildingId
,
name
,
link
,
callback
)
{
return
thunkRequestManager
(
`/b/
${
buildingId
}
/docs`
,
{
"buildingId"
:
buildingId
,
"name"
:
name
,
"link"
:
link
},
callback
)
}
export
function
deleteDocument
(
buildingId
,
doc
)
{
return
thunkRequestManager
(
`/b/
${
buildingId
}
/docs`
,
{
buildingId
,
doc
},
null
,
"DELETE"
,
true
)
}
export
function
postLogin
(
username
,
password
,
isManager
,
callback
)
{
//NOTE: jwt is not important for this route, it could be used thunkRequestTenant
return
thunkRequestManager
(
isManager
?
'/auth/login-manager'
:
'/auth/login'
,
{
username
,
password
},
callback
,
"POST"
,
false
)
}
export
function
getBuilding
(
buildingId
)
{
return
thunkRequestTenant
(
'/'
+
buildingId
+
"/building"
,
null
,
(
err
,
data
,
dsp
)
=>
{
if
(
err
)
{
if
(
err
.
status
===
401
)
{
dsp
(
genericAction
(
UNAUTHENTICATED
))
}
// console.log(err)
console
.
error
(
"Can not get tenant building"
)
return
}
dsp
(
genericAction
(
TENANT_BUILDING_RECEIVED
,
data
))
},
"GET"
,
false
)
}
//TODO: Consider caching, forcing request
// export function getTenantNotification(buildingId) {
// return getBuilding(buildingId)
// }
// export function getTenantActivities(buildingId) {
// return getBuilding(buildingId)
// }
export
function
getTenentVoting
(
buildingId
,
callback
)
{
return
thunkRequestTenant
(
'/'
+
buildingId
+
'/voting'
,
null
,
(
err
,
data
,
dsp
)
=>
{
if
(
err
)
{
if
(
err
.
status
===
401
)
{
dsp
(
genericAction
(
UNAUTHENTICATED
))
}
console
.
error
(
"Can not get tenant voting"
)
return
}
dsp
(
genericAction
(
TENANT_VOTING_RECEIVED
,
data
))
},
"GET"
,
false
)
}
export
function
getTenantInfo
(
callback
)
{
return
thunkRequestTenant
(
'/info'
,
null
,
callback
,
"GET"
)
}
export
function
getAllUsers
(
callback
)
{
return
thunkRequestTenant
(
'/tenants'
,
null
,
callback
,
"GET"
);
}
// export function getTenentInvoices(buildingId) {
// return getBuilding(buildingId)
// }
// export function getTenantDocs(buildingId) {
// return getBuilding(buildingId)
// }
// export function getTenantBuildingFinance(buildingId) {
// return getBuilding(buildingId)
// }
export
function
getPreRegisterData
(
token
,
callback
)
{
//TODO: check if thunk is suffecient
//NOTE: jwt is not relevant for this request
thunkRequestManager
(
'/auth/pre-register/'
+
token
,
null
,
callback
,
"GET"
,
false
)(
null
)
}
export
function
registerUser
(
token
,
data
,
callback
)
{
//TODO: check if thunk is needed
thunkRequestManager
(
'/auth/register/'
+
token
,
data
,
callback
,
"POST"
,
false
)(
null
)
}
export
function
confirmUserUnit
(
buildingId
,
unitId
,
userId
)
{
return
thunkRequestManager
(
`/b/
${
buildingId
}
/auth/confirm-user-unit/
${
unitId
}
/
${
userId
}
`
,
{},
null
,
"POST"
,
true
)
}
export
function
assignUserUnit
(
buildingId
,
unitId
,
userId
,
data
)
{
return
thunkRequestManager
(
`/b/
${
buildingId
}
/auth/assign-user-unit/
${
unitId
}
/
${
userId
}
`
,
data
,
null
,
"POST"
,
true
)
}
export
function
setUnitOwner
(
buildingId
,
unitId
,
data
)
{
return
thunkRequestManager
(
`/b/
${
buildingId
}
/auth/set-unit-owner/
${
unitId
}
`
,
data
,
null
,
"POST"
,
true
)
}
export
function
postInflow
(
buildingId
,
invoiceId
,
payer
,
amount
,
callback
)
{
return
dispatch
=>
{
fetchRequestManager
(
"/finance/inflow"
,
(
err
,
data
,
dispatch
)
=>
{
if
(
callback
)
{
callback
()
}
//TODO: consider this
fetchBuildings
()(
dispatch
);
},
dispatch
,
"POST"
,
{
"buildingId"
:
buildingId
,
"invoiceId"
:
invoiceId
,
// "payer": payer,
"amount"
:
amount
}
)
};
}
export
function
postInflowRevert
(
buildingId
,
invoiceId
,
payer
,
amount
,
callback
)
{
return
dispatch
=>
{
fetchRequestManager
(
"/finance/inflow-revert"
,
(
err
,
data
,
dispatch
)
=>
{
if
(
callback
)
{
callback
()
}
//TODO: consider this
fetchBuildings
()(
dispatch
);
},
dispatch
,
"POST"
,
{
"buildingId"
:
buildingId
,
"invoiceId"
:
invoiceId
,
// "payer": payer,
"amount"
:
amount
}
)
};
}
export
function
postOutflow
(
buildingId
,
payableId
,
amount
,
reason
,
callback
)
{
return
dispatch
=>
{
fetchRequestManager
(
"/finance/outflow"
,
(
err
,
data
,
dispatch
)
=>
{
if
(
callback
)
{
callback
()
}
//TODO: consider this
fetchBuildings
()(
dispatch
);
},
dispatch
,
"POST"
,
{
"buildingId"
:
buildingId
,
"reason"
:
reason
,
// "payer": payer,
"amount"
:
amount
,
"payableId"
:
payableId
}
)
};
}
export
function
settleUnsettled
(
buildingId
)
{
return
thunkRequestManager
(
"/finance/settle-unsettled"
,
{
buildingId
},
null
,
"POST"
,
true
)
}
////////////////////////////////////////
//TODO: consider not using reducer
export
function
editSolution
(
buildingId
,
issueIndex
,
solutionIndex
,
data
)
{
let
address
=
`/b/
${
buildingId
}
/issue/solution/
${
issueIndex
}
/
${
solutionIndex
}
`
return
thunkRequestManager
(
address
,
data
,
(
err
,
data
,
dsp
)
=>
{
if
(
err
)
{
if
(
err
.
status
===
401
)
{
dsp
(
genericAction
(
UNAUTHENTICATED
))
}
console
.
error
(
"Can not get update solution"
)
return
}
},
"PUT"
,
true
)
}
export
function
deleteSolution
(
buildingId
,
data
)
{
let
address
=
`/b/
${
buildingId
}
/issue/solution/`
return
thunkRequestManager
(
address
,
data
,
(
err
,
data
,
dsp
)
=>
{
if
(
err
)
{
if
(
err
.
status
===
401
)
{
dsp
(
genericAction
(
UNAUTHENTICATED
))
}
console
.
error
(
"Can not delete solution"
)
return
}
},
"PUT"
,
true
)
}
export
function
editIssue
(
buildingId
,
issueIndex
,
data
)
{
let
address
=
`/b/
${
buildingId
}
/issue/
${
issueIndex
}
`
return
thunkRequestManager
(
address
,
data
,
(
err
,
data
,
dsp
)
=>
{
if
(
err
)
{
if
(
err
.
status
===
401
)
{
dsp
(
genericAction
(
UNAUTHENTICATED
))
}
console
.
error
(
"Can not get update solution"
)
return
}
},
"PUT"
,
true
)
}
export
function
deleteIssue
(
buildingId
,
issueId
)
{
let
address
=
`/b/
${
buildingId
}
/issue/
${
issueId
}
`
return
thunkRequestManager
(
address
,
null
,
(
err
,
data
,
dsp
)
=>
{
if
(
err
)
{
if
(
err
.
status
===
401
)
{
dsp
(
genericAction
(
UNAUTHENTICATED
))
}
console
.
error
(
"Can not get update solution"
)
return
}
},
"DELETE"
,
true
)
}
export
function
moveUpIssue
(
buildingId
,
issueIndex
,
issueId
)
{
let
address
=
`/b/
${
buildingId
}
/issue-move-up/
${
issueIndex
}
/
${
issueId
}
`
return
thunkRequestManager
(
address
,
null
,
(
err
,
data
,
dsp
)
=>
{
if
(
err
)
{
if
(
err
.
status
===
401
)
{
dsp
(
genericAction
(
UNAUTHENTICATED
))
}
console
.
error
(
"Can not move issue"
)
return
}
},
"PUT"
,
true
)
}
///////////////////
//TODO: add UI success notification
//TODO: add error handling
//NETWORK - Data Caching... TBD...
src/actions/index.js
0 → 100644
View file @
4a8a1a6c
export
const
ADD_BUILDING
=
"ADD_BUILDING"
;
export
const
CHANGE_NEW_BUILDING
=
"CHANGE_NEW_BUILDING"
export
const
CHANGE_NEW_UNIT_COUNT
=
"CHANGE_NEW_UNIT_COUNT"
export
const
CHANGE_NEW_UNIT
=
"CHANGE_NEW_UNIT"
export
const
CHANGE_OWNER
=
"CHANGE_OWNER"
export
const
CREATE_DOCUMENTS
=
"CREATE_DOCUMENTS"
;
export
const
CHANGE_SELECTED_BUILDING
=
"CHANGE_SELECTED_BUILDING"
export
const
GENERIC_STATE_CHANGE
=
"GENERIC_STATE_CHANGE"
export
const
FETCH_ALL_BUILDING_SUCCESS
=
"FETCH_ALL_BUILDING_SUCCESS"
export
const
TOKEN_RECEIVED
=
"TOKEN_RECEIVED"
export
const
TOKEN_RECEIVED_MANAGER
=
"TOKEN_RECEIVED_MANAGER"
export
const
TENANT_BUILDING_RECEIVED
=
"TENANT_BUILDING_RECEIVED"
export
const
TENANT_VOTING_RECEIVED
=
"TENANT_VOTING_RECEIVED"
export
const
UNAUTHENTICATED
=
"UNAUTHENTICATED"
//TBD:
// ChangeTenant/Owner
// SubmitIssue
// AddProposal
// Vote
export
function
genericAction
(
type
,
payload
){
return
{
type
,
payload
}
}
// export function tokenReceived(jwt, role){
// return genericAction(TOKEN_RECEIVED, {jwt, role})
// }
// export function
// export function tenantBuildingReceived(building){
// return genericAction(TENANT_BUILDING_RECEIVED, building)
// }
//TODO: this should be called when is already added
export
function
addBuilding
(
building
)
{
return
{
type
:
ADD_BUILDING
,
payload
:
building
}
}
export
function
changeNewBuilding
(
updateData
)
{
return
{
type
:
CHANGE_NEW_BUILDING
,
payload
:
updateData
}
}
export
function
changeNewUnitCount
(
count
)
{
return
{
type
:
CHANGE_NEW_UNIT_COUNT
,
payload
:
count
}
}
export
function
changeNewUnit
(
updateData
)
{
return
{
type
:
CHANGE_NEW_UNIT
,
payload
:
updateData
}
}
export
function
changeNewUnitOwner
(
updateData
)
{
return
{
type
:
CHANGE_OWNER
,
payload
:
updateData
}
}
export
const
fetchBuildingsSuccess
=
buildings
=>
({
type
:
FETCH_ALL_BUILDING_SUCCESS
,
payload
:
{
buildings
}
});
//TODO: this should not be called by reducer
export
function
createDocuments
(
building
)
{
// console.log(building)
return
{
type
:
CREATE_DOCUMENTS
,
payload
:
building
}
}
export
function
changeSelectedBuilding
(
buildingId
,
selectedIndex
)
{
return
{
type
:
CHANGE_SELECTED_BUILDING
,
payload
:
{
selectedBuilding
:
buildingId
,
selectedBuildingIndex
:
selectedIndex
-
1
}
}
}
export
function
genericStateChange
(
key
,
value
)
{
return
{
type
:
GENERIC_STATE_CHANGE
,
payload
:
{
key
,
value
}
}
}
src/actions/network-manager.js
0 → 100644
View file @
4a8a1a6c
// console.log("process.env.REACT_APP_USE_DEV")
// console.log(process.env.REACT_APP_USE_DEV)
// let API_ADDRESS
// if (process.env.REACT_APP_USE_DEV) {
// // API_ADDRESS = API_ADDRESS = "http://localhost:3001"
// } else {
// API_ADDRESS = "/api"
// }
const
API_ADDRESS
=
"/api"
export
const
JWT_TENANT
=
"jwtt"
export
const
JWT_MANAGER
=
"jwtm"
function
fetchRequestBase
(
jwt
,
api_prefix
,
address
,
callback
,
dispatch
,
method
=
"GET"
,
object
=
undefined
,
isDownload
=
false
)
{
let
requestInit
=
{
method
,
headers
:
{
// 'Accept': 'application/json',
'Content-Type'
:
'application/json'
,
'Authorization'
:
localStorage
.
getItem
(
jwt
)
}
}
if
(
!
isDownload
&&
object
)
{
requestInit
[
"body"
]
=
JSON
.
stringify
(
object
)
}
return
fetch
(
API_ADDRESS
+
api_prefix
+
address
,
requestInit
)
.
then
(
res
=>
{
//NOTE: cascade promise is used in order to get both res.body and res status in same processing phase.
let
promise
;
if
(
!
isDownload
)
{
promise
=
res
.
json
()
}
else
{
promise
=
res
.
blob
()
}
promise
.
then
(
json
=>
{
//TODO: unify error handling
//TODO: verify status
if
(
!
res
.
ok
)
{
if
(
typeof
(
json
)
===
"string"
)
{
json
=
{
errorMessage
:
json
}
}
console
.
log
(
json
)
json
.
statusText
=
res
.
statusText
json
.
status
=
res
.
status
console
.
error
(
json
)
// if (json.status === "error") {}
if
(
callback
)
{
callback
(
json
,
null
,
dispatch
)
}
return
}
if
(
!
isDownload
)
{
if
(
callback
)
{
callback
(
null
,
json
,
dispatch
)
};
}
else
{
// 1. Create blob link to download
const
url
=
window
.
URL
.
createObjectURL
(
new
Blob
([
json
]));
const
link
=
document
.
createElement
(
'a'
);
link
.
href
=
url
;
link
.
setAttribute
(
'download'
,
object
);
// 2. Append to html page
document
.
body
.
appendChild
(
link
);
// 3. Force download
link
.
click
();
// 4. Clean up and remove the link
link
.
parentNode
.
removeChild
(
link
);
if
(
callback
)
{
callback
(
null
,
json
,
dispatch
)
};
}
})
.
catch
(
error
=>
{
// dispatch(fetchProductsFailure(error))
// console.error("ERR fetch")
console
.
error
(
error
)
if
(
callback
)
{
callback
(
error
,
null
,
dispatch
)
}
});
})
.
catch
(
error
=>
{
// dispatch(fetchProductsFailure(error))
// console.error("ERR fetch")
console
.
error
(
error
)
if
(
callback
)
{
callback
(
error
,
null
,
dispatch
)
}
});
}
export
function
fetchRequestManager
(
address
,
callback
,
dispatch
,
method
=
"GET"
,
object
=
undefined
,
isDownload
=
false
)
{
return
fetchRequestBase
(
JWT_MANAGER
,
"/manager"
,
address
,
callback
,
dispatch
,
method
,
object
,
isDownload
)
}
export
function
fetchRequestTenant
(...
args
)
{
return
fetchRequestBase
(
JWT_TENANT
,
"/tenant"
,
...
args
)
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment