issue log time && ui of revision history

This commit is contained in:
zhijie 2013-07-23 15:45:41 +08:00
parent 448d2a4982
commit e60bd809d1
21 changed files with 931 additions and 95 deletions

View File

@ -25,11 +25,16 @@
2B9968AB1794F71B0086F115 /* OZLModelIssueCategory.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B9968AA1794F71B0086F115 /* OZLModelIssueCategory.m */; };
2B9968AF1794FC0A0086F115 /* OZLProjectCreateViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B9968AD1794FC0A0086F115 /* OZLProjectCreateViewController.m */; };
2B9968B417951A5C0086F115 /* OZLIssueCreateViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B9968B217951A5C0086F115 /* OZLIssueCreateViewController.m */; };
2BBE440F179E500E00FD9E20 /* OZLIssueLogtimeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BBE440E179E500E00FD9E20 /* OZLIssueLogtimeViewController.m */; };
2BBE4411179E503100FD9E20 /* OZLIssueLogtimeViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2BBE4410179E503100FD9E20 /* OZLIssueLogtimeViewController.storyboard */; };
2BBE4414179E586B00FD9E20 /* OZLModelTimeEntryActivity.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BBE4413179E586B00FD9E20 /* OZLModelTimeEntryActivity.m */; };
2BC4DD8C179928C80090F52C /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2BC4DD8B179928C80090F52C /* SenTestingKit.framework */; };
2BC4DD8D179928C80090F52C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5DB80591792F2BF0081662A /* UIKit.framework */; };
2BC4DD8E179928C80090F52C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5DB805B1792F2BF0081662A /* Foundation.framework */; };
2BC4DD94179928C80090F52C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2BC4DD92179928C80090F52C /* InfoPlist.strings */; };
2BC4DD97179928C80090F52C /* RedmineMobileUnitTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BC4DD96179928C80090F52C /* RedmineMobileUnitTest.m */; };
2BCBA81D179E292800E5FD46 /* OZLModelIssueJournal.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BCBA81C179E292800E5FD46 /* OZLModelIssueJournal.m */; };
2BCBA820179E2AA500E5FD46 /* OZLModelIssueJournalDetail.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BCBA81F179E2AA400E5FD46 /* OZLModelIssueJournalDetail.m */; };
2BCC0FCF179D5458003DFB44 /* OZLIssueHistoryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BCC0FCE179D5458003DFB44 /* OZLIssueHistoryViewController.m */; };
2BCC0FD2179D56BA003DFB44 /* OZLModelTimeEntries.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BCC0FD1179D56BA003DFB44 /* OZLModelTimeEntries.m */; };
2BCCA0541795312E00FA8B1A /* OZLConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BCCA0531795312E00FA8B1A /* OZLConstants.m */; };
@ -113,6 +118,11 @@
2B9968AD1794FC0A0086F115 /* OZLProjectCreateViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OZLProjectCreateViewController.m; path = ViewControllers/OZLProjectCreateViewController.m; sourceTree = "<group>"; };
2B9968B117951A5C0086F115 /* OZLIssueCreateViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OZLIssueCreateViewController.h; path = ViewControllers/OZLIssueCreateViewController.h; sourceTree = "<group>"; };
2B9968B217951A5C0086F115 /* OZLIssueCreateViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OZLIssueCreateViewController.m; path = ViewControllers/OZLIssueCreateViewController.m; sourceTree = "<group>"; };
2BBE440D179E500E00FD9E20 /* OZLIssueLogtimeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OZLIssueLogtimeViewController.h; path = ViewControllers/OZLIssueLogtimeViewController.h; sourceTree = "<group>"; };
2BBE440E179E500E00FD9E20 /* OZLIssueLogtimeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OZLIssueLogtimeViewController.m; path = ViewControllers/OZLIssueLogtimeViewController.m; sourceTree = "<group>"; };
2BBE4410179E503100FD9E20 /* OZLIssueLogtimeViewController.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = OZLIssueLogtimeViewController.storyboard; path = ViewControllers/OZLIssueLogtimeViewController.storyboard; sourceTree = "<group>"; };
2BBE4412179E586B00FD9E20 /* OZLModelTimeEntryActivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OZLModelTimeEntryActivity.h; path = Models/OZLModelTimeEntryActivity.h; sourceTree = "<group>"; };
2BBE4413179E586B00FD9E20 /* OZLModelTimeEntryActivity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OZLModelTimeEntryActivity.m; path = Models/OZLModelTimeEntryActivity.m; sourceTree = "<group>"; };
2BC4DD8A179928C80090F52C /* RedmineMobileUnitTest.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RedmineMobileUnitTest.octest; sourceTree = BUILT_PRODUCTS_DIR; };
2BC4DD8B179928C80090F52C /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
2BC4DD91179928C80090F52C /* RedmineMobileUnitTest-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RedmineMobileUnitTest-Info.plist"; sourceTree = "<group>"; };
@ -120,6 +130,10 @@
2BC4DD95179928C80090F52C /* RedmineMobileUnitTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RedmineMobileUnitTest.h; sourceTree = "<group>"; };
2BC4DD96179928C80090F52C /* RedmineMobileUnitTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RedmineMobileUnitTest.m; sourceTree = "<group>"; };
2BC4DD98179928C80090F52C /* RedmineMobileUnitTest-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RedmineMobileUnitTest-Prefix.pch"; sourceTree = "<group>"; };
2BCBA81B179E292800E5FD46 /* OZLModelIssueJournal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OZLModelIssueJournal.h; path = Models/OZLModelIssueJournal.h; sourceTree = "<group>"; };
2BCBA81C179E292800E5FD46 /* OZLModelIssueJournal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OZLModelIssueJournal.m; path = Models/OZLModelIssueJournal.m; sourceTree = "<group>"; };
2BCBA81E179E2AA400E5FD46 /* OZLModelIssueJournalDetail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OZLModelIssueJournalDetail.h; path = Models/OZLModelIssueJournalDetail.h; sourceTree = "<group>"; };
2BCBA81F179E2AA400E5FD46 /* OZLModelIssueJournalDetail.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OZLModelIssueJournalDetail.m; path = Models/OZLModelIssueJournalDetail.m; sourceTree = "<group>"; };
2BCC0FCD179D5458003DFB44 /* OZLIssueHistoryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OZLIssueHistoryViewController.h; path = ViewControllers/OZLIssueHistoryViewController.h; sourceTree = "<group>"; };
2BCC0FCE179D5458003DFB44 /* OZLIssueHistoryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OZLIssueHistoryViewController.m; path = ViewControllers/OZLIssueHistoryViewController.m; sourceTree = "<group>"; };
2BCC0FD0179D56BA003DFB44 /* OZLModelTimeEntries.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OZLModelTimeEntries.h; path = Models/OZLModelTimeEntries.h; sourceTree = "<group>"; };
@ -333,6 +347,9 @@
2B62D0E71796A8D800AC3C19 /* OZLIssueFilterViewController.m */,
2BCC0FCD179D5458003DFB44 /* OZLIssueHistoryViewController.h */,
2BCC0FCE179D5458003DFB44 /* OZLIssueHistoryViewController.m */,
2BBE440D179E500E00FD9E20 /* OZLIssueLogtimeViewController.h */,
2BBE440E179E500E00FD9E20 /* OZLIssueLogtimeViewController.m */,
2BBE4410179E503100FD9E20 /* OZLIssueLogtimeViewController.storyboard */,
);
name = Issue;
sourceTree = "<group>";
@ -514,6 +531,12 @@
2B9968AA1794F71B0086F115 /* OZLModelIssueCategory.m */,
2BCC0FD0179D56BA003DFB44 /* OZLModelTimeEntries.h */,
2BCC0FD1179D56BA003DFB44 /* OZLModelTimeEntries.m */,
2BCBA81B179E292800E5FD46 /* OZLModelIssueJournal.h */,
2BCBA81C179E292800E5FD46 /* OZLModelIssueJournal.m */,
2BCBA81E179E2AA400E5FD46 /* OZLModelIssueJournalDetail.h */,
2BCBA81F179E2AA400E5FD46 /* OZLModelIssueJournalDetail.m */,
2BBE4412179E586B00FD9E20 /* OZLModelTimeEntryActivity.h */,
2BBE4413179E586B00FD9E20 /* OZLModelTimeEntryActivity.m */,
);
name = Models;
sourceTree = "<group>";
@ -617,6 +640,7 @@
2B6F38341797A00A00D06F51 /* MLTableAlertButtonPressed@2x.png in Resources */,
2B6F38351797A00A00D06F51 /* MLTableAlertShadowMask.png in Resources */,
2B6F38361797A00A00D06F51 /* MLTableAlertShadowMask@2x.png in Resources */,
2BBE4411179E503100FD9E20 /* OZLIssueLogtimeViewController.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -690,6 +714,10 @@
2B6F38371797A00A00D06F51 /* MLTableAlert.m in Sources */,
2BCC0FCF179D5458003DFB44 /* OZLIssueHistoryViewController.m in Sources */,
2BCC0FD2179D56BA003DFB44 /* OZLModelTimeEntries.m in Sources */,
2BCBA81D179E292800E5FD46 /* OZLModelIssueJournal.m in Sources */,
2BCBA820179E2AA500E5FD46 /* OZLModelIssueJournalDetail.m in Sources */,
2BBE440F179E500E00FD9E20 /* OZLIssueLogtimeViewController.m in Sources */,
2BBE4414179E586B00FD9E20 /* OZLModelTimeEntryActivity.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -41,9 +41,9 @@
_name = [dic objectForKey:@"name"];
return self;
}
//-(NSMutableDictionary*) toParametersDic
//{
//
//}
-(NSMutableDictionary*) toParametersDic
{
return nil;
}
@end

View File

@ -0,0 +1,66 @@
//
// OZLModelIssueJournal.h
// RedmineMobile
//
// Created by lizhijie on 7/23/13.
// This code is distributed under the terms and conditions of the MIT license.
// Copyright (c) 2013 Zhijie Lee(onezeros.lee@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <Foundation/Foundation.h>
#import "OZLModelUser.h"
#import "OZLModelIssueJournalDetail.h"
/*
{
"id": 12353,
"user": {
"id": 20043,
"name": "wang lei"
},
"notes": "fdfcasvawefqwf\r\n\r\nasdfasd\r\nasdfasdf",
"created_on": "2013-07-22T08:47:47Z",
"details": [
{
"property": "attr",
"name": "done_ratio",
"old_value": "0",
"new_value": "20"
}
]
}
*/
@interface OZLModelIssueJournal : NSObject
@property(nonatomic) int index;
@property(nonatomic, strong) NSString* notes;
@property(nonatomic, strong) NSString* createdOn;
@property(nonatomic, strong) OZLModelUser* user;
@property(nonatomic, strong) NSArray* detailArray;
-(id)initWithDictionary:(NSDictionary*)dic;
-(NSMutableDictionary*) toParametersDic;
@end

