pict-section-prompteditor 1.1.1 → 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 = {}; }
|
|
@@ -732,6 +767,17 @@ class PictViewPromptEditor extends libPictView
|
|
|
732
767
|
this.render();
|
|
733
768
|
}
|
|
734
769
|
|
|
770
|
+
/* Replace the selectable prompt-type set (the cascade behind the type dropdown) and repaint. The
|
|
771
|
+
type list is cached as this._types at construction; a host that updates its shape library
|
|
772
|
+
mid-session calls this so the dropdown reflects the new set without a full page reload. */
|
|
773
|
+
setPromptTypes(pTypes)
|
|
774
|
+
{
|
|
775
|
+
this.options.PromptTypes = pTypes || null;
|
|
776
|
+
this._types = libTypes.resolvePromptTypes(this.options.PromptTypes);
|
|
777
|
+
this._shape();
|
|
778
|
+
this.render();
|
|
779
|
+
}
|
|
780
|
+
|
|
735
781
|
setDataProvider(pProvider)
|
|
736
782
|
{
|
|
737
783
|
this._provider = pProvider || null;
|
|
@@ -855,6 +901,12 @@ class PictViewPromptEditor extends libPictView
|
|
|
855
901
|
this._state = tmpState;
|
|
856
902
|
}
|
|
857
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
|
+
|
|
858
910
|
_shapePromptsPane(pReadOnly)
|
|
859
911
|
{
|
|
860
912
|
let tmpActive = this._activePrompt();
|
|
@@ -871,14 +923,36 @@ class PictViewPromptEditor extends libPictView
|
|
|
871
923
|
OnClass: (tmpActive && tmpActive.Key === pPrompt.Key) ? 'pspe-rail-item-on' : ''
|
|
872
924
|
})),
|
|
873
925
|
EmptySlot: this._loaded.Prompts.length ? [] : [{ Text: 'No prompts yet.' }],
|
|
926
|
+
ReaderSlot: [],
|
|
874
927
|
EditorSlot: [],
|
|
875
928
|
NoSelectionSlot: []
|
|
876
929
|
};
|
|
877
|
-
if (tmpActive) { tmpPane.
|
|
930
|
+
if (tmpActive && this._isPromptReadMode()) { tmpPane.ReaderSlot = [this._shapePromptReader(tmpActive)]; }
|
|
931
|
+
else if (tmpActive) { tmpPane.EditorSlot = [this._shapePromptEditor(tmpActive, pReadOnly)]; }
|
|
878
932
|
else { tmpPane.NoSelectionSlot = [{ Text: pReadOnly ? 'Nothing to show.' : 'Create a prompt to start crafting.' }]; }
|
|
879
933
|
return tmpPane;
|
|
880
934
|
}
|
|
881
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
|
+
|
|
882
956
|
_shapePromptEditor(pPrompt, pReadOnly)
|
|
883
957
|
{
|
|
884
958
|
let tmpType = libTypes.getPromptType(this._types, pPrompt.TypeKey);
|
|
@@ -942,6 +1016,7 @@ class PictViewPromptEditor extends libPictView
|
|
|
942
1016
|
Label: pTypeOption.Name,
|
|
943
1017
|
SelectedAttr: (pTypeOption.Key === pPrompt.TypeKey) ? 'selected' : ''
|
|
944
1018
|
})),
|
|
1019
|
+
ReadToggleSlot: pReadOnly ? [] : [{ ViewHash: this.Hash }],
|
|
945
1020
|
ActionsSlot: pReadOnly ? [] : [{ ViewHash: this.Hash }],
|
|
946
1021
|
OptionsSlot: pReadOnly ? [] :
|
|
947
1022
|
[{
|
|
@@ -1058,6 +1133,24 @@ class PictViewPromptEditor extends libPictView
|
|
|
1058
1133
|
{
|
|
1059
1134
|
if (this._ui.ActivePromptKey !== pKey) { this._ui.Preview = null; }
|
|
1060
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;
|
|
1061
1154
|
this._reshape();
|
|
1062
1155
|
}
|
|
1063
1156
|
selectWordList(pKey) { this._ui.ActiveWordListKey = pKey; this._reshape(); }
|
|
@@ -1071,6 +1164,8 @@ class PictViewPromptEditor extends libPictView
|
|
|
1071
1164
|
.then((pPrompt) =>
|
|
1072
1165
|
{
|
|
1073
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';
|
|
1074
1169
|
this._fire('onPromptSaved', pPrompt);
|
|
1075
1170
|
return this.load();
|
|
1076
1171
|
})
|
|
@@ -1123,6 +1218,8 @@ class PictViewPromptEditor extends libPictView
|
|
|
1123
1218
|
.then((pCopy) =>
|
|
1124
1219
|
{
|
|
1125
1220
|
this._ui.ActivePromptKey = pCopy.Key;
|
|
1221
|
+
// A copy is made to be changed; open it in the editor.
|
|
1222
|
+
this._ui.PromptMode = 'edit';
|
|
1126
1223
|
this._fire('onPromptSaved', pCopy);
|
|
1127
1224
|
return this.load();
|
|
1128
1225
|
})
|
|
@@ -1342,6 +1439,8 @@ class PictViewPromptEditor extends libPictView
|
|
|
1342
1439
|
let tmpPrompt = this._activePrompt();
|
|
1343
1440
|
if (!tmpPrompt) { return; }
|
|
1344
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';
|
|
1345
1444
|
this._ui.Preview = { PromptKey: tmpPrompt.Key, Markdown: this._generateOnce(tmpPrompt, tmpType) };
|
|
1346
1445
|
this._reshape();
|
|
1347
1446
|
}
|