@vixoniccom/aniversarios 1.2.3-dev.2 → 1.3.0-dev.1

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.
@@ -0,0 +1,30 @@
1
+ name: Sonarqube Analysis
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - development
7
+ pull_request:
8
+ types: [opened, synchronize, reopened]
9
+
10
+ jobs:
11
+ sonarqube:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ with:
16
+ # Disabling shallow clone is recommended for improving relevancy of reporting.
17
+ fetch-depth: 0
18
+
19
+ - name: SonarQube Scan
20
+ uses: sonarsource/sonarqube-scan-action@master
21
+ env:
22
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
23
+ SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
24
+
25
+ - name: SonarQube Quality Gate Check
26
+ uses: sonarsource/sonarqube-quality-gate-action@master
27
+ timeout-minutes: 5
28
+ env:
29
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
30
+ SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
package/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [1.3.0-dev.1](https://github.com/Vixonic/store-aniversarios/compare/v1.3.0-dev.0...v1.3.0-dev.1) (2025-07-14)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * Replace logical OR with nullish coalescing operator for default values in various components ([c9f2bba](https://github.com/Vixonic/store-aniversarios/commit/c9f2bbafcf44f38b1578b6946a19434f41e50f52))
11
+ * Update maskId generation for unique identifiers in AnniversaryImage component ([6f5b452](https://github.com/Vixonic/store-aniversarios/commit/6f5b4525f640d8730488331c56aed5fb68378e56))
12
+ * Update maskId generation for unique identifiers in AnniversaryImage component ([c9a3d43](https://github.com/Vixonic/store-aniversarios/commit/c9a3d43acc57f707a39a31f131fda6266f674f30))
13
+
14
+ ## [1.3.0-dev.0](https://github.com/Vixonic/store-aniversarios/compare/v1.2.3-dev.2...v1.3.0-dev.0) (2025-07-14)
15
+
16
+
17
+ ### Features
18
+
19
+ * Add support for photo mode in settings and related components ([5eeab44](https://github.com/Vixonic/store-aniversarios/commit/5eeab443f73553239c940941fc6740b41601228b))
20
+
5
21
  ### [1.2.3-dev.2](https://github.com/Vixonic/store-aniversarios/compare/v1.2.3-dev.1...v1.2.3-dev.2) (2025-07-11)
6
22
 
7
23
  ### [1.2.3-dev.1](https://github.com/Vixonic/store-aniversarios/compare/v1.2.3-dev.0...v1.2.3-dev.1) (2025-07-09)
package/build.zip CHANGED
Binary file
@@ -25,6 +25,16 @@ export const dataInputs = [
25
25
  serviceType: 'RexmasAnniversarieService',
26
26
  show: serviceEnabled.rexmasServiceEnabled
27
27
  }),
28
+ new SelectInput({
29
+ id: 'photoMode',
30
+ label: 'Modo de fotos',
31
+ items: [
32
+ { label: 'Zip', value: 'zip' },
33
+ { label: 'En linea', value: 'online' }
34
+ ],
35
+ defaultValue: 'zip',
36
+ description: 'Selecciona el modo de fotos. Por defecto, Zip.'
37
+ }),
28
38
  new SelectAssetKna({
29
39
  id: 'photosZip',
30
40
  label: 'Archivo Zip para fotos',
@@ -40,6 +40,23 @@
40
40
  "type": "service-input",
41
41
  "serviceType": "RexmasAnniversarieService"
42
42
  },
43
+ {
44
+ "id": "photoMode",
45
+ "label": "Modo de fotos",
46
+ "type": "select-input",
47
+ "description": "Selecciona el modo de fotos. Por defecto, Zip.",
48
+ "items": [
49
+ {
50
+ "label": "Zip",
51
+ "value": "zip"
52
+ },
53
+ {
54
+ "label": "En linea",
55
+ "value": "online"
56
+ }
57
+ ],
58
+ "defaultValue": "zip"
59
+ },
43
60
  {
44
61
  "id": "photosZip",
45
62
  "label": "Archivo Zip para fotos",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vixoniccom/aniversarios",
3
3
  "alias": "Aniversarios",
4
- "version": "1.2.3-dev.2",
4
+ "version": "1.3.0-dev.1",
5
5
  "description": "Muestra el día que el trabajador está de aniversario en la empresa.",
6
6
  "main": "main.js",
7
7
  "author": "",
@@ -0,0 +1 @@
1
+ sonar.projectKey=Vixonic_store-aniversarios_cb1129c3-491c-4ada-ac60-75ab0fad0c6a
package/src/App.tsx CHANGED
@@ -10,7 +10,7 @@ interface Props {
10
10
  export const App: React.FunctionComponent<Props> = ({ start, appData, anniversaries }) => {
11
11
 
12
12
  const parameters = appData?.parameters
13
- const [aniversariesElements, setAnniversariesElements] = useState<Anniversary[]>(anniversaries)
13
+ const [anniversariesElements, setAnniversariesElements] = useState<Anniversary[]>(anniversaries)
14
14
 
15
15
  useEffect(() => {
16
16
  setAnniversariesElements(anniversaries)
@@ -19,8 +19,8 @@ export const App: React.FunctionComponent<Props> = ({ start, appData, anniversar
19
19
  if (!appData) return null
20
20
 
21
21
  return (
22
- (aniversariesElements.length === 0) ?
22
+ (anniversariesElements.length === 0) ?
23
23
  <FormattedText text={parameters?.defaultMessage ?? 'No hay ingresos para mostrar'} format={parameters?.defaultMessageFormat} />
24
- : <Render appData={appData} start={start} anniversaries={aniversariesElements} />
24
+ : <Render appData={appData} start={start} anniversaries={anniversariesElements} />
25
25
  )
26
26
  }
@@ -20,8 +20,8 @@ export const CircleDate: React.FunctionComponent<Props> = ({ day, month, data })
20
20
  <circle fill={datePrimaryColor} cx='200' cy='200' r='200' />
21
21
  <foreignObject width='400' height='400'>
22
22
  <div style={{ height: 400, width: 400, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
23
- <FormattedText text={AnniveraryDateUtils.getMonth(month, true)} format={Object.assign({}, dateMonthFormat, { fontSize: monthSize })} unit='px' />
24
- <FormattedText text={AnniveraryDateUtils.getZeroLeadedText(day)} format={Object.assign({}, dateDayFormat, { fontSize: daySize })} unit='px' />
23
+ <FormattedText text={AnniveraryDateUtils.getMonth(month, true)} format={{...dateMonthFormat, fontSize: monthSize}} unit='px' />
24
+ <FormattedText text={AnniveraryDateUtils.getZeroLeadedText(day)} format={{...dateDayFormat, fontSize: daySize}} unit='px' />
25
25
  </div>
26
26
  </foreignObject>
27
27
  </g>
@@ -11,8 +11,8 @@ export const FlatDate: React.FunctionComponent<Props> = ({ month, day, data }: P
11
11
  const { abbreviatedMonths, dateDayFormat, dateMonthFormat, orientation, datePrimaryColor } = data.parameters
12
12
 
13
13
  const sizeProp = AnniveraryDateUtils.utils(orientation)
14
- const monthSize = ((dateMonthFormat?.fontSize || 18.5) * 400) / 100
15
- const daySize = ((dateDayFormat?.fontSize || 57.5) * 400) / 100
14
+ const monthSize = ((dateMonthFormat?.fontSize ?? 18.5) * 400) / 100
15
+ const daySize = ((dateDayFormat?.fontSize ?? 57.5) * 400) / 100
16
16
 
17
17
  const getFontFamily = (format: any) => {
18
18
  if (format?.font?.filename) return format.font.filename.replace('.', '-')
@@ -29,7 +29,7 @@ export const FlatDate: React.FunctionComponent<Props> = ({ month, day, data }: P
29
29
  textAnchor='middle'
30
30
  alignmentBaseline='central' x='200' y='55'
31
31
  fontSize={monthSize} preserveAspectRatio='none'
32
- fill={dateMonthFormat?.fontColor || '#fff'} fontSizeAdjust=''>
32
+ fill={dateMonthFormat?.fontColor ?? '#fff'} fontSizeAdjust=''>
33
33
  {AnniveraryDateUtils.getMonth(month, abbreviatedMonths)}
34
34
  </text>
35
35
 
@@ -37,7 +37,7 @@ export const FlatDate: React.FunctionComponent<Props> = ({ month, day, data }: P
37
37
  textAnchor='middle'
38
38
  alignmentBaseline='central' x='200' y='245'
39
39
  fontSize={daySize} preserveAspectRatio='none'
40
- fill={dateDayFormat?.fontColor || '#fff'} fontSizeAdjust=''>
40
+ fill={dateDayFormat?.fontColor ?? '#fff'} fontSizeAdjust=''>
41
41
  {AnniveraryDateUtils.getZeroLeadedText(day)}
42
42
  </text>
43
43
  </g>
@@ -14,11 +14,10 @@ export const OutlineDate: React.FunctionComponent<Props> = ({ day, month, data }
14
14
  const sizeProp = AnniveraryDateUtils.utils(orientation)
15
15
 
16
16
  const parseFormat = (format: any, defaultSize: any) => {
17
- return Object.assign(
18
- {},
19
- format,
20
- { fontSize: format.fontSize || defaultSize }
21
- )
17
+ return {
18
+ ...format,
19
+ fontSize: format.fontSize || defaultSize
20
+ }
22
21
  }
23
22
 
24
23
  const [monthFormatState,] = useState(parseFormat(dateMonthFormat, 20))
@@ -13,11 +13,10 @@ export const TextCalendarDate: React.FunctionComponent<Props> = ({ day, month, d
13
13
  const sizeProp = AnniveraryDateUtils.utils(orientation, '100%')
14
14
 
15
15
  const parseFormat = (format: any, defaultSize: any) => {
16
- return Object.assign(
17
- {},
18
- format,
19
- { fontSize: format.fontSize || defaultSize }
20
- )
16
+ return {
17
+ ...format,
18
+ fontSize: format.fontSize || defaultSize
19
+ }
21
20
  }
22
21
 
23
22
  const [monthFormatState,] = useState(parseFormat(dateMonthFormat, 20))
@@ -12,14 +12,6 @@ const itemStyles = {
12
12
  outlines: OutlineDate
13
13
  }
14
14
 
15
- interface itemStyles {
16
- calendarFlat: string
17
- calendarText: string
18
- circle: string
19
- text: string
20
- outlines: string
21
- }
22
-
23
15
  interface Props {
24
16
  style: keyof typeof itemStyles,
25
17
  day: number,
@@ -2,6 +2,7 @@ import React, { useEffect, useRef, useState } from 'react'
2
2
  import { AnniveraryDateUtils } from '../AnniversaryDate/utils'
3
3
 
4
4
  const defaultImg = require('../default-profile.png')
5
+ let idCounter = 0
5
6
  const borderStyles = {
6
7
  normal: '0',
7
8
  rounded: '10',
@@ -18,7 +19,7 @@ interface Props {
18
19
  export const AnniversaryImage: React.FunctionComponent<Props> = ({ url, size, borderStyle, orientation }) => {
19
20
  const [urlState, setUrlState] = useState(url || defaultImg)
20
21
  const input = useRef<SVGImageElement>(null)
21
- const maskId = `${Math.random() * 10}${Math.random() * 10}${Math.random() * 10}`
22
+ const maskId = `mask-${Date.now()}-${++idCounter}`
22
23
  const imageExist = (url: any) => {
23
24
  const isValidImage = url.substr(-3).toLowerCase() === 'png' || url.substr(-3).toLowerCase() === 'jpg' || url.substr(-4).toLowerCase() === 'jpeg'
24
25
  return isValidImage ? url : defaultImg
@@ -14,11 +14,11 @@ export const ClassicItem: React.FunctionComponent<Props> = ({ anniversary, data
14
14
  const { parameters, downloadsPath } = data
15
15
  const { orientation, separatorColor, separatorWidth, imageSize } = parameters
16
16
  const [margins, setMargins] = useState(parseBorderMargin(parameters.itemMargins))
17
- const [state, setState] = useState(Object.assign({}, parseParameters(parameters)))
17
+ const [state, setState] = useState({...parseParameters(parameters)})
18
18
 
19
19
  useEffect(() => {
20
20
  setMargins(parseBorderMargin(parameters.itemMargins))
21
- setState(Object.assign({}, parseParameters(parameters)))
21
+ setState({...parseParameters(parameters)})
22
22
  }, [])
23
23
 
24
24
  const separatorProps = {
@@ -72,7 +72,7 @@ export const ClassicItem: React.FunctionComponent<Props> = ({ anniversary, data
72
72
  />
73
73
  {state.descriptionEnabled && (
74
74
  <FormattedText
75
- text={anniversary.position || ''}
75
+ text={anniversary.position ?? ''}
76
76
  format={parameters.descriptionFormat}
77
77
  maxChar={Number(parameters.descriptionMaxChar)}
78
78
  lineHeight={1.2}
@@ -80,7 +80,7 @@ export const ClassicItem: React.FunctionComponent<Props> = ({ anniversary, data
80
80
  )}
81
81
  {state.optionalEnabled && (
82
82
  <FormattedText
83
- text={anniversary.optional || ''}
83
+ text={anniversary.optional ?? ''}
84
84
  format={parameters.optionalFormat}
85
85
  maxChar={Number(parameters.descriptionMaxChar)}
86
86
  lineHeight={1.2}
@@ -1,5 +1,3 @@
1
- import React from 'react'
2
-
3
1
  interface Props {
4
2
  order: number | undefined
5
3
  size: number | undefined
@@ -12,12 +10,12 @@ export const Separator = ({ order, size, color, orientation, margins }: Props) =
12
10
  const getSizeStyle = (orientation: any, size: any) => {
13
11
  if (orientation === 'h') {
14
12
  return {
15
- width: size || 0,
13
+ width: size ?? 0,
16
14
  height: '100%'
17
15
  }
18
16
  } else {
19
17
  return {
20
- height: size || 0,
18
+ height: size ?? 0,
21
19
  width: '100%'
22
20
  }
23
21
  }
@@ -29,7 +27,7 @@ export const Separator = ({ order, size, color, orientation, margins }: Props) =
29
27
  <div style={{
30
28
  flexShrink: 0,
31
29
  order: order,
32
- backgroundColor: color || '',
30
+ backgroundColor: color ?? '',
33
31
  margin: margins,
34
32
  ...sizeStyle
35
33
  }} />
@@ -1,11 +1,20 @@
1
1
  export const utils = (orientation: string, size: number) => {
2
2
  const sizeAttr = orientation === 'v' ? 'width' : 'height'
3
- const percentage = size ? `${size}` : orientation === 'v' ? '40%' : '80%'
3
+ let percentage: string
4
+ if (size) {
5
+ percentage = `${size}%`
6
+ } else {
7
+ percentage = orientation === 'v' ? '40%' : '80%'
8
+ }
4
9
  return { [sizeAttr]: percentage }
5
10
  }
6
11
 
7
12
  export const parseBorderMargin = (marginString: any) => {
8
- const pattern = /(( )?[+-]?[0-9]+.?([0-9]+)?(px|em|ex|%|in|cm|mm|pt|pc))?/g
13
+ const numberPattern = '[+-]?[0-9]+\\.?[0-9]*'
14
+ const unitPattern = '(px|em|ex|%|in|cm|mm|pt|pc)'
15
+ const spacePattern = '( )?'
16
+ const fullPattern = `(${spacePattern}${numberPattern}${unitPattern})?`
17
+ const pattern = new RegExp(fullPattern, 'g')
9
18
  const match = marginString ? marginString.match(pattern) : ['']
10
19
 
11
20
  switch (match.length) {
@@ -22,11 +31,11 @@ const parseElementStyles = (margin: string, position: number, defaultPosition: n
22
31
  const { orientation, separator } = parameters
23
32
  const marginAttr = orientation === 'v' ? 'marginBottom' : 'marginRight'
24
33
  const sizeAttr = orientation === 'v' ? 'width' : 'height'
25
- const pos = position !== undefined ? position : defaultPosition
34
+ const pos = position ?? defaultPosition
26
35
  return {
27
36
  order: pos,
28
37
  [sizeAttr]: '100%',
29
- [marginAttr]: margin !== undefined && margin !== '' ? `${margin}%` : pos === 3 || separator === true ? 0 : '4%',
38
+ [marginAttr]: getMarginValue(margin, pos, separator)
30
39
  }
31
40
  }
32
41
 
@@ -37,39 +46,45 @@ export const parseParameters = (parameters: any) => {
37
46
 
38
47
  return {
39
48
  imageEnabled: parameters.imageEnabled,
40
- imageStyle: Object.assign(
41
- {
42
- flexShrink: 0,
43
- display: 'flex',
44
- justifyContent: imageAlignment,
45
- alignItems: imageAlignment,
46
- },
47
- parseElementStyles(parameters.imageMargin, parameters.imagePosition, 1, parameters)
48
- ),
49
+ imageStyle: {
50
+ flexShrink: 0,
51
+ display: 'flex',
52
+ justifyContent: imageAlignment,
53
+ alignItems: imageAlignment,
54
+ ...parseElementStyles(parameters.imageMargin, parameters.imagePosition, 1, parameters)
55
+ },
49
56
  descriptionEnabled: parameters.descriptionEnabled,
50
57
  optionalEnabled: parameters.optionalEnabled,
51
- textStyle: Object.assign(
52
- { display: 'flex', flexDirection: 'column', justifyContent: textAlignment, flex: 1 },
53
- parseElementStyles(parameters.textMargin, parameters.textPosition, 2, parameters)
54
- ),
58
+ textStyle: {
59
+ display: 'flex',
60
+ flexDirection: 'column',
61
+ justifyContent: textAlignment,
62
+ flex: 1,
63
+ ...parseElementStyles(parameters.textMargin, parameters.textPosition, 2, parameters)
64
+ },
55
65
  dateEnabled: parameters.dateEnabled,
56
- dateStyle: Object.assign(
57
- {
58
- display: 'flex',
59
- justifyContent: dateAlignment,
60
- alignItems: dateAlignment,
61
- flexShrink: 0,
62
- },
63
- parseElementStyles(parameters.dateMargin, parameters.datePosition, 3, parameters)
64
- ),
66
+ dateStyle: {
67
+ display: 'flex',
68
+ justifyContent: dateAlignment,
69
+ alignItems: dateAlignment,
70
+ flexShrink: 0,
71
+ ...parseElementStyles(parameters.dateMargin, parameters.datePosition, 3, parameters)
72
+ },
65
73
  }
66
74
  }
67
75
 
68
76
  export const getPhotoUrl = (filename: string, parameters: VixonicParameters, downloadsPath: string) => {
69
- const mode = parameters.photosMode
70
- if (mode === 'zip' && parameters.photosZip && parameters.photosZip.filename !== undefined) {
77
+ const mode = parameters.photoMode
78
+ if (mode === 'zip' && parameters.photosZip?.filename !== undefined) {
71
79
  return downloadsPath + '/' + parameters.photosZip.filename.replace('.zip', '/') + filename
72
80
  } else {
73
81
  return filename
74
82
  }
75
83
  }
84
+
85
+ const getMarginValue = (margin: string, pos: number, separator?: boolean): string | number => {
86
+ if (margin !== undefined && margin !== '') {
87
+ return `${margin}%`;
88
+ }
89
+ return pos === 3 || separator === true ? 0 : '4%';
90
+ };
@@ -1,5 +1,3 @@
1
- import PropTypes from 'prop-types'
2
-
3
1
  interface Props {
4
2
  paths: Array<string>
5
3
  data: VixonicData
@@ -40,13 +38,3 @@ export const FontLoader = ({ paths, data }: Props) => {
40
38
  <style>{fonts}</style>
41
39
  )
42
40
  }
43
-
44
- FontLoader.defaultProps = {
45
- paths: []
46
- }
47
-
48
- FontLoader.propTypes = {
49
- paths: PropTypes.arrayOf(PropTypes.string).isRequired,
50
- data: PropTypes.object.isRequired
51
- }
52
-
@@ -1,4 +1,4 @@
1
- import React from 'react'
1
+ import React, { CSSProperties } from 'react'
2
2
 
3
3
  const alignments = {
4
4
  center: 'center',
@@ -15,7 +15,7 @@ interface Props {
15
15
  format?: any
16
16
  lineHeight?: number
17
17
  maxChar?: number
18
- style?: number
18
+ style?: CSSProperties
19
19
  text: string
20
20
  unit?: string
21
21
  paddingBottom?: string
@@ -25,7 +25,7 @@ interface Props {
25
25
  export const FormattedText: React.FunctionComponent<Props> = ({ text, format, maxChar, lineHeight, style, unit, paddingBottom, paddingTop }) => {
26
26
  const trimText = (text: any, maxChar: any) => {
27
27
  const isValid = maxChar && maxChar >= 3
28
- if (isValid && (text && text.length > maxChar) || false) {
28
+ if (isValid && (text && text.length > maxChar)) {
29
29
  const returnText = text.substring(0, maxChar - 3)
30
30
  returnText.substr(-1, 3)
31
31
  return `${returnText.trim()}...`
@@ -35,7 +35,7 @@ export const FormattedText: React.FunctionComponent<Props> = ({ text, format, ma
35
35
 
36
36
  const checkNested = (obj: any, path: string): boolean => {
37
37
  return path.split('.').every(segment => {
38
- if (obj && obj.hasOwnProperty(segment)) {
38
+ if (obj?.hasOwnProperty(segment)) {
39
39
  obj = obj[segment]
40
40
  return true
41
41
  }
@@ -52,10 +52,11 @@ export const FormattedText: React.FunctionComponent<Props> = ({ text, format, ma
52
52
  }
53
53
 
54
54
  const renderText = maxChar ? trimText(text, maxChar) : text
55
- const containerStyle = Object.assign({
55
+ const containerStyle = {
56
56
  display: 'inline-flex',
57
- justifyContent: getHorizontalAlignment(format.alignment)
58
- }, style)
57
+ justifyContent: getHorizontalAlignment(format.alignment),
58
+ ...style
59
+ }
59
60
 
60
61
  return (
61
62
  <div style={containerStyle}>
@@ -16,9 +16,21 @@ interface Props {
16
16
  style: any
17
17
  }
18
18
 
19
+
20
+
19
21
  export const Item = ({ width, height, containerData, verticalGap, horizontalGap, children, style }: Props) => {
20
22
  const itemRef = useRef(null)
21
23
 
24
+ let topPosition = '0';
25
+ if (containerData.ic_rowIndex !== 0) {
26
+ topPosition = verticalGap ? `${verticalGap * containerData.ic_rowIndex}%` : '0';
27
+ }
28
+
29
+ let leftPadding = '0'
30
+ if (containerData.ic_columnIndex !== 0) {
31
+ leftPadding = horizontalGap ? `${horizontalGap}%` : '0';
32
+ }
33
+
22
34
  return (
23
35
  <div ref={itemRef}
24
36
  style={{
@@ -29,13 +41,9 @@ export const Item = ({ width, height, containerData, verticalGap, horizontalGap,
29
41
  justifyContent: aligments['center'],
30
42
  width: width,
31
43
  height: height,
32
- top: containerData.ic_rowIndex === 0
33
- ? '0'
34
- : verticalGap ? `${verticalGap * containerData.ic_rowIndex}%` : '0',
35
- paddingLeft: containerData.ic_columnIndex === 0
36
- ? '0'
37
- : horizontalGap ? `${horizontalGap}%` : '0'
38
- , ...style
44
+ top: topPosition,
45
+ paddingLeft: leftPadding,
46
+ ...style
39
47
  }}
40
48
  >
41
49
  {React.cloneElement(children, containerData)}
@@ -75,10 +75,10 @@ export class AnimationController {
75
75
 
76
76
  configure(options: Partial<Options>) {
77
77
  this.mode = options.mode && animationModes.hasOwnProperty(options.mode) ? animationModes[options.mode] : animationModes.fade
78
- this.duration = options.duration || 10000
79
- this.speed = 1000 * (options.speed || 1)
80
- this.stagger = this.speed / (options.stagger || 4)
81
- this.reverse = options.reverse !== undefined ? options.reverse : true
78
+ this.duration = options.duration ?? 10000
79
+ this.speed = 1000 * (options.speed ?? 1)
80
+ this.stagger = this.speed / (options.stagger ?? 4)
81
+ this.reverse = options.reverse ?? true
82
82
  }
83
83
 
84
84
  getInitialStyle() {
@@ -96,31 +96,27 @@ export class AnimationController {
96
96
  autoplay: false,
97
97
  })
98
98
  animation.add(
99
- Object.assign(
100
- {
101
- targets: els,
102
- duration: this.speed,
103
- delay: function (_el: any, i: any, _l: any) {
104
- return i * self.stagger
105
- },
99
+ {
100
+ targets: els,
101
+ duration: this.speed,
102
+ delay: function (_el: any, i: any, _l: any) {
103
+ return i * self.stagger
106
104
  },
107
- this.mode.in
108
- )
105
+ ...this.mode.in
106
+ }
109
107
  )
110
108
  animation.add(
111
- Object.assign(
112
- {
113
- targets: els,
114
- duration: this.speed,
115
- delay: function (_el: any, _i: any, _l: any) {
116
- return _i * self.stagger
117
- },
118
- complete: () => {
119
- finished()
120
- },
109
+ {
110
+ targets: els,
111
+ duration: this.speed,
112
+ delay: function (_el: any, _i: any, _l: any) {
113
+ return _i * self.stagger
121
114
  },
122
- this.mode.out
123
- ),
115
+ complete: () => {
116
+ finished()
117
+ },
118
+ ...this.mode.out
119
+ },
124
120
  `+=${offset}`
125
121
  )
126
122
  animation.play()
@@ -21,11 +21,11 @@ export const Render = ({ start, appData, anniversaries }: Props) => {
21
21
  animationTime,
22
22
  } = parameters
23
23
 
24
- const backgroundImageState = backgroundImage && backgroundImage.filename
24
+ const backgroundImageState = backgroundImage?.filename
25
25
  ? `url("${downloadsPath}/${backgroundImage.filename}")` : ''
26
26
 
27
27
  const anniversaryItems = anniversaries.map((anniversary: Anniversary) => {
28
- return <AnniversaryItem style={'standard'} anniversary={anniversary} data={appData} />
28
+ return <AnniversaryItem style={'standard'} anniversary={anniversary} data={appData} key={anniversary?.name} />
29
29
  })
30
30
 
31
31
  return (
package/src/index.html CHANGED
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html style="position: absolute; height:100%; width: 100%; overflow: hidden;">
2
+ <html lang="es" xml:lang="es" style="position: absolute; height:100%; width: 100%; overflow: hidden;">
3
3
  <head>
4
4
  <title></title>
5
5
  <meta charset="utf-8">
@@ -5,5 +5,5 @@ declare type VixonicData = {
5
5
  }
6
6
 
7
7
  declare type VixonicParameters = Partial<{
8
- displayService: 'AnniversaryAppService' | 'RexmasAnniversarieService', documentService: { id: string }, rexmasService: { id: string }, photosZip: {id?: string, filename?: string, extension?: string}, updateTime: 600000 | 1800000 | 3600000 | 21600000 | 43200000 | 86400000 | 604800000, defaultMessage: string, defaultMessageFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, orientation: 'h' | 'v', animationMode: 'fade' | 'slideRight' | 'slideLeft', animationSpeed: 2 | 1.5 | 1, animationOrder: boolean, animationTime: number, containerColumns: number, containerColumnsGap: number, containerRows: number, containerRowsGap: number, backgroundImage: {id?: string, filename?: string, extension?: string}, padding: string, textPosition: 1 | 2 | 3, textAlignment: 'start' | 'center' | 'end', nameFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, nameMaxChar: number, textMargin: string, descriptionEnabled: boolean, descriptionFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, descriptionMaxChar: number, optionalEnabled: boolean, optionalFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, imageEnabled: boolean, imagePosition: 1 | 2 | 3, imageAlignment: 'start' | 'center' | 'end', imageStyle: 'normal' | 'rounded' | 'circle', imageMargin: string, imageSize: number, dateEnabled: boolean, datePosition: 1 | 2 | 3, dateAlignment: 'start' | 'center' | 'end', dateStyle: 'calendarFlat' | 'calendarText' | 'circle' | 'text' | 'outlines', dateDayFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, dateMonthFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, abbreviatedMonths: boolean, datePrimaryColor: string, dateMargin: string, separator: boolean, separatorWidth: number, separatorColor: string, itemMargins: string
8
+ displayService: 'AnniversaryAppService' | 'RexmasAnniversarieService', documentService: { id: string }, rexmasService: { id: string }, photoMode: 'zip' | 'online', photosZip: {id?: string, filename?: string, extension?: string}, updateTime: 600000 | 1800000 | 3600000 | 21600000 | 43200000 | 86400000 | 604800000, defaultMessage: string, defaultMessageFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, orientation: 'h' | 'v', animationMode: 'fade' | 'slideRight' | 'slideLeft', animationSpeed: 2 | 1.5 | 1, animationOrder: boolean, animationTime: number, containerColumns: number, containerColumnsGap: number, containerRows: number, containerRowsGap: number, backgroundImage: {id?: string, filename?: string, extension?: string}, padding: string, textPosition: 1 | 2 | 3, textAlignment: 'start' | 'center' | 'end', nameFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, nameMaxChar: number, textMargin: string, descriptionEnabled: boolean, descriptionFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, descriptionMaxChar: number, optionalEnabled: boolean, optionalFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, imageEnabled: boolean, imagePosition: 1 | 2 | 3, imageAlignment: 'start' | 'center' | 'end', imageStyle: 'normal' | 'rounded' | 'circle', imageMargin: string, imageSize: number, dateEnabled: boolean, datePosition: 1 | 2 | 3, dateAlignment: 'start' | 'center' | 'end', dateStyle: 'calendarFlat' | 'calendarText' | 'circle' | 'text' | 'outlines', dateDayFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, dateMonthFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, abbreviatedMonths: boolean, datePrimaryColor: string, dateMargin: string, separator: boolean, separatorWidth: number, separatorColor: string, itemMargins: string
9
9
  }>