@brickclay-org/ui 0.1.91 → 0.1.92

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.
@@ -8,9 +8,9 @@ import * as i2 from '@angular/cdk/overlay';
8
8
  import { OverlayModule, Overlay } from '@angular/cdk/overlay';
9
9
  import { Subject, filter } from 'rxjs';
10
10
  import moment from 'moment';
11
- import * as i3 from '@angular/cdk/drag-drop';
11
+ import * as i1$1 from '@angular/cdk/drag-drop';
12
12
  import { moveItemInArray, DragDropModule, CdkDragHandle } from '@angular/cdk/drag-drop';
13
- import * as i1$1 from '@angular/cdk/scrolling';
13
+ import * as i1$2 from '@angular/cdk/scrolling';
14
14
  import { ScrollingModule, CdkScrollable, CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
15
15
  import { NgxMaskDirective, provideNgxMask } from 'ngx-mask';
16
16
  import { DIALOG_DATA, CdkDialogContainer, Dialog, DialogModule } from '@angular/cdk/dialog';
@@ -5955,7 +5955,7 @@ class BkGrid {
5955
5955
  return this.noRecordImgUrl || './assets/icons/no-data-found.jpg';
5956
5956
  }
5957
5957
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkGrid, deps: [], target: i0.ɵɵFactoryTarget.Component });
5958
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkGrid, isStandalone: true, selector: "bk-grid", inputs: { draggable: "draggable", columns: "columns", result: "result", actions: "actions", customClass: "customClass", actionIconClass: "actionIconClass", actionClass: "actionClass", showNoRecords: "showNoRecords", noRecordFoundHeight: "noRecordFoundHeight", noRecordImgUrl: "noRecordImgUrl", showNoRecordImg: "showNoRecordImg", noRecordMessage: "noRecordMessage", rows: "rows" }, outputs: { change: "change", actionClick: "actionClick", sortChange: "sortChange", dragDropChange: "dragDropChange" }, viewQueries: [{ propertyName: "tableScrollContainer", first: true, predicate: ["tableScrollContainer"], descendants: true }], ngImport: i0, template: "<div #tableScrollContainer cdkScrollable class=\"overflow-y-auto\" [ngClass]=\"customClass\">\r\n <table class=\"min-w-full text-sm text-left text-gray-800 table-auto border-collapse\">\r\n <!-- ================= HEADER ================= -->\r\n <thead>\r\n <tr>\r\n @for (col of columns; track col.header; let i = $index) {\r\n @if (isColumnVisible(col)) {\r\n <th\r\n class=\"grid-header sticky top-[-1px]\"\r\n [class.cursor-pointer]=\"col.sortable\"\r\n [class.cursor-default]=\"!col.sortable\"\r\n [class.action-sticky]=\"col.sticky\"\r\n [class.z-10]=\"col.sticky\"\r\n class=\"{{ col.headerClass }} {{ col.cellClass }}\"\r\n (click)=\"sort(col, i)\"\r\n >\r\n <!-- [ngClass]=\"col.headerClass\"\r\n [ngClass]=\"col.cellClass\" -->\r\n <span\r\n class=\"flex items-center gap-1\"\r\n [ngClass]=\"\r\n sortColumn === col.field\r\n ? sortDirection === 'asc'\r\n ? 'grid-asc'\r\n : 'grid-desc'\r\n : ''\r\n \"\r\n >\r\n {{ col.header }}\r\n @if (col.sortable) {\r\n <span class=\"grid-sort-icon\"></span>\r\n }\r\n </span>\r\n </th>\r\n }\r\n }\r\n\r\n @if (actions.length) {\r\n <th class=\"grid-header sticky top-0 action-sticky z-10 !bg-[#FBFBFC] w-20 {{actionClass}}\">Action</th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <!-- ================= BODY ================= -->\r\n <tbody\r\n cdkDropList\r\n [cdkDropListDisabled]=\"!draggable\"\r\n [cdkDropListData]=\"result || []\"\r\n (cdkDropListDropped)=\"dropList($event)\"\r\n >\r\n @for (row of result; track row; let rowIndex = $index) {\r\n <tr\r\n cdkDrag\r\n cdkDragLockAxis=\"y\"\r\n [cdkDragDisabled]=\"!draggable\"\r\n (cdkDragStarted)=\"onDragStart($event)\"\r\n (cdkDragMoved)=\"onDragMoved($event)\"\r\n class=\"\"\r\n [ngClass]=\"{ 'cursor-move ': draggable }\"\r\n >\r\n @for (col of columns; track col.header; let colIndex = $index) {\r\n @if (isColumnVisible(col)) {\r\n <td class=\"grid-cell text-nowrap\" [ngClass]=\"col.cellClass\">\r\n @if (draggable && colIndex === firstVisibleColumnIndex) {\r\n <span\r\n cdkDragHandle\r\n class=\"mr-2 text-gray-400\"\r\n [ngClass]=\"{ 'cursor-move': draggable }\"\r\n >\u2630</span\r\n >\r\n }\r\n @if (col.checkbox) {\r\n <bk-checkbox\r\n checkboxClass=\"sm\"\r\n [ngModel]=\"getCheckboxValue(row, col)\"\r\n (ngModelChange)=\"setCheckboxValue(row, col, $event)\"\r\n [disabled]=\"typeof col.checkboxDisabled === 'function' ? col.checkboxDisabled(row) : col.checkboxDisabled || false\"\r\n [bkTooltip]=\"typeof col.checkboxTooltip === 'function' ? col.checkboxTooltip(row) : col.checkboxTooltip || ''\"\r\n [bkTooltipPosition]=\"col.checkboxTooltipPosition || 'top'\"\r\n ></bk-checkbox>\r\n } @else if (col.badges) {\r\n @let badge = getBadge(row, col);\r\n @if (badge) {\r\n <bk-badge\r\n [label]=\"badge.label\"\r\n [variant]=\"badge.variant\"\r\n [size]=\"badge.size\"\r\n [color]=\"badge.color\"\r\n [dot]=\"badge.dot\"\r\n [customClass]=\"badge.customClass\"\r\n [bkTooltip]=\"badge.toolTipLabel || ''\"\r\n [bkTooltipPosition]=\"badge.tooltipPosition || 'top'\"\r\n ></bk-badge>\r\n }\r\n } @else if (col.icons) {\r\n @let iconsList = getIcons(row, col);\r\n <div class=\"flex justify-center items-center gap-2\">\r\n @for (icon of iconsList; track $index) {\r\n @if(icon.url){\r\n <img\r\n [src]=\"icon.url\"\r\n class=\"size-4\"\r\n [ngClass]=\"{ 'cursor-pointer': icon.url }\"\r\n [bkTooltip]=\"icon.toolTipLabel || []\"\r\n [bkTooltipPosition]=\"icon.tooltipPosition || 'top'\"\r\n />\r\n }\r\n }\r\n </div>\r\n } @else if (col.toolTipField) {\r\n <span\r\n [bkTooltip]=\"getTooltipValue(row, col)\"\r\n [bkTooltipPosition]=\"col.toolTipPosition || 'top'\"\r\n >\r\n {{ getCellValue(row, col) }}\r\n </span>\r\n } @else {\r\n {{ getCellValue(row, col) }}\r\n }\r\n </td>\r\n }\r\n }\r\n\r\n @if (getRowActions(row).length) {\r\n <td class=\"grid-cell action-sticky text-center\">\r\n <div class=\"flex items-center justify-center gap-1.5\">\r\n @for (action of getRowActions(row); track action.name) {\r\n @if (isActionVisible(action, row)) {\r\n <!-- <bk-icon-button\r\n [bkTooltip]=\"action.tooltip\"\r\n [size]=\"\"\r\n [bkTooltipPosition]=\"action?.tooltipPosition || 'top'\"\r\n class=\"size-6 flex items-center justify-center rounded hover:bg-[#F8F8FA]\"\r\n (clicked)=\"emitAction(action, row)\"\r\n [disabled]=\"isActionDisabled(action, row)\">\r\n </bk-icon-button> -->\r\n <button\r\n [bkTooltip]=\"action.tooltip\"\r\n [bkTooltipPosition]=\"action?.tooltipPosition || 'top'\"\r\n class=\"size-6 flex items-center justify-center rounded hover:bg-[#F8F8FA] {{actionIconClass}}\"\r\n (click)=\"emitAction(action, row)\"\r\n [disabled]=\"isActionDisabled(action, row)\"\r\n >\r\n <img [src]=\"action.icon\" width=\"14\" height=\"14\" alt=\"action-icon\" />\r\n </button>\r\n }\r\n }\r\n </div>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n @if (showNoRecords) {\r\n <tr>\r\n <td\r\n [attr.colspan]=\"columns.length + (actions.length ? 1 : 0)\"\r\n class=\"text-center py-10 {{ noRecordFoundHeight }}\"\r\n >\r\n <div class=\"flex flex-col justify-center items-center w-full h-auto\">\r\n @if (showNoRecordImg) {\r\n <img\r\n [src]=\"noRecordImagePath\"\r\n class=\"mb-3 w-96\"\r\n alt=\"No data found\"\r\n />\r\n }\r\n\r\n <span class=\"block text-sm leading-3 text-center font-semibold text-[#60646C] mt-2\"\r\n >{{ noRecordMessage }}</span\r\n >\r\n </div>\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n</div>\r\n", styles: [".grid-header{@apply bg-[#F9FAFA] text-xs text-[#60646C] font-semibold capitalize px-[17px] py-2.5 whitespace-nowrap;box-shadow:0 1px #ebedf3;-webkit-transform:translateZ(0);transform:translateZ(0);backface-visibility:hidden;-webkit-backface-visibility:hidden}thead tr th:first-child{border-top-left-radius:.75rem}thead tr th:last-child{border-top-right-radius:.75rem}.grid-cell{@apply text-[#15191E] text-[13px] font-medium leading-4 px-4 py-2 border-x border-b border-[#EBEDF3];}.grid-cell:last-child{@apply border-e-0;}.grid-cell:first-child,.grid-first-cell{@apply border-s-0;}.grid-last-cell{@apply border-e-0;}.grid-action-sticky{@apply sticky bg-white right-[.1px] z-[1px];}.grid-action-sticky:before{@apply absolute top-0 bottom-0 left-[-8px] w-2;content:\"\";background-image:linear-gradient(to left,rgba(0,0,0,.05),transparent)}.grid-required{@apply font-medium text-sm leading-normal after:content-[\"*\"] after:text-[#C10007] after:ms-0.5;}.grid-sort{display:inline-flex;align-items:center;gap:.35rem;cursor:pointer;line-height:1}.grid-sort-icon{display:inline-flex;flex-direction:column;justify-content:center;align-items:center;height:.875rem;width:.875rem;gap:.125rem;line-height:1}.grid-sort-icon:before{display:inline-block;content:\"\";height:.3rem;width:.54rem;background-repeat:no-repeat;background-position:center;background-size:cover;background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M1.08333 4.83333C0.908333 4.83333 0.791667 4.775 0.675 4.65833C0.441667 4.425 0.441667 4.075 0.675 3.84167L3.59167 0.925C3.825 0.691667 4.175 0.691667 4.40833 0.925L7.325 3.84167C7.55833 4.075 7.55833 4.425 7.325 4.65833C7.09167 4.89167 6.74167 4.89167 6.50833 4.65833L4 2.15L1.49167 4.65833C1.375 4.775 1.25833 4.83333 1.08333 4.83333Z' fill='%2378829D'/%3e%3c/svg%3e\")}.grid-sort-icon:after{display:inline-block;content:\"\";height:.3rem;width:.54rem;background-repeat:no-repeat;background-position:center;background-size:cover;background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M4 4.24984C3.825 4.24984 3.70833 4.1915 3.59167 4.07484L0.675 1.15817C0.441667 0.924838 0.441667 0.574837 0.675 0.341504C0.908333 0.108171 1.25833 0.108171 1.49167 0.341504L4 2.84984L6.50833 0.341504C6.74167 0.108171 7.09167 0.108171 7.325 0.341504C7.55833 0.574837 7.55833 0.924838 7.325 1.15817L4.40833 4.07484C4.29167 4.1915 4.175 4.24984 4 4.24984Z' fill='%2378829D'/%3e%3c/svg%3e\")}.grid-asc>.grid-sort-icon:before{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M1.08333 4.83333C0.908333 4.83333 0.791667 4.775 0.675 4.65833C0.441667 4.425 0.441667 4.075 0.675 3.84167L3.59167 0.925C3.825 0.691667 4.175 0.691667 4.40833 0.925L7.325 3.84167C7.55833 4.075 7.55833 4.425 7.325 4.65833C7.09167 4.89167 6.74167 4.89167 6.50833 4.65833L4 2.15L1.49167 4.65833C1.375 4.775 1.25833 4.83333 1.08333 4.83333Z' fill='%234B5675'/%3e%3c/svg%3e\")}.grid-asc>.grid-sort-icon:after{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M4 4.24984C3.825 4.24984 3.70833 4.1915 3.59167 4.07484L0.675 1.15817C0.441667 0.924838 0.441667 0.574837 0.675 0.341504C0.908333 0.108171 1.25833 0.108171 1.49167 0.341504L4 2.84984L6.50833 0.341504C6.74167 0.108171 7.09167 0.108171 7.325 0.341504C7.55833 0.574837 7.55833 0.924838 7.325 1.15817L4.40833 4.07484C4.29167 4.1915 4.175 4.24984 4 4.24984Z' fill='%23C4CADA'/%3e%3c/svg%3e\")}.grid-desc>.grid-sort-icon:before{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M1.08333 4.83333C0.908333 4.83333 0.791667 4.775 0.675 4.65833C0.441667 4.425 0.441667 4.075 0.675 3.84167L3.59167 0.925C3.825 0.691667 4.175 0.691667 4.40833 0.925L7.325 3.84167C7.55833 4.075 7.55833 4.425 7.325 4.65833C7.09167 4.89167 6.74167 4.89167 6.50833 4.65833L4 2.15L1.49167 4.65833C1.375 4.775 1.25833 4.83333 1.08333 4.83333Z' fill='%23C4CADA'/%3e%3c/svg%3e\")}.grid-desc>.grid-sort-icon:after{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M4 4.24984C3.825 4.24984 3.70833 4.1915 3.59167 4.07484L0.675 1.15817C0.441667 0.924838 0.441667 0.574837 0.675 0.341504C0.908333 0.108171 1.25833 0.108171 1.49167 0.341504L4 2.84984L6.50833 0.341504C6.74167 0.108171 7.09167 0.108171 7.325 0.341504C7.55833 0.574837 7.55833 0.924838 7.325 1.15817L4.40833 4.07484C4.29167 4.1915 4.175 4.24984 4 4.24984Z' fill='%234B5675'/%3e%3c/svg%3e\")}.cdk-drag-preview{display:table;width:100%;background:#fff;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:.4;background-color:#f3f4f6}.cdk-drag-animating,.cdk-drop-list-dragging .cdk-drag{transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "directive", type: i3.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i3.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "component", type: BkBadge, selector: "bk-badge", inputs: ["label", "variant", "color", "size", "dot", "removable", "customClass", "customBg", "customBorder", "customText"], outputs: ["clicked"] }, { kind: "directive", type: BKTooltipDirective, selector: "[bkTooltip]", inputs: ["bkTooltip", "bkTooltipPosition", "bkTooltipScrollable", "bkTooltipMaxHeight", "bkTooltipSize", "bkTooltipAutoHeight"] }, { kind: "component", type: BkCheckbox, selector: "bk-checkbox", inputs: ["checkboxClass", "label", "labelClass", "disabled"], outputs: ["change"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
5958
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkGrid, isStandalone: true, selector: "bk-grid", inputs: { draggable: "draggable", columns: "columns", result: "result", actions: "actions", customClass: "customClass", actionIconClass: "actionIconClass", actionClass: "actionClass", showNoRecords: "showNoRecords", noRecordFoundHeight: "noRecordFoundHeight", noRecordImgUrl: "noRecordImgUrl", showNoRecordImg: "showNoRecordImg", noRecordMessage: "noRecordMessage", rows: "rows" }, outputs: { change: "change", actionClick: "actionClick", sortChange: "sortChange", dragDropChange: "dragDropChange" }, viewQueries: [{ propertyName: "tableScrollContainer", first: true, predicate: ["tableScrollContainer"], descendants: true }], ngImport: i0, template: "<div #tableScrollContainer cdkScrollable class=\"overflow-y-auto\" [ngClass]=\"customClass\">\r\n <table class=\"min-w-full text-sm text-left text-gray-800 table-auto border-collapse\">\r\n <!-- ================= HEADER ================= -->\r\n <thead>\r\n <tr>\r\n @for (col of columns; track col.header; let i = $index) {\r\n @if (isColumnVisible(col)) {\r\n <th\r\n class=\"grid-header sticky top-[-1px]\"\r\n [class.cursor-pointer]=\"col.sortable\"\r\n [class.cursor-default]=\"!col.sortable\"\r\n [class.action-sticky]=\"col.sticky\"\r\n [class.z-10]=\"col.sticky\"\r\n class=\"{{ col.headerClass }} {{ col.cellClass }}\"\r\n (click)=\"sort(col, i)\"\r\n >\r\n <!-- [ngClass]=\"col.headerClass\"\r\n [ngClass]=\"col.cellClass\" -->\r\n <span\r\n class=\"flex items-center gap-1\"\r\n [ngClass]=\"\r\n sortColumn === col.field\r\n ? sortDirection === 'asc'\r\n ? 'grid-asc'\r\n : 'grid-desc'\r\n : ''\r\n \"\r\n >\r\n {{ col.header }}\r\n @if (col.sortable) {\r\n <span class=\"grid-sort-icon\"></span>\r\n }\r\n </span>\r\n </th>\r\n }\r\n }\r\n\r\n @if (actions.length) {\r\n <th class=\"grid-header sticky top-0 action-sticky z-10 !bg-[#FBFBFC] w-20 {{actionClass}}\">Action</th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <!-- ================= BODY ================= -->\r\n <tbody\r\n cdkDropList\r\n [cdkDropListDisabled]=\"!draggable\"\r\n [cdkDropListData]=\"result || []\"\r\n (cdkDropListDropped)=\"dropList($event)\"\r\n >\r\n @for (row of result; track row; let rowIndex = $index) {\r\n <tr\r\n cdkDrag\r\n cdkDragLockAxis=\"y\"\r\n [cdkDragDisabled]=\"!draggable\"\r\n (cdkDragStarted)=\"onDragStart($event)\"\r\n (cdkDragMoved)=\"onDragMoved($event)\"\r\n class=\"\"\r\n [ngClass]=\"{ 'cursor-move ': draggable }\"\r\n >\r\n @for (col of columns; track col.header; let colIndex = $index) {\r\n @if (isColumnVisible(col)) {\r\n <td class=\"grid-cell text-nowrap\" [ngClass]=\"col.cellClass\">\r\n @if (draggable && colIndex === firstVisibleColumnIndex) {\r\n <span\r\n cdkDragHandle\r\n class=\"mr-2 text-gray-400\"\r\n [ngClass]=\"{ 'cursor-move': draggable }\"\r\n >\u2630</span\r\n >\r\n }\r\n @if (col.checkbox) {\r\n <bk-checkbox\r\n checkboxClass=\"sm\"\r\n [ngModel]=\"getCheckboxValue(row, col)\"\r\n (ngModelChange)=\"setCheckboxValue(row, col, $event)\"\r\n [disabled]=\"typeof col.checkboxDisabled === 'function' ? col.checkboxDisabled(row) : col.checkboxDisabled || false\"\r\n [bkTooltip]=\"typeof col.checkboxTooltip === 'function' ? col.checkboxTooltip(row) : col.checkboxTooltip || ''\"\r\n [bkTooltipPosition]=\"col.checkboxTooltipPosition || 'top'\"\r\n ></bk-checkbox>\r\n } @else if (col.badges) {\r\n @let badge = getBadge(row, col);\r\n @if (badge) {\r\n <bk-badge\r\n [label]=\"badge.label\"\r\n [variant]=\"badge.variant\"\r\n [size]=\"badge.size\"\r\n [color]=\"badge.color\"\r\n [dot]=\"badge.dot\"\r\n [customClass]=\"badge.customClass\"\r\n [bkTooltip]=\"badge.toolTipLabel || ''\"\r\n [bkTooltipPosition]=\"badge.tooltipPosition || 'top'\"\r\n ></bk-badge>\r\n }\r\n } @else if (col.icons) {\r\n @let iconsList = getIcons(row, col);\r\n <div class=\"flex justify-center items-center gap-2\">\r\n @for (icon of iconsList; track $index) {\r\n @if(icon.url){\r\n <img\r\n [src]=\"icon.url\"\r\n class=\"size-4\"\r\n [ngClass]=\"{ 'cursor-pointer': icon.url }\"\r\n [bkTooltip]=\"icon.toolTipLabel || []\"\r\n [bkTooltipPosition]=\"icon.tooltipPosition || 'top'\"\r\n />\r\n }\r\n }\r\n </div>\r\n } @else if (col.toolTipField) {\r\n <span\r\n [bkTooltip]=\"getTooltipValue(row, col)\"\r\n [bkTooltipPosition]=\"col.toolTipPosition || 'top'\"\r\n >\r\n {{ getCellValue(row, col) }}\r\n </span>\r\n } @else {\r\n {{ getCellValue(row, col) }}\r\n }\r\n </td>\r\n }\r\n }\r\n\r\n @if (getRowActions(row).length) {\r\n <td class=\"grid-cell action-sticky text-center\">\r\n <div class=\"flex items-center justify-center gap-1.5\">\r\n @for (action of getRowActions(row); track action.name) {\r\n @if (isActionVisible(action, row)) {\r\n <!-- <bk-icon-button\r\n [bkTooltip]=\"action.tooltip\"\r\n [size]=\"\"\r\n [bkTooltipPosition]=\"action?.tooltipPosition || 'top'\"\r\n class=\"size-6 flex items-center justify-center rounded hover:bg-[#F8F8FA]\"\r\n (clicked)=\"emitAction(action, row)\"\r\n [disabled]=\"isActionDisabled(action, row)\">\r\n </bk-icon-button> -->\r\n <button\r\n [bkTooltip]=\"action.tooltip\"\r\n [bkTooltipPosition]=\"action?.tooltipPosition || 'top'\"\r\n class=\"size-6 flex items-center justify-center rounded hover:bg-[#F8F8FA] {{actionIconClass}}\"\r\n (click)=\"emitAction(action, row)\"\r\n [disabled]=\"isActionDisabled(action, row)\"\r\n >\r\n <img [src]=\"action.icon\" width=\"14\" height=\"14\" alt=\"action-icon\" />\r\n </button>\r\n }\r\n }\r\n </div>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n @if (showNoRecords) {\r\n <tr>\r\n <td\r\n [attr.colspan]=\"columns.length + (actions.length ? 1 : 0)\"\r\n class=\"text-center py-10 {{ noRecordFoundHeight }}\"\r\n >\r\n <div class=\"flex flex-col justify-center items-center w-full h-auto\">\r\n @if (showNoRecordImg) {\r\n <img\r\n [src]=\"noRecordImagePath\"\r\n class=\"mb-3 w-96\"\r\n alt=\"No data found\"\r\n />\r\n }\r\n\r\n <span class=\"block text-sm leading-3 text-center font-semibold text-[#60646C] mt-2\"\r\n >{{ noRecordMessage }}</span\r\n >\r\n </div>\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n</div>\r\n", styles: [".grid-header{@apply bg-[#F9FAFA] text-xs text-[#60646C] font-semibold capitalize px-[17px] py-2.5 whitespace-nowrap;box-shadow:0 1px #ebedf3;-webkit-transform:translateZ(0);transform:translateZ(0);backface-visibility:hidden;-webkit-backface-visibility:hidden}thead tr th:first-child{border-top-left-radius:.75rem}thead tr th:last-child{border-top-right-radius:.75rem}.grid-cell{@apply text-[#15191E] text-[13px] font-medium leading-4 px-4 py-2 border-x border-b border-[#EBEDF3];}.grid-cell:last-child{@apply border-e-0;}.grid-cell:first-child,.grid-first-cell{@apply border-s-0;}.grid-last-cell{@apply border-e-0;}.grid-action-sticky{@apply sticky bg-white right-[.1px] z-[1px];}.grid-action-sticky:before{@apply absolute top-0 bottom-0 left-[-8px] w-2;content:\"\";background-image:linear-gradient(to left,rgba(0,0,0,.05),transparent)}.grid-required{@apply font-medium text-sm leading-normal after:content-[\"*\"] after:text-[#C10007] after:ms-0.5;}.grid-sort{display:inline-flex;align-items:center;gap:.35rem;cursor:pointer;line-height:1}.grid-sort-icon{display:inline-flex;flex-direction:column;justify-content:center;align-items:center;height:.875rem;width:.875rem;gap:.125rem;line-height:1}.grid-sort-icon:before{display:inline-block;content:\"\";height:.3rem;width:.54rem;background-repeat:no-repeat;background-position:center;background-size:cover;background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M1.08333 4.83333C0.908333 4.83333 0.791667 4.775 0.675 4.65833C0.441667 4.425 0.441667 4.075 0.675 3.84167L3.59167 0.925C3.825 0.691667 4.175 0.691667 4.40833 0.925L7.325 3.84167C7.55833 4.075 7.55833 4.425 7.325 4.65833C7.09167 4.89167 6.74167 4.89167 6.50833 4.65833L4 2.15L1.49167 4.65833C1.375 4.775 1.25833 4.83333 1.08333 4.83333Z' fill='%2378829D'/%3e%3c/svg%3e\")}.grid-sort-icon:after{display:inline-block;content:\"\";height:.3rem;width:.54rem;background-repeat:no-repeat;background-position:center;background-size:cover;background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M4 4.24984C3.825 4.24984 3.70833 4.1915 3.59167 4.07484L0.675 1.15817C0.441667 0.924838 0.441667 0.574837 0.675 0.341504C0.908333 0.108171 1.25833 0.108171 1.49167 0.341504L4 2.84984L6.50833 0.341504C6.74167 0.108171 7.09167 0.108171 7.325 0.341504C7.55833 0.574837 7.55833 0.924838 7.325 1.15817L4.40833 4.07484C4.29167 4.1915 4.175 4.24984 4 4.24984Z' fill='%2378829D'/%3e%3c/svg%3e\")}.grid-asc>.grid-sort-icon:before{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M1.08333 4.83333C0.908333 4.83333 0.791667 4.775 0.675 4.65833C0.441667 4.425 0.441667 4.075 0.675 3.84167L3.59167 0.925C3.825 0.691667 4.175 0.691667 4.40833 0.925L7.325 3.84167C7.55833 4.075 7.55833 4.425 7.325 4.65833C7.09167 4.89167 6.74167 4.89167 6.50833 4.65833L4 2.15L1.49167 4.65833C1.375 4.775 1.25833 4.83333 1.08333 4.83333Z' fill='%234B5675'/%3e%3c/svg%3e\")}.grid-asc>.grid-sort-icon:after{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M4 4.24984C3.825 4.24984 3.70833 4.1915 3.59167 4.07484L0.675 1.15817C0.441667 0.924838 0.441667 0.574837 0.675 0.341504C0.908333 0.108171 1.25833 0.108171 1.49167 0.341504L4 2.84984L6.50833 0.341504C6.74167 0.108171 7.09167 0.108171 7.325 0.341504C7.55833 0.574837 7.55833 0.924838 7.325 1.15817L4.40833 4.07484C4.29167 4.1915 4.175 4.24984 4 4.24984Z' fill='%23C4CADA'/%3e%3c/svg%3e\")}.grid-desc>.grid-sort-icon:before{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M1.08333 4.83333C0.908333 4.83333 0.791667 4.775 0.675 4.65833C0.441667 4.425 0.441667 4.075 0.675 3.84167L3.59167 0.925C3.825 0.691667 4.175 0.691667 4.40833 0.925L7.325 3.84167C7.55833 4.075 7.55833 4.425 7.325 4.65833C7.09167 4.89167 6.74167 4.89167 6.50833 4.65833L4 2.15L1.49167 4.65833C1.375 4.775 1.25833 4.83333 1.08333 4.83333Z' fill='%23C4CADA'/%3e%3c/svg%3e\")}.grid-desc>.grid-sort-icon:after{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M4 4.24984C3.825 4.24984 3.70833 4.1915 3.59167 4.07484L0.675 1.15817C0.441667 0.924838 0.441667 0.574837 0.675 0.341504C0.908333 0.108171 1.25833 0.108171 1.49167 0.341504L4 2.84984L6.50833 0.341504C6.74167 0.108171 7.09167 0.108171 7.325 0.341504C7.55833 0.574837 7.55833 0.924838 7.325 1.15817L4.40833 4.07484C4.29167 4.1915 4.175 4.24984 4 4.24984Z' fill='%234B5675'/%3e%3c/svg%3e\")}.cdk-drag-preview{display:table;width:100%;background:#fff;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:.4;background-color:#f3f4f6}.cdk-drag-animating,.cdk-drop-list-dragging .cdk-drag{transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2.CdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "directive", type: i1$1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1$1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i1$1.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "component", type: BkBadge, selector: "bk-badge", inputs: ["label", "variant", "color", "size", "dot", "removable", "customClass", "customBg", "customBorder", "customText"], outputs: ["clicked"] }, { kind: "directive", type: BKTooltipDirective, selector: "[bkTooltip]", inputs: ["bkTooltip", "bkTooltipPosition", "bkTooltipScrollable", "bkTooltipMaxHeight", "bkTooltipSize", "bkTooltipAutoHeight"] }, { kind: "component", type: BkCheckbox, selector: "bk-checkbox", inputs: ["checkboxClass", "label", "labelClass", "disabled"], outputs: ["change"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
5959
5959
  }
5960
5960
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkGrid, decorators: [{
5961
5961
  type: Component,
@@ -9193,7 +9193,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
9193
9193
  */
9194
9194
  class BkDialogContent {
9195
9195
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkDialogContent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
9196
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: BkDialogContent, isStandalone: true, selector: "[bk-dialog-content], bk-dialog-content, [bkDialogContent]", host: { classAttribute: "bk-dialog-content" }, exportAs: ["bkDialogContent"], hostDirectives: [{ directive: i1$1.CdkScrollable }], ngImport: i0 });
9196
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.16", type: BkDialogContent, isStandalone: true, selector: "[bk-dialog-content], bk-dialog-content, [bkDialogContent]", host: { classAttribute: "bk-dialog-content" }, exportAs: ["bkDialogContent"], hostDirectives: [{ directive: i1$2.CdkScrollable }], ngImport: i0 });
9197
9197
  }
9198
9198
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkDialogContent, decorators: [{
9199
9199
  type: Directive,
@@ -13776,7 +13776,7 @@ class BkDragHandle {
13776
13776
  icon = input(null, ...(ngDevMode ? [{ debugName: "icon" }] : []));
13777
13777
  ariaLabel = input('Reorder row', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
13778
13778
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkDragHandle, deps: [], target: i0.ɵɵFactoryTarget.Component });
13779
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: BkDragHandle, isStandalone: true, selector: "bk-drag-handle", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "button" }, properties: { "attr.aria-label": "ariaLabel()" }, classAttribute: "bk-drag-handle" }, exportAs: ["bkDragHandle"], hostDirectives: [{ directive: i3.CdkDragHandle }], ngImport: i0, template: `
13779
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: BkDragHandle, isStandalone: true, selector: "bk-drag-handle", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "button" }, properties: { "attr.aria-label": "ariaLabel()" }, classAttribute: "bk-drag-handle" }, exportAs: ["bkDragHandle"], hostDirectives: [{ directive: i1$1.CdkDragHandle }], ngImport: i0, template: `
13780
13780
  <ng-container [ngTemplateOutlet]="icon() ?? defaultIcon"></ng-container>
13781
13781
  <ng-template #defaultIcon>
13782
13782
  <svg width="10" height="16" viewBox="0 0 10 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
@@ -14077,6 +14077,396 @@ const BK_TABLE = [
14077
14077
  BkTreeDrag
14078
14078
  ];
14079
14079
 
14080
+ /**
14081
+ * Content-agnostic kanban board: column layout, card positioning and
14082
+ * drag-and-drop, and nothing about what a card contains or what a click on
14083
+ * one should do.
14084
+ *
14085
+ * The board never renders a card's insides itself — `cardTemplate` does that,
14086
+ * receiving the card and its column as context:
14087
+ *
14088
+ * <bk-kanban
14089
+ * [columns]="columns"
14090
+ * [cards]="cards()"
14091
+ * [cardTemplate]="card"
14092
+ * (cardMoved)="onCardMoved($event)"
14093
+ * (cardClicked)="onCardClicked($event)"
14094
+ * ></bk-kanban>
14095
+ *
14096
+ * <ng-template #card let-card let-column="column">
14097
+ * <div [bkKanbanClickTarget]="'hours'">{{ card.hours }}h</div>
14098
+ * {{ card.title }}
14099
+ * </ng-template>
14100
+ *
14101
+ * That is deliberate, not an oversight — see the package spec's Design
14102
+ * Principles. Three consequences fall out of it directly:
14103
+ *
14104
+ * - **Data ownership stays with the caller.** A move is reported through
14105
+ * `cardMoved`, not applied to some copy of `cards` this component keeps to
14106
+ * itself. Internally it *does* mutate the card objects it was handed
14107
+ * (`columnIdField`'s field, and an `order` field used to remember position
14108
+ * within a column) so the board redraws in the right place immediately,
14109
+ * exactly the way `bk-grid`'s own row-drag mutates `result` in place and
14110
+ * renumbers `sortOrder` — but persistence, and reverting the view if a
14111
+ * save fails, are the host's job. Reverting is just handing back a
14112
+ * `cards` array (or updated objects) that reflect the pre-move state; nothing
14113
+ * further to undo on this end.
14114
+ * - **Clicks are reported, never acted on.** `cardClicked` says which card and
14115
+ * which named region (see `[bkKanbanClickTarget]`); opening a popup or
14116
+ * doing nothing at all is entirely up to whoever is listening.
14117
+ * - **A card's own shape is never inspected**, beyond the two fields above.
14118
+ * Tags, hours, avatars, due dates — the board doesn't know they exist.
14119
+ */
14120
+ class BkKanban {
14121
+ /* ================= Inputs ================= */
14122
+ /** Column/status definitions. Unlimited — the board renders whatever it's given. */
14123
+ columns = input.required(...(ngDevMode ? [{ debugName: "columns" }] : []));
14124
+ /** Flat card list. Grouped into columns via `columnIdField`, ordered within
14125
+ * a column by an `order` field when the cards carry one, otherwise left in
14126
+ * the sequence they appear here. */
14127
+ cards = input.required(...(ngDevMode ? [{ debugName: "cards" }] : []));
14128
+ /** Renders a card's body. Receives `{ $implicit: card, card, column, index }`. */
14129
+ cardTemplate = input.required(...(ngDevMode ? [{ debugName: "cardTemplate" }] : []));
14130
+ /** Field name, or a resolver function, that gives a card's column id.
14131
+ *
14132
+ * A field name can be both read and written, so a cross-column drop
14133
+ * updates it directly. A resolver function is read-only — the board still
14134
+ * reports the move via `cardMoved`, but leaves updating the source data to
14135
+ * the host, since there's nowhere on a function to write the new value. */
14136
+ columnIdField = input('columnId', ...(ngDevMode ? [{ debugName: "columnIdField" }] : []));
14137
+ dragEnabled = input(true, ...(ngDevMode ? [{ debugName: "dragEnabled" }] : []));
14138
+ dragScope = input('both', ...(ngDevMode ? [{ debugName: "dragScope" }] : []));
14139
+ wipLimitBehavior = input('warn', ...(ngDevMode ? [{ debugName: "wipLimitBehavior" }] : []));
14140
+ /** Lets columns themselves be dragged into a new order, via their header
14141
+ * (`.bk-kanban-column-header` is the drag handle — a card's own drag
14142
+ * keeps working independently, since it's a separate, unconnected drop
14143
+ * list one level down). Off by default: reordering the board's own
14144
+ * columns is a bigger commitment than reordering cards within it, and not
14145
+ * every consumer wants a "To do / In progress / Done" pipeline to be
14146
+ * rearrangeable. `columns` is mutated in place the same way `cards` is
14147
+ * (see the component doc) — persisting the new order, if it needs to be,
14148
+ * is the host's job, done from `columnMoved`. */
14149
+ columnDragEnabled = input(false, ...(ngDevMode ? [{ debugName: "columnDragEnabled" }] : []));
14150
+ /** See `BkKanbanColumnScrollMode`. */
14151
+ columnScrollMode = input('body', ...(ngDevMode ? [{ debugName: "columnScrollMode" }] : []));
14152
+ /** Extra class(es) appended to the board's own wrapper — `.bk-kanban-board`
14153
+ * in `kanban.html`, the element that directly contains the scrollable
14154
+ * region holding every column. Same idea as `columnClass`/`colHeaderClass`
14155
+ * one level down: it only adds classes, nothing here replaces bk-kanban's
14156
+ * own layout.
14157
+ *
14158
+ * Deliberately kept off the *scrolling* element itself
14159
+ * (`.bk-kanban`, one level further in): a `padding` or `border` in here
14160
+ * would otherwise become part of what has to be scrolled past, and change
14161
+ * where the scrollbar itself ends up sitting relative to the columns —
14162
+ * this wrapper exists specifically so `boardClass` can decorate (a
14163
+ * background, a border, padding around the whole board) without ever
14164
+ * touching the box CDK and `columnScrollMode` are actually scrolling. */
14165
+ boardClass = input('', ...(ngDevMode ? [{ debugName: "boardClass" }] : []));
14166
+ /** Identity for `@for`'s `track`. Defaults to position in the rendered column. */
14167
+ trackBy = input(null, ...(ngDevMode ? [{ debugName: "trackBy" }] : []));
14168
+ /** Rendered in a fixed slot in every column's header — e.g. an "add card"
14169
+ * button. Receives `BkKanbanColumnActionsContext`. The board owns where it
14170
+ * sits; the consumer owns what it does. */
14171
+ columnHeaderActionsTemplate = input(null, ...(ngDevMode ? [{ debugName: "columnHeaderActionsTemplate" }] : []));
14172
+ /** Overrides the built-in "No cards" placeholder for an empty column.
14173
+ * Receives `BkKanbanEmptyStateContext`. Takes priority over both
14174
+ * `noDataText` and a column's own `noDataText` — see `emptyStateText`. */
14175
+ emptyStateTemplate = input(null, ...(ngDevMode ? [{ debugName: "emptyStateTemplate" }] : []));
14176
+ /** Board-wide placeholder text for an empty column, used whenever a column
14177
+ * doesn't set its own `noDataText`. Only read when `emptyStateTemplate`
14178
+ * isn't supplied — see `emptyStateText`. */
14179
+ noDataText = input('No cards', ...(ngDevMode ? [{ debugName: "noDataText" }] : []));
14180
+ /** Whether a column flags an over-limit drop while still dragging (`'live'`)
14181
+ * or only once the drop is attempted (`'on-drop'`). See the doc block on
14182
+ * `isLiveOverLimit` for how the two relate to `wipLimitBehavior`. */
14183
+ dragPreviewMode = input('live', ...(ngDevMode ? [{ debugName: "dragPreviewMode" }] : []));
14184
+ /* ================= Outputs ================= */
14185
+ cardMoved = output();
14186
+ cardClicked = output();
14187
+ columnLimitExceeded = output();
14188
+ /** A column reorder completed — see `columnDragEnabled`. */
14189
+ columnMoved = output();
14190
+ /** Reserved — see `BkKanbanColumnActionsContext.trigger`. Most consumers
14191
+ * bind a click handler directly on their own header-actions template and
14192
+ * never reach for this. */
14193
+ columnActionTriggered = output();
14194
+ /* ================= Grouping ================= */
14195
+ /**
14196
+ * Bumped after every in-place mutation (`setColumnId`, `renumber`) so
14197
+ * `grouped` re-runs even though neither `cards()`'s array identity nor any
14198
+ * card's object identity changed — the same trick as the table demo's
14199
+ * `pgSelectionTick`, needed for exactly the same reason: signals only
14200
+ * notice a new reference, and mutating fields in place is what lets a drop
14201
+ * redraw in the right place without waiting on the host to hand back a
14202
+ * whole new array.
14203
+ */
14204
+ structureTick = signal(0, ...(ngDevMode ? [{ debugName: "structureTick" }] : []));
14205
+ /** Cards grouped by column id, each group in `order` order when present
14206
+ * (falling back to their sequence in `cards()` otherwise). Cards whose
14207
+ * resolved column id matches no known column are dropped silently rather
14208
+ * than rendered nowhere. */
14209
+ grouped = computed(() => {
14210
+ this.structureTick();
14211
+ const map = new Map();
14212
+ for (const column of this.columns())
14213
+ map.set(column.id, []);
14214
+ for (const card of this.cards()) {
14215
+ const list = map.get(this.resolveColumnId(card));
14216
+ list?.push(card);
14217
+ }
14218
+ for (const list of map.values()) {
14219
+ if (list.some((c) => this.cardOrder(c) !== null)) {
14220
+ list.sort((a, b) => (this.cardOrder(a) ?? 0) - (this.cardOrder(b) ?? 0));
14221
+ }
14222
+ }
14223
+ return map;
14224
+ }, ...(ngDevMode ? [{ debugName: "grouped" }] : []));
14225
+ /** The cards to render for one column, in display order. */
14226
+ cardsFor(columnId) {
14227
+ return this.grouped().get(columnId) ?? [];
14228
+ }
14229
+ resolveColumnId(card) {
14230
+ const field = this.columnIdField();
14231
+ return typeof field === 'function' ? field(card) : card[field];
14232
+ }
14233
+ cardOrder(card) {
14234
+ const value = card['order'];
14235
+ return typeof value === 'number' ? value : null;
14236
+ }
14237
+ resolveTrackBy(card, index) {
14238
+ const fn = this.trackBy();
14239
+ return fn ? fn(card) : index;
14240
+ }
14241
+ /* ================= Column-level view state ================= */
14242
+ /** Column-header count badge, flagged once the column is over its limit —
14243
+ * only while `wipLimitBehavior` is `'warn'`; `'block'` should never let a
14244
+ * column get there and `'none'` treats the number as pure information. */
14245
+ isColumnOverLimit(column) {
14246
+ return (this.wipLimitBehavior() === 'warn' &&
14247
+ column.wipLimit != null &&
14248
+ this.cardsFor(column.id).length > column.wipLimit);
14249
+ }
14250
+ /** "3" with no limit, "3 / 5" with one — the header count badge's label. */
14251
+ columnCountLabel(column) {
14252
+ const count = this.cardsFor(column.id).length;
14253
+ return column.wipLimit != null ? `${count} / ${column.wipLimit}` : `${count}`;
14254
+ }
14255
+ columnActionsContext(column) {
14256
+ return {
14257
+ $implicit: column,
14258
+ column,
14259
+ trigger: () => this.columnActionTriggered.emit({ columnId: column.id })
14260
+ };
14261
+ }
14262
+ emptyStateContext(column) {
14263
+ return { $implicit: column, column };
14264
+ }
14265
+ /** Text for the built-in empty-column placeholder: a column's own
14266
+ * `noDataText` when it sets one, else the board-wide `noDataText` input.
14267
+ * Only consulted when `emptyStateTemplate` isn't supplied — the template
14268
+ * wins outright once given, exactly like `emptyStateContext` itself. */
14269
+ emptyStateText(column) {
14270
+ return column.noDataText ?? this.noDataText();
14271
+ }
14272
+ cardContext(card, column, index) {
14273
+ return { $implicit: card, card, column, index };
14274
+ }
14275
+ /** Which columns a column's drop list connects to, per `dragScope`. */
14276
+ connectedListIds(columnId) {
14277
+ if (!this.dragEnabled() || this.dragScope() === 'same')
14278
+ return [];
14279
+ return this.columns()
14280
+ .filter((c) => c.id !== columnId)
14281
+ .map((c) => c.id);
14282
+ }
14283
+ /** `'cross'` means *only* moves between columns — reordering within one has
14284
+ * to be switched off at the list level, since a scoped-out `connectedTo`
14285
+ * alone still leaves the list free to sort itself. */
14286
+ sortingDisabled = computed(() => this.dragScope() === 'cross', ...(ngDevMode ? [{ debugName: "sortingDisabled" }] : []));
14287
+ /* ================= Column-level drag (reordering columns) ================= */
14288
+ /**
14289
+ * `columns` is reordered in place — same trick as `cards` (see the
14290
+ * component doc): the array reference the host handed in is mutated
14291
+ * directly (`moveItemInArray`) rather than swapped for a new one, so the
14292
+ * next render just reflects the new order. There's no `structureTick`-style
14293
+ * signal to bump here the way card moves need one — nothing derives
14294
+ * columns through a `computed()` the way `cardsFor` derives through
14295
+ * `grouped`; the template reads `columns()` directly in its `@for`, so the
14296
+ * drop event's own change detection pass is enough.
14297
+ */
14298
+ onColumnDrop(event) {
14299
+ if (!this.columnDragEnabled() || event.previousIndex === event.currentIndex)
14300
+ return;
14301
+ const columns = this.columns();
14302
+ const moved = columns[event.previousIndex];
14303
+ moveItemInArray(columns, event.previousIndex, event.currentIndex);
14304
+ this.columnMoved.emit({
14305
+ columnId: moved.id,
14306
+ fromIndex: event.previousIndex,
14307
+ toIndex: event.currentIndex
14308
+ });
14309
+ }
14310
+ /* ================= Drag state (for the live WIP preview) ================= */
14311
+ dragSourceColumnId = signal(null, ...(ngDevMode ? [{ debugName: "dragSourceColumnId" }] : []));
14312
+ hoveredOverLimitColumnId = signal(null, ...(ngDevMode ? [{ debugName: "hoveredOverLimitColumnId" }] : []));
14313
+ onDragStarted(column) {
14314
+ this.dragSourceColumnId.set(column.id);
14315
+ }
14316
+ onDragEnded() {
14317
+ this.dragSourceColumnId.set(null);
14318
+ this.hoveredOverLimitColumnId.set(null);
14319
+ }
14320
+ /**
14321
+ * Live WIP-limit preview (§12 of the spec): as the dragged card enters a
14322
+ * column, work out whether *landing* here would exceed its `wipLimit` and
14323
+ * flag it immediately — before release, and independent of
14324
+ * `wipLimitBehavior`, which only governs what happens once the card is
14325
+ * actually dropped. A card re-entering its own source column doesn't grow
14326
+ * that column's count, so only a genuine cross-column entry counts as +1.
14327
+ */
14328
+ onListEntered(event, column) {
14329
+ if (this.dragPreviewMode() !== 'live' || column.wipLimit == null)
14330
+ return;
14331
+ const enteringFromElsewhere = this.dragSourceColumnId() !== column.id;
14332
+ const wouldBeCount = event.container.data.length + (enteringFromElsewhere ? 1 : 0);
14333
+ this.hoveredOverLimitColumnId.set(wouldBeCount > column.wipLimit ? column.id : null);
14334
+ }
14335
+ onListExited(column) {
14336
+ if (this.hoveredOverLimitColumnId() === column.id)
14337
+ this.hoveredOverLimitColumnId.set(null);
14338
+ }
14339
+ isLiveOverLimit(column) {
14340
+ return this.hoveredOverLimitColumnId() === column.id;
14341
+ }
14342
+ /* ================= Drop handling ================= */
14343
+ onDrop(event, column) {
14344
+ this.dragSourceColumnId.set(null);
14345
+ this.hoveredOverLimitColumnId.set(null);
14346
+ if (!this.dragEnabled())
14347
+ return;
14348
+ const fromColumnId = event.previousContainer.id;
14349
+ const toColumnId = event.container.id;
14350
+ const card = event.item.data;
14351
+ if (fromColumnId === toColumnId) {
14352
+ if (event.previousIndex === event.currentIndex)
14353
+ return;
14354
+ const list = this.cardsFor(toColumnId);
14355
+ moveItemInArray(list, event.previousIndex, event.currentIndex);
14356
+ this.renumber(list);
14357
+ this.structureTick.update((n) => n + 1);
14358
+ this.cardMoved.emit({ card, fromColumnId, toColumnId, newIndex: event.currentIndex });
14359
+ return;
14360
+ }
14361
+ const targetList = this.cardsFor(toColumnId);
14362
+ const attemptedCount = targetList.length + 1;
14363
+ const wipLimit = column.wipLimit;
14364
+ const wouldExceed = wipLimit != null && attemptedCount > wipLimit;
14365
+ if (wouldExceed) {
14366
+ this.columnLimitExceeded.emit({ columnId: toColumnId, wipLimit: wipLimit, attemptedCount });
14367
+ }
14368
+ if (wouldExceed && this.wipLimitBehavior() === 'block') {
14369
+ // Rejected: nothing below is mutated, so the next render finds the card
14370
+ // still exactly where `cards()` says it is — the same "snap back" any
14371
+ // cancelled CDK drag shows, not a bespoke undo.
14372
+ return;
14373
+ }
14374
+ const sourceList = this.cardsFor(fromColumnId);
14375
+ const fromIndex = sourceList.indexOf(card);
14376
+ if (fromIndex < 0)
14377
+ return; // Column and card disagree about where it lives; leave state alone.
14378
+ sourceList.splice(fromIndex, 1);
14379
+ targetList.splice(event.currentIndex, 0, card);
14380
+ this.setColumnId(card, toColumnId);
14381
+ this.renumber(sourceList);
14382
+ this.renumber(targetList);
14383
+ this.structureTick.update((n) => n + 1);
14384
+ this.cardMoved.emit({ card, fromColumnId, toColumnId, newIndex: event.currentIndex });
14385
+ }
14386
+ setColumnId(card, columnId) {
14387
+ const field = this.columnIdField();
14388
+ // A resolver function has nowhere to write back to — the host owns that
14389
+ // mapping and is expected to apply the move from `cardMoved` itself.
14390
+ if (typeof field === 'string')
14391
+ card[field] = columnId;
14392
+ }
14393
+ renumber(list) {
14394
+ list.forEach((card, index) => {
14395
+ card['order'] = index;
14396
+ });
14397
+ }
14398
+ /* ================= Click handling (§5) ================= */
14399
+ /**
14400
+ * One listener per card resolves both the whole-card click and every
14401
+ * `[bkKanbanClickTarget]` region: `closest()` from the actual event target
14402
+ * finds the nearest marked ancestor within this card, or there isn't one
14403
+ * and it's a plain card click. Either way this fires exactly once — never
14404
+ * once for the region and again for the card underneath it.
14405
+ */
14406
+ onCardClick(event, card) {
14407
+ const wrapper = event.currentTarget;
14408
+ const marked = event.target?.closest('[data-bk-kanban-click-target]');
14409
+ const target = marked && wrapper.contains(marked)
14410
+ ? (marked.dataset['bkKanbanClickTarget'] ?? 'card')
14411
+ : 'card';
14412
+ this.cardClicked.emit({ card, target });
14413
+ }
14414
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkKanban, deps: [], target: i0.ɵɵFactoryTarget.Component });
14415
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkKanban, isStandalone: true, selector: "bk-kanban", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, cards: { classPropertyName: "cards", publicName: "cards", isSignal: true, isRequired: true, transformFunction: null }, cardTemplate: { classPropertyName: "cardTemplate", publicName: "cardTemplate", isSignal: true, isRequired: true, transformFunction: null }, columnIdField: { classPropertyName: "columnIdField", publicName: "columnIdField", isSignal: true, isRequired: false, transformFunction: null }, dragEnabled: { classPropertyName: "dragEnabled", publicName: "dragEnabled", isSignal: true, isRequired: false, transformFunction: null }, dragScope: { classPropertyName: "dragScope", publicName: "dragScope", isSignal: true, isRequired: false, transformFunction: null }, wipLimitBehavior: { classPropertyName: "wipLimitBehavior", publicName: "wipLimitBehavior", isSignal: true, isRequired: false, transformFunction: null }, columnDragEnabled: { classPropertyName: "columnDragEnabled", publicName: "columnDragEnabled", isSignal: true, isRequired: false, transformFunction: null }, columnScrollMode: { classPropertyName: "columnScrollMode", publicName: "columnScrollMode", isSignal: true, isRequired: false, transformFunction: null }, boardClass: { classPropertyName: "boardClass", publicName: "boardClass", isSignal: true, isRequired: false, transformFunction: null }, trackBy: { classPropertyName: "trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null }, columnHeaderActionsTemplate: { classPropertyName: "columnHeaderActionsTemplate", publicName: "columnHeaderActionsTemplate", isSignal: true, isRequired: false, transformFunction: null }, emptyStateTemplate: { classPropertyName: "emptyStateTemplate", publicName: "emptyStateTemplate", isSignal: true, isRequired: false, transformFunction: null }, noDataText: { classPropertyName: "noDataText", publicName: "noDataText", isSignal: true, isRequired: false, transformFunction: null }, dragPreviewMode: { classPropertyName: "dragPreviewMode", publicName: "dragPreviewMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cardMoved: "cardMoved", cardClicked: "cardClicked", columnLimitExceeded: "columnLimitExceeded", columnMoved: "columnMoved", columnActionTriggered: "columnActionTriggered" }, host: { classAttribute: "bk-kanban-host" }, exportAs: ["bkKanban"], ngImport: i0, template: "<div class=\"bk-kanban-board\" [class]=\"boardClass()\">\r\n <div\r\n class=\"bk-kanban\"\r\n [class.bk-kanban--scroll-wrapper]=\"columnScrollMode() === 'wrapper'\"\r\n cdkDropList\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"columns()\"\r\n [cdkDropListDisabled]=\"!columnDragEnabled()\"\r\n (cdkDropListDropped)=\"onColumnDrop($event)\"\r\n >\r\n @for (column of columns(); track column.id) {\r\n <div\r\n class=\"bk-kanban-column\"\r\n cdkDrag\r\n [cdkDragData]=\"column\"\r\n [cdkDragDisabled]=\"!columnDragEnabled()\"\r\n [class]=\"column.columnClass\"\r\n [class.bk-kanban-column-warn]=\"isColumnOverLimit(column)\"\r\n [class.bk-kanban-column-live-over]=\"isLiveOverLimit(column)\"\r\n >\r\n <div class=\"bk-kanban-column-header\" cdkDragHandle [class]=\"column.colHeaderClass\">\r\n <span class=\"bk-kanban-column-title\">{{ column.label }}</span>\r\n <bk-badge\r\n class=\"bk-kanban-column-count\"\r\n [label]=\"columnCountLabel(column)\"\r\n size=\"sm\"\r\n [color]=\"isColumnOverLimit(column) || isLiveOverLimit(column) ? 'Warning' : 'Gray'\"\r\n ></bk-badge>\r\n\r\n @if (columnHeaderActionsTemplate(); as actionsTpl) {\r\n <div class=\"bk-kanban-column-actions\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"actionsTpl\"\r\n [ngTemplateOutletContext]=\"columnActionsContext(column)\"\r\n ></ng-container>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"bk-kanban-column-body\"\r\n cdkDropList\r\n [id]=\"column.id\"\r\n [cdkDropListData]=\"cardsFor(column.id)\"\r\n [cdkDropListConnectedTo]=\"connectedListIds(column.id)\"\r\n [cdkDropListSortingDisabled]=\"sortingDisabled()\"\r\n [cdkDropListDisabled]=\"!dragEnabled()\"\r\n (cdkDropListDropped)=\"onDrop($event, column)\"\r\n (cdkDropListEntered)=\"onListEntered($event, column)\"\r\n (cdkDropListExited)=\"onListExited(column)\"\r\n >\r\n @if (cardsFor(column.id).length === 0) {\r\n <div class=\"bk-kanban-empty\">\r\n @if (emptyStateTemplate(); as emptyTpl) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"emptyTpl\"\r\n [ngTemplateOutletContext]=\"emptyStateContext(column)\"\r\n ></ng-container>\r\n } @else {\r\n <span class=\"bk-kanban-empty-text\">{{ emptyStateText(column) }}</span>\r\n }\r\n </div>\r\n }\r\n\r\n @for (card of cardsFor(column.id); track resolveTrackBy(card, $index); let i = $index) {\r\n <div\r\n class=\"bk-kanban-card\"\r\n cdkDrag\r\n [cdkDragData]=\"card\"\r\n [cdkDragDisabled]=\"!dragEnabled()\"\r\n (cdkDragStarted)=\"onDragStarted(column)\"\r\n (cdkDragEnded)=\"onDragEnded()\"\r\n (click)=\"onCardClick($event, card)\"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"cardTemplate()\"\r\n [ngTemplateOutletContext]=\"cardContext(card, column, i)\"\r\n ></ng-container>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".bk-kanban-host,.bk-kanban-board{display:block;height:100%}.bk-kanban{@apply flex items-stretch gap-4 w-full h-full overflow-x-auto;scroll-snap-type:x proximity}.bk-kanban--scroll-wrapper{align-items:flex-start;overflow-y:auto}.bk-kanban--scroll-wrapper .bk-kanban-column-body{overflow-y:visible}.bk-kanban-column{@apply flex flex-col shrink-0 w-[300px] max-w-[85vw] rounded-xl border border-[#EBEDF3] overflow-hidden;background:var(--bk-kanban-column-bg, #f9fafa);scroll-snap-align:start}.bk-kanban-column-header{@apply flex items-center justify-between gap-2 px-3 py-2.5;background:var(--bk-kanban-header-bg, #f9fafa);border-bottom:1px solid #ebedf3}.bk-kanban-column:not(.cdk-drag-disabled)>.bk-kanban-column-header{cursor:grab}.bk-kanban-column.cdk-drag-dragging>.bk-kanban-column-header{cursor:grabbing}.bk-kanban-column-title{@apply text-[13px] font-semibold text-[#15191E] truncate;}.bk-kanban-column-count{@apply shrink-0;}.bk-kanban-column-actions{@apply shrink-0 flex items-center;}.bk-kanban-column-body{@apply flex-1 flex flex-col gap-2 p-2.5 overflow-y-auto;min-height:96px}.bk-kanban-empty{@apply flex flex-1 flex-col items-center justify-center py-6 text-center;}.bk-kanban-empty-text{@apply text-xs font-medium text-[#78829D];}.bk-kanban-card{@apply bg-white rounded-lg border border-[#EBEDF3] p-3 cursor-pointer;box-shadow:0 1px 2px #1018280a;transition:box-shadow .15s ease,border-color .15s ease}.bk-kanban-card:hover{@apply border-[#C4CADA];box-shadow:0 2px 6px #10182814}.bk-kanban-card.cdk-drag-dragging{transition:none}.bk-kanban-column-warn{@apply border-amber-300 bg-amber-50;}.bk-kanban-column-warn .bk-kanban-column-header{@apply bg-amber-50 border-amber-200;}.bk-kanban-column-live-over{@apply border-amber-400 bg-amber-50;outline:2px dashed theme(\"colors.amber.400\");outline-offset:-2px}.bk-kanban-column-live-over .bk-kanban-column-header{@apply bg-amber-50 border-amber-200;}.bk-kanban-card.cdk-drag-preview{@apply rounded-lg;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;cursor:grabbing}.bk-kanban-card.cdk-drag-placeholder{@apply border-dashed border-[#C4CADA] bg-[#F1F2F4];box-shadow:none;opacity:.6}.bk-kanban-column-body.cdk-drop-list-dragging .bk-kanban-card:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.bk-kanban-column.cdk-drag-preview{box-shadow:0 8px 10px -6px #0003,0 20px 25px -5px #00000024}.bk-kanban-column.cdk-drag-placeholder{@apply border-dashed border-[#C4CADA] bg-[#F1F2F4];box-shadow:none;opacity:.5}.bk-kanban-column.cdk-drag-placeholder .bk-kanban-column-header,.bk-kanban-column.cdk-drag-placeholder .bk-kanban-column-body{visibility:hidden}.bk-kanban.cdk-drop-list-dragging .bk-kanban-column:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}@media (max-width: 640px){.bk-kanban-column{width:86vw}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1$1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1$1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i1$1.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: BkBadge, selector: "bk-badge", inputs: ["label", "variant", "color", "size", "dot", "removable", "customClass", "customBg", "customBorder", "customText"], outputs: ["clicked"] }], encapsulation: i0.ViewEncapsulation.None });
14416
+ }
14417
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkKanban, decorators: [{
14418
+ type: Component,
14419
+ args: [{ selector: 'bk-kanban', standalone: true, exportAs: 'bkKanban', imports: [NgTemplateOutlet, DragDropModule, BkBadge], encapsulation: ViewEncapsulation.None, host: {
14420
+ class: 'bk-kanban-host'
14421
+ }, template: "<div class=\"bk-kanban-board\" [class]=\"boardClass()\">\r\n <div\r\n class=\"bk-kanban\"\r\n [class.bk-kanban--scroll-wrapper]=\"columnScrollMode() === 'wrapper'\"\r\n cdkDropList\r\n cdkDropListOrientation=\"horizontal\"\r\n [cdkDropListData]=\"columns()\"\r\n [cdkDropListDisabled]=\"!columnDragEnabled()\"\r\n (cdkDropListDropped)=\"onColumnDrop($event)\"\r\n >\r\n @for (column of columns(); track column.id) {\r\n <div\r\n class=\"bk-kanban-column\"\r\n cdkDrag\r\n [cdkDragData]=\"column\"\r\n [cdkDragDisabled]=\"!columnDragEnabled()\"\r\n [class]=\"column.columnClass\"\r\n [class.bk-kanban-column-warn]=\"isColumnOverLimit(column)\"\r\n [class.bk-kanban-column-live-over]=\"isLiveOverLimit(column)\"\r\n >\r\n <div class=\"bk-kanban-column-header\" cdkDragHandle [class]=\"column.colHeaderClass\">\r\n <span class=\"bk-kanban-column-title\">{{ column.label }}</span>\r\n <bk-badge\r\n class=\"bk-kanban-column-count\"\r\n [label]=\"columnCountLabel(column)\"\r\n size=\"sm\"\r\n [color]=\"isColumnOverLimit(column) || isLiveOverLimit(column) ? 'Warning' : 'Gray'\"\r\n ></bk-badge>\r\n\r\n @if (columnHeaderActionsTemplate(); as actionsTpl) {\r\n <div class=\"bk-kanban-column-actions\">\r\n <ng-container\r\n [ngTemplateOutlet]=\"actionsTpl\"\r\n [ngTemplateOutletContext]=\"columnActionsContext(column)\"\r\n ></ng-container>\r\n </div>\r\n }\r\n </div>\r\n\r\n <div\r\n class=\"bk-kanban-column-body\"\r\n cdkDropList\r\n [id]=\"column.id\"\r\n [cdkDropListData]=\"cardsFor(column.id)\"\r\n [cdkDropListConnectedTo]=\"connectedListIds(column.id)\"\r\n [cdkDropListSortingDisabled]=\"sortingDisabled()\"\r\n [cdkDropListDisabled]=\"!dragEnabled()\"\r\n (cdkDropListDropped)=\"onDrop($event, column)\"\r\n (cdkDropListEntered)=\"onListEntered($event, column)\"\r\n (cdkDropListExited)=\"onListExited(column)\"\r\n >\r\n @if (cardsFor(column.id).length === 0) {\r\n <div class=\"bk-kanban-empty\">\r\n @if (emptyStateTemplate(); as emptyTpl) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"emptyTpl\"\r\n [ngTemplateOutletContext]=\"emptyStateContext(column)\"\r\n ></ng-container>\r\n } @else {\r\n <span class=\"bk-kanban-empty-text\">{{ emptyStateText(column) }}</span>\r\n }\r\n </div>\r\n }\r\n\r\n @for (card of cardsFor(column.id); track resolveTrackBy(card, $index); let i = $index) {\r\n <div\r\n class=\"bk-kanban-card\"\r\n cdkDrag\r\n [cdkDragData]=\"card\"\r\n [cdkDragDisabled]=\"!dragEnabled()\"\r\n (cdkDragStarted)=\"onDragStarted(column)\"\r\n (cdkDragEnded)=\"onDragEnded()\"\r\n (click)=\"onCardClick($event, card)\"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"cardTemplate()\"\r\n [ngTemplateOutletContext]=\"cardContext(card, column, i)\"\r\n ></ng-container>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".bk-kanban-host,.bk-kanban-board{display:block;height:100%}.bk-kanban{@apply flex items-stretch gap-4 w-full h-full overflow-x-auto;scroll-snap-type:x proximity}.bk-kanban--scroll-wrapper{align-items:flex-start;overflow-y:auto}.bk-kanban--scroll-wrapper .bk-kanban-column-body{overflow-y:visible}.bk-kanban-column{@apply flex flex-col shrink-0 w-[300px] max-w-[85vw] rounded-xl border border-[#EBEDF3] overflow-hidden;background:var(--bk-kanban-column-bg, #f9fafa);scroll-snap-align:start}.bk-kanban-column-header{@apply flex items-center justify-between gap-2 px-3 py-2.5;background:var(--bk-kanban-header-bg, #f9fafa);border-bottom:1px solid #ebedf3}.bk-kanban-column:not(.cdk-drag-disabled)>.bk-kanban-column-header{cursor:grab}.bk-kanban-column.cdk-drag-dragging>.bk-kanban-column-header{cursor:grabbing}.bk-kanban-column-title{@apply text-[13px] font-semibold text-[#15191E] truncate;}.bk-kanban-column-count{@apply shrink-0;}.bk-kanban-column-actions{@apply shrink-0 flex items-center;}.bk-kanban-column-body{@apply flex-1 flex flex-col gap-2 p-2.5 overflow-y-auto;min-height:96px}.bk-kanban-empty{@apply flex flex-1 flex-col items-center justify-center py-6 text-center;}.bk-kanban-empty-text{@apply text-xs font-medium text-[#78829D];}.bk-kanban-card{@apply bg-white rounded-lg border border-[#EBEDF3] p-3 cursor-pointer;box-shadow:0 1px 2px #1018280a;transition:box-shadow .15s ease,border-color .15s ease}.bk-kanban-card:hover{@apply border-[#C4CADA];box-shadow:0 2px 6px #10182814}.bk-kanban-card.cdk-drag-dragging{transition:none}.bk-kanban-column-warn{@apply border-amber-300 bg-amber-50;}.bk-kanban-column-warn .bk-kanban-column-header{@apply bg-amber-50 border-amber-200;}.bk-kanban-column-live-over{@apply border-amber-400 bg-amber-50;outline:2px dashed theme(\"colors.amber.400\");outline-offset:-2px}.bk-kanban-column-live-over .bk-kanban-column-header{@apply bg-amber-50 border-amber-200;}.bk-kanban-card.cdk-drag-preview{@apply rounded-lg;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;cursor:grabbing}.bk-kanban-card.cdk-drag-placeholder{@apply border-dashed border-[#C4CADA] bg-[#F1F2F4];box-shadow:none;opacity:.6}.bk-kanban-column-body.cdk-drop-list-dragging .bk-kanban-card:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}.bk-kanban-column.cdk-drag-preview{box-shadow:0 8px 10px -6px #0003,0 20px 25px -5px #00000024}.bk-kanban-column.cdk-drag-placeholder{@apply border-dashed border-[#C4CADA] bg-[#F1F2F4];box-shadow:none;opacity:.5}.bk-kanban-column.cdk-drag-placeholder .bk-kanban-column-header,.bk-kanban-column.cdk-drag-placeholder .bk-kanban-column-body{visibility:hidden}.bk-kanban.cdk-drop-list-dragging .bk-kanban-column:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}@media (max-width: 640px){.bk-kanban-column{width:86vw}}\n"] }]
14422
+ }], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], cards: [{ type: i0.Input, args: [{ isSignal: true, alias: "cards", required: true }] }], cardTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "cardTemplate", required: true }] }], columnIdField: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnIdField", required: false }] }], dragEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragEnabled", required: false }] }], dragScope: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragScope", required: false }] }], wipLimitBehavior: [{ type: i0.Input, args: [{ isSignal: true, alias: "wipLimitBehavior", required: false }] }], columnDragEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnDragEnabled", required: false }] }], columnScrollMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnScrollMode", required: false }] }], boardClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "boardClass", required: false }] }], trackBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackBy", required: false }] }], columnHeaderActionsTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnHeaderActionsTemplate", required: false }] }], emptyStateTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyStateTemplate", required: false }] }], noDataText: [{ type: i0.Input, args: [{ isSignal: true, alias: "noDataText", required: false }] }], dragPreviewMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragPreviewMode", required: false }] }], cardMoved: [{ type: i0.Output, args: ["cardMoved"] }], cardClicked: [{ type: i0.Output, args: ["cardClicked"] }], columnLimitExceeded: [{ type: i0.Output, args: ["columnLimitExceeded"] }], columnMoved: [{ type: i0.Output, args: ["columnMoved"] }], columnActionTriggered: [{ type: i0.Output, args: ["columnActionTriggered"] }] } });
14423
+
14424
+ /**
14425
+ * Marks an element inside a `cardTemplate` as its own click region.
14426
+ *
14427
+ * `bk-kanban` never attaches a listener to this element directly — it puts
14428
+ * one listener on the whole card and, on click, walks up from
14429
+ * `event.target` (`Element.closest`) looking for the nearest marked
14430
+ * ancestor. That single-listener design is what makes a click on a marked
14431
+ * region resolve to *just* that region's name, instead of firing once for
14432
+ * the region and once more, as a duplicate, for the card underneath it.
14433
+ * This directive's only job is to leave something that walk can find: a
14434
+ * `data-bk-kanban-click-target` attribute carrying the name you gave it.
14435
+ *
14436
+ * <div [bkKanbanClickTarget]="'hours'">{{ card.hours }}h</div>
14437
+ * <div [bkKanbanClickTarget]="'assignee'">
14438
+ * <bk-ui-avatar [name]="card.assignee"></bk-ui-avatar>
14439
+ * </div>
14440
+ *
14441
+ * A click on either fires `cardClicked` with `target: 'hours'` /
14442
+ * `'assignee'`; a click anywhere else on the card falls back to the default
14443
+ * `target: 'card'`. See `BkKanbanCardClickedEvent`.
14444
+ */
14445
+ class BkKanbanClickTarget {
14446
+ target = input.required(...(ngDevMode ? [{ debugName: "target", alias: 'bkKanbanClickTarget' }] : [{ alias: 'bkKanbanClickTarget' }]));
14447
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkKanbanClickTarget, deps: [], target: i0.ɵɵFactoryTarget.Directive });
14448
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.16", type: BkKanbanClickTarget, isStandalone: true, selector: "[bkKanbanClickTarget]", inputs: { target: { classPropertyName: "target", publicName: "bkKanbanClickTarget", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "attr.data-bk-kanban-click-target": "target()" } }, ngImport: i0 });
14449
+ }
14450
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkKanbanClickTarget, decorators: [{
14451
+ type: Directive,
14452
+ args: [{
14453
+ selector: '[bkKanbanClickTarget]',
14454
+ standalone: true,
14455
+ host: {
14456
+ '[attr.data-bk-kanban-click-target]': 'target()'
14457
+ }
14458
+ }]
14459
+ }], propDecorators: { target: [{ type: i0.Input, args: [{ isSignal: true, alias: "bkKanbanClickTarget", required: true }] }] } });
14460
+
14461
+ /**
14462
+ * Types for bk-kanban.
14463
+ *
14464
+ * The board is content-agnostic by design (see the component's own doc
14465
+ * comment): it only ever moves opaque `T` values between columns and reports
14466
+ * what happened. Every type here describes either a column, or one of the
14467
+ * events the board reports — never anything about what a card renders as.
14468
+ */
14469
+
14080
14470
  /*
14081
14471
  * Public API Surface of brickclay-lib
14082
14472
  */
