@edifice.io/react 2.5.15-develop-b2school.20260327180304 → 2.5.15-develop.20260330155151

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 (77) hide show
  1. package/dist/components/AddAttachments/AddAttachments.d.ts +6 -3
  2. package/dist/components/AddAttachments/AddAttachments.js +17 -29
  3. package/dist/components/AddAttachments/hooks/useFileToAttachment.d.ts +3 -0
  4. package/dist/components/AddAttachments/hooks/useFileToAttachment.js +16 -0
  5. package/dist/components/AddAttachments/models/attachment.d.ts +1 -0
  6. package/dist/components/Tree/components/SortableTree.js +4 -3
  7. package/dist/components/Tree/components/Tree.js +4 -3
  8. package/dist/components/UserRightsList/SaveBookmark.d.ts +5 -0
  9. package/dist/components/UserRightsList/SaveBookmark.js +29 -0
  10. package/dist/components/UserRightsList/UserRightsBookmarkRow.d.ts +11 -0
  11. package/dist/components/UserRightsList/UserRightsBookmarkRow.js +30 -0
  12. package/dist/components/UserRightsList/UserRightsItem.d.ts +13 -0
  13. package/dist/components/UserRightsList/UserRightsItem.js +36 -0
  14. package/dist/components/UserRightsList/UserRightsList.d.ts +19 -0
  15. package/dist/components/UserRightsList/UserRightsList.js +94 -0
  16. package/dist/components/UserRightsList/helpers/rightsHelpers.d.ts +9 -0
  17. package/dist/components/UserRightsList/helpers/rightsHelpers.js +53 -0
  18. package/dist/components/UserRightsList/hooks/useBookmarkEntries.d.ts +19 -0
  19. package/dist/components/UserRightsList/hooks/useBookmarkEntries.js +58 -0
  20. package/dist/components/UserRightsList/hooks/useSharingItems.d.ts +20 -0
  21. package/dist/components/UserRightsList/hooks/useSharingItems.js +57 -0
  22. package/dist/components/UserRightsList/index.d.ts +2 -0
  23. package/dist/components/UserRightsList/types/types.d.ts +34 -0
  24. package/dist/components/UserRightsList/types/types.js +6 -0
  25. package/dist/components/UserSearch/UserSearch.d.ts +7 -0
  26. package/dist/components/UserSearch/UserSearch.js +82 -0
  27. package/dist/components/UserSearch/index.d.ts +3 -0
  28. package/dist/components/UserSearch/types/types.d.ts +24 -0
  29. package/dist/components/UserSearch/types/visible.d.ts +24 -0
  30. package/dist/components/UserSearch/types/visible.js +4 -0
  31. package/dist/components/index.d.ts +2 -0
  32. package/dist/hooks/useDirectory/useDirectory.d.ts +3 -2
  33. package/dist/hooks/useDropzone/useDropzone.js +4 -4
  34. package/dist/icons.js +364 -332
  35. package/dist/index.js +10 -0
  36. package/dist/modules/editor/components/EditorToolbar/EditorToolbar.js +1 -1
  37. package/dist/modules/icons/components/IconBulle.d.ts +7 -0
  38. package/dist/modules/icons/components/IconBulle.js +16 -0
  39. package/dist/modules/icons/components/IconBulleError.d.ts +7 -0
  40. package/dist/modules/icons/components/IconBulleError.js +13 -0
  41. package/dist/modules/icons/components/IconBulleSuccess.d.ts +7 -0
  42. package/dist/modules/icons/components/IconBulleSuccess.js +13 -0
  43. package/dist/modules/icons/components/IconLsuArt.d.ts +7 -0
  44. package/dist/modules/icons/components/IconLsuArt.js +13 -0
  45. package/dist/modules/icons/components/IconLsuCompetenceNumerique.d.ts +7 -0
  46. package/dist/modules/icons/components/IconLsuCompetenceNumerique.js +12 -0
  47. package/dist/modules/icons/components/IconLsuEmc.d.ts +7 -0
  48. package/dist/modules/icons/components/IconLsuEmc.js +13 -0
  49. package/dist/modules/icons/components/IconLsuFrancais.d.ts +7 -0
  50. package/dist/modules/icons/components/IconLsuFrancais.js +13 -0
  51. package/dist/modules/icons/components/IconLsuHistoireGeo.d.ts +7 -0
  52. package/dist/modules/icons/components/IconLsuHistoireGeo.js +12 -0
  53. package/dist/modules/icons/components/IconLsuLangue.d.ts +7 -0
  54. package/dist/modules/icons/components/IconLsuLangue.js +16 -0
  55. package/dist/modules/icons/components/IconLsuLangue2.d.ts +7 -0
  56. package/dist/modules/icons/components/IconLsuLangue2.js +13 -0
  57. package/dist/modules/icons/components/IconLsuMath.d.ts +7 -0
  58. package/dist/modules/icons/components/IconLsuMath.js +16 -0
  59. package/dist/modules/icons/components/IconLsuParcoursEducatif.d.ts +7 -0
  60. package/dist/modules/icons/components/IconLsuParcoursEducatif.js +12 -0
  61. package/dist/modules/icons/components/IconLsuSport.d.ts +7 -0
  62. package/dist/modules/icons/components/IconLsuSport.js +12 -0
  63. package/dist/modules/icons/components/IconLsuSvt.d.ts +7 -0
  64. package/dist/modules/icons/components/IconLsuSvt.js +12 -0
  65. package/dist/modules/icons/components/IconParcoursCitoyen.d.ts +7 -0
  66. package/dist/modules/icons/components/IconParcoursCitoyen.js +14 -0
  67. package/dist/modules/icons/components/IconParcoursSecours.d.ts +7 -0
  68. package/dist/modules/icons/components/IconParcoursSecours.js +14 -0
  69. package/dist/modules/icons/components/index.d.ts +16 -0
  70. package/dist/modules/modals/OnboardingModal/index.d.ts +1 -1
  71. package/dist/types/index.d.ts +1 -0
  72. package/dist/types/sharing.d.ts +8 -0
  73. package/dist/utilities/index.d.ts +1 -0
  74. package/dist/utilities/rotate-transition-style/get-rotate-transition-style.d.ts +5 -0
  75. package/dist/utilities/rotate-transition-style/get-rotate-transition-style.js +12 -0
  76. package/dist/utilities/rotate-transition-style/index.d.ts +1 -0
  77. package/package.json +7 -7
