Merge branch 'develop'
commit
289b05d6f5
|
@ -2144,21 +2144,45 @@ Result in JSON
|
||||||
| message | string | Web Message Body |
|
| message | string | Web Message Body |
|
||||||
| created_datetime| float | Web Message Created Datetime (POSIX timestamp * 1000)|
|
| created_datetime| float | Web Message Created Datetime (POSIX timestamp * 1000)|
|
||||||
| status | string | Status ('new', 'acknowledged', 'timeout') |
|
| status | string | Status ('new', 'acknowledged', 'timeout') |
|
||||||
| reply | string | User's Reply text, allow null |
|
| reply | string | User's Reply text, required for 'acknowledged' status, otherwise allow null |
|
||||||
```bash
|
```bash
|
||||||
curl -i -H "User-UUID: 793f1bb4-6e25-4242-8cdc-2f662b25484f" -H "Token: GET-TOKEN-AFTER-LOGIN" -X GET {{base_url}}/webmessages/{id}
|
curl --location --request GET '{{base_url}}/webmessages/{id}' \
|
||||||
|
--header 'User-UUID: dcdb67d1-6116-4987-916f-6fc6cf2bc0e4' \
|
||||||
|
--header 'Token: 24bb236244f26784fb1397344d926b4871e87a90096eae926a0e448396dbd3ff4a2f70f727089f025238cb47bdbccdc877ef4a50fad8f05a4e5100c5d3eb0d3c'
|
||||||
```
|
```
|
||||||
* GET Web Messages by Datetime Range
|
* GET Web Messages by Datetime Range
|
||||||
```bash
|
```bash
|
||||||
curl -i -H "User-UUID: 793f1bb4-6e25-4242-8cdc-2f662b25484f" -H "Token: GET-TOKEN-AFTER-LOGIN" -X GET {{base_url}}/webmessages?startdatetime={startdatetime}&enddatetime={enddatetime}
|
curl --location --request GET '{{base_url}}/webmessages?startdatetime=2021-12-11T00:00:00&enddatetime=2021-12-21T00:00:00' \
|
||||||
|
--header 'User-UUID: dcdb67d1-6116-4987-916f-6fc6cf2bc0e4' \
|
||||||
|
--header 'Token: 9ac434f394c735092cfeb083612e533ca33ca6db4815ebb0c3ff47896d7eaa610e7dc312c04279253f817d65d1ef379378d4a5d07150faee5f6d899adb8b7ca7'
|
||||||
```
|
```
|
||||||
* GET New Web Messages
|
* GET New Web Messages
|
||||||
```bash
|
```bash
|
||||||
curl -i -H "User-UUID: 793f1bb4-6e25-4242-8cdc-2f662b25484f" -H "Token: GET-TOKEN-AFTER-LOGIN" -X GET {{base_url}}/webmessagesnew
|
curl --location --request GET '{{base_url}}/webmessagesnew' \
|
||||||
|
--header 'User-UUID: dcdb67d1-6116-4987-916f-6fc6cf2bc0e4' \
|
||||||
|
--header 'Token: 9bcd171e4f4169f1f45791aeadc8f90cfe8694be92f21af7bf95673f8cc910ca7a91bfd4a577d48d0720155de497eb02baab614be5c6c83891f1a856f9cf666a'
|
||||||
|
```
|
||||||
|
* PUT Update a Web Message (Acknowledge)
|
||||||
|
```bash
|
||||||
|
curl --location --request PUT '{{base_url}}/webmessages/{id}' \
|
||||||
|
--header 'User-UUID: dcdb67d1-6116-4987-916f-6fc6cf2bc0e4' \
|
||||||
|
--header 'Token: 9bcd171e4f4169f1f45791aeadc8f90cfe8694be92f21af7bf95673f8cc910ca7a91bfd4a577d48d0720155de497eb02baab614be5c6c83891f1a856f9cf666a' \
|
||||||
|
--header 'Content-Type: text/plain' \
|
||||||
|
--data-raw '{"data":{"status":"acknowledged", "reply":"this is my reply"}}'
|
||||||
|
```
|
||||||
|
* PUT Update a Web Message (Mark As Read)
|
||||||
|
```bash
|
||||||
|
curl --location --request PUT '{{base_url}}/webmessages/{id}' \
|
||||||
|
--header 'User-UUID: dcdb67d1-6116-4987-916f-6fc6cf2bc0e4' \
|
||||||
|
--header 'Token: 9bcd171e4f4169f1f45791aeadc8f90cfe8694be92f21af7bf95673f8cc910ca7a91bfd4a577d48d0720155de497eb02baab614be5c6c83891f1a856f9cf666a' \
|
||||||
|
--header 'Content-Type: text/plain' \
|
||||||
|
--data-raw '{"data":{"status":"read"}}'
|
||||||
```
|
```
|
||||||
* DELETE a Web Message by ID
|
* DELETE a Web Message by ID
|
||||||
```bash
|
```bash
|
||||||
curl -i -H "User-UUID: 793f1bb4-6e25-4242-8cdc-2f662b25484f" -H "Token: GET-TOKEN-AFTER-LOGIN" -X DELETE {{base_url}}/webmessages/{id}
|
curl --location --request DELETE '{{base_url}}/webmessages/{id}' \
|
||||||
|
--header 'User-UUID: dcdb67d1-6116-4987-916f-6fc6cf2bc0e4' \
|
||||||
|
--header 'Token: 24bb236244f26784fb1397344d926b4871e87a90096eae926a0e448396dbd3ff4a2f70f727089f025238cb47bdbccdc877ef4a50fad8f05a4e5100c5d3eb0d3c'
|
||||||
```
|
```
|
||||||
|
|
||||||
### Wechat Message
|
### Wechat Message
|
||||||
|
|
|
@ -367,17 +367,21 @@ class WebMessageItem:
|
||||||
if 'status' not in new_values['data'].keys() or \
|
if 'status' not in new_values['data'].keys() or \
|
||||||
not isinstance(new_values['data']['status'], str) or \
|
not isinstance(new_values['data']['status'], str) or \
|
||||||
len(str.strip(new_values['data']['status'])) == 0 or \
|
len(str.strip(new_values['data']['status'])) == 0 or \
|
||||||
str.strip(new_values['data']['status']) not in ('new', 'acknowledged', 'timeout'):
|
str.strip(new_values['data']['status']) not in ('new', 'acknowledged', 'read'):
|
||||||
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
||||||
description='API.INVALID_STATUS')
|
description='API.INVALID_STATUS')
|
||||||
status = str.strip(new_values['data']['status'])
|
status = str.strip(new_values['data']['status'])
|
||||||
|
|
||||||
if 'reply' not in new_values['data'].keys() or \
|
# reply is required for 'acknowledged' status
|
||||||
not isinstance(new_values['data']['reply'], str) or \
|
if status == 'acknowledged' and \
|
||||||
len(str.strip(new_values['data']['reply'])) == 0:
|
('reply' not in new_values['data'].keys() or
|
||||||
|
not isinstance(new_values['data']['reply'], str) or
|
||||||
|
len(str.strip(new_values['data']['reply'])) == 0):
|
||||||
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
|
||||||
description='API.INVALID_REPLY')
|
description='API.INVALID_REPLY')
|
||||||
reply = str.strip(new_values['data']['reply'])
|
reply = str.strip(new_values['data']['reply'])
|
||||||
|
else:
|
||||||
|
reply = None
|
||||||
|
|
||||||
# Verify User Session
|
# Verify User Session
|
||||||
token = req.headers.get('TOKEN')
|
token = req.headers.get('TOKEN')
|
||||||
|
|
|
@ -128,7 +128,7 @@ const Notification = ({ setRedirect, setRedirectUrl, t }) => {
|
||||||
|
|
||||||
const subjectFormatter = (dataField, { url }) => (
|
const subjectFormatter = (dataField, { url }) => (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<a href={`${url}`}>{dataField}</a>
|
<span>{dataField}</span>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -143,16 +143,16 @@ const Notification = ({ setRedirect, setRedirectUrl, t }) => {
|
||||||
let icon = '';
|
let icon = '';
|
||||||
let text = '';
|
let text = '';
|
||||||
switch (status) {
|
switch (status) {
|
||||||
|
case 'acknowledged':
|
||||||
|
color = 'success';
|
||||||
|
icon = 'envelope-open';
|
||||||
|
text = t('Notification Acknowledged');
|
||||||
|
break;
|
||||||
case 'read':
|
case 'read':
|
||||||
color = 'success';
|
color = 'success';
|
||||||
icon = 'envelope-open';
|
icon = 'envelope-open';
|
||||||
text = t('Notification Read');
|
text = t('Notification Read');
|
||||||
break;
|
break;
|
||||||
case 'unread':
|
|
||||||
color = 'primary';
|
|
||||||
icon = 'envelope';
|
|
||||||
text = t('Notification Unread');
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
color = 'primary';
|
color = 'primary';
|
||||||
icon = 'envelope';
|
icon = 'envelope';
|
||||||
|
@ -175,9 +175,9 @@ const Notification = ({ setRedirect, setRedirectUrl, t }) => {
|
||||||
</DropdownToggle>
|
</DropdownToggle>
|
||||||
<DropdownMenu right className="border py-2">
|
<DropdownMenu right className="border py-2">
|
||||||
<DropdownItem onClick={() => handleRead(id)}>{t('Notification Mark As Read')}</DropdownItem>
|
<DropdownItem onClick={() => handleRead(id)}>{t('Notification Mark As Read')}</DropdownItem>
|
||||||
<DropdownItem onClick={() => console.log('Archive: ', id)}>{t('Notification Archive')}</DropdownItem>
|
<DropdownItem onClick={() => handleAcknowledged(id)}>{t('Notification Mark As Acknowledged')}</DropdownItem>
|
||||||
<DropdownItem divider />
|
<DropdownItem divider />
|
||||||
<DropdownItem onClick={() => console.log('Delete: ', id)} className="text-danger">{t('Notification Delete')}</DropdownItem>
|
<DropdownItem onClick={() => handledelete(id)} className="text-danger">{t('Notification Delete')}</DropdownItem>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</UncontrolledDropdown>
|
</UncontrolledDropdown>
|
||||||
);
|
);
|
||||||
|
@ -260,8 +260,7 @@ const Notification = ({ setRedirect, setRedirectUrl, t }) => {
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
"data": {
|
"data": {
|
||||||
"status": 'acknowledged',
|
"status": 'read'
|
||||||
"reply": 'ok'
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
|
@ -283,6 +282,71 @@ const Notification = ({ setRedirect, setRedirectUrl, t }) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleAcknowledged = (id, ) => {
|
||||||
|
console.log('Mark As Acknowledged: ', id)
|
||||||
|
let isResponseOK = false;
|
||||||
|
fetch(APIBaseURL + '/webmessages/' + id, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
"Content-type": "application/json",
|
||||||
|
"User-UUID": getCookieValue('user_uuid'),
|
||||||
|
"Token": getCookieValue('token')
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
"data": {
|
||||||
|
"status": 'acknowledged',
|
||||||
|
"reply": 'OK'
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
}).then(response => {
|
||||||
|
if (response.ok) {
|
||||||
|
isResponseOK = true;
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
}).then(json => {
|
||||||
|
console.log(isResponseOK);
|
||||||
|
if (isResponseOK) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
toast.error(json.description)
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handledelete = (id, ) => {
|
||||||
|
console.log('Delete: ', id)
|
||||||
|
let isResponseOK = false;
|
||||||
|
fetch(APIBaseURL + '/webmessages/' + id, {
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: {
|
||||||
|
"Content-type": "application/json",
|
||||||
|
"User-UUID": getCookieValue('user_uuid'),
|
||||||
|
"Token": getCookieValue('token')
|
||||||
|
},
|
||||||
|
body: null,
|
||||||
|
}).then(response => {
|
||||||
|
if (response.ok) {
|
||||||
|
isResponseOK = true;
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
}).then(json => {
|
||||||
|
console.log(isResponseOK);
|
||||||
|
if (isResponseOK) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
toast.error(json.description)
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
|
@ -294,7 +358,7 @@ const Notification = ({ setRedirect, setRedirectUrl, t }) => {
|
||||||
<CustomInput type="select" id="bulk-select">
|
<CustomInput type="select" id="bulk-select">
|
||||||
<option>{t('Bulk actions')}</option>
|
<option>{t('Bulk actions')}</option>
|
||||||
<option value="MarkAsRead">{t('Notification Mark As Read')}</option>
|
<option value="MarkAsRead">{t('Notification Mark As Read')}</option>
|
||||||
<option value="Archive">{t('Notification Archive')}</option>
|
<option value="MarkAsAcknowledged">{t('Notification Mark As Acknowledged')}</option>
|
||||||
<option value="Delete">{t('Notification Delete')}</option>
|
<option value="Delete">{t('Notification Delete')}</option>
|
||||||
</CustomInput>
|
</CustomInput>
|
||||||
<Button color="falcon-default" size="sm" className="ml-2">
|
<Button color="falcon-default" size="sm" className="ml-2">
|
||||||
|
|
|
@ -95,8 +95,7 @@ const NotificationDropdown = ({ t }) => {
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
"data": {
|
"data": {
|
||||||
"status": 'acknowledged',
|
"status": 'read'
|
||||||
"reply": 'ok'
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
|
|
|
@ -315,8 +315,10 @@ const resources = {
|
||||||
'Notification Message': 'Message',
|
'Notification Message': 'Message',
|
||||||
'Notification Status': 'Status',
|
'Notification Status': 'Status',
|
||||||
'Notification Mark As Read': 'Mark As Read',
|
'Notification Mark As Read': 'Mark As Read',
|
||||||
|
'Notification Mark As Acknowledged': 'Acknowledge',
|
||||||
'Notification Unread': 'Unread',
|
'Notification Unread': 'Unread',
|
||||||
'Notification Read': 'Read',
|
'Notification Read': 'Read',
|
||||||
|
'Notification Acknowledged': 'Acknowledged',
|
||||||
'Notification Archive': 'Archive',
|
'Notification Archive': 'Archive',
|
||||||
'Notification Delete': 'Delete',
|
'Notification Delete': 'Delete',
|
||||||
'Notification Apply': 'Apply',
|
'Notification Apply': 'Apply',
|
||||||
|
@ -1101,8 +1103,10 @@ const resources = {
|
||||||
'Notification Message': 'Nachricht',
|
'Notification Message': 'Nachricht',
|
||||||
'Notification Status': 'Status',
|
'Notification Status': 'Status',
|
||||||
'Notification Mark As Read': 'Mark as read',
|
'Notification Mark As Read': 'Mark as read',
|
||||||
|
'Notification Mark As Acknowledged': 'Bestätigen',
|
||||||
'Notification Unread': 'Ungelesene',
|
'Notification Unread': 'Ungelesene',
|
||||||
'Notification Read': 'Lesen',
|
'Notification Read': 'Lesen',
|
||||||
|
'Notification Acknowledged': 'Anerkannt',
|
||||||
'Notification Archive': 'Archiv',
|
'Notification Archive': 'Archiv',
|
||||||
'Notification Delete': 'Löschen',
|
'Notification Delete': 'Löschen',
|
||||||
'Notification Apply': 'Anwenden',
|
'Notification Apply': 'Anwenden',
|
||||||
|
@ -1864,8 +1868,10 @@ const resources = {
|
||||||
'Notification Message': '内容',
|
'Notification Message': '内容',
|
||||||
'Notification Status': '状态',
|
'Notification Status': '状态',
|
||||||
'Notification Mark As Read': '标记为已读',
|
'Notification Mark As Read': '标记为已读',
|
||||||
|
'Notification Mark As Acknowledged': '确认',
|
||||||
'Notification Unread': '未读',
|
'Notification Unread': '未读',
|
||||||
'Notification Read': '已读',
|
'Notification Read': '已读',
|
||||||
|
'Notification Acknowledged': '已确认',
|
||||||
'Notification Archive': '存档',
|
'Notification Archive': '存档',
|
||||||
'Notification Delete': '删除',
|
'Notification Delete': '删除',
|
||||||
'Notification Apply': '应用',
|
'Notification Apply': '应用',
|
||||||
|
|
Loading…
Reference in New Issue