Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Start of the Status admin

  • Loading branch information...
commit a1cf05a7da998256927605a22ad4aa708cc1b8a9 1 parent 7e20a1e
@kyleconroy kyleconroy authored
View
69 scripts/gen_fixture.py
@@ -0,0 +1,69 @@
+# Copyright (c) 2010 Twilio Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# Requires Python 2.7
+
+import argparse
+import os
+import json
+
+# List of supported icon sets
+# These sets live in stashboard/static/images/icons
+ICON_SETS = ["fugue", "iconic"]
+
+parser = argparse.ArgumentParser(description="")
+parser.add_argument("directory", type=str,
+ help="Stashboard image directory")
+args = parser.parse_args()
+
+# Icons path
+icons = os.path.join(args.directory, "icons")
+
+image_set = set()
+images = []
+
+for p in os.listdir(icons):
+ if p in ICON_SETS:
+ for i in os.listdir(os.path.join(icons, p)):
+ if i[0] != '.': #ignore hidden files
+ filename, ext = os.path.splitext(i)
+ if filename in image_set:
+ name = filename + "_alt"
+ else:
+ name = filename
+
+ image_set.add(name)
+ image = {
+ "name": name,
+ "set": p,
+ "url": os.path.join("icons", p, i),
+ }
+ images.append(image)
+
+print json.dumps(images, indent=4)
+
+
+
+
+
+
+
@OyugiK
OyugiK added a note

