ywana-core8 0.0.572 → 0.0.575

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": "ywana-core8",
3
- "version": "0.0.572",
3
+ "version": "0.0.575",
4
4
  "description": "ywana-core8",
5
5
  "homepage": "https://ywana.github.io/workspace",
6
6
  "author": "Ernesto Roldan Garcia",
@@ -47,3 +47,4 @@ main.collection-page>.content-editor {
47
47
  flex: 1;
48
48
  }
49
49
 
50
+
@@ -393,7 +393,7 @@ export const MultiSelectionEditor = ({ field, value = [], content, onChange }) =
393
393
  */
394
394
  export const CollectionEditor = ({ field, value = [], onChange, onReload }) => {
395
395
 
396
- const { id, item, label, Feeder, Renderer, Adder = true, editable = true } = field
396
+ const { id, item, label, groupBy="field1", Feeder, Renderer, Adder = true, editable = true } = field
397
397
 
398
398
  function add(rows) {
399
399
  if (onChange) {
@@ -421,7 +421,7 @@ export const CollectionEditor = ({ field, value = [], onChange, onReload }) => {
421
421
  if (onReload) onReload()
422
422
  }
423
423
 
424
- const columns = Object.values(item)
424
+ /* const columns = Object.values(item)
425
425
  .filter(field => field.column === true)
426
426
  .map((item) => ({ ...item, onChange: change }))
427
427
  columns.push({ id: 'actions', label: 'Actions' })
@@ -435,6 +435,7 @@ export const CollectionEditor = ({ field, value = [], onChange, onReload }) => {
435
435
  }))
436
436
 
437
437
  const table = { columns, rows }
438
+ */
438
439
 
439
440
  return (
440
441
  <div className='collection-editor'>
@@ -442,7 +443,7 @@ export const CollectionEditor = ({ field, value = [], onChange, onReload }) => {
442
443
  Renderer ?
443
444
  <Renderer field={field} value={value} onRemove={remove} onChange={onChange} onReload={reload} />
444
445
  // : <DataTable {...table} editable={editable} />
445
- : <TableEditor icon={"info"} title={label} data={value} schema={item} groupBy={"field1"} canDelete={true} remove={remove}/>
446
+ : <TableEditor icon={"info"} title={label} data={value} schema={item} groupBy={groupBy} canDelete={true} remove={remove}/>
446
447
 
447
448
  }
448
449
  <footer>
@@ -200,10 +200,12 @@ const TableSelector = (props) => {
200
200
  columns,
201
201
  rows: rows || []
202
202
  }
203
+
203
204
  const buttons = actions.map(({ label, action, validate }) => {
204
205
  return <Button
205
206
  label={label} raised
206
207
  action={() => action(checked, pageContext, async () => {
208
+ await pageContext.clearChecks()
207
209
  await pageContext.load()
208
210
  setPageContext(Object.assign({}, pageContext))
209
211
  }, rows)}
@@ -540,6 +542,10 @@ const TableContext = (url, field, host, urlQuery, params) => {
540
542
  }
541
543
  },
542
544
 
545
+ clearChecks() {
546
+ this.checked = new Set([])
547
+ },
548
+
543
549
  select(id) {
544
550
  const result = this.all.find(item => item.id === id);
545
551
  this.selected = result;
@@ -1,9 +1,9 @@
1
1
  import equal from 'deep-equal'
2
2
  import React, { Fragment, useContext, useEffect, useMemo, useRef, useState } from 'react'
3
- import { Accordion, Button, DataTable, DropDown, Header, Icon, MenuIcon, MenuItem, Text } from '../html'
3
+ import { Accordion, Button, DataTable, DropDown, Header, Icon, MenuIcon, MenuItem, Text, Tabs, Tab } from '../html'
4
4
  import { HTTPClient, Session } from '../http'
5
5
  import { PageContext, SiteContext } from '../site'
6
- import { ContentEditor, GroupedContentEditor } from './ContentEditor'
6
+ import { ContentEditor } from './ContentEditor'
7
7
  import { CHECK, Content, TYPES } from './ContentType'
8
8
  import { ContentViewer } from './ContentViewer'
9
9
  import { CreateContentDialog } from './CreateContentDialog'
@@ -18,19 +18,20 @@ export const TablePage2 = (props) => {
18
18
  const site = useContext(SiteContext)
19
19
  const { id = "table",
20
20
  icon, title, name,
21
- schema, url, field, host, params = "",
22
- autosave = true, delay = 1000,
23
- editable,
24
- actions = [], dev = false, tableActions, selectionActions = [],
21
+ schema,
22
+ url, field, host, params = "", // TableContext
23
+ canQuery = false, urlQuery, user, // TableQueries
24
+ editable, autosave = true, delay = 1000, // TableEditor
25
+ actions = [], tableActions, selectionActions = [],
25
26
  canFilter = false, canAdd = true, canDelete = true, canEdit = true,
26
- canQuery = false, urlQuery, user,
27
- groupBy, validator, scenario,
27
+ groupBy, validator,
28
28
  formFilter, tableFilter, editorFilter = false,
29
+ tabbedBy,
29
30
  tableClassName,
30
31
  children
31
32
  } = props
32
33
 
33
- const [pageContext, setPageContext] = useContext(PageContext)
34
+ const [cd, setPageContext] = useContext(PageContext)
34
35
  const context = TableContext(url, field, host, urlQuery, params)
35
36
  const { selected } = pageContext
36
37
  const timer = useRef(null)
@@ -94,17 +95,6 @@ export const TablePage2 = (props) => {
94
95
  setPageContext(Object.assign({}, pageContext))
95
96
  }
96
97
 
97
- async function playScenario() {
98
- const promises1 = pageContext.all.map(async item => await pageContext.remove(item.id))
99
- Promise.all(promises1).then(async () => {
100
- const promises2 = scenario.map(async (item) => await pageContext.create(item))
101
- Promise.all(promises2).then(async () => {
102
- await pageContext.load()
103
- setPageContext(Object.assign({}, pageContext))
104
- })
105
- })
106
- }
107
-
108
98
  function closeAside() {
109
99
  pageContext.select(null)
110
100
  setPageContext(Object.assign({}, pageContext))
@@ -138,11 +128,6 @@ export const TablePage2 = (props) => {
138
128
  {canAdd ? <Button icon="add" label="Añadir" action={add} raised /> : null}
139
129
  &nbsp;
140
130
  <Button icon="refresh" label="Reload" action={reload} />
141
- {dev ? (
142
- <MenuIcon align="alignRight">
143
- <MenuItem label="Cargar Escenario 1" onSelect={playScenario} />
144
- </MenuIcon>
145
- ) : null}
146
131
  {renderActions()}
147
132
  </Header>
148
133
  {canQuery || canFilter ? (
@@ -152,7 +137,7 @@ export const TablePage2 = (props) => {
152
137
  </menu>
153
138
  ) : null}
154
139
  <main key={id} className="table-page">
155
- <TableEditor icon={icon} title={name} schema={schema} delay={delay} editable={editable} groupBy={groupBy} filter={tableFilter} actions={tableActions} canDelete={canDelete} className={tableClassName} />
140
+ <TableEditor icon={icon} title={name} schema={schema} delay={delay} editable={editable} tabbedBy={tabbedBy} groupBy={groupBy} filter={tableFilter} actions={tableActions} canDelete={canDelete} className={tableClassName} />
156
141
  {children ? <article>{children}</article> : null}
157
142
  </main>
158
143
  {renderAside()}
@@ -348,6 +333,15 @@ export const TableEditor = (props) => {
348
333
  const { all = [], filters } = pageContext
349
334
  const { icon, title, schema, editable, canDelete, filter, actions, className } = props
350
335
  const [groupBy, setGroupBy] = useState(props.groupBy)
336
+ const [tab, setTab] = useState(0)
337
+
338
+ useEffect(async () => {
339
+ if (tab) {
340
+ const filter = { [tab.field]: tab.value }
341
+ await pageContext.load(filter, [])
342
+ setPageContext(Object.assign({}, pageContext))
343
+ }
344
+ }, [tab])
351
345
 
352
346
  function changeGroup(id, value) {
353
347
  setGroupBy(value)
@@ -415,6 +409,9 @@ export const TableEditor = (props) => {
415
409
  }
416
410
  }
417
411
 
412
+ const tabField = Object.values(schema).find(field => field.tab === true)
413
+ const tabs = tabField ? tabField.options.map(option => Object.assign({}, option, { field: tabField.id })) : []
414
+
418
415
  const table = useMemo(() => {
419
416
  return {
420
417
  columns: Object.values(schema).filter(field => field.column === true).map(field => {
@@ -481,6 +478,9 @@ export const TableEditor = (props) => {
481
478
  <Fragment>
482
479
  <Header icon={icon} title={<Text>{title}</Text>}>
483
480
  {groupBy ? <DropDown id="groupBy" label="Agrupar Por" value={groupBy} options={buildGroupOptions(schema)} onChange={changeGroup} /> : null}
481
+ {tabbedBy ? <Tabs fillRight={true} fillLeft={false}>
482
+ {tabs.map(tab => <Tab id={tab.value} label={tab.label} />)}
483
+ </Tabs> : ''}
484
484
  </Header>
485
485
  <main className="table-editor">
486
486
  <Accordion sections={sections} />
@@ -501,6 +501,7 @@ const TableContext = (url, field, host, urlQuery, params) => {
501
501
  all: [],
502
502
  checked: new Set([]),
503
503
  selected: null,
504
+
504
505
  filters: {},
505
506
  queries: [],
506
507
 
@@ -508,7 +509,6 @@ const TableContext = (url, field, host, urlQuery, params) => {
508
509
  try {
509
510
  const filters = filter ? Object.keys(filter).reduce((filters, key) => {
510
511
  const field = filter[key];
511
-
512
512
  if (field) {
513
513
  if (CHECK['isObject'](field)) {
514
514
  Object.keys(field).forEach(key2 => {
@@ -519,7 +519,6 @@ const TableContext = (url, field, host, urlQuery, params) => {
519
519
  filters[key] = field;
520
520
  }
521
521
  }
522
-
523
522
  return filters;
524
523
  }, {}) : []
525
524
  const data = await API.all(filters);
@@ -612,7 +611,7 @@ const TableContext = (url, field, host, urlQuery, params) => {
612
611
  }
613
612
 
614
613
  /**
615
- * table API
614
+ * Table API
616
615
  */
617
616
  const TableAPI = (url, host, params = "") => {
618
617
 
@@ -0,0 +1,33 @@
1
+ import { FORMATS } from "./FORMATS";
2
+
3
+ /**
4
+ * Content
5
+ */
6
+ class Content {
7
+
8
+ constructor(schema, value) {
9
+ this.schema = schema;
10
+ this.value = value;
11
+ }
12
+
13
+ }
14
+
15
+ const ADDRESS_SCHEMA = {
16
+ id : { type: TYPES.STRING },
17
+ street : { type: TYPES.STRING, default: '' },
18
+ city : { type: TYPES.STRING, default: '' },
19
+ state : { type: TYPES.STRING, default: '' },
20
+ zip : { type: TYPES.STRING, default: '' },
21
+ country: { type: TYPES.STRING, default: '' },
22
+ }
23
+
24
+ const PERSON_SCHEMA = {
25
+ id : { type: TYPES.STRING },
26
+ name : { type: TYPES.STRING , format: FORMATS.NONE, label: 'Name' },
27
+ address : { type: TYPES.ENTITY, item: ADDRESS_SCHEMA, format: FORMATS.NONE, label: 'Address' },
28
+ age : { type: TYPES.NUMBER , format: FORMATS.NONE, label: 'Age' , default: 0 },
29
+ married : { type: TYPES.BOOLEAN , format: FORMATS.NONE, label: 'Married' , default: false },
30
+ children: { type: TYPES.ARRAY , item: TYPES.STRING , format: FORMATS.NONE, label: 'Children', default: [] },
31
+ }
32
+
33
+ const person = new Content(PERSON_SCHEMA, {})
@@ -0,0 +1,74 @@
1
+ export const ContentFilters = (props) => {
2
+
3
+ const [pageContext, setPageContext] = useContext(PageContext)
4
+ const { filters } = pageContext
5
+ const { schema, onSave } = props
6
+ const [form, setForm] = useState({})
7
+
8
+ const filterSchema = useMemo(() => {
9
+ const filterSchema = Object.assign({}, schema)
10
+ for (var key in filterSchema) {
11
+ if (filterSchema[key].filter === false) {
12
+ delete filterSchema[key]
13
+ } else {
14
+ if (filterSchema[key].type === TYPES.ENTITY) {
15
+ const fs = filterSchema[key].item
16
+ for (var key in fs) {
17
+ if (fs[key].filter === false) delete fs[key]
18
+ }
19
+ }
20
+ }
21
+ }
22
+ //Object.values(filterSchema).forEach(field => field.section = null)
23
+ delete filterSchema.flows
24
+ return filterSchema
25
+ }, [schema])
26
+
27
+ const likes = useMemo(() => {
28
+ const fields = Object.values(schema)
29
+ return fields.reduce((likes, field) => {
30
+ if (field.like === true) likes.push(field.id)
31
+ return likes
32
+ }, [])
33
+ }, [schema])
34
+
35
+ useEffect(() => {
36
+ if (filters) setForm(filters)
37
+ }, [filters])
38
+
39
+ useEffect(() => {
40
+ reload()
41
+ }, [form])
42
+
43
+ async function change(next) {
44
+ setForm(next)
45
+ }
46
+
47
+ async function reload() {
48
+ await pageContext.load(form, likes)
49
+ setPageContext(Object.assign({}, pageContext))
50
+ }
51
+
52
+ function clear() {
53
+ change({})
54
+ }
55
+
56
+ function save() {
57
+ if (onSave) {
58
+ onSave(form)
59
+ }
60
+ }
61
+
62
+ const content = new Content(filterSchema, form)
63
+ return (
64
+ <Fragment>
65
+ <Header className="table-filters" title={<Text>Filters</Text>} >
66
+ <Icon icon="filter_list_off" size="small" clickable action={clear} />
67
+ {onSave ? <Icon icon="save" size="small" clickable action={save} /> : null}
68
+ </Header>
69
+ <main className="table-filters">
70
+ <ContentEditor content={content} onChange={change} />
71
+ </main>
72
+ </Fragment>
73
+ )
74
+ }
@@ -0,0 +1,96 @@
1
+ export const ContentPage = (props) => {
2
+
3
+ const {
4
+ icon, title, className,
5
+ schema, url,
6
+ } = props
7
+
8
+ return (
9
+ <>
10
+ <header className="content-page"></header>
11
+ <nav className="content-page"></nav>
12
+ <menu className="content-page">
13
+
14
+ </menu>
15
+ <main className="content-page">
16
+
17
+ </main>
18
+ <aside className="content-page"></aside>
19
+ <footer className="content-page"></footer>
20
+ </>
21
+ )
22
+ }
23
+
24
+
25
+
26
+ /**
27
+ * Content API
28
+ */
29
+ const ContentAPI = (url, host) => {
30
+
31
+ const http = HTTPClient(host || window.API || process.env.REACT_APP_API, Session);
32
+
33
+ return {
34
+ all(filters = [], likes = [], page) {
35
+ let queryParams = page ? `?page=${page}&` : "?"
36
+ const filterQuery = Object.keys(filters).reduce((query, key) => {
37
+ const value = filters[key]
38
+ if (typeof (value) === 'boolean') return query.concat(`${key}=${value}&`)
39
+ if (Array.isArray(value)) {
40
+ const param = value.length === 0 ? '' : value.reduce((param, item) => {
41
+ param = param.concat(`${key}=${item}&`)
42
+ return param
43
+ }, "")
44
+ return query.concat(param)
45
+ }
46
+ const likeSymbol = likes.includes(key) ? '%' : ''
47
+ return query.concat(`${key}=${likeSymbol}${value}${likeSymbol}&`)
48
+ }, "")
49
+ queryParams = queryParams.concat(filterQuery)
50
+ return http.GET(url + queryParams)
51
+ },
52
+
53
+ find(id) {
54
+ return http.GET(`${url}/${id}`)
55
+ },
56
+
57
+ create(form) {
58
+ const body = JSON.stringify(form)
59
+ return http.POST(url, body)
60
+ },
61
+
62
+ update(form) {
63
+ const body = JSON.stringify(form)
64
+ return http.PUT(`${url}/${form.id}`, body)
65
+ },
66
+
67
+ updateProperty(id, propertyName, form) {
68
+ const body = JSON.stringify(form)
69
+ return http.PUT(`${url}/${id}/${propertyName}`, body)
70
+ },
71
+
72
+ patch(id, form) {
73
+ const body = JSON.stringify(form)
74
+ return http.PATCH(`${url}/${id}`, body)
75
+ },
76
+
77
+ remove(id) {
78
+ return http.DELETE(`${url}/${id}`)
79
+ },
80
+
81
+ queries(user) {
82
+ const queryParams = user ? `?user=${user}` : ""
83
+ return http.GET(`/queries/${url}${queryParams}`)
84
+ },
85
+
86
+ createQuery(form) {
87
+ const body = JSON.stringify(form)
88
+ return http.POST(`/queries/${url}`, body)
89
+ },
90
+
91
+ removeQuery(id) {
92
+ return http.DELETE(`/queries/${url}/${id}`)
93
+ },
94
+
95
+ }
96
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * FORMATS
3
+ */
4
+ export const FORMATS = {
5
+ NONE: '',
6
+ DATE: 'date',
7
+ DATERANGE: 'DATERANGE',
8
+ TIME: 'time',
9
+ EMAIL: 'email',
10
+ HTML: 'HTML',
11
+ URL: 'URL',
12
+ IMG: 'IMG',
13
+ COLOR: 'COLOR',
14
+ TOKENS: 'TOKENS'
15
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * TYPES
3
+ */
4
+ export const TYPES = {
5
+ STRING: 'String',
6
+ NUMBER: 'Number',
7
+ BOOLEAN: 'Boolean',
8
+ ARRAY: 'Array',
9
+ ENTITY: 'Object',
10
+ FUNCTION: 'Function',
11
+ }
@@ -167,18 +167,17 @@ const Page4 = (props) => {
167
167
  field1: { id: "field1", section: "E-INFO1", type: TYPES.STRING, format: FORMATS.NONE , required: true, tab: false, grouper: true , column: true , filter: true , label: "E field1" },
168
168
  field2: { id: "field2", section: "E-INFO2", type: TYPES.STRING, format: FORMATS.NONE , required: true, tab: false, grouper: true , column: true , filter: true , label: "E field2" },
169
169
  field3: { id: "field3", section: "E-INFO2", type: TYPES.STRING, format: FORMATS.NONE , required: true, tab: false, grouper: true , column: true , filter: true , label: "E field3" },
170
-
171
170
  }
172
171
 
173
172
  const schema = {
174
- name : { id: "name" , section: "A", type: TYPES.STRING, format: FORMATS.NONE , required: true, tab: false, grouper: true , column: true , filter: true , like: true, label: "Name" },
175
- state : { id: "state" , section: "A", type: TYPES.STRING, format: FORMATS.NONE , required: true, tab: true , grouper: true , column: true , filter: false , label: "State" , options: [
173
+ name : { id: "name" , section: "A", type: TYPES.STRING , format: FORMATS.NONE , required: true, tab: false, grouper: true , column: true , filter: true , like: true , label: "Name" },
174
+ state : { id: "state" , section: "A", type: TYPES.STRING , format: FORMATS.NONE , required: true, tab: true , grouper: true , column: true , filter: false , label: "State" , options: [
176
175
  { label: "Pendiente", value: "NOT_CLASSIFIED" },
177
176
  { label: "Clasificada", value: "CLASSIFIED"},
178
177
  ]},
179
- field1: { id: "field1", section: "A", type: TYPES.STRING , format: FORMATS.NONE , required: true, tab: false, grouper: true , column: true , filter: true , label: "field1" },
180
- field2: { id: "field2", section: "B", type: TYPES.STRING , format: FORMATS.NONE , required: true, tab: false, grouper: true , column: true , filter: true , label: "field2" },
181
- field4: { id: "field4", section: "B", type: TYPES.STRING , format: FORMATS.COLOR, required: true, tab: false, grouper: true , column: true , filter: true , label: "Color" },
178
+ field1: { id: "field1", section: "A", type: TYPES.STRING , format: FORMATS.NONE , required: true, tab: false, grouper: true , column: true , filter: true , label: "field1" },
179
+ field2: { id: "field2", section: "B", type: TYPES.STRING , format: FORMATS.NONE , required: true, tab: false, grouper: true , column: true , filter: true , label: "field2" },
180
+ field4: { id: "field4", section: "B", type: TYPES.STRING , format: FORMATS.COLOR, required: true, tab: false, grouper: true , column: true , filter: true , label: "Color" },
182
181
  field5: { id: "field5", section: "B", type: TYPES.ENTITY, item: ENTITYTYPE, format: FORMATS.NONE , editable: true, tab: false, grouper: false, column: true , filter: true , like: false, label: "Entity5"},
183
182
 
184
183
  }
@@ -193,10 +192,10 @@ const Page4 = (props) => {
193
192
  const Page5 = (props) => {
194
193
 
195
194
  const ENTITYTYPE = {
196
- name : { id: "name" , section: "", type: TYPES.STRING, format: FORMATS.NONE , required: true, tab: false, grouper: true , column: true , filter: true , like: true, label: "Name" },
197
- field1: { id: "field1", section: "", type: TYPES.STRING, format: FORMATS.NONE , required: true, tab: false, grouper: true , column: false, filter: true , label: "E field1" },
198
- field2: { id: "field2", section: "", type: TYPES.STRING, format: FORMATS.NONE , required: true, tab: false, grouper: true , column: false, filter: true , label: "E field2" },
199
- field3: { id: "field3", section: "", type: TYPES.STRING, format: FORMATS.NONE , required: true, tab: false, grouper: true , column: true , filter: true , label: "E field3" },
195
+ name : { id: "name" , section: "", type: TYPES.STRING , format: FORMATS.NONE , required: true, tab: false, grouper: true , column: true , filter: true , like: true, label: "Name" },
196
+ field1: { id: "field1", section: "", type: TYPES.STRING , format: FORMATS.NONE , required: true, tab: false, grouper: true , column: false, filter: true , label: "E field1" },
197
+ field2: { id: "field2", section: "", type: TYPES.STRING , format: FORMATS.NONE , required: true, tab: false, grouper: true , column: false, filter: true , label: "E field2" },
198
+ field3: { id: "field3", section: "", type: TYPES.STRING , format: FORMATS.NONE , required: true, tab: false, grouper: true , column: true , filter: true , label: "E field3" },
200
199
  }
201
200
 
202
201
  const schema = {
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useMemo, useState } from "react";
1
+ import React, { useEffect, useMemo, useState, useRef } from "react";
2
2
  import { DropDown, Header, Icon, Text, TextField, Button } from "../../html";
3
3
  import moment from "moment";
4
4
  import { extendMoment } from "moment-range";
@@ -15,15 +15,16 @@ const DATE_RANGE = [
15
15
  /**
16
16
  * Planner
17
17
  */
18
- export const Planner = ({ title, events = [], lanes = [], navigation = true, onSelectCell, focusEvent, config = { range: "year", from: "2022-01-01", to: "2022-12-30"}, onChange }) => {
18
+ export const Planner = ({ title, events = [], lanes = [], navigation = true, onSelectCell, focusEvent, config = { range: "year", from: "2022-01-01", to: "2022-12-30" }, onChange }) => {
19
19
 
20
20
  const [dateRange, setDateRange] = useState(config.range);
21
21
  const [from, setFrom] = useState(config.from);
22
22
  const [to, setTo] = useState(config.to);
23
-
23
+ const thisMondayElement = useRef(null)
24
+
24
25
  useEffect(() => {
25
- showThisWeek()
26
- }, [])
26
+ if (thisMondayElement.current) { showThisWeek() }
27
+ }, [thisMondayElement])
27
28
 
28
29
  useEffect(() => {
29
30
  const element = document.getElementById(focusEvent)
@@ -93,7 +94,7 @@ export const Planner = ({ title, events = [], lanes = [], navigation = true, onS
93
94
  {navigation ? (
94
95
  <Header title={label}>
95
96
  &nbsp;&nbsp;
96
- <Button label="Esta Semana" outlined action={showThisWeek}/>
97
+ <Button label="Esta Semana" outlined action={showThisWeek} />
97
98
  <Icon icon="chevron_right" clickable action={next} />
98
99
  <TextField id="to" type="date" label="Hasta" value={to} onChange={(id, value) => setTo(value)} />
99
100
  <div className="expand"></div>
@@ -108,11 +109,7 @@ export const Planner = ({ title, events = [], lanes = [], navigation = true, onS
108
109
 
109
110
  <div className="column0">
110
111
  <div className="column-header"></div>
111
- {lanes.map((lane) => (
112
- <div className="row-header">
113
- {lane.label}
114
- </div>
115
- ))}
112
+ {lanes.map((lane) => <div className="row-header">{lane.label}</div>)}
116
113
  </div>
117
114
 
118
115
  <div className="rows">
@@ -133,8 +130,13 @@ export const Planner = ({ title, events = [], lanes = [], navigation = true, onS
133
130
  const isWekend = [0, 6].includes(date.moment.day());
134
131
  const weekend = isWekend ? "weekend" : "";
135
132
  const thisWeek = moment().startOf('week').isSame(date.moment, "week") ? "thisWeek" : "";
133
+
134
+ const today = moment()
135
+ var weekStart = today.clone().startOf('week')
136
+ const isThisMonday = (date.moment.isSame(weekStart))
137
+
136
138
  return (
137
- <div className="column-header">
139
+ <div className="column-header" ref={isThisMonday ? thisMondayElement : null}>
138
140
  <div className={`date-header ${weekend} ${thisWeek}`}>
139
141
  <Text use="headline6">{date.moment.format("DD")}</Text>
140
142
  &nbsp;
@@ -145,7 +147,7 @@ export const Planner = ({ title, events = [], lanes = [], navigation = true, onS
145
147
  })}
146
148
  </div>
147
149
 
148
- {lanes.map((lane) => <PlannerRow key={lane.id} lane={lane} events={events} period={period} onSelectCell={selectCell} onChange={onChange}/>)}
150
+ {lanes.map((lane) => <PlannerRow key={lane.id} lane={lane} events={events} period={period} onSelectCell={selectCell} onChange={onChange} />)}
149
151
 
150
152
  </div>
151
153
  </main>
@@ -177,7 +179,7 @@ const PlannerRow = (props) => {
177
179
  return eventDate.getTime() === slotDate.getTime();
178
180
  })
179
181
  return (
180
- <PlannerCell key={`${lane.id}-${slotDate.toString()}`} lane={lane} date={date} events={cellEvents} onSelect={onSelectCell} onDrop={change}/>
182
+ <PlannerCell key={`${lane.id}-${slotDate.toString()}`} lane={lane} date={date} events={cellEvents} onSelect={onSelectCell} onDrop={change} />
181
183
  );
182
184
  })}
183
185
  </div>
@@ -227,7 +229,7 @@ const PlannerCell = ({ lane, events, date, disabled = false, onAdd, onDelete, on
227
229
  var weekStart = today.clone().startOf('week')
228
230
  const thisMonday = (date.moment.isSame(weekStart)) ? "thisMonday" : ""
229
231
  const dragOverStyle = dragOver ? "drag-over" : ""
230
- return (
232
+ return (
231
233
  <div className={`cell ${thisMonday} ${weekend} ${dragOverStyle}`} onDragOver={onDragOver} onDragLeave={onDragLeave} onDrop={drop} onClick={select}>
232
234
  {events.map(event => {
233
235
  const { Renderer = EventCard } = event