apostrophe 4.4.2 → 4.5.0

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 (85) hide show
  1. package/CHANGELOG.md +62 -3
  2. package/index.js +2 -3
  3. package/lib/glob.js +12 -0
  4. package/lib/moog-require.js +3 -3
  5. package/modules/@apostrophecms/admin-bar/index.js +9 -2
  6. package/modules/@apostrophecms/admin-bar/ui/apos/apps/AposAdminBar.js +1 -1
  7. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextBar.vue +2 -2
  8. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextTitle.vue +0 -1
  9. package/modules/@apostrophecms/area/ui/apos/components/AposAreaContextualMenu.vue +2 -2
  10. package/modules/@apostrophecms/area/ui/apos/components/AposAreaEditor.vue +6 -6
  11. package/modules/@apostrophecms/area/ui/apos/components/AposAreaExpandedMenu.vue +7 -1
  12. package/modules/@apostrophecms/asset/index.js +5 -6
  13. package/modules/@apostrophecms/command-menu/index.js +7 -2
  14. package/modules/@apostrophecms/doc/index.js +2 -2
  15. package/modules/@apostrophecms/doc-type/index.js +1 -1
  16. package/modules/@apostrophecms/i18n/i18n/en.json +37 -1
  17. package/modules/@apostrophecms/i18n/index.js +2 -2
  18. package/modules/@apostrophecms/i18n/ui/apos/components/AposI18nLocalize.vue +5 -5
  19. package/modules/@apostrophecms/image/index.js +1 -1
  20. package/modules/@apostrophecms/image/ui/apos/components/AposImageRelationshipEditor.vue +4 -3
  21. package/modules/@apostrophecms/image/ui/apos/components/AposMediaManager.vue +221 -76
  22. package/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerDisplay.vue +91 -24
  23. package/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerEditor.vue +48 -51
  24. package/modules/@apostrophecms/image/ui/apos/components/AposMediaManagerSelections.vue +1 -0
  25. package/modules/@apostrophecms/login/index.js +3 -3
  26. package/modules/@apostrophecms/modal/ui/apos/components/AposDocsManagerToolbar.vue +3 -11
  27. package/modules/@apostrophecms/modal/ui/apos/components/AposModal.vue +4 -12
  28. package/modules/@apostrophecms/modal/ui/apos/components/AposModalBody.vue +20 -6
  29. package/modules/@apostrophecms/modal/ui/apos/components/AposModalBreadcrumbs.vue +1 -1
  30. package/modules/@apostrophecms/modal/ui/apos/components/AposModalShareDraft.vue +1 -1
  31. package/modules/@apostrophecms/modal/ui/apos/components/AposModalTabs.vue +3 -5
  32. package/modules/@apostrophecms/modal/ui/apos/components/AposWidgetModalTabs.vue +3 -5
  33. package/modules/@apostrophecms/modal/ui/apos/mixins/AposDocErrorsMixin.js +2 -2
  34. package/modules/@apostrophecms/modal/ui/apos/mixins/AposDocsManagerMixin.js +44 -39
  35. package/modules/@apostrophecms/modal/ui/apos/mixins/AposModalTabsMixin.js +2 -2
  36. package/modules/@apostrophecms/oembed/index.js +2 -2
  37. package/modules/@apostrophecms/oembed-field/ui/apos/components/AposInputOembed.vue +2 -2
  38. package/modules/@apostrophecms/page/index.js +5 -2
  39. package/modules/@apostrophecms/page/ui/apos/components/AposPagesManager.vue +1 -2
  40. package/modules/@apostrophecms/page/ui/apos/logic/AposPagesManager.js +14 -7
  41. package/modules/@apostrophecms/piece-type/index.js +5 -2
  42. package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManager.vue +23 -11
  43. package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManagerDisplay.vue +4 -1
  44. package/modules/@apostrophecms/rich-text-widget/index.js +31 -3
  45. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapColor.vue +285 -0
  46. package/modules/@apostrophecms/rich-text-widget/ui/apos/tiptap-extensions/Color.js +5 -0
  47. package/modules/@apostrophecms/schema/lib/addFieldTypes.js +38 -25
  48. package/modules/@apostrophecms/schema/ui/apos/components/AposInputBoolean.vue +2 -2
  49. package/modules/@apostrophecms/schema/ui/apos/components/AposInputColor.vue +0 -1
  50. package/modules/@apostrophecms/schema/ui/apos/components/AposInputObject.vue +1 -0
  51. package/modules/@apostrophecms/schema/ui/apos/components/AposInputWrapper.vue +13 -2
  52. package/modules/@apostrophecms/schema/ui/apos/logic/AposArrayEditor.js +11 -9
  53. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputArea.js +4 -4
  54. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputArray.js +7 -7
  55. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputObject.js +11 -0
  56. package/modules/@apostrophecms/schema/ui/apos/logic/AposInputSlug.js +45 -51
  57. package/modules/@apostrophecms/schema/ui/apos/logic/AposSchema.js +3 -1
  58. package/modules/@apostrophecms/schema/ui/apos/mixins/AposInputMixin.js +1 -1
  59. package/modules/@apostrophecms/submitted-draft/index.js +2 -2
  60. package/modules/@apostrophecms/ui/ui/apos/components/AposButton.vue +7 -3
  61. package/modules/@apostrophecms/ui/ui/apos/components/AposButtonSplit.vue +0 -1
  62. package/modules/@apostrophecms/ui/ui/apos/components/AposContextMenu.vue +12 -4
  63. package/modules/@apostrophecms/ui/ui/apos/components/AposFile.vue +4 -4
  64. package/modules/@apostrophecms/ui/ui/apos/components/AposFilterMenu.vue +2 -1
  65. package/modules/@apostrophecms/ui/ui/apos/components/AposLoading.vue +1 -1
  66. package/modules/@apostrophecms/ui/ui/apos/components/AposLoadingBlock.vue +50 -0
  67. package/modules/@apostrophecms/ui/ui/apos/components/AposSlat.vue +0 -1
  68. package/modules/@apostrophecms/ui/ui/apos/components/AposSlatList.vue +6 -4
  69. package/modules/@apostrophecms/ui/ui/apos/components/AposTagApply.vue +17 -11
  70. package/modules/@apostrophecms/ui/ui/apos/components/AposTree.vue +2 -2
  71. package/modules/@apostrophecms/ui/ui/apos/components/AposTreeRows.vue +2 -2
  72. package/modules/@apostrophecms/ui/ui/apos/lib/tooltip.js +2 -2
  73. package/modules/@apostrophecms/ui/ui/apos/stores/modal.js +3 -3
  74. package/modules/@apostrophecms/user/index.js +1 -0
  75. package/modules/@apostrophecms/util/index.js +12 -4
  76. package/modules/@apostrophecms/widget-type/ui/apos/components/AposWidgetEditor.vue +2 -2
  77. package/package.json +8 -7
  78. package/scripts/lint-i18n.js +8 -3
  79. package/test/command-menu.js +76 -12
  80. package/test/pages-rest.js +102 -0
  81. package/test/pieces.js +133 -10
  82. package/test/recursionGuard.js +5 -5
  83. package/test/schemas.js +1 -1
  84. package/test/utils/commands.js +26 -0
  85. package/test-lib/util.js +2 -2
