Skip to content

Commit 2e918b5

Browse files
ChannelAdmin.makeChannelRoot should use ElementOwnsChannelRootAspect relationship (#8797)
Co-authored-by: Paul Connelly <[email protected]>
1 parent 13562d0 commit 2e918b5

File tree

6 files changed

+76
-3
lines changed

6 files changed

+76
-3
lines changed

common/api/core-backend.api.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2592,6 +2592,13 @@ export class ElementMultiAspect extends ElementAspect {
25922592
static get className(): string;
25932593
}
25942594

2595+
// @public
2596+
export class ElementOwnsChannelRootAspect extends ElementOwnsUniqueAspect {
2597+
constructor(elementId: Id64String, relClassName?: string);
2598+
// (undocumented)
2599+
static classFullName: string;
2600+
}
2601+
25952602
// @public
25962603
export class ElementOwnsChildElements extends RelatedElement {
25972604
constructor(parentId: Id64String, relClassName?: string);

common/api/summary/core-backend.exports.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ public;class;ElementGroupsMembers
190190
public;interface;ElementGroupsMembersProps
191191
public;class;ElementMultiAspect
192192
preview;class;ElementMultiAspect
193+
public;class;ElementOwnsChannelRootAspect
193194
public;class;ElementOwnsChildElements
194195
public;class;ElementOwnsExternalSourceAspects
195196
public;class;ElementOwnsMultiAspects
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@itwin/core-backend",
5+
"comment": "ChannelRoot gets created with the correct aspect relationship class.",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@itwin/core-backend"
10+
}

core/backend/src/NavigationRelationship.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ export class FolderContainsRepositories extends ElementOwnsChildElements {
110110
export class SheetIndexFolderOwnsEntries extends ElementOwnsChildElements {
111111
public static override classFullName = "BisCore:SheetIndexFolderOwnsEntries";
112112
public constructor(parentId: Id64String, relClassName: string = SheetIndexFolderOwnsEntries.classFullName) {
113-
super(parentId, relClassName );
113+
super(parentId, relClassName);
114114
}
115115
}
116116

@@ -120,7 +120,7 @@ export class SheetIndexFolderOwnsEntries extends ElementOwnsChildElements {
120120
export class SheetIndexOwnsEntries extends ElementOwnsChildElements {
121121
public static override classFullName = "BisCore:SheetIndexOwnsEntries";
122122
public constructor(parentId: Id64String, relClassName: string = SheetIndexOwnsEntries.classFullName) {
123-
super(parentId, relClassName );
123+
super(parentId, relClassName);
124124
}
125125
}
126126

@@ -287,3 +287,15 @@ export class SheetOwnsSheetInformationAspect extends ElementOwnsUniqueAspect {
287287
super(sheetId, relClassName);
288288
}
289289
}
290+
291+
/** Relates an [[Element]] to the [[ChannelRootAspect]] that identifies it as a channel root.
292+
* @see [[ChannelControl.makeChannelRoot]] to create an instance of this relationship.
293+
* @public
294+
*/
295+
export class ElementOwnsChannelRootAspect extends ElementOwnsUniqueAspect {
296+
public static override classFullName = "BisCore:ElementOwnsChannelRootAspect";
297+
298+
public constructor(elementId: Id64String, relClassName = ElementOwnsChannelRootAspect.classFullName) {
299+
super(elementId, relClassName);
300+
}
301+
}

core/backend/src/internal/ChannelAdmin.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { ChannelControl, ChannelKey } from "../ChannelControl";
1212
import { Subject } from "../Element";
1313
import { IModelDb } from "../IModelDb";
1414
import { IModelHost } from "../IModelHost";
15+
import { ElementOwnsChannelRootAspect } from "../NavigationRelationship";
1516
import { _implementationProhibited, _nativeDb, _verifyChannel } from "./Symbols";
1617

1718
class ChannelAdmin implements ChannelControl {
@@ -94,7 +95,14 @@ class ChannelAdmin implements ChannelControl {
9495
if (this.queryChannelRoot(args.channelKey) !== undefined)
9596
ChannelControlError.throwError("root-exists", `Channel ${args.channelKey} root already exist`, channelKey);
9697

97-
const props: ChannelRootAspectProps = { classFullName: ChannelAdmin.channelClassName, element: { id: args.elementId }, owner: args.channelKey };
98+
const props: ChannelRootAspectProps = {
99+
classFullName: ChannelAdmin.channelClassName,
100+
element: {
101+
id: args.elementId,
102+
relClassName: ElementOwnsChannelRootAspect.classFullName,
103+
},
104+
owner: args.channelKey,
105+
};
98106
this._iModel.elements.insertAspect(props);
99107
}
100108

core/backend/src/test/element/ElementAspect.test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,4 +411,39 @@ describe("ElementAspect", () => {
411411
assert.equal(ExternalSourceAspect.findAllBySource(iModelDb, scopeId1, kind, "<notfound>").length, 0);
412412
});
413413

414+
it("should create ChannelRootAspect with correct relationship class", async () => {
415+
const iModelDb = SnapshotDb.createEmpty(IModelTestUtils.prepareOutputFile("ElementAspect", "ChannelRootAspectTest.bim"), { rootSubject: { name: "ChannelRootAspectTest" } });
416+
417+
const testChannelKey = "test-channel";
418+
419+
// Enable the test channel
420+
iModelDb.channels.addAllowedChannel(testChannelKey);
421+
422+
// Create a channel subject using insertChannelSubject
423+
const subjectId = iModelDb.channels.insertChannelSubject({
424+
subjectName: "Test Channel Subject",
425+
channelKey: testChannelKey,
426+
});
427+
iModelDb.saveChanges();
428+
assert.isTrue(Id64.isValidId64(subjectId), "Subject ID should be valid");
429+
430+
// Get the ChannelRootAspect
431+
const aspects = iModelDb.elements.getAspects(subjectId, "BisCore:ChannelRootAspect");
432+
assert.equal(aspects.length, 1, "Should be exactly one as it's a unique aspect");
433+
434+
const aspect = aspects[0];
435+
assert.exists(aspect);
436+
assert.equal(aspect.classFullName, "BisCore:ChannelRootAspect", "Aspect class should be ChannelRootAspect");
437+
438+
// Verify the relationship class
439+
expect(aspect.element.relClassName).to.equal("BisCore.ElementOwnsChannelRootAspect");
440+
assert.equal((aspect as any).owner, testChannelKey, "Channel owner should match the channel key");
441+
442+
// Query the db to confirm the relationship class
443+
const reader = iModelDb.createQueryReader("select ec_classname(Element.RelECClassId) as relClassName from BisCore.ChannelRootAspect");
444+
expect(await reader.step()).to.be.true;
445+
expect(reader.current.relClassName).to.equal("BisCore:ElementOwnsChannelRootAspect");
446+
447+
iModelDb.close();
448+
});
414449
});

0 commit comments

Comments
 (0)