<commit_before>

(function() {

    var TEMPLATE =
        '
' +
        '

' +
		'
<input type="checkbox" name="open_access" id="cbopen_access" />open access
' +
		'
<input type="button" value="publish" id="publish_button"/>

' +
		'
ERROR3
' +
        '
';

        function publishAction(e){
			$(publish_button).prop('disabled', true);
            fileInfo = e.data.param;
            selected_community = $(ddCommunitySelector).val();
			open_access = $('input[name="open_access"]:checked').length > 0;
            $.post(
                OC.generateUrl('/apps/b2sharebridge/publish'),
                {
                    id: fileInfo.id,
                    community: selected_community,
					open_access: open_access
                },
                function (result) {
                    if (result && result.status === 'success') {
                        OC.dialogs.info(
                            t('b2sharebridge', result.message),
                            t('b2sharebridge', 'Info'));
                    }
                });
        }

    /**
     * @class OCA.B2shareBridge.B2shareBridgeTabView
     * @memberof OCA.B2shareBridge
     * @classdesc
     *
     * Shows publication (to b2share) information for file
     *
     */
    var B2shareBridgeTabView = OCA.Files.DetailTabView.extend(
        /** @lends OCA.B2shareBridge.B2shareBridgeTabView.prototype */{
        id: 'b2shareBridgeTabView',
        className: 'b2shareBridgeTabView tab',

        _label: 'b2sharebridge',

        _loading: false,

		_publish_buton_disabled: false,

        initialize: function() {

            OCA.Files.DetailTabView.prototype.initialize.apply(this, arguments);
            this.collection = new OCA.B2shareBridge.B2shareBridgeCollection();
            this.collection.setObjectType('files');
            this.collection.on('request', this._onRequest, this);
            this.collection.on('sync', this._onEndRequest, this);
            this.collection.on('update', this._onChange, this);
            this.collection.on('error', this._onError, this);
			this._error_msg = "initializing";

        },

        events: {
        },

        getLabel: function() {
            return t('b2sharebridge', 'B2SHARE');
        },

        nextPage: function() {
        },

        _onClickShowMoreVersions: function(ev) {
        },

        _onClickRevertVersion: function(ev) {
        },

        _toggleLoading: function(state) {
        },

        _onRequest: function() {
        },

        _onEndRequest: function() {
        },

        _onAddModel: function(model) {
        },

        getCommunitySelectorHTML: function(){
            //TODO implement warning if token not yet set in settings
            var url_path =
                "/apps/b2sharebridge/gettabviewcontent?requesttoken=" +
                encodeURIComponent(oc_requesttoken);
            communities = [];
            result = "";
            $.ajax({
                type: 'GET',
                url: OC.generateUrl(url_path),
                async: false
            }).done(function(data){
                result = "<select id='ddCommunitySelector'>";
                $.each(data, function(key, value){
                    result = result + "<option value=\"" + key + "\">"+ value + "</option>";
                });
                result = result + "</select>"
            }).fail(function(data){
                //TODO: implement unhappy flow

            });

            return result;
        }
        ,

        template: function(data) {

            if (!this._template) {
                this._template = Handlebars.compile(TEMPLATE);
            }
            return this._template(data);
        },

        itemTemplate: function(data) {
        },

        setFileInfo: function(fileInfo) {
            if (fileInfo){
                this.fileInfo = fileInfo;
            }
			this.initializeB2ShareUI(fileInfo);
            this.render();
        },

        _formatItem: function(version) {
        },

        /**
         * Renders this details view
         */
        render: function() {
            this.$el.html(this.template());
            $(communitySelector).html(this.getCommunitySelectorHTML());
            $(publish_button).bind('click',{param: this.fileInfo}, publishAction);
			$(publish_button).prop('disabled', this._publish_button_disabled);
            this.delegateEvents();
			$(b2sharebridge_errormsg).html(this._error_msg);
			if (this._error_msg!=""){
				$(b2sharebridge_errormsg).show();
			}
        },

        /**
         * Returns true for files, false for folders.
         *
         * @return {bool} true for files, false for folders
         */
        canDisplay: function(fileInfo) {
            if (!fileInfo) {
                return false;
            }
            return !fileInfo.isDirectory();
        },

		processData: function(data){
			this._publish_button_disabled = data['error'];
			this._error_msg = data['error_msg'];
		},

		initializeB2ShareUI: function(fileInfo){
        var url_path =
            "/apps/b2sharebridge/initializeb2shareui?requesttoken=" +
            encodeURIComponent(oc_requesttoken) + "&file_id=" +
			encodeURIComponent(fileInfo.id);
        communities = [];
        result = "";
		that = this;
        $.ajax({
            type: 'GET',
            url: OC.generateUrl(url_path),
            async: false
        }).done(function(data){
        	that.processData(data);
        }).fail(function(data){
            //if PHP not reachable, disable publish button
			that._publish_button_disabled = true;
			that._error_msg = "ERROR - Owncloud server cannot be reached."

        });
		}
    });

    OCA.B2shareBridge = OCA.B2shareBridge || {};

    OCA.B2shareBridge.B2shareBridgeTabView = B2shareBridgeTabView;
})();

<commit_msg>do not initialize the b2share fileinfo/tabview stuff when no fileinfo object is given. Addresses #37<commit_after>

(function() {

    var TEMPLATE =
        '
' +
        '

' +
		'
<input type="checkbox" name="open_access" id="cbopen_access" />open access
' +
		'
<input type="button" value="publish" id="publish_button"/>

' +
		'
ERROR3
' +
        '
';

        function publishAction(e){
			$(publish_button).prop('disabled', true);
            fileInfo = e.data.param;
            selected_community = $(ddCommunitySelector).val();
			open_access = $('input[name="open_access"]:checked').length > 0;
            $.post(
                OC.generateUrl('/apps/b2sharebridge/publish'),
                {
                    id: fileInfo.id,
                    community: selected_community,
					open_access: open_access
                },
                function (result) {
                    if (result && result.status === 'success') {
                        OC.dialogs.info(
                            t('b2sharebridge', result.message),
                            t('b2sharebridge', 'Info'));
                    }
                });
        }

    /**
     * @class OCA.B2shareBridge.B2shareBridgeTabView
     * @memberof OCA.B2shareBridge
     * @classdesc
     *
     * Shows publication (to b2share) information for file
     *
     */
    var B2shareBridgeTabView = OCA.Files.DetailTabView.extend(
        /** @lends OCA.B2shareBridge.B2shareBridgeTabView.prototype */{
        id: 'b2shareBridgeTabView',
        className: 'b2shareBridgeTabView tab',

        _label: 'b2sharebridge',

        _loading: false,

		_publish_buton_disabled: false,

        initialize: function() {

            OCA.Files.DetailTabView.prototype.initialize.apply(this, arguments);
            this.collection = new OCA.B2shareBridge.B2shareBridgeCollection();
            this.collection.setObjectType('files');
            this.collection.on('request', this._onRequest, this);
            this.collection.on('sync', this._onEndRequest, this);
            this.collection.on('update', this._onChange, this);
            this.collection.on('error', this._onError, this);
			this._error_msg = "initializing";

        },

        events: {
        },

        getLabel: function() {
            return t('b2sharebridge', 'B2SHARE');
        },

        nextPage: function() {
        },

        _onClickShowMoreVersions: function(ev) {
        },

        _onClickRevertVersion: function(ev) {
        },

        _toggleLoading: function(state) {
        },

        _onRequest: function() {
        },

        _onEndRequest: function() {
        },

        _onAddModel: function(model) {
        },

        getCommunitySelectorHTML: function(){
            //TODO implement warning if token not yet set in settings
            var url_path =
                "/apps/b2sharebridge/gettabviewcontent?requesttoken=" +
                encodeURIComponent(oc_requesttoken);
            communities = [];
            result = "";
            $.ajax({
                type: 'GET',
                url: OC.generateUrl(url_path),
                async: false
            }).done(function(data){
                result = "<select id='ddCommunitySelector'>";
                $.each(data, function(key, value){
                    result = result + "<option value=\"" + key + "\">"+ value + "</option>";
                });
                result = result + "</select>"
            }).fail(function(data){
                //TODO: implement unhappy flow

            });

            return result;
        }
        ,

        template: function(data) {

            if (!this._template) {
                this._template = Handlebars.compile(TEMPLATE);
            }
            return this._template(data);
        },

        itemTemplate: function(data) {
        },

        setFileInfo: function(fileInfo) {
            if (fileInfo){
                this.fileInfo = fileInfo;
                this.initializeB2ShareUI(fileInfo);
                this.render();
            }
        },

        _formatItem: function(version) {
        },

        /**
         * Renders this details view
         */
        render: function() {
            this.$el.html(this.template());
            $(communitySelector).html(this.getCommunitySelectorHTML());
            $(publish_button).bind('click',{param: this.fileInfo}, publishAction);
			$(publish_button).prop('disabled', this._publish_button_disabled);
            this.delegateEvents();
			$(b2sharebridge_errormsg).html(this._error_msg);
			if (this._error_msg!=""){
				$(b2sharebridge_errormsg).show();
			}
        },

        /**
         * Returns true for files, false for folders.
         *
         * @return {bool} true for files, false for folders
         */
        canDisplay: function(fileInfo) {
            if (!fileInfo) {
                return false;
            }
            return !fileInfo.isDirectory();
        },

		processData: function(data){
			this._publish_button_disabled = data['error'];
			this._error_msg = data['error_msg'];
		},

		initializeB2ShareUI: function(fileInfo){
        var url_path =
            "/apps/b2sharebridge/initializeb2shareui?requesttoken=" +
            encodeURIComponent(oc_requesttoken) + "&file_id=" +
			encodeURIComponent(fileInfo.id);
        communities = [];
        result = "";
		that = this;
        $.ajax({
            type: 'GET',
            url: OC.generateUrl(url_path),
            async: false
        }).done(function(data){
        	that.processData(data);
        }).fail(function(data){
            //if PHP not reachable, disable publish button
			that._publish_button_disabled = true;
			that._error_msg = "ERROR - Owncloud server cannot be reached."

        });
		}
    });

    OCA.B2shareBridge = OCA.B2shareBridge || {};

    OCA.B2shareBridge.B2shareBridgeTabView = B2shareBridgeTabView;
})();

