pict-section-prompteditor 1.1.2 → 1.1.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pict-section-prompteditor",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "Prompt crafting and management section for Pict: typed prompts with segments (context, request, success criteria), curated word list matrices with weights, a {~WordListEntry:Name~} template expression for weighted-random generation, batch generation with zip download, and a pluggable data provider that defaults to in-memory AppData.",
5
5
  "main": "source/Pict-Section-PromptEditor.js",
6
6
  "files": [
@@ -216,6 +216,16 @@ const _DefaultConfiguration =
216
216
  .pspe-viewer-tools { display: flex; gap: 8px; justify-content: flex-end; padding: 8px 0 2px; }
217
217
 
218
218
  .pspe-rich-host { min-height: 320px; }
219
+
220
+ /* Read mode: a header strip (type + browse actions) above the assembled
221
+ prompt rendered as one markdown document. */
222
+ .pspe-reader-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }
223
+ .pspe-reader-type { font-size: 12.5px; color: var(--theme-color-text-muted, #97a1ab); margin-right: auto;
224
+ font-family: var(--theme-typography-family-display, inherit);
225
+ text-transform: var(--theme-typography-display-transform, none);
226
+ letter-spacing: var(--theme-typography-display-tracking, normal); }
227
+ .pspe-reader-body { padding: 4px 18px; }
228
+ .pspe-reader-body h1:first-child, .pspe-reader-body h2:first-child { margin-top: 8px; }
219
229
  `,
220
230
 
221
231
  Templates:
@@ -248,6 +258,7 @@ const _DefaultConfiguration =
248
258
  {~TS:PromptEditor-EmptyNote:Record.EmptySlot~}
249
259
  </div>
250
260
  <div class="pspe-main">
261
+ {~TS:PromptEditor-PromptReader:Record.ReaderSlot~}
251
262
  {~TS:PromptEditor-PromptEditorPanel:Record.EditorSlot~}
252
263
  {~TS:PromptEditor-EmptyNote:Record.NoSelectionSlot~}
253
264
  </div>
@@ -263,6 +274,21 @@ const _DefaultConfiguration =
263
274
  <span class="pspe-rail-item-sub">{~D:Record.TypeName~}</span>
264
275
  </button>`
265
276
  },
