<commit_before>/************************************************************************
Author: Eric Simmons
Contact: info AT jswitch DOT com
Website: http://www.jswitch.com
Version: 2.0 12/2005
Browser Target: Mozilla 6+/FireFox Netscape 6+, IE 5.0+
Type: XP Style Menus ver 2

DISCLAIMER:
THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT
ANY EXPRESS OR IMPLIED WARRANTIES, JSWITCH.COM
IS NOT RESPONSIBLE FOR ANY ADVERSE AFFECTS TO
YOUR COMPUTER OR SYSTEMS RUNNING THIS SCRIPT.

LICENSE:
YOU ARE GRANTED THE RIGHT TO USE THE SCRIPT
PERSONALLY OR COMMERCIALLY. THE AUTHOR, WEBSITE LINKS
AND LICENSE INFORMATION IN THE HEADER OF THIS SCRIPT
MUST NOT BE MODIFIED OR REMOVED. IF PORTIONS OF THE
CODE ARE TRANSFERED TO ANOTHER SCRIT THE AUTHORS NAME
AND CONTACT INFORMATION MUST BE STATED IN THE NEW SCRIPT
BY THE PORTIONS CODE THAT HAVE BEEN TRANSFERED.

v 2.0
-W3C HTML 4.01 Transitional compliant
-Support for initially open menu
-New fading capability
-Cookie menu persistence
-Redesigned code

Notes:

If you want a menu to be open initially set the style display to
"inline" in the subMenu class div like this...

The fading effect can be disabled by setting the
doFading var to false. I have only tested this feature on
ie 6, Netscape 1.7, firefox 1 & 1.5

If the user has cookies enabled the script will bake a cookie ;) on
the browser to track the state of the menus. This is good news for those
of you who don't use frames, you can now have persistent menu states

In version 2's example I have also added some wintery, <- is that even a word,
themes to the menus, You can see how I did by looking at the html and the
style sheet.

Make sure you put the java script include tag after all the menus otherwise
it will not be able find and initialize them. If you have questions, or comments
about the XpStyle Menu v2 send me an email.

And lastly a plug for myself, If you need some professional help with technical
web development please drop me an email, I do contracts for a competitive price. :)

v 1.0
XP style sliding Menu Bar

***********************************************************************/

var menuObjArray = new Array();
menuObjArray[0] = new Array();
menuObjArray[1] = new Array();
menuObjArray[2] = new Array();
menuObjArray[3] = new Array();
menuObjArray[4] = new Array();
menuObjArray[5] = new Array();
menuObjArray[6] = new Array();
menuObjArray[7] = new Array();

var timerSlide = null;
var numMenuItem = 0;
var slideDelay = 0;
var divHeight = 22;
var moveSlidePix = 60;
var isLocked = false;
var doFading = false;

InitAll();

function InitAll()
{
	var divs = document.getElementsByTagName("DIV");
	menuStateAry = GetUserCookie("xpMenuCookv2").split(",");

	aryNum = 0;
	for(dn=0; dn < divs.length;dn++)
	{
		if(String(divs.item(dn).className).substring(0,7) == "topItem")
		{
			mainMenuDiv = divs.item(dn).parentNode;
			menuContainerDiv= mainMenuDiv.getElementsByTagName("DIV").item(1);
			itemContainerDiv= menuContainerDiv.getElementsByTagName("DIV").item(0);

			if(menuStateAry != 0)
				itemContainerDiv.style.height = parseInt(menuStateAry[aryNum]) + "px";

			if(!doFading)
			{

				if (menuContainerDiv.filters)
					menuContainerDiv.filters.alpha.opacity = 100;
				else
					menuContainerDiv.opacity = 1;
			}

			if(menuStateAry != 0 )
			{
				if( parseInt(menuStateAry[aryNum]) == 0)
					itemContainerDiv.style.display = 'none';
				else
					itemContainerDiv.style.display = 'inline';
			}

			Init(divs.item(dn));
			aryNum++;

		}
	}
}

function Init(objDiv)
{

    if (isLocked)
        return;

    var mainMenuDiv, subMenuDiv, menuContainerDiv, itemContainerDiv,styleRules;

	for(r=0;r < document.styleSheets.length; r++)
	{
		if( -1 != String(document.styleSheets[r].href).indexOf("sddm.css") )
			break;
	}
	if(!document.styleSheets[r].rules)
		styleRules = document.styleSheets[r].cssRules;
	else
		styleRules = document.styleSheets[r].rules;

    numMenuItem = 0;
    mainMenuDiv = objDiv.parentNode;
    subMenuDiv =  mainMenuDiv.getElementsByTagName("DIV").item(0);

    menuContainerDiv= mainMenuDiv.getElementsByTagName("DIV").item(1);
    itemContainerDiv= menuContainerDiv.getElementsByTagName("DIV").item(0);

    aLen = menuObjArray[0].length;
    for (i=0 ;i < aLen ; i++)
    {
        if (menuObjArray[0][i] == menuContainerDiv)
        {
            break;
        }
    }

    if (i == aLen)
    {
        menuObjArray[0][i]  = menuContainerDiv;
        menuObjArray[1][i] = itemContainerDiv;
        menuObjArray[7][i] = subMenuDiv;
        subMenuDiv.onclick = SetSlide;

		lastmenuNum = -1;
        for (b=0;b<itemContainerDiv.childNodes.length;b++)
        {
            if (itemContainerDiv.childNodes.item(b).tagName == "SPAN")
            {
                numMenuItem ++;
                itemContainerDiv.childNodes.item(b).onmouseover= ChangeStyle;
                itemContainerDiv.childNodes.item(b).onmouseout= ChangeStyle;
                lastmenuNum = b;
            }
        }

		for(r=0;r < styleRules.length; r++)
		{
			tmpStr1 = String(styleRules[r].selectorText);
			tmpStr2 = String("." + itemContainerDiv.childNodes.item(lastmenuNum).className);
			if(tmpStr1 == tmpStr2)
			{
				if(NaN != parseInt(styleRules[r].style.height))
				{
					divHeight = parseInt(styleRules[r].style.height);
					break;
				}

			}
		}

        menuObjArray[2][i] = numMenuItem;
        menuObjArray[3][i] = mainMenuDiv;

        if (itemContainerDiv.style.display == "inline")
        {
            menuObjArray[4][i] = numMenuItem * divHeight;
            menuObjArray[0][i].style.height = numMenuItem * divHeight + "px";
            menuObjArray[6][i] = true;
            if(doFading)
			{
				if (menuObjArray[0][i].filters)
					menuObjArray[0][i].filters.alpha.opacity = 100;
				else
					menuObjArray[0][i].style.opacity = 1;
			}

        } else
        {
			menuObjArray[7][i].className = menuObjArray[7][i].className+"Over";
            menuObjArray[4][i] = 0;
            menuObjArray[0][i].style.height = 0 + "px";
            menuObjArray[6][i] = false;
            if(doFading)
			{
				if (menuObjArray[0][i].filters) {
					menuObjArray[0][i].filters.alpha.opacity = 0;}
				else
					menuObjArray[0][i].style.opacity = .0;
			}
        }

    }//end if

    mainMenuDiv = null;
    subMenuDiv =  null;
    menuContainerDiv= null;
    itemContainerDiv= null;

}

function SetSlide()
{
    if (isLocked)
        return;
    else
        isLocked = true;
    for (i=0 ;i < menuObjArray[0].length; i++)
    {
        if (menuObjArray[3][i] == this.parentNode)
        {
            if (menuObjArray[5][i] == null)
                menuObjArray[5][i] = setInterval("RunSlide(" + i + ")", slideDelay);
            break;
        }
    }

}

function UpdateUserCookie(aryIndex)
{
    date = new Date();
    date.setTime(date.getTime() + (1000 * 60 * 60 * 24 * 30));
    document.cookie = "xpMenuCookv2" + "=" + escape(menuObjArray[4].toString()) + "; expires=" + date.toGMTString();

}

function GetUserCookie(crumbName)
{
    colCookie = document.cookie.split("; ");

    for (a=0; a < colCookie.length; a++)
    {
        colCrumb = colCookie[a].split("=");
        if(colCrumb[0] == crumbName)
            return unescape(colCrumb[1]);
    }

    return "";

}

function RunSlide(objIndex)
{

    if (menuObjArray[6][objIndex])
    {
		if(doFading)
		{
			if(menuObjArray[0][objIndex].filters)
				menuObjArray[0][objIndex].filters.alpha.opacity -= 100/ ( ( (menuObjArray[2][i] * divHeight) / moveSlidePix) +1);
			else
				menuObjArray[0][objIndex].style.opacity -= .9/(((menuObjArray[2][i] * divHeight) / moveSlidePix)+1);
		}
        menuObjArray[1][objIndex].style.display = 'none';
        menuObjArray[4][objIndex] -=  moveSlidePix;
        if (menuObjArray[4][objIndex] > 0)
            menuObjArray[0][objIndex].style.height = menuObjArray[4][i] + "px";
        else
        {
            if(doFading)
			{
				if(menuObjArray[0][objIndex].filters)
					menuObjArray[0][objIndex].filters.alpha.opacity = 0;
				else
					menuObjArray[0][objIndex].style.opacity = 0;
			}

			menuObjArray[7][objIndex].className = menuObjArray[7][objIndex].className+"Over";

            menuObjArray[4][objIndex] = 0;
            menuObjArray[0][objIndex].style.height = 0 + "px";
            clearInterval(menuObjArray[5][objIndex]);
            menuObjArray[5][objIndex] = null;
            menuObjArray[6][objIndex] = false;
            isLocked = false;
            UpdateUserCookie(objIndex);
            return 0;
        }

        return 0;

    }

    if (!menuObjArray[6][objIndex])
    {
		if(doFading)
		{
			if(menuObjArray[0][objIndex].filters)
				menuObjArray[0][objIndex].filters.alpha.opacity += 100/ ( ( (menuObjArray[2][i] * divHeight) / moveSlidePix) +1);
			else
			{
				opcVal = parseFloat(menuObjArray[0][objIndex].style.opacity);
				opcVal += .9/((menuObjArray[2][i] * divHeight) / moveSlidePix);
				menuObjArray[0][objIndex].style.opacity = opcVal;
			}
		}
        menuObjArray[4][objIndex] +=  moveSlidePix;
        if (menuObjArray[4][objIndex] < (menuObjArray[2][objIndex] * divHeight))
            menuObjArray[0][objIndex].style.height = menuObjArray[4][i] + "px";
        else
        {

			if(doFading)
			{
				if(menuObjArray[0][objIndex].filters)
					menuObjArray[0][objIndex].filters.alpha.opacity = 100;
				else
					menuObjArray[0][objIndex].style.opacity = 1;
			}
			strClassName = String(menuObjArray[7][objIndex].className);
			menuObjArray[7][objIndex].className = strClassName.substring(0,strClassName.length - 4);
			menuObjArray[4][objIndex] = (menuObjArray[2][objIndex] * divHeight);
			menuObjArray[0][objIndex].style.height = (menuObjArray[2][objIndex] * divHeight)+ "px";
            menuObjArray[1][objIndex].style.display = 'inline';
            clearInterval(menuObjArray[5][objIndex]);
            menuObjArray[5][objIndex] = null;
            menuObjArray[6][objIndex] = true;
            isLocked = false;
             UpdateUserCookie(objIndex);
            return 0;
        }
        return 0;

    }

}

