JSFiddle - React, Tailwind, and code Playground

HTML

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.min.js"></script>
<div ng-controller="Test" sortable>
    <div ng-repeat="item in data().paragraphs" class="box slide_content" id="{{$index}}"> 
        {{item.content}}, ID: {{$index}}
    </div>
    
    <input type="button" ng-click="add()" value="Add">
</div>

CSS

.box {
    width: 200px;
    height: 20px;
    border: solid black 1px;
    margin-top: 5px;
}

JavaScript

var App = angular.module("MyApp", []);

App.controller("Test", function($scope, StorageService) {
    StorageService.set({
        paragraphs: [
            {content: "content one"},
            {content: "cnt two"},
            {content: "random three"},
            {content: "last one yeeaah"}
        ]
    });
    
    $scope.data = StorageService.get;
    
    $scope.add = StorageService.add;
});

App.directive("sortable", function(StorageService) {
	return {
		link: function(scope, element, attrs) {
			$(element[0]).sortable({
				cancel: ".disabled",
				items: "> .slide_content:not(.disabled)",
				start: function(e, t) {
					t.item.data("start_pos", t.item.index());
				},
				stop: function(e, t) {
					var r = t.item.data("start_pos");
					if (r != t.item.index()) {
						            StorageService.sort($(this).sortable("toArray"));
					}
				}
			});
		}
	};
});

App.factory('StorageService', function() {
	var output = {};

	return {
		set: function(data) {
			angular.copy(data, output);
			return output;
		},
		get: function() {
			return output;
		},
		remove: function(id) {
			output.paragraphs.splice(id, 1);
		},
		add: function() {
			output.paragraphs.push({
				content: 'Content'
			});
		},
		sort: function(order) {
			var localOutput = [];

			for (var j in order) {
				var id = parseInt(order[j]);
				localOutput.push(output.paragraphs[id]);
			}
            
            console.log('new order', localOutput);

			output.paragraphs = localOutput;
			return output;
		}
	};
});