Add project config page

master
Drew DeVault 2020-04-02 12:55:05 -04:00
parent cbc4326657
commit 2ec9808304
5 changed files with 256 additions and 10 deletions

View File

@ -6,7 +6,7 @@ from hubsrht.types import Project, RepoType, Visibility
from srht.database import db
from srht.flask import paginate_query
from srht.oauth import current_user, loginrequired
from srht.validation import Validation
from srht.validation import Validation, valid_url
projects = Blueprint("projects", __name__)
@ -93,3 +93,32 @@ def create_POST():
return redirect(url_for("projects.summary_GET",
owner=current_user.canonical_name,
project_name=project.name))
@projects.route("/<owner>/<project_name>/settings")
@loginrequired
def config_GET(owner, project_name):
owner, project = get_project(owner, project_name, ProjectAccess.write)
return render_template("project-config.html", view="add more",
owner=owner, project=project)
@projects.route("/<owner>/<project_name>/settings", methods=["POST"])
@loginrequired
def config_POST(owner, project_name):
owner, project = get_project(owner, project_name, ProjectAccess.write)
valid = Validation(request)
description = valid.require("description")
website = valid.optional("website")
valid.expect(not website or valid_url(website),
"Website must be a valid http or https URL")
if not valid.ok:
return render_template("project-config.html", view="add more",
owner=owner, project=project, **valid.kwargs)
project.description = description
project.website = website
db.session.commit()
return redirect(url_for("projects.summary_GET",
owner=current_user.canonical_name,
project_name=project.name))

View File