<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2.view',
  name: 'FObjectView',
  extends: 'foam.u2.Controller',

  documentation: 'View for editing FObjects.',

  imports: [
    'setTimeout',
    'strategizer?'
  ],

  requires: [
    'foam.core.Latch'
  ],

  properties: [
    {
      class: 'foam.core.FObjectProperty',
      of: 'foam.core.Latch',
      name: 'choicesLoaded',
      documentation: 'A latch used to wait on choices loaded.',
      factory: function() {
        return this.Latch.create();
      }
    },
    {
      class: 'String',
      name: 'objectClass',
      label: '',
      visibility: function(allowCustom, choices) {
        return allowCustom || choices.length > 1 ?
          foam.u2.DisplayMode.RW :
          foam.u2.DisplayMode.HIDDEN;
      },
      view: function(args, X) {
        return {
          class: X.data.allowCustom ? 'foam.u2.TextField' : 'foam.u2.view.ChoiceView',
          choices$: X.data.choices$
        };
      }
    },
    {
      class: 'FObjectProperty',
      name: 'data',
      label: '',
      // We need to override the default view, otherwise we end up with a
      // circular definition where FObjectView has an FObjectProperty which gets
      // rendered as an FObjectView, which leads to infinite recursion.
      preSet: function(o, n) {
        return n || o;
      },
      view: 'foam.u2.detail.SectionedDetailView'
    },
    {
      class: 'foam.u2.ViewSpec',
      name: 'dataView',
      documentation: 'Set this to change the view of the FObject being created.'
    },
    {
      class: 'Class',
      name: 'of'
    },
    {
      class: 'Boolean',
      name: 'allowCustom',
      expression: function(choices) {
        return choices.length == 0;
      }
    },
    {
      class: 'Array',
      name: 'choices',
      documentation: `
        A list of choices for a ChoiceView containing models related to the
        model in the 'of' property. The user can choose to create an instance
        of one of the models in this list.
      `
    },
    {
      name: 'predicate',
      documentation: `
        Predicate to pass into strategizer query request. Used to define results from strategizer query.
        Example use of strategizer predicate on FObjectView from property view:

        name: 'exampleProp',
        view: function(_, X) {
          let predicate = expr.AND(
              expr.EQ(foam.strategy.StrategyReference.DESIRED_MODEL_ID, 'foam.nanos.auth.User'),
              expr.IN(
                foam.strategy.StrategyReference.STRATEGY,
                [foam.lookup('foam.nanos.auth.SomeUserClass'), foam.lookup('foam.nanos.auth.AnotherUserClass') ]
              )
          );
          return foam.u2.view.FObjectView.create({
            data: X.data.exampleProp,
            of: foam.nanos.auth.User,
            predicate: predicate
          }, X);
        }
      `
    }
  ],

  methods: [
    function updateChoices() {
      if ( this.of == null ) {
        this.choices = [];
        return;
      }

      // If this view is being used in a nanos application, then use the
      // strategizer service to populate the list of choices. Otherwise
      // populate the list of choices using models related to 'of' via the
      // implements and extends relations.
      if ( this.strategizer != null ) {
        this.strategizer.query(null, this.of.id, null, this.predicate).then((strategyReferences) => {
          if ( ! Array.isArray(strategyReferences) || strategyReferences.length === 0 ) {
            this.choices = [[this.of.id, this.of.model_.label]];
            this.choicesLoaded.resolve();
            return;
          }

          var choices = strategyReferences
            .reduce((arr, sr) => {
              if ( ! sr.strategy ) {
                console.warn('Invalid strategy reference: ' + sr.id);
                return arr;
              }

              return arr.concat([[sr.strategy.id, sr.strategy.model_.label]]);
            }, [])
            .filter(x => x);

          // Sort choices alphabetically by label.
          choices.sort((a, b) => a[1] > b[1] ? 1 : -1);

          this.choices = choices;
          this.choicesLoaded.resolve();
        }).catch(err => console.warn(err));
      } else {
        this.choices = this.choicesFallback(this.of);
      }
    },

    async function initE() {
      this.SUPER();

      if ( ! this.choices.length ) {
        this.onDetach(this.of$.sub(this.updateChoices));
        this.updateChoices();
        await this.choicesLoaded;
      }

      function dataToClass(d) {
        return d ? d.cls_.id : '';
      }

      var classToData = function(c) {
        var m = c && this.__context__.lookup(c, true);
        return m ? m.create(null, this) : null;
      }.bind(this);

      this.data$.relateTo(
        this.objectClass$,
        dataToClass,
        classToData
      );
      if ( this.data ) { this.objectClass = dataToClass(this.data); }
      if ( ! this.data && ! this.objectClass && this.choices.length ) this.objectClass = this.choices[0][0];

      this.
        tag(this.OBJECT_CLASS).
        tag(foam.u2.detail.VerticalDetailView, {
          data$: this.data$
        });

    },

    function choicesFallback(of) {
      /**
       * Return a list of choices for a ChoiceView containing models related to
       * 'of' via the implements and extends relations. Does not include
       * interfaces or abstract models in the list of choices.
       */
      if ( ! of ) return [];

      var modelIdToDeps = Object.values(foam.USED)
        .concat(Object.values(foam.UNUSED))
        .reduce((map, m) => {
          // QUESTION: If we're filtering out instances of InterfaceModel
          // below, why do we care about getting the list of things the model
          // implements? Won't they all be interfaces? Or are some of them
          // mixins?
          var deps = m.implements
            ? m.implements.map((imp) => {
              return foam.String.isInstance(imp) ? imp : imp.path;
            })
            : [];
          if ( m.extends ) deps.push(m.extends);
          var id = m.id || m.package + '.' + m.name;
          map[id] = deps;
          return map;
        }, {});

      var choices = {};
      choices[of.id] = true;

      while ( true ) {
        var prev = Object.keys(choices).length;
        for ( var [id, deps] of Object.entries(modelIdToDeps) ) {
          if ( deps.filter((d) => choices[d]).length ) choices[id] = true;
        }
        if ( prev == Object.keys(choices).length ) break;
      }

      return Object.keys(choices)
        .map((id) => foam.lookup(id).model_)
        .filter((m) => ! foam.core.InterfaceModel.isInstance(m))
        .filter((m) => ! m.abstract )
        .map((m) => [m.id, m.label]);
    }
  ]
});
<commit_msg>fix appConfig UI broken<commit_after>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2.view',
  name: 'FObjectView',
  extends: 'foam.u2.Controller',

  documentation: 'View for editing FObjects.',

  imports: [
    'setTimeout',
    'strategizer?'
  ],

  requires: [
    'foam.core.Latch'
  ],

  properties: [
    {
      class: 'foam.core.FObjectProperty',
      of: 'foam.core.Latch',
      name: 'choicesLoaded',
      documentation: 'A latch used to wait on choices loaded.',
      factory: function() {
        return this.Latch.create();
      }
    },
    {
      class: 'String',
      name: 'objectClass',
      label: '',
      visibility: function(allowCustom, choices) {
        return allowCustom || choices.length > 1 ?
          foam.u2.DisplayMode.RW :
          foam.u2.DisplayMode.HIDDEN;
      },
      view: function(args, X) {
        return {
          class: X.data.allowCustom ? 'foam.u2.TextField' : 'foam.u2.view.ChoiceView',
          choices$: X.data.choices$
        };
      }
    },
    {
      class: 'FObjectProperty',
      name: 'data',
      label: '',
      // We need to override the default view, otherwise we end up with a
      // circular definition where FObjectView has an FObjectProperty which gets
      // rendered as an FObjectView, which leads to infinite recursion.
      preSet: function(o, n) {
        return n || o;
      },
      view: 'foam.u2.detail.SectionedDetailView'
    },
    {
      class: 'foam.u2.ViewSpec',
      name: 'dataView',
      documentation: 'Set this to change the view of the FObject being created.'
    },
    {
      class: 'Class',
      name: 'of'
    },
    {
      class: 'Boolean',
      name: 'allowCustom',
      expression: function(choices) {
        return choices.length == 0;
      }
    },
    {
      class: 'Array',
      name: 'choices',
      documentation: `
        A list of choices for a ChoiceView containing models related to the
        model in the 'of' property. The user can choose to create an instance
        of one of the models in this list.
      `
    },
    {
      name: 'predicate',
      documentation: `
        Predicate to pass into strategizer query request. Used to define results from strategizer query.
        Example use of strategizer predicate on FObjectView from property view:

        name: 'exampleProp',
        view: function(_, X) {
          let predicate = expr.AND(
              expr.EQ(foam.strategy.StrategyReference.DESIRED_MODEL_ID, 'foam.nanos.auth.User'),
              expr.IN(
                foam.strategy.StrategyReference.STRATEGY,
                [foam.lookup('foam.nanos.auth.SomeUserClass'), foam.lookup('foam.nanos.auth.AnotherUserClass') ]
              )
          );
          return foam.u2.view.FObjectView.create({
            data: X.data.exampleProp,
            of: foam.nanos.auth.User,
            predicate: predicate
          }, X);
        }
      `
    }
  ],

  methods: [
    function updateChoices() {
      if ( this.of == null ) {
        this.choices = [];
        return;
      }

      // If this view is being used in a nanos application, then use the
      // strategizer service to populate the list of choices. Otherwise
      // populate the list of choices using models related to 'of' via the
      // implements and extends relations.
      if ( this.strategizer != null ) {
        this.strategizer.query(null, this.of.id, null, this.predicate).then((strategyReferences) => {
          if ( ! Array.isArray(strategyReferences) || strategyReferences.length === 0 ) {
            this.choices = [[this.of.id, this.of.model_.label]];
            this.choicesLoaded.resolve();
            return;
          }

          var choices = strategyReferences
            .reduce((arr, sr) => {
              if ( ! sr.strategy ) {
                console.warn('Invalid strategy reference: ' + sr.id);
                return arr;
              }

              return arr.concat([[sr.strategy.id, sr.strategy.model_.label]]);
            }, [])
            .filter(x => x);

          // Sort choices alphabetically by label.
          choices.sort((a, b) => a[1] > b[1] ? 1 : -1);

          this.choices = choices;
          this.choicesLoaded.resolve();
        }).catch(err => console.warn(err));
      } else {
        this.choices = this.choicesFallback(this.of);
      }
    },

    async function initE() {
      this.SUPER();

      if ( ! this.choices.length ) {
        this.onDetach(this.of$.sub(this.updateChoices));
        this.updateChoices();
        this.choicesLoaded;
      }

      function dataToClass(d) {
        return d ? d.cls_.id : '';
      }

      var classToData = function(c) {
        var m = c && this.__context__.lookup(c, true);
        return m ? m.create(null, this) : null;
      }.bind(this);

      this.data$.relateTo(
        this.objectClass$,
        dataToClass,
        classToData
      );
      if ( this.data ) { this.objectClass = dataToClass(this.data); }
      if ( ! this.data && ! this.objectClass && this.choices.length ) this.objectClass = this.choices[0][0];

      this.
        tag(this.OBJECT_CLASS).
        tag(foam.u2.detail.VerticalDetailView, {
          data$: this.data$
        });

    },

    function choicesFallback(of) {
      /**
       * Return a list of choices for a ChoiceView containing models related to
       * 'of' via the implements and extends relations. Does not include
       * interfaces or abstract models in the list of choices.
       */
      if ( ! of ) return [];

      var modelIdToDeps = Object.values(foam.USED)
        .concat(Object.values(foam.UNUSED))
        .reduce((map, m) => {
          // QUESTION: If we're filtering out instances of InterfaceModel
          // below, why do we care about getting the list of things the model
          // implements? Won't they all be interfaces? Or are some of them
          // mixins?
          var deps = m.implements
            ? m.implements.map((imp) => {
              return foam.String.isInstance(imp) ? imp : imp.path;
            })
            : [];
          if ( m.extends ) deps.push(m.extends);
          var id = m.id || m.package + '.' + m.name;
          map[id] = deps;
          return map;
        }, {});

      var choices = {};
      choices[of.id] = true;

      while ( true ) {
        var prev = Object.keys(choices).length;
        for ( var [id, deps] of Object.entries(modelIdToDeps) ) {
          if ( deps.filter((d) => choices[d]).length ) choices[id] = true;
        }
        if ( prev == Object.keys(choices).length ) break;
      }

      return Object.keys(choices)
        .map((id) => foam.lookup(id).model_)
        .filter((m) => ! foam.core.InterfaceModel.isInstance(m))
        .filter((m) => ! m.abstract )
        .map((m) => [m.id, m.label]);
    }
  ]
});
<|endoftext|>


