59 lines
3.0 KiB
TypeScript
59 lines
3.0 KiB
TypeScript
import { Component, computed, input } from '@angular/core';
|
|
import { PluginToolView } from '../../utils/plugin-tool-view.util';
|
|
import { ExpandableValueComponent } from '../expandable-value/expandable-value.component';
|
|
|
|
/** Readable presentation only: the full receipt and model context stay intact. */
|
|
@Component({
|
|
selector: 'app-plugin-tool-result',
|
|
standalone: true,
|
|
imports: [ExpandableValueComponent],
|
|
template: `
|
|
@if (view().facts.length) {
|
|
<dl class="receipt-facts">
|
|
@for (fact of view().facts; track fact.key) {
|
|
<div><dt>{{ fact.key }}</dt><dd><app-expandable-value [label]="fact.key" [value]="fact.value" /></dd></div>
|
|
}
|
|
</dl>
|
|
}
|
|
@if (view().result) {
|
|
<pre class="receipt-preview">{{ preview() }}</pre>
|
|
@if (isLong()) {
|
|
<details class="receipt-detail receipt-text">
|
|
<summary>完整文本与控件树 <span>{{ view().result.length }} 字符</span></summary>
|
|
<pre>{{ view().result }}</pre>
|
|
</details>
|
|
}
|
|
}
|
|
@if (view().rawResult) {
|
|
<details class="receipt-detail receipt-raw">
|
|
<summary>原始返回 payload <span>完整保留</span></summary>
|
|
<pre>{{ view().rawResult }}</pre>
|
|
</details>
|
|
}
|
|
`,
|
|
styles: [`
|
|
:host { display: block; min-width: 0; width: 100%; user-select: text; cursor: auto; }
|
|
.receipt-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr)); gap: 8px 16px; margin: 0 0 12px; }
|
|
.receipt-facts div { min-width: 0; }
|
|
dt { font-size: 11px; color: var(--app-text-muted, #64748b); }
|
|
dd { margin: 3px 0 0; font-size: 12px; color: var(--app-text-control, #334155); overflow-wrap: anywhere; }
|
|
pre { margin: 0; padding: 10px 12px; border-radius: 6px; font: 12px/1.6 Consolas, monospace; color: var(--app-text-control, #334155); background: var(--app-surface-soft, #f8fafc); white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
.receipt-preview { max-height: 180px; overflow: auto; }
|
|
.receipt-detail { margin-top: 10px; border: 1px solid var(--app-border, #e2e8f0); border-radius: 6px; min-width: 0; }
|
|
summary { padding: 9px 10px; font-size: 12px; color: var(--app-text-secondary, #475569); cursor: pointer; overflow-wrap: anywhere; }
|
|
summary span { margin-left: 8px; font-size: 11px; color: var(--app-text-muted, #64748b); }
|
|
summary:focus-visible { outline: 2px solid var(--app-primary-text, #1a73e8); outline-offset: 2px; }
|
|
.receipt-detail pre { max-height: 400px; overflow: auto; border-top: 1px solid var(--app-border, #e2e8f0); border-radius: 0 0 6px 6px; }
|
|
`]
|
|
})
|
|
export class PluginToolResultComponent {
|
|
view = input.required<PluginToolView>();
|
|
private readonly previewLimit = 1000;
|
|
preview = computed(() => {
|
|
const text = this.view().result;
|
|
const excerpt = text.split('\n').slice(0, 7).join('\n').slice(0, this.previewLimit);
|
|
return excerpt.length < text.length ? `${excerpt}\n…` : text;
|
|
});
|
|
isLong = computed(() => this.preview() !== this.view().result);
|
|
}
|