@jumoo/usync 17.5.0 → 17.5.2-prerelease.15

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 (63) hide show
  1. package/LICENCE +372 -372
  2. package/README.md +10 -10
  3. package/dist/api/index.d.ts +1 -1
  4. package/dist/api/index.js +1 -1
  5. package/dist/api/sdk.gen.d.ts +2 -1
  6. package/dist/api/sdk.gen.js +7 -0
  7. package/dist/api/types.gen.d.ts +361 -0
  8. package/dist/api/types.gen.js +13 -0
  9. package/dist/components/index.d.ts +3 -0
  10. package/dist/components/index.js +3 -0
  11. package/dist/components/usync-action-box.js +61 -61
  12. package/dist/components/usync-change-detail.js +409 -409
  13. package/dist/components/usync-change-view.js +49 -49
  14. package/dist/components/usync-content-preview.d.ts +27 -0
  15. package/dist/components/usync-content-preview.js +540 -0
  16. package/dist/components/usync-content-type-preview.d.ts +25 -0
  17. package/dist/components/usync-content-type-preview.js +548 -0
  18. package/dist/components/usync-data-type-preview.d.ts +21 -0
  19. package/dist/components/usync-data-type-preview.js +293 -0
  20. package/dist/components/usync-progress-box.js +106 -106
  21. package/dist/components/usync-result-row.js +61 -61
  22. package/dist/components/usync-results-group-view.js +55 -55
  23. package/dist/components/usync-results-view.js +76 -68
  24. package/dist/components/usync-sync-file-info-view.js +10 -10
  25. package/dist/dialogs/details-modal-element.d.ts +12 -1
  26. package/dist/dialogs/details-modal-element.js +172 -42
  27. package/dist/dialogs/details-modal-token.d.ts +10 -1
  28. package/dist/dialogs/error-modal-element.js +21 -21
  29. package/dist/dialogs/legacy-modal-element.js +22 -22
  30. package/dist/dialogs/single-import-modal.element.js +30 -30
  31. package/dist/icons/svg/logo.js +20 -20
  32. package/dist/lang/files/da-dk.d.ts +37 -0
  33. package/dist/lang/files/da-dk.js +49 -12
  34. package/dist/lang/files/de-de.d.ts +37 -0
  35. package/dist/lang/files/de-de.js +49 -12
  36. package/dist/lang/files/en-us.d.ts +37 -0
  37. package/dist/lang/files/en-us.js +49 -12
  38. package/dist/lang/files/es-es.d.ts +37 -0
  39. package/dist/lang/files/es-es.js +49 -12
  40. package/dist/lang/files/fr-fr.d.ts +37 -0
  41. package/dist/lang/files/fr-fr.js +49 -12
  42. package/dist/lang/files/nl-nl.d.ts +37 -0
  43. package/dist/lang/files/nl-nl.js +49 -12
  44. package/dist/repository/SyncAction.respositoy.d.ts +8 -0
  45. package/dist/repository/SyncAction.respositoy.js +6 -0
  46. package/dist/repository/sources/SyncAction.source.d.ts +5 -0
  47. package/dist/repository/sources/SyncAction.source.js +5 -0
  48. package/dist/tree/usync.menu-element.js +8 -8
  49. package/dist/utils/preview/content-type-diff.d.ts +18 -0
  50. package/dist/utils/preview/content-type-diff.js +72 -0
  51. package/dist/utils/preview/content-type-layout.d.ts +39 -0
  52. package/dist/utils/preview/content-type-layout.js +100 -0
  53. package/dist/workspace/components/usync-action-button.js +50 -50
  54. package/dist/workspace/components/usync-file-picker.element.js +33 -33
  55. package/dist/workspace/components/usync-file-upload.element.js +25 -25
  56. package/dist/workspace/dialogs/import-modal.element.js +22 -22
  57. package/dist/workspace/views/addons/addons.element.js +97 -97
  58. package/dist/workspace/views/default/default.element.js +186 -186
  59. package/dist/workspace/views/legacy/legacy.element.js +81 -81
  60. package/dist/workspace/views/settings/components/usyncSettingItem.element.js +38 -38
  61. package/dist/workspace/views/settings/settings.element.js +124 -124
  62. package/dist/workspace/workspace.element.js +16 -16
  63. package/package.json +70 -70
@@ -22,26 +22,26 @@ let uSyncResultGroupView = class uSyncResultGroupView extends UmbLitElement {
22
22
  const changeCount = this.getChangeCount() ?? 0;
23
23
  if (changeCount === 0 && !this.showAll)
24
24
  return nothing;
25
- return html `
26
- <uui-box
25
+ return html `
26
+ <uui-box
27
27
  class=${classMap({
28
28
  has_changes: changeCount > 0,
29
- })}>
30
- <div
31
- class="summary ${when(this.expanded, () => 'expanded')}"
32
- @click=${() => (this.expanded = !this.expanded)}>
33
- <h4>${this.localize.termOrDefault('uSync_' + this.groupName, this.groupName)}</h4>
34
- <div class="summary-right">
35
- <h4 class="count">${changeCount}/${this.results?.length}</h4>
36
- <uui-icon
37
- name="icon-play"
38
- class=${classMap({ expanded: this.expanded })}></uui-icon>
39
- </div>
40
- </div>
41
- <uui-table>
42
- ${when(this.expanded == true, () => html `${this.renderGroupedRows(this.results)}`)}
43
- </uui-table>
44
- </uui-box>
29
+ })}>
30
+ <div
31
+ class="summary ${when(this.expanded, () => 'expanded')}"
32
+ @click=${() => (this.expanded = !this.expanded)}>
33
+ <h4>${this.localize.termOrDefault('uSync_' + this.groupName, this.groupName)}</h4>
34
+ <div class="summary-right">
35
+ <h4 class="count">${changeCount}/${this.results?.length}</h4>
36
+ <uui-icon
37
+ name="icon-play"
38
+ class=${classMap({ expanded: this.expanded })}></uui-icon>
39
+ </div>
40
+ </div>
41
+ <uui-table>
42
+ ${when(this.expanded == true, () => html `${this.renderGroupedRows(this.results)}`)}
43
+ </uui-table>
44
+ </uui-box>
45
45
  `;
46
46
  }
47
47
  renderGroupedRows(results) {
@@ -53,43 +53,43 @@ let uSyncResultGroupView = class uSyncResultGroupView extends UmbLitElement {
53
53
  return rowsHtml;
54
54
  }
55
55
  };
56
- uSyncResultGroupView.styles = css `
57
- uui-box {
58
- cursor: pointer;
59
- --uui-box-default-padding: 0;
60
- }
61
-
62
- .expanded {
63
- border-bottom: 1px solid var(--uui-color-border);
64
- }
65
-
66
- .summary {
67
- display: flex;
68
- margin: 0;
69
- padding: 0 20px;
70
- justify-content: space-between;
71
- }
72
-
73
- .summary-right {
74
- display: flex;
75
- align-items: center;
76
- gap: var(--uui-size-space-2);
77
- color: var(--uui-color-border-emphasis);
78
- }
79
-
80
- .summary-right uui-icon {
81
- transform: rotate(90deg);
82
- transition: transform 0.5s cubic-bezier(0.42, 0, 0.37, 1.62);
83
- }
84
-
85
- .summary-right uui-icon.expanded {
86
- transform: rotate(-90deg);
87
- border-bottom: none;
88
- }
89
-
90
- .count {
91
- color: var(--uui-text);
92
- }
56
+ uSyncResultGroupView.styles = css `
57
+ uui-box {
58
+ cursor: pointer;
59
+ --uui-box-default-padding: 0;
60
+ }
61
+
62
+ .expanded {
63
+ border-bottom: 1px solid var(--uui-color-border);
64
+ }
65
+
66
+ .summary {
67
+ display: flex;
68
+ margin: 0;
69
+ padding: 0 20px;
70
+ justify-content: space-between;
71
+ }
72
+
73
+ .summary-right {
74
+ display: flex;
75
+ align-items: center;
76
+ gap: var(--uui-size-space-2);
77
+ color: var(--uui-color-border-emphasis);
78
+ }
79
+
80
+ .summary-right uui-icon {
81
+ transform: rotate(90deg);
82
+ transition: transform 0.5s cubic-bezier(0.42, 0, 0.37, 1.62);
83
+ }
84
+
85
+ .summary-right uui-icon.expanded {
86
+ transform: rotate(-90deg);
87
+ border-bottom: none;
88
+ }
89
+
90
+ .count {
91
+ color: var(--uui-text);
92
+ }
93
93
  `;
