apostrophe 3.50.0 → 3.51.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 (36) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/modules/@apostrophecms/admin-bar/index.js +33 -1
  3. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposAdminBar.vue +26 -2
  4. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposAdminBarMenu.vue +3 -2
  5. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposAdminBarUser.vue +8 -15
  6. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextBar.vue +14 -10
  7. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextTitle.vue +12 -2
  8. package/modules/@apostrophecms/area/ui/apos/components/AposAreaMenu.vue +0 -1
  9. package/modules/@apostrophecms/area/ui/apos/components/AposAreaWidget.vue +109 -20
  10. package/modules/@apostrophecms/area/ui/apos/components/AposWidgetControls.vue +85 -6
  11. package/modules/@apostrophecms/asset/lib/globalIcons.js +3 -0
  12. package/modules/@apostrophecms/doc-type/ui/apos/components/AposDocContextMenu.vue +7 -0
  13. package/modules/@apostrophecms/login/index.js +14 -0
  14. package/modules/@apostrophecms/modal/ui/apos/mixins/AposEditorMixin.js +11 -149
  15. package/modules/@apostrophecms/page/index.js +2 -1
  16. package/modules/@apostrophecms/rich-text-widget/index.js +8 -4
  17. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposRichTextWidgetEditor.vue +105 -9
  18. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapAnchor.vue +5 -0
  19. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapButton.vue +6 -1
  20. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapImage.vue +5 -0
  21. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapLink.vue +6 -0
  22. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposTiptapStyles.vue +27 -13
  23. package/modules/@apostrophecms/schema/index.js +4 -1
  24. package/modules/@apostrophecms/schema/ui/apos/components/AposInputArray.vue +33 -5
  25. package/modules/@apostrophecms/schema/ui/apos/components/AposInputObject.vue +18 -2
  26. package/modules/@apostrophecms/schema/ui/apos/components/AposSchema.vue +1 -0
  27. package/modules/@apostrophecms/schema/ui/apos/lib/conditionalFields.js +181 -0
  28. package/modules/@apostrophecms/schema/ui/apos/mixins/AposInputConditionalFieldsMixin.js +57 -0
  29. package/modules/@apostrophecms/ui/ui/apos/components/AposButton.vue +0 -11
  30. package/modules/@apostrophecms/ui/ui/apos/components/AposButtonGroup.vue +2 -1
  31. package/modules/@apostrophecms/ui/ui/apos/lib/tooltip-options.js +4 -2
  32. package/modules/@apostrophecms/ui/ui/apos/scss/global/_theme.scss +3 -0
  33. package/modules/@apostrophecms/ui/ui/apos/scss/global/_tooltips.scss +24 -9
  34. package/modules/@apostrophecms/ui/ui/apos/scss/mixins/_theme_mixins.scss +3 -1
  35. package/package.json +1 -1
  36. package/test/admin-bar.js +45 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.51.0 (2023-06-21)