View File

@ -0,0 +1,59 @@
//
// OZLModelIssueJournal.m
// RedmineMobile
//
// Created by lizhijie on 7/23/13.
// This code is distributed under the terms and conditions of the MIT license.
// Copyright (c) 2013 Zhijie Lee(onezeros.lee@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "OZLModelIssueJournal.h"
@implementation OZLModelIssueJournal
-(id)initWithDictionary:(NSDictionary*)dic
{
self = [super init];
if (!self) {
return nil;
}
_index = [[dic objectForKey:@"index"] intValue];
_notes = [dic objectForKey:@"notes"];
_createdOn = [dic objectForKey:@"created_on"];
_user = [[ OZLModelUser alloc] initWithDictionary:[dic objectForKey:@"user"]];
NSMutableArray* detailItems = [[NSMutableArray alloc] init];
NSArray* dataArray = [dic objectForKey:@"details"];
for (NSDictionary* detailDic in dataArray) {
[detailItems addObject:[[OZLModelIssueJournalDetail alloc] initWithDictionary:detailDic]];
}
_detailArray = detailItems;
return self;
}
-(NSMutableDictionary*) toParametersDic
{
return nil;
}
@end

View File

@ -0,0 +1,51 @@
//
// OZLModelIssueJournalDetail.h
// RedmineMobile
//
// Created by lizhijie on 7/23/13.
// This code is distributed under the terms and conditions of the MIT license.
// Copyright (c) 2013 Zhijie Lee(onezeros.lee@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <Foundation/Foundation.h>
/*
"details": [
{
"property": "attr",
"name": "done_ratio",
"old_value": "0",
"new_value": "20"
}
]
*/
@interface OZLModelIssueJournalDetail : NSObject
@property(nonatomic, strong) NSString* property;
@property(nonatomic, strong) NSString* name;
@property(nonatomic, strong) NSString* oldValue;
@property(nonatomic, strong) NSString* freshValue;
-(id)initWithDictionary:(NSDictionary*)dic;
-(NSMutableDictionary*) toParametersDic;
@end

