<commit_before>define('Mobile/SalesLogix/Views/History/Edit', [
    'dojo/_base/declare',
    'dojo/_base/array',
    'dojo/string',
    'Mobile/SalesLogix/Validator',
    'Sage/Platform/Mobile/Utility',
    'Sage/Platform/Mobile/Edit'
], function(
    declare,
    array,
    string,
    validator,
    utility,
    Edit
) {

    return declare('Mobile.SalesLogix.Views.History.Edit', [Edit], {
        //Localization
        accountText: 'account',
        noteDescriptionTitleText: 'Note Description',
        contactText: 'contact',
        longNotesText: 'notes',
        longNotesTitleText: 'Notes',
        opportunityText: 'opportunity',
        ticketNumberText: 'ticket',
        regardingText: 'regarding',
        isLeadText: 'for lead',
        startingText: 'time',
		startingFormatText : 'M/d/yyyy h:mm tt',
        titleText: 'Note',
        companyText: 'company',
        leadText: 'lead',
        relatedItemsText: 'Related Items',
        yesText: 'YES',
        noText: 'NO',

        //View Properties
        id: 'history_edit',
        fieldsForLeads: ['AccountName', 'Lead'],
        fieldsForStandard: ['Account', 'Contact', 'Opportunity', 'Ticket'],
        entityName: 'History',
        resourceKind: 'history',
        insertSecurity: null, //'Entities/History/Add',
        updateSecurity: null, //'Entities/History/Edit',
        querySelect: [
            'AccountId',
            'AccountName',
            'ContactId',
            'ContactName',
            'Description',
            'LongNotes',
            'Notes',
            'OpportunityId',
            'OpportunityName',
            'TicketId',
            'TicketNumber',
            'Type',
            'LeadId',
            'LeadName',
            'StartDate'
        ],

        init: function() {
            this.inherited(arguments);

            this.connect(this.fields['Lead'], 'onChange', this.onLeadChange);
            this.connect(this.fields['IsLead'], 'onChange', this.onIsLeadChange);

            this.connect(this.fields['Account'], 'onChange', this.onAccountChange);
            this.connect(this.fields['Contact'], 'onChange', this.onAccountDependentChange);
            this.connect(this.fields['Opportunity'], 'onChange', this.onAccountDependentChange);
            this.connect(this.fields['Ticket'], 'onChange', this.onAccountDependentChange);
        },
        isHistoryForLead: function(entry) {
            return entry && /^[\w]{12}$/.test(entry['LeadId']);
        },
        isInLeadContext: function() {
            var insert = this.options && this.options.insert,
                entry = this.options && this.options.entry,
                lead = (insert && App.isNavigationFromResourceKind('leads', function(o, c) { return c.resourceKind === 'leads'; })) || this.isHistoryForLead(entry);
            return !!lead;
        },
        beforeTransitionTo: function() {
            this.inherited(arguments);

            // we hide the lead or standard fields here, as the view is currently hidden, in order to prevent flashing.
            // the value for the 'IsLead' field will be set later, based on the value derived here.

            // todo: there is an issue when refreshing the edit view as options.isLead is persisted in the navigation state.
            if (this.options.isForLead != undefined) return;

            this.options.isForLead = this.isInLeadContext();

            if (this.options.isForLead)
                this.showFieldsForLead();
            else
                this.showFieldsForStandard();
        },
        onIsLeadChange: function(value, field) {
            this.options.isForLead = value;

            if (this.options.isForLead)
                this.showFieldsForLead();
            else
                this.showFieldsForStandard();
        },
        onLeadChange: function(value, field) {
            var selection = field.getSelection();

            if (selection && this.insert)
            {
                this.fields['AccountName'].setValue(utility.getValue(selection, 'Company'));
            }
        },
        onAccountChange: function(value, field) {
            var fields = this.fields;
            array.forEach(['Contact', 'Opportunity', 'Ticket'], function(f) {
                if (value)
                {
                    fields[f].dependsOn = 'Account';
                    fields[f].where = string.substitute('Account.Id eq "${0}"', [value['AccountId'] || value['key']]);

                    if (fields[f].currentSelection &&
                        fields[f].currentSelection.Account['$key'] != (value['AccountId'] || value['key'])) {

                        fields[f].setValue(false);
                    }

                }
                else
                {
                    fields[f].dependsOn = null;
                    fields[f].where = 'Account.AccountName ne null';
                }
            });
        },
        onAccountDependentChange: function(value, field) {
            if (value && !field.dependsOn && field.currentSelection && field.currentSelection.Account) {

                var accountField = this.fields['Account'];
                accountField.setValue({
                    'AccountId': field.currentSelection.Account['$key'],
                    'AccountName': field.currentSelection.Account['AccountName']
                });
                this.onAccountChange(accountField.getValue(), accountField);
            }
        },
        showFieldsForLead: function() {
            array.forEach(this.fieldsForStandard.concat(this.fieldsForLeads), function(item) {
                if (this.fields[item])
                    this.fields[item].hide();
            }, this);

            array.forEach(this.fieldsForLeads, function(item) {
                if (this.fields[item])
                    this.fields[item].show();
            }, this);
        },
        showFieldsForStandard: function() {
            array.forEach(this.fieldsForStandard.concat(this.fieldsForLeads), function(item) {
                if (this.fields[item])
                    this.fields[item].hide();
            }, this);

            array.forEach(this.fieldsForStandard, function(item) {
                    if (this.fields[item])
                        this.fields[item].show();
                }, this);
        },
        applyContext: function() {
            var found = App.queryNavigationContext(function(o) {
                var context = (o.options && o.options.source) || o;
                return /^(accounts|contacts|opportunities|leads|tickets)$/.test(context.resourceKind) && context.key;
            });

            found = (found && found.options && found.options.source) || found;

            var lookup = {
                'accounts': this.applyAccountContext,
                'contacts': this.applyContactContext,
                'opportunities': this.applyOpportunityContext,
                'leads': this.applyLeadContext,
                'tickets': this.applyTicketContext
            };

            if (found && lookup[found.resourceKind])
                lookup[found.resourceKind].call(this, found);

            this.context = found;

            var user = App.context && App.context.user;

            this.fields['Type'].setValue('atNote');
            this.fields['UserId'].setValue(user && user['$key']);
            this.fields['UserName'].setValue(user && user['$descriptor']);
            this.fields['StartDate'].setValue(new Date());
        },
        applyAccountContext: function(context) {
            var accountField = this.fields['Account'],
                accountValue = {
                    'AccountId': context.key,
                    'AccountName': context.descriptor
                };
            accountField.setValue(accountValue);
            this.onAccountChange(accountValue, accountField);
        },
        applyLeadContext: function(context) {
            var view = App.getView(context.id),
                entry = context.entry || (view && view.entry);

            if (!entry || !entry['$key']) return;

            var leadField = this.fields['Lead'],
                leadValue = {
                    'LeadId': entry['$key'],
                    'LeadName': entry['$descriptor']
                };
            leadField.setValue(leadValue);
            this.onLeadChange(leadValue, leadField);

            this.fields['AccountName'].setValue(entry['Company']);

            var isLeadField = this.fields['IsLead'];
            isLeadField.setValue(context.resourceKind == 'leads');
            this.onIsLeadChange(isLeadField.getValue(), isLeadField);
        },
        applyOpportunityContext: function(context) {
            var opportunityField = this.fields['Opportunity'];
            opportunityField.setValue({
                'OpportunityId': context.key,
                'OpportunityName': context.descriptor
            });
            this.onAccountDependentChange(opportunityField.getValue, opportunityField);

            var accountEntry;
            if (context.entry && context.entry['Account'])
            {
                accountEntry = context.entry['Account'];
            }
            else
            {
                var view = App.getView(context.id),
                    entry = view && view.entry;
                accountEntry = entry['Account'];
            }

            if (accountEntry)
            {
                var accountField = this.fields['Account'];
                accountField.setValue({
                    'AccountId': accountEntry['$key'],
                    'AccountName': accountEntry['AccountName']
                });
                this.onAccountChange(accountField.getValue(), accountField);
            }

            // todo: find a good way to get the primary contact and apply
        },
        applyContactContext: function(context) {
            var contactField = this.fields['Contact'];
            contactField.setValue({
                'ContactId': context.key,
                'ContactName': context.descriptor
            });
            this.onAccountDependentChange(contactField.getValue(), contactField);

            var accountEntry;
            if (context.entry && context.entry['Account'])
            {
                accountEntry = context.entry['Account'];
            }
            else
            {
                var view = App.getView(context.id),
                    entry = view && view.entry;
                accountEntry = entry['Account'];
            }

            if (accountEntry)
            {
                var accountField = this.fields['Account'];
                accountField.setValue({
                    'AccountId': accountEntry['$key'],
                    'AccountName': accountEntry['AccountName']
                });
                this.onAccountChange(accountField.getValue(), accountField);
            }
        },
        applyTicketContext: function(context) {
            var ticketField = this.fields['Ticket'];
            ticketField.setValue({
                'TicketId': context.key,
                'TicketNumber': context.descriptor
            });
            this.onAccountDependentChange(ticketField.getValue(), ticketField);

            var accountEntry, contactEntry;
            if (context.entry && context.entry['Account'])
            {
                accountEntry = context.entry['Account'];
                contactEntry = context.entry['Contact'];
            }
            else
            {
                var view = App.getView(context.id),
                    entry = view && view.entry;
                accountEntry = entry['Account'];
                contactEntry = entry['Contact'];
            }

            if (accountEntry)
            {
                var accountField = this.fields['Account'];
                accountField.setValue({
                    'AccountId': accountEntry['$key'],
                    'AccountName': accountEntry['AccountName']
                });
                this.onAccountChange(accountField.getValue(), accountField);
            }

            if (contactEntry)
            {
                var contactField = this.fields['Contact'];
                contactField.setValue({
                    'ContactId': contactEntry['$key'],
                    'ContactName': contactEntry['NameLF']
                });
                this.onAccountDependentChange(contactField.getValue(), contactField);
            }
        },
        setValues: function(values) {
            this.inherited(arguments);

            if (this.isInLeadContext())
            {
                var isLeadField = this.fields['IsLead'];
                isLeadField.setValue(true);
                this.onIsLeadChange(true, isLeadField);

                var leadCompany = utility.getValue(values, 'Company');
                if (leadCompany)
                   this.fields['AccountName'].setValue(leadCompany);
            }

            // entry may have been passed as full entry, reapply context logic to extract properties
            if (this.context && this.context.resourceKind)
            {
                var lookup = {
                    'accounts': this.applyAccountContext,
                    'contacts': this.applyContactContext,
                    'opportunities': this.applyOpportunityContext,
                    'leads': this.applyLeadContext,
                    'tickets': this.applyTicketContext
                };
                lookup[this.context.resourceKind].call(this, this.context);
            }

            this.fields['Text'].setValue(values['LongNotes'] || values['Notes'] || '');
        },
        formatDependentQuery: function(dependentValue, format, property) {
            property = property || '$key';

            return string.substitute(format, [utility.getValue(dependentValue, property)]);
        },
        getValues: function() {
            var values = this.inherited(arguments);

            if (this.fields['Text'].isDirty())
            {
                var text = this.fields['Text'].getValue();

                values = values || {};
                values['LongNotes'] = text;
                values['Notes'] = text && text.length > 250
                    ? text.substr(0, 250)
                    : text;
            }

            return values;
        },
        createLayout: function() {
            return this.layout || (this.layout = [{
                title: this.detailsText,
                name: 'DetailsSection',
                children: [{
                    name: 'Type',
                    property: 'Type',
                    type: 'hidden'
                },{
                    name: 'UserId',
                    property: 'UserId',
                    type: 'hidden'
                },{
                    name: 'UserName',
                    property: 'UserName',
                    type: 'hidden'
                },{
                    label: this.startingText,
                    name: 'StartDate',
                    property: 'StartDate',
                    type: 'date',
                    showTimePicker: true,
                    dateFormatText: this.startingFormatText,
                    minValue: (new Date(1900, 0, 1)),
                    validator: [
                        validator.exists,
                        validator.isDateInRange
                    ]
                },{
                    dependsOn: 'Type',
                    label: this.regardingText,
                    name: 'Description',
                    property: 'Description',
                    picklist: 'Note Regarding',
                    orderBy: 'text asc',
                    title: this.noteDescriptionTitleText,
                    type: 'picklist'
                }]
            },{
                title: this.longNotesTitleText,
                name: 'NotesSection',
                children: [{
                    name: 'Text',
                    property: 'Text',
                    label: this.longNotesText,
                    cls: 'row-edit-text',
                    type: 'textarea'
                }]
            },{
                title: this.relatedItemsText,
                name: 'RelatedItemsSection',
                children: [{
                    label: this.isLeadText,
                    name: 'IsLead',
                    include: false,
                    type: 'boolean',
                    onText: this.yesText,
                    offText: this.noText
                },{
                    label: this.accountText,
                    name: 'Account',
                    property: 'Account',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'AccountId',
                    valueTextProperty: 'AccountName',
                    view: 'account_related',
                    validator: validator.exists
                },{
                    label: this.contactText,
                    name: 'Contact',
                    property: 'Contact',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'ContactId',
                    valueTextProperty: 'ContactName',
                    view: 'contact_related',
                    where: this.formatDependentQuery.bindDelegate(
                        this, 'Account.Id eq "${0}"', 'AccountId'
                    )
                },{
                    label: this.opportunityText,
                    name: 'Opportunity',
                    property: 'Opportunity',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'OpportunityId',
                    valueTextProperty: 'OpportunityName',
                    view: 'opportunity_related',
                    where: this.formatDependentQuery.bindDelegate(
                        this, 'Account.Id eq "${0}"', 'AccountId'
                    )
                },{
                    label: this.ticketNumberText,
                    name: 'Ticket',
                    property: 'Ticket',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'TicketId',
                    valueTextProperty: 'TicketNumber',
                    view: 'ticket_related',
                    where: this.formatDependentQuery.bindDelegate(
                        this, 'Account.Id eq "${0}"', 'AccountId'
                    )
                },{
                    label: this.leadText,
                    name: 'Lead',
                    property: 'Lead',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'LeadId',
                    valueTextProperty: 'LeadName',
                    view: 'lead_related',
                    validator: validator.exists
                },{
                    label: this.companyText,
                    name: 'AccountName',
                    property: 'AccountName',
                    type: 'text'
                }]
            }]);
        }
    });
});<commit_msg>[Defect #12089232] fix error when attempting a lookup on notes/history edit<commit_after>define('Mobile/SalesLogix/Views/History/Edit', [
    'dojo/_base/declare',
    'dojo/_base/array',
    'dojo/string',
    'Mobile/SalesLogix/Validator',
    'Sage/Platform/Mobile/Utility',
    'Sage/Platform/Mobile/Edit'
], function(
    declare,
    array,
    string,
    validator,
    utility,
    Edit
) {

    return declare('Mobile.SalesLogix.Views.History.Edit', [Edit], {
        //Localization
        accountText: 'account',
        noteDescriptionTitleText: 'Note Description',
        contactText: 'contact',
        longNotesText: 'notes',
        longNotesTitleText: 'Notes',
        opportunityText: 'opportunity',
        ticketNumberText: 'ticket',
        regardingText: 'regarding',
        isLeadText: 'for lead',
        startingText: 'time',
		startingFormatText : 'M/d/yyyy h:mm tt',
        titleText: 'Note',
        companyText: 'company',
        leadText: 'lead',
        relatedItemsText: 'Related Items',
        yesText: 'YES',
        noText: 'NO',

        //View Properties
        id: 'history_edit',
        fieldsForLeads: ['AccountName', 'Lead'],
        fieldsForStandard: ['Account', 'Contact', 'Opportunity', 'Ticket'],
        entityName: 'History',
        resourceKind: 'history',
        insertSecurity: null, //'Entities/History/Add',
        updateSecurity: null, //'Entities/History/Edit',
        querySelect: [
            'AccountId',
            'AccountName',
            'ContactId',
            'ContactName',
            'Description',
            'LongNotes',
            'Notes',
            'OpportunityId',
            'OpportunityName',
            'TicketId',
            'TicketNumber',
            'Type',
            'LeadId',
            'LeadName',
            'StartDate'
        ],

        init: function() {
            this.inherited(arguments);

            this.connect(this.fields['Lead'], 'onChange', this.onLeadChange);
            this.connect(this.fields['IsLead'], 'onChange', this.onIsLeadChange);

            this.connect(this.fields['Account'], 'onChange', this.onAccountChange);
            this.connect(this.fields['Contact'], 'onChange', this.onAccountDependentChange);
            this.connect(this.fields['Opportunity'], 'onChange', this.onAccountDependentChange);
            this.connect(this.fields['Ticket'], 'onChange', this.onAccountDependentChange);
        },
        isHistoryForLead: function(entry) {
            return entry && /^[\w]{12}$/.test(entry['LeadId']);
        },
        isInLeadContext: function() {
            var insert = this.options && this.options.insert,
                entry = this.options && this.options.entry,
                lead = (insert && App.isNavigationFromResourceKind('leads', function(o, c) { return c.resourceKind === 'leads'; })) || this.isHistoryForLead(entry);
            return !!lead;
        },
        beforeTransitionTo: function() {
            this.inherited(arguments);

            // we hide the lead or standard fields here, as the view is currently hidden, in order to prevent flashing.
            // the value for the 'IsLead' field will be set later, based on the value derived here.

            // todo: there is an issue when refreshing the edit view as options.isLead is persisted in the navigation state.
            if (this.options.isForLead != undefined) return;

            this.options.isForLead = this.isInLeadContext();

            if (this.options.isForLead)
                this.showFieldsForLead();
            else
                this.showFieldsForStandard();
        },
        onIsLeadChange: function(value, field) {
            this.options.isForLead = value;

            if (this.options.isForLead)
                this.showFieldsForLead();
            else
                this.showFieldsForStandard();
        },
        onLeadChange: function(value, field) {
            var selection = field.getSelection();

            if (selection && this.insert)
            {
                this.fields['AccountName'].setValue(utility.getValue(selection, 'Company'));
            }
        },
        onAccountChange: function(value, field) {
            var fields = this.fields;
            array.forEach(['Contact', 'Opportunity', 'Ticket'], function(f) {
                if (value)
                {
                    fields[f].dependsOn = 'Account';
                    fields[f].where = string.substitute('Account.Id eq "${0}"', [value['AccountId'] || value['key']]);

                    if (fields[f].currentSelection &&
                        fields[f].currentSelection.Account['$key'] != (value['AccountId'] || value['key'])) {

                        fields[f].setValue(false);
                    }

                }
                else
                {
                    fields[f].dependsOn = null;
                    fields[f].where = 'Account.AccountName ne null';
                }
            });
        },
        onAccountDependentChange: function(value, field) {
            if (value && !field.dependsOn && field.currentSelection && field.currentSelection.Account) {

                var accountField = this.fields['Account'];
                accountField.setValue({
                    'AccountId': field.currentSelection.Account['$key'],
                    'AccountName': field.currentSelection.Account['AccountName']
                });
                this.onAccountChange(accountField.getValue(), accountField);
            }
        },
        showFieldsForLead: function() {
            array.forEach(this.fieldsForStandard.concat(this.fieldsForLeads), function(item) {
                if (this.fields[item])
                    this.fields[item].hide();
            }, this);

            array.forEach(this.fieldsForLeads, function(item) {
                if (this.fields[item])
                    this.fields[item].show();
            }, this);
        },
        showFieldsForStandard: function() {
            array.forEach(this.fieldsForStandard.concat(this.fieldsForLeads), function(item) {
                if (this.fields[item])
                    this.fields[item].hide();
            }, this);

            array.forEach(this.fieldsForStandard, function(item) {
                    if (this.fields[item])
                        this.fields[item].show();
                }, this);
        },
        applyContext: function() {
            var found = App.queryNavigationContext(function(o) {
                var context = (o.options && o.options.source) || o;
                return /^(accounts|contacts|opportunities|leads|tickets)$/.test(context.resourceKind) && context.key;
            });

            found = (found && found.options && found.options.source) || found;

            var lookup = {
                'accounts': this.applyAccountContext,
                'contacts': this.applyContactContext,
                'opportunities': this.applyOpportunityContext,
                'leads': this.applyLeadContext,
                'tickets': this.applyTicketContext
            };

            if (found && lookup[found.resourceKind])
                lookup[found.resourceKind].call(this, found);

            this.context = found;

            var user = App.context && App.context.user;

            this.fields['Type'].setValue('atNote');
            this.fields['UserId'].setValue(user && user['$key']);
            this.fields['UserName'].setValue(user && user['$descriptor']);
            this.fields['StartDate'].setValue(new Date());
        },
        applyAccountContext: function(context) {
            var accountField = this.fields['Account'],
                accountValue = {
                    'AccountId': context.key,
                    'AccountName': context.descriptor
                };
            accountField.setValue(accountValue);
            this.onAccountChange(accountValue, accountField);
        },
        applyLeadContext: function(context) {
            var view = App.getView(context.id),
                entry = context.entry || (view && view.entry);

            if (!entry || !entry['$key']) return;

            var leadField = this.fields['Lead'],
                leadValue = {
                    'LeadId': entry['$key'],
                    'LeadName': entry['$descriptor']
                };
            leadField.setValue(leadValue);
            this.onLeadChange(leadValue, leadField);

            this.fields['AccountName'].setValue(entry['Company']);

            var isLeadField = this.fields['IsLead'];
            isLeadField.setValue(context.resourceKind == 'leads');
            this.onIsLeadChange(isLeadField.getValue(), isLeadField);
        },
        applyOpportunityContext: function(context) {
            var opportunityField = this.fields['Opportunity'];
            opportunityField.setValue({
                'OpportunityId': context.key,
                'OpportunityName': context.descriptor
            });
            this.onAccountDependentChange(opportunityField.getValue, opportunityField);

            var accountEntry;
            if (context.entry && context.entry['Account'])
            {
                accountEntry = context.entry['Account'];
            }
            else
            {
                var view = App.getView(context.id),
                    entry = view && view.entry;
                accountEntry = entry['Account'];
            }

            if (accountEntry)
            {
                var accountField = this.fields['Account'];
                accountField.setValue({
                    'AccountId': accountEntry['$key'],
                    'AccountName': accountEntry['AccountName']
                });
                this.onAccountChange(accountField.getValue(), accountField);
            }

            // todo: find a good way to get the primary contact and apply
        },
        applyContactContext: function(context) {
            var contactField = this.fields['Contact'];
            contactField.setValue({
                'ContactId': context.key,
                'ContactName': context.descriptor
            });
            this.onAccountDependentChange(contactField.getValue(), contactField);

            var accountEntry;
            if (context.entry && context.entry['Account'])
            {
                accountEntry = context.entry['Account'];
            }
            else
            {
                var view = App.getView(context.id),
                    entry = view && view.entry;
                accountEntry = entry['Account'];
            }

            if (accountEntry)
            {
                var accountField = this.fields['Account'];
                accountField.setValue({
                    'AccountId': accountEntry['$key'],
                    'AccountName': accountEntry['AccountName']
                });
                this.onAccountChange(accountField.getValue(), accountField);
            }
        },
        applyTicketContext: function(context) {
            var ticketField = this.fields['Ticket'];
            ticketField.setValue({
                'TicketId': context.key,
                'TicketNumber': context.descriptor
            });
            this.onAccountDependentChange(ticketField.getValue(), ticketField);

            var accountEntry, contactEntry;
            if (context.entry && context.entry['Account'])
            {
                accountEntry = context.entry['Account'];
                contactEntry = context.entry['Contact'];
            }
            else
            {
                var view = App.getView(context.id),
                    entry = view && view.entry;
                accountEntry = entry['Account'];
                contactEntry = entry['Contact'];
            }

            if (accountEntry)
            {
                var accountField = this.fields['Account'];
                accountField.setValue({
                    'AccountId': accountEntry['$key'],
                    'AccountName': accountEntry['AccountName']
                });
                this.onAccountChange(accountField.getValue(), accountField);
            }

            if (contactEntry)
            {
                var contactField = this.fields['Contact'];
                contactField.setValue({
                    'ContactId': contactEntry['$key'],
                    'ContactName': contactEntry['NameLF']
                });
                this.onAccountDependentChange(contactField.getValue(), contactField);
            }
        },
        setValues: function(values) {
            this.inherited(arguments);

            if (this.isInLeadContext())
            {
                var isLeadField = this.fields['IsLead'];
                isLeadField.setValue(true);
                this.onIsLeadChange(true, isLeadField);

                var leadCompany = utility.getValue(values, 'Company');
                if (leadCompany)
                   this.fields['AccountName'].setValue(leadCompany);
            }

            // entry may have been passed as full entry, reapply context logic to extract properties
            if (this.context && this.context.resourceKind)
            {
                var lookup = {
                    'accounts': this.applyAccountContext,
                    'contacts': this.applyContactContext,
                    'opportunities': this.applyOpportunityContext,
                    'leads': this.applyLeadContext,
                    'tickets': this.applyTicketContext
                };
                lookup[this.context.resourceKind].call(this, this.context);
            }

            this.fields['Text'].setValue(values['LongNotes'] || values['Notes'] || '');
        },
        formatDependentQuery: function(dependentValue, format, property) {
            property = property || '$key';

            return string.substitute(format, [utility.getValue(dependentValue, property)]);
        },
        getValues: function() {
            var values = this.inherited(arguments);

            if (this.fields['Text'].isDirty())
            {
                var text = this.fields['Text'].getValue();

                values = values || {};
                values['LongNotes'] = text;
                values['Notes'] = text && text.length > 250
                    ? text.substr(0, 250)
                    : text;
            }

            return values;
        },
        createLayout: function() {
            return this.layout || (this.layout = [{
                title: this.detailsText,
                name: 'DetailsSection',
                children: [{
                    name: 'Type',
                    property: 'Type',
                    type: 'hidden'
                },{
                    name: 'UserId',
                    property: 'UserId',
                    type: 'hidden'
                },{
                    name: 'UserName',
                    property: 'UserName',
                    type: 'hidden'
                },{
                    label: this.startingText,
                    name: 'StartDate',
                    property: 'StartDate',
                    type: 'date',
                    showTimePicker: true,
                    dateFormatText: this.startingFormatText,
                    minValue: (new Date(1900, 0, 1)),
                    validator: [
                        validator.exists,
                        validator.isDateInRange
                    ]
                },{
                    dependsOn: 'Type',
                    label: this.regardingText,
                    name: 'Description',
                    property: 'Description',
                    picklist: 'Note Regarding',
                    orderBy: 'text asc',
                    title: this.noteDescriptionTitleText,
                    type: 'picklist'
                }]
            },{
                title: this.longNotesTitleText,
                name: 'NotesSection',
                children: [{
                    name: 'Text',
                    property: 'Text',
                    label: this.longNotesText,
                    cls: 'row-edit-text',
                    type: 'textarea'
                }]
            },{
                title: this.relatedItemsText,
                name: 'RelatedItemsSection',
                children: [{
                    label: this.isLeadText,
                    name: 'IsLead',
                    include: false,
                    type: 'boolean',
                    onText: this.yesText,
                    offText: this.noText
                },{
                    label: this.accountText,
                    name: 'Account',
                    property: 'Account',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'AccountId',
                    valueTextProperty: 'AccountName',
                    view: 'account_related',
                    validator: validator.exists
                },{
                    dependsOn: 'Account',
                    label: this.contactText,
                    name: 'Contact',
                    property: 'Contact',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'ContactId',
                    valueTextProperty: 'ContactName',
                    view: 'contact_related',
                    where: this.formatDependentQuery.bindDelegate(
                        this, 'Account.Id eq "${0}"', 'AccountId'
                    )
                },{
                    dependsOn: 'Account',
                    label: this.opportunityText,
                    name: 'Opportunity',
                    property: 'Opportunity',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'OpportunityId',
                    valueTextProperty: 'OpportunityName',
                    view: 'opportunity_related',
                    where: this.formatDependentQuery.bindDelegate(
                        this, 'Account.Id eq "${0}"', 'AccountId'
                    )
                },{
                    dependsOn: 'Account',
                    label: this.ticketNumberText,
                    name: 'Ticket',
                    property: 'Ticket',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'TicketId',
                    valueTextProperty: 'TicketNumber',
                    view: 'ticket_related',
                    where: this.formatDependentQuery.bindDelegate(
                        this, 'Account.Id eq "${0}"', 'AccountId'
                    )
                },{
                    label: this.leadText,
                    name: 'Lead',
                    property: 'Lead',
                    type: 'lookup',
                    emptyText: '',
                    applyTo: '.',
                    valueKeyProperty: 'LeadId',
                    valueTextProperty: 'LeadName',
                    view: 'lead_related',
                    validator: validator.exists
                },{
                    label: this.companyText,
                    name: 'AccountName',
                    property: 'AccountName',
                    type: 'text'
                }]
            }]);
        }
    });
});<|endoftext|>


