const original = component.getOriginalObject({ id: 4 } as Tag)
expect(original).toEqual(childTag)
})
+
+ it('getSelectableIDs should return flat ids when not overridden', () => {
+ const ids = (
+ ManagementListComponent.prototype as any
+ ).getSelectableIDs.call({}, [{ id: 1 }, { id: 5 }] as any)
+ expect(ids).toEqual([1, 5])
+ })
})
}
toggleAll(event: PointerEvent) {
- if ((event.target as HTMLInputElement).checked) {
- this.selectedObjects = new Set(this.data.map((o) => o.id))
+ const checked = (event.target as HTMLInputElement).checked
+ this.togggleAll = checked
+ if (checked) {
+ this.selectedObjects = new Set(this.getSelectableIDs(this.data))
} else {
this.clearSelection()
}
}
+ protected getSelectableIDs(objects: T[]): number[] {
+ return objects.map((o) => o.id)
+ }
+
clearSelection() {
this.togggleAll = false
this.selectedObjects.clear()
let component: TagListComponent
let fixture: ComponentFixture<TagListComponent>
let tagService: TagService
+ let listFilteredSpy: jest.SpyInstance
beforeEach(async () => {
TestBed.configureTestingModule({
}).compileComponents()
tagService = TestBed.inject(TagService)
- jest.spyOn(tagService, 'listFiltered').mockReturnValue(
+ listFilteredSpy = jest.spyOn(tagService, 'listFiltered').mockReturnValue(
of({
count: 3,
all: [1, 2, 3],
const filteredWithName = component.filterData(tags as any)
expect(filteredWithName.length).toBe(3)
})
+
+ it('should request only parent tags when no name filter is applied', () => {
+ expect(tagService.listFiltered).toHaveBeenCalledWith(
+ 1,
+ null,
+ undefined,
+ undefined,
+ undefined,
+ true,
+ { is_root: true }
+ )
+ })
+
+ it('should include child tags when a name filter is applied', () => {
+ listFilteredSpy.mockClear()
+ component['_nameFilter'] = 'Tag'
+ component.reloadData()
+ expect(tagService.listFiltered).toHaveBeenCalledWith(
+ 1,
+ null,
+ undefined,
+ undefined,
+ 'Tag',
+ true,
+ null
+ )
+ })
+
+ it('should include child tags when selecting all', () => {
+ const parent = {
+ id: 10,
+ name: 'Parent',
+ children: [
+ {
+ id: 11,
+ name: 'Child',
+ },
+ ],
+ }
+
+ component.data = [parent as any]
+ const selectEvent = { target: { checked: true } } as unknown as PointerEvent
+ component.toggleAll(selectEvent)
+
+ expect(component.selectedObjects.has(10)).toBe(true)
+ expect(component.selectedObjects.has(11)).toBe(true)
+
+ const deselectEvent = {
+ target: { checked: false },
+ } as unknown as PointerEvent
+ component.toggleAll(deselectEvent)
+ expect(component.selectedObjects.size).toBe(0)
+ })
})
return $localize`Do you really want to delete the tag "${object.name}"?`
}
+ override reloadData(extraParams: { [key: string]: any } = null) {
+ const params = this.nameFilter?.length
+ ? extraParams
+ : { ...extraParams, is_root: true }
+ super.reloadData(params)
+ }
+
filterData(data: Tag[]) {
return this.nameFilter?.length
? [...data]
: data.filter((tag) => !tag.parent)
}
+
+ protected override getSelectableIDs(tags: Tag[]): number[] {
+ const ids: number[] = []
+ for (const tag of tags.filter(Boolean)) {
+ if (tag.id != null) {
+ ids.push(tag.id)
+ }
+ if (Array.isArray(tag.children) && tag.children.length) {
+ ids.push(...this.getSelectableIDs(tag.children))
+ }
+ }
+ return ids
+ }
}
"name": CHAR_KWARGS,
}
+ is_root = BooleanFilter(
+ label="Is root tag",
+ field_name="tn_parent",
+ lookup_expr="isnull",
+ )
+
class DocumentTypeFilterSet(FilterSet):
class Meta:
assert resp_ok.status_code in (200, 202)
x.refresh_from_db()
assert x.parent_pk == c.id
+
+ def test_is_root_filter_returns_only_root_tags(self):
+ other_root = Tag.objects.create(name="Other parent")
+
+ response = self.client.get(
+ "/api/tags/",
+ {"is_root": "true"},
+ )
+
+ assert response.status_code == 200
+ assert response.data["count"] == 2
+
+ returned_ids = {row["id"] for row in response.data["results"]}
+ assert self.child.pk not in returned_ids
+ assert self.parent.pk in returned_ids
+ assert other_root.pk in returned_ids
+
+ parent_entry = next(
+ row for row in response.data["results"] if row["id"] == self.parent.pk
+ )
+ assert any(child["id"] == self.child.pk for child in parent_entry["children"])