@acorex-platform/extension-source-control-core-client 0.0.30 → 0.0.33

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.
@@ -1,19 +1,19 @@
1
- import * as i6$1 from '@angular/common';
1
+ import * as i6 from '@angular/common';
2
2
  import { AsyncPipe, CommonModule } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
4
  import { inject, Injectable, input, signal, computed, effect, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
5
- import * as i2 from '@acorex/components/badge';
5
+ import * as i1 from '@acorex/components/badge';
6
6
  import { AXBadgeModule } from '@acorex/components/badge';
7
- import * as i3 from '@acorex/components/button';
7
+ import * as i2 from '@acorex/components/button';
8
8
  import { AXButtonModule } from '@acorex/components/button';
9
- import * as i4 from '@acorex/components/decorators';
9
+ import * as i3 from '@acorex/components/decorators';
10
10
  import { AXDecoratorModule } from '@acorex/components/decorators';
11
11
  import { AXDialogService } from '@acorex/components/dialog';
12
- import * as i5 from '@acorex/components/loading';
12
+ import * as i4 from '@acorex/components/loading';
13
13
  import { AXLoadingModule } from '@acorex/components/loading';
14
14
  import * as i5$1 from '@acorex/components/search-box';
15
15
  import { AXSearchBoxModule } from '@acorex/components/search-box';
16
- import * as i7 from '@acorex/core/translation';
16
+ import * as i5 from '@acorex/core/translation';
17
17
  import { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';
18
18
  import { AXPPageLayoutBaseComponent, AXPPageLayoutBase } from '@acorex-platform/framework-client/layout/views';
19
19
  import { AXE_SC_PROVIDER_GITHUB, AXE_SC_PROVIDER_GITLAB, AXE_SC_PROVIDER_IDS, RootConfig, AXESourceControlHookKeys } from '@acorex-platform/extension-source-control-core-client/contracts';
@@ -24,10 +24,8 @@ import { AXPQueryService, AXPCommandExecutor } from '@acorex-platform/framework-
24
24
  import { runtimeQueryPayloadData, AXPRegionalSetting } from '@acorex-platform/framework-shared/core';
25
25
  import { AXEGithubQueryKeys } from '@acorex-platform/extension-github-client/contracts';
26
26
  import { AXEGitLabQueryKeys } from '@acorex-platform/extension-gitlab-client/contracts';
27
- import * as i1 from '@angular/forms';
28
27
  import { FormsModule } from '@angular/forms';
29
- import * as i6 from '@acorex/components/select-box';
30
- import { AXSelectBoxModule } from '@acorex/components/select-box';
28
+ import { AXComboBoxComponent } from '@acorex/components/combo-box';
31
29
  import { AXPSettingsService } from '@acorex-platform/framework-client/common';
32
30
  import { AXPStateMessageComponent } from '@acorex-platform/framework-client/layout/components';
33
31
  import { AXFormatService } from '@acorex/core/format';
@@ -301,8 +299,9 @@ class AXERepositoryCommitsPanelComponent {
301
299
  }, /* @ts-ignore */
302
300
  ...(ngDevMode ? [{ debugName: "baseBranch" }] : /* istanbul ignore next */ []));
303
301
  this.branchOptions = computed(() => this.branches().map((branch) => ({
304
- name: branch.name,
305
- title: branch.name,
302
+ id: branch.name,
303
+ text: branch.name,
304
+ value: branch.name,
306
305
  })), /* @ts-ignore */
307
306
  ...(ngDevMode ? [{ debugName: "branchOptions" }] : /* istanbul ignore next */ []));
308
307
  effect(() => {
@@ -329,6 +328,10 @@ class AXERepositoryCommitsPanelComponent {
329
328
  }
330
329
  //#endregion
331
330
  //#region ----- Event Handlers -----
331
+ onBranchComboChange(event) {
332
+ const value = event.value;
333
+ this.onBranchChange(typeof value === 'string' ? value : null);
334
+ }
332
335
  onBranchChange(branch) {
333
336
  this.selectedBranch.set(trim(branch ?? ''));
334
337
  }
@@ -452,7 +455,7 @@ class AXERepositoryCommitsPanelComponent {
452
455
  console.error(message, error);
453
456
  }
454
457
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXERepositoryCommitsPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
455
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXERepositoryCommitsPanelComponent, isStandalone: true, selector: "axe-repository-commits-panel", inputs: { projectId: { classPropertyName: "projectId", publicName: "projectId", isSignal: true, isRequired: true, transformFunction: null }, link: { classPropertyName: "link", publicName: "link", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<section class=\"flex flex-col gap-4 rounded-lg border border-surface bg-lighter-surface p-4\">\n\n <div class=\"flex flex-wrap items-start justify-between gap-3\">\n\n <div>\n\n <div class=\"font-medium\">{{ (i18n + '.title' | translate | async) ?? '' }}</div>\n\n <div class=\"text-sm opacity-70\">{{ (i18n + '.description' | translate | async) ?? '' }}</div>\n\n </div>\n\n <!-- ----- Branch filter ----- -->\n\n @if (branchOptions().length) {\n\n <ax-select-box\n\n class=\"min-w-[12rem]\"\n\n [dataSource]=\"branchOptions()\"\n\n [ngModel]=\"selectedBranch()\"\n\n (ngModelChange)=\"onBranchChange($event)\"\n\n valueField=\"name\"\n\n textField=\"title\"\n\n [placeholder]=\"(i18n + '.branch.placeholder' | translate | async) ?? ''\"\n\n ></ax-select-box>\n\n }\n\n </div>\n\n\n\n <!-- ----- Branch-level hook actions ----- -->\n\n @if (branchActions().length) {\n\n <div class=\"flex flex-wrap gap-2\">\n\n @for (action of branchActions(); track action.name ?? action.title) {\n\n <ax-button\n\n look=\"outline\"\n\n color=\"primary\"\n\n size=\"sm\"\n\n [text]=\"(actionTextKey(action) | translate | async) ?? ''\"\n\n (onClick)=\"onActionClick(action)\"\n\n >\n\n @if (action.icon) {\n\n <ax-prefix>\n\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n\n </ax-prefix>\n\n }\n\n </ax-button>\n\n }\n\n </div>\n\n }\n\n\n\n <!-- ----- Commits loading indicator ----- -->\n\n @if (loading()) {\n\n <ax-loading></ax-loading>\n\n }\n\n <!-- ----- Empty commits state ----- -->\n\n @else if (!commits().length) {\n\n <axp-state-message\n\n icon=\"fa-light fa-code-commit\"\n\n [title]=\"i18n + '.empty.title'\"\n\n [description]=\"i18n + '.empty.description'\"\n\n look=\"minimal\"\n\n ></axp-state-message>\n\n }\n\n <!-- ----- Commits list ----- -->\n\n @else {\n\n <div class=\"flex flex-col gap-2\">\n\n @for (commit of commits(); track commit.sha) {\n\n <article class=\"flex flex-wrap items-start justify-between gap-3 rounded-lg border border-surface bg-surface p-3\">\n\n <div class=\"min-w-0 flex-1\">\n\n <div class=\"flex flex-wrap items-center gap-2\">\n\n <ax-badge\n\n size=\"sm\"\n\n look=\"twotone\"\n\n color=\"primary\"\n\n [text]=\"commit.shortSha ?? commit.sha.slice(0, 7)\"\n\n ></ax-badge>\n\n <span class=\"font-medium\">{{ commitMessage(commit) }}</span>\n\n </div>\n\n <div class=\"mt-1 flex flex-wrap gap-x-4 gap-y-1 text-sm opacity-70\">\n\n <span>{{ commit.authorName }}</span>\n\n <span>{{ formatCommittedAt(commit.committedAt) }}</span>\n\n </div>\n\n </div>\n\n <div class=\"flex shrink-0 flex-wrap items-center gap-2\">\n\n <ax-button\n\n look=\"blank\"\n\n size=\"sm\"\n\n [text]=\"(i18n + '.actions.view' | translate | async) ?? ''\"\n\n (onClick)=\"onViewCommit(commit)\"\n\n >\n\n <ax-prefix>\n\n <ax-icon icon=\"fa-light fa-arrow-up-right-from-square\"></ax-icon>\n\n </ax-prefix>\n\n </ax-button>\n\n <!-- ----- Commit-level hook actions ----- -->\n\n @for (action of commitActions(commit.sha); track action.name ?? action.title) {\n\n <ax-button\n\n look=\"outline\"\n\n size=\"sm\"\n\n color=\"primary\"\n\n [text]=\"(actionTextKey(action) | translate | async) ?? ''\"\n\n (onClick)=\"onActionClick(action)\"\n\n >\n\n @if (action.icon) {\n\n <ax-prefix>\n\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n\n </ax-prefix>\n\n }\n\n </ax-button>\n\n }\n\n </div>\n\n </article>\n\n }\n\n </div>\n\n }\n\n</section>\n\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i2.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i4.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i4.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i5.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "component", type: i6.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "itemHeight", "maxVisibleItems", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i7.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
458
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXERepositoryCommitsPanelComponent, isStandalone: true, selector: "axe-repository-commits-panel", inputs: { projectId: { classPropertyName: "projectId", publicName: "projectId", isSignal: true, isRequired: true, transformFunction: null }, link: { classPropertyName: "link", publicName: "link", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<section class=\"flex flex-col gap-4 rounded-lg border border-surface bg-lighter-surface p-4\">\n\n <div class=\"flex flex-wrap items-start justify-between gap-3\">\n\n <div>\n\n <div class=\"font-medium\">{{ (i18n + '.title' | translate | async) ?? '' }}</div>\n\n <div class=\"text-sm opacity-70\">{{ (i18n + '.description' | translate | async) ?? '' }}</div>\n\n </div>\n\n <!-- ----- Branch filter ----- -->\n\n @if (branchOptions().length) {\n\n <ax-combo-box\n\n class=\"min-w-[12rem]\"\n\n [items]=\"branchOptions()\"\n\n [searchable]=\"false\"\n\n [value]=\"selectedBranch()\"\n\n (onValueChanged)=\"onBranchComboChange($event)\"\n\n [placeholder]=\"(i18n + '.branch.placeholder' | translate | async) ?? ''\"\n\n ></ax-combo-box>\n\n }\n\n </div>\n\n\n\n <!-- ----- Branch-level hook actions ----- -->\n\n @if (branchActions().length) {\n\n <div class=\"flex flex-wrap gap-2\">\n\n @for (action of branchActions(); track action.name ?? action.title) {\n\n <ax-button\n\n look=\"outline\"\n\n color=\"primary\"\n\n size=\"sm\"\n\n [text]=\"(actionTextKey(action) | translate | async) ?? ''\"\n\n (onClick)=\"onActionClick(action)\"\n\n >\n\n @if (action.icon) {\n\n <ax-prefix>\n\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n\n </ax-prefix>\n\n }\n\n </ax-button>\n\n }\n\n </div>\n\n }\n\n\n\n <!-- ----- Commits loading indicator ----- -->\n\n @if (loading()) {\n\n <ax-loading></ax-loading>\n\n }\n\n <!-- ----- Empty commits state ----- -->\n\n @else if (!commits().length) {\n\n <axp-state-message\n\n icon=\"fa-light fa-code-commit\"\n\n [title]=\"i18n + '.empty.title'\"\n\n [description]=\"i18n + '.empty.description'\"\n\n look=\"minimal\"\n\n ></axp-state-message>\n\n }\n\n <!-- ----- Commits list ----- -->\n\n @else {\n\n <div class=\"flex flex-col gap-2\">\n\n @for (commit of commits(); track commit.sha) {\n\n <article class=\"flex flex-wrap items-start justify-between gap-3 rounded-lg border border-surface bg-surface p-3\">\n\n <div class=\"min-w-0 flex-1\">\n\n <div class=\"flex flex-wrap items-center gap-2\">\n\n <ax-badge\n\n size=\"sm\"\n\n look=\"twotone\"\n\n color=\"primary\"\n\n [text]=\"commit.shortSha ?? commit.sha.slice(0, 7)\"\n\n ></ax-badge>\n\n <span class=\"font-medium\">{{ commitMessage(commit) }}</span>\n\n </div>\n\n <div class=\"mt-1 flex flex-wrap gap-x-4 gap-y-1 text-sm opacity-70\">\n\n <span>{{ commit.authorName }}</span>\n\n <span>{{ formatCommittedAt(commit.committedAt) }}</span>\n\n </div>\n\n </div>\n\n <div class=\"flex shrink-0 flex-wrap items-center gap-2\">\n\n <ax-button\n\n look=\"blank\"\n\n size=\"sm\"\n\n [text]=\"(i18n + '.actions.view' | translate | async) ?? ''\"\n\n (onClick)=\"onViewCommit(commit)\"\n\n >\n\n <ax-prefix>\n\n <ax-icon icon=\"fa-light fa-arrow-up-right-from-square\"></ax-icon>\n\n </ax-prefix>\n\n </ax-button>\n\n <!-- ----- Commit-level hook actions ----- -->\n\n @for (action of commitActions(commit.sha); track action.name ?? action.title) {\n\n <ax-button\n\n look=\"outline\"\n\n size=\"sm\"\n\n color=\"primary\"\n\n [text]=\"(actionTextKey(action) | translate | async) ?? ''\"\n\n (onClick)=\"onActionClick(action)\"\n\n >\n\n @if (action.icon) {\n\n <ax-prefix>\n\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n\n </ax-prefix>\n\n }\n\n </ax-button>\n\n }\n\n </div>\n\n </article>\n\n }\n\n </div>\n\n }\n\n</section>\n\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i4.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "component", type: AXComboBoxComponent, selector: "ax-combo-box", inputs: ["name", "items", "searchable", "multiple", "adaptivityEnabled", "caption", "alternate", "placeholder", "searchPlaceholder", "emptyTemplate", "itemTemplate", "selectedTemplate", "disabled", "readonly", "look", "value"], outputs: ["lookChange", "valueChange", "onValueChanged", "onFocus", "onBlur", "onItemClick", "onItemSelected", "onOpened", "onClosed"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
456
459
  }
457
460
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXERepositoryCommitsPanelComponent, decorators: [{
458
461
  type: Component,
@@ -463,10 +466,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
463
466
  AXButtonModule,
464
467
  AXDecoratorModule,
465
468
  AXLoadingModule,
466
- AXSelectBoxModule,
469
+ AXComboBoxComponent,
467
470
  AXTranslationModule,
468
471
  AXPStateMessageComponent,
469
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<section class=\"flex flex-col gap-4 rounded-lg border border-surface bg-lighter-surface p-4\">\n\n <div class=\"flex flex-wrap items-start justify-between gap-3\">\n\n <div>\n\n <div class=\"font-medium\">{{ (i18n + '.title' | translate | async) ?? '' }}</div>\n\n <div class=\"text-sm opacity-70\">{{ (i18n + '.description' | translate | async) ?? '' }}</div>\n\n </div>\n\n <!-- ----- Branch filter ----- -->\n\n @if (branchOptions().length) {\n\n <ax-select-box\n\n class=\"min-w-[12rem]\"\n\n [dataSource]=\"branchOptions()\"\n\n [ngModel]=\"selectedBranch()\"\n\n (ngModelChange)=\"onBranchChange($event)\"\n\n valueField=\"name\"\n\n textField=\"title\"\n\n [placeholder]=\"(i18n + '.branch.placeholder' | translate | async) ?? ''\"\n\n ></ax-select-box>\n\n }\n\n </div>\n\n\n\n <!-- ----- Branch-level hook actions ----- -->\n\n @if (branchActions().length) {\n\n <div class=\"flex flex-wrap gap-2\">\n\n @for (action of branchActions(); track action.name ?? action.title) {\n\n <ax-button\n\n look=\"outline\"\n\n color=\"primary\"\n\n size=\"sm\"\n\n [text]=\"(actionTextKey(action) | translate | async) ?? ''\"\n\n (onClick)=\"onActionClick(action)\"\n\n >\n\n @if (action.icon) {\n\n <ax-prefix>\n\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n\n </ax-prefix>\n\n }\n\n </ax-button>\n\n }\n\n </div>\n\n }\n\n\n\n <!-- ----- Commits loading indicator ----- -->\n\n @if (loading()) {\n\n <ax-loading></ax-loading>\n\n }\n\n <!-- ----- Empty commits state ----- -->\n\n @else if (!commits().length) {\n\n <axp-state-message\n\n icon=\"fa-light fa-code-commit\"\n\n [title]=\"i18n + '.empty.title'\"\n\n [description]=\"i18n + '.empty.description'\"\n\n look=\"minimal\"\n\n ></axp-state-message>\n\n }\n\n <!-- ----- Commits list ----- -->\n\n @else {\n\n <div class=\"flex flex-col gap-2\">\n\n @for (commit of commits(); track commit.sha) {\n\n <article class=\"flex flex-wrap items-start justify-between gap-3 rounded-lg border border-surface bg-surface p-3\">\n\n <div class=\"min-w-0 flex-1\">\n\n <div class=\"flex flex-wrap items-center gap-2\">\n\n <ax-badge\n\n size=\"sm\"\n\n look=\"twotone\"\n\n color=\"primary\"\n\n [text]=\"commit.shortSha ?? commit.sha.slice(0, 7)\"\n\n ></ax-badge>\n\n <span class=\"font-medium\">{{ commitMessage(commit) }}</span>\n\n </div>\n\n <div class=\"mt-1 flex flex-wrap gap-x-4 gap-y-1 text-sm opacity-70\">\n\n <span>{{ commit.authorName }}</span>\n\n <span>{{ formatCommittedAt(commit.committedAt) }}</span>\n\n </div>\n\n </div>\n\n <div class=\"flex shrink-0 flex-wrap items-center gap-2\">\n\n <ax-button\n\n look=\"blank\"\n\n size=\"sm\"\n\n [text]=\"(i18n + '.actions.view' | translate | async) ?? ''\"\n\n (onClick)=\"onViewCommit(commit)\"\n\n >\n\n <ax-prefix>\n\n <ax-icon icon=\"fa-light fa-arrow-up-right-from-square\"></ax-icon>\n\n </ax-prefix>\n\n </ax-button>\n\n <!-- ----- Commit-level hook actions ----- -->\n\n @for (action of commitActions(commit.sha); track action.name ?? action.title) {\n\n <ax-button\n\n look=\"outline\"\n\n size=\"sm\"\n\n color=\"primary\"\n\n [text]=\"(actionTextKey(action) | translate | async) ?? ''\"\n\n (onClick)=\"onActionClick(action)\"\n\n >\n\n @if (action.icon) {\n\n <ax-prefix>\n\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n\n </ax-prefix>\n\n }\n\n </ax-button>\n\n }\n\n </div>\n\n </article>\n\n }\n\n </div>\n\n }\n\n</section>\n\n" }]
472
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<section class=\"flex flex-col gap-4 rounded-lg border border-surface bg-lighter-surface p-4\">\n\n <div class=\"flex flex-wrap items-start justify-between gap-3\">\n\n <div>\n\n <div class=\"font-medium\">{{ (i18n + '.title' | translate | async) ?? '' }}</div>\n\n <div class=\"text-sm opacity-70\">{{ (i18n + '.description' | translate | async) ?? '' }}</div>\n\n </div>\n\n <!-- ----- Branch filter ----- -->\n\n @if (branchOptions().length) {\n\n <ax-combo-box\n\n class=\"min-w-[12rem]\"\n\n [items]=\"branchOptions()\"\n\n [searchable]=\"false\"\n\n [value]=\"selectedBranch()\"\n\n (onValueChanged)=\"onBranchComboChange($event)\"\n\n [placeholder]=\"(i18n + '.branch.placeholder' | translate | async) ?? ''\"\n\n ></ax-combo-box>\n\n }\n\n </div>\n\n\n\n <!-- ----- Branch-level hook actions ----- -->\n\n @if (branchActions().length) {\n\n <div class=\"flex flex-wrap gap-2\">\n\n @for (action of branchActions(); track action.name ?? action.title) {\n\n <ax-button\n\n look=\"outline\"\n\n color=\"primary\"\n\n size=\"sm\"\n\n [text]=\"(actionTextKey(action) | translate | async) ?? ''\"\n\n (onClick)=\"onActionClick(action)\"\n\n >\n\n @if (action.icon) {\n\n <ax-prefix>\n\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n\n </ax-prefix>\n\n }\n\n </ax-button>\n\n }\n\n </div>\n\n }\n\n\n\n <!-- ----- Commits loading indicator ----- -->\n\n @if (loading()) {\n\n <ax-loading></ax-loading>\n\n }\n\n <!-- ----- Empty commits state ----- -->\n\n @else if (!commits().length) {\n\n <axp-state-message\n\n icon=\"fa-light fa-code-commit\"\n\n [title]=\"i18n + '.empty.title'\"\n\n [description]=\"i18n + '.empty.description'\"\n\n look=\"minimal\"\n\n ></axp-state-message>\n\n }\n\n <!-- ----- Commits list ----- -->\n\n @else {\n\n <div class=\"flex flex-col gap-2\">\n\n @for (commit of commits(); track commit.sha) {\n\n <article class=\"flex flex-wrap items-start justify-between gap-3 rounded-lg border border-surface bg-surface p-3\">\n\n <div class=\"min-w-0 flex-1\">\n\n <div class=\"flex flex-wrap items-center gap-2\">\n\n <ax-badge\n\n size=\"sm\"\n\n look=\"twotone\"\n\n color=\"primary\"\n\n [text]=\"commit.shortSha ?? commit.sha.slice(0, 7)\"\n\n ></ax-badge>\n\n <span class=\"font-medium\">{{ commitMessage(commit) }}</span>\n\n </div>\n\n <div class=\"mt-1 flex flex-wrap gap-x-4 gap-y-1 text-sm opacity-70\">\n\n <span>{{ commit.authorName }}</span>\n\n <span>{{ formatCommittedAt(commit.committedAt) }}</span>\n\n </div>\n\n </div>\n\n <div class=\"flex shrink-0 flex-wrap items-center gap-2\">\n\n <ax-button\n\n look=\"blank\"\n\n size=\"sm\"\n\n [text]=\"(i18n + '.actions.view' | translate | async) ?? ''\"\n\n (onClick)=\"onViewCommit(commit)\"\n\n >\n\n <ax-prefix>\n\n <ax-icon icon=\"fa-light fa-arrow-up-right-from-square\"></ax-icon>\n\n </ax-prefix>\n\n </ax-button>\n\n <!-- ----- Commit-level hook actions ----- -->\n\n @for (action of commitActions(commit.sha); track action.name ?? action.title) {\n\n <ax-button\n\n look=\"outline\"\n\n size=\"sm\"\n\n color=\"primary\"\n\n [text]=\"(actionTextKey(action) | translate | async) ?? ''\"\n\n (onClick)=\"onActionClick(action)\"\n\n >\n\n @if (action.icon) {\n\n <ax-prefix>\n\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n\n </ax-prefix>\n\n }\n\n </ax-button>\n\n }\n\n </div>\n\n </article>\n\n }\n\n </div>\n\n }\n\n</section>\n\n" }]
470
473
  }], ctorParameters: () => [], propDecorators: { projectId: [{ type: i0.Input, args: [{ isSignal: true, alias: "projectId", required: true }] }], link: [{ type: i0.Input, args: [{ isSignal: true, alias: "link", required: true }] }] } });
471
474
 
472
475
  //#region ----- Imports -----
@@ -724,7 +727,7 @@ class AXESourceControlPageComponent extends AXPPageLayoutBaseComponent {
724
727
  provide: AXPPageLayoutBase,
725
728
  useExisting: AXESourceControlPageComponent,
726
729
  },
727
- ], usesInheritance: true, ngImport: i0, template: "<div class=\"flex w-full flex-col gap-4\">\n <!-- ----- Loading indicator while page data is fetched ----- -->\n @if (loading()) {\n <ax-loading></ax-loading>\n }\n <!-- ----- Linked repository summary ----- -->\n @else if (linkedRepository(); as link) {\n <section class=\"flex flex-col gap-4 rounded-lg border border-surface bg-lighter-surface p-4\">\n <div class=\"flex flex-wrap items-start justify-between gap-3\">\n <div class=\"min-w-0\">\n <div class=\"text-sm opacity-70\">\n {{ (i18n + '.linked.summary' | translate | async) ?? '' }}\n </div>\n <div class=\"mt-1 text-lg font-medium\">{{ link.fullName }}</div>\n </div>\n <ax-badge\n size=\"sm\"\n look=\"twotone\"\n color=\"success\"\n [text]=\"(i18n + '.linked.badge' | translate | async) ?? ''\"\n ></ax-badge>\n </div>\n\n <div class=\"grid gap-3 md:grid-cols-2\">\n <div>\n <div class=\"text-sm opacity-70\">{{ (i18n + '.fields.provider' | translate | async) ?? '' }}</div>\n <div class=\"font-medium\">{{ link.providerId }}</div>\n </div>\n <!-- ----- Default branch when configured ----- -->\n @if (link.defaultBranch) {\n <div>\n <div class=\"text-sm opacity-70\">{{ (i18n + '.fields.default-branch' | translate | async) ?? '' }}</div>\n <div class=\"font-medium\">{{ link.defaultBranch }}</div>\n </div>\n }\n <div class=\"md:col-span-2\">\n <div class=\"text-sm opacity-70\">{{ (i18n + '.fields.web-url' | translate | async) ?? '' }}</div>\n <a class=\"font-medium text-primary hover:underline\" [href]=\"link.webUrl\" target=\"_blank\" rel=\"noopener noreferrer\">\n {{ link.webUrl }}\n </a>\n </div>\n </div>\n\n <div class=\"flex flex-wrap gap-2\">\n <ax-button\n look=\"outline\"\n color=\"primary\"\n [disabled]=\"linking()\"\n [text]=\"(i18n + '.actions.change' | translate | async) ?? ''\"\n (onClick)=\"onChangeRepository()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-arrow-right-arrow-left\"></ax-icon>\n </ax-prefix>\n </ax-button>\n <ax-button\n look=\"outline\"\n color=\"danger\"\n [disabled]=\"linking()\"\n [text]=\"(i18n + '.actions.unlink' | translate | async) ?? ''\"\n (onClick)=\"onUnlinkRepository()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-link-slash\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n </section>\n\n <axe-repository-commits-panel [projectId]=\"projectId()\" [link]=\"link\"></axe-repository-commits-panel>\n }\n <!-- ----- No provider connection configured ----- -->\n @else if (!hasConnections()) {\n <section class=\"rounded-lg border border-dashed border-surface bg-lighter-surface p-6 text-center\">\n <ax-icon class=\"mb-3 text-3xl opacity-60\">\n <i class=\"fa-light fa-plug-circle-xmark\"></i>\n </ax-icon>\n <div class=\"font-medium\">{{ (i18n + '.empty.no-connection.title' | translate | async) ?? '' }}</div>\n <div class=\"mt-2 text-sm opacity-70\">{{ (i18n + '.empty.no-connection.description' | translate | async) ?? '' }}</div>\n </section>\n }\n <!-- ----- Provider selection step ----- -->\n @else if (step() === 'provider') {\n <section class=\"flex flex-col gap-3\">\n <div class=\"flex flex-wrap items-start justify-between gap-3\">\n <div>\n <div class=\"font-medium\">{{ (i18n + '.steps.provider.title' | translate | async) ?? '' }}</div>\n <div class=\"text-sm opacity-70\">{{ (i18n + '.steps.provider.description' | translate | async) ?? '' }}</div>\n </div>\n <!-- ----- Cancel change when a repository is already linked ----- -->\n @if (selectingNewLink()) {\n <ax-button\n look=\"blank\"\n size=\"sm\"\n [disabled]=\"linking()\"\n [text]=\"(i18n + '.actions.back' | translate | async) ?? ''\"\n (onClick)=\"onCancelChange()\"\n ></ax-button>\n }\n </div>\n\n <div class=\"grid gap-3 md:grid-cols-2\">\n @for (connection of connections(); track connection.id) {\n <button\n type=\"button\"\n class=\"flex items-start gap-3 rounded-lg border border-surface bg-lighter-surface p-4 text-start transition hover:border-primary hover:shadow-sm\"\n [disabled]=\"linking()\"\n (click)=\"onSelectConnection(connection)\"\n >\n <ax-icon class=\"mt-0.5 text-2xl\">\n <i [class]=\"providerIcon(connection)\"></i>\n </ax-icon>\n <div class=\"min-w-0 flex-1\">\n <div class=\"font-medium\">\n @if (providerTitle(connection).startsWith('@')) {\n {{ providerTitle(connection) | translate | async }}\n }\n <!-- ----- Fallback when provider title is a plain display name ----- -->\n @else {\n {{ providerTitle(connection) }}\n }\n </div>\n <div class=\"mt-1 truncate text-sm opacity-70\">\n {{ connection.displayName || connection.providerId }}\n </div>\n </div>\n <ax-icon class=\"opacity-50\">\n <i class=\"fa-light fa-chevron-right\"></i>\n </ax-icon>\n </button>\n }\n </div>\n </section>\n }\n <!-- ----- Repository search and selection step ----- -->\n @else {\n <section class=\"flex flex-col gap-4\">\n <div class=\"flex flex-wrap items-center justify-between gap-3\">\n <div class=\"flex min-w-0 items-center gap-3\">\n <ax-button\n look=\"blank\"\n size=\"sm\"\n [disabled]=\"linking()\"\n [text]=\"(i18n + '.actions.back' | translate | async) ?? ''\"\n (onClick)=\"onBackToProviders()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-arrow-left\"></ax-icon>\n </ax-prefix>\n </ax-button>\n <div class=\"min-w-0\">\n <div class=\"font-medium\">{{ (i18n + '.steps.repositories.title' | translate | async) ?? '' }}</div>\n @if (selectedConnection(); as connection) {\n <div class=\"truncate text-sm opacity-70\">\n @if (providerTitle(connection).startsWith('@')) {\n {{ providerTitle(connection) | translate | async }}\n }\n <!-- ----- Fallback when provider title is a plain display name ----- -->\n @else {\n {{ providerTitle(connection) }}\n }\n \u00B7 {{ connection.displayName || connection.providerId }}\n </div>\n }\n </div>\n </div>\n </div>\n\n <ax-search-box\n [value]=\"searchQuery()\"\n [disabled]=\"linking()\"\n (valueChange)=\"onSearchChange($event)\"\n [placeholder]=\"(i18n + '.steps.repositories.search-placeholder' | translate | async) ?? ''\"\n ></ax-search-box>\n\n <!-- ----- Repository list loading indicator ----- -->\n @if (reposLoading()) {\n <ax-loading></ax-loading>\n }\n <!-- ----- Empty repository search results ----- -->\n @else if (!repositories().length) {\n <div class=\"rounded-lg border border-dashed border-surface p-6 text-center text-sm opacity-70\">\n {{ (i18n + '.steps.repositories.empty' | translate | async) ?? '' }}\n </div>\n }\n <!-- ----- Repository results ----- -->\n @else {\n <div class=\"flex flex-col gap-2\">\n @for (repo of repositories(); track repo.remoteId) {\n <button\n type=\"button\"\n class=\"flex items-start justify-between gap-3 rounded-lg border border-surface bg-lighter-surface p-4 text-start transition hover:border-primary hover:shadow-sm\"\n [disabled]=\"linking()\"\n (click)=\"onSelectRepository(repo)\"\n >\n <div class=\"min-w-0\">\n <div class=\"font-medium\">{{ repo.fullName }}</div>\n <!-- ----- Repository description when available ----- -->\n @if (repo.description) {\n <div class=\"mt-1 line-clamp-2 text-sm opacity-70\">{{ repo.description }}</div>\n }\n <!-- ----- Default branch metadata ----- -->\n @if (repo.defaultBranch) {\n <div class=\"mt-2 text-xs opacity-60\">\n {{ (i18n + '.fields.default-branch' | translate | async) ?? '' }}: {{ repo.defaultBranch }}\n </div>\n }\n </div>\n <ax-icon class=\"shrink-0 opacity-50\">\n <i class=\"fa-light fa-link\"></i>\n </ax-icon>\n </button>\n }\n </div>\n }\n </section>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i2.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i4.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i4.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i5.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i5$1.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXERepositoryCommitsPanelComponent, selector: "axe-repository-commits-panel", inputs: ["projectId", "link"] }, { kind: "pipe", type: i6$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i7.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
730
+ ], usesInheritance: true, ngImport: i0, template: "<div class=\"flex w-full flex-col gap-4\">\n <!-- ----- Loading indicator while page data is fetched ----- -->\n @if (loading()) {\n <ax-loading></ax-loading>\n }\n <!-- ----- Linked repository summary ----- -->\n @else if (linkedRepository(); as link) {\n <section class=\"flex flex-col gap-4 rounded-lg border border-surface bg-lighter-surface p-4\">\n <div class=\"flex flex-wrap items-start justify-between gap-3\">\n <div class=\"min-w-0\">\n <div class=\"text-sm opacity-70\">\n {{ (i18n + '.linked.summary' | translate | async) ?? '' }}\n </div>\n <div class=\"mt-1 text-lg font-medium\">{{ link.fullName }}</div>\n </div>\n <ax-badge\n size=\"sm\"\n look=\"twotone\"\n color=\"success\"\n [text]=\"(i18n + '.linked.badge' | translate | async) ?? ''\"\n ></ax-badge>\n </div>\n\n <div class=\"grid gap-3 md:grid-cols-2\">\n <div>\n <div class=\"text-sm opacity-70\">{{ (i18n + '.fields.provider' | translate | async) ?? '' }}</div>\n <div class=\"font-medium\">{{ link.providerId }}</div>\n </div>\n <!-- ----- Default branch when configured ----- -->\n @if (link.defaultBranch) {\n <div>\n <div class=\"text-sm opacity-70\">{{ (i18n + '.fields.default-branch' | translate | async) ?? '' }}</div>\n <div class=\"font-medium\">{{ link.defaultBranch }}</div>\n </div>\n }\n <div class=\"md:col-span-2\">\n <div class=\"text-sm opacity-70\">{{ (i18n + '.fields.web-url' | translate | async) ?? '' }}</div>\n <a class=\"font-medium text-primary hover:underline\" [href]=\"link.webUrl\" target=\"_blank\" rel=\"noopener noreferrer\">\n {{ link.webUrl }}\n </a>\n </div>\n </div>\n\n <div class=\"flex flex-wrap gap-2\">\n <ax-button\n look=\"outline\"\n color=\"primary\"\n [disabled]=\"linking()\"\n [text]=\"(i18n + '.actions.change' | translate | async) ?? ''\"\n (onClick)=\"onChangeRepository()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-arrow-right-arrow-left\"></ax-icon>\n </ax-prefix>\n </ax-button>\n <ax-button\n look=\"outline\"\n color=\"danger\"\n [disabled]=\"linking()\"\n [text]=\"(i18n + '.actions.unlink' | translate | async) ?? ''\"\n (onClick)=\"onUnlinkRepository()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-link-slash\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n </section>\n\n <axe-repository-commits-panel [projectId]=\"projectId()\" [link]=\"link\"></axe-repository-commits-panel>\n }\n <!-- ----- No provider connection configured ----- -->\n @else if (!hasConnections()) {\n <section class=\"rounded-lg border border-dashed border-surface bg-lighter-surface p-6 text-center\">\n <ax-icon class=\"mb-3 text-3xl opacity-60\">\n <i class=\"fa-light fa-plug-circle-xmark\"></i>\n </ax-icon>\n <div class=\"font-medium\">{{ (i18n + '.empty.no-connection.title' | translate | async) ?? '' }}</div>\n <div class=\"mt-2 text-sm opacity-70\">{{ (i18n + '.empty.no-connection.description' | translate | async) ?? '' }}</div>\n </section>\n }\n <!-- ----- Provider selection step ----- -->\n @else if (step() === 'provider') {\n <section class=\"flex flex-col gap-3\">\n <div class=\"flex flex-wrap items-start justify-between gap-3\">\n <div>\n <div class=\"font-medium\">{{ (i18n + '.steps.provider.title' | translate | async) ?? '' }}</div>\n <div class=\"text-sm opacity-70\">{{ (i18n + '.steps.provider.description' | translate | async) ?? '' }}</div>\n </div>\n <!-- ----- Cancel change when a repository is already linked ----- -->\n @if (selectingNewLink()) {\n <ax-button\n look=\"blank\"\n size=\"sm\"\n [disabled]=\"linking()\"\n [text]=\"(i18n + '.actions.back' | translate | async) ?? ''\"\n (onClick)=\"onCancelChange()\"\n ></ax-button>\n }\n </div>\n\n <div class=\"grid gap-3 md:grid-cols-2\">\n @for (connection of connections(); track connection.id) {\n <button\n type=\"button\"\n class=\"flex items-start gap-3 rounded-lg border border-surface bg-lighter-surface p-4 text-start transition hover:border-primary hover:shadow-sm\"\n [disabled]=\"linking()\"\n (click)=\"onSelectConnection(connection)\"\n >\n <ax-icon class=\"mt-0.5 text-2xl\">\n <i [class]=\"providerIcon(connection)\"></i>\n </ax-icon>\n <div class=\"min-w-0 flex-1\">\n <div class=\"font-medium\">\n @if (providerTitle(connection).startsWith('@')) {\n {{ providerTitle(connection) | translate | async }}\n }\n <!-- ----- Fallback when provider title is a plain display name ----- -->\n @else {\n {{ providerTitle(connection) }}\n }\n </div>\n <div class=\"mt-1 truncate text-sm opacity-70\">\n {{ connection.displayName || connection.providerId }}\n </div>\n </div>\n <ax-icon class=\"opacity-50\">\n <i class=\"fa-light fa-chevron-right\"></i>\n </ax-icon>\n </button>\n }\n </div>\n </section>\n }\n <!-- ----- Repository search and selection step ----- -->\n @else {\n <section class=\"flex flex-col gap-4\">\n <div class=\"flex flex-wrap items-center justify-between gap-3\">\n <div class=\"flex min-w-0 items-center gap-3\">\n <ax-button\n look=\"blank\"\n size=\"sm\"\n [disabled]=\"linking()\"\n [text]=\"(i18n + '.actions.back' | translate | async) ?? ''\"\n (onClick)=\"onBackToProviders()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-arrow-left\"></ax-icon>\n </ax-prefix>\n </ax-button>\n <div class=\"min-w-0\">\n <div class=\"font-medium\">{{ (i18n + '.steps.repositories.title' | translate | async) ?? '' }}</div>\n @if (selectedConnection(); as connection) {\n <div class=\"truncate text-sm opacity-70\">\n @if (providerTitle(connection).startsWith('@')) {\n {{ providerTitle(connection) | translate | async }}\n }\n <!-- ----- Fallback when provider title is a plain display name ----- -->\n @else {\n {{ providerTitle(connection) }}\n }\n \u00B7 {{ connection.displayName || connection.providerId }}\n </div>\n }\n </div>\n </div>\n </div>\n\n <ax-search-box\n [value]=\"searchQuery()\"\n [disabled]=\"linking()\"\n (valueChange)=\"onSearchChange($event)\"\n [placeholder]=\"(i18n + '.steps.repositories.search-placeholder' | translate | async) ?? ''\"\n ></ax-search-box>\n\n <!-- ----- Repository list loading indicator ----- -->\n @if (reposLoading()) {\n <ax-loading></ax-loading>\n }\n <!-- ----- Empty repository search results ----- -->\n @else if (!repositories().length) {\n <div class=\"rounded-lg border border-dashed border-surface p-6 text-center text-sm opacity-70\">\n {{ (i18n + '.steps.repositories.empty' | translate | async) ?? '' }}\n </div>\n }\n <!-- ----- Repository results ----- -->\n @else {\n <div class=\"flex flex-col gap-2\">\n @for (repo of repositories(); track repo.remoteId) {\n <button\n type=\"button\"\n class=\"flex items-start justify-between gap-3 rounded-lg border border-surface bg-lighter-surface p-4 text-start transition hover:border-primary hover:shadow-sm\"\n [disabled]=\"linking()\"\n (click)=\"onSelectRepository(repo)\"\n >\n <div class=\"min-w-0\">\n <div class=\"font-medium\">{{ repo.fullName }}</div>\n <!-- ----- Repository description when available ----- -->\n @if (repo.description) {\n <div class=\"mt-1 line-clamp-2 text-sm opacity-70\">{{ repo.description }}</div>\n }\n <!-- ----- Default branch metadata ----- -->\n @if (repo.defaultBranch) {\n <div class=\"mt-2 text-xs opacity-60\">\n {{ (i18n + '.fields.default-branch' | translate | async) ?? '' }}: {{ repo.defaultBranch }}\n </div>\n }\n </div>\n <ax-icon class=\"shrink-0 opacity-50\">\n <i class=\"fa-light fa-link\"></i>\n </ax-icon>\n </button>\n }\n </div>\n }\n </section>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i4.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i5$1.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXERepositoryCommitsPanelComponent, selector: "axe-repository-commits-panel", inputs: ["projectId", "link"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
728
731
  }
729
732
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXESourceControlPageComponent, decorators: [{
730
733
  type: Component,
@@ -746,4 +749,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
746
749
  }], ctorParameters: () => [], propDecorators: { rootContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "rootContext", required: false }] }], pageConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageConfig", required: false }] }] } });
747
750
 
748
751
  export { AXESourceControlPageComponent };
749
- //# sourceMappingURL=acorex-platform-extension-source-control-core-client-source-control-page.component-DOALkPKo.mjs.map
752
+ //# sourceMappingURL=acorex-platform-extension-source-control-core-client-source-control-page.component-BcNNvSDq.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-extension-source-control-core-client-source-control-page.component-BcNNvSDq.mjs","sources":["../../../../libs/extensions/source-control/core/client/src/lib/features/link-repository/source-control-repo-search.client.ts","../../../../libs/extensions/source-control/core/client/src/lib/features/project-management/source-control-project-link.service.ts","../../../../libs/extensions/source-control/core/client/src/lib/features/project-management/repository-commits-panel/source-control-repository-browse.client.ts","../../../../libs/extensions/source-control/core/client/src/lib/features/project-management/repository-commits-panel/source-control-repository-hooks.service.ts","../../../../libs/extensions/source-control/core/client/src/lib/features/project-management/repository-commits-panel/repository-commits-panel.component.ts","../../../../libs/extensions/source-control/core/client/src/lib/features/project-management/repository-commits-panel/repository-commits-panel.component.html","../../../../libs/extensions/source-control/core/client/src/lib/features/project-management/source-control-page/source-control-page.component.ts","../../../../libs/extensions/source-control/core/client/src/lib/features/project-management/source-control-page/source-control-page.component.html"],"sourcesContent":["//#region ----- Imports -----\n\nimport { AXPQueryService } from '@acorex-platform/framework-client/runtime';\nimport { runtimeQueryPayloadData } from '@acorex-platform/framework-shared/core';\nimport {\n AXE_SC_PROVIDER_GITHUB,\n AXE_SC_PROVIDER_GITLAB,\n type AXESourceControlRemoteRepoDto,\n type AXESourceControlSearchReposRequest,\n type AXESourceControlSearchReposResponse,\n} from '@acorex-platform/extension-source-control-core-client/contracts';\nimport { AXEGithubQueryKeys } from '@acorex-platform/extension-github-client/contracts';\nimport { AXEGitLabQueryKeys } from '@acorex-platform/extension-gitlab-client/contracts';\nimport { inject, Injectable } from '@angular/core';\n\n//#endregion\n\n//#region ----- Service -----\n\n@Injectable({ providedIn: 'root' })\nexport class AXESourceControlRepoSearchClient {\n private readonly queryService = inject(AXPQueryService);\n\n async search(input: AXESourceControlSearchReposRequest): Promise<AXESourceControlRemoteRepoDto[]> {\n const key = this.resolveQueryKey(input.providerId);\n const result = await this.queryService.fetch<AXESourceControlSearchReposRequest, AXESourceControlSearchReposResponse>(\n key,\n input,\n );\n return runtimeQueryPayloadData(result)?.items ?? [];\n }\n\n private resolveQueryKey(providerId: string): string {\n if (providerId === AXE_SC_PROVIDER_GITHUB) {\n return AXEGithubQueryKeys.RepoSearch;\n }\n if (providerId === AXE_SC_PROVIDER_GITLAB) {\n return AXEGitLabQueryKeys.RepoSearch;\n }\n throw new Error(`Unsupported source-control provider: ${providerId}`);\n }\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport { AXMIntegrationConnectionManager } from '@acorex-platform/module-integration-management-client';\nimport type { AXMIntegrationManagementIntegrationConnectionEntityModel } from '@acorex-platform/module-integration-management-client/contracts';\nimport { AXPEntityService } from '@acorex-platform/framework-client/layout/entity';\nimport { Injectable, inject } from '@angular/core';\nimport { trim } from 'lodash-es';\nimport {\n AXE_SC_PROVIDER_IDS,\n RootConfig,\n type AXESourceControlProjectSourceControlLinkEntityModel,\n type AXESourceControlRemoteRepoDto,\n} from '@acorex-platform/extension-source-control-core-client/contracts';\nimport { AXESourceControlRepoSearchClient } from '../link-repository/source-control-repo-search.client';\n\n//#endregion\n\n//#region ----- Types -----\n\nexport interface AXESourceControlSaveLinkInput {\n projectId: string;\n connection: AXMIntegrationManagementIntegrationConnectionEntityModel;\n repo: AXESourceControlRemoteRepoDto;\n}\n\n//#endregion\n\n//#region ----- Service -----\n\n@Injectable({ providedIn: 'root' })\nexport class AXESourceControlProjectLinkService {\n //#region ----- Services & Dependencies -----\n\n private readonly connectionManager = inject(AXMIntegrationConnectionManager);\n private readonly entityService = inject(AXPEntityService);\n private readonly repoSearch = inject(AXESourceControlRepoSearchClient);\n\n //#endregion\n\n //#region ----- Connections -----\n\n async listConnections(): Promise<AXMIntegrationManagementIntegrationConnectionEntityModel[]> {\n const connections = await this.connectionManager.listForCurrentUser('tenant');\n return connections.filter(\n (item) =>\n AXE_SC_PROVIDER_IDS.includes(item.providerId as (typeof AXE_SC_PROVIDER_IDS)[number]) &&\n !item.isRevoked &&\n !item.isDisabled,\n );\n }\n\n //#endregion\n\n //#region ----- Link persistence -----\n\n async findLinkByProjectId(projectId: string): Promise<AXESourceControlProjectSourceControlLinkEntityModel | null> {\n const id = trim(projectId);\n if (!id) {\n return null;\n }\n\n const result = await this.entityService\n .withEntity(RootConfig.module.name, RootConfig.entities.projectSourceControlLink.name)\n .data<string, AXESourceControlProjectSourceControlLinkEntityModel>()\n .query({\n skip: 0,\n take: 1,\n filter: {\n field: 'projectId',\n operator: { type: 'equal' },\n value: id,\n },\n });\n\n return result.items?.[0] ?? null;\n }\n\n async saveLink(input: AXESourceControlSaveLinkInput): Promise<AXESourceControlProjectSourceControlLinkEntityModel> {\n const projectId = trim(input.projectId);\n if (!projectId) {\n throw new Error('Project id is required.');\n }\n\n const accessor = this.entityService\n .withEntity(RootConfig.module.name, RootConfig.entities.projectSourceControlLink.name)\n .data<string, AXESourceControlProjectSourceControlLinkEntityModel>();\n\n const existing = await this.findLinkByProjectId(projectId);\n const linkedAt = new Date().toISOString();\n const payload = {\n projectId,\n providerId: input.connection.providerId,\n connectionId: input.connection.id,\n remoteId: input.repo.remoteId,\n fullName: input.repo.fullName,\n webUrl: input.repo.webUrl,\n defaultBranch: input.repo.defaultBranch,\n linkedAt,\n };\n\n if (existing) {\n await accessor.update(existing.id, payload);\n return { ...existing, ...payload };\n }\n\n const createdId = await accessor.create(payload);\n return {\n id: String(createdId),\n ...payload,\n };\n }\n\n async removeLink(projectId: string): Promise<void> {\n const existing = await this.findLinkByProjectId(projectId);\n if (!existing) {\n return;\n }\n\n await this.entityService\n .withEntity(RootConfig.module.name, RootConfig.entities.projectSourceControlLink.name)\n .data<string, AXESourceControlProjectSourceControlLinkEntityModel>()\n .delete(existing.id);\n }\n\n //#endregion\n\n //#region ----- Repository search -----\n\n async searchRepositories(\n connection: AXMIntegrationManagementIntegrationConnectionEntityModel,\n query?: string,\n ): Promise<AXESourceControlRemoteRepoDto[]> {\n return this.repoSearch.search({\n providerId: connection.providerId,\n connectionId: connection.id,\n query: trim(query),\n });\n }\n\n //#endregion\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport { AXEGithubQueryKeys } from '@acorex-platform/extension-github-client/contracts';\nimport { AXEGitLabQueryKeys } from '@acorex-platform/extension-gitlab-client/contracts';\nimport {\n AXE_SC_PROVIDER_GITHUB,\n AXE_SC_PROVIDER_GITLAB,\n type AXESourceControlBranchDto,\n type AXESourceControlCommitDto,\n type AXESourceControlListBranchesRequest,\n type AXESourceControlListBranchesResponse,\n type AXESourceControlListCommitsRequest,\n type AXESourceControlListCommitsResponse,\n type AXESourceControlProjectSourceControlLinkEntityModel,\n} from '@acorex-platform/extension-source-control-core-client/contracts';\nimport { AXPQueryService } from '@acorex-platform/framework-client/runtime';\nimport { runtimeQueryPayloadData } from '@acorex-platform/framework-shared/core';\nimport { inject, Injectable } from '@angular/core';\n\n//#endregion\n\n//#region ----- Service -----\n\n@Injectable({ providedIn: 'root' })\nexport class AXESourceControlRepositoryBrowseClient {\n private readonly queryService = inject(AXPQueryService);\n\n async listBranches(link: AXESourceControlProjectSourceControlLinkEntityModel): Promise<AXESourceControlBranchDto[]> {\n const input: AXESourceControlListBranchesRequest = {\n providerId: link.providerId,\n connectionId: link.connectionId,\n fullName: link.fullName,\n };\n const result = await this.queryService.fetch<AXESourceControlListBranchesRequest, AXESourceControlListBranchesResponse>(this.resolveBranchesQueryKey(link.providerId), input);\n return runtimeQueryPayloadData(result)?.items ?? [];\n }\n\n async listCommits(link: AXESourceControlProjectSourceControlLinkEntityModel, branch: string, take = 30): Promise<AXESourceControlCommitDto[]> {\n const input: AXESourceControlListCommitsRequest = {\n providerId: link.providerId,\n connectionId: link.connectionId,\n fullName: link.fullName,\n branch,\n take,\n };\n const result = await this.queryService.fetch<AXESourceControlListCommitsRequest, AXESourceControlListCommitsResponse>(this.resolveCommitsQueryKey(link.providerId), input);\n return runtimeQueryPayloadData(result)?.items ?? [];\n }\n\n private resolveBranchesQueryKey(providerId: string): string {\n if (providerId === AXE_SC_PROVIDER_GITHUB) {\n return AXEGithubQueryKeys.ListBranches;\n }\n if (providerId === AXE_SC_PROVIDER_GITLAB) {\n return AXEGitLabQueryKeys.ListBranches;\n }\n throw new Error(`Unsupported source-control provider: ${providerId}`);\n }\n\n private resolveCommitsQueryKey(providerId: string): string {\n if (providerId === AXE_SC_PROVIDER_GITHUB) {\n return AXEGithubQueryKeys.ListCommits;\n }\n if (providerId === AXE_SC_PROVIDER_GITLAB) {\n return AXEGitLabQueryKeys.ListCommits;\n }\n throw new Error(`Unsupported source-control provider: ${providerId}`);\n }\n}\n\n//#endregion\n","//#region ----- Imports -----\r\r\n\r\r\nimport { AXPHookService } from '@acorex-platform/framework-client/core';\r\r\nimport type { AXPActionMenuItem } from '@acorex-platform/framework-shared/core';\r\r\nimport {\r\r\n AXESourceControlHookKeys,\r\r\n type AXESourceControlBranchActionsHookPayload,\r\r\n type AXESourceControlCommitActionsHookPayload,\r\r\n type AXESourceControlCommitDto,\r\r\n type AXESourceControlProjectSourceControlLinkEntityModel,\r\r\n} from '@acorex-platform/extension-source-control-core-client/contracts';\r\r\nimport { inject, Injectable } from '@angular/core';\r\r\n\r\r\n//#endregion\r\r\n\r\r\n//#region ----- Service -----\r\r\n\r\r\n@Injectable({ providedIn: 'root' })\r\r\nexport class AXESourceControlRepositoryHooksService {\r\r\n private readonly hooks = inject(AXPHookService);\r\r\n\r\r\n async resolveCommitActions(input: {\r\r\n projectId: string;\r\r\n link: AXESourceControlProjectSourceControlLinkEntityModel;\r\r\n branch: string;\r\r\n commit: AXESourceControlCommitDto;\r\r\n }): Promise<AXPActionMenuItem[]> {\r\r\n const payload: AXESourceControlCommitActionsHookPayload = {\r\r\n projectId: input.projectId,\r\r\n link: input.link,\r\r\n branch: input.branch,\r\r\n commit: input.commit,\r\r\n actions: [],\r\r\n };\r\r\n const result = await this.hooks.runAsync<AXESourceControlCommitActionsHookPayload>(\r\r\n AXESourceControlHookKeys.CommitActions,\r\r\n payload,\r\r\n );\r\r\n return result?.actions ?? [];\r\r\n }\r\r\n\r\r\n async resolveBranchActions(input: {\r\r\n projectId: string;\r\r\n link: AXESourceControlProjectSourceControlLinkEntityModel;\r\r\n branch: string;\r\r\n baseBranch: string;\r\r\n }): Promise<AXPActionMenuItem[]> {\r\r\n const payload: AXESourceControlBranchActionsHookPayload = {\r\r\n projectId: input.projectId,\r\r\n link: input.link,\r\r\n branch: input.branch,\r\r\n baseBranch: input.baseBranch,\r\r\n actions: [],\r\r\n };\r\r\n const result = await this.hooks.runAsync<AXESourceControlBranchActionsHookPayload>(\r\r\n AXESourceControlHookKeys.BranchActions,\r\r\n payload,\r\r\n );\r\r\n return result?.actions ?? [];\r\r\n }\r\r\n}\r\r\n\r\r\n//#endregion\r\r\n","//#region ----- Imports -----\n\n\n\nimport { AsyncPipe } from '@angular/common';\n\nimport {\n\n ChangeDetectionStrategy,\n\n Component,\n\n computed,\n\n effect,\n\n inject,\n\n input,\n\n signal,\n\n untracked,\n\n} from '@angular/core';\n\nimport { AXValueChangedEvent } from '@acorex/cdk/common';\n\nimport { FormsModule } from '@angular/forms';\n\nimport { AXBadgeModule } from '@acorex/components/badge';\n\nimport { AXButtonModule } from '@acorex/components/button';\n\nimport { AXDecoratorModule } from '@acorex/components/decorators';\n\nimport { AXLoadingModule } from '@acorex/components/loading';\n\nimport { AXComboBoxComponent, type AXComboBoxItem, type AXComboBoxValue } from '@acorex/components/combo-box';\n\nimport { AXTranslationModule } from '@acorex/core/translation';\n\nimport { AXPSettingsService } from '@acorex-platform/framework-client/common';\n\nimport { AXPStateMessageComponent } from '@acorex-platform/framework-client/layout/components';\n\nimport { AXPCommandExecutor } from '@acorex-platform/framework-client/runtime';\n\nimport type { AXPActionMenuItem } from '@acorex-platform/framework-shared/core';\n\nimport { AXPRegionalSetting } from '@acorex-platform/framework-shared/core';\n\nimport type {\n\n AXESourceControlBranchDto,\n\n AXESourceControlCommitDto,\n\n AXESourceControlProjectSourceControlLinkEntityModel,\n\n} from '@acorex-platform/extension-source-control-core-client/contracts';\n\nimport { AXFormatService } from '@acorex/core/format';\n\nimport { defaultTo, trim } from 'lodash-es';\n\nimport { AXESourceControlRepositoryBrowseClient } from './source-control-repository-browse.client';\n\nimport { AXESourceControlRepositoryHooksService } from './source-control-repository-hooks.service';\n\n\n\n//#endregion\n\n\n\n//#region ----- Constants -----\n\n\n\nconst I18N = '@extensions-source-control:pages.repository.commits';\n\n\n\n//#endregion\n\n\n\n//#region ----- Component -----\n\n\n\n@Component({\n\n selector: 'axe-repository-commits-panel',\n\n templateUrl: './repository-commits-panel.component.html',\n\n imports: [\n\n AsyncPipe,\n\n FormsModule,\n\n AXBadgeModule,\n\n AXButtonModule,\n\n AXDecoratorModule,\n\n AXLoadingModule,\n\n AXComboBoxComponent,\n\n AXTranslationModule,\n\n AXPStateMessageComponent,\n\n ],\n\n changeDetection: ChangeDetectionStrategy.OnPush,\n\n})\n\nexport class AXERepositoryCommitsPanelComponent {\n\n //#region ----- Inputs -----\n\n\n\n projectId = input.required<string>();\n\n link = input.required<AXESourceControlProjectSourceControlLinkEntityModel>();\n\n\n\n //#endregion\n\n\n\n //#region ----- Services & Dependencies -----\n\n\n\n protected readonly i18n = I18N;\n\n private readonly browseClient = inject(AXESourceControlRepositoryBrowseClient);\n\n private readonly hooksService = inject(AXESourceControlRepositoryHooksService);\n\n private readonly commandExecutor = inject(AXPCommandExecutor);\n\n private readonly settingsService = inject(AXPSettingsService);\n\n private readonly formatService = inject(AXFormatService);\n\n\n\n //#endregion\n\n\n\n //#region ----- State Signals -----\n\n\n\n protected readonly loading = signal(false);\n\n protected readonly branches = signal<AXESourceControlBranchDto[]>([]);\n\n protected readonly selectedBranch = signal('');\n\n protected readonly commits = signal<AXESourceControlCommitDto[]>([]);\n\n protected readonly branchActions = signal<AXPActionMenuItem[]>([]);\n\n protected readonly commitActionsBySha = signal<Record<string, AXPActionMenuItem[]>>({});\n\n private readonly datetimeFormat = signal('');\n\n\n\n //#endregion\n\n\n\n //#region ----- Computed Properties -----\n\n\n\n protected readonly baseBranch = computed(() => {\n\n const link = this.link();\n\n const defaultBranch = trim(link.defaultBranch ?? '');\n\n if (defaultBranch) {\n\n return defaultBranch;\n\n }\n\n const branches = this.branches();\n\n const markedDefault = branches.find((branch) => branch.isDefault)?.name;\n\n return markedDefault ?? branches[0]?.name ?? 'main';\n\n });\n\n\n\n protected readonly branchOptions = computed<AXComboBoxItem[]>(() =>\n\n this.branches().map((branch) => ({\n\n id: branch.name,\n\n text: branch.name,\n\n value: branch.name,\n\n })),\n\n );\n\n\n\n //#endregion\n\n\n\n //#region ----- Lifecycle -----\n\n\n\n constructor() {\n\n effect(() => {\n\n const link = this.link();\n\n const projectId = trim(this.projectId());\n\n if (!link || !projectId) {\n\n return;\n\n }\n\n untracked(() => {\n\n void this.initialize(link, projectId);\n\n });\n\n });\n\n\n\n effect(() => {\n\n const link = this.link();\n\n const projectId = trim(this.projectId());\n\n const branch = trim(this.selectedBranch());\n\n if (!link || !projectId || !branch) {\n\n return;\n\n }\n\n untracked(() => {\n\n void this.loadBranchData(link, projectId, branch);\n\n });\n\n });\n\n }\n\n\n\n //#endregion\n\n\n\n //#region ----- Event Handlers -----\n\n\n\n protected onBranchComboChange(event: AXValueChangedEvent<AXComboBoxValue>): void {\n const value = event.value;\n this.onBranchChange(typeof value === 'string' ? value : null);\n }\n\n\n\n protected onBranchChange(branch: string | null | undefined): void {\n\n this.selectedBranch.set(trim(branch ?? ''));\n\n }\n\n\n\n protected commitActions(sha: string): AXPActionMenuItem[] {\n\n return this.commitActionsBySha()[sha] ?? [];\n\n }\n\n\n\n protected commitMessage(commit: AXESourceControlCommitDto): string {\n\n const message = trim(commit.message);\n\n if (!message) {\n\n return '—';\n\n }\n\n const firstLine = message.split('\\n')[0]?.trim();\n\n return firstLine || message;\n\n }\n\n\n\n protected formatCommittedAt(value: string): string {\n\n const iso = trim(value);\n\n if (!iso) {\n\n return '—';\n\n }\n\n const format = this.datetimeFormat();\n\n if (!format) {\n\n return iso;\n\n }\n\n return this.formatService.format(new Date(iso), 'datetime', { format });\n\n }\n\n\n\n protected actionTextKey(action: AXPActionMenuItem): string {\n\n const title = action.title;\n\n return typeof title === 'string' ? title : '';\n\n }\n\n\n\n protected async onActionClick(action: AXPActionMenuItem): Promise<void> {\n\n const command = action.command;\n\n if (!command?.name) {\n\n return;\n\n }\n\n await this.commandExecutor.execute(command.name, command.options ?? {});\n\n }\n\n\n\n protected onViewCommit(commit: AXESourceControlCommitDto): void {\n\n const url = trim(commit.webUrl);\n\n if (url) {\n\n window.open(url, '_blank', 'noopener,noreferrer');\n\n }\n\n }\n\n\n\n //#endregion\n\n\n\n //#region ----- Data Loading -----\n\n\n\n private async initialize(\n\n link: AXESourceControlProjectSourceControlLinkEntityModel,\n\n projectId: string,\n\n ): Promise<void> {\n\n this.loading.set(true);\n\n try {\n\n await this.loadDatetimeFormat();\n\n const branches = await this.browseClient.listBranches(link);\n\n this.branches.set(branches);\n\n const initialBranch = this.resolveInitialBranch(link, branches);\n\n this.selectedBranch.set(initialBranch);\n\n if (!initialBranch) {\n\n this.commits.set([]);\n\n this.branchActions.set([]);\n\n this.commitActionsBySha.set({});\n\n }\n\n } catch (error: unknown) {\n\n this.handleError(error, 'Failed to load repository branches.');\n\n this.branches.set([]);\n\n this.selectedBranch.set('');\n\n } finally {\n\n this.loading.set(false);\n\n }\n\n }\n\n\n\n private async loadBranchData(\n\n link: AXESourceControlProjectSourceControlLinkEntityModel,\n\n projectId: string,\n\n branch: string,\n\n ): Promise<void> {\n\n this.loading.set(true);\n\n try {\n\n const [commits, branchActions] = await Promise.all([\n\n this.browseClient.listCommits(link, branch),\n\n this.hooksService.resolveBranchActions({\n\n projectId,\n\n link,\n\n branch,\n\n baseBranch: this.baseBranch(),\n\n }),\n\n ]);\n\n this.commits.set(commits);\n\n this.branchActions.set(branchActions);\n\n const commitActionsEntries = await Promise.all(\n\n commits.map(async (commit) => {\n\n const actions = await this.hooksService.resolveCommitActions({\n\n projectId,\n\n link,\n\n branch,\n\n commit,\n\n });\n\n return [commit.sha, actions] as const;\n\n }),\n\n );\n\n this.commitActionsBySha.set(Object.fromEntries(commitActionsEntries));\n\n } catch (error: unknown) {\n\n this.handleError(error, 'Failed to load repository commits.');\n\n this.commits.set([]);\n\n this.branchActions.set([]);\n\n this.commitActionsBySha.set({});\n\n } finally {\n\n this.loading.set(false);\n\n }\n\n }\n\n\n\n private resolveInitialBranch(\n\n link: AXESourceControlProjectSourceControlLinkEntityModel,\n\n branches: AXESourceControlBranchDto[],\n\n ): string {\n\n const preferred = trim(link.defaultBranch ?? '');\n\n if (preferred && branches.some((branch) => branch.name === preferred)) {\n\n return preferred;\n\n }\n\n const markedDefault = branches.find((branch) => branch.isDefault)?.name;\n\n if (markedDefault) {\n\n return markedDefault;\n\n }\n\n return defaultTo(branches[0]?.name, '');\n\n }\n\n\n\n private async loadDatetimeFormat(): Promise<void> {\n\n const dateFormat = await this.settingsService.get(AXPRegionalSetting.ShortDate);\n\n const timeFormat = await this.settingsService.get(AXPRegionalSetting.ShortTime);\n\n this.datetimeFormat.set(`${dateFormat} ${timeFormat}`.trim());\n\n }\n\n\n\n private handleError(error: unknown, fallback: string): void {\n\n const message = error instanceof Error ? error.message : fallback;\n\n console.error(message, error);\n\n }\n\n\n\n //#endregion\n\n}\n\n\n\n//#endregion\n\n","<section class=\"flex flex-col gap-4 rounded-lg border border-surface bg-lighter-surface p-4\">\n\n <div class=\"flex flex-wrap items-start justify-between gap-3\">\n\n <div>\n\n <div class=\"font-medium\">{{ (i18n + '.title' | translate | async) ?? '' }}</div>\n\n <div class=\"text-sm opacity-70\">{{ (i18n + '.description' | translate | async) ?? '' }}</div>\n\n </div>\n\n <!-- ----- Branch filter ----- -->\n\n @if (branchOptions().length) {\n\n <ax-combo-box\n\n class=\"min-w-[12rem]\"\n\n [items]=\"branchOptions()\"\n\n [searchable]=\"false\"\n\n [value]=\"selectedBranch()\"\n\n (onValueChanged)=\"onBranchComboChange($event)\"\n\n [placeholder]=\"(i18n + '.branch.placeholder' | translate | async) ?? ''\"\n\n ></ax-combo-box>\n\n }\n\n </div>\n\n\n\n <!-- ----- Branch-level hook actions ----- -->\n\n @if (branchActions().length) {\n\n <div class=\"flex flex-wrap gap-2\">\n\n @for (action of branchActions(); track action.name ?? action.title) {\n\n <ax-button\n\n look=\"outline\"\n\n color=\"primary\"\n\n size=\"sm\"\n\n [text]=\"(actionTextKey(action) | translate | async) ?? ''\"\n\n (onClick)=\"onActionClick(action)\"\n\n >\n\n @if (action.icon) {\n\n <ax-prefix>\n\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n\n </ax-prefix>\n\n }\n\n </ax-button>\n\n }\n\n </div>\n\n }\n\n\n\n <!-- ----- Commits loading indicator ----- -->\n\n @if (loading()) {\n\n <ax-loading></ax-loading>\n\n }\n\n <!-- ----- Empty commits state ----- -->\n\n @else if (!commits().length) {\n\n <axp-state-message\n\n icon=\"fa-light fa-code-commit\"\n\n [title]=\"i18n + '.empty.title'\"\n\n [description]=\"i18n + '.empty.description'\"\n\n look=\"minimal\"\n\n ></axp-state-message>\n\n }\n\n <!-- ----- Commits list ----- -->\n\n @else {\n\n <div class=\"flex flex-col gap-2\">\n\n @for (commit of commits(); track commit.sha) {\n\n <article class=\"flex flex-wrap items-start justify-between gap-3 rounded-lg border border-surface bg-surface p-3\">\n\n <div class=\"min-w-0 flex-1\">\n\n <div class=\"flex flex-wrap items-center gap-2\">\n\n <ax-badge\n\n size=\"sm\"\n\n look=\"twotone\"\n\n color=\"primary\"\n\n [text]=\"commit.shortSha ?? commit.sha.slice(0, 7)\"\n\n ></ax-badge>\n\n <span class=\"font-medium\">{{ commitMessage(commit) }}</span>\n\n </div>\n\n <div class=\"mt-1 flex flex-wrap gap-x-4 gap-y-1 text-sm opacity-70\">\n\n <span>{{ commit.authorName }}</span>\n\n <span>{{ formatCommittedAt(commit.committedAt) }}</span>\n\n </div>\n\n </div>\n\n <div class=\"flex shrink-0 flex-wrap items-center gap-2\">\n\n <ax-button\n\n look=\"blank\"\n\n size=\"sm\"\n\n [text]=\"(i18n + '.actions.view' | translate | async) ?? ''\"\n\n (onClick)=\"onViewCommit(commit)\"\n\n >\n\n <ax-prefix>\n\n <ax-icon icon=\"fa-light fa-arrow-up-right-from-square\"></ax-icon>\n\n </ax-prefix>\n\n </ax-button>\n\n <!-- ----- Commit-level hook actions ----- -->\n\n @for (action of commitActions(commit.sha); track action.name ?? action.title) {\n\n <ax-button\n\n look=\"outline\"\n\n size=\"sm\"\n\n color=\"primary\"\n\n [text]=\"(actionTextKey(action) | translate | async) ?? ''\"\n\n (onClick)=\"onActionClick(action)\"\n\n >\n\n @if (action.icon) {\n\n <ax-prefix>\n\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n\n </ax-prefix>\n\n }\n\n </ax-button>\n\n }\n\n </div>\n\n </article>\n\n }\n\n </div>\n\n }\n\n</section>\n\n","//#region ----- Imports -----\n\nimport { CommonModule } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n inject,\n input,\n OnDestroy,\n signal,\n untracked,\n} from '@angular/core';\nimport { AXBadgeModule } from '@acorex/components/badge';\nimport { AXButtonModule } from '@acorex/components/button';\nimport { AXDecoratorModule } from '@acorex/components/decorators';\nimport { AXDialogService } from '@acorex/components/dialog';\nimport { AXLoadingModule } from '@acorex/components/loading';\nimport { AXSearchBoxModule } from '@acorex/components/search-box';\nimport { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';\nimport { AXPPageLayoutBase, AXPPageLayoutBaseComponent } from '@acorex-platform/framework-client/layout/views';\nimport {\n AXE_SC_PROVIDER_GITHUB,\n AXE_SC_PROVIDER_GITLAB,\n type AXESourceControlProjectSourceControlLinkEntityModel,\n type AXESourceControlRemoteRepoDto,\n} from '@acorex-platform/extension-source-control-core-client/contracts';\nimport type { AXMIntegrationManagementIntegrationConnectionEntityModel } from '@acorex-platform/module-integration-management-client/contracts';\nimport { defaultTo, trim } from 'lodash-es';\nimport { AXESourceControlProjectLinkService } from '../source-control-project-link.service';\nimport { AXERepositoryCommitsPanelComponent } from '../repository-commits-panel/repository-commits-panel.component';\n\n//#endregion\n\n//#region ----- Types -----\n\ntype SourceControlPageStep = 'provider' | 'repositories';\n\ninterface ProviderPresentation {\n providerId: string;\n icon: string;\n titleKey: string;\n}\n\n//#endregion\n\n//#region ----- Constants -----\n\nconst I18N = '@extensions-source-control:pages.repository';\n\nconst PROVIDER_PRESENTATION: Record<string, ProviderPresentation> = {\n [AXE_SC_PROVIDER_GITHUB]: {\n providerId: AXE_SC_PROVIDER_GITHUB,\n icon: 'fa-brands fa-github',\n titleKey: '@extensions-github:integration.display-name',\n },\n [AXE_SC_PROVIDER_GITLAB]: {\n providerId: AXE_SC_PROVIDER_GITLAB,\n icon: 'fa-brands fa-gitlab',\n titleKey: '@extensions-gitlab:integration.display-name',\n },\n};\n\n//#endregion\n\n//#region ----- Component -----\n\n@Component({\n selector: 'axe-source-control-page',\n templateUrl: './source-control-page.component.html',\n imports: [\n CommonModule,\n AXBadgeModule,\n AXButtonModule,\n AXDecoratorModule,\n AXLoadingModule,\n AXSearchBoxModule,\n AXTranslationModule,\n AXERepositoryCommitsPanelComponent,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: AXPPageLayoutBase,\n useExisting: AXESourceControlPageComponent,\n },\n ],\n})\nexport class AXESourceControlPageComponent extends AXPPageLayoutBaseComponent implements OnDestroy {\n //#region ----- Inputs -----\n\n rootContext = input<Record<string, unknown>>({});\n pageConfig = input<Record<string, unknown>>();\n\n //#endregion\n\n //#region ----- Services & Dependencies -----\n\n protected readonly i18n = I18N;\n private readonly linkService = inject(AXESourceControlProjectLinkService);\n private readonly dialogService = inject(AXDialogService);\n private readonly translationService = inject(AXTranslationService);\n\n //#endregion\n\n //#region ----- State Signals -----\n\n protected readonly loading = signal(true);\n protected readonly linking = signal(false);\n protected readonly reposLoading = signal(false);\n protected readonly step = signal<SourceControlPageStep>('provider');\n protected readonly connections = signal<AXMIntegrationManagementIntegrationConnectionEntityModel[]>([]);\n protected readonly selectedConnection = signal<AXMIntegrationManagementIntegrationConnectionEntityModel | null>(null);\n protected readonly repositories = signal<AXESourceControlRemoteRepoDto[]>([]);\n protected readonly searchQuery = signal('');\n protected readonly existingLink = signal<AXESourceControlProjectSourceControlLinkEntityModel | null>(null);\n protected readonly selectingNewLink = signal(false);\n\n //#endregion\n\n //#region ----- Computed Properties -----\n\n protected readonly projectId = computed(() => {\n const id = this.rootContext()?.['id'];\n return typeof id === 'string' ? trim(id) : '';\n });\n\n protected readonly hasConnections = computed(() => this.connections().length > 0);\n\n protected readonly showLinkedSummary = computed(() => Boolean(this.existingLink()) && !this.selectingNewLink());\n\n protected readonly linkedRepository = computed(() => (this.showLinkedSummary() ? this.existingLink() : null));\n\n //#endregion\n\n //#region ----- Lifecycle -----\n\n private searchDebounce?: ReturnType<typeof setTimeout>;\n\n constructor() {\n super();\n effect(() => {\n const projectId = this.projectId();\n if (!projectId) {\n return;\n }\n untracked(() => {\n void this.initialize(projectId);\n });\n });\n }\n\n ngOnDestroy(): void {\n clearTimeout(this.searchDebounce);\n }\n\n //#endregion\n\n //#region ----- Event Handlers -----\n\n protected providerTitle(connection: AXMIntegrationManagementIntegrationConnectionEntityModel): string {\n const presentation = PROVIDER_PRESENTATION[connection.providerId];\n if (presentation?.titleKey) {\n return presentation.titleKey;\n }\n return defaultTo(connection.displayName, connection.providerId);\n }\n\n protected providerIcon(connection: AXMIntegrationManagementIntegrationConnectionEntityModel): string {\n return PROVIDER_PRESENTATION[connection.providerId]?.icon ?? 'fa-light fa-code-branch';\n }\n\n protected async onSelectConnection(connection: AXMIntegrationManagementIntegrationConnectionEntityModel): Promise<void> {\n this.selectedConnection.set(connection);\n this.step.set('repositories');\n this.searchQuery.set('');\n await this.loadRepositories();\n }\n\n protected onBackToProviders(): void {\n if (this.existingLink()) {\n this.onCancelChange();\n return;\n }\n this.step.set('provider');\n this.selectedConnection.set(null);\n this.repositories.set([]);\n this.searchQuery.set('');\n }\n\n protected onSearchChange(value: string | null | undefined): void {\n this.searchQuery.set(value ?? '');\n clearTimeout(this.searchDebounce);\n this.searchDebounce = setTimeout(() => {\n void this.loadRepositories();\n }, 350);\n }\n\n protected async onSelectRepository(repo: AXESourceControlRemoteRepoDto): Promise<void> {\n const connection = this.selectedConnection();\n const projectId = this.projectId();\n if (!connection || !projectId) {\n return;\n }\n\n const confirmed = await this.confirmLink(repo);\n if (!confirmed) {\n return;\n }\n\n this.linking.set(true);\n try {\n const link = await this.linkService.saveLink({ projectId, connection, repo });\n this.existingLink.set(link);\n this.selectingNewLink.set(false);\n this.step.set('provider');\n this.selectedConnection.set(null);\n this.repositories.set([]);\n this.searchQuery.set('');\n await this.showLinkedToast(repo.fullName);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to link repository.';\n this.toastService.show({ color: 'danger', content: message });\n } finally {\n this.linking.set(false);\n }\n }\n\n protected async onChangeRepository(): Promise<void> {\n this.selectingNewLink.set(true);\n this.step.set('provider');\n this.selectedConnection.set(null);\n this.repositories.set([]);\n this.searchQuery.set('');\n }\n\n protected onCancelChange(): void {\n this.selectingNewLink.set(false);\n this.step.set('provider');\n this.selectedConnection.set(null);\n this.repositories.set([]);\n this.searchQuery.set('');\n }\n\n protected async onUnlinkRepository(): Promise<void> {\n const link = this.existingLink();\n const projectId = this.projectId();\n if (!link || !projectId) {\n return;\n }\n\n const confirmed = await this.confirmUnlink(link.fullName);\n if (!confirmed) {\n return;\n }\n\n this.linking.set(true);\n try {\n await this.linkService.removeLink(projectId);\n this.existingLink.set(null);\n this.step.set('provider');\n const message = await this.translationService.translateAsync(`${I18N}.messages.unlinked`);\n this.toastService.show({ color: 'success', content: message ?? 'Repository unlinked.' });\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to unlink repository.';\n this.toastService.show({ color: 'danger', content: message });\n } finally {\n this.linking.set(false);\n }\n }\n\n //#endregion\n\n //#region ----- Data Loading -----\n\n private async initialize(projectId: string): Promise<void> {\n this.loading.set(true);\n try {\n const [connections, link] = await Promise.all([\n this.linkService.listConnections(),\n this.linkService.findLinkByProjectId(projectId),\n ]);\n this.connections.set(connections);\n this.existingLink.set(link);\n if (!link) {\n this.step.set('provider');\n }\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to load source-control data.';\n this.toastService.show({ color: 'danger', content: message });\n } finally {\n this.loading.set(false);\n }\n }\n\n private async loadRepositories(): Promise<void> {\n const connection = this.selectedConnection();\n if (!connection) {\n this.repositories.set([]);\n return;\n }\n\n this.reposLoading.set(true);\n try {\n const items = await this.linkService.searchRepositories(connection, this.searchQuery());\n this.repositories.set(items);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to search repositories.';\n this.toastService.show({ color: 'danger', content: message });\n this.repositories.set([]);\n } finally {\n this.reposLoading.set(false);\n }\n }\n\n //#endregion\n\n //#region ----- Dialogs -----\n\n private async confirmLink(repo: AXESourceControlRemoteRepoDto): Promise<boolean> {\n const title = await this.translationService.translateAsync(`${I18N}.dialogs.link.title`);\n const message = await this.translationService.translateAsync(`${I18N}.dialogs.link.message`, {\n params: { fullName: repo.fullName },\n });\n return Boolean(await this.dialogService.confirm(title ?? 'Link Repository', message ?? 'Link this repository?'));\n }\n\n private async confirmUnlink(fullName: string): Promise<boolean> {\n const title = await this.translationService.translateAsync(`${I18N}.dialogs.unlink.title`);\n const message = await this.translationService.translateAsync(`${I18N}.dialogs.unlink.message`, {\n params: { fullName },\n });\n return Boolean(await this.dialogService.confirm(title ?? 'Unlink Repository', message ?? 'Unlink this repository?'));\n }\n\n private async showLinkedToast(fullName: string): Promise<void> {\n const message = await this.translationService.translateAsync(`${I18N}.messages.linked`, {\n params: { fullName },\n });\n this.toastService.show({ color: 'success', content: message ?? 'Repository linked.' });\n }\n\n //#endregion\n}\n\n//#endregion\n","<div class=\"flex w-full flex-col gap-4\">\n <!-- ----- Loading indicator while page data is fetched ----- -->\n @if (loading()) {\n <ax-loading></ax-loading>\n }\n <!-- ----- Linked repository summary ----- -->\n @else if (linkedRepository(); as link) {\n <section class=\"flex flex-col gap-4 rounded-lg border border-surface bg-lighter-surface p-4\">\n <div class=\"flex flex-wrap items-start justify-between gap-3\">\n <div class=\"min-w-0\">\n <div class=\"text-sm opacity-70\">\n {{ (i18n + '.linked.summary' | translate | async) ?? '' }}\n </div>\n <div class=\"mt-1 text-lg font-medium\">{{ link.fullName }}</div>\n </div>\n <ax-badge\n size=\"sm\"\n look=\"twotone\"\n color=\"success\"\n [text]=\"(i18n + '.linked.badge' | translate | async) ?? ''\"\n ></ax-badge>\n </div>\n\n <div class=\"grid gap-3 md:grid-cols-2\">\n <div>\n <div class=\"text-sm opacity-70\">{{ (i18n + '.fields.provider' | translate | async) ?? '' }}</div>\n <div class=\"font-medium\">{{ link.providerId }}</div>\n </div>\n <!-- ----- Default branch when configured ----- -->\n @if (link.defaultBranch) {\n <div>\n <div class=\"text-sm opacity-70\">{{ (i18n + '.fields.default-branch' | translate | async) ?? '' }}</div>\n <div class=\"font-medium\">{{ link.defaultBranch }}</div>\n </div>\n }\n <div class=\"md:col-span-2\">\n <div class=\"text-sm opacity-70\">{{ (i18n + '.fields.web-url' | translate | async) ?? '' }}</div>\n <a class=\"font-medium text-primary hover:underline\" [href]=\"link.webUrl\" target=\"_blank\" rel=\"noopener noreferrer\">\n {{ link.webUrl }}\n </a>\n </div>\n </div>\n\n <div class=\"flex flex-wrap gap-2\">\n <ax-button\n look=\"outline\"\n color=\"primary\"\n [disabled]=\"linking()\"\n [text]=\"(i18n + '.actions.change' | translate | async) ?? ''\"\n (onClick)=\"onChangeRepository()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-arrow-right-arrow-left\"></ax-icon>\n </ax-prefix>\n </ax-button>\n <ax-button\n look=\"outline\"\n color=\"danger\"\n [disabled]=\"linking()\"\n [text]=\"(i18n + '.actions.unlink' | translate | async) ?? ''\"\n (onClick)=\"onUnlinkRepository()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-link-slash\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n </section>\n\n <axe-repository-commits-panel [projectId]=\"projectId()\" [link]=\"link\"></axe-repository-commits-panel>\n }\n <!-- ----- No provider connection configured ----- -->\n @else if (!hasConnections()) {\n <section class=\"rounded-lg border border-dashed border-surface bg-lighter-surface p-6 text-center\">\n <ax-icon class=\"mb-3 text-3xl opacity-60\">\n <i class=\"fa-light fa-plug-circle-xmark\"></i>\n </ax-icon>\n <div class=\"font-medium\">{{ (i18n + '.empty.no-connection.title' | translate | async) ?? '' }}</div>\n <div class=\"mt-2 text-sm opacity-70\">{{ (i18n + '.empty.no-connection.description' | translate | async) ?? '' }}</div>\n </section>\n }\n <!-- ----- Provider selection step ----- -->\n @else if (step() === 'provider') {\n <section class=\"flex flex-col gap-3\">\n <div class=\"flex flex-wrap items-start justify-between gap-3\">\n <div>\n <div class=\"font-medium\">{{ (i18n + '.steps.provider.title' | translate | async) ?? '' }}</div>\n <div class=\"text-sm opacity-70\">{{ (i18n + '.steps.provider.description' | translate | async) ?? '' }}</div>\n </div>\n <!-- ----- Cancel change when a repository is already linked ----- -->\n @if (selectingNewLink()) {\n <ax-button\n look=\"blank\"\n size=\"sm\"\n [disabled]=\"linking()\"\n [text]=\"(i18n + '.actions.back' | translate | async) ?? ''\"\n (onClick)=\"onCancelChange()\"\n ></ax-button>\n }\n </div>\n\n <div class=\"grid gap-3 md:grid-cols-2\">\n @for (connection of connections(); track connection.id) {\n <button\n type=\"button\"\n class=\"flex items-start gap-3 rounded-lg border border-surface bg-lighter-surface p-4 text-start transition hover:border-primary hover:shadow-sm\"\n [disabled]=\"linking()\"\n (click)=\"onSelectConnection(connection)\"\n >\n <ax-icon class=\"mt-0.5 text-2xl\">\n <i [class]=\"providerIcon(connection)\"></i>\n </ax-icon>\n <div class=\"min-w-0 flex-1\">\n <div class=\"font-medium\">\n @if (providerTitle(connection).startsWith('@')) {\n {{ providerTitle(connection) | translate | async }}\n }\n <!-- ----- Fallback when provider title is a plain display name ----- -->\n @else {\n {{ providerTitle(connection) }}\n }\n </div>\n <div class=\"mt-1 truncate text-sm opacity-70\">\n {{ connection.displayName || connection.providerId }}\n </div>\n </div>\n <ax-icon class=\"opacity-50\">\n <i class=\"fa-light fa-chevron-right\"></i>\n </ax-icon>\n </button>\n }\n </div>\n </section>\n }\n <!-- ----- Repository search and selection step ----- -->\n @else {\n <section class=\"flex flex-col gap-4\">\n <div class=\"flex flex-wrap items-center justify-between gap-3\">\n <div class=\"flex min-w-0 items-center gap-3\">\n <ax-button\n look=\"blank\"\n size=\"sm\"\n [disabled]=\"linking()\"\n [text]=\"(i18n + '.actions.back' | translate | async) ?? ''\"\n (onClick)=\"onBackToProviders()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-arrow-left\"></ax-icon>\n </ax-prefix>\n </ax-button>\n <div class=\"min-w-0\">\n <div class=\"font-medium\">{{ (i18n + '.steps.repositories.title' | translate | async) ?? '' }}</div>\n @if (selectedConnection(); as connection) {\n <div class=\"truncate text-sm opacity-70\">\n @if (providerTitle(connection).startsWith('@')) {\n {{ providerTitle(connection) | translate | async }}\n }\n <!-- ----- Fallback when provider title is a plain display name ----- -->\n @else {\n {{ providerTitle(connection) }}\n }\n · {{ connection.displayName || connection.providerId }}\n </div>\n }\n </div>\n </div>\n </div>\n\n <ax-search-box\n [value]=\"searchQuery()\"\n [disabled]=\"linking()\"\n (valueChange)=\"onSearchChange($event)\"\n [placeholder]=\"(i18n + '.steps.repositories.search-placeholder' | translate | async) ?? ''\"\n ></ax-search-box>\n\n <!-- ----- Repository list loading indicator ----- -->\n @if (reposLoading()) {\n <ax-loading></ax-loading>\n }\n <!-- ----- Empty repository search results ----- -->\n @else if (!repositories().length) {\n <div class=\"rounded-lg border border-dashed border-surface p-6 text-center text-sm opacity-70\">\n {{ (i18n + '.steps.repositories.empty' | translate | async) ?? '' }}\n </div>\n }\n <!-- ----- Repository results ----- -->\n @else {\n <div class=\"flex flex-col gap-2\">\n @for (repo of repositories(); track repo.remoteId) {\n <button\n type=\"button\"\n class=\"flex items-start justify-between gap-3 rounded-lg border border-surface bg-lighter-surface p-4 text-start transition hover:border-primary hover:shadow-sm\"\n [disabled]=\"linking()\"\n (click)=\"onSelectRepository(repo)\"\n >\n <div class=\"min-w-0\">\n <div class=\"font-medium\">{{ repo.fullName }}</div>\n <!-- ----- Repository description when available ----- -->\n @if (repo.description) {\n <div class=\"mt-1 line-clamp-2 text-sm opacity-70\">{{ repo.description }}</div>\n }\n <!-- ----- Default branch metadata ----- -->\n @if (repo.defaultBranch) {\n <div class=\"mt-2 text-xs opacity-60\">\n {{ (i18n + '.fields.default-branch' | translate | async) ?? '' }}: {{ repo.defaultBranch }}\n </div>\n }\n </div>\n <ax-icon class=\"shrink-0 opacity-50\">\n <i class=\"fa-light fa-link\"></i>\n </ax-icon>\n </button>\n }\n </div>\n }\n </section>\n }\n</div>\n"],"names":["I18N","i5","i7"],"mappings":"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"}
@@ -243,7 +243,7 @@ class AXESourceControlPageComponentProvider {
243
243
  return [
244
244
  {
245
245
  key: SOURCE_CONTROL_PAGE_COMPONENT_KEY,
246
- loader: () => import('./acorex-platform-extension-source-control-core-client-source-control-page.component-DOALkPKo.mjs').then((m) => m.AXESourceControlPageComponent),
246
+ loader: () => import('./acorex-platform-extension-source-control-core-client-source-control-page.component-BcNNvSDq.mjs').then((m) => m.AXESourceControlPageComponent),
247
247
  },
248
248
  ];
249
249
  }
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@acorex-platform/extension-source-control-core-client",
3
- "version": "0.0.30",
3
+ "version": "0.0.33",
4
4
  "sideEffects": false,
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0 || ^22.0.0",
7
7
  "@angular/core": "^21.0.0 || ^22.0.0"
