@trebco/treb 31.3.4 → 31.7.0

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.
@@ -43,7 +43,7 @@ import type { DataModel, ConditionalFormat, // MacroFunction, SerializedModel, S
43
43
  import type { Parser, UnitAddress} from 'treb-parser';
44
44
  import { type ExpressionUnit, IllegalSheetNameRegex, ParseCSV, DecimalMarkType } from 'treb-parser';
45
45
  import { Area, IsCellAddress, ValueType, DefaultTableSortOptions } from 'treb-base-types';
46
- import type { ICellAddress, IArea, Cell, CellValue, CellStyle, Table, TableSortOptions, TableTheme, Complex, PatchOptions as PatchAreaOptions } from 'treb-base-types';
46
+ import type { ICellAddress, IArea, Cell, CellValue, CellStyle, Table, TableSortOptions, TableTheme, Complex, PatchOptions as PatchAreaOptions, Color } from 'treb-base-types';
47
47
 
48
48
  import { Sheet, type SerializeOptions, type Annotation } from 'treb-data-model';
49
49
 
@@ -53,7 +53,7 @@ import { NumberFormat, ValueParser } from 'treb-format';
53
53
 
54
54
  import type { GridEvent } from './grid_events';
55
55
  import { ErrorCode } from './grid_events';
56
- import type { CommandRecord, DataValidationCommand, DuplicateSheetCommand, FreezeCommand, InsertColumnsCommand, InsertRowsCommand, ResizeColumnsCommand, ResizeRowsCommand, SelectCommand, SetRangeCommand, ShowSheetCommand, SortTableCommand } from './grid_command';
56
+ import type { CommandRecord, CreateAnnotationCommand, DataValidationCommand, DuplicateSheetCommand, FreezeCommand, InsertColumnsCommand, InsertRowsCommand, RemoveAnnotationCommand, ResizeColumnsCommand, ResizeRowsCommand, SelectCommand, SetRangeCommand, ShowSheetCommand, SortTableCommand } from './grid_command';
57
57
  import { DefaultGridOptions, type GridOptions } from './grid_options';
58
58
 
59
59
  import { BorderConstants } from './border_constants';
@@ -813,6 +813,34 @@ export class GridBase {
813
813
 
814
814
  }
815
815
 
816
+ protected RemoveAnnotationInternal(command: RemoveAnnotationCommand) {
817
+
818
+ for (let i = 0; i < command.sheet.annotations.length; i++) {
819
+ if (command.annotation === command.sheet.annotations[i]) {
820
+ command.sheet.annotations.splice(i, 1);
821
+
822
+ // subclass only // this.layout.RemoveAnnotation(annotation);
823
+
824
+ // do we still need this message? not sure
825
+
826
+ this.grid_events.Publish({
827
+ type: 'annotation',
828
+ annotation: command.annotation,
829
+ event: 'delete',
830
+ });
831
+
832
+ return;
833
+ }
834
+ }
835
+
836
+ }
837
+
838
+ /** placeholder */
839
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
840
+ protected CreateAnnotationInternal(command: CreateAnnotationCommand) {
841
+
842
+ }
843
+
816
844
  /**
817
845
  * resize rows. this supports auto size, but that will fail in !ui grid,
818
846
  * because it uses HTML. also non-ui doesn't really need to worry about
@@ -1904,6 +1932,7 @@ export class GridBase {
1904
1932
 
1905
1933
  // nothing
1906
1934
  case CommandKey.Null:
1935
+ case CommandKey.TabColor:
1907
1936
  case CommandKey.ShowHeaders:
1908
1937
  case CommandKey.ShowSheet:
1909
1938
  case CommandKey.AddSheet:
@@ -1913,6 +1942,8 @@ export class GridBase {
1913
1942
  case CommandKey.RenameSheet:
1914
1943
  case CommandKey.ReorderSheet:
1915
1944
  case CommandKey.Reset:
1945
+ case CommandKey.CreateAnnotation:
1946
+ case CommandKey.RemoveAnnotation:
1916
1947
  break;
1917
1948
 
1918
1949
  /*
@@ -2009,6 +2040,14 @@ export class GridBase {
2009
2040
 
2010
2041
  }
2011
2042
 
2043
+ public TabColor(sheet: Sheet, color?: Color) {
2044
+ this.ExecCommand({
2045
+ key: CommandKey.TabColor,
2046
+ sheet,
2047
+ color,
2048
+ });
2049
+ }
2050
+
2012
2051
  /**
2013
2052
  * add sheet. data only.
2014
2053
  */
@@ -4183,6 +4222,20 @@ export class GridBase {
4183
4222
  flags.structure_event = true;
4184
4223
  break;
4185
4224
 
4225
+ case CommandKey.TabColor:
4226
+ command.sheet.tab_color = command.color;
4227
+
4228
+ // NOTE: the flag.sheets originally did not update tab colors,
4229
+ // which were cached. we could create a new flag for that, or
4230
+ // we could just refresh the colors. since there aren't that
4231
+ // many of them, it's probably OK to just refresh the colors any
4232
+ // time this flag is set. if that becomes a perf issue in the
4233
+ // future we could add a new flag.
4234
+
4235
+ flags.sheets = true; // repaint tab bar
4236
+ flags.structure_event = true;
4237
+ break;
4238
+
4186
4239
  case CommandKey.ReorderSheet:
4187
4240
  {
4188
4241
  // COEDITING: seems OK, irrespective of active sheet
@@ -4225,6 +4278,20 @@ export class GridBase {
4225
4278
  }
4226
4279
  break;
4227
4280
 
4281
+ case CommandKey.RemoveAnnotation:
4282
+ this.RemoveAnnotationInternal(command);
4283
+ flags.structure_event = true;
4284
+ flags.structure_rebuild_required = true;
4285
+ flags.annotation_event = true;
4286
+ break;
4287
+
4288
+ case CommandKey.CreateAnnotation:
4289
+ this.CreateAnnotationInternal(command);
4290
+ flags.structure_event = true;
4291
+ flags.structure_rebuild_required = true;
4292
+ flags.annotation_event = true;
4293
+ break;
4294
+
4228
4295
  case CommandKey.ResizeRows:
4229
4296
 
4230
4297
  // moving this to a method so we can specialize: non-UI grid
@@ -4483,6 +4550,7 @@ export class GridBase {
4483
4550
  type: 'structure',
4484
4551
  rebuild_required: flags.structure_rebuild_required,
4485
4552
  conditional_format: flags.conditional_formatting_event,
4553
+ update_annotations: flags.annotation_event,
4486
4554
  });
4487
4555
  }
4488
4556
 
@@ -19,10 +19,10 @@
19
19
  *
20
20
  */
21
21
 
22
- import type { ICellAddress, IArea, CellStyle, Color, CellValue, Table, TableSortType, TableTheme } from 'treb-base-types';
22
+ import type { ICellAddress, IArea, CellStyle, Color, CellValue, Table, TableSortType, TableTheme, IRectangle } from 'treb-base-types';
23
23
  import type { ExpressionUnit } from 'treb-parser';
24
24
  import type { BorderConstants } from './border_constants';
25
- import type { ConditionalFormat } from 'treb-data-model';
25
+ import type { Annotation, AnnotationData, ConditionalFormat, Sheet } from 'treb-data-model';
26
26
 
27
27
  /**
28
28
  * switching to an exec-command based model, so we can serialize
@@ -78,6 +78,27 @@ export enum CommandKey {
78
78
  AddConditionalFormat,
79
79
  RemoveConditionalFormat,
80
80
 
81
+ TabColor,
82
+ CreateAnnotation,
83
+ RemoveAnnotation,
84
+
85
+ }
86
+
87
+ export interface RemoveAnnotationCommand {
88
+ key: CommandKey.RemoveAnnotation;
89
+ sheet: Sheet;
90
+ annotation: Annotation;
91
+ }
92
+
93
+ export interface CreateAnnotationCommand {
94
+ key: CommandKey.CreateAnnotation;
95
+ sheet: Sheet;
96
+ properties: Partial<AnnotationData>;
97
+ add_to_sheet?: boolean;
98
+ offset?: boolean;
99
+ target?: IArea|IRectangle;
100
+ focus?: boolean;
101
+
81
102
  }
82
103
 
83
104
  /** base type for sheet commands -- can select sheet by name, id or index */
@@ -439,6 +460,12 @@ export interface AddConditionalFormatCommand {
439
460
  format: ConditionalFormat;
440
461
  }
441
462
 
463
+ export interface TabColorCommand {
464
+ key: CommandKey.TabColor;
465
+ sheet: Sheet;
466
+ color?: Color;
467
+ }
468
+
442
469
  /**
443
470
  * remove conditional format, either as an object or from a target
444
471
  * area. as an object, we'll match using object equivalence and not
@@ -480,6 +507,7 @@ export type Command =
480
507
  | SetNameCommand
481
508
  | AddSheetCommand
482
509
  | SetRangeCommand
510
+ | TabColorCommand
483
511
  | SortTableCommand
484
512
  | ShowSheetCommand
485
513
  | MergeCellsCommand
@@ -499,6 +527,8 @@ export type Command =
499
527
  | ActivateSheetCommand
500
528
  | DataValidationCommand
501
529
  | DuplicateSheetCommand
530
+ | CreateAnnotationCommand
531
+ | RemoveAnnotationCommand
502
532
  | AddConditionalFormatCommand
503
533
  | RemoveConditionalFormatCommand
504
534
  ) ; // & Ephemeral;
@@ -83,7 +83,13 @@ export interface StructureEvent {
83
83
  * we can use this when conditional formats are modified/added/removed
84
84
  */
85
85
  conditional_format?: boolean;
86
-
86
+
87
+ /**
88
+ * this flag should be set if annotations have been added or removed,
89
+ * so parent/child views can update as necessary
90
+ */
91
+ update_annotations?: boolean;
92
+
87
93
  }
88
94
 
89
95
  export interface AnnotationEvent {
@@ -90,6 +90,9 @@ export interface GridOptions {
90
90
  /** support MD formatting in text */
91
91
  markdown?: boolean;
92
92
 
93
+ /** support MD formatting in comments */
94
+ comment_markdown?: boolean;
95
+
93
96
  /** support font stacks */
94
97
  support_font_stacks?: boolean;
95
98
 
@@ -104,6 +107,7 @@ export const DefaultGridOptions: GridOptions = {
104
107
  // insert_function_button: false,
105
108
  expand_formula_button: false,
106
109
  expand: true,
110
+ comment_markdown: true,
107
111
  repaint_on_cell_change: true,
108
112
  grid_over_background: false, // true,
109
113
  };
@@ -443,6 +443,8 @@ export class TabBar extends EventSource<TabEvent> {
443
443
  */
444
444
  public Update(): void {
445
445
 
446
+ this.tab_color_cache.clear(); // we're setting tab color but it's not getting updated otherwise
447
+
446
448
  // this is a hack to normalize behavior if you try to re-order
447
449
  // a tab that's not the active tab. what ordinarily happens is
448
450
  // we start the drag, but then Update is called again which rebuilds
@@ -68,6 +68,12 @@ export interface UpdateFlags {
68
68
  structure_event?: boolean;
69
69
  structure_rebuild_required?: boolean;
70
70
 
71
+ /**
72
+ * new, an indication to split views that we might need to update/reinflate
73
+ * annotations.
74
+ */
75
+ annotation_event?: boolean;
76
+
71
77
  render_area?: Area;
72
78
  data_area?: Area;
73
79
  style_area?: Area;
@@ -103,8 +103,16 @@ export class MDParser {
103
103
  *
104
104
  * also the way this works adds extra tags if you have nested styles. not
105
105
  * an issue if it's just for testing though.
106
+ *
107
+ * update to optionally not add breaking spaces (<br/>). we need this for
108
+ * containers that are set to white-space: pre-line, where we will already
109
+ * get a linebreak.
110
+ *
106
111
  */
107
- public HTML(formatted: FormattedString[][]): string {
112
+ public HTML(formatted: FormattedString[][], options: { br?: boolean } = {}): string {
113
+
114
+ // default options
115
+ options = { br: true, ...options };
108
116
 
109
117
  const lines: string[] = [];
110
118
 
@@ -128,7 +136,7 @@ export class MDParser {
128
136
  lines.push(text.join(''));
129
137
  }
130
138
 
131
- return lines.join('<br/>\n');
139
+ return lines.join(options.br ? '<br/>\n' : '\n');
132
140
 
133
141
  }
134
142
 
@@ -454,7 +462,12 @@ export class MDParser {
454
462
  tokens.push({ type: 'text', text: current_token });
455
463
  }
456
464
 
457
- let tmp = char;
465
+ tokens.push({
466
+ type: 'newline',
467
+ text: char,
468
+ })
469
+
470
+ let tmp = '';
458
471
  for (;;) { // while (true) {
459
472
  const next_char = text[index+1];
460
473
  if (this.IsNewline(next_char)) {
@@ -465,10 +478,13 @@ export class MDParser {
465
478
  break;
466
479
  }
467
480
  }
468
- tokens.push({
469
- type: 'newline',
470
- text: tmp,
471
- })
481
+
482
+ if (tmp.length) {
483
+ tokens.push({
484
+ type: 'newline',
485
+ text: tmp,
486
+ });
487
+ }
472
488
  escape = false;
473
489
  current_token = '';
474
490
 
package/test/parser.ts DELETED
@@ -1,13 +0,0 @@
1
-
2
- import { Parser } from '../treb-parser/src/parser.js';
3
-
4
- const parser = new Parser();
5
-
6
- let text = "=NORMDIST((LN(S/K)+(r+s^2/2)*T)/(s*SQRT(T)), 0, 1, TRUE)*S - NORMDIST((LN(S/K)+(r-s^2/2)*T)/(s*SQRT(T)), 0, 1, TRUE)*K*EXP(-r*T)";
7
- let result = parser.Parse(text);
8
- // console.info('valid?', result.valid, result.expression);
9
-
10
- text = "=s*SQRT(T)";
11
- result = parser.Parse(text);
12
- console.info('valid?', result.valid, result.expression);
13
-