apostrophe 3.41.1 → 3.42.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 (43) hide show
  1. package/CHANGELOG.md +45 -1
  2. package/modules/@apostrophecms/admin-bar/index.js +1 -0
  3. package/modules/@apostrophecms/admin-bar/ui/apos/components/TheAposContextBar.vue +1 -1
  4. package/modules/@apostrophecms/asset/lib/globalIcons.js +3 -0
  5. package/modules/@apostrophecms/doc/ui/apos/apps/AposDoc.js +42 -0
  6. package/modules/@apostrophecms/doc-type/index.js +82 -51
  7. package/modules/@apostrophecms/doc-type/ui/apos/components/AposDocEditor.vue +10 -3
  8. package/modules/@apostrophecms/file/index.js +2 -1
  9. package/modules/@apostrophecms/file-tag/index.js +2 -1
  10. package/modules/@apostrophecms/i18n/i18n/en.json +115 -109
  11. package/modules/@apostrophecms/i18n/i18n/es.json +83 -78
  12. package/modules/@apostrophecms/i18n/i18n/fr.json +89 -84
  13. package/modules/@apostrophecms/i18n/i18n/pt-BR.json +81 -76
  14. package/modules/@apostrophecms/i18n/i18n/sk.json +91 -86
  15. package/modules/@apostrophecms/image/index.js +5 -1
  16. package/modules/@apostrophecms/image/ui/apos/components/AposMediaManager.vue +6 -1
  17. package/modules/@apostrophecms/image-tag/index.js +2 -1
  18. package/modules/@apostrophecms/modal/ui/apos/mixins/AposDocsManagerMixin.js +35 -2
  19. package/modules/@apostrophecms/modal/ui/apos/mixins/AposEditorMixin.js +2 -2
  20. package/modules/@apostrophecms/page/index.js +8 -4
  21. package/modules/@apostrophecms/piece-type/index.js +24 -3
  22. package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManager.vue +3 -63
  23. package/modules/@apostrophecms/piece-type/ui/apos/components/AposDocsManagerDisplay.vue +9 -2
  24. package/modules/@apostrophecms/piece-type/ui/apos/components/AposUtilityOperations.vue +126 -0
  25. package/modules/@apostrophecms/rich-text-widget/ui/apos/components/AposRichTextWidgetEditor.vue +10 -10
  26. package/modules/@apostrophecms/rich-text-widget/ui/apos/tiptap-extensions/Default.js +44 -48
  27. package/modules/@apostrophecms/schema/index.js +105 -35
  28. package/modules/@apostrophecms/schema/lib/addFieldTypes.js +21 -2
  29. package/modules/@apostrophecms/schema/ui/apos/components/AposInputArray.vue +339 -112
  30. package/modules/@apostrophecms/schema/ui/apos/components/AposInputRelationship.vue +72 -20
  31. package/modules/@apostrophecms/schema/ui/apos/components/AposInputSelect.vue +6 -0
  32. package/modules/@apostrophecms/schema/ui/apos/components/AposInputString.vue +1 -1
  33. package/modules/@apostrophecms/schema/ui/apos/components/AposInputWrapper.vue +7 -1
  34. package/modules/@apostrophecms/schema/ui/apos/components/AposSchema.vue +18 -4
  35. package/modules/@apostrophecms/schema/ui/apos/components/AposSearchList.vue +111 -30
  36. package/modules/@apostrophecms/submitted-draft/index.js +1 -1
  37. package/modules/@apostrophecms/ui/ui/apos/components/AposSlatList.vue +5 -1
  38. package/modules/@apostrophecms/ui/ui/apos/lib/i18next.js +1 -0
  39. package/modules/@apostrophecms/user/index.js +2 -1
  40. package/modules/@apostrophecms/widget-type/index.js +6 -3
  41. package/package.json +15 -15
  42. package/test/pieces.js +726 -13
  43. package/test/schemas.js +392 -22
@@ -10,6 +10,7 @@
10
10
  <AposSelect
11
11
  :icon="icon"
12
12
  :choices="choices"
