This commit is contained in:
parent
7e7f6ff746
commit
d5fb85d933
|
@ -3,30 +3,23 @@ package eu.dnetlib.is.resources;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.PutMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import eu.dnetlib.is.resource.model.SimpleResource;
|
import eu.dnetlib.is.resource.model.SimpleResource;
|
||||||
import eu.dnetlib.is.resource.repository.SimpleResourceRepository;
|
|
||||||
import eu.dnetlib.is.util.DatabaseUtils;
|
|
||||||
import eu.dnetlib.is.util.InformationServiceException;
|
import eu.dnetlib.is.util.InformationServiceException;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
|
@ -34,19 +27,11 @@ import eu.dnetlib.is.util.InformationServiceException;
|
||||||
public class ResourcesRestController {
|
public class ResourcesRestController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SimpleResourceRepository simpleResourceRepository;
|
private SimpleResourceService service;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private DatabaseUtils databaseUtils;
|
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(ResourcesRestController.class);
|
|
||||||
|
|
||||||
@GetMapping("/")
|
@GetMapping("/")
|
||||||
public List<SimpleResource> listResources(@RequestParam final String type) {
|
public List<SimpleResource> listResources(@RequestParam final String type) {
|
||||||
return simpleResourceRepository.findByType(type)
|
return service.listResources(type);
|
||||||
.stream()
|
|
||||||
.sorted((r1, r2) -> StringUtils.compareIgnoreCase(r1.getName(), r2.getName()))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/")
|
@PostMapping("/")
|
||||||
|
@ -57,24 +42,23 @@ public class ResourcesRestController {
|
||||||
@RequestParam final String content)
|
@RequestParam final String content)
|
||||||
throws InformationServiceException {
|
throws InformationServiceException {
|
||||||
|
|
||||||
return databaseUtils.saveNewResource(name, type, description, ctype, content);
|
return service.saveNewResource(name, type, description, ctype, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping("/{id}")
|
@DeleteMapping("/{id}")
|
||||||
public void deleteResource(@PathVariable final String id) {
|
public void deleteResource(@PathVariable final String id) {
|
||||||
log.info("Deleting resource: " + id);
|
service.deleteResource(id);
|
||||||
simpleResourceRepository.deleteById(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/{id}/metadata")
|
@GetMapping("/{id}/metadata")
|
||||||
public SimpleResource getMetadata(@PathVariable final String id) throws InformationServiceException {
|
public SimpleResource getMetadata(@PathVariable final String id) throws InformationServiceException {
|
||||||
return simpleResourceRepository.findById(id).orElseThrow(() -> new InformationServiceException("Id not found"));
|
return service.getMetadata(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/{id}/content")
|
@GetMapping("/{id}/content")
|
||||||
public void getContent(@PathVariable final String id, final HttpServletResponse res) throws InformationServiceException {
|
public void getContent(@PathVariable final String id, final HttpServletResponse res) throws InformationServiceException {
|
||||||
final String ctype = simpleResourceRepository.findContentTypeById(id).orElseThrow(() -> new InformationServiceException("Id not found"));
|
final String ctype = service.getContentType(id);
|
||||||
final String content = simpleResourceRepository.findContentById(id).orElseThrow(() -> new InformationServiceException("Id not found"));
|
final String content = service.getContent(id);
|
||||||
|
|
||||||
res.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
res.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||||
res.setContentType(ctype);
|
res.setContentType(ctype);
|
||||||
|
@ -87,36 +71,24 @@ public class ResourcesRestController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/{id}/metadata")
|
@PostMapping("/{id}/metadata")
|
||||||
public void saveMetadata(@RequestBody final SimpleResource r) throws InformationServiceException {
|
public void saveMetadata(@PathVariable final String id, @RequestBody final SimpleResource r) throws InformationServiceException {
|
||||||
if (simpleResourceRepository.existsById(r.getId())) {
|
service.saveMetadata(id, r);
|
||||||
simpleResourceRepository.save(r);
|
|
||||||
} else {
|
|
||||||
throw new InformationServiceException("Resource not found");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/{id}/content")
|
@PostMapping("/{id}/content")
|
||||||
public void saveContent(@PathVariable final String id, @RequestParam final String content) throws InformationServiceException {
|
public void saveContent(@PathVariable final String id, @RequestParam final String content) throws InformationServiceException {
|
||||||
if (simpleResourceRepository.existsById(id)) {
|
service.saveContent(id, content);
|
||||||
simpleResourceRepository.setContentById(id, content);
|
|
||||||
} else {
|
|
||||||
throw new InformationServiceException("Resource not found");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping(value = "/{id}/content", consumes = {
|
@PostMapping(value = "/{id}/file", consumes = {
|
||||||
MediaType.TEXT_PLAIN_VALUE, MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE
|
MediaType.TEXT_PLAIN_VALUE, MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE
|
||||||
})
|
})
|
||||||
public void uploadContent(@PathVariable final String id, final HttpServletRequest request) throws InformationServiceException {
|
public void uploadContent(@PathVariable final String id, final HttpServletRequest request) throws InformationServiceException {
|
||||||
if (simpleResourceRepository.existsById(id)) {
|
try {
|
||||||
try {
|
final String content = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
|
||||||
final String content = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
|
service.saveContent(id, content);
|
||||||
simpleResourceRepository.setContentById(id, content);
|
} catch (final IOException e) {
|
||||||
} catch (final Exception e) {
|
throw new InformationServiceException("Error processing input file", e);
|
||||||
throw new InformationServiceException("Error processing file", e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new InformationServiceException("Resource not found");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
package eu.dnetlib.is.resources;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
|
||||||
|
import eu.dnetlib.is.resource.model.SimpleResource;
|
||||||
|
import eu.dnetlib.is.resource.repository.SimpleResourceRepository;
|
||||||
|
import eu.dnetlib.is.util.InformationServiceException;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SimpleResourceService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SimpleResourceRepository simpleResourceRepository;
|
||||||
|
|
||||||
|
private static final Log log = LogFactory.getLog(SimpleResourceService.class);
|
||||||
|
|
||||||
|
public SimpleResource getMetadata(final String id) throws InformationServiceException {
|
||||||
|
return simpleResourceRepository.findById(id).orElseThrow(() -> new InformationServiceException("Id not found"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContent(final String id) throws InformationServiceException {
|
||||||
|
return simpleResourceRepository.findContentById(id).orElseThrow(() -> new InformationServiceException("Id not found"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContentType(final String id) throws InformationServiceException {
|
||||||
|
return simpleResourceRepository.findContentTypeById(id).orElseThrow(() -> new InformationServiceException("Id not found"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SimpleResource> listResources(final String type) {
|
||||||
|
return simpleResourceRepository.findByType(type)
|
||||||
|
.stream()
|
||||||
|
.sorted((r1, r2) -> StringUtils.compareIgnoreCase(r1.getName(), r2.getName()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteResource(@PathVariable final String id) {
|
||||||
|
log.info("Deleting resource: " + id);
|
||||||
|
simpleResourceRepository.deleteById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public SimpleResource saveNewResource(final String name,
|
||||||
|
final String type,
|
||||||
|
final String description,
|
||||||
|
final String ctype,
|
||||||
|
final String content) {
|
||||||
|
final Date now = new Date();
|
||||||
|
|
||||||
|
final SimpleResource res = new SimpleResource();
|
||||||
|
res.setId(UUID.randomUUID().toString());
|
||||||
|
res.setName(name);
|
||||||
|
res.setType(type);
|
||||||
|
res.setDescription(description);
|
||||||
|
res.setCreationDate(now);
|
||||||
|
res.setModificationDate(now);
|
||||||
|
|
||||||
|
simpleResourceRepository.save(res);
|
||||||
|
simpleResourceRepository.setContentById(res.getId(), content);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void saveMetadata(final String id, final SimpleResource r) throws InformationServiceException {
|
||||||
|
if (simpleResourceRepository.existsById(id)) {
|
||||||
|
r.setId(id);
|
||||||
|
simpleResourceRepository.save(r);
|
||||||
|
} else {
|
||||||
|
throw new InformationServiceException("Resource not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void saveContent(final String id, final String content) throws InformationServiceException {
|
||||||
|
if (simpleResourceRepository.existsById(id)) {
|
||||||
|
simpleResourceRepository.setContentById(id, content);
|
||||||
|
} else {
|
||||||
|
throw new InformationServiceException("Resource not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,41 +0,0 @@
|
||||||
package eu.dnetlib.is.util;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import javax.transaction.Transactional;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import eu.dnetlib.is.resource.model.SimpleResource;
|
|
||||||
import eu.dnetlib.is.resource.repository.SimpleResourceRepository;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class DatabaseUtils {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SimpleResourceRepository simpleResourceRepository;
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public SimpleResource saveNewResource(final String name,
|
|
||||||
final String type,
|
|
||||||
final String description,
|
|
||||||
final String ctype,
|
|
||||||
final String content) {
|
|
||||||
final Date now = new Date();
|
|
||||||
|
|
||||||
final SimpleResource res = new SimpleResource();
|
|
||||||
res.setId(UUID.randomUUID().toString());
|
|
||||||
res.setName(name);
|
|
||||||
res.setType(type);
|
|
||||||
res.setDescription(description);
|
|
||||||
res.setCreationDate(now);
|
|
||||||
res.setModificationDate(now);
|
|
||||||
|
|
||||||
simpleResourceRepository.save(res);
|
|
||||||
simpleResourceRepository.setContentById(res.getId(), content);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,7 +4,6 @@ app.controller('resourcesController', function($scope, $http) {
|
||||||
$scope.resources = [];
|
$scope.resources = [];
|
||||||
$scope.tmpRes = {};
|
$scope.tmpRes = {};
|
||||||
$scope.tmpContent = "loading...";
|
$scope.tmpContent = "loading...";
|
||||||
$scope.mode = '';
|
|
||||||
$scope.type = typeId();
|
$scope.type = typeId();
|
||||||
|
|
||||||
$scope.reload = function() {
|
$scope.reload = function() {
|
||||||
|
@ -16,7 +15,6 @@ app.controller('resourcesController', function($scope, $http) {
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.prepareNewRes = function() {
|
$scope.prepareNewRes = function() {
|
||||||
$scope.mode = 'new';
|
|
||||||
$scope.tmpRes = {
|
$scope.tmpRes = {
|
||||||
'id' : '',
|
'id' : '',
|
||||||
'name' : '',
|
'name' : '',
|
||||||
|
@ -26,7 +24,6 @@ app.controller('resourcesController', function($scope, $http) {
|
||||||
|
|
||||||
$scope.prepareEditMetadata = function(res) {
|
$scope.prepareEditMetadata = function(res) {
|
||||||
$scope.tmpRes = angular.copy(res);
|
$scope.tmpRes = angular.copy(res);
|
||||||
$scope.mode = 'edit';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.prepareEditContent = function(res) {
|
$scope.prepareEditContent = function(res) {
|
||||||
|
@ -43,22 +40,9 @@ app.controller('resourcesController', function($scope, $http) {
|
||||||
$scope.tmpRes = angular.copy(res);
|
$scope.tmpRes = angular.copy(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.saveMetadata = function(md) {
|
$scope.saveMetadata = function(id, md) {
|
||||||
if ($scope.mode == 'new') {
|
|
||||||
var found = false;
|
|
||||||
|
|
||||||
angular.forEach($scope.resources, function(r) {
|
|
||||||
if (md.id == r.id) { found = true; };
|
|
||||||
});
|
|
||||||
|
|
||||||
if (found) {
|
|
||||||
alert("Insertion failed: resource already exists !");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$http.defaults.headers.post["Content-Type"] = "application/json;charset=UTF-8";
|
$http.defaults.headers.post["Content-Type"] = "application/json;charset=UTF-8";
|
||||||
$http.post('./api/resources/?' + $.now(), md).then(function successCallback(res) {
|
$http.post('./api/resources/' + id + '/metadata?' + $.now(), md).then(function successCallback(res) {
|
||||||
alert("Resource saved");
|
alert("Resource saved");
|
||||||
$scope.reload();
|
$scope.reload();
|
||||||
}, function errorCallback(res) {
|
}, function errorCallback(res) {
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
</p>
|
</p>
|
||||||
<button type="button" class="btn btn-sm btn-primary" data-toggle="modal" data-target="#editMetadataModal" ng-click="prepareEditMetadata(r)">edit metadata</button>
|
<button type="button" class="btn btn-sm btn-primary" data-toggle="modal" data-target="#editMetadataModal" ng-click="prepareEditMetadata(r)">edit metadata</button>
|
||||||
<button type="button" class="btn btn-sm btn-primary" data-toggle="modal" data-target="#editContentModal" ng-click="prepareEditContent(r)">edit content</button>
|
<button type="button" class="btn btn-sm btn-primary" data-toggle="modal" data-target="#editContentModal" ng-click="prepareEditContent(r)">edit content</button>
|
||||||
<button type="button" class="btn btn-sm btn-primary" data-toggle="modal" data-target="#uploadContentModal" ng-click="prepareUploadContent(r)">upload content file</button>
|
|
||||||
<a href="./api/resources/{{r.id}}/content" class="btn btn-sm btn-primary" target="_blank">raw content</a>
|
<a href="./api/resources/{{r.id}}/content" class="btn btn-sm btn-primary" target="_blank">raw content</a>
|
||||||
<button type="button" class="btn btn-sm btn-danger" ng-click="deleteResource(r)">delete</button>
|
<button type="button" class="btn btn-sm btn-danger" ng-click="deleteResource(r)">delete</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -55,12 +54,11 @@
|
||||||
<h4 class="modal-title" ng-if="mode == 'edit'">Edit resource</h4>
|
<h4 class="modal-title" ng-if="mode == 'edit'">Edit resource</h4>
|
||||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<form>
|
||||||
<form>
|
<div class="modal-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>ID</label>
|
<label>ID</label>
|
||||||
<input ng-show="mode == 'new'" type="text" class="form-control" ng-model="tmpRes.id" />
|
<input type="text" readonly class="form-control-plaintext" ng-model="tmpRes.id" />
|
||||||
<input ng-show="mode == 'edit'" type="text" readonly class="form-control-plaintext" ng-model="tmpRes.id" />
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Type</label>
|
<label>Type</label>
|
||||||
|
@ -74,12 +72,12 @@
|
||||||
<label>Description</label>
|
<label>Description</label>
|
||||||
<textarea class="form-control" ng-model="tmpRes.description"></textarea>
|
<textarea class="form-control" ng-model="tmpRes.description"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
</div>
|
<div class="modal-footer">
|
||||||
<div class="modal-footer">
|
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">Close</button>
|
||||||
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">Close</button>
|
<button type="submit" class="btn btn-sm btn-primary" data-dismiss="modal" ng-click="saveMetadata(tmpRes.id, tmpRes)" ng-disabled="!tmpRes.id || !tmpRes.name">Submit</button>
|
||||||
<button type="submit" class="btn btn-sm btn-primary" data-dismiss="modal" ng-click="saveResource(tmpRes)" ng-disabled="!tmpRes.id || !tmpRes.name">Submit</button>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -91,38 +89,15 @@
|
||||||
<h4 class="modal-title">Edit content</h4>
|
<h4 class="modal-title">Edit content</h4>
|
||||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<form>
|
||||||
<form>
|
<div class="modal-body">
|
||||||
<textarea class="form-control small" ng-model="tmpContent" rows="25"></textarea>
|
<textarea class="form-control small" ng-model="tmpContent" rows="25"></textarea>
|
||||||
</form>
|
</div>
|
||||||
</div>
|
<div class="modal-footer">
|
||||||
<div class="modal-footer">
|
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">Close</button>
|
||||||
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">Close</button>
|
<button type="submit" class="btn btn-sm btn-primary" data-dismiss="modal" ng-click="saveContent(tmpRes.id, tmpContent)" ng-disabled="!tmpContent">Submit</button>
|
||||||
<button type="submit" class="btn btn-sm btn-primary" data-dismiss="modal" ng-click="saveContent(tmpRes.id, tmpContent)" ng-disabled="!tmpContent">Submit</button>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal fade" tabindex="-1" id="uploadContentModal">
|
|
||||||
<div class="modal-dialog modal-lg">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h4 class="modal-title">Upload content</h4>
|
|
||||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<form>
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Format: <i th:text="${type.contentType}"></i></label>
|
|
||||||
<input type="file" class="form-control-file" />
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">Close</button>
|
|
||||||
<button type="submit" class="btn btn-sm btn-primary" data-dismiss="modal" ng-click="saveResource(tmpRes)" ng-disabled="!tmpContent">Submit</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue