@vanillabp/bc-shared 0.0.3 → 0.0.4

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.
@@ -1,14 +1,12 @@
1
1
  import { BoxExtendedProps, TextExtendedProps } from 'grommet';
2
- import { ColorType } from 'grommet/utils/index.js';
2
+ import { ColorType, BackgroundType } from 'grommet/utils/index.js';
3
3
  import React, { PropsWithChildren, FC } from 'react';
4
- import { BackgroundType } from 'grommet/utils';
5
4
  import { ListItem, Column } from '../types/ListCell.js';
6
5
  import { TranslationFunction } from '../types/translate.js';
7
6
 
8
- declare const ENDED_FONT_COLOR = "light-4";
9
7
  declare const ENDED_FONT_COLOR_ODD = "#b4b4b4";
10
8
  declare type Alignment = 'left' | 'center' | 'right';
11
- declare const colorForEndedItemsOrUndefined: (item: ListItem<any>) => ColorType;
9
+ declare const textColorAccordingToStatus: (item: ListItem<any>) => ColorType | undefined;
12
10
  interface ListCellProps extends BoxExtendedProps {
13
11
  background?: BackgroundType;
14
12
  align?: Alignment;
@@ -17,6 +15,7 @@ declare const ListCell: React.FC<PropsWithChildren<ListCellProps>>;
17
15
  interface TextListCellProps extends TextExtendedProps {
18
16
  item: ListItem<any>;
19
17
  value?: string | String;
18
+ column: string;
20
19
  tip?: string;
21
20
  showUnreadAsBold?: boolean;
22
21
  background?: BackgroundType;
@@ -28,7 +27,6 @@ interface DefaultListCellProps<D> {
28
27
  item: ListItem<D>;
29
28
  column: Column;
30
29
  showUnreadAsBold?: boolean;
31
- defaultLanguage?: string;
32
30
  currentLanguage: string;
33
31
  nameOfList?: string;
34
32
  selectItem: (select: boolean) => void;
@@ -38,7 +36,7 @@ interface DefaultListCellProps<D> {
38
36
  interface DefaultListCellAwareProps<T> extends DefaultListCellProps<T> {
39
37
  defaultCell: FC<DefaultListCellProps<T>>;
40
38
  }
41
- declare const colorRowAccordingToUpdateStatus: <T extends ListItem<any>>(item: T) => BackgroundType | undefined;
39
+ declare const backgroundColorAccordingToStatus: <T extends ListItem<any>>(item: T) => BackgroundType | undefined;
42
40
  declare const DefaultListCell: FC<DefaultListCellProps<any>>;
43
41
 
44
- export { Alignment, DefaultListCell, DefaultListCellAwareProps, DefaultListCellProps, ENDED_FONT_COLOR, ENDED_FONT_COLOR_ODD, ListCell, TextListCell, colorForEndedItemsOrUndefined, colorRowAccordingToUpdateStatus };
42
+ export { Alignment, DefaultListCell, DefaultListCellAwareProps, DefaultListCellProps, ENDED_FONT_COLOR_ODD, ListCell, TextListCell, backgroundColorAccordingToStatus, textColorAccordingToStatus };
@@ -5,6 +5,7 @@ import {
5
5
  } from "../chunk-YH4NJHER.js";
6
6
  import { jsx } from "react/jsx-runtime";
7
7
  import { Box, Text } from "grommet";
8
+ import { memo } from "react";
8
9
  import { ListItemStatus } from "../types/index.js";
9
10
  import {
10
11
  getObjectProperty,
@@ -12,11 +13,11 @@ import {
12
13
  toLocaleStringWithoutSeconds,
13
14
  toLocaleTimeStringWithoutSeconds
14
15
  } from "../utils/index.js";
16
+ import { UserDetailsBox } from "./index.js";
15
17
  const DATE_REGEXP = /^(\d{4})-(\d{2})-(\d{2})/;
16
- const ENDED_FONT_COLOR = "light-4";
17
18
  const ENDED_FONT_COLOR_ODD = "#b4b4b4";
18
- const colorForEndedItemsOrUndefined = (item) => {
19
- return item.status !== ListItemStatus.ENDED ? void 0 : ENDED_FONT_COLOR;
19
+ const textColorAccordingToStatus = (item) => {
20
+ return item.status === ListItemStatus.NEW ? "list-text-new" : item.status === ListItemStatus.UPDATED ? "list-text-updated" : item.status === ListItemStatus.ENDED ? "list-text-ended" : item.status === ListItemStatus.REMOVED_FROM_LIST ? "list-text-removed_from_list" : void 0;
20
21
  };
21
22
  const ListCell = (_a) => {
22
23
  var _b = _a, {
@@ -43,7 +44,7 @@ const ListCell = (_a) => {
43
44
  })
44
45
  );
45
46
  };
46
- const TextListCell = (_c) => {
47
+ const TextListCell = memo((_c) => {
47
48
  var _d = _c, {
48
49
  item,
49
50
  value = "",
@@ -59,7 +60,7 @@ const TextListCell = (_c) => {
59
60
  "showUnreadAsBold",
60
61
  "background"
61
62
  ]);
62
- const color = colorForEndedItemsOrUndefined(item);
63
+ const color = textColorAccordingToStatus(item);
63
64
  return /* @__PURE__ */ jsx(
64
65
  ListCell,
65
66
  {
@@ -87,28 +88,67 @@ const TextListCell = (_c) => {
87
88
  )
88
89
  }
89
90
  );
90
- };
91
- const render = (t, propertyValue, currentLanguage, defaultLanguage) => {
91
+ }, (prevProps, nextProps) => {
92
+ if (prevProps.item.id !== nextProps.item.id)
93
+ return false;
94
+ if (prevProps.column !== nextProps.column)
95
+ return false;
96
+ return Object.is(prevProps.value, nextProps.value);
97
+ });
98
+ const PersonListCell = memo((_e) => {
99
+ var _f = _e, {
100
+ t,
101
+ item,
102
+ column,
103
+ value,
104
+ showUnreadAsBold = false,
105
+ background
106
+ } = _f, props = __objRest(_f, [
107
+ "t",
108
+ "item",
109
+ "column",
110
+ "value",
111
+ "showUnreadAsBold",
112
+ "background"
113
+ ]);
114
+ var _a, _b;
115
+ const color = textColorAccordingToStatus(item);
116
+ return /* @__PURE__ */ jsx(
117
+ ListCell,
118
+ {
119
+ background,
120
+ align: "left",
121
+ children: /* @__PURE__ */ jsx(
122
+ Text,
123
+ __spreadProps(__spreadValues({
124
+ truncate: true,
125
+ color,
126
+ weight: showUnreadAsBold && item.read === void 0 ? "bold" : "normal",
127
+ tip: { content: /* @__PURE__ */ jsx(UserDetailsBox, { user: value, t }) }
128
+ }, props), {
129
+ children: value === void 0 ? void 0 : (_b = (_a = value.displayShort) != null ? _a : value.email) != null ? _b : value.id
130
+ })
131
+ )
132
+ }
133
+ );
134
+ }, (prevProps, nextProps) => {
135
+ if (prevProps.item.id !== nextProps.item.id)
136
+ return false;
137
+ if (prevProps.column !== nextProps.column)
138
+ return false;
139
+ return Object.is(prevProps.value, nextProps.value);
140
+ });
141
+ const render = (t, propertyValue, currentLanguage) => {
92
142
  let align = "left";
93
143
  let value;
94
- let tip;
95
144
  if (typeof propertyValue === "object") {
96
- let langValue = propertyValue[currentLanguage];
97
- if (langValue !== void 0) {
98
- propertyValue = langValue;
99
- } else if (defaultLanguage !== void 0) {
100
- langValue = propertyValue[defaultLanguage];
101
- if (langValue !== void 0) {
102
- propertyValue = langValue;
103
- }
104
- }
105
- }
106
- if (propertyValue === void 0) {
145
+ value = "[object - define custom cell to render content]";
146
+ } else if (propertyValue === void 0) {
107
147
  value = "";
108
148
  } else if (propertyValue instanceof Date) {
109
- value = toLocaleTimeStringWithoutSeconds(propertyValue);
149
+ value = toLocaleTimeStringWithoutSeconds(propertyValue, currentLanguage);
110
150
  } else if (typeof propertyValue === "number") {
111
- value = propertyValue.toLocaleString(window.navigator.language);
151
+ value = propertyValue.toLocaleString(currentLanguage != null ? currentLanguage : window.navigator.language);
112
152
  align = "right";
113
153
  } else if (typeof propertyValue === "boolean") {
114
154
  if (propertyValue) {
@@ -120,11 +160,11 @@ const render = (t, propertyValue, currentLanguage, defaultLanguage) => {
120
160
  const dateMatch = DATE_REGEXP.exec(propertyValue);
121
161
  if (dateMatch) {
122
162
  if (propertyValue.length === 10) {
123
- value = toLocaleDateString(new Date(Date.parse(propertyValue)));
163
+ value = toLocaleDateString(new Date(Date.parse(propertyValue)), currentLanguage);
124
164
  align = "right";
125
165
  } else {
126
166
  const tmpDate = new Date(Date.parse(propertyValue));
127
- value = toLocaleStringWithoutSeconds(tmpDate);
167
+ value = toLocaleStringWithoutSeconds(tmpDate, currentLanguage);
128
168
  }
129
169
  } else {
130
170
  value = propertyValue;
@@ -132,35 +172,61 @@ const render = (t, propertyValue, currentLanguage, defaultLanguage) => {
132
172
  }
133
173
  return { value, align };
134
174
  };
135
- const colorRowAccordingToUpdateStatus = (item) => item.status === ListItemStatus.NEW ? { color: "accent-3", opacity: 0.1 } : item.status === ListItemStatus.UPDATED ? { color: "accent-1", opacity: 0.15 } : item.status === ListItemStatus.ENDED ? { color: "light-2", opacity: 0.5 } : item.status === ListItemStatus.REMOVED_FROM_LIST ? { color: "light-2", opacity: 0.5 } : void 0;
175
+ const backgroundColorAccordingToStatus = (item) => item.status === ListItemStatus.NEW ? "list-new" : item.status === ListItemStatus.UPDATED ? "list-updated" : item.status === ListItemStatus.ENDED ? "list-ended" : item.status === ListItemStatus.REMOVED_FROM_LIST ? "list-removed_from_list" : void 0;
136
176
  const DefaultListCell = ({
137
177
  item,
138
178
  column,
139
179
  showUnreadAsBold,
140
180
  currentLanguage,
141
- defaultLanguage,
142
181
  t,
143
182
  selectItem
144
183
  }) => {
145
- let propertyValue = getObjectProperty(item.data, column.path);
146
184
  let align = "left";
147
185
  let value;
148
186
  let tip;
149
- if (column.path === "dueDate") {
150
- value = toLocaleDateString(item.data.dueDate);
151
- tip = toLocaleStringWithoutSeconds(item.data.dueDate);
187
+ let path = column.path;
188
+ if (column.type === "i18n") {
189
+ path = `${path}.${currentLanguage}`;
190
+ }
191
+ const background = backgroundColorAccordingToStatus(item);
192
+ let propertyValue = getObjectProperty(item.data, path);
193
+ if (column.type === "date" && Boolean(propertyValue)) {
194
+ const date = Object.prototype.toString.call(propertyValue) === "[object Date]" ? propertyValue : new Date(propertyValue.toString());
195
+ value = toLocaleDateString(date, currentLanguage);
196
+ tip = toLocaleStringWithoutSeconds(date, currentLanguage);
152
197
  align = "right";
198
+ } else if (column.type === "time" && Boolean(propertyValue)) {
199
+ const date = Object.prototype.toString.call(propertyValue) === "[object Date]" ? propertyValue : new Date(propertyValue.toString());
200
+ value = date.toLocaleTimeString(currentLanguage);
201
+ align = "right";
202
+ } else if (column.type === "date-time" && Boolean(propertyValue)) {
203
+ const date = Object.prototype.toString.call(propertyValue) === "[object Date]" ? propertyValue : new Date(propertyValue.toString());
204
+ value = date.toLocaleDateString() + " " + toLocaleTimeStringWithoutSeconds(date, currentLanguage);
205
+ tip = date.toLocaleTimeString(currentLanguage);
206
+ align = "right";
207
+ } else if (column.type === "person" && Boolean(propertyValue)) {
208
+ return /* @__PURE__ */ jsx(
209
+ PersonListCell,
210
+ {
211
+ t,
212
+ item,
213
+ value: propertyValue,
214
+ column: column.path,
215
+ showUnreadAsBold,
216
+ background
217
+ }
218
+ );
153
219
  } else {
154
- const { value: v, align: a } = render(t, propertyValue, currentLanguage, defaultLanguage);
220
+ const { value: v, align: a } = render(t, propertyValue, currentLanguage);
155
221
  value = v;
156
222
  align = a;
157
223
  }
158
- const background = colorRowAccordingToUpdateStatus(item);
159
224
  return /* @__PURE__ */ jsx(
160
225
  TextListCell,
161
226
  {
162
227
  item,
163
228
  value,
229
+ column: column.path,
164
230
  tip,
165
231
  showUnreadAsBold,
166
232
  background,
@@ -170,10 +236,9 @@ const DefaultListCell = ({
170
236
  };
171
237
  export {
172
238
  DefaultListCell,
173
- ENDED_FONT_COLOR,
174
239
  ENDED_FONT_COLOR_ODD,
175
240
  ListCell,
176
241
  TextListCell,
177
- colorForEndedItemsOrUndefined,
178
- colorRowAccordingToUpdateStatus
242
+ backgroundColorAccordingToStatus,
243
+ textColorAccordingToStatus
179
244
  };
@@ -10,7 +10,9 @@ interface DefaultListHeaderProps<D> {
10
10
  selectAll: (select: boolean) => void;
11
11
  allSelected: boolean;
12
12
  sort?: boolean;
13
+ isDefaultSort: boolean;
13
14
  sortAscending?: boolean;
15
+ defaultSortAscending: boolean;
14
16
  setSort: (column?: Column) => void;
15
17
  setSortAscending: (ascending: boolean) => void;
16
18
  }
@@ -6,12 +6,32 @@ const DefaultListHeader = ({
6
6
  column,
7
7
  currentLanguage,
8
8
  sort,
9
+ isDefaultSort,
9
10
  sortAscending,
11
+ defaultSortAscending,
10
12
  setSort,
11
13
  setSortAscending,
12
14
  allSelected,
13
15
  selectAll
14
16
  }) => {
17
+ const language = currentLanguage != null ? currentLanguage : window.navigator.language.replace(
18
+ /* exclude country */
19
+ /-.*$/,
20
+ ""
21
+ );
22
+ const setNewSortAscending = () => {
23
+ if (isDefaultSort) {
24
+ if (sortAscending === defaultSortAscending) {
25
+ setSortAscending(!defaultSortAscending);
26
+ } else {
27
+ setSort(void 0);
28
+ }
29
+ } else if (sortAscending) {
30
+ setSortAscending(false);
31
+ } else {
32
+ setSort(void 0);
33
+ }
34
+ };
15
35
  if (column.path === "id") {
16
36
  return /* @__PURE__ */ jsx(
17
37
  Box,
@@ -39,7 +59,7 @@ const DefaultListHeader = ({
39
59
  children: /* @__PURE__ */ jsx(
40
60
  Tip,
41
61
  {
42
- content: column.title[currentLanguage] || column.title["en"],
62
+ content: column.title[language],
43
63
  children: /* @__PURE__ */ jsx(ContactInfo, {})
44
64
  }
45
65
  )
@@ -58,7 +78,7 @@ const DefaultListHeader = ({
58
78
  Text,
59
79
  {
60
80
  truncate: "tip",
61
- children: column.title[currentLanguage] || column.title["en"]
81
+ children: column.title[language]
62
82
  }
63
83
  ),
64
84
  /* @__PURE__ */ jsx(
@@ -68,36 +88,49 @@ const DefaultListHeader = ({
68
88
  direction: "row",
69
89
  justify: "end",
70
90
  style: { maxHeight: "1.5rem", minWidth: "2rem" },
71
- children: !column.sortable ? void 0 : !Boolean(sort) ? /* @__PURE__ */ jsx(
91
+ children: !column.sortable ? void 0 : /* @__PURE__ */ jsx(
72
92
  Box,
73
93
  {
74
- overflow: "hidden",
75
- focusIndicator: false,
94
+ style: { position: "relative" },
76
95
  width: "1.6rem",
77
- onClick: (event) => setSort(column),
78
- children: /* @__PURE__ */ jsx(
79
- Unsorted,
96
+ height: "2rem",
97
+ align: "center",
98
+ children: !Boolean(sort) ? /* @__PURE__ */ jsx(
99
+ Box,
100
+ {
101
+ style: { position: "relative", top: "-1px" },
102
+ focusIndicator: false,
103
+ onClick: (event) => setSort(column),
104
+ direction: "column",
105
+ justify: "around",
106
+ children: /* @__PURE__ */ jsx(Unsorted, { size: "34px" })
107
+ }
108
+ ) : sortAscending ? /* @__PURE__ */ jsx(
109
+ Box,
110
+ {
111
+ focusIndicator: false,
112
+ style: { marginRight: "-0.5rem" },
113
+ width: "1.2rem",
114
+ height: "2rem",
115
+ direction: "column",
116
+ justify: "around",
117
+ onClick: (event) => setNewSortAscending(),
118
+ children: /* @__PURE__ */ jsx(Ascend, { size: "18px" })
119
+ }
120
+ ) : /* @__PURE__ */ jsx(
121
+ Box,
80
122
  {
81
- size: "32rem"
123
+ focusIndicator: false,
124
+ style: { marginRight: "-0.5rem" },
125
+ width: "1.2rem",
126
+ height: "2rem",
127
+ direction: "column",
128
+ justify: "around",
129
+ onClick: (event) => setNewSortAscending(),
130
+ children: /* @__PURE__ */ jsx(Descend, { size: "18px" })
82
131
  }
83
132
  )
84
133
  }
85
- ) : sortAscending ? /* @__PURE__ */ jsx(
86
- Box,
87
- {
88
- focusIndicator: false,
89
- onClick: (event) => setSortAscending(false),
90
- pad: { right: "0.5rem" },
91
- children: /* @__PURE__ */ jsx(Ascend, { size: "16rem" })
92
- }
93
- ) : /* @__PURE__ */ jsx(
94
- Box,
95
- {
96
- focusIndicator: false,
97
- onClick: (event) => setSort(void 0),
98
- pad: { right: "0.5rem" },
99
- children: /* @__PURE__ */ jsx(Descend, { size: "16rem" })
100
- }
101
134
  )
102
135
  }
103
136
  )
@@ -5,19 +5,20 @@ import {
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  import { Text } from "grommet";
7
7
  import styled from "styled-components";
8
+ import { normalizeColor } from "grommet/utils/index.js";
8
9
  ;
9
10
  const StyledLink = styled(Text)`
10
11
  text-decoration: none;
11
- color: ${(props) => props.theme.global.colors["accent-3"]};
12
+ color: ${(props) => props.color ? normalizeColor(props.color, props.theme) : normalizeColor(props.theme.global.colors["link"], props.theme)};
12
13
  cursor: pointer;
13
14
 
14
15
  &:hover {
15
16
  text-decoration: underline;
16
- color: black;
17
+ color: ${(props) => props.color ? normalizeColor(props.color, props.theme) : normalizeColor(props.theme.global.colors["link"], props.theme)};
17
18
  }
18
19
 
19
20
  &:visited {
20
- color: ${(props) => props.theme.global.colors["accent-3"]};
21
+ color: ${(props) => props.color ? normalizeColor(props.color, props.theme) : normalizeColor(props.theme.global.colors["link"], props.theme)};
21
22
  }
22
23
  `;
23
24
  const Link = (_a) => {
@@ -0,0 +1,10 @@
1
+ import { Person } from '@vanillabp/bc-official-gui-client';
2
+ import { Person as Person$1 } from '../types/ListCell.js';
3
+ import { TranslationFunction } from '../types/translate.js';
4
+
5
+ declare const UserDetailsBox: ({ t, user }: {
6
+ t: TranslationFunction;
7
+ user: Person | Person$1;
8
+ }) => JSX.Element;
9
+
10
+ export { UserDetailsBox };
@@ -0,0 +1,42 @@
1
+ import "../chunk-YH4NJHER.js";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { Grid, Text } from "grommet";
4
+ const UserDetailsBox = ({
5
+ t,
6
+ user
7
+ }) => {
8
+ return /* @__PURE__ */ jsxs(
9
+ Grid,
10
+ {
11
+ columns: ["auto", "auto"],
12
+ rows: ["auto", "auto", "auto"],
13
+ areas: [{ name: "person", start: [0, 0], end: [1, 0] }],
14
+ gap: "xsmall",
15
+ children: [
16
+ /* @__PURE__ */ jsx(
17
+ Text,
18
+ {
19
+ gridArea: "person",
20
+ style: { fontStyle: "italic" },
21
+ children: user.display
22
+ }
23
+ ),
24
+ /* @__PURE__ */ jsxs(Text, { children: [
25
+ t("person-id"),
26
+ ":"
27
+ ] }),
28
+ /* @__PURE__ */ jsx(Text, { weight: "bold", children: user.id }),
29
+ user.email !== null ? /* @__PURE__ */ jsxs(Fragment, { children: [
30
+ /* @__PURE__ */ jsxs(Text, { children: [
31
+ t("person-email"),
32
+ ":"
33
+ ] }),
34
+ /* @__PURE__ */ jsx(Text, { weight: "bold", children: user.email })
35
+ ] }) : void 0
36
+ ]
37
+ }
38
+ );
39
+ };
40
+ export {
41
+ UserDetailsBox
42
+ };
@@ -25,6 +25,7 @@ const UserTaskAppLayout = ({
25
25
  /* @__PURE__ */ jsx(
26
26
  Box,
27
27
  {
28
+ overflow: { vertical: "auto" },
28
29
  fill: true,
29
30
  children
30
31
  }
@@ -7,9 +7,10 @@ export { Link } from './Link.js';
7
7
  export { Modal } from './ModalDialog.js';
8
8
  export { UserTaskAppLayout } from './UserTaskAppLayout.js';
9
9
  export { WarningListCell } from './WarningListCell.js';
10
- export { Alignment, DefaultListCell, DefaultListCellAwareProps, DefaultListCellProps, ENDED_FONT_COLOR, ENDED_FONT_COLOR_ODD, ListCell, TextListCell, colorForEndedItemsOrUndefined, colorRowAccordingToUpdateStatus } from './DefaultListCell.js';
10
+ export { Alignment, DefaultListCell, DefaultListCellAwareProps, DefaultListCellProps, ENDED_FONT_COLOR_ODD, ListCell, TextListCell, backgroundColorAccordingToStatus, textColorAccordingToStatus } from './DefaultListCell.js';
11
11
  export { DefaultListHeader, DefaultListHeaderAwareProps, DefaultListHeaderProps } from './DefaultListHeader.js';
12
12
  export { CopyClipboard, CopyClipboardButton } from './CopyClipboard.js';
13
+ export { UserDetailsBox } from './UserDetailsBox.js';
13
14
  import '@microsoft/fetch-event-source';
14
15
  import 'react';
15
16
  import 'grommet';
@@ -18,3 +19,4 @@ import 'i18next';
18
19
  import 'grommet/utils/index.js';
19
20
  import '../types/ListCell.js';
20
21
  import '../types/translate.js';
22
+ import '@vanillabp/bc-official-gui-client';
@@ -10,3 +10,4 @@ export * from "./WarningListCell.js";
10
10
  export * from "./DefaultListCell.js";
11
11
  export * from "./DefaultListHeader.js";
12
12
  export * from "./CopyClipboard.js";
13
+ export * from "./UserDetailsBox.js";
package/dist/index.d.ts CHANGED
@@ -7,9 +7,10 @@ export { Link } from './components/Link.js';
7
7
  export { Modal } from './components/ModalDialog.js';
8
8
  export { UserTaskAppLayout } from './components/UserTaskAppLayout.js';
9
9
  export { WarningListCell } from './components/WarningListCell.js';
10
- export { Alignment, DefaultListCell, DefaultListCellAwareProps, DefaultListCellProps, ENDED_FONT_COLOR, ENDED_FONT_COLOR_ODD, ListCell, TextListCell, colorForEndedItemsOrUndefined, colorRowAccordingToUpdateStatus } from './components/DefaultListCell.js';
10
+ export { Alignment, DefaultListCell, DefaultListCellAwareProps, DefaultListCellProps, ENDED_FONT_COLOR_ODD, ListCell, TextListCell, backgroundColorAccordingToStatus, textColorAccordingToStatus } from './components/DefaultListCell.js';
11
11
  export { DefaultListHeader, DefaultListHeaderAwareProps, DefaultListHeaderProps } from './components/DefaultListHeader.js';
12
12
  export { CopyClipboard, CopyClipboardButton } from './components/CopyClipboard.js';
13
+ export { UserDetailsBox } from './components/UserDetailsBox.js';
13
14
  export { useOnClickOutside } from './utils/clickOutside.js';
14
15
  export { debounce, debounceByKey } from './utils/debounce.js';
15
16
  export { REFRESH_TOKEN_HEADER, buildFetchApi } from './utils/fetchApi.js';
@@ -21,11 +22,13 @@ export { i18n } from './utils/i18n.js';
21
22
  export { theme } from './theme/index.js';
22
23
  export { UserTaskForm } from './types/UserTaskForm.js';
23
24
  export { ColumnsOfUserTaskFunction, UserTaskListCell } from './types/UserTaskListCell.js';
24
- export { Column, ListItem, ListItemStatus } from './types/ListCell.js';
25
+ export { Column, ListItem, ListItemStatus, Person } from './types/ListCell.js';
25
26
  export { WorkflowPage } from './types/WorkflowPage.js';
26
27
  export { ColumnsOfWorkflowFunction, WorkflowListCell } from './types/WorkflowListCell.js';
27
28
  export { BcWorkflow, GetUserTasksFunction, NavigateToWorkflowFunction } from './types/BcWorkflow.js';
28
- export { BcUserTask, OpenUserTaskFunction, OpenWorkflowFunction, UnassignFunction } from './types/BcUserTask.js';
29
+ export { AssignFunction, BcUserTask, ClaimFunction, OpenUserTaskFunction, OpenWorkflowFunction, UnassignFunction, UnclaimFunction } from './types/BcUserTask.js';
30
+ export { BcWorkflowModule } from './types/BcWorkflowModule.js';
31
+ export { WorkflowModule, WorkflowModuleComponent, WorkflowModuleComponentProps } from './types/WorkflowModuleComponent.js';
29
32
  export { TranslationFunction } from './types/translate.js';
30
33
  import '@microsoft/fetch-event-source';
31
34
  import 'react';
@@ -10,7 +10,17 @@ const theme = {
10
10
  "accent-4": "#333333",
11
11
  "placeholder": "#bbbbbb",
12
12
  "light-5": "#c7c7c7",
13
- "light-6": "#b4b4b4"
13
+ "light-6": "#b4b4b4",
14
+ "link": "#663300",
15
+ "list-new": "rgba(102, 51, 0, 0.1)",
16
+ "list-text-new": "dark-1",
17
+ "list-updated": "rgba(255, 230, 153, 0.15)",
18
+ "list-text-updated": "dark-1",
19
+ "list-ended": "rgba(242, 242, 242, 0.25)",
20
+ "list-text-ended": "dark-4",
21
+ "list-removed_from_list": "rgba(242, 242, 242, 0.25)",
22
+ "list-text-removed_from_list": "dark-1",
23
+ "list-refresh": "#ffe699"
14
24
  },
15
25
  font: {
16
26
  family: "Roboto",
@@ -24,6 +34,9 @@ const theme = {
24
34
  outline: {
25
35
  color: "#e0a244"
26
36
  }
37
+ },
38
+ drop: {
39
+ zIndex: 99
27
40
  }
28
41
  },
29
42
  table: {
@@ -2,11 +2,17 @@ import { UserTask } from '@vanillabp/bc-official-gui-client';
2
2
 
3
3
  declare type OpenUserTaskFunction = () => void;
4
4
  declare type OpenWorkflowFunction = () => void;
5
+ declare type AssignFunction = (userId: string) => void;
5
6
  declare type UnassignFunction = (userId: string) => void;
7
+ declare type ClaimFunction = () => void;
8
+ declare type UnclaimFunction = () => void;
6
9
  interface BcUserTask extends UserTask {
7
10
  open: OpenUserTaskFunction;
8
11
  navigateToWorkflow: OpenWorkflowFunction;
12
+ assign: AssignFunction;
9
13
  unassign: UnassignFunction;
14
+ claim: ClaimFunction;
15
+ unclaim: UnclaimFunction;
10
16
  }
11
17
 
12
- export { BcUserTask, OpenUserTaskFunction, OpenWorkflowFunction, UnassignFunction };
18
+ export { AssignFunction, BcUserTask, ClaimFunction, OpenUserTaskFunction, OpenWorkflowFunction, UnassignFunction, UnclaimFunction };
@@ -0,0 +1,30 @@
1
+ import { UiUriType } from '@vanillabp/bc-official-gui-client';
2
+
3
+ interface BcWorkflowModule {
4
+ /**
5
+ * The workflow module of this usertask
6
+ * @type {string}
7
+ * @memberof UserTask
8
+ */
9
+ workflowModuleId: string;
10
+ /**
11
+ * An URI as an entrypoint URI for UI components. Maybe a technical URL (e.g. for WEBPACK) or an URL targeting a human readable form (e.g. EXTERNAL)
12
+ * @type {string}
13
+ * @memberof UserTask
14
+ */
15
+ uiUri: string;
16
+ /**
17
+ *
18
+ * @type {UiUriType}
19
+ * @memberof UserTask
20
+ */
21
+ uiUriType: UiUriType;
22
+ /**
23
+ * An URI pointing to the workflow-module's own API (maybe used by user-task forms)
24
+ * @type {string}
25
+ * @memberof UserTask
26
+ */
27
+ workflowModuleUri: string;
28
+ }
29
+
30
+ export { BcWorkflowModule };
File without changes
@@ -4,6 +4,7 @@ interface Title {
4
4
  interface Column {
5
5
  title: Title;
6
6
  path: string;
7
+ type?: 'value' | 'i18n' | 'person' | 'date' | 'date-time' | 'time';
7
8
  priority: number;
8
9
  width: string;
9
10
  show: boolean;
@@ -11,6 +12,16 @@ interface Column {
11
12
  filterable: boolean;
12
13
  resizeable: boolean;
13
14
  }
15
+ interface Person {
16
+ id: string;
17
+ display?: string;
18
+ displayShort?: string;
19
+ email?: string;
20
+ avatar?: number;
21
+ details?: {
22
+ [key: string]: any;
23
+ };
24
+ }
14
25
  declare enum ListItemStatus {
15
26
  INITIAL = 0,
16
27
  NEW = 1,
@@ -27,4 +38,4 @@ interface ListItem<D> {
27
38
  read?: Date;
28
39
  }
29
40
 
30
- export { Column, ListItem, ListItemStatus };
41
+ export { Column, ListItem, ListItemStatus, Person };
@@ -1,5 +1,4 @@
1
1
  import "../chunk-YH4NJHER.js";
2
- ;
3
2
  var ListItemStatus = /* @__PURE__ */ ((ListItemStatus2) => {
4
3
  ListItemStatus2[ListItemStatus2["INITIAL"] = 0] = "INITIAL";
5
4
  ListItemStatus2[ListItemStatus2["NEW"] = 1] = "NEW";
@@ -5,7 +5,6 @@ import { Column } from './ListCell.js';
5
5
  import { DefaultListCellAwareProps } from '../components/DefaultListCell.js';
6
6
  import 'grommet';
7
7
  import 'grommet/utils/index.js';
8
- import 'grommet/utils';
9
8
  import './translate.js';
10
9
 
11
10
  interface UserTaskListCellProps extends DefaultListCellAwareProps<BcUserTask> {
@@ -5,7 +5,6 @@ import { Column } from './ListCell.js';
5
5
  import { BcWorkflow } from './BcWorkflow.js';
6
6
  import 'grommet';
7
7
  import 'grommet/utils/index.js';
8
- import 'grommet/utils';
9
8
  import './translate.js';
10
9
  import './BcUserTask.js';
11
10
 
@@ -0,0 +1,16 @@
1
+ import { FC } from 'react';
2
+ import { ToastFunction } from '../components/Toast.js';
3
+ import 'grommet';
4
+
5
+ interface WorkflowModule {
6
+ id: string;
7
+ version: number;
8
+ uri: string;
9
+ }
10
+ interface WorkflowModuleComponentProps {
11
+ workflowModule: WorkflowModule;
12
+ toast: ToastFunction;
13
+ }
14
+ declare type WorkflowModuleComponent = FC<WorkflowModuleComponentProps>;
15
+
16
+ export { WorkflowModule, WorkflowModuleComponent, WorkflowModuleComponentProps };
File without changes
@@ -1,14 +1,16 @@
1
1
  export { UserTaskForm } from './UserTaskForm.js';
2
2
  export { ColumnsOfUserTaskFunction, UserTaskListCell } from './UserTaskListCell.js';
3
- export { Column, ListItem, ListItemStatus } from './ListCell.js';
3
+ export { Column, ListItem, ListItemStatus, Person } from './ListCell.js';
4
4
  export { WorkflowPage } from './WorkflowPage.js';
5
5
  export { ColumnsOfWorkflowFunction, WorkflowListCell } from './WorkflowListCell.js';
6
6
  export { BcWorkflow, GetUserTasksFunction, NavigateToWorkflowFunction } from './BcWorkflow.js';
7
- export { BcUserTask, OpenUserTaskFunction, OpenWorkflowFunction, UnassignFunction } from './BcUserTask.js';
7
+ export { AssignFunction, BcUserTask, ClaimFunction, OpenUserTaskFunction, OpenWorkflowFunction, UnassignFunction, UnclaimFunction } from './BcUserTask.js';
8
+ export { BcWorkflowModule } from './BcWorkflowModule.js';
9
+ export { WorkflowModule, WorkflowModuleComponent, WorkflowModuleComponentProps } from './WorkflowModuleComponent.js';
8
10
  export { TranslationFunction } from './translate.js';
9
11
  import 'react';
10
12
  import '@vanillabp/bc-official-gui-client';
11
13
  import '../components/DefaultListCell.js';
12
14
  import 'grommet';
13
15
  import 'grommet/utils/index.js';
14
- import 'grommet/utils';
16
+ import '../components/Toast.js';
@@ -5,4 +5,6 @@ export * from "./WorkflowPage.js";
5
5
  export * from "./WorkflowListCell.js";
6
6
  export * from "./BcWorkflow.js";
7
7
  export * from "./BcUserTask.js";
8
+ export * from "./BcWorkflowModule.js";
9
+ export * from "./WorkflowModuleComponent.js";
8
10
  export * from "./translate.js";
@@ -1,10 +1,10 @@
1
- import { Dispatch } from 'react';
2
1
  import { WakeupSseCallback } from '../components/SseProvider.js';
3
- import { ToastAction } from '../components/Toast.js';
2
+ import { ToastFunction } from '../components/Toast.js';
4
3
  import '@microsoft/fetch-event-source';
4
+ import 'react';
5
5
  import 'grommet';
6
6
 
7
7
  declare const REFRESH_TOKEN_HEADER = "x-refresh-token";
8
- declare const buildFetchApi: (dispatch: Dispatch<ToastAction>, wakeupSeeCallback?: WakeupSseCallback) => WindowOrWorkerGlobalScope['fetch'];
8
+ declare const buildFetchApi: (toast: ToastFunction, wakeupSeeCallback?: WakeupSseCallback) => WindowOrWorkerGlobalScope['fetch'];
9
9
 
10
10
  export { REFRESH_TOKEN_HEADER, buildFetchApi };
@@ -4,7 +4,7 @@ import {
4
4
  __spreadValues
5
5
  } from "../chunk-YH4NJHER.js";
6
6
  const REFRESH_TOKEN_HEADER = "x-refresh-token";
7
- const doRequest = (dispatch, resolve, reject, input, init, refreshToken) => {
7
+ const doRequest = (toast, resolve, reject, input, init, refreshToken) => {
8
8
  navigator.locks.request(
9
9
  "bc-webapp",
10
10
  {
@@ -32,41 +32,41 @@ const doRequest = (dispatch, resolve, reject, input, init, refreshToken) => {
32
32
  if (isRefresh && !Boolean(responseRefreshToken)) {
33
33
  window.localStorage.removeItem(REFRESH_TOKEN_HEADER);
34
34
  } else if (Boolean(storedRefreshToken)) {
35
- doRequest(dispatch, resolve, reject, input, init, storedRefreshToken);
35
+ doRequest(toast, resolve, reject, input, init, storedRefreshToken);
36
36
  return;
37
37
  }
38
38
  } else if (response.status >= 500) {
39
- dispatch({ type: "toast", toast: {
39
+ toast({
40
40
  namespace: "app",
41
41
  title: "error",
42
42
  message: "unexpected"
43
- } });
43
+ });
44
44
  } else if (response.status === 403) {
45
- dispatch({ type: "toast", toast: {
45
+ toast({
46
46
  namespace: "app",
47
47
  title: "error",
48
48
  message: "forbidden"
49
- } });
49
+ });
50
50
  }
51
51
  resolve(response);
52
52
  } catch (error) {
53
- dispatch({ type: "toast", toast: {
53
+ toast({
54
54
  namespace: "app",
55
55
  title: "error",
56
56
  message: "unexpected"
57
- } });
57
+ });
58
58
  reject(error);
59
59
  }
60
60
  })
61
61
  );
62
62
  };
63
- const buildFetchApi = (dispatch, wakeupSeeCallback) => {
63
+ const buildFetchApi = (toast, wakeupSeeCallback) => {
64
64
  return (input, init) => {
65
65
  return new Promise((resolve, reject) => {
66
66
  if (wakeupSeeCallback !== void 0) {
67
67
  wakeupSeeCallback();
68
68
  }
69
- doRequest(dispatch, resolve, reject, input, init);
69
+ doRequest(toast, resolve, reject, input, init);
70
70
  });
71
71
  };
72
72
  };
@@ -2,9 +2,9 @@ declare const isValidLocalDate: (localDate: string) => boolean;
2
2
  declare const parseLocalDate: (localDate: string | undefined) => Date | undefined;
3
3
  declare const parseLocalDateToIsoString: (localDate: string | undefined | null) => string | undefined;
4
4
  declare const toLocalDateString: (date?: Date) => string | undefined;
5
- declare const toLocaleTimeStringWithoutSeconds: (date?: Date) => string | undefined;
6
- declare const toLocaleDateString: (date?: Date) => string | undefined;
7
- declare const toLocaleStringWithoutSeconds: (date?: Date) => string | undefined;
5
+ declare const toLocaleTimeStringWithoutSeconds: (date?: Date | string, language?: string) => string | undefined;
6
+ declare const toLocaleDateString: (date?: Date | string, language?: string) => string | undefined;
7
+ declare const toLocaleStringWithoutSeconds: (date?: Date | string, language?: string) => string | undefined;
8
8
  declare const currentHour: () => Date;
9
9
  declare const nextHours: (from: Date, hours: number, history: boolean) => Date;
10
10
  declare const hoursBetween: (from: Date, to: Date) => Array<Date>;
@@ -33,23 +33,29 @@ const toLocalDateString = (date) => {
33
33
  }
34
34
  return String(date.getFullYear()).padStart(4, "0") + "-" + String(date.getMonth() + 1).padStart(2, "0") + "-" + String(date.getDate()).padStart(2, "0");
35
35
  };
36
- const toLocaleTimeStringWithoutSeconds = (date) => {
36
+ const toLocaleTimeStringWithoutSeconds = (date, language) => {
37
37
  if (!Boolean(date)) {
38
38
  return void 0;
39
39
  }
40
- return date.toLocaleTimeString(window.navigator.language).replace(/:[0-9]{2}(?: |$)/, "");
40
+ if (typeof date === "string") {
41
+ date = new Date(date);
42
+ }
43
+ return date.toLocaleTimeString(language != null ? language : window.navigator.language).replace(/:[0-9]{2}(?: |$)/, "");
41
44
  };
42
- const toLocaleDateString = (date) => {
45
+ const toLocaleDateString = (date, language) => {
43
46
  if (!Boolean(date)) {
44
47
  return void 0;
45
48
  }
46
- return date.toLocaleDateString(window.navigator.language);
49
+ if (typeof date === "string") {
50
+ date = new Date(date);
51
+ }
52
+ return date.toLocaleDateString(language != null ? language : window.navigator.language);
47
53
  };
48
- const toLocaleStringWithoutSeconds = (date) => {
54
+ const toLocaleStringWithoutSeconds = (date, language) => {
49
55
  if (!Boolean(date)) {
50
56
  return void 0;
51
57
  }
52
- return `${toLocaleDateString(date)} ${toLocaleTimeStringWithoutSeconds(date)}`;
58
+ return `${toLocaleDateString(date, language)} ${toLocaleTimeStringWithoutSeconds(date, language)}`;
53
59
  };
54
60
  const currentHour = () => {
55
61
  const now = /* @__PURE__ */ new Date();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vanillabp/bc-shared",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/vanillabp/business-cockpit.git"
@@ -17,7 +17,7 @@
17
17
  ],
18
18
  "dependencies": {
19
19
  "@microsoft/fetch-event-source": "2.0.1",
20
- "@vanillabp/bc-official-gui-client": "0.0.3",
20
+ "@vanillabp/bc-official-gui-client": "0.0.4",
21
21
  "react-cookie": "4.1.1",
22
22
  "usehooks-ts": "2.7.1"
23
23
  },