function ChangeStyle()
{
    className = String(this.className);

    if (className.substring(className.length - 4, className.length) == "Over")
        this.className = className.substring(0,className.length - 4);
    else
        this.className = this.className + "Over";

}
function changeColor(id, color) {
  document.getElementById(id).style.color = color;
}
<commit_msg>modified the menu defaults<commit_after>/************************************************************************
Author: Eric Simmons
Contact: info AT jswitch DOT com
Website: http://www.jswitch.com
Version: 2.0 12/2005
Browser Target: Mozilla 6+/FireFox Netscape 6+, IE 5.0+
Type: XP Style Menus ver 2

DISCLAIMER:
THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT
ANY EXPRESS OR IMPLIED WARRANTIES, JSWITCH.COM
IS NOT RESPONSIBLE FOR ANY ADVERSE AFFECTS TO
YOUR COMPUTER OR SYSTEMS RUNNING THIS SCRIPT.

LICENSE:
YOU ARE GRANTED THE RIGHT TO USE THE SCRIPT
PERSONALLY OR COMMERCIALLY. THE AUTHOR, WEBSITE LINKS
AND LICENSE INFORMATION IN THE HEADER OF THIS SCRIPT
MUST NOT BE MODIFIED OR REMOVED. IF PORTIONS OF THE
CODE ARE TRANSFERED TO ANOTHER SCRIT THE AUTHORS NAME
AND CONTACT INFORMATION MUST BE STATED IN THE NEW SCRIPT
BY THE PORTIONS CODE THAT HAVE BEEN TRANSFERED.

v 2.0
-W3C HTML 4.01 Transitional compliant
-Support for initially open menu
-New fading capability
-Cookie menu persistence
-Redesigned code

Notes:

If you want a menu to be open initially set the style display to
"inline" in the subMenu class div like this...

The fading effect can be disabled by setting the
doFading var to false. I have only tested this feature on
ie 6, Netscape 1.7, firefox 1 & 1.5

If the user has cookies enabled the script will bake a cookie ;) on
the browser to track the state of the menus. This is good news for those
of you who don't use frames, you can now have persistent menu states

In version 2's example I have also added some wintery, <- is that even a word,
themes to the menus, You can see how I did by looking at the html and the
style sheet.

Make sure you put the java script include tag after all the menus otherwise
it will not be able find and initialize them. If you have questions, or comments
about the XpStyle Menu v2 send me an email.

And lastly a plug for myself, If you need some professional help with technical
web development please drop me an email, I do contracts for a competitive price. :)

v 1.0
XP style sliding Menu Bar

***********************************************************************/

var menuObjArray = new Array();
menuObjArray[0] = new Array();
menuObjArray[1] = new Array();
menuObjArray[2] = new Array();
menuObjArray[3] = new Array();
menuObjArray[4] = new Array();
menuObjArray[5] = new Array();
menuObjArray[6] = new Array();
menuObjArray[7] = new Array();

var timerSlide = null;
var numMenuItem = 0;
var slideDelay = 0;
var divHeight = 22;
var moveSlidePix = 60;
var isLocked = false;
var doFading = false;

function InitAll()
{
	var divs = document.getElementsByTagName("DIV");
	menuStateAry = GetUserCookie("xpMenuCookv2").split(",");

	aryNum = 0;
	for(dn=0; dn < divs.length;dn++)
	{
		if(String(divs.item(dn).className).substring(0,7) == "topItem")
		{
			mainMenuDiv = divs.item(dn).parentNode;
			menuContainerDiv= mainMenuDiv.getElementsByTagName("DIV").item(1);
			itemContainerDiv= menuContainerDiv.getElementsByTagName("DIV").item(0);

			if(menuStateAry != 0)
				itemContainerDiv.style.height = parseInt(menuStateAry[aryNum]) + "px";

			if(!doFading)
			{

				if (menuContainerDiv.filters)
					menuContainerDiv.filters.alpha.opacity = 100;
				else
					menuContainerDiv.opacity = 1;
			}

			if(menuStateAry != 0 )
			{
				if( parseInt(menuStateAry[aryNum]) != 0)
					//itemContainerDiv.style.display = 'none';
//				else
					itemContainerDiv.style.display = 'inline';
			}

			Init(divs.item(dn));
			aryNum++;

		}
	}
}

function Init(objDiv)
{

    if (isLocked)
        return;

    var mainMenuDiv, subMenuDiv, menuContainerDiv, itemContainerDiv,styleRules;

	for(r=0;r < document.styleSheets.length; r++)
	{
		if( -1 != String(document.styleSheets[r].href).indexOf("sddm.css") )
			break;
	}
	if(!document.styleSheets[r].rules)
		styleRules = document.styleSheets[r].cssRules;
	else
		styleRules = document.styleSheets[r].rules;

    numMenuItem = 0;
    mainMenuDiv = objDiv.parentNode;
    subMenuDiv =  mainMenuDiv.getElementsByTagName("DIV").item(0);

    menuContainerDiv= mainMenuDiv.getElementsByTagName("DIV").item(1);
    itemContainerDiv= menuContainerDiv.getElementsByTagName("DIV").item(0);

    aLen = menuObjArray[0].length;
    for (i=0 ;i < aLen ; i++)
    {
        if (menuObjArray[0][i] == menuContainerDiv)
        {
            break;
        }
    }

    if (i == aLen)
    {
        menuObjArray[0][i]  = menuContainerDiv;
        menuObjArray[1][i] = itemContainerDiv;
        menuObjArray[7][i] = subMenuDiv;
        subMenuDiv.onclick = SetSlide;

		lastmenuNum = -1;
        for (b=0;b<itemContainerDiv.childNodes.length;b++)
        {
            if (itemContainerDiv.childNodes.item(b).tagName == "SPAN")
            {
                numMenuItem ++;
                itemContainerDiv.childNodes.item(b).onmouseover= ChangeStyle;
                itemContainerDiv.childNodes.item(b).onmouseout= ChangeStyle;
                lastmenuNum = b;
            }
        }

		for(r=0;r < styleRules.length; r++)
		{
			tmpStr1 = String(styleRules[r].selectorText);
			tmpStr2 = String("." + itemContainerDiv.childNodes.item(lastmenuNum).className);
			if(tmpStr1 == tmpStr2)
			{
				if(NaN != parseInt(styleRules[r].style.height))
				{
					divHeight = parseInt(styleRules[r].style.height);
					break;
				}

			}
		}

        menuObjArray[2][i] = numMenuItem;
        menuObjArray[3][i] = mainMenuDiv;

        if (itemContainerDiv.style.display == "inline")
        {
            menuObjArray[4][i] = numMenuItem * divHeight;
            menuObjArray[0][i].style.height = numMenuItem * divHeight + "px";
            menuObjArray[6][i] = true;
            if(doFading)
			{
				if (menuObjArray[0][i].filters)
					menuObjArray[0][i].filters.alpha.opacity = 100;
				else
					menuObjArray[0][i].style.opacity = 1;
			}

        } else
        {
			menuObjArray[7][i].className = menuObjArray[7][i].className+"Over";
            menuObjArray[4][i] = 0;
            menuObjArray[0][i].style.height = 0 + "px";
            menuObjArray[6][i] = false;
            if(doFading)
			{
				if (menuObjArray[0][i].filters) {
					menuObjArray[0][i].filters.alpha.opacity = 0;}
				else
					menuObjArray[0][i].style.opacity = .0;
			}
        }

    }//end if

    mainMenuDiv = null;
    subMenuDiv =  null;
    menuContainerDiv= null;
    itemContainerDiv= null;

}

function SetSlide()
{
    if (isLocked)
        return;
    else
        isLocked = true;
    for (i=0 ;i < menuObjArray[0].length; i++)
    {
        if (menuObjArray[3][i] == this.parentNode)
        {
            if (menuObjArray[5][i] == null)
                menuObjArray[5][i] = setInterval("RunSlide(" + i + ")", slideDelay);
            break;
        }
    }

}

function UpdateUserCookie(aryIndex)
{
    date = new Date();
    date.setTime(date.getTime() + (1000 * 60 * 60 * 24 * 30));
    document.cookie = "xpMenuCookv2" + "=" + escape(menuObjArray[4].toString()) + "; expires=" + date.toGMTString();

}

function GetUserCookie(crumbName)
{
    colCookie = document.cookie.split("; ");

    for (a=0; a < colCookie.length; a++)
    {
        colCrumb = colCookie[a].split("=");
        if(colCrumb[0] == crumbName)
            return unescape(colCrumb[1]);
    }

    return "";

}

function RunSlide(objIndex)
{

    if (menuObjArray[6][objIndex])
    {
		if(doFading)
		{
			if(menuObjArray[0][objIndex].filters)
				menuObjArray[0][objIndex].filters.alpha.opacity -= 100/ ( ( (menuObjArray[2][i] * divHeight) / moveSlidePix) +1);
			else
				menuObjArray[0][objIndex].style.opacity -= .9/(((menuObjArray[2][i] * divHeight) / moveSlidePix)+1);
		}
        menuObjArray[1][objIndex].style.display = 'none';
        menuObjArray[4][objIndex] -=  moveSlidePix;
        if (menuObjArray[4][objIndex] > 0)
            menuObjArray[0][objIndex].style.height = menuObjArray[4][i] + "px";
        else
        {
            if(doFading)
			{
				if(menuObjArray[0][objIndex].filters)
					menuObjArray[0][objIndex].filters.alpha.opacity = 0;
				else
					menuObjArray[0][objIndex].style.opacity = 0;
			}

			menuObjArray[7][objIndex].className = menuObjArray[7][objIndex].className+"Over";

            menuObjArray[4][objIndex] = 0;
            menuObjArray[0][objIndex].style.height = 0 + "px";
            clearInterval(menuObjArray[5][objIndex]);
            menuObjArray[5][objIndex] = null;
            menuObjArray[6][objIndex] = false;
            isLocked = false;
            UpdateUserCookie(objIndex);
            return 0;
        }

        return 0;

    }

    if (!menuObjArray[6][objIndex])
    {
		if(doFading)
		{
			if(menuObjArray[0][objIndex].filters)
				menuObjArray[0][objIndex].filters.alpha.opacity += 100/ ( ( (menuObjArray[2][i] * divHeight) / moveSlidePix) +1);
			else
			{
				opcVal = parseFloat(menuObjArray[0][objIndex].style.opacity);
				opcVal += .9/((menuObjArray[2][i] * divHeight) / moveSlidePix);
				menuObjArray[0][objIndex].style.opacity = opcVal;
			}
		}
        menuObjArray[4][objIndex] +=  moveSlidePix;
        if (menuObjArray[4][objIndex] < (menuObjArray[2][objIndex] * divHeight))
            menuObjArray[0][objIndex].style.height = menuObjArray[4][i] + "px";
        else
        {

			if(doFading)
			{
				if(menuObjArray[0][objIndex].filters)
					menuObjArray[0][objIndex].filters.alpha.opacity = 100;
				else
					menuObjArray[0][objIndex].style.opacity = 1;
			}
			strClassName = String(menuObjArray[7][objIndex].className);
			menuObjArray[7][objIndex].className = strClassName.substring(0,strClassName.length - 4);
			menuObjArray[4][objIndex] = (menuObjArray[2][objIndex] * divHeight);
			menuObjArray[0][objIndex].style.height = (menuObjArray[2][objIndex] * divHeight)+ "px";
            menuObjArray[1][objIndex].style.display = 'inline';
            clearInterval(menuObjArray[5][objIndex]);
            menuObjArray[5][objIndex] = null;
            menuObjArray[6][objIndex] = true;
            isLocked = false;
             UpdateUserCookie(objIndex);
            return 0;
        }
        return 0;

    }

}

function ChangeStyle()
{
    className = String(this.className);

    if (className.substring(className.length - 4, className.length) == "Over")
        this.className = className.substring(0,className.length - 4);
    else
        this.className = this.className + "Over";

}
function changeColor(id, color) {
  document.getElementById(id).style.color = color;
}
<|endoftext|>


<commit_before>import {LightningElement, api, track, wire} from 'lwc';
import {isNotEmpty, debouncify, isUndefined} from 'c/utilCommon';
import GeFormService from 'c/geFormService';
import GeLabelService from 'c/geLabelService';
import {getObjectInfo} from "lightning/uiObjectInfoApi";
import { fireEvent } from 'c/pubsubNoPageRef';
import DI_DONATION_AMOUNT from '@salesforce/schema/DataImport__c.Donation_Amount__c';
import DONATION_DONOR_FIELD from '@salesforce/schema/DataImport__c.Donation_Donor__c';
import DONATION_RECORD_TYPE_NAME from '@salesforce/schema/DataImport__c.Donation_Record_Type_Name__c';

const LOOKUP_TYPE = 'REFERENCE';
const PICKLIST_TYPE = 'PICKLIST';
const TEXT_AREA_TYPE = 'TEXTAREA';
const BOOLEAN_TYPE = 'BOOLEAN';
const DELAY = 300;
const RICH_TEXT_FORMATS = [
    'font', 'size', 'bold', 'italic', 'underline', 'strike', 'list', 'indent', 'align', 'link', 'clean', 'table', 'header'
];
const CURRENCY = 'currency';
const PERCENT = 'percent';
const DECIMAL = 'decimal';

export default class GeFormField extends LightningElement {
    @track value;
    @track picklistValues = [];
    @track objectDescribeInfo;
    @track richTextValid = true;
    @track _disabled = false;
    @api element;
    @api targetFieldName;
    _defaultValue = null;
    _recordTypeId;

    richTextFormats = RICH_TEXT_FORMATS;
    CUSTOM_LABELS = GeLabelService.CUSTOM_LABELS;

    handleValueChangeSync = (event) => {
        this.value = this.getValueFromChangeEvent(event);
        const detail = {
            element: this.element,
            value: this.value,
            targetFieldName: this.targetFieldName
        };
        const evt = new CustomEvent('valuechange', {detail, bubbles: true});
        this.dispatchEvent(evt);

        if (this.isLookup) {
            const objMappingDevName =
                GeFormService.importedRecordFieldNames.includes(this.fieldApiName) ?
                    GeFormService.getObjectMappingWrapperByImportedFieldName(this.fieldApiName)
                        .DeveloperName :
                    this.objectMappingDevName;

            const detail = {
                ...event.detail,
                objectMappingDevName: objMappingDevName
            }

            const selectRecordEvent = new CustomEvent(
                'lookuprecordselect',
                { detail: detail });
            this.dispatchEvent(selectRecordEvent);
        }

        if (this.isPicklist) {
            this.handlePicklistChange();
        }

        if(this.isRichText) {
            this.checkRichTextValidity();
        }

        if(this.sourceFieldAPIName === DI_DONATION_AMOUNT.fieldApiName) {
            // fire event for reactive widget component containing the Data Import field API name and Value
            // currently only used for the Donation Amount.
            fireEvent(null, 'widgetData', { donationAmount: this.value });
        }
    };

    handleValueChange = debouncify(this.handleValueChangeSync.bind(this), DELAY);

    handlePicklistChange() {
        if (this.fieldApiName === DONATION_DONOR_FIELD.fieldApiName) {
            const changeDonationDonorEvent = new CustomEvent(
                'changedonationdonor',
                {detail: {value: this.value}});
            this.dispatchEvent(changeDonationDonorEvent);
        }
    }

    /**
     * Retrieve object metadata. Used to configure how fields are displayed on the form.
     */
    @wire(getObjectInfo, { objectApiName: '$objectApiName' })
    wiredObjectInfo(response) {
        if(response.data) {
            this.objectDescribeInfo = response.data;
        }
    }

    connectedCallback() {
        const { defaultValue, recordValue } = this.element;

        if(recordValue) {

            // set the record value to the element value
            this.value = recordValue;
        } else if(defaultValue) {

            // Set the default value if there is one
            // and no record value.
            this._defaultValue = defaultValue;
            this.value = defaultValue;
            this.handlePicklistChange();
        }
    }

    getValueFromChangeEvent(event) {
        if(this.fieldType === BOOLEAN_TYPE) {
            return event.detail.checked.toString();
        } else if(this.isRichText) {
            return event.target.value;
        }

        return event.detail.value;
    }

    /**
     * TRUE when a field is required and filled in correctly, or not required at all.
     * @returns {boolean}
     */
    @api
    isValid() {
        // We need to check for invalid values, regardless if the field is required
        let fieldIsValid = this.checkFieldValidity();

        if(this.element !== null && this.element.required) {
            return isNotEmpty(this.value) && fieldIsValid;
        }

        return fieldIsValid;
    }

    /**
     * TRUE when a field is filled in, and is the correct format.
     * @returns {boolean}
     */
    checkFieldValidity() {
        // TODO: Handle other input types, if needed
        const inputField = this.template.querySelector('[data-id="inputComponent"]');
        if(typeof inputField !== 'undefined'
            && inputField !== null
            && typeof inputField.reportValidity === 'function'
            && typeof inputField.checkValidity === 'function') {
                inputField.reportValidity();
                return inputField.checkValidity();
        } else if(this.isRichText) {
            this.checkRichTextValidity();
            if(!this.richTextValid) {
                // workaround, field will not display as invalid if it is untouched
                inputField.focus();
                inputField.blur();
            }
            return this.richTextValid;
        }
        return true;
    }

    checkRichTextValidity() {
        if(this.element.required) {
            const isValid = isNotEmpty(this.value) && this.value.length > 0;
            this.richTextValid = isValid;
            return isValid;
        }
        return true;
    }

    @api
    disable() {
        this._disabled = true;
    }

    @api
    enable() {
        this._disabled = false;
    }

    @api
    get fieldAndValue() {
        let fieldAndValue = {};

        // KIET TBD: This is where we are keeping the field mapping
        // CMT record name at, element.value.
        // However, it may change to the array dataImportFieldMappingDevNames
        // If so, we need to update this to reflect that.
        // In the Execute Anonymous code, both fields are populated.

        if (this.value &&
            this.sourceFieldAPIName === DONATION_RECORD_TYPE_NAME.fieldApiName &&
            Object.keys(this.objectDescribeInfo.recordTypeInfos).includes(this.value)) {
            // value is the RecordType Id, but the DataImport's source field expects
            // the RecordType Name
            fieldAndValue[this.formElementName] =
                this.objectDescribeInfo.recordTypeInfos[this.value].name;
        } else {
            fieldAndValue[this.formElementName] = this.value;
        }

        return fieldAndValue;
    }

    get formElementName() {
        return this.element.componentName ? this.element.componentName : this.element.dataImportFieldMappingDevNames[0];
    }

    get inputType() {
        return GeFormService.getInputTypeFromDataType(this.fieldType);
    }

    get formatter() {
        return GeFormService.getNumberFormatterByDescribeType(this.fieldType);
    }

    get required() {
        return (this.fieldInfo && this.fieldInfo.Is_Required && this.fieldType !== BOOLEAN_TYPE) ||
            (this.element && this.element.required);
    }

    get disabled() {
        return this._disabled || (this.element && this.element.disabled);
    }

    get granularity() {
        if (this.formatter) {
            switch (this.fieldType.toLowerCase()) {
                case CURRENCY: return '0.01';
                case PERCENT: return '0.01';
                case DECIMAL: return '0.001';
                default: return 'any';
            }
        }
        return undefined;
    }

    get fieldInfo() {
        return isNotEmpty(this.targetFieldName) ?
            GeFormService.getFieldMappingWrapperFromTarget(this.targetFieldName) :
            GeFormService.getFieldMappingWrapper(this.formElementName);
    }

    get fieldDescribeInfo() {
        if(this.objectDescribeInfo) {
            return this.objectDescribeInfo.fields[this.fieldApiName];
        }
    }

    get objectInfo() {
        return GeFormService.getObjectMappingWrapper(this.objectMappingDevName);
    }

    get fieldType() {
        return this.fieldInfo.Target_Field_Data_Type;
    }

    get isLightningInput() {
        return typeof GeFormService.getInputTypeFromDataType(this.fieldType) !== 'undefined';
    }

    get isRichText() {
        if(typeof this.fieldDescribeInfo !== 'undefined' && this.fieldType === TEXT_AREA_TYPE) {
            return this.fieldDescribeInfo.htmlFormatted;
        }
    }

    @api
    get isLookup() {
        return this.fieldType === LOOKUP_TYPE;
    }

    @api
    get isPicklist() {
        return this.fieldType === PICKLIST_TYPE;
    }

    get isTextArea() {
        if(typeof this.fieldDescribeInfo !== 'undefined' && this.fieldType === TEXT_AREA_TYPE) {
            return !this.fieldDescribeInfo.htmlFormatted;
        }
    }

    @api
    get objectMappingDevName() {
        return this.fieldInfo.Target_Object_Mapping_Dev_Name;
    }

    get objectApiName() {
        if(typeof this.objectInfo !== 'undefined') {
            return this.objectInfo.Object_API_Name;
        }
    }

    get fieldApiName() {
        return this.fieldInfo.Target_Field_API_Name;
    }

    @api
    get sourceFieldAPIName() {
        return this.fieldInfo.Source_Field_API_Name;
    }

    @api
    get fieldLabel() {
        return this.element.customLabel;
    }

    @api
    get fieldValueAndLabel() {

        let fieldWrapper = { value: this.value, label: this.fieldLabel };
        let returnMap = {};
        returnMap[ this.sourceFieldAPIName ] = fieldWrapper;

        return returnMap;

    }

    @api
    setCustomValidity(errorMessage) {

        let inputField = this.template.querySelector('[data-id="inputComponent"]');
        inputField.setCustomValidity(errorMessage);
        inputField.reportValidity();

    }

    @api
    clearCustomValidity() {

        if (this.isLookup) {
            let inputField = this.template.querySelector('[data-id="inputComponent"]');
            inputField.clearCustomValidity();
        } else {
            this.setCustomValidity('');
        }

    }

    /**
     * Load a value into the form field.
     * @param data  An sObject potentially containing a value to load.
     * */
    @api
    load(data) {
        let value;
        if (data.hasOwnProperty(this.sourceFieldAPIName)) {
            value = data[this.sourceFieldAPIName];
            if (value === null || value.value === null) {
                this.reset();
            } else {
                this.value = value.value || value;

                if (this.isLookup) {
                    if (this.fieldApiName === 'RecordTypeId') {
                        if (value && !value.displayName) {
                            // If the RecordTypeId field for a target record is being
                            // loaded with only the Id (like when a Lookup field is
                            // selected/populated on the form), get the RecordType Name
                            // and pass it with the Id to loadLookup
                            data[this.sourceFieldAPIName] = {
                                value: value,
                                displayValue: this.getRecordTypeNameById(value)
                            };
                        }
                    }
                    this.loadLookUp(data, this.value);
                }
            }

            if (this.sourceFieldAPIName === DI_DONATION_AMOUNT.fieldApiName) {
                // fire event for reactive widget component containing the Data Import field API name and Value
                // currently only used for the Donation Amount.
                fireEvent(null, 'widgetData', {donationAmount: this.value});
            }

        } else if (!isUndefined(data.value)) {
            // When the geFormField cmp is used inside of geFormWidgetAllocation,
            // geFormWidgetAllocation selects the field cmp to load a value into manually,
            // and passes an {value: <value>} object.  To support that case this block
            // loads the value directly even though data does not have a property for
            // this.sourceFieldAPIName
           this.value = data.value;
        } else {
            // Property isn't defined.  Don't do anything.
            return false;
        }
    }

    /**
     * Loads a value into a look-up field
     * @param data An sObject potentially containing a value to load.
     * @param value A form field value
     */
    loadLookUp(data, value) {
        const lookup = this.template.querySelector('c-ge-form-field-lookup');

        let displayValue;
        const relationshipFieldName = this.sourceFieldAPIName.replace('__c', '__r');

        if (data[relationshipFieldName] &&
            data[relationshipFieldName]['Name']) {
            displayValue = data[relationshipFieldName].Name;

        } else if (data[this.sourceFieldAPIName] &&
            data[this.sourceFieldAPIName]['displayValue']) {
            displayValue = data[this.sourceFieldAPIName].displayValue;

        } else if (data.displayValue) {
            displayValue = data.displayValue;

        }

        lookup.setSelected({value, displayValue});
    }

    @api
    reset() {
        this.value = this._defaultValue;

        if (this.isLookup) {
            const lookup = this.template.querySelector('c-ge-form-field-lookup');
            lookup.reset();
            if (this.fieldApiName === 'RecordTypeId') {
                // Using setTimeout here ensures that this recordTypeId
                // will be set on sibling fields after they are reset by queueing the event.
                setTimeout(() => {
                    this.fireLookupRecordSelectEvent();
                }, 0);
            }
        }

        if (this.isPicklist) {
            this.template.querySelector('c-ge-form-field-picklist').reset();
            this.handlePicklistChange();
        }
    }

    @api
    set recordTypeId(id) {
        this._recordTypeId = id;
        this.setRecordTypeIdOnChildComponents();
    }