<commit_before>class Soda {
  constructor (vm, options = {}) {
    this.mutations = options.mutations
    this.state = options.state
    this._inject = false

    const init = root => {
      const map = (_vm) => {
        if (!vm.$children.length) return
        _vm.$children.forEach(child => {
          inject(child)
          map(child)
        })
      }
      const inject = (_vm) => {
        _vm.$soda = this
        _vm.soda = this.state
      }
      root.soda = this.state
      map(root)
    }
    init(vm)
    return this
  }

  commit (type, payload) {
    this.mutations[type](this.state, payload)
  }
}

export default Soda
<commit_msg>improve soad add root<commit_after>class Soda {
  constructor (vm, options = {}) {
    this.mutations = options.mutations
    this.state = options.state
    this._inject = false
    this.root = vm

    // const { commit } = this

    // const store = this

    // this.commit = function boundCommit (type, payload, options) {
    //   return commit.call(store, type, payload, options)
    // }

    const init = root => {
      const map = (_vm) => {
        if (!_vm.$children.length) return
        _vm.$children.forEach(child => {
          inject(child)
          map(child)
        })
      }
      const inject = (_vm) => {
        if (typeof _vm.soda === 'undefined') return
        _vm.$soda = this
        _vm.soda = this.state
      }
      root.soda = this.state
      map(root)
    }
    init(vm)
    return this
  }

  commit (type, payload) {
    this.mutations[type].call(this, this.state, payload)
  }
}

