wip checkpoint api server
This commit is contained in:
parent
2565814775
commit
058c84ad23
|
|
@ -1,17 +1,66 @@
|
||||||
import { forwardRef } from "react";
|
import { forwardRef } from "react";
|
||||||
import { useGlobal, useLocal } from "web-utils";
|
import { useGlobal, useLocal } from "web-utils";
|
||||||
import { EDGlobal } from "../../../logic/ed-global";
|
import { EDGlobal, PG } from "../../../logic/ed-global";
|
||||||
|
import { checkAPI, dev } from "./api-utils";
|
||||||
|
|
||||||
export const EdApiServer = forwardRef<HTMLDivElement>((arg, ref) => {
|
export const EdApiServer = forwardRef<HTMLDivElement>((arg, ref) => {
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
const local = useLocal({ api_url: p.site.config.api_url });
|
const local = useLocal(
|
||||||
|
{
|
||||||
|
api_url: p.site.config.api_url,
|
||||||
|
status: "offline" as "online" | "offline" | "checking",
|
||||||
|
deployable: false,
|
||||||
|
hasDB: false,
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
try {
|
||||||
|
if (dev) {
|
||||||
|
const vdev = JSON.parse(localStorage.getItem("prasi-dev") || "{}");
|
||||||
|
if (vdev) {
|
||||||
|
dev.url = vdev.url;
|
||||||
|
dev.enabled = vdev.enabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
check();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const check = () => {
|
||||||
|
local.status = "checking";
|
||||||
|
local.render();
|
||||||
|
const res = checkAPI(p);
|
||||||
|
if (res) {
|
||||||
|
local.hasDB = res.hasDB;
|
||||||
|
local.status = "online";
|
||||||
|
local.deployable = res.deployable;
|
||||||
|
local.render();
|
||||||
|
} else {
|
||||||
|
local.hasDB = false;
|
||||||
|
local.status = "offline";
|
||||||
|
local.deployable = false;
|
||||||
|
local.render();
|
||||||
|
}
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className="flex flex-col w-[400px] items-stretch bg-white min-h-[200px] -mx-[8px] -my-[3px] text-[14px]"
|
className="flex flex-col w-[400px] items-stretch bg-white -mx-[8px] -my-[3px] text-[14px]"
|
||||||
>
|
>
|
||||||
<div className="p-1">Server URL:</div>
|
<div className="flex justify-between items-center pr-1">
|
||||||
|
<div className="p-1">Server URL:</div>
|
||||||
|
<div className="text-[12px]">
|
||||||
|
{local.status === "online" && (
|
||||||
|
<div className="bg-green-700 px-2 text-white">ONLINE</div>
|
||||||
|
)}
|
||||||
|
{local.status === "offline" && (
|
||||||
|
<div className="text-white px-2 bg-slate-500">OFFLINE</div>
|
||||||
|
)}
|
||||||
|
{local.status === "checking" && (
|
||||||
|
<div className="text-blue-500">Checking...</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className="flex border-y">
|
<div className="flex border-y">
|
||||||
<div className="flex flex-1 p-1 ">
|
<div className="flex flex-1 p-1 ">
|
||||||
<input
|
<input
|
||||||
|
|
@ -27,18 +76,74 @@ export const EdApiServer = forwardRef<HTMLDivElement>((arg, ref) => {
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
type="text"
|
type="text"
|
||||||
className="outline-none focus:border-blue-500 flex-1"
|
className={cx(
|
||||||
|
"outline-none focus:border-blue-500 flex-1",
|
||||||
|
dev.enabled && "line-through opacity-30"
|
||||||
|
)}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
e.currentTarget.blur();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onBlur={check}
|
||||||
placeholder="https://..."
|
placeholder="https://..."
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{local.api_url !== p.site.config.api_url && (
|
|
||||||
<div className="p-1 flex w-[80px] border-l">
|
|
||||||
<div className="bg-blue-500 hover:bg-blue-300 cursor-pointer flex-1 flex items-center justify-center text-white">
|
|
||||||
Check
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
className={cx(
|
||||||
|
"flex items-stretch h-[30px] border border-t-0",
|
||||||
|
dev.enabled ? " bg-green-50" : ""
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={cx(
|
||||||
|
"border cursor-pointer m-1 flex items-center px-2 space-x-1 w-[70px] justify-center",
|
||||||
|
!dev.enabled
|
||||||
|
? "hover:bg-green-50 hover:border-green-700 hover:text-green-700 text-slate-500 "
|
||||||
|
: "bg-green-700 text-white border-green-700"
|
||||||
|
)}
|
||||||
|
onClick={async () => {
|
||||||
|
dev.enabled = !dev.enabled;
|
||||||
|
localStorage.setItem("prasi-dev", JSON.stringify(dev));
|
||||||
|
local.render();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span>DEV</span>{" "}
|
||||||
|
{dev.enabled && <span className="text-white">ON</span>}
|
||||||
|
{!dev.enabled && <span className="text-slate-300">OFF</span>}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className={cx(
|
||||||
|
"px-1 m-1 border flex-1 font-mono text-[11px] outline-none focus:border-blue-500",
|
||||||
|
dev.enabled && "border-green-700"
|
||||||
|
)}
|
||||||
|
value={dev.url}
|
||||||
|
onChange={(e) => {
|
||||||
|
dev.url = e.currentTarget.value;
|
||||||
|
localStorage.setItem("prasi-dev", JSON.stringify(dev));
|
||||||
|
local.render();
|
||||||
|
}}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
e.currentTarget.blur();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onBlur={check}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{local.status === "online" && (
|
||||||
|
<>
|
||||||
|
{!local.deployable && !local.hasDB && (
|
||||||
|
<div className="h-[50px] flex items-center justify-center text-slate-400 text-center">
|
||||||
|
This server is not deployable <br />
|
||||||
|
and do not have DB
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { PG } from "../../../logic/ed-global";
|
||||||
|
|
||||||
|
export const dev = JSON.parse(localStorage.getItem("prasi-dev") || "{}") as {
|
||||||
|
enabled: boolean;
|
||||||
|
url: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const apiUrl = function (p: PG): string {
|
||||||
|
if (dev.enabled) {
|
||||||
|
return dev.url;
|
||||||
|
}
|
||||||
|
return p.site.config.api_url;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const checkAPI = (p: PG) => {
|
||||||
|
const url = apiUrl(p);
|
||||||
|
if (!url) return null;
|
||||||
|
|
||||||
|
return { deployable: false, hasDB: false };
|
||||||
|
};
|
||||||
|
|
@ -9,61 +9,75 @@ export const EdSiteHead = ({
|
||||||
reload,
|
reload,
|
||||||
orglen,
|
orglen,
|
||||||
conf,
|
conf,
|
||||||
|
local,
|
||||||
}: {
|
}: {
|
||||||
orglen: number;
|
orglen: number;
|
||||||
group: NodeModel<SiteGroupItem>[];
|
group: NodeModel<SiteGroupItem>[];
|
||||||
update: (val: NodeModel<SiteGroupItem>[]) => void;
|
update: (val: NodeModel<SiteGroupItem>[]) => void;
|
||||||
reload: (id?: string) => Promise<void>;
|
reload: (id?: string) => Promise<void>;
|
||||||
conf: { group: any };
|
conf: { group: any };
|
||||||
|
local: { search: string; render: () => void };
|
||||||
}) => {
|
}) => {
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="border-b text-[20px] pt-[10px] pb-[5px] pl-1 flex items-center">
|
<div className="border-b text-[20px] pt-[10px] pb-[5px] pl-1 flex items-center justify-between">
|
||||||
<div>
|
<div className="flex items-center">
|
||||||
{orglen} Organization{orglen > 1 ? "s" : ""}
|
<div>
|
||||||
</div>
|
{orglen} Organization{orglen > 1 ? "s" : ""}
|
||||||
<div
|
</div>
|
||||||
className="text-[12px] bg-white border rounded ml-2 px-2 hover:bg-blue-100 cursor-pointer flex items-center space-x-1 "
|
|
||||||
onClick={async () => {
|
|
||||||
const neworg = prompt("New Organization Name");
|
|
||||||
if (neworg) {
|
|
||||||
const res = await db.org.create({
|
|
||||||
data: {
|
|
||||||
name: neworg,
|
|
||||||
org_user: {
|
|
||||||
create: { id_user: p.user.id, role: "owner" },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
update([]);
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
reload(res.id);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
dangerouslySetInnerHTML={{
|
className="text-[12px] bg-white border rounded ml-2 px-2 hover:bg-blue-100 cursor-pointer flex items-center space-x-1 "
|
||||||
__html: `<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2 3.5C2 3.22386 2.22386 3 2.5 3H12.5C12.7761 3 13 3.22386 13 3.5V9.5C13 9.77614 12.7761 10 12.5 10H2.5C2.22386 10 2 9.77614 2 9.5V3.5ZM2 10.9146C1.4174 10.7087 1 10.1531 1 9.5V3.5C1 2.67157 1.67157 2 2.5 2H12.5C13.3284 2 14 2.67157 14 3.5V9.5C14 10.1531 13.5826 10.7087 13 10.9146V11.5C13 12.3284 12.3284 13 11.5 13H3.5C2.67157 13 2 12.3284 2 11.5V10.9146ZM12 11V11.5C12 11.7761 11.7761 12 11.5 12H3.5C3.22386 12 3 11.7761 3 11.5V11H12ZM5 6.5C5 6.22386 5.22386 6 5.5 6H7V4.5C7 4.22386 7.22386 4 7.5 4C7.77614 4 8 4.22386 8 4.5V6H9.5C9.77614 6 10 6.22386 10 6.5C10 6.77614 9.77614 7 9.5 7H8V8.5C8 8.77614 7.77614 9 7.5 9C7.22386 9 7 8.77614 7 8.5V7H5.5C5.22386 7 5 6.77614 5 6.5Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>`,
|
onClick={async () => {
|
||||||
}}
|
const neworg = prompt("New Organization Name");
|
||||||
></div>
|
if (neworg) {
|
||||||
<div>New</div>
|
const res = await db.org.create({
|
||||||
</div>
|
data: {
|
||||||
|
name: neworg,
|
||||||
|
org_user: {
|
||||||
|
create: { id_user: p.user.id, role: "owner" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
<div
|
update([]);
|
||||||
className={cx(
|
|
||||||
"text-[12px] bg-white border rounded px-2 hover:bg-blue-100 cursor-pointer flex items-center ml-1 space-x-1 "
|
setTimeout(() => {
|
||||||
)}
|
reload(res.id);
|
||||||
onClick={() => {
|
});
|
||||||
conf.group = null;
|
}
|
||||||
reload();
|
}}
|
||||||
}}
|
>
|
||||||
>
|
<div
|
||||||
Refresh
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: `<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2 3.5C2 3.22386 2.22386 3 2.5 3H12.5C12.7761 3 13 3.22386 13 3.5V9.5C13 9.77614 12.7761 10 12.5 10H2.5C2.22386 10 2 9.77614 2 9.5V3.5ZM2 10.9146C1.4174 10.7087 1 10.1531 1 9.5V3.5C1 2.67157 1.67157 2 2.5 2H12.5C13.3284 2 14 2.67157 14 3.5V9.5C14 10.1531 13.5826 10.7087 13 10.9146V11.5C13 12.3284 12.3284 13 11.5 13H3.5C2.67157 13 2 12.3284 2 11.5V10.9146ZM12 11V11.5C12 11.7761 11.7761 12 11.5 12H3.5C3.22386 12 3 11.7761 3 11.5V11H12ZM5 6.5C5 6.22386 5.22386 6 5.5 6H7V4.5C7 4.22386 7.22386 4 7.5 4C7.77614 4 8 4.22386 8 4.5V6H9.5C9.77614 6 10 6.22386 10 6.5C10 6.77614 9.77614 7 9.5 7H8V8.5C8 8.77614 7.77614 9 7.5 9C7.22386 9 7 8.77614 7 8.5V7H5.5C5.22386 7 5 6.77614 5 6.5Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>`,
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
<div>New</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={cx(
|
||||||
|
"text-[12px] bg-white border rounded px-2 hover:bg-blue-100 cursor-pointer flex items-center ml-1 space-x-1 "
|
||||||
|
)}
|
||||||
|
onClick={() => {
|
||||||
|
conf.group = null;
|
||||||
|
reload();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Refresh
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<input
|
||||||
|
type="search"
|
||||||
|
value={local.search}
|
||||||
|
placeholder="Search..."
|
||||||
|
className="outline-none mr-2 border focus:border-blue-500 "
|
||||||
|
onChange={(e) => {
|
||||||
|
local.search = e.currentTarget.value;
|
||||||
|
local.render();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,9 @@ const SitePicker = ({
|
||||||
update: (val: NodeModel<SiteGroupItem>[]) => void;
|
update: (val: NodeModel<SiteGroupItem>[]) => void;
|
||||||
reload: (id?: string) => Promise<void>;
|
reload: (id?: string) => Promise<void>;
|
||||||
}) => {
|
}) => {
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const local = useLocal({
|
||||||
|
search: "",
|
||||||
|
});
|
||||||
const orglen = group.filter((e) => e.parent === "site-root").length;
|
const orglen = group.filter((e) => e.parent === "site-root").length;
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-1 flex-col">
|
<div className="flex flex-1 flex-col">
|
||||||
|
|
@ -171,6 +173,7 @@ const SitePicker = ({
|
||||||
reload={reload}
|
reload={reload}
|
||||||
orglen={orglen}
|
orglen={orglen}
|
||||||
conf={conf}
|
conf={conf}
|
||||||
|
local={local}
|
||||||
/>
|
/>
|
||||||
<EdSiteTree
|
<EdSiteTree
|
||||||
group={group}
|
group={group}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
import get from "lodash.get";
|
|
||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { useGlobal, useLocal } from "web-utils";
|
import { useGlobal, useLocal } from "web-utils";
|
||||||
import { initApi } from "../../../../../../utils/script/init-api";
|
|
||||||
import { Loading } from "../../../../../../utils/ui/loading";
|
import { Loading } from "../../../../../../utils/ui/loading";
|
||||||
import { EditorGlobal } from "../../../../logic/global";
|
import { EditorGlobal } from "../../../../logic/global";
|
||||||
import { ExternalAPI } from "./External";
|
import { ExternalAPI } from "./External";
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue