Skip to main content

#EspoCRM #Business #Open_Source

Since last few weeks I'm working on EspoCRM - open source business software.

I'll edit the post with explanation. just a quick backup. Ref. here: ORM, How to manage entities and perform queries - EspoCRM Documentation

Here are some steps to get started:

Here's how you can incorporate your custom search.js script for the Lead entity in a "upgrade safe" way while your pull request is approved:

Define your own search.js class in the custom namespace. for example:
client/custom/src/views/record/search.js
Code:
define('custom:views/record/search', 'views/record/search', function (Dep) {

    return Dep.extend({

WRITE HERE ALL YOUR CUSTOM SEARCH CODE

    });
});
Define a custom header list view class that will invoke the custom search instead of the core class, for example:
client/custom/src/views/header/list.js
Code:
define('custom:views/header/list', 'views/list', function (Dep) {

    return Dep.extend({

        searchView: 'custom:views/record/search'

    )};

});
Define a custom clientDefs metadata script to set the custom header list view as the "list view" for your target Entity ("Lead") class:
custom/Espo/Custom/Resources/metadata/clientDefs/Lead.json
Code:
{
    "views": {
        "list": "custom:views/header/list"
    }

}

Clear cache and rebuild.



===:errors:===

VM232:2755 crbug/1173575, non-JS module files deprecated.

Failed to load resource: the server responded with a status of 404 ()

Failed to launch 'chrome-error://chromewebdata/' because the scheme does not have a registered handler.