    get recordTypeId() {
        return this._recordTypeId;
    }

    setRecordTypeIdOnChildComponents() {
        if (this.isPicklist) {
            this.template.querySelector('c-ge-form-field-picklist')
                .recordTypeId = this.recordTypeId;
        }
    }

    fireLookupRecordSelectEvent() {
        this.dispatchEvent(new CustomEvent(
            'lookuprecordselect',
            {
                detail: {
                    value: this.value,
                    displayValue: this.value,
                    fieldApiName: this.fieldApiName,
                    objectMappingDevName: this.objectMappingDevName
                }
            }
        ));
    }

    /**
     * @description Returns the name of the RecordType that corresponds to a RecordType Id.
     *              This method references this component's objectInfo.recordTypeInfos
     *              property.
     * @param Id The Id of the RecordType.
     * @returns {string|null} The name of the RecordType or null if the RecordType was
     *          not found.
     */
    getRecordTypeNameById(Id) {
        if (this.objectDescribeInfo &&
            this.objectDescribeInfo.recordTypeInfos &&
            this.objectDescribeInfo.recordTypeInfos[Id]) {
            return this.objectDescribeInfo.recordTypeInfos[Id].name;
        } else {
            return null;
        }
    }

    renderedCallback() {
        if (this.value && this.isLookup) {
            // If this field is a Lookup and has a value when connected,
            // fire event so that the form knows to populate related fields
            // and set recordTypeId on sibling fields.
            this.fireLookupRecordSelectEvent();
        }
    }

}<commit_msg>set --None-- displayed value to blank when building the DI row<commit_after>import {LightningElement, api, track, wire} from 'lwc';
import {isNotEmpty, debouncify, isUndefined} from 'c/utilCommon';
import GeFormService from 'c/geFormService';
import GeLabelService from 'c/geLabelService';
import {getObjectInfo} from "lightning/uiObjectInfoApi";
import { fireEvent } from 'c/pubsubNoPageRef';
import DI_DONATION_AMOUNT from '@salesforce/schema/DataImport__c.Donation_Amount__c';
import DONATION_DONOR_FIELD from '@salesforce/schema/DataImport__c.Donation_Donor__c';
import DONATION_RECORD_TYPE_NAME from '@salesforce/schema/DataImport__c.Donation_Record_Type_Name__c';

const LOOKUP_TYPE = 'REFERENCE';
const PICKLIST_TYPE = 'PICKLIST';
const TEXT_AREA_TYPE = 'TEXTAREA';
const BOOLEAN_TYPE = 'BOOLEAN';
const DELAY = 300;
const RICH_TEXT_FORMATS = [
    'font', 'size', 'bold', 'italic', 'underline', 'strike', 'list', 'indent', 'align', 'link', 'clean', 'table', 'header'
];
const CURRENCY = 'currency';
const PERCENT = 'percent';
const DECIMAL = 'decimal';

export default class GeFormField extends LightningElement {
    @track value;
    @track picklistValues = [];
    @track objectDescribeInfo;
    @track richTextValid = true;
    @track _disabled = false;
    @api element;
    @api targetFieldName;
    _defaultValue = null;
    _recordTypeId;

    richTextFormats = RICH_TEXT_FORMATS;
    CUSTOM_LABELS = GeLabelService.CUSTOM_LABELS;

    handleValueChangeSync = (event) => {
        this.value = this.getValueFromChangeEvent(event);
        const detail = {
            element: this.element,
            value: this.value,
            targetFieldName: this.targetFieldName
        };
        const evt = new CustomEvent('valuechange', {detail, bubbles: true});
        this.dispatchEvent(evt);

        if (this.isLookup) {
            const objMappingDevName =
                GeFormService.importedRecordFieldNames.includes(this.fieldApiName) ?
                    GeFormService.getObjectMappingWrapperByImportedFieldName(this.fieldApiName)
                        .DeveloperName :
                    this.objectMappingDevName;

            const detail = {
                ...event.detail,
                objectMappingDevName: objMappingDevName
            }

            const selectRecordEvent = new CustomEvent(
                'lookuprecordselect',
                { detail: detail });
            this.dispatchEvent(selectRecordEvent);
        }

        if (this.isPicklist) {
            this.handlePicklistChange();
        }

        if(this.isRichText) {
            this.checkRichTextValidity();
        }

        if(this.sourceFieldAPIName === DI_DONATION_AMOUNT.fieldApiName) {
            // fire event for reactive widget component containing the Data Import field API name and Value
            // currently only used for the Donation Amount.
            fireEvent(null, 'widgetData', { donationAmount: this.value });
        }
    };

    handleValueChange = debouncify(this.handleValueChangeSync.bind(this), DELAY);

    handlePicklistChange() {
        if (this.fieldApiName === DONATION_DONOR_FIELD.fieldApiName) {
            const changeDonationDonorEvent = new CustomEvent(
                'changedonationdonor',
                {detail: {value: this.value}});
            this.dispatchEvent(changeDonationDonorEvent);
        }
    }

    /**
     * Retrieve object metadata. Used to configure how fields are displayed on the form.
     */
    @wire(getObjectInfo, { objectApiName: '$objectApiName' })
    wiredObjectInfo(response) {
        if(response.data) {
            this.objectDescribeInfo = response.data;
        }
    }

    connectedCallback() {
        const { defaultValue, recordValue } = this.element;

        if(recordValue) {

            // set the record value to the element value
            this.value = recordValue;
        } else if(defaultValue) {

            // Set the default value if there is one
            // and no record value.
            this._defaultValue = defaultValue;
            this.value = defaultValue;
            this.handlePicklistChange();
        }
    }

    getValueFromChangeEvent(event) {
        if(this.fieldType === BOOLEAN_TYPE) {
            return event.detail.checked.toString();
        } else if(this.isRichText) {
            return event.target.value;
        }

        return event.detail.value;
    }

    /**
     * TRUE when a field is required and filled in correctly, or not required at all.
     * @returns {boolean}
     */
    @api
    isValid() {
        // We need to check for invalid values, regardless if the field is required
        let fieldIsValid = this.checkFieldValidity();

        if(this.element !== null && this.element.required) {
            return isNotEmpty(this.value) && fieldIsValid;
        }

        return fieldIsValid;
    }

    /**
     * TRUE when a field is filled in, and is the correct format.
     * @returns {boolean}
     */
    checkFieldValidity() {
        // TODO: Handle other input types, if needed
        const inputField = this.template.querySelector('[data-id="inputComponent"]');
        if(typeof inputField !== 'undefined'
            && inputField !== null
            && typeof inputField.reportValidity === 'function'
            && typeof inputField.checkValidity === 'function') {
                inputField.reportValidity();
                return inputField.checkValidity();
        } else if(this.isRichText) {
            this.checkRichTextValidity();
            if(!this.richTextValid) {
                // workaround, field will not display as invalid if it is untouched
                inputField.focus();
                inputField.blur();
            }
            return this.richTextValid;
        }
        return true;
    }

    checkRichTextValidity() {
        if(this.element.required) {
            const isValid = isNotEmpty(this.value) && this.value.length > 0;
            this.richTextValid = isValid;
            return isValid;
        }
        return true;
    }

    @api
    disable() {
        this._disabled = true;
    }

    @api
    enable() {
        this._disabled = false;
    }

    @api
    get fieldAndValue() {
        let fieldAndValue = {};

        // KIET TBD: This is where we are keeping the field mapping
        // CMT record name at, element.value.
        // However, it may change to the array dataImportFieldMappingDevNames
        // If so, we need to update this to reflect that.
        // In the Execute Anonymous code, both fields are populated.

        if (this.value &&
            this.sourceFieldAPIName === DONATION_RECORD_TYPE_NAME.fieldApiName &&
            Object.keys(this.objectDescribeInfo.recordTypeInfos).includes(this.value)) {
            // value is the RecordType Id, but the DataImport's source field expects
            // the RecordType Name
            fieldAndValue[this.formElementName] =
                this.objectDescribeInfo.recordTypeInfos[this.value].name;
        } else if (this.isPicklist){
            // If the displayed value of the picklist is '--None--' treat the value as blank.
            fieldAndValue[this.formElementName] = (this.value === this.CUSTOM_LABELS.commonLabelNone) ? '' : this.value;
        } else {
            fieldAndValue[this.formElementName] = this.value;
        }

        return fieldAndValue;
    }

    get formElementName() {
        return this.element.componentName ? this.element.componentName : this.element.dataImportFieldMappingDevNames[0];
    }

    get inputType() {
        return GeFormService.getInputTypeFromDataType(this.fieldType);
    }

    get formatter() {
        return GeFormService.getNumberFormatterByDescribeType(this.fieldType);
    }

    get required() {
        return (this.fieldInfo && this.fieldInfo.Is_Required && this.fieldType !== BOOLEAN_TYPE) ||
            (this.element && this.element.required);
    }

    get disabled() {
        return this._disabled || (this.element && this.element.disabled);
    }

    get granularity() {
        if (this.formatter) {
            switch (this.fieldType.toLowerCase()) {
                case CURRENCY: return '0.01';
                case PERCENT: return '0.01';
                case DECIMAL: return '0.001';
                default: return 'any';
            }
        }
        return undefined;
    }

    get fieldInfo() {
        return isNotEmpty(this.targetFieldName) ?
            GeFormService.getFieldMappingWrapperFromTarget(this.targetFieldName) :
            GeFormService.getFieldMappingWrapper(this.formElementName);
    }

    get fieldDescribeInfo() {
        if(this.objectDescribeInfo) {
            return this.objectDescribeInfo.fields[this.fieldApiName];
        }
    }

    get objectInfo() {
        return GeFormService.getObjectMappingWrapper(this.objectMappingDevName);
    }

    get fieldType() {
        return this.fieldInfo.Target_Field_Data_Type;
    }

    get isLightningInput() {
        return typeof GeFormService.getInputTypeFromDataType(this.fieldType) !== 'undefined';
    }

    get isRichText() {
        if(typeof this.fieldDescribeInfo !== 'undefined' && this.fieldType === TEXT_AREA_TYPE) {
            return this.fieldDescribeInfo.htmlFormatted;
        }
    }

    @api
    get isLookup() {
        return this.fieldType === LOOKUP_TYPE;
    }

    @api
    get isPicklist() {
        return this.fieldType === PICKLIST_TYPE;
    }

    get isTextArea() {
        if(typeof this.fieldDescribeInfo !== 'undefined' && this.fieldType === TEXT_AREA_TYPE) {
            return !this.fieldDescribeInfo.htmlFormatted;
        }
    }

    @api
    get objectMappingDevName() {
        return this.fieldInfo.Target_Object_Mapping_Dev_Name;
    }

    get objectApiName() {
        if(typeof this.objectInfo !== 'undefined') {
            return this.objectInfo.Object_API_Name;
        }
    }

    get fieldApiName() {
        return this.fieldInfo.Target_Field_API_Name;
    }

    @api
    get sourceFieldAPIName() {
        return this.fieldInfo.Source_Field_API_Name;
    }

    @api
    get fieldLabel() {
        return this.element.customLabel;
    }

    @api
    get fieldValueAndLabel() {

        let fieldWrapper = { value: this.value, label: this.fieldLabel };
        let returnMap = {};
        returnMap[ this.sourceFieldAPIName ] = fieldWrapper;

        return returnMap;

    }

    @api
    setCustomValidity(errorMessage) {

        let inputField = this.template.querySelector('[data-id="inputComponent"]');
        inputField.setCustomValidity(errorMessage);
        inputField.reportValidity();

    }

    @api
    clearCustomValidity() {

        if (this.isLookup) {
            let inputField = this.template.querySelector('[data-id="inputComponent"]');
            inputField.clearCustomValidity();
        } else {
            this.setCustomValidity('');
        }

    }