94
94
  __decorate([
95
95
  state()
@@ -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';
@@ -52,37 +52,37 @@ let uSyncResultsView = class uSyncResultsView extends UmbElementMixin(LitElement
52
52
  const groupChanges = groups[key].filter((r) => r.change !== ChangeType.NO_CHANGE).length ?? 0;
53
53
  if (groupChanges === 0 && !this.showAll)
54
54
  continue;
55
- const groupHtml = html `<usync-result-group
56
- .groupName=${key}
57
- .results=${groups[key]}
58
- .showAll=${this.showAll}
55
+ const groupHtml = html `<usync-result-group
56
+ .groupName=${key}
57
+ .results=${groups[key]}
58
+ .showAll=${this.showAll}
59
59
  @show-detail=${__classPrivateFieldGet(this, _uSyncResultsView_instances, "m", _uSyncResultsView_showDetail)}></usync-result-group> `;
60
60
  groupsHtml.push(groupHtml);
61
61
  }
62
62
  return this.changeCount == 0 && !this.showAll
63
- ? html `
64
- ${this.renderResultBar(this.results?.length || 0, this.changeCount)}
65
- <div class="empty">
66
- <umb-localize key="uSync_noChange"></umb-localize>
67
- </div>
63
+ ? html `
64
+ ${this.renderResultBar(this.results?.length || 0, this.changeCount)}
65
+ <div class="empty">
66
+ <umb-localize key="uSync_noChange"></umb-localize>
67
+ </div>
68
68
  `
69
- : html `<div id="result-box">
70
- ${this.renderResultBar(this.results?.length || 0, this.changeCount)}
71
- ${groupsHtml}
69
+ : html `<div id="result-box">
70
+ ${this.renderResultBar(this.results?.length || 0, this.changeCount)}
71
+ ${groupsHtml}
72
72
  </div>`;
73
73
  }
74
74
  renderResultBar(count, changes) {
75
75
  if (this.hideResultBar)
76
76
  return nothing;
77
77
  const localKey = changes === 0 ? 'uSync_noChangeCount' : 'uSync_changeCount';
78
- return html `<div class="result-header">
79
- <uui-toggle
80
- .label=${this.localize.termOrDefault('uSync_showAll', 'Show all items')}
81
- ?checked=${this.showAll}
82
- @change=${__classPrivateFieldGet(this, _uSyncResultsView_instances, "m", _uSyncResultsView_toggleShowAll)}></uui-toggle>
83
- <umb-localize .key=${localKey} .args=${[count, changes]}
84
- >${changes}/${count} items</umb-localize
85
- >
78
+ return html `<div class="result-header">
79
+ <uui-toggle
80
+ .label=${this.localize.termOrDefault('uSync_showAll', 'Show all items')}
81
+ ?checked=${this.showAll}
82
+ @change=${__classPrivateFieldGet(this, _uSyncResultsView_instances, "m", _uSyncResultsView_toggleShowAll)}></uui-toggle>
83
+ <umb-localize .key=${localKey} .args=${[count, changes]}
84
+ >${changes}/${count} items</umb-localize
85
+ >
86
86
  </div>`;
87
87
  }
88
88
  };
@@ -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
- showActions: !this.hideActions &&
102
- (e.action.change == ChangeType.CREATE ||
103
- e.action.change == ChangeType.UPDATE ||
104
- e.action.change == ChangeType.IMPORT),
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,49 +111,56 @@ _uSyncResultsView_showDetail = async function _uSyncResultsView_showDetail(e) {
110
111
  if (!data)
111
112
  return;
112
113
  };
113
- uSyncResultsView.styles = css `
114
- :host {
115
- display: block;
116
- margin: var(--uui-size-space-4) 0;
117
- display: flex;
118
- flex-direction: column;
119
- gap: var(--uui-size-space-4);
120
- }
121
-
122
- #result-box {
123
- display: flex;
124
- flex-direction: column;
125
- gap: var(--uui-size-space-4);
126
- }
127
-
128
- uui-table {
129
- position: relative;
130
- z-index: 100;
131
- }
132
-
133
- .result-header {
134
- display: flex;
135
- justify-content: space-between;
136
- padding: var(--uui-size-space-4);
137
- border: 1px solid var(--uui-color-border);
138
- padding: var(--uui-size-space-4);
139
- }
140
-
141
- .result-header h3 {
142
- margin: 0;
143
- padding: 0;
144
- }
145
-
146
- .empty {
147
- padding: var(--uui-size-20);
148
- font-size: var(--uui-type-h5-size);
149
- text-align: center;
150
- font-weight: 900;
151
- }
152
-
153
- .error {
154
- background-color: #fce4ec;
155
- }
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
+ };
121
+ uSyncResultsView.styles = css `
122
+ :host {
123
+ display: block;
124
+ margin: var(--uui-size-space-4) 0;
125
+ display: flex;
126
+ flex-direction: column;
127
+ gap: var(--uui-size-space-4);
128
+ }
129
+
130
+ #result-box {
131
+ display: flex;
132
+ flex-direction: column;
133
+ gap: var(--uui-size-space-4);
134
+ }
135
+
136
+ uui-table {
137
+ position: relative;
138
+ z-index: 100;
139
+ }
140
+
141
+ .result-header {
142
+ display: flex;
143
+ justify-content: space-between;
144
+ padding: var(--uui-size-space-4);
145
+ border: 1px solid var(--uui-color-border);
146
+ padding: var(--uui-size-space-4);
147
+ }
148
+
149
+ .result-header h3 {
150
+ margin: 0;
151
+ padding: 0;
152
+ }
153
+
154
+ .empty {
155
+ padding: var(--uui-size-20);
156
+ font-size: var(--uui-type-h5-size);
157
+ text-align: center;
158
+ font-weight: 900;
159
+ }
160
+
161
+ .error {
162
+ background-color: #fce4ec;
163
+ }
156
164
  `;
157
165
  __decorate([
158
166
  property({ type: Array })
@@ -30,8 +30,8 @@ _uSyncSyncFileInfoView_renderHmacMismatch = function _uSyncSyncFileInfoView_rend
30
30
  return nothing;
31
31
  if (this._syncFileInfo.hmacMatch)
32
32
  return nothing;
33
- return html `<div class="banner">
34
- <umb-localize key="uSync_hmacMismatch"></umb-localize>
33
+ return html `<div class="banner">
34
+ <umb-localize key="uSync_hmacMismatch"></umb-localize>
35
35
  </div>`;