VirtualProtectEx, ERROR_INVALID_PARAMETER (error 87)

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview This file defines a singleton which provides access to all data
 * that is available as soon as the page's resources are loaded (before DOM
 * content has finished loading). This data includes both localized strings and
 * any data that is important to have ready from a very early stage (e.g. things
 * that must be displayed right away).
 *
 * Note that loadTimeData is not guaranteed to be consistent between page
 * refreshes (https://crbug.com/740629) and should not contain values that might
 * change if the page is re-opened later.
 */

// #import {assert} from './assert.m.js';
// #import {parseHtmlSubset} from './parse_html_subset.m.js';

/**
 * @typedef {{
 *   substitutions: (!Array<string>|undefined),
 *   attrs: (!Array<string>|undefined),
 *   tags: (!Array<string>|undefined),
 * }}
 */
/* #export */ let SanitizeInnerHtmlOpts;

// eslint-disable-next-line no-var
/* #export */ /** @type {!LoadTimeData} */ var loadTimeData;

class LoadTimeData {
  constructor() {
    /** @type {Object} */
    this.data_;
  }

  /**
   * Sets the backing object.
   *
   * Note that there is no getter for |data_| to discourage abuse of the form:
   *
   *     var value = loadTimeData.data()['key'];
   *
   * @param {Object} value The de-serialized page data.
   */
  set data(value) {
    expect(!this.data_, 'Re-setting data.');
    this.data_ = value;
  }

  /**
   * Returns a JsEvalContext for |data_|.
   * @returns {JsEvalContext}
   */
  createJsEvalContext() {
    return new JsEvalContext(this.data_);
  }

  /**
   * @param {string} id An ID of a value that might exist.
   * @return {boolean} True if |id| is a key in the dictionary.
   */
  valueExists(id) {
    return id in this.data_;
  }

  /**
   * Fetches a value, expecting that it exists.
   * @param {string} id The key that identifies the desired value.
   * @return {*} The corresponding value.
   */
  getValue(id) {
    expect(this.data_, 'No data. Did you remember to include strings.js?');
    const value = this.data_[id];
    expect(typeof value !== 'undefined', 'Could not find value for ' + id);
    return value;
  }

  /**
   * As above, but also makes sure that the value is a string.
   * @param {string} id The key that identifies the desired string.
   * @return {string} The corresponding string value.
   */
  getString(id) {
    const value = this.getValue(id);
    expectIsType(id, value, 'string');
    return /** @type {string} */ (value);
  }

  /**
   * Returns a formatted localized string where $1 to $9 are replaced by the
   * second to the tenth argument.
   * @param {string} id The ID of the string we want.
   * @param {...(string|number)} var_args The extra values to include in the
   *     formatted output.
   * @return {string} The formatted string.
   */
  getStringF(id, var_args) {
    const value = this.getString(id);
    if (!value) {
      return '';
    }

    const args = Array.prototype.slice.call(arguments);
    args[0] = value;
    return this.substituteString.apply(this, args);
  }

  /**
   * Make a string safe for use with with Polymer bindings that are
   * inner-h-t-m-l (or other innerHTML use).
   * @param {string} rawString The unsanitized string.
   * @param {SanitizeInnerHtmlOpts=} opts Optional additional allowed tags and
   *     attributes.
   * @return {string}
   */
  sanitizeInnerHtml(rawString, opts) {
    opts = opts || {};
    return parseHtmlSubset('<b>' + rawString + '</b>', opts.tags, opts.attrs)
        .firstChild.innerHTML;
  }

  /**
   * Returns a formatted localized string where $1 to $9 are replaced by the
   * second to the tenth argument. Any standalone $ signs must be escaped as
   * $$.
   * @param {string} label The label to substitute through.
   *     This is not an resource ID.
   * @param {...(string|number)} var_args The extra values to include in the
   *     formatted output.
   * @return {string} The formatted string.
   */
  substituteString(label, var_args) {
    const varArgs = arguments;
    return label.replace(/\$(.|$|\n)/g, function(m) {
      assert(m.match(/\$[$1-9]/), 'Unescaped $ found in localized string.');
      return m === '$$' ? '$' : varArgs[m[1]];
    });
  }

  /**
   * Returns a formatted string where $1 to $9 are replaced by the second to
   * tenth argument, split apart into a list of pieces describing how the
   * substitution was performed. Any standalone $ signs must be escaped as $$.
   * @param {string} label A localized string to substitute through.
   *     This is not an resource ID.
   * @param {...(string|number)} var_args The extra values to include in the
   *     formatted output.
   * @return {!Array<!{value: string, arg: (null|string)}>} The formatted
   *     string pieces.
   */
  getSubstitutedStringPieces(label, var_args) {
    const varArgs = arguments;
    // Split the string by separately matching all occurrences of $1-9 and of
    // non $1-9 pieces.
    const pieces = (label.match(/(\$[1-9])|(([^$]|\$([^1-9]|$))+)/g) ||
                    []).map(function(p) {
      // Pieces that are not $1-9 should be returned after replacing $$
      // with $.
      if (!p.match(/^\$[1-9]$/)) {
        assert(
            (p.match(/\$/g) || []).length % 2 === 0,
            'Unescaped $ found in localized string.');
        return {value: p.replace(/\$\$/g, '$'), arg: null};
      }

      // Otherwise, return the substitution value.
      return {value: varArgs[p[1]], arg: p};
    });

    return pieces;
  }

  /**
   * As above, but also makes sure that the value is a boolean.
   * @param {string} id The key that identifies the desired boolean.
   * @return {boolean} The corresponding boolean value.
   */
  getBoolean(id) {
    const value = this.getValue(id);
    expectIsType(id, value, 'boolean');
    return /** @type {boolean} */ (value);
  }

  /**
   * As above, but also makes sure that the value is an integer.
   * @param {string} id The key that identifies the desired number.
   * @return {number} The corresponding number value.
   */
  getInteger(id) {
    const value = this.getValue(id);
    expectIsType(id, value, 'number');
    expect(value === Math.floor(value), 'Number isn\'t integer: ' + value);
    return /** @type {number} */ (value);
  }

  /**
   * Override values in loadTimeData with the values found in |replacements|.
   * @param {Object} replacements The dictionary object of keys to replace.
   */
  overrideValues(replacements) {
    expect(
        typeof replacements === 'object',
        'Replacements must be a dictionary object.');
    for (const key in replacements) {
      this.data_[key] = replacements[key];
    }
  }
}

  /**
   * Checks condition, displays error message if expectation fails.
   * @param {*} condition The condition to check for truthiness.
   * @param {string} message The message to display if the check fails.
   */
  function expect(condition, message) {
    if (!condition) {
      console.error(
          'Unexpected condition on ' + document.location.href + ': ' + message);
    }
  }

  /**
   * Checks that the given value has the given type.
   * @param {string} id The id of the value (only used for error message).
   * @param {*} value The value to check the type on.
   * @param {string} type The type we expect |value| to be.
   */
  function expectIsType(id, value, type) {
    expect(
        typeof value === type, '[' + value + '] (' + id + ') is not a ' + type);
  }

  expect(!loadTimeData, 'should only include this file once');
  loadTimeData = new LoadTimeData;

  // Expose |loadTimeData| directly on |window|. This is only necessary by the
  // auto-generated load_time_data.m.js, since within a JS module the scope is
  // local.
  window.loadTimeData = loadTimeData;

/* #ignore */ console.warn('crbug/1173575, non-JS module files deprecated.');

Comments

Popular posts from this blog

GraphQL vs REST

  GraphQL   GraphQL is an application layer server-side technology which is developed by Facebook for executing queries with existing data. GraphQL can optimize RESTful API calls. It gives a declarative way of fetching and updating your data. GraphQL helps you to load data from server to client. It enables programmers to choose the types of requests they want to make. REST REST is a software architectural style that defines a set of constraints for creating web services. It is designed specifically for working with media components, files, or hardware device. The full form of REST is Representational State Transfer. ========================================================= Here is the important difference between GraphQL and REST. GraphQL REST GraphQL is an application layer server-side technology which is developed by Facebook for executing queries with existing data. REST is a software architectural style that defines a set of constraints for creating Web services. It follow...

Competitor or Alternative of IDM (Internet Download Manager) 🤔

  Yes you heard right, a perfect competitor and alternative of IDM (Internet Download Manager) that helps you to get links from Torrent download, YouTube videos and many more. I was really fan of IDM (Internet Download Manager). I always use genuine products for my work and productivity but yes free applications as well 😉😄 mostly. But sometimes laziness and saving money a bit helps too. Problem started when I installed the crack version of IDM and it always prompted to buy/register the product. Although it was a valid reason from their side as well. ðŸ˜„😄 I started to search and got a free, powerful, best alternative named   EagleGet for Windows  You can download it from Softinic  or Filehippo   I found it very useful in many ways, some of them are faster downloads it can track links and starts downloading as soon you copy  works like a charm, it doesn't integrate videos after downloading finishes (like you can notice in IDM) I think yo...

DBMS ACID Properties

 1. Atomicity states that database modifications must follow an all or nothing rule 2. Consistency states that only valid data will be written to the database. If, for some reason, a transaction is executed that violates the database's consistency rules, the entire transaction will be rolled back and the database will be restored to a state consistent with those rules.  3. Isolation requires that multiple transactions occurring at the same time not impact each other's execution. For example, if Joe issues a transaction against a database at the same time that Mary issues a different transaction, both transactions should operate on the database in an isolated manner. The database should either perform Joe's entire transaction before executing Mary's or vice-versa. 4.  Durability ensures that any transaction committed to the database will not be lost. Durability is ensured through the use of database backups and transaction logs that facilitate the restoration of committe...