@@ -4,6 +4,7 @@ import bubble.model.account.Account; | |||||
import bubble.model.app.AppData; | import bubble.model.app.AppData; | ||||
import bubble.model.app.BubbleApp; | import bubble.model.app.BubbleApp; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.cobbzilla.util.collection.SingletonList; | |||||
import org.hibernate.criterion.Criterion; | import org.hibernate.criterion.Criterion; | ||||
import org.hibernate.criterion.Order; | import org.hibernate.criterion.Order; | ||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
@@ -77,6 +78,10 @@ public class AppDataDAO extends AppTemplateEntityDAO<AppData> { | |||||
} | } | ||||
public List<AppData> findByExample(Account account, AppData basis, String key) { | public List<AppData> findByExample(Account account, AppData basis, String key) { | ||||
// try by uuid first | |||||
final AppData byUuid = findByAccountAndId(account.getUuid(), key); | |||||
if (byUuid != null) return new SingletonList<>(byUuid); | |||||
final List<Criterion> crits = new ArrayList<>(); | final List<Criterion> crits = new ArrayList<>(); | ||||
if (account != null) crits.add(eq("account", account.getUuid())); | if (account != null) crits.add(eq("account", account.getUuid())); | ||||
if (basis.hasApp()) crits.add(eq("app", basis.getApp())); | if (basis.hasApp()) crits.add(eq("app", basis.getApp())); | ||||
@@ -5,8 +5,14 @@ import bubble.model.device.Device; | |||||
import org.cobbzilla.wizard.dao.SearchResults; | import org.cobbzilla.wizard.dao.SearchResults; | ||||
import org.cobbzilla.wizard.model.search.SearchQuery; | import org.cobbzilla.wizard.model.search.SearchQuery; | ||||
import static org.cobbzilla.wizard.resources.ResourceUtil.invalidEx; | |||||
public interface AppDataDriver { | public interface AppDataDriver { | ||||
SearchResults query(Account caller, Device device, BubbleApp app, AppSite site, AppDataView view, SearchQuery query); | SearchResults query(Account caller, Device device, BubbleApp app, AppSite site, AppDataView view, SearchQuery query); | ||||
default void takeAction(String id, String action) { | |||||
throw invalidEx("err.data.action.notSupported", "Action is not supported", action); | |||||
} | |||||
} | } |
@@ -3,24 +3,33 @@ package bubble.resources.app; | |||||
import bubble.model.account.Account; | import bubble.model.account.Account; | ||||
import bubble.model.app.AppData; | import bubble.model.app.AppData; | ||||
import bubble.model.app.BubbleApp; | import bubble.model.app.BubbleApp; | ||||
import org.cobbzilla.util.collection.SingletonList; | |||||
import org.glassfish.jersey.server.ContainerRequest; | import org.glassfish.jersey.server.ContainerRequest; | ||||
import javax.ws.rs.core.Context; | import javax.ws.rs.core.Context; | ||||
import javax.ws.rs.core.Response; | import javax.ws.rs.core.Response; | ||||
import java.util.List; | import java.util.List; | ||||
import static org.cobbzilla.wizard.resources.ResourceUtil.*; | |||||
import static org.cobbzilla.wizard.resources.ResourceUtil.forbidden; | |||||
import static org.cobbzilla.wizard.resources.ResourceUtil.ok; | |||||
public class AppDataResource extends DataResourceBase { | public class AppDataResource extends DataResourceBase { | ||||
public AppDataResource(Account account, BubbleApp app) { | public AppDataResource(Account account, BubbleApp app) { | ||||
super(account, new AppData().setAccount(account.getUuid()).setApp(app.getUuid())); | |||||
super(account, app, new AppData().setAccount(account.getUuid()).setApp(app.getUuid())); | |||||
} | } | ||||
public Response delete(@Context ContainerRequest ctx, String key) { | public Response delete(@Context ContainerRequest ctx, String key) { | ||||
final Account caller = checkEditable(ctx); | final Account caller = checkEditable(ctx); | ||||
final List<AppData> found = getDao().findByAccountAndAppAndAndKey(getAccountUuid(ctx), basis.getApp(), key); | |||||
// try by id first | |||||
final String accountUuid = getAccountUuid(ctx); | |||||
final AppData byUuid = getDao().findByAccountAndId(accountUuid, key); | |||||
final List<AppData> found; | |||||
if (byUuid != null) { | |||||
found = new SingletonList<>(byUuid); | |||||
} else { | |||||
found = getDao().findByAccountAndAppAndAndKey(accountUuid, basis.getApp(), key); | |||||
} | |||||
for (AppData d : found) { | for (AppData d : found) { | ||||
if (!canDelete(ctx, caller, d)) return forbidden(); | if (!canDelete(ctx, caller, d)) return forbidden(); | ||||
} | } | ||||
@@ -8,7 +8,7 @@ import bubble.model.app.BubbleApp; | |||||
public class AppSiteDataResource extends DataResourceBase { | public class AppSiteDataResource extends DataResourceBase { | ||||
public AppSiteDataResource(Account account, BubbleApp app, AppSite site) { | public AppSiteDataResource(Account account, BubbleApp app, AppSite site) { | ||||
super(account, new AppData() | |||||
super(account, app, new AppData() | |||||
.setApp(app.getUuid()) | .setApp(app.getUuid()) | ||||
.setSite(site.getUuid()) | .setSite(site.getUuid()) | ||||
.setAccount(account == null ? null : account.getUuid())); | .setAccount(account == null ? null : account.getUuid())); | ||||
@@ -22,8 +22,7 @@ import javax.ws.rs.core.Context; | |||||
import javax.ws.rs.core.Response; | import javax.ws.rs.core.Response; | ||||
import java.util.List; | import java.util.List; | ||||
import static bubble.ApiConstants.EP_DISABLE; | |||||
import static bubble.ApiConstants.EP_ENABLE; | |||||
import static bubble.ApiConstants.*; | |||||
import static org.cobbzilla.util.reflect.ReflectionUtil.copy; | import static org.cobbzilla.util.reflect.ReflectionUtil.copy; | ||||
import static org.cobbzilla.wizard.resources.ResourceUtil.*; | import static org.cobbzilla.wizard.resources.ResourceUtil.*; | ||||
@@ -41,10 +40,12 @@ public abstract class DataResourceBase extends AccountOwnedTemplateResource<AppD | |||||
@Autowired protected AppMatcherDAO matcherDAO; | @Autowired protected AppMatcherDAO matcherDAO; | ||||
@Autowired protected AppSiteDAO siteDAO; | @Autowired protected AppSiteDAO siteDAO; | ||||
protected BubbleApp app; | |||||
protected AppData basis; | protected AppData basis; | ||||
public DataResourceBase (Account account, AppData basis) { | |||||
public DataResourceBase (Account account, BubbleApp app, AppData basis) { | |||||
super(account); | super(account); | ||||
this.app = app; | |||||
this.basis = basis; | this.basis = basis; | ||||
} | } | ||||
@@ -80,6 +81,21 @@ public abstract class DataResourceBase extends AccountOwnedTemplateResource<AppD | |||||
return ok(found); | return ok(found); | ||||
} | } | ||||
@POST @Path("/{id}"+EP_ACTIONS+"/{action}") | |||||
public Response takeAction(@Context ContainerRequest ctx, | |||||
@PathParam("id") String id, | |||||
@PathParam("action") String action) { | |||||
if (isReadOnly(ctx)) return forbidden(); | |||||
switch (action) { | |||||
case "enable": return enable(ctx, id); | |||||
case "disable": return disable(ctx, id); | |||||
case "delete": return delete(ctx, id); | |||||
default: | |||||
app.getDataConfig().getDriver(configuration).takeAction(id, action); | |||||
return ok(); | |||||
} | |||||
} | |||||
@Override protected AppData setReferences(ContainerRequest ctx, Account caller, AppData request) { | @Override protected AppData setReferences(ContainerRequest ctx, Account caller, AppData request) { | ||||
copy(request, basis, BASIS_FIELDS); | copy(request, basis, BASIS_FIELDS); | ||||
@@ -405,6 +405,7 @@ button_label_app_data_delete_icon=fa fa-trash | |||||
message_app_data_previous_page=<< previous page << | message_app_data_previous_page=<< previous page << | ||||
message_app_data_next_page=>> next page >> | message_app_data_next_page=>> next page >> | ||||
message_data_results={{appData.totalCount}} total records, showing page {{query.pageNumber}} of {{numPages}} | message_data_results={{appData.totalCount}} total records, showing page {{query.pageNumber}} of {{numPages}} | ||||
message_data_actions=Actions | |||||
message_no_data=No Data | message_no_data=No Data | ||||
# AppSite | # AppSite | ||||
@@ -10,8 +10,8 @@ | |||||
{"name": "key"}, {"name": "enabled"}, {"name": "ctime"} | {"name": "key"}, {"name": "enabled"}, {"name": "ctime"} | ||||
], | ], | ||||
"actions": [ | "actions": [ | ||||
{"name": "enable", "when": "!data.enabled()"}, | |||||
{"name": "disable", "when": "data.enabled()"}, | |||||
{"name": "enable", "when": "!data.enabled"}, | |||||
{"name": "disable", "when": "data.enabled"}, | |||||
{"name": "delete"} | {"name": "delete"} | ||||
], | ], | ||||
"views": [ | "views": [ | ||||
@@ -1 +1 @@ | |||||
Subproject commit 7f057c060912e80c4fa78e3ace494fec82e050f6 | |||||
Subproject commit 37f50c4764bfa243aaa26b80a1772574e29679e2 |