You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
6.4 KiB

11 months ago
11 months ago
11 months ago
  1. import React, { useState, useEffect, memo } from "react";
  2. import { X } from "@phosphor-icons/react";
  3. import { useParams } from "react-router-dom";
  4. import Workspace from "../../../models/workspace";
  5. import System from "../../../models/system";
  6. import { isMobile } from "react-device-detect";
  7. import useUser from "../../../hooks/useUser";
  8. import DocumentSettings from "./Documents";
  9. import DataConnectors from "./DataConnectors";
  10. import ModalWrapper from "@/components/ModalWrapper";
  11. const noop = () => {};
  12. const ManageWorkspace = ({ hideModal = noop, providedSlug = null }) => {
  13. const { slug } = useParams();
  14. const { user } = useUser();
  15. const [workspace, setWorkspace] = useState(null);
  16. const [settings, setSettings] = useState({});
  17. const [selectedTab, setSelectedTab] = useState("documents");
  18. useEffect(() => {
  19. async function getSettings() {
  20. const _settings = await System.keys();
  21. setSettings(_settings ?? {});
  22. }
  23. getSettings();
  24. }, []);
  25. useEffect(() => {
  26. async function fetchWorkspace() {
  27. const workspace = await Workspace.bySlug(providedSlug ?? slug);
  28. setWorkspace(workspace);
  29. }
  30. fetchWorkspace();
  31. }, [providedSlug, slug]);
  32. if (!workspace) return null;
  33. if (isMobile) {
  34. return (
  35. <ModalWrapper isOpen={true}>
  36. <div className="w-full max-w-2xl bg-theme-bg-secondary rounded-lg shadow border-2 border-theme-modal-border overflow-hidden">
  37. <div className="relative p-6 border-b rounded-t border-theme-modal-border">
  38. <div className="w-full flex gap-x-2 items-center">
  39. <h3 className="text-xl font-semibold text-white overflow-hidden overflow-ellipsis whitespace-nowrap">
  40. Editing "{workspace.name}"
  41. </h3>
  42. </div>
  43. <button
  44. onClick={hideModal}
  45. type="button"
  46. 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"
  47. >
  48. <X size={24} weight="bold" className="text-white" />
  49. </button>
  50. </div>
  51. <div
  52. className="h-full w-full overflow-y-auto"
  53. style={{ maxHeight: "calc(100vh - 200px)" }}
  54. >
  55. <div className="py-7 px-9 space-y-2 flex-col">
  56. <p className="text-white">
  57. Editing these settings are only available on a desktop device.
  58. Please access this page on your desktop to continue.
  59. </p>
  60. </div>
  61. </div>
  62. <div className="flex w-full justify-end items-center p-6 space-x-2 border-t border-theme-modal-border rounded-b">
  63. <button
  64. onClick={hideModal}
  65. type="button"
  66. className="transition-all duration-300 bg-white text-black hover:opacity-60 px-4 py-2 rounded-lg text-sm"
  67. >
  68. Dismiss
  69. </button>
  70. </div>
  71. </div>
  72. </ModalWrapper>
  73. );
  74. }
  75. return (
  76. <div className="w-screen h-screen fixed top-0 left-0 flex justify-center items-center z-99">
  77. <div className="backdrop h-full w-full absolute top-0 z-10" />
  78. <div className="absolute max-h-full w-fit transition duration-300 z-20 md:overflow-y-auto py-10">
  79. <div className="relative bg-theme-bg-secondary rounded-[12px] shadow border-2 border-theme-modal-border">
  80. <div className="flex items-start justify-between p-2 rounded-t border-theme-modal-border relative">
  81. <button
  82. onClick={hideModal}
  83. type="button"
  84. 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"
  85. >
  86. <X size={20} weight="bold" className="text-white" />
  87. </button>
  88. </div>
  89. {user?.role !== "default" && (
  90. <ModalTabSwitcher
  91. selectedTab={selectedTab}
  92. setSelectedTab={setSelectedTab}
  93. />
  94. )}
  95. {selectedTab === "documents" ? (
  96. <DocumentSettings workspace={workspace} systemSettings={settings} />
  97. ) : (
  98. <DataConnectors workspace={workspace} systemSettings={settings} />
  99. )}
  100. </div>
  101. </div>
  102. </div>
  103. );
  104. };
  105. export default memo(ManageWorkspace);
  106. const ModalTabSwitcher = ({ selectedTab, setSelectedTab }) => {
  107. return (
  108. <div className="w-full flex justify-center z-10 relative">
  109. <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">
  110. <button
  111. onClick={() => setSelectedTab("documents")}
  112. className={`border-none px-4 py-2 rounded-[8px] font-semibold hover:bg-theme-modal-border hover:bg-opacity-60 ${
  113. selectedTab === "documents"
  114. ? "bg-theme-modal-border font-bold text-white light:bg-[#E0F2FE] light:text-[#026AA2]"
  115. : "text-white/20 font-medium hover:text-white light:bg-white light:text-[#535862] light:hover:bg-[#E0F2FE]"
  116. }`}
  117. >
  118. 文档
  119. </button>
  120. <button
  121. onClick={() => setSelectedTab("dataConnectors")}
  122. className={`border-none px-4 py-2 rounded-[8px] font-semibold hover:bg-theme-modal-border hover:bg-opacity-60 ${
  123. selectedTab === "dataConnectors"
  124. ? "bg-theme-modal-border font-bold text-white light:bg-[#E0F2FE] light:text-[#026AA2]"
  125. : "text-white/20 font-medium hover:text-white light:bg-white light:text-[#535862] light:hover:bg-[#E0F2FE]"
  126. }`}
  127. >
  128. 数据连接器
  129. </button>
  130. </div>
  131. </div>
  132. );
  133. };
  134. export function useManageWorkspaceModal() {
  135. const { user } = useUser();
  136. const [showing, setShowing] = useState(false);
  137. function showModal() {
  138. if (user?.role !== "default") {
  139. setShowing(true);
  140. }
  141. }
  142. function hideModal() {
  143. setShowing(false);
  144. }
  145. useEffect(() => {
  146. function onEscape(event) {
  147. if (!showing || event.key !== "Escape") return;
  148. setShowing(false);
  149. }
  150. document.addEventListener("keydown", onEscape);
  151. return () => {
  152. document.removeEventListener("keydown", onEscape);
  153. };
  154. }, [showing]);
  155. return { showing, showModal, hideModal };
  156. }