UNPKG

@memberjunction/ng-action-gallery

Version:

MemberJunction Action Gallery - A beautiful, filterable gallery component for browsing and selecting actions

803 lines 81.2 kB
import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core'; import { FormControl } from '@angular/forms'; import { Subject, BehaviorSubject, combineLatest, debounceTime, distinctUntilChanged, takeUntil } from 'rxjs'; import { RunView } from '@memberjunction/core'; import * as i0 from "@angular/core"; import * as i1 from "@angular/forms"; import * as i2 from "@progress/kendo-angular-buttons"; import * as i3 from "@progress/kendo-angular-inputs"; import * as i4 from "@progress/kendo-angular-indicators"; import * as i5 from "@progress/kendo-angular-tooltip"; import * as i6 from "@angular/common"; const _c0 = ["searchInput"]; const _forTrack0 = ($index, $item) => $item.id; const _forTrack1 = ($index, $item) => $item.ID; function ActionGalleryComponent_Conditional_1_ng_template_5_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelement(0, "i", 21); } } function ActionGalleryComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) { const _r1 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "div", 2)(1, "div", 10)(2, "div", 11)(3, "kendo-textbox", 12, 0); i0.ɵɵtemplate(5, ActionGalleryComponent_Conditional_1_ng_template_5_Template, 1, 0, "ng-template", 13); i0.ɵɵelementEnd()(); i0.ɵɵelementStart(6, "div", 14)(7, "div", 15)(8, "button", 16); i0.ɵɵpipe(9, "async"); i0.ɵɵpipe(10, "async"); i0.ɵɵlistener("click", function ActionGalleryComponent_Conditional_1_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleViewMode()); }); i0.ɵɵelement(11, "i", 17); i0.ɵɵpipe(12, "async"); i0.ɵɵpipe(13, "async"); i0.ɵɵelementEnd()(); i0.ɵɵelementStart(14, "div", 18)(15, "span", 19); i0.ɵɵelement(16, "i", 20); i0.ɵɵtext(17); i0.ɵɵpipe(18, "async"); i0.ɵɵelementEnd()()()()(); } if (rf & 2) { let tmp_9_0; const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵadvance(3); i0.ɵɵproperty("formControl", ctx_r1.searchControl)("clearButton", true); i0.ɵɵadvance(5); i0.ɵɵproperty("toggleable", true)("selected", i0.ɵɵpipeBind1(9, 11, ctx_r1.viewMode$) === "grid")("title", i0.ɵɵpipeBind1(10, 13, ctx_r1.viewMode$) === "grid" ? "Switch to list view" : "Switch to grid view"); i0.ɵɵadvance(3); i0.ɵɵclassProp("fa-th", i0.ɵɵpipeBind1(12, 15, ctx_r1.viewMode$) === "grid")("fa-list", i0.ɵɵpipeBind1(13, 17, ctx_r1.viewMode$) === "list"); i0.ɵɵadvance(6); i0.ɵɵtextInterpolate2(" ", (tmp_9_0 = i0.ɵɵpipeBind1(18, 19, ctx_r1.filteredActions$)) == null ? null : tmp_9_0.length, " of ", ctx_r1.totalActions, " actions "); } } function ActionGalleryComponent_Conditional_3_For_3_Conditional_8_Template(rf, ctx) { if (rf & 1) { const _r5 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "i", 30); i0.ɵɵlistener("click", function ActionGalleryComponent_Conditional_3_For_3_Conditional_8_Template_i_click_0_listener($event) { i0.ɵɵrestoreView(_r5); const category_r4 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); ctx_r1.toggleCategoryExpanded(category_r4.id); return i0.ɵɵresetView($event.stopPropagation()); }); i0.ɵɵelementEnd(); } if (rf & 2) { const category_r4 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵclassProp("expanded", ctx_r1.expandedCategories.has(category_r4.id)); } } function ActionGalleryComponent_Conditional_3_For_3_Conditional_9_For_2_Template(rf, ctx) { if (rf & 1) { const _r6 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "div", 32); i0.ɵɵpipe(1, "async"); i0.ɵɵlistener("click", function ActionGalleryComponent_Conditional_3_For_3_Conditional_9_For_2_Template_div_click_0_listener($event) { const subCategory_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); ctx_r1.selectCategory(subCategory_r7.id); return i0.ɵɵresetView($event.stopPropagation()); }); i0.ɵɵelementStart(2, "div", 25); i0.ɵɵelement(3, "i"); i0.ɵɵelementStart(4, "span", 26); i0.ɵɵtext(5); i0.ɵɵelementEnd(); i0.ɵɵelementStart(6, "span", 27); i0.ɵɵtext(7); i0.ɵɵelementEnd()()(); } if (rf & 2) { const subCategory_r7 = ctx.$implicit; const ctx_r1 = i0.ɵɵnextContext(4); i0.ɵɵclassProp("selected", i0.ɵɵpipeBind1(1, 7, ctx_r1.selectedCategory$) === subCategory_r7.id); i0.ɵɵadvance(3); i0.ɵɵclassMapInterpolate1("fa-solid ", subCategory_r7.icon, " category-icon"); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(subCategory_r7.name); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(subCategory_r7.count); } } function ActionGalleryComponent_Conditional_3_For_3_Conditional_9_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 29); i0.ɵɵrepeaterCreate(1, ActionGalleryComponent_Conditional_3_For_3_Conditional_9_For_2_Template, 8, 9, "div", 31, _forTrack0); i0.ɵɵelementEnd(); } if (rf & 2) { const category_r4 = i0.ɵɵnextContext().$implicit; i0.ɵɵadvance(); i0.ɵɵrepeater(category_r4.children); } } function ActionGalleryComponent_Conditional_3_For_3_Template(rf, ctx) { if (rf & 1) { const _r3 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "div", 24); i0.ɵɵpipe(1, "async"); i0.ɵɵlistener("click", function ActionGalleryComponent_Conditional_3_For_3_Template_div_click_0_listener() { const category_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.selectCategory(category_r4.id)); }); i0.ɵɵelementStart(2, "div", 25); i0.ɵɵelement(3, "i"); i0.ɵɵelementStart(4, "span", 26); i0.ɵɵtext(5); i0.ɵɵelementEnd(); i0.ɵɵelementStart(6, "span", 27); i0.ɵɵtext(7); i0.ɵɵelementEnd(); i0.ɵɵtemplate(8, ActionGalleryComponent_Conditional_3_For_3_Conditional_8_Template, 1, 2, "i", 28); i0.ɵɵelementEnd(); i0.ɵɵtemplate(9, ActionGalleryComponent_Conditional_3_For_3_Conditional_9_Template, 3, 0, "div", 29); i0.ɵɵelementEnd(); } if (rf & 2) { const category_r4 = ctx.$implicit; const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵclassProp("selected", i0.ɵɵpipeBind1(1, 11, ctx_r1.selectedCategory$) === category_r4.id)("has-children", category_r4.children && category_r4.children.length > 0); i0.ɵɵadvance(3); i0.ɵɵclassMapInterpolate1("fa-solid ", category_r4.icon, " category-icon"); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(category_r4.name); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(category_r4.count); i0.ɵɵadvance(); i0.ɵɵconditional(category_r4.children && category_r4.children.length > 0 ? 8 : -1); i0.ɵɵadvance(); i0.ɵɵconditional(category_r4.children && ctx_r1.expandedCategories.has(category_r4.id) ? 9 : -1); } } function ActionGalleryComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 4)(1, "div", 22); i0.ɵɵrepeaterCreate(2, ActionGalleryComponent_Conditional_3_For_3_Template, 10, 13, "div", 23, _forTrack0); i0.ɵɵpipe(4, "async"); i0.ɵɵelementEnd()(); } if (rf & 2) { const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵadvance(2); i0.ɵɵrepeater(i0.ɵɵpipeBind1(4, 0, ctx_r1.categoryTree$)); } } function ActionGalleryComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 6); i0.ɵɵelement(1, "kendo-loader", 33); i0.ɵɵelementStart(2, "p"); i0.ɵɵtext(3, "Loading actions..."); i0.ɵɵelementEnd()(); } } function ActionGalleryComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) { const _r8 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "div", 7); i0.ɵɵelement(1, "i", 34); i0.ɵɵelementStart(2, "h3"); i0.ɵɵtext(3, "No actions found"); i0.ɵɵelementEnd(); i0.ɵɵelementStart(4, "p"); i0.ɵɵtext(5, "Try adjusting your search criteria or selecting a different category"); i0.ɵɵelementEnd(); i0.ɵɵelementStart(6, "button", 35); i0.ɵɵlistener("click", function ActionGalleryComponent_Conditional_7_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.clearSearch()); }); i0.ɵɵtext(7, "Clear Search"); i0.ɵɵelementEnd()(); } } function ActionGalleryComponent_Conditional_10_For_2_Conditional_8_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "span", 44); i0.ɵɵelement(1, "i", 54); i0.ɵɵtext(2); i0.ɵɵelementEnd(); } if (rf & 2) { const action_r10 = i0.ɵɵnextContext().$implicit; i0.ɵɵadvance(2); i0.ɵɵtextInterpolate1(" ", action_r10.Category, " "); } } function ActionGalleryComponent_Conditional_10_For_2_Conditional_10_Template(rf, ctx) { if (rf & 1) { const _r11 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "button", 55); i0.ɵɵlistener("click", function ActionGalleryComponent_Conditional_10_For_2_Conditional_10_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r11); const action_r10 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.testAction(action_r10, $event)); }); i0.ɵɵelementEnd(); } } function ActionGalleryComponent_Conditional_10_For_2_Conditional_16_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "span", 51); i0.ɵɵelement(1, "i", 56); i0.ɵɵtext(2); i0.ɵɵelementEnd(); } if (rf & 2) { const action_r10 = i0.ɵɵnextContext().$implicit; i0.ɵɵadvance(2); i0.ɵɵtextInterpolate1(" ", (action_r10.parameters == null ? null : action_r10.parameters.length) || 0, " params "); } } function ActionGalleryComponent_Conditional_10_For_2_Conditional_17_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "span", 51); i0.ɵɵelement(1, "i", 57); i0.ɵɵtext(2); i0.ɵɵelementEnd(); } if (rf & 2) { const action_r10 = i0.ɵɵnextContext().$implicit; i0.ɵɵadvance(2); i0.ɵɵtextInterpolate1(" ", (action_r10.resultCodes == null ? null : action_r10.resultCodes.length) || 0, " results "); } } function ActionGalleryComponent_Conditional_10_For_2_Conditional_18_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "span", 51); i0.ɵɵelement(1, "i", 58); i0.ɵɵtext(2); i0.ɵɵelementEnd(); } if (rf & 2) { const action_r10 = i0.ɵɵnextContext().$implicit; i0.ɵɵadvance(2); i0.ɵɵtextInterpolate1(" ", action_r10.Type, " "); } } function ActionGalleryComponent_Conditional_10_For_2_Conditional_19_Conditional_1_For_6_Conditional_5_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "span", 64); i0.ɵɵtext(1, "Required"); i0.ɵɵelementEnd(); } } function ActionGalleryComponent_Conditional_10_For_2_Conditional_19_Conditional_1_For_6_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 61)(1, "span", 62); i0.ɵɵtext(2); i0.ɵɵelementEnd(); i0.ɵɵelementStart(3, "span", 63); i0.ɵɵtext(4); i0.ɵɵelementEnd(); i0.ɵɵtemplate(5, ActionGalleryComponent_Conditional_10_For_2_Conditional_19_Conditional_1_For_6_Conditional_5_Template, 2, 0, "span", 64); i0.ɵɵelementEnd(); } if (rf & 2) { const param_r12 = ctx.$implicit; i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(param_r12.Name); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(param_r12.Type); i0.ɵɵadvance(); i0.ɵɵconditional(param_r12.IsRequired ? 5 : -1); } } function ActionGalleryComponent_Conditional_10_For_2_Conditional_19_Conditional_1_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 59)(1, "h4"); i0.ɵɵelement(2, "i", 56); i0.ɵɵtext(3, " Parameters "); i0.ɵɵelementEnd(); i0.ɵɵelementStart(4, "div", 60); i0.ɵɵrepeaterCreate(5, ActionGalleryComponent_Conditional_10_For_2_Conditional_19_Conditional_1_For_6_Template, 6, 3, "div", 61, _forTrack1); i0.ɵɵelementEnd()(); } if (rf & 2) { const action_r10 = i0.ɵɵnextContext(2).$implicit; i0.ɵɵadvance(5); i0.ɵɵrepeater(action_r10.parameters); } } function ActionGalleryComponent_Conditional_10_For_2_Conditional_19_Conditional_2_For_6_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 66)(1, "span", 67); i0.ɵɵtext(2); i0.ɵɵelementEnd(); i0.ɵɵelementStart(3, "span", 68); i0.ɵɵtext(4); i0.ɵɵelementEnd()(); } if (rf & 2) { const code_r13 = ctx.$implicit; i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(code_r13.ResultCode); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(code_r13.Description); } } function ActionGalleryComponent_Conditional_10_For_2_Conditional_19_Conditional_2_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 59)(1, "h4"); i0.ɵɵelement(2, "i", 57); i0.ɵɵtext(3, " Result Codes "); i0.ɵɵelementEnd(); i0.ɵɵelementStart(4, "div", 65); i0.ɵɵrepeaterCreate(5, ActionGalleryComponent_Conditional_10_For_2_Conditional_19_Conditional_2_For_6_Template, 5, 2, "div", 66, _forTrack1); i0.ɵɵelementEnd()(); } if (rf & 2) { const action_r10 = i0.ɵɵnextContext(2).$implicit; i0.ɵɵadvance(5); i0.ɵɵrepeater(action_r10.resultCodes); } } function ActionGalleryComponent_Conditional_10_For_2_Conditional_19_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 52); i0.ɵɵtemplate(1, ActionGalleryComponent_Conditional_10_For_2_Conditional_19_Conditional_1_Template, 7, 0, "div", 59)(2, ActionGalleryComponent_Conditional_10_For_2_Conditional_19_Conditional_2_Template, 7, 0, "div", 59); i0.ɵɵelementEnd(); } if (rf & 2) { const action_r10 = i0.ɵɵnextContext().$implicit; i0.ɵɵadvance(); i0.ɵɵconditional(action_r10.parameters && action_r10.parameters.length > 0 ? 1 : -1); i0.ɵɵadvance(); i0.ɵɵconditional(action_r10.resultCodes && action_r10.resultCodes.length > 0 ? 2 : -1); } } function ActionGalleryComponent_Conditional_10_For_2_Conditional_20_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 53); i0.ɵɵelement(1, "i", 17); i0.ɵɵelementEnd(); } if (rf & 2) { const action_r10 = i0.ɵɵnextContext().$implicit; i0.ɵɵadvance(); i0.ɵɵclassProp("fa-check-circle", action_r10.selected)("fa-circle", !action_r10.selected); } } function ActionGalleryComponent_Conditional_10_For_2_Template(rf, ctx) { if (rf & 1) { const _r9 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "div", 38); i0.ɵɵlistener("mouseenter", function ActionGalleryComponent_Conditional_10_For_2_Template_div_mouseenter_0_listener() { const action_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.hoveredAction = action_r10.ID); })("mouseleave", function ActionGalleryComponent_Conditional_10_For_2_Template_div_mouseleave_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.hoveredAction = null); })("click", function ActionGalleryComponent_Conditional_10_For_2_Template_div_click_0_listener() { const action_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleActionSelection(action_r10)); }); i0.ɵɵelementStart(1, "div", 39); i0.ɵɵlistener("click", function ActionGalleryComponent_Conditional_10_For_2_Template_div_click_1_listener($event) { const action_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); ctx_r1.toggleActionExpanded(action_r10); return i0.ɵɵresetView($event.stopPropagation()); }); i0.ɵɵelementStart(2, "div", 40); i0.ɵɵelement(3, "i"); i0.ɵɵelementEnd(); i0.ɵɵelementStart(4, "div", 41)(5, "h3", 42); i0.ɵɵtext(6); i0.ɵɵelementEnd(); i0.ɵɵelementStart(7, "div", 43); i0.ɵɵtemplate(8, ActionGalleryComponent_Conditional_10_For_2_Conditional_8_Template, 3, 1, "span", 44); i0.ɵɵelementEnd()(); i0.ɵɵelementStart(9, "div", 45); i0.ɵɵtemplate(10, ActionGalleryComponent_Conditional_10_For_2_Conditional_10_Template, 1, 0, "button", 46); i0.ɵɵelement(11, "i", 47); i0.ɵɵelementEnd()(); i0.ɵɵelementStart(12, "div", 48)(13, "p", 49); i0.ɵɵtext(14); i0.ɵɵelementEnd(); i0.ɵɵelementStart(15, "div", 50); i0.ɵɵtemplate(16, ActionGalleryComponent_Conditional_10_For_2_Conditional_16_Template, 3, 1, "span", 51)(17, ActionGalleryComponent_Conditional_10_For_2_Conditional_17_Template, 3, 1, "span", 51)(18, ActionGalleryComponent_Conditional_10_For_2_Conditional_18_Template, 3, 1, "span", 51); i0.ɵɵelementEnd()(); i0.ɵɵtemplate(19, ActionGalleryComponent_Conditional_10_For_2_Conditional_19_Template, 3, 2, "div", 52)(20, ActionGalleryComponent_Conditional_10_For_2_Conditional_20_Template, 2, 4, "div", 53); i0.ɵɵelementEnd(); } if (rf & 2) { const action_r10 = ctx.$implicit; const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵclassProp("expanded", action_r10.expanded)("selected", action_r10.selected)("animate", ctx_r1.animateCards)("hover", ctx_r1.hoveredAction === action_r10.ID); i0.ɵɵadvance(3); i0.ɵɵclassMapInterpolate1("fa-solid ", ctx_r1.getActionIcon(action_r10), ""); i0.ɵɵadvance(3); i0.ɵɵtextInterpolate(action_r10.Name); i0.ɵɵadvance(2); i0.ɵɵconditional(action_r10.Category ? 8 : -1); i0.ɵɵadvance(2); i0.ɵɵconditional(ctx_r1.config.enableQuickTest ? 10 : -1); i0.ɵɵadvance(); i0.ɵɵclassProp("fa-chevron-down", !action_r10.expanded)("fa-chevron-up", action_r10.expanded); i0.ɵɵadvance(3); i0.ɵɵtextInterpolate(action_r10.Description || "No description available"); i0.ɵɵadvance(2); i0.ɵɵconditional((action_r10.parameters == null ? null : action_r10.parameters.length) ? 16 : -1); i0.ɵɵadvance(); i0.ɵɵconditional((action_r10.resultCodes == null ? null : action_r10.resultCodes.length) ? 17 : -1); i0.ɵɵadvance(); i0.ɵɵconditional(action_r10.Type ? 18 : -1); i0.ɵɵadvance(); i0.ɵɵconditional(action_r10.expanded ? 19 : -1); i0.ɵɵadvance(); i0.ɵɵconditional(ctx_r1.config.selectionMode ? 20 : -1); } } function ActionGalleryComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 36); i0.ɵɵrepeaterCreate(1, ActionGalleryComponent_Conditional_10_For_2_Template, 21, 24, "div", 37, _forTrack1); i0.ɵɵpipe(3, "async"); i0.ɵɵelementEnd(); } if (rf & 2) { const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵstyleProp("grid-template-columns", "repeat(" + (ctx_r1.config.gridColumns || 3) + ", 1fr)"); i0.ɵɵadvance(); i0.ɵɵrepeater(i0.ɵɵpipeBind1(3, 2, ctx_r1.filteredActions$)); } } function ActionGalleryComponent_Conditional_15_For_13_Conditional_11_Template(rf, ctx) { if (rf & 1) { const _r16 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "button", 55); i0.ɵɵlistener("click", function ActionGalleryComponent_Conditional_15_For_13_Conditional_11_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r16); const action_r15 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.testAction(action_r15, $event)); }); i0.ɵɵelementEnd(); } } function ActionGalleryComponent_Conditional_15_For_13_Conditional_12_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 53); i0.ɵɵelement(1, "i", 17); i0.ɵɵelementEnd(); } if (rf & 2) { const action_r15 = i0.ɵɵnextContext().$implicit; i0.ɵɵadvance(); i0.ɵɵclassProp("fa-check-circle", action_r15.selected)("fa-circle", !action_r15.selected); } } function ActionGalleryComponent_Conditional_15_For_13_Template(rf, ctx) { if (rf & 1) { const _r14 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "div", 76); i0.ɵɵlistener("click", function ActionGalleryComponent_Conditional_15_For_13_Template_div_click_0_listener() { const action_r15 = i0.ɵɵrestoreView(_r14).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleActionSelection(action_r15)); }); i0.ɵɵelementStart(1, "span", 70); i0.ɵɵelement(2, "i"); i0.ɵɵtext(3); i0.ɵɵelementEnd(); i0.ɵɵelementStart(4, "span", 71); i0.ɵɵtext(5); i0.ɵɵelementEnd(); i0.ɵɵelementStart(6, "span", 72); i0.ɵɵtext(7); i0.ɵɵelementEnd(); i0.ɵɵelementStart(8, "span", 73); i0.ɵɵtext(9); i0.ɵɵelementEnd(); i0.ɵɵelementStart(10, "span", 74); i0.ɵɵtemplate(11, ActionGalleryComponent_Conditional_15_For_13_Conditional_11_Template, 1, 0, "button", 46); i0.ɵɵelementEnd(); i0.ɵɵtemplate(12, ActionGalleryComponent_Conditional_15_For_13_Conditional_12_Template, 2, 4, "div", 53); i0.ɵɵelementEnd(); } if (rf & 2) { const action_r15 = ctx.$implicit; const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵclassProp("selected", action_r15.selected); i0.ɵɵadvance(2); i0.ɵɵclassMapInterpolate1("fa-solid ", ctx_r1.getActionIcon(action_r15), " action-icon"); i0.ɵɵadvance(); i0.ɵɵtextInterpolate1(" ", action_r15.Name, " "); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(action_r15.Category || "-"); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(action_r15.Type || "-"); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate((action_r15.parameters == null ? null : action_r15.parameters.length) || 0); i0.ɵɵadvance(2); i0.ɵɵconditional(ctx_r1.config.enableQuickTest ? 11 : -1); i0.ɵɵadvance(); i0.ɵɵconditional(ctx_r1.config.selectionMode ? 12 : -1); } } function ActionGalleryComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 9)(1, "div", 69)(2, "span", 70); i0.ɵɵtext(3, "Name"); i0.ɵɵelementEnd(); i0.ɵɵelementStart(4, "span", 71); i0.ɵɵtext(5, "Category"); i0.ɵɵelementEnd(); i0.ɵɵelementStart(6, "span", 72); i0.ɵɵtext(7, "Type"); i0.ɵɵelementEnd(); i0.ɵɵelementStart(8, "span", 73); i0.ɵɵtext(9, "Parameters"); i0.ɵɵelementEnd(); i0.ɵɵelementStart(10, "span", 74); i0.ɵɵtext(11, "Actions"); i0.ɵɵelementEnd()(); i0.ɵɵrepeaterCreate(12, ActionGalleryComponent_Conditional_15_For_13_Template, 13, 11, "div", 75, _forTrack1); i0.ɵɵpipe(14, "async"); i0.ɵɵelementEnd(); } if (rf & 2) { const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵadvance(12); i0.ɵɵrepeater(i0.ɵɵpipeBind1(14, 0, ctx_r1.filteredActions$)); } } export class ActionGalleryComponent { constructor() { this.config = { selectionMode: false, multiSelect: false, showCategories: true, showSearch: true, defaultView: 'grid', gridColumns: 3, enableQuickTest: true, theme: 'light' }; this.preSelectedActions = []; this.actionSelected = new EventEmitter(); this.actionsSelected = new EventEmitter(); this.actionTestRequested = new EventEmitter(); // State management this.destroy$ = new Subject(); this.actions$ = new BehaviorSubject([]); this.categories$ = new BehaviorSubject([]); this.filteredActions$ = new BehaviorSubject([]); this.categoryTree$ = new BehaviorSubject([]); this.selectedCategory$ = new BehaviorSubject('all'); this.viewMode$ = new BehaviorSubject('grid'); this.isLoading$ = new BehaviorSubject(false); this.selectedActions$ = new BehaviorSubject(new Set()); // Form controls this.searchControl = new FormControl(''); // UI state this.expandedCategories = new Set(); this.hoveredAction = null; this.animateCards = false; // Statistics this.totalActions = 0; this.categoryCounts = new Map(); } ngOnInit() { // Set initial view mode this.viewMode$.next(this.config.defaultView || 'grid'); // Load data this.loadData(); // Set up filtering combineLatest([ this.actions$, this.searchControl.valueChanges.pipe(debounceTime(300), distinctUntilChanged()), this.selectedCategory$ ]).pipe(takeUntil(this.destroy$)).subscribe(([actions, searchTerm, category]) => { this.filterActions(actions, searchTerm || '', category); }); // Initialize with pre-selected actions if (this.preSelectedActions.length > 0) { this.selectedActions$.next(new Set(this.preSelectedActions)); } // Enable animations after initial load setTimeout(() => { this.animateCards = true; }, 100); } ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); } async loadData() { this.isLoading$.next(true); try { const rv = new RunView(); // Load actions and categories in parallel const [actionsResult, categoriesResult] = await rv.RunViews([ { EntityName: 'Actions', ResultType: 'entity_object', OrderBy: 'Category, Name', MaxRows: 5000 }, { EntityName: 'Action Categories', ResultType: 'entity_object', OrderBy: 'Name', MaxRows: 1000 } ]); if (actionsResult.Success && categoriesResult.Success) { const actions = actionsResult.Results || []; const categories = categoriesResult.Results || []; // Process actions const actionsWithDetails = actions.map(action => ({ ...action, expanded: false, selected: this.preSelectedActions.includes(action.ID) })); this.actions$.next(actionsWithDetails); this.totalActions = actions.length; // Process categories this.categories$.next(categories); this.buildCategoryTree(categories, actions); // Initial filter this.filterActions(actionsWithDetails, '', 'all'); } } catch (error) { console.error('Error loading gallery data:', error); } finally { this.isLoading$.next(false); } } buildCategoryTree(categories, actions) { // Count actions per category this.categoryCounts.clear(); actions.forEach(action => { const count = this.categoryCounts.get(action.Category || 'Uncategorized') || 0; this.categoryCounts.set(action.Category || 'Uncategorized', count + 1); }); // Build tree structure const nodeMap = new Map(); const rootNodes = []; // Create nodes categories.forEach(cat => { const node = { id: cat.ID, name: cat.Name, parent: cat.ParentID || undefined, children: [], count: this.categoryCounts.get(cat.Name) || 0, icon: this.getCategoryIcon(cat.Name) }; nodeMap.set(cat.ID, node); }); // Build hierarchy nodeMap.forEach(node => { if (node.parent && nodeMap.has(node.parent)) { const parent = nodeMap.get(node.parent); parent.children.push(node); // Accumulate counts up the tree parent.count = (parent.count || 0) + (node.count || 0); } else { rootNodes.push(node); } }); // Add "All" category at the top const allNode = { id: 'all', name: 'All Actions', count: this.totalActions, icon: 'fa-th' }; // Add "Uncategorized" if needed const uncategorizedCount = this.categoryCounts.get('Uncategorized') || 0; if (uncategorizedCount > 0) { const uncategorizedNode = { id: 'uncategorized', name: 'Uncategorized', count: uncategorizedCount, icon: 'fa-question-circle' }; rootNodes.push(uncategorizedNode); } this.categoryTree$.next([allNode, ...rootNodes]); } getCategoryIcon(categoryName) { const iconMap = { 'Data': 'fa-database', 'Communication': 'fa-envelope', 'Integration': 'fa-plug', 'Security': 'fa-shield', 'Workflow': 'fa-project-diagram', 'AI': 'fa-brain', 'Files': 'fa-file', 'Utilities': 'fa-tools', 'System': 'fa-cog', 'Analytics': 'fa-chart-line' }; return iconMap[categoryName] || 'fa-folder'; } getCategoryIconClass(category) { // Ensure we have a valid icon if (!category.icon) { return 'fa-solid fa-folder category-icon'; } return `fa-solid ${category.icon} category-icon`; } filterActions(actions, searchTerm, category) { let filtered = [...actions]; // Category filter if (category && category !== 'all') { if (category === 'uncategorized') { filtered = filtered.filter(a => !a.Category); } else { const categoryName = this.getCategoryName(category); filtered = filtered.filter(a => a.Category === categoryName); } } // Search filter if (searchTerm) { const term = searchTerm.toLowerCase(); filtered = filtered.filter(action => action.Name.toLowerCase().includes(term) || action.Description?.toLowerCase().includes(term) || action.Category?.toLowerCase().includes(term)); } this.filteredActions$.next(filtered); } getCategoryName(categoryId) { const category = this.categories$.value.find(c => c.ID === categoryId); return category?.Name || ''; } selectCategory(categoryId) { this.selectedCategory$.next(categoryId); } toggleCategoryExpanded(categoryId) { if (this.expandedCategories.has(categoryId)) { this.expandedCategories.delete(categoryId); } else { this.expandedCategories.add(categoryId); } } toggleViewMode() { const currentMode = this.viewMode$.value; this.viewMode$.next(currentMode === 'grid' ? 'list' : 'grid'); } async toggleActionExpanded(action) { action.expanded = !action.expanded; // Load details if expanding and not already loaded if (action.expanded && !action.parameters) { await this.loadActionDetails(action); } } async loadActionDetails(action) { const rv = new RunView(); try { const [paramsResult, resultCodesResult] = await rv.RunViews([ { EntityName: 'Action Params', ExtraFilter: `ActionID='${action.ID}'`, OrderBy: 'Sequence', ResultType: 'entity_object', MaxRows: 100 }, { EntityName: 'Action Result Codes', ExtraFilter: `ActionID='${action.ID}'`, OrderBy: 'ResultCode', ResultType: 'entity_object', MaxRows: 100 } ]); if (paramsResult.Success) { action.parameters = paramsResult.Results || []; } if (resultCodesResult.Success) { action.resultCodes = resultCodesResult.Results || []; } } catch (error) { console.error('Error loading action details:', error); } } toggleActionSelection(action) { if (!this.config.selectionMode) return; const selected = this.selectedActions$.value; if (!this.config.multiSelect) { // Single select mode selected.clear(); if (!action.selected) { selected.add(action.ID); action.selected = true; this.actionSelected.emit(action); } } else { // Multi-select mode if (action.selected) { selected.delete(action.ID); action.selected = false; } else { selected.add(action.ID); action.selected = true; } } this.selectedActions$.next(new Set(selected)); if (this.config.multiSelect) { const selectedActions = this.actions$.value.filter(a => selected.has(a.ID)); this.actionsSelected.emit(selectedActions); } } testAction(action, event) { event.stopPropagation(); if (this.config.enableQuickTest) { // TODO: Implement test harness integration console.log('Test action:', action.Name); } this.actionTestRequested.emit(action); } clearSearch() { this.searchControl.reset(); if (this.searchInput) { this.searchInput.nativeElement.focus(); } } getSelectedActions() { const selected = this.selectedActions$.value; return this.actions$.value.filter(a => selected.has(a.ID)); } getActionIcon(action) { const typeIcons = { 'Create': 'fa-plus-circle', 'Update': 'fa-edit', 'Delete': 'fa-trash', 'Query': 'fa-search', 'Process': 'fa-cogs', 'Email': 'fa-envelope', 'Report': 'fa-file-alt', 'Export': 'fa-file-export', 'Import': 'fa-file-import', 'API': 'fa-plug', 'Script': 'fa-code' }; for (const [key, icon] of Object.entries(typeIcons)) { if (action.Name.toLowerCase().includes(key.toLowerCase()) || action.Type?.toLowerCase().includes(key.toLowerCase())) { return icon; } } return 'fa-bolt'; } static { this.ɵfac = function ActionGalleryComponent_Factory(t) { return new (t || ActionGalleryComponent)(); }; } static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ActionGalleryComponent, selectors: [["mj-action-gallery"]], viewQuery: function ActionGalleryComponent_Query(rf, ctx) { if (rf & 1) { i0.ɵɵviewQuery(_c0, 5); } if (rf & 2) { let _t; i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.searchInput = _t.first); } }, inputs: { config: "config", preSelectedActions: "preSelectedActions" }, outputs: { actionSelected: "actionSelected", actionsSelected: "actionsSelected", actionTestRequested: "actionTestRequested" }, decls: 20, vars: 34, consts: [["searchInput", ""], [1, "action-gallery"], [1, "gallery-header"], [1, "gallery-content"], [1, "category-sidebar"], [1, "actions-container"], [1, "loading-state"], [1, "empty-state"], [1, "actions-grid", 3, "grid-template-columns"], [1, "actions-list"], [1, "header-content"], [1, "search-section"], ["placeholder", "Search actions by name, description, or category...", 1, "search-input", 3, "formControl", "clearButton"], ["kendoTextBoxPrefixTemplate", ""], [1, "header-actions"], [1, "view-toggle"], ["kendoButton", "", "size", "small", "kendoTooltip", "", 3, "click", "toggleable", "selected", "title"], [1, "fa-solid"], [1, "stats"], [1, "stat-item"], [1, "fa-solid", "fa-bolt"], [1, "fa-solid", "fa-search"], [1, "category-tree"], [1, "category-item", 3, "selected", "has-children"], [1, "category-item", 3, "click"], [1, "category-header"], [1, "category-name"], [1, "category-count"], [1, "fa-solid", "fa-chevron-right", "expand-icon", 3, "expanded"], [1, "sub-categories"], [1, "fa-solid", "fa-chevron-right", "expand-icon", 3, "click"], [1, "category-item", "sub-category", 3, "selected"], [1, "category-item", "sub-category", 3, "click"], ["size", "large"], [1, "fa-solid", "fa-search-minus"], ["kendoButton", "", 3, "click"], [1, "actions-grid"], [1, "action-card", 3, "expanded", "selected", "animate", "hover"], [1, "action-card", 3, "mouseenter", "mouseleave", "click"], [1, "card-header", 3, "click"], [1, "action-icon"], [1, "action-info"], [1, "action-name"], [1, "action-meta"], [1, "category-badge"], [1, "card-actions"], ["kendoButton", "", "look", "flat", "size", "small", "icon", "play", "kendoTooltip", "", "title", "Test this action"], [1, "fa-solid", "expand-indicator"], [1, "card-body"], [1, "action-description"], [1, "action-stats"], [1, "stat"], [1, "card-details"], [1, "selection-indicator"], [1, "fa-solid", "fa-folder"], ["kendoButton", "", "look", "flat", "size", "small", "icon", "play", "kendoTooltip", "", "title", "Test this action", 3, "click"], [1, "fa-solid", "fa-sliders"], [1, "fa-solid", "fa-code-branch"], [1, "fa-solid", "fa-tag"], [1, "detail-section"], [1, "parameters-list"], [1, "parameter-item"], [1, "param-name"], [1, "param-type"], [1, "param-required"], [1, "result-codes-list"], [1, "result-code-item"], [1, "code-value"], [1, "code-desc"], [1, "list-header"], [1, "col-name"], [1, "col-category"], [1, "col-type"], [1, "col-params"], [1, "col-actions"], [1, "list-item", 3, "selected"], [1, "list-item", 3, "click"]], template: function ActionGalleryComponent_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 1); i0.ɵɵtemplate(1, ActionGalleryComponent_Conditional_1_Template, 19, 21, "div", 2); i0.ɵɵelementStart(2, "div", 3); i0.ɵɵtemplate(3, ActionGalleryComponent_Conditional_3_Template, 5, 2, "div", 4); i0.ɵɵelementStart(4, "div", 5); i0.ɵɵtemplate(5, ActionGalleryComponent_Conditional_5_Template, 4, 0, "div", 6); i0.ɵɵpipe(6, "async"); i0.ɵɵtemplate(7, ActionGalleryComponent_Conditional_7_Template, 8, 0, "div", 7); i0.ɵɵpipe(8, "async"); i0.ɵɵpipe(9, "async"); i0.ɵɵtemplate(10, ActionGalleryComponent_Conditional_10_Template, 4, 4, "div", 8); i0.ɵɵpipe(11, "async"); i0.ɵɵpipe(12, "async"); i0.ɵɵpipe(13, "async"); i0.ɵɵpipe(14, "async"); i0.ɵɵtemplate(15, ActionGalleryComponent_Conditional_15_Template, 15, 2, "div", 9); i0.ɵɵpipe(16, "async"); i0.ɵɵpipe(17, "async"); i0.ɵɵpipe(18, "async"); i0.ɵɵpipe(19, "async"); i0.ɵɵelementEnd()()(); } if (rf & 2) { let tmp_6_0; i0.ɵɵclassProp("dark-theme", ctx.config.theme === "dark")("selection-mode", ctx.config.selectionMode); i0.ɵɵadvance(); i0.ɵɵconditional(ctx.config.showSearch ? 1 : -1); i0.ɵɵadvance(); i0.ɵɵclassProp("no-categories", !ctx.config.showCategories); i0.ɵɵadvance(); i0.ɵɵconditional(ctx.config.showCategories ? 3 : -1); i0.ɵɵadvance(2); i0.ɵɵconditional(i0.ɵɵpipeBind1(6, 12, ctx.isLoading$) ? 5 : -1); i0.ɵɵadvance(2); i0.ɵɵconditional(!i0.ɵɵpipeBind1(8, 14, ctx.isLoading$) && ((tmp_6_0 = i0.ɵɵpipeBind1(9, 16, ctx.filteredActions$)) == null ? null : tmp_6_0.length) === 0 ? 7 : -1); i0.ɵɵadvance(3); i0.ɵɵconditional(!i0.ɵɵpipeBind1(11, 18, ctx.isLoading$) && i0.ɵɵpipeBind1(12, 20, ctx.viewMode$) === "grid" && i0.ɵɵpipeBind1(13, 22, ctx.filteredActions$) && i0.ɵɵpipeBind1(14, 24, ctx.filteredActions$).length > 0 ? 10 : -1); i0.ɵɵadvance(5); i0.ɵɵconditional(!i0.ɵɵpipeBind1(16, 26, ctx.isLoading$) && i0.ɵɵpipeBind1(17, 28, ctx.viewMode$) === "list" && i0.ɵɵpipeBind1(18, 30, ctx.filteredActions$) && i0.ɵɵpipeBind1(19, 32, ctx.filteredActions$).length > 0 ? 15 : -1); } }, dependencies: [i1.NgControlStatus, i1.FormControlDirective, i2.ButtonComponent, i3.TextBoxComponent, i3.TextBoxPrefixTemplateDirective, i4.LoaderComponent, i5.TooltipDirective, i6.AsyncPipe], styles: ["@import '@progress/kendo-theme-default/scss/all';\n\n//[_ngcontent-%COMP%] Variables\n$primary-color[_ngcontent-%COMP%]: #3b82f6[_ngcontent-%COMP%];\n$secondary-color[_ngcontent-%COMP%]: #8b5cf6[_ngcontent-%COMP%];\n$success-color[_ngcontent-%COMP%]: #10b981[_ngcontent-%COMP%];\n$warning-color[_ngcontent-%COMP%]: #f59e0b[_ngcontent-%COMP%];\n$error-color[_ngcontent-%COMP%]: #ef4444[_ngcontent-%COMP%];\n$dark-bg[_ngcontent-%COMP%]: #1e293b[_ngcontent-%COMP%];\n$light-bg[_ngcontent-%COMP%]: #f8fafc[_ngcontent-%COMP%];\n$card-shadow[_ngcontent-%COMP%]: 0[_ngcontent-%COMP%] 1px[_ngcontent-%COMP%] 3px[_ngcontent-%COMP%] 0[_ngcontent-%COMP%] rgba(0[_ngcontent-%COMP%], 0[_ngcontent-%COMP%], 0[_ngcontent-%COMP%], 0.1)[_ngcontent-%COMP%], 0[_ngcontent-%COMP%] 1px[_ngcontent-%COMP%] 2px[_ngcontent-%COMP%] 0[_ngcontent-%COMP%] rgba(0[_ngcontent-%COMP%], 0[_ngcontent-%COMP%], 0[_ngcontent-%COMP%], 0.06)[_ngcontent-%COMP%];\n$card-hover-shadow[_ngcontent-%COMP%]: 0[_ngcontent-%COMP%] 10px[_ngcontent-%COMP%] 15px[_ngcontent-%COMP%] -3px[_ngcontent-%COMP%] rgba(0[_ngcontent-%COMP%], 0[_ngcontent-%COMP%], 0[_ngcontent-%COMP%], 0.1)[_ngcontent-%COMP%], 0[_ngcontent-%COMP%] 4px[_ngcontent-%COMP%] 6px[_ngcontent-%COMP%] -2px[_ngcontent-%COMP%] rgba(0[_ngcontent-%COMP%], 0[_ngcontent-%COMP%], 0[_ngcontent-%COMP%], 0.05)[_ngcontent-%COMP%];\n$border-radius[_ngcontent-%COMP%]: 12px[_ngcontent-%COMP%];\n$transition-speed[_ngcontent-%COMP%]: 0.3s[_ngcontent-%COMP%];\n\n//[_ngcontent-%COMP%] Animations\n@keyframes[_ngcontent-%COMP%] fadeIn[_ngcontent-%COMP%] {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes _ngcontent-%COMP%_scaleIn {\n from {\n transform: scale(0.95);\n opacity: 0;\n }\n to {\n transform: scale(1);\n opacity: 1;\n }\n}\n\n@keyframes _ngcontent-%COMP%_shimmer {\n 0% {\n background-position: -1000px 0;\n }\n 100% {\n background-position: 1000px 0;\n }\n}\n\n.action-gallery[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n \n &.dark-theme {\n background: $dark-bg;\n color: #f1f5f9;\n \n .gallery-header {\n background: #0f172a;\n border-bottom-color: #334155;\n }\n \n .category-sidebar {\n background: #0f172a;\n border-right-color: #334155;\n }\n \n .action-card {\n background: #1e293b;\n border-color: #334155;\n \n &:hover {\n background: #253449;\n }\n }\n \n .search-input .k-textbox {\n background: #1e293b;\n border-color: #334155;\n color: #f1f5f9;\n }\n }\n}\n\n//[_ngcontent-%COMP%] Gallery[_ngcontent-%COMP%] Header\n.gallery-header[_ngcontent-%COMP%] {\n background: white;\n border-bottom: 1px solid #e5e7eb;\n padding: 1rem 1.5rem;\n \n .header-content {\n display: flex;\n align-items: center;\n gap: 1.5rem;\n }\n \n .search-section {\n flex: 1;\n \n .search-input {\n width: 100%;\n \n .k-textbox {\n padding-left: 2.5rem;\n border-radius: 8px;\n height: 40px;\n transition: all $transition-speed ease;\n \n &:focus {\n border-color: $primary-color;\n box-shadow: 0 0 0 3px rgba($primary-color, 0.1);\n }\n }\n \n .fa-search {\n position: absolute;\n left: 1rem;\n color: #94a3b8;\n }\n }\n }\n \n .header-actions {\n display: flex;\n align-items: center;\n gap: 1.5rem;\n \n .view-toggle {\n .k-button {\n border-radius: 6px;\n }\n }\n \n .stats {\n .stat-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n color: #64748b;\n font-size: 0.875rem;\n \n i {\n color: $primary-color;\n }\n }\n }\n }\n}\n\n//[_ngcontent-%COMP%] Main[_ngcontent-%COMP%] Content\n.gallery-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n overflow: hidden;\n \n &.no-categories {\n .actions-container {\n margin-left: 0;\n }\n }\n}\n\n//[_ngcontent-%COMP%] Category[_ngcontent-%COMP%] Sidebar\n.category-sidebar[_ngcontent-%COMP%] {\n width: 280px;\n background: $light-bg;\n border-right: 1px solid #e5e7eb;\n overflow-y: auto;\n padding: 1rem;\n \n .category-tree {\n .category-item {\n margin-bottom: 0.25rem;\n cursor: pointer;\n transition: all $transition-speed ease;\n \n &:hover {\n .category-header {\n background: rgba($primary-color, 0.05);\n }\n }\n \n &.selected {\n .category-header {\n background: rgba($primary-color, 0.1);\n color: $primary-color;\n font-weight: 500;\n }\n }\n \n .category-header {\n display: flex;\n align-items: center;\n padding: 0.75rem 1rem;\n border-radius: 8px;\n transition: all $transition-speed ease;\n \n .category-icon {\n width: 20px;\n margin-right: 0.75rem;\n color: #64748b;\n }\n \n .category-name {\n flex: 1;\n }\n \n .category-count {\n font-size: 0.875rem;\n color: #94a3b8;\n background: rgba(0, 0, 0, 0.05);\n padding: 0.125rem 0.5rem;\n border-radius: 12px;\n margin-right: 0.5rem;\n }\n \n .expand-icon {\n color: #94a3b8;\n transition: transform $transition-speed ease;\n \n &.expanded {\n transform: rotate(90deg);\n }\n }\n }\n \n &.sub-category {\n .category-header {\n padding-left: 2.5rem;\n font-size: 0.875rem;\n }\n }\n }\n \n .sub-categories {\n animation: fadeIn $transition-speed ease;\n }\n }\n}\n\n//[_ngcontent-%COMP%] Actions[_ngcontent-%COMP%] Container\n.actions-container[_ngcontent-%COMP%] {\n flex: 1;\n padding: 1.5rem;\n overflow-y: auto;\n background: white;\n}\n\n//[_ngcontent-%COMP%] Loading[_ngcontent-%COMP%] State\n.loading-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: #64748b;\n \n p {\n margin-top: 1rem;\n font-size: 1.125rem;\n }\n}\n\n//[_ngcontent-%COMP%] Empty[_ngcontent-%COMP%] State\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n text-align: center;\n color: #64748b;\n \n i {\n font-size: 4rem;\n color: #cbd5e1;\n margin-bottom: 1rem;\n }\n \n h3 {\n font-size: 1.5rem;\n font-weight: 600;\n margin-bottom: 0.5rem;\n color: #475569;\n }\n \n p {\n margin-bottom: 1.5rem;\n }\n \n .k-button {\n border-radius: 8px;\n }\n}\n\n//[_ngcontent-%COMP%] Grid[_ngcontent-%COMP%] View\n.actions-grid[_ngcontent-%COMP%] {\n display: grid;\n gap: 1.5rem;\n grid-auto-rows: min-content;\n \n .action-card {\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: $border-radius;\n overflow: hidden;\n transition: all $transition-speed ease;\n cursor: pointer;\n position: relative;\n \n &.animate {\n animation: _ngcontent-%COMP%_scaleIn 0.4s ease-out;\n animation-fill-mode: both;\n \n @for $i from 1 through 20 {\n &:nth-child(#{$i}) {\n animation-delay: #{$i * 0.05}s;\n }\n }\n }\n \n &:hover {\n transform: translateY(-4px);\n box-shadow: $card-hover-shadow;\n border-color: $primary-color;\n }\n \n &.selected {\n border-color: $primary-color;\n box-shadow: 0 0 0 3px rgba($primary-color, 0.1);\n \n .selection-indicator {\n color: $primary-color;\n }\n }\n \n .card-header {\n padding: 1.25rem;\n display: flex;\n align-items: flex-start;\n gap: 1rem;\n cursor: pointer;\n \n .action-icon {\n width: 48px;\n height: 48px;\n border-radius: 10px;\n background: linear-gradient(135deg, $primary-color, $secondary-color);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 1.5rem;\n flex-shrink: 0;\n }\n \n .action-info {\n flex: 1;\n min-width: 0;\n \n .action-name {\n font-size: 1.125rem;\n font-weight: 600;\n margin: 0 0 0.5rem 0;\n line-height: 1.2;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n }\n \n .action-meta {\n display: flex;\n gap: 0.5rem;\n flex-wrap: wrap;\n \n .category-badge {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n font-size: 0.75rem;\n padding: 0.25rem 0.75rem;\n background: rgba($primary-color, 0.1);\n color: $primary-color;\n border-radius: 16px;\n font-weight: 500;\n \n i {\n font-size: 0.625rem;\n }\n }\n }\n }\n \n .card-actions {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n \n .k-button {\n opacity: 0;\n transition: opacity $transition-speed ease;\n }\n \n .expand-indicator {\n color: #94a3b8;\n transition: transform $transition-speed ease;\n }\n }\n }\n \n &:hover .card-header .card-actions .k-button {\n opacity: 1;\n }\n \n .card-body {\n padding: 0 1.25rem 1.25rem;\n \n .action-description {\n font-size: 0.875rem;\n color: #64748b;\n line-height: 1.5;\n margin-bottom: 1rem;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -w