task-manager 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +4 -0
  3. data/Rakefile +27 -0
  4. data/app/assets/images/task-manager/icons/add.png +0 -0
  5. data/app/assets/images/task-manager/icons/delete.png +0 -0
  6. data/app/assets/images/task-manager/icons/edit.png +0 -0
  7. data/app/assets/javascripts/task-manager/application.js +43 -0
  8. data/app/assets/javascripts/task-manager/extjs/app/controller/Plans.js +359 -0
  9. data/app/assets/javascripts/task-manager/extjs/app/controller/Tasks.js +56 -0
  10. data/app/assets/javascripts/task-manager/extjs/app/helper/application_helper.js +24 -0
  11. data/app/assets/javascripts/task-manager/extjs/app/model/Assignee.js +19 -0
  12. data/app/assets/javascripts/task-manager/extjs/app/model/Plan.js +195 -0
  13. data/app/assets/javascripts/task-manager/extjs/app/model/Task.js +23 -0
  14. data/app/assets/javascripts/task-manager/extjs/app/store/Assignees.js +53 -0
  15. data/app/assets/javascripts/task-manager/extjs/app/store/AssigneesTree.js +3 -0
  16. data/app/assets/javascripts/task-manager/extjs/app/store/Booleans.js +9 -0
  17. data/app/assets/javascripts/task-manager/extjs/app/store/Days.js +38 -0
  18. data/app/assets/javascripts/task-manager/extjs/app/store/Hours.js +31 -0
  19. data/app/assets/javascripts/task-manager/extjs/app/store/Minutes.js +67 -0
  20. data/app/assets/javascripts/task-manager/extjs/app/store/Months.js +19 -0
  21. data/app/assets/javascripts/task-manager/extjs/app/store/Plans.js +6 -0
  22. data/app/assets/javascripts/task-manager/extjs/app/store/QuarterlyMonths.js +10 -0
  23. data/app/assets/javascripts/task-manager/extjs/app/store/Statuses.js +11 -0
  24. data/app/assets/javascripts/task-manager/extjs/app/store/Tasks.js +6 -0
  25. data/app/assets/javascripts/task-manager/extjs/app/store/Types.js +12 -0
  26. data/app/assets/javascripts/task-manager/extjs/app/store/WeekDays.js +14 -0
  27. data/app/assets/javascripts/task-manager/extjs/app/view/plan/AssignablesWindow.js +23 -0
  28. data/app/assets/javascripts/task-manager/extjs/app/view/plan/Edit.js +189 -0
  29. data/app/assets/javascripts/task-manager/extjs/app/view/plan/EditWindow.js +21 -0
  30. data/app/assets/javascripts/task-manager/extjs/app/view/plan/Grid.js +92 -0
  31. data/app/assets/javascripts/task-manager/extjs/app/view/plan/Index.js +24 -0
  32. data/app/assets/javascripts/task-manager/extjs/app/view/plan/New.js +190 -0
  33. data/app/assets/javascripts/task-manager/extjs/app/view/plan/Search.js +132 -0
  34. data/app/assets/javascripts/task-manager/extjs/app/view/plan/SelectAssignables.js +22 -0
  35. data/app/assets/javascripts/task-manager/extjs/app/view/plan/SelectAssignablesGrid.js +22 -0
  36. data/app/assets/javascripts/task-manager/extjs/app/view/plan/SelectAssignablesTree.js +9 -0
  37. data/app/assets/javascripts/task-manager/extjs/app/view/plan/Window.js +21 -0
  38. data/app/assets/javascripts/task-manager/extjs/app/view/task/Grid.js +62 -0
  39. data/app/assets/javascripts/task-manager/extjs/app/view/task/Index.js +21 -0
  40. data/app/assets/javascripts/task-manager/extjs/app/view/task/Search.js +148 -0
  41. data/app/assets/javascripts/task-manager/extjs/lib/ux/MultiSelectablePagingGrid.js +20 -0
  42. data/app/assets/javascripts/task-manager/extjs/lib/ux/RowExpander.js +230 -0
  43. data/app/assets/stylesheets/task-manager/application.css.scss +13 -0
  44. data/app/assets/stylesheets/task-manager/extjs.css.scss +43 -0
  45. data/app/controllers/task_manager/api/v1/plans_controller.rb +251 -0
  46. data/app/controllers/task_manager/api/v1/tasks_controller.rb +82 -0
  47. data/app/controllers/task_manager/application_controller.rb +4 -0
  48. data/app/helpers/task_manager/application_helper.rb +4 -0
  49. data/app/models/task_manager/assignable.rb +10 -0
  50. data/app/models/task_manager/callable.rb +10 -0
  51. data/app/models/task_manager/plan.rb +114 -0
  52. data/app/models/task_manager/task.rb +81 -0
  53. data/app/serializers/task_manager/plan_serializer.rb +8 -0
  54. data/app/serializers/task_manager/task_serializer.rb +8 -0
  55. data/app/views/layouts/task-manager/application.html.erb +14 -0
  56. data/config/routes.rb +8 -0
  57. data/db/migrate/20121102054723_setup_hstore.rb +9 -0
  58. data/db/migrate/20121102055137_create_task_manager_plans.rb +16 -0
  59. data/db/migrate/20121102142657_create_task_manager_assignables.rb +13 -0
  60. data/db/migrate/20121102150720_create_task_manager_callables.rb +13 -0
  61. data/db/migrate/20121105170602_create_task_manager_tasks.rb +18 -0
  62. data/lib/task-manager.rb +37 -0
  63. data/lib/task-manager/api_constraints.rb +12 -0
  64. data/lib/task-manager/deadline_calculator.rb +22 -0
  65. data/lib/task-manager/deadline_validator.rb +27 -0
  66. data/lib/task-manager/engine.rb +5 -0
  67. data/lib/task-manager/version.rb +3 -0
  68. data/lib/tasks/task-manager_tasks.rake +4 -0
  69. metadata +327 -0
