123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- module Gql::Queries
- class AutocompleteSearch::Ticket < BaseQuery
- description 'Search for tickets'
- argument :input, Gql::Types::Input::AutocompleteSearch::TicketInputType, required: true, description: 'The input object for the autocomplete search'
- type [Gql::Types::AutocompleteSearch::TicketEntryType], null: false
- def self.authorize(_obj, ctx)
- ctx.current_user.permissions?('ticket.agent')
- end
- def resolve(input:)
- # TODO: check if change permission is correct for all usages or if we maybe need a argument from outside for this
- search_tickets(
- query: input.query,
- limit: input.limit || 10,
- except_ticket_internal_id: input.except_ticket_internal_id
- ).map { |t| coerce_to_result(t) }
- end
- def search_tickets(query:, limit:, except_ticket_internal_id:)
- return search_db(limit: limit, except_ticket_internal_id:) if query.strip.empty?
- search_index(query: query, limit: limit, except_ticket_internal_id:)
- end
- def search_db(limit:, except_ticket_internal_id:)
- TicketPolicy::ChangeScope.new(context.current_user).resolve.where.not(state_id: ignore_state_ids).where.not(id: except_ticket_internal_id).reorder(created_at: :desc).limit(limit)
- end
- def search_index(query:, limit:, except_ticket_internal_id:)
- # We have to filter out the states afterwards, because the search method can only handle either query OR condition.
- ::Ticket.search(
- current_user: context.current_user,
- query: query,
- scope: TicketPolicy::ChangeScope,
- limit: limit,
- sort_by: 'created_at',
- order_by: 'desc',
- ).reject do |ticket|
- ignore_state_ids.include?(ticket.state_id) || except_ticket_internal_id == ticket.id
- end
- end
- def coerce_to_result(ticket)
- {
- value: Gql::ZammadSchema.id_from_object(ticket),
- label: "#{ticket_hook}#{ticket.number} - #{ticket.title}",
- heading: ticket.customer.fullname,
- ticket: ticket,
- }
- end
- private
- def ignore_state_ids
- # TODO: needs this to be more generic?
- ::Ticket::State.where(state_type_id: ::Ticket::StateType.where(name: %w[merged removed]).map(&:id)).map(&:id)
- end
- def ticket_hook
- @ticket_hook ||= Setting.get('ticket_hook')
- end
- end
- end
|