[WEB-3827] refactor: work item widget components (#6902)

This commit is contained in:
Aaryan Khandelwal
2025-04-09 19:58:16 +05:30
committed by GitHub
parent 9eeff158d5
commit a3fd616ec4
19 changed files with 173 additions and 118 deletions

View File

@@ -1,8 +1,10 @@
"use client";
import React, { FC } from "react";
import { Layers, Link, Paperclip, Waypoints } from "lucide-react";
//i18n
// plane imports
import { useTranslation } from "@plane/i18n";
import { TIssueServiceType } from "@plane/types";
// components
import {
IssueAttachmentActionButton,
@@ -10,6 +12,7 @@ import {
RelationActionButton,
SubIssuesActionButton,
IssueDetailWidgetButton,
TWorkItemWidgets,
} from "@/components/issues/issue-detail-widgets";
type Props = {
@@ -17,58 +20,74 @@ type Props = {
projectId: string;
issueId: string;
disabled: boolean;
issueServiceType: TIssueServiceType;
hideWidgets?: TWorkItemWidgets[];
};
export const IssueDetailWidgetActionButtons: FC<Props> = (props) => {
const { workspaceSlug, projectId, issueId, disabled } = props;
const { workspaceSlug, projectId, issueId, disabled, issueServiceType, hideWidgets } = props;
// translation
const { t } = useTranslation();
return (
<div className="flex items-center flex-wrap gap-2">
<SubIssuesActionButton
issueId={issueId}
customButton={
<IssueDetailWidgetButton
title={t("issue.add.sub_issue")}
icon={<Layers className="h-3.5 w-3.5 flex-shrink-0" strokeWidth={2} />}
disabled={disabled}
/>
}
disabled={disabled}
/>
<RelationActionButton
issueId={issueId}
customButton={
<IssueDetailWidgetButton
title={t("issue.add.relation")}
icon={<Waypoints className="h-3.5 w-3.5 flex-shrink-0" strokeWidth={2} />}
disabled={disabled}
/>
}
disabled={disabled}
/>
<IssueLinksActionButton
customButton={
<IssueDetailWidgetButton
title={t("issue.add.link")}
icon={<Link className="h-3.5 w-3.5 flex-shrink-0" strokeWidth={2} />}
disabled={disabled}
/>
}
disabled={disabled}
/>
<IssueAttachmentActionButton
workspaceSlug={workspaceSlug}
projectId={projectId}
issueId={issueId}
customButton={
<IssueDetailWidgetButton
title={t("common.attach")}
icon={<Paperclip className="h-3.5 w-3.5 flex-shrink-0" strokeWidth={2} />}
disabled={disabled}
/>
}
disabled={disabled}
/>
{!hideWidgets?.includes("sub-work-items") && (
<SubIssuesActionButton
issueId={issueId}
customButton={
<IssueDetailWidgetButton
title={t("issue.add.sub_issue")}
icon={<Layers className="h-3.5 w-3.5 flex-shrink-0" strokeWidth={2} />}
disabled={disabled}
/>
}
disabled={disabled}
issueServiceType={issueServiceType}
/>
)}
{!hideWidgets?.includes("relations") && (
<RelationActionButton
issueId={issueId}
customButton={
<IssueDetailWidgetButton
title={t("issue.add.relation")}
icon={<Waypoints className="h-3.5 w-3.5 flex-shrink-0" strokeWidth={2} />}
disabled={disabled}
/>
}
disabled={disabled}
issueServiceType={issueServiceType}
/>
)}
{!hideWidgets?.includes("links") && (
<IssueLinksActionButton
customButton={
<IssueDetailWidgetButton
title={t("issue.add.link")}
icon={<Link className="h-3.5 w-3.5 flex-shrink-0" strokeWidth={2} />}
disabled={disabled}
/>
}
disabled={disabled}
issueServiceType={issueServiceType}
/>
)}
{!hideWidgets?.includes("attachments") && (
<IssueAttachmentActionButton
workspaceSlug={workspaceSlug}
projectId={projectId}
issueId={issueId}
customButton={
<IssueDetailWidgetButton
title={t("common.attach")}
icon={<Paperclip className="h-3.5 w-3.5 flex-shrink-0" strokeWidth={2} />}
disabled={disabled}
/>
}
disabled={disabled}
issueServiceType={issueServiceType}
/>
)}
</div>
);
};

View File

@@ -4,15 +4,14 @@ import React, { FC, useCallback, useState } from "react";
import { observer } from "mobx-react";
import { FileRejection, useDropzone } from "react-dropzone";
import { Plus } from "lucide-react";
import { EIssueServiceType } from "@plane/constants";
// plane imports
import { TIssueServiceType } from "@plane/types";
// plane ui
import { TOAST_TYPE, setToast } from "@plane/ui";
// hooks
import { useIssueDetail } from "@/hooks/store";
// plane web hooks
import { useFileSize } from "@/plane-web/hooks/use-file-size";
// local imports
import { useAttachmentOperations } from "./helper";
type Props = {
@@ -21,18 +20,11 @@ type Props = {
issueId: string;
customButton?: React.ReactNode;
disabled?: boolean;
issueServiceType?: TIssueServiceType;
issueServiceType: TIssueServiceType;
};
export const IssueAttachmentActionButton: FC<Props> = observer((props) => {
const {
workspaceSlug,
projectId,
issueId,
customButton,
disabled = false,
issueServiceType = EIssueServiceType.ISSUES,
} = props;
const { workspaceSlug, projectId, issueId, customButton, disabled = false, issueServiceType } = props;
// state
const [isLoading, setIsLoading] = useState(false);
// store hooks

View File

@@ -1,7 +1,7 @@
"use client";
import React, { FC } from "react";
import { observer } from "mobx-react";
import { EIssueServiceType } from "@plane/constants";
// plane imports
import { TIssueServiceType } from "@plane/types";
import { Collapsible } from "@plane/ui";
// components
@@ -17,11 +17,11 @@ type Props = {
projectId: string;
issueId: string;
disabled?: boolean;
issueServiceType?: TIssueServiceType;
issueServiceType: TIssueServiceType;
};
export const AttachmentsCollapsible: FC<Props> = observer((props) => {
const { workspaceSlug, projectId, issueId, disabled = false, issueServiceType = EIssueServiceType.ISSUES } = props;
const { workspaceSlug, projectId, issueId, disabled = false, issueServiceType } = props;
// store hooks
const { openWidgets, toggleOpenWidget } = useIssueDetail(issueServiceType);

View File

@@ -1,12 +1,15 @@
"use client";
import React, { FC } from "react";
import { observer } from "mobx-react";
// plane imports
import { TIssueServiceType } from "@plane/types";
// components
import {
AttachmentsCollapsible,
LinksCollapsible,
RelationsCollapsible,
SubIssuesCollapsible,
TWorkItemWidgets,
} from "@/components/issues/issue-detail-widgets";
// hooks
import { useIssueDetail } from "@/hooks/store";
@@ -19,31 +22,33 @@ type Props = {
projectId: string;
issueId: string;
disabled: boolean;
issueServiceType: TIssueServiceType;
hideWidgets?: TWorkItemWidgets[];
};
export const IssueDetailWidgetCollapsibles: FC<Props> = observer((props) => {
const { workspaceSlug, projectId, issueId, disabled } = props;
const { workspaceSlug, projectId, issueId, disabled, issueServiceType, hideWidgets } = props;
// store hooks
const {
issue: { getIssueById },
subIssues: { subIssuesByIssueId },
attachment: { getAttachmentsCountByIssueId, getAttachmentsUploadStatusByIssueId },
relation: { getRelationCountByIssueId },
} = useIssueDetail();
} = useIssueDetail(issueServiceType);
// derived values
const issue = getIssueById(issueId);
const subIssues = subIssuesByIssueId(issueId);
const ISSUE_RELATION_OPTIONS = useTimeLineRelationOptions();
const issueRelationsCount = getRelationCountByIssueId(issueId, ISSUE_RELATION_OPTIONS);
// render conditions
const shouldRenderSubIssues = !!subIssues && subIssues.length > 0;
const shouldRenderRelations = issueRelationsCount > 0;
const shouldRenderLinks = !!issue?.link_count && issue?.link_count > 0;
const shouldRenderSubIssues = !!subIssues && subIssues.length > 0 && !hideWidgets?.includes("sub-work-items");
const shouldRenderRelations = issueRelationsCount > 0 && !hideWidgets?.includes("relations");
const shouldRenderLinks = !!issue?.link_count && issue?.link_count > 0 && !hideWidgets?.includes("links");
const attachmentUploads = getAttachmentsUploadStatusByIssueId(issueId);
const attachmentsCount = getAttachmentsCountByIssueId(issueId);
const shouldRenderAttachments = attachmentsCount > 0 || (!!attachmentUploads && attachmentUploads.length > 0);
const shouldRenderAttachments =
attachmentsCount > 0 ||
(!!attachmentUploads && attachmentUploads.length > 0 && !hideWidgets?.includes("attachments"));
return (
<div className="flex flex-col">
@@ -53,13 +58,25 @@ export const IssueDetailWidgetCollapsibles: FC<Props> = observer((props) => {
projectId={projectId}
issueId={issueId}
disabled={disabled}
issueServiceType={issueServiceType}
/>
)}
{shouldRenderRelations && (
<RelationsCollapsible workspaceSlug={workspaceSlug} issueId={issueId} disabled={disabled} />
<RelationsCollapsible
workspaceSlug={workspaceSlug}
issueId={issueId}
disabled={disabled}
issueServiceType={issueServiceType}
/>
)}
{shouldRenderLinks && (
<LinksCollapsible workspaceSlug={workspaceSlug} projectId={projectId} issueId={issueId} disabled={disabled} />
<LinksCollapsible
workspaceSlug={workspaceSlug}
projectId={projectId}
issueId={issueId}
disabled={disabled}
issueServiceType={issueServiceType}
/>
)}
{shouldRenderAttachments && (
<AttachmentsCollapsible
@@ -67,9 +84,9 @@ export const IssueDetailWidgetCollapsibles: FC<Props> = observer((props) => {
projectId={projectId}
issueId={issueId}
disabled={disabled}
issueServiceType={issueServiceType}
/>
)}
<WorkItemAdditionalWidgets
workspaceSlug={workspaceSlug}
projectId={projectId}

View File

@@ -1,6 +1,6 @@
import React, { FC } from "react";
import { observer } from "mobx-react";
import { ISearchIssueResponse, TIssue } from "@plane/types";
import { ISearchIssueResponse, TIssue, TIssueServiceType } from "@plane/types";
import { setToast, TOAST_TYPE } from "@plane/ui";
// components
import { ExistingIssuesListModal } from "@/components/core";
@@ -17,10 +17,11 @@ type Props = {
workspaceSlug: string;
projectId: string;
issueId: string;
issueServiceType: TIssueServiceType;
};
export const IssueDetailWidgetModals: FC<Props> = observer((props) => {
const { workspaceSlug, projectId, issueId } = props;
const { workspaceSlug, projectId, issueId, issueServiceType } = props;
// store hooks
const {
isIssueLinkModalOpen,
@@ -146,6 +147,7 @@ export const IssueDetailWidgetModals: FC<Props> = observer((props) => {
isModalOpen={isIssueLinkModalOpen}
handleOnClose={handleIssueLinkModalOnClose}
linkOperations={handleLinkOperations}
issueServiceType={issueServiceType}
/>
{shouldRenderCreateUpdateModal && (

View File

@@ -1,6 +1,5 @@
"use client";
import React, { FC } from "react";
import { EIssueServiceType } from "@plane/constants";
import { TIssueServiceType } from "@plane/types";
// components
import { LinkList } from "../../issue-detail/links";
@@ -12,11 +11,11 @@ type Props = {
projectId: string;
issueId: string;
disabled: boolean;
issueServiceType?: TIssueServiceType;
issueServiceType: TIssueServiceType;
};
export const IssueLinksCollapsibleContent: FC<Props> = (props) => {
const { workspaceSlug, projectId, issueId, disabled, issueServiceType = EIssueServiceType.ISSUES } = props;
const { workspaceSlug, projectId, issueId, disabled, issueServiceType } = props;
// helper
const handleLinkOperations = useLinkOperations(workspaceSlug, projectId, issueId, issueServiceType);

View File

@@ -2,7 +2,7 @@
import React, { FC } from "react";
import { observer } from "mobx-react";
import { Plus } from "lucide-react";
import { EIssueServiceType } from "@plane/constants";
// plane imports
import { TIssueServiceType } from "@plane/types";
// hooks
import { useIssueDetail } from "@/hooks/store";
@@ -10,11 +10,11 @@ import { useIssueDetail } from "@/hooks/store";
type Props = {
customButton?: React.ReactNode;
disabled?: boolean;
issueServiceType?: TIssueServiceType;
issueServiceType: TIssueServiceType;
};
export const IssueLinksActionButton: FC<Props> = observer((props) => {
const { customButton, disabled = false, issueServiceType = EIssueServiceType.ISSUES } = props;
const { customButton, disabled = false, issueServiceType } = props;
// store hooks
const { toggleIssueLinkModal } = useIssueDetail(issueServiceType);

View File

@@ -1,7 +1,7 @@
"use client";
import React, { FC } from "react";
import { observer } from "mobx-react";
import { EIssueServiceType } from "@plane/constants";
// plane imports
import { TIssueServiceType } from "@plane/types";
import { Collapsible } from "@plane/ui";
// components
@@ -14,14 +14,13 @@ type Props = {
projectId: string;
issueId: string;
disabled?: boolean;
issueServiceType?: TIssueServiceType;
issueServiceType: TIssueServiceType;
};
export const LinksCollapsible: FC<Props> = observer((props) => {
const { workspaceSlug, projectId, issueId, disabled = false, issueServiceType = EIssueServiceType.ISSUES } = props;
const { workspaceSlug, projectId, issueId, disabled = false, issueServiceType } = props;
// store hooks
const { openWidgets, toggleOpenWidget } = useIssueDetail(issueServiceType);
// derived values
const isCollapsibleOpen = openWidgets.includes("links");

View File

@@ -1,7 +1,7 @@
"use client";
import React, { FC, useMemo } from "react";
import { observer } from "mobx-react";
import { EIssueServiceType } from "@plane/constants";
// plane imports
import { useTranslation } from "@plane/i18n";
import { TIssueServiceType } from "@plane/types";
import { CollapsibleButton } from "@plane/ui";
@@ -14,11 +14,12 @@ type Props = {
isOpen: boolean;
issueId: string;
disabled: boolean;
issueServiceType?: TIssueServiceType;
issueServiceType: TIssueServiceType;
};
export const IssueLinksCollapsibleTitle: FC<Props> = observer((props) => {
const { isOpen, issueId, disabled, issueServiceType = EIssueServiceType.ISSUES } = props;
const { isOpen, issueId, disabled, issueServiceType } = props;
// translation
const { t } = useTranslation();
// store hooks
const {

View File

@@ -2,7 +2,7 @@
import React, { FC } from "react";
import { observer } from "mobx-react";
import { Plus } from "lucide-react";
import { EIssueServiceType } from "@plane/constants";
// plane imports
import { useTranslation } from "@plane/i18n";
import { TIssueServiceType } from "@plane/types";
import { CustomMenu } from "@plane/ui";
@@ -16,11 +16,11 @@ type Props = {
issueId: string;
customButton?: React.ReactNode;
disabled?: boolean;
issueServiceType?: TIssueServiceType;
issueServiceType: TIssueServiceType;
};
export const RelationActionButton: FC<Props> = observer((props) => {
const { customButton, issueId, disabled = false, issueServiceType = EIssueServiceType.ISSUES } = props;
const { customButton, issueId, disabled = false, issueServiceType } = props;
const { t } = useTranslation();
// store hooks
const { toggleRelationModal, setRelationKey } = useIssueDetail(issueServiceType);

View File

@@ -1,7 +1,7 @@
"use client";
import React, { FC } from "react";
import { observer } from "mobx-react";
import { EIssueServiceType } from "@plane/constants";
// plane imports
import { TIssueServiceType } from "@plane/types";
import { Collapsible } from "@plane/ui";
// components
@@ -13,14 +13,13 @@ type Props = {
workspaceSlug: string;
issueId: string;
disabled?: boolean;
issueServiceType?: TIssueServiceType;
issueServiceType: TIssueServiceType;
};
export const RelationsCollapsible: FC<Props> = observer((props) => {
const { workspaceSlug, issueId, disabled = false, issueServiceType = EIssueServiceType.ISSUES } = props;
const { workspaceSlug, issueId, disabled = false, issueServiceType } = props;
// store hooks
const { openWidgets, toggleOpenWidget } = useIssueDetail(issueServiceType);
// derived values
const isCollapsibleOpen = openWidgets.includes("relations");

View File

@@ -1,5 +1,8 @@
"use client";
import React, { FC } from "react";
// plane imports
import { TIssueServiceType } from "@plane/types";
// components
import {
IssueDetailWidgetActionButtons,
@@ -7,16 +10,29 @@ import {
IssueDetailWidgetModals,
} from "@/components/issues/issue-detail-widgets";
export type TWorkItemWidgets = "sub-work-items" | "relations" | "links" | "attachments";
type Props = {
workspaceSlug: string;
projectId: string;
issueId: string;
disabled: boolean;
renderWidgetModals?: boolean;
issueServiceType: TIssueServiceType;
hideWidgets?: TWorkItemWidgets[];
};
export const IssueDetailWidgets: FC<Props> = (props) => {
const { workspaceSlug, projectId, issueId, disabled, renderWidgetModals = true } = props;
const {
workspaceSlug,
projectId,
issueId,
disabled,
renderWidgetModals = true,
issueServiceType,
hideWidgets,
} = props;
return (
<>
<div className="flex flex-col gap-5">
@@ -25,16 +41,25 @@ export const IssueDetailWidgets: FC<Props> = (props) => {
projectId={projectId}
issueId={issueId}
disabled={disabled}
issueServiceType={issueServiceType}
hideWidgets={hideWidgets}
/>
<IssueDetailWidgetCollapsibles
workspaceSlug={workspaceSlug}
projectId={projectId}
issueId={issueId}
disabled={disabled}
issueServiceType={issueServiceType}
hideWidgets={hideWidgets}
/>
</div>
{renderWidgetModals && (
<IssueDetailWidgetModals workspaceSlug={workspaceSlug} projectId={projectId} issueId={issueId} />
<IssueDetailWidgetModals
workspaceSlug={workspaceSlug}
projectId={projectId}
issueId={issueId}
issueServiceType={issueServiceType}
/>
)}
</>
);

View File

@@ -2,7 +2,7 @@
import React, { FC } from "react";
import { observer } from "mobx-react";
import { LayersIcon, Plus } from "lucide-react";
import { EIssueServiceType } from "@plane/constants";
// plane imports
import { useTranslation } from "@plane/i18n";
import { TIssue, TIssueServiceType } from "@plane/types";
import { CustomMenu } from "@plane/ui";
@@ -13,11 +13,12 @@ type Props = {
issueId: string;
customButton?: React.ReactNode;
disabled?: boolean;
issueServiceType?: TIssueServiceType;
issueServiceType: TIssueServiceType;
};
export const SubIssuesActionButton: FC<Props> = observer((props) => {
const { issueId, customButton, disabled = false, issueServiceType = EIssueServiceType.ISSUES } = props;
const { issueId, customButton, disabled = false, issueServiceType } = props;
// translation
const { t } = useTranslation();
// store hooks
const {

View File

@@ -1,7 +1,7 @@
"use client";
import React, { FC } from "react";
import { observer } from "mobx-react";
import { EIssueServiceType } from "@plane/constants";
// plane imports
import { TIssueServiceType } from "@plane/types";
import { Collapsible } from "@plane/ui";
// components
@@ -14,15 +14,13 @@ type Props = {
projectId: string;
issueId: string;
disabled?: boolean;
issueServiceType?: TIssueServiceType;
issueServiceType: TIssueServiceType;
};
export const SubIssuesCollapsible: FC<Props> = observer((props) => {
const { workspaceSlug, projectId, issueId, disabled = false, issueServiceType = EIssueServiceType.ISSUES } = props;
const { workspaceSlug, projectId, issueId, disabled = false, issueServiceType } = props;
// store hooks
const { openWidgets, toggleOpenWidget } = useIssueDetail(issueServiceType);
// derived state
const isCollapsibleOpen = openWidgets.includes("sub-issues");

View File

@@ -3,7 +3,6 @@
import { FC, useEffect } from "react";
import { observer } from "mobx-react";
import { Controller, useForm } from "react-hook-form";
import { EIssueServiceType } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
// plane types
import type { TIssueLinkEditableFields, TIssueServiceType } from "@plane/types";
@@ -24,7 +23,7 @@ export type TIssueLinkCreateEditModal = {
isModalOpen: boolean;
handleOnClose?: () => void;
linkOperations: TLinkOperationsModal;
issueServiceType?: TIssueServiceType;
issueServiceType: TIssueServiceType;
};
const defaultValues: TIssueLinkCreateFormFieldOptions = {
@@ -33,10 +32,9 @@ const defaultValues: TIssueLinkCreateFormFieldOptions = {
};
export const IssueLinkCreateUpdateModal: FC<TIssueLinkCreateEditModal> = observer((props) => {
const { isModalOpen, handleOnClose, linkOperations, issueServiceType } = props;
// i18n
const { t } = useTranslation();
// props
const { isModalOpen, handleOnClose, linkOperations, issueServiceType = EIssueServiceType.ISSUES } = props;
// react hook form
const {
formState: { errors, isSubmitting },

View File

@@ -1,11 +1,11 @@
import { FC } from "react";
import { observer } from "mobx-react";
import { EIssueServiceType } from "@plane/constants";
// plane imports
import { TIssueServiceType } from "@plane/types";
// computed
import { useIssueDetail } from "@/hooks/store";
// local imports
import { IssueLinkItem } from "./link-item";
// hooks
import { TLinkOperations } from "./root";
type TLinkOperationsModal = Exclude<TLinkOperations, "create">;
@@ -14,12 +14,12 @@ type TLinkList = {
issueId: string;
linkOperations: TLinkOperationsModal;
disabled?: boolean;
issueServiceType?: TIssueServiceType;
issueServiceType: TIssueServiceType;
};
export const LinkList: FC<TLinkList> = observer((props) => {
// props
const { issueId, linkOperations, disabled = false, issueServiceType = EIssueServiceType.ISSUES } = props;
const { issueId, linkOperations, disabled = false, issueServiceType } = props;
// hooks
const {
link: { getLinksByIssueId },

View File

@@ -2,15 +2,15 @@
import { FC, useCallback, useMemo, useState } from "react";
import { Plus } from "lucide-react";
// plane imports
import { EIssueServiceType } from "@plane/constants";
import { TIssueLink } from "@plane/types";
// hooks
import { TOAST_TYPE, setToast } from "@plane/ui";
// hooks
import { useIssueDetail } from "@/hooks/store";
// ui
// components
// local imports
import { IssueLinkCreateUpdateModal } from "./create-update-link-modal";
import { IssueLinkList } from "./links";
// types
export type TLinkOperations = {
create: (data: Partial<TIssueLink>) => Promise<void>;
@@ -90,7 +90,7 @@ export const IssueLinkRoot: FC<TIssueLinkRoot> = (props) => {
title: "Link removed",
});
toggleIssueLinkModal(false);
} catch (error) {
} catch {
setToast({
message: "The link could not be removed",
type: TOAST_TYPE.ERROR,
@@ -112,6 +112,7 @@ export const IssueLinkRoot: FC<TIssueLinkRoot> = (props) => {
isModalOpen={isIssueLinkModal}
handleOnClose={handleOnClose}
linkOperations={handleLinkOperations}
issueServiceType={EIssueServiceType.ISSUES}
/>
<div className="py-1 text-xs">

View File

@@ -3,6 +3,7 @@
import { useEffect, useRef, useState } from "react";
import { observer } from "mobx-react";
// plane imports
import { EIssueServiceType } from "@plane/constants";
import { EditorRefApi } from "@plane/editor";
import { TNameDescriptionLoader } from "@plane/types";
// components
@@ -179,6 +180,7 @@ export const IssueMainContent: React.FC<Props> = observer((props) => {
issueId={issueId}
disabled={!isEditable || isArchived}
renderWidgetModals={!isPeekModeActive}
issueServiceType={EIssueServiceType.ISSUES}
/>
{windowSize[0] < 768 && (

View File

@@ -199,6 +199,7 @@ export const IssueView: FC<IIssueView> = observer((props) => {
projectId={projectId}
issueId={issueId}
disabled={disabled || is_archived}
issueServiceType={EIssueServiceType.ISSUES}
/>
</div>
@@ -238,6 +239,7 @@ export const IssueView: FC<IIssueView> = observer((props) => {
projectId={projectId}
issueId={issueId}
disabled={disabled}
issueServiceType={EIssueServiceType.ISSUES}
/>
</div>