export default Soda
<|endoftext|>


<commit_before>import { Component } from 'react';
import PropTypes from 'prop-types';
import { connectGeoSearch } from 'react-instantsearch-dom';
import { LatLngPropType, BoundingBoxPropType } from './propTypes';

function isEqualPosition(a, b) {
  if (a === b) {
    return true;
  }
  if (a === undefined || b === undefined) {
    return false;
  }

  return a.lat === b.lat && a.lng === b.lng;
}

function isEqualCurrentRefinement(a, b) {
  if (a === b) {
    return true;
  }

  if (a === undefined || b === undefined) {
    return false;
  }

  return (
    isEqualPosition(a.northEast, b.northEast) &&
    isEqualPosition(a.southWest, b.southWest)
  );
}

export class Connector extends Component {
  static propTypes = {
    hits: PropTypes.arrayOf(PropTypes.object).isRequired,
    isRefinedWithMap: PropTypes.bool.isRequired,
    enableRefineOnMapMove: PropTypes.bool.isRequired,
    refine: PropTypes.func.isRequired,
    children: PropTypes.func.isRequired,
    position: LatLngPropType,
    currentRefinement: BoundingBoxPropType,
  };

  static getDerivedStateFromProps(props, state) {
    const { position, currentRefinement } = props;
    const { previousPosition, previousCurrentRefinement } = state;

    const positionChanged = !isEqualPosition(previousPosition, position);
    const currentRefinementChanged = !isEqualCurrentRefinement(
      previousCurrentRefinement,
      currentRefinement
    );

    const sliceNextState = {
      previousPosition: position,
      previousCurrentRefinement: currentRefinement,
    };

    if (positionChanged || currentRefinementChanged) {
      return {
        ...sliceNextState,
        hasMapMoveSinceLastRefine: false,
      };
    }

    return sliceNextState;
  }

