@memberjunction/ng-scheduling 5.33.0 → 5.34.0
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.
|
@@ -226,11 +226,11 @@ export class ScheduledJobEditorComponent extends BaseAngularComponent {
|
|
|
226
226
|
this.FailedRuns = runs.filter(r => r.Status === 'Failed').length;
|
|
227
227
|
}
|
|
228
228
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ScheduledJobEditorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
229
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ScheduledJobEditorComponent, isStandalone: false, selector: "mj-scheduled-job-editor", inputs: { ScheduledJobID: "ScheduledJobID", JobTypeID: "JobTypeID", DefaultConfiguration: "DefaultConfiguration", HideJobType: "HideJobType" }, outputs: { Saved: "Saved", Deleted: "Deleted", Cancelled: "Cancelled" }, usesInheritance: true, ngImport: i0, template: "@if (IsLoading) {\n <div class=\"editor-loading\">\n <mj-loading text=\"Loading...\"></mj-loading>\n </div>\n} @else {\n <div class=\"editor-container\">\n <!-- General Section -->\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-circle-info\"></i> General\n </div>\n\n <div class=\"form-group\">\n <label for=\"jobName\">Name <span class=\"required\">*</span></label>\n <input id=\"jobName\" type=\"text\" [(ngModel)]=\"Name\" placeholder=\"Job name\" />\n </div>\n\n <div class=\"form-group\">\n <label for=\"jobDesc\">Description</label>\n <textarea id=\"jobDesc\" [(ngModel)]=\"Description\" rows=\"2\" placeholder=\"Optional description\"></textarea>\n </div>\n\n @if (!HideJobType) {\n <div class=\"form-group\">\n <label for=\"jobType\">Job Type <span class=\"required\">*</span></label>\n <select id=\"jobType\" [(ngModel)]=\"SelectedJobTypeID\">\n <option value=\"\">-- Select Type --</option>\n @for (jt of JobTypes; track jt.ID) {\n <option [value]=\"jt.ID\">{{ jt.Name }}</option>\n }\n </select>\n </div>\n }\n\n <div class=\"form-group\">\n <label for=\"jobStatus\">Status</label>\n <select id=\"jobStatus\" [(ngModel)]=\"Status\">\n @for (s of StatusOptions; track s) {\n <option [value]=\"s\">{{ s }}</option>\n }\n </select>\n </div>\n </div>\n\n <!-- Schedule Section -->\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-clock\"></i> Schedule\n </div>\n\n <div class=\"form-group\">\n <label for=\"cronExpr\">Cron Expression <span class=\"required\">*</span></label>\n <input id=\"cronExpr\" type=\"text\" [(ngModel)]=\"CronExpression\"\n placeholder=\"e.g. 0 */15 * * * *\" />\n <div class=\"hint\">Standard cron format: second minute hour day month weekday</div>\n </div>\n\n <div class=\"form-group\">\n <label for=\"timezone\">Timezone</label>\n <select id=\"timezone\" [(ngModel)]=\"Timezone\">\n @for (tz of Timezones; track tz) {\n <option [value]=\"tz\">{{ tz }}</option>\n }\n </select>\n </div>\n\n <div class=\"form-group\">\n <label for=\"concurrency\">Concurrency</label>\n <select id=\"concurrency\" [(ngModel)]=\"ConcurrencyMode\">\n @for (c of ConcurrencyOptions; track c) {\n <option [value]=\"c\">{{ c }}</option>\n }\n </select>\n </div>\n </div>\n\n <!-- Configuration Section -->\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-code\"></i> Configuration\n </div>\n\n <div class=\"form-group\">\n <label for=\"config\">Configuration JSON</label>\n <textarea id=\"config\" [(ngModel)]=\"Configuration\" rows=\"6\"\n class=\"code-textarea\"\n placeholder='{ \"key\": \"value\" }'></textarea>\n </div>\n </div>\n\n <!-- Notifications Section -->\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-bell\"></i> Notifications\n </div>\n\n <div class=\"toggle-row\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" [(ngModel)]=\"NotifyOnSuccess\" />\n Notify on success\n </label>\n </div>\n <div class=\"toggle-row\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" [(ngModel)]=\"NotifyOnFailure\" />\n Notify on failure\n </label>\n </div>\n </div>\n\n <!-- Statistics (edit mode only) -->\n @if (!IsNew && TotalRuns > 0) {\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-chart-bar\"></i> Statistics\n </div>\n <div class=\"stats-grid\">\n <div class=\"stat-item\">\n <span class=\"stat-value\">{{ TotalRuns }}</span>\n <span class=\"stat-label\">Total Runs</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-value success\">{{ SuccessRuns }}</span>\n <span class=\"stat-label\">Succeeded</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-value error\">{{ FailedRuns }}</span>\n <span class=\"stat-label\">Failed</span>\n </div>\n </div>\n </div>\n }\n\n <!-- Footer Actions -->\n <div class=\"editor-footer\">\n @if (!IsNew) {\n <button class=\"btn btn-danger\" (click)=\"ConfirmDelete()\" [disabled]=\"IsSaving\">\n <i class=\"fa-solid fa-trash\"></i> Delete\n </button>\n }\n <div class=\"footer-right\">\n <button class=\"btn btn-primary\" (click)=\"Save()\" [disabled]=\"!CanSave || IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n }\n {{ IsNew ? 'Create' : 'Save' }}\n </button>\n <button class=\"btn btn-secondary\" (click)=\"Cancel()\" [disabled]=\"IsSaving\">\n Cancel\n </button>\n </div>\n </div>\n\n <!-- Delete Confirmation -->\n @if (ShowDeleteConfirm) {\n <div class=\"confirm-overlay\" (click)=\"CancelDelete()\">\n <div class=\"confirm-dialog\" (click)=\"$event.stopPropagation()\">\n <p>Are you sure you want to delete this scheduled job?</p>\n <div class=\"confirm-actions\">\n <button class=\"btn btn-danger\" (click)=\"DeleteJob()\">Delete</button>\n <button class=\"btn btn-secondary\" (click)=\"CancelDelete()\">Cancel</button>\n </div>\n </div>\n </div>\n }\n </div>\n}\n", styles: [".editor-loading {\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 40px;\n}\n\n.editor-container {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 16px;\n}\n\n.form-section {\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n padding: 16px;\n background: #fff;\n}\n\n.section-title {\n font-size: 14px;\n font-weight: 600;\n color: #334155;\n margin-bottom: 12px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.section-title i {\n color: #0076b6;\n font-size: 14px;\n}\n\n.form-group {\n margin-bottom: 12px;\n}\n\n.form-group:last-child {\n margin-bottom: 0;\n}\n\n.form-group label {\n display: block;\n font-size: 12px;\n font-weight: 500;\n color: #64748b;\n margin-bottom: 4px;\n}\n\n.required {\n color: #ef4444;\n}\n\n.form-group input,\n.form-group textarea,\n.form-group select {\n width: 100%;\n padding: 8px 10px;\n border: 1px solid #cbd5e1;\n border-radius: 6px;\n font-size: 13px;\n color: #1e293b;\n background: #fff;\n box-sizing: border-box;\n transition: border-color 0.15s;\n}\n\n.form-group input:focus,\n.form-group textarea:focus,\n.form-group select:focus {\n outline: none;\n border-color: #0076b6;\n box-shadow: 0 0 0 2px rgba(0, 118, 182, 0.15);\n}\n\n.code-textarea {\n font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n font-size: 12px;\n line-height: 1.5;\n}\n\n.hint {\n font-size: 11px;\n color: #94a3b8;\n margin-top: 4px;\n}\n\n.toggle-row {\n margin-bottom: 8px;\n}\n\n.toggle-label {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n color: #334155;\n cursor: pointer;\n}\n\n.toggle-label input[type=\"checkbox\"] {\n width: auto;\n}\n\n.stats-grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 12px;\n}\n\n.stat-item {\n text-align: center;\n}\n\n.stat-value {\n display: block;\n font-size: 20px;\n font-weight: 700;\n color: #334155;\n}\n\n.stat-value.success {\n color: #10b981;\n}\n\n.stat-value.error {\n color: #ef4444;\n}\n\n.stat-label {\n display: block;\n font-size: 11px;\n color: #94a3b8;\n margin-top: 2px;\n}\n\n.editor-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-top: 8px;\n border-top: 1px solid #e2e8f0;\n}\n\n.footer-right {\n display: flex;\n gap: 8px;\n margin-left: auto;\n}\n\n.btn {\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n transition: background 0.15s, opacity 0.15s;\n}\n\n.btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.btn-primary {\n background: #0076b6;\n color: #fff;\n}\n\n.btn-primary:hover:not(:disabled) {\n background: #005a8c;\n}\n\n.btn-secondary {\n background: #f1f5f9;\n color: #334155;\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: #e2e8f0;\n}\n\n.btn-danger {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.btn-danger:hover:not(:disabled) {\n background: #fecaca;\n}\n\n.confirm-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 1100;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.confirm-dialog {\n background: #fff;\n border-radius: 10px;\n padding: 24px;\n max-width: 360px;\n text-align: center;\n box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);\n}\n\n.confirm-dialog p {\n margin: 0 0 16px;\n color: #334155;\n font-size: 14px;\n}\n\n.confirm-actions {\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n\n@media (max-width: 480px) {\n .stats-grid {\n grid-template-columns: 1fr;\n }\n\n .editor-footer {\n flex-direction: column;\n gap: 8px;\n }\n\n .footer-right {\n margin-left: 0;\n width: 100%;\n }\n\n .footer-right .btn {\n flex: 1;\n justify-content: center;\n }\n}\n"], dependencies: [{ kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.LoadingComponent, selector: "mj-loading", inputs: ["text", "showText", "animationDuration", "size", "textColor", "logoColor", "logoGradient", "animation"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
229
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ScheduledJobEditorComponent, isStandalone: false, selector: "mj-scheduled-job-editor", inputs: { ScheduledJobID: "ScheduledJobID", JobTypeID: "JobTypeID", DefaultConfiguration: "DefaultConfiguration", HideJobType: "HideJobType" }, outputs: { Saved: "Saved", Deleted: "Deleted", Cancelled: "Cancelled" }, usesInheritance: true, ngImport: i0, template: "@if (IsLoading) {\n <div class=\"editor-loading\">\n <mj-loading text=\"Loading...\"></mj-loading>\n </div>\n} @else {\n <div class=\"editor-container\">\n <!-- General Section -->\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-circle-info\"></i> General\n </div>\n\n <div class=\"form-group\">\n <label for=\"jobName\">Name <span class=\"required\">*</span></label>\n <input id=\"jobName\" type=\"text\" [(ngModel)]=\"Name\" placeholder=\"Job name\" />\n </div>\n\n <div class=\"form-group\">\n <label for=\"jobDesc\">Description</label>\n <textarea id=\"jobDesc\" [(ngModel)]=\"Description\" rows=\"2\" placeholder=\"Optional description\"></textarea>\n </div>\n\n @if (!HideJobType) {\n <div class=\"form-group\">\n <label for=\"jobType\">Job Type <span class=\"required\">*</span></label>\n <select id=\"jobType\" [(ngModel)]=\"SelectedJobTypeID\">\n <option value=\"\">-- Select Type --</option>\n @for (jt of JobTypes; track jt.ID) {\n <option [value]=\"jt.ID\">{{ jt.Name }}</option>\n }\n </select>\n </div>\n }\n\n <div class=\"form-group\">\n <label for=\"jobStatus\">Status</label>\n <select id=\"jobStatus\" [(ngModel)]=\"Status\">\n @for (s of StatusOptions; track s) {\n <option [value]=\"s\">{{ s }}</option>\n }\n </select>\n </div>\n </div>\n\n <!-- Schedule Section -->\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-clock\"></i> Schedule\n </div>\n\n <div class=\"form-group\">\n <label for=\"cronExpr\">Cron Expression <span class=\"required\">*</span></label>\n <input id=\"cronExpr\" type=\"text\" [(ngModel)]=\"CronExpression\"\n placeholder=\"e.g. 0 */15 * * * *\" />\n <div class=\"hint\">Standard cron format: second minute hour day month weekday</div>\n </div>\n\n <div class=\"form-group\">\n <label for=\"timezone\">Timezone</label>\n <select id=\"timezone\" [(ngModel)]=\"Timezone\">\n @for (tz of Timezones; track tz) {\n <option [value]=\"tz\">{{ tz }}</option>\n }\n </select>\n </div>\n\n <div class=\"form-group\">\n <label for=\"concurrency\">Concurrency</label>\n <select id=\"concurrency\" [(ngModel)]=\"ConcurrencyMode\">\n @for (c of ConcurrencyOptions; track c) {\n <option [value]=\"c\">{{ c }}</option>\n }\n </select>\n </div>\n </div>\n\n <!-- Configuration Section -->\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-code\"></i> Configuration\n </div>\n\n <div class=\"form-group\">\n <label for=\"config\">Configuration JSON</label>\n <textarea id=\"config\" [(ngModel)]=\"Configuration\" rows=\"6\"\n class=\"code-textarea\"\n placeholder='{ \"key\": \"value\" }'></textarea>\n </div>\n </div>\n\n <!-- Notifications Section -->\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-bell\"></i> Notifications\n </div>\n\n <div class=\"toggle-row\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" [(ngModel)]=\"NotifyOnSuccess\" />\n Notify on success\n </label>\n </div>\n <div class=\"toggle-row\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" [(ngModel)]=\"NotifyOnFailure\" />\n Notify on failure\n </label>\n </div>\n </div>\n\n <!-- Statistics (edit mode only) -->\n @if (!IsNew && TotalRuns > 0) {\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-chart-bar\"></i> Statistics\n </div>\n <div class=\"stats-grid\">\n <div class=\"stat-item\">\n <span class=\"stat-value\">{{ TotalRuns }}</span>\n <span class=\"stat-label\">Total Runs</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-value success\">{{ SuccessRuns }}</span>\n <span class=\"stat-label\">Succeeded</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-value error\">{{ FailedRuns }}</span>\n <span class=\"stat-label\">Failed</span>\n </div>\n </div>\n </div>\n }\n\n <!-- Footer Actions -->\n <div class=\"editor-footer\">\n @if (!IsNew) {\n <button class=\"btn btn-danger\" (click)=\"ConfirmDelete()\" [disabled]=\"IsSaving\">\n <i class=\"fa-solid fa-trash\"></i> Delete\n </button>\n }\n <div class=\"footer-right\">\n <button class=\"btn btn-primary\" (click)=\"Save()\" [disabled]=\"!CanSave || IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n }\n {{ IsNew ? 'Create' : 'Save' }}\n </button>\n <button class=\"btn btn-secondary\" (click)=\"Cancel()\" [disabled]=\"IsSaving\">\n Cancel\n </button>\n </div>\n </div>\n\n <!-- Delete Confirmation -->\n @if (ShowDeleteConfirm) {\n <div class=\"confirm-overlay\" (click)=\"CancelDelete()\">\n <div class=\"confirm-dialog\" (click)=\"$event.stopPropagation()\">\n <p>Are you sure you want to delete this scheduled job?</p>\n <div class=\"confirm-actions\">\n <button class=\"btn btn-danger\" (click)=\"DeleteJob()\">Delete</button>\n <button class=\"btn btn-secondary\" (click)=\"CancelDelete()\">Cancel</button>\n </div>\n </div>\n </div>\n }\n </div>\n}\n", styles: [".editor-loading {\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 40px;\n}\n\n.editor-container {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 16px;\n}\n\n.form-section {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 16px;\n background: var(--mj-bg-surface);\n}\n\n.section-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 12px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.section-title i {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.form-group {\n margin-bottom: 12px;\n}\n\n.form-group:last-child {\n margin-bottom: 0;\n}\n\n.form-group label {\n display: block;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n margin-bottom: 4px;\n}\n\n.required {\n color: var(--mj-status-error);\n}\n\n.form-group input,\n.form-group textarea,\n.form-group select {\n width: 100%;\n padding: 8px 10px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n box-sizing: border-box;\n transition: border-color 0.15s;\n}\n\n.form-group input:focus,\n.form-group textarea:focus,\n.form-group select:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.code-textarea {\n font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n font-size: 12px;\n line-height: 1.5;\n}\n\n.hint {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 4px;\n}\n\n.toggle-row {\n margin-bottom: 8px;\n}\n\n.toggle-label {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n color: var(--mj-text-primary);\n cursor: pointer;\n}\n\n.toggle-label input[type=\"checkbox\"] {\n width: auto;\n}\n\n.stats-grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 12px;\n}\n\n.stat-item {\n text-align: center;\n}\n\n.stat-value {\n display: block;\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.stat-value.success {\n color: var(--mj-status-success);\n}\n\n.stat-value.error {\n color: var(--mj-status-error);\n}\n\n.stat-label {\n display: block;\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.editor-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-top: 8px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.footer-right {\n display: flex;\n gap: 8px;\n margin-left: auto;\n}\n\n.btn {\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n transition: background 0.15s, opacity 0.15s;\n}\n\n.btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.btn-primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-secondary {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: var(--mj-bg-surface-active);\n}\n\n.btn-danger {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n}\n\n.btn-danger:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n}\n\n.confirm-overlay {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 1100;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.confirm-dialog {\n background: var(--mj-bg-surface);\n border-radius: 10px;\n padding: 24px;\n max-width: 360px;\n text-align: center;\n box-shadow: var(--mj-shadow-lg);\n}\n\n.confirm-dialog p {\n margin: 0 0 16px;\n color: var(--mj-text-primary);\n font-size: 14px;\n}\n\n.confirm-actions {\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n\n@media (max-width: 480px) {\n .stats-grid {\n grid-template-columns: 1fr;\n }\n\n .editor-footer {\n flex-direction: column;\n gap: 8px;\n }\n\n .footer-right {\n margin-left: 0;\n width: 100%;\n }\n\n .footer-right .btn {\n flex: 1;\n justify-content: center;\n }\n}\n"], dependencies: [{ kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.LoadingComponent, selector: "mj-loading", inputs: ["text", "showText", "animationDuration", "size", "textColor", "logoColor", "logoGradient", "animation"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
230
230
|
}
|
|
231
231
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ScheduledJobEditorComponent, decorators: [{
|
|
232
232
|
type: Component,
|
|
233
|
-
args: [{ selector: 'mj-scheduled-job-editor', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (IsLoading) {\n <div class=\"editor-loading\">\n <mj-loading text=\"Loading...\"></mj-loading>\n </div>\n} @else {\n <div class=\"editor-container\">\n <!-- General Section -->\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-circle-info\"></i> General\n </div>\n\n <div class=\"form-group\">\n <label for=\"jobName\">Name <span class=\"required\">*</span></label>\n <input id=\"jobName\" type=\"text\" [(ngModel)]=\"Name\" placeholder=\"Job name\" />\n </div>\n\n <div class=\"form-group\">\n <label for=\"jobDesc\">Description</label>\n <textarea id=\"jobDesc\" [(ngModel)]=\"Description\" rows=\"2\" placeholder=\"Optional description\"></textarea>\n </div>\n\n @if (!HideJobType) {\n <div class=\"form-group\">\n <label for=\"jobType\">Job Type <span class=\"required\">*</span></label>\n <select id=\"jobType\" [(ngModel)]=\"SelectedJobTypeID\">\n <option value=\"\">-- Select Type --</option>\n @for (jt of JobTypes; track jt.ID) {\n <option [value]=\"jt.ID\">{{ jt.Name }}</option>\n }\n </select>\n </div>\n }\n\n <div class=\"form-group\">\n <label for=\"jobStatus\">Status</label>\n <select id=\"jobStatus\" [(ngModel)]=\"Status\">\n @for (s of StatusOptions; track s) {\n <option [value]=\"s\">{{ s }}</option>\n }\n </select>\n </div>\n </div>\n\n <!-- Schedule Section -->\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-clock\"></i> Schedule\n </div>\n\n <div class=\"form-group\">\n <label for=\"cronExpr\">Cron Expression <span class=\"required\">*</span></label>\n <input id=\"cronExpr\" type=\"text\" [(ngModel)]=\"CronExpression\"\n placeholder=\"e.g. 0 */15 * * * *\" />\n <div class=\"hint\">Standard cron format: second minute hour day month weekday</div>\n </div>\n\n <div class=\"form-group\">\n <label for=\"timezone\">Timezone</label>\n <select id=\"timezone\" [(ngModel)]=\"Timezone\">\n @for (tz of Timezones; track tz) {\n <option [value]=\"tz\">{{ tz }}</option>\n }\n </select>\n </div>\n\n <div class=\"form-group\">\n <label for=\"concurrency\">Concurrency</label>\n <select id=\"concurrency\" [(ngModel)]=\"ConcurrencyMode\">\n @for (c of ConcurrencyOptions; track c) {\n <option [value]=\"c\">{{ c }}</option>\n }\n </select>\n </div>\n </div>\n\n <!-- Configuration Section -->\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-code\"></i> Configuration\n </div>\n\n <div class=\"form-group\">\n <label for=\"config\">Configuration JSON</label>\n <textarea id=\"config\" [(ngModel)]=\"Configuration\" rows=\"6\"\n class=\"code-textarea\"\n placeholder='{ \"key\": \"value\" }'></textarea>\n </div>\n </div>\n\n <!-- Notifications Section -->\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-bell\"></i> Notifications\n </div>\n\n <div class=\"toggle-row\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" [(ngModel)]=\"NotifyOnSuccess\" />\n Notify on success\n </label>\n </div>\n <div class=\"toggle-row\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" [(ngModel)]=\"NotifyOnFailure\" />\n Notify on failure\n </label>\n </div>\n </div>\n\n <!-- Statistics (edit mode only) -->\n @if (!IsNew && TotalRuns > 0) {\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-chart-bar\"></i> Statistics\n </div>\n <div class=\"stats-grid\">\n <div class=\"stat-item\">\n <span class=\"stat-value\">{{ TotalRuns }}</span>\n <span class=\"stat-label\">Total Runs</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-value success\">{{ SuccessRuns }}</span>\n <span class=\"stat-label\">Succeeded</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-value error\">{{ FailedRuns }}</span>\n <span class=\"stat-label\">Failed</span>\n </div>\n </div>\n </div>\n }\n\n <!-- Footer Actions -->\n <div class=\"editor-footer\">\n @if (!IsNew) {\n <button class=\"btn btn-danger\" (click)=\"ConfirmDelete()\" [disabled]=\"IsSaving\">\n <i class=\"fa-solid fa-trash\"></i> Delete\n </button>\n }\n <div class=\"footer-right\">\n <button class=\"btn btn-primary\" (click)=\"Save()\" [disabled]=\"!CanSave || IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n }\n {{ IsNew ? 'Create' : 'Save' }}\n </button>\n <button class=\"btn btn-secondary\" (click)=\"Cancel()\" [disabled]=\"IsSaving\">\n Cancel\n </button>\n </div>\n </div>\n\n <!-- Delete Confirmation -->\n @if (ShowDeleteConfirm) {\n <div class=\"confirm-overlay\" (click)=\"CancelDelete()\">\n <div class=\"confirm-dialog\" (click)=\"$event.stopPropagation()\">\n <p>Are you sure you want to delete this scheduled job?</p>\n <div class=\"confirm-actions\">\n <button class=\"btn btn-danger\" (click)=\"DeleteJob()\">Delete</button>\n <button class=\"btn btn-secondary\" (click)=\"CancelDelete()\">Cancel</button>\n </div>\n </div>\n </div>\n }\n </div>\n}\n", styles: [".editor-loading {\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 40px;\n}\n\n.editor-container {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 16px;\n}\n\n.form-section {\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n padding: 16px;\n background: #fff;\n}\n\n.section-title {\n font-size: 14px;\n font-weight: 600;\n color: #334155;\n margin-bottom: 12px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.section-title i {\n color: #0076b6;\n font-size: 14px;\n}\n\n.form-group {\n margin-bottom: 12px;\n}\n\n.form-group:last-child {\n margin-bottom: 0;\n}\n\n.form-group label {\n display: block;\n font-size: 12px;\n font-weight: 500;\n color: #64748b;\n margin-bottom: 4px;\n}\n\n.required {\n color: #ef4444;\n}\n\n.form-group input,\n.form-group textarea,\n.form-group select {\n width: 100%;\n padding: 8px 10px;\n border: 1px solid #cbd5e1;\n border-radius: 6px;\n font-size: 13px;\n color: #1e293b;\n background: #fff;\n box-sizing: border-box;\n transition: border-color 0.15s;\n}\n\n.form-group input:focus,\n.form-group textarea:focus,\n.form-group select:focus {\n outline: none;\n border-color: #0076b6;\n box-shadow: 0 0 0 2px rgba(0, 118, 182, 0.15);\n}\n\n.code-textarea {\n font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n font-size: 12px;\n line-height: 1.5;\n}\n\n.hint {\n font-size: 11px;\n color: #94a3b8;\n margin-top: 4px;\n}\n\n.toggle-row {\n margin-bottom: 8px;\n}\n\n.toggle-label {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n color: #334155;\n cursor: pointer;\n}\n\n.toggle-label input[type=\"checkbox\"] {\n width: auto;\n}\n\n.stats-grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 12px;\n}\n\n.stat-item {\n text-align: center;\n}\n\n.stat-value {\n display: block;\n font-size: 20px;\n font-weight: 700;\n color: #334155;\n}\n\n.stat-value.success {\n color: #10b981;\n}\n\n.stat-value.error {\n color: #ef4444;\n}\n\n.stat-label {\n display: block;\n font-size: 11px;\n color: #94a3b8;\n margin-top: 2px;\n}\n\n.editor-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-top: 8px;\n border-top: 1px solid #e2e8f0;\n}\n\n.footer-right {\n display: flex;\n gap: 8px;\n margin-left: auto;\n}\n\n.btn {\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n transition: background 0.15s, opacity 0.15s;\n}\n\n.btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.btn-primary {\n background: #0076b6;\n color: #fff;\n}\n\n.btn-primary:hover:not(:disabled) {\n background: #005a8c;\n}\n\n.btn-secondary {\n background: #f1f5f9;\n color: #334155;\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: #e2e8f0;\n}\n\n.btn-danger {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.btn-danger:hover:not(:disabled) {\n background: #fecaca;\n}\n\n.confirm-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 1100;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.confirm-dialog {\n background: #fff;\n border-radius: 10px;\n padding: 24px;\n max-width: 360px;\n text-align: center;\n box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);\n}\n\n.confirm-dialog p {\n margin: 0 0 16px;\n color: #334155;\n font-size: 14px;\n}\n\n.confirm-actions {\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n\n@media (max-width: 480px) {\n .stats-grid {\n grid-template-columns: 1fr;\n }\n\n .editor-footer {\n flex-direction: column;\n gap: 8px;\n }\n\n .footer-right {\n margin-left: 0;\n width: 100%;\n }\n\n .footer-right .btn {\n flex: 1;\n justify-content: center;\n }\n}\n"] }]
|
|
233
|
+
args: [{ selector: 'mj-scheduled-job-editor', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (IsLoading) {\n <div class=\"editor-loading\">\n <mj-loading text=\"Loading...\"></mj-loading>\n </div>\n} @else {\n <div class=\"editor-container\">\n <!-- General Section -->\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-circle-info\"></i> General\n </div>\n\n <div class=\"form-group\">\n <label for=\"jobName\">Name <span class=\"required\">*</span></label>\n <input id=\"jobName\" type=\"text\" [(ngModel)]=\"Name\" placeholder=\"Job name\" />\n </div>\n\n <div class=\"form-group\">\n <label for=\"jobDesc\">Description</label>\n <textarea id=\"jobDesc\" [(ngModel)]=\"Description\" rows=\"2\" placeholder=\"Optional description\"></textarea>\n </div>\n\n @if (!HideJobType) {\n <div class=\"form-group\">\n <label for=\"jobType\">Job Type <span class=\"required\">*</span></label>\n <select id=\"jobType\" [(ngModel)]=\"SelectedJobTypeID\">\n <option value=\"\">-- Select Type --</option>\n @for (jt of JobTypes; track jt.ID) {\n <option [value]=\"jt.ID\">{{ jt.Name }}</option>\n }\n </select>\n </div>\n }\n\n <div class=\"form-group\">\n <label for=\"jobStatus\">Status</label>\n <select id=\"jobStatus\" [(ngModel)]=\"Status\">\n @for (s of StatusOptions; track s) {\n <option [value]=\"s\">{{ s }}</option>\n }\n </select>\n </div>\n </div>\n\n <!-- Schedule Section -->\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-clock\"></i> Schedule\n </div>\n\n <div class=\"form-group\">\n <label for=\"cronExpr\">Cron Expression <span class=\"required\">*</span></label>\n <input id=\"cronExpr\" type=\"text\" [(ngModel)]=\"CronExpression\"\n placeholder=\"e.g. 0 */15 * * * *\" />\n <div class=\"hint\">Standard cron format: second minute hour day month weekday</div>\n </div>\n\n <div class=\"form-group\">\n <label for=\"timezone\">Timezone</label>\n <select id=\"timezone\" [(ngModel)]=\"Timezone\">\n @for (tz of Timezones; track tz) {\n <option [value]=\"tz\">{{ tz }}</option>\n }\n </select>\n </div>\n\n <div class=\"form-group\">\n <label for=\"concurrency\">Concurrency</label>\n <select id=\"concurrency\" [(ngModel)]=\"ConcurrencyMode\">\n @for (c of ConcurrencyOptions; track c) {\n <option [value]=\"c\">{{ c }}</option>\n }\n </select>\n </div>\n </div>\n\n <!-- Configuration Section -->\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-code\"></i> Configuration\n </div>\n\n <div class=\"form-group\">\n <label for=\"config\">Configuration JSON</label>\n <textarea id=\"config\" [(ngModel)]=\"Configuration\" rows=\"6\"\n class=\"code-textarea\"\n placeholder='{ \"key\": \"value\" }'></textarea>\n </div>\n </div>\n\n <!-- Notifications Section -->\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-bell\"></i> Notifications\n </div>\n\n <div class=\"toggle-row\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" [(ngModel)]=\"NotifyOnSuccess\" />\n Notify on success\n </label>\n </div>\n <div class=\"toggle-row\">\n <label class=\"toggle-label\">\n <input type=\"checkbox\" [(ngModel)]=\"NotifyOnFailure\" />\n Notify on failure\n </label>\n </div>\n </div>\n\n <!-- Statistics (edit mode only) -->\n @if (!IsNew && TotalRuns > 0) {\n <div class=\"form-section\">\n <div class=\"section-title\">\n <i class=\"fa-solid fa-chart-bar\"></i> Statistics\n </div>\n <div class=\"stats-grid\">\n <div class=\"stat-item\">\n <span class=\"stat-value\">{{ TotalRuns }}</span>\n <span class=\"stat-label\">Total Runs</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-value success\">{{ SuccessRuns }}</span>\n <span class=\"stat-label\">Succeeded</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-value error\">{{ FailedRuns }}</span>\n <span class=\"stat-label\">Failed</span>\n </div>\n </div>\n </div>\n }\n\n <!-- Footer Actions -->\n <div class=\"editor-footer\">\n @if (!IsNew) {\n <button class=\"btn btn-danger\" (click)=\"ConfirmDelete()\" [disabled]=\"IsSaving\">\n <i class=\"fa-solid fa-trash\"></i> Delete\n </button>\n }\n <div class=\"footer-right\">\n <button class=\"btn btn-primary\" (click)=\"Save()\" [disabled]=\"!CanSave || IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n }\n {{ IsNew ? 'Create' : 'Save' }}\n </button>\n <button class=\"btn btn-secondary\" (click)=\"Cancel()\" [disabled]=\"IsSaving\">\n Cancel\n </button>\n </div>\n </div>\n\n <!-- Delete Confirmation -->\n @if (ShowDeleteConfirm) {\n <div class=\"confirm-overlay\" (click)=\"CancelDelete()\">\n <div class=\"confirm-dialog\" (click)=\"$event.stopPropagation()\">\n <p>Are you sure you want to delete this scheduled job?</p>\n <div class=\"confirm-actions\">\n <button class=\"btn btn-danger\" (click)=\"DeleteJob()\">Delete</button>\n <button class=\"btn btn-secondary\" (click)=\"CancelDelete()\">Cancel</button>\n </div>\n </div>\n </div>\n }\n </div>\n}\n", styles: [".editor-loading {\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 40px;\n}\n\n.editor-container {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 16px;\n}\n\n.form-section {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 16px;\n background: var(--mj-bg-surface);\n}\n\n.section-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 12px;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.section-title i {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.form-group {\n margin-bottom: 12px;\n}\n\n.form-group:last-child {\n margin-bottom: 0;\n}\n\n.form-group label {\n display: block;\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n margin-bottom: 4px;\n}\n\n.required {\n color: var(--mj-status-error);\n}\n\n.form-group input,\n.form-group textarea,\n.form-group select {\n width: 100%;\n padding: 8px 10px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n box-sizing: border-box;\n transition: border-color 0.15s;\n}\n\n.form-group input:focus,\n.form-group textarea:focus,\n.form-group select:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.code-textarea {\n font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n font-size: 12px;\n line-height: 1.5;\n}\n\n.hint {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 4px;\n}\n\n.toggle-row {\n margin-bottom: 8px;\n}\n\n.toggle-label {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n color: var(--mj-text-primary);\n cursor: pointer;\n}\n\n.toggle-label input[type=\"checkbox\"] {\n width: auto;\n}\n\n.stats-grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 12px;\n}\n\n.stat-item {\n text-align: center;\n}\n\n.stat-value {\n display: block;\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.stat-value.success {\n color: var(--mj-status-success);\n}\n\n.stat-value.error {\n color: var(--mj-status-error);\n}\n\n.stat-label {\n display: block;\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.editor-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-top: 8px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.footer-right {\n display: flex;\n gap: 8px;\n margin-left: auto;\n}\n\n.btn {\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n transition: background 0.15s, opacity 0.15s;\n}\n\n.btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.btn-primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-secondary {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: var(--mj-bg-surface-active);\n}\n\n.btn-danger {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n}\n\n.btn-danger:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n}\n\n.confirm-overlay {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 1100;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.confirm-dialog {\n background: var(--mj-bg-surface);\n border-radius: 10px;\n padding: 24px;\n max-width: 360px;\n text-align: center;\n box-shadow: var(--mj-shadow-lg);\n}\n\n.confirm-dialog p {\n margin: 0 0 16px;\n color: var(--mj-text-primary);\n font-size: 14px;\n}\n\n.confirm-actions {\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n\n@media (max-width: 480px) {\n .stats-grid {\n grid-template-columns: 1fr;\n }\n\n .editor-footer {\n flex-direction: column;\n gap: 8px;\n }\n\n .footer-right {\n margin-left: 0;\n width: 100%;\n }\n\n .footer-right .btn {\n flex: 1;\n justify-content: center;\n }\n}\n"] }]
|
|
234
234
|
}], propDecorators: { ScheduledJobID: [{
|
|
235
235
|
type: Input
|
|
236
236
|
}], JobTypeID: [{
|
|
@@ -68,11 +68,11 @@ export class ScheduledJobSummaryComponent {
|
|
|
68
68
|
this.cdr.markForCheck();
|
|
69
69
|
}
|
|
70
70
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ScheduledJobSummaryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
71
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ScheduledJobSummaryComponent, isStandalone: false, selector: "mj-scheduled-job-summary", inputs: { ScheduledJobID: "ScheduledJobID", ShowEditButton: "ShowEditButton" }, outputs: { EditRequested: "EditRequested" }, ngImport: i0, template: "@if (IsLoading) {\n <div class=\"summary-loading\">\n <mj-loading size=\"small\"></mj-loading>\n </div>\n} @else if (Job) {\n <div class=\"summary-card\">\n <div class=\"summary-header\">\n <div class=\"summary-name\">\n <i class=\"fa-solid fa-calendar-check\"></i>\n {{ Job.Name }}\n </div>\n <span class=\"status-chip\" [class]=\"StatusClass\">{{ Job.Status }}</span>\n </div>\n\n <div class=\"summary-meta\">\n <div class=\"meta-item\">\n <i class=\"fa-regular fa-clock\"></i>\n <span>{{ Job.CronExpression }}</span>\n </div>\n @if (Job.Timezone && Job.Timezone !== 'UTC') {\n <div class=\"meta-item\">\n <i class=\"fa-solid fa-globe\"></i>\n <span>{{ Job.Timezone }}</span>\n </div>\n }\n </div>\n\n <div class=\"summary-stats\">\n <div class=\"stat\">\n <span class=\"stat-num\">{{ TotalRuns }}</span>\n <span class=\"stat-lbl\">Runs</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-num success\">{{ SuccessRuns }}</span>\n <span class=\"stat-lbl\">OK</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-num error\">{{ FailedRuns }}</span>\n <span class=\"stat-lbl\">Failed</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-num\">{{ SuccessRate }}</span>\n <span class=\"stat-lbl\">Rate</span>\n </div>\n </div>\n\n @if (ShowEditButton) {\n <div class=\"summary-actions\">\n <button class=\"edit-btn\" (click)=\"OnEditClick()\">\n <i class=\"fa-solid fa-pen-to-square\"></i> Edit Schedule\n </button>\n </div>\n }\n </div>\n} @else {\n <div class=\"summary-empty\">\n <i class=\"fa-regular fa-calendar-xmark\"></i>\n <span>No schedule configured</span>\n </div>\n}\n", styles: [".summary-loading {\n display: flex;\n justify-content: center;\n padding: 16px;\n}\n\n.summary-card {\n border: 1px solid
|
|
71
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ScheduledJobSummaryComponent, isStandalone: false, selector: "mj-scheduled-job-summary", inputs: { ScheduledJobID: "ScheduledJobID", ShowEditButton: "ShowEditButton" }, outputs: { EditRequested: "EditRequested" }, ngImport: i0, template: "@if (IsLoading) {\n <div class=\"summary-loading\">\n <mj-loading size=\"small\"></mj-loading>\n </div>\n} @else if (Job) {\n <div class=\"summary-card\">\n <div class=\"summary-header\">\n <div class=\"summary-name\">\n <i class=\"fa-solid fa-calendar-check\"></i>\n {{ Job.Name }}\n </div>\n <span class=\"status-chip\" [class]=\"StatusClass\">{{ Job.Status }}</span>\n </div>\n\n <div class=\"summary-meta\">\n <div class=\"meta-item\">\n <i class=\"fa-regular fa-clock\"></i>\n <span>{{ Job.CronExpression }}</span>\n </div>\n @if (Job.Timezone && Job.Timezone !== 'UTC') {\n <div class=\"meta-item\">\n <i class=\"fa-solid fa-globe\"></i>\n <span>{{ Job.Timezone }}</span>\n </div>\n }\n </div>\n\n <div class=\"summary-stats\">\n <div class=\"stat\">\n <span class=\"stat-num\">{{ TotalRuns }}</span>\n <span class=\"stat-lbl\">Runs</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-num success\">{{ SuccessRuns }}</span>\n <span class=\"stat-lbl\">OK</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-num error\">{{ FailedRuns }}</span>\n <span class=\"stat-lbl\">Failed</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-num\">{{ SuccessRate }}</span>\n <span class=\"stat-lbl\">Rate</span>\n </div>\n </div>\n\n @if (ShowEditButton) {\n <div class=\"summary-actions\">\n <button class=\"edit-btn\" (click)=\"OnEditClick()\">\n <i class=\"fa-solid fa-pen-to-square\"></i> Edit Schedule\n </button>\n </div>\n }\n </div>\n} @else {\n <div class=\"summary-empty\">\n <i class=\"fa-regular fa-calendar-xmark\"></i>\n <span>No schedule configured</span>\n </div>\n}\n", styles: [".summary-loading {\n display: flex;\n justify-content: center;\n padding: 16px;\n}\n\n.summary-card {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 14px;\n background: var(--mj-bg-surface);\n}\n\n.summary-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 10px;\n}\n\n.summary-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.summary-name i {\n color: var(--mj-brand-primary);\n}\n\n.status-chip {\n font-size: 11px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.status-active {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n}\n\n.status-paused {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n}\n\n.status-disabled {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n}\n\n.status-pending {\n background: var(--mj-status-info-bg);\n color: var(--mj-status-info-text);\n}\n\n.summary-meta {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n margin-bottom: 10px;\n}\n\n.meta-item {\n display: flex;\n align-items: center;\n gap: 5px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.meta-item i {\n font-size: 11px;\n}\n\n.summary-stats {\n display: flex;\n gap: 16px;\n padding: 8px 0;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.stat {\n text-align: center;\n flex: 1;\n}\n\n.stat-num {\n display: block;\n font-size: 16px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.stat-num.success {\n color: var(--mj-status-success);\n}\n\n.stat-num.error {\n color: var(--mj-status-error);\n}\n\n.stat-lbl {\n display: block;\n font-size: 10px;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.summary-actions {\n margin-top: 10px;\n padding-top: 10px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.edit-btn {\n background: none;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n padding: 6px 12px;\n font-size: 12px;\n color: var(--mj-brand-primary);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n gap: 5px;\n transition: background 0.15s;\n}\n\n.edit-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.summary-empty {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px;\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.summary-empty i {\n font-size: 16px;\n}\n"], dependencies: [{ kind: "component", type: i1.LoadingComponent, selector: "mj-loading", inputs: ["text", "showText", "animationDuration", "size", "textColor", "logoColor", "logoGradient", "animation"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
72
72
|
}
|
|
73
73
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ScheduledJobSummaryComponent, decorators: [{
|
|
74
74
|
type: Component,
|
|
75
|
-
args: [{ selector: 'mj-scheduled-job-summary', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (IsLoading) {\n <div class=\"summary-loading\">\n <mj-loading size=\"small\"></mj-loading>\n </div>\n} @else if (Job) {\n <div class=\"summary-card\">\n <div class=\"summary-header\">\n <div class=\"summary-name\">\n <i class=\"fa-solid fa-calendar-check\"></i>\n {{ Job.Name }}\n </div>\n <span class=\"status-chip\" [class]=\"StatusClass\">{{ Job.Status }}</span>\n </div>\n\n <div class=\"summary-meta\">\n <div class=\"meta-item\">\n <i class=\"fa-regular fa-clock\"></i>\n <span>{{ Job.CronExpression }}</span>\n </div>\n @if (Job.Timezone && Job.Timezone !== 'UTC') {\n <div class=\"meta-item\">\n <i class=\"fa-solid fa-globe\"></i>\n <span>{{ Job.Timezone }}</span>\n </div>\n }\n </div>\n\n <div class=\"summary-stats\">\n <div class=\"stat\">\n <span class=\"stat-num\">{{ TotalRuns }}</span>\n <span class=\"stat-lbl\">Runs</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-num success\">{{ SuccessRuns }}</span>\n <span class=\"stat-lbl\">OK</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-num error\">{{ FailedRuns }}</span>\n <span class=\"stat-lbl\">Failed</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-num\">{{ SuccessRate }}</span>\n <span class=\"stat-lbl\">Rate</span>\n </div>\n </div>\n\n @if (ShowEditButton) {\n <div class=\"summary-actions\">\n <button class=\"edit-btn\" (click)=\"OnEditClick()\">\n <i class=\"fa-solid fa-pen-to-square\"></i> Edit Schedule\n </button>\n </div>\n }\n </div>\n} @else {\n <div class=\"summary-empty\">\n <i class=\"fa-regular fa-calendar-xmark\"></i>\n <span>No schedule configured</span>\n </div>\n}\n", styles: [".summary-loading {\n display: flex;\n justify-content: center;\n padding: 16px;\n}\n\n.summary-card {\n border: 1px solid
|
|
75
|
+
args: [{ selector: 'mj-scheduled-job-summary', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (IsLoading) {\n <div class=\"summary-loading\">\n <mj-loading size=\"small\"></mj-loading>\n </div>\n} @else if (Job) {\n <div class=\"summary-card\">\n <div class=\"summary-header\">\n <div class=\"summary-name\">\n <i class=\"fa-solid fa-calendar-check\"></i>\n {{ Job.Name }}\n </div>\n <span class=\"status-chip\" [class]=\"StatusClass\">{{ Job.Status }}</span>\n </div>\n\n <div class=\"summary-meta\">\n <div class=\"meta-item\">\n <i class=\"fa-regular fa-clock\"></i>\n <span>{{ Job.CronExpression }}</span>\n </div>\n @if (Job.Timezone && Job.Timezone !== 'UTC') {\n <div class=\"meta-item\">\n <i class=\"fa-solid fa-globe\"></i>\n <span>{{ Job.Timezone }}</span>\n </div>\n }\n </div>\n\n <div class=\"summary-stats\">\n <div class=\"stat\">\n <span class=\"stat-num\">{{ TotalRuns }}</span>\n <span class=\"stat-lbl\">Runs</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-num success\">{{ SuccessRuns }}</span>\n <span class=\"stat-lbl\">OK</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-num error\">{{ FailedRuns }}</span>\n <span class=\"stat-lbl\">Failed</span>\n </div>\n <div class=\"stat\">\n <span class=\"stat-num\">{{ SuccessRate }}</span>\n <span class=\"stat-lbl\">Rate</span>\n </div>\n </div>\n\n @if (ShowEditButton) {\n <div class=\"summary-actions\">\n <button class=\"edit-btn\" (click)=\"OnEditClick()\">\n <i class=\"fa-solid fa-pen-to-square\"></i> Edit Schedule\n </button>\n </div>\n }\n </div>\n} @else {\n <div class=\"summary-empty\">\n <i class=\"fa-regular fa-calendar-xmark\"></i>\n <span>No schedule configured</span>\n </div>\n}\n", styles: [".summary-loading {\n display: flex;\n justify-content: center;\n padding: 16px;\n}\n\n.summary-card {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 14px;\n background: var(--mj-bg-surface);\n}\n\n.summary-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 10px;\n}\n\n.summary-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.summary-name i {\n color: var(--mj-brand-primary);\n}\n\n.status-chip {\n font-size: 11px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.status-active {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n}\n\n.status-paused {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n}\n\n.status-disabled {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n}\n\n.status-pending {\n background: var(--mj-status-info-bg);\n color: var(--mj-status-info-text);\n}\n\n.summary-meta {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n margin-bottom: 10px;\n}\n\n.meta-item {\n display: flex;\n align-items: center;\n gap: 5px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.meta-item i {\n font-size: 11px;\n}\n\n.summary-stats {\n display: flex;\n gap: 16px;\n padding: 8px 0;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.stat {\n text-align: center;\n flex: 1;\n}\n\n.stat-num {\n display: block;\n font-size: 16px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.stat-num.success {\n color: var(--mj-status-success);\n}\n\n.stat-num.error {\n color: var(--mj-status-error);\n}\n\n.stat-lbl {\n display: block;\n font-size: 10px;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.summary-actions {\n margin-top: 10px;\n padding-top: 10px;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.edit-btn {\n background: none;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n padding: 6px 12px;\n font-size: 12px;\n color: var(--mj-brand-primary);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n gap: 5px;\n transition: background 0.15s;\n}\n\n.edit-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.summary-empty {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px;\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.summary-empty i {\n font-size: 16px;\n}\n"] }]
|
|
76
76
|
}], propDecorators: { ScheduledJobID: [{
|
|
77
77
|
type: Input
|
|
78
78
|
}], ShowEditButton: [{
|
|
@@ -28,11 +28,11 @@ export class ScheduledJobSlidePanelComponent {
|
|
|
28
28
|
return this.ScheduledJobID ? 'Edit Schedule' : 'Create Schedule';
|
|
29
29
|
}
|
|
30
30
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ScheduledJobSlidePanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
31
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ScheduledJobSlidePanelComponent, isStandalone: false, selector: "mj-scheduled-job-slide-panel", inputs: { IsOpen: "IsOpen", ScheduledJobID: "ScheduledJobID", JobTypeID: "JobTypeID", DefaultConfiguration: "DefaultConfiguration", HideJobType: "HideJobType" }, outputs: { Close: "Close", Saved: "Saved", Deleted: "Deleted" }, host: { listeners: { "document:keydown.escape": "OnEscKey()" } }, ngImport: i0, template: "@if (IsOpen) {\n <div class=\"slide-panel-backdrop\" (click)=\"ClosePanel()\"></div>\n <div class=\"slide-panel\" [class.open]=\"IsOpen\">\n <div class=\"slide-panel-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-calendar-check\"></i>\n <span>{{ PanelTitle }}</span>\n </div>\n <button class=\"close-btn\" (click)=\"ClosePanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"slide-panel-body\">\n <mj-scheduled-job-editor\n [ScheduledJobID]=\"ScheduledJobID\"\n [JobTypeID]=\"JobTypeID\"\n [DefaultConfiguration]=\"DefaultConfiguration\"\n [HideJobType]=\"HideJobType\"\n (Saved)=\"OnSaved($event)\"\n (Deleted)=\"OnDeleted($event)\"\n (Cancelled)=\"ClosePanel()\">\n </mj-scheduled-job-editor>\n </div>\n </div>\n}\n", styles: [".slide-panel-backdrop {\n position: fixed;\n inset: 0;\n background:
|
|
31
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ScheduledJobSlidePanelComponent, isStandalone: false, selector: "mj-scheduled-job-slide-panel", inputs: { IsOpen: "IsOpen", ScheduledJobID: "ScheduledJobID", JobTypeID: "JobTypeID", DefaultConfiguration: "DefaultConfiguration", HideJobType: "HideJobType" }, outputs: { Close: "Close", Saved: "Saved", Deleted: "Deleted" }, host: { listeners: { "document:keydown.escape": "OnEscKey()" } }, ngImport: i0, template: "@if (IsOpen) {\n <div class=\"slide-panel-backdrop\" (click)=\"ClosePanel()\"></div>\n <div class=\"slide-panel\" [class.open]=\"IsOpen\">\n <div class=\"slide-panel-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-calendar-check\"></i>\n <span>{{ PanelTitle }}</span>\n </div>\n <button class=\"close-btn\" (click)=\"ClosePanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"slide-panel-body\">\n <mj-scheduled-job-editor\n [ScheduledJobID]=\"ScheduledJobID\"\n [JobTypeID]=\"JobTypeID\"\n [DefaultConfiguration]=\"DefaultConfiguration\"\n [HideJobType]=\"HideJobType\"\n (Saved)=\"OnSaved($event)\"\n (Deleted)=\"OnDeleted($event)\"\n (Cancelled)=\"ClosePanel()\">\n </mj-scheduled-job-editor>\n </div>\n </div>\n}\n", styles: [".slide-panel-backdrop {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 1000;\n animation: fadeIn 0.2s ease;\n}\n\n.slide-panel {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 520px;\n max-width: 90vw;\n background: var(--mj-bg-surface-card);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n box-shadow: -4px 0 20px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n transform: translateX(100%);\n transition: transform 0.25s ease;\n}\n\n.slide-panel.open {\n transform: translateX(0);\n}\n\n.slide-panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n background: linear-gradient(135deg, var(--mj-brand-secondary) 0%, var(--mj-brand-primary) 100%);\n color: var(--mj-text-inverse);\n flex-shrink: 0;\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n}\n\n.close-btn {\n background: none;\n border: none;\n color: rgba(255, 255, 255, 0.8);\n font-size: 18px;\n cursor: pointer;\n padding: 4px 8px;\n border-radius: 4px;\n transition: color 0.15s, background 0.15s;\n}\n\n.close-btn:hover {\n color: var(--mj-text-inverse);\n background: rgba(255, 255, 255, 0.15);\n}\n\n.slide-panel-body {\n flex: 1;\n overflow-y: auto;\n padding: 0;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@media (max-width: 600px) {\n .slide-panel {\n width: 100vw;\n }\n}\n"], dependencies: [{ kind: "component", type: i1.ScheduledJobEditorComponent, selector: "mj-scheduled-job-editor", inputs: ["ScheduledJobID", "JobTypeID", "DefaultConfiguration", "HideJobType"], outputs: ["Saved", "Deleted", "Cancelled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
32
32
|
}
|
|
33
33
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ScheduledJobSlidePanelComponent, decorators: [{
|
|
34
34
|
type: Component,
|
|
35
|
-
args: [{ selector: 'mj-scheduled-job-slide-panel', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (IsOpen) {\n <div class=\"slide-panel-backdrop\" (click)=\"ClosePanel()\"></div>\n <div class=\"slide-panel\" [class.open]=\"IsOpen\">\n <div class=\"slide-panel-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-calendar-check\"></i>\n <span>{{ PanelTitle }}</span>\n </div>\n <button class=\"close-btn\" (click)=\"ClosePanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"slide-panel-body\">\n <mj-scheduled-job-editor\n [ScheduledJobID]=\"ScheduledJobID\"\n [JobTypeID]=\"JobTypeID\"\n [DefaultConfiguration]=\"DefaultConfiguration\"\n [HideJobType]=\"HideJobType\"\n (Saved)=\"OnSaved($event)\"\n (Deleted)=\"OnDeleted($event)\"\n (Cancelled)=\"ClosePanel()\">\n </mj-scheduled-job-editor>\n </div>\n </div>\n}\n", styles: [".slide-panel-backdrop {\n position: fixed;\n inset: 0;\n background:
|
|
35
|
+
args: [{ selector: 'mj-scheduled-job-slide-panel', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (IsOpen) {\n <div class=\"slide-panel-backdrop\" (click)=\"ClosePanel()\"></div>\n <div class=\"slide-panel\" [class.open]=\"IsOpen\">\n <div class=\"slide-panel-header\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-calendar-check\"></i>\n <span>{{ PanelTitle }}</span>\n </div>\n <button class=\"close-btn\" (click)=\"ClosePanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"slide-panel-body\">\n <mj-scheduled-job-editor\n [ScheduledJobID]=\"ScheduledJobID\"\n [JobTypeID]=\"JobTypeID\"\n [DefaultConfiguration]=\"DefaultConfiguration\"\n [HideJobType]=\"HideJobType\"\n (Saved)=\"OnSaved($event)\"\n (Deleted)=\"OnDeleted($event)\"\n (Cancelled)=\"ClosePanel()\">\n </mj-scheduled-job-editor>\n </div>\n </div>\n}\n", styles: [".slide-panel-backdrop {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 1000;\n animation: fadeIn 0.2s ease;\n}\n\n.slide-panel {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 520px;\n max-width: 90vw;\n background: var(--mj-bg-surface-card);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n box-shadow: -4px 0 20px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n transform: translateX(100%);\n transition: transform 0.25s ease;\n}\n\n.slide-panel.open {\n transform: translateX(0);\n}\n\n.slide-panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n background: linear-gradient(135deg, var(--mj-brand-secondary) 0%, var(--mj-brand-primary) 100%);\n color: var(--mj-text-inverse);\n flex-shrink: 0;\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n}\n\n.close-btn {\n background: none;\n border: none;\n color: rgba(255, 255, 255, 0.8);\n font-size: 18px;\n cursor: pointer;\n padding: 4px 8px;\n border-radius: 4px;\n transition: color 0.15s, background 0.15s;\n}\n\n.close-btn:hover {\n color: var(--mj-text-inverse);\n background: rgba(255, 255, 255, 0.15);\n}\n\n.slide-panel-body {\n flex: 1;\n overflow-y: auto;\n padding: 0;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n@media (max-width: 600px) {\n .slide-panel {\n width: 100vw;\n }\n}\n"] }]
|
|
36
36
|
}], propDecorators: { IsOpen: [{
|
|
37
37
|
type: Input
|
|
38
38
|
}], ScheduledJobID: [{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-scheduling",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.34.0",
|
|
4
4
|
"description": "MemberJunction: Reusable Angular components for viewing and editing Scheduled Jobs - panels, slide-in, dialog, and service",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
"@angular/forms": "21.1.3"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@memberjunction/core": "5.
|
|
35
|
-
"@memberjunction/ng-base-types": "5.
|
|
36
|
-
"@memberjunction/core-entities": "5.
|
|
37
|
-
"@memberjunction/global": "5.
|
|
38
|
-
"@memberjunction/ng-notifications": "5.
|
|
39
|
-
"@memberjunction/ng-shared-generic": "5.
|
|
40
|
-
"@memberjunction/ng-ui-components": "5.
|
|
34
|
+
"@memberjunction/core": "5.34.0",
|
|
35
|
+
"@memberjunction/ng-base-types": "5.34.0",
|
|
36
|
+
"@memberjunction/core-entities": "5.34.0",
|
|
37
|
+
"@memberjunction/global": "5.34.0",
|
|
38
|
+
"@memberjunction/ng-notifications": "5.34.0",
|
|
39
|
+
"@memberjunction/ng-shared-generic": "5.34.0",
|
|
40
|
+
"@memberjunction/ng-ui-components": "5.34.0",
|
|
41
41
|
"tslib": "^2.8.1",
|
|
42
42
|
"rxjs": "^7.8.2"
|
|
43
43
|
},
|