layers-design-system 2.3.0 → 2.5.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.
Files changed (186) hide show
  1. package/dist/layers-design-system.js +78496 -0
  2. package/dist/layers-design-system.umd.cjs +285 -0
  3. package/dist/style.css +1 -0
  4. package/package.json +26 -12
  5. package/.nvmrc +0 -1
  6. package/babel.config.js +0 -5
  7. package/src/assets/button-text-editor/double-quotes.svg +0 -4
  8. package/src/assets/button-text-editor/remove-formatting.svg +0 -5
  9. package/src/assets/button-text-editor/title.svg +0 -4
  10. package/src/assets/failed-to-load/failed-to-load.svg +0 -60
  11. package/src/assets/l-presentation/external-apps.png +0 -0
  12. package/src/assets/l-presentation/notification.png +0 -0
  13. package/src/assets/search-topics/empty-tags.svg +0 -59
  14. package/src/components/LAlert/docs.vue +0 -81
  15. package/src/components/LAlert/index.vue +0 -43
  16. package/src/components/LAttachmentChip/docs.vue +0 -84
  17. package/src/components/LAttachmentChip/index.vue +0 -179
  18. package/src/components/LBox/docs.vue +0 -26
  19. package/src/components/LBox/index.vue +0 -19
  20. package/src/components/LBoxHeader/index.vue +0 -24
  21. package/src/components/LBreadcrumb/docs.vue +0 -21
  22. package/src/components/LBreadcrumb/index.vue +0 -22
  23. package/src/components/LBreadcrumbItem/index.vue +0 -7
  24. package/src/components/LButton/docs.vue +0 -205
  25. package/src/components/LButton/index.vue +0 -369
  26. package/src/components/LButtonGroup/index.vue +0 -7
  27. package/src/components/LCarousel/docs.vue +0 -32
  28. package/src/components/LCarousel/index.vue +0 -88
  29. package/src/components/LCheckbox/docs.vue +0 -62
  30. package/src/components/LCheckbox/index.vue +0 -34
  31. package/src/components/LCheckboxButton/index.vue +0 -30
  32. package/src/components/LCheckboxGroup/index.vue +0 -53
  33. package/src/components/LChip/docs.vue +0 -113
  34. package/src/components/LChip/index.vue +0 -78
  35. package/src/components/LCircularLoader/docs.vue +0 -30
  36. package/src/components/LCircularLoader/index.vue +0 -97
  37. package/src/components/LCollapse/docs.vue +0 -68
  38. package/src/components/LCollapse/index.vue +0 -13
  39. package/src/components/LCollapseItem/index.vue +0 -28
  40. package/src/components/LDatePicker/docs.vue +0 -66
  41. package/src/components/LDatePicker/index.vue +0 -63
  42. package/src/components/LDialog/docs.vue +0 -36
  43. package/src/components/LDialog/index.vue +0 -37
  44. package/src/components/LDropdown/index.vue +0 -7
  45. package/src/components/LDropdownItem/index.vue +0 -13
  46. package/src/components/LDropdownMenu/docs.vue +0 -44
  47. package/src/components/LDropdownMenu/index.vue +0 -12
  48. package/src/components/LFailedToLoad/docs.vue +0 -37
  49. package/src/components/LFailedToLoad/index.vue +0 -61
  50. package/src/components/LForm/index.vue +0 -7
  51. package/src/components/LFormItem/index.vue +0 -12
  52. package/src/components/LHelperBox/assets/link.svg +0 -4
  53. package/src/components/LHelperBox/assets/open-envelope.svg +0 -9
  54. package/src/components/LHelperBox/docs.vue +0 -29
  55. package/src/components/LHelperBox/index.vue +0 -83
  56. package/src/components/LIcon/docs.vue +0 -174
  57. package/src/components/LIcon/index.vue +0 -55
  58. package/src/components/LImage/index.vue +0 -7
  59. package/src/components/LImageViewer/docs.vue +0 -111
  60. package/src/components/LImageViewer/index.vue +0 -449
  61. package/src/components/LInput/docs.vue +0 -43
  62. package/src/components/LInput/index.vue +0 -60
  63. package/src/components/LLinearProgress/docs.vue +0 -21
  64. package/src/components/LLinearProgress/index.vue +0 -74
  65. package/src/components/LNotice/docs.vue +0 -26
  66. package/src/components/LNotice/index.vue +0 -86
  67. package/src/components/LNotification/index.vue +0 -182
  68. package/src/components/LOption/index.vue +0 -7
  69. package/src/components/LOptionGroup/index.vue +0 -7
  70. package/src/components/LPresentation/docs.vue +0 -35
  71. package/src/components/LPresentation/index.vue +0 -182
  72. package/src/components/LProgress/index.vue +0 -7
  73. package/src/components/LPromptDialog/index.vue +0 -82
  74. package/src/components/LRadio/docs.vue +0 -54
  75. package/src/components/LRadio/index.vue +0 -13
  76. package/src/components/LRadioButton/index.vue +0 -30
  77. package/src/components/LRadioGroup/index.vue +0 -54
  78. package/src/components/LSearchBar/AddFilterButton.vue +0 -71
  79. package/src/components/LSearchBar/Filters/Editors/AmountEditor.vue +0 -110
  80. package/src/components/LSearchBar/Filters/Editors/DateEditor.vue +0 -146
  81. package/src/components/LSearchBar/Filters/Editors/NumberEditor.vue +0 -141
  82. package/src/components/LSearchBar/Filters/Editors/StringEditor.vue +0 -140
  83. package/src/components/LSearchBar/Filters/Editors/index.js +0 -16
  84. package/src/components/LSearchBar/Filters/FilterChip.vue +0 -105
  85. package/src/components/LSearchBar/Filters/Views/AmountView.vue +0 -28
  86. package/src/components/LSearchBar/Filters/Views/DateView.vue +0 -46
  87. package/src/components/LSearchBar/Filters/Views/NumberView.vue +0 -24
  88. package/src/components/LSearchBar/Filters/Views/StringView.vue +0 -47
  89. package/src/components/LSearchBar/Filters/Views/index.js +0 -16
  90. package/src/components/LSearchBar/docs.vue +0 -60
  91. package/src/components/LSearchBar/index.vue +0 -240
  92. package/src/components/LSearchTopics/RecentTermSearched.vue +0 -30
  93. package/src/components/LSearchTopics/TopicItem.vue +0 -346
  94. package/src/components/LSearchTopics/docs/drawer.vue +0 -254
  95. package/src/components/LSearchTopics/docs.vue +0 -60
  96. package/src/components/LSearchTopics/header.vue +0 -199
  97. package/src/components/LSearchTopics/helpers/showDialogConfirmation.js +0 -30
  98. package/src/components/LSearchTopics/helpers/showDiscardChangesDialog.js +0 -27
  99. package/src/components/LSearchTopics/index.vue +0 -750
  100. package/src/components/LSelect/docs.vue +0 -129
  101. package/src/components/LSelect/index.vue +0 -9
  102. package/src/components/LSlider/index.vue +0 -7
  103. package/src/components/LSwitch/docs.vue +0 -24
  104. package/src/components/LSwitch/index.vue +0 -60
  105. package/src/components/LTabPane/index.vue +0 -7
  106. package/src/components/LTable/FieldTypes/AmountView.vue +0 -16
  107. package/src/components/LTable/FieldTypes/DateView.vue +0 -18
  108. package/src/components/LTable/FieldTypes/EmailView.vue +0 -8
  109. package/src/components/LTable/FieldTypes/NumberView.vue +0 -13
  110. package/src/components/LTable/FieldTypes/PaymentStatusView.vue +0 -8
  111. package/src/components/LTable/FieldTypes/StringView.vue +0 -24
  112. package/src/components/LTable/FieldTypes/index.js +0 -18
  113. package/src/components/LTable/LTableBody.vue +0 -245
  114. package/src/components/LTable/LTableBodySpacer.vue +0 -17
  115. package/src/components/LTable/LTableEndspace.vue +0 -20
  116. package/src/components/LTable/LTableHeader.vue +0 -155
  117. package/src/components/LTable/LTableHeaderCell.vue +0 -188
  118. package/src/components/LTable/LTableHeaderLoader.vue +0 -62
  119. package/src/components/LTable/LTableHeaderResizer.vue +0 -162
  120. package/src/components/LTable/LTableLoadMore.vue +0 -56
  121. package/src/components/LTable/LTablePagination.vue +0 -174
  122. package/src/components/LTable/LTableReloader.vue +0 -61
  123. package/src/components/LTable/ListAdapter.js +0 -74
  124. package/src/components/LTable/docs.vue +0 -111
  125. package/src/components/LTable/helpers.js +0 -194
  126. package/src/components/LTable/index.vue +0 -961
  127. package/src/components/LTabs/docs.vue +0 -28
  128. package/src/components/LTabs/index.vue +0 -37
  129. package/src/components/LTargetChip/docs.vue +0 -86
  130. package/src/components/LTargetChip/index.vue +0 -64
  131. package/src/components/LTargetInput/docs.vue +0 -72
  132. package/src/components/LTargetInput/index.vue +0 -78
  133. package/src/components/LTextEditor/FloatingLink.vue +0 -91
  134. package/src/components/LTextEditor/LinkBox.vue +0 -94
  135. package/src/components/LTextEditor/docs.vue +0 -32
  136. package/src/components/LTextEditor/extensions/LayersBlockquote.js +0 -12
  137. package/src/components/LTextEditor/extensions/LayersBold.js +0 -11
  138. package/src/components/LTextEditor/extensions/LayersBreakLine.js +0 -16
  139. package/src/components/LTextEditor/extensions/LayersBubbleMenu.js +0 -10
  140. package/src/components/LTextEditor/extensions/LayersBulletList.js +0 -12
  141. package/src/components/LTextEditor/extensions/LayersHeading.js +0 -13
  142. package/src/components/LTextEditor/extensions/LayersHistory.js +0 -10
  143. package/src/components/LTextEditor/extensions/LayersItalic.js +0 -11
  144. package/src/components/LTextEditor/extensions/LayersLink.js +0 -29
  145. package/src/components/LTextEditor/extensions/LayersOrderedList.js +0 -12
  146. package/src/components/LTextEditor/extensions/LayersParagraph.js +0 -44
  147. package/src/components/LTextEditor/extensions/LayersPlaceholder.js +0 -11
  148. package/src/components/LTextEditor/extensions/LayersUnderline.js +0 -29
  149. package/src/components/LTextEditor/helpers/addProtocol.js +0 -5
  150. package/src/components/LTextEditor/helpers/removeEmptyTags.js +0 -5
  151. package/src/components/LTextEditor/index.vue +0 -421
  152. package/src/components/LTimeSelect/docs.vue +0 -41
  153. package/src/components/LTimeSelect/index.vue +0 -49
  154. package/src/components/LToggleButtonGroup/index.vue +0 -87
  155. package/src/components/LTooltip/docs.vue +0 -66
  156. package/src/components/LTooltip/index.vue +0 -28
  157. package/src/components/LTransitionExpand/docs.vue +0 -26
  158. package/src/components/LTransitionExpand/index.vue +0 -88
  159. package/src/components/LUpload/index.vue +0 -7
  160. package/src/docs/Colors.vue +0 -50
  161. package/src/docs/Home.vue +0 -11
  162. package/src/docs/Notifications.vue +0 -88
  163. package/src/docs/index.vue +0 -76
  164. package/src/docs/routes.js +0 -20
  165. package/src/helpers/Colors.js +0 -79
  166. package/src/helpers/FieldTypeComponents.js +0 -43
  167. package/src/helpers/Icons.js +0 -67
  168. package/src/helpers/Notification.js +0 -94
  169. package/src/helpers/PrettySize.js +0 -25
  170. package/src/helpers/RegisterElementUIComponents.js +0 -9
  171. package/src/helpers/Schemas.js +0 -18
  172. package/src/helpers/util.js +0 -15
  173. package/src/main-docs.js +0 -132
  174. package/src/main.js +0 -101
  175. package/src/style/colors.scss +0 -31
  176. package/src/style/element-variables.scss +0 -21
  177. package/src/style/icons.scss +0 -5
  178. package/src/style/layers-variables.scss +0 -73
  179. package/src/style/layout.scss +0 -2288
  180. package/src/style/main.scss +0 -11
  181. package/src/style/notifications.scss +0 -88
  182. package/src/style/transitions.scss +0 -43
  183. package/src/style/typography.scss +0 -155
  184. package/vue.config.js +0 -14
  185. /package/{public → dist}/favicon.ico +0 -0
  186. /package/{public → dist}/index.html +0 -0
