@edifice.io/react 2.5.10-develop-pedago.20260217101848 → 2.5.10-develop-pedago.20260217165027

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,8 +1,11 @@
1
1
  import { Attachment } from './models/attachment';
2
+ export type AttachmentType = Attachment;
3
+ export { useFileToAttachment } from './hooks/useFileToAttachment';
2
4
  export interface AddAttachmentsProps {
3
5
  attachments: Attachment[];
4
- onFilesSelected: (files: File[]) => void;
5
- onRemoveAttachment: (attachmentId: string) => void;
6
+ onChange?: (attachments: Attachment[]) => void;
7
+ onFilesSelected?: (files: File[]) => void;
8
+ onRemoveAttachment?: (attachmentId: string) => void;
6
9
  editMode?: boolean;
7
10
  isMutating?: boolean;
8
11
  onCopyToWorkspace?: (attachments: Attachment[], folderId: string) => Promise<boolean>;
@@ -12,7 +15,7 @@ export interface AddAttachmentsProps {
12
15
  downloadAllUrl?: string;
13
16
  }
14
17
  export declare const AddAttachments: {
15
- ({ attachments, onFilesSelected, onRemoveAttachment, editMode, isMutating, onCopyToWorkspace, getDownloadUrl, downloadAllUrl, }: AddAttachmentsProps): import("react/jsx-runtime").JSX.Element | null;
18
+ ({ attachments, onChange, onFilesSelected, onRemoveAttachment, editMode, isMutating, onCopyToWorkspace, getDownloadUrl, downloadAllUrl, }: AddAttachmentsProps): import("react/jsx-runtime").JSX.Element | null;
16
19
  displayName: string;
17
20
  };
18
21
  export default AddAttachments;
@@ -1,6 +1,6 @@
1
1
  import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
2
  import clsx from "clsx";
3
- import { useRef, useState, useEffect } from "react";
3
+ import { useRef, useState } from "react";
4
4
  import { useTranslation } from "react-i18next";
5
5
  import SvgIconDelete from "../../modules/icons/components/IconDelete.js";
6
6
  import SvgIconDownload from "../../modules/icons/components/IconDownload.js";
@@ -8,22 +8,13 @@ import SvgIconFolderAdd from "../../modules/icons/components/IconFolderAdd.js";
8
8
  import SvgIconPlus from "../../modules/icons/components/IconPlus.js";
9
9
  import { AddAttachmentToWorkspaceModal } from "./components/AddAttachmentToWorkspaceModal.js";
10
10
  import { SingleAttachment } from "./components/SingleAttachment.js";
11
+ import { useFileToAttachment } from "./hooks/useFileToAttachment.js";
11
12
  import Flex from "../Flex/Flex.js";
12
13
  import IconButton from "../Button/IconButton.js";
13
14
  import Button from "../Button/Button.js";
14
- function fileToAttachment(file) {
15
- return {
16
- id: `${file.name}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
17
- charset: "UTF-8",
18
- contentTransferEncoding: "binary",
19
- contentType: file.type || "application/octet-stream",
20
- filename: file.name,
21
- name: file.name,
22
- size: file.size
23
- };
24
- }
25
15
  const AddAttachments = ({
26
16
  attachments,
17
+ onChange,
27
18
  onFilesSelected,
28
19
  onRemoveAttachment,
29
20
  editMode = !1,
@@ -34,10 +25,8 @@ const AddAttachments = ({
34
25
  }) => {
35
26
  const {
36
27
  t
37
- } = useTranslation(), inputRef = useRef(null), [optimisticAttachments, setOptimisticAttachments] = useState([]), [attachmentsToAddToWorkspace, setAttachmentsToAddToWorkspace] = useState(void 0), prevAttachmentsLengthRef = useRef(attachments.length), displayedAttachments = [...attachments, ...optimisticAttachments];
38
- if (useEffect(() => {
39
- attachments.length > prevAttachmentsLengthRef.current && setOptimisticAttachments([]), prevAttachmentsLengthRef.current = attachments.length;
40
- }, [attachments.length]), !editMode && !displayedAttachments.length) return null;
28
+ } = useTranslation(), inputRef = useRef(null), fileToAttachment = useFileToAttachment(), [attachmentsToAddToWorkspace, setAttachmentsToAddToWorkspace] = useState(void 0);
29
+ if (!editMode && !attachments.length) return null;
41
30
  const resetInputValue = () => {
42
31
  inputRef.current && (inputRef.current.value = "");
43
32
  }, handleAttachClick = () => {
@@ -46,33 +35,31 @@ const AddAttachments = ({
46
35
  }, handleFileChange = (event) => {
47
36
  const files = Array.from(event.target.files ?? []);
48
37
  if (files.length > 0) {
49
- onFilesSelected(files);
50
- const newOptimistic = files.map(fileToAttachment);
51
- setOptimisticAttachments((prev) => [...prev, ...newOptimistic]);
38
+ const newAttachments = files.map(fileToAttachment);
39
+ onChange == null || onChange([...attachments, ...newAttachments]), onFilesSelected == null || onFilesSelected(files);
52
40
  }
53
41
  resetInputValue();
54
42
  }, handleDetachAllClick = () => {
55
- setOptimisticAttachments([]), attachments.forEach((attachment) => {
56
- onRemoveAttachment(attachment.id);
57
- }), resetInputValue();
43
+ onChange == null || onChange([]), attachments.forEach((a) => onRemoveAttachment == null ? void 0 : onRemoveAttachment(a.id)), resetInputValue();
58
44
  }, handleDetachClick = (attachmentId) => {
59
- optimisticAttachments.some((attachment) => attachment.id === attachmentId) ? setOptimisticAttachments((prev) => prev.filter((attachment) => attachment.id !== attachmentId)) : onRemoveAttachment(attachmentId), resetInputValue();
45
+ const next = attachments.filter((a) => a.id !== attachmentId);
46
+ onChange == null || onChange(next), onRemoveAttachment == null || onRemoveAttachment(attachmentId), resetInputValue();
60
47
  }, handleCopyToWorkspace = (attachments2) => {
61
48
  setAttachmentsToAddToWorkspace(attachments2);
62
49
  }, className = clsx("bg-gray-200 rounded px-12 py-8 message-attachments align-self-start gap-8 d-flex flex-column mw-100", {
63
50
  "border add-attachments-edit mx-16": editMode
64
51
  });
65
52
  return /* @__PURE__ */ jsxs("div", { className, "data-drag-handle": !0, children: [
66
- !!displayedAttachments.length && /* @__PURE__ */ jsxs(Fragment, { children: [
53
+ !!attachments.length && /* @__PURE__ */ jsxs(Fragment, { children: [
67
54
  /* @__PURE__ */ jsxs(Flex, { direction: "row", align: "center", justify: "between", className: "border-bottom", children: [
68
55
  /* @__PURE__ */ jsx("span", { className: "caption fw-bold my-8", children: t("attachments") }),
69
- displayedAttachments.length > 1 && /* @__PURE__ */ jsxs("div", { children: [
70
- onCopyToWorkspace && /* @__PURE__ */ jsx(IconButton, { title: t("conversation.copy.all.toworkspace"), color: "tertiary", type: "button", icon: /* @__PURE__ */ jsx(SvgIconFolderAdd, {}), onClick: () => handleCopyToWorkspace(displayedAttachments), variant: "ghost" }),
56
+ attachments.length > 1 && /* @__PURE__ */ jsxs("div", { children: [
57
+ onCopyToWorkspace && /* @__PURE__ */ jsx(IconButton, { title: t("conversation.copy.all.toworkspace"), color: "tertiary", type: "button", icon: /* @__PURE__ */ jsx(SvgIconFolderAdd, {}), onClick: () => handleCopyToWorkspace(attachments), variant: "ghost" }),
71
58
  downloadAllUrl && /* @__PURE__ */ jsx("a", { href: downloadAllUrl, download: !0, children: /* @__PURE__ */ jsx(IconButton, { title: t("download.all.attachment"), color: "tertiary", type: "button", icon: /* @__PURE__ */ jsx(SvgIconDownload, {}), variant: "ghost" }) }),
72
59
  editMode && /* @__PURE__ */ jsx(IconButton, { title: t("remove.all.attachment"), color: "danger", type: "button", icon: /* @__PURE__ */ jsx(SvgIconDelete, {}), variant: "ghost", onClick: handleDetachAllClick, disabled: isMutating })
73
60
  ] })
74
61
  ] }),
75
- /* @__PURE__ */ jsx("ul", { className: "d-flex gap-8 flex-column list-unstyled m-0", children: displayedAttachments.map((attachment) => /* @__PURE__ */ jsx("li", { className: "mw-100", children: /* @__PURE__ */ jsx(SingleAttachment, { attachment, editMode, onDelete: handleDetachClick, onCopyToWorkspace: onCopyToWorkspace ? (attachment2) => handleCopyToWorkspace([attachment2]) : void 0, getDownloadUrl, disabled: isMutating }) }, attachment.id)) })
62
+ /* @__PURE__ */ jsx("ul", { className: "d-flex gap-8 flex-column list-unstyled m-0", children: attachments.map((attachment) => /* @__PURE__ */ jsx("li", { className: "mw-100", children: /* @__PURE__ */ jsx(SingleAttachment, { attachment, editMode, onDelete: handleDetachClick, onCopyToWorkspace: onCopyToWorkspace ? (attachment2) => handleCopyToWorkspace([attachment2]) : void 0, getDownloadUrl, disabled: isMutating }) }, `${attachment.id}-${attachment.name}`)) })
76
63
  ] }),
77
64
  editMode && /* @__PURE__ */ jsxs(Fragment, { children: [
78
65
  /* @__PURE__ */ jsx(Button, { color: "secondary", variant: "ghost", isLoading: isMutating, onClick: handleAttachClick, disabled: isMutating, className: "align-self-start", leftIcon: /* @__PURE__ */ jsx(SvgIconPlus, {}), children: t("add.attachment") }),
@@ -83,5 +70,6 @@ const AddAttachments = ({
83
70
  };
84
71
  export {
85
72
  AddAttachments,
86
- AddAttachments as default
73
+ AddAttachments as default,
74
+ useFileToAttachment
87
75
  };
@@ -0,0 +1,3 @@
1
+ import { Attachment } from '../models/attachment';
2
+ /** Convertit un File en Attachment (id unique généré). Exposé pour les apps qui utilisent AddAttachments. */
3
+ export declare function useFileToAttachment(): (file: File) => Attachment;
@@ -0,0 +1,16 @@
1
+ import { useCallback } from "react";
2
+ function useFileToAttachment() {
3
+ return useCallback((file) => ({
4
+ id: `${file.name}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
5
+ charset: "UTF-8",
6
+ contentTransferEncoding: "binary",
7
+ contentType: file.type || "application/octet-stream",
8
+ filename: file.name,
9
+ name: file.name,
10
+ size: file.size,
11
+ file
12
+ }), []);
13
+ }
14
+ export {
15
+ useFileToAttachment
16
+ };
@@ -6,4 +6,5 @@ export type Attachment = {
6
6
  filename: string;
7
7
  name: string;
8
8
  size: number;
9
+ file: File;
9
10
  };