@@ -50,45 +50,50 @@
50
50
  </AposModalRail>
51
51
  </template>
52
52
  <template #main>
53
- <AposModalBody>
53
+ <AposLoadingBlock v-if="isFirstLoading" />
54
+ <AposModalBody v-else>
54
55
  <template #bodyHeader>
55
56
  <AposDocsManagerToolbar
56
57
  :selected-state="selectAllState"
57
58
  :total-pages="totalPages"
58
59
  :current-page="currentPage"
59
60
  :filters="toolbarFilters"
61
+ :filter-values="filterValues"
60
62
  :labels="moduleLabels"
61
63
  :disable="relationshipErrors === 'min'"
62
64
  :displayed-items="items.length"
63
65
  :checked="checked"
64
66
  :checked-count="checked.length"
65
67
  :module-name="moduleName"
66
- @page-change="updatePage"
68
+ :options="{noPager: true}"
67
69
  @select-click="selectClick"
68
70
  @search="search"
69
71
  @filter="filter"
70
72
  />
71
73
  </template>
72
74
  <template #bodyMain>
75
+ <AposLoadingBlock v-if="isLoading" />
73
76
  <AposMediaManagerDisplay
77
+ v-else
74
78
  ref="display"
75
- :checked="checked"
79
+ v-model:checked="checked"
76
80
  :accept="accept"
