@dvrd/dvr-controls 0.0.34 → 0.0.38

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dvrd/dvr-controls",
3
- "version": "0.0.34",
3
+ "version": "0.0.38",
4
4
  "description": "Custom web controls",
5
5
  "main": "index.ts",
6
6
  "scripts": {},
@@ -84,6 +84,7 @@
84
84
  opacity: 0;
85
85
  transition: color .2s ease-in-out, opacity .2s ease-in-out, visibility .2s ease-in-out;
86
86
  padding: .25rem;
87
+ user-select: none;
87
88
 
88
89
  &:hover {
89
90
  color: $color-gray-7;
@@ -5,7 +5,7 @@ import './style/pdfImage.scss';
5
5
 
6
6
  import React, {MouseEventHandler} from 'react';
7
7
  import {
8
- ElementPosition, IndexedObject, PDFElementParams, PDFElementPersist, PDFElementType, PDFImageParams
8
+ ElementPosition, IndexedObject, PDFDisplay, PDFElementParams, PDFElementPersist, PDFElementType, PDFImageParams
9
9
  } from "../../util/interfaces";
10
10
  import {PDFDraggable, PdfElement} from "../element/pdfElement";
11
11
  import {nullify} from "../../util/miscUtil";
@@ -28,7 +28,7 @@ interface Props {
28
28
 
29
29
  interface State {
30
30
  dragging: boolean;
31
- settings: { img: string; persistent: PDFElementPersist; alignment?: ElementPosition };
31
+ settings: { img: string; persistent: PDFElementPersist; alignment?: ElementPosition; display?: PDFDisplay };
32
32
  }
33
33
 
34
34
  export default class PdfImage extends PdfElement<Props, State> {
@@ -46,6 +46,7 @@ export default class PdfImage extends PdfElement<Props, State> {
46
46
  img: props.values?.default_image || '',
47
47
  persistent: PDFElementPersist.NOT_PERSISTENT,
48
48
  alignment: undefined,
49
+ display: PDFDisplay.ALL_PAGES,
49
50
  }, props.defaultSettings),
50
51
  dragging: false,
51
52
  };
@@ -124,6 +125,7 @@ export default class PdfImage extends PdfElement<Props, State> {
124
125
  img: this.image ?? nullify(settings.img),
125
126
  persistent: settings.persistent,
126
127
  alignment: settings.alignment,
128
+ display: settings.display,
127
129
  },
128
130
  };
129
131
  };
@@ -151,7 +151,7 @@ export default class PdfInvoiceTable extends PdfElement<Props, State> {
151
151
  <PDFDraggable dragging={dragging} draggable={draggable} onDragStart={this.onDragStart}
152
152
  alignment={settings.alignment} elementLabel='Factuurregels' onDragEnd={this.onDragEnd}
153
153
  position={defaultPosition} width={width} height={height} onEdit={this.onClick}
154
- onClickBar={this.onClickBar}
154
+ onClickBar={this.onClickBar} matchParentSize
155
155
  forwardRef={(ref: HTMLDivElement) => {
156
156
  this.element = ref
157
157
  }} ref={(ref: PDFDraggable) => {
@@ -30,6 +30,7 @@ interface Props {
30
30
  mainFont: PdfFont;
31
31
  disableElements: ('text' | 'image' | 'invoiceTable')[];
32
32
  maxWidth?: string;
33
+ supportMultiPage: boolean;
33
34
  }
34
35
 
35
36
  interface State {
@@ -43,6 +44,7 @@ export default class PDFTemplateCreator extends PureComponent<Props, State> {
43
44
  static defaultProps = {
44
45
  values: {},
45
46
  disableElements: [],
47
+ supportMultiPage: false,
46
48
  };
47
49
 
48
50
  private readonly id: string = generateComponentId(this.props.id, true);
@@ -220,7 +222,9 @@ export default class PDFTemplateCreator extends PureComponent<Props, State> {
220
222
 
221
223
  render = () => {
222
224
  const {elements, focusedElement, canUndo, canRedo,} = this.state,
223
- {customVariables, onPreview, mainFont, disableElements, onClickProceed, maxWidth} = this.props;
225
+ {
226
+ customVariables, onPreview, mainFont, disableElements, onClickProceed, maxWidth, supportMultiPage
227
+ } = this.props;
224
228
  return (
225
229
  <div className='pdf-creator' onClick={this.onResetElement}
226
230
  style={{maxWidth: maxWidth ?? '100%'}}>
@@ -229,17 +233,17 @@ export default class PDFTemplateCreator extends PureComponent<Props, State> {
229
233
  <div>
230
234
  <Button onClick={this.onSubmit} label='Opslaan'/>
231
235
  {onClickProceed !== undefined &&
232
- <Button onClick={this.onClickProceed} label='Naar volgende stap' className='proceed-btn'/>}
236
+ <Button onClick={this.onClickProceed} label='Naar volgende stap' className='proceed-btn'/>}
233
237
  </div>
234
238
  </div>
235
239
  <div/>
236
240
  <div className='elements-container'>
237
241
  {!disableElements.includes('image') &&
238
- this.renderElementButton('image', 'Afbeelding', PDFElementType.IMAGE)}
242
+ this.renderElementButton('image', 'Afbeelding', PDFElementType.IMAGE)}
239
243
  {!disableElements.includes('text') &&
240
- this.renderElementButton('font', 'Tekst', PDFElementType.TEXT)}
244
+ this.renderElementButton('font', 'Tekst', PDFElementType.TEXT)}
241
245
  {!disableElements.includes('invoiceTable') &&
242
- this.renderElementButton('list', 'Factuurregels', PDFElementType.INVOICE_TABLE)}
246
+ this.renderElementButton('list', 'Factuurregels', PDFElementType.INVOICE_TABLE)}
243
247
  <div className='history'>
244
248
  <div className={classNames('history-button', !canUndo && 'disabled')}
245
249
  onClick={canUndo ? this.onUndo : voidFunction}
@@ -266,7 +270,7 @@ export default class PDFTemplateCreator extends PureComponent<Props, State> {
266
270
  <div className='right-col'>
267
271
  <PdfElementSettings element={focusedElement} onReset={this.onResetElement}
268
272
  customVariables={customVariables} font={mainFont}
269
- onChangeFont={this.onChangeFont}/>
273
+ onChangeFont={this.onChangeFont} supportMultiPage={supportMultiPage}/>
270
274
  </div>
271
275
  </div>
272
276
  )
@@ -5,26 +5,43 @@ import './style/pdfImageSettings.scss';
5
5
 
6
6
  import React, {PureComponent} from 'react';
7
7
  import PdfImage from "../../image/pdfImage";
8
- import {Button, ElementPosition} from "../../../../../index";
8
+ import {Button, DvrdSelect, ElementPosition, SelectItemShape} from "../../../../../index";
9
9
  import IconButton, {IconButtonType} from "../buttons/iconButton";
10
+ import {PDFDisplay} from "../../../util/interfaces";
10
11
 
11
12
  interface Props {
12
13
  element: PdfImage;
14
+ supportMultiPage: boolean;
13
15
  }
14
16
 
15
17
  interface State {
16
18
  alignment?: ElementPosition;
19
+ display: PDFDisplay;
17
20
  }
18
21
 
22
+ const displayItems: SelectItemShape[] = [
23
+ {value: PDFDisplay.ALL_PAGES, label: 'Alle pagina\'s'},
24
+ {value: PDFDisplay.FIRST_PAGE, label: 'Alleen eerste pagina'},
25
+ {value: PDFDisplay.LAST_PAGE, label: 'Alleen laatste pagina'},
26
+ ]
27
+
19
28
  export default class PdfImageSettings extends PureComponent<Props, State> {
20
29
  constructor(props: Props) {
21
30
  super(props);
22
31
  const settings = props.element.getSettings();
23
32
  this.state = {
24
33
  alignment: settings.alignment,
34
+ display: settings.display ?? PDFDisplay.ALL_PAGES,
25
35
  };
26
36
  }
27
37
 
38
+ onChangeDisplay = (value: PDFDisplay) => {
39
+ const {element} = this.props;
40
+ element.setSetting('display', value, () => {
41
+ this.setState({display: value});
42
+ })
43
+ }
44
+
28
45
  onToggleAlignment = (type: IconButtonType) => () => {
29
46
  const {alignment} = this.state, {element} = this.props;
30
47
  let nextAlignment: ElementPosition | undefined;
@@ -40,9 +57,14 @@ export default class PdfImageSettings extends PureComponent<Props, State> {
40
57
  }
41
58
 
42
59
  render = () => {
43
- const {element} = this.props, {alignment} = this.state;
60
+ const {element, supportMultiPage} = this.props, {alignment, display} = this.state;
44
61
  return (
45
62
  <div className='pdf-image-settings'>
63
+ {supportMultiPage && <>
64
+ <label className='settings-title'>Pagina's</label>
65
+ <DvrdSelect onChange={this.onChangeDisplay} value={display} items={displayItems}/>
66
+ </>}
67
+ <div className='divider'/>
46
68
  <label className='settings-title'>Uitlijning</label>
47
69
  <div className='alignment'>
48
70
  <IconButton onClick={this.onToggleAlignment} active={alignment === ElementPosition.LEFT}
@@ -20,6 +20,7 @@ interface Props {
20
20
  element: PdfElement | null;
21
21
  customVariables?: PDFTextVariables;
22
22
  font: PdfFont;
23
+ supportMultiPage: boolean;
23
24
  }
24
25
 
25
26
  export default class PdfElementSettings extends PureComponent<Props> {
@@ -45,10 +46,12 @@ export default class PdfElementSettings extends PureComponent<Props> {
45
46
  };
46
47
 
47
48
  renderSettings = () => {
48
- const {element, customVariables} = this.props;
49
+ const {element, customVariables, supportMultiPage} = this.props;
49
50
  if (element === null) return this.renderMainSettings();
50
- if (element instanceof PdfText) return <PdfTextSettings element={element} customVariables={customVariables}/>;
51
- if (element instanceof PdfImage) return <PdfImageSettings element={element}/>;
51
+ if (element instanceof PdfText) return <PdfTextSettings element={element} customVariables={customVariables}
52
+ supportMultiPage={supportMultiPage}/>;
53
+ if (element instanceof PdfImage) return <PdfImageSettings element={element}
54
+ supportMultiPage={supportMultiPage}/>;
52
55
  if (element instanceof PdfInvoiceTable) return <PdfInvoiceTableSettings element={element}/>
53
56
  return null;
54
57
  };
@@ -74,7 +77,7 @@ export default class PdfElementSettings extends PureComponent<Props> {
74
77
  <div className='buttons-container'>
75
78
  <Button onClick={onReset} label='Oké' className='reset-btn'/>
76
79
  {deleteAble &&
77
- <Button onClick={this.onClickDelete} label='Verwijderen' primary={false} textColor='red'/>}
80
+ <Button onClick={this.onClickDelete} label='Verwijderen' primary={false} textColor='red'/>}
78
81
  </div>
79
82
  )}
80
83
  </div>
@@ -5,14 +5,23 @@ import './style/pdfTextSettings.scss';
5
5
 
6
6
  import React, {PureComponent} from 'react';
7
7
  import PdfText from "../../text/pdfText";
8
- import {ElementPosition, IndexedObject, PdfFont, PDFTextParams, PDFTextVariables} from "../../../util/interfaces";
9
- import {ColorPicker, fontItems, getPdfVariables, NumberField, Select} from "../../../../../index";
8
+ import {
9
+ ElementPosition,
10
+ IndexedObject,
11
+ PDFDisplay,
12
+ PdfFont,
13
+ PDFTextParams,
14
+ PDFTextVariables,
15
+ SelectItemShape
16
+ } from "../../../util/interfaces";
17
+ import {ColorPicker, DvrdSelect, fontItems, getPdfVariables, NumberField, Select} from "../../../../../index";
10
18
  import classNames from 'classnames';
11
19
  import IconButton, {IconButtonType} from "../buttons/iconButton";
12
20
 
13
21
  interface Props {
14
22
  element: PdfText;
15
23
  customVariables?: PDFTextVariables;
24
+ supportMultiPage: boolean;
16
25
  }
17
26
 
18
27
  interface State extends IndexedObject<any> {
@@ -24,8 +33,15 @@ interface State extends IndexedObject<any> {
24
33
  font: PdfFont;
25
34
  color: string;
26
35
  colorPickerActive: boolean;
36
+ display: PDFDisplay;
27
37
  }
28
38
 
39
+ const displayItems: SelectItemShape[] = [
40
+ {value: PDFDisplay.ALL_PAGES, label: 'Alle pagina\'s'},
41
+ {value: PDFDisplay.FIRST_PAGE, label: 'Alleen eerste pagina'},
42
+ {value: PDFDisplay.LAST_PAGE, label: 'Alleen laatste pagina'},
43
+ ]
44
+
29
45
  export default class PdfTextSettings extends PureComponent<Props, State> {
30
46
  constructor(props: Props) {
31
47
  super(props);
@@ -39,9 +55,17 @@ export default class PdfTextSettings extends PureComponent<Props, State> {
39
55
  font: settings.font,
40
56
  color: settings.color,
41
57
  colorPickerActive: false,
58
+ display: settings.display ?? PDFDisplay.ALL_PAGES,
42
59
  };
43
60
  }
44
61
 
62
+ onChangeDisplay = (value: PDFDisplay) => {
63
+ const {element} = this.props;
64
+ element.setSetting('display', value, () => {
65
+ this.setState({display: value});
66
+ })
67
+ }
68
+
45
69
  onCloseColorPicker = () => {
46
70
  this.setState({colorPickerActive: false});
47
71
  };
@@ -125,10 +149,16 @@ export default class PdfTextSettings extends PureComponent<Props, State> {
125
149
  );
126
150
 
127
151
  render = () => {
128
- const {element} = this.props, {bold, underline, italic, alignment, colorPickerActive, color} = this.state,
152
+ const {element, supportMultiPage} = this.props,
153
+ {bold, underline, italic, alignment, colorPickerActive, color, display} = this.state,
129
154
  settings: PDFTextParams = element.getSettings();
130
155
  return (
131
156
  <div className='pdf-text-settings'>
157
+ {supportMultiPage && <>
158
+ <label className='settings-title'>Weergave</label>
159
+ <DvrdSelect onChange={this.onChangeDisplay} value={display} items={displayItems}/>
160
+ </>}
161
+ <div className='divider'/>
132
162
  <div className='text-settings'>
133
163
  <IconButton onClick={this.onToggleSetting} active={bold} type={IconButtonType.BOLD}
134
164
  title='Vet'/>
@@ -5,7 +5,14 @@ import './style/pdfText.scss';
5
5
 
6
6
  import React, {CSSProperties, MouseEventHandler} from 'react';
7
7
  import {
8
- CustomAppEvent, IndexedObject, PDFElementParams, PDFElementPersist, PDFElementType, PdfFont, PDFTextParams,
8
+ CustomAppEvent,
9
+ IndexedObject,
10
+ PDFDisplay,
11
+ PDFElementParams,
12
+ PDFElementPersist,
13
+ PDFElementType,
14
+ PdfFont,
15
+ PDFTextParams,
9
16
  PDFTextVariables
10
17
  } from "../../util/interfaces";
11
18
  import {PDFDraggable, PdfElement} from "../element/pdfElement";
@@ -14,7 +21,7 @@ import {merge} from 'lodash';
14
21
  import {PAGE_WIDTH, pxToPt, setPdfVariables, waitForFonts} from "../../util/pdfUtil";
15
22
  import {directTimeout} from "../../util/componentUtil";
16
23
  import {dispatchCustomEvent, showDialog} from "../../util/eventUtil";
17
- import {WithEvents, remToPx} from "../../../../";
24
+ import {remToPx, WithEvents} from "../../../../";
18
25
 
19
26
  interface Props {
20
27
  onDelete: MouseEventHandler;
@@ -34,6 +41,7 @@ interface Props {
34
41
  interface State {
35
42
  settings: PDFTextParams;
36
43
  dragging: boolean;
44
+ focused: boolean;
37
45
  }
38
46
 
39
47
  export default class PdfText extends PdfElement<Props, State> {
@@ -59,8 +67,10 @@ export default class PdfText extends PdfElement<Props, State> {
59
67
  font: props.mainFont,
60
68
  color: '#000',
61
69
  persistent: PDFElementPersist.NOT_PERSISTENT,
70
+ display: PDFDisplay.ALL_PAGES,
62
71
  }, props.defaultSettings),
63
72
  dragging: false,
73
+ focused: false,
64
74
  }
65
75
  this.currentText = this.state.settings.text;
66
76
  this.events = [this.event, {eventName: 'onLinkedElementMoved', handler: this.onLinkedElementMoved}]
@@ -68,14 +78,23 @@ export default class PdfText extends PdfElement<Props, State> {
68
78
 
69
79
  private onBlur = (evt: React.FocusEvent<HTMLTextAreaElement>) => {
70
80
  this.lastKnownCursor = evt.target.selectionEnd || 0;
81
+ this.setState({focused: false}, this.setWidth);
71
82
  if (this.state.settings.text !== this.currentText) this.props.onSaveHistory();
72
83
  };
73
84
 
74
85
  private onFocus = (evt: React.FocusEvent) => {
75
86
  evt.stopPropagation();
87
+ this.setState({focused: true}, this.setWidth);
76
88
  this.currentText = this.state.settings.text;
89
+ this.onClick();
77
90
  };
78
91
 
92
+ getTextValue = (): string => {
93
+ const {settings, focused} = this.state, {values} = this.props;
94
+ if (focused) return settings.text;
95
+ return setPdfVariables(settings.text, values);
96
+ }
97
+
79
98
  public setSetting = (key: string, value: any, callback?: VoidFunction, save: boolean = true) => {
80
99
  this.setState({settings: Object.assign({}, this.state.settings, {[key]: value})}, () => {
81
100
  this.setWidth();
@@ -104,8 +123,9 @@ export default class PdfText extends PdfElement<Props, State> {
104
123
  this.onClick(evt);
105
124
  };
106
125
 
107
- onClick = (evt: React.MouseEvent) => {
108
- evt.stopPropagation();
126
+ onClick = (evt?: React.MouseEvent) => {
127
+ if (evt)
128
+ evt.stopPropagation();
109
129
  this.props.onFocusElement(this);
110
130
  if (this.draggable)
111
131
  this.draggable.setFocus();
@@ -168,13 +188,14 @@ export default class PdfText extends PdfElement<Props, State> {
168
188
  };
169
189
 
170
190
  getParams = (convertPixels: boolean = true): PDFElementParams<PDFElementType.TEXT, PDFTextParams> => {
171
- const {settings} = this.state, {bold, italic, text, underline, alignment, font, color, persistent} = settings,
191
+ const {settings} = this.state,
192
+ {bold, italic, text, underline, alignment, font, color, persistent, display} = settings,
172
193
  fontSize = convertPixels ? pxToPt(settings.fontSize) : settings.fontSize, {linkedID} = this.props;
173
194
  return {
174
195
  dimensions: this.getDimensions(convertPixels),
175
196
  key: this.id,
176
197
  type: PDFElementType.TEXT,
177
- options: {fontSize: fontSize, bold, italic, text, underline, alignment, font, color, persistent},
198
+ options: {fontSize: fontSize, bold, italic, text, underline, alignment, font, color, persistent, display},
178
199
  linkedID: linkedID,
179
200
  };
180
201
  }
@@ -215,7 +236,6 @@ export default class PdfText extends PdfElement<Props, State> {
215
236
  render = () => {
216
237
  const {settings, dragging} = this.state, {
217
238
  draggable,
218
- values,
219
239
  defaultPosition,
220
240
  onSaveHistory,
221
241
  persistent
@@ -234,7 +254,7 @@ export default class PdfText extends PdfElement<Props, State> {
234
254
  <div className='pdf-text-container'>
235
255
  <textarea className='pdf-text-input' style={this.getTextStyle()}
236
256
  readOnly={settings.disabled === true}
237
- value={sanitizeHtml(setPdfVariables(settings.text, values))} onChange={this.onChange}
257
+ value={sanitizeHtml(this.getTextValue())} onChange={this.onChange}
238
258
  rows={this.getRows()} onFocus={this.onFocus} onBlur={this.onBlur} onClick={this.onClick}
239
259
  ref={(ref: HTMLTextAreaElement) => {
240
260
  this.field = ref
@@ -33,6 +33,7 @@ interface Props {
33
33
  asCurrency: boolean;
34
34
  autoSelect?: boolean;
35
35
  }
36
+ // TODO Add option to disable symbols (+,-)
36
37
 
37
38
  export default class DvrdNumberInput extends PureComponent<Props> {
38
39
  static defaultProps = {
@@ -91,15 +91,25 @@ export enum PDFElementSubType {INVOICE_TITLE = 'invoice_title'}
91
91
  export enum PDFElementPersist {CONFIRM = 'confirm', PERSISTENT = 'persistent', NOT_PERSISTENT = 'not-persistent'}
92
92
 
93
93
  export enum PdfFont {
94
- LATO = 'lato', MERRIWEATHER = 'merriweather', NOTO_SANS = 'noto-sans', NOTO_SERIF = 'noto-serif',
95
- OPEN_SANS = 'open-sans', PLAYFAIR = 'playfair', PT_SERIF = 'pt-serif', ROBOTO = 'roboto', ROBOTO_MONO = 'roboto-mono',
96
- HELVETICA = 'helvetica', SOURCE_SANS_PRO = 'source-sans-pro'
94
+ LATO = 'lato',
95
+ MERRIWEATHER = 'merriweather',
96
+ NOTO_SANS = 'noto-sans',
97
+ NOTO_SERIF = 'noto-serif',
98
+ OPEN_SANS = 'open-sans',
99
+ PLAYFAIR = 'playfair',
100
+ PT_SERIF = 'pt-serif',
101
+ ROBOTO = 'roboto',
102
+ ROBOTO_MONO = 'roboto-mono',
103
+ HELVETICA = 'helvetica',
104
+ SOURCE_SANS_PRO = 'source-sans-pro'
97
105
  }
98
106
 
99
107
  export enum MediaType {VIDEO, IMAGE}
100
108
 
101
109
  export enum SideMenuMode {COMPACT, FULL}
102
110
 
111
+ export enum PDFDisplay {FIRST_PAGE = 'first_page', LAST_PAGE = 'last_page', ALL_PAGES = 'all_pages'}
112
+
103
113
  // =========== TYPES
104
114
  export type OptionsMenuItem = {
105
115
  label: string;
@@ -139,8 +149,8 @@ export type DefaultPDFElementParams<T extends PDFElementType, O extends IndexedO
139
149
  key: string;
140
150
  linkedID?: string;
141
151
  }>
142
- export type PDFImageParams = { img: File | string | null, persistent: PDFElementPersist; alignment?: ElementPosition };
143
- export type PDFTextParams = { bold: boolean; underline: boolean; italic: boolean; fontSize: number; text: string; alignment?: ElementPosition; disabled?: boolean, font: PdfFont, color: string; persistent: PDFElementPersist };
152
+ export type PDFImageParams = { img: File | string | null, persistent: PDFElementPersist; alignment?: ElementPosition; display?: PDFDisplay };
153
+ export type PDFTextParams = { bold: boolean; underline: boolean; italic: boolean; fontSize: number; text: string; alignment?: ElementPosition; disabled?: boolean, font: PdfFont, color: string; persistent: PDFElementPersist; display?: PDFDisplay };
144
154
  export type PDFInvoiceTableParams = { fontSize: number; widths: number[], font: PdfFont, color: string, alignment?: ElementPosition; persistent: PDFElementPersist };
145
155
  export type PDFInvoiceWidths = { name: number; price: number; quantity: number; subtotal: number }
146
156
  export type PDFTextVariables = { company: IndexedObject<string>; client: IndexedObject<string>; invoice: IndexedObject<string>; }