@@ -14086,5 +14476,5 @@ const BK_TABLE = [
14086
14476
  * Generated bundle index. Do not edit.
14087
14477
  */
14088
14478
 
14089
- export { ARROW_CORNER_GAP, BKTooltipDirective, BK_DEFAULT_DIALOG_CONFIG, BK_DIALOG_DATA, BK_DIALOG_GLOBAL_CONFIG, BK_TABLE, BkAvatar, BkAvatarGroup, BkAvatarUploader, BkBadge, BkBreadcrumb, BkButton, BkButtonGroup, BkCalendarManagerService, BkCheckbox, BkColumnFilterService, BkColumnSelect, BkCustomCalendar, BkDialogActions, BkDialogClose, BkDialogContent, BkDialogModule, BkDialogRef, BkDialogService, BkDialogTitle, BkDragHandle, BkDropdown, BkFileCard, BkFilePicker, BkGrid, BkHierarchicalSelect, BkIconButton, BkInput, BkInputChips, BkLoader, BkMenu, BkPagination, BkPill, BkPopover, BkRadioButton, BkScheduledDatePicker, BkSelect, BkSpinner, BkTable, BkTableDrag, BkTableFooter, BkTableSummary, BkTableTitle, BkTabs, BkTd, BkTextarea, BkTh, BkTimePicker, BkToastr, BkToastrService, BkToggle, BkTooltipInteractionService, BkTrExpand, BkTreeDrag, BkValidator, BkVirtualScroll, BrickclayIcons, BrickclayLib, CalendarModule, CalendarMonth, CalendarSelection, CalendarWeekday, ColumnFilterOption, DEFAULT_COUNTRY_OPTIONS, NEUTRAL_APPEARANCE, OPPOSITE_SIDE, POPOVER_PLACEMENTS, clamp, containsBkTreeNode, deriveAppearance, flattenBkTreeData, getDialogBackdropAnimation, getDialogPanelAnimation, joinPlacement, moveBkTreeNode, normalizeBkTableSize, parseColor, splitPlacement };
14479
+ export { ARROW_CORNER_GAP, BKTooltipDirective, BK_DEFAULT_DIALOG_CONFIG, BK_DIALOG_DATA, BK_DIALOG_GLOBAL_CONFIG, BK_TABLE, BkAvatar, BkAvatarGroup, BkAvatarUploader, BkBadge, BkBreadcrumb, BkButton, BkButtonGroup, BkCalendarManagerService, BkCheckbox, BkColumnFilterService, BkColumnSelect, BkCustomCalendar, BkDialogActions, BkDialogClose, BkDialogContent, BkDialogModule, BkDialogRef, BkDialogService, BkDialogTitle, BkDragHandle, BkDropdown, BkFileCard, BkFilePicker, BkGrid, BkHierarchicalSelect, BkIconButton, BkInput, BkInputChips, BkKanban, BkKanbanClickTarget, BkLoader, BkMenu, BkPagination, BkPill, BkPopover, BkRadioButton, BkScheduledDatePicker, BkSelect, BkSpinner, BkTable, BkTableDrag, BkTableFooter, BkTableSummary, BkTableTitle, BkTabs, BkTd, BkTextarea, BkTh, BkTimePicker, BkToastr, BkToastrService, BkToggle, BkTooltipInteractionService, BkTrExpand, BkTreeDrag, BkValidator, BkVirtualScroll, BrickclayIcons, BrickclayLib, CalendarModule, CalendarMonth, CalendarSelection, CalendarWeekday, ColumnFilterOption, DEFAULT_COUNTRY_OPTIONS, NEUTRAL_APPEARANCE, OPPOSITE_SIDE, POPOVER_PLACEMENTS, clamp, containsBkTreeNode, deriveAppearance, flattenBkTreeData, getDialogBackdropAnimation, getDialogPanelAnimation, joinPlacement, moveBkTreeNode, normalizeBkTableSize, parseColor, splitPlacement };
14090
14480
  //# sourceMappingURL=brickclay-org-ui.mjs.map