Working webpack config
parent
6dea12aea3
commit
299c5b72cc
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,29 @@
|
|||||||
|
html {
|
||||||
|
background: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
max-width: 1024px;
|
||||||
|
margin: 1rem auto;
|
||||||
|
background: white;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task {
|
||||||
|
list-style: none;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task input[type="checkbox"] {
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-button {
|
||||||
|
height: 1rem;
|
||||||
|
padding: 0;
|
||||||
|
line-height: 0;
|
||||||
|
padding: 0.5rem;
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
export default function frame(id: string, body: string) {
|
||||||
|
return /* HTML */ `<turbo-frame id="${id}"> ${body} </turbo-frame>`;
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
export default function html(body: string): string {
|
||||||
|
return /* HTML */ `<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<link href="/style.css" rel="stylesheet" type="text/css" />
|
||||||
|
${body}
|
||||||
|
<script type="module">
|
||||||
|
import hotwiredTurbo from "https://cdn.skypack.dev/@hotwired/turbo";
|
||||||
|
</script>
|
||||||
|
<script src="/bundle.js"></script>
|
||||||
|
</html>`;
|
||||||
|
}
|
@ -0,0 +1,147 @@
|
|||||||
|
import _locreq from "locreq";
|
||||||
|
import { resolve } from "path";
|
||||||
|
import Sealious, {
|
||||||
|
App,
|
||||||
|
Collection,
|
||||||
|
Context,
|
||||||
|
FieldTypes,
|
||||||
|
Policies,
|
||||||
|
Middlewares,
|
||||||
|
CollectionItem,
|
||||||
|
} from "sealious";
|
||||||
|
import frame from "./frame";
|
||||||
|
import html from "./html";
|
||||||
|
const locreq = _locreq(__dirname);
|
||||||
|
|
||||||
|
declare module "koa" {
|
||||||
|
interface BaseContext {
|
||||||
|
$context: Sealious.Context;
|
||||||
|
$app: Sealious.App;
|
||||||
|
$body: Record<string, unknown>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const app = new (class extends App {
|
||||||
|
config = {
|
||||||
|
upload_path: locreq.resolve("uploaded_files"),
|
||||||
|
datastore_mongo: {
|
||||||
|
host: "localhost",
|
||||||
|
port: 20723,
|
||||||
|
db_name: "sealious-playground",
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
from_address: "sealious-playground@example.com",
|
||||||
|
from_name: "Sealious playground app",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
manifest = {
|
||||||
|
name: "Sealious Playground",
|
||||||
|
logo: resolve(__dirname, "../assets/logo.png"),
|
||||||
|
version: "0.0.1",
|
||||||
|
default_language: "en",
|
||||||
|
base_url: "localhost:8080",
|
||||||
|
admin_email: "admin@example.com",
|
||||||
|
colors: {
|
||||||
|
primary: "#5294a1",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
collections = {
|
||||||
|
...App.BaseCollections,
|
||||||
|
tasks: new (class extends Collection {
|
||||||
|
fields = {
|
||||||
|
title: new FieldTypes.Text(),
|
||||||
|
done: new FieldTypes.Boolean(),
|
||||||
|
};
|
||||||
|
defaultPolicy = new Policies.Public();
|
||||||
|
})(),
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
app.start();
|
||||||
|
|
||||||
|
const router = app.HTTPServer.router;
|
||||||
|
|
||||||
|
function Task(task: CollectionItem<any>) {
|
||||||
|
return frame(
|
||||||
|
`task-${task.id}`,
|
||||||
|
/* HTML */ `<li class="task">
|
||||||
|
<input type="checkbox" /> ${task.get("title")}
|
||||||
|
<form
|
||||||
|
method="DELETE"
|
||||||
|
action="/task/${task.id}"
|
||||||
|
data-turbo-frame="task-list"
|
||||||
|
>
|
||||||
|
<input class="delete-button" type="submit" value="🗑" />
|
||||||
|
</form>
|
||||||
|
</li>`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function NewTask() {
|
||||||
|
return frame(
|
||||||
|
"new-task",
|
||||||
|
/* HTML */ `<form
|
||||||
|
method="POST"
|
||||||
|
action="/new-task"
|
||||||
|
data-turbo-frame="task-list"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
id="new-task-title"
|
||||||
|
type="text"
|
||||||
|
placeholder="write an app"
|
||||||
|
name="title"
|
||||||
|
/>
|
||||||
|
<input type="submit" value="Add" />
|
||||||
|
</form>`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function TaskList(context: Context) {
|
||||||
|
const { items: tasks } = await app.collections.tasks.list(context).fetch();
|
||||||
|
return frame(
|
||||||
|
"task-list",
|
||||||
|
/* HTML */ `
|
||||||
|
<ul>
|
||||||
|
${tasks.map(Task).join("\n")}
|
||||||
|
</ul>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function MainView(context: Context) {
|
||||||
|
return html(/* HTML */ `<title>My ToDo App</title>
|
||||||
|
<body>
|
||||||
|
<h1>My ToDo App</h1>
|
||||||
|
${await TaskList(context)} ${NewTask()}
|
||||||
|
</body>`);
|
||||||
|
}
|
||||||
|
|
||||||
|
router.get("/", Middlewares.extractContext(), async (ctx) => {
|
||||||
|
ctx.body = await MainView(ctx.$context);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post(
|
||||||
|
"/new-task",
|
||||||
|
Middlewares.extractContext(),
|
||||||
|
Middlewares.parseBody(),
|
||||||
|
async (ctx) => {
|
||||||
|
await app.collections.tasks
|
||||||
|
.make({
|
||||||
|
title: ctx.$body.title as string,
|
||||||
|
done: false,
|
||||||
|
})
|
||||||
|
.save(ctx.$context);
|
||||||
|
ctx.body = await MainView(ctx.$context);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
router.delete("/task/:task_id", Middlewares.extractContext(), async (ctx) => {
|
||||||
|
const task = await app.collections.tasks.getByID(
|
||||||
|
ctx.$context,
|
||||||
|
ctx.params.task_id
|
||||||
|
);
|
||||||
|
await task.remove(ctx.$context);
|
||||||
|
ctx.body = await MainView(ctx.$context);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.HTTPServer.addStaticRoute("/", locreq.resolve("public"));
|
@ -0,0 +1,3 @@
|
|||||||
|
import { Controller } from "stimulus";
|
||||||
|
|
||||||
|
export class TaskItem extends Controller {}
|
@ -1,50 +0,0 @@
|
|||||||
import _locreq from "locreq";
|
|
||||||
import { resolve } from "path";
|
|
||||||
import Sealious, { App, Collection, FieldTypes, Policies } from "sealious";
|
|
||||||
const locreq = _locreq(__dirname);
|
|
||||||
|
|
||||||
declare module "koa" {
|
|
||||||
interface BaseContext {
|
|
||||||
$context: Sealious.Context;
|
|
||||||
$app: Sealious.App;
|
|
||||||
$body: Record<string, unknown>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const app = new (class extends App {
|
|
||||||
config = {
|
|
||||||
upload_path: locreq.resolve("uploaded_files"),
|
|
||||||
datastore_mongo: {
|
|
||||||
host: "localhost",
|
|
||||||
port: 20723,
|
|
||||||
db_name: "sealious-playground",
|
|
||||||
},
|
|
||||||
email: {
|
|
||||||
from_address: "sealious-playground@example.com",
|
|
||||||
from_name: "Sealious playground app",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
manifest = {
|
|
||||||
name: "Sealious Playground",
|
|
||||||
logo: resolve(__dirname, "../assets/logo.png"),
|
|
||||||
version: "0.0.1",
|
|
||||||
default_language: "en",
|
|
||||||
base_url: "localhost:8080",
|
|
||||||
admin_email: "admin@example.com",
|
|
||||||
colors: {
|
|
||||||
primary: "#5294a1",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
collections = {
|
|
||||||
...App.BaseCollections,
|
|
||||||
tasks: new (class extends Collection {
|
|
||||||
fields = {
|
|
||||||
title: new FieldTypes.Text(),
|
|
||||||
done: new FieldTypes.Boolean(),
|
|
||||||
};
|
|
||||||
defaultPolicy = new Policies.Public();
|
|
||||||
})(),
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
app.start();
|
|
@ -0,0 +1,28 @@
|
|||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
name: "front-end-components",
|
||||||
|
entry: {
|
||||||
|
bundle: "./src/front/index.ts",
|
||||||
|
},
|
||||||
|
|
||||||
|
output: {
|
||||||
|
filename: "[name].js",
|
||||||
|
path: path.resolve(__dirname, "public/dist"),
|
||||||
|
},
|
||||||
|
|
||||||
|
mode: "production",
|
||||||
|
devtool: "source-map",
|
||||||
|
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
exclude: [/node_modules/],
|
||||||
|
use: [{ loader: "babel-loader" }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
Loading…
Reference in New Issue