@edifice.io/react 2.5.9-develop-pedago.20260213101441 → 2.5.9-develop-pedago.20260213112355

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.
@@ -11,4 +11,8 @@ export interface AddAttachmentsProps {
11
11
  /** Si fourni et qu'il y a plusieurs pièces jointes, affiche un bouton « télécharger tout ». */
12
12
  downloadAllUrl?: string;
13
13
  }
14
- export declare function AddAttachments({ attachments, onFilesSelected, onRemoveAttachment, editMode, isMutating, onCopyToWorkspace, getDownloadUrl, downloadAllUrl, }: AddAttachmentsProps): import("react/jsx-runtime").JSX.Element | null;
14
+ export declare const AddAttachments: {
15
+ ({ attachments, onFilesSelected, onRemoveAttachment, editMode, isMutating, onCopyToWorkspace, getDownloadUrl, downloadAllUrl, }: AddAttachmentsProps): import("react/jsx-runtime").JSX.Element | null;
16
+ displayName: string;
17
+ };
18
+ export default AddAttachments;
@@ -0,0 +1,87 @@
1
+ import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
+ import clsx from "clsx";
3
+ import { useRef, useState, useEffect } from "react";
4
+ import { useTranslation } from "react-i18next";
5
+ import SvgIconDelete from "../../modules/icons/components/IconDelete.js";
6
+ import SvgIconDownload from "../../modules/icons/components/IconDownload.js";
7
+ import SvgIconFolderAdd from "../../modules/icons/components/IconFolderAdd.js";
8
+ import SvgIconPlus from "../../modules/icons/components/IconPlus.js";
9
+ import { AddAttachmentToWorkspaceModal } from "./components/AddAttachmentToWorkspaceModal.js";
10
+ import { SingleAttachment } from "./components/SingleAttachment.js";
11
+ import Flex from "../Flex/Flex.js";
12
+ import IconButton from "../Button/IconButton.js";
13
+ 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
+ const AddAttachments = ({
26
+ attachments,
27
+ onFilesSelected,
28
+ onRemoveAttachment,
29
+ editMode = !1,
30
+ isMutating = !1,
31
+ onCopyToWorkspace,
32
+ getDownloadUrl,
33
+ downloadAllUrl
34
+ }) => {
35
+ const {
36
+ 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;
41
+ const resetInputValue = () => {
42
+ inputRef.current && (inputRef.current.value = "");
43
+ }, handleAttachClick = () => {
44
+ var _a;
45
+ return (_a = inputRef == null ? void 0 : inputRef.current) == null ? void 0 : _a.click();
46
+ }, handleFileChange = (event) => {
47
+ const files = Array.from(event.target.files ?? []);
48
+ if (files.length > 0) {
49
+ onFilesSelected(files);
50
+ const newOptimistic = files.map(fileToAttachment);
51
+ setOptimisticAttachments((prev) => [...prev, ...newOptimistic]);
52
+ }
53
+ resetInputValue();
54
+ }, handleDetachAllClick = () => {
55
+ setOptimisticAttachments([]), attachments.forEach((attachment) => {
56
+ onRemoveAttachment(attachment.id);
57
+ }), resetInputValue();
58
+ }, handleDetachClick = (attachmentId) => {
59
+ optimisticAttachments.some((attachment) => attachment.id === attachmentId) ? setOptimisticAttachments((prev) => prev.filter((attachment) => attachment.id !== attachmentId)) : onRemoveAttachment(attachmentId), resetInputValue();
60
+ }, handleCopyToWorkspace = (attachments2) => {
61
+ setAttachmentsToAddToWorkspace(attachments2);
62
+ }, className = clsx("bg-gray-200 rounded px-12 py-8 message-attachments align-self-start gap-8 d-flex flex-column mw-100", {
63
+ "border add-attachments-edit mx-16": editMode
64
+ });
65
+ return /* @__PURE__ */ jsxs("div", { className, "data-drag-handle": !0, children: [
66
+ !!displayedAttachments.length && /* @__PURE__ */ jsxs(Fragment, { children: [
67
+ /* @__PURE__ */ jsxs(Flex, { direction: "row", align: "center", justify: "between", className: "border-bottom", children: [
68
+ /* @__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" }),
71
+ 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
+ editMode && /* @__PURE__ */ jsx(IconButton, { title: t("remove.all.attachment"), color: "danger", type: "button", icon: /* @__PURE__ */ jsx(SvgIconDelete, {}), variant: "ghost", onClick: handleDetachAllClick, disabled: isMutating })
73
+ ] })
74
+ ] }),
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)) })
76
+ ] }),
77
+ editMode && /* @__PURE__ */ jsxs(Fragment, { children: [
78
+ /* @__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") }),
79
+ /* @__PURE__ */ jsx("input", { ref: inputRef, multiple: !0, type: "file", name: "attachment-input", id: "attachment-input", onChange: handleFileChange, hidden: !0 })
80
+ ] }),
81
+ onCopyToWorkspace && !!attachmentsToAddToWorkspace && /* @__PURE__ */ jsx(AddAttachmentToWorkspaceModal, { isOpen: !0, onModalClose: () => setAttachmentsToAddToWorkspace(void 0), attachments: attachmentsToAddToWorkspace, onCopyToWorkspace })
82
+ ] });
83
+ };
84
+ export {
85
+ AddAttachments,
86
+ AddAttachments as default
87
+ };
@@ -0,0 +1,41 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useState, useEffect } from "react";
3
+ import { createPortal } from "react-dom";
4
+ import { toast } from "react-hot-toast";
5
+ import { useTranslation } from "react-i18next";
6
+ import Modal from "../../Modal/Modal.js";
7
+ import WorkspaceFolders from "../../../modules/multimedia/WorkspaceFolders/WorkspaceFolders.js";
8
+ import Button from "../../Button/Button.js";
9
+ function AddAttachmentToWorkspaceModal({
10
+ attachments,
11
+ isOpen = !1,
12
+ onModalClose,
13
+ onCopyToWorkspace
14
+ }) {
15
+ const {
16
+ t
17
+ } = useTranslation(), [selectedFolderIdToCopyFile, setSelectedFolderIdToCopyFile] = useState(void 0), [isLoading, setIsLoading] = useState(!1), [disabled, setDisabled] = useState(!1), handleFolderSelected = (folderId, canCopyFileInto) => {
18
+ setSelectedFolderIdToCopyFile(canCopyFileInto ? folderId : void 0);
19
+ }, handleAddAttachmentToWorkspace = async () => {
20
+ if (selectedFolderIdToCopyFile === void 0) return;
21
+ setIsLoading(!0), await onCopyToWorkspace(attachments, selectedFolderIdToCopyFile) ? onModalClose() : toast.error(t("attachments.add.to.folder.modal.error")), setIsLoading(!1);
22
+ };
23
+ return useEffect(() => {
24
+ setDisabled(selectedFolderIdToCopyFile === void 0);
25
+ }, [selectedFolderIdToCopyFile]), /* @__PURE__ */ createPortal(/* @__PURE__ */ jsxs(Modal, { isOpen, onModalClose, id: "add-attachment-to-workspace-modal", size: "md", children: [
26
+ /* @__PURE__ */ jsx(Modal.Header, { onModalClose, children: t("attachments.add.to.folder.modal.title") }),
27
+ /* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsxs("div", { className: "d-flex flex-column gap-12", children: [
28
+ /* @__PURE__ */ jsx("p", { children: t("attachments.add.to.folder.modal.description", {
29
+ count: attachments.length
30
+ }) }),
31
+ /* @__PURE__ */ jsx(WorkspaceFolders, { onFolderSelected: handleFolderSelected })
32
+ ] }) }),
33
+ /* @__PURE__ */ jsxs(Modal.Footer, { children: [
34
+ /* @__PURE__ */ jsx(Button, { type: "button", color: "tertiary", variant: "ghost", onClick: onModalClose, children: t("attachments.add.to.folder.modal.cancel") }),
35
+ /* @__PURE__ */ jsx(Button, { color: "primary", variant: "filled", onClick: handleAddAttachmentToWorkspace, disabled: isLoading || disabled, isLoading, children: t("attachments.add.to.folder.modal.add") })
36
+ ] })
37
+ ] }), document.getElementById("portal"));
38
+ }
39
+ export {
40
+ AddAttachmentToWorkspaceModal
41
+ };
@@ -0,0 +1,27 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import SvgIconDelete from "../../../modules/icons/components/IconDelete.js";
3
+ import SvgIconDownload from "../../../modules/icons/components/IconDownload.js";
4
+ import SvgIconFolderAdd from "../../../modules/icons/components/IconFolderAdd.js";
5
+ import { useTranslation } from "react-i18next";
6
+ import Attachment from "../../Attachment/Attachment.js";
7
+ import IconButton from "../../Button/IconButton.js";
8
+ function SingleAttachment({
9
+ attachment,
10
+ onDelete,
11
+ editMode = !1,
12
+ onCopyToWorkspace,
13
+ getDownloadUrl,
14
+ disabled = !1
15
+ }) {
16
+ const {
17
+ t
18
+ } = useTranslation(), downloadUrl = getDownloadUrl == null ? void 0 : getDownloadUrl(attachment.id);
19
+ return /* @__PURE__ */ jsx(Attachment, { name: attachment.filename, options: /* @__PURE__ */ jsxs(Fragment, { children: [
20
+ onCopyToWorkspace && /* @__PURE__ */ jsx(IconButton, { title: t("conversation.copy.toworkspace"), color: "tertiary", type: "button", icon: /* @__PURE__ */ jsx(SvgIconFolderAdd, {}), variant: "ghost", onClick: () => onCopyToWorkspace(attachment), disabled }),
21
+ downloadUrl !== void 0 && /* @__PURE__ */ jsx("a", { href: downloadUrl, download: !0, children: /* @__PURE__ */ jsx(IconButton, { title: t("download.attachment"), color: "tertiary", type: "button", icon: /* @__PURE__ */ jsx(SvgIconDownload, {}), variant: "ghost", disabled }) }),
22
+ editMode && /* @__PURE__ */ jsx(IconButton, { title: t("remove.attachment"), color: "danger", type: "button", icon: /* @__PURE__ */ jsx(SvgIconDelete, {}), variant: "ghost", onClick: () => onDelete(attachment.id), disabled })
23
+ ] }) });
24
+ }
25
+ export {
26
+ SingleAttachment
27
+ };
@@ -0,0 +1,2 @@
1
+ export { default as AddAttachments } from './AddAttachments';
2
+ export * from './AddAttachments';
@@ -1,4 +1,5 @@
1
1
  export * from './ActionBar';
