partial synch with ph2 updates
This commit is contained in:
+141
-37
@@ -13,31 +13,34 @@ HASHKEY = 028ffbae928d7191c0017f298260995f901d78eabde1436c0af0423459cc3715832136
|
|||||||
# CRMURL = "devcrm2016.llcdt.gov.wales/DVPINS"
|
# CRMURL = "devcrm2016.llcdt.gov.wales/DVPINS"
|
||||||
|
|
||||||
# //New Dev oauth ESNR
|
# //New Dev oauth ESNR
|
||||||
# CLIENT_ID = 9b834097-03d7-409b-b038-ecfec31a394a
|
CLIENT_ID = 9b834097-03d7-409b-b038-ecfec31a394a
|
||||||
# CLIENT_SECRET = .Jf8Q~tKMObCJjhh_hy3J5AIctFrBalU4FS~tdxk
|
CLIENT_SECRET = .Jf8Q~tKMObCJjhh_hy3J5AIctFrBalU4FS~tdxk
|
||||||
# RELAY_ROOT = https://ar-ns-lz-pedw-dev-uks-01.servicebus.windows.net/ar-hc-lz-pedw-dev-uks-01/
|
RELAY_ROOT = https://ar-ns-lz-pedw-dev-uks-01.servicebus.windows.net/ar-hc-lz-pedw-dev-uks-01/
|
||||||
# RELAYURI = "ar-ns-lz-pedw-dev-uks-01.servicebus.windows.net"
|
RELAYURI = "ar-ns-lz-pedw-dev-uks-01.servicebus.windows.net"
|
||||||
# RELAYPATH = "ar-hc-lz-pedw-dev-uks-01"
|
RELAYPATH = "ar-hc-lz-pedw-dev-uks-01"
|
||||||
# CRMURL = "devcrm2016.llcdt.gov.wales/DVPINS"
|
CRMURL = "devcrm2016.llcdt.gov.wales/DVPINS"
|
||||||
|
CRMURL_VERSION = "v8.2"
|
||||||
|
|
||||||
# //New Test
|
# //New Test
|
||||||
# CLIENT_ID = d40b9373-96c2-4b04-8bd8-c2a2fe6444c1
|
CLIENT_ID = d40b9373-96c2-4b04-8bd8-c2a2fe6444c1
|
||||||
# CLIENT_SECRET = 6hT8Q~glL~jloWpGmvXw3UY37QFwjUE0r._jobEM
|
CLIENT_SECRET = 6hT8Q~glL~jloWpGmvXw3UY37QFwjUE0r._jobEM
|
||||||
# RELAY_ROOT = https://ar-ns-lz-pedw-test-uks-01.servicebus.windows.net/ar-hc-lz-pedw-test-uks-01/
|
RELAY_ROOT = https://ar-ns-lz-pedw-test-uks-01.servicebus.windows.net/ar-hc-lz-pedw-test-uks-01/
|
||||||
# RELAYURI = "ar-ns-lz-pedw-test-uks-01.servicebus.windows.net"
|
RELAYURI = "ar-ns-lz-pedw-test-uks-01.servicebus.windows.net"
|
||||||
# RELAYPATH = "ar-hc-lz-pedw-test-uks-01"
|
RELAYPATH = "ar-hc-lz-pedw-test-uks-01"
|
||||||
# CRMURL = "tscrm2016.llcdt.gov.wales/UATPINS"
|
CRMURL = "tscrm2016.llcdt.gov.wales/UATPINS"
|
||||||
|
CRMURL_VERSION = "v8.2"
|
||||||
|
|
||||||
# //New PreProd
|
# # //New PreProd
|
||||||
CLIENT_ID = ab6c4678-b31a-4eb3-b429-e039120e488a
|
# CLIENT_ID = ab6c4678-b31a-4eb3-b429-e039120e488a
|
||||||
CLIENT_SECRET = V288Q~P1lFMvvX9Xnkx2pLixK~GOREH983Owqc1E
|
# CLIENT_SECRET = V288Q~P1lFMvvX9Xnkx2pLixK~GOREH983Owqc1E
|
||||||
RELAY_ROOT = https://ar-ns-lz-pedw-ppe-uks-01.servicebus.windows.net/ar-hc-lz-pedw-ppe-uks-01/
|
# RELAY_ROOT = https://ar-ns-lz-pedw-ppe-uks-01.servicebus.windows.net/ar-hc-lz-pedw-ppe-uks-01/
|
||||||
RELAYURI = "ar-ns-lz-pedw-ppe-uks-01.servicebus.windows.net"
|
# RELAYURI = "ar-ns-lz-pedw-ppe-uks-01.servicebus.windows.net"
|
||||||
RELAYPATH = "ar-hc-lz-pedw-ppe-uks-01"
|
# RELAYPATH = "ar-hc-lz-pedw-ppe-uks-01"
|
||||||
# RELAY_ROOT = https://ar-ns-lz-pedw-ppe-ukw-01.servicebus.windows.net/ar-hc-lz-pedw-ppe-ukw-01/
|
# # RELAY_ROOT = https://ar-ns-lz-pedw-ppe-ukw-01.servicebus.windows.net/ar-hc-lz-pedw-ppe-ukw-01/
|
||||||
# RELAYURI = "ar-ns-lz-pedw-ppe-ukw-01.servicebus.windows.net"
|
# # RELAYURI = "ar-ns-lz-pedw-ppe-ukw-01.servicebus.windows.net"
|
||||||
# RELAYPATH = "ar-hc-lz-pedw-ppe-ukw-01"
|
# # RELAYPATH = "ar-hc-lz-pedw-ppe-ukw-01"
|
||||||
CRMURL = "ppcrm2016.llcdt.gov.wales/PPPINSWales"
|
# CRMURL = "ppcrm2016.llcdt.gov.wales/PPPINSWales"
|
||||||
|
# CRMURL_VERSION = "v8.2"
|
||||||
|
|
||||||
|
|
||||||
# //Prod Oauth WGO
|
# //Prod Oauth WGO
|
||||||
@@ -48,6 +51,57 @@ CRMURL = "ppcrm2016.llcdt.gov.wales/PPPINSWales"
|
|||||||
# RELAYPATH = "prod-pedw-hc"
|
# RELAYPATH = "prod-pedw-hc"
|
||||||
# CRMURL = "crm2016.llc.gov.wales/PEDW"
|
# CRMURL = "crm2016.llc.gov.wales/PEDW"
|
||||||
|
|
||||||
|
# //New Prod
|
||||||
|
# CLIENT_ID = 3e4141a3-1fbd-454e-98f0-7f3a4f14a3cc
|
||||||
|
# CLIENT_SECRET = tFk8Q~E.R-HFjROTu1sRKqwb_ONzy05uPYoF6awR
|
||||||
|
# RELAY_ROOT = https://ar-ns-lz-pedw-prod-uks-01.servicebus.windows.net/ar-hc-lz-pedw-prod-uks-01/
|
||||||
|
# RELAYURI = "ar-ns-lz-pedw-prod-uks-01.servicebus.windows.net"
|
||||||
|
# RELAYPATH = "ar-hc-lz-pedw-prod-uks-01"
|
||||||
|
# # RELAY_ROOT = https://ar-ns-lz-pedw-ppe-ukw-01.servicebus.windows.net/ar-hc-lz-pedw-prod-ukw-01/
|
||||||
|
# # RELAYURI = "ar-ns-lz-pedw-prod-ukw-01.servicebus.windows.net"
|
||||||
|
# # RELAYPATH = "ar-hc-lz-pedw-prod-ukw-01"
|
||||||
|
# CRMURL = "crm2016.llc.gov.wales/PEDW"
|
||||||
|
# CRMURL_VERSION = "v8.2"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# D365 cnr WGO
|
||||||
|
# CLIENT_ID = 3125ac03-91ac-46a7-a166-0086f0ed90b3
|
||||||
|
# CLIENT_SECRET = bFq8Q~9VX5Ra3lKnGGIXsB.G6-ZGMx7LqyqXjdr4
|
||||||
|
# RELAY_ROOT = https://ar-ns-lz-pedw-d365cnr-uks-01.servicebus.windows.net/ar-hc-lz-pedw-d365cnr-uks-01/
|
||||||
|
# RELAYURI = "ar-ns-lz-pedw-d365cnr-uks-01.servicebus.windows.net"
|
||||||
|
# RELAYPATH = "ar-hc-lz-pedw-d365cnr-uks-01"
|
||||||
|
# CRMURL = "dv-pedw.crm11.dynamics.com"
|
||||||
|
# CRMURL_VERSION = "v9.2"
|
||||||
|
|
||||||
|
# D365 Dev WGO
|
||||||
|
# CLIENT_ID = 9b834097-03d7-409b-b038-ecfec31a394a
|
||||||
|
# CLIENT_SECRET = .Jf8Q~tKMObCJjhh_hy3J5AIctFrBalU4FS~tdxk
|
||||||
|
# RELAY_ROOT = https://ar-ns-lz-pedw-d365dev-uks-01.servicebus.windows.net/ar-hc-lz-pedw-d365dev-uks-01/
|
||||||
|
# RELAYURI = "ar-ns-lz-pedw-d365dev-uks-01.servicebus.windows.net"
|
||||||
|
# RELAYPATH = "ar-hc-lz-pedw-d365dev-uks-01"
|
||||||
|
# CRMURL = "dv-pedw.crm11.dynamics.com"
|
||||||
|
# CRMURL_VERSION = "v9.2"
|
||||||
|
|
||||||
|
# D365 Test WGO
|
||||||
|
# CLIENT_ID = d40b9373-96c2-4b04-8bd8-c2a2fe6444c1
|
||||||
|
# CLIENT_SECRET = 6hT8Q~glL~jloWpGmvXw3UY37QFwjUE0r._jobEM
|
||||||
|
# RELAY_ROOT = https://ar-ns-lz-pedw-d365test-uks-01.servicebus.windows.net/ar-hc-lz-pedw-d365test-uks-01/
|
||||||
|
# RELAYURI = "ar-ns-lz-pedw-d365test-uks-01.servicebus.windows.net"
|
||||||
|
# RELAYPATH = "ar-hc-lz-pedw-d365test-uks-01"
|
||||||
|
# CRMURL = "ts-pedw.crm11.dynamics.com"
|
||||||
|
# CRMURL_VERSION = "v9.2"
|
||||||
|
|
||||||
|
# D365 PP WGO
|
||||||
|
# CLIENT_ID = ab6c4678-b31a-4eb3-b429-e039120e488a
|
||||||
|
# CLIENT_SECRET = V288Q~P1lFMvvX9Xnkx2pLixK~GOREH983Owqc1E
|
||||||
|
# RELAY_ROOT = https://ar-ns-lz-pedw-d365ppe-uks-01.servicebus.windows.net/ar-hc-lz-pedw-d365ppe-uks-01/
|
||||||
|
# RELAYURI = "ar-ns-lz-pedw-d365ppe-uks-01.servicebus.windows.net"
|
||||||
|
# RELAYPATH = "ar-hc-lz-pedw-d365ppe-uks-01"
|
||||||
|
# CRMURL = "wg-pp-pedw.crm11.dynamics.com"
|
||||||
|
# CRMURL_VERSION = "v9.2"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//GOOGLE_TAG_MANAGER = GTM-T78CBC3
|
//GOOGLE_TAG_MANAGER = GTM-T78CBC3
|
||||||
GOOGLE_TAG_MANAGER = G-GTWW3JT03Z
|
GOOGLE_TAG_MANAGER = G-GTWW3JT03Z
|
||||||
@@ -58,8 +112,9 @@ SHOWMAPS = false
|
|||||||
API_ROOT = "http://localhost:3000"
|
API_ROOT = "http://localhost:3000"
|
||||||
CY_API_ROOT = "http://cymru.local:3000"
|
CY_API_ROOT = "http://cymru.local:3000"
|
||||||
I18N_DOMAIN = "cymru.local"
|
I18N_DOMAIN = "cymru.local"
|
||||||
DOCAPI_OFFLINE = "12:00:00,14:00:00"
|
DOCAPI_OFFLINE = "07:00:00,14:00:00"
|
||||||
SHOWFILTERDOCS = false
|
# DOCAPI_OFFLINE = "01:00:00,04:00:00"
|
||||||
|
SHOWFILTERDOCS = true
|
||||||
|
|
||||||
|
|
||||||
// Next Auth vars
|
// Next Auth vars
|
||||||
@@ -68,18 +123,35 @@ NEXTAUTH_URL_INTERNAL = $API_ROOT
|
|||||||
NEXTAUTH_SECRET = SuperSecret
|
NEXTAUTH_SECRET = SuperSecret
|
||||||
|
|
||||||
// CNR sql server
|
// CNR sql server
|
||||||
# DATABASE_URL = sqlserver://sql-srv-plt-pedw-cnr-uks-01.database.windows.net:1433;database=PEDW;user=PedwSqlAdmin;password=GhWKr62F5sQ69dZx;encrypt=true;trustServerCertificate=true;hostNameInCertificate=*.database.windows.net;loginTimeout=30;authentication=ActiveDirectoryPassword
|
DATABASE_URL = sqlserver://sql-srv-plt-pedw-cnr-uks-01.database.windows.net:1433;database=PEDW;user=PedwSqlAdmin;password=GhWKr62F5sQ69dZx;encrypt=true;trustServerCertificate=true;hostNameInCertificate=*.database.windows.net;loginTimeout=30;authentication=ActiveDirectoryPassword
|
||||||
|
|
||||||
// dev test sql server
|
// dev test sql server
|
||||||
# DATABASE_URL = sqlserver://pedw-dev-test-sql-svr.database.windows.net:1433;database=PEDWDev;user=RobBondSQL;password=GhWKr62F5sQ69dZx;encrypt=true;trustServerCertificate=true;hostNameInCertificate=*.database.windows.net;loginTimeout=30;authentication=ActiveDirectoryPassword
|
# DATABASE_URL = sqlserver://pedw-dev-test-sql-svr.database.windows.net:1433;database=PEDWDev;user=RobBondSQL;password=GhWKr62F5sQ69dZx;encrypt=true;trustServerCertificate=true;hostNameInCertificate=*.database.windows.net;loginTimeout=30;authentication=ActiveDirectoryPassword
|
||||||
# DATABASE_URL = sqlserver://sql-srv-plt-pedw-dev-uks-01.database.windows.net:1433;database=PEDW;user=PedwSqlAdmin;password=GhWKr62F5sQ69dZx;encrypt=true;trustServerCertificate=true;hostNameInCertificate=*.database.windows.net;loginTimeout=30;authentication=ActiveDirectoryPassword
|
DATABASE_URL = sqlserver://sql-srv-plt-pedw-dev-uks-01.database.windows.net:1433;database=PEDW;user=PedwSqlAdmin;password=GhWKr62F5sQ69dZx;encrypt=true;trustServerCertificate=true;hostNameInCertificate=*.database.windows.net;loginTimeout=30;authentication=ActiveDirectoryPassword
|
||||||
|
|
||||||
|
// test sql server
|
||||||
|
DATABASE_URL = sqlserver://sql-srv-plt-pedw-test-uks-01.database.windows.net:1433;database=PEDW;user=PedwSqlAdmin;password=GhWKr62F5sQ69dZx;encrypt=true;trustServerCertificate=true;hostNameInCertificate=*.database.windows.net;loginTimeout=30;authentication=ActiveDirectoryPassword
|
||||||
|
|
||||||
|
|
||||||
// Pre prod sql server
|
// Pre prod sql server
|
||||||
DATABASE_URL = sqlserver://sql-srv-plt-pedw-ppe-uks-01.database.windows.net:1433;database=PEDW;user=PedwSqlAdmin;password=GhWKr62F5sQ69dZx;encrypt=true;trustservercertificate=true;hostnameincertificate=*.database.windows.net;logintimeout=30;authentication=SqlPassword
|
# DATABASE_URL = sqlserver://sql-srv-plt-pedw-ppe-uks-01.database.windows.net:1433;database=PEDW;user=PedwSqlAdmin;password=GhWKr62F5sQ69dZx;encrypt=true;trustservercertificate=true;hostnameincertificate=*.database.windows.net;logintimeout=30;authentication=SqlPassword
|
||||||
|
|
||||||
// Prod sql server
|
// Prod sql server
|
||||||
# DATABASE_URL = sqlserver://pp-pedw-sql.database.windows.net:1433;database=PEDWPreProd;user=RobBondSQL;password=GhWKr62F5sQ69dZx;encrypt=true;trustServerCertificate=true;hostNameInCertificate=*.database.windows.net;loginTimeout=30;authentication=ActiveDirectoryPassword
|
# DATABASE_URL = sqlserver://pp-pedw-sql.database.windows.net:1433;database=PEDWPreProd;user=RobBondSQL;password=GhWKr62F5sQ69dZx;encrypt=true;trustServerCertificate=true;hostNameInCertificate=*.database.windows.net;loginTimeout=30;authentication=ActiveDirectoryPassword
|
||||||
|
|
||||||
|
// Prod sql server
|
||||||
|
# DATABASE_URL = sqlserver://sql-srv-plt-pedw-prod-uks-01.database.windows.net:1433;database=PEDW;user=PedwSqlAdmin;password=GhWKr62F5sQ69dZx;encrypt=true;trustServerCertificate=true;hostNameInCertificate=*.database.windows.net;loginTimeout=30;authentication=ActiveDirectoryPassword
|
||||||
|
|
||||||
|
// D365 CNR sql server
|
||||||
|
# DATABASE_URL = sqlserver://sql-srv-plt-pedw-d365cnr-uks-01.database.windows.net:1433;database=PEDW;user=PedwSqlAdmin;password=GhWKr62F5sQ69dZx;encrypt=true;trustServerCertificate=true;hostNameInCertificate=*.database.windows.net;loginTimeout=30;authentication=ActiveDirectoryPassword
|
||||||
|
|
||||||
|
// D365 Test sql server
|
||||||
|
# DATABASE_URL = sqlserver://sql-srv-plt-pedw-d365test-uks-01.database.windows.net:1433;database=PEDW;user=PedwSqlAdmin;password=GhWKr62F5sQ69dZx;encrypt=true;trustServerCertificate=true;hostNameInCertificate=*.database.windows.net;loginTimeout=30;authentication=ActiveDirectoryPassword
|
||||||
|
|
||||||
|
|
||||||
|
// D365 PPE sql server
|
||||||
|
# DATABASE_URL = sqlserver://sql-srv-plt-pedw-d365ppe-uks-01.database.windows.net:1433;database=PEDW;user=PedwSqlAdmin;password=GhWKr62F5sQ69dZx;encrypt=true;trustServerCertificate=true;hostNameInCertificate=*.database.windows.net;loginTimeout=30;authentication=ActiveDirectoryPassword
|
||||||
|
|
||||||
|
|
||||||
SECRET = SuperSecret
|
SECRET = SuperSecret
|
||||||
|
|
||||||
@@ -91,24 +163,24 @@ AZURE_TENANT_ID = $TENANT
|
|||||||
AZURE_CLIENT_SECRET = $CLIENT_SECRET
|
AZURE_CLIENT_SECRET = $CLIENT_SECRET
|
||||||
|
|
||||||
// CNR key
|
// CNR key
|
||||||
# AZURE_STORAGE_ACCOUNT_NAME = "sapltpedwcnruks"
|
AZURE_STORAGE_ACCOUNT_NAME = "sapltpedwcnruks"
|
||||||
# AZURE_STORAGE_ACCOUNT_KEY = hRffHq4IwctpaTKdS/U33Xq6nyTDF1t++WJgIwsw7gzstktZin/rRwbTIAL9KKqesVsK7EHrTTG6+ASt4+7skw==
|
AZURE_STORAGE_ACCOUNT_KEY = hRffHq4IwctpaTKdS/U33Xq6nyTDF1t++WJgIwsw7gzstktZin/rRwbTIAL9KKqesVsK7EHrTTG6+ASt4+7skw==
|
||||||
# AZURE_PEDW_STORAGE_ENDPOINT = https://sapltpedwcnruks.blob.core.windows.net
|
AZURE_PEDW_STORAGE_ENDPOINT = https://sapltpedwcnruks.blob.core.windows.net
|
||||||
|
|
||||||
// new dev key
|
// new dev key
|
||||||
# AZURE_STORAGE_ACCOUNT_NAME = "sapltpedwdevuks"
|
AZURE_STORAGE_ACCOUNT_NAME = "sapltpedwdevuks"
|
||||||
# AZURE_STORAGE_ACCOUNT_KEY = MmrsrCjBfop9pI2oImsP/+lJUWU2DrXsAB8nq5bOVROTmPovSGxjCjKw9+TAFr00k8WDUK9r6mVx+AStcMLyAA==
|
AZURE_STORAGE_ACCOUNT_KEY = MmrsrCjBfop9pI2oImsP/+lJUWU2DrXsAB8nq5bOVROTmPovSGxjCjKw9+TAFr00k8WDUK9r6mVx+AStcMLyAA==
|
||||||
# AZURE_PEDW_STORAGE_ENDPOINT = https://sapltpedwdevuks.blob.core.windows.net
|
AZURE_PEDW_STORAGE_ENDPOINT = https://sapltpedwdevuks.blob.core.windows.net
|
||||||
|
|
||||||
// New test key
|
// New test key
|
||||||
# AZURE_STORAGE_ACCOUNT_NAME = "sapltpedwtestuks"
|
# AZURE_STORAGE_ACCOUNT_NAME = "sapltpedwtestuks"
|
||||||
# AZURE_STORAGE_ACCOUNT_KEY = bqJAz5pYQVGee8dnVhlsqW+xHwinNTjgY2AmojNyB+d4uAotMR20WcO4Op13yB+9dFaXAkkjtIA4+AStHT/IYg==
|
# AZURE_STORAGE_ACCOUNT_KEY = 5NdDO9GGlbTFLHFOXZRw8H2C0Ow5bFTvHwUHEbStyzg2mbd1uwHSeBSvM/dkN+HfdwrFzqAkwL5P+AStdO6cig==
|
||||||
# AZURE_PEDW_STORAGE_ENDPOINT = https://sapltpedwtestuks.blob.core.windows.net
|
# AZURE_PEDW_STORAGE_ENDPOINT = https://sapltpedwtestuks.blob.core.windows.net
|
||||||
|
|
||||||
// New preprod key
|
// New preprod key
|
||||||
AZURE_STORAGE_ACCOUNT_NAME = "sapltpedwppeuks"
|
# AZURE_STORAGE_ACCOUNT_NAME = "sapltpedwppeuks"
|
||||||
AZURE_STORAGE_ACCOUNT_KEY = B4GRKr+cA9b9mNM/GHFivzhzflJIZltG8bMmooXlYvGYySPAspTTHistAT30sHipnR+hh6dqUc9q+ASttAjPRQ==
|
# AZURE_STORAGE_ACCOUNT_KEY = B4GRKr+cA9b9mNM/GHFivzhzflJIZltG8bMmooXlYvGYySPAspTTHistAT30sHipnR+hh6dqUc9q+ASttAjPRQ==
|
||||||
AZURE_PEDW_STORAGE_ENDPOINT = https://sapltpedwppeuks.blob.core.windows.net
|
# AZURE_PEDW_STORAGE_ENDPOINT = https://sapltpedwppeuks.blob.core.windows.net
|
||||||
|
|
||||||
|
|
||||||
// PROD key
|
// PROD key
|
||||||
@@ -116,6 +188,34 @@ AZURE_PEDW_STORAGE_ENDPOINT = https://sapltpedwppeuks.blob.core.windows.net
|
|||||||
# AZURE_STORAGE_ACCOUNT_KEY = koZ46STRqapSa2Dod8MLL6aju1eYLhhyJ6DXpCLMTnFLJvbDT6CHUv/jwr5U/Ta8a60MWzwToHQy+AStADO7sg==
|
# AZURE_STORAGE_ACCOUNT_KEY = koZ46STRqapSa2Dod8MLL6aju1eYLhhyJ6DXpCLMTnFLJvbDT6CHUv/jwr5U/Ta8a60MWzwToHQy+AStADO7sg==
|
||||||
# AZURE_PEDW_STORAGE_ENDPOINT = https://pedwprod.blob.core.windows.net
|
# AZURE_PEDW_STORAGE_ENDPOINT = https://pedwprod.blob.core.windows.net
|
||||||
|
|
||||||
|
# // New PROD key
|
||||||
|
# AZURE_STORAGE_ACCOUNT_NAME = "sapltpedwproduks"
|
||||||
|
# AZURE_STORAGE_ACCOUNT_KEY = OfV9MFqXcLLPam9GhEdMWadIOwIzhc5hd5TUqzIuQoswFdtV4ybaemjatSv+Kht0Ny1qQKjLplwY+AStUTZJrg==
|
||||||
|
# AZURE_PEDW_STORAGE_ENDPOINT = https://sapltpedwproduks.blob.core.windows.net
|
||||||
|
|
||||||
|
# D365 CNR key
|
||||||
|
# AZURE_STORAGE_ACCOUNT_NAME = "sapltpedwd365cnruks"
|
||||||
|
# AZURE_STORAGE_ACCOUNT_KEY = nEwCp+4FuVf/9a4DOyKuQO2yRRV4Ypigg20ch1YaiL09YmEhWMEO5pNLpYtI3WnQCkIqeu1CUqwM+AStCLW01g==
|
||||||
|
# AZURE_PEDW_STORAGE_ENDPOINT = https://sapltpedwd365cnruks.blob.core.windows.net
|
||||||
|
|
||||||
|
|
||||||
|
# D365 DEV key
|
||||||
|
# AZURE_STORAGE_ACCOUNT_NAME = "sapltpedwd365devuks"
|
||||||
|
# AZURE_STORAGE_ACCOUNT_KEY = XzwQxuZXSwYrVgemDUD2ymTpYTIfWqhypbmEALw1ZEEP0M4D3b3Gh28clSymxwFu7Gu9mhwkW4/V+AStZ6RF8Q==
|
||||||
|
# AZURE_PEDW_STORAGE_ENDPOINT = https://sapltpedwd365devuks.blob.core.windows.net
|
||||||
|
|
||||||
|
|
||||||
|
# D365 TEST key
|
||||||
|
# AZURE_STORAGE_ACCOUNT_NAME = "sapltpedwd365testuks"
|
||||||
|
# AZURE_STORAGE_ACCOUNT_KEY = 5NdDO9GGlbTFLHFOXZRw8H2C0Ow5bFTvHwUHEbStyzg2mbd1uwHSeBSvM/dkN+HfdwrFzqAkwL5P+AStdO6cig==
|
||||||
|
# AZURE_PEDW_STORAGE_ENDPOINT = https://sapltpedwd365testuks.blob.core.windows.net
|
||||||
|
|
||||||
|
|
||||||
|
# D365 PP key
|
||||||
|
# AZURE_STORAGE_ACCOUNT_NAME = "sapltpedwd365ppeuks"
|
||||||
|
# AZURE_STORAGE_ACCOUNT_KEY = xQz4FWDnQDE09uPOCj1t7axRiquvZG9vbxL88ywzVsJnTsAgewrHnuAGkxGPBCp2xGE53ffYOme6+AStSr8OoQ==
|
||||||
|
# AZURE_PEDW_STORAGE_ENDPOINT = https://sapltpedwd365ppeuks.blob.core.windows.net
|
||||||
|
|
||||||
|
|
||||||
AZURE_PEDW_CONTAINER = "pedwapplications"
|
AZURE_PEDW_CONTAINER = "pedwapplications"
|
||||||
AZURE_PEDW_QUEUE_ENDPOINT = https://$AZURE_STORAGE_ACCOUNT_NAME.queue.core.windows.net
|
AZURE_PEDW_QUEUE_ENDPOINT = https://$AZURE_STORAGE_ACCOUNT_NAME.queue.core.windows.net
|
||||||
@@ -147,3 +247,7 @@ NEXT_PUBLIC_APP_INSIGHT = InstrumentationKey=a41b91bf-f7dc-4f44-bb66-a67df4eee43
|
|||||||
|
|
||||||
|
|
||||||
HIDEERRORLOGS = false
|
HIDEERRORLOGS = false
|
||||||
|
|
||||||
|
SHOWSIPS = true
|
||||||
|
|
||||||
|
ALLOWED_IPS=::1,203.0.113.42,198.51.100.17
|
||||||
|
|||||||
+3
-3
@@ -45,6 +45,6 @@ public/swagger.json
|
|||||||
certificates/cert-key.pem
|
certificates/cert-key.pem
|
||||||
certificates/cert.pem
|
certificates/cert.pem
|
||||||
gitclean.sh
|
gitclean.sh
|
||||||
|
pages/admin/logcheck.js
|
||||||
dockerfile
|
pages/admin/logchecker.js
|
||||||
Jenkinsfile
|
pages/baracuda.html
|
||||||
|
|||||||
+124
-29
@@ -210,31 +210,31 @@ export const getBlobs = async (containerName, casefolderID) => {
|
|||||||
"/api/file/downloadblob?container=" +
|
"/api/file/downloadblob?container=" +
|
||||||
containerName +
|
containerName +
|
||||||
"&casefolderID=" +
|
"&casefolderID=" +
|
||||||
casefolderID +
|
encodeURIComponent(casefolderID) +
|
||||||
"&blobname=" +
|
"&blobname=" +
|
||||||
blob.name,
|
encodeURIComponent(blob.name),
|
||||||
"hashedfilepath": hashAPIPath(
|
"hashedfilepath": hashAPIPath(
|
||||||
"/api/file/downloadblob?container=" +
|
"/api/file/downloadblob?container=" +
|
||||||
containerName +
|
containerName +
|
||||||
"&casefolderID=" +
|
"&casefolderID=" +
|
||||||
casefolderID +
|
encodeURIComponent(casefolderID) +
|
||||||
"&blobname=" +
|
"&blobname=" +
|
||||||
blob.name.split("/")[2]
|
encodeURIComponent(blob.name.split("/")[2])
|
||||||
),
|
),
|
||||||
"deletepath":
|
"deletepath":
|
||||||
"/api/file/deleteblob?container=" +
|
"/api/file/deleteblob?container=" +
|
||||||
containerName +
|
containerName +
|
||||||
"&casefolderID=" +
|
"&casefolderID=" +
|
||||||
casefolderID +
|
encodeURIComponent(casefolderID) +
|
||||||
"&blobname=" +
|
"&blobname=" +
|
||||||
blob.name.split("/")[2],
|
encodeURIComponent(blob.name.split("/")[2]),
|
||||||
"hasheddeletepath": hashAPIPath(
|
"hasheddeletepath": hashAPIPath(
|
||||||
"/api/file/deleteblob?container=" +
|
"/api/file/deleteblob?container=" +
|
||||||
containerName +
|
containerName +
|
||||||
"&casefolderID=" +
|
"&casefolderID=" +
|
||||||
casefolderID +
|
encodeURIComponent(casefolderID) +
|
||||||
"&blobname=" +
|
"&blobname=" +
|
||||||
blob.name.split("/")[2]
|
encodeURIComponent(blob.name.split("/")[2])
|
||||||
),
|
),
|
||||||
"hashgetblobs": hashAPIPath(
|
"hashgetblobs": hashAPIPath(
|
||||||
"/api/file/getbloblist?container=" +
|
"/api/file/getbloblist?container=" +
|
||||||
@@ -309,7 +309,7 @@ export const createRepBlob = async (formContent, containerName, caseref) => {
|
|||||||
|
|
||||||
const tags = {
|
const tags = {
|
||||||
containerid: containerName,
|
containerid: containerName,
|
||||||
caseID: formContent.caseRef,
|
caseID: formContent.ticketnumber,
|
||||||
blobType: "Representation",
|
blobType: "Representation",
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -317,7 +317,7 @@ export const createRepBlob = async (formContent, containerName, caseref) => {
|
|||||||
const withTags = await blockBlobClient.setTags(tags);
|
const withTags = await blockBlobClient.setTags(tags);
|
||||||
const withMeta = await blockBlobClient.setMetadata(tags);
|
const withMeta = await blockBlobClient.setMetadata(tags);
|
||||||
|
|
||||||
return formContent.pinswg_name;
|
return formContent.ticketnumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createAppealPDFBlob = async (
|
export const createAppealPDFBlob = async (
|
||||||
@@ -432,7 +432,6 @@ export const createRepPDFBlob = async (
|
|||||||
containerid: containerName,
|
containerid: containerName,
|
||||||
caseID: caseID,
|
caseID: caseID,
|
||||||
blobType: "Representation PDF",
|
blobType: "Representation PDF",
|
||||||
documentLocationId: whichLocation,
|
|
||||||
ishareLocation: whichLocation,
|
ishareLocation: whichLocation,
|
||||||
documentLocationId: whichLocation,
|
documentLocationId: whichLocation,
|
||||||
};
|
};
|
||||||
@@ -624,7 +623,6 @@ export const uploadFile = async (formContent, containerName, foldername) => {
|
|||||||
caseID: foldername.split("/")[0],
|
caseID: foldername.split("/")[0],
|
||||||
documentType: files[prop][0].fieldName.split(".")[1],
|
documentType: files[prop][0].fieldName.split(".")[1],
|
||||||
blobType: "RepresentationFile",
|
blobType: "RepresentationFile",
|
||||||
documentLocationId: whichLocation,
|
|
||||||
ishareLocation: whichLocation,
|
ishareLocation: whichLocation,
|
||||||
documentLocationId: whichLocation,
|
documentLocationId: whichLocation,
|
||||||
};
|
};
|
||||||
@@ -1244,17 +1242,17 @@ export const getProgressBlobs = async (containerName, caseReference) => {
|
|||||||
"/api/file/downloadblob?container=" +
|
"/api/file/downloadblob?container=" +
|
||||||
containerName +
|
containerName +
|
||||||
"&casefolderID=" +
|
"&casefolderID=" +
|
||||||
caseReference +
|
encodeURIComponent(caseReference) +
|
||||||
"&blobname=" +
|
"&blobname=" +
|
||||||
blob.name.split("/")[1]
|
encodeURIComponent(blob.name.split("/")[1])
|
||||||
),
|
),
|
||||||
"hasheddeletepath": hashAPIPath(
|
"hasheddeletepath": hashAPIPath(
|
||||||
"/api/file/deleteblob?container=" +
|
"/api/file/deleteblob?container=" +
|
||||||
containerName +
|
containerName +
|
||||||
"&casefolderID=" +
|
"&casefolderID=" +
|
||||||
caseReference +
|
encodeURIComponent(caseReference) +
|
||||||
"&blobname=" +
|
"&blobname=" +
|
||||||
blob.name.split("/")[1]
|
encodeURIComponent(blob.name.split("/")[1])
|
||||||
),
|
),
|
||||||
"hashgetblobs": hashAPIPath(
|
"hashgetblobs": hashAPIPath(
|
||||||
"/api/file/getbloblist?container=" +
|
"/api/file/getbloblist?container=" +
|
||||||
@@ -1415,20 +1413,20 @@ export const getRepsFilesBlobs = async (
|
|||||||
"/api/file/downloadblob?container=" +
|
"/api/file/downloadblob?container=" +
|
||||||
containerName +
|
containerName +
|
||||||
"&casefolderID=" +
|
"&casefolderID=" +
|
||||||
blob.name.split("/")[0] +
|
encodeURIComponent(
|
||||||
"/" +
|
blob.name.split("/")[0] + "/" + blob.name.split("/")[1]
|
||||||
blob.name.split("/")[1] +
|
) +
|
||||||
"&blobname=" +
|
"&blobname=" +
|
||||||
blob.name.split("/")[3],
|
encodeURIComponent(blob.name.split("/")[3]),
|
||||||
"hashedfilepath": hashAPIPath(
|
"hashedfilepath": hashAPIPath(
|
||||||
"/api/file/downloadblob?container=" +
|
"/api/file/downloadblob?container=" +
|
||||||
containerName +
|
containerName +
|
||||||
"&casefolderID=" +
|
"&casefolderID=" +
|
||||||
blob.name.split("/")[0] +
|
encodeURIComponent(
|
||||||
"/" +
|
blob.name.split("/")[0] + "/" + blob.name.split("/")[1]
|
||||||
blob.name.split("/")[1] +
|
) +
|
||||||
"&blobname=" +
|
"&blobname=" +
|
||||||
blob.name
|
encodeURIComponent(blob.name.split("/")[3])
|
||||||
),
|
),
|
||||||
"deletepath":
|
"deletepath":
|
||||||
"/api/file/deleteblob?container=" +
|
"/api/file/deleteblob?container=" +
|
||||||
@@ -1443,11 +1441,11 @@ export const getRepsFilesBlobs = async (
|
|||||||
"/api/file/deleteblob?container=" +
|
"/api/file/deleteblob?container=" +
|
||||||
containerName +
|
containerName +
|
||||||
"&casefolderID=" +
|
"&casefolderID=" +
|
||||||
blob.name.split("/")[0] +
|
encodeURIComponent(
|
||||||
"/" +
|
blob.name.split("/")[0] + "/" + blob.name.split("/")[1]
|
||||||
blob.name.split("/")[1] +
|
) +
|
||||||
"&blobname=" +
|
"&blobname=" +
|
||||||
blob.name.split("/")[3]
|
encodeURIComponent(blob.name.split("/")[3])
|
||||||
),
|
),
|
||||||
"hashgetblobs": hashAPIPath(
|
"hashgetblobs": hashAPIPath(
|
||||||
"/api/file/getbloblist?container=" +
|
"/api/file/getbloblist?container=" +
|
||||||
@@ -1459,7 +1457,7 @@ export const getRepsFilesBlobs = async (
|
|||||||
),
|
),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//console.log("blobObj:", blobObj);
|
console.log("blobObj:", blobObj);
|
||||||
|
|
||||||
return blobObj;
|
return blobObj;
|
||||||
};
|
};
|
||||||
@@ -1702,3 +1700,100 @@ export const listBlobHierarchical = async (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function formatTimeSince(date) {
|
||||||
|
if (!date) return "Unknown date";
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
const diffMs = now - date;
|
||||||
|
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
||||||
|
|
||||||
|
if (diffDays < 7) {
|
||||||
|
return `${diffDays} day${diffDays !== 1 ? "s" : ""} ago`;
|
||||||
|
} else {
|
||||||
|
const diffWeeks = Math.floor(diffDays / 7);
|
||||||
|
return `${diffWeeks} week${diffWeeks !== 1 ? "s" : ""} ago`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDateDisplay(date) {
|
||||||
|
return date
|
||||||
|
? `${date.toLocaleString("en-GB")} (${formatTimeSince(date)})`
|
||||||
|
: "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listBlobHierarchicalForUser(containerClient) {
|
||||||
|
const blobNames = [];
|
||||||
|
for await (const blob of containerClient.listBlobsFlat()) {
|
||||||
|
const lastModifiedDate = blob.properties?.lastModified || null;
|
||||||
|
const createdOnDate = blob.properties?.createdOn || null;
|
||||||
|
|
||||||
|
let displayDate = "";
|
||||||
|
|
||||||
|
if (createdOnDate && lastModifiedDate) {
|
||||||
|
if (
|
||||||
|
createdOnDate.toDateString() === lastModifiedDate.toDateString()
|
||||||
|
) {
|
||||||
|
// Same day — show just one
|
||||||
|
displayDate = `Date: ${formatDateDisplay(lastModifiedDate)}`;
|
||||||
|
} else {
|
||||||
|
// Different days — show both
|
||||||
|
displayDate = `Created: ${formatDateDisplay(
|
||||||
|
createdOnDate
|
||||||
|
)}, Modified: ${formatDateDisplay(lastModifiedDate)}`;
|
||||||
|
}
|
||||||
|
} else if (lastModifiedDate) {
|
||||||
|
displayDate = `Modified: ${formatDateDisplay(lastModifiedDate)}`;
|
||||||
|
} else if (createdOnDate) {
|
||||||
|
displayDate = `Created: ${formatDateDisplay(createdOnDate)}`;
|
||||||
|
} else {
|
||||||
|
displayDate = "Unknown date";
|
||||||
|
}
|
||||||
|
|
||||||
|
blobNames.push({
|
||||||
|
name: blob.name,
|
||||||
|
size: blob.properties.contentLength || 0,
|
||||||
|
lastModified: lastModifiedDate
|
||||||
|
? lastModifiedDate.toISOString()
|
||||||
|
: null,
|
||||||
|
createdOn: createdOnDate ? createdOnDate.toISOString() : null,
|
||||||
|
displayDate,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return blobNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listContainersForUser(
|
||||||
|
blobServiceClient,
|
||||||
|
containerNamePrefix,
|
||||||
|
emailAddress
|
||||||
|
) {
|
||||||
|
const options = {
|
||||||
|
includeDeleted: false,
|
||||||
|
includeMetadata: true,
|
||||||
|
includeSystem: true,
|
||||||
|
prefix: containerNamePrefix,
|
||||||
|
};
|
||||||
|
|
||||||
|
const results = [];
|
||||||
|
|
||||||
|
for await (const containerItem of blobServiceClient.listContainers(
|
||||||
|
options
|
||||||
|
)) {
|
||||||
|
const containerClient = blobServiceClient.getContainerClient(
|
||||||
|
containerItem.name
|
||||||
|
);
|
||||||
|
const blobNames = await listBlobHierarchicalForUser(
|
||||||
|
containerClient
|
||||||
|
).catch(console.error);
|
||||||
|
|
||||||
|
if (blobNames && blobNames.length > 0) {
|
||||||
|
results.push({
|
||||||
|
container: containerItem.name,
|
||||||
|
blobs: blobNames,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results; // array of non-empty containers
|
||||||
|
}
|
||||||
|
|||||||
+154
-38
@@ -389,7 +389,7 @@ export const getDNSCoords = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDNSList = async (searchString) => {
|
export const getDNSList = (searchString) => {
|
||||||
return axios
|
return axios
|
||||||
.get(BASE_URL + "/api/endpoint/getdnslist_api")
|
.get(BASE_URL + "/api/endpoint/getdnslist_api")
|
||||||
.then((res) => res.data)
|
.then((res) => res.data)
|
||||||
@@ -544,23 +544,42 @@ export const getBasicSearchDetailsPaged = async (
|
|||||||
appealTypeName,
|
appealTypeName,
|
||||||
caseReference,
|
caseReference,
|
||||||
primaryIdAttribute,
|
primaryIdAttribute,
|
||||||
incidentID
|
incidentIDs
|
||||||
) => {
|
) => {
|
||||||
//console.log("check appealtype:", appealType, caseReference);
|
if (!incidentIDs || incidentIDs.length === 0) return [];
|
||||||
|
|
||||||
return axios
|
console.log("=======", primaryIdAttribute);
|
||||||
.get(
|
// Build OData filter correctly
|
||||||
"/api/endpoint/getbasicsearchdetailspaged_api?appealTypeName=" +
|
// const filter = incidentIDs
|
||||||
appealTypeName +
|
// .map((id) => `_${primaryIdAttribute}s_value eq ${id}`)
|
||||||
"&primaryIdAttribute=" +
|
// .join(" or ");
|
||||||
primaryIdAttribute +
|
|
||||||
"&incidentID=" +
|
const filter = incidentIDs
|
||||||
incidentID
|
.map((id) => {
|
||||||
)
|
const suffix =
|
||||||
.then((res) => res.data)
|
primaryIdAttribute === "pinswg_sipscase"
|
||||||
.catch((error) => {
|
? `_${primaryIdAttribute}_value`
|
||||||
consoleLogger(error);
|
: `_${primaryIdAttribute}s_value`;
|
||||||
});
|
|
||||||
|
return `${suffix} eq ${id}`;
|
||||||
|
})
|
||||||
|
.join(" or ");
|
||||||
|
|
||||||
|
const url = `/api/endpoint/getbasicsearchdetailspaged_api?appealTypeName=${appealTypeName}&primaryIdAttribute=${primaryIdAttribute}&incidentID=${encodeURIComponent(
|
||||||
|
filter
|
||||||
|
)}`;
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`Fetching ${incidentIDs.length} incidents for appeal type: ${appealTypeName}`
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await axios.get(url);
|
||||||
|
return res.data.value || []; // ensure returning an array
|
||||||
|
} catch (error) {
|
||||||
|
consoleLogger(error);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSearchDocumentDetails = (incidentID) => {
|
export const getSearchDocumentDetails = (incidentID) => {
|
||||||
@@ -828,6 +847,19 @@ export const getMyCases = (loggedInUserId) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getMyInvolvements = async (loggedInUserId) => {
|
||||||
|
try {
|
||||||
|
const res = await axios.get(
|
||||||
|
BASE_URL +
|
||||||
|
"/api/endpoint/getmyinvolvements_api?loggedInUserId=" +
|
||||||
|
loggedInUserId
|
||||||
|
);
|
||||||
|
return res.data;
|
||||||
|
} catch (error) {
|
||||||
|
consoleLogger(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const getMyLPACases = (lpaid) => {
|
export const getMyLPACases = (lpaid) => {
|
||||||
return axios
|
return axios
|
||||||
.get(BASE_URL + "/api/endpoint/getmylpacases_api?lpaid=" + lpaid)
|
.get(BASE_URL + "/api/endpoint/getmylpacases_api?lpaid=" + lpaid)
|
||||||
@@ -1492,23 +1524,20 @@ export const deleteMyRepresentationsFromBlob = (
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const deleteWatchedCases = (watchedCaseID) => {
|
export const deleteWatchedCases = async (watchedCaseID) => {
|
||||||
var queryUrl =
|
var queryUrl =
|
||||||
"/api/endpoint/deletewatchedcasesproxy_api?watchedCaseID=" +
|
"/api/endpoint/deletewatchedcases_api?watchedCaseID=" + watchedCaseID;
|
||||||
watchedCaseID;
|
|
||||||
var config = {
|
var config = {
|
||||||
method: "get",
|
method: "delete",
|
||||||
url: queryUrl,
|
url: queryUrl,
|
||||||
};
|
};
|
||||||
|
|
||||||
return axios(config)
|
try {
|
||||||
.then((res) => {
|
const res = await axios(config);
|
||||||
//console.log("deleted ", res.data);
|
return res.data;
|
||||||
return res.data;
|
} catch (error) {
|
||||||
})
|
consoleLogger(error);
|
||||||
.catch((error) => {
|
}
|
||||||
consoleLogger(error);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createAccount = (formValues) => {
|
export const createAccount = (formValues) => {
|
||||||
@@ -1813,9 +1842,9 @@ export const deleteBlob = async (
|
|||||||
"/api/file/deleteblob?container=" +
|
"/api/file/deleteblob?container=" +
|
||||||
containerName +
|
containerName +
|
||||||
"&casefolderID=" +
|
"&casefolderID=" +
|
||||||
casefolderID +
|
encodeURIComponent(casefolderID) +
|
||||||
"&blobname=" +
|
"&blobname=" +
|
||||||
blobName +
|
encodeURIComponent(blobName) +
|
||||||
deleteblobhash
|
deleteblobhash
|
||||||
);
|
);
|
||||||
return res.data;
|
return res.data;
|
||||||
@@ -1836,11 +1865,9 @@ export const deleteRepBlob = async (
|
|||||||
"/api/file/deleteblob?container=" +
|
"/api/file/deleteblob?container=" +
|
||||||
containerName +
|
containerName +
|
||||||
"&casefolderID=" +
|
"&casefolderID=" +
|
||||||
casefolderID +
|
encodeURIComponent(casefolderID + "/" + filenamePrefix) +
|
||||||
"/" +
|
|
||||||
filenamePrefix +
|
|
||||||
"&blobname=" +
|
"&blobname=" +
|
||||||
blobName +
|
encodeURIComponent(blobName) +
|
||||||
deleteblobhash
|
deleteblobhash
|
||||||
);
|
);
|
||||||
return res.data;
|
return res.data;
|
||||||
@@ -1894,14 +1921,14 @@ export const getProgressFromBlob = async (containerName, casereference) => {
|
|||||||
const res = await axios.get(
|
const res = await axios.get(
|
||||||
BASE_URL +
|
BASE_URL +
|
||||||
"/api/file/getprogressobjblob?container=" +
|
"/api/file/getprogressobjblob?container=" +
|
||||||
containerName +
|
encodeURIComponent(containerName) +
|
||||||
"&casefolderID=" +
|
"&casefolderID=" +
|
||||||
casereference +
|
encodeURIComponent(casereference) +
|
||||||
hashAPIPath(
|
hashAPIPath(
|
||||||
"/api/file/getprogressobjblob?container=" +
|
"/api/file/getprogressobjblob?container=" +
|
||||||
containerName +
|
encodeURIComponent(containerName) +
|
||||||
"&casefolderID=" +
|
"&casefolderID=" +
|
||||||
casereference
|
encodeURIComponent(casereference)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
return res.data;
|
return res.data;
|
||||||
@@ -2209,3 +2236,92 @@ export const getAppealPDFDocument = async (incidentid) => {
|
|||||||
return error.response;
|
return error.response;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
export const getNewAppeals = async (searchString) => {
|
||||||
|
try {
|
||||||
|
const res = await axios.get(BASE_URL + "/api/admin/getnewappeals_api");
|
||||||
|
return res.data;
|
||||||
|
} catch (error) {
|
||||||
|
consoleLogger(error);
|
||||||
|
return error.response;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getNewAppealsPage = async (
|
||||||
|
searchString,
|
||||||
|
pageNumber,
|
||||||
|
orderBy,
|
||||||
|
fieldSort,
|
||||||
|
showNumberOfRecords
|
||||||
|
) => {
|
||||||
|
return axios
|
||||||
|
.get(
|
||||||
|
"/api/admin/getnewappeals_api?searchString=" +
|
||||||
|
searchString +
|
||||||
|
"&pageNumber=" +
|
||||||
|
pageNumber +
|
||||||
|
"&orderby=" +
|
||||||
|
orderBy +
|
||||||
|
"&fieldSort=" +
|
||||||
|
fieldSort +
|
||||||
|
"&showNumberOfRecords=" +
|
||||||
|
showNumberOfRecords
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
|
return res.data;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
consoleLogger(error);
|
||||||
|
return error.response;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getNewDocumentsPaged = async (
|
||||||
|
pageNumber,
|
||||||
|
orderBy,
|
||||||
|
fieldSort,
|
||||||
|
showNumberOfRecords,
|
||||||
|
documentType,
|
||||||
|
documentOrigin,
|
||||||
|
selectedWeeks
|
||||||
|
) => {
|
||||||
|
console.log(
|
||||||
|
"/api/admin/getlatestdocuments_api?pageNumber=" +
|
||||||
|
pageNumber +
|
||||||
|
"&orderby=" +
|
||||||
|
orderBy +
|
||||||
|
"&fieldSort=" +
|
||||||
|
fieldSort +
|
||||||
|
"&showNumberOfRecords=" +
|
||||||
|
showNumberOfRecords +
|
||||||
|
"&documentType=" +
|
||||||
|
documentType +
|
||||||
|
"&numberWeeks=" +
|
||||||
|
selectedWeeks +
|
||||||
|
"&documentOrigin=" +
|
||||||
|
documentOrigin
|
||||||
|
);
|
||||||
|
return axios
|
||||||
|
.get(
|
||||||
|
"/api/admin/getlatestdocuments_api?pageNumber=" +
|
||||||
|
pageNumber +
|
||||||
|
"&orderby=" +
|
||||||
|
orderBy +
|
||||||
|
"&fieldSort=" +
|
||||||
|
fieldSort +
|
||||||
|
"&showNumberOfRecords=" +
|
||||||
|
showNumberOfRecords +
|
||||||
|
"&documentType=" +
|
||||||
|
documentType +
|
||||||
|
"&numberWeeks=" +
|
||||||
|
selectedWeeks +
|
||||||
|
"&documentOrigin=" +
|
||||||
|
documentOrigin
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
|
return res.data;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
consoleLogger(error);
|
||||||
|
return error.response;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ export const getSelectQuery = (appealTypeName) => {
|
|||||||
return "&$select=pinswg_detailedeiascreeningrequired,pinswg_speacialistcaseprocess,modifiedon,_pinswg_appellant_value,pinswg_name,pinswg_siteaddresscounty,pinswg_siteaddressline1,pinswg_siteaddressline2,pinswg_siteaddresspostcode,pinswg_siteaddresstown,_pinswg_associatedlpa_value,pinswg_casedecisiondate,pinswg_dateeventrequested,pinswg_decision,pinswg_procedure,pinswg_questionnaireduedate,statuscode,pinswg_startdateoftheevent,pinswg_typeofevent,pinswg_startdate,pinswg_otherpartiesstatement,pinswg_finalcommentsduedate,pinswg_proofsofevidencewrittenstatementsofeviden,pinswg_speacialistcaseprocess,pinswg_statementduedate";
|
return "&$select=pinswg_detailedeiascreeningrequired,pinswg_speacialistcaseprocess,modifiedon,_pinswg_appellant_value,pinswg_name,pinswg_siteaddresscounty,pinswg_siteaddressline1,pinswg_siteaddressline2,pinswg_siteaddresspostcode,pinswg_siteaddresstown,_pinswg_associatedlpa_value,pinswg_casedecisiondate,pinswg_dateeventrequested,pinswg_decision,pinswg_procedure,pinswg_questionnaireduedate,statuscode,pinswg_startdateoftheevent,pinswg_typeofevent,pinswg_startdate,pinswg_otherpartiesstatement,pinswg_finalcommentsduedate,pinswg_proofsofevidencewrittenstatementsofeviden,pinswg_speacialistcaseprocess,pinswg_statementduedate";
|
||||||
break;
|
break;
|
||||||
case "pinswg_callinss77s":
|
case "pinswg_callinss77s":
|
||||||
return "&$select=pinswg_eiarequired,modifiedon,_pinswg_appellant_value,pinswg_name,pinswg_siteaddresscounty,pinswg_siteaddressline1,pinswg_siteaddressline2,pinswg_siteaddresspostcode,pinswg_siteaddresstown,_pinswg_associatedlpa_value,pinswg_casedecisiondate,pinswg_dateeventrequested,pinswg_decision,pinswg_finalcommentsduedate,pinswg_procedure,pinswg_proofsofevidencewrittenstatementsofeviden,pinswg_questionnaireduedate,pinswg_startdate,statuscode,pinswg_dateexportedtoiss,pinswg_startdateofevent,pinswg_typeofevent,pinswg_statementsduedate";
|
return "&$select=pinswg_eiarequired,modifiedon,_pinswg_appellant_value,pinswg_name,pinswg_siteaddresscounty,pinswg_siteaddressline1,pinswg_siteaddressline2,pinswg_siteaddresspostcode,pinswg_siteaddresstown,_pinswg_associatedlpa_value,pinswg_casedecisiondate,pinswg_dateeventrequested,pinswg_decision,pinswg_finalcommentsduedate,pinswg_procedure,pinswg_proofsofevidencewrittenstatementsofeviden,pinswg_questionnaireduedate,pinswg_startdate,statuscode,pinswg_dateexportedtoiss,pinswg_startdateofevent,pinswg_typeofevent,pinswg_statementsduedate,pinswg_otherpartiesstatement";
|
||||||
break;
|
break;
|
||||||
case "pinswg_commonlands":
|
case "pinswg_commonlands":
|
||||||
return "&$select=pinswg_detailedeiascreeningrequired,modifiedon,_pinswg_appellant_value,pinswg_name,pinswg_siteaddresscounty,pinswg_siteaddressline1,pinswg_siteaddressline2,pinswg_siteaddresspostcode,pinswg_siteaddresstown,_pinswg_associatedlpa_value,pinswg_casedecisiondate,pinswg_dateeventrequested,pinswg_decision,pinswg_finalcommentsduedate,pinswg_otherpartiesstatement,pinswg_procedure,pinswg_proofsofevidencewrittenstatementsofeviden,pinswg_questionnaireduedate,pinswg_relevantauthorityname,pinswg_startdate,statuscode,pinswg_starttimeoftheevent,pinswg_typeofevent,pinswg_statementsduedate";
|
return "&$select=pinswg_detailedeiascreeningrequired,modifiedon,_pinswg_appellant_value,pinswg_name,pinswg_siteaddresscounty,pinswg_siteaddressline1,pinswg_siteaddressline2,pinswg_siteaddresspostcode,pinswg_siteaddresstown,_pinswg_associatedlpa_value,pinswg_casedecisiondate,pinswg_dateeventrequested,pinswg_decision,pinswg_finalcommentsduedate,pinswg_otherpartiesstatement,pinswg_procedure,pinswg_proofsofevidencewrittenstatementsofeviden,pinswg_questionnaireduedate,pinswg_relevantauthorityname,pinswg_startdate,statuscode,pinswg_starttimeoftheevent,pinswg_typeofevent,pinswg_statementsduedate";
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
// components/admin/tabs/AccountsTab.js
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
export default function AccountsTab({ userData }) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>User Accounts</h1>
|
||||||
|
<p>Number of accounts created: {userData.length}</p>
|
||||||
|
|
||||||
|
<dl className="govuk-summary-list govuk-!-margin-bottom-9 results">
|
||||||
|
<div className="govuk-summary-list__row results-headings">
|
||||||
|
<dd className="govuk-summary-list__key govuk-!-font-size-16">
|
||||||
|
Name
|
||||||
|
</dd>
|
||||||
|
<dd className="govuk-summary-list__key govuk-!-font-size-16">
|
||||||
|
Last accessed
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{userData.map((user) => (
|
||||||
|
<div key={user.id} className="govuk-summary-list__row">
|
||||||
|
<dd className="govuk-summary-list__value govuk-!-font-size-16 ">
|
||||||
|
<Link
|
||||||
|
target="_blank"
|
||||||
|
href={`/auth/signin2?email=${user.email}`}
|
||||||
|
>
|
||||||
|
{user.email}
|
||||||
|
</Link>
|
||||||
|
<br />
|
||||||
|
{user.id}
|
||||||
|
</dd>
|
||||||
|
<dd className="govuk-summary-list__value govuk-!-font-size-16 ">
|
||||||
|
Last accessed: {user.created}
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,568 @@
|
|||||||
|
// components/admin/tabs/AppealsTab.js
|
||||||
|
import useTranslation from "next-translate/useTranslation";
|
||||||
|
import { useCallback, useState, useEffect } from "react";
|
||||||
|
import { JSONPath as jsonpath } from "jsonpath-plus";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
import PaginationControl from "../../../components/search/pagination";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
|
||||||
|
import {
|
||||||
|
setSearchResults,
|
||||||
|
setSearchDetails,
|
||||||
|
} from "../../../store/searchOutput/action";
|
||||||
|
|
||||||
|
import { getDetailsProxy, getSearchDetailsPaged } from "../../utils";
|
||||||
|
import { getAdvancedSearchPaged, getNewAppealsPage } from "../../../actions";
|
||||||
|
import {
|
||||||
|
setCurrentPage,
|
||||||
|
setCurrentReference,
|
||||||
|
} from "../../../store/currentView/action";
|
||||||
|
|
||||||
|
function AppealsTab(props) {
|
||||||
|
const [searchLoaded, setSearchLoaded] = useState(false);
|
||||||
|
const [showSpinnerState, setShowSpinnerState] = useState(false);
|
||||||
|
const [selectedOption, setSelectedOption] = useState(10);
|
||||||
|
const [orderByState, setOrderbyState] = useState("createdon");
|
||||||
|
const [fieldSortState, setfieldSortState] = useState("desc");
|
||||||
|
const [loginToWatch, setLoginToWatch] = useState("true");
|
||||||
|
|
||||||
|
const searchDetailsObj = props.searchResultsObj.searchDetailsObj || {};
|
||||||
|
const resultsArr = props.searchResultsObj.searchResultsObj.value || [];
|
||||||
|
const searchResultsObj = props.searchResultsObj.searchResultsObj;
|
||||||
|
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const router = useRouter();
|
||||||
|
const myportal = false;
|
||||||
|
const advancedSearch = false;
|
||||||
|
const searchString = "";
|
||||||
|
|
||||||
|
const spinnerState = () => {
|
||||||
|
setShowSpinnerState((prev) => !prev);
|
||||||
|
};
|
||||||
|
|
||||||
|
const pagesCount = Math.ceil(searchResultsObj["@odata.count"] / 10);
|
||||||
|
|
||||||
|
let currentPage = 0;
|
||||||
|
try {
|
||||||
|
currentPage = decodeURI(searchResultsObj["@odata.nextLink"]).split(
|
||||||
|
"skiptoken="
|
||||||
|
)[1];
|
||||||
|
currentPage =
|
||||||
|
typeof currentPage !== "undefined"
|
||||||
|
? parseInt(
|
||||||
|
decodeURI(currentPage)
|
||||||
|
.split('pagenumber="')[1]
|
||||||
|
.slice(
|
||||||
|
0,
|
||||||
|
decodeURI(currentPage)
|
||||||
|
.split('pagenumber="')[1]
|
||||||
|
.indexOf('"')
|
||||||
|
) - 1
|
||||||
|
)
|
||||||
|
: pagesCount;
|
||||||
|
} catch (e) {
|
||||||
|
currentPage = pagesCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getSearchPageResults = useCallback(
|
||||||
|
(pageNumber, orderBy, fieldSort) => {
|
||||||
|
getNewAppealsPage(
|
||||||
|
searchString,
|
||||||
|
pageNumber,
|
||||||
|
orderBy,
|
||||||
|
fieldSort,
|
||||||
|
selectedOption
|
||||||
|
).then((data) => {
|
||||||
|
props.setSearchResults(data); // ✅ use props, not import
|
||||||
|
return getSearchDetailsPaged(data).then((details) => {
|
||||||
|
props.setSearchDetails(details); // ✅ use props, not import
|
||||||
|
setShowSpinnerState(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[
|
||||||
|
advancedSearch,
|
||||||
|
searchString,
|
||||||
|
selectedOption,
|
||||||
|
props.setSearchDetails,
|
||||||
|
props.setSearchResults,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (searchLoaded) {
|
||||||
|
if (selectedOption) {
|
||||||
|
setShowSpinnerState(true);
|
||||||
|
getSearchPageResults(1, orderByState, fieldSortState);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setSearchLoaded(true);
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
selectedOption,
|
||||||
|
fieldSortState,
|
||||||
|
orderByState,
|
||||||
|
searchLoaded,
|
||||||
|
getSearchPageResults,
|
||||||
|
router.query,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const ResultsView = (resultsArr) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<dl className="govuk-summary-list govuk-!-margin-bottom-9 results">
|
||||||
|
<div className="govuk-summary-list__row results-headings">
|
||||||
|
<dd className="govuk-summary-list__key govuk-!-font-size-16 results_wider ">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => sortDataBy("title")}
|
||||||
|
className={
|
||||||
|
orderByState == "title"
|
||||||
|
? fieldSortState == "asc"
|
||||||
|
? `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16 sortAsc`
|
||||||
|
: `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16 sortDesc`
|
||||||
|
: `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16`
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{t("search:searchresults-case-reference-label")}
|
||||||
|
</button>
|
||||||
|
</dd>
|
||||||
|
<dd className="govuk-summary-list__key govuk-!-font-size-16">
|
||||||
|
{t("search:searchresults-site-address-label")}
|
||||||
|
</dd>
|
||||||
|
<dd className="govuk-summary-list__key govuk-!-font-size-16">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => sortDataBy("_customerid_value")}
|
||||||
|
className={
|
||||||
|
orderByState == "_customerid_value"
|
||||||
|
? fieldSortState == "asc"
|
||||||
|
? `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16 sortAsc`
|
||||||
|
: `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16 sortDesc`
|
||||||
|
: `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16`
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{t("search:searchresults-applicant-label")}
|
||||||
|
</button>
|
||||||
|
</dd>
|
||||||
|
<dd className="govuk-summary-list__key govuk-!-font-size-16">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() =>
|
||||||
|
sortDataBy("_pinswg_associatedlpa_value")
|
||||||
|
}
|
||||||
|
className={
|
||||||
|
orderByState ==
|
||||||
|
"_pinswg_associatedlpa_value"
|
||||||
|
? fieldSortState == "asc"
|
||||||
|
? `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16 sortAsc`
|
||||||
|
: `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16 sortDesc`
|
||||||
|
: `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16`
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{t("search:searchresults-authority-label")}
|
||||||
|
</button>
|
||||||
|
</dd>
|
||||||
|
<dd className="govuk-summary-list__key govuk-!-font-size-16">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() =>
|
||||||
|
sortDataBy("pinswg_appealcasetype")
|
||||||
|
}
|
||||||
|
className={
|
||||||
|
orderByState == "pinswg_appealcasetype"
|
||||||
|
? fieldSortState == "asc"
|
||||||
|
? `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16 sortAsc`
|
||||||
|
: `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16 sortDesc`
|
||||||
|
: `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16`
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{t("search:searchresults-case-type-label")}
|
||||||
|
</button>
|
||||||
|
</dd>
|
||||||
|
<dd className="govuk-summary-list__key govuk-!-font-size-16">
|
||||||
|
{/* {t("search:searchresults-status-label")} */}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => sortDataBy("statuscode")}
|
||||||
|
className={
|
||||||
|
orderByState == "statuscode"
|
||||||
|
? fieldSortState == "asc"
|
||||||
|
? `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16 sortAsc`
|
||||||
|
: `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16 sortDesc`
|
||||||
|
: `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16`
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{t("search:searchresults-status-label")}
|
||||||
|
</button>
|
||||||
|
</dd>
|
||||||
|
|
||||||
|
<dd className="govuk-summary-list__key govuk-!-font-size-16 govuk-summary-list__action">
|
||||||
|
Origin
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
{showSpinnerState == true ? (
|
||||||
|
<div className="govuk-summary-list__row">
|
||||||
|
<div className="govuk-!-margin-top-9 govuk-!-margin-bottom-9 govuk-!-font-weight-bold govuk-!-font-size-20 ">
|
||||||
|
{t("common:spinner-fetching-data")}
|
||||||
|
<img
|
||||||
|
className="data-loading-icon"
|
||||||
|
src="/assets/images/loading.gif"
|
||||||
|
alt={
|
||||||
|
router.locale == "cy"
|
||||||
|
? "Nôl data"
|
||||||
|
: "Fetching data"
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
resultsArr.map((item, key) => {
|
||||||
|
let detailsObj = jsonpath({
|
||||||
|
path:
|
||||||
|
'$..[?(@ && @.ticketnumber=="' +
|
||||||
|
item.ticketnumber +
|
||||||
|
'")]',
|
||||||
|
json: searchDetailsObj,
|
||||||
|
eval: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
detailsObj = detailsObj[0] || {};
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="govuk-summary-list__row"
|
||||||
|
key={key}
|
||||||
|
>
|
||||||
|
<dd className="govuk-summary-list__value govuk-!-font-size-16 ">
|
||||||
|
<div></div>
|
||||||
|
{item.pinswg_publishtoweb == true ? (
|
||||||
|
<Link
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
href={
|
||||||
|
(router.locale == "cy"
|
||||||
|
? myportal == true
|
||||||
|
? "/fymhorth/achos"
|
||||||
|
: "/achos"
|
||||||
|
: myportal == true
|
||||||
|
? "/myportal/case"
|
||||||
|
: "/case") +
|
||||||
|
"/" +
|
||||||
|
item.ticketnumber
|
||||||
|
}
|
||||||
|
className="govuk-link--no-underline"
|
||||||
|
onClick={() => {
|
||||||
|
setCurrentReference({
|
||||||
|
"ticketnumber":
|
||||||
|
item.ticketnumber,
|
||||||
|
"currentReference":
|
||||||
|
item.title,
|
||||||
|
"currentType":
|
||||||
|
"searchResultsObj",
|
||||||
|
"incidentid":
|
||||||
|
item.incidentid,
|
||||||
|
"appealType":
|
||||||
|
item.pinswg_appealcasetype,
|
||||||
|
"showLoginCheck":
|
||||||
|
props.showLoginCheck,
|
||||||
|
"specialistProcess":
|
||||||
|
detailsObj.hasOwnProperty(
|
||||||
|
"pinswg_speacialistcaseprocess"
|
||||||
|
)
|
||||||
|
? detailsObj.pinswg_speacialistcaseprocess
|
||||||
|
: detailsObj.hasOwnProperty(
|
||||||
|
"pinswg_specialistcaseprocess"
|
||||||
|
)
|
||||||
|
? detailsObj.pinswg_specialistcaseprocess
|
||||||
|
: "",
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span className="results-visually-hidden">
|
||||||
|
{t(
|
||||||
|
"search:searchresults-case-reference-label"
|
||||||
|
)}
|
||||||
|
:
|
||||||
|
</span>
|
||||||
|
{item.title}
|
||||||
|
</Link>
|
||||||
|
) : (
|
||||||
|
item.title
|
||||||
|
)}
|
||||||
|
|
||||||
|
<br />
|
||||||
|
{new Date(
|
||||||
|
item.createdon
|
||||||
|
).toLocaleString()}
|
||||||
|
</dd>
|
||||||
|
<dd className="govuk-summary-list__value govuk-!-font-size-16">
|
||||||
|
<span className="results-visually-hidden">
|
||||||
|
{t(
|
||||||
|
"search:searchresults-site-address-label"
|
||||||
|
)}
|
||||||
|
:
|
||||||
|
</span>
|
||||||
|
{_.has(
|
||||||
|
detailsObj,
|
||||||
|
"pinswg_projectlocation"
|
||||||
|
)
|
||||||
|
? detailsObj.pinswg_projectlocation !=
|
||||||
|
null
|
||||||
|
? detailsObj.pinswg_projectlocation.indexOf(
|
||||||
|
";"
|
||||||
|
) < 0
|
||||||
|
? detailsObj.pinswg_projectlocation
|
||||||
|
: router.locale == "cy"
|
||||||
|
? detailsObj.pinswg_projectlocation.split(
|
||||||
|
";"
|
||||||
|
)[1]
|
||||||
|
: detailsObj.pinswg_projectlocation.split(
|
||||||
|
";"
|
||||||
|
)[0]
|
||||||
|
: ""
|
||||||
|
: ""}
|
||||||
|
{_.has(
|
||||||
|
detailsObj,
|
||||||
|
"pinswg_siteaddressline1"
|
||||||
|
)
|
||||||
|
? detailsObj.pinswg_siteaddressline1
|
||||||
|
: ""}
|
||||||
|
|
||||||
|
{/* {detailsObj.pinswg_siteaddressline1 !=
|
||||||
|
null && <br />} */}
|
||||||
|
|
||||||
|
{_.has(
|
||||||
|
detailsObj,
|
||||||
|
"pinswg_siteaddressline1"
|
||||||
|
) &&
|
||||||
|
detailsObj.pinswg_siteaddressline1 !=
|
||||||
|
null && <br />}
|
||||||
|
|
||||||
|
{_.has(
|
||||||
|
detailsObj,
|
||||||
|
"pinswg_siteaddressline1"
|
||||||
|
)
|
||||||
|
? detailsObj.pinswg_siteaddressline2
|
||||||
|
: ""}
|
||||||
|
|
||||||
|
{_.has(
|
||||||
|
detailsObj,
|
||||||
|
"pinswg_siteaddressline2"
|
||||||
|
) &&
|
||||||
|
detailsObj.pinswg_siteaddressline2 !=
|
||||||
|
null && <br />}
|
||||||
|
{_.has(
|
||||||
|
detailsObj,
|
||||||
|
"pinswg_siteaddresstown"
|
||||||
|
)
|
||||||
|
? detailsObj.pinswg_siteaddresstown
|
||||||
|
: ""}
|
||||||
|
{_.has(
|
||||||
|
detailsObj,
|
||||||
|
"pinswg_siteaddresstown"
|
||||||
|
) &&
|
||||||
|
detailsObj.pinswg_siteaddresstown !=
|
||||||
|
null && <br />}
|
||||||
|
|
||||||
|
{_.has(
|
||||||
|
detailsObj,
|
||||||
|
"pinswg_siteaddresscounty"
|
||||||
|
)
|
||||||
|
? detailsObj.pinswg_siteaddresscounty
|
||||||
|
: ""}
|
||||||
|
{_.has(
|
||||||
|
detailsObj,
|
||||||
|
"pinswg_siteaddresscounty"
|
||||||
|
) &&
|
||||||
|
detailsObj.pinswg_siteaddresscounty !=
|
||||||
|
null && <br />}
|
||||||
|
{_.has(
|
||||||
|
detailsObj,
|
||||||
|
"pinswg_siteaddresspostcode"
|
||||||
|
)
|
||||||
|
? detailsObj.pinswg_siteaddresspostcode
|
||||||
|
: ""}
|
||||||
|
</dd>
|
||||||
|
<dd className="govuk-summary-list__value govuk-!-font-size-16">
|
||||||
|
<span className="results-visually-hidden">
|
||||||
|
{t(
|
||||||
|
"search:searchresults-applicant-label"
|
||||||
|
)}
|
||||||
|
:
|
||||||
|
</span>
|
||||||
|
{item.pinswg_appellantagent == 846040001
|
||||||
|
? item.pinswg_appellantfirstname +
|
||||||
|
" " +
|
||||||
|
item.pinswg_appellantlastname
|
||||||
|
: _.has(detailsObj, [
|
||||||
|
"_pinswg_appellant_value@OData.Community.Display.V1.FormattedValue",
|
||||||
|
])
|
||||||
|
? detailsObj[
|
||||||
|
"_pinswg_appellant_value@OData.Community.Display.V1.FormattedValue"
|
||||||
|
]
|
||||||
|
: ""}
|
||||||
|
</dd>
|
||||||
|
<dd className="govuk-summary-list__value govuk-!-font-size-16">
|
||||||
|
<span className="results-visually-hidden">
|
||||||
|
{t(
|
||||||
|
"search:searchresults-authority-label"
|
||||||
|
)}
|
||||||
|
:
|
||||||
|
</span>
|
||||||
|
{_.has(item, [
|
||||||
|
"_pinswg_associatedlpa_value@OData.Community.Display.V1.FormattedValue",
|
||||||
|
])
|
||||||
|
? router.locale == "cy"
|
||||||
|
? jsonpath({
|
||||||
|
path:
|
||||||
|
'$..[?(@ && @.value=="' +
|
||||||
|
item[
|
||||||
|
"_pinswg_associatedlpa_value@OData.Community.Display.V1.FormattedValue"
|
||||||
|
] +
|
||||||
|
'")].value_cy',
|
||||||
|
json: transLookup,
|
||||||
|
eval: true,
|
||||||
|
})
|
||||||
|
: item[
|
||||||
|
"_pinswg_associatedlpa_value@OData.Community.Display.V1.FormattedValue"
|
||||||
|
] || "N/A"
|
||||||
|
: ""}
|
||||||
|
</dd>
|
||||||
|
<dd className="govuk-summary-list__value govuk-!-font-size-16">
|
||||||
|
<span className="results-visually-hidden">
|
||||||
|
{t(
|
||||||
|
"search:searchresults-case-type-label"
|
||||||
|
)}
|
||||||
|
:
|
||||||
|
</span>
|
||||||
|
{router.locale == "cy"
|
||||||
|
? jsonpath({
|
||||||
|
path:
|
||||||
|
'$..[?(@ && @.value=="' +
|
||||||
|
item[
|
||||||
|
"pinswg_appealcasetype@OData.Community.Display.V1.FormattedValue"
|
||||||
|
] +
|
||||||
|
'")].value_cy',
|
||||||
|
json: transLookup,
|
||||||
|
eval: true,
|
||||||
|
})
|
||||||
|
: item[
|
||||||
|
"pinswg_appealcasetype@OData.Community.Display.V1.FormattedValue"
|
||||||
|
] || "N/A"}
|
||||||
|
</dd>
|
||||||
|
<dd className="govuk-summary-list__value govuk-!-font-size-16">
|
||||||
|
<span className="results-visually-hidden">
|
||||||
|
{t(
|
||||||
|
"search:searchresults-status-label"
|
||||||
|
)}
|
||||||
|
:
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{router.locale == "cy"
|
||||||
|
? jsonpath({
|
||||||
|
path:
|
||||||
|
'$..[?(@ && @.value=="' +
|
||||||
|
item[
|
||||||
|
"statuscode@OData.Community.Display.V1.FormattedValue"
|
||||||
|
] +
|
||||||
|
'")].value_cy',
|
||||||
|
json: transLookup,
|
||||||
|
eval: true,
|
||||||
|
})
|
||||||
|
: item[
|
||||||
|
"statuscode@OData.Community.Display.V1.FormattedValue"
|
||||||
|
] || "N/A"}
|
||||||
|
</dd>
|
||||||
|
<dd className="govuk-summary-list__value govuk-!-font-size-16">
|
||||||
|
{item[
|
||||||
|
"caseorigincode@OData.Community.Display.V1.FormattedValue"
|
||||||
|
] || "N/A"}
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
)}
|
||||||
|
</dl>
|
||||||
|
<PaginationControl
|
||||||
|
showNoOfRecords={selectedOption}
|
||||||
|
currentPage={currentPage}
|
||||||
|
searchResultsObj={props.searchResultsObj.searchResultsObj}
|
||||||
|
orderBy={orderByState}
|
||||||
|
fieldSort={fieldSortState}
|
||||||
|
spinnerState={spinnerState}
|
||||||
|
getSearchPageResults={getSearchPageResults}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>Appeals</h1>
|
||||||
|
{searchResultsObj["@odata.count"] > 5 && (
|
||||||
|
<div id="recordCountSelect" className="">
|
||||||
|
<div className="govuk-form-group">
|
||||||
|
<label
|
||||||
|
className="govuk-label-s "
|
||||||
|
htmlFor="showNumberOfRecords"
|
||||||
|
>
|
||||||
|
{t("search:searchresults-show-records-label-a")}
|
||||||
|
<select
|
||||||
|
onChange={(e) => {
|
||||||
|
setSelectedOption(e.target.value);
|
||||||
|
props.setCurrentPage(1);
|
||||||
|
}}
|
||||||
|
value={selectedOption}
|
||||||
|
className="govuk-select"
|
||||||
|
id="showNumberOfRecords"
|
||||||
|
name="showNumberOfRecords"
|
||||||
|
>
|
||||||
|
<option value="5">5</option>
|
||||||
|
<option value="10">10</option>
|
||||||
|
<option value="20">20</option>
|
||||||
|
<option value="30">30</option>
|
||||||
|
<option value="50">50</option>
|
||||||
|
</select>{" "}
|
||||||
|
{t("search:searchresults-show-records-label-b")}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{resultsArr.length > 0 ? (
|
||||||
|
ResultsView(resultsArr)
|
||||||
|
) : (
|
||||||
|
<div className="govuk-grid-row">
|
||||||
|
<div className="govuk-grid-column-two-thirds">
|
||||||
|
<h3>{t("search:searchresults-no-records-label")}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => {
|
||||||
|
return {
|
||||||
|
setCurrentReference: (currentReference) => {
|
||||||
|
dispatch(setCurrentReference(currentReference));
|
||||||
|
},
|
||||||
|
setSearchResults: (searchResultsObj) => {
|
||||||
|
dispatch(setSearchResults(searchResultsObj));
|
||||||
|
},
|
||||||
|
setSearchDetails: (searchDetailsObj) => {
|
||||||
|
dispatch(setSearchDetails(searchDetailsObj));
|
||||||
|
},
|
||||||
|
setCurrentPage: (currentPage) => {
|
||||||
|
dispatch(setCurrentPage(currentPage));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => {
|
||||||
|
return {
|
||||||
|
searchResultsObj: state.searchResultsObj,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(AppealsTab);
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,266 @@
|
|||||||
|
// components/admin/tabs/StorageTab.js
|
||||||
|
import { useState } from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { bytesToSize } from "../../../components/utils";
|
||||||
|
import {
|
||||||
|
deleteMyRepresentationsFromBlob,
|
||||||
|
deleteAwaitingSubmissionsFromBlob,
|
||||||
|
sendRepCompleteMessage,
|
||||||
|
} from "../../../actions";
|
||||||
|
|
||||||
|
import { formatBlobDates } from "../utils/adminHelper";
|
||||||
|
|
||||||
|
export default function StorageTab({ data, repCompleteCount }) {
|
||||||
|
const [showRepJson, setShowRepJson] = useState(true);
|
||||||
|
const [showTmpFile, setShowTmpFile] = useState(true);
|
||||||
|
const [listData, setListData] = useState(data);
|
||||||
|
|
||||||
|
const toggleAll = () => {
|
||||||
|
const newState = !(showRepJson || showTmpFile);
|
||||||
|
setShowRepJson(newState);
|
||||||
|
setShowTmpFile(newState);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>Storage Account Contents</h1>
|
||||||
|
{repCompleteCount > 0 && (
|
||||||
|
<p>Number of Orphaned Reps: {repCompleteCount}</p>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Toggle buttons */}
|
||||||
|
<div style={{ marginBottom: "0.2rem" }}>
|
||||||
|
<button
|
||||||
|
className="govuk-button govuk-button--secondary"
|
||||||
|
onClick={() => setShowRepJson(!showRepJson)}
|
||||||
|
>
|
||||||
|
{showRepJson ? "Hide Reps" : "Show Reps"}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="govuk-button govuk-button--secondary"
|
||||||
|
onClick={() => setShowTmpFile(!showTmpFile)}
|
||||||
|
style={{ marginLeft: "0.5rem" }}
|
||||||
|
>
|
||||||
|
{showTmpFile ? "Hide Temp Appeal" : "Show Temp Appeal"}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="govuk-button govuk-button--secondary"
|
||||||
|
onClick={toggleAll}
|
||||||
|
style={{ marginLeft: "0.5rem" }}
|
||||||
|
>
|
||||||
|
Show/Hide All
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Render users & containers */}
|
||||||
|
{listData.map((user) => (
|
||||||
|
<div key={user.id} className="govuk-grid-row">
|
||||||
|
{user.containers.map((c) => (
|
||||||
|
<div key={c.container} className="card">
|
||||||
|
<div className="card-body">
|
||||||
|
<h3>
|
||||||
|
{c.container} -{" "}
|
||||||
|
<Link
|
||||||
|
href={`/auth/signin2?email=${user.email}`}
|
||||||
|
>
|
||||||
|
{user.email}
|
||||||
|
</Link>
|
||||||
|
</h3>
|
||||||
|
{/* folders */}
|
||||||
|
{c.folders.map((folder) => (
|
||||||
|
<div
|
||||||
|
key={folder.folderPath}
|
||||||
|
style={
|
||||||
|
showRepJson && folder.hasRepJson
|
||||||
|
? { display: "block" }
|
||||||
|
: showTmpFile &&
|
||||||
|
folder.hasTmpFile
|
||||||
|
? { display: "block" }
|
||||||
|
: { display: "none" }
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<h4>{folder.folderPath || "Root"}</h4>
|
||||||
|
|
||||||
|
{/* Buttons for TMP + Rep actions go here (same logic as before) */}
|
||||||
|
|
||||||
|
{folder.hasTmpFile && (
|
||||||
|
<>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
confirm(
|
||||||
|
"Do you want to remove this unsubmitted appeal " +
|
||||||
|
folder.folderPath +
|
||||||
|
"?\n"
|
||||||
|
) &&
|
||||||
|
(deleteCaseItem(
|
||||||
|
c.container,
|
||||||
|
folder.folderPath,
|
||||||
|
setData
|
||||||
|
),
|
||||||
|
alert(
|
||||||
|
"Temp case Deleted!"
|
||||||
|
));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Delete this TMP appeal
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{folder.hasRepJson && (
|
||||||
|
<div>
|
||||||
|
{" "}
|
||||||
|
<button
|
||||||
|
title={
|
||||||
|
"Do you want to delete rep"
|
||||||
|
}
|
||||||
|
className=" cardModuleRemoveCase govuk-link govuk-link--no-underline govuk-link--inverse "
|
||||||
|
onClick={() => {
|
||||||
|
confirm(
|
||||||
|
"Do you want tyo delete rep " +
|
||||||
|
folder.repJsonBlob.name.split(
|
||||||
|
"/"
|
||||||
|
)[0] +
|
||||||
|
"?\n"
|
||||||
|
) &&
|
||||||
|
(deleteRepItem(
|
||||||
|
c.container,
|
||||||
|
folder.repJsonBlob.name.split(
|
||||||
|
"/"
|
||||||
|
)[0],
|
||||||
|
folder.repJsonBlob.name.split(
|
||||||
|
"/"
|
||||||
|
)[1]
|
||||||
|
),
|
||||||
|
alert(
|
||||||
|
"Rep Deleted!"
|
||||||
|
),
|
||||||
|
window.location.reload());
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Delete Rep
|
||||||
|
</button>
|
||||||
|
{folder.repComplete && (
|
||||||
|
<button
|
||||||
|
onClick={async () => {
|
||||||
|
const response =
|
||||||
|
await fetch(
|
||||||
|
"/api/file/editRepJson",
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers:
|
||||||
|
{
|
||||||
|
"Content-Type":
|
||||||
|
"application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(
|
||||||
|
{
|
||||||
|
container:
|
||||||
|
c.container,
|
||||||
|
blobName:
|
||||||
|
folder
|
||||||
|
.repJsonBlob
|
||||||
|
.name,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const result =
|
||||||
|
await response.json();
|
||||||
|
if (response.ok) {
|
||||||
|
alert(
|
||||||
|
"repComplete removed!"
|
||||||
|
),
|
||||||
|
window.location.reload();
|
||||||
|
// Optionally refresh the page or update UI state here
|
||||||
|
} else {
|
||||||
|
alert(
|
||||||
|
"Error: " +
|
||||||
|
result.error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Remove repComplete
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
{folder.repComplete && (
|
||||||
|
<button
|
||||||
|
onClick={async () => {
|
||||||
|
confirm(
|
||||||
|
"Do you want resend the rep queue message " +
|
||||||
|
folder.repJsonBlob.name.split(
|
||||||
|
"/"
|
||||||
|
)[0] +
|
||||||
|
" --- " +
|
||||||
|
folder.repJsonBlob.name.split(
|
||||||
|
"/"
|
||||||
|
)[1]
|
||||||
|
) &&
|
||||||
|
(sendRepCompleteMessage(
|
||||||
|
c.container,
|
||||||
|
folder.repJsonBlob.name.split(
|
||||||
|
"/"
|
||||||
|
)[0],
|
||||||
|
folder.repJsonBlob.name.split(
|
||||||
|
"/"
|
||||||
|
)[1]
|
||||||
|
),
|
||||||
|
alert(
|
||||||
|
"rep queue message sent!"
|
||||||
|
),
|
||||||
|
window.location.reload());
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Recreate Queue Message
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<ul>
|
||||||
|
{folder.blobs.map((blob) => (
|
||||||
|
<li key={blob.name}>
|
||||||
|
<Link
|
||||||
|
scroll={false}
|
||||||
|
href={`/api/file/downloadblob?container=${
|
||||||
|
c.container
|
||||||
|
}&casefolderID=${
|
||||||
|
folder.folderPath
|
||||||
|
}&blobname=${blob.name.substring(
|
||||||
|
blob.name.lastIndexOf(
|
||||||
|
"/"
|
||||||
|
) + 1
|
||||||
|
)}&hash=${
|
||||||
|
blob.hashedfilepath
|
||||||
|
}`}
|
||||||
|
className="govuk-body govuk-!-font-size-14 govuk-link"
|
||||||
|
>
|
||||||
|
{blob.name} (
|
||||||
|
{bytesToSize(
|
||||||
|
blob.contentLength ||
|
||||||
|
blob.size
|
||||||
|
)}
|
||||||
|
)
|
||||||
|
</Link>{" "}
|
||||||
|
{blob.lastModified && (
|
||||||
|
<span className="govuk-!-font-size-14">
|
||||||
|
{/* {
|
||||||
|
blob.displayDate
|
||||||
|
} */}
|
||||||
|
{formatBlobDates(
|
||||||
|
blob
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
// components/admin/utils/adminStorage.js
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the folder path up to the last slash.
|
||||||
|
* Used for grouping blobs by "case folder".
|
||||||
|
*/
|
||||||
|
export function getUpToLastSlash(url) {
|
||||||
|
let lastSlash = url.lastIndexOf("/");
|
||||||
|
|
||||||
|
url = url.substring(0, lastSlash);
|
||||||
|
|
||||||
|
url =
|
||||||
|
url.lastIndexOf("/files") > 0
|
||||||
|
? url.substring(0, url.lastIndexOf("/files"))
|
||||||
|
: url;
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a stream (Azure blob download) to a string.
|
||||||
|
*/
|
||||||
|
export async function streamToString(readableStream) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const chunks = [];
|
||||||
|
readableStream.on("data", (data) => {
|
||||||
|
chunks.push(data.toString());
|
||||||
|
});
|
||||||
|
readableStream.on("end", () => {
|
||||||
|
resolve(chunks.join(""));
|
||||||
|
});
|
||||||
|
readableStream.on("error", reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format how long ago a date occurred.
|
||||||
|
*/
|
||||||
|
export function formatTimeSince(date) {
|
||||||
|
if (!date) return "Unknown date";
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
const diffMs = now - date;
|
||||||
|
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
||||||
|
|
||||||
|
if (diffDays < 7) {
|
||||||
|
return `${diffDays} day${diffDays !== 1 ? "s" : ""} ago`;
|
||||||
|
} else {
|
||||||
|
const diffWeeks = Math.floor(diffDays / 7);
|
||||||
|
return `${diffWeeks} week${diffWeeks !== 1 ? "s" : ""} ago`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format Azure blob created/modified dates into a readable string.
|
||||||
|
*/
|
||||||
|
export function formatBlobDates(blob) {
|
||||||
|
const created = blob.createdOn ? new Date(blob.createdOn) : null;
|
||||||
|
const modified = blob.lastModified ? new Date(blob.lastModified) : null;
|
||||||
|
|
||||||
|
if (!created && !modified) return "Unknown";
|
||||||
|
|
||||||
|
// If both exist and are the same
|
||||||
|
if (created && modified && created.getTime() === modified.getTime()) {
|
||||||
|
return `${created.toLocaleString("en-GB")} (${formatTimeSince(
|
||||||
|
created
|
||||||
|
)})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If modified exists and is newer than created
|
||||||
|
if (created && modified && modified.getTime() > created.getTime()) {
|
||||||
|
return `Created: ${created.toLocaleString("en-GB")} (${formatTimeSince(
|
||||||
|
created
|
||||||
|
)}), Modified: ${modified.toLocaleString("en-GB")} (${formatTimeSince(
|
||||||
|
modified
|
||||||
|
)})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only one date exists
|
||||||
|
const date = modified || created;
|
||||||
|
return `${date.toLocaleString("en-GB")} (${formatTimeSince(date)})`;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// lib/prisma.js
|
||||||
|
import { PrismaClient } from "@prisma/client";
|
||||||
|
|
||||||
|
const globalForPrisma = globalThis;
|
||||||
|
|
||||||
|
export const prisma =
|
||||||
|
globalForPrisma.prisma ||
|
||||||
|
new PrismaClient({
|
||||||
|
log: ["query", "error", "warn"],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV !== "production") {
|
||||||
|
globalForPrisma.prisma = prisma;
|
||||||
|
}
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
// components/admin/utils/serverStorage.js
|
||||||
|
import { DefaultAzureCredential } from "@azure/identity";
|
||||||
|
import { BlobServiceClient } from "@azure/storage-blob";
|
||||||
|
import { PrismaClient } from "@prisma/client";
|
||||||
|
import CryptoJS from "crypto-js";
|
||||||
|
import { getUpToLastSlash, streamToString } from "../utils/adminHelper";
|
||||||
|
import { listContainersForUser } from "../../../actions/azurestorage";
|
||||||
|
|
||||||
|
const prisma = global.prisma || new PrismaClient();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate HMAC hash for blob API link.
|
||||||
|
*/
|
||||||
|
function hashAPIPath(queryPath, WORDKEY) {
|
||||||
|
let hashlink = CryptoJS.HmacSHA256(
|
||||||
|
queryPath,
|
||||||
|
CryptoJS.enc.Hex.parse(WORDKEY)
|
||||||
|
);
|
||||||
|
return hashlink.toString(CryptoJS.enc.Hex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch blob structure + users for admin storage page.
|
||||||
|
*/
|
||||||
|
export async function fetchAdminStorageData() {
|
||||||
|
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
|
||||||
|
const creds = new DefaultAzureCredential();
|
||||||
|
const blobServiceClient = new BlobServiceClient(
|
||||||
|
`https://${accountName}.blob.core.windows.net`,
|
||||||
|
creds
|
||||||
|
);
|
||||||
|
|
||||||
|
const prisma = global.prisma || new PrismaClient();
|
||||||
|
|
||||||
|
const users = await prisma.user.findMany();
|
||||||
|
|
||||||
|
let data = await Promise.all(
|
||||||
|
users.map(async (user) => {
|
||||||
|
const containers = await listContainersForUser(
|
||||||
|
blobServiceClient,
|
||||||
|
`${user.id}`,
|
||||||
|
user.email
|
||||||
|
);
|
||||||
|
|
||||||
|
const containersWithHashes = await Promise.all(
|
||||||
|
containers.map(async (container) => {
|
||||||
|
const groupedByFolder = await container.blobs.reduce(
|
||||||
|
async (accP, blob) => {
|
||||||
|
const acc = await accP;
|
||||||
|
const folderPath =
|
||||||
|
getUpToLastSlash(blob.name.trim()) || "";
|
||||||
|
|
||||||
|
const hashedfilepath = hashAPIPath(
|
||||||
|
`/api/file/downloadblob?container=${
|
||||||
|
container.container
|
||||||
|
}&casefolderID=${folderPath}&blobname=${blob.name
|
||||||
|
.substring(blob.name.lastIndexOf("/") + 1)
|
||||||
|
.trim()}`,
|
||||||
|
process.env.HASHKEY
|
||||||
|
);
|
||||||
|
|
||||||
|
const fileNameOnly = blob.name.substring(
|
||||||
|
blob.name.lastIndexOf("/") + 1
|
||||||
|
);
|
||||||
|
const isTmpFile = fileNameOnly.startsWith("TMP-");
|
||||||
|
|
||||||
|
const blobWithHash = {
|
||||||
|
...blob,
|
||||||
|
hashedfilepath,
|
||||||
|
isTmpFile,
|
||||||
|
};
|
||||||
|
|
||||||
|
let folderGroup = acc.find(
|
||||||
|
(f) => f.folderPath === folderPath
|
||||||
|
);
|
||||||
|
if (!folderGroup) {
|
||||||
|
folderGroup = {
|
||||||
|
folderPath,
|
||||||
|
blobs: [],
|
||||||
|
hasRepJson: false,
|
||||||
|
repJsonBlob: null,
|
||||||
|
repComplete: false,
|
||||||
|
hasTmpFile: false,
|
||||||
|
};
|
||||||
|
acc.push(folderGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
folderGroup.blobs.push(blobWithHash);
|
||||||
|
|
||||||
|
if (isTmpFile) {
|
||||||
|
folderGroup.hasTmpFile = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rep.json handling
|
||||||
|
if (blob.name.toLowerCase().endsWith("rep.json")) {
|
||||||
|
folderGroup.hasRepJson = true;
|
||||||
|
folderGroup.repJsonBlob = blobWithHash;
|
||||||
|
|
||||||
|
const containerClient =
|
||||||
|
blobServiceClient.getContainerClient(
|
||||||
|
container.container
|
||||||
|
);
|
||||||
|
const blockBlobClient =
|
||||||
|
containerClient.getBlockBlobClient(
|
||||||
|
blob.name
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const downloadResponse =
|
||||||
|
await blockBlobClient.download(0);
|
||||||
|
const downloaded = await streamToString(
|
||||||
|
downloadResponse.readableStreamBody
|
||||||
|
);
|
||||||
|
const json = JSON.parse(downloaded);
|
||||||
|
folderGroup.repComplete = Boolean(
|
||||||
|
json.repComplete
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(
|
||||||
|
"Error reading rep.json",
|
||||||
|
err
|
||||||
|
);
|
||||||
|
folderGroup.repComplete = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
Promise.resolve([])
|
||||||
|
);
|
||||||
|
|
||||||
|
return { ...container, folders: groupedByFolder };
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return containersWithHashes.length > 0
|
||||||
|
? {
|
||||||
|
id: user.id,
|
||||||
|
email: user.email,
|
||||||
|
containers: containersWithHashes,
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
data = data.filter(Boolean);
|
||||||
|
|
||||||
|
let userData = users
|
||||||
|
.filter((user) => user.email && user.email.trim() !== "")
|
||||||
|
.map((user) => ({
|
||||||
|
id: user.id,
|
||||||
|
email: user.email,
|
||||||
|
created: user.emailVerified?.toLocaleString("en-GB") || "",
|
||||||
|
}));
|
||||||
|
|
||||||
|
let repCompleteCount = 0;
|
||||||
|
data.forEach((user) => {
|
||||||
|
user.containers.forEach((container) => {
|
||||||
|
container.folders.forEach((folder) => {
|
||||||
|
if (folder.repComplete === true) repCompleteCount++;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return { data, userData, repCompleteCount };
|
||||||
|
}
|
||||||
@@ -17,9 +17,11 @@ import {
|
|||||||
import { setCurrentPage } from "../../store/currentView/action";
|
import { setCurrentPage } from "../../store/currentView/action";
|
||||||
|
|
||||||
import { setDocumentDetails } from "../../store/searchOutput/action";
|
import { setDocumentDetails } from "../../store/searchOutput/action";
|
||||||
|
import DocumentLink from "../utils/downloads";
|
||||||
|
import { useDownloadQueue } from "../utils/downloadmanager";
|
||||||
|
|
||||||
const DocumentDetails = (props) => {
|
const DocumentDetails = (props) => {
|
||||||
let { t } = useTranslation();
|
let { t, lang } = useTranslation();
|
||||||
const firstRender = useRef(false);
|
const firstRender = useRef(false);
|
||||||
const {
|
const {
|
||||||
incidentid,
|
incidentid,
|
||||||
@@ -37,7 +39,7 @@ const DocumentDetails = (props) => {
|
|||||||
const { locale } = router;
|
const { locale } = router;
|
||||||
|
|
||||||
var documentDetailsArr = documentDetailsObj || [];
|
var documentDetailsArr = documentDetailsObj || [];
|
||||||
|
const { startDownload, getStatus } = useDownloadQueue(3);
|
||||||
const [selectedOption, setSelectedOption] = useState(10);
|
const [selectedOption, setSelectedOption] = useState(10);
|
||||||
const [documentTypes, setDocumentTypes] = useState([{}]);
|
const [documentTypes, setDocumentTypes] = useState([{}]);
|
||||||
const [selectedDocumentType, setSelectedDocumentType] = useState("all");
|
const [selectedDocumentType, setSelectedDocumentType] = useState("all");
|
||||||
@@ -287,12 +289,9 @@ const DocumentDetails = (props) => {
|
|||||||
{/* {t("case:documents-date-published-label")} */}
|
{/* {t("case:documents-date-published-label")} */}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() =>
|
onClick={() => sortDataBy("createdon")}
|
||||||
sortDataBy("pinswg_documentpublisheddate")
|
|
||||||
}
|
|
||||||
className={
|
className={
|
||||||
orderByState ==
|
orderByState == "createdon"
|
||||||
"pinswg_documentpublisheddate"
|
|
||||||
? fieldSortState == "asc"
|
? fieldSortState == "asc"
|
||||||
? `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16 sortAsc`
|
? `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16 sortAsc`
|
||||||
: `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16 sortDesc`
|
: `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16 sortDesc`
|
||||||
@@ -419,7 +418,7 @@ const DocumentDetails = (props) => {
|
|||||||
] +
|
] +
|
||||||
'")].value_cy',
|
'")].value_cy',
|
||||||
json: transLookup,
|
json: transLookup,
|
||||||
sanbox: {},
|
eval: true,
|
||||||
})
|
})
|
||||||
: detailsObj[
|
: detailsObj[
|
||||||
"pinswg_isharedocumentlocations@OData.Community.Display.V1.FormattedValue"
|
"pinswg_isharedocumentlocations@OData.Community.Display.V1.FormattedValue"
|
||||||
@@ -507,7 +506,7 @@ const DocumentDetails = (props) => {
|
|||||||
</p>
|
</p>
|
||||||
<div>
|
<div>
|
||||||
<button onClick={clearCheckboxes}>
|
<button onClick={clearCheckboxes}>
|
||||||
{t("case:documents-clear-filter-label")}
|
{t("search:clear-filter-button-label")}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="govuk-checkboxes govuk-checkboxes--small">
|
<div className="govuk-checkboxes govuk-checkboxes--small">
|
||||||
@@ -584,8 +583,8 @@ const DocumentDetails = (props) => {
|
|||||||
'$..[?(@ && @.value=="' +
|
'$..[?(@ && @.value=="' +
|
||||||
item.pinswg_isharedocumentlocationsLabel +
|
item.pinswg_isharedocumentlocationsLabel +
|
||||||
'")].value_cy',
|
'")].value_cy',
|
||||||
jsonL: transLookup,
|
json: transLookup,
|
||||||
sanbox: {},
|
eval: true,
|
||||||
})
|
})
|
||||||
: item.pinswg_isharedocumentlocationsLabel ||
|
: item.pinswg_isharedocumentlocationsLabel ||
|
||||||
t(
|
t(
|
||||||
@@ -611,7 +610,7 @@ const DocumentDetails = (props) => {
|
|||||||
setCurrentPage(1);
|
setCurrentPage(1);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{t("case:documents-filter-button")}
|
{t("search:filter-documents-label")}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{documentDetailsObj["@odata.count"] > 5 && (
|
{documentDetailsObj["@odata.count"] > 5 && (
|
||||||
@@ -700,14 +699,9 @@ const DocumentDetails = (props) => {
|
|||||||
{/* {t("case:documents-date-published-label")} */}
|
{/* {t("case:documents-date-published-label")} */}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() =>
|
onClick={() => sortDataBy("createdon")}
|
||||||
sortDataBy(
|
|
||||||
"pinswg_documentpublisheddate"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
className={
|
className={
|
||||||
orderByState ==
|
orderByState == "createdon"
|
||||||
"pinswg_documentpublisheddate"
|
|
||||||
? fieldSortState == "asc"
|
? fieldSortState == "asc"
|
||||||
? `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16 sortAsc`
|
? `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16 sortAsc`
|
||||||
: `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16 sortDesc`
|
: `govuk-link govuk-link--no-underline govuk-!-font-weight-bold govuk-!-font-size-16 sortDesc`
|
||||||
@@ -772,41 +766,63 @@ const DocumentDetails = (props) => {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{!ShowDocLinks ? (
|
{!ShowDocLinks ? (
|
||||||
<Link
|
<>
|
||||||
scroll={false}
|
<DocumentLink
|
||||||
href={
|
key={
|
||||||
detailsObj.pinswg_hashlink
|
detailsObj.pinswg_documentid
|
||||||
}
|
}
|
||||||
key={key}
|
id={
|
||||||
onClick={() => {
|
detailsObj.pinswg_documentid
|
||||||
toggleDownLoadLink(
|
}
|
||||||
key
|
detailsObj={
|
||||||
),
|
detailsObj
|
||||||
sendGAEvent(
|
}
|
||||||
"event",
|
caseReference={
|
||||||
"DownloadedFile",
|
caseReference
|
||||||
{
|
}
|
||||||
caseReference:
|
startDownload={
|
||||||
props.caseReference,
|
startDownload
|
||||||
filename:
|
}
|
||||||
detailsObj.pinswg_name,
|
getStatus={
|
||||||
}
|
getStatus
|
||||||
);
|
}
|
||||||
}}
|
/>
|
||||||
>
|
{/* <Link
|
||||||
<span className="results-visually-hidden">
|
scroll={false}
|
||||||
{t(
|
href={
|
||||||
"case:documents-name-label"
|
detailsObj.pinswg_hashlink
|
||||||
)}
|
}
|
||||||
:
|
key={key}
|
||||||
</span>
|
onClick={() => {
|
||||||
{_.has(
|
toggleDownLoadLink(
|
||||||
detailsObj,
|
key
|
||||||
"pinswg_name"
|
),
|
||||||
)
|
sendGAEvent(
|
||||||
? detailsObj.pinswg_name
|
"event",
|
||||||
: ""}
|
"DownloadedFile",
|
||||||
</Link>
|
{
|
||||||
|
caseReference:
|
||||||
|
props.caseReference,
|
||||||
|
filename:
|
||||||
|
detailsObj.pinswg_name,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span className="results-visually-hidden">
|
||||||
|
{t(
|
||||||
|
"case:documents-name-label"
|
||||||
|
)}
|
||||||
|
:
|
||||||
|
</span>
|
||||||
|
{_.has(
|
||||||
|
detailsObj,
|
||||||
|
"pinswg_name"
|
||||||
|
)
|
||||||
|
? detailsObj.pinswg_name
|
||||||
|
: ""}
|
||||||
|
</Link> */}
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<span className="results-visually-hidden">
|
<span className="results-visually-hidden">
|
||||||
@@ -858,36 +874,14 @@ const DocumentDetails = (props) => {
|
|||||||
:
|
:
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{/* {
|
{_.has(
|
||||||
detailsObj.pinswg_documentpublisheddate
|
|
||||||
}
|
|
||||||
{
|
|
||||||
detailsObj.pinswg_latestpublisheddate
|
|
||||||
} */}
|
|
||||||
|
|
||||||
{detailsObj.pinswg_documentpublisheddate !=
|
|
||||||
null
|
|
||||||
? formatDates(
|
|
||||||
detailsObj.pinswg_documentpublisheddate
|
|
||||||
)
|
|
||||||
: formatDates(
|
|
||||||
detailsObj.pinswg_latestpublisheddate
|
|
||||||
)}
|
|
||||||
{/* {_.has(
|
|
||||||
detailsObj,
|
detailsObj,
|
||||||
"pinswg_documentpublisheddate"
|
"pinswg_latestpublisheddate"
|
||||||
)
|
)
|
||||||
? formatDates(
|
|
||||||
detailsObj.pinswg_documentpublisheddate
|
|
||||||
)
|
|
||||||
: _.has(
|
|
||||||
detailsObj,
|
|
||||||
"pinswg_latestpublisheddate"
|
|
||||||
)
|
|
||||||
? formatDates(
|
? formatDates(
|
||||||
detailsObj.pinswg_latestpublisheddate
|
detailsObj.pinswg_latestpublisheddate
|
||||||
)
|
)
|
||||||
: ""} */}
|
: ""}
|
||||||
</dd>
|
</dd>
|
||||||
{/* <dd className="govuk-summary-list__value govuk-!-font-size-16">
|
{/* <dd className="govuk-summary-list__value govuk-!-font-size-16">
|
||||||
<span className="results-visually-hidden">
|
<span className="results-visually-hidden">
|
||||||
@@ -931,9 +925,8 @@ const DocumentDetails = (props) => {
|
|||||||
selectedOption,
|
selectedOption,
|
||||||
selectedDocumentType
|
selectedDocumentType
|
||||||
)
|
)
|
||||||
// .then((data) => data)
|
.then((data) => data)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
setDocumentSearchState(true);
|
|
||||||
setDocumentDetails(data);
|
setDocumentDetails(data);
|
||||||
setShowSpinnerState(false);
|
setShowSpinnerState(false);
|
||||||
});
|
});
|
||||||
@@ -1003,10 +996,8 @@ const DocumentDetails = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const [showDocumentSearchState, setDocumentSearchState] = useState(false);
|
const [showDocumentSearchState, setDocumentSearchState] = useState(false);
|
||||||
const [orderByState, setOrderbyState] = useState(
|
const [orderByState, setOrderbyState] = useState("createdon");
|
||||||
"pinswg_documentpublisheddate"
|
const [fieldSortState, setfieldSortState] = useState("asc");
|
||||||
);
|
|
||||||
const [fieldSortState, setfieldSortState] = useState("desc");
|
|
||||||
|
|
||||||
let documentSearchState = () => {
|
let documentSearchState = () => {
|
||||||
showDocumentSearchState == true
|
showDocumentSearchState == true
|
||||||
@@ -1016,14 +1007,14 @@ const DocumentDetails = (props) => {
|
|||||||
|
|
||||||
const sortDataBy = (whichField) => {
|
const sortDataBy = (whichField) => {
|
||||||
setOrderbyState(whichField);
|
setOrderbyState(whichField);
|
||||||
setfieldSortState("desc");
|
setfieldSortState("asc");
|
||||||
|
|
||||||
getDocumentResults(1, whichField, fieldSortState);
|
getDocumentResults(1, whichField, fieldSortState);
|
||||||
whichField == orderByState
|
whichField == orderByState
|
||||||
? fieldSortState == "asc"
|
? fieldSortState == "desc"
|
||||||
? setfieldSortState("desc")
|
? setfieldSortState("asc")
|
||||||
: setfieldSortState("asc")
|
: setfieldSortState("desc")
|
||||||
: setfieldSortState("desc");
|
: setfieldSortState("asc");
|
||||||
setCurrentPage(1);
|
setCurrentPage(1);
|
||||||
setShowSpinnerState(true);
|
setShowSpinnerState(true);
|
||||||
};
|
};
|
||||||
@@ -1058,7 +1049,7 @@ const DocumentDetails = (props) => {
|
|||||||
return docObj;
|
return docObj;
|
||||||
};
|
};
|
||||||
|
|
||||||
//const searchDocumentResultsObj = docDetailsObj();
|
const searchDocumentResultsObj = docDetailsObj();
|
||||||
}, [
|
}, [
|
||||||
incidentid,
|
incidentid,
|
||||||
setDocumentDetails,
|
setDocumentDetails,
|
||||||
@@ -1068,6 +1059,7 @@ const DocumentDetails = (props) => {
|
|||||||
orderByState,
|
orderByState,
|
||||||
getDocumentTypes,
|
getDocumentTypes,
|
||||||
getDocumentResults,
|
getDocumentResults,
|
||||||
|
lang,
|
||||||
]);
|
]);
|
||||||
return (
|
return (
|
||||||
<div className="govuk-grid-row">
|
<div className="govuk-grid-row">
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ const CaseSummary = (props) => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { locale } = router;
|
const { locale } = router;
|
||||||
const {
|
const {
|
||||||
|
appealTypeID,
|
||||||
incidentid,
|
incidentid,
|
||||||
caseReference,
|
caseReference,
|
||||||
myCases,
|
myCases,
|
||||||
@@ -76,9 +77,9 @@ const CaseSummary = (props) => {
|
|||||||
currentView,
|
currentView,
|
||||||
messagesObj,
|
messagesObj,
|
||||||
docsOffline,
|
docsOffline,
|
||||||
|
ticketnumber,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
let appealTypeID = props.appealTypeID || router.query.appealType;
|
|
||||||
const showLoginCheck =
|
const showLoginCheck =
|
||||||
currentType == "directResultsObj" ? "true" : currentView.showLogin;
|
currentType == "directResultsObj" ? "true" : currentView.showLogin;
|
||||||
const { data: session, status } = useSession();
|
const { data: session, status } = useSession();
|
||||||
@@ -233,13 +234,13 @@ const CaseSummary = (props) => {
|
|||||||
|
|
||||||
currentType == "searchResultsObj"
|
currentType == "searchResultsObj"
|
||||||
? (casesObj = jsonpath({
|
? (casesObj = jsonpath({
|
||||||
path: '$..[?(@ && @.title=="' + caseReference + '")]',
|
path: '$..[?(@ && @.ticketnumber=="' + ticketnumber + '")]',
|
||||||
json: searchResultsObj,
|
json: searchResultsObj,
|
||||||
eval: true,
|
eval: true,
|
||||||
}))
|
}))
|
||||||
: currentType == "watchedCases"
|
: currentType == "watchedCases"
|
||||||
? (casesObj = jsonpath({
|
? (casesObj = jsonpath({
|
||||||
path: '$..[?(@ && @.pinswg_title=="' + caseReference + '")]',
|
path: '$..[?(@ && @.ticketnumber=="' + ticketnumber + '")]',
|
||||||
json: setCaseQueryObj,
|
json: setCaseQueryObj,
|
||||||
eval: true,
|
eval: true,
|
||||||
}))
|
}))
|
||||||
@@ -251,7 +252,7 @@ const CaseSummary = (props) => {
|
|||||||
}))
|
}))
|
||||||
: currentType == "directResultsObj"
|
: currentType == "directResultsObj"
|
||||||
? (casesObj = jsonpath({
|
? (casesObj = jsonpath({
|
||||||
path: '$..[?(@ && @.ticketnumber=="' + caseReference + '")]',
|
path: '$..[?(@ && @.ticketnumber=="' + ticketnumber + '")]',
|
||||||
json: setCaseQueryObj,
|
json: setCaseQueryObj,
|
||||||
eval: true,
|
eval: true,
|
||||||
}))
|
}))
|
||||||
@@ -481,14 +482,19 @@ const CaseSummary = (props) => {
|
|||||||
<div className="govuk-summary-list__row">
|
<div className="govuk-summary-list__row">
|
||||||
<dt className="govuk-summary-list__key">
|
<dt className="govuk-summary-list__key">
|
||||||
{getFormCollectionByID(
|
{getFormCollectionByID(
|
||||||
appealTypeID
|
appealTypeID ||
|
||||||
|
setCaseQueryObj.value[0]
|
||||||
|
.pinswg_appealcasetype
|
||||||
).PrimaryIdAttribute ==
|
).PrimaryIdAttribute ==
|
||||||
"pinswg_dnsid"
|
"pinswg_dnsid"
|
||||||
? t(
|
? t(
|
||||||
"case:summary-applicantonly-label"
|
"case:summary-applicantonly-label"
|
||||||
)
|
)
|
||||||
: getFormCollectionByID(
|
: getFormCollectionByID(
|
||||||
appealTypeID
|
appealTypeID ||
|
||||||
|
setCaseQueryObj
|
||||||
|
.value[0]
|
||||||
|
.pinswg_appealcasetype
|
||||||
).PrimaryIdAttribute ==
|
).PrimaryIdAttribute ==
|
||||||
"pinswg_nonvalidationid"
|
"pinswg_nonvalidationid"
|
||||||
? t(
|
? t(
|
||||||
@@ -541,7 +547,9 @@ const CaseSummary = (props) => {
|
|||||||
</dt>
|
</dt>
|
||||||
<dd className="govuk-summary-list__value">
|
<dd className="govuk-summary-list__value">
|
||||||
{getFormCollectionByID(
|
{getFormCollectionByID(
|
||||||
appealTypeID
|
appealTypeID ||
|
||||||
|
setCaseQueryObj.value[0]
|
||||||
|
.pinswg_appealcasetype
|
||||||
).PrimaryIdAttribute ==
|
).PrimaryIdAttribute ==
|
||||||
"pinswg_dnsid" ||
|
"pinswg_dnsid" ||
|
||||||
getFormCollectionByID(
|
getFormCollectionByID(
|
||||||
@@ -1955,7 +1963,9 @@ const CaseSummary = (props) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const linkCaseObj = async () => {
|
const linkCaseObj = async () => {
|
||||||
let docObj = await getLinkedCases(incidentid).then((data) => {
|
let docObj = await getLinkedCases(
|
||||||
|
incidentid || setCaseQueryObj.value[0].incidentid
|
||||||
|
).then((data) => {
|
||||||
//console.log(data);
|
//console.log(data);
|
||||||
setCurrentLinkedCases(data);
|
setCurrentLinkedCases(data);
|
||||||
return data;
|
return data;
|
||||||
@@ -1972,6 +1982,67 @@ const CaseSummary = (props) => {
|
|||||||
|
|
||||||
expDate.setDate(now.getDate() + 365);
|
expDate.setDate(now.getDate() + 365);
|
||||||
|
|
||||||
|
function formatDates(dateObj, showTime) {
|
||||||
|
var dateObj = new Date(dateObj);
|
||||||
|
var dd = String(dateObj.getDate()).padStart(2, "0");
|
||||||
|
var mm = String(dateObj.getMonth() + 1).padStart(2, "0"); //January is 0!
|
||||||
|
var yyyy = dateObj.getFullYear();
|
||||||
|
var hh = dateObj.getHours();
|
||||||
|
hh = ("0" + hh).slice(-2);
|
||||||
|
var mins = dateObj.getMinutes();
|
||||||
|
mins = ("0" + mins).slice(-2);
|
||||||
|
|
||||||
|
const dateStr = showTime
|
||||||
|
? hh == 0 && mins == 0
|
||||||
|
? ""
|
||||||
|
: hh + ":" + mins
|
||||||
|
: dd + "/" + mm + "/" + yyyy + " ";
|
||||||
|
return dateStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function linkedCasesList(linkedCasesReference) {
|
||||||
|
//console.log(linkedCasesReference);
|
||||||
|
|
||||||
|
linkedCasesReference = linkedCasesReference.value || [];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ul className="govuk-list govuk-!-font-size-16">
|
||||||
|
{linkedCasesReference.map((item, key) => {
|
||||||
|
return (
|
||||||
|
<li key={key}>
|
||||||
|
<Link
|
||||||
|
href={
|
||||||
|
router.locale == "cy"
|
||||||
|
? "/canlyniadauchwilio?q=" +
|
||||||
|
item.title +
|
||||||
|
"&lk=1"
|
||||||
|
: "/searchresults?q=" +
|
||||||
|
item.title +
|
||||||
|
"&lk=1"
|
||||||
|
}
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
{item.title}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
//console.log(item.incidentid, item.title);
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showReps(startDate, endDate) {
|
||||||
|
let date = new Date();
|
||||||
|
date = new Date(date.toDateString());
|
||||||
|
const start = new Date(startDate);
|
||||||
|
const end = new Date(endDate);
|
||||||
|
|
||||||
|
return date >= start && date <= end ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
function showRepButton(appealType) {
|
function showRepButton(appealType) {
|
||||||
switch (appealType) {
|
switch (appealType) {
|
||||||
case 846040012:
|
case 846040012:
|
||||||
@@ -2019,6 +2090,14 @@ const CaseSummary = (props) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showRepsEnded(startDate, endDate) {
|
||||||
|
let date = new Date();
|
||||||
|
date = new Date(date.toDateString());
|
||||||
|
const start = new Date(startDate);
|
||||||
|
const end = new Date(endDate);
|
||||||
|
return date > start && date > end ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
if (status == "authenticated" && cookies.pedwWatchCase != null) {
|
if (status == "authenticated" && cookies.pedwWatchCase != null) {
|
||||||
selectWatchedCase(
|
selectWatchedCase(
|
||||||
props.accountDetails.accountDetails.contactid,
|
props.accountDetails.accountDetails.contactid,
|
||||||
|
|||||||
@@ -4,8 +4,14 @@ import CRMError from "./crmError";
|
|||||||
import DNSSearchResults from "./search/dnssearchresults";
|
import DNSSearchResults from "./search/dnssearchresults";
|
||||||
|
|
||||||
export default function Search(props) {
|
export default function Search(props) {
|
||||||
const { searchString, searchResultsObj, myportal, watchedCases, showMap } =
|
const {
|
||||||
props;
|
searchString,
|
||||||
|
searchResultsObj,
|
||||||
|
myportal,
|
||||||
|
watchedCases,
|
||||||
|
showMap,
|
||||||
|
showLoginCheck,
|
||||||
|
} = props;
|
||||||
let { t } = useTranslation();
|
let { t } = useTranslation();
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -41,6 +47,7 @@ export default function Search(props) {
|
|||||||
myportal={myportal}
|
myportal={myportal}
|
||||||
watchedCases={watchedCases}
|
watchedCases={watchedCases}
|
||||||
showMap={showMap}
|
showMap={showMap}
|
||||||
|
showLoginCheck={showLoginCheck}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -748,7 +748,7 @@ const RenderDatePicker = ({
|
|||||||
: value
|
: value
|
||||||
: null
|
: null
|
||||||
} //{parseISO(value) || null}
|
} //{parseISO(value) || null}
|
||||||
className="govuk-input govuk-input--width-12"
|
className="govuk-input govuk-input--width-10"
|
||||||
minDate={minDate}
|
minDate={minDate}
|
||||||
maxDate={maxDate}
|
maxDate={maxDate}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
@@ -1973,10 +1973,6 @@ const RenderFileUpload = (field) => {
|
|||||||
case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
|
case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
|
||||||
return "/assets/images/documenttypes/xlsx.png";
|
return "/assets/images/documenttypes/xlsx.png";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "application/zip":
|
|
||||||
return "/assets/images/documenttypes/zip.png";
|
|
||||||
break;
|
|
||||||
case "image/jpeg":
|
case "image/jpeg":
|
||||||
return "/assets/images/documenttypes/jpg.png";
|
return "/assets/images/documenttypes/jpg.png";
|
||||||
case "image/png":
|
case "image/png":
|
||||||
@@ -2145,7 +2141,6 @@ const RenderFileUpload = (field) => {
|
|||||||
[".docx"],
|
[".docx"],
|
||||||
"image/tiff": [".tif", ".tiff"],
|
"image/tiff": [".tif", ".tiff"],
|
||||||
"image/jpeg": [".jpg", ".jpeg"],
|
"image/jpeg": [".jpg", ".jpeg"],
|
||||||
"application/zip": [".zip"],
|
|
||||||
"image/png": [".png"],
|
"image/png": [".png"],
|
||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
|
||||||
[".xlsx"],
|
[".xlsx"],
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import { JSONPath as jsonpath } from "jsonpath-plus";
|
|||||||
import transLookup from "../data/lookuptranslations.json";
|
import transLookup from "../data/lookuptranslations.json";
|
||||||
|
|
||||||
const MyPortal = (props) => {
|
const MyPortal = (props) => {
|
||||||
const { showFileUpload, showLoginCheck } = props;
|
const { showFileUpload, showLoginCheck, docsOffline } = props;
|
||||||
let { t } = useTranslation();
|
let { t } = useTranslation();
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -126,7 +126,9 @@ const MyPortal = (props) => {
|
|||||||
<div className="govuk-grid-row">
|
<div className="govuk-grid-row">
|
||||||
<div className="govuk-grid-column-full">
|
<div className="govuk-grid-column-full">
|
||||||
<div className="flex-container grid-row govuk-body ">
|
<div className="flex-container grid-row govuk-body ">
|
||||||
{!isLPA && <MakeNewAppeal />}
|
{!isLPA && (
|
||||||
|
<MakeNewAppeal docsOffline={docsOffline} />
|
||||||
|
)}
|
||||||
<SearchCases />
|
<SearchCases />
|
||||||
{/* {props.awaitingSubmission.awaitingSubmission[
|
{/* {props.awaitingSubmission.awaitingSubmission[
|
||||||
"@odata.count"
|
"@odata.count"
|
||||||
@@ -168,6 +170,7 @@ const MyPortal = (props) => {
|
|||||||
watchedCases={props.watchedCases}
|
watchedCases={props.watchedCases}
|
||||||
isLPA={isLPA}
|
isLPA={isLPA}
|
||||||
myReps={false}
|
myReps={false}
|
||||||
|
accountDetails={props.accountDetails}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{props.myRepresentations.hasOwnProperty(
|
{props.myRepresentations.hasOwnProperty(
|
||||||
|
|||||||
@@ -34,12 +34,11 @@ const AwaitingSubmission = (props) => {
|
|||||||
<div className="cardVieAll">
|
<div className="cardVieAll">
|
||||||
<Link
|
<Link
|
||||||
href={
|
href={
|
||||||
(router.locale != "en"
|
router.locale != "en"
|
||||||
? "/" +
|
? "/" +
|
||||||
router.locale +
|
router.locale +
|
||||||
"/fymhorth/gweldpopeth"
|
"/fymhorth/gweldpopeth?key=awaitingSubmission"
|
||||||
: "/myportal/viewall") +
|
: "/myportal/viewall?key=awaitingSubmission"
|
||||||
"?viewKey=awaitingSubmission"
|
|
||||||
}
|
}
|
||||||
className="govuk-link--no-underline"
|
className="govuk-link--no-underline"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|||||||
@@ -351,12 +351,11 @@ const AwaitingSubmissionFromBlob = (props) => {
|
|||||||
<div className="cardVieAll">
|
<div className="cardVieAll">
|
||||||
<Link
|
<Link
|
||||||
href={
|
href={
|
||||||
(router.locale != "en"
|
router.locale != "en"
|
||||||
? "/" +
|
? "/" +
|
||||||
router.locale +
|
router.locale +
|
||||||
"/fymhorth/gweldpopeth"
|
"/fymhorth/gweldpopeth?key=awaitingSubmissionDetails"
|
||||||
: "/myportal/viewall") +
|
: "/myportal/viewall?key=awaitingSubmissionDetails"
|
||||||
"?viewKey=awaitingSubmissionDetails"
|
|
||||||
}
|
}
|
||||||
className="govuk-link--no-underline"
|
className="govuk-link--no-underline"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|||||||
@@ -2,11 +2,46 @@ import useTranslation from "next-translate/useTranslation";
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
|
||||||
export default function MakeNewAppeal() {
|
export default function MakeNewAppeal(props) {
|
||||||
let { t } = useTranslation();
|
let { t } = useTranslation();
|
||||||
|
|
||||||
|
const { docsOffline } = props;
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { locale } = router;
|
const { locale } = router;
|
||||||
|
|
||||||
|
let ShowDocLinks = false;
|
||||||
|
let checkShowDocLinks = docsOffline != false ? true : false;
|
||||||
|
|
||||||
|
const getDocLink = (docsOffline) => {
|
||||||
|
var startTime = docsOffline.split(",")[0];
|
||||||
|
var endTime = docsOffline.split(",")[1];
|
||||||
|
|
||||||
|
// console.log(startTime);
|
||||||
|
// console.log(endTime);
|
||||||
|
|
||||||
|
var currentDate = new Date();
|
||||||
|
|
||||||
|
var startDate = new Date(currentDate.getTime());
|
||||||
|
startDate.setHours(startTime.split(":")[0]);
|
||||||
|
startDate.setMinutes(startTime.split(":")[1]);
|
||||||
|
startDate.setSeconds(startTime.split(":")[2]);
|
||||||
|
|
||||||
|
var endDate = new Date(currentDate.getTime());
|
||||||
|
endDate.setHours(endTime.split(":")[0]);
|
||||||
|
endDate.setMinutes(endTime.split(":")[1]);
|
||||||
|
endDate.setSeconds(endTime.split(":")[2]);
|
||||||
|
|
||||||
|
// console.log(startDate);
|
||||||
|
// console.log(endDate);
|
||||||
|
// console.log(currentDate);
|
||||||
|
|
||||||
|
var valid = startDate < currentDate && endDate > currentDate;
|
||||||
|
ShowDocLinks = valid;
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log("docsOffline", docsOffline, getDocLink(docsOffline));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card" id="new-appeal-card">
|
<div className="card" id="new-appeal-card">
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
@@ -22,11 +57,29 @@ export default function MakeNewAppeal() {
|
|||||||
<p className="govuk-body-s">
|
<p className="govuk-body-s">
|
||||||
{t("myportal:makenewappeal-card-paragraph-two")}
|
{t("myportal:makenewappeal-card-paragraph-two")}
|
||||||
</p>
|
</p>
|
||||||
<div>
|
{ShowDocLinks ? (
|
||||||
<Link href={"/newappeal"} className="govuk-button">
|
<div className="govuk-warning-text ">
|
||||||
{t("myportal:makenewappeal-card-button-label")}
|
<span
|
||||||
</Link>
|
className="govuk-warning-text__icon"
|
||||||
</div>
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
!
|
||||||
|
</span>
|
||||||
|
<strong className="govuk-warning-text__text govuk-!-margin-top-2">
|
||||||
|
<span className="govuk-visually-hidden">
|
||||||
|
Notice
|
||||||
|
</span>
|
||||||
|
{t("myportal:docsoffline-newappeal-label")}
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div>
|
||||||
|
<Link href={"/newappeal"} className="govuk-button">
|
||||||
|
{t("myportal:makenewappeal-card-button-label")}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<p className="govuk-body-s govuk govuk-!-margin-top-5">
|
<p className="govuk-body-s govuk govuk-!-margin-top-5">
|
||||||
{t("myportal:makenewappeal-card-paragraph-three")}
|
{t("myportal:makenewappeal-card-paragraph-three")}
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -29,11 +29,11 @@ const MyCases = (props) => {
|
|||||||
<div className="cardVieAll">
|
<div className="cardVieAll">
|
||||||
<Link
|
<Link
|
||||||
href={
|
href={
|
||||||
(router.locale != "en"
|
router.locale != "en"
|
||||||
? "/" +
|
? "/" +
|
||||||
router.locale +
|
router.locale +
|
||||||
"/fymhorth/gweldpopeth"
|
"/fymhorth/gweldpopeth?key=myCases"
|
||||||
: "/myportal/viewall") + "?viewKey=myCases"
|
: "/myportal/viewall?key=myCases"
|
||||||
}
|
}
|
||||||
className="govuk-link--no-underline"
|
className="govuk-link--no-underline"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|||||||
@@ -34,12 +34,11 @@ const MyRepresentations = (props) => {
|
|||||||
<div className="cardVieAll">
|
<div className="cardVieAll">
|
||||||
<Link
|
<Link
|
||||||
href={
|
href={
|
||||||
(router.locale != "en"
|
router.locale != "en"
|
||||||
? "/" +
|
? "/" +
|
||||||
router.locale +
|
router.locale +
|
||||||
"/fymhorth/gweldpopeth"
|
"/fymhorth/gweldpopeth?key=myRepresentations"
|
||||||
: "/myportal/viewall") +
|
: "/myportal/viewall?key=myRepresentations"
|
||||||
"?viewKey=myRepresentations"
|
|
||||||
}
|
}
|
||||||
className="govuk-link--no-underline"
|
className="govuk-link--no-underline"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|||||||
@@ -33,12 +33,11 @@ const MyRepresentations = (props) => {
|
|||||||
<div className="cardVieAll">
|
<div className="cardVieAll">
|
||||||
<Link
|
<Link
|
||||||
href={
|
href={
|
||||||
(router.locale != "en"
|
router.locale != "en"
|
||||||
? "/" +
|
? "/" +
|
||||||
router.locale +
|
router.locale +
|
||||||
"/fymhorth/gweldpopeth"
|
"/fymhorth/gweldpopeth?key=myRepresentations"
|
||||||
: "/myportal/viewall") +
|
: "/myportal/viewall?key=myRepresentations"
|
||||||
"?viewKey=myRepresentations"
|
|
||||||
}
|
}
|
||||||
className="govuk-link--no-underline"
|
className="govuk-link--no-underline"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|||||||
@@ -40,12 +40,11 @@ const MySubmittedReps = (props) => {
|
|||||||
<div className="cardVieAll">
|
<div className="cardVieAll">
|
||||||
<Link
|
<Link
|
||||||
href={
|
href={
|
||||||
(router.locale != "en"
|
router.locale != "en"
|
||||||
? "/" +
|
? "/" +
|
||||||
router.locale +
|
router.locale +
|
||||||
"/fymhorth/gweldpopeth"
|
"/fymhorth/gweldpopeth?key=mySubmittedReps"
|
||||||
: "/myportal/viewall") +
|
: "/myportal/viewall?key=mySubmittedReps"
|
||||||
"?viewKey=mySubmittedReps"
|
|
||||||
}
|
}
|
||||||
className="govuk-link--no-underline"
|
className="govuk-link--no-underline"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|||||||
@@ -43,6 +43,11 @@ const ServiceBanner = (props) => {
|
|||||||
{portalLogoLink.includes(router.pathname) ? (
|
{portalLogoLink.includes(router.pathname) ? (
|
||||||
<Link href={"/myportal"}>
|
<Link href={"/myportal"}>
|
||||||
<img
|
<img
|
||||||
|
className={
|
||||||
|
router.locale == "cy"
|
||||||
|
? "serviceTitle cy"
|
||||||
|
: "serviceTitle"
|
||||||
|
}
|
||||||
src={
|
src={
|
||||||
router.locale == "cy"
|
router.locale == "cy"
|
||||||
? "/assets/images/planning-casework-cy.svg"
|
? "/assets/images/planning-casework-cy.svg"
|
||||||
@@ -57,6 +62,11 @@ const ServiceBanner = (props) => {
|
|||||||
</Link>
|
</Link>
|
||||||
) : (
|
) : (
|
||||||
<img
|
<img
|
||||||
|
className={
|
||||||
|
router.locale == "cy"
|
||||||
|
? "serviceTitle cy"
|
||||||
|
: "serviceTitle"
|
||||||
|
}
|
||||||
src={
|
src={
|
||||||
router.locale == "cy"
|
router.locale == "cy"
|
||||||
? "/assets/images/planning-casework-cy.svg"
|
? "/assets/images/planning-casework-cy.svg"
|
||||||
@@ -75,7 +85,7 @@ const ServiceBanner = (props) => {
|
|||||||
<div className="serviceBanner_userDetails_name">
|
<div className="serviceBanner_userDetails_name">
|
||||||
<Link
|
<Link
|
||||||
href="/account/personaldetails"
|
href="/account/personaldetails"
|
||||||
className="govuk-button-secondary govuk-link--no-underline"
|
className="govuk-button-secondary govuk-link"
|
||||||
>
|
>
|
||||||
{props.accountDetails.accountDetails.firstname}{" "}
|
{props.accountDetails.accountDetails.firstname}{" "}
|
||||||
{props.accountDetails.accountDetails.lastname}
|
{props.accountDetails.accountDetails.lastname}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ const WatchedCases = (props) => {
|
|||||||
currentView={props.currentView}
|
currentView={props.currentView}
|
||||||
myReps={props.myReps}
|
myReps={props.myReps}
|
||||||
props={props}
|
props={props}
|
||||||
|
accountDetails={props.accountDetails}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -40,12 +41,11 @@ const WatchedCases = (props) => {
|
|||||||
<div className="cardVieAll">
|
<div className="cardVieAll">
|
||||||
<Link
|
<Link
|
||||||
href={
|
href={
|
||||||
(router.locale != "en"
|
router.locale != "en"
|
||||||
? "/" +
|
? "/" +
|
||||||
router.locale +
|
router.locale +
|
||||||
"/fymhorth/gweldpopeth"
|
"/fymhorth/gweldpopeth?key=watchedCases"
|
||||||
: "/myportal/viewall") +
|
: "/myportal/viewall?key=watchedCases"
|
||||||
"?viewKey=watchedCases"
|
|
||||||
}
|
}
|
||||||
className="govuk-link--no-underline"
|
className="govuk-link--no-underline"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|||||||
@@ -311,8 +311,8 @@ const SearchResults = (props) => {
|
|||||||
resultsArrPaged.map((item, key) => {
|
resultsArrPaged.map((item, key) => {
|
||||||
let detailsObj = jsonpath({
|
let detailsObj = jsonpath({
|
||||||
path:
|
path:
|
||||||
'$..value[?(@ && @.pinswg_name=="' +
|
'$..value[?(@ && @.ticketnumber=="' +
|
||||||
item.pinswg_name +
|
item.ticketnumber +
|
||||||
'")]',
|
'")]',
|
||||||
|
|
||||||
json: searchDetailsObj,
|
json: searchDetailsObj,
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ const SearchResults = (props) => {
|
|||||||
const [showSpinnerState, setShowSpinnerState] = useState(false);
|
const [showSpinnerState, setShowSpinnerState] = useState(false);
|
||||||
const [selectedOption, setSelectedOption] = useState(10);
|
const [selectedOption, setSelectedOption] = useState(10);
|
||||||
const [orderByState, setOrderbyState] = useState("createdon");
|
const [orderByState, setOrderbyState] = useState("createdon");
|
||||||
const [fieldSortState, setfieldSortState] = useState("asc");
|
const [fieldSortState, setfieldSortState] = useState("desc");
|
||||||
const [loginToWatch, setLoginToWatch] = useState("true");
|
const [loginToWatch, setLoginToWatch] = useState("true");
|
||||||
|
|
||||||
let spinnerState = () => {
|
let spinnerState = () => {
|
||||||
|
|||||||
@@ -18,7 +18,11 @@ export default function ServiceBanner(props) {
|
|||||||
<div className="servicebanner">
|
<div className="servicebanner">
|
||||||
<h1>
|
<h1>
|
||||||
<img
|
<img
|
||||||
className="govuk-!-margin-top-4"
|
className={
|
||||||
|
router.locale == "cy"
|
||||||
|
? "govuk-!-margin-top-4 serviceTitle cy"
|
||||||
|
: "govuk-!-margin-top-4 serviceTitle"
|
||||||
|
}
|
||||||
src={
|
src={
|
||||||
router.locale == "cy"
|
router.locale == "cy"
|
||||||
? "/assets/images/planning-casework-cy.svg"
|
? "/assets/images/planning-casework-cy.svg"
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import { useState, useCallback } from "react";
|
||||||
|
|
||||||
|
export function useDownloadQueue(maxConcurrent = 3) {
|
||||||
|
const [queue, setQueue] = useState([]); // queued tasks
|
||||||
|
const [activeCount, setActiveCount] = useState(0);
|
||||||
|
const [statuses, setStatuses] = useState({}); // { id: "idle"|"queued"|"downloading"|"done"|"failed" }
|
||||||
|
|
||||||
|
const scheduleNext = useCallback(() => {
|
||||||
|
setQueue((queueCurr) => {
|
||||||
|
if (activeCount >= maxConcurrent || queueCurr.length === 0)
|
||||||
|
return queueCurr;
|
||||||
|
|
||||||
|
const [task, ...rest] = queueCurr;
|
||||||
|
|
||||||
|
setStatuses((s) => ({ ...s, [task.id]: "downloading" }));
|
||||||
|
setActiveCount((c) => c + 1);
|
||||||
|
|
||||||
|
// Run the download fully in async IIFE
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
await task.downloadFn(); // triggers fetch + blob + <a> click
|
||||||
|
setStatuses((s) => ({ ...s, [task.id]: "done" }));
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
setStatuses((s) => ({ ...s, [task.id]: "failed" }));
|
||||||
|
} finally {
|
||||||
|
setActiveCount((c) => c - 1);
|
||||||
|
scheduleNext(); // promote next in queue
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
return rest;
|
||||||
|
});
|
||||||
|
}, [activeCount, maxConcurrent]);
|
||||||
|
|
||||||
|
const startDownload = useCallback(
|
||||||
|
(id, downloadFn) => {
|
||||||
|
setStatuses((s) => ({ ...s, [id]: "queued" }));
|
||||||
|
setQueue((curr) => [...curr, { id, downloadFn }]);
|
||||||
|
scheduleNext();
|
||||||
|
},
|
||||||
|
[scheduleNext]
|
||||||
|
);
|
||||||
|
|
||||||
|
const getStatus = useCallback((id) => statuses[id] || "idle", [statuses]);
|
||||||
|
|
||||||
|
return { startDownload, getStatus };
|
||||||
|
}
|
||||||
@@ -0,0 +1,325 @@
|
|||||||
|
// // import { useState } from "react";
|
||||||
|
|
||||||
|
// // export default function DocumentLink({ detailsObj, caseReference }) {
|
||||||
|
// // const [downloadStatus, setDownloadStatus] = useState("");
|
||||||
|
// // const [progress, setProgress] = useState(null);
|
||||||
|
|
||||||
|
// // const handleDownload = async () => {
|
||||||
|
// // setDownloadStatus("Downloading");
|
||||||
|
// // setProgress(0);
|
||||||
|
|
||||||
|
// // try {
|
||||||
|
// // const res = await fetch(detailsObj.pinswg_hashlink);
|
||||||
|
// // if (!res.ok) throw new Error("Download failed");
|
||||||
|
|
||||||
|
// // const contentDisposition = res.headers.get("content-disposition");
|
||||||
|
// // const filename = contentDisposition
|
||||||
|
// // ? contentDisposition.split("filename=")[1]
|
||||||
|
// // : detailsObj.pinswg_name || "document";
|
||||||
|
|
||||||
|
// // const contentLength = res.headers.get("content-length");
|
||||||
|
// // const totalBytes = contentLength
|
||||||
|
// // ? parseInt(contentLength, 10)
|
||||||
|
// // : null;
|
||||||
|
|
||||||
|
// // const reader = res.body.getReader();
|
||||||
|
// // let receivedBytes = 0;
|
||||||
|
// // const chunks = [];
|
||||||
|
|
||||||
|
// // while (true) {
|
||||||
|
// // const { done, value } = await reader.read();
|
||||||
|
// // if (done) break;
|
||||||
|
|
||||||
|
// // chunks.push(value);
|
||||||
|
// // receivedBytes += value.length;
|
||||||
|
|
||||||
|
// // if (totalBytes) {
|
||||||
|
// // const percent = Math.round(
|
||||||
|
// // (receivedBytes / totalBytes) * 100
|
||||||
|
// // );
|
||||||
|
// // setProgress(percent);
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // // Combine chunks into one blob
|
||||||
|
// // const blob = new Blob(chunks);
|
||||||
|
// // const url = window.URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
// // const link = document.createElement("a");
|
||||||
|
// // link.href = url;
|
||||||
|
// // link.download = filename;
|
||||||
|
// // document.body.appendChild(link);
|
||||||
|
// // link.click();
|
||||||
|
// // document.body.removeChild(link);
|
||||||
|
|
||||||
|
// // setDownloadStatus("Download complete!");
|
||||||
|
// // setProgress(100);
|
||||||
|
|
||||||
|
// // // Fire GA event
|
||||||
|
// // window.gtag?.("event", "DownloadedFile", {
|
||||||
|
// // caseReference,
|
||||||
|
// // filename,
|
||||||
|
// // });
|
||||||
|
// // } catch (err) {
|
||||||
|
// // console.error(err);
|
||||||
|
// // setDownloadStatus("Download failed");
|
||||||
|
// // setProgress(null);
|
||||||
|
// // }
|
||||||
|
// // };
|
||||||
|
|
||||||
|
// // return (
|
||||||
|
// // <>
|
||||||
|
// // {detailsObj.pinswg_publishtoweb ? (
|
||||||
|
// // <button className="documentLink" onClick={handleDownload}>
|
||||||
|
// // <span className="results-visually-hidden">
|
||||||
|
// // Document name:
|
||||||
|
// // </span>
|
||||||
|
// // {detailsObj.pinswg_name || ""}
|
||||||
|
// // </button>
|
||||||
|
// // ) : (
|
||||||
|
// // <>
|
||||||
|
// // <span className="results-visually-hidden">
|
||||||
|
// // Document name:
|
||||||
|
// // </span>
|
||||||
|
// // {detailsObj.pinswg_name || ""}
|
||||||
|
// // </>
|
||||||
|
// // )}
|
||||||
|
|
||||||
|
// // {downloadStatus && (
|
||||||
|
// // <p
|
||||||
|
// // className={
|
||||||
|
// // downloadStatus == "Downloading"
|
||||||
|
// // ? "govuk-!-font-size-14 govuk-!-margin-left-0 textloading"
|
||||||
|
// // : "govuk-!-font-size-14 govuk-!-margin-left-0 "
|
||||||
|
// // }
|
||||||
|
// // >
|
||||||
|
// // {downloadStatus}
|
||||||
|
// // {/* {progress !== null && ` (${progress}%)`} */}
|
||||||
|
// // </p>
|
||||||
|
// // )}
|
||||||
|
// // </>
|
||||||
|
// // );
|
||||||
|
// // }
|
||||||
|
// import { useState } from "react";
|
||||||
|
|
||||||
|
// export default function DocumentLink({
|
||||||
|
// id,
|
||||||
|
// detailsObj,
|
||||||
|
// caseReference,
|
||||||
|
// startDownload,
|
||||||
|
// getStatus,
|
||||||
|
// }) {
|
||||||
|
// const [downloadStatus, setDownloadStatus] = useState("");
|
||||||
|
// const [progress, setProgress] = useState(null);
|
||||||
|
|
||||||
|
// const downloadFile = async () => {
|
||||||
|
// setDownloadStatus("Downloading");
|
||||||
|
// setProgress(0);
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// const res = await fetch(detailsObj.pinswg_hashlink);
|
||||||
|
// if (!res.ok) throw new Error("Download failed");
|
||||||
|
|
||||||
|
// const contentDisposition = res.headers.get("content-disposition");
|
||||||
|
// const filename = contentDisposition
|
||||||
|
// ? contentDisposition.split("filename=")[1]
|
||||||
|
// : detailsObj.pinswg_name || "document";
|
||||||
|
|
||||||
|
// const contentLength = res.headers.get("content-length");
|
||||||
|
// const totalBytes = contentLength
|
||||||
|
// ? parseInt(contentLength, 10)
|
||||||
|
// : null;
|
||||||
|
|
||||||
|
// const reader = res.body.getReader();
|
||||||
|
// let receivedBytes = 0;
|
||||||
|
// const chunks = [];
|
||||||
|
|
||||||
|
// while (true) {
|
||||||
|
// const { done, value } = await reader.read();
|
||||||
|
// if (done) break;
|
||||||
|
|
||||||
|
// chunks.push(value);
|
||||||
|
// receivedBytes += value.length;
|
||||||
|
|
||||||
|
// if (totalBytes) {
|
||||||
|
// const percent = Math.round(
|
||||||
|
// (receivedBytes / totalBytes) * 100
|
||||||
|
// );
|
||||||
|
// setProgress(percent);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const blob = new Blob(chunks);
|
||||||
|
// const url = window.URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
// const link = document.createElement("a");
|
||||||
|
// link.href = url;
|
||||||
|
// link.download = filename;
|
||||||
|
// document.body.appendChild(link);
|
||||||
|
// link.click();
|
||||||
|
// document.body.removeChild(link);
|
||||||
|
|
||||||
|
// setDownloadStatus("Download complete!");
|
||||||
|
// setProgress(100);
|
||||||
|
|
||||||
|
// window.gtag?.("event", "DownloadedFile", {
|
||||||
|
// caseReference,
|
||||||
|
// filename,
|
||||||
|
// });
|
||||||
|
// } catch (err) {
|
||||||
|
// console.error(err);
|
||||||
|
// setDownloadStatus("Download failed");
|
||||||
|
// setProgress(null);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const handleClick = () => {
|
||||||
|
// if (getStatus(id) !== "idle") return; // don't double enqueue
|
||||||
|
// startDownload(id, downloadFile);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const status = getStatus(id);
|
||||||
|
|
||||||
|
// return (
|
||||||
|
// <>
|
||||||
|
// {detailsObj.pinswg_publishtoweb ? (
|
||||||
|
// <button className="documentLink" onClick={handleClick}>
|
||||||
|
// <span className="results-visually-hidden">
|
||||||
|
// Document name:
|
||||||
|
// </span>
|
||||||
|
// {detailsObj.pinswg_name || ""}
|
||||||
|
// </button>
|
||||||
|
// ) : (
|
||||||
|
// <>
|
||||||
|
// <span className="results-visually-hidden">
|
||||||
|
// Document name:
|
||||||
|
// </span>
|
||||||
|
// {detailsObj.pinswg_name || ""}
|
||||||
|
// </>
|
||||||
|
// )}
|
||||||
|
|
||||||
|
// {status !== "idle" && (
|
||||||
|
// <p
|
||||||
|
// className={
|
||||||
|
// status === "downloading"
|
||||||
|
// ? "govuk-!-font-size-14 govuk-!-margin-left-0 textloading"
|
||||||
|
// : "govuk-!-font-size-14 govuk-!-margin-left-0"
|
||||||
|
// }
|
||||||
|
// >
|
||||||
|
// {status === "downloading" && progress !== null
|
||||||
|
// ? `Downloading (${progress}%)`
|
||||||
|
// : status === "queued"
|
||||||
|
// ? "Queued"
|
||||||
|
// : status === "done"
|
||||||
|
// ? "Download complete!"
|
||||||
|
// : status === "failed"
|
||||||
|
// ? "Download failed"
|
||||||
|
// : ""}
|
||||||
|
// </p>
|
||||||
|
// )}
|
||||||
|
// </>
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
|
import useTranslation from "next-translate/useTranslation";
|
||||||
|
|
||||||
|
export default function DocumentLink({
|
||||||
|
id,
|
||||||
|
detailsObj,
|
||||||
|
caseReference,
|
||||||
|
startDownload,
|
||||||
|
getStatus,
|
||||||
|
}) {
|
||||||
|
const [progress, setProgress] = useState(null);
|
||||||
|
let { t } = useTranslation();
|
||||||
|
const downloadFile = async () => {
|
||||||
|
setProgress(0);
|
||||||
|
|
||||||
|
const res = await fetch(detailsObj.pinswg_hashlink);
|
||||||
|
if (!res.ok) throw new Error("Download failed");
|
||||||
|
|
||||||
|
const contentDisposition = res.headers.get("content-disposition");
|
||||||
|
const filename = contentDisposition
|
||||||
|
? contentDisposition.split("filename=")[1]
|
||||||
|
: detailsObj.pinswg_name || "document";
|
||||||
|
|
||||||
|
const contentLength = res.headers.get("content-length");
|
||||||
|
const totalBytes = contentLength ? parseInt(contentLength, 10) : null;
|
||||||
|
|
||||||
|
const reader = res.body.getReader();
|
||||||
|
let receivedBytes = 0;
|
||||||
|
const chunks = [];
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const { done, value } = await reader.read();
|
||||||
|
if (done) break;
|
||||||
|
|
||||||
|
chunks.push(value);
|
||||||
|
receivedBytes += value.length;
|
||||||
|
|
||||||
|
if (totalBytes) {
|
||||||
|
const percent = Math.round((receivedBytes / totalBytes) * 100);
|
||||||
|
setProgress(percent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const blob = new Blob(chunks);
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
const link = document.createElement("a");
|
||||||
|
link.href = url;
|
||||||
|
link.download = filename;
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
|
||||||
|
setProgress(100);
|
||||||
|
window.gtag?.("event", "DownloadedFile", { caseReference, filename });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
if (getStatus(id) !== "idle") return; // avoid double enqueue
|
||||||
|
startDownload(id, downloadFile);
|
||||||
|
};
|
||||||
|
|
||||||
|
const status = getStatus(id);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{detailsObj.pinswg_publishtoweb ? (
|
||||||
|
<button className="documentLink" onClick={handleClick}>
|
||||||
|
<span className="results-visually-hidden">
|
||||||
|
Document name:
|
||||||
|
</span>
|
||||||
|
{detailsObj.pinswg_name || ""}
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<span className="results-visually-hidden">
|
||||||
|
{detailsObj.pinswg_name || ""}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{status !== "idle" && (
|
||||||
|
<p
|
||||||
|
className={
|
||||||
|
status === "downloading"
|
||||||
|
? "govuk-!-font-size-14 govuk-!-margin-left-0 textloading"
|
||||||
|
: "govuk-!-font-size-14 govuk-!-margin-left-0"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{status === "downloading" && progress !== null
|
||||||
|
? t("case:downloading-label")
|
||||||
|
: status === "queued"
|
||||||
|
? t("case:download-queued-label")
|
||||||
|
: status === "done"
|
||||||
|
? t("case:download-complete-label")
|
||||||
|
: status === "failed"
|
||||||
|
? t("case:download-failed-label")
|
||||||
|
: ""}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
+59
-21
@@ -34,6 +34,15 @@ export const getFormCollectionByID = (appealTypeID) => {
|
|||||||
return collectionName[0];
|
return collectionName[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getNavigationPropertyByPrimaryAttribute = (primaryAttribute) => {
|
||||||
|
const collectionName = jsonpath({
|
||||||
|
path: "$..[?(@ && @.PrimaryIdAttribute =='" + primaryAttribute + "')]",
|
||||||
|
json: data,
|
||||||
|
eval: true,
|
||||||
|
});
|
||||||
|
return collectionName[0];
|
||||||
|
};
|
||||||
|
|
||||||
export const getFormIDByLogicalName = (appealTypeLogicalName) => {
|
export const getFormIDByLogicalName = (appealTypeLogicalName) => {
|
||||||
const collectionName = jsonpath({
|
const collectionName = jsonpath({
|
||||||
path: "$..[?(@ && @.LogicalName =='" + appealTypeLogicalName + "')]",
|
path: "$..[?(@ && @.LogicalName =='" + appealTypeLogicalName + "')]",
|
||||||
@@ -170,29 +179,58 @@ export const getPartSavedDetails = (searchResultsObj) => {
|
|||||||
* Get the details of a case from the appeal type
|
* Get the details of a case from the appeal type
|
||||||
* @param object searchResultsObj
|
* @param object searchResultsObj
|
||||||
*/
|
*/
|
||||||
export const getSearchDetailsPaged = (searchResultsObj) => {
|
export const getSearchDetailsPaged = async (searchResultsObj) => {
|
||||||
let detailsArr = [];
|
|
||||||
searchResultsObj = searchResultsObj.value;
|
searchResultsObj = searchResultsObj.value;
|
||||||
const detailsObj = searchResultsObj.map((searchDetail, index) => {
|
|
||||||
if (searchDetail.pinswg_appealcasetype == null) {
|
// Group incidents by appeal type
|
||||||
console.log(searchDetail.title);
|
const groupedByAppealType = searchResultsObj.reduce((acc, detail) => {
|
||||||
} else {
|
const appealType = detail.pinswg_appealcasetype;
|
||||||
let formMeta = getFormCollectionByID(
|
if (!appealType) {
|
||||||
searchDetail.pinswg_appealcasetype
|
console.log("No appeal type for:", detail.title);
|
||||||
);
|
return acc;
|
||||||
// formMeta?.LogicalCollectionName &&
|
|
||||||
// formMeta?.LogicalCollectionName != "pinswg_sipses" &&
|
|
||||||
detailsArr.push(
|
|
||||||
getBasicSearchDetailsPaged(
|
|
||||||
formMeta.LogicalCollectionName,
|
|
||||||
searchDetail.title,
|
|
||||||
formMeta.PrimaryIdAttribute,
|
|
||||||
searchDetail.incidentid
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
return Promise.all(detailsArr);
|
if (!acc[appealType]) acc[appealType] = [];
|
||||||
|
acc[appealType].push({
|
||||||
|
incidentID: detail.incidentid,
|
||||||
|
title: detail.title,
|
||||||
|
});
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
const allDetails = [];
|
||||||
|
|
||||||
|
// For each appeal type, call getBasicSearchDetailsPaged once with all incident IDs
|
||||||
|
for (const [appealType, incidents] of Object.entries(groupedByAppealType)) {
|
||||||
|
const incidentIDs = incidents.map((i) => i.incidentID);
|
||||||
|
|
||||||
|
// Get the form meta for this appeal type to access primaryIdAttribute
|
||||||
|
const formMeta = getFormCollectionByID(appealType);
|
||||||
|
|
||||||
|
if (!formMeta || !formMeta.PrimaryIdAttribute) {
|
||||||
|
console.log(`Missing form metadata for appeal type: ${appealType}`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log(
|
||||||
|
// `Fetching ${incidentIDs.length} incidents for appeal type: ${appealType} with primaryIdAttribute: ${formMeta.PrimaryIdAttribute}`
|
||||||
|
// );
|
||||||
|
|
||||||
|
try {
|
||||||
|
const details = await getBasicSearchDetailsPaged(
|
||||||
|
formMeta.LogicalCollectionName, // appealTypeName
|
||||||
|
null, // caseReference is no longer used in batch
|
||||||
|
formMeta.PrimaryIdAttribute, // primaryIdAttribute
|
||||||
|
incidentIDs // pass array of incidentIDs
|
||||||
|
);
|
||||||
|
|
||||||
|
allDetails.push(...details);
|
||||||
|
} catch (err) {
|
||||||
|
consoleLogger(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return allDetails;
|
||||||
};
|
};
|
||||||
|
|
||||||
// export const absoluteUrl = (req, setLocalhost) => {
|
// export const absoluteUrl = (req, setLocalhost) => {
|
||||||
|
|||||||
+2
-22
@@ -47,27 +47,7 @@
|
|||||||
"UrlName": "transportandworkact",
|
"UrlName": "transportandworkact",
|
||||||
"MetadataId": "bc3edc4b-7d82-eb11-aac0-00224800be9c",
|
"MetadataId": "bc3edc4b-7d82-eb11-aac0-00224800be9c",
|
||||||
"appealTypeID": "846040013",
|
"appealTypeID": "846040013",
|
||||||
"NavigationProperty": "",
|
"NavigationProperty": "pinswg_TransportandWorkActIds",
|
||||||
"value": "Transport and Works Act"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"LogicalCollectionName": "pinswg_transportandworkacts",
|
|
||||||
"LogicalName": "pinswg_transportandworkact",
|
|
||||||
"PrimaryIdAttribute": "pinswg_transportandworkactid",
|
|
||||||
"UrlName": "transportandworkact",
|
|
||||||
"MetadataId": "bc3edc4b-7d82-eb11-aac0-00224800be9c",
|
|
||||||
"appealTypeID": "846040013",
|
|
||||||
"NavigationProperty": "pinswg_TransportandWorkActIdspinswg_TransportandWorkActIds",
|
|
||||||
"value": "Transport and Works Act"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"LogicalCollectionName": "pinswg_transportandworkacts",
|
|
||||||
"LogicalName": "pinswg_transportandworksact",
|
|
||||||
"PrimaryIdAttribute": "pinswg_transportandworkactid",
|
|
||||||
"UrlName": "transportandworksact",
|
|
||||||
"MetadataId": "bc3edc4b-7d82-eb11-aac0-00224800be9c",
|
|
||||||
"appealTypeID": "846040013",
|
|
||||||
"NavigationProperty": "pinswg_TransportandWorkActIdspinswg_TransportandWorkActIds",
|
|
||||||
"value": "Transport and Works Act"
|
"value": "Transport and Works Act"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -378,7 +358,7 @@
|
|||||||
"UrlName": "sips",
|
"UrlName": "sips",
|
||||||
"MetadataId": "8d31911b-b8ea-ef11-ab08-00224800be9c",
|
"MetadataId": "8d31911b-b8ea-ef11-ab08-00224800be9c",
|
||||||
"appealTypeID": "846040002",
|
"appealTypeID": "846040002",
|
||||||
"NavigationProperty": "pinswg_SIPSIds",
|
"NavigationProperty": "pinswg_sipscase",
|
||||||
"value": "SIP"
|
"value": "SIP"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -78,5 +78,6 @@ module.exports = {
|
|||||||
"/auth/signin": ["common", "common", "auth"],
|
"/auth/signin": ["common", "common", "auth"],
|
||||||
"/auth/verify-request": ["common", "common", "auth"],
|
"/auth/verify-request": ["common", "common", "auth"],
|
||||||
"/auth/error": ["common", "common", "auth"],
|
"/auth/error": ["common", "common", "auth"],
|
||||||
|
"/admin": ["case"],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -109,10 +109,16 @@
|
|||||||
"trying-to-watch-case-redirect-label": "Fe'ch anogir nawr i fewngofnodi",
|
"trying-to-watch-case-redirect-label": "Fe'ch anogir nawr i fewngofnodi",
|
||||||
"you-have-stopped-watching-label": "Ydych chi am roi'r gorau i wylio achos ",
|
"you-have-stopped-watching-label": "Ydych chi am roi'r gorau i wylio achos ",
|
||||||
"do-you-want-to-delete-case-label": "Ydych chi am ddileu achos",
|
"do-you-want-to-delete-case-label": "Ydych chi am ddileu achos",
|
||||||
|
"do-you-want-to-delete-rep-label": "Ydych chi eisiau dileu cynrychiolaeth sy'n aros i'w chyflwyno",
|
||||||
"do-you-want-to-delete-case-disclaimer-label": "Ar ôl dileu, bydd yr holl wybodaeth a gyflwynwyd gennych yn cael ei cholli.",
|
"do-you-want-to-delete-case-disclaimer-label": "Ar ôl dileu, bydd yr holl wybodaeth a gyflwynwyd gennych yn cael ei cholli.",
|
||||||
"representation-date-passed-label": "Mae'r cyfnod cyflwyno sylwadau ar gyfer yr apêl hon rhwng {{startDate}} a {{endDate}}",
|
"representation-date-passed-label": "Mae'r cyfnod cyflwyno sylwadau ar gyfer yr apêl hon rhwng {{startDate}} a {{endDate}}",
|
||||||
"representation-date-passed-additional-label": "Gallwch wneud sylw drwy e-bostio,",
|
"representation-date-passed-additional-label": "Gallwch wneud sylw drwy e-bostio,",
|
||||||
"date-raised": "Dyddiad codi",
|
"date-raised": "Dyddiad codi",
|
||||||
|
"download-complete-label": "Lawrlwytho wedi'i gwblhau!",
|
||||||
|
"downloading-label": "Wrthi'n llwytho i lawr",
|
||||||
|
"download-failed-label": "Methodd y lawrlwythiad",
|
||||||
|
"download-queued-label": "Wedi'i giwio",
|
||||||
|
"docsoffline-reps-label": "Oherwydd cynnal a chadw'r system, ni allwn dderbyn sylwadau ar hyn o bryd. Rhowch gynnig arall arni yn nes ymlaen.",
|
||||||
"event-title": "Digwyddiadau",
|
"event-title": "Digwyddiadau",
|
||||||
"event-name-label": " Enw",
|
"event-name-label": " Enw",
|
||||||
"event-event-name-label": "Enw'r digwyddiad ",
|
"event-event-name-label": "Enw'r digwyddiad ",
|
||||||
|
|||||||
@@ -52,5 +52,6 @@
|
|||||||
"date-raised": "Dyddiad codi",
|
"date-raised": "Dyddiad codi",
|
||||||
"representation-submitted": "Cyflwynwyd y sylw",
|
"representation-submitted": "Cyflwynwyd y sylw",
|
||||||
"submission-processing-label": "Prosesu cyflwyniad",
|
"submission-processing-label": "Prosesu cyflwyniad",
|
||||||
"appeal-pending-label": "Yn yr arfaeth"
|
"appeal-pending-label": "Yn yr arfaeth",
|
||||||
|
"docsoffline-newappeal-label": "Oherwydd gwaith cynnal a chadw'r system, ni allwn dderbyn apeliadau newydd ar hyn o bryd. Rhowch gynnig arall arni yn nes ymlaen."
|
||||||
}
|
}
|
||||||
@@ -110,10 +110,16 @@
|
|||||||
"trying-to-watch-case-redirect-label": "You will now be prompted to sign in",
|
"trying-to-watch-case-redirect-label": "You will now be prompted to sign in",
|
||||||
"you-have-stopped-watching-label": "Do you want to stop watching case ",
|
"you-have-stopped-watching-label": "Do you want to stop watching case ",
|
||||||
"do-you-want-to-delete-case-label": "Do you want to delete case ",
|
"do-you-want-to-delete-case-label": "Do you want to delete case ",
|
||||||
|
"do-you-want-to-delete-rep-label": "Do you want to delete representation awaiting submission",
|
||||||
"do-you-want-to-delete-case-disclaimer-label": "Once deleted all information you have submited, will be lost.",
|
"do-you-want-to-delete-case-disclaimer-label": "Once deleted all information you have submited, will be lost.",
|
||||||
"representation-date-passed-label": "The representation period for this appeal is between {{startDate}} and {{endDate}}",
|
"representation-date-passed-label": "The representation period for this appeal is between {{startDate}} and {{endDate}}",
|
||||||
"representation-date-passed-additional-label": "You can make a representation by emailing,",
|
"representation-date-passed-additional-label": "You can make a representation by emailing,",
|
||||||
"date-raised": "Date raised",
|
"date-raised": "Date raised",
|
||||||
|
"download-complete-label": "Download complete!",
|
||||||
|
"downloading-label": "Downloading",
|
||||||
|
"download-failed-label": "Download failed",
|
||||||
|
"download-queued-label": "Queued",
|
||||||
|
"docsoffline-reps-label": "Due to system maintenance, we are unable to accept representations at this time. Please try again later.",
|
||||||
"event-title": "Events",
|
"event-title": "Events",
|
||||||
"event-name-label": "Name",
|
"event-name-label": "Name",
|
||||||
"event-event-name-label": "Event name",
|
"event-event-name-label": "Event name",
|
||||||
|
|||||||
@@ -52,5 +52,6 @@
|
|||||||
"date-raised": "Date raised",
|
"date-raised": "Date raised",
|
||||||
"representation-submitted": "Representation submitted",
|
"representation-submitted": "Representation submitted",
|
||||||
"submission-processing-label": "Submission processing",
|
"submission-processing-label": "Submission processing",
|
||||||
"appeal-pending-label": "Pending"
|
"appeal-pending-label": "Pending",
|
||||||
|
"docsoffline-newappeal-label": "Due to system maintenance, we are unable to accept new appeals at this time. Please try again later."
|
||||||
}
|
}
|
||||||
Vendored
+1
-2
@@ -1,6 +1,5 @@
|
|||||||
/// <reference types="next" />
|
/// <reference types="next" />
|
||||||
/// <reference types="next/image-types/global" />
|
/// <reference types="next/image-types/global" />
|
||||||
/// <reference types="next/navigation-types/compat/navigation" />
|
|
||||||
|
|
||||||
// NOTE: This file should not be edited
|
// NOTE: This file should not be edited
|
||||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
|
||||||
|
|||||||
@@ -0,0 +1,216 @@
|
|||||||
|
// pages/admin/storage.js
|
||||||
|
import { useState } from "react";
|
||||||
|
import Head from "next/head";
|
||||||
|
import CookieBanner from "../../components/cookieBanner";
|
||||||
|
import Header from "../../components/header";
|
||||||
|
import Footer from "../../components/footer";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { wrapper } from "../../store/store";
|
||||||
|
|
||||||
|
import StorageTab from "../../components/admin/tabs/storage";
|
||||||
|
import AccountsTab from "../../components/admin/tabs/accounts";
|
||||||
|
import AppealsTab from "../../components/admin/tabs/appeals";
|
||||||
|
import DocumentsTab from "../../components/admin/tabs/documents";
|
||||||
|
|
||||||
|
import { fetchAdminStorageData } from "../../components/admin/utils/serverside";
|
||||||
|
import { getNewAppeals } from "../../actions";
|
||||||
|
|
||||||
|
import { getSearchDetails } from "../../components/utils";
|
||||||
|
|
||||||
|
import {
|
||||||
|
setSearchDetails,
|
||||||
|
setSearchResults,
|
||||||
|
} from "../../store/searchOutput/action";
|
||||||
|
import { setCurrentPage } from "../../store/currentView/action";
|
||||||
|
|
||||||
|
const StoragePage = (props) => {
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
userData,
|
||||||
|
repCompleteCount,
|
||||||
|
searchResultsObj,
|
||||||
|
docsOffline,
|
||||||
|
showFilteredDocs,
|
||||||
|
} = props;
|
||||||
|
const [whichTab, setWhichTab] = useState("documents");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Head>
|
||||||
|
<title>Admin Browser</title>
|
||||||
|
</Head>
|
||||||
|
<div id="page_wrapper">
|
||||||
|
<CookieBanner />
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
<div
|
||||||
|
className="govuk-width-containera"
|
||||||
|
style={{ width: "90%", margin: "auto" }}
|
||||||
|
>
|
||||||
|
<div className="js-enabled govuk-template__body govuk-frontend-supported">
|
||||||
|
<div className="govuk-tabs" data-module="govuk-tabs">
|
||||||
|
<h2 className="govuk-tabs__title">Contents</h2>
|
||||||
|
|
||||||
|
{/* Tabs */}
|
||||||
|
<ul className="govuk-tabs__list">
|
||||||
|
{[
|
||||||
|
"documents",
|
||||||
|
"appeals",
|
||||||
|
"storage",
|
||||||
|
"accounts",
|
||||||
|
].map((tab) => (
|
||||||
|
<li
|
||||||
|
key={tab}
|
||||||
|
className={
|
||||||
|
whichTab === tab
|
||||||
|
? "govuk-tabs__list-item govuk-tabs__list-item--selected"
|
||||||
|
: "govuk-tabs__list-item"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
className="govuk-tabs__tab"
|
||||||
|
href={`#${tab}`}
|
||||||
|
onClick={() => {
|
||||||
|
setWhichTab(tab);
|
||||||
|
tab === "appeals" &&
|
||||||
|
props.setCurrentPage(1);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
{tab === "documents" &&
|
||||||
|
"Latest Documents"}
|
||||||
|
{tab === "appeals" &&
|
||||||
|
"Latest Appeals"}
|
||||||
|
{tab === "storage" &&
|
||||||
|
"Storage Account"}
|
||||||
|
{tab === "accounts" &&
|
||||||
|
"User Accounts"}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{/* Panels */}
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
whichTab === "documents"
|
||||||
|
? "govuk-tabs__panel"
|
||||||
|
: "govuk-tabs__panel govuk-tabs__panel--hidden"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<DocumentsTab
|
||||||
|
documentDetailsObj={
|
||||||
|
props.searchResultsObj
|
||||||
|
.documentDetailsObj
|
||||||
|
}
|
||||||
|
docsOffline={docsOffline}
|
||||||
|
showFilteredDocs={props.showFilteredDocs}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
whichTab === "appeals"
|
||||||
|
? "govuk-tabs__panel"
|
||||||
|
: "govuk-tabs__panel govuk-tabs__panel--hidden"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<AppealsTab
|
||||||
|
searchResultsObj={searchResultsObj}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
whichTab === "storage"
|
||||||
|
? "govuk-tabs__panel"
|
||||||
|
: "govuk-tabs__panel govuk-tabs__panel--hidden"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<StorageTab
|
||||||
|
data={data}
|
||||||
|
repCompleteCount={repCompleteCount}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
whichTab === "accounts"
|
||||||
|
? "govuk-tabs__panel"
|
||||||
|
: "govuk-tabs__panel govuk-tabs__panel--hidden"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<AccountsTab userData={userData} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getServerSideProps = wrapper.getServerSideProps(
|
||||||
|
(store) => async (ctx) => {
|
||||||
|
const { query, req, res } = ctx;
|
||||||
|
// IP restriction check
|
||||||
|
const ALLOWED_IPS = process.env.ALLOWED_IPS
|
||||||
|
? process.env.ALLOWED_IPS.split(",").map((ip) => ip.trim())
|
||||||
|
: [];
|
||||||
|
const LOCALHOST_IPS = ["127.0.0.1", "::1"];
|
||||||
|
const forwarded = req.headers["x-forwarded-for"];
|
||||||
|
const ip =
|
||||||
|
typeof forwarded === "string"
|
||||||
|
? forwarded.split(",")[0]
|
||||||
|
: req.socket.remoteAddress;
|
||||||
|
|
||||||
|
if (![...ALLOWED_IPS, ...LOCALHOST_IPS].includes(ip)) {
|
||||||
|
return {
|
||||||
|
redirect: { destination: "/403", permanent: false },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔹 fetch actual data
|
||||||
|
const { data, userData, repCompleteCount } =
|
||||||
|
await fetchAdminStorageData();
|
||||||
|
|
||||||
|
const newAppeals = await getNewAppeals();
|
||||||
|
|
||||||
|
const searchDetailsObj = await getSearchDetails(newAppeals);
|
||||||
|
|
||||||
|
store.dispatch(setSearchResults(newAppeals));
|
||||||
|
store.dispatch(setSearchDetails(searchDetailsObj));
|
||||||
|
const state = store.getState();
|
||||||
|
|
||||||
|
store.dispatch(setCurrentPage(1));
|
||||||
|
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
data,
|
||||||
|
userData,
|
||||||
|
repCompleteCount,
|
||||||
|
docsOffline: process.env.DOCAPI_OFFLINE || false,
|
||||||
|
showFilteredDocs: process.env.SHOWFILTERDOCS || false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) => {
|
||||||
|
return {
|
||||||
|
setCurrentPage: (currentPage) => {
|
||||||
|
dispatch(setCurrentPage(currentPage));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => {
|
||||||
|
console.log("===============================\n state:", state);
|
||||||
|
return {
|
||||||
|
searchResultsObj: state.searchResultsObj,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(StoragePage);
|
||||||
@@ -124,8 +124,8 @@ export const getServerSideProps = wrapper.getServerSideProps(
|
|||||||
// "=============================== Advanced Search results:",
|
// "=============================== Advanced Search results:",
|
||||||
// searchResultsObj
|
// searchResultsObj
|
||||||
// );
|
// );
|
||||||
const searchDetailsObj =
|
// const searchDetailsObj =
|
||||||
(await getSearchDetails(searchResultsObj)) || null;
|
// (await getSearchDetails(searchResultsObj)) || null;
|
||||||
// console.log(
|
// console.log(
|
||||||
// "=============================== Advanced Search results details:",
|
// "=============================== Advanced Search results details:",
|
||||||
// searchDetailsObj
|
// searchDetailsObj
|
||||||
@@ -136,7 +136,7 @@ export const getServerSideProps = wrapper.getServerSideProps(
|
|||||||
store.dispatch(setShowReps(showReps, showLoginCheck));
|
store.dispatch(setShowReps(showReps, showLoginCheck));
|
||||||
|
|
||||||
store.dispatch(setSearchResults(searchResultsObj));
|
store.dispatch(setSearchResults(searchResultsObj));
|
||||||
store.dispatch(setSearchDetails(searchDetailsObj));
|
// store.dispatch(setSearchDetails(searchDetailsObj));
|
||||||
store.dispatch(setSearch(Object.entries(query)));
|
store.dispatch(setSearch(Object.entries(query)));
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
|
|||||||
@@ -0,0 +1,180 @@
|
|||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/endpoint/getbasicsearch_api:
|
||||||
|
* get:
|
||||||
|
* tags: [Search]
|
||||||
|
* description: Basic search
|
||||||
|
* parameters:
|
||||||
|
* - name: searchString
|
||||||
|
* in: query
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: Success
|
||||||
|
*/
|
||||||
|
|
||||||
|
import axios from "axios";
|
||||||
|
import CryptoJS from "crypto-js";
|
||||||
|
import _ from "lodash";
|
||||||
|
import {
|
||||||
|
azureHeadersPagedCustom,
|
||||||
|
consoleLogger,
|
||||||
|
getToken,
|
||||||
|
} from "../../../actions";
|
||||||
|
import { number } from "prop-types";
|
||||||
|
|
||||||
|
const WORDKEY = process.env.HASHKEY;
|
||||||
|
|
||||||
|
const WEBAPI_URL =
|
||||||
|
process.env.RELAY_ROOT ||
|
||||||
|
"https://dev-pedw-ns.servicebus.windows.net/dev-pedw-hc/";
|
||||||
|
|
||||||
|
const hashAPIPath = (queryPath) => {
|
||||||
|
var hashlink = CryptoJS.HmacSHA256(
|
||||||
|
queryPath,
|
||||||
|
CryptoJS.enc.Hex.parse(WORDKEY)
|
||||||
|
);
|
||||||
|
hashlink = hashlink.toString(CryptoJS.enc.Hex);
|
||||||
|
|
||||||
|
//return "&hash=" + hashlink;
|
||||||
|
|
||||||
|
return (queryPath.indexOf("?") > -1 ? "&hash=" : "?hash=") + hashlink;
|
||||||
|
};
|
||||||
|
|
||||||
|
const encryptDocReference = (documentRef) => {
|
||||||
|
var hashlink = CryptoJS.HmacSHA256(
|
||||||
|
"documents/download/" + documentRef,
|
||||||
|
CryptoJS.enc.Hex.parse(WORDKEY)
|
||||||
|
);
|
||||||
|
hashlink = hashlink.toString(CryptoJS.enc.Hex);
|
||||||
|
|
||||||
|
var hashStr =
|
||||||
|
"/api/documents/download/" + documentRef + "?hash=" + hashlink;
|
||||||
|
|
||||||
|
return hashStr;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default async function ApiProxy(req, res) {
|
||||||
|
var pageNumber = req.query.pageNumber || 1;
|
||||||
|
var token = await getToken();
|
||||||
|
|
||||||
|
var orderby = req.query.orderby || "createdon";
|
||||||
|
var fieldSort = req.query.fieldSort || "desc";
|
||||||
|
var showNumberOfRecords = req.query.showNumberOfRecords || 10;
|
||||||
|
var documentType = req.query.documentType || "all";
|
||||||
|
var documentOrigin = req.query.documentOrigin || "all";
|
||||||
|
var numberOfWeeks = req.query.numberWeeks || 1;
|
||||||
|
|
||||||
|
var docTypeQueryString = "";
|
||||||
|
var docOriginQueryString = "";
|
||||||
|
|
||||||
|
if (documentType != "all") {
|
||||||
|
if (documentType.indexOf(",") >= 0) {
|
||||||
|
const documentTypeArr = documentType.split(",");
|
||||||
|
|
||||||
|
docTypeQueryString = " and (";
|
||||||
|
documentTypeArr.forEach(function (item, index) {
|
||||||
|
console.log(item, index);
|
||||||
|
|
||||||
|
if (item != "all") {
|
||||||
|
docTypeQueryString +=
|
||||||
|
" pinswg_isharedocumentlocations eq " + item;
|
||||||
|
|
||||||
|
docTypeQueryString +=
|
||||||
|
index < documentTypeArr.length - 1 ? " or " : "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
docTypeQueryString += " )";
|
||||||
|
} else {
|
||||||
|
docTypeQueryString +=
|
||||||
|
" and pinswg_isharedocumentlocations eq " + documentType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (documentOrigin != "all") {
|
||||||
|
if (documentOrigin.indexOf(",") >= 0) {
|
||||||
|
const documentOriginArr = documentOrigin.split(",");
|
||||||
|
|
||||||
|
docOriginQueryString = " and (";
|
||||||
|
documentOriginArr.forEach(function (item, index) {
|
||||||
|
console.log(item, index);
|
||||||
|
|
||||||
|
if (item != "all") {
|
||||||
|
docOriginQueryString += " pinswg_origin eq " + item;
|
||||||
|
|
||||||
|
docOriginQueryString +=
|
||||||
|
index < documentOriginArr.length - 1 ? " or " : "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
docOriginQueryString += " )";
|
||||||
|
} else {
|
||||||
|
docOriginQueryString += " and pinswg_origin eq " + documentOrigin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function daysAgoISO(days) {
|
||||||
|
const today = new Date();
|
||||||
|
const resultDate = new Date(today);
|
||||||
|
resultDate.setUTCDate(today.getUTCDate() - days); // subtract weeks
|
||||||
|
resultDate.setUTCHours(0, 0, 0, 0); // reset time to 00:00:00
|
||||||
|
return resultDate.toISOString().replace(/\.000Z$/, "Z"); // format as 'YYYY-MM-DDT00:00:00Z'
|
||||||
|
}
|
||||||
|
|
||||||
|
var queryUrl =
|
||||||
|
"pinswg_documents?$select=pinswg_name,createdon,pinswg_publishtoweb,_pinswg_documentids_value,pinswg_isharedocumentlocations,pinswg_isharedocumentreference,pinswg_uploadurl,pinswg_uploadstatus,pinswg_origin&$filter=createdon ge " +
|
||||||
|
daysAgoISO(numberOfWeeks) +
|
||||||
|
docTypeQueryString +
|
||||||
|
docOriginQueryString +
|
||||||
|
"&$orderby=" +
|
||||||
|
orderby +
|
||||||
|
" " +
|
||||||
|
fieldSort +
|
||||||
|
"&$count=true" +
|
||||||
|
"&$expand=pinswg_DocumentIds($select = ticketnumber,pinswg_publishtoweb)" +
|
||||||
|
(typeof pageNumber != "undefined"
|
||||||
|
? "&$skiptoken=" + '<cookie pagenumber="' + pageNumber + '" />'
|
||||||
|
: "");
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
"\n==========================================\n",
|
||||||
|
"\nnew docs search---- ",
|
||||||
|
"\n\nQuery url: " + queryUrl,
|
||||||
|
"\n\nRelay link: " + WEBAPI_URL + queryUrl + hashAPIPath(queryUrl),
|
||||||
|
"\n==========================================\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
var apiResponse = axios
|
||||||
|
.get(
|
||||||
|
WEBAPI_URL + queryUrl + hashAPIPath(queryUrl),
|
||||||
|
azureHeadersPagedCustom(token.access_token, showNumberOfRecords)
|
||||||
|
)
|
||||||
|
.then(({ data }) => {
|
||||||
|
let flattened = data.value.map((r) => ({
|
||||||
|
...r,
|
||||||
|
ticketnumber: r.pinswg_DocumentIds?.ticketnumber || null,
|
||||||
|
publishtoweb: r.pinswg_DocumentIds?.pinswg_publishtoweb || null,
|
||||||
|
}));
|
||||||
|
|
||||||
|
data.value = flattened;
|
||||||
|
data.value.forEach(function (element) {
|
||||||
|
element.pinswg_hashlink = encryptDocReference(
|
||||||
|
element.pinswg_isharedocumentreference
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
var dataStr;
|
||||||
|
|
||||||
|
_.has(data, "@odata.nextLink") == true &&
|
||||||
|
((dataStr = JSON.stringify(data["@odata.nextLink"])),
|
||||||
|
(data["@odata.nextLink"] = dataStr.split("/v8.2/")[1]));
|
||||||
|
res.status(200).json(data);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
consoleLogger(error);
|
||||||
|
res.status(400).json(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
return apiResponse;
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
/**
|
||||||
|
* @swagger
|
||||||
|
* /api/endpoint/getbasicsearch_api:
|
||||||
|
* get:
|
||||||
|
* tags: [Search]
|
||||||
|
* description: Basic search
|
||||||
|
* parameters:
|
||||||
|
* - name: searchString
|
||||||
|
* in: query
|
||||||
|
* required: true
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: Success
|
||||||
|
*/
|
||||||
|
|
||||||
|
import axios from "axios";
|
||||||
|
import CryptoJS from "crypto-js";
|
||||||
|
import _ from "lodash";
|
||||||
|
import {
|
||||||
|
azureHeadersPagedCustom,
|
||||||
|
consoleLogger,
|
||||||
|
getToken,
|
||||||
|
} from "../../../actions";
|
||||||
|
|
||||||
|
const WORDKEY = process.env.HASHKEY;
|
||||||
|
|
||||||
|
const WEBAPI_URL =
|
||||||
|
process.env.RELAY_ROOT ||
|
||||||
|
"https://dev-pedw-ns.servicebus.windows.net/dev-pedw-hc/";
|
||||||
|
|
||||||
|
const hashAPIPath = (queryPath) => {
|
||||||
|
var hashlink = CryptoJS.HmacSHA256(
|
||||||
|
queryPath,
|
||||||
|
CryptoJS.enc.Hex.parse(WORDKEY)
|
||||||
|
);
|
||||||
|
hashlink = hashlink.toString(CryptoJS.enc.Hex);
|
||||||
|
|
||||||
|
//return "&hash=" + hashlink;
|
||||||
|
|
||||||
|
return (queryPath.indexOf("?") > -1 ? "&hash=" : "?hash=") + hashlink;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default async function ApiProxy(req, res) {
|
||||||
|
var searchString = req.query.searchString;
|
||||||
|
var pageNumber = req.query.pageNumber || 1;
|
||||||
|
var token = await getToken();
|
||||||
|
|
||||||
|
var orderby = req.query.orderby || "createdon";
|
||||||
|
var fieldSort = req.query.fieldSort || "desc";
|
||||||
|
var showNumberOfRecords = req.query.showNumberOfRecords || 10;
|
||||||
|
|
||||||
|
var queryUrl =
|
||||||
|
"incidents?$select=caseorigincode,pinswg_publishtoweb,modifiedon,description,numberofchildincidents,_accountid_value,_customerid_value,_pinswg_associatedlpa_value,_ownerid_value,pinswg_appealcasetype,statuscode,ticketnumber,title, _primarycontactid_value,pinswg_lpareference,pinswg_appellantagent,pinswg_appellantfirstname,pinswg_appellantlastname&$expand=primarycontactid($select=fullname)&$orderby=" +
|
||||||
|
orderby +
|
||||||
|
" " +
|
||||||
|
fieldSort +
|
||||||
|
"&$count=true" +
|
||||||
|
(typeof pageNumber != "undefined"
|
||||||
|
? "&$skiptoken=" + '<cookie pagenumber="' + pageNumber + '" />'
|
||||||
|
: "");
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
"\n==========================================\n",
|
||||||
|
"\nnew appeal search ",
|
||||||
|
"\n\nQuery url: " + queryUrl,
|
||||||
|
"\n\nRelay link: " + WEBAPI_URL + queryUrl + hashAPIPath(queryUrl),
|
||||||
|
"\n==========================================\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
var apiResponse = axios
|
||||||
|
.get(
|
||||||
|
WEBAPI_URL + queryUrl + hashAPIPath(queryUrl),
|
||||||
|
azureHeadersPagedCustom(token.access_token, showNumberOfRecords)
|
||||||
|
)
|
||||||
|
.then(({ data }) => {
|
||||||
|
var dataStr;
|
||||||
|
_.has(data, "@odata.nextLink") == true &&
|
||||||
|
((dataStr = JSON.stringify(data["@odata.nextLink"])),
|
||||||
|
(data["@odata.nextLink"] = dataStr.split("/v8.2/")[1]));
|
||||||
|
res.status(200).json(data);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
consoleLogger(error);
|
||||||
|
res.status(400).json(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
return apiResponse;
|
||||||
|
}
|
||||||
@@ -1,110 +1,203 @@
|
|||||||
/**
|
// /**
|
||||||
* @swagger
|
// * @swagger
|
||||||
* /api/documents/download/{id}:
|
// * /api/documents/download/{id}:
|
||||||
* get:
|
// * get:
|
||||||
* tags:
|
// * tags:
|
||||||
* - Documents
|
// * - Documents
|
||||||
* description: Get document
|
// * description: Get document
|
||||||
* parameters:
|
// * parameters:
|
||||||
* - name: id
|
// * - name: id
|
||||||
* in: path
|
// * in: path
|
||||||
* description: iShare ID
|
// * description: iShare ID
|
||||||
* type: string
|
// * type: string
|
||||||
* required: true
|
// * required: true
|
||||||
* default: A41567436
|
// * default: A41567436
|
||||||
* - name: hash
|
// * - name: hash
|
||||||
* in: query
|
// * in: query
|
||||||
* description: Hash string
|
// * description: Hash string
|
||||||
* default: e0a1c9cd2817826a25bca67e60b807eae747cbed769e3ec42cf997541c32be71
|
// * default: e0a1c9cd2817826a25bca67e60b807eae747cbed769e3ec42cf997541c32be71
|
||||||
* responses:
|
// * responses:
|
||||||
* 200:
|
// * 200:
|
||||||
* description: Success
|
// * description: Success
|
||||||
*/
|
// */
|
||||||
|
|
||||||
|
// import axios from "axios";
|
||||||
|
// import CryptoJS from "crypto-js";
|
||||||
|
// import { getToken, consoleLogger } from "../../../../actions";
|
||||||
|
|
||||||
|
// const WORDKEY = process.env.HASHKEY;
|
||||||
|
// const accessTokenEndpoint = process.env.ACCESS_TOKEN_ENDPOINT;
|
||||||
|
// const tenantId = process.env.TENANT;
|
||||||
|
|
||||||
|
// const WEBAPI_URL =
|
||||||
|
// process.env.RELAY_ROOT ||
|
||||||
|
// "https://dev-pedw-ns.servicebus.windows.net/dev-pedw-hc/";
|
||||||
|
|
||||||
|
// const hashAPIPath = (queryPath) => {
|
||||||
|
// var hashlink = CryptoJS.HmacSHA256(
|
||||||
|
// queryPath,
|
||||||
|
// CryptoJS.enc.Hex.parse(WORDKEY)
|
||||||
|
// );
|
||||||
|
// hashlink = hashlink.toString(CryptoJS.enc.Hex);
|
||||||
|
|
||||||
|
// //return "&hash=" + hashlink;
|
||||||
|
|
||||||
|
// return (queryPath.indexOf("?") > -1 ? "&hash=" : "?hash=") + hashlink;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const azureHeadersPaged = (access_token) => {
|
||||||
|
// return {
|
||||||
|
// headers: {
|
||||||
|
// "OData-MaxVersion": "4.0",
|
||||||
|
// "OData-Version": "4.0",
|
||||||
|
// "Accept": "application/json;odata.metadata=none",
|
||||||
|
// "Prefer":
|
||||||
|
// 'odata.include-annotations="*",return=representation, odata.maxpagesize=10',
|
||||||
|
// "Content-Type": "application/json",
|
||||||
|
// "Authorization": "Bearer " + access_token,
|
||||||
|
// },
|
||||||
|
// };
|
||||||
|
// };
|
||||||
|
|
||||||
|
// export default async function ApiProxy(req, res) {
|
||||||
|
// var token = await getToken();
|
||||||
|
|
||||||
|
// var docRef = req.query;
|
||||||
|
|
||||||
|
// var queryUrl = "documents/download/" + docRef.id + "?hash=" + docRef.hash;
|
||||||
|
|
||||||
|
// const configDocument = (access_token) => {
|
||||||
|
// return {
|
||||||
|
// headers: {
|
||||||
|
// "OData-MaxVersion": "4.0",
|
||||||
|
// "OData-Version": "4.0",
|
||||||
|
// "Accept": "application/json",
|
||||||
|
// "Prefer": 'odata.include-annotations="*",return=representation',
|
||||||
|
// "Content-Type": "application/json",
|
||||||
|
// "Authorization": "Bearer " + access_token,
|
||||||
|
// },
|
||||||
|
// responseType: "arraybuffer",
|
||||||
|
// };
|
||||||
|
// };
|
||||||
|
|
||||||
|
// return axios
|
||||||
|
// .get(
|
||||||
|
// WEBAPI_URL + queryUrl, // + hashAPIPath(queryUrl),
|
||||||
|
// configDocument(token.access_token)
|
||||||
|
// )
|
||||||
|
// .then((response) => {
|
||||||
|
// const bytes = response.data.byteLength;
|
||||||
|
// console.log(bytes);
|
||||||
|
|
||||||
|
// res.setHeader(
|
||||||
|
// "content-disposition",
|
||||||
|
// "attachment; filename=" +
|
||||||
|
// response.headers["content-disposition"].split(
|
||||||
|
// "filename="
|
||||||
|
// )[1]
|
||||||
|
// );
|
||||||
|
// return res.status(200).send(response.data);
|
||||||
|
// })
|
||||||
|
// .then(() => {
|
||||||
|
// console.log(docRef.id + "has downloaded");
|
||||||
|
|
||||||
|
// return "downloadComplete";
|
||||||
|
// })
|
||||||
|
// .catch((error) => {
|
||||||
|
// consoleLogger(error);
|
||||||
|
// res.redirect("/filenotavailable");
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import CryptoJS from "crypto-js";
|
|
||||||
import { getToken, consoleLogger } from "../../../../actions";
|
import { getToken, consoleLogger } from "../../../../actions";
|
||||||
|
|
||||||
const WORDKEY = process.env.HASHKEY;
|
|
||||||
const accessTokenEndpoint = process.env.ACCESS_TOKEN_ENDPOINT;
|
|
||||||
const tenantId = process.env.TENANT;
|
|
||||||
|
|
||||||
const WEBAPI_URL =
|
const WEBAPI_URL =
|
||||||
process.env.RELAY_ROOT ||
|
process.env.RELAY_ROOT ||
|
||||||
"https://dev-pedw-ns.servicebus.windows.net/dev-pedw-hc/";
|
"https://dev-pedw-ns.servicebus.windows.net/dev-pedw-hc/";
|
||||||
|
|
||||||
const hashAPIPath = (queryPath) => {
|
// Retry utility with logging
|
||||||
var hashlink = CryptoJS.HmacSHA256(
|
async function retry(fn, retries = 3, delay = 1000) {
|
||||||
queryPath,
|
for (let attempt = 1; attempt <= retries; attempt++) {
|
||||||
CryptoJS.enc.Hex.parse(WORDKEY)
|
try {
|
||||||
);
|
return { response: await fn(), attempts: attempt };
|
||||||
hashlink = hashlink.toString(CryptoJS.enc.Hex);
|
} catch (err) {
|
||||||
|
if (attempt === retries) throw err;
|
||||||
//return "&hash=" + hashlink;
|
console.log(`Retry ${attempt} failed, retrying in ${delay}ms...`);
|
||||||
|
await new Promise((res) => setTimeout(res, delay));
|
||||||
return (queryPath.indexOf("?") > -1 ? "&hash=" : "?hash=") + hashlink;
|
delay *= 2; // exponential backoff
|
||||||
};
|
}
|
||||||
|
}
|
||||||
const azureHeadersPaged = (access_token) => {
|
|
||||||
return {
|
|
||||||
headers: {
|
|
||||||
"OData-MaxVersion": "4.0",
|
|
||||||
"OData-Version": "4.0",
|
|
||||||
"Accept": "application/json;odata.metadata=none",
|
|
||||||
"Prefer":
|
|
||||||
'odata.include-annotations="*",return=representation, odata.maxpagesize=10',
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Authorization": "Bearer " + access_token,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default async function ApiProxy(req, res) {
|
|
||||||
var token = await getToken();
|
|
||||||
|
|
||||||
var docRef = req.query;
|
|
||||||
|
|
||||||
var queryUrl = "documents/download/" + docRef.id + "?hash=" + docRef.hash;
|
|
||||||
|
|
||||||
const configDocument = (access_token) => {
|
|
||||||
return {
|
|
||||||
headers: {
|
|
||||||
"OData-MaxVersion": "4.0",
|
|
||||||
"OData-Version": "4.0",
|
|
||||||
"Accept": "application/json",
|
|
||||||
"Prefer": 'odata.include-annotations="*",return=representation',
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Authorization": "Bearer " + access_token,
|
|
||||||
},
|
|
||||||
responseType: "arraybuffer",
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
return axios
|
|
||||||
.get(
|
|
||||||
WEBAPI_URL + queryUrl, // + hashAPIPath(queryUrl),
|
|
||||||
configDocument(token.access_token)
|
|
||||||
)
|
|
||||||
.then((response) => {
|
|
||||||
const bytes = response.data.byteLength;
|
|
||||||
console.log(bytes);
|
|
||||||
|
|
||||||
res.setHeader(
|
|
||||||
"content-disposition",
|
|
||||||
"attachment; filename=" +
|
|
||||||
response.headers["content-disposition"].split(
|
|
||||||
"filename="
|
|
||||||
)[1]
|
|
||||||
);
|
|
||||||
return res.status(200).send(response.data);
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
console.log(docRef.id + "has downloaded");
|
|
||||||
|
|
||||||
return "downloadComplete";
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
consoleLogger(error);
|
|
||||||
res.redirect("/filenotavailable");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ApiProxy = async (req, res) => {
|
||||||
|
const docRef = req.query;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const token = await getToken();
|
||||||
|
const startTime = Date.now();
|
||||||
|
|
||||||
|
const fetchStream = async () => {
|
||||||
|
const queryUrl =
|
||||||
|
"documents/download/" + docRef.id + "?hash=" + docRef.hash;
|
||||||
|
|
||||||
|
return axios.get(WEBAPI_URL + queryUrl, {
|
||||||
|
headers: {
|
||||||
|
"OData-MaxVersion": "4.0",
|
||||||
|
"OData-Version": "4.0",
|
||||||
|
"Accept": "application/json",
|
||||||
|
"Prefer":
|
||||||
|
'odata.include-annotations="*",return=representation',
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Authorization": "Bearer " + token.access_token,
|
||||||
|
},
|
||||||
|
responseType: "stream",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const { response, attempts } = await retry(fetchStream, 3, 1000);
|
||||||
|
|
||||||
|
// Extract filename
|
||||||
|
const contentDisposition = response.headers["content-disposition"];
|
||||||
|
const filename = contentDisposition
|
||||||
|
? contentDisposition.split("filename=")[1]
|
||||||
|
: docRef.id;
|
||||||
|
|
||||||
|
res.setHeader(
|
||||||
|
"Content-Disposition",
|
||||||
|
`attachment; filename=${filename}`
|
||||||
|
);
|
||||||
|
res.setHeader("Content-Type", "application/octet-stream");
|
||||||
|
|
||||||
|
let totalBytes = 0;
|
||||||
|
|
||||||
|
response.data.on("data", (chunk) => {
|
||||||
|
totalBytes += chunk.length;
|
||||||
|
});
|
||||||
|
|
||||||
|
response.data.pipe(res);
|
||||||
|
|
||||||
|
response.data.on("end", () => {
|
||||||
|
const durationMs = Date.now() - startTime;
|
||||||
|
console.log(
|
||||||
|
`[Download Complete] Document: ${filename}, ID: ${docRef.id}, Size: ${totalBytes} bytes, Duration: ${durationMs}ms, Attempts: ${attempts}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
response.data.on("error", (err) => {
|
||||||
|
consoleLogger(err);
|
||||||
|
if (!res.headersSent) res.redirect("/filenotavailable");
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
consoleLogger(error);
|
||||||
|
if (!res.headersSent) res.redirect("/filenotavailable");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
api: {
|
||||||
|
responseLimit: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ApiProxy;
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ export default async function ApiProxy(req, res) {
|
|||||||
"MetadataId": "8d31911b-b8ea-ef11-ab08-00224800be9c",
|
"MetadataId": "8d31911b-b8ea-ef11-ab08-00224800be9c",
|
||||||
"appealTypeID": "846040002",
|
"appealTypeID": "846040002",
|
||||||
"tmpNav": "pinswg_sipsid",
|
"tmpNav": "pinswg_sipsid",
|
||||||
"NavigationProperty": "pinswg_SIPSids",
|
"NavigationProperty": "pinswg_sipscase",
|
||||||
"value": "SIP",
|
"value": "SIP",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import CryptoJS from "crypto-js";
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import { azureHeadersPaged, consoleLogger, getToken } from "../../../actions";
|
import { azureHeadersPaged, consoleLogger, getToken } from "../../../actions";
|
||||||
import { getSelectQuery } from "../../../actions/selectQueryTypes";
|
import { getSelectQuery } from "../../../actions/selectQueryTypes";
|
||||||
|
import { getNavigationPropertyByPrimaryAttribute } from "../../../components/utils";
|
||||||
const WORDKEY = process.env.HASHKEY;
|
const WORDKEY = process.env.HASHKEY;
|
||||||
|
|
||||||
const WEBAPI_URL =
|
const WEBAPI_URL =
|
||||||
@@ -59,15 +59,27 @@ export default async function ApiProxy(req, res) {
|
|||||||
var incidentID = req.query.incidentID;
|
var incidentID = req.query.incidentID;
|
||||||
var token = await getToken();
|
var token = await getToken();
|
||||||
|
|
||||||
|
let navigationProperty =
|
||||||
|
getNavigationPropertyByPrimaryAttribute(
|
||||||
|
primaryIdAttribute
|
||||||
|
).NavigationProperty;
|
||||||
|
|
||||||
|
// "?$filter=_" +
|
||||||
|
// (primaryIdAttribute == "pinswg_sipscase"
|
||||||
|
// ? "pinswg_sipscase_value"
|
||||||
|
// : primaryIdAttribute + "s_value ") +
|
||||||
|
// " eq " +
|
||||||
|
// incidentID +
|
||||||
|
|
||||||
var queryUrl =
|
var queryUrl =
|
||||||
appealTypeName +
|
appealTypeName +
|
||||||
"?$filter=_" +
|
"?$filter=" +
|
||||||
(primaryIdAttribute == "pinswg_sipscase"
|
|
||||||
? "pinswg_sipscase_value"
|
|
||||||
: primaryIdAttribute + "s_value ") +
|
|
||||||
" eq " +
|
|
||||||
incidentID +
|
incidentID +
|
||||||
"&$count=true";
|
"&$count=true" +
|
||||||
|
"&$expand=" +
|
||||||
|
navigationProperty +
|
||||||
|
"($select=ticketnumber)";
|
||||||
|
|
||||||
//" and statuscode eq 1&$count=true";
|
//" and statuscode eq 1&$count=true";
|
||||||
|
|
||||||
queryUrl =
|
queryUrl =
|
||||||
@@ -86,10 +98,18 @@ export default async function ApiProxy(req, res) {
|
|||||||
azureHeadersPaged(token.access_token)
|
azureHeadersPaged(token.access_token)
|
||||||
)
|
)
|
||||||
.then(({ data }) => {
|
.then(({ data }) => {
|
||||||
|
let flattened = data.value.map((r) => ({
|
||||||
|
...r,
|
||||||
|
ticketnumber: r[navigationProperty]?.ticketnumber || null,
|
||||||
|
}));
|
||||||
|
|
||||||
|
data.value = flattened;
|
||||||
|
|
||||||
var dataStr;
|
var dataStr;
|
||||||
_.has(data, "@odata.nextLink") == true &&
|
_.has(data, "@odata.nextLink") == true &&
|
||||||
((dataStr = JSON.stringify(data["@odata.nextLink"])),
|
((dataStr = JSON.stringify(data["@odata.nextLink"])),
|
||||||
(data["@odata.nextLink"] = dataStr.split("/v8.2/")[1]));
|
(data["@odata.nextLink"] = dataStr.split("/v8.2/")[1]));
|
||||||
|
|
||||||
return res.status(200).json(data);
|
return res.status(200).json(data);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
|||||||
@@ -207,6 +207,35 @@ const SignIn = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export async function getServerSideProps(context) {
|
export async function getServerSideProps(context) {
|
||||||
|
const { query, req, res } = context;
|
||||||
|
|
||||||
|
// Load allowed IPs from env and trim spaces
|
||||||
|
const ALLOWED_IPS = process.env.ALLOWED_IPS
|
||||||
|
? process.env.ALLOWED_IPS.split(",").map((ip) => ip.trim())
|
||||||
|
: [];
|
||||||
|
|
||||||
|
// Always allow localhost addresses
|
||||||
|
const LOCALHOST_IPS = ["127.0.0.1", "::1"];
|
||||||
|
|
||||||
|
// Get IP address from headers or socket
|
||||||
|
const forwarded = req.headers["x-forwarded-for"];
|
||||||
|
const ip =
|
||||||
|
typeof forwarded === "string"
|
||||||
|
? forwarded.split(",")[0]
|
||||||
|
: req.socket.remoteAddress;
|
||||||
|
|
||||||
|
console.log("Visitor IP:", ip);
|
||||||
|
|
||||||
|
// Check whitelist + localhost
|
||||||
|
if (![...ALLOWED_IPS, ...LOCALHOST_IPS].includes(ip)) {
|
||||||
|
return {
|
||||||
|
redirect: {
|
||||||
|
destination: "/403", // custom "Access Denied" page
|
||||||
|
permanent: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (process.env.SHOWLOGIN == false) {
|
if (process.env.SHOWLOGIN == false) {
|
||||||
return {
|
return {
|
||||||
redirect: {
|
redirect: {
|
||||||
|
|||||||
@@ -81,9 +81,16 @@ const CaseHome = (props) => {
|
|||||||
props.awaitingSubmission.awaitingSubmission
|
props.awaitingSubmission.awaitingSubmission
|
||||||
}
|
}
|
||||||
caseReference={
|
caseReference={
|
||||||
|
props.searchResultsObj.searchResultsObj.value[0]
|
||||||
|
.caseReference
|
||||||
|
}
|
||||||
|
ticketnumber={
|
||||||
props.searchResultsObj.searchResultsObj.value[0]
|
props.searchResultsObj.searchResultsObj.value[0]
|
||||||
.ticketnumber
|
.ticketnumber
|
||||||
}
|
}
|
||||||
|
// ticketnumber={
|
||||||
|
// props.currentView.caseReference.ticketnumber
|
||||||
|
// }
|
||||||
currentType={props.currentType}
|
currentType={props.currentType}
|
||||||
appealTypeID={
|
appealTypeID={
|
||||||
props.searchResultsObj.searchResultsObj.value[0]
|
props.searchResultsObj.searchResultsObj.value[0]
|
||||||
|
|||||||
+37
-29
@@ -20,7 +20,7 @@ import { wrapper } from "../store/store";
|
|||||||
import ServiceBanner from "../components/servicebanner";
|
import ServiceBanner from "../components/servicebanner";
|
||||||
|
|
||||||
const Home = (props) => {
|
const Home = (props) => {
|
||||||
const { footerLinks, pages, showMap } = props;
|
const { footerLinks, pages, showMap, showLoginCheck } = props;
|
||||||
let { t, lang } = useTranslation();
|
let { t, lang } = useTranslation();
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -105,6 +105,7 @@ const Home = (props) => {
|
|||||||
showMap={showMap}
|
showMap={showMap}
|
||||||
searchString="DNS"
|
searchString="DNS"
|
||||||
searchResultsObj={props.searchResultsObj}
|
searchResultsObj={props.searchResultsObj}
|
||||||
|
showLoginCheck={showLoginCheck}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Footer footerLinks={footerLinks} ticketnumber={props} />
|
<Footer footerLinks={footerLinks} ticketnumber={props} />
|
||||||
@@ -123,40 +124,47 @@ export const getServerSideProps = wrapper.getServerSideProps(
|
|||||||
"public, s-maxage=10, stale-while-revalidate=59"
|
"public, s-maxage=10, stale-while-revalidate=59"
|
||||||
);
|
);
|
||||||
|
|
||||||
let searchResultsObj = await getBasicDNSSearch();
|
// let searchResultsObj = await getBasicDNSSearch();
|
||||||
|
|
||||||
searchResultsObj =
|
// searchResultsObj =
|
||||||
searchResultsObj.status == 502
|
// searchResultsObj.status == 502
|
||||||
? {
|
// ? {
|
||||||
value: [],
|
// value: [],
|
||||||
errorCode: searchResultsObj.status,
|
// errorCode: searchResultsObj.status,
|
||||||
errorMsg: searchResultsObj.statusText,
|
// errorMsg: searchResultsObj.statusText,
|
||||||
}
|
// }
|
||||||
: searchResultsObj;
|
// : searchResultsObj;
|
||||||
|
|
||||||
|
const showLoginCheck = process.env.SHOWLOGIN || false;
|
||||||
const showMapCheck = process.env.SHOWMAPS || false;
|
const showMapCheck = process.env.SHOWMAPS || false;
|
||||||
|
|
||||||
if (_.has(searchResultsObj, "status") == true) {
|
// if (_.has(searchResultsObj, "status") == true) {
|
||||||
return {
|
// return {
|
||||||
redirect: {
|
// redirect: {
|
||||||
//destination: "/dns-not-found",
|
// //destination: "/dns-not-found",
|
||||||
destination: "/error",
|
// destination: "/error",
|
||||||
permanent: false,
|
// permanent: false,
|
||||||
},
|
// },
|
||||||
};
|
// };
|
||||||
} else {
|
// } else {
|
||||||
const searchDetailsObj = await getSearchDetails(
|
// // const searchDetailsObj = await getSearchDetails(
|
||||||
searchResultsObj
|
// // searchResultsObj
|
||||||
);
|
// // );
|
||||||
const dnsCoords = await getDNSCoords();
|
// const dnsCoords = await getDNSCoords();
|
||||||
store.dispatch(setSearchResults(searchResultsObj));
|
// // store.dispatch(setSearchResults(searchResultsObj));
|
||||||
store.dispatch(setSearchDetails(searchDetailsObj));
|
// // store.dispatch(setSearchDetails(searchDetailsObj));
|
||||||
store.dispatch(setSearch("DNS"));
|
// store.dispatch(setSearch("DNS"));
|
||||||
store.dispatch(setDNSCoords(dnsCoords));
|
// store.dispatch(setDNSCoords(dnsCoords));
|
||||||
}
|
// }
|
||||||
|
const dnsCoords = await getDNSCoords();
|
||||||
|
store.dispatch(setSearch("DNS"));
|
||||||
|
store.dispatch(setDNSCoords(dnsCoords));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: { showMap: showMapCheck },
|
props: {
|
||||||
|
showMap: showMapCheck,
|
||||||
|
showLoginCheck: showLoginCheck,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -70,7 +70,9 @@ const CaseHome = (props) => {
|
|||||||
<Head>
|
<Head>
|
||||||
<title>
|
<title>
|
||||||
Reference:{" "}
|
Reference:{" "}
|
||||||
{props.currentView.caseReference.currentReference}{" "}
|
{props.currentView.caseReference.currentReference ||
|
||||||
|
props.searchResultsObj.searchResultsObj.value[0]
|
||||||
|
.title}{" "}
|
||||||
</title>
|
</title>
|
||||||
</Head>
|
</Head>
|
||||||
<div id="page_wrapper">
|
<div id="page_wrapper">
|
||||||
@@ -104,18 +106,17 @@ const CaseHome = (props) => {
|
|||||||
props.awaitingSubmission.awaitingSubmission
|
props.awaitingSubmission.awaitingSubmission
|
||||||
}
|
}
|
||||||
caseReference={
|
caseReference={
|
||||||
props.searchResultsObj.searchResultsObj.value[0]
|
props.currentView.caseReference.currentReference
|
||||||
.ticketnumber
|
}
|
||||||
|
ticketnumber={
|
||||||
|
props.currentView.caseReference.ticketnumber ||
|
||||||
|
router.query.ticketnumber
|
||||||
}
|
}
|
||||||
currentType={props.currentType}
|
currentType={props.currentType}
|
||||||
appealTypeID={
|
appealTypeID={
|
||||||
props.searchResultsObj.searchResultsObj.value[0]
|
props.currentView.caseReference.appealType
|
||||||
.pinswg_appealcasetype
|
|
||||||
}
|
|
||||||
incidentid={
|
|
||||||
props.searchResultsObj.searchResultsObj.value[0]
|
|
||||||
.incidentid
|
|
||||||
}
|
}
|
||||||
|
incidentid={props.currentView.caseReference.incidentid}
|
||||||
representationsObj={
|
representationsObj={
|
||||||
props.searchResultsObj.representationsObj
|
props.searchResultsObj.representationsObj
|
||||||
}
|
}
|
||||||
@@ -220,10 +221,10 @@ export const getServerSideProps = wrapper.getServerSideProps(
|
|||||||
|
|
||||||
store.dispatch(setSearch(developmentQuery));
|
store.dispatch(setSearch(developmentQuery));
|
||||||
|
|
||||||
console.log(
|
// console.log(
|
||||||
searchResultsObj["@odata.count"] > 1 ||
|
// searchResultsObj["@odata.count"] > 1 ||
|
||||||
searchResultsObj["@odata.count"] < 1
|
// searchResultsObj["@odata.count"] < 1
|
||||||
);
|
// );
|
||||||
|
|
||||||
if (searchResultsObj["@odata.count"] < 1) {
|
if (searchResultsObj["@odata.count"] < 1) {
|
||||||
return {
|
return {
|
||||||
@@ -440,6 +441,7 @@ const getDetails = (resultsObj, detailsType) => {
|
|||||||
];
|
];
|
||||||
break;
|
break;
|
||||||
case "awaitingSubmission":
|
case "awaitingSubmission":
|
||||||
|
case "myWatchedCases":
|
||||||
case "myRepresentations":
|
case "myRepresentations":
|
||||||
caseID = data.ticketnumber;
|
caseID = data.ticketnumber;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -58,9 +58,10 @@ const Home = (props) => {
|
|||||||
showLoginCheck,
|
showLoginCheck,
|
||||||
currentView,
|
currentView,
|
||||||
mySubmittedReps,
|
mySubmittedReps,
|
||||||
|
docsOffline,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const { t } = useTranslation();
|
let { t, lang } = useTranslation();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { locale, query } = router;
|
const { locale, query } = router;
|
||||||
const { appealtypes } = query;
|
const { appealtypes } = query;
|
||||||
@@ -150,6 +151,7 @@ const Home = (props) => {
|
|||||||
containerID={accountDetails.containerID}
|
containerID={accountDetails.containerID}
|
||||||
showLoginCheck={showLoginCheck}
|
showLoginCheck={showLoginCheck}
|
||||||
currentView={currentView}
|
currentView={currentView}
|
||||||
|
docsOffline={docsOffline}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Footer footerLinks={footerLinks} ticketnumber={props} />
|
<Footer footerLinks={footerLinks} ticketnumber={props} />
|
||||||
@@ -357,6 +359,7 @@ export const getServerSideProps = wrapper.getServerSideProps(
|
|||||||
showFileUpload: Boolean(process.env.SHOWFILEUPLOAD),
|
showFileUpload: Boolean(process.env.SHOWFILEUPLOAD),
|
||||||
containerID: thisSession.user.id,
|
containerID: thisSession.user.id,
|
||||||
showLoginCheck,
|
showLoginCheck,
|
||||||
|
docsOffline: process.env.DOCAPI_OFFLINE || false,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-23
@@ -132,33 +132,34 @@ export const getServerSideProps = wrapper.getServerSideProps(
|
|||||||
const showReps = process.env.SHOWREPRESENTATIONS || false;
|
const showReps = process.env.SHOWREPRESENTATIONS || false;
|
||||||
store.dispatch(setShowReps(showReps, showLoginCheck));
|
store.dispatch(setShowReps(showReps, showLoginCheck));
|
||||||
|
|
||||||
let searchResultsObj = await getBasicSearch(query.q);
|
// let searchResultsObj = await getBasicSearch(query.q);
|
||||||
|
|
||||||
searchResultsObj =
|
// searchResultsObj =
|
||||||
searchResultsObj.status == 502
|
// searchResultsObj.status == 502
|
||||||
? {
|
// ? {
|
||||||
value: [],
|
// value: [],
|
||||||
errorCode: searchResultsObj.status,
|
// errorCode: searchResultsObj.status,
|
||||||
errorMsg: searchResultsObj.statusText,
|
// errorMsg: searchResultsObj.statusText,
|
||||||
}
|
// }
|
||||||
: searchResultsObj;
|
// : searchResultsObj;
|
||||||
|
|
||||||
if (_.has(searchResultsObj, "status") == true) {
|
// if (_.has(searchResultsObj, "status") == true) {
|
||||||
return {
|
// return {
|
||||||
redirect: {
|
// redirect: {
|
||||||
//destination: "/dns-not-found",
|
// //destination: "/dns-not-found",
|
||||||
destination: "/error",
|
// destination: "/error",
|
||||||
permanent: false,
|
// permanent: false,
|
||||||
},
|
// },
|
||||||
};
|
// };
|
||||||
} else {
|
// } else {
|
||||||
const searchDetailsObj = await getSearchDetails(searchResultsObj);
|
// // const searchDetailsObj = await getSearchDetails(searchResultsObj);
|
||||||
|
|
||||||
store.dispatch(setSearchResults(searchResultsObj));
|
// store.dispatch(setSearchResults(searchResultsObj));
|
||||||
store.dispatch(setSearchDetails(searchDetailsObj));
|
// // store.dispatch(setSearchDetails(searchDetailsObj));
|
||||||
store.dispatch(setSearch(query.q));
|
// store.dispatch(setSearch(query.q));
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
store.dispatch(setSearch(query.q));
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
isLinkedCase: isLinked,
|
isLinkedCase: isLinked,
|
||||||
|
|||||||
@@ -84,6 +84,8 @@ html[data-useragent*="MSIE 10.0"] .flex-container {
|
|||||||
font-size: 1.17rem;
|
font-size: 1.17rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.card-body {
|
.card-body {
|
||||||
//border-bottom: 1px solid $govuk-border-colour; //$panel-colour;
|
//border-bottom: 1px solid $govuk-border-colour; //$panel-colour;
|
||||||
padding: 40px 20px;
|
padding: 40px 20px;
|
||||||
@@ -328,3 +330,15 @@ div.cardModuleItem:last-of-type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.card {
|
||||||
|
.cardList-nobullet {
|
||||||
|
list-style-type: none;
|
||||||
|
padding-left: 20px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -300,6 +300,17 @@ a.longLinkBreak {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 670px) {
|
@media screen and (max-width: 670px) {
|
||||||
|
img {
|
||||||
|
|
||||||
|
&.serviceTitle {
|
||||||
|
width: 236px;
|
||||||
|
|
||||||
|
&.cy {
|
||||||
|
width: 238px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
flex-direction: column-reverse;
|
flex-direction: column-reverse;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|
||||||
@@ -539,7 +550,7 @@ a.longLinkBreak {
|
|||||||
label {
|
label {
|
||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
background-color: $lightgrey_semi;
|
background-color: $lightgrey_semi;
|
||||||
padding: 20px 20px 20px 20px;
|
padding: 20px 20px 20px 50px;
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
top: 18px;
|
top: 18px;
|
||||||
@@ -742,7 +753,7 @@ textarea,
|
|||||||
right: -10px;
|
right: -10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.govuk-header__link {
|
a.govuk-header__link {
|
||||||
background-color: $black;
|
background-color: $black;
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@@ -754,9 +765,9 @@ textarea,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.govuk-header__link:focus {
|
a.govuk-header__link:focus {
|
||||||
background-color: $black;
|
background-color: $black;
|
||||||
padding: 10px 20px;
|
padding: 10px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
@@ -1465,6 +1476,22 @@ textarea,
|
|||||||
top: calc(50% - 10px);
|
top: calc(50% - 10px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.documentLink {
|
||||||
|
border: none;
|
||||||
|
text-align: left;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #0360a6;
|
||||||
|
display: block;
|
||||||
|
padding-left: 0px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $white;
|
||||||
|
color: #3b7dc5;
|
||||||
|
border: none;
|
||||||
|
padding-left: 0px
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.appealModule {
|
.appealModule {
|
||||||
@@ -1506,6 +1533,14 @@ textarea,
|
|||||||
.govuk-summary-list__key {
|
.govuk-summary-list__key {
|
||||||
width: 45%;
|
width: 45%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#login-card {
|
||||||
|
.heading-small {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.react-datepicker__input-container input {
|
.react-datepicker__input-container input {
|
||||||
@@ -2848,8 +2883,6 @@ fade {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.fieldArrayLink {
|
.fieldArrayLink {
|
||||||
border: none;
|
border: none;
|
||||||
background: no-repeat;
|
background: no-repeat;
|
||||||
@@ -2971,6 +3004,10 @@ fade {
|
|||||||
.govuk-label-s {
|
.govuk-label-s {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.govuk-checkboxes_short {
|
||||||
|
height: 180px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user