fix: Propagate review filtered status (#2370)

This commit is contained in:
Dermot Duffy
2026-02-22 15:50:20 -08:00
committed by GitHub
parent 191b5a289a
commit dd25e191ce
3 changed files with 117 additions and 19 deletions
+6 -3
View File
@@ -167,13 +167,16 @@ export class AdvancedCameraCardThumbnailFeature extends LitElement {
}} }}
@click=${async (ev: Event) => { @click=${async (ev: Event) => {
stopEventFromActivatingCardWideActions(ev); stopEventFromActivatingCardWideActions(ev);
if (this.item) { if (
await toggleReviewed( this.item &&
(await toggleReviewed(
this.item, this.item,
this.viewItemManager, this.viewItemManager,
this.viewManagerEpoch, this.viewManagerEpoch,
this.filterReviewed, this.filterReviewed,
); ))
) {
this.requestUpdate();
} }
}} }}
></advanced-camera-card-icon>` ></advanced-camera-card-icon>`
+26 -16
View File
@@ -355,9 +355,11 @@ export class UnifiedQueryBuilder {
return null; return null;
} }
return this._buildQueryNodesCapabilityUnchecked(spec, cameraID, { return this._buildQueryNodesCapabilityUnchecked(
limit: options?.limit, spec,
}); cameraID,
this._resolveReviewedFilter(spec, cameraID, options),
);
} }
// ========================================================================= // =========================================================================
@@ -399,21 +401,13 @@ export class UnifiedQueryBuilder {
continue; continue;
} }
// For reviews, resolve the reviewed filter from camera config if not provided
const resolvedOptions =
cameraSpec.mediaType === 'reviews' && options?.reviewed === undefined
? {
...options,
reviewed: getReviewedQueryFilterFromConfig(
this._cameraManager.getStore().getCameraConfig(cameraID)?.media
?.reviewed,
),
}
: options;
this._addNode( this._addNode(
query, query,
this._buildQueryNodesCapabilityUnchecked(cameraSpec, cameraID, resolvedOptions), this._buildQueryNodesCapabilityUnchecked(
cameraSpec,
cameraID,
this._resolveReviewedFilter(cameraSpec, cameraID, options),
),
); );
} }
return query.hasNodes() ? query : null; return query.hasNodes() ? query : null;
@@ -530,6 +524,22 @@ export class UnifiedQueryBuilder {
}; };
} }
private _resolveReviewedFilter(
spec: MediaTypeSpec,
cameraID: string,
options?: QueryFiltersOptions,
): QueryFiltersOptions | undefined {
if (spec.mediaType !== 'reviews' || options?.reviewed !== undefined) {
return options;
}
return {
...options,
reviewed: getReviewedQueryFilterFromConfig(
this._cameraManager.getStore().getCameraConfig(cameraID)?.media?.reviewed,
),
};
}
private _extractFilterOptions(options?: QueryFilters): QueryFilters { private _extractFilterOptions(options?: QueryFilters): QueryFilters {
return { return {
...(options?.favorite !== undefined && { favorite: options.favorite }), ...(options?.favorite !== undefined && { favorite: options.favorite }),
+85
View File
@@ -652,6 +652,91 @@ describe('UnifiedQueryBuilder', () => {
assert(isReviewQuery(query.getNodes()[0])); assert(isReviewQuery(query.getNodes()[0]));
}); });
it('should apply reviewed filter from config for reviews query', () => {
const { cameraManager, foldersManager, store } = createMocks();
store.getCameraIDs.mockReturnValue(new Set(['camera.office']));
store.getCameraConfig.mockReturnValue(
createCameraConfig({ media: { type: 'auto', reviewed: 'unreviewed' } }),
);
cameraManager.getCameraCapabilities.mockReturnValue(
createCapabilities({ reviews: true }),
);
const builder = new UnifiedQueryBuilder(cameraManager, foldersManager);
const query = builder.buildDefaultCameraQuery();
assert(query);
expect(query.getNodes()[0]).toMatchObject({
type: QueryType.Review,
reviewed: false,
});
});
it('should apply reviewed=true filter from config', () => {
const { cameraManager, foldersManager, store } = createMocks();
store.getCameraIDs.mockReturnValue(new Set(['camera.office']));
store.getCameraConfig.mockReturnValue(
createCameraConfig({ media: { type: 'auto', reviewed: 'reviewed' } }),
);
cameraManager.getCameraCapabilities.mockReturnValue(
createCapabilities({ reviews: true }),
);
const builder = new UnifiedQueryBuilder(cameraManager, foldersManager);
const query = builder.buildDefaultCameraQuery();
assert(query);
expect(query.getNodes()[0]).toMatchObject({
type: QueryType.Review,
reviewed: true,
});
});
it('should not apply reviewed filter when config is all', () => {
const { cameraManager, foldersManager, store } = createMocks();
store.getCameraIDs.mockReturnValue(new Set(['camera.office']));
store.getCameraConfig.mockReturnValue(
createCameraConfig({ media: { type: 'auto', reviewed: 'all' } }),
);
cameraManager.getCameraCapabilities.mockReturnValue(
createCapabilities({ reviews: true }),
);
const builder = new UnifiedQueryBuilder(cameraManager, foldersManager);
const query = builder.buildDefaultCameraQuery();
assert(query);
assert(isReviewQuery(query.getNodes()[0]));
expect(query.getNodes()[0]).not.toHaveProperty('reviewed');
});
it('should not apply reviewed filter to non-review queries', () => {
const { cameraManager, foldersManager, store } = createMocks();
store.getCameraIDs.mockReturnValue(new Set(['camera.office']));
store.getCameraConfig.mockReturnValue(
createCameraConfig({
media: { type: 'auto', reviewed: 'unreviewed' },
}),
);
cameraManager.getCameraCapabilities.mockReturnValue(
createCapabilities({ clips: true }),
);
const builder = new UnifiedQueryBuilder(cameraManager, foldersManager);
const query = builder.buildDefaultCameraQuery();
assert(query);
expect(query.getNodes()[0]).toMatchObject({
type: QueryType.Event,
hasClip: true,
});
expect(query.getNodes()[0]).not.toHaveProperty('reviewed');
});
it('should build clips query for camera with clips capability', () => { it('should build clips query for camera with clips capability', () => {
const { cameraManager, foldersManager, store } = createMocks(); const { cameraManager, foldersManager, store } = createMocks();
store.getCameraIDs.mockReturnValue(new Set(['camera.office'])); store.getCameraIDs.mockReturnValue(new Set(['camera.office']));