    /**
     * Load a value into the form field.
     * @param data  An sObject potentially containing a value to load.
     * */
    @api
    load(data) {
        let value;
        if (data.hasOwnProperty(this.sourceFieldAPIName)) {
            value = data[this.sourceFieldAPIName];
            if (value === null || value.value === null) {
                this.reset();
            } else {
                this.value = value.value || value;

                if (this.isLookup) {
                    if (this.fieldApiName === 'RecordTypeId') {
                        if (value && !value.displayName) {
                            // If the RecordTypeId field for a target record is being
                            // loaded with only the Id (like when a Lookup field is
                            // selected/populated on the form), get the RecordType Name
                            // and pass it with the Id to loadLookup
                            data[this.sourceFieldAPIName] = {
                                value: value,
                                displayValue: this.getRecordTypeNameById(value)
                            };
                        }
                    }
                    this.loadLookUp(data, this.value);
                }
            }

            if (this.sourceFieldAPIName === DI_DONATION_AMOUNT.fieldApiName) {
                // fire event for reactive widget component containing the Data Import field API name and Value
                // currently only used for the Donation Amount.
                fireEvent(null, 'widgetData', {donationAmount: this.value});
            }

        } else if (!isUndefined(data.value)) {
            // When the geFormField cmp is used inside of geFormWidgetAllocation,
            // geFormWidgetAllocation selects the field cmp to load a value into manually,
            // and passes an {value: <value>} object.  To support that case this block
            // loads the value directly even though data does not have a property for
            // this.sourceFieldAPIName
           this.value = data.value;
        } else {
            // Property isn't defined.  Don't do anything.
            return false;
        }
    }

    /**
     * Loads a value into a look-up field
     * @param data An sObject potentially containing a value to load.
     * @param value A form field value
     */
    loadLookUp(data, value) {
        const lookup = this.template.querySelector('c-ge-form-field-lookup');

        let displayValue;
        const relationshipFieldName = this.sourceFieldAPIName.replace('__c', '__r');

        if (data[relationshipFieldName] &&
            data[relationshipFieldName]['Name']) {
            displayValue = data[relationshipFieldName].Name;

        } else if (data[this.sourceFieldAPIName] &&
            data[this.sourceFieldAPIName]['displayValue']) {
            displayValue = data[this.sourceFieldAPIName].displayValue;

        } else if (data.displayValue) {
            displayValue = data.displayValue;

        }

        lookup.setSelected({value, displayValue});
    }

    @api
    reset() {
        this.value = this._defaultValue;

        if (this.isLookup) {
            const lookup = this.template.querySelector('c-ge-form-field-lookup');
            lookup.reset();
            if (this.fieldApiName === 'RecordTypeId') {
                // Using setTimeout here ensures that this recordTypeId
                // will be set on sibling fields after they are reset by queueing the event.
                setTimeout(() => {
                    this.fireLookupRecordSelectEvent();
                }, 0);
            }
        }

        if (this.isPicklist) {
            this.template.querySelector('c-ge-form-field-picklist').reset();
            this.handlePicklistChange();
        }
    }

    @api
    set recordTypeId(id) {
        this._recordTypeId = id;
        this.setRecordTypeIdOnChildComponents();
    }

    get recordTypeId() {
        return this._recordTypeId;
    }

    setRecordTypeIdOnChildComponents() {
        if (this.isPicklist) {
            this.template.querySelector('c-ge-form-field-picklist')
                .recordTypeId = this.recordTypeId;
        }
    }

    fireLookupRecordSelectEvent() {
        this.dispatchEvent(new CustomEvent(
            'lookuprecordselect',
            {
                detail: {
                    value: this.value,
                    displayValue: this.value,
                    fieldApiName: this.fieldApiName,
                    objectMappingDevName: this.objectMappingDevName
                }
            }
        ));
    }

    /**
     * @description Returns the name of the RecordType that corresponds to a RecordType Id.
     *              This method references this component's objectInfo.recordTypeInfos
     *              property.
     * @param Id The Id of the RecordType.
     * @returns {string|null} The name of the RecordType or null if the RecordType was
     *          not found.
     */
    getRecordTypeNameById(Id) {
        if (this.objectDescribeInfo &&
            this.objectDescribeInfo.recordTypeInfos &&
            this.objectDescribeInfo.recordTypeInfos[Id]) {
            return this.objectDescribeInfo.recordTypeInfos[Id].name;
        } else {
            return null;
        }
    }

    renderedCallback() {
        if (this.value && this.isLookup) {
            // If this field is a Lookup and has a value when connected,
            // fire event so that the form knows to populate related fields
            // and set recordTypeId on sibling fields.
            this.fireLookupRecordSelectEvent();
        }
    }

}<|endoftext|>


<commit_before><commit_msg>Zero in on failing test<commit_after><|endoftext|>


<commit_before>// True is for red corner, False is for blue corner
// NOTE this function expects a consistent html structure
// and is based on the existance of a 'class named corner' on
// both fighter corners. updating that html may require an update
// of this function

RED_CORNER = true;
BLUE_CORNER = false;

// clear all dropdown menus in corner
function clear_fighter_selection(corner) {
  // clear gender

  var side = 99;

  if( corner === RED_CORNER ) {
  side = 0;
  } else {
  side = 1;
  }

  var _gender = 0;
  var _promotion = 1;
  var _weight = 2;
  var _fighter = 3;

  // clear fighter info
  var gender_sel = $('.corner')[side].getElementsByTagName('select');
  $( gender_sel[_gender] ).selectpicker('val', 'Gender');
  $( gender_sel[_promotion] ).selectpicker('val', 'Promotion');
  $( gender_sel[_weight] ).selectpicker('val', 'Weight');
  $( gender_sel[_fighter] ).selectpicker('val', 'Fighter');

  // clear the image
  $('.corner')[side].getElementsByTagName('img')[0].src = "../static/images/Body-1.png";

  var _name = 1;
  var _nickname = 3;
  var _weightclass = 5;
  var _record = 7;

  // clear fighter info text
  finfo_txt = $('.corner')[side].getElementsByTagName('td');
  finfo_txt[_name].innerHTML = "";
  finfo_txt[_nickname].innerHTML = "";
  finfo_txt[_weightclass].innerHTML = "";
  finfo_txt[_record].innerHTML = "";
} // end of clear_player_selection

// clear fighter info only
function clear_fighter_info(corner) {

  var side = 99;

  if( corner === RED_CORNER ) {
  side = 0;
  } else {
  side = 1;
  }

  $('.corner')[side].getElementsByTagName('img')[0].src = "../static/images/Body-1.png";

  var _name = 1;
  var _nickname = 3;
  var _weightclass = 5;
  var _record = 7;

  // clear fighter info text
  finfo_txt = $('.corner')[side].getElementsByTagName('td');
  finfo_txt[_name].innerHTML = "";
  finfo_txt[_nickname].innerHTML = "";
  finfo_txt[_weightclass].innerHTML = "";
  finfo_txt[_record].innerHTML = "";
}

// capture menu selection event including which corner is chosen
function which_menu(evt, corner) {

  var corner_name = corner === true ? "red corner" : "blue corner";
  var reverse_side = corner === true ? 1 : 0;

  // array default indexes
  var _gender = 0;
  var _promotion = 1;
  var _weight = 2;
  var _fighter = 3;

  reverse_sel = $('.corner')[reverse_side].getElementsByTagName('select');

  if (evt.target.classList.contains("gender_menu")) {
    console.log(corner_name + ", gender menu selected");
    // use jQuery to extract the data via selectpicker from evt.target
    // which is an object menu
    var gender_val = $(evt.target).selectpicker('val');
    var reverse_val = $(reverse_sel[_gender]).selectpicker('val');

    if (gender_val !== reverse_val && reverse_val != "") {
      // corner is just true and false, so we flip with a negation using '!'
      var ok = confirm(
        "Fighters must be the same gender. Choose 'OK' to erase the " +
        (corner === true ? "blue corner" : "red corner") +
        " selection or choose 'Cancel' to keep the current gender");

      if (true === ok) {
        // apply the filters to the current corner
        clear_fighter_selection(!corner);
        $(reverse_sel[_gender]).selectpicker('val', gender_val);
        ui_apply_gender_filter(!corner, gender_val.toLowerCase());
        ui_set_weight_by_gender(!corner, gender_val.toLowerCase());
      } else {
        clear_fighter_selection(corner);
        return;
      }
    } // end of gender_menu
    ui_apply_gender_filter(corner, gender_val.toLowerCase());
    ui_set_weight_by_gender(corner, gender_val.toLowerCase());
    return;
  }

  if (evt.target.classList.contains("promotion_menu")) {
    console.log(corner_name + ", promotion menu selected");
    return;
  } // end of promotion_menu

  if (evt.target.classList.contains("weight_menu")) {

    var side = 99;

    if( corner === RED_CORNER ) {
    side = 0;
    } else {
    side = 1;
    }

    console.log(corner_name + ", weight menu selected");
    var gender_sel = $('.corner')[side].getElementsByTagName('select');
    var gender_val = $( gender_sel[_gender] ).selectpicker('val').toLowerCase();
    var weight_val = $(evt.target).selectpicker('val');
    ui_apply_weight_filter(corner, weight_val, gender_val);
    return;
  } // end of weight_menu

  if (evt.target.classList.contains("fighter_menu")) {
    console.log(corner_name + ", fighter menu selected");
    var fighter_val = $(evt.target).selectpicker('val');
    ui_load_fighter_info(corner, fighter_val);
    return;
  } // end of fighter_menu

  console.log(corner_name + ", something changes, can't say what");
  return;
}

// determine which corner is being acted on
function corner_event_handler(evtData) {
  var evt = evtData;

  if (evt.currentTarget.classList.contains("red_side")) {
    // check if the target is gender
    which_menu(evt, RED_CORNER);
    return;
  }

  which_menu(evt, BLUE_CORNER);
  return;

}

// trap on change ( menu option, gender, so that it applies to both corners )

// populate fighter dropdown based on gender selection
function ui_apply_gender_filter(corner, gender) {

  var corners = $('.corner');
  // 0 is red, 1 is blue
  var side = corner === true ? 0 : 1;
  var _promotion_menu = 1;
  var _weight_menu = 2;
  var _fighter_menu = 3;
  var fighters = get_fighters_by_gender(gender);

  var promotion_menu_sel = corners[side].getElementsByTagName('select')[_promotion_menu];
  var weight_menu_sel = corners[side].getElementsByTagName('select')[_weight_menu];
  var fighter_menu_sel = corners[side].getElementsByTagName('select')[_fighter_menu];
  // clean previous selections
  $(promotion_menu_sel).selectpicker('val', 'Promotion');
  $(weight_menu_sel).selectpicker('val', 'Weight');
  $(fighter_menu_sel).empty().selectpicker('refresh');

  for (var i=0; i<fighters.length; ++i) {
    full_name = fighters[i].last_name + ", " + fighters[i].first_name;
    // add new filtered data
    $(fighter_menu_sel).append('<option>' + full_name + '</option>').selectpicker('refresh');
  }
}

// set weight class based on gender selected
function ui_set_weight_by_gender(corner, gender) {

  var corners = $('.corner');
  // 0 is red, 1 is blue
  var side = corner === true ? 0 : 1;
  var _weight_menu = 2;
  var weight_menu_sel = corners[side].getElementsByTagName('select')[_weight_menu];
  var weight_menu_opt = $(weight_menu_sel.options);

  if (gender === "female") {
    $(weight_menu_sel).empty().selectpicker('refresh');
    $(weight_menu_sel).append('<option>Strawweight</option>');
    $(weight_menu_sel).append('<option>Bantamweight</option>').selectpicker('refresh');
    return;
  }
  $(weight_menu_sel).empty().selectpicker('refresh');
  $(weight_menu_sel).append('<option>Flyweight</option>');
  $(weight_menu_sel).append('<option>Bantamweight</option>');
  $(weight_menu_sel).append('<option>Featherweight</option>');
  $(weight_menu_sel).append('<option>Lightweight</option>');
  $(weight_menu_sel).append('<option>Welterweight</option>');
  $(weight_menu_sel).append('<option>Middleweight</option>');
  $(weight_menu_sel).append('<option>Light Heavyweight</option>');
  $(weight_menu_sel).append('<option>Heavyweight</option>').selectpicker('refresh');
  return;
}