2
+ export * from './AddAttachments';
2
3
  export * from './Alert';
3
4
  export * from './AppHeader';
4
5
  export * from './AppIcon';
@@ -1,4 +1,4 @@
1
1
  import { App, IGetConf } from '@edifice.io/client';
2
2
  export default function useConf({ appCode }: {
3
3
  appCode: App;
4
- }): import('../../node_modules/@tanstack/react-query').UseQueryResult<IGetConf, Error>;
4
+ }): import('../../../node_modules/@tanstack/react-query').UseQueryResult<IGetConf, Error>;
@@ -1,2 +1,2 @@
1
1
  import { IGetSession } from '@edifice.io/client';
2
- export default function useSession(): import('../../node_modules/@tanstack/react-query').UseQueryResult<IGetSession, Error>;
2
+ export default function useSession(): import('../../../node_modules/@tanstack/react-query').UseQueryResult<IGetSession, Error>;
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { default as default2 } from "./components/ActionBar/ActionBar.js";
2
+ import { AddAttachments } from "./components/AddAttachments/AddAttachments.js";
2
3
  import { default as default3 } from "./components/Alert/Alert.js";
3
4
  import { default as default4 } from "./components/AppHeader/AppHeader.js";
4
5
  import { default as default5 } from "./components/AppIcon/AppIcon.js";
