var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.menu = {
    sections: [{
      name: "NEW SECTION 1",
      sections: [{
        name: "NEW SECTION",
        sections: [],
        products: [{
          "name": "Product",
          "price": "0.00"
        }]
      }],
      products: []
    }]
  };

  $scope.addSection = function() {
    $scope.menu.sections.push({
      name: "NEW SECTION",
      sections: [],
      products: []
    });
  };
});

app
  .directive('adminSections', function() {
    return {
      restrict: "E",
      replace: true,
      scope: {
        sections: '='
      },
      templateUrl: 'sections.html'
    };
  })
  .directive('adminSection', function($compile) {
    return {
      restrict: "E",
      replace: true,
      scope: {
        section: '='
      },
      templateUrl: 'section.html',

      link: function(scope, element, attrs, controller) {
        if (angular.isArray(scope.section.sections)) {
          element.append($compile('<admin-sections sections="section.sections"></admin-sections>')(scope));
        }
        if (angular.isArray(scope.section.products)) {
          element.append($compile('<admin-products products="section.products"></admin-products>')(scope));
        }

        scope.addSub = function(section) {
          section.sections.push({
            "name": "NEW SECTION",
            "sections": [],
            "products": []
          });
        };

        scope.addProduct = function(section) {
          section.products.push({
            "name": "Product",
            "price": "0.00"
          });
        };

        scope.deleteSection = function(section) {
          var idx = scope.$parent.sections.indexOf(section);
          scope.$parent.sections.splice(idx, 1);
        };
      }
    };
  })
  .directive('adminProducts', function() {
    return {
      restrict: "E",
      replace: true,
      scope: {
        products: '='
      },
      templateUrl: 'products.html',
      link: function(scope, element, attrs, controller) {
        scope.editProduct = function(product) {
          if (product.price === undefined) {
            product.price = 0;
          }
          element.append($compile('<productform product="product"></productform>')(scope));
        };

        scope.deleteProduct = function(idx) {
          if (confirm('Are you sure you want to delete this product?\n\nClick OK to confirm.')) {
            scope.products.splice(idx, 1);
          }
        };
      }
    };
  })
  .directive('adminProduct', function($compile) {
    return {
      restrict: "E",
      replace: true,
      scope: {
        product: '='
      },
      templateUrl: 'product.html',
      link: function(scope, element, attr, controller) {

        scope.editProduct = function(product) {
          if (product.price === undefined) {
            product.price = 0;
          }
          element.append($compile('<productform product="product" />')(scope));
        };

        scope.deleteProduct = function(idx) {
          scope.$parent.deleteProduct(idx);
        };
      }
    };
  })
  .directive('productform', function($compile) {
    return {
      restrict: "E",
      replace: true,
      scope: {
        product: "="
      },
      templateUrl: 'productform.html',
      link: function(scope, element, attrs, controller) {
        scope.orig = angular.copy(scope.product);
        scope.ok = function() {
          element.remove();
          scope.$parent.editMode = false;
        };

        scope.cancel = function() {
          scope.reset();
          element.remove();
          scope.$parent.editMode = false;
        }

        scope.reset = function() {
          scope.product = angular.copy(scope.orig);
        }
      }
    };
  });
<!DOCTYPE html>
<html ng-app="plunker">

<head>
  <meta charset="utf-8" />
  <title>AngularJS Plunker</title>
  <script>
    document.write('<base href="' + document.location + '" />');
  </script>
  <link rel="stylesheet" href="style.css" />
  <script data-require="angular.js@1.3.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.7/angular.js" data-semver="1.3.7"></script>
  <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl">
  <h1>Menu</h1>
  <button ng-click="addSection()">Add</button>
  <admin-sections sections="menu.sections"></admin-sections>
</body>

</html>
/* Put your css in here */
<li class="list-group-item section" ng-class="{'active':expanded}" ng-init="expanded=false;editMode=false;" ng-click="$event.stopPropagation();">
  <div ng-click="expanded=!expanded;">
    <i class="glyphicon" ng-class="{'glyphicon-chevron-right':!expanded, 'glyphicon-chevron-down':expanded}"></i>
    <span ng-hide="editMode">
      {{section.name}}
      <div class="controls" ng-click="$event.stopPropagation();">
        <button class="btn btn-xs btn-default" ng-click="editMode=true;">Edit</button>
        <button class="btn btn-xs btn-default" ng-show="section.sections.length + section.products.length == 0;" ng-click="deleteSection(section);">Remove</button>
      </div>
    </span>
    <span ng-show="editMode" ng-click="$event.stopPropagation();">
      <input type="text" ng-model="section.name"/>
      <button class="btn btn-xs btn-default" ng-click="editMode=false;">Done</button>
    </span>

    <div class="tools pull-right" ng-mouseenter="showControls=true;" ng-mouseleave="showControls=false;"
         ng-init="showControls=false;" ng-click="$event.stopPropagation();">
      Add To Section
      <div ng-show="showControls" ng-click="expanded=true;">
        <button class="btn btn-xs btn-default" ng-click="addSub(section);">SubSection</button>
        <button class="btn btn-xs btn-default" ng-click="addProduct(section);">Product</button>
      </div>
    </div>
  </div>
</li>
<ul class="list-group">
  <admin-section ng-repeat="section in sections" section="section"></admin-section>
</ul>
<ul class="list-group">
  <admin-product ng-repeat="product in products" product="product"></admin-product>
</ul>
<li class="list-group-item product" ng-init="expanded=false;">
  <div ng-click="expanded=!expanded; $event.stopPropagation();">
    <span>{{product.name}} - {{product.price}}</span>
    <button ng-hide="editMode" ng-click="deleteProduct($parent.$index);">Delete</button>
  </div>
</li>
<div>
  <div class="modal-header">
    <input type="text" ng-model="product.name" />
    <input type="text" ng-model="product.price" />
  </div>
  <div class="modal-footer">
    <button class="btn btn-primary" ng-click="ok()">OK</button>
    <button class="btn btn-primary" ng-click="reset()">Reset</button>
    <button class="btn btn-warning" ng-click="cancel()">Cancel</button>
  </div>
</div>