Content copilot UI#793
Conversation
- new CopilotModule with sidebar component (header, empty container,
disabled chat input)
- toolbar button surfaces only while a page is in EDIT mode and the
customer-supplied {ui-conf}/config/copilot.yml has 'enabled: true'
- YAML config supports an 'actions:' list, parsed by a dependency-free
parser; sidebar renders entries automatically when populated
- feature is fully disabled by default — no behaviour change without
config file present
- new CopilotModule (sidebar component, YAML config loader, runtime state)
- toolbar button surfaces only while a page is in EDIT mode and the
customer-supplied {ui-conf}/config/copilot.yml has 'enabled: true'
- YAML supports an 'actions:' list parsed by a small dependency-free
parser; sidebar renders entries automatically when populated
- services use providedIn: 'root' so the bootstrap-time fetch survives
ContentFrameModule being lazy-loaded; load() is triggered from
AppComponent.ngOnInit, mirroring UIOverridesService
- de/en i18n entries under 'copilot.*'
- feature is fully disabled by default — no behaviour change without
config file present
- new CopilotModule with sidebar component (header, action container,
disabled chat input); CopilotConfigService and CopilotStateService
use providedIn: 'root' so the bootstrap-time fetch survives
ContentFrameModule being lazy-loaded — load() is triggered from
AppComponent.ngOnInit, mirroring UIOverridesService
- toolbar button surfaces only while a page is in EDIT mode, the
customer-supplied {ui-conf}/config/copilot.yml has 'enabled: true',
the page is not locked and not in language comparison
- YAML supports an 'actions:' list parsed by a small dependency-free
parser; sidebar renders entries automatically when populated — no
UI rebuild required to add or change actions
- de/en i18n entries under 'copilot.*'
- styling reuses existing SCSS variables; drawer drop shadow extracted
into a reusable gcmsDrawerBoxShadow mixin in _variables.scss; sidebar
width expressed in rem
- specs for copilot-yaml.parser, CopilotStateService and
CopilotConfigService; existing EditorToolbarComponent spec extended
with a MockCopilotConfigService
- feature is fully disabled by default — no behaviour change without
config file present
- copilot.spec.ts in apps/editor-ui/e2e covering button visibility,
open/close interaction, empty-state vs configured action rendering,
and the disabled chat input
- each test stubs {ui-conf}/config/copilot.yml via page.route before
navigateToApp so the App-Initializer fetch sees the per-test response
- add data-id attribute to copilot-sidebar action items so the spec
can target individual cards reliably
|
Philipp Doerre seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
There was a problem hiding this comment.
We don't need a YAML Parser.
The Configuration itself should either be a JSON file, or in the future will be done in the CMS, and will be made available via a REST Endpoint in JSON.
| * dot it's treated as an i18n key, otherwise rendered as-is. Keeps | ||
| * configuration files concise without precluding localisation. | ||
| */ | ||
| label: string; |
There was a problem hiding this comment.
Should be labelI18n with a I18nString type, as translation strings only work if they are bundled into the editor-ui already, which limits the use-case for this.
| * Short description shown under the label. Same dot-vs-literal | ||
| * heuristic as `label`. | ||
| */ | ||
| description?: string; |
There was a problem hiding this comment.
Same as label above, with descriptionI18n
There was a problem hiding this comment.
Remove the tests for the parser, as there shouldn't be a parser to begin with
There was a problem hiding this comment.
The state should be done in the already used NgXS store, instead of a custom solution.
Since it's only a single boolean flag, it should be integrated into the existing ui state.
| await expect(summarize).toBeVisible(); | ||
| await expect(summarize.locator('.copilot-action-label')).toHaveText('Zusammenfassen'); | ||
| await expect(summarize.locator('.copilot-action-description')) | ||
| .toHaveText('Eine kurze Zusammenfassung der Seite erstellen'); |
There was a problem hiding this comment.
Checking for translatable text values is not a good way to test.
While the settings are stubed and therefore the values are known, these texts can't be directly used due to changes for label -> labelI18n and description -> descriptionI18n.
We'd first need to ensure a specific UI language (as it's initially determined by the browser/system language), and therefore translation texts may differ.
| [title]="'copilot.button_tooltip' | gtxI18n" | ||
| (click)="toggleCopilot()" | ||
| > | ||
| <icon left>auto_awesome</icon> |
There was a problem hiding this comment.
There's no icon named auto_awesome in the material symbols font.
| * invalidation. | ||
| */ | ||
| public load(): void { | ||
| const url = `${CUSTOMER_CONFIG_PATH}config/copilot.yml?t=${Date.now()}`; |
There was a problem hiding this comment.
Why is the path ui-conf/config? Should be simply ui-conf
| <icon class="copilot-action-icon">{{ action.icon }}</icon> | ||
| } | ||
| <div class="copilot-action-text"> | ||
| <span class="copilot-action-label">{{ action.label }}</span> |
There was a problem hiding this comment.
The label and description need to be translated using the gtxI18n pipes, or with the changes for labelI18n and descriptionI18n using the gtxI18nObject pipe.
|
|
||
| <footer class="copilot-sidebar-footer"> | ||
| <div class="copilot-chat-input"> | ||
| <textarea |
There was a problem hiding this comment.
Use the existing gtx-textarea component instead and remove special styling for this textarea.
- drop the hand-rolled YAML parser; load `{ui-conf}/copilot.json` as
JSON via JSON.parse with shape validation (review #1, #7, #15)
- switch action label/description to per-language objects `labelI18n`
and `descriptionI18n` (type: `I18nString` = Record<string,string>)
so config values stay translatable without UI rebuild (review #3, #5)
- new `gtxI18nObject` pipe in cms-components for resolving I18nString
against the active UI language with en-fallback (review #17)
- move sidebar open/close flag from a custom service into the existing
NGXS UI state slice (`state.ui.copilotOpen` + `SetCopilotOpenAction`);
remove `CopilotStateService` (review #9)
- replace native <textarea> with <gtx-textarea>; drop the custom CSS
that styled the native element (review #19)
- replace `auto_awesome` icon with `lightbulb` (subset-safe) (review #13)
- e2e tests no longer assert on translated label text — they verify
structural hooks (data-id, label container non-empty) so the suite
stays language-agnostic (review #11)
- update COPILOT.md docs and copilot.example.json accordingly
No description provided.