@brickclay-org/ui 0.0.65 → 0.0.66

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.
@@ -6742,65 +6742,113 @@ class BkColumnSelect {
6742
6742
  columnFilterService;
6743
6743
  searchable = false;
6744
6744
  cacheKey;
6745
- columns;
6745
+ columns = [];
6746
6746
  isOpened = false;
6747
- formBoxRef;
6748
- change = new EventEmitter();
6749
6747
  isOpenedChange = new EventEmitter();
6748
+ formBoxRef;
6749
+ /** Value bound via ngModel – only updated when user ticks/unticks a checkbox, never on search. */
6750
6750
  columnsFilterList = [];
6751
6751
  search = '';
6752
+ onChangeCallback = () => { };
6753
+ onTouchedCallback = () => { };
6752
6754
  constructor(columnFilterService) {
6753
6755
  this.columnFilterService = columnFilterService;
6754
6756
  }
6755
- ngOnInit() {
6756
- this.getColumnsFilterList();
6757
+ writeValue(value) {
6758
+ const isEmpty = !value || !Array.isArray(value) || value.length === 0;
6759
+ if (isEmpty && this.shouldLoadFromService()) {
6760
+ this.loadColumnsFilterListFromService();
6761
+ }
6762
+ else {
6763
+ this.columnsFilterList = Array.isArray(value) ? value : [];
6764
+ }
6757
6765
  }
6758
6766
  ngOnChanges(changes) {
6759
- if (changes['columns'] && !changes['columns'].firstChange) {
6760
- this.getColumnsFilterList();
6767
+ const columnsChanged = changes['columns'] && !changes['columns'].firstChange;
6768
+ const cacheKeyChanged = changes['cacheKey'] && !changes['cacheKey'].firstChange;
6769
+ if ((columnsChanged || cacheKeyChanged) && this.columnsFilterList.length === 0 && this.shouldLoadFromService()) {
6770
+ this.loadColumnsFilterListFromService();
6761
6771
  }
6762
6772
  }
6763
- getColumnsFilterList() {
6773
+ shouldLoadFromService() {
6774
+ return !!this.cacheKey && !!this.columns?.length;
6775
+ }
6776
+ loadColumnsFilterListFromService() {
6764
6777
  this.columnsFilterList = this.columnFilterService.getColumnsFilterList(this.cacheKey, this.columns);
6765
- this.change.emit(this.columnsFilterList);
6778
+ this.onChangeCallback(this.columnsFilterList);
6779
+ }
6780
+ registerOnChange(fn) {
6781
+ this.onChangeCallback = fn;
6782
+ }
6783
+ registerOnTouched(fn) {
6784
+ this.onTouchedCallback = fn;
6785
+ }
6786
+ setDisabledState(isDisabled) {
6787
+ // Optional: disable button/dropdown when control is disabled
6766
6788
  }
6767
6789
  filterButtonClicked(event) {
6768
6790
  event.stopPropagation();
6769
- this.isOpenedChange.emit(!this.isOpened);
6791
+ const willOpen = !this.isOpened;
6792
+ if (!willOpen) {
6793
+ this.clearSearch();
6794
+ this.onTouchedCallback();
6795
+ }
6796
+ this.isOpenedChange.emit(willOpen);
6770
6797
  }
6771
- onChangeColumnFilter(evt) {
6798
+ /** Called only on checkbox tick/untick – not on search. Emits via CVA so ngModel updates. */
6799
+ onChangeColumnFilter() {
6772
6800
  this.columnFilterService.updateColumnFilterList(this.cacheKey, this.columnsFilterList);
6773
- this.change.emit(this.columnsFilterList);
6801
+ this.onChangeCallback(this.columnsFilterList);
6802
+ this.onTouchedCallback();
6803
+ }
6804
+ clearSearch() {
6805
+ this.search = '';
6806
+ }
6807
+ closeDropdown() {
6808
+ this.clearSearch();
6809
+ this.onTouchedCallback();
6810
+ this.isOpened = false;
6811
+ this.isOpenedChange.emit(this.isOpened);
6774
6812
  }
6775
6813
  onClick(event) {
6776
- // Check if the click target is inside the form_box
6777
- if ((this.isOpened) &&
6778
- this.formBoxRef.nativeElement.contains(event.target)) {
6779
- return; // Do nothing if click occurred inside the form_box
6814
+ if (!this.isOpened) {
6815
+ return;
6816
+ }
6817
+ const formBox = this.formBoxRef?.nativeElement;
6818
+ if (formBox && formBox.contains(event.target)) {
6819
+ return;
6780
6820
  }
6781
- // Check if the click target is .ng-value-icon
6782
6821
  if (event.target instanceof HTMLElement &&
6783
6822
  event.target.classList.contains('ng-value-icon')) {
6784
- // Do nothing if click is on .ng-value-icon
6785
6823
  return;
6786
6824
  }
6787
- // Check if the click target is the button
6788
- if (!(event.target instanceof HTMLElement) ||
6789
- !event.target.closest('.btn-light-primary-custom')) {
6790
- // Close the popup if the click is not on the button
6791
- this.isOpened = false;
6792
- this.isOpenedChange.emit(this.isOpened);
6825
+ if (event.target instanceof HTMLElement &&
6826
+ event.target.closest('.btn-light-primary-custom')) {
6827
+ return;
6793
6828
  }
6829
+ this.closeDropdown();
6794
6830
  }
6795
6831
  get list() {
6796
6832
  return this.columnsFilterList.filter((x) => x.columnName.toLowerCase().includes(this.search.toLowerCase()));
6797
6833
  }
6798
6834
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkColumnSelect, deps: [{ token: BkColumnFilterService }], target: i0.ɵɵFactoryTarget.Component });
6799
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkColumnSelect, isStandalone: true, selector: "bk-column-select", inputs: { searchable: "searchable", cacheKey: "cacheKey", columns: "columns", isOpened: "isOpened" }, outputs: { change: "change", isOpenedChange: "isOpenedChange" }, host: { listeners: { "document:click": "onClick($event)" } }, viewQueries: [{ propertyName: "formBoxRef", first: true, predicate: ["formBox"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"relative\">\r\n\r\n <bk-button [size]=\"'xsm'\" [variant]=\"'secondary'\" [leftIcon]=\"'../../../../assets/icons/columns-black.svg'\"\r\n (click)=\"filterButtonClicked($event)\" [label]=\"'Columns'\" [buttonClass]=\"'!text-black'\"></bk-button>\r\n\r\n <!-- Dropdown Box -->\r\n @if(isOpened){\r\n\r\n <div #formBox\r\n class=\"absolute right-0 mt-2 w-[178px] bg-white border border-[#EFEFF1] rounded-xl shadow-xl p-3 pe-1 z-[9999]\">\r\n @if(searchable){\r\n <bk-input class=\"w-full\" [id]=\"'search-input-1'\" [name]=\"'search-input-1'\"\r\n [iconSrc]=\"'../../../../assets/icons/search-input.svg'\" type=\"text\" [(ngModel)]=\"search\"\r\n placeholder=\"Search\"></bk-input>\r\n }\r\n <div class=\"flex flex-col gap-0.5 max-h-[360px] overflow-y-auto\">\r\n @for (column of list; track $index;let i=$index) {\r\n <div class=\"flex items-center gap-2 px-3 py-2\">\r\n <bk-checkbox id=\"columnsFilterList-{{i}}\" checkboxClass=\"sm\" [(ngModel)]=\"column.selected\"\r\n (change)=\"onChangeColumnFilter($event)\">\r\n\r\n </bk-checkbox>\r\n\r\n\r\n\r\n <label class=\"text-xs cursor-pointer text-[#141414] select-none truncate font-medium\"\r\n for=\"columnsFilterList-{{i}}\">\r\n {{column.columnName}}\r\n </label>\r\n </div>\r\n }\r\n @if(!list.length){\r\n <p class=\"text-sm font-medium text-gray-500 mt-3 text-center\">No Records Found</p>\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: BkButton, selector: "bk-button", inputs: ["variant", "size", "label", "leftIcon", "rightIcon", "iconAlt", "type", "loading", "disabled", "buttonClass", "textClass", "spinnerClass"], outputs: ["clicked"] }, { kind: "component", type: BkCheckbox, selector: "bk-checkbox", inputs: ["checkboxClass", "label", "labelClass", "disabled"], outputs: ["change"] }, { kind: "component", type: BkInput, selector: "bk-input", inputs: ["id", "name", "mask", "autoComplete", "label", "placeholder", "hint", "required", "type", "value", "hasError", "showErrorIcon", "errorMessage", "disabled", "tabIndex", "readOnly", "autoCapitalize", "inputMode", "iconSrc", "iconAlt", "showIcon", "phone", "countryCode", "countryOptions", "iconOrientation", "password", "showPassword", "pattern", "max", "min", "step", "maxlength", "minlength"], outputs: ["input", "change", "focus", "blur", "clicked"] }] });
6835
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkColumnSelect, isStandalone: true, selector: "bk-column-select", inputs: { searchable: "searchable", cacheKey: "cacheKey", columns: "columns", isOpened: "isOpened" }, outputs: { isOpenedChange: "isOpenedChange" }, host: { listeners: { "document:click": "onClick($event)" } }, providers: [
6836
+ {
6837
+ provide: NG_VALUE_ACCESSOR,
6838
+ useExisting: forwardRef(() => BkColumnSelect),
6839
+ multi: true,
6840
+ },
6841
+ ], viewQueries: [{ propertyName: "formBoxRef", first: true, predicate: ["formBox"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"relative\">\r\n\r\n <bk-button [size]=\"'xsm'\" [variant]=\"'secondary'\" [leftIcon]=\"'../../../../assets/icons/columns-black.svg'\"\r\n (click)=\"filterButtonClicked($event)\" [label]=\"'Columns'\" [buttonClass]=\"'!text-black'\"></bk-button>\r\n\r\n <!-- Dropdown Box -->\r\n @if(isOpened){\r\n\r\n <div #formBox\r\n class=\"absolute right-0 mt-2 w-[178px] bg-white border border-[#EFEFF1] rounded-xl shadow-xl p-3 pe-1 z-[9999]\">\r\n @if(searchable){\r\n <bk-input [id]=\"'search-input-1'\" [name]=\"'search-input-1'\"\r\n [iconSrc]=\"'../../../../assets/icons/search-input.svg'\" type=\"text\" [(ngModel)]=\"search\"\r\n placeholder=\"Search\"></bk-input>\r\n }\r\n <div class=\"flex flex-col gap-0.5 max-h-[360px] overflow-y-auto\">\r\n @for (column of list; track column.columnName; let i = $index) {\r\n <div class=\"flex items-center gap-2 px-3 py-2\">\r\n <bk-checkbox id=\"columnsFilterList-{{column.columnName}}\" checkboxClass=\"sm\" [(ngModel)]=\"column.selected\"\r\n (change)=\"onChangeColumnFilter()\">\r\n\r\n </bk-checkbox>\r\n\r\n\r\n\r\n <label class=\"text-xs cursor-pointer text-[#141414] select-none truncate font-medium\"\r\n for=\"columnsFilterList-{{column.columnName}}\">\r\n {{column.columnName}}\r\n </label>\r\n </div>\r\n }\r\n @if(!list.length){\r\n <p class=\"column-select-option-empty\">No items found</p>\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n\r\n\r\n", styles: [".column-select-option-empty{@apply px-3 py-2 text-gray-400 cursor-default text-sm;}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: BkButton, selector: "bk-button", inputs: ["variant", "size", "label", "leftIcon", "rightIcon", "iconAlt", "type", "loading", "disabled", "buttonClass", "textClass", "spinnerClass"], outputs: ["clicked"] }, { kind: "component", type: BkCheckbox, selector: "bk-checkbox", inputs: ["checkboxClass", "label", "labelClass", "disabled"], outputs: ["change"] }, { kind: "component", type: BkInput, selector: "bk-input", inputs: ["id", "name", "mask", "autoComplete", "label", "placeholder", "hint", "required", "type", "value", "hasError", "showErrorIcon", "errorMessage", "disabled", "tabIndex", "readOnly", "autoCapitalize", "inputMode", "iconSrc", "iconAlt", "showIcon", "phone", "countryCode", "countryOptions", "iconOrientation", "password", "showPassword", "pattern", "max", "min", "step", "maxlength", "minlength"], outputs: ["input", "change", "focus", "blur", "clicked"] }] });
6800
6842
  }
6801
6843
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkColumnSelect, decorators: [{
6802
6844
  type: Component,
6803
- args: [{ selector: 'bk-column-select', imports: [FormsModule, BkButton, BkCheckbox, BkInput], standalone: true, template: "<div class=\"relative\">\r\n\r\n <bk-button [size]=\"'xsm'\" [variant]=\"'secondary'\" [leftIcon]=\"'../../../../assets/icons/columns-black.svg'\"\r\n (click)=\"filterButtonClicked($event)\" [label]=\"'Columns'\" [buttonClass]=\"'!text-black'\"></bk-button>\r\n\r\n <!-- Dropdown Box -->\r\n @if(isOpened){\r\n\r\n <div #formBox\r\n class=\"absolute right-0 mt-2 w-[178px] bg-white border border-[#EFEFF1] rounded-xl shadow-xl p-3 pe-1 z-[9999]\">\r\n @if(searchable){\r\n <bk-input class=\"w-full\" [id]=\"'search-input-1'\" [name]=\"'search-input-1'\"\r\n [iconSrc]=\"'../../../../assets/icons/search-input.svg'\" type=\"text\" [(ngModel)]=\"search\"\r\n placeholder=\"Search\"></bk-input>\r\n }\r\n <div class=\"flex flex-col gap-0.5 max-h-[360px] overflow-y-auto\">\r\n @for (column of list; track $index;let i=$index) {\r\n <div class=\"flex items-center gap-2 px-3 py-2\">\r\n <bk-checkbox id=\"columnsFilterList-{{i}}\" checkboxClass=\"sm\" [(ngModel)]=\"column.selected\"\r\n (change)=\"onChangeColumnFilter($event)\">\r\n\r\n </bk-checkbox>\r\n\r\n\r\n\r\n <label class=\"text-xs cursor-pointer text-[#141414] select-none truncate font-medium\"\r\n for=\"columnsFilterList-{{i}}\">\r\n {{column.columnName}}\r\n </label>\r\n </div>\r\n }\r\n @if(!list.length){\r\n <p class=\"text-sm font-medium text-gray-500 mt-3 text-center\">No Records Found</p>\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n" }]
6845
+ args: [{ selector: 'bk-column-select', imports: [FormsModule, BkButton, BkCheckbox, BkInput], standalone: true, providers: [
6846
+ {
6847
+ provide: NG_VALUE_ACCESSOR,
6848
+ useExisting: forwardRef(() => BkColumnSelect),
6849
+ multi: true,
6850
+ },
6851
+ ], template: "<div class=\"relative\">\r\n\r\n <bk-button [size]=\"'xsm'\" [variant]=\"'secondary'\" [leftIcon]=\"'../../../../assets/icons/columns-black.svg'\"\r\n (click)=\"filterButtonClicked($event)\" [label]=\"'Columns'\" [buttonClass]=\"'!text-black'\"></bk-button>\r\n\r\n <!-- Dropdown Box -->\r\n @if(isOpened){\r\n\r\n <div #formBox\r\n class=\"absolute right-0 mt-2 w-[178px] bg-white border border-[#EFEFF1] rounded-xl shadow-xl p-3 pe-1 z-[9999]\">\r\n @if(searchable){\r\n <bk-input [id]=\"'search-input-1'\" [name]=\"'search-input-1'\"\r\n [iconSrc]=\"'../../../../assets/icons/search-input.svg'\" type=\"text\" [(ngModel)]=\"search\"\r\n placeholder=\"Search\"></bk-input>\r\n }\r\n <div class=\"flex flex-col gap-0.5 max-h-[360px] overflow-y-auto\">\r\n @for (column of list; track column.columnName; let i = $index) {\r\n <div class=\"flex items-center gap-2 px-3 py-2\">\r\n <bk-checkbox id=\"columnsFilterList-{{column.columnName}}\" checkboxClass=\"sm\" [(ngModel)]=\"column.selected\"\r\n (change)=\"onChangeColumnFilter()\">\r\n\r\n </bk-checkbox>\r\n\r\n\r\n\r\n <label class=\"text-xs cursor-pointer text-[#141414] select-none truncate font-medium\"\r\n for=\"columnsFilterList-{{column.columnName}}\">\r\n {{column.columnName}}\r\n </label>\r\n </div>\r\n }\r\n @if(!list.length){\r\n <p class=\"column-select-option-empty\">No items found</p>\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n\r\n\r\n", styles: [".column-select-option-empty{@apply px-3 py-2 text-gray-400 cursor-default text-sm;}\n"] }]
6804
6852
  }], ctorParameters: () => [{ type: BkColumnFilterService }], propDecorators: { searchable: [{
6805
6853
  type: Input
6806
6854
  }], cacheKey: [{
@@ -6809,13 +6857,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
6809
6857
  type: Input
6810
6858
  }], isOpened: [{
6811
6859
  type: Input
6860
+ }], isOpenedChange: [{
6861
+ type: Output
6812
6862
  }], formBoxRef: [{
6813
6863
  type: ViewChild,
6814
6864
  args: ['formBox']
6815
- }], change: [{
6816
- type: Output
6817
- }], isOpenedChange: [{
6818
- type: Output
6819
6865
  }], onClick: [{
6820
6866
  type: HostListener,
6821
6867
  args: ['document:click', ['$event']]