<commit_before>function date (format, timestamp) {
    // http://kevin.vanzonneveld.net
    // +   original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
    // +      parts by: Peter-Paul Koch (http://www.quirksmode.org/js/beat.html)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: MeEtc (http://yass.meetcweb.com)
    // +   improved by: Brad Touesnard
    // +   improved by: Tim Wiel
    // +   improved by: Bryan Elliott
    //
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: David Randall
    // +      input by: Brett Zamir (http://brett-zamir.me)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Theriault
    // +  derived from: gettimeofday
    // +      input by: majak
    // +   bugfixed by: majak
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: Alex
    // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Theriault
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Theriault
    // +   improved by: Thomas Beaucourt (http://www.webapp.fr)
    // +   improved by: JT
    // +   improved by: Theriault
    // +   improved by: Rafał Kukawski (http://blog.kukawski.pl)
    // +   bugfixed by: omid (http://phpjs.org/functions/380:380#comment_137122)
    // +      input by: Martin
    // +      input by: Alex Wilson
    // %        note 1: Uses global: php_js to store the default timezone
    // %        note 2: Although the function potentially allows timezone info (see notes), it currently does not set
    // %        note 2: per a timezone specified by date_default_timezone_set(). Implementers might use
    // %        note 2: this.php_js.currentTimezoneOffset and this.php_js.currentTimezoneDST set by that function
    // %        note 2: in order to adjust the dates in this function (or our other date functions!) accordingly
    // *     example 1: date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400);
    // *     returns 1: '09:09:40 m is month'
    // *     example 2: date('F j, Y, g:i a', 1062462400);
    // *     returns 2: 'September 2, 2003, 2:26 am'
    // *     example 3: date('Y W o', 1062462400);
    // *     returns 3: '2003 36 2003'
    // *     example 4: x = date('Y m d', (new Date()).getTime()/1000);
    // *     example 4: (x+'').length == 10 // 2009 01 09
    // *     returns 4: true
    // *     example 5: date('W', 1104534000);
    // *     returns 5: '53'
    // *     example 6: date('B t', 1104534000);
    // *     returns 6: '999 31'
    // *     example 7: date('W U', 1293750000.82); // 2010-12-31
    // *     returns 7: '52 1293750000'
    // *     example 8: date('W', 1293836400); // 2011-01-01
    // *     returns 8: '52'
    // *     example 9: date('W Y-m-d', 1293974054); // 2011-01-02
    // *     returns 9: '52 2011-01-02'
    var that = this,
        jsdate, f, formatChr = /\\?([a-z])/gi,
        formatChrCb,
        // Keep this here (works, but for code commented-out
        // below for file size reasons)
        //, tal= [],
        _pad = function (n, c) {
            if ((n = n + '').length < c) {
                return new Array((++c) - n.length).join('0') + n;
            }
            return n;
        },
        txt_words = ["Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
    formatChrCb = function (t, s) {
        return f[t] ? f[t]() : s;
    };
    f = {
        // Day
        d: function () { // Day of month w/leading 0; 01..31
            return _pad(f.j(), 2);
        },
        D: function () { // Shorthand day name; Mon...Sun
            return f.l().slice(0, 3);
        },
        j: function () { // Day of month; 1..31
            return jsdate.getDate();
        },
        l: function () { // Full day name; Monday...Sunday
            return txt_words[f.w()] + 'day';
        },
        N: function () { // ISO-8601 day of week; 1[Mon]..7[Sun]
            return f.w() || 7;
        },
        S: function () { // Ordinal suffix for day of month; st, nd, rd, th
            var j = f.j();
            return j < 4 | j > 20 && ['st', 'nd', 'rd'][j%10 - 1] || 'th';
        },
        w: function () { // Day of week; 0[Sun]..6[Sat]
            return jsdate.getDay();
        },
        z: function () { // Day of year; 0..365
            var a = new Date(f.Y(), f.n() - 1, f.j()),
                b = new Date(f.Y(), 0, 1);
            return Math.round((a - b) / 864e5) + 1;
        },

        // Week
        W: function () { // ISO-8601 week number
            var a = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3),
                b = new Date(a.getFullYear(), 0, 4);
            return _pad(1 + Math.round((a - b) / 864e5 / 7), 2);
        },

        // Month
        F: function () { // Full month name; January...December
            return txt_words[6 + f.n()];
        },
        m: function () { // Month w/leading 0; 01...12
            return _pad(f.n(), 2);
        },
        M: function () { // Shorthand month name; Jan...Dec
            return f.F().slice(0, 3);
        },
        n: function () { // Month; 1...12
            return jsdate.getMonth() + 1;
        },
        t: function () { // Days in month; 28...31
            return (new Date(f.Y(), f.n(), 0)).getDate();
        },

        // Year
        L: function () { // Is leap year?; 0 or 1
            var j = f.Y();
            return j%4==0 & j%100!=0 | j%400==0;
        },
        o: function () { // ISO-8601 year
            var n = f.n(),
                W = f.W(),
                Y = f.Y();
            return Y + (n === 12 && W < 9 ? -1 : n === 1 && W > 9);
        },
        Y: function () { // Full year; e.g. 1980...2010
            return jsdate.getFullYear();
        },
        y: function () { // Last two digits of year; 00...99
            return (f.Y() + "").slice(-2);
        },

        // Time
        a: function () { // am or pm
            return jsdate.getHours() > 11 ? "pm" : "am";
        },
        A: function () { // AM or PM
            return f.a().toUpperCase();
        },
        B: function () { // Swatch Internet time; 000..999
            var H = jsdate.getUTCHours() * 36e2,
                // Hours
                i = jsdate.getUTCMinutes() * 60,
                // Minutes
                s = jsdate.getUTCSeconds(); // Seconds
            return _pad(Math.floor((H + i + s + 36e2) / 86.4) % 1e3, 3);
        },
        g: function () { // 12-Hours; 1..12
            return f.G() % 12 || 12;
        },
        G: function () { // 24-Hours; 0..23
            return jsdate.getHours();
        },
        h: function () { // 12-Hours w/leading 0; 01..12
            return _pad(f.g(), 2);
        },
        H: function () { // 24-Hours w/leading 0; 00..23
            return _pad(f.G(), 2);
        },
        i: function () { // Minutes w/leading 0; 00..59
            return _pad(jsdate.getMinutes(), 2);
        },
        s: function () { // Seconds w/leading 0; 00..59
            return _pad(jsdate.getSeconds(), 2);
        },
        u: function () { // Microseconds; 000000-999000
            return _pad(jsdate.getMilliseconds() * 1000, 6);
        },

        // Timezone
        e: function () { // Timezone identifier; e.g. Atlantic/Azores, ...
            // The following works, but requires inclusion of the very large
            // timezone_abbreviations_list() function.
/*              return this.date_default_timezone_get();
*/
            throw 'Not supported (see source code of date() for timezone on how to add support)';
        },
        I: function () { // DST observed?; 0 or 1
            // Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC.
            // If they are not equal, then DST is observed.
            var a = new Date(f.Y(), 0),
                // Jan 1
                c = Date.UTC(f.Y(), 0),
                // Jan 1 UTC
                b = new Date(f.Y(), 6),
                // Jul 1
                d = Date.UTC(f.Y(), 6); // Jul 1 UTC
            return 0 + ((a - c) !== (b - d));
        },
        O: function () { // Difference to GMT in hour format; e.g. +0200
            var tzo = jsdate.getTimezoneOffset(),
                a = Math.abs(tzo);
            return (tzo > 0 ? "-" : "+") + _pad(Math.floor(a / 60) * 100 + a % 60, 4);
        },
        P: function () { // Difference to GMT w/colon; e.g. +02:00
            var O = f.O();
            return (O.substr(0, 3) + ":" + O.substr(3, 2));
        },
        T: function () { // Timezone abbreviation; e.g. EST, MDT, ...
            // The following works, but requires inclusion of the very
            // large timezone_abbreviations_list() function.
/*              var abbr = '', i = 0, os = 0, default = 0;
            if (!tal.length) {
                tal = that.timezone_abbreviations_list();
            }
            if (that.php_js && that.php_js.default_timezone) {
                default = that.php_js.default_timezone;
                for (abbr in tal) {
                    for (i=0; i < tal[abbr].length; i++) {
                        if (tal[abbr][i].timezone_id === default) {
                            return abbr.toUpperCase();
                        }
                    }
                }
            }
            for (abbr in tal) {
                for (i = 0; i < tal[abbr].length; i++) {
                    os = -jsdate.getTimezoneOffset() * 60;
                    if (tal[abbr][i].offset === os) {
                        return abbr.toUpperCase();
                    }
                }
            }
*/
            return 'UTC';
        },
        Z: function () { // Timezone offset in seconds (-43200...50400)
            return -jsdate.getTimezoneOffset() * 60;
        },

        // Full Date/Time
        c: function () { // ISO-8601 date.
            return 'Y-m-d\\Th:i:sP'.replace(formatChr, formatChrCb);
        },
        r: function () { // RFC 2822
            return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb);
        },
        U: function () { // Seconds since UNIX epoch
            return jsdate / 1000 | 0;
        }
    };
    this.date = function (format, timestamp) {
        that = this;
        jsdate = (timestamp == null ? new Date() : // Not provided
        (timestamp instanceof Date) ? new Date(timestamp) : // JS Date()
        new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int)
        );
        return format.replace(formatChr, formatChrCb);
    };
    return this.date(format, timestamp);
}
<commit_msg>Fixed bug in the "c" format (ISO-8601).<commit_after>function date (format, timestamp) {
    // http://kevin.vanzonneveld.net
    // +   original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
    // +      parts by: Peter-Paul Koch (http://www.quirksmode.org/js/beat.html)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: MeEtc (http://yass.meetcweb.com)
    // +   improved by: Brad Touesnard
    // +   improved by: Tim Wiel
    // +   improved by: Bryan Elliott
    //
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: David Randall
    // +      input by: Brett Zamir (http://brett-zamir.me)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Theriault
    // +  derived from: gettimeofday
    // +      input by: majak
    // +   bugfixed by: majak
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: Alex
    // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Theriault
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Theriault
    // +   improved by: Thomas Beaucourt (http://www.webapp.fr)
    // +   improved by: JT
    // +   improved by: Theriault
    // +   improved by: Rafał Kukawski (http://blog.kukawski.pl)
    // +   bugfixed by: omid (http://phpjs.org/functions/380:380#comment_137122)
    // +      input by: Martin
    // +      input by: Alex Wilson
    // %        note 1: Uses global: php_js to store the default timezone
    // %        note 2: Although the function potentially allows timezone info (see notes), it currently does not set
    // %        note 2: per a timezone specified by date_default_timezone_set(). Implementers might use
    // %        note 2: this.php_js.currentTimezoneOffset and this.php_js.currentTimezoneDST set by that function
    // %        note 2: in order to adjust the dates in this function (or our other date functions!) accordingly
    // *     example 1: date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400);
    // *     returns 1: '09:09:40 m is month'
    // *     example 2: date('F j, Y, g:i a', 1062462400);
    // *     returns 2: 'September 2, 2003, 2:26 am'
    // *     example 3: date('Y W o', 1062462400);
    // *     returns 3: '2003 36 2003'
    // *     example 4: x = date('Y m d', (new Date()).getTime()/1000);
    // *     example 4: (x+'').length == 10 // 2009 01 09
    // *     returns 4: true
    // *     example 5: date('W', 1104534000);
    // *     returns 5: '53'
    // *     example 6: date('B t', 1104534000);
    // *     returns 6: '999 31'
    // *     example 7: date('W U', 1293750000.82); // 2010-12-31
    // *     returns 7: '52 1293750000'
    // *     example 8: date('W', 1293836400); // 2011-01-01
    // *     returns 8: '52'
    // *     example 9: date('W Y-m-d', 1293974054); // 2011-01-02
    // *     returns 9: '52 2011-01-02'
    var that = this,
        jsdate, f, formatChr = /\\?([a-z])/gi,
        formatChrCb,
        // Keep this here (works, but for code commented-out
        // below for file size reasons)
        //, tal= [],
        _pad = function (n, c) {
            if ((n = n + '').length < c) {
                return new Array((++c) - n.length).join('0') + n;
            }
            return n;
        },
        txt_words = ["Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
    formatChrCb = function (t, s) {
        return f[t] ? f[t]() : s;
    };
    f = {
        // Day
        d: function () { // Day of month w/leading 0; 01..31
            return _pad(f.j(), 2);
        },
        D: function () { // Shorthand day name; Mon...Sun
            return f.l().slice(0, 3);
        },
        j: function () { // Day of month; 1..31
            return jsdate.getDate();
        },
        l: function () { // Full day name; Monday...Sunday
            return txt_words[f.w()] + 'day';
        },
        N: function () { // ISO-8601 day of week; 1[Mon]..7[Sun]
            return f.w() || 7;
        },
        S: function () { // Ordinal suffix for day of month; st, nd, rd, th
            var j = f.j();
            return j < 4 | j > 20 && ['st', 'nd', 'rd'][j%10 - 1] || 'th';
        },
        w: function () { // Day of week; 0[Sun]..6[Sat]
            return jsdate.getDay();
        },
        z: function () { // Day of year; 0..365
            var a = new Date(f.Y(), f.n() - 1, f.j()),
                b = new Date(f.Y(), 0, 1);
            return Math.round((a - b) / 864e5) + 1;
        },

        // Week
        W: function () { // ISO-8601 week number
            var a = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3),
                b = new Date(a.getFullYear(), 0, 4);
            return _pad(1 + Math.round((a - b) / 864e5 / 7), 2);
        },

        // Month
        F: function () { // Full month name; January...December
            return txt_words[6 + f.n()];
        },
        m: function () { // Month w/leading 0; 01...12
            return _pad(f.n(), 2);
        },
        M: function () { // Shorthand month name; Jan...Dec
            return f.F().slice(0, 3);
        },
        n: function () { // Month; 1...12
            return jsdate.getMonth() + 1;
        },
        t: function () { // Days in month; 28...31
            return (new Date(f.Y(), f.n(), 0)).getDate();
        },

        // Year
        L: function () { // Is leap year?; 0 or 1
            var j = f.Y();
            return j%4==0 & j%100!=0 | j%400==0;
        },
        o: function () { // ISO-8601 year
            var n = f.n(),
                W = f.W(),
                Y = f.Y();
            return Y + (n === 12 && W < 9 ? -1 : n === 1 && W > 9);
        },
        Y: function () { // Full year; e.g. 1980...2010
            return jsdate.getFullYear();
        },
        y: function () { // Last two digits of year; 00...99
            return (f.Y() + "").slice(-2);
        },

        // Time
        a: function () { // am or pm
            return jsdate.getHours() > 11 ? "pm" : "am";
        },
        A: function () { // AM or PM
            return f.a().toUpperCase();
        },
        B: function () { // Swatch Internet time; 000..999
            var H = jsdate.getUTCHours() * 36e2,
                // Hours
                i = jsdate.getUTCMinutes() * 60,
                // Minutes
                s = jsdate.getUTCSeconds(); // Seconds
            return _pad(Math.floor((H + i + s + 36e2) / 86.4) % 1e3, 3);
        },
        g: function () { // 12-Hours; 1..12
            return f.G() % 12 || 12;
        },
        G: function () { // 24-Hours; 0..23
            return jsdate.getHours();
        },
        h: function () { // 12-Hours w/leading 0; 01..12
            return _pad(f.g(), 2);
        },
        H: function () { // 24-Hours w/leading 0; 00..23
            return _pad(f.G(), 2);
        },
        i: function () { // Minutes w/leading 0; 00..59
            return _pad(jsdate.getMinutes(), 2);
        },
        s: function () { // Seconds w/leading 0; 00..59
            return _pad(jsdate.getSeconds(), 2);
        },
        u: function () { // Microseconds; 000000-999000
            return _pad(jsdate.getMilliseconds() * 1000, 6);
        },

        // Timezone
        e: function () { // Timezone identifier; e.g. Atlantic/Azores, ...
            // The following works, but requires inclusion of the very large
            // timezone_abbreviations_list() function.
/*              return this.date_default_timezone_get();
*/
            throw 'Not supported (see source code of date() for timezone on how to add support)';
        },
        I: function () { // DST observed?; 0 or 1
            // Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC.
            // If they are not equal, then DST is observed.
            var a = new Date(f.Y(), 0),
                // Jan 1
                c = Date.UTC(f.Y(), 0),
                // Jan 1 UTC
                b = new Date(f.Y(), 6),
                // Jul 1
                d = Date.UTC(f.Y(), 6); // Jul 1 UTC
            return 0 + ((a - c) !== (b - d));
        },
        O: function () { // Difference to GMT in hour format; e.g. +0200
            var tzo = jsdate.getTimezoneOffset(),
                a = Math.abs(tzo);
            return (tzo > 0 ? "-" : "+") + _pad(Math.floor(a / 60) * 100 + a % 60, 4);
        },
        P: function () { // Difference to GMT w/colon; e.g. +02:00
            var O = f.O();
            return (O.substr(0, 3) + ":" + O.substr(3, 2));
        },
        T: function () { // Timezone abbreviation; e.g. EST, MDT, ...
            // The following works, but requires inclusion of the very
            // large timezone_abbreviations_list() function.
/*              var abbr = '', i = 0, os = 0, default = 0;
            if (!tal.length) {
                tal = that.timezone_abbreviations_list();
            }
            if (that.php_js && that.php_js.default_timezone) {
                default = that.php_js.default_timezone;
                for (abbr in tal) {
                    for (i=0; i < tal[abbr].length; i++) {
                        if (tal[abbr][i].timezone_id === default) {
                            return abbr.toUpperCase();
                        }
                    }
                }
            }
            for (abbr in tal) {
                for (i = 0; i < tal[abbr].length; i++) {
                    os = -jsdate.getTimezoneOffset() * 60;
                    if (tal[abbr][i].offset === os) {
                        return abbr.toUpperCase();
                    }
                }
            }
*/
            return 'UTC';
        },
        Z: function () { // Timezone offset in seconds (-43200...50400)
            return -jsdate.getTimezoneOffset() * 60;
        },

        // Full Date/Time
        c: function () { // ISO-8601 date.
            return 'Y-m-d\\TH:i:sP'.replace(formatChr, formatChrCb);
        },
        r: function () { // RFC 2822
            return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb);
        },
        U: function () { // Seconds since UNIX epoch
            return jsdate / 1000 | 0;
        }
    };
    this.date = function (format, timestamp) {
        that = this;
        jsdate = (timestamp == null ? new Date() : // Not provided
        (timestamp instanceof Date) ? new Date(timestamp) : // JS Date()
        new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int)
        );
        return format.replace(formatChr, formatChrCb);
    };
    return this.date(format, timestamp);
}
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2.view',
  name: 'FObjectView',
  extends: 'foam.u2.Controller',

  documentation: 'View for editing FObjects.',

  imports: [
    'setTimeout',
    'strategizer?'
  ],

  requires: [
    'foam.core.Latch'
  ],

  messages: [
    { name: 'PLACEHOLDER_TEXT', message: 'select...' }
  ],

  properties: [
    {
      class: 'foam.core.FObjectProperty',
      of: 'foam.core.Latch',
      name: 'choicesLoaded',
      documentation: 'A latch used to wait on choices loaded.',
      factory: function() { return this.Latch.create(); }
    },
    {
      class: 'String',
      name: 'objectClass',
      label: '',
      visibility: function(allowCustom, classIsFinal, choices, data, placeholder) {
        if ( ! allowCustom && choices.length <= 1 && ! placeholder ) return foam.u2.DisplayMode.HIDDEN;
        if ( classIsFinal && this.dataWasProvided_ ) return foam.u2.DisplayMode.HIDDEN;
        return foam.u2.DisplayMode.RW;
      },
      view: function(args, X) {
        return {
          class: X.data.allowCustom ? 'foam.u2.TextField' : 'foam.u2.view.ChoiceView',
          displayWidth: 60,
          placeholder: X.data.placeholder,
          header: X.data.header,
          choices$: X.data.choices$
        };
      }
    },
    {
      name: 'config'
      // Map of property-name: {map of property overrides} for configuring properties
      // values include 'label', 'units', and 'view'
    },
    {
      class: 'FObjectProperty',
      name: 'data',
      label: '',
      // We need to override the default view, otherwise we end up with a
      // circular definition where FObjectView has an FObjectProperty which gets
      // rendered as an FObjectView, which leads to infinite recursion.
      preSet: function(o, n) { return n || o; },
      view: 'foam.u2.detail.SectionedDetailView'
    },
    {
      class: 'foam.u2.ViewSpec',
      name: 'dataView',
      documentation: 'Set this to change the view of the FObject being created.'
    },
    {
      class: 'Class',
      name: 'of'
    },
    {
      class: 'Boolean',
      name: 'skipBaseClass',
      documentation: 'If true, skips of base-class as a choice when no strategies fetched.',
      value: false
    },
    {
      class: 'Boolean',
      name: 'allowCustom',
      expression: function(choices) {
        return choices.length == 0;
      }
    },
    {
      class: 'Function',
      name: 'copyOldData',
      documentation: `
        Function to copy data from old object to new object when objectClass changes.
        The default implementation copies all properties with the same name, but
        if you don't want this behaviour, then implement your own copy method.
        Ex. if we only wanted to copy two fields:
          copyOldData: function(o) { return {
            field1: o.field1,
            field2: o.field2
        }; }
        You do not need to handle the case where the old object is null.
      `,
      value: function(o) { return o; }
    },
    {
      class: 'Boolean',
      name: 'classIsFinal',
      documentation: 'If true, objectClass cannot be changed if data is provided.'
    },
    {
      class: 'Boolean',
      name: 'dataWasProvided_',
      documentation: 'Set to true if data was initially provided. Used to implement classIsFinal.'
    },
    {
      class: 'String',
      name: 'placeholder',
      factory: function() {
        return this.PLACEHOLDER_TEXT;
      },
      documentation: 'If no placeholder, the choiceView will select the first element',
    },
    {
      class: 'String',
      name: 'header',
      documentation: 'The heading text for the choices',
    },
    {
      class: 'Array',
      name: 'choices',
      documentation: `
        A list of choices for a ChoiceView containing models related to the
        model in the 'of' property. The user can choose to create an instance
        of one of the models in this list.
      `
    },
    {
      name: 'predicate',
      documentation: `
        Predicate to pass into strategizer query request. Used to define results from strategizer query.
        Example use of strategizer predicate on FObjectView from property view:

        name: 'exampleProp',
        view: function(_, X) {
          let predicate = expr.AND(
              expr.EQ(foam.strategy.StrategyReference.DESIRED_MODEL_ID, 'foam.nanos.auth.User'),
              expr.IN(
                foam.strategy.StrategyReference.STRATEGY,
                [foam.lookup('foam.nanos.auth.SomeUserClass'), foam.lookup('foam.nanos.auth.AnotherUserClass') ]
              )
          );
          return foam.u2.view.FObjectView.create({
            data: X.data.exampleProp,
            of: foam.nanos.auth.User,
            predicate: predicate
          }, X);
        }
      `
    }
  ],

  methods: [
    function updateChoices() {
      if ( this.of == null ) {
        this.choices = [];
        this.choicesLoaded.resolve();
        return;
      }

      // If this view is being used in a nanos application, then use the
      // strategizer service to populate the list of choices. Otherwise
      // populate the list of choices using models related to 'of' via the
      // implements and extends relations.
      if ( this.strategizer != null ) {
        this.strategizer.query(null, this.of.id, null, this.predicate).then((strategyReferences) => {
          if ( ! Array.isArray(strategyReferences) || strategyReferences.length === 0 ) {
            this.choices = this.skipBaseClass ? [] : [[this.of.id, this.of.model_.label]];
            this.choicesLoaded.resolve();
            return;
          }

          var choices = strategyReferences
            .reduce((arr, sr) => {
              if ( ! sr.strategy ) {
                console.warn('Invalid strategy reference: ' + sr.id);
                return arr;
              }

              return arr.concat([[sr.strategy.id, sr.strategy.model_.label]]);
            }, [])
            .filter(x => x);

          // Sort choices alphabetically by label.
          choices.sort((a, b) => a[1] > b[1] ? 1 : -1);

          this.choices = choices;
          this.choicesLoaded.resolve();
        }).catch(err => console.warn(err));
      } else {
        this.choices = this.choicesFallback(this.of);
      }
    },

    async function initE() {
      this.SUPER();

      function dataToClass(d) {
        return d ? d.cls_.id : '';
      }

      var classToData = function(c) {
        if ( ! c ) return undefined;
        var m = c && this.__context__.lookup(c, true);
        return m.create(this.data ? this.copyOldData(this.data) : null, this);
      }.bind(this);

      this.dataWasProvided_ = !! this.data;

      if ( ! this.data && this.objectClass )
        this.data = classToData(this.objectClass);

      if ( ! this.choices.length ) {
        this.onDetach(this.of$.sub(this.updateChoices));
        this.updateChoices();
        await this.choicesLoaded;
      }

      this.data$.relateTo(
        this.objectClass$,
        dataToClass,
        classToData
      );

      if ( this.data ) { this.objectClass = dataToClass(this.data); }
      if ( ! this.data && ! this.objectClass && this.choices.length && !this.placeholder ) this.objectClass = this.choices[0][0];

      this.
        start(this.OBJECT_CLASS).
          // If we were using a DetailView, this would be done for us, but since
          // we aren't, we need to connect the 'visibility' property ourself.
          show(this.OBJECT_CLASS.createVisibilityFor(foam.core.SimpleSlot.create({value: this}), this.controllerMode$).map(function(m) {
            return m != foam.u2.DisplayMode.HIDDEN;
          })).
        end().
        start().
          show(this.objectClass$).
          tag(foam.u2.detail.VerticalDetailView, {
            data$: this.data$,
            config: this.config
          }).
        end();
    },

    function choicesFallback(of) {
      /**
       * Return a list of choices for a ChoiceView containing models related to
       * 'of' via the implements and extends relations. Does not include
       * interfaces or abstract models in the list of choices.
       */
      if ( ! of ) return [];

      var modelIdToDeps = Object.values(foam.USED)
        .concat(Object.values(foam.UNUSED))
        .reduce((map, m) => {
          // QUESTION: If we're filtering out instances of InterfaceModel
          // below, why do we care about getting the list of things the model
          // implements? Won't they all be interfaces? Or are some of them
          // mixins?
          var deps = m.implements
            ? m.implements.map((imp) => {
              return foam.String.isInstance(imp) ? imp : imp.path;
            })
            : [];
          if ( m.extends ) deps.push(m.extends);
          var id = m.id || m.package + '.' + m.name;
          map[id] = deps;
          return map;
        }, {});

      var choices = {};
      choices[of.id] = true;

      while ( true ) {
        var prev = Object.keys(choices).length;
        for ( var [id, deps] of Object.entries(modelIdToDeps) ) {
          if ( deps.filter((d) => choices[d]).length ) choices[id] = true;
        }
        if ( prev == Object.keys(choices).length ) break;
      }

      return Object.keys(choices)
        .map((id) => foam.lookup(id).model_)
        .filter((m) => ! foam.core.InterfaceModel.isInstance(m))
        .filter((m) => ! m.abstract )
        .map((m) => [m.id, m.label]);
    }
  ]
});
<commit_msg>Fix FObjectView placeholder regression (#4738)<commit_after>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2.view',
  name: 'FObjectView',
  extends: 'foam.u2.Controller',

  documentation: 'View for editing FObjects.',

  imports: [
    'setTimeout',
    'strategizer?'
  ],

  requires: [
    'foam.core.Latch'
  ],

  messages: [
    { name: 'PLACEHOLDER_TEXT', message: 'select...' }
  ],

  properties: [
    {
      class: 'foam.core.FObjectProperty',
      of: 'foam.core.Latch',
      name: 'choicesLoaded',
      documentation: 'A latch used to wait on choices loaded.',
      factory: function() { return this.Latch.create(); }
    },
    {
      class: 'String',
      name: 'objectClass',
      label: '',
      visibility: function(allowCustom, classIsFinal, choices, data, placeholder) {
        if ( ! allowCustom && choices.length <= 1 && ! this.hasOwnProperty('placeholder') ) return foam.u2.DisplayMode.HIDDEN;
        if ( classIsFinal && this.dataWasProvided_ ) return foam.u2.DisplayMode.HIDDEN;
        return foam.u2.DisplayMode.RW;
      },
      view: function(args, X) {
        return {
          class: X.data.allowCustom ? 'foam.u2.TextField' : 'foam.u2.view.ChoiceView',
          displayWidth: 60,
          placeholder: X.data.placeholder,
          header: X.data.header,
          choices$: X.data.choices$
        };
      }
    },
    {
      name: 'config'
      // Map of property-name: {map of property overrides} for configuring properties
      // values include 'label', 'units', and 'view'
    },
    {
      class: 'FObjectProperty',
      name: 'data',
      label: '',
      // We need to override the default view, otherwise we end up with a
      // circular definition where FObjectView has an FObjectProperty which gets
      // rendered as an FObjectView, which leads to infinite recursion.
      preSet: function(o, n) { return n || o; },
      view: 'foam.u2.detail.SectionedDetailView'
    },
    {
      class: 'foam.u2.ViewSpec',
      name: 'dataView',
      documentation: 'Set this to change the view of the FObject being created.'
    },
    {
      class: 'Class',
      name: 'of'
    },
    {
      class: 'Boolean',
      name: 'skipBaseClass',
      documentation: 'If true, skips of base-class as a choice when no strategies fetched.',
      value: false
    },
    {
      class: 'Boolean',
      name: 'allowCustom',
      expression: function(choices) {
        return choices.length == 0;
      }
    },
    {
      class: 'Function',
      name: 'copyOldData',
      documentation: `
        Function to copy data from old object to new object when objectClass changes.
        The default implementation copies all properties with the same name, but
        if you don't want this behaviour, then implement your own copy method.
        Ex. if we only wanted to copy two fields:
          copyOldData: function(o) { return {
            field1: o.field1,
            field2: o.field2
        }; }
        You do not need to handle the case where the old object is null.
      `,
      value: function(o) { return o; }
    },
    {
      class: 'Boolean',
      name: 'classIsFinal',
      documentation: 'If true, objectClass cannot be changed if data is provided.'
    },
    {
      class: 'Boolean',
      name: 'dataWasProvided_',
      documentation: 'Set to true if data was initially provided. Used to implement classIsFinal.'
    },
    {
      class: 'String',
      name: 'placeholder',
      expression: function() {
        return this.PLACEHOLDER_TEXT;
      },
      documentation: 'If no placeholder, the choiceView will select the first element',
    },
    {
      class: 'String',
      name: 'header',
      documentation: 'The heading text for the choices',
    },
    {
      class: 'Array',
      name: 'choices',
      documentation: `
        A list of choices for a ChoiceView containing models related to the
        model in the 'of' property. The user can choose to create an instance
        of one of the models in this list.
      `
    },
    {
      name: 'predicate',
      documentation: `
        Predicate to pass into strategizer query request. Used to define results from strategizer query.
        Example use of strategizer predicate on FObjectView from property view:

        name: 'exampleProp',
        view: function(_, X) {
          let predicate = expr.AND(
              expr.EQ(foam.strategy.StrategyReference.DESIRED_MODEL_ID, 'foam.nanos.auth.User'),
              expr.IN(
                foam.strategy.StrategyReference.STRATEGY,
                [foam.lookup('foam.nanos.auth.SomeUserClass'), foam.lookup('foam.nanos.auth.AnotherUserClass') ]
              )
          );
          return foam.u2.view.FObjectView.create({
            data: X.data.exampleProp,
            of: foam.nanos.auth.User,
            predicate: predicate
          }, X);
        }
      `
    }
  ],

  methods: [
    function updateChoices() {
      if ( this.of == null ) {
        this.choices = [];
        this.choicesLoaded.resolve();
        return;
      }

      // If this view is being used in a nanos application, then use the
      // strategizer service to populate the list of choices. Otherwise
      // populate the list of choices using models related to 'of' via the
      // implements and extends relations.
      if ( this.strategizer != null ) {
        this.strategizer.query(null, this.of.id, null, this.predicate).then((strategyReferences) => {
          if ( ! Array.isArray(strategyReferences) || strategyReferences.length === 0 ) {
            this.choices = this.skipBaseClass ? [] : [[this.of.id, this.of.model_.label]];
            this.choicesLoaded.resolve();
            return;
          }

          var choices = strategyReferences
            .reduce((arr, sr) => {
              if ( ! sr.strategy ) {
                console.warn('Invalid strategy reference: ' + sr.id);
                return arr;
              }

              return arr.concat([[sr.strategy.id, sr.strategy.model_.label]]);
            }, [])
            .filter(x => x);

          // Sort choices alphabetically by label.
          choices.sort((a, b) => a[1] > b[1] ? 1 : -1);

          this.choices = choices;
          this.choicesLoaded.resolve();
        }).catch(err => console.warn(err));
      } else {
        this.choices = this.choicesFallback(this.of);
      }
    },

    async function initE() {
      this.SUPER();

      function dataToClass(d) {
        return d ? d.cls_.id : '';
      }

      var classToData = function(c) {
        if ( ! c ) return undefined;
        var m = c && this.__context__.lookup(c, true);
        return m.create(this.data ? this.copyOldData(this.data) : null, this);
      }.bind(this);

      this.dataWasProvided_ = !! this.data;

      if ( ! this.data && this.objectClass )
        this.data = classToData(this.objectClass);

      if ( ! this.choices.length ) {
        this.onDetach(this.of$.sub(this.updateChoices));
        this.updateChoices();
        await this.choicesLoaded;
      }

      this.data$.relateTo(
        this.objectClass$,
        dataToClass,
        classToData
      );

      if ( this.data ) { this.objectClass = dataToClass(this.data); }
      if ( ! this.data && ! this.objectClass && this.choices.length && ! this.hasOwnProperty('placeholder') ) this.objectClass = this.choices[0][0];

      this.
        start(this.OBJECT_CLASS).
          // If we were using a DetailView, this would be done for us, but since
          // we aren't, we need to connect the 'visibility' property ourself.
          show(this.OBJECT_CLASS.createVisibilityFor(foam.core.SimpleSlot.create({value: this}), this.controllerMode$).map(function(m) {
            return m != foam.u2.DisplayMode.HIDDEN;
          })).
        end().
        start().
          show(this.objectClass$).
          tag(foam.u2.detail.VerticalDetailView, {
            data$: this.data$,
            config: this.config
          }).
        end();
    },

    function choicesFallback(of) {
      /**
       * Return a list of choices for a ChoiceView containing models related to
       * 'of' via the implements and extends relations. Does not include
       * interfaces or abstract models in the list of choices.
       */
      if ( ! of ) return [];

      var modelIdToDeps = Object.values(foam.USED)
        .concat(Object.values(foam.UNUSED))
        .reduce((map, m) => {
          // QUESTION: If we're filtering out instances of InterfaceModel
          // below, why do we care about getting the list of things the model
          // implements? Won't they all be interfaces? Or are some of them
          // mixins?
          var deps = m.implements
            ? m.implements.map((imp) => {
              return foam.String.isInstance(imp) ? imp : imp.path;
            })
            : [];
          if ( m.extends ) deps.push(m.extends);
          var id = m.id || m.package + '.' + m.name;
          map[id] = deps;
          return map;
        }, {});

      var choices = {};
      choices[of.id] = true;

      while ( true ) {
        var prev = Object.keys(choices).length;
        for ( var [id, deps] of Object.entries(modelIdToDeps) ) {
          if ( deps.filter((d) => choices[d]).length ) choices[id] = true;
        }
        if ( prev == Object.keys(choices).length ) break;
      }

      return Object.keys(choices)
        .map((id) => foam.lookup(id).model_)
        .filter((m) => ! foam.core.InterfaceModel.isInstance(m))
        .filter((m) => ! m.abstract )
        .map((m) => [m.id, m.label]);
    }
  ]
});
<|endoftext|>