// populate fighers based on weight class selection
function ui_apply_weight_filter(corner, weight, gender) {

  var corners = $('.corner');
  // 0 is red, 1 is blue
  var side = corner === true ? 0 : 1;
  var _fighter_menu = 3;
  var fighter_menu_sel = corners[side].getElementsByTagName('select')[_fighter_menu];
  $(fighter_menu_sel).empty().selectpicker('refresh');

  var fighters = get_fighters_by_weight(weight);

  for (var i=0; i<fighters.length; ++i) {
    if (fighters[i].gender === gender) {
      full_name = fighters[i].last_name + ", " + fighters[i].first_name;
      // add new filtered data
      $(fighter_menu_sel).append('<option>' + full_name + '</option>').selectpicker('refresh');
    }
  }
}

// load fighter info on selection
function ui_load_fighter_info(corner, name) {

  var side = 99;

  if( corner === RED_CORNER ) {
  side = 0;
  } else {
  side = 1;
  }

  $('.corner')[side].getElementsByTagName('img')[0].src = "../static/images/Body-1.png";

  var _name = 1;
  var _nickname = 3;
  var _weightclass = 5;
  var _record = 7;

  var fighters = get_fighters_by_name(name);
  for (var i=0; i<fighters.length; ++i) {
    full_name = fighters[i].last_name + ", " + fighters[i].first_name;
    if (full_name === name) {
      var fighter = fighters[i];

      $('.corner')[side].getElementsByTagName('img')[0].src = get_img_path(fighter);
      finfo_txt = $('.corner')[side].getElementsByTagName('td');
      finfo_txt[_name].innerHTML = get_fighter_name(fighter);
      finfo_txt[_nickname].innerHTML = get_fighter_nickname(fighter);
      finfo_txt[_weightclass].innerHTML = get_weight_class(fighter);
      finfo_txt[_record].innerHTML = get_fighter_record(fighter);
    }
  }
}

$(document).ready(function() {
  $('.corner').change(corner_event_handler);
});<commit_msg>improved filtering to clear menus and fighter info on gender and weight class change<commit_after>// True is for red corner, False is for blue corner
// NOTE this function expects a consistent html structure
// and is based on the existance of a 'class named corner' on
// both fighter corners. updating that html may require an update
// of this function

RED_CORNER = true;
BLUE_CORNER = false;

// clear all dropdown menus in corner
function clear_fighter_selection(corner) {
  // clear gender

  var side = 99;

  if( corner === RED_CORNER ) {
  side = 0;
  } else {
  side = 1;
  }

  var _gender = 0;
  var _promotion = 1;
  var _weight = 2;
  var _fighter = 3;

  // clear fighter info
  var gender_sel = $('.corner')[side].getElementsByTagName('select');
  $( gender_sel[_gender] ).selectpicker('val', 'Gender');
  $( gender_sel[_promotion] ).selectpicker('val', 'Promotion');
  $( gender_sel[_weight] ).selectpicker('val', 'Weight');
  $( gender_sel[_fighter] ).selectpicker('val', 'Fighter');

  // clear the image
  $('.corner')[side].getElementsByTagName('img')[0].src = "../static/images/Body-1.png";

  var _name = 1;
  var _nickname = 3;
  var _weightclass = 5;
  var _record = 7;

  // clear fighter info text
  finfo_txt = $('.corner')[side].getElementsByTagName('td');
  finfo_txt[_name].innerHTML = "";
  finfo_txt[_nickname].innerHTML = "";
  finfo_txt[_weightclass].innerHTML = "";
  finfo_txt[_record].innerHTML = "";
} // end of clear_player_selection

// clear fighter info only
function clear_fighter_info(corner) {

  var side = 99;

  if( corner === RED_CORNER ) {
  side = 0;
  } else {
  side = 1;
  }

  $('.corner')[side].getElementsByTagName('img')[0].src = "../static/images/Body-1.png";

  var _name = 1;
  var _nickname = 3;
  var _weightclass = 5;
  var _record = 7;

  // clear fighter info text
  finfo_txt = $('.corner')[side].getElementsByTagName('td');
  finfo_txt[_name].innerHTML = "";
  finfo_txt[_nickname].innerHTML = "";
  finfo_txt[_weightclass].innerHTML = "";
  finfo_txt[_record].innerHTML = "";
}

// capture menu selection event including which corner is chosen
function which_menu(evt, corner) {

  var corner_name = corner === true ? "red corner" : "blue corner";
  var reverse_side = corner === true ? 1 : 0;

  // array default indexes
  var _gender = 0;
  var _promotion = 1;
  var _weight = 2;
  var _fighter = 3;

  reverse_sel = $('.corner')[reverse_side].getElementsByTagName('select');

  if (evt.target.classList.contains("gender_menu")) {
    console.log(corner_name + ", gender menu selected");
    clear_fighter_info(corner);
    // use jQuery to extract the data via selectpicker from evt.target
    // which is an object menu
    var gender_val = $(evt.target).selectpicker('val');
    var reverse_val = $(reverse_sel[_gender]).selectpicker('val');

    if (gender_val !== reverse_val && reverse_val != "") {
      // corner is just true and false, so we flip with a negation using '!'
      var ok = confirm(
        "Fighters must be the same gender. Choose 'OK' to erase the " +
        (corner === true ? "blue corner" : "red corner") +
        " selection or choose 'Cancel' to keep the current gender");

      if (true === ok) {
        // apply the filters to the current corner
        clear_fighter_selection(!corner);
        $(reverse_sel[_gender]).selectpicker('val', gender_val);
        ui_apply_gender_filter(!corner, gender_val.toLowerCase());
        ui_set_weight_by_gender(!corner, gender_val.toLowerCase());
      } else {
        clear_fighter_selection(corner);
        return;
      }
    } // end of gender_menu
    ui_apply_gender_filter(corner, gender_val.toLowerCase());
    ui_set_weight_by_gender(corner, gender_val.toLowerCase());
    return;
  }

  if (evt.target.classList.contains("promotion_menu")) {
    console.log(corner_name + ", promotion menu selected");
    return;
  } // end of promotion_menu

  if (evt.target.classList.contains("weight_menu")) {
    clear_fighter_info(corner);

    var side = 99;

    if( corner === RED_CORNER ) {
    side = 0;
    } else {
    side = 1;
    }

    console.log(corner_name + ", weight menu selected");
    var gender_sel = $('.corner')[side].getElementsByTagName('select');
    var gender_val = $( gender_sel[_gender] ).selectpicker('val').toLowerCase();
    var weight_val = $(evt.target).selectpicker('val');
    ui_apply_weight_filter(corner, weight_val, gender_val);
    return;
  } // end of weight_menu

  if (evt.target.classList.contains("fighter_menu")) {
    console.log(corner_name + ", fighter menu selected");
    var fighter_val = $(evt.target).selectpicker('val');
    ui_load_fighter_info(corner, fighter_val);
    return;
  } // end of fighter_menu

  console.log(corner_name + ", something changes, can't say what");
  return;
}

// determine which corner is being acted on
function corner_event_handler(evtData) {
  var evt = evtData;

  if (evt.currentTarget.classList.contains("red_side")) {
    // check if the target is gender
    which_menu(evt, RED_CORNER);
    return;
  }

  which_menu(evt, BLUE_CORNER);
  return;

}

// trap on change ( menu option, gender, so that it applies to both corners )

// populate fighter dropdown based on gender selection
function ui_apply_gender_filter(corner, gender) {

  var corners = $('.corner');
  // 0 is red, 1 is blue
  var side = corner === true ? 0 : 1;
  var _promotion_menu = 1;
  var _weight_menu = 2;
  var _fighter_menu = 3;
  var fighters = get_fighters_by_gender(gender);

  var promotion_menu_sel = corners[side].getElementsByTagName('select')[_promotion_menu];
  var weight_menu_sel = corners[side].getElementsByTagName('select')[_weight_menu];
  var fighter_menu_sel = corners[side].getElementsByTagName('select')[_fighter_menu];
  // clean previous selections
  $(promotion_menu_sel).selectpicker('val', 'Promotion');
  $(weight_menu_sel).selectpicker('val', 'Weight');
  $(fighter_menu_sel).empty().selectpicker('refresh');

  for (var i=0; i<fighters.length; ++i) {
    full_name = fighters[i].last_name + ", " + fighters[i].first_name;
    // add new filtered data
    $(fighter_menu_sel).append('<option>' + full_name + '</option>').selectpicker('refresh');
  }
}

// set weight class based on gender selected
function ui_set_weight_by_gender(corner, gender) {

  var corners = $('.corner');
  // 0 is red, 1 is blue
  var side = corner === true ? 0 : 1;
  var _weight_menu = 2;
  var weight_menu_sel = corners[side].getElementsByTagName('select')[_weight_menu];
  var weight_menu_opt = $(weight_menu_sel.options);

  if (gender === "female") {
    $(weight_menu_sel).empty().selectpicker('refresh');
    $(weight_menu_sel).append('<option>Strawweight</option>');
    $(weight_menu_sel).append('<option>Bantamweight</option>').selectpicker('refresh');
    return;
  }
  $(weight_menu_sel).empty().selectpicker('refresh');
  $(weight_menu_sel).append('<option>Flyweight</option>');
  $(weight_menu_sel).append('<option>Bantamweight</option>');
  $(weight_menu_sel).append('<option>Featherweight</option>');
  $(weight_menu_sel).append('<option>Lightweight</option>');
  $(weight_menu_sel).append('<option>Welterweight</option>');
  $(weight_menu_sel).append('<option>Middleweight</option>');
  $(weight_menu_sel).append('<option>Light Heavyweight</option>');
  $(weight_menu_sel).append('<option>Heavyweight</option>').selectpicker('refresh');
  return;
}

// populate fighers based on weight class selection
function ui_apply_weight_filter(corner, weight, gender) {

  var corners = $('.corner');
  // 0 is red, 1 is blue
  var side = corner === true ? 0 : 1;
  var _fighter_menu = 3;
  var fighter_menu_sel = corners[side].getElementsByTagName('select')[_fighter_menu];
  $(fighter_menu_sel).empty().selectpicker('refresh');

  var fighters = get_fighters_by_weight(weight);

  for (var i=0; i<fighters.length; ++i) {
    if (fighters[i].gender === gender) {
      full_name = fighters[i].last_name + ", " + fighters[i].first_name;
      // add new filtered data
      $(fighter_menu_sel).append('<option>' + full_name + '</option>').selectpicker('refresh');
    }
  }
}

// load fighter info on selection
function ui_load_fighter_info(corner, name) {

  var side = 99;

  if( corner === RED_CORNER ) {
  side = 0;
  } else {
  side = 1;
  }

  $('.corner')[side].getElementsByTagName('img')[0].src = "../static/images/Body-1.png";

  var _name = 1;
  var _nickname = 3;
  var _weightclass = 5;
  var _record = 7;

  var fighters = get_fighters_by_name(name);
  for (var i=0; i<fighters.length; ++i) {
    full_name = fighters[i].last_name + ", " + fighters[i].first_name;
    if (full_name === name) {
      var fighter = fighters[i];

      $('.corner')[side].getElementsByTagName('img')[0].src = get_img_path(fighter);
      finfo_txt = $('.corner')[side].getElementsByTagName('td');
      finfo_txt[_name].innerHTML = get_fighter_name(fighter);
      finfo_txt[_nickname].innerHTML = get_fighter_nickname(fighter);
      finfo_txt[_weightclass].innerHTML = get_weight_class(fighter);
      finfo_txt[_record].innerHTML = get_fighter_record(fighter);
    }
  }
}

$(document).ready(function() {
  $('.corner').change(corner_event_handler);
});<|endoftext|>


<commit_before>/** @jsx React.DOM */

define(
  [
    'react',
    'backbone',
    'context'
  ],
  function (React, Backbone, context) {

    return React.createClass({

      propTypes: {
        isVisible: React.PropTypes.bool.isRequired,
        onMoveSelectedResources: React.PropTypes.func.isRequired,
        onDeleteSelectedResources: React.PropTypes.func.isRequired,
        onReportSelectedResources: React.PropTypes.func.isRequired,
        onRemoveSelectedResources: React.PropTypes.func.isRequired
      },

      render: function () {
        var className = "btn btn-default";
        if(!this.props.isVisible) className += " invisible";

        var removeResourceButton;
        if(context.profile.get('username') === "jchansen"){
          removeResourceButton = (
            <button className={className} style={{"background-color": "bisque"}} onClick={this.props.onRemoveSelectedResources}>

            </button>
          );
        }

        return (

            <button className="btn btn-default" onClick={this.props.onReportSelectedResources}>

            </button>
            <button className={className} onClick={this.props.onMoveSelectedResources}>

            </button>
            <button className={className} onClick={this.props.onDeleteSelectedResources}>

            </button>
            {removeResourceButton}

        );
      }

    });

  });
