about summary refs log blame commit diff stats
path: root/pkgs/by-name/ba/back/src/web/issue_html.rs
blob: 45c02818699d39d58e20119693263a0ede1deaa1 (plain) (tree)




































































































































































                                                                                                                                                                                                                                                                                  
// Back - An extremely simple git issue tracking system. Inspired by tvix's
// panettone
//
// Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
// SPDX-License-Identifier: AGPL-3.0-or-later
//
// This file is part of Back.
//
// You should have received a copy of the License along with this program.
// If not, see <https://www.gnu.org/licenses/agpl.txt>.

use rocket::response::content::RawHtml;

use crate::{
    config::BackConfig,
    git_bug::{
        format::HtmlString,
        issue::{identity::Author, CollapsedIssue, Comment},
    },
};

impl CollapsedIssue {
    pub fn to_list_entry(&self) -> RawHtml<String> {
        let comment_list = if self.comments.is_empty() {
            String::new()
        } else {
            let comments_string = if self.comments.len() > 1 {
                "comments"
            } else {
                "comment"
            };

            format!(
                r#"
                <span class="comment-count"> - {} {}</span>
            "#,
                self.comments.len(),
                comments_string
            )
        };

        let CollapsedIssue {
            id,
            title,
            message: _,
            author,
            timestamp,
            comments: _,
            status: _,
            last_status_change: _,
            labels: _,
        } = self;

        let Author { name, email, id: _ } = author;

        RawHtml(format!(
            r#"
               <li>
                  <a href="/issue/{id}">
                     <p>
                        <span class="issue-subject">{title}</span>
                     </p>
                     <span class="issue-number">{id}</span> - <span class="created-by-at">Opened by <span class="user-name">{name}</span> <span class="user-email">&lt;{email}&gt;</span> at <span class="timestamp">{timestamp}</span></span>{comment_list}                  </a>
               </li>
"#,
        ))
    }

    pub fn to_html(&self, config: &BackConfig) -> RawHtml<String> {
        let comments = if self.comments.is_empty() {
            String::new()
        } else {
            let fmt_comments: String = self
                .comments
                .iter()
                .map(|val| {
                    let Comment {
                        id,
                        author,
                        message,
                        timestamp,
                    } = val;
                    let Author {
                        name,
                        email: _,
                        id: _,
                    } = author;

                    format!(
                        r#"
               <li class="comment" id="{id}">
                  {message}
                  <p class="comment-info"><span class="user-name">{name} at {timestamp}</span></p>
               </li>
                "#,
                    )
                })
                .collect::<Vec<String>>()
                .join("\n");

            format!(
                r#"
            <ol class="issue-history">
            {fmt_comments}
            </ol>
            "#
            )
        };

        {
            let CollapsedIssue {
                id,
                title,
                message,
                author,
                timestamp,
                comments: _,
                status: _,
                last_status_change: _,
                labels: _,
            } = self;
            let Author { name, email, id: _ } = author;
            let html_title = HtmlString::from(title.clone());

            RawHtml(format!(
                r#"
<!DOCTYPE html>
<html lang="en">
   <head>
      <title>{html_title} | Back</title>
      <link href="/style.css" rel="stylesheet" type="text/css">
      <meta content="width=device-width,initial-scale=1" name="viewport">
   </head>
   <body>
      <div class="content">
         <nav>
         <a href="/issues/open">Open Issues</a>
         <a href="/issues/closed">Closed Issues</a>
         </nav>
         <header>
            <h1>{title}</h1>
            <div class="issue-number">{id}</div>
         </header>
         <main>
            <div class="issue-info">
                <span class="created-by-at">Opened by <span class="user-name">{name}</span> <span class="user-email">&lt;{email}&gt;</span> at <span class="timestamp">{timestamp}</span></span>
            </div>
            {message}
            {comments}
         </main>
         <footer>
            <nav>
            <a href="/issues/open">Open Issues</a>
            <a href="{}">Source code</a>
            <a href="/issues/closed">Closed Issues</a>
            </nav>
         </footer>
      </div>
   </body>
</html>
"#,
                config.source_code_repository_url
            ))
        }
    }
}