@@ -1,8 +1,11 @@
1
1
  import { Attachment } from './models/attachment';
2
+ export type SingleAttachmentType = 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,36 +35,34 @@ 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
- /* @__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") }),
65
+ /* @__PURE__ */ jsx(Button, { color: "secondary", variant: "ghost", isLoading: isMutating, onClick: handleAttachClick, disabled: isMutating, className: "align-self-start", leftIcon: /* @__PURE__ */ jsx(SvgIconPlus, {}), "data-testid": "common-add-attachments-button-add-attachment", children: t("add.attachment") }),
79
66
  /* @__PURE__ */ jsx("input", { ref: inputRef, multiple: !0, type: "file", name: "attachment-input", id: "attachment-input", onChange: handleFileChange, hidden: !0 })
80
67
  ] }),
81
68
  onCopyToWorkspace && !!attachmentsToAddToWorkspace && /* @__PURE__ */ jsx(AddAttachmentToWorkspaceModal, { isOpen: !0, onModalClose: () => setAttachmentsToAddToWorkspace(void 0), attachments: attachmentsToAddToWorkspace, onCopyToWorkspace })
@@ -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
  };
@@ -11,6 +11,7 @@ import SvgIconRafterRight from "../../../modules/icons/components/IconRafterRigh
11
11
  import { useTree } from "../hooks/useTree.js";
12
12
  import { useTreeSortable } from "../hooks/useTreeSortable.js";
13
13
  import { flattenNodes } from "../utilities/tree-sortable.js";
14
+ import { getRotateTransitionStyle } from "../../../utilities/rotate-transition-style/get-rotate-transition-style.js";
14
15
  import { mergeRefs } from "../../../utilities/refs/ref.js";