<commit_msg>make remove resource button visible to all superusers<commit_after>/** @jsx React.DOM */

define(
  [
    'react',
    'backbone',
    'context'
  ],
  function (React, Backbone, context) {

    return React.createClass({

      propTypes: {
        isVisible: React.PropTypes.bool.isRequired,
        onMoveSelectedResources: React.PropTypes.func.isRequired,
        onDeleteSelectedResources: React.PropTypes.func.isRequired,
        onReportSelectedResources: React.PropTypes.func.isRequired,
        onRemoveSelectedResources: React.PropTypes.func.isRequired
      },

      render: function () {
        var className = "btn btn-default";
        if(!this.props.isVisible) className += " invisible";

        var removeResourceButton;
        if(context.profile.get('is_superuser') === true){
          removeResourceButton = (
            <button className={className} style={{"background-color": "bisque"}} onClick={this.props.onRemoveSelectedResources}>

            </button>
          );
        }

        return (

            <button className="btn btn-default" onClick={this.props.onReportSelectedResources}>

            </button>
            <button className={className} onClick={this.props.onMoveSelectedResources}>

            </button>
            <button className={className} onClick={this.props.onDeleteSelectedResources}>

            </button>
            {removeResourceButton}

        );
      }

    });

  });
<|endoftext|>


<commit_before>var Base = require('./base');
var Util = require('../controllers/util');

/**
 * Expose `Post` Model
 */
module.exports = Post;

/**
 * Post model constructor.
 * @param {express.app} app Express App instance.
 * @param {Object=} opt_resource Optional resource.
 * @constructor
 * @extends {app.models.base}
 */
function Post(app, opt_resource) {
  this.app = app;
  this.resource = opt_resource || null;
  this.db = app.db;
  Base.call(this);
}
require('util').inherits(Post, Base);

/**
 * Table name.
 * @const
 * @private {string}
 */
Post.TABLE_ = 'post';

/**
 * User's table name.
 * @const
 * @private {string}
 */
Post.USERS_TABLE_ = 'user';

/**
 * Columns to retrieve in SELECT statements.
 * @const
 * @private {Array.<string>}
 */
Post.SELECT_COLUMNS_ = ['post.id', 'post.title', 'post.description',
  'post.description_md', 'post.body', 'post.body_md', 'post.slug',
  'post.created', 'post.updated', 'user.displayName', 'user.email', 'user.id',
  'user.slug'];

/**
 * MySQL Query Strings.
 *
 * TODO: You might want some MORE specific queries here for articles, etc -
 * you don't need all the fields...
 *
 * @private
 * @enum {string}
 */
Post.QUERIES_ = {
  find: 'SELECT ?? FROM `' + Post.TABLE_ + '` ' +
      'LEFT JOIN `' + Post.USERS_TABLE_ + '` ' +
      'ON `' + Post.TABLE_ + '`.`user_id` = `' + Post.USERS_TABLE_ + '`.`id` ' +
      'WHERE ?',
  findOne: 'SELECT ?? FROM `' + Post.TABLE_ + '` ' +
      'LEFT JOIN `' + Post.USERS_TABLE_ + '` ' +
      'ON `' + Post.TABLE_ + '`.`user_id` = `' + Post.USERS_TABLE_ + '`.`id` ' +
      'WHERE ? ' +
      'LIMIT 1',
  insert: 'INSERT INTO `' + Post.TABLE_ + '` SET ?',
  update: 'UPDATE `' + Post.TABLE_ + '` SET ? WHERE ?',
  remove: 'DELETE FROM `' + Post.TABLE_ + '` WHERE ? LIMIT 1'
};

/**
 * Table strucure. Describes field types and validation properties.
 * Note: Fields that will get generated (i.e. date, markdown formatted content)
 *   should NOT be required - they will always fail validation if they are.
 * @private
 * @enum {string}
 */
Post.STRUCTURE_ = {
  id: {type: 'Number'},
  user_id: {type: 'Number', length: 10, required: true, displayName: 'User'},
  title: {type: 'String', length: 255, required: true, displayName: 'Title'},
  slug: {type: 'String', length: 255},
  description: {type: 'Text'},
  description_md: {type: 'Text', required: true, displayName: 'Description'},
  body: {type: 'Text'},
  body_md: {type: 'Text', required: true, displayName: 'Body'},
  created: {type: 'Number', required: false},
  updated: {type: 'Number', required: false}
};

/**
 * Gets the named query, or returns them all.
 * @param {?string} action Type of query to get/perform.
 * @return {string|Object} query or queries.
 */
Post.prototype.getQuery = function(action) {
  if (action) {
    return Post.QUERIES_[action];
  } else {
    return Post.QUERIES_;
  }
};

/**
 * Gets the columns to be displayed in a result, or returns them all.
 * @param {?string} action Type of query to get/perform.
 * @return {string|Object} query or queries.
 */
Post.prototype.getColumns = function(action) {
  return Post.SELECT_COLUMNS_;
};

/**
 * Gets the current model's structure.
 * @return {Object} structure object.
 */
Post.prototype.getStructure = function() {
  return Post.STRUCTURE_;
};

/**
 * Gets the table name for the current model.
 * @return {string} table name.
 */
Post.prototype.getTable = function() {
  return Post.TABLE_;
};

/**
 * Add / Modify fields that are not populated by the form, and that need to be
 * generated.
 */
Post.prototype.prepare = function() {
  var resource = this.resource;
  var date = Util.getDate();
  resource.created = date; // Um shouldn't update on edit...
  resource.updated = date;
  resource.slug = this.convertToSlug(resource.title);
  resource.body_md = Util.sanitize(resource.body_md);
  resource.body = this.convertMarkdown(resource.body_md);
  resource.description_md = Util.sanitize(resource.description_md);
  resource.description = this.convertMarkdown(resource.description_md);
  return resource;
};

// TODO: Move to Util
Post.prototype.convertMarkdown = function(text) {
  return require('marked')(text || '');
};

/**
 * TODO: Why is this NOT in a common area???
 * Converts a string into a friendly url string.
 * @param {string} text The string to convert.
 * @return {string} The converted string.
 */
Post.prototype.convertToSlug = function(text) {
  return (text || '')
      .toString()
      .toLowerCase()
      .replace(/[^\w ]+/g, '')
      .replace(/ +/g, '-');
};
<commit_msg>Updated slug conversion in Posts model.<commit_after>var Base = require('./base');
var Util = require('../controllers/util');

/**
 * Expose `Post` Model
 */
module.exports = Post;

/**
 * Post model constructor.
 * @param {express.app} app Express App instance.
 * @param {Object=} opt_resource Optional resource.
 * @constructor
 * @extends {app.models.base}
 */
function Post(app, opt_resource) {
  this.app = app;
  this.resource = opt_resource || null;
  this.db = app.db;
  Base.call(this);
}
require('util').inherits(Post, Base);

/**
 * Table name.
 * @const
 * @private {string}
 */
Post.TABLE_ = 'post';

/**
 * User's table name.
 * @const
 * @private {string}
 */
Post.USERS_TABLE_ = 'user';

/**
 * Columns to retrieve in SELECT statements.
 * @const
 * @private {Array.<string>}
 */
Post.SELECT_COLUMNS_ = ['post.id', 'post.title', 'post.description',
  'post.description_md', 'post.body', 'post.body_md', 'post.slug',
  'post.created', 'post.updated', 'user.displayName', 'user.email', 'user.id',
  'user.slug'];

/**
 * MySQL Query Strings.
 *
 * TODO: You might want some MORE specific queries here for articles, etc -
 * you don't need all the fields...
 *
 * @private
 * @enum {string}
 */
Post.QUERIES_ = {
  find: 'SELECT ?? FROM `' + Post.TABLE_ + '` ' +
      'LEFT JOIN `' + Post.USERS_TABLE_ + '` ' +
      'ON `' + Post.TABLE_ + '`.`user_id` = `' + Post.USERS_TABLE_ + '`.`id` ' +
      'WHERE ?',
  findOne: 'SELECT ?? FROM `' + Post.TABLE_ + '` ' +
      'LEFT JOIN `' + Post.USERS_TABLE_ + '` ' +
      'ON `' + Post.TABLE_ + '`.`user_id` = `' + Post.USERS_TABLE_ + '`.`id` ' +
      'WHERE ? ' +
      'LIMIT 1',
  insert: 'INSERT INTO `' + Post.TABLE_ + '` SET ?',
  update: 'UPDATE `' + Post.TABLE_ + '` SET ? WHERE ?',
  remove: 'DELETE FROM `' + Post.TABLE_ + '` WHERE ? LIMIT 1'
};

/**
 * Table strucure. Describes field types and validation properties.
 * Note: Fields that will get generated (i.e. date, markdown formatted content)
 *   should NOT be required - they will always fail validation if they are.
 * @private
 * @enum {string}
 */
Post.STRUCTURE_ = {
  id: {type: 'Number'},
  user_id: {type: 'Number', length: 10, required: true, displayName: 'User'},
  title: {type: 'String', length: 255, required: true, displayName: 'Title'},
  slug: {type: 'String', length: 255},
  description: {type: 'Text'},
  description_md: {type: 'Text', required: true, displayName: 'Description'},
  body: {type: 'Text'},
  body_md: {type: 'Text', required: true, displayName: 'Body'},
  created: {type: 'Number', required: false},
  updated: {type: 'Number', required: false}
};

/**
 * Gets the named query, or returns them all.
 * @param {?string} action Type of query to get/perform.
 * @return {string|Object} query or queries.
 */
Post.prototype.getQuery = function(action) {
  if (action) {
    return Post.QUERIES_[action];
  } else {
    return Post.QUERIES_;
  }
};

/**
 * Gets the columns to be displayed in a result, or returns them all.
 * @param {?string} action Type of query to get/perform.
 * @return {string|Object} query or queries.
 */
Post.prototype.getColumns = function(action) {
  return Post.SELECT_COLUMNS_;
};

/**
 * Gets the current model's structure.
 * @return {Object} structure object.
 */
Post.prototype.getStructure = function() {
  return Post.STRUCTURE_;
};

/**
 * Gets the table name for the current model.
 * @return {string} table name.
 */
Post.prototype.getTable = function() {
  return Post.TABLE_;
};

/**
 * Add / Modify fields that are not populated by the form, and that need to be
 * generated.
 */
Post.prototype.prepare = function() {
  var resource = this.resource;
  var date = Util.getDate();
  // TODO: 'created' shouldn't update on edit, only on insert.
  resource.created = date;
  resource.updated = date;
  resource.slug = Util.convertToSlug(resource.title);
  resource.body_md = Util.sanitize(resource.body_md);
  resource.body = this.convertMarkdown(resource.body_md);
  resource.description_md = Util.sanitize(resource.description_md);
  resource.description = this.convertMarkdown(resource.description_md);
  return resource;
};

// TODO: Move to Util
Post.prototype.convertMarkdown = function(text) {
  return require('marked')(text || '');
};
<|endoftext|>


