@memberjunction/ng-user-routines 6.2.0-edge.0 → 6.2.0-edge.1
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/dist/lib/new-routine.component.js +2 -2
- package/dist/lib/new-routine.component.js.map +1 -1
- package/dist/lib/user-routines-slide-in.component.d.ts +2 -0
- package/dist/lib/user-routines-slide-in.component.d.ts.map +1 -1
- package/dist/lib/user-routines-slide-in.component.js +7 -3
- package/dist/lib/user-routines-slide-in.component.js.map +1 -1
- package/package.json +15 -15
|
@@ -1046,7 +1046,7 @@ export class NewRoutineComponent extends BaseAngularComponent {
|
|
|
1046
1046
|
return errors;
|
|
1047
1047
|
}
|
|
1048
1048
|
static ɵfac = /*@__PURE__*/ (() => { let ɵNewRoutineComponent_BaseFactory; return function NewRoutineComponent_Factory(__ngFactoryType__) { return (ɵNewRoutineComponent_BaseFactory || (ɵNewRoutineComponent_BaseFactory = i0.ɵɵgetInheritedFactory(NewRoutineComponent)))(__ngFactoryType__ || NewRoutineComponent); }; })();
|
|
1049
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: NewRoutineComponent, selectors: [["mj-new-routine"]], inputs: { RoutineID: "RoutineID" }, outputs: { Saved: "Saved", Cancelled: "Cancelled", BeforeRoutineCreated: "BeforeRoutineCreated", AfterRoutineCreated: "AfterRoutineCreated" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 1, consts: [[1, "editor-loading"], [1, "routine-editor"], ["text", "
|
|
1049
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: NewRoutineComponent, selectors: [["mj-new-routine"]], inputs: { RoutineID: "RoutineID" }, outputs: { Saved: "Saved", Cancelled: "Cancelled", BeforeRoutineCreated: "BeforeRoutineCreated", AfterRoutineCreated: "AfterRoutineCreated" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 1, consts: [[1, "editor-loading"], [1, "routine-editor"], ["text", "Getting the editor ready...", "size", "medium"], ["Variant", "error"], [1, "editor-section"], [1, "editor-field"], ["for", "routine-name", 1, "editor-label"], [1, "editor-required"], ["id", "routine-name", "type", "text", "placeholder", "e.g. Morning membership digest", 1, "mj-input", 3, "ngModelChange", "ngModel"], [1, "editor-label"], ["DefaultExpansion", "all", "SelectionMode", "single", "SelectableTypes", "leaf", "Placeholder", "Select an agent...", 3, "BranchConfig", "LeafConfig", "Value", "Clearable"], [1, "editor-hint"], ["for", "routine-message", 1, "editor-label"], ["id", "routine-message", "placeholder", "The message the routine sends to the agent each time it runs", 3, "ngModelChange", "ngModel", "ExcludedTriggerKeys", "Provider", "enableAttachments", "autoFocus", "currentUser"], ["role", "radiogroup", "aria-label", "Schedule frequency", 1, "editor-segmented", "editor-segmented--wrap"], ["type", "button", 1, "editor-segment", 3, "editor-segment--active"], [1, "editor-schedule-detail"], [1, "editor-field", "editor-field--inline"], [1, "editor-schedule-preview"], [1, "fa-solid", "fa-calendar-check"], ["type", "button", 1, "editor-advanced-toggle", 3, "click"], [1, "fa-solid"], [1, "editor-hint-inline"], [1, "editor-footer"], ["mjButton", "", "variant", "primary", "size", "md", 3, "click", "disabled"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-check"], ["mjButton", "", "variant", "secondary", "size", "md", 3, "click", "disabled"], [1, "editor-errors"], ["DefaultExpansion", "all", "SelectionMode", "single", "SelectableTypes", "leaf", "Placeholder", "Select an agent...", 3, "AfterNodeSelect", "BranchConfig", "LeafConfig", "Value", "Clearable"], ["type", "button", 1, "editor-segment", 3, "click"], [3, "ngModelChange", "ngModel", "Min", "Max", "Step"], ["type", "time", 1, "mj-input", "editor-time-input", 3, "ngModelChange", "ngModel"], ["TextField", "text", "ValueField", "value", 1, "editor-inline-dropdown", 3, "ngModelChange", "Data", "ValuePrimitive", "ngModel"], ["for", "routine-cron", 1, "editor-label"], ["id", "routine-cron", "type", "text", "placeholder", "minute hour day-of-month month day-of-week", 1, "mj-input", "editor-mono", 3, "ngModelChange", "ngModel"], [1, "editor-section-title"], [1, "fa-solid", "fa-circle-info"], ["for", "routine-description", 1, "editor-label"], ["id", "routine-description", "rows", "2", "placeholder", "What does this routine do?", 1, "mj-textarea", 3, "ngModelChange", "ngModel"], ["role", "radiogroup", "aria-label", "Routine type", 1, "editor-segmented"], [1, "fa-solid", "fa-clock"], [1, "fa-solid", "fa-eye"], ["Placeholder", "Select an IANA timezone...", 3, "ngModelChange", "Data", "ValuePrimitive", "ngModel"], [1, "editor-field-row"], ["for", "routine-startat", 1, "editor-label"], ["id", "routine-startat", "type", "datetime-local", 1, "mj-input", 3, "ngModelChange", "ngModel"], ["for", "routine-endat", 1, "editor-label"], ["id", "routine-endat", "type", "datetime-local", 1, "mj-input", 3, "ngModelChange", "ngModel"], [1, "editor-code"], ["language", "json", "placeholder", "{ \"example\": true }", 3, "ngModelChange", "ngModel"], [1, "fa-solid", "fa-bell"], ["TextField", "text", "ValueField", "value", 3, "ngModelChange", "Data", "ValuePrimitive", "ngModel"], [1, "editor-field", "editor-field--inline", "editor-switches"], ["OnLabel", "In-app", "OffLabel", "In-app", 3, "ngModelChange", "ngModel"], ["OnLabel", "Email", "OffLabel", "Email", 3, "ngModelChange", "ngModel"], [1, "editor-recipients-header"], ["mjButton", "", "variant", "outline", "size", "sm", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "editor-recipient-row"], [1, "editor-skills"], ["type", "button", 1, "editor-skill-chip", 3, "editor-skill-chip--selected", "title"], ["type", "button", 1, "editor-skill-chip", 3, "click", "title"], [1, "fa-solid", "fa-check", "editor-skill-check"], [1, "editor-recipient-order"], ["mjButton", "", "variant", "icon", "size", "sm", "title", "Move up", 3, "click", "disabled"], [1, "fa-solid", "fa-chevron-up"], ["mjButton", "", "variant", "icon", "size", "sm", "title", "Move down", 3, "click", "disabled"], [1, "fa-solid", "fa-chevron-down"], ["TextField", "text", "ValueField", "value", 1, "editor-recipient-mode", 3, "ngModelChange", "Data", "ValuePrimitive", "ngModel"], ["TextField", "Name", "ValueField", "ID", "Placeholder", "Select a user...", 1, "editor-recipient-target", 3, "Data", "ValuePrimitive", "ngModel"], ["type", "email", "placeholder", "name@example.com", 1, "mj-input", "editor-recipient-target", 3, "ngModel"], ["TextField", "text", "ValueField", "value", 1, "editor-recipient-channel", 3, "ngModelChange", "Data", "ValuePrimitive", "ngModel"], ["mjButton", "", "variant", "icon", "size", "sm", "title", "Remove recipient", 3, "click"], [1, "fa-solid", "fa-trash-can"], ["TextField", "Name", "ValueField", "ID", "Placeholder", "Select a user...", 1, "editor-recipient-target", 3, "ngModelChange", "Data", "ValuePrimitive", "ngModel"], ["type", "email", "placeholder", "name@example.com", 1, "mj-input", "editor-recipient-target", 3, "ngModelChange", "ngModel"]], template: function NewRoutineComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1050
1050
|
i0.ɵɵconditionalCreate(0, NewRoutineComponent_Conditional_0_Template, 2, 0, "div", 0)(1, NewRoutineComponent_Conditional_1_Template, 49, 22, "div", 1);
|
|
1051
1051
|
} if (rf & 2) {
|
|
1052
1052
|
i0.ɵɵconditional(ctx.IsLoading ? 0 : 1);
|
|
@@ -1054,7 +1054,7 @@ export class NewRoutineComponent extends BaseAngularComponent {
|
|
|
1054
1054
|
}
|
|
1055
1055
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(NewRoutineComponent, [{
|
|
1056
1056
|
type: Component,
|
|
1057
|
-
args: [{ standalone: false, selector: 'mj-new-routine', template: "@if (IsLoading) {\n <div class=\"editor-loading\">\n <mj-loading text=\"Loading editor...\" size=\"medium\"></mj-loading>\n </div>\n} @else {\n <div class=\"routine-editor\">\n\n @if (ValidationErrors.length > 0) {\n <mj-alert Variant=\"error\">\n <ul class=\"editor-errors\">\n @for (error of ValidationErrors; track error) {\n <li>{{ error }}</li>\n }\n </ul>\n </mj-alert>\n }\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 BASICS (the 80% path: name, agent, message, schedule) \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <section class=\"editor-section\">\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-name\">Name <span class=\"editor-required\">*</span></label>\n <input id=\"routine-name\" class=\"mj-input\" type=\"text\" [(ngModel)]=\"Name\" placeholder=\"e.g. Morning membership digest\" />\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Which agent should this routine run? <span class=\"editor-required\">*</span></label>\n @if (AgentTreeLeafConfig) {\n <mj-tree-dropdown\n [BranchConfig]=\"AgentTreeBranchConfig\"\n [LeafConfig]=\"AgentTreeLeafConfig\"\n DefaultExpansion=\"all\"\n SelectionMode=\"single\"\n SelectableTypes=\"leaf\"\n [Value]=\"SelectedAgentKey\"\n [Clearable]=\"false\"\n Placeholder=\"Select an agent...\"\n (AfterNodeSelect)=\"OnAgentNodeSelected($event)\">\n </mj-tree-dropdown>\n }\n <div class=\"editor-hint\">Active agents only, grouped by category \u2014 realtime (voice) agents are interactive-only and can't be scheduled.</div>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-message\">Message sent on each run</label>\n <!-- Composer mention editor in DISCOVERY mode: trigger providers are ClassFactory-\n discovered (ng-conversations registers '@' agent / '#' record / '/' skill plugins\n when loaded). '@' agent mentions are excluded \u2014 the routine's agent is fixed by\n the picker above. With no providers registered this degrades gracefully to a\n plain text editor. -->\n <mj-mention-editor id=\"routine-message\"\n [(ngModel)]=\"InitialMessage\"\n placeholder=\"The message the routine sends to the agent each time it runs\"\n [ExcludedTriggerKeys]=\"['agent-mentions']\"\n [Provider]=\"Provider\"\n [enableAttachments]=\"false\"\n [autoFocus]=\"false\"\n [currentUser]=\"ProviderToUse.CurrentUser\"></mj-mention-editor>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Frequency</label>\n <div class=\"editor-segmented editor-segmented--wrap\" role=\"radiogroup\" aria-label=\"Schedule frequency\">\n @for (option of ScheduleKindOptions; track option.Value) {\n <button type=\"button\" class=\"editor-segment\"\n [class.editor-segment--active]=\"ScheduleKind === option.Value\"\n (click)=\"SetScheduleKind(option.Value)\">\n {{ option.Label }}\n </button>\n }\n </div>\n </div>\n\n <div class=\"editor-schedule-detail\">\n @switch (ScheduleKind) {\n @case ('hourly') {\n <div class=\"editor-field editor-field--inline\">\n <label class=\"editor-label\">At minute</label>\n <mj-numeric-input [(ngModel)]=\"ScheduleMinute\" [Min]=\"0\" [Max]=\"59\" [Step]=\"5\"></mj-numeric-input>\n <span class=\"editor-hint-inline\">past every hour</span>\n </div>\n }\n @case ('daily') {\n <div class=\"editor-field editor-field--inline\">\n <label class=\"editor-label\">At</label>\n <input class=\"mj-input editor-time-input\" type=\"time\" [(ngModel)]=\"ScheduleTime\" />\n <span class=\"editor-hint-inline\">every day</span>\n </div>\n }\n @case ('weekly') {\n <div class=\"editor-field editor-field--inline\">\n <label class=\"editor-label\">Every</label>\n <mj-dropdown class=\"editor-inline-dropdown\" [Data]=\"DayOfWeekOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"ScheduleDayOfWeek\"></mj-dropdown>\n <label class=\"editor-label\">at</label>\n <input class=\"mj-input editor-time-input\" type=\"time\" [(ngModel)]=\"ScheduleTime\" />\n </div>\n }\n @case ('monthly') {\n <div class=\"editor-field editor-field--inline\">\n <label class=\"editor-label\">On day</label>\n <mj-dropdown class=\"editor-inline-dropdown\" [Data]=\"DayOfMonthOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"ScheduleDayOfMonth\"></mj-dropdown>\n <label class=\"editor-label\">at</label>\n <input class=\"mj-input editor-time-input\" type=\"time\" [(ngModel)]=\"ScheduleTime\" />\n </div>\n }\n @case ('advanced') {\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-cron\">Cron expression</label>\n <input id=\"routine-cron\" class=\"mj-input editor-mono\" type=\"text\" [(ngModel)]=\"RawCron\"\n placeholder=\"minute hour day-of-month month day-of-week\" />\n </div>\n }\n }\n <div class=\"editor-schedule-preview\">\n <i class=\"fa-solid fa-calendar-check\"></i> {{ SchedulePreview || 'No schedule yet' }}\n </div>\n </div>\n </section>\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 ADVANCED (progressive disclosure \u2014 collapsed by default) \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <button type=\"button\" class=\"editor-advanced-toggle\" (click)=\"ShowAdvanced = !ShowAdvanced\"\n [attr.aria-expanded]=\"ShowAdvanced\">\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"!ShowAdvanced\" [class.fa-chevron-down]=\"ShowAdvanced\"></i>\n Advanced options\n <span class=\"editor-hint-inline\">description \u00B7 monitoring \u00B7 timezone \u00B7 window \u00B7 payload \u00B7 skills \u00B7 notifications</span>\n </button>\n\n @if (ShowAdvanced) {\n <section class=\"editor-section\">\n <h3 class=\"editor-section-title\"><i class=\"fa-solid fa-circle-info\"></i> Details</h3>\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-description\">Description</label>\n <textarea id=\"routine-description\" class=\"mj-textarea\" rows=\"2\" [(ngModel)]=\"Description\"\n placeholder=\"What does this routine do?\"></textarea>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Routine type</label>\n <div class=\"editor-segmented\" role=\"radiogroup\" aria-label=\"Routine type\">\n <button type=\"button\" class=\"editor-segment\"\n [class.editor-segment--active]=\"RoutineType === 'Scheduled'\"\n (click)=\"RoutineType = 'Scheduled'\">\n <i class=\"fa-solid fa-clock\"></i> Scheduled\n </button>\n <button type=\"button\" class=\"editor-segment\"\n [class.editor-segment--active]=\"RoutineType === 'Monitoring'\"\n (click)=\"RoutineType = 'Monitoring'\">\n <i class=\"fa-solid fa-eye\"></i> Monitoring\n </button>\n </div>\n <div class=\"editor-hint\">{{ RoutineTypeHelp }}</div>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Timezone</label>\n <mj-combobox\n [Data]=\"TimezoneOptions\"\n [ValuePrimitive]=\"true\"\n Placeholder=\"Select an IANA timezone...\"\n [(ngModel)]=\"Timezone\">\n </mj-combobox>\n </div>\n\n <div class=\"editor-field-row\">\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-startat\">Active from (optional)</label>\n <input id=\"routine-startat\" class=\"mj-input\" type=\"datetime-local\" [(ngModel)]=\"StartAtLocal\" />\n </div>\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-endat\">Active until (optional)</label>\n <input id=\"routine-endat\" class=\"mj-input\" type=\"datetime-local\" [(ngModel)]=\"EndAtLocal\" />\n </div>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Starting payload (JSON, optional)</label>\n <div class=\"editor-code\">\n <mj-code-editor [(ngModel)]=\"StartingPayloadText\" language=\"json\"\n placeholder='{ \"example\": true }'></mj-code-editor>\n </div>\n <div class=\"editor-hint\">Passed to the agent on each run. Leave blank for none.</div>\n </div>\n\n @if (SkillOptions.length > 0) {\n <div class=\"editor-field\">\n <label class=\"editor-label\">Pre-activate skills (optional)</label>\n <div class=\"editor-skills\">\n @for (skill of SkillOptions; track skill.ID) {\n <button type=\"button\" class=\"editor-skill-chip\"\n [class.editor-skill-chip--selected]=\"IsSkillSelected(skill.ID)\"\n [title]=\"skill.Description ?? skill.Name\"\n (click)=\"ToggleSkill(skill.ID)\">\n <i [class]=\"skill.IconClass || 'fa-solid fa-wand-magic-sparkles'\"></i>\n {{ skill.Name }}\n @if (IsSkillSelected(skill.ID)) {\n <i class=\"fa-solid fa-check editor-skill-check\"></i>\n }\n </button>\n }\n </div>\n <div class=\"editor-hint\">Selected skills start every run with their instructions and tools in effect (subject to the agent's skill gates).</div>\n </div>\n }\n </section>\n\n <section class=\"editor-section\">\n <h3 class=\"editor-section-title\"><i class=\"fa-solid fa-bell\"></i> Notifications</h3>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Notify me</label>\n <mj-dropdown [Data]=\"NotifyConditionOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"NotifyCondition\"></mj-dropdown>\n </div>\n\n <div class=\"editor-field editor-field--inline editor-switches\">\n <mj-switch [(ngModel)]=\"NotifyViaInApp\" OnLabel=\"In-app\" OffLabel=\"In-app\"></mj-switch>\n <mj-switch [(ngModel)]=\"NotifyViaEmail\" OnLabel=\"Email\" OffLabel=\"Email\"></mj-switch>\n </div>\n\n <div class=\"editor-field\">\n <div class=\"editor-recipients-header\">\n <label class=\"editor-label\">Additional recipients</label>\n <button mjButton variant=\"outline\" size=\"sm\" (click)=\"AddRecipient()\">\n <i class=\"fa-solid fa-plus\"></i> Add recipient\n </button>\n </div>\n @if (Recipients.length === 0) {\n <div class=\"editor-hint\">Only you (the owner) will be notified.</div>\n }\n @for (row of Recipients; track $index; let i = $index; let first = $first; let last = $last) {\n <div class=\"editor-recipient-row\">\n <div class=\"editor-recipient-order\">\n <button mjButton variant=\"icon\" size=\"sm\" title=\"Move up\" [disabled]=\"first\" (click)=\"MoveRecipient(i, -1)\">\n <i class=\"fa-solid fa-chevron-up\"></i>\n </button>\n <button mjButton variant=\"icon\" size=\"sm\" title=\"Move down\" [disabled]=\"last\" (click)=\"MoveRecipient(i, 1)\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n </div>\n <mj-dropdown class=\"editor-recipient-mode\" [Data]=\"RecipientModeOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"row.Mode\" (ngModelChange)=\"OnRecipientModeChange(row)\"></mj-dropdown>\n @if (row.Mode === 'user') {\n <mj-combobox class=\"editor-recipient-target\" [Data]=\"UserOptions\" TextField=\"Name\" ValueField=\"ID\"\n [ValuePrimitive]=\"true\" Placeholder=\"Select a user...\" [(ngModel)]=\"row.UserID\"></mj-combobox>\n } @else {\n <input class=\"mj-input editor-recipient-target\" type=\"email\" placeholder=\"name@example.com\" [(ngModel)]=\"row.Email\" />\n }\n <mj-dropdown class=\"editor-recipient-channel\" [Data]=\"ChannelOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"row.Channel\"></mj-dropdown>\n <button mjButton variant=\"icon\" size=\"sm\" title=\"Remove recipient\" (click)=\"RemoveRecipient(i)\">\n <i class=\"fa-solid fa-trash-can\"></i>\n </button>\n </div>\n }\n </div>\n </section>\n }\n\n <!-- ======================= Footer (confirm LEFT, cancel RIGHT) ======================= -->\n <div class=\"editor-footer\">\n <button mjButton variant=\"primary\" size=\"md\" [disabled]=\"IsSaving\" (click)=\"Save()\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-check\"></i>\n }\n {{ IsEdit ? 'Save Changes' : 'Create Routine' }}\n </button>\n <button mjButton variant=\"secondary\" size=\"md\" [disabled]=\"IsSaving\" (click)=\"Cancel()\">Cancel</button>\n </div>\n </div>\n}\n", styles: [":host {\n display: block;\n height: 100%;\n}\n\n.editor-loading {\n display: flex;\n justify-content: center;\n padding: 48px 0;\n}\n\n.routine-editor {\n display: flex;\n flex-direction: column;\n gap: 20px;\n padding: 4px 2px 0 2px;\n}\n\n.editor-errors {\n margin: 0;\n padding-left: 18px;\n}\n\n.editor-section {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: var(--mj-radius-lg, 10px);\n}\n\n.editor-section-title {\n margin: 0;\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.editor-section-title > i {\n color: var(--mj-brand-primary);\n}\n\n.editor-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n}\n\n.editor-field--inline {\n flex-direction: row;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.editor-field-row {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.editor-field-row > .editor-field {\n flex: 1 1 220px;\n}\n\n.editor-label {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.editor-required {\n color: var(--mj-status-error);\n}\n\n.editor-hint {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.editor-hint-inline {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n/* Segmented pickers (target type / routine type / frequency) */\n.editor-segmented {\n display: inline-flex;\n gap: 0;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n overflow: hidden;\n width: fit-content;\n}\n\n.editor-segmented--wrap {\n flex-wrap: wrap;\n}\n\n.editor-segment {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 14px;\n font-size: 13px;\n border: none;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background 0.12s ease, color 0.12s ease;\n}\n\n.editor-segment + .editor-segment {\n border-left: 1px solid var(--mj-border-default);\n}\n\n.editor-segment:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.editor-segment--active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n/* Schedule */\n.editor-schedule-detail {\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-subtle);\n border-radius: var(--mj-radius-md, 8px);\n}\n\n.editor-schedule-preview {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.editor-schedule-preview > i {\n color: var(--mj-status-success);\n}\n\n.editor-time-input {\n width: 130px;\n}\n\n.editor-inline-dropdown {\n min-width: 140px;\n}\n\n.editor-mono {\n font-family: var(--mj-font-mono, monospace);\n}\n\n/* Code editor container */\n.editor-code {\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n overflow: hidden;\n min-height: 90px;\n}\n\n/* Skills */\n.editor-skills {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.editor-skill-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 12px;\n font-size: 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full, 999px);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;\n}\n\n.editor-skill-chip:hover {\n border-color: var(--mj-border-strong);\n}\n\n.editor-skill-chip--selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.editor-skill-check {\n font-size: 10px;\n}\n\n/* Notifications */\n.editor-switches {\n gap: 24px;\n}\n\n.editor-recipients-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n}\n\n.editor-recipient-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px;\n border: 1px solid var(--mj-border-subtle);\n border-radius: var(--mj-radius-md, 8px);\n background: var(--mj-bg-surface);\n}\n\n.editor-recipient-order {\n display: flex;\n flex-direction: column;\n}\n\n.editor-recipient-mode {\n flex: 0 0 150px;\n}\n\n.editor-recipient-target {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.editor-recipient-channel {\n flex: 0 0 120px;\n}\n\n/* Footer \u2014 confirm on the LEFT, cancel on the RIGHT (MJ convention) */\n.editor-footer {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 0 4px 0;\n border-top: 1px solid var(--mj-border-default);\n position: sticky;\n bottom: 0;\n background: var(--mj-bg-surface);\n}\n\n/* Agent tree picker */\n.editor-selected-agent {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: var(--mj-radius-md, 8px);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 13px;\n font-weight: 600;\n width: fit-content;\n}\n\n.editor-selected-agent-hint {\n font-size: 11px;\n font-weight: 400;\n color: var(--mj-text-muted);\n}\n\n.editor-agent-tree {\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n max-height: 280px;\n overflow: auto;\n background: var(--mj-bg-surface);\n}\n\n/* Progressive-disclosure toggle between the basic path and the advanced sections */\n.editor-advanced-toggle {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 10px 12px;\n border: 1px dashed var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n text-align: left;\n}\n\n.editor-advanced-toggle:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.editor-advanced-toggle .editor-hint-inline {\n font-weight: 400;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n"] }]
|
|
1057
|
+
args: [{ standalone: false, selector: 'mj-new-routine', template: "@if (IsLoading) {\n <div class=\"editor-loading\">\n <mj-loading text=\"Getting the editor ready...\" size=\"medium\"></mj-loading>\n </div>\n} @else {\n <div class=\"routine-editor\">\n\n @if (ValidationErrors.length > 0) {\n <mj-alert Variant=\"error\">\n <ul class=\"editor-errors\">\n @for (error of ValidationErrors; track error) {\n <li>{{ error }}</li>\n }\n </ul>\n </mj-alert>\n }\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 BASICS (the 80% path: name, agent, message, schedule) \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <section class=\"editor-section\">\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-name\">Name <span class=\"editor-required\">*</span></label>\n <input id=\"routine-name\" class=\"mj-input\" type=\"text\" [(ngModel)]=\"Name\" placeholder=\"e.g. Morning membership digest\" />\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Which agent should this routine run? <span class=\"editor-required\">*</span></label>\n @if (AgentTreeLeafConfig) {\n <mj-tree-dropdown\n [BranchConfig]=\"AgentTreeBranchConfig\"\n [LeafConfig]=\"AgentTreeLeafConfig\"\n DefaultExpansion=\"all\"\n SelectionMode=\"single\"\n SelectableTypes=\"leaf\"\n [Value]=\"SelectedAgentKey\"\n [Clearable]=\"false\"\n Placeholder=\"Select an agent...\"\n (AfterNodeSelect)=\"OnAgentNodeSelected($event)\">\n </mj-tree-dropdown>\n }\n <div class=\"editor-hint\">Active agents only, grouped by category \u2014 realtime (voice) agents are interactive-only and can't be scheduled.</div>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-message\">Message sent on each run</label>\n <!-- Composer mention editor in DISCOVERY mode: trigger providers are ClassFactory-\n discovered (ng-conversations registers '@' agent / '#' record / '/' skill plugins\n when loaded). '@' agent mentions are excluded \u2014 the routine's agent is fixed by\n the picker above. With no providers registered this degrades gracefully to a\n plain text editor. -->\n <mj-mention-editor id=\"routine-message\"\n [(ngModel)]=\"InitialMessage\"\n placeholder=\"The message the routine sends to the agent each time it runs\"\n [ExcludedTriggerKeys]=\"['agent-mentions']\"\n [Provider]=\"Provider\"\n [enableAttachments]=\"false\"\n [autoFocus]=\"false\"\n [currentUser]=\"ProviderToUse.CurrentUser\"></mj-mention-editor>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Frequency</label>\n <div class=\"editor-segmented editor-segmented--wrap\" role=\"radiogroup\" aria-label=\"Schedule frequency\">\n @for (option of ScheduleKindOptions; track option.Value) {\n <button type=\"button\" class=\"editor-segment\"\n [class.editor-segment--active]=\"ScheduleKind === option.Value\"\n (click)=\"SetScheduleKind(option.Value)\">\n {{ option.Label }}\n </button>\n }\n </div>\n </div>\n\n <div class=\"editor-schedule-detail\">\n @switch (ScheduleKind) {\n @case ('hourly') {\n <div class=\"editor-field editor-field--inline\">\n <label class=\"editor-label\">At minute</label>\n <mj-numeric-input [(ngModel)]=\"ScheduleMinute\" [Min]=\"0\" [Max]=\"59\" [Step]=\"5\"></mj-numeric-input>\n <span class=\"editor-hint-inline\">past every hour</span>\n </div>\n }\n @case ('daily') {\n <div class=\"editor-field editor-field--inline\">\n <label class=\"editor-label\">At</label>\n <input class=\"mj-input editor-time-input\" type=\"time\" [(ngModel)]=\"ScheduleTime\" />\n <span class=\"editor-hint-inline\">every day</span>\n </div>\n }\n @case ('weekly') {\n <div class=\"editor-field editor-field--inline\">\n <label class=\"editor-label\">Every</label>\n <mj-dropdown class=\"editor-inline-dropdown\" [Data]=\"DayOfWeekOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"ScheduleDayOfWeek\"></mj-dropdown>\n <label class=\"editor-label\">at</label>\n <input class=\"mj-input editor-time-input\" type=\"time\" [(ngModel)]=\"ScheduleTime\" />\n </div>\n }\n @case ('monthly') {\n <div class=\"editor-field editor-field--inline\">\n <label class=\"editor-label\">On day</label>\n <mj-dropdown class=\"editor-inline-dropdown\" [Data]=\"DayOfMonthOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"ScheduleDayOfMonth\"></mj-dropdown>\n <label class=\"editor-label\">at</label>\n <input class=\"mj-input editor-time-input\" type=\"time\" [(ngModel)]=\"ScheduleTime\" />\n </div>\n }\n @case ('advanced') {\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-cron\">Cron expression</label>\n <input id=\"routine-cron\" class=\"mj-input editor-mono\" type=\"text\" [(ngModel)]=\"RawCron\"\n placeholder=\"minute hour day-of-month month day-of-week\" />\n </div>\n }\n }\n <div class=\"editor-schedule-preview\">\n <i class=\"fa-solid fa-calendar-check\"></i> {{ SchedulePreview || 'No schedule yet' }}\n </div>\n </div>\n </section>\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 ADVANCED (progressive disclosure \u2014 collapsed by default) \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <button type=\"button\" class=\"editor-advanced-toggle\" (click)=\"ShowAdvanced = !ShowAdvanced\"\n [attr.aria-expanded]=\"ShowAdvanced\">\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"!ShowAdvanced\" [class.fa-chevron-down]=\"ShowAdvanced\"></i>\n Advanced options\n <span class=\"editor-hint-inline\">description \u00B7 monitoring \u00B7 timezone \u00B7 window \u00B7 payload \u00B7 skills \u00B7 notifications</span>\n </button>\n\n @if (ShowAdvanced) {\n <section class=\"editor-section\">\n <h3 class=\"editor-section-title\"><i class=\"fa-solid fa-circle-info\"></i> Details</h3>\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-description\">Description</label>\n <textarea id=\"routine-description\" class=\"mj-textarea\" rows=\"2\" [(ngModel)]=\"Description\"\n placeholder=\"What does this routine do?\"></textarea>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Routine type</label>\n <div class=\"editor-segmented\" role=\"radiogroup\" aria-label=\"Routine type\">\n <button type=\"button\" class=\"editor-segment\"\n [class.editor-segment--active]=\"RoutineType === 'Scheduled'\"\n (click)=\"RoutineType = 'Scheduled'\">\n <i class=\"fa-solid fa-clock\"></i> Scheduled\n </button>\n <button type=\"button\" class=\"editor-segment\"\n [class.editor-segment--active]=\"RoutineType === 'Monitoring'\"\n (click)=\"RoutineType = 'Monitoring'\">\n <i class=\"fa-solid fa-eye\"></i> Monitoring\n </button>\n </div>\n <div class=\"editor-hint\">{{ RoutineTypeHelp }}</div>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Timezone</label>\n <mj-combobox\n [Data]=\"TimezoneOptions\"\n [ValuePrimitive]=\"true\"\n Placeholder=\"Select an IANA timezone...\"\n [(ngModel)]=\"Timezone\">\n </mj-combobox>\n </div>\n\n <div class=\"editor-field-row\">\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-startat\">Active from (optional)</label>\n <input id=\"routine-startat\" class=\"mj-input\" type=\"datetime-local\" [(ngModel)]=\"StartAtLocal\" />\n </div>\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-endat\">Active until (optional)</label>\n <input id=\"routine-endat\" class=\"mj-input\" type=\"datetime-local\" [(ngModel)]=\"EndAtLocal\" />\n </div>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Starting payload (JSON, optional)</label>\n <div class=\"editor-code\">\n <mj-code-editor [(ngModel)]=\"StartingPayloadText\" language=\"json\"\n placeholder='{ \"example\": true }'></mj-code-editor>\n </div>\n <div class=\"editor-hint\">Passed to the agent on each run. Leave blank for none.</div>\n </div>\n\n @if (SkillOptions.length > 0) {\n <div class=\"editor-field\">\n <label class=\"editor-label\">Pre-activate skills (optional)</label>\n <div class=\"editor-skills\">\n @for (skill of SkillOptions; track skill.ID) {\n <button type=\"button\" class=\"editor-skill-chip\"\n [class.editor-skill-chip--selected]=\"IsSkillSelected(skill.ID)\"\n [title]=\"skill.Description ?? skill.Name\"\n (click)=\"ToggleSkill(skill.ID)\">\n <i [class]=\"skill.IconClass || 'fa-solid fa-wand-magic-sparkles'\"></i>\n {{ skill.Name }}\n @if (IsSkillSelected(skill.ID)) {\n <i class=\"fa-solid fa-check editor-skill-check\"></i>\n }\n </button>\n }\n </div>\n <div class=\"editor-hint\">Selected skills start every run with their instructions and tools in effect (subject to the agent's skill gates).</div>\n </div>\n }\n </section>\n\n <section class=\"editor-section\">\n <h3 class=\"editor-section-title\"><i class=\"fa-solid fa-bell\"></i> Notifications</h3>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Notify me</label>\n <mj-dropdown [Data]=\"NotifyConditionOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"NotifyCondition\"></mj-dropdown>\n </div>\n\n <div class=\"editor-field editor-field--inline editor-switches\">\n <mj-switch [(ngModel)]=\"NotifyViaInApp\" OnLabel=\"In-app\" OffLabel=\"In-app\"></mj-switch>\n <mj-switch [(ngModel)]=\"NotifyViaEmail\" OnLabel=\"Email\" OffLabel=\"Email\"></mj-switch>\n </div>\n\n <div class=\"editor-field\">\n <div class=\"editor-recipients-header\">\n <label class=\"editor-label\">Additional recipients</label>\n <button mjButton variant=\"outline\" size=\"sm\" (click)=\"AddRecipient()\">\n <i class=\"fa-solid fa-plus\"></i> Add recipient\n </button>\n </div>\n @if (Recipients.length === 0) {\n <div class=\"editor-hint\">Only you (the owner) will be notified.</div>\n }\n @for (row of Recipients; track $index; let i = $index; let first = $first; let last = $last) {\n <div class=\"editor-recipient-row\">\n <div class=\"editor-recipient-order\">\n <button mjButton variant=\"icon\" size=\"sm\" title=\"Move up\" [disabled]=\"first\" (click)=\"MoveRecipient(i, -1)\">\n <i class=\"fa-solid fa-chevron-up\"></i>\n </button>\n <button mjButton variant=\"icon\" size=\"sm\" title=\"Move down\" [disabled]=\"last\" (click)=\"MoveRecipient(i, 1)\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n </div>\n <mj-dropdown class=\"editor-recipient-mode\" [Data]=\"RecipientModeOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"row.Mode\" (ngModelChange)=\"OnRecipientModeChange(row)\"></mj-dropdown>\n @if (row.Mode === 'user') {\n <mj-combobox class=\"editor-recipient-target\" [Data]=\"UserOptions\" TextField=\"Name\" ValueField=\"ID\"\n [ValuePrimitive]=\"true\" Placeholder=\"Select a user...\" [(ngModel)]=\"row.UserID\"></mj-combobox>\n } @else {\n <input class=\"mj-input editor-recipient-target\" type=\"email\" placeholder=\"name@example.com\" [(ngModel)]=\"row.Email\" />\n }\n <mj-dropdown class=\"editor-recipient-channel\" [Data]=\"ChannelOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"row.Channel\"></mj-dropdown>\n <button mjButton variant=\"icon\" size=\"sm\" title=\"Remove recipient\" (click)=\"RemoveRecipient(i)\">\n <i class=\"fa-solid fa-trash-can\"></i>\n </button>\n </div>\n }\n </div>\n </section>\n }\n\n <!-- ======================= Footer (confirm LEFT, cancel RIGHT) ======================= -->\n <div class=\"editor-footer\">\n <button mjButton variant=\"primary\" size=\"md\" [disabled]=\"IsSaving\" (click)=\"Save()\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-check\"></i>\n }\n {{ IsEdit ? 'Save Changes' : 'Create Routine' }}\n </button>\n <button mjButton variant=\"secondary\" size=\"md\" [disabled]=\"IsSaving\" (click)=\"Cancel()\">Cancel</button>\n </div>\n </div>\n}\n", styles: [":host {\n display: block;\n height: 100%;\n}\n\n.editor-loading {\n display: flex;\n justify-content: center;\n padding: 48px 0;\n}\n\n.routine-editor {\n display: flex;\n flex-direction: column;\n gap: 20px;\n padding: 4px 2px 0 2px;\n}\n\n.editor-errors {\n margin: 0;\n padding-left: 18px;\n}\n\n.editor-section {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: var(--mj-radius-lg, 10px);\n}\n\n.editor-section-title {\n margin: 0;\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.editor-section-title > i {\n color: var(--mj-brand-primary);\n}\n\n.editor-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n}\n\n.editor-field--inline {\n flex-direction: row;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.editor-field-row {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.editor-field-row > .editor-field {\n flex: 1 1 220px;\n}\n\n.editor-label {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.editor-required {\n color: var(--mj-status-error);\n}\n\n.editor-hint {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.editor-hint-inline {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n/* Segmented pickers (target type / routine type / frequency) */\n.editor-segmented {\n display: inline-flex;\n gap: 0;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n overflow: hidden;\n width: fit-content;\n}\n\n.editor-segmented--wrap {\n flex-wrap: wrap;\n}\n\n.editor-segment {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 14px;\n font-size: 13px;\n border: none;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background 0.12s ease, color 0.12s ease;\n}\n\n.editor-segment + .editor-segment {\n border-left: 1px solid var(--mj-border-default);\n}\n\n.editor-segment:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.editor-segment--active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n/* Schedule */\n.editor-schedule-detail {\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 12px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-subtle);\n border-radius: var(--mj-radius-md, 8px);\n}\n\n.editor-schedule-preview {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.editor-schedule-preview > i {\n color: var(--mj-status-success);\n}\n\n.editor-time-input {\n width: 130px;\n}\n\n.editor-inline-dropdown {\n min-width: 140px;\n}\n\n.editor-mono {\n font-family: var(--mj-font-mono, monospace);\n}\n\n/* Code editor container */\n.editor-code {\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n overflow: hidden;\n min-height: 90px;\n}\n\n/* Skills */\n.editor-skills {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.editor-skill-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 12px;\n font-size: 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full, 999px);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;\n}\n\n.editor-skill-chip:hover {\n border-color: var(--mj-border-strong);\n}\n\n.editor-skill-chip--selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.editor-skill-check {\n font-size: 10px;\n}\n\n/* Notifications */\n.editor-switches {\n gap: 24px;\n}\n\n.editor-recipients-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n}\n\n.editor-recipient-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px;\n border: 1px solid var(--mj-border-subtle);\n border-radius: var(--mj-radius-md, 8px);\n background: var(--mj-bg-surface);\n}\n\n.editor-recipient-order {\n display: flex;\n flex-direction: column;\n}\n\n.editor-recipient-mode {\n flex: 0 0 150px;\n}\n\n.editor-recipient-target {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.editor-recipient-channel {\n flex: 0 0 120px;\n}\n\n/* Footer \u2014 confirm on the LEFT, cancel on the RIGHT (MJ convention) */\n.editor-footer {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 0 4px 0;\n border-top: 1px solid var(--mj-border-default);\n position: sticky;\n bottom: 0;\n background: var(--mj-bg-surface);\n}\n\n/* Agent tree picker */\n.editor-selected-agent {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: var(--mj-radius-md, 8px);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 13px;\n font-weight: 600;\n width: fit-content;\n}\n\n.editor-selected-agent-hint {\n font-size: 11px;\n font-weight: 400;\n color: var(--mj-text-muted);\n}\n\n.editor-agent-tree {\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n max-height: 280px;\n overflow: auto;\n background: var(--mj-bg-surface);\n}\n\n/* Progressive-disclosure toggle between the basic path and the advanced sections */\n.editor-advanced-toggle {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 10px 12px;\n border: 1px dashed var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n text-align: left;\n}\n\n.editor-advanced-toggle:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.editor-advanced-toggle .editor-hint-inline {\n font-weight: 400;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n"] }]
|
|
1058
1058
|
}], null, { RoutineID: [{
|
|
1059
1059
|
type: Input
|
|
1060
1060
|
}], Saved: [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"new-routine.component.js","sourceRoot":"","sources":["../../src/lib/new-routine.component.ts","../../src/lib/new-routine.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAU,MAAM,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC1G,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,YAAY,EAAqB,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAqD,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACrH,OAAO,EACH,mBAAmB,EACnB,cAAc,EAGd,sBAAsB,EACtB,yBAAyB,EACzB,aAAa,EACb,mBAAmB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAEzE,OAAO,EACH,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,oBAAoB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,wBAAwB,EAA4C,MAAM,0BAA0B,CAAC;AAC9G,OAAO,EAAE,4BAA4B,EAAE,6BAA6B,EAAE,MAAM,wBAAwB,CAAC;;;;;;;;;;;;IC3BnG,8BAA4B;IAC1B,gCAAgE;IAClE,iBAAM;;;IAQI,0BAAI;IAAA,YAAW;IAAA,iBAAK;;;IAAhB,cAAW;IAAX,8BAAW;;;IAFnB,AADF,mCAA0B,aACE;IACxB,sIAEC;IAEL,AADE,iBAAK,EACI;;;IAJP,eAEC;IAFD,sCAEC;;;;IAeD,4CASkD;IAAhD,2OAAmB,kCAA2B,KAAC;IACjD,iBAAmB;;;IAHjB,AADA,AAJA,AADA,2DAAsC,0CACJ,kCAIR,oBACP;;;;IA6BnB,kCAE0C;IAAxC,2NAAS,uCAA6B,KAAC;IACvC,YACF;IAAA,iBAAS;;;;IAHP,iFAA8D;IAE9D,cACF;IADE,gDACF;;;;IASE,AADF,+BAA+C,eACjB;IAAA,yBAAS;IAAA,iBAAQ;IAC7C,4CAA+E;IAA7D,2UAA4B;IAAiC,iBAAmB;IAClG,gCAAiC;IAAA,+BAAe;IAClD,AADkD,iBAAO,EACnD;;;IAFc,eAA4B;IAA5B,qDAA4B;IAAsB,AAAX,AAAV,uBAAS,WAAW,WAAW;;;;IAM9E,AADF,+BAA+C,eACjB;IAAA,kBAAE;IAAA,iBAAQ;IACtC,iCAAmF;IAA7B,4TAA0B;IAAhF,iBAAmF;IACnF,gCAAiC;IAAA,yBAAS;IAC5C,AAD4C,iBAAO,EAC7C;;;IAFkD,eAA0B;IAA1B,mDAA0B;;;;IAMhF,AADF,+BAA+C,eACjB;IAAA,qBAAK;IAAA,iBAAQ;IACzC,uCAC0D;IAAhC,4UAA+B;IAAC,iBAAc;IACxE,gCAA4B;IAAA,kBAAE;IAAA,iBAAQ;IACtC,iCAAmF;IAA7B,4TAA0B;IAClF,AADE,iBAAmF,EAC/E;;;IAJwC,eAAyB;IACnE,AAD0C,8CAAyB,wBAC5C;IAAC,wDAA+B;IAEH,eAA0B;IAA1B,mDAA0B;;;;IAKhF,AADF,+BAA+C,eACjB;IAAA,sBAAM;IAAA,iBAAQ;IAC1C,uCAC2D;IAAjC,+UAAgC;IAAC,iBAAc;IACzE,gCAA4B;IAAA,kBAAE;IAAA,iBAAQ;IACtC,iCAAmF;IAA7B,6TAA0B;IAClF,AADE,iBAAmF,EAC/E;;;IAJwC,eAA0B;IACpE,AAD0C,+CAA0B,wBAC7C;IAAC,yDAAgC;IAEJ,eAA0B;IAA1B,mDAA0B;;;;IAKhF,AADF,8BAA0B,gBACuB;IAAA,+BAAe;IAAA,iBAAQ;IACtE,iCAC6D;IADK,mTAAqB;IAEzF,AAFE,iBAC6D,EACzD;;;IAF8D,eAAqB;IAArB,8CAAqB;;;IAuFjF,wBAAoD;;;;IAPxD,kCAGkC;IAAhC,yPAAS,gCAAqB,KAAC;IAC/B,oBAAsE;IACtE,YACA;IAAA,sIAAiC;IAGnC,iBAAS;;;;IARP,mFAA+D;IAC/D,+DAAyC;IAEtC,cAA8D;IAA9D,uEAA8D;IACjE,cACA;IADA,+CACA;IAAA,cAEC;IAFD,+DAEC;;;IAXP,AADF,8BAA0B,eACI;IAAA,8CAA8B;IAAA,iBAAQ;IAClE,+BAA2B;IACzB,sIAWC;IACH,iBAAM;IACN,+BAAyB;IAAA,iIAAiH;IAC5I,AAD4I,iBAAM,EAC5I;;;IAdF,eAWC;IAXD,kCAWC;;;IA6BH,+BAAyB;IAAA,sDAAsC;IAAA,iBAAM;;;;IAejE,uCACkF;IAAzB,+VAAwB;IAAC,iBAAc;;;;IAA9F,AAD2C,yCAAoB,wBACxC;IAAgC,8CAAwB;;;;IAEjF,iCAAsH;IAA1B,uVAAuB;IAAnH,iBAAsH;;;IAA1B,6CAAuB;;;;IAbnH,AADF,AADF,+BAAkC,cACI,iBAC0E;IAA/B,8OAAS,uCAAkB,CAAC,CAAC,KAAC;IACzG,wBAAsC;IACxC,iBAAS;IACT,kCAA4G;IAA9B,8OAAS,sCAAiB,CAAC,CAAC,KAAC;IACzG,wBAAwC;IAE5C,AADE,iBAAS,EACL;IACN,uCAC8F;IAApE,yTAAsB;IAAC,8PAAiB,qCAA0B,KAAC;IAAC,iBAAc;IAI1G,AAHF,kIAA2B,sGAGlB;IAGT,uCACoD;IAA1B,+TAAyB;IAAC,iBAAc;IAClE,mCAAgG;IAA7B,+OAAS,uCAAkB,KAAC;IAC7F,yBAAqC;IAEzC,AADE,iBAAS,EACL;;;;;;IApBwD,eAAkB;IAAlB,gDAAkB;IAGhB,eAAiB;IAAjB,kEAAiB;IAIpC,eAA6B;IACtE,AADyC,kDAA6B,wBAC/C;IAAC,4CAAsB;IAChD,cAKC;IALD,iDAKC;IAC6C,eAAuB;IACnE,AAD4C,4CAAuB,wBAC5C;IAAC,+CAAyB;;;;IAvHzD,AADF,kCAAgC,aACG;IAAA,wBAAuC;IAAC,wBAAO;IAAA,iBAAK;IAEnF,AADF,8BAA0B,gBAC8B;IAAA,2BAAW;IAAA,iBAAQ;IACzE,oCAC2C;IADqB,qUAAyB;IAE3F,AAD6C,iBAAW,EAClD;IAGJ,AADF,8BAA0B,eACI;IAAA,6BAAY;IAAA,iBAAQ;IAE9C,AADF,gCAA0E,kBAGlC;IAApC,8NAAuB,WAAW,KAAC;IACnC,yBAAiC;IAAC,4BACpC;IAAA,iBAAS;IACT,mCAEuC;IAArC,8NAAuB,YAAY,KAAC;IACpC,yBAA+B;IAAC,6BAClC;IACF,AADE,iBAAS,EACL;IACN,gCAAyB;IAAA,aAAqB;IAChD,AADgD,iBAAM,EAChD;IAGJ,AADF,+BAA0B,gBACI;IAAA,yBAAQ;IAAA,iBAAQ;IAC5C,wCAIyB;IAAvB,mUAAsB;IAE1B,AADE,iBAAc,EACV;IAIF,AADF,AADF,gCAA8B,cACF,iBAC0B;IAAA,uCAAsB;IAAA,iBAAQ;IAChF,kCAAgG;IAA7B,qUAA0B;IAC/F,AADE,iBAAgG,EAC5F;IAEJ,AADF,+BAA0B,iBACwB;IAAA,wCAAuB;IAAA,iBAAQ;IAC/E,kCAA4F;IAA3B,iUAAwB;IAE7F,AADE,AADE,iBAA4F,EACxF,EACF;IAGJ,AADF,+BAA0B,gBACI;IAAA,kDAAiC;IAAA,iBAAQ;IAEnE,AADF,gCAAyB,0BAEa;IADpB,4VAAiC;IAEnD,AADsC,iBAAiB,EACjD;IACN,gCAAyB;IAAA,uEAAsD;IACjF,AADiF,iBAAM,EACjF;IAEN,oHAA+B;IAoBjC,iBAAU;IAGR,AADF,mCAAgC,cACG;IAAA,yBAAgC;IAAC,+BAAa;IAAA,iBAAK;IAGlF,AADF,+BAA0B,gBACI;IAAA,0BAAS;IAAA,iBAAQ;IAC7C,wCACwD;IAA9B,iVAA6B;IACzD,AAD0D,iBAAc,EAClE;IAGJ,AADF,gCAA+D,qBACc;IAAhE,6UAA4B;IAAoC,iBAAY;IACvF,sCAAyE;IAA9D,6UAA4B;IACzC,AAD2E,iBAAY,EACjF;IAIF,AADF,AADF,+BAA0B,eACc,gBACR;IAAA,sCAAqB;IAAA,iBAAQ;IACzD,mCAAsE;IAAzB,yMAAS,qBAAc,KAAC;IACnE,yBAAgC;IAAC,gCACnC;IACF,AADE,iBAAS,EACL;IACN,qHAA+B;IAG/B,sIAwBC;IAEL,AADE,iBAAM,EACE;;;IA3H0D,eAAyB;IAAzB,kDAAyB;IAQrF,eAA4D;IAA5D,4EAA4D;IAK5D,eAA6D;IAA7D,6EAA6D;IAKxC,eAAqB;IAArB,4CAAqB;IAM5C,eAAwB;IACxB,AADA,6CAAwB,wBACD;IAEvB,+CAAsB;IAO6C,eAA0B;IAA1B,mDAA0B;IAI5B,eAAwB;IAAxB,iDAAwB;IAOzE,eAAiC;IAAjC,0DAAiC;IAMrD,eAmBC;IAnBD,0DAmBC;IAQc,eAA+B;IAC1C,AADW,oDAA+B,wBACnB;IAAC,sDAA6B;IAI5C,eAA4B;IAA5B,qDAA4B;IAC5B,cAA4B;IAA5B,qDAA4B;IAUvC,eAEC;IAFD,0DAEC;IACD,cAwBC;IAxBD,gCAwBC;;;IASD,wBAA2C;;;IAE3C,wBAAiC;;;;IApQzC,8BAA4B;IAE1B,wGAAmC;IAa/B,AADF,AADF,kCAAgC,aACJ,eACuB;IAAA,qBAAK;IAAA,+BAA8B;IAAA,iBAAC;IAAO,AAAP,iBAAO,EAAQ;IAClG,gCAAwH;IAAlE,mSAAkB;IAC1E,AADE,iBAAwH,EACpH;IAGJ,AADF,8BAA0B,gBACI;IAAA,sDAAqC;IAAA,gCAA8B;IAAA,kBAAC;IAAO,AAAP,iBAAO,EAAQ;IAC/G,mHAA2B;IAa3B,gCAAyB;IAAA,oIAA8G;IACzI,AADyI,iBAAM,EACzI;IAGJ,AADF,+BAA0B,iBAC0B;IAAA,yCAAwB;IAAA,iBAAQ;IAMlF,8CAO4C;IAN1C,oUAA4B;IAOhC,AAD8C,iBAAoB,EAC5D;IAGJ,AADF,+BAA0B,gBACI;IAAA,0BAAS;IAAA,iBAAQ;IAC7C,gCAAuG;IACrG,0GAMC;IAEL,AADE,iBAAM,EACF;IAEN,gCAAoC;IAkChC,AATA,AATA,AAPA,AAPA,+FAAkB,yEAOD,yEAOC,yEASC,wEASC;IAQtB,gCAAqC;IACnC,yBAA0C;IAAC,aAC7C;IAEJ,AADE,AADE,iBAAM,EACF,EACE;IAGV,mCACsC;IADe,uOAAsC;IAEzF,yBAAwG;IACxG,mCACA;IAAA,iCAAiC;IAAA,8HAA+E;IAClH,AADkH,iBAAO,EAChH;IAET,6FAAoB;IAqIlB,AADF,gCAA2B,kBAC2D;IAAjB,wLAAS,aAAM,KAAC;IAG/E,AAFF,oGAAgB,8EAEP;IAGT,aACF;IAAA,iBAAS;IACT,mCAAwF;IAAnB,wLAAS,eAAQ,KAAC;IAAC,uBAAM;IAElG,AADE,AADgG,iBAAS,EACnG,EACF;;;;IAxQJ,cAQC;IARD,6DAQC;IAMyD,eAAkB;IAAlB,2CAAkB;IAKxE,eAYC;IAZD,sDAYC;IAYC,eAA4B;IAA5B,qDAA4B;IAM5B,AADA,AADA,AADA,AADA,iEAA0C,6BACrB,4BACM,oBACR,iDACsB;IAMzC,eAMC;IAND,yCAMC;IAKH,eAwCC;IAxCD,sDAAA,QAAQ,qBAAR,OAAO,qBAAP,QAAQ,qBAAR,SAAS,qBAAT,UAAU,WAwCT;IAE4C,eAC7C;IAD6C,4EAC7C;IAMF,cAAmC;;IACf,cAAwC;IAAC,AAAzC,wDAAwC,wCAAuC;IAKrG,eAiIC;IAjID,+CAiIC;IAI8C,eAAqB;IAArB,0CAAqB;IAChE,cAIC;IAJD,2CAIC;IACD,eACF;IADE,kFACF;IAC+C,cAAqB;IAArB,0CAAqB;;AD/N1E;;;;;;;;;;;;;;;GAeG;AAOH,MAAM,OAAO,mBAAoB,SAAQ,oBAAoB;IACjD,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAChC,aAAa,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAEtD,kEAAkE;IAClE,mBAAmB;IACnB,kEAAkE;IAC1D,UAAU,GAAkB,IAAI,CAAC;IACzC,8DAA8D;IAC9D,IACW,SAAS,CAAC,KAAoB;QACrC,IAAI,KAAK,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;YAC5B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;YACxB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACnB,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;YACvB,CAAC;QACL,CAAC;IACL,CAAC;IACD,IAAW,SAAS;QAChB,OAAO,IAAI,CAAC,UAAU,CAAC;IAC3B,CAAC;IAED,0FAA0F;IAChF,KAAK,GAAG,IAAI,YAAY,EAAuB,CAAC;IAC1D,oDAAoD;IAC1C,SAAS,GAAG,IAAI,YAAY,EAAQ,CAAC;IAC/C,0EAA0E;IAChE,oBAAoB,GAAG,IAAI,YAAY,EAAiC,CAAC;IACnF,mFAAmF;IACzE,mBAAmB,GAAG,IAAI,YAAY,EAAgC,CAAC;IAEjF,kEAAkE;IAClE,aAAa;IACb,kEAAkE;IAC3D,IAAI,GAAG,EAAE,CAAC;IACV,WAAW,GAAG,EAAE,CAAC;IACxB,kEAAkE;IAC3D,QAAQ,GAAkB,IAAI,CAAC;IAC/B,cAAc,GAAG,EAAE,CAAC;IACpB,mBAAmB,GAAG,EAAE,CAAC;IACzB,gBAAgB,GAAa,EAAE,CAAC;IAChC,WAAW,GAAuC,WAAW,CAAC;IAE9D,YAAY,GAAmB,OAAO,CAAC;IAC9C,mDAAmD;IAC5C,cAAc,GAAG,CAAC,CAAC;IAC1B,yDAAyD;IAClD,YAAY,GAAG,OAAO,CAAC;IACvB,iBAAiB,GAAG,CAAC,CAAC;IACtB,kBAAkB,GAAG,CAAC,CAAC;IACvB,OAAO,GAAG,EAAE,CAAC;IAEb,QAAQ,GAAW,gBAAgB,EAAE,CAAC;IACtC,YAAY,GAAG,EAAE,CAAC;IAClB,UAAU,GAAG,EAAE,CAAC;IAEhB,eAAe,GAA2C,QAAQ,CAAC;IACnE,cAAc,GAAG,IAAI,CAAC;IACtB,cAAc,GAAG,KAAK,CAAC;IACvB,UAAU,GAAmB,EAAE,CAAC;IAEvC,kEAAkE;IAClE,mBAAmB;IACnB,kEAAkE;IAClE;;;;OAIG;IACI,YAAY,GAAG,KAAK,CAAC;IAErB,OAAO,GAAgC,IAAI,CAAC;IAC5C,WAAW,GAAiB,EAAE,CAAC;IAC/B,eAAe,GAAa,kBAAkB,EAAE,CAAC;IACjD,SAAS,GAAG,IAAI,CAAC;IACjB,QAAQ,GAAG,KAAK,CAAC;IACjB,gBAAgB,GAAa,EAAE,CAAC;IAEvC,mDAAmD;IAC5C,qBAAqB,GAAqB;QAC7C,UAAU,EAAE,yBAAyB;QACrC,YAAY,EAAE,MAAM;QACpB,aAAa,EAAE,UAAU;QACzB,WAAW,EAAE,oBAAoB;QACjC,OAAO,EAAE,UAAU;KACtB,CAAC;IACF,0FAA0F;IACnF,mBAAmB,CAA6B;IACvD,6CAA6C;IACtC,gBAAgB,GAAa,EAAE,CAAC;IAEvB,QAAQ,GAAG,cAAc,CAAC;IAC1B,gBAAgB,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/E,iBAAiB,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/F,mBAAmB,GAAoD;QACnF,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;QACpC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;QAClC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;QACpC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;QACtC,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,iBAAiB,EAAE;KAClD,CAAC;IACc,sBAAsB,GAAG;QACrC,EAAE,IAAI,EAAE,0BAA0B,EAAE,KAAK,EAAE,QAAQ,EAAE;QACrD,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,WAAW,EAAE;QAC/C,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,WAAW,EAAE;QAC/C,EAAE,IAAI,EAAE,wDAAwD,EAAE,KAAK,EAAE,UAAU,EAAE;KACxF,CAAC;IACc,cAAc,GAAG;QAC7B,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE;QAClC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;KACpC,CAAC;IACc,oBAAoB,GAAG;QACnC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE;QAClC,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,OAAO,EAAE;KAC7C,CAAC;IAEM,aAAa,GAA+B,IAAI,CAAC;IACjD,iBAAiB,GAAmC,EAAE,CAAC;IACvD,WAAW,GAAG,KAAK,CAAC;IAE5B,KAAK,CAAC,QAAQ;QACV,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;IACxB,CAAC;IAED,sEAAsE;IACtE,IAAW,MAAM;QACb,OAAO,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC;IACnC,CAAC;IAED,kDAAkD;IAClD,IAAW,YAAY;QACnB,OAAO,IAAI,CAAC,OAAO,EAAE,MAAM,IAAI,EAAE,CAAC;IACtC,CAAC;IAED,8DAA8D;IAC9D,IAAW,iBAAiB;QACxB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACjB,OAAO,EAAE,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1E,CAAC;IAED,kEAAkE;IAClE,IAAW,iBAAiB;QACxB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACjB,OAAO,mBAAmB,CAAC;QAC/B,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,mBAAmB,CAAC;IAC3F,CAAC;IAED,+DAA+D;IAC/D,IAAW,eAAe;QACtB,OAAO,sBAAsB,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,gDAAgD;IAChD,IAAW,eAAe;QACtB,OAAO,IAAI,CAAC,WAAW,KAAK,WAAW;YACnC,CAAC,CAAC,mEAAmE;YACrE,CAAC,CAAC,gIAAgI,CAAC;IAC3I,CAAC;IAED,wEAAwE;IACxE,kFAAkF;IAClF,IAAW,gBAAgB;QACvB,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,+FAA+F;IACrK,CAAC;IAEM,mBAAmB,CAAC,IAA8B;QACrD,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC5B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,gBAAgB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACvC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC5B,CAAC;IACL,CAAC;IAEM,eAAe,CAAC,IAAoB;QACvC,IAAI,IAAI,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;YAC7B,OAAO;QACX,CAAC;QACD,IAAI,IAAI,KAAK,UAAU,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YAC9C,mEAAmE;YACnE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QACpC,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAED,iEAAiE;IAC1D,WAAW,CAAC,OAAe;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACrD,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YACb,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;QACjF,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,gBAAgB,GAAG,CAAC,GAAG,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAChE,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAEM,eAAe,CAAC,OAAe;QAClC,OAAO,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACnD,CAAC;IAED,kEAAkE;IAClE,aAAa;IACb,kEAAkE;IAC3D,YAAY;QACf,IAAI,CAAC,UAAU,GAAG;YACd,GAAG,IAAI,CAAC,UAAU;YAClB,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE;SAC5E,CAAC;QACF,KAAK,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAClC,CAAC;IAEM,eAAe,CAAC,KAAa;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,GAAG,EAAE,MAAM,EAAE,CAAC;YACd,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC;IACpE,CAAC;IAED,uEAAuE;IAChE,aAAa,CAAC,KAAa,EAAE,KAAa;QAC7C,MAAM,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;QAC7B,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;YACjD,OAAO;QACX,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QAClC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IAC3B,CAAC;IAED,iEAAiE;IAC1D,qBAAqB,CAAC,GAAiB;QAC1C,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACtB,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC;YACf,KAAK,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAClC,CAAC;aAAM,CAAC;YACJ,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC;QACtB,CAAC;IACL,CAAC;IAED,kEAAkE;IAClE,gBAAgB;IAChB,kEAAkE;IAC3D,MAAM;QACT,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IAC1B,CAAC;IAEM,KAAK,CAAC,IAAI;QACb,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,OAAO;QACX,CAAC;QACD,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QACxC,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YACxB,OAAO;QACX,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QACxB,IAAI,CAAC;YACD,MAAM,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC;YAC7B,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;YAC3B,MAAM,OAAO,GACT,IAAI,CAAC,aAAa;gBAClB,CAAC,MAAM,CAAC,CAAC,eAAe,CAAsB,mBAAmB,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;YACvF,IAAI,KAAK,EAAE,CAAC;gBACR,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC;YACtC,CAAC;YAED,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAChC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;YACtD,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;YACvC,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC;YAC7B,mCAAmC;YACnC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAkB,CAAC;YAC3C,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;YAC5D,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;YAClE,OAAO,CAAC,iBAAiB,GAAG,iBAAiB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACrE,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YAC1C,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;YACjC,OAAO,CAAC,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACvD,OAAO,CAAC,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACnD,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;YAC/C,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;YAC7C,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;YAE7C,IAAI,KAAK,EAAE,CAAC;gBACR,MAAM,UAAU,GAAG,IAAI,6BAA6B,CAAC,OAAO,CAAC,CAAC;gBAC9D,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC3C,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;oBACpB,OAAO;gBACX,CAAC;YACL,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YACnC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,IAAI,CAAC,gBAAgB,GAAG;oBACpB,gBAAgB,OAAO,CAAC,YAAY,EAAE,eAAe,IAAI,eAAe,EAAE;iBAC7E,CAAC;gBACF,OAAO;YACX,CAAC;YAED,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YAC3D,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC;gBACxC,OAAO;YACX,CAAC;YAED,IAAI,KAAK,EAAE,CAAC;gBACR,uEAAuE;gBACvE,wEAAwE;gBACxE,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;gBAC3C,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,4BAA4B,CAAC,OAAO,CAAC,CAAC,CAAC;YAC7E,CAAC;YAED,IAAI,CAAC,aAAa,CAAC,wBAAwB,CACvC,KAAK,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,WAAW,EACjE,SAAS,EACT,IAAI,CACP,CAAC;YACF,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC5B,CAAC;IACL,CAAC;IAED,kEAAkE;IAClE,YAAY;IACZ,kEAAkE;IAC1D,MAAM;QACV,OAAO,iBAAiB,CAAC,mBAAmB,CAAoB,IAAI,CAAC,aAAa,EAAE,iBAAiB,CAAsB,CAAC;IAChI,CAAC;IAED,+FAA+F;IACvF,oBAAoB;QACxB,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;eAClC,IAAI,CAAC,WAAW,KAAK,YAAY;eACjC,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;eAC1C,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC;eAChC,IAAI,CAAC,QAAQ,KAAK,gBAAgB,EAAE;eACpC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;eACnC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;eACjC,IAAI,CAAC,eAAe,KAAK,QAAQ;eACjC,CAAC,IAAI,CAAC,cAAc;eACpB,IAAI,CAAC,cAAc;eACnB,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;IACtC,CAAC;IAEO,KAAK,CAAC,MAAM;QAChB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QACxB,IAAI,CAAC;YACD,MAAM,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC;YAC7B,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAChC,wBAAwB,CAAC,CAAC,CAAC;gBAC3B,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;aAChD,CAAC,CAAC;YACH,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;YACvB,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC;YAC7B,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBAClB,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACzC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACpD,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,WAAW,EAAE,CAAC;gBACnB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;YAC9B,CAAC;YACD,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,CAAC;gBACjD,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACnC,CAAC;QACL,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,IAAI,CAAC,gBAAgB,GAAG;gBACpB,8BAA8B,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE;aACnF,CAAC;QACN,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC5B,CAAC;IACL,CAAC;IAED;;;;OAIG;IACK,oBAAoB,CAAC,QAA2B;QACpD,MAAM,eAAe,GAAG,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAC;QAC9D,MAAM,OAAO,GAAG,CAAC,iBAAiB,EAAE,kBAAkB,CAAC,CAAC;QACxD,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChE,OAAO,CAAC,IAAI,CAAC,qCAAqC,MAAM,IAAI,CAAC,CAAC;QAClE,CAAC;QACD,IAAI,CAAC,mBAAmB,GAAG;YACvB,UAAU,EAAE,eAAe;YAC3B,WAAW,EAAE,YAAY;YACzB,YAAY,EAAE,MAAM;YACpB,SAAS,EAAE,WAAW;YACtB,WAAW,EAAE,mBAAmB;YAChC,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;YAClC,OAAO,EAAE,UAAU;SACtB,CAAC;IACN,CAAC;IAED,iFAAiF;IACzE,sBAAsB,CAAC,QAA2B;QACtD,2EAA2E;QAC3E,oEAAoE;QACpE,MAAM,MAAM,GAAG,YAAY,CAAC,mBAAmB,CAAe,QAAQ,EAAE,YAAY,CAAiB,CAAC;QACtG,OAAO,MAAM,CAAC,UAAU;aACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC;aAC1D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC;IAEO,WAAW;QACf,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QACtB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC,mBAAmB,GAAG,EAAE,CAAC;QAC9B,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC;QAC5B,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;QACxB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC;QAC5B,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,kBAAkB,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,QAAQ,GAAG,gBAAgB,EAAE,CAAC;QACnC,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC;QAChC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;IACzB,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,SAAiB;QACxC,MAAM,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC;QAC7B,iFAAiF;QACjF,8DAA8D;QAC9D,IAAI,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;QAC9D,IAAI,CAAC,OAAO,EAAE,CAAC;YACX,MAAM,YAAY,GAAG,MAAM,CAAC,CAAC,eAAe,CAAsB,mBAAmB,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;YACtG,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAClD,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3C,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,CAAC;YACX,IAAI,CAAC,gBAAgB,GAAG,CAAC,WAAW,SAAS,uBAAuB,CAAC,CAAC;YACtE,IAAI,CAAC,WAAW,EAAE,CAAC;YACnB,OAAO;QACX,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;QAC7C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,EAAE,CAAC;QACnD,IAAI,CAAC,mBAAmB,GAAG,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC;QACzD,IAAI,CAAC,gBAAgB,GAAG,aAAa,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACjE,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACvC,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;QAC5D,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,YAAY,GAAG,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACrD,IAAI,CAAC,UAAU,GAAG,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACjD,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;QAC/C,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;QAC7C,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;QAC7C,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAEO,SAAS,CAAC,QAAsB;QACpC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC;QAClC,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC;QACtC,IAAI,CAAC,YAAY,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;QAClH,IAAI,CAAC,iBAAiB,GAAG,QAAQ,CAAC,SAAS,CAAC;QAC5C,IAAI,CAAC,kBAAkB,GAAG,QAAQ,CAAC,UAAU,CAAC;QAC9C,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC;IAChC,CAAC;IAEO,SAAS;QACb,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAiB;YAC3B,IAAI,EAAE,IAAI,CAAC,YAAY;YACvB,MAAM,EAAE,IAAI,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,MAAM;YACvF,IAAI,EAAE,IAAI;YACV,SAAS,EAAE,IAAI,CAAC,iBAAiB;YACjC,UAAU,EAAE,IAAI,CAAC,kBAAkB;YACnC,GAAG,EAAE,IAAI,CAAC,OAAO;SACpB,CAAC;QACF,OAAO,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IAEO,iBAAiB;QACrB,MAAM,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAClC,CAAC;QACD,OAAO;YACH,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YACvD,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;SACnD,CAAC;IACN,CAAC;IAEO,WAAW,CAAC,MAAc;QAC9B,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,8EAA8E;IACtE,iBAAiB,CAAC,SAAiB;QACvC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE;aAC1B,oBAAoB,CAAC,SAAS,CAAC;aAC/B,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACd,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,MAAgB,CAAC,CAAC,CAAE,OAAiB;YAC5D,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;YACzB,OAAO,EAAE,MAAM,CAAC,OAAO;SAC1B,CAAC,CAAC,CAAC;IACZ,CAAC;IAED,kFAAkF;IAC1E,KAAK,CAAC,iBAAiB;QAC3B,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,OAAO;QACX,CAAC;QACD,MAAM,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC;QAC7B,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAC3B;YACI,UAAU,EAAE,WAAW;YACvB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC;YAC/B,WAAW,EAAE,YAAY;YACzB,OAAO,EAAE,UAAU;YACnB,UAAU,EAAE,QAAQ;SACvB,EACD,CAAC,CAAC,WAAW,CAChB,CAAC;QACF,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;YACxC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC5B,CAAC;IACL,CAAC;IAEO,QAAQ;QACZ,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACrC,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACjB,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QAC7D,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,KAAK,UAAU,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/E,MAAM,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAC;QAC3F,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACzC,CAAC;QACD,MAAM,YAAY,GAAG,oBAAoB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACpE,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;YACtB,MAAM,CAAC,IAAI,CAAC,uCAAuC,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACjD,IAAI,OAAO,IAAI,KAAK,IAAI,KAAK,CAAC,OAAO,EAAE,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAC3D,MAAM,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;YAC/B,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;gBACrC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;YAC/F,CAAC;YACD,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvD,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;YACpE,CAAC;QACL,CAAC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,oFAAoF;IAC5E,KAAK,CAAC,cAAc,CAAC,OAA4B;QACrD,MAAM,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC;QAC7B,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC1C,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;YACtC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CACP,iCAAiC,MAAM,CAAC,YAAY,EAAE,eAAe,IAAI,eAAe,EAAE,CAC7F,CAAC;YACN,CAAC;QACL,CAAC;QACD,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAE5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,MAAM,GACR,GAAG,CAAC,MAAM;gBACV,CAAC,MAAM,CAAC,CAAC,eAAe,CAA+B,6BAA6B,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;YAC1G,MAAM,CAAC,SAAS,GAAG,OAAO,CAAC,EAAE,CAAC;YAC9B,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;YACxD,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YAC9D,MAAM,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;YAC7B,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC;YACpB,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAClC,IAAI,KAAK,EAAE,CAAC;gBACR,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;YACxB,CAAC;iBAAM,CAAC;gBACJ,MAAM,CAAC,IAAI,CACP,4BAA4B,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,YAAY,EAAE,eAAe,IAAI,eAAe,EAAE,CAClG,CAAC;YACN,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;yPA5mBQ,mBAAmB,yBAAnB,mBAAmB;6DAAnB,mBAAmB;YChE9B,AAJF,qFAAiB,iEAIR;;YAJT,uCAgRC;;;iFD5MY,mBAAmB;cAN/B,SAAS;6BACM,KAAK,YACP,gBAAgB;;kBAazB,KAAK;;kBAcL,MAAM;;kBAEN,MAAM;;kBAEN,MAAM;;kBAEN,MAAM;;kFA7BE,mBAAmB","sourcesContent":["import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, inject } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { CompositeKey, IMetadataProvider, RunView } from '@memberjunction/core';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\nimport { MJUserRoutineEntity, MJUserRoutineRecipientEntity, UserRoutineEngine } from '@memberjunction/core-entities';\nimport {\n BuildCronExpression,\n CRON_DAY_NAMES,\n CronPresetKind,\n CronSchedule,\n DescribeCronExpression,\n IsPlausibleCronExpression,\n NormalizeUUID,\n ParseCronExpression,\n} from '@memberjunction/global';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { AfterNodeSelectEventArgs, TreeBranchConfig, TreeLeafConfig } from '@memberjunction/ng-trees';\nimport {\n FromDateTimeLocal,\n GetLocalTimezone,\n GetTimezoneOptions,\n IsPlausibleEmail,\n ParseSkillIDs,\n SerializeSkillIDs,\n ToDateTimeLocal,\n ValidateOptionalJson,\n} from './routine-ui-helpers';\nimport { LoadRoutineTargetCatalog, RoutineSkillOption, RoutineTargetCatalog } from './routine-target-catalog';\nimport { AfterRoutineCreatedEventArgs, BeforeRoutineCreatedEventArgs } from './user-routines-events';\n\n/** One editable recipient row (existing rows carry their entity for update/delete). */\ninterface RecipientRow {\n Entity: MJUserRoutineRecipientEntity | null;\n Mode: 'user' | 'email';\n UserID: string | null;\n Email: string;\n Channel: MJUserRoutineRecipientEntity['Channel'];\n}\n\n/** Minimal user shape for the recipient user picker. */\ninterface UserOption {\n ID: string;\n Name: string;\n Email: string | null;\n}\n\n/**\n * Create/edit form for a User Routine. Routines run an AI AGENT on a schedule\n * (TargetType is implicitly 'Agent') — the agent is chosen from a categorical tree\n * grouped by Agent Category, showing each agent's own IconClass, with Realtime-type\n * agents excluded (interactive-only). Also covers the initial message, optional JSON\n * payload, AI Skills pre-activation, cron presets + advanced escape hatch, IANA\n * timezone, activation window, notification settings, and the ordered recipients list.\n *\n * Reusable (Generic) component: no Router, no page chrome. The host mounts it\n * (slide-in / dialog / inline), passes `RoutineID` (null = create), and reacts to\n * `Saved` / `Cancelled` plus the cancelable `BeforeRoutineCreated` /\n * `AfterRoutineCreated` pair for new routines. All persistence flows through MJ\n * entity objects with explicit `Save()` boolean checks; failures surface\n * `LatestResult.CompleteMessage`. Cached routine/recipient data comes from\n * {@link UserRoutineEngine}.\n */\n@Component({\n standalone: false,\n selector: 'mj-new-routine',\n templateUrl: './new-routine.component.html',\n styleUrls: ['./new-routine.component.css'],\n})\nexport class NewRoutineComponent extends BaseAngularComponent implements OnInit {\n private cdr = inject(ChangeDetectorRef);\n private notifications = inject(MJNotificationService);\n\n // ---------------------------------------------------------------\n // Inputs / Outputs\n // ---------------------------------------------------------------\n private _routineID: string | null = null;\n /** ID of the routine to edit, or null to create a new one. */\n @Input()\n public set RoutineID(value: string | null) {\n if (value !== this._routineID) {\n this._routineID = value;\n if (this.initialized) {\n void this.reload();\n }\n }\n }\n public get RoutineID(): string | null {\n return this._routineID;\n }\n\n /** Emitted after a successful save (routine + recipients persisted) — create AND edit. */\n @Output() Saved = new EventEmitter<MJUserRoutineEntity>();\n /** Emitted when the user cancels without saving. */\n @Output() Cancelled = new EventEmitter<void>();\n /** Cancelable: fires before a NEW routine is saved for the first time. */\n @Output() BeforeRoutineCreated = new EventEmitter<BeforeRoutineCreatedEventArgs>();\n /** Informational: fires after a new routine (and its recipients) was persisted. */\n @Output() AfterRoutineCreated = new EventEmitter<AfterRoutineCreatedEventArgs>();\n\n // ---------------------------------------------------------------\n // Form state\n // ---------------------------------------------------------------\n public Name = '';\n public Description = '';\n /** The selected agent's ID (TargetType is implicitly 'Agent'). */\n public TargetID: string | null = null;\n public InitialMessage = '';\n public StartingPayloadText = '';\n public SelectedSkillIDs: string[] = [];\n public RoutineType: MJUserRoutineEntity['RoutineType'] = 'Scheduled';\n\n public ScheduleKind: CronPresetKind = 'daily';\n /** Minute past each hour for the hourly preset. */\n public ScheduleMinute = 0;\n /** \"HH:MM\" run time for daily/weekly/monthly presets. */\n public ScheduleTime = '09:00';\n public ScheduleDayOfWeek = 1;\n public ScheduleDayOfMonth = 1;\n public RawCron = '';\n\n public Timezone: string = GetLocalTimezone();\n public StartAtLocal = '';\n public EndAtLocal = '';\n\n public NotifyCondition: MJUserRoutineEntity['NotifyCondition'] = 'Always';\n public NotifyViaInApp = true;\n public NotifyViaEmail = false;\n public Recipients: RecipientRow[] = [];\n\n // ---------------------------------------------------------------\n // Options / status\n // ---------------------------------------------------------------\n /**\n * Progressive disclosure: the basic view (name / agent / message / frequency)\n * covers the 80% path; everything else lives behind this toggle. Auto-expands\n * when editing a routine that already uses advanced settings.\n */\n public ShowAdvanced = false;\n\n public Catalog: RoutineTargetCatalog | null = null;\n public UserOptions: UserOption[] = [];\n public TimezoneOptions: string[] = GetTimezoneOptions();\n public IsLoading = true;\n public IsSaving = false;\n public ValidationErrors: string[] = [];\n\n /** Tree config for the agent-category branches. */\n public AgentTreeBranchConfig: TreeBranchConfig = {\n EntityName: 'MJ: AI Agent Categories',\n DisplayField: 'Name',\n ParentIDField: 'ParentID',\n DefaultIcon: 'fa-solid fa-folder',\n OrderBy: 'Name ASC',\n };\n /** Tree config for the pickable agents (built at load time — excludes Realtime types). */\n public AgentTreeLeafConfig: TreeLeafConfig | undefined;\n /** Tree selection binding (single agent). */\n public SelectedAgentIDs: string[] = [];\n\n public readonly DayNames = CRON_DAY_NAMES;\n public readonly DayOfWeekOptions = CRON_DAY_NAMES.map((name, i) => ({ text: name, value: i }));\n public readonly DayOfMonthOptions = Array.from({ length: 31 }, (_, i) => ({ text: `${i + 1}`, value: i + 1 }));\n public readonly ScheduleKindOptions: Array<{ Value: CronPresetKind; Label: string }> = [\n { Value: 'hourly', Label: 'Hourly' },\n { Value: 'daily', Label: 'Daily' },\n { Value: 'weekly', Label: 'Weekly' },\n { Value: 'monthly', Label: 'Monthly' },\n { Value: 'advanced', Label: 'Advanced (cron)' },\n ];\n public readonly NotifyConditionOptions = [\n { text: 'Always — after every run', value: 'Always' },\n { text: 'On success only', value: 'OnSuccess' },\n { text: 'On failure only', value: 'OnFailure' },\n { text: 'On change — when the result differs from the prior run', value: 'OnChange' },\n ];\n public readonly ChannelOptions = [\n { text: 'In-app', value: 'InApp' },\n { text: 'Email', value: 'Email' },\n ];\n public readonly RecipientModeOptions = [\n { text: 'MJ user', value: 'user' },\n { text: 'External email', value: 'email' },\n ];\n\n private editingEntity: MJUserRoutineEntity | null = null;\n private deletedRecipients: MJUserRoutineRecipientEntity[] = [];\n private initialized = false;\n\n async ngOnInit(): Promise<void> {\n this.initialized = true;\n await this.reload();\n }\n\n /** True when editing an existing routine (vs. creating a new one). */\n public get IsEdit(): boolean {\n return this._routineID != null;\n }\n\n /** Active skills available for pre-activation. */\n public get SkillOptions(): RoutineSkillOption[] {\n return this.Catalog?.Skills ?? [];\n }\n\n /** Name of the currently selected agent (empty when none). */\n public get SelectedAgentName(): string {\n if (!this.TargetID) {\n return '';\n }\n return this.Catalog?.NameByID.get(NormalizeUUID(this.TargetID)) ?? '';\n }\n\n /** IconClass of the currently selected agent (robot fallback). */\n public get SelectedAgentIcon(): string {\n if (!this.TargetID) {\n return 'fa-solid fa-robot';\n }\n return this.Catalog?.IconByID.get(NormalizeUUID(this.TargetID)) ?? 'fa-solid fa-robot';\n }\n\n /** Live human-readable preview of the schedule being built. */\n public get SchedulePreview(): string {\n return DescribeCronExpression(this.buildCron());\n }\n\n /** Helper text under the RoutineType toggle. */\n public get RoutineTypeHelp(): string {\n return this.RoutineType === 'Scheduled'\n ? 'Runs on the schedule and notifies per the notification condition.'\n : 'Runs on the schedule and hashes each result — pair with the \"On change\" condition to be notified only when the result changes.';\n }\n\n /** Handles agent selection from the category tree (leaf nodes only). */\n /** The selected agent as a CompositeKey for the tree-dropdown's Value binding. */\n public get SelectedAgentKey(): CompositeKey | null {\n return this.TargetID ? CompositeKey.FromID(this.TargetID) : null; // first-pk-ok: TargetID is an MJ: AI Agents record (agent tree leaf) — core entity keyed by ID\n }\n\n public OnAgentNodeSelected(args: AfterNodeSelectEventArgs): void {\n if (args.Node.Type === 'leaf') {\n this.TargetID = args.Node.ID;\n this.SelectedAgentIDs = [args.Node.ID];\n this.cdr.markForCheck();\n }\n }\n\n public SetScheduleKind(kind: CronPresetKind): void {\n if (kind === this.ScheduleKind) {\n return;\n }\n if (kind === 'advanced' && !this.RawCron.trim()) {\n // Seed the advanced box from the current preset so nothing is lost\n this.RawCron = this.buildCron();\n }\n this.ScheduleKind = kind;\n this.cdr.markForCheck();\n }\n\n /** Toggles a skill in/out of the RequestedSkillIDs selection. */\n public ToggleSkill(skillID: string): void {\n const index = this.SelectedSkillIDs.indexOf(skillID);\n if (index >= 0) {\n this.SelectedSkillIDs = this.SelectedSkillIDs.filter((id) => id !== skillID);\n } else {\n this.SelectedSkillIDs = [...this.SelectedSkillIDs, skillID];\n }\n this.cdr.markForCheck();\n }\n\n public IsSkillSelected(skillID: string): boolean {\n return this.SelectedSkillIDs.includes(skillID);\n }\n\n // ---------------------------------------------------------------\n // Recipients\n // ---------------------------------------------------------------\n public AddRecipient(): void {\n this.Recipients = [\n ...this.Recipients,\n { Entity: null, Mode: 'user', UserID: null, Email: '', Channel: 'InApp' },\n ];\n void this.ensureUserOptions();\n }\n\n public RemoveRecipient(index: number): void {\n const row = this.Recipients[index];\n if (row?.Entity) {\n this.deletedRecipients.push(row.Entity);\n }\n this.Recipients = this.Recipients.filter((_, i) => i !== index);\n }\n\n /** Moves a recipient up/down — the saved Sequence is the row index. */\n public MoveRecipient(index: number, delta: -1 | 1): void {\n const target = index + delta;\n if (target < 0 || target >= this.Recipients.length) {\n return;\n }\n const next = [...this.Recipients];\n [next[index], next[target]] = [next[target], next[index]];\n this.Recipients = next;\n }\n\n /** When the row's mode flips, clear the other identity field. */\n public OnRecipientModeChange(row: RecipientRow): void {\n if (row.Mode === 'user') {\n row.Email = '';\n void this.ensureUserOptions();\n } else {\n row.UserID = null;\n }\n }\n\n // ---------------------------------------------------------------\n // Save / cancel\n // ---------------------------------------------------------------\n public Cancel(): void {\n this.Cancelled.emit();\n }\n\n public async Save(): Promise<void> {\n if (this.IsSaving) {\n return;\n }\n this.ValidationErrors = this.validate();\n if (this.ValidationErrors.length > 0) {\n this.cdr.markForCheck();\n return;\n }\n\n this.IsSaving = true;\n this.cdr.markForCheck();\n try {\n const p = this.ProviderToUse;\n const isNew = !this.IsEdit;\n const routine =\n this.editingEntity ??\n (await p.GetEntityObject<MJUserRoutineEntity>('MJ: User Routines', p.CurrentUser));\n if (isNew) {\n routine.UserID = p.CurrentUser.ID;\n }\n\n routine.Name = this.Name.trim();\n routine.Description = this.Description.trim() || null;\n routine.RoutineType = this.RoutineType;\n routine.TargetType = 'Agent';\n // Validated non-null in validate()\n routine.TargetID = this.TargetID as string;\n routine.InitialMessage = this.InitialMessage.trim() || null;\n routine.StartingPayload = this.StartingPayloadText.trim() || null;\n routine.RequestedSkillIDs = SerializeSkillIDs(this.SelectedSkillIDs);\n routine.CronExpression = this.buildCron();\n routine.Timezone = this.Timezone;\n routine.StartAt = FromDateTimeLocal(this.StartAtLocal);\n routine.EndAt = FromDateTimeLocal(this.EndAtLocal);\n routine.NotifyCondition = this.NotifyCondition;\n routine.NotifyViaInApp = this.NotifyViaInApp;\n routine.NotifyViaEmail = this.NotifyViaEmail;\n\n if (isNew) {\n const beforeArgs = new BeforeRoutineCreatedEventArgs(routine);\n this.BeforeRoutineCreated.emit(beforeArgs);\n if (beforeArgs.Cancel) {\n return;\n }\n }\n\n const saved = await routine.Save();\n if (!saved) {\n this.ValidationErrors = [\n `Save failed: ${routine.LatestResult?.CompleteMessage ?? 'unknown error'}`,\n ];\n return;\n }\n\n const recipientErrors = await this.saveRecipients(routine);\n if (recipientErrors.length > 0) {\n this.ValidationErrors = recipientErrors;\n return;\n }\n\n if (isNew) {\n // Re-scope the engine's dependent (recipients/runs) configs to include\n // the new routine — their client-side filter is a Config-time snapshot.\n await this.engine().Refresh(p.CurrentUser);\n this.AfterRoutineCreated.emit(new AfterRoutineCreatedEventArgs(routine));\n }\n\n this.notifications.CreateSimpleNotification(\n isNew ? `'${routine.Name}' created` : `'${routine.Name}' updated`,\n 'success',\n 3000\n );\n this.Saved.emit(routine);\n } finally {\n this.IsSaving = false;\n this.cdr.markForCheck();\n }\n }\n\n // ---------------------------------------------------------------\n // Internals\n // ---------------------------------------------------------------\n private engine(): UserRoutineEngine {\n return UserRoutineEngine.GetProviderInstance<UserRoutineEngine>(this.ProviderToUse, UserRoutineEngine) as UserRoutineEngine;\n }\n\n /** True when the loaded routine differs from the basic-path defaults in any advanced field. */\n private usesAdvancedSettings(): boolean {\n return this.Description.trim().length > 0\n || this.RoutineType === 'Monitoring'\n || this.StartingPayloadText.trim().length > 0\n || this.SelectedSkillIDs.length > 0\n || this.Timezone !== GetLocalTimezone()\n || this.StartAtLocal.trim().length > 0\n || this.EndAtLocal.trim().length > 0\n || this.NotifyCondition !== 'Always'\n || !this.NotifyViaInApp\n || this.NotifyViaEmail\n || this.Recipients.length > 0;\n }\n\n private async reload(): Promise<void> {\n this.IsLoading = true;\n this.ValidationErrors = [];\n this.deletedRecipients = [];\n this.cdr.markForCheck();\n try {\n const p = this.ProviderToUse;\n const [catalog] = await Promise.all([\n LoadRoutineTargetCatalog(p),\n this.engine().Config(false, p.CurrentUser, p),\n ]);\n this.Catalog = catalog;\n this.buildAgentTreeConfig(p);\n if (this._routineID) {\n await this.loadExisting(this._routineID);\n this.ShowAdvanced = this.usesAdvancedSettings();\n } else {\n this.resetForNew();\n this.ShowAdvanced = false;\n }\n if (this.Recipients.some((r) => r.Mode === 'user')) {\n await this.ensureUserOptions();\n }\n } catch (e) {\n this.ValidationErrors = [\n `Failed to load the editor: ${e instanceof Error ? e.message : 'unknown error'}`,\n ];\n } finally {\n this.IsLoading = false;\n this.cdr.markForCheck();\n }\n }\n\n /**\n * Builds the agent tree leaf config: Active, root-level agents only, EXCLUDING\n * agents whose type is the Realtime agent type. The exclusion is expressed as an\n * inline NOT IN list of type IDs resolved from metadata BY NAME (never hardcoded).\n */\n private buildAgentTreeConfig(provider: IMetadataProvider): void {\n const realtimeTypeIDs = this.resolveRealtimeTypeIDs(provider);\n const filters = [`Status='Active'`, `ParentID IS NULL`];\n if (realtimeTypeIDs.length > 0) {\n const inList = realtimeTypeIDs.map((id) => `'${id}'`).join(',');\n filters.push(`(TypeID IS NULL OR TypeID NOT IN (${inList}))`);\n }\n this.AgentTreeLeafConfig = {\n EntityName: 'MJ: AI Agents',\n ParentField: 'CategoryID',\n DisplayField: 'Name',\n IconField: 'IconClass',\n DefaultIcon: 'fa-solid fa-robot',\n ExtraFilter: filters.join(' AND '),\n OrderBy: 'Name ASC',\n };\n }\n\n /** Realtime agent-type IDs resolved from the cached AI metadata by type NAME. */\n private resolveRealtimeTypeIDs(provider: IMetadataProvider): string[] {\n // The catalog load above already Config'd AIEngineBase for this provider —\n // reuse its cached AgentTypes through the provider-scoped instance.\n const engine = AIEngineBase.GetProviderInstance<AIEngineBase>(provider, AIEngineBase) as AIEngineBase;\n return engine.AgentTypes\n .filter((t) => t.Name?.trim().toLowerCase() === 'realtime')\n .map((t) => t.ID);\n }\n\n private resetForNew(): void {\n this.editingEntity = null;\n this.Name = '';\n this.Description = '';\n this.TargetID = null;\n this.SelectedAgentIDs = [];\n this.InitialMessage = '';\n this.StartingPayloadText = '';\n this.SelectedSkillIDs = [];\n this.RoutineType = 'Scheduled';\n this.ScheduleKind = 'daily';\n this.ScheduleMinute = 0;\n this.ScheduleTime = '09:00';\n this.ScheduleDayOfWeek = 1;\n this.ScheduleDayOfMonth = 1;\n this.RawCron = '';\n this.Timezone = GetLocalTimezone();\n this.StartAtLocal = '';\n this.EndAtLocal = '';\n this.NotifyCondition = 'Always';\n this.NotifyViaInApp = true;\n this.NotifyViaEmail = false;\n this.Recipients = [];\n }\n\n private async loadExisting(routineID: string): Promise<void> {\n const p = this.ProviderToUse;\n // Prefer the engine's cached entity; fall back to a direct load (e.g., deep link\n // into a routine saved elsewhere before the cache refreshed).\n let routine = this.engine().GetRoutineByID(routineID) ?? null;\n if (!routine) {\n const loadedEntity = await p.GetEntityObject<MJUserRoutineEntity>('MJ: User Routines', p.CurrentUser);\n const loaded = await loadedEntity.Load(routineID);\n routine = loaded ? loadedEntity : null;\n }\n if (!routine) {\n this.ValidationErrors = [`Routine ${routineID} could not be loaded.`];\n this.resetForNew();\n return;\n }\n this.editingEntity = routine;\n this.Name = routine.Name;\n this.Description = routine.Description ?? '';\n this.TargetID = routine.TargetID;\n this.SelectedAgentIDs = routine.TargetID ? [routine.TargetID] : [];\n this.InitialMessage = routine.InitialMessage ?? '';\n this.StartingPayloadText = routine.StartingPayload ?? '';\n this.SelectedSkillIDs = ParseSkillIDs(routine.RequestedSkillIDs);\n this.RoutineType = routine.RoutineType;\n this.applyCron(ParseCronExpression(routine.CronExpression));\n this.Timezone = routine.Timezone;\n this.StartAtLocal = ToDateTimeLocal(routine.StartAt);\n this.EndAtLocal = ToDateTimeLocal(routine.EndAt);\n this.NotifyCondition = routine.NotifyCondition;\n this.NotifyViaInApp = routine.NotifyViaInApp;\n this.NotifyViaEmail = routine.NotifyViaEmail;\n this.loadRecipientRows(routineID);\n }\n\n private applyCron(schedule: CronSchedule): void {\n this.ScheduleKind = schedule.Kind;\n this.ScheduleMinute = schedule.Minute;\n this.ScheduleTime = `${schedule.Hour.toString().padStart(2, '0')}:${schedule.Minute.toString().padStart(2, '0')}`;\n this.ScheduleDayOfWeek = schedule.DayOfWeek;\n this.ScheduleDayOfMonth = schedule.DayOfMonth;\n this.RawCron = schedule.Raw;\n }\n\n private buildCron(): string {\n const { hour, minute } = this.parseScheduleTime();\n const schedule: CronSchedule = {\n Kind: this.ScheduleKind,\n Minute: this.ScheduleKind === 'hourly' ? this.clampMinute(this.ScheduleMinute) : minute,\n Hour: hour,\n DayOfWeek: this.ScheduleDayOfWeek,\n DayOfMonth: this.ScheduleDayOfMonth,\n Raw: this.RawCron,\n };\n return BuildCronExpression(schedule);\n }\n\n private parseScheduleTime(): { hour: number; minute: number } {\n const match = /^(\\d{1,2}):(\\d{2})$/.exec(this.ScheduleTime.trim());\n if (!match) {\n return { hour: 9, minute: 0 };\n }\n return {\n hour: Math.min(23, Math.max(0, parseInt(match[1], 10))),\n minute: this.clampMinute(parseInt(match[2], 10)),\n };\n }\n\n private clampMinute(minute: number): number {\n return Math.min(59, Math.max(0, Math.round(minute ?? 0)));\n }\n\n /** Builds the editable recipient rows from the engine's cached recipients. */\n private loadRecipientRows(routineID: string): void {\n this.Recipients = this.engine()\n .RecipientsForRoutine(routineID)\n .map((entity) => ({\n Entity: entity,\n Mode: entity.UserID ? ('user' as const) : ('email' as const),\n UserID: entity.UserID,\n Email: entity.Email ?? '',\n Channel: entity.Channel,\n }));\n }\n\n /** Lazily loads the user picker options the first time a user-mode row exists. */\n private async ensureUserOptions(): Promise<void> {\n if (this.UserOptions.length > 0) {\n return;\n }\n const p = this.ProviderToUse;\n const rv = RunView.FromMetadataProvider(p);\n const result = await rv.RunView<UserOption>(\n {\n EntityName: 'MJ: Users',\n Fields: ['ID', 'Name', 'Email'],\n ExtraFilter: `IsActive=1`,\n OrderBy: 'Name ASC',\n ResultType: 'simple',\n },\n p.CurrentUser\n );\n if (result.Success) {\n this.UserOptions = result.Results ?? [];\n this.cdr.markForCheck();\n }\n }\n\n private validate(): string[] {\n const errors: string[] = [];\n if (!this.Name.trim()) {\n errors.push('Name is required.');\n }\n if (!this.TargetID) {\n errors.push('Select the agent this routine should run.');\n }\n if (this.ScheduleKind === 'advanced' && !IsPlausibleCronExpression(this.RawCron)) {\n errors.push('The advanced cron expression must have 5 (or 6) space-separated fields.');\n }\n if (!this.Timezone?.trim()) {\n errors.push('Timezone is required.');\n }\n const payloadCheck = ValidateOptionalJson(this.StartingPayloadText);\n if (!payloadCheck.Valid) {\n errors.push(`Starting payload is not valid JSON: ${payloadCheck.Error}`);\n }\n const startAt = FromDateTimeLocal(this.StartAtLocal);\n const endAt = FromDateTimeLocal(this.EndAtLocal);\n if (startAt && endAt && endAt.getTime() <= startAt.getTime()) {\n errors.push('End of the activation window must be after its start.');\n }\n this.Recipients.forEach((row, i) => {\n if (row.Mode === 'user' && !row.UserID) {\n errors.push(`Recipient ${i + 1}: choose a user (or switch the row to an external email).`);\n }\n if (row.Mode === 'email' && !IsPlausibleEmail(row.Email)) {\n errors.push(`Recipient ${i + 1}: enter a valid email address.`);\n }\n });\n return errors;\n }\n\n /** Persists recipient rows in order (Sequence = index) and deletes removed rows. */\n private async saveRecipients(routine: MJUserRoutineEntity): Promise<string[]> {\n const p = this.ProviderToUse;\n const errors: string[] = [];\n\n for (const entity of this.deletedRecipients) {\n const deleted = await entity.Delete();\n if (!deleted) {\n errors.push(\n `Failed to remove a recipient: ${entity.LatestResult?.CompleteMessage ?? 'unknown error'}`\n );\n }\n }\n this.deletedRecipients = [];\n\n for (let i = 0; i < this.Recipients.length; i++) {\n const row = this.Recipients[i];\n const entity =\n row.Entity ??\n (await p.GetEntityObject<MJUserRoutineRecipientEntity>('MJ: User Routine Recipients', p.CurrentUser));\n entity.RoutineID = routine.ID;\n entity.UserID = row.Mode === 'user' ? row.UserID : null;\n entity.Email = row.Mode === 'email' ? row.Email.trim() : null;\n entity.Channel = row.Channel;\n entity.Sequence = i;\n const saved = await entity.Save();\n if (saved) {\n row.Entity = entity;\n } else {\n errors.push(\n `Failed to save recipient ${i + 1}: ${entity.LatestResult?.CompleteMessage ?? 'unknown error'}`\n );\n }\n }\n return errors;\n }\n}\n","@if (IsLoading) {\n <div class=\"editor-loading\">\n <mj-loading text=\"Loading editor...\" size=\"medium\"></mj-loading>\n </div>\n} @else {\n <div class=\"routine-editor\">\n\n @if (ValidationErrors.length > 0) {\n <mj-alert Variant=\"error\">\n <ul class=\"editor-errors\">\n @for (error of ValidationErrors; track error) {\n <li>{{ error }}</li>\n }\n </ul>\n </mj-alert>\n }\n\n <!-- ═══════════ BASICS (the 80% path: name, agent, message, schedule) ═══════════ -->\n <section class=\"editor-section\">\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-name\">Name <span class=\"editor-required\">*</span></label>\n <input id=\"routine-name\" class=\"mj-input\" type=\"text\" [(ngModel)]=\"Name\" placeholder=\"e.g. Morning membership digest\" />\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Which agent should this routine run? <span class=\"editor-required\">*</span></label>\n @if (AgentTreeLeafConfig) {\n <mj-tree-dropdown\n [BranchConfig]=\"AgentTreeBranchConfig\"\n [LeafConfig]=\"AgentTreeLeafConfig\"\n DefaultExpansion=\"all\"\n SelectionMode=\"single\"\n SelectableTypes=\"leaf\"\n [Value]=\"SelectedAgentKey\"\n [Clearable]=\"false\"\n Placeholder=\"Select an agent...\"\n (AfterNodeSelect)=\"OnAgentNodeSelected($event)\">\n </mj-tree-dropdown>\n }\n <div class=\"editor-hint\">Active agents only, grouped by category — realtime (voice) agents are interactive-only and can't be scheduled.</div>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-message\">Message sent on each run</label>\n <!-- Composer mention editor in DISCOVERY mode: trigger providers are ClassFactory-\n discovered (ng-conversations registers '@' agent / '#' record / '/' skill plugins\n when loaded). '@' agent mentions are excluded — the routine's agent is fixed by\n the picker above. With no providers registered this degrades gracefully to a\n plain text editor. -->\n <mj-mention-editor id=\"routine-message\"\n [(ngModel)]=\"InitialMessage\"\n placeholder=\"The message the routine sends to the agent each time it runs\"\n [ExcludedTriggerKeys]=\"['agent-mentions']\"\n [Provider]=\"Provider\"\n [enableAttachments]=\"false\"\n [autoFocus]=\"false\"\n [currentUser]=\"ProviderToUse.CurrentUser\"></mj-mention-editor>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Frequency</label>\n <div class=\"editor-segmented editor-segmented--wrap\" role=\"radiogroup\" aria-label=\"Schedule frequency\">\n @for (option of ScheduleKindOptions; track option.Value) {\n <button type=\"button\" class=\"editor-segment\"\n [class.editor-segment--active]=\"ScheduleKind === option.Value\"\n (click)=\"SetScheduleKind(option.Value)\">\n {{ option.Label }}\n </button>\n }\n </div>\n </div>\n\n <div class=\"editor-schedule-detail\">\n @switch (ScheduleKind) {\n @case ('hourly') {\n <div class=\"editor-field editor-field--inline\">\n <label class=\"editor-label\">At minute</label>\n <mj-numeric-input [(ngModel)]=\"ScheduleMinute\" [Min]=\"0\" [Max]=\"59\" [Step]=\"5\"></mj-numeric-input>\n <span class=\"editor-hint-inline\">past every hour</span>\n </div>\n }\n @case ('daily') {\n <div class=\"editor-field editor-field--inline\">\n <label class=\"editor-label\">At</label>\n <input class=\"mj-input editor-time-input\" type=\"time\" [(ngModel)]=\"ScheduleTime\" />\n <span class=\"editor-hint-inline\">every day</span>\n </div>\n }\n @case ('weekly') {\n <div class=\"editor-field editor-field--inline\">\n <label class=\"editor-label\">Every</label>\n <mj-dropdown class=\"editor-inline-dropdown\" [Data]=\"DayOfWeekOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"ScheduleDayOfWeek\"></mj-dropdown>\n <label class=\"editor-label\">at</label>\n <input class=\"mj-input editor-time-input\" type=\"time\" [(ngModel)]=\"ScheduleTime\" />\n </div>\n }\n @case ('monthly') {\n <div class=\"editor-field editor-field--inline\">\n <label class=\"editor-label\">On day</label>\n <mj-dropdown class=\"editor-inline-dropdown\" [Data]=\"DayOfMonthOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"ScheduleDayOfMonth\"></mj-dropdown>\n <label class=\"editor-label\">at</label>\n <input class=\"mj-input editor-time-input\" type=\"time\" [(ngModel)]=\"ScheduleTime\" />\n </div>\n }\n @case ('advanced') {\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-cron\">Cron expression</label>\n <input id=\"routine-cron\" class=\"mj-input editor-mono\" type=\"text\" [(ngModel)]=\"RawCron\"\n placeholder=\"minute hour day-of-month month day-of-week\" />\n </div>\n }\n }\n <div class=\"editor-schedule-preview\">\n <i class=\"fa-solid fa-calendar-check\"></i> {{ SchedulePreview || 'No schedule yet' }}\n </div>\n </div>\n </section>\n\n <!-- ═══════════ ADVANCED (progressive disclosure — collapsed by default) ═══════════ -->\n <button type=\"button\" class=\"editor-advanced-toggle\" (click)=\"ShowAdvanced = !ShowAdvanced\"\n [attr.aria-expanded]=\"ShowAdvanced\">\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"!ShowAdvanced\" [class.fa-chevron-down]=\"ShowAdvanced\"></i>\n Advanced options\n <span class=\"editor-hint-inline\">description · monitoring · timezone · window · payload · skills · notifications</span>\n </button>\n\n @if (ShowAdvanced) {\n <section class=\"editor-section\">\n <h3 class=\"editor-section-title\"><i class=\"fa-solid fa-circle-info\"></i> Details</h3>\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-description\">Description</label>\n <textarea id=\"routine-description\" class=\"mj-textarea\" rows=\"2\" [(ngModel)]=\"Description\"\n placeholder=\"What does this routine do?\"></textarea>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Routine type</label>\n <div class=\"editor-segmented\" role=\"radiogroup\" aria-label=\"Routine type\">\n <button type=\"button\" class=\"editor-segment\"\n [class.editor-segment--active]=\"RoutineType === 'Scheduled'\"\n (click)=\"RoutineType = 'Scheduled'\">\n <i class=\"fa-solid fa-clock\"></i> Scheduled\n </button>\n <button type=\"button\" class=\"editor-segment\"\n [class.editor-segment--active]=\"RoutineType === 'Monitoring'\"\n (click)=\"RoutineType = 'Monitoring'\">\n <i class=\"fa-solid fa-eye\"></i> Monitoring\n </button>\n </div>\n <div class=\"editor-hint\">{{ RoutineTypeHelp }}</div>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Timezone</label>\n <mj-combobox\n [Data]=\"TimezoneOptions\"\n [ValuePrimitive]=\"true\"\n Placeholder=\"Select an IANA timezone...\"\n [(ngModel)]=\"Timezone\">\n </mj-combobox>\n </div>\n\n <div class=\"editor-field-row\">\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-startat\">Active from (optional)</label>\n <input id=\"routine-startat\" class=\"mj-input\" type=\"datetime-local\" [(ngModel)]=\"StartAtLocal\" />\n </div>\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-endat\">Active until (optional)</label>\n <input id=\"routine-endat\" class=\"mj-input\" type=\"datetime-local\" [(ngModel)]=\"EndAtLocal\" />\n </div>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Starting payload (JSON, optional)</label>\n <div class=\"editor-code\">\n <mj-code-editor [(ngModel)]=\"StartingPayloadText\" language=\"json\"\n placeholder='{ \"example\": true }'></mj-code-editor>\n </div>\n <div class=\"editor-hint\">Passed to the agent on each run. Leave blank for none.</div>\n </div>\n\n @if (SkillOptions.length > 0) {\n <div class=\"editor-field\">\n <label class=\"editor-label\">Pre-activate skills (optional)</label>\n <div class=\"editor-skills\">\n @for (skill of SkillOptions; track skill.ID) {\n <button type=\"button\" class=\"editor-skill-chip\"\n [class.editor-skill-chip--selected]=\"IsSkillSelected(skill.ID)\"\n [title]=\"skill.Description ?? skill.Name\"\n (click)=\"ToggleSkill(skill.ID)\">\n <i [class]=\"skill.IconClass || 'fa-solid fa-wand-magic-sparkles'\"></i>\n {{ skill.Name }}\n @if (IsSkillSelected(skill.ID)) {\n <i class=\"fa-solid fa-check editor-skill-check\"></i>\n }\n </button>\n }\n </div>\n <div class=\"editor-hint\">Selected skills start every run with their instructions and tools in effect (subject to the agent's skill gates).</div>\n </div>\n }\n </section>\n\n <section class=\"editor-section\">\n <h3 class=\"editor-section-title\"><i class=\"fa-solid fa-bell\"></i> Notifications</h3>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Notify me</label>\n <mj-dropdown [Data]=\"NotifyConditionOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"NotifyCondition\"></mj-dropdown>\n </div>\n\n <div class=\"editor-field editor-field--inline editor-switches\">\n <mj-switch [(ngModel)]=\"NotifyViaInApp\" OnLabel=\"In-app\" OffLabel=\"In-app\"></mj-switch>\n <mj-switch [(ngModel)]=\"NotifyViaEmail\" OnLabel=\"Email\" OffLabel=\"Email\"></mj-switch>\n </div>\n\n <div class=\"editor-field\">\n <div class=\"editor-recipients-header\">\n <label class=\"editor-label\">Additional recipients</label>\n <button mjButton variant=\"outline\" size=\"sm\" (click)=\"AddRecipient()\">\n <i class=\"fa-solid fa-plus\"></i> Add recipient\n </button>\n </div>\n @if (Recipients.length === 0) {\n <div class=\"editor-hint\">Only you (the owner) will be notified.</div>\n }\n @for (row of Recipients; track $index; let i = $index; let first = $first; let last = $last) {\n <div class=\"editor-recipient-row\">\n <div class=\"editor-recipient-order\">\n <button mjButton variant=\"icon\" size=\"sm\" title=\"Move up\" [disabled]=\"first\" (click)=\"MoveRecipient(i, -1)\">\n <i class=\"fa-solid fa-chevron-up\"></i>\n </button>\n <button mjButton variant=\"icon\" size=\"sm\" title=\"Move down\" [disabled]=\"last\" (click)=\"MoveRecipient(i, 1)\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n </div>\n <mj-dropdown class=\"editor-recipient-mode\" [Data]=\"RecipientModeOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"row.Mode\" (ngModelChange)=\"OnRecipientModeChange(row)\"></mj-dropdown>\n @if (row.Mode === 'user') {\n <mj-combobox class=\"editor-recipient-target\" [Data]=\"UserOptions\" TextField=\"Name\" ValueField=\"ID\"\n [ValuePrimitive]=\"true\" Placeholder=\"Select a user...\" [(ngModel)]=\"row.UserID\"></mj-combobox>\n } @else {\n <input class=\"mj-input editor-recipient-target\" type=\"email\" placeholder=\"name@example.com\" [(ngModel)]=\"row.Email\" />\n }\n <mj-dropdown class=\"editor-recipient-channel\" [Data]=\"ChannelOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"row.Channel\"></mj-dropdown>\n <button mjButton variant=\"icon\" size=\"sm\" title=\"Remove recipient\" (click)=\"RemoveRecipient(i)\">\n <i class=\"fa-solid fa-trash-can\"></i>\n </button>\n </div>\n }\n </div>\n </section>\n }\n\n <!-- ======================= Footer (confirm LEFT, cancel RIGHT) ======================= -->\n <div class=\"editor-footer\">\n <button mjButton variant=\"primary\" size=\"md\" [disabled]=\"IsSaving\" (click)=\"Save()\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-check\"></i>\n }\n {{ IsEdit ? 'Save Changes' : 'Create Routine' }}\n </button>\n <button mjButton variant=\"secondary\" size=\"md\" [disabled]=\"IsSaving\" (click)=\"Cancel()\">Cancel</button>\n </div>\n </div>\n}\n"]}
|
|
1
|
+
{"version":3,"file":"new-routine.component.js","sourceRoot":"","sources":["../../src/lib/new-routine.component.ts","../../src/lib/new-routine.component.html"],"names":[],"mappings":"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","sourcesContent":["import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, inject } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { CompositeKey, IMetadataProvider, RunView } from '@memberjunction/core';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\nimport { MJUserRoutineEntity, MJUserRoutineRecipientEntity, UserRoutineEngine } from '@memberjunction/core-entities';\nimport {\n BuildCronExpression,\n CRON_DAY_NAMES,\n CronPresetKind,\n CronSchedule,\n DescribeCronExpression,\n IsPlausibleCronExpression,\n NormalizeUUID,\n ParseCronExpression,\n} from '@memberjunction/global';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { AfterNodeSelectEventArgs, TreeBranchConfig, TreeLeafConfig } from '@memberjunction/ng-trees';\nimport {\n FromDateTimeLocal,\n GetLocalTimezone,\n GetTimezoneOptions,\n IsPlausibleEmail,\n ParseSkillIDs,\n SerializeSkillIDs,\n ToDateTimeLocal,\n ValidateOptionalJson,\n} from './routine-ui-helpers';\nimport { LoadRoutineTargetCatalog, RoutineSkillOption, RoutineTargetCatalog } from './routine-target-catalog';\nimport { AfterRoutineCreatedEventArgs, BeforeRoutineCreatedEventArgs } from './user-routines-events';\n\n/** One editable recipient row (existing rows carry their entity for update/delete). */\ninterface RecipientRow {\n Entity: MJUserRoutineRecipientEntity | null;\n Mode: 'user' | 'email';\n UserID: string | null;\n Email: string;\n Channel: MJUserRoutineRecipientEntity['Channel'];\n}\n\n/** Minimal user shape for the recipient user picker. */\ninterface UserOption {\n ID: string;\n Name: string;\n Email: string | null;\n}\n\n/**\n * Create/edit form for a User Routine. Routines run an AI AGENT on a schedule\n * (TargetType is implicitly 'Agent') — the agent is chosen from a categorical tree\n * grouped by Agent Category, showing each agent's own IconClass, with Realtime-type\n * agents excluded (interactive-only). Also covers the initial message, optional JSON\n * payload, AI Skills pre-activation, cron presets + advanced escape hatch, IANA\n * timezone, activation window, notification settings, and the ordered recipients list.\n *\n * Reusable (Generic) component: no Router, no page chrome. The host mounts it\n * (slide-in / dialog / inline), passes `RoutineID` (null = create), and reacts to\n * `Saved` / `Cancelled` plus the cancelable `BeforeRoutineCreated` /\n * `AfterRoutineCreated` pair for new routines. All persistence flows through MJ\n * entity objects with explicit `Save()` boolean checks; failures surface\n * `LatestResult.CompleteMessage`. Cached routine/recipient data comes from\n * {@link UserRoutineEngine}.\n */\n@Component({\n standalone: false,\n selector: 'mj-new-routine',\n templateUrl: './new-routine.component.html',\n styleUrls: ['./new-routine.component.css'],\n})\nexport class NewRoutineComponent extends BaseAngularComponent implements OnInit {\n private cdr = inject(ChangeDetectorRef);\n private notifications = inject(MJNotificationService);\n\n // ---------------------------------------------------------------\n // Inputs / Outputs\n // ---------------------------------------------------------------\n private _routineID: string | null = null;\n /** ID of the routine to edit, or null to create a new one. */\n @Input()\n public set RoutineID(value: string | null) {\n if (value !== this._routineID) {\n this._routineID = value;\n if (this.initialized) {\n void this.reload();\n }\n }\n }\n public get RoutineID(): string | null {\n return this._routineID;\n }\n\n /** Emitted after a successful save (routine + recipients persisted) — create AND edit. */\n @Output() Saved = new EventEmitter<MJUserRoutineEntity>();\n /** Emitted when the user cancels without saving. */\n @Output() Cancelled = new EventEmitter<void>();\n /** Cancelable: fires before a NEW routine is saved for the first time. */\n @Output() BeforeRoutineCreated = new EventEmitter<BeforeRoutineCreatedEventArgs>();\n /** Informational: fires after a new routine (and its recipients) was persisted. */\n @Output() AfterRoutineCreated = new EventEmitter<AfterRoutineCreatedEventArgs>();\n\n // ---------------------------------------------------------------\n // Form state\n // ---------------------------------------------------------------\n public Name = '';\n public Description = '';\n /** The selected agent's ID (TargetType is implicitly 'Agent'). */\n public TargetID: string | null = null;\n public InitialMessage = '';\n public StartingPayloadText = '';\n public SelectedSkillIDs: string[] = [];\n public RoutineType: MJUserRoutineEntity['RoutineType'] = 'Scheduled';\n\n public ScheduleKind: CronPresetKind = 'daily';\n /** Minute past each hour for the hourly preset. */\n public ScheduleMinute = 0;\n /** \"HH:MM\" run time for daily/weekly/monthly presets. */\n public ScheduleTime = '09:00';\n public ScheduleDayOfWeek = 1;\n public ScheduleDayOfMonth = 1;\n public RawCron = '';\n\n public Timezone: string = GetLocalTimezone();\n public StartAtLocal = '';\n public EndAtLocal = '';\n\n public NotifyCondition: MJUserRoutineEntity['NotifyCondition'] = 'Always';\n public NotifyViaInApp = true;\n public NotifyViaEmail = false;\n public Recipients: RecipientRow[] = [];\n\n // ---------------------------------------------------------------\n // Options / status\n // ---------------------------------------------------------------\n /**\n * Progressive disclosure: the basic view (name / agent / message / frequency)\n * covers the 80% path; everything else lives behind this toggle. Auto-expands\n * when editing a routine that already uses advanced settings.\n */\n public ShowAdvanced = false;\n\n public Catalog: RoutineTargetCatalog | null = null;\n public UserOptions: UserOption[] = [];\n public TimezoneOptions: string[] = GetTimezoneOptions();\n public IsLoading = true;\n public IsSaving = false;\n public ValidationErrors: string[] = [];\n\n /** Tree config for the agent-category branches. */\n public AgentTreeBranchConfig: TreeBranchConfig = {\n EntityName: 'MJ: AI Agent Categories',\n DisplayField: 'Name',\n ParentIDField: 'ParentID',\n DefaultIcon: 'fa-solid fa-folder',\n OrderBy: 'Name ASC',\n };\n /** Tree config for the pickable agents (built at load time — excludes Realtime types). */\n public AgentTreeLeafConfig: TreeLeafConfig | undefined;\n /** Tree selection binding (single agent). */\n public SelectedAgentIDs: string[] = [];\n\n public readonly DayNames = CRON_DAY_NAMES;\n public readonly DayOfWeekOptions = CRON_DAY_NAMES.map((name, i) => ({ text: name, value: i }));\n public readonly DayOfMonthOptions = Array.from({ length: 31 }, (_, i) => ({ text: `${i + 1}`, value: i + 1 }));\n public readonly ScheduleKindOptions: Array<{ Value: CronPresetKind; Label: string }> = [\n { Value: 'hourly', Label: 'Hourly' },\n { Value: 'daily', Label: 'Daily' },\n { Value: 'weekly', Label: 'Weekly' },\n { Value: 'monthly', Label: 'Monthly' },\n { Value: 'advanced', Label: 'Advanced (cron)' },\n ];\n public readonly NotifyConditionOptions = [\n { text: 'Always — after every run', value: 'Always' },\n { text: 'On success only', value: 'OnSuccess' },\n { text: 'On failure only', value: 'OnFailure' },\n { text: 'On change — when the result differs from the prior run', value: 'OnChange' },\n ];\n public readonly ChannelOptions = [\n { text: 'In-app', value: 'InApp' },\n { text: 'Email', value: 'Email' },\n ];\n public readonly RecipientModeOptions = [\n { text: 'MJ user', value: 'user' },\n { text: 'External email', value: 'email' },\n ];\n\n private editingEntity: MJUserRoutineEntity | null = null;\n private deletedRecipients: MJUserRoutineRecipientEntity[] = [];\n private initialized = false;\n\n async ngOnInit(): Promise<void> {\n this.initialized = true;\n await this.reload();\n }\n\n /** True when editing an existing routine (vs. creating a new one). */\n public get IsEdit(): boolean {\n return this._routineID != null;\n }\n\n /** Active skills available for pre-activation. */\n public get SkillOptions(): RoutineSkillOption[] {\n return this.Catalog?.Skills ?? [];\n }\n\n /** Name of the currently selected agent (empty when none). */\n public get SelectedAgentName(): string {\n if (!this.TargetID) {\n return '';\n }\n return this.Catalog?.NameByID.get(NormalizeUUID(this.TargetID)) ?? '';\n }\n\n /** IconClass of the currently selected agent (robot fallback). */\n public get SelectedAgentIcon(): string {\n if (!this.TargetID) {\n return 'fa-solid fa-robot';\n }\n return this.Catalog?.IconByID.get(NormalizeUUID(this.TargetID)) ?? 'fa-solid fa-robot';\n }\n\n /** Live human-readable preview of the schedule being built. */\n public get SchedulePreview(): string {\n return DescribeCronExpression(this.buildCron());\n }\n\n /** Helper text under the RoutineType toggle. */\n public get RoutineTypeHelp(): string {\n return this.RoutineType === 'Scheduled'\n ? 'Runs on the schedule and notifies per the notification condition.'\n : 'Runs on the schedule and hashes each result — pair with the \"On change\" condition to be notified only when the result changes.';\n }\n\n /** Handles agent selection from the category tree (leaf nodes only). */\n /** The selected agent as a CompositeKey for the tree-dropdown's Value binding. */\n public get SelectedAgentKey(): CompositeKey | null {\n return this.TargetID ? CompositeKey.FromID(this.TargetID) : null; // first-pk-ok: TargetID is an MJ: AI Agents record (agent tree leaf) — core entity keyed by ID\n }\n\n public OnAgentNodeSelected(args: AfterNodeSelectEventArgs): void {\n if (args.Node.Type === 'leaf') {\n this.TargetID = args.Node.ID;\n this.SelectedAgentIDs = [args.Node.ID];\n this.cdr.markForCheck();\n }\n }\n\n public SetScheduleKind(kind: CronPresetKind): void {\n if (kind === this.ScheduleKind) {\n return;\n }\n if (kind === 'advanced' && !this.RawCron.trim()) {\n // Seed the advanced box from the current preset so nothing is lost\n this.RawCron = this.buildCron();\n }\n this.ScheduleKind = kind;\n this.cdr.markForCheck();\n }\n\n /** Toggles a skill in/out of the RequestedSkillIDs selection. */\n public ToggleSkill(skillID: string): void {\n const index = this.SelectedSkillIDs.indexOf(skillID);\n if (index >= 0) {\n this.SelectedSkillIDs = this.SelectedSkillIDs.filter((id) => id !== skillID);\n } else {\n this.SelectedSkillIDs = [...this.SelectedSkillIDs, skillID];\n }\n this.cdr.markForCheck();\n }\n\n public IsSkillSelected(skillID: string): boolean {\n return this.SelectedSkillIDs.includes(skillID);\n }\n\n // ---------------------------------------------------------------\n // Recipients\n // ---------------------------------------------------------------\n public AddRecipient(): void {\n this.Recipients = [\n ...this.Recipients,\n { Entity: null, Mode: 'user', UserID: null, Email: '', Channel: 'InApp' },\n ];\n void this.ensureUserOptions();\n }\n\n public RemoveRecipient(index: number): void {\n const row = this.Recipients[index];\n if (row?.Entity) {\n this.deletedRecipients.push(row.Entity);\n }\n this.Recipients = this.Recipients.filter((_, i) => i !== index);\n }\n\n /** Moves a recipient up/down — the saved Sequence is the row index. */\n public MoveRecipient(index: number, delta: -1 | 1): void {\n const target = index + delta;\n if (target < 0 || target >= this.Recipients.length) {\n return;\n }\n const next = [...this.Recipients];\n [next[index], next[target]] = [next[target], next[index]];\n this.Recipients = next;\n }\n\n /** When the row's mode flips, clear the other identity field. */\n public OnRecipientModeChange(row: RecipientRow): void {\n if (row.Mode === 'user') {\n row.Email = '';\n void this.ensureUserOptions();\n } else {\n row.UserID = null;\n }\n }\n\n // ---------------------------------------------------------------\n // Save / cancel\n // ---------------------------------------------------------------\n public Cancel(): void {\n this.Cancelled.emit();\n }\n\n public async Save(): Promise<void> {\n if (this.IsSaving) {\n return;\n }\n this.ValidationErrors = this.validate();\n if (this.ValidationErrors.length > 0) {\n this.cdr.markForCheck();\n return;\n }\n\n this.IsSaving = true;\n this.cdr.markForCheck();\n try {\n const p = this.ProviderToUse;\n const isNew = !this.IsEdit;\n const routine =\n this.editingEntity ??\n (await p.GetEntityObject<MJUserRoutineEntity>('MJ: User Routines', p.CurrentUser));\n if (isNew) {\n routine.UserID = p.CurrentUser.ID;\n }\n\n routine.Name = this.Name.trim();\n routine.Description = this.Description.trim() || null;\n routine.RoutineType = this.RoutineType;\n routine.TargetType = 'Agent';\n // Validated non-null in validate()\n routine.TargetID = this.TargetID as string;\n routine.InitialMessage = this.InitialMessage.trim() || null;\n routine.StartingPayload = this.StartingPayloadText.trim() || null;\n routine.RequestedSkillIDs = SerializeSkillIDs(this.SelectedSkillIDs);\n routine.CronExpression = this.buildCron();\n routine.Timezone = this.Timezone;\n routine.StartAt = FromDateTimeLocal(this.StartAtLocal);\n routine.EndAt = FromDateTimeLocal(this.EndAtLocal);\n routine.NotifyCondition = this.NotifyCondition;\n routine.NotifyViaInApp = this.NotifyViaInApp;\n routine.NotifyViaEmail = this.NotifyViaEmail;\n\n if (isNew) {\n const beforeArgs = new BeforeRoutineCreatedEventArgs(routine);\n this.BeforeRoutineCreated.emit(beforeArgs);\n if (beforeArgs.Cancel) {\n return;\n }\n }\n\n const saved = await routine.Save();\n if (!saved) {\n this.ValidationErrors = [\n `Save failed: ${routine.LatestResult?.CompleteMessage ?? 'unknown error'}`,\n ];\n return;\n }\n\n const recipientErrors = await this.saveRecipients(routine);\n if (recipientErrors.length > 0) {\n this.ValidationErrors = recipientErrors;\n return;\n }\n\n if (isNew) {\n // Re-scope the engine's dependent (recipients/runs) configs to include\n // the new routine — their client-side filter is a Config-time snapshot.\n await this.engine().Refresh(p.CurrentUser);\n this.AfterRoutineCreated.emit(new AfterRoutineCreatedEventArgs(routine));\n }\n\n this.notifications.CreateSimpleNotification(\n isNew ? `'${routine.Name}' created` : `'${routine.Name}' updated`,\n 'success',\n 3000\n );\n this.Saved.emit(routine);\n } finally {\n this.IsSaving = false;\n this.cdr.markForCheck();\n }\n }\n\n // ---------------------------------------------------------------\n // Internals\n // ---------------------------------------------------------------\n private engine(): UserRoutineEngine {\n return UserRoutineEngine.GetProviderInstance<UserRoutineEngine>(this.ProviderToUse, UserRoutineEngine) as UserRoutineEngine;\n }\n\n /** True when the loaded routine differs from the basic-path defaults in any advanced field. */\n private usesAdvancedSettings(): boolean {\n return this.Description.trim().length > 0\n || this.RoutineType === 'Monitoring'\n || this.StartingPayloadText.trim().length > 0\n || this.SelectedSkillIDs.length > 0\n || this.Timezone !== GetLocalTimezone()\n || this.StartAtLocal.trim().length > 0\n || this.EndAtLocal.trim().length > 0\n || this.NotifyCondition !== 'Always'\n || !this.NotifyViaInApp\n || this.NotifyViaEmail\n || this.Recipients.length > 0;\n }\n\n private async reload(): Promise<void> {\n this.IsLoading = true;\n this.ValidationErrors = [];\n this.deletedRecipients = [];\n this.cdr.markForCheck();\n try {\n const p = this.ProviderToUse;\n const [catalog] = await Promise.all([\n LoadRoutineTargetCatalog(p),\n this.engine().Config(false, p.CurrentUser, p),\n ]);\n this.Catalog = catalog;\n this.buildAgentTreeConfig(p);\n if (this._routineID) {\n await this.loadExisting(this._routineID);\n this.ShowAdvanced = this.usesAdvancedSettings();\n } else {\n this.resetForNew();\n this.ShowAdvanced = false;\n }\n if (this.Recipients.some((r) => r.Mode === 'user')) {\n await this.ensureUserOptions();\n }\n } catch (e) {\n this.ValidationErrors = [\n `Failed to load the editor: ${e instanceof Error ? e.message : 'unknown error'}`,\n ];\n } finally {\n this.IsLoading = false;\n this.cdr.markForCheck();\n }\n }\n\n /**\n * Builds the agent tree leaf config: Active, root-level agents only, EXCLUDING\n * agents whose type is the Realtime agent type. The exclusion is expressed as an\n * inline NOT IN list of type IDs resolved from metadata BY NAME (never hardcoded).\n */\n private buildAgentTreeConfig(provider: IMetadataProvider): void {\n const realtimeTypeIDs = this.resolveRealtimeTypeIDs(provider);\n const filters = [`Status='Active'`, `ParentID IS NULL`];\n if (realtimeTypeIDs.length > 0) {\n const inList = realtimeTypeIDs.map((id) => `'${id}'`).join(',');\n filters.push(`(TypeID IS NULL OR TypeID NOT IN (${inList}))`);\n }\n this.AgentTreeLeafConfig = {\n EntityName: 'MJ: AI Agents',\n ParentField: 'CategoryID',\n DisplayField: 'Name',\n IconField: 'IconClass',\n DefaultIcon: 'fa-solid fa-robot',\n ExtraFilter: filters.join(' AND '),\n OrderBy: 'Name ASC',\n };\n }\n\n /** Realtime agent-type IDs resolved from the cached AI metadata by type NAME. */\n private resolveRealtimeTypeIDs(provider: IMetadataProvider): string[] {\n // The catalog load above already Config'd AIEngineBase for this provider —\n // reuse its cached AgentTypes through the provider-scoped instance.\n const engine = AIEngineBase.GetProviderInstance<AIEngineBase>(provider, AIEngineBase) as AIEngineBase;\n return engine.AgentTypes\n .filter((t) => t.Name?.trim().toLowerCase() === 'realtime')\n .map((t) => t.ID);\n }\n\n private resetForNew(): void {\n this.editingEntity = null;\n this.Name = '';\n this.Description = '';\n this.TargetID = null;\n this.SelectedAgentIDs = [];\n this.InitialMessage = '';\n this.StartingPayloadText = '';\n this.SelectedSkillIDs = [];\n this.RoutineType = 'Scheduled';\n this.ScheduleKind = 'daily';\n this.ScheduleMinute = 0;\n this.ScheduleTime = '09:00';\n this.ScheduleDayOfWeek = 1;\n this.ScheduleDayOfMonth = 1;\n this.RawCron = '';\n this.Timezone = GetLocalTimezone();\n this.StartAtLocal = '';\n this.EndAtLocal = '';\n this.NotifyCondition = 'Always';\n this.NotifyViaInApp = true;\n this.NotifyViaEmail = false;\n this.Recipients = [];\n }\n\n private async loadExisting(routineID: string): Promise<void> {\n const p = this.ProviderToUse;\n // Prefer the engine's cached entity; fall back to a direct load (e.g., deep link\n // into a routine saved elsewhere before the cache refreshed).\n let routine = this.engine().GetRoutineByID(routineID) ?? null;\n if (!routine) {\n const loadedEntity = await p.GetEntityObject<MJUserRoutineEntity>('MJ: User Routines', p.CurrentUser);\n const loaded = await loadedEntity.Load(routineID);\n routine = loaded ? loadedEntity : null;\n }\n if (!routine) {\n this.ValidationErrors = [`Routine ${routineID} could not be loaded.`];\n this.resetForNew();\n return;\n }\n this.editingEntity = routine;\n this.Name = routine.Name;\n this.Description = routine.Description ?? '';\n this.TargetID = routine.TargetID;\n this.SelectedAgentIDs = routine.TargetID ? [routine.TargetID] : [];\n this.InitialMessage = routine.InitialMessage ?? '';\n this.StartingPayloadText = routine.StartingPayload ?? '';\n this.SelectedSkillIDs = ParseSkillIDs(routine.RequestedSkillIDs);\n this.RoutineType = routine.RoutineType;\n this.applyCron(ParseCronExpression(routine.CronExpression));\n this.Timezone = routine.Timezone;\n this.StartAtLocal = ToDateTimeLocal(routine.StartAt);\n this.EndAtLocal = ToDateTimeLocal(routine.EndAt);\n this.NotifyCondition = routine.NotifyCondition;\n this.NotifyViaInApp = routine.NotifyViaInApp;\n this.NotifyViaEmail = routine.NotifyViaEmail;\n this.loadRecipientRows(routineID);\n }\n\n private applyCron(schedule: CronSchedule): void {\n this.ScheduleKind = schedule.Kind;\n this.ScheduleMinute = schedule.Minute;\n this.ScheduleTime = `${schedule.Hour.toString().padStart(2, '0')}:${schedule.Minute.toString().padStart(2, '0')}`;\n this.ScheduleDayOfWeek = schedule.DayOfWeek;\n this.ScheduleDayOfMonth = schedule.DayOfMonth;\n this.RawCron = schedule.Raw;\n }\n\n private buildCron(): string {\n const { hour, minute } = this.parseScheduleTime();\n const schedule: CronSchedule = {\n Kind: this.ScheduleKind,\n Minute: this.ScheduleKind === 'hourly' ? this.clampMinute(this.ScheduleMinute) : minute,\n Hour: hour,\n DayOfWeek: this.ScheduleDayOfWeek,\n DayOfMonth: this.ScheduleDayOfMonth,\n Raw: this.RawCron,\n };\n return BuildCronExpression(schedule);\n }\n\n private parseScheduleTime(): { hour: number; minute: number } {\n const match = /^(\\d{1,2}):(\\d{2})$/.exec(this.ScheduleTime.trim());\n if (!match) {\n return { hour: 9, minute: 0 };\n }\n return {\n hour: Math.min(23, Math.max(0, parseInt(match[1], 10))),\n minute: this.clampMinute(parseInt(match[2], 10)),\n };\n }\n\n private clampMinute(minute: number): number {\n return Math.min(59, Math.max(0, Math.round(minute ?? 0)));\n }\n\n /** Builds the editable recipient rows from the engine's cached recipients. */\n private loadRecipientRows(routineID: string): void {\n this.Recipients = this.engine()\n .RecipientsForRoutine(routineID)\n .map((entity) => ({\n Entity: entity,\n Mode: entity.UserID ? ('user' as const) : ('email' as const),\n UserID: entity.UserID,\n Email: entity.Email ?? '',\n Channel: entity.Channel,\n }));\n }\n\n /** Lazily loads the user picker options the first time a user-mode row exists. */\n private async ensureUserOptions(): Promise<void> {\n if (this.UserOptions.length > 0) {\n return;\n }\n const p = this.ProviderToUse;\n const rv = RunView.FromMetadataProvider(p);\n const result = await rv.RunView<UserOption>(\n {\n EntityName: 'MJ: Users',\n Fields: ['ID', 'Name', 'Email'],\n ExtraFilter: `IsActive=1`,\n OrderBy: 'Name ASC',\n ResultType: 'simple',\n },\n p.CurrentUser\n );\n if (result.Success) {\n this.UserOptions = result.Results ?? [];\n this.cdr.markForCheck();\n }\n }\n\n private validate(): string[] {\n const errors: string[] = [];\n if (!this.Name.trim()) {\n errors.push('Name is required.');\n }\n if (!this.TargetID) {\n errors.push('Select the agent this routine should run.');\n }\n if (this.ScheduleKind === 'advanced' && !IsPlausibleCronExpression(this.RawCron)) {\n errors.push('The advanced cron expression must have 5 (or 6) space-separated fields.');\n }\n if (!this.Timezone?.trim()) {\n errors.push('Timezone is required.');\n }\n const payloadCheck = ValidateOptionalJson(this.StartingPayloadText);\n if (!payloadCheck.Valid) {\n errors.push(`Starting payload is not valid JSON: ${payloadCheck.Error}`);\n }\n const startAt = FromDateTimeLocal(this.StartAtLocal);\n const endAt = FromDateTimeLocal(this.EndAtLocal);\n if (startAt && endAt && endAt.getTime() <= startAt.getTime()) {\n errors.push('End of the activation window must be after its start.');\n }\n this.Recipients.forEach((row, i) => {\n if (row.Mode === 'user' && !row.UserID) {\n errors.push(`Recipient ${i + 1}: choose a user (or switch the row to an external email).`);\n }\n if (row.Mode === 'email' && !IsPlausibleEmail(row.Email)) {\n errors.push(`Recipient ${i + 1}: enter a valid email address.`);\n }\n });\n return errors;\n }\n\n /** Persists recipient rows in order (Sequence = index) and deletes removed rows. */\n private async saveRecipients(routine: MJUserRoutineEntity): Promise<string[]> {\n const p = this.ProviderToUse;\n const errors: string[] = [];\n\n for (const entity of this.deletedRecipients) {\n const deleted = await entity.Delete();\n if (!deleted) {\n errors.push(\n `Failed to remove a recipient: ${entity.LatestResult?.CompleteMessage ?? 'unknown error'}`\n );\n }\n }\n this.deletedRecipients = [];\n\n for (let i = 0; i < this.Recipients.length; i++) {\n const row = this.Recipients[i];\n const entity =\n row.Entity ??\n (await p.GetEntityObject<MJUserRoutineRecipientEntity>('MJ: User Routine Recipients', p.CurrentUser));\n entity.RoutineID = routine.ID;\n entity.UserID = row.Mode === 'user' ? row.UserID : null;\n entity.Email = row.Mode === 'email' ? row.Email.trim() : null;\n entity.Channel = row.Channel;\n entity.Sequence = i;\n const saved = await entity.Save();\n if (saved) {\n row.Entity = entity;\n } else {\n errors.push(\n `Failed to save recipient ${i + 1}: ${entity.LatestResult?.CompleteMessage ?? 'unknown error'}`\n );\n }\n }\n return errors;\n }\n}\n","@if (IsLoading) {\n <div class=\"editor-loading\">\n <mj-loading text=\"Getting the editor ready...\" size=\"medium\"></mj-loading>\n </div>\n} @else {\n <div class=\"routine-editor\">\n\n @if (ValidationErrors.length > 0) {\n <mj-alert Variant=\"error\">\n <ul class=\"editor-errors\">\n @for (error of ValidationErrors; track error) {\n <li>{{ error }}</li>\n }\n </ul>\n </mj-alert>\n }\n\n <!-- ═══════════ BASICS (the 80% path: name, agent, message, schedule) ═══════════ -->\n <section class=\"editor-section\">\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-name\">Name <span class=\"editor-required\">*</span></label>\n <input id=\"routine-name\" class=\"mj-input\" type=\"text\" [(ngModel)]=\"Name\" placeholder=\"e.g. Morning membership digest\" />\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Which agent should this routine run? <span class=\"editor-required\">*</span></label>\n @if (AgentTreeLeafConfig) {\n <mj-tree-dropdown\n [BranchConfig]=\"AgentTreeBranchConfig\"\n [LeafConfig]=\"AgentTreeLeafConfig\"\n DefaultExpansion=\"all\"\n SelectionMode=\"single\"\n SelectableTypes=\"leaf\"\n [Value]=\"SelectedAgentKey\"\n [Clearable]=\"false\"\n Placeholder=\"Select an agent...\"\n (AfterNodeSelect)=\"OnAgentNodeSelected($event)\">\n </mj-tree-dropdown>\n }\n <div class=\"editor-hint\">Active agents only, grouped by category — realtime (voice) agents are interactive-only and can't be scheduled.</div>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-message\">Message sent on each run</label>\n <!-- Composer mention editor in DISCOVERY mode: trigger providers are ClassFactory-\n discovered (ng-conversations registers '@' agent / '#' record / '/' skill plugins\n when loaded). '@' agent mentions are excluded — the routine's agent is fixed by\n the picker above. With no providers registered this degrades gracefully to a\n plain text editor. -->\n <mj-mention-editor id=\"routine-message\"\n [(ngModel)]=\"InitialMessage\"\n placeholder=\"The message the routine sends to the agent each time it runs\"\n [ExcludedTriggerKeys]=\"['agent-mentions']\"\n [Provider]=\"Provider\"\n [enableAttachments]=\"false\"\n [autoFocus]=\"false\"\n [currentUser]=\"ProviderToUse.CurrentUser\"></mj-mention-editor>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Frequency</label>\n <div class=\"editor-segmented editor-segmented--wrap\" role=\"radiogroup\" aria-label=\"Schedule frequency\">\n @for (option of ScheduleKindOptions; track option.Value) {\n <button type=\"button\" class=\"editor-segment\"\n [class.editor-segment--active]=\"ScheduleKind === option.Value\"\n (click)=\"SetScheduleKind(option.Value)\">\n {{ option.Label }}\n </button>\n }\n </div>\n </div>\n\n <div class=\"editor-schedule-detail\">\n @switch (ScheduleKind) {\n @case ('hourly') {\n <div class=\"editor-field editor-field--inline\">\n <label class=\"editor-label\">At minute</label>\n <mj-numeric-input [(ngModel)]=\"ScheduleMinute\" [Min]=\"0\" [Max]=\"59\" [Step]=\"5\"></mj-numeric-input>\n <span class=\"editor-hint-inline\">past every hour</span>\n </div>\n }\n @case ('daily') {\n <div class=\"editor-field editor-field--inline\">\n <label class=\"editor-label\">At</label>\n <input class=\"mj-input editor-time-input\" type=\"time\" [(ngModel)]=\"ScheduleTime\" />\n <span class=\"editor-hint-inline\">every day</span>\n </div>\n }\n @case ('weekly') {\n <div class=\"editor-field editor-field--inline\">\n <label class=\"editor-label\">Every</label>\n <mj-dropdown class=\"editor-inline-dropdown\" [Data]=\"DayOfWeekOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"ScheduleDayOfWeek\"></mj-dropdown>\n <label class=\"editor-label\">at</label>\n <input class=\"mj-input editor-time-input\" type=\"time\" [(ngModel)]=\"ScheduleTime\" />\n </div>\n }\n @case ('monthly') {\n <div class=\"editor-field editor-field--inline\">\n <label class=\"editor-label\">On day</label>\n <mj-dropdown class=\"editor-inline-dropdown\" [Data]=\"DayOfMonthOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"ScheduleDayOfMonth\"></mj-dropdown>\n <label class=\"editor-label\">at</label>\n <input class=\"mj-input editor-time-input\" type=\"time\" [(ngModel)]=\"ScheduleTime\" />\n </div>\n }\n @case ('advanced') {\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-cron\">Cron expression</label>\n <input id=\"routine-cron\" class=\"mj-input editor-mono\" type=\"text\" [(ngModel)]=\"RawCron\"\n placeholder=\"minute hour day-of-month month day-of-week\" />\n </div>\n }\n }\n <div class=\"editor-schedule-preview\">\n <i class=\"fa-solid fa-calendar-check\"></i> {{ SchedulePreview || 'No schedule yet' }}\n </div>\n </div>\n </section>\n\n <!-- ═══════════ ADVANCED (progressive disclosure — collapsed by default) ═══════════ -->\n <button type=\"button\" class=\"editor-advanced-toggle\" (click)=\"ShowAdvanced = !ShowAdvanced\"\n [attr.aria-expanded]=\"ShowAdvanced\">\n <i class=\"fa-solid\" [class.fa-chevron-right]=\"!ShowAdvanced\" [class.fa-chevron-down]=\"ShowAdvanced\"></i>\n Advanced options\n <span class=\"editor-hint-inline\">description · monitoring · timezone · window · payload · skills · notifications</span>\n </button>\n\n @if (ShowAdvanced) {\n <section class=\"editor-section\">\n <h3 class=\"editor-section-title\"><i class=\"fa-solid fa-circle-info\"></i> Details</h3>\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-description\">Description</label>\n <textarea id=\"routine-description\" class=\"mj-textarea\" rows=\"2\" [(ngModel)]=\"Description\"\n placeholder=\"What does this routine do?\"></textarea>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Routine type</label>\n <div class=\"editor-segmented\" role=\"radiogroup\" aria-label=\"Routine type\">\n <button type=\"button\" class=\"editor-segment\"\n [class.editor-segment--active]=\"RoutineType === 'Scheduled'\"\n (click)=\"RoutineType = 'Scheduled'\">\n <i class=\"fa-solid fa-clock\"></i> Scheduled\n </button>\n <button type=\"button\" class=\"editor-segment\"\n [class.editor-segment--active]=\"RoutineType === 'Monitoring'\"\n (click)=\"RoutineType = 'Monitoring'\">\n <i class=\"fa-solid fa-eye\"></i> Monitoring\n </button>\n </div>\n <div class=\"editor-hint\">{{ RoutineTypeHelp }}</div>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Timezone</label>\n <mj-combobox\n [Data]=\"TimezoneOptions\"\n [ValuePrimitive]=\"true\"\n Placeholder=\"Select an IANA timezone...\"\n [(ngModel)]=\"Timezone\">\n </mj-combobox>\n </div>\n\n <div class=\"editor-field-row\">\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-startat\">Active from (optional)</label>\n <input id=\"routine-startat\" class=\"mj-input\" type=\"datetime-local\" [(ngModel)]=\"StartAtLocal\" />\n </div>\n <div class=\"editor-field\">\n <label class=\"editor-label\" for=\"routine-endat\">Active until (optional)</label>\n <input id=\"routine-endat\" class=\"mj-input\" type=\"datetime-local\" [(ngModel)]=\"EndAtLocal\" />\n </div>\n </div>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Starting payload (JSON, optional)</label>\n <div class=\"editor-code\">\n <mj-code-editor [(ngModel)]=\"StartingPayloadText\" language=\"json\"\n placeholder='{ \"example\": true }'></mj-code-editor>\n </div>\n <div class=\"editor-hint\">Passed to the agent on each run. Leave blank for none.</div>\n </div>\n\n @if (SkillOptions.length > 0) {\n <div class=\"editor-field\">\n <label class=\"editor-label\">Pre-activate skills (optional)</label>\n <div class=\"editor-skills\">\n @for (skill of SkillOptions; track skill.ID) {\n <button type=\"button\" class=\"editor-skill-chip\"\n [class.editor-skill-chip--selected]=\"IsSkillSelected(skill.ID)\"\n [title]=\"skill.Description ?? skill.Name\"\n (click)=\"ToggleSkill(skill.ID)\">\n <i [class]=\"skill.IconClass || 'fa-solid fa-wand-magic-sparkles'\"></i>\n {{ skill.Name }}\n @if (IsSkillSelected(skill.ID)) {\n <i class=\"fa-solid fa-check editor-skill-check\"></i>\n }\n </button>\n }\n </div>\n <div class=\"editor-hint\">Selected skills start every run with their instructions and tools in effect (subject to the agent's skill gates).</div>\n </div>\n }\n </section>\n\n <section class=\"editor-section\">\n <h3 class=\"editor-section-title\"><i class=\"fa-solid fa-bell\"></i> Notifications</h3>\n\n <div class=\"editor-field\">\n <label class=\"editor-label\">Notify me</label>\n <mj-dropdown [Data]=\"NotifyConditionOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"NotifyCondition\"></mj-dropdown>\n </div>\n\n <div class=\"editor-field editor-field--inline editor-switches\">\n <mj-switch [(ngModel)]=\"NotifyViaInApp\" OnLabel=\"In-app\" OffLabel=\"In-app\"></mj-switch>\n <mj-switch [(ngModel)]=\"NotifyViaEmail\" OnLabel=\"Email\" OffLabel=\"Email\"></mj-switch>\n </div>\n\n <div class=\"editor-field\">\n <div class=\"editor-recipients-header\">\n <label class=\"editor-label\">Additional recipients</label>\n <button mjButton variant=\"outline\" size=\"sm\" (click)=\"AddRecipient()\">\n <i class=\"fa-solid fa-plus\"></i> Add recipient\n </button>\n </div>\n @if (Recipients.length === 0) {\n <div class=\"editor-hint\">Only you (the owner) will be notified.</div>\n }\n @for (row of Recipients; track $index; let i = $index; let first = $first; let last = $last) {\n <div class=\"editor-recipient-row\">\n <div class=\"editor-recipient-order\">\n <button mjButton variant=\"icon\" size=\"sm\" title=\"Move up\" [disabled]=\"first\" (click)=\"MoveRecipient(i, -1)\">\n <i class=\"fa-solid fa-chevron-up\"></i>\n </button>\n <button mjButton variant=\"icon\" size=\"sm\" title=\"Move down\" [disabled]=\"last\" (click)=\"MoveRecipient(i, 1)\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n </div>\n <mj-dropdown class=\"editor-recipient-mode\" [Data]=\"RecipientModeOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"row.Mode\" (ngModelChange)=\"OnRecipientModeChange(row)\"></mj-dropdown>\n @if (row.Mode === 'user') {\n <mj-combobox class=\"editor-recipient-target\" [Data]=\"UserOptions\" TextField=\"Name\" ValueField=\"ID\"\n [ValuePrimitive]=\"true\" Placeholder=\"Select a user...\" [(ngModel)]=\"row.UserID\"></mj-combobox>\n } @else {\n <input class=\"mj-input editor-recipient-target\" type=\"email\" placeholder=\"name@example.com\" [(ngModel)]=\"row.Email\" />\n }\n <mj-dropdown class=\"editor-recipient-channel\" [Data]=\"ChannelOptions\" TextField=\"text\" ValueField=\"value\"\n [ValuePrimitive]=\"true\" [(ngModel)]=\"row.Channel\"></mj-dropdown>\n <button mjButton variant=\"icon\" size=\"sm\" title=\"Remove recipient\" (click)=\"RemoveRecipient(i)\">\n <i class=\"fa-solid fa-trash-can\"></i>\n </button>\n </div>\n }\n </div>\n </section>\n }\n\n <!-- ======================= Footer (confirm LEFT, cancel RIGHT) ======================= -->\n <div class=\"editor-footer\">\n <button mjButton variant=\"primary\" size=\"md\" [disabled]=\"IsSaving\" (click)=\"Save()\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n <i class=\"fa-solid fa-check\"></i>\n }\n {{ IsEdit ? 'Save Changes' : 'Create Routine' }}\n </button>\n <button mjButton variant=\"secondary\" size=\"md\" [disabled]=\"IsSaving\" (click)=\"Cancel()\">Cancel</button>\n </div>\n </div>\n}\n"]}
|
|
@@ -50,6 +50,8 @@ export declare class UserRoutinesSlideInComponent extends BaseAngularComponent {
|
|
|
50
50
|
Close(): void;
|
|
51
51
|
OnPanelClosed(): void;
|
|
52
52
|
/** Applies InitialRoutineID / StartInNewRoutine once the command center is mounted. */
|
|
53
|
+
ApplyInitialView(): void;
|
|
54
|
+
/** @deprecated Use {@link ApplyInitialView}. */
|
|
53
55
|
applyInitialView(): void;
|
|
54
56
|
static ɵfac: i0.ɵɵFactoryDeclaration<UserRoutinesSlideInComponent, never>;
|
|
55
57
|
static ɵcmp: i0.ɵɵComponentDeclaration<UserRoutinesSlideInComponent, "mj-user-routines-slide-in", never, { "Visible": { "alias": "Visible"; "required": false; }; "WidthPx": { "alias": "WidthPx"; "required": false; }; "InitialRoutineID": { "alias": "InitialRoutineID"; "required": false; }; "StartInNewRoutine": { "alias": "StartInNewRoutine"; "required": false; }; }, { "VisibleChange": "VisibleChange"; "Closed": "Closed"; "BeforeRoutineCreated": "BeforeRoutineCreated"; "AfterRoutineCreated": "AfterRoutineCreated"; "BeforeRoutinePaused": "BeforeRoutinePaused"; "AfterRoutinePaused": "AfterRoutinePaused"; "BeforeRoutineRunNow": "BeforeRoutineRunNow"; "AfterRoutineRunNow": "AfterRoutineRunNow"; "BeforeRoutineDeleted": "BeforeRoutineDeleted"; "AfterRoutineDeleted": "AfterRoutineDeleted"; "RoutineSelected": "RoutineSelected"; "HistoryRecordOpened": "HistoryRecordOpened"; "ConversationOpened": "ConversationOpened"; }, never, never, false, never>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-routines-slide-in.component.d.ts","sourceRoot":"","sources":["../../src/lib/user-routines-slide-in.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,YAAY,EAAoC,MAAM,eAAe,CAAC;AAC7G,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,2BAA2B,EAChC,4BAA4B,EAC5B,4BAA4B,EAC5B,2BAA2B,EAC3B,2BAA2B,EAC3B,6BAA6B,EAC7B,6BAA6B,EAC7B,4BAA4B,EAC5B,4BAA4B,EAC5B,4BAA4B,EAC5B,wBAAwB,EAC3B,MAAM,wBAAwB,CAAC;;AAGhC;;;;;;;GAOG;AACH,qBAMa,4BAA6B,SAAQ,oBAAoB;IAClE,OAAO,CAAC,GAAG,CAA6B;IAEZ,OAAO,CAAC,aAAa,CAAC,CAAqC;IAKvF,OAAO,CAAC,QAAQ,CAAS;IACzB,qEAAqE;IACrE,IACW,OAAO,CAAC,KAAK,EAAE,OAAO,EAWhC;IACD,IAAW,OAAO,IAAI,OAAO,CAE5B;IAED,qCAAqC;IAC5B,OAAO,SAAO;IAEvB;;;OAGG;IACM,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEhD,8EAA8E;IACrE,iBAAiB,UAAS;IAKzB,aAAa,wBAA+B;IACtD,qDAAqD;IAC3C,MAAM,qBAA4B;IAGlC,oBAAoB,8CAAqD;IACzE,mBAAmB,6CAAoD;IACvE,mBAAmB,6CAAoD;IACvE,kBAAkB,4CAAmD;IACrE,mBAAmB,6CAAoD;IACvE,kBAAkB,4CAAmD;IACrE,oBAAoB,8CAAqD;IACzE,mBAAmB,6CAAoD;IACvE,eAAe,yCAAgD;IAC/D,mBAAmB,6CAAoD;IACjF,uEAAuE;IAC7D,kBAAkB,4CAAmD;IAE/E,uFAAuF;IAChF,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAUzE,2BAA2B;IACpB,KAAK,IAAI,IAAI;IASb,aAAa,IAAI,IAAI;IAI5B,uFAAuF;IAChF,gBAAgB,IAAI,IAAI;
|
|
1
|
+
{"version":3,"file":"user-routines-slide-in.component.d.ts","sourceRoot":"","sources":["../../src/lib/user-routines-slide-in.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,YAAY,EAAoC,MAAM,eAAe,CAAC;AAC7G,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,2BAA2B,EAChC,4BAA4B,EAC5B,4BAA4B,EAC5B,2BAA2B,EAC3B,2BAA2B,EAC3B,6BAA6B,EAC7B,6BAA6B,EAC7B,4BAA4B,EAC5B,4BAA4B,EAC5B,4BAA4B,EAC5B,wBAAwB,EAC3B,MAAM,wBAAwB,CAAC;;AAGhC;;;;;;;GAOG;AACH,qBAMa,4BAA6B,SAAQ,oBAAoB;IAClE,OAAO,CAAC,GAAG,CAA6B;IAEZ,OAAO,CAAC,aAAa,CAAC,CAAqC;IAKvF,OAAO,CAAC,QAAQ,CAAS;IACzB,qEAAqE;IACrE,IACW,OAAO,CAAC,KAAK,EAAE,OAAO,EAWhC;IACD,IAAW,OAAO,IAAI,OAAO,CAE5B;IAED,qCAAqC;IAC5B,OAAO,SAAO;IAEvB;;;OAGG;IACM,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEhD,8EAA8E;IACrE,iBAAiB,UAAS;IAKzB,aAAa,wBAA+B;IACtD,qDAAqD;IAC3C,MAAM,qBAA4B;IAGlC,oBAAoB,8CAAqD;IACzE,mBAAmB,6CAAoD;IACvE,mBAAmB,6CAAoD;IACvE,kBAAkB,4CAAmD;IACrE,mBAAmB,6CAAoD;IACvE,kBAAkB,4CAAmD;IACrE,oBAAoB,8CAAqD;IACzE,mBAAmB,6CAAoD;IACvE,eAAe,yCAAgD;IAC/D,mBAAmB,6CAAoD;IACjF,uEAAuE;IAC7D,kBAAkB,4CAAmD;IAE/E,uFAAuF;IAChF,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAUzE,2BAA2B;IACpB,KAAK,IAAI,IAAI;IASb,aAAa,IAAI,IAAI;IAI5B,uFAAuF;IAChF,gBAAgB,IAAI,IAAI;IAY/B,gDAAgD;IACzC,gBAAgB,IAAI,IAAI;yCAnGtB,4BAA4B;2CAA5B,4BAA4B;CAsGxC"}
|
|
@@ -38,7 +38,7 @@ export class UserRoutinesSlideInComponent extends BaseAngularComponent {
|
|
|
38
38
|
// Declarative open ([(Visible)] binding) must honor InitialRoutineID /
|
|
39
39
|
// StartInNewRoutine exactly like the imperative Open() path. The command
|
|
40
40
|
// center mounts via @if — apply the initial view next tick.
|
|
41
|
-
Promise.resolve().then(() => this.
|
|
41
|
+
Promise.resolve().then(() => this.ApplyInitialView());
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
}
|
|
@@ -81,7 +81,7 @@ export class UserRoutinesSlideInComponent extends BaseAngularComponent {
|
|
|
81
81
|
this.VisibleChange.emit(true);
|
|
82
82
|
this.cdr.markForCheck();
|
|
83
83
|
// The command center mounts via @if — apply the initial view next tick
|
|
84
|
-
Promise.resolve().then(() => this.
|
|
84
|
+
Promise.resolve().then(() => this.ApplyInitialView());
|
|
85
85
|
}
|
|
86
86
|
/** Closes the slide-in. */
|
|
87
87
|
Close() {
|
|
@@ -96,7 +96,7 @@ export class UserRoutinesSlideInComponent extends BaseAngularComponent {
|
|
|
96
96
|
this.Close();
|
|
97
97
|
}
|
|
98
98
|
/** Applies InitialRoutineID / StartInNewRoutine once the command center is mounted. */
|
|
99
|
-
|
|
99
|
+
ApplyInitialView() {
|
|
100
100
|
const cc = this.commandCenter;
|
|
101
101
|
if (!cc) {
|
|
102
102
|
return;
|
|
@@ -108,6 +108,10 @@ export class UserRoutinesSlideInComponent extends BaseAngularComponent {
|
|
|
108
108
|
cc.ShowHistory(this.InitialRoutineID);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
+
/** @deprecated Use {@link ApplyInitialView}. */
|
|
112
|
+
applyInitialView() {
|
|
113
|
+
return this.ApplyInitialView();
|
|
114
|
+
}
|
|
111
115
|
static ɵfac = /*@__PURE__*/ (() => { let ɵUserRoutinesSlideInComponent_BaseFactory; return function UserRoutinesSlideInComponent_Factory(__ngFactoryType__) { return (ɵUserRoutinesSlideInComponent_BaseFactory || (ɵUserRoutinesSlideInComponent_BaseFactory = i0.ɵɵgetInheritedFactory(UserRoutinesSlideInComponent)))(__ngFactoryType__ || UserRoutinesSlideInComponent); }; })();
|
|
112
116
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: UserRoutinesSlideInComponent, selectors: [["mj-user-routines-slide-in"]], viewQuery: function UserRoutinesSlideInComponent_Query(rf, ctx) { if (rf & 1) {
|
|
113
117
|
i0.ɵɵviewQuery(_c0, 5);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-routines-slide-in.component.js","sourceRoot":"","sources":["../../src/lib/user-routines-slide-in.component.ts","../../src/lib/user-routines-slide-in.component.html"],"names":[],"mappings":"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","sourcesContent":["import { ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewChild, inject } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { ConversationOpenedEventArgs,\n AfterRoutineCreatedEventArgs,\n AfterRoutineDeletedEventArgs,\n AfterRoutinePausedEventArgs,\n AfterRoutineRunNowEventArgs,\n BeforeRoutineCreatedEventArgs,\n BeforeRoutineDeletedEventArgs,\n BeforeRoutinePausedEventArgs,\n BeforeRoutineRunNowEventArgs,\n HistoryRecordOpenedEventArgs,\n RoutineSelectedEventArgs,\n} from './user-routines-events';\nimport { UserRoutinesCommandCenterComponent } from './user-routines-command-center.component';\n\n/**\n * Slide-in wrapper for the User Routines command center — the standard right-edge\n * panel (via `mj-slide-panel` from `@memberjunction/ng-ui-components`) hosting the\n * full command center (list / new / history). Used by ng-conversations' sidebar\n * routines section and any other host that wants the drop-in overlay experience.\n *\n * Two-way bind `[(Visible)]`; all command-center events bubble unchanged.\n */\n@Component({\n standalone: false,\n selector: 'mj-user-routines-slide-in',\n templateUrl: './user-routines-slide-in.component.html',\n styleUrls: ['./user-routines-slide-in.component.css'],\n})\nexport class UserRoutinesSlideInComponent extends BaseAngularComponent {\n private cdr = inject(ChangeDetectorRef);\n\n @ViewChild('commandCenter') private commandCenter?: UserRoutinesCommandCenterComponent;\n\n // ---------------------------------------------------------------\n // Inputs\n // ---------------------------------------------------------------\n private _visible = false;\n /** Whether the slide-in is open. Two-way bindable: `[(Visible)]`. */\n @Input()\n public set Visible(value: boolean) {\n if (value !== this._visible) {\n this._visible = value;\n this.cdr.markForCheck();\n if (value) {\n // Declarative open ([(Visible)] binding) must honor InitialRoutineID /\n // StartInNewRoutine exactly like the imperative Open() path. The command\n // center mounts via @if — apply the initial view next tick.\n Promise.resolve().then(() => this.applyInitialView());\n }\n }\n }\n public get Visible(): boolean {\n return this._visible;\n }\n\n /** Initial panel width in pixels. */\n @Input() WidthPx = 720;\n\n /**\n * When set, the command center opens directly on this routine's history each time\n * the slide-in becomes visible with the value set.\n */\n @Input() InitialRoutineID: string | null = null;\n\n /** When true, the command center opens directly on the New Routine editor. */\n @Input() StartInNewRoutine = false;\n\n // ---------------------------------------------------------------\n // Outputs\n // ---------------------------------------------------------------\n @Output() VisibleChange = new EventEmitter<boolean>();\n /** The panel was closed (X, backdrop, or Escape). */\n @Output() Closed = new EventEmitter<void>();\n\n // Bubbled command-center events\n @Output() BeforeRoutineCreated = new EventEmitter<BeforeRoutineCreatedEventArgs>();\n @Output() AfterRoutineCreated = new EventEmitter<AfterRoutineCreatedEventArgs>();\n @Output() BeforeRoutinePaused = new EventEmitter<BeforeRoutinePausedEventArgs>();\n @Output() AfterRoutinePaused = new EventEmitter<AfterRoutinePausedEventArgs>();\n @Output() BeforeRoutineRunNow = new EventEmitter<BeforeRoutineRunNowEventArgs>();\n @Output() AfterRoutineRunNow = new EventEmitter<AfterRoutineRunNowEventArgs>();\n @Output() BeforeRoutineDeleted = new EventEmitter<BeforeRoutineDeletedEventArgs>();\n @Output() AfterRoutineDeleted = new EventEmitter<AfterRoutineDeletedEventArgs>();\n @Output() RoutineSelected = new EventEmitter<RoutineSelectedEventArgs>();\n @Output() HistoryRecordOpened = new EventEmitter<HistoryRecordOpenedEventArgs>();\n /** Re-emitted — the routine's dedicated conversation was requested. */\n @Output() ConversationOpened = new EventEmitter<ConversationOpenedEventArgs>();\n\n /** Opens the slide-in (optionally straight onto a routine's history or the editor). */\n public Open(options?: { RoutineID?: string; NewRoutine?: boolean }): void {\n this.InitialRoutineID = options?.RoutineID ?? null;\n this.StartInNewRoutine = options?.NewRoutine ?? false;\n this._visible = true;\n this.VisibleChange.emit(true);\n this.cdr.markForCheck();\n // The command center mounts via @if — apply the initial view next tick\n Promise.resolve().then(() => this.applyInitialView());\n }\n\n /** Closes the slide-in. */\n public Close(): void {\n if (this._visible) {\n this._visible = false;\n this.VisibleChange.emit(false);\n this.Closed.emit();\n this.cdr.markForCheck();\n }\n }\n\n public OnPanelClosed(): void {\n this.Close();\n }\n\n /** Applies InitialRoutineID / StartInNewRoutine once the command center is mounted. */\n public applyInitialView(): void {\n const cc = this.commandCenter;\n if (!cc) {\n return;\n }\n if (this.StartInNewRoutine) {\n cc.ShowNewRoutine();\n } else if (this.InitialRoutineID) {\n cc.ShowHistory(this.InitialRoutineID);\n }\n }\n}\n","<mj-slide-panel Mode=\"slide\" Title=\"\" [Visible]=\"Visible\" [WidthPx]=\"WidthPx\" [MinWidthPx]=\"480\"\n (Closed)=\"OnPanelClosed()\">\n @if (Visible) {\n <div class=\"ur-slidein\">\n <mj-user-routines-command-center #commandCenter\n [Provider]=\"Provider\"\n [ShowHeader]=\"true\"\n [ShowClose]=\"true\"\n (CloseRequested)=\"Close()\"\n (BeforeRoutineCreated)=\"BeforeRoutineCreated.emit($event)\"\n (AfterRoutineCreated)=\"AfterRoutineCreated.emit($event)\"\n (BeforeRoutinePaused)=\"BeforeRoutinePaused.emit($event)\"\n (AfterRoutinePaused)=\"AfterRoutinePaused.emit($event)\"\n (BeforeRoutineRunNow)=\"BeforeRoutineRunNow.emit($event)\"\n (AfterRoutineRunNow)=\"AfterRoutineRunNow.emit($event)\"\n (BeforeRoutineDeleted)=\"BeforeRoutineDeleted.emit($event)\"\n (AfterRoutineDeleted)=\"AfterRoutineDeleted.emit($event)\"\n (RoutineSelected)=\"RoutineSelected.emit($event)\"\n (HistoryRecordOpened)=\"HistoryRecordOpened.emit($event)\"\n (ConversationOpened)=\"ConversationOpened.emit($event)\">\n </mj-user-routines-command-center>\n </div>\n }\n</mj-slide-panel>\n"]}
|
|
1
|
+
{"version":3,"file":"user-routines-slide-in.component.js","sourceRoot":"","sources":["../../src/lib/user-routines-slide-in.component.ts","../../src/lib/user-routines-slide-in.component.html"],"names":[],"mappings":"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","sourcesContent":["import { ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewChild, inject } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { ConversationOpenedEventArgs,\n AfterRoutineCreatedEventArgs,\n AfterRoutineDeletedEventArgs,\n AfterRoutinePausedEventArgs,\n AfterRoutineRunNowEventArgs,\n BeforeRoutineCreatedEventArgs,\n BeforeRoutineDeletedEventArgs,\n BeforeRoutinePausedEventArgs,\n BeforeRoutineRunNowEventArgs,\n HistoryRecordOpenedEventArgs,\n RoutineSelectedEventArgs,\n} from './user-routines-events';\nimport { UserRoutinesCommandCenterComponent } from './user-routines-command-center.component';\n\n/**\n * Slide-in wrapper for the User Routines command center — the standard right-edge\n * panel (via `mj-slide-panel` from `@memberjunction/ng-ui-components`) hosting the\n * full command center (list / new / history). Used by ng-conversations' sidebar\n * routines section and any other host that wants the drop-in overlay experience.\n *\n * Two-way bind `[(Visible)]`; all command-center events bubble unchanged.\n */\n@Component({\n standalone: false,\n selector: 'mj-user-routines-slide-in',\n templateUrl: './user-routines-slide-in.component.html',\n styleUrls: ['./user-routines-slide-in.component.css'],\n})\nexport class UserRoutinesSlideInComponent extends BaseAngularComponent {\n private cdr = inject(ChangeDetectorRef);\n\n @ViewChild('commandCenter') private commandCenter?: UserRoutinesCommandCenterComponent;\n\n // ---------------------------------------------------------------\n // Inputs\n // ---------------------------------------------------------------\n private _visible = false;\n /** Whether the slide-in is open. Two-way bindable: `[(Visible)]`. */\n @Input()\n public set Visible(value: boolean) {\n if (value !== this._visible) {\n this._visible = value;\n this.cdr.markForCheck();\n if (value) {\n // Declarative open ([(Visible)] binding) must honor InitialRoutineID /\n // StartInNewRoutine exactly like the imperative Open() path. The command\n // center mounts via @if — apply the initial view next tick.\n Promise.resolve().then(() => this.ApplyInitialView());\n }\n }\n }\n public get Visible(): boolean {\n return this._visible;\n }\n\n /** Initial panel width in pixels. */\n @Input() WidthPx = 720;\n\n /**\n * When set, the command center opens directly on this routine's history each time\n * the slide-in becomes visible with the value set.\n */\n @Input() InitialRoutineID: string | null = null;\n\n /** When true, the command center opens directly on the New Routine editor. */\n @Input() StartInNewRoutine = false;\n\n // ---------------------------------------------------------------\n // Outputs\n // ---------------------------------------------------------------\n @Output() VisibleChange = new EventEmitter<boolean>();\n /** The panel was closed (X, backdrop, or Escape). */\n @Output() Closed = new EventEmitter<void>();\n\n // Bubbled command-center events\n @Output() BeforeRoutineCreated = new EventEmitter<BeforeRoutineCreatedEventArgs>();\n @Output() AfterRoutineCreated = new EventEmitter<AfterRoutineCreatedEventArgs>();\n @Output() BeforeRoutinePaused = new EventEmitter<BeforeRoutinePausedEventArgs>();\n @Output() AfterRoutinePaused = new EventEmitter<AfterRoutinePausedEventArgs>();\n @Output() BeforeRoutineRunNow = new EventEmitter<BeforeRoutineRunNowEventArgs>();\n @Output() AfterRoutineRunNow = new EventEmitter<AfterRoutineRunNowEventArgs>();\n @Output() BeforeRoutineDeleted = new EventEmitter<BeforeRoutineDeletedEventArgs>();\n @Output() AfterRoutineDeleted = new EventEmitter<AfterRoutineDeletedEventArgs>();\n @Output() RoutineSelected = new EventEmitter<RoutineSelectedEventArgs>();\n @Output() HistoryRecordOpened = new EventEmitter<HistoryRecordOpenedEventArgs>();\n /** Re-emitted — the routine's dedicated conversation was requested. */\n @Output() ConversationOpened = new EventEmitter<ConversationOpenedEventArgs>();\n\n /** Opens the slide-in (optionally straight onto a routine's history or the editor). */\n public Open(options?: { RoutineID?: string; NewRoutine?: boolean }): void {\n this.InitialRoutineID = options?.RoutineID ?? null;\n this.StartInNewRoutine = options?.NewRoutine ?? false;\n this._visible = true;\n this.VisibleChange.emit(true);\n this.cdr.markForCheck();\n // The command center mounts via @if — apply the initial view next tick\n Promise.resolve().then(() => this.ApplyInitialView());\n }\n\n /** Closes the slide-in. */\n public Close(): void {\n if (this._visible) {\n this._visible = false;\n this.VisibleChange.emit(false);\n this.Closed.emit();\n this.cdr.markForCheck();\n }\n }\n\n public OnPanelClosed(): void {\n this.Close();\n }\n\n /** Applies InitialRoutineID / StartInNewRoutine once the command center is mounted. */\n public ApplyInitialView(): void {\n const cc = this.commandCenter;\n if (!cc) {\n return;\n }\n if (this.StartInNewRoutine) {\n cc.ShowNewRoutine();\n } else if (this.InitialRoutineID) {\n cc.ShowHistory(this.InitialRoutineID);\n }\n }\n\n /** @deprecated Use {@link ApplyInitialView}. */\n public applyInitialView(): void {\n return this.ApplyInitialView();\n }\n}\n","<mj-slide-panel Mode=\"slide\" Title=\"\" [Visible]=\"Visible\" [WidthPx]=\"WidthPx\" [MinWidthPx]=\"480\"\n (Closed)=\"OnPanelClosed()\">\n @if (Visible) {\n <div class=\"ur-slidein\">\n <mj-user-routines-command-center #commandCenter\n [Provider]=\"Provider\"\n [ShowHeader]=\"true\"\n [ShowClose]=\"true\"\n (CloseRequested)=\"Close()\"\n (BeforeRoutineCreated)=\"BeforeRoutineCreated.emit($event)\"\n (AfterRoutineCreated)=\"AfterRoutineCreated.emit($event)\"\n (BeforeRoutinePaused)=\"BeforeRoutinePaused.emit($event)\"\n (AfterRoutinePaused)=\"AfterRoutinePaused.emit($event)\"\n (BeforeRoutineRunNow)=\"BeforeRoutineRunNow.emit($event)\"\n (AfterRoutineRunNow)=\"AfterRoutineRunNow.emit($event)\"\n (BeforeRoutineDeleted)=\"BeforeRoutineDeleted.emit($event)\"\n (AfterRoutineDeleted)=\"AfterRoutineDeleted.emit($event)\"\n (RoutineSelected)=\"RoutineSelected.emit($event)\"\n (HistoryRecordOpened)=\"HistoryRecordOpened.emit($event)\"\n (ConversationOpened)=\"ConversationOpened.emit($event)\">\n </mj-user-routines-command-center>\n </div>\n }\n</mj-slide-panel>\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-user-routines",
|
|
3
|
-
"version": "6.2.0-edge.
|
|
3
|
+
"version": "6.2.0-edge.1",
|
|
4
4
|
"description": "MemberJunction: Reusable Angular components for User Routines — list, editor, and run history for cron-scheduled Agent / Action / Prompt routines",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"@angular/compiler": "21.2.22",
|
|
15
15
|
"@angular/compiler-cli": "21.2.22",
|
|
16
16
|
"vitest": "^4.0.18",
|
|
17
|
-
"@memberjunction/ng-test-utils": "6.2.0-edge.
|
|
17
|
+
"@memberjunction/ng-test-utils": "6.2.0-edge.1"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
20
|
"@angular/animations": "^21.2.22",
|
|
@@ -24,19 +24,19 @@
|
|
|
24
24
|
"@angular/platform-browser": "^21.2.22"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@memberjunction/actions-base": "6.2.0-edge.
|
|
28
|
-
"@memberjunction/ai-engine-base": "6.2.0-edge.
|
|
29
|
-
"@memberjunction/core": "6.2.0-edge.
|
|
30
|
-
"@memberjunction/core-entities": "6.2.0-edge.
|
|
31
|
-
"@memberjunction/global": "6.2.0-edge.
|
|
32
|
-
"@memberjunction/ng-base-types": "6.2.0-edge.
|
|
33
|
-
"@memberjunction/ng-code-editor": "6.2.0-edge.
|
|
34
|
-
"@memberjunction/ng-composer": "6.2.0-edge.
|
|
35
|
-
"@memberjunction/ng-container-directives": "6.2.0-edge.
|
|
36
|
-
"@memberjunction/ng-notifications": "6.2.0-edge.
|
|
37
|
-
"@memberjunction/ng-shared-generic": "6.2.0-edge.
|
|
38
|
-
"@memberjunction/ng-trees": "6.2.0-edge.
|
|
39
|
-
"@memberjunction/ng-ui-components": "6.2.0-edge.
|
|
27
|
+
"@memberjunction/actions-base": "6.2.0-edge.1",
|
|
28
|
+
"@memberjunction/ai-engine-base": "6.2.0-edge.1",
|
|
29
|
+
"@memberjunction/core": "6.2.0-edge.1",
|
|
30
|
+
"@memberjunction/core-entities": "6.2.0-edge.1",
|
|
31
|
+
"@memberjunction/global": "6.2.0-edge.1",
|
|
32
|
+
"@memberjunction/ng-base-types": "6.2.0-edge.1",
|
|
33
|
+
"@memberjunction/ng-code-editor": "6.2.0-edge.1",
|
|
34
|
+
"@memberjunction/ng-composer": "6.2.0-edge.1",
|
|
35
|
+
"@memberjunction/ng-container-directives": "6.2.0-edge.1",
|
|
36
|
+
"@memberjunction/ng-notifications": "6.2.0-edge.1",
|
|
37
|
+
"@memberjunction/ng-shared-generic": "6.2.0-edge.1",
|
|
38
|
+
"@memberjunction/ng-trees": "6.2.0-edge.1",
|
|
39
|
+
"@memberjunction/ng-ui-components": "6.2.0-edge.1",
|
|
40
40
|
"rxjs": "^7.8.2",
|
|
41
41
|
"tslib": "^2.8.1"
|
|
42
42
|
},
|