4
+
5
+ ### Adds
6
+
7
+ * Items can now be added to the user's personal menu in the
8
+ admin bar, alongside the "Log Out" option. To do so, specify
9
+ the `user: true` option when calling `self.apos.adminBar.add`.
10
+ This should be reserved for items that manage personal settings.
11
+ * When duplicating another document, the `_id` properties of
12
+ array items, widgets and areas are still regenerated to ensure
13
+ uniqueness across documents. However, an `_originalId` property
14
+ is now available for reference while the document remains in memory.
15
+ This facilitates change detection within array items in
16
+ `beforeSave` handlers and the like.
17
+ * Adds the possibility to add custom admin bars via the `addBar()` method from the `admin-bar` module.
18
+ * Adds support for conditional fields within `array` and `object` field schema. See the [documentation](https://v3.docs.apostrophecms.org/guide/conditional-fields/) for more information.
19
+
20
+ ### Fixes
21
+
22
+ * Uses `findForEditing` method in the page put route.
23
+ * The "Duplicate" option in the page or piece manager now correctly duplicates the
24
+ entire document. This was a regression introduced in 3.48.0. The "Duplicate" option
25
+ in the editor dialog box always worked correctly.
26
+
27
+ ### Changes
28
+
29
+ * Browser URL now changes to reflect the slug of the document according to the mode that is being viewed.
30
+
3
31
  ## 3.50.0 (2023-06-09)
4
32
 
5
33
  ### Adds
@@ -15,6 +43,7 @@ be needed in normal circumstances.
15
43
  ## 3.49.0 (2023-06-08)
16
44
 
17
45
  ### Changes
46
+
18
47
  * Updates area UX to not display Add Content controls when a widget is focused.
19
48
  * Updates area UX to unfocus widget on esc key.
20
49
  * Updates widget UI to use dashed outlines instead of borders to indicate bounds.
@@ -27,6 +56,7 @@ we encourage you to consider replacing your `script` tag with the new version, w
27
56
  available in your project.
28
57
 
29
58
  ### Adds
59
+
30
60
  * Adds keyboard accessibility to Insert menu.
31
61
  * Adds regex pattern feature for string fields.
32
62
  * Adds `pnpm` support. Introduces new optional Apostrophe root configuration `pnpm` to force opt-in/out when auto detection fails. See the [documentation](https://v3.docs.apostrophecms.org/guide/using-pnpm.html) for more details.
@@ -45,6 +75,7 @@ order to guarantee it. This implicitly sets `singleton: true` as well. This is n
45
75
  internally by `@apostrophecms/global` as well as the optional `@apostrophecms-pro/palette` module.
46
76
 
47
77
  ### Fixes
78
+
48
79
  * Fix 404 error when viewing/editing a doc which draft has a different version of the slug than the published one.
49
80
  * Fixed a bug where multiple home pages can potentially be inserted into the database if the
50
81
  default locale is renamed. Introduced the `async apos.doc.bestAposDocId(criteria)` method to
@@ -91,6 +91,7 @@ module.exports = {
91
91
  self.items = [];
92
92
  self.groups = [];
93
93
  self.groupLabels = {};
94
+ self.bars = [];
94
95
  self.enableBrowserData();
95
96
  },
96
97
  handlers(self) {
@@ -142,6 +143,10 @@ module.exports = {
142
143
  // for screenreaders only. The contextUtility functionality is typically used for
143
144
  // experiences that temporarily change the current editing context.
144
145
  //
146
+ // If `options.user` is true, the menu bar item will appear
147
+ // on the user's personal dropdown, where "Log Out" appears. Such items
148
+ // cannot be grouped further.
149
+
145
150
  // If an `options.when` function is provided, it will be invoked with
146
151
  // `req` to test whether this admin bar item should be displayed or not.
147
152
 
@@ -349,8 +354,35 @@ module.exports = {
349
354
  contextId: context && context._id,
350
355
  tabId: cuid(),
351
356
  contextEditorName,
352
- pageTree: self.options.pageTree && self.apos.permission.can(req, 'edit', '@apostrophecms/any-page-type', 'draft')
357
+ pageTree: self.options.pageTree && self.apos.permission.can(req, 'edit', '@apostrophecms/any-page-type', 'draft'),
358
+ bars: self.bars
353
359
  };
360
+ },
361
+
362
+ // Add custom bars and place the ones
363
+ // that have `last: true` at the end
364
+ // of the list so that they will be
365
+ // displayed below the others.
366
+ //
367
+ // Example:
368
+ //
369
+ // ```js
370
+ // self.addBar({
371
+ // id: 'template',
372
+ // componentName: 'TheAposTemplateBar',
373
+ // props: { content: 'Some content' },
374
+ // last: true
375
+ // });
376
+ // ```
377
+ addBar(bar) {
378
+ self.bars.push(bar);
379
+
380
+ self.bars.sort((a, b) => {
381
+ if (a.last === true && b.last === true) {
382
+ return 0;
383
+ }
384
+ return b.last === true ? -1 : 1;
385
+ });
354
386
  }
355
387
  };
356
388
  }
@@ -8,11 +8,21 @@
8
8
  <nav class="apos-admin-bar" ref="adminBar">
9
9
  <div class="apos-admin-bar__row">
10
10
  <AposLogoPadless class="apos-admin-bar__logo" />
11
- <TheAposAdminBarMenu :items="items" />
11
+ <TheAposAdminBarMenu :items="menuItems" />
12
12
  <TheAposAdminBarLocale v-if="hasLocales()" />
13
- <TheAposAdminBarUser data-apos-test="authenticatedUserMenuTrigger" class="apos-admin-bar__user" />
13
+ <TheAposAdminBarUser
14
+ data-apos-test="authenticatedUserMenuTrigger"
15
+ class="apos-admin-bar__user"
16
+ :items="userItems"
17
+ />
14
18
  </div>
15
19
  <TheAposContextBar @mounted="setSpacer" />
20
+ <component
21
+ v-for="bar in bars"
22
+ v-bind="bar.props || {}"
23
+ :key="bar.id"
24
+ :is="bar.componentName"
25
+ />
16
26
  </nav>
17
27
  </div>
18
28
  </template>
@@ -31,6 +41,20 @@ export default {
31
41
  }
32
42
  }