<commit_before>const Discord = require('discord.js');
module.exports = async function (message, hotline){
    let me = message.embeds.shift();
    if(me && me!=null)
    {
        return message.reply("Embeds not supported yet")
    }
    const embed = new Discord.RichEmbed();
    embed.setAuthor(message.author.username, message.author.avatarURL)
    if (!hotline)
        embed.setTitle((message.guild)?(message.channel.name + " in " + message.guild.name):(" in a DM with " + message.channel.recipient.tag));
    if (!message.content.trim() == "")
        embed.setDescription(message.cleanContent);
    else
        embed.setDescription("**" + (( me.author && me.author!=null)?(me.author.name+ " : "):"")  + ((me.title && me.title!=null)?me.title:"") + "**\n	" + (me.description || "") + ((me.footer) ? ("\n*At " + me.footer.text + "*") : ""));
    if (!hotline)
        embed.setTimestamp(message.createdAt)
    let color = message.member;
    if (color) {
        color = color.roles.filter((r) => {
            if (r.color !== 0)
                return r;
        }).array().sort((r1, r2) => {
            if (r1.position < r2.position)
                return 1;
        }).shift();
        if (color)
            color = color.color;
    }
    else
        color = 0;
    embed.setColor(color);
    //embed.setTitle("Quote");
    return embed;
}
<commit_msg>copy embed<commit_after>const Discord = require('discord.js');
module.exports = async function (message, hotline){
    let me = message.embeds.shift();
    const embed = new Discord.RichEmbed();
    if(me && me!=null)
    {
        if(me.author && me.author.name)
            embed.author = {
                name: me.author.name,
                icon_url: me.author.icon_url
            }
        if(me.description)
            embed.description = me.description
        if(me.fields && me.fields.length >0)
        {
            me.fields.map(function(f)=>{
                embed.fields.push({
                          name: f.name,
                          value: f.value,
                          inline: f.inline
                          });
            });
        }
        if(me.thumbnail)
            embed.thumbnail = me.thumbnail;
        if(me.image)
            embed.thumbnail = me.image;
        if(me.url)
            embed.url = me.url;
        if(me.title)
            embed.title = me.title;
        if(me.color)
            embed.color = me.color;
        if(me.timestamp)
            embed.timestamp = me.timestamp;
        if(me.footer)
            embed.footer = {
                icon_url: me.footer.icon_url,
                text: me.footer.text
              };
        return me;
        //return message.reply("Embeds not supported yet")
    }
    embed.setAuthor(message.author.username, message.author.avatarURL)
    if (!hotline)
        embed.setTitle((message.guild)?(message.channel.name + " in " + message.guild.name):(" in a DM with " + message.channel.recipient.tag));
    if (!message.content.trim() == "")
        embed.setDescription(message.cleanContent);
    else
        embed.setDescription("**" + (( me.author && me.author!=null)?(me.author.name+ " : "):"")  + ((me.title && me.title!=null)?me.title:"") + "**\n	" + (me.description || "") + ((me.footer) ? ("\n*At " + me.footer.text + "*") : ""));
    if (!hotline)
        embed.setTimestamp(message.createdAt)
    let color = message.member;
    if (color) {
        color = color.roles.filter((r) => {
            if (r.color !== 0)
                return r;
        }).array().sort((r1, r2) => {
            if (r1.position < r2.position)
                return 1;
        }).shift();
        if (color)
            color = color.color;
    }
    else
        color = 0;
    embed.setColor(color);
    //embed.setTitle("Quote");
    return embed;
}
<|endoftext|>


<commit_before>import fs from "fs";
import xml2js from "xml2js";
const parser = new xml2js.Parser();
import deepCopy from "deepcopy";

import CameraShot from "../objects/CameraShot";
import CameraTimeline from "../objects/CameraTimeline";
import DirectorTimeline from "../objects/DirectorTimeline.js";
import DirectorShot from "../objects/DirectorShot.js";
import User from "./User";

// Singleton Object
let projectManagerInstance = null;

/*
 * Class for storing a Project
 */
class ProjectManager {

    constructor() {
        if (!projectManagerInstance) {
            projectManagerInstance = this;

            this.initialized = false;
            if (typeof this.data === "undefined") {
                this.parseXML();
            } else {
                this.initialized = true;
            }
        }

        return projectManagerInstance;
    }

    generateXML() {
        const xml = deepCopy(this.data);
        xml.scriptingProject.directorTimeline = this.data.scriptingProject.directorTimeline.toXML();
        xml.scriptingProject.users = this.usersToXML(this.data.scriptingProject.users);
        xml.scriptingProject["camera-centerarea"] = this.cameraTimelinesToXML(this.data.scriptingProject.cameraTimelines);
        delete xml.scriptingProject.cameraTimelines;

        return xml;
    }

    parseXML() {
        fs.readFile(`${__dirname}/../project-scp-files/project.scp`, (err, data) => {
            if (err) {
                // TODO something with the error
                this.data = null;
                this.initialized = true;
            } else {
                parser.parseString(data, (err, result) => {
                    this.data = result;
                    const directorTimelineXML = result.scriptingProject.directorTimeline[0];
                    this.data.scriptingProject.directorTimeline = DirectorTimeline.fromXML(directorTimelineXML);

                    this.data.scriptingProject.users = this.getUsersFromXML(result.scriptingProject.users);

                    // Add timelines to data object
                    this.data.scriptingProject.cameraTimelines = this.getCameraTimelinesFromXML(
                        result.scriptingProject["camera-centerarea"]);
                    delete this.data.scriptingProject["camera-centerarea"];
                    this.initialized = true;
                });
            }
        });
    }

    getCameraTimelinesFromXML(XMLObject) {
        // Read timelines from xml
        const cameraTimelinesXML =  XMLObject[0].cameraTimeline;
        const cameraTimelines = [];

        if (typeof cameraTimelinesXML !== "undefined") {
            // Insert shots in timeline which is pushed to timelinesarray
            cameraTimelinesXML.forEach((timeline) => {
                cameraTimelines.push(CameraTimeline.fromXML(timeline));
            });
        }
        return cameraTimelines;
    }

    cameraTimelinesToXML(cameraTimelines) {
        const XMLObject = [{cameraTimeline: []}];
        cameraTimelines.forEach((timeline) => {
           XMLObject[0].cameraTimeline.push(timeline.toXML());
        });
        return XMLObject;
    }

    getUsersFromXML(XMLObject) {
        if (typeof XMLObject !== "undefined") {
            const usersXML = XMLObject[0].user;
            const users = [];
            if (typeof usersXML !== "undefined") {
                usersXML.forEach((user, index) => {
                    users.push(User.fromXML(user, index));
                });
            }
            return users;
        } else {
            return [];
        }
    }

    usersToXML(users) {
        const usersXML = [];
        users.forEach((user) => {
            usersXML.push(user.toXML());
        });

        return [{user: usersXML}];
    }

    filterTimelines(pickedTimelines, data) {
        const flattenedTimelines = [];
        const resultingData = {};
        resultingData.scriptingProject = {};
        resultingData.scriptingProject.cameraTimelines = [];

        data.scriptingProject.cameraTimelines.forEach((timeline, index) => {
            if (pickedTimelines.indexOf(index) >= 0) {
                flattenedTimelines.concat(timeline.getCameraShots);
                resultingData.scriptingProject.cameraTimelines.push(timeline);
            }
        });
        return resultingData;
    }

    /*
     * Reload Project File After New Upload
     */
    reloadProject(callback) {
        this.initialized = false;
        // Force a call to reload the file, then wait for loaded file
        this.parseXML();
        ProjectManager.waitForXML(callback);
    }

    /*
     * Helper method for ensuring that XML has been parsed before
     * reading ProjectManager data
     */
    static waitForXML(callback) {
        const projectManager = new ProjectManager();
        function xmlWait() {
            if (!projectManager.initialized) {
                setTimeout(xmlWait, 10);
            } else {
                callback(projectManager);
            }
        }
        xmlWait();
    }

    /*
     * Helper method for ensuring that XML has been parsed before
     * reading ProjectManager data
     */
    static waitForGenerateXML(callback) {
        const projectManager = new ProjectManager();
        const xmlJSON = projectManager.generateXML();
        return xmlJSON;
    }
}

export default ProjectManager;
<commit_msg>extraced xml filepath to constant<commit_after>import fs from "fs";
import xml2js from "xml2js";
const parser = new xml2js.Parser();
import deepCopy from "deepcopy";

import CameraShot from "../objects/CameraShot";
import CameraTimeline from "../objects/CameraTimeline";
import DirectorTimeline from "../objects/DirectorTimeline.js";
import DirectorShot from "../objects/DirectorShot.js";
import User from "./User";

// Singleton Object
let projectManagerInstance = null;
const filepath = `${__dirname}/../project-scp-files/project.scp`;

/*
 * Class for storing a Project
 */
class ProjectManager {

    constructor() {
        if (!projectManagerInstance) {
            projectManagerInstance = this;

            this.initialized = false;
            if (typeof this.data === "undefined") {
                this.parseXML();
            } else {
                this.initialized = true;
            }
        }

        return projectManagerInstance;
    }

    generateXML() {
        const xml = deepCopy(this.data);
        xml.scriptingProject.directorTimeline = this.data.scriptingProject.directorTimeline.toXML();
        xml.scriptingProject.users = this.usersToXML(this.data.scriptingProject.users);
        xml.scriptingProject["camera-centerarea"] = this.cameraTimelinesToXML(this.data.scriptingProject.cameraTimelines);
        delete xml.scriptingProject.cameraTimelines;

        return xml;
    }

    parseXML() {
        fs.readFile(filename, (err, data) => {
            if (err) {
                // TODO something with the error
                this.data = null;
                this.initialized = true;
            } else {
                parser.parseString(data, (err, result) => {
                    this.data = result;
                    const directorTimelineXML = result.scriptingProject.directorTimeline[0];
                    this.data.scriptingProject.directorTimeline = DirectorTimeline.fromXML(directorTimelineXML);

                    this.data.scriptingProject.users = this.getUsersFromXML(result.scriptingProject.users);

                    // Add timelines to data object
                    this.data.scriptingProject.cameraTimelines = this.getCameraTimelinesFromXML(
                        result.scriptingProject["camera-centerarea"]);
                    delete this.data.scriptingProject["camera-centerarea"];
                    this.initialized = true;
                });
            }
        });
    }

    getCameraTimelinesFromXML(XMLObject) {
        // Read timelines from xml
        const cameraTimelinesXML =  XMLObject[0].cameraTimeline;
        const cameraTimelines = [];

        if (typeof cameraTimelinesXML !== "undefined") {
            // Insert shots in timeline which is pushed to timelinesarray
            cameraTimelinesXML.forEach((timeline) => {
                cameraTimelines.push(CameraTimeline.fromXML(timeline));
            });
        }
        return cameraTimelines;
    }

    cameraTimelinesToXML(cameraTimelines) {
        const XMLObject = [{cameraTimeline: []}];
        cameraTimelines.forEach((timeline) => {
           XMLObject[0].cameraTimeline.push(timeline.toXML());
        });
        return XMLObject;
    }

    getUsersFromXML(XMLObject) {
        if (typeof XMLObject !== "undefined") {
            const usersXML = XMLObject[0].user;
            const users = [];
            if (typeof usersXML !== "undefined") {
                usersXML.forEach((user, index) => {
                    users.push(User.fromXML(user, index));
                });
            }
            return users;
        } else {
            return [];
        }
    }

    usersToXML(users) {
        const usersXML = [];
        users.forEach((user) => {
            usersXML.push(user.toXML());
        });

        return [{user: usersXML}];
    }

    filterTimelines(pickedTimelines, data) {
        const flattenedTimelines = [];
        const resultingData = {};
        resultingData.scriptingProject = {};
        resultingData.scriptingProject.cameraTimelines = [];

        data.scriptingProject.cameraTimelines.forEach((timeline, index) => {
            if (pickedTimelines.indexOf(index) >= 0) {
                flattenedTimelines.concat(timeline.getCameraShots);
                resultingData.scriptingProject.cameraTimelines.push(timeline);
            }
        });
        return resultingData;
    }

    /*
     * Reload Project File After New Upload
     */
    reloadProject(callback) {
        this.initialized = false;
        // Force a call to reload the file, then wait for loaded file
        this.parseXML();
        ProjectManager.waitForXML(callback);
    }

    /*
     * Helper method for ensuring that XML has been parsed before
     * reading ProjectManager data
     */
    static waitForXML(callback) {
        const projectManager = new ProjectManager();
        function xmlWait() {
            if (!projectManager.initialized) {
                setTimeout(xmlWait, 10);
            } else {
                callback(projectManager);
            }
        }
        xmlWait();
    }

    /*
     * Helper method for ensuring that XML has been parsed before
     * reading ProjectManager data
     */
    static waitForGenerateXML(callback) {
        const projectManager = new ProjectManager();
        const xmlJSON = projectManager.generateXML();
        return xmlJSON;
    }
}

export default ProjectManager;
<|endoftext|>