@ -0,0 +1,210 @@
{% extends "project-base.html" %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-lg-12 event-list">
<form class="event" method="POST">
{{csrf_token()}}
<div class="row">
<div class="col-lg-6">
<div class="form-group">
<label for="name">
Project name <small class="text-muted">(you can't edit this)</small>
</label>
<input
type="text"
id="name"
class="form-control"
readonly
value="{{project.name}}" />
</div>
<div class="form-group">
<label for="description">Description</label>
<input
class="form-control {{valid.cls("description")}}"
type="text"
id="description"
name="description"
placeholder="Short description of your project, shown in lists"
value="{{description or project.description}}"
required />
{{valid.summary("description")}}
</div>
<div class="form-group">
<label for="project-website">Website</label>
<input
class="form-control {{valid.cls("website")}}"
type="text"
id="website"
name="website"
placeholder="http://example.org"
value="{{website or project.website or ""}}" />
{{valid.summary("website")}}
</div>
</div>
<div class="col-lg-6">
<fieldset class="form-group">
<legend>Project Visibility</legend>
<div class="form-check">
<label class="form-check-label">
<input
class="form-check-input"
type="radio"
name="visibility"
value="public"
checked> Public
<small id="visibility-public-help" class="form-text text-muted">
Shown on your profile and listed in the public project index
</small>
</label>
</div>
<div class="form-check">
<label
class="form-check-label"
title="Visible to anyone with the link, but not shown on your profile"
>
<input
class="form-check-input"
type="radio"
name="visibility"
value="unlisted"> Unlisted
<small id="visibility-unlisted-help" class="form-text text-muted">
Visible to anyone who knows the URL, but not shown on your profile
</small>
</label>
</div>
<div class="form-check">
<label
class="form-check-label"
title="Only visible to you and your collaborators"
>
<input
class="form-check-input"
type="radio"
name="visibility"
value="private"> Private
<small id="visibility-unlisted-help" class="form-text text-muted">
Only visible to you and your collaborators
</small>
</label>
</div>
</fieldset>
</div>
</div>
<div class="row form-group" style="margin-top: 1rem">
<div class="col-md-3">
<button type="submit" class="btn btn-primary btn-block">
Save details {{icon('caret-right')}}
</button>
</div>
</div>
</form>
</div>
<div class="col-lg-10 event-list">
<div class="event">
<h3>Source code repositories</h3>
<p>
Git and Mercurial repositories help you share this project's source
code with your collaborators.
</p>
<div class="row">
<div class="col-md-3">
<a
href="{{url_for("sources.new_GET",
owner=owner.canonical_name, project_name=project.name)}}"
class="btn btn-primary btn-block"
>
Add repository {{icon('caret-right')}}
</a>
</div>
<div class="col-md-3">
<a
href="{{url_for("sources.manage_GET",
owner=owner.canonical_name, project_name=project.name)}}"
class="btn btn-default btn-block"
>
Manage sources {{icon('caret-right')}}
</a>
</div>
</div>
</div>
<div class="event">
<h3>Mailing lists</h3>
<p>
Mailing lists give users a place to ask questions about the project
or send patches to contribute to the code.
</p>
<div class="row">
<div class="col-md-3">
<a
href="{{url_for("mailing_lists.new_GET",
owner=owner.canonical_name, project_name=project.name)}}"
class="btn btn-primary btn-block"
>
Add mailing list {{icon('caret-right')}}
</a>
</div>
<div class="col-md-3">
<a
href="{{url_for("mailing_lists.manage_GET",
owner=owner.canonical_name, project_name=project.name)}}"
class="btn btn-default btn-block"
>
Manage mailing lists {{icon('caret-right')}}
</a>
</div>
</div>
</div>
<div class="event">
<h3>Ticket trackers</h3>
<p>
Bug trackers give you a place to organize your tasks and record known
defects.
</p>
<div class="row">
<div class="col-md-3">
<a
href="{{url_for("trackers.new_GET",
owner=owner.canonical_name, project_name=project.name)}}"
class="btn btn-primary btn-block"
>
Add tracker {{icon('caret-right')}}
</a>
</div>
<div class="col-md-3">
<a
href="{{url_for("trackers.manage_GET",
owner=owner.canonical_name, project_name=project.name)}}"
class="btn btn-default btn-block"
>
Manage trackers {{icon('caret-right')}}
</a>
</div>
</div>
</div>
<div class="event">
<h3>Delete project</h3>
<p>
This will permanently delete your project,
<strong>{{project.name}}</strong>. This cannot be undone.
</p>
<div class="row">
<div class="col-md-3">
<a
href="#"
class="btn btn-danger btn-block"
>
Delete project {{icon('caret-right')}}
</a>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -14,6 +14,15 @@
owner=owner.canonical_name,
project_name=project.name), "summary")}}
</li>
{% if project.website %}
<li class="nav-item">
<a
class="nav-link"
href="{{project.website}}"
rel="noopener nofollow"
>website&nbsp;{{icon('external-link-alt')}}</a>
</li>
{% endif %}
{% if any(project.source_repos) %}
<li class="nav-item">
{{link(url_for("sources.sources_GET",
@ -36,11 +45,6 @@
</li>
{% endif %}
{# TODO
<li class="nav-item">
<a
class="nav-link" href="#"
>website&nbsp;{{icon('external-link-alt')}}</a>
</li>
<li class="nav-item">
{{link("#", "documentation")}}
</li>
@ -48,7 +52,9 @@
{% if current_user and current_user.id == owner.id %}
<li class="flex-grow-1"></li>
<li class="nav-item">
{{link("#", "add more +")}}
{{link(url_for("projects.config_GET",
owner=owner.canonical_name, project_name=project.name), "more +",
alternates=["add more"])}}
</li>
{% endif %}
</ul>

View File

@ -63,8 +63,8 @@
>Add mailing lists&nbsp;{{icon('arrow-right')}}</a>
<br />
<small class="text-muted">
Mailing lists give users a means of asking questions about the
project or sending patches to contribute to the source code.
Mailing lists give users a place to ask questions about the
project or send patches to contribute to the code.
</small>
{% endif %}
</li>
@ -99,7 +99,7 @@
dismiss
</button>
You're all set! If you want to set up more things for your project,
click "add more" on the top right.
click "more +" on the top right.
</p>
</div>
{% endif %}

View File

@ -14,6 +14,7 @@ class Project(Base):
name = sa.Column(sa.Unicode(128), nullable=False)
description = sa.Column(sa.Unicode(512), nullable=False)
website = sa.Column(sa.Unicode)
visibility = sa.Column(sau.ChoiceType(Visibility, impl=sa.String()),
nullable=False, server_default="unlisted")