<commit_before>View = require './view'

Request = require '../models/Request'

class RequestsView extends View

    templateRequestsAll: require './templates/requestsAll'
    templateRequestsAllBody: require './templates/requestsAllBody'

    templateRequestsActive: require './templates/requestsActive'
    templateRequestsActiveBody: require './templates/requestsActiveBody'
    templateRequestsActiveFilter: require './templates/requestsActiveFilter'
    
    templateRequestsCooldown: require './templates/requestsCooldown'
    templateRequestsCooldownBody: require './templates/requestsCooldownBody'
    
    templateRequestsPaused: require './templates/requestsPaused'
    templateRequestsPausedBody: require './templates/requestsPausedBody'

    templateRequestsPending: require './templates/requestsPending'
    templateRequestsPendingBody: require './templates/requestsPendingBody'

    templateRequestsCleaning: require './templates/requestsCleaning'
    templateRequestsCleaningBody: require './templates/requestsCleaningBody'

    removeRequestTemplate: require './templates/vex/removeRequest'

    # Which table views have sub-filters (daemon, scheduled, on-demand)
    haveSubfilter: ['all', 'active', 'paused', 'cooldown']

    events:
        'click [data-action="viewJSON"]': 'viewJson'
        'click [data-action="remove"]': 'removeRequest'
        'click [data-action="unpause"]': 'unpauseRequest'
        'click [data-action="starToggle"]': 'toggleStar'
        'click [data-action="run-now"]': 'runRequest'
        'click [data-requests-active-filter]': 'changeFilters'

    initialize: ->
        @lastRequestsFilter = @options.requestsFilter
        @lastRequestsSubFilter = @options.requestsSubFilter

        if @lastRequestsFilter in @haveSubfilter
            @lastRequestsActiveSubFilter = @lastRequestsSubFilter

    fetch: ->
        @collection = switch @lastRequestsFilter
            when 'all'
                app.collections.requestsAll
            when 'active'
                app.collections.requestsActive
            when 'cooldown'
                app.collections.requestsCooldown
            when 'paused'
                app.collections.requestsPaused
            when 'pending'
                app.collections.requestsPending
            when 'cleaning'
                app.collections.requestsCleaning

        @collection.fetch()

    refresh: ->
        return @ if @$el.find('[data-sorted-direction]').length

        @fetch(@lastRequestsFilter).done =>
            @render(@lastRequestsFilter, @lastRequestsSubFilter, @lastSearchFilter, refresh = true)

        @

    render: (requestsFilter, requestsSubFilter, searchFilter, refresh) =>
        return @ unless @ is app.views.current

        forceFullRender = requestsFilter isnt @lastRequestsFilter

        @lastRequestsFilter = requestsFilter
        @lastSearchFilter = searchFilter
        @$el.find('input[type="search"]').val searchFilter

        if @lastRequestsFilter in @haveSubfilter
            if @lastRequestsActiveSubFilter
                @lastRequestsSubFilter = @lastRequestsActiveSubFilter
        else
            @lastRequestsSubFilter = requestsSubFilter

        if @lastRequestsFilter is 'all'
            @collection = app.collections.requestsAll
            template = @templateRequestsAll
            templateBody = @templateRequestsAllBody

        if @lastRequestsFilter is 'active'
            @collection = app.collections.requestsActive
            template = @templateRequestsActive
            templateBody = @templateRequestsActiveBody

        if @lastRequestsFilter is 'cooldown'
            @collection = app.collections.requestsCooldown
            template = @templateRequestsCooldown
            templateBody = @templateRequestsCooldownBody

        if @lastRequestsFilter is 'paused'
            @collection = app.collections.requestsPaused
            template = @templateRequestsPaused
            templateBody = @templateRequestsPausedBody

        # The following have filters
        if @lastRequestsFilter in @haveSubfilter
            templateFilter = @templateRequestsActiveFilter

        if @lastRequestsFilter is 'pending'
            @collection = app.collections.requestsPending
            template = @templateRequestsPending
            templateBody = @templateRequestsPendingBody

        if @lastRequestsFilter is 'cleaning'
            @collection = app.collections.requestsCleaning
            template = @templateRequestsCleaning
            templateBody = @templateRequestsCleaningBody

        context =
            collectionSynced: @collection.synced
            requestsSubFilter: requestsSubFilter
            searchFilter: searchFilter

        if @lastRequestsFilter is 'paused'
            context.requests = _.filter(_.pluck(@collection.models, 'attributes'), (r) => not r.scheduled and not r.onDemand)
            context.requestsScheduled = _.filter(_.pluck(@collection.models, 'attributes'), (r) => r.scheduled)
            context.requests.reverse()
            context.requestsScheduled.reverse()

        if @lastRequestsFilter in @haveSubfilter
            if requestsSubFilter is 'all'
                context.requests = _.pluck(@collection.models, 'attributes')

            else
                filterFunction = => false

                if requestsSubFilter is 'daemon'
                    filterFunction = (r) => not r.scheduled and not r.onDemand

                if requestsSubFilter is 'daemon-on-demand'
                    filterFunction = (r) => not r.scheduled

                if requestsSubFilter is 'daemon-scheduled'
                    filterFunction = (r) => not r.onDemand

                if requestsSubFilter is 'on-demand'
                    filterFunction = (r) => r.onDemand

                if requestsSubFilter is 'on-demand-scheduled'
                    filterFunction = (r) => r.onDemand or r.scheduled

                if requestsSubFilter is 'scheduled'
                    filterFunction = (r) => r.scheduled

                context.requests = _.filter(_.pluck(@collection.models, 'attributes'), filterFunction)

            context.requests.reverse()

        else
            context.requests = _.pluck(@collection.models, 'attributes')

        for request in context.requests
            if app.collections.requestsStarred.get(request.name)?
                request.starred = true

        partials =
            partials:
                requestsBody: templateBody

        $search = @$el.find('input[type="search"]')
        searchWasFocused = $search.is(':focus')

        $requestsBodyContainer =  @$el.find('[data-requests-body-container]')

        if templateFilter?
            partials.partials.requestsFilter = templateFilter
            $requestsFilterContainer =  @$el.find('[data-requests-filter-container]')

        if not $requestsBodyContainer.length or forceFullRender
            @$el.html template(context, partials)

        else
            if templateFilter?
                $requestsFilterContainer.html templateFilter context

            $requestsBodyContainer.html templateBody context

            @$el.find('input[type="search"]').val context.searchFilter

        @setUpSearchEvents(refresh, searchWasFocused)
        utils.setupSortableTables()

        @

    viewJson: (e) ->
        utils.viewJSON 'request', $(e.target).data('request-id')

    removeRequest: (e) ->
        $row = $(e.target).parents('tr')
        requestModel = @collection.get($(e.target).data('request-id'))

        if $(e.target).data('action-remove-type') is 'deletePaused'
            vex.dialog.confirm
                message: "<p>Are you sure you want to delete the paused request?</p><pre>#{ requestModel.get('id') }</pre>"
                callback: (confirmed) =>
                    return unless confirmed
                    $row.remove()
                    requestModel.deletePaused().done =>
                        delete app.allRequests[requestModel.get('id')]
                        @collection.remove(requestModel)

        else
            vex.dialog.confirm
                message: @removeRequestTemplate(requestId: requestModel.get('id'))
                buttons: [
                    $.extend({}, vex.dialog.buttons.YES, (text: 'Remove', className: 'vex-dialog-button-primary vex-dialog-button-primary-remove'))
                    vex.dialog.buttons.NO
                ]
                callback: (confirmed) =>
                    return unless confirmed
                    requestModel.destroy()
                    delete app.allRequests[requestModel.get('id')] # TODO - move to model on destroy?
                    @collection.remove(requestModel)
                    $row.remove()

    unpauseRequest: (e) ->
        $row = $(e.target).parents('tr')
        requestModel = @collection.get($(e.target).data('request-id'))

        vex.dialog.confirm
            message: "<p>Are you sure you want to unpause the request?</p><pre>#{ requestModel.get('id') }</pre>"
            callback: (confirmed) =>
                return unless confirmed
                
                if @lastRequestsFilter is "paused"
                    $row.remove()
                    
                requestModel.unpause().done =>
                    @refresh()
                        
    toggleStar: (e) ->
        $target = $(e.target)
        $table = $target.parents 'table'

        requestName = $target.data 'request-name'
        starred = $target.attr('data-starred') is 'true'

        app.collections.requestsStarred.toggle(requestName)
        $requests = $table.find("""[data-request-name="#{ requestName }"]""")

        if starred
            $requests.each -> $(@).attr('data-starred', 'false')
        else
            $requests.each -> $(@).attr('data-starred', 'true')

    runRequest: (e) ->
        requestModel = new Request id: $(e.target).data('request-id')
        $row = $(e.target).parents 'tr'

        requestType = $(e.target).data 'request-type'

        dialogOptions =
            message: "<p>Are you sure you want to run a task for this #{ requestType } request immediately?</p><pre>#{ requestModel.get('id') }</pre>"
            buttons: [
                $.extend({}, vex.dialog.buttons.YES, text: 'Run now')
                vex.dialog.buttons.NO
            ]
            callback: (confirmedOrPromptData) =>
                return if confirmedOrPromptData is false

                requestModel.run(confirmedOrPromptData)
                utils.flashRow $row

        if requestType is 'on-demand'
            dialogType = vex.dialog.prompt
            dialogOptions.message += '<p>Additional command line input (optional):</p>'
        else
            dialogType = vex.dialog.confirm

        dialogType dialogOptions

    changeFilters: (e) ->
        e.preventDefault()
        requestsActiveFilter = $(e.target).data('requests-active-filter')
        if e.metaKey or e.ctrlKey or e.shiftKey
            requestsActiveFilter = $(e.target).data('requests-active-filter-shift')
        @lastRequestsActiveSubFilter = requestsActiveFilter
        @lastSearchFilter = _.trim @$el.find('input[type="search"]').val()
        app.router.navigate "/requests/#{ @lastRequestsFilter }/#{ requestsActiveFilter }/#{ @lastSearchFilter }", trigger: true

    setUpSearchEvents: (refresh, searchWasFocused) ->
        $search = @$el.find('input[type="search"]')

        if not app.isMobile and (not refresh or searchWasFocused)
            setTimeout -> $search.focus()

        $rows = @$('tbody > tr')

        previousLastSearchFilter = ''

        onChange = =>
            return unless @ is app.views.current

            @lastSearchFilter = _.trim $search.val()

            if @lastSearchFilter is ''
                $rows.removeClass('filtered')
                app.router.navigate "/requests/#{ @lastRequestsFilter }/#{ @lastRequestsSubFilter }", { replace: true }

            if previousLastSearchFilter isnt @lastSearchFilter
                app.router.navigate "/requests/#{ @lastRequestsFilter }/#{ @lastRequestsSubFilter }/#{ @lastSearchFilter }", { replace: true }
                previousLastSearchFilter = @lastSearchFilter

                $rows.each (i, row) =>
                    $row = $(row)

                    rowText = $row.data('request-id')
                    user = $row.data('request-deploy-user')
                    rowText = "#{ rowText } #{ user }" if user?

                    if utils.matchLowercaseOrWordsInWords(@lastSearchFilter, rowText)
                        $row.removeClass('filtered')
                    else
                        $row.addClass('filtered')

            @$('table').each ->
                utils.handlePotentiallyEmptyFilteredTable $(@), 'request', @lastSearchFilter

        onChangeDebounced = _.debounce onChange, 200

        $search.unbind().on 'change keypress paste focus textInput input click keydown', onChangeDebounced

        if refresh
            onChange()