77
81
  :items="items"
78
82
  :module-options="moduleOptions"
79
83
  :max-reached="maxReached()"
84
+ :is-last-page="isLastPage"
80
85
  :options="{
81
- disableUnchecked: maxReached(),
82
86
  hideCheckboxes: !relationshipField
83
87
  }"
84
- @update:checked="setCheckedDocs"
88
+ :relationship-field="relationshipField"
89
+ :is-scroll-loading="isScrollLoading"
85
90
  @edit="updateEditing"
86
91
  @select="select"
87
92
  @select-series="selectSeries"
88
93
  @select-another="selectAnother"
89
- @upload-started="uploading = true"
90
94
  @upload-complete="completeUploading"
91
95
  @create-placeholder="createPlaceholder"
96
+ @set-load-ref="setLoadRef"
92
97
  />
93
98
  </template>
94
99
  </AposModalBody>
@@ -102,16 +107,14 @@
102
107
  <AposMediaManagerEditor
103
108
  v-show="editing"
104
109
  :media="editing"
105
- :selected="selected"
106
110
  :is-modified="isModified"
107
111
  :module-labels="moduleLabels"
108
112
  @back="updateEditing(null)"
109
- @saved="updateMedia"
110
113
  @modified="editorModified"
111
114
  />
112
115
  <AposMediaManagerSelections
113
116
  v-show="!editing"
114
- :items="selected"
117
+ :items="checkedDocs"
115
118
  @clear="clearSelected"
116
119
  @edit="updateEditing"
117
120
  />
@@ -122,9 +125,12 @@
122
125
  </template>
123
126
 
124
127
  <script>
128
+ import { debounce } from 'Modules/@apostrophecms/ui/utils';
125
129
  import AposModifiedMixin from 'Modules/@apostrophecms/ui/mixins/AposModifiedMixin';
126
130
  import AposDocsManagerMixin from 'Modules/@apostrophecms/modal/mixins/AposDocsManagerMixin';
127
- import cuid from 'cuid';
131
+ import { createId } from '@paralleldrive/cuid2';
132
+
133
+ const DEBOUNCE_TIMEOUT = 500;
128
134
 
129
135
  export default {
130
136
  mixins: [ AposModifiedMixin, AposDocsManagerMixin ],
@@ -138,6 +144,10 @@ export default {
138
144
  data() {
139
145
  return {
140
146
  items: [],
147
+ isFirstLoading: true,
148
+ isLoading: false,
149
+ isScrollLoading: false,
150
+ loadRef: null,
141
151
  totalPages: 1,
142
152
  currentPage: 1,
143
153
  tagList: [],
@@ -149,14 +159,22 @@ export default {
149
159
  },
150
160
  editing: undefined,
151
161
  modified: false,
152
- uploading: false,
153
162
  lastSelected: null,
154
163
  emptyDisplay: {
155
164
  title: 'apostrophe:noMediaFound',
156
165
  message: 'apostrophe:uploadedMediaPlaceholder',
157
166
  emoji: '🖼'
158
167
  },
159
- cancelDescription: 'apostrophe:discardImageChangesPrompt'
168
+ cancelDescription: 'apostrophe:discardImageChangesPrompt',
169
+ debouncedGetMedia: debounce(this.getMedia, DEBOUNCE_TIMEOUT),
170
+ loadObserver: new IntersectionObserver(
171
+ this.handleIntersect,
172
+ {
173
+ root: null,
174
+ rootMargin: '30px',
175
+ threshold: 0
176
+ }
177
+ )
160
178
  };
161
179
  },
162
180
  computed: {
@@ -197,9 +215,6 @@ export default {
197
215
  pluralLabel: this.moduleOptions.pluralLabel
198
216
  };
199
217
  },
200
- selected() {
201
- return this.items.filter(item => this.checked.includes(item._id));
202
- },
203
218
  accept() {
204
219
  return this.moduleOptions.schema.find(field => field.name === 'attachment').accept;
205
220
  },
@@ -223,20 +238,46 @@ export default {
223
238
  typeLabel: this.$t(this.moduleLabels.pluralLabel)
224
239
  };
225
240
  }
241
+ },
242
+ isLastPage() {
243
+ return this.totalPages > 1 && this.currentPage === this.totalPages;
226
244
  }
