@edifice.io/react 2.5.4 → 2.5.5-develop-b2school.20251218111717
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.
- package/dist/components/AppIcon/index.d.ts +1 -0
- package/dist/components/Divider/Divider.d.ts +38 -0
- package/dist/components/Divider/Divider.js +11 -0
- package/dist/components/Divider/index.d.ts +2 -0
- package/dist/components/Flex/Flex.js +1 -1
- package/dist/components/Menu/components/MenuButton.d.ts +2 -0
- package/dist/components/Menu/components/MenuButton.js +13 -4
- package/dist/components/SegmentedControl/SegmentedControl.d.ts +59 -0
- package/dist/components/SegmentedControl/SegmentedControl.js +21 -0
- package/dist/components/SegmentedControl/index.d.ts +2 -0
- package/dist/components/Select/Select.d.ts +6 -2
- package/dist/components/Select/Select.js +10 -4
- package/dist/components/index.d.ts +2 -0
- package/dist/editor.js +40 -36
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/useInfiniteScroll/index.d.ts +1 -0
- package/dist/hooks/useInfiniteScroll/useInfiniteScroll.d.ts +33 -0
- package/dist/hooks/useInfiniteScroll/useInfiniteScroll.js +20 -0
- package/dist/icons.js +300 -294
- package/dist/index.js +180 -170
- package/dist/modals.js +8 -6
- package/dist/modules/comments/components/Comment.js +4 -2
- package/dist/modules/comments/components/CommentList.js +1 -1
- package/dist/modules/comments/components/DeleteModal.js +14 -8
- package/dist/modules/editor/components/Editor/EditorPreview.d.ts +14 -0
- package/dist/modules/editor/components/Editor/EditorPreview.js +56 -0
- package/dist/modules/editor/components/Editor/EditorPreviewSkeleton.d.ts +8 -0
- package/dist/modules/editor/components/Editor/EditorPreviewSkeleton.js +24 -0
- package/dist/modules/editor/components/Editor/index.d.ts +2 -0
- package/dist/modules/editor/components/Renderer/MediaRenderer.js +2 -2
- package/dist/modules/editor/hooks/useResizeMedia.js +3 -3
- package/dist/modules/icons/components/IconClockAlert.d.ts +7 -0
- package/dist/modules/icons/components/IconClockAlert.js +17 -0
- package/dist/modules/icons/components/IconThumbDown.d.ts +7 -0
- package/dist/modules/icons/components/IconThumbDown.js +12 -0
- package/dist/modules/icons/components/IconThumbUp.d.ts +7 -0
- package/dist/modules/icons/components/IconThumbUp.js +12 -0
- package/dist/modules/icons/components/index.d.ts +3 -0
- package/dist/modules/modals/ShareModal/ShareBookmark.d.ts +1 -1
- package/dist/modules/modals/ShareModal/ShareBookmark.js +5 -2
- package/dist/modules/modals/ShareModal/ShareModal.d.ts +1 -11
- package/dist/modules/modals/ShareModal/ShareModal.js +13 -105
- package/dist/modules/modals/ShareModal/ShareResources.d.ts +174 -0
- package/dist/modules/modals/ShareModal/ShareResources.js +137 -0
- package/dist/modules/modals/ShareModal/hooks/useSearch.d.ts +2 -1
- package/dist/modules/modals/ShareModal/hooks/useSearch.js +3 -2
- package/dist/modules/modals/ShareModal/hooks/useShare.d.ts +12 -5
- package/dist/modules/modals/ShareModal/hooks/useShare.js +20 -13
- package/dist/modules/modals/ShareModal/hooks/useShareBookmark.d.ts +1 -1
- package/dist/modules/modals/ShareModal/hooks/useShareBookmark.js +1 -1
- package/dist/modules/modals/ShareModal/index.d.ts +3 -1
- package/dist/modules/multimedia/FileCard/FileCard.js +1 -1
- package/dist/modules/multimedia/FileCard/FileIcon.js +1 -1
- package/dist/modules/multimedia/Linker/InternalLinker/InternalLinker.js +4 -1
- package/dist/style.css +1 -1
- package/dist/utilities/index.d.ts +1 -0
- package/dist/utilities/react-query/index.d.ts +1 -0
- package/dist/utilities/react-query/react-query-utils.d.ts +21 -0
- package/dist/utilities/react-query/react-query-utils.js +13 -0
- package/package.json +6 -6
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import clsx from "clsx";
|
|
3
|
+
import TextSkeleton from "../../../../components/Skeleton/TextSkeleton.js";
|
|
4
|
+
import Image from "../../../../components/Image/Image.js";
|
|
5
|
+
const EditorPreview = ({
|
|
6
|
+
variant = "outline"
|
|
7
|
+
}) => {
|
|
8
|
+
const borderClass = clsx(variant === "outline" && "border rounded-3"), contentClass = clsx("mt-16", variant === "outline" && "my-12 mx-16");
|
|
9
|
+
return /* @__PURE__ */ jsx("div", { className: borderClass, "data-testid": "editor-preview", children: /* @__PURE__ */ jsxs("div", { className: contentClass, children: [
|
|
10
|
+
/* @__PURE__ */ jsx(TextSkeleton, { className: "col-12" }),
|
|
11
|
+
/* @__PURE__ */ jsx(TextSkeleton, { className: "col-12" }),
|
|
12
|
+
/* @__PURE__ */ jsxs("div", { className: "d-flex justify-content-center gap-24 px-32 pt-16", children: [
|
|
13
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
14
|
+
maxWidth: "150px"
|
|
15
|
+
}, className: "col-12 col-md-4", children: /* @__PURE__ */ jsx(Image, { alt: "", objectFit: "cover", ratio: "16", className: "rounded placeholder", src: "", sizes: "" }) }),
|
|
16
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
17
|
+
maxWidth: "150px"
|
|
18
|
+
}, className: "col-12 col-md-4", children: /* @__PURE__ */ jsx(Image, { alt: "", objectFit: "cover", ratio: "16", className: "rounded placeholder", src: "", sizes: "" }) })
|
|
19
|
+
] })
|
|
20
|
+
] }) });
|
|
21
|
+
};
|
|
22
|
+
export {
|
|
23
|
+
EditorPreview as default
|
|
24
|
+
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export * from './Editor';
|
|
2
2
|
export { default as Editor } from './Editor';
|
|
3
|
+
export { default as EditorPreview } from './EditorPreview';
|
|
4
|
+
export { default as EditorPreviewSkeleton } from './EditorPreviewSkeleton';
|
|
3
5
|
export { default as EditorSkeleton } from './EditorSkeleton';
|
|
@@ -18,7 +18,7 @@ const MediaRenderer = (props) => {
|
|
|
18
18
|
startVerticalResize,
|
|
19
19
|
stopVerticalResize,
|
|
20
20
|
isVerticalResizeActive
|
|
21
|
-
} = useResizeMedia(props, resizableMedia),
|
|
21
|
+
} = useResizeMedia(props, resizableMedia), alignContent = (textalign) => {
|
|
22
22
|
switch (textalign) {
|
|
23
23
|
case "center":
|
|
24
24
|
case "justify":
|
|
@@ -66,7 +66,7 @@ const MediaRenderer = (props) => {
|
|
|
66
66
|
case "iframe":
|
|
67
67
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
68
68
|
/* @__PURE__ */ jsx("div", { className: "iframe-node-view" }),
|
|
69
|
-
/* @__PURE__ */ jsx("iframe", { ref: resizableMedia, src: node.attrs.src, width, height, allowFullScreen: node.attrs.allowfullscreen ?? !0 })
|
|
69
|
+
/* @__PURE__ */ jsx("iframe", { ref: resizableMedia, src: node.attrs.src, width: node.attrs.width, height: node.attrs.height, allowFullScreen: node.attrs.allowfullscreen ?? !0 })
|
|
70
70
|
] });
|
|
71
71
|
default:
|
|
72
72
|
return null;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useRef, useEffect } from "react";
|
|
2
|
-
const
|
|
3
|
-
const aspectRatio = useRef(0), lastCursorX = useRef(-1), isVerticalResizeActive = useRef(!1), proseMirrorContainerWidth = useRef(0),
|
|
2
|
+
const useResizeMedia = (props, refResizable, forcedAspectRatio) => {
|
|
3
|
+
const aspectRatio = useRef(0), lastCursorX = useRef(-1), isVerticalResizeActive = useRef(!1), proseMirrorContainerWidth = useRef(0), readCurrentPixelWidth = () => {
|
|
4
4
|
const el = refResizable.current;
|
|
5
5
|
if (!el) return 0;
|
|
6
6
|
const rect = el.getBoundingClientRect();
|
|
@@ -22,7 +22,7 @@ const MIN_WIDTH = 80, useResizeMedia = (props, refResizable, forcedAspectRatio)
|
|
|
22
22
|
}, []);
|
|
23
23
|
const clampWidth = (w) => {
|
|
24
24
|
let width = w;
|
|
25
|
-
return proseMirrorContainerWidth.current > 0 && width > proseMirrorContainerWidth.current && (width = proseMirrorContainerWidth.current),
|
|
25
|
+
return proseMirrorContainerWidth.current > 0 && width > proseMirrorContainerWidth.current && (width = proseMirrorContainerWidth.current), Math.round(width);
|
|
26
26
|
}, onVerticalResize = (direction, diff) => {
|
|
27
27
|
const currWidth = readCurrentPixelWidth();
|
|
28
28
|
if (!currWidth) return;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SVGProps } from 'react';
|
|
2
|
+
interface SVGRProps {
|
|
3
|
+
title?: string;
|
|
4
|
+
titleId?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const SvgIconClockAlert: ({ title, titleId, ...props }: SVGProps<SVGSVGElement> & SVGRProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default SvgIconClockAlert;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
const SvgIconClockAlert = ({
|
|
3
|
+
title,
|
|
4
|
+
titleId,
|
|
5
|
+
...props
|
|
6
|
+
}) => /* @__PURE__ */ jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", fill: "none", viewBox: "0 0 24 24", "aria-hidden": "true", "aria-labelledby": titleId, ...props, children: [
|
|
7
|
+
title ? /* @__PURE__ */ jsx("title", { id: titleId, children: title }) : null,
|
|
8
|
+
/* @__PURE__ */ jsxs("g", { fill: "currentColor", clipPath: "url(#icon-clock-alert_svg__a)", children: [
|
|
9
|
+
/* @__PURE__ */ jsx("path", { d: "M0 10.075C0 4.51 4.51 0 10.075 0c4.573 0 8.431 3.046 9.663 7.217a1 1 0 0 1-1.918.566A8.075 8.075 0 1 0 7.783 17.82a1 1 0 0 1-.566 1.918C3.046 18.506 0 14.648 0 10.075" }),
|
|
10
|
+
/* @__PURE__ */ jsx("path", { d: "M10.075 4.108a1 1 0 0 1 1 1v5.43a1 1 0 0 1-.357.767L7.83 13.728a1 1 0 1 1-1.286-1.532l2.53-2.123V5.108a1 1 0 0 1 1-1M17 13.3a1 1 0 0 1 1 1v2.2a1 1 0 1 1-2 0v-2.2a1 1 0 0 1 1-1M17 18.4a1 1 0 1 0 0 2h.006a1 1 0 1 0 0-2z" }),
|
|
11
|
+
/* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M17 10a7 7 0 1 0 0 14 7 7 0 0 0 0-14m-5 7a5 5 0 1 1 10 0 5 5 0 0 1-10 0", clipRule: "evenodd" })
|
|
12
|
+
] }),
|
|
13
|
+
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("clipPath", { id: "icon-clock-alert_svg__a", children: /* @__PURE__ */ jsx("path", { fill: "#fff", d: "M0 0h24v24H0z" }) }) })
|
|
14
|
+
] });
|
|
15
|
+
export {
|
|
16
|
+
SvgIconClockAlert as default
|
|
17
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SVGProps } from 'react';
|
|
2
|
+
interface SVGRProps {
|
|
3
|
+
title?: string;
|
|
4
|
+
titleId?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const SvgIconThumbDown: ({ title, titleId, ...props }: SVGProps<SVGSVGElement> & SVGRProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default SvgIconThumbDown;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
const SvgIconThumbDown = ({
|
|
3
|
+
title,
|
|
4
|
+
titleId,
|
|
5
|
+
...props
|
|
6
|
+
}) => /* @__PURE__ */ jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", fill: "none", viewBox: "0 0 24 24", "aria-hidden": "true", "aria-labelledby": titleId, ...props, children: [
|
|
7
|
+
title ? /* @__PURE__ */ jsx("title", { id: titleId, children: title }) : null,
|
|
8
|
+
/* @__PURE__ */ jsx("path", { fill: "currentColor", fillRule: "evenodd", d: "M8.069 15a1.67 1.67 0 0 0 1.16 1.588l3.007-6.765V1.667H3.66a.834.834 0 0 0-.834.708v.002l-1.15 7.498-.009.09a.835.835 0 0 0 .843.869h4.726c.46 0 .833.373.833.833zm8.333-12.5a.833.833 0 0 0-.833-.833h-1.667v7.5h1.667a.833.833 0 0 0 .833-.833zm-10 10H2.52a2.5 2.5 0 0 1-2.49-2.875l1.15-7.5A2.5 2.5 0 0 1 3.668 0h11.9a2.5 2.5 0 0 1 2.5 2.5v5.833a2.5 2.5 0 0 1-2.5 2.5H13.61l-3.114 7.005-.057.108a.83.83 0 0 1-.704.387 3.333 3.333 0 0 1-3.334-3.333z", clipRule: "evenodd" })
|
|
9
|
+
] });
|
|
10
|
+
export {
|
|
11
|
+
SvgIconThumbDown as default
|
|
12
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SVGProps } from 'react';
|
|
2
|
+
interface SVGRProps {
|
|
3
|
+
title?: string;
|
|
4
|
+
titleId?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const SvgIconThumbUp: ({ title, titleId, ...props }: SVGProps<SVGSVGElement> & SVGRProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default SvgIconThumbUp;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
const SvgIconThumbUp = ({
|
|
3
|
+
title,
|
|
4
|
+
titleId,
|
|
5
|
+
...props
|
|
6
|
+
}) => /* @__PURE__ */ jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", fill: "none", viewBox: "0 0 24 24", "aria-hidden": "true", "aria-labelledby": titleId, ...props, children: [
|
|
7
|
+
title ? /* @__PURE__ */ jsx("title", { id: titleId, children: title }) : null,
|
|
8
|
+
/* @__PURE__ */ jsx("path", { fill: "currentColor", fillRule: "evenodd", d: "M10 3.333a1.67 1.67 0 0 0-1.16-1.587L5.833 8.511v8.156h8.576a.834.834 0 0 0 .833-.708l.001-.002 1.15-7.498.008-.09a.834.834 0 0 0-.842-.869h-4.726A.833.833 0 0 1 10 6.667zm-8.333 12.5a.833.833 0 0 0 .833.834h1.667v-7.5H2.5a.833.833 0 0 0-.833.833zm10-10h3.883a2.5 2.5 0 0 1 2.49 2.876l-1.15 7.5a2.5 2.5 0 0 1-2.49 2.124H2.5a2.5 2.5 0 0 1-2.5-2.5V10a2.5 2.5 0 0 1 2.5-2.5h1.958L7.572.495l.057-.108A.83.83 0 0 1 8.333 0a3.333 3.333 0 0 1 3.334 3.333z", clipRule: "evenodd" })
|
|
9
|
+
] });
|
|
10
|
+
export {
|
|
11
|
+
SvgIconThumbUp as default
|
|
12
|
+
};
|
|
@@ -24,6 +24,7 @@ export { default as IconCantoo } from './IconCantoo';
|
|
|
24
24
|
export { default as IconCenter } from './IconCenter';
|
|
25
25
|
export { default as IconCheck } from './IconCheck';
|
|
26
26
|
export { default as IconChecklist } from './IconChecklist';
|
|
27
|
+
export { default as IconClockAlert } from './IconClockAlert';
|
|
27
28
|
export { default as IconClock } from './IconClock';
|
|
28
29
|
export { default as IconCloseFullScreen } from './IconCloseFullScreen';
|
|
29
30
|
export { default as IconClose } from './IconClose';
|
|
@@ -150,6 +151,8 @@ export { default as IconTextToSpeech } from './IconTextToSpeech';
|
|
|
150
151
|
export { default as IconTextTypo } from './IconTextTypo';
|
|
151
152
|
export { default as IconTextUnderline } from './IconTextUnderline';
|
|
152
153
|
export { default as IconTextVanilla } from './IconTextVanilla';
|
|
154
|
+
export { default as IconThumbDown } from './IconThumbDown';
|
|
155
|
+
export { default as IconThumbUp } from './IconThumbUp';
|
|
153
156
|
export { default as IconToolCenter } from './IconToolCenter';
|
|
154
157
|
export { default as IconTool } from './IconTool';
|
|
155
158
|
export { default as IconTrendingUp } from './IconTrendingUp';
|
|
@@ -4,5 +4,5 @@ export declare const ShareBookmark: ({ bookmark, refBookmark, onBookmarkChange,
|
|
|
4
4
|
bookmark: BookmarkProps;
|
|
5
5
|
refBookmark: Ref<HTMLInputElement>;
|
|
6
6
|
onBookmarkChange: () => void;
|
|
7
|
-
onSave: () => void
|
|
7
|
+
onSave: () => Promise<void>;
|
|
8
8
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
2
3
|
import { useTranslation } from "react-i18next";
|
|
3
4
|
import SvgIconSave from "../../icons/components/IconSave.js";
|
|
4
5
|
import FormControl from "../../../components/Form/FormControl.js";
|
|
@@ -11,10 +12,12 @@ const ShareBookmark = ({
|
|
|
11
12
|
}) => {
|
|
12
13
|
const {
|
|
13
14
|
t
|
|
14
|
-
} = useTranslation()
|
|
15
|
+
} = useTranslation(), [isSaving, setIsSaving] = useState(!1), handleSaveClick = async () => {
|
|
16
|
+
setIsSaving(!0), await onSave(), setIsSaving(!1);
|
|
17
|
+
};
|
|
15
18
|
return /* @__PURE__ */ jsx("div", { className: "mt-16", children: /* @__PURE__ */ jsxs(FormControl, { id: "bookmarkName", className: "d-flex flex-wrap align-items-center gap-16", children: [
|
|
16
19
|
/* @__PURE__ */ jsx("div", { className: "flex-fill", children: /* @__PURE__ */ jsx(FormControl.Input, { ref: refBookmark, onChange: onBookmarkChange, placeholder: t("explorer.modal.share.sharebookmark.placeholder"), size: "sm", type: "text" }, bookmark.id) }),
|
|
17
|
-
/* @__PURE__ */ jsx(Button, { type: "button", color: "primary", variant: "ghost", disabled: bookmark.name.length === 0, leftIcon: /* @__PURE__ */ jsx(SvgIconSave, {}), onClick:
|
|
20
|
+
/* @__PURE__ */ jsx(Button, { type: "button", color: "primary", variant: "ghost", disabled: bookmark.name.length === 0 || isSaving, leftIcon: /* @__PURE__ */ jsx(SvgIconSave, {}), onClick: handleSaveClick, className: "text-nowrap", isLoading: isSaving, children: t("explorer.modal.share.sharebookmark.save") })
|
|
18
21
|
] }) });
|
|
19
22
|
};
|
|
20
23
|
export {
|
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { UseMutationResult } from '../../../node_modules/@tanstack/react-query';
|
|
4
|
-
export type ShareOptions = {
|
|
5
|
-
resourceId: ID;
|
|
6
|
-
resourceRights: RightStringified[];
|
|
7
|
-
resourceCreatorId: string;
|
|
8
|
-
};
|
|
9
|
-
export type ShareResourceMutation = UseMutationResult<PutShareResponse, unknown, {
|
|
10
|
-
resourceId: string;
|
|
11
|
-
rights: ShareRight[];
|
|
12
|
-
}, unknown>;
|
|
2
|
+
import { ShareOptions, ShareResourceMutation } from './ShareResources';
|
|
13
3
|
interface ShareResourceModalProps {
|
|
14
4
|
/** Handle open/close state */
|
|
15
5
|
isOpen: boolean;
|
|
@@ -1,25 +1,11 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from "react";
|
|
2
|
+
import { useRef, useState } from "react";
|
|
3
3
|
import { createPortal } from "react-dom";
|
|
4
4
|
import { useTranslation } from "react-i18next";
|
|
5
|
-
import
|
|
6
|
-
import SvgIconInfoCircle from "../../icons/components/IconInfoCircle.js";
|
|
7
|
-
import SvgIconRafterDown from "../../icons/components/IconRafterDown.js";
|
|
8
|
-
import { ShareBookmark } from "./ShareBookmark.js";
|
|
9
|
-
import { ShareBookmarkLine } from "./ShareBookmarkLine.js";
|
|
10
|
-
import { useSearch } from "./hooks/useSearch.js";
|
|
11
|
-
import useShare from "./hooks/useShare.js";
|
|
12
|
-
import { useShareBookmark } from "./hooks/useShareBookmark.js";
|
|
5
|
+
import ShareResources from "./ShareResources.js";
|
|
13
6
|
import Modal from "../../../components/Modal/Modal.js";
|
|
14
7
|
import Alert from "../../../components/Alert/Alert.js";
|
|
15
|
-
import Heading from "../../../components/Heading/Heading.js";
|
|
16
|
-
import LoadingScreen from "../../../components/LoadingScreen/LoadingScreen.js";
|
|
17
|
-
import VisuallyHidden from "../../../components/VisuallyHidden/VisuallyHidden.js";
|
|
18
|
-
import Avatar from "../../../components/Avatar/Avatar.js";
|
|
19
|
-
import Checkbox from "../../../components/Checkbox/Checkbox.js";
|
|
20
8
|
import Button from "../../../components/Button/Button.js";
|
|
21
|
-
import Tooltip from "../../../components/Tooltip/Tooltip.js";
|
|
22
|
-
import Combobox from "../../../components/Combobox/Combobox.js";
|
|
23
9
|
function ShareResourceModal({
|
|
24
10
|
isOpen,
|
|
25
11
|
shareOptions,
|
|
@@ -28,104 +14,26 @@ function ShareResourceModal({
|
|
|
28
14
|
onSuccess,
|
|
29
15
|
onCancel
|
|
30
16
|
}) {
|
|
31
|
-
const {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
} = shareOptions, [isLoading, setIsLoading] = useState(!0), {
|
|
36
|
-
state: {
|
|
37
|
-
isSharing,
|
|
38
|
-
shareRights,
|
|
39
|
-
shareRightActions
|
|
40
|
-
},
|
|
41
|
-
dispatch: shareDispatch,
|
|
42
|
-
myAvatar,
|
|
43
|
-
currentIsAuthor,
|
|
44
|
-
handleShare,
|
|
45
|
-
toggleRight,
|
|
46
|
-
handleDeleteRow
|
|
47
|
-
} = useShare({
|
|
48
|
-
resourceId,
|
|
49
|
-
resourceCreatorId,
|
|
50
|
-
resourceRights,
|
|
51
|
-
shareResource,
|
|
52
|
-
setIsLoading,
|
|
53
|
-
onSuccess
|
|
54
|
-
}), {
|
|
55
|
-
state: {
|
|
56
|
-
searchResults,
|
|
57
|
-
searchInputValue
|
|
58
|
-
},
|
|
59
|
-
showSearchAdmlHint,
|
|
60
|
-
showSearchLoading,
|
|
61
|
-
showSearchNoResults,
|
|
62
|
-
getSearchMinLength,
|
|
63
|
-
handleSearchInputChange,
|
|
64
|
-
handleSearchResultsChange
|
|
65
|
-
} = useSearch({
|
|
66
|
-
resourceId,
|
|
67
|
-
resourceCreatorId,
|
|
68
|
-
shareRights,
|
|
69
|
-
shareDispatch
|
|
70
|
-
}), {
|
|
71
|
-
refBookmark,
|
|
72
|
-
showBookmark,
|
|
73
|
-
handleBookmarkChange,
|
|
74
|
-
toggleBookmark,
|
|
75
|
-
bookmark,
|
|
76
|
-
handleOnSave,
|
|
77
|
-
showBookmarkInput,
|
|
78
|
-
toggleBookmarkInput
|
|
79
|
-
} = useShareBookmark({
|
|
80
|
-
shareRights,
|
|
81
|
-
shareDispatch
|
|
82
|
-
}), {
|
|
17
|
+
const refShareResources = useRef(null), handleShare = () => {
|
|
18
|
+
var _a;
|
|
19
|
+
(_a = refShareResources.current) == null || _a.handleShare();
|
|
20
|
+
}, [isSaving, setIsSaving] = useState(!1), {
|
|
83
21
|
t
|
|
84
|
-
} = useTranslation(),
|
|
22
|
+
} = useTranslation(), onSaving = (isSaving2) => {
|
|
23
|
+
setIsSaving(isSaving2);
|
|
24
|
+
};
|
|
85
25
|
return /* @__PURE__ */ createPortal(/* @__PURE__ */ jsxs(Modal, { id: "share_modal", size: "lg", isOpen, onModalClose: onCancel, children: [
|
|
86
26
|
/* @__PURE__ */ jsx(Modal.Header, { onModalClose: onCancel, children: t("share.title") }),
|
|
87
27
|
/* @__PURE__ */ jsxs(Modal.Body, { children: [
|
|
88
28
|
/* @__PURE__ */ jsx(Alert, { type: "info", className: "mb-16", children: t("explorer.modal.share.alert.community") }),
|
|
89
|
-
/* @__PURE__ */ jsx(
|
|
90
|
-
/* @__PURE__ */ jsx("div", { className: "table-responsive", children: isLoading ? /* @__PURE__ */ jsx(LoadingScreen, {}) : /* @__PURE__ */ jsxs("table", { className: "table border align-middle mb-0", children: [
|
|
91
|
-
/* @__PURE__ */ jsx("thead", { className: "bg-secondary", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
92
|
-
/* @__PURE__ */ jsx("th", { scope: "col", className: "w-32", children: /* @__PURE__ */ jsx(VisuallyHidden, { children: t("explorer.modal.share.avatar.shared.alt") }) }),
|
|
93
|
-
/* @__PURE__ */ jsx("th", { scope: "col", children: /* @__PURE__ */ jsx(VisuallyHidden, { children: t("explorer.modal.share.search.placeholder") }) }),
|
|
94
|
-
shareRightActions.map((shareRightAction) => /* @__PURE__ */ jsx("th", { scope: "col", className: "text-center text-white", children: t(shareRightAction.displayName) }, shareRightAction.displayName)),
|
|
95
|
-
/* @__PURE__ */ jsx("th", { scope: "col", children: /* @__PURE__ */ jsx(VisuallyHidden, { children: t("close") }) })
|
|
96
|
-
] }) }),
|
|
97
|
-
/* @__PURE__ */ jsxs("tbody", { children: [
|
|
98
|
-
currentIsAuthor() && /* @__PURE__ */ jsxs("tr", { children: [
|
|
99
|
-
/* @__PURE__ */ jsx("th", { scope: "row", children: /* @__PURE__ */ jsx(Avatar, { alt: t("explorer.modal.share.avatar.me.alt"), size: "xs", src: myAvatar, variant: "circle" }) }),
|
|
100
|
-
/* @__PURE__ */ jsx("td", { children: t("share.me") }),
|
|
101
|
-
shareRightActions.map((shareRightAction) => /* @__PURE__ */ jsx("td", { style: {
|
|
102
|
-
width: "80px"
|
|
103
|
-
}, className: "text-center text-white", children: /* @__PURE__ */ jsx(Checkbox, { checked: !0, disabled: !0 }) }, shareRightAction.displayName)),
|
|
104
|
-
/* @__PURE__ */ jsx("td", {})
|
|
105
|
-
] }),
|
|
106
|
-
/* @__PURE__ */ jsx(ShareBookmarkLine, { showBookmark, shareRightActions, shareRights, onDeleteRow: handleDeleteRow, toggleRight, toggleBookmark })
|
|
107
|
-
] })
|
|
108
|
-
] }) }),
|
|
109
|
-
/* @__PURE__ */ jsxs("div", { className: "mt-16", children: [
|
|
110
|
-
/* @__PURE__ */ jsx(Button, { color: "tertiary", leftIcon: /* @__PURE__ */ jsx(SvgIconBookmark, {}), rightIcon: /* @__PURE__ */ jsx(SvgIconRafterDown, { title: t("show"), className: "w-16 min-w-0", style: {
|
|
111
|
-
transition: "rotate 0.2s ease-out",
|
|
112
|
-
rotate: showBookmarkInput ? "-180deg" : "0deg"
|
|
113
|
-
} }), type: "button", variant: "ghost", className: "fw-normal", onClick: () => toggleBookmarkInput(!showBookmarkInput), children: t("share.save.sharebookmark") }),
|
|
114
|
-
showBookmarkInput && /* @__PURE__ */ jsx(ShareBookmark, { refBookmark, bookmark, onBookmarkChange: handleBookmarkChange, onSave: handleOnSave })
|
|
115
|
-
] }),
|
|
116
|
-
/* @__PURE__ */ jsx("hr", {}),
|
|
117
|
-
/* @__PURE__ */ jsxs(Heading, { headingStyle: "h4", level: "h3", className: "mb-16 d-flex align-items-center", children: [
|
|
118
|
-
/* @__PURE__ */ jsx("div", { className: "me-8", children: t("explorer.modal.share.search") }),
|
|
119
|
-
/* @__PURE__ */ jsx(Tooltip, { message: "Vos favoris de partage s’affichent en priorité dans votre liste lorsque vous recherchez un groupe ou une personne, vous pouvez les retrouver dans l’annuaire.", placement: "top", children: /* @__PURE__ */ jsx(SvgIconInfoCircle, { className: "c-pointer", height: "18" }) })
|
|
120
|
-
] }),
|
|
121
|
-
/* @__PURE__ */ jsx("div", { className: "row", children: /* @__PURE__ */ jsx("div", { className: "col-10", children: /* @__PURE__ */ jsx(Combobox, { value: searchInputValue, placeholder: searchPlaceholder, isLoading: showSearchLoading(), noResult: showSearchNoResults(), options: searchResults, searchMinLength: getSearchMinLength(), onSearchInputChange: handleSearchInputChange, onSearchResultsChange: handleSearchResultsChange }) }) }),
|
|
29
|
+
/* @__PURE__ */ jsx(ShareResources, { shareOptions, shareResource, ref: refShareResources, onSuccess, onSubmit: onSaving, classNameSearchInput: "flex-fill" }),
|
|
122
30
|
children
|
|
123
31
|
] }),
|
|
124
32
|
/* @__PURE__ */ jsxs(Modal.Footer, { children: [
|
|
125
|
-
/* @__PURE__ */ jsx(Button, { type: "button", color: "tertiary", variant: "ghost", onClick: onCancel, children: t("explorer.cancel") }),
|
|
126
|
-
/* @__PURE__ */ jsx(Button, { type: "button", color: "primary", variant: "filled", isLoading:
|
|
33
|
+
/* @__PURE__ */ jsx(Button, { type: "button", color: "tertiary", variant: "ghost", onClick: onCancel, disabled: isSaving, children: t("explorer.cancel") }),
|
|
34
|
+
/* @__PURE__ */ jsx(Button, { type: "button", color: "primary", variant: "filled", isLoading: isSaving, onClick: handleShare, disabled: isSaving, children: t("share") })
|
|
127
35
|
] })
|
|
128
|
-
] }), document.getElementById("portal"));
|
|
36
|
+
] }), document.getElementById("portal") || document.body);
|
|
129
37
|
}
|
|
130
38
|
export {
|
|
131
39
|
ShareResourceModal as default
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { ID, PutShareResponse, RightStringified, ShareRight, ShareRightActionDisplayName, ShareUrls } from '@edifice.io/client';
|
|
2
|
+
import { UseMutationResult } from '../../../node_modules/@tanstack/react-query';
|
|
3
|
+
/**
|
|
4
|
+
* Configuration options for sharing a resource
|
|
5
|
+
*
|
|
6
|
+
* @typedef {Object} ShareOptions
|
|
7
|
+
* @property {ID} resourceId - Unique identifier of the resource to share
|
|
8
|
+
* @property {RightStringified[]} resourceRights - Current rights assigned to the resource
|
|
9
|
+
* @property {string} resourceCreatorId - User ID of the resource creator
|
|
10
|
+
* @property {ShareRightActionDisplayName[]} [filteredActions] - Optional list of allowed actions to display
|
|
11
|
+
* @property {ShareUrls} [shareUrls] - Optional custom URLs for API endpoints related to sharing operations default endpoints are used if not provided
|
|
12
|
+
* default: {
|
|
13
|
+
* getResourceRights: `/${app}/share/json/${resourceId}?search=`,
|
|
14
|
+
* saveResourceRights: `/${app}/share/resource/${resourceId}`,
|
|
15
|
+
* getShareMapping: `/${app}/rights/sharing`
|
|
16
|
+
* }
|
|
17
|
+
*
|
|
18
|
+
* @example Example related to sharing thread resources:
|
|
19
|
+
* ```ts
|
|
20
|
+
* const shareOptions: ShareOptions = {
|
|
21
|
+
* resourceId: '12345',
|
|
22
|
+
* resourceRights: [],
|
|
23
|
+
* resourceCreatorId: 'user-67890',
|
|
24
|
+
* filteredActions: ['read', 'contrib'],
|
|
25
|
+
* shareUrls: {
|
|
26
|
+
* getResourceRights: '/api/V1/thread/shares', (get endpoint)
|
|
27
|
+
* saveResourceRights: '/api/V1/thread/shares', (put endpoint)
|
|
28
|
+
* getShareMapping: '/api/V1/rights/sharing'
|
|
29
|
+
* }
|
|
30
|
+
* };
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @example Example related to sharing info resources:
|
|
34
|
+
* ```ts
|
|
35
|
+
* const shareOptions: ShareOptions = {
|
|
36
|
+
* resourceId: '12345',
|
|
37
|
+
* resourceRights: [],
|
|
38
|
+
* resourceCreatorId: 'user-67890',
|
|
39
|
+
* filteredActions: ['read', 'contrib'],
|
|
40
|
+
* shareUrls: {
|
|
41
|
+
* getResourceRights: '/api/V1/info/shares', (get endpoint)
|
|
42
|
+
* saveResourceRights: '/api/V1/info/shares', (put endpoint)
|
|
43
|
+
* getShareMapping: '/api/V1/rights/sharing'
|
|
44
|
+
* }
|
|
45
|
+
* };
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export type ShareOptions = {
|
|
49
|
+
resourceId: ID;
|
|
50
|
+
resourceRights: RightStringified[];
|
|
51
|
+
resourceCreatorId: string;
|
|
52
|
+
filteredActions?: ShareRightActionDisplayName[];
|
|
53
|
+
shareUrls?: ShareUrls;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* React Query mutation result for share operations
|
|
57
|
+
*
|
|
58
|
+
* @typedef {UseMutationResult<PutShareResponse, unknown, {resourceId: string; rights: ShareRight[]}, unknown>} ShareResourceMutation
|
|
59
|
+
*/
|
|
60
|
+
export type ShareResourceMutation = UseMutationResult<PutShareResponse, unknown, {
|
|
61
|
+
resourceId: string;
|
|
62
|
+
rights: ShareRight[];
|
|
63
|
+
}, unknown>;
|
|
64
|
+
/**
|
|
65
|
+
* Props for the ShareResources component
|
|
66
|
+
*
|
|
67
|
+
* @interface ShareResourceProps
|
|
68
|
+
* @property {ShareOptions} shareOptions - Configuration for the resource being shared
|
|
69
|
+
* @property {ShareResourceMutation} [shareResource] - Optional React Query mutation for optimistic UI updates
|
|
70
|
+
* @property {() => void} [onSuccess] - Callback fired after successful share operation
|
|
71
|
+
* @property {(shareRights: ShareRight[], isDirty: boolean) => void} [onChange] - Callback fired when share rights change
|
|
72
|
+
* @property {(isSubmitting: boolean) => void} [onSubmit] - Callback fired when share operation is submitting
|
|
73
|
+
* @property {string} [classNameSearchInput] - Optional CSS class for the search input wrapper (default: 'col-6')
|
|
74
|
+
*/
|
|
75
|
+
interface ShareResourceProps {
|
|
76
|
+
/**
|
|
77
|
+
* Expect resourceId,
|
|
78
|
+
* new rights array (replace shared array),
|
|
79
|
+
* creatorId
|
|
80
|
+
* of a resource */
|
|
81
|
+
shareOptions: ShareOptions;
|
|
82
|
+
/**
|
|
83
|
+
* Use the `shareResource` props when you need to do Optimistic UI
|
|
84
|
+
* otherwise ShareModal handles everything
|
|
85
|
+
* Must use React Query */
|
|
86
|
+
shareResource?: ShareResourceMutation;
|
|
87
|
+
/**
|
|
88
|
+
* onSuccess callback when a resource is successfully shared
|
|
89
|
+
*/
|
|
90
|
+
onSuccess?: () => void;
|
|
91
|
+
/**
|
|
92
|
+
* Callback when share rights change
|
|
93
|
+
*/
|
|
94
|
+
onChange?: (shareRights: ShareRight[], isDirty: boolean) => void;
|
|
95
|
+
/**
|
|
96
|
+
* Callback when ShareResources component is submitting share rights or bookmark changes
|
|
97
|
+
*/
|
|
98
|
+
onSubmit?: (isSubmitting: boolean) => void;
|
|
99
|
+
/**
|
|
100
|
+
* Optional className for the search input wrapper (default: 'col-6')
|
|
101
|
+
*/
|
|
102
|
+
classNameSearchInput?: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Ref interface exposed by ShareResources component
|
|
106
|
+
*
|
|
107
|
+
* @interface ShareResourcesRef
|
|
108
|
+
* @property {() => void} handleShare - Method to trigger the share operation
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```tsx
|
|
112
|
+
* const ref = useRef<ShareResourcesRef>(null);
|
|
113
|
+
*
|
|
114
|
+
* // Trigger share programmatically
|
|
115
|
+
* ref.current?.handleShare();
|
|
116
|
+
*
|
|
117
|
+
* // Check sharing status
|
|
118
|
+
* const sharing = ref.current?.isSharing();
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
export interface ShareResourcesRef {
|
|
122
|
+
handleShare: (notify?: boolean) => void;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* ShareResources Component
|
|
126
|
+
*
|
|
127
|
+
* A component for managing resource sharing permissions with users and groups.
|
|
128
|
+
* Provides search functionality, bookmark management, and granular rights control.
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```tsx
|
|
132
|
+
* import { useRef } from 'react';
|
|
133
|
+
* import ShareResources, { ShareResourcesRef, ShareOptions } from './ShareResources';
|
|
134
|
+
*
|
|
135
|
+
* function MyComponent() {
|
|
136
|
+
* const shareRef = useRef<ShareResourcesRef>(null);
|
|
137
|
+
*
|
|
138
|
+
* const shareOptions: ShareOptions = {
|
|
139
|
+
* resourceId: '123',
|
|
140
|
+
* resourceRights: [],
|
|
141
|
+
* resourceCreatorId: 'user-456',
|
|
142
|
+
* filteredActions: ['read', 'contrib'],
|
|
143
|
+
* urls: {
|
|
144
|
+
* getResourceRights: '/api/share/rights',
|
|
145
|
+
* putResourceRights: '/api/share/update'
|
|
146
|
+
* }
|
|
147
|
+
* };
|
|
148
|
+
*
|
|
149
|
+
* const handleSave = () => {
|
|
150
|
+
* if (shareRef.current) {
|
|
151
|
+
* shareRef.current.handleShare();
|
|
152
|
+
* }
|
|
153
|
+
* };
|
|
154
|
+
*
|
|
155
|
+
* return (
|
|
156
|
+
* <>
|
|
157
|
+
* <ShareResources
|
|
158
|
+
* ref={shareRef}
|
|
159
|
+
* shareOptions={shareOptions}
|
|
160
|
+
* onSuccess={() => console.log('Shared successfully')}
|
|
161
|
+
* onChange={(rights, isDirty) => console.log('Rights changed:', isDirty)}
|
|
162
|
+
* onSubmit={(isSubmitting) => console.log('Submitting share...', isSubmitting)}
|
|
163
|
+
* />
|
|
164
|
+
* <button onClick={handleSave}>Save Changes</button>
|
|
165
|
+
* </>
|
|
166
|
+
* );
|
|
167
|
+
* }
|
|
168
|
+
* ```
|
|
169
|
+
*
|
|
170
|
+
* @component
|
|
171
|
+
* @forwardRef
|
|
172
|
+
*/
|
|
173
|
+
declare const ShareResources: import('react').ForwardRefExoticComponent<ShareResourceProps & import('react').RefAttributes<ShareResourcesRef>>;
|
|
174
|
+
export default ShareResources;
|