web: allow setting of querystring arguments with API Client, update table
This commit is contained in:
		
							
								
								
									
										4
									
								
								web/dist/main.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								web/dist/main.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								web/dist/main.js.map
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								web/dist/main.js.map
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -13,6 +13,6 @@ export class Application { | |||||||
|     policies?: string[]; |     policies?: string[]; | ||||||
|  |  | ||||||
|     static get(slug: string): Promise<Application> { |     static get(slug: string): Promise<Application> { | ||||||
|         return DefaultClient.fetch<Application>("core", "applications", slug); |         return DefaultClient.fetch<Application>(["core", "applications", slug]); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -3,17 +3,25 @@ import { NotFoundError, RequestError } from "./errors"; | |||||||
| export const VERSION = "v2beta"; | export const VERSION = "v2beta"; | ||||||
|  |  | ||||||
| export class Client { | export class Client { | ||||||
|     makeUrl(...url: string[]): string { |     makeUrl(url: string[], query?: { [key: string]: string }): string { | ||||||
|         return `/api/${VERSION}/${url.join("/")}/`; |         let builtUrl = `/api/${VERSION}/${url.join("/")}/`; | ||||||
|  |         if (query) { | ||||||
|  |             let queryString = Object.keys(query) | ||||||
|  |                 .map((k) => encodeURIComponent(k) + "=" + encodeURIComponent(query[k])) | ||||||
|  |                 .join("&"); | ||||||
|  |             builtUrl += `?${queryString}`; | ||||||
|  |         } | ||||||
|  |         return builtUrl; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fetch<T>(...url: string[]): Promise<T> { |     fetch<T>(url: string[], query?: { [key: string]: string }): Promise<T> { | ||||||
|         return fetch(this.makeUrl(...url)) |         const finalUrl = this.makeUrl(url, query); | ||||||
|  |         return fetch(finalUrl) | ||||||
|             .then((r) => { |             .then((r) => { | ||||||
|                 if (r.status > 300) { |                 if (r.status > 300) { | ||||||
|                     switch (r.status) { |                     switch (r.status) { | ||||||
|                         case 404: |                         case 404: | ||||||
|                             throw new NotFoundError(`URL ${this.makeUrl(...url)} not found`); |                             throw new NotFoundError(`URL ${finalUrl} not found`); | ||||||
|                         default: |                         default: | ||||||
|                             throw new RequestError(r.statusText); |                             throw new RequestError(r.statusText); | ||||||
|                     } |                     } | ||||||
|  | |||||||
| @ -5,6 +5,6 @@ export class Config { | |||||||
|     branding_title?: string; |     branding_title?: string; | ||||||
|  |  | ||||||
|     static get(): Promise<Config> { |     static get(): Promise<Config> { | ||||||
|         return DefaultClient.fetch<Config>("root", "config"); |         return DefaultClient.fetch<Config>(["root", "config"]); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ interface TokenResponse { | |||||||
| } | } | ||||||
|  |  | ||||||
| export function tokenByIdentifier(identifier: string): Promise<string> { | export function tokenByIdentifier(identifier: string): Promise<string> { | ||||||
|     return DefaultClient.fetch<TokenResponse>("core", "tokens", identifier, "view_key").then( |     return DefaultClient.fetch<TokenResponse>(["core", "tokens", identifier, "view_key"]).then( | ||||||
|         (r) => r.key |         (r) => r.key | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
|  | |||||||
| @ -10,6 +10,6 @@ export class User { | |||||||
|     avatar?: string; |     avatar?: string; | ||||||
|  |  | ||||||
|     static me(): Promise<User> { |     static me(): Promise<User> { | ||||||
|         return DefaultClient.fetch<User>("core", "users", "me"); |         return DefaultClient.fetch<User>(["core", "users", "me"]); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -76,10 +76,19 @@ export const SIDEBAR_ITEMS: SidebarItem[] = [ | |||||||
|                     }, |                     }, | ||||||
|                 ], |                 ], | ||||||
|             }, |             }, | ||||||
|  |             { | ||||||
|  |                 name: "Policies", | ||||||
|  |                 children: [ | ||||||
|                     { |                     { | ||||||
|                         name: "Policies", |                         name: "Policies", | ||||||
|                         path: ["/administration/policies/"], |                         path: ["/administration/policies/"], | ||||||
|                     }, |                     }, | ||||||
|  |                     { | ||||||
|  |                         name: "Bindings", | ||||||
|  |                         path: ["/administration/policies/bindings/"], | ||||||
|  |                     }, | ||||||
|  |                 ], | ||||||
|  |             }, | ||||||
|             { |             { | ||||||
|                 name: "Property Mappings", |                 name: "Property Mappings", | ||||||
|                 path: ["/administration/property-mappings/"], |                 path: ["/administration/property-mappings/"], | ||||||
|  | |||||||
| @ -1,57 +1,46 @@ | |||||||
| import { css, html, LitElement, TemplateResult } from "lit-element"; | import { html, LitElement } from "lit-element"; | ||||||
| import { until } from "lit-html/directives/until.js"; | import { until } from "lit-html/directives/until.js"; | ||||||
| import { DefaultClient, PBResponse } from "../api/client"; | import { PBResponse } from "../api/client"; | ||||||
|  | import { COMMON_STYLES } from "../common/styles"; | ||||||
|  |  | ||||||
| export abstract class Table extends LitElement { | export abstract class Table extends LitElement { | ||||||
|     abstract apiEndpoint(): string[]; |     abstract apiEndpoint(): Promise<PBResponse>; | ||||||
|     abstract columns(): Array<string>; |     abstract columns(): Array<string>; | ||||||
|     abstract row(item: any): Array<TemplateResult>; |     abstract row(item: any): Array<string>; | ||||||
|  |  | ||||||
|     private data: PBResponse = <PBResponse>{}; |     private data: PBResponse = <PBResponse>{}; | ||||||
|  |  | ||||||
|     public static get styles() { |     static get styles() { | ||||||
|         return css` |         return [COMMON_STYLES]; | ||||||
|             table { |  | ||||||
|                 width: 100%; |  | ||||||
|             } |  | ||||||
|             table, |  | ||||||
|             tr, |  | ||||||
|             td { |  | ||||||
|                 border: 1px inset white; |  | ||||||
|                 border-collapse: collapse; |  | ||||||
|             } |  | ||||||
|             td, |  | ||||||
|             th { |  | ||||||
|                 padding: 0.5rem; |  | ||||||
|             } |  | ||||||
|             td:hover { |  | ||||||
|                 border: 1px solid red; |  | ||||||
|             } |  | ||||||
|         `; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private renderRows() { |     private renderRows() { | ||||||
|         return DefaultClient.fetch<PBResponse>(...this.apiEndpoint()) |         return this.apiEndpoint() | ||||||
|             .then((r) => (this.data = r)) |             .then((r) => (this.data = r)) | ||||||
|             .then(() => { |             .then(() => { | ||||||
|                 return this.data.results.map((item) => { |                 return this.data.results.map((item) => { | ||||||
|                     return this.row(item).map((col) => { |                     const fullRow = [`<tr role="row">`].concat( | ||||||
|                         // let t = <TemplateStringsArray>[]; |                         this.row(item).map((col) => { | ||||||
|                         return col; |                             return `<td role="cell">${col}</td>`; | ||||||
|                     }); |                         }) | ||||||
|  |                     ); | ||||||
|  |                     fullRow.push(`</tr>`); | ||||||
|  |                     return html(<any>fullRow); | ||||||
|                 }); |                 }); | ||||||
|             }); |             }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     render() { |     render() { | ||||||
|         return html`<table> |         return html`<table class="pf-c-table pf-m-compact pf-m-grid-md"> | ||||||
|             <thead> |             <thead> | ||||||
|                 <tr> |                 <tr role="row"> | ||||||
|                     ${this.columns().map((col) => html`<th>${col}</th>`)} |                     ${this.columns().map( | ||||||
|  |                         (col) => html`<th role="columnheader" scope="col">${col}</th>` | ||||||
|  |                     )} | ||||||
|                 </tr> |                 </tr> | ||||||
|             </thead> |             </thead> | ||||||
|             <tbody> |             <tbody role="rowgroup"> | ||||||
|                 ${until(this.renderRows(), html`<tr><td>loading...</tr></td>`)} |                 ${until(this.renderRows(), html`<tr role="row"><td>loading...</tr></td>`)} | ||||||
|             </tbody> |             </tbody> | ||||||
|         </table>`; |         </table>`; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| import { css, customElement, html, LitElement, property, TemplateResult } from "lit-element"; | import { css, customElement, html, LitElement, property, TemplateResult } from "lit-element"; | ||||||
| import { Application } from "../../api/application"; | import { Application } from "../../api/application"; | ||||||
| import { DefaultClient } from "../../api/client"; | import { DefaultClient, PBResponse } from "../../api/client"; | ||||||
| import { COMMON_STYLES } from "../../common/styles"; | import { COMMON_STYLES } from "../../common/styles"; | ||||||
| import { Table } from "../../elements/Table"; | import { Table } from "../../elements/Table"; | ||||||
|  |  | ||||||
| @ -9,16 +9,38 @@ export class BoundPoliciesList extends Table { | |||||||
|     @property() |     @property() | ||||||
|     target?: string; |     target?: string; | ||||||
|  |  | ||||||
|     apiEndpoint(): string[] { |     apiEndpoint(): Promise<PBResponse> { | ||||||
|         return ["policies", "bindings", `?target=${this.target}`]; |         return DefaultClient.fetch<PBResponse>(["policies", "bindings"], { | ||||||
|  |             target: this.target!, | ||||||
|  |             ordering: "order", | ||||||
|  |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     columns(): string[] { |     columns(): string[] { | ||||||
|         return ["Foo"]; |         return ["Policy", "Enabled", "Order", "Timeout", ""]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     row(item: any): TemplateResult[] { |     row(item: any): string[] { | ||||||
|         return [html`${item}`]; |         return [ | ||||||
|  |             item.policy.name, | ||||||
|  |             item.enabled, | ||||||
|  |             item.order, | ||||||
|  |             item.timeout, | ||||||
|  |             ` | ||||||
|  |             <pb-modal-button href="{% url 'passbook_admin:policy-binding-update' pk=binding.pk %}"> | ||||||
|  |                 <button slot="trigger" class="pf-c-button pf-m-secondary"> | ||||||
|  |                     Edit | ||||||
|  |                 </button> | ||||||
|  |                 <div slot="modal"></div> | ||||||
|  |             </pb-modal-button> | ||||||
|  |             <pb-modal-button href="{% url 'passbook_admin:policy-binding-delete' pk=binding.pk %}"> | ||||||
|  |                 <button slot="trigger" class="pf-c-button pf-m-danger"> | ||||||
|  |                     Delete | ||||||
|  |                 </button> | ||||||
|  |                 <div slot="modal"></div> | ||||||
|  |             </pb-modal-button> | ||||||
|  |             ` | ||||||
|  |         ]; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -79,12 +101,12 @@ export class ApplicationViewPage extends LitElement { | |||||||
|                             </div> |                             </div> | ||||||
|                             <div class="pf-c-card__body"> |                             <div class="pf-c-card__body"> | ||||||
|                                 <pb-admin-logins-chart |                                 <pb-admin-logins-chart | ||||||
|                                     url="${DefaultClient.makeUrl( |                                     url="${DefaultClient.makeUrl([ | ||||||
|                                         "core", |                                         "core", | ||||||
|                                         "applications", |                                         "applications", | ||||||
|                                         this.application?.slug!, |                                         this.application?.slug!, | ||||||
|                                         "metrics" |                                         "metrics", | ||||||
|                                     )}" |                                     ])}" | ||||||
|                                 ></pb-admin-logins-chart> |                                 ></pb-admin-logins-chart> | ||||||
|                             </div> |                             </div> | ||||||
|                         </div> |                         </div> | ||||||
| @ -95,17 +117,12 @@ export class ApplicationViewPage extends LitElement { | |||||||
|                     tab-title="Policy Bindings" |                     tab-title="Policy Bindings" | ||||||
|                     class="pf-c-page__main-section pf-m-no-padding-mobile" |                     class="pf-c-page__main-section pf-m-no-padding-mobile" | ||||||
|                 > |                 > | ||||||
|                     <div class="pf-l-gallery pf-m-gutter"> |                     <div class="pf-c-card"> | ||||||
|                         <div |  | ||||||
|                             class="pf-c-card pf-c-card-aggregate pf-l-gallery__item pf-m-4-col" |  | ||||||
|                             style="grid-column-end: span 3;grid-row-end: span 2;" |  | ||||||
|                         > |  | ||||||
|                         <pb-bound-policies-list |                         <pb-bound-policies-list | ||||||
|                             .target=${this.application.pk} |                             .target=${this.application.pk} | ||||||
|                         ></pb-bound-policies-list> |                         ></pb-bound-policies-list> | ||||||
|                     </div> |                     </div> | ||||||
|                 </div> |                 </div> | ||||||
|                 </div> |  | ||||||
|             </pb-tabs>`; |             </pb-tabs>`; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Jens Langhammer
					Jens Langhammer