View File

@ -0,0 +1,50 @@
//
// OZLModelIssueJournalDetail.m
// RedmineMobile
//
// Created by lizhijie on 7/23/13.
// This code is distributed under the terms and conditions of the MIT license.
// Copyright (c) 2013 Zhijie Lee(onezeros.lee@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "OZLModelIssueJournalDetail.h"
@implementation OZLModelIssueJournalDetail
-(id)initWithDictionary:(NSDictionary*)dic
{
self = [super init];
if (!self) {
return nil;
}
_name = [dic objectForKey:@"name"];
_property = [dic objectForKey:@"property"];
_oldValue = [dic objectForKey:@"old_value"];
_freshValue = [dic objectForKey:@"new_value"];
return self;
}
-(NSMutableDictionary*) toParametersDic
{
return nil;
}
@end

View File

@ -31,6 +31,7 @@
#import "OZLModelProject.h"
#import "OZLModelIssue.h"
#import "OZLModelUser.h"
#import "OZLModelTimeEntryActivity.h"
@interface OZLModelTimeEntries : NSObject
@ -39,6 +40,7 @@
@property(nonatomic, strong) OZLModelProject* project;
@property(nonatomic, strong) OZLModelUser* user;
@property(nonatomic, strong) OZLModelIssue* issue;
@property(nonatomic, strong) OZLModelTimeEntryActivity* activity;
@property(nonatomic) float hours;
@property(nonatomic, strong) NSString* comments;
@property(nonatomic, strong) NSString* spentOn;
@ -46,6 +48,7 @@
@property(nonatomic, strong) NSString* updatedOn;
-(id)initWithDictionary:(NSDictionary*)dic;
-(NSMutableDictionary*) toParametersDic;

View File

