@churchapps/apphelper 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/.eslintignore +3 -3
  2. package/.eslintrc.json +22 -22
  3. package/LICENSE +21 -21
  4. package/README.md +24 -22
  5. package/dist/components/markdownEditor/editor.css +787 -787
  6. package/dist/components/markdownEditor/images/icons/arrow-clockwise.svg +3 -3
  7. package/dist/components/markdownEditor/images/icons/arrow-counterclockwise.svg +3 -3
  8. package/dist/components/markdownEditor/images/icons/chat-square-quote.svg +3 -3
  9. package/dist/components/markdownEditor/images/icons/chevron-down.svg +2 -2
  10. package/dist/components/markdownEditor/images/icons/code.svg +2 -2
  11. package/dist/components/markdownEditor/images/icons/journal-code.svg +4 -4
  12. package/dist/components/markdownEditor/images/icons/journal-text.svg +4 -4
  13. package/dist/components/markdownEditor/images/icons/justify.svg +2 -2
  14. package/dist/components/markdownEditor/images/icons/link.svg +3 -3
  15. package/dist/components/markdownEditor/images/icons/list-ol.svg +3 -3
  16. package/dist/components/markdownEditor/images/icons/list-ul.svg +2 -2
  17. package/dist/components/markdownEditor/images/icons/pencil-fill.svg +2 -2
  18. package/dist/components/markdownEditor/images/icons/text-center.svg +2 -2
  19. package/dist/components/markdownEditor/images/icons/text-left.svg +2 -2
  20. package/dist/components/markdownEditor/images/icons/text-paragraph.svg +2 -2
  21. package/dist/components/markdownEditor/images/icons/text-right.svg +2 -2
  22. package/dist/components/markdownEditor/images/icons/type-bold.svg +2 -2
  23. package/dist/components/markdownEditor/images/icons/type-h1.svg +2 -2
  24. package/dist/components/markdownEditor/images/icons/type-h2.svg +2 -2
  25. package/dist/components/markdownEditor/images/icons/type-h3.svg +2 -2
  26. package/dist/components/markdownEditor/images/icons/type-h4.svg +12 -12
  27. package/dist/components/markdownEditor/images/icons/type-italic.svg +2 -2
  28. package/dist/components/markdownEditor/images/icons/type-strikethrough.svg +2 -2
  29. package/dist/components/markdownEditor/images/icons/type-underline.svg +2 -2
  30. package/dist/components/notes/Notes.d.ts +1 -0
  31. package/dist/components/notes/Notes.d.ts.map +1 -1
  32. package/dist/components/notes/Notes.js +1 -1
  33. package/dist/components/notes/Notes.js.map +1 -1
  34. package/dist/components/wrapper/NotificationMenu.d.ts.map +1 -1
  35. package/dist/components/wrapper/NotificationMenu.js +28 -11
  36. package/dist/components/wrapper/NotificationMenu.js.map +1 -1
  37. package/dist/components/wrapper/Notifications.d.ts +1 -0
  38. package/dist/components/wrapper/Notifications.d.ts.map +1 -1
  39. package/dist/components/wrapper/Notifications.js +2 -0
  40. package/dist/components/wrapper/Notifications.js.map +1 -1
  41. package/dist/components/wrapper/PrivateMessageDetails.d.ts +1 -0
  42. package/dist/components/wrapper/PrivateMessageDetails.d.ts.map +1 -1
  43. package/dist/components/wrapper/PrivateMessageDetails.js +1 -1
  44. package/dist/components/wrapper/PrivateMessageDetails.js.map +1 -1
  45. package/dist/components/wrapper/PrivateMessages.d.ts +2 -0
  46. package/dist/components/wrapper/PrivateMessages.d.ts.map +1 -1
  47. package/dist/components/wrapper/PrivateMessages.js +6 -3
  48. package/dist/components/wrapper/PrivateMessages.js.map +1 -1
  49. package/dist/components/wrapper/SiteWrapper.d.ts.map +1 -1
  50. package/dist/components/wrapper/SiteWrapper.js +1 -0
  51. package/dist/components/wrapper/SiteWrapper.js.map +1 -1
  52. package/dist/helpers/DateHelper.d.ts.map +1 -1
  53. package/dist/helpers/DateHelper.js +2 -0
  54. package/dist/helpers/DateHelper.js.map +1 -1
  55. package/dist/helpers/SocketHelper.d.ts.map +1 -1
  56. package/dist/helpers/SocketHelper.js +4 -2
  57. package/dist/helpers/SocketHelper.js.map +1 -1
  58. package/dist/interfaces/Messaging.d.ts +10 -1
  59. package/dist/interfaces/Messaging.d.ts.map +1 -1
  60. package/package.json +86 -85
  61. package/src/components/CreatePerson.tsx +80 -80
  62. package/src/components/DisplayBox.tsx +68 -68
  63. package/src/components/ErrorMessages.tsx +26 -26
  64. package/src/components/ExportLink.tsx +67 -67
  65. package/src/components/FloatingSupport.tsx +16 -16
  66. package/src/components/FormSubmissionEdit.tsx +120 -120
  67. package/src/components/HelpIcon.tsx +10 -10
  68. package/src/components/ImageEditor.tsx +126 -126
  69. package/src/components/InputBox.tsx +73 -73
  70. package/src/components/Loading.tsx +29 -29
  71. package/src/components/PersonAdd.tsx +75 -75
  72. package/src/components/QuestionEdit.tsx +63 -63
  73. package/src/components/SmallButton.tsx +39 -39
  74. package/src/components/SupportModal.tsx +26 -26
  75. package/src/components/TabPanel.tsx +34 -34
  76. package/src/components/gallery/GalleryModal.tsx +102 -102
  77. package/src/components/gallery/StockPhotos.tsx +74 -74
  78. package/src/components/gallery/index.ts +1 -1
  79. package/src/components/iconPicker/IconNamesList.ts +2240 -2240
  80. package/src/components/iconPicker/IconPicker.tsx +153 -153
  81. package/src/components/index.tsx +24 -24
  82. package/src/components/markdownEditor/Editor.tsx +132 -132
  83. package/src/components/markdownEditor/MarkdownEditor.tsx +16 -16
  84. package/src/components/markdownEditor/MarkdownModal.tsx +46 -46
  85. package/src/components/markdownEditor/MarkdownPreview.tsx +14 -14
  86. package/src/components/markdownEditor/editor.css +787 -787
  87. package/src/components/markdownEditor/images/icons/arrow-clockwise.svg +3 -3
  88. package/src/components/markdownEditor/images/icons/arrow-counterclockwise.svg +3 -3
  89. package/src/components/markdownEditor/images/icons/chat-square-quote.svg +3 -3
  90. package/src/components/markdownEditor/images/icons/chevron-down.svg +2 -2
  91. package/src/components/markdownEditor/images/icons/code.svg +2 -2
  92. package/src/components/markdownEditor/images/icons/journal-code.svg +4 -4
  93. package/src/components/markdownEditor/images/icons/journal-text.svg +4 -4
  94. package/src/components/markdownEditor/images/icons/justify.svg +2 -2
  95. package/src/components/markdownEditor/images/icons/link.svg +3 -3
  96. package/src/components/markdownEditor/images/icons/list-ol.svg +3 -3
  97. package/src/components/markdownEditor/images/icons/list-ul.svg +2 -2
  98. package/src/components/markdownEditor/images/icons/pencil-fill.svg +2 -2
  99. package/src/components/markdownEditor/images/icons/text-center.svg +2 -2
  100. package/src/components/markdownEditor/images/icons/text-left.svg +2 -2
  101. package/src/components/markdownEditor/images/icons/text-paragraph.svg +2 -2
  102. package/src/components/markdownEditor/images/icons/text-right.svg +2 -2
  103. package/src/components/markdownEditor/images/icons/type-bold.svg +2 -2
  104. package/src/components/markdownEditor/images/icons/type-h1.svg +2 -2
  105. package/src/components/markdownEditor/images/icons/type-h2.svg +2 -2
  106. package/src/components/markdownEditor/images/icons/type-h3.svg +2 -2
  107. package/src/components/markdownEditor/images/icons/type-h4.svg +12 -12
  108. package/src/components/markdownEditor/images/icons/type-italic.svg +2 -2
  109. package/src/components/markdownEditor/images/icons/type-strikethrough.svg +2 -2
  110. package/src/components/markdownEditor/images/icons/type-underline.svg +2 -2
  111. package/src/components/markdownEditor/index.ts +2 -2
  112. package/src/components/markdownEditor/plugins/AutoLinkPlugin.tsx +35 -35
  113. package/src/components/markdownEditor/plugins/ControlledEditorPlugin.tsx +24 -24
  114. package/src/components/markdownEditor/plugins/ListMaxIndentLevelPlugin.tsx +68 -68
  115. package/src/components/markdownEditor/plugins/MarkdownTransformers.ts +106 -106
  116. package/src/components/markdownEditor/plugins/ReadOnlyPlugin.tsx +15 -15
  117. package/src/components/markdownEditor/plugins/ToolbarPlugin.tsx +401 -401
  118. package/src/components/markdownEditor/plugins/customLink/CustomLinkNode.tsx +224 -224
  119. package/src/components/markdownEditor/plugins/customLink/CustomLinkNodePlugin.tsx +32 -32
  120. package/src/components/markdownEditor/plugins/customLink/CustomLinkNodeTransformer.tsx +102 -102
  121. package/src/components/markdownEditor/plugins/customLink/FloatingLinkEditor.tsx +243 -243
  122. package/src/components/markdownEditor/plugins/customLink/FloatingLinkEditor.types.ts +11 -11
  123. package/src/components/markdownEditor/plugins/emoji/EmojiNode.tsx +95 -95
  124. package/src/components/markdownEditor/plugins/emoji/EmojiNodeTransform.ts +41 -41
  125. package/src/components/markdownEditor/plugins/emoji/EmojiPickerPlugin.tsx +152 -152
  126. package/src/components/markdownEditor/plugins/emoji/EmojisPlugin.tsx +65 -65
  127. package/src/components/markdownEditor/plugins/index.ts +6 -6
  128. package/src/components/markdownEditor/theme.ts +65 -65
  129. package/src/components/notes/AddNote.tsx +90 -90
  130. package/src/components/notes/Conversation.tsx +82 -82
  131. package/src/components/notes/Conversations.tsx +58 -58
  132. package/src/components/notes/NewConversation.tsx +78 -78
  133. package/src/components/notes/Note.tsx +44 -44
  134. package/src/components/notes/Notes.tsx +69 -68
  135. package/src/components/notes/index.ts +5 -5
  136. package/src/components/reporting/ChartReport.tsx +98 -98
  137. package/src/components/reporting/ReportFilter.tsx +54 -54
  138. package/src/components/reporting/ReportFilterField.tsx +160 -160
  139. package/src/components/reporting/ReportOutput.tsx +79 -79
  140. package/src/components/reporting/ReportWithFilter.tsx +70 -70
  141. package/src/components/reporting/TableReport.tsx +57 -57
  142. package/src/components/reporting/TreeReport.tsx +111 -111
  143. package/src/components/reporting/index.ts +4 -4
  144. package/src/components/wrapper/AppList.tsx +20 -20
  145. package/src/components/wrapper/ChurchList.tsx +22 -22
  146. package/src/components/wrapper/Drawers.tsx +60 -60
  147. package/src/components/wrapper/NavItem.tsx +41 -41
  148. package/src/components/wrapper/NewPrivateMessage.tsx +103 -103
  149. package/src/components/wrapper/NotificationMenu.tsx +96 -85
  150. package/src/components/wrapper/Notifications.tsx +53 -50
  151. package/src/components/wrapper/PrivateMessageDetails.tsx +24 -23
  152. package/src/components/wrapper/PrivateMessages.tsx +92 -87
  153. package/src/components/wrapper/SiteWrapper.tsx +97 -96
  154. package/src/components/wrapper/TabPanel.tsx +30 -30
  155. package/src/components/wrapper/UserMenu.tsx +106 -106
  156. package/src/components/wrapper/index.tsx +5 -5
  157. package/src/donationComponents/DonationPage.tsx +136 -136
  158. package/src/donationComponents/components/BankForm.tsx +159 -159
  159. package/src/donationComponents/components/CardForm.tsx +104 -104
  160. package/src/donationComponents/components/DonationForm.tsx +235 -235
  161. package/src/donationComponents/components/FundDonation.tsx +49 -49
  162. package/src/donationComponents/components/FundDonations.tsx +39 -39
  163. package/src/donationComponents/components/NonAuthDonation.tsx +31 -31
  164. package/src/donationComponents/components/NonAuthDonationInner.tsx +259 -259
  165. package/src/donationComponents/components/PaymentMethods.tsx +135 -135
  166. package/src/donationComponents/components/RecurringDonations.tsx +121 -121
  167. package/src/donationComponents/components/RecurringDonationsEdit.tsx +93 -93
  168. package/src/donationComponents/components/index.tsx +9 -9
  169. package/src/donationComponents/index.ts +3 -3
  170. package/src/donationComponents/modals/DonationPreviewModal.tsx +66 -66
  171. package/src/helpers/AnalyticsHelper.ts +33 -33
  172. package/src/helpers/ApiHelper.ts +125 -125
  173. package/src/helpers/AppearanceHelper.ts +69 -69
  174. package/src/helpers/ArrayHelper.ts +81 -81
  175. package/src/helpers/CommonEnvironmentHelper.ts +80 -80
  176. package/src/helpers/CurrencyHelper.ts +10 -10
  177. package/src/helpers/DateHelper.ts +109 -108
  178. package/src/helpers/DonationHelper.ts +26 -26
  179. package/src/helpers/ErrorHelper.ts +36 -36
  180. package/src/helpers/EventHelper.ts +52 -52
  181. package/src/helpers/FileHelper.ts +31 -31
  182. package/src/helpers/PersonHelper.ts +60 -60
  183. package/src/helpers/SocketHelper.ts +78 -76
  184. package/src/helpers/Themes.ts +14 -14
  185. package/src/helpers/UniqueIdHelper.ts +36 -36
  186. package/src/helpers/UserHelper.ts +59 -59
  187. package/src/helpers/createEmotionCache.ts +17 -17
  188. package/src/helpers/index.ts +18 -18
  189. package/src/hooks/index.ts +1 -1
  190. package/src/hooks/useMountedState.ts +16 -16
  191. package/src/index.ts +6 -6
  192. package/src/interfaces/Access.ts +24 -24
  193. package/src/interfaces/Attendance.ts +8 -8
  194. package/src/interfaces/Content.ts +10 -10
  195. package/src/interfaces/Doing.ts +24 -24
  196. package/src/interfaces/Donation.ts +45 -45
  197. package/src/interfaces/Error.ts +17 -17
  198. package/src/interfaces/Membership.ts +51 -51
  199. package/src/interfaces/Messaging.ts +11 -21
  200. package/src/interfaces/Permissions.ts +68 -68
  201. package/src/interfaces/Reporting.ts +7 -7
  202. package/src/interfaces/UserContextInterface.ts +13 -13
  203. package/src/interfaces/index.ts +13 -13
  204. package/src/pageComponents/LoginPage.tsx +244 -244
  205. package/src/pageComponents/LogoutPage.tsx +28 -28
  206. package/src/pageComponents/components/Forgot.tsx +79 -79
  207. package/src/pageComponents/components/Login.tsx +54 -54
  208. package/src/pageComponents/components/LoginSetPassword.tsx +63 -63
  209. package/src/pageComponents/components/Register.tsx +107 -107
  210. package/src/pageComponents/components/SelectChurchModal.tsx +41 -41
  211. package/src/pageComponents/components/SelectChurchRegister.tsx +88 -88
  212. package/src/pageComponents/components/SelectChurchSearch.tsx +69 -69
  213. package/src/pageComponents/components/SelectableChurch.tsx +38 -38
  214. package/src/pageComponents/index.ts +3 -3
  215. package/tsconfig.json +34 -34
  216. package/tslint.json +14 -14
