<commit_before>/**
    Framework for building object relational database apps

    Copyright (C) 2015  <NAME>
    This program 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.
    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
**/

/*global window, f, m */
(function (f) {
  "use strict";

  f.components.tableDisplay = function (options) {
    var component = {};

    component.controller = function () {
      var selection,
        that = this,
        feather = options.feather,
        name = feather.toCamelCase(),
        pathName = feather.toSpinalCase(),
        plural = f.catalog.getFeather(feather).plural.toSpinalCase();

      this.models = f.models[name].list();
      this.attrs = options.attrs || ["id"];
      this.goHome = function () {
        m.route("/home");
      };
      this.hasSelection = function () {
        return !selection;
      };
      this.isSelected = function (model) {
        return selection === model;
      };
      this.modelDelete = function () {
        selection.delete().then(function () {
          that.models().remove(selection);
          m.route("/" + plural);
        });
      };
      this.modelNew = function () {
        m.route("/" + pathName);
      };
      this.modelOpen = function () {
        m.route("/" + pathName + "/" + selection.data.id());
      };
      this.select = function (model) {
        if (selection !== model) {
          selection = model;
        }
        return selection;
      };
      this.selection = function () {
        return selection;
      };
      this.toggleOpen = function (model) {
        selection = model;
        that.modelOpen();
      };
      this.toggleSelection = function (model) {
        if (selection === model) {
          that.select(undefined);
          return false;
        }
        that.select(model);
        return true;
      };
    };

    component.view = function (ctrl) {
      return m("div", [
        m("div", {id: "toolbar"}, [
          m("button", {
            type: "button",
            onclick: ctrl.goHome
          }, "Home"),
          m("button", {
            type: "button",
            onclick: ctrl.modelNew
          }, "New"),
          m("button", {
            type: "button",
            onclick: ctrl.modelOpen,
            disabled: ctrl.hasSelection()
          }, "Open"),
          m("button", {
            type: "button",
            onclick: ctrl.modelDelete,
            disabled: ctrl.hasSelection()
          }, "Delete"),
          m("input", {
            type: "search",
            value: "Search",
            style: {
              color: "LightGrey",
              fontStyle: "italic"
            }
          }),
        ]),
        m("div", {
          style: {
            overflow: "auto"
          },
          config: function (e) {
            var tb = document.getElementById("toolbar");

            // Set fields table to scroll and toolbar to stay put
            document.documentElement.style.overflow = 'hidden';
            e.style.maxHeight = (window.innerHeight - tb.clientHeight) + "px";
          }
        }, [
          m("table", [
            (function () {
              var tds = ctrl.attrs.map(function (key) {
                  return m("td", key.toProperCase(true));
                });
              return m("tr", {style: {backgroundColor: "LightGrey"}}, tds);
            }()),
            ctrl.models().map(function (model) {
              var d = model.data,
                tds = ctrl.attrs.map(function (col) {
                  var value = d[col](),
                    hasLocale = value !== null &&
                      typeof value.toLocaleString === "function";
                  return m("td", hasLocale ? value.toLocaleString() : value);
                });
              return m("tr", {
                onclick: ctrl.toggleSelection.bind(this, model),
                ondblclick: ctrl.toggleOpen.bind(this, model),
                style: {
                  backgroundColor: ctrl.isSelected(model) ?
                      "LightBlue" : "White"
                }
              }, tds);
            })
          ])
        ])
      ]);
    };

    return component;
  };

}(f));

<commit_msg>Implement view-model on table display<commit_after>/**
    Framework for building object relational database apps

    Copyright (C) 2015  <NAME>
    This program 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.
    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
**/

/*global window, f, m */
(function (f) {
  "use strict";

  f.viewModels.tableViewModel = function (options) {
    var vm = {},
      selection,
      feather = options.feather,
      name = feather.toCamelCase(),
      pathName = feather.toSpinalCase(),
      plural = f.catalog.getFeather(feather).plural.toSpinalCase();

    vm.models = f.models[name].list();
    vm.attrs = options.attrs || ["id"];
    vm.goHome = function () {
      m.route("/home");
    };
    vm.hasSelection = function () {
      return !selection;
    };
    vm.isSelected = function (model) {
      return selection === model;
    };
    vm.modelDelete = function () {
      selection.delete().then(function () {
        vm.models().remove(selection);
        m.route("/" + plural);
      });
    };
    vm.modelNew = function () {
      m.route("/" + pathName);
    };
    vm.modelOpen = function () {
      m.route("/" + pathName + "/" + selection.data.id());
    };
    vm.select = function (model) {
      if (selection !== model) {
        selection = model;
      }
      return selection;
    };
    vm.selection = function () {
      return selection;
    };
    vm.toggleOpen = function (model) {
      selection = model;
      vm.modelOpen();
    };
    vm.toggleSelection = function (model) {
      if (selection === model) {
        vm.select(undefined);
        return false;
      }
      vm.select(model);
      return true;
    };
    return vm;
  };

  f.components.tableDisplay = function (options) {
    var component = {};

    component.controller = function () {
      this.vm = f.viewModels.tableViewModel(options);
    };

    component.view = function (ctrl) {
      var vm = ctrl.vm;
      return m("div", [
        m("div", {id: "toolbar"}, [
          m("button", {
            type: "button",
            onclick: vm.goHome
          }, "Home"),
          m("button", {
            type: "button",
            onclick: vm.modelNew
          }, "New"),
          m("button", {
            type: "button",
            onclick: vm.modelOpen,
            disabled: vm.hasSelection()
          }, "Open"),
          m("button", {
            type: "button",
            onclick: vm.modelDelete,
            disabled: vm.hasSelection()
          }, "Delete"),
          m("input", {
            type: "search",
            value: "Search",
            style: {
              color: "LightGrey",
              fontStyle: "italic"
            }
          }),
        ]),
        m("div", {
          style: {
            overflow: "auto"
          },
          config: function (e) {
            var tb = document.getElementById("toolbar");

            // Set fields table to scroll and toolbar to stay put
            document.documentElement.style.overflow = 'hidden';
            e.style.maxHeight = (window.innerHeight - tb.clientHeight) + "px";
          }
        }, [
          m("table", [
            (function () {
              var tds = vm.attrs.map(function (key) {
                  return m("td", key.toProperCase(true));
                });
              return m("tr", {style: {backgroundColor: "LightGrey"}}, tds);
            }()),
            vm.models().map(function (model) {
              var d = model.data,
                tds = vm.attrs.map(function (col) {
                  var value = d[col](),
                    hasLocale = value !== null &&
                      typeof value.toLocaleString === "function";
                  return m("td", hasLocale ? value.toLocaleString() : value);
                });
              return m("tr", {
                onclick: vm.toggleSelection.bind(this, model),
                ondblclick: vm.toggleOpen.bind(this, model),
                style: {
                  backgroundColor: vm.isSelected(model) ?
                      "LightBlue" : "White"
                }
              }, tds);
            })
          ])
        ])
      ]);
    };

    return component;
  };

}(f));


{'fraction_non_alphanumeric': 0.1306088055614072, 'fraction_numerical': 0.0010532968190436064, 'mean_word_length': 1.6113861386138615, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5303787', 'n_tokens_mistral': 2559, 'n_tokens_neox': 2503, 'n_words': 671}