mirror of
https://git.sr.ht/~sircmpwn/hub.sr.ht
synced 2024-12-04 20:25:39 +01:00
Add project config page
This commit is contained in:
parent
cbc4326657
commit
2ec9808304
5 changed files with 256 additions and 10 deletions
|
@ -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))
|
||||
|
|
210
hubsrht/templates/project-config.html
Normal file
210
hubsrht/templates/project-config.html
Normal 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 %}
|
|
@ -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 {{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 {{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>
|
||||
|
|
|
@ -63,8 +63,8 @@
|
|||
>Add mailing lists {{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 %}
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
Loading…
Reference in a new issue