@steroidsjs/core 3.0.0-beta.99 → 3.0.0

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 (168) hide show
  1. package/actions/notifications.js +7 -1
  2. package/actions/router.js +16 -2
  3. package/components/HttpComponent.d.ts +7 -7
  4. package/components/JwtHttpComponent.d.ts +2 -2
  5. package/components/LocaleComponent.d.ts +6 -6
  6. package/components/MetaComponent.d.ts +90 -1
  7. package/components/MetricsComponent.js +2 -1
  8. package/components/ResourceComponent.d.ts +4 -4
  9. package/components/UiComponent.d.ts +7 -7
  10. package/components/WebSocketComponent.d.ts +11 -11
  11. package/docs-autogen-result.json +15147 -6371
  12. package/en.json +151 -92
  13. package/hooks/index.d.ts +4 -3
  14. package/hooks/index.js +7 -5
  15. package/hooks/useAbsolutePositioning.js +0 -1
  16. package/hooks/useAddressBar.js +0 -1
  17. package/hooks/useApplication.js +8 -1
  18. package/hooks/useDataProvider.d.ts +17 -2
  19. package/hooks/useDataSelect.js +21 -4
  20. package/hooks/useFetch.js +6 -1
  21. package/hooks/useFile.d.ts +1 -0
  22. package/hooks/useFile.js +2 -0
  23. package/hooks/useList.d.ts +53 -14
  24. package/hooks/useList.js +31 -70
  25. package/hooks/useTree.d.ts +104 -0
  26. package/hooks/useTree.js +169 -0
  27. package/index.d.ts +3 -3
  28. package/package.json +94 -93
  29. package/reducers/router.d.ts +2 -1
  30. package/ui/content/Accordion/Accordion.d.ts +8 -5
  31. package/ui/content/Accordion/Accordion.js +6 -1
  32. package/ui/content/Accordion/AccordionItem.d.ts +2 -2
  33. package/ui/content/Accordion/AccordionItem.js +1 -12
  34. package/ui/content/Alert/Alert.d.ts +5 -2
  35. package/ui/content/Alert/Alert.js +13 -12
  36. package/ui/content/Avatar/Avatar.js +18 -12
  37. package/ui/content/Badge/Badge.d.ts +5 -1
  38. package/ui/content/Badge/Badge.js +14 -12
  39. package/ui/content/Calendar/Calendar.d.ts +6 -1
  40. package/ui/content/Calendar/Calendar.js +19 -12
  41. package/ui/content/CalendarSystem/CalendarSystem.d.ts +40 -18
  42. package/ui/content/CalendarSystem/CalendarSystem.js +65 -76
  43. package/ui/content/CalendarSystem/hooks/useCalendarControls.d.ts +1 -2
  44. package/ui/content/CalendarSystem/hooks/useCalendarControls.js +14 -17
  45. package/ui/content/CalendarSystem/hooks/useCalendarSystemEventGroupModals.js +11 -3
  46. package/ui/content/CalendarSystem/hooks/useCalendarSystemModals.js +2 -2
  47. package/ui/content/CalendarSystem/hooks/useCalendarType.d.ts +5 -0
  48. package/ui/content/CalendarSystem/hooks/useCalendarType.js +22 -0
  49. package/ui/content/CalendarSystem/hooks/useEventsFromDate.d.ts +5 -0
  50. package/ui/content/CalendarSystem/hooks/useEventsFromDate.js +49 -0
  51. package/ui/content/CalendarSystem/hooks/{useMonthCalendar.d.ts → useMonthGrid.d.ts} +4 -5
  52. package/ui/content/CalendarSystem/hooks/{useMonthCalendar.js → useMonthGrid.js} +24 -15
  53. package/ui/content/CalendarSystem/hooks/{useWeekCalendar.d.ts → useWeekGrid.d.ts} +6 -5
  54. package/ui/content/CalendarSystem/hooks/useWeekGrid.js +72 -0
  55. package/ui/content/CalendarSystem/utils/utils.d.ts +8 -0
  56. package/ui/content/CalendarSystem/utils/utils.js +27 -1
  57. package/ui/content/Card/Card.d.ts +33 -27
  58. package/ui/content/Card/Card.js +1 -12
  59. package/ui/content/Chart/Chart.d.ts +38 -8
  60. package/ui/content/Chart/Chart.js +16 -12
  61. package/ui/content/Chat/Chat.d.ts +90 -5
  62. package/ui/content/Chat/Chat.js +40 -14
  63. package/ui/content/Chat/constants/timeTemplatesAndUnits.d.ts +1 -0
  64. package/ui/content/Chat/constants/timeTemplatesAndUnits.js +2 -1
  65. package/ui/content/Chat/hooks/useChat.d.ts +5 -6
  66. package/ui/content/Chat/hooks/useChat.js +49 -3
  67. package/ui/content/Chat/utils/addNewMessageIntoGroupedMessages.d.ts +5 -0
  68. package/ui/content/Chat/utils/addNewMessageIntoGroupedMessages.js +61 -0
  69. package/ui/content/Chat/utils/getMessagesGroupedByDate.d.ts +1 -0
  70. package/ui/content/Chat/utils/getMessagesGroupedByDate.js +3 -2
  71. package/ui/content/Chat/utils/index.d.ts +4 -2
  72. package/ui/content/Chat/utils/index.js +6 -1
  73. package/ui/content/Chat/utils/isTodayMessage.d.ts +1 -0
  74. package/ui/content/Chat/utils/isTodayMessage.js +13 -0
  75. package/ui/content/CopyToClipboard/CopyToClipboard.d.ts +3 -3
  76. package/ui/content/CopyToClipboard/CopyToClipboard.js +10 -12
  77. package/ui/content/Dashboard/Dashboard.d.ts +5 -2
  78. package/ui/content/Dashboard/Dashboard.js +27 -3
  79. package/ui/content/Detail/Detail.d.ts +15 -2
  80. package/ui/content/Detail/Detail.js +12 -1
  81. package/ui/content/DropDown/DropDown.d.ts +1 -1
  82. package/ui/content/DropDown/DropDown.js +16 -4
  83. package/ui/content/Icon/Icon.js +13 -15
  84. package/ui/content/Kanban/Kanban.d.ts +15 -4
  85. package/ui/content/Kanban/Kanban.js +8 -12
  86. package/ui/content/Kanban/hooks/useKanban.d.ts +33 -26
  87. package/ui/content/Menu/Menu.js +10 -12
  88. package/ui/content/Slider/Slider.js +1 -12
  89. package/ui/crud/index.d.ts +3 -0
  90. package/ui/form/AutoCompleteField/AutoCompleteField.js +1 -1
  91. package/ui/form/Button/Button.js +8 -2
  92. package/ui/form/CheckboxField/CheckboxField.d.ts +1 -0
  93. package/ui/form/CheckboxField/CheckboxField.js +2 -2
  94. package/ui/form/CheckboxListField/CheckboxListField.d.ts +18 -2
  95. package/ui/form/CheckboxListField/CheckboxListField.js +1 -1
  96. package/ui/form/CheckboxTreeField/CheckboxTreeField.d.ts +67 -0
  97. package/ui/form/CheckboxTreeField/CheckboxTreeField.js +126 -0
  98. package/ui/form/CheckboxTreeField/index.d.ts +2 -0
  99. package/ui/form/CheckboxTreeField/index.js +7 -0
  100. package/ui/form/DateField/DateField.js +4 -1
  101. package/ui/form/DateField/useDateRange.d.ts +1 -0
  102. package/ui/form/DateField/useDateRange.js +13 -2
  103. package/ui/form/DateRangeField/DateRangeField.d.ts +34 -1
  104. package/ui/form/DateRangeField/DateRangeField.js +59 -8
  105. package/ui/form/DateTimeField/DateTimeField.d.ts +10 -0
  106. package/ui/form/DateTimeField/DateTimeField.js +11 -3
  107. package/ui/form/DateTimeRangeField/DateTimeRangeField.d.ts +25 -1
  108. package/ui/form/DateTimeRangeField/DateTimeRangeField.js +66 -13
  109. package/ui/form/DropDownField/DropDownField.d.ts +23 -3
  110. package/ui/form/DropDownField/DropDownField.js +1 -1
  111. package/ui/form/EmailField/EmailField.d.ts +6 -0
  112. package/ui/form/EmailField/EmailField.js +0 -4
  113. package/ui/form/Field/Field.d.ts +9 -1
  114. package/ui/form/Field/Field.js +1 -1
  115. package/ui/form/Field/fieldWrapper.d.ts +9 -1
  116. package/ui/form/FieldList/FieldList.d.ts +13 -7
  117. package/ui/form/FieldList/FieldList.js +30 -4
  118. package/ui/form/FileField/FileField.js +5 -0
  119. package/ui/form/Form/Form.d.ts +26 -3
  120. package/ui/form/Form/Form.js +5 -3
  121. package/ui/form/ImageField/ImageField.d.ts +9 -1
  122. package/ui/form/InputField/InputField.d.ts +5 -2
  123. package/ui/form/InputField/hooks/useInputFieldWarningByType.js +1 -0
  124. package/ui/form/NumberField/NumberField.js +34 -7
  125. package/ui/form/SliderField/SliderField.d.ts +10 -2
  126. package/ui/form/TimeRangeField/TimeRangeField.d.ts +10 -1
  127. package/ui/form/TimeRangeField/TimeRangeField.js +3 -1
  128. package/ui/form/WizardForm/WizardForm.d.ts +119 -0
  129. package/ui/form/WizardForm/WizardForm.js +167 -0
  130. package/ui/form/WizardForm/index.d.ts +2 -0
  131. package/ui/form/WizardForm/index.js +7 -0
  132. package/ui/form/WizardForm/utils.d.ts +12 -0
  133. package/ui/form/WizardForm/utils.js +111 -0
  134. package/ui/form/index.d.ts +3 -1
  135. package/ui/form/index.js +4 -1
  136. package/ui/layout/ProgressBar/ProgressBar.js +8 -2
  137. package/ui/layout/Skeleton/Skeleton.d.ts +3 -1
  138. package/ui/layout/Tooltip/Tooltip.d.ts +4 -1
  139. package/ui/list/ControlsColumn/ControlsColumn.d.ts +17 -3
  140. package/ui/list/FlexGrid/FlexGrid.d.ts +11 -1
  141. package/ui/list/Grid/Grid.d.ts +42 -6
  142. package/ui/list/Grid/Grid.js +1 -2
  143. package/ui/list/LayoutNames/LayoutNames.d.ts +11 -1
  144. package/ui/list/Steps/Steps.d.ts +19 -7
  145. package/ui/list/Steps/Steps.js +46 -26
  146. package/ui/list/TreeTable/TreeTable.d.ts +34 -33
  147. package/ui/list/TreeTable/TreeTable.js +19 -8
  148. package/ui/modal/Modal/Modal.d.ts +7 -1
  149. package/ui/nav/Breadcrumbs/Breadcrumbs.d.ts +11 -1
  150. package/ui/nav/ButtonGroup/ButtonGroup.d.ts +13 -4
  151. package/ui/nav/Controls/Controls.d.ts +7 -1
  152. package/ui/nav/Link/Link.d.ts +1 -1
  153. package/ui/nav/Nav/Nav.d.ts +19 -4
  154. package/ui/nav/Router/Router.d.ts +19 -3
  155. package/ui/nav/Router/Router.js +11 -6
  156. package/ui/nav/Router/helpers.d.ts +2 -2
  157. package/ui/nav/Router/helpers.js +39 -7
  158. package/ui/nav/Tree/Tree.d.ts +32 -62
  159. package/ui/nav/Tree/Tree.js +18 -165
  160. package/utils/calculateComponentAbsolutePosition.js +74 -24
  161. package/utils/calendar.d.ts +8 -0
  162. package/utils/calendar.js +76 -1
  163. package/utils/data.js +1 -0
  164. package/utils/form.d.ts +1 -0
  165. package/utils/form.js +16 -1
  166. package/ui/content/CalendarSystem/hooks/useWeekCalendar.js +0 -86
  167. package/utils/list.d.ts +0 -1
  168. package/utils/list.js +0 -5
