[Salesforce]拡張機能でレイアウトを変更する


{
	"manifest_version": 3
    , "version": "0.1"
    , "name": "Salesforceケース登録"
    , "description": "Salesforceケースの自動登録を行う"
    , "action": {}
    , "content_scripts":[
        {
            "matches": ["https://testcompany83-dev-ed.develop.lightning.force.com/lightning/o/Case/new?*"]
            , "js": [
                "salesforce/SalesforceItemHidden.js"
                , "salesforce/SalesforceItemWidthExpansion.js"
                , "salesforce/SalesforceLabelDecoration.js"
                , "util/util.js"
                , "contents/createScreen.js"
            ]
            , "run_at":"document_end"
        }
    ]
        , "content_scripts":[
        {
            "matches": ["https://testcompany83-dev-ed.develop.lightning.force.com/lightning/o/Case/new?*"]
            , "js": [
                "salesforce/SalesforceItemHidden.js"
                , "salesforce/SalesforceItemWidthExpansion.js"
                , "salesforce/SalesforceLabelDecoration.js"
                , "util/util.js"
                , "util/DOMCreator.js"
                , "contents/createScreen.js"
            ]
            , "run_at":"document_end"
        }
        , {
            "matches": ["https://testcompany83-dev-ed.develop.lightning.force.com/lightning/r/*/view"]
            , "js": [
                "salesforce/SalesforceItemHidden.js"
                , "salesforce/SalesforceItemWidthExpansion.js"
                , "salesforce/SalesforceLabelDecoration.js"
                , "util/util.js"
                , "contents/viewScreen.js"
            ]
            , "run_at":"document_end"
        }
    ]
}


async function main(){
    
    await wait(5000);
    // 不要要素の非表示
    let target_item_label_names = ['取引先名'];
    SalesforceItemHidden.hideOnCreateView(target_item_label_names);

    // 要素の幅拡張
    target_item_label_names = ['Web 電話', '発生源'];
    SalesforceItemWidthExpansion.expandOnCreateView(target_item_label_names);

    // 上部ラベル装飾
    SalesforceLabelDecoration.decorate();
}


main();



async function main(){
    
    await wait(5000);
    // 不要要素の非表示
    let target_item_label_names = ['取引先名'];
    SalesforceItemHidden.hideOnDetailView(target_item_label_names);

    // 要素の幅拡張
    target_item_label_names = ['Web 電話', '発生源'];
    SalesforceItemWidthExpansion.expandOnDetailView(target_item_label_names);

    // 上部ラベル装飾
    SalesforceLabelDecoration.decorate();
}


main();

/**
 * セールスフォースにおける要素の非表示クラス
 */
class SalesforceItemHidden {

    /**
     * オブジェクト作成画面
     */
    static hideOnCreateView(target_item_label_names) {
        const root = document.querySelectorAll('.actionBody')[0];
        this.#hideOnCommon(root, target_item_label_names);
    }

    /**
     * オブジェクト詳細画面
     */
    static hideOnDetailView(target_item_label_names) {
        const root = document.querySelectorAll('.tabsetBody')[0];
        this.#hideOnCommon(root, target_item_label_names);
    }

    /**
     * 指定したラベル名と一致する要素を非表示にする
     * @param {*} root_element: オブジェクトを包含するルート要素 
     * @param {*} target_item_label_names: 幅拡張の対象とするラベル名の配列
     */
    static #hideOnCommon(root_element, target_item_label_names) {
        const items = root_element.querySelectorAll('records-record-layout-item');
        items.forEach((item) => {
            const text = item.innerText;
            const is_target = target_item_label_names.some((val) => {
                return text.includes(val);
            });
            if (is_target) {
                item.style.display = 'none';
            }
        });
    }
}

/**
 * セールスフォースにおける要素の幅拡張クラス
 */
class SalesforceItemWidthExpansion {

    /**
     * オブジェクト作成画面
     */
    static expandOnCreateView(target_item_label_names) {
        const root = document.querySelectorAll('.actionBody')[0];
        this.#expandCommon(root, target_item_label_names);
    }

    /**
     * オブジェクト詳細画面
     */
    static expandOnDetailView(target_item_label_names) {
        const root = document.querySelectorAll('.tabsetBody')[0];
        this.#expandCommon(root, target_item_label_names);
    }

    /**
     * 指定したラベル名と一致する要素の幅を拡げる
     * @param {*} root_element: オブジェクトを包含するルート要素 
     * @param {*} target_item_label_names: 幅拡張の対象とするラベル名の配列
     */
    static #expandCommon(root_element, target_item_label_names) {

        // css:flexが設定されている要素を列挙
        const items = root_element.querySelectorAll('slot.slds-size_1-of-1');
        
        items.forEach((item) => {
            const text = item.innerText;
            // 指定ラベル名が幅拡張対象のラベル名と一致する場合、flexを無効にする
            //  -> 幅を2列から1列にする
            const is_target = target_item_label_names.some((val) => {
                return text.includes(val);
            });
            if (is_target) {
                item.style.display = 'block';
            }
        });
    }
}

/**
 * セールスフォースにおけるラベル装飾クラス
 */
class SalesforceLabelDecoration {

    /**
     * 上部ラベルをオブジェクトの種別ごとにレイアウトを装飾する
     */
    static decorate() {
        // 上部タブメニュー
        const tab_menu = document.querySelectorAll('.slds-context-bar .tabBarContainer');
        // タブ
        const tabs = tab_menu[0].querySelectorAll('li[role="presentation"]');
        // タブアイコン
        const tab_icons = Array.from(tabs).map((item) => {
            return item.querySelector('.slds-show_inline-block');
        });

        // タブアイコンの背景色を変更する
        tab_icons.forEach((tab_icon) => {
            console.log(tab_icon);
            // ケースならば
            if (tab_icon.title === 'Case') {
                tab_icon.style.backgroundColor = '#00FF00';
            } else {
                tab_icon.style.backgroundColor = '#0000FF';
            }
        });
    }
}

/**
 * スリープメソッド
 */
async function wait(ms) {
    await new Promise(resolve => {
        setTimeout(resolve, ms);
    });
}