<commit_before>/*
 * Copyright 2016 EPAM Systems
 *
 *
 * This file is part of EPAM Report Portal.
 * https://github.com/epam/ReportPortal
 *
 * Report Portal is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Report Portal is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Report Portal.  If not, see <http://www.gnu.org/licenses/>.
 */
define(function (require) {
    'use strict';

    var $ = require('jquery');
    var Epoxy = require('backbone-epoxy');
    var Util = require('util');

    var StepLogDefectTypeView = require('launches/common/StepLogDefectTypeView');

    var LogItemInfoStackTraceView = require('launches/logLevel/LogItemInfoTabs/LogItemInfoStackTraceView');
    var LogItemInfoDetailsView = require('launches/logLevel/LogItemInfoTabs/LogItemInfoDetailsView');
    var LogItemInfoActivity = require('launches/logLevel/LogItemInfoTabs/LogItemInfoActivity');
    var LogItemInfoAttachmentsView = require('launches/logLevel/LogItemInfoTabs/LogItemInfoAttachments');
    var App = require('app');
    var _ = require('underscore');

    var config = App.getInstance();

    var LogItemInfoTabsView = Epoxy.View.extend({
        template: 'tpl-launch-log-item-info-tabs',
        className: 'launch-log-item-info-tabs',

        events: {
            'click [data-js-item-stack-trace-label]': function () {
                config.trackingDispatcher.trackEventNumber(200);
                this.toggleModelField('stackTrace');
            },
            'click [data-js-item-gallery-label]': function () {
                config.trackingDispatcher.trackEventNumber(201);
                this.toggleModelField('attachments');
            },
            'click [data-js-item-details-label]': function () {
                config.trackingDispatcher.trackEventNumber(202);
                this.toggleModelField('itemDetails');
            },
            'click [data-js-item-activity-label]': function () {
                config.trackingDispatcher.trackEventNumber(203);
                this.toggleModelField('activity');
            }
        },

        bindings: {
            '[data-js-item-stack-trace-label]': 'classes: {active: stackTrace}',
            '[data-js-item-gallery-label]': 'classes: {active: attachments}',
            '[data-js-item-details-label]': 'classes: {active: itemDetails}',
            '[data-js-item-activity-label]': 'classes: {active: activity}',
            '[data-js-item-stack-trace]': 'classes: {hide: not(stackTrace)}',
            '[data-js-item-gallery]': 'classes: {hide: not(attachments)}',
            '[data-js-item-details]': 'classes: {hide: not(itemDetails)}',
            '[data-js-item-activity]': 'classes: {hide: not(activity)}'
        },
        initialize: function (options) {
            this.viewModel = options.itemModel;
            this.model = new (Epoxy.Model.extend({
                defaults: {
                    stackTrace: false,
                    attachments: false,
                    itemDetails: false,
                    activity: false
                }
            }))();
            this.listenTo(this.model, 'change:stackTrace change:attachments change:itemDetails change:activity', this.onChangeTabModel);
            this.render();
            if (this.validateForIssue()) {
                this.issueView = new StepLogDefectTypeView({
                    model: this.viewModel,
                    pageType: 'logs',
                    el: $('[data-js-step-issue]', this.$el)
                });
            }
            this.stackTrace = new LogItemInfoStackTraceView({
                el: $('[data-js-item-stack-trace]', this.$el),
                itemModel: this.viewModel,
                parentModel: this.model
            });
            this.details = new LogItemInfoDetailsView({
                el: $('[data-js-item-details]', this.$el),
                itemModel: this.viewModel,
                parentModel: this.model
            });
            this.activity = new LogItemInfoActivity({
                el: $('[ data-js-item-activity]', this.$el),
                itemModel: this.viewModel,
                parentModel: this.model
            });
            this.attachments = new LogItemInfoAttachmentsView({
                el: $('[data-js-item-gallery]', this.$el),
                itemModel: this.viewModel,
                parentModel: this.model
            });
            this.listenTo(this.stackTrace, 'goToLog', this.goToLog);
            this.listenTo(this.attachments, 'click:attachment', this.onClickAttachment);
        },
        onClickAttachment: function (model) {
            this.trigger('click:attachment', model);
        },
        goToLog: function (logId) {
            this.trigger('goToLog', logId);
        },
        endGoToLog: function () {
            this.stackTrace.endGoToLog();
        },
        goToAttachment: function (logId) {
            var self = this;
            config.mainScrollElement.animate({ scrollTop: this.el.offsetTop }, 500, function () {
                self.attachments.goToAttachmentsPrev();
                self.model.set({ attachments: true });
                self.attachments.goToAttachments(logId);
            });
        },
        validateForIssue: function () {
            return !!this.viewModel.get('issue');
        },
        onChangeTabModel: function (model, value) {
            if (value) {
                this.model.set(_.extend(_.clone(this.model.defaults), model.changed));
            }
        },
        toggleModelField: function (field) {
            this.model.set(field, !this.model.get(field));
        },

        render: function () {
            this.$el.html(Util.templates(this.template, {}));
        },

        onDestroy: function () {
            this.stackTrace && this.stackTrace.destroy();
            this.details && this.details.destroy();
            this.activity && this.activity.destroy();
            this.attachments && this.attachments.destroy();
        }
    });

    return LogItemInfoTabsView;
});
<commit_msg>EPMRPP-31282. Hided 'History of actions' tab for retry items.<commit_after>/*
 * Copyright 2016 EPAM Systems
 *
 *
 * This file is part of EPAM Report Portal.
 * https://github.com/epam/ReportPortal
 *
 * Report Portal is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Report Portal is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Report Portal.  If not, see <http://www.gnu.org/licenses/>.
 */