@@ -1,14 +1,27 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
2
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
15
  };
5
16
  exports.__esModule = true;
6
- exports.sortEventsInGroup = exports.getOmittedEvent = exports.isDateIsToday = exports.getWeekDaysFromDate = void 0;
17
+ exports.getFormattedWeekFromDate = exports.getSourceCalendarControl = exports.sortEventsInGroup = exports.getOmittedEvent = exports.isDateIsToday = exports.getWeekDaysFromDate = void 0;
7
18
  /* eslint-disable no-plusplus */
8
19
  var dayjs_1 = __importDefault(require("dayjs"));
9
20
  var omit_1 = __importDefault(require("lodash-es/omit"));
21
+ var calendar_1 = require("../../../../utils/calendar");
10
22
  var SIX_DAYS_DIFF = 6;
11
23
  var MAX_DAYS_DIFF_IN_WEEK = 7;
24
+ var WEEK_DAY_FORMAT = 'dd, D MMM';
12
25
  var getWeekDaysFromDate = function (date) {
13
26
  var weekDays = [];
14
27
  var firstDayOfWeek = new Date(date);
@@ -32,3 +45,16 @@ var getOmittedEvent = function (event) { return (0, omit_1["default"])(event, ['
32
45
  exports.getOmittedEvent = getOmittedEvent;
33
46
  var sortEventsInGroup = function (group) { return group.events.sort(function (eventA, eventB) { return eventA.date.getTime() - eventB.date.getTime(); }); };
34
47
  exports.sortEventsInGroup = sortEventsInGroup;
48
+ var getSourceCalendarControl = function (control) { return document.querySelector("[data-sourcecontrol=\"".concat(control, "\"]")); };
49
+ exports.getSourceCalendarControl = getSourceCalendarControl;
50
+ var getFormattedWeekFromDate = function (fromDate) {
51
+ if (fromDate === void 0) { fromDate = null; }
52
+ var currentWeek = (0, exports.getWeekDaysFromDate)(fromDate || new Date());
53
+ return currentWeek.map(function (dayOfWeek) {
54
+ var copyOfDayWeek = __assign({}, dayOfWeek);
55
+ copyOfDayWeek.formattedDisplay = (0, calendar_1.convertDate)(dayOfWeek.date, null, WEEK_DAY_FORMAT);
56
+ copyOfDayWeek.isToday = (0, exports.isDateIsToday)(copyOfDayWeek.date);
57
+ return copyOfDayWeek;
58
+ });
59
+ };
60
+ exports.getFormattedWeekFromDate = getFormattedWeekFromDate;
@@ -1,4 +1,4 @@
1
- /// <reference types="react" />
1
+ import React from 'react';
2
2
  import { ILinkProps } from '../../nav/Link/Link';
3
3
  import { IButtonProps } from '../../form/Button/Button';
4
4
  import { IAvatarProps } from '../Avatar/Avatar';
@@ -38,6 +38,10 @@ export interface ICardHeader {
38
38
  * футер, коллекцию ссылок и коллекцию кнопок.
39
39
  */
40
40
  export interface ICardProps extends IUiComponent {
41
+ /**
42
+ * Коллекция кнопок
43
+ */
44
+ buttons?: IButtonProps[];
41
45
  /**
42
46
  * Дочерние элементы
43
47
  */
@@ -52,46 +56,48 @@ export interface ICardProps extends IUiComponent {
52
56
  * @example 'Scroll to see more...'
53
57
  */
54
58
  description?: string;
59
+ /**
60
+ * Контент футера
61
+ */
62
+ footer?: {
63
+ head: string;
64
+ subhead: string;
65
+ };
55
66
  /**
56
67
  * Контент хедера
57
68
  * @example
58
69
  * avatar: {
59
- * src: 'Kate.png',
60
- * status: true,
70
+ * src: 'Kate.png',
71
+ * status: true,
61
72
  * },
62
73
  * head: 'Header',
63
74
  * subhead: 'Subhead',
64
75
  * menu: {
65
76
  * dropDownProps: {
66
- position: 'bottom',
67
- closeMode: 'click-any',
68
- },
69
- items: [
70
- {label: 'Вырезать', icon: 'cut', onClick: voidFunction},
71
- {label: 'Копировать', icon: 'copy', hasBorder: true, onClick: voidFunction},
72
- {label: 'Показать историю изменений', hasBorder: true, onClick: voidFunction},
73
- {label: 'Редактировать', icon: 'edit', onClick: voidFunction},
74
- {label: 'Удалить', icon: 'trash', onClick: voidFunction},
75
- ],
76
- icon: 'menu_dots',
77
+ * position: 'bottom',
78
+ * closeMode: 'click-any',
79
+ * },
80
+ * items: [
81
+ * {
82
+ * label: 'Вырезать',
83
+ * icon: 'cut',
84
+ * onClick: voidFunction
85
+ * },
86
+ * {
87
+ * label: 'Копировать',
88
+ * icon: 'copy',
89
+ * hasBorder: true
90
+ * onClick: voidFunction
91
+ * },
92
+ * ],
93
+ * icon: 'menu_dots',
77
94
  * },
78
95
  */
79
96
  header?: ICardHeader;
80
97
  /**
81
- * Контент футера
98
+ * Коллекция ссылок
82
99
  */
83
- footer?: {
84
- head: string;
85
- subhead: string;
86
- };
87
- /**
88
- * Коллекция ссылок
89
- */
90
100
  links?: ILinkProps[];
91
- /**
92
- * Коллекция кнопок
93
- */
94
- buttons?: IButtonProps[];
95
101
  /**
96
102
  * Заголовок карточки
97
103
  * @example 'Main card'
@@ -99,5 +105,5 @@ export interface ICardProps extends IUiComponent {
99
105
  title?: string;
100
106
  }
101
107
  export type ICardViewProps = ICardProps;
102
- declare function Card(props: ICardProps): import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
108
+ declare function Card(props: ICardProps): React.ReactElement<any, string | React.JSXElementConstructor<any>>;
103
109
  export default Card;
@@ -1,19 +1,8 @@
1
1
  "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
2
  exports.__esModule = true;
14
3
  var hooks_1 = require("../../../hooks");
15
4
  function Card(props) {
16
5
  var components = (0, hooks_1.useComponents)();
17
- return components.ui.renderView(props.view || 'content.CardView', __assign({}, props));
6
+ return components.ui.renderView(props.view || 'content.CardView', props);
18
7
  }
19
8
  exports["default"] = Card;
@@ -1,9 +1,12 @@
1
1
  /// <reference types="react" />
2
+ import { ICheckboxListFieldProps } from 'src/ui/form/CheckboxListField/CheckboxListField';
3
+ import { IButtonGroupProps } from 'src/ui/nav/ButtonGroup/ButtonGroup';
2
4
  /**
3
5
  * Chart
4
- * Этот компонент позволяет создавать в проекте графики разных типов. Под капотом для графиков используется библиотека nivo.
5
- * Для работы этого компонента необходимо установить в проекте зависимости @nivo/core и пакет конкретного графика nivo, например @nivo/line.
6
- * Компонент графика nivo нужно передать в пропс chartComponent
6
+ * Этот компонент позволяет создавать в проекте графики разных типов, используя библиотеки nivo, react-vis и другие.
7
+ * Под капотом для графиков могут использоваться различные библиотеки в зависимости от предпочтений и потребностей проекта.
8
+ * Для работы с nivo графиками, необходимо установить в проекте зависимости @nivo/core и соответствующий пакет графика, например @nivo/line.
9
+ * Компонент графика, независимо от выбранной библиотеки, нужно передать в пропс chartComponent.
7
10
  */
8
11
  export interface IChartProps extends IUiComponent {
9
12
  /**
@@ -13,19 +16,46 @@ export interface IChartProps extends IUiComponent {
13
16
  chartComponent: any;
14
17
  /**
15
18
  * Данные для графика
16
- * @example [{id: 1, value: 15}, {id: 2, value: 30}]
19
+ * @example
20
+ * [
21
+ * {id: 1, value: 15},
22
+ * {id: 2, value: 30}
23
+ * ]
17
24
  */
18
- data: Record<string, any>[];
25
+ data?: Record<string, any>[];
19
26
  /**
20
27
  * Конфигурация, настройки отображения графика
21
- * @example {lineWidth: 3, pointSize: 10}
28
+ * @example
29
+ * {
30
+ * lineWidth: 3,
31
+ * pointSize: 10
32
+ * }
22
33
  */
23
34
  config?: Record<string, any>;
24
35
  /**
25
- * Фиксированная высота графика в пикселях
36
+ * Фиксированная высота обертки в пикселях
26
37
  * @example 500
27
38
  */
28
- height?: number;
39
+ wrapperHeight?: number;
40
+ /**
41
+ * Фиксированная высота обертки в пикселях
42
+ * @example 500
43
+ */
44
+ chartHeight?: number;
45
+ /**
46
+ * Чекбоксы
47
+ * Могут служить в качестве настаиваемых контроллов для создания функционала
48
+ */
49
+ checkboxes?: ICheckboxListFieldProps;
50
+ /**
51
+ * Кнопки
52
+ * Могут служить в качестве настаиваемых контроллов для создания функционала
53
+ */
54
+ buttonGroup?: IButtonGroupProps;
55
+ /**
56
+ * Заголовок графика
57
+ */
58
+ title?: string;
29
59
  /**
30
60
  * Использовать ли дефолтную конфигурацию для графика типа line
31
61
  * @example ResponsiveLine
@@ -1,19 +1,23 @@
1
1
  "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
2
  exports.__esModule = true;
3
+ var react_1 = require("react");
14
4
  var hooks_1 = require("../../../hooks");
15
5
  function Chart(props) {
16
6
  var components = (0, hooks_1.useComponents)();
17
- return components.ui.renderView(props.view || 'content.ChartView', __assign({}, props));
7
+ var viewProps = (0, react_1.useMemo)(function () { return ({
8
+ chartComponent: props.chartComponent,
9
+ data: props.data,
10
+ config: props.config,
11
+ wrapperHeight: props.wrapperHeight,
12
+ chartHeight: props.chartHeight,
13
+ checkboxes: props.checkboxes,
14
+ buttonGroup: props.buttonGroup,
15
+ title: props.title,
16
+ useDefaultLineChartConfig: props.useDefaultLineChartConfig,
17
+ className: props.className,
18
+ style: props.style
19
+ }); }, [props.chartComponent, props.data, props.config, props.wrapperHeight, props.chartHeight,
20
+ props.checkboxes, props.buttonGroup, props.title, props.useDefaultLineChartConfig, props.className, props.style]);
21
+ return components.ui.renderView(props.view || 'content.ChartView', viewProps);
18
22
  }
19
23
  exports["default"] = Chart;
@@ -1,24 +1,109 @@
1
1
  import React from 'react';
2
+ import { IFileFieldProps } from '../../form/FileField/FileField';
2
3
  import { IAvatarProps } from '../Avatar/Avatar';
3
- import { IChatConfig, IGroupedMessagesByDates } from './hooks/useChat';
4
+ import { IGroupedMessagesByDates } from './hooks/useChat';
4
5
  export interface IChatUser {
5
6
  id: number;
6
7
  firstName?: string;
7
8
  lastName?: string;
8
9
  avatar?: IAvatarProps;
9
10
  }
11
+ export interface IMessageFile {
12
+ uid?: string;
13
+ title?: string;
14
+ size?: number;
15
+ url?: string;
16
+ downloadUrl?: string;
17
+ fullHeight?: number;
18
+ fullWidth?: number;
19
+ }
10
20
  export interface IChatMessage {
11
21
  id: number;
12
22
  user: IChatUser;
13
23
  text: string;
14
- timestamp: Date;
24
+ timestamp: Date | string;
25
+ files?: IMessageFile[];
15
26
  }
16
- interface IChatProps extends IChatConfig, IUiComponent {
27
+ /**
28
+ * Chat
29
+ *
30
+ * Комплексный компонент `Chat` предназначен для коммуникации пользователей с помощью текстовых сообщений.
31
+ */
32
+ export interface IChatProps extends IUiComponent {
33
+ /**
34
+ * Идентификатор чата
35
+ * @example TaskChat
36
+ */
17
37
  chatId: string;
38
+ /**
39
+ * Коллекция сообщений
40
+ * @example
41
+ * [
42
+ * {
43
+ * id: 1,
44
+ * text: 'Всем привет!',
45
+ * files: [
46
+ * {
47
+ * id: 929,
48
+ * uid: 'c46f3d14-5891-4601-9e98-06f2c1e70a07',
49
+ * title: 'image.jpg',
50
+ * url: 'https://kozhin.dev/files/uploaded/c46f3d14-5891-4601-9e98-06f2c1e70a07.jpg',
51
+ * size: 47305,
52
+ * }
53
+ * ],
54
+ * user: {
55
+ * id: 1,
56
+ * firstName: 'Olga',
57
+ * lastName: 'Petrova',
58
+ * avatar: {
59
+ * src: 'images.com/image.png',
60
+ * status: true,
61
+ * },
62
+ * },
63
+ * timestamp: '2023-10-25T12:38:00',
64
+ * },
65
+ * ]
66
+ */
67
+ messages: IChatMessage[];
68
+ /**
69
+ * Данные о текущем пользователе, нужны для отправки сообщений и определения сообщений пользователя
70
+ * @example
71
+ * {
72
+ * id: 1,
73
+ * firstName: 'Olga',
74
+ * lastName: 'Petrova',
75
+ * avatar: {
76
+ * src: 'images.com/image.png',
77
+ * status: true,
78
+ * },
79
+ * }
80
+ */
18
81
  currentUser: IChatUser;
82
+ /**
83
+ * Обработчик события отправки сообщения
84
+ */
85
+ onSendMessage?: (chatId: string, message: IChatMessage) => void;
86
+ /**
87
+ * Переопределение view React компонента для кастомизации отображения элемента инпута
88
+ * @example MyCustomView
89
+ */
90
+ customChatInputView?: React.ReactNode;
91
+ /**
92
+ * Кастомный placeholder для инпута
93
+ */
94
+ customInputPlaceholder?: string;
95
+ /**
96
+ * Пропсы для инпута загрузки файлов
97
+ */
98
+ fileFieldProps?: IFileFieldProps;
19
99
  }
20
- export interface IChatViewProps extends Omit<IChatProps, 'messages'> {
100
+ export interface IChatViewProps extends Pick<IChatProps, 'currentUser'> {
21
101
  groupedMessagesByDates: IGroupedMessagesByDates;
102
+ renderChatInput: () => JSX.Element;
103
+ }
104
+ export interface IChatInputViewProps extends Pick<IChatProps, 'chatId' | 'fileFieldProps'> {
105
+ onSendMessage: (data: any) => void;
106
+ onUploadFiles: (files: any) => void;
107
+ inputPlaceholder: string;
22
108
  }
23
109
  export default function Chat(props: IChatProps): React.ReactElement<any, string | React.JSXElementConstructor<any>>;
24
- export {};
@@ -1,26 +1,52 @@
1
1
  "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
12
24
  };
13
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
14
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
27
  };
16
28
  exports.__esModule = true;
29
+ var react_1 = __importStar(require("react"));
17
30
  var hooks_1 = require("../../../hooks");
18
31
  var useChat_1 = __importDefault(require("./hooks/useChat"));
19
32
  function Chat(props) {
20
33
  var components = (0, hooks_1.useComponents)();
21
- var groupedMessagesByDates = (0, useChat_1["default"])({
22
- messages: props.messages
23
- }).groupedMessagesByDates;
24
- return components.ui.renderView(props.view || 'content.ChatView', __assign(__assign({}, props), { groupedMessagesByDates: groupedMessagesByDates }));
34
+ var _a = (0, useChat_1["default"])({
35
+ chatId: props.chatId,
36
+ messages: props.messages,
37
+ currentUser: props.currentUser,
38
+ onSendMessage: props.onSendMessage
39
+ }), onSendMessage = _a.onSendMessage, onUploadFiles = _a.onUploadFiles, groupedMessagesByDates = _a.groupedMessagesByDates;
40
+ var ChatInputView = props.customChatInputView || components.ui.getView('content.ChatInputView');
41
+ var renderChatInput = (0, react_1.useCallback)(function () { return (react_1["default"].createElement(ChatInputView, { chatId: props.chatId, onSendMessage: onSendMessage, onUploadFiles: onUploadFiles, fileFieldProps: props.fileFieldProps, inputPlaceholder: props.customInputPlaceholder || __('Введите сообщение') })); }, [ChatInputView, onSendMessage, onUploadFiles, props.chatId, props.customInputPlaceholder, props.fileFieldProps]);
42
+ var viewProps = (0, react_1.useMemo)(function () { return ({
43
+ currentUser: props.currentUser,
44
+ groupedMessagesByDates: groupedMessagesByDates,
45
+ onSendMessage: onSendMessage,
46
+ renderChatInput: renderChatInput,
47
+ className: props.className,
48
+ style: props.style
49
+ }); }, [groupedMessagesByDates, onSendMessage, props.className, props.currentUser, props.style, renderChatInput]);
50
+ return components.ui.renderView(props.view || 'content.ChatView', viewProps);
25
51
  }
26
52
  exports["default"] = Chat;
@@ -1,6 +1,7 @@
1
1
  export declare const MONTH_AND_DAY_TEMPLATE = "MMMM DD";
2
2
  export declare const HOURS_AND_MINUTES_TEMPLATE = "HH:mm";
3
3
  export declare const MINUTE_UNIT = "minute";
4
+ export declare const ISO_TIMESTAMP_TEMPLATE = "YYYY-MM-DDTHH:mm:ss.SSS";
4
5
  export declare const HOUR_UNIT = "hour";
5
6
  export declare const SECONDS_IN_MINUTE_VALUE = 60000;
6
7
  export declare const MINUTES_IN_HOUR_VALUE = 60;
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  exports.__esModule = true;
3
- exports.HOURS_IN_DAY_VALUE = exports.MINUTES_IN_HOUR_VALUE = exports.SECONDS_IN_MINUTE_VALUE = exports.HOUR_UNIT = exports.MINUTE_UNIT = exports.HOURS_AND_MINUTES_TEMPLATE = exports.MONTH_AND_DAY_TEMPLATE = void 0;
3
+ exports.HOURS_IN_DAY_VALUE = exports.MINUTES_IN_HOUR_VALUE = exports.SECONDS_IN_MINUTE_VALUE = exports.HOUR_UNIT = exports.ISO_TIMESTAMP_TEMPLATE = exports.MINUTE_UNIT = exports.HOURS_AND_MINUTES_TEMPLATE = exports.MONTH_AND_DAY_TEMPLATE = void 0;
4
4
  exports.MONTH_AND_DAY_TEMPLATE = 'MMMM DD';
5
5
  exports.HOURS_AND_MINUTES_TEMPLATE = 'HH:mm';
6
6
  exports.MINUTE_UNIT = 'minute';
7
+ exports.ISO_TIMESTAMP_TEMPLATE = 'YYYY-MM-DDTHH:mm:ss.SSS';
7
8
  exports.HOUR_UNIT = 'hour';
8
9
  exports.SECONDS_IN_MINUTE_VALUE = 60000;
9
10
  exports.MINUTES_IN_HOUR_VALUE = 60;
@@ -1,13 +1,12 @@
1
- import { IChatMessage } from '../Chat';
2
- export interface IChatConfig {
3
- messages: IChatMessage[];
4
- }
1
+ import { IChatMessage, IChatProps } from '../Chat';
2
+ export type IChatConfig = Pick<IChatProps, 'chatId' | 'messages' | 'currentUser' | 'onSendMessage'>;
5
3
  export interface IGroupedMessage extends IChatMessage {
6
4
  isFirstMessage?: boolean;
7
5
  isLastMessage?: boolean;
8
6
  }
9
7
  export type IGroupedMessagesByDates = Record<string, IGroupedMessage[][]>;
10
- declare const useChat: (config: IChatConfig) => {
8
+ export default function useChat(config: IChatConfig): {
11
9
  groupedMessagesByDates: {};
10
+ onSendMessage: (rawMessage: any) => void;
11
+ onUploadFiles: (files: any) => void;
12
12
  };
13
- export default useChat;
@@ -1,12 +1,58 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
2
16
  exports.__esModule = true;
3
17
  var react_1 = require("react");
18
+ var dayjs_1 = __importDefault(require("dayjs"));
19
+ var uniqueId_1 = __importDefault(require("lodash-es/uniqueId"));
20
+ var isEqual_1 = __importDefault(require("lodash-es/isEqual"));
21
+ var File_1 = __importDefault(require("fileup-core/lib/models/File"));
22
+ var hooks_1 = require("../../../../hooks");
23
+ var form_1 = require("../../../../actions/form");
4
24
  var utils_1 = require("../utils");
5
- var useChat = function (config) {
25
+ var timeTemplatesAndUnits_1 = require("../constants/timeTemplatesAndUnits");
26
+ function useChat(config) {
27
+ var dispatch = (0, hooks_1.useDispatch)();
6
28
  var _a = (0, react_1.useState)({}), groupedMessagesByDates = _a[0], setGroupedMessagesByDates = _a[1];
29
+ var _b = (0, react_1.useState)([]), uploadedFiles = _b[0], setUploadedFiles = _b[1];
7
30
  (0, react_1.useEffect)(function () { return setGroupedMessagesByDates((0, utils_1.getMessagesGroupedByDate)(config.messages)); }, [config.messages]);
31
+ var onUploadFiles = (0, react_1.useCallback)(function (files) {
32
+ if (!(0, isEqual_1["default"])(uploadedFiles, files)) {
33
+ setUploadedFiles(files);
34
+ }
35
+ }, [uploadedFiles]);
36
+ var onSendMessage = (0, react_1.useCallback)(function (rawMessage) {
37
+ if (!rawMessage) {
38
+ return;
39
+ }
40
+ var newMessage = __assign(__assign({}, rawMessage), { id: (0, uniqueId_1["default"])(), user: config.currentUser, timestamp: (0, dayjs_1["default"])().format(timeTemplatesAndUnits_1.ISO_TIMESTAMP_TEMPLATE), files: (uploadedFiles === null || uploadedFiles === void 0 ? void 0 : uploadedFiles.reduce(function (acc, file) {
41
+ if (file.getResult() !== File_1["default"].RESULT_ERROR) {
42
+ acc.push(__assign({}, file._resultHttpMessage));
43
+ }
44
+ return acc;
45
+ }, [])) || null });
46
+ if (config.onSendMessage) {
47
+ config.onSendMessage(config.chatId, newMessage);
48
+ }
49
+ setGroupedMessagesByDates(function (prevGroupedMessagesByDates) { return (0, utils_1.addNewMessageIntoGroupedMessages)(newMessage, prevGroupedMessagesByDates); });
50
+ dispatch((0, form_1.formReset)(config.chatId));
51
+ }, [config, dispatch, uploadedFiles]);
8
52
  return {
9
- groupedMessagesByDates: groupedMessagesByDates
53
+ groupedMessagesByDates: groupedMessagesByDates,
54
+ onSendMessage: onSendMessage,
55
+ onUploadFiles: onUploadFiles
10
56
  };
11
- };
57
+ }
12
58
  exports["default"] = useChat;
@@ -0,0 +1,5 @@
1
+ import { IChatMessage } from '@steroidsjs/core/ui/content/Chat/Chat';
2
+ import { IGroupedMessage, IGroupedMessagesByDates } from '../hooks/useChat';
3
+ export declare const addNewMessageIntoGroupedMessages: (newMessage: IChatMessage, groupedMessagesByDates: IGroupedMessagesByDates) => {
4
+ [x: string]: IGroupedMessage[][];
5
+ };
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
14
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
15
+ if (ar || !(i in from)) {
16
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
17
+ ar[i] = from[i];
18
+ }
19
+ }
20
+ return to.concat(ar || Array.prototype.slice.call(from));
21
+ };
22
+ var __importDefault = (this && this.__importDefault) || function (mod) {
23
+ return (mod && mod.__esModule) ? mod : { "default": mod };
24
+ };
25
+ exports.__esModule = true;
26
+ exports.addNewMessageIntoGroupedMessages = void 0;
27
+ var dayjs_1 = __importDefault(require("dayjs"));
28
+ var last_1 = __importDefault(require("lodash-es/last"));
29
+ var getMessagesGroupedByDate_1 = require("../utils/getMessagesGroupedByDate");
30
+ var timeTemplatesAndUnits_1 = require("../constants/timeTemplatesAndUnits");
31
+ var addMessageToExistingGroup = function (newMessage, groupedMessagesByDates, dateKey) {
32
+ var _a;
33
+ var currentGroupedMessagesByDates = __spreadArray([], groupedMessagesByDates[dateKey], true);
34
+ // last array of messages for this date
35
+ var lastMessageGroup = currentGroupedMessagesByDates.pop();
36
+ // last message for this date
37
+ var lastMessageFromGroup = (0, last_1["default"])(lastMessageGroup);
38
+ var messagesGroupForCurrentDate = __spreadArray(__spreadArray([], groupedMessagesByDates[dateKey], true), [[newMessage]], false);
39
+ if ((0, getMessagesGroupedByDate_1.isWithinTimeThreshold)(lastMessageFromGroup, newMessage)) {
40
+ // make a new message the last in the group
41
+ delete lastMessageFromGroup.isLastMessage;
42
+ delete newMessage.isFirstMessage;
43
+ if (lastMessageGroup.length === 1) {
44
+ messagesGroupForCurrentDate = __spreadArray(__spreadArray([], currentGroupedMessagesByDates, true), [[lastMessageFromGroup, newMessage]], false);
45
+ }
46
+ else {
47
+ messagesGroupForCurrentDate = __spreadArray(__spreadArray([], currentGroupedMessagesByDates, true), [__spreadArray(__spreadArray([], lastMessageGroup, true), [newMessage], false)], false);
48
+ }
49
+ }
50
+ return __assign(__assign({}, groupedMessagesByDates), (_a = {}, _a[dateKey] = messagesGroupForCurrentDate, _a));
51
+ };
52
+ var addNewMessageIntoGroupedMessages = function (newMessage, groupedMessagesByDates) {
53
+ var _a;
54
+ var dateKey = (0, dayjs_1["default"])(newMessage.timestamp).format(timeTemplatesAndUnits_1.MONTH_AND_DAY_TEMPLATE);
55
+ var singleMessageInGroup = __assign(__assign({}, newMessage), { isFirstMessage: true, isLastMessage: true });
56
+ if (groupedMessagesByDates[dateKey]) {
57
+ return addMessageToExistingGroup(singleMessageInGroup, groupedMessagesByDates, dateKey);
58
+ }
59
+ return __assign(__assign({}, groupedMessagesByDates), (_a = {}, _a[dateKey] = [[singleMessageInGroup]], _a));
60
+ };
61
+ exports.addNewMessageIntoGroupedMessages = addNewMessageIntoGroupedMessages;
@@ -1,3 +1,4 @@
1
1
  import { IGroupedMessagesByDates } from '../hooks/useChat';
2
2
  import { IChatMessage } from '../Chat';
3
+ export declare const isWithinTimeThreshold: (firstMessage: IChatMessage, secondMessage: IChatMessage) => boolean;
3
4
  export declare const getMessagesGroupedByDate: (messages: IChatMessage[]) => IGroupedMessagesByDates;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  exports.__esModule = true;
6
- exports.getMessagesGroupedByDate = void 0;
6
+ exports.getMessagesGroupedByDate = exports.isWithinTimeThreshold = void 0;
7
7
  var first_1 = __importDefault(require("lodash-es/first"));
8
8
  var last_1 = __importDefault(require("lodash-es/last"));
9
9
  var dayjs_1 = __importDefault(require("dayjs"));
@@ -13,6 +13,7 @@ var isWithinTimeThreshold = function (firstMessage, secondMessage) {
13
13
  var secondMessageTime = new Date(secondMessage.timestamp).getTime();
14
14
  return firstMessage.user.id === secondMessage.user.id && Math.abs(firstMessageTime - secondMessageTime) <= timeTemplatesAndUnits_1.SECONDS_IN_MINUTE_VALUE;
15
15
  };
16
+ exports.isWithinTimeThreshold = isWithinTimeThreshold;
16
17
  var addFirstAndLastKeyForMessageGroup = function (messageGroup) {
17
18
  (0, first_1["default"])(messageGroup).isFirstMessage = true;
18
19
  (0, last_1["default"])(messageGroup).isLastMessage = true;
@@ -35,7 +36,7 @@ var getMessagesGroupedByDate = function (messages) {
35
36
  }
36
37
  var lastMessageFromGroup = (0, last_1["default"])(lastMessageGroup);
37
38
  // if time difference between messages is less than a minute, and they are from the same user
38
- if (lastMessageFromGroup && isWithinTimeThreshold(lastMessageFromGroup, message)) {
39
+ if (lastMessageFromGroup && (0, exports.isWithinTimeThreshold)(lastMessageFromGroup, message)) {
39
40
  lastMessageGroup.push(message);
40
41
  }
41
42
  else if (lastMessageGroup) {