This impelents the Python function above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+
+
View
562 stashboard/fixtures/images.json
@@ -0,0 +1,562 @@
+[
+ {
+ "url": "icons/fugue/broom.png",
+ "set": "fugue",
+ "name": "broom"
+ },
+ {
+ "url": "icons/fugue/bug.png",
+ "set": "fugue",
+ "name": "bug"
+ },
+ {
+ "url": "icons/fugue/clock.png",
+ "set": "fugue",
+ "name": "clock"
+ },
+ {
+ "url": "icons/fugue/cross-circle.png",
+ "set": "fugue",
+ "name": "cross-circle"
+ },
+ {
+ "url": "icons/fugue/exclamation.png",
+ "set": "fugue",
+ "name": "exclamation"
+ },
+ {
+ "url": "icons/fugue/flag.png",
+ "set": "fugue",
+ "name": "flag"
+ },
+ {
+ "url": "icons/fugue/hard-hat.png",
+ "set": "fugue",
+ "name": "hard-hat"
+ },
+ {
+ "url": "icons/fugue/heart.png",
+ "set": "fugue",
+ "name": "heart"
+ },
+ {
+ "url": "icons/fugue/information-small.png",
+ "set": "fugue",
+ "name": "information-small"
+ },
+ {
+ "url": "icons/fugue/information-white.png",
+ "set": "fugue",
+ "name": "information-white"
+ },
+ {
+ "url": "icons/fugue/information.png",
+ "set": "fugue",
+ "name": "information"
+ },
+ {
+ "url": "icons/fugue/lock.png",
+ "set": "fugue",
+ "name": "lock"
+ },
+ {
+ "url": "icons/fugue/plug.png",
+ "set": "fugue",
+ "name": "plug"
+ },
+ {
+ "url": "icons/fugue/plus-circle.png",
+ "set": "fugue",
+ "name": "plus-circle"
+ },
+ {
+ "url": "icons/fugue/question-white.png",
+ "set": "fugue",
+ "name": "question-white"
+ },
+ {
+ "url": "icons/fugue/question.png",
+ "set": "fugue",
+ "name": "question"
+ },
+ {
+ "url": "icons/fugue/tick-circle.png",
+ "set": "fugue",
+ "name": "tick-circle"
+ },
+ {
+ "url": "icons/fugue/traffic-cone.png",
+ "set": "fugue",
+ "name": "traffic-cone"
+ },
+ {
+ "url": "icons/fugue/wrench.png",
+ "set": "fugue",
+ "name": "wrench"
+ },
+ {
+ "url": "icons/iconic/arrow_down.png",
+ "set": "iconic",
+ "name": "arrow_down"
+ },
+ {
+ "url": "icons/iconic/arrow_down_alt1.png",
+ "set": "iconic",
+ "name": "arrow_down_alt1"
+ },
+ {
+ "url": "icons/iconic/arrow_down_alt2.png",
+ "set": "iconic",
+ "name": "arrow_down_alt2"
+ },
+ {
+ "url": "icons/iconic/arrow_left.png",
+ "set": "iconic",
+ "name": "arrow_left"
+ },
+ {
+ "url": "icons/iconic/arrow_left_alt1.png",
+ "set": "iconic",
+ "name": "arrow_left_alt1"
+ },
+ {
+ "url": "icons/iconic/arrow_left_alt2.png",
+ "set": "iconic",
+ "name": "arrow_left_alt2"
+ },
+ {
+ "url": "icons/iconic/arrow_right.png",
+ "set": "iconic",
+ "name": "arrow_right"
+ },
+ {
+ "url": "icons/iconic/arrow_right_alt1.png",
+ "set": "iconic",
+ "name": "arrow_right_alt1"
+ },
+ {
+ "url": "icons/iconic/arrow_right_alt2.png",
+ "set": "iconic",
+ "name": "arrow_right_alt2"
+ },
+ {
+ "url": "icons/iconic/arrow_up.png",
+ "set": "iconic",
+ "name": "arrow_up"
+ },
+ {
+ "url": "icons/iconic/arrow_up_alt1.png",
+ "set": "iconic",
+ "name": "arrow_up_alt1"
+ },
+ {
+ "url": "icons/iconic/arrow_up_alt2.png",
+ "set": "iconic",
+ "name": "arrow_up_alt2"
+ },
+ {
+ "url": "icons/iconic/article.png",
+ "set": "iconic",
+ "name": "article"
+ },
+ {
+ "url": "icons/iconic/at.png",
+ "set": "iconic",
+ "name": "at"
+ },
+ {
+ "url": "icons/iconic/bolt.png",
+ "set": "iconic",
+ "name": "bolt"
+ },
+ {
+ "url": "icons/iconic/book.png",
+ "set": "iconic",
+ "name": "book"
+ },
+ {
+ "url": "icons/iconic/book_alt.png",
+ "set": "iconic",
+ "name": "book_alt"
+ },
+ {
+ "url": "icons/iconic/box.png",
+ "set": "iconic",
+ "name": "box"
+ },
+ {
+ "url": "icons/iconic/calendar.png",
+ "set": "iconic",
+ "name": "calendar"
+ },
+ {
+ "url": "icons/iconic/calendar_alt_fill.png",
+ "set": "iconic",
+ "name": "calendar_alt_fill"
+ },
+ {
+ "url": "icons/iconic/calendar_alt_stroke.png",
+ "set": "iconic",
+ "name": "calendar_alt_stroke"
+ },
+ {
+ "url": "icons/iconic/cd.png",
+ "set": "iconic",
+ "name": "cd"
+ },
+ {
+ "url": "icons/iconic/chat.png",
+ "set": "iconic",
+ "name": "chat"
+ },
+ {
+ "url": "icons/iconic/chat_alt_fill.png",
+ "set": "iconic",
+ "name": "chat_alt_fill"
+ },
+ {
+ "url": "icons/iconic/chat_alt_stroke.png",
+ "set": "iconic",
+ "name": "chat_alt_stroke"
+ },
+ {
+ "url": "icons/iconic/check_alt.png",
+ "set": "iconic",
+ "name": "check_alt"
+ },
+ {
+ "url": "icons/iconic/clock.png",
+ "set": "iconic",
+ "name": "clock_alt"
+ },
+ {
+ "url": "icons/iconic/cog.png",
+ "set": "iconic",
+ "name": "cog"
+ },
+ {
+ "url": "icons/iconic/cog_alt.png",
+ "set": "iconic",
+ "name": "cog_alt"
+ },
+ {
+ "url": "icons/iconic/comment_alt1_fill.png",
+ "set": "iconic",
+ "name": "comment_alt1_fill"
+ },
+ {
+ "url": "icons/iconic/comment_alt1_stroke.png",
+ "set": "iconic",
+ "name": "comment_alt1_stroke"
+ },
+ {
+ "url": "icons/iconic/compass.png",
+ "set": "iconic",
+ "name": "compass"
+ },
+ {
+ "url": "icons/iconic/cursor.png",
+ "set": "iconic",
+ "name": "cursor"
+ },
+ {
+ "url": "icons/iconic/denied.png",
+ "set": "iconic",
+ "name": "denied"
+ },
+ {
+ "url": "icons/iconic/denied_alt.png",
+ "set": "iconic",
+ "name": "denied_alt"
+ },
+ {
+ "url": "icons/iconic/dial.png",
+ "set": "iconic",
+ "name": "dial"
+ },
+ {
+ "url": "icons/iconic/document_fill.png",
+ "set": "iconic",
+ "name": "document_fill"
+ },
+ {
+ "url": "icons/iconic/document_stroke.png",
+ "set": "iconic",
+ "name": "document_stroke"
+ },
+ {
+ "url": "icons/iconic/eject.png",
+ "set": "iconic",
+ "name": "eject"
+ },
+ {
+ "url": "icons/iconic/equalizer.png",
+ "set": "iconic",
+ "name": "equalizer"
+ },
+ {
+ "url": "icons/iconic/eyedropper.png",
+ "set": "iconic",
+ "name": "eyedropper"
+ },
+ {
+ "url": "icons/iconic/first.png",
+ "set": "iconic",
+ "name": "first"
+ },
+ {
+ "url": "icons/iconic/folder_fill.png",
+ "set": "iconic",
+ "name": "folder_fill"
+ },
+ {
+ "url": "icons/iconic/folder_stroke.png",
+ "set": "iconic",
+ "name": "folder_stroke"
+ },
+ {
+ "url": "icons/iconic/fullscreen.png",
+ "set": "iconic",
+ "name": "fullscreen"
+ },
+ {
+ "url": "icons/iconic/fullscreen_alt.png",
+ "set": "iconic",
+ "name": "fullscreen_alt"
+ },
+ {
+ "url": "icons/iconic/fullscreen_exit.png",
+ "set": "iconic",
+ "name": "fullscreen_exit"
+ },
+ {
+ "url": "icons/iconic/fullscreen_exit_alt.png",
+ "set": "iconic",
+ "name": "fullscreen_exit_alt"
+ },
+ {
+ "url": "icons/iconic/home.png",
+ "set": "iconic",
+ "name": "home"
+ },
+ {
+ "url": "icons/iconic/image.png",
+ "set": "iconic",
+ "name": "image"
+ },
+ {
+ "url": "icons/iconic/key_fill.png",
+ "set": "iconic",
+ "name": "key_fill"
+ },
+ {
+ "url": "icons/iconic/key_stroke.png",
+ "set": "iconic",
+ "name": "key_stroke"
+ },
+ {
+ "url": "icons/iconic/last.png",
+ "set": "iconic",
+ "name": "last"
+ },
+ {
+ "url": "icons/iconic/left_quote.png",
+ "set": "iconic",
+ "name": "left_quote"
+ },
+ {
+ "url": "icons/iconic/left_quote_alt.png",
+ "set": "iconic",
+ "name": "left_quote_alt"
+ },
+ {
+ "url": "icons/iconic/link.png",
+ "set": "iconic",
+ "name": "link"
+ },
+ {
+ "url": "icons/iconic/loop.png",
+ "set": "iconic",
+ "name": "loop"
+ },
+ {
+ "url": "icons/iconic/magnifying_glass.png",
+ "set": "iconic",
+ "name": "magnifying_glass"
+ },
+ {
+ "url": "icons/iconic/magnifying_glass_alt.png",
+ "set": "iconic",
+ "name": "magnifying_glass_alt"
+ },
+ {
+ "url": "icons/iconic/map_pin_fill.png",
+ "set": "iconic",
+ "name": "map_pin_fill"
+ },
+ {
+ "url": "icons/iconic/map_pin_stroke.png",
+ "set": "iconic",
+ "name": "map_pin_stroke"
+ },
+ {
+ "url": "icons/iconic/minus_alt.png",
+ "set": "iconic",
+ "name": "minus_alt"
+ },
+ {
+ "url": "icons/iconic/moon_fill.png",
+ "set": "iconic",
+ "name": "moon_fill"
+ },
+ {
+ "url": "icons/iconic/moon_stroke.png",
+ "set": "iconic",
+ "name": "moon_stroke"
+ },
+ {
+ "url": "icons/iconic/move.png",
+ "set": "iconic",
+ "name": "move"
+ },
+ {
+ "url": "icons/iconic/move_alt1.png",
+ "set": "iconic",
+ "name": "move_alt1"
+ },
+ {
+ "url": "icons/iconic/move_alt2.png",
+ "set": "iconic",
+ "name": "move_alt2"
+ },
+ {
+ "url": "icons/iconic/move_horizontal_alt2.png",
+ "set": "iconic",
+ "name": "move_horizontal_alt2"
+ },
+ {
+ "url": "icons/iconic/move_vertical_alt2.png",
+ "set": "iconic",
+ "name": "move_vertical_alt2"
+ },
+ {
+ "url": "icons/iconic/movie.png",
+ "set": "iconic",
+ "name": "movie"
+ },
+ {
+ "url": "icons/iconic/new_window.png",
+ "set": "iconic",
+ "name": "new_window"
+ },
+ {
+ "url": "icons/iconic/pen.png",
+ "set": "iconic",
+ "name": "pen"
+ },
+ {
+ "url": "icons/iconic/pen_alt_fill.png",
+ "set": "iconic",
+ "name": "pen_alt_fill"
+ },
+ {
+ "url": "icons/iconic/pen_alt_stroke.png",
+ "set": "iconic",
+ "name": "pen_alt_stroke"
+ },
+ {
+ "url": "icons/iconic/pin.png",
+ "set": "iconic",
+ "name": "pin"
+ },
+ {
+ "url": "icons/iconic/play_alt.png",
+ "set": "iconic",
+ "name": "play_alt"
+ },
+ {
+ "url": "icons/iconic/plus.png",
+ "set": "iconic",
+ "name": "plus"
+ },
+ {
+ "url": "icons/iconic/plus_alt.png",
+ "set": "iconic",
+ "name": "plus_alt"
+ },
+ {
+ "url": "icons/iconic/read_more.png",
+ "set": "iconic",
+ "name": "read_more"
+ },
+ {
+ "url": "icons/iconic/right_quote.png",
+ "set": "iconic",
+ "name": "right_quote"
+ },
+ {
+ "url": "icons/iconic/right_quote_alt.png",
+ "set": "iconic",
+ "name": "right_quote_alt"
+ },
+ {
+ "url": "icons/iconic/rss.png",
+ "set": "iconic",
+ "name": "rss"
+ },
+ {
+ "url": "icons/iconic/rss_alt.png",
+ "set": "iconic",
+ "name": "rss_alt"
+ },
+ {
+ "url": "icons/iconic/spin_alt.png",
+ "set": "iconic",
+ "name": "spin_alt"
+ },
+ {
+ "url": "icons/iconic/star.png",
+ "set": "iconic",
+ "name": "star"
+ },
+ {
+ "url": "icons/iconic/stop.png",
+ "set": "iconic",
+ "name": "stop"
+ },
+ {
+ "url": "icons/iconic/sun.png",
+ "set": "iconic",
+ "name": "sun"
+ },
+ {
+ "url": "icons/iconic/tag_fill.png",
+ "set": "iconic",
+ "name": "tag_fill"
+ },
+ {
+ "url": "icons/iconic/tag_stroke.png",
+ "set": "iconic",
+ "name": "tag_stroke"
+ },
+ {
+ "url": "icons/iconic/trash_fill.png",
+ "set": "iconic",
+ "name": "trash_fill"
+ },
+ {
+ "url": "icons/iconic/trash_stroke.png",
+ "set": "iconic",
+ "name": "trash_stroke"
+ },
+ {
+ "url": "icons/iconic/undo.png",
+ "set": "iconic",
+ "name": "undo"
+ },
+ {
+ "url": "icons/iconic/x_alt.png",
+ "set": "iconic",
+ "name": "x_alt"
+ }
+]
View
12 stashboard/fixtures/statuses.json
@@ -0,0 +1,12 @@
+[
+ {
+ "url": "icons/fugue/broom.png",
+ "set": "fugue",
+ "name": "broom"
+ },
+ {
+ "url": "icons/fugue/bug.png",
+ "set": "fugue",
+ "name": "bug"
+ }
+]
View
60 stashboard/handlers/admin.py
@@ -2,7 +2,7 @@
from google.appengine.api import users
from google.appengine.ext import db
from handlers import site
-from models import Service, Status, Event
+from models import Service, Status, Event, Level
from utils import slugify
def default_template_data():
@@ -151,3 +151,61 @@ def get(self, slug, key_str):
td.update(site.default_template_data())
self.render(td, 'admin/events_delete.html')
+class EditStatusHandler(site.BaseHandler):
+
+ def get(self, slug):
+ status = Status.get_by_slug(slug)
+ if not status:
+ self.not_found()
+ return
+
+ td = {
+ "statuses_selected": True,
+ "status": status,
+ "action": "edit",
+ "description": status.description,
+ "name": status.name,
+ # "images": Images.all(),
+ "levels": Level.all(),
+ }
+
+ td.update(site.default_template_data())
+ self.render(td, 'admin/status_edit.html')
+
+
+class DeleteStatusHandler(site.BaseHandler):
+
+ def get(self, slug):
+ status = Status.get_by_slug(slug)
+ if not status:
+ self.not_found()
+ return
+
+ td = {
+ "statuses_selected": True,
+ "status": status,
+ }
+
+ td.update(site.default_template_data())
+ self.render(td, 'admin/status_delete.html')
+
+class CreateServiceHandler(site.BaseHandler):
+
+ def get(self):
+ td = {
+ "statuses_selected": True,
+ "url": "/admin/api/v1/statuses",
+ "action": "create",
+ }
+
+ td.update(site.default_template_data())
+ self.render(td, 'admin/statuses_create.html')
+
+class StatusHandler(site.BaseHandler):
+
+ def get(self):
+ td = default_template_data()
+ td["statuses_selected"] = True
+ td["statuses"] = Status.all().order("name").fetch(1000)
+ self.render(td, 'admin/status.html')
+
View
3  stashboard/main.py
@@ -72,6 +72,9 @@
(r'/admin/services/(.*)/edit', admin.EditServiceHandler),
(r'/admin/services/(.*)', admin.ServiceInstanceHandler),
(r'/admin/services', admin.ServiceHandler),
+ (r'/admin/statuses/(.*)/delete', admin.DeleteStatusHandler),
+ (r'/admin/statuses/(.*)/edit', admin.EditStatusHandler),
+ (r'/admin/statuses', admin.StatusHandler),
(r'/admin/credentials', site.ProfileHandler),
(r'/admin/verify', site.VerifyAccessHandler),
(r'/admin', admin.RootHandler),
View
4 stashboard/static/css/style.css
@@ -292,11 +292,11 @@ ul.admin li {
border-bottom: 1px solid #CCC;
}
-ul.admin .service {
+ul.admin .name {
font-size: 20px;
}
-ul.admin .service:hover {
+ul.admin .name:hover {
font-size: 20px;
text-decoration: underline;
}
View
2  stashboard/templates/admin/admin.html
@@ -12,7 +12,7 @@
<a href="/admin/services">Services</a></li>
<li {% if statuses_selected %} class="selected" {% endif %}>
- <a href="/admin/stauses">Statuses</a></li>
+ <a href="/admin/statuses">Statuses</a></li>
</ul>
</nav>
View
2  stashboard/templates/admin/services.html
@@ -5,7 +5,7 @@
<ul class="admin">
{% for service in services %}
<li>
- <a class="service" href="/admin/services/{{ service.slug }}">{{ service.name }}</a>
+ <a class="name" href="/admin/services/{{ service.slug }}">{{ service.name }}</a>
<a class="button danger icon trash" href="/admin/services/{{ service.slug }}/delete">Delete</a>
<a class="button icon edit" href="/admin/services/{{ service.slug }}/edit">Edit</a>
</li>
View
74 stashboard/templates/admin/status.html
@@ -1,63 +1,19 @@
-<div class="legend" id="legend">
- <h4> Legend </h4>
- <table>
- {% if user_is_admin %}
- <thead>
- <tr>
- <th></th>
- <th>Description</th>
- <th>Level</th>
- <th>Edit</th>
- <th>Delete</th>
- </tr>
- </thead>
- {% endif %}
+{% extends "admin/admin.html" %}
- <tbody id="legend-body">
- </tbody>
- </table>
+{% block section %}
- {% if user_is_admin %}
- <a id="add-status" class="button" href="#">Add New Status</a>
+<ul class="admin">
+ {% for status in statuses %}
+ <li>
+ <span class="name">{{ status.name }}</span>
+ <a class="button danger icon trash" href="/admin/services/{{ status.slug }}/delete">Delete</a>
+ <a class="button icon edit" href="/admin/statuses/{{ status.slug }}/edit">Edit</a>
+ </li>
+ {% endfor %}
+</ul>
- <div id="add-status-modal" class="dialog" title="Add New Status">
- <label class="side-label" for="status-name">Name</label>
- <input type="text" id="status-name"name="status-name">
+<a id="create" href="/admin/statuses/create" class="button pill big primary">
+ Create a Status
+</a>
- <label class="side-label" for="status-level">Level</label>
- <select id="statusLevel" class="status-level" name="level">
- </select>
-
- <label for="status-image">Image</label>
- {% for image_row in common_statuses %}
- <div>
- {% for image in image_row %}
-
- <input type="radio" name="status-image" value="{{ image }}">
- <img src="/images/status/{{ image }}.png" />
- {% endfor %}
- </div>
-
- {% endfor %}
-
- <label for="status-description">Description</label>
- <textarea
- id="status-description" name="status-description"></textarea>
- </div>
-
- <div class="dialog" id="delete-status-modal" title="Delete Status">
- <p>Are you sure you want to delete this status? ALL EVENTS with this status will also be deleted</p>
- </div>
-
- {% endif %}
-
- <script type="text/javascript">
- $(document).ready(function(){
- {% if user_is_admin %}
- stashboard.fillLegend(true);
- {% else %}
- stashboard.fillLegend(false);
- {% endif %}
- });
- </script>
-</div>
+{% endblock %}
View
46 stashboard/templates/admin/status_edit.html
@@ -0,0 +1,46 @@
+{% extends "admin/admin.html" %}
+
+{% block section %}
+
+
+<form class="admin" action="{{ url }}" method="post">
+
+ <h1>{{ action|title }} a Status</h1>
+
+ <div class="error">{{ error }}</div>
+
+ <dl class="form">
+ <dt><label for="name">Name</label></dt>
+ <dd><input id="name" name="name" size="30" type="text" value="{{name}}"></dd>
+ <dt><label for="description">Description</label></dt>
+ <dd><textarea id="description" name="description" size="30" type="text">{{description}}</textarea></dd>
+ <dt><label for="image">Image</label></dt>
+ <dd>
+ <fieldset>
+ {% for i in images %}
+ <input type="checkbox" name="image" value="{{i}}" />{{i}}
+ {% endfor %}
+ </fieldset>
+ </dd>
+ <dt><label for="level">Level</label></dt>
+ <dd>
+ <select name="level">
+ {% for l in levels %}
+ <option value="{{ l }}">{{ l }}</option>
+ {% endfor %}
+ </select>
+ </dd>
+ </dl>
+
+ {% if slug %}
+ <link rel="redirect" href="/admin/statuses/{{slug}}" />
+ {% else %}
+ <link rel="redirect" href="/admin/statuses" />
+ {% endif%}
+
+ <button type="submit" class="button pill big primary">
+ {{ action|title }}
+ </button>
+
+</form>
+{% endblock %}
@OyugiK

This impelents the Python function above

Please sign in to comment.
Something went wrong with that request. Please try again.