@ -38,9 +38,22 @@
return nil;
}
_index = [[dic objectForKey:@"id"] intValue];
_project = [[OZLModelProject alloc] initWithDictionary:[dic objectForKey:@"project"]];
_user = [[OZLModelUser alloc] initWithDictionary:[dic objectForKey:@"user"] ];
_issue = [[OZLModelIssue alloc] initWithDictionary:[dic objectForKey:@"issue"]];
id project = [dic objectForKey:@"project"];
if (project != nil) {
_project = [[OZLModelProject alloc] initWithDictionary:project];
}
id user = [dic objectForKey:@"user"];
if (user != nil) {
_user = [[OZLModelUser alloc] initWithDictionary: user];
}
id issue = [dic objectForKey:@"issue"];
if (issue != nil ) {
_issue = [[OZLModelIssue alloc] initWithDictionary:issue];
}
id activity = [dic objectForKey:@"activity"];
if (activity != nil) {
_activity = [[OZLModelTimeEntryActivity alloc] initWithDictionary:activity];
}
_hours = [[dic objectForKey:@"hours"] floatValue];
_comments = [dic objectForKey:@"comments"];
_spentOn = [dic objectForKey:@"spent_on"];
@ -51,7 +64,24 @@
-(NSMutableDictionary*) toParametersDic
{
NSMutableDictionary* entryDic = [[NSMutableDictionary alloc] init];
[entryDic setObject:[NSNumber numberWithFloat:_hours] forKey:@"hours"];//required
if (_issue) {
[entryDic setObject:[NSNumber numberWithInt:_issue.index] forKey:@"issue_id"];
}else if(_project){
[entryDic setObject:[NSNumber numberWithInt:_project.index] forKey:@"project_id"];
}
if (_spentOn) {
[entryDic setObject:_spentOn forKey:@"spent_on"];
}
if (_activity) {
[entryDic setObject:[NSNumber numberWithInt:_activity.index] forKey:@"activity_id"];
}
if (_comments) {
[entryDic setObject:_comments forKey:@"comments"];
}
return [[NSMutableDictionary alloc] initWithObjectsAndKeys:entryDic,@"time_entry",nil];
}

View File

@ -0,0 +1,39 @@
//
// OZLModelTimeEntryActivity.h
// RedmineMobile
//
// Created by lizhijie on 7/23/13.
// This code is distributed under the terms and conditions of the MIT license.
// Copyright (c) 2013 Zhijie Lee(onezeros.lee@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <Foundation/Foundation.h>
@interface OZLModelTimeEntryActivity : NSObject
@property(nonatomic) int index;
@property(nonatomic,strong) NSString* name;
-(id)initWithDictionary:(NSDictionary*)dic;
-(NSMutableDictionary*) toParametersDic;
@end

View File

@ -0,0 +1,48 @@
//
// OZLModelTimeEntryActivity.m
// RedmineMobile
//
// Created by lizhijie on 7/23/13.
// This code is distributed under the terms and conditions of the MIT license.
// Copyright (c) 2013 Zhijie Lee(onezeros.lee@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "OZLModelTimeEntryActivity.h"
@implementation OZLModelTimeEntryActivity
-(id)initWithDictionary:(NSDictionary*)dic
{
self = [super init];
if (!self) {
return nil;
}
_index = [[dic objectForKey:@"id"] intValue];
_name = [dic objectForKey:@"name"];
return self;
}
-(NSMutableDictionary*) toParametersDic
{
return nil;
}
@end

View File

@ -33,6 +33,10 @@
#import "OZLModelIssueStatus.h"
#import "OZLModelTracker.h"
#import "OZLModelUser.h"
#import "OZLModelTimeEntries.h"
#import "OZLModelIssueJournal.h"
#import "OZLModelIssueJournalDetail.h"
#import "OZLModelTimeEntryActivity.h"
@interface OZLNetwork : NSObject
@ -50,6 +54,7 @@
+(void)createIssue:(OZLModelIssue*)issueData withParams:(NSDictionary*)params andBlock:(void (^)(BOOL success, NSError *error))block;
+(void)updateIssue:(OZLModelIssue*)issueData withParams:(NSDictionary*)params andBlock:(void (^)(BOOL success, NSError *error))block;
+(void)deleteIssue:(int)issueid withParams:(NSDictionary*)params andBlock:(void (^)(BOOL success, NSError *error))block;
+(void)getJournalListForIssue:(int)issueid withParams:(NSDictionary*)params andBlock:(void (^)(NSArray *result, NSError *error))block;
// priority
+(void)getPriorityListWithParams:(NSDictionary*)params andBlock:(void (^)(NSArray *result, NSError *error))block;
@ -64,4 +69,8 @@
+(void)getTimeEntriesWithParams:(NSDictionary*)params andBlock:(void (^)(NSArray *result, NSError *error))block;
+(void)getTimeEntriesForIssueId:(int)issueid withParams:(NSDictionary*)params andBlock:(void (^)(NSArray *result, NSError *error))block;
+(void)getTimeEntriesForProjectId:(int)projectid withParams:(NSDictionary*)params andBlock:(void (^)(NSArray *result, NSError *error))block;
+(void)getTimeEntryListWithParams:(NSDictionary*)params andBlock:(void (^)(NSArray *result, NSError *error))block;
+(void)createTimeEntry:(OZLModelTimeEntries*)timeEntry withParams:(NSDictionary*)params andBlock:(void (^)(BOOL success, NSError *error))block;
@end

View File

