1- <template >
2- <FullCalendar :options =" calendarOptions" />
1+ <template lang="pug">
2+ div.mx-3
3+ b-form
4+ b-form-group( label ="Bucket:" )
5+ select( v-model ="selectedBucket" )
6+ option( v-for ="bucket in buckets" , :value ="bucket.id" ) {{ bucket.id }}
7+ b-form-group( label ="Show:" )
8+ select( v-model ="view" )
9+ option( value ="timeGridDay" ) Day
10+ option( value ="timeGridWeek" ) Week
11+ b-form-group
12+ b-checkbox( v-model ="fitToActive" )
13+ | Fit to active
14+ FullCalendar( ref ="fullCalendar" , :options ="calendarOptions" )
315</template >
416
517<script >
618import { getTitleAttr , getColorFromString } from ' ../util/color' ;
719import moment from ' moment' ;
20+ import _ from ' lodash' ;
821import FullCalendar from ' @fullcalendar/vue' ;
922import timeGridPlugin from ' @fullcalendar/timegrid' ;
1023
11- // TODO: Use canonical timeline query instead, with flooding and categorization
24+ // TODO: Use canonical timeline query, with flooding and categorization
25+ // TODO: Checkbox for toggling category-view, where adjacent events with same category are merged and the events are labeled by category
1226// TODO: Use the recommended way of dynamically getting events: https://fullcalendar.io/docs/events-function
1327export default {
1428 components: {
@@ -18,19 +32,26 @@ export default {
1832 buckets: { type: Array },
1933 },
2034 data () {
21- return { fitToActive: true };
35+ return { fitToActive: false , selectedBucket : null , view : ' timeGridDay ' };
2236 },
2337 computed: {
24- calendarOptions : function () {
38+ calendarOptions : function () {
2539 const events = this .events ;
2640 const first = _ .minBy (events, e => e .start );
2741 const last = _ .maxBy (events, e => e .end );
2842 // FIXME: end must be at least one slot (1 hour) after start, otherwise it fails hard
29- const start = this .fitToActive && events .length > 0 ? first .start .slice (11 , 16 ) : ' 00:00:00' ;
30- const end = this .fitToActive && events .length > 0 ? last .end .slice (11 , 16 ) : ' 24:00:00' ;
43+ let start, end;
44+ if (this .fitToActive && events .length > 0 ) {
45+ console .log (first .start );
46+ start = moment (first .start ).startOf (' hour' ).format ().slice (11 , 16 );
47+ end = moment (last .end ).endOf (' hour' ).format ().slice (11 , 16 );
48+ } else {
49+ start = ' 00:00:00' ;
50+ end = ' 24:00:00' ;
51+ }
3152 return {
3253 plugins: [timeGridPlugin],
33- initialView: ' timeGridDay ' ,
54+ initialView: this . view ,
3455 eventClick: this .onEventClick ,
3556 events: events,
3657 allDaySlot: false ,
@@ -46,28 +67,35 @@ export default {
4667 },
4768 };
4869 },
49- events : function () {
70+ events : function () {
5071 // NOTE: This returns FullCalendar events, not ActivityWatch events.
5172 if (this .buckets == null ) return [];
5273
53- const bucket = _ .find (this .buckets , b => b .id == ' aw-watcher-window_erb-main2-arch' );
74+ const bucket = _ .find (this .buckets , b => b .id == this .selectedBucket );
75+ if (bucket == null ) {
76+ return ;
77+ }
5478 let events = bucket .events ;
5579 events = _ .filter (events, e => e .duration > 10 );
5680 events = _ .map (events, e => {
5781 return {
5882 title: getTitleAttr (bucket, e),
5983 start: moment (e .timestamp ).format (),
60- end: moment (e .timestamp )
61- .add (e .duration , ' seconds' )
62- .format (),
84+ end: moment (e .timestamp ).add (e .duration , ' seconds' ).format (),
6385 backgroundColor: getColorFromString (getTitleAttr (bucket, e)),
6486 };
6587 });
6688 return events;
6789 },
6890 },
91+ watch: {
92+ view : function (to ) {
93+ const calendar = this .$refs .fullCalendar .getApi ();
94+ calendar .changeView (to);
95+ },
96+ },
6997 methods: {
70- onEventClick : function (arg ) {
98+ onEventClick : function (arg ) {
7199 // TODO: Open event inspector/editor here
72100 alert (' event click! ' + JSON .stringify (arg .event ));
73101 },
0 commit comments