<commit_msg>Extracted search events<commit_after>View = require './view'

Request = require '../models/Request'

class RequestsView extends View

    templateRequestsAll: require './templates/requestsAll'
    templateRequestsAllBody: require './templates/requestsAllBody'

    templateRequestsActive: require './templates/requestsActive'
    templateRequestsActiveBody: require './templates/requestsActiveBody'
    templateRequestsActiveFilter: require './templates/requestsActiveFilter'
    
    templateRequestsCooldown: require './templates/requestsCooldown'
    templateRequestsCooldownBody: require './templates/requestsCooldownBody'
    
    templateRequestsPaused: require './templates/requestsPaused'
    templateRequestsPausedBody: require './templates/requestsPausedBody'

    templateRequestsPending: require './templates/requestsPending'
    templateRequestsPendingBody: require './templates/requestsPendingBody'

    templateRequestsCleaning: require './templates/requestsCleaning'
    templateRequestsCleaningBody: require './templates/requestsCleaningBody'

    removeRequestTemplate: require './templates/vex/removeRequest'

    # Which table views have sub-filters (daemon, scheduled, on-demand)
    haveSubfilter: ['all', 'active', 'paused', 'cooldown']

    events:
        'click [data-action="viewJSON"]': 'viewJson'
        'click [data-action="remove"]': 'removeRequest'
        'click [data-action="unpause"]': 'unpauseRequest'
        'click [data-action="starToggle"]': 'toggleStar'
        'click [data-action="run-now"]': 'runRequest'
        'click [data-requests-active-filter]': 'changeFilters'

        'change input[type="search"]': 'searchChange'
        'keyup input[type="search"]': 'searchChange'
        'input input[type="search"]': 'searchChange'

    initialize: ->
        @lastRequestsFilter = @options.requestsFilter
        @lastRequestsSubFilter = @options.requestsSubFilter

        if @lastRequestsFilter in @haveSubfilter
            @lastRequestsActiveSubFilter = @lastRequestsSubFilter

    fetch: ->
        @collection = switch @lastRequestsFilter
            when 'all'
                app.collections.requestsAll
            when 'active'
                app.collections.requestsActive
            when 'cooldown'
                app.collections.requestsCooldown
            when 'paused'
                app.collections.requestsPaused
            when 'pending'
                app.collections.requestsPending
            when 'cleaning'
                app.collections.requestsCleaning

        @collection.fetch()

    refresh: ->
        return @ if @$el.find('[data-sorted-direction]').length

        @fetch(@lastRequestsFilter).done =>
            @render(@lastRequestsFilter, @lastRequestsSubFilter, @lastSearchFilter, refresh = true)

        @

    render: (requestsFilter, requestsSubFilter, searchFilter, refresh) =>
        return @ unless @ is app.views.current

        forceFullRender = requestsFilter isnt @lastRequestsFilter

        @lastRequestsFilter = requestsFilter
        @lastSearchFilter = searchFilter
        @$el.find('input[type="search"]').val searchFilter

        if @lastRequestsFilter in @haveSubfilter
            if @lastRequestsActiveSubFilter
                @lastRequestsSubFilter = @lastRequestsActiveSubFilter
        else
            @lastRequestsSubFilter = requestsSubFilter

        if @lastRequestsFilter is 'all'
            @collection = app.collections.requestsAll
            template = @templateRequestsAll
            templateBody = @templateRequestsAllBody

        if @lastRequestsFilter is 'active'
            @collection = app.collections.requestsActive
            template = @templateRequestsActive
            templateBody = @templateRequestsActiveBody

        if @lastRequestsFilter is 'cooldown'
            @collection = app.collections.requestsCooldown
            template = @templateRequestsCooldown
            templateBody = @templateRequestsCooldownBody

        if @lastRequestsFilter is 'paused'
            @collection = app.collections.requestsPaused
            template = @templateRequestsPaused
            templateBody = @templateRequestsPausedBody

        # The following have filters
        if @lastRequestsFilter in @haveSubfilter
            templateFilter = @templateRequestsActiveFilter

        if @lastRequestsFilter is 'pending'
            @collection = app.collections.requestsPending
            template = @templateRequestsPending
            templateBody = @templateRequestsPendingBody

        if @lastRequestsFilter is 'cleaning'
            @collection = app.collections.requestsCleaning
            template = @templateRequestsCleaning
            templateBody = @templateRequestsCleaningBody

        context =
            collectionSynced: @collection.synced
            requestsSubFilter: requestsSubFilter
            searchFilter: searchFilter

        if @lastRequestsFilter is 'paused'
            context.requests = _.filter(_.pluck(@collection.models, 'attributes'), (r) => not r.scheduled and not r.onDemand)
            context.requestsScheduled = _.filter(_.pluck(@collection.models, 'attributes'), (r) => r.scheduled)
            context.requests.reverse()
            context.requestsScheduled.reverse()

        if @lastRequestsFilter in @haveSubfilter
            if requestsSubFilter is 'all'
                context.requests = _.pluck(@collection.models, 'attributes')

            else
                filterFunction = => false

                if requestsSubFilter is 'daemon'
                    filterFunction = (r) => not r.scheduled and not r.onDemand

                if requestsSubFilter is 'daemon-on-demand'
                    filterFunction = (r) => not r.scheduled

                if requestsSubFilter is 'daemon-scheduled'
                    filterFunction = (r) => not r.onDemand

                if requestsSubFilter is 'on-demand'
                    filterFunction = (r) => r.onDemand

                if requestsSubFilter is 'on-demand-scheduled'
                    filterFunction = (r) => r.onDemand or r.scheduled

                if requestsSubFilter is 'scheduled'
                    filterFunction = (r) => r.scheduled

                context.requests = _.filter(_.pluck(@collection.models, 'attributes'), filterFunction)

            context.requests.reverse()

        else
            context.requests = _.pluck(@collection.models, 'attributes')

        for request in context.requests
            if app.collections.requestsStarred.get(request.name)?
                request.starred = true

        partials =
            partials:
                requestsBody: templateBody

        $search = @$el.find('input[type="search"]')

        $requestsBodyContainer =  @$el.find('[data-requests-body-container]')

        if templateFilter?
            partials.partials.requestsFilter = templateFilter
            $requestsFilterContainer =  @$el.find('[data-requests-filter-container]')

        if not $requestsBodyContainer.length or forceFullRender
            @$el.html template(context, partials)

        else
            if templateFilter?
                $requestsFilterContainer.html templateFilter context

            $requestsBodyContainer.html templateBody context

            @$el.find('input[type="search"]').val context.searchFilter
            
        utils.setupSortableTables()

        @

    viewJson: (e) ->
        utils.viewJSON 'request', $(e.target).data('request-id')

    removeRequest: (e) ->
        $row = $(e.target).parents('tr')
        requestModel = @collection.get($(e.target).data('request-id'))

        if $(e.target).data('action-remove-type') is 'deletePaused'
            vex.dialog.confirm
                message: "<p>Are you sure you want to delete the paused request?</p><pre>#{ requestModel.get('id') }</pre>"
                callback: (confirmed) =>
                    return unless confirmed
                    $row.remove()
                    requestModel.deletePaused().done =>
                        delete app.allRequests[requestModel.get('id')]
                        @collection.remove(requestModel)

        else
            vex.dialog.confirm
                message: @removeRequestTemplate(requestId: requestModel.get('id'))
                buttons: [
                    $.extend({}, vex.dialog.buttons.YES, (text: 'Remove', className: 'vex-dialog-button-primary vex-dialog-button-primary-remove'))
                    vex.dialog.buttons.NO
                ]
                callback: (confirmed) =>
                    return unless confirmed
                    requestModel.destroy()
                    delete app.allRequests[requestModel.get('id')] # TODO - move to model on destroy?
                    @collection.remove(requestModel)
                    $row.remove()

    unpauseRequest: (e) ->
        $row = $(e.target).parents('tr')
        requestModel = @collection.get($(e.target).data('request-id'))

        vex.dialog.confirm
            message: "<p>Are you sure you want to unpause the request?</p><pre>#{ requestModel.get('id') }</pre>"
            callback: (confirmed) =>
                return unless confirmed
                
                if @lastRequestsFilter is "paused"
                    $row.remove()
                    
                requestModel.unpause().done =>
                    @refresh()
                        
    toggleStar: (e) ->
        $target = $(e.target)
        $table = $target.parents 'table'

        requestName = $target.data 'request-name'
        starred = $target.attr('data-starred') is 'true'

        app.collections.requestsStarred.toggle(requestName)
        $requests = $table.find("""[data-request-name="#{ requestName }"]""")

        if starred
            $requests.each -> $(@).attr('data-starred', 'false')
        else
            $requests.each -> $(@).attr('data-starred', 'true')

    runRequest: (e) ->
        requestModel = new Request id: $(e.target).data('request-id')
        $row = $(e.target).parents 'tr'

        requestType = $(e.target).data 'request-type'

        dialogOptions =
            message: "<p>Are you sure you want to run a task for this #{ requestType } request immediately?</p><pre>#{ requestModel.get('id') }</pre>"
            buttons: [
                $.extend({}, vex.dialog.buttons.YES, text: 'Run now')
                vex.dialog.buttons.NO
            ]
            callback: (confirmedOrPromptData) =>
                return if confirmedOrPromptData is false

                requestModel.run(confirmedOrPromptData)
                utils.flashRow $row

        if requestType is 'on-demand'
            dialogType = vex.dialog.prompt
            dialogOptions.message += '<p>Additional command line input (optional):</p>'
        else
            dialogType = vex.dialog.confirm

        dialogType dialogOptions

    changeFilters: (e) ->
        e.preventDefault()
        requestsActiveFilter = $(e.target).data('requests-active-filter')
        if e.metaKey or e.ctrlKey or e.shiftKey
            requestsActiveFilter = $(e.target).data('requests-active-filter-shift')
        @lastRequestsActiveSubFilter = requestsActiveFilter
        @lastSearchFilter = _.trim @$el.find('input[type="search"]').val()
        app.router.navigate "/requests/#{ @lastRequestsFilter }/#{ requestsActiveFilter }/#{ @lastSearchFilter }", trigger: true

    searchChange: (event) =>
        onChange = =>
            $search = $(event.currentTarget)
            previousLastSearchFilter = ''
            $rows = @$('tbody > tr')
            return unless @ is app.views.current

            @lastSearchFilter = _.trim $search.val()

            if @lastSearchFilter is ''
                $rows.removeClass('filtered')
                app.router.navigate "/requests/#{ @lastRequestsFilter }/#{ @lastRequestsSubFilter }", { replace: true }

            if previousLastSearchFilter isnt @lastSearchFilter
                app.router.navigate "/requests/#{ @lastRequestsFilter }/#{ @lastRequestsSubFilter }/#{ @lastSearchFilter }", { replace: true }
                previousLastSearchFilter = @lastSearchFilter

                $rows.each (i, row) =>
                    $row = $(row)

                    rowText = $row.data('request-id')
                    user = $row.data('request-deploy-user')
                    rowText = "#{ rowText } #{ user }" if user?

                    if utils.matchLowercaseOrWordsInWords(@lastSearchFilter, rowText)
                        $row.removeClass('filtered')
                    else
                        $row.addClass('filtered')

            @$('table').each ->
                utils.handlePotentiallyEmptyFilteredTable $(@), 'request', @lastSearchFilter

        (_.debounce onChange, 200)()


{'fraction_non_alphanumeric': 0.10691190706679574, 'fraction_numerical': 0.00023233301064859633, 'mean_word_length': 2.152972774996948, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 98, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '511458', 'n_tokens_mistral': 6646, 'n_tokens_neox': 6406, 'n_words': 1346}