Commit graph

12 commits

Author SHA1 Message Date
Johannes Millan
c7d6131db8
feat(plainspace): Collaborate-on-Plainspace discovery + smoother connect (#8649)
* feat(plainspace): add Collaborate action to project context menu

Surface Plainspace sharing from the project context menu (active, non-Inbox,
not-yet-shared projects) so it can be discovered at the moment of collaboration
intent, reusing PlainspaceShareService. A new selectIsProjectSharedOnPlainspace
selector hides the action once a project is shared to avoid provisioning a
duplicate space on a repeat click.

* docs(plainspace): document collaboration in wiki

Add Plainspace to the issue-integration comparison (matrix + per-provider
section) and a how-to for sharing a project via the project menu, including the
network/privacy caveat.

* feat(plainspace): place Collaborate action below the share-list item

Group the two share/export actions and lift Collaborate higher for
discoverability. Gated to active, non-inbox, not-already-shared projects.

* fix(plainspace): smoother first-run connect and value-first dialog

Pre-check connectivity and revalidate a stored token before the space
picker, so a stale/foreign token routes to the connect dialog and an
offline state shows a calm message instead of the raw 'check your token'
picker error. Make the connect dialog value-first: lead with what you
get, drop the 4-step how-to and email hint in favor of one short pointer
(token-creation guidance moves to plainspace.org).

* docs(plans): dedicated from-Super-Productivity flow on plainspace.org

Open plan for a guided token/connect flow on plainspace.org when a user
arrives from SP (Model A manual token, Model B OAuth-style handoff).

* refactor(plainspace): drop redundant connect pre-check (multi-review)

The space picker already detects a stale token and offers a reconnect
(#8616), so the revalidate() pre-check duplicated that path, cost an
extra GET /me, and forced re-auth on a valid token during a transient
server blip. Keep only the one-line offline guard; drop revalidate(),
the discriminated union, and the unnecessary _isOnline() seam (navigator
.onLine is spyable in the runner). Fix stale doc comments and document
the disabled-provider trade-off in the selector.

* feat(plainspace): show brand icon in the connect dialog title

* feat(plainspace): deep-link connect dialog to the from-SP onboarding flow

Point the dialog's 'Open Plainspace' link at the dedicated
/connect/super-productivity entrypoint (which guides token creation)
instead of the bare marketing host, closing the connect-flow funnel leak.

* feat(plainspace): bounce back to the app after connecting (desktop)

Append a validated `?return=superproductivity://plainspace-connect` deep
link to the connect URL, gated on IS_ELECTRON (only desktop registers the
scheme — web/mobile would get dead buttons). Handle that action in the
Electron protocol handler by surfacing the window, so the connect page's
"Open Super Productivity" button re-focuses the app.

Desktop-only; needs an on-device check.
2026-07-01 16:39:34 +02:00
John Costa
0a0723521b
feat(azure-devops): add optional WIQL override for auto backlog import (#8516)
* feat(azure-devops): add optional WIQL override for auto backlog import

Adds an optional autoImportWiql config field to the Azure DevOps issue
provider plugin. When set, it fully replaces the generated auto-import
backlog query, so the user controls scope, state filtering and ordering
(e.g. to filter by iteration path, area path or work item type, or to
match custom done-state names). When empty, behavior is unchanged from
today's scope-based query, so it is fully backward compatible.

This mirrors the Jira provider's autoAddBacklogJqlQuery (a full query the
user owns) rather than appending a fragment, which can only narrow the
hard-coded English done-state exclusion and cannot accept a real exported
WIQL Select..From..Where statement.

Adds a vitest suite covering the default scopes, quote escaping, the
verbatim override and the blank-fallback, wires the plugin into the
plugin-tests CI matrix, and updates the issue integration comparison wiki.

Closes #7674

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DY1ESWymmU9x9ykLNaRHGH

* test(azure-devops): use node test env, drop unneeded jsdom dependency

The plugin tests exercise no DOM API, so vitest's default node
environment is sufficient (matching the clickup and google-calendar
provider plugins). Removing jsdom prunes ~530 lines of transitive
devDependencies from the lockfile.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Johannes Millan <johannes.millan@gmail.com>
2026-06-22 17:38:49 +02:00
Symon Baikov
cbe3f1527f
fix(caldav): support Vikunja project discovery (#8481) 2026-06-19 12:15:31 +02:00
felix bear
9cb9aef948
fix(redmine): support non-latin issue search #4149 (#8150)
Co-authored-by: cocojojo5213 <cocojojo5213@users.noreply.github.com>
2026-06-10 12:50:43 +02:00
felix bear
5314126b93
feat(azure-devops): configure auto import limit (#8092)
* feat(azure-devops): configure auto import limit #7017

* fix(azure-devops): translate auto import limit form #7017

---------

Co-authored-by: cocojojo5213 <cocojojo5213@users.noreply.github.com>
2026-06-09 00:22:15 +02:00
felix bear
5be516a02c
fix(calendar): disable iCal polling on Android (#8173)
Co-authored-by: cocojojo5213 <cocojojo5213@users.noreply.github.com>
2026-06-09 00:21:17 +02:00
agncr
541bc1b0fd
feat(calendar): add per-provider include/exclude regex filters for iCal events (#7528)
* feat(calendar): add per-provider include/exclude regex filters for iCal events

* fix(calendar): mask filterIncludeRegex and filterExcludeRegex in privacy export

Regex filter patterns can contain user-specific title fragments (e.g.
ClientName|Project Alpha) and must be treated as PII.

* fix(calendar): apply regex filters to initial cached calendar emission

Cached events emitted via defer() bypassed regex filters because
provider config was not yet available. The initial emission now reads
selectCalendarProviders first so filterIncludeRegex/filterExcludeRegex
are applied consistently from the start.

* fix(calendar): reconcile banner queue when provider regex filters change

Events queued in _currentlyShownBanners$ were not re-evaluated when a
provider's filterIncludeRegex or filterExcludeRegex changed, so excluded
events could linger until dismissed. The new reconcileBannersOnProviderChange
effect filters the queue against the updated config on every provider change.

* fix(calendar): store raw fetch data in cache before applying regex filters

Regex-excluded events were permanently lost from the cache because
saveToRealLs was called after the filter pass. If a user loosens or
removes a regex while offline, the fallback cache could not restore
those events until the next successful fetch.

The cache now stores unfiltered source data; regex and task/skip/hidden
filters are applied only for the downstream emission.

* fix(calendar): resolve regex filter config per-event in initial cached emission

The defer() path derived one provider config from entry.items[0]?.calProviderId
and applied it to every item in the cache entry. Mixed-provider entries
would apply provider A's regex to provider B's events.

Config is now resolved inside the filter callback via calEv.calProviderId,
matching how _groupCachedEventsByProvider() already handles per-item grouping.

Regression test added with a mixed-provider cached entry verifying that
each event is filtered against its own provider's config.

* fix(calendar): apply full view-level filters to initial cached emission

The defer() path only applied regex filters, so task-imported, skipped,
and hidden events could briefly reappear on startup until the first fetch
completed. Now reads all four filter sources in a single combineLatest
snapshot and applies the same ID-based checks as the live fetch path.

Regression test added for all three ID-based filter types.

* fix(calendar): reapply regex filters from cache

* fix(calendar): hide stale cached provider events

* fix(calendar): filter manual iCal search

* fix(calendar): refresh agenda filters

---------

Co-authored-by: agncr <a.gencer@thalia.de>
Co-authored-by: agncr <agncr@users.noreply.github.com>
Co-authored-by: johannesjo <johannes.millan@gmail.com>
2026-05-11 00:12:01 +02:00
Florian Bachmann
6c1a0b54f9
Caldav subtask import (#7409)
* fix(electron): disable webSecurity in dev mode to suppress CORS preflights

* feat(CalDAV): Option to import sub-tasks along with parent

* test(CalDAV): Adds specs for option to import subtasks along with parent

* doc(CalDAV): Adds notion on automatic sub-task import

* feat(CalDAV): Handles grandchildren and ignores subtasks of archived tasks.

* fix(setup): removes policy violating code

* fix(caldav):_resolve N+1 issue

* test(caldav):_adds more tests

* fix(electron):_fix task-widget mock in electron test
2026-05-01 13:07:03 +02:00
Spyros Seimenis
fede2c6ada
feat(gitea): add label-based include and exclude filters (#7359)
* feat(gitea): add label-based include and exclude filters

Adds two optional config fields to the Gitea issue provider. filterLabels
is a comma-separated allowlist forwarded to the issues endpoint as the
`labels` query param (AND-matched server-side). excludeLabels is a
comma-separated denylist applied client-side, since Gitea/Forgejo's
issues endpoint has no negation syntax. Scoped labels (scope/name) work
with both.

This lets users point multiple Gitea integrations at the same repository
and route disjoint subsets of issues into different Super Productivity
projects, e.g. one project filtering `project/foo` and another excluding
it.

Filters apply only to ingestion (search suggestions and auto-import of
open issues). Already-imported tasks keep refreshing regardless of label
changes, matching how the existing `scope` filter behaves.

* docs(gitea): document label include/exclude filtering

Update the issue-integration comparison page with the new label
allowlist and denylist filters, including scoped-label support.

* feat(gitea): enforce filterLabels AND match client-side

Gitea's two issue endpoints (`/repos/{o}/{r}/issues` and
`/repos/issues/search`) parse the `labels=` query param into different
internal fields and produce different semantics (AND vs OR), so the
same `filterLabels` config behaved differently on auto-import vs
manual search. The AND on the auto-import path is also a Gitea bug
(go-gitea/gitea#33509) that may flip to OR upstream at any time.

Apply AND-matching on the client (mirroring how `excludeLabels`
already filters client-side) so behavior is consistent across both
endpoints and independent of server version. The `labels=` query is
still sent as a coarse pre-filter (always a superset of the right
answer regardless of server semantics). Forgejo inherits the same
endpoints from Gitea, so the same fix covers it.
2026-04-26 19:10:18 +02:00
Corey Newton
d4b615abde docs(wiki): clarify differences between iCal and CalDAV
Some discussion and research has confirmed a few things. More field
reports needed to help extend How-To guides
2026-02-16 16:23:32 +01:00
Corey Newton
5f1dd7ef7f docs(wiki): normalize tables and rework ToC 2026-02-04 14:45:00 +01:00
Corey Newton
ff674fc6c9 docs(wiki): substantial addition of integrations (issue and sync)
Much of these notes will need additional validation prior to v1.0 as I have not yet used supersync and many of the other services.
2026-02-04 14:45:00 +01:00