  state = {
    isRefineOnMapMove: this.props.enableRefineOnMapMove,
    hasMapMoveSinceLastRefine: false,
    previousPosition: this.props.position,
    previousCurrentRefinement: this.props.currentRefinement,
  };

  toggleRefineOnMapMove = () =>
    this.setState(({ isRefineOnMapMove }) => ({
      isRefineOnMapMove: !isRefineOnMapMove,
    }));

  setMapMoveSinceLastRefine = next => {
    const { hasMapMoveSinceLastRefine } = this.state;

    if (hasMapMoveSinceLastRefine === next) {
      return;
    }

    this.setState(() => ({
      hasMapMoveSinceLastRefine: next,
    }));
  };

  render() {
    const {
      hits,
      isRefinedWithMap,
      position,
      currentRefinement,
      refine,
      children,
    } = this.props;

    const { isRefineOnMapMove, hasMapMoveSinceLastRefine } = this.state;

    return children({
      toggleRefineOnMapMove: this.toggleRefineOnMapMove,
      setMapMoveSinceLastRefine: this.setMapMoveSinceLastRefine,
      hits,
      isRefinedWithMap,
      isRefineOnMapMove,
      hasMapMoveSinceLastRefine,
      position,
      currentRefinement,
      refine,
    });
  }
}