@@ -1,961 +0,0 @@
1
- <template>
2
- <div
3
- class="l-table-container"
4
- ref="container"
5
- :style="contentStyle"
6
- :class="contentClasses"
7
- @scroll="onScroll">
8
-
9
- <!-- Main table -->
10
- <table class="l-table-table" cellspacing="0" cellpadding="0" border="0">
11
- <!-- Header -->
12
- <LTableHeader
13
- :height="headerHeight"
14
- :selectable="selectable"
15
- :columnSpecs="columnSpecs"
16
- :loading="!!fetching"
17
- :total="totalCount"
18
- :includedIds="includedIds"
19
- :excludedIds="excludedIds"
20
- :multiselect="multiselect"
21
- @selected="changeSelection($event)"
22
- />
23
-
24
- <!-- Preceding body that inflates table -->
25
- <LTableBodySpacer :height="spacing.top" />
26
-
27
- <!-- Pages to present data -->
28
- <LTableBody
29
- v-for="page in visiblePages"
30
- :key="page.index"
31
- :page="page"
32
- :perPage="perPage"
33
- :pagesCount="pagesCount"
34
- :totalCount="totalCount"
35
- :selectable="selectable"
36
- :clickable="clickable"
37
- :columnSpecs="columnSpecs"
38
- :includedIds="includedIds"
39
- :excludedIds="excludedIds"
40
- :multiselect="multiselect"
41
- @click-item="$emit('click-item', $event)"
42
- @selected="changeSelection($event)"
43
- />
44
-
45
-
46
- <!-- Proceding body that inflates table -->
47
- <LTableBodySpacer :height="spacing.bottom"/>
48
- </table>
49
-
50
- <!-- Load More -->
51
- <LTableLoadMore
52
- v-if="isLoadMoreVisible"
53
- @click="loadMore(true)"
54
- @appeared="loadMore()"
55
- :automatic="autoLoadMore"/>
56
-
57
- <!-- Spacer to fill remaining space -->
58
- <LTableEndspace/>
59
-
60
- <!-- Error message -->
61
- <transition name="scale-up">
62
- <LTableReloader v-if="hasVisibleFailedPages" @reload="reloadFailedPages()"/>
63
- </transition>
64
-
65
- <!-- Pagination -->
66
- <LTablePagination
67
- v-if="isPaginationVisible"
68
- :currentPage="currentPage"
69
- :pagesCount="pagesCount"
70
- :totalCount="totalCount"
71
- @goto="gotoPage($event)"/>
72
- </div>
73
- </template>
74
-
75
- <script>
76
- /* eslint-disable no-console */
77
-
78
- import FieldTypes from "./FieldTypes";
79
- FieldTypes.register();
80
-
81
- import LTableBody from "./LTableBody.vue";
82
- import LTableHeader from "./LTableHeader.vue";
83
- import LTableEndspace from "./LTableEndspace.vue"
84
- import LTableLoadMore from "./LTableLoadMore.vue";
85
- import LTableReloader from "./LTableReloader.vue";
86
- import LTableBodySpacer from "./LTableBodySpacer.vue";
87
- import LTablePagination from "./LTablePagination.vue";
88
-
89
- import {changeSelection} from './helpers'
90
-
91
- const SCROLL_DEBOUNCE_MS = 100;
92
- const SCROLL_FAST_SCROLL_SPEED = 30000;
93
- const MAX_PARALEL_RELOADED_PAGES = 3;
94
- const IS_SMOOTH_SCROLL_SUPPORTED = 'scrollBehavior' in document.documentElement.style;
95
-
96
-
97
- export default {
98
- name: "LTable",
99
- tagName: "l-table",
100
-
101
- components: {
102
- LTableHeader,
103
- LTableBody,
104
- LTableReloader,
105
- LTableLoadMore,
106
- LTableEndspace,
107
- LTableBodySpacer,
108
- LTablePagination,
109
- },
110
-
111
- props: {
112
- /**
113
- * Array of items to display as rows.
114
- *
115
- * Each row data must be a object and carry a top level field key
116
- * named equal to the `primaryKey` parameter (defaults to `id`)
117
- */
118
- rows: {
119
- type: Array
120
- },
121
-
122
- /**
123
- * Used to identify the key in item elements
124
- */
125
- primaryKey: {
126
- type: String,
127
- default: "id"
128
- },
129
-
130
- /**
131
- * An async method that gets called for every page load,
132
- * and should reply with data in form of Array of rows
133
- *
134
- * It receives only one parameter with an object consisting of:
135
- * { page: Number, perPage: Number, columns: Array of Column, primaryKey: String }
136
- */
137
- fetch: {
138
- type: Function
139
- },
140
-
141
- /**
142
- * Columns that will be presented on the table
143
- */
144
- columns: {
145
- type: Array
146
- },
147
-
148
- /**
149
- * If it should show pagination or not.
150
- *
151
- * If display is paged, it will always be paginated regardless of this flag.
152
- */
153
- pagination: {
154
- type: Boolean,
155
- default: false
156
- },
157
-
158
- /**
159
- * Display mode of the table:
160
- *
161
- * all: Makes scroll have enought space for all rows regardless of being loaded or not.
162
- * more: Makes scroll until last page loaded. More pages get added once they are loaded.
163
- * paged: Makes scroll have space for a single page of data. Pagination is shown by default.
164
- */
165
- display: {
166
- type: String,
167
- enum: ['all', 'more', 'paged'],
168
- default: 'all',
169
- },
170
-
171
- /**
172
- * Automatic loads more if reached the end on 'more' mode
173
- */
174
- autoLoadMore: {
175
- type: Boolean,
176
- default: false,
177
- },
178
-
179
- /**
180
- * If set, columns might have only the identifier of the field in schema
181
- * and avoid duplication of data inside the columns field
182
- */
183
- schema: {
184
- type: Object,
185
- required: true
186
- },
187
-
188
- /**
189
- * Allows selection to occur
190
- */
191
- selectable: {
192
- type: Boolean,
193
- default: false
194
- },
195
-
196
- /**
197
- * Show cursor pointer on item hover
198
- */
199
- clickable: {
200
- type: Boolean,
201
- default: false
202
- },
203
-
204
- /**
205
- * Allows more than one item to be selected
206
- */
207
- multiselect: {
208
- type: Boolean,
209
- default: true
210
- },
211
-
212
- /**
213
- * If enabled, will allow a "inverse" selection to occur, in order to
214
- * select huge amounts of unloaded items.
215
- */
216
- allowInvertedSelection: {
217
- type: Boolean,
218
- default: true
219
- },
220
-
221
- /**
222
- * The height in pixels of each line. Must be set to a number that exactly
223
- * matches the table.
224
- *
225
- * If this size differs from actual size in dom, recycling will not work properly
226
- */
227
- rowHeight: {
228
- type: Number,
229
- default: 32
230
- },
231
-
232
- /**
233
- * Tickness of the border rows
234
- */
235
- borderTick: {
236
- type: Number,
237
- default: 1
238
- },
239
-
240
- /**
241
- * Snaps the viewport to the new page being loaded after triggering the loadmore
242
- */
243
- snapToPageOnMore: {
244
- type: Boolean,
245
- default: true,
246
- },
247
-
248
- /**
249
- * Forces first left column to be sticky
250
- */
251
- stickyColumnLeft: {
252
- type: Boolean,
253
- default: false,
254
- },
255
-
256
- /**
257
- * If possible, will use recycle layout in order to prevent large volumes of rows being rendered
258
- */
259
- recycle: {
260
- type: Boolean,
261
- default: true,
262
- },
263
-
264
- /**
265
- * If set, will load this number of rows at a time
266
- */
267
- limitPerPage: {
268
- type: Number,
269
- default: 50,
270
- },
271
- },
272
-
273
- mounted() {
274
- this.computeVisibleRows();
275
- },
276
-
277
- data() {
278
- return {
279
- fetching: 0,
280
- headerHeight: 56,
281
-
282
- nonce: 0,
283
-
284
- // Internal identification for hole state of loaded pages
285
- id: 0,
286
- extraRows: 15,
287
-
288
- lastComputedOffsetY: 0,
289
-
290
- includedIds: [],
291
- excludedIds: [],
292
-
293
- scrollAtTop: true,
294
- scrollAtLeft: true,
295
-
296
- totalCount: 0,
297
- firstPage: null,
298
- currentPage: null,
299
- lastPage: null,
300
-
301
- loadedPages: []
302
- };
303
- },
304
-
305
- watch: {
306
- totalCount(val) {
307
- this.$emit('changeSelection', {
308
- includedIds: this.includedIds,
309
- excludedIds: this.excludedIds,
310
- selectionCount: this.selectionCount,
311
- totalCount: val
312
- })
313
- },
314
- somePageIsLoading(val) {
315
- this.$emit('loading', val)
316
- }
317
- },
318
-
319
- computed: {
320
-
321
- perPage() {
322
- return this.limitPerPage;
323
- },
324
-
325
- pagesCount() {
326
- return Math.floor(this.totalCount / this.perPage) + 1;
327
- },
328
-
329
- selectionCount() {
330
- if (this.includedIds.toString() === "*") {
331
- return this.totalCount - this.excludedIds.length;
332
- }
333
-
334
- return this.includedIds.length;
335
- },
336
-
337
- lastLoadedPage() {
338
- return this.loadedPages.length
339
- },
340
-
341
- isLoadMoreVisible() {
342
- return this.display === 'more' && (this.lastLoadedPage < this.pagesCount)
343
- },
344
-
345
- isPaginationVisible() {
346
- return (this.display === 'page' || !!this.pagination) && (this.display !== 'more') && this.pagesCount !== null
347
- },
348
-
349
- isLeftColumnSticky() {
350
- return this.stickyColumnLeft || (this.columns && this.columns[0] && this.columns[0].sticky)
351
- },
352
-
353
- usingRecycledLayout() {
354
- return this.display !== 'paged' && this.recycle
355
- },
356
-
357
- hasVisibleFailedPages() {
358
- for (let page = this.firstPageRendered; page <= this.lastPageRendered; page++) {
359
- if (this.loadedPages[page] && this.loadedPages[page].failed) {
360
- return true
361
- }
362
- }
363
- return false
364
- },
365
-
366
- firstPageRendered() {
367
- // Render from page 0 if not using recycledLayout
368
- if (!this.usingRecycledLayout && this.display !== 'paged') {
369
- return 0
370
- }
371
-
372
- return this.firstPage
373
- },
374
-
375
- lastPageRendered() {
376
- // Force one page being rendered on paged mode
377
- if (this.display === 'paged') {
378
- return this.firstPage
379
- }
380
-
381
- // If not using recycled layout, we should limit to the number of currently loadedPages
382
- if (!this.usingRecycledLayout) {
383
- return Math.max(0, this.lastLoadedPage - 1)
384
- }
385
-
386
- return this.lastPage
387
- },
388
-
389
- visiblePages() {
390
- let pages = [];
391
-
392
- for (let i = this.firstPageRendered; i <= this.lastPageRendered; i++) {
393
- let pageData = this.loadedPages[i] || {index: i}
394
- pages.push(pageData);
395
- }
396
-
397
- return pages;
398
- },
399
- contentStyle() {
400
- return {
401
- // General
402
- "--l-table-primary-color": "#2F8AF5",
403
- "--l-table-warning-color": "#fd3a57",
404
- "--l-table-bg-color": "white",
405
-
406
- // Header
407
- "--l-table-header-height": `${this.headerHeight}px`,
408
- "--l-table-header-text-color": "#232B34",
409
- "--l-table-header-border-color": "#E8E8E8",
410
-
411
- // Loader and Skeleton
412
- "--l-table-skeleton-height": `${Math.min(this.rowHeight - 8, 8)}px`,
413
- "--l-table-loader-height": "3px",
414
- "--l-table-loader-color": "var(--l-table-primary-color)",
415
-
416
- // Rows
417
- "--l-table-row-height": `${this.rowHeight}px`,
418
- "--l-table-cell-padding": "0 8px",
419
- "--l-table-row-hover-color": "#fafbfd",
420
- "--l-table-row-selected-color": "#eef5fa",
421
- "--l-table-row-selected-hover-color": "#e6f0f8",
422
- "--l-table-border-color": "#D3DAE6",
423
- "--l-table-border-tick": `${this.borderTick}px`,
424
-
425
- // Selector
426
- "--l-table-selector-width": `${this.selectable ? Math.min(this.headerHeight, this.rowHeight) : 0}px`,
427
-
428
- // Load more
429
- "--l-table-loadmore-height": "46px",
430
-
431
- // Pagination
432
- '--l-table-pagination-height': '48px',
433
- '--l-table-pagination-color': 'var(--l-table-primary-color)',
434
- '--l-table-pagination-bg-color': 'white',
435
-
436
- // Reloader
437
- '--l-table-reloader-margin': '16px',
438
-
439
- // Endspace
440
- '--l-table-endspace-bg-color': '#f5f5f5',
441
-
442
- // Links
443
- '--l-table-link-color': 'var(--l-table-primary-color)',
444
- };
445
- },
446
-
447
- contentClasses() {
448
- return {
449
- "l-table-at-top": this.scrollAtTop,
450
- "l-table-at-left": this.scrollAtLeft,
451
- "l-table-sticky-column-left": this.isLeftColumnSticky,
452
- };
453
- },
454
-
455
- spacing() {
456
- let top = 0
457
- let bottom = 0
458
- let display = this.display
459
- let totalCount = this.totalCount
460
-
461
- // Override totalCount on more mode, to make it fill until last loaded page
462
- if (display === 'more') {
463
- totalCount = this.loadedPages.length * this.perPage
464
- }
465
-
466
- if (display === 'all' || display === 'more') {
467
- // Add spacing before
468
- top = this.firstPageRendered * this.perPage * this.rowHeight
469
-
470
- // Add spacing after
471
- bottom = Math.max(0, (totalCount - (this.lastPageRendered + 1) * this.perPage) * this.rowHeight)
472
- }
473
-
474
- // console.log({top, bottom, totalCount: this.totalCount, lastPage: this.lastPage, pagesCount: this.pagesCount, perPage: this.perPage})
475
- return {
476
- top: Math.max(0, top),
477
- bottom: Math.max(0, bottom),
478
- };
479
- },
480
-
481
- // Aggregate of all asked columns and their schema
482
- columnSpecs() {
483
- if (!this.columns) {
484
- return [];
485
- }
486
-
487
- return this.columns.map(col => this.buildColumnSpec(col));
488
- },
489
-
490
- rect() {
491
- return this.$refs.container.getBoundingClientRect();
492
- },
493
-
494
- somePageIsLoading() {
495
- return this.loadedPages.map(page => page.loading).some(loading => loading)
496
- }
497
- },
498
-
499
- methods: {
500
- itemToId(entity) {
501
- if (!entity) return null;
502
-
503
- if (this.primaryKey) return entity[this.primaryKey];
504
-
505
- return entity;
506
- },
507
-
508
- scrollTo(offset = 0, smooth) {
509
- // Add smooth behavior only if distance to target is not so high
510
- let behavior = 'auto'
511
- if (smooth) {
512
- let scrollTop = this.$refs.container.scrollTop
513
- let maxSmoothDistance = this.perPage * this.rowHeight + 1
514
- behavior = Math.abs(scrollTop - offset) < maxSmoothDistance ? 'smooth' : 'auto'
515
- }
516
-
517
- // Scroll to target
518
- this.$refs.container.scrollTo({top: offset, behavior})
519
- },
520
-
521
- gotoPage(pageIndex, smooth) {
522
- pageIndex = Math.max(0, Math.min(this.pagesCount, pageIndex))
523
-
524
- if (this.display === 'paged') {
525
- this.setViewablePages(pageIndex, pageIndex, pageIndex)
526
- this.scrollTo(0, true)
527
- return
528
- }
529
-
530
- // Set viewable pages depending on display mode
531
- if (this.display === 'more') {
532
- this.setViewablePages(pageIndex - 1, pageIndex, pageIndex)
533
- } else {
534
- this.setViewablePages(pageIndex, pageIndex, pageIndex)
535
- }
536
-
537
- // Scroll into view
538
- let offset = pageIndex * this.rowHeight * this.perPage
539
- this.scrollTo(offset, smooth)
540
- },
541
-
542
- async loadMore(allowSnap) {
543
- // Check if its already loading last page
544
- let lastPage = this.loadedPages[this.loadedPages.length - 1]
545
-
546
- if (!lastPage || lastPage.loading) {
547
- return false
548
- }
549
-
550
- // Trigger load
551
- let nextPage = this.loadedPages.length
552
-
553
- this.setViewablePages(this.firstPage, nextPage)
554
- if (allowSnap && this.snapToPageOnMore && IS_SMOOTH_SCROLL_SUPPORTED) {
555
- setTimeout(() => this.gotoPage(nextPage, true), 100)
556
- }
557
- },
558
-
559
- reload() {
560
- this.id++
561
- this.fetching = 0;
562
- this.firstPage = null
563
- this.lastPage = null
564
- this.totalCount = null
565
- this.loadedPages = [];
566
- this.includedIds = [];
567
- this.excludedIds = [];
568
- this.gotoPage(0)
569
- this.computeVisibleRows();
570
- },
571
-
572
- /**
573
- * Forces reloading of failed pages that are visible
574
- */
575
- reloadFailedPages() {
576
- // Safe guard to prevent too many reloads
577
- let reloadedPages = 0
578
-
579
- // Iterate visible pages and re-fetches
580
- for (let page = this.firstPageRendered; page <= this.lastPageRendered; page++) {
581
- // If not failed, continue
582
- if (!this.loadedPages[page] || !this.loadedPages[page].failed) {
583
- continue
584
- }
585
-
586
- // Remove page data
587
- this.$set(this.loadedPages, page, null)
588
-
589
- // Re-fetch page
590
- this.fetchPage(page)
591
-
592
- // Safe guard
593
- if (++reloadedPages >= MAX_PARALEL_RELOADED_PAGES) {
594
- break;
595
- }
596
- }
597
- },
598
-
599
- onScroll() {
600
- // Paged mode doesnt need scroll events
601
- // if (this.display === 'paged') {
602
- // return
603
- // }
604
-
605
- // Is it too fast?
606
- let scrollSpeed = this.getScrollSpeed();
607
- let tooFast = scrollSpeed > SCROLL_FAST_SCROLL_SPEED;
608
-
609
- // Not too fast and is not currently inside a debounce
610
- if (!tooFast && !this._scrollDebounce) {
611
- return this.computeVisibleRows();
612
- }
613
-
614
- // Post compute visible rows if its too fast scrolling
615
- clearTimeout(this._scrollDebounce);
616
- this._scrollDebounce = setTimeout(() => {
617
- this.computeVisibleRows();
618
- this._scrollDebounce = null;
619
- }, SCROLL_DEBOUNCE_MS);
620
- },
621
-
622
- getScrollSpeed() {
623
- // Check if is scrolling too fast and postergate computation
624
- let lastOffsetY = this._lastOffsetY || 0;
625
- let lastOffsetYTime = this._lastOffsetYTime || 0;
626
- let offsetY = (this._lastOffsetY = this.$refs.container.scrollTop);
627
- let offsetYTime = (this._lastOffsetYTime = Date.now());
628
- let speedY = Math.abs(
629
- (1000 * (lastOffsetY - offsetY)) / (offsetYTime - lastOffsetYTime)
630
- );
631
- return speedY;
632
- },
633
-
634
- computeVisibleRows() {
635
- // Read scroll offset from container
636
- let offsetY = this.$refs.container.scrollTop;
637
- let offsetX = this.$refs.container.scrollLeft;
638
- let lastComputedOffsetY = this.lastComputedOffsetY;
639
-
640
- // Check if is at top/left
641
- this.scrollAtTop = offsetY === 0;
642
- this.scrollAtLeft = offsetX === 0;
643
-
644
- // Skip computation on small scrolling
645
- let deltaY = Math.abs(lastComputedOffsetY - offsetY);
646
- if (offsetY > 2 && lastComputedOffsetY > 2 && deltaY < 150) {
647
- return;
648
- }
649
- // Update last offsetY
650
- this.lastComputedOffsetY = offsetY;
651
-
652
- // Paged mode doesnt compute visible rows
653
- if (this.display === 'paged') {
654
- return
655
- }
656
-
657
- // Compute and get height of container
658
- let rect = this.rect;
659
- let height = rect.height - this.headerHeight;
660
-
661
- // Compute the first row index visible in the table
662
- let firstRow = Math.max(0, Math.floor(offsetY / this.rowHeight));
663
- let visibleRows = Math.ceil(height / this.rowHeight);
664
- let lastRow = firstRow + visibleRows;
665
-
666
- // Compute first and last visible page
667
- let extraRows = this.extraRows;
668
- let perPage = this.perPage;
669
- let firstPage = Math.floor((firstRow - extraRows) / this.perPage);
670
- let lastPage = Math.floor((lastRow + extraRows) / perPage);
671
-
672
- // Find out best page to set as current
673
- let currentPageExtraRows = (lastPage >= this.pagesCount - 1) ? visibleRows : visibleRows / 2
674
- let currentPage = Math.floor((firstRow + currentPageExtraRows) / this.perPage);
675
-
676
- // If operating in 'more' mode, limit firstPage and lastPage
677
- if (this.display === 'more') {
678
- firstPage = Math.min(firstPage, this.lastLoadedPage)
679
- while(!this.loadedPages[firstPage] && firstPage > 0) {
680
- firstPage--
681
- }
682
- lastPage = Math.max(lastPage, firstPage)
683
- while(!this.loadedPages[lastPage] && lastPage > firstPage && lastPage > 0) {
684
- lastPage--
685
- }
686
- }
687
-
688
- // Updates first and lastPage
689
- this.setViewablePages(firstPage, lastPage, currentPage)
690
- },
691
-
692
- setViewablePages(firstPage = 0, lastPage = 0, currentPage = 0) {
693
- // console.log('setViewablePages', {firstPage, lastPage, pagesCount: this.pagesCount})
694
- // If operating in paged mode, lastPage always equals firstPage
695
- if (this.display === 'paged') {
696
- lastPage = firstPage
697
- }
698
-
699
- // Limit first/last page indexes
700
- firstPage = Math.min(Math.max(firstPage, 0), this.pagesCount - 1);
701
- lastPage = Math.min(Math.max(lastPage, firstPage), this.pagesCount - 1);
702
- currentPage = Math.min(lastPage, Math.max(firstPage, currentPage || 0));
703
-
704
- // Check if changed pages
705
- let pagesChanged =
706
- firstPage !== this.firstPage || lastPage !== this.lastPage;
707
-
708
- // Save pages indexes
709
- this.firstPage = firstPage;
710
- this.lastPage = lastPage;
711
- this.currentPage = currentPage
712
-
713
- // Schedule fetching on change
714
- if (pagesChanged) {
715
- // console.log('setViewablePages pagesChanged', firstPage, lastPage)
716
- this.scheduleFeching();
717
- }
718
- },
719
-
720
- buildColumnSpec(column) {
721
- if (!this.schema.fields) {
722
- throw new Error("Missing schema.fields!");
723
- }
724
- const field = this.schema.fields.find(c => c.path === column.path);
725
- if (!field) {
726
- throw new Error(`Missing field schema for path ${column.path}`);
727
- }
728
- const component = this.$L.FieldTypeComponents.get(field, "default");
729
-
730
- return Object.assign({}, field, {
731
- width: column.width || null,
732
- sortable: field ? field.sortable : false,
733
- sticky: (field && field.sticky) || column.sticky || false,
734
- align: (field && field.align) || "left",
735
- column,
736
- field,
737
- component
738
- });
739
- },
740
-
741
- changeSelection({ key, selected }) {
742
- const { includedIds, excludedIds } = changeSelection({key, selected}, this)
743
- this.includedIds = includedIds
744
- this.excludedIds = excludedIds
745
-
746
- this.$nextTick(() => {
747
- this.$emit('changeSelection', {
748
- includedIds: this.includedIds,
749
- excludedIds: this.excludedIds,
750
- selectionCount: this.selectionCount,
751
- totalCount: this.totalCount
752
- })
753
- })
754
- },
755
-
756
- scheduleFeching() {
757
- for (let page = this.firstPage; page <= this.lastPage; page++) {
758
- this.fetchPage(page);
759
- }
760
- },
761
-
762
- async fetchPage(page) {
763
- // Check if page is fetched and return same reference
764
- let pageData = this.loadedPages[page];
765
- if (pageData) {
766
- return pageData;
767
- }
768
-
769
- // Get current hash of params to know if still the same after fetching
770
- pageData = this.$set(this.loadedPages, page, {
771
- id: this.id,
772
- index: page,
773
- startedAt: Date.now(),
774
- duration: null,
775
- loading: true,
776
- loaded: false,
777
- failed: false,
778
- error: null,
779
- data: null
780
- });
781
-
782
- // Fetch page data (internal or external)
783
- try {
784
- // Increment fetching stack
785
- this.fetching++
786
-
787
- // Do fetching from remote source or local source
788
- const { hits, total } = await this.resolvePageData(page);
789
-
790
- // Update result data and loaded flag
791
- Object.assign(pageData, {
792
- duration: Date.now() - pageData.startedAt,
793
- loading: false,
794
- loaded: true,
795
- data: hits
796
- });
797
-
798
- // Verifies if page data still valid
799
- // (might have been replaced due to async task delay)
800
- let stillValid = this.loadedPages.indexOf(pageData) >= 0;
801
-
802
- // Update total if set and pageData still recent
803
- if (total !== undefined && stillValid) {
804
- this.totalCount = total;
805
- }
806
-
807
- // console.log("fetching complete", {
808
- // page,
809
- // complete: true,
810
- // total,
811
- // stillValid,
812
- // pageData
813
- // });
814
- } catch (e) {
815
- console.error("LTable", 'Failed to call `fetch` callback', e);
816
- Object.assign(pageData, {
817
- loading: false,
818
- failed: true,
819
- error: e.toString()
820
- });
821
- } finally {
822
- // Only decrement fetching stack if id of state matches
823
- if (this.id === pageData.id) {
824
- this.fetching--
825
- }
826
- }
827
-
828
- return pageData;
829
- },
830
-
831
- async resolvePageData(page) {
832
- if (this.rows) {
833
- // Slice rows and get page data
834
- let perPage = this.perPage;
835
- let begin = page * perPage;
836
- return {
837
- data: this.rows.slice(begin, begin + perPage),
838
- total: this.rows.length
839
- };
840
- } else if (this.fetch) {
841
- // Call external fetching and get data
842
- return await this.fetch({
843
- page,
844
- offset: page * this.perPage,
845
- limit: this.perPage,
846
- schema: this.schema,
847
- columns: this.columns,
848
- perPage: this.perPage,
849
- primaryKey: this.primaryKey
850
- });
851
- } else {
852
- throw new Error(
853
- "Cannot discover data. Either `rows` or `fetch` property must be assigned to table"
854
- );
855
- }
856
- }
857
- }
858
- };
859
- </script>
860
-
861
- <style>
862
- .l-table-container {
863
- position: relative;
864
-
865
- display: flex;
866
- flex-direction: column;
867
-
868
- overflow-y: auto;
869
- overflow-x: auto;
870
- overscroll-behavior-x: none;
871
- }
872
-
873
- /* Native Table style */
874
- .l-table-table {
875
- flex: 0 0 auto;
876
- min-width: 100%;
877
- border-spacing: 0;
878
- box-sizing: border-box;
879
- font-size: 0.875rem;
880
- }
881
-
882
- /* Internal selection column (both header and body) */
883
- .l-table-column-selector {
884
- padding: 0 !important;
885
- text-align: center !important;
886
- width: var(--l-table-selector-width);
887
- min-width: var(--l-table-selector-width);
888
- max-width: var(--l-table-selector-width);
889
- }
890
-
891
- /**
892
- Sticky columns and Shadows
893
- */
894
- .l-table-column-selector {
895
- position: sticky;
896
- z-index: 2;
897
- left: 0;
898
- background: inherit;
899
- }
900
-
901
- /* Enables first column on left to to be sticky */
902
- .l-table-container.l-table-sticky-column-left .l-table-column-selector + .l-table-cell,
903
- .l-table-container.l-table-sticky-column-left .l-table-cell:not(.l-table-column-selector):first-child,
904
- .l-table-container.l-table-sticky-column-left .l-table-column-selector + .l-table-header-cell {
905
- position: sticky;
906
- z-index: 2;
907
- left: var(--l-table-selector-width);
908
- background: inherit;
909
- }
910
-
911
- /* Let it be over other headers while being dragged/resized */
912
- .l-table-header-cell:active {
913
- z-index: 5;
914
- }
915
-
916
- /* Header sticky cells should be on top of normal ones */
917
- .l-table-column-selector.l-table-header-cell,
918
- .l-table-container.l-table-sticky-column-left .l-table-header .l-table-column-selector + .l-table-cell,
919
- .l-table-container.l-table-sticky-column-left .l-table-header .l-table-cell:not(.l-table-column-selector):first-child,
920
- .l-table-container.l-table-sticky-column-left .l-table-header .l-table-column-selector + .l-table-header-cell {
921
- z-index: 8;
922
- }
923
-
924
- /* Applies shadow to the right of the last sticky column */
925
- .l-table-container.l-table-sticky-column-left .l-table-column-selector + .l-table-cell:after,
926
- .l-table-container.l-table-sticky-column-left .l-table-cell:not(.l-table-column-selector):first-child:after,
927
- .l-table-container:not(.l-table-sticky-column-left) .l-table-cell.l-table-column-selector:after
928
- {
929
- opacity: 1;
930
- content: ' ';
931
- position: absolute;
932
- top: 0;
933
- bottom: 0;
934
- right: -4px;
935
- width: 4px;
936
- background-image: linear-gradient(to right, rgba(0,0,0,0.1), transparent);
937
- z-index: 9;
938
- pointer-events: none;
939
- transition: opacity 0.2s;
940
- }
941
-
942
- /* Hides left shadow if at left of scroll */
943
- .l-table-container.l-table-sticky-column-left.l-table-at-left .l-table-column-selector + .l-table-cell:after,
944
- .l-table-container.l-table-sticky-column-left.l-table-at-left .l-table-cell:not(.l-table-column-selector):first-child:after,
945
- .l-table-container.l-table-at-left:not(.l-table-sticky-column-left) .l-table-cell.l-table-column-selector:after {
946
- opacity: 0;
947
- }
948
-
949
-
950
- /* Bottom widgets Transition */
951
- .scale-up-enter-active {
952
- transition: all .3s ease;
953
- }
954
- .scale-up-leave-active {
955
- transition: all .3s ease;
956
- }
957
- .scale-up-enter, .scale-up-leave-to {
958
- transform: rotateX(30deg) translateY(10px);
959
- opacity: 0;
960
- }
961
- </style>