Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .agents/skills/testing-guidelines/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ uses(UnitTestCase::class)->in('Unit');
## Core Rules

- Read nearby tests first and follow their declaration and organization conventions.
- Before writing a test, identify the smallest regression it must catch and reuse an existing fixture, factory, or mount helper. For a small behavior change, prefer extending an existing test or adding one focused case.
- Keep setup and assertions proportional to the change's complexity and risk. If a short change needs a much larger test, simplify the setup before adding custom payloads or nested scenarios; retain extra coverage only for a distinct regression the change could cause.
- Use Boost's `search-docs` for version-specific Pest and Laravel testing syntax. Confirm an assertion or feature before using it.
- Test observable behavior and application contracts. Cover each changed decision and applicable high-value failure path, but leave framework behavior to framework tests.
- Run the narrowest relevant test file or filter. Rerun a test after changing it.
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
> [!IMPORTANT]
> This update contains breaking changes for plugins. See [#19574](https://github.com/craftcms/cms/pull/19574), [#19563](https://github.com/craftcms/cms/pull/19563), [#19588](https://github.com/craftcms/cms/pull/19588), and [#19585](https://github.com/craftcms/cms/pull/19585) for details.

- Replaced the condition builder with a Vue editor supporting nested AND/OR groups and repeated rules. Condition rules are now validated when applying filters or saving conditions. ([#19587](https://github.com/craftcms/cms/pull/19587))
- Removed HTMX.
- Moved legacy relation-field settings HTML and entry-title input HTML into the Yii adapter. ([#19591](https://github.com/craftcms/cms/pull/19591))
- Migrated the reassign entries, replace relations, and replace references modals to the Form API. ([#19589](https://github.com/craftcms/cms/pull/19589))
- Added support for refreshable standard plugin settings forms and conditional configuration of core form nodes. ([#19545](https://github.com/craftcms/cms/pull/19545))
Expand Down
5 changes: 0 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 0 additions & 16 deletions packages/craftcms-legacy/conditionbuilder/src/ConditionBuilder.js

This file was deleted.

17 changes: 0 additions & 17 deletions packages/craftcms-legacy/conditionbuilder/webpack.config.js

This file was deleted.

60 changes: 0 additions & 60 deletions packages/craftcms-legacy/cp/src/css/_main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4677,66 +4677,6 @@ table.data tbody tr:not(.disabled).active-drop-target {
}
}

/* ----------------------------------------
/* Condition builders
/* ---------------------------------------- */

.condition-rule,
.condition-footer {
padding: 7px;
}

.condition-footer {
border: 1px dashed var(--border-hairline-medium);
border-radius: var(--radius-lg);

.condition:not(:empty) + & {
border-block-start-width: 0;
border-start-start-radius: 0;
border-start-end-radius: 0;
}

.spinner:not(.loading) {
display: none;
}
}

.condition-rule {
margin: 0;
border: 1px solid var(--border-hairline);
background-color: var(--gray-050);

&:first-child {
border-start-start-radius: var(--radius-lg);
border-start-end-radius: var(--radius-lg);
}

& + .condition-rule {
border-block-start-width: 0;
}

& > .rule-move,
& > .rule-actions {
margin-block-start: 5px;
}

& > .rule-body {
.lightswitch {
margin-block-start: 6px;
display: block;
}

.selectize {
min-width: 100px;
}

.text.fullwidth {
min-width: 100px;
max-width: 100%;
}
}
}

/* ----------------------------------------
/* Progress bar
/* ---------------------------------------- */
Expand Down
36 changes: 26 additions & 10 deletions packages/craftcms-legacy/cp/src/js/BaseElementIndex.js
Original file line number Diff line number Diff line change
Expand Up @@ -4851,6 +4851,7 @@ const FilterHud = Garnish.HUD.extend({
serialized: null,
$clearBtn: null,
cleared: false,
applied: false,

get isActive() {
return this.showing || this.conditionConfig || this.serialized;
Expand Down Expand Up @@ -4904,8 +4905,14 @@ const FilterHud = Garnish.HUD.extend({
this.$tip.remove();
this.$tip = null;

this.$body.on('submit', (ev) => {
this.$body.on('submit', async (ev) => {
ev.preventDefault();

if (!(await this.$main.find('craft-condition-builder')[0].validate())) {
return;
}

this.applied = true;
this.hide();
});

Expand Down Expand Up @@ -4952,12 +4959,15 @@ const FilterHud = Garnish.HUD.extend({
this.clear();
});

this.$hud.find('.condition-container').on('htmx:beforeRequest', () => {
this.setBusy();
this.$hud.on('condition-builder-valid', (event) => {
const valid = event.originalEvent.detail.valid;
this.conditionValid = valid;

this.$main.find('button[type="submit"]').prop('disabled', !valid);
valid ? this.setReady() : this.setBusy();
});

this.$hud.find('.condition-container').on('htmx:load', () => {
this.setReady();
this.$hud.on('condition-builder-change', () => {
this.updateSizeAndPosition(true);
});
this.setFocus();
Expand Down Expand Up @@ -4989,10 +4999,7 @@ const FilterHud = Garnish.HUD.extend({
setBusy: function () {
this.$hud.attr('aria-busy', 'true');

$('<div/>', {
class: 'visually-hidden',
text: Craft.t('app', 'Loading'),
}).insertAfter(this.$main.find('.htmx-indicator'));
Craft.cp.announce(Craft.t('app', 'Loading'));
},

setReady: function () {
Expand Down Expand Up @@ -5072,10 +5079,15 @@ const FilterHud = Garnish.HUD.extend({
this.base();

// If something changed, update the elements
if (this.serialized !== (this.serialized = this.serialize())) {
if (
(this.applied || this.cleared) &&
this.serialized !== (this.serialized = this.serialize())
) {
this.elementIndex.updateElements();
}

this.applied = false;

if (this.cleared) {
this.destroy();
} else {
Expand All @@ -5092,6 +5104,10 @@ const FilterHud = Garnish.HUD.extend({
},

serialize: function () {
if (!this.cleared && this.conditionValid === false) {
return this.serialized;
}

return !this.cleared && this.hasRules() ? this.$body.serialize() : null;
},

Expand Down
85 changes: 0 additions & 85 deletions packages/craftcms-legacy/htmx/src/htmx.js

This file was deleted.

24 changes: 0 additions & 24 deletions packages/craftcms-legacy/htmx/webpack.config.js

This file was deleted.

1 change: 0 additions & 1 deletion packages/craftcms-legacy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
"codemirror": "^5.65.21",
"d3": "^7.9.0",
"fabric": "^1.7.22",
"htmx.org": "^1.9.12",
"iframe-resizer": "^4.4.5",
"inputmask": "^5.0.9",
"jquery": "^3.7.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/craftcms-ui/src/components/card/card.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default css`
var(--c-color-fill-quiet, var(--c-color-neutral-fill-quiet)),
transparent 70%
);
border: 1px solid
border: var(--c-card-border-width, 1px) solid
var(--c-color-border-quiet, var(--c-color-neutral-border-quiet));
border-radius: var(--c-card-radius, var(--c-radius-md));
box-shadow: var(--c-card-shadow, var(--c-shadow-sm));
Expand Down
11 changes: 6 additions & 5 deletions packages/craftcms-ui/src/components/card/card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {classMap} from 'lit/directives/class-map.js';
*
* @csspart label - The label slot within the header.
*
* @cssproperty --c-card-border-width - Border width. Defaults to `1px`.
* @cssproperty --c-card-radius - Corner radius. Defaults to `--c-radius-md`.
* @cssproperty --c-card-shadow - Box shadow. Defaults to `--c-shadow-sm`.
* @cssproperty --c-card-padding-inline - Inline (horizontal) padding of the
Expand Down Expand Up @@ -100,11 +101,11 @@ export default class CraftCard extends LitElement {

private _syncSlotPresence() {
this._hasSlottedHeader =
!!this.querySelector('[slot="header"]') ||
!!this.querySelector('[slot="label"]') ||
!!this.querySelector('[slot="actions"]');
this._hasSlottedFooter = !!this.querySelector('[slot="footer"]');
this._hasThumbnail = !!this.querySelector('[slot="thumbnail"]');
!!this.querySelector(':scope > [slot="header"]') ||
!!this.querySelector(':scope > [slot="label"]') ||
!!this.querySelector(':scope > [slot="actions"]');
this._hasSlottedFooter = !!this.querySelector(':scope > [slot="footer"]');
this._hasThumbnail = !!this.querySelector(':scope > [slot="thumbnail"]');
}

private _handleThumbnailSlotChange(event: Event) {
Expand Down
2 changes: 1 addition & 1 deletion packages/craftcms-ui/src/components/combobox/combobox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ export default class CraftCombobox extends LionCombobox {
this.inputs.setAttribute('data-combobox-inputs', '');
this.append(this.inputs);
}
// HTMX also serializes condition builders that are not inside a form.
// Detached controls can still be serialized by their host.
render(
!this.name || this.disabled || this.fieldsetDisabled
? nothing
Expand Down
Loading
Loading