Skip to content

Stable#819

Open
knep wants to merge 192 commits into
bugy:stablefrom
knep:stable
Open

Stable#819
knep wants to merge 192 commits into
bugy:stablefrom
knep:stable

Conversation

@knep

@knep knep commented Jun 17, 2026

Copy link
Copy Markdown

No description provided.

dependabot Bot and others added 30 commits August 30, 2023 22:13
Bumps [apollo-server-core](https://github.com/apollographql/apollo-server/tree/HEAD/packages/apollo-server-core) from 2.26.0 to 2.26.2.
- [Release notes](https://github.com/apollographql/apollo-server/releases)
- [Commits](https://github.com/apollographql/apollo-server/commits/apollo-server-core@2.26.2/packages/apollo-server-core)

---
updated-dependencies:
- dependency-name: apollo-server-core
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
…/apollo-server-core-2.26.2

Bump apollo-server-core from 2.26.0 to 2.26.2 in /web-src
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.21.4 to 7.23.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
…/babel/traverse-7.23.2

Bump @babel/traverse from 7.21.4 to 7.23.2 in /web-src
Bumps [browserify-sign](https://github.com/crypto-browserify/browserify-sign) from 4.2.1 to 4.2.2.
- [Changelog](https://github.com/browserify/browserify-sign/blob/main/CHANGELOG.md)
- [Commits](browserify/browserify-sign@v4.2.1...v4.2.2)

---
updated-dependencies:
- dependency-name: browserify-sign
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
…/browserify-sign-4.2.2

Bump browserify-sign from 4.2.1 to 4.2.2 in /web-src
Bumps [axios](https://github.com/axios/axios) from 0.27.2 to 1.6.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](axios/axios@v0.27.2...v1.6.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
…/axios-1.6.0

Bump axios from 0.27.2 to 1.6.0 in /web-src
Bumps the npm_and_yarn at /web-src security update group in /web-src with 1 update: [rss-parser](https://github.com/bobby-brennan/rss-parser).

- [Commits](rbren/rss-parser@v3.12.0...v3.13.0)

---
updated-dependencies:
- dependency-name: rss-parser
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [@adobe/css-tools](https://github.com/adobe/css-tools) from 4.0.1 to 4.3.2.
- [Changelog](https://github.com/adobe/css-tools/blob/main/History.md)
- [Commits](https://github.com/adobe/css-tools/commits)

---
updated-dependencies:
- dependency-name: "@adobe/css-tools"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
…/adobe/css-tools-4.3.2

Bump @adobe/css-tools from 4.0.1 to 4.3.2 in /web-src
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.2 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](follow-redirects/follow-redirects@v1.15.2...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
…/follow-redirects-1.15.4

Bump follow-redirects from 1.15.2 to 1.15.4 in /web-src
fix: XSS attack via next login parameter.
Bumps [ip](https://github.com/indutny/node-ip) from 1.1.8 to 1.1.9.
- [Commits](indutny/node-ip@v1.1.8...v1.1.9)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
…/ip-1.1.9

Bump ip from 1.1.8 to 1.1.9 in /web-src
Thomas Kpenou and others added 29 commits June 10, 2026 20:10
Third component on Vuetify. Only the rendering layer changed: v-textarea
with auto-grow replaces the materialize textarea + M.textareaAutoResize /
M.updateTextFields. The validation logic (required, max_length) and the
external contract (modelValue/config props, update:modelValue + error
emits, data-error attribute) are untouched; setCustomValidity is still
applied to the native textarea.

Test note: Vuetify forwards non class/style/id/data-* attrs to the inner
textarea, so the config.description tooltip now lives on the <textarea>
instead of the root element (same as the migrated Textfield); the
assertion was updated accordingly.

Validation: 821 unit tests green, e2e 8/8, build green. Visual check on
the admin script form (port 5099 fixture): v-textarea renders with the
floating label and auto-grows, value round-trips through v-model, no
console errors, no materialize textarea left, no style bleed on the
surrounding materialize inputs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…dialog

Fourth component on Vuetify. v-radio-group/v-radio replace the materialize
radio markup; the custom per-option icon (changed-mode warning) keeps its
own <i class="option-icon"> in the label slot since Vuetify's md iconset
also renders i.material-icons for the radio glyphs. New RadioGroup unit
tests (the component had none).

The migration surfaced two latent Vue 3 bugs around its only consumer,
the script-edit dialog — both fixed:

- ScriptField declared the dialog with the Vue 2 async-component syntax
  (`() => import(...)`), which Vue 3 renders as the literal text
  "[object Promise]": the dialog could never open in the built app. The
  module was already statically imported for its mode constants, so the
  lazy wrapper is simply dropped.
- RadioGroup still used the Vue 2 v-model contract (value prop + input
  event), so the dialog's v-model never received mode changes. Moved to
  modelValue/update:modelValue.

Fallout of the earlier textfield migration, fixed here: the old Textfield
imported materialize input-fields globally, which defined
M.updateTextFields for everyone. ScriptEditDialog's call (its fields are
all Vuetify now) is removed; SchedulePanel and TimePicker, still
materialize, now import input-fields themselves.

Validation: 826 unit tests green (incl. 5 new RadioGroup), e2e 8/8, build
green. Browser check on the fixture admin: dialog opens, the three modes
(path/code/upload) switch correctly via the Vuetify radios, no console
errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fifth and biggest component on Vuetify. v-select renders the dropdown;
when the option list is long enough to need filtering (>10 options, as
before), the component switches to v-autocomplete with type-to-filter in
the field — replacing the materialize in-dropdown ComboboxSearch, which
is deleted. All the FormSelect plumbing (rebuildCombobox, manual DOM
sync, onchange subscription, Firefox two-phase disable) is gone; the
value/validation business logic (_fixValueByAllowedValues, _validate,
forceValue with disabled obsolete options, multiselect emit filtering)
is untouched. External contract preserved: config/modelValue/disabled/
forceValue/showHeader props, update:modelValue + error emits, data-error.
dropdownContainer is accepted but unused (Vuetify menus are teleported
overlays). The "Choose your option(s)" header becomes a persistent
placeholder; loading uses the built-in progress bar instead of the
CircleSpinner overlay.

Tests:
- combobox_test.js rewritten against the Vuetify markup (40 tests, all
  active): options are read from the teleported overlay, search drives
  the v-autocomplete input. 8 scenarios that were skipped under jsdom
  with materialize (multiselect by clicks, forced initial values, click
  on disabled values, loading=true) now actually run.
- the shared admin-form helper setValueByUser drives Combobox through
  its update handler (no native <select> anymore); findFieldInputElement
  returns the v-select <input>.
- e2e "changes a combobox value" updated to click the v-field and the
  overlay list item.

Side fix: materialize Collapsible relied on the anime.js global loaded
transitively via the old combobox (select -> dropdown -> anime); the
collapsible import now loads it explicitly.

Validation: 827 unit tests green, e2e 8/8, build green. Browser check on
the fixture main app: v-select renders with label/selection, menu opens,
selecting beta updates the field, no console errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Three more components on Vuetify:

- ChipsList: v-combobox (multiple + chips + closable-chips) replaces
  M.Chips. Enter-to-add and chip removal come with the component; the CSV
  behaviours are preserved as business logic: typing an unescaped comma
  commits the finished segments live (keeping the trailing fragment in
  the input), focus loss commits the pending text (via VCombobox's own
  blur commit, normalized in the update handler), and `\,` escapes a
  comma inside a value. One subtlety: when the committed search returns
  to the same prop value (''), Vue won't rewrite the user-typed DOM input,
  so the component syncs the native input explicitly.

- PromisableButton: v-btn with the built-in :loading spinner replaces the
  materialize flat button + embedded preloader markup. Promise handling
  (click -> inProgress -> error with userMessage) untouched; the
  preloaderStyle prop is accepted but unused now. The dead spinner CSS in
  ScriptConfig's footer is removed.

- CircleSpinner: deleted — its last consumer was the pre-migration
  combobox.

Tests: ChipList suite rewritten against the v-combobox markup (9 tests,
incl. 2 new: external value change, chip removal via the close button).
The shared setChipListValue helper now emits through the component's
v-model instead of driving the M.Chips instance.

Validation: 829 unit tests green, e2e 8/8, build green. Browser check on
the fixture admin: CSV typing 'user1,user2\,with-comma,partial' produces
the user1 + "user2,with-comma" chips with 'partial' left in the input;
Delete/Save footer buttons render as v-btn; no console errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Pickers on Vuetify:

- DatePicker: v-date-input (text field + calendar menu) replaces the
  M.Datepicker modal. Same constraints: min date today, weeks start on
  Monday, value emitted only when the picked date changed. The
  showHeaderInModal prop is kept for compatibility (the Vuetify calendar
  has no modal header at all, matching the old headless rendering).
- TimePicker: v-text-field replaces the materialize input +
  M.updateTextFields / M.validate_field plumbing. The HH:MM validation is
  untouched; the displayed text is deliberately decoupled from the model
  so an invalid typed time stays visible with its error instead of
  snapping back to the last valid value (the model only receives valid
  times, as before). The 10 existing TimePicker tests pass unchanged.
- SchedulePanel drops its materialize datepicker import.

Third latent Vue 3 bug found and fixed (browser check, not by tests):
SchedulePanel.checkErrors walked this.$children — an API removed in
Vue 3 — and threw on every field error, so the Schedule button was never
disabled on invalid input. Field errors now arrive through keyed @error
events into a fieldErrors map, filtered by the fields rendered in the
current mode (one-time vs repeat, end option), which mirrors the old
walk over mounted children.

e2e fixture: scheduling enabled on E2E Echo so the schedule panel is
reachable in e2e and manual checks.

Validation: 829 unit tests green, e2e 8/8, build green. Browser check on
the fixture main app: schedule panel opens with both Vuetify pickers
prefilled, calendar opens with past days disabled, picking a date
updates the field, typing 99:99 shows 'Format HH:MM' and disables the
Schedule button, fixing the time re-enables it; no console errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The server-file picker field is on Vuetify: a readonly v-text-field with
the folder_open icon inside the field (append-inner) opens a v-dialog
hosting the existing FileDialog browser — file_dialog.vue is untouched,
it never depended on materialize JS (only on shared CSS classes).
Preserved behaviours: open on click/Enter/Space, focus the browser on
open and the field back on close, required validation, value emitted
only when the chosen path changed, left-side path truncation.

e2e fixture: a ConfFile server_file (recursive) parameter was added to
E2E Echo so the field actually renders in e2e and manual checks
(non-recursive server_file params are flattened to plain list values by
the server and render as a Combobox). Parameter-count assertions updated
to 3.

Validation: 829 unit tests green, e2e 8/8, build green. Browser check on
the fixture main app: field renders with the folder icon, the dialog
opens with the file listing, double-clicking a file closes the dialog
and fills the field; no console errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat: UI migration to Vuetify 4 (phase 1 — all form components)
Two refreshes in flight with the same refresh token caused the second
to get a 401 from the provider (token already rotated) and log the
user out. Guard _refresh_token with a per-user asyncio.Lock and add
regression tests for refresh/validation races. Also stop expiring old
access tokens in the Keycloak test mock on refresh - real Keycloak
access tokens are stateless JWTs that stay valid until expiration.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
_schedule_token_refresh checked self._scheduler but assigned
self.scheduler, so the check never passed and every refresh created a
new Scheduler with its own daemon thread. Use _scheduler consistently
so a single instance is created lazily and reused.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fix(auth): OAuth refresh race and Scheduler thread leak
Replace all remaining materialize-css usage in the main-app sidebar:

- ScriptListItem: materialize spinner + collection-item → v-list-item
  with v-progress-circular / v-icon state indicator
- ScriptListGroup: collection-item toggle → v-list-group with activator
  slot; open state managed by v-list v-model:opened
- ScriptsList: div.collection → v-list open-strategy="single";
  activeGroup/groupClicked replaced by openedGroups array
- SearchPanel: PNG image buttons → v-btn icon (search/close Material Icons)
- MainAppSidebar: waves-effect btn-flat → plain router-link + CSS;
  btn-icon-flat waves-circle → v-btn icon
- AppLayout: btn-flat menu → v-btn icon; progress indeterminate → v-progress-linear

Test suite updated to use Vuetify DOM selectors (.v-list-group,
.v-list-group__header, .v-list-group--open); all 12 group tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- AdminApp: M.Tabs → v-tabs + v-tab :to; home btn-flat → v-btn icon
- admin/ScriptsList: collection/btn → v-list/v-btn; parsing-failed via :title
- ScriptParamList: ul.collapsible → v-expansion-panels v-model (guid-based);
  M.toast FIFO queue → v-snackbar + undoQueue; M.Collapsible → openedPanel state
- ParamListItem: <li> → v-expansion-panel :value; action btns absolutely
  positioned outside title button to avoid nested-<button> invalid HTML
- ScriptEditDialog: M.Modal → v-dialog v-model; non-scoped CSS for overlay sizing
- ScriptField: btn-icon-flat → v-btn :icon size="large"
- CodeEditor: remove materializecss/cards import
- ScriptConfig: deep CSS selectors a.btn-flat → .v-btn (PromisableButton migrated)
- ParameterList_test: rewrite helpers for Vuetify DOM (openedPanel/panelValue,
  snackbar vm state, querySelector 'i' for buttons)
- ScriptField_test: remove M.Modal.defaults from beforeAll/afterAll

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove the materialize-css package and all associated glue code now that
every component has been migrated to Vuetify or vanilla CSS:
- Delete src/common/materializecss/imports/ (13 JS shim files)
- Delete src/assets/css/materializecss/ (13 material-*.css overrides)
- Delete src/common/style_imports.js (no longer imported anywhere)
- Remove materialize-css from package.json; fix tinycolor2 indentation
- Strip the two vite.config.js plugins that patched materialize internals
- Strip the SCSS preprocessorOptions block (no more materialize SCSS tokens)
- Update entry points (admin.js, main-app/index.js, login.js) to import
  material-design-icons, typeface-roboto and shared.css directly
- Remove M.updateTextFields / M.toast / materialize import calls from
  SchedulePanel, login, and other migrated components
- Fix tests/unit/setup.js: drop the M-global bootstrap import
- Fix ScriptField_test.js: drop M.Dropdown animation tweaks (all dialog
  tests using materialize modals are already in describe.skip)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Update the 2026-06-10 entry to reflect the completed migration:
- Mark as complete (was "in progress")
- Add the sidebar, script-view, admin tabs/dialogs, and login to the
  migrated-views list
- Document materialize-css removal (shims, CSS overrides, Vite plugins)
- Collapse redundant detail; keep the bug-fix and behaviour-change notes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace every Vuex module with a Pinia store (defineStore, Options API
style). Dynamic per-execution Vuex modules become createExecutor() factory
returning reactive() objects. Runtime require() workarounds inside action
bodies replaced by standard top-level ES imports.

Key changes:
- src/{admin,common,main-app}/store/ removed; src/*/stores/ added
- ScriptListItem.vue: missed Vuex accessor fixed (uses executionsStore now)
- All 14 test files rewritten: createPinia/setActivePinia, direct state
  assignment, vi.spyOn for side-effect stubs
- execution-details_test: date assertion made locale-independent
- ExecutionInstanceTabs_test: updated for Vuetify 4 DOM (button.v-tab,
  v-tab--selected)
- AppHistoryPanel_test: axios mock added to suppress init() network calls;
  state reset after route changes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
.tab → .v-tab, .collection-item → .v-list-item after Vuetify migration.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.4.8 to 3.4.9.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](cure53/DOMPurify@3.4.8...3.4.9)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-version: 3.4.9
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [form-data](https://github.com/form-data/form-data) from 4.0.5 to 4.0.6.
- [Release notes](https://github.com/form-data/form-data/releases)
- [Changelog](https://github.com/form-data/form-data/blob/master/CHANGELOG.md)
- [Commits](form-data/form-data@v4.0.5...v4.0.6)

---
updated-dependencies:
- dependency-name: form-data
  dependency-version: 4.0.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
…urify-3.4.9

chore(deps): bump dompurify from 3.4.8 to 3.4.9 in /web-src
…-data-4.0.6

chore(deps): bump form-data from 4.0.5 to 4.0.6 in /web-src
Without emits declarations, Vue 3 treats onXxx listeners as fallthrough
attributes on the root element, causing native DOM events to trigger
component handlers (as seen in ScriptEditDialog where radio change events
were incorrectly invoking onScriptChange).

Components fixed: ScriptEditDialog, ScriptUploader, CodeEditor,
ParameterConfigForm, ParameterValuesUiMapping, SchedulePanel,
ParameterHistoryModal, ScheduleButton, ScriptViewScheduleHolder.

ScriptField_test.js: un-skip the 3 dialog describe blocks (now testable
via document.body.querySelector on Vuetify teleported overlay), fix
verifyRadioWarnings selector (i.material-icons.option-icon), reset
getFileInputValueMock in afterEach to prevent cross-test contamination.

ExecutionInstanceTabs_test.js: remove permanently-skipped indicator
position block (jsdom has no layout engine; Vuetify handles tabs natively).

867 unit tests passing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Both were dead dependencies — the codebase uses ace-builds exclusively
for code editing. Neither brace nor codemirror were imported anywhere
in src/.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
tornado>=6.1 and requests>=2.28 had no upper bound, meaning a future
tornado 7.x or requests 3.x (currently in development) could be
installed on a fresh pip run and silently break the build.

~= (PEP 440 compatible release) allows patch/minor updates within the
current major (tornado~=6.1 → >=6.1,<7 ; requests~=2.28 → >=2.28,<3)
without opening the door to breaking major versions.

1662 Python tests passing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ExecutionInstanceTabs: 4 it.skip removed — the add-tab button is now
always rendered (Vuetify manages overflow natively; no more hasMoreSpace
layout guard). Fix selectors: .add-execution-tab-button → .add-execution-tab.

htpasswd DES-crypt: replace removed stdlib `crypt` module with a ctypes
call to the system crypt(3) function (available on macOS via libc and
on Linux via libcrypt). Remove 2 @unittest.skipIf guards.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…thon 3.16)

server.py: on Windows, use asyncio.set_event_loop(SelectorEventLoop())
instead of the deprecated WindowsSelectorEventLoopPolicy — same effect,
no global policy change.

server_test.py: replace set_event_loop_policy(None) teardown with
asyncio.set_event_loop(None), which clears the current loop without
touching the global policy and carries no deprecation warning.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- fix(vue): declare missing emits on 9 components, fix ScriptField tests
- chore(deps): remove unused brace and codemirror packages
- chore(deps): pin Python deps to compatible-release bounds (~=)
- fix(tests): un-skip 6 tests — Vuetify migration and crypt module removal
- fix(asyncio): replace deprecated set_event_loop_policy (removed in Python 3.16)
- docs: README — code quality and Python 3.14 compatibility section
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.