define(function (require) {
    'use strict';

    var $ = require('jquery');
    var Epoxy = require('backbone-epoxy');
    var Util = require('util');

    var StepLogDefectTypeView = require('launches/common/StepLogDefectTypeView');

    var LogItemInfoStackTraceView = require('launches/logLevel/LogItemInfoTabs/LogItemInfoStackTraceView');
    var LogItemInfoDetailsView = require('launches/logLevel/LogItemInfoTabs/LogItemInfoDetailsView');
    var LogItemInfoActivity = require('launches/logLevel/LogItemInfoTabs/LogItemInfoActivity');
    var LogItemInfoAttachmentsView = require('launches/logLevel/LogItemInfoTabs/LogItemInfoAttachments');
    var App = require('app');
    var _ = require('underscore');

    var config = App.getInstance();

    var LogItemInfoTabsView = Epoxy.View.extend({
        template: 'tpl-launch-log-item-info-tabs',
        className: 'launch-log-item-info-tabs',

        events: {
            'click [data-js-item-stack-trace-label]': function () {
                config.trackingDispatcher.trackEventNumber(200);
                this.toggleModelField('stackTrace');
            },
            'click [data-js-item-gallery-label]': function () {
                config.trackingDispatcher.trackEventNumber(201);
                this.toggleModelField('attachments');
            },
            'click [data-js-item-details-label]': function () {
                config.trackingDispatcher.trackEventNumber(202);
                this.toggleModelField('itemDetails');
            },
            'click [data-js-item-activity-label]': function () {
                config.trackingDispatcher.trackEventNumber(203);
                this.toggleModelField('activity');
            }
        },

        bindings: {
            '[data-js-item-stack-trace-label]': 'classes: {active: stackTrace}',
            '[data-js-item-gallery-label]': 'classes: {active: attachments}',
            '[data-js-item-details-label]': 'classes: {active: itemDetails}',
            '[data-js-item-activity-label]': 'classes: {hide: isShowActivities, active: activity}',
            '[data-js-item-stack-trace]': 'classes: {hide: not(stackTrace)}',
            '[data-js-item-gallery]': 'classes: {hide: not(attachments)}',
            '[data-js-item-details]': 'classes: {hide: not(itemDetails)}',
            '[data-js-item-activity]': 'classes: {hide: not(activity)}'
        },

        computeds: {
            isShowActivities: function () {
                return ~this.viewModel.get('id').indexOf('retry:');
            }
        },
        initialize: function (options) {
            this.viewModel = options.itemModel;
            this.model = new (Epoxy.Model.extend({
                defaults: {
                    stackTrace: false,
                    attachments: false,
                    itemDetails: false,
                    activity: false
                }
            }))();
            this.listenTo(this.model, 'change:stackTrace change:attachments change:itemDetails change:activity', this.onChangeTabModel);
            this.render();
            if (this.validateForIssue()) {
                this.issueView = new StepLogDefectTypeView({
                    model: this.viewModel,
                    pageType: 'logs',
                    el: $('[data-js-step-issue]', this.$el)
                });
            }
            this.stackTrace = new LogItemInfoStackTraceView({
                el: $('[data-js-item-stack-trace]', this.$el),
                itemModel: this.viewModel,
                parentModel: this.model
            });
            this.details = new LogItemInfoDetailsView({
                el: $('[data-js-item-details]', this.$el),
                itemModel: this.viewModel,
                parentModel: this.model
            });
            this.activity = new LogItemInfoActivity({
                el: $('[ data-js-item-activity]', this.$el),
                itemModel: this.viewModel,
                parentModel: this.model
            });
            this.attachments = new LogItemInfoAttachmentsView({
                el: $('[data-js-item-gallery]', this.$el),
                itemModel: this.viewModel,
                parentModel: this.model
            });
            this.listenTo(this.stackTrace, 'goToLog', this.goToLog);
            this.listenTo(this.attachments, 'click:attachment', this.onClickAttachment);
        },
        onClickAttachment: function (model) {
            this.trigger('click:attachment', model);
        },
        goToLog: function (logId) {
            this.trigger('goToLog', logId);
        },
        endGoToLog: function () {
            this.stackTrace.endGoToLog();
        },
        goToAttachment: function (logId) {
            var self = this;
            config.mainScrollElement.animate({ scrollTop: this.el.offsetTop }, 500, function () {
                self.attachments.goToAttachmentsPrev();
                self.model.set({ attachments: true });
                self.attachments.goToAttachments(logId);
            });
        },
        validateForIssue: function () {
            return !!this.viewModel.get('issue');
        },
        onChangeTabModel: function (model, value) {
            if (value) {
                this.model.set(_.extend(_.clone(this.model.defaults), model.changed));
            }
        },
        toggleModelField: function (field) {
            this.model.set(field, !this.model.get(field));
        },

        render: function () {
            this.$el.html(Util.templates(this.template, {}));
        },

        onDestroy: function () {
            this.stackTrace && this.stackTrace.destroy();
            this.details && this.details.destroy();
            this.activity && this.activity.destroy();
            this.attachments && this.attachments.destroy();
        }
    });

    return LogItemInfoTabsView;
});
<|endoftext|>


