aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile1
-rw-r--r--Gemfile.lock9
-rw-r--r--app/assets/images/icons/select_parent.pngbin0 -> 847 bytes
-rw-r--r--app/assets/javascripts/jquery.tokeninput.js860
-rw-r--r--app/assets/stylesheets/application.css1
-rw-r--r--app/assets/stylesheets/connection_links.css.scss40
-rw-r--r--app/assets/stylesheets/layout.css.scss12
-rw-r--r--app/assets/stylesheets/pagination.css.scss88
-rw-r--r--app/assets/stylesheets/stop_areas.css.scss7
-rw-r--r--app/assets/stylesheets/token-input.css113
-rw-r--r--app/controllers/connection_links_controller.rb27
-rw-r--r--app/controllers/stop_area_parents_controller.rb21
-rw-r--r--app/controllers/stop_areas_controller.rb16
-rw-r--r--app/models/referential.rb4
-rw-r--r--app/views/companies/index.html.erb12
-rw-r--r--app/views/connection_links/_connection_link.erb22
-rw-r--r--app/views/connection_links/_form.erb22
-rw-r--r--app/views/connection_links/edit.html.erb3
-rw-r--r--app/views/connection_links/index.html.erb48
-rw-r--r--app/views/connection_links/new.html.erb3
-rw-r--r--app/views/connection_links/show.html.erb55
-rw-r--r--app/views/help/companies.textile4
-rw-r--r--app/views/help/connection_links.textile46
-rw-r--r--app/views/help/index.textile10
-rw-r--r--app/views/help/lines.textile2
-rw-r--r--app/views/help/networks.textile2
-rw-r--r--app/views/help/normalisation.textile2
-rw-r--r--app/views/help/routes.textile38
-rw-r--r--app/views/help/stop_areas.textile2
-rw-r--r--app/views/help/timetables.textile2
-rw-r--r--app/views/help/toc.textile6
-rw-r--r--app/views/layouts/application.html.erb1
-rw-r--r--app/views/lines/index.html.erb12
-rw-r--r--app/views/networks/index.html.erb12
-rw-r--r--app/views/stop_areas/index.html.erb11
-rw-r--r--app/views/stop_areas/select_parent.html.erb30
-rw-r--r--app/views/stop_areas/show.html.erb4
-rw-r--r--app/views/time_tables/index.html.erb11
-rw-r--r--config/locales/connection_link_types.yml13
-rw-r--r--config/locales/connection_links.yml96
-rw-r--r--config/locales/directions.yml8
-rw-r--r--config/locales/lines.yml4
-rw-r--r--config/locales/stop_areas.yml8
-rw-r--r--config/routes.rb24
-rw-r--r--db/migrate/20120426141032_create_chouette_connection_link.rb28
-rw-r--r--db/schema.rb25
-rw-r--r--spec/requests/connection_links_spec.rb58
-rw-r--r--spec/requests/time_tables_spec.rb50
-rw-r--r--spec/views/connection_links/edit.html.erb_spec.rb24
-rw-r--r--spec/views/connection_links/index.html.erb_spec.rb21
-rw-r--r--spec/views/connection_links/new.html.erb_spec.rb17
-rw-r--r--spec/views/connection_links/show.html.erb_spec.rb30
-rw-r--r--spec/views/time_tables/edit.html.erb_spec.rb23
-rw-r--r--spec/views/time_tables/index.html.erb_spec.rb21
-rw-r--r--spec/views/time_tables/new.html.erb_spec.rb17
-rw-r--r--spec/views/time_tables/show.html.erb_spec.rb24
-rw-r--r--vendor/assets/stylesheets/images/ui-bg_flat_0_aaaaaa_40x100.pngbin0 -> 180 bytes
-rw-r--r--vendor/assets/stylesheets/images/ui-bg_glass_55_fbf9ee_1x400.pngbin0 -> 120 bytes
-rw-r--r--vendor/assets/stylesheets/images/ui-bg_glass_65_ffffff_1x400.pngbin0 -> 105 bytes
-rw-r--r--vendor/assets/stylesheets/images/ui-bg_glass_75_dadada_1x400.pngbin0 -> 111 bytes
-rw-r--r--vendor/assets/stylesheets/images/ui-bg_glass_75_e6e6e6_1x400.pngbin0 -> 110 bytes
-rw-r--r--vendor/assets/stylesheets/images/ui-bg_glass_75_ffffff_1x400.pngbin0 -> 107 bytes
-rw-r--r--vendor/assets/stylesheets/images/ui-bg_highlight-soft_75_cccccc_1x100.pngbin0 -> 101 bytes
-rw-r--r--vendor/assets/stylesheets/images/ui-bg_inset-soft_95_fef1ec_1x100.pngbin0 -> 123 bytes
-rw-r--r--vendor/assets/stylesheets/images/ui-icons_222222_256x240.pngbin0 -> 4369 bytes
-rw-r--r--vendor/assets/stylesheets/images/ui-icons_2e83ff_256x240.pngbin0 -> 4369 bytes
-rw-r--r--vendor/assets/stylesheets/images/ui-icons_454545_256x240.pngbin0 -> 4369 bytes
-rw-r--r--vendor/assets/stylesheets/images/ui-icons_888888_256x240.pngbin0 -> 4369 bytes
-rw-r--r--vendor/assets/stylesheets/images/ui-icons_cd0a0a_256x240.pngbin0 -> 4369 bytes
-rw-r--r--vendor/assets/stylesheets/jquery-ui.css565
70 files changed, 2531 insertions, 84 deletions
diff --git a/Gemfile b/Gemfile
index a37199d13..15e851710 100644
--- a/Gemfile
+++ b/Gemfile
@@ -26,6 +26,7 @@ gem 'inherited_resources'
gem 'will_paginate', '~> 3.0'
gem 'ransack'
gem 'squeel'
+gem 'RedCloth'
gem "acts_as_tree", :git => "git://github.com/dryade/acts_as_tree.git"
gem 'apartment', :git => 'git://github.com/dryade/apartment.git'
diff --git a/Gemfile.lock b/Gemfile.lock
index bdbcf1e80..6825f1f71 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -51,6 +51,8 @@ GEM
remote: http://rubygems.org/
specs:
GeoRuby (1.3.4)
+ RedCloth (4.2.9)
+ RedCloth (4.2.9-java)
SyslogLogger (1.4.0)
hoe (>= 1.2.0)
actionmailer (3.1.3)
@@ -162,8 +164,8 @@ GEM
jruby-openssl (0.7.4)
bouncy-castle-java
jruby-rack (1.1.5)
- json (1.6.6)
- json (1.6.6-java)
+ json (1.7.0)
+ json (1.7.0-java)
launchy (2.0.5)
addressable (~> 2.2.6)
launchy (2.0.5-java)
@@ -261,7 +263,7 @@ GEM
shoulda-context (1.0.0)
shoulda-matchers (1.0.0)
spoon (0.0.1)
- sprockets (2.0.3)
+ sprockets (2.0.4)
hike (~> 1.2)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
@@ -296,6 +298,7 @@ PLATFORMS
ruby
DEPENDENCIES
+ RedCloth
SyslogLogger
activerecord-jdbcpostgresql-adapter!
activerecord-jdbcsqlite3-adapter
diff --git a/app/assets/images/icons/select_parent.png b/app/assets/images/icons/select_parent.png
new file mode 100644
index 000000000..429991dc4
--- /dev/null
+++ b/app/assets/images/icons/select_parent.png
Binary files differ
diff --git a/app/assets/javascripts/jquery.tokeninput.js b/app/assets/javascripts/jquery.tokeninput.js
new file mode 100644
index 000000000..87641a57a
--- /dev/null
+++ b/app/assets/javascripts/jquery.tokeninput.js
@@ -0,0 +1,860 @@
+/*
+ * jQuery Plugin: Tokenizing Autocomplete Text Entry
+ * Version 1.6.0
+ *
+ * Copyright (c) 2009 James Smith (http://loopj.com)
+ * Licensed jointly under the GPL and MIT licenses,
+ * choose which one suits your project best!
+ *
+ */
+
+(function ($) {
+// Default settings
+var DEFAULT_SETTINGS = {
+ // Search settings
+ method: "GET",
+ contentType: "json",
+ queryParam: "q",
+ searchDelay: 300,
+ minChars: 1,
+ propertyToSearch: "name",
+ jsonContainer: null,
+
+ // Display settings
+ hintText: "Type in a search term",
+ noResultsText: "No results",
+ searchingText: "Searching...",
+ deleteText: "×",
+ animateDropdown: true,
+
+ // Tokenization settings
+ tokenLimit: null,
+ tokenDelimiter: ",",
+ preventDuplicates: false,
+
+ // Output settings
+ tokenValue: "id",
+
+ // Prepopulation settings
+ prePopulate: null,
+ processPrePopulate: false,
+
+ // Manipulation settings
+ idPrefix: "token-input-",
+
+ // Formatters
+ resultsFormatter: function(item){ return "<li>" + item[this.propertyToSearch]+ "</li>" },
+ tokenFormatter: function(item) { return "<li><p>" + item[this.propertyToSearch] + "</p></li>" },
+
+ // Callbacks
+ onResult: null,
+ onAdd: null,
+ onDelete: null,
+ onReady: null
+};
+
+// Default classes to use when theming
+var DEFAULT_CLASSES = {
+ tokenList: "token-input-list",
+ token: "token-input-token",
+ tokenDelete: "token-input-delete-token",
+ selectedToken: "token-input-selected-token",
+ highlightedToken: "token-input-highlighted-token",
+ dropdown: "token-input-dropdown",
+ dropdownItem: "token-input-dropdown-item",
+ dropdownItem2: "token-input-dropdown-item2",
+ selectedDropdownItem: "token-input-selected-dropdown-item",
+ inputToken: "token-input-input-token"
+};
+
+// Input box position "enum"
+var POSITION = {
+ BEFORE: 0,
+ AFTER: 1,
+ END: 2
+};
+
+// Keys "enum"
+var KEY = {
+ BACKSPACE: 8,
+ TAB: 9,
+ ENTER: 13,
+ ESCAPE: 27,
+ SPACE: 32,
+ PAGE_UP: 33,
+ PAGE_DOWN: 34,
+ END: 35,
+ HOME: 36,
+ LEFT: 37,
+ UP: 38,
+ RIGHT: 39,
+ DOWN: 40,
+ NUMPAD_ENTER: 108,
+ COMMA: 188
+};
+
+// Additional public (exposed) methods
+var methods = {
+ init: function(url_or_data_or_function, options) {
+ var settings = $.extend({}, DEFAULT_SETTINGS, options || {});
+
+ return this.each(function () {
+ $(this).data("tokenInputObject", new $.TokenList(this, url_or_data_or_function, settings));
+ });
+ },
+ clear: function() {
+ this.data("tokenInputObject").clear();
+ return this;
+ },
+ add: function(item) {
+ this.data("tokenInputObject").add(item);
+ return this;
+ },
+ remove: function(item) {
+ this.data("tokenInputObject").remove(item);
+ return this;
+ },
+ get: function() {
+ return this.data("tokenInputObject").getTokens();
+ }
+}
+
+// Expose the .tokenInput function to jQuery as a plugin
+$.fn.tokenInput = function (method) {
+ // Method calling and initialization logic
+ if(methods[method]) {
+ return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
+ } else {
+ return methods.init.apply(this, arguments);
+ }
+};
+
+// TokenList class for each input
+$.TokenList = function (input, url_or_data, settings) {
+ //
+ // Initialization
+ //
+
+ // Configure the data source
+ if($.type(url_or_data) === "string" || $.type(url_or_data) === "function") {
+ // Set the url to query against
+ settings.url = url_or_data;
+
+ // If the URL is a function, evaluate it here to do our initalization work
+ var url = computeURL();
+
+ // Make a smart guess about cross-domain if it wasn't explicitly specified
+ if(settings.crossDomain === undefined) {
+ if(url.indexOf("://") === -1) {
+ settings.crossDomain = false;
+ } else {
+ settings.crossDomain = (location.href.split(/\/+/g)[1] !== url.split(/\/+/g)[1]);
+ }
+ }
+ } else if(typeof(url_or_data) === "object") {
+ // Set the local data to search through
+ settings.local_data = url_or_data;
+ }
+
+ // Build class names
+ if(settings.classes) {
+ // Use custom class names
+ settings.classes = $.extend({}, DEFAULT_CLASSES, settings.classes);
+ } else if(settings.theme) {
+ // Use theme-suffixed default class names
+ settings.classes = {};
+ $.each(DEFAULT_CLASSES, function(key, value) {
+ settings.classes[key] = value + "-" + settings.theme;
+ });
+ } else {
+ settings.classes = DEFAULT_CLASSES;
+ }
+
+
+ // Save the tokens
+ var saved_tokens = [];
+
+ // Keep track of the number of tokens in the list
+ var token_count = 0;
+
+ // Basic cache to save on db hits
+ var cache = new $.TokenList.Cache();
+
+ // Keep track of the timeout, old vals
+ var timeout;
+ var input_val;
+
+ // Create a new text input an attach keyup events
+ var input_box = $("<input type=\"text\" autocomplete=\"off\">")
+ .css({
+ outline: "none"
+ })
+ .attr("id", settings.idPrefix + input.id)
+ .focus(function () {
+ if (settings.tokenLimit === null || settings.tokenLimit !== token_count) {
+ show_dropdown_hint();
+ }
+ })
+ .blur(function () {
+ hide_dropdown();
+ $(this).val("");
+ })
+ .bind("keyup keydown blur update", resize_input)
+ .keydown(function (event) {
+ var previous_token;
+ var next_token;
+
+ switch(event.keyCode) {
+ case KEY.LEFT:
+ case KEY.RIGHT:
+ case KEY.UP:
+ case KEY.DOWN:
+ if(!$(this).val()) {
+ previous_token = input_token.prev();
+ next_token = input_token.next();
+
+ if((previous_token.length && previous_token.get(0) === selected_token) || (next_token.length && next_token.get(0) === selected_token)) {
+ // Check if there is a previous/next token and it is selected
+ if(event.keyCode === KEY.LEFT || event.keyCode === KEY.UP) {
+ deselect_token($(selected_token), POSITION.BEFORE);
+ } else {
+ deselect_token($(selected_token), POSITION.AFTER);
+ }
+ } else if((event.keyCode === KEY.LEFT || event.keyCode === KEY.UP) && previous_token.length) {
+ // We are moving left, select the previous token if it exists
+ select_token($(previous_token.get(0)));
+ } else if((event.keyCode === KEY.RIGHT || event.keyCode === KEY.DOWN) && next_token.length) {
+ // We are moving right, select the next token if it exists
+ select_token($(next_token.get(0)));
+ }
+ } else {
+ var dropdown_item = null;
+
+ if(event.keyCode === KEY.DOWN || event.keyCode === KEY.RIGHT) {
+ dropdown_item = $(selected_dropdown_item).next();
+ } else {
+ dropdown_item = $(selected_dropdown_item).prev();
+ }
+
+ if(dropdown_item.length) {
+ select_dropdown_item(dropdown_item);
+ }
+ return false;
+ }
+ break;
+
+ case KEY.BACKSPACE:
+ previous_token = input_token.prev();
+
+ if(!$(this).val().length) {
+ if(selected_token) {
+ delete_token($(selected_token));
+ hidden_input.change();
+ } else if(previous_token.length) {
+ select_token($(previous_token.get(0)));
+ }
+
+ return false;
+ } else if($(this).val().length === 1) {
+ hide_dropdown();
+ } else {
+ // set a timeout just long enough to let this function finish.
+ setTimeout(function(){do_search();}, 5);
+ }
+ break;
+
+ case KEY.TAB:
+ case KEY.ENTER:
+ case KEY.NUMPAD_ENTER:
+ case KEY.COMMA:
+ if(selected_dropdown_item) {
+ add_token($(selected_dropdown_item).data("tokeninput"));
+ hidden_input.change();
+ return false;
+ }
+ break;
+
+ case KEY.ESCAPE:
+ hide_dropdown();
+ return true;
+
+ default:
+ if(String.fromCharCode(event.which)) {
+ // set a timeout just long enough to let this function finish.
+ setTimeout(function(){do_search();}, 5);
+ }
+ break;
+ }
+ });
+
+ // Keep a reference to the original input box
+ var hidden_input = $(input)
+ .hide()
+ .val("")
+ .focus(function () {
+ input_box.focus();
+ })
+ .blur(function () {
+ input_box.blur();
+ });
+
+ // Keep a reference to the selected token and dropdown item
+ var selected_token = null;
+ var selected_token_index = 0;
+ var selected_dropdown_item = null;
+
+ // The list to store the token items in
+ var token_list = $("<ul />")
+ .addClass(settings.classes.tokenList)
+ .click(function (event) {
+ var li = $(event.target).closest("li");
+ if(li && li.get(0) && $.data(li.get(0), "tokeninput")) {
+ toggle_select_token(li);
+ } else {
+ // Deselect selected token
+ if(selected_token) {
+ deselect_token($(selected_token), POSITION.END);
+ }
+
+ // Focus input box
+ input_box.focus();
+ }
+ })
+ .mouseover(function (event) {
+ var li = $(event.target).closest("li");
+ if(li && selected_token !== this) {
+ li.addClass(settings.classes.highlightedToken);
+ }
+ })
+ .mouseout(function (event) {
+ var li = $(event.target).closest("li");
+ if(li && selected_token !== this) {
+ li.removeClass(settings.classes.highlightedToken);
+ }
+ })
+ .insertBefore(hidden_input);
+
+ // The token holding the input box
+ var input_token = $("<li />")
+ .addClass(settings.classes.inputToken)
+ .appendTo(token_list)
+ .append(input_box);
+
+ // The list to store the dropdown items in
+ var dropdown = $("<div>")
+ .addClass(settings.classes.dropdown)
+ .appendTo("body")
+ .hide();
+
+ // Magic element to help us resize the text input
+ var input_resizer = $("<tester/>")
+ .insertAfter(input_box)
+ .css({
+ position: "absolute",
+ top: -9999,
+ left: -9999,
+ width: "auto",
+ fontSize: input_box.css("fontSize"),
+ fontFamily: input_box.css("fontFamily"),
+ fontWeight: input_box.css("fontWeight"),
+ letterSpacing: input_box.css("letterSpacing"),
+ whiteSpace: "nowrap"
+ });
+
+ // Pre-populate list if items exist
+ hidden_input.val("");
+ var li_data = settings.prePopulate || hidden_input.data("pre");
+ if(settings.processPrePopulate && $.isFunction(settings.onResult)) {
+ li_data = settings.onResult.call(hidden_input, li_data);
+ }
+ if(li_data && li_data.length) {
+ $.each(li_data, function (index, value) {
+ insert_token(value);
+ checkTokenLimit();
+ });
+ }
+
+ // Initialization is done
+ if($.isFunction(settings.onReady)) {
+ settings.onReady.call();
+ }
+
+ //
+ // Public functions
+ //
+
+ this.clear = function() {
+ token_list.children("li").each(function() {
+ if ($(this).children("input").length === 0) {
+ delete_token($(this));
+ }
+ });
+ }
+
+ this.add = function(item) {
+ add_token(item);
+ }
+
+ this.remove = function(item) {
+ token_list.children("li").each(function() {
+ if ($(this).children("input").length === 0) {
+ var currToken = $(this).data("tokeninput");
+ var match = true;
+ for (var prop in item) {
+ if (item[prop] !== currToken[prop]) {
+ match = false;
+ break;
+ }
+ }
+ if (match) {
+ delete_token($(this));
+ }
+ }
+ });
+ }
+
+ this.getTokens = function() {
+ return saved_tokens;
+ }
+
+ //
+ // Private functions
+ //
+
+ function checkTokenLimit() {
+ if(settings.tokenLimit !== null && token_count >= settings.tokenLimit) {
+ input_box.hide();
+ hide_dropdown();
+ return;
+ }
+ }
+
+ function resize_input() {
+ if(input_val === (input_val = input_box.val())) {return;}
+
+ // Enter new content into resizer and resize input accordingly
+ var escaped = input_val.replace(/&/g, '&amp;').replace(/\s/g,' ').replace(/</g, '&lt;').replace(/>/g, '&gt;');
+ input_resizer.html(escaped);
+ input_box.width(input_resizer.width() + 30);
+ }
+
+ function is_printable_character(keycode) {
+ return ((keycode >= 48 && keycode <= 90) || // 0-1a-z
+ (keycode >= 96 && keycode <= 111) || // numpad 0-9 + - / * .
+ (keycode >= 186 && keycode <= 192) || // ; = , - . / ^
+ (keycode >= 219 && keycode <= 222)); // ( \ ) '
+ }
+
+ // Inner function to a token to the list
+ function insert_token(item) {
+ var this_token = settings.tokenFormatter(item);
+ this_token = $(this_token)
+ .addClass(settings.classes.token)
+ .insertBefore(input_token);
+
+ // The 'delete token' button
+ $("<span>" + settings.deleteText + "</span>")
+ .addClass(settings.classes.tokenDelete)
+ .appendTo(this_token)
+ .click(function () {
+ delete_token($(this).parent());
+ hidden_input.change();
+ return false;
+ });
+
+ // Store data on the token
+ var token_data = {"id": item.id};
+ token_data[settings.propertyToSearch] = item[settings.propertyToSearch];
+ $.data(this_token.get(0), "tokeninput", item);
+
+ // Save this token for duplicate checking
+ saved_tokens = saved_tokens.slice(0,selected_token_index).concat([token_data]).concat(saved_tokens.slice(selected_token_index));
+ selected_token_index++;
+
+ // Update the hidden input
+ update_hidden_input(saved_tokens, hidden_input);
+
+ token_count += 1;
+
+ // Check the token limit
+ if(settings.tokenLimit !== null && token_count >= settings.tokenLimit) {
+ input_box.hide();
+ hide_dropdown();
+ }
+
+ return this_token;
+ }
+
+ // Add a token to the token list based on user input
+ function add_token (item) {
+ var callback = settings.onAdd;
+
+ // See if the token already exists and select it if we don't want duplicates
+ if(token_count > 0 && settings.preventDuplicates) {
+ var found_existing_token = null;
+ token_list.children().each(function () {
+ var existing_token = $(this);
+ var existing_data = $.data(existing_token.get(0), "tokeninput");
+ if(existing_data && existing_data.id === item.id) {
+ found_existing_token = existing_token;
+ return false;
+ }
+ });
+
+ if(found_existing_token) {
+ select_token(found_existing_token);
+ input_token.insertAfter(found_existing_token);
+ input_box.focus();
+ return;
+ }
+ }
+
+ // Insert the new tokens
+ if(settings.tokenLimit == null || token_count < settings.tokenLimit) {
+ insert_token(item);
+ checkTokenLimit();
+ }
+
+ // Clear input box
+ input_box.val("");
+
+ // Don't show the help dropdown, they've got the idea
+ hide_dropdown();
+
+ // Execute the onAdd callback if defined
+ if($.isFunction(callback)) {
+ callback.call(hidden_input,item);
+ }
+ }
+
+ // Select a token in the token list
+ function select_token (token) {
+ token.addClass(settings.classes.selectedToken);
+ selected_token = token.get(0);
+
+ // Hide input box
+ input_box.val("");
+
+ // Hide dropdown if it is visible (eg if we clicked to select token)
+ hide_dropdown();
+ }
+
+ // Deselect a token in the token list
+ function deselect_token (token, position) {
+ token.removeClass(settings.classes.selectedToken);
+ selected_token = null;
+
+ if(position === POSITION.BEFORE) {
+ input_token.insertBefore(token);
+ selected_token_index--;
+ } else if(position === POSITION.AFTER) {
+ input_token.insertAfter(token);
+ selected_token_index++;
+ } else {
+ input_token.appendTo(token_list);
+ selected_token_index = token_count;
+ }
+
+ // Show the input box and give it focus again
+ input_box.focus();
+ }
+
+ // Toggle selection of a token in the token list
+ function toggle_select_token(token) {
+ var previous_selected_token = selected_token;
+
+ if(selected_token) {
+ deselect_token($(selected_token), POSITION.END);
+ }
+
+ if(previous_selected_token === token.get(0)) {
+ deselect_token(token, POSITION.END);
+ } else {
+ select_token(token);
+ }
+ }
+
+ // Delete a token from the token list
+ function delete_token (token) {
+ // Remove the id from the saved list
+ var token_data = $.data(token.get(0), "tokeninput");
+ var callback = settings.onDelete;
+
+ var index = token.prevAll().length;
+ if(index > selected_token_index) index--;
+
+ // Delete the token
+ token.remove();
+ selected_token = null;
+
+ // Show the input box and give it focus again
+ input_box.focus();
+
+ // Remove this token from the saved list
+ saved_tokens = saved_tokens.slice(0,index).concat(saved_tokens.slice(index+1));
+ if(index < selected_token_index) selected_token_index--;
+
+ // Update the hidden input
+ update_hidden_input(saved_tokens, hidden_input);
+
+ token_count -= 1;
+
+ if(settings.tokenLimit !== null) {
+ input_box
+ .show()
+ .val("")
+ .focus();
+ }
+
+ // Execute the onDelete callback if defined
+ if($.isFunction(callback)) {
+ callback.call(hidden_input,token_data);
+ }
+ }
+
+ // Update the hidden input box value
+ function update_hidden_input(saved_tokens, hidden_input) {
+ var token_values = $.map(saved_tokens, function (el) {
+ return el[settings.tokenValue];
+ });
+ hidden_input.val(token_values.join(settings.tokenDelimiter));
+
+ }
+
+ // Hide and clear the results dropdown
+ function hide_dropdown () {
+ dropdown.hide().empty();
+ selected_dropdown_item = null;
+ }
+
+ function show_dropdown() {
+ dropdown
+ .css({
+ position: "absolute",
+ top: $(token_list).offset().top + $(token_list).outerHeight(),
+ left: $(token_list).offset().left,
+ zindex: 999
+ })
+ .show();
+ }
+
+ function show_dropdown_searching () {
+ if(settings.searchingText) {
+ dropdown.html("<p>"+settings.searchingText+"</p>");
+ show_dropdown();
+ }
+ }
+
+ function show_dropdown_hint () {
+ if(settings.hintText) {
+ dropdown.html("<p>"+settings.hintText+"</p>");
+ show_dropdown();
+ }
+ }
+
+ // Highlight the query part of the search term
+ function highlight_term(value, term) {
+ return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<b>$1</b>");
+ }
+
+ function find_value_and_highlight_term(template, value, term) {
+ return template.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + value + ")(?![^<>]*>)(?![^&;]+;)", "g"), highlight_term(value, term));
+ }
+
+ // Populate the results dropdown with some results
+ function populate_dropdown (query, results) {
+ if(results && results.length) {
+ dropdown.empty();
+ var dropdown_ul = $("<ul>")
+ .appendTo(dropdown)
+ .mouseover(function (event) {
+ select_dropdown_item($(event.target).closest("li"));
+ })
+ .mousedown(function (event) {
+ add_token($(event.target).closest("li").data("tokeninput"));
+ hidden_input.change();
+ return false;
+ })
+ .hide();
+
+ $.each(results, function(index, value) {
+ var this_li = settings.resultsFormatter(value);
+
+ this_li = find_value_and_highlight_term(this_li ,value[settings.propertyToSearch], query);
+
+ this_li = $(this_li).appendTo(dropdown_ul);
+
+ if(index % 2) {
+ this_li.addClass(settings.classes.dropdownItem);
+ } else {
+ this_li.addClass(settings.classes.dropdownItem2);
+ }
+
+ if(index === 0) {
+ select_dropdown_item(this_li);
+ }
+
+ $.data(this_li.get(0), "tokeninput", value);
+ });
+
+ show_dropdown();
+
+ if(settings.animateDropdown) {
+ dropdown_ul.slideDown("fast");
+ } else {
+ dropdown_ul.show();
+ }
+ } else {
+ if(settings.noResultsText) {
+ dropdown.html("<p>"+settings.noResultsText+"</p>");
+ show_dropdown();
+ }
+ }
+ }
+
+ // Highlight an item in the results dropdown
+ function select_dropdown_item (item) {
+ if(item) {
+ if(selected_dropdown_item) {
+ deselect_dropdown_item($(selected_dropdown_item));
+ }
+
+ item.addClass(settings.classes.selectedDropdownItem);
+ selected_dropdown_item = item.get(0);
+ }
+ }
+
+ // Remove highlighting from an item in the results dropdown
+ function deselect_dropdown_item (item) {
+ item.removeClass(settings.classes.selectedDropdownItem);
+ selected_dropdown_item = null;
+ }
+
+ // Do a search and show the "searching" dropdown if the input is longer
+ // than settings.minChars
+ function do_search() {
+ var query = input_box.val().toLowerCase();
+
+ if(query && query.length) {
+ if(selected_token) {
+ deselect_token($(selected_token), POSITION.AFTER);
+ }
+
+ if(query.length >= settings.minChars) {
+ show_dropdown_searching();
+ clearTimeout(timeout);
+
+ timeout = setTimeout(function(){
+ run_search(query);
+ }, settings.searchDelay);
+ } else {
+ hide_dropdown();
+ }
+ }
+ }
+
+ // Do the actual search
+ function run_search(query) {
+ var cache_key = query + computeURL();
+ var cached_results = cache.get(cache_key);
+ if(cached_results) {
+ populate_dropdown(query, cached_results);
+ } else {
+ // Are we doing an ajax search or local data search?
+ if(settings.url) {
+ var url = computeURL();
+ // Extract exisiting get params
+ var ajax_params = {};
+ ajax_params.data = {};
+ if(url.indexOf("?") > -1) {
+ var parts = url.split("?");
+ ajax_params.url = parts[0];
+
+ var param_array = parts[1].split("&");
+ $.each(param_array, function (index, value) {
+ var kv = value.split("=");
+ ajax_params.data[kv[0]] = kv[1];
+ });
+ } else {
+ ajax_params.url = url;
+ }
+
+ // Prepare the request
+ ajax_params.data[settings.queryParam] = query;
+ ajax_params.type = settings.method;
+ ajax_params.dataType = settings.contentType;
+ if(settings.crossDomain) {
+ ajax_params.dataType = "jsonp";
+ }
+
+ // Attach the success callback
+ ajax_params.success = function(results) {
+ if($.isFunction(settings.onResult)) {
+ results = settings.onResult.call(hidden_input, results);
+ }
+ cache.add(cache_key, settings.jsonContainer ? results[settings.jsonContainer] : results);
+
+ // only populate the dropdown if the results are associated with the active search query
+ if(input_box.val().toLowerCase() === query) {
+ populate_dropdown(query, settings.jsonContainer ? results[settings.jsonContainer] : results);
+ }
+ };
+
+ // Make the request
+ $.ajax(ajax_params);
+ } else if(settings.local_data) {
+ // Do the search through local data
+ var results = $.grep(settings.local_data, function (row) {
+ return row[settings.propertyToSearch].toLowerCase().indexOf(query.toLowerCase()) > -1;
+ });
+
+ if($.isFunction(settings.onResult)) {
+ results = settings.onResult.call(hidden_input, results);
+ }
+ cache.add(cache_key, results);
+ populate_dropdown(query, results);
+ }
+ }
+ }
+
+ // compute the dynamic URL
+ function computeURL() {
+ var url = settings.url;
+ if(typeof settings.url == 'function') {
+ url = settings.url.call();
+ }
+ return url;
+ }
+};
+
+// Really basic cache for the results
+$.TokenList.Cache = function (options) {
+ var settings = $.extend({
+ max_size: 500
+ }, options);
+
+ var data = {};
+ var size = 0;
+
+ var flush = function () {
+ data = {};
+ size = 0;
+ };
+
+ this.add = function (query, results) {
+ if(size > settings.max_size) {
+ flush();
+ }
+
+ if(!data[query]) {
+ size += 1;
+ }
+
+ data[query] = results;
+ };
+
+ this.get = function (query) {
+ return data[query];
+ };
+};
+}(jQuery));
diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css
index fc25b5723..b17893104 100644
--- a/app/assets/stylesheets/application.css
+++ b/app/assets/stylesheets/application.css
@@ -3,5 +3,6 @@
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
* the top of the compiled file, but it's generally better to create a new file per style scope.
*= require_self
+ *= require jquery-ui
*= require_tree .
*/ \ No newline at end of file
diff --git a/app/assets/stylesheets/connection_links.css.scss b/app/assets/stylesheets/connection_links.css.scss
new file mode 100644
index 000000000..e3aedc918
--- /dev/null
+++ b/app/assets/stylesheets/connection_links.css.scss
@@ -0,0 +1,40 @@
+// Place all the styles related to the lines controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
+@import "common";
+
+#workspace.connection_links.index
+{
+ .connection_link:after {
+ @include after_div_for_object;
+ }
+
+ .connection_links {
+ margin-top: 20px;
+ }
+
+ .connection_links:after {
+ @include content_to_clear;
+ }
+
+ .connection_link {
+ @include div_for_object;
+
+ /* to create multi-column index */
+ width: 350px;
+ float: left;
+ padding-right: 10px;
+ }
+}
+
+
+#workspace.connection_links.show
+{
+
+ .summary p label {
+ font-weight: bold;
+ }
+}
+
+
+
diff --git a/app/assets/stylesheets/layout.css.scss b/app/assets/stylesheets/layout.css.scss
index 335c5b61b..21640e266 100644
--- a/app/assets/stylesheets/layout.css.scss
+++ b/app/assets/stylesheets/layout.css.scss
@@ -32,6 +32,16 @@ $text_color: #222;
#map {
float: right;
- width: 600px;
+ width: 400px;
height: 400px;
+}
+
+.actions {
+ a.add_children {
+ background: url(image-path('user_interface/ui/add.png')) no-repeat;
+ }
+
+ a.select_parent {
+ background: url(image-path('icons/select_parent.png')) no-repeat;
+ }
} \ No newline at end of file
diff --git a/app/assets/stylesheets/pagination.css.scss b/app/assets/stylesheets/pagination.css.scss
index 76ff3cb8f..222ab861b 100644
--- a/app/assets/stylesheets/pagination.css.scss
+++ b/app/assets/stylesheets/pagination.css.scss
@@ -1,52 +1,50 @@
.pagination {
+ background: white;
cursor: default;
-
- margin: 10px 0;
-
- > a, > span, > em {
- padding: 0.2em 0.5em;
- display: block;
- float: left;
- margin-right: 1px;
- }
-
- > .disabled{
- color: #999999;
- /* border: 1px solid #dddddd; */
- }
-
- > .current{
- font-style: normal;
- font-weight: bold;
- background: #61970b;
- color: white;
- border: 1px solid #61970b;
- }
-
- > a{
- text-decoration: none;
- color: #61970b;
- border: 1px solid #ddd;
- &:hover, &:focus{
+ margin-top: 20px;
+
+ /* self-clearing method: */
+ a, span, em {
+ padding: 0.2em 0.5em;
+ display: block;
+ float: left;
+ margin-right: 1px; }
+ .disabled {
+ color: #999999;
+ border: 1px solid #dddddd; }
+ .current {
+ font-style: normal;
+ font-weight: bold;
+ background: #61970b;
+ color: white;
+ border: 1px solid #61970b; }
+ a {
+ text-decoration: none;
color: #86b41d;
- border-color: #86b41d;
- }
- }
-
- .paginated_content {
- padding: 0.4em 0.6em
- }
-
- &:after{
+ border: 1px solid #86b41d; }
+ a:hover, a:focus {
+ color: #000033;
+ border-color: #000033; }
+ .page_info {
+ background: #61970b;
+ color: white;
+ padding: 0.4em 0.6em;
+ width: 22em;
+ margin-bottom: 0.3em;
+ text-align: center; }
+ .page_info b {
+ color: #000033;
+ background: #86b41d;
+ padding: 0.1em 0.25em; }
+}
+
+.pagination:after {
content: ".";
display: block;
height: 0;
clear: both;
- visibility: hidden;}
-
- * html & {
- height: 1%;}
-
- *:first-child+html & {
- overflow: hidden;}
-} \ No newline at end of file
+ visibility: hidden; }
+* html .pagination{
+ height: 1%; }
+*:first-child + html .pagination {
+ overflow: hidden; } \ No newline at end of file
diff --git a/app/assets/stylesheets/stop_areas.css.scss b/app/assets/stylesheets/stop_areas.css.scss
index 60fba8749..b837f4f15 100644
--- a/app/assets/stylesheets/stop_areas.css.scss
+++ b/app/assets/stylesheets/stop_areas.css.scss
@@ -101,5 +101,12 @@
}
}
+#workspace.stop_areas.select_parent
+{
+ .token-input-list{
+ display: inline-block;
+ }
+}
+
diff --git a/app/assets/stylesheets/token-input.css b/app/assets/stylesheets/token-input.css
new file mode 100644
index 000000000..03bb01c4d
--- /dev/null
+++ b/app/assets/stylesheets/token-input.css
@@ -0,0 +1,113 @@
+/* Example tokeninput style #1: Token vertical list*/
+ul.token-input-list {
+ overflow: hidden;
+ height: auto !important;
+ height: 1%;
+ width: 400px;
+ border: 1px solid #999;
+ cursor: text;
+ font-size: 12px;
+ font-family: Verdana;
+ z-index: 999;
+ margin: 0;
+ padding: 0;
+ background-color: #fff;
+ list-style-type: none;
+ clear: left;
+}
+
+ul.token-input-list li {
+ list-style-type: none;
+}
+
+ul.token-input-list li input {
+ border: 0;
+ width: 350px;
+ padding: 3px 8px;
+ background-color: white;
+ -webkit-appearance: caret;
+}
+
+li.token-input-token {
+ overflow: hidden;
+ height: auto !important;
+ height: 1%;
+ margin: 3px;
+ padding: 3px 5px;
+ background-color: #d0efa0;
+ color: #000;
+ font-weight: bold;
+ cursor: default;
+ display: block;
+}
+
+li.token-input-token p {
+ float: left;
+ padding: 0;
+ margin: 0;
+}
+
+li.token-input-token span {
+ float: right;
+ color: #777;
+ cursor: pointer;
+}
+
+li.token-input-selected-token {
+ background-color: #08844e;
+ color: #fff;
+}
+
+li.token-input-selected-token span {
+ color: #bbb;
+}
+
+div.token-input-dropdown {
+ position: absolute;
+ width: 400px;
+ background-color: #fff;
+ overflow: hidden;
+ border-left: 1px solid #ccc;
+ border-right: 1px solid #ccc;
+ border-bottom: 1px solid #ccc;
+ cursor: default;
+ font-size: 12px;
+ font-family: Verdana;
+ z-index: 1;
+}
+
+div.token-input-dropdown p {
+ margin: 0;
+ padding: 5px;
+ font-weight: bold;
+ color: #777;
+}
+
+div.token-input-dropdown ul {
+ margin: 0;
+ padding: 0;
+}
+
+div.token-input-dropdown ul li {
+ background-color: #fff;
+ padding: 3px;
+ list-style-type: none;
+}
+
+div.token-input-dropdown ul li.token-input-dropdown-item {
+ background-color: #fafafa;
+}
+
+div.token-input-dropdown ul li.token-input-dropdown-item2 {
+ background-color: #fff;
+}
+
+div.token-input-dropdown ul li em {
+ font-weight: bold;
+ font-style: normal;
+}
+
+div.token-input-dropdown ul li.token-input-selected-dropdown-item {
+ background-color: #d0efa0;
+}
+
diff --git a/app/controllers/connection_links_controller.rb b/app/controllers/connection_links_controller.rb
new file mode 100644
index 000000000..327fb7989
--- /dev/null
+++ b/app/controllers/connection_links_controller.rb
@@ -0,0 +1,27 @@
+class ConnectionLinksController < ChouetteController
+ defaults :resource_class => Chouette::ConnectionLink
+
+ belongs_to :referential do
+ #belongs_to :departure, :parent_class => Chouette::StopArea, :optional => false
+ #belongs_to :arrival, :parent_class => Chouette::StopArea, :optional => false
+ end
+
+ respond_to :html, :xml, :json
+
+
+ protected
+
+ def collection
+ @q = referential.connection_links.search(params[:q])
+ @connection_links ||= @q.result(:distinct => true).order(:name).paginate(:page => params[:page], :per_page => 10)
+ end
+
+ def resource_url(connection_link = nil)
+ referential_connection_link_path(referential, connection_link || resource)
+ end
+
+ def collection_url
+ referential_connection_links_path(referential)
+ end
+
+end
diff --git a/app/controllers/stop_area_parents_controller.rb b/app/controllers/stop_area_parents_controller.rb
new file mode 100644
index 000000000..526c1cd42
--- /dev/null
+++ b/app/controllers/stop_area_parents_controller.rb
@@ -0,0 +1,21 @@
+class StopAreaParentsController < ChouetteController
+
+ respond_to :json, :only => :index
+
+ def index
+ respond_to do |format|
+ format.json { render :json => parents_maps }
+ end
+ end
+
+ def parents_maps
+ parents.collect do |parent|
+ { :id => parent.id.to_s, :name => "#{parent.name} #{parent.country_code}" }
+ end
+ end
+
+ def parents
+ referential.stop_areas.find(params[:stop_area_id]).possible_parents.select{ |p| p.name =~ /#{params[:q]}/i }
+ end
+
+end
diff --git a/app/controllers/stop_areas_controller.rb b/app/controllers/stop_areas_controller.rb
index baca38598..98111a804 100644
--- a/app/controllers/stop_areas_controller.rb
+++ b/app/controllers/stop_areas_controller.rb
@@ -13,6 +13,20 @@ class StopAreasController < ChouetteController
# render :layout => false
# end
+ def select_parent
+ @stop_area = stop_area
+ @parent = stop_area.parent
+ end
+
+ def add_children
+ @stop_area = stop_area
+ end
+
+ def possible_children
+ @possible_children= stop_area.possible_children
+ render :layout => false
+ end
+
def index
request.format.kml? ? @per_page = nil : @per_page = 10
index!
@@ -39,7 +53,7 @@ class StopAreasController < ChouetteController
end
protected
-
+
alias_method :stop_area, :resource
def collection
diff --git a/app/models/referential.rb b/app/models/referential.rb
index dd5908b8b..8faeea170 100644
--- a/app/models/referential.rb
+++ b/app/models/referential.rb
@@ -21,6 +21,10 @@ class Referential < ActiveRecord::Base
def time_tables
Chouette::TimeTable.scoped
end
+
+ def connection_links
+ Chouette::ConnectionLink.scoped
+ end
def switch
raise "Referential not created" if new_record?
diff --git a/app/views/companies/index.html.erb b/app/views/companies/index.html.erb
index b6ed91aff..257e1a945 100644
--- a/app/views/companies/index.html.erb
+++ b/app/views/companies/index.html.erb
@@ -8,11 +8,19 @@
<%= link_to t("cancel"), referential_companies_path(@referential) %>
<% end %>
-<%= will_paginate @companies %>
+<div class="pagination">
+ <div class="page_info">
+ <%= page_entries_info @companies %>
+ </div>
+ <%= will_paginate @companies, :container => false %>
+</div>
<div class="companies paginated_content">
<%= render :partial => "company", :collection => @companies %>
</div>
-<%= will_paginate @companies %>
+<div class="pagination">
+ <%= will_paginate @companies, :container => false %>
+</div>
+
<% content_for :sidebar do %>
diff --git a/app/views/connection_links/_connection_link.erb b/app/views/connection_links/_connection_link.erb
new file mode 100644
index 000000000..04ed2e833
--- /dev/null
+++ b/app/views/connection_links/_connection_link.erb
@@ -0,0 +1,22 @@
+<%= div_for(connection_link) do %>
+ <%= link_to truncate(connection_link.name, :length => 30), [@referential, connection_link], :title => "Correspondance #{connection_link.name}" %>
+ <div class="info">
+ <%= connection_link.human_attribute_name('departure') %>
+ <% if connection_link.departure.present? %>
+ <%= link_to_if connection_link.departure, connection_link.departure.name, referential_stop_area_path(@referential, connection_link.departure), :title => "#{connection_link.human_attribute_name('departure')} #{connection_link.departure.name}" %>
+ <% else %>
+ <%= connection_link.human_attribute_name("undefined") %>
+ <% end %>
+ &nbsp;-&nbsp;<%= connection_link.human_attribute_name('arrival') %>
+ <% if connection_link.arrival.present? %>
+ <%= link_to_if( connection_link.arrival, connection_link.arrival.name, referential_stop_area_path(@referential, connection_link.arrival), :title => "#{connection_link.human_attribute_name('arrival')} #{connection_link.arrival.name}" ) %>
+ <% else %>
+ <%= connection_link.human_attribute_name("undefined") %>
+ <% end %>
+
+ <div class="actions">
+ <%= link_to t("actions.edit"), edit_referential_connection_link_path(@referential, connection_link), :class => "edit" %> |
+ <%= link_to t("actions.destroy"), referential_connection_link_path(@referential, connection_link), :method => :delete, :confirm => t('connection_links.actions.destroy_confirm'), :class => "remove" %>
+ </div>
+ </div>
+<% end %>
diff --git a/app/views/connection_links/_form.erb b/app/views/connection_links/_form.erb
new file mode 100644
index 000000000..31777c253
--- /dev/null
+++ b/app/views/connection_links/_form.erb
@@ -0,0 +1,22 @@
+<!-- <%= @connection_link.errors.inspect %> -->
+<%= semantic_form_for [@referential, @connection_link] do |form| %>
+ <%= form.inputs do %>
+ <%= form.input :name %>
+ <%= form.input :connection_link_type, :as => :select, :collection => Chouette::ConnectionLink.connection_link_types, :include_blank => false, :member_label => Proc.new { |type| t("connection_link_types.label.#{type}") } %>
+ <%= form.input :comment %>
+ <% if @connection_link.new_record? %>
+ <%= form.input :objectid %>
+ <% else %>
+ <li>
+ <label><%= @connection_link.human_attribute_name("objectid") %>: </label>
+ <%= @connection_link.objectid %>
+ </li>
+ <% end %>
+ <% end %>
+
+ <%= form.buttons do %>
+ <%= form.commit_button true %>
+ <li><%= t('or') %></li>
+ <li><%= link_to t('cancel'), :back %></li>
+ <% end %>
+<% end %>
diff --git a/app/views/connection_links/edit.html.erb b/app/views/connection_links/edit.html.erb
new file mode 100644
index 000000000..77200420b
--- /dev/null
+++ b/app/views/connection_links/edit.html.erb
@@ -0,0 +1,3 @@
+<%= title_tag t('connection_links.edit.title', :connection_link => @connection_link.name ) %>
+
+<%= render "form" %>
diff --git a/app/views/connection_links/index.html.erb b/app/views/connection_links/index.html.erb
new file mode 100644
index 000000000..8b9fc04fa
--- /dev/null
+++ b/app/views/connection_links/index.html.erb
@@ -0,0 +1,48 @@
+<%= title_tag t('connection_links.index.title') %>
+
+<%= search_form_for @q, :url => referential_connection_links_path(@referential), :html => {:method => :get} do |f| %>
+ <%= f.label :name_cont, "#{t('.name')} :" %>
+ <%= f.text_field :name_cont %>
+
+<!--
+ <%= f.hidden_field :departure_id_eq %>
+ <%= f.hidden_field :arrival_id_eq %>
+-->
+
+ <%= f.submit t('actions.search') %> <%= t("or") %>
+ <%= link_to t("cancel"), referential_connection_links_path(@referential) %>
+<% end %>
+
+<!--
+<% if @q.departure_id_eq.present? %>
+<p>
+ <%= Chouette::ConnectionLink.human_attribute_name('departure') %> : <%= @referential.stop_areas.find(@q.departure_id_eq).name %>
+</p>
+<% end %>
+
+<% if @q.arrival_id_eq.present? %>
+<p>
+ <%= Chouette::ConnectionLink.human_attribute_name('arrival') %> : <%= @referential.stop_areas.find(@q.arrival_id_eq).name %>
+</p>
+<% end %>
+-->
+
+<div class="pagination">
+ <div class="page_info">
+ <%= page_entries_info @connection_links %>
+ </div>
+ <%= will_paginate @connection_links, :container => false %>
+</div>
+<div class="connection_links paginated_content">
+ <%= render :partial => "connection_link", :collection => @connection_links %>
+</div>
+<div class="pagination">
+ <%= will_paginate @connection_links, :container => false %>
+</div>
+
+<% content_for :sidebar do %>
+<ul class="actions">
+ <li><%= link_to t('connection_links.actions.new'), new_referential_connection_link_path(@referential), :class => "add" %></li>
+</ul>
+
+<% end %>
diff --git a/app/views/connection_links/new.html.erb b/app/views/connection_links/new.html.erb
new file mode 100644
index 000000000..bd098adc0
--- /dev/null
+++ b/app/views/connection_links/new.html.erb
@@ -0,0 +1,3 @@
+<%= title_tag t('connection_links.new.title') %>
+
+<%= render "form" %>
diff --git a/app/views/connection_links/show.html.erb b/app/views/connection_links/show.html.erb
new file mode 100644
index 000000000..69aad91ea
--- /dev/null
+++ b/app/views/connection_links/show.html.erb
@@ -0,0 +1,55 @@
+<%= title_tag t('connection_links.show.title', :connection_link => @connection_link.name ) %>
+
+<div class="connection_link_show">
+
+ <div class="summary">
+ <p>
+ <label><%= @connection_link.human_attribute_name(:departure) %>: </label>
+ <% if @connection_link.departure.present? %>
+ <%= link_to @connection_link.departure.name, [@referential, @connection_link.departure] %>
+ <% else %>
+ <%= @connection_link.human_attribute_name("undefined") %>
+ <% end %>
+ </p>
+ <p>
+ <label><%= @connection_link.human_attribute_name(:arrival) %>: </label>
+ <% if @connection_link.arrival.present? %>
+ <%= link_to @connection_link.arrival.name, [@referential, @connection_link.arrival] %>
+ <% else %>
+ <%= @connection_link.human_attribute_name("undefined") %>
+ <% end %>
+ </p>
+ <p>
+ <label><%= @connection_link.human_attribute_name("name") %>: </label>
+ <%= @connection_link.name %>
+ </p>
+ <p>
+ <label><%= @connection_link.human_attribute_name("connection_link_type") %>: </label>
+ <%= t("connection_link_types.label.#{@connection_link.connection_link_type}") %>
+ </p>
+ <p>
+ <label><%= @connection_link.human_attribute_name("comment") %>: </label>
+ <%= @connection_link.comment %>
+ </p>
+ <p>
+ <label><%= @connection_link.human_attribute_name("objectid") %>: </label>
+ <%= @connection_link.objectid %>
+ </p>
+ <p>
+ <label><%= @connection_link.human_attribute_name("creation_time") %>: </label>
+ <%= @connection_link.creation_time %>
+ </p>
+ <p>
+ <label><%= @connection_link.human_attribute_name("creator_id") %>: </label>
+ <%= @connection_link.creator_id %>
+ </p>
+ </div>
+</div>
+
+<% content_for :sidebar do %>
+<ul class="actions">
+ <li><%= link_to t('connection_links.actions.edit'), edit_referential_connection_link_path(@referential, @connection_link), :class => "edit" %></li>
+ <li><%= link_to t('connection_links.actions.destroy'), referential_connection_link_path(@referential, @connection_link), :method => :delete, :confirm => t('connection_links.actions.destroy_confirm'), :class => "remove" %></li>
+ <br>
+</ul>
+<% end %>
diff --git a/app/views/help/companies.textile b/app/views/help/companies.textile
index c1db6f4d3..07d7789c5 100644
--- a/app/views/help/companies.textile
+++ b/app/views/help/companies.textile
@@ -9,7 +9,7 @@ Dans la r&eacute;alit&eacute;, le transporteur est l'entit&eacute; en charge de
Ce principe se retrouve dans ce logiciel.
* Il s'agit de l'exploitant de la ligne; chaque ligne est rattach&eacute;e &agrave; un seul transporteur, un transporteur pouvant &eacute;videmment g&eacute;rer plusieurs lignes.
-* Chaque transporteur dispose d'un identifiant fonctionnel (&laquo; num&eacute;ro d'enregistrement &raquo;) qui est utilis&eacute; dans les &eacute;changes XML pour identifier le transporteur et le mettre &agrave; jour. Cet identifiant est unique pour toute la base CHOUETTE, quel que soit le r&eacute;seau ; il est donc important que le gestionnaire de la base CHOUETTE le renseigne d'une mani&egrave;re bien d&eacute;finie et p&eacute;renne.
+* Chaque transporteur dispose d'un identifiant fonctionnel (&laquo; num&eacute;ro d'enregistrement &raquo;) qui est utilis&eacute; dans les &eacute;changes XML pour identifier le transporteur et le mettre &agrave; jour. Cet identifiant est unique pour toute la base CHOUETTE, quel que soit le r&eacute;seau ; il est donc important que le gestionnaire de la base CHOUETTE le renseigne d'une mani&egrave;re bien d&eacute;finie et p&eacute;renne.
h3. Attributs
@@ -32,7 +32,7 @@ cet identifiant est compos&eacute; de 3 parties : pr&eacute;fixe:type:id_techniq
* type = Company : cl&eacute; identifiant le type d'objet (valeur impos&eacute;e)
* id_technique : valeur identifiant un seul object d'un type donn&eacute; pour un m&ecirc;me producteur
ce champ obligatoire est automatiquement g&eacute;n&eacute;r&eacute; s'il n'est pas renseign&eacute;
-il est possible aussi de ne renseigner que le pr&eacute;fixe auquel cas la valeur sera compl&eacute;t&eacute;e automatiquement.
+il est possible aussi de ne renseigner que l'identifiant technique auquel cas la valeur sera compl&eacute;t&eacute;e automatiquement.
=:
- Date de cr&eacute;ation := date &agrave; laquelle l'objet a &eacute;t&eacute; cr&eacute;&eacute; ou modifi&eacute; pour la derni&egrave;re fois
- Version := version de l'objet (auto incr&eacute;ment&eacute; &agrave; chaque modification)
diff --git a/app/views/help/connection_links.textile b/app/views/help/connection_links.textile
new file mode 100644
index 000000000..941918e2d
--- /dev/null
+++ b/app/views/help/connection_links.textile
@@ -0,0 +1,46 @@
+---
+layout: default
+title: Correspondances
+---
+
+h3. D&eacute;finition
+
+Une correspondance ou un changement est, dans un voyage en transports en commun, une &eacute;tape n&eacute;cessitant de changer de ligne. Le changement peut se faire soit au sein du m&ecirc;me r&eacute;seau, soit de mani&egrave;re intermodale, c'est-&agrave;-dire en changeant &eacute;galement de mode de transport.
+La correspondance permet d'&eacute;tablir une liaison entre un arr&ecirc;t physique (ou une zone d'arr&ecirc;t de type &laquo; arr&ecirc;t commercial &raquo; ou de type &laquo; p&ocirc;le d'&eacute;change &raquo;) et un autre arr&ecirc;t physique (ou une autre zone d'arr&ecirc;t de type &laquo; arr&ecirc;t commercial &raquo; ou de type &laquo; p&ocirc;le d'&eacute;change &raquo;).
+Cette liaison d&eacute;finit aussi une dur&eacute;e de parcours entre les arr&ecirc;ts (ou zones) reli&eacute;s.
+
+h3. Attributs
+
+- Nom := nom de la correspondances
+- Commentaire := zone de texte libre
+- Distance := distance en m&egrave;tres
+- Type := liste de choix parmi &laquo; A&eacute;rien &raquo;, &laquo; Souterrain&raquo; ou mixte &laquo; A&eacute;rien et souterrain &raquo;
+- D&eacute;part := arr&ecirc;t de d&eacute;part de la correspondance
+- Arriv&eacute;e := arr&ecirc;t d'arriv&eacute;e de la correspondance
+- Dur&eacute;e moyenne := champ de type horaire hh:mm
+- Dur&eacute;e pour un voyageur &agrave; mobilit&eacute; r&eacute;duite := champ de type horaire hh:mm
+- Dur&eacute;e pour un voyageur occasionnel := champ de type horaire hh:mm
+- Dur&eacute;e pour un habitu&eacute; := champ de type horaire hh:mm
+- Ascenseur := indicateur (Oui ou Non)
+- Acc&egrave;s pour personne &agrave; mobilit&eacute; r&eacute;duite := indicateur (Oui ou Non)
+- Escalator disponible := indicateur (Oui ou Non)
+
+p(attr_data). Donn&eacute;es de gestion :
+
+- Identifiant Neptune :=
+cl&eacute; unique p&eacute;renne identifiant la correspondance pour les &eacute;changes Neptune
+cet identifiant est compos&eacute; de 3 parties : pr&eacute;fixe:type:id_technique
+* pr&eacute;fixe : cl&eacute; identifiant un producteur de donn&eacute;es unique
+* type = ConnectionLink : cl&eacute; identifiant le type d'objet (valeur impos&eacute;e)
+* id_technique : valeur identifiant un seul object d'un type donn&eacute; pour un m&ecirc;me producteur
+ce champ obligatoire est automatiquement g&eacute;n&eacute;r&eacute; s'il n'est pas renseign&eacute;
+il est possible aussi de ne renseigner que l'identifiant technique auquel cas la valeur sera compl&eacute;t&eacute;e automatiquement.
+=:
+- Date de cr&eacute;ation := date &agrave; laquelle l'objet a &eacute;t&eacute; cr&eacute;&eacute; ou modifi&eacute; pour la derni&egrave;re fois
+- Version := version de l'objet (auto incr&eacute;ment&eacute; &agrave; chaque modification)
+- Cr&eacute;&eacute; par := compte utilisateur ayant proc&eacute;d&eacute; &agrave; la derni&egrave;re modification
+
+h3. Impl&eacute;mentation
+
+p. TODO
+
diff --git a/app/views/help/index.textile b/app/views/help/index.textile
index c3b5ee2bd..a5e488cca 100644
--- a/app/views/help/index.textile
+++ b/app/views/help/index.textile
@@ -3,7 +3,7 @@ layout: default
title: Présentation
---
-Chouette v2 : it&eacute;ration 4 du 16/04/2012
+Chouette v2 : it&eacute;ration 5 du 07/05/2012
Cette it&eacute;ration pr&eacute;sente les formulaires de :
@@ -12,16 +12,20 @@ Cette it&eacute;ration pr&eacute;sente les formulaires de :
* lignes
* arr&ecirc;ts
* calendriers d'application
+* correspondances
+* s&eacute;quences d'arr&ecirc;ts
l'avancement actuel permet de :
* cr&eacute;er, modifier et supprimer les objets
* consulter les cartes
+* d&eacute;placer un arr&ecirc;t depuis la carte (voir mode op&eacute;ratoire dans l'aide des arr&ecirc;ts)
+* associer les arr&ecirc;ts &agrave; leurs parents
les action suivantes ne sont pas encore disponible :
-* d&eacute;placer un arr&ecirc;t depuis la carte
* afficher le fond G&eacute;oportail
* ajouter ou supprimer des dates et des p&eacute;riodes aux calendriers
-* associer les arr&ecirc;ts &agrave; leurs parents
+* associer des arr&ecirc;ts à une s&eacute;quences d'arr&ecirc;ts
* associer une ITL &agrave; une ligne
+
diff --git a/app/views/help/lines.textile b/app/views/help/lines.textile
index 9997c0d50..78348896f 100644
--- a/app/views/help/lines.textile
+++ b/app/views/help/lines.textile
@@ -34,7 +34,7 @@ cet identifiant est compos&eacute; de 3 parties : pr&eacute;fixe:type:id_techniq
* type = Line : cl&eacute; identifiant le type d'objet (valeur impos&eacute;e)
* id_technique : valeur identifiant un seul object d'un type donn&eacute; pour un m&ecirc;me producteur
ce champ obligatoire est automatiquement g&eacute;n&eacute;r&eacute; s'il n'est pas renseign&eacute;
-il est possible aussi de ne renseigner que le pr&eacute;fixe auquel cas la valeur sera compl&eacute;t&eacute;e automatiquement.
+il est possible aussi de ne renseigner que l'identifiant technique auquel cas la valeur sera compl&eacute;t&eacute;e automatiquement.
=:
- Date de cr&eacute;ation := date &agrave; laquelle l'objet a &eacute;t&eacute; cr&eacute;&eacute; ou modifi&eacute; pour la derni&egrave;re fois
- Version := version de l'objet (auto incr&eacute;ment&eacute; &agrave; chaque modification)
diff --git a/app/views/help/networks.textile b/app/views/help/networks.textile
index 424808f48..2a2de2309 100644
--- a/app/views/help/networks.textile
+++ b/app/views/help/networks.textile
@@ -29,7 +29,7 @@ cet identifiant est compos&eacute; de 3 parties : pr&eacute;fixe:type:id_techniq
* type = GroupOfLine : cl&eacute; identifiant le type d'objet (valeur impos&eacute;e)
* id_technique : valeur identifiant un seul object d'un type donn&eacute; pour un m&ecirc;me producteur
ce champ obligatoire est automatiquement g&eacute;n&eacute;r&eacute; s'il n'est pas renseign&eacute;
-il est possible aussi de ne renseigner que le pr&eacute;fixe auquel cas la valeur sera compl&eacute;t&eacute;e automatiquement.
+il est possible aussi de ne renseigner que l'identifiant technique auquel cas la valeur sera compl&eacute;t&eacute;e automatiquement.
=:
- Date de cr&eacute;ation := date &agrave; laquelle l'objet a &eacute;t&eacute; cr&eacute;&eacute; ou modifi&eacute; pour la derni&egrave;re fois
- Version := version de l'objet (auto incr&eacute;ment&eacute; &agrave; chaque modification)
diff --git a/app/views/help/normalisation.textile b/app/views/help/normalisation.textile
index 2790d5320..6d7793eb4 100644
--- a/app/views/help/normalisation.textile
+++ b/app/views/help/normalisation.textile
@@ -21,7 +21,7 @@ Ces sp&eacute;cifications d'&eacute;change couvrent l'information VP et TC, th&e
* un mod&egrave;le de donn&eacute;es orient&eacute; objets d&eacute;crit en UML, reprenant pour ce qui concerne les transports publics, le mod&egrave;le conceptuel de donn&eacute;es Transmodel V4.0, normalis&eacute; au niveau europ&eacute;en ;
* un format d'&eacute;change XML sp&eacute;cifi&eacute; sous forme de sch&eacute;mas XSD.
-Les sp&eacute;cifications TRIDENT ont &eacute;t&eacute; impl&eacute;ment&eacute;es dans plusieurs pays europ&eacute;ens, et en France ont &eacute;t&eacute; mises en &oelig;uvre par la RATP pour son syst&egrave;me d'information sur les situations perturb&eacute;es SIPRE, et &eacute;galement pour les &eacute;changes d'information au niveau francilien en cours entre les syst&egrave;mes de la RATP et du STIF, pour ce qui concerne l'information th&eacute;orique.
+Les sp&eacute;cifications TRIDENT ont &eacute;t&eacute; impl&eacute;ment&eacute;es dans plusieurs pays europ&eacute;ens, et en France ont &eacute;t&eacute; mises en &&oelig;lig;uvre par la RATP pour son syst&egrave;me d'information sur les situations perturb&eacute;es SIPRE, et &eacute;galement pour les &eacute;changes d'information au niveau francilien en cours entre les syst&egrave;mes de la RATP et du STIF, pour ce qui concerne l'information th&eacute;orique.
Le travail du groupe GT7 a abouti &agrave; des sp&eacute;cifications de profil d'&eacute;change TRIDENT / Chouette en 2006, qui ont servi de r&eacute;f&eacute;rence pour impl&eacute;menter le logiciel CHOUETTE et sont utilis&eacute;es depuis lors par plusieurs projets de SIM en France.
diff --git a/app/views/help/routes.textile b/app/views/help/routes.textile
new file mode 100644
index 000000000..30234c492
--- /dev/null
+++ b/app/views/help/routes.textile
@@ -0,0 +1,38 @@
+---
+layout: default
+title: Séquence d'arrêts
+---
+
+h3. D&eacute;finition
+
+La s&eacute;quence d'arr&ecirc;ts est une s&eacute;lection ordonn&eacute;e de r&eacute;f&eacute;rences aux points d'arr&ecirc;t (exemple: itin&eacute;raires aller et retour d'une ligne). Une s&eacute;quence d'arr&ecirc;ts est sp&eacute;cifique &agrave; une ligne; les s&eacute;quences d'arr&ecirc;ts peuvent r&eacute;f&eacute;rencer des arr&ecirc;ts communs.
+
+h3. Attributs
+
+- Nom := nom de la s&eacute;quence d'arr&ecirc;ts
+- Nom public := nom public pour les voyageurs
+- Commentaire := zone de texte libre sur le r&eacute;seau
+- Direction := orientation principale (points cardinaux, circulaire ou aller/retour)
+- Indoce := num&eacute;ro de la s&eacute;quence d'arr&ecirc;ts
+- Sens := aller ou retour
+- Itin&eacute;raire associ&eacute; en sens oppos&eacute; := r&eacute;f&eacute;rence de l'itin&eacute;raire de sens oppos&eacute; associ&eacute;
+
+p(attr_data). Donn&eacute;es de gestion :
+
+- Identifiant Neptune :=
+cl&eacute; unique p&eacute;renne identifiant la s&eacute;quence d'arr&ecirc;ts pour les &eacute;changes Neptune
+cet identifiant est compos&eacute; de 3 parties : pr&eacute;fixe:type:id_technique
+* pr&eacute;fixe : cl&eacute; identifiant un producteur de donn&eacute;es unique
+* type = Route : cl&eacute; identifiant le type d'objet (valeur impos&eacute;e)
+* id_technique : valeur identifiant un seul object d'un type donn&eacute; pour un m&ecirc;me producteur
+ce champ obligatoire est automatiquement g&eacute;n&eacute;r&eacute; s'il n'est pas renseign&eacute;
+il est possible aussi de ne renseigner que l'identifiant technique auquel cas la valeur sera compl&eacute;t&eacute;e automatiquement.
+=:
+- Date de cr&eacute;ation := date &agrave; laquelle l'objet a &eacute;t&eacute; cr&eacute;&eacute; ou modifi&eacute; pour la derni&egrave;re fois
+- Version := version de l'objet (auto incr&eacute;ment&eacute; &agrave; chaque modification)
+- Cr&eacute;&eacute; par := compte utilisateur ayant proc&eacute;d&eacute; &agrave; la derni&egrave;re modification
+
+h3. Impl&eacute;mentation
+
+p. TODO
+
diff --git a/app/views/help/stop_areas.textile b/app/views/help/stop_areas.textile
index 8c468e9f1..94b73c574 100644
--- a/app/views/help/stop_areas.textile
+++ b/app/views/help/stop_areas.textile
@@ -68,7 +68,7 @@ cet identifiant est compos&eacute; de 3 parties : pr&eacute;fixe:type:id_techniq
* type = Line : cl&eacute; identifiant le type d'objet (valeur impos&eacute;e)
* id_technique : valeur identifiant un seul object d'un type donn&eacute; pour un m&ecirc;me producteur
ce champ obligatoire est automatiquement g&eacute;n&eacute;r&eacute; s'il n'est pas renseign&eacute;
-il est possible aussi de ne renseigner que le pr&eacute;fixe auquel cas la valeur sera compl&eacute;t&eacute;e automatiquement.
+il est possible aussi de ne renseigner que l'identifiant technique auquel cas la valeur sera compl&eacute;t&eacute;e automatiquement.
=:
- Date de cr&eacute;ation := date &agrave; laquelle l'objet a &eacute;t&eacute; cr&eacute;&eacute; ou modifi&eacute; pour la derni&egrave;re fois
- Version := version de l'objet (auto incr&eacute;ment&eacute; &agrave; chaque modification)
diff --git a/app/views/help/timetables.textile b/app/views/help/timetables.textile
index 57fe0d50b..6c55e8440 100644
--- a/app/views/help/timetables.textile
+++ b/app/views/help/timetables.textile
@@ -43,7 +43,7 @@ cet identifiant est compos&eacute; de 3 parties : pr&eacute;fixe:type:id_techniq
* type = Timetable : cl&eacute; identifiant le type d'objet (valeur impos&eacute;e)
* id_technique : valeur identifiant un seul object d'un type donn&eacute; pour un m&ecirc;me producteur
ce champ obligatoire est automatiquement g&eacute;n&eacute;r&eacute; s'il n'est pas renseign&eacute;
-il est possible aussi de ne renseigner que le pr&eacute;fixe auquel cas la valeur sera compl&eacute;t&eacute;e automatiquement.
+il est possible aussi de ne renseigner que l'identifiant technique auquel cas la valeur sera compl&eacute;t&eacute;e automatiquement.
=:
- Date de cr&eacute;ation := date &agrave; laquelle l'objet a &eacute;t&eacute; cr&eacute;&eacute; ou modifi&eacute; pour la derni&egrave;re fois
- Version := version de l'objet (auto incr&eacute;ment&eacute; &agrave; chaque modification)
diff --git a/app/views/help/toc.textile b/app/views/help/toc.textile
index f4f6998f8..e3ed1ba6f 100644
--- a/app/views/help/toc.textile
+++ b/app/views/help/toc.textile
@@ -1,6 +1,6 @@
---
layout: default
-title: sommaire
+title: Sommaire
---
h3. Sommaire
@@ -11,10 +11,10 @@ h3. Sommaire
# "R&eacute;seaux":networks
# "Transporteurs":companies
# "Lignes":lines
-## S&eacute;quences d'arr&ecirc;ts
+## "S&eacute;quences d'arr&ecirc;ts":routes
## Horaires
# "Arr&ecirc;ts":stop_areas
-## Correspondances
+## "Correspondances":connection_links
## Acc&egrave;s
## Liaisons Arr&ecirc;t-Acc&egrave;s
# "Calendriers d'application":timetables
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 9c48ff00b..d757c92d4 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -41,6 +41,7 @@
<li><%= tab_link_to Chouette::Company, referential_companies_path(@referential) %></li>
<li><%= tab_link_to Chouette::Line, referential_lines_path(@referential) %></li>
<li><%= tab_link_to Chouette::StopArea, referential_stop_areas_path(@referential) %></li>
+ <li><%= tab_link_to Chouette::ConnectionLink, referential_connection_links_path(@referential) %></li>
<li><%= tab_link_to Chouette::TimeTable, referential_time_tables_path(@referential) %></li>
<% end %>
</ul>
diff --git a/app/views/lines/index.html.erb b/app/views/lines/index.html.erb
index 49c6de226..26b97e0b3 100644
--- a/app/views/lines/index.html.erb
+++ b/app/views/lines/index.html.erb
@@ -23,11 +23,19 @@
</p>
<% end %>
-<%= will_paginate @lines %>
+
+<div class="pagination">
+ <div class="page_info">
+ <%= page_entries_info @lines %>
+ </div>
+ <%= will_paginate @lines, :container => false %>
+</div>
<div class="lines paginated_content">
<%= render :partial => "line", :collection => @lines %>
</div>
-<%= will_paginate @lines %>
+<div class="pagination">
+ <%= will_paginate @lines, :container => false %>
+</div>
<% content_for :sidebar do %>
<ul class="actions">
diff --git a/app/views/networks/index.html.erb b/app/views/networks/index.html.erb
index 4514939f1..825bb3dcb 100644
--- a/app/views/networks/index.html.erb
+++ b/app/views/networks/index.html.erb
@@ -8,12 +8,18 @@
<%= link_to t("cancel"), referential_networks_path(@referential) %>
<% end %>
-<%= will_paginate @networks %>
+<div class="pagination">
+ <div class="page_info">
+ <%= page_entries_info @networks %>
+ </div>
+ <%= will_paginate @networks, :container => false %>
+</div>
<div class="networks paginated_content">
<%= render :partial => "network", :collection => @networks %>
</div>
-<%= will_paginate @networks %>
-
+<div class="pagination">
+ <%= will_paginate @networks, :container => false %>
+</div>
<% content_for :sidebar do %>
<ul class="actions">
diff --git a/app/views/stop_areas/index.html.erb b/app/views/stop_areas/index.html.erb
index deb5b1643..57617f559 100644
--- a/app/views/stop_areas/index.html.erb
+++ b/app/views/stop_areas/index.html.erb
@@ -8,11 +8,18 @@
<%= link_to t("cancel"), referential_stop_areas_path(@referential) %>
<% end %>
-<%= will_paginate @stop_areas %>
+<div class="pagination">
+ <div class="page_info">
+ <%= page_entries_info @stop_areas %>
+ </div>
+ <%= will_paginate @stop_areas, :container => false %>
+</div>
<div class="stop_areas paginated_content">
<%= render :partial => "stop_area", :collection => @stop_areas %>
</div>
-<%= will_paginate @stop_areas %>
+<div class="pagination">
+ <%= will_paginate @stop_areas, :container => false %>
+</div>
<% content_for :sidebar do %>
<ul class="actions">
diff --git a/app/views/stop_areas/select_parent.html.erb b/app/views/stop_areas/select_parent.html.erb
new file mode 100644
index 000000000..b608b9427
--- /dev/null
+++ b/app/views/stop_areas/select_parent.html.erb
@@ -0,0 +1,30 @@
+<%= title_tag t('stop_areas.select_parent.title', :stop_area => @stop_area.name ) %>
+
+<%= semantic_form_for [@referential, @stop_area] do |form| %>
+<div>
+ <%= form.inputs do %>
+ <%= form.input :parent_id, :as => :text, :input_html => { :"data-pre" => [{ :id => @parent.id.to_s, :name => "#{@parent.name} #{@parent.country_code}" }].to_json } %>
+ <% end %>
+
+ <%= form.buttons do %>
+ <%= form.commit_button %>
+ ou <%= link_to "revenir", [@referential, @stop_area] %>
+ <% end %>
+</div>
+<% end %>
+
+<script>
+ $(function() {
+ $( "#stop_area_parent_id" ).tokenInput('<%= referential_stop_area_stop_area_parents_path(@referential, @stop_area, :format => :json) %>', {
+ crossDomain: false,
+ prePopulate: $('#stop_area_parent_id').data('pre'),
+ tokenLimit: 1,
+ minChars: 3,
+ });
+ });
+</script>
+
+<% content_for :sidebar do %>
+<ul class="actions">
+</ul>
+<% end %>
diff --git a/app/views/stop_areas/show.html.erb b/app/views/stop_areas/show.html.erb
index b786eec34..6536ac5cb 100644
--- a/app/views/stop_areas/show.html.erb
+++ b/app/views/stop_areas/show.html.erb
@@ -90,7 +90,7 @@
<% if @stop_area.parent.present? %>
<div class="parent">
- <%= link_to([@referential, stop_area.parent]) do %>
+ <%= link_to([@referential, @stop_area.parent]) do %>
<%= image_tag "map/" + @stop_area.parent.type + ".png" %><span><%= @stop_area.parent.name %></span>
<% end %>
<%= link_to image_tag("user_interface/ui/remove.png"), referential_stop_area_path(@referential, @stop_area.parent), :method => :delete, :confirm => t('stop_areas.actions.destroy_confirm'), :class => "remove" %>
@@ -125,6 +125,8 @@
<ul class="actions">
<li><%= link_to t('stop_areas.actions.edit'), edit_referential_stop_area_path(@referential, @stop_area), :class => "edit" %></li>
<li><%= link_to t('stop_areas.actions.destroy'), referential_stop_area_path(@referential, @stop_area), :method => :delete, :confirm => t('stop_areas.actions.destroy_confirm'), :class => "remove" %></li>
+ <li><%= link_to t('stop_areas.actions.select_parent'), select_parent_referential_stop_area_path(@referential, @stop_area), :class => "select_parent" %></li>
+ <li><%= link_to t('stop_areas.actions.add_children'), add_children_referential_stop_area_path(@referential, @stop_area), :class => "add_children" %></li>
<br>
</ul>
<% end %>
diff --git a/app/views/time_tables/index.html.erb b/app/views/time_tables/index.html.erb
index 90225446a..26e484554 100644
--- a/app/views/time_tables/index.html.erb
+++ b/app/views/time_tables/index.html.erb
@@ -8,11 +8,18 @@
<%= link_to t("cancel"), referential_time_tables_path(@referential) %>
<% end %>
-<%= will_paginate @time_tables %>
+<div class="pagination">
+ <div class="page_info">
+ <%= page_entries_info @time_tables %>
+ </div>
+ <%= will_paginate @time_tables, :container => false %>
+</div>
<div class="time_tables paginated_content">
<%= render :partial => "time_table", :collection => @time_tables %>
</div>
-<%= will_paginate @time_tables %>
+<div class="pagination">
+ <%= will_paginate @time_tables, :container => false %>
+</div>
<% content_for :sidebar do %>
diff --git a/config/locales/connection_link_types.yml b/config/locales/connection_link_types.yml
new file mode 100644
index 000000000..2404aeeff
--- /dev/null
+++ b/config/locales/connection_link_types.yml
@@ -0,0 +1,13 @@
+en:
+ connection_link_types:
+ label:
+ underground: Underground
+ mixed: Mixed
+ overground: Overground
+
+fr:
+ connection_link_types:
+ label:
+ underground: Souterrain
+ mixed: Mixte
+ overground: Aérien
diff --git a/config/locales/connection_links.yml b/config/locales/connection_links.yml
new file mode 100644
index 000000000..15463e47c
--- /dev/null
+++ b/config/locales/connection_links.yml
@@ -0,0 +1,96 @@
+en:
+ connection_links:
+ actions:
+ new: Add a new connection link
+ edit: Edit this connection link
+ destroy: Remove this liconnection linkne
+ destroy_confirm: Are you sure you want destroy this connection link?
+ new:
+ title: Add a new connection link
+ edit:
+ title: Update connection link %{connection_link}
+ show:
+ title: Connection link %{connection_link}
+ index:
+ title: Connection_ links
+ name: Name
+ departure: Start of link
+ arrival: End of link
+ selection: Selection
+ selection_all: All
+ activerecord:
+ models:
+ connection_link: Connection link
+ attributes:
+ connection_link:
+ departure: Start of link
+ arrival: End of link
+ undefined: not yet set
+ name: Name
+ comment: Comment
+ linkdistance: Distance
+ connection_link_type: Type
+ defaultduration: Average duration
+ frequenttravellerduration: Regular passenger duration
+ occasionaltravellerduration: Occasional passenger duration
+ mobilityrestrictedtravellerduration: Mobility reduced passenger duration
+ mobilityrestrictedsuitability: Mobility reduced passenger suitable
+ stairsavailability: Escalator
+ liftavailability: Lift
+ objectid: Neptune identifier
+ object_version: Version
+ creation_time: Created on
+ creator_id: Created by
+ formtastic:
+ hints:
+ connection_link:
+ objectid: "[prefix]:ConnectionLink:[unique_key] : prefix contains only alphanumerical or underscore characters, unique_key accepts also minus character"
+
+fr:
+ connection_links:
+ actions:
+ new: Ajouter une correspondance
+ edit: Modifier cette correspondance
+ destroy: Supprimer cette correspondance
+ destroy_confirm: Etes vous sûr de détruire cette correspondance ?
+ new:
+ title: Ajouter une correspondance
+ edit:
+ title: Modifier la correspondance %{connection_link}
+ show:
+ title: Correspondance %{connection_link}
+ index:
+ name: Nom
+ title: Correspondances
+ departure: Arrêt de départ
+ arrival: "Arrêt d'arrivée"
+ selection: Sélection
+ selection_all: Tous
+ activerecord:
+ models:
+ connection_link: Correspondance
+ attributes:
+ connection_link:
+ departure: Arrêt de départ
+ arrival: "Arrêt d'arrivée"
+ undefined: non défini
+ name: Nom
+ comment: Commentaire
+ linkdistance: Distance
+ connection_link_type: Type
+ defaultduration: Durée moyenne
+ frequenttravellerduration: Durée pour un habitué
+ occasionaltravellerduration: Durée pour un voyageur occasionnel
+ mobilityrestrictedtravellerduration: Durée pour un voyageur à mobilité réduite
+ mobilityrestrictedsuitability: Accès pour personne à mobilité réduite
+ stairsavailability: Escalator
+ liftavailability: Ascenseur
+ objectid: Identifiant Neptune
+ object_version: Version
+ creation_time: Créé le
+ creator_id: Créé par
+ formtastic:
+ hints:
+ connection_link:
+ objectid: "[prefixe]:ConnectionLink:[clé_unique] caractères autorisés : alphanumériques et 'souligné' pour le préfixe, la clé unique accepte en plus le 'moins'"
+
diff --git a/config/locales/directions.yml b/config/locales/directions.yml
index 82b87673a..8e59b0b84 100644
--- a/config/locales/directions.yml
+++ b/config/locales/directions.yml
@@ -3,8 +3,8 @@ en:
label:
straight_forward: straight forward
backward: backward
- clockwise: clockwise
- anti_clockwise: anticlockwise
+ clock_wise: clockwise
+ counter_clock_wise: counterclockwise
north: north
north_west: north west
west: west
@@ -18,8 +18,8 @@ fr:
label:
straight_forward: aller
backward: retour
- clockwise: sens horaire
- anti_clockwise: sens anti horaire
+ clock_wise: sens horaire
+ counter_clock_wise: sens anti horaire
north: nord
north_west: nord ouest
west: ouest
diff --git a/config/locales/lines.yml b/config/locales/lines.yml
index 490a7b630..a2ba7df95 100644
--- a/config/locales/lines.yml
+++ b/config/locales/lines.yml
@@ -28,7 +28,7 @@ en:
name: Name
published_name: Published name
number: Number
- transport_mode_name: Transport mode
+ transport_mode: Transport mode
comment: Comments
objectid: Neptune identifier
object_version: Version
@@ -70,7 +70,7 @@ fr:
name: Nom
published_name: Nom public
number: Indice
- transport_mode_name: Mode de transport
+ transport_mode: Mode de transport
comment: Commentaire
objectid: Identifiant Neptune
object_version: Version
diff --git a/config/locales/stop_areas.yml b/config/locales/stop_areas.yml
index ca4751dbe..78ca3c2d1 100644
--- a/config/locales/stop_areas.yml
+++ b/config/locales/stop_areas.yml
@@ -8,6 +8,8 @@ en:
edit: Edit this stop
destroy: Remove this stop
destroy_confirm: Are you sure you want destroy this stop?
+ select_parent: Select Parent
+ add_children: Add Children
new:
title: Add a new stop
edit:
@@ -23,6 +25,8 @@ en:
selection: Selection
selection_all: All
area_type: Area Type
+ select_parent:
+ title: Select parent of stop area %{stop_area}
activerecord:
models:
stop_area: Stop area
@@ -62,6 +66,8 @@ fr:
edit: Modifier cet arrêt
destroy: Supprimer cet arrêt
destroy_confirm: Etes vous sûr de détruire cet arrêt ?
+ select_parent: Sélectionner le parent
+ add_children: Ajouter un fils
new:
title: Ajouter un arrêt
edit:
@@ -77,6 +83,8 @@ fr:
selection: Sélection
selection_all: Tous
area_type: Type d'arrêt
+ select_parent:
+ title: Sélection du parent de l'arrêt %{stop_area}
activerecord:
models:
stop_area: Arrêt
diff --git a/config/routes.rb b/config/routes.rb
index 4aaedc87b..4e7bebfc2 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -16,11 +16,31 @@ ChouetteIhm::Application.routes.draw do
# resources :products
resources :referentials do
resources :lines, :networks do
- resources :stop_areas
+ resources :stop_areas do
+ resources :stop_area_parents
+ member do
+ get 'add_children'
+ get 'select_parent'
+ end
+ end
resources :routes
end
- resources :companies, :stop_areas, :time_tables
+ resources :companies, :stop_areas, :connection_links
+
+ resources :time_tables do
+ resources :time_table_dates
+ resources :time_table_periods
+ end
+
+ resources :stop_areas do
+ resources :stop_area_parents
+ member do
+ get 'add_children'
+ get 'select_parent'
+ end
+ end
+
end
match '/help/(*slug)' => 'help#show'
diff --git a/db/migrate/20120426141032_create_chouette_connection_link.rb b/db/migrate/20120426141032_create_chouette_connection_link.rb
new file mode 100644
index 000000000..185c49af2
--- /dev/null
+++ b/db/migrate/20120426141032_create_chouette_connection_link.rb
@@ -0,0 +1,28 @@
+class CreateChouetteConnectionLink < ActiveRecord::Migration
+ def up
+ create_table "connectionlink", :force => true do |t|
+ t.integer "departureid", :limit => 8
+ t.integer "arrivalid", :limit => 8
+ t.string "objectid", :null => false
+ t.integer "objectversion"
+ t.datetime "creationtime"
+ t.string "creatorid"
+ t.string "name"
+ t.string "comment"
+ t.decimal "linkdistance", :precision => 19, :scale => 2
+ t.string "linktype"
+ t.time "defaultduration"
+ t.time "frequenttravellerduration"
+ t.time "occasionaltravellerduration"
+ t.time "mobilityrestrictedtravellerduration"
+ t.boolean "mobilityrestrictedsuitability"
+ t.boolean "stairsavailability"
+ t.boolean "liftavailability"
+ t.integer "intuserneeds"
+ end
+ add_index "connectionlink", ["objectid"], :name => "connectionlink_objectid_key", :unique => true
+ end
+
+ def down
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 07dc4922d..7666b10bf 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20120425125542) do
+ActiveRecord::Schema.define(:version => 20120426141032) do
create_table "company", :force => true do |t|
t.string "objectid"
@@ -31,6 +31,29 @@ ActiveRecord::Schema.define(:version => 20120425125542) do
add_index "company", ["objectid"], :name => "company_objectid_key", :unique => true
add_index "company", ["registrationnumber"], :name => "company_registrationnumber_key", :unique => true
+ create_table "connectionlink", :force => true do |t|
+ t.integer "departureid", :limit => 8
+ t.integer "arrivalid", :limit => 8
+ t.string "objectid", :null => false
+ t.integer "objectversion"
+ t.datetime "creationtime"
+ t.string "creatorid"
+ t.string "name"
+ t.string "comment"
+ t.decimal "linkdistance", :precision => 19, :scale => 2
+ t.string "linktype"
+ t.time "defaultduration"
+ t.time "frequenttravellerduration"
+ t.time "occasionaltravellerduration"
+ t.time "mobilityrestrictedtravellerduration"
+ t.boolean "mobilityrestrictedsuitability"
+ t.boolean "stairsavailability"
+ t.boolean "liftavailability"
+ t.integer "intuserneeds"
+ end
+
+ add_index "connectionlink", ["objectid"], :name => "connectionlink_objectid_key", :unique => true
+
create_table "line", :force => true do |t|
t.integer "ptnetworkid", :limit => 8
t.integer "companyid", :limit => 8
diff --git a/spec/requests/connection_links_spec.rb b/spec/requests/connection_links_spec.rb
new file mode 100644
index 000000000..e137a330b
--- /dev/null
+++ b/spec/requests/connection_links_spec.rb
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*-
+require 'spec_helper'
+
+describe "ConnectionLinks" do
+ login_user
+
+ let!(:referential) { create(:referential).switch }
+ let!(:connection_links) { referential; Array.new(2) { create(:connection_link) } }
+ subject { connection_links.first }
+
+ describe "list" do
+ it "display connection_links" do
+ visit referential_connection_links_path(referential)
+ page.should have_content(connection_links.first.name)
+ page.should have_content(connection_links.last.name)
+ end
+
+ end
+
+ describe "show" do
+ it "display connection_link" do
+ visit referential_connection_links_path(referential)
+ click_link "#{connection_links.first.name}"
+ page.should have_content(connection_links.first.name)
+ end
+
+ it "display map" do
+ pending ": map not yet implemented"
+# subject.stub(:stop_areas).and_return(Array.new(2) { Factory(:stop_area) })
+# visit referential_connection_links_path(referential)
+# click_link "#{connection_links.first.name}"
+# page.should have_selector("#map", :class => 'connection_link')
+ end
+
+ end
+
+ describe "new" do
+ it "creates connection_link and return to show" do
+ visit referential_connection_links_path(referential)
+ click_link "Ajouter une correspondance"
+ fill_in "Nom", :with => "ConnectionLink 1"
+ fill_in "Identifiant Neptune", :with => "test:ConnectionLink:1"
+ click_button("Créer Correspondance")
+ page.should have_content("ConnectionLink 1")
+ end
+ end
+
+ describe "edit and return to show" do
+ it "edit connection_link" do
+ visit referential_connection_link_path(referential, subject)
+ click_link "Modifier cette correspondance"
+ fill_in "Nom", :with => "ConnectionLink Modified"
+ click_button("Modifier Correspondance")
+ page.should have_content("ConnectionLink Modified")
+ end
+ end
+
+end
diff --git a/spec/requests/time_tables_spec.rb b/spec/requests/time_tables_spec.rb
new file mode 100644
index 000000000..720370ead
--- /dev/null
+++ b/spec/requests/time_tables_spec.rb
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+require 'spec_helper'
+
+describe "TimeTables" do
+ login_user
+
+ let!(:referential) { create(:referential).switch }
+ let!(:time_tables) { referential; Array.new(2) { create(:time_table) } }
+ subject { time_tables.first }
+
+ describe "list" do
+ it "display time_tables" do
+ visit referential_time_tables_path(referential)
+ page.should have_content(time_tables.first.comment)
+ page.should have_content(time_tables.last.comment)
+ end
+
+ end
+
+ describe "show" do
+ it "display time_table" do
+ visit referential_time_tables_path(referential)
+ click_link "#{time_tables.first.comment}"
+ page.should have_content(time_tables.first.comment)
+ end
+
+ end
+
+ describe "new" do
+ it "creates time_table and return to show" do
+ visit referential_time_tables_path(referential)
+ click_link "Ajouter un calendrier"
+ fill_in "Description", :with => "TimeTable 1"
+ fill_in "Identifiant Neptune", :with => "test:Timetable:1"
+ click_button("Créer Calendrier")
+ page.should have_content("TimeTable 1")
+ end
+ end
+
+ describe "edit and return to show" do
+ it "edit time_table" do
+ visit referential_time_table_path(referential, subject)
+ click_link "Modifier ce calendrier"
+ fill_in "Description", :with => "TimeTable Modified"
+ click_button("Modifier Calendrier")
+ page.should have_content("TimeTable Modified")
+ end
+ end
+
+end
diff --git a/spec/views/connection_links/edit.html.erb_spec.rb b/spec/views/connection_links/edit.html.erb_spec.rb
new file mode 100644
index 000000000..331529ff8
--- /dev/null
+++ b/spec/views/connection_links/edit.html.erb_spec.rb
@@ -0,0 +1,24 @@
+require 'spec_helper'
+
+describe "/connection_links/edit" do
+ let!(:referential) { assign(:referential, create(:referential)) }
+ let!(:connection_link) { assign(:connection_link, create(:connection_link)) }
+ let!(:connection_links) { Array.new(2) { create(:connection_link) } }
+
+ describe "test" do
+ it "should render h2 with the connection_link name" do
+ render
+ rendered.should have_selector("h2", :text => Regexp.new(connection_link.name))
+ end
+ end
+
+ describe "form" do
+ it "should render input for name" do
+ render
+ rendered.should have_selector("form") do
+ with_tag "input[type=text][name='connection_link[name]'][value=?]", connection_link.name
+ end
+ end
+ end
+
+end
diff --git a/spec/views/connection_links/index.html.erb_spec.rb b/spec/views/connection_links/index.html.erb_spec.rb
new file mode 100644
index 000000000..9732c16c5
--- /dev/null
+++ b/spec/views/connection_links/index.html.erb_spec.rb
@@ -0,0 +1,21 @@
+require 'spec_helper'
+
+describe "/connection_links/index" do
+
+ let!(:referential) { assign( :referential, create(:referential) ) }
+ let!(:connection_links) { assign :connection_links, Array.new(2) { create(:connection_link) }.paginate }
+ let!(:search) { assign :q, Ransack::Search.new(Chouette::ConnectionLink) }
+
+ it "should render a show link for each group" do
+ render
+ connection_links.each do |connection_link|
+ rendered.should have_selector(".connection_link a[href='#{view.referential_connection_link_path(referential, connection_link)}']", :text => connection_link.name)
+ end
+ end
+
+ it "should render a link to create a new group" do
+ render
+ view.content_for(:sidebar).should have_selector(".actions a[href='#{new_referential_connection_link_path(referential)}']")
+ end
+
+end
diff --git a/spec/views/connection_links/new.html.erb_spec.rb b/spec/views/connection_links/new.html.erb_spec.rb
new file mode 100644
index 000000000..1e9ee570d
--- /dev/null
+++ b/spec/views/connection_links/new.html.erb_spec.rb
@@ -0,0 +1,17 @@
+require 'spec_helper'
+
+describe "/connection_links/new" do
+ let!(:referential) { assign(:referential, create(:referential)) }
+ let!(:connection_link) { assign(:connection_link, build(:connection_link)) }
+
+ describe "form" do
+
+ it "should render input for name" do
+ render
+ rendered.should have_selector("form") do
+ with_selector "input[type=text][name=?]", connection_link.name
+ end
+ end
+
+ end
+end
diff --git a/spec/views/connection_links/show.html.erb_spec.rb b/spec/views/connection_links/show.html.erb_spec.rb
new file mode 100644
index 000000000..bc8d075cf
--- /dev/null
+++ b/spec/views/connection_links/show.html.erb_spec.rb
@@ -0,0 +1,30 @@
+require 'spec_helper'
+
+describe "/connection_links/show" do
+
+ let!(:referential) { assign(:referential, create(:referential)) }
+ let!(:connection_link) { assign(:connection_link, create(:connection_link)) }
+
+ it "should render h2 with the connection_link name" do
+ render
+ rendered.should have_selector("h2", :text => Regexp.new(connection_link.name))
+ end
+
+ it "should display a map with class 'connection_link'" do
+ pending ": map not yet implemented"
+ # render
+ # rendered.should have_selector("#map", :class => 'connection_link')
+ end
+
+ it "should render a link to edit the connection_link" do
+ render
+ view.content_for(:sidebar).should have_selector(".actions a[href='#{view.edit_referential_connection_link_path(referential, connection_link)}']")
+ end
+
+ it "should render a link to remove the connection_link" do
+ render
+ view.content_for(:sidebar).should have_selector(".actions a[href='#{view.referential_connection_link_path(referential, connection_link)}'][class='remove']")
+ end
+
+end
+
diff --git a/spec/views/time_tables/edit.html.erb_spec.rb b/spec/views/time_tables/edit.html.erb_spec.rb
new file mode 100644
index 000000000..6baf741fc
--- /dev/null
+++ b/spec/views/time_tables/edit.html.erb_spec.rb
@@ -0,0 +1,23 @@
+require 'spec_helper'
+
+describe "/time_tables/edit" do
+ let!(:referential) { assign(:referential, create(:referential)) }
+ let!(:time_table) { assign(:time_table, create(:time_table) ) }
+
+ describe "test" do
+ it "should render h2 with the group comment" do
+ render
+ rendered.should have_selector("h2", :text => Regexp.new(time_table.comment))
+ end
+ end
+
+ describe "form" do
+ it "should render input for comment" do
+ render
+ rendered.should have_selector("form") do
+ with_tag "input[type=text][comment='time_table[comment]'][value=?]", time_table.comment
+ end
+ end
+
+ end
+end
diff --git a/spec/views/time_tables/index.html.erb_spec.rb b/spec/views/time_tables/index.html.erb_spec.rb
new file mode 100644
index 000000000..7d56ad982
--- /dev/null
+++ b/spec/views/time_tables/index.html.erb_spec.rb
@@ -0,0 +1,21 @@
+require 'spec_helper'
+
+describe "/time_tables/index" do
+
+ let!(:referential) { assign :referential, create(:referential) }
+ let!(:time_tables) { assign :time_tables, Array.new(2){ create(:time_table) }.paginate }
+ let!(:search) { assign :q, Ransack::Search.new(Chouette::TimeTable) }
+
+ it "should render a show link for each group" do
+ render
+ time_tables.each do |time_table|
+ rendered.should have_selector(".time_table a[href='#{view.referential_time_table_path(referential, time_table)}']", :text => time_table.comment)
+ end
+ end
+
+ it "should render a link to create a new group" do
+ render
+ view.content_for(:sidebar).should have_selector(".actions a[href='#{new_referential_time_table_path(referential)}']")
+ end
+
+end
diff --git a/spec/views/time_tables/new.html.erb_spec.rb b/spec/views/time_tables/new.html.erb_spec.rb
new file mode 100644
index 000000000..dd7a35b3b
--- /dev/null
+++ b/spec/views/time_tables/new.html.erb_spec.rb
@@ -0,0 +1,17 @@
+require 'spec_helper'
+
+describe "/time_tables/new" do
+ let!(:referential) { assign(:referential, create(:referential)) }
+ let!(:time_table) { assign(:time_table, build(:time_table)) }
+
+ describe "form" do
+
+ it "should render input for comment" do
+ render
+ rendered.should have_selector("form") do
+ with_selector "input[type=text][comment=?]", time_table.comment
+ end
+ end
+
+ end
+end
diff --git a/spec/views/time_tables/show.html.erb_spec.rb b/spec/views/time_tables/show.html.erb_spec.rb
new file mode 100644
index 000000000..056919b2b
--- /dev/null
+++ b/spec/views/time_tables/show.html.erb_spec.rb
@@ -0,0 +1,24 @@
+require 'spec_helper'
+
+describe "/time_tables/show" do
+
+ let!(:referential) { assign(:referential, create(:referential)) }
+ let!(:time_table) { assign(:time_table, create(:time_table)) }
+
+ it "should render h2 with the time_table comment" do
+ render
+ rendered.should have_selector("h2", :text => Regexp.new(time_table.comment))
+ end
+
+ it "should render a link to edit the time_table" do
+ render
+ view.content_for(:sidebar).should have_selector(".actions a[href='#{view.edit_referential_time_table_path(referential, time_table)}']")
+ end
+
+ it "should render a link to remove the time_table" do
+ render
+ view.content_for(:sidebar).should have_selector(".actions a[href='#{view.referential_time_table_path(referential, time_table)}'][class='remove']")
+ end
+
+end
+
diff --git a/vendor/assets/stylesheets/images/ui-bg_flat_0_aaaaaa_40x100.png b/vendor/assets/stylesheets/images/ui-bg_flat_0_aaaaaa_40x100.png
new file mode 100644
index 000000000..5b5dab2ab
--- /dev/null
+++ b/vendor/assets/stylesheets/images/ui-bg_flat_0_aaaaaa_40x100.png
Binary files differ
diff --git a/vendor/assets/stylesheets/images/ui-bg_glass_55_fbf9ee_1x400.png b/vendor/assets/stylesheets/images/ui-bg_glass_55_fbf9ee_1x400.png
new file mode 100644
index 000000000..ad3d6346e
--- /dev/null
+++ b/vendor/assets/stylesheets/images/ui-bg_glass_55_fbf9ee_1x400.png
Binary files differ
diff --git a/vendor/assets/stylesheets/images/ui-bg_glass_65_ffffff_1x400.png b/vendor/assets/stylesheets/images/ui-bg_glass_65_ffffff_1x400.png
new file mode 100644
index 000000000..42ccba269
--- /dev/null
+++ b/vendor/assets/stylesheets/images/ui-bg_glass_65_ffffff_1x400.png
Binary files differ
diff --git a/vendor/assets/stylesheets/images/ui-bg_glass_75_dadada_1x400.png b/vendor/assets/stylesheets/images/ui-bg_glass_75_dadada_1x400.png
new file mode 100644
index 000000000..5a46b47cb
--- /dev/null
+++ b/vendor/assets/stylesheets/images/ui-bg_glass_75_dadada_1x400.png
Binary files differ
diff --git a/vendor/assets/stylesheets/images/ui-bg_glass_75_e6e6e6_1x400.png b/vendor/assets/stylesheets/images/ui-bg_glass_75_e6e6e6_1x400.png
new file mode 100644
index 000000000..86c2baa65
--- /dev/null
+++ b/vendor/assets/stylesheets/images/ui-bg_glass_75_e6e6e6_1x400.png
Binary files differ
diff --git a/vendor/assets/stylesheets/images/ui-bg_glass_75_ffffff_1x400.png b/vendor/assets/stylesheets/images/ui-bg_glass_75_ffffff_1x400.png
new file mode 100644
index 000000000..e65ca1297
--- /dev/null
+++ b/vendor/assets/stylesheets/images/ui-bg_glass_75_ffffff_1x400.png
Binary files differ
diff --git a/vendor/assets/stylesheets/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/vendor/assets/stylesheets/images/ui-bg_highlight-soft_75_cccccc_1x100.png
new file mode 100644
index 000000000..7c9fa6c6e
--- /dev/null
+++ b/vendor/assets/stylesheets/images/ui-bg_highlight-soft_75_cccccc_1x100.png
Binary files differ
diff --git a/vendor/assets/stylesheets/images/ui-bg_inset-soft_95_fef1ec_1x100.png b/vendor/assets/stylesheets/images/ui-bg_inset-soft_95_fef1ec_1x100.png
new file mode 100644
index 000000000..0e05810ff
--- /dev/null
+++ b/vendor/assets/stylesheets/images/ui-bg_inset-soft_95_fef1ec_1x100.png
Binary files differ
diff --git a/vendor/assets/stylesheets/images/ui-icons_222222_256x240.png b/vendor/assets/stylesheets/images/ui-icons_222222_256x240.png
new file mode 100644
index 000000000..b273ff111
--- /dev/null
+++ b/vendor/assets/stylesheets/images/ui-icons_222222_256x240.png
Binary files differ
diff --git a/vendor/assets/stylesheets/images/ui-icons_2e83ff_256x240.png b/vendor/assets/stylesheets/images/ui-icons_2e83ff_256x240.png
new file mode 100644
index 000000000..09d1cdc85
--- /dev/null
+++ b/vendor/assets/stylesheets/images/ui-icons_2e83ff_256x240.png
Binary files differ
diff --git a/vendor/assets/stylesheets/images/ui-icons_454545_256x240.png b/vendor/assets/stylesheets/images/ui-icons_454545_256x240.png
new file mode 100644
index 000000000..59bd45b90
--- /dev/null
+++ b/vendor/assets/stylesheets/images/ui-icons_454545_256x240.png
Binary files differ
diff --git a/vendor/assets/stylesheets/images/ui-icons_888888_256x240.png b/vendor/assets/stylesheets/images/ui-icons_888888_256x240.png
new file mode 100644
index 000000000..6d02426c1
--- /dev/null
+++ b/vendor/assets/stylesheets/images/ui-icons_888888_256x240.png
Binary files differ
diff --git a/vendor/assets/stylesheets/images/ui-icons_cd0a0a_256x240.png b/vendor/assets/stylesheets/images/ui-icons_cd0a0a_256x240.png
new file mode 100644
index 000000000..2ab019b73
--- /dev/null
+++ b/vendor/assets/stylesheets/images/ui-icons_cd0a0a_256x240.png
Binary files differ
diff --git a/vendor/assets/stylesheets/jquery-ui.css b/vendor/assets/stylesheets/jquery-ui.css
new file mode 100644
index 000000000..9a5a29c86
--- /dev/null
+++ b/vendor/assets/stylesheets/jquery-ui.css
@@ -0,0 +1,565 @@
+/*!
+ * jQuery UI CSS Framework 1.8.19
+ *
+ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
+.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; }
+.ui-helper-clearfix:after { clear: both; }
+.ui-helper-clearfix { zoom: 1; }
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+
+
+/*!
+ * jQuery UI CSS Framework 1.8.19
+ *
+ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ *
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ctl=themeroller
+ */
+
+
+/* Component containers
+----------------------------------*/
+.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; }
+.ui-widget .ui-widget { font-size: 1em; }
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; }
+.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_75_ffffff_1x400.png) 50% 50% repeat-x; color: #222222; }
+.ui-widget-content a { color: #222222; }
+.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; }
+.ui-widget-header a { color: #222222; }
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; }
+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
+.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; }
+.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; }
+.ui-widget :active { outline: none; }
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; }
+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
+.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_inset-soft_95_fef1ec_1x100.png) 50% bottom repeat-x; color: #cd0a0a; }
+.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
+.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
+.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-off { background-position: -96px -144px; }
+.ui-icon-radio-on { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; }
+.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; }
+.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
+.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+
+/* Overlays */
+.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
+.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*!
+ * jQuery UI Resizable 1.8.19
+ *
+ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Resizable#theming
+ */
+.ui-resizable { position: relative;}
+.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; }
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*!
+ * jQuery UI Selectable 1.8.19
+ *
+ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Selectable#theming
+ */
+.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
+/*!
+ * jQuery UI Accordion 1.8.19
+ *
+ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Accordion#theming
+ */
+/* IE/Win - Fix animation bug - #4615 */
+.ui-accordion { width: 100%; }
+.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
+.ui-accordion .ui-accordion-li-fix { display: inline; }
+.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
+.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }
+.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
+.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
+.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }
+.ui-accordion .ui-accordion-content-active { display: block; }
+/*!
+ * jQuery UI Autocomplete 1.8.19
+ *
+ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Autocomplete#theming
+ */
+.ui-autocomplete { position: absolute; cursor: default; }
+
+/* workarounds */
+* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
+
+/*
+ * jQuery UI Menu @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Menu#theming
+ */
+.ui-menu {
+ list-style:none;
+ padding: 2px;
+ margin: 0;
+ display:block;
+ float: left;
+}
+.ui-menu .ui-menu {
+ margin-top: -3px;
+}
+.ui-menu .ui-menu-item {
+ margin:0;
+ padding: 0;
+ zoom: 1;
+ float: left;
+ clear: left;
+ width: 100%;
+}
+.ui-menu .ui-menu-item a {
+ text-decoration:none;
+ display:block;
+ padding:.2em .4em;
+ line-height:1.5;
+ zoom:1;
+}
+.ui-menu .ui-menu-item a.ui-state-hover,
+.ui-menu .ui-menu-item a.ui-state-active {
+ font-weight: normal;
+ margin: -1px;
+}
+/*!
+ * jQuery UI Button 1.8.19
+ *
+ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Button#theming
+ */
+.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
+.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
+button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
+.ui-button-icons-only { width: 3.4em; }
+button.ui-button-icons-only { width: 3.7em; }
+
+/*button text element */
+.ui-button .ui-button-text { display: block; line-height: 1.4; }
+.ui-button-text-only .ui-button-text { padding: .4em 1em; }
+.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
+.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
+.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
+.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
+/* no icon support for input elements, provide padding by default */
+input.ui-button { padding: .4em 1em; }
+
+/*button icon element(s) */
+.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
+.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
+.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
+.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+
+/*button sets*/
+.ui-buttonset { margin-right: 7px; }
+.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
+
+/* workarounds */
+button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
+/*!
+ * jQuery UI Dialog 1.8.19
+ *
+ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Dialog#theming
+ */
+.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
+.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; }
+.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }
+.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
+.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
+.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
+.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
+.ui-draggable .ui-dialog-titlebar { cursor: move; }
+/*!
+ * jQuery UI Slider 1.8.19
+ *
+ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Slider#theming
+ */
+.ui-slider { position: relative; text-align: left; }
+.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
+.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
+
+.ui-slider-horizontal { height: .8em; }
+.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
+.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
+.ui-slider-horizontal .ui-slider-range-min { left: 0; }
+.ui-slider-horizontal .ui-slider-range-max { right: 0; }
+
+.ui-slider-vertical { width: .8em; height: 100px; }
+.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
+.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
+.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
+.ui-slider-vertical .ui-slider-range-max { top: 0; }/*!
+ * jQuery UI Tabs 1.8.19
+ *
+ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Tabs#theming
+ */
+.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
+.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
+.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
+.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
+.ui-tabs .ui-tabs-hide { display: none !important; }
+/*!
+ * jQuery UI Datepicker 1.8.19
+ *
+ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Datepicker#theming
+ */
+.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
+.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
+.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
+.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
+.ui-datepicker .ui-datepicker-prev { left:2px; }
+.ui-datepicker .ui-datepicker-next { right:2px; }
+.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
+.ui-datepicker .ui-datepicker-next-hover { right:1px; }
+.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
+.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
+.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
+.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year { width: 49%;}
+.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
+.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
+.ui-datepicker td { border: 0; padding: 1px; }
+.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
+.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
+.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi { width:auto; }
+.ui-datepicker-multi .ui-datepicker-group { float:left; }
+.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
+.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
+.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
+.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
+.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; }
+
+/* RTL support */
+.ui-datepicker-rtl { direction: rtl; }
+.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+
+/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
+.ui-datepicker-cover {
+ display: none; /*sorry for IE5*/
+ display/**/: block; /*sorry for IE5*/
+ position: absolute; /*must have*/
+ z-index: -1; /*must have*/
+ filter: mask(); /*must have*/
+ top: -4px; /*must have*/
+ left: -4px; /*must have*/
+ width: 200px; /*must have*/
+ height: 200px; /*must have*/
+}/*!
+ * jQuery UI Progressbar 1.8.19
+ *
+ * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Progressbar#theming
+ */
+.ui-progressbar { height:2em; text-align: left; overflow: hidden; }
+.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file