15
16
  const SortableTree = ({
16
17
  nodes,
@@ -113,9 +114,9 @@ const SortableTree = ({
113
114
  ...style,
114
115
  marginLeft: spaceGestion()
115
116
  }, ...listeners, children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs("div", { className: treeItemClasses.action, children: [
116
- node.haveChilds && /* @__PURE__ */ jsx("div", { tabIndex: 0, role: "button", onClick: () => onToggleNode == null ? void 0 : onToggleNode(node.id), onKeyDown: handleItemToggleKeyDown, "aria-label": t("foldUnfold"), children: /* @__PURE__ */ jsx(SvgIconRafterRight, { width: 16, style: {
117
- transform: expanded ? "rotate(90deg)" : ""
118
- } }) }),
117
+ node.haveChilds && /* @__PURE__ */ jsx("div", { tabIndex: 0, role: "button", onClick: () => onToggleNode == null ? void 0 : onToggleNode(node.id), onKeyDown: handleItemToggleKeyDown, "aria-label": t("foldUnfold"), children: /* @__PURE__ */ jsx(SvgIconRafterRight, { width: 16, style: getRotateTransitionStyle(expanded, {
118
+ degrees: 90
119
+ }) }) }),
119
120
  node.children && showIcon ? /* @__PURE__ */ jsx(SvgIconFolder, { title: "folder", width: 20, height: 20 }) : null,
120
121
  /* @__PURE__ */ jsx("div", { tabIndex: 0, role: "button", className: treeItemClasses.button, onClick: () => onTreeItemClick(node.id), onKeyDown: handleItemKeyDown, children: renderNode ? renderNode({
121
122
  node,
@@ -5,6 +5,7 @@ import { useTranslation } from "react-i18next";
5
5
  import SvgIconFolder from "../../../modules/icons/components/IconFolder.js";
6
6
  import SvgIconRafterRight from "../../../modules/icons/components/IconRafterRight.js";
7
7
  import { useTree } from "../hooks/useTree.js";
8
+ import { getRotateTransitionStyle } from "../../../utilities/rotate-transition-style/get-rotate-transition-style.js";
8
9
  const Tree = ({
9
10
  nodes,
10
11
  selectedNodeId: externalSelectedNodeId,
@@ -66,9 +67,9 @@ const Tree = ({
66
67
  };
67
68
  return /* @__PURE__ */ createElement("li", { ...restProps, ref, key: node.id, id: `treeitem-${node.id}`, role: "treeitem", "aria-selected": selected, "aria-expanded": expanded }, /* @__PURE__ */ jsxs("div", { children: [
68
69
  /* @__PURE__ */ jsxs("div", { className: treeItemClasses.action, children: [
69
- node.children && node.children.length > 0 ? /* @__PURE__ */ jsx("div", { className: treeItemClasses.arrow, tabIndex: 0, role: "button", onClick: () => onToggleNode == null ? void 0 : onToggleNode(node.id), onKeyDown: handleItemToggleKeyDown, "aria-label": t("foldUnfold"), children: /* @__PURE__ */ jsx(SvgIconRafterRight, { width: 16, style: {
70
- transform: expanded ? "rotate(90deg)" : ""
71
- } }) }) : /* @__PURE__ */ jsx("div", { className: "py-8 invisible" }),
70
+ node.children && node.children.length > 0 ? /* @__PURE__ */ jsx("div", { className: treeItemClasses.arrow, tabIndex: 0, role: "button", onClick: () => onToggleNode == null ? void 0 : onToggleNode(node.id), onKeyDown: handleItemToggleKeyDown, "aria-label": t("foldUnfold"), children: /* @__PURE__ */ jsx(SvgIconRafterRight, { width: 16, style: getRotateTransitionStyle(expanded, {
71
+ degrees: 90
72
+ }) }) }) : /* @__PURE__ */ jsx("div", { className: "py-8 invisible" }),
72
73
  node.children && showIcon ? /* @__PURE__ */ jsx(SvgIconFolder, { title: "folder", width: 20, height: 20 }) : null,
73
74
  /* @__PURE__ */ jsx("div", { tabIndex: 0, role: "button", className: treeItemClasses.button, onClick: () => onTreeItemClick(node.id), onKeyDown: handleItemKeyDown, children: renderNode ? renderNode({
74
75
  node,
@@ -0,0 +1,5 @@
1
+ interface SaveBookmarkProps {
2
+ onSave: (bookmarkName: string) => Promise<void>;
3
+ }
4
+ export declare const SaveBookmark: ({ onSave }: SaveBookmarkProps) => import("react/jsx-runtime").JSX.Element;
5
+ export {};
@@ -0,0 +1,29 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { useTranslation } from "react-i18next";
4
+ import SvgIconSave from "../../modules/icons/components/IconSave.js";
5
+ import FormControl from "../Form/FormControl.js";
6
+ import Button from "../Button/Button.js";
7
+ const SaveBookmark = ({
8
+ onSave
9
+ }) => {
10
+ const [bookmarkName, setBookmarkName] = useState(""), [isSaving, setIsSaving] = useState(!1), {
11
+ t
12
+ } = useTranslation(), handleBookmarkNameChange = (e) => {
13
+ setBookmarkName(e.target.value);
14
+ }, handleSaveClick = async () => {
15
+ setIsSaving(!0);
16
+ try {
17
+ await onSave(bookmarkName), setBookmarkName("");
18
+ } finally {
19
+ setIsSaving(!1);
20
+ }
21
+ };
22
+ return /* @__PURE__ */ jsx("div", { className: "mt-16", children: /* @__PURE__ */ jsxs(FormControl, { id: "bookmarkName", className: "d-flex flex-wrap align-items-center gap-16", children: [
23
+ /* @__PURE__ */ jsx("div", { className: "flex-fill", children: /* @__PURE__ */ jsx(FormControl.Input, { "data-testid": "common-save-bookmark-name-input", value: bookmarkName, onChange: handleBookmarkNameChange, placeholder: t("explorer.modal.share.sharebookmark.placeholder"), size: "sm", type: "text" }) }),
24
+ /* @__PURE__ */ jsx(Button, { "data-testid": "common-save-bookmark-save-button", color: "primary", variant: "ghost", disabled: bookmarkName.length === 0 || isSaving, leftIcon: /* @__PURE__ */ jsx(SvgIconSave, {}), onClick: handleSaveClick, className: "text-nowrap", isLoading: isSaving, children: t("explorer.modal.share.sharebookmark.save") })
25
+ ] }) });
26
+ };
27
+ export {
28
+ SaveBookmark
29
+ };
@@ -0,0 +1,11 @@
1
+ import { BookmarkState, ResourceRightName, ResourceRights } from './types/types';
2
+ interface UserRightsBookmarkRowProps {
3
+ bookmark: BookmarkState;
4
+ resourceRights: ResourceRights;
5
+ isReadOnly: boolean;
6
+ onToggleRight: (bookmarkId: string, rightName: ResourceRightName) => void;
7
+ onDelete: (bookmarkId: string) => void;
8
+ onToggleExpand: (bookmarkId: string) => void;
9
+ }
10
+ declare const UserRightsBookmarkRow: ({ bookmark, resourceRights, isReadOnly, onToggleRight, onDelete, onToggleExpand, }: UserRightsBookmarkRowProps) => import("react/jsx-runtime").JSX.Element;
11
+ export default UserRightsBookmarkRow;
@@ -0,0 +1,30 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useTranslation } from "react-i18next";
3
+ import SvgIconBookmark from "../../modules/icons/components/IconBookmark.js";
4
+ import SvgIconClose from "../../modules/icons/components/IconClose.js";
5
+ import SvgIconRafterDown from "../../modules/icons/components/IconRafterDown.js";
6
+ import Button from "../Button/Button.js";
7
+ import Checkbox from "../Checkbox/Checkbox.js";
8
+ import IconButton from "../Button/IconButton.js";
9
+ import { getRotateTransitionStyle } from "../../utilities/rotate-transition-style/get-rotate-transition-style.js";
10
+ const UserRightsBookmarkRow = ({
11
+ bookmark,
12
+ resourceRights,
13
+ isReadOnly,
14
+ onToggleRight,
15
+ onDelete,
16
+ onToggleExpand
17
+ }) => {
18
+ const {
19
+ t
20
+ } = useTranslation();
21
+ return /* @__PURE__ */ jsxs("tr", { "data-testid": "user-rights-list-bookmark-row", children: [
22
+ /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(SvgIconBookmark, {}) }),
23
+ /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(Button, { color: "tertiary", variant: "ghost", className: "fw-normal ps-0", "aria-expanded": bookmark.isExpanded, rightIcon: /* @__PURE__ */ jsx(SvgIconRafterDown, { title: bookmark.isExpanded ? t("hide") : t("show"), className: "w-16 min-w-0", style: getRotateTransitionStyle(bookmark.isExpanded) }), onClick: () => onToggleExpand(bookmark.id), children: bookmark.name }) }),
24
+ Object.entries(resourceRights).map(([rightName]) => /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(Checkbox, { checked: bookmark.permission.includes(rightName), onChange: () => onToggleRight(bookmark.id, rightName), disabled: isReadOnly, "aria-label": `${bookmark.name} - ${rightName}`, "data-testid": `user-rights-list-bookmark-${rightName}-checkbox` }) }, rightName)),
25
+ /* @__PURE__ */ jsx("td", { children: !isReadOnly && /* @__PURE__ */ jsx(IconButton, { "data-testid": "user-rights-list-bookmark-close-button", color: "tertiary", onClick: () => onDelete(bookmark.id), icon: /* @__PURE__ */ jsx(SvgIconClose, {}), title: `${t("close")} ${bookmark.name}`, variant: "ghost" }) })
26
+ ] });
27
+ };
28
+ export {
29
+ UserRightsBookmarkRow as default
30
+ };
@@ -0,0 +1,13 @@
1
+ import { ResourceRightName, ResourceRights, SharingItem } from './types/types';
2
+ interface UserRightsItemProps {
3
+ item: SharingItem;
4
+ resourceRights: ResourceRights;
5
+ isReadOnly: boolean;
6
+ isDeletable?: boolean;
7
+ rowClassName?: string;
8
+ bookmarkName?: string;
9
+ onChange?: (item: SharingItem, rightName: ResourceRightName) => void;
10
+ onDeleteItem?: (item: SharingItem) => void;
11
+ }
12
+ declare const UserRightsItem: ({ item, resourceRights, isReadOnly, isDeletable, rowClassName, bookmarkName, onChange, onDeleteItem, }: UserRightsItemProps) => import("react/jsx-runtime").JSX.Element;
13
+ export default UserRightsItem;
@@ -0,0 +1,36 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useTranslation } from "react-i18next";
3
+ import SvgIconClose from "../../modules/icons/components/IconClose.js";
4
+ import useDirectory from "../../hooks/useDirectory/useDirectory.js";
5
+ import Avatar from "../Avatar/Avatar.js";
6
+ import Checkbox from "../Checkbox/Checkbox.js";
7
+ import IconButton from "../Button/IconButton.js";
8
+ const UserRightsItem = ({
9
+ item,
10
+ resourceRights,
11
+ isReadOnly,
12
+ isDeletable = !0,
13
+ rowClassName,
14
+ bookmarkName,
15
+ onChange,
16
+ onDeleteItem
17
+ }) => {
18
+ const {
19
+ getAvatarURL
20
+ } = useDirectory(), {
21
+ t
22
+ } = useTranslation(), handleChange = (rightName) => {
23
+ onChange == null || onChange(item, rightName);
24
+ }, handleDeleteItem = () => {
25
+ onDeleteItem == null || onDeleteItem(item);
26
+ };
27
+ return /* @__PURE__ */ jsxs("tr", { "data-testid": "user-rights-list-item-row", className: rowClassName, "aria-label": bookmarkName ? `${item.displayName} - ${bookmarkName}` : void 0, children: [
28
+ /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(Avatar, { src: getAvatarURL(item.recipientId, item.recipientType), size: "xs", alt: item.displayName, variant: "circle" }) }),
29
+ /* @__PURE__ */ jsx("td", { children: item.displayName }),
30
+ Object.entries(resourceRights).map(([rightName]) => /* @__PURE__ */ jsx("td", { "data-testid": `user-rights-list-item-${rightName}-checkbox`, children: /* @__PURE__ */ jsx(Checkbox, { checked: item.permission.includes(rightName), onChange: () => handleChange(rightName), disabled: isReadOnly, "aria-label": `${item.displayName} - ${rightName}` }) }, rightName)),
31
+ /* @__PURE__ */ jsx("td", { children: !isReadOnly && isDeletable && /* @__PURE__ */ jsx(IconButton, { "data-testid": "user-rights-list-close-button", color: "tertiary", onClick: () => handleDeleteItem(), icon: /* @__PURE__ */ jsx(SvgIconClose, {}), title: `${t("close")} ${item.displayName}`, variant: "ghost", type: "button" }) })
32
+ ] });
33
+ };
34
+ export {
35
+ UserRightsItem as default
36
+ };
@@ -0,0 +1,19 @@
1
+ import { SharingItem } from '../../types';
2
+ import { BookmarkInput, ResourceRights } from './types/types';
3
+ interface UserRightsListProps {
4
+ resourceRights: ResourceRights;
5
+ isReadOnly: boolean;
6
+ isLoading: boolean;
7
+ ownerId: string;
8
+ isCreating: boolean;
9
+ initialSharings?: SharingItem[];
10
+ onChange: (value: SharingItem[]) => void;
11
+ onAddItems: (value: SharingItem[]) => void;
12
+ onDeleteItems: (value: SharingItem[]) => void;
13
+ onSaveBookmark?: (bookmarkName: string, items: SharingItem[]) => Promise<void>;
14
+ }
15
+ export interface UserRightsListRef {
16
+ addItem: (item: SharingItem | BookmarkInput) => void;
17
+ }
18
+ export declare const UserRightsList: import('react').ForwardRefExoticComponent<UserRightsListProps & import('react').RefAttributes<UserRightsListRef>>;
19
+ export {};
@@ -0,0 +1,94 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { forwardRef, useState, useRef, useMemo, useImperativeHandle, Fragment as Fragment$1 } from "react";
3
+ import { useTranslation } from "react-i18next";
4
+ import SvgIconBookmark from "../../modules/icons/components/IconBookmark.js";
5
+ import SvgIconRafterDown from "../../modules/icons/components/IconRafterDown.js";
6
+ import { createRightsHelpers } from "./helpers/rightsHelpers.js";
7
+ import { useBookmarkEntries } from "./hooks/useBookmarkEntries.js";
8
+ import { useSharingItems } from "./hooks/useSharingItems.js";
9
+ import { SaveBookmark } from "./SaveBookmark.js";
10
+ import { isBookmarkInput } from "./types/types.js";
11
+ import UserRightsBookmarkRow from "./UserRightsBookmarkRow.js";
12
+ import UserRightsItem from "./UserRightsItem.js";
13
+ import { useEdificeClient } from "../../providers/EdificeClientProvider/EdificeClientProvider.hook.js";
14
+ import LoadingScreen from "../LoadingScreen/LoadingScreen.js";
15
+ import VisuallyHidden from "../VisuallyHidden/VisuallyHidden.js";
16
+ import Button from "../Button/Button.js";
17
+ import { getRotateTransitionStyle } from "../../utilities/rotate-transition-style/get-rotate-transition-style.js";
18
+ const UserRightsList = /* @__PURE__ */ forwardRef(({
19
+ resourceRights,
20
+ isReadOnly = !0,
21
+ isLoading = !1,
22
+ ownerId,
23
+ isCreating = !1,
24
+ initialSharings = [],
25
+ onChange,
26
+ onAddItems,
27
+ onDeleteItems,
28
+ onSaveBookmark
29
+ }, ref) => {
30
+ const [showBookmarkInput, setBookmarkInput] = useState(!1), tableRef = useRef(null), {
31
+ t
32
+ } = useTranslation(), {
33
+ user
34
+ } = useEdificeClient(), {
35
+ applyRight,
36
+ toggleRight,
37
+ getOwnerItem
38
+ } = useMemo(() => createRightsHelpers(resourceRights), [resourceRights]), ownerItem = getOwnerItem(ownerId, user, isCreating), sharingItems = useSharingItems({
39
+ initialSharings,
40
+ toggleRight,
41
+ applyRight,
42
+ onChange,
43
+ onAddItems,
44
+ onDeleteItems
45
+ }), itemsByRecipientId = useMemo(() => new Map(sharingItems.items.map((item) => [item.recipientId, item])), [sharingItems.items]), existingRecipientIds = useMemo(() => new Set(itemsByRecipientId.keys()), [itemsByRecipientId]), bookmarks = useBookmarkEntries({
46
+ resourceRights,
47
+ existingRecipientIds,
48
+ toggleRight,
49
+ addItems: sharingItems.addItems,
50
+ deleteItemsByIds: sharingItems.deleteItemsByIds,
51
+ applyRightToIds: sharingItems.applyRightToIds
52
+ }), regularItems = useMemo(() => sharingItems.items.filter((item) => !bookmarks.bookmarkUserIds.has(item.recipientId)), [sharingItems.items, bookmarks.bookmarkUserIds]), focusTable = () => {
53
+ var _a;
54
+ (_a = tableRef.current) == null || _a.focus();
55
+ }, handleAddItem = (item) => {
56
+ isBookmarkInput(item) ? bookmarks.addBookmark(item) : sharingItems.addItem(item);
57
+ }, handleDeleteItem = (item) => {
58
+ sharingItems.deleteItem(item), focusTable();
59
+ }, handleDeleteBookmark = (bookmarkId) => {
60
+ bookmarks.deleteBookmark(bookmarkId), focusTable();
61
+ }, handleOnSaveBookmark = (bookmarkName) => onSaveBookmark ? onSaveBookmark(bookmarkName, sharingItems.items) : Promise.resolve(), toggleBookmarkInput = () => {
62
+ setBookmarkInput((prev) => !prev);
63
+ };
64
+ return useImperativeHandle(ref, () => ({
65
+ addItem: handleAddItem
66
+ })), /* @__PURE__ */ jsx("div", { className: "user-rights-list", children: isLoading ? /* @__PURE__ */ jsx(LoadingScreen, {}) : /* @__PURE__ */ jsxs(Fragment, { children: [
67
+ /* @__PURE__ */ jsx("div", { className: "table-responsive", children: /* @__PURE__ */ jsxs("table", { ref: tableRef, tabIndex: -1, className: "table border align-middle", children: [
68
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
69
+ /* @__PURE__ */ jsx("th", { scope: "col", className: "w-32", children: /* @__PURE__ */ jsx(VisuallyHidden, { children: t("explorer.modal.share.avatar.shared.alt") }) }),
70
+ /* @__PURE__ */ jsx("th", { scope: "col", children: /* @__PURE__ */ jsx(VisuallyHidden, { children: t("explorer.modal.share.search.placeholder") }) }),
71
+ Object.entries(resourceRights).map(([rightName]) => /* @__PURE__ */ jsx("th", { children: rightName }, rightName)),
72
+ !isReadOnly && /* @__PURE__ */ jsx("th", { scope: "col", children: /* @__PURE__ */ jsx(VisuallyHidden, { children: t("close") }) })
73
+ ] }) }),
74
+ /* @__PURE__ */ jsxs("tbody", { children: [
75
+ /* @__PURE__ */ jsx(UserRightsItem, { item: ownerItem, resourceRights, isReadOnly: !0 }, ownerItem == null ? void 0 : ownerItem.recipientId),
76
+ bookmarks.bookmarkEntries.map((bookmark) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
77
+ /* @__PURE__ */ jsx(UserRightsBookmarkRow, { bookmark, resourceRights, isReadOnly, onToggleRight: bookmarks.toggleBookmarkRight, onDelete: handleDeleteBookmark, onToggleExpand: bookmarks.toggleExpand }),
78
+ bookmark.isExpanded && bookmark.userIds.map((userId) => {
79
+ const item = itemsByRecipientId.get(userId);
80
+ return item ? /* @__PURE__ */ jsx(UserRightsItem, { item, resourceRights, isReadOnly, isDeletable: !1, rowClassName: "bg-light", bookmarkName: bookmark.name, onChange: sharingItems.changeRight }, item.recipientId) : null;
81
+ })
82
+ ] }, bookmark.id)),
83
+ regularItems.map((item) => /* @__PURE__ */ jsx(UserRightsItem, { item, resourceRights, isReadOnly: isReadOnly || (ownerItem == null ? void 0 : ownerItem.recipientId) === item.recipientId, onChange: sharingItems.changeRight, onDeleteItem: handleDeleteItem }, item.recipientId))
84
+ ] })
85
+ ] }) }),
86
+ onSaveBookmark && /* @__PURE__ */ jsxs("div", { className: "mt-16", children: [
87
+ /* @__PURE__ */ jsx(Button, { "data-testid": "common-user-rights-list-share-bookmark-show-button", color: "tertiary", leftIcon: /* @__PURE__ */ jsx(SvgIconBookmark, {}), rightIcon: /* @__PURE__ */ jsx(SvgIconRafterDown, { title: t("show"), className: "w-16 min-w-0", style: getRotateTransitionStyle(showBookmarkInput) }), type: "button", variant: "ghost", className: "fw-normal", onClick: () => toggleBookmarkInput(), children: t("share.save.sharebookmark") }),
88
+ showBookmarkInput && /* @__PURE__ */ jsx(SaveBookmark, { onSave: handleOnSaveBookmark })
89
+ ] })
90
+ ] }) });
91
+ });
92
+ export {
93
+ UserRightsList
94
+ };
@@ -0,0 +1,9 @@
1
+ import { IUserInfo } from '@edifice.io/client';
2
+ import { SharingItem } from '../../../types';
3
+ import { ResourceRightName, ResourceRights } from '../types/types';
4
+ export declare const createRightsHelpers: (resourceRights: ResourceRights) => {
5
+ applyRight: (item: SharingItem, rightName: ResourceRightName, add: boolean) => SharingItem;
6
+ toggleRight: (item: SharingItem, rightName: ResourceRightName) => SharingItem;
7
+ createOwnerItem: (user: IUserInfo) => SharingItem;
8
+ getOwnerItem: (ownerId: string, user: IUserInfo | undefined, isCreating: boolean) => SharingItem;
9
+ };
@@ -0,0 +1,53 @@
1
+ const createRightsHelpers = (resourceRights) => {
2
+ const getOwnerItem = (ownerId, user, isCreating) => {
3
+ if (!ownerId && user && isCreating || user && ownerId === user.userId)
4
+ return createOwnerItem(user);
5
+ if (!ownerId)
6
+ throw new Error("Owner ID or user is required");
7
+ return {
8
+ recipientId: ownerId,
9
+ recipientType: "user",
10
+ displayName: "owner",
11
+ permission: Object.keys(resourceRights)
12
+ };
13
+ }, createOwnerItem = (user) => ({
14
+ recipientId: user.userId ?? "",
15
+ recipientType: "user",
16
+ displayName: user.username,
17
+ permission: Object.keys(resourceRights)
18
+ }), applyRight = (item, rightName, add) => {
19
+ const {
20
+ requires,
21
+ excludes
22
+ } = resourceRights[rightName];
23
+ let newPermission;
24
+ if (add)
25
+ newPermission = [.../* @__PURE__ */ new Set([...item.permission.filter((perm) => !excludes.includes(perm)), ...requires, rightName])];
26
+ else {
27
+ const toRemove = /* @__PURE__ */ new Set([rightName]);
28
+ let changed = !0;
29
+ for (; changed; ) {
30
+ changed = !1;
31
+ for (const [name, definition] of Object.entries(resourceRights))
32
+ !toRemove.has(name) && definition.requires.some((required) => toRemove.has(required)) && (toRemove.add(name), changed = !0);
33
+ }
34
+ newPermission = item.permission.filter((perm) => !toRemove.has(perm));
35
+ }
36
+ return {
37
+ ...item,
38
+ permission: newPermission
39
+ };
40
+ };
41
+ return {
42
+ applyRight,
43
+ toggleRight: (item, rightName) => {
44
+ const hasRight = item.permission.includes(rightName);
45
+ return applyRight(item, rightName, !hasRight);
46
+ },
47
+ createOwnerItem,
48
+ getOwnerItem
49
+ };
50
+ };
51
+ export {
52
+ createRightsHelpers
53
+ };
@@ -0,0 +1,19 @@
1
+ import { SharingItem } from '../../../types';
2
+ import { BookmarkInput, BookmarkState, ResourceRightName, ResourceRights } from '../types/types';
3
+ interface UseBookmarkEntriesParams {
4
+ resourceRights: ResourceRights;
5
+ existingRecipientIds: Set<string>;
6
+ toggleRight: (item: SharingItem, rightName: ResourceRightName) => SharingItem;
7
+ addItems: (items: SharingItem[]) => void;
8
+ deleteItemsByIds: (ids: Set<string>) => void;
9
+ applyRightToIds: (ids: Set<string>, rightName: ResourceRightName, shouldAdd: boolean) => void;
10
+ }
11
+ export declare const useBookmarkEntries: ({ resourceRights, existingRecipientIds, toggleRight, addItems, deleteItemsByIds, applyRightToIds, }: UseBookmarkEntriesParams) => {
12
+ bookmarkEntries: BookmarkState[];
13
+ bookmarkUserIds: Set<string>;
14
+ addBookmark: (bookmark: BookmarkInput) => void;
15
+ deleteBookmark: (bookmarkId: string) => void;
16
+ toggleBookmarkRight: (bookmarkId: string, rightName: ResourceRightName) => void;
17
+ toggleExpand: (bookmarkId: string) => void;
18
+ };
19
+ export {};
@@ -0,0 +1,58 @@
1
+ import { useState, useMemo } from "react";
2
+ const useBookmarkEntries = ({
3
+ resourceRights,
4
+ existingRecipientIds,
5
+ toggleRight,
6
+ addItems,
7
+ deleteItemsByIds,
8
+ applyRightToIds
9
+ }) => {
10
+ const [bookmarkEntries, setBookmarkEntries] = useState([]), bookmarkUserIds = useMemo(() => new Set(bookmarkEntries.flatMap((entry) => entry.userIds)), [bookmarkEntries]), getDefaultPermissions = () => Object.entries(resourceRights).filter(([, definition]) => definition.default).map(([name]) => name);
11
+ return {
12
+ bookmarkEntries,
13
+ bookmarkUserIds,
14
+ addBookmark: (bookmark) => {
15
+ if (bookmarkEntries.some((entry) => entry.id === bookmark.id)) return;
16
+ const defaultPermissions = getDefaultPermissions(), newBookmarkUsers = bookmark.users.filter((bookmarkUser) => !existingRecipientIds.has(bookmarkUser.id)), newUsers = newBookmarkUsers.map((bookmarkUser) => ({
17
+ recipientId: bookmarkUser.id,
18
+ recipientType: "user",
19
+ displayName: bookmarkUser.displayName,
20
+ permission: [...defaultPermissions]
21
+ })), bookmarkState = {
22
+ id: bookmark.id,
23
+ name: bookmark.name,
24
+ permission: [...defaultPermissions],
25
+ userIds: newBookmarkUsers.map((bookmarkUser) => bookmarkUser.id),
26
+ isExpanded: !1
27
+ };
28
+ setBookmarkEntries((prev) => [...prev, bookmarkState]), addItems(newUsers);
29
+ },
30
+ deleteBookmark: (bookmarkId) => {
31
+ const bookmark = bookmarkEntries.find((entry) => entry.id === bookmarkId);
32
+ bookmark && (setBookmarkEntries((prev) => prev.filter((entry) => entry.id !== bookmarkId)), deleteItemsByIds(new Set(bookmark.userIds)));
33
+ },
34
+ toggleBookmarkRight: (bookmarkId, rightName) => {
35
+ const bookmark = bookmarkEntries.find((entry) => entry.id === bookmarkId);
36
+ if (!bookmark) return;
37
+ const shouldAdd = !bookmark.permission.includes(rightName), bookmarkAsSharingItem = {
38
+ recipientId: bookmark.id,
39
+ recipientType: "bookmark",
40
+ displayName: bookmark.name,
41
+ permission: bookmark.permission
42
+ }, toggledBookmark = toggleRight(bookmarkAsSharingItem, rightName);
43
+ setBookmarkEntries((prev) => prev.map((entry) => entry.id === bookmarkId ? {
44
+ ...entry,
45
+ permission: toggledBookmark.permission
46
+ } : entry)), applyRightToIds(new Set(bookmark.userIds), rightName, shouldAdd);
47
+ },
48
+ toggleExpand: (bookmarkId) => {
49
+ setBookmarkEntries((prev) => prev.map((entry) => entry.id === bookmarkId ? {
50
+ ...entry,
51
+ isExpanded: !entry.isExpanded
52
+ } : entry));
53
+ }
54
+ };
55
+ };
56
+ export {
57
+ useBookmarkEntries
58
+ };
@@ -0,0 +1,20 @@
1
+ import { SharingItem } from '../../../types';
2
+ import { ResourceRightName } from '../types/types';
3
+ interface UseSharingItemsParams {
4
+ initialSharings: SharingItem[];
5
+ toggleRight: (item: SharingItem, rightName: ResourceRightName) => SharingItem;
6
+ applyRight: (item: SharingItem, rightName: ResourceRightName, add: boolean) => SharingItem;
7
+ onChange: (value: SharingItem[]) => void;
8
+ onAddItems: (value: SharingItem[]) => void;
9
+ onDeleteItems: (value: SharingItem[]) => void;
10
+ }
11
+ export declare const useSharingItems: ({ initialSharings, toggleRight, applyRight, onChange, onAddItems, onDeleteItems, }: UseSharingItemsParams) => {
12
+ items: SharingItem[];
13
+ addItem: (item: SharingItem) => void;
14
+ addItems: (newItems: SharingItem[]) => void;
15
+ deleteItem: (item: SharingItem) => void;
16
+ deleteItemsByIds: (ids: Set<string>) => void;
17
+ changeRight: (item: SharingItem, rightName: ResourceRightName) => void;
18
+ applyRightToIds: (ids: Set<string>, rightName: ResourceRightName, shouldAdd: boolean) => void;
19
+ };
20
+ export {};