web: add more related links, add policy/user/group support for bindings
This commit is contained in:
		| @ -11,7 +11,7 @@ from authentik.lib.sentry import SentryIgnoredException | |||||||
| def get_attrs(obj: SerializerModel) -> Dict[str, Any]: | def get_attrs(obj: SerializerModel) -> Dict[str, Any]: | ||||||
|     """Get object's attributes via their serializer, and covert it to a normal dict""" |     """Get object's attributes via their serializer, and covert it to a normal dict""" | ||||||
|     data = dict(obj.serializer(obj).data) |     data = dict(obj.serializer(obj).data) | ||||||
|     to_remove = ("policies", "stages", "pk", "background") |     to_remove = ("policies", "stages", "pk", "background", "group", "user") | ||||||
|     for to_remove_name in to_remove: |     for to_remove_name in to_remove: | ||||||
|         if to_remove_name in data: |         if to_remove_name in data: | ||||||
|             data.pop(to_remove_name) |             data.pop(to_remove_name) | ||||||
|  | |||||||
| @ -82,6 +82,8 @@ class FlowImporter: | |||||||
|         main_query = Q(pk=attrs["pk"]) |         main_query = Q(pk=attrs["pk"]) | ||||||
|         sub_query = Q() |         sub_query = Q() | ||||||
|         for identifier, value in attrs.items(): |         for identifier, value in attrs.items(): | ||||||
|  |             if isinstance(value, dict): | ||||||
|  |                 continue | ||||||
|             if identifier == "pk": |             if identifier == "pk": | ||||||
|                 continue |                 continue | ||||||
|             sub_query &= Q(**{identifier: value}) |             sub_query &= Q(**{identifier: value}) | ||||||
|  | |||||||
| @ -99,15 +99,12 @@ class PolicyBindingSerializer(ModelSerializer): | |||||||
|         required=True, |         required=True, | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     policy_obj = PolicySerializer(read_only=True, source="policy") |  | ||||||
|  |  | ||||||
|     class Meta: |     class Meta: | ||||||
|  |  | ||||||
|         model = PolicyBinding |         model = PolicyBinding | ||||||
|         fields = [ |         fields = [ | ||||||
|             "pk", |             "pk", | ||||||
|             "policy", |             "policy", | ||||||
|             "policy_obj", |  | ||||||
|             "group", |             "group", | ||||||
|             "user", |             "user", | ||||||
|             "target", |             "target", | ||||||
| @ -115,12 +112,13 @@ class PolicyBindingSerializer(ModelSerializer): | |||||||
|             "order", |             "order", | ||||||
|             "timeout", |             "timeout", | ||||||
|         ] |         ] | ||||||
|  |         depth = 2 | ||||||
|  |  | ||||||
|  |  | ||||||
| class PolicyBindingViewSet(ModelViewSet): | class PolicyBindingViewSet(ModelViewSet): | ||||||
|     """PolicyBinding Viewset""" |     """PolicyBinding Viewset""" | ||||||
|  |  | ||||||
|     queryset = PolicyBinding.objects.all() |     queryset = PolicyBinding.objects.all().select_related("policy", "target", "group", "user") | ||||||
|     serializer_class = PolicyBindingSerializer |     serializer_class = PolicyBindingSerializer | ||||||
|     filterset_fields = ["policy", "target", "enabled", "order", "timeout"] |     filterset_fields = ["policy", "target", "enabled", "order", "timeout"] | ||||||
|     search_fields = ["policy__name"] |     search_fields = ["policy__name"] | ||||||
|  | |||||||
							
								
								
									
										332
									
								
								swagger.yaml
									
									
									
									
									
								
							
							
						
						
									
										332
									
								
								swagger.yaml
									
									
									
									
									
								
							| @ -8643,21 +8643,327 @@ definitions: | |||||||
