static: rewrite API Fetching to make API Version upgrades easier
This commit is contained in:
parent
f83087d04d
commit
c7b6eac33d
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,3 +1,5 @@
|
||||||
|
import { DefaultClient } from "./client";
|
||||||
|
|
||||||
export class Application {
|
export class Application {
|
||||||
pk?: string;
|
pk?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
|
@ -11,8 +13,6 @@ export class Application {
|
||||||
policies?: string[];
|
policies?: string[];
|
||||||
|
|
||||||
static get(slug: string): Promise<Application> {
|
static get(slug: string): Promise<Application> {
|
||||||
return fetch(`/api/v2beta/core/applications/${slug}/`)
|
return DefaultClient.fetch<Application>("core", "applications", slug);
|
||||||
.then((r) => r.json())
|
|
||||||
.then((r) => <Application>r);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { NotFoundError, RequestError } from "./errors";
|
||||||
|
|
||||||
|
export const VERSION = "v2beta";
|
||||||
|
|
||||||
|
export class Client {
|
||||||
|
private makeUrl(...url: string[]): string {
|
||||||
|
return `/api/${VERSION}/${url.join("/")}/`;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch<T>(...url: string[]): Promise<T> {
|
||||||
|
return fetch(this.makeUrl(...url))
|
||||||
|
.then((r) => {
|
||||||
|
if (r.status > 300) {
|
||||||
|
switch (r.status) {
|
||||||
|
case 404:
|
||||||
|
throw new NotFoundError(
|
||||||
|
`URL ${this.makeUrl(...url)} not found`
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
throw new RequestError(r.statusText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
})
|
||||||
|
.then((r) => r.json())
|
||||||
|
.then((r) => <T>r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DefaultClient = new Client();
|
|
@ -1,10 +1,10 @@
|
||||||
export interface Config {
|
import { DefaultClient } from "./client";
|
||||||
branding_logo: string;
|
|
||||||
branding_title: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getConfig(): Promise<Config> {
|
export class Config {
|
||||||
return fetch("/api/v2beta/root/config/")
|
branding_logo?: string;
|
||||||
.then((r) => r.json())
|
branding_title?: string;
|
||||||
.then((r) => <Config>r);
|
|
||||||
|
static get(): Promise<Config> {
|
||||||
|
return DefaultClient.fetch<Config>("root", "config");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
export class NotFoundError extends Error {}
|
export class NotFoundError extends Error {}
|
||||||
|
export class RequestError extends Error {}
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
export function tokenByIdentifier(identifier: string): Promise<string> {
|
import { DefaultClient } from "./client";
|
||||||
return fetch(`/api/v2beta/core/tokens/${identifier}/view_key/`)
|
|
||||||
.then((r) => r.json())
|
interface TokenResponse {
|
||||||
.then((r) => r["key"]);
|
key: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function tokenByIdentifier(identifier: string): Promise<string> {
|
||||||
|
return DefaultClient.fetch<TokenResponse>(
|
||||||
|
"core",
|
||||||
|
"tokens",
|
||||||
|
identifier,
|
||||||
|
"view_key"
|
||||||
|
).then((r) => r.key);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
export interface User {
|
import { Primitive } from "lit-html/lib/parts";
|
||||||
pk: number;
|
import { DefaultClient } from "./client";
|
||||||
username: string;
|
|
||||||
name: string;
|
|
||||||
is_superuser: boolean;
|
|
||||||
email: boolean;
|
|
||||||
avatar: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function me(): Promise<User> {
|
export class User {
|
||||||
return fetch("/api/v2beta/core/users/me/")
|
pk?: number;
|
||||||
.then((r) => r.json())
|
username?: string;
|
||||||
.then((r) => <User>r);
|
name?: string;
|
||||||
|
is_superuser?: boolean;
|
||||||
|
email?: boolean;
|
||||||
|
avatar?: string;
|
||||||
|
|
||||||
|
static me(): Promise<User> {
|
||||||
|
return DefaultClient.fetch<User>("core", "users", "me");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ export class Messages extends LitElement {
|
||||||
console.debug(`passbook/messages: closed ws connection: ${e}`);
|
console.debug(`passbook/messages: closed ws connection: ${e}`);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
console.debug(
|
console.debug(
|
||||||
`passbook/messages: reconnecting ws in ${this.retryDelay}`
|
`passbook/messages: reconnecting ws in ${this.retryDelay}ms`
|
||||||
);
|
);
|
||||||
this.connect();
|
this.connect();
|
||||||
}, this.retryDelay);
|
}, this.retryDelay);
|
||||||
|
@ -67,7 +67,7 @@ export class Messages extends LitElement {
|
||||||
this.messageSocket.addEventListener("error", (e) => {
|
this.messageSocket.addEventListener("error", (e) => {
|
||||||
console.warn(`passbook/messages: error ${e}`);
|
console.warn(`passbook/messages: error ${e}`);
|
||||||
this.retryDelay = this.retryDelay * 2;
|
this.retryDelay = this.retryDelay * 2;
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch messages which were stored in the session.
|
/* Fetch messages which were stored in the session.
|
||||||
|
@ -90,9 +90,7 @@ export class Messages extends LitElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderMessage(message: Message) {
|
renderMessage(message: Message) {
|
||||||
const container = <HTMLElement>(
|
const container = <HTMLElement>this.querySelector(".pf-c-alert-group")!;
|
||||||
this.querySelector(".pf-c-alert-group")!
|
|
||||||
);
|
|
||||||
const id = ID("pb-message");
|
const id = ID("pb-message");
|
||||||
const el = document.createElement("template");
|
const el = document.createElement("template");
|
||||||
el.innerHTML = `<li id=${id} class="pf-c-alert-group__item">
|
el.innerHTML = `<li id=${id} class="pf-c-alert-group__item">
|
||||||
|
|
|
@ -13,7 +13,7 @@ import NavStyle from "@patternfly/patternfly/components/Nav/nav.css";
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import GlobalsStyle from "@patternfly/patternfly/base/patternfly-globals.css";
|
import GlobalsStyle from "@patternfly/patternfly/base/patternfly-globals.css";
|
||||||
|
|
||||||
import { me, User } from "../api/user";
|
import { User } from "../api/user";
|
||||||
|
|
||||||
export interface SidebarItem {
|
export interface SidebarItem {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -166,7 +166,7 @@ export class Sidebar extends LitElement {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
me().then((u) => (this.user = u));
|
User.me().then((u) => (this.user = u));
|
||||||
this.activePath = window.location.hash.slice(1, Infinity);
|
this.activePath = window.location.hash.slice(1, Infinity);
|
||||||
window.addEventListener("hashchange", (e) => {
|
window.addEventListener("hashchange", (e) => {
|
||||||
this.activePath = window.location.hash.slice(1, Infinity);
|
this.activePath = window.location.hash.slice(1, Infinity);
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { css, customElement, html, LitElement, property } from "lit-element";
|
||||||
import PageStyle from "@patternfly/patternfly/components/Page/page.css";
|
import PageStyle from "@patternfly/patternfly/components/Page/page.css";
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import GlobalsStyle from "@patternfly/patternfly/base/patternfly-globals.css";
|
import GlobalsStyle from "@patternfly/patternfly/base/patternfly-globals.css";
|
||||||
import { Config, getConfig } from "../api/config";
|
import { Config } from "../api/config";
|
||||||
|
|
||||||
@customElement("pb-sidebar-brand")
|
@customElement("pb-sidebar-brand")
|
||||||
export class SidebarBrand extends LitElement {
|
export class SidebarBrand extends LitElement {
|
||||||
|
@ -37,7 +37,7 @@ export class SidebarBrand extends LitElement {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
getConfig().then((c) => (this.config = c));
|
Config.get().then((c) => (this.config = c));
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
// Fetch from data-attributes
|
|
||||||
document.querySelectorAll("[data-pb-fetch-fill]").forEach((el) => {
|
|
||||||
const url = el.dataset.pbFetchFill;
|
|
||||||
const key = el.dataset.pbFetchKey;
|
|
||||||
fetch(url)
|
|
||||||
.then((r) => r.json())
|
|
||||||
.then((r) => {
|
|
||||||
el.textContent = r[key];
|
|
||||||
el.value = r[key];
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Modal
|
|
||||||
document.querySelectorAll("[data-target='modal']").forEach((m) => {
|
|
||||||
m.addEventListener("click", (e) => {
|
|
||||||
const parentContainer = e.target.closest('[data-target="modal"]');
|
|
||||||
const modalId = parentContainer.attributes["data-modal"].value;
|
|
||||||
document.querySelector(`#${modalId}`).removeAttribute("hidden");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
document.querySelectorAll(".pf-c-modal-box [data-modal-close]").forEach((b) => {
|
|
||||||
b.addEventListener("click", (e) => {
|
|
||||||
const parentContainer = e.target.closest(".pf-c-backdrop");
|
|
||||||
parentContainer.setAttribute("hidden", true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Make Checkbox label click trigger checkbox toggle
|
|
||||||
document.querySelectorAll(".pf-c-check__label").forEach((checkLabel) => {
|
|
||||||
checkLabel.addEventListener("click", (e) => {
|
|
||||||
const checkbox = e.target.parentElement.querySelector(
|
|
||||||
"input[type=checkbox]"
|
|
||||||
);
|
|
||||||
checkbox.checked = !checkbox.checked;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Hamburger Menu
|
|
||||||
document
|
|
||||||
.querySelectorAll(".pf-c-page__header-brand-toggle>button")
|
|
||||||
.forEach((toggle) => {
|
|
||||||
toggle.addEventListener("click", (e) => {
|
|
||||||
const sidebar = document.querySelector(".pf-c-page__sidebar");
|
|
||||||
if (sidebar.classList.contains("pf-m-expanded")) {
|
|
||||||
// Sidebar already expanded
|
|
||||||
sidebar.classList.remove("pf-m-expanded");
|
|
||||||
sidebar.style.zIndex = 0;
|
|
||||||
} else {
|
|
||||||
// Sidebar not expanded yet
|
|
||||||
sidebar.classList.add("pf-m-expanded");
|
|
||||||
sidebar.style.zIndex = 200;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Collapsable Menus in Sidebar
|
|
||||||
document
|
|
||||||
.querySelectorAll(".pf-m-expandable>.pf-c-nav__link")
|
|
||||||
.forEach((menu) => {
|
|
||||||
menu.addEventListener("click", (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
menu.parentElement.classList.toggle("pf-m-expanded");
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,7 +1,5 @@
|
||||||
import "construct-style-sheets-polyfill";
|
import "construct-style-sheets-polyfill";
|
||||||
|
|
||||||
import "./legacy.js";
|
|
||||||
|
|
||||||
import "./elements/ActionButton";
|
import "./elements/ActionButton";
|
||||||
import "./elements/AdminLoginsChart";
|
import "./elements/AdminLoginsChart";
|
||||||
import "./elements/CodeMirror";
|
import "./elements/CodeMirror";
|
||||||
|
|
Reference in New Issue