@jumoo/usync 17.5.2 → 17.5.3-prerelease.17
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.
- package/dist/api/client.gen.js +1 -2
- package/dist/api/index.d.ts +1 -1
- package/dist/api/sdk.gen.d.ts +2 -1
- package/dist/api/sdk.gen.js +7 -0
- package/dist/api/types.gen.d.ts +37 -0
- package/dist/components/usync-content-preview.d.ts +27 -0
- package/dist/components/usync-content-preview.js +532 -0
- package/dist/components/usync-content-type-preview.d.ts +25 -0
- package/dist/components/usync-content-type-preview.js +530 -0
- package/dist/components/usync-data-type-preview.d.ts +21 -0
- package/dist/components/usync-data-type-preview.js +295 -0
- package/dist/components/usync-results-view.js +13 -5
- package/dist/dialogs/details-modal-element.d.ts +15 -0
- package/dist/dialogs/details-modal-element.js +217 -9
- package/dist/dialogs/details-modal-token.d.ts +10 -1
- package/dist/exports.d.ts +1 -0
- package/dist/exports.js +1 -0
- package/dist/index.js +9 -1
- package/dist/lang/files/da-dk.d.ts +37 -0
- package/dist/lang/files/da-dk.js +37 -0
- package/dist/lang/files/de-de.d.ts +37 -0
- package/dist/lang/files/de-de.js +37 -0
- package/dist/lang/files/en-us.d.ts +50 -0
- package/dist/lang/files/en-us.js +50 -0
- package/dist/lang/files/es-es.d.ts +37 -0
- package/dist/lang/files/es-es.js +37 -0
- package/dist/lang/files/fr-fr.d.ts +37 -0
- package/dist/lang/files/fr-fr.js +37 -0
- package/dist/lang/files/nl-nl.d.ts +37 -0
- package/dist/lang/files/nl-nl.js +37 -0
- package/dist/manifests.js +2 -0
- package/dist/preview/index.d.ts +1 -0
- package/dist/preview/index.js +1 -0
- package/dist/preview/manifest.d.ts +2 -0
- package/dist/preview/manifest.js +22 -0
- package/dist/preview/types.d.ts +72 -0
- package/dist/preview/types.js +2 -0
- package/dist/repository/SyncAction.respositoy.d.ts +8 -0
- package/dist/repository/SyncAction.respositoy.js +6 -0
- package/dist/repository/sources/SyncAction.source.d.ts +5 -0
- package/dist/repository/sources/SyncAction.source.js +5 -0
- package/dist/utils/preview/content-type-diff.d.ts +18 -0
- package/dist/utils/preview/content-type-diff.js +72 -0
- package/dist/utils/preview/content-type-layout.d.ts +39 -0
- package/dist/utils/preview/content-type-layout.js +100 -0
- package/package.json +2 -2
- package/dist/hey-api.d.ts +0 -11
- package/dist/hey-api.js +0 -14
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _uSyncDataTypePreviewElement_instances, _uSyncDataTypePreviewElement_renderSide, _uSyncDataTypePreviewElement_renderMissing, _uSyncDataTypePreviewElement_renderInfo, _uSyncDataTypePreviewElement_renderEditor, _uSyncDataTypePreviewElement_renderConfig;
|
|
13
|
+
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
|
14
|
+
import { classMap, css, customElement, html, nothing, property, } from '@umbraco-cms/backoffice/external/lit';
|
|
15
|
+
import '@umbraco-cms/backoffice/components';
|
|
16
|
+
import { getPreviewModel } from '../preview/types.js';
|
|
17
|
+
import { deepEqual, prettyJson } from '../utils/diff/index.js';
|
|
18
|
+
/**
|
|
19
|
+
* Shows the current and incoming versions of a data type side by side,
|
|
20
|
+
* rendered with the real property editor, so you can see what an import
|
|
21
|
+
* will do before running it.
|
|
22
|
+
*/
|
|
23
|
+
let uSyncDataTypePreviewElement = class uSyncDataTypePreviewElement extends UmbLitElement {
|
|
24
|
+
constructor() {
|
|
25
|
+
super(...arguments);
|
|
26
|
+
_uSyncDataTypePreviewElement_instances.add(this);
|
|
27
|
+
}
|
|
28
|
+
render() {
|
|
29
|
+
if (!this.preview)
|
|
30
|
+
return nothing;
|
|
31
|
+
const model = getPreviewModel(this.preview);
|
|
32
|
+
const current = model?.current ?? undefined;
|
|
33
|
+
const incoming = model?.incoming ?? undefined;
|
|
34
|
+
return html `
|
|
35
|
+
<div class="sides">
|
|
36
|
+
${__classPrivateFieldGet(this, _uSyncDataTypePreviewElement_instances, "m", _uSyncDataTypePreviewElement_renderSide).call(this, 'current', current, incoming)}
|
|
37
|
+
${__classPrivateFieldGet(this, _uSyncDataTypePreviewElement_instances, "m", _uSyncDataTypePreviewElement_renderSide).call(this, 'incoming', incoming, current)}
|
|
38
|
+
</div>
|
|
39
|
+
`;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
_uSyncDataTypePreviewElement_instances = new WeakSet();
|
|
43
|
+
_uSyncDataTypePreviewElement_renderSide = function _uSyncDataTypePreviewElement_renderSide(side, dataType, other) {
|
|
44
|
+
const headline = side === 'current'
|
|
45
|
+
? this.localize.termOrDefault('uSync_previewCurrent', 'Current (this site)')
|
|
46
|
+
: this.localize.termOrDefault('uSync_previewIncoming', 'Incoming (uSync files)');
|
|
47
|
+
return html `
|
|
48
|
+
<div class="side">
|
|
49
|
+
<h4 class="side-headline">${headline}</h4>
|
|
50
|
+
${dataType
|
|
51
|
+
? html `
|
|
52
|
+
${__classPrivateFieldGet(this, _uSyncDataTypePreviewElement_instances, "m", _uSyncDataTypePreviewElement_renderInfo).call(this, dataType, other)} ${__classPrivateFieldGet(this, _uSyncDataTypePreviewElement_instances, "m", _uSyncDataTypePreviewElement_renderEditor).call(this, dataType)}
|
|
53
|
+
${__classPrivateFieldGet(this, _uSyncDataTypePreviewElement_instances, "m", _uSyncDataTypePreviewElement_renderConfig).call(this, dataType, other, side)}
|
|
54
|
+
`
|
|
55
|
+
: __classPrivateFieldGet(this, _uSyncDataTypePreviewElement_instances, "m", _uSyncDataTypePreviewElement_renderMissing).call(this, side)}
|
|
56
|
+
</div>
|
|
57
|
+
`;
|
|
58
|
+
};
|
|
59
|
+
_uSyncDataTypePreviewElement_renderMissing = function _uSyncDataTypePreviewElement_renderMissing(side) {
|
|
60
|
+
const message = side === 'current'
|
|
61
|
+
? this.localize.termOrDefault('uSync_previewNotInSite', 'This item does not exist in the site yet')
|
|
62
|
+
: this.preview?.isDelete
|
|
63
|
+
? this.localize.termOrDefault('uSync_previewDeleted', 'This item will be deleted or renamed by the import')
|
|
64
|
+
: this.localize.termOrDefault('uSync_previewFailed', 'The incoming item could not be built for the preview');
|
|
65
|
+
return html `<uui-box class="info"><p class="empty">${message}</p></uui-box>`;
|
|
66
|
+
};
|
|
67
|
+
_uSyncDataTypePreviewElement_renderInfo = function _uSyncDataTypePreviewElement_renderInfo(dataType, other) {
|
|
68
|
+
const changed = (field) => other !== undefined && other[field] !== dataType[field];
|
|
69
|
+
return html `
|
|
70
|
+
<uui-box class="info">
|
|
71
|
+
<div slot="headline" class="headline">
|
|
72
|
+
<umb-icon name="icon-autofill"></umb-icon>
|
|
73
|
+
<span class=${classMap({ changed: changed('name') })}>${dataType.name}</span>
|
|
74
|
+
</div>
|
|
75
|
+
<dl class="meta">
|
|
76
|
+
<dt>
|
|
77
|
+
${this.localize.termOrDefault('uSync_previewPropertyEditor', 'Property editor')}
|
|
78
|
+
</dt>
|
|
79
|
+
<dd class=${classMap({ changed: changed('editorAlias') })}>
|
|
80
|
+
<code>${dataType.editorAlias}</code>
|
|
81
|
+
</dd>
|
|
82
|
+
<dt>
|
|
83
|
+
${this.localize.termOrDefault('uSync_previewPropertyEditorUi', 'Property editor UI')}
|
|
84
|
+
</dt>
|
|
85
|
+
<dd class=${classMap({ changed: changed('editorUiAlias') })}>
|
|
86
|
+
<code>${dataType.editorUiAlias}</code>
|
|
87
|
+
</dd>
|
|
88
|
+
</dl>
|
|
89
|
+
</uui-box>
|
|
90
|
+
`;
|
|
91
|
+
};
|
|
92
|
+
_uSyncDataTypePreviewElement_renderEditor = function _uSyncDataTypePreviewElement_renderEditor(dataType) {
|
|
93
|
+
return html `
|
|
94
|
+
<uui-box
|
|
95
|
+
.headline=${this.localize.termOrDefault('uSync_previewEditor', 'Editor preview')}>
|
|
96
|
+
<!-- inert rather than readonly: most editors render only their value when
|
|
97
|
+
readonly, which is empty here, so you wouldn't see the editor at all. -->
|
|
98
|
+
<umb-property-dataset .value=${[]} inert>
|
|
99
|
+
<umb-property
|
|
100
|
+
alias="usyncPreview"
|
|
101
|
+
.label=${dataType.name}
|
|
102
|
+
.description=${this.localize.termOrDefault('uSync_previewEditorDesc', 'How this data type looks to editors')}
|
|
103
|
+
.propertyEditorUiAlias=${dataType.editorUiAlias}
|
|
104
|
+
.config=${dataType.values}></umb-property>
|
|
105
|
+
</umb-property-dataset>
|
|
106
|
+
</uui-box>
|
|
107
|
+
`;
|
|
108
|
+
};
|
|
109
|
+
_uSyncDataTypePreviewElement_renderConfig = function _uSyncDataTypePreviewElement_renderConfig(dataType, other, side) {
|
|
110
|
+
const values = [...dataType.values].sort((a, b) => a.alias.localeCompare(b.alias));
|
|
111
|
+
return html `
|
|
112
|
+
<uui-box
|
|
113
|
+
.headline=${this.localize.termOrDefault('uSync_previewConfiguration', 'Configuration')}>
|
|
114
|
+
${values.length === 0
|
|
115
|
+
? html `<p class="empty">
|
|
116
|
+
${this.localize.termOrDefault('uSync_previewNoConfiguration', 'No configuration')}
|
|
117
|
+
</p>`
|
|
118
|
+
: html `<table>
|
|
119
|
+
${values.map((value) => {
|
|
120
|
+
const status = configStatus(value.alias, value.value, other, side);
|
|
121
|
+
return html `<tr class="row-${status}">
|
|
122
|
+
<th><code>${value.alias}</code></th>
|
|
123
|
+
<td><pre>${formatConfigValue(value.value)}</pre></td>
|
|
124
|
+
</tr>`;
|
|
125
|
+
})}
|
|
126
|
+
</table>`}
|
|
127
|
+
</uui-box>
|
|
128
|
+
`;
|
|
129
|
+
};
|
|
130
|
+
uSyncDataTypePreviewElement.styles = css `
|
|
131
|
+
:host {
|
|
132
|
+
display: block;
|
|
133
|
+
container-type: inline-size;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/* the two sides share rows (headline, info, editor, config), so the
|
|
137
|
+
boxes line up across the sides. */
|
|
138
|
+
.sides {
|
|
139
|
+
display: grid;
|
|
140
|
+
grid-template-columns: 1fr 1fr;
|
|
141
|
+
grid-template-rows: auto auto auto 1fr;
|
|
142
|
+
gap: var(--uui-size-space-4) var(--uui-size-space-5);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.side {
|
|
146
|
+
display: grid;
|
|
147
|
+
grid-row: span 4;
|
|
148
|
+
grid-template-rows: subgrid;
|
|
149
|
+
min-width: 0;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.side > :last-child {
|
|
153
|
+
align-self: start;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
@container (max-width: 760px) {
|
|
157
|
+
.sides {
|
|
158
|
+
grid-template-columns: 1fr;
|
|
159
|
+
grid-template-rows: none;
|
|
160
|
+
row-gap: var(--uui-size-layout-1);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.side {
|
|
164
|
+
display: flex;
|
|
165
|
+
flex-direction: column;
|
|
166
|
+
gap: var(--uui-size-space-4);
|
|
167
|
+
grid-row: auto;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.side-headline {
|
|
172
|
+
margin: 0;
|
|
173
|
+
font-size: var(--uui-type-small-size);
|
|
174
|
+
text-transform: uppercase;
|
|
175
|
+
letter-spacing: 0.04em;
|
|
176
|
+
color: var(--uui-color-text-alt);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.headline {
|
|
180
|
+
display: flex;
|
|
181
|
+
align-items: center;
|
|
182
|
+
gap: var(--uui-size-space-3);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.meta {
|
|
186
|
+
display: grid;
|
|
187
|
+
grid-template-columns: max-content 1fr;
|
|
188
|
+
align-items: baseline;
|
|
189
|
+
gap: var(--uui-size-space-3) var(--uui-size-space-5);
|
|
190
|
+
margin: 0;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.meta dt {
|
|
194
|
+
font-weight: 700;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.meta dd {
|
|
198
|
+
margin: 0;
|
|
199
|
+
overflow-wrap: anywhere;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/* a changed field gets a soft highlight, spread with a shadow so the text doesn't move. */
|
|
203
|
+
.changed {
|
|
204
|
+
background: color-mix(in srgb, var(--uui-color-warning) 35%, transparent);
|
|
205
|
+
border-radius: var(--uui-border-radius);
|
|
206
|
+
box-shadow: 0 0 0 var(--uui-size-space-1)
|
|
207
|
+
color-mix(in srgb, var(--uui-color-warning) 35%, transparent);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/* umb-property pads itself for a full workspace, tighten it up here. */
|
|
211
|
+
umb-property {
|
|
212
|
+
--uui-size-layout-1: var(--uui-size-space-2);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
table {
|
|
216
|
+
width: 100%;
|
|
217
|
+
border-collapse: collapse;
|
|
218
|
+
margin: calc(-1 * var(--uui-size-space-2)) 0;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
tr + tr {
|
|
222
|
+
border-top: 1px solid var(--uui-color-divider);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
th,
|
|
226
|
+
td {
|
|
227
|
+
text-align: left;
|
|
228
|
+
vertical-align: baseline;
|
|
229
|
+
padding: var(--uui-size-space-3) var(--uui-size-space-3);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/* the alias column is as wide as the longest alias (up to 40%), so values sit beside their names. */
|
|
233
|
+
th {
|
|
234
|
+
width: 1%;
|
|
235
|
+
max-width: 40%;
|
|
236
|
+
white-space: nowrap;
|
|
237
|
+
font-weight: 700;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
th code,
|
|
241
|
+
td pre {
|
|
242
|
+
font-size: var(--uui-type-small-size);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
td pre {
|
|
246
|
+
margin: 0;
|
|
247
|
+
white-space: pre-wrap;
|
|
248
|
+
word-break: break-word;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/* marked with an inset bar rather than a border, so the content doesn't shift. */
|
|
252
|
+
tr.row-changed {
|
|
253
|
+
box-shadow: inset 3px 0 0 var(--uui-color-warning);
|
|
254
|
+
background: color-mix(in srgb, var(--uui-color-warning) 10%, transparent);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
tr.row-added {
|
|
258
|
+
box-shadow: inset 3px 0 0 var(--uui-color-positive);
|
|
259
|
+
background: color-mix(in srgb, var(--uui-color-positive) 6%, transparent);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
tr.row-removed {
|
|
263
|
+
box-shadow: inset 3px 0 0 var(--uui-color-danger);
|
|
264
|
+
background: color-mix(in srgb, var(--uui-color-danger) 6%, transparent);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.empty {
|
|
268
|
+
margin: 0;
|
|
269
|
+
color: var(--uui-color-text-alt);
|
|
270
|
+
}
|
|
271
|
+
`;
|
|
272
|
+
__decorate([
|
|
273
|
+
property({ type: Object })
|
|
274
|
+
], uSyncDataTypePreviewElement.prototype, "preview", void 0);
|
|
275
|
+
uSyncDataTypePreviewElement = __decorate([
|
|
276
|
+
customElement('usync-data-type-preview')
|
|
277
|
+
], uSyncDataTypePreviewElement);
|
|
278
|
+
export { uSyncDataTypePreviewElement };
|
|
279
|
+
/**
|
|
280
|
+
* how a config value on this side compares to the other side. an alias
|
|
281
|
+
* missing from the current side is being added, one missing from the
|
|
282
|
+
* incoming side is being removed.
|
|
283
|
+
*/
|
|
284
|
+
function configStatus(alias, value, other, side) {
|
|
285
|
+
if (!other)
|
|
286
|
+
return 'unchanged';
|
|
287
|
+
const match = other.values.find((v) => v.alias === alias);
|
|
288
|
+
if (!match)
|
|
289
|
+
return side === 'incoming' ? 'added' : 'removed';
|
|
290
|
+
return deepEqual(value, match.value) ? 'unchanged' : 'changed';
|
|
291
|
+
}
|
|
292
|
+
function formatConfigValue(value) {
|
|
293
|
+
return typeof value === 'string' ? value : prettyJson(value);
|
|
294
|
+
}
|
|
295
|
+
export default uSyncDataTypePreviewElement;
|
|
@@ -15,7 +15,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
15
15
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
16
16
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
17
17
|
};
|
|
18
|
-
var _uSyncResultsView_instances, _uSyncResultsView_modalContext, _uSyncResultsView_toggleShowAll, _uSyncResultsView_showDetail;
|
|
18
|
+
var _uSyncResultsView_instances, _uSyncResultsView_modalContext, _uSyncResultsView_toggleShowAll, _uSyncResultsView_showDetail, _uSyncResultsView_visibleItems;
|
|
19
19
|
import { LitElement, html, customElement, property, css, state, nothing, } from '@umbraco-cms/backoffice/external/lit';
|
|
20
20
|
import { ChangeType } from '@jumoo/uSync';
|
|
21
21
|
import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
|
|
@@ -98,10 +98,11 @@ _uSyncResultsView_showDetail = async function _uSyncResultsView_showDetail(e) {
|
|
|
98
98
|
const detailsModal = __classPrivateFieldGet(this, _uSyncResultsView_modalContext, "f")?.open(this, USYNC_DETAILS_MODAL, {
|
|
99
99
|
data: {
|
|
100
100
|
item: e.action,
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
101
|
+
items: __classPrivateFieldGet(this, _uSyncResultsView_instances, "m", _uSyncResultsView_visibleItems).call(this),
|
|
102
|
+
showActions: (item) => !this.hideActions &&
|
|
103
|
+
(item.change == ChangeType.CREATE ||
|
|
104
|
+
item.change == ChangeType.UPDATE ||
|
|
105
|
+
item.change == ChangeType.IMPORT),
|
|
105
106
|
},
|
|
106
107
|
});
|
|
107
108
|
const data = await detailsModal?.onSubmit().catch(() => {
|
|
@@ -110,6 +111,13 @@ _uSyncResultsView_showDetail = async function _uSyncResultsView_showDetail(e) {
|
|
|
110
111
|
if (!data)
|
|
111
112
|
return;
|
|
112
113
|
};
|
|
114
|
+
_uSyncResultsView_visibleItems = function _uSyncResultsView_visibleItems() {
|
|
115
|
+
const groups = this.groupBy(this.results || [], (result) => result.itemType);
|
|
116
|
+
return Object.values(groups)
|
|
117
|
+
.flat()
|
|
118
|
+
.filter((r) => r.change !== ChangeType.EXPORT &&
|
|
119
|
+
(this.showAll || r.change !== ChangeType.NO_CHANGE));
|
|
120
|
+
};
|
|
113
121
|
uSyncResultsView.styles = css `
|
|
114
122
|
:host {
|
|
115
123
|
display: block;
|
|
@@ -2,11 +2,26 @@ import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
|
|
|
2
2
|
import { nothing } from '@umbraco-cms/backoffice/external/lit';
|
|
3
3
|
import { uSyncDetailsModalData, uSyncDetailsModalValue } from '@jumoo/uSync';
|
|
4
4
|
import { UUIButtonState } from '@umbraco-cms/backoffice/external/uui';
|
|
5
|
+
type DetailsTab = 'changes' | 'diff';
|
|
5
6
|
export declare class uSyncDetailsModalElement extends UmbModalBaseElement<uSyncDetailsModalData, uSyncDetailsModalValue> {
|
|
6
7
|
#private;
|
|
7
8
|
importState: UUIButtonState;
|
|
9
|
+
private _preview?;
|
|
10
|
+
private _tab;
|
|
11
|
+
private _loading;
|
|
12
|
+
private _item?;
|
|
13
|
+
private _index;
|
|
14
|
+
/** the entity types there is a 'usync-item-preview' element for */
|
|
15
|
+
private _previewTypes;
|
|
8
16
|
constructor();
|
|
17
|
+
connectedCallback(): void;
|
|
9
18
|
render(): import("lit-html").TemplateResult<1>;
|
|
19
|
+
renderHeadline(): typeof nothing | import("lit-html").TemplateResult<1>;
|
|
20
|
+
renderNavigation(): typeof nothing | import("lit-html").TemplateResult<1>;
|
|
21
|
+
renderTabs(): typeof nothing | import("lit-html").TemplateResult<1>;
|
|
22
|
+
renderTab(tab: DetailsTab, key: string, fallback: string, icon: string): import("lit-html").TemplateResult<1>;
|
|
23
|
+
renderTabContent(): import("lit-html").TemplateResult<1>;
|
|
24
|
+
renderPreview(): import("lit-html").TemplateResult<1>;
|
|
10
25
|
renderActions(): typeof nothing | import("lit-html").TemplateResult<1>;
|
|
11
26
|
static styles: import("lit").CSSResult;
|
|
12
27
|
}
|
|
@@ -9,22 +9,48 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var
|
|
12
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
13
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
14
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
15
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
16
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
17
|
+
};
|
|
18
|
+
var _uSyncDetailsModalElement_instances, _uSyncDetailsModalElement_repository, _uSyncDetailsModalElement_previewFilter, _uSyncDetailsModalElement_previewProps, _uSyncDetailsModalElement_moveTo, _uSyncDetailsModalElement_loadPreview, _uSyncDetailsModalElement_hasPreview, _uSyncDetailsModalElement_showActions, _uSyncDetailsModalElement_onImport, _uSyncDetailsModalElement_onClose;
|
|
13
19
|
import { UMB_MODAL_MANAGER_CONTEXT, UmbModalBaseElement, } from '@umbraco-cms/backoffice/modal';
|
|
14
20
|
import { css, customElement, html, nothing, state, } from '@umbraco-cms/backoffice/external/lit';
|
|
15
|
-
import { USYNC_IMPORT_SINGLE_MODAL, } from '@jumoo/uSync';
|
|
21
|
+
import { USYNC_IMPORT_SINGLE_MODAL, uSyncActionRepository, } from '@jumoo/uSync';
|
|
22
|
+
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
|
|
16
23
|
let uSyncDetailsModalElement = class uSyncDetailsModalElement extends UmbModalBaseElement {
|
|
17
24
|
constructor() {
|
|
18
25
|
super();
|
|
19
26
|
_uSyncDetailsModalElement_instances.add(this);
|
|
27
|
+
this._tab = 'changes';
|
|
28
|
+
this._loading = false;
|
|
29
|
+
this._index = -1;
|
|
30
|
+
/** the entity types there is a 'usync-item-preview' element for */
|
|
31
|
+
this._previewTypes = new Set();
|
|
32
|
+
_uSyncDetailsModalElement_repository.set(this, new uSyncActionRepository(this));
|
|
33
|
+
// kept between renders, so the extension slot doesn't rebuild the preview each time.
|
|
34
|
+
_uSyncDetailsModalElement_previewFilter.set(this, (_manifest) => false);
|
|
35
|
+
_uSyncDetailsModalElement_previewProps.set(this, {});
|
|
36
|
+
this.observe(umbExtensionsRegistry.byType('usync-item-preview'), (manifests) => {
|
|
37
|
+
this._previewTypes = new Set(manifests.flatMap((m) => m.forEntityTypes));
|
|
38
|
+
});
|
|
20
39
|
// this.consumeContext(USYNC_CORE_CONTEXT_TOKEN, (_instance) => {
|
|
21
40
|
// if (!_instance) return;
|
|
22
41
|
// this.#actionContext = _instance;
|
|
23
42
|
// });
|
|
24
43
|
}
|
|
44
|
+
connectedCallback() {
|
|
45
|
+
super.connectedCallback();
|
|
46
|
+
this._item = this.data?.item;
|
|
47
|
+
this._index = this.data?.items?.indexOf(this.data.item) ?? -1;
|
|
48
|
+
__classPrivateFieldGet(this, _uSyncDetailsModalElement_instances, "m", _uSyncDetailsModalElement_loadPreview).call(this);
|
|
49
|
+
}
|
|
25
50
|
render() {
|
|
26
51
|
return html `
|
|
27
|
-
<umb-body-layout
|
|
52
|
+
<umb-body-layout>
|
|
53
|
+
${this.renderHeadline()}
|
|
28
54
|
<div class="layout">
|
|
29
55
|
<uui-box style="--uui-box-default-padding: 0;">
|
|
30
56
|
<div slot="header" id="header">
|
|
@@ -33,10 +59,10 @@ let uSyncDetailsModalElement = class uSyncDetailsModalElement extends UmbModalBa
|
|
|
33
59
|
</div>
|
|
34
60
|
<div slot="header-actions">${this.renderActions()}</div>
|
|
35
61
|
</uui-box>
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
</uui-box>
|
|
62
|
+
${this.renderTabs()}
|
|
63
|
+
${this.renderTabContent()}
|
|
39
64
|
</div>
|
|
65
|
+
${this.renderNavigation()}
|
|
40
66
|
<div slot="actions">
|
|
41
67
|
<uui-button
|
|
42
68
|
id="cancel"
|
|
@@ -46,8 +72,87 @@ let uSyncDetailsModalElement = class uSyncDetailsModalElement extends UmbModalBa
|
|
|
46
72
|
</umb-body-layout>
|
|
47
73
|
`;
|
|
48
74
|
}
|
|
75
|
+
renderHeadline() {
|
|
76
|
+
const item = this._item;
|
|
77
|
+
if (!item)
|
|
78
|
+
return nothing;
|
|
79
|
+
// singular names first (Content type), then the plural group
|
|
80
|
+
// names the results use (Content Types), then the raw type.
|
|
81
|
+
const itemType = this.localize.termOrDefault(`uSync_itemType${item.itemType}`, this.localize.termOrDefault(`uSync_${item.itemType}`, item.itemType));
|
|
82
|
+
return html `<div slot="header" id="headline">
|
|
83
|
+
<h3 title=${item.name}>Changes : ${item.name}</h3>
|
|
84
|
+
<span class="item-info">${itemType} · ${item.change}</span>
|
|
85
|
+
</div>`;
|
|
86
|
+
}
|
|
87
|
+
renderNavigation() {
|
|
88
|
+
const count = this.data?.items?.length ?? 0;
|
|
89
|
+
if (count < 2 || this._index < 0)
|
|
90
|
+
return nothing;
|
|
91
|
+
return html `<div slot="footer-info" id="navigation">
|
|
92
|
+
<uui-button
|
|
93
|
+
compact
|
|
94
|
+
look="secondary"
|
|
95
|
+
.label=${this.localize.term('general_previous')}
|
|
96
|
+
?disabled=${this._index === 0}
|
|
97
|
+
@click=${() => __classPrivateFieldGet(this, _uSyncDetailsModalElement_instances, "m", _uSyncDetailsModalElement_moveTo).call(this, this._index - 1)}>
|
|
98
|
+
<uui-icon name="icon-arrow-left"></uui-icon>
|
|
99
|
+
</uui-button>
|
|
100
|
+
<span>
|
|
101
|
+
${this.localize.termOrDefault('uSync_detailPosition', `${this._index + 1} of ${count}`, this.localize.number(this._index + 1), this.localize.number(count))}
|
|
102
|
+
</span>
|
|
103
|
+
<uui-button
|
|
104
|
+
compact
|
|
105
|
+
look="secondary"
|
|
106
|
+
.label=${this.localize.term('general_next')}
|
|
107
|
+
?disabled=${this._index === count - 1}
|
|
108
|
+
@click=${() => __classPrivateFieldGet(this, _uSyncDetailsModalElement_instances, "m", _uSyncDetailsModalElement_moveTo).call(this, this._index + 1)}>
|
|
109
|
+
<uui-icon name="icon-arrow-right"></uui-icon>
|
|
110
|
+
</uui-button>
|
|
111
|
+
</div>`;
|
|
112
|
+
}
|
|
113
|
+
renderTabs() {
|
|
114
|
+
if (!__classPrivateFieldGet(this, _uSyncDetailsModalElement_instances, "m", _uSyncDetailsModalElement_hasPreview).call(this))
|
|
115
|
+
return nothing;
|
|
116
|
+
return html `<uui-tab-group>
|
|
117
|
+
${this.renderTab('changes', 'uSync_changesTab', 'Changes', 'icon-eye')}
|
|
118
|
+
${this.renderTab('diff', 'uSync_diffTab', 'Diff', 'icon-code')}
|
|
119
|
+
</uui-tab-group>`;
|
|
120
|
+
}
|
|
121
|
+
renderTab(tab, key, fallback, icon) {
|
|
122
|
+
const label = this.localize.termOrDefault(key, fallback);
|
|
123
|
+
return html `<uui-tab
|
|
124
|
+
.label=${label}
|
|
125
|
+
?active=${this._tab === tab}
|
|
126
|
+
@click=${() => (this._tab = tab)}>
|
|
127
|
+
<!-- uui-tab stacks its icon slot above the label, so the icon
|
|
128
|
+
goes in the label to keep them on one line. -->
|
|
129
|
+
<span class="tab-label"><umb-icon name=${icon}></umb-icon>${label}</span>
|
|
130
|
+
</uui-tab>`;
|
|
131
|
+
}
|
|
132
|
+
renderTabContent() {
|
|
133
|
+
// the visual changes view is the default, the raw diff is there
|
|
134
|
+
// for anything that doesn't have a preview (or if you ask for it).
|
|
135
|
+
if (this._tab === 'changes') {
|
|
136
|
+
if (this._loading)
|
|
137
|
+
return html `<uui-loader-bar></uui-loader-bar>`;
|
|
138
|
+
if (__classPrivateFieldGet(this, _uSyncDetailsModalElement_instances, "m", _uSyncDetailsModalElement_hasPreview).call(this))
|
|
139
|
+
return this.renderPreview();
|
|
140
|
+
}
|
|
141
|
+
return html `<uui-box style="--uui-box-default-padding: 0;">
|
|
142
|
+
<usync-change-view .item=${this._item}></usync-change-view>
|
|
143
|
+
</uui-box>`;
|
|
144
|
+
}
|
|
145
|
+
renderPreview() {
|
|
146
|
+
// packages can show previews for their own items by registering a
|
|
147
|
+
// 'usync-item-preview' element for the entity type their preview mapper returns.
|
|
148
|
+
return html `<umb-extension-slot
|
|
149
|
+
type="usync-item-preview"
|
|
150
|
+
single
|
|
151
|
+
.filter=${__classPrivateFieldGet(this, _uSyncDetailsModalElement_previewFilter, "f")}
|
|
152
|
+
.props=${__classPrivateFieldGet(this, _uSyncDetailsModalElement_previewProps, "f")}></umb-extension-slot>`;
|
|
153
|
+
}
|
|
49
154
|
renderActions() {
|
|
50
|
-
if (!this.
|
|
155
|
+
if (!__classPrivateFieldGet(this, _uSyncDetailsModalElement_instances, "m", _uSyncDetailsModalElement_showActions).call(this))
|
|
51
156
|
return nothing;
|
|
52
157
|
return html ` <uui-button
|
|
53
158
|
id="import"
|
|
@@ -58,16 +163,59 @@ let uSyncDetailsModalElement = class uSyncDetailsModalElement extends UmbModalBa
|
|
|
58
163
|
@click="${__classPrivateFieldGet(this, _uSyncDetailsModalElement_instances, "m", _uSyncDetailsModalElement_onImport)}"></uui-button>`;
|
|
59
164
|
}
|
|
60
165
|
};
|
|
166
|
+
_uSyncDetailsModalElement_repository = new WeakMap();
|
|
167
|
+
_uSyncDetailsModalElement_previewFilter = new WeakMap();
|
|
168
|
+
_uSyncDetailsModalElement_previewProps = new WeakMap();
|
|
61
169
|
_uSyncDetailsModalElement_instances = new WeakSet();
|
|
170
|
+
_uSyncDetailsModalElement_moveTo = function _uSyncDetailsModalElement_moveTo(index) {
|
|
171
|
+
const item = this.data?.items?.[index];
|
|
172
|
+
if (!item)
|
|
173
|
+
return;
|
|
174
|
+
this._index = index;
|
|
175
|
+
this._item = item;
|
|
176
|
+
this._preview = undefined;
|
|
177
|
+
__classPrivateFieldGet(this, _uSyncDetailsModalElement_instances, "m", _uSyncDetailsModalElement_loadPreview).call(this);
|
|
178
|
+
};
|
|
179
|
+
_uSyncDetailsModalElement_loadPreview = async function _uSyncDetailsModalElement_loadPreview() {
|
|
180
|
+
const item = this._item;
|
|
181
|
+
if (!item?.handler || !item.key)
|
|
182
|
+
return;
|
|
183
|
+
// only some handlers support previews, the rest return a 404
|
|
184
|
+
// and the modal shows the diff on its own. we leave _tab alone
|
|
185
|
+
// so a user who picked the diff stays on it as they move through.
|
|
186
|
+
this._loading = true;
|
|
187
|
+
const { data } = await __classPrivateFieldGet(this, _uSyncDetailsModalElement_repository, "f").getPreview(item.handler, item.key);
|
|
188
|
+
// moving through the list quickly can return previews out of order,
|
|
189
|
+
// so drop anything that isn't for the item we are now showing.
|
|
190
|
+
if (item !== this._item)
|
|
191
|
+
return;
|
|
192
|
+
this._loading = false;
|
|
193
|
+
if (data?.entityType) {
|
|
194
|
+
const entityType = data.entityType;
|
|
195
|
+
__classPrivateFieldSet(this, _uSyncDetailsModalElement_previewFilter, (manifest) => manifest.forEntityTypes.includes(entityType), "f");
|
|
196
|
+
__classPrivateFieldSet(this, _uSyncDetailsModalElement_previewProps, { preview: data }, "f");
|
|
197
|
+
this._preview = data;
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
_uSyncDetailsModalElement_hasPreview = function _uSyncDetailsModalElement_hasPreview() {
|
|
201
|
+
return !!this._preview && this._previewTypes.has(this._preview.entityType);
|
|
202
|
+
};
|
|
203
|
+
_uSyncDetailsModalElement_showActions = function _uSyncDetailsModalElement_showActions() {
|
|
204
|
+
const showActions = this.data?.showActions;
|
|
205
|
+
if (typeof showActions === 'function') {
|
|
206
|
+
return this._item ? showActions(this._item) : false;
|
|
207
|
+
}
|
|
208
|
+
return showActions ?? false;
|
|
209
|
+
};
|
|
62
210
|
_uSyncDetailsModalElement_onImport = async function _uSyncDetailsModalElement_onImport(e) {
|
|
63
211
|
e.stopPropagation();
|
|
64
|
-
if (!this.
|
|
212
|
+
if (!this._item)
|
|
65
213
|
return;
|
|
66
214
|
const modalContext = await this.getContext(UMB_MODAL_MANAGER_CONTEXT);
|
|
67
215
|
if (!modalContext)
|
|
68
216
|
return;
|
|
69
217
|
const modal = modalContext.open(this, USYNC_IMPORT_SINGLE_MODAL, {
|
|
70
|
-
data: { action: this.
|
|
218
|
+
data: { action: this._item },
|
|
71
219
|
});
|
|
72
220
|
const data = await modal?.onSubmit().catch(() => {
|
|
73
221
|
return;
|
|
@@ -87,10 +235,70 @@ uSyncDetailsModalElement.styles = css `
|
|
|
87
235
|
#header h3 {
|
|
88
236
|
margin: 0;
|
|
89
237
|
}
|
|
238
|
+
|
|
239
|
+
#headline {
|
|
240
|
+
display: flex;
|
|
241
|
+
flex-direction: column;
|
|
242
|
+
min-width: 0;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
#headline h3 {
|
|
246
|
+
margin: 0;
|
|
247
|
+
white-space: nowrap;
|
|
248
|
+
overflow: hidden;
|
|
249
|
+
text-overflow: ellipsis;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
#headline .item-info {
|
|
253
|
+
font-size: var(--uui-type-small-size);
|
|
254
|
+
color: var(--uui-color-text-alt);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
uui-tab-group {
|
|
258
|
+
background-color: var(--uui-color-surface);
|
|
259
|
+
border-radius: var(--uui-border-radius);
|
|
260
|
+
box-shadow: var(--uui-shadow-depth-1);
|
|
261
|
+
padding: 0 var(--uui-size-space-2);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.tab-label {
|
|
265
|
+
display: inline-flex;
|
|
266
|
+
align-items: center;
|
|
267
|
+
gap: var(--uui-size-space-2);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.tab-label umb-icon {
|
|
271
|
+
font-size: 16px;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
#navigation {
|
|
275
|
+
display: flex;
|
|
276
|
+
align-items: center;
|
|
277
|
+
gap: var(--uui-size-space-3);
|
|
278
|
+
padding-left: var(--uui-size-space-4);
|
|
279
|
+
}
|
|
90
280
|
`;
|
|
91
281
|
__decorate([
|
|
92
282
|
state()
|
|
93
283
|
], uSyncDetailsModalElement.prototype, "importState", void 0);
|
|
284
|
+
__decorate([
|
|
285
|
+
state()
|
|
286
|
+
], uSyncDetailsModalElement.prototype, "_preview", void 0);
|
|
287
|
+
__decorate([
|
|
288
|
+
state()
|
|
289
|
+
], uSyncDetailsModalElement.prototype, "_tab", void 0);
|
|
290
|
+
__decorate([
|
|
291
|
+
state()
|
|
292
|
+
], uSyncDetailsModalElement.prototype, "_loading", void 0);
|
|
293
|
+
__decorate([
|
|
294
|
+
state()
|
|
295
|
+
], uSyncDetailsModalElement.prototype, "_item", void 0);
|
|
296
|
+
__decorate([
|
|
297
|
+
state()
|
|
298
|
+
], uSyncDetailsModalElement.prototype, "_index", void 0);
|
|
299
|
+
__decorate([
|
|
300
|
+
state()
|
|
301
|
+
], uSyncDetailsModalElement.prototype, "_previewTypes", void 0);
|
|
94
302
|
uSyncDetailsModalElement = __decorate([
|
|
95
303
|
customElement('usync-details-modal')
|
|
96
304
|
], uSyncDetailsModalElement);
|
|
@@ -2,7 +2,16 @@ import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
|
|
|
2
2
|
import { USyncActionView } from '@jumoo/uSync';
|
|
3
3
|
export interface uSyncDetailsModalData {
|
|
4
4
|
item: USyncActionView;
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* show the import button, either for every item or decided per item
|
|
7
|
+
* (when moving through `items` the answer can change from item to item).
|
|
8
|
+
*/
|
|
9
|
+
showActions?: boolean | ((item: USyncActionView) => boolean);
|
|
10
|
+
/**
|
|
11
|
+
* the full list the item came from, when set the dialog can move
|
|
12
|
+
* to the previous / next item in the list.
|
|
13
|
+
*/
|
|
14
|
+
items?: Array<USyncActionView>;
|
|
6
15
|
}
|
|
7
16
|
export interface uSyncDetailsModalValue {
|
|
8
17
|
result: boolean;
|
package/dist/exports.d.ts
CHANGED
package/dist/exports.js
CHANGED