🔥 Remove external packages for unity
This commit is contained in:
parent
4ea28030c7
commit
4b1e34487d
59 changed files with 3 additions and 1905 deletions
|
|
@ -18,12 +18,12 @@ keywords = [
|
|||
"pagetop", "web", "framework", "frontend", "ssr"
|
||||
]
|
||||
exclude = [
|
||||
"drust/", "examples/", "helpers/", "packages/", "tests/"
|
||||
"examples/", "helpers/", "tests/"
|
||||
]
|
||||
rust-version = "1.70.0"
|
||||
|
||||
[workspace]
|
||||
members = ["drust", "helpers/*", "packages/*"]
|
||||
members = ["helpers/*"]
|
||||
|
||||
[lib]
|
||||
name = "pagetop"
|
||||
|
|
@ -72,9 +72,6 @@ serde = { version = "1.0", features = ["derive"] }
|
|||
version = "0.3.30"
|
||||
optional = true
|
||||
|
||||
[dependencies.heck]
|
||||
version = "0.4.1"
|
||||
|
||||
[dependencies.sea-orm]
|
||||
version = "0.12.15"
|
||||
features = ["debug-print", "macros", "runtime-async-std-native-tls"]
|
||||
|
|
|
|||
35
README.md
35
README.md
|
|
@ -57,19 +57,7 @@ This program features a `HelloWorld` package, providing a service that serves a
|
|||
accessible via `http://localhost:8088` under default settings.
|
||||
|
||||
|
||||
# 📂 Repository Structure
|
||||
|
||||
This repository is organized into a workspace that includes several subprojects, each serving a
|
||||
distinct role within the PageTop ecosystem:
|
||||
|
||||
## Application
|
||||
|
||||
* [drust](https://github.com/manuelcillero/pagetop/tree/latest/drust):
|
||||
A simple Content Management System (CMS) built on PageTop, which enables the creation, editing,
|
||||
and maintenance of dynamic, fast, and modular websites. It uses the following essential packages
|
||||
to provide standard CMS functionalities.
|
||||
|
||||
## Helpers
|
||||
# 📂 Helpers
|
||||
|
||||
* [pagetop-macros](https://github.com/manuelcillero/pagetop/tree/latest/helpers/pagetop-macros):
|
||||
A collection of procedural macros that enhance the development experience within PageTop.
|
||||
|
|
@ -77,27 +65,6 @@ distinct role within the PageTop ecosystem:
|
|||
* [pagetop-build](https://github.com/manuelcillero/pagetop/tree/latest/helpers/pagetop-build):
|
||||
Simplifies the process of embedding resources directly into binary files for PageTop applications.
|
||||
|
||||
## Packages
|
||||
|
||||
* [pagetop-user](https://github.com/manuelcillero/pagetop/tree/latest/packages/pagetop-user):
|
||||
Facilitates user management, including roles, permissions, and session handling, for applications
|
||||
built on PageTop.
|
||||
|
||||
* [pagetop-admin](https://github.com/manuelcillero/pagetop/tree/latest/packages/pagetop-admin):
|
||||
Provides a unified interface for administrators to configure and manage package settings.
|
||||
|
||||
* [pagetop-node](https://github.com/manuelcillero/pagetop/tree/latest/packages/pagetop-node):
|
||||
Enables the creation and customization of content types, enhancing website content management.
|
||||
|
||||
## Themes
|
||||
|
||||
* [pagetop-bootsier](https://github.com/manuelcillero/pagetop/tree/latest/packages/pagetop-bootsier):
|
||||
Utilizes the *[Bootstrap](https://getbootstrap.com/)* framework to offer versatile page layouts
|
||||
and component stylings.
|
||||
|
||||
* [pagetop-bulmix](https://github.com/manuelcillero/pagetop/tree/latest/packages/pagetop-bulmix):
|
||||
Utilizes the *[Bulma](https://bulma.io/)* framework for sleek, responsive design elements.
|
||||
|
||||
|
||||
# 🚧 Warning
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
[package]
|
||||
name = "drust"
|
||||
version = "0.0.3"
|
||||
edition = "2021"
|
||||
|
||||
description = "A modern web Content Management System to share your world."
|
||||
homepage = "https://pagetop.cillero.es"
|
||||
repository = "https://github.com/manuelcillero/pagetop"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
authors = [
|
||||
"Manuel Cillero <manuel@cillero.es>"
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
pagetop = { version = "0.0", path = "../", features = ["mysql"], default-features = false }
|
||||
# Packages.
|
||||
pagetop-admin = { version = "0.0", path = "../packages/pagetop-admin" }
|
||||
pagetop-user = { version = "0.0", path = "../packages/pagetop-user" }
|
||||
pagetop-node = { version = "0.0", path = "../packages/pagetop-node" }
|
||||
# Themes.
|
||||
pagetop-bootsier = { version = "0.0", path = "../packages/pagetop-bootsier" }
|
||||
pagetop-bulmix = { version = "0.0", path = "../packages/pagetop-bulmix" }
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
<div align="center">
|
||||
<h1>Drust</h1>
|
||||
<p>A Content Management System built on PageTop.</p>
|
||||
</div>
|
||||
|
||||
## Overview
|
||||
|
||||
Modestly inspired by [Drupal](https://www.drupal.org), **Drust** utilizes **PageTop** to develop a
|
||||
CMS (*Content Management System*). It enables the creation of dynamic, manageable, and customizable
|
||||
websites, allowing users to effortlessly create, manage, and organize a wide variety of content on a
|
||||
website.
|
||||
|
||||
|
||||
# 📦 About PageTop
|
||||
|
||||
[PageTop](https://docs.rs/pagetop) is an opinionated web framework to build modular *Server-Side
|
||||
Rendering* web solutions.
|
||||
|
||||
|
||||
# 🚧 Warning
|
||||
|
||||
**PageTop** framework is currently in active development. The API is unstable and subject to
|
||||
frequent changes. Production use is not recommended until version **0.1.0**.
|
||||
|
||||
|
||||
# 📜 License
|
||||
|
||||
All code in this project is dual-licensed under either:
|
||||
|
||||
* MIT License
|
||||
([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT)
|
||||
|
||||
* Apache License, Version 2.0,
|
||||
([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
||||
at your option. This means you can select the license you prefer! This dual-licensing approach is
|
||||
the de-facto standard in the Rust ecosystem.
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
[app]
|
||||
name = "Drust"
|
||||
description = """\
|
||||
A modern web Content Management System to share your world.\
|
||||
"""
|
||||
|
||||
[database]
|
||||
db_type = "mysql"
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
[app]
|
||||
#theme = "Basic"
|
||||
#theme = "Chassis"
|
||||
theme = "Inception"
|
||||
#theme = "Bootsier"
|
||||
#theme = "Bulmix"
|
||||
language = "es-ES"
|
||||
|
||||
[log]
|
||||
tracing = "Info,pagetop=Debug,sqlx::query=Warn"
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
struct Drust;
|
||||
|
||||
impl PackageTrait for Drust {
|
||||
fn dependencies(&self) -> Vec<PackageRef> {
|
||||
vec![
|
||||
// Packages.
|
||||
&pagetop_admin::Admin,
|
||||
&pagetop_user::User,
|
||||
&pagetop_node::Node,
|
||||
// Themes.
|
||||
&pagetop_bootsier::Bootsier,
|
||||
&pagetop_bulmix::Bulmix,
|
||||
]
|
||||
}
|
||||
|
||||
fn drop_packages(&self) -> Vec<PackageRef> {
|
||||
vec![
|
||||
// &pagetop_node::Node
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
#[pagetop::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
Application::prepare(&Drust).run()?.await
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
[package]
|
||||
name = "pagetop-admin"
|
||||
version = "0.0.21"
|
||||
edition = "2021"
|
||||
|
||||
description = "PageTop package that provides a unified settings interface to other packages."
|
||||
homepage = "https://pagetop.cillero.es"
|
||||
repository = "https://github.com/manuelcillero/pagetop"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
authors = [
|
||||
"Manuel Cillero <manuel@cillero.es>"
|
||||
]
|
||||
categories = [
|
||||
"web-programming", "gui"
|
||||
]
|
||||
keywords = [
|
||||
"pagetop", "admin", "config", "settings", "packages"
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
pagetop = { version = "0.0", path = "../../" }
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
<div align="center">
|
||||
|
||||
<h1>PageTop Admin</h1>
|
||||
|
||||
<p>PageTop package that provides a unified settings interface to other packages.</p>
|
||||
|
||||
[](#-license)
|
||||
[](https://docs.rs/pagetop-admin)
|
||||
[](https://crates.io/crates/pagetop-admin)
|
||||
[](https://crates.io/crates/pagetop-admin)
|
||||
|
||||
</div>
|
||||
|
||||
# 📦 About PageTop
|
||||
|
||||
[PageTop](https://docs.rs/pagetop) is an opinionated web framework to build modular *Server-Side
|
||||
Rendering* web solutions.
|
||||
|
||||
|
||||
# 🚧 Warning
|
||||
|
||||
**PageTop** framework is currently in active development. The API is unstable and subject to
|
||||
frequent changes. Production use is not recommended until version **0.1.0**.
|
||||
|
||||
|
||||
# 📜 License
|
||||
|
||||
All code in this crate is dual-licensed under either:
|
||||
|
||||
* MIT License
|
||||
([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT)
|
||||
|
||||
* Apache License, Version 2.0,
|
||||
([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
||||
at your option. This means you can select the license you prefer! This dual-licensing approach is
|
||||
the de-facto standard in the Rust ecosystem.
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
static_locales!(LOCALES_ADMIN);
|
||||
|
||||
mod summary;
|
||||
|
||||
pub struct Admin;
|
||||
|
||||
impl PackageTrait for Admin {
|
||||
fn name(&self) -> L10n {
|
||||
L10n::t("package_name", &LOCALES_ADMIN)
|
||||
}
|
||||
|
||||
fn description(&self) -> L10n {
|
||||
L10n::t("package_description", &LOCALES_ADMIN)
|
||||
}
|
||||
|
||||
fn actions(&self) -> Vec<ActionBox> {
|
||||
actions![
|
||||
action::page::BeforePrepareBody::new(before_prepare_body),
|
||||
action::component::BeforePrepare::<Menu>::new(before_prepare_menu)
|
||||
.filter_by_referer_id("admin-menu-test"),
|
||||
]
|
||||
}
|
||||
|
||||
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {
|
||||
scfg.service(
|
||||
service::web::scope("/admin").route("", service::web::get().to(summary::summary)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn before_prepare_body(page: &mut Page) {
|
||||
page.alter_body_classes(ClassesOp::Add, "test-admin");
|
||||
}
|
||||
|
||||
fn before_prepare_menu(component: &mut Menu, _cx: &mut Context) {
|
||||
component.alter_id("admin-menu-test-altered");
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
package_name = Admin module
|
||||
package_description = Administration module.
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
package_name = Admin module
|
||||
package_description = Módulo de administración.
|
||||
|
|
@ -1,163 +0,0 @@
|
|||
use crate::LOCALES_ADMIN;
|
||||
|
||||
use pagetop::prelude::*;
|
||||
|
||||
pub async fn summary(request: HttpRequest) -> ResultPage<Markup, ErrorPage> {
|
||||
let top_menu = Menu::new()
|
||||
.with_id("admin-menu-test")
|
||||
.add_item(menu::Item::label(L10n::t("package_name", &LOCALES_ADMIN)))
|
||||
.add_item(menu::Item::label(L10n::n("Ejemplo \"Label\"")))
|
||||
.add_item(menu::Item::link(L10n::n("Ejemplo \"Link\""), |_| {
|
||||
"https://www.google.es"
|
||||
}))
|
||||
.add_item(menu::Item::link_blank(
|
||||
L10n::n("Ejemplo \"LinkBlank\""),
|
||||
|_| "https://www.google.es",
|
||||
))
|
||||
.add_item(menu::Item::submenu(
|
||||
L10n::n("Ejemplo Submenú"),
|
||||
menu::Submenu::new()
|
||||
.with_title(L10n::n("Título submenú"))
|
||||
.add_item(menu::Item::link(L10n::n("Opción \"Link\""), |_| {
|
||||
"https://www.google.es"
|
||||
}))
|
||||
.add_item(menu::Item::link_blank(
|
||||
L10n::n("Opción \"LinkBlank\""),
|
||||
|_| "https://www.google.es",
|
||||
))
|
||||
.add_item(menu::Item::submenu(
|
||||
L10n::n("Otro submenú con un texto muy, pero que muy largo"),
|
||||
menu::Submenu::new()
|
||||
.add_item(menu::Item::label(L10n::n("Opción \"Label\"")))
|
||||
.add_item(menu::Item::link(L10n::n("Opción \"Link\""), |_| {
|
||||
"https://www.google.es"
|
||||
}))
|
||||
.add_item(menu::Item::link_blank(
|
||||
L10n::n("Opción \"LinkBlank\""),
|
||||
|_| "https://www.google.es",
|
||||
))
|
||||
.add_item(menu::Item::label(L10n::n("Opción \"Label\""))),
|
||||
))
|
||||
.add_item(menu::Item::label(L10n::n("Opción \"Label\""))),
|
||||
))
|
||||
.add_item(menu::Item::megamenu(
|
||||
L10n::n("Ejemplo Megamenú 1"),
|
||||
menu::Megamenu::new()
|
||||
.add_group(
|
||||
menu::Group::new()
|
||||
.add_element(menu::Element::submenu(
|
||||
menu::Submenu::new()
|
||||
.with_title(L10n::n("Título submenú"))
|
||||
.add_item(menu::Item::label(L10n::n("Opción \"Label\"")))
|
||||
.add_item(menu::Item::link(L10n::n("Opción \"Link\""), |_| {
|
||||
"https://www.google.es"
|
||||
}))
|
||||
.add_item(menu::Item::link_blank(
|
||||
L10n::n("Opción \"LinkBlank\""),
|
||||
|_| "https://www.google.es",
|
||||
)),
|
||||
))
|
||||
.add_element(menu::Element::submenu(
|
||||
menu::Submenu::new()
|
||||
.with_title(L10n::n("Título submenú"))
|
||||
.add_item(menu::Item::label(L10n::n("Opción \"Label\"")))
|
||||
.add_item(menu::Item::link(L10n::n("Opción \"Link\""), |_| {
|
||||
"https://www.google.es"
|
||||
}))
|
||||
.add_item(menu::Item::link_blank(
|
||||
L10n::n("Opción \"LinkBlank\""),
|
||||
|_| "https://www.google.es",
|
||||
)),
|
||||
)),
|
||||
)
|
||||
.add_group(
|
||||
menu::Group::new().add_element(menu::Element::submenu(
|
||||
menu::Submenu::new()
|
||||
.add_item(menu::Item::label(L10n::n("Opción \"Label\"")))
|
||||
.add_item(menu::Item::link(L10n::n("Opción \"Link\""), |_| {
|
||||
"https://www.google.es"
|
||||
}))
|
||||
.add_item(menu::Item::link_blank(
|
||||
L10n::n("Opción \"LinkBlank\""),
|
||||
|_| "https://www.google.es",
|
||||
))
|
||||
.add_item(menu::Item::label(L10n::n("Opción \"Label\""))),
|
||||
)),
|
||||
)
|
||||
.add_group(
|
||||
menu::Group::new()
|
||||
.add_element(menu::Element::submenu(
|
||||
menu::Submenu::new()
|
||||
.with_title(L10n::n("Título submenú"))
|
||||
.add_item(menu::Item::label(L10n::n("Opción \"Label\"")))
|
||||
.add_item(menu::Item::link(L10n::n("Opción \"Link\""), |_| {
|
||||
"https://www.google.es"
|
||||
}))
|
||||
.add_item(menu::Item::link_blank(
|
||||
L10n::n("Opción \"LinkBlank\""),
|
||||
|_| "https://www.google.es",
|
||||
)),
|
||||
))
|
||||
.add_element(menu::Element::submenu(
|
||||
menu::Submenu::new()
|
||||
.with_title(L10n::n("Título submenú"))
|
||||
.add_item(menu::Item::label(L10n::n("Opción \"Label\"")))
|
||||
.add_item(menu::Item::link(L10n::n("Opción \"Link\""), |_| {
|
||||
"https://www.google.es"
|
||||
}))
|
||||
.add_item(menu::Item::link_blank(
|
||||
L10n::n("Opción \"LinkBlank\""),
|
||||
|_| "https://www.google.es",
|
||||
)),
|
||||
)),
|
||||
)
|
||||
.add_group(
|
||||
menu::Group::new().add_element(menu::Element::submenu(
|
||||
menu::Submenu::new()
|
||||
.add_item(menu::Item::label(L10n::n("Opción \"Label\"")))
|
||||
.add_item(menu::Item::link(L10n::n("Opción \"Link\""), |_| {
|
||||
"https://www.google.es"
|
||||
}))
|
||||
.add_item(menu::Item::link_blank(
|
||||
L10n::n("Opción \"LinkBlank\""),
|
||||
|_| "https://www.google.es",
|
||||
))
|
||||
.add_item(menu::Item::label(L10n::n("Opción \"Label\""))),
|
||||
)),
|
||||
),
|
||||
));
|
||||
|
||||
let side_menu = Menu::new()
|
||||
.add_item(menu::Item::label(L10n::n("Opción 1")))
|
||||
.add_item(menu::Item::link(L10n::n("Opción 2"), |_| {
|
||||
"https://www.google.es"
|
||||
}))
|
||||
.add_item(menu::Item::link_blank(L10n::n("Opción 3"), |_| {
|
||||
"https://www.google.es"
|
||||
}))
|
||||
.add_item(menu::Item::submenu(
|
||||
L10n::n("Submenú 1"),
|
||||
menu::Submenu::new()
|
||||
.add_item(menu::Item::label(L10n::n("Opción 1")))
|
||||
.add_item(menu::Item::label(L10n::n("Opción 2"))),
|
||||
)) /*
|
||||
.add_item(menu::Item::separator()) */
|
||||
.add_item(menu::Item::submenu(
|
||||
L10n::n("Submenú 2"),
|
||||
menu::Submenu::new()
|
||||
.add_item(menu::Item::label(L10n::n("Opción 1")))
|
||||
.add_item(menu::Item::label(L10n::n("Opción 2"))),
|
||||
))
|
||||
.add_item(menu::Item::label(L10n::n("Opción 4")));
|
||||
|
||||
Page::new(request)
|
||||
.with_title(L10n::n("Admin"))
|
||||
.with_component_in("top-menu", side_menu)
|
||||
.with_component(
|
||||
flex::Container::new()
|
||||
.add_item(flex::Item::with(Html::with(html! { p { "Columna 1"} })))
|
||||
.add_item(flex::Item::with(top_menu))
|
||||
.add_item(flex::Item::with(Html::with(html! { p { "Columna 3"} }))),
|
||||
)
|
||||
.render()
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
[package]
|
||||
name = "pagetop-bootsier"
|
||||
version = "0.0.18"
|
||||
edition = "2021"
|
||||
|
||||
description = "PageTop theme that uses Bootstrap framework for versatile styles and components."
|
||||
homepage = "https://pagetop.cillero.es"
|
||||
repository = "https://github.com/manuelcillero/pagetop"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
authors = [
|
||||
"Manuel Cillero <manuel@cillero.es>"
|
||||
]
|
||||
categories = [
|
||||
"web-programming", "gui"
|
||||
]
|
||||
keywords = [
|
||||
"pagetop", "theme", "bootstrap", "css", "js"
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
pagetop = { version = "0.0", path = "../../" }
|
||||
static-files = "0.2.3"
|
||||
|
||||
[build-dependencies]
|
||||
pagetop-build = { version = "0.0", path = "../../helpers/pagetop-build" }
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
<div align="center">
|
||||
|
||||
<h1>PageTop Bootsier</h1>
|
||||
|
||||
<p>PageTop theme that uses Bootstrap framework for versatile styles and components.</p>
|
||||
|
||||
[](#-license)
|
||||
[](https://docs.rs/pagetop-bootsier)
|
||||
[](https://crates.io/crates/pagetop-bootsier)
|
||||
[](https://crates.io/crates/pagetop-bootsier)
|
||||
|
||||
</div>
|
||||
|
||||
# 📦 About PageTop
|
||||
|
||||
[PageTop](https://docs.rs/pagetop) is an opinionated web framework to build modular *Server-Side
|
||||
Rendering* web solutions.
|
||||
|
||||
|
||||
# 🚧 Warning
|
||||
|
||||
**PageTop** framework is currently in active development. The API is unstable and subject to
|
||||
frequent changes. Production use is not recommended until version **0.1.0**.
|
||||
|
||||
|
||||
# 📜 License
|
||||
|
||||
All code in this crate is dual-licensed under either:
|
||||
|
||||
* MIT License
|
||||
([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT)
|
||||
|
||||
* Apache License, Version 2.0,
|
||||
([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
||||
at your option. This means you can select the license you prefer! This dual-licensing approach is
|
||||
the de-facto standard in the Rust ecosystem.
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
use pagetop_build::StaticFilesBundle;
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
StaticFilesBundle::from_dir("./static")
|
||||
.with_name("bootsier")
|
||||
.build()
|
||||
}
|
||||
|
|
@ -1,179 +0,0 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
static_locales!(LOCALES_BOOTSIER);
|
||||
|
||||
static_files!(bootsier);
|
||||
|
||||
pub struct Bootsier;
|
||||
|
||||
impl PackageTrait for Bootsier {
|
||||
fn theme(&self) -> Option<ThemeRef> {
|
||||
Some(&Bootsier)
|
||||
}
|
||||
|
||||
fn actions(&self) -> Vec<ActionBox> {
|
||||
actions![
|
||||
action::theme::BeforePrepare::<Icon>::new(&Self, before_prepare_icon),
|
||||
action::theme::BeforePrepare::<Button>::new(&Self, before_prepare_button),
|
||||
action::theme::BeforePrepare::<Heading>::new(&Self, before_prepare_heading),
|
||||
action::theme::BeforePrepare::<Paragraph>::new(&Self, before_prepare_paragraph),
|
||||
action::theme::RenderComponent::<Error404>::new(&Self, render_error404),
|
||||
]
|
||||
}
|
||||
|
||||
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {
|
||||
service_for_static_files!(scfg, bootsier => "/bootsier");
|
||||
}
|
||||
}
|
||||
|
||||
impl ThemeTrait for Bootsier {
|
||||
#[rustfmt::skip]
|
||||
fn regions(&self) -> Vec<(&'static str, L10n)> {
|
||||
vec![
|
||||
("header", L10n::t("header", &LOCALES_BOOTSIER)),
|
||||
("nav_branding", L10n::t("nav_branding", &LOCALES_BOOTSIER)),
|
||||
("nav_main", L10n::t("nav_main", &LOCALES_BOOTSIER)),
|
||||
("nav_additional", L10n::t("nav_additional", &LOCALES_BOOTSIER)),
|
||||
("breadcrumb", L10n::t("breadcrumb", &LOCALES_BOOTSIER)),
|
||||
("content", L10n::t("breadcrumb", &LOCALES_BOOTSIER)),
|
||||
("sidebar_first", L10n::t("sidebar_first", &LOCALES_BOOTSIER)),
|
||||
("sidebar_second", L10n::t("sidebar_second", &LOCALES_BOOTSIER)),
|
||||
("footer", L10n::t("footer", &LOCALES_BOOTSIER)),
|
||||
]
|
||||
}
|
||||
|
||||
fn prepare_body(&self, page: &mut Page) -> Markup {
|
||||
Body::with(match page.context().layout() {
|
||||
"admin" => flex::Container::new()
|
||||
.add_item(flex::Item::region().with_id("top-menu"))
|
||||
.add_item(flex::Item::region().with_id("side-menu"))
|
||||
.add_item(flex::Item::region().with_id("content")),
|
||||
_ => flex::Container::new()
|
||||
.add_item(flex::Item::region().with_id("header"))
|
||||
.add_item(flex::Item::region().with_id("nav_branding"))
|
||||
.add_item(flex::Item::region().with_id("nav_main"))
|
||||
.add_item(flex::Item::region().with_id("nav_additional"))
|
||||
.add_item(flex::Item::region().with_id("breadcrumb"))
|
||||
.add_item(flex::Item::region().with_id("content"))
|
||||
.add_item(flex::Item::region().with_id("sidebar_first"))
|
||||
.add_item(flex::Item::region().with_id("sidebar_second"))
|
||||
.add_item(flex::Item::region().with_id("footer")),
|
||||
})
|
||||
.render(page.context())
|
||||
}
|
||||
|
||||
fn after_prepare_body(&self, page: &mut Page) {
|
||||
page.alter_favicon(Some(Favicon::new().with_icon("/base/favicon.ico")))
|
||||
.alter_assets(AssetsOp::AddStyleSheet(
|
||||
StyleSheet::at("/bootsier/css/bootstrap.min.css")
|
||||
.with_version("5.1.3")
|
||||
.with_weight(-99),
|
||||
))
|
||||
.alter_assets(AssetsOp::AddJavaScript(
|
||||
JavaScript::at("/bootsier/js/bootstrap.bundle.min.js")
|
||||
.with_version("5.1.3")
|
||||
.with_weight(-99),
|
||||
))
|
||||
.alter_assets(AssetsOp::AddBaseAssets)
|
||||
.alter_assets(AssetsOp::AddStyleSheet(
|
||||
StyleSheet::at("/bootsier/css/styles.css").with_version("0.0.1"),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
fn before_prepare_icon(i: &mut Icon, _cx: &mut Context) {
|
||||
i.alter_classes(
|
||||
ClassesOp::Replace(i.font_size().to_string()),
|
||||
with_font(i.font_size()),
|
||||
);
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn before_prepare_button(b: &mut Button, _cx: &mut Context) {
|
||||
b.alter_classes(ClassesOp::Replace("button__tap".to_owned()), "btn");
|
||||
b.alter_classes(
|
||||
ClassesOp::Replace(b.style().to_string()),
|
||||
match b.style() {
|
||||
StyleBase::Default => "btn-primary",
|
||||
StyleBase::Info => "btn-info",
|
||||
StyleBase::Success => "btn-success",
|
||||
StyleBase::Warning => "btn-warning",
|
||||
StyleBase::Danger => "btn-danger",
|
||||
StyleBase::Light => "btn-light",
|
||||
StyleBase::Dark => "btn-dark",
|
||||
StyleBase::Link => "btn-link",
|
||||
},
|
||||
);
|
||||
b.alter_classes(
|
||||
ClassesOp::Replace(b.font_size().to_string()),
|
||||
with_font(b.font_size()),
|
||||
);
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn before_prepare_heading(h: &mut Heading, _cx: &mut Context) {
|
||||
h.alter_classes(
|
||||
ClassesOp::Replace(h.size().to_string()),
|
||||
match h.size() {
|
||||
HeadingSize::ExtraLarge => "display-1",
|
||||
HeadingSize::XxLarge => "display-2",
|
||||
HeadingSize::XLarge => "display-3",
|
||||
HeadingSize::Large => "display-4",
|
||||
HeadingSize::Medium => "display-5",
|
||||
_ => "",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn before_prepare_paragraph(p: &mut Paragraph, _cx: &mut Context) {
|
||||
p.alter_classes(
|
||||
ClassesOp::Replace(p.font_size().to_string()),
|
||||
with_font(p.font_size()),
|
||||
);
|
||||
}
|
||||
|
||||
fn render_error404(_: &Error404, cx: &mut Context) -> Option<Markup> {
|
||||
Some(html! {
|
||||
div class="jumbotron" {
|
||||
div class="media" {
|
||||
img
|
||||
src="/bootsier/images/caution.png"
|
||||
class="mr-4"
|
||||
style="width: 20%; max-width: 188px"
|
||||
alt="Caution!";
|
||||
div class="media-body" {
|
||||
h1 class="display-4" { ("RESOURCE NOT FOUND") }
|
||||
p class="lead" {
|
||||
(L10n::t("e404-description", &LOCALES_BOOTSIER)
|
||||
.escaped(cx.langid()))
|
||||
}
|
||||
hr class="my-4";
|
||||
p {
|
||||
(L10n::t("e404-description", &LOCALES_BOOTSIER)
|
||||
.escaped(cx.langid()))
|
||||
}
|
||||
a
|
||||
class="btn btn-primary btn-lg"
|
||||
href="/"
|
||||
role="button"
|
||||
{
|
||||
(L10n::t("back-homepage", &LOCALES_BOOTSIER)
|
||||
.escaped(cx.langid()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn with_font(font_size: &FontSize) -> String {
|
||||
String::from(match font_size {
|
||||
FontSize::ExtraLarge => "fs-1",
|
||||
FontSize::XxLarge => "fs-2",
|
||||
FontSize::XLarge => "fs-3",
|
||||
FontSize::Large => "fs-4",
|
||||
FontSize::Medium => "fs-5",
|
||||
_ => "",
|
||||
})
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
e404-description = Oops! Page Not Found
|
||||
e404-message = The page you are looking for may have been removed, had its name changed, or is temporarily unavailable.
|
||||
e500-description = Oops! Unexpected Error
|
||||
e500-message = We're having an issue. Please report this error to an administrator.
|
||||
back-homepage = Back to homepage
|
||||
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
header = Header
|
||||
nav_branding = Navigation branding region
|
||||
nav_main = Main navigation region
|
||||
nav_additional = Additional navigation region (eg search form, social icons, etc)
|
||||
breadcrumb = Breadcrumb
|
||||
content = Main content
|
||||
sidebar_first = Sidebar first
|
||||
sidebar_second = Sidebar second
|
||||
footer = Footer
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
e404-description = ¡Vaya! Página No Encontrada
|
||||
e404-message = La página que está buscando puede haber sido eliminada, cambiada de nombre o no está disponible temporalmente.
|
||||
e500-description = ¡Vaya! Error Inesperado
|
||||
e500-message = Está ocurriendo una incidencia. Por favor, informe de este error a un administrador.
|
||||
back-homepage = Volver al inicio
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
header = Cabecera
|
||||
nav_branding = Navegación y marca
|
||||
nav_main = Navegación principal
|
||||
nav_additional = Navegación adicional (p.e. formulario de búsqueda, iconos sociales, etc.)
|
||||
breadcrumb = Ruta de posicionamiento
|
||||
content = Contenido principal
|
||||
sidebar_first = Barra lateral primera
|
||||
sidebar_second = Barra lateral segunda
|
||||
footer = Pie
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,13 +0,0 @@
|
|||
/* OVERRIDE COMPONENT STYLES */
|
||||
|
||||
/* Heading component */
|
||||
|
||||
.heading__subtitle {
|
||||
margin-top: calc(-1 * var(--val-gap-0-35));
|
||||
}
|
||||
|
||||
/* Button component */
|
||||
|
||||
.btn > span {
|
||||
margin: 0 var(--val-gap-0-5);
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,26 +0,0 @@
|
|||
[package]
|
||||
name = "pagetop-bulmix"
|
||||
version = "0.0.17"
|
||||
edition = "2021"
|
||||
|
||||
description = "PageTop theme that uses the Bulma framework for sleek, responsive design elements."
|
||||
homepage = "https://pagetop.cillero.es"
|
||||
repository = "https://github.com/manuelcillero/pagetop"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
authors = [
|
||||
"Manuel Cillero <manuel@cillero.es>"
|
||||
]
|
||||
categories = [
|
||||
"web-programming", "gui"
|
||||
]
|
||||
keywords = [
|
||||
"pagetop", "theme", "bulma", "css", "js"
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
pagetop = { version = "0.0", path = "../../" }
|
||||
static-files = "0.2.3"
|
||||
|
||||
[build-dependencies]
|
||||
pagetop-build = { version = "0.0", path = "../../helpers/pagetop-build" }
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
<div align="center">
|
||||
|
||||
<h1>PageTop Bulmix</h1>
|
||||
|
||||
<p>PageTop theme that uses the Bulma framework for sleek, responsive design elements.</p>
|
||||
|
||||
[](#-license)
|
||||
[](https://docs.rs/pagetop-bulmix)
|
||||
[](https://crates.io/crates/pagetop-bulmix)
|
||||
[](https://crates.io/crates/pagetop-bulmix)
|
||||
|
||||
</div>
|
||||
|
||||
# 📦 About PageTop
|
||||
|
||||
[PageTop](https://docs.rs/pagetop) is an opinionated web framework to build modular *Server-Side
|
||||
Rendering* web solutions.
|
||||
|
||||
|
||||
# 🚧 Warning
|
||||
|
||||
**PageTop** framework is currently in active development. The API is unstable and subject to
|
||||
frequent changes. Production use is not recommended until version **0.1.0**.
|
||||
|
||||
|
||||
# 📜 License
|
||||
|
||||
All code in this crate is dual-licensed under either:
|
||||
|
||||
* MIT License
|
||||
([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT)
|
||||
|
||||
* Apache License, Version 2.0,
|
||||
([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
||||
at your option. This means you can select the license you prefer! This dual-licensing approach is
|
||||
the de-facto standard in the Rust ecosystem.
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
use pagetop_build::StaticFilesBundle;
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
StaticFilesBundle::from_dir("./static")
|
||||
.with_name("bulmix")
|
||||
.build()
|
||||
}
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
static_files!(bulmix);
|
||||
|
||||
pub struct Bulmix;
|
||||
|
||||
impl PackageTrait for Bulmix {
|
||||
fn theme(&self) -> Option<ThemeRef> {
|
||||
Some(&Bulmix)
|
||||
}
|
||||
|
||||
fn actions(&self) -> Vec<ActionBox> {
|
||||
actions![
|
||||
action::theme::BeforePrepare::<Icon>::new(&Self, before_prepare_icon),
|
||||
action::theme::BeforePrepare::<Button>::new(&Self, before_prepare_button),
|
||||
action::theme::BeforePrepare::<Heading>::new(&Self, before_prepare_heading),
|
||||
action::theme::BeforePrepare::<Paragraph>::new(&Self, before_prepare_paragraph),
|
||||
action::theme::RenderComponent::<Icon>::new(&Self, render_icon),
|
||||
]
|
||||
}
|
||||
|
||||
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {
|
||||
service_for_static_files!(scfg, bulmix => "/bulmix");
|
||||
}
|
||||
}
|
||||
|
||||
impl ThemeTrait for Bulmix {
|
||||
/*
|
||||
#[rustfmt::skip]
|
||||
fn builtin_classes(&self, builtin: ThemeBuiltInClasses) -> Option<String> {
|
||||
match builtin {
|
||||
ThemeBuiltInClasses::BodyWrapper => Some(String::from("container")),
|
||||
ThemeBuiltInClasses::FlexWrapper => Some(String::from("container")),
|
||||
ThemeBuiltInClasses::RegionContainer => Some(String::from("container")),
|
||||
_ => Some(builtin.to_string()),
|
||||
}
|
||||
}
|
||||
*/
|
||||
fn after_prepare_body(&self, page: &mut Page) {
|
||||
page.alter_favicon(Some(Favicon::new().with_icon("/base/favicon.ico")))
|
||||
.alter_assets(AssetsOp::AddStyleSheet(
|
||||
StyleSheet::at("/bulmix/css/bulma.min.css")
|
||||
.with_version("0.9.4")
|
||||
.with_weight(-99),
|
||||
))
|
||||
.alter_assets(AssetsOp::AddBaseAssets)
|
||||
.alter_assets(AssetsOp::AddStyleSheet(
|
||||
StyleSheet::at("/bulmix/css/styles.css").with_version("0.0.1"),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
fn before_prepare_icon(i: &mut Icon, _cx: &mut Context) {
|
||||
i.alter_classes(
|
||||
ClassesOp::Replace(i.font_size().to_string()),
|
||||
with_font(i.font_size()),
|
||||
);
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn before_prepare_button(b: &mut Button, _cx: &mut Context) {
|
||||
b.alter_classes(ClassesOp::Replace("button__tap".to_owned()), "button");
|
||||
b.alter_classes(
|
||||
ClassesOp::Replace(b.style().to_string()),
|
||||
match b.style() {
|
||||
StyleBase::Default => "is-primary",
|
||||
StyleBase::Info => "is-info",
|
||||
StyleBase::Success => "is-success",
|
||||
StyleBase::Warning => "is-warning",
|
||||
StyleBase::Danger => "is-danger",
|
||||
StyleBase::Light => "is-light",
|
||||
StyleBase::Dark => "is-dark",
|
||||
StyleBase::Link => "is-text",
|
||||
},
|
||||
);
|
||||
b.alter_classes(
|
||||
ClassesOp::Replace(b.font_size().to_string()),
|
||||
with_font(b.font_size()),
|
||||
);
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn before_prepare_heading(h: &mut Heading, _cx: &mut Context) {
|
||||
match h.size() {
|
||||
HeadingSize::Subtitle => {
|
||||
h.alter_classes(ClassesOp::Replace(h.size().to_string()), "subtitle")
|
||||
}
|
||||
_ => h.alter_classes(ClassesOp::Add, "title"),
|
||||
};
|
||||
}
|
||||
|
||||
fn before_prepare_paragraph(p: &mut Paragraph, _cx: &mut Context) {
|
||||
p.alter_classes(ClassesOp::Add, "block");
|
||||
p.alter_classes(
|
||||
ClassesOp::Replace(p.font_size().to_string()),
|
||||
with_font(p.font_size()),
|
||||
);
|
||||
}
|
||||
|
||||
fn render_icon(i: &Icon, _cx: &mut Context) -> Option<Markup> {
|
||||
return match i.icon_name().get() {
|
||||
None => None,
|
||||
_ => Some(html! { span class="icon" { i class=[i.classes().get()] {} } }),
|
||||
};
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn with_font(font_size: &FontSize) -> String {
|
||||
String::from(match font_size {
|
||||
FontSize::ExtraLarge => "is-size-1",
|
||||
FontSize::XxLarge => "is-size-2",
|
||||
FontSize::XLarge => "is-size-3",
|
||||
FontSize::Large => "is-size-4",
|
||||
FontSize::Medium => "is-size-5",
|
||||
_ => "",
|
||||
})
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,11 +0,0 @@
|
|||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* OVERRIDE COMPONENT STYLES */
|
||||
|
||||
/* Button component */
|
||||
|
||||
.is-link {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
[package]
|
||||
name = "pagetop-node"
|
||||
version = "0.0.20"
|
||||
edition = "2021"
|
||||
|
||||
description = "PageTop package for easy content type creation and customization."
|
||||
homepage = "https://pagetop.cillero.es"
|
||||
repository = "https://github.com/manuelcillero/pagetop"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
authors = [
|
||||
"Manuel Cillero <manuel@cillero.es>"
|
||||
]
|
||||
categories = [
|
||||
"web-programming", "gui"
|
||||
]
|
||||
keywords = [
|
||||
"pagetop", "node", "cms", "content", "workflow"
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
pagetop = { version = "0.0", path = "../../", features = ["database"], default-features = false }
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
<div align="center">
|
||||
|
||||
<h1>PageTop Node</h1>
|
||||
|
||||
<p>PageTop package for easy content type creation and customization.</p>
|
||||
|
||||
[](#-license)
|
||||
[](https://docs.rs/pagetop-node)
|
||||
[](https://crates.io/crates/pagetop-node)
|
||||
[](https://crates.io/crates/pagetop-node)
|
||||
|
||||
</div>
|
||||
|
||||
# 📦 About PageTop
|
||||
|
||||
[PageTop](https://docs.rs/pagetop) is an opinionated web framework to build modular *Server-Side
|
||||
Rendering* web solutions.
|
||||
|
||||
|
||||
# 🚧 Warning
|
||||
|
||||
**PageTop** framework is currently in active development. The API is unstable and subject to
|
||||
frequent changes. Production use is not recommended until version **0.1.0**.
|
||||
|
||||
|
||||
# 📜 License
|
||||
|
||||
All code in this crate is dual-licensed under either:
|
||||
|
||||
* MIT License
|
||||
([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT)
|
||||
|
||||
* Apache License, Version 2.0,
|
||||
([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
||||
at your option. This means you can select the license you prefer! This dual-licensing approach is
|
||||
the de-facto standard in the Rust ecosystem.
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
static_locales!(LOCALES_NODE);
|
||||
|
||||
//mod entity;
|
||||
mod migration;
|
||||
|
||||
pub struct Node;
|
||||
|
||||
impl PackageTrait for Node {
|
||||
fn name(&self) -> L10n {
|
||||
L10n::t("package_name", &LOCALES_NODE)
|
||||
}
|
||||
|
||||
fn description(&self) -> L10n {
|
||||
L10n::t("package_description", &LOCALES_NODE)
|
||||
}
|
||||
|
||||
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {
|
||||
scfg.route("/node", service::web::get().to(node));
|
||||
}
|
||||
|
||||
fn actions(&self) -> Vec<ActionBox> {
|
||||
actions![action::page::BeforePrepareBody::new(before_prepare_body).with_weight(-1)]
|
||||
}
|
||||
|
||||
fn migrations(&self) -> Vec<MigrationItem> {
|
||||
migrations![
|
||||
m20220316_000001_create_table_node_type,
|
||||
m20220316_000002_create_table_node,
|
||||
m20220316_000003_create_table_node_access,
|
||||
m20220316_000004_create_table_node_revision,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
async fn node(request: HttpRequest) -> ResultPage<Markup, ErrorPage> {
|
||||
Page::new(request).with_title(L10n::n("Nodo")).render()
|
||||
}
|
||||
|
||||
fn before_prepare_body(page: &mut Page) {
|
||||
page.alter_body_classes(ClassesOp::Add, "test-node");
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
package_name = Node
|
||||
package_description = Allows content to be submitted to the site and displayed on pages.
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
package_name = Nodo
|
||||
package_description = Permite enviar contenidos al sitio y mostrarlos en páginas.
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
pub mod m20220316_000001_create_table_node_type;
|
||||
pub mod m20220316_000002_create_table_node;
|
||||
pub mod m20220316_000003_create_table_node_access;
|
||||
pub mod m20220316_000004_create_table_node_revision;
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Iden)]
|
||||
enum NodeType {
|
||||
Table, // node_type: Stores information about all defined Node types.
|
||||
|
||||
Type, // The machine-readable name of this type.
|
||||
Name, // The human-readable name of this type.
|
||||
Description, // Descripción breve del tipo.
|
||||
Help, // Help information shown to the user when creating a Node of this type.
|
||||
HasTitle, // Boolean indicating whether this type uses the Node.Title field.
|
||||
TitleLabel, // The label displayed for the title field on the edit form.
|
||||
Custom, // A boolean indicating whether this type is defined by a module (FALSE) or
|
||||
// by a user via Add content type (TRUE).
|
||||
Locked, // A boolean indicating whether the administrator can change the machine
|
||||
// name of this type.
|
||||
Disabled, // A boolean indicating whether the node type is disabled.
|
||||
OrigType, // The original machine-readable name of this node type, this may be
|
||||
// different from the current type name if the locked field is 0.
|
||||
}
|
||||
|
||||
new_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(NodeType::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(NodeType::Type)
|
||||
.integer()
|
||||
.not_null()
|
||||
.auto_increment()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(NodeType::Name).string().not_null())
|
||||
.col(ColumnDef::new(NodeType::Description).string().not_null())
|
||||
.col(ColumnDef::new(NodeType::Help).string().not_null())
|
||||
.col(ColumnDef::new(NodeType::HasTitle).string().not_null())
|
||||
.col(ColumnDef::new(NodeType::TitleLabel).string().not_null())
|
||||
.col(ColumnDef::new(NodeType::Custom).string().not_null())
|
||||
.col(ColumnDef::new(NodeType::Locked).string().not_null())
|
||||
.col(ColumnDef::new(NodeType::Disabled).string().not_null())
|
||||
.col(ColumnDef::new(NodeType::OrigType).string().not_null())
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(NodeType::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Iden)]
|
||||
enum Node {
|
||||
Table, // node: The base table for nodes.
|
||||
|
||||
Nid, // The primary identifier for a node.
|
||||
Vid, // The current NodeRevision.vid version identifier.
|
||||
Type, // The NodeType.type of this node.
|
||||
Language, // The {languages}.language of this node.
|
||||
Title, // The title of this node, always treated as non-markup plain text.
|
||||
Uid, // The User.uid that owns this node; initially, this is the user that
|
||||
// created it.
|
||||
Status, // Boolean indicating whether the node is published (visible to
|
||||
// non-administrators).
|
||||
Created, // The Unix timestamp when the node was created.
|
||||
Changed, // The Unix timestamp when the node was most recently saved.
|
||||
Comment, // Whether comments are allowed on this node: 0 = no, 1 = closed (read
|
||||
// only), 2 = open (read/write).
|
||||
Promote, // Boolean indicating whether the node should be displayed on the front
|
||||
// page.
|
||||
Sticky, // Boolean indicating whether the node should be displayed at the top of
|
||||
// lists in which it appears.
|
||||
Tnid, // The translation set id for this node, which equals the node id of the
|
||||
// source post in each set.
|
||||
Translate, // A boolean indicating whether this translation page needs to be updated.
|
||||
}
|
||||
|
||||
new_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(Node::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(Node::Nid)
|
||||
.integer()
|
||||
.not_null()
|
||||
.auto_increment()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(Node::Vid).string().not_null())
|
||||
.col(ColumnDef::new(Node::Type).string().not_null())
|
||||
.col(ColumnDef::new(Node::Language).string().not_null())
|
||||
.col(ColumnDef::new(Node::Title).string().not_null())
|
||||
.col(ColumnDef::new(Node::Uid).string().not_null())
|
||||
.col(ColumnDef::new(Node::Status).string().not_null())
|
||||
.col(ColumnDef::new(Node::Created).string().not_null())
|
||||
.col(ColumnDef::new(Node::Changed).string().not_null())
|
||||
.col(ColumnDef::new(Node::Comment).string().not_null())
|
||||
.col(ColumnDef::new(Node::Promote).string().not_null())
|
||||
.col(ColumnDef::new(Node::Sticky).string().not_null())
|
||||
.col(ColumnDef::new(Node::Tnid).string().not_null())
|
||||
.col(ColumnDef::new(Node::Translate).string().not_null())
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(Node::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Iden)]
|
||||
enum NodeAccess {
|
||||
Table, // node_access: Identifies which realm/grant pairs a user must possess in
|
||||
// order to view, update, or delete specific nodes.
|
||||
|
||||
Nid, // The Node.nid this record affects.
|
||||
Gid, // The grant ID a user must possess in the specified realm to gain this
|
||||
// row's privileges on the node.
|
||||
Realm, // The realm in which the user must possess the grant ID. Each node access
|
||||
// node can define one or more realms.
|
||||
GrantView, // Boolean indicating whether a user with the realm/grant pair can view this
|
||||
// node.
|
||||
GrantUpdate, // Boolean indicating whether a user with the realm/grant pair can edit this
|
||||
// node.
|
||||
GrantDelete, // Boolean indicating whether a user with the realm/grant pair can delete
|
||||
// this node.
|
||||
}
|
||||
|
||||
new_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(NodeAccess::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(NodeAccess::Nid)
|
||||
.integer()
|
||||
.not_null()
|
||||
.auto_increment()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(NodeAccess::Gid).string().not_null())
|
||||
.col(ColumnDef::new(NodeAccess::Realm).string().not_null())
|
||||
.col(ColumnDef::new(NodeAccess::GrantView).string().not_null())
|
||||
.col(ColumnDef::new(NodeAccess::GrantUpdate).string().not_null())
|
||||
.col(ColumnDef::new(NodeAccess::GrantDelete).string().not_null())
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(NodeAccess::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Iden)]
|
||||
enum NodeRevision {
|
||||
Table, // node_revision: Stores information about each saved version of a Node.
|
||||
|
||||
Nid, // The Node this version belongs to.
|
||||
Vid, // The primary identifier for this version.
|
||||
Uid, // The User.uid that created this version.
|
||||
Title, // The title of this version.
|
||||
Log, // The log entry explaining the changes in this version.
|
||||
Timestamp, // A Unix timestamp indicating when this version was created.
|
||||
Status, // Boolean indicating whether the node (at the time of this revision) is
|
||||
// published (visible to non-administrators).
|
||||
Comment, // Whether comments are allowed on this node (at the time of this revision):
|
||||
// 0 = no, 1 = closed (read only), 2 = open (read/write).
|
||||
Promote, // Boolean indicating whether the node (at the time of this revision) should
|
||||
// be displayed on the front page.
|
||||
Sticky, // Boolean indicating whether the node (at the time of this revision) should
|
||||
// be displayed at the top of lists in which it appears.
|
||||
}
|
||||
|
||||
new_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(NodeRevision::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(NodeRevision::Nid)
|
||||
.integer()
|
||||
.not_null()
|
||||
.auto_increment()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(NodeRevision::Vid).string().not_null())
|
||||
.col(ColumnDef::new(NodeRevision::Uid).string().not_null())
|
||||
.col(ColumnDef::new(NodeRevision::Title).string().not_null())
|
||||
.col(ColumnDef::new(NodeRevision::Log).string().not_null())
|
||||
.col(ColumnDef::new(NodeRevision::Timestamp).string().not_null())
|
||||
.col(ColumnDef::new(NodeRevision::Status).string().not_null())
|
||||
.col(ColumnDef::new(NodeRevision::Comment).string().not_null())
|
||||
.col(ColumnDef::new(NodeRevision::Promote).string().not_null())
|
||||
.col(ColumnDef::new(NodeRevision::Sticky).string().not_null())
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(NodeRevision::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
[package]
|
||||
name = "pagetop-user"
|
||||
version = "0.0.19"
|
||||
edition = "2021"
|
||||
|
||||
description = "PageTop package for user, roles, permissions, and session management."
|
||||
homepage = "https://pagetop.cillero.es"
|
||||
repository = "https://github.com/manuelcillero/pagetop"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
authors = [
|
||||
"Manuel Cillero <manuel@cillero.es>"
|
||||
]
|
||||
categories = [
|
||||
"web-programming", "gui", "authentication"
|
||||
]
|
||||
keywords = [
|
||||
"pagetop", "user", "login", "grants", "preferences"
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
pagetop = { version = "0.0", path = "../../", features = ["database"], default-features = false }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
<div align="center">
|
||||
|
||||
<h1>PageTop User</h1>
|
||||
|
||||
<p>PageTop package for user, roles, permissions, and session management.</p>
|
||||
|
||||
[](#-license)
|
||||
[](https://docs.rs/pagetop-user)
|
||||
[](https://crates.io/crates/pagetop-user)
|
||||
[](https://crates.io/crates/pagetop-user)
|
||||
|
||||
</div>
|
||||
|
||||
# 📦 About PageTop
|
||||
|
||||
[PageTop](https://docs.rs/pagetop) is an opinionated web framework to build modular *Server-Side
|
||||
Rendering* web solutions.
|
||||
|
||||
|
||||
# 🚧 Warning
|
||||
|
||||
**PageTop** framework is currently in active development. The API is unstable and subject to
|
||||
frequent changes. Production use is not recommended until version **0.1.0**.
|
||||
|
||||
|
||||
# 📜 License
|
||||
|
||||
All code in this crate is dual-licensed under either:
|
||||
|
||||
* MIT License
|
||||
([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT)
|
||||
|
||||
* Apache License, Version 2.0,
|
||||
([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
||||
at your option. This means you can select the license you prefer! This dual-licensing approach is
|
||||
the de-facto standard in the Rust ecosystem.
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
static_locales!(LOCALES_USER);
|
||||
|
||||
mod migration;
|
||||
|
||||
pub struct User;
|
||||
|
||||
impl PackageTrait for User {
|
||||
fn name(&self) -> L10n {
|
||||
L10n::t("package_name", &LOCALES_USER)
|
||||
}
|
||||
|
||||
fn description(&self) -> L10n {
|
||||
L10n::t("package_description", &LOCALES_USER)
|
||||
}
|
||||
|
||||
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {
|
||||
scfg.route("/user/login", service::web::get().to(login));
|
||||
}
|
||||
|
||||
fn migrations(&self) -> Vec<MigrationItem> {
|
||||
migrations![
|
||||
m20220312_000001_create_table_role,
|
||||
m20220312_000002_create_table_role_permission,
|
||||
m20220312_000003_create_table_user,
|
||||
m20220312_000004_create_table_user_role,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
async fn login(request: HttpRequest) -> ResultPage<Markup, ErrorPage> {
|
||||
Page::new(request)
|
||||
.with_title(L10n::n("Identificación del usuario"))
|
||||
.with_component(
|
||||
flex::Container::new()
|
||||
.with_id("welcome")
|
||||
.add_item(flex::Item::with(form_login())),
|
||||
)
|
||||
.render()
|
||||
}
|
||||
|
||||
fn form_login() -> Form {
|
||||
Form::new()
|
||||
.with_id("user-login")
|
||||
.add_element(
|
||||
form::Input::textfield()
|
||||
.with_name("name")
|
||||
.with_label(L10n::t("username", &LOCALES_USER))
|
||||
.with_help_text(
|
||||
L10n::t("username_help", &LOCALES_USER)
|
||||
.with_arg("app", config::SETTINGS.app.name.to_owned()),
|
||||
)
|
||||
.with_autofocus(true),
|
||||
)
|
||||
.add_element(
|
||||
form::Input::password()
|
||||
.with_name("pass")
|
||||
.with_label(L10n::t("password", &LOCALES_USER))
|
||||
.with_help_text(L10n::t("password_help", &LOCALES_USER)),
|
||||
)
|
||||
.add_element(form::ActionButton::submit().with_value(L10n::t("login", &LOCALES_USER)))
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
package_name = User
|
||||
package_description = Manages the user registration and login system.
|
||||
|
||||
username = User name
|
||||
password = Password
|
||||
username_help = Enter your { $app } username.
|
||||
password_help = Enter the password that accompanies your username.
|
||||
login = Log in
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
package_name = Usuario
|
||||
package_description = Gestiona el registro de usuarios y el sistema de accesos.
|
||||
|
||||
username = Nombre de usuario
|
||||
password = Contraseña
|
||||
username_help = Introduzca su nombre de usuario en { $app }.
|
||||
password_help = Introduzca la contraseña asociada a su nombre de usuario.
|
||||
login = Iniciar sesión
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
pub mod m20220312_000001_create_table_role;
|
||||
pub mod m20220312_000002_create_table_role_permission;
|
||||
pub mod m20220312_000003_create_table_user;
|
||||
pub mod m20220312_000004_create_table_user_role;
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Iden)]
|
||||
enum Role {
|
||||
Table, // role: Store user roles.
|
||||
|
||||
Rid, // Primary Key: Unique role ID.
|
||||
Name, // Unique role name.
|
||||
Weight, // The weight of this role in listings and the user interface.
|
||||
}
|
||||
|
||||
new_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(Role::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(Role::Rid)
|
||||
.unsigned()
|
||||
.not_null()
|
||||
.auto_increment()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Role::Name)
|
||||
.string_len(64)
|
||||
.not_null()
|
||||
.unique_key(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(Role::Weight)
|
||||
.integer()
|
||||
.not_null()
|
||||
.default(10),
|
||||
)
|
||||
// INDEXES.
|
||||
.index(
|
||||
Index::create()
|
||||
.name("weight-name")
|
||||
.col(Role::Weight)
|
||||
.col(Role::Name),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Built-in roles.
|
||||
db::exec::<InsertStatement>(
|
||||
Query::insert()
|
||||
.into_table(Role::Table)
|
||||
.columns(vec![Role::Name, Role::Weight])
|
||||
.values_panic(vec!["anonymous".into(), "1".into()])
|
||||
.values_panic(vec!["authenticated".into(), "2".into()])
|
||||
.values_panic(vec!["administrator".into(), "3".into()]),
|
||||
)
|
||||
.await
|
||||
.map(|_| ())
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(Role::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Iden)]
|
||||
enum RolePermission {
|
||||
Table, // role_permission: Stores the permissions assigned to user roles.
|
||||
|
||||
Rid, // Foreign Key: Role::Rid.
|
||||
Permission, // A single permission granted to the role identified by Rid.
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
enum Role {
|
||||
Table,
|
||||
Rid,
|
||||
/* ... */
|
||||
}
|
||||
|
||||
new_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(RolePermission::Table)
|
||||
.if_not_exists()
|
||||
.col(ColumnDef::new(RolePermission::Rid).unsigned().not_null())
|
||||
.col(
|
||||
ColumnDef::new(RolePermission::Permission)
|
||||
.string_len(128)
|
||||
.not_null(),
|
||||
)
|
||||
// INDEXES.
|
||||
.primary_key(
|
||||
Index::create()
|
||||
.col(RolePermission::Rid)
|
||||
.col(RolePermission::Permission),
|
||||
)
|
||||
.index(
|
||||
Index::create()
|
||||
.name("permission")
|
||||
.col(RolePermission::Permission),
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_role_permission-rid")
|
||||
.from(RolePermission::Table, RolePermission::Rid)
|
||||
.to(Role::Table, Role::Rid)
|
||||
.on_delete(ForeignKeyAction::Restrict)
|
||||
.on_update(ForeignKeyAction::Restrict),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(RolePermission::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Iden)]
|
||||
enum User {
|
||||
Table, // user: Stores user data.
|
||||
|
||||
Uid, // Primary Key: Unique user ID.
|
||||
Name, // Unique user name.
|
||||
Pass, // User's password (hashed).
|
||||
Mail, // User's e-mail address.
|
||||
Created, // Timestamp for when user was created.
|
||||
Changed, // Timestamp for when user was changed.
|
||||
Access, // Timestamp for previous time user accessed the site.
|
||||
Login, // Timestamp for user's last login.
|
||||
Status, // Whether the user is active(1) or blocked(0).
|
||||
Timezone, // User's time zone.
|
||||
}
|
||||
|
||||
new_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(User::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(User::Uid)
|
||||
.unsigned()
|
||||
.not_null()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(
|
||||
ColumnDef::new(User::Name)
|
||||
.string_len(60)
|
||||
.not_null()
|
||||
.unique_key(),
|
||||
)
|
||||
.col(ColumnDef::new(User::Pass).string_len(128).not_null())
|
||||
.col(ColumnDef::new(User::Mail).string_len(255))
|
||||
.col(ColumnDef::new(User::Created).timestamp().not_null())
|
||||
.col(ColumnDef::new(User::Changed).timestamp().not_null())
|
||||
.col(ColumnDef::new(User::Access).timestamp().not_null())
|
||||
.col(ColumnDef::new(User::Login).timestamp().not_null())
|
||||
.col(ColumnDef::new(User::Status).boolean().not_null())
|
||||
.col(ColumnDef::new(User::Timezone).string_len(32))
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(User::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Iden)]
|
||||
enum UserRole {
|
||||
Table, // user_role: Maps users to roles.
|
||||
|
||||
Uid, // Foreign Key: User::Uid for user.
|
||||
Rid, // Foreign Key: Role::Rid for role.
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
enum User {
|
||||
Table,
|
||||
Uid,
|
||||
/* ... */
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
enum Role {
|
||||
Table,
|
||||
Rid,
|
||||
/* ... */
|
||||
}
|
||||
|
||||
new_migration!(Migration);
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(UserRole::Table)
|
||||
.if_not_exists()
|
||||
.col(ColumnDef::new(UserRole::Uid).unsigned().not_null())
|
||||
.col(ColumnDef::new(UserRole::Rid).unsigned().not_null())
|
||||
// INDEXES.
|
||||
.primary_key(Index::create().col(UserRole::Uid).col(UserRole::Rid))
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_user_role-uid")
|
||||
.from(UserRole::Table, UserRole::Uid)
|
||||
.to(User::Table, User::Uid)
|
||||
.on_delete(ForeignKeyAction::Restrict)
|
||||
.on_update(ForeignKeyAction::Restrict),
|
||||
)
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk_user_role-rid")
|
||||
.from(UserRole::Table, UserRole::Rid)
|
||||
.to(Role::Table, Role::Rid)
|
||||
.on_delete(ForeignKeyAction::Restrict)
|
||||
.on_update(ForeignKeyAction::Restrict),
|
||||
)
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(UserRole::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Ask the user which database system to use
|
||||
read -p "Which database system are you using? (mysql/postgresql/sqlite): " DB_SYSTEM
|
||||
|
||||
# Check if selected database system is installed
|
||||
if [ "$DB_SYSTEM" == "mysql" ]; then
|
||||
if ! command -v mysql &> /dev/null; then
|
||||
echo "mysql is not installed or not found in PATH. Please install mysql and try again."
|
||||
exit 1
|
||||
fi
|
||||
elif [ "$DB_SYSTEM" == "postgresql" ]; then
|
||||
if ! command -v psql &> /dev/null; then
|
||||
echo "postgresql is not installed or not found in PATH. Please install postgresql and try again."
|
||||
exit 1
|
||||
fi
|
||||
elif [ "$DB_SYSTEM" == "sqlite" ]; then
|
||||
if ! command -v sqlite3 &> /dev/null; then
|
||||
echo "sqlite3 is not installed or not found in PATH. Please install sqlite3 and try again."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "Invalid database system selected. Please choose either 'mysql', 'postgresql', or 'sqlite'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
EXIT_CODE=0
|
||||
|
||||
echo
|
||||
echo "You will be prompted to provide details for creating the Drust database."
|
||||
echo "Press ENTER to accept the default values."
|
||||
echo
|
||||
|
||||
if [ "$DB_SYSTEM" == "sqlite" ]; then
|
||||
DEFAULT_DB_NAME="drust.db"
|
||||
|
||||
# Only prompt for database name, as user and password are not used by SQLite
|
||||
read -p "Enter database name [$DEFAULT_DB_NAME]: " DB_NAME
|
||||
DB_NAME=${DB_NAME:-$DEFAULT_DB_NAME}
|
||||
|
||||
# For SQLite, just check if the database file exists and create it if it doesn't
|
||||
if [ ! -f "$DB_NAME" ]; then
|
||||
echo "Creating SQLite database file: $DB_NAME"
|
||||
sqlite3 "$DB_NAME" ".quit"
|
||||
EXIT_CODE=$?
|
||||
else
|
||||
echo "SQLite database file $DB_NAME already exists."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
DEFAULT_DB_NAME="drust"
|
||||
DEFAULT_DB_USER="drust"
|
||||
DEFAULT_DB_PASS="demo"
|
||||
DEFAULT_DB_HOST="localhost"
|
||||
|
||||
# Prompt for database details, allow defaults
|
||||
read -p "Enter database name [$DEFAULT_DB_NAME]: " DB_NAME
|
||||
DB_NAME=${DB_NAME:-$DEFAULT_DB_NAME}
|
||||
|
||||
read -p "Enter database user [$DEFAULT_DB_USER]: " DB_USER
|
||||
DB_USER=${DB_USER:-$DEFAULT_DB_USER}
|
||||
|
||||
read -p "Enter database password [$DEFAULT_DB_PASS]: " DB_PASS
|
||||
DB_PASS=${DB_PASS:-$DEFAULT_DB_PASS}
|
||||
|
||||
read -p "Enter database host [$DEFAULT_DB_HOST]: " DB_HOST
|
||||
DB_HOST=${DB_HOST:-$DEFAULT_DB_HOST}
|
||||
|
||||
# Prompt for database system root or another privileged user's credentials
|
||||
echo
|
||||
read -p "Enter $DB_SYSTEM root or admin user: " DB_ROOT_USER
|
||||
read -sp "Enter $DB_SYSTEM root or admin password: " DB_ROOT_PASS
|
||||
echo
|
||||
|
||||
# Confirm before proceeding
|
||||
echo
|
||||
echo "You are about to create the database \"$DB_NAME\" and assign privileges to user \"$DB_USER\"."
|
||||
read -p "Are you sure you want to proceed? (y/N): " confirm
|
||||
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
|
||||
echo "Operation cancelled."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Execute commands for MySQL or PostgreSQL
|
||||
if [ "$DB_SYSTEM" == "mysql" ]; then
|
||||
MYSQL_PWD="$DB_ROOT_PASS" mysql -u "$DB_ROOT_USER" -h "$DB_HOST" <<EOF
|
||||
CREATE DATABASE IF NOT EXISTS $DB_NAME;
|
||||
CREATE USER IF NOT EXISTS '$DB_USER'@'$DB_HOST' IDENTIFIED BY '$DB_PASS';
|
||||
GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USER'@'$DB_HOST';
|
||||
FLUSH PRIVILEGES;
|
||||
EOF
|
||||
elif [ "$DB_SYSTEM" == "postgresql" ]; then
|
||||
PGPASSWORD="$DB_ROOT_PASS" psql -U "$DB_ROOT_USER" -h "$DB_HOST" <<EOF
|
||||
CREATE DATABASE IF NOT EXISTS $DB_NAME;
|
||||
DO \$\$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT FROM pg_catalog.pg_user
|
||||
WHERE usename = '$DB_USER') THEN
|
||||
CREATE USER $DB_USER WITH ENCRYPTED PASSWORD '$DB_PASS';
|
||||
END IF;
|
||||
END
|
||||
\$\$;
|
||||
GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;
|
||||
EOF
|
||||
fi
|
||||
EXIT_CODE=$?
|
||||
fi
|
||||
|
||||
if [ $EXIT_CODE -eq 0 ]; then
|
||||
echo "Operation completed."
|
||||
else
|
||||
echo "An error occurred. Exit code: $EXIT_CODE"
|
||||
fi
|
||||
|
||||
# Exit the script with the mysql command's exit code
|
||||
exit $EXIT_CODE
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Ask the user which database system to use
|
||||
read -p "Which database system are you using? (mysql/postgresql/sqlite): " DB_SYSTEM
|
||||
|
||||
# Check if selected database system is installed
|
||||
if [ "$DB_SYSTEM" == "mysql" ]; then
|
||||
if ! command -v mysql &> /dev/null; then
|
||||
echo "mysql is not installed or not found in PATH. Please install mysql and try again."
|
||||
exit 1
|
||||
fi
|
||||
elif [ "$DB_SYSTEM" == "postgresql" ]; then
|
||||
if ! command -v psql &> /dev/null; then
|
||||
echo "postgresql is not installed or not found in PATH. Please install postgresql and try again."
|
||||
exit 1
|
||||
fi
|
||||
elif [ "$DB_SYSTEM" == "sqlite" ]; then
|
||||
if ! command -v sqlite3 &> /dev/null; then
|
||||
echo "sqlite3 is not installed or not found in PATH. Please install sqlite3 and try again."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "Invalid database system selected. Please choose either 'mysql', 'postgresql', or 'sqlite'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
EXIT_CODE=0
|
||||
|
||||
echo
|
||||
echo "You will be prompted to provide details to delete the Drust database."
|
||||
echo "Press ENTER to accept the default values."
|
||||
echo
|
||||
|
||||
if [ "$DB_SYSTEM" == "sqlite" ]; then
|
||||
DEFAULT_DB_NAME="drust.db"
|
||||
|
||||
# Only prompt for database name
|
||||
read -p "Enter database name to delete [$DEFAULT_DB_NAME]: " DB_NAME
|
||||
DB_NAME=${DB_NAME:-$DEFAULT_DB_NAME}
|
||||
|
||||
# For SQLite, check if the database file exists and delete it
|
||||
if [ -f "$DB_NAME" ]; then
|
||||
echo "Deleting SQLite database file: $DB_NAME"
|
||||
rm "$DB_NAME"
|
||||
EXIT_CODE=$?
|
||||
else
|
||||
echo "SQLite database file $DB_NAME does not exist."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
DEFAULT_DB_NAME="drust"
|
||||
DEFAULT_DB_HOST="localhost"
|
||||
|
||||
# Prompt for database details, allow defaults
|
||||
read -p "Enter database name to delete [$DEFAULT_DB_NAME]: " DB_NAME
|
||||
DB_NAME=${DB_NAME:-$DEFAULT_DB_NAME}
|
||||
|
||||
read -p "Enter database host [$DEFAULT_DB_HOST]: " DB_HOST
|
||||
DB_HOST=${DB_HOST:-$DEFAULT_DB_HOST}
|
||||
|
||||
# Prompt for database system root or another privileged user's credentials
|
||||
echo
|
||||
read -p "Enter $DB_SYSTEM root or admin user: " DB_ROOT_USER
|
||||
read -sp "Enter $DB_SYSTEM root or admin password: " DB_ROOT_PASS
|
||||
echo
|
||||
|
||||
# Confirm before proceeding
|
||||
echo
|
||||
echo "You are about to delete the database \"$DB_NAME\"."
|
||||
read -p "Are you sure you want to proceed? (y/N): " confirm
|
||||
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
|
||||
echo "Operation cancelled."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Execute commands for MySQL or PostgreSQL
|
||||
if [ "$DB_SYSTEM" == "mysql" ]; then
|
||||
MYSQL_PWD="$DB_ROOT_PASS" mysql -u "$DB_ROOT_USER" -h "$DB_HOST" <<EOF
|
||||
DROP DATABASE $DB_NAME;
|
||||
EOF
|
||||
elif [ "$DB_SYSTEM" == "postgresql" ]; then
|
||||
PGPASSWORD="$DB_ROOT_PASS" psql -U "$DB_ROOT_USER" -h "$DB_HOST" <<EOF
|
||||
DROP DATABASE $DB_NAME;
|
||||
EOF
|
||||
fi
|
||||
EXIT_CODE=$?
|
||||
fi
|
||||
|
||||
if [ $EXIT_CODE -eq 0 ]; then
|
||||
echo "Database deletion completed successfully."
|
||||
else
|
||||
echo "An error occurred during database deletion. Exit code: $EXIT_CODE"
|
||||
fi
|
||||
|
||||
# Exit the script with the mysql command's exit code
|
||||
exit $EXIT_CODE
|
||||
|
|
@ -55,13 +55,6 @@ HELPERS=(
|
|||
pagetop-macros
|
||||
pagetop-build
|
||||
)
|
||||
PACKAGES=(
|
||||
pagetop-user
|
||||
pagetop-admin
|
||||
pagetop-node
|
||||
pagetop-bootsier
|
||||
pagetop-bulmix
|
||||
)
|
||||
|
||||
# Publish all helper crates
|
||||
pushd helpers > /dev/null 2>&1
|
||||
|
|
@ -75,15 +68,6 @@ popd > /dev/null 2>&1
|
|||
# Publish the root crate
|
||||
CRATE=pagetop; publish_crate
|
||||
|
||||
# Publish all main packages
|
||||
pushd packages > /dev/null 2>&1
|
||||
for CRATE in "${PACKAGES[@]}"; do
|
||||
pushd "$CRATE" > /dev/null 2>&1
|
||||
publish_crate
|
||||
popd > /dev/null 2>&1
|
||||
done
|
||||
popd > /dev/null 2>&1
|
||||
|
||||
# Reset local Git repository to clean licenses after publishing
|
||||
echo -e "\nCleaning local state"
|
||||
git reset HEAD --hard
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue