@addev-be/ui 3.3.3 → 3.4.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.
@@ -9,6 +9,7 @@ import "lodash";
9
9
  import "../forms/Form/index.js";
10
10
  import "../forms/Form/styles.js";
11
11
  import "../forms/NumberInput.js";
12
+ import "../forms/SqlPrefixFilterCombobox/SqlPrefixFilterCombobox.js";
12
13
  import { useParams as x, Link as R } from "react-router-dom";
13
14
  import "../common/Accordion/Accordion.js";
14
15
  import "../common/Avatar/styles.js";
@@ -26,7 +27,7 @@ import "../common/TreeView/TreeContext.js";
26
27
  import { FormContainer as j } from "./styles.js";
27
28
  import { StackedLabel as w } from "../forms/VerticalLabel.js";
28
29
  import { useAuthentication as E } from "../../hooks/providers.js";
29
- const ne = () => {
30
+ const ae = () => {
30
31
  const { key: t } = x(), [s, y] = o(""), [i, C] = o(""), [n, v] = o(-1), [p, k] = o(-1), [c, u] = o(""), { resetPassword: d, checkRecoveryKey: l } = E();
31
32
  S(() => {
32
33
  t && l(t).then((r) => {
@@ -75,5 +76,5 @@ const ne = () => {
75
76
  ] }) });
76
77
  };
77
78
  export {
78
- ne as PasswordResetForm
79
+ ae as PasswordResetForm
79
80
  };
@@ -0,0 +1,9 @@
1
+ import { UseSqlPrefixFilterComboboxStateProps } from './useSqlPrefixFilterComboboxState';
2
+ export type SqlPrefixFilterComboboxProps<T> = UseSqlPrefixFilterComboboxStateProps<T> & {
3
+ label?: string;
4
+ itemKey: (item: T, index: number) => string;
5
+ noResultsText?: string;
6
+ placeholder?: string;
7
+ readOnly?: boolean;
8
+ };
9
+ export declare const SqlPrefixFilterCombobox: <T>({ label, value, itemKey, itemLabel, readOnly, noResultsText, placeholder, ...props }: SqlPrefixFilterComboboxProps<T>) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,140 @@
1
+ import { jsx as o, jsxs as a, Fragment as _ } from "react/jsx-runtime";
2
+ import { CardForm as h } from "../Form/index.js";
3
+ import r from "styled-components";
4
+ import { useSqlPrefixFilterComboboxState as $ } from "./useSqlPrefixFilterComboboxState.js";
5
+ const A = 20, B = 40, O = r.div`
6
+ position: relative;
7
+ width: 100%;
8
+ `, j = r.input`
9
+ font-family: var(--font-input);
10
+ font-size: var(--text-base);
11
+ font-weight: 500;
12
+ border: 1px solid var(--color-base-300);
13
+ color: var(--color-text-800);
14
+ background: var(--color-base-0);
15
+ box-sizing: border-box;
16
+ width: 100%;
17
+ padding: var(--space-2);
18
+ border-radius: var(--rounded-md);
19
+
20
+ &:focus {
21
+ outline: none;
22
+ border-color: var(--color-sky-500);
23
+ box-shadow: 0 0 0 1px var(--color-sky-500);
24
+ }
25
+ `, q = r.div`
26
+ position: absolute;
27
+ top: calc(100% + var(--space-1));
28
+ left: 0;
29
+ right: 0;
30
+ z-index: 20;
31
+ max-height: ${A}rem;
32
+ background: var(--color-base-0);
33
+ border: 1px solid var(--color-base-300);
34
+ border-radius: var(--rounded-md);
35
+ box-shadow: var(--shadow-lg);
36
+ overflow-y: auto;
37
+ overflow-x: hidden;
38
+ `, K = r.button`
39
+ width: 100%;
40
+ border: 0;
41
+ height: ${B}px;
42
+ padding: 0 var(--space-3);
43
+ text-align: left;
44
+ cursor: pointer;
45
+ background: ${({ $highlighted: t }) => t ? "var(--color-base-100)" : "var(--color-base-0)"};
46
+ color: var(--color-text-800);
47
+ display: flex;
48
+ align-items: center;
49
+
50
+ &:hover {
51
+ background: var(--color-base-100);
52
+ }
53
+ `, l = r.div`
54
+ padding: var(--space-2) var(--space-3);
55
+ color: var(--color-text-500);
56
+ font-size: var(--text-sm);
57
+ `, V = ({
58
+ label: t,
59
+ value: g,
60
+ itemKey: v,
61
+ itemLabel: i,
62
+ readOnly: p = !1,
63
+ noResultsText: b = "Aucun resultat",
64
+ placeholder: x,
65
+ ...f
66
+ }) => {
67
+ const {
68
+ bottomSpacerHeight: m,
69
+ filteredRows: s,
70
+ handleBlur: w,
71
+ handleChange: S,
72
+ handleFocus: C,
73
+ handleKeyDown: y,
74
+ handleOpenAllItems: d,
75
+ handleSuggestionsScroll: I,
76
+ inputValue: k,
77
+ isLoading: c,
78
+ opened: u,
79
+ highlightedIndex: F,
80
+ selectedLabel: H,
81
+ selectItem: D,
82
+ suggestionsContainerRef: E,
83
+ topSpacerHeight: M,
84
+ visibleRows: R,
85
+ visibleStartIndex: z
86
+ } = $({
87
+ ...f,
88
+ itemLabel: i,
89
+ value: g
90
+ });
91
+ return p ? /* @__PURE__ */ o(h.Input, { label: t, value: H, readOnly: !0 }) : /* @__PURE__ */ o(h.Row, { label: t, children: /* @__PURE__ */ a(O, { children: [
92
+ /* @__PURE__ */ o(
93
+ j,
94
+ {
95
+ type: "text",
96
+ value: k,
97
+ placeholder: u ? void 0 : x,
98
+ autoComplete: "off",
99
+ onMouseDown: d,
100
+ onClick: d,
101
+ onFocus: C,
102
+ onBlur: w,
103
+ onKeyDown: y,
104
+ onChange: (e) => S(e.target.value)
105
+ }
106
+ ),
107
+ u && /* @__PURE__ */ a(
108
+ q,
109
+ {
110
+ ref: E,
111
+ onScroll: I,
112
+ children: [
113
+ s.length > 0 ? /* @__PURE__ */ a(_, { children: [
114
+ /* @__PURE__ */ o("div", { style: { height: M } }),
115
+ R.map((e, G) => {
116
+ const n = z + G;
117
+ return /* @__PURE__ */ o(
118
+ K,
119
+ {
120
+ type: "button",
121
+ $highlighted: n === F,
122
+ onMouseDown: (T) => {
123
+ T.preventDefault(), D(e);
124
+ },
125
+ children: i(e, n)
126
+ },
127
+ v(e, n)
128
+ );
129
+ }),
130
+ /* @__PURE__ */ o("div", { style: { height: m } })
131
+ ] }) : c ? /* @__PURE__ */ o(l, { children: "Chargement..." }) : /* @__PURE__ */ o(l, { children: b }),
132
+ c && s.length > 0 && /* @__PURE__ */ o(l, { children: "Chargement..." })
133
+ ]
134
+ }
135
+ )
136
+ ] }) });
137
+ };
138
+ export {
139
+ V as SqlPrefixFilterCombobox
140
+ };
@@ -0,0 +1,36 @@
1
+ import { ConditionDTO, OrderByDTO, SqlRequestRow } from '../../../services/sqlRequests';
2
+ export type UseSqlPrefixFilterComboboxStateProps<T> = {
3
+ requestName: string;
4
+ columns: string[];
5
+ returnColumns?: string[];
6
+ parser?: (row: SqlRequestRow<T>) => T;
7
+ value: T | null;
8
+ itemLabel: (item: T, index: number) => string;
9
+ filterField: string;
10
+ conditions?: ConditionDTO[];
11
+ orderBy?: OrderByDTO[];
12
+ onChange?: (value: T | null) => void;
13
+ initialPageSize?: number;
14
+ pageSize?: number;
15
+ };
16
+ export declare const useSqlPrefixFilterComboboxState: <T>({ requestName, columns, returnColumns, parser, value, itemLabel, filterField, conditions, orderBy, onChange, initialPageSize, pageSize, }: UseSqlPrefixFilterComboboxStateProps<T>) => {
17
+ bottomSpacerHeight: number;
18
+ filteredRows: T[];
19
+ handleBlur: () => void;
20
+ handleChange: (nextValue: string) => void;
21
+ handleFocus: () => void;
22
+ handleKeyDown: (event: React.KeyboardEvent<HTMLInputElement>) => void;
23
+ handleOpenAllItems: () => void;
24
+ handleSuggestionsScroll: (event: React.UIEvent<HTMLDivElement>) => void;
25
+ inputValue: string;
26
+ isLoading: boolean;
27
+ opened: boolean;
28
+ highlightedIndex: number;
29
+ resetToSelectedValue: () => void;
30
+ selectedLabel: string;
31
+ selectItem: (item: T | null) => void;
32
+ suggestionsContainerRef: import('react').RefObject<HTMLDivElement | null>;
33
+ topSpacerHeight: number;
34
+ visibleRows: T[];
35
+ visibleStartIndex: number;
36
+ };
@@ -0,0 +1,275 @@
1
+ import { useSqlRequestHandler as De } from "../../../services/sqlRequests.js";
2
+ import { useRef as b, useMemo as g, useState as i, useCallback as o, useEffect as R } from "react";
3
+ const Fe = 25, ye = 50, N = 40, qe = 80, Ce = 8, Te = 6, pe = 2, Ue = 250, v = (r) => (r ?? "").normalize("NFD").replace(/[\u0300-\u036f]/g, "").trim().toLowerCase(), se = (r) => v(r).replace(/[^a-z0-9]+/g, ""), be = (r) => {
4
+ const u = se(r);
5
+ if (!u) return "";
6
+ const d = v(r).match(/^[a-z0-9]+/)?.[0] ?? "";
7
+ return /[^a-z0-9]/i.test(r ?? "") && d || u.slice(0, pe);
8
+ }, Ge = ({
9
+ requestName: r,
10
+ columns: u,
11
+ returnColumns: M = u,
12
+ parser: d,
13
+ value: z,
14
+ itemLabel: S,
15
+ filterField: k,
16
+ conditions: G = [],
17
+ orderBy: B = [],
18
+ onChange: oe,
19
+ initialPageSize: O = Fe,
20
+ pageSize: V = ye
21
+ }) => {
22
+ const K = b(null), P = b(null), Y = b(0), T = b(!1), re = b(
23
+ /* @__PURE__ */ new Map()
24
+ ), [ce] = De(r), f = g(
25
+ () => z ? S(z, -1) : "",
26
+ [S, z]
27
+ ), [p, W] = i(f), [n, x] = i(!1), [c, m] = i(!1), [h, _] = i(-1), [a, X] = i([]), [Z, $] = i(!1), [D, le] = i(!1), [Ie, ue] = i(0), [I, J] = i(null), F = g(() => !n || c ? "" : se(p), [p, n, c]), Q = g(
28
+ () => v(p).length === 0,
29
+ [p]
30
+ ), y = g(
31
+ () => !n || c ? "" : be(p),
32
+ [p, n, c]
33
+ ), ae = g(
34
+ () => JSON.stringify({
35
+ requestName: r,
36
+ columns: u,
37
+ returnColumns: M,
38
+ filterField: k,
39
+ conditions: G,
40
+ orderBy: B,
41
+ initialPageSize: O,
42
+ pageSize: V,
43
+ hasParser: !!d
44
+ }),
45
+ [
46
+ u,
47
+ G,
48
+ k,
49
+ O,
50
+ B,
51
+ V,
52
+ d,
53
+ r,
54
+ M
55
+ ]
56
+ ), w = g(
57
+ () => `${ae}::${y || "__all__"}`,
58
+ [ae, y]
59
+ ), s = g(() => c || !F ? a : a.filter(
60
+ (e, t) => se(S(e, t)).startsWith(
61
+ F
62
+ )
63
+ ), [S, F, a, c]), q = Math.max(
64
+ 0,
65
+ Math.floor(Ie / N) - Te
66
+ ), we = Ce + Te * 2, ee = Math.min(
67
+ s.length,
68
+ q + we
69
+ ), Ee = g(
70
+ () => s.slice(q, ee),
71
+ [s, ee, q]
72
+ ), Re = q * N, Se = (s.length - ee) * N, l = o(() => {
73
+ K.current !== null && (window.clearTimeout(K.current), K.current = null);
74
+ }, []);
75
+ R(
76
+ () => () => {
77
+ l();
78
+ },
79
+ [l]
80
+ ), R(() => {
81
+ n || (T.current = !1);
82
+ }, [n]), R(() => {
83
+ n || W(I ?? f);
84
+ }, [n, I, f]), R(() => {
85
+ I !== null && I === f && J(null);
86
+ }, [I, f]);
87
+ const C = o(() => {
88
+ P.current && (P.current.scrollTop = 0), ue(0);
89
+ }, []), A = o(() => {
90
+ x(!1), m(!1), _(-1), X([]), $(!1), C();
91
+ }, [C]), H = o(() => {
92
+ T.current = !1, J(null), W(f), A();
93
+ }, [A, f]), L = o(
94
+ async (e, t, U) => {
95
+ const ie = ++Y.current;
96
+ le(!0);
97
+ const fe = [...G];
98
+ y && fe.push({
99
+ field: k,
100
+ operator: "startsWith",
101
+ value: y
102
+ });
103
+ const Oe = (t ? O : V) + 1, Ve = {
104
+ columns: u,
105
+ returnColumns: M,
106
+ conditions: fe,
107
+ orderBy: B,
108
+ start: e,
109
+ length: Oe,
110
+ getCount: !1
111
+ };
112
+ try {
113
+ const xe = await ce(Ve);
114
+ if (Y.current !== ie) return;
115
+ const te = xe.data ?? [], he = t ? O : V, ne = te.length > he, ge = (ne ? te.slice(0, he) : te).map((j) => d ? d(j) : j);
116
+ X((j) => {
117
+ const de = t ? ge : [...j, ...ge];
118
+ return re.current.set(U, {
119
+ rows: de,
120
+ hasMore: ne
121
+ }), de;
122
+ }), $(ne);
123
+ } finally {
124
+ Y.current === ie && le(!1);
125
+ }
126
+ },
127
+ [
128
+ u,
129
+ G,
130
+ k,
131
+ O,
132
+ B,
133
+ V,
134
+ d,
135
+ M,
136
+ y,
137
+ ce
138
+ ]
139
+ );
140
+ R(() => {
141
+ if (!n) return;
142
+ const e = re.current.get(w);
143
+ if (e) {
144
+ X(e.rows), $(e.hasMore), _(-1), C();
145
+ return;
146
+ }
147
+ X([]), $(!1);
148
+ const t = window.setTimeout(
149
+ () => {
150
+ _(-1), C(), L(0, !0, w);
151
+ },
152
+ c ? 0 : 120
153
+ );
154
+ return () => {
155
+ window.clearTimeout(t);
156
+ };
157
+ }, [
158
+ L,
159
+ n,
160
+ w,
161
+ C,
162
+ c
163
+ ]), R(() => {
164
+ if (!n || h < 0) return;
165
+ const e = P.current;
166
+ if (!e) return;
167
+ const t = h * N, U = t + N;
168
+ t < e.scrollTop ? e.scrollTop = t : U > e.scrollTop + e.clientHeight && (e.scrollTop = U - e.clientHeight);
169
+ }, [h, n]);
170
+ const E = o(
171
+ (e) => {
172
+ const t = e ? S(e, -1) : "";
173
+ T.current = !0, l(), J(t), W(t), A(), oe?.(e);
174
+ },
175
+ [l, A, S, oe]
176
+ ), me = o(() => {
177
+ T.current = !1, l(), x(!0), m(!0);
178
+ }, [l]), _e = o(() => {
179
+ T.current = !1, l(), x(!0), m(!0);
180
+ }, [l]), Ae = o(() => {
181
+ if (l(), Q) {
182
+ E(null);
183
+ return;
184
+ }
185
+ if (T.current || I !== null) {
186
+ A();
187
+ return;
188
+ }
189
+ K.current = window.setTimeout(() => {
190
+ H();
191
+ }, 150);
192
+ }, [
193
+ l,
194
+ A,
195
+ Q,
196
+ I,
197
+ H,
198
+ E
199
+ ]), He = o((e) => {
200
+ T.current = !1, J(null), W(e), x(!0), m(!1), _(v(e).length === 0 ? -1 : 0);
201
+ }, []), Le = o(
202
+ (e) => {
203
+ if (e.key === "ArrowDown") {
204
+ e.preventDefault(), x(!0), m(!1), _(
205
+ (t) => Math.min(t + 1, s.length - 1)
206
+ );
207
+ return;
208
+ }
209
+ if (e.key === "ArrowUp") {
210
+ e.preventDefault(), m(!1), _((t) => Math.max(t - 1, 0));
211
+ return;
212
+ }
213
+ if (e.key === "Enter") {
214
+ if (e.preventDefault(), Q) {
215
+ E(null);
216
+ return;
217
+ }
218
+ if (h >= 0 && s[h]) {
219
+ E(s[h]);
220
+ return;
221
+ }
222
+ if (s.length === 1) {
223
+ E(s[0]);
224
+ return;
225
+ }
226
+ H();
227
+ return;
228
+ }
229
+ e.key === "Escape" && (e.preventDefault(), H());
230
+ },
231
+ [s, h, Q, H, E]
232
+ ), Me = o(
233
+ (e) => {
234
+ const t = e.currentTarget;
235
+ ue(t.scrollTop), t.scrollTop + t.clientHeight >= t.scrollHeight - qe && !D && Z && L(a.length, !1, w);
236
+ },
237
+ [Z, D, L, w, a.length]
238
+ );
239
+ return R(() => {
240
+ !n || c || !F || D || !Z || s.length > 0 || a.length === 0 || a.length >= Ue || L(a.length, !1, w);
241
+ }, [
242
+ s.length,
243
+ Z,
244
+ D,
245
+ L,
246
+ F,
247
+ n,
248
+ w,
249
+ a.length,
250
+ c
251
+ ]), {
252
+ bottomSpacerHeight: Se,
253
+ filteredRows: s,
254
+ handleBlur: Ae,
255
+ handleChange: He,
256
+ handleFocus: me,
257
+ handleKeyDown: Le,
258
+ handleOpenAllItems: _e,
259
+ handleSuggestionsScroll: Me,
260
+ inputValue: p,
261
+ isLoading: D,
262
+ opened: n,
263
+ highlightedIndex: h,
264
+ resetToSelectedValue: H,
265
+ selectedLabel: f,
266
+ selectItem: E,
267
+ suggestionsContainerRef: P,
268
+ topSpacerHeight: Re,
269
+ visibleRows: Ee,
270
+ visibleStartIndex: q
271
+ };
272
+ };
273
+ export {
274
+ Ge as useSqlPrefixFilterComboboxState
275
+ };
@@ -9,3 +9,4 @@ export * from './Form/styles';
9
9
  export * from './Form/Row';
10
10
  export * from './styles';
11
11
  export * from './NumberInput';
12
+ export * from './SqlPrefixFilterCombobox/SqlPrefixFilterCombobox';
@@ -1,37 +1,39 @@
1
1
  import { AutoTextArea as r } from "./AutoTextArea.js";
2
2
  import { BillitIdentifier as m } from "./BillitIdentifier/index.js";
3
3
  import { Button as p, StyledButton as x } from "./Button.js";
4
- import { Select as d } from "./Select.js";
5
- import { IconButton as i } from "./IconButton.js";
6
- import { IndeterminateCheckbox as f } from "./IndeterminateCheckbox.js";
4
+ import { Select as i } from "./Select.js";
5
+ import { IconButton as d } from "./IconButton.js";
6
+ import { IndeterminateCheckbox as u } from "./IndeterminateCheckbox.js";
7
7
  import { CardForm as C } from "./Form/index.js";
8
- import { FormCondensedFields as c, FormFields as y, FormGroupContainer as b, FormGroupHeader as s, FormRowContainer as I, FormRowLabel as B, ReadOnlyValue as R, StyledCheckbox as k, inputCss as w } from "./Form/styles.js";
8
+ import { FormCondensedFields as b, FormFields as c, FormGroupContainer as y, FormGroupHeader as s, FormRowContainer as I, FormRowLabel as B, ReadOnlyValue as R, StyledCheckbox as k, inputCss as w } from "./Form/styles.js";
9
9
  import { FormRow as h } from "./Form/Row.js";
10
- import { Input as L, StackedLabelContainer as N, StyledNumericFormat as T, StyledTextArea as H, inputStyle as O } from "./styles.js";
11
- import { NumberInput as g } from "./NumberInput.js";
10
+ import { Input as L, StackedLabelContainer as N, StyledNumericFormat as T, StyledTextArea as q, inputStyle as H } from "./styles.js";
11
+ import { NumberInput as P } from "./NumberInput.js";
12
+ import { SqlPrefixFilterCombobox as g } from "./SqlPrefixFilterCombobox/SqlPrefixFilterCombobox.js";
12
13
  export {
13
14
  r as AutoTextArea,
14
15
  m as BillitIdentifier,
15
16
  p as Button,
16
17
  C as CardForm,
17
- c as FormCondensedFields,
18
- y as FormFields,
19
- b as FormGroupContainer,
18
+ b as FormCondensedFields,
19
+ c as FormFields,
20
+ y as FormGroupContainer,
20
21
  s as FormGroupHeader,
21
22
  h as FormRow,
22
23
  I as FormRowContainer,
23
24
  B as FormRowLabel,
24
- i as IconButton,
25
- f as IndeterminateCheckbox,
25
+ d as IconButton,
26
+ u as IndeterminateCheckbox,
26
27
  L as Input,
27
- g as NumberInput,
28
+ P as NumberInput,
28
29
  R as ReadOnlyValue,
29
- d as Select,
30
+ i as Select,
31
+ g as SqlPrefixFilterCombobox,
30
32
  N as StackedLabelContainer,
31
33
  x as StyledButton,
32
34
  k as StyledCheckbox,
33
35
  T as StyledNumericFormat,
34
- H as StyledTextArea,
36
+ q as StyledTextArea,
35
37
  w as inputCss,
36
- O as inputStyle
38
+ H as inputStyle
37
39
  };
@@ -8,6 +8,7 @@ export * from './requests/tracking';
8
8
  export * from './requests/users';
9
9
  export * from './requests/userProfiles';
10
10
  export * from './types/auth';
11
+ export * from './types/audit';
11
12
  export * from './types/base';
12
13
  export * from './types/generic';
13
14
  export * from './types/tracking';
@@ -0,0 +1,13 @@
1
+ export type AuditLogSqlRow = {
2
+ Id: string;
3
+ CreatedAt: string;
4
+ Action: string;
5
+ EntityType: string;
6
+ EntityId: string | null;
7
+ RequestHandler: string | null;
8
+ Username: string | null;
9
+ DisplayName: string | null;
10
+ Success: boolean;
11
+ Message: string | null;
12
+ MetadataJson: string | null;
13
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@addev-be/ui",
3
- "version": "3.3.3",
3
+ "version": "3.4.0",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "watch": "vite build --watch",
@@ -74,7 +74,7 @@
74
74
  "update-version": "../../node/update-version.mjs"
75
75
  },
76
76
  "devDependencies": {
77
- "@addev-be/framework-utils": "^3.3.3",
77
+ "@addev-be/framework-utils": "^3.4.0",
78
78
  "@testing-library/dom": "^10.4.1",
79
79
  "@testing-library/react": "^16.3.0",
80
80
  "@testing-library/react-hooks": "^8.0.1",
@@ -114,5 +114,9 @@
114
114
  "tailwind-merge": "^3.5.0",
115
115
  "uuid": "^13.0.0",
116
116
  "zod": "^4.1.9"
117
+ },
118
+ "publishConfig": {
119
+ "registry": "https://registry.npmjs.org/",
120
+ "access": "public"
117
121
  }
118
122
  }