@@ -1,58 +1,58 @@
1
- import React from "react";
2
- import { Loading } from "../";
3
- import { ApiHelper, ArrayHelper } from "../../helpers";
4
- import { ConversationInterface, UserContextInterface } from "../../interfaces";
5
- import { Conversation } from "./Conversation";
6
- import { NewConversation } from "./NewConversation";
7
-
8
- interface Props {
9
- contentType: string;
10
- contentId: string;
11
- groupId: string;
12
- context: UserContextInterface;
13
- }
14
-
15
- export function Conversations(props: Props) {
16
-
17
- const [conversations, setConversations] = React.useState<ConversationInterface[]>(null)
18
- //const [editMessageId, setEditMessageId] = React.useState(null)
19
-
20
- const loadConversations = async () => {
21
- const conversations: ConversationInterface[] = (props.contentId) ? await ApiHelper.get("/conversations/" + props.contentType + "/" + props.contentId, "MessagingApi") : [];
22
- if (conversations.length > 0) {
23
- const peopleIds: string[] = [];
24
- conversations.forEach(c => {
25
- c.messages.forEach(m => {
26
- if (peopleIds.indexOf(m.personId) === -1) peopleIds.push(m.personId);
27
- });
28
- })
29
- const people = await ApiHelper.get("/people/ids?ids=" + peopleIds.join(","), "MembershipApi");
30
- conversations.forEach(c => {
31
- c.messages.forEach(m => {
32
- m.person = ArrayHelper.getOne(people, "id", m.personId);
33
- });
34
- })
35
- }
36
- setConversations(conversations);
37
- //setEditMessageId(null);
38
- };
39
-
40
- const getConversations = () => {
41
- if (conversations.length === 0) return <></>
42
- else {
43
- let noteArray: React.ReactNode[] = [];
44
- for (let i = 0; i < conversations.length; i++) noteArray.push(<Conversation context={props.context} conversation={conversations[i]} key={conversations[i].id} />);
45
- return noteArray;
46
- }
47
- }
48
-
49
- React.useEffect(() => { loadConversations() }, [props.contentId]); //eslint-disable-line
50
-
51
- if (!conversations) return <Loading />
52
- else return (
53
- <>
54
- <NewConversation context={props.context} contentType={props.contentType} contentId={props.contentId} onUpdate={loadConversations} groupId={props.groupId} visibility="public" />
55
- {getConversations()}
56
- </>
57
- );
58
- };
1
+ import React from "react";
2
+ import { Loading } from "../";
3
+ import { ApiHelper, ArrayHelper } from "../../helpers";
4
+ import { ConversationInterface, UserContextInterface } from "../../interfaces";
5
+ import { Conversation } from "./Conversation";
6
+ import { NewConversation } from "./NewConversation";
7
+
8
+ interface Props {
9
+ contentType: string;
10
+ contentId: string;
11
+ groupId: string;
12
+ context: UserContextInterface;
13
+ }
14
+
15
+ export function Conversations(props: Props) {
16
+
17
+ const [conversations, setConversations] = React.useState<ConversationInterface[]>(null)
18
+ //const [editMessageId, setEditMessageId] = React.useState(null)
19
+
20
+ const loadConversations = async () => {
21
+ const conversations: ConversationInterface[] = (props.contentId) ? await ApiHelper.get("/conversations/" + props.contentType + "/" + props.contentId, "MessagingApi") : [];
22
+ if (conversations.length > 0) {
23
+ const peopleIds: string[] = [];
24
+ conversations.forEach(c => {
25
+ c.messages.forEach(m => {
26
+ if (peopleIds.indexOf(m.personId) === -1) peopleIds.push(m.personId);
27
+ });
28
+ })
29
+ const people = await ApiHelper.get("/people/ids?ids=" + peopleIds.join(","), "MembershipApi");
30
+ conversations.forEach(c => {
31
+ c.messages.forEach(m => {
32
+ m.person = ArrayHelper.getOne(people, "id", m.personId);
33
+ });
34
+ })
35
+ }
36
+ setConversations(conversations);
37
+ //setEditMessageId(null);
38
+ };
39
+
40
+ const getConversations = () => {
41
+ if (conversations.length === 0) return <></>
42
+ else {
43
+ let noteArray: React.ReactNode[] = [];
44
+ for (let i = 0; i < conversations.length; i++) noteArray.push(<Conversation context={props.context} conversation={conversations[i]} key={conversations[i].id} />);
45
+ return noteArray;
46
+ }
47
+ }
48
+
49
+ React.useEffect(() => { loadConversations() }, [props.contentId]); //eslint-disable-line
50
+
51
+ if (!conversations) return <Loading />
52
+ else return (
53
+ <>
54
+ <NewConversation context={props.context} contentType={props.contentType} contentId={props.contentId} onUpdate={loadConversations} groupId={props.groupId} visibility="public" />
55
+ {getConversations()}
56
+ </>
57
+ );
58
+ };
@@ -1,78 +1,78 @@
1
- import { Icon, Paper, Stack, TextField } from "@mui/material";
2
- import React from "react";
3
- import { ApiHelper, PersonHelper } from "../../helpers";
4
- import { ConversationInterface, MessageInterface, UserContextInterface } from "../../interfaces";
5
- import { ErrorMessages } from "../ErrorMessages";
6
- import { SmallButton } from "../SmallButton";
7
-
8
- interface Props {
9
- contentType: string;
10
- contentId: string;
11
- groupId: string;
12
- visibility: "public" | "hidden";
13
- context: UserContextInterface;
14
- onUpdate: () => void;
15
- }
16
-
17
- export function NewConversation({ context, ...props }: Props) {
18
- const [message, setMessage] = React.useState<MessageInterface>({})
19
- const [errors, setErrors] = React.useState<string[]>([]);
20
- const [isSubmitting, setIsSubmitting] = React.useState(false);
21
-
22
- const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) => {
23
- setErrors([]);
24
- const m = { ...message } as MessageInterface;
25
- m.content = e.target.value;
26
- setMessage(m);
27
- }
28
-
29
- const validate = () => {
30
- const result = [];
31
- if (!message.content.trim()) result.push("Please enter a note.");
32
- setErrors(result);
33
- return result.length === 0;
34
- }
35
-
36
- async function handleSave() {
37
- if (validate()) {
38
- setIsSubmitting(true);
39
-
40
- const conv: ConversationInterface = { contentType: props.contentType, contentId: props.contentId, title: props.contentType + " " + props.contentId + " Conversation", groupId: props.groupId, visibility: props.visibility, allowAnonymousPosts: false }
41
- const result = await ApiHelper.post("/conversations", [conv], "MessagingApi");
42
- const cId = result[0].id;
43
-
44
- const m = { ...message };
45
- m.conversationId = cId;
46
- ApiHelper.post("/messages", [m], "MessagingApi")
47
- .then(() => {
48
- props.onUpdate();
49
- const m = { ...message } as MessageInterface;
50
- m.content = "";
51
- setMessage(m);
52
- })
53
- .finally(() => { setIsSubmitting(false); });
54
-
55
- }
56
- };
57
-
58
- const image = PersonHelper.getPhotoUrl(context?.person)
59
-
60
- return (
61
- <Paper sx={{ padding: 1, marginBottom: 2 }}>
62
- <ErrorMessages errors={errors} />
63
-
64
- <Stack direction="row" spacing={1.5} style={{ marginTop: 15 }} justifyContent="end">
65
-
66
- {image ? <img src={image} alt="user" style={{ width: 60, height: 45, borderRadius: 5, marginLeft: 8 }} /> : <Icon>person</Icon>}
67
- <Stack direction="column" spacing={2} style={{ width: "100%" }} justifyContent="end">
68
- <div><b>{context?.person?.name?.display}</b></div>
69
- <TextField fullWidth name="noteText" aria-label={"Start a conversation"} placeholder="Start a conversation" multiline style={{ marginTop: 0, border: "none" }} variant="standard" onChange={handleChange} value={message.content} />
70
- </Stack>
71
- <Stack direction="column" spacing={1} justifyContent="end">
72
- <SmallButton icon="send" onClick={handleSave} disabled={isSubmitting} />
73
- </Stack>
74
- </Stack>
75
- </Paper>
76
- );
77
-
78
- };
1
+ import { Icon, Paper, Stack, TextField } from "@mui/material";
2
+ import React from "react";
3
+ import { ApiHelper, PersonHelper } from "../../helpers";
4
+ import { ConversationInterface, MessageInterface, UserContextInterface } from "../../interfaces";
5
+ import { ErrorMessages } from "../ErrorMessages";
6
+ import { SmallButton } from "../SmallButton";
7
+
8
+ interface Props {
9
+ contentType: string;
10
+ contentId: string;
11
+ groupId: string;
12
+ visibility: "public" | "hidden";
13
+ context: UserContextInterface;
14
+ onUpdate: () => void;
15
+ }
16
+
17
+ export function NewConversation({ context, ...props }: Props) {
18
+ const [message, setMessage] = React.useState<MessageInterface>({})
19
+ const [errors, setErrors] = React.useState<string[]>([]);
20
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
21
+
22
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) => {
23
+ setErrors([]);
24
+ const m = { ...message } as MessageInterface;
25
+ m.content = e.target.value;
26
+ setMessage(m);
27
+ }
28
+
29
+ const validate = () => {
30
+ const result = [];
31
+ if (!message.content.trim()) result.push("Please enter a note.");
32
+ setErrors(result);
33
+ return result.length === 0;
34
+ }
35
+
36
+ async function handleSave() {
37
+ if (validate()) {
38
+ setIsSubmitting(true);
39
+
40
+ const conv: ConversationInterface = { contentType: props.contentType, contentId: props.contentId, title: props.contentType + " " + props.contentId + " Conversation", groupId: props.groupId, visibility: props.visibility, allowAnonymousPosts: false }
41
+ const result = await ApiHelper.post("/conversations", [conv], "MessagingApi");
42
+ const cId = result[0].id;
43
+
44
+ const m = { ...message };
45
+ m.conversationId = cId;
46
+ ApiHelper.post("/messages", [m], "MessagingApi")
47
+ .then(() => {
48
+ props.onUpdate();
49
+ const m = { ...message } as MessageInterface;
50
+ m.content = "";
51
+ setMessage(m);
52
+ })
53
+ .finally(() => { setIsSubmitting(false); });
54
+
55
+ }
56
+ };
57
+
58
+ const image = PersonHelper.getPhotoUrl(context?.person)
59
+
60
+ return (
61
+ <Paper sx={{ padding: 1, marginBottom: 2 }}>
62
+ <ErrorMessages errors={errors} />
63
+
64
+ <Stack direction="row" spacing={1.5} style={{ marginTop: 15 }} justifyContent="end">
65
+
66
+ {image ? <img src={image} alt="user" style={{ width: 60, height: 45, borderRadius: 5, marginLeft: 8 }} /> : <Icon>person</Icon>}
67
+ <Stack direction="column" spacing={2} style={{ width: "100%" }} justifyContent="end">
68
+ <div><b>{context?.person?.name?.display}</b></div>
69
+ <TextField fullWidth name="noteText" aria-label={"Start a conversation"} placeholder="Start a conversation" multiline style={{ marginTop: 0, border: "none" }} variant="standard" onChange={handleChange} value={message.content} />
70
+ </Stack>
71
+ <Stack direction="column" spacing={1} justifyContent="end">
72
+ <SmallButton icon="send" onClick={handleSave} disabled={isSubmitting} />
73
+ </Stack>
74
+ </Stack>
75
+ </Paper>
76
+ );
77
+
78
+ };
@@ -1,44 +1,44 @@
1
- import { Icon, IconButton, Stack, Box } from "@mui/material";
2
- import React, { useState, useEffect } from "react";
3
- import { DateHelper, PersonHelper } from "../../helpers"
4
- import { MessageInterface } from "../../interfaces"
5
-
6
- interface Props {
7
- message: MessageInterface;
8
- showEditNote: (noteId?: string) => void
9
- }
10
-
11
- export const Note: React.FC<Props> = (props) => {
12
- const [message, setMessage] = useState<MessageInterface>(null);
13
-
14
- useEffect(() => setMessage(props.message), [props.message]);
15
-
16
- if (message === null) return null;
17
- const photoUrl = PersonHelper.getPhotoUrl(message.person);
18
- let datePosted = new Date(message.timeUpdated || message.timeSent);
19
- const displayDuration = DateHelper.getDisplayDuration(datePosted);
20
-
21
- const isEdited = message.timeUpdated && message.timeUpdated !== message.timeSent && <>(edited)</>;
22
- const contents = message.content?.split("\n");
23
- return (
24
- <div className="note">
25
- <div className="postedBy">
26
- <img src={photoUrl} alt="avatar" />
27
- </div>
28
- <Box sx={{ width: "100%" }} className="note-contents">
29
- <Stack direction="row" justifyContent="space-between">
30
- <div>
31
- <b>{message.person?.name?.display}</b> · <span className="text-grey">{displayDuration}{isEdited}</span>
32
- {contents.map((c, i) => c ? <p key={i}>{c}</p> : <br />)}
33
- </div>
34
- <div>
35
- <IconButton aria-label="editNote" onClick={() => props.showEditNote(message.id)}>
36
- <Icon style={{ color: "#03a9f4" }}>edit</Icon>
37
- </IconButton>
38
- </div>
39
- </Stack>
40
-
41
- </Box>
42
- </div>
43
- );
44
- };
1
+ import { Icon, IconButton, Stack, Box } from "@mui/material";
2
+ import React, { useState, useEffect } from "react";
3
+ import { DateHelper, PersonHelper } from "../../helpers"
4
+ import { MessageInterface } from "../../interfaces"
5
+
6
+ interface Props {
7
+ message: MessageInterface;
8
+ showEditNote: (noteId?: string) => void
9
+ }
10
+
11
+ export const Note: React.FC<Props> = (props) => {
12
+ const [message, setMessage] = useState<MessageInterface>(null);
13
+
14
+ useEffect(() => setMessage(props.message), [props.message]);
15
+
16
+ if (message === null) return null;
17
+ const photoUrl = PersonHelper.getPhotoUrl(message.person);
18
+ let datePosted = new Date(message.timeUpdated || message.timeSent);
19
+ const displayDuration = DateHelper.getDisplayDuration(datePosted);
20
+
21
+ const isEdited = message.timeUpdated && message.timeUpdated !== message.timeSent && <>(edited)</>;
22
+ const contents = message.content?.split("\n");
23
+ return (
24
+ <div className="note">
25
+ <div className="postedBy">
26
+ <img src={photoUrl} alt="avatar" />
27
+ </div>
28
+ <Box sx={{ width: "100%" }} className="note-contents">
29
+ <Stack direction="row" justifyContent="space-between">
30
+ <div>
31
+ <b>{message.person?.name?.display}</b> · <span className="text-grey">{displayDuration}{isEdited}</span>
32
+ {contents.map((c, i) => c ? <p key={i}>{c}</p> : <br />)}
33
+ </div>
34
+ <div>
35
+ <IconButton aria-label="editNote" onClick={() => props.showEditNote(message.id)}>
36
+ <Icon style={{ color: "#03a9f4" }}>edit</Icon>
37
+ </IconButton>
38
+ </div>
39
+ </Stack>
40
+
41
+ </Box>
42
+ </div>
43
+ );
44
+ };
@@ -1,68 +1,69 @@
1
- import React from "react";
2
- import { Note } from "./Note";
3
- import { AddNote } from "./AddNote";
4
- import { DisplayBox, Loading } from "../";
5
- import { ApiHelper, ArrayHelper } from "../../helpers";
6
- import { MessageInterface, UserContextInterface } from "../../interfaces";
7
-
8
- interface Props {
9
- //showEditNote: (messageId?: string) => void;
10
- conversationId: string;
11
- createConversation?: () => Promise<string>;
12
- noDisplayBox?: boolean;
13
- context: UserContextInterface;
14
- maxHeight?: any;
15
- }
16
-
17
- export function Notes(props: Props) {
18
-
19
- const [messages, setMessages] = React.useState<MessageInterface[]>(null)
20
- const [editMessageId, setEditMessageId] = React.useState(null)
21
-
22
- const loadNotes = async () => {
23
- const messages: MessageInterface[] = (props.conversationId) ? await ApiHelper.get("/messages/conversation/" + props.conversationId, "MessagingApi") : [];
24
- if (messages.length > 0) {
25
- const peopleIds = ArrayHelper.getIds(messages, "personId");
26
- const people = await ApiHelper.get("/people/ids?ids=" + peopleIds.join(","), "MembershipApi");
27
- messages.forEach(n => {
28
- n.person = ArrayHelper.getOne(people, "id", n.personId);
29
- })
30
- }
31
- setMessages(messages);
32
- setEditMessageId(null);
33
- };
34
-
35
- const getNotes = () => {
36
- if (!messages) return <Loading />
37
- if (messages.length === 0) return <></>
38
- else {
39
- let noteArray: React.ReactNode[] = [];
40
- for (let i = 0; i < messages.length; i++) noteArray.push(<Note message={messages[i]} key={messages[i].id} showEditNote={setEditMessageId} />);
41
- return noteArray;
42
- }
43
- }
44
-
45
- const getNotesWrapper = () => {
46
- const notes = getNotes();
47
- if (props.maxHeight) return <div id="notesScroll" style={{maxHeight: props.maxHeight, overflowY: "scroll"}}>{notes}</div>
48
- else return notes;
49
- }
50
-
51
- React.useEffect(() => { loadNotes() }, [props.conversationId]); //eslint-disable-line
52
-
53
- React.useEffect(() => {
54
- if (props.maxHeight && messages?.length>0) {
55
- setTimeout(() => {
56
- const element = window?.document?.getElementById("notesScroll");
57
- if (element) element.scrollTop = element.scrollHeight;
58
- }, 100);
59
- }
60
- }, [messages, props.maxHeight]);
61
-
62
- let result = <>
63
- {getNotesWrapper()}
64
- {messages && (<AddNote context={props.context} conversationId={props.conversationId} onUpdate={loadNotes} createConversation={props.createConversation} messageId={editMessageId} />)}
65
- </>
66
- if (props.noDisplayBox) return result;
67
- else return (<DisplayBox id="notesBox" data-cy="notes-box" headerIcon="sticky_note_2" headerText="Notes">{result}</DisplayBox>);
68
- };
1
+ import React from "react";
2
+ import { Note } from "./Note";
3
+ import { AddNote } from "./AddNote";
4
+ import { DisplayBox, Loading } from "../";
5
+ import { ApiHelper, ArrayHelper } from "../../helpers";
6
+ import { MessageInterface, UserContextInterface } from "../../interfaces";
7
+
8
+ interface Props {
9
+ //showEditNote: (messageId?: string) => void;
10
+ conversationId: string;
11
+ createConversation?: () => Promise<string>;
12
+ noDisplayBox?: boolean;
13
+ context: UserContextInterface;
14
+ maxHeight?: any;
15
+ refreshKey?: number;
16
+ }
17
+
18
+ export function Notes(props: Props) {
19
+
20
+ const [messages, setMessages] = React.useState<MessageInterface[]>(null)
21
+ const [editMessageId, setEditMessageId] = React.useState(null)
22
+
23
+ const loadNotes = async () => {
24
+ const messages: MessageInterface[] = (props.conversationId) ? await ApiHelper.get("/messages/conversation/" + props.conversationId, "MessagingApi") : [];
25
+ if (messages.length > 0) {
26
+ const peopleIds = ArrayHelper.getIds(messages, "personId");
27
+ const people = await ApiHelper.get("/people/ids?ids=" + peopleIds.join(","), "MembershipApi");
28
+ messages.forEach(n => {
29
+ n.person = ArrayHelper.getOne(people, "id", n.personId);
30
+ })
31
+ }
32
+ setMessages(messages);
33
+ setEditMessageId(null);
34
+ };
35
+
36
+ const getNotes = () => {
37
+ if (!messages) return <Loading />
38
+ if (messages.length === 0) return <></>
39
+ else {
40
+ let noteArray: React.ReactNode[] = [];
41
+ for (let i = 0; i < messages.length; i++) noteArray.push(<Note message={messages[i]} key={messages[i].id} showEditNote={setEditMessageId} />);
42
+ return noteArray;
43
+ }
44
+ }
45
+
46
+ const getNotesWrapper = () => {
47
+ const notes = getNotes();
48
+ if (props.maxHeight) return <div id="notesScroll" style={{maxHeight: props.maxHeight, overflowY: "scroll"}}>{notes}</div>
49
+ else return notes;
50
+ }
51
+
52
+ React.useEffect(() => { loadNotes() }, [props.conversationId, props.refreshKey]); //eslint-disable-line
53
+
54
+ React.useEffect(() => {
55
+ if (props.maxHeight && messages?.length>0) {
56
+ setTimeout(() => {
57
+ const element = window?.document?.getElementById("notesScroll");
58
+ if (element) element.scrollTop = element.scrollHeight;
59
+ }, 100);
60
+ }
61
+ }, [messages, props.maxHeight]);
62
+
63
+ let result = <>
64
+ {getNotesWrapper()}
65
+ {messages && (<AddNote context={props.context} conversationId={props.conversationId} onUpdate={loadNotes} createConversation={props.createConversation} messageId={editMessageId} />)}
66
+ </>
67
+ if (props.noDisplayBox) return result;
68
+ else return (<DisplayBox id="notesBox" data-cy="notes-box" headerIcon="sticky_note_2" headerText="Notes">{result}</DisplayBox>);
69
+ };
@@ -1,5 +1,5 @@
1
- export { Notes } from "./Notes";
2
- export { Note } from "./Note";
3
- export { Conversation } from "./Conversation";
4
- export { Conversations } from "./Conversations";
5
- export { AddNote } from "./AddNote";
1
+ export { Notes } from "./Notes";
2
+ export { Note } from "./Note";
3
+ export { Conversation } from "./Conversation";
4
+ export { Conversations } from "./Conversations";
5
+ export { AddNote } from "./AddNote";