@@ -0,0 +1,67 @@
1
+ Ext.define('TM.store.Minutes',{
2
+ extend: 'Ext.data.Store',
3
+
4
+ fields: ['text', 'value'],
5
+ data : [
6
+ { "text": "0", 'value': '0' },
7
+ { "text": "1", 'value': '1' },
8
+ { "text": "2", 'value': '2' },
9
+ { "text": "3", 'value': '3' },
10
+ { "text": "4", 'value': '4' },
11
+ { "text": "5", 'value': '5' },
12
+ { "text": "6", 'value': '6' },
13
+ { "text": "7", 'value': '7' },
14
+ { "text": "8", 'value': '8' },
15
+ { "text": "9", 'value': '9' },
16
+ { "text": "10", 'value': '10' },
17
+ { "text": "11", 'value': '11' },
18
+ { "text": "12", 'value': '12' },
19
+ { "text": "13", 'value': '13' },
20
+ { "text": "14", 'value': '14' },
21
+ { "text": "15", 'value': '15' },
22
+ { "text": "16", 'value': '16' },
23
+ { "text": "17", 'value': '17' },
24
+ { "text": "18", 'value': '18' },
25
+ { "text": "19", 'value': '19' },
26
+ { "text": "20", 'value': '20' },
27
+ { "text": "21", 'value': '21' },
28
+ { "text": "22", 'value': '22' },
29
+ { "text": "23", 'value': '23' },
30
+ { "text": "24", 'value': '24' },
31
+ { "text": "25", 'value': '25' },
32
+ { "text": "26", 'value': '26' },
33
+ { "text": "27", 'value': '27' },
34
+ { "text": "28", 'value': '28' },
35
+ { "text": "29", 'value': '29' },
36
+ { "text": "30", 'value': '30' },
37
+ { "text": "31", 'value': '31' },
38
+ { "text": "32", 'value': '32' },
39
+ { "text": "33", 'value': '33' },
40
+ { "text": "34", 'value': '34' },
41
+ { "text": "35", 'value': '35' },
42
+ { "text": "36", 'value': '36' },
43
+ { "text": "37", 'value': '37' },
44
+ { "text": "38", 'value': '38' },
45
+ { "text": "39", 'value': '39' },
46
+ { "text": "40", 'value': '40' },
47
+ { "text": "41", 'value': '41' },
48
+ { "text": "42", 'value': '42' },
49
+ { "text": "43", 'value': '43' },
50
+ { "text": "44", 'value': '44' },
51
+ { "text": "45", 'value': '45' },
52
+ { "text": "46", 'value': '46' },
53
+ { "text": "47", 'value': '47' },
54
+ { "text": "48", 'value': '48' },
55
+ { "text": "49", 'value': '49' },
56
+ { "text": "50", 'value': '50' },
57
+ { "text": "51", 'value': '51' },
58
+ { "text": "52", 'value': '52' },
59
+ { "text": "53", 'value': '53' },
60
+ { "text": "54", 'value': '54' },
61
+ { "text": "55", 'value': '55' },
62
+ { "text": "56", 'value': '56' },
63
+ { "text": "57", 'value': '57' },
64
+ { "text": "58", 'value': '58' },
65
+ { "text": "59", 'value': '59' }
66
+ ]
67
+ });
@@ -0,0 +1,19 @@
1
+ Ext.define('TM.store.Months',{
2
+ extend: 'Ext.data.Store',
3
+
4
+ fields: ['text', 'value'],
5
+ data : [
6
+ { "text": "1月", 'value': '01' },
7
+ { "text": "2月", 'value': '02' },
8
+ { "text": "3月", 'value': '03' },
9
+ { "text": "4月", 'value': '04' },
10
+ { "text": "5月", 'value': '05' },
11
+ { "text": "6月", 'value': '06' },
12
+ { "text": "7月", 'value': '07' },
13
+ { "text": "8月", 'value': '08' },
14
+ { "text": "9月", 'value': '09' },
15
+ { "text": "10月", 'value': '10' },
16
+ { "text": "11月", 'value': '11' },
17
+ { "text": "12月", 'value': '12' },
18
+ ]
19
+ });
@@ -0,0 +1,6 @@
1
+ Ext.define('TM.store.Plans', {
2
+ extend: 'Ext.data.Store',
3
+
4
+ autoLoad: true,
5
+ model: 'TM.model.Plan'
6
+ });
@@ -0,0 +1,10 @@
1
+ Ext.define('TM.store.QuarterlyMonths',{
2
+ extend: 'Ext.data.Store',
3
+
4
+ fields: ['text', 'value'],
5
+ data : [
6
+ { "text": "第一个月", 'value': '1' },
7
+ { "text": "第二个月", 'value': '2' },
8
+ { "text": "第三个月", 'value': '3' }
9
+ ]
10
+ });
@@ -0,0 +1,11 @@
1
+ Ext.define('TM.store.Statuses',{
2
+ extend: 'Ext.data.Store',
3
+
4
+ fields: ['text', 'value'],
5
+ data : [
6
+ { "text": "新建", 'value': 'new' },
7
+ { "text": "进行中", 'value': 'in_process' },
8
+ { "text": "已过期", 'value': 'expired' },
9
+ { "text": "已完成", 'value': 'finished' }
10
+ ]
11
+ });
@@ -0,0 +1,6 @@
1
+ Ext.define('TM.store.Tasks',{
2
+ extend: 'Ext.data.Store',
3
+
4
+ autoLoad: true,
5
+ model: 'TM.model.Task'
6
+ });
@@ -0,0 +1,12 @@
1
+ Ext.define('TM.store.Types',{
2
+ extend: 'Ext.data.Store',
3
+
4
+ fields: ['text', 'value'],
5
+ data : [
6
+ { "text": "年计划", 'value': 'yearly' },
7
+ { "text": "季计划", 'value': 'quarterly' },
8
+ { "text": "月计划", 'value': 'monthly' },
9
+ { "text": "周计划", 'value': 'weekly' },
10
+ { "text": "日计划", 'value': 'daily' }
11
+ ]
12
+ });
@@ -0,0 +1,14 @@
1
+ Ext.define('TM.store.WeekDays',{
2
+ extend: 'Ext.data.Store',
3
+
4
+ fields: ['text', 'value'],
5
+ data : [
6
+ { "text": "星期一", 'value': '1' },
7
+ { "text": "星期二", 'value': '2' },
8
+ { "text": "星期三", 'value': '3' },
9
+ { "text": "星期四", 'value': '4' },
10
+ { "text": "星期五", 'value': '5' },
11
+ { "text": "星期六", 'value': '6' },
12
+ { "text": "星期日", 'value': '7' }
13
+ ]
14
+ });
@@ -0,0 +1,23 @@
1
+ Ext.define('TM.view.plan.AssignablesWindow', {
2
+ extend: 'Ext.window.Window',
3
+ requires: ['TM.view.plan.SelectAssignables'],
4
+ xtype: 'plan_assignableswindow',
5
+
6
+ title: '选择执行人',
7
+ modal: true,
8
+
9
+ action: '',
10
+
11
+ width: 480,
12
+ height: 550,
13
+
14
+ layout: {
15
+ type: 'fit',
16
+ align: 'stretch'
17
+ },
18
+
19
+ items: [{
20
+ xtype: 'plan_selectassignables',
21
+ border: false
22
+ }]
23
+ });
@@ -0,0 +1,189 @@
1
+ Ext.define('TM.view.plan.Edit', {
2
+ extend: 'Ext.form.Panel',
3
+ xtype: 'plan_edit',
4
+
5
+ defaults: {
6
+ xtype: 'fieldset',
7
+ margin: '5 10'
8
+ },
9
+
10
+ assignees: [],
11
+
12
+ items: [{
13
+ id: 'editFillField',
14
+ title: '基本信息',
15
+ layout: {
16
+ type: 'table',
17
+ columns: 1
18
+ },
19
+ defaults: {
20
+ xtype: 'textfield',
21
+ labelAlign: 'right',
22
+ margin: '10 0',
23
+ width: 510
24
+ },
25
+
26
+ items: [{
27
+ fieldLabel: '计划名称',
28
+ name: 'name',
29
+ allowBlank: false
30
+ },{
31
+ fieldLabel: '计划执行人',
32
+ name: 'assignables',
33
+ id: 'editassignables',
34
+ readOnly: true
35
+ }, {
36
+ fieldLabel: '计划类型',
37
+ name: 'plan_type',
38
+ store: 'TM.store.Types',
39
+ editable: false,
40
+ valueField: 'value',
41
+ xtype: 'combo',
42
+ blankText: '请选择计划类型!',
43
+ allowBlank: false
44
+ }, {
45
+ fieldLabel: '横向指标',
46
+ name: 'dataX'
47
+ }, {
48
+ fieldLabel: '纵向指标',
49
+ name: 'dataY'
50
+ }, {
51
+ fieldLabel: '生效时间',
52
+ xtype: 'datefield',
53
+ editable: false,
54
+ anchor: '100%',
55
+ format: 'Y/m/d',
56
+ name: 'enabled_at',
57
+ id: 'editenabled_at'
58
+ }, {
59
+ fieldLabel: '完成前几天提醒',
60
+ id: 'edit_begin_to_remind',
61
+ emptyText: '计划完成前多少天开始提醒,此处为倒计时。',
62
+ value: '0',
63
+ name: 'begin_to_remind'
64
+ }, {
65
+ fieldLabel: '是否自动完成',
66
+ xtype: 'checkbox',
67
+ name: 'autocompletable'
68
+ }]
69
+ }, {
70
+ xtype: 'fieldset',
71
+ id: 'editSelectField',
72
+ title: '计划完成截至时限',
73
+ layout: {
74
+ type: 'table',
75
+ columns: 2
76
+ },
77
+ defaults: {
78
+ labelAlign: 'right',
79
+ },
80
+ items: [{
81
+ fieldLabel: '月',
82
+ id: 'edit_quarterly_month',
83
+ name: 'quarterly_month',
84
+ xtype: 'combo',
85
+ store: 'TM.store.QuarterlyMonths',
86
+ valueField: 'value',
87
+ editable: false
88
+ }, {
89
+ fieldLabel: '月',
90
+ id: 'edit_month',
91
+ name: 'month',
92
+ xtype: 'combo',
93
+ store: 'TM.store.Months',
94
+ valueField: 'value',
95
+ editable: false
96
+ }, {
97
+ fieldLabel: '日',
98
+ id: 'edit_weekly_day',
99
+ name: 'weekly_day',
100
+ store: 'TM.store.WeekDays',
101
+ valueField: 'value',
102
+ xtype: 'combo',
103
+ editable: false
104
+ }, {
105
+ fieldLabel: '日',
106
+ id: 'edit_day',
107
+ name: 'day',
108
+ store: 'TM.store.Days',
109
+ valueField: 'value',
110
+ xtype: 'combo',
111
+ editable: false
112
+ }, {
113
+ fieldLabel: '时',
114
+ id: 'edit_hour',
115
+ name: 'hour',
116
+ store: 'TM.store.Hours',
117
+ valueField: 'value',
118
+ xtype: 'combo',
119
+ editable: false
120
+ }, {
121
+ fieldLabel: '分',
122
+ id: 'edit_minute',
123
+ name: 'minute',
124
+ store: 'TM.store.Minutes',
125
+ valueField: 'value',
126
+ xtype: 'combo',
127
+ editable: false
128
+ }]
129
+ }],
130
+
131
+ buttons: [{
132
+ text: '更新',
133
+ formBind: true,
134
+ action: 'update'
135
+ }, {
136
+ text: '关闭',
137
+ action: 'close'
138
+ }],
139
+
140
+ showYearlyField: function() {
141
+ var fieldSet = this.getComponent('editSelectField');
142
+ fieldSet.getComponent('edit_quarterly_month').hide();
143
+ fieldSet.getComponent('edit_weekly_day').hide();
144
+ fieldSet.getComponent('edit_month').show();
145
+ fieldSet.getComponent('edit_day').show();
146
+ fieldSet.getComponent('edit_hour').show();
147
+ fieldSet.getComponent('edit_minute').show();
148
+ },
149
+
150
+ showMonthlyField: function() {
151
+ var fieldSet = this.getComponent('editSelectField');
152
+ fieldSet.getComponent('edit_quarterly_month').hide();
153
+ fieldSet.getComponent('edit_weekly_day').hide();
154
+ fieldSet.getComponent('edit_month').hide();
155
+ fieldSet.getComponent('edit_day').show();
156
+ fieldSet.getComponent('edit_hour').show();
157
+ fieldSet.getComponent('edit_minute').show();
158
+ },
159
+
160
+ showQuarterlyField: function() {
161
+ var fieldSet = this.getComponent('editSelectField');
162
+ fieldSet.getComponent('edit_quarterly_month').show();
163
+ fieldSet.getComponent('edit_weekly_day').hide();
164
+ fieldSet.getComponent('edit_month').hide();
165
+ fieldSet.getComponent('edit_day').show();
166
+ fieldSet.getComponent('edit_hour').show();
167
+ fieldSet.getComponent('edit_minute').show();
168
+ },
169
+
170
+ showWeeklyField: function() {
171
+ var fieldSet = this.getComponent('editSelectField');
172
+ fieldSet.getComponent('edit_quarterly_month').hide();
173
+ fieldSet.getComponent('edit_weekly_day').show();
174
+ fieldSet.getComponent('edit_month').hide();
175
+ fieldSet.getComponent('edit_day').hide();
176
+ fieldSet.getComponent('edit_hour').show();
177
+ fieldSet.getComponent('edit_minute').show();
178
+ },
179
+
180
+ showDailyField: function() {
181
+ var fieldSet = this.getComponent('editSelectField');
182
+ fieldSet.getComponent('edit_quarterly_month').hide();
183
+ fieldSet.getComponent('edit_weekly_day').hide();
184
+ fieldSet.getComponent('edit_month').hide();
185
+ fieldSet.getComponent('edit_day').hide();
186
+ fieldSet.getComponent('edit_hour').show();
187
+ fieldSet.getComponent('edit_minute').show();
188
+ }
189
+ });
@@ -0,0 +1,21 @@
1
+ Ext.define('TM.view.plan.EditWindow', {
2
+ extend: 'Ext.window.Window',
3
+ requires: ['TM.view.plan.Edit'],
4
+ xtype: 'plan_editwindow',
5
+
6
+ title: '修改计划',
7
+ modal: true,
8
+
9
+ width: 600,
10
+ height: 550,
11
+
12
+ layout: {
13
+ type: 'fit',
14
+ align: 'stretch'
15
+ },
16
+
17
+ items: [{
18
+ xtype: 'plan_edit',
19
+ border: false
20
+ }]
21
+ });
@@ -0,0 +1,92 @@
1
+ Ext.define('TM.view.plan.Grid', {
2
+ extend: 'Ext.ux.MultiSelectablePagingGrid',
3
+ xtype: 'plan_grid',
4
+
5
+ requires: [
6
+ 'Ext.ux.RowExpander'
7
+ ],
8
+
9
+ mixins: [
10
+ 'TM.helper.ApplicationHelper'
11
+ ],
12
+
13
+ store: 'TM.store.Plans',
14
+
15
+ tbar: [{
16
+ text: '添加',
17
+ iconCls: 'btn-add-icon',
18
+ action: 'add'
19
+ }, '-', {
20
+ text: '修改',
21
+ iconCls: 'btn-edit-icon',
22
+ action: 'edit'
23
+ }, '-', {
24
+ text: '删除',
25
+ iconCls: 'btn-delete-icon',
26
+ action: 'delete'
27
+ }],
28
+
29
+ plugins: [{
30
+ ptype: 'rowexpander',
31
+ rowBodyTpl: [
32
+ '<table class="data">',
33
+ '<tr>',
34
+ '<td rowspan="3" class="title">内容</td>',
35
+ '<td class="name">截止时间:</td>',
36
+ '<td class="value">第{[values.data.deadline_month == null ? 0 : values.data.deadline_month]}',
37
+ '个月,第{[values.data.deadline_day == null ? 0 : values.data.deadline_day]}天,',
38
+ '{data.deadline_hour}时{data.deadline_minute}分</td>',
39
+ '</tr>',
40
+ '<tr>',
41
+ '<td class="name">横向指标:</td>',
42
+ '<td class="value">{[values.data.x == null ? "" : values.data.x]}</td>',
43
+ '</tr>',
44
+ '<tr>',
45
+ '<td class="name">纵向指标:</td>',
46
+ '<td class="value">{[values.data.y == null ? "" : values.data.y]}</td>',
47
+ '</tr>',
48
+ '</table>',
49
+ ]
50
+ }],
51
+
52
+ columns: [{
53
+ text: '名称',
54
+ dataIndex: 'name',
55
+ flex: 2
56
+ }, {
57
+ text: '类型',
58
+ dataIndex: 'plan_type',
59
+ renderer: function(v, m, record) {
60
+ return this.translateType(v);
61
+ },
62
+ flex: 1
63
+ }, {
64
+ text: '执行者',
65
+ renderer: function(v, m, record) {
66
+ var names = new Array();
67
+ Ext.Array.forEach(record.get('assignees'), function(assignee, index, assignees) {names.push(assignee.name)});
68
+ return names.join(', ');
69
+ },
70
+ flex: 3
71
+ //}, {
72
+ //text: '最后任务生成时间',
73
+ //dataIndex: 'last_task_created_at',
74
+ //flex: 2
75
+ }, {
76
+ text: '生效时间',
77
+ renderer: function(v, m, record) {
78
+ return Ext.Date.format(record.get('enabled_at'), 'Y年m月j日 H:i:s');
79
+ },
80
+ flex: 2
81
+ }, {
82
+ text: '是否自动完成',
83
+ renderer: function(v, m, record) {
84
+ return record.get('autocompletable') == true ? '是' : '否';
85
+ },
86
+ flex: 1
87
+ }, {
88
+ text: '开始提醒天数',
89
+ dataIndex: 'begin_to_remind',
90
+ flex: 1
91
+ }]
92
+ });