export default connectGeoSearch(Connector);
<commit_msg>chore(dom-maps): add major version note on spelling (#2892)<commit_after>import { Component } from 'react';
import PropTypes from 'prop-types';
import { connectGeoSearch } from 'react-instantsearch-dom';
import { LatLngPropType, BoundingBoxPropType } from './propTypes';

function isEqualPosition(a, b) {
  if (a === b) {
    return true;
  }
  if (a === undefined || b === undefined) {
    return false;
  }

  return a.lat === b.lat && a.lng === b.lng;
}

function isEqualCurrentRefinement(a, b) {
  if (a === b) {
    return true;
  }

  if (a === undefined || b === undefined) {
    return false;
  }

  return (
    isEqualPosition(a.northEast, b.northEast) &&
    isEqualPosition(a.southWest, b.southWest)
  );
}

export class Connector extends Component {
  static propTypes = {
    hits: PropTypes.arrayOf(PropTypes.object).isRequired,
    isRefinedWithMap: PropTypes.bool.isRequired,
    enableRefineOnMapMove: PropTypes.bool.isRequired,
    refine: PropTypes.func.isRequired,
    children: PropTypes.func.isRequired,
    position: LatLngPropType,
    currentRefinement: BoundingBoxPropType,
  };

  static getDerivedStateFromProps(props, state) {
    const { position, currentRefinement } = props;
    const { previousPosition, previousCurrentRefinement } = state;

    const positionChanged = !isEqualPosition(previousPosition, position);
    const currentRefinementChanged = !isEqualCurrentRefinement(
      previousCurrentRefinement,
      currentRefinement
    );

    const sliceNextState = {
      previousPosition: position,
      previousCurrentRefinement: currentRefinement,
    };

    if (positionChanged || currentRefinementChanged) {
      return {
        ...sliceNextState,
        hasMapMoveSinceLastRefine: false,
      };
    }

    return sliceNextState;
  }

  state = {
    isRefineOnMapMove: this.props.enableRefineOnMapMove,
    hasMapMoveSinceLastRefine: false,
    previousPosition: this.props.position,
    previousCurrentRefinement: this.props.currentRefinement,
  };

  toggleRefineOnMapMove = () =>
    this.setState(({ isRefineOnMapMove }) => ({
      isRefineOnMapMove: !isRefineOnMapMove,
    }));

  setMapMoveSinceLastRefine = next => {
    const { hasMapMoveSinceLastRefine } = this.state;

    if (hasMapMoveSinceLastRefine === next) {
      return;
    }

    this.setState(() => ({
      hasMapMoveSinceLastRefine: next,
    }));
  };

  render() {
    const {
      hits,
      isRefinedWithMap,
      position,
      currentRefinement,
      refine,
      children,
    } = this.props;

    const { isRefineOnMapMove, hasMapMoveSinceLastRefine } = this.state;

    return children({
      toggleRefineOnMapMove: this.toggleRefineOnMapMove,
      setMapMoveSinceLastRefine: this.setMapMoveSinceLastRefine,
      hits,
      isRefinedWithMap,
      isRefineOnMapMove,
      // @MAJOR hasMapMoveSinceLastRefine -> hasMapMovedSinceLastRefine
      hasMapMoveSinceLastRefine,
      position,
      currentRefinement,
      refine,
    });
  }
}

export default connectGeoSearch(Connector);
<|endoftext|>


<commit_before>/**
 * Staballoy is created by Rene Pot (2017)
 * Version 0.2.1 -- 2017-10-19
 * It extends alloy to add reactive components to Titanium.
 * The latest version can be found at Github: https://github.com/topener/staballoy
 */

var requiredControllers = {};
var activeControllers = [];
var subscribers = [];
var vars = {};
var currentlyFocussed = false;

/**
 * Alloy.createController override
 */
Alloy.createController = function(name, args) {
    var args = args || {};

    if (!requiredControllers[name]){
        requiredControllers[name] = require("/alloy/controllers/" + name);
    }
    var controllerGuid = guid();
    args.staballoy = {setVar: setVar, getVar: getVar, guid: controllerGuid};
    args.subscribe = subscribe;
    var controller = new (requiredControllers[name])(args);
    controller.getView().guid = controllerGuid;

    // only parse through all subscribable components
    if (isSubscribable(controller.getView().apiName)){
    	if (controller.getView().apiName == 'Ti.UI.iOS.NavigationWindow'){
	        parseChildren(controller.getView().window.children, controller);
    	} else {
	        parseChildren(controller.getView().children, controller);
    	}
        activeControllers.push({controller: controller, guid: controllerGuid});
        controller.getView().addEventListener('focus', handleFocus);
        controller.getView().addEventListener('close', handleClose);

        if (!currentlyFocussed){
            currentlyFocussed = controllerGuid;
        }
    }

    return controller;
};

/**
 * look through all UI elements and find those that need subscribing
 */
function parseChildren(children, controller){
    _.each(children, function(child){
        if (child.children && child.children.length > 0){
            parseChildren(child.children, controller);
            if (child.staballoy){
                parseSubscriptions(child, controller);
            }
        } else if (child.sections && child.sections.length > 0){
        	parseChildren(child.sections, controller);
        }

        if (child.staballoy){
            parseSubscriptions(child, controller);
        }
    });
}

/**
 * parse through all subscriptions of the component
 */
function parseSubscriptions(elem, controller){

    if (!elem.staballoy.subscriptions || elem.staballoy.subscriptions.length == 0) return;
    _.each(elem.staballoy.subscriptions, function(attribute, variable){

        // create a subscription model
        var data = {"var": variable, "component": elem, "attribute": attribute, "window": controller.args.staballoy.guid};
        if (elem.staballoy.logicFunction){
            if (typeof elem.staballoy.logicFunction == 'string'){

                if (controller[elem.staballoy.logicFunction] && typeof controller[elem.staballoy.logicFunction] == 'function'){
                    data.logicFunction = controller[elem.staballoy.logicFunction];
                }
            } else {
                data.logicFunction = elem.staballoy.logicFunction;
            }
        }
        trigger(data);
        subscribers.push(data);
    });
}

/**
 * The in-controller exposed subscribe method
 */
function subscribe(args){
    if (!isSubscribable(args.window.getView().apiName)){
        return console.error('subscription not possible without context window');
    }

    if (!args.subscriptions || args.subscriptions.length == 0) return;

    args.component.staballoy = {subscriptions: args.subscriptions, logicFunction: args.logicFunction};
    parseSubscriptions(args.component, args.window);

}

/**
 * handle focus and store which is focussed last
 */
function handleFocus(e){
    currentlyFocussed = e.source.guid;
}

function getWindowById(guid){
    var index = _.findIndex(activeControllers, function(c){
        return c.guid == guid;
    });
    return activeControllers[index].controller;
}

/**
 * Callback method on the close event listener
 */
function handleClose(e){
    var controller = getWindowById(e.source.guid);
    controller.getView().removeEventListener('close', handleClose);
    controller.off();
    controller.destroy();
    activeControllers.splice(index,1);

    removeSubscribersForWindow(e.source.guid);
}

/**
 * remove all subscribers based on the GUID of a window
 */
function removeSubscribersForWindow(guid){
    var toRemove =  _.where(subscribers, {'window' : guid});
    _.each(toRemove, function(r){
        subscribers.splice(subscribers.indexOf(r), 1);
    });
}

/**
 * Set variable in staballoy and trigger update throughout all subscribers
 */
function setVar(key, value){

    if (!vars.hasOwnProperty(key)) vars[key];
    vars[key] = value;

    var toUpdate = _.where(subscribers, {"var" : key});
    _.each(toUpdate, function(sub){
        trigger(sub);
    });
}

/**
 * Trigger a variable update
 */
function trigger(sub){

    var value = vars[sub.var];

    if (sub.logicFunction){
        value = sub.logicFunction(value);
    }

    if (sub.attribute.indexOf('set') === 0){
        return sub.component[sub.attribute](value);
    }

    sub.component[sub.attribute] = value;
}

/**
 * Get variable from staballoy
 */
function getVar(key){
    if (!vars.hasOwnProperty(key)) return null;
    return vars[key];
}

/**
 * Check if, based on ApiName, a subscription is allowed
 */
function isSubscribable(apiName){
    return apiName === 'Ti.UI.Window' || apiName === 'Ti.UI.iOS.NavigationWindow' || apiName === 'Ti.UI.TabGroup';
}

/**
 * Method to get a unique GUID (from Alloy source code)
 */
function guid() {
    function S4() {
        return (65536 * (1 + Math.random()) | 0).toString(16).substring(1);
    }

    return S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4();
}

module.exports = {
    setVar: setVar,
    getVar: getVar
};
<commit_msg>fix close event<commit_after>/**
 * Staballoy is created by Rene Pot (2017)
 * Version 0.2.1 -- 2017-10-19
 * It extends alloy to add reactive components to Titanium.
 * The latest version can be found at Github: https://github.com/topener/staballoy
 */

var requiredControllers = {};
var activeControllers = [];
var subscribers = [];
var vars = {};
var currentlyFocussed = false;

/**
 * Alloy.createController override
 */
Alloy.createController = function(name, args) {
    var args = args || {};

    if (!requiredControllers[name]){
        requiredControllers[name] = require("/alloy/controllers/" + name);
    }
    var controllerGuid = guid();
    args.staballoy = {setVar: setVar, getVar: getVar, guid: controllerGuid};
    args.subscribe = subscribe;
    var controller = new (requiredControllers[name])(args);
    controller.getView().guid = controllerGuid;

    // only parse through all subscribable components
    if (isSubscribable(controller.getView().apiName)){
    	if (controller.getView().apiName == 'Ti.UI.iOS.NavigationWindow'){
	        parseChildren(controller.getView().window.children, controller);
    	} else {
	        parseChildren(controller.getView().children, controller);
    	}
        activeControllers.push({controller: controller, guid: controllerGuid});
        controller.getView().addEventListener('focus', handleFocus);
        controller.getView().addEventListener('close', handleClose);

        if (!currentlyFocussed){
            currentlyFocussed = controllerGuid;
        }
    }

    return controller;
};

/**
 * look through all UI elements and find those that need subscribing
 */
function parseChildren(children, controller){
    _.each(children, function(child){
        if (child.children && child.children.length > 0){
            parseChildren(child.children, controller);
            if (child.staballoy){
                parseSubscriptions(child, controller);
            }
        } else if (child.sections && child.sections.length > 0){
        	parseChildren(child.sections, controller);
        }

        if (child.staballoy){
            parseSubscriptions(child, controller);
        }
    });
}

/**
 * parse through all subscriptions of the component
 */
function parseSubscriptions(elem, controller){

    if (!elem.staballoy.subscriptions || elem.staballoy.subscriptions.length == 0) return;
    _.each(elem.staballoy.subscriptions, function(attribute, variable){

        // create a subscription model
        var data = {"var": variable, "component": elem, "attribute": attribute, "window": controller.args.staballoy.guid};
        if (elem.staballoy.logicFunction){
            if (typeof elem.staballoy.logicFunction == 'string'){

                if (controller[elem.staballoy.logicFunction] && typeof controller[elem.staballoy.logicFunction] == 'function'){
                    data.logicFunction = controller[elem.staballoy.logicFunction];
                }
            } else {
                data.logicFunction = elem.staballoy.logicFunction;
            }
        }
        trigger(data);
        subscribers.push(data);
    });
}

/**
 * The in-controller exposed subscribe method
 */
function subscribe(args){
    if (!isSubscribable(args.window.getView().apiName)){
        return console.error('subscription not possible without context window');
    }

    if (!args.subscriptions || args.subscriptions.length == 0) return;

    args.component.staballoy = {subscriptions: args.subscriptions, logicFunction: args.logicFunction};
    parseSubscriptions(args.component, args.window);

}

/**
 * handle focus and store which is focussed last
 */
function handleFocus(e){
    currentlyFocussed = e.source.guid;
}

function getWindowIndexById(guid){
    return _.findIndex(activeControllers, function(c){
        return c.guid == guid;
    });
}

/**
 * Callback method on the close event listener
 */
function handleClose(e){
    var index = getWindowIndexById(e.source.guid);
    var controller = activeControllers[index].controller;
    controller.getView().removeEventListener('close', handleClose);
    controller.off();
    controller.destroy();
    activeControllers.splice(index,1);

    removeSubscribersForWindow(e.source.guid);
}

/**
 * remove all subscribers based on the GUID of a window
 */
function removeSubscribersForWindow(guid){
    var toRemove =  _.where(subscribers, {'window' : guid});
    _.each(toRemove, function(r){
        subscribers.splice(subscribers.indexOf(r), 1);
    });
}

/**
 * Set variable in staballoy and trigger update throughout all subscribers
 */
function setVar(key, value){

    if (!vars.hasOwnProperty(key)) vars[key];
    vars[key] = value;

    var toUpdate = _.where(subscribers, {"var" : key});
    _.each(toUpdate, function(sub){
        trigger(sub);
    });
}

/**
 * Trigger a variable update
 */
function trigger(sub){

    var value = vars[sub.var];

    if (sub.logicFunction){
        value = sub.logicFunction(value);
    }

    if (sub.attribute.indexOf('set') === 0){
        return sub.component[sub.attribute](value);
    }

    sub.component[sub.attribute] = value;
}

/**
 * Get variable from staballoy
 */
function getVar(key){
    if (!vars.hasOwnProperty(key)) return null;
    return vars[key];
}

/**
 * Check if, based on ApiName, a subscription is allowed
 */
function isSubscribable(apiName){
    return apiName === 'Ti.UI.Window' || apiName === 'Ti.UI.iOS.NavigationWindow' || apiName === 'Ti.UI.TabGroup';
}

/**
 * Method to get a unique GUID (from Alloy source code)
 */
function guid() {
    function S4() {
        return (65536 * (1 + Math.random()) | 0).toString(16).substring(1);
    }

    return S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4();
}

module.exports = {
    setVar: setVar,
    getVar: getVar
};
<|endoftext|>


<commit_before>// Karma configuration
// Generated on Fri Mar 01 2019 22:02:29 GMT+0100 (CET)

module.exports = function (config) {
  config.set({
    // frameworks to use
    // available frameworks: https://www.npmjs.com/browse/keyword/karma-adapter
    frameworks: ['karma-typescript', 'tap'],

    // list of files / patterns to load in the browser
    files: ['./tests/**/*.ts', './lib/**/*.ts'],

    // list of files / patterns to exclude
    exclude: [],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://www.npmjs.com/browse/keyword/karma-preprocessor
    preprocessors: {
      '**/*.ts': ['karma-typescript'],
    },

    karmaTypescriptConfig: {
      compilerOptions: {
        resolveJsonModule: true,
      },
      bundlerOptions: {
        entrypoints: /\.spec\.ts$/,
      },
    },

    proxies: {
      '/mcl_c384_256.wasm': '../../node_modules/mcl-wasm/mcl_c384_256.wasm',
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://www.npmjs.com/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: false,

    // start these browsers
    // available browser launchers: https://www.npmjs.com/browse/keyword/karma-launcher
    browsers: ['FirefoxHeadless', 'ChromeHeadless'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: true,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity,

    // Fail after timeout
    browserDisconnectTimeout: 100000,
    browserNoActivityTimeout: 100000,
  })
}
<commit_msg>vm: karma tests tuning<commit_after>// Karma configuration
// Generated on Fri Mar 01 2019 22:02:29 GMT+0100 (CET)

module.exports = function (config) {
  config.set({
    // frameworks to use
    // available frameworks: https://www.npmjs.com/browse/keyword/karma-adapter
    frameworks: ['karma-typescript', 'tap'],

    // list of files / patterns to load in the browser
    files: ['./tests/**/*.ts', './lib/**/*.ts'],

    // list of files / patterns to exclude
    exclude: [],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://www.npmjs.com/browse/keyword/karma-preprocessor
    preprocessors: {
      '**/*.ts': ['karma-typescript'],
    },

    karmaTypescriptConfig: {
      compilerOptions: {
        resolveJsonModule: true,
        esModuleInterop: true,
      },
      bundlerOptions: {
        entrypoints: /\.spec\.ts$/,
      },
    },

    proxies: {
      '/mcl_c384_256.wasm': '../../node_modules/mcl-wasm/mcl_c384_256.wasm',
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://www.npmjs.com/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: false,

    // start these browsers
    // available browser launchers: https://www.npmjs.com/browse/keyword/karma-launcher
    browsers: ['FirefoxHeadless', 'ChromeHeadless'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: true,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: 1,

    // Fail after timeout
    browserDisconnectTimeout: 100000,
    browserNoActivityTimeout: 100000,
  })
}
<|endoftext|>


<commit_before>'use strict';

module.exports.onCheckpointReached = function (handler) {
  var db = this;
  var plugin = db.__checkpointPlugin;

  if (!plugin) {
    plugin = db.__checkpointPlugin = new CheckpointPlugin(db);
  }

  plugin.registerHandler(handler);
};

var DEFAULT_DELAY = 200;

var CheckpointPlugin = function (_db) {
  // Private data
  var db = _db;
  var checkpoint = db.__opts.checkpoint;
  var delay = db.__opts.checkpointDelay || DEFAULT_DELAY;
  var events = null;
  var handlers = [];

  // Private methods
  function setupSizePlugin () {
    if (!db.installSizeWrapper) {
      throw new Error('This plugin depends on pouchdb-size plugin. Please add pouchdb-size plugin befor this one.');
    }

    db.installSizeWrapper();
  }

  function setupDBEvents () {
    events = db.changes({
      live: true,
      since: 'now'
    });

    events.on('change', executeOnce(checkDBSize.bind(this), delay));

    db.on('destroyed', function () {
      events.cancel();
    });
  }

  function checkDBSize () {
    return db.info()
      .then(function (response) {
        var dbSize = response.disk_size;
        // Handlers should be called only once
        // after the first reaching of a checkpoint
        if (dbSize >= checkpoint) {
          handlers
            .forEach(function (handler) {
              // It might be better for performance
              // to execute handlers asynchronously
              executeAsync(handler)(checkpoint);
            });
        }
      })
      .catch(function (error) {
        db.emit('error', error);
        console.log('Error while fetching db info: ', error);
      });
  }

  // Public constructor
  function CheckpointPlugin () {
    setupSizePlugin();
    setupDBEvents();
  }

  // Public methods
  CheckpointPlugin.prototype.registerHandler = function (handler) {
    handlers.push(handler);
  };

  return new CheckpointPlugin();
};

var executeOnce = function (fn, delay) {
  var timeout = null;
  return function () {
    var args = arguments;
    if (!timeout) {
      timeout = setTimeout(function () {
        fn.apply(null, args);
        clearTimeout(timeout);
        timeout = null;
      }, delay);
    }
  }
}

var executeAsync = function (fn) {
  return function () {
    var args = arguments;
    setTimeout(function () {
      fn.apply(null, args);
    });
  }
}
<commit_msg>Fixed disk_size error<commit_after>'use strict';

module.exports.onCheckpointReached = function (handler) {
  var db = this;
  var plugin = db.__checkpointPlugin;

  if (!plugin) {
    plugin = db.__checkpointPlugin = new CheckpointPlugin(db);
  }

  plugin.registerHandler(handler);
};

var DEFAULT_DELAY = 200;

var CheckpointPlugin = function (_db) {
  // Private data
  var db = _db;
  var checkpoint = db.__opts.checkpoint;
  var delay = db.__opts.checkpointDelay || DEFAULT_DELAY;
  var events = null;
  var handlers = [];

  // Private methods
  function setupSizePlugin () {
    if (!db.installSizeWrapper) {
      throw new Error('This plugin depends on pouchdb-size plugin. Please add pouchdb-size plugin befor this one.');
    }

    db.installSizeWrapper();
  }

  function setupDBEvents () {
    events = db.changes({
      live: true,
      since: 'now'
    });

    events.on('change', executeOnce(checkDBSize.bind(this), delay));

    db.on('destroyed', function () {
      events.cancel();
    });
  }

  function checkDBSize () {
    return db.info()
      .then(function (response) {
        if (!response) return;

        var dbSize = response.disk_size;
        // Handlers should be called only once
        // after the first reaching of a checkpoint
        if (dbSize >= checkpoint) {
          handlers
            .forEach(function (handler) {
              // It might be better for performance
              // to execute handlers asynchronously
              executeAsync(handler)(checkpoint);
            });
        }
      })
      .catch(function (error) {
        db.emit('error', error);
        console.log('Error while fetching db info: ', error);
      });
  }

  // Public constructor
  function CheckpointPlugin () {
    setupSizePlugin();
    setupDBEvents();
  }

  // Public methods
  CheckpointPlugin.prototype.registerHandler = function (handler) {
    handlers.push(handler);
  };

  return new CheckpointPlugin();
};

var executeOnce = function (fn, delay) {
  var timeout = null;
  return function () {
    var args = arguments;
    if (!timeout) {
      timeout = setTimeout(function () {
        fn.apply(null, args);
        clearTimeout(timeout);
        timeout = null;
      }, delay);
    }
  }
}

var executeAsync = function (fn) {
  return function () {
    var args = arguments;
    setTimeout(function () {
      fn.apply(null, args);
    });
  }
}
<|endoftext|>


<commit_before>var MadChatter = {

	init: function(ws_host){
		$('#chat_wrapper').hide();
		MadChatter.init_websocket(ws_host);
		MadChatter.wait_for_join();
	},

	init_websocket: function(ws_host){
		if (typeof WebSocket === 'undefined') {
			return false;
	    }
		var ws =  new WebSocket(ws_host);
		ws.onopen = function(){
			MadChatter.resume_chat();
		};
		ws.onclose = function(){
			MadChatter.token = null;
			MadChatter.reconnect(ws_host);
		};
		ws.onmessage = function(e){
			var data = JSON.parse(e.data);
			// console.log(data);
			MadChatter.message_received(data);
		};
		MadChatter.ws = ws;
	},

	reconnect: function(ws_host){
		$('#disconnected').modal('show');
		setTimeout('MadChatter.init_websocket("'+ws_host+'")', 10000);
	},

	resume_chat: function(){
		setTimeout(function(){
			$('#disconnected').modal('hide');
			if (MadChatter.token && MadChatter.username) {
				MadChatter.set_username(MadChatter.username);
				$('#channel_tabs li').each(function(){
					var channel = $(this).find('a').attr('data-channel');
					if (channel != 'lobby') {
						MadChatter.send_message('/join', channel);
					}
				});
			}
		}, 2000); //wait two seconds. we should have a token by then
	},

	wait_for_join: function(){
		$('#pick_a_username').submit(function(e){
			e.preventDefault();
			MadChatter.join_chat();
		});
	},

	join_chat: function(){
		var username = $.trim($('#username').val());
		if (username.length == 0) {
			alert('Please enter your name.');
			return false;
		}

		MadChatter.set_username(username);
		$('#login_screen').hide();
		$('#chat_wrapper').show();

		MadChatter.add_channel_tab('lobby', 'Lobby').trigger('click');

		$('.navbar .brand').on('click', function(e){
			e.preventDefault();
			MadChatter.join_channel('lobby');
		});

		$('#users-nav').popover({
			placement: 'bottom',
			content: function(){
				return $('.channel:visible .users-list').html();
			},
			delay: { show: 0, hide: 1000 }
		});

		$('#channels, #channel_tabs').on('click', '.join_channel', function(e){
			e.preventDefault();
			var channel_id = $(this).attr('data-channel'),
				channel_name = $(this).text();
			MadChatter.add_channel_tab(channel_id, channel_name).trigger('click');
		});

		$('#share_photo .btn-primary').on('click', function(e){
			e.preventDefault();
			var channel = $('.channel:visible').attr('data-channel'),
				$input = $(this).closest('.modal').find('input[name="url"]'),
				img_url = $input.val();
			if ($.trim(img_url).length > 0) {
				MadChatter.send_message('/img ' + img_url, channel);
				$('#share_photo').modal('hide');
				$input.val('');
			}
		});

		$('#share_code .btn-primary').on('click', function(e){
			e.preventDefault();
			var channel = $('.channel:visible').attr('data-channel'),
				$input = $(this).closest('.modal').find('textarea'),
				code = $input.val();
			if ($.trim(code).length > 0) {
				MadChatter.send_message('/code ' + code, channel);
				$('#share_code').modal('hide');
				$input.val('');
			}
		});

		$('#create_channel .btn-primary').on('click', function(e){
			e.preventDefault();
			var $input = $(this).closest('.modal').find('input');
			var channel_name = $.trim($input.val());
			if (channel_name.length > 0) {
				MadChatter.send_message('/channel create ' + channel_name);
				$('#create_channel').modal('hide');
				$input.val('');
			}
		});
	},

	set_username: function(username){
		MadChatter.username = username;
		MadChatter.send_message('/nick ' + username);
	},

	add_channel_tab: function(channel_id, channel_name){
		var $existing_channel_tab = $('#channel_tabs a[data-channel="' + channel_id + '"]');
		if ($existing_channel_tab.length > 0) {
			return $existing_channel_tab;
		}

		var $channel_tab = $('
' + channel_name + '
')

		$channel_tab.on('click', function(e){
			e.preventDefault();
			MadChatter.join_channel(channel_id);
		});

		$('#channel_tabs').append($channel_tab);
		return $channel_tab;
	},

	join_channel: function(channel_id){
		$('#channel_tabs li')
			.removeClass('active')
			.find('a[data-channel="' + channel_id + '"]').parent().addClass('active');
		$('.channel').hide();
		var $channel = $('.channel[data-channel="' + channel_id + '"]');
		if ($channel.length == 0) {
			MadChatter.send_message('/join', channel_id);
			//need to figure out how to wait for response to see if we're allowed to join
			//solution: create .channel, but when server responds, it wont send messages, it will send not-authorized message
			var $channel = $('#channel_template').clone();
			$channel
				.removeAttr('id')
				.attr('data-channel', channel_id)
				.appendTo('#chat_wrapper');
			MadChatter.add_channel_actions($channel);
		}
		if (channel_id == 'lobby') {
			$('#users-nav').hide();
		} else {
			$('#users-nav').show();
		}
		$channel.show();
	},

	add_channel_actions: function($channel){

		function send_message($input){
			var message = $input.val(),
				channel = $input.closest('.channel').attr('data-channel');
			if ($.trim(message) != '') {
				MadChatter.send_message(message, channel);
				$input.val('');
			}
		}

		$('.new_message input', $channel).keyup(function(e){
			if (e.keyCode == 13) { // The enter key.
				send_message($(this));
			}
		});

		$('.new_message .send_message', $channel).on('click', function(e){
			e.preventDefault();
			var $input = $(this).closest('.new_message').find('input');
			send_message($input);
		});
	},

	scroll_to_bottom_of_chat: function(channel_id){
		$('body')[0].scrollTop = $(document).height();
	},

	send_message: function(message, channel){
		if (message == '/clear') {
			MadChatter.clear_messages();
		} else {
			var json = {
				token: MadChatter.token,
				message: message,
				channel: channel
			};
			MadChatter.ws.send(JSON.stringify(json));
		}
	},

	clear_messages: function(channel){
		$('.channel[data-channel="' + channel + '"] .messages').empty();
	},

	message_received: function(data){
		if (data.type == 'error') {
			console.log('Client error: ' + data.text)
			return;
		}
		if (data.type == 'token') {
			MadChatter.token = data.text;
			return;
		}
		if (data.type == 'channels') {
			MadChatter.update_channels_list(data.json);
			return;
		}
		if (data.type == 'users') {
			MadChatter.update_users_list(data.channel, data.json);
			return;
		}
		if (data.type == 'status') {
			MadChatter.display_status(data.channel, data.text, data.time);
		}
		if (data.type == 'action') {
			MadChatter.exec_action(data.channel, data.json);
		}
		if (data.type == 'message') {
			MadChatter.display_message(data.channel, data.username, data.html, data.time);
			if (typeof(MadChatterGrowl) != 'undefined') {
				MadChatterGrowl.send_(data.username, data.growl);
			}
		}
		MadChatter.scroll_to_bottom_of_chat();
	},

	update_channels_list: function(channels){
		var $list  = $('#channels');
		$list.html('');
		$.each(channels, function(index, channel) {
		  $list.append('
' + channel.name + '
');
		});
	},

	update_users_list: function(channel, users){
		var $list  = $('.channel[data-channel="' + channel + '"] ul.users');
		$list.find('li:not(.nav-header)').remove();
		$.each(users, function(index, username) {
		  $list.append('
' + username + '
');
		});
	},

	exec_action: function(channel, action){
		// this isnt working in IE 8...why?
		// window[action.function].apply(window, action.args);
	},

	display_status: function(channel, message, timestamp){
		var html = '
' + MadChatter.get_time_html(timestamp) + message + '
';
		$('.channel[data-channel="' + channel + '"] .messages').append(html);
	},

	display_message: function(channel, username, message, timestamp){
		var html = '
' + MadChatter.get_time_html(timestamp) + '' + username + ': ' + message + '
';
		$('.channel[data-channel="' + channel + '"] .messages').append(html);
	},

	get_time_html: function(timestamp){
		var html = '';
		var last_message_time = MadChatter.last_message_time;
		var	current_time = MadChatter.get_time_string(timestamp);
		if (last_message_time != current_time) {
			MadChatter.last_message_time = current_time;
			html = '<time>' + current_time + '</time>';
		}
		return html;
	},

	get_time_string: function(timestamp){
		var time = new Date(timestamp*1000); //timestamp must me in milliseconds
		var hours = time.getHours();
		var minutes = time.getMinutes();
		var ampm = 'am';
		if (hours > 11) { ampm = 'pm'; }
		if (minutes < 10) { minutes = "0" + minutes; }
		if (hours == 0) { hours = 12; }
		if (hours > 12) { hours = hours - 12; }
		return hours + ':' + minutes + ampm;
	}
};
<commit_msg>added missing parameter<commit_after>var MadChatter = {

	init: function(ws_host){
		$('#chat_wrapper').hide();
		MadChatter.init_websocket(ws_host);
		MadChatter.wait_for_join();
	},

	init_websocket: function(ws_host){
		if (typeof WebSocket === 'undefined') {
			return false;
	    }
		var ws =  new WebSocket(ws_host);
		ws.onopen = function(){
			MadChatter.resume_chat();
		};
		ws.onclose = function(){
			MadChatter.token = null;
			MadChatter.reconnect(ws_host);
		};
		ws.onmessage = function(e){
			var data = JSON.parse(e.data);
			// console.log(data);
			MadChatter.message_received(data);
		};
		MadChatter.ws = ws;
	},

	reconnect: function(ws_host){
		$('#disconnected').modal('show');
		setTimeout('MadChatter.init_websocket("'+ws_host+'")', 10000);
	},

	resume_chat: function(){
		setTimeout(function(){
			$('#disconnected').modal('hide');
			if (MadChatter.token && MadChatter.username) {
				MadChatter.set_username(MadChatter.username);
				$('#channel_tabs li').each(function(){
					var channel = $(this).find('a').attr('data-channel');
					if (channel != 'lobby') {
						MadChatter.send_message('/join', channel);
					}
				});
			}
		}, 2000); //wait two seconds. we should have a token by then
	},

	wait_for_join: function(){
		$('#pick_a_username').submit(function(e){
			e.preventDefault();
			MadChatter.join_chat();
		});
	},

	join_chat: function(){
		var username = $.trim($('#username').val());
		if (username.length == 0) {
			alert('Please enter your name.');
			return false;
		}

		MadChatter.set_username(username);
		$('#login_screen').hide();
		$('#chat_wrapper').show();

		MadChatter.add_channel_tab('lobby', 'Lobby').trigger('click');

		$('.navbar .brand').on('click', function(e){
			e.preventDefault();
			MadChatter.join_channel('lobby');
		});

		$('#users-nav').popover({
			placement: 'bottom',
			content: function(){
				return $('.channel:visible .users-list').html();
			},
			delay: { show: 0, hide: 1000 }
		});

		$('#channels, #channel_tabs').on('click', '.join_channel', function(e){
			e.preventDefault();
			var channel_id = $(this).attr('data-channel'),
				channel_name = $(this).text();
			MadChatter.add_channel_tab(channel_id, channel_name).trigger('click');
		});

		$('#share_photo .btn-primary').on('click', function(e){
			e.preventDefault();
			var channel = $('.channel:visible').attr('data-channel'),
				$input = $(this).closest('.modal').find('input[name="url"]'),
				img_url = $input.val();
			if ($.trim(img_url).length > 0) {
				MadChatter.send_message('/img ' + img_url, channel);
				$('#share_photo').modal('hide');
				$input.val('');
			}
		});

		$('#share_code .btn-primary').on('click', function(e){
			e.preventDefault();
			var channel = $('.channel:visible').attr('data-channel'),
				$input = $(this).closest('.modal').find('textarea'),
				code = $input.val();
			if ($.trim(code).length > 0) {
				MadChatter.send_message('/code ' + code, channel);
				$('#share_code').modal('hide');
				$input.val('');
			}
		});

		$('#create_channel .btn-primary').on('click', function(e){
			e.preventDefault();
			var $input = $(this).closest('.modal').find('input');
			var channel_name = $.trim($input.val());
			if (channel_name.length > 0) {
				MadChatter.send_message('/channel create ' + channel_name);
				$('#create_channel').modal('hide');
				$input.val('');
			}
		});
	},

	set_username: function(username){
		MadChatter.username = username;
		MadChatter.send_message('/nick ' + username);
	},

	add_channel_tab: function(channel_id, channel_name){
		var $existing_channel_tab = $('#channel_tabs a[data-channel="' + channel_id + '"]');
		if ($existing_channel_tab.length > 0) {
			return $existing_channel_tab;
		}

		var $channel_tab = $('
' + channel_name + '
')

		$channel_tab.on('click', function(e){
			e.preventDefault();
			MadChatter.join_channel(channel_id);
		});

		$('#channel_tabs').append($channel_tab);
		return $channel_tab;
	},

	join_channel: function(channel_id){
		$('#channel_tabs li')
			.removeClass('active')
			.find('a[data-channel="' + channel_id + '"]').parent().addClass('active');
		$('.channel').hide();
		var $channel = $('.channel[data-channel="' + channel_id + '"]');
		if ($channel.length == 0) {
			MadChatter.send_message('/join', channel_id);
			//need to figure out how to wait for response to see if we're allowed to join
			//solution: create .channel, but when server responds, it wont send messages, it will send not-authorized message
			var $channel = $('#channel_template').clone();
			$channel
				.removeAttr('id')
				.attr('data-channel', channel_id)
				.appendTo('#chat_wrapper');
			MadChatter.add_channel_actions($channel);
		}
		if (channel_id == 'lobby') {
			$('#users-nav').hide();
		} else {
			$('#users-nav').show();
		}
		$channel.show();
	},

	add_channel_actions: function($channel){

		function send_message($input){
			var message = $input.val(),
				channel = $input.closest('.channel').attr('data-channel');
			if ($.trim(message) != '') {
				MadChatter.send_message(message, channel);
				$input.val('');
			}
		}

		$('.new_message input', $channel).keyup(function(e){
			if (e.keyCode == 13) { // The enter key.
				send_message($(this));
			}
		});

		$('.new_message .send_message', $channel).on('click', function(e){
			e.preventDefault();
			var $input = $(this).closest('.new_message').find('input');
			send_message($input);
		});
	},

	scroll_to_bottom_of_chat: function(channel_id){
		$('body')[0].scrollTop = $(document).height();
	},

	send_message: function(message, channel){
		if (message == '/clear') {
			MadChatter.clear_messages(channel);
		} else {
			var json = {
				token: MadChatter.token,
				message: message,
				channel: channel
			};
			MadChatter.ws.send(JSON.stringify(json));
		}
	},

	clear_messages: function(channel){
		$('.channel[data-channel="' + channel + '"] .messages').empty();
	},

	message_received: function(data){
		if (data.type == 'error') {
			console.log('Client error: ' + data.text)
			return;
		}
		if (data.type == 'token') {
			MadChatter.token = data.text;
			return;
		}
		if (data.type == 'channels') {
			MadChatter.update_channels_list(data.json);
			return;
		}
		if (data.type == 'users') {
			MadChatter.update_users_list(data.channel, data.json);
			return;
		}
		if (data.type == 'status') {
			MadChatter.display_status(data.channel, data.text, data.time);
		}
		if (data.type == 'action') {
			MadChatter.exec_action(data.channel, data.json);
		}
		if (data.type == 'message') {
			MadChatter.display_message(data.channel, data.username, data.html, data.time);
			if (typeof(MadChatterGrowl) != 'undefined') {
				MadChatterGrowl.send_(data.username, data.growl);
			}
		}
		MadChatter.scroll_to_bottom_of_chat();
	},

	update_channels_list: function(channels){
		var $list  = $('#channels');
		$list.html('');
		$.each(channels, function(index, channel) {
		  $list.append('
' + channel.name + '
');
		});
	},

	update_users_list: function(channel, users){
		var $list  = $('.channel[data-channel="' + channel + '"] ul.users');
		$list.find('li:not(.nav-header)').remove();
		$.each(users, function(index, username) {
		  $list.append('
' + username + '
');
		});
	},

	exec_action: function(channel, action){
		// this isnt working in IE 8...why?
		// window[action.function].apply(window, action.args);
	},

	display_status: function(channel, message, timestamp){
		var html = '
' + MadChatter.get_time_html(timestamp) + message + '
';
		$('.channel[data-channel="' + channel + '"] .messages').append(html);
	},

	display_message: function(channel, username, message, timestamp){
		var html = '
' + MadChatter.get_time_html(timestamp) + '' + username + ': ' + message + '
';
		$('.channel[data-channel="' + channel + '"] .messages').append(html);
	},

	get_time_html: function(timestamp){
		var html = '';
		var last_message_time = MadChatter.last_message_time;
		var	current_time = MadChatter.get_time_string(timestamp);
		if (last_message_time != current_time) {
			MadChatter.last_message_time = current_time;
			html = '<time>' + current_time + '</time>';
		}
		return html;
	},

	get_time_string: function(timestamp){
		var time = new Date(timestamp*1000); //timestamp must me in milliseconds
		var hours = time.getHours();
		var minutes = time.getMinutes();
		var ampm = 'am';
		if (hours > 11) { ampm = 'pm'; }
		if (minutes < 10) { minutes = "0" + minutes; }
		if (hours == 0) { hours = 12; }
		if (hours > 12) { hours = hours - 12; }
		return hours + ':' + minutes + ampm;
	}
};
<|endoftext|>


<commit_before>/**
 * @file ColGroup component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import isEmpty from 'lodash/isEmpty';

import TableFragment from '../_statics/TableFragment';
import HorizontalAlign from '../_statics/HorizontalAlign';
import SelectMode from '../_statics/SelectMode';
import SelectAllMode from '../_statics/SelectAllMode';
import SortingType from '../_statics/SortingType';

import Util from '../_vendors/Util';

class ColGroup extends Component {

    static Fragment = TableFragment;
    static Align = HorizontalAlign;
    static SelectMode = SelectMode;
    static SelectAllMode = SelectAllMode;
    static SortingType = SortingType;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    getColStyle = column => {

        const result = {};

        if (column.width != null) {
            result.width = column.width;
        }
        if (column.minWidth != null) {
            result.minWidth = column.minWidth;
        }

        return isEmpty(result) ? null : result;

    };

    render() {

        const {columns} = this.props;

        return columns ?
            <colgroup>
                {
                    columns.map((column, index) => column ?
                        <col key={index}
                             style={this.getColStyle(column)}/>
                        :
                        null
                    )
                }
            </colgroup>
            :
            null;

    }
}

ColGroup.propTypes = {

    /**
     * Children passed into table header.
     */
    columns: PropTypes.arrayOf(PropTypes.shape({

        /**
         * width of column
         */
        width: PropTypes.number,

        /**
         * minimum width of column
         */
        minWidth: PropTypes.number,

        /**
         * The class name of header.
         */
        headClassName: PropTypes.string,

        /**
         * Override the styles of header.
         */
        headStyle: PropTypes.object,

        /**
         * The render content in header.
         * (1) string，example： 'id'
         * (2) callback，example：function (colIndex) {return colIndex;}
         */
        headRenderer: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),

        /**
         * align of table header cell
         */
        headAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * column span of table header
         */
        headSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * The class name of td.
         */
        bodyClassName: PropTypes.string,

        /**
         * Override the styles of td.
         */
        bodyStyle: PropTypes.object,

        /**
         * The render content in table.
         * (1) data key，example： 'id'
         * (2) data key tamplate，example：'${id} - ${name}'
         * (3) callback，example：function (rowData, rowIndex, colIndex) {return rowData.id;}
         */
        bodyRenderer: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),

        /**
         * align of table body cell
         */
        bodyAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * column span of table body
         */
        bodySpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * The class name of footer.
         */
        footClassName: PropTypes.string,

        /**
         * Override the styles of footer.
         */
        footStyle: PropTypes.object,

        /**
         * The render content in footer.
         * (1) string，example： 'id'
         * (2) callback，example：function (colIndex) {return colIndex;}
         */
        footRenderer: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),

        /**
         * align of table footer cell
         */
        footAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * column span of table foot
         */
        footSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * If true,this column can be sorted.
         */
        sortable: PropTypes.bool,

        /**
         * Sorting property.
         */
        sortingProp: PropTypes.string,

        defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType))

    })).isRequired

};

export default ColGroup;
<commit_msg>update ColGroup<commit_after>/**
 * @file ColGroup component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import isEmpty from 'lodash/isEmpty';

import TableFragment from '../_statics/TableFragment';
import HorizontalAlign from '../_statics/HorizontalAlign';
import SelectMode from '../_statics/SelectMode';
import SelectAllMode from '../_statics/SelectAllMode';
import SortingType from '../_statics/SortingType';

import Util from '../_vendors/Util';

class ColGroup extends Component {

    static Fragment = TableFragment;
    static Align = HorizontalAlign;
    static SelectMode = SelectMode;
    static SelectAllMode = SelectAllMode;
    static SortingType = SortingType;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    getColStyle = column => {

        const result = {};

        if (column.width != null) {
            result.width = column.width;
        }
        if (column.minWidth != null) {
            result.minWidth = column.minWidth;
        }

        return isEmpty(result) ? null : result;

    };

    render() {

        const {columns} = this.props;

        return columns ?
            <colgroup>
                {
                    columns.map(({column}, index) => column ?
                        <col key={index}
                             style={this.getColStyle(column)}/>
                        :
                        null
                    )
                }
            </colgroup>
            :
            null;

    }
}

ColGroup.propTypes = {

    /**
     * Children passed into table header.
     */
    columns: PropTypes.arrayOf(PropTypes.shape({

        /**
         * width of column
         */
        width: PropTypes.number,

        /**
         * minimum width of column
         */
        minWidth: PropTypes.number,

        /**
         * The class name of header.
         */
        headClassName: PropTypes.string,

        /**
         * Override the styles of header.
         */
        headStyle: PropTypes.object,

        /**
         * The render content in header.
         * (1) string，example： 'id'
         * (2) callback，example：function (colIndex) {return colIndex;}
         */
        headRenderer: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),

        /**
         * align of table header cell
         */
        headAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * column span of table header
         */
        headSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * The class name of td.
         */
        bodyClassName: PropTypes.string,

        /**
         * Override the styles of td.
         */
        bodyStyle: PropTypes.object,

        /**
         * The render content in table.
         * (1) data key，example： 'id'
         * (2) data key tamplate，example：'${id} - ${name}'
         * (3) callback，example：function (rowData, rowIndex, colIndex) {return rowData.id;}
         */
        bodyRenderer: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),

        /**
         * align of table body cell
         */
        bodyAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * column span of table body
         */
        bodySpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * The class name of footer.
         */
        footClassName: PropTypes.string,

        /**
         * Override the styles of footer.
         */
        footStyle: PropTypes.object,

        /**
         * The render content in footer.
         * (1) string，example： 'id'
         * (2) callback，example：function (colIndex) {return colIndex;}
         */
        footRenderer: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),

        /**
         * align of table footer cell
         */
        footAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * column span of table foot
         */
        footSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * If true,this column can be sorted.
         */
        sortable: PropTypes.bool,

        /**
         * Sorting property.
         */
        sortingProp: PropTypes.string,

        defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType))

    })).isRequired

};

export default ColGroup;
<|endoftext|>