mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-09 23:15:43 +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
|
## Unreleased
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Extension point entries with supplied extensionName are sorted ascending
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Modification for mercurial repositories with enabled XSRF protection
|
- Modification for mercurial repositories with enabled XSRF protection
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class ConfigurationBinder {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// bind navigation link to extension point
|
// 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
|
// route for global configuration, passes the link from the index resource to component
|
||||||
const ConfigRoute = ({ url, links, ...additionalProps }: GlobalRouteProps) => {
|
const ConfigRoute = ({ url, links, ...additionalProps }: GlobalRouteProps) => {
|
||||||
|
|||||||
@@ -13,31 +13,31 @@ describe("binder tests", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should return the binded extensions", () => {
|
it("should return the binded extensions", () => {
|
||||||
binder.bind("hitchhicker.trillian", "heartOfGold");
|
binder.bind("hitchhiker.trillian", "heartOfGold");
|
||||||
binder.bind("hitchhicker.trillian", "earth");
|
binder.bind("hitchhiker.trillian", "earth");
|
||||||
|
|
||||||
const extensions = binder.getExtensions("hitchhicker.trillian");
|
const extensions = binder.getExtensions("hitchhiker.trillian");
|
||||||
expect(extensions).toEqual(["heartOfGold", "earth"]);
|
expect(extensions).toEqual(["heartOfGold", "earth"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return the first bound extension", () => {
|
it("should return the first bound extension", () => {
|
||||||
binder.bind("hitchhicker.trillian", "heartOfGold");
|
binder.bind("hitchhiker.trillian", "heartOfGold");
|
||||||
binder.bind("hitchhicker.trillian", "earth");
|
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", () => {
|
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", () => {
|
it("should return true, if an extension is bound", () => {
|
||||||
binder.bind("hitchhicker.trillian", "heartOfGold");
|
binder.bind("hitchhiker.trillian", "heartOfGold");
|
||||||
expect(binder.hasExtension("hitchhicker.trillian")).toBe(true);
|
expect(binder.hasExtension("hitchhiker.trillian")).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return false, if no extension is bound", () => {
|
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 = {
|
type Props = {
|
||||||
@@ -45,13 +45,34 @@ describe("binder tests", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
it("should return only extensions which predicates matches", () => {
|
it("should return only extensions which predicates matches", () => {
|
||||||
binder.bind("hitchhicker.trillian", "heartOfGold", (props: Props) => props.category === "a");
|
binder.bind("hitchhiker.trillian", "heartOfGold", (props: Props) => props.category === "a");
|
||||||
binder.bind("hitchhicker.trillian", "earth", (props: Props) => props.category === "b");
|
binder.bind("hitchhiker.trillian", "earth", (props: Props) => props.category === "b");
|
||||||
binder.bind("hitchhicker.trillian", "earth2", (props: Props) => props.category === "a");
|
binder.bind("hitchhiker.trillian", "earth2", (props: Props) => props.category === "a");
|
||||||
|
|
||||||
const extensions = binder.getExtensions("hitchhicker.trillian", {
|
const extensions = binder.getExtensions("hitchhiker.trillian", {
|
||||||
category: "b"
|
category: "b"
|
||||||
});
|
});
|
||||||
expect(extensions).toEqual(["earth"]);
|
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 = {
|
type ExtensionRegistration = {
|
||||||
predicate: Predicate;
|
predicate: Predicate;
|
||||||
extension: any;
|
extension: any;
|
||||||
|
extensionName: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -25,13 +26,14 @@ export class Binder {
|
|||||||
* @param extension provided extension
|
* @param extension provided extension
|
||||||
* @param predicate to decide if the extension gets rendered for the given props
|
* @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]) {
|
if (!this.extensionPoints[extensionPoint]) {
|
||||||
this.extensionPoints[extensionPoint] = [];
|
this.extensionPoints[extensionPoint] = [];
|
||||||
}
|
}
|
||||||
const registration = {
|
const registration = {
|
||||||
predicate: predicate ? predicate : () => true,
|
predicate: predicate ? predicate : () => true,
|
||||||
extension
|
extension,
|
||||||
|
extensionName: extensionName ? extensionName : ""
|
||||||
};
|
};
|
||||||
this.extensionPoints[extensionPoint].push(registration);
|
this.extensionPoints[extensionPoint].push(registration);
|
||||||
}
|
}
|
||||||
@@ -61,6 +63,7 @@ export class Binder {
|
|||||||
if (props) {
|
if (props) {
|
||||||
registrations = registrations.filter(reg => reg.predicate(props || {}));
|
registrations = registrations.filter(reg => reg.predicate(props || {}));
|
||||||
}
|
}
|
||||||
|
registrations.sort(this.sortExtensions);
|
||||||
return registrations.map(reg => reg.extension);
|
return registrations.map(reg => reg.extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,6 +73,27 @@ export class Binder {
|
|||||||
hasExtension(extensionPoint: string, props?: object): boolean {
|
hasExtension(extensionPoint: string, props?: object): boolean {
|
||||||
return this.getExtensions(extensionPoint, props).length > 0;
|
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
|
// singleton binder
|
||||||
|
|||||||
Reference in New Issue
Block a user