Commit Graph

1236 Commits

Author SHA1 Message Date
agent_coder 8829c8cfd2 fix(#6): theme-consistent search highlight + Copied ack on Copy button
- F3: give the <mark> search highlight the full theme-token tier set
  (light / th-dark / th-highcontrast, with a legible text colour) so it reads
  correctly in every theme now that the viewer is theme-aware.
- F6: restore the transient 'Copied' acknowledgement on the Copy button via
  useCopy's copiedSuccessfully (Check icon + 'Copied' label).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 21:46:55 +03:00
agent_coder 331319f7f1 feat(logs): theme-aware log viewer (standard colors), fill height
Per maintainer feedback ('сделай поддержку светлой/темной темы', 'цвета фона
карточки подтяни к стандартным', and the white gap below):
- Drop the hardcoded dark palette; style the card/header/toolbar with the
  project's standard theme tokens (Card/Card.Header token set) + th-dark: /
  th-highcontrast: variants, so it adapts to light/dark/high-contrast like every
  other Portainer view. Reuse project Button/Input/Checkbox/Icon components; the
  log body uses the themed .log_viewer class; the range picker inherits themed
  form-control styling.
- Fill the available page height (root flex column, calc(100vh - nav/header),
  log body flex:1 min-h:0 overflow-y) so there's no dead white space below.
Layout (single toolbar row, three toggles, gutter), real data, and props are
unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 21:35:49 +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 f6752130ac feat(logs): re-skin viewer to maintainer's mockup design
Reproduce the maintainer-provided ContainerLogs mockup faithfully: dark card
(#0c0c0d), his header + single toolbar row styling, his custom search box /
'Filter search results' checkbox / Copy+Download buttons, his toggle-button
style (Line numbers / Timestamp / Wrap — no Auto refresh), and the dark log
area with a right-aligned line-number gutter. Palette carried inline in this one
component (deliberate dark log-viewer design).

Deviations from the mockup, by design: fonts/sizes use the project scale and
monospace (no Google Fonts / hardcoded Inter/JetBrains); real streaming data via
useLogViewer rendered as safe React span nodes (no dangerouslySetInnerHTML);
mock page chrome dropped (Portainer's page provides breadcrumb/title); the
datetime range keeps the functional react-datetimerange-picker. Live-tails by
default; selecting an upper bound in the range picker shows a bounded snapshot.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 20:41:23 +03:00
agent_coder 9a6dd0c408 feat(logs): match EE reference — combined datetime range picker, toggle icons
Close the visual gaps vs the maintainer's reference viewer:
- Replace the two separate From/To DateTimeField controls with a single combined
  datetime range picker (@wojtekmaj/react-datetimerange-picker, sibling of the
  react-datetime-picker / react-daterange-picker already used), from-to with time
  in one control — mirrors the existing DateRangePicker wrapper.
- Add icons to the Line numbers (List), Timestamp (Clock) and Wrap lines
  (WrapText) toggles (Auto refresh already had one).
- Line numbers gutter on by default.

Adds one dependency (@wojtekmaj/react-datetimerange-picker); all its transitive
deps were already present via the sibling pickers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 19:50:41 +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
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
vvzvlad 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 f27e44f5f2 refactor(ce): remove vestigial limitedToBE plumbing from BoxSelector (F8)
After the BE indicator was removed, limitedToBE was hardcoded false and threaded
through BoxSelectorItem.onSelect -> BoxSelector.onChange/handleSelect ->
BoxSelectorAngular.handleChange, where $setValidity(name, !limitedToBE) was a
permanent no-op (always valid). Drop the parameter from the whole chain and the
no-op $setValidity. That left formCtrl/require:'^form'/IFormController dead (they
existed only for that validity call), so remove them too — the component no longer
needs a parent form. The real on-change wiring ($evalAsync -> onChange(value)) is
unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 21:26:10 +03:00
claude code agent 5f16799b4c refactor(ce): drop orphaned OPEN_LDAP type and collapse degenerate buildUrl (F6,F7)
F6: remove SERVER_TYPES.OPEN_LDAP (read nowhere after the OpenLDAP retirement).
F7: the S3 callers that passed buildUrl(subResource, action) are gone; the only
    remaining caller uses buildUrl() with no args, so collapse it to return 'backup'.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 20:49:32 +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 28a06e80a8 refactor(ce): finish dead-BE removal — S3 backup, user-activity, LDAP, edition markers (F1-F5)
Maintainer pre-merge review follow-up (all non-blocker dead code):
F1: delete the dead S3-backup remnants (validation, query hooks, S3-only query
    key, BackupS3Model/Settings types) — kept the CE file-backup path.
F2: delete the orphaned user-activity services + their registration (kept the
    notifications component and routes).
F3: drop the unused buildOpenLDAPSettingsModel().
F4: drop the dead one-option ldap-options data (the selector was already collapsed).
F5: remove the dead data-edition attribute + its process.env typing; silence the
    intentional hasAuthorizations unused-params; drop the dead useRolesState meta.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 19:52:33 +03:00
claude code agent 90f51d48bb refactor(ce): drop orphaned access role column + no-op lodash compact (F6,F7)
F6: delete AccessDatatable/columns/role.tsx — the BE-only role column lost its
    only importer when useColumns stopped importing it; zero importers remain.
F7: useColumns wrapped only always-truthy helper.accessor results in _.compact,
    a no-op; return the plain array and drop the now-dead lodash import (same
    collapse already done in the parallel Wizard column files).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 15:08:01 +03:00
claude code agent b1b09e5da0 refactor(ce): remove leftover dead BE code — gates, orphans, dead selectors/CSS (F1-F4)
F1: drop the two HomeView edition-gate panels + their files (License/BackupFailed).
F2: delete zero-importer orphans (edition mutation, HubspotForm, HomepageFilter,
    relations mutation, ActivityLogsView cluster, ExperimentalFeatures subtree).
F3: collapse single-option selectors (Backup settings, init restore, env types)
    and delete the option files they orphaned.
F4: remove dead BE-teaser CSS rules and the --BE-only variable.
Also drop the orphaned .btn-warninglight BE-teaser variant.
F5 (limitedToBE) intentionally left — it is still read by BoxSelectorAngular.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 14:13:55 +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 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 b7df90905d feat(ce): drop OCI "Business Feature" teaser and orphaned BE edge module
Remove the disabled "Installing from an OCI registry is a Portainer
Business Feature" option from the CE Helm repository selector so no
Business Feature teaser remains; CE Helm Repositories options are
unaffected.

Delete the orphaned AutomaticEdgeEnvCreation module (incl.
EnableWaitingRoomSwitch) — its render was already removed from
EdgeComputeSettingsView and nothing imports it anymore.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 06:47:43 +03:00
claude code agent ef47503bf8 feat(ce): tear down BE edition-gating engine
Delete the feature-flags edition machinery (isBE, init/selectShow/
isLimitedToBE, FeatureId/Edition/FeatureState enums, BEFeatureIndicator,
BEOverlay, BETeaserButton, withEdition, useLimitToBE, limitedFeatureDir)
now that all consumers are gone, drop the initFeatureService bootstrap,
and update tests/stories to assert CE-only behaviour. Mechanism B
(runtime FeatureFlag) and withHideOnExtension are left untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 06:33:27 +03:00
claude code agent 7dc98df2b6 feat(ce): remove BE chrome, routes, upsell banner and shared teaser props
Drop the Upgrade-to-Business banner, BE sidebar items (Licenses, Shared
Credentials, Edge Configurations, Waiting Room, Update & Rollback), BE
branding (BE logo/footer), and BE-only routed views (update-schedules,
EdgeAutoCreateScript, WaitingRoom, TimeWindowDisplay/Picker). Prune the
featureId/feature/BEFeatureID teaser props from shared components
(Switch, SwitchField, BoxSelector, TooltipWithChildren, wizard Option)
and fold isBE in useUser while preserving CE authorization semantics.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 06:33:15 +03:00
claude code agent cddccd2a5f feat(ce): remove BE teasers from Portainer React views
Collapse isBE/isLimitedToBE consumers and delete BE-only teaser UI in
settings, gitops, registries, custom templates, environments wizard,
access control, activity logs, registries and home/system views. The
Activity Audit view keeps its route but renders a plain CE empty state.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 06:33:15 +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 6bfd2360d8 docs(security): add FAQ link to setup token messages [BE-13125] (#2995)
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-22 20:30:49 +03:00
Chaim Lev-Ari 872d1e03f6 feat(gitops): add "create new source" button to GitSourceSelector [BE-13054] (#2960)
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-22 17:19:53 +03:00
Chaim Lev-Ari a5cacd712d refactor(gitops): remove manual credential entry from git form [BE-13047] (#2951)
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-22 15:42:09 +03:00
bernard-portainer 5395dee4c6 feat(gpu-stats): add gpu stats to environments [C9S-200] (#2735) 2026-06-22 09:21:43 +12:00
nickl-portainer de5d84ade4 fix(kubernetes): handling undefined responseStatus [R8S-1072] (#2933) 2026-06-17 09:32:59 +12:00
Chaim Lev-Ari 4d539a691d feat(custom-templates): reuse existing git sources in create/update [BE-13053] (#2925)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 21:45:35 +03:00
Chaim Lev-Ari ee8e73d7f9 feat(edge/stacks): use source ID for edge stack git creation [BE-13044] (#2926)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 17:33:19 +03:00
Chaim Lev-Ari 32c6bedb98 feat(stacks): use source for kubernetes manifest git stacks [BE-13045] (#2915)
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-16 14:35:16 +03:00
Ali cd9bb18ba1 feat(policies): reuse filter status component, give consistent styles [c9s-210] (#2723) 2026-06-16 15:58:33 +12:00
Chaim Lev-Ari d9673e33ec feat(helm): reuse existing git sources in Kubernetes Helm-from-git install [BE-13046] (#2900)
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-15 22:01:31 +03:00
Chaim Lev-Ari 491df61fbf chore(hey-api): disable api validator [BE-13102] (#2918) 2026-06-15 21:35:19 +03:00
Chaim Lev-Ari ca1d9dc6a2 fix(edge/stacks): load envs by id [BE-13097] (#2917) 2026-06-15 21:23:49 +03:00
Chaim Lev-Ari fcdd6b4510 feat(stacks): use source id to create git stacks [BE-13043] (#2870)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 18:49:26 +03:00
Chaim Lev-Ari 04048c3818 fix(api): update environment status field to be optional [BE-13070] (#2847) 2026-06-15 13:36:12 +03:00
Steven Kang f87fec6d61 fix(omni): prevent partial cluster creation on Talos/Kubernetes mismatch [R8S-1058] (#2849)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 11:50:16 +12:00
Ali 391eb22d98 fix(ui): ui consistency and bug fixes [r8s-1061] (#2880) 2026-06-12 11:49:45 +12:00
andres-portainer 0da42c01b6 feat(gitcredential): remove GitCredential BE-12919 (#2838) 2026-06-11 18:53:24 -03:00
Cara Ryan ade5b2a3db feat(rbac): Add toggle for additive kubernetes RBAC policy [C9S-177] (#2814) 2026-06-11 13:44:43 +12:00
nickl-portainer 96d694b66b fix(storybook): add row id for example data for datatable story [R8S-1062] (#2856) 2026-06-11 09:10:29 +12:00
LP B 0c2f07988a feat(app/sources): source create view (#2680)
Co-authored-by: Chaim Lev-Ari <chaim.lev-ari@portainer.io>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 21:34:46 +03:00
Ali d7a1d34be7 feat(policies): docker cleanup policy [c9s-87] (#2681) 2026-06-10 16:17:23 +12:00
nickl-portainer 6a465637d4 feat(components): add new FilePicker component [R8S-1050] (#2754) 2026-06-10 10:34:14 +12:00
bernard-portainer c9e1467244 fix(stats-items): ensure stats items have consistent widths [C92-215] (#2844) 2026-06-09 16:53:17 +12:00