Commit 016bb01e authored by Frank Bergmann's avatar Frank Bergmann

- Dunno

parent 89a576bf
......@@ -6,6 +6,7 @@
Ext.Loader.setPath('PO.model', '/sencha-core/model');
Ext.Loader.setPath('PO.store', '/sencha-core/store');
Ext.Loader.setPath('PO.class', '/sencha-core/class');
Ext.Loader.setPath('Ext.ux', '/sencha-core/ux');
Ext.Loader.setPath('PO.view.gantt', '/sencha-core/view/gantt');
Ext.Loader.setPath('PO.controller', '/sencha-core/controller');
......@@ -19,7 +20,8 @@ Ext.require([
'PO.model.timesheet.HourInterval',
'PO.store.timesheet.HourIntervalStore',
'PO.store.timesheet.TaskTreeStore',
'PO.store.timesheet.HourIntervalActivityStore'
'PO.store.timesheet.HourIntervalActivityStore',
'Ext.ux.TreeCombo'
]);
......@@ -43,17 +45,40 @@ function launchTreePanel(){
return projectName;
};
var rowEditing = Ext.create('Ext.grid.plugin.RowEditing', {
clicksToMoveEditor: 2,
listeners: {
edit: function(editor, context, eOpts) {
context.record.save();
}
}
});
var hourIntervalGrid = Ext.create('Ext.grid.Panel', {
store: hourIntervalStore,
layout: 'fit',
region: 'center',
columns: [
{text: "Project", flex: 1, dataIndex: 'project_id', renderer: hourIntervalGridProjectRenderer},
{text: "Start", flex: 1, dataIndex: 'interval_start', renderer: Ext.util.Format.dateRenderer('Y-m-d H:i:s') },
{text: "End", flex: 1, dataIndex: 'interval_end', renderer: Ext.util.Format.dateRenderer('Y-m-d H:i:s') },
{text: "Note", flex: 1, dataIndex: 'note'}
],
plugins: [rowEditing],
columns: [{
text: "Project", flex: 1, dataIndex: 'project_id', renderer: hourIntervalGridProjectRenderer,
editor: {
xtype: 'treecombo',
store: taskTreeStore,
rootVisible: false,
displayField: 'project_name',
valueField: 'id',
allowBlank: false
}
}, {
text: "Start", flex: 1, dataIndex: 'interval_start', renderer: Ext.util.Format.dateRenderer('Y-m-d H:i:s'),
editor: { allowBlank: false }
}, {
text: "End", flex: 1, dataIndex: 'interval_end', renderer: Ext.util.Format.dateRenderer('Y-m-d H:i:s'),
editor: { allowBlank: false }
}, {
text: "Note", flex: 1, dataIndex: 'note',
editor: { allowBlank: false }
}],
columnLines: true,
enableLocking: true,
collapsible: false,
......@@ -121,6 +146,7 @@ function launchTreePanel(){
'selectedTask': null, // Task selected by selection model
'loggingTask': null, // contains the task on which hours are logged or null otherwise
'loggingStartDate': null, // contains the time when "start" was pressed or null otherwise
'loggingInterval': null, // the hourInterval object created when logging
// Parameters
'renderDiv': null,
......@@ -144,12 +170,27 @@ function launchTreePanel(){
// Listen to changes in the selction model in order to enable/disable the start/stop buttons
me.ganttTreePanel.on('selectionchange', this.onTreePanelSelectionChange, me);
// Listen to a click into the empty space below the tree in order to add a new task
me.ganttTreePanel.on('containerclick', me.ganttTreePanel.onContainerClick, me.ganttTreePanel);
// Listen to a click into the empty space below the grid entries in order to start creating a new entry
me.hourIntervalGrid.on('containerclick', this.onGridContainerClick, me);
return this;
},
// Click into the empty space below the grid entries in order to start creating a new entry
onGridContainerClick: function() {
console.log('GanttButtonController.GridContainerClick');
var buttonStartLogging = Ext.getCmp('buttonStartLogging');
var disabled = buttonStartLogging.disabled;
if (!disabled) {
this.onButtonStartLogging();
}
},
/*
* Start logging the time.
* Before calling this procedure, the user must have selected a single
* leaf in the task tree for logging hours.
*/
onButtonStartLogging: function() {
console.log('GanttButtonController.ButtonStartLogging');
var buttonStartLogging = Ext.getCmp('buttonStartLogging');
......@@ -157,18 +198,41 @@ function launchTreePanel(){
buttonStartLogging.disable();
buttonStopLogging.enable();
rowEditing.cancelEdit();
// Start logging
this.loggingTask = selectedTask;
this.loggingStartTime = new Date();
var hourInterval = new Ext.create('PO.model.timesheet.HourInterval', {
user_id: @current_user_id@,
project_id: selectedTask.get('id'),
interval_start: this.loggingStartTime
// inverval_end: this.loggingStartTime
});
// Remember the new interval, add to store and start editing
this.loggingInterval = hourInterval;
hourIntervalStore.add(hourInterval);
//var rowIndex = hourIntervalStore.count() -1;
// rowEditing.startEdit(0, 0);
},
onButtonStopLogging: function() {
console.log('GanttButtonController.ButtonStopLogging');
var buttonStartLogging = Ext.getCmp('buttonStartLogging');
var buttonStopLogging = Ext.getCmp('buttonStopLogging');
buttonStartLogging.disable();
buttonStartLogging.enable();
buttonStopLogging.disable();
// Complete the hourInterval created when starting to log
this.loggingInterval.set('interval_end', new Date());
var rowIndex = hourIntervalStore.count() -1;
rowEditing.startEdit(rowIndex, 3);
this.loggingInterval.save();
// Stop logging
this.loggingTask = null;
this.loggingStartTime = null;
......@@ -191,6 +255,15 @@ function launchTreePanel(){
selectedTask = record; // Remember which task is selected
var isLeaf = record.isLeaf();
buttonStartLogging.setDisabled(!isLeaf);
// load the list of hourIntervals into the hourIntervalGrid
var projectId = record.get('id');
hourIntervalStore.getProxy().extraParams = { project_id: projectId, user_id: @current_user_id@, format: 'json' };
hourIntervalStore.load({
callback: function() {
console.log('PO.store.timesheet.HourIntervalStore: loaded');
}
});
} else { // Zero or two or more records enabled
buttonStartLogging.setDisabled(true);
}
......
......@@ -25,3 +25,6 @@ set task_editor_rand [expr round(rand() * 100000000.0)]
set task_editor_id "task_editor_$task_editor_rand"
set please_add_note_required_l10n [lang::message::lookup "" intranet-timesheet2-inverval.Please_add_a_note_required "Please add a note (required)"]
......@@ -81,6 +81,100 @@ create index im_hour_intervals_interval_start_idx on im_hour_intervals(interval_
-- ------------------------------------------------------------
-- Trigger for synchronization between intervals and hours
-- ------------------------------------------------------------
-- Create a new im_hour row for the interval or update
-- an existing one.
create or replace function im_hour_interval_update_im_hours (integer, integer, date)
returns integer as $body$
DECLARE
p_user_id alias for $1;
p_project_id alias for $2;
p_day alias for $3;
v_hour_id integer;
v_sum_hours numeric;
v_sum_notes varchar;
row record;
BEGIN
-- Check if there is already an im_hours entry
select h.hour_id into v_hour_id
from im_hours h
where h.user_id = p_user_id and
h.project_id = p_project_id and
h.day = p_day;
-- Create a new entry if there wasnt one before
IF v_hour_id is null THEN
v_hour_id := nextval('im_hours_seq');
RAISE NOTICE 'im_hour_interval_insert_tr: About to insert a new im_hour with ID=%', v_hour_id;
insert into im_hours (
hour_id, user_id, project_id, day, hours, note
) values (
v_hour_id, p_user_id, p_project_id, p_day, 0, ''
);
END IF;
-- Sum up all interval properties into one hour row
v_sum_hours := 0.0;
v_sum_notes := '';
FOR row IN
select *
from im_hour_intervals
where user_id = p_user_id and
project_id = p_project_id and
interval_start::date = p_day
LOOP
v_sum_hours := v_sum_hours + coalesce(extract(epoch from row.interval_end - row.interval_start) / 3600.0, 0.0);
v_sum_notes := v_sum_notes || coalesce(row.note, '') || E'\n';
END LOOP;
-- Update the im_hours entry with the sum of the values
update im_hours
set hours = v_sum_hours, note = v_sum_notes
where hour_id = v_hour_id;
return 0;
END;$body$ language 'plpgsql';
create or replace function im_hour_interval_insert_tr ()
returns trigger as $body$
BEGIN
PERFORM im_hour_interval_update_im_hours (new.user_id, new.project_id, new.interval_start::date);
return new;
END;$body$ language 'plpgsql';
create or replace function im_hour_interval_update_tr ()
returns trigger as $body$
BEGIN
PERFORM im_hour_interval_update_im_hours (new.user_id, new.project_id, new.interval_start::date);
IF new.interval_start::date != old.interval_start::date THEN
PERFORM im_hour_interval_update_im_hours (old.user_id, old.project_id, old.interval_start::date);
END IF;
return new;
END;$body$ language 'plpgsql';
create or replace function im_hour_interval_delete_tr ()
returns trigger as $body$
BEGIN
PERFORM im_hour_interval_update_im_hours (old.user_id, old.project_id, old.interval_start::date);
return old;
END;$body$ language 'plpgsql';
create trigger im_hour_interval_insert_tr after insert on im_hour_intervals for each row execute procedure im_hour_interval_insert_tr();
create trigger im_hour_interval_update_tr after update on im_hour_intervals for each row execute procedure im_hour_interval_update_tr();
create trigger im_hour_interval_delete_tr after delete on im_hour_intervals for each row execute procedure im_hour_interval_delete_tr();
-- ------------------------------------------------------------
-- Portlet
-- ------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment