@vixoniccom/menu-daily 0.2.0-dev.1 → 0.2.0-dev.3

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/build.zip CHANGED
Binary file
@@ -1,11 +1,28 @@
1
- import { ServiceInput, TextInput } from '@vixoniccom/modules'
1
+ import { SelectInput, ServiceInput, TextInput } from '@vixoniccom/modules'
2
2
 
3
3
  export const dataInputs = [
4
+ new SelectInput({
5
+ id: 'menuServiceProvider',
6
+ label: 'Origen de los datos',
7
+ items: [
8
+ { value: 'google', label: 'Google Sheets' },
9
+ { value: 'excel', label: 'Microsoft Excel' },
10
+ ],
11
+ defaultValue: 'google',
12
+ }),
4
13
  new ServiceInput({
5
14
  id: 'menuService',
6
15
  label: 'Hoja de cálculo de Google Sheets con el menú',
7
16
  serviceType: 'MenuAppService',
8
17
  required: true,
18
+ show: `{{menuServiceProvider}} !== 'excel'`,
19
+ }),
20
+ new ServiceInput({
21
+ id: 'excelMenuService',
22
+ label: 'Libro de Excel de Microsoft con el menú',
23
+ serviceType: 'MenuAppService',
24
+ required: true,
25
+ show: `{{menuServiceProvider}} === 'excel'`,
9
26
  }),
10
27
  new TextInput({
11
28
  id: 'mealType',
@@ -5,9 +5,34 @@
5
5
  "label": "Datos",
6
6
  "type": "group",
7
7
  "items": [
8
+ {
9
+ "id": "menuServiceProvider",
10
+ "label": "Origen de los datos",
11
+ "type": "select-input",
12
+ "items": [
13
+ {
14
+ "value": "google",
15
+ "label": "Google Sheets"
16
+ },
17
+ {
18
+ "value": "excel",
19
+ "label": "Microsoft Excel"
20
+ }
21
+ ],
22
+ "defaultValue": "google"
23
+ },
8
24
  {
9
25
  "id": "menuService",
10
26
  "label": "Hoja de cálculo de Google Sheets con el menú",
27
+ "show": "{{menuServiceProvider}} !== 'excel'",
28
+ "type": "service-input",
29
+ "serviceType": "MenuAppService",
30
+ "required": true
31
+ },
32
+ {
33
+ "id": "excelMenuService",
34
+ "label": "Libro de Excel de Microsoft con el menú",
35
+ "show": "{{menuServiceProvider}} === 'excel'",
11
36
  "type": "service-input",
12
37
  "serviceType": "MenuAppService",
13
38
  "required": true
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "author": {
11
11
  "name": ""
12
12
  },
13
- "version": "0.2.0-dev.1",
13
+ "version": "0.2.0-dev.3",
14
14
  "scripts": {
15
15
  "prepublish": "vixonic-module-packager --mode build",
16
16
  "watch": "vixonic-module-packager --mode watch",
package/src/logger.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export const LOGGER_PROPERTY = 'vxAppLogger'
2
2
  class Logger {
3
3
  log(message: any, ...optionalParams: any[]) {
4
- if ((window as any)[LOGGER_PROPERTY] === true) {
4
+ if ((globalThis.window as any)[LOGGER_PROPERTY] === true) {
5
5
  if (optionalParams && optionalParams.length > 0) console.log(message, optionalParams)
6
6
  else console.log(message)
7
7
  }
@@ -1,31 +1,9 @@
1
1
  declare type VixonicData = {
2
2
  downloadsPath: string
3
- services: { [key: string]: { data?: any; updatedAt?: number } }
3
+ services: { [key: string]: { data?: any, updatedAt?: number } }
4
4
  parameters: VixonicParameters
5
5
  }
6
6
 
7
7
  declare type VixonicParameters = Partial<{
8
- menuService: { id: string }
9
- mealType: string
10
- msj0: string
11
- animationDuration: number
12
- animationMode: 'fade' | 'slideRight' | 'slideLeft'
13
- containerGridColumns: number
14
- containerGridColumnsGap: number
15
- containerGridRows: number
16
- containerGridRowsGap: number
17
- containerGridMargins: string
18
- backgroundImage: { id?: string; filename?: string; extension?: string }
19
- itemGridRows: number
20
- itemGridMargins: string
21
- itemAnimationDuration: number
22
- itemTitleTextFormat: { fontSize?: number; fontColor?: string; alignment?: { horizontal?: 'left' | 'right' | 'center' }; font?: { filename: string; id: string; __isAsset: true } }
23
- itemTitleBackgroundColor: string
24
- itemOptionsTextFormat: {
25
- fontSize?: number
26
- fontColor?: string
27
- alignment?: { horizontal?: 'left' | 'right' | 'center' }
28
- font?: { filename: string; id: string; __isAsset: true }
29
- }
30
- itemStyle: 'standard' | 'modern' | 'framed'
31
- }>
8
+ menuServiceProvider: 'google' | 'excel', menuService: { id: string }, excelMenuService: { id: string }, mealType: string, msj0: string, animationDuration: number, animationMode: 'fade' | 'slideRight' | 'slideLeft', containerGridColumns: number, containerGridColumnsGap: number, containerGridRows: number, containerGridRowsGap: number, containerGridMargins: string, backgroundImage: {id?: string, filename?: string, extension?: string}, itemGridRows: number, itemGridMargins: string, itemAnimationDuration: number, itemTitleTextFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, itemTitleBackgroundColor: string, itemOptionsTextFormat: { fontSize?: number, fontColor?: string, alignment?: { horizontal?: 'left' | 'right' | 'center' }, font?: { filename: string, id: string, __isAsset: true } }, itemStyle: 'standard' | 'modern' | 'framed'
9
+ }>
@@ -15,9 +15,12 @@ type TodayMenu = {
15
15
  error?: string
16
16
  }
17
17
 
18
+ const selectedServiceId = ({ menuServiceProvider, menuService, excelMenuService }: VixonicParameters): string | undefined =>
19
+ (menuServiceProvider === 'excel' ? excelMenuService : menuService)?.id
20
+
18
21
  const resolveTodayMenu = (vixonicData: VixonicData): TodayMenu => {
19
22
  const { parameters, services } = vixonicData
20
- const serviceId = parameters.menuService?.id
23
+ const serviceId = selectedServiceId(parameters)
21
24
  const serviceData = serviceId ? (services?.[serviceId]?.data as MenuAppServiceData | undefined) : undefined
22
25
 
23
26
  if (!serviceData) return { status: 'loading' }
@@ -35,7 +38,7 @@ const resolveTodayMenu = (vixonicData: VixonicData): TodayMenu => {
35
38
  }
36
39
 
37
40
  class App extends React.Component<AppProps> {
38
- render () {
41
+ render() {
39
42
  const { parameters, downloadsPath } = this.props.vixonicData
40
43
  let cycle = parameters.animationDuration && parameters.animationDuration * 1000 || 15000
41
44
  const { status, data, error } = resolveTodayMenu(this.props.vixonicData)
@@ -45,13 +48,29 @@ class App extends React.Component<AppProps> {
45
48
  position: 'absolute',
46
49
  top: 0, right: 0, bottom: 0, left: 0,
47
50
  backgroundImage: parameters.backgroundImage &&
48
- `url("${downloadsPath + '/' + parameters.backgroundImage.filename}")` || undefined,
51
+ `url("${downloadsPath + '/' + parameters.backgroundImage.filename}")` || undefined,
49
52
  backgroundSize: '100% 100%',
50
53
  padding: parameters.containerGridMargins
51
54
  }}>
52
- {
53
- !data?.[0] ?
54
- <div style={{width: '100%', height: '100%', display: 'flex', fontSize: `${100 / (parameters.itemGridRows || 1)}vmin`, justifyContent: 'center', alignItems: 'center'}}>
55
+ {data?.[0] ?
56
+ <Grid
57
+ animate={this.props.start}
58
+ style={{ width: '100%', height: '100%' }}
59
+ items={data.map((meal) => (<MealContainer key={meal.type} data={meal} interval={cycle} vixonicData={this.props.vixonicData} />))}
60
+ animationConfig={{
61
+ mode: parameters.animationMode || 'fade',
62
+ duration: cycle
63
+ }} layout={{
64
+ alignment: {
65
+ h: 'start',
66
+ v: 'center'
67
+ },
68
+ columns: parameters.containerGridColumns || 1,
69
+ columnsGap: parameters.containerGridColumnsGap || 0,
70
+ rows: parameters.containerGridRows || 1,
71
+ rowsGap: parameters.containerGridRowsGap || 0
72
+ }} /> :
73
+ <div style={{ width: '100%', height: '100%', display: 'flex', fontSize: `${100 / (parameters.itemGridRows || 1)}vmin`, justifyContent: 'center', alignItems: 'center' }}>
55
74
  <FormattedText
56
75
  text={placeholder}
57
76
  defaults={{
@@ -59,31 +78,13 @@ class App extends React.Component<AppProps> {
59
78
  fontColor: 'black',
60
79
  fontSize: 10
61
80
  }}
62
- style={{width: '100%'}}
81
+ style={{ width: '100%' }}
63
82
  format={parameters.itemOptionsTextFormat || {}}
64
- unit='%'/>
65
- </div> :
66
- <Grid
67
- id='container'
68
- animate={this.props.start}
69
- style={{width: '100%', height: '100%'}}
70
- items={data.map((meal) => (<MealContainer key={meal.type} data={meal} interval={cycle} vixonicData={this.props.vixonicData} />))}
71
- animation={{
72
- mode: parameters.animationMode || 'fade',
73
- duration: cycle
74
- }} layout={{
75
- alignment: {
76
- h: 'start',
77
- v: 'center'
78
- },
79
- columns: parameters.containerGridColumns || 1,
80
- columnsGap: parameters.containerGridColumnsGap || 0,
81
- rows: parameters.containerGridRows || 1,
82
- rowsGap: parameters.containerGridRowsGap || 0
83
- }}/>
84
- }
85
- <FontLoader downloadPath={downloadsPath} fonts={fontParser(parameters)}/>
86
- </div>
83
+ unit='%' />
84
+ </div>
85
+ }
86
+ <FontLoader downloadPath={downloadsPath} fonts={fontParser(parameters)} />
87
+ </div>
87
88
  }
88
89
  }
89
90
 
@@ -22,13 +22,15 @@ type Props = {
22
22
  }
23
23
 
24
24
  class FormattedText extends React.Component<Props> {
25
- render () {
26
- let { format, defaults } = this.props
27
- let { alignment, font, fontColor, fontSize } = format
28
- let containerStyle = Object.assign({
25
+ render() {
26
+ const { format, defaults } = this.props
27
+ const { alignment, font, fontColor, fontSize } = format
28
+ const containerStyle = {
29
29
  display: 'inline-flex',
30
- justifyContent: this.getHorizontalAlignment(alignment?.horizontal || defaults.alignment)
31
- }, this.props.style)
30
+ justifyContent: this.getHorizontalAlignment(alignment?.horizontal || defaults.alignment),
31
+ ...this.props.style
32
+ }
33
+
32
34
  return <div style={containerStyle}>
33
35
  <span style={{
34
36
  color: fontColor || defaults.fontColor,
@@ -44,7 +46,7 @@ class FormattedText extends React.Component<Props> {
44
46
  </div>
45
47
  }
46
48
 
47
- getHorizontalAlignment (alignment: any) {
49
+ getHorizontalAlignment(alignment: any) {
48
50
  if (alignment) {
49
51
  return alignments.hasOwnProperty(alignment) ? (alignments as any)[alignment] : 'flex-start'
50
52
  }
@@ -4,14 +4,14 @@ import Item from './GridItem'
4
4
 
5
5
  type GridProps = {
6
6
  animate: boolean,
7
- animation: {
7
+ animationConfig: {
8
8
  mode: 'fade' | 'slideLeft' | 'slideRight',
9
9
  duration: number,
10
10
  speed?: number,
11
11
  stagger?: number,
12
12
  reverse?: boolean
13
13
  },
14
- layout: {
14
+ layout: Readonly<{
15
15
  rows: number,
16
16
  rowsGap?: number,
17
17
  columns: number,
@@ -20,10 +20,9 @@ type GridProps = {
20
20
  h: 'start' | 'center' | 'end',
21
21
  v: 'start' | 'center' | 'end'
22
22
  }
23
- }
23
+ }>
24
24
  style?: React.CSSProperties
25
25
  fontSize?: string
26
- id: string
27
26
  items: React.ReactNode[]
28
27
  }
29
28
 
@@ -54,39 +53,42 @@ class Grid extends React.Component<GridProps, GridState> {
54
53
  items: []
55
54
  }
56
55
 
57
- constructor (props: GridProps) {
58
- super (props)
56
+ constructor(props: GridProps) {
57
+ super(props)
59
58
  this.lastIndex = 0
60
59
  this.animation = new AnimationController()
61
60
  }
62
61
 
63
- componentDidMount () {
64
- this.configure(this.props)
62
+ componentDidMount() {
63
+ this.configure()
65
64
  }
66
65
 
67
- componentWillUnmount () {
66
+ componentWillUnmount() {
68
67
  this.unmounting = true
69
68
  }
70
69
 
71
- configure (props: GridProps) {
72
- this.animation.configure(props.animation)
73
- this.columns = props.layout.columns || 1
74
- this.columnsGap = props.layout.columnsGap || 0
75
- this.rows = props.layout.rows || 1
76
- this.rowsGap = props.layout.rowsGap || 0
70
+ configure() {
71
+ const { animationConfig, layout, animate } = this.props
72
+ this.animation.configure(animationConfig)
73
+ this.columns = layout.columns || 1
74
+ this.columnsGap = layout.columnsGap || 0
75
+ this.rows = layout.rows || 1
76
+ this.rowsGap = layout.rowsGap || 0
77
77
  this.itemsCount = this.rows * this.columns
78
- if (props.animate && !this.animating && this.state.stage === 'idle') {
78
+ if (animate && !this.animating && this.state.stage === 'idle') {
79
79
  this.animating = true
80
- this.createItems(props)
80
+ this.createItems()
81
81
  }
82
82
  }
83
83
 
84
84
  // Filter items by index and create the proper item within its container.
85
- createItems (props: GridProps) {
86
- if (!props.items) return
85
+ createItems() {
86
+ const { items, layout } = this.props
87
+ if (!items) return
88
+
87
89
  let count = 0
88
- this.lastIndex = this.lastIndex < props.items.length ? this.lastIndex : 0
89
- let newItems = props.items.filter((_item, index) => {
90
+ this.lastIndex = this.lastIndex < items.length ? this.lastIndex : 0
91
+ const newItems = items.filter((_item, index) => {
90
92
  return index >= this.lastIndex
91
93
  }).map((item, index, arr) => {
92
94
  if (count >= this.itemsCount) return null
@@ -101,7 +103,7 @@ class Grid extends React.Component<GridProps, GridState> {
101
103
  ic_lastChild: index === (arr.length - 1)
102
104
  }} style={this.animation.getInitialStyle()}
103
105
  // Item alignment. By default is center - center.
104
- alignment={props.layout.alignment}
106
+ alignment={layout.alignment}
105
107
  // Setup item width based on columns count.
106
108
  width={(100 - (this.columnsGap * (this.columns - 1))) / this.columns}
107
109
  // Setup item height based on rows count. If 0 set up on auto.
@@ -129,7 +131,7 @@ class Grid extends React.Component<GridProps, GridState> {
129
131
  }
130
132
  }
131
133
 
132
- render () {
134
+ render() {
133
135
  return <div ref={(container) => { this.container = container }} style={{
134
136
  opacity: this.state.show ? 1 : 0,
135
137
  position: 'relative',
@@ -142,14 +144,14 @@ class Grid extends React.Component<GridProps, GridState> {
142
144
  </div>
143
145
  }
144
146
 
145
- componentDidUpdate (prevProps: GridProps) {
147
+ componentDidUpdate(prevProps: GridProps) {
146
148
  if (prevProps !== this.props) {
147
- this.configure(this.props)
149
+ this.configure()
148
150
  }
149
151
  if (this.props.animate && this.state.stage === 'prepared') {
150
152
  // Start animations.
151
153
  this.animation.animate(this.container!.childNodes, () => {
152
- !this.unmounting && this.createItems(this.props)
154
+ !this.unmounting && this.createItems()
153
155
  })
154
156
  this.setState({
155
157
  stage: 'animating'
@@ -41,13 +41,23 @@ class GridItem extends React.Component<GridItemProps, any> {
41
41
  this.setState({height: this.el.offsetHeight})
42
42
  }
43
43
 
44
- componentWillReceiveProps () {
45
- this.setState({ height: this.el.offsetHeight })
44
+ componentDidUpdate () {
45
+ const height = this.el.offsetHeight
46
+ if (height !== this.state.height) {
47
+ this.setState({ height })
48
+ }
46
49
  }
47
50
 
48
51
  render () {
49
- let props = this.props
50
- let style: React.CSSProperties = {
52
+ const props = this.props
53
+ const { ic_rowIndex, ic_columnIndex } = props.containerData
54
+ const top = ic_rowIndex > 0 && props.verticalGap
55
+ ? `${props.verticalGap * ic_rowIndex}%`
56
+ : '0'
57
+ const paddingLeft = ic_columnIndex > 0 && props.horizontalGap
58
+ ? `${props.horizontalGap}%`
59
+ : '0'
60
+ const style: React.CSSProperties = {
51
61
  overflow: 'hidden',
52
62
  display: 'flex',
53
63
  position: 'relative',
@@ -56,16 +66,8 @@ class GridItem extends React.Component<GridItemProps, any> {
56
66
  width: `${props.width}%`,
57
67
  height: `${props.height}%`,
58
68
  fontSize: this.props.fontSize || this.state.height && `${this.state.height}px`,
59
- top: props.containerData.ic_rowIndex === 0
60
- ? '0'
61
- : props.verticalGap
62
- ? `${props.verticalGap * props.containerData.ic_rowIndex}%`
63
- : '0',
64
- paddingLeft: props.containerData.ic_columnIndex === 0
65
- ? '0'
66
- : props.horizontalGap
67
- ? `${props.horizontalGap}%`
68
- : '0',
69
+ top,
70
+ paddingLeft,
69
71
  ...props.style
70
72
  }
71
73
  return <div style={style}
@@ -29,16 +29,17 @@ class Title extends React.Component<Props> {
29
29
  }
30
30
 
31
31
  componentDidMount() {
32
- this.setup(this.props)
32
+ this.setup()
33
33
  }
34
34
 
35
- setup(props: Props) {
36
- const { parameters } = props.vixonicData
35
+ setup() {
36
+ const { vixonicData, getPadding } = this.props
37
+ const { parameters } = vixonicData
37
38
  if (parameters.itemStyle && TitleStyles[parameters.itemStyle]) {
38
39
  this.style = TitleStyles[parameters.itemStyle]
39
40
  }
40
41
  const fontSize = parameters.itemTitleTextFormat?.fontSize
41
- props.getPadding(this.style.getPadding(fontSize || defaultFontSize))
42
+ getPadding(this.style.getPadding(fontSize || defaultFontSize))
42
43
  }
43
44
 
44
45
  render() {
@@ -38,10 +38,9 @@ export default class MealContainer extends React.Component<Props, any> {
38
38
  padding: parameters.itemGridMargins || this.state.padding
39
39
  }}
40
40
  fontSize='inherit'
41
- id={data.type}
42
41
  items={data.options.map((option) => (<OptionItem key={option} data={option} vixonicData={vixonicData} />))}
43
42
  animate={true}
44
- animation={{
43
+ animationConfig={{
45
44
  mode: parameters.animationMode || 'fade',
46
45
  duration: cycle
47
46
  }}
@@ -1,31 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(find /home/danielalvayail/repos/server-ruffo -type f -name \"package.json\" -o -name \"tsconfig.json\" -o -name \".gitmodules\" | head -20)",
5
- "Read(//home/danielalvayail/repos/server-ruffo/**)",
6
- "Bash(grep -n \"insertAgendaApp\\\\|insertBirthdayApp\\\\|insertSheetsReader\\\\|insertLocalAppSheets\\\\|__resolveType\\\\|AgendaAppService\\\\|implements Service\\\\|gql\\\\`\" src/schema/modules/services/index.ts)",
7
- "Bash(npx tsc *)",
8
- "Bash(echo \"exit=$? \\(vacío = sin errores en esos archivos relativos a MenuAppService\\)\")",
9
- "Bash(echo \"exit=$? \\(vacío = sin errores que mencionen Menu/MenuApp\\)\")",
10
- "Bash(xargs ls -lh)",
11
- "Bash(echo \"exit=$? \\(vacío = sin errores que mencionen MenuApp/MenuAppForm\\)\")",
12
- "Bash(echo \"exit=$? \\(vacío = sin errores en esos archivos\\)\")",
13
- "Bash(node -e \"JSON.parse\\(require\\('fs'\\).readFileSync\\('src/i18n/locales/es.json','utf8'\\)\\); console.log\\('es.json OK'\\)\")",
14
- "Bash(python3 -c \"import json; json.load\\(open\\('src/i18n/locales/es.json'\\)\\); print\\('es.json OK'\\)\")",
15
- "Bash(find /home/danielalvayail/repos/apps/store-birthdays -type f \\\\\\( -name \"*.ts\" -o -name \"*.tsx\" -o -name \"*.json\" -o -name \"*.d.ts\" \\\\\\) | head -30)",
16
- "Read(//home/danielalvayail/repos/apps/store-birthdays/**)",
17
- "Bash(python3 -c \"import json; d=json.load\\(open\\('src/test/services.json'\\)\\); k=list\\(d['services']\\)[0]; print\\('services.json OK — id:', k\\); print\\('hojas:', list\\(d['services'][k]['data']['menus']\\)\\)\")",
18
- "Bash(python3 -c \"import json; p=json.load\\(open\\('src/test/parameters.json'\\)\\); print\\('parameters menuService.id:', p['parameters']['menuService']['id']\\)\")",
19
- "Bash(python3 -c \"import json; d=json.load\\(open\\('src/test/services.json'\\)\\); print\\('services.json OK, primer date AMANECIDA:', d['services']['38c3df7c-fb9e-e5a5-489a-d6e31048c2d3']['data']['menus']['AMANECIDA'][0]['date']\\)\")",
20
- "Read(//home/danielalvayail/.nvm/versions/node/**)",
21
- "Bash(command -v nodejs)",
22
- "Bash(node -e \"const r=require\\('./node_modules/react'\\); console.log\\('SFC=',typeof r.SFC,'StatelessComponent=',typeof r.StatelessComponent\\)\")",
23
- "Bash(git add *)",
24
- "Bash(git commit -m ' *)",
25
- "Bash(git push *)",
26
- "Bash(command -v nvm)",
27
- "Read(//usr/local/bin/**)",
28
- "Bash(bash -lc 'which node')"
29
- ]
30
- }
31
- }
@@ -1,3 +0,0 @@
1
- {
2
- "js/ts.tsdk.path": "node_modules/typescript/lib"
3
- }