@trebco/treb 32.4.1 → 32.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -6
- package/dist/treb-spreadsheet.mjs +12 -12
- package/package.json +2 -2
- package/treb-base-types/src/import.ts +14 -10
- package/treb-calculator/src/calculator.ts +5 -0
- package/treb-charts/src/chart-types.ts +2 -0
- package/treb-charts/src/chart-utils.ts +45 -4
- package/treb-charts/src/default-chart-renderer.ts +84 -24
- package/treb-data-model/src/sheet.ts +9 -0
- package/treb-embed/src/embedded-spreadsheet.ts +2 -2
- package/treb-embed/style/tab-bar.scss +1 -0
- package/treb-export/src/{drawing2/drawing2.ts → drawing/drawing.ts} +2 -2
- package/treb-export/src/export.ts +11 -11
- package/treb-export/src/import.ts +216 -20
- package/treb-export/src/metadata.ts +187 -0
- package/treb-export/src/{workbook-sheet2.ts → workbook-sheet.ts} +2 -2
- package/treb-export/src/{workbook-style2.ts → workbook-style.ts} +1 -1
- package/treb-export/src/{workbook-theme2.ts → workbook-theme.ts} +0 -2
- package/treb-export/src/{workbook2.ts → workbook.ts} +157 -11
- package/treb-grid/src/types/grid.ts +9 -9
- package/treb-grid/src/types/grid_base.ts +2 -1
- package/treb-grid/src/types/grid_command.ts +3 -0
- package/treb-grid/src/types/tab_bar.ts +36 -7
- /package/treb-export/src/{drawing2 → drawing}/bubble-chart-template.ts +0 -0
- /package/treb-export/src/{drawing2 → drawing}/chart-template-components2.ts +0 -0
- /package/treb-export/src/{drawing2/chart2.ts → drawing/chart.ts} +0 -0
- /package/treb-export/src/{drawing2 → drawing}/column-chart-template2.ts +0 -0
- /package/treb-export/src/{drawing2 → drawing}/donut-chart-template2.ts +0 -0
- /package/treb-export/src/{drawing2 → drawing}/embedded-image.ts +0 -0
- /package/treb-export/src/{drawing2 → drawing}/scatter-chart-template2.ts +0 -0
- /package/treb-export/src/{shared-strings2.ts → shared-strings.ts} +0 -0
|
@@ -28,16 +28,17 @@ const xmlparser2 = new XMLParser(XMLOptions2);
|
|
|
28
28
|
|
|
29
29
|
// import * as he from 'he';
|
|
30
30
|
|
|
31
|
-
import type { TwoCellAnchor, CellAnchor } from './
|
|
31
|
+
import type { TwoCellAnchor, CellAnchor } from './drawing/drawing';
|
|
32
32
|
|
|
33
|
-
import { SharedStrings } from './shared-
|
|
34
|
-
import { StyleCache } from './workbook-
|
|
35
|
-
import { Theme } from './workbook-
|
|
36
|
-
import { Sheet, VisibleState } from './workbook-
|
|
33
|
+
import { SharedStrings } from './shared-strings';
|
|
34
|
+
import { StyleCache } from './workbook-style';
|
|
35
|
+
import { Theme } from './workbook-theme';
|
|
36
|
+
import { Sheet, VisibleState } from './workbook-sheet';
|
|
37
37
|
import type { RelationshipMap } from './relationship';
|
|
38
38
|
import { ZipWrapper } from './zip-wrapper';
|
|
39
|
-
import type { CellStyle,
|
|
39
|
+
import type { CellStyle, ThemeColor } from 'treb-base-types';
|
|
40
40
|
import type { SerializedNamed } from 'treb-data-model';
|
|
41
|
+
import { type Metadata, ParseMetadataXML } from './metadata';
|
|
41
42
|
|
|
42
43
|
/**
|
|
43
44
|
* @privateRemarks -- FIXME: not sure about the equal/equals thing. need to check.
|
|
@@ -53,20 +54,42 @@ export const ConditionalFormatOperators: Record<string, string> = {
|
|
|
53
54
|
notEqual: '<>',
|
|
54
55
|
};
|
|
55
56
|
|
|
57
|
+
//
|
|
58
|
+
// enums? really? in 2025? FIXME
|
|
59
|
+
//
|
|
56
60
|
export enum ChartType {
|
|
57
|
-
|
|
61
|
+
Null = 0,
|
|
62
|
+
Column,
|
|
63
|
+
Bar,
|
|
64
|
+
Line,
|
|
65
|
+
Scatter,
|
|
66
|
+
Donut,
|
|
67
|
+
Pie,
|
|
68
|
+
Bubble,
|
|
69
|
+
Box,
|
|
70
|
+
Histogram,
|
|
71
|
+
Unknown
|
|
58
72
|
}
|
|
59
73
|
|
|
60
74
|
export interface ChartSeries {
|
|
61
75
|
values?: string;
|
|
62
76
|
categories?: string;
|
|
63
77
|
bubble_size?: string;
|
|
78
|
+
|
|
79
|
+
/** special for histogram */
|
|
80
|
+
bin_count?: number;
|
|
81
|
+
|
|
64
82
|
title?: string;
|
|
65
83
|
}
|
|
66
84
|
|
|
85
|
+
type ChartFlags =
|
|
86
|
+
'stacked'
|
|
87
|
+
;
|
|
88
|
+
|
|
67
89
|
export interface ChartDescription {
|
|
68
90
|
title?: string;
|
|
69
91
|
type: ChartType;
|
|
92
|
+
flags?: ChartFlags[];
|
|
70
93
|
series?: ChartSeries[];
|
|
71
94
|
}
|
|
72
95
|
|
|
@@ -151,6 +174,9 @@ export class Workbook {
|
|
|
151
174
|
/** the workbook "rels" */
|
|
152
175
|
public rels: RelationshipMap = {};
|
|
153
176
|
|
|
177
|
+
/** metadata reference; new and WIP */
|
|
178
|
+
public metadata?: Metadata;
|
|
179
|
+
|
|
154
180
|
public sheets: Sheet[] = [];
|
|
155
181
|
|
|
156
182
|
public active_tab = 0;
|
|
@@ -200,6 +226,13 @@ export class Workbook {
|
|
|
200
226
|
let xml = xmlparser2.parse(data || '');
|
|
201
227
|
this.shared_strings.FromXML(xml);
|
|
202
228
|
|
|
229
|
+
// new(ish) metadata
|
|
230
|
+
if (this.zip.Has('xl/metadata.xml')) {
|
|
231
|
+
data = this.zip.Get('xl/metadata.xml');
|
|
232
|
+
xml = xmlparser2.parse(data);
|
|
233
|
+
this.metadata = ParseMetadataXML(xml);
|
|
234
|
+
}
|
|
235
|
+
|
|
203
236
|
// theme
|
|
204
237
|
data = this.zip.Get('xl/theme/theme1.xml');
|
|
205
238
|
xml = xmlparser2.parse(data);
|
|
@@ -542,7 +575,7 @@ export class Workbook {
|
|
|
542
575
|
const xml = xmlparser2.parse(data);
|
|
543
576
|
|
|
544
577
|
const result: ChartDescription = {
|
|
545
|
-
type: ChartType.
|
|
578
|
+
type: ChartType.Null
|
|
546
579
|
};
|
|
547
580
|
|
|
548
581
|
// console.info("RC", xml);
|
|
@@ -562,8 +595,29 @@ export class Workbook {
|
|
|
562
595
|
}
|
|
563
596
|
}
|
|
564
597
|
else {
|
|
598
|
+
|
|
599
|
+
// there's a bug in FindAll -- seems to have to do with the nodes
|
|
600
|
+
// here being strings
|
|
601
|
+
|
|
602
|
+
const nodes: (string | { t$: string })[] = [];
|
|
603
|
+
const parents = XMLUtils.FindAll(title_node, 'c:tx/c:rich/a:p/a:r');
|
|
604
|
+
for (const entry of parents) {
|
|
605
|
+
if (entry['a:t']) {
|
|
606
|
+
nodes.push(entry['a:t'])
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/*
|
|
611
|
+
const xx = XMLUtils.FindAll(title_node, 'c:tx/c:rich/a:p/a:r');
|
|
612
|
+
const yy = XMLUtils.FindAll(title_node, 'c:tx/c:rich/a:p/a:r/a:t');
|
|
613
|
+
console.info({xx, yy});
|
|
614
|
+
|
|
565
615
|
const nodes = XMLUtils.FindAll(title_node, 'c:tx/c:rich/a:p/a:r/a:t');
|
|
566
|
-
|
|
616
|
+
*/
|
|
617
|
+
|
|
618
|
+
result.title = '"' + nodes.map(node => {
|
|
619
|
+
return typeof node === 'string' ? node : (node.t$ || '');
|
|
620
|
+
}).join('') + '"';
|
|
567
621
|
}
|
|
568
622
|
|
|
569
623
|
}
|
|
@@ -653,6 +707,14 @@ export class Workbook {
|
|
|
653
707
|
if (node['c:barDir']) {
|
|
654
708
|
if (node['c:barDir'].a$?.val === 'col') {
|
|
655
709
|
result.type = ChartType.Column;
|
|
710
|
+
|
|
711
|
+
if (node['c:grouping']?.a$?.val === 'stacked') {
|
|
712
|
+
if (!result.flags) {
|
|
713
|
+
result.flags = [];
|
|
714
|
+
}
|
|
715
|
+
result.flags.push('stacked');
|
|
716
|
+
}
|
|
717
|
+
|
|
656
718
|
}
|
|
657
719
|
}
|
|
658
720
|
|
|
@@ -705,9 +767,92 @@ export class Workbook {
|
|
|
705
767
|
// box plot uses "extended chart" which is totally different... but we
|
|
706
768
|
// might need it again later? for the time being it's just inlined
|
|
707
769
|
|
|
770
|
+
// hmmm also used for histogram... histograms aren't named, they are
|
|
771
|
+
// clustered column type with a binning element, which has some attributes
|
|
772
|
+
|
|
708
773
|
const ex_series = XMLUtils.FindAll(xml, 'cx:chartSpace/cx:chart/cx:plotArea/cx:plotAreaRegion/cx:series');
|
|
709
774
|
if (ex_series?.length) {
|
|
710
|
-
|
|
775
|
+
|
|
776
|
+
// testing seems to require looping, so let's try to merge loops
|
|
777
|
+
|
|
778
|
+
let clustered_column = true;
|
|
779
|
+
let histogram = true;
|
|
780
|
+
let box_whisker = true;
|
|
781
|
+
|
|
782
|
+
for (const series of ex_series) {
|
|
783
|
+
|
|
784
|
+
const layout = series.a$?.layoutId;
|
|
785
|
+
|
|
786
|
+
if (clustered_column && layout !== 'clusteredColumn') {
|
|
787
|
+
clustered_column = false;
|
|
788
|
+
}
|
|
789
|
+
if (box_whisker && layout !== 'boxWhisker') {
|
|
790
|
+
box_whisker = false;
|
|
791
|
+
}
|
|
792
|
+
if (clustered_column && histogram) {
|
|
793
|
+
const binning = XMLUtils.FindAll(series, `cx:layoutPr/cx:binning`);
|
|
794
|
+
if (!binning.length) {
|
|
795
|
+
histogram = false;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
// ok that's what we know so far...
|
|
802
|
+
|
|
803
|
+
if (histogram) {
|
|
804
|
+
result.type = ChartType.Histogram;
|
|
805
|
+
result.series = [];
|
|
806
|
+
|
|
807
|
+
for (const series_entry of ex_series) {
|
|
808
|
+
|
|
809
|
+
if (series_entry.a$?.hidden === '1') {
|
|
810
|
+
continue;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
const series: ChartSeries = {};
|
|
814
|
+
|
|
815
|
+
const data = XMLUtils.FindAll(xml, 'cx:chartSpace/cx:chartData/cx:data');
|
|
816
|
+
|
|
817
|
+
// so there are multiple series, and multiple datasets,
|
|
818
|
+
// but they are all merged together? no idea how this design
|
|
819
|
+
// works
|
|
820
|
+
|
|
821
|
+
const values_list: string[] = [];
|
|
822
|
+
for (const data_series of data) {
|
|
823
|
+
values_list.push(data_series['cx:numDim']?.['cx:f'] || '');
|
|
824
|
+
}
|
|
825
|
+
series.values = values_list.join(',');
|
|
826
|
+
|
|
827
|
+
const bin_count = XMLUtils.FindAll(series_entry, `cx:layoutPr/cx:binning/cx:binCount`);
|
|
828
|
+
if (bin_count[0]) {
|
|
829
|
+
const count = Number(bin_count[0].a$?.val || 0);
|
|
830
|
+
if (count) {
|
|
831
|
+
series.bin_count = count;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
result.series.push(series);
|
|
836
|
+
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
const title = XMLUtils.FindAll(xml, 'cx:chartSpace/cx:chart/cx:title/cx:tx/cx:txData');
|
|
840
|
+
if (title) {
|
|
841
|
+
if (title[0]?.['cx:f']) {
|
|
842
|
+
result.title = title[0]['cx:f'];
|
|
843
|
+
}
|
|
844
|
+
else if (title[0]?.['cx:v']) {
|
|
845
|
+
result.title = '"' + title[0]['cx:v'] + '"';
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
console.info("histogram", result);
|
|
850
|
+
return result;
|
|
851
|
+
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
if (box_whisker) {
|
|
855
|
+
|
|
711
856
|
result.type = ChartType.Box;
|
|
712
857
|
result.series = [];
|
|
713
858
|
const data = XMLUtils.FindAll(xml, 'cx:chartSpace/cx:chartData/cx:data'); // /cx:data/cx:numDim/cx:f');
|
|
@@ -758,7 +903,8 @@ export class Workbook {
|
|
|
758
903
|
}
|
|
759
904
|
|
|
760
905
|
if (!node) {
|
|
761
|
-
console.info("Chart type not handled");
|
|
906
|
+
console.info("Chart type not handled", {xml});
|
|
907
|
+
result.type = ChartType.Unknown;
|
|
762
908
|
}
|
|
763
909
|
|
|
764
910
|
// console.info("RX?", result);
|
|
@@ -1311,7 +1311,7 @@ export class Grid extends GridBase {
|
|
|
1311
1311
|
}
|
|
1312
1312
|
|
|
1313
1313
|
if (this.tab_bar) {
|
|
1314
|
-
this.tab_bar.Update();
|
|
1314
|
+
this.tab_bar.Update(false); // !user
|
|
1315
1315
|
}
|
|
1316
1316
|
|
|
1317
1317
|
}
|
|
@@ -1320,7 +1320,7 @@ export class Grid extends GridBase {
|
|
|
1320
1320
|
* This function is called via Shift+PageUp/PageDown. We need
|
|
1321
1321
|
* to update to account for hidden sheets, which can't be activated.
|
|
1322
1322
|
*/
|
|
1323
|
-
public NextSheet(step = 1): void {
|
|
1323
|
+
public NextSheet(step = 1, user = false): void {
|
|
1324
1324
|
|
|
1325
1325
|
if (this.model.sheets.length === 1) {
|
|
1326
1326
|
return;
|
|
@@ -1344,7 +1344,7 @@ export class Grid extends GridBase {
|
|
|
1344
1344
|
if (visible[i].sheet === this.active_sheet) {
|
|
1345
1345
|
let index = (i + step) % visible.length;
|
|
1346
1346
|
while (index < 0) { index += visible.length; }
|
|
1347
|
-
this.ActivateSheet(visible[index].index);
|
|
1347
|
+
this.ActivateSheet(visible[index].index, user);
|
|
1348
1348
|
return;
|
|
1349
1349
|
}
|
|
1350
1350
|
}
|
|
@@ -1430,7 +1430,7 @@ export class Grid extends GridBase {
|
|
|
1430
1430
|
}
|
|
1431
1431
|
|
|
1432
1432
|
if (this.tab_bar) {
|
|
1433
|
-
this.tab_bar.Update();
|
|
1433
|
+
this.tab_bar.Update(false); // !user
|
|
1434
1434
|
}
|
|
1435
1435
|
|
|
1436
1436
|
}
|
|
@@ -1453,7 +1453,7 @@ export class Grid extends GridBase {
|
|
|
1453
1453
|
*/
|
|
1454
1454
|
public UpdateTabBar(): void {
|
|
1455
1455
|
if (this.tab_bar) {
|
|
1456
|
-
this.tab_bar.Update();
|
|
1456
|
+
this.tab_bar.Update(true); // user? ...
|
|
1457
1457
|
}
|
|
1458
1458
|
}
|
|
1459
1459
|
|
|
@@ -1730,7 +1730,7 @@ export class Grid extends GridBase {
|
|
|
1730
1730
|
// this.tab_bar.Update();
|
|
1731
1731
|
//}
|
|
1732
1732
|
|
|
1733
|
-
this.tab_bar?.Update();
|
|
1733
|
+
this.tab_bar?.Update(false);
|
|
1734
1734
|
|
|
1735
1735
|
this.Repaint(true);
|
|
1736
1736
|
}
|
|
@@ -2673,7 +2673,7 @@ export class Grid extends GridBase {
|
|
|
2673
2673
|
|
|
2674
2674
|
protected RenameSheetInternal(target: Sheet, name: string) {
|
|
2675
2675
|
super.RenameSheetInternal(target, name);
|
|
2676
|
-
this.tab_bar?.Update();
|
|
2676
|
+
this.tab_bar?.Update(false);
|
|
2677
2677
|
|
|
2678
2678
|
}
|
|
2679
2679
|
|
|
@@ -2898,7 +2898,7 @@ export class Grid extends GridBase {
|
|
|
2898
2898
|
activate: this.active_sheet,
|
|
2899
2899
|
});
|
|
2900
2900
|
|
|
2901
|
-
if (this.tab_bar) { this.tab_bar.Update(); }
|
|
2901
|
+
if (this.tab_bar) { this.tab_bar.Update(!!command.user); }
|
|
2902
2902
|
|
|
2903
2903
|
this.layout.scroll_offset = this.active_sheet.scroll_offset;
|
|
2904
2904
|
|
|
@@ -5237,7 +5237,7 @@ export class Grid extends GridBase {
|
|
|
5237
5237
|
case 'PageUp':
|
|
5238
5238
|
case 'PageDown':
|
|
5239
5239
|
if (event.shiftKey) {
|
|
5240
|
-
this.NextSheet(event.key === 'PageUp' ? -1 : 1);
|
|
5240
|
+
this.NextSheet(event.key === 'PageUp' ? -1 : 1, true);
|
|
5241
5241
|
break;
|
|
5242
5242
|
}
|
|
5243
5243
|
|
|
@@ -254,7 +254,7 @@ export class GridBase {
|
|
|
254
254
|
* activate sheet, by name or index number
|
|
255
255
|
* @param sheet number (index into the array) or string (name)
|
|
256
256
|
*/
|
|
257
|
-
public ActivateSheet(sheet: number | string): void {
|
|
257
|
+
public ActivateSheet(sheet: number | string, user?: boolean): void {
|
|
258
258
|
|
|
259
259
|
const index = (typeof sheet === 'number') ? sheet : undefined;
|
|
260
260
|
const name = (typeof sheet === 'string') ? sheet : undefined;
|
|
@@ -263,6 +263,7 @@ export class GridBase {
|
|
|
263
263
|
key: CommandKey.ActivateSheet,
|
|
264
264
|
index,
|
|
265
265
|
name,
|
|
266
|
+
user,
|
|
266
267
|
});
|
|
267
268
|
|
|
268
269
|
}
|
|
@@ -235,7 +235,8 @@ export class TabBar extends EventSource<TabEvent> {
|
|
|
235
235
|
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
-
public SetActive(tab: HTMLElement, active: boolean): void {
|
|
238
|
+
public SetActive(tab: HTMLElement, active: boolean, user = false): void {
|
|
239
|
+
|
|
239
240
|
if (active) {
|
|
240
241
|
// tab.classList.add('treb-selected');
|
|
241
242
|
tab.setAttribute('selected', '');
|
|
@@ -245,8 +246,33 @@ export class TabBar extends EventSource<TabEvent> {
|
|
|
245
246
|
tab.style.color = '';
|
|
246
247
|
}
|
|
247
248
|
|
|
249
|
+
// this is forcing the page to scroll if the sheet is below
|
|
250
|
+
// the fold. this is not useful behavior. at the same time,
|
|
251
|
+
// we do need this to work... we probably have to do it manually
|
|
252
|
+
// instead of using scrollIntoView. would be nice if we could
|
|
253
|
+
// toggle this on manual/auto, so user clicks would still be
|
|
254
|
+
// smooth. call that a TODO
|
|
255
|
+
|
|
248
256
|
requestAnimationFrame(() => {
|
|
249
|
-
|
|
257
|
+
if (user) {
|
|
258
|
+
tab.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest'});
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
if (tab.parentElement) {
|
|
262
|
+
const left = tab.offsetLeft;
|
|
263
|
+
const width = tab.offsetWidth;
|
|
264
|
+
const container_width = tab.parentElement.clientWidth || 0;
|
|
265
|
+
const scroll_left = tab.parentElement.scrollLeft || 0;
|
|
266
|
+
|
|
267
|
+
if (left > container_width) {
|
|
268
|
+
tab.parentElement.scrollLeft = left - width;
|
|
269
|
+
}
|
|
270
|
+
else if (scroll_left > left) {
|
|
271
|
+
tab.parentElement.scrollLeft = left;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
}
|
|
275
|
+
}
|
|
250
276
|
});
|
|
251
277
|
|
|
252
278
|
}
|
|
@@ -298,7 +324,7 @@ export class TabBar extends EventSource<TabEvent> {
|
|
|
298
324
|
case 'Escape':
|
|
299
325
|
tab.innerText = sheet.name;
|
|
300
326
|
this.Publish({ type: 'cancel' });
|
|
301
|
-
this.Update();
|
|
327
|
+
this.Update(true);
|
|
302
328
|
break;
|
|
303
329
|
|
|
304
330
|
default:
|
|
@@ -314,7 +340,7 @@ export class TabBar extends EventSource<TabEvent> {
|
|
|
314
340
|
this.Publish({ type: 'rename-sheet', name, sheet });
|
|
315
341
|
}
|
|
316
342
|
else {
|
|
317
|
-
this.Update();
|
|
343
|
+
this.Update(true);
|
|
318
344
|
}
|
|
319
345
|
});
|
|
320
346
|
|
|
@@ -350,7 +376,7 @@ export class TabBar extends EventSource<TabEvent> {
|
|
|
350
376
|
// then the classes won't change.
|
|
351
377
|
|
|
352
378
|
for (const candidate of tabs) {
|
|
353
|
-
this.SetActive(candidate, candidate === tab);
|
|
379
|
+
this.SetActive(candidate, candidate === tab, true);
|
|
354
380
|
}
|
|
355
381
|
|
|
356
382
|
this.dragging = true;
|
|
@@ -445,8 +471,11 @@ export class TabBar extends EventSource<TabEvent> {
|
|
|
445
471
|
|
|
446
472
|
/**
|
|
447
473
|
* update tabs from model.
|
|
474
|
+
*
|
|
475
|
+
* @param user - this is a user action, so use smooth scrolling
|
|
476
|
+
* when activating the tab. otherwise it's automatic so jump.
|
|
448
477
|
*/
|
|
449
|
-
public Update(): void {
|
|
478
|
+
public Update(user = false): void {
|
|
450
479
|
|
|
451
480
|
this.tab_color_cache.clear(); // we're setting tab color but it's not getting updated otherwise
|
|
452
481
|
|
|
@@ -512,7 +541,7 @@ export class TabBar extends EventSource<TabEvent> {
|
|
|
512
541
|
tab.style.order = (index * 2).toString();
|
|
513
542
|
tab.role = 'tab';
|
|
514
543
|
|
|
515
|
-
this.SetActive(tab, sheet === this.view.active_sheet);
|
|
544
|
+
this.SetActive(tab, sheet === this.view.active_sheet, user);
|
|
516
545
|
|
|
517
546
|
const mousedown = (event: MouseEvent) => this.MouseDownTab(event, tab, sheet, index, tabs);
|
|
518
547
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|