| import React, { useState, useEffect, memo } from "react"; |
| import { X } from "@phosphor-icons/react"; |
| import { useTranslation } from "react-i18next"; |
| import { useParams } from "react-router-dom"; |
| import Workspace from "../../../models/workspace"; |
| import System from "../../../models/system"; |
| import { isMobile } from "react-device-detect"; |
| import useUser from "../../../hooks/useUser"; |
| import DocumentSettings from "./Documents"; |
| import DataConnectors from "./DataConnectors"; |
| import ModalWrapper from "@/components/ModalWrapper"; |
|
|
| const noop = () => {}; |
| const ManageWorkspace = ({ hideModal = noop, providedSlug = null }) => { |
| const { t } = useTranslation(); |
| const { slug } = useParams(); |
| const { user } = useUser(); |
| const [workspace, setWorkspace] = useState(null); |
| const [settings, setSettings] = useState({}); |
| const [selectedTab, setSelectedTab] = useState("documents"); |
|
|
| useEffect(() => { |
| async function getSettings() { |
| const _settings = await System.keys(); |
| setSettings(_settings ?? {}); |
| } |
| getSettings(); |
| }, []); |
|
|
| useEffect(() => { |
| async function fetchWorkspace() { |
| const workspace = await Workspace.bySlug(providedSlug ?? slug); |
| setWorkspace(workspace); |
| } |
| fetchWorkspace(); |
| }, [providedSlug, slug]); |
|
|
| if (!workspace) return null; |
|
|
| if (isMobile) { |
| return ( |
| <ModalWrapper isOpen={true}> |
| <div className="w-full max-w-2xl bg-theme-bg-secondary rounded-lg shadow border-2 border-theme-modal-border overflow-hidden"> |
| <div className="relative p-6 border-b rounded-t border-theme-modal-border"> |
| <div className="w-full flex gap-x-2 items-center"> |
| <h3 className="text-xl font-semibold text-white overflow-hidden overflow-ellipsis whitespace-nowrap"> |
| {t("connectors.manage.editing")} "{workspace.name}" |
| </h3> |
| </div> |
| <button |
| onClick={hideModal} |
| type="button" |
| className="absolute top-4 right-4 transition-all duration-300 bg-transparent rounded-lg text-sm p-1 inline-flex items-center hover:bg-theme-modal-border hover:border-theme-modal-border hover:border-opacity-50 border-transparent border" |
| > |
| <X size={24} weight="bold" className="text-white" /> |
| </button> |
| </div> |
| <div |
| className="h-full w-full overflow-y-auto" |
| style={{ maxHeight: "calc(100vh - 200px)" }} |
| > |
| <div className="py-7 px-9 space-y-2 flex-col"> |
| <p className="text-white"> |
| {t("connectors.manage.desktop-only")} |
| </p> |
| </div> |
| </div> |
| <div className="flex w-full justify-end items-center p-6 space-x-2 border-t border-theme-modal-border rounded-b"> |
| <button |
| onClick={hideModal} |
| type="button" |
| className="transition-all duration-300 bg-white text-black hover:opacity-60 px-4 py-2 rounded-lg text-sm" |
| > |
| {t("connectors.manage.dismiss")} |
| </button> |
| </div> |
| </div> |
| </ModalWrapper> |
| ); |
| } |
|
|
| return ( |
| <div className="w-screen h-screen fixed top-0 left-0 flex justify-center items-center z-99"> |
| <div className="backdrop h-full w-full absolute top-0 z-10" /> |
| <div className="absolute max-h-full w-fit transition duration-300 z-20 md:overflow-y-auto py-10"> |
| <div className="relative bg-theme-bg-secondary rounded-[12px] shadow border-2 border-theme-modal-border"> |
| <div className="flex items-start justify-between p-2 rounded-t border-theme-modal-border relative"> |
| <button |
| onClick={hideModal} |
| type="button" |
| className="z-29 text-white bg-transparent rounded-lg text-sm p-1.5 ml-auto inline-flex items-center bg-sidebar-button hover:bg-theme-modal-border hover:border-theme-modal-border hover:border-opacity-50 border-transparent border" |
| > |
| <X size={20} weight="bold" className="text-white" /> |
| </button> |
| </div> |
| |
| {user?.role !== "default" && ( |
| <ModalTabSwitcher |
| selectedTab={selectedTab} |
| setSelectedTab={setSelectedTab} |
| /> |
| )} |
| |
| {selectedTab === "documents" ? ( |
| <DocumentSettings workspace={workspace} systemSettings={settings} /> |
| ) : ( |
| <DataConnectors workspace={workspace} systemSettings={settings} /> |
| )} |
| </div> |
| </div> |
| </div> |
| ); |
| }; |
|
|
| export default memo(ManageWorkspace); |
|
|
| const ModalTabSwitcher = ({ selectedTab, setSelectedTab }) => { |
| const { t } = useTranslation(); |
| return ( |
| <div className="w-full flex justify-center z-10 relative"> |
| <div className="gap-x-2 flex justify-center -mt-[68px] mb-10 bg-theme-bg-secondary p-1 rounded-xl shadow border-2 border-theme-modal-border w-fit"> |
| <button |
| onClick={() => setSelectedTab("documents")} |
| className={`border-none px-4 py-2 rounded-[8px] font-semibold hover:bg-theme-modal-border hover:bg-opacity-60 ${ |
| selectedTab === "documents" |
| ? "bg-theme-modal-border font-bold text-white light:bg-[#E0F2FE] light:text-[#026AA2]" |
| : "text-white/20 font-medium hover:text-white light:bg-white light:text-[#535862] light:hover:bg-[#E0F2FE]" |
| }`} |
| > |
| {t("connectors.manage.documents")} |
| </button> |
| <button |
| onClick={() => setSelectedTab("dataConnectors")} |
| className={`border-none px-4 py-2 rounded-[8px] font-semibold hover:bg-theme-modal-border hover:bg-opacity-60 ${ |
| selectedTab === "dataConnectors" |
| ? "bg-theme-modal-border font-bold text-white light:bg-[#E0F2FE] light:text-[#026AA2]" |
| : "text-white/20 font-medium hover:text-white light:bg-white light:text-[#535862] light:hover:bg-[#E0F2FE]" |
| }`} |
| > |
| {t("connectors.manage.data-connectors")} |
| </button> |
| </div> |
| </div> |
| ); |
| }; |
|
|
| export function useManageWorkspaceModal() { |
| const { user } = useUser(); |
| const [showing, setShowing] = useState(false); |
|
|
| function showModal() { |
| if (user?.role !== "default") { |
| setShowing(true); |
| } |
| } |
|
|
| function hideModal() { |
| setShowing(false); |
| } |
|
|
| useEffect(() => { |
| function onEscape(event) { |
| if (!showing || event.key !== "Escape") return; |
| setShowing(false); |
| } |
|
|
| document.addEventListener("keydown", onEscape); |
| return () => { |
| document.removeEventListener("keydown", onEscape); |
| }; |
| }, [showing]); |
|
|
| return { showing, showModal, hideModal }; |
| } |
|
|