|         format: uuid |         format: uuid | ||||||
|         readOnly: true |         readOnly: true | ||||||
|       policy: |       policy: | ||||||
|         title: Policy |         description: Policies which specify if a user is authorized to use an Application. | ||||||
|         type: string |           Can be overridden by other types to add other fields, more logic, etc. | ||||||
|         format: uuid |         type: object | ||||||
|         x-nullable: true |         properties: | ||||||
|       policy_obj: |           policy_uuid: | ||||||
|         $ref: '#/definitions/Policy' |             title: Policy uuid | ||||||
|  |             type: string | ||||||
|  |             format: uuid | ||||||
|  |             readOnly: true | ||||||
|  |           created: | ||||||
|  |             title: Created | ||||||
|  |             type: string | ||||||
|  |             format: date-time | ||||||
|  |             readOnly: true | ||||||
|  |           last_updated: | ||||||
|  |             title: Last updated | ||||||
|  |             type: string | ||||||
|  |             format: date-time | ||||||
|  |             readOnly: true | ||||||
|  |           name: | ||||||
|  |             title: Name | ||||||
|  |             type: string | ||||||
|  |             x-nullable: true | ||||||
|  |           execution_logging: | ||||||
|  |             title: Execution logging | ||||||
|  |             description: When this option is enabled, all executions of this policy | ||||||
|  |               will be logged. By default, only execution errors are logged. | ||||||
|  |             type: boolean | ||||||
|  |         readOnly: true | ||||||
|       group: |       group: | ||||||
|         title: Group |         description: Custom Group model which supports a basic hierarchy | ||||||
|         type: string |         required: | ||||||
|         format: uuid |           - name | ||||||
|         x-nullable: true |         type: object | ||||||
|  |         properties: | ||||||
|  |           group_uuid: | ||||||
|  |             title: Group uuid | ||||||
|  |             type: string | ||||||
|  |             format: uuid | ||||||
|  |             readOnly: true | ||||||
|  |           name: | ||||||
|  |             title: Name | ||||||
|  |             type: string | ||||||
|  |             maxLength: 80 | ||||||
|  |             minLength: 1 | ||||||
|  |           is_superuser: | ||||||
|  |             title: Is superuser | ||||||
|  |             description: Users added to this group will be superusers. | ||||||
|  |             type: boolean | ||||||
|  |           attributes: | ||||||
|  |             title: Attributes | ||||||
|  |             type: object | ||||||
|  |           parent: | ||||||
|  |             description: Custom Group model which supports a basic hierarchy | ||||||
|  |             required: | ||||||
|  |               - name | ||||||
|  |               - parent | ||||||
|  |             type: object | ||||||
|  |             properties: | ||||||
|  |               group_uuid: | ||||||
|  |                 title: Group uuid | ||||||
|  |                 type: string | ||||||
|  |                 format: uuid | ||||||
|  |                 readOnly: true | ||||||
|  |               name: | ||||||
|  |                 title: Name | ||||||
|  |                 type: string | ||||||
|  |                 maxLength: 80 | ||||||
|  |                 minLength: 1 | ||||||
|  |               is_superuser: | ||||||
|  |                 title: Is superuser | ||||||
|  |                 description: Users added to this group will be superusers. | ||||||
|  |                 type: boolean | ||||||
|  |               attributes: | ||||||
|  |                 title: Attributes | ||||||
|  |                 type: object | ||||||
|  |               parent: | ||||||
|  |                 title: Parent | ||||||
|  |                 type: string | ||||||
|  |                 format: uuid | ||||||
|  |             readOnly: true | ||||||
|  |         readOnly: true | ||||||
|       user: |       user: | ||||||
|         title: User |         description: Custom User model to allow easier adding o f user-based settings | ||||||
|         type: integer |         required: | ||||||
|         x-nullable: true |           - password | ||||||
|  |           - username | ||||||
|  |           - name | ||||||
|  |         type: object | ||||||
|  |         properties: | ||||||
|  |           id: | ||||||
|  |             title: ID | ||||||
|  |             type: integer | ||||||
|  |             readOnly: true | ||||||
|  |           password: | ||||||
|  |             title: Password | ||||||
|  |             type: string | ||||||
|  |             maxLength: 128 | ||||||
|  |             minLength: 1 | ||||||
|  |           last_login: | ||||||
|  |             title: Last login | ||||||
|  |             type: string | ||||||
|  |             format: date-time | ||||||
|  |             x-nullable: true | ||||||
|  |           username: | ||||||
|  |             title: Username | ||||||
|  |             description: Required. 150 characters or fewer. Letters, digits and @/./+/-/_ | ||||||
|  |               only. | ||||||
|  |             type: string | ||||||
|  |             pattern: ^[\w.@+-]+$ | ||||||
|  |             maxLength: 150 | ||||||
|  |             minLength: 1 | ||||||
|  |           first_name: | ||||||
|  |             title: First name | ||||||
|  |             type: string | ||||||
|  |             maxLength: 150 | ||||||
|  |           last_name: | ||||||
|  |             title: Last name | ||||||
|  |             type: string | ||||||
|  |             maxLength: 150 | ||||||
|  |           email: | ||||||
|  |             title: Email address | ||||||
|  |             type: string | ||||||
|  |             format: email | ||||||
|  |             maxLength: 254 | ||||||
|  |           is_active: | ||||||
|  |             title: Active | ||||||
|  |             description: Designates whether this user should be treated as active. | ||||||
|  |               Unselect this instead of deleting accounts. | ||||||
|  |             type: boolean | ||||||
|  |           date_joined: | ||||||
|  |             title: Date joined | ||||||
|  |             type: string | ||||||
|  |             format: date-time | ||||||
|  |           uuid: | ||||||
|  |             title: Uuid | ||||||
|  |             type: string | ||||||
|  |             format: uuid | ||||||
|  |             readOnly: true | ||||||
|  |           name: | ||||||
|  |             title: Name | ||||||
|  |             description: User's display name. | ||||||
|  |             type: string | ||||||
|  |             minLength: 1 | ||||||
|  |           password_change_date: | ||||||
|  |             title: Password change date | ||||||
|  |             type: string | ||||||
|  |             format: date-time | ||||||
|  |             readOnly: true | ||||||
|  |           attributes: | ||||||
|  |             title: Attributes | ||||||
|  |             type: object | ||||||
|  |           groups: | ||||||
|  |             description: '' | ||||||
|  |             type: array | ||||||
|  |             items: | ||||||
|  |               description: Groups are a generic way of categorizing users to apply | ||||||
|  |                 permissions, or some other label, to those users. A user can belong | ||||||
|  |                 to any number of groups. A user in a group automatically has all the | ||||||
|  |                 permissions granted to that group. For example, if the group 'Site | ||||||
|  |                 editors' has the permission can_edit_home_page, any user in that group | ||||||
|  |                 will have that permission. Beyond permissions, groups are a convenient | ||||||
|  |                 way to categorize users to apply some label, or extended functionality, | ||||||
|  |                 to them. For example, you could create a group 'Special users', and | ||||||
|  |                 you could write code that would do special things to those users -- | ||||||
|  |                 such as giving them access to a members-only portion of your site, | ||||||
|  |                 or sending them members-only email messages. | ||||||
|  |               required: | ||||||
|  |                 - name | ||||||
|  |               type: object | ||||||
|  |               properties: | ||||||
|  |                 id: | ||||||
|  |                   title: ID | ||||||
|  |                   type: integer | ||||||
|  |                   readOnly: true | ||||||
|  |                 name: | ||||||
|  |                   title: Name | ||||||
|  |                   type: string | ||||||
|  |                   maxLength: 150 | ||||||
|  |                   minLength: 1 | ||||||
|  |                 permissions: | ||||||
|  |                   type: array | ||||||
|  |                   items: | ||||||
|  |                     type: integer | ||||||
|  |                   uniqueItems: true | ||||||
|  |             readOnly: true | ||||||
|  |           user_permissions: | ||||||
|  |             description: '' | ||||||
|  |             type: array | ||||||
|  |             items: | ||||||
|  |               description: "The permissions system provides a way to assign permissions\ | ||||||
|  |                 \ to specific users and groups of users. The permission system is\ | ||||||
|  |                 \ used by the Django admin site, but may also be useful in your own\ | ||||||
|  |                 \ code. The Django admin site uses permissions as follows: - The \"\ | ||||||
|  |                 add\" permission limits the user's ability to view the \"add\" form\ | ||||||
|  |                 \ and add an object. - The \"change\" permission limits a user's ability\ | ||||||
|  |                 \ to view the change list, view the \"change\" form and change an\ | ||||||
|  |                 \ object. - The \"delete\" permission limits the ability to delete\ | ||||||
|  |                 \ an object. - The \"view\" permission limits the ability to view\ | ||||||
|  |                 \ an object. Permissions are set globally per type of object, not\ | ||||||
|  |                 \ per specific object instance. It is possible to say \"Mary may change\ | ||||||
|  |                 \ news stories,\" but it's not currently possible to say \"Mary may\ | ||||||
|  |                 \ change news stories, but only the ones she created herself\" or\ | ||||||
|  |                 \ \"Mary may only change news stories that have a certain status or\ | ||||||
|  |                 \ publication date.\" The permissions listed above are automatically\ | ||||||
|  |                 \ created for each model." | ||||||
|  |               required: | ||||||
|  |                 - name | ||||||
|  |                 - codename | ||||||
|  |                 - content_type | ||||||
|  |               type: object | ||||||
|  |               properties: | ||||||
|  |                 id: | ||||||
|  |                   title: ID | ||||||
|  |                   type: integer | ||||||
|  |                   readOnly: true | ||||||
|  |                 name: | ||||||
|  |                   title: Name | ||||||
|  |                   type: string | ||||||
|  |                   maxLength: 255 | ||||||
|  |                   minLength: 1 | ||||||
|  |                 codename: | ||||||
|  |                   title: Codename | ||||||
|  |                   type: string | ||||||
|  |                   maxLength: 100 | ||||||
|  |                   minLength: 1 | ||||||
|  |                 content_type: | ||||||
|  |                   title: Content type | ||||||
|  |                   type: integer | ||||||
|  |             readOnly: true | ||||||
|  |           sources: | ||||||
|  |             description: '' | ||||||
|  |             type: array | ||||||
|  |             items: | ||||||
|  |               description: Base Authentication source, i.e. an OAuth Provider, SAML | ||||||
|  |                 Remote or LDAP Server | ||||||
|  |               required: | ||||||
|  |                 - name | ||||||
|  |                 - slug | ||||||
|  |               type: object | ||||||
|  |               properties: | ||||||
|  |                 pbm_uuid: | ||||||
|  |                   title: Pbm uuid | ||||||
|  |                   type: string | ||||||
|  |                   format: uuid | ||||||
|  |                   readOnly: true | ||||||
|  |                 name: | ||||||
|  |                   title: Name | ||||||
|  |                   description: Source's display Name. | ||||||
|  |                   type: string | ||||||
|  |                   minLength: 1 | ||||||
|  |                 slug: | ||||||
|  |                   title: Slug | ||||||
|  |                   description: Internal source name, used in URLs. | ||||||
|  |                   type: string | ||||||
|  |                   format: slug | ||||||
|  |                   pattern: ^[-a-zA-Z0-9_]+$ | ||||||
|  |                   maxLength: 50 | ||||||
|  |                   minLength: 1 | ||||||
|  |                 enabled: | ||||||
|  |                   title: Enabled | ||||||
|  |                   type: boolean | ||||||
|  |                 authentication_flow: | ||||||
|  |                   title: Authentication flow | ||||||
|  |                   description: Flow to use when authenticating existing users. | ||||||
|  |                   type: string | ||||||
|  |                   format: uuid | ||||||
|  |                   x-nullable: true | ||||||
|  |                 enrollment_flow: | ||||||
|  |                   title: Enrollment flow | ||||||
|  |                   description: Flow to use when enrolling new users. | ||||||
|  |                   type: string | ||||||
|  |                   format: uuid | ||||||
|  |                   x-nullable: true | ||||||
|  |                 policies: | ||||||
|  |                   type: array | ||||||
|  |                   items: | ||||||
|  |                     type: string | ||||||
|  |                     format: uuid | ||||||
|  |                   readOnly: true | ||||||
|  |                   uniqueItems: true | ||||||
|  |                 property_mappings: | ||||||
|  |                   type: array | ||||||
|  |                   items: | ||||||
|  |                     type: string | ||||||
|  |                     format: uuid | ||||||
|  |                   uniqueItems: true | ||||||
|  |             readOnly: true | ||||||
|  |           ak_groups: | ||||||
|  |             description: '' | ||||||
|  |             type: array | ||||||
|  |             items: | ||||||
|  |               description: Custom Group model which supports a basic hierarchy | ||||||
|  |               required: | ||||||
|  |                 - name | ||||||
|  |                 - parent | ||||||
|  |               type: object | ||||||
|  |               properties: | ||||||
|  |                 group_uuid: | ||||||
|  |                   title: Group uuid | ||||||
|  |                   type: string | ||||||
|  |                   format: uuid | ||||||
|  |                   readOnly: true | ||||||
|  |                 name: | ||||||
|  |                   title: Name | ||||||
|  |                   type: string | ||||||
|  |                   maxLength: 80 | ||||||
|  |                   minLength: 1 | ||||||
|  |                 is_superuser: | ||||||
|  |                   title: Is superuser | ||||||
|  |                   description: Users added to this group will be superusers. | ||||||
|  |                   type: boolean | ||||||
|  |                 attributes: | ||||||
|  |                   title: Attributes | ||||||
|  |                   type: object | ||||||
|  |                 parent: | ||||||
|  |                   title: Parent | ||||||
|  |                   type: string | ||||||
|  |                   format: uuid | ||||||
|  |             readOnly: true | ||||||
|  |         readOnly: true | ||||||
|       target: |       target: | ||||||
|         title: Target |         title: Target | ||||||
|         type: string |         type: string | ||||||
|  | |||||||
| @ -1,10 +1,14 @@ | |||||||
| import { DefaultClient, AKResponse, QueryArguments } from "./Client"; | import { DefaultClient, AKResponse, QueryArguments } from "./Client"; | ||||||
|  | import { Group } from "./Groups"; | ||||||
| import { Policy } from "./Policies"; | import { Policy } from "./Policies"; | ||||||
|  | import { User } from "./Users"; | ||||||
|  |  | ||||||
| export class PolicyBinding { | export class PolicyBinding { | ||||||
|     pk: string; |     pk: string; | ||||||
|     policy: string; |     policy: string; | ||||||
|     policy_obj: Policy; |     policy_obj?: Policy; | ||||||
|  |     group?: Group; | ||||||
|  |     user?: User; | ||||||
|     target: string; |     target: string; | ||||||
|     enabled: boolean; |     enabled: boolean; | ||||||
|     order: number; |     order: number; | ||||||
|  | |||||||
| @ -24,7 +24,7 @@ export class BoundPoliciesList extends Table<PolicyBinding> { | |||||||
|  |  | ||||||
|     columns(): TableColumn[] { |     columns(): TableColumn[] { | ||||||
|         return [ |         return [ | ||||||
|             new TableColumn("Policy"), |             new TableColumn("Policy / User / Group"), | ||||||
|             new TableColumn("Enabled", "enabled"), |             new TableColumn("Enabled", "enabled"), | ||||||
|             new TableColumn("Order", "order"), |             new TableColumn("Order", "order"), | ||||||
|             new TableColumn("Timeout", "timeout"), |             new TableColumn("Timeout", "timeout"), | ||||||
| @ -32,9 +32,21 @@ export class BoundPoliciesList extends Table<PolicyBinding> { | |||||||
|         ]; |         ]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     getPolicyUserGroupRow(item: PolicyBinding): string { | ||||||
|  |         if (item.policy_obj) { | ||||||
|  |             return gettext(`Policy ${item.policy_obj.name}`); | ||||||
|  |         } else if (item.group) { | ||||||
|  |             return gettext(`Group ${item.group.name}`); | ||||||
|  |         } else if (item.user) { | ||||||
|  |             return gettext(`User ${item.user.name}`); | ||||||
|  |         } else { | ||||||
|  |             return gettext(``); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     row(item: PolicyBinding): TemplateResult[] { |     row(item: PolicyBinding): TemplateResult[] { | ||||||
|         return [ |         return [ | ||||||
|             html`${item.policy_obj.name}`, |             html`${this.getPolicyUserGroupRow(item)}`, | ||||||
|             html`${item.enabled ? "Yes" : "No"}`, |             html`${item.enabled ? "Yes" : "No"}`, | ||||||
|             html`${item.order}`, |             html`${item.order}`, | ||||||
|             html`${item.timeout}`, |             html`${item.timeout}`, | ||||||
|  | |||||||
							
								
								
									
										24
									
								
								web/src/elements/utils/LoadingState.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								web/src/elements/utils/LoadingState.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | |||||||
|  | import { commands } from "codemirror"; | ||||||
|  | import { CSSResult, customElement, html, LitElement, TemplateResult } from "lit-element"; | ||||||
|  | import { COMMON_STYLES } from "../../common/styles"; | ||||||
|  | import { SpinnerSize } from "../Spinner"; | ||||||
|  |  | ||||||
|  | @customElement("ak-loading-state") | ||||||
|  | export class LoadingState extends LitElement { | ||||||
|  |  | ||||||
|  |     static get styles(): CSSResult[] { | ||||||
|  |         return COMMON_STYLES; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     render(): TemplateResult { | ||||||
|  |         return html`<div class="pf-c-empty-state pf-m-full-height"> | ||||||
|  |             <div class="pf-c-empty-state__content"> | ||||||
|  |                 <div class="pf-l-bullseye"> | ||||||
|  |                     <div class="pf-l-bullseye__item"> | ||||||
|  |                         <ak-spinner size="${SpinnerSize.XLarge}"></ak-spinner> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |         </div>`; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -9,6 +9,7 @@ import "../../elements/AdminLoginsChart"; | |||||||
| import "../../elements/buttons/ModalButton"; | import "../../elements/buttons/ModalButton"; | ||||||
| import "../../elements/buttons/SpinnerButton"; | import "../../elements/buttons/SpinnerButton"; | ||||||
| import "../../elements/policies/BoundPoliciesList"; | import "../../elements/policies/BoundPoliciesList"; | ||||||
|  | import "../../elements/utils/LoadingState"; | ||||||
|  |  | ||||||
| @customElement("ak-application-view") | @customElement("ak-application-view") | ||||||
| export class ApplicationViewPage extends LitElement { | export class ApplicationViewPage extends LitElement { | ||||||
| @ -37,7 +38,7 @@ export class ApplicationViewPage extends LitElement { | |||||||
|  |  | ||||||
|     render(): TemplateResult { |     render(): TemplateResult { | ||||||
|         if (!this.application) { |         if (!this.application) { | ||||||
|             return html``; |             return html`<ak-loading-state></ak-loading-state>`;; | ||||||
|         } |         } | ||||||
|         return html`<section class="pf-c-page__main-section pf-m-light"> |         return html`<section class="pf-c-page__main-section pf-m-light"> | ||||||
|                 <div class="pf-c-content"> |                 <div class="pf-c-content"> | ||||||
| @ -49,7 +50,7 @@ export class ApplicationViewPage extends LitElement { | |||||||
|                 </div> |                 </div> | ||||||
|             </section> |             </section> | ||||||
|             <ak-tabs> |             <ak-tabs> | ||||||
|                 <section slot="page-1" data-tab-title="${gettext("Users")}" class="pf-c-page__main-section pf-m-no-padding-mobile"> |                 <section slot="page-1" data-tab-title="${gettext("Overview")}" class="pf-c-page__main-section pf-m-no-padding-mobile"> | ||||||
|                     <div class="pf-l-gallery pf-m-gutter"> |                     <div class="pf-l-gallery pf-m-gutter"> | ||||||
|                         <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;"> |                         <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;"> | ||||||
|                             <div class="pf-c-card__header"> |                             <div class="pf-c-card__header"> | ||||||
| @ -64,6 +65,31 @@ export class ApplicationViewPage extends LitElement { | |||||||
|                                     </ak-admin-logins-chart>`: ""} |                                     </ak-admin-logins-chart>`: ""} | ||||||
|                             </div> |                             </div> | ||||||
|                         </div> |                         </div> | ||||||
|  |                         <div class="pf-c-card pf-c-card-aggregate pf-l-gallery__item pf-m-2-col"> | ||||||
|  |                             <div class="pf-c-card__header"> | ||||||
|  |                                 <div class="pf-c-card__header-main"> | ||||||
|  |                                     <i class="fas fa-external-link-alt"></i> ${gettext("Related")} | ||||||
|  |                                 </div> | ||||||
|  |                             </div> | ||||||
|  |                             <div class="pf-c-card__body"> | ||||||
|  |                                 <dl class="pf-c-description-list pf-m-horizontal"> | ||||||
|  |                                     ${this.application.provider ? | ||||||
|  |                                     html`<div class="pf-c-description-list__group"> | ||||||
|  |                                             <dt class="pf-c-description-list__term"> | ||||||
|  |                                                 <span class="pf-c-description-list__text">${gettext("Provider")}</span> | ||||||
|  |                                             </dt> | ||||||
|  |                                             <dd class="pf-c-description-list__description"> | ||||||
|  |                                                 <div class="pf-c-description-list__text"> | ||||||
|  |                                                     <a href="#/providers/${this.application.provider.pk}"> | ||||||
|  |                                                         ${this.application.provider.name} | ||||||
|  |                                                     </a> | ||||||
|  |                                                 </div> | ||||||
|  |                                             </dd> | ||||||
|  |                                         </div>`: | ||||||
|  |                                     html``} | ||||||
|  |                                 </dl> | ||||||
|  |                             </div> | ||||||
|  |                         </div> | ||||||
|                     </div> |                     </div> | ||||||
|                 </section> |                 </section> | ||||||
|                 <div slot="page-2" data-tab-title="${gettext("Policy Bindings")}" class="pf-c-page__main-section pf-m-no-padding-mobile"> |                 <div slot="page-2" data-tab-title="${gettext("Policy Bindings")}" class="pf-c-page__main-section pf-m-no-padding-mobile"> | ||||||
|  | |||||||
| @ -13,11 +13,6 @@ import "./FlowDiagram"; | |||||||
|  |  | ||||||
| @customElement("ak-flow-view") | @customElement("ak-flow-view") | ||||||
| export class FlowViewPage extends LitElement { | export class FlowViewPage extends LitElement { | ||||||
|     @property() |  | ||||||
|     set args(value: { [key: string]: string }) { |  | ||||||
|         this.flowSlug = value.slug; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @property() |     @property() | ||||||
|     set flowSlug(value: string) { |     set flowSlug(value: string) { | ||||||
|         Flow.get(value).then((flow) => (this.flow = flow)); |         Flow.get(value).then((flow) => (this.flow = flow)); | ||||||
|  | |||||||
| @ -4,7 +4,6 @@ import { COMMON_STYLES } from "../../common/styles"; | |||||||
|  |  | ||||||
| import "../../elements/buttons/ModalButton"; | import "../../elements/buttons/ModalButton"; | ||||||
| import "../../elements/buttons/SpinnerButton"; | import "../../elements/buttons/SpinnerButton"; | ||||||
| import { SpinnerSize } from "../../elements/Spinner"; |  | ||||||
|  |  | ||||||
| import "./SAMLProviderViewPage"; | import "./SAMLProviderViewPage"; | ||||||
| import "./OAuth2ProviderViewPage"; | import "./OAuth2ProviderViewPage"; | ||||||
| @ -27,15 +26,7 @@ export class ProviderViewPage extends LitElement { | |||||||
|  |  | ||||||
|     render(): TemplateResult { |     render(): TemplateResult { | ||||||
|         if (!this.provider) { |         if (!this.provider) { | ||||||
|             return html`<div class="pf-c-empty-state pf-m-full-height"> |             return html`<ak-loading-state></ak-loading-state>`;; | ||||||
|                 <div class="pf-c-empty-state__content"> |  | ||||||
|                     <div class="pf-l-bullseye"> |  | ||||||
|                         <div class="pf-l-bullseye__item"> |  | ||||||
|                             <ak-spinner size="${SpinnerSize.XLarge}"></ak-spinner> |  | ||||||
|                         </div> |  | ||||||
|                     </div> |  | ||||||
|                 </div> |  | ||||||
|             </div>`; |  | ||||||
|         } |         } | ||||||
|         switch (this.provider?.object_type) { |         switch (this.provider?.object_type) { | ||||||
|             case "saml": |             case "saml": | ||||||
|  | |||||||
| @ -36,7 +36,7 @@ export const ROUTES: Route[] = [ | |||||||
|         return html`<ak-source-view .args=${args}></ak-source-view>`; |         return html`<ak-source-view .args=${args}></ak-source-view>`; | ||||||
|     }), |     }), | ||||||
|     new Route(new RegExp(`^/flows/(?<slug>${SLUG_REGEX})$`)).then((args) => { |     new Route(new RegExp(`^/flows/(?<slug>${SLUG_REGEX})$`)).then((args) => { | ||||||
|         return html`<ak-flow-view .args=${args}></ak-flow-view>`; |         return html`<ak-flow-view .flowSlug=${args.slug}></ak-flow-view>`; | ||||||
|     }), |     }), | ||||||
|     new Route(new RegExp("^/events/log$"), html`<ak-event-list></ak-event-list>`), |     new Route(new RegExp("^/events/log$"), html`<ak-event-list></ak-event-list>`), | ||||||
|     new Route(new RegExp(`^/events/log/(?<id>${UUID_REGEX})$`)).then((args) => { |     new Route(new RegExp(`^/events/log/(?<id>${UUID_REGEX})$`)).then((args) => { | ||||||
|  | |||||||
| @ -47,15 +47,7 @@ export function htmlFromString(...strings: string[]): TemplateResult { | |||||||
|  |  | ||||||
| export function loading<T>(v: T, actual: TemplateResult): TemplateResult { | export function loading<T>(v: T, actual: TemplateResult): TemplateResult { | ||||||
|     if (!v) { |     if (!v) { | ||||||
|         return html`<div class="pf-c-empty-state pf-m-full-height"> |         return html`<ak-loading-state></ak-loading-state>`; | ||||||
|             <div class="pf-c-empty-state__content"> |  | ||||||
|                 <div class="pf-l-bullseye"> |  | ||||||
|                     <div class="pf-l-bullseye__item"> |  | ||||||
|                         <ak-spinner size="${SpinnerSize.XLarge}"></ak-spinner> |  | ||||||
|                     </div> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|         </div>`; |  | ||||||
|     } |     } | ||||||
|     return actual; |     return actual; | ||||||
| } | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Jens Langhammer
					Jens Langhammer