* web/config-provider: (23 commits)
web: Added a README with a description of the applications' "mental model," essentially an architectural description.
stages/email: improve error handling for incorrect template syntax (#7758)
core: bump github.com/go-openapi/strfmt from 0.21.7 to 0.21.8 (#7768)
website: bump postcss from 8.4.31 to 8.4.32 in /website (#7770)
web: bump the eslint group in /tests/wdio with 1 update (#7773)
website: bump @types/react from 18.2.39 to 18.2.41 in /website (#7769)
web: bump the eslint group in /web with 1 update (#7772)
website: fix typos in example URLs (#7774)
root: include ca-certificates in container (#7763)
root: don't show warning when app has no URLs to import (#7765)
web: revert storybook (#7764)
web: bump the eslint group in /web with 2 updates (#7730)
website: bump @types/react from 18.2.38 to 18.2.39 in /website (#7720)
web: bump the storybook group in /web with 5 updates (#7750)
website/blog: fix email syntax (#7753)
web: bump the wdio group in /tests/wdio with 3 updates (#7751)
web: bump the babel group in /web with 3 updates (#7741)
web: bump the sentry group in /web with 2 updates (#7747)
web: bump pyright from 1.1.337 to 1.1.338 in /web (#7743)
website: bump the docusaurus group in /website with 9 updates (#7746)
...
* main: (22 commits)
stages/email: improve error handling for incorrect template syntax (#7758)
core: bump github.com/go-openapi/strfmt from 0.21.7 to 0.21.8 (#7768)
website: bump postcss from 8.4.31 to 8.4.32 in /website (#7770)
web: bump the eslint group in /tests/wdio with 1 update (#7773)
website: bump @types/react from 18.2.39 to 18.2.41 in /website (#7769)
web: bump the eslint group in /web with 1 update (#7772)
website: fix typos in example URLs (#7774)
root: include ca-certificates in container (#7763)
root: don't show warning when app has no URLs to import (#7765)
web: revert storybook (#7764)
web: bump the eslint group in /web with 2 updates (#7730)
website: bump @types/react from 18.2.38 to 18.2.39 in /website (#7720)
web: bump the storybook group in /web with 5 updates (#7750)
website/blog: fix email syntax (#7753)
web: bump the wdio group in /tests/wdio with 3 updates (#7751)
web: bump the babel group in /web with 3 updates (#7741)
web: bump the sentry group in /web with 2 updates (#7747)
web: bump pyright from 1.1.337 to 1.1.338 in /web (#7743)
website: bump the docusaurus group in /website with 9 updates (#7746)
web: bump rollup from 4.6.0 to 4.6.1 in /web (#7748)
...
* Revert "web: bump the storybook group in /web with 5 updates (#7750)"
This reverts commit 8898709a9a.
* Revert "web: bump the storybook group in /web with 5 updates (#7733)"
This reverts commit f559d2531f.
`tenant`, that can be mixed into any AKElement object that requires access to it.
Like `WithCapabilitiesConfig` and `WithAuthentikConfig`, this one is named `WithTenantConfig`.
TODO:
``` javascript
rootInterface()?.uiConfig;
me();
```
`authentikConfig`, that can be mixed into any AKElement object that requires access to it.
Since access to `rootInterface()?.config?` is _universally_ used for a single (and repetitive)
boolean check, a separate accessor has been provided that converts all calls of the form:
``` javascript
rootInterface()?.config?.capabilities.includes(CapabilitiesEnum.CanImpersonate)
```
into:
``` javascript
this.can(CapabilitiesEnum.CanImpersonate)
```
It does this via a Mixin, `WithCapabilitiesConfig`, which understands that these calls only make
sense in the context of a running, fully configured authentik instance, and that their purpose is to
inform authentik components of a user’s capabilities. The latter is why I don’t feel uncomfortable
turning a function call into a method; we should make it explicit that this is a relationship
between components.
The mixin has a single single field, `[WCC.capabilitiesConfig]`, where its association with the
upper-level configuration is made. If that syntax looks peculiar to you, good! I’ve used an explict
unique symbol as the field name; it is inaccessable an innumerable in the object list. The debugger
shows it only as:
Symbol(): {
cacheTimeout: 300
cacheTimeoutFlows: 300
cacheTimeoutPolicies: 300
cacheTimeoutReputation: 300
capabilities: (5) ['can_save_media', 'can_geo_ip', 'can_impersonate', 'can_debug', 'is_enterprise']
}
Since you can’t reference it by identity, you can’t write to it. Until every browser supports actual
private fields, this is the best we can do; it does guarantee that field name collisions are
impossible, which is a win.
The mixin takes a second optional boolean; setting this to true will cause any web component using
the mixin to automatically schedule a re-render if the capabilities list changes.
The mixin is also generic; despite the "...into a Lit-Context" in the title, the internals of the
Mixin can be replaced with anything so long as the signature of `.can()` is preserved.
Because this work builds off the work I did to give the Sidebar access to the configuration without
ad-hoc retrieval or prop-drilling, it wasn’t necessary to create a new context for it. That will be
necessary for the following:
TODO:
``` javascript
rootInterface()?.uiConfig;
rootInterface()?.tenant;
me();
```
* web: break circular dependency between AKElement & Interface.
This commit changes the way the root node of the web application shell is
discovered by child components, such that the base class shared by both
no longer results in a circular dependency between the two models.
I've run this in isolation and have seen no failures of discovery; the identity
token exists as soon as the Interface is constructed and is found by every item
on the page.
* web: fix broken typescript references
This built... and then it didn't? Anyway, the current fix is to
provide type information the AkInterface for the data that consumers
require.
* web: rollback dependabot's upgrade of context
The most frustrating part of this is that I RAN THIS, dammit, with the updated
context and the current Wizard, and it finished the End-to-End tests without
complaint.
* web: fix labels on group view page
This is a wild bug, because what caused it and how it manifested are seemingly
unrelated as to be hallcinatory.
* web: break circular dependency between AKElement & Interface.
This commit changes the way the root node of the web application shell is
discovered by child components, such that the base class shared by both
no longer results in a circular dependency between the two models.
I've run this in isolation and have seen no failures of discovery; the identity
token exists as soon as the Interface is constructed and is found by every item
on the page.
* web: fix broken typescript references
This built... and then it didn't? Anyway, the current fix is to
provide type information the AkInterface for the data that consumers
require.
* A quality of life thing: `<ak-status-label good>`
There's an idiom throughout the UI:
``` HTML
<ak-label color=${item.enabled ? PFColor.Green : PFColor.Red}>
${item.enabled ? msg("Yes") : msg("No")}
</ak-label>
```
There are two problems with this.
- Repeating the conditional multiple times is error-prone
- The color scheme doesn't communicate much.
There are uses for ak-label that aren't like this, but I'm focusing on this particular use case,
which occurs about 20 times throughout the UI.
Since it's so common, let's isolate the most common case: `<ak-status-label good />` gives you the
"good" status, and `<ak-status-label/>` gives you the "bad" status, which is the default (no
arguments to the function).
There wasn't much clarity in the system for when to use orange vs red vs grey, but looking through
the use cases, it became clear that Red meant fail/inaccessible, Orange meant "Warning, but not
blocking," and Grey just means "info: this thing is off".
So let's define that with meaning: there are three types, error, warning, and info. Which
corresponds to debugging levels, but whatever, nerds grok that stuff.
So that example at the top becomes
```<ak-status-label ?good=${item.enabled}></ak-status-label>```
... and we can now more clearly understand what that conveys.
There is some heavy tension in this case: this is an easier and quicker-to-write solution to
informing the user of a binary status in an iconic way, but the developer has to remember that it
exists.
Story provided, and changes to the existing uses of the existing idiom provided.
* Added the 'compact label' story to storybook.
* web: break circular dependency between AKElement & Interface.
This commit changes the way the root node of the web application shell is
discovered by child components, such that the base class shared by both
no longer results in a circular dependency between the two models.
I've run this in isolation and have seen no failures of discovery; the identity
token exists as soon as the Interface is constructed and is found by every item
on the page.
* web: fix broken typescript references
This built... and then it didn't? Anyway, the current fix is to
provide type information the AkInterface for the data that consumers
require.
* web: rollback dependabot's upgrade of context
The most frustrating part of this is that I RAN THIS, dammit, with the updated
context and the current Wizard, and it finished the End-to-End tests without
complaint.
* Due for amendment
* Revert "Due for amendment"
This reverts commit 829ad5d3f2.
* web: refactor sidebar capabilities for categorical subsections
The project "Change Admin UI lists to have sublists per type" requires some initial changes to the
UI to facilitate this request. The AdminSidebar is the principle target of this project, and it is
embedded in the AdminInterface. To facilitate editing the AdminSidebar as an independent entity,
AdminInterface has been moved into its own folder and the AdminSidebar extracted as a standalone Web
Component. This removes, oh, about half the code from AdminInterface. A little cleanup with
`classMap` was also committed.
The rollup config was adjusted to find the new AdminInterface location.
The Sidebar uses the global `config: Config` object to check for Enterprise capabilities. Rather
than plumb all the way down through the Interface => AdminInterface -> AdminSidebar, I chose to make
provide an alternative way of reaching the `config` object, as a *context*. Other configuration
objects (Me, UiConfig, Tenant) interfaces will be contextualized as demand warrants.
Demand will warrant. Just not yet. <sup>1</sup>
The Sidebar has been refactored only slightly; the renderers are entirely the same as they were
prior to extraction. What has been changed is the source of information: when we retrieve the
current version we story *only* the information, and use type information to ensure that the version
we store is the version we care about. The same is true of `impersonation`; we care only about the
name of the person being impersonated being present, so we don't store anything else.
Fetches have been moved from `firstUpdated` to the constructor. No reason to have the sidebar
render twice if the network returns before the render is scheduled.
Because the path used to identify the user being impersonated has changed, the `str()` references in
the XLIFF files had to be adjusted. **This change is to a variable only and does not require
translation.**
---
<sup>1</sup> The code is littered with checks to `me()?`, `uiConfig?`, `config?`, etc. In the
*context* of being logged in as an administrator those should never be in doubt. I intend to make
our interfaces not have any doubt.
* Function to help generate sizing solutions across Javascript and CSS.
* web: refactor sidebar capabilities for categorical subsections
Move open/close logic into the ak-admin-sidebar itself.
This commit removes the responsibility for opening/closing the sidebar from the interface parent
code and places it inside the sidebar entirely. Since the Django invocation passes none of the
properties ak-interface-admin is capable of receiving, this seems like a safe operation.
The sidebar now assumes the responsibility for hooking up the window event listeners for open/close
and resize.
On connection to the DOM, and on resize, the sidebar checks to see if the viewport width meets the
criteria for a behavioral change (slide-overlay vs slide-push), and on slide-push automatically
opens the sidebar on the assumption that there's plenty of room. In order to support more dynamic
styling going forward, I've substituted the 1280px with 80rem, which is the same, but allows for
some better styling if someone with older eyes needs to "zoom in" on the whole thing with a larger
font size.
The hide/show code involves "reaching up" to touch the host's classList. There's a comment
indicating that this is a slightly fragile thing to do, but in a well-known way.