mirror of https://github.com/realaravinth/gitpad
feat: add new gist form gets error handling and rendering with
user-provided values on errormaster
parent
7fdf815a14
commit
92f48b7bfb
|
@ -55,11 +55,37 @@ impl CtxError for NewGist {
|
|||
}
|
||||
|
||||
impl NewGist {
|
||||
pub fn new(username: &str, settings: &Settings, payload: Option<&[FieldNames<&str>]>) -> Self {
|
||||
let ctx = RefCell::new(auth_ctx(username, settings));
|
||||
if let Some(payload) = payload {
|
||||
ctx.borrow_mut().insert(PAYLOAD_KEY, &payload);
|
||||
pub fn new(
|
||||
username: &str,
|
||||
settings: &Settings,
|
||||
description: Option<&str>,
|
||||
payload: Option<&[FieldNames<&str>]>,
|
||||
) -> Self {
|
||||
const FIELDNAMES_KEY: &str = "fieldnames";
|
||||
let mut ctx = auth_ctx(username, settings);
|
||||
ctx.insert("visibility_private", GistVisibility::Private.to_str());
|
||||
ctx.insert("visibility_unlisted", GistVisibility::Unlisted.to_str());
|
||||
ctx.insert("visibility_public", GistVisibility::Public.to_str());
|
||||
|
||||
if let Some(description) = description {
|
||||
ctx.insert("description", description);
|
||||
}
|
||||
|
||||
if let Some(payload) = payload {
|
||||
ctx.insert(PAYLOAD_KEY, &payload);
|
||||
let fields = payload.len();
|
||||
let mut fieldnames = Vec::with_capacity(fields);
|
||||
for i in 1..=payload.len() {
|
||||
fieldnames.push(FieldNames::<String>::new(i))
|
||||
}
|
||||
ctx.insert(FIELDNAMES_KEY, &fieldnames);
|
||||
} else {
|
||||
ctx.insert(FIELDNAMES_KEY, &[FieldNames::<String>::new(1)]);
|
||||
ctx.insert(PAYLOAD_KEY, &[FieldNames::<&'static str>::default()]);
|
||||
}
|
||||
|
||||
println!("{:?}", ctx.get(PAYLOAD_KEY));
|
||||
let ctx = RefCell::new(ctx);
|
||||
Self { ctx }
|
||||
}
|
||||
|
||||
|
@ -68,7 +94,7 @@ impl NewGist {
|
|||
}
|
||||
|
||||
pub fn page(username: &str, s: &Settings) -> String {
|
||||
let p = Self::new(username, s, None);
|
||||
let p = Self::new(username, s, None, None);
|
||||
p.render()
|
||||
}
|
||||
}
|
||||
|
@ -90,6 +116,15 @@ pub struct FieldNames<T: Serialize + ToString> {
|
|||
pub content: T,
|
||||
}
|
||||
|
||||
impl Default for FieldNames<&'static str> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
content: "",
|
||||
filename: "",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Serialize + ToString> From<FieldNames<T>> for FileInfo {
|
||||
fn from(f: FieldNames<T>) -> Self {
|
||||
FileInfo {
|
||||
|
@ -164,6 +199,7 @@ fn get_description(payload: &serde_json::Value) -> Option<&str> {
|
|||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json::json;
|
||||
|
@ -267,9 +303,9 @@ mod tests {
|
|||
);
|
||||
|
||||
let some_partially_empty_files = json!({
|
||||
f1.filename.clone(): f1_name,
|
||||
f1.content.clone(): f1_content,
|
||||
f2.content.clone(): f2_content,
|
||||
f1.filename: f1_name,
|
||||
f1.content: f1_content,
|
||||
f2.content: f2_content,
|
||||
});
|
||||
let some_empty_gist_err = FieldNames::<&str>::from_serde_json(&some_partially_empty_files);
|
||||
assert!(some_empty_gist_err.is_err());
|
||||
|
|
|
@ -224,5 +224,28 @@ footer {
|
|||
width: 100%;
|
||||
margin: 10px 0;
|
||||
padding: 5px 0;
|
||||
height: 350px;
|
||||
height: 320px;
|
||||
}
|
||||
|
||||
|
||||
.gist__button-group {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.gist__button-container {
|
||||
flex: 1;
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.form__submit--secondary {
|
||||
width: 100%;
|
||||
display: block;
|
||||
margin: 10px 0;
|
||||
border: none;
|
||||
padding: 5px 0;
|
||||
cursor: pointer;
|
||||
background-color: #e9e9ed;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{% extends 'gistbase' %}
|
||||
{% block gist_main %}
|
||||
<form class="gist__new" action="/new" method="POST" accept-charset="utf-8">
|
||||
<form class="gist__new" action={{ page.gist.new }} method="POST" accept-charset="utf-8">
|
||||
{% include "error_comp" %}
|
||||
<label class="form__label" for="login">
|
||||
<label class="form__label" for="description">
|
||||
Gist description
|
||||
<input
|
||||
class="form__input"
|
||||
|
@ -15,61 +15,79 @@
|
|||
{% endif %}
|
||||
/>
|
||||
</label>
|
||||
{% if payload.files %}
|
||||
{% for file in payload.files %}
|
||||
{% for fieldname in fieldnames%}
|
||||
{% set content = payload | nth(n=(loop.index - 1)) %}
|
||||
<legend class="gist__file">
|
||||
<label class="form__label" for="login">
|
||||
<label class="form__label" for={{ fieldname.filename }}>
|
||||
File name with extension
|
||||
<input
|
||||
required
|
||||
class="form__input"
|
||||
name="filename"
|
||||
name={{ fieldname.filename }}
|
||||
autofocus
|
||||
id="filename"
|
||||
id={{ fieldname.filename }}
|
||||
type="text"
|
||||
value={{ file.filename }}
|
||||
value="{{ content.filename }}"
|
||||
/>
|
||||
</label>
|
||||
<label class="form__label" for="login">
|
||||
<label class="form__label" for={{ fieldname.content }}>
|
||||
<textarea
|
||||
required
|
||||
class="gist__file-content"
|
||||
name="content"
|
||||
autofocus
|
||||
id="content"
|
||||
name={{ fieldname.content }}
|
||||
id={{ fieldname.content }}
|
||||
type="text"
|
||||
value={{ file.content }}
|
||||
>
|
||||
</textarea>
|
||||
|
||||
>{{ content.content }}</textarea>
|
||||
</label>
|
||||
</legend>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<legend class="gist__file">
|
||||
<label class="form__label" for="login">
|
||||
File name with extension
|
||||
<input
|
||||
class="form__input"
|
||||
name="filename"
|
||||
autofocus
|
||||
id="filename"
|
||||
type="text"
|
||||
/>
|
||||
</label>
|
||||
<label class="form__label" for="login">
|
||||
<textarea
|
||||
required
|
||||
class="gist__file-content"
|
||||
name="content"
|
||||
autofocus
|
||||
id="content"
|
||||
type="text"
|
||||
>
|
||||
</textarea>
|
||||
</label>
|
||||
</legend>
|
||||
<div class="gist__radio-group">
|
||||
<label class="gist__radio-label" for={{ visibility_public }}>
|
||||
<input
|
||||
required
|
||||
class="gist__radio-btn"
|
||||
name="visibility"
|
||||
id={{ visibility_public }}
|
||||
type="radio"
|
||||
value={{ visibility_public }}
|
||||
/>
|
||||
Public
|
||||
</label>
|
||||
|
||||
{% endif %}
|
||||
<label class="gist__radio-label" for={{ visibility_unlisted }}>
|
||||
<input
|
||||
class="gist__radio-btn"
|
||||
name="visibility"
|
||||
id={{ visibility_unlisted }}
|
||||
type="radio"
|
||||
value={{ visibility_unlisted }}
|
||||
/>
|
||||
Unlisted
|
||||
</label>
|
||||
|
||||
<label class="gist__radio-label" for={{ visibility_private }}>
|
||||
<input
|
||||
class="gist__radio-btn"
|
||||
name="visibility"
|
||||
id={{ visibility_private }}
|
||||
type="radio"
|
||||
value={{ visibility_private }}
|
||||
/>
|
||||
Private
|
||||
</label>
|
||||
</div>
|
||||
<div class="gist__button-group">
|
||||
<div class="gist__button-container">
|
||||
<button
|
||||
class="form__submit--secondary"
|
||||
name="add_file"
|
||||
value="true"
|
||||
type="submit"
|
||||
>Add File</button>
|
||||
</div>
|
||||
<div class="gist__button-container">
|
||||
<button class="form__submit" type="submit">Create Gist</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
Loading…
Reference in New Issue