JSFiddle - React, Tailwind, and code Playground

HTML

<body ng-app>
    <div ng-controller="Ctrl">
      <ul>
        <li>
            <input type="checkbox" value="allChecks.id" ng-model="allChecks.isChecked" ng-change="checkChange(allChecks)" />
          <label>{{allChecks.id}}</label>
        </li>
        <li ng-repeat="child in allChecks.children">
            <input type="checkbox" ng-model="child.isChecked" ng-change="checkChange(child)" />
          <label>{{child.id}}</label>
          <ul>
            <li ng-repeat="grandchild in child.children">
                <input type="checkbox" ng-model="grandchild.isChecked" ng-change="checkChange(grandchild)" />
              <label>{{grandchild.id}}</label>
              <ul>
                <li ng-repeat="grandgrandchild in grandchild.children">
                    <input type="checkbox" ng-model="grandgrandchild.isChecked" ng-change="checkChange(grandgrandchild)" />
                  <label>{{grandgrandchild.id}}</label>
                </li>
              </ul>
            </li>
          </ul>
        </li>
      </ul>
    </div>
  </body>

JavaScript

function Ctrl($scope) { 
  function Node(id, isChecked, parent) {
    this.id = id;
    this.isChecked = isChecked;
    this.parent = parent;
    this.children = [];
  }
  
  var parent = new Node('ALL', true, "");
  
  var child1 = new Node('Group1', true, parent);
  
 
  var gchild1 = new Node('Host1', true, child1);
  child1.children.push(gchild1);
  
  var ggchild111 = new Node('Node 1', true, gchild1);
  var ggchild222 = new Node('Node 2', true, gchild1);
  var ggchild333 = new Node('Node 3', true, gchild1);
  gchild1.children.push(ggchild111, ggchild222, ggchild333);
 
	 var child2 = new Node('Group2', true, parent);
  var gchild2 = new Node('Host1', true, child1);
 
  var gchild3 = new Node('Host2', true, child2);
  
   var ggchild11 = new Node('Node 1', true, gchild3);
  var ggchild22 = new Node('Node 2', true, gchild3);
  var ggchild33 = new Node('Node 3', true, gchild3);
  
  
  var ggchild1 = new Node('Node 1', true, gchild2);
  var ggchild2 = new Node('Node 2', true, gchild2);
  var ggchild3 = new Node('Node 3', true, gchild2);
  
  gchild2.children.push(ggchild1, ggchild2, ggchild3);
  gchild3.children.push(ggchild11, ggchild22, ggchild33);
  
  child2.children.push(gchild3, gchild2);
  parent.children.push(child1, child2);
  $scope.allChecks = parent;
  
  function parentCheckChange(item) {
    for (var i in item.children) {
      item.children[i].isChecked = item.isChecked;
      if (item.children[i].children) {
        parentCheckChange(item.children[i]);
      }
    }
  }
  
  function childCheckChange(parent) {
    var allChecks = true;
    for (var i in parent.children) {
      if (!parent.children[i].isChecked) {
        allChecks = false;
        break;
      }
    }
    if (allChecks) {
      parent.isChecked = true;
    }
    else {
      parent.isChecked = false;
    }
    if (parent.parent) {
      childCheckChange(parent.parent);
    }
  }
  
  $scope.checkChange = function(item) {
    // We're handling the ALL checkbox here
    if...