@happyvertical/smrt-content 0.31.0 → 0.31.1

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 (33) hide show
  1. package/dist/content-chat-session.d.ts.map +1 -1
  2. package/dist/content-versions.d.ts.map +1 -1
  3. package/dist/content.d.ts +35 -4
  4. package/dist/content.d.ts.map +1 -1
  5. package/dist/index.js +135 -18
  6. package/dist/index.js.map +1 -1
  7. package/dist/manifest.json +34 -2
  8. package/dist/smrt-knowledge.json +8 -4
  9. package/dist/svelte/components/ContentClaimAuditTool.svelte +2 -2
  10. package/dist/svelte/components/ContentCorrectionsTool.svelte +2 -2
  11. package/dist/svelte/components/ContentEditor.svelte +53 -2
  12. package/dist/svelte/components/ContentEditor.svelte.d.ts.map +1 -1
  13. package/dist/svelte/components/ContentGovernancePanel.svelte +35 -6
  14. package/dist/svelte/components/ContentGovernancePanel.svelte.d.ts.map +1 -1
  15. package/dist/svelte/components/ContentList.svelte +32 -8
  16. package/dist/svelte/components/ContentList.svelte.d.ts.map +1 -1
  17. package/dist/svelte/components/ContentVersionsTool.svelte +34 -6
  18. package/dist/svelte/components/ContentVersionsTool.svelte.d.ts.map +1 -1
  19. package/dist/svelte/i18n.contribution.d.ts +3 -0
  20. package/dist/svelte/i18n.contribution.d.ts.map +1 -1
  21. package/dist/svelte/i18n.contribution.js +3 -0
  22. package/dist/svelte/i18n.editor.d.ts +3 -0
  23. package/dist/svelte/i18n.editor.d.ts.map +1 -1
  24. package/dist/svelte/i18n.editor.js +3 -0
  25. package/dist/svelte/i18n.governance.d.ts +4 -0
  26. package/dist/svelte/i18n.governance.d.ts.map +1 -1
  27. package/dist/svelte/i18n.governance.js +4 -0
  28. package/dist/svelte/i18n.tools.d.ts +4 -0
  29. package/dist/svelte/i18n.tools.d.ts.map +1 -1
  30. package/dist/svelte/i18n.tools.js +4 -0
  31. package/dist/thumbnail-generator.d.ts.map +1 -1
  32. package/dist/utils.d.ts.map +1 -1
  33. package/package.json +14 -14
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "version": "1.0.0",
3
- "timestamp": 1782183834014,
3
+ "timestamp": 1782192627068,
4
4
  "packageName": "@happyvertical/smrt-content",