8
8
  },
9
9
  "dependencies": {
10
- "@acorex-platform/extension-source-control-core-domain": "0.0.30",
10
+ "@acorex-platform/extension-source-control-core-domain": "0.0.33",
11
11
  "tslib": "^2.3.0"
12
12
  },
13
13
  "module": "fesm2022/acorex-platform-extension-source-control-core-client.mjs",
@@ -1 +0,0 @@
1
- {"version":3,"file":"acorex-platform-extension-source-control-core-client-source-control-page.component-DOALkPKo.mjs","sources":["../../../../libs/extensions/source-control/core/client/src/lib/features/link-repository/source-control-repo-search.client.ts","../../../../libs/extensions/source-control/core/client/src/lib/features/project-management/source-control-project-link.service.ts","../../../../libs/extensions/source-control/core/client/src/lib/features/project-management/repository-commits-panel/source-control-repository-browse.client.ts","../../../../libs/extensions/source-control/core/client/src/lib/features/project-management/repository-commits-panel/source-control-repository-hooks.service.ts","../../../../libs/extensions/source-control/core/client/src/lib/features/project-management/repository-commits-panel/repository-commits-panel.component.ts","../../../../libs/extensions/source-control/core/client/src/lib/features/project-management/repository-commits-panel/repository-commits-panel.component.html","../../../../libs/extensions/source-control/core/client/src/lib/features/project-management/source-control-page/source-control-page.component.ts","../../../../libs/extensions/source-control/core/client/src/lib/features/project-management/source-control-page/source-control-page.component.html"],"sourcesContent":["//#region ----- Imports -----\n\nimport { AXPQueryService } from '@acorex-platform/framework-client/runtime';\nimport { runtimeQueryPayloadData } from '@acorex-platform/framework-shared/core';\nimport {\n AXE_SC_PROVIDER_GITHUB,\n AXE_SC_PROVIDER_GITLAB,\n type AXESourceControlRemoteRepoDto,\n type AXESourceControlSearchReposRequest,\n type AXESourceControlSearchReposResponse,\n} from '@acorex-platform/extension-source-control-core-client/contracts';\nimport { AXEGithubQueryKeys } from '@acorex-platform/extension-github-client/contracts';\nimport { AXEGitLabQueryKeys } from '@acorex-platform/extension-gitlab-client/contracts';\nimport { inject, Injectable } from '@angular/core';\n\n//#endregion\n\n//#region ----- Service -----\n\n@Injectable({ providedIn: 'root' })\nexport class AXESourceControlRepoSearchClient {\n private readonly queryService = inject(AXPQueryService);\n\n async search(input: AXESourceControlSearchReposRequest): Promise<AXESourceControlRemoteRepoDto[]> {\n const key = this.resolveQueryKey(input.providerId);\n const result = await this.queryService.fetch<AXESourceControlSearchReposRequest, AXESourceControlSearchReposResponse>(\n key,\n input,\n );\n return runtimeQueryPayloadData(result)?.items ?? [];\n }\n\n private resolveQueryKey(providerId: string): string {\n if (providerId === AXE_SC_PROVIDER_GITHUB) {\n return AXEGithubQueryKeys.RepoSearch;\n }\n if (providerId === AXE_SC_PROVIDER_GITLAB) {\n return AXEGitLabQueryKeys.RepoSearch;\n }\n throw new Error(`Unsupported source-control provider: ${providerId}`);\n }\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport { AXMIntegrationConnectionManager } from '@acorex-platform/module-integration-management-client';\nimport type { AXMIntegrationManagementIntegrationConnectionEntityModel } from '@acorex-platform/module-integration-management-client/contracts';\nimport { AXPEntityService } from '@acorex-platform/framework-client/layout/entity';\nimport { Injectable, inject } from '@angular/core';\nimport { trim } from 'lodash-es';\nimport {\n AXE_SC_PROVIDER_IDS,\n RootConfig,\n type AXESourceControlProjectSourceControlLinkEntityModel,\n type AXESourceControlRemoteRepoDto,\n} from '@acorex-platform/extension-source-control-core-client/contracts';\nimport { AXESourceControlRepoSearchClient } from '../link-repository/source-control-repo-search.client';\n\n//#endregion\n\n//#region ----- Types -----\n\nexport interface AXESourceControlSaveLinkInput {\n projectId: string;\n connection: AXMIntegrationManagementIntegrationConnectionEntityModel;\n repo: AXESourceControlRemoteRepoDto;\n}\n\n//#endregion\n\n//#region ----- Service -----\n\n@Injectable({ providedIn: 'root' })\nexport class AXESourceControlProjectLinkService {\n //#region ----- Services & Dependencies -----\n\n private readonly connectionManager = inject(AXMIntegrationConnectionManager);\n private readonly entityService = inject(AXPEntityService);\n private readonly repoSearch = inject(AXESourceControlRepoSearchClient);\n\n //#endregion\n\n //#region ----- Connections -----\n\n async listConnections(): Promise<AXMIntegrationManagementIntegrationConnectionEntityModel[]> {\n const connections = await this.connectionManager.listForCurrentUser('tenant');\n return connections.filter(\n (item) =>\n AXE_SC_PROVIDER_IDS.includes(item.providerId as (typeof AXE_SC_PROVIDER_IDS)[number]) &&\n !item.isRevoked &&\n !item.isDisabled,\n );\n }\n\n //#endregion\n\n //#region ----- Link persistence -----\n\n async findLinkByProjectId(projectId: string): Promise<AXESourceControlProjectSourceControlLinkEntityModel | null> {\n const id = trim(projectId);\n if (!id) {\n return null;\n }\n\n const result = await this.entityService\n .withEntity(RootConfig.module.name, RootConfig.entities.projectSourceControlLink.name)\n .data<string, AXESourceControlProjectSourceControlLinkEntityModel>()\n .query({\n skip: 0,\n take: 1,\n filter: {\n field: 'projectId',\n operator: { type: 'equal' },\n value: id,\n },\n });\n\n return result.items?.[0] ?? null;\n }\n\n async saveLink(input: AXESourceControlSaveLinkInput): Promise<AXESourceControlProjectSourceControlLinkEntityModel> {\n const projectId = trim(input.projectId);\n if (!projectId) {\n throw new Error('Project id is required.');\n }\n\n const accessor = this.entityService\n .withEntity(RootConfig.module.name, RootConfig.entities.projectSourceControlLink.name)\n .data<string, AXESourceControlProjectSourceControlLinkEntityModel>();\n\n const existing = await this.findLinkByProjectId(projectId);\n const linkedAt = new Date().toISOString();\n const payload = {\n projectId,\n providerId: input.connection.providerId,\n connectionId: input.connection.id,\n remoteId: input.repo.remoteId,\n fullName: input.repo.fullName,\n webUrl: input.repo.webUrl,\n defaultBranch: input.repo.defaultBranch,\n linkedAt,\n };\n\n if (existing) {\n await accessor.update(existing.id, payload);\n return { ...existing, ...payload };\n }\n\n const createdId = await accessor.create(payload);\n return {\n id: String(createdId),\n ...payload,\n };\n }\n\n async removeLink(projectId: string): Promise<void> {\n const existing = await this.findLinkByProjectId(projectId);\n if (!existing) {\n return;\n }\n\n await this.entityService\n .withEntity(RootConfig.module.name, RootConfig.entities.projectSourceControlLink.name)\n .data<string, AXESourceControlProjectSourceControlLinkEntityModel>()\n .delete(existing.id);\n }\n\n //#endregion\n\n //#region ----- Repository search -----\n\n async searchRepositories(\n connection: AXMIntegrationManagementIntegrationConnectionEntityModel,\n query?: string,\n ): Promise<AXESourceControlRemoteRepoDto[]> {\n return this.repoSearch.search({\n providerId: connection.providerId,\n connectionId: connection.id,\n query: trim(query),\n });\n }\n\n //#endregion\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport { AXEGithubQueryKeys } from '@acorex-platform/extension-github-client/contracts';\nimport { AXEGitLabQueryKeys } from '@acorex-platform/extension-gitlab-client/contracts';\nimport {\n AXE_SC_PROVIDER_GITHUB,\n AXE_SC_PROVIDER_GITLAB,\n type AXESourceControlBranchDto,\n type AXESourceControlCommitDto,\n type AXESourceControlListBranchesRequest,\n type AXESourceControlListBranchesResponse,\n type AXESourceControlListCommitsRequest,\n type AXESourceControlListCommitsResponse,\n type AXESourceControlProjectSourceControlLinkEntityModel,\n} from '@acorex-platform/extension-source-control-core-client/contracts';\nimport { AXPQueryService } from '@acorex-platform/framework-client/runtime';\nimport { runtimeQueryPayloadData } from '@acorex-platform/framework-shared/core';\nimport { inject, Injectable } from '@angular/core';\n\n//#endregion\n\n//#region ----- Service -----\n\n@Injectable({ providedIn: 'root' })\nexport class AXESourceControlRepositoryBrowseClient {\n private readonly queryService = inject(AXPQueryService);\n\n async listBranches(link: AXESourceControlProjectSourceControlLinkEntityModel): Promise<AXESourceControlBranchDto[]> {\n const input: AXESourceControlListBranchesRequest = {\n providerId: link.providerId,\n connectionId: link.connectionId,\n fullName: link.fullName,\n };\n const result = await this.queryService.fetch<AXESourceControlListBranchesRequest, AXESourceControlListBranchesResponse>(this.resolveBranchesQueryKey(link.providerId), input);\n return runtimeQueryPayloadData(result)?.items ?? [];\n }\n\n async listCommits(link: AXESourceControlProjectSourceControlLinkEntityModel, branch: string, take = 30): Promise<AXESourceControlCommitDto[]> {\n const input: AXESourceControlListCommitsRequest = {\n providerId: link.providerId,\n connectionId: link.connectionId,\n fullName: link.fullName,\n branch,\n take,\n };\n const result = await this.queryService.fetch<AXESourceControlListCommitsRequest, AXESourceControlListCommitsResponse>(this.resolveCommitsQueryKey(link.providerId), input);\n return runtimeQueryPayloadData(result)?.items ?? [];\n }\n\n private resolveBranchesQueryKey(providerId: string): string {\n if (providerId === AXE_SC_PROVIDER_GITHUB) {\n return AXEGithubQueryKeys.ListBranches;\n }\n if (providerId === AXE_SC_PROVIDER_GITLAB) {\n return AXEGitLabQueryKeys.ListBranches;\n }\n throw new Error(`Unsupported source-control provider: ${providerId}`);\n }\n\n private resolveCommitsQueryKey(providerId: string): string {\n if (providerId === AXE_SC_PROVIDER_GITHUB) {\n return AXEGithubQueryKeys.ListCommits;\n }\n if (providerId === AXE_SC_PROVIDER_GITLAB) {\n return AXEGitLabQueryKeys.ListCommits;\n }\n throw new Error(`Unsupported source-control provider: ${providerId}`);\n }\n}\n\n//#endregion\n","//#region ----- Imports -----\r\r\n\r\r\nimport { AXPHookService } from '@acorex-platform/framework-client/core';\r\r\nimport type { AXPActionMenuItem } from '@acorex-platform/framework-shared/core';\r\r\nimport {\r\r\n AXESourceControlHookKeys,\r\r\n type AXESourceControlBranchActionsHookPayload,\r\r\n type AXESourceControlCommitActionsHookPayload,\r\r\n type AXESourceControlCommitDto,\r\r\n type AXESourceControlProjectSourceControlLinkEntityModel,\r\r\n} from '@acorex-platform/extension-source-control-core-client/contracts';\r\r\nimport { inject, Injectable } from '@angular/core';\r\r\n\r\r\n//#endregion\r\r\n\r\r\n//#region ----- Service -----\r\r\n\r\r\n@Injectable({ providedIn: 'root' })\r\r\nexport class AXESourceControlRepositoryHooksService {\r\r\n private readonly hooks = inject(AXPHookService);\r\r\n\r\r\n async resolveCommitActions(input: {\r\r\n projectId: string;\r\r\n link: AXESourceControlProjectSourceControlLinkEntityModel;\r\r\n branch: string;\r\r\n commit: AXESourceControlCommitDto;\r\r\n }): Promise<AXPActionMenuItem[]> {\r\r\n const payload: AXESourceControlCommitActionsHookPayload = {\r\r\n projectId: input.projectId,\r\r\n link: input.link,\r\r\n branch: input.branch,\r\r\n commit: input.commit,\r\r\n actions: [],\r\r\n };\r\r\n const result = await this.hooks.runAsync<AXESourceControlCommitActionsHookPayload>(\r\r\n AXESourceControlHookKeys.CommitActions,\r\r\n payload,\r\r\n );\r\r\n return result?.actions ?? [];\r\r\n }\r\r\n\r\r\n async resolveBranchActions(input: {\r\r\n projectId: string;\r\r\n link: AXESourceControlProjectSourceControlLinkEntityModel;\r\r\n branch: string;\r\r\n baseBranch: string;\r\r\n }): Promise<AXPActionMenuItem[]> {\r\r\n const payload: AXESourceControlBranchActionsHookPayload = {\r\r\n projectId: input.projectId,\r\r\n link: input.link,\r\r\n branch: input.branch,\r\r\n baseBranch: input.baseBranch,\r\r\n actions: [],\r\r\n };\r\r\n const result = await this.hooks.runAsync<AXESourceControlBranchActionsHookPayload>(\r\r\n AXESourceControlHookKeys.BranchActions,\r\r\n payload,\r\r\n );\r\r\n return result?.actions ?? [];\r\r\n }\r\r\n}\r\r\n\r\r\n//#endregion\r\r\n","//#region ----- Imports -----\n\n\n\nimport { AsyncPipe } from '@angular/common';\n\nimport {\n\n ChangeDetectionStrategy,\n\n Component,\n\n computed,\n\n effect,\n\n inject,\n\n input,\n\n signal,\n\n untracked,\n\n} from '@angular/core';\n\nimport { FormsModule } from '@angular/forms';\n\nimport { AXBadgeModule } from '@acorex/components/badge';\n\nimport { AXButtonModule } from '@acorex/components/button';\n\nimport { AXDecoratorModule } from '@acorex/components/decorators';\n\nimport { AXLoadingModule } from '@acorex/components/loading';\n\nimport { AXSelectBoxModule } from '@acorex/components/select-box';\n\nimport { AXTranslationModule } from '@acorex/core/translation';\n\nimport { AXPSettingsService } from '@acorex-platform/framework-client/common';\n\nimport { AXPStateMessageComponent } from '@acorex-platform/framework-client/layout/components';\n\nimport { AXPCommandExecutor } from '@acorex-platform/framework-client/runtime';\n\nimport type { AXPActionMenuItem } from '@acorex-platform/framework-shared/core';\n\nimport { AXPRegionalSetting } from '@acorex-platform/framework-shared/core';\n\nimport type {\n\n AXESourceControlBranchDto,\n\n AXESourceControlCommitDto,\n\n AXESourceControlProjectSourceControlLinkEntityModel,\n\n} from '@acorex-platform/extension-source-control-core-client/contracts';\n\nimport { AXFormatService } from '@acorex/core/format';\n\nimport { defaultTo, trim } from 'lodash-es';\n\nimport { AXESourceControlRepositoryBrowseClient } from './source-control-repository-browse.client';\n\nimport { AXESourceControlRepositoryHooksService } from './source-control-repository-hooks.service';\n\n\n\n//#endregion\n\n\n\n//#region ----- Constants -----\n\n\n\nconst I18N = '@extensions-source-control:pages.repository.commits';\n\n\n\n//#endregion\n\n\n\n//#region ----- Component -----\n\n\n\n@Component({\n\n selector: 'axe-repository-commits-panel',\n\n templateUrl: './repository-commits-panel.component.html',\n\n imports: [\n\n AsyncPipe,\n\n FormsModule,\n\n AXBadgeModule,\n\n AXButtonModule,\n\n AXDecoratorModule,\n\n AXLoadingModule,\n\n AXSelectBoxModule,\n\n AXTranslationModule,\n\n AXPStateMessageComponent,\n\n ],\n\n changeDetection: ChangeDetectionStrategy.OnPush,\n\n})\n\nexport class AXERepositoryCommitsPanelComponent {\n\n //#region ----- Inputs -----\n\n\n\n projectId = input.required<string>();\n\n link = input.required<AXESourceControlProjectSourceControlLinkEntityModel>();\n\n\n\n //#endregion\n\n\n\n //#region ----- Services & Dependencies -----\n\n\n\n protected readonly i18n = I18N;\n\n private readonly browseClient = inject(AXESourceControlRepositoryBrowseClient);\n\n private readonly hooksService = inject(AXESourceControlRepositoryHooksService);\n\n private readonly commandExecutor = inject(AXPCommandExecutor);\n\n private readonly settingsService = inject(AXPSettingsService);\n\n private readonly formatService = inject(AXFormatService);\n\n\n\n //#endregion\n\n\n\n //#region ----- State Signals -----\n\n\n\n protected readonly loading = signal(false);\n\n protected readonly branches = signal<AXESourceControlBranchDto[]>([]);\n\n protected readonly selectedBranch = signal('');\n\n protected readonly commits = signal<AXESourceControlCommitDto[]>([]);\n\n protected readonly branchActions = signal<AXPActionMenuItem[]>([]);\n\n protected readonly commitActionsBySha = signal<Record<string, AXPActionMenuItem[]>>({});\n\n private readonly datetimeFormat = signal('');\n\n\n\n //#endregion\n\n\n\n //#region ----- Computed Properties -----\n\n\n\n protected readonly baseBranch = computed(() => {\n\n const link = this.link();\n\n const defaultBranch = trim(link.defaultBranch ?? '');\n\n if (defaultBranch) {\n\n return defaultBranch;\n\n }\n\n const branches = this.branches();\n\n const markedDefault = branches.find((branch) => branch.isDefault)?.name;\n\n return markedDefault ?? branches[0]?.name ?? 'main';\n\n });\n\n\n\n protected readonly branchOptions = computed(() =>\n\n this.branches().map((branch) => ({\n\n name: branch.name,\n\n title: branch.name,\n\n })),\n\n );\n\n\n\n //#endregion\n\n\n\n //#region ----- Lifecycle -----\n\n\n\n constructor() {\n\n effect(() => {\n\n const link = this.link();\n\n const projectId = trim(this.projectId());\n\n if (!link || !projectId) {\n\n return;\n\n }\n\n untracked(() => {\n\n void this.initialize(link, projectId);\n\n });\n\n });\n\n\n\n effect(() => {\n\n const link = this.link();\n\n const projectId = trim(this.projectId());\n\n const branch = trim(this.selectedBranch());\n\n if (!link || !projectId || !branch) {\n\n return;\n\n }\n\n untracked(() => {\n\n void this.loadBranchData(link, projectId, branch);\n\n });\n\n });\n\n }\n\n\n\n //#endregion\n\n\n\n //#region ----- Event Handlers -----\n\n\n\n protected onBranchChange(branch: string | null | undefined): void {\n\n this.selectedBranch.set(trim(branch ?? ''));\n\n }\n\n\n\n protected commitActions(sha: string): AXPActionMenuItem[] {\n\n return this.commitActionsBySha()[sha] ?? [];\n\n }\n\n\n\n protected commitMessage(commit: AXESourceControlCommitDto): string {\n\n const message = trim(commit.message);\n\n if (!message) {\n\n return '—';\n\n }\n\n const firstLine = message.split('\\n')[0]?.trim();\n\n return firstLine || message;\n\n }\n\n\n\n protected formatCommittedAt(value: string): string {\n\n const iso = trim(value);\n\n if (!iso) {\n\n return '—';\n\n }\n\n const format = this.datetimeFormat();\n\n if (!format) {\n\n return iso;\n\n }\n\n return this.formatService.format(new Date(iso), 'datetime', { format });\n\n }\n\n\n\n protected actionTextKey(action: AXPActionMenuItem): string {\n\n const title = action.title;\n\n return typeof title === 'string' ? title : '';\n\n }\n\n\n\n protected async onActionClick(action: AXPActionMenuItem): Promise<void> {\n\n const command = action.command;\n\n if (!command?.name) {\n\n return;\n\n }\n\n await this.commandExecutor.execute(command.name, command.options ?? {});\n\n }\n\n\n\n protected onViewCommit(commit: AXESourceControlCommitDto): void {\n\n const url = trim(commit.webUrl);\n\n if (url) {\n\n window.open(url, '_blank', 'noopener,noreferrer');\n\n }\n\n }\n\n\n\n //#endregion\n\n\n\n //#region ----- Data Loading -----\n\n\n\n private async initialize(\n\n link: AXESourceControlProjectSourceControlLinkEntityModel,\n\n projectId: string,\n\n ): Promise<void> {\n\n this.loading.set(true);\n\n try {\n\n await this.loadDatetimeFormat();\n\n const branches = await this.browseClient.listBranches(link);\n\n this.branches.set(branches);\n\n const initialBranch = this.resolveInitialBranch(link, branches);\n\n this.selectedBranch.set(initialBranch);\n\n if (!initialBranch) {\n\n this.commits.set([]);\n\n this.branchActions.set([]);\n\n this.commitActionsBySha.set({});\n\n }\n\n } catch (error: unknown) {\n\n this.handleError(error, 'Failed to load repository branches.');\n\n this.branches.set([]);\n\n this.selectedBranch.set('');\n\n } finally {\n\n this.loading.set(false);\n\n }\n\n }\n\n\n\n private async loadBranchData(\n\n link: AXESourceControlProjectSourceControlLinkEntityModel,\n\n projectId: string,\n\n branch: string,\n\n ): Promise<void> {\n\n this.loading.set(true);\n\n try {\n\n const [commits, branchActions] = await Promise.all([\n\n this.browseClient.listCommits(link, branch),\n\n this.hooksService.resolveBranchActions({\n\n projectId,\n\n link,\n\n branch,\n\n baseBranch: this.baseBranch(),\n\n }),\n\n ]);\n\n this.commits.set(commits);\n\n this.branchActions.set(branchActions);\n\n const commitActionsEntries = await Promise.all(\n\n commits.map(async (commit) => {\n\n const actions = await this.hooksService.resolveCommitActions({\n\n projectId,\n\n link,\n\n branch,\n\n commit,\n\n });\n\n return [commit.sha, actions] as const;\n\n }),\n\n );\n\n this.commitActionsBySha.set(Object.fromEntries(commitActionsEntries));\n\n } catch (error: unknown) {\n\n this.handleError(error, 'Failed to load repository commits.');\n\n this.commits.set([]);\n\n this.branchActions.set([]);\n\n this.commitActionsBySha.set({});\n\n } finally {\n\n this.loading.set(false);\n\n }\n\n }\n\n\n\n private resolveInitialBranch(\n\n link: AXESourceControlProjectSourceControlLinkEntityModel,\n\n branches: AXESourceControlBranchDto[],\n\n ): string {\n\n const preferred = trim(link.defaultBranch ?? '');\n\n if (preferred && branches.some((branch) => branch.name === preferred)) {\n\n return preferred;\n\n }\n\n const markedDefault = branches.find((branch) => branch.isDefault)?.name;\n\n if (markedDefault) {\n\n return markedDefault;\n\n }\n\n return defaultTo(branches[0]?.name, '');\n\n }\n\n\n\n private async loadDatetimeFormat(): Promise<void> {\n\n const dateFormat = await this.settingsService.get(AXPRegionalSetting.ShortDate);\n\n const timeFormat = await this.settingsService.get(AXPRegionalSetting.ShortTime);\n\n this.datetimeFormat.set(`${dateFormat} ${timeFormat}`.trim());\n\n }\n\n\n\n private handleError(error: unknown, fallback: string): void {\n\n const message = error instanceof Error ? error.message : fallback;\n\n console.error(message, error);\n\n }\n\n\n\n //#endregion\n\n}\n\n\n\n//#endregion\n\n","<section class=\"flex flex-col gap-4 rounded-lg border border-surface bg-lighter-surface p-4\">\n\n <div class=\"flex flex-wrap items-start justify-between gap-3\">\n\n <div>\n\n <div class=\"font-medium\">{{ (i18n + '.title' | translate | async) ?? '' }}</div>\n\n <div class=\"text-sm opacity-70\">{{ (i18n + '.description' | translate | async) ?? '' }}</div>\n\n </div>\n\n <!-- ----- Branch filter ----- -->\n\n @if (branchOptions().length) {\n\n <ax-select-box\n\n class=\"min-w-[12rem]\"\n\n [dataSource]=\"branchOptions()\"\n\n [ngModel]=\"selectedBranch()\"\n\n (ngModelChange)=\"onBranchChange($event)\"\n\n valueField=\"name\"\n\n textField=\"title\"\n\n [placeholder]=\"(i18n + '.branch.placeholder' | translate | async) ?? ''\"\n\n ></ax-select-box>\n\n }\n\n </div>\n\n\n\n <!-- ----- Branch-level hook actions ----- -->\n\n @if (branchActions().length) {\n\n <div class=\"flex flex-wrap gap-2\">\n\n @for (action of branchActions(); track action.name ?? action.title) {\n\n <ax-button\n\n look=\"outline\"\n\n color=\"primary\"\n\n size=\"sm\"\n\n [text]=\"(actionTextKey(action) | translate | async) ?? ''\"\n\n (onClick)=\"onActionClick(action)\"\n\n >\n\n @if (action.icon) {\n\n <ax-prefix>\n\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n\n </ax-prefix>\n\n }\n\n </ax-button>\n\n }\n\n </div>\n\n }\n\n\n\n <!-- ----- Commits loading indicator ----- -->\n\n @if (loading()) {\n\n <ax-loading></ax-loading>\n\n }\n\n <!-- ----- Empty commits state ----- -->\n\n @else if (!commits().length) {\n\n <axp-state-message\n\n icon=\"fa-light fa-code-commit\"\n\n [title]=\"i18n + '.empty.title'\"\n\n [description]=\"i18n + '.empty.description'\"\n\n look=\"minimal\"\n\n ></axp-state-message>\n\n }\n\n <!-- ----- Commits list ----- -->\n\n @else {\n\n <div class=\"flex flex-col gap-2\">\n\n @for (commit of commits(); track commit.sha) {\n\n <article class=\"flex flex-wrap items-start justify-between gap-3 rounded-lg border border-surface bg-surface p-3\">\n\n <div class=\"min-w-0 flex-1\">\n\n <div class=\"flex flex-wrap items-center gap-2\">\n\n <ax-badge\n\n size=\"sm\"\n\n look=\"twotone\"\n\n color=\"primary\"\n\n [text]=\"commit.shortSha ?? commit.sha.slice(0, 7)\"\n\n ></ax-badge>\n\n <span class=\"font-medium\">{{ commitMessage(commit) }}</span>\n\n </div>\n\n <div class=\"mt-1 flex flex-wrap gap-x-4 gap-y-1 text-sm opacity-70\">\n\n <span>{{ commit.authorName }}</span>\n\n <span>{{ formatCommittedAt(commit.committedAt) }}</span>\n\n </div>\n\n </div>\n\n <div class=\"flex shrink-0 flex-wrap items-center gap-2\">\n\n <ax-button\n\n look=\"blank\"\n\n size=\"sm\"\n\n [text]=\"(i18n + '.actions.view' | translate | async) ?? ''\"\n\n (onClick)=\"onViewCommit(commit)\"\n\n >\n\n <ax-prefix>\n\n <ax-icon icon=\"fa-light fa-arrow-up-right-from-square\"></ax-icon>\n\n </ax-prefix>\n\n </ax-button>\n\n <!-- ----- Commit-level hook actions ----- -->\n\n @for (action of commitActions(commit.sha); track action.name ?? action.title) {\n\n <ax-button\n\n look=\"outline\"\n\n size=\"sm\"\n\n color=\"primary\"\n\n [text]=\"(actionTextKey(action) | translate | async) ?? ''\"\n\n (onClick)=\"onActionClick(action)\"\n\n >\n\n @if (action.icon) {\n\n <ax-prefix>\n\n <ax-icon [icon]=\"action.icon\"></ax-icon>\n\n </ax-prefix>\n\n }\n\n </ax-button>\n\n }\n\n </div>\n\n </article>\n\n }\n\n </div>\n\n }\n\n</section>\n\n","//#region ----- Imports -----\n\nimport { CommonModule } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n inject,\n input,\n OnDestroy,\n signal,\n untracked,\n} from '@angular/core';\nimport { AXBadgeModule } from '@acorex/components/badge';\nimport { AXButtonModule } from '@acorex/components/button';\nimport { AXDecoratorModule } from '@acorex/components/decorators';\nimport { AXDialogService } from '@acorex/components/dialog';\nimport { AXLoadingModule } from '@acorex/components/loading';\nimport { AXSearchBoxModule } from '@acorex/components/search-box';\nimport { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';\nimport { AXPPageLayoutBase, AXPPageLayoutBaseComponent } from '@acorex-platform/framework-client/layout/views';\nimport {\n AXE_SC_PROVIDER_GITHUB,\n AXE_SC_PROVIDER_GITLAB,\n type AXESourceControlProjectSourceControlLinkEntityModel,\n type AXESourceControlRemoteRepoDto,\n} from '@acorex-platform/extension-source-control-core-client/contracts';\nimport type { AXMIntegrationManagementIntegrationConnectionEntityModel } from '@acorex-platform/module-integration-management-client/contracts';\nimport { defaultTo, trim } from 'lodash-es';\nimport { AXESourceControlProjectLinkService } from '../source-control-project-link.service';\nimport { AXERepositoryCommitsPanelComponent } from '../repository-commits-panel/repository-commits-panel.component';\n\n//#endregion\n\n//#region ----- Types -----\n\ntype SourceControlPageStep = 'provider' | 'repositories';\n\ninterface ProviderPresentation {\n providerId: string;\n icon: string;\n titleKey: string;\n}\n\n//#endregion\n\n//#region ----- Constants -----\n\nconst I18N = '@extensions-source-control:pages.repository';\n\nconst PROVIDER_PRESENTATION: Record<string, ProviderPresentation> = {\n [AXE_SC_PROVIDER_GITHUB]: {\n providerId: AXE_SC_PROVIDER_GITHUB,\n icon: 'fa-brands fa-github',\n titleKey: '@extensions-github:integration.display-name',\n },\n [AXE_SC_PROVIDER_GITLAB]: {\n providerId: AXE_SC_PROVIDER_GITLAB,\n icon: 'fa-brands fa-gitlab',\n titleKey: '@extensions-gitlab:integration.display-name',\n },\n};\n\n//#endregion\n\n//#region ----- Component -----\n\n@Component({\n selector: 'axe-source-control-page',\n templateUrl: './source-control-page.component.html',\n imports: [\n CommonModule,\n AXBadgeModule,\n AXButtonModule,\n AXDecoratorModule,\n AXLoadingModule,\n AXSearchBoxModule,\n AXTranslationModule,\n AXERepositoryCommitsPanelComponent,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: AXPPageLayoutBase,\n useExisting: AXESourceControlPageComponent,\n },\n ],\n})\nexport class AXESourceControlPageComponent extends AXPPageLayoutBaseComponent implements OnDestroy {\n //#region ----- Inputs -----\n\n rootContext = input<Record<string, unknown>>({});\n pageConfig = input<Record<string, unknown>>();\n\n //#endregion\n\n //#region ----- Services & Dependencies -----\n\n protected readonly i18n = I18N;\n private readonly linkService = inject(AXESourceControlProjectLinkService);\n private readonly dialogService = inject(AXDialogService);\n private readonly translationService = inject(AXTranslationService);\n\n //#endregion\n\n //#region ----- State Signals -----\n\n protected readonly loading = signal(true);\n protected readonly linking = signal(false);\n protected readonly reposLoading = signal(false);\n protected readonly step = signal<SourceControlPageStep>('provider');\n protected readonly connections = signal<AXMIntegrationManagementIntegrationConnectionEntityModel[]>([]);\n protected readonly selectedConnection = signal<AXMIntegrationManagementIntegrationConnectionEntityModel | null>(null);\n protected readonly repositories = signal<AXESourceControlRemoteRepoDto[]>([]);\n protected readonly searchQuery = signal('');\n protected readonly existingLink = signal<AXESourceControlProjectSourceControlLinkEntityModel | null>(null);\n protected readonly selectingNewLink = signal(false);\n\n //#endregion\n\n //#region ----- Computed Properties -----\n\n protected readonly projectId = computed(() => {\n const id = this.rootContext()?.['id'];\n return typeof id === 'string' ? trim(id) : '';\n });\n\n protected readonly hasConnections = computed(() => this.connections().length > 0);\n\n protected readonly showLinkedSummary = computed(() => Boolean(this.existingLink()) && !this.selectingNewLink());\n\n protected readonly linkedRepository = computed(() => (this.showLinkedSummary() ? this.existingLink() : null));\n\n //#endregion\n\n //#region ----- Lifecycle -----\n\n private searchDebounce?: ReturnType<typeof setTimeout>;\n\n constructor() {\n super();\n effect(() => {\n const projectId = this.projectId();\n if (!projectId) {\n return;\n }\n untracked(() => {\n void this.initialize(projectId);\n });\n });\n }\n\n ngOnDestroy(): void {\n clearTimeout(this.searchDebounce);\n }\n\n //#endregion\n\n //#region ----- Event Handlers -----\n\n protected providerTitle(connection: AXMIntegrationManagementIntegrationConnectionEntityModel): string {\n const presentation = PROVIDER_PRESENTATION[connection.providerId];\n if (presentation?.titleKey) {\n return presentation.titleKey;\n }\n return defaultTo(connection.displayName, connection.providerId);\n }\n\n protected providerIcon(connection: AXMIntegrationManagementIntegrationConnectionEntityModel): string {\n return PROVIDER_PRESENTATION[connection.providerId]?.icon ?? 'fa-light fa-code-branch';\n }\n\n protected async onSelectConnection(connection: AXMIntegrationManagementIntegrationConnectionEntityModel): Promise<void> {\n this.selectedConnection.set(connection);\n this.step.set('repositories');\n this.searchQuery.set('');\n await this.loadRepositories();\n }\n\n protected onBackToProviders(): void {\n if (this.existingLink()) {\n this.onCancelChange();\n return;\n }\n this.step.set('provider');\n this.selectedConnection.set(null);\n this.repositories.set([]);\n this.searchQuery.set('');\n }\n\n protected onSearchChange(value: string | null | undefined): void {\n this.searchQuery.set(value ?? '');\n clearTimeout(this.searchDebounce);\n this.searchDebounce = setTimeout(() => {\n void this.loadRepositories();\n }, 350);\n }\n\n protected async onSelectRepository(repo: AXESourceControlRemoteRepoDto): Promise<void> {\n const connection = this.selectedConnection();\n const projectId = this.projectId();\n if (!connection || !projectId) {\n return;\n }\n\n const confirmed = await this.confirmLink(repo);\n if (!confirmed) {\n return;\n }\n\n this.linking.set(true);\n try {\n const link = await this.linkService.saveLink({ projectId, connection, repo });\n this.existingLink.set(link);\n this.selectingNewLink.set(false);\n this.step.set('provider');\n this.selectedConnection.set(null);\n this.repositories.set([]);\n this.searchQuery.set('');\n await this.showLinkedToast(repo.fullName);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to link repository.';\n this.toastService.show({ color: 'danger', content: message });\n } finally {\n this.linking.set(false);\n }\n }\n\n protected async onChangeRepository(): Promise<void> {\n this.selectingNewLink.set(true);\n this.step.set('provider');\n this.selectedConnection.set(null);\n this.repositories.set([]);\n this.searchQuery.set('');\n }\n\n protected onCancelChange(): void {\n this.selectingNewLink.set(false);\n this.step.set('provider');\n this.selectedConnection.set(null);\n this.repositories.set([]);\n this.searchQuery.set('');\n }\n\n protected async onUnlinkRepository(): Promise<void> {\n const link = this.existingLink();\n const projectId = this.projectId();\n if (!link || !projectId) {\n return;\n }\n\n const confirmed = await this.confirmUnlink(link.fullName);\n if (!confirmed) {\n return;\n }\n\n this.linking.set(true);\n try {\n await this.linkService.removeLink(projectId);\n this.existingLink.set(null);\n this.step.set('provider');\n const message = await this.translationService.translateAsync(`${I18N}.messages.unlinked`);\n this.toastService.show({ color: 'success', content: message ?? 'Repository unlinked.' });\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to unlink repository.';\n this.toastService.show({ color: 'danger', content: message });\n } finally {\n this.linking.set(false);\n }\n }\n\n //#endregion\n\n //#region ----- Data Loading -----\n\n private async initialize(projectId: string): Promise<void> {\n this.loading.set(true);\n try {\n const [connections, link] = await Promise.all([\n this.linkService.listConnections(),\n this.linkService.findLinkByProjectId(projectId),\n ]);\n this.connections.set(connections);\n this.existingLink.set(link);\n if (!link) {\n this.step.set('provider');\n }\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to load source-control data.';\n this.toastService.show({ color: 'danger', content: message });\n } finally {\n this.loading.set(false);\n }\n }\n\n private async loadRepositories(): Promise<void> {\n const connection = this.selectedConnection();\n if (!connection) {\n this.repositories.set([]);\n return;\n }\n\n this.reposLoading.set(true);\n try {\n const items = await this.linkService.searchRepositories(connection, this.searchQuery());\n this.repositories.set(items);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to search repositories.';\n this.toastService.show({ color: 'danger', content: message });\n this.repositories.set([]);\n } finally {\n this.reposLoading.set(false);\n }\n }\n\n //#endregion\n\n //#region ----- Dialogs -----\n\n private async confirmLink(repo: AXESourceControlRemoteRepoDto): Promise<boolean> {\n const title = await this.translationService.translateAsync(`${I18N}.dialogs.link.title`);\n const message = await this.translationService.translateAsync(`${I18N}.dialogs.link.message`, {\n params: { fullName: repo.fullName },\n });\n return Boolean(await this.dialogService.confirm(title ?? 'Link Repository', message ?? 'Link this repository?'));\n }\n\n private async confirmUnlink(fullName: string): Promise<boolean> {\n const title = await this.translationService.translateAsync(`${I18N}.dialogs.unlink.title`);\n const message = await this.translationService.translateAsync(`${I18N}.dialogs.unlink.message`, {\n params: { fullName },\n });\n return Boolean(await this.dialogService.confirm(title ?? 'Unlink Repository', message ?? 'Unlink this repository?'));\n }\n\n private async showLinkedToast(fullName: string): Promise<void> {\n const message = await this.translationService.translateAsync(`${I18N}.messages.linked`, {\n params: { fullName },\n });\n this.toastService.show({ color: 'success', content: message ?? 'Repository linked.' });\n }\n\n //#endregion\n}\n\n//#endregion\n","<div class=\"flex w-full flex-col gap-4\">\n <!-- ----- Loading indicator while page data is fetched ----- -->\n @if (loading()) {\n <ax-loading></ax-loading>\n }\n <!-- ----- Linked repository summary ----- -->\n @else if (linkedRepository(); as link) {\n <section class=\"flex flex-col gap-4 rounded-lg border border-surface bg-lighter-surface p-4\">\n <div class=\"flex flex-wrap items-start justify-between gap-3\">\n <div class=\"min-w-0\">\n <div class=\"text-sm opacity-70\">\n {{ (i18n + '.linked.summary' | translate | async) ?? '' }}\n </div>\n <div class=\"mt-1 text-lg font-medium\">{{ link.fullName }}</div>\n </div>\n <ax-badge\n size=\"sm\"\n look=\"twotone\"\n color=\"success\"\n [text]=\"(i18n + '.linked.badge' | translate | async) ?? ''\"\n ></ax-badge>\n </div>\n\n <div class=\"grid gap-3 md:grid-cols-2\">\n <div>\n <div class=\"text-sm opacity-70\">{{ (i18n + '.fields.provider' | translate | async) ?? '' }}</div>\n <div class=\"font-medium\">{{ link.providerId }}</div>\n </div>\n <!-- ----- Default branch when configured ----- -->\n @if (link.defaultBranch) {\n <div>\n <div class=\"text-sm opacity-70\">{{ (i18n + '.fields.default-branch' | translate | async) ?? '' }}</div>\n <div class=\"font-medium\">{{ link.defaultBranch }}</div>\n </div>\n }\n <div class=\"md:col-span-2\">\n <div class=\"text-sm opacity-70\">{{ (i18n + '.fields.web-url' | translate | async) ?? '' }}</div>\n <a class=\"font-medium text-primary hover:underline\" [href]=\"link.webUrl\" target=\"_blank\" rel=\"noopener noreferrer\">\n {{ link.webUrl }}\n </a>\n </div>\n </div>\n\n <div class=\"flex flex-wrap gap-2\">\n <ax-button\n look=\"outline\"\n color=\"primary\"\n [disabled]=\"linking()\"\n [text]=\"(i18n + '.actions.change' | translate | async) ?? ''\"\n (onClick)=\"onChangeRepository()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-arrow-right-arrow-left\"></ax-icon>\n </ax-prefix>\n </ax-button>\n <ax-button\n look=\"outline\"\n color=\"danger\"\n [disabled]=\"linking()\"\n [text]=\"(i18n + '.actions.unlink' | translate | async) ?? ''\"\n (onClick)=\"onUnlinkRepository()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-link-slash\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n </section>\n\n <axe-repository-commits-panel [projectId]=\"projectId()\" [link]=\"link\"></axe-repository-commits-panel>\n }\n <!-- ----- No provider connection configured ----- -->\n @else if (!hasConnections()) {\n <section class=\"rounded-lg border border-dashed border-surface bg-lighter-surface p-6 text-center\">\n <ax-icon class=\"mb-3 text-3xl opacity-60\">\n <i class=\"fa-light fa-plug-circle-xmark\"></i>\n </ax-icon>\n <div class=\"font-medium\">{{ (i18n + '.empty.no-connection.title' | translate | async) ?? '' }}</div>\n <div class=\"mt-2 text-sm opacity-70\">{{ (i18n + '.empty.no-connection.description' | translate | async) ?? '' }}</div>\n </section>\n }\n <!-- ----- Provider selection step ----- -->\n @else if (step() === 'provider') {\n <section class=\"flex flex-col gap-3\">\n <div class=\"flex flex-wrap items-start justify-between gap-3\">\n <div>\n <div class=\"font-medium\">{{ (i18n + '.steps.provider.title' | translate | async) ?? '' }}</div>\n <div class=\"text-sm opacity-70\">{{ (i18n + '.steps.provider.description' | translate | async) ?? '' }}</div>\n </div>\n <!-- ----- Cancel change when a repository is already linked ----- -->\n @if (selectingNewLink()) {\n <ax-button\n look=\"blank\"\n size=\"sm\"\n [disabled]=\"linking()\"\n [text]=\"(i18n + '.actions.back' | translate | async) ?? ''\"\n (onClick)=\"onCancelChange()\"\n ></ax-button>\n }\n </div>\n\n <div class=\"grid gap-3 md:grid-cols-2\">\n @for (connection of connections(); track connection.id) {\n <button\n type=\"button\"\n class=\"flex items-start gap-3 rounded-lg border border-surface bg-lighter-surface p-4 text-start transition hover:border-primary hover:shadow-sm\"\n [disabled]=\"linking()\"\n (click)=\"onSelectConnection(connection)\"\n >\n <ax-icon class=\"mt-0.5 text-2xl\">\n <i [class]=\"providerIcon(connection)\"></i>\n </ax-icon>\n <div class=\"min-w-0 flex-1\">\n <div class=\"font-medium\">\n @if (providerTitle(connection).startsWith('@')) {\n {{ providerTitle(connection) | translate | async }}\n }\n <!-- ----- Fallback when provider title is a plain display name ----- -->\n @else {\n {{ providerTitle(connection) }}\n }\n </div>\n <div class=\"mt-1 truncate text-sm opacity-70\">\n {{ connection.displayName || connection.providerId }}\n </div>\n </div>\n <ax-icon class=\"opacity-50\">\n <i class=\"fa-light fa-chevron-right\"></i>\n </ax-icon>\n </button>\n }\n </div>\n </section>\n }\n <!-- ----- Repository search and selection step ----- -->\n @else {\n <section class=\"flex flex-col gap-4\">\n <div class=\"flex flex-wrap items-center justify-between gap-3\">\n <div class=\"flex min-w-0 items-center gap-3\">\n <ax-button\n look=\"blank\"\n size=\"sm\"\n [disabled]=\"linking()\"\n [text]=\"(i18n + '.actions.back' | translate | async) ?? ''\"\n (onClick)=\"onBackToProviders()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-arrow-left\"></ax-icon>\n </ax-prefix>\n </ax-button>\n <div class=\"min-w-0\">\n <div class=\"font-medium\">{{ (i18n + '.steps.repositories.title' | translate | async) ?? '' }}</div>\n @if (selectedConnection(); as connection) {\n <div class=\"truncate text-sm opacity-70\">\n @if (providerTitle(connection).startsWith('@')) {\n {{ providerTitle(connection) | translate | async }}\n }\n <!-- ----- Fallback when provider title is a plain display name ----- -->\n @else {\n {{ providerTitle(connection) }}\n }\n · {{ connection.displayName || connection.providerId }}\n </div>\n }\n </div>\n </div>\n </div>\n\n <ax-search-box\n [value]=\"searchQuery()\"\n [disabled]=\"linking()\"\n (valueChange)=\"onSearchChange($event)\"\n [placeholder]=\"(i18n + '.steps.repositories.search-placeholder' | translate | async) ?? ''\"\n ></ax-search-box>\n\n <!-- ----- Repository list loading indicator ----- -->\n @if (reposLoading()) {\n <ax-loading></ax-loading>\n }\n <!-- ----- Empty repository search results ----- -->\n @else if (!repositories().length) {\n <div class=\"rounded-lg border border-dashed border-surface p-6 text-center text-sm opacity-70\">\n {{ (i18n + '.steps.repositories.empty' | translate | async) ?? '' }}\n </div>\n }\n <!-- ----- Repository results ----- -->\n @else {\n <div class=\"flex flex-col gap-2\">\n @for (repo of repositories(); track repo.remoteId) {\n <button\n type=\"button\"\n class=\"flex items-start justify-between gap-3 rounded-lg border border-surface bg-lighter-surface p-4 text-start transition hover:border-primary hover:shadow-sm\"\n [disabled]=\"linking()\"\n (click)=\"onSelectRepository(repo)\"\n >\n <div class=\"min-w-0\">\n <div class=\"font-medium\">{{ repo.fullName }}</div>\n <!-- ----- Repository description when available ----- -->\n @if (repo.description) {\n <div class=\"mt-1 line-clamp-2 text-sm opacity-70\">{{ repo.description }}</div>\n }\n <!-- ----- Default branch metadata ----- -->\n @if (repo.defaultBranch) {\n <div class=\"mt-2 text-xs opacity-60\">\n {{ (i18n + '.fields.default-branch' | translate | async) ?? '' }}: {{ repo.defaultBranch }}\n </div>\n }\n </div>\n <ax-icon class=\"shrink-0 opacity-50\">\n <i class=\"fa-light fa-link\"></i>\n </ax-icon>\n </button>\n }\n </div>\n }\n </section>\n }\n</div>\n"],"names":["I18N","i2","i3","i4","i5","i6"],"mappings":"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"}