Compare commits

...

44 Commits

Author SHA1 Message Date
Paul van Tilburg 8af4d4d148
Don't use UTF-8 dots in the header 2021-10-02 17:10:23 +02:00
Paul van Tilburg 39949606e5
Switch to Nokogiri 1.12.5 (addresses CVE-2021-41098) 2021-10-02 17:05:51 +02:00
Paul van Tilburg 0e74472983
Bundle update 2021-09-27 16:25:06 +02:00
Paul van Tilburg 9ba33c9b71
Switch to our own Git master of the camping gem 2021-09-27 16:08:59 +02:00
Paul van Tilburg 975ab31440 Switch to Nokogiri 1.10.4 (addresses CVE-2019-5477) 2019-08-21 19:40:08 +02:00
Paul van Tilburg 8e6fcddd49 Use Bundler in config.ru 2019-06-08 12:09:03 +02:00
Paul van Tilburg 6b7d96ecb9 Add a Gemfile that locks Camping back in time
Camping development has stalled for a few years now.
Use the Gemfile to help bundle create an environment in which it still
works, which is basically: Camping Git master plus
ActiveSupport/ActionView 4.2.
2019-06-08 12:09:01 +02:00
Paul van Tilburg 819fb5f530 Add comments to the gitignore 2019-06-08 12:08:58 +02:00
Paul van Tilburg f4c34d8e4e Fix some code wrapping; remove trailing whitespace 2019-03-31 00:12:07 +01:00
Paul van Tilburg 825387cc6f Merge tag 'v1.17.1' into development
Release 1.17.1
2018-10-15 19:59:12 +02:00
Paul van Tilburg 9d48c1ac6b Merge branch 'release/1.17.1' 2018-10-15 19:58:48 +02:00
Paul van Tilburg c5f6808e6b Update the changelog 2018-10-15 19:50:40 +02:00
Paul van Tilburg f6a412f9be Bump the version to 1.17.1 2018-10-15 19:49:38 +02:00
Paul van Tilburg d89f9ac65b Redirect to the customer after editing it
All other edit/forms redirect to the same page, why not this one?
2018-10-15 19:43:27 +02:00
Paul van Tilburg 157af0c2c3 Make the default hourly rate input field also a number field 2018-10-15 19:42:24 +02:00
Paul van Tilburg fa6aa24e0d Set minimal and step attributes for (currency) number input fields
If the step attribute not set, the default step is set to 0.50, which is
inconvient since it is also used for validation, i.e. if you have 35.50 in
the field, the only surrounding values 36.0 and 35.0 are valid, not 35.60.
2018-10-15 19:40:28 +02:00
Paul van Tilburg 548dfe22cc Update the changelog for the 0.17.0 release 2016-09-11 15:21:00 +02:00
Paul van Tilburg 1f955f55a6 Merge tag 'v1.17.0' into development
Release 1.17.0
2016-09-11 15:10:10 +02:00
Paul van Tilburg f04956cdcb Merge branch 'release/1.17.0' 2016-09-11 15:10:03 +02:00
Paul van Tilburg 9585515565 Bump bump to 1.17.0 2016-09-11 15:10:01 +02:00
Paul van Tilburg cb215e54eb Ensure that only time entries with tasks are selected (closes: #89c2a1)
Time entries without tasks shouldn't exist/be possible though.
2016-09-11 15:09:14 +02:00
Paul van Tilburg 7184248ccd Fix the last company info is used-check 2016-03-06 15:01:14 +01:00
Paul van Tilburg bbf2566352 Use #dup to copy models
Since we require ActiveRecord >= 3.2, #dup should be used,
not #clone (which is <= 3.1).
2016-03-06 14:59:59 +01:00
Paul van Tilburg 7c41c32dfd Add documentation for the #date_time_new_entry helper method 2016-03-06 12:17:46 +01:00
Paul van Tilburg 49bfdff822 Add support for choosing what date/time is used for new entries 2016-02-26 23:12:36 +01:00
Paul van Tilburg 81e6db24ef Fix wrong CSS class name 2015-12-17 09:41:58 +01:00
Paul van Tilburg faf95f842e Small textual tweak 2015-12-15 12:46:27 +01:00
Paul van Tilburg a2e021a6c6 Merge tag 'v1.16.1' into development
Release 1.16.1
2015-07-11 21:51:14 +02:00
Paul van Tilburg ce2ebc76d4 Merge branch 'release/1.16.1' 2015-07-11 21:51:07 +02:00
Paul van Tilburg 8c15c2f318 Update the changelog for the 1.16.1 release 2015-07-11 21:51:02 +02:00
Paul van Tilburg 1376ac3828 Bump version to 1.16.1 2015-07-11 21:48:40 +02:00
Paul van Tilburg f5d2c5af08 Rename the time entry filter param 2015-07-11 21:42:02 +02:00
Paul van Tilburg 1e33df19d6 Small Sass reformatting 2015-07-11 21:39:41 +02:00
Paul van Tilburg ebd220aac6 Also add missing subtitle in the invoice form 2015-07-11 21:38:29 +02:00
Paul van Tilburg 5160e79953 Actually count and show the active projects/tasks in the overview 2015-07-11 21:29:35 +02:00
Paul van Tilburg 23af29b800 Add missing subtitle on the customers view 2015-07-11 21:29:09 +02:00
Paul van Tilburg 58ec60ab60 Add an anchor for timelines
Also expand the customer timeline table row to have full width.
2015-07-11 21:23:51 +02:00
Paul van Tilburg 16b13de52c Reduce the padding in form controls 2015-07-11 21:23:28 +02:00
Paul van Tilburg 1cf130c1dd Tweaked some form grid column widths 2015-07-11 21:23:19 +02:00
Paul van Tilburg 7ecece3950 Shorten some button labels 2015-07-11 21:21:33 +02:00
Paul van Tilburg 4eef4669a5 Only show unbilled time in the customer form
Done so that it is the same as in the task form.
Also the list of all time entries for a customer can be very long,
thus creating a long load time of the customer form.
2015-07-11 21:20:18 +02:00
Paul van Tilburg 43b9c1336f Move the customers table into a more narrow row 2015-06-20 23:30:56 +02:00
Paul van Tilburg ad4362f471 Allow for forward navigation through the company info versions in the view 2015-06-20 23:30:02 +02:00
Paul van Tilburg c15f6c4e2e Merge tag 'v1.16.0' into development
Release 1.16.0
2015-06-20 22:06:51 +02:00
10 changed files with 313 additions and 101 deletions

21
.gitignore vendored
View File

@ -1,11 +1,32 @@
# Ignore bundler config
/.bundle
# Ignore bundler installation
/vendor/bundle
# Ignore SASS and YARD cache
.sass-cache
.yardoc
# Ignore the local configuration
config.yaml
htpasswd
# Ignore the SQLite databases
db/*
# Ignore generated documentation
doc/*
# Ignore generated invoice assets
public/invoices/*
# Ignore compiled asssets
public/stylesheets/style.css
public/stylesheets/style.css.map
# Ignore custom invoice templates
templates/*_invoice.tex.erb
# Ignore temporary files
tmp/*

1
.ruby-version Normal file
View File

@ -0,0 +1 @@
2.5.1

View File

@ -1,5 +1,33 @@
= Stop… Camping Time! release news
== 1.17.1
Bugfixes:
* Fix the number/currency input to allow for all values ≥ 0.00
== 1.17.0
Features:
* Add support for choosing what date/time is used for new entries
* Some textual and style tweaks
Bugfixes:
* Fix crash when showing all entries in the timeline [#89c2a1]
Other bugfixes:
* Fix check that determines if last company info is used
== 1.16.1
Features:
* Allow back/forth navigation through company info version
* Only show unbilled time in the customer from (load time improvement!)
* Tweaked some form input sizes
* Add missing view subtitles
== 1.16.0
Features:

18
Gemfile Normal file
View File

@ -0,0 +1,18 @@
source "http://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
# This application is build on Camping, use it from our own Git master
gem "camping", github: "paulvt/camping", branch: "master"
# Use ActionView for the templates.
gem "actionview", "~> 4.2.10"
# Use ActiveRecord as the ORM.
gem "activerecord", "~> 4.2.10"
# Use SASS for handling CSS assets/Bootstrap.
gem "sass", "~> 3.4.6"
# Use SQLite as the database.
gem "sqlite3", "~> 1.3.9"

74
Gemfile.lock Normal file
View File

@ -0,0 +1,74 @@
GIT
remote: https://github.com/paulvt/camping.git
revision: e6834563b244e0f24af2034d679cd6e8e9d932c0
branch: master
specs:
camping (2.1.602)
mab (>= 0.0.3)
rack (>= 1.0)
GEM
remote: http://rubygems.org/
specs:
actionview (4.2.11.3)
activesupport (= 4.2.11.3)
builder (~> 3.1)
erubis (~> 2.7.0)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.3)
activemodel (4.2.11.3)
activesupport (= 4.2.11.3)
builder (~> 3.1)
activerecord (4.2.11.3)
activemodel (= 4.2.11.3)
activesupport (= 4.2.11.3)
arel (~> 6.0)
activesupport (4.2.11.3)
i18n (~> 0.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
arel (6.0.4)
builder (3.2.4)
concurrent-ruby (1.1.9)
crass (1.0.6)
erubis (2.7.0)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
loofah (2.12.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mab (0.0.3)
mini_portile2 (2.6.1)
minitest (5.14.4)
nokogiri (1.12.5)
mini_portile2 (~> 2.6.1)
racc (~> 1.4)
racc (1.5.2)
rack (2.2.3)
rails-deprecated_sanitizer (1.0.4)
activesupport (>= 4.2.0.alpha)
rails-dom-testing (1.0.9)
activesupport (>= 4.2.0, < 5.0)
nokogiri (~> 1.6)
rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.4.2)
loofah (~> 2.3)
sass (3.4.25)
sqlite3 (1.3.13)
thread_safe (0.3.6)
tzinfo (1.2.9)
thread_safe (~> 0.1)
PLATFORMS
ruby
DEPENDENCIES
actionview (~> 4.2.10)
activerecord (~> 4.2.10)
camping!
sass (~> 3.4.6)
sqlite3 (~> 1.3.9)
BUNDLED WITH
1.17.3

View File

@ -39,6 +39,9 @@ and the following LaTeX programs:
* isodoc package (>= 1.00)
* rubber
It is also possible to use Bundler (which is the default when using
@config.ru@), in this you only need Ruby and Bundler installed.
== Installation
For now, Stop… Camping Time! is in a developing state and not ready for

View File

@ -1,9 +1,10 @@
#!/usr/bin/env rackup
require "bundler/setup"
require "./stoptime"
StopTime::Models::Base.establish_connection( :adapter => 'sqlite3',
:database => 'db/stoptime.db',
:timeout => 10000 )
StopTime::Models::Base.establish_connection(adapter: "sqlite3",
database: "db/stoptime.db",
timeout: 10000)
StopTime.create
run StopTime

View File

@ -3,6 +3,10 @@
# Time resolution in minutes
#time_resolution: 1
# Which date to use for new entries
# Supported values are: previous, today, none
#date_new_entry: today
# The default hourly rate
#hourly_rate: 20.0

View File

@ -55,7 +55,7 @@ end
module StopTime
# The version of the application
VERSION = '1.16.0'
VERSION = '1.17.1'
puts "Starting Stop… Camping Time! version #{VERSION}"
# @return [Hash{String=>Object}] The parsed configuration.
@ -166,6 +166,7 @@ module StopTime::Models
"invoice_template" => "invoice",
"hourly_rate" => 20.0,
"time_resolution" => 1,
"date_new_entry" => "today",
"vat_rate" => 21.0 }
# Creates a new configuration object and loads the configuation.
@ -888,6 +889,30 @@ module StopTime::Models
end # StopTime::Models
# = The Stop… Camping Time! helpers
module StopTime::Helpers
# Returns the date/time to use for new time entry defaults, or +nil+ if
# none is to be used. This method can use the last time entry (if any
# and if so configured). The result is based on the +date_new_entry+
# configuration option.
#
# @param last_entry [DateTime] the last time entry to use if configured
# for "previous"
# @return [DateTime, nil] the date/time to be used for new entry defaults
def date_time_new_entry(last_entry = nil)
case @config["date_new_entry"]
when "previous"
TimeEntry.last.end
when "today"
DateTime.now
when "none"
nil
end
end
end
# = The Stop… Camping Time! controllers
module StopTime::Controllers
@ -905,6 +930,7 @@ module StopTime::Controllers
@tasks = {}
@task_count = 0
@active_tasks = {}
@active_task_count = 0
@active_tasks_summary = {}
@totals = [0.0, 0,0]
Customer.all.each do |customer|
@ -913,6 +939,7 @@ module StopTime::Controllers
@task_count += tasks.count
active_tasks = customer.active_tasks
@active_tasks[customer] = active_tasks
@active_task_count += active_tasks.count
@active_tasks_summary[customer] =
active_tasks.inject([0.0, 0.0]) do |summ, task|
task_summ = task.summary
@ -1025,7 +1052,8 @@ module StopTime::Controllers
end
end
@time_entries = @customer.time_entries.order("start DESC")
@time_entries = @customer.time_entries.order("start DESC")\
.reject { |te| te.task.billed? }
@invoices = @customer.invoices
@invoices.each do |i|
@input["paid_#{i.number}"] = true if i.paid?
@ -1069,7 +1097,7 @@ module StopTime::Controllers
return render :customer_form
end
end
redirect R(Customers)
redirect R(CustomersN, customer_id)
end
end # class StopTime::Controllers::CustomersN
@ -1278,7 +1306,7 @@ module StopTime::Controllers
tasks.each_key do |task|
# Create a new (billed) task clone that contains the selected time
# entries, leave the rest unbilled and associated with their task.
bill_task = task.dup # FIXME: depends on rails version!
bill_task = task.dup
task.time_entries = task.time_entries - tasks[task]
task.save
bill_task.time_entries = tasks[task]
@ -1485,13 +1513,14 @@ module StopTime::Controllers
# Retrieves all registered time in descending order to present
# the timeline using {Views#timeline}.
def get
if @input["show"] == "all"
if @input["time_entries"] == "all"
@time_entries = TimeEntry.order("start DESC")
else
@time_entries = TimeEntry.joins(:task)\
.where("stoptime_tasks.invoice_id" => nil)\
.order("start DESC")
end
@time_entries = @time_entries.where.not(task_id: nil)
@time_entries.each do |te|
@input["bill_#{te.id}"] = true if te.bill?
end
@ -1547,9 +1576,11 @@ module StopTime::Controllers
@task_list[t.customer.shortest_name] << [t.id, t.name]
end
@input["bill"] = true
@input["date"] = DateTime.now.to_date
@input["start"] = Time.now.to_formatted_s(:time_only)
date_time_new = date_time_new_entry(TimeEntry.last)
if date_time_new
@input["date"] = date_time_new.to_date.to_formatted_s
@input["start"] = date_time_new.to_formatted_s(:time_only)
end
@target = [Timeline]
@button = "enter"
render :time_entry_form
@ -1679,6 +1710,7 @@ module StopTime::Controllers
else
CompanyInfo.last
end
@company_last = @company == CompanyInfo.last
@input = @company.attributes
@history_warn = true if @company != CompanyInfo.last
render :company_form
@ -1696,9 +1728,9 @@ module StopTime::Controllers
# If we are editing the current info and it is already associated
# with some invoices, create a new revision.
@history_warn = true if @company != CompanyInfo.last
if @company == CompanyInfo.last and @company.invoices.length > 0
if @company.id == CompanyInfo.last.id and @company.invoices.length > 0
old_company = @company
@company = old_company.clone # FIXME: depends on rails version!
@company = old_company.dup
@company.original = old_company
end
@ -1798,7 +1830,8 @@ module StopTime::Views
header.page_header do
h1 do
text! "Overview"
small "#{@tasks.count} customers, #{@task_count} active projects/tasks"
small "#{@tasks.count} customers, " +
"#{@active_task_count} active projects/tasks"
end
end
if @tasks.empty?
@ -1829,7 +1862,7 @@ module StopTime::Views
elsif @active_tasks[customer].empty?
p do
em "No active projects/tasks found! " +
"Register time on one of these tasks: "
"Register time on one of these projects/tasks: "
br
@tasks[customer].each do |task|
a task.name, href: R(CustomersNTasksN, customer.id, task.id)
@ -1900,12 +1933,12 @@ module StopTime::Views
a.btn.btn_default.btn_sm.dropdown_toggle role: "button", href: "#",
data_toggle: "dropdown" do
_icon("filter")
text! @input["show"] == "all" ? "All" : "Unbilled"
text! @input["time_entries"] == "all" ? "All" : "Unbilled"
span.caret
end
ul.dropdown_menu role: "menu", aria_labelledby: "dLabel" do
li { a "All", href: R(Timeline, show: "all") }
li { a "Unbilled", href: R(Timeline, show: "unbilled") }
li { a "All", href: R(Timeline, time_entries: "all") }
li { a "Unbilled", href: R(Timeline, time_entries: "unbilled") }
end
end
end
@ -2014,10 +2047,11 @@ module StopTime::Views
header.page_header do
h1 do
text! "Customers"
small "#{@customers.count} customers"
div.btn_group.navbar_right do
a.btn.btn_default.btn_sm role: "button", href: R(CustomersNew) do
_icon("plus")
span "Add new customer"
span "Add customer"
end
end
end
@ -2028,59 +2062,63 @@ module StopTime::Views
"#{a "here", href: R(CustomersNew)}."
end
else
table.table.table_striped.table_condensed do
thead do
tr do
th.col_md_2.col_xs_5 "Name"
th.col_md_1.hidden_xs "Short name"
th.col_md_4.col_xs_5 "Address"
th.col_md_2.hidden_xs "Email"
th.col_md_2.hidden_xs "Phone"
th.col_md_1.col_xs_2 {}
end
end
tbody do
@customers.each do |customer|
tr do
td { a customer.name, href: R(CustomersN, customer.id) }
td.hidden_xs { customer.short_name || ""}
td do
if customer.address_street.present?
text! customer.address_street
br
text! customer.address_postal_code + "&nbsp;" +
customer.address_city
if customer.email.present?
a.visible_xs customer.email,
href: "mailto:#{customer.email}"
div.row do
div.col_md_9.col_xs_12 do
table.table.table_striped.table_condensed do
thead do
tr do
th.col_md_2.col_xs_5 "Name"
th.col_md_2.hidden_xs "Short name"
th.col_md_3.col_xs_5 "Address"
th.col_md_2.hidden_xs "Email"
th.col_md_2.hidden_xs "Phone"
th.col_md_1.col_xs_2 {}
end
end
tbody do
@customers.each do |customer|
tr do
td { a customer.name, href: R(CustomersN, customer.id) }
td.hidden_xs { customer.short_name || ""}
td do
if customer.address_street.present?
text! customer.address_street
br
text! customer.address_postal_code + "&nbsp;" +
customer.address_city
if customer.email.present?
a.visible_xs customer.email,
href: "mailto:#{customer.email}"
end
if customer.phone.present?
# FIXME: hardcoded prefix!
span.visible_xs "0#{customer.phone}"
end
else
""
end
end
if customer.phone.present?
# FIXME: hardcoded prefix!
span.visible_xs "0#{customer.phone}"
td.hidden_xs do
if customer.email.present?
a customer.email, href: "mailto:#{customer.email}"
else
""
end
end
td.hidden_xs do
if customer.phone.present?
# FIXME: hardcoded prefix!
"0#{customer.phone}"
else
""
end
end
td do
form action: R(CustomersN, customer.id), method: :post do
button.btn.btn_xs.btn_danger "Delete", type: :submit,
name: "delete", value: "Delete"
end
end
else
""
end
end
td.hidden_xs do
if customer.email.present?
a customer.email, href: "mailto:#{customer.email}"
else
""
end
end
td.hidden_xs do
if customer.phone.present?
# FIXME: hardcoded prefix!
"0#{customer.phone}"
else
""
end
end
td do
form action: R(CustomersN, customer.id), method: :post do
button.btn.btn_xs.btn_danger "Delete", type: :submit,
name: "delete", value: "Delete"
end
end
end
@ -2123,11 +2161,13 @@ module StopTime::Views
control_class: "col-sm-3 col-xs-4")
_form_input_with_label("Financial contact", "financial_contact", :text,
control_class: "col-sm-6 col-xs-8")
_form_input_with_label("Default hourly rate", "hourly_rate", :text,
control_class: "col-sm-3 col-xs-4",
input_addon: "€ / h")
_form_input_with_label("Default hourly rate", "hourly_rate", :number,
control_class: "col-sm-4 col-xs-5",
input_addon: "€ / h",
min: "0.00",
step: "0.01")
div.form_group do
label.control_label.col_sm_4.col_xs_4 "Time specifications?"
label.control_label.col_sm_3.col_xs_4 "Time specifications?"
div.col_sm_6.col_xs_8 do
div.checkbox do
_form_input_checkbox("time_specification")
@ -2135,7 +2175,7 @@ module StopTime::Views
end
end
div.form_group do
div.col_sm_offset_4.col_sm_6.col_xs_offset_4.col_xs_8 do
div.col_sm_offset_3.col_sm_6.col_xs_offset_4.col_xs_8 do
button.btn.btn_primary @button.capitalize, type: "submit",
name: @button, value: @button.capitalize
button.btn.btn_default "Cancel", type: "submit",
@ -2153,7 +2193,7 @@ module StopTime::Views
a.btn.btn_default.btn_sm role: "button",
href: R(CustomersNTasksNew, @customer.id) do
_icon("plus")
span "Add new project/task"
span "Add project/task"
end
end
end
@ -2243,7 +2283,7 @@ module StopTime::Views
a.btn.btn_default.btn_sm role: "button",
href: R(CustomersNInvoicesNew, @customer.id) do
_icon("plus")
span "Create new invoice"
span "Create invoice"
end
end
end
@ -2254,8 +2294,8 @@ module StopTime::Views
# Show registered time using the time_entries view as partial view.
div.row do
div.col_md_10.col_xs_12 do
h2 "Registered time"
div.col_xs_12 do
h2.timeline! "Registered unbilled time"
_time_entries(@customer)
end
end unless @button == "create"
@ -2279,14 +2319,16 @@ module StopTime::Views
end if @task.billed?
div.row do
div.col_md_6.col_xs_12 do
form.form_horizontal.form_condensed action: R(*@target), method: :post do
form.form_horizontal.form_condensed action: R(*@target),
method: :post do
div.form_group do
label.control_label.col_sm_3.col_xs_4 "Customer", for: "customer"
div.col_sm_4.col_xs_8 do
_form_select("customer", @customer_list)
end
div.col_sm_offset_2.col_sm_3.hidden_xs do
a.btn.btn_default role: "button", href: R(CustomersN, @customer.id) do
a.btn.btn_default role: "button",
href: R(CustomersN, @customer.id) do
_icon("user")
span "Show customer"
end
@ -2295,13 +2337,14 @@ module StopTime::Views
_form_input_with_label("Name", "name", :text)
div.form_group do
label.control_label.col_sm_3.col_xs_4 "Project/Task type"
div.col_sm_4.col_xs_8 do
div.col_sm_5.col_xs_8 do
div.radio do
label do
_form_input_radio("type", "hourly_rate", true)
text!("Hourly rate: ")
div.input_group do
_form_input("hourly_rate", :number, "Hourly rate")
_form_input("hourly_rate", :number, "Hourly rate",
min: "0.00", step: "0.01")
span.input_group_addon "€ / h"
end
end
@ -2311,7 +2354,8 @@ module StopTime::Views
_form_input_radio("type", "fixed_cost")
text!("Fixed cost: ")
div.input_group do
_form_input("fixed_cost", :number, "Fixed cost")
_form_input("fixed_cost", :number, "Fixed cost",
min: "0.00", step: "0.01")
span.input_group_addon ""
end
end
@ -2319,7 +2363,7 @@ module StopTime::Views
end
end
_form_input_with_label("VAT rate", "vat_rate", :number,
control_class: "col-sm-3 col-xs-6",
control_class: "col-lg-3 col-sm-4 col-xs-6",
input_addon: "%")
if @task.billed?
div.form_group do
@ -2350,7 +2394,7 @@ module StopTime::Views
# Show registered time (ab)using the time_entries view as partial view.
div.row do
div.col_md_8.col_xs_12 do
h2 "Registered #{@task.billed? ? "billed" : "unbilled"} time"
h2.timeline! "Registered #{@task.billed? ? "billed" : "unbilled"} time"
_time_entries(@customer, @task)
end
end unless @method == "create"
@ -2382,7 +2426,7 @@ module StopTime::Views
a.btn.btn_default.btn_sm role: "button",
href: R(CustomersNInvoicesNew, customer.id) do
_icon("plus")
span "Create new invoice"
span "Create invoice"
end
end
end
@ -2403,6 +2447,7 @@ module StopTime::Views
h1 do
text! "Invoice for "
a @customer.name, href: R(CustomersN, @customer.id)
small @invoice.number
end
end
div.row do
@ -2444,7 +2489,7 @@ module StopTime::Views
end
end
div.form_group do
div.col_sm_offset_3.col_sm_4.col_xs_offset_4.col_xs_8 do
div.col_sm_offset_3.col_sm_6.col_xs_offset_4.col_xs_8 do
button.btn.btn_primary "Update", type: :submit,
name: "update", value: "Update"
button.btn.btn_default "Reset", type: :reset,
@ -2545,7 +2590,7 @@ module StopTime::Views
href: R(CustomersNInvoicesX,
@customer.id, "#{@invoice.number}.tex") do
_icon("download")
span "Download LaTeX source"
span "Download LaTeX"
end
a.btn.btn_default role: "button",
href: R(Company, revision: @company.revision) do
@ -2714,7 +2759,7 @@ module StopTime::Views
button.btn.btn_primary "Create invoice", type: :submit,
name: "create", value: "Create invoice",
disabled: @none_found
button.btn.btn_default "Cancel", type: :submit, name: "cancel",
button.btn.btn_default "Cancel", type: :submit, name: "cancel",
value: "Cancel"
end
end
@ -2745,11 +2790,25 @@ module StopTime::Views
div.alert.alert_info do
text! " Viewing revision #{@company.revision}, " +
" last update at #{@company.updated_at}."
if @company.original.present?
a.btn.btn_default role: "button",
href: R(Company, revision: @company.original.revision) do
_icon("backward")
span "View previous revision"
div.btn_group do
if @company.original.present?
a.btn.btn_default role: "button",
href: R(Company, revision: @company.original.revision) do
_icon("backward")
span "View previous revision"
end
end
unless @company_last
a.btn.btn_default role: "button",
href: R(Company, revision: @company.revision.succ) do
_icon("forward")
span "View next revision"
end
a.btn.btn_default role: "button",
href: R(Company) do
_icon("fast-forward")
span "Most recent revision"
end
end
end
end
@ -2761,7 +2820,7 @@ module StopTime::Views
text! "Only make changes if you know what you are doing!"
end if @history_warn
div.row do
div.col_md_6.col_xs_12 do
div.col_md_8.col_xs_12 do
form.form_horizontal.form_condensed \
action: R(Company, revision: @company.revision),
method: :post do
@ -2894,7 +2953,7 @@ module StopTime::Views
tbody do
invoices.each do |invoice|
due_class = invoice.past_due? ? "warning" : ""
due_class = "error" if invoice.way_past_due?
due_class = "danger" if invoice.way_past_due?
tr(class: due_class) do
td do
a invoice.number,
@ -3098,6 +3157,7 @@ module StopTime::Views
# @param [Customer, nil] task a task to show time entries for
# @return [Mab::Mixin::Tag] the main menu
def _time_entries(customer=nil, task=nil)
date_time_new = date_time_new_entry(@time_entries.first)
form.form_inline action: R(Timeline), method: :post do
table.table.table_condensed.table_striped.table_hover do
thead do
@ -3131,11 +3191,11 @@ module StopTime::Views
end
td.col_md_1 do
input.form_control type: :text, name: "date",
value: DateTime.now.to_date.to_formatted_s
value: date_time_new && date_time_new.to_date.to_formatted_s
end
td.col_md_1 do
input.form_control type: :text, name: "start",
value: DateTime.now.to_time.to_formatted_s(:time_only)
value: date_time_new && date_time_new.to_formatted_s(:time_only)
end
td.col_md_1 do
input.form_control type: :text, name: "end"

View File

@ -1,4 +1,4 @@
/* CSS file for Stop Camping Time! */
/* CSS file for Stop... Camping Time! */
/* Main elements */
html
@ -52,7 +52,6 @@ table
th
overflow: hidden
table.table-condensed
td.indent
padding-left: 20px
@ -78,6 +77,9 @@ table.grand-total
.form-group
margin-bottom: 8px
.form-control
padding: 4px 6px
.form-inline
label
padding-top: 6px