mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
update document title on action done
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Odoo Web Core Demo</title>
|
<title>Odoo</title>
|
||||||
<link rel="icon" href="data:,">
|
<link rel="icon" href="data:,">
|
||||||
|
|
||||||
<!-- Bootstrap... This sucks. -->
|
<!-- Bootstrap... This sucks. -->
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export async function loadTemplates(): Promise<string> {
|
|||||||
// Menus
|
// Menus
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
interface BaseMenuItem {
|
export interface BaseMenuItem {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
parent_id: number | false;
|
parent_id: number | false;
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ export function actionManagerMixin<T extends ReturnType<typeof rpcMixin>>(
|
|||||||
|
|
||||||
async doAction(request: ActionRequest) {
|
async doAction(request: ActionRequest) {
|
||||||
if (typeof request === "number") {
|
if (typeof request === "number") {
|
||||||
await this.loadAction(request);
|
const descr = await this.loadAction(request);
|
||||||
// this is an action ID
|
// this is an action ID
|
||||||
let name = request === 131 ? "discuss" : "crm";
|
let name = request === 131 ? "discuss" : "crm";
|
||||||
let title =
|
let title =
|
||||||
@@ -84,6 +84,7 @@ export function actionManagerMixin<T extends ReturnType<typeof rpcMixin>>(
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
document.title = descr.name + " - Odoo";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,201 +0,0 @@
|
|||||||
import { readFile } from "fs";
|
|
||||||
import { WEnv } from "../src/ts/core/component";
|
|
||||||
import { Callback } from "../src/ts/core/event_bus";
|
|
||||||
import { QWeb } from "../src/ts/core/qweb_vdom";
|
|
||||||
import { idGenerator } from "../src/ts/core/utils";
|
|
||||||
import { getMenuInfo } from "../src/ts/loaders";
|
|
||||||
import { actionRegistry } from "../src/ts/registries";
|
|
||||||
import { IRouter, Query, RouterEvent } from "../src/ts/services/router";
|
|
||||||
import { MenuInfo, Services, Store } from "../src/ts/store/store";
|
|
||||||
|
|
||||||
export function makeTestFixture() {
|
|
||||||
let fixture = document.createElement("div");
|
|
||||||
document.body.appendChild(fixture);
|
|
||||||
return fixture;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function makeTestWEnv(): WEnv {
|
|
||||||
return {
|
|
||||||
qweb: new QWeb(),
|
|
||||||
getID: idGenerator()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function makeTestStore(services: Partial<Services> = {}): Store {
|
|
||||||
const fullservices: Services = Object.assign(
|
|
||||||
{
|
|
||||||
rpc: mockFetch,
|
|
||||||
router: new MockRouter()
|
|
||||||
},
|
|
||||||
services
|
|
||||||
);
|
|
||||||
const menuInfo = makeDemoMenuInfo();
|
|
||||||
const store = new Store(fullservices, menuInfo, actionRegistry);
|
|
||||||
return store;
|
|
||||||
}
|
|
||||||
|
|
||||||
function mockFetch(route: string, params: any): Promise<any> {
|
|
||||||
return Promise.resolve(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
export class MockRouter implements IRouter {
|
|
||||||
currentQuery: Query;
|
|
||||||
|
|
||||||
constructor(query: Query = {}) {
|
|
||||||
this.currentQuery = query;
|
|
||||||
}
|
|
||||||
|
|
||||||
navigate(query: Query) {
|
|
||||||
this.currentQuery = query;
|
|
||||||
}
|
|
||||||
on(event: RouterEvent, owner: any, callback: Callback) {}
|
|
||||||
getQuery(): Query {
|
|
||||||
return this.currentQuery;
|
|
||||||
}
|
|
||||||
|
|
||||||
formatURL(path: string, query: Query): string {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function normalize(str: string): string {
|
|
||||||
return str.replace(/\s+/g, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function loadTemplates(): Promise<string> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
readFile("web/static/src/xml/templates.xml", "utf-8", (err, result) => {
|
|
||||||
resolve(result);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function makeDemoMenuInfo(): MenuInfo {
|
|
||||||
return getMenuInfo([
|
|
||||||
{
|
|
||||||
id: 96,
|
|
||||||
name: "Discuss",
|
|
||||||
parent_id: false,
|
|
||||||
action: "ir.actions.client,131",
|
|
||||||
icon: "fa fa-comment",
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
id: 97,
|
|
||||||
name: "Integrations",
|
|
||||||
parent_id: 96,
|
|
||||||
action: false,
|
|
||||||
icon: false,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
id: 188,
|
|
||||||
name: "Github Repositories",
|
|
||||||
parent_id: 97,
|
|
||||||
action: "ir.actions.act_window,233",
|
|
||||||
icon: false,
|
|
||||||
children: []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 205,
|
|
||||||
name: "Notes",
|
|
||||||
parent_id: false,
|
|
||||||
action: "ir.actions.act_window,250",
|
|
||||||
icon: "fa fa-pen",
|
|
||||||
children: []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 409,
|
|
||||||
name: "CRM",
|
|
||||||
parent_id: false,
|
|
||||||
action: "ir.actions.act_window,597",
|
|
||||||
icon: "fa fa-handshake",
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
id: 418,
|
|
||||||
name: "Sales",
|
|
||||||
parent_id: 409,
|
|
||||||
action: false,
|
|
||||||
icon: false,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
id: 423,
|
|
||||||
name: "My Pipeline",
|
|
||||||
parent_id: 418,
|
|
||||||
action: "ir.actions.act_window,597",
|
|
||||||
icon: false,
|
|
||||||
children: []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 812,
|
|
||||||
name: "My Quotations",
|
|
||||||
parent_id: 418,
|
|
||||||
action: "ir.actions.act_window,1051",
|
|
||||||
icon: false,
|
|
||||||
children: []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 419,
|
|
||||||
name: "Team Pipelines",
|
|
||||||
parent_id: 418,
|
|
||||||
action: "ir.actions.act_window,275",
|
|
||||||
icon: false,
|
|
||||||
children: []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 421,
|
|
||||||
name: "Leads",
|
|
||||||
parent_id: 409,
|
|
||||||
action: false,
|
|
||||||
icon: false,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
id: 422,
|
|
||||||
name: "Leads",
|
|
||||||
parent_id: 421,
|
|
||||||
action: "ir.actions.act_window,595",
|
|
||||||
icon: false,
|
|
||||||
children: []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 752,
|
|
||||||
name: "Scoring Rules",
|
|
||||||
parent_id: 421,
|
|
||||||
icon: false,
|
|
||||||
action: "ir.actions.act_window,1083",
|
|
||||||
children: []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function nextMicroTick(): Promise<void> {
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
export function nextTick(): Promise<void> {
|
|
||||||
return new Promise(resolve => setTimeout(resolve));
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Deferred extends Promise<any> {
|
|
||||||
resolve(val?: any): void;
|
|
||||||
reject(): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function makeDeferred(): Deferred {
|
|
||||||
let resolve, reject;
|
|
||||||
let def = new Promise((_resolve, _reject) => {
|
|
||||||
resolve = _resolve;
|
|
||||||
reject = _reject;
|
|
||||||
});
|
|
||||||
(<Deferred>def).resolve = resolve;
|
|
||||||
(<Deferred>def).reject = reject;
|
|
||||||
return <Deferred>def;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
import { readFile } from "fs";
|
||||||
|
import { WEnv } from "../../src/ts/core/component";
|
||||||
|
import { Callback } from "../../src/ts/core/event_bus";
|
||||||
|
import { QWeb } from "../../src/ts/core/qweb_vdom";
|
||||||
|
import { idGenerator } from "../../src/ts/core/utils";
|
||||||
|
import { getMenuInfo } from "../../src/ts/loaders";
|
||||||
|
import { menuInfo, actions } from "./test_data";
|
||||||
|
import { actionRegistry } from "../../src/ts/registries";
|
||||||
|
import { IRouter, Query, RouterEvent } from "../../src/ts/services/router";
|
||||||
|
import { MenuInfo, Services, Store } from "../../src/ts/store/store";
|
||||||
|
|
||||||
|
export function makeTestFixture() {
|
||||||
|
let fixture = document.createElement("div");
|
||||||
|
document.body.appendChild(fixture);
|
||||||
|
return fixture;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function makeTestWEnv(): WEnv {
|
||||||
|
return {
|
||||||
|
qweb: new QWeb(),
|
||||||
|
getID: idGenerator()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function makeTestStore(services: Partial<Services> = {}): Store {
|
||||||
|
const fullservices: Services = Object.assign(
|
||||||
|
{
|
||||||
|
rpc: mockFetch,
|
||||||
|
router: new MockRouter()
|
||||||
|
},
|
||||||
|
services
|
||||||
|
);
|
||||||
|
const menuInfo = makeDemoMenuInfo();
|
||||||
|
const store = new Store(fullservices, menuInfo, actionRegistry);
|
||||||
|
return store;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mockFetch(route: string, params: any): Promise<any> {
|
||||||
|
if (route === "web/action/load") {
|
||||||
|
const action = actions.find(a => a.id === params.action_id);
|
||||||
|
return Promise.resolve(action);
|
||||||
|
}
|
||||||
|
return Promise.resolve(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MockRouter implements IRouter {
|
||||||
|
currentQuery: Query;
|
||||||
|
|
||||||
|
constructor(query: Query = {}) {
|
||||||
|
this.currentQuery = query;
|
||||||
|
}
|
||||||
|
|
||||||
|
navigate(query: Query) {
|
||||||
|
this.currentQuery = query;
|
||||||
|
}
|
||||||
|
on(event: RouterEvent, owner: any, callback: Callback) {}
|
||||||
|
getQuery(): Query {
|
||||||
|
return this.currentQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
formatURL(path: string, query: Query): string {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalize(str: string): string {
|
||||||
|
return str.replace(/\s+/g, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadTemplates(): Promise<string> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
readFile("web/static/src/xml/templates.xml", "utf-8", (err, result) => {
|
||||||
|
resolve(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function makeDemoMenuInfo(): MenuInfo {
|
||||||
|
return getMenuInfo(menuInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function nextMicroTick(): Promise<void> {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function nextTick(): Promise<void> {
|
||||||
|
return new Promise(resolve => setTimeout(resolve));
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Deferred extends Promise<any> {
|
||||||
|
resolve(val?: any): void;
|
||||||
|
reject(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function makeDeferred(): Deferred {
|
||||||
|
let resolve, reject;
|
||||||
|
let def = new Promise((_resolve, _reject) => {
|
||||||
|
resolve = _resolve;
|
||||||
|
reject = _reject;
|
||||||
|
});
|
||||||
|
(<Deferred>def).resolve = resolve;
|
||||||
|
(<Deferred>def).reject = reject;
|
||||||
|
return <Deferred>def;
|
||||||
|
}
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
import { BaseMenuItem } from "../../src/ts/loaders";
|
||||||
|
import { ActionDescription } from "../../src/ts/store/action_manager_mixin";
|
||||||
|
|
||||||
|
export const menuInfo: BaseMenuItem[] = [
|
||||||
|
{
|
||||||
|
id: 96,
|
||||||
|
name: "Discuss",
|
||||||
|
parent_id: false,
|
||||||
|
action: "ir.actions.client,131",
|
||||||
|
icon: "fa fa-comment",
|
||||||
|
children: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 205,
|
||||||
|
name: "Notes",
|
||||||
|
parent_id: false,
|
||||||
|
action: "ir.actions.act_window,250",
|
||||||
|
icon: "fa fa-pen",
|
||||||
|
children: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 409,
|
||||||
|
name: "CRM",
|
||||||
|
parent_id: false,
|
||||||
|
action: "ir.actions.act_window,597",
|
||||||
|
icon: "fa fa-handshake",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 418,
|
||||||
|
name: "Sales",
|
||||||
|
parent_id: 409,
|
||||||
|
action: false,
|
||||||
|
icon: false,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 423,
|
||||||
|
name: "My Pipeline",
|
||||||
|
parent_id: 418,
|
||||||
|
action: "ir.actions.act_window,597",
|
||||||
|
icon: false,
|
||||||
|
children: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 812,
|
||||||
|
name: "My Quotations",
|
||||||
|
parent_id: 418,
|
||||||
|
action: "ir.actions.act_window,1051",
|
||||||
|
icon: false,
|
||||||
|
children: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 419,
|
||||||
|
name: "Team Pipelines",
|
||||||
|
parent_id: 418,
|
||||||
|
action: "ir.actions.act_window,275",
|
||||||
|
icon: false,
|
||||||
|
children: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 421,
|
||||||
|
name: "Leads",
|
||||||
|
parent_id: 409,
|
||||||
|
action: false,
|
||||||
|
icon: false,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 422,
|
||||||
|
name: "Leads",
|
||||||
|
parent_id: 421,
|
||||||
|
action: "ir.actions.act_window,595",
|
||||||
|
icon: false,
|
||||||
|
children: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 752,
|
||||||
|
name: "Scoring Rules",
|
||||||
|
parent_id: 421,
|
||||||
|
icon: false,
|
||||||
|
action: "ir.actions.act_window,1083",
|
||||||
|
children: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export const actions: ActionDescription[] = [
|
||||||
|
{
|
||||||
|
id: 131,
|
||||||
|
type: "ir.actions.client",
|
||||||
|
target: "current",
|
||||||
|
name: "Discuss",
|
||||||
|
tag: "mail.discuss"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 250,
|
||||||
|
type: "ir.actions.act_window",
|
||||||
|
name: "Notes",
|
||||||
|
target: "current",
|
||||||
|
domain: false,
|
||||||
|
context: "{}",
|
||||||
|
views: [[false, "kanban"], [false, "list"], [false, "form"]],
|
||||||
|
res_id: 0,
|
||||||
|
res_model: "note.note"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 597,
|
||||||
|
type: "ir.actions.act_window",
|
||||||
|
name: "Pipeline",
|
||||||
|
target: "current",
|
||||||
|
domain: false,
|
||||||
|
context: { default_team_id: 1 },
|
||||||
|
views: [[2103, "kanban"], [2106, "list"], [2105, "form"]],
|
||||||
|
res_id: 0,
|
||||||
|
res_model: "crm.lead"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1051,
|
||||||
|
type: "ir.actions.act_window",
|
||||||
|
name: "Quotations",
|
||||||
|
target: "current",
|
||||||
|
domain: false,
|
||||||
|
context: "{'search_default_my_quotation': 1}",
|
||||||
|
views: [
|
||||||
|
[3387, "list"],
|
||||||
|
[3385, "kanban"],
|
||||||
|
[3389, "form"],
|
||||||
|
[3382, "calendar"],
|
||||||
|
[3384, "pivot"],
|
||||||
|
[3383, "graph"]
|
||||||
|
],
|
||||||
|
res_id: 0,
|
||||||
|
res_model: "sale.order"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 275,
|
||||||
|
type: "ir.actions.act_window",
|
||||||
|
name: "Team Pipelines",
|
||||||
|
target: "current",
|
||||||
|
context: "{}",
|
||||||
|
domain: "[('use_opportunities', '=', True)]",
|
||||||
|
views: [[false, "kanban"], [false, "form"]],
|
||||||
|
res_id: 0,
|
||||||
|
res_model: "crm.team"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 595,
|
||||||
|
type: "ir.actions.act_window",
|
||||||
|
name: "Leads",
|
||||||
|
target: "current",
|
||||||
|
context:
|
||||||
|
"{ 'default_type':'lead', 'search_default_type': 'lead', 'search_default_to_process':1, }",
|
||||||
|
domain: "['|', ('type','=','lead'), ('type','=',False)]",
|
||||||
|
views: [
|
||||||
|
[2098, "list"],
|
||||||
|
[2099, "kanban"],
|
||||||
|
[2100, "calendar"],
|
||||||
|
[2108, "pivot"],
|
||||||
|
[2107, "graph"],
|
||||||
|
[false, "form"]
|
||||||
|
],
|
||||||
|
res_id: 0,
|
||||||
|
res_model: "crm.lead"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1083,
|
||||||
|
type: "ir.actions.act_window",
|
||||||
|
name: "Scores",
|
||||||
|
target: "current",
|
||||||
|
context: "{}",
|
||||||
|
domain: false,
|
||||||
|
views: [[false, "list"], [false, "kanban"], [false, "form"]],
|
||||||
|
res_id: 0,
|
||||||
|
res_model: "website.crm.score"
|
||||||
|
}
|
||||||
|
];
|
||||||
@@ -129,4 +129,19 @@ describe("state transitions", () => {
|
|||||||
menu_id: "96"
|
menu_id: "96"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("document title", async () => {
|
||||||
|
document.title = "Odoo";
|
||||||
|
const store = makeTestStore();
|
||||||
|
expect(store.state.inHome).toBe(true);
|
||||||
|
expect(document.title).toBe("Odoo");
|
||||||
|
const promise = store.activateMenuItem(96);
|
||||||
|
expect(document.title).toBe("Odoo");
|
||||||
|
await promise;
|
||||||
|
expect(document.title).toBe("Discuss - Odoo");
|
||||||
|
|
||||||
|
store.toggleHomeMenu();
|
||||||
|
|
||||||
|
expect(document.title).toBe("Discuss - Odoo");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -22,24 +22,7 @@ exports[`can render one menu item 1`] = `
|
|||||||
Discuss
|
Discuss
|
||||||
</a>
|
</a>
|
||||||
<ul class=\\"o_menu_sections\\">
|
<ul class=\\"o_menu_sections\\">
|
||||||
<li>
|
|
||||||
|
|
||||||
<a href=\\"#\\" role=\\"button\\" class=\\"dropdown-toggle o-no-caret\\" data-toggle=\\"dropdown\\">
|
|
||||||
<span>
|
|
||||||
Integrations
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
<div class=\\"dropdown-menu\\" role=\\"menu\\">
|
|
||||||
|
|
||||||
<a href=\\"\\" data-toggle=\\"collapse\\" data-target=\\"#someid\\" role=\\"menuitem\\" class=\\"dropdown-item\\">
|
|
||||||
<span>
|
|
||||||
Github Repositories
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|||||||
@@ -118,24 +118,7 @@ exports[`start with no action => clicks on client action => discuss is rendered
|
|||||||
Discuss
|
Discuss
|
||||||
</a>
|
</a>
|
||||||
<ul class=\\"o_menu_sections\\">
|
<ul class=\\"o_menu_sections\\">
|
||||||
<li>
|
|
||||||
|
|
||||||
<a href=\\"#\\" role=\\"button\\" class=\\"dropdown-toggle o-no-caret\\" data-toggle=\\"dropdown\\">
|
|
||||||
<span>
|
|
||||||
Integrations
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
<div class=\\"dropdown-menu\\" role=\\"menu\\">
|
|
||||||
|
|
||||||
<a href=\\"\\" data-toggle=\\"collapse\\" data-target=\\"#someid\\" role=\\"menuitem\\" class=\\"dropdown-item\\">
|
|
||||||
<span>
|
|
||||||
Github Repositories
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user