13
+ :classes="classes"
13
14
  :disabled="field.readOnly"
14
15
  :selected="value.data"
15
16
  @change="change"
@@ -37,6 +38,11 @@ export default {
37
38
  choices: []
38
39
  };
39
40
  },
41
+ computed: {
42
+ classes () {
43
+ return [ this.value.duplicate && 'apos-input--error' ];
44
+ }
45
+ },
40
46
  async mounted() {
41
47
  // Add an null option if there isn't one already
42
48
  if (!this.field.required && !this.choices.find(choice => {
@@ -66,7 +66,7 @@ export default {
66
66
  }
67
67
  },
68
68
  classes () {
69
- return [ 'apos-input', `apos-input--${this.type}` ];
69
+ return [ 'apos-input', `apos-input--${this.type}`, this.value.duplicate && 'apos-input--error' ];
70
70
  },
71
71
  icon () {
72
72
  if (this.error) {
@@ -1,7 +1,10 @@
1
1
  <template>
2
2
  <div
3
3
  class="apos-field__wrapper"
4
- :class="`apos-field__wrapper--${field.type}`"
4
+ :class="{
5
+ [`apos-field__wrapper--${field.type}`]: true,
6
+ 'apos-field__wrapper--full-width': field.type === 'array' && field.style === 'table'
7
+ }"
5
8
  >
6
9
  <component :is="wrapEl" :class="classList">
7
10
  <div class="apos-field__info">
@@ -178,6 +181,9 @@ export default {
178
181
  .apos-field__wrapper {
179
182
  position: relative;
180
183
  }
184
+ .apos-field__wrapper.apos-field__wrapper--full-width {
185
+ max-width: 100%;
186
+ }
181
187
 
182
188
  .apos-field {
183
189
  border-width: 0;
@@ -23,10 +23,15 @@
23
23
  an external reason.
24
24
  -->
25
25
  <template>
26
- <div class="apos-schema">
27
- <div
26
+ <component
27
+ class="apos-schema"
28
+ :is="fieldStyle === 'table' ? 'tr' : 'div'"
29
+ >
30
+ <slot name="before" />
31
+ <component
28
32
  v-for="field in schema" :key="field.name"
29
33
  :data-apos-field="field.name"
34
+ :is="fieldStyle === 'table' ? 'td' : 'div'"
30
35
  >
31
36
  <component
32
37
  v-show="displayComponent(field.name)"
@@ -43,8 +48,9 @@
43
48
  :ref="field.name"
44
49
  :generation="generation"
45
50
  />
46
- </div>
47
- </div>
51
+ </component>
52
+ <slot name="after" />
53
+ </component>
48
54
  </template>
49
55
 
50
56
  <script>
@@ -68,6 +74,11 @@ export default {
68
74
  type: Array,
69
75
  required: true
70
76
  },
77
+ fieldStyle: {
78
+ type: String,
79
+ required: false,
80
+ default: ''
81
+ },
71
82
  currentFields: {
72
83
  type: Array,
73
84
  default() {
@@ -318,6 +329,9 @@ export default {
318
329
  .apos-schema ::v-deep .apos-field__wrapper {
319
330
  max-width: $input-max-width;
320
331
  }
332
+ .apos-schema ::v-deep .apos-field__wrapper.apos-field__wrapper--full-width {
333
+ max-width: inherit;
334
+ }
321
335
 
322
336
  .apos-schema ::v-deep .apos-field__wrapper--area {
323
337
  max-width: 100%;
@@ -1,19 +1,35 @@
1
1
  <template>
2
- <ul class="apos-search">
2
+ <ul class="apos-primary-scrollbar apos-search">
3
3
  <li
4
4
  v-for="item in list"
5
5
  :key="item._id"
6
6
  :class="getClasses(item)"
7
- v-apos-tooltip="item.disabled ? disabledTooltip : null"
7
+ v-apos-tooltip="getTooltip(item)"
8
8
  @click="select(item, $event)"
9
9
  >
10
- <div class="apos-search__item__main">
11
- <div class="apos-search__item__title">
12
- {{ item.title }}
13
- </div>
14
- <div class="apos-search__item__slug">
15
- {{ item.slug }}
16
- </div>
10
+ <AposIndicator
11
+ v-if="getIcon(item).icon"
12
+ :icon="getIcon(item).icon"
13
+ :icon-size="getIcon(item).iconSize"
14
+ class="apos-button__icon"
15
+ fill-color="currentColor"
16
+ />
17
+ <div class="apos-search__item__title">
18
+ {{ item.title }}
19
+ </div>
20
+ <div
21
+ v-for="field in fields"
22
+ :key="field"
23
+ class="apos-search__item__field"
24
+ >
25
+ {{ item[field] }}
26
+ </div>
27
+ <div
28
+ v-for="field in item.customFields"
29
+ :key="field"
30
+ class="apos-search__item__field"
31
+ >
32
+ {{ item[field] }}
17
33
  </div>
18
34
  </li>
19
35
  </ul>
@@ -30,6 +46,12 @@ export default {
30
46
  return [];
31
47
  }
32
48
  },
49
+ customFields: {
50
+ type: Array,
51
+ default() {
52
+ return [];
53
+ }
54
+ },
33
55
  selectedItems: {
34
56
  type: Array,
35
57
  default() {
@@ -39,6 +61,28 @@ export default {
39
61
  disabledTooltip: {
40
62
  type: String,
41
63
  default: null
64
+ },
65
+ label: {
66
+ type: String,
67
+ default: ''
68
+ },
69
+ help: {
70
+ type: [ String, Object ],
71
+ default: ''
72
+ },
73
+ icon: {
74
+ type: String,
75
+ default: 'text-box-icon'
76
+ },
77
+ iconSize: {
78
+ type: Number,
79
+ default: 20
80
+ },
81
+ fields: {
82
+ type: Array,
83
+ default() {
84
+ return [ 'slug' ];
85
+ }
42
86
  }
43
87
  },
44
88
  emits: [ 'select' ],
@@ -61,7 +105,20 @@ export default {
61
105
  if (item.disabled) {
62
106
  classes['apos-search__item--disabled'] = true;
63
107
  }
108
+ item.classes && Array.isArray(item.classes) && item.classes.forEach(suffix => {
109
+ classes[`apos-search__item--${suffix}`] = true;
110
+ });
111
+
64
112
  return classes;
113
+ },
114
+ getTooltip(item) {
115
+ return item.disabled && item.tooltip !== false ? this.disabledTooltip : null;
116
+ },
117
+ getIcon(item) {
118
+ return {
119
+ icon: item.icon ?? this.icon,
120
+ iconSize: item.iconSize || this.iconSize
121
+ };
65
122
  }
66
123
  }
67
124
  };
@@ -71,13 +128,13 @@ export default {
71
128
  .apos-search {
72
129
  z-index: $z-index-default;
73
130
  position: absolute;
74
- top: 37px;
75
131
  overflow: auto;
76
132
  width: 100%;
77
133
  list-style: none;
78
134
  box-shadow: var(--a-box-shadow);
79
135
  box-sizing: border-box;
80
136
  max-height: 300px;
137
+ margin: 0;
81
138
  padding: 0;
82
139
  border-bottom-left-radius: var(--a-border-radius);
83
140
  border-bottom-right-radius: var(--a-border-radius);
@@ -97,17 +154,42 @@ export default {
97
154
  .apos-search__item__title {
98
155
  color: $input-color-disabled;
99
156
  }
100
- .apos-search__item__slug {
157
+ .apos-search__item__field {
101
158
  color: $input-color-disabled;
102
159
  }
103
160
  }
104
161
 
162
+ @mixin suggestion {
163
+ padding-top: 14px;
164
+ background-color: var(--a-background-inverted);
165
+ .apos-search__item__title {
166
+ color: var(--a-text-inverted);
167
+ }
168
+ .apos-search__item__field {
169
+ color: var(--a-base-8);
170
+ }
171
+ }
172
+
173
+ @mixin hint {
174
+ flex-direction: column;
175
+ gap: 4px;
176
+ border-top: 1px solid var(--a-base-5);
177
+ .apos-search__item__title {
178
+ color: var(--a-base-2);
179
+ }
180
+ .apos-search__item__field {
181
+ color: var(--a-text-primary);
182
+ }
183
+ }
184
+
105
185
  .apos-search__item {
106
186
  display: flex;
107
- justify-content: space-between;
108
- margin: 10px;
187
+ justify-content: flex-start;
188
+ align-items: center;
189
+ gap: 10px;
190
+ margin: 0;
109
191
  padding: 10px 20px;
110
- border-radius: var(--a-border-radius);
192
+ border-top: 1px solid var(--a-base-5);
111
193
  box-sizing: border-box;
112
194
  transition: background-color 0.3s ease;
113
195
  & * {
@@ -115,34 +197,25 @@ export default {
115
197
  }
116
198
 
117
199
  &:hover.apos-search__item {
118
- padding: 9px 19px;
119
- border: 1px solid var(--a-base-5);
120
200
  background-color: var(--a-base-10);
121
201
  cursor: pointer;
122
202
  &.apos-search__item--disabled {
123
203
  @include disabled;
124
204
  }
125
- }
126
-
127
- &:hover.apos-search__item {
128
- padding: 9px 19px;
129
- border: 1px solid var(--a-base-5);
130
- background-color: var(--a-base-10);
131
- cursor: pointer;
132
- }
133
-
134
- &__main {
135
- display: flex;
136
- flex-direction: column;
205
+ &.apos-search__item--suggestion {
206
+ @include suggestion;
207
+ }
208
+ &.apos-search__item--hint {
209
+ @include hint;
210
+ }
137
211
  }
138
212
 
139
213
  &__title {
140
214
  @include type-base;
141
215
  color: var(--a-text-primary);
142
- margin-bottom: 3px;
143
216
  }
144
217
 
145
- &__slug {
218
+ &__field {
146
219
  @include type-base;
147
220
  color: var(--a-base-2);
148
221
  }
@@ -150,5 +223,13 @@ export default {
150
223
  &.apos-search__item--disabled {
151
224
  @include disabled;
152
225
  }
226
+
227
+ &.apos-search__item--suggestion {
228
+ @include suggestion;
229
+ }
230
+
231
+ &.apos-search__item--hint {
232
+ @include hint;
233
+ }
153
234
  }
154
235
  </style>
@@ -9,7 +9,7 @@ module.exports = {
9
9
  quickCreate: false,
10
10
  label: 'apostrophe:submittedDraft',
11
11
  pluralLabel: 'Submitted Drafts',
12
- canCreate: false,
12
+ showCreate: false,
13
13
  showDismissSubmission: true,
14
14
  showArchive: false,
15
15
  showDiscardDraft: false,
@@ -25,7 +25,7 @@
25
25
  :key="item._id"
26
26
  :item="item"
27
27
  :selected="selected === item._id"
28
- :class="{'apos-slat-list__item--disabled' : disabled}"
28
+ :class="{'apos-slat-list__item--disabled' : disabled, 'apos-input--error': duplicate}"
29
29
  :disabled="disabled"
30
30
  :engaged="engaged === item._id"
31
31
  :parent="listId"
@@ -77,6 +77,10 @@ export default {
77
77
  editorIcon: {
78
78
  type: String,
79
79
  default: null
80
+ },
81
+ duplicate: {
82
+ type: String,
83
+ default: null
80
84
  }
81
85
  },
82
86
  emits: [ 'update', 'item-clicked', 'select', 'input' ],
@@ -24,6 +24,7 @@ export default {
24
24
  interpolation: {
25
25
  escapeValue: false
26
26
  },
27
+ skipOnVariables: false,
27
28
  appendNamespaceToMissingKey: true,
28
29
  defaultNS: [ apos.i18n.defaultNamespace ],
29
30
  parseMissingKeyHandler (key) {
@@ -46,7 +46,8 @@ module.exports = {
46
46
  editRole: 'admin',
47
47
  publishRole: 'admin',
48
48
  viewRole: 'admin',
49
- showPermissions: true
49
+ showPermissions: true,
50
+ relationshipSuggestionIcon: 'account-box-icon'
50
51
  },
51
52
  fields(self) {
52
53
  return {
@@ -323,12 +323,15 @@ module.exports = {
323
323
  },
324
324
 
325
325
  // Return a new schema containing only fields for which the
326
- // current user has the permission specified by the `permission`
327
- // property of the schema field, or there is no `permission` property for the field.
326
+ // current user has the permission specified by the `editPermission`
327
+ // property of the schema field, or there is no `editPermission`|`viewPermission` property for the field.
328
328
 
329
329
  allowedSchema(req) {
330
330
  return _.filter(self.schema, function (field) {
331
- return !field.permission || self.apos.permission.can(req, field.permission.action, field.permission.type);
331
+ return (!field.editPermission && !field.viewPermission) ||
332
+ (field.editPermission && self.apos.permission.can(req, field.editPermission.action, field.editPermission.type)) ||
333
+ (field.viewPermission && self.apos.permission.can(req, field.viewPermission.action, field.viewPermission.type)) ||
334
+ false;
332
335
  });
333
336
  },
334
337
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apostrophe",
3
- "version": "3.41.1",
3
+ "version": "3.42.0",
4
4
  "description": "The Apostrophe Content Management System.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -33,20 +33,20 @@
33
33
  "@apostrophecms/vue-color": "^2.8.2",
34
34
  "@opentelemetry/api": "^1.0.4",
35
35
  "@opentelemetry/semantic-conventions": "^1.0.1",
36
- "@tiptap/extension-highlight": "^2.0.0-beta.33",
37
- "@tiptap/extension-link": "^2.0.0-beta.38",
38
- "@tiptap/extension-placeholder": "^2.0.0-beta.196",
39
- "@tiptap/extension-subscript": "^2.0.0-beta.209",
40
- "@tiptap/extension-superscript": "^2.0.0-beta.209",
41
- "@tiptap/extension-table": "^2.0.0-beta.209",
42
- "@tiptap/extension-table-cell": "^2.0.0-beta.209",
43
- "@tiptap/extension-table-header": "^2.0.0-beta.209",
44
- "@tiptap/extension-table-row": "^2.0.0-beta.209",
45
- "@tiptap/extension-text-align": "^2.0.0-beta.29",
46
- "@tiptap/extension-text-style": "^2.0.0-beta.23",
47
- "@tiptap/extension-underline": "^2.0.0-beta.23",
48
- "@tiptap/starter-kit": "^2.0.0-beta.185",
49
- "@tiptap/vue-2": "^2.0.0-beta.79",
36
+ "@tiptap/extension-highlight": "^2.0.0-beta.220",
37
+ "@tiptap/extension-link": "^2.0.0-beta.220",
38
+ "@tiptap/extension-placeholder": "^2.0.0-beta.220",
39
+ "@tiptap/extension-subscript": "^2.0.0-beta.220",
40
+ "@tiptap/extension-superscript": "^2.0.0-beta.220",
41
+ "@tiptap/extension-table": "^2.0.0-beta.220",
42
+ "@tiptap/extension-table-cell": "^2.0.0-beta.220",
43
+ "@tiptap/extension-table-header": "^2.0.0-beta.220",
44
+ "@tiptap/extension-table-row": "^2.0.0-beta.220",
45
+ "@tiptap/extension-text-align": "^2.0.0-beta.220",
46
+ "@tiptap/extension-text-style": "^2.0.0-beta.220",
47
+ "@tiptap/extension-underline": "^2.0.0-beta.220",
48
+ "@tiptap/starter-kit": "^2.0.0-beta.220",
49
+ "@tiptap/vue-2": "^2.0.0-beta.220",
50
50
  "autoprefixer": "^10.4.1",
51
51
  "bluebird": "^3.7.2",
52
52
  "body-parser": "^1.18.2",