36
36
  };
37
37
  _uSyncSyncFileInfoView_renderFormatMismatch = function _uSyncSyncFileInfoView_renderFormatMismatch() {
@@ -39,17 +39,17 @@ _uSyncSyncFileInfoView_renderFormatMismatch = function _uSyncSyncFileInfoView_re
39
39
  return nothing;
40
40
  if (this._syncFileInfo.isCurrent)
41
41
  return nothing;
42
- return html `<div class="banner">
43
- <umb-localize key="uSync_formatMismatch"></umb-localize>
42
+ return html `<div class="banner">
43
+ <umb-localize key="uSync_formatMismatch"></umb-localize>
44
44
  </div>`;
45
45
  };
46
46
  uSyncSyncFileInfoView.styles = [
47
- css `
48
- .banner {
49
- padding: var(--uui-size-space-2) var(--uui-size-space-4);
50
- margin: 0 0 var(--uui-size-space-4);
51
- background-color: var(--uui-color-surface);
52
- }
47
+ css `
48
+ .banner {
49
+ padding: var(--uui-size-space-2) var(--uui-size-space-4);
50
+ margin: 0 0 var(--uui-size-space-4);
51
+ background-color: var(--uui-color-surface);
52
+ }
53
53
  `,
54
54
  ];
55
55
  __decorate([
@@ -1,12 +1,23 @@
1
1
  import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
2
2
  import { nothing } from '@umbraco-cms/backoffice/external/lit';
3
- import { uSyncDetailsModalData, uSyncDetailsModalValue } from '@jumoo/uSync';
3
+ import { uSyncDetailsModalData, uSyncDetailsModalValue, type SyncItemPreviewResponse } from '@jumoo/uSync';
4
4
  import { UUIButtonState } from '@umbraco-cms/backoffice/external/uui';
5
+ import '../components/usync-data-type-preview.js';
6
+ import '../components/usync-content-type-preview.js';
7
+ import '../components/usync-content-preview.js';
5
8
  export declare class uSyncDetailsModalElement extends UmbModalBaseElement<uSyncDetailsModalData, uSyncDetailsModalValue> {
6
9
  #private;
7
10
  importState: UUIButtonState;
11
+ private _preview?;
12
+ private _tab;
13
+ private _item?;
14
+ private _index;
8
15
  constructor();
16
+ connectedCallback(): void;
9
17
  render(): import("lit-html").TemplateResult<1>;
18
+ renderNavigation(): typeof nothing | import("lit-html").TemplateResult<1>;
19
+ renderTabs(): typeof nothing | import("lit-html").TemplateResult<1>;
20
+ renderPreview(preview: SyncItemPreviewResponse): typeof nothing | import("lit-html").TemplateResult<1>;
10
21
  renderActions(): typeof nothing | import("lit-html").TemplateResult<1>;
11
22
  static styles: import("lit").CSSResult;
12
23
  }
@@ -9,65 +9,176 @@ 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 _uSyncDetailsModalElement_instances, _uSyncDetailsModalElement_onImport, _uSyncDetailsModalElement_onClose;
12
+ var _uSyncDetailsModalElement_instances, _uSyncDetailsModalElement_repository, _uSyncDetailsModalElement_moveTo, _uSyncDetailsModalElement_loadPreview, _uSyncDetailsModalElement_showActions, _uSyncDetailsModalElement_onImport, _uSyncDetailsModalElement_onClose;
13
13
  import { UMB_MODAL_MANAGER_CONTEXT, UmbModalBaseElement, } from '@umbraco-cms/backoffice/modal';
14
14
  import { css, customElement, html, nothing, state, } from '@umbraco-cms/backoffice/external/lit';
15
- import { USYNC_IMPORT_SINGLE_MODAL, } from '@jumoo/uSync';
15
+ import { USYNC_IMPORT_SINGLE_MODAL, uSyncActionRepository, } from '@jumoo/uSync';
16
+ import '../components/usync-data-type-preview.js';
17
+ import '../components/usync-content-type-preview.js';
18
+ import '../components/usync-content-preview.js';
16
19
  let uSyncDetailsModalElement = class uSyncDetailsModalElement extends UmbModalBaseElement {
17
20
  constructor() {
18
21
  super();
19
22
  _uSyncDetailsModalElement_instances.add(this);
23
+ this._tab = 'changes';
24
+ this._index = -1;
25
+ _uSyncDetailsModalElement_repository.set(this, new uSyncActionRepository(this));
20
26
  // this.consumeContext(USYNC_CORE_CONTEXT_TOKEN, (_instance) => {
21
27
  // if (!_instance) return;
22
28
  // this.#actionContext = _instance;
23
29
  // });
24
30
  }
31
+ connectedCallback() {
32
+ super.connectedCallback();
33
+ this._item = this.data?.item;
34
+ this._index = this.data?.items?.indexOf(this.data.item) ?? -1;
35
+ __classPrivateFieldGet(this, _uSyncDetailsModalElement_instances, "m", _uSyncDetailsModalElement_loadPreview).call(this);
36
+ }
25
37
  render() {
26
- return html `
27
- <umb-body-layout headline="Changes : ${this.data?.item.name ?? ''}">
28
- <div class="layout">
29
- <uui-box style="--uui-box-default-padding: 0;">
30
- <div slot="header" id="header">
31
- <h3><umb-localize key="uSync_detailHeadline"></umb-localize></h3>
32
- <umb-localize key="uSync_detailHeader"></umb-localize>
33
- </div>
34
- <div slot="header-actions">${this.renderActions()}</div>
35
- </uui-box>
36
- <uui-box style="--uui-box-default-padding: 0;">
37
- <usync-change-view .item=${this.data?.item}></usync-change-view>
38
- </uui-box>
39
- </div>
40
- <div slot="actions">
41
- <uui-button
42
- id="cancel"
43
- .label=${this.localize.term('general_close')}
44
- @click="${__classPrivateFieldGet(this, _uSyncDetailsModalElement_instances, "m", _uSyncDetailsModalElement_onClose)}"></uui-button>
45
- </div>
46
- </umb-body-layout>
38
+ return html `
39
+ <umb-body-layout headline="Changes : ${this._item?.name ?? ''}">
40
+ <div class="layout">
41
+ <uui-box style="--uui-box-default-padding: 0;">
42
+ <div slot="header" id="header">
43
+ <h3><umb-localize key="uSync_detailHeadline"></umb-localize></h3>
44
+ <umb-localize key="uSync_detailHeader"></umb-localize>
45
+ </div>
46
+ <div slot="header-actions">${this.renderActions()}</div>
47
+ </uui-box>
48
+ ${this.renderTabs()}
49
+ ${this._tab === 'preview' && this._preview
50
+ ? this.renderPreview(this._preview)
51
+ : html `<uui-box style="--uui-box-default-padding: 0;">
52
+ <usync-change-view .item=${this._item}></usync-change-view>
53
+ </uui-box>`}
54
+ </div>
55
+ ${this.renderNavigation()}
56
+ <div slot="actions">
57
+ <uui-button
58
+ id="cancel"
59
+ .label=${this.localize.term('general_close')}
60
+ @click="${__classPrivateFieldGet(this, _uSyncDetailsModalElement_instances, "m", _uSyncDetailsModalElement_onClose)}"></uui-button>
61
+ </div>
62
+ </umb-body-layout>
47
63
  `;
48
64
  }
65
+ renderNavigation() {
66
+ const count = this.data?.items?.length ?? 0;
67
+ if (count < 2 || this._index < 0)
68
+ return nothing;
69
+ return html `<div slot="footer-info" id="navigation">
70
+ <uui-button
71
+ compact
72
+ look="secondary"
73
+ .label=${this.localize.term('general_previous')}
74
+ ?disabled=${this._index === 0}
75
+ @click=${() => __classPrivateFieldGet(this, _uSyncDetailsModalElement_instances, "m", _uSyncDetailsModalElement_moveTo).call(this, this._index - 1)}>
76
+ <uui-icon name="icon-arrow-left"></uui-icon>
77
+ </uui-button>
78
+ <span>
79
+ ${this.localize.termOrDefault('uSync_detailPosition', `${this._index + 1} of ${count}`, this.localize.number(this._index + 1), this.localize.number(count))}
80
+ </span>
81
+ <uui-button
82
+ compact
83
+ look="secondary"
84
+ .label=${this.localize.term('general_next')}
85
+ ?disabled=${this._index === count - 1}
86
+ @click=${() => __classPrivateFieldGet(this, _uSyncDetailsModalElement_instances, "m", _uSyncDetailsModalElement_moveTo).call(this, this._index + 1)}>
87
+ <uui-icon name="icon-arrow-right"></uui-icon>
88
+ </uui-button>
89
+ </div>`;
90
+ }
91
+ renderTabs() {
92
+ if (!this._preview)
93
+ return nothing;
94
+ return html `<uui-tab-group>
95
+ <uui-tab
96
+ .label=${this.localize.termOrDefault('uSync_changesTab', 'Changes')}
97
+ ?active=${this._tab === 'changes'}
98
+ @click=${() => (this._tab = 'changes')}></uui-tab>
99
+ <uui-tab
100
+ .label=${this.localize.termOrDefault('uSync_previewTab', 'Preview')}
101
+ ?active=${this._tab === 'preview'}
102
+ @click=${() => (this._tab = 'preview')}></uui-tab>
103
+ </uui-tab-group>`;
104
+ }
105
+ renderPreview(preview) {
106
+ switch (preview.entityType) {
107
+ case 'data-type':
108
+ return html `<usync-data-type-preview
109
+ .preview=${preview}></usync-data-type-preview>`;
110
+ case 'document-type':
111
+ case 'media-type':
112
+ case 'member-type':
113
+ return html `<usync-content-type-preview
114
+ .preview=${preview}></usync-content-type-preview>`;
115
+ case 'document':
116
+ case 'media':
117
+ return html `<usync-content-preview
118
+ .preview=${preview}></usync-content-preview>`;
119
+ default:
120
+ return nothing;
121
+ }
122
+ }
49
123
  renderActions() {
50
- if (!this.data?.showActions)
124
+ if (!__classPrivateFieldGet(this, _uSyncDetailsModalElement_instances, "m", _uSyncDetailsModalElement_showActions).call(this))
51
125
  return nothing;
52
- return html ` <uui-button
53
- id="import"
54
- type="button"
55
- look="outline"
56
- .state=${this.importState}
57
- .label=${this.localize.termOrDefault('uSync_importSingle', 'Import')}
126
+ return html ` <uui-button
127
+ id="import"
128
+ type="button"
129
+ look="outline"
130
+ .state=${this.importState}
131
+ .label=${this.localize.termOrDefault('uSync_importSingle', 'Import')}
58
132
  @click="${__classPrivateFieldGet(this, _uSyncDetailsModalElement_instances, "m", _uSyncDetailsModalElement_onImport)}"></uui-button>`;
59
133
  }
60
134
  };
135
+ _uSyncDetailsModalElement_repository = new WeakMap();
61
136
  _uSyncDetailsModalElement_instances = new WeakSet();
137
+ _uSyncDetailsModalElement_moveTo = function _uSyncDetailsModalElement_moveTo(index) {
138
+ const item = this.data?.items?.[index];
139
+ if (!item)
140
+ return;
141
+ this._index = index;
142
+ this._item = item;
143
+ this._preview = undefined;
144
+ __classPrivateFieldGet(this, _uSyncDetailsModalElement_instances, "m", _uSyncDetailsModalElement_loadPreview).call(this);
145
+ };
146
+ _uSyncDetailsModalElement_loadPreview = async function _uSyncDetailsModalElement_loadPreview() {
147
+ const item = this._item;
148
+ if (!item?.handler || !item.key) {
149
+ this._tab = 'changes';
150
+ return;
151
+ }
152
+ // only some handlers support previews, the rest return a 404
153
+ // and the modal stays as it was (just the changes list).
154
+ const { data } = await __classPrivateFieldGet(this, _uSyncDetailsModalElement_repository, "f").getPreview(item.handler, item.key);
155
+ // moving through the list quickly can return previews out of order,
156
+ // so drop anything that isn't for the item we are now showing.
157
+ if (item !== this._item)
158
+ return;
159
+ if (data?.entityType) {
160
+ this._preview = data;
161
+ }
162
+ else {
163
+ this._tab = 'changes';
164
+ }
165
+ };
166
+ _uSyncDetailsModalElement_showActions = function _uSyncDetailsModalElement_showActions() {
167
+ const showActions = this.data?.showActions;
168
+ if (typeof showActions === 'function') {
169
+ return this._item ? showActions(this._item) : false;
170
+ }
171
+ return showActions ?? false;
172
+ };
62
173
  _uSyncDetailsModalElement_onImport = async function _uSyncDetailsModalElement_onImport(e) {
63
174
  e.stopPropagation();
64
- if (!this.data?.item)
175
+ if (!this._item)
65
176
  return;
66
177
  const modalContext = await this.getContext(UMB_MODAL_MANAGER_CONTEXT);
67
178
  if (!modalContext)
68
179
  return;
69
180
  const modal = modalContext.open(this, USYNC_IMPORT_SINGLE_MODAL, {
70
- data: { action: this.data?.item },
181
+ data: { action: this._item },
71
182
  });
72
183
  const data = await modal?.onSubmit().catch(() => {
73
184
  return;
@@ -77,20 +188,39 @@ _uSyncDetailsModalElement_onImport = async function _uSyncDetailsModalElement_on
77
188
  _uSyncDetailsModalElement_onClose = function _uSyncDetailsModalElement_onClose() {
78
189
  this.modalContext?.reject();
79
190
  };
80
- uSyncDetailsModalElement.styles = css `
81
- .layout {
82
- display: flex;
83
- flex-direction: column;
84
- gap: var(--uui-size-space-4);
85
- }
86
-
87
- #header h3 {
88
- margin: 0;
89
- }
191
+ uSyncDetailsModalElement.styles = css `
192
+ .layout {
193
+ display: flex;
194
+ flex-direction: column;
195
+ gap: var(--uui-size-space-4);
196
+ }
197
+
198
+ #header h3 {
199
+ margin: 0;
200
+ }
201
+
202
+ #navigation {
203
+ display: flex;
204
+ align-items: center;
205
+ gap: var(--uui-size-space-3);
206
+ padding-left: var(--uui-size-space-4);
207
+ }
90
208
  `;
91
209
  __decorate([
92
210
  state()
93
211
  ], uSyncDetailsModalElement.prototype, "importState", void 0);
212
+ __decorate([
213
+ state()
214
+ ], uSyncDetailsModalElement.prototype, "_preview", void 0);
215
+ __decorate([
216
+ state()
217
+ ], uSyncDetailsModalElement.prototype, "_tab", void 0);
218
+ __decorate([
219
+ state()
220
+ ], uSyncDetailsModalElement.prototype, "_item", void 0);
221
+ __decorate([
222
+ state()
223
+ ], uSyncDetailsModalElement.prototype, "_index", void 0);
94
224
  uSyncDetailsModalElement = __decorate([
95
225
  customElement('usync-details-modal')
96
226
  ], 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
- showActions?: boolean;
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;