mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-09 15:05:44 +01:00
Sorted extension point entries with supplied extensionName
This commit is contained in:
@@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
- Extension point entries with supplied extensionName are sorted ascending
|
||||
|
||||
### Fixed
|
||||
- Modification for mercurial repositories with enabled XSRF protection
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ class ConfigurationBinder {
|
||||
});
|
||||
|
||||
// bind navigation link to extension point
|
||||
binder.bind("admin.setting", ConfigNavLink, configPredicate);
|
||||
binder.bind("admin.setting", ConfigNavLink, configPredicate, labelI18nKey);
|
||||
|
||||
// route for global configuration, passes the link from the index resource to component
|
||||
const ConfigRoute = ({ url, links, ...additionalProps }: GlobalRouteProps) => {
|
||||
|
||||
@@ -13,31 +13,31 @@ describe("binder tests", () => {
|
||||
});
|
||||
|
||||
it("should return the binded extensions", () => {
|
||||
binder.bind("hitchhicker.trillian", "heartOfGold");
|
||||
binder.bind("hitchhicker.trillian", "earth");
|
||||
binder.bind("hitchhiker.trillian", "heartOfGold");
|
||||
binder.bind("hitchhiker.trillian", "earth");
|
||||
|
||||
const extensions = binder.getExtensions("hitchhicker.trillian");
|
||||
const extensions = binder.getExtensions("hitchhiker.trillian");
|
||||
expect(extensions).toEqual(["heartOfGold", "earth"]);
|
||||
});
|
||||
|
||||
it("should return the first bound extension", () => {
|
||||
binder.bind("hitchhicker.trillian", "heartOfGold");
|
||||
binder.bind("hitchhicker.trillian", "earth");
|
||||
binder.bind("hitchhiker.trillian", "heartOfGold");
|
||||
binder.bind("hitchhiker.trillian", "earth");
|
||||
|
||||
expect(binder.getExtension("hitchhicker.trillian")).toBe("heartOfGold");
|
||||
expect(binder.getExtension("hitchhiker.trillian")).toBe("heartOfGold");
|
||||
});
|
||||
|
||||
it("should return null if no extension was bound", () => {
|
||||
expect(binder.getExtension("hitchhicker.trillian")).toBe(null);
|
||||
expect(binder.getExtension("hitchhiker.trillian")).toBe(null);
|
||||
});
|
||||
|
||||
it("should return true, if an extension is bound", () => {
|
||||
binder.bind("hitchhicker.trillian", "heartOfGold");
|
||||
expect(binder.hasExtension("hitchhicker.trillian")).toBe(true);
|
||||
binder.bind("hitchhiker.trillian", "heartOfGold");
|
||||
expect(binder.hasExtension("hitchhiker.trillian")).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false, if no extension is bound", () => {
|
||||
expect(binder.hasExtension("hitchhicker.trillian")).toBe(false);
|
||||
expect(binder.hasExtension("hitchhiker.trillian")).toBe(false);
|
||||
});
|
||||
|
||||
type Props = {
|
||||
@@ -45,13 +45,34 @@ describe("binder tests", () => {
|
||||
};
|
||||
|
||||
it("should return only extensions which predicates matches", () => {
|
||||
binder.bind("hitchhicker.trillian", "heartOfGold", (props: Props) => props.category === "a");
|
||||
binder.bind("hitchhicker.trillian", "earth", (props: Props) => props.category === "b");
|
||||
binder.bind("hitchhicker.trillian", "earth2", (props: Props) => props.category === "a");
|
||||
binder.bind("hitchhiker.trillian", "heartOfGold", (props: Props) => props.category === "a");
|
||||
binder.bind("hitchhiker.trillian", "earth", (props: Props) => props.category === "b");
|
||||
binder.bind("hitchhiker.trillian", "earth2", (props: Props) => props.category === "a");
|
||||
|
||||
const extensions = binder.getExtensions("hitchhicker.trillian", {
|
||||
const extensions = binder.getExtensions("hitchhiker.trillian", {
|
||||
category: "b"
|
||||
});
|
||||
expect(extensions).toEqual(["earth"]);
|
||||
});
|
||||
|
||||
it("should return extensions in ascending order", () => {
|
||||
binder.bind("hitchhiker.trillian", "planetA", () => true, "zeroWaste");
|
||||
binder.bind("hitchhiker.trillian", "planetB", () => true, "EPSILON");
|
||||
binder.bind("hitchhiker.trillian", "planetC", () => true, "emptyBin");
|
||||
binder.bind("hitchhiker.trillian", "planetD", () => true, "absolute");
|
||||
|
||||
const extensions = binder.getExtensions("hitchhiker.trillian");
|
||||
expect(extensions).toEqual(["planetD", "planetC", "planetB", "planetA"]);
|
||||
});
|
||||
|
||||
it("should return extensions starting with entries with specified extensionName", () => {
|
||||
binder.bind("hitchhiker.trillian", "planetA", () => true);
|
||||
binder.bind("hitchhiker.trillian", "planetB", () => true, "zeroWaste");
|
||||
binder.bind("hitchhiker.trillian", "planetC", () => true);
|
||||
binder.bind("hitchhiker.trillian", "planetD", () => true, "emptyBin");
|
||||
|
||||
const extensions = binder.getExtensions("hitchhiker.trillian");
|
||||
expect(extensions[0]).toEqual("planetD");
|
||||
expect(extensions[1]).toEqual("planetB");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@ type Predicate = (props: any) => boolean;
|
||||
type ExtensionRegistration = {
|
||||
predicate: Predicate;
|
||||
extension: any;
|
||||
extensionName: string;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -25,13 +26,14 @@ export class Binder {
|
||||
* @param extension provided extension
|
||||
* @param predicate to decide if the extension gets rendered for the given props
|
||||
*/
|
||||
bind(extensionPoint: string, extension: any, predicate?: Predicate) {
|
||||
bind(extensionPoint: string, extension: any, predicate?: Predicate, extensionName?: string) {
|
||||
if (!this.extensionPoints[extensionPoint]) {
|
||||
this.extensionPoints[extensionPoint] = [];
|
||||
}
|
||||
const registration = {
|
||||
predicate: predicate ? predicate : () => true,
|
||||
extension
|
||||
extension,
|
||||
extensionName: extensionName ? extensionName : ""
|
||||
};
|
||||
this.extensionPoints[extensionPoint].push(registration);
|
||||
}
|
||||
@@ -61,6 +63,7 @@ export class Binder {
|
||||
if (props) {
|
||||
registrations = registrations.filter(reg => reg.predicate(props || {}));
|
||||
}
|
||||
registrations.sort(this.sortExtensions);
|
||||
return registrations.map(reg => reg.extension);
|
||||
}
|
||||
|
||||
@@ -70,6 +73,27 @@ export class Binder {
|
||||
hasExtension(extensionPoint: string, props?: object): boolean {
|
||||
return this.getExtensions(extensionPoint, props).length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort extensions in ascending order.
|
||||
*/
|
||||
sortExtensions = (a: ExtensionRegistration, b: ExtensionRegistration) => {
|
||||
const regA = a.extensionName ? a.extensionName.toUpperCase() : "";
|
||||
const regB = b.extensionName ? b.extensionName.toUpperCase() : "";
|
||||
|
||||
if (regA === "" && regB === "") {
|
||||
return 0;
|
||||
} else if (regA === "") {
|
||||
return 1;
|
||||
} else if (regB === "") {
|
||||
return -1;
|
||||
} else if (regA > regB) {
|
||||
return 1;
|
||||
} else if (regA < regB) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
// singleton binder
|
||||
|
||||
Reference in New Issue
Block a user