Add statistics table
This commit is contained in:
parent
76bae89331
commit
a2d8855f28
@ -18,6 +18,16 @@
|
|||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
<p class="profile-info">Профиль: {{ profileId }}</p>
|
<p class="profile-info">Профиль: {{ profileId }}</p>
|
||||||
|
<a href="#" v-on:click.prevent="show_stat = !show_stat">Статистика</a>
|
||||||
|
<div v-if="show_stat">
|
||||||
|
<table class="stat-table">
|
||||||
|
<tr v-for="item in statistics">
|
||||||
|
<td>{{ item.date }}</td>
|
||||||
|
<td>{{ item.planned.total_minutes }}</td>
|
||||||
|
<td>{{ item.worked.total_minutes }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -31,11 +41,14 @@ export default {
|
|||||||
started: false,
|
started: false,
|
||||||
total_time: null,
|
total_time: null,
|
||||||
today_time: null,
|
today_time: null,
|
||||||
|
show_stat: false,
|
||||||
|
statistics: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.profileId = h.extract_profile_id();
|
this.profileId = h.extract_profile_id();
|
||||||
this.get_status();
|
this.get_status();
|
||||||
|
this.get_statistics();
|
||||||
setInterval(() => this.get_status(), 60 * 1000);
|
setInterval(() => this.get_status(), 60 * 1000);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -46,6 +59,11 @@ export default {
|
|||||||
this.today_time = TimeSpan.fromObject(data.today.time);
|
this.today_time = TimeSpan.fromObject(data.today.time);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
get_statistics() {
|
||||||
|
h.get_statistics(this.profileId).then(data => {
|
||||||
|
this.statistics = data;
|
||||||
|
});
|
||||||
|
},
|
||||||
start() {
|
start() {
|
||||||
h.start(this.profileId).then(() => this.get_status());
|
h.start(this.profileId).then(() => this.get_status());
|
||||||
},
|
},
|
||||||
@ -85,4 +103,8 @@ export default {
|
|||||||
.profile-info {
|
.profile-info {
|
||||||
margin-top: 2em;
|
margin-top: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stat-table {
|
||||||
|
display: inline-table;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -32,4 +32,19 @@ async function finish(profileId) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export default { extract_profile_id, check_profile, get_status, start, finish };
|
async function get_statistics(profileId) {
|
||||||
|
const response = await fetch('/api/statistics?profile_id=' + profileId, {
|
||||||
|
method: 'GET',
|
||||||
|
});
|
||||||
|
const data = await response.json();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
extract_profile_id,
|
||||||
|
check_profile,
|
||||||
|
get_status,
|
||||||
|
start,
|
||||||
|
finish,
|
||||||
|
get_statistics,
|
||||||
|
};
|
||||||
|
@ -77,5 +77,11 @@ module Dayoff::Test
|
|||||||
span = prof.date_status t(1, 15)
|
span = prof.date_status t(1, 15)
|
||||||
span.total_hours.should eq 3
|
span.total_hours.should eq 3
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "can get statistics" do
|
||||||
|
prof = create_profile
|
||||||
|
stat = prof.statistics t(3, 12)
|
||||||
|
stat.size.should eq 3
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -22,6 +22,7 @@ def serialize_span(span : Time::Span)
|
|||||||
status: span < Time::Span.zero ? STATUS_OVERTIME : STATUS_UPTIME,
|
status: span < Time::Span.zero ? STATUS_OVERTIME : STATUS_UPTIME,
|
||||||
hours: span.abs.total_hours.to_i32,
|
hours: span.abs.total_hours.to_i32,
|
||||||
minutes: span.abs.minutes.to_i32,
|
minutes: span.abs.minutes.to_i32,
|
||||||
|
total_minutes: span.abs.total_minutes.to_i32,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -55,6 +56,19 @@ get "/api/status" do |env|
|
|||||||
data.to_json
|
data.to_json
|
||||||
end
|
end
|
||||||
|
|
||||||
|
get "/api/statistics" do |env|
|
||||||
|
profile = app.profile Dayoff::ProfileId.new(env.get("profile_id").to_s)
|
||||||
|
data = profile.statistics now
|
||||||
|
mapped = data.map do |v|
|
||||||
|
{
|
||||||
|
date: v.date.to_s("%Y-%m-%d"),
|
||||||
|
planned: serialize_span(v.planned),
|
||||||
|
worked: serialize_span(v.worked),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
mapped.to_json
|
||||||
|
end
|
||||||
|
|
||||||
get "/" do
|
get "/" do
|
||||||
render "public/index.ecr"
|
render "public/index.ecr"
|
||||||
end
|
end
|
||||||
|
@ -23,9 +23,13 @@ module Dayoff
|
|||||||
def initialize(@date : Time, @hours : Int32)
|
def initialize(@date : Time, @hours : Int32)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def hours_as_span : Time::Span
|
||||||
|
Time::Span.new(hours: @hours, minutes: 0, seconds: 0)
|
||||||
|
end
|
||||||
|
|
||||||
def in_range(from_time : Time, to_time : Time) : Time::Span
|
def in_range(from_time : Time, to_time : Time) : Time::Span
|
||||||
if @date >= from_time && @date < to_time
|
if @date >= from_time && @date < to_time
|
||||||
Time::Span.new(hours: @hours, minutes: 0, seconds: 0)
|
hours_as_span
|
||||||
else
|
else
|
||||||
Time::Span.zero
|
Time::Span.zero
|
||||||
end
|
end
|
||||||
@ -61,6 +65,10 @@ module Dayoff
|
|||||||
!@finish.nil?
|
!@finish.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get_span(to_time : Time) : Time::Span
|
||||||
|
in_range @start, to_time
|
||||||
|
end
|
||||||
|
|
||||||
def in_range(from_time : Time, to_time : Time) : Time::Span
|
def in_range(from_time : Time, to_time : Time) : Time::Span
|
||||||
if finished?
|
if finished?
|
||||||
in_range_finished from_time, to_time
|
in_range_finished from_time, to_time
|
||||||
|
@ -12,6 +12,23 @@ module Dayoff
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class DayStatRecord
|
||||||
|
getter date
|
||||||
|
getter planned
|
||||||
|
getter worked
|
||||||
|
|
||||||
|
def initialize(@date : Time, @planned : Time::Span, @worked : Time::Span)
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_planned(v : Time::Span)
|
||||||
|
@planned += v
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_worked(v : Time::Span)
|
||||||
|
@worked += v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class Profile
|
class Profile
|
||||||
@pdates = [] of PlannedDate
|
@pdates = [] of PlannedDate
|
||||||
@wrecords = [] of WorkRecord
|
@wrecords = [] of WorkRecord
|
||||||
@ -75,5 +92,40 @@ module Dayoff
|
|||||||
worked = get_worked on_time.at_beginning_of_day, on_time
|
worked = get_worked on_time.at_beginning_of_day, on_time
|
||||||
planned - worked
|
planned - worked
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def statistics(on_time : Time) : Array(DayStatRecord)
|
||||||
|
dates = {} of String => DayStatRecord
|
||||||
|
|
||||||
|
@pdates.each do |pd|
|
||||||
|
key = pd.date.to_s("%Y-%m-%d")
|
||||||
|
dates[key] = DayStatRecord.new(
|
||||||
|
pd.date,
|
||||||
|
pd.hours_as_span,
|
||||||
|
Time::Span.zero
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
@wrecords.each do |wr|
|
||||||
|
key = wr.start.to_s("%Y-%m-%d")
|
||||||
|
if dates.has_key? key
|
||||||
|
dates[key].add_worked wr.in_range(Helpers.zero_time, on_time)
|
||||||
|
else
|
||||||
|
dates[key] = DayStatRecord.new(
|
||||||
|
wr.start,
|
||||||
|
Time::Span.zero,
|
||||||
|
wr.in_range(Helpers.zero_time, on_time)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
date_keys = dates.keys.sort!.reverse!
|
||||||
|
|
||||||
|
result = [] of DayStatRecord
|
||||||
|
date_keys.each do |k|
|
||||||
|
result.push dates[k]
|
||||||
|
end
|
||||||
|
|
||||||
|
result
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user