Ported task list prototype to Angular Dart. Migrating client codebase to Dart.
This commit is contained in:
parent
66cda56502
commit
b18ac3ad32
|
@ -4,6 +4,7 @@ passenger_wsgi.py
|
|||
rookeries_webapp_config.cfg
|
||||
rookeries/static/node_modules
|
||||
rookeries/static/css/penguin-*-theme.css
|
||||
rookeries/static/dart/rookeries.dart.*js*
|
||||
rookeries/static/dart/packages
|
||||
rookeries/static/dart/test/packages
|
||||
rookeries/static/dart/pubspec.lock
|
||||
|
|
|
@ -35,8 +35,8 @@ from rookeries.core import decorators
|
|||
|
||||
@app.route("/")
|
||||
def serve_landing_page():
|
||||
# TODO Get rid of this.
|
||||
return serve_static_file("index.html")
|
||||
nav_menu = generate_menu(bool(session.get('logged_in')))
|
||||
return render_template("base.html", navigation_menu=nav_menu)
|
||||
|
||||
|
||||
@app.route("/tasks")
|
||||
|
@ -45,13 +45,6 @@ def serve_tasks():
|
|||
return render_template("base.html", navigation_menu=nav_menu)
|
||||
|
||||
|
||||
@app.route("/legacy")
|
||||
def serve_legacy_js():
|
||||
# TODO This is deprecated.
|
||||
nav_menu = generate_menu(bool(session.get('logged_in')))
|
||||
return render_template("legacy_base.html", navigation_menu=nav_menu)
|
||||
|
||||
|
||||
@app.before_request
|
||||
def before_session():
|
||||
g.db_session = database.init_db_session(app.config["DATABASE_URI"])
|
||||
|
@ -66,8 +59,7 @@ def generate_menu(logged_in):
|
|||
# TODO Make this generated from the "activated" modules.
|
||||
menu = [{'name': "Home", 'url': "/"},
|
||||
{'name': "Tasks", 'url': "/tasks"},
|
||||
{'name': "FAQ", 'url': "/docs/faq"},
|
||||
{'name': "License", 'url': "/docs/license"}]
|
||||
{'name': "About", 'url': "/about"}]
|
||||
|
||||
if logged_in:
|
||||
menu.append({'name': "Your Profile", 'url': "/user_profile"})
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Rookeries frontend - Controllers
|
||||
* Rookeries frontend - CSS theme switcher.
|
||||
*
|
||||
* (c) Copyright 2013 Dorian Pula
|
||||
* @license: AGPL v3
|
||||
|
@ -8,6 +8,8 @@
|
|||
|
||||
part of rookeries;
|
||||
|
||||
// TODO Document and test.
|
||||
// TODO Consider changing this controller into a directive or component.
|
||||
/**
|
||||
* Toggle between themes.
|
||||
* Based off : http://stackoverflow.com/questions/16514330/angularjs-switch-stylesheets-based-on-user-input
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
name: rookeries_client
|
||||
version: 0.0.2
|
||||
|
||||
environment:
|
||||
sdk: '>=0.8.10+6 <2.0.0'
|
||||
#environment:
|
||||
# sdk: '>=0.8.10+6 <2.0.0'
|
||||
|
||||
dependencies:
|
||||
angular: any
|
||||
browser: any
|
||||
js: any
|
||||
# markdown: any
|
||||
# bootjack: any
|
||||
# ice_code_editor: 0.0.12
|
||||
|
||||
# angular:
|
||||
# git: https://github.com/angular/angular.dart.git
|
||||
|
|
|
@ -8,16 +8,27 @@
|
|||
|
||||
library rookeries;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import 'package:angular/angular.dart';
|
||||
import 'package:di/di.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
part 'controllers.dart';
|
||||
part 'tasks.dart';
|
||||
|
||||
// Rookeries app.
|
||||
class RookeriesApp extends Module {
|
||||
RookeriesApp() {
|
||||
type(SwitchThemeController);
|
||||
type(TaskListController);
|
||||
type(TaskDetailsController);
|
||||
type(CheckmarkFilter);
|
||||
type(DateFormatFilter);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
* Rookeries frontend - Tasks app
|
||||
*
|
||||
* (c) Copyright 2013 Dorian Pula
|
||||
* @license: AGPL v3
|
||||
* @author: Dorian Pula [dorian.pula@amber-penguin-software.ca]
|
||||
*/
|
||||
|
||||
part of rookeries;
|
||||
|
||||
class Task {
|
||||
|
||||
int id;
|
||||
String state;
|
||||
String description;
|
||||
String priority;
|
||||
DateTime due_date;
|
||||
String icon;
|
||||
bool checked;
|
||||
|
||||
Task(this.id, this.state, this.description, this.priority, this.due_date, this.icon, this.checked);
|
||||
|
||||
factory Task.fromJsonMap(Map json) {
|
||||
return new Task(json['id'], json['state'], json['description'], json['priority'],
|
||||
DateTime.parse(json['due_date']), json['icon'], json['checked']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Controls the task list.
|
||||
@NgController(
|
||||
selector: '[task-list]',
|
||||
publishAs: 'task_list')
|
||||
class TaskListController {
|
||||
|
||||
Http _http;
|
||||
List<Task> task_list =[];
|
||||
|
||||
TaskListController(Http this._http) {
|
||||
_fetchTasks();
|
||||
}
|
||||
|
||||
void _fetchTasks() {
|
||||
_http.get('/api/tasks')
|
||||
.then((HttpResponse response) {
|
||||
for (Map task in response.data) {
|
||||
task_list.add(new Task.fromJsonMap(task));
|
||||
}
|
||||
|
||||
}, onError: (Object obj) {
|
||||
print('Oops. Didn\'t get the list of tasks.');
|
||||
print(obj);
|
||||
});
|
||||
}
|
||||
|
||||
void popup(Task task) {
|
||||
var task_id = task.id;
|
||||
document.window.alert('I am task #$task_id');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NgFilter(name: 'checkmark')
|
||||
class CheckmarkFilter {
|
||||
call(input) {
|
||||
if (input is bool) {
|
||||
return input ? "\u2713" : "\u2718";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NgFilter(name: 'date_format')
|
||||
class DateFormatFilter {
|
||||
call(date) {
|
||||
if (date is DateTime) {
|
||||
DateFormat formatter = new DateFormat("yyyy-MMM-dd");
|
||||
return formatter.format(date);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Controls the task details
|
||||
@NgController(
|
||||
selector: '[task-details]',
|
||||
publishAs: 'task')
|
||||
class TaskDetailsController {
|
||||
|
||||
Http _http;
|
||||
Task task;
|
||||
|
||||
TaskDetailsController(Http this._http) {
|
||||
_fetchTask();
|
||||
}
|
||||
|
||||
void _fetchTask() {
|
||||
_http.get('/api/tasks')
|
||||
.then((HttpResponse response) {
|
||||
task = new Task.fromJsonMap(response.body);
|
||||
|
||||
}, onError: (Object obj) {
|
||||
print('Oops. Didn\'t get the list of tasks.');
|
||||
print(obj);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -59,19 +59,6 @@ rookeriesApp.controller(
|
|||
|
||||
}]);
|
||||
|
||||
// Toggle between themes.
|
||||
// Based off : http://stackoverflow.com/questions/16514330/angularjs-switch-stylesheets-based-on-user-input
|
||||
rookeriesApp.controller(
|
||||
"SwitchThemeCtrl", ["$scope", "Theme", function ($scope, Theme) {
|
||||
|
||||
// Use a nice theme object here.
|
||||
$scope.theme = Theme.init("daytime");
|
||||
|
||||
$scope.switchTheme = function() {
|
||||
$scope.theme.switch_theme();
|
||||
}
|
||||
}]);
|
||||
|
||||
rookeriesApp.controller(
|
||||
"NavMenuCtrl", ["$scope", "$state", "NavMenu", function($scope, $state, NavMenu) {
|
||||
|
||||
|
|
|
@ -23,44 +23,6 @@ rookeriesApp
|
|||
});
|
||||
}])
|
||||
|
||||
// Gets the theme dependent on the type of theme being used.
|
||||
.factory("Theme", function() {
|
||||
|
||||
var Theme = {
|
||||
name: "",
|
||||
alternative_theme: "",
|
||||
icon_colour_flag: "",
|
||||
|
||||
// Initialize the theme object.
|
||||
init: function(theme_name) {
|
||||
"use strict";
|
||||
|
||||
if (theme_name === "daytime") {
|
||||
Theme.name = "daytime";
|
||||
Theme.alternative_theme = "evening";
|
||||
Theme.icon_colour_flag = " ";
|
||||
} else {
|
||||
Theme.name = "evening";
|
||||
Theme.alternative_theme = "daytime";
|
||||
Theme.icon_colour_flag = "icon-white";
|
||||
}
|
||||
|
||||
return Theme;
|
||||
},
|
||||
|
||||
// Allow for switching the themes.
|
||||
switch_theme: function() {
|
||||
"use strict";
|
||||
|
||||
Theme.init(Theme.alternative_theme);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return Theme.init("daytime");
|
||||
|
||||
} )
|
||||
|
||||
// Setup for the navigation menu.
|
||||
.factory("NavMenu", ["$state", function($state) {
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
<div>
|
||||
My task ID is {{ task.id }}... <br /><br />
|
||||
I talk about {{ task.description }}.
|
||||
<div task-details>
|
||||
<ul>
|
||||
<li>My task ID is {{ task.id }}.</li>
|
||||
<li>I talk about {{ task.description }}.</li>
|
||||
<li>I am due on {{ task.due_date | date_format }}</li>
|
||||
</ul>
|
||||
</div>
|
|
@ -47,15 +47,15 @@ def task_experiment(task_id):
|
|||
def generate_experimental_task_list():
|
||||
task_list = [{
|
||||
"id": 1, "state": "Done", "description": "Build out basic ui layout for tasks.", "priority": "Normal",
|
||||
"due_date": "2013 July 05", "icon": "icon-android", "checked": False
|
||||
"due_date": "2013-07-05", "icon": "icon-android", "checked": False
|
||||
}, {
|
||||
"id": 2, "state": "In Progress", "description": "Add Angular JS application for tasks.",
|
||||
"priority": "Urgent", "due_date": "2013 July 05", "icon": "icon-linux", "checked": True
|
||||
"priority": "Urgent", "due_date": "2013-07-05", "icon": "icon-linux", "checked": True
|
||||
}, {
|
||||
"id": 3, "state": "Not Started", "description": "Profit ???",
|
||||
"priority": "Normal", "due_date": "2013 July 05", "icon": "icon-bug", "checked": False
|
||||
"priority": "Normal", "due_date": "2013-07-05", "icon": "icon-bug", "checked": False
|
||||
}, {
|
||||
"id": 4, "state": "Done", "description": "Should be the last task", "priority": "Normal",
|
||||
"due_date": "2013 December 05", "icon": "icon-save", "checked": True
|
||||
"due_date": "2013-12-05", "icon": "icon-save", "checked": True
|
||||
}]
|
||||
return task_list
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
{# TODO Figure out how to get rid of scope in Angular directive. #}
|
||||
<html ng-app switch-theme>
|
||||
<head>
|
||||
{% include "page_header.html" %}
|
||||
{% block page_headers %}{% include "page_header.html" %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
|
|
@ -1,6 +1,48 @@
|
|||
{# Body content section #}
|
||||
<div class="col-lg-8 ice-floe" ui-view="content_body_view">
|
||||
<div class="col-lg-8 ice-floe">
|
||||
{% block body_content %}
|
||||
{# Insert in Angular apps and regular Jinja2 templates here. -->#}
|
||||
{# Insert in Angular apps and regular Jinja2 templates here. #}
|
||||
|
||||
{# TODO Move out into partial or something. #}
|
||||
{% raw %}
|
||||
|
||||
<div task-list>
|
||||
<h1>Tasks</h1>
|
||||
<a href="#"><i class="icon-plus"></i> Add New Project</a>
|
||||
<h2>Project Name <i class="icon-edit"></i> <i class="icon-remove"></i></h2>
|
||||
<p>Project description here.</p>
|
||||
<a href="#"><i class="icon-plus"></i> Add New Task</a>
|
||||
<table class="table-bordered table-striped table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">State</th>
|
||||
<th scope="col">Task</th>
|
||||
<th scope="col">Priority</th>
|
||||
<th scope="col">Due Date</th>
|
||||
<th scope="col">Details [XP]</th>
|
||||
<th scope="col" colspan="2">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- tr>
|
||||
<td><i class="icon-ok"></i> Done</td>
|
||||
<td><i class="icon-time"></i> In Progress</td>
|
||||
<td><i class="icon-tasks"></i> Not Started</td>
|
||||
</tr -->
|
||||
<!--<tr ng-repeat="task in tasks_list.list | orderBy:orderProp">-->
|
||||
<tr ng-repeat="task in task_list.task_list">
|
||||
<td><i class="icon-tasks"></i> {{ task.state }}</td>
|
||||
<td>{{ task.description }}</td>
|
||||
<td>{{ task.priority }} - <i ng-class="task.icon"> </i></td>
|
||||
<td>{{ task.due_date | date_format }} - {{ task.checked | checkmark }}</td>
|
||||
<td><a ng-href="#/tasks/{{ task.id }}">Details</a></td>
|
||||
<td><i class="icon-edit" ng-click="task_list.popup(task)"></i></td>
|
||||
<td><i class="icon-remove"></i></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% endraw %}
|
||||
{% endblock %}
|
||||
</div>
|
|
@ -1,23 +0,0 @@
|
|||
{# TODO Purge out legacy AngularJS code #}
|
||||
{% extends "base.html" %}
|
||||
{% body scripts %}
|
||||
<script src="static/js/angular.min.js"></script>
|
||||
<script src="static/js/angular-resource.min.js"></script>
|
||||
|
||||
<script src="static/js/ui-bootstrap-tpls-0.4.0.min.js"></script>
|
||||
<script src="static/js/angular-ui-router-0.0.1.min.js"></script>
|
||||
<script src="static/js/showdown-0.3.1.min.js"></script>
|
||||
|
||||
<script src="static/js/rookeries-application.js"></script>
|
||||
<script src="static/js/rookeries-controllers.js"></script>
|
||||
<script src="static/js/rookeries-directives.js"></script>
|
||||
<script src="static/js/rookeries-filters.js"></script>
|
||||
<script src="static/js/rookeries-services.js"></script>
|
||||
{% endbody %}
|
||||
{% body content %}
|
||||
<!--Sidebar navigation content-->
|
||||
<div class="col-lg-2 col-offset-1 ice-menu" ui-view="nav_menu_view"></div>
|
||||
|
||||
<!--Body content-->
|
||||
<div class="col-lg-8 ice-floe" ui-view="content_body_view"></div>
|
||||
{% endbody %}
|
|
@ -14,6 +14,6 @@
|
|||
<link rel="stylesheet" type="text/css" media="screen" ng-href="static/css/penguin-{{ theme.name }}-theme.css" />
|
||||
{% endraw %}
|
||||
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="http://openfontlibrary.org/face/lavoir" />
|
||||
<!-- link rel="stylesheet" type="text/css" media="screen" href="http://openfontlibrary.org/face/lavoir" />
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="http://openfontlibrary.org/face/benveno" />
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="http://openfontlibrary.org/face/consolamono" />
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="http://openfontlibrary.org/face/consolamono" /-->
|
Loading…
Reference in New Issue