tg-ganttchart 0.0.8 → 0.0.9

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.
Files changed (66) hide show
  1. package/dist/demo.html +1 -0
  2. package/dist/tgganttchart.common.js +9232 -0
  3. package/dist/tgganttchart.common.js.map +1 -0
  4. package/dist/tgganttchart.css +1 -0
  5. package/dist/tgganttchart.umd.js +9243 -0
  6. package/dist/tgganttchart.umd.js.map +1 -0
  7. package/dist/tgganttchart.umd.min.js +7 -0
  8. package/dist/tgganttchart.umd.min.js.map +1 -0
  9. package/package.json +7 -4
  10. package/babel.config.js +0 -5
  11. package/src/.eslintrc.js +0 -18
  12. package/src/App.vue +0 -780
  13. package/src/GanttElastic.standalone.vue +0 -48
  14. package/src/GanttElastic.vue +0 -2305
  15. package/src/assets/logo.png +0 -0
  16. package/src/components/Calendar/Calendar.vue +0 -559
  17. package/src/components/Calendar/CalendarRow.vue +0 -112
  18. package/src/components/Chart/Chart.vue +0 -117
  19. package/src/components/Chart/DaysHighlight.vue +0 -60
  20. package/src/components/Chart/DependencyLines.vue +0 -112
  21. package/src/components/Chart/Grid.vue +0 -205
  22. package/src/components/Chart/ProgressBar.vue +0 -110
  23. package/src/components/Chart/Row/Epic.vue +0 -131
  24. package/src/components/Chart/Row/Milestone.vue +0 -117
  25. package/src/components/Chart/Row/Project.vue +0 -132
  26. package/src/components/Chart/Row/Story.vue +0 -127
  27. package/src/components/Chart/Row/Subtask.vue +0 -117
  28. package/src/components/Chart/Row/Task.mixin.js +0 -47
  29. package/src/components/Chart/Row/Task.vue +0 -82
  30. package/src/components/Chart/Text.vue +0 -105
  31. package/src/components/Expander.vue +0 -114
  32. package/src/components/GanttElastic.standalone.vue +0 -48
  33. package/src/components/GanttElastic.vue +0 -1646
  34. package/src/components/Header/GanttViewFilter.vue +0 -154
  35. package/src/components/Header/Header.vue +0 -266
  36. package/src/components/MainView.vue +0 -283
  37. package/src/components/TaskList/ItemColumn.vue +0 -212
  38. package/src/components/TaskList/TaskList.vue +0 -45
  39. package/src/components/TaskList/TaskListHeader.vue +0 -143
  40. package/src/components/TaskList/TaskListItem.vue +0 -35
  41. package/src/components/bundle.js +0 -28
  42. package/src/components/components/Calendar/Calendar.vue +0 -332
  43. package/src/components/components/Calendar/CalendarRow.vue +0 -96
  44. package/src/components/components/Chart/Chart.vue +0 -111
  45. package/src/components/components/Chart/DaysHighlight.vue +0 -71
  46. package/src/components/components/Chart/DependencyLines.vue +0 -112
  47. package/src/components/components/Chart/Grid.vue +0 -164
  48. package/src/components/components/Chart/ProgressBar.vue +0 -110
  49. package/src/components/components/Chart/Row/Milestone.vue +0 -117
  50. package/src/components/components/Chart/Row/Project.vue +0 -131
  51. package/src/components/components/Chart/Row/Task.mixin.js +0 -46
  52. package/src/components/components/Chart/Row/Task.vue +0 -107
  53. package/src/components/components/Chart/Text.vue +0 -105
  54. package/src/components/components/Expander.vue +0 -126
  55. package/src/components/components/Header/Header.vue +0 -265
  56. package/src/components/components/MainView.vue +0 -282
  57. package/src/components/components/TaskList/ItemColumn.vue +0 -121
  58. package/src/components/components/TaskList/TaskList.vue +0 -45
  59. package/src/components/components/TaskList/TaskListHeader.vue +0 -143
  60. package/src/components/components/TaskList/TaskListItem.vue +0 -35
  61. package/src/components/components/bundle.js +0 -28
  62. package/src/components/style.js +0 -308
  63. package/src/index.js +0 -12
  64. package/src/main.js +0 -6
  65. package/src/style.js +0 -398
  66. package/vue.config.js +0 -42
