diff options
Diffstat (limited to 'app/graphql/resolvers/timelog_resolver.rb')
-rw-r--r-- | app/graphql/resolvers/timelog_resolver.rb | 101 |
1 files changed, 74 insertions, 27 deletions
diff --git a/app/graphql/resolvers/timelog_resolver.rb b/app/graphql/resolvers/timelog_resolver.rb index 8ac30c4cb5d..14831a29d90 100644 --- a/app/graphql/resolvers/timelog_resolver.rb +++ b/app/graphql/resolvers/timelog_resolver.rb @@ -3,33 +3,50 @@ module Resolvers class TimelogResolver < BaseResolver include LooksAhead + include ResolvesIds type ::Types::TimelogType.connection_type, null: false argument :start_date, Types::TimeType, required: false, - description: 'List time logs within a date range where the logged date is equal to or after startDate.' + description: 'List timelogs within a date range where the logged date is equal to or after startDate.' argument :end_date, Types::TimeType, required: false, - description: 'List time logs within a date range where the logged date is equal to or before endDate.' + description: 'List timelogs within a date range where the logged date is equal to or before endDate.' argument :start_time, Types::TimeType, required: false, - description: 'List time-logs within a time range where the logged time is equal to or after startTime.' + description: 'List timelogs within a time range where the logged time is equal to or after startTime.' argument :end_time, Types::TimeType, required: false, - description: 'List time-logs within a time range where the logged time is equal to or before endTime.' + description: 'List timelogs within a time range where the logged time is equal to or before endTime.' + + argument :project_id, ::Types::GlobalIDType[::Project], + required: false, + description: 'List timelogs for a project.' + + argument :group_id, ::Types::GlobalIDType[::Group], + required: false, + description: 'List timelogs for a group.' + + argument :username, GraphQL::Types::String, + required: false, + description: 'List timelogs for a user.' def resolve_with_lookahead(**args) - build_timelogs + validate_args!(object, args) + + timelogs = object&.timelogs || Timelog.limit(GitlabSchema.default_max_page_size) if args.any? - validate_args!(args) - build_parsed_args(args) - validate_time_difference! - apply_time_filter + args = parse_datetime_args(args) + + timelogs = apply_user_filter(timelogs, args) + timelogs = apply_project_filter(timelogs, args) + timelogs = apply_time_filter(timelogs, args) + timelogs = apply_group_filter(timelogs, args) end apply_lookahead(timelogs) @@ -37,30 +54,32 @@ module Resolvers private - attr_reader :parsed_args, :timelogs - def preloads { note: [:note] } end - def validate_args!(args) - if args[:start_time] && args[:start_date] + def validate_args!(object, args) + if args.empty? && object.nil? + raise_argument_error('Provide at least one argument') + elsif args[:start_time] && args[:start_date] raise_argument_error('Provide either a start date or time, but not both') elsif args[:end_time] && args[:end_date] raise_argument_error('Provide either an end date or time, but not both') end end - def build_parsed_args(args) + def parse_datetime_args(args) if times_provided?(args) - @parsed_args = args + args else - @parsed_args = args.except(:start_date, :end_date) + parsed_args = args.except(:start_date, :end_date) - @parsed_args[:start_time] = args[:start_date].beginning_of_day if args[:start_date] - @parsed_args[:end_time] = args[:end_date].end_of_day if args[:end_date] + parsed_args[:start_time] = args[:start_date].beginning_of_day if args[:start_date] + parsed_args[:end_time] = args[:end_date].end_of_day if args[:end_date] + + parsed_args end end @@ -68,23 +87,51 @@ module Resolvers args[:start_time] && args[:end_time] end - def validate_time_difference! - return unless end_time_before_start_time? + def validate_time_difference!(args) + return unless end_time_before_start_time?(args) raise_argument_error('Start argument must be before End argument') end - def end_time_before_start_time? - times_provided?(parsed_args) && parsed_args[:end_time] < parsed_args[:start_time] + def end_time_before_start_time?(args) + times_provided?(args) && args[:end_time] < args[:start_time] end - def build_timelogs - @timelogs = Timelog.in_group(object) + def apply_project_filter(timelogs, args) + return timelogs unless args[:project_id] + + project = resolve_ids(args[:project_id], ::Types::GlobalIDType[::Project]) + timelogs.in_project(project) end - def apply_time_filter - @timelogs = timelogs.at_or_after(parsed_args[:start_time]) if parsed_args[:start_time] - @timelogs = timelogs.at_or_before(parsed_args[:end_time]) if parsed_args[:end_time] + def apply_group_filter(timelogs, args) + return timelogs unless args[:group_id] + + group = Group.find_by_id(resolve_ids(args[:group_id], ::Types::GlobalIDType[::Group])) + timelogs.in_group(group) + end + + def apply_user_filter(timelogs, args) + return timelogs unless args[:username] + + user = UserFinder.new(args[:username]).find_by_username! + timelogs.for_user(user) + end + + def apply_time_filter(timelogs, args) + return timelogs unless args[:start_time] || args[:end_time] + + validate_time_difference!(args) + + if args[:start_time] + timelogs = timelogs.at_or_after(args[:start_time]) + end + + if args[:end_time] + timelogs = timelogs.at_or_before(args[:end_time]) + end + + timelogs end def raise_argument_error(message) |