12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- # Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
- module Gql::Queries
- class Tickets::Cached::ByOverview < BaseQuery
- include Gql::Concerns::HandlesOverviewCaching
- description 'Fetch tickets of a given ticket overview'
- # These arguments (and the ones from pagination such as first:) are part of the cache key.
- argument :overview_id, GraphQL::Types::ID, loads: Gql::Types::OverviewType, description: 'Overview ID'
- argument :order_by, String, required: false, description: 'Set a custom order by'
- argument :order_direction, Gql::Types::Enum::OrderDirectionType, required: false, description: 'Set a custom order direction'
- argument :cache_ttl, Integer do
- description 'How long to cache the overview data, in seconds. This will be part of the cache key so that different durations get different caches.'
- end
- # The following arguments will not be part of the cache key.
- argument :renew_cache, Boolean, required: false, description: 'Force a refresh of the cache content.'
- argument :known_collection_signature, String, required: false do
- description 'Signature of a known collection state on the front end. If there is the same state still on the server, it will not return edges data.'
- end
- type Gql::Types::TicketType.custom_connection_type(type_class: Gql::Types::BaseCachedConnection, type_name: 'CachedTicketConnection'), null: false
- def self.register_in_schema(schema)
- schema.field graphql_field_name, resolver: self do
- # Frontend needs to fetch all visible tickets at once, that can be up to 1000.
- # Reduce the calculated complexity to make this possible for the current query.
- complexity lambda { |_ctx, _args, child_complexity|
- (child_complexity / 10).to_i
- }
- end
- end
- def resolve(cache_ttl:, overview:, renew_cache: false, order_by: nil, order_direction: nil, known_collection_signature: nil)
- if renew_cache
- context.scoped_set!(:renew_cache, true)
- end
- maybe_cached_value(cache_ttl:, overview:, order_by:, order_direction:)
- end
- def maybe_cached_value(cache_ttl:, overview:, order_by:, order_direction:)
- cache_fragment(path_cache_key: filtered_path_cache_key, object_cache_key: object_cache_key(overview), expires_in: cache_ttl) do
- # This will fetch tickets with 'overview' permissions, which logically include 'read' permissions.
- ::Ticket::Overviews.tickets_for_overview(overview, context.current_user, order_by: order_by, order_direction: order_direction)
- end
- end
- # We need to arguments. This can currently only be achieved with a hack,
- # see https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/issues/133 (perhaps it can be improved
- # after this is solved).
- def filtered_path_cache_key
- GraphQL::FragmentCache::CacheKeyBuilder.new(query: context.query, path: context.current_path).send(:path_cache_key)
- .sub(%r{,renew_cache:(?:true|false)?}, '')
- end
- end
- end
|