Skip to content

Commit

Permalink
Clone a grid
Browse files Browse the repository at this point in the history
#CTCTOWALTZ-2626
finos#6368
  • Loading branch information
jessica-woodland-scott-db committed Jan 24, 2023
1 parent aee9e97 commit e3d6f4c
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<script>
import _ from "lodash";
export let grid;
export let doClone;
export let doCancel;
const workingCopy = {
name: null,
description: null,
}
</script>


<h4>Cloning report grid: {grid.definition.name}</h4>
<ul>
<li>Please provide a name for the new grid</li>
<li>All columns will be copied to the newly created grid</li>
<li>You will be an owner of the new grid, able to edit columns and members</li>
</ul>
<br>
<div class="form-group">
<label for="title">Title</label>
<input class="form-control"
id="title"
placeholder="Grid Name"
bind:value={workingCopy.name}>
</div>

<div class="form-group">
<label for="description">Description</label>
<textarea class="form-control"
id="description"
bind:value={workingCopy.description}/>
</div>

<button class="btn-success btn-sm"
disabled={_.isNil(workingCopy.name)}
on:click={() => doClone(grid.definition.id, workingCopy)}>
Clone
</button>
<button class="btn-primary btn btn-sm"
on:click={doCancel}>
Cancel
</button>
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import {ownedReportIds, selectedGrid} from "./report-grid-store";
import {reportGridKinds} from "./report-grid-utils";
import ReportGridEditor from "./ReportGridEditor.svelte";
import ReportGridCloneConfirmation from "./ReportGridCloneConfirmation.svelte";
import {reportGridMemberStore} from "../../../svelte-stores/report-grid-member-store";
import {reportGridStore} from "../../../svelte-stores/report-grid-store";
import toasts from "../../../svelte-stores/toast-store";
Expand All @@ -19,7 +20,8 @@
const Modes = {
VIEW: "VIEW",
EDIT: "EDIT",
REMOVE: "REMOVE"
REMOVE: "REMOVE",
CLONE: "CLONE"
};
let activeMode = Modes.VIEW;
Expand Down Expand Up @@ -76,7 +78,19 @@
.catch(e => toasts.error("Could not update grid. " + e.error));
}
function remove(grid){
function clone(gridId, cloneCmd) {
let savePromise = reportGridStore.clone(gridId, cloneCmd);
Promise.resolve(savePromise)
.then(r => {
toasts.success("Grid cloned successfully")
const grid = r.data;
selectGrid(grid);
reportGridCall = reportGridStore.findForUser(true);
})
.catch(e => toasts.error("Could not clone grid. " + e.error));
}
function remove(grid) {
let rmPromise = reportGridStore.remove(grid.id);
Promise.resolve(rmPromise)
Expand Down Expand Up @@ -141,6 +155,10 @@
<ReportGridEditor grid={$selectedGrid?.definition}
doSave={saveReportGrid}
doCancel={cancel}/>
{:else if activeMode === Modes.CLONE}
<ReportGridCloneConfirmation grid={$selectedGrid}
doClone={clone}
doCancel={cancel}/>
{:else if activeMode === Modes.VIEW || activeMode === Modes.REMOVE}
{#if $selectedGrid?.definition?.id}
<h4 title="Click to open in dedicated view">
Expand Down Expand Up @@ -235,20 +253,34 @@
{#if activeMode === Modes.VIEW}
<button class="btn btn-sm btn-primary"
on:click={() => activeMode = Modes.EDIT}>
<Icon name="pencil"/>Edit Grid Overview
<Icon name="pencil"/>
Edit Grid Overview
</button>
<button class="btn btn-sm btn-primary"
on:click={() => activeMode = Modes.CLONE}>
<Icon name="clone"/>
Clone Grid
</button>
<button class="btn btn-sm btn-danger"
on:click={() => activeMode = Modes.REMOVE}>
<Icon name="trash"/>Delete Grid
<Icon name="trash"/>
Delete Grid
</button>
<div class="help-block small">
<Icon name="info-circle"/>To edit the columns for the grid use the 'Column Editor' tab above.
<Icon name="info-circle"/>
To edit the columns for the grid use the 'Column Editor' tab above.
</div>
{/if}
{:else}
<div class="help-block small">
<Icon name="info-circle"/>You cannot edit this grid as you are not an owner.
<Icon name="info-circle"/>
You cannot edit this grid as you are not an owner.
</div>
<button class="btn btn-sm btn-primary"
on:click={() => activeMode = Modes.CLONE}>
<Icon name="clone"/>
Clone Grid
</button>
{/if}
{:else}
<NoData>Waiting for grid selection</NoData>
Expand Down
7 changes: 6 additions & 1 deletion waltz-ng/client/svelte-stores/report-grid-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ export function mkReportGridStore() {
return remote.execute("DELETE", `api/report-grid/id/${id}`);
};

const clone = (id, cloneCmd) => {
return remote.execute("POST", `api/report-grid/id/${id}/clone`, cloneCmd);
};


return {
findAll,
Expand All @@ -60,7 +64,8 @@ export function mkReportGridStore() {
updateColumnDefinitions,
create,
update,
remove
remove,
clone
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,4 +283,26 @@ public Set<AdditionalColumnOptions> findAdditionalColumnOptionsForKind(EntityKin
public ReportGridDefinition getGridDefinitionByExtId(String gridExtId) {
return reportGridDao.getGridDefinitionByExternalId(gridExtId);
}

public ReportGridDefinition clone(long id, ReportGridUpdateCommand updateCommand, String username) {

ReportGridDefinition gridToClone = reportGridDao.getGridDefinitionById(id);

ImmutableReportGridCreateCommand newGridCreateCommand = ImmutableReportGridCreateCommand.builder()
.name(updateCommand.name())
.description(updateCommand.description())
.subjectKind(gridToClone.subjectKind())
.build();

ReportGridDefinition newGrid = create(newGridCreateCommand, username);

ImmutableReportGridColumnDefinitionsUpdateCommand updateColsCmd = ImmutableReportGridColumnDefinitionsUpdateCommand.builder()
.fixedColumnDefinitions(gridToClone.fixedColumnDefinitions())
.derivedColumnDefinitions(gridToClone.derivedColumnDefinitions())
.build();

reportGridDao.updateColumnDefinitions(newGrid.id().get(), updateColsCmd);

return newGrid;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public void register() {
String createPath = mkPath(BASE_URL, "create");
String updatePath = mkPath(BASE_URL, "id", ":id", "update");
String removalPath = mkPath(BASE_URL, "id", ":id");
String clonePath = mkPath(BASE_URL, "id", ":id", "clone");
String findForOwnerPath = mkPath(BASE_URL, "owner");
String getViewByIdPath = mkPath(BASE_URL, "view", "id", ":id");
String getDefinitionByIdPath = mkPath(BASE_URL, "definition", "id", ":id");
Expand All @@ -70,6 +71,7 @@ public void register() {
postForDatum(updateColumnDefsPath, this::updateColumnDefsRoute);
postForDatum(createPath, this::createRoute);
postForDatum(updatePath, this::updateRoute);
postForDatum(clonePath, this::cloneRoute);
deleteForDatum(removalPath, this::removalRoute);
}

Expand Down Expand Up @@ -118,6 +120,12 @@ public ReportGridDefinition updateRoute(Request req,
update(getId(req), readBody(req, ReportGridUpdateCommand.class), getUsername(req));
}

public ReportGridDefinition cloneRoute(Request req,
Response resp) throws IOException, InsufficientPrivelegeException {
return reportGridService
.clone(getId(req), readBody(req, ReportGridUpdateCommand.class), getUsername(req));
}


public Set<ReportGridDefinition> findForOwnerRoute(Request req,
Response resp) {
Expand Down

0 comments on commit e3d6f4c

Please sign in to comment.