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.
|
|
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.
|
|
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
|
}
|