diff --git a/webapp/openapi-playground/mod/openapi/OperationView.tsx b/webapp/openapi-playground/mod/openapi/OperationView.tsx
index 4bea8b24..b8f981df 100644
--- a/webapp/openapi-playground/mod/openapi/OperationView.tsx
+++ b/webapp/openapi-playground/mod/openapi/OperationView.tsx
@@ -5,6 +5,7 @@ import { Box, styled } from "@innoai-tech/vueuikit";
import { ResponseView } from "./ResponseView.tsx";
import { RequestBuilder } from "./RequestBuilder.tsx";
import { Markdown } from "@innoai-tech/vuemarkdown";
+import { DatabaseErContainer } from "./components/DatabaseErView.tsx";
export const OperationView = component$({
operationId: t.string()
@@ -87,24 +88,32 @@ export const OperationView = component$({
if (!op) {
return null;
}
+ if (op.operationId == "SycDatabaseEr") {
+ return (
+
+ {$heading}
+ {$desc}
+
+
+
+
+ )
+ }
+
return (
{$heading}
{$desc}
-
+
{$requestBuilder}
-
+
);
})
@@ -118,6 +127,16 @@ const OperationContainer = styled("div")({
alignItems: "stretch"
});
+
+const OperationMain = styled("div")({
+ flex: 1,
+ overflow: "hidden",
+ display: "flex",
+ flexDirection: "column",
+ alignItems: "stretch"
+});
+
+
const OperationHeading = styled("div")({
display: "flex",
alignItems: "center",
diff --git a/webapp/openapi-playground/mod/openapi/components/DatabaseErView.tsx b/webapp/openapi-playground/mod/openapi/components/DatabaseErView.tsx
new file mode 100644
index 00000000..758c0562
--- /dev/null
+++ b/webapp/openapi-playground/mod/openapi/components/DatabaseErView.tsx
@@ -0,0 +1,241 @@
+import { component, component$, rx } from "@innoai-tech/vuekit";
+import type { OperationWithMethodPath } from "../models";
+import { OpenAPIProvider } from "../OpenAPIProvider.tsx";
+import { onMounted } from "vue";
+import { alpha, styled, variant } from "@innoai-tech/vueuikit";
+import { Icon, mdiKey } from "@innoai-tech/vuematerial";
+import { mdiKeyOutline } from "@mdi/js";
+
+export type ErDatabase = {
+ name: string
+ tables: Record
+}
+
+export type ErTable = {
+ title?: string
+ description?: string
+ columns: Record
+ constraints: Record
+}
+
+export type ErColumn = {
+ type: string
+ title?: string
+ description?: string
+ of?: string
+}
+
+export type ErConstraint = {
+ title?: string
+ description?: string
+ columnNames: Array
+ method?: string
+ unique?: boolean
+ primary?: boolean
+}
+
+
+export const DatabaseErContainer = component$<{
+ op: OperationWithMethodPath
+}>((props, { render }) => {
+
+ const openapi$ = OpenAPIProvider.use();
+
+ onMounted(() => {
+ openapi$.request(props.op.operationId, {});
+ });
+
+ return rx(
+ openapi$.response$(props.op.operationId),
+ render((resp) => {
+ return ;
+ })
+ );
+});
+
+export const DatabaseErView = component<{
+ database: ErDatabase
+}>((props) => {
+ return () => {
+ return (
+
+
+ {props.database.name}
+
+ {Object.keys(props.database.tables).toSorted().map((tableName) => {
+ const t = props.database.tables[tableName] ?? { columns: {}, constraints: {} };
+
+ const columns = t.columns;
+ const constraints = t.constraints;
+
+ return (
+
+
+
+ {tableName}
+
+
+
+ {t.title}
+
+
+ {Object.keys(columns).toSorted().map((colName) => {
+ const col = columns[colName]!;
+
+ return (
+
+
+ {colName}
+
+ {col.of ? (
+
+ {col.of}
+
+ ) : (
+
+ {col.type}
+
+ )}
+
+ {col.title}
+
+
+ );
+ })}
+
+ {Object.entries(constraints).toSorted(([name1, c1], [name2, c2]) => {
+ if (c2.primary && !c1.primary) {
+ return 1;
+ }
+
+ if (!c2.primary && c1.primary) {
+ return -1;
+ }
+
+ if (c2.unique && !c1.unique) {
+ return 1;
+ }
+
+ if (!c2.unique && c1.unique) {
+ return -1;
+ }
+
+ return name1.localeCompare(name2);
+ }).map(([constraintName, constraint]) => {
+
+ return (
+
+
+
+
+ {constraintName}
+
+
+ ({constraint.columnNames.join(",")})
+
+
+
+ );
+ })}
+
+ );
+ })}
+
+ );
+ };
+});
+
+
+const DatabaseErMain = styled("div")({
+ py: 18,
+ px: 24,
+ flex: 1,
+ overflow: "auto"
+});
+
+const DatabaseErHeader = styled("div")({
+ py: 8,
+ px: 16,
+ textStyle: "sys.label-large"
+});
+
+
+const DatabaseErTable = styled("details")({
+ "& + &": {
+ mt: 16
+ },
+
+ rounded: "sm",
+ border: "1px solid",
+ borderColor: variant("sys.outline-variant", alpha(0.38)),
+ overflow: "hidden"
+});
+
+const DatabaseErTableSummary = styled("summary")({
+ textStyle: "sys.label-large",
+ py: 8,
+ px: 16,
+ display: "flex",
+ color: "sys.primary"
+});
+
+
+const DatabaseErTableDef = styled("div")({
+ px: 16,
+ py: 4,
+ display: "flex",
+ "&:hover": {
+ containerStyle: "sys.surface-container-low"
+ }
+});
+
+
+export const DatabaseErTableColumnName = styled("div")({
+ display: "flex",
+ width: "20vw",
+ textStyle: "sys.label-small",
+ font: "code"
+});
+
+
+export const DatabaseErTableColumnComment = styled("div")({
+ display: "flex",
+ textStyle: "sys.label-small",
+ width: "20vw",
+ justifyContent: "end"
+});
+
+export const DatabaseErTableColumnOf = styled("div")({
+ flex: 1,
+ textStyle: "sys.label-small",
+ font: "code",
+ color: "sys.primary"
+});
+
+
+export const DatabaseErTableColumnType = styled("div")({
+ flex: 1,
+ textStyle: "sys.label-small"
+});
+
+
+export const DatabaseErTableConstraintName = styled("div")({
+ flex: 1,
+ textStyle: "sys.label-small",
+ font: "code",
+ display: "flex",
+ alignItems: "center",
+ gap: "1em",
+
+ _primary: {
+ [`${Icon}`]: {
+ color: "sys.primary"
+ }
+ }
+});
+
+const Spacer = styled("div")({
+ flex: 1
+});
\ No newline at end of file