33
43
  },
44
+ computed: {
45
+ menuItems() {
46
+ return this.items.filter(item => !item.options?.user);
47
+ },
48
+ userItems() {
49
+ return this.items.filter(item => item.options?.user);
50
+ },
51
+ moduleOptions() {
52
+ return window.apos.adminBar;
53
+ },
54
+ bars() {
55
+ return this.moduleOptions.bars;
56
+ }
57
+ },
34
58
  async mounted() {
35
59
  this.setSpacer();
36
60
  },
@@ -54,10 +54,11 @@
54
54
  <Component
55
55
  v-if="item.options.component"
56
56
  :is="item.options.component"
57
- :key="item.name"
57
+ :key="`${item.name}.component`"
58
58
  />
59
59
  <AposButton
60
- v-else :key="item.name"
60
+ v-else
61
+ :key="`${item.name}.fallback`"
61
62
  type="subtle" :modifiers="['small', 'no-motion']"
62
63
  :tooltip="trayItemTooltip(item)" class="apos-admin-bar__context-button"
63
64
  :icon="item.options.icon" :icon-only="true"
@@ -2,7 +2,7 @@
2
2
  <AposContextMenu
3
3
  class="apos-admin-user"
4
4
  :button="button"
5
- :menu="menu"
5
+ :menu="items"
6
6
  menu-placement="bottom-end"
7
7
  @item-clicked="emitEvent"
8
8
  >
@@ -19,16 +19,11 @@
19
19
 
