This commit is contained in:
Tom Moor
2025-10-01 14:09:14 +02:00
parent e02ac64277
commit 1847baaa20
6 changed files with 109 additions and 15 deletions
-1
View File
@@ -182,7 +182,6 @@ function placeCaret(element: HTMLElement, atStart: boolean) {
}
const Content = styled.span`
background: ${s("background")};
color: ${s("text")};
-webkit-text-fill-color: ${s("text")};
outline: none;
+3 -3
View File
@@ -3,18 +3,18 @@ import { useCallback } from "react";
import { toast } from "sonner";
import useStores from "~/hooks/useStores";
import { TemplateForm } from "./TemplateForm";
import Template from "~/models/Template";
type Props = {
templateId: string;
template: Template;
onSubmit: () => void;
};
export const TemplateEdit = observer(function TemplateEdit_({
templateId,
template,
onSubmit,
}: Props) {
const { templates } = useStores();
const template = templates.get(templateId);
const handleSubmit = useCallback(async () => {
try {
+1 -1
View File
@@ -11,7 +11,7 @@ type Props = {
export const TemplateNew = observer(function TemplateNew_({ onSubmit }: Props) {
const { templates } = useStores();
const [template] = useState(new Template({}, templates));
const [template] = useState(new Template({ title: "" }, templates));
const handleSubmit = useCallback(async () => {
try {
+7 -1
View File
@@ -6,6 +6,7 @@ import lazy from "~/utils/lazyWithRetry";
import { settingsPath } from "~/utils/routeHelpers";
const Application = lazy(() => import("~/scenes/Settings/Application"));
const Template = lazy(() => import("~/scenes/Settings/Template"));
export default function SettingsRoutes() {
const configs = useSettingsConfig();
@@ -23,9 +24,14 @@ export default function SettingsRoutes() {
{/* TODO: Refactor these exceptions into config? */}
<Route
exact
path={`${settingsPath("applications")}/:id`}
path={settingsPath("applications", ":id")}
component={Application}
/>
<Route
exact
path={settingsPath("templates", ":id")}
component={Template}
/>
<Route component={Error404} />
</Switch>
);
+95
View File
@@ -0,0 +1,95 @@
import { observer } from "mobx-react";
import { CopyIcon, InternetIcon, ReplaceIcon, ShapesIcon } from "outline-icons";
import { useEffect, useCallback, useMemo } from "react";
import { Controller, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { useParams } from "react-router-dom";
import { toast } from "sonner";
import { OAuthClientValidation } from "@shared/validations";
import OAuthClient from "~/models/oauth/OAuthClient";
import Breadcrumb from "~/components/Breadcrumb";
import Button from "~/components/Button";
import ConfirmationDialog from "~/components/ConfirmationDialog";
import ContentEditable from "~/components/ContentEditable";
import Heading from "~/components/Heading";
import Input from "~/components/Input";
import LoadingIndicator from "~/components/LoadingIndicator";
import NudeButton from "~/components/NudeButton";
import { FormData } from "~/components/OAuthClient/OAuthClientForm";
import Scene from "~/components/Scene";
import Switch from "~/components/Switch";
import Tooltip from "~/components/Tooltip";
import useRequest from "~/hooks/useRequest";
import useStores from "~/hooks/useStores";
import OAuthClientMenu from "~/menus/OAuthClientMenu";
import isCloudHosted from "~/utils/isCloudHosted";
import { settingsPath } from "~/utils/routeHelpers";
import { ActionRow } from "./components/ActionRow";
import { CopyButton } from "./components/CopyButton";
import ImageInput from "./components/ImageInput";
import SettingRow from "./components/SettingRow";
import { createInternalLinkActionV2 } from "~/actions";
import { NavigationSection } from "~/actions/sections";
import Template from "~/models/Template";
import TemplateMenu from "~/menus/TemplateMenu";
import { TemplateForm } from "~/components/Template/TemplateForm";
import { TemplateNew } from "~/components/Template/TemplateNew";
import history from "~/utils/history";
import { TemplateEdit } from "~/components/Template/TemplateEdit";
type Props = {
template: Template;
};
const LoadingState = observer(function LoadingState() {
const { id } = useParams<{ id: string }>();
const { templates } = useStores();
const template = templates.get(id);
const { request } = useRequest(() => templates.fetch(id));
useEffect(() => {
if (!template) {
void request();
}
}, [template]);
if (!template) {
return <LoadingIndicator />;
}
return <TemplateSetting template={template} />;
});
const TemplateSetting = observer(function Template_({ template }: Props) {
const { t } = useTranslation();
const { dialogs } = useStores();
const breadcrumbActions = useMemo(
() => [
createInternalLinkActionV2({
name: t("Templates"),
section: NavigationSection,
icon: <ShapesIcon />,
to: settingsPath("templates"),
}),
],
[t]
);
const handleSave = useCallback(() => {
history.push(settingsPath("templates"));
}, []);
return (
<Scene
title={template.title}
left={<Breadcrumb actions={breadcrumbActions} />}
actions={<TemplateMenu template={template} />}
>
{template ? <TemplateEdit template={template} onSubmit={handleSave} /> : <TemplateNew onSubmit={handleSave} />}
</Scene>
);
});
export default LoadingState;
@@ -23,6 +23,8 @@ import Time from "~/components/Time";
import useStores from "~/hooks/useStores";
import TemplateMenu from "~/menus/TemplateMenu";
import { FILTER_HEIGHT } from "./StickyFilters";
import history from "~/utils/history";
import { settingsPath } from "~/utils/routeHelpers";
const ROW_HEIGHT = 60;
const STICKY_OFFSET = HEADER_HEIGHT + FILTER_HEIGHT;
@@ -35,15 +37,7 @@ export function TemplatesTable(props: Props) {
const { dialogs } = useStores();
const handleOpen = (template: Template) => () => {
dialogs.openModal({
title: "",
content: (
<TemplateEdit
templateId={template.id}
onSubmit={dialogs.closeAllModals}
/>
),
});
history.push(settingsPath("templates", template.id));
};
const columns = React.useMemo<TableColumn<Template>[]>(