Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GUI based on Glimmer for Windows users #90

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,11 @@ group :tui, optional: true do
gem 'ncursesw', '~>1.4.0'
gem 'rb-inotify', '~>0.10.0'
end

group :gui, optional: true do
# Keep in sync with buchungsstreber-gui dependencies
gem 'glimmer-dsl-libui', '~>0.5.4'
gem 'concurrent-ruby', '~>1.1.9'
gem 'matrix', '~>0.4.2'
gem 'rb-inotify', '~>0.10.0'
end
26 changes: 26 additions & 0 deletions buchungsstreber-gui.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
lib = File.expand_path('lib', __dir__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'buchungsstreber/version'

Gem::Specification.new do |spec|
spec.name = 'buchungsstreber-gui'
spec.version = Buchungsstreber::VERSION
spec.licenses = ['MIT']
spec.authors = ['jbuch']
spec.email = ['[email protected]']

spec.summary = %q{Enables timely timekeeping}
spec.description = "Enriches buchungsstreber with GUI."
spec.homepage = 'https://buchungsstreber.synyx.de'

spec.metadata['allowed_push_host'] = 'https://nexus.synyx.de/content/repositories/gems/'

spec.metadata['homepage_uri'] = spec.homepage
spec.metadata['source_code_uri'] = 'https://gitlab.synyx.de/synyx/buchungsstreber'
spec.metadata['changelog_uri'] = 'https://gitlab.synyx.de/synyx/buchungsstreber/CHANGELOG.md'
spec.files = []

spec.add_dependency 'buchungsstreber', Buchungsstreber::VERSION
spec.add_dependency 'glimmer-dsl-libui', '~> 1.4.0'
spec.add_dependency 'concurrent-ruby', '~> 1.1.9'
end
12 changes: 12 additions & 0 deletions lib/buchungsstreber/cli/app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,18 @@ def watch(date = nil)
handle_error(e, options[:debug])
end

desc 'gui [date]', _('Graphisches Interface')
def gui(date = nil)
date = parse_date(date) || Date.today
buchungsstreber = Buchungsstreber::Context.new(options[:file])

require_relative 'gui'
tui = Buchungsstreber::GUI::App.new(buchungsstreber, date, options)
tui.start
rescue Interrupt, StandardError => e
handle_error(e, options[:debug])
end

desc 'add [--date date] entry', _('Buchung ueber Kommandozeile hinzufuegen')
method_option :date, :default => 'today'
def add(*entry)
Expand Down
125 changes: 125 additions & 0 deletions lib/buchungsstreber/cli/gui.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
require 'concurrent-ruby'
require 'glimmer-dsl-libui'

require_relative '../../buchungsstreber/watcher'

module Buchungsstreber
module GUI
class App
include Glimmer

def initialize(buchungsstreber, startdate = nil, options = {})
@buchungsstreber = buchungsstreber
@date = startdate
@options = options
@data = Concurrent::Array.new
@day = ""
end

def start
refresh_data

@window = window('Buchungsstreber', 800, 400) {
margined true
vertical_box {
label("Buchungsstreber") {
stretchy false
text @day
}
table {
text_column(' ')
text_column(' ')
text_column(' ')
text_column(' ')
text_column(' ')
text_column(' ')

cell_rows @data
}
horizontal_box {
stretchy false
button(_('Buchen')) {
stretchy true
on_clicked do
buchen
end
}
button(_('Generate')) {
stretchy true
on_clicked do
generate
refresh_data
end
}
}
}
}

Thread.start do
Watcher.watch(@buchungsstreber.timesheet_file) do |_|
refresh_data
end
end

@window.show
rescue Interrupt
exit
end

private

def refresh_data
stats = @buchungsstreber.entries(@date)

hours = stats[:entries].map { |x| x[:time] }.sum
@day.replace "%s %sh / %sh\n" % [@date, hours, stats[:work_hours][@date]]

entries = Aggregator.aggregate(stats[:entries])
data = entries.map do |e|
err = e[:errors].map { |x| "<#{x.gsub(/:.*/m, '')}> " }.join('')
[
'',
e[:date],
e[:time],
e[:redmine],
(err || e[:title])[0..50],
e[:text],
]
end
@data.replace data
end

def generate
entries = @buchungsstreber.generate(@date)
entries.each do |e|
@buchungsstreber.resolve(e)
e[:redmine] = nil if @buchungsstreber.redmines.default?(e[:redmine])
end

parser = @buchungsstreber.timesheet_parser
parser.add(entries)
end

def buchen(date = nil)
redmines = @buchungsstreber.redmines
entries = @entries[:entries].select { |e| date.nil? || date == e[:date] }
entries = Aggregator.aggregate(entries)

entries.each_with_index do |entry, i|
redmine = redmines.get(entry[:redmine])
status = Validator.status!(entry, redmine)

if status.grep(/(time|activity)_different/).any?
success = false
entry[:errors] << _('-> DIFF') + " #{$1}"
elsif status.include?(:existing)
success = true
else
success = redmine.add_time entry
end
@data[i][0] = success ? _('o') : _('x')
end
end
end
end
end