@@ -145,6 +146,7 @@ import { useTreeView } from "./components/TreeView/hooks/useTreeView.js";
145
146
  export {
146
147
  AccessiblePalette,
147
148
  default2 as ActionBar,
149
+ AddAttachments,
148
150
  default3 as Alert,
149
151
  AntProvider,
150
152
  default4 as AppHeader,
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { CreateParameters, CreateResult, ID, IFolder, UpdateParameters, UpdateResult } from '@edifice.io/client';
3
- import { UseMutationResult } from '../../../node_modules/@tanstack/react-query';
3
+ import { UseMutationResult } from '../../../../node_modules/@tanstack/react-query';
4
4
  export interface FormInputs {
5
5
  title: string;
6
6
  description: string;
@@ -1,5 +1,5 @@
1
1
  import { UpdateParameters, UpdateResult } from '@edifice.io/client';
2
- import { UseMutationOptions, UseMutationResult } from '../../../../node_modules/@tanstack/react-query';
2
+ import { UseMutationOptions, UseMutationResult } from '../../../../../node_modules/@tanstack/react-query';
3
3
  declare const useUpdateMutation: ({ application, options, }: {
4
4
  application: string;
5
5
  options?: UseMutationOptions<UpdateResult, Error, UpdateParameters>;
@@ -1,5 +1,5 @@
1
1
  import { ID, PutShareResponse, RightStringified, ShareRight, ShareRightAction, ShareRightActionDisplayName, ShareUrls } from '@edifice.io/client';
2
- import { UseMutationResult } from '../../../node_modules/@tanstack/react-query';
2
+ import { UseMutationResult } from '../../../../node_modules/@tanstack/react-query';
3
3
  /**
4
4
  * Configuration options for sharing a resource
5
5
  *
@@ -1,5 +1,5 @@
1
1
  import { ID, UpdateParameters, UpdateResult } from '@edifice.io/client';
2
- import { UseMutationResult } from '../../../../node_modules/@tanstack/react-query';
2
+ import { UseMutationResult } from '../../../../../node_modules/@tanstack/react-query';
3
3
  export type PublicationType = 'RESTRAINT' | 'IMMEDIATE' | undefined;
4
4
  export interface ShareBlogProps {
5
5
  resourceId: ID;
@@ -1,5 +1,5 @@
1
1
  import { PutShareResponse, ShareRight } from '@edifice.io/client';
2
- import { UseMutationOptions, UseMutationResult } from '../../../../node_modules/@tanstack/react-query';
2
+ import { UseMutationOptions, UseMutationResult } from '../../../../../node_modules/@tanstack/react-query';
3
3
  declare const useShareMutation: ({ application, options, }: {
4
4
  application: string;
5
5
  options?: UseMutationOptions<PutShareResponse, Error, {
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { App, IGetConf, IGetSession, IUserDescription, IUserInfo, IWebApp, UserProfile } from '@edifice.io/client';
3
- import { UseQueryResult } from '../../node_modules/@tanstack/react-query';
3
+ import { UseQueryResult } from '../../../node_modules/@tanstack/react-query';
4
4
  export interface EdificeClientParams {
5
5
  alternativeApp?: boolean;
6
6
  app: App;
@@ -0,0 +1,3 @@
1
+ export type CommonColor = 'black' | 'gray-800' | 'gray-700' | 'gray-600' | 'gray-500' | 'gray-400' | 'gray-300' | 'gray-200' | 'white' | 'danger' | 'warning' | 'success' | 'info' | 'danger-800' | 'warning-800' | 'success-800' | 'info-800' | 'danger-300' | 'warning-300' | 'success-300' | 'info-300' | 'danger-200' | 'warning-200' | 'success-200' | 'info-200' | 'accessible-blue' | 'accessible-deep-blue' | 'accessible-pink' | 'accessible-salamander' | 'accessible-sunshade' | 'accessible-yellow';
2
+ export type ThemeColor = 'primary' | 'primary-800' | 'primary-300' | 'primary-200' | 'secondary' | 'secondary-800' | 'secondary-300' | 'secondary-200';
3
+ export type Color = CommonColor | ThemeColor;
@@ -1,4 +1,4 @@
1
- import { InvalidateQueryFilters, QueryClient } from '../../node_modules/@tanstack/react-query';
1
+ import { InvalidateQueryFilters, QueryClient } from '../../../node_modules/@tanstack/react-query';
2
2
  /**
3
3
  * Invalidates queries and resets infinite query data to only contain the first page.
4
4
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edifice.io/react",
3
- "version": "2.5.9-develop-pedago.20260213101441",
3
+ "version": "2.5.9-develop-pedago.20260213112355",
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.9-develop-pedago.20260213101441",
139
- "@edifice.io/tiptap-extensions": "2.5.9-develop-pedago.20260213101441",
140
- "@edifice.io/utilities": "2.5.9-develop-pedago.20260213101441"
138
+ "@edifice.io/bootstrap": "2.5.9-develop-pedago.20260213112355",
139
+ "@edifice.io/utilities": "2.5.9-develop-pedago.20260213112355",
140
+ "@edifice.io/tiptap-extensions": "2.5.9-develop-pedago.20260213112355"
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.9-develop-pedago.20260213101441",
172
- "@edifice.io/config": "2.5.9-develop-pedago.20260213101441"
171
+ "@edifice.io/client": "2.5.9-develop-pedago.20260213112355",
172
+ "@edifice.io/config": "2.5.9-develop-pedago.20260213112355"
173
173
  },
174
174
  "peerDependencies": {
175
175
  "@react-spring/web": "^9.7.5",