diff --git a/sdk/src/main/java/com/walmartlabs/concord/sdk/Constants.java b/sdk/src/main/java/com/walmartlabs/concord/sdk/Constants.java index bca994d61a..d32e04b710 100644 --- a/sdk/src/main/java/com/walmartlabs/concord/sdk/Constants.java +++ b/sdk/src/main/java/com/walmartlabs/concord/sdk/Constants.java @@ -615,6 +615,8 @@ public static class Multipart { public static final String SYNC = "sync"; public static final String META = "meta"; + + public static final String ORDER_ID = "orderId"; } public static class Headers { diff --git a/server/db/src/main/resources/com/walmartlabs/concord/server/db/liquibase.xml b/server/db/src/main/resources/com/walmartlabs/concord/server/db/liquibase.xml index 23dde8d830..579954483c 100644 --- a/server/db/src/main/resources/com/walmartlabs/concord/server/db/liquibase.xml +++ b/server/db/src/main/resources/com/walmartlabs/concord/server/db/liquibase.xml @@ -116,5 +116,6 @@ + diff --git a/server/db/src/main/resources/com/walmartlabs/concord/server/db/v2.22.0.xml b/server/db/src/main/resources/com/walmartlabs/concord/server/db/v2.22.0.xml new file mode 100644 index 0000000000..eef58c7715 --- /dev/null +++ b/server/db/src/main/resources/com/walmartlabs/concord/server/db/v2.22.0.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/server/impl/src/main/java/com/walmartlabs/concord/server/MultipartUtils.java b/server/impl/src/main/java/com/walmartlabs/concord/server/MultipartUtils.java index 335cc86c5e..69301bd333 100644 --- a/server/impl/src/main/java/com/walmartlabs/concord/server/MultipartUtils.java +++ b/server/impl/src/main/java/com/walmartlabs/concord/server/MultipartUtils.java @@ -174,6 +174,14 @@ public static UUID assertUuid(MultipartInput input, String key) { throw new ConcordApplicationException(key + " not specified", Response.Status.BAD_REQUEST); } + public static Integer getInt(MultipartInput input, String key) { + String s = getString(input, key); + if (s == null) { + return null; + } + return Integer.parseInt(s); + } + public static InputStream getStream(MultipartInput input, String key) { try { for (InputPart p : input.getParts()) { diff --git a/server/impl/src/main/java/com/walmartlabs/concord/server/console/ProcessCardEntry.java b/server/impl/src/main/java/com/walmartlabs/concord/server/console/ProcessCardEntry.java index a4f1092772..dc16593d76 100644 --- a/server/impl/src/main/java/com/walmartlabs/concord/server/console/ProcessCardEntry.java +++ b/server/impl/src/main/java/com/walmartlabs/concord/server/console/ProcessCardEntry.java @@ -70,6 +70,9 @@ public interface ProcessCardEntry extends Serializable { boolean isCustomForm(); + @Nullable + Integer orderId(); + static ImmutableProcessCardEntry.Builder builder() { return ImmutableProcessCardEntry.builder(); } diff --git a/server/impl/src/main/java/com/walmartlabs/concord/server/console/ProcessCardManager.java b/server/impl/src/main/java/com/walmartlabs/concord/server/console/ProcessCardManager.java index 327260033d..bf39f6e122 100644 --- a/server/impl/src/main/java/com/walmartlabs/concord/server/console/ProcessCardManager.java +++ b/server/impl/src/main/java/com/walmartlabs/concord/server/console/ProcessCardManager.java @@ -94,7 +94,7 @@ public List listUserCards(UUID userId) { return dao.listCards(userId); } - public ProcessCardOperationResponse createOrUpdate(UUID id, UUID projectId, UUID repoId, String name, Optional entryPoint, String description, InputStream icon, InputStream form, Map data) { + public ProcessCardOperationResponse createOrUpdate(UUID id, UUID projectId, UUID repoId, String name, Optional entryPoint, String description, InputStream icon, InputStream form, Map data, Integer orderId) { boolean exists; if (id == null) { if (projectId == null) { @@ -110,12 +110,12 @@ public ProcessCardOperationResponse createOrUpdate(UUID id, UUID projectId, UUID } if (!exists) { - UUID resultId = dao.insert(id, projectId, repoId, name, entryPoint.orElse(Constants.Request.DEFAULT_ENTRY_POINT_NAME), description, icon, form, data); + UUID resultId = dao.insert(id, projectId, repoId, name, entryPoint.orElse(Constants.Request.DEFAULT_ENTRY_POINT_NAME), description, icon, form, data, orderId); return new ProcessCardOperationResponse(resultId, OperationResult.CREATED); } else { assertAccess(id); - dao.update(id, projectId, repoId, name, entryPoint.orElse(null), description, icon, form, data); + dao.update(id, projectId, repoId, name, entryPoint.orElse(null), description, icon, form, data, orderId); return new ProcessCardOperationResponse(id, OperationResult.UPDATED); } } @@ -161,7 +161,7 @@ public Optional getIdByName(UUID projectId, String name) { .fetchOptional(UI_PROCESS_CARDS.UI_PROCESS_CARD_ID); } - public UUID insert(UUID cardId, UUID projectId, UUID repoId, String name, String entryPoint, String description, InputStream icon, InputStream form, Map data) { + public UUID insert(UUID cardId, UUID projectId, UUID repoId, String name, String entryPoint, String description, InputStream icon, InputStream form, Map data, Integer orderId) { return txResult(tx -> { String sql = tx.insertInto(UI_PROCESS_CARDS) .columns(UI_PROCESS_CARDS.UI_PROCESS_CARD_ID, @@ -173,8 +173,9 @@ public UUID insert(UUID cardId, UUID projectId, UUID repoId, String name, String UI_PROCESS_CARDS.ICON, UI_PROCESS_CARDS.FORM, UI_PROCESS_CARDS.DATA, - UI_PROCESS_CARDS.OWNER_ID) - .values((UUID) null, null, null, null, null, null, null, null, null, null) + UI_PROCESS_CARDS.OWNER_ID, + UI_PROCESS_CARDS.ORDER_ID) + .values((UUID) null, null, null, null, null, null, null, null, null, null, null) .returning(UI_PROCESS_CARDS.UI_PROCESS_CARD_ID) .getSQL(); @@ -190,6 +191,7 @@ public UUID insert(UUID cardId, UUID projectId, UUID repoId, String name, String ps.setBinaryStream(8, form); ps.setObject(9, data != null ? objectMapper.toJSONB(data).data() : null); ps.setObject(10, UserPrincipal.assertCurrent().getId()); + ps.setObject(11, orderId); try (ResultSet rs = ps.executeQuery()) { if (!rs.next()) { @@ -205,7 +207,7 @@ public UUID insert(UUID cardId, UUID projectId, UUID repoId, String name, String public void update(UUID cardId, UUID projectId, UUID repoId, String name, String entryPoint, String description, InputStream icon, InputStream form, - Map data) { + Map data, Integer orderId) { tx(tx -> { List params = new ArrayList<>(); UpdateSetStep q = tx.update(UI_PROCESS_CARDS); @@ -254,6 +256,11 @@ public void update(UUID cardId, UUID projectId, UUID repoId, String name, return; } + if (orderId != null) { + q.set(UI_PROCESS_CARDS.ORDER_ID, (Integer) null); + params.add(orderId); + } + String sql = q.set(UI_PROCESS_CARDS.UI_PROCESS_CARD_ID, cardId) .where(UI_PROCESS_CARDS.UI_PROCESS_CARD_ID.eq(cardId)) .getSQL(); @@ -358,7 +365,7 @@ private List listCards(DSLContext tx, UUID userId) { .where(UI_PROCESS_CARDS.UI_PROCESS_CARD_ID.in(userCardsFilter)); return query - .orderBy(UI_PROCESS_CARDS.UI_PROCESS_CARD_ID) + .orderBy(UI_PROCESS_CARDS.ORDER_ID, UI_PROCESS_CARDS.UI_PROCESS_CARD_ID) .fetch(this::toEntry); } @@ -404,7 +411,7 @@ private static Optional getInputStream(DSLContext tx, String sql, UUID ca }); } - private static SelectOnConditionStep> buildSelect(DSLContext tx) { + private static SelectOnConditionStep> buildSelect(DSLContext tx) { Field isCustomForm = when(field(UI_PROCESS_CARDS.FORM).isNotNull(), true).otherwise(false); return tx.select( @@ -419,14 +426,15 @@ private static SelectOnConditionStep r) { + private ProcessCardEntry toEntry(Record13 r) { return ProcessCardEntry.builder() .id(r.get(UI_PROCESS_CARDS.UI_PROCESS_CARD_ID)) .orgName(r.get(ORGANIZATIONS.ORG_NAME)) @@ -437,6 +445,7 @@ private ProcessCardEntry toEntry(Record12 data = r.getData(); UUID id = r.getId(); + Integer orderId = r.getOrderId(); try (InputStream icon = r.getIcon(); InputStream form = r.getForm()) { - return processCardManager.createOrUpdate(id, projectId, repoId, name, entryPoint, description, icon, form, data); + return processCardManager.createOrUpdate(id, projectId, repoId, name, entryPoint, description, icon, form, data, orderId); } }