From fbb11fbcd8310cb4c9af444774b79ca064f470ac Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev <anwinged@ya.ru> Date: Sun, 17 Nov 2019 20:48:25 +0300 Subject: [PATCH] More consistent api --- assets/App.vue | 40 +++++++++++++++++++--------------------- spec/profile_spec.cr | 2 +- src/dayoff.cr | 16 ++++++++-------- src/dayoff/entities.cr | 3 ++- src/dayoff/helpers.cr | 12 ++++++++++++ src/dayoff/profile.cr | 17 ++++++----------- 6 files changed, 48 insertions(+), 42 deletions(-) create mode 100644 src/dayoff/helpers.cr diff --git a/assets/App.vue b/assets/App.vue index cda5e32..4c9b488 100644 --- a/assets/App.vue +++ b/assets/App.vue @@ -1,14 +1,18 @@ <template> <div id="app"> - <section class="timer" v-bind:class="{ overtime: isOvertime }"> - {{ time }} + <section + v-if="total_time" + class="timer" + v-bind:class="{ overtime: isOvertime }" + > + {{ total_time | str_time }} </section> <section class="actions"> <a v-if="started" v-on:click.prevent="finish" href="#">Закончить</a> <a v-else v-on:click.prevent="start" href="#">Начать</a> </section> - <section class="today"> - Сегодня {{ today_time }} + <section v-if="today_time" class="today"> + Сегодня {{ today_time | str_time }} </section> <p class="profile-info">Профиль: {{ profileId }}</p> </div> @@ -21,10 +25,8 @@ export default { return { profileId: null, started: false, - status: '', - hours: 0, - minutes: 0, - today: null, + total_time: null, + today_time: null, }; }, created() { @@ -33,26 +35,16 @@ export default { setInterval(() => this.get_status(), 60 * 1000); }, computed: { - time() { - const sign = this.isOvertime ? '+' : ''; - return sign + this.hours + ':' + String(this.minutes).padStart(2, '0'); - }, isOvertime() { - return this.status === 'overtime'; + return this.total_time && this.total_time.status === 'overtime'; }, - today_time() { - const sign = this.today.status === 'overtime' ? '+' : ''; - return sign + this.today.hours + ':' + String(this.today.minutes).padStart(2, '0'); - } }, methods: { get_status() { h.get_status(this.profileId).then(data => { this.started = data.started; - this.status = data.total.status; - this.hours = data.total.hours; - this.minutes = data.total.minutes; - this.today = data.today; + this.total_time = data.total.time; + this.today_time = data.today.time; }); }, start() { @@ -62,6 +54,12 @@ export default { h.finish(this.profileId).then(() => this.get_status()); }, }, + filters: { + str_time(time) { + const sign = time.status === 'overtime' ? '+' : ''; + return sign + time.hours + ':' + String(time.minutes).padStart(2, '0'); + }, + }, }; </script> diff --git a/spec/profile_spec.cr b/spec/profile_spec.cr index 017f8ea..9c779a6 100644 --- a/spec/profile_spec.cr +++ b/spec/profile_spec.cr @@ -67,7 +67,7 @@ module Dayoff::Test it "can calc remaining time" do prof = create_profile - span = prof.remaining_time t(3, 12) + span = prof.total_status t(3, 12) expected = 8 * 3 - 10 * 2 expected.should eq span.total_hours end diff --git a/src/dayoff.cr b/src/dayoff.cr index 6198e16..8b33b4f 100644 --- a/src/dayoff.cr +++ b/src/dayoff.cr @@ -17,10 +17,8 @@ def now Time.local(Time::Location.load("Europe/Moscow")) end -def date_status(profile, date) - span = profile.date_status date +def serialize_span(span : Time::Span) { - date: date.to_s("%Y-%m-%d"), status: span < Time::Span.zero ? STATUS_OVERTIME : STATUS_UPTIME, hours: span.abs.total_hours.to_i32, minutes: span.abs.minutes.to_i32, @@ -41,15 +39,17 @@ end get "/api/status" do |env| profile = app.profile Dayoff::ProfileId.new(env.get("profile_id").to_s) - rem_span = profile.remaining_time now + total_span = profile.total_status now + today_span = profile.date_status now data = { started: profile.started?, total: { - status: rem_span < Time::Span.zero ? STATUS_OVERTIME : STATUS_UPTIME, - hours: rem_span.abs.total_hours.to_i32, - minutes: rem_span.abs.minutes.to_i32, + time: serialize_span total_span, + }, + today: { + date: now.to_s("%Y-%m-%d"), + time: serialize_span today_span, }, - today: date_status(profile, now), } env.response.content_type = "application/json" data.to_json diff --git a/src/dayoff/entities.cr b/src/dayoff/entities.cr index 421daa0..6b1ea86 100644 --- a/src/dayoff/entities.cr +++ b/src/dayoff/entities.cr @@ -70,7 +70,8 @@ module Dayoff end private def in_range_finished(from_time : Time, to_time : Time) : Time::Span - if @start <= to_time && finish! >= from_time + crossed = Helpers.crossed? @start, finish!, from_time, to_time + if crossed normalized_start = Math.max(@start, from_time) normalized_finish = Math.min(finish!, to_time) normalized_finish - normalized_start diff --git a/src/dayoff/helpers.cr b/src/dayoff/helpers.cr new file mode 100644 index 0000000..34e0db0 --- /dev/null +++ b/src/dayoff/helpers.cr @@ -0,0 +1,12 @@ +module Dayoff::Helpers + extend self + + def zero_time : Time + location = Time::Location.load("Europe/Moscow") + Time.local(1, 1, 1, 0, 0, location: location) + end + + def crossed?(s1 : Time, f1 : Time, s2 : Time, f2 : Time) : Bool + s1 <= f2 && f1 >= s2 + end +end diff --git a/src/dayoff/profile.cr b/src/dayoff/profile.cr index 757fe17..bcd7141 100644 --- a/src/dayoff/profile.cr +++ b/src/dayoff/profile.cr @@ -64,20 +64,15 @@ module Dayoff end end - private def zero_time : Time - location = Time::Location.load("Europe/Moscow") - Time.local(1, 1, 1, 0, 0, location: location) - end - - def remaining_time(on_time : Time) : Time::Span - planned = get_planned zero_time, on_time - worked = get_worked zero_time, on_time + def total_status(on_time : Time) : Time::Span + planned = get_planned Helpers.zero_time, on_time + worked = get_worked Helpers.zero_time, on_time planned - worked end - def date_status(date : Time) : Time::Span - planned = get_planned date.at_beginning_of_day, date.at_end_of_day - worked = get_worked date.at_beginning_of_day, date + def date_status(on_time : Time) : Time::Span + planned = get_planned on_time.at_beginning_of_day, on_time.at_end_of_day + worked = get_worked on_time.at_beginning_of_day, on_time planned - worked end end