@acorex-platform/extension-project-management-jira-client 2.0.0-next.2 → 2.0.0-next.21

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,355 +0,0 @@
1
- import { resolveMultiLanguageString, AXP_INTEGRATION_AUTH_METHOD_TYPE, runtimeCommandPayloadData } from '@acorex-platform/framework-shared/core';
2
- import { AXMIntegrationManagementCommandKeys } from '@acorex-platform/module-integration-management-client/contracts';
3
- import { AXPSessionService } from '@acorex-platform/framework-client/auth';
4
- import { AXPLayoutBuilderService, resolveLayoutBuilderDialogResult } from '@acorex-platform/framework-client/layout/builder';
5
- import { AXPEntityService } from '@acorex-platform/framework-client/layout/entity';
6
- import { AXPCommandService } from '@acorex-platform/framework-client/runtime';
7
- import { AXPopupService } from '@acorex/components/popup';
8
- import { AXPDialogOpener } from '@acorex-platform/framework-client/core';
9
- import * as i6 from '@acorex/core/translation';
10
- import { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';
11
- import * as i0 from '@angular/core';
12
- import { ChangeDetectionStrategy, Component, inject, Injectable } from '@angular/core';
13
- import { defaultTo, trim } from 'lodash-es';
14
- import { RootConfig } from '@acorex-platform/extension-project-management-jira-client/contracts';
15
- import * as i2 from '@acorex/components/button';
16
- import { AXButtonModule } from '@acorex/components/button';
17
- import * as i4 from '@acorex/components/decorators';
18
- import { AXDecoratorModule } from '@acorex/components/decorators';
19
- import { AXBasePageComponent } from '@acorex/components/page';
20
- import * as i3 from '@acorex/components/selection-list';
21
- import { AXSelectionListModule } from '@acorex/components/selection-list';
22
- import { AsyncPipe } from '@angular/common';
23
-
24
- //#endregion
25
- //#region ---- Component ----
26
- class AXMJiraInstancePickerPopupComponent extends AXBasePageComponent {
27
- constructor() {
28
- super(...arguments);
29
- this.instances = [];
30
- }
31
- instanceListItems() {
32
- return this.instances.map((instance) => ({
33
- id: instance.id,
34
- title: this.instanceTitle(instance),
35
- deploymentLabelKey: this.deploymentLabelKey(instance),
36
- }));
37
- }
38
- handleInstanceSelection(event) {
39
- if (!event.isUserInteraction) {
40
- return;
41
- }
42
- const instance = this.instances.find((item) => item.id === event.value);
43
- if (instance) {
44
- this.selectInstance(instance);
45
- }
46
- }
47
- instanceTitle(instance) {
48
- return resolveMultiLanguageString(instance.title, 'en-US');
49
- }
50
- deploymentLabelKey(instance) {
51
- return instance.deploymentType === 'cloud'
52
- ? '@extensions-jira:instances.entities.instance.fields.deployment-type.options.cloud'
53
- : '@extensions-jira:instances.entities.instance.fields.deployment-type.options.self-hosted';
54
- }
55
- selectInstance(instance) {
56
- this.close({ instance });
57
- }
58
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMJiraInstancePickerPopupComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
59
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMJiraInstancePickerPopupComponent, isStandalone: true, selector: "axm-jira-instance-picker-popup", usesInheritance: true, ngImport: i0, template: `
60
- <div class="flex flex-col gap-2 p-4">
61
- @if (instances.length === 0) {
62
- <p class="text-sm opacity-70">
63
- {{ '@extensions-jira:integration.connect.instance-picker.empty' | translate | async }}
64
- </p>
65
- } @else {
66
- <ax-selection-list
67
- class="w-full"
68
- valueField="id"
69
- textField="title"
70
- [direction]="'vertical'"
71
- [look]="'solid'"
72
- [multiple]="false"
73
- [showControl]="false"
74
- [items]="instanceListItems()"
75
- [customTemplate]="instanceItemTemplate"
76
- (onValueChanged)="handleInstanceSelection($event)"
77
- >
78
- <ng-template #instanceItemTemplate let-item>
79
- <div class="flex w-full flex-col items-start gap-0.5 py-1">
80
- <span class="font-medium">{{ item.data.title }}</span>
81
- <span class="text-xs opacity-70">{{ item.data.deploymentLabelKey | translate | async }}</span>
82
- </div>
83
- </ng-template>
84
- </ax-selection-list>
85
- }
86
- </div>
87
- <ax-footer>
88
- <ax-suffix>
89
- <ax-button
90
- look="outline"
91
- [text]="'@general:actions.cancel.title' | translate | async"
92
- (onClick)="close()"
93
- ></ax-button>
94
- </ax-suffix>
95
- </ax-footer>
96
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "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.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: AXSelectionListModule }, { kind: "component", type: i3.AXSelectionListComponent, selector: "ax-selection-list", inputs: ["id", "name", "disabled", "readonly", "tabIndex", "value", "valueField", "textField", "disabledField", "readonlyField", "multiple", "direction", "customTemplate", "showControl", "items", "look"], outputs: ["onValueChanged", "onBlur", "onFocus"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
97
- }
98
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMJiraInstancePickerPopupComponent, decorators: [{
99
- type: Component,
100
- args: [{
101
- selector: 'axm-jira-instance-picker-popup',
102
- changeDetection: ChangeDetectionStrategy.OnPush,
103
- imports: [AsyncPipe, AXButtonModule, AXDecoratorModule, AXSelectionListModule, AXTranslationModule],
104
- template: `
105
- <div class="flex flex-col gap-2 p-4">
106
- @if (instances.length === 0) {
107
- <p class="text-sm opacity-70">
108
- {{ '@extensions-jira:integration.connect.instance-picker.empty' | translate | async }}
109
- </p>
110
- } @else {
111
- <ax-selection-list
112
- class="w-full"
113
- valueField="id"
114
- textField="title"
115
- [direction]="'vertical'"
116
- [look]="'solid'"
117
- [multiple]="false"
118
- [showControl]="false"
119
- [items]="instanceListItems()"
120
- [customTemplate]="instanceItemTemplate"
121
- (onValueChanged)="handleInstanceSelection($event)"
122
- >
123
- <ng-template #instanceItemTemplate let-item>
124
- <div class="flex w-full flex-col items-start gap-0.5 py-1">
125
- <span class="font-medium">{{ item.data.title }}</span>
126
- <span class="text-xs opacity-70">{{ item.data.deploymentLabelKey | translate | async }}</span>
127
- </div>
128
- </ng-template>
129
- </ax-selection-list>
130
- }
131
- </div>
132
- <ax-footer>
133
- <ax-suffix>
134
- <ax-button
135
- look="outline"
136
- [text]="'@general:actions.cancel.title' | translate | async"
137
- (onClick)="close()"
138
- ></ax-button>
139
- </ax-suffix>
140
- </ax-footer>
141
- `,
142
- }]
143
- }] });
144
-
145
- //#endregion
146
- //#region ---- Command ----
147
- /** Jira connect: pick instance → self-hosted PAT or cloud OAuth2. */
148
- class ConnectJiraCommand {
149
- constructor() {
150
- //#region ---- Services & Dependencies ----
151
- this.popupService = inject(AXPopupService);
152
- this.dialogOpener = inject(AXPDialogOpener);
153
- this.translationService = inject(AXTranslationService);
154
- this.entityService = inject(AXPEntityService);
155
- this.layoutBuilder = inject(AXPLayoutBuilderService);
156
- this.commandService = inject(AXPCommandService);
157
- this.sessionService = inject(AXPSessionService);
158
- }
159
- //#endregion
160
- //#region ---- Execute ----
161
- async execute(input = {}) {
162
- try {
163
- const providerId = defaultTo(input.providerId, 'jira');
164
- const connectionScope = input.connectionScope ?? 'tenant';
165
- const I18N = '@extensions-jira:integration.connect';
166
- const instance = await this.pickInstance();
167
- if (!instance) {
168
- return { success: true, kind: 'object', data: { outcome: 'cancelled' } };
169
- }
170
- if (instance.deploymentType === 'selfHosted') {
171
- return this.connectSelfHosted(providerId, connectionScope, instance, I18N);
172
- }
173
- return this.connectCloud(providerId, connectionScope, instance, I18N);
174
- }
175
- catch (error) {
176
- const message = error instanceof Error ? error.message : 'Failed to connect Jira instance.';
177
- return { success: false, message: { text: message } };
178
- }
179
- }
180
- //#endregion
181
- //#region ---- Instance Picker ----
182
- async pickInstance() {
183
- const instances = await this.loadActiveInstances();
184
- let title = '';
185
- const result = await this.dialogOpener.openPopup({
186
- load: () => Promise.resolve(AXMJiraInstancePickerPopupComponent),
187
- data: { instanceIds: instances.map((instance) => instance.id) },
188
- prepare: async () => {
189
- title = await this.translationService.translateAsync('@extensions-jira:integration.connect.instance-picker.title');
190
- },
191
- show: (component) => this.popupService.open(component, {
192
- title,
193
- size: 'sm',
194
- data: { instances },
195
- }),
196
- });
197
- return result?.data?.instance ?? null;
198
- }
199
- async loadActiveInstances() {
200
- const accessor = this.entityService
201
- .withEntity(RootConfig.module.name, RootConfig.entities.jiraInstance.name)
202
- .data();
203
- const result = await accessor.query({
204
- skip: 0,
205
- take: 200,
206
- filter: {
207
- logic: 'and',
208
- filters: [{ field: 'isActive', operator: { type: 'equal' }, value: true }],
209
- },
210
- });
211
- return result.items ?? [];
212
- }
213
- //#endregion
214
- //#region ---- Self-Hosted (PAT) ----
215
- async connectSelfHosted(providerId, connectionScope, instance, i18nPrefix) {
216
- const form = await this.openPatDialog({
217
- i18nPrefix,
218
- context: {
219
- displayName: instance.name,
220
- instanceUrl: defaultTo(instance.baseUrl, ''),
221
- token: '',
222
- },
223
- instanceUrlReadonly: true,
224
- });
225
- if (!form) {
226
- return { success: true, kind: 'object', data: { outcome: 'cancelled' } };
227
- }
228
- const result = await this.commandService.execute(AXMIntegrationManagementCommandKeys.ConnectionConnectWithCredentials, {
229
- providerId,
230
- authMethodType: AXP_INTEGRATION_AUTH_METHOD_TYPE.Pat,
231
- connectionScope,
232
- connectionKey: instance.name,
233
- displayName: defaultTo(trim(form.displayName), instance.name),
234
- instanceUrl: defaultTo(trim(form.instanceUrl), defaultTo(instance.baseUrl, '')),
235
- credentials: { token: form.token },
236
- config: { jiraInstanceId: instance.id },
237
- });
238
- const data = runtimeCommandPayloadData(result);
239
- if (!data) {
240
- return {
241
- success: false,
242
- message: result?.message ?? { text: 'Failed to save Jira connection.' },
243
- };
244
- }
245
- return { success: true, kind: 'object', data: { outcome: 'connected', connection: data } };
246
- }
247
- //#endregion
248
- //#region ---- Cloud (OAuth2) ----
249
- async connectCloud(providerId, connectionScope, instance, i18nPrefix) {
250
- const instructions = await this.translationService.translateAsync('@extensions-jira:integration.auth.oauth.instructions');
251
- const confirmedResult = await this.layoutBuilder
252
- .create()
253
- .dialog((dialog) => {
254
- dialog
255
- .setTitle(`${i18nPrefix}.oauth-dialog.title`)
256
- .setSize('sm')
257
- .setCloseButton(true)
258
- .content((flex) => {
259
- flex
260
- .setDirection('column')
261
- .setGap('12px')
262
- .customWidget('text-block-layout', {
263
- content: instructions ?? '',
264
- });
265
- })
266
- .setActions((actions) => {
267
- actions.cancel('@general:actions.cancel.title').submit(`${i18nPrefix}.oauth-dialog.actions.connect`);
268
- })
269
- .onAction(async (ref) => ref.action() !== 'cancel');
270
- })
271
- .show();
272
- const confirmed = resolveLayoutBuilderDialogResult(confirmedResult);
273
- if (!confirmed) {
274
- return { success: true, kind: 'object', data: { outcome: 'cancelled' } };
275
- }
276
- return {
277
- success: false,
278
- message: {
279
- text: '@extensions-jira:integration.auth.oauth.not-implemented',
280
- },
281
- };
282
- }
283
- //#endregion
284
- //#region ---- Dialogs ----
285
- async openPatDialog(input) {
286
- const instructions = await this.translationService.translateAsync('@extensions-jira:integration.auth.pat.instructions');
287
- const result = await this.layoutBuilder
288
- .create()
289
- .dialog((dialog) => {
290
- dialog
291
- .setTitle(`${input.i18nPrefix}.pat-dialog.title`)
292
- .setSize('md')
293
- .setCloseButton(true)
294
- .setContext({ ...input.context })
295
- .content((flex) => {
296
- flex
297
- .setDirection('column')
298
- .setGap('12px')
299
- .customWidget('text-block-layout', { content: instructions ?? '' })
300
- .formField(`${input.i18nPrefix}.pat-dialog.fields.display-name`, (field) => {
301
- field.path('displayName');
302
- field.textBox({ placeholder: `${input.i18nPrefix}.pat-dialog.placeholders.display-name` });
303
- })
304
- .formField(`${input.i18nPrefix}.pat-dialog.fields.instance-url`, (field) => {
305
- field.path('instanceUrl');
306
- if (input.instanceUrlReadonly) {
307
- field.readonly(true);
308
- }
309
- field.textBox({
310
- placeholder: `${input.i18nPrefix}.pat-dialog.placeholders.instance-url`,
311
- });
312
- })
313
- .formField(`${input.i18nPrefix}.pat-dialog.fields.token`, (field) => {
314
- field.path('token');
315
- field.passwordBox({
316
- placeholder: `${input.i18nPrefix}.pat-dialog.placeholders.token`,
317
- revealToggle: true,
318
- validations: [{ rule: 'required' }],
319
- });
320
- });
321
- })
322
- .setActions((actions) => {
323
- actions
324
- .cancel('@general:actions.cancel.title')
325
- .submit(`${input.i18nPrefix}.pat-dialog.actions.save`);
326
- })
327
- .onAction(async (ref) => {
328
- if (ref.action() === 'cancel') {
329
- return null;
330
- }
331
- const ctx = ref.context();
332
- const token = trim(ctx.token);
333
- if (!token) {
334
- throw new Error('Personal access token is required.');
335
- }
336
- return {
337
- displayName: trim(ctx.displayName),
338
- instanceUrl: trim(ctx.instanceUrl),
339
- token,
340
- };
341
- });
342
- })
343
- .show();
344
- return resolveLayoutBuilderDialogResult(result);
345
- }
346
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ConnectJiraCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
347
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ConnectJiraCommand, providedIn: 'root' }); }
348
- }
349
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ConnectJiraCommand, decorators: [{
350
- type: Injectable,
351
- args: [{ providedIn: 'root' }]
352
- }] });
353
-
354
- export { ConnectJiraCommand };
355
- //# sourceMappingURL=acorex-platform-extension-project-management-jira-client-connect-jira.command-BhnLiDk0.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"acorex-platform-extension-project-management-jira-client-connect-jira.command-BhnLiDk0.mjs","sources":["../../../../libs/extensions/project-management/jira/client/src/lib/features/connect/ui/jira-instance-picker-popup.component.ts","../../../../libs/extensions/project-management/jira/client/src/lib/features/connect/connect-jira.command.ts"],"sourcesContent":["//#region ---- Imports ----\n\nimport { AXValueChangedEvent } from '@acorex/cdk/common';\nimport { AXButtonModule } from '@acorex/components/button';\nimport { AXDecoratorModule } from '@acorex/components/decorators';\nimport { AXBasePageComponent } from '@acorex/components/page';\nimport { AXSelectionListModule } from '@acorex/components/selection-list';\nimport { AXTranslationModule } from '@acorex/core/translation';\nimport { resolveMultiLanguageString } from '@acorex-platform/framework-shared/core';\nimport type { AXEJiraInstanceEntityModel } from '@acorex-platform/extension-project-management-jira-domain';\nimport { AsyncPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component } from '@angular/core';\n\n//#endregion\n\n//#region ---- Types ----\n\nexport interface AXMJiraInstancePickerPopupResult {\n instance: AXEJiraInstanceEntityModel;\n}\n\n//#endregion\n\n//#region ---- Component ----\n\n@Component({\n selector: 'axm-jira-instance-picker-popup',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [AsyncPipe, AXButtonModule, AXDecoratorModule, AXSelectionListModule, AXTranslationModule],\n template: `\n <div class=\"flex flex-col gap-2 p-4\">\n @if (instances.length === 0) {\n <p class=\"text-sm opacity-70\">\n {{ '@extensions-jira:integration.connect.instance-picker.empty' | translate | async }}\n </p>\n } @else {\n <ax-selection-list\n class=\"w-full\"\n valueField=\"id\"\n textField=\"title\"\n [direction]=\"'vertical'\"\n [look]=\"'solid'\"\n [multiple]=\"false\"\n [showControl]=\"false\"\n [items]=\"instanceListItems()\"\n [customTemplate]=\"instanceItemTemplate\"\n (onValueChanged)=\"handleInstanceSelection($event)\"\n >\n <ng-template #instanceItemTemplate let-item>\n <div class=\"flex w-full flex-col items-start gap-0.5 py-1\">\n <span class=\"font-medium\">{{ item.data.title }}</span>\n <span class=\"text-xs opacity-70\">{{ item.data.deploymentLabelKey | translate | async }}</span>\n </div>\n </ng-template>\n </ax-selection-list>\n }\n </div>\n <ax-footer>\n <ax-suffix>\n <ax-button\n look=\"outline\"\n [text]=\"'@general:actions.cancel.title' | translate | async\"\n (onClick)=\"close()\"\n ></ax-button>\n </ax-suffix>\n </ax-footer>\n `,\n})\nexport class AXMJiraInstancePickerPopupComponent extends AXBasePageComponent {\n instances: AXEJiraInstanceEntityModel[] = [];\n\n protected instanceListItems(): Array<{\n id: string;\n title: string;\n deploymentLabelKey: string;\n }> {\n return this.instances.map((instance) => ({\n id: instance.id,\n title: this.instanceTitle(instance),\n deploymentLabelKey: this.deploymentLabelKey(instance),\n }));\n }\n\n protected handleInstanceSelection(event: AXValueChangedEvent): void {\n if (!event.isUserInteraction) {\n return;\n }\n\n const instance = this.instances.find((item) => item.id === event.value);\n if (instance) {\n this.selectInstance(instance);\n }\n }\n\n protected instanceTitle(instance: AXEJiraInstanceEntityModel): string {\n return resolveMultiLanguageString(instance.title, 'en-US');\n }\n\n protected deploymentLabelKey(instance: AXEJiraInstanceEntityModel): string {\n return instance.deploymentType === 'cloud'\n ? '@extensions-jira:instances.entities.instance.fields.deployment-type.options.cloud'\n : '@extensions-jira:instances.entities.instance.fields.deployment-type.options.self-hosted';\n }\n\n protected selectInstance(instance: AXEJiraInstanceEntityModel): void {\n this.close({ instance } satisfies AXMJiraInstancePickerPopupResult);\n }\n}\n\n//#endregion\n","//#region ---- Imports ----\n\nimport { AXPCommand, type AXPCommandExecuteResultPromise } from '@acorex-platform/framework-shared/runtime';\nimport {\n AXP_INTEGRATION_AUTH_METHOD_TYPE,\n runtimeCommandPayloadData,\n type AXPIntegrationConnectionScope,\n type AXPRuntimeCommandResult,\n type AXPSafeIntegrationConnectionDto,\n} from '@acorex-platform/framework-shared/core';\nimport {\n type ConnectCommandResult,\n} from '@acorex-platform/module-integration-management-client';\nimport { AXMIntegrationManagementCommandKeys } from '@acorex-platform/module-integration-management-client/contracts';\nimport { AXPSessionService } from '@acorex-platform/framework-client/auth';\nimport {\n AXPLayoutBuilderService,\n resolveLayoutBuilderDialogResult,\n type AXPDialogRef,\n type IActionBuilder,\n type IDialogBuilder,\n type IFlexContainerBuilder,\n type IFormFieldBuilder,\n} from '@acorex-platform/framework-client/layout/builder';\nimport { AXPEntityService } from '@acorex-platform/framework-client/layout/entity';\nimport { AXPCommandService } from '@acorex-platform/framework-client/runtime';\nimport { AXPopupService } from '@acorex/components/popup';\nimport { AXPDialogOpener } from '@acorex-platform/framework-client/core';\nimport { AXTranslationService } from '@acorex/core/translation';\nimport { Injectable, inject } from '@angular/core';\nimport { defaultTo, get, trim } from 'lodash-es';\n\nimport { RootConfig } from '@acorex-platform/extension-project-management-jira-client/contracts';\nimport type { AXEJiraInstanceEntityModel } from '@acorex-platform/extension-project-management-jira-domain';\nimport {\n AXMJiraInstancePickerPopupComponent,\n type AXMJiraInstancePickerPopupResult,\n} from './ui/jira-instance-picker-popup.component';\n\n//#endregion\n\n//#region ---- Types ----\n\nexport interface ConnectJiraCommandInput {\n providerId?: string;\n connectionScope?: AXPIntegrationConnectionScope;\n}\n\ninterface JiraPatFormContext {\n displayName: string;\n instanceUrl: string;\n token: string;\n}\n\ninterface JiraPatFormResult {\n displayName: string;\n instanceUrl: string;\n token: string;\n}\n\n//#endregion\n\n//#region ---- Command ----\n\n/** Jira connect: pick instance → self-hosted PAT or cloud OAuth2. */\n@Injectable({ providedIn: 'root' })\nexport class ConnectJiraCommand implements AXPCommand<ConnectJiraCommandInput, ConnectCommandResult> {\n //#region ---- Services & Dependencies ----\n\n private readonly popupService = inject(AXPopupService);\n private readonly dialogOpener = inject(AXPDialogOpener);\n private readonly translationService = inject(AXTranslationService);\n private readonly entityService = inject(AXPEntityService);\n private readonly layoutBuilder = inject(AXPLayoutBuilderService);\n private readonly commandService = inject(AXPCommandService);\n private readonly sessionService = inject(AXPSessionService);\n\n //#endregion\n\n //#region ---- Execute ----\n\n async execute(input: ConnectJiraCommandInput = {}): AXPCommandExecuteResultPromise<ConnectCommandResult> {\n try {\n const providerId = defaultTo(input.providerId, 'jira');\n const connectionScope: AXPIntegrationConnectionScope = input.connectionScope ?? 'tenant';\n const I18N = '@extensions-jira:integration.connect';\n\n const instance = await this.pickInstance();\n if (!instance) {\n return { success: true, kind: 'object', data: { outcome: 'cancelled' } };\n }\n\n if (instance.deploymentType === 'selfHosted') {\n return this.connectSelfHosted(providerId, connectionScope, instance, I18N);\n }\n\n return this.connectCloud(providerId, connectionScope, instance, I18N);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to connect Jira instance.';\n return { success: false, message: { text: message } };\n }\n }\n\n //#endregion\n\n //#region ---- Instance Picker ----\n\n private async pickInstance(): Promise<AXEJiraInstanceEntityModel | null> {\n const instances = await this.loadActiveInstances();\n let title = '';\n\n const result = await this.dialogOpener.openPopup({\n load: () => Promise.resolve(AXMJiraInstancePickerPopupComponent),\n data: { instanceIds: instances.map((instance) => instance.id) },\n prepare: async () => {\n title = await this.translationService.translateAsync(\n '@extensions-jira:integration.connect.instance-picker.title',\n );\n },\n show: (component) =>\n this.popupService.open(component, {\n title,\n size: 'sm',\n data: { instances },\n }),\n });\n\n return (result?.data as AXMJiraInstancePickerPopupResult | undefined)?.instance ?? null;\n }\n\n private async loadActiveInstances(): Promise<AXEJiraInstanceEntityModel[]> {\n const accessor = this.entityService\n .withEntity(RootConfig.module.name, RootConfig.entities.jiraInstance.name)\n .data<string, AXEJiraInstanceEntityModel>();\n\n const result = await accessor.query({\n skip: 0,\n take: 200,\n filter: {\n logic: 'and',\n filters: [{ field: 'isActive', operator: { type: 'equal' }, value: true }],\n },\n });\n\n return result.items ?? [];\n }\n\n //#endregion\n\n //#region ---- Self-Hosted (PAT) ----\n\n private async connectSelfHosted(\n providerId: string,\n connectionScope: AXPIntegrationConnectionScope,\n instance: AXEJiraInstanceEntityModel,\n i18nPrefix: string,\n ): AXPCommandExecuteResultPromise<ConnectCommandResult> {\n const form = await this.openPatDialog({\n i18nPrefix,\n context: {\n displayName: instance.name,\n instanceUrl: defaultTo(instance.baseUrl, ''),\n token: '',\n },\n instanceUrlReadonly: true,\n });\n\n if (!form) {\n return { success: true, kind: 'object', data: { outcome: 'cancelled' } };\n }\n\n const result = await this.commandService.execute<\n Record<string, unknown>,\n AXPSafeIntegrationConnectionDto\n >(AXMIntegrationManagementCommandKeys.ConnectionConnectWithCredentials, {\n providerId,\n authMethodType: AXP_INTEGRATION_AUTH_METHOD_TYPE.Pat,\n connectionScope,\n connectionKey: instance.name,\n displayName: defaultTo(trim(form.displayName), instance.name),\n instanceUrl: defaultTo(trim(form.instanceUrl), defaultTo(instance.baseUrl, '')),\n credentials: { token: form.token },\n config: { jiraInstanceId: instance.id },\n });\n\n const data = runtimeCommandPayloadData(result);\n if (!data) {\n return {\n success: false,\n message: result?.message ?? { text: 'Failed to save Jira connection.' },\n };\n }\n\n return { success: true, kind: 'object', data: { outcome: 'connected', connection: data } };\n }\n\n //#endregion\n\n //#region ---- Cloud (OAuth2) ----\n\n private async connectCloud(\n providerId: string,\n connectionScope: AXPIntegrationConnectionScope,\n instance: AXEJiraInstanceEntityModel,\n i18nPrefix: string,\n ): AXPCommandExecuteResultPromise<ConnectCommandResult> {\n const instructions = await this.translationService.translateAsync(\n '@extensions-jira:integration.auth.oauth.instructions',\n );\n\n const confirmedResult = await this.layoutBuilder\n .create()\n .dialog<boolean>((dialog: IDialogBuilder<boolean>) => {\n dialog\n .setTitle(`${i18nPrefix}.oauth-dialog.title`)\n .setSize('sm')\n .setCloseButton(true)\n .content((flex: IFlexContainerBuilder) => {\n flex\n .setDirection('column')\n .setGap('12px')\n .customWidget('text-block-layout', {\n content: instructions ?? '',\n });\n })\n .setActions((actions: IActionBuilder) => {\n actions.cancel('@general:actions.cancel.title').submit(`${i18nPrefix}.oauth-dialog.actions.connect`);\n })\n .onAction(async (ref: AXPDialogRef) => ref.action() !== 'cancel');\n })\n .show();\n\n const confirmed = resolveLayoutBuilderDialogResult<boolean>(confirmedResult);\n if (!confirmed) {\n return { success: true, kind: 'object', data: { outcome: 'cancelled' } };\n }\n\n return {\n success: false,\n message: {\n text: '@extensions-jira:integration.auth.oauth.not-implemented',\n },\n };\n }\n\n //#endregion\n\n //#region ---- Dialogs ----\n\n private async openPatDialog(input: {\n i18nPrefix: string;\n context: JiraPatFormContext;\n instanceUrlReadonly?: boolean;\n }): Promise<JiraPatFormResult | null> {\n const instructions = await this.translationService.translateAsync(\n '@extensions-jira:integration.auth.pat.instructions',\n );\n\n const result = await this.layoutBuilder\n .create()\n .dialog<JiraPatFormResult | null>((dialog: IDialogBuilder<JiraPatFormResult | null>) => {\n dialog\n .setTitle(`${input.i18nPrefix}.pat-dialog.title`)\n .setSize('md')\n .setCloseButton(true)\n .setContext({ ...input.context })\n .content((flex: IFlexContainerBuilder) => {\n flex\n .setDirection('column')\n .setGap('12px')\n .customWidget('text-block-layout', { content: instructions ?? '' })\n .formField(`${input.i18nPrefix}.pat-dialog.fields.display-name`, (field: IFormFieldBuilder) => {\n field.path('displayName');\n field.textBox({ placeholder: `${input.i18nPrefix}.pat-dialog.placeholders.display-name` });\n })\n .formField(`${input.i18nPrefix}.pat-dialog.fields.instance-url`, (field) => {\n field.path('instanceUrl');\n if (input.instanceUrlReadonly) {\n field.readonly(true);\n }\n field.textBox({\n placeholder: `${input.i18nPrefix}.pat-dialog.placeholders.instance-url`,\n });\n })\n .formField(`${input.i18nPrefix}.pat-dialog.fields.token`, (field) => {\n field.path('token');\n field.passwordBox({\n placeholder: `${input.i18nPrefix}.pat-dialog.placeholders.token`,\n revealToggle: true,\n validations: [{ rule: 'required' }],\n });\n });\n })\n .setActions((actions: IActionBuilder) => {\n actions\n .cancel('@general:actions.cancel.title')\n .submit(`${input.i18nPrefix}.pat-dialog.actions.save`);\n })\n .onAction(async (ref: AXPDialogRef) => {\n if (ref.action() === 'cancel') {\n return null;\n }\n const ctx = ref.context() as JiraPatFormContext;\n const token = trim(ctx.token);\n if (!token) {\n throw new Error('Personal access token is required.');\n }\n return {\n displayName: trim(ctx.displayName),\n instanceUrl: trim(ctx.instanceUrl),\n token,\n };\n });\n })\n .show();\n\n return resolveLayoutBuilderDialogResult<JiraPatFormResult>(result);\n }\n\n //#endregion\n}\n\n//#endregion\n"],"names":["i2","i4"],"mappings":"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"}