@ -335,6 +335,37 @@
}];
}
+(void)getJournalListForIssue:(int)issueid withParams:(NSDictionary*)params andBlock:(void (^)(NSArray *result, NSError *error))block
{
NSString* path = [NSString stringWithFormat:@"/issues/%d.json?include=journals",issueid];
NSMutableDictionary* paramsDic = [[NSMutableDictionary alloc] initWithDictionary:params];
NSString* accessKey = [[OZLSingleton sharedInstance] redmineUserKey];
if (accessKey.length > 0) {
[paramsDic setObject:accessKey forKey:@"key"];
}
[[OZLNetworkBase sharedClient] getPath:path parameters:paramsDic success:^(AFHTTPRequestOperation *operation, id responseObject) {
if (block) {
NSLog(@"the repsonse:%@",responseObject);
NSMutableArray* journals = [[NSMutableArray alloc] init];
NSArray* journalsDic = [[responseObject objectForKey:@"issue"] objectForKey:@"journals"];
for (NSDictionary* p in journalsDic) {
[journals addObject:[[OZLModelIssueJournal alloc] initWithDictionary:p]];
}
block(journals,nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (block) {
block([NSArray array], error);
}
}];
}
#pragma mark -
#pragma mark priority api
@ -495,7 +526,7 @@
NSArray* dic = [responseObject objectForKey:@"time_entries"];
for (NSDictionary* p in dic) {
[priorities addObject:[[OZLModelTracker alloc] initWithDictionary:p]];
[priorities addObject:[[OZLModelTimeEntries alloc] initWithDictionary:p]];
}
block(priorities,nil);
}
@ -511,11 +542,75 @@
+(void)getTimeEntriesForIssueId:(int)issueid withParams:(NSDictionary*)params andBlock:(void (^)(NSArray *result, NSError *error))block
{
NSDictionary* param = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithInt:issueid],@"issue_id", nil];
[OZLNetwork getTimeEntriesWithParams:param andBlock:block];
}
+(void)getTimeEntriesForProjectId:(int)projectid withParams:(NSDictionary*)params andBlock:(void (^)(NSArray *result, NSError *error))block
{
NSDictionary* param = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithInt:projectid],@"project_id", nil];
[OZLNetwork getTimeEntriesWithParams:param andBlock:block];
}
+(void)getTimeEntryListWithParams:(NSDictionary*)params andBlock:(void (^)(NSArray *result, NSError *error))block
{
NSString* path = @"/enumerations/time_entry_activities.json";
NSMutableDictionary* paramsDic = [[NSMutableDictionary alloc] initWithDictionary:params];
NSString* accessKey = [[OZLSingleton sharedInstance] redmineUserKey];
if (accessKey.length > 0) {
[paramsDic setObject:accessKey forKey:@"key"];
}
[[OZLNetworkBase sharedClient] setAuthorizationHeader];
[[OZLNetworkBase sharedClient] getPath:path parameters:paramsDic success:^(AFHTTPRequestOperation *operation, id responseObject) {
if (block) {
NSLog(@"the repsonse:%@",responseObject);
NSMutableArray* activities = [[NSMutableArray alloc] init];
NSArray* dic = [responseObject objectForKey:@"time_entry_activities"];
for (NSDictionary* p in dic) {
[activities addObject:[[OZLModelTimeEntryActivity alloc] initWithDictionary:p]];
}
block(activities,nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (block) {
block([NSArray array], error);
}
}];
}
+(void)createTimeEntry:(OZLModelTimeEntries*)timeEntry withParams:(NSDictionary*)params andBlock:(void (^)(BOOL success, NSError *error))block
{
NSString* path = [NSString stringWithFormat:@"/time_entries.json"];
//project info
NSMutableDictionary* paramsDic = [[NSMutableDictionary alloc] initWithDictionary:params];
[paramsDic addEntriesFromDictionary:[timeEntry toParametersDic]];
NSString* accessKey = [[OZLSingleton sharedInstance] redmineUserKey];
if (accessKey.length > 0) {
[paramsDic setObject:accessKey forKey:@"key"];
}
[[OZLNetworkBase sharedClient] postPath:path parameters:paramsDic success:^(AFHTTPRequestOperation *operation, id responseObject) {
if (block) {
NSLog(@"the repsonse:%@",responseObject);
block(YES,nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (block) {
block(NO, error);
}
}];
}
@end

View File

@ -90,7 +90,7 @@
UIToolbar* inputAccessoryView = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 40)];
UIBarButtonItem* accessoryDoneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(accessoryDoneClicked:)];
UIBarButtonItem* flexleft = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
inputAccessoryView.items = [NSArray arrayWithObjects:flexleft, accessoryDoneButton, nil];;
inputAccessoryView.items = [NSArray arrayWithObjects:flexleft, accessoryDoneButton, nil];
_startDateLabel.inputView = datePicker;
_startDateLabel.inputAccessoryView = inputAccessoryView;
@ -288,16 +288,16 @@
}else if( indexPath.section == 2){
switch (indexPath.row) {
case 0:{//start date
[_startDateLabel becomeFirstResponder];
}break;
case 1:{//due date
[_dueDateLabel becomeFirstResponder];
}break;
case 2:{//estimated hours
[_estimatedHoursLabel becomeFirstResponder];
}break;
case 3:{//done
[_doneProgressLabel becomeFirstResponder];
}break;
default:

View File

@ -28,9 +28,13 @@
#import <UIKit/UIKit.h>
#import "OZLModelIssue.h"
#import "OZLModelTimeEntryActivity.h"
@interface OZLIssueDetailViewController : UITableViewController
@property(nonatomic,strong) OZLModelIssue* issueData;
@property(nonatomic, strong) OZLModelIssue* issueData;
@property(nonatomic, strong) NSArray* timeEntryActivityList;
@property (weak, nonatomic) IBOutlet UILabel *subject;
@property (weak, nonatomic) IBOutlet UILabel *description;
@property (weak, nonatomic) IBOutlet UIProgressView *progressbar;

View File

@ -27,6 +27,8 @@
// THE SOFTWARE.
#import "OZLIssueDetailViewController.h"
#import "OZLIssueHistoryViewController.h"
#import "OZLIssueLogtimeViewController.h"
@interface OZLIssueDetailViewController ()
@ -81,16 +83,22 @@
{
if (indexPath.section == 1) {
switch (indexPath.row) {
case 0:{
case 0:{//history
OZLIssueHistoryViewController* history = [[OZLIssueHistoryViewController alloc] init];
[history setIssueData:_issueData];
[self.navigationController pushViewController:history animated:YES];
}break;
case 1:{
case 1:{// add sub task
}break;
case 2:{
case 2:{//logtime
UIStoryboard *tableViewStoryboard = [UIStoryboard storyboardWithName:@"OZLIssueLogtimeViewController" bundle:nil];
OZLIssueLogtimeViewController* creator = [tableViewStoryboard instantiateViewControllerWithIdentifier:@"OZLIssueLogtimeViewController"];
[creator setTimeEntryActivityList:_timeEntryActivityList];
[creator setIssueData:_issueData];
[self.navigationController pushViewController:creator animated:YES];
}break;
default:
break;
}

View File

@ -28,8 +28,15 @@
#import "OZLIssueHistoryViewController.h"
#import "MBProgressHUD.h"
#import "OZLNetwork.h"
#import "OZLModelIssueJournal.h"
#import "OZLModelIssueJournalDetail.h"
@interface OZLIssueHistoryViewController ()
@interface OZLIssueHistoryViewController () {
MBProgressHUD* _HUD;
NSMutableArray* _journalList;
}
@end
@ -54,9 +61,27 @@
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
_HUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:_HUD];
_HUD.labelText = @"Refreshing...";
[self.navigationItem setTitle:_issueData.subject];
}
-(void) viewWillAppear:(BOOL)animated
{
[_HUD show:YES];
// refresh journal list
[OZLNetwork getJournalListForIssue:_issueData.index withParams:nil andBlock:^(NSArray *result, NSError *error) {
NSLog(@"respond:%@",result.description);
_journalList = [[NSMutableArray alloc] initWithArray: result];
[self.tableView reloadData];
[_HUD hide:YES];
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
@ -67,78 +92,25 @@
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 0;
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
// Return the number of rows in the section.
return 0;
return _journalList.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
static NSString *CellIdentifier = @"timeEntryCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
if (!cell) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
OZLModelIssueJournal* journal = [_journalList objectAtIndex:indexPath.row];
cell.textLabel.text = journal.user.name;
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
*/
}
@end

View File

@ -0,0 +1,23 @@
//
// OZLIssueLogtimeViewController.h
// RedmineMobile
//
// Created by lizhijie on 7/23/13.
// Copyright (c) 2013 Lee Zhijie. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "OZLModelIssue.h"
#import "OZLModelTimeEntryActivity.h"
@interface OZLIssueLogtimeViewController : UITableViewController
@property (nonatomic, strong) OZLModelIssue* issueData;
@property (nonatomic, strong) NSArray* timeEntryActivityList;
@property (weak, nonatomic) IBOutlet UITextField *hours;
@property (weak, nonatomic) IBOutlet UITextField *activity;
@property (weak, nonatomic) IBOutlet UITextField *dateLabel;
@property (weak, nonatomic) IBOutlet UITextView *comment;
@end

View File

@ -0,0 +1,194 @@
//
// OZLIssueLogtimeViewController.m
// RedmineMobile
//
// Created by lizhijie on 7/23/13.
// Copyright (c) 2013 Lee Zhijie. All rights reserved.
//
#import "OZLIssueLogtimeViewController.h"
#import "MBProgressHUD.h"
#import "MLTableAlert.h"
#import "OZLNetwork.h"
@interface OZLIssueLogtimeViewController () {
MBProgressHUD* _HUD;
float _hourValue;
OZLModelTimeEntries* _entry;
}
@end
@implementation OZLIssueLogtimeViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// initialize data
_hourValue = 0;
_entry = [[OZLModelTimeEntries alloc] init];
UIBarButtonItem* cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(onCancel:)];
[self.navigationItem setLeftBarButtonItem:cancelBtn];
UIBarButtonItem* saveBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(onSave:)];
[self.navigationItem setRightBarButtonItem:saveBtn];
[self.navigationItem setTitle:@"Log Time"];
[self setupInputViews];
// hud
_HUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:_HUD];
_HUD.labelText = @"Loading...";
}
-(void)setupInputViews
{
[_activity setUserInteractionEnabled:NO];
// setup time picker inputview
UIDatePicker* timerPicker = [[UIDatePicker alloc]init];
[timerPicker setDatePickerMode:UIDatePickerModeCountDownTimer];
[timerPicker addTarget:self action:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
timerPicker.minuteInterval = 5;
// setup datapicker inputview
UIDatePicker* datePicker = [[UIDatePicker alloc]init];
[datePicker setDatePickerMode:UIDatePickerModeDate];
[datePicker addTarget:self action:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
// accessoryview
UIToolbar* inputAccessoryView = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 40)];
UIBarButtonItem* accessoryDoneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(accessoryDoneClicked:)];
UIBarButtonItem* flexleft = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
inputAccessoryView.items = [NSArray arrayWithObjects:flexleft, accessoryDoneButton, nil];
_hours.inputView = timerPicker;
_hours.inputAccessoryView = inputAccessoryView;
_dateLabel.inputView = datePicker;
_dateLabel.inputAccessoryView = inputAccessoryView;
}
-(void) onCancel:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
-(void) onSave:(id)sender
{
_HUD.mode = MBProgressHUDModeIndeterminate;
_HUD.labelText = @"Logging time ...";
[_HUD show:YES];
// build entry
_entry.issue = _issueData;
_entry.hours = _hourValue;
if (_comment.text.length > 0) {
_entry.comments = _comment.text;
}
if (_dateLabel.text.length > 0) {
_entry.createdOn = _dateLabel.text;
}
[OZLNetwork createTimeEntry:_entry withParams:nil andBlock:^(BOOL success, NSError *error){
if (error) {
NSLog(@"log time error: %@",error.description);
}else {
[self.navigationController popViewControllerAnimated:YES];
}
[_HUD hide:YES];
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0 && indexPath.row == 1) {//activity
MLTableAlert* tableAlert = [MLTableAlert tableAlertWithTitle:@"Activty" cancelButtonTitle:@"Cancel" numberOfRows:^NSInteger (NSInteger section)
{
return [_timeEntryActivityList count] + 1;
}
andCells:^UITableViewCell* (MLTableAlert *anAlert, NSIndexPath *alertIndexPath)
{
static NSString *CellIdentifier = @"CellIdentifier";
UITableViewCell *cell = [anAlert.table dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
if (alertIndexPath.row == 0) {
cell.textLabel.text = @"None";
}else {
cell.textLabel.text = [[_timeEntryActivityList objectAtIndex:alertIndexPath.row - 1] name];
}
return cell;
}];
// Setting custom alert height
tableAlert.height = 350;
// configure actions to perform
[tableAlert configureSelectionBlock:^(NSIndexPath *selectedIndex){
if (selectedIndex.row == 0) {
_activity.text = @"None";
_entry.activity = nil;
}else {
_activity.text = [[ _timeEntryActivityList objectAtIndex:selectedIndex.row - 1] name];
_entry.activity = [_timeEntryActivityList objectAtIndex:selectedIndex.row -1];
}
[_activity sizeToFit];
} andCompletionBlock:^{
}];
[tableAlert show];
}
}
- (void)viewDidUnload {
[self setHours:nil];
[self setActivity:nil];
[self setDateLabel:nil];
[self setComment:nil];
[super viewDidUnload];
}
#pragma mark data picker value changed
-(void)datePickerValueChanged:(id)sender
{
UIDatePicker* datepicker = (UIDatePicker*)sender;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
if (_hours.isFirstResponder) {
NSString* timeStr = [NSString stringWithFormat:@"%d Mins",(int)datepicker.countDownDuration/60];
_hours.text = timeStr;
_hourValue = (int)(datepicker.countDownDuration/3600.f);
}else {
[dateFormatter setDateFormat:@"yyyy-MM-dd"];
NSString* dateStr = [dateFormatter stringFromDate:datepicker.date];
_dateLabel.text = dateStr;
}
}
-(void)accessoryDoneClicked:(id)sender
{
[self.view endEditing:YES];
}
@end

View File

@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="2.0" toolsVersion="3084" systemVersion="11G63" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="Y1n-hd-Xzh">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="2083"/>
</dependencies>
<scenes>
<!--Issue Logtime View Controller-->
<scene sceneID="4a8-6A-Jvc">
<objects>
<tableViewController storyboardIdentifier="OZLIssueLogtimeViewController" useStoryboardIdentifierAsRestorationIdentifier="YES" id="Y1n-hd-Xzh" customClass="OZLIssueLogtimeViewController" sceneMemberID="viewController">
<tableView key="view" opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="singleLineEtched" rowHeight="44" sectionHeaderHeight="10" sectionFooterHeight="10" id="AwV-ne-sqM">
<rect key="frame" x="0.0" y="64" width="320" height="504"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
<sections>
<tableViewSection headerTitle="Log time for Issue" id="NHu-XP-Dl8">
<cells>
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" id="yRz-4G-JYz">
<rect key="frame" x="0.0" y="46" width="320" height="45"/>
<autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="10" y="1" width="300" height="43"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Hours" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="715-mq-jZy">
<rect key="frame" x="20" y="11" width="61" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<color key="highlightedColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</label>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" minimumFontSize="17" id="5hZ-Ny-ipF">
<rect key="frame" x="89" y="7" width="191" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="textColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
</textField>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" id="xpw-8N-Bk3">
<rect key="frame" x="0.0" y="91" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="10" y="0.0" width="300" height="43"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Activity" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="7SE-fh-nDW">
<rect key="frame" x="20" y="11" width="61" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<color key="highlightedColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</label>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" minimumFontSize="17" id="gqS-Eg-4oB">
<rect key="frame" x="89" y="7" width="191" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="textColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
</textField>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" id="O63-Tl-6H4">
<rect key="frame" x="0.0" y="135" width="320" height="45"/>
<autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="10" y="0.0" width="300" height="43"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Date" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="WJI-e1-LjU">
<rect key="frame" x="20" y="11" width="61" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<color key="highlightedColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</label>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" minimumFontSize="17" id="m0h-uj-KYA">
<rect key="frame" x="89" y="7" width="191" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="textColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
</textField>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
</tableViewCell>
</cells>
</tableViewSection>
<tableViewSection headerTitle="Comment" id="R5b-q8-l9R">
<cells>
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" rowHeight="98" id="rJD-Wu-rig">
<rect key="frame" x="0.0" y="226" width="320" height="100"/>
<autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="10" y="1" width="300" height="97"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" id="DKg-Ux-yxJ">
<rect key="frame" x="7" y="5" width="286" height="87"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
</tableViewCell>
</cells>
</tableViewSection>
</sections>
<connections>
<outlet property="dataSource" destination="Y1n-hd-Xzh" id="PlF-Ol-Ea7"/>
<outlet property="delegate" destination="Y1n-hd-Xzh" id="aqW-BZ-8qX"/>
</connections>
</tableView>
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/>
<connections>
<outlet property="activity" destination="gqS-Eg-4oB" id="u7L-l8-tPM"/>
<outlet property="comment" destination="DKg-Ux-yxJ" id="X4h-1x-sE9"/>
<outlet property="dateLabel" destination="m0h-uj-KYA" id="3Sa-Pc-bHL"/>
<outlet property="hours" destination="5hZ-Ny-ipF" id="btM-cc-1oG"/>
</connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="lhm-m1-RSV" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="229" y="-15"/>
</scene>
</scenes>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>

View File

@ -36,9 +36,10 @@
- (IBAction)onSortSetting:(id)sender;
@property (weak, nonatomic) NSArray* trackerList;
@property (weak, nonatomic) NSArray* priorityList;
@property (weak, nonatomic) NSArray* statusList;
@property (weak, nonatomic) NSArray* userList;
@property (strong, nonatomic) NSArray* trackerList;
@property (strong, nonatomic) NSArray* priorityList;
@property (strong, nonatomic) NSArray* statusList;
@property (strong, nonatomic) NSArray* userList;
@property (strong, nonatomic) NSArray* timeEntryActivityList;
@end

View File

@ -149,6 +149,7 @@
_issueListOption = [[NSMutableDictionary alloc] init];
static int doneCount = 0;
const int totalCount = 5;
[OZLNetwork getTrackerListWithParams:nil andBlock:^(NSArray *result, NSError *error) {
if (!error) {
_trackerList = result;
@ -156,7 +157,7 @@
NSLog(@"get tracker list error : %@",error.description);
}
doneCount ++;
if (doneCount == 4) {
if (doneCount == totalCount) {
[self loadProjectDetail];
doneCount = 0;
}
@ -169,7 +170,7 @@
NSLog(@"get issue status list error : %@",error.description);
}
doneCount ++;
if (doneCount == 4) {
if (doneCount == totalCount) {
[self loadProjectDetail];
doneCount = 0;
}
@ -181,7 +182,7 @@
NSLog(@"get priority list error : %@",error.description);
}
doneCount ++;
if (doneCount == 4) {
if (doneCount == totalCount) {
[self loadProjectDetail];
doneCount = 0;
}
@ -193,7 +194,20 @@
NSLog(@"get user list error : %@",error.description);
}
doneCount ++;
if (doneCount == 4) {
if (doneCount == totalCount) {
[self loadProjectDetail];
doneCount = 0;
}
}];
[OZLNetwork getTimeEntryListWithParams:nil andBlock:^(NSArray *result, NSError *error) {
if (!error) {
_timeEntryActivityList = result;
}else {
NSLog(@"get user list error : %@",error.description);
}
doneCount ++;
if (doneCount == totalCount) {
[self loadProjectDetail];
doneCount = 0;
}
@ -340,6 +354,7 @@
UIStoryboard *tableViewStoryboard = [UIStoryboard storyboardWithName:@"OZLIssueDetailViewController" bundle:nil];
OZLIssueDetailViewController* detail = [tableViewStoryboard instantiateViewControllerWithIdentifier:@"OZLIssueDetailViewController"];
[detail setIssueData:[_issuesList objectAtIndex:indexPath.row]];
[detail setTimeEntryActivityList:_timeEntryActivityList];
[self.navigationController pushViewController:detail animated:YES];
}