@@ -1,8 +1,7 @@
1
- import { default as UAParser } from 'ua-parser-js';
2
1
  export default function useBrowserInfo(userAgent?: string): {
3
- os: UAParser.IOS;
4
- device: UAParser.IDevice;
5
- browser: UAParser.IBrowser;
2
+ os: import('ua-parser-js').IOS;
3
+ device: import('ua-parser-js').IDevice;
4
+ browser: import('ua-parser-js').IBrowser;
6
5
  isIphone: boolean;
7
6
  isIpod: boolean;
8
7
  isIpad: boolean;
@@ -1,4 +1,4 @@
1
- import UAParser from "ua-parser-js";
1
+ import { UAParser } from "ua-parser-js";
2
2
  function useBrowserInfo(userAgent) {
3
3
  var _a, _b, _c;
4
4
  const uaParser = new UAParser(userAgent), os = uaParser.getOS(), device = uaParser.getDevice(), browser = uaParser.getBrowser(), isIphone = ((_a = device.model) == null ? void 0 : _a.indexOf("iPhone")) != -1, isIpod = ((_b = device.model) == null ? void 0 : _b.indexOf("iPod")) != -1, isIpad = ((_c = device.model) == null ? void 0 : _c.indexOf("iPad")) != -1;
package/dist/index.js CHANGED
@@ -141,6 +141,7 @@ import { mergeRefs, setRef } from "./utilities/refs/ref.js";
141
141
  import { useCheckable } from "./hooks/useCheckable/useCheckable.js";
142
142
  import { useEdificeClient } from "./providers/EdificeClientProvider/EdificeClientProvider.hook.js";
143
143
  import { useEdificeTheme } from "./providers/EdificeThemeProvider/EdificeThemeProvider.hook.js";
144
+ import { useFileToAttachment } from "./components/AddAttachments/hooks/useFileToAttachment.js";
144
145
  import { useTreeSortable } from "./components/Tree/hooks/useTreeSortable.js";
145
146
  import { useTreeView } from "./components/TreeView/hooks/useTreeView.js";
146
147
  export {
@@ -291,6 +292,7 @@ export {
291
292
  useEdificeClient,
292
293
  default85 as useEdificeIcons,
293
294
  useEdificeTheme,
295
+ useFileToAttachment,
294
296
  default86 as useHasWorkflow,
295
297
  default87 as useHover,
296
298
  default88 as useHttpErrorToast,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edifice.io/react",
3
- "version": "2.5.10-develop-pedago.20260217101848",
3
+ "version": "2.5.10-develop-pedago.20260217165027",
4
4
  "description": "Edifice React Library",
5
5
  "keywords": [
6
6
  "react",
@@ -135,9 +135,9 @@
135
135
  "swiper": "^10.1.0",
136
136
  "ua-parser-js": "^1.0.36",
137
137
  "react-pdf": "10.2.0",
138
- "@edifice.io/bootstrap": "2.5.10-develop-pedago.20260217101848",
139
- "@edifice.io/utilities": "2.5.10-develop-pedago.20260217101848",
140
- "@edifice.io/tiptap-extensions": "2.5.10-develop-pedago.20260217101848"
138
+ "@edifice.io/bootstrap": "2.5.10-develop-pedago.20260217165027",
139
+ "@edifice.io/utilities": "2.5.10-develop-pedago.20260217165027",
140
+ "@edifice.io/tiptap-extensions": "2.5.10-develop-pedago.20260217165027"
141
141
  },
142
142
  "devDependencies": {
143
143
  "@babel/plugin-transform-react-pure-annotations": "^7.23.3",
@@ -168,8 +168,8 @@
168
168
  "vite": "^5.4.11",
169
169
  "vite-plugin-dts": "^4.1.0",
170
170
  "vite-tsconfig-paths": "^5.0.1",
171
- "@edifice.io/client": "2.5.10-develop-pedago.20260217101848",
172
- "@edifice.io/config": "2.5.10-develop-pedago.20260217101848"
171
+ "@edifice.io/client": "2.5.10-develop-pedago.20260217165027",
172
+ "@edifice.io/config": "2.5.10-develop-pedago.20260217165027"
173
173
  },
174
174
  "peerDependencies": {
175
175
  "@react-spring/web": "^9.7.5",