<commit_before>(function () {
  'use strict';

  /*POLICY OUTPUTS CONTROLLER*/
  angular
    .module('webApp')
    .controller('PolicyOutputCtrl', PolicyOutputCtrl);

  PolicyOutputCtrl.$inject = ['FragmentFactory', 'policyModelFactory', '$q'];

  function PolicyOutputCtrl(FragmentFactory, policyModelFactory, $q) {
    var vm = this;
    vm.outputList = [];
    init();

    function init() {
      var defer = $q.defer();
      vm.policy = policyModelFactory.GetCurrentPolicy();

      vm.outputList = [
        {
          "name": "out-print",
          "description": "dfsdfdfsdfdsfdsgfggfg",
          "type": "Print",
          "configuration": {
            "multiplexer": "true",
            "isAutoCalculateId": "true"
          }
        },
        {
          "name": "out-print 2",
          "description": "dfd fggfhty ghgvc fgh",
          "type": "Print",
          "configuration": {
            "multiplexer": "true",
            "isAutoCalculateId": "true"
          }
        }
      ];
      //var outputList = FragmentFactory.GetFragments("output");
      //outputList.then(function (result) {
      //  vm.outputList = result;
      //  defer.resolve();
      //}, function () {
      //  defer.reject();
      //});
      //return defer.promise;
    }

  }
})();
<commit_msg>feature(policy output): Remove fake outputs in order to use real call to back<commit_after>(function () {
  'use strict';

  /*POLICY OUTPUTS CONTROLLER*/
  angular
    .module('webApp')
    .controller('PolicyOutputCtrl', PolicyOutputCtrl);

  PolicyOutputCtrl.$inject = ['FragmentFactory', 'policyModelFactory', '$q'];

  function PolicyOutputCtrl(FragmentFactory, policyModelFactory, $q) {
    var vm = this;
    vm.outputList = [];
    init();

    function init() {
      var defer = $q.defer();
      vm.policy = policyModelFactory.GetCurrentPolicy();

      var outputList = FragmentFactory.GetFragments("output");
      outputList.then(function (result) {
        vm.outputList = result;
        defer.resolve();
      }, function () {
        defer.reject();
      });
      return defer.promise;
    }

  }
})();
<|endoftext|>