5
- "packageVersion": "0.31.0",
5
+ "packageVersion": "0.31.1",
6
6
  "objects": {
7
7
  "@happyvertical/smrt-content:ContentAsset": {
8
8
  "name": "contentasset",
@@ -5696,6 +5696,14 @@
5696
5696
  "isStatic": false,
5697
5697
  "isPublic": true
5698
5698
  },
5699
+ "getReferenceEdges": {
5700
+ "name": "getReferenceEdges",
5701
+ "async": true,
5702
+ "parameters": [],
5703
+ "returnType": "Promise<Array<object>>",
5704
+ "isStatic": false,
5705
+ "isPublic": true
5706
+ },
5699
5707
  "getReferenceDrift": {
5700
5708
  "name": "getReferenceDrift",
5701
5709
  "async": true,
@@ -7270,6 +7278,14 @@
7270
7278
  "isStatic": false,
7271
7279
  "isPublic": true
7272
7280
  },
7281
+ "getReferenceEdges": {
7282
+ "name": "getReferenceEdges",
7283
+ "async": true,
7284
+ "parameters": [],
7285
+ "returnType": "Promise<Array<object>>",
7286
+ "isStatic": false,
7287
+ "isPublic": true
7288
+ },
7273
7289
  "getReferenceDrift": {
7274
7290
  "name": "getReferenceDrift",
7275
7291
  "async": true,
@@ -8873,6 +8889,14 @@
8873
8889
  "isStatic": false,
8874
8890
  "isPublic": true
8875
8891
  },
8892
+ "getReferenceEdges": {
8893
+ "name": "getReferenceEdges",
8894
+ "async": true,
8895
+ "parameters": [],
8896
+ "returnType": "Promise<Array<object>>",
8897
+ "isStatic": false,
8898
+ "isPublic": true
8899
+ },
8876
8900
  "getReferenceDrift": {
8877
8901
  "name": "getReferenceDrift",
8878
8902
  "async": true,
@@ -10928,6 +10952,14 @@
10928
10952
  "isStatic": false,
10929
10953
  "isPublic": true
10930
10954
  },
10955
+ "getReferenceEdges": {
10956
+ "name": "getReferenceEdges",
10957
+ "async": true,
10958
+ "parameters": [],
10959
+ "returnType": "Promise<Array<object>>",
10960
+ "isStatic": false,
10961
+ "isPublic": true
10962
+ },
10931
10963
  "getReferenceDrift": {
10932
10964
  "name": "getReferenceDrift",
10933
10965
  "async": true,
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "generatedAt": "2026-06-23T03:03:55.008Z",
3
+ "generatedAt": "2026-06-23T05:30:28.173Z",
4
4
  "packageName": "@happyvertical/smrt-content",
5
- "packageVersion": "0.31.0",
5
+ "packageVersion": "0.31.1",
6
6
  "sourceManifestPath": "dist/manifest.json",
7
7
  "agentDocPath": "AGENTS.md",
8
8
  "sourceHashes": {
9
- "manifest": "ef50eae4b2f603f92afca445c4531c2165d54a708e4e5e0a0ead3cd61a44d8be",
10
- "packageJson": "3c5670cc1079f85823340391d9b38de42463e8259fff2afa4d61bbafac4c072a",
9
+ "manifest": "4f9b5ada2f79bd8fc24017a693e4c92c3e9509b35f1f35d5d0879d2f6d4f9a1b",
10
+ "packageJson": "3dc2ff0095be1eadefb32ce33181fbb287410db83e9a07575c89b376f1cff8aa",
11
11
  "agents": "d3e1fdba8cf8c8f393e682616c56fefcc789c44018407bbdf7332d5f06cfbb5c"
12
12
  },
13
13
  "exports": [
@@ -3132,6 +3132,7 @@
3132
3132
  "getPublishedTransparency",
3133
3133
  "getPublishedTransparencyAction",
3134
3134
  "getReferenceDrift",
3135
+ "getReferenceEdges",
3135
3136
  "getReferences",
3136
3137
  "getRelated",
3137
3138
  "getReviewRequirements",
@@ -3403,6 +3404,7 @@
3403
3404
  "getPublishedTransparency",
3404
3405
  "getPublishedTransparencyAction",
3405
3406
  "getReferenceDrift",
3407
+ "getReferenceEdges",
3406
3408
  "getReferences",
3407
3409
  "getRelated",
3408
3410
  "getReviewRequirements",
@@ -3724,6 +3726,7 @@
3724
3726
  "getPublishedTransparency",
3725
3727
  "getPublishedTransparencyAction",
3726
3728
  "getReferenceDrift",
3729
+ "getReferenceEdges",
3727
3730
  "getReferences",
3728
3731
  "getRelated",
3729
3732
  "getReviewRequirements",
@@ -4213,6 +4216,7 @@
4213
4216
  "getPublishedTransparency",
4214
4217
  "getPublishedTransparencyAction",
4215
4218
  "getReferenceDrift",
4219
+ "getReferenceEdges",
4216
4220
  "getReferences",
4217
4221
  "getRelated",
4218
4222
  "getReviewRequirements",
@@ -179,11 +179,11 @@ async function recheckFactClaims(claimIds: string[]) {
179
179
 
180
180
  <div class="governance-tool">
181
181
  {#if error}
182
- <p class="tool-error">{error}</p>
182
+ <p class="tool-error" role="alert" aria-live="assertive">{error}</p>
183
183
  {/if}
184
184
 
185
185
  {#if notice}
186
- <p class="tool-notice">{notice}</p>
186
+ <p class="tool-notice" role="status" aria-live="polite">{notice}</p>
187
187
  {/if}
188
188
 
189
189
  {#if !savedContentId}
@@ -160,11 +160,11 @@ async function issueCorrection() {
160
160
 
161
161
  <div class="governance-tool">
162
162
  {#if error}
163
- <p class="tool-error">{error}</p>
163
+ <p class="tool-error" role="alert" aria-live="assertive">{error}</p>
164
164
  {/if}
165
165
 
166
166
  {#if notice}
167
- <p class="tool-notice">{notice}</p>
167
+ <p class="tool-notice" role="status" aria-live="polite">{notice}</p>
168
168
  {/if}
169
169
 
170
170
  {#if !savedContentId}
@@ -349,6 +349,10 @@ let selectedEvidenceIds = $state<string[]>([]);
349
349
  let evidenceBusy = $state<string | null>(null);
350
350
  let evidenceError = $state<string | null>(null);
351
351
  let evidenceNotice = $state<string | null>(null);
352
+ // Surfaces reference-drop / image-attach failures that were previously
353
+ // swallowed by empty catch blocks (#1387 #6), reusing the evidence-message
354
+ // error styling for a consistent in-editor notice.
355
+ let editorError = $state<string | null>(null);
352
356
  let bulkEvidenceStatus = $state<FactEvidenceStatus>('supports');
353
357
  const evidenceStatuses: FactEvidenceStatus[] = [
354
358
  'supports',
@@ -706,8 +710,11 @@ async function handleRefDrop(e: DragEvent) {
706
710
  formData.referenceIds = [...formData.referenceIds, newId];
707
711
  }
708
712
  } else {
713
+ editorError = t(M['content.content_editor.reference_drop_failed']);
709
714
  }
710
- } catch (err) {}
715
+ } catch (err) {
716
+ editorError = t(M['content.content_editor.reference_drop_failed']);
717
+ }
711
718
  }
712
719
 
713
720
  // Handle dropped URL or plain text (add as reference ID)
@@ -830,6 +837,7 @@ function handleImageSelect(selected: ImageLike | File | string) {
830
837
  try {
831
838
  await resolveSelectedImage(selected);
832
839
  } catch (err) {
840
+ editorError = t(M['content.content_editor.image_select_failed']);
833
841
  } finally {
834
842
  showImageUploader = false;
835
843
  }
@@ -870,6 +878,7 @@ async function handleInlineImageSelect(selected: ImageLike | File | string) {
870
878
  selectedBodyImageIndex = Math.max(bodyImages.length, 0);
871
879
  }
872
880
  } catch (err) {
881
+ editorError = t(M['content.content_editor.image_select_failed']);
873
882
  } finally {
874
883
  showInlineImageUploader = false;
875
884
  }
@@ -879,6 +888,7 @@ async function resolveBodyDropImage(selected: ImageLike | File | string) {
879
888
  try {
880
889
  return await resolveSelectedImage(selected);
881
890
  } catch (err) {
891
+ editorError = t(M['content.content_editor.image_select_failed']);
882
892
  return null;
883
893
  }
884
894
  }
@@ -916,6 +926,21 @@ function removeAsset(id: string) {
916
926
  class="editor-main-col"
917
927
  onsubmit={handleSubmit}
918
928
  >
929
+ {#if editorError}
930
+ <div class="editor-message editor-message--error" role="alert" aria-live="assertive">
931
+ <span>{editorError}</span>
932
+ <button
933
+ type="button"
934
+ class="editor-message__dismiss"
935
+ onclick={() => {
936
+ editorError = null;
937
+ }}
938
+ aria-label={t(M['content.content_editor.dismiss_message'])}
939
+ >
940
+ ×
941
+ </button>
942
+ </div>
943
+ {/if}
919
944
  <div class="editor-toolbar">
920
945
  <div class="editor-toolbar-left">
921
946
  <div class="mui-field">
@@ -1755,6 +1780,32 @@ function removeAsset(id: string) {
1755
1780
  color: var(--smrt-color-primary);
1756
1781
  }
1757
1782
 
1783
+ .editor-message {
1784
+ display: flex;
1785
+ align-items: center;
1786
+ justify-content: space-between;
1787
+ gap: var(--smrt-spacing-2, 0.5rem);
1788
+ margin: 0 0 var(--smrt-spacing-3, 0.75rem);
1789
+ padding: var(--smrt-spacing-2, 0.5rem) var(--smrt-spacing-3, 0.75rem);
1790
+ border-radius: var(--smrt-radius-md, 0.5rem);
1791
+ font-size: var(--smrt-typography-body-medium-size, 0.8125rem);
1792
+ }
1793
+
1794
+ .editor-message--error {
1795
+ color: var(--smrt-color-on-error-container);
1796
+ background: color-mix(in srgb, var(--smrt-color-error) 12%, transparent);
1797
+ }
1798
+
1799
+ .editor-message__dismiss {
1800
+ border: none;
1801
+ background: transparent;
1802
+ color: inherit;
1803
+ cursor: pointer;
1804
+ font-size: var(--smrt-typography-title-medium-size, 1.1rem);
1805
+ line-height: 1;
1806
+ padding: 0 0.25rem;
1807
+ }
1808
+
1758
1809
  .reference-detail-header a,
1759
1810
  .reference-detail-header span,
1760
1811
  .resource-claim-body,
@@ -2116,7 +2167,7 @@ function removeAsset(id: string) {
2116
2167
  top: 0.25rem;
2117
2168
  left: 0.25rem;
2118
2169
  background: var(--smrt-color-primary, #3b82f6);
2119
- color: white;
2170
+ color: var(--smrt-color-on-primary, #ffffff);
2120
2171
  font-size: var(--smrt-typography-label-small-size, 0.65rem);
2121
2172
  font-weight: var(--smrt-typography-weight-semibold, 600);
2122
2173
  padding: 0.15rem 0.4rem;
@@ -1 +1 @@
1
- {"version":3,"file":"ContentEditor.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ContentEditor.svelte.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAEV,mCAAmC,EACnC,0CAA0C,EAE3C,MAAM,gCAAgC,CAAC;AAKxC,OAAO,KAAK,EAEV,kBAAkB,EAEnB,MAAM,wBAAwB,CAAC;AAiBhC,MAAM,WAAW,KAAK;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACtC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uBAAuB,CAAC,EAAE,0CAA0C,CAAC;IACrE,wBAAwB,CAAC,EAAE,mCAAmC,CAAC;IAC/D,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,CAAC;IAC/D,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAmtCD,QAAA,MAAM,aAAa;;MAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"ContentEditor.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ContentEditor.svelte.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAEV,mCAAmC,EACnC,0CAA0C,EAE3C,MAAM,gCAAgC,CAAC;AAKxC,OAAO,KAAK,EAEV,kBAAkB,EAEnB,MAAM,wBAAwB,CAAC;AAiBhC,MAAM,WAAW,KAAK;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACtC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uBAAuB,CAAC,EAAE,0CAA0C,CAAC;IACrE,wBAAwB,CAAC,EAAE,mCAAmC,CAAC;IAC/D,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,CAAC;IAC/D,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAuuCD,QAAA,MAAM,aAAa;;MAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { ConfirmDialog } from '@happyvertical/smrt-ui/feedback';
2
3
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
3
4
  import {
4
5
  type ContentCorrectionData,
@@ -111,6 +112,7 @@ let selectedClaimIds = $state<string[]>([]);
111
112
  let catalogError = $state<string | null>(null);
112
113
  let workflowError = $state<string | null>(null);
113
114
  let workflowNotice = $state<string | null>(null);
115
+ let pendingRestoreVersion = $state<number | null>(null);
114
116
  let catalogLoaded = $state(false);
115
117
  let loadedContentId = $state<string | null>(null);
116
118
  let resolvedDraftGovernanceKey = $state<string | null>(null);
@@ -909,12 +911,27 @@ async function createSnapshot() {
909
911
  }
910
912
  }
911
913
 
912
- async function restoreVersion(versionNumber: number) {
914
+ function requestRestoreVersion(versionNumber: number) {
913
915
  if (!savedContentId) {
914
916
  return;
915
917
  }
918
+ pendingRestoreVersion = versionNumber;
919
+ }
920
+
921
+ function cancelRestoreVersion() {
922
+ pendingRestoreVersion = null;
923
+ }
924
+
925
+ function confirmRestoreVersion() {
926
+ const versionNumber = pendingRestoreVersion;
927
+ pendingRestoreVersion = null;
928
+ if (versionNumber !== null) {
929
+ void restoreVersion(versionNumber);
930
+ }
931
+ }
916
932
 
917
- if (!confirm(`Restore content version ${versionNumber}?`)) {
933
+ async function restoreVersion(versionNumber: number) {
934
+ if (!savedContentId) {
918
935
  return;
919
936
  }
920
937
 
@@ -1242,7 +1259,7 @@ function getVersionProvenanceCopy(version: ContentVersionData) {
1242
1259
  </div>
1243
1260
 
1244
1261
  {#if catalogError}
1245
- <p class="workflow-error">{catalogError}</p>
1262
+ <p class="workflow-error" role="alert" aria-live="assertive">{catalogError}</p>
1246
1263
  {/if}
1247
1264
 
1248
1265
  <div class="fact-catalog">
@@ -1322,11 +1339,11 @@ function getVersionProvenanceCopy(version: ContentVersionData) {
1322
1339
  <div class="editor-drawer-content">
1323
1340
 
1324
1341
  {#if workflowError}
1325
- <p class="workflow-error">{workflowError}</p>
1342
+ <p class="workflow-error" role="alert" aria-live="assertive">{workflowError}</p>
1326
1343
  {/if}
1327
1344
 
1328
1345
  {#if workflowNotice}
1329
- <p class="workflow-notice">{workflowNotice}</p>
1346
+ <p class="workflow-notice" role="status" aria-live="polite">{workflowNotice}</p>
1330
1347
  {/if}
1331
1348
 
1332
1349
  {#if !savedContentId}
@@ -1757,7 +1774,7 @@ function getVersionProvenanceCopy(version: ContentVersionData) {
1757
1774
  version.version !== null &&
1758
1775
  version.version !== undefined
1759
1776
  ) {
1760
- void restoreVersion(version.version);
1777
+ requestRestoreVersion(version.version);
1761
1778
  }
1762
1779
  }}
1763
1780
  >
@@ -1773,6 +1790,18 @@ function getVersionProvenanceCopy(version: ContentVersionData) {
1773
1790
  {/if}
1774
1791
  </div>
1775
1792
 
1793
+ <ConfirmDialog
1794
+ open={pendingRestoreVersion !== null}
1795
+ title={t(M['content.governance_panel.restore_confirm_title'])}
1796
+ message={t(M['content.governance_panel.restore_confirm_message'], {
1797
+ version: pendingRestoreVersion ?? '',
1798
+ })}
1799
+ confirmLabel={t(M['content.governance_panel.restore_confirm_action'])}
1800
+ cancelLabel={t(M['content.governance_panel.restore_confirm_cancel'])}
1801
+ onconfirm={confirmRestoreVersion}
1802
+ oncancel={cancelRestoreVersion}
1803
+ />
1804
+
1776
1805
  <style>
1777
1806
  .editor-drawer {
1778
1807
  margin: 0 0 2rem 0;
@@ -1 +1 @@
1
- {"version":3,"file":"ContentGovernancePanel.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ContentGovernancePanel.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,EAIL,KAAK,0BAA0B,EAQ/B,KAAK,kBAAkB,EACvB,KAAK,QAAQ,EAEd,MAAM,wBAAwB,CAAC;AAMhC,MAAM,MAAM,6BAA6B,GACrC,WAAW,GACX,OAAO,GACP,SAAS,GACT,cAAc,GACd,aAAa,GACb,UAAU,CAAC;AASf,MAAM,WAAW,KAAK;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;IAC/D,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,0BAA0B,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7E,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,CAAC;IAC/D,cAAc,CAAC,EAAE,6BAA6B,EAAE,CAAC;CAClD;AA2mDD,QAAA,MAAM,sBAAsB;gCAx3Bc,MAAM;MAw3BoB,CAAC;AACrE,KAAK,sBAAsB,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACxE,eAAe,sBAAsB,CAAC"}
1
+ {"version":3,"file":"ContentGovernancePanel.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ContentGovernancePanel.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,EAIL,KAAK,0BAA0B,EAQ/B,KAAK,kBAAkB,EACvB,KAAK,QAAQ,EAEd,MAAM,wBAAwB,CAAC;AAMhC,MAAM,MAAM,6BAA6B,GACrC,WAAW,GACX,OAAO,GACP,SAAS,GACT,cAAc,GACd,aAAa,GACb,UAAU,CAAC;AASf,MAAM,WAAW,KAAK;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,aAAa,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;IAC/D,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,0BAA0B,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7E,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,CAAC;IAC/D,cAAc,CAAC,EAAE,6BAA6B,EAAE,CAAC;CAClD;AAgoDD,QAAA,MAAM,sBAAsB;gCA34Bc,MAAM;MA24BoB,CAAC;AACrE,KAAK,sBAAsB,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACxE,eAAe,sBAAsB,CAAC"}
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { ConfirmDialog } from '@happyvertical/smrt-ui/feedback';
2
3
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
3
4
  import type { Snippet } from 'svelte';
4
5
  import { untrack } from 'svelte';
@@ -127,13 +128,23 @@ function getStateBadge(value: unknown) {
127
128
  }
128
129
  }
129
130
 
131
+ let pendingDelete = $state<any | null>(null);
132
+
130
133
  function handleDeleteContent(content: any) {
131
- if (
132
- confirm(`Are you sure you want to delete "${getDisplayTitle(content)}"?`)
133
- ) {
134
- onDelete(content);
134
+ pendingDelete = content;
135
+ }
136
+
137
+ function confirmDelete() {
138
+ const target = pendingDelete;
139
+ pendingDelete = null;
140
+ if (target) {
141
+ onDelete(target);
135
142
  }
136
143
  }
144
+
145
+ function cancelDelete() {
146
+ pendingDelete = null;
147
+ }
137
148
  </script>
138
149
 
139
150
  <div class="content-list-wrapper">
@@ -248,10 +259,10 @@ function handleDeleteContent(content: any) {
248
259
  <td><span class="badge state-{getStateBadge(content.state)}">{content.state}</span></td>
249
260
  <td class="actions-cell">
250
261
  {#if getViewHref?.(content)}
251
- <a class="icon-btn" href={getViewHref(content) || '#'} title={t(M['content.content_list.view_published_article'])}>🔎</a>
262
+ <a class="icon-btn" href={getViewHref(content) || '#'} title={t(M['content.content_list.view_published_article'])} aria-label={t(M['content.content_list.view_published_article'])}>🔎</a>
252
263
  {/if}
253
- <button class="icon-btn" type="button" onclick={() => onEdit(content)} title={t(M['content.content_list.edit'])}>✏️</button>
254
- <button class="icon-btn delete-icon" type="button" onclick={() => handleDeleteContent(content)} title={t(M['content.content_list.delete'])}>🗑️</button>
264
+ <button class="icon-btn" type="button" onclick={() => onEdit(content)} title={t(M['content.content_list.edit'])} aria-label={t(M['content.content_list.edit'])}>✏️</button>
265
+ <button class="icon-btn delete-icon" type="button" onclick={() => handleDeleteContent(content)} title={t(M['content.content_list.delete'])} aria-label={t(M['content.content_list.delete'])}>🗑️</button>
255
266
  </td>
256
267
  </tr>
257
268
  {/each}
@@ -371,9 +382,22 @@ function handleDeleteContent(content: any) {
371
382
  {/each}
372
383
  </div>
373
384
  {/if}
374
-
385
+
375
386
  </div>
376
387
 
388
+ <ConfirmDialog
389
+ open={pendingDelete !== null}
390
+ title={t(M['content.content_list.delete_confirm_title'])}
391
+ message={t(M['content.content_list.delete_confirm_message'], {
392
+ title: pendingDelete ? getDisplayTitle(pendingDelete) : '',
393
+ })}
394
+ confirmLabel={t(M['content.content_list.delete'])}
395
+ cancelLabel={t(M['content.content_list.cancel'])}
396
+ destructive
397
+ onconfirm={confirmDelete}
398
+ oncancel={cancelDelete}
399
+ />
400
+
377
401
  <style>
378
402
  .content-list-wrapper {
379
403
  display: flex;
@@ -1 +1 @@
1
- {"version":3,"file":"ContentList.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ContentList.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAKrC,KAAK,gBAAgB,GAAG;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,GAAG,EAAE,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAClD,MAAM,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,QAAQ,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;IACjC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,MAAM,GAAG,IAAI,CAAC;CAC/C,CAAC;AA6VF,QAAA,MAAM,WAAW,sDAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"ContentList.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ContentList.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAKrC,KAAK,gBAAgB,GAAG;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,GAAG,EAAE,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAClD,MAAM,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,QAAQ,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;IACjC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,MAAM,GAAG,IAAI,CAAC;CAC/C,CAAC;AA4WF,QAAA,MAAM,WAAW,sDAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { ConfirmDialog } from '@happyvertical/smrt-ui/feedback';
2
3
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
3
4
  import type { ContentVersionData } from '../../mock-smrt-client';
4
5
  import { createClient } from '../../mock-smrt-client';
@@ -119,12 +120,27 @@ async function createSnapshot() {
119
120
  }
120
121
  }
121
122
 
122
- async function restoreVersion(versionNumber: number) {
123
+ let pendingRestoreVersion = $state<number | null>(null);
124
+
125
+ function requestRestoreVersion(versionNumber: number) {
123
126
  if (!savedContentId) return;
127
+ pendingRestoreVersion = versionNumber;
128
+ }
124
129
 
125
- if (!confirm(`Restore content version ${versionNumber}?`)) {
126
- return;
130
+ function cancelRestoreVersion() {
131
+ pendingRestoreVersion = null;
132
+ }
133
+
134
+ function confirmRestoreVersion() {
135
+ const versionNumber = pendingRestoreVersion;
136
+ pendingRestoreVersion = null;
137
+ if (versionNumber !== null) {
138
+ void restoreVersion(versionNumber);
127
139
  }
140
+ }
141
+
142
+ async function restoreVersion(versionNumber: number) {
143
+ if (!savedContentId) return;
128
144
 
129
145
  const contentIdToRestore = savedContentId;
130
146
  busy = true;
@@ -160,11 +176,11 @@ async function restoreVersion(versionNumber: number) {
160
176
  </div>
161
177
 
162
178
  {#if error}
163
- <p class="tool-error">{error}</p>
179
+ <p class="tool-error" role="alert" aria-live="assertive">{error}</p>
164
180
  {/if}
165
181
 
166
182
  {#if notice}
167
- <p class="tool-notice">{notice}</p>
183
+ <p class="tool-notice" role="status" aria-live="polite">{notice}</p>
168
184
  {/if}
169
185
 
170
186
  {#if !savedContentId}
@@ -191,7 +207,7 @@ async function restoreVersion(versionNumber: number) {
191
207
  disabled={busy || version.version === null || version.version === undefined}
192
208
  onclick={() => {
193
209
  if (version.version !== null && version.version !== undefined) {
194
- void restoreVersion(version.version);
210
+ requestRestoreVersion(version.version);
195
211
  }
196
212
  }}
197
213
  >
@@ -204,6 +220,18 @@ async function restoreVersion(versionNumber: number) {
204
220
  {/if}
205
221
  </div>
206
222
 
223
+ <ConfirmDialog
224
+ open={pendingRestoreVersion !== null}
225
+ title={t(M['content.versions_tool.restore_confirm_title'])}
226
+ message={t(M['content.versions_tool.restore_confirm_message'], {
227
+ version: pendingRestoreVersion ?? '',
228
+ })}
229
+ confirmLabel={t(M['content.versions_tool.restore_confirm_action'])}
230
+ cancelLabel={t(M['content.versions_tool.restore_confirm_cancel'])}
231
+ onconfirm={confirmRestoreVersion}
232
+ oncancel={cancelRestoreVersion}
233
+ />
234
+
207
235
  <style>
208
236
  .governance-tool,
209
237
  .tool-list,
@@ -1 +1 @@
1
- {"version":3,"file":"ContentVersionsTool.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ContentVersionsTool.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAMjE,MAAM,WAAW,KAAK;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,EAAE,KAAK,IAAI,CAAC;CAC7D;AAoMD,QAAA,MAAM,mBAAmB,2CAAwC,CAAC;AAClE,KAAK,mBAAmB,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAClE,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"ContentVersionsTool.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ContentVersionsTool.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAMjE,MAAM,WAAW,KAAK;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,EAAE,KAAK,IAAI,CAAC;CAC7D;AAwND,QAAA,MAAM,mBAAmB,2CAAwC,CAAC;AAClE,KAAK,mBAAmB,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAClE,eAAe,mBAAmB,CAAC"}
@@ -50,6 +50,9 @@ export declare const M: {
50
50
  readonly 'content.content_list.view_published_article': "content.content_list.view_published_article";
51
51
  readonly 'content.content_list.edit': "content.content_list.edit";
52
52
  readonly 'content.content_list.delete': "content.content_list.delete";
53
+ readonly 'content.content_list.delete_confirm_title': "content.content_list.delete_confirm_title";
54
+ readonly 'content.content_list.delete_confirm_message': "content.content_list.delete_confirm_message";
55
+ readonly 'content.content_list.cancel': "content.content_list.cancel";
53
56
  readonly 'content.content_list.source_material': "content.content_list.source_material";
54
57
  readonly 'content.content_list.view_article': "content.content_list.view_article";
55
58
  readonly 'content.content_list.view_article_button': "content.content_list.view_article_button";
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.contribution.d.ts","sourceRoot":"","sources":["../../src/svelte/i18n.contribution.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkFZ,CAAC"}
1
+ {"version":3,"file":"i18n.contribution.d.ts","sourceRoot":"","sources":["../../src/svelte/i18n.contribution.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsFZ,CAAC"}
@@ -58,6 +58,9 @@ export const M = defineMessages({
58
58
  'content.content_list.view_published_article': 'View published article',
59
59
  'content.content_list.edit': 'Edit',
60
60
  'content.content_list.delete': 'Delete',
61
+ 'content.content_list.delete_confirm_title': 'Delete content?',
62
+ 'content.content_list.delete_confirm_message': 'Are you sure you want to delete "{title}"? This cannot be undone.',
63
+ 'content.content_list.cancel': 'Cancel',
61
64
  'content.content_list.source_material': 'Source material',
62
65
  'content.content_list.view_article': 'View article',
63
66
  'content.content_list.view_article_button': 'View Article',
@@ -53,6 +53,9 @@ export declare const M: {
53
53
  readonly 'content.content_editor.reference_id_or_url_placeholder': "content.content_editor.reference_id_or_url_placeholder";
54
54
  readonly 'content.content_editor.file_key': "content.content_editor.file_key";
55
55
  readonly 'content.content_editor.agent_chat_unavailable': "content.content_editor.agent_chat_unavailable";
56
+ readonly 'content.content_editor.reference_drop_failed': "content.content_editor.reference_drop_failed";
57
+ readonly 'content.content_editor.image_select_failed': "content.content_editor.image_select_failed";
58
+ readonly 'content.content_editor.dismiss_message': "content.content_editor.dismiss_message";
56
59
  readonly 'content.content_image_browser.no_images_attached': "content.content_image_browser.no_images_attached";
57
60
  readonly 'content.content_image_chooser.body_images': "content.content_image_chooser.body_images";
58
61
  readonly 'content.content_image_chooser.previous_body_image': "content.content_image_chooser.previous_body_image";
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.editor.d.ts","sourceRoot":"","sources":["../../src/svelte/i18n.editor.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6FZ,CAAC"}
1
+ {"version":3,"file":"i18n.editor.d.ts","sourceRoot":"","sources":["../../src/svelte/i18n.editor.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkGZ,CAAC"}
@@ -64,6 +64,9 @@ export const M = defineMessages({
64
64
  'content.content_editor.reference_id_or_url_placeholder': 'Reference ID or URL',
65
65
  'content.content_editor.file_key': 'File Key:',
66
66
  'content.content_editor.agent_chat_unavailable': 'Agent chat unavailable',
67
+ 'content.content_editor.reference_drop_failed': 'Could not add the dropped file as a reference. Please try again.',
68
+ 'content.content_editor.image_select_failed': 'Could not add the selected image. Please try again.',
69
+ 'content.content_editor.dismiss_message': 'Dismiss',
67
70
  // ContentImageBrowser
68
71
  'content.content_image_browser.no_images_attached': 'No images attached.',
69
72
  // ContentImageChooser
@@ -59,6 +59,10 @@ export declare const M: {
59
59
  readonly 'content.governance_panel.published_history': "content.governance_panel.published_history";
60
60
  readonly 'content.governance_panel.no_corrections_issued': "content.governance_panel.no_corrections_issued";
61
61
  readonly 'content.governance_panel.no_versions_saved': "content.governance_panel.no_versions_saved";
62
+ readonly 'content.governance_panel.restore_confirm_title': "content.governance_panel.restore_confirm_title";
63
+ readonly 'content.governance_panel.restore_confirm_message': "content.governance_panel.restore_confirm_message";
64
+ readonly 'content.governance_panel.restore_confirm_action': "content.governance_panel.restore_confirm_action";
65
+ readonly 'content.governance_panel.restore_confirm_cancel': "content.governance_panel.restore_confirm_cancel";
62
66
  readonly 'content.governance_panel.what_was_wrong': "content.governance_panel.what_was_wrong";
63
67
  readonly 'content.governance_panel.provide_corrected_wording': "content.governance_panel.provide_corrected_wording";
64
68
  readonly 'content.governance_panel.optional_public_correction_note': "content.governance_panel.optional_public_correction_note";
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.governance.d.ts","sourceRoot":"","sources":["../../src/svelte/i18n.governance.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyFZ,CAAC"}
1
+ {"version":3,"file":"i18n.governance.d.ts","sourceRoot":"","sources":["../../src/svelte/i18n.governance.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8FZ,CAAC"}
@@ -60,6 +60,10 @@ export const M = defineMessages({
60
60
  'content.governance_panel.published_history': 'Published history',
61
61
  'content.governance_panel.no_corrections_issued': 'No corrections issued.',
62
62
  'content.governance_panel.no_versions_saved': 'No versions saved yet.',
63
+ 'content.governance_panel.restore_confirm_title': 'Restore this version?',
64
+ 'content.governance_panel.restore_confirm_message': 'Restore content to version {version}? Current unsaved content will be overwritten.',
65
+ 'content.governance_panel.restore_confirm_action': 'Restore',
66
+ 'content.governance_panel.restore_confirm_cancel': 'Cancel',
63
67
  'content.governance_panel.what_was_wrong': 'What was wrong?',
64
68
  'content.governance_panel.provide_corrected_wording': 'Provide the corrected claim or wording',
65
69
  'content.governance_panel.optional_public_correction_note': 'Optional public-facing correction note',
@@ -77,5 +77,9 @@ export declare const M: {
77
77
  readonly 'content.transparency_tool.no_published_snapshot': "content.transparency_tool.no_published_snapshot";
78
78
  readonly 'content.versions_tool.save_to_manage_versions': "content.versions_tool.save_to_manage_versions";
79
79
  readonly 'content.versions_tool.no_versions_saved': "content.versions_tool.no_versions_saved";
80
+ readonly 'content.versions_tool.restore_confirm_title': "content.versions_tool.restore_confirm_title";
81
+ readonly 'content.versions_tool.restore_confirm_message': "content.versions_tool.restore_confirm_message";
82
+ readonly 'content.versions_tool.restore_confirm_action': "content.versions_tool.restore_confirm_action";
83
+ readonly 'content.versions_tool.restore_confirm_cancel': "content.versions_tool.restore_confirm_cancel";
80
84
  };
81
85
  //# sourceMappingURL=i18n.tools.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.tools.d.ts","sourceRoot":"","sources":["../../src/svelte/i18n.tools.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmIZ,CAAC"}
1
+ {"version":3,"file":"i18n.tools.d.ts","sourceRoot":"","sources":["../../src/svelte/i18n.tools.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwIZ,CAAC"}
@@ -87,4 +87,8 @@ export const M = defineMessages({
87
87
  // ContentVersionsTool
88
88
  'content.versions_tool.save_to_manage_versions': 'Save this content to manage versions.',
89
89
  'content.versions_tool.no_versions_saved': 'No versions saved yet.',
90
+ 'content.versions_tool.restore_confirm_title': 'Restore this version?',
91
+ 'content.versions_tool.restore_confirm_message': 'Restore content to version {version}? Current unsaved content will be overwritten.',
92
+ 'content.versions_tool.restore_confirm_action': 'Restore',
93
+ 'content.versions_tool.restore_confirm_cancel': 'Cancel',
90
94
  });