mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-18 00:46:45 +00:00
Co-authored-by: cocojojo5213 <cocojojo5213@users.noreply.github.com>
This commit is contained in:
parent
c0146e2307
commit
667e8c3aa0
6 changed files with 89 additions and 15 deletions
|
|
@ -28,6 +28,10 @@ If the integration “doesn’t work,” check that you used the right link and
|
|||
|
||||
After saving, a new **tab** appears in the panel for that provider. You can have multiple instances of the same type (e.g. two Jira configurations) and reorder tabs by dragging.
|
||||
|
||||
### Azure DevOps and Self-Hosted TFS URLs
|
||||
|
||||
For **Azure DevOps**, enter the full organization or collection URL in **Host**. For Azure DevOps Services this looks like `https://dev.azure.com/<organization>`. For self-hosted Azure DevOps Server/TFS this can include the collection path, for example `https://server:8080/tfs/DefaultCollection`. The separate **Project** field is still required.
|
||||
|
||||
## Add an Issue or Calendar Item as a Task
|
||||
|
||||
1. Open the issue provider panel and select the **tab** for the provider (e.g. Jira or GitHub).
|
||||
|
|
|
|||
|
|
@ -63,6 +63,22 @@ describe('AzureDevOpsApiService', () => {
|
|||
req.flush({ workItems: [] });
|
||||
});
|
||||
|
||||
it('should use the configured host directly for self-hosted Azure DevOps Server URLs (#7672)', () => {
|
||||
const cfg: AzureDevOpsCfg = {
|
||||
...mockCfg,
|
||||
host: 'https://ado.example.com/tfs/DefaultCollection',
|
||||
organization: null,
|
||||
};
|
||||
|
||||
service.searchIssues$('test', cfg).subscribe();
|
||||
|
||||
const req = httpMock.expectOne(
|
||||
`${cfg.host}/${cfg.project}/_apis/wit/wiql?api-version=6.0`,
|
||||
);
|
||||
|
||||
req.flush({ workItems: [] });
|
||||
});
|
||||
|
||||
it('should map search results correctly including ticket type', () => {
|
||||
const searchTerm = 'test';
|
||||
service.searchIssues$(searchTerm, mockCfg).subscribe((issues) => {
|
||||
|
|
@ -108,5 +124,22 @@ describe('AzureDevOpsApiService', () => {
|
|||
|
||||
req.flush({ authenticatedUser: { providerDisplayName: 'Test User' } });
|
||||
});
|
||||
|
||||
it('should not require organization when host already contains the collection path (#7672)', () => {
|
||||
const cfg: AzureDevOpsCfg = {
|
||||
...mockCfg,
|
||||
host: 'https://ado.example.com/tfs/DefaultCollection',
|
||||
organization: null,
|
||||
};
|
||||
|
||||
service.getCurrentUser$(cfg).subscribe();
|
||||
|
||||
const req = httpMock.expectOne(
|
||||
`${cfg.host}/_apis/connectionData?api-version=5.1-preview`,
|
||||
);
|
||||
expect(req.request.method).toBe('GET');
|
||||
|
||||
req.flush({ authenticatedUser: { providerDisplayName: 'Test User' } });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
import { AZURE_DEVOPS_CONFIG_FORM_SECTION } from './azure-devops-cfg-form.const';
|
||||
|
||||
describe('AZURE_DEVOPS_CONFIG_FORM_SECTION', () => {
|
||||
it('does not require a separate organization field when host is the full Azure DevOps URL (#7672)', () => {
|
||||
const fields = AZURE_DEVOPS_CONFIG_FORM_SECTION.items ?? [];
|
||||
const keys = fields.map((field) => field.key);
|
||||
const hostField = fields.find((field) => field.key === 'host');
|
||||
|
||||
expect(keys).toContain('host');
|
||||
expect(keys).not.toContain('organization');
|
||||
expect(hostField?.templateOptions?.required).toBeTrue();
|
||||
expect(hostField?.templateOptions?.label).toBe('F.AZURE_DEVOPS.FORM.HOST');
|
||||
expect(hostField?.templateOptions?.description).toBe(
|
||||
'F.AZURE_DEVOPS.FORM.HOST_DESCRIPTION',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -11,25 +11,18 @@ export const AZURE_DEVOPS_CONFIG_FORM_SECTION: ConfigFormSection<AzureDevOpsCfg>
|
|||
key: 'host',
|
||||
type: 'input',
|
||||
templateOptions: {
|
||||
label: 'Host (Organization URL)',
|
||||
label: T.F.AZURE_DEVOPS.FORM.HOST,
|
||||
placeholder: 'https://dev.azure.com/your-org',
|
||||
description: T.F.AZURE_DEVOPS.FORM.HOST_DESCRIPTION,
|
||||
required: true,
|
||||
type: 'url',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'organization',
|
||||
type: 'input',
|
||||
templateOptions: {
|
||||
label: 'Organization',
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'project',
|
||||
type: 'input',
|
||||
templateOptions: {
|
||||
label: 'Project',
|
||||
label: T.F.AZURE_DEVOPS.FORM.PROJECT,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
|
@ -37,7 +30,7 @@ export const AZURE_DEVOPS_CONFIG_FORM_SECTION: ConfigFormSection<AzureDevOpsCfg>
|
|||
key: 'token',
|
||||
type: 'input',
|
||||
templateOptions: {
|
||||
label: 'Personal Access Token',
|
||||
label: T.F.AZURE_DEVOPS.FORM.TOKEN,
|
||||
required: true,
|
||||
type: 'password',
|
||||
},
|
||||
|
|
@ -53,11 +46,14 @@ export const AZURE_DEVOPS_CONFIG_FORM_SECTION: ConfigFormSection<AzureDevOpsCfg>
|
|||
defaultValue: 'assigned-to-me',
|
||||
templateOptions: {
|
||||
required: true,
|
||||
label: 'Scope (Auto Import only)',
|
||||
label: T.F.AZURE_DEVOPS.FORM.SCOPE,
|
||||
options: [
|
||||
{ value: 'all', label: 'All' },
|
||||
{ value: 'created-by-me', label: 'Created by me' },
|
||||
{ value: 'assigned-to-me', label: 'Assigned to me' },
|
||||
{ value: 'all', label: T.F.AZURE_DEVOPS.FORM.SCOPE_ALL },
|
||||
{ value: 'created-by-me', label: T.F.AZURE_DEVOPS.FORM.SCOPE_CREATED },
|
||||
{
|
||||
value: 'assigned-to-me',
|
||||
label: T.F.AZURE_DEVOPS.FORM.SCOPE_ASSIGNED,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -77,6 +77,18 @@ const T = {
|
|||
'F.ANDROID.FOREGROUND_SERVICE_START_FAILED_TRACKING',
|
||||
OPEN_NOTIFICATION_SETTINGS: 'F.ANDROID.OPEN_NOTIFICATION_SETTINGS',
|
||||
},
|
||||
AZURE_DEVOPS: {
|
||||
FORM: {
|
||||
HOST: 'F.AZURE_DEVOPS.FORM.HOST',
|
||||
HOST_DESCRIPTION: 'F.AZURE_DEVOPS.FORM.HOST_DESCRIPTION',
|
||||
PROJECT: 'F.AZURE_DEVOPS.FORM.PROJECT',
|
||||
SCOPE: 'F.AZURE_DEVOPS.FORM.SCOPE',
|
||||
SCOPE_ALL: 'F.AZURE_DEVOPS.FORM.SCOPE_ALL',
|
||||
SCOPE_ASSIGNED: 'F.AZURE_DEVOPS.FORM.SCOPE_ASSIGNED',
|
||||
SCOPE_CREATED: 'F.AZURE_DEVOPS.FORM.SCOPE_CREATED',
|
||||
TOKEN: 'F.AZURE_DEVOPS.FORM.TOKEN',
|
||||
},
|
||||
},
|
||||
ATTACHMENT: {
|
||||
LOCAL_FILE_UNAVAILABLE: 'F.ATTACHMENT.LOCAL_FILE_UNAVAILABLE',
|
||||
DIALOG_EDIT: {
|
||||
|
|
|
|||
|
|
@ -75,6 +75,18 @@
|
|||
"FOREGROUND_SERVICE_START_FAILED_TRACKING": "Android blocked the persistent time tracking notification. Time is still tracked in the app, but background recovery may be unavailable. Check notification permission and battery/background restrictions.",
|
||||
"OPEN_NOTIFICATION_SETTINGS": "Open settings"
|
||||
},
|
||||
"AZURE_DEVOPS": {
|
||||
"FORM": {
|
||||
"HOST": "Host (organization or collection URL)",
|
||||
"HOST_DESCRIPTION": "Use the full Azure DevOps URL, for example https://dev.azure.com/your-org or https://server:8080/tfs/DefaultCollection.",
|
||||
"PROJECT": "Project",
|
||||
"SCOPE": "Scope (Auto Import only)",
|
||||
"SCOPE_ALL": "All",
|
||||
"SCOPE_ASSIGNED": "Assigned to me",
|
||||
"SCOPE_CREATED": "Created by me",
|
||||
"TOKEN": "Personal Access Token"
|
||||
}
|
||||
},
|
||||
"ATTACHMENT": {
|
||||
"LOCAL_FILE_UNAVAILABLE": "This attachment is only available on the device where it was added.",
|
||||
"DIALOG_EDIT": {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue