Skip to content

Commit c955dc4

Browse files
committed
[IMP] model: improve figure export data
Currently, charts/images/carousels are exported inside `figure.data` in the JSON. That's not ideal, `figure.data` then needs to be typed as `any`, and the charts plugin need to be aware of carousels for its import. This commit changes the export, now each plugin has its own key in the data, so it can be typed correctly and they are not interlinked. Task: 5002886
1 parent 4a43861 commit c955dc4

24 files changed

+363
-412
lines changed

src/migrations/data.ts

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -272,15 +272,19 @@ function fixChartDefinitions(data: Partial<WorkbookData>, initialMessages: State
272272
const map = {};
273273
for (const sheet of data.sheets || []) {
274274
sheet.figures?.forEach((figure) => {
275-
if (figure.tag === "chart") {
276-
// chart definition
277-
if (data.version && compareVersions(String(data.version), "18.5.1") <= 0) {
278-
map[figure.data.chartId] = figure.data;
279-
} else {
280-
map[figure.id] = figure.data;
281-
}
275+
if (
276+
figure.tag === "chart" &&
277+
data.version &&
278+
compareVersions(String(data.version), "18.5.1") > 0
279+
) {
280+
map[figure.id] = (figure as any).data;
282281
}
283282
});
283+
for (const chartId in sheet.charts || {}) {
284+
if (data.version && compareVersions(String(data.version), "18.5.1") <= 0) {
285+
map[chartId] = sheet.charts[chartId].chart;
286+
}
287+
}
284288
}
285289
for (const message of initialMessages) {
286290
if (message.type === "REMOTE_REVISION") {
@@ -415,6 +419,9 @@ export function createEmptySheet(sheetId: UID, name: string): SheetData {
415419
conditionalFormats: [],
416420
dataValidationRules: [],
417421
figures: [],
422+
charts: {},
423+
carousels: {},
424+
images: {},
418425
tables: [],
419426
isVisible: true,
420427
};
@@ -438,10 +445,27 @@ export function createEmptyWorkbookData(sheetName = "Sheet1"): WorkbookData {
438445

439446
export function createEmptyExcelSheet(sheetId: UID, name: string): ExcelSheetData {
440447
return {
441-
...(createEmptySheet(sheetId, name) as Omit<ExcelSheetData, "charts">),
442-
charts: [],
443-
images: [],
448+
id: sheetId,
449+
name,
450+
colNumber: 26,
451+
rowNumber: 100,
452+
cells: {},
453+
styles: {},
454+
formats: {},
455+
borders: {},
456+
cols: {},
457+
rows: {},
458+
merges: [],
459+
conditionalFormats: [],
460+
dataValidationRules: [],
461+
figures: [],
462+
charts: {},
463+
carousels: {},
464+
tables: [],
465+
isVisible: true,
466+
images: {},
444467
cellValues: {},
468+
formulaSpillRanges: {},
445469
};
446470
}
447471

src/migrations/migration_steps.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ migrationStepRegistry
372372
})
373373
.add("18.0.4", {
374374
// "Add operator in gauge inflection points",
375-
migrate(data: WorkbookData): any {
375+
migrate(data: any): any {
376376
for (const sheet of data.sheets || []) {
377377
for (const figure of sheet.figures || []) {
378378
if (figure.tag !== "chart" || figure.data.type !== "gauge") {
@@ -503,7 +503,7 @@ migrationStepRegistry
503503
},
504504
})
505505
.add("18.4.2", {
506-
migrate(data: WorkbookData): any {
506+
migrate(data: any): any {
507507
for (const sheet of data.sheets || []) {
508508
for (const figure of sheet.figures || []) {
509509
if (figure.tag !== "chart" || figure.data.type !== "scorecard") {
@@ -538,11 +538,24 @@ migrationStepRegistry
538538
},
539539
})
540540
.add("18.5.1", {
541-
migrate(data: WorkbookData): any {
541+
migrate(data: any): WorkbookData {
542542
for (const sheet of data.sheets || []) {
543+
if (!sheet.charts) {
544+
sheet.charts = {};
545+
}
546+
if (!sheet.images) {
547+
sheet.images = {};
548+
}
549+
543550
for (const figure of sheet.figures || []) {
544551
if (figure.tag === "chart") {
545-
figure.data.chartId = figure.id;
552+
const chart = figure.data;
553+
delete figure.data;
554+
sheet.charts[figure.id] = { figureId: figure.id, chart };
555+
} else if (figure.tag === "image") {
556+
const image = figure.data;
557+
delete figure.data;
558+
sheet.images[figure.id] = { figureId: figure.id, image };
546559
}
547560
}
548561
}

src/plugins/core/carousel.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,19 +122,19 @@ export class CarouselPlugin extends CorePlugin<CarouselState> implements Carouse
122122

123123
import(data: WorkbookData) {
124124
for (const sheet of data.sheets) {
125-
const carousels = (sheet.figures || []).filter((figure) => figure.tag === "carousel");
126-
for (const carousel of carousels) {
127-
this.history.update("carousels", sheet.id, carousel.id, { items: carousel.data.items });
125+
for (const carouselId in sheet.carousels || {}) {
126+
const { carousel } = sheet.carousels[carouselId];
127+
this.history.update("carousels", sheet.id, carouselId, carousel);
128128
}
129129
}
130130
}
131131

132132
export(data: WorkbookData) {
133133
for (const sheet of data.sheets) {
134-
const carousels = sheet.figures.filter((figure) => figure.tag === "carousel");
135-
for (const carousel of carousels) {
136-
if (this.carousels[sheet.id]?.[carousel.id]) {
137-
carousel.data = { ...carousel.data, ...this.carousels[sheet.id]?.[carousel.id] };
134+
for (const carouselId in this.carousels[sheet.id] || {}) {
135+
const carousel = this.carousels[sheet.id]?.[carouselId];
136+
if (carousel) {
137+
sheet.carousels[carouselId] = { figureId: carouselId, carousel };
138138
}
139139
}
140140
}

src/plugins/core/chart.ts

Lines changed: 11 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import {
1212
CreateChartCommand,
1313
DeleteChartCommand,
1414
DOMDimension,
15-
FigureData,
1615
HeaderIndex,
1716
PixelPosition,
1817
UID,
@@ -212,59 +211,26 @@ export class ChartPlugin extends CorePlugin<ChartState> implements ChartState {
212211

213212
import(data: WorkbookData) {
214213
for (const sheet of data.sheets) {
215-
if (sheet.figures) {
216-
for (const figure of sheet.figures) {
217-
// TODO:
218-
// figure data should be external IMO => chart should be in sheet.chart
219-
// instead of in figure.data
220-
if (figure.tag === "chart") {
221-
const chartId = figure.data.chartId;
222-
const chart = this.createChart(figure.id, figure.data, sheet.id);
223-
this.charts[chartId] = { chart, figureId: figure.id };
224-
} else if (figure.tag === "carousel") {
225-
for (const chartId in figure.data.chartDefinitions || {}) {
226-
const chartDefinition = figure.data.chartDefinitions[chartId];
227-
const chart = this.createChart(figure.id, chartDefinition, sheet.id);
228-
this.charts[chartId] = { chart, figureId: figure.id };
229-
}
230-
}
231-
}
214+
for (const chartId in sheet.charts) {
215+
const { figureId, chart: chartData } = sheet.charts[chartId];
216+
const chart = this.createChart(figureId, chartData, sheet.id);
217+
this.charts[chartId] = { chart, figureId };
232218
}
233219
}
234220
}
235221

236222
export(data: WorkbookData) {
237223
if (data.sheets) {
238224
for (const sheet of data.sheets) {
239-
// TODO This code is false, if two plugins want to insert figures on the sheet, it will crash !
240-
const sheetFigures = this.getters.getFigures(sheet.id);
241-
const figures: FigureData<any>[] = [];
242-
for (const sheetFigure of sheetFigures) {
243-
const figure = sheetFigure as FigureData<any>;
244-
const chartId = Object.keys(this.charts).find(
245-
(chartId) => this.charts[chartId]?.figureId === sheetFigure.id
246-
);
247-
if (figure && figure.tag === "chart" && chartId) {
248-
const data = this.charts[chartId]?.chart.getDefinition();
249-
if (data) {
250-
figure.data = { ...data, chartId };
251-
figures.push(figure);
252-
}
253-
} else if (figure && figure.tag === "carousel") {
254-
const chartIds = Object.keys(this.charts).filter(
255-
(chartId) => this.charts[chartId]?.figureId === sheetFigure.id
256-
);
257-
const data = {};
258-
for (const chartId of chartIds) {
259-
data[chartId] = this.charts[chartId]?.chart.getDefinition();
260-
}
261-
figure.data = { chartDefinitions: data };
262-
figures.push(figure);
263-
} else {
264-
figures.push(figure);
225+
for (const chartId of this.getChartIds(sheet.id)) {
226+
const figureChart = this.charts[chartId];
227+
if (figureChart) {
228+
sheet.charts[chartId] = {
229+
figureId: figureChart.figureId,
230+
chart: figureChart.chart.getDefinition(),
231+
};
265232
}
266233
}
267-
sheet.figures = figures;
268234
}
269235
}
270236
}

src/plugins/core/figures.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,7 @@ export class FigurePlugin extends CorePlugin<FigureState> implements FigureState
364364
export(data: WorkbookData) {
365365
for (const sheet of data.sheets) {
366366
for (const figure of this.getFigures(sheet.id)) {
367-
const data = undefined;
368-
sheet.figures.push({ ...figure, data });
367+
sheet.figures.push({ ...figure });
369368
}
370369
}
371370
}

src/plugins/core/image.ts

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
CoreCommand,
88
DOMDimension,
99
ExcelWorkbookData,
10-
FigureData,
1110
FigureSize,
1211
HeaderIndex,
1312
PixelPosition,
@@ -141,43 +140,27 @@ export class ImagePlugin extends CorePlugin<ImageState> implements ImageState {
141140

142141
import(data: WorkbookData) {
143142
for (const sheet of data.sheets) {
144-
const images = (sheet.figures || []).filter((figure) => figure.tag === "image");
145-
for (const image of images) {
146-
this.history.update("images", sheet.id, image.id, image.data);
147-
this.syncedImages.add(image.data.path);
143+
for (const imageId in sheet.images || {}) {
144+
const { figureId, image } = sheet.images[imageId];
145+
this.history.update("images", sheet.id, figureId, image);
146+
this.syncedImages.add(image.path);
148147
}
149148
}
150149
}
151150

152151
export(data: WorkbookData) {
153152
for (const sheet of data.sheets) {
154-
const images = sheet.figures.filter((figure) => figure.tag === "image");
155-
for (const image of images) {
156-
image.data = this.images[sheet.id]?.[image.id];
153+
for (const imageId in this.images[sheet.id] || {}) {
154+
const image = this.images[sheet.id]?.[imageId];
155+
if (image) {
156+
sheet.images[imageId] = { figureId: imageId, image };
157+
}
157158
}
158159
}
159160
}
160161

161162
exportForExcel(data: ExcelWorkbookData) {
162-
for (const sheet of data.sheets) {
163-
if (!sheet.images) {
164-
sheet.images = [];
165-
}
166-
const figures = this.getters.getFigures(sheet.id);
167-
const images: FigureData<Image>[] = [];
168-
for (const figure of figures) {
169-
if (figure?.tag === "image") {
170-
const image = this.getImage(figure.id);
171-
if (image) {
172-
images.push({
173-
...figure,
174-
data: deepCopy(image),
175-
});
176-
}
177-
}
178-
}
179-
sheet.images = [...sheet.images, ...images];
180-
}
163+
return this.export(data);
181164
}
182165

183166
private getAllImages(): Image[] {

src/plugins/core/sheet.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
toCartesian,
1818
} from "../../helpers/index";
1919
import { isSheetNameEqual } from "../../helpers/sheet";
20+
import { createEmptySheet } from "../../migrations/data";
2021
import {
2122
Cell,
2223
CellPosition,
@@ -283,21 +284,11 @@ export class SheetPlugin extends CorePlugin<SheetState> implements SheetState {
283284
data.sheets = this.orderedSheetIds.filter(isDefined).map((id) => {
284285
const sheet = this.sheets[id]!;
285286
const sheetData: SheetData = {
287+
...createEmptySheet(sheet.id, sheet.name),
286288
id: sheet.id,
287289
name: sheet.name,
288290
colNumber: sheet.numberOfCols,
289291
rowNumber: this.getters.getNumberRows(sheet.id),
290-
rows: {},
291-
cols: {},
292-
merges: [],
293-
cells: {},
294-
styles: {},
295-
formats: {},
296-
borders: {},
297-
conditionalFormats: [],
298-
dataValidationRules: [],
299-
figures: [],
300-
tables: [],
301292
areGridLinesVisible:
302293
sheet.areGridLinesVisible === undefined ? true : sheet.areGridLinesVisible,
303294
isVisible: sheet.isVisible,

0 commit comments

Comments
 (0)