Page Menu
Home
Sealhub
Search
Configure Global Search
Log In
Files
F10360607
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/back/routes/admin/pages/[id]/edit.jdd-editor.tsx b/src/back/routes/admin/pages/[id]/edit.jdd-editor.tsx
new file mode 100644
index 0000000..88df822
--- /dev/null
+++ b/src/back/routes/admin/pages/[id]/edit.jdd-editor.tsx
@@ -0,0 +1,30 @@
+import type { Context } from "koa";
+import type { FieldNames } from "sealious";
+import { TempstreamJSX } from "tempstream";
+import type Pages from "src/back/collections/pages.js";
+import { EditJDDField } from "@sealcode/jdd-editor";
+import html from "src/back/html.js";
+import { registry } from "src/back/jdd-components/registry.js";
+import { makeJDDContext } from "src/back/jdd-context.js";
+import { defaultHead } from "src/back/defaultHead.js";
+
+export const actionName = "EditPateContent";
+
+export default new (class JDDCreatePreviewPage extends EditJDDField<Pages> {
+ getCollection(ctx: Context) {
+ return ctx.$app.collections["pages"];
+ }
+
+ getJDDFieldName(): FieldNames<Pages["fields"]> {
+ return "content";
+ }
+
+ async renderPreParameterButtons(ctx: Context) {
+ const item = await this.getItem(ctx);
+ return (
+ <div>
+ <h1>Edit pages: {item.id}</h1>{" "}
+ </div>
+ );
+ }
+})({ html, registry, makeJDDContext, defaultHead });
diff --git a/src/back/routes/admin/pages/index.list.tsx b/src/back/routes/admin/pages/index.list.tsx
index 501de8f..b93c3ef 100644
--- a/src/back/routes/admin/pages/index.list.tsx
+++ b/src/back/routes/admin/pages/index.list.tsx
@@ -1,185 +1,167 @@
import type { Context } from "koa";
import type { CollectionItem } from "sealious";
import type { FlatTemplatable, Templatable } from "tempstream";
import { TempstreamJSX, tempstream } from "tempstream";
import { Pages } from "src/back/collections/collections.js";
import html from "src/back/html.js";
import type { ListFilterRender } from "@sealcode/sealgen";
import {
SealiousItemListPage,
BaseListPageFields,
DefaultListFilters,
} from "@sealcode/sealgen";
import qs from "qs";
import {
PagesCRUDCreateURL,
PagesCRUDEditURL,
PagesCRUDDeleteURL,
EditPageContentURL,
} from "../../urls.js";
import type { FilePointer } from "@sealcode/file-manager";
import { imageRouter } from "src/back/image-router.js";
export const actionName = "PagesCRUDList";
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
-const filterFields = [
- { field: "url", ...DefaultListFilters["text"] },
- { field: "content", ...DefaultListFilters.fallback },
- { field: "domain", ...DefaultListFilters["text"] },
- { field: "title", ...DefaultListFilters["text"] },
- { field: "heading", ...DefaultListFilters["text"] },
- { field: "description", ...DefaultListFilters["text"] },
- { field: "imageForMetadata", ...DefaultListFilters.fallback },
- { field: "hideNavigation", ...DefaultListFilters["boolean"] },
-] as {
+const filterFields = [{ field: "title", ...DefaultListFilters["text"] }] as {
field: keyof (typeof Pages)["fields"];
render?: ListFilterRender;
prepareValue?: (filter_value: unknown) => unknown; // set this function to change what filter value is passed to Sealious
}[];
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const displayFields = [
{ field: "url", label: "url" },
- { field: "content", label: "content" },
- { field: "domain", label: "domain" },
{ field: "title", label: "title" },
- { field: "heading", label: "heading" },
- { field: "description", label: "description" },
{
field: "imageForMetadata",
label: "imageForMetadata",
format: async (value: FilePointer) => {
return imageRouter.image(await value.getPath(), {
container: { width: 45, height: 45 },
crop: { width: 45, height: 45 },
alt: "",
});
},
},
- {
- field: "hideNavigation",
- label: "hideNavigation",
- format: (v: boolean) => (v ? "YES" : "NO"),
- },
] as {
field: string;
label: string;
format?: (value: unknown, item: CollectionItem<typeof Pages>) => FlatTemplatable;
}[];
export default new (class PagesCRUDListPage extends SealiousItemListPage<
typeof Pages,
typeof BaseListPageFields
> {
fields = BaseListPageFields;
async renderFilters(ctx: Context): Promise<FlatTemplatable> {
const query_params = qs.parse(ctx.search.slice(1));
query_params.page = "1";
const filter_values = await super.getFilterValues(ctx);
return (
<form>
{Object.entries(query_params).map(([key, value]) => {
if (key == "filter") {
return "";
}
// this is necessary to not lose any query params when the user changes the filter values
return <input type="hidden" name={key} value={value} />;
})}
{filterFields.map(({ field, render }) => {
if (!render) {
render = DefaultListFilters.fallback.render;
}
return (
render(
filter_values[field] || "",
this.collection.fields[field]
) || ""
);
})}
<input type="submit" />
</form>
);
}
async getFilterValues(ctx: Context) {
// adding opportunity to adjust the values for a given field filter before it's sent to Sealious
const values = await super.getFilterValues(ctx);
for (const filterField of filterFields) {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const key = filterField.field as keyof typeof values;
if (key in values) {
const prepare_fn = filterField.prepareValue;
if (prepare_fn) {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment
values[key] = prepare_fn(values[key]) as any;
}
}
}
return values;
}
async renderItem(ctx: Context, item: CollectionItem<typeof Pages>) {
return (
<tr>
{displayFields.map(({ field, format }) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any
const value = item.get(field as any);
return <td>{format ? format(value, item) : value}</td>;
})}
<td>
<div class="sealious-list__actions">
<a href={PagesCRUDEditURL(item.id)}>Edit Metadata</a>
<a
data-turbo-method="POST"
data-turbo-confirm="Delete item?"
href={PagesCRUDDeleteURL(item.id)}
>
Delete
</a>
<a href={EditPageContentURL(item.id)}>Edit Content</a>
</div>
</td>
</tr>
);
}
renderListContainer(ctx: Context, content: Templatable): FlatTemplatable {
return (
<table class="sealious-list pages-crudlist-table">
{this.renderTableHead(ctx, displayFields)}
<tbody>{content}</tbody>
</table>
);
}
renderTableHead(
ctx: Context,
fields: { field: string; label?: string }[]
): FlatTemplatable {
return tempstream/* HTML */ `<thead>
<tr>
${fields.map(({ label, field }) => this.renderHeading(ctx, field, label))}
<th>Actions</th>
</tr>
</thead>`;
}
async render(ctx: Context) {
return html({
ctx,
title: "PagesCRUDList",
description: "",
body: (
<div class="sealious-list-wrapper pages-crudlist--wrapper">
<h2>PagesCRUDList List</h2>
<a href={PagesCRUDCreateURL}> Create </a>
{super.render(ctx)}
</div>
),
});
}
})(Pages);
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Nov 8, 07:50 (1 d, 10 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1034295
Default Alt Text
(7 KB)
Attached To
Mode
rPIWO PIWO 2025
Attached
Detach File
Event Timeline
Log In to Comment