20
20
  export default {
21
21
  name: 'TheAposAdminBarUser',
22
- data() {
23
- return {
24
- menu: [
25
- {
26
- label: 'apostrophe:logOut',
27
- name: 'logOut',
28
- action: 'user-logout'
29
- }
30
- ]
31
- };
22
+ props: {
23
+ items: {
24
+ type: Array,
25
+ required: true
26
+ }
32
27
  },
33
28
  computed: {
34
29
  button() {
@@ -47,10 +42,8 @@ export default {
47
42
  }
48
43
  },
49
44
  methods: {
50
- emitEvent(e) {
51
- if (e === 'user-logout') {
52
- apos.bus.$emit('admin-menu-click', '@apostrophecms/login-logout');
53
- }
45
+ emitEvent(name) {
46
+ apos.bus.$emit('admin-menu-click', name);
54
47
  }
55
48
  }
56
49
  };
@@ -525,6 +525,19 @@ export default {
525
525
  return;
526
526
  }
527
527
 
528
+ const { action } = window.apos.modules[this.context.type];
529
+ const doc = await apos.http.get(`${action}/${this.context.aposDocId}`, {
530
+ qs: {
531
+ aposMode: this.draftMode,
532
+ project: { _url: 1 }
533
+ }
534
+ });
535
+
536
+ if (this.urlDiffers(doc._url)) {
537
+ // Slug changed, change browser URL to reflect the actual url of the doc
538
+ history.replaceState(null, '', doc._url);
539
+ }
540
+
528
541
  const qs = {
529
542
  ...apos.http.parseQuery(window.location.search),
530
543
  aposRefresh: '1',
@@ -534,16 +547,7 @@ export default {
534
547
  } : {})
535
548
  };
536
549
 
537
- const { action } = window.apos.modules[this.context.type];
538
- const doc = await apos.http.get(`${action}/${this.context.aposDocId}`, {
539
- qs: {
540
- aposMode: this.draftMode,
541
- project: { _url: 1 }
542
- }
543
- });
544
-
545
- const url = apos.http.addQueryToUrl(doc._url, qs);
546
- const content = await apos.http.get(url, {
550
+ const content = await apos.http.get(doc._url, {
547
551
  qs,
548
552
  headers: {
549
553
  'Cache-Control': 'no-cache'
@@ -33,8 +33,9 @@
33
33
  />
34
34
  <AposLabel
35
35
  v-else
36
- label="apostrophe:draft" :modifiers="['apos-is-warning', 'apos-is-filled']"
37
- tooltip="apostrophe:notYetPublished"
36
+ :label="unpublishedLabel"
37
+ :tooltip="unpublishedTooltip"
38
+ :modifiers="['apos-is-warning', 'apos-is-filled']"
38
39
  />
39
40
  </span>
40
41
  </transition-group>
@@ -105,6 +106,15 @@ export default {
105
106
  },
106
107
  canTogglePublishDraftMode() {
107
108
  return !this.isUnpublished && !this.hasCustomUi;
109
+ },
110
+ moduleOptions() {
111
+ return window.apos.adminBar;
112
+ },
113
+ unpublishedLabel() {
114
+ return this.moduleOptions.unpublishedLabel || 'apostrophe:draft';
115
+ },
116
+ unpublishedTooltip() {
117
+ return this.moduleOptions.unpublishedTooltip || 'apostrophe:notYetPublished';
108
118
  }
109
119
  },
110
120
  mounted() {
@@ -61,7 +61,6 @@ export default {
61
61
  buttonOptions() {
62
62
  return {
63
63
  label: 'apostrophe:addContent',
64
- iconOnly: this.empty === false,
65
64
  icon: 'plus-icon',
66
65
  type: 'primary',
67
66
  modifiers: this.empty ? [] : [ 'round', 'tiny' ],
@@ -20,10 +20,14 @@
20
20
  :class="ui.labels"
21
21
  >
22
22
  <ol class="apos-area-widget__breadcrumbs">
23
+ <li class="apos-area-widget__breadcrumb apos-area-widget__breadcrumb--widget-icon">
24
+ <AposIndicator :icon="widgetIcon" :icon-size="13" />
25
+ </li>
23
26
  <li
24
- v-for="item in breadcrumbs.list"
27
+ v-for="(item, index) in breadcrumbs.list"
25
28
  :key="item.id"
26
29
  class="apos-area-widget__breadcrumb"
30
+ :data-apos-widget-breadcrumb="breadcrumbs.list.length - index"
27
31
  >
28
32
  <AposButton
29
33
  type="quiet"
@@ -34,7 +38,7 @@
34
38
  :modifiers="['icon-right', 'no-motion']"
35
39
  />
36
40
  </li>
37
- <li class="apos-area-widget__breadcrumb">
41
+ <li class="apos-area-widget__breadcrumb" data-apos-widget-breadcrumb="0">
38
42
  <AposButton
39
43
  type="quiet"
40
44
  @click="foreign ? $emit('edit', i) : false"
@@ -267,6 +271,9 @@ export default {
267
271
  menuPlacement: 'top'
268
272
  };
269
273
  },
274
+ widgetIcon() {
275
+ return this.contextMenuOptions.menu.filter(item => item.name === this.widget.type)[0]?.icon || 'shape-icon';
276
+ },
270
277
  widgetLabel() {
271
278
  const moduleName = `${this.widget.type}-widget`;
272
279
  const module = window.apos.modules[moduleName];
@@ -587,32 +594,92 @@ export default {
587
594
  }
588
595
  }
589
596
 
590
- // TODO commented code awaiting the triumphant return of the canvas -SR
591
-
592
597
  .apos-area-widget-controls--modify {
593
598
  right: 0;
594
- // transform: translate3d(calc(100% + 5px), 0, 0);
595
- // @media (max-width: ($a-canvas-max + 100px)) { // include extra space for tools
596
- // transform: translate3d(-10px, 30px, 0);
597
599
  transform: translate3d(-10px, 30px, 0);
598
- // }
600
+ ::v-deep .apos-button-group__inner {
601
+ border: 1px solid var(--a-primary-transparent-25);
602
+ box-shadow: var(--a-box-shadow);
603
+ }
604
+ ::v-deep .apos-button-group .apos-button {
605
+ width: 32px;
606
+ height: 32px;
607
+ padding: 0;
608
+ border: none;
609
+ border-radius: var(--a-border-radius);
610
+ background-color: transparent;
611
+ color: var(--a-base-1);
612
+ &:hover[disabled] {
613
+ background-color: transparent;
614
+ }
615
+ &:hover:not([disabled]), &:active:not([disabled]), &:focus:not([disabled]) {
616
+ background-color: var(--a-primary-transparent-10);
617
+ color: var(--a-primary);
618
+ }
619
+ &[disabled] {
620
+ color: var(--a-base-6);
621
+ }
622
+ }
599
623
  }
600
624
 
601
- // .apos-area-widget-inner .apos-area-widget-inner .apos-area-widget-controls--modify {
602
- // right: auto;
603
- // left: 0;
604
- // transform: translate3d(calc(-100% - 5px), 0, 0);
605
- // @media (max-width: ($a-canvas-max + 100px)) { // include extra space for tools
606
- // transform: translate3d(5px, 30px, 0);
607
- // }
608
- // }
609
-
610
625
  .apos-area-widget-controls--add {
611
626
  top: 0;
612
627
  left: 50%;
613
628
  transform: translate(-50%, -50%);
614
629
  }
615
630
 
631
+ .apos-area-widget-controls--add ::v-deep {
632
+
633
+ .apos-button__wrapper {
634
+ padding: 8px;
635
+
636
+ &:hover .apos-button:not([disabled]) {
637
+ transform: scale(1.15);
638
+ background-size: 150% 100%;
639
+ border-radius: 10px;
640
+ transition-duration: 0.5s;
641
+
642
+ /* stylelint-disable-next-line max-nesting-depth */
643
+ .apos-button__label {
644
+ max-width: 100px;
645
+ max-height: 100px;
646
+ transition-duration: 0.5s;
647
+ padding: 0 5px 0 0;
648
+ }
649
+
650
+ /* stylelint-disable-next-line max-nesting-depth */
651
+ .apos-button__icon {
652
+ margin-right: 5px;
653
+ }
654
+ }
655
+ }
656
+
657
+ .apos-button__icon {
658
+ margin-right: 0;
659
+ }
660
+
661
+ .apos-button__label {
662
+ display: inline-block;
663
+ overflow: hidden;
664
+ max-width: 0;
665
+ max-height: 0;
666
+ transition: max-width 0.2s var(--a-transition-timing-bounce);
667
+ white-space: nowrap;
668
+ font-size: var(--a-type-small);
669
+ }
670
+
671
+ .apos-button {
672
+ display: flex;
673
+ align-items: center;
674
+ justify-content: center;
675
+ background-image: linear-gradient( 45deg, var(--a-primary), var(--a-primary-dark-15), var(--a-primary-light-40), var(--a-primary) );
676
+ background-size: 200% 100%;
677
+ transition: all 0.2s var(--a-transition-timing-bounce);
678
+ padding: 5px;
679
+ border-radius: 12px;
680
+ }
681
+ }
682
+
616
683
  .apos-area-widget-controls--add--bottom {
617
684
  top: auto;
618
685
  bottom: 0;
@@ -627,7 +694,7 @@ export default {
627
694
 
628
695
  .apos-area-widget__label {
629
696
  position: absolute;
630
- top: 1px;
697
+ top: -8px;
631
698
  right: 0;
632
699
  display: flex;
633
700
  transform: translateY(-100%);
@@ -643,9 +710,10 @@ export default {
643
710
  display: flex;
644
711
  align-items: center;
645
712
  margin: 0;
646
- padding: 2px;
713
+ padding: 4px 6px;
647
714
  background-color: var(--a-background-primary);
648
- border: 1px solid var(--a-primary-dark-10);
715
+ border: 1px solid var(--a-primary-transparent-50);
716
+ border-radius: 8px;
649
717
  }
650
718
 
651
719
  .apos-area-widget-wrapper--foreign .apos-area-widget-inner .apos-area-widget__breadcrumbs {
@@ -660,13 +728,34 @@ export default {
660
728
  @include type-help;
661
729
  padding: 2px;
662
730
  white-space: nowrap;
731
+ color: var(--a-base-1);
732
+ transition: background-color 0.3s var(--a-transition-timing-bounce);
663
733
  &:hover {
664
734
  cursor: pointer;
665
735
  }
666
736
  }
667
737
 
738
+ .apos-area-widget__breadcrumbs:hover .apos-area-widget__breadcrumb,
739
+ .apos-area-widget__breadcrumbs:hover .apos-area-widget__breadcrumb ::v-deep .apos-button__content {
740
+ color: var(--a-text-primary);
741
+ }
742
+
743
+ .apos-area-widget__breadcrumb--widget-icon {
744
+ padding: 3px 2px 2px;
745
+ background-color: var(--a-primary-transparent-10);
746
+ color: var(--a-primary);
747
+ border-radius: 4px;
748
+ margin-right: 2px;
749
+ transition: background-color 0.3s var(--a-transition-timing-bounce);
750
+ }
751
+
752
+ .apos-area-widget__breadcrumbs:hover .apos-area-widget__breadcrumb--widget-icon {
753
+ background-color: var(--a-primary-transparent-25);
754
+ }
755
+
668
756
  .apos-area-widget__breadcrumb--icon {
669
757
  padding: 2px;
758
+ color: var(--a-text-primary);
670
759
  }
671
760
 
672
761
  .apos-area-widget__breadcrumb ::v-deep .apos-button {
@@ -8,20 +8,32 @@
8
8
  v-bind="upButton"
9
9
  :disabled="first || disabled"
10
10
  @click="$emit('up')"
11
- :tooltip="(!disabled && !first) ? 'apostrophe:nudgeUp' : null"
11
+ :tooltip="{
12
+ content: (!disabled && !first) ? 'apostrophe:nudgeUp' : null,
13
+ placement: 'left'
14
+ }"
15
+ :modifiers="[ 'inline' ]"
12
16
  />
13
17
  <AposButton
14
18
  v-bind="editButton"
15
19
  :disabled="disabled"
16
20
  v-if="!foreign && !options.contextual"
17
21
  @click="$emit('edit')"
18
- tooltip="apostrophe:editWidget"
22
+ :tooltip="{
23
+ content: 'apostrophe:editWidget',
24
+ placement: 'left'
25
+ }"
26
+ :modifiers="[ 'inline' ]"
19
27
  />
20
28
  <AposButton
21
29
  v-bind="cutButton"
22
30
  v-if="!foreign"
23
31
  @click="$emit('cut')"
24
- tooltip="apostrophe:cut"
32
+ :tooltip="{
33
+ content: 'apostrophe:cut',
34
+ placement: 'left'
35
+ }"
36
+ :modifiers="[ 'inline' ]"
25
37
  />
26
38
  <!-- <AposButton
27
39
  v-bind="copyButton"
@@ -34,21 +46,33 @@
34
46
  :disabled="disabled || maxReached"
35
47
  v-bind="cloneButton"
36
48
  @click="$emit('clone')"
37
- tooltip="apostrophe:duplicate"
49
+ :tooltip="{
50
+ content: 'apostrophe:duplicate',
51
+ placement: 'left'
52
+ }"
53
+ :modifiers="[ 'inline' ]"
38
54
  />
39
55
  <AposButton
40
56
  v-if="!foreign"
41
57
  :disabled="disabled"
42
58
  v-bind="removeButton"
43
59
  @click="$emit('remove')"
44
- tooltip="apostrophe:delete"
60
+ :tooltip="{
61
+ content: 'apostrophe:delete',
62
+ placement: 'left'
63
+ }"
64
+ :modifiers="[ 'inline' ]"
45
65
  />
46
66
  <AposButton
47
67
  v-if="!foreign"
48
68
  v-bind="downButton"
49
69
  :disabled="last || disabled"
50
70
  @click="$emit('down')"
51
- :tooltip="(!disabled && !last) ? 'apostrophe:nudgeDown' : null"
71
+ :tooltip="{
72
+ content: (!disabled && !last) ? 'apostrophe:nudgeDown' : null,
73
+ placement: 'left'
74
+ }"
75
+ :modifiers="[ 'inline' ]"
52
76
  />
53
77
  </AposButtonGroup>
54
78
  </div>
@@ -161,3 +185,58 @@ export default {
161
185
  }
162
186
  };
163
187
  </script>
188
+
189
+ <style lang="scss" scoped>
190
+ $z-index-button-background: 1;
191
+ $z-index-button-foreground: 2;
192
+
193
+ .apos-area-modify-controls ::v-deep {
194
+ .apos-button__content {
195
+ z-index: $z-index-button-foreground;
196
+ position: relative;
197
+ }
198
+ .apos-button__icon {
199
+ transition: all 0.3s var(--a-transition-timing-bounce);
200
+ }
201
+ .apos-button {
202
+ background-color: transparent;
203
+
204
+ &:not([disabled]):hover:after {
205
+ background-color: var(--a-base-9);
206
+ }
207
+ &:active {
208
+ background-color: transparent;
209
+ }
210
+ &:active .apos-button__icon {
211
+ transform: scale(0.8);
212
+ }
213
+ &:active:after, &:focus:after {
214
+ background-color: var(--a-primary-transparent-25);
215
+ }
216
+ &:after,
217
+ &:not([disabled]):hover:after,
218
+ &:not([disabled]):active:after,
219
+ &:not([disabled]):focus:after {
220
+ opacity: 1;
221
+ transform: scale(1.15) translateY(0);
222
+ }
223
+ &:after {
224
+ content: '';
225
+ z-index: $z-index-button-background;
226
+ position: absolute;
227
+ top: 0;
228
+ left: 0;
229
+ display: block;
230
+ width: 100%;
231
+ height: 100%;
232
+ background-color: transparent;
233
+ transition:
234
+ opacity 0.5s var(--a-transition-timing-bounce),
235
+ transform 0.5s var(--a-transition-timing-bounce),
236
+ background-color 0.5s ease;
237
+ opacity: 0;
238
+ transform: scale(0.3) translateY(-4px);
239
+ }
240
+ }
241
+ }
242
+ </style>
@@ -52,6 +52,7 @@ module.exports = {
52
52
  'format-align-left-icon': 'FormatAlignLeft',
53
53
  'format-align-right-icon': 'FormatAlignRight',
54
54
  'format-bold-icon': 'FormatBold',
55
+ 'format-font-icon': 'FormatFont',
55
56
  'format-italic-icon': 'FormatItalic',
56
57
  'format-list-bulleted-icon': 'FormatListBulleted',
57
58
  'format-list-numbered-icon': 'FormatListNumbered',
@@ -59,6 +60,7 @@ module.exports = {
59
60
  'format-strikethrough-variant-icon': 'FormatStrikethroughVariant',
60
61
  'format-superscript-icon': 'FormatSuperscript',
61
62
  'format-subscript-icon': 'FormatSubscript',
63
+ 'format-text-icon': 'FormatText',
62
64
  'format-underline-icon': 'FormatUnderline',
63
65
  'help-circle-icon': 'HelpCircle',
64
66
  'image-edit-outline': 'ImageEditOutline',
@@ -101,6 +103,7 @@ module.exports = {
101
103
  'plus-icon': 'Plus',
102
104
  'redo-icon': 'RedoVariant',
103
105
  'refresh-icon': 'Refresh',
106
+ 'shape-icon': 'Shape',
104
107
  'sign-text-icon': 'SignText',
105
108
  'tag-icon': 'Tag',
106
109
  'text-box-icon': 'TextBox',
@@ -390,6 +390,13 @@ export default {
390
390
  this.$emit('close', doc);
391
391
  }
392
392
  }
393
+ // Because the page or piece manager might give us just a projected,
394
+ // minimum number of properties otherwise
395
+ const complete = await apos.http.get(`${this.moduleOptions.action}/${doc._id}`, {
396
+ busy: true
397
+ });
398
+ Object.assign(doc, complete);
399
+
393
400
  apos.bus.$emit('admin-menu-click', {
394
401
  itemName: `${this.moduleName}:editor`,
395
402
  props: {
@@ -74,6 +74,7 @@ module.exports = {
74
74
  }
75
75
  self.enableBrowserData();
76
76
  await self.enableBearerTokens();
77
+ self.addToAdminBar();
77
78
  },
78
79
  handlers(self) {
79
80
  return {
@@ -850,7 +851,20 @@ module.exports = {
850
851
  namespace,
851
852
  key: username
852
853
  });
854
+ },
855
+
856
+ addToAdminBar() {
857
+ self.apos.adminBar.add(
858
+ `${self.__meta.name}-logout`,
859
+ 'apostrophe:logOut',
860
+ false,
861
+ {
862
+ user: true,
863
+ last: true
864
+ }
865
+ );
853
866
  }
867
+
854
868
  };
855
869
  },
856
870