159 Commits

Author SHA1 Message Date
agent_coder
3c7400ca2a fix(update): derive git-stack flag from WorkflowID to match Go daemon (closes #17)
The TS update-routing used the deprecated `!!stack.GitConfig` to flag a
git-backed stack, which can diverge from the canonical Go daemon routing
(`IsGit: st.WorkflowID != 0`) on the new Workflow/Source model. Derive it from
WorkflowID instead (added WorkflowID to the client Stack type). The stack-type
filter (Type === DockerCompose) was already in place and tested.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 23:34:10 +03:00
594312a777 Merge pull request 'feat(automation): native container auto-update (Watchtower-style) + auto-heal (#3)' (#19) from feat/3-auto-update into develop
Reviewed-on: #19
2026-07-01 23:25:24 +03:00
6a4242b166 Merge pull request 'feat(logs): live HTTP stream + append-only render (#2)' (#6) from feat/2-stream-logs into develop
Reviewed-on: #6
2026-07-01 22:09:47 +03:00
agent_coder
a60b7be55d fix(#6): address review — hook reconnect/trim tests, sticky error banner, stale comment
- F1: cover the hook's riskiest path — a following stream that ends with an
  unwritten tail fragment then resumes (tail:0 + nano-since), asserting the
  fragment is dropped, resume params are correct, and the boundary line is
  deduped to one; plus MAX_LOG_LINES head-trim and buffer reset on
  resourceId/lineCount change.
- F2: clear the error banner on a SUCCESSFUL reconnect (via a new onOpen signal
  on StreamLogsFn), not only when new lines arrive — an idle-but-healthy
  reconnect no longer leaves a stuck 'unable to stream' banner.
- F4: update the stale comment in the React logs view registration (the React
  logs migration is now complete).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 20:55:15 +03:00
agent_coder
5bb678d3ba fix(#19): address review F1-F4 (badge test, force write-back test, force throttle, per-container stack notifications)
- F1: test that clicking the badge/UpdateNowButton actually dispatches the update
  (confirm->mutate) for standalone and stack, and not on dismiss.
- F2: Go test that a successful forced re-check repopulates the caches (a later
  non-force read hits cache, no second registry HEAD).
- F3: throttle forced image-status re-checks against registry amplification —
  coalesce concurrent forced re-checks of the same image via singleflight, plus a
  5s per-image min-interval (== remoteDigestCache TTL) caching only successes. The
  non-force path (daemon + background badges) is unchanged.
- F4: notifications are now per-container. Stack-member containers each emit their
  own EventUpdated (not one aggregate stack event), Event carries the stack name
  (from the com.docker.compose.project label), and the new image digest is fetched
  best-effort by re-inspecting the container after the redeploy. Message:
  'Environment | .. / Stack [<name>] / Update [<container>]: <old> -> <new>'.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 20:50:55 +03:00
agent_coder
7f02d20e54 feat(logs): React log viewer for container logs
Replace the legacy AngularJS <log-viewer> on the container logs page with a
modern React log viewer, reusing the existing streaming (#6) and formatting/
coloring pipeline. Features: line-number gutter, zerolog level + key=value
coloring (from the existing formatter spans), from/to datetime range, Lines
limit, Line numbers / Timestamp / Wrap lines toggles, Auto refresh (live tail
on/off), Search + 'Filter search results', Copy, Download logs, and fullscreen.

The viewer is source-agnostic (StreamLogsFn), so service/task logs can adopt it
later; this PR wires container logs only. containerLogsController.js no longer
opens its own live stream (React owns fetching now), preventing a double stream.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 19:05:56 +03:00
agent_coder
6aecdfbe46 feat(containers): interactive image-status badge (click to update / re-check)
Make the container image-status badge actionable, matching native Portainer:
- Clicking "Update available" opens the update confirm dialog and runs the
  existing update flow (standalone recreate-with-pull / stack redeploy), gated
  and disabled while in flight to avoid a double submit. The confirm+apply logic
  is extracted from UpdateNowButton into a shared useApplyContainerImageUpdate
  hook so the details button and the list badge share one implementation.
- Clicking "Up to date" re-queries the registry. Because the server caches image
  status (statusCache 5m + remoteDigestCache 5s), a plain refetch was a no-op, so
  the endpoint gains an optional ?force=true that bypasses BOTH caches for a
  manual re-check while still repopulating them; the default (auto badges + the
  auto-update daemon) keeps using the caches unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 19:04:49 +03:00
agent_coder
f379e8057e fix(stacks): keep stack breadcrumb on container Quick Actions
The stack container list reuses the shared containers datatable, whose
Quick Actions column linked to the global docker.containers.container.*
states with only {id,nodeName}. Clicking Logs/Stats/Console/Inspect/Attach
from within a stack therefore jumped to the global route and collapsed the
breadcrumb to "Containers > <name> > Logs", losing the stack trail that
PR #7 added.

Thread the current stack route params (via RowContext) down to
ContainerQuickActions so, when rendered inside a stack, its links target the
stack-scoped docker.stacks.stack.container.* sub-tab states (reusing #7's
buildStackContainerLinkParams / STACK_CONTAINER_STATE_NAME helpers). The
global containers list and service tasks pass no stack params and keep the
global links unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 18:52:44 +03:00
claude code agent
474c41ec8e Merge remote-tracking branch 'origin/develop' into feat/2-stream-logs
# Conflicts:
#	app/docker/views/containers/logs/containerLogsController.js
2026-07-01 03:53:45 +03:00
0e572f4ccc Merge pull request 'fix(stacks): keep stack breadcrumb trail when opening a container from a stack (#4)' (#7) from feat/4-stack-breadcrumbs into develop
Reviewed-on: #7
2026-07-01 02:23:40 +03:00
claude code agent
0bf4e71b79 fix(stacks): keep the stack breadcrumb trail on container attribute sub-tabs
When a container is opened from a stack, the detail tab kept the stack
trail (PR #7) but the attribute sub-tabs (Logs, Stats, Inspect, Console,
Attach) dropped it: those tabs were registered only under the global
docker.containers.container.* tree, so navigating to one left the stack
state (and its inherited params) behind, and each sub-view set a hardcoded
"Containers > ..." breadcrumb.

- Register stack-scoped child states docker.stacks.stack.container.{attach,
  exec,inspect,logs,stats} mirroring the global ones, so the inherited stack
  params survive and the trail can be kept.
- Centralize the breadcrumb logic in containerBreadcrumbs.ts (moved out of
  ItemView, which re-exports it) and add isStackContainerState +
  getContainerSubTabBreadcrumbs + buildStackContainerLinkParams.
- ActionLinksRow links sub-tabs into the stack tree (with stack+container
  params) when opened from a stack, else the global states unchanged.
- InspectView + the logs/stats/console controllers render the stack-aware
  trail; set up-front (no name) so it survives the load window and errors.

Covers regular/external/orphaned stacks and the non-stack fallback,
matching the existing ItemView breadcrumb behavior. New unit tests in
containerBreadcrumbs.test.ts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 02:25:04 +03:00
claude code agent
9768d7bb99 fix(logs): content-exact reconnect dedup; flush partial on pause; unify since; lines fallback (F1-F5)
Maintainer pre-merge review follow-up:
F1: dedup reconnect redeliveries by EXACT boundary-line content, not just
    timestamp <= resume — a new line that merely shares the boundary nanosecond
    with a redelivered duplicate is no longer dropped (skipBoundaryContents +
    pendingBoundary). Test proves line B survives while a real dup is dropped.
F2: flush the buffered partial line on intentional pause (not reconnect) and
    strip those cosmetic lines on resume so since re-delivers the full line with
    no stale-partial twin; resume point is not advanced past the partial.
F3: unify the since param to <unix>.<nanos> for initial and reconnect.
F4: fall back to 100 lines when the Lines field is cleared (avoid tail=all).
F5: memoize the API-version pin per session; warn on frame desync.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 20:05:18 +03:00
claude code agent
e9fae32b43 test(stacks): cover orphaned branch; name the stack-container state; type link params (F1,F2,F4)
Maintainer pre-merge review follow-up:
F1: test the orphaned-stack breadcrumb branch (orphaned=true, no regular) —
    href carries stackId/orphaned, not external.
F2: extract STACK_CONTAINER_STATE_NAME so code + test share one literal.
F4: type buildStackLinkParams' return as StackLinkParams (documents the real
    shape; external stays boolean, serialized by ui-router — no runtime change).
F3 (legacy ?id= deep links) answered wontfix in the PR thread.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 19:55:41 +03:00
claude code agent
be3bfd0513 fix(automation): maintainer pre-merge review — stale detection, daemon edge cases, parity (F1-F9)
F1: cap the image-status cache TTL at 5m (was 24h) — the cache is keyed by the
    LOCAL imageID, which doesn't change when upstream pushes a new image under the
    same tag, so the 24h TTL hid new images from both the badge and the auto-update
    daemon; a short TTL re-resolves the remote digest within the poll window.
F2: document that the update->rollback guard map is in-memory (restart implication).
F3: skip auto-update for an unnamed container when rollback is on (the endpoint+name
    keyed guard can't record it, so it would loop) — pure skipUnnamedForRollback + test.
F4: wrap the pre-update ContainerInspect in context.WithTimeout(endpointTimeout).
F5: document Reload() does not interrupt an in-flight tick.
F6: floor auto-heal CheckInterval at 1s (mirrors auto-update) + test.
F7: wontfix — migration is currently correct; namespace rework is out of scope.
F8: correct the misleading SSRF/AllowList comment (no filter is applied).
F9: front auto-heal interval floor + test; dedup STALE_TIME; fix invalidation comment.
Also refresh three stale '24h/long-lived cache' comments to match the 5m TTL.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 19:51:15 +03:00
claude code agent
922f506fe5 feat(automation): guard update→rollback loop; name Settings types; tests & doc fixes (F1-F7)
F1: record rolled-back targets per service (endpointID/containerName + remote
    digest) and skip auto-update during a 24h cooldown unless the remote digest
    changes — breaks the infinite update→rollback loop on a persistently
    unhealthy image, without blocking a genuinely new image.
F2: unit-test applyContainerUpdate dispatch/payload mapping.
F3: settings_update.go comments mention auto-heal AND auto-update.
F4: drop stale '(future M4)' TS docs; primitives are frontend-only.
F5: replace the anonymous ContainerAutomation settings struct with named
    types (identical JSON tags).
F6: drop parseEnable (duplicate of boolLabel).
F7: remove the unused gitService dependency.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 14:29:57 +03:00
claude code agent
a1851417d1 test(stacks): cover external-stack breadcrumb branch in buildStackLinkParams (F1)
Add a test case driving the external-stack branch (external='true', no DB
stackId) and assert the back-link carries external=true/type and omits
stackId/regular. stackId/regular are set in the route params so the negative
assertions actually catch a fall-through-to-regular regression.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 14:06:25 +03:00
claude code agent
70f7fe5e84 Merge remote-tracking branch 'origin/feat/10-update-now' into feat/3-auto-update 2026-06-29 12:48:24 +03:00
claude code agent
b3ae5f3659 feat(automation): native auto-update daemon (#11, epic #3 M4)
Add an optional periodic auto-update daemon that detects outdated container
images and applies updates, replacing the containrrr/watchtower sidecar. It
extends M1's containerautomation service/scheduler/labels infrastructure and
reuses the existing zlib image-detection engine, the standalone Recreate path
and the stack deployer.

Backend:
- api/containerautomation/autoupdate.go: scheduler job iterating Docker
  (non-edge) endpoints -> in-scope running containers -> ContainerImageStatus;
  for Outdated: standalone -> ContainerService.Recreate(pull); stack-managed ->
  one stack redeploy-with-pull per stack per tick (git via RedeployWhenChanged,
  file via the deployer directly); external compose -> detect only. Monitor-only
  containers are status-checked (warms the badge cache) but never applied.
  Overlap guard (atomic), pull/registry-auth failure -> leave running container
  untouched, conservative cleanup of the dangling old image on the Cleanup flag
  (non-forced ImageRemove only succeeds when truly unused).
- labels.go: update enable / monitor-only labels with watchtower aliases,
  InUpdateScope, IsMonitorOnly, and pure resolveContainerUpdateRouting /
  groupContainersForUpdate (Go analogue of M3's TS routing + grouping).
- service.go: run both jobs, Reload restarts/stops each per settings; NewService
  also takes ContainerService, StackDeployer and GitService.
- Settings.ContainerAutomation.AutoUpdate {Enabled, PollInterval, Scope,
  Cleanup} with fresh-install defaults and a 2.43.0 backfill (extends M1's
  migration; golden test data updated). settings handler validates + reloads.

Frontend:
- Global AutoUpdatePanel in SettingsView (enable / poll interval / scope /
  cleanup) via useUpdateSettingsMutation, plus settings TS types.
- Read-only per-container Auto-update row in the container details view
  (Docker labels are immutable at runtime), surfacing monitor-only.

Tests: Go unit tests for the update label aliases, scope, monitor-only, the
routing decision and the one-redeploy-per-stack grouping; vitest for the panel
and the per-container row.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 10:04:09 +03:00
claude code agent
ccd5897915 fix(automation): gate stack redeploy on PortainerStackUpdate + bulk/name polish (#10 review)
F1: single-container "Update now" and bulk "Update" now require
PortainerStackUpdate when the resolved path is a stack, disabling the
action with a tooltip / skipping it rather than letting the click 403.

F2: resolveContainerUpdatePath only matches a Docker Compose stack; a
same-named swarm/kubernetes stack is treated as external.

F3: SecondaryActions no longer renders an empty ButtonGroup when all of
recreate/duplicate/update-now are hidden.

F4: bulk update reports an explicit no-op toast and counts containers vs
stacks honestly in the success summary.

F5: bulk toasts use trimmed container names (no leading slash).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 09:42:33 +03:00
claude code agent
f7cb0f3241 feat(automation): "Update now" action (stack-aware) + bulk update (#10, epic #3 M3)
Add a discoverable per-container "Update now" action, shown only when the
image status is `outdated`, plus a bulk "Update selected" action in the
containers list.

Both manual paths share ONE apply primitive (applyContainerUpdate /
useUpdateContainerImage) that also backs the future M4 auto-update job:

- standalone container  -> recreate-with-pull (existing recreate endpoint)
- stack-managed         -> stack redeploy-with-pull (existing git/file stack
                           update mutations), so the container stays in its
                           stack and is never recreated out-of-band
- externally-managed    -> refused; the details button is disabled with an
  compose                  explanatory tooltip and the bulk action skips it

Decision logic lives in the pure, unit-tested resolveContainerUpdatePath /
groupContainersForUpdate helpers. The bulk action filters to outdated
containers and redeploys each owning stack exactly once even when several of
its containers are selected, reporting per-item success/failure.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 09:24:10 +03:00
claude code agent
7eaff4dab0 fix(automation): real status cache read + nodeName key + honest errors (#9 review)
F1: ContainerImageStatus now reads the 24h statusCache (keyed by imageID)
before the remote registry digest lookup, so the cache is effective on the
input side for all callers instead of being write-only. This avoids the
rate-limited registry HEAD on repeat loads.

F2: add nodeName to the imageStatus query key so cached results cannot be
reused across nodes.

F3: correct the swagger annotations to reflect that engine-level issues
degrade to a 200 skipped/error status rather than 400/404.

F4: return a generic error message to the client instead of the raw
registry/engine error; the raw error is still logged server-side.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 09:09:18 +03:00
claude code agent
f69eb3f9eb feat(automation): CE container image update detection endpoint + badge (#9, epic #3 M2)
Add native CE detection of "a newer image is available" for running
containers, surfaced as a read-only HTTP endpoint and a containers-list
badge/column. No applying of updates (M3/M4), no auto-heal (M1).

Backend:
- New CE handler GET /docker/{id}/containers/{containerId}/image_status
  backed by the existing zlib/CE digest engine
  (images.NewClientWithRegistry + ContainerImageStatus). Honors nodeName,
  authz, and routes registry calls through the credential store / SSRF
  AllowList. Engine failures degrade to a 200 {Status:"error"} so the UI
  stays graceful. Response shape: {Status, Message?}.

Frontend (CE-only, no isBE gating; the EE ImageStatus component is left
untouched):
- useContainerImageStatus TanStack Query hook (5min staleTime, no
  refetch-on-focus; backend caches 24h) calling the non-proxied endpoint.
- UpdateStatusBadge component (own assets, neutral on skipped/error).
- "Update available" column in the containers datatable; one cached,
  non-blocking query per visible row.

Tests: Go response-shape unit test; vitest for the badge (all statuses)
and the hook (url + nodeName query param via msw).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 08:59:54 +03:00
claude code agent
b233f75ab7 fix(automation): retry-state retention + running-only heal + per-restart ctx (#8 F1-F6)
F1: prune retry-state by elapsed window since lastRestart instead of "not
seen this tick", so a container flapping through "starting" keeps its
cooldown/max-retries accounting (storm guard no longer defeated). Recovered
containers quiet for > window are still cleaned up.
F2: list running containers only (All:false) so stopped-unhealthy containers
are never revived.
F3: each ContainerRestart gets its own context (stop-timeout + buffer),
separate from the per-endpoint list context, so a slow/hung restart cannot
starve the others or exhaust a single shared deadline.
F4: start() is idempotent (no-op when a job is already scheduled); Reload
still stops first so it always reschedules.
F5: frontend parseBool mirrors Go strconv.ParseBool (case-insensitive
1/t/true; present-but-invalid counts as present & false).
F6: tests TestPruneRetries and TestRetryStateSurvivesStartingTick lock in
the F1 behavior; added AutoHealRow parse cases.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 08:39:17 +03:00
claude code agent
51957d2f98 feat(automation): native auto-heal daemon (#8, epic #3 M1)
Add a native, CE-only auto-heal daemon that restarts Docker containers whose
healthcheck reports "unhealthy", replacing the willfarrell/autoheal sidecar.

Backend:
- New package api/containerautomation (service lifecycle + scheduler job,
  per-endpoint heal pass, label/scope parsing, in-memory cooldown/retry state).
- Settings.ContainerAutomation.AutoHeal {Enabled, CheckInterval, Scope} with
  fresh-install defaults and a 2.43.0 migration backfilling existing installs.
- Settings update handler reloads/stops the job via a small Reloader interface
  (no import cycle); service bootstrapped from main.go after stack schedules.

Frontend:
- Global AutoHealPanel in SettingsView (enable / interval / scope) via
  useUpdateSettingsMutation, plus settings TS types.
- Read-only per-container Auto-heal row in the container details view (Docker
  labels are immutable at runtime; opt-in is set via Create/Edit form labels).

Tests: Go unit tests for label/scope resolution and the cooldown/retry decision;
vitest for the panel and the per-container row.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 08:22:46 +03:00
claude code agent
b4d10a67b2 fix(stacks): preserve stack tab on breadcrumb back-link + assert default crumb (F1,F2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 07:55:47 +03:00
claude code agent
cb11b0fca4 fix(stacks): keep stack breadcrumb trail when opening a container from a stack (#4)
Opening a container from a stack's Containers table showed
"Home > Containers > <container>" instead of keeping the stack trail,
so the user could not navigate back to the stack.

Two root causes are addressed:

1. Route param collision: docker.stacks.stack used the query param `id`
   for the numeric stack DB id, while its child docker.stacks.stack.container
   uses the path param `id` for the container id. Navigating into a container
   overwrote the stack id. The stack id param is renamed `id` -> `stackId`
   everywhere it is read or written (route url, stacks datatable link,
   create-stack redirect, gitops workflow card link, stack ItemView reader).

2. Hardcoded breadcrumbs: the container details ItemView always rendered the
   global "Containers" crumb. Breadcrumbs are now state-aware: when reached
   via docker.stacks.stack.container the stack trail
   (Stacks > <stack> > <container>) is rebuilt from the inherited stack params,
   honoring external/orphaned stacks.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 07:44:18 +03:00
claude code agent
960d43e70b fix(logs): byte-level frame demux + reconnect/since + notify throttle (F1-F8)
Container log live-stream review fixes (frontend only):

- F1/F2: demux Docker's multiplexed (non-TTY) stream at the BYTE level by
  frame length, decoding only payloads. Previously the stream was text-decoded
  whole and cut on '\n' before stripping 8-byte headers, which desynced when a
  length low-byte was 0x0a or a header byte was >= 0x80. streamContainerLogs
  now hands the processor raw Uint8Array chunks; createLogStreamProcessor is
  rewritten to parse frames, concatenate payloads, split lines on 0x0a, and
  UTF-8-decode complete lines. formatLogs is called without stripHeaders so
  headers are not stripped twice. Added explicit byte-frame tests.
- F3: request timestamps=1 internally and resume reconnects from the parsed
  RFC3339 timestamp of the last line (not client wall-clock); strip the prefix
  before display when the user's timestamps toggle is off; dedup the inclusive
  `since` boundary lines on reconnect.
- F4: run the fetch stream URL through dockerMaxAPIVersionInterceptor so it
  matches the axios getContainerLogs version pinning.
- F5: notify on stream error once per reconnect loop, not every 3s retry.
- F6: resuming Live no longer wipes the buffer (startStream(false)) and
  continues from `since`.
- F7: service/task logs still poll; documented the re-render limitation
  (out of scope: issue #2 is container logs).
- F8: flush the trailing partial line on the error path too (parity with onEnd).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 07:32:16 +03:00
claude code agent
c3cdb8007e feat(logs): live HTTP stream + append-only render for container logs
Replace the 3s $interval polling of container logs with a live HTTP
stream, and stop re-writing already-rendered lines (fixes selection bug).

- streamContainerLogs (containers.service.ts): fetch + ReadableStream
  reader with follow=1, same-origin credentials:'include' (httpOnly JWT
  cookie; CSRF only guards mutations), agent-target / manager-operation
  headers replicated for Agent/Edge, AbortSignal-driven lifetime.
- containerLogsController: stream instead of poll; append parsed lines
  into the buffer (push, never replace), cap at 5000 lines trimming from
  the head; AbortController on pause/destroy/param-change; reconnect with
  3s backoff resuming from `since` (dropping tail) on stream end/error;
  Live toggle pauses/resumes the stream; tail/since/timestamps changes
  restart the stream.
- log-viewer: `track by log.id` (was $index), filtering moved out of the
  template into the controller (applyFilter via $watchCollection), removed
  inert force-glue, decoupled auto-scroll from log collection, relabelled
  "Auto-refresh logs" -> "Live logs", clearer empty states.

Backend unchanged (logs already stream transparently through the Docker
proxy). Shared task/service log views keep working via the new id'd lines.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 07:03:23 +03:00
claude code agent
003a90c235 feat(ce): collapse BE edition gating in Docker/Kubernetes/Edge views
Remove always-false isBE branches, BE-only teaser controls and the
now-dead imports across the Docker, Kubernetes and Edge-stack React
views. CE behaviour is preserved; only the Business Edition branches,
teasers and BE-only (non-functional) controls are removed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 06:33:03 +03:00
nickl-portainer
152c89972b chore(eslint): update eslint to latest v9 [R8S-1090] (#2954) 2026-06-23 11:04:33 +12:00
Chaim Lev-Ari
7e5e71ae67 chore(deps): bump patch/minor frontend dependencies [BE-13004] (#2808)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 15:45:58 +03:00
Chaim Lev-Ari
dd68560ad0 chore(deps): upgrade prettier (#2592)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 16:39:58 +03:00
nickl-portainer
5eaf145eda chore(react-query): update all deprecated withError to use withGlobalError [R8S-968] (#2461)
Co-authored-by: Ali <83188384+testA113@users.noreply.github.com>
2026-04-24 16:01:59 +12:00
LP B
73ea33f36c fix(app/container): handle no healthcheck logs output (#2387) 2026-04-21 13:46:36 +02:00
Chaim Lev-Ari
3e57bc5aa0 fix(containers): show volume label when selected [BE-12819] (#2369) 2026-04-21 09:48:26 +03:00
Chaim Lev-Ari
4880e61e0f fix(containers): show ports in wrapping rows [BE-12709] (#2370) 2026-04-21 09:47:52 +03:00
Ali
ab3e0956a4 chore(tailwind): format tailwind class order [r8s-949] (#2289) 2026-04-13 16:01:10 +12:00
Chaim Lev-Ari
d5a3e46791 feat(stacks): update git url and config path [BE-12670] (#2099)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Devon Steenberg <devon.steenberg@portainer.io>
2026-03-24 15:01:46 +13:00
Oscar Zhou
8b3edb4e28 fix(docker): show correct container state for restarting and removing [BE-12707] (#2088) 2026-03-20 08:49:59 +13:00
nickl-portainer
9cba6c7475 chore(tsconfig): remove obsolete aliases (#2078) 2026-03-18 16:01:17 +13:00
nickl-portainer
ac7ff0fff4 chore(axios): move axios into own folder CE [R8S-871] (#2075) 2026-03-18 13:24:44 +13:00
Chaim Lev-Ari
808ceba848 feat(docker): allow user to specify security-opts (#2022)
Co-authored-by: dylan <dfldylan@qq.com>
Co-authored-by: jerry-yuan <i@jerryzone.cn>
2026-03-11 08:56:42 +02:00
LP B
8b61d8a9d2 fix(app/container): query env registries instead of system registries (#1996) 2026-03-06 15:03:11 +01:00
nickl-portainer
8aadddcc68 test(react): add test coverage for forms to enforce no errors showing on initial load [R8S-730] (#1696) 2026-01-28 08:12:12 +13:00
Devon Steenberg
b1cb95c3b0 fix(docker): bump docker max api version [BE-12462] (#1556) 2026-01-08 14:22:48 +13:00
LP B
372bc3c97c fix(app): generate a container name when names list is empty (#1615) 2026-01-07 20:20:28 +01:00
Chaim Lev-Ari
38c42cb47b refactor(containers): migrate container item view to react BE-6582 (#1606)
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-06 12:33:24 +02:00
Chaim Lev-Ari
c9c779d5d5 refactor(containers): migrate volume section to react BE-12495 (#1605) 2026-01-06 10:18:51 +02:00
Chaim Lev-Ari
dabfd4249e refactor(containers): migrate container details section to react BE-12494 (#1602) 2026-01-06 08:05:30 +02:00
Chaim Lev-Ari
935f3b8754 refactor(containers): migrate image section to react BE-12493 (#1594) 2026-01-01 11:12:05 +02:00