@@ -1,332 +0,0 @@
1
-
2
- <template>
3
- <div
4
- class="gantt-elastic__calendar-wrapper"
5
- :style="{ ...root.style['calendar-wrapper'], width: root.state.options.width + 'px' }"
6
- >
7
- <div class="gantt-elastic__calendar" :style="{ ...root.style['calendar'], width: root.state.options.width + 'px' }">
8
- <calendar-row :items="dates.months" which="month" v-if="root.state.options.calendar.month.display"></calendar-row>
9
- <calendar-row :items="dates.days" which="day" v-if="root.state.options.calendar.day.display"></calendar-row>
10
- <calendar-row :items="dates.hours" which="hour" v-if="root.state.options.calendar.hour.display"></calendar-row>
11
- </div>
12
- </div>
13
- </template>
14
-
15
- <script>
16
- import dayjs from 'dayjs';
17
- import CalendarRow from './CalendarRow.vue';
18
-
19
- export default {
20
- name: 'Calendar',
21
- components: {
22
- CalendarRow
23
- },
24
- inject: ['root'],
25
- data() {
26
- return {};
27
- },
28
-
29
- methods: {
30
- /**
31
- * How many hours will fit?
32
- *
33
- * @returns {object}
34
- */
35
- howManyHoursFit(dayIndex) {
36
- const stroke = 1;
37
- const additionalSpace = stroke + 2;
38
- let fullCellWidth = this.root.state.options.times.steps[dayIndex].width.px;
39
- let formatNames = Object.keys(this.root.state.options.calendar.hour.format);
40
- for (let hours = 24; hours > 1; hours = Math.ceil(hours / 2)) {
41
- for (let formatName of formatNames) {
42
- if (
43
- (this.root.state.options.calendar.hour.maxWidths[formatName] + additionalSpace) * hours <= fullCellWidth &&
44
- hours > 1
45
- ) {
46
- return {
47
- count: hours,
48
- type: formatName
49
- };
50
- }
51
- }
52
- }
53
- return {
54
- count: 0,
55
- type: ''
56
- };
57
- },
58
-
59
- /**
60
- * How many days will fit?
61
- *
62
- * @returns {object}
63
- */
64
- howManyDaysFit() {
65
- const stroke = 1;
66
- const additionalSpace = stroke + 2;
67
- let fullWidth = this.root.state.options.width;
68
- let formatNames = Object.keys(this.root.state.options.calendar.day.format);
69
- for (let days = this.root.state.options.times.steps.length; days > 1; days = Math.ceil(days / 2)) {
70
- for (let formatName of formatNames) {
71
- if (
72
- (this.root.state.options.calendar.day.maxWidths[formatName] + additionalSpace) * days <= fullWidth &&
73
- days > 1
74
- ) {
75
- return {
76
- count: days,
77
- type: formatName
78
- };
79
- }
80
- }
81
- }
82
- return {
83
- count: 0,
84
- type: ''
85
- };
86
- },
87
-
88
- /**
89
- * How many months will fit?
90
- *
91
- * @returns {object}
92
- */
93
- howManyMonthsFit() {
94
- const stroke = 1;
95
- const additionalSpace = stroke + 2;
96
- let fullWidth = this.root.state.options.width;
97
- let formatNames = Object.keys(this.root.state.options.calendar.month.format);
98
- let currentMonth = dayjs(this.root.state.options.times.firstTime);
99
- let previousMonth = currentMonth.clone();
100
- const lastTime = this.root.state.options.times.lastTime;
101
- let monthsCount = this.root.monthsCount(
102
- this.root.state.options.times.firstTime,
103
- this.root.state.options.times.lastTime
104
- );
105
- if (monthsCount === 1) {
106
- for (let formatName of formatNames) {
107
- if (this.root.state.options.calendar.month.maxWidths[formatName] + additionalSpace <= fullWidth) {
108
- return {
109
- count: 1,
110
- type: formatName
111
- };
112
- }
113
- }
114
- }
115
- for (let months = monthsCount; months > 1; months = Math.ceil(months / 2)) {
116
- for (let formatName of formatNames) {
117
- if (
118
- (this.root.state.options.calendar.month.maxWidths[formatName] + additionalSpace) * months <= fullWidth &&
119
- months > 1
120
- ) {
121
- return {
122
- count: months,
123
- type: formatName
124
- };
125
- }
126
- }
127
- }
128
- return {
129
- count: 0,
130
- type: formatNames[0]
131
- };
132
- },
133
-
134
- /**
135
- * Generate hours
136
- *
137
- * @returns {array}
138
- */
139
- generateHours() {
140
- let allHours = [];
141
- if (!this.root.state.options.calendar.hour.display) {
142
- return allHours;
143
- }
144
- const steps = this.root.state.options.times.steps;
145
- const localeName = this.root.state.options.locale.name;
146
- for (let hourIndex = 0, len = steps.length; hourIndex < len; hourIndex++) {
147
- const hoursCount = this.howManyHoursFit(hourIndex);
148
- if (hoursCount.count === 0) {
149
- continue;
150
- }
151
- const hours = { key: hourIndex + 'step', children: [] };
152
- const hourStep = 24 / hoursCount.count;
153
- const hourWidthPx = steps[hourIndex].width.px / hoursCount.count;
154
- for (let i = 0, len = hoursCount.count; i < len; i++) {
155
- const hour = i * hourStep;
156
- let index = hourIndex;
157
- if (hourIndex > 0) {
158
- index = hourIndex - Math.floor(hourIndex / 24) * 24;
159
- }
160
- let textWidth = 0;
161
- if (typeof this.root.state.options.calendar.hour.widths[index] !== 'undefined') {
162
- textWidth = this.root.state.options.calendar.hour.widths[index][hoursCount.type];
163
- }
164
- let x = steps[hourIndex].offset.px + hourWidthPx * i;
165
- hours.children.push({
166
- index: hourIndex,
167
- key: 'h' + i,
168
- x,
169
- y: this.root.state.options.calendar.day.height + this.root.state.options.calendar.month.height,
170
- width: hourWidthPx,
171
- textWidth,
172
- height: this.root.state.options.calendar.hour.height,
173
- label: this.root.state.options.calendar.hour.formatted[hoursCount.type][hour]
174
- });
175
- }
176
- allHours.push(hours);
177
- }
178
- return allHours;
179
- },
180
-
181
- /**
182
- * Generate days
183
- *
184
- * @returns {array}
185
- */
186
- generateDays() {
187
- let days = [];
188
- if (!this.root.state.options.calendar.day.display) {
189
- return days;
190
- }
191
- const daysCount = this.howManyDaysFit();
192
- if (daysCount.count === 0) {
193
- return days;
194
- }
195
- const steps = this.root.state.options.times.steps;
196
- const localeName = this.root.state.options.locale.name;
197
- const dayStep = Math.ceil(steps.length / daysCount.count);
198
- for (let dayIndex = 0, len = steps.length; dayIndex < len; dayIndex += dayStep) {
199
- let dayWidthPx = 0;
200
- // day could be shorter (daylight saving time) so join widths and divide
201
- for (let currentStep = 0; currentStep < dayStep; currentStep++) {
202
- if (typeof steps[dayIndex + currentStep] !== 'undefined') {
203
- dayWidthPx += steps[dayIndex + currentStep].width.px;
204
- }
205
- }
206
- const date = dayjs(steps[dayIndex].time);
207
- let textWidth = 0;
208
- if (typeof this.root.state.options.calendar.day.widths[dayIndex] !== 'undefined') {
209
- textWidth = this.root.state.options.calendar.day.widths[dayIndex][daysCount.type];
210
- }
211
- let x = steps[dayIndex].offset.px;
212
- days.push({
213
- index: dayIndex,
214
- key: steps[dayIndex].time + 'd',
215
- x,
216
- y: this.root.state.options.calendar.month.height,
217
- width: dayWidthPx,
218
- textWidth,
219
- height: this.root.state.options.calendar.day.height,
220
- label: this.root.state.options.calendar.day.format[daysCount.type](date.locale(localeName))
221
- });
222
- }
223
- return days.map(item => ({
224
- key: item.key,
225
- children: [item]
226
- }));
227
- },
228
-
229
- /**
230
- * Generate months
231
- *
232
- * @returns {array}
233
- */
234
- generateMonths() {
235
- let months = [];
236
- if (!this.root.state.options.calendar.month.display) {
237
- return months;
238
- }
239
- const monthsCount = this.howManyMonthsFit();
240
- if (monthsCount.count === 0) {
241
- return months;
242
- }
243
- const steps = this.root.state.options.times.steps;
244
- const localeName = this.root.state.options.locale.name;
245
- let formatNames = Object.keys(this.root.state.options.calendar.month.format);
246
- let currentDate = dayjs(this.root.state.options.times.firstTime);
247
- for (let monthIndex = 0; monthIndex < monthsCount.count; monthIndex++) {
248
- let monthWidth = 0;
249
- let monthOffset = Number.MAX_SAFE_INTEGER;
250
- let finalDate = dayjs(currentDate)
251
- .add(1, 'month')
252
- .startOf('month');
253
- if (finalDate.valueOf() > this.root.state.options.times.lastTime) {
254
- finalDate = dayjs(this.root.state.options.times.lastTime);
255
- }
256
- // we must find first and last step to get the offsets / widths
257
- for (let step = 0, len = this.root.state.options.times.steps.length; step < len; step++) {
258
- let currentStep = this.root.state.options.times.steps[step];
259
- if (currentStep.time >= currentDate.valueOf() && currentStep.time < finalDate.valueOf()) {
260
- monthWidth += currentStep.width.px;
261
- if (currentStep.offset.px < monthOffset) {
262
- monthOffset = currentStep.offset.px;
263
- }
264
- }
265
- }
266
- let label = '';
267
- let choosenFormatName;
268
- for (let formatName of formatNames) {
269
- if (this.root.state.options.calendar.month.maxWidths[formatName] + 2 <= monthWidth) {
270
- label = this.root.state.options.calendar.month.format[formatName](currentDate.locale(localeName));
271
- choosenFormatName = formatName;
272
- }
273
- }
274
- let textWidth = 0;
275
- if (typeof this.root.state.options.calendar.month.widths[monthIndex] !== 'undefined') {
276
- textWidth = this.root.state.options.calendar.month.widths[monthIndex][choosenFormatName];
277
- }
278
- let x = monthOffset;
279
- months.push({
280
- index: monthIndex,
281
- key: monthIndex + 'm',
282
- x,
283
- y: 0,
284
- width: monthWidth,
285
- textWidth,
286
- choosenFormatName,
287
- height: this.root.state.options.calendar.month.height,
288
- label
289
- });
290
- currentDate = currentDate.add(1, 'month').startOf('month');
291
- if (currentDate.valueOf() > this.root.state.options.times.lastTime) {
292
- currentDate = dayjs(this.root.state.options.times.lastTime);
293
- }
294
- }
295
- return months.map(item => ({
296
- key: item.key,
297
- children: [item]
298
- }));
299
- },
300
-
301
- /**
302
- * Sum all calendar rows height and return result
303
- *
304
- * @returns {int}
305
- */
306
- calculateCalendarDimensions({ hours, days, months }) {
307
- let height = 0;
308
- if (this.root.state.options.calendar.hour.display && hours.length > 0) {
309
- height += this.root.state.options.calendar.hour.height;
310
- }
311
- if (this.root.state.options.calendar.day.display && days.length > 0) {
312
- height += this.root.state.options.calendar.day.height;
313
- }
314
- if (this.root.state.options.calendar.month.display && months.length > 0) {
315
- height += this.root.state.options.calendar.month.height;
316
- }
317
- this.root.state.options.calendar.height = height;
318
- }
319
- },
320
-
321
- computed: {
322
- dates() {
323
- const hours = this.generateHours();
324
- const days = this.generateDays();
325
- const months = this.generateMonths();
326
- const allDates = { hours, days, months };
327
- this.calculateCalendarDimensions(allDates);
328
- return allDates;
329
- }
330
- }
331
- };
332
- </script>
@@ -1,96 +0,0 @@
1
-
2
- <template>
3
- <div :class="'gantt-elastic__calendar-row gantt-elastic__calendar-row--' + which" :style="rowStyle">
4
- <div
5
- v-for="(item, itemIndex) in items"
6
- :key="item.key"
7
- :class="'gantt-elastic__calendar-row-rect gantt-elastic__calendar-row-rect--' + which"
8
- :style="rectStyle"
9
- >
10
- <div
11
- :class="'gantt-elastic__calendar-row-rect-child gantt-elastic__calendar-row-rect-child--' + which"
12
- v-for="(child, childIndex) in item.children"
13
- :key="child.key"
14
- :style="rectChildStyle[itemIndex][childIndex]"
15
- >
16
- <div
17
- :class="'gantt-elastic__calendar-row-text gantt-elastic__calendar-row-text--' + which"
18
- :style="textStyle(child)"
19
- >
20
- {{ child.label }}
21
- </div>
22
- </div>
23
- </div>
24
- </div>
25
- </template>
26
-
27
- <script>
28
- export default {
29
- name: 'CalendarRow',
30
- inject: ['root'],
31
- props: ['items', 'which'],
32
- data() {
33
- return {};
34
- },
35
- methods: {
36
- /**
37
- * Get x position
38
- *
39
- * @returns {number}
40
- */
41
- getTextX(item) {
42
- let x = item.x + item.width / 2 - item.textWidth / 2;
43
- if (this.which === 'month' && this.root.isInsideViewPort(item.x, item.width, 0)) {
44
- let scrollWidth = this.root.state.options.scroll.chart.right - this.root.state.options.scroll.chart.left;
45
- x = this.root.state.options.scroll.chart.left + scrollWidth / 2 - item.textWidth / 2 + 2;
46
- if (x + item.textWidth + 2 > item.x + item.width) {
47
- x = item.x + item.width - item.textWidth - 2;
48
- } else if (x < item.x) {
49
- x = item.x + 2;
50
- }
51
- }
52
- return x - item.x;
53
- }
54
- },
55
- computed: {
56
- rowStyle() {
57
- return { ...this.root.style['calendar-row'], ...this.root.style['calendar-row--' + this.which] };
58
- },
59
- rectStyle() {
60
- return { ...this.root.style['calendar-row-rect'], ...this.root.style['calendar-row-rect--' + this.which] };
61
- },
62
- rectChildStyle() {
63
- const basicStyle = {
64
- ...this.root.style['calendar-row-rect-child'],
65
- ...this.root.style['calendar-row-rect-child--' + this.which]
66
- };
67
- const style = [];
68
- for (let item of this.items) {
69
- const childrenStyle = [];
70
- for (let child of item.children) {
71
- childrenStyle.push({
72
- ...basicStyle,
73
- width: child.width + 'px',
74
- height: child.height + 'px'
75
- });
76
- }
77
- style.push(childrenStyle);
78
- }
79
- return style;
80
- },
81
- textStyle() {
82
- const basicStyle = {
83
- ...this.root.style['calendar-row-text'],
84
- ...this.root.style['calendar-row-text--' + this.which]
85
- };
86
- return child => {
87
- const style = { ...basicStyle };
88
- if (this.which === 'month') {
89
- style.left = this.getTextX(child) + 'px';
90
- }
91
- return style;
92
- };
93
- }
94
- }
95
- };
96
- </script>
@@ -1,111 +0,0 @@
1
-
2
- <template>
3
- <div class="gantt-elastic__chart" :style="{ ...root.style['chart'] }" ref="chart">
4
- <div
5
- class="gantt-elastic__chart-calendar-container"
6
- ref="chartCalendarContainer"
7
- :style="{
8
- ...root.style['chart-calendar-container'],
9
- height: root.state.options.calendar.height + 'px',
10
- 'margin-bottom': root.state.options.calendar.gap + 'px'
11
- }"
12
- >
13
- <calendar></calendar>
14
- </div>
15
- <div
16
- class="gantt-elastic__chart-graph-container"
17
- ref="chartGraphContainer"
18
- :style="{
19
- ...root.style['chart-graph-container'],
20
- height: root.state.options.height - root.state.options.calendar.height + 'px'
21
- }"
22
- >
23
- <div
24
- :style="{
25
- ...root.style['chart-area'],
26
- width: root.state.options.width + 'px',
27
- height: root.state.options.rowsHeight + 'px'
28
- }"
29
- >
30
- <div
31
- class="gantt-elastic__chart-graph"
32
- ref="chartGraph"
33
- :style="{ ...root.style['chart-graph'], height: '100%' }"
34
- >
35
- <svg
36
- class="gantt-elastic__chart-graph-svg"
37
- :style="{ ...root.style['chart-graph-svg'] }"
38
- ref="chartGraphSvg"
39
- x="0"
40
- y="0"
41
- :width="root.state.options.width + 'px'"
42
- :height="root.state.options.allVisibleTasksHeight + 'px'"
43
- xmlns="http://www.w3.org/2000/svg"
44
- >
45
- <days-highlight></days-highlight>
46
- <grid></grid>
47
- <dependency-lines :tasks="root.visibleTasks"></dependency-lines>
48
- <g
49
- class="gantt-elastic__chart-row-wrapper"
50
- :style="{ ...root.style['chart-row-wrapper'] }"
51
- v-for="task in root.visibleTasks"
52
- :task="task"
53
- :key="task.id"
54
- >
55
- <component :task="task" :is="task.type"></component>
56
- </g>
57
- </svg>
58
- </div>
59
- </div>
60
- </div>
61
- </div>
62
- </template>
63
-
64
- <script>
65
- import Grid from './Grid.vue';
66
- import DaysHighlight from './DaysHighlight.vue';
67
- import Calendar from '../Calendar/Calendar.vue';
68
- import DependencyLines from './DependencyLines.vue';
69
- import Task from './Row/Task.vue';
70
- import Milestone from './Row/Milestone.vue';
71
- import Project from './Row/Project.vue';
72
- export default {
73
- name: 'Chart',
74
- components: {
75
- Grid,
76
- DependencyLines,
77
- Calendar,
78
- Task,
79
- Milestone,
80
- Project,
81
- DaysHighlight
82
- },
83
- inject: ['root'],
84
- data() {
85
- return {
86
- moving: false
87
- };
88
- },
89
- /**
90
- * Mounted
91
- */
92
- mounted() {
93
- this.root.state.refs.chart = this.$refs.chart;
94
- this.root.state.refs.chartCalendarContainer = this.$refs.chartCalendarContainer;
95
- this.root.state.refs.chartGraphContainer = this.$refs.chartGraphContainer;
96
- this.root.state.refs.chartGraph = this.$refs.chartGraph;
97
- this.root.state.refs.chartGraphSvg = this.$refs.chartGraphSvg;
98
- },
99
-
100
- computed: {
101
- /**
102
- * Get view box
103
- *
104
- * @returns {string}
105
- */
106
- getViewBox() {
107
- return `0 0 ${this.root.state.options.width} ${this.root.state.options.allVisibleTasksHeight}`;
108
- }
109
- }
110
- };
111
- </script>
@@ -1,71 +0,0 @@
1
-
2
-
3
- <template>
4
- <g
5
- class="gantt-elastic__chart-days-highlight-container"
6
- :style="{ ...root.style['chart-days-highlight-container'] }"
7
- v-if="showWorkingDays"
8
- >
9
- <rect
10
- class="gantt-elastic__chart-days-highlight-rect"
11
- v-for="day in workingDays"
12
- :key="getKey(day)"
13
- :x="day.offset.px"
14
- y="0"
15
- :width="day.width.px"
16
- height="100%"
17
- :style="{ ...root.style['chart-days-highlight-rect'] }"
18
- ></rect>
19
- </g>
20
- </template>
21
-
22
- <script>
23
- import dayjs from 'dayjs';
24
- export default {
25
- name: 'DaysHighlight',
26
- inject: ['root'],
27
- data() {
28
- return {};
29
- },
30
- methods: {
31
- /**
32
- * Get key
33
- *
34
- * @param {object} day
35
- * @returns {string} key ideintifier for loop
36
- */
37
- getKey(day) {
38
- return dayjs(day.time).format('YYYY-MM-DD');
39
- }
40
- },
41
- computed: {
42
- /**
43
- * Get working days
44
- *
45
- * @returns {array}
46
- */
47
- workingDays() {
48
- return this.root.state.options.times.steps.filter(step => {
49
- return this.root.state.options.calendar.workingDays.indexOf(dayjs(step.time).day()) === -1;
50
- });
51
- },
52
-
53
- /**
54
- * Show working days?
55
- *
56
- * @returns {bool}
57
- */
58
- showWorkingDays() {
59
- const calendar = this.root.state.options.calendar;
60
- if (
61
- typeof calendar.workingDays !== 'undefined' &&
62
- Array.isArray(calendar.workingDays) &&
63
- calendar.workingDays.length
64
- ) {
65
- return true;
66
- }
67
- return false;
68
- }
69
- }
70
- };
71
- </script>