227
245
  },
228
246
  watch: {
229
247
  async checked (newVal, oldVal) {
248
+ this.lastSelected = newVal.at(-1);
230
249
  if (newVal.length > 1 || newVal.length === 0) {
231
- if (!await this.updateEditing(null)) {
250
+ if (
251
+ !this.checked.includes(this.editing?._id) &&
252
+ oldVal.includes(this.editing?._id) &&
253
+ !await this.updateEditing(null)
254
+ ) {
232
255
  this.checked = oldVal;
233
256
  }
257
+
258
+ if (this.modified === false) {
259
+ await this.updateEditing(null);
260
+ }
261
+
262
+ return;
263
+ }
264
+
265
+ await this.updateEditing(newVal.at(0));
266
+ },
267
+ isLastPage(newVal) {
268
+ if (newVal) {
269
+ this.disconnectObserver();
234
270
  }
235
271
  }
236
272
  },
273
+ created() {
274
+ this.setDefaultFilters();
275
+ },
237
276
  async mounted() {
238
277
  this.modal.active = true;
239
278
  await this.getMedia({ tags: true });
279
+ this.isFirstLoading = false;
280
+
240
281
  apos.bus.$on('content-changed', this.onContentChanged);
241
282
  apos.bus.$on('command-menu-manager-close', this.confirmAndCancel);
242
283
  },
@@ -245,12 +286,17 @@ export default {
245
286
  apos.bus.$off('command-menu-manager-close', this.confirmAndCancel);
246
287
  },
247
288
  methods: {
289
+ setDefaultFilters() {
290
+ this.moduleOptions.filters.forEach(filter => {
291
+ this.filterValues[filter.name] = filter.def;
292
+ });
293
+ },
248
294
  // Update our current idea of whether the doc in the right hand rail
249
295
  // has been modified (via event from the editor)
250
296
  editorModified (val) {
251
297
  this.modified = val;
252
298
  },
253
- async getMedia (options) {
299
+ async getMedia (options = {}) {
254
300
  const qs = {
255
301
  ...this.filterValues,
256
302
  page: this.currentPage,
@@ -279,13 +325,12 @@ export default {
279
325
  }
280
326
  const apiResponse = (await apos.http.get(
281
327
  this.moduleOptions.action, {
282
- busy: true,
283
328
  qs,
284
329
  draft: true
285
330
  }
286
331
  ));
287
332
 
288
- if (options && options.tags) {
333
+ if (options.tags) {
289
334
  if (filtered) {
290
335
  // We never filter the tag list because they are presented like folders,
291
336
  // and folders don't disappear when empty. So we need to make a
@@ -307,28 +352,33 @@ export default {
307
352
 
308
353
  this.currentPage = apiResponse.currentPage;
309
354
  this.totalPages = apiResponse.pages;
310
- this.items = apiResponse.results;
355
+ for (const image of apiResponse.results) {
356
+ this.items.push(image);
357
+ }
311
358
  },
312
- async updateMedia () {
359
+ async refetchMedia(opts) {
360
+ this.isLoading = true;
361
+ this.currentPage = 1;
362
+ this.items = [];
363
+ await this.getMedia(opts);
364
+ this.isLoading = false;
365
+ this.modified = false;
313
366
  this.updateEditing(null);
314
- await this.getMedia();
315
367
  },
316
368
  async filter(name, value) {
317
369
  this.filterValues[name] = value;
318
- this.currentPage = 1;
319
-
320
- this.updateEditing(null);
321
- await this.getMedia();
370
+ this.refetchMedia();
322
371
  },
323
372
  createPlaceholder(dimensions) {
324
373
  this.items.unshift({
325
- _id: cuid(),
374
+ _id: createId(),
326
375
  title: 'placeholder image',
327
376
  dimensions
328
377
  });
329
378
  },
330
379
  async completeUploading (imgIds) {
331
- this.uploading = false;
380
+ this.currentPage = 1;
381
+ this.items = [];
332
382
  await this.getMedia();
333
383
 
334
384
  if (Array.isArray(imgIds) && imgIds.length && this.items.length === 0) {
@@ -347,7 +397,8 @@ export default {
347
397
  return;
348
398
  }
349
399
  if (Array.isArray(imgIds) && imgIds.length) {
350
- this.concatCheckedDocs(imgIds);
400
+ const checked = this.checked.concat(imgIds);
401
+ this.checked = checked.slice(0, this.relationshipField?.max || checked.length);
351
402
 
352
403
  // If we're currently editing one, don't interrupt that by replacing it.
353
404
  if (!this.editing && imgIds.length === 1) {
@@ -357,7 +408,6 @@ export default {
357
408
  },
358
409
  clearSelected() {
359
410
  this.checked = [];
360
- this.editing = undefined;
361
411
  },
362
412
  async updateEditing(id) {
363
413
  const item = this.items.find(item => item._id === id);
@@ -385,85 +435,180 @@ export default {
385
435
  // select setters
386
436
  select(id) {
387
437
  if (this.checked.includes(id)) {
388
- this.setCheckedDocs([]);
438
+ this.updateEditing(id);
439
+ } else if (this.relationshipField && (this.relationshipField.max > 1 || !this.relationshipField.max)) {
440
+ this.selectAnother(id);
389
441
  } else {
390
- const item = this.items.find(item => item._id === id);
391
- if (item) {
392
- this.setCheckedDocs([ item ]);
393
- }
442
+ this.checked = [ id ];
394
443
  }
395
- this.updateEditing(id);
396
- this.lastSelected = id;
397
444
  },
398
445
  selectAnother(id) {
446
+ if (this.relationshipField?.max === 1) {
447
+ this.select(id);
448
+ return;
449
+ }
399
450
  if (this.checked.includes(id)) {
400
- this.removeCheckedDoc(id);
451
+ this.checked = this.checked.filter(checkedId => checkedId !== id);
401
452
  } else {
402
- this.addCheckedDoc(id);
453
+ this.checked = [ ...this.checked, id ];
403
454
  }
404
-
405
- this.lastSelected = id;
406
- this.editing = undefined;
407
455
  },
408
-
409
456
  selectSeries(id) {
410
- if (!this.lastSelected) {
457
+ if (!this.lastSelected || this.relationshipField?.max === 1) {
411
458
  this.select(id);
412
459
  return;
413
460
  }
414
461
 
415
- let beginIndex = this.items.findIndex(item => item._id === this.lastSelected);
416
- let endIndex = this.items.findIndex(item => item._id === id);
462
+ const beginIndex = this.items.findIndex(item => item._id === this.lastSelected);
463
+ const endIndex = this.items.findIndex(item => item._id === id);
417
464
  const direction = beginIndex > endIndex ? -1 : 1;
418
465
 
419
- if (direction < 0) {
420
- [ beginIndex, endIndex ] = [ endIndex, beginIndex ];
421
- } else {
422
- endIndex++;
423
- }
424
-
425
- const sliced = this.items.slice(beginIndex, endIndex);
426
- // always want to check, never toggle
427
- sliced.forEach(item => {
428
- if (!this.checked.includes(item._id)) {
429
- this.addCheckedDoc(item._id);
430
- }
431
- });
466
+ const start = direction < 0 ? endIndex : beginIndex;
467
+ const end = direction < 0 ? beginIndex : endIndex + 1;
468
+ const imgIds = this.items
469
+ .slice(start, end)
470
+ .map(item => item._id)
471
+ .filter(_id => !this.checked.includes(_id));
432
472
 
433
- this.lastSelected = sliced[sliced.length - 1]._id;
434
- this.editing = undefined;
473
+ const checked = this.checked.concat(imgIds);
474
+ this.checked = checked.slice(0, this.relationshipField?.max || checked.length);
435
475
  },
436
476
 
437
477
  // Toolbar handlers
438
- selectClick() {
439
- this.selectAll();
440
- this.editing = undefined;
441
- },
442
- async updatePage(num) {
443
- if (num) {
444
- this.currentPage = num;
445
- await this.getMedia();
478
+ async selectClick() {
479
+ if (await this.updateEditing(null)) {
480
+ this.selectAll();
446
481
  }
447
482
  },
448
483
  archiveClick() {
449
484
  this.$emit('archive', this.checked);
450
485
  },
451
486
 
452
- async search(query) {
453
- this.filter('autocomplete', query);
487
+ async search(value) {
488
+ this.filterValues.autocomplete = value;
489
+ this.currentPage = 1;
490
+ this.items = [];
491
+ this.isLoading = true;
492
+ await this.debouncedGetMedia();
493
+ this.isLoading = false;
454
494
  },
455
495
 
456
- async onContentChanged() {
457
- await this.getMedia({ tags: true });
496
+ async onContentChanged({ action, doc }) {
497
+ if (doc.type !== '@apostrophecms/image' || ![ 'archive', 'update' ].includes(action)) {
498
+ return;
499
+ }
500
+
501
+ this.modified = false;
502
+ if (action === 'archive') {
503
+ this.removeStateDoc(doc);
504
+ }
505
+ if (action === 'update') {
506
+ this.updateStateDoc(doc);
507
+ }
508
+
509
+ await this.updateEditing(null);
510
+ },
511
+
512
+ updateStateDoc(doc) {
513
+ const index = this.items.findIndex(item => item._id === doc._id);
514
+ const checkedIndex = this.checkedDocs
515
+ .findIndex(checkedDoc => checkedDoc._id === doc._id);
516
+ if (index !== -1) {
517
+ this.items[index] = doc;
518
+ }
519
+ if (checkedIndex !== -1) {
520
+ this.checkedDocs[checkedIndex] = doc;
521
+ }
522
+ },
523
+
524
+ removeStateDoc(doc) {
525
+ const index = this.items.findIndex(item => item._id === doc._id);
526
+ const checkedIndex = this.checked.findIndex(checkedId => checkedId === doc._id);
527
+ const checkedDocsIndex = this.checkedDocs.findIndex(({ _id }) => _id === doc._id);
528
+
529
+ if (index !== -1) {
530
+ this.items.splice(index, 1);
531
+ }
532
+ if (checkedIndex !== -1) {
533
+ this.checked.splice(checkedIndex, 1);
534
+ }
535
+ if (checkedDocsIndex !== -1) {
536
+ this.checkedDocs.splice(checkedDocsIndex, 1);
537
+ }
538
+ },
539
+
540
+ async handleIntersect(entries) {
541
+ for (const entry of entries) {
542
+ if (
543
+ entry.isIntersecting &&
544
+ this.currentPage < this.totalPages &&
545
+ !this.isFirstLoading &&
546
+ this.items.length
547
+ ) {
548
+ this.currentPage++;
549
+ this.isScrollLoading = true;
550
+ await this.$nextTick();
551
+ this.loadRef.scrollIntoView({
552
+ behavior: 'smooth'
553
+ });
554
+ await this.getMedia();
555
+ this.isScrollLoading = false;
556
+ }
557
+ }
558
+ },
559
+ observeLoadRef() {
560
+ if (this.totalPages < 2) {
561
+ return;
562
+ }
563
+
564
+ this.loadObserver.observe(this.loadRef);
565
+ },
566
+
567
+ disconnectObserver() {
568
+ if (this.loadObserver) {
569
+ this.loadObserver.disconnect();
570
+ }
571
+ },
572
+
573
+ setLoadRef(ref) {
574
+ this.loadRef = ref;
575
+ this.disconnectObserver();
576
+ if (ref) {
577
+ this.observeLoadRef();
578
+ }
458
579
  }
459
580
  }
460
581
  };
461
582
  </script>
462
583
 
463
584
  <style lang="scss" scoped>
464
- .apos-media-manager :deep(.apos-media-manager-toolbar) {
465
- z-index: $z-index-manager-toolbar;
466
- position: relative;
585
+ .apos-media-manager {
586
+ :deep(.apos-modal__body) {
587
+ padding: 0;
588
+ }
589
+
590
+ :deep(.apos-modal__body-inner) {
591
+ overflow: hidden;
592
+ height: 100%;
593
+ }
594
+
595
+ :deep(.apos-modal__body-header) {
596
+ padding: $spacing-double $spacing-double 20px;
597
+
598
+ @include media-up(lap) {
599
+ padding: $spacing-quadruple $spacing-quadruple 20px;
600
+ }
601
+ }
602
+
603
+ :deep(.apos-modal__body-main) {
604
+ overflow-y: auto;
605
+ box-sizing: border-box;
606
+ padding: 0 $spacing-double 20px;
607
+
608
+ @include media-up(lap) {
609
+ padding: 0 $spacing-quadruple 20px;
610
+ }
611
+ }
467
612
  }
468
613
 
469
614
  .apos-media-manager__empty {