Modifica la estructura general del código fuente
Importante actualización que reorganiza el código fuente de PageTop. Usa Cargo para crear un espacio de trabajo con los diferentes proyectos que estructuran las funcionalidades de PageTop en módulos interdependientes que se integran en Drust para construir una solución web para la gestión de contenidos.
This commit is contained in:
parent
4b5d8ce38a
commit
ab0ac11f65
83 changed files with 115 additions and 81 deletions
|
|
@ -1,105 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
pub struct Block {
|
||||
renderable: fn() -> bool,
|
||||
weight : i8,
|
||||
id : Option<String>,
|
||||
title : Option<String>,
|
||||
markup : Vec<Markup>,
|
||||
template : String,
|
||||
}
|
||||
|
||||
impl PageComponent for Block {
|
||||
|
||||
fn prepare() -> Self {
|
||||
Block {
|
||||
renderable: always,
|
||||
weight : 0,
|
||||
id : None,
|
||||
title : None,
|
||||
markup : Vec::new(),
|
||||
template : "default".to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_renderable(&self) -> bool {
|
||||
(self.renderable)()
|
||||
}
|
||||
|
||||
fn weight(&self) -> i8 {
|
||||
self.weight
|
||||
}
|
||||
|
||||
fn default_render(&self, assets: &mut PageAssets) -> Markup {
|
||||
let id = assets.serial_id(self.name(), self.id());
|
||||
html! {
|
||||
div id=(id) class="block" {
|
||||
@if self.title != None {
|
||||
h2 class="block-title" { (self.title()) }
|
||||
}
|
||||
div class="block-body" {
|
||||
@for markup in self.markup.iter() {
|
||||
(*markup)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Block {
|
||||
|
||||
pub fn markup(markup: Markup) -> Self {
|
||||
Block::prepare().add_markup(markup)
|
||||
}
|
||||
|
||||
// Block BUILDER.
|
||||
|
||||
pub fn with_renderable(mut self, renderable: fn() -> bool) -> Self {
|
||||
self.renderable = renderable;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_weight(mut self, weight: i8) -> Self {
|
||||
self.weight = weight;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_id(mut self, id: &str) -> Self {
|
||||
self.id = util::valid_id(id);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_title(mut self, title: &str) -> Self {
|
||||
self.title = util::optional_str(title);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_markup(mut self, markup: Markup) -> Self {
|
||||
self.markup.push(markup);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn using_template(mut self, template: &str) -> Self {
|
||||
self.template = template.to_owned();
|
||||
self
|
||||
}
|
||||
|
||||
// Block GETTERS.
|
||||
|
||||
pub fn id(&self) -> &str {
|
||||
util::assigned_str(&self.id)
|
||||
}
|
||||
|
||||
pub fn title(&self) -> &str {
|
||||
util::assigned_str(&self.title)
|
||||
}
|
||||
|
||||
pub fn template(&self) -> &str {
|
||||
self.template.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
fn always() -> bool {
|
||||
true
|
||||
}
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
pub struct Chunck {
|
||||
renderable: fn() -> bool,
|
||||
weight : i8,
|
||||
markup : Vec<Markup>,
|
||||
template : String,
|
||||
}
|
||||
|
||||
impl PageComponent for Chunck {
|
||||
|
||||
fn prepare() -> Self {
|
||||
Chunck {
|
||||
renderable: always,
|
||||
weight : 0,
|
||||
markup : Vec::new(),
|
||||
template : "default".to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_renderable(&self) -> bool {
|
||||
(self.renderable)()
|
||||
}
|
||||
|
||||
fn weight(&self) -> i8 {
|
||||
self.weight
|
||||
}
|
||||
|
||||
fn default_render(&self, _: &mut PageAssets) -> Markup {
|
||||
html! {
|
||||
@for markup in self.markup.iter() {
|
||||
(*markup)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Chunck {
|
||||
|
||||
pub fn markup(markup: Markup) -> Self {
|
||||
Chunck::prepare().add_markup(markup)
|
||||
}
|
||||
|
||||
// Chunck BUILDER.
|
||||
|
||||
pub fn with_renderable(mut self, renderable: fn() -> bool) -> Self {
|
||||
self.renderable = renderable;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_weight(mut self, weight: i8) -> Self {
|
||||
self.weight = weight;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_markup(mut self, markup: Markup) -> Self {
|
||||
self.markup.push(markup);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn using_template(mut self, template: &str) -> Self {
|
||||
self.template = template.to_owned();
|
||||
self
|
||||
}
|
||||
|
||||
// Chunck GETTERS.
|
||||
|
||||
pub fn template(&self) -> &str {
|
||||
self.template.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
fn always() -> bool {
|
||||
true
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
enum ContainerType { Column, Row, Wrapper }
|
||||
|
||||
pub struct Container {
|
||||
renderable: fn() -> bool,
|
||||
weight : i8,
|
||||
id : Option<String>,
|
||||
container : ContainerType,
|
||||
components: PageContainer,
|
||||
template : String,
|
||||
}
|
||||
|
||||
impl PageComponent for Container {
|
||||
|
||||
fn prepare() -> Self {
|
||||
Container {
|
||||
renderable: always,
|
||||
weight : 0,
|
||||
id : None,
|
||||
container : ContainerType::Wrapper,
|
||||
components: PageContainer::new(),
|
||||
template : "default".to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_renderable(&self) -> bool {
|
||||
(self.renderable)()
|
||||
}
|
||||
|
||||
fn weight(&self) -> i8 {
|
||||
self.weight
|
||||
}
|
||||
|
||||
fn default_render(&self, assets: &mut PageAssets) -> Markup {
|
||||
let classes = match self.container {
|
||||
ContainerType::Wrapper => "container",
|
||||
ContainerType::Row => "row",
|
||||
ContainerType::Column => "col",
|
||||
};
|
||||
html! {
|
||||
div id=[&self.id] class=(classes) {
|
||||
(self.components.render(assets))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Container {
|
||||
|
||||
pub fn row() -> Self {
|
||||
let mut grid = Container::prepare();
|
||||
grid.container = ContainerType::Row;
|
||||
grid
|
||||
}
|
||||
|
||||
pub fn column() -> Self {
|
||||
let mut grid = Container::prepare();
|
||||
grid.container = ContainerType::Column;
|
||||
grid
|
||||
}
|
||||
|
||||
// Container BUILDER.
|
||||
|
||||
pub fn with_renderable(mut self, renderable: fn() -> bool) -> Self {
|
||||
self.renderable = renderable;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_weight(mut self, weight: i8) -> Self {
|
||||
self.weight = weight;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_id(mut self, id: &str) -> Self {
|
||||
self.id = util::valid_id(id);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add(mut self, component: impl PageComponent) -> Self {
|
||||
self.components.add(component);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn using_template(mut self, template: &str) -> Self {
|
||||
self.template = template.to_owned();
|
||||
self
|
||||
}
|
||||
|
||||
// Container GETTERS.
|
||||
|
||||
pub fn id(&self) -> &str {
|
||||
util::assigned_str(&self.id)
|
||||
}
|
||||
|
||||
pub fn template(&self) -> &str {
|
||||
self.template.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
fn always() -> bool {
|
||||
true
|
||||
}
|
||||
|
|
@ -1,160 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
enum ButtonType {Button, Reset, Submit}
|
||||
|
||||
pub struct Button {
|
||||
renderable : fn() -> bool,
|
||||
weight : i8,
|
||||
button_type: ButtonType,
|
||||
name : Option<String>,
|
||||
value : Option<String>,
|
||||
autofocus : Option<String>,
|
||||
disabled : Option<String>,
|
||||
template : String,
|
||||
}
|
||||
|
||||
impl PageComponent for Button {
|
||||
|
||||
fn prepare() -> Self {
|
||||
Button {
|
||||
renderable : always,
|
||||
weight : 0,
|
||||
button_type: ButtonType::Button,
|
||||
name : None,
|
||||
value : None,
|
||||
autofocus : None,
|
||||
disabled : None,
|
||||
template : "default".to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_renderable(&self) -> bool {
|
||||
(self.renderable)()
|
||||
}
|
||||
|
||||
fn weight(&self) -> i8 {
|
||||
self.weight
|
||||
}
|
||||
|
||||
fn default_render(&self, _: &mut PageAssets) -> Markup {
|
||||
let (button_type, button_class) = match &self.button_type {
|
||||
ButtonType::Button => ("button", "btn btn-primary form-button"),
|
||||
ButtonType::Reset => ("reset", "btn btn-primary form-reset" ),
|
||||
ButtonType::Submit => ("submit", "btn btn-primary form-submit")
|
||||
};
|
||||
let id_item = match &self.name {
|
||||
Some(name) => Some(format!("edit-{}", name)),
|
||||
_ => None
|
||||
};
|
||||
html! {
|
||||
button
|
||||
type=(button_type)
|
||||
id=[&id_item]
|
||||
class=(button_class)
|
||||
name=[&self.name]
|
||||
value=[&self.value]
|
||||
autofocus=[&self.autofocus]
|
||||
disabled=[&self.disabled]
|
||||
{
|
||||
@match &self.value {
|
||||
Some(value) => (value),
|
||||
_ => ""
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Button {
|
||||
|
||||
pub fn button(value: &str) -> Self {
|
||||
Button::prepare().with_value(value)
|
||||
}
|
||||
|
||||
pub fn reset(value: &str) -> Self {
|
||||
let mut button = Button::prepare().with_value(value);
|
||||
button.button_type = ButtonType::Reset;
|
||||
button
|
||||
}
|
||||
|
||||
pub fn submit(value: &str) -> Self {
|
||||
let mut button = Button::prepare().with_value(value);
|
||||
button.button_type = ButtonType::Submit;
|
||||
button
|
||||
}
|
||||
|
||||
// Button BUILDER.
|
||||
|
||||
pub fn with_renderable(mut self, renderable: fn() -> bool) -> Self {
|
||||
self.renderable = renderable;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_weight(mut self, weight: i8) -> Self {
|
||||
self.weight = weight;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_name(mut self, name: &str) -> Self {
|
||||
self.name = util::valid_id(name);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_value(mut self, value: &str) -> Self {
|
||||
self.value = util::optional_str(value);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn autofocus(mut self, toggle: bool) -> Self {
|
||||
self.autofocus = match toggle {
|
||||
true => Some("autofocus".to_owned()),
|
||||
false => None
|
||||
};
|
||||
self
|
||||
}
|
||||
|
||||
pub fn disabled(mut self, toggle: bool) -> Self {
|
||||
self.disabled = match toggle {
|
||||
true => Some("disabled".to_owned()),
|
||||
false => None
|
||||
};
|
||||
self
|
||||
}
|
||||
|
||||
pub fn using_template(mut self, template: &str) -> Self {
|
||||
self.template = template.to_owned();
|
||||
self
|
||||
}
|
||||
|
||||
// Button GETTERS.
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
util::assigned_str(&self.name)
|
||||
}
|
||||
|
||||
pub fn value(&self) -> &str {
|
||||
util::assigned_str(&self.value)
|
||||
}
|
||||
|
||||
pub fn has_autofocus(&self) -> bool {
|
||||
match &self.autofocus {
|
||||
Some(_) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_disabled(&self) -> bool {
|
||||
match &self.disabled {
|
||||
Some(_) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn template(&self) -> &str {
|
||||
self.template.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
fn always() -> bool {
|
||||
true
|
||||
}
|
||||
|
|
@ -1,243 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
pub struct Date {
|
||||
renderable : fn() -> bool,
|
||||
weight : i8,
|
||||
name : Option<String>,
|
||||
value : Option<String>,
|
||||
label : Option<String>,
|
||||
placeholder : Option<String>,
|
||||
autofocus : Option<String>,
|
||||
autocomplete: Option<String>,
|
||||
disabled : Option<String>,
|
||||
readonly : Option<String>,
|
||||
required : Option<String>,
|
||||
help_text : Option<String>,
|
||||
template : String,
|
||||
}
|
||||
|
||||
impl PageComponent for Date {
|
||||
|
||||
fn prepare() -> Self {
|
||||
Date {
|
||||
renderable : always,
|
||||
weight : 0,
|
||||
name : None,
|
||||
value : None,
|
||||
label : None,
|
||||
placeholder : None,
|
||||
autofocus : None,
|
||||
autocomplete: None,
|
||||
disabled : None,
|
||||
readonly : None,
|
||||
required : None,
|
||||
help_text : None,
|
||||
template : "default".to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_renderable(&self) -> bool {
|
||||
(self.renderable)()
|
||||
}
|
||||
|
||||
fn weight(&self) -> i8 {
|
||||
self.weight
|
||||
}
|
||||
|
||||
fn default_render(&self, _: &mut PageAssets) -> Markup {
|
||||
let (class_item, id_item) = match &self.name {
|
||||
Some(name) => (
|
||||
format!("form-item form-item-{} form-type-date", name),
|
||||
Some(format!("edit-{}", name))
|
||||
),
|
||||
None => (
|
||||
"form-item form-type-date".to_owned(),
|
||||
None
|
||||
)
|
||||
};
|
||||
html! {
|
||||
div class=(class_item) {
|
||||
@if self.label != None {
|
||||
label class="form-label" for=[&id_item] {
|
||||
(self.label()) " "
|
||||
@if self.required != None {
|
||||
span
|
||||
class="form-required"
|
||||
title="Este campo es obligatorio."
|
||||
{
|
||||
"*"
|
||||
} " "
|
||||
}
|
||||
}
|
||||
}
|
||||
input
|
||||
type="date"
|
||||
id=[&id_item]
|
||||
class="form-control"
|
||||
name=[&self.name]
|
||||
value=[&self.value]
|
||||
placeholder=[&self.placeholder]
|
||||
autofocus=[&self.autofocus]
|
||||
autocomplete=[&self.autocomplete]
|
||||
readonly=[&self.readonly]
|
||||
required=[&self.required]
|
||||
disabled=[&self.disabled];
|
||||
@if self.help_text != None {
|
||||
div class="form-text" {
|
||||
(self.help_text())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Date {
|
||||
|
||||
// Date BUILDER.
|
||||
|
||||
pub fn with_renderable(mut self, renderable: fn() -> bool) -> Self {
|
||||
self.renderable = renderable;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_weight(mut self, weight: i8) -> Self {
|
||||
self.weight = weight;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_name(mut self, name: &str) -> Self {
|
||||
self.name = util::valid_id(name);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_value(mut self, value: &str) -> Self {
|
||||
self.value = util::optional_str(value);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_label(mut self, label: &str) -> Self {
|
||||
self.label = util::optional_str(label);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_placeholder(mut self, placeholder: &str) -> Self {
|
||||
self.placeholder = util::optional_str(placeholder);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn autofocus(mut self, toggle: bool) -> Self {
|
||||
self.autofocus = match toggle {
|
||||
true => Some("autofocus".to_owned()),
|
||||
false => None
|
||||
};
|
||||
self
|
||||
}
|
||||
|
||||
pub fn autocomplete(mut self, toggle: bool) -> Self {
|
||||
self.autocomplete = match toggle {
|
||||
true => None,
|
||||
false => Some("off".to_owned())
|
||||
};
|
||||
self
|
||||
}
|
||||
|
||||
pub fn disabled(mut self, toggle: bool) -> Self {
|
||||
self.disabled = match toggle {
|
||||
true => Some("disabled".to_owned()),
|
||||
false => None
|
||||
};
|
||||
self
|
||||
}
|
||||
|
||||
pub fn readonly(mut self, toggle: bool) -> Self {
|
||||
self.readonly = match toggle {
|
||||
true => Some("readonly".to_owned()),
|
||||
false => None
|
||||
};
|
||||
self
|
||||
}
|
||||
|
||||
pub fn required(mut self, toggle: bool) -> Self {
|
||||
self.required = match toggle {
|
||||
true => Some("required".to_owned()),
|
||||
false => None
|
||||
};
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_help_text(mut self, help_text: &str) -> Self {
|
||||
self.help_text = util::optional_str(help_text);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn using_template(mut self, template: &str) -> Self {
|
||||
self.template = template.to_owned();
|
||||
self
|
||||
}
|
||||
|
||||
// Date GETTERS.
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
util::assigned_str(&self.name)
|
||||
}
|
||||
|
||||
pub fn value(&self) -> &str {
|
||||
util::assigned_str(&self.value)
|
||||
}
|
||||
|
||||
pub fn label(&self) -> &str {
|
||||
util::assigned_str(&self.label)
|
||||
}
|
||||
|
||||
pub fn placeholder(&self) -> &str {
|
||||
util::assigned_str(&self.placeholder)
|
||||
}
|
||||
|
||||
pub fn has_autofocus(&self) -> bool {
|
||||
match &self.autofocus {
|
||||
Some(_) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_autocomplete(&self) -> bool {
|
||||
match &self.autocomplete {
|
||||
Some(_) => false,
|
||||
_ => true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_disabled(&self) -> bool {
|
||||
match &self.disabled {
|
||||
Some(_) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_readonly(&self) -> bool {
|
||||
match &self.readonly {
|
||||
Some(_) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_required(&self) -> bool {
|
||||
match &self.required {
|
||||
Some(_) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn help_text(&self) -> &str {
|
||||
util::assigned_str(&self.help_text)
|
||||
}
|
||||
|
||||
pub fn template(&self) -> &str {
|
||||
self.template.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
fn always() -> bool {
|
||||
true
|
||||
}
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
pub enum FormMethod {Get, Post}
|
||||
|
||||
pub struct Form {
|
||||
renderable: fn() -> bool,
|
||||
weight : i8,
|
||||
id : Option<String>,
|
||||
action : Option<String>,
|
||||
method : FormMethod,
|
||||
charset : Option<String>,
|
||||
elements : PageContainer,
|
||||
template : String,
|
||||
}
|
||||
|
||||
impl PageComponent for Form {
|
||||
|
||||
fn prepare() -> Self {
|
||||
Form {
|
||||
renderable: always,
|
||||
weight : 0,
|
||||
id : None,
|
||||
action : None,
|
||||
method : FormMethod::Post,
|
||||
charset : Some("UTF-8".to_owned()),
|
||||
elements : PageContainer::new(),
|
||||
template : "default".to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_renderable(&self) -> bool {
|
||||
(self.renderable)()
|
||||
}
|
||||
|
||||
fn weight(&self) -> i8 {
|
||||
self.weight
|
||||
}
|
||||
|
||||
fn default_render(&self, assets: &mut PageAssets) -> Markup {
|
||||
let method = match self.method {
|
||||
FormMethod::Get => None,
|
||||
FormMethod::Post => Some("post".to_owned())
|
||||
};
|
||||
html! {
|
||||
form
|
||||
id=[&self.id]
|
||||
action=[&self.action]
|
||||
method=[method]
|
||||
accept-charset=[&self.charset]
|
||||
{
|
||||
div {
|
||||
(self.elements.render(assets))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Form {
|
||||
|
||||
// Form BUILDER.
|
||||
|
||||
pub fn with_renderable(mut self, renderable: fn() -> bool) -> Self {
|
||||
self.renderable = renderable;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_weight(mut self, weight: i8) -> Self {
|
||||
self.weight = weight;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_id(mut self, id: &str) -> Self {
|
||||
self.id = util::valid_id(id);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_action(mut self, action: &str) -> Self {
|
||||
self.action = util::optional_str(action);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_method(mut self, method: FormMethod) -> Self {
|
||||
self.method = method;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_charset(mut self, charset: &str) -> Self {
|
||||
self.charset = util::optional_str(charset);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add(mut self, element: impl PageComponent) -> Self {
|
||||
self.elements.add(element);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn using_template(mut self, template: &str) -> Self {
|
||||
self.template = template.to_owned();
|
||||
self
|
||||
}
|
||||
|
||||
// Form GETTERS.
|
||||
|
||||
pub fn id(&self) -> &str {
|
||||
util::assigned_str(&self.id)
|
||||
}
|
||||
|
||||
pub fn action(&self) -> &str {
|
||||
util::assigned_str(&self.action)
|
||||
}
|
||||
|
||||
pub fn method(&self) -> &str {
|
||||
match &self.method {
|
||||
FormMethod::Get => "get",
|
||||
FormMethod::Post => "post"
|
||||
}
|
||||
}
|
||||
|
||||
pub fn charset(&self) -> &str {
|
||||
util::assigned_str(&self.charset)
|
||||
}
|
||||
|
||||
pub fn template(&self) -> &str {
|
||||
self.template.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
fn always() -> bool {
|
||||
true
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
pub struct Hidden {
|
||||
weight : i8,
|
||||
name : Option<String>,
|
||||
value : Option<String>,
|
||||
}
|
||||
|
||||
impl PageComponent for Hidden {
|
||||
|
||||
fn prepare() -> Self {
|
||||
Hidden {
|
||||
weight : 0,
|
||||
name : None,
|
||||
value : None,
|
||||
}
|
||||
}
|
||||
|
||||
fn weight(&self) -> i8 {
|
||||
self.weight
|
||||
}
|
||||
|
||||
fn default_render(&self, _: &mut PageAssets) -> Markup {
|
||||
let id_item = match &self.name {
|
||||
Some(name) => Some(format!("value-{}", name)),
|
||||
_ => None
|
||||
};
|
||||
html! {
|
||||
input
|
||||
type="hidden"
|
||||
id=[&id_item]
|
||||
name=[&self.name]
|
||||
value=[&self.value];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Hidden {
|
||||
|
||||
pub fn set(name: &str, value: &str) -> Self {
|
||||
Hidden::prepare().with_name(name).with_value(value)
|
||||
}
|
||||
|
||||
// Hidden BUILDER.
|
||||
|
||||
pub fn with_weight(mut self, weight: i8) -> Self {
|
||||
self.weight = weight;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_name(mut self, name: &str) -> Self {
|
||||
self.name = util::valid_id(name);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_value(mut self, value: &str) -> Self {
|
||||
self.value = util::optional_str(value);
|
||||
self
|
||||
}
|
||||
|
||||
// Hidden GETTERS.
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
util::assigned_str(&self.name)
|
||||
}
|
||||
|
||||
pub fn value(&self) -> &str {
|
||||
util::assigned_str(&self.value)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,325 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
enum InputType {Email, Password, Search, Telephone, Textfield, Url}
|
||||
|
||||
pub struct Input {
|
||||
renderable : fn() -> bool,
|
||||
weight : i8,
|
||||
input_type : InputType,
|
||||
name : Option<String>,
|
||||
value : Option<String>,
|
||||
label : Option<String>,
|
||||
size : Option<u16>,
|
||||
minlength : Option<u16>,
|
||||
maxlength : Option<u16>,
|
||||
placeholder : Option<String>,
|
||||
autofocus : Option<String>,
|
||||
autocomplete: Option<String>,
|
||||
disabled : Option<String>,
|
||||
readonly : Option<String>,
|
||||
required : Option<String>,
|
||||
help_text : Option<String>,
|
||||
template : String,
|
||||
}
|
||||
|
||||
impl PageComponent for Input {
|
||||
|
||||
fn prepare() -> Self {
|
||||
Input {
|
||||
renderable : always,
|
||||
weight : 0,
|
||||
input_type : InputType::Textfield,
|
||||
name : None,
|
||||
value : None,
|
||||
label : None,
|
||||
size : Some(60),
|
||||
minlength : None,
|
||||
maxlength : Some(128),
|
||||
placeholder : None,
|
||||
autofocus : None,
|
||||
autocomplete: None,
|
||||
disabled : None,
|
||||
readonly : None,
|
||||
required : None,
|
||||
help_text : None,
|
||||
template : "default".to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_renderable(&self) -> bool {
|
||||
(self.renderable)()
|
||||
}
|
||||
|
||||
fn weight(&self) -> i8 {
|
||||
self.weight
|
||||
}
|
||||
|
||||
fn default_render(&self, _: &mut PageAssets) -> Markup {
|
||||
let (input_type, class_type) = match &self.input_type {
|
||||
InputType::Email => ("email", "form-type-email"),
|
||||
InputType::Password => ("password", "form-type-password"),
|
||||
InputType::Search => ("search", "form-type-search"),
|
||||
InputType::Telephone => ("tel", "form-type-telephone"),
|
||||
InputType::Textfield => ("text", "form-type-textfield"),
|
||||
InputType::Url => ("url", "form-type-url")
|
||||
};
|
||||
let (class_item, id_item) = match &self.name {
|
||||
Some(name) => (
|
||||
format!("form-item form-item-{} {}", name, class_type),
|
||||
Some(format!("edit-{}", name))
|
||||
),
|
||||
None => (
|
||||
format!("form-item {}", class_type),
|
||||
None
|
||||
)
|
||||
};
|
||||
html! {
|
||||
div class=(class_item) {
|
||||
@if self.label != None {
|
||||
label class="form-label" for=[&id_item] {
|
||||
(self.label()) " "
|
||||
@if self.required != None {
|
||||
span
|
||||
class="form-required"
|
||||
title="Este campo es obligatorio."
|
||||
{
|
||||
"*"
|
||||
} " "
|
||||
}
|
||||
}
|
||||
}
|
||||
input
|
||||
type=(input_type)
|
||||
id=[&id_item]
|
||||
class="form-control"
|
||||
name=[&self.name]
|
||||
value=[&self.value]
|
||||
size=[self.size]
|
||||
minlength=[self.minlength]
|
||||
maxlength=[self.maxlength]
|
||||
placeholder=[&self.placeholder]
|
||||
autofocus=[&self.autofocus]
|
||||
autocomplete=[&self.autocomplete]
|
||||
readonly=[&self.readonly]
|
||||
required=[&self.required]
|
||||
disabled=[&self.disabled];
|
||||
@if self.help_text != None {
|
||||
div class="form-text" {
|
||||
(self.help_text())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Input {
|
||||
|
||||
pub fn textfield() -> Self {
|
||||
Input::prepare()
|
||||
}
|
||||
|
||||
pub fn password() -> Self {
|
||||
let mut input = Input::prepare();
|
||||
input.input_type = InputType::Password;
|
||||
input
|
||||
}
|
||||
|
||||
pub fn search() -> Self {
|
||||
let mut input = Input::prepare();
|
||||
input.input_type = InputType::Search;
|
||||
input
|
||||
}
|
||||
|
||||
pub fn email() -> Self {
|
||||
let mut input = Input::prepare();
|
||||
input.input_type = InputType::Email;
|
||||
input
|
||||
}
|
||||
|
||||
pub fn telephone() -> Self {
|
||||
let mut input = Input::prepare();
|
||||
input.input_type = InputType::Telephone;
|
||||
input
|
||||
}
|
||||
|
||||
pub fn url() -> Self {
|
||||
let mut input = Input::prepare();
|
||||
input.input_type = InputType::Url;
|
||||
input
|
||||
}
|
||||
|
||||
// Input BUILDER.
|
||||
|
||||
pub fn with_renderable(mut self, renderable: fn() -> bool) -> Self {
|
||||
self.renderable = renderable;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_weight(mut self, weight: i8) -> Self {
|
||||
self.weight = weight;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_name(mut self, name: &str) -> Self {
|
||||
self.name = util::valid_id(name);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_value(mut self, value: &str) -> Self {
|
||||
self.value = util::optional_str(value);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_label(mut self, label: &str) -> Self {
|
||||
self.label = util::optional_str(label);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_size(mut self, size: Option<u16>) -> Self {
|
||||
self.size = size;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_minlength(mut self, minlength: Option<u16>) -> Self {
|
||||
self.minlength = minlength;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_maxlength(mut self, maxlength: Option<u16>) -> Self {
|
||||
self.maxlength = maxlength;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_placeholder(mut self, placeholder: &str) -> Self {
|
||||
self.placeholder = util::optional_str(placeholder);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn autofocus(mut self, toggle: bool) -> Self {
|
||||
self.autofocus = match toggle {
|
||||
true => Some("autofocus".to_owned()),
|
||||
false => None
|
||||
};
|
||||
self
|
||||
}
|
||||
|
||||
pub fn autocomplete(mut self, toggle: bool) -> Self {
|
||||
self.autocomplete = match toggle {
|
||||
true => None,
|
||||
false => Some("off".to_owned())
|
||||
};
|
||||
self
|
||||
}
|
||||
|
||||
pub fn disabled(mut self, toggle: bool) -> Self {
|
||||
self.disabled = match toggle {
|
||||
true => Some("disabled".to_owned()),
|
||||
false => None
|
||||
};
|
||||
self
|
||||
}
|
||||
|
||||
pub fn readonly(mut self, toggle: bool) -> Self {
|
||||
self.readonly = match toggle {
|
||||
true => Some("readonly".to_owned()),
|
||||
false => None
|
||||
};
|
||||
self
|
||||
}
|
||||
|
||||
pub fn required(mut self, toggle: bool) -> Self {
|
||||
self.required = match toggle {
|
||||
true => Some("required".to_owned()),
|
||||
false => None
|
||||
};
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_help_text(mut self, help_text: &str) -> Self {
|
||||
self.help_text = util::optional_str(help_text);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn using_template(mut self, template: &str) -> Self {
|
||||
self.template = template.to_owned();
|
||||
self
|
||||
}
|
||||
|
||||
// Input GETTERS.
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
util::assigned_str(&self.name)
|
||||
}
|
||||
|
||||
pub fn value(&self) -> &str {
|
||||
util::assigned_str(&self.value)
|
||||
}
|
||||
|
||||
pub fn label(&self) -> &str {
|
||||
util::assigned_str(&self.label)
|
||||
}
|
||||
|
||||
pub fn size(&self) -> Option<u16> {
|
||||
self.size
|
||||
}
|
||||
|
||||
pub fn minlength(&self) -> Option<u16> {
|
||||
self.minlength
|
||||
}
|
||||
|
||||
pub fn maxlength(&self) -> Option<u16> {
|
||||
self.maxlength
|
||||
}
|
||||
|
||||
pub fn placeholder(&self) -> &str {
|
||||
util::assigned_str(&self.placeholder)
|
||||
}
|
||||
|
||||
pub fn has_autofocus(&self) -> bool {
|
||||
match &self.autofocus {
|
||||
Some(_) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_autocomplete(&self) -> bool {
|
||||
match &self.autocomplete {
|
||||
Some(_) => false,
|
||||
_ => true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_disabled(&self) -> bool {
|
||||
match &self.disabled {
|
||||
Some(_) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_readonly(&self) -> bool {
|
||||
match &self.readonly {
|
||||
Some(_) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_required(&self) -> bool {
|
||||
match &self.required {
|
||||
Some(_) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn help_text(&self) -> &str {
|
||||
util::assigned_str(&self.help_text)
|
||||
}
|
||||
|
||||
pub fn template(&self) -> &str {
|
||||
self.template.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
fn always() -> bool {
|
||||
true
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
mod form;
|
||||
pub use form::{Form, FormMethod};
|
||||
|
||||
mod input;
|
||||
pub use input::Input;
|
||||
mod hidden;
|
||||
pub use hidden::Hidden;
|
||||
mod date;
|
||||
pub use date::Date;
|
||||
mod button;
|
||||
pub use button::Button;
|
||||
|
|
@ -1,252 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
enum MenuItemType {
|
||||
Label(String),
|
||||
Link(String, String),
|
||||
LinkBlank(String, String),
|
||||
Markup(Markup),
|
||||
Separator,
|
||||
Submenu(String, Menu),
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// MenuItem.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
pub struct MenuItem {
|
||||
renderable: fn() -> bool,
|
||||
weight : i8,
|
||||
item_type : Option<MenuItemType>,
|
||||
}
|
||||
|
||||
impl PageComponent for MenuItem {
|
||||
|
||||
fn prepare() -> Self {
|
||||
MenuItem {
|
||||
renderable: always,
|
||||
weight : 0,
|
||||
item_type : None,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_renderable(&self) -> bool {
|
||||
(self.renderable)()
|
||||
}
|
||||
|
||||
fn weight(&self) -> i8 {
|
||||
self.weight
|
||||
}
|
||||
|
||||
fn default_render(&self, assets: &mut PageAssets) -> Markup {
|
||||
match &self.item_type {
|
||||
Some(MenuItemType::Label(label)) => html! {
|
||||
li class="label" { a href="#" { (label) } }
|
||||
},
|
||||
Some(MenuItemType::Link(label, path)) => html! {
|
||||
li class="link" { a href=(path) { (label) } }
|
||||
},
|
||||
Some(MenuItemType::LinkBlank(label, path)) => html! {
|
||||
li class="link_blank" {
|
||||
a href=(path) target="_blank" { (label) }
|
||||
}
|
||||
},
|
||||
Some(MenuItemType::Markup(markup)) => html! {
|
||||
li class="markup" { (*markup) }
|
||||
},
|
||||
Some(MenuItemType::Submenu(label, menu)) => html! {
|
||||
li class="submenu" {
|
||||
a href="#" { (label) }
|
||||
ul {
|
||||
(menu.render_items(assets))
|
||||
}
|
||||
}
|
||||
},
|
||||
Some(MenuItemType::Separator) => html! {
|
||||
li class="separator" { }
|
||||
},
|
||||
None => html! {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MenuItem {
|
||||
|
||||
pub fn label(label: &str) -> Self {
|
||||
MenuItem {
|
||||
renderable: always,
|
||||
weight : 0,
|
||||
item_type : Some(MenuItemType::Label(label.to_owned())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn link(label: &str, path: &str) -> Self {
|
||||
MenuItem {
|
||||
renderable: always,
|
||||
weight : 0,
|
||||
item_type : Some(MenuItemType::Link(
|
||||
label.to_owned(),
|
||||
path.to_owned(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn link_blank(label: &str, path: &str) -> Self {
|
||||
MenuItem {
|
||||
renderable: always,
|
||||
weight : 0,
|
||||
item_type : Some(MenuItemType::LinkBlank(
|
||||
label.to_owned(),
|
||||
path.to_owned(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn markup(markup: Markup) -> Self {
|
||||
MenuItem {
|
||||
renderable: always,
|
||||
weight : 0,
|
||||
item_type : Some(MenuItemType::Markup(markup)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn separator() -> Self {
|
||||
MenuItem {
|
||||
renderable: always,
|
||||
weight : 0,
|
||||
item_type : Some(MenuItemType::Separator),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn submenu(label: &str, menu: Menu) -> Self {
|
||||
MenuItem {
|
||||
renderable: always,
|
||||
weight : 0,
|
||||
item_type : Some(MenuItemType::Submenu(
|
||||
label.to_owned(),
|
||||
menu
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
// MenuItem BUILDER.
|
||||
|
||||
pub fn with_renderable(mut self, renderable: fn() -> bool) -> Self {
|
||||
self.renderable = renderable;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_weight(mut self, weight: i8) -> Self {
|
||||
self.weight = weight;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Menu.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
pub struct Menu {
|
||||
renderable: fn() -> bool,
|
||||
weight : i8,
|
||||
id : Option<String>,
|
||||
items : PageContainer,
|
||||
template : String,
|
||||
}
|
||||
|
||||
impl PageComponent for Menu {
|
||||
|
||||
fn prepare() -> Self {
|
||||
Menu {
|
||||
renderable: always,
|
||||
weight : 0,
|
||||
id : None,
|
||||
items : PageContainer::new(),
|
||||
template : "default".to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_renderable(&self) -> bool {
|
||||
(self.renderable)()
|
||||
}
|
||||
|
||||
fn weight(&self) -> i8 {
|
||||
self.weight
|
||||
}
|
||||
|
||||
fn default_render(&self, assets: &mut PageAssets) -> Markup {
|
||||
assets
|
||||
.add_stylesheet(StyleSheet::source(
|
||||
"/theme/menu/css/menu.css?ver=1.1.1"
|
||||
))
|
||||
.add_stylesheet(StyleSheet::source(
|
||||
"/theme/menu/css/menu-clean.css?ver=1.1.1"
|
||||
))
|
||||
.add_javascript(JavaScript::source(
|
||||
"/theme/menu/js/menu.min.js?ver=1.1.1"
|
||||
))
|
||||
.add_jquery();
|
||||
|
||||
let id = assets.serial_id(self.name(), self.id());
|
||||
html! {
|
||||
ul id=(id) class="sm sm-clean" {
|
||||
(self.render_items(assets))
|
||||
}
|
||||
script type="text/javascript" defer {
|
||||
"jQuery(function(){jQuery('#" (id) "').smartmenus({"
|
||||
"hideTimeout: 0,"
|
||||
"showTimeout: 80,"
|
||||
"});});"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Menu {
|
||||
|
||||
// Menu BUILDER.
|
||||
|
||||
pub fn with_renderable(mut self, renderable: fn() -> bool) -> Self {
|
||||
self.renderable = renderable;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_weight(mut self, weight: i8) -> Self {
|
||||
self.weight = weight;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_id(mut self, id: &str) -> Self {
|
||||
self.id = util::valid_id(id);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add(mut self, item: MenuItem) -> Self {
|
||||
self.items.add(item);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn using_template(mut self, template: &str) -> Self {
|
||||
self.template = template.to_owned();
|
||||
self
|
||||
}
|
||||
|
||||
// Menu GETTERS.
|
||||
|
||||
pub fn id(&self) -> &str {
|
||||
util::assigned_str(&self.id)
|
||||
}
|
||||
|
||||
pub fn template(&self) -> &str {
|
||||
self.template.as_str()
|
||||
}
|
||||
|
||||
// Menu EXTRAS.
|
||||
|
||||
pub fn render_items(&self, assets: &mut PageAssets) -> Markup {
|
||||
html! { (self.items.render(assets)) }
|
||||
}
|
||||
}
|
||||
|
||||
fn always() -> bool {
|
||||
true
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
mod container;
|
||||
pub use container::Container;
|
||||
mod chunck;
|
||||
pub use chunck::Chunck;
|
||||
mod block;
|
||||
pub use block::Block;
|
||||
mod menu;
|
||||
pub use menu::{Menu, MenuItem};
|
||||
|
||||
pub mod form;
|
||||
pub use form::{Form, FormMethod};
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
//! Temas, Módulos y Componentes base.
|
||||
|
||||
pub mod theme;
|
||||
pub mod module;
|
||||
pub mod component;
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
module_fullname = Admin module
|
||||
module_description = Administration module.
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
module_fullname = Admin module
|
||||
module_description = Módulo de administración.
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
localize!("en-US", "src/base/module/admin/locales");
|
||||
|
||||
mod summary;
|
||||
|
||||
pub struct AdminModule;
|
||||
|
||||
impl Module for AdminModule {
|
||||
fn name(&self) -> &'static str {
|
||||
"admin"
|
||||
}
|
||||
|
||||
fn fullname(&self) -> String {
|
||||
l("module_fullname")
|
||||
}
|
||||
|
||||
fn description(&self) -> Option<String> {
|
||||
Some(l("module_description"))
|
||||
}
|
||||
|
||||
fn configure_module(&self, cfg: &mut server::web::ServiceConfig) {
|
||||
cfg.service(
|
||||
server::web::scope("/admin")
|
||||
.route("", server::web::get().to(summary::summary))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
use super::l;
|
||||
|
||||
pub async fn summary() -> server::Result<Markup> {
|
||||
let top_menu = Menu::prepare()
|
||||
.add(MenuItem::label(l("module_fullname").as_str()))
|
||||
.add(MenuItem::link("Opción 2", "https://www.google.es"))
|
||||
.add(MenuItem::link_blank("Opción 3", "https://www.google.es"))
|
||||
.add(MenuItem::submenu("Submenú 1", Menu::prepare()
|
||||
.add(MenuItem::label("Opción 1"))
|
||||
.add(MenuItem::label("Opción 2"))
|
||||
))
|
||||
.add(MenuItem::separator())
|
||||
.add(MenuItem::submenu("Submenú 2", Menu::prepare()
|
||||
.add(MenuItem::label("Opción 1"))
|
||||
.add(MenuItem::label("Opción 2"))
|
||||
))
|
||||
.add(MenuItem::label("Opción 4"));
|
||||
|
||||
let side_menu = Menu::prepare()
|
||||
.add(MenuItem::label("Opción 1"))
|
||||
.add(MenuItem::link("Opción 2", "https://www.google.es"))
|
||||
.add(MenuItem::link_blank("Opción 3", "https://www.google.es"))
|
||||
.add(MenuItem::submenu("Submenú 1", Menu::prepare()
|
||||
.add(MenuItem::label("Opción 1"))
|
||||
.add(MenuItem::label("Opción 2"))
|
||||
))
|
||||
.add(MenuItem::separator())
|
||||
.add(MenuItem::submenu("Submenú 2", Menu::prepare()
|
||||
.add(MenuItem::label("Opción 1"))
|
||||
.add(MenuItem::label("Opción 2"))
|
||||
))
|
||||
.add(MenuItem::label("Opción 4"));
|
||||
|
||||
Page::prepare()
|
||||
|
||||
.using_theme("bootsier")
|
||||
|
||||
.with_title("Admin")
|
||||
|
||||
.add_to("top-menu", top_menu)
|
||||
|
||||
.add_to("content", Container::row()
|
||||
.add(Container::column()
|
||||
.add(side_menu)
|
||||
)
|
||||
.add(Container::column()
|
||||
.add(Chunck::markup(html! {
|
||||
p { "Columna 2"}
|
||||
}))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
.using_template("admin")
|
||||
|
||||
.render()
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
module_fullname = Default homepage
|
||||
module_description = Displays a default homepage when none is configured.
|
||||
|
||||
page_title = Hello world!
|
||||
|
||||
text_welcome = This page is used to test the proper operation of { $app } after installation. This web solution is powered by { $pagetop }. If you can read this page, it means that the PageTop server is working properly, but has not yet been configured.
|
||||
|
||||
title_normal_user = Just visiting?
|
||||
text1_normal_user = If you are a normal user of this web site and don't know what this page is about, this probably means that the site is either experiencing problems or is undergoing routine maintenance.
|
||||
text2_normal_user = If the problem persists, please contact your system administrator.
|
||||
|
||||
title_about_pagetop = About PageTop
|
||||
text1_about_pagetop = PageTop defines an interface for the most stable and popular Rust packages to build modular, extensible and configurable web solutions.
|
||||
text2_about_pagetop = For information on PageTop please visit the "PageTop website".
|
||||
|
||||
title_promo_pagetop = Promoting PageTop
|
||||
text1_promo_pagetop = You are free to use the image below on applications powered by { $pagetop }. Thanks for using PageTop!
|
||||
|
||||
title_report_problems = Reporting Problems
|
||||
text1_report_problems = Please use the GitLab tool to report bugs in PageTop. However, check "existing bug reports" before reporting a new bug.
|
||||
text2_report_problems = Please report bugs specific to modules (such as admin, and others) to respective packages, not to PageTop itself.
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
module_fullname = Página de inicio predeterminada
|
||||
module_description = Muestra una página de inicio predeterminada cuando no hay ninguna configurada.
|
||||
|
||||
page_title = ¡Hola mundo!
|
||||
|
||||
text_welcome = Esta página se utiliza para probar el correcto funcionamiento de { $app } después de la instalación. Esta solución web funciona con { $pagetop }. Si puede leer esta página, significa que el servidor PageTop funciona correctamente, pero aún no se ha configurado.
|
||||
|
||||
title_normal_user = ¿Sólo de visita?
|
||||
text1_normal_user = Si usted es un usuario normal de este sitio web y no sabe de qué trata esta página, probablemente significa que el sitio está experimentando problemas o está pasando por un mantenimiento de rutina.
|
||||
text2_normal_user = Si el problema persiste, póngase en contacto con el administrador del sistema.
|
||||
|
||||
title_about_pagetop = Sobre PageTop
|
||||
text1_about_pagetop = PageTop define una interfaz para los paquetes Rust más estables y populares para crear soluciones web modulares, extensibles y configurables.
|
||||
text2_about_pagetop = Para obtener información sobre PageTop, visite el "sitio web de PageTop".
|
||||
|
||||
title_promo_pagetop = Promociona PageTop
|
||||
text1_promo_pagetop = Puede usar la siguiente imagen en aplicaciones desarrolladas sobre { $pagetop }. ¡Gracias por usar PageTop!
|
||||
|
||||
title_report_problems = Informando Problemas
|
||||
text1_report_problems = Utilice la herramienta GitLab para informar errores en PageTop. Sin embargo, verifique los "informes de errores existentes" antes de informar de un nuevo error.
|
||||
text2_report_problems = Informe los errores específicos de los módulos (como admin y otros) a los paquetes respectivos, no a PageTop en sí.
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
localize!("en-US", "src/base/module/homepage/locales");
|
||||
|
||||
pub struct HomepageModule;
|
||||
|
||||
impl Module for HomepageModule {
|
||||
fn name(&self) -> &'static str {
|
||||
"homepage"
|
||||
}
|
||||
|
||||
fn fullname(&self) -> String {
|
||||
l("module_fullname")
|
||||
}
|
||||
|
||||
fn description(&self) -> Option<String> {
|
||||
Some(l("module_description"))
|
||||
}
|
||||
|
||||
fn configure_module(&self, cfg: &mut server::web::ServiceConfig) {
|
||||
cfg.route("/", server::web::get().to(home));
|
||||
}
|
||||
}
|
||||
|
||||
async fn home() -> server::Result<Markup> {
|
||||
Page::prepare()
|
||||
.with_title(
|
||||
l("page_title").as_str()
|
||||
)
|
||||
.add_to("content", Container::prepare()
|
||||
.with_id("welcome")
|
||||
.add(Chunck::markup(html! {
|
||||
h1 { (l("page_title")) }
|
||||
p { (e("text_welcome", &args![
|
||||
"app" => format!("<strong>{}</strong>", &SETTINGS.app.name),
|
||||
"pagetop" => "<a href=\"https://pagetop-rs\">PageTop</a>"
|
||||
])) }
|
||||
}))
|
||||
)
|
||||
.add_to("content", Container::prepare()
|
||||
.add(Container::row()
|
||||
.add(Container::column()
|
||||
.with_id("visitors")
|
||||
.add(Chunck::markup(html! {
|
||||
h2 { (l("title_normal_user")) }
|
||||
p { (l("text1_normal_user")) }
|
||||
p { (l("text2_normal_user")) }
|
||||
})))
|
||||
.add(Container::column()
|
||||
.with_id("pagetop")
|
||||
.add(Chunck::markup(html! {
|
||||
h2 { (l("title_about_pagetop")) }
|
||||
p { (l("text1_about_pagetop")) }
|
||||
p { (l("text2_about_pagetop")) }
|
||||
|
||||
h2 { (l("title_promo_pagetop")) }
|
||||
p { (e("text1_promo_pagetop", &args![
|
||||
"pagetop" =>
|
||||
"<a href=\"https://pagetop-rs\">PageTop</a>"
|
||||
])) }
|
||||
}))
|
||||
)
|
||||
)
|
||||
)
|
||||
.add_to("content", Container::prepare()
|
||||
.with_id("reporting")
|
||||
.add(Chunck::markup(html! {
|
||||
h2 { (l("title_report_problems")) }
|
||||
p { (l("text1_report_problems")) }
|
||||
p { (l("text2_report_problems")) }
|
||||
}))
|
||||
)
|
||||
.render()
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
pub mod admin;
|
||||
pub mod homepage;
|
||||
pub mod user;
|
||||
|
|
@ -1 +0,0 @@
|
|||
pub mod user;
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
use crate::db::entity::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Deserialize, Serialize)]
|
||||
#[sea_orm(table_name = "user")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key)]
|
||||
#[serde(skip_deserializing)]
|
||||
pub id: i32,
|
||||
pub title: String,
|
||||
#[sea_orm(column_type = "Text")]
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
module_fullname = User
|
||||
module_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 @@
|
|||
module_fullname = Usuario
|
||||
module_description = Gestion 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,54 +0,0 @@
|
|||
use crate::db::migration::*;
|
||||
|
||||
#[derive(Iden)]
|
||||
enum User {
|
||||
Table,
|
||||
Id,
|
||||
Title,
|
||||
Text,
|
||||
}
|
||||
|
||||
pub struct Migration;
|
||||
|
||||
impl MigrationName for Migration {
|
||||
fn name(&self) -> &str {
|
||||
"m20220312_000001_create_table_user"
|
||||
}
|
||||
}
|
||||
|
||||
#[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::Id)
|
||||
.integer()
|
||||
.not_null()
|
||||
.auto_increment()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(User::Title)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.col(ColumnDef::new(User::Text)
|
||||
.string()
|
||||
.not_null()
|
||||
)
|
||||
.to_owned()
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop()
|
||||
.table(User::Table)
|
||||
.to_owned()
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
use crate::db::migration::*;
|
||||
|
||||
pub mod m20220312_000001_create_table_user;
|
||||
|
||||
pub struct Migrator;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigratorTrait for Migrator {
|
||||
fn migrations() -> Vec<Box<dyn MigrationTrait>> {
|
||||
vec![Box::new(m20220312_000001_create_table_user::Migration)]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
localize!("en-US", "src/base/module/user/locales");
|
||||
|
||||
mod entity;
|
||||
mod migration;
|
||||
|
||||
pub struct UserModule;
|
||||
|
||||
impl Module for UserModule {
|
||||
fn name(&self) -> &'static str {
|
||||
"user"
|
||||
}
|
||||
|
||||
fn fullname(&self) -> String {
|
||||
l("module_fullname")
|
||||
}
|
||||
|
||||
fn description(&self) -> Option<String> {
|
||||
Some(l("module_description"))
|
||||
}
|
||||
|
||||
fn configure_module(&self, cfg: &mut server::web::ServiceConfig) {
|
||||
cfg.route("/user/login", server::web::get().to(login));
|
||||
}
|
||||
|
||||
fn migrations(&self, dbconn: &db::DbConn) -> Result<(), db::DbErr> {
|
||||
db_migrations!(dbconn)
|
||||
}
|
||||
}
|
||||
|
||||
fn form_login() -> impl PageComponent {
|
||||
Form::prepare()
|
||||
.with_id("user-login")
|
||||
.add(form::Input::textfield()
|
||||
.with_name("name")
|
||||
.with_label(l("username").as_str())
|
||||
.with_help_text(t("username_help", &args![
|
||||
"app" => SETTINGS.app.name.to_owned()
|
||||
]).as_str())
|
||||
.autofocus(true)
|
||||
)
|
||||
.add(form::Input::password()
|
||||
.with_name("pass")
|
||||
.with_label(l("password").as_str())
|
||||
.with_help_text(l("password_help").as_str())
|
||||
)
|
||||
.add(form::Button::submit(l("login").as_str()))
|
||||
}
|
||||
|
||||
async fn login() -> server::Result<Markup> {
|
||||
Page::prepare()
|
||||
.with_title(
|
||||
"Identificación del usuario"
|
||||
)
|
||||
.add_to("content", Container::prepare()
|
||||
.with_id("welcome")
|
||||
.add(form_login())
|
||||
)
|
||||
.render()
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/aliner.rs"));
|
||||
|
||||
pub struct AlinerTheme;
|
||||
|
||||
impl Theme for AlinerTheme {
|
||||
fn name(&self) -> &'static str {
|
||||
"aliner"
|
||||
}
|
||||
|
||||
fn fullname(&self) -> String {
|
||||
"Aliner".to_owned()
|
||||
}
|
||||
|
||||
fn configure_theme(&self, cfg: &mut server::web::ServiceConfig) {
|
||||
cfg.service(actix_web_static_files::ResourceFiles::new(
|
||||
"/aliner",
|
||||
assets()
|
||||
));
|
||||
}
|
||||
|
||||
fn before_render_page(&self, page: &mut Page) {
|
||||
page.assets()
|
||||
.add_stylesheet(
|
||||
StyleSheet::source(
|
||||
"/aliner/css/styles.css"
|
||||
)
|
||||
.with_weight(-99)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +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,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,86 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/bootsier.rs"));
|
||||
|
||||
localize!("en-US", "src/base/theme/bootsier/locales");
|
||||
|
||||
pub struct BootsierTheme;
|
||||
|
||||
impl Theme for BootsierTheme {
|
||||
fn name(&self) -> &'static str {
|
||||
"bootsier"
|
||||
}
|
||||
|
||||
fn fullname(&self) -> String {
|
||||
"Bootsier".to_owned()
|
||||
}
|
||||
|
||||
fn configure_theme(&self, cfg: &mut server::web::ServiceConfig) {
|
||||
cfg.service(actix_web_static_files::ResourceFiles::new(
|
||||
"/bootsier",
|
||||
assets()
|
||||
));
|
||||
}
|
||||
|
||||
fn before_render_page(&self, page: &mut Page) {
|
||||
page.assets()
|
||||
.with_favicon(
|
||||
Favicon::new()
|
||||
.with_icon("/bootsier/favicon.png")
|
||||
)
|
||||
.add_stylesheet(
|
||||
StyleSheet::source(
|
||||
"/bootsier/css/bootstrap.min.css?ver=5.1.3"
|
||||
)
|
||||
.with_weight(-99)
|
||||
)
|
||||
.add_javascript(
|
||||
JavaScript::source(
|
||||
"/bootsier/js/bootstrap.bundle.min.js?ver=5.1.3"
|
||||
)
|
||||
.with_weight(-99)
|
||||
)
|
||||
.add_jquery();
|
||||
}
|
||||
|
||||
fn render_error_page(&self, mut s: server::http::StatusCode) -> server::Result<Markup> {
|
||||
let mut description = "e500-description";
|
||||
let mut message = "e500-description";
|
||||
match s {
|
||||
server::http::StatusCode::NOT_FOUND => {
|
||||
description = "e404-description";
|
||||
message = "e404-message";
|
||||
},
|
||||
_ => {
|
||||
s = server::http::StatusCode::INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
}
|
||||
Page::prepare()
|
||||
.with_title(format!("Error {}", s.as_str()).as_str())
|
||||
.add_to("content", Chunck::markup(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" { (s) }
|
||||
p class="lead" { (l(description)) }
|
||||
hr class="my-4";
|
||||
p { (l(message)) }
|
||||
a
|
||||
class="btn btn-primary btn-lg"
|
||||
href="/"
|
||||
role="button"
|
||||
{
|
||||
(l("back-homepage"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}))
|
||||
.render()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
pub struct MinimalTheme;
|
||||
|
||||
impl Theme for MinimalTheme {
|
||||
fn name(&self) -> &'static str {
|
||||
"minimal"
|
||||
}
|
||||
|
||||
fn fullname(&self) -> String {
|
||||
"Minimal".to_owned()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
pub mod aliner;
|
||||
pub mod minimal;
|
||||
pub mod bootsier;
|
||||
Loading…
Add table
Add a link
Reference in a new issue