Subversion Repositories SmartDukaan

Rev

Rev 37331 | Rev 37337 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 37331 Rev 37335
Line 1... Line 1...
1
$(function () {
1
$(function () {
2
 
2
 
3
    // The screen is an AJAX fragment injected into #main-content, so every handler
3
    // The screen is an AJAX fragment injected into #main-content, so every handler
4
    // is delegated from document and state is re-initialised on each load.
4
    // is delegated from document and state is re-initialised on each load.
5
    var state = { page: 1, rows: [], total: 0, pages: 1, pageSize: 50, brandsLoaded: false,
5
    var state = { page: 1, rows: [], total: 0, pages: 1, pageSize: 50, brandsLoaded: false,
6
                  decisions: [], huntTimer: null };
6
                  decisions: [], huntTimer: null, documents: [], pollTimer: null };
7
 
7
 
8
    function ctx() {
8
    function ctx() {
9
        return (typeof context !== 'undefined' && context) ? context : (window.ocContext || '');
9
        return (typeof context !== 'undefined' && context) ? context : (window.ocContext || '');
10
    }
10
    }
11
 
11
 
Line 365... Line 365...
365
            state.total = payload.total || 0;
365
            state.total = payload.total || 0;
366
            state.pages = payload.pages || 1;
366
            state.pages = payload.pages || 1;
367
            state.page = payload.page || 1;
367
            state.page = payload.page || 1;
368
            state.pageSize = payload.pageSize || 50;
368
            state.pageSize = payload.pageSize || 50;
369
 
369
 
-
 
370
            state.documents = payload.documents || state.documents || [];
370
            if (payload.documents) {
371
            if (payload.documents) {
371
                var docSel = root().find('[data-oc-doc]');
372
                var docSel = root().find('[data-oc-doc]');
372
                if (docSel.find('option').filter(function () { return this.value !== ''; }).length === 0) {
373
                if (docSel.find('option').filter(function () { return this.value !== ''; }).length === 0) {
373
                    docSel.empty();
374
                    docSel.empty();
374
                    payload.documents.forEach(function (doc) {
375
                    payload.documents.forEach(function (doc) {
Line 394... Line 395...
394
                select.val(current);
395
                select.val(current);
395
                root().find('[data-oc-stat="brands"]').text(payload.brands.filter(Boolean).length);
396
                root().find('[data-oc-stat="brands"]').text(payload.brands.filter(Boolean).length);
396
                state.brandsLoaded = true;
397
                state.brandsLoaded = true;
397
            }
398
            }
398
            render();
399
            render();
-
 
400
            renderIngestState();
-
 
401
            schedulePoll();
399
            // an empty result while circulars exist is nearly always a filter
402
            // an empty result while circulars exist is nearly always a filter
400
            // mismatch, so name the months that actually hold rows
403
            // mismatch, so name the months that actually hold rows
401
            if (state.total === 0 && payload.documents && payload.documents.length > 0) {
404
            if (state.total === 0 && payload.documents && payload.documents.length > 0) {
402
                root().find('[data-oc-summary]').text(
405
                root().find('[data-oc-summary]').text(
403
                    'No rows matched these filters. Loaded circulars: ' +
406
                    'No rows matched these filters. Loaded circulars: ' +
Line 417... Line 420...
417
    // sidebar entry / any trigger loads the fragment then initialises it
420
    // sidebar entry / any trigger loads the fragment then initialises it
418
    function openOfferCircularReview(domId) {
421
    function openOfferCircularReview(domId) {
419
        ocGet(ctx() + '/offerCircularReview', function (response) {
422
        ocGet(ctx() + '/offerCircularReview', function (response) {
420
            $('#' + (domId || 'main-content')).html(response);
423
            $('#' + (domId || 'main-content')).html(response);
421
            state = { page: 1, rows: [], total: 0, pages: 1, pageSize: 50, brandsLoaded: false,
424
            state = { page: 1, rows: [], total: 0, pages: 1, pageSize: 50, brandsLoaded: false,
422
                      decisions: [], huntTimer: null };
425
                      decisions: [], huntTimer: null, documents: [], pollTimer: null };
423
            loadRows();
426
            loadRows();
424
        });
427
        });
425
    }
428
    }
426
    window.openOfferCircularReview = openOfferCircularReview;
429
    window.openOfferCircularReview = openOfferCircularReview;
427
 
430
 
Line 891... Line 894...
891
            btn.prop('disabled', false).text('Re-ingest to apply');
894
            btn.prop('disabled', false).text('Re-ingest to apply');
892
            resolveMsg('Could not queue re-ingest: ' + failMessage(xhr));
895
            resolveMsg('Could not queue re-ingest: ' + failMessage(xhr));
893
        });
896
        });
894
    });
897
    });
895
 
898
 
-
 
899
    // ------------------------------------------------------- ingest status polling
-
 
900
    //
-
 
901
    // Upload and parsing run in different processes: the portal stores the PDF as
-
 
902
    // DRAFT, and the cron job claims and parses it on its own schedule. Without this
-
 
903
    // the screen looks identical before and after a successful ingest, so a reviewer
-
 
904
    // has no way to tell "not parsed yet" from "parsed and produced nothing".
-
 
905
 
-
 
906
    var PENDING_STATES = { DRAFT: 'queued for parsing', PROCESSING: 'parsing now' };
-
 
907
 
-
 
908
    function selectedDoc() {
-
 
909
        var id = currentDocumentId();
-
 
910
        if (!id) { return null; }
-
 
911
        for (var i = 0; i < (state.documents || []).length; i++) {
-
 
912
            if (String(state.documents[i].documentId) === String(id)) {
-
 
913
                return state.documents[i];
-
 
914
            }
-
 
915
        }
-
 
916
        return null;
-
 
917
    }
-
 
918
 
-
 
919
    function renderIngestState() {
-
 
920
        var box = root().find('[data-oc-ingest-state]');
-
 
921
        var doc = selectedDoc();
-
 
922
        if (!doc) { box.empty(); return; }
-
 
923
 
-
 
924
        if (PENDING_STATES[doc.status]) {
-
 
925
            box.html('<span class="oc-pill oc-pill-warn">' + esc(PENDING_STATES[doc.status])
-
 
926
                + '</span> <span class="oc-num">the ingest job runs every 5 minutes; '
-
 
927
                + 'this refreshes itself</span>');
-
 
928
        } else if (doc.status === 'FAILED') {
-
 
929
            box.html('<span class="oc-pill oc-pill-danger">ingest failed</span> '
-
 
930
                + '<span class="oc-num">' + esc(doc.ingestError || 'no reason recorded')
-
 
931
                + '</span>');
-
 
932
        } else if (doc.status === 'PUBLISHED') {
-
 
933
            box.html('<span class="oc-pill oc-pill-ok">parsed</span> '
-
 
934
                + '<span class="oc-num">' + esc(doc.ingestSummary || '') + '</span>');
-
 
935
        } else {
-
 
936
            box.html('<span class="oc-pill oc-pill-muted">' + esc(doc.status) + '</span>');
-
 
937
        }
-
 
938
    }
-
 
939
 
-
 
940
    function schedulePoll() {
-
 
941
        clearTimeout(state.pollTimer);
-
 
942
        var doc = selectedDoc();
-
 
943
        if (!doc || !PENDING_STATES[doc.status]) {
-
 
944
            return;                      // settled - stop polling, do not spin forever
-
 
945
        }
-
 
946
        state.pollTimer = setTimeout(function () {
-
 
947
            ocGet(ctx() + '/offerCircular/documents', function (response) {
-
 
948
                var docs;
-
 
949
                try { docs = typeof response === 'string' ? JSON.parse(response) : response; }
-
 
950
                catch (e) { return; }
-
 
951
                var was = selectedDoc();
-
 
952
                state.documents = docs || [];
-
 
953
                var now = selectedDoc();
-
 
954
                renderIngestState();
-
 
955
                // it just finished: pull in the rows the parse produced
-
 
956
                if (was && now && was.status !== now.status && !PENDING_STATES[now.status]) {
-
 
957
                    loadRows();
-
 
958
                    return;
-
 
959
                }
-
 
960
                schedulePoll();
-
 
961
            }, function () { schedulePoll(); });   // transient failure - keep waiting
-
 
962
        }, 15000);
-
 
963
    }
-
 
964
 
896
    // direct navigation: the fragment is already on the page
965
    // direct navigation: the fragment is already on the page
897
    if (root().length > 0) {
966
    if (root().length > 0) {
898
        loadRows();
967
        loadRows();
899
    }
968
    }
900
});
969
});