277
+ {
278
+ Hash: 'PromptEditor-PromptReader',
279
+ Template: /*html*/`
280
+ <div class="pspe-reader">
281
+ <div class="pspe-reader-head">
282
+ <span class="pspe-reader-type">{~D:Record.TypeName~}</span>
283
+ {~TS:PromptEditor-ReaderActions:Record.ActionsSlot~}
284
+ </div>
285
+ <div class="pspe-viewer pspe-md pspe-reader-body">{~D:Record.MarkdownHtml~}</div>
286
+ </div>`
287
+ },
288
+ {
289
+ Hash: 'PromptEditor-ReaderActions',
290
+ Template: /*html*/`<button class="pspe-btn pspe-btn-sm" title="Duplicate this prompt" onclick="_Pict.views['{~D:Record.ViewHash~}'].duplicatePrompt()">Duplicate</button><button class="pspe-btn pspe-btn-sm pspe-btn-primary" onclick="_Pict.views['{~D:Record.ViewHash~}'].editActivePrompt()">Edit</button>`
291
+ },
266
292
  {
267
293
  Hash: 'PromptEditor-PromptEditorPanel',
268
294
  Template: /*html*/`
@@ -273,6 +299,7 @@ const _DefaultConfiguration =
273
299
  <select class="pspe-select" onchange="_Pict.views['{~D:Record.ViewHash~}'].setPromptType(this.value)">
274
300
  {~TS:PromptEditor-TypeOption:Record.TypeOptions~}
275
301
  </select>
302
+ {~TS:PromptEditor-ReadToggle:Record.ReadToggleSlot~}
276
303
  {~TS:PromptEditor-PromptActions:Record.ActionsSlot~}
277
304
  </div>
278
305
  <div class="pspe-type-desc">{~D:Record.TypeDescription~}</div>
@@ -301,6 +328,10 @@ const _DefaultConfiguration =
301
328
  { Hash: 'PromptEditor-PreviewRendered', Template: /*html*/`<div class="pspe-viewer pspe-md">{~D:Record.MarkdownHtml~}</div>` },
302
329
  { Hash: 'PromptEditor-PreviewRaw', Template: /*html*/`<pre class="pspe-viewer pspe-preview-raw">{~D:Record.MarkdownEscaped~}</pre>` },
303
330
  { Hash: 'PromptEditor-TypeOption', Template: /*html*/`<option value="{~D:Record.Value~}" {~D:Record.SelectedAttr~}>{~D:Record.Label~}</option>` },
331
+ {
332
+ Hash: 'PromptEditor-ReadToggle',
333
+ Template: /*html*/`<button class="pspe-btn pspe-btn-sm" title="Back to reading view" onclick="_Pict.views['{~D:Record.ViewHash~}'].readActivePrompt()">Done</button>`
334
+ },
304
335
  {
305
336
  Hash: 'PromptEditor-PromptActions',
306
337
  Template: /*html*/`<button class="pspe-btn pspe-btn-sm" title="Duplicate this prompt" onclick="_Pict.views['{~D:Record.ViewHash~}'].duplicatePrompt()">Duplicate</button><button class="pspe-btn pspe-btn-sm pspe-btn-danger" onclick="_Pict.views['{~D:Record.ViewHash~}'].deletePrompt()">Delete</button>`
@@ -496,7 +527,11 @@ class PictViewPromptEditor extends libPictView
496
527
  GenerateCount: this.options.GenerateDefaultCount,
497
528
  PreviewSegments: {},
498
529
  Preview: null,
499
- PreviewMode: 'rendered'
530
+ PreviewMode: 'rendered',
531
+ // Browsing a prompt shows it read-only (the assembled markdown, no
532
+ // segment boxes); 'edit' swaps in the segment editor. Selecting a
533
+ // prompt lands on 'read'; creating/duplicating/previewing enters 'edit'.
534
+ PromptMode: 'read'
500
535
  };
501
536
  this._state = {};
502
537
  this._richEditorViewHash = null;
@@ -568,7 +603,7 @@ class PictViewPromptEditor extends libPictView
568
603
  {
569
604
  let tmpPickerProvider = this.pict.providers['Pict-Section-Picker'];
570
605
  if (!tmpPickerProvider || typeof document === 'undefined') { return; }
571
- if (this._ui.Tab !== 'prompts' || this.options.ReadOnly) { return; }
606
+ if (this._ui.Tab !== 'prompts' || this.options.ReadOnly || this._ui.PromptMode === 'read') { return; }
572
607
  let tmpPrompt = this._activePrompt();
573
608
  if (!tmpPrompt) { return; }
574
609
  if (!this.pict.AppData.PromptEditorInsertPick) { this.pict.AppData.PromptEditorInsertPick = {}; }
@@ -866,6 +901,12 @@ class PictViewPromptEditor extends libPictView
866
901
  this._state = tmpState;
867
902
  }
868
903
 
904
+ // A prompt is browsed read-only (the assembled markdown) unless the caller
905
+ // flipped it into 'edit'. A globally ReadOnly section keeps its own preview
906
+ // path (the pReadOnly branch of _shapePromptEditor), so this only governs the
907
+ // editable library's browse-vs-edit swap.
908
+ _isPromptReadMode() { return !this.options.ReadOnly && this._ui.PromptMode !== 'edit'; }
909
+
869
910
  _shapePromptsPane(pReadOnly)
870
911
  {
871
912
  let tmpActive = this._activePrompt();
@@ -882,14 +923,36 @@ class PictViewPromptEditor extends libPictView
882
923
  OnClass: (tmpActive && tmpActive.Key === pPrompt.Key) ? 'pspe-rail-item-on' : ''
883
924
  })),
884
925
  EmptySlot: this._loaded.Prompts.length ? [] : [{ Text: 'No prompts yet.' }],
926
+ ReaderSlot: [],
885
927
  EditorSlot: [],
886
928
  NoSelectionSlot: []
887
929
  };
888
- if (tmpActive) { tmpPane.EditorSlot = [this._shapePromptEditor(tmpActive, pReadOnly)]; }
930
+ if (tmpActive && this._isPromptReadMode()) { tmpPane.ReaderSlot = [this._shapePromptReader(tmpActive)]; }
931
+ else if (tmpActive) { tmpPane.EditorSlot = [this._shapePromptEditor(tmpActive, pReadOnly)]; }
889
932
  else { tmpPane.NoSelectionSlot = [{ Text: pReadOnly ? 'Nothing to show.' : 'Create a prompt to start crafting.' }]; }
890
933
  return tmpPane;
891
934
  }
892
935
 
936
+ // The read model: the whole prompt compiled to one markdown document (the
937
+ // same source the compiler versions and generation rolls), rendered as
938
+ // content with a compact header carrying the type and browse actions.
939
+ _shapePromptReader(pPrompt)
940
+ {
941
+ let tmpType = libTypes.getPromptType(this._types, pPrompt.TypeKey);
942
+ let tmpSource = libCompiler.assembleSource(pPrompt, tmpType,
943
+ {
944
+ IncludeTitleHeading: this.options.IncludeTitleHeading,
945
+ SegmentHeadingLevel: this.options.SegmentHeadingLevel
946
+ });
947
+ return (
948
+ {
949
+ ViewHash: this.Hash,
950
+ TypeName: tmpType.Name,
951
+ ActionsSlot: this.options.ReadOnly ? [] : [{ ViewHash: this.Hash }],
952
+ MarkdownHtml: this._renderMarkdown(tmpSource)
953
+ });
954
+ }
955
+
893
956
  _shapePromptEditor(pPrompt, pReadOnly)
894
957
  {
895
958
  let tmpType = libTypes.getPromptType(this._types, pPrompt.TypeKey);
@@ -953,6 +1016,7 @@ class PictViewPromptEditor extends libPictView
953
1016
  Label: pTypeOption.Name,
954
1017
  SelectedAttr: (pTypeOption.Key === pPrompt.TypeKey) ? 'selected' : ''
955
1018
  })),
1019
+ ReadToggleSlot: pReadOnly ? [] : [{ ViewHash: this.Hash }],
956
1020
  ActionsSlot: pReadOnly ? [] : [{ ViewHash: this.Hash }],
957
1021
  OptionsSlot: pReadOnly ? [] :
958
1022
  [{
@@ -1069,6 +1133,24 @@ class PictViewPromptEditor extends libPictView
1069
1133
  {
1070
1134
  if (this._ui.ActivePromptKey !== pKey) { this._ui.Preview = null; }
1071
1135
  this._ui.ActivePromptKey = pKey;
1136
+ // Picking a prompt in the rail is browsing: land on the read view.
1137
+ this._ui.PromptMode = 'read';
1138
+ this._reshape();
1139
+ }
1140
+
1141
+ // The reader's Edit button; swap the segment editor in for the active prompt.
1142
+ editActivePrompt()
1143
+ {
1144
+ if (this.options.ReadOnly) { return; }
1145
+ this._ui.PromptMode = 'edit';
1146
+ this._reshape();
1147
+ }
1148
+
1149
+ // The editor's Done button; back to the read view, dropping any preview roll.
1150
+ readActivePrompt()
1151
+ {
1152
+ this._ui.PromptMode = 'read';
1153
+ this._ui.Preview = null;
1072
1154
  this._reshape();
1073
1155
  }
1074
1156
  selectWordList(pKey) { this._ui.ActiveWordListKey = pKey; this._reshape(); }
@@ -1082,6 +1164,8 @@ class PictViewPromptEditor extends libPictView
1082
1164
  .then((pPrompt) =>
1083
1165
  {
1084
1166
  this._ui.ActivePromptKey = pPrompt.Key;
1167
+ // A fresh prompt opens ready to write in, not in the read view.
1168
+ this._ui.PromptMode = 'edit';
1085
1169
  this._fire('onPromptSaved', pPrompt);
1086
1170
  return this.load();
1087
1171
  })
@@ -1134,6 +1218,8 @@ class PictViewPromptEditor extends libPictView
1134
1218
  .then((pCopy) =>
1135
1219
  {
1136
1220
  this._ui.ActivePromptKey = pCopy.Key;
1221
+ // A copy is made to be changed; open it in the editor.
1222
+ this._ui.PromptMode = 'edit';
1137
1223
  this._fire('onPromptSaved', pCopy);
1138
1224
  return this.load();
1139
1225
  })
@@ -1353,6 +1439,8 @@ class PictViewPromptEditor extends libPictView
1353
1439
  let tmpPrompt = this._activePrompt();
1354
1440
  if (!tmpPrompt) { return; }
1355
1441
  let tmpType = libTypes.getPromptType(this._types, tmpPrompt.TypeKey);
1442
+ // The preview roll lives under the segment editor; rolling implies editing.
1443
+ this._ui.PromptMode = 'edit';
1356
1444
  this._ui.Preview = { PromptKey: tmpPrompt.Key, Markdown: this._generateOnce(tmpPrompt, tmpType) };
1357
1445
  this._reshape();
1358
1446
  }