* unrelated: remove deprecated sentry tracing package since its in the main package
no of course this does not fix the circular import, sigh
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* fix syntax error in group view page
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* improve error handling in search-select
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* remove requiredness from flow input for invitation
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* fix dark theme for date and datetime input fields' picker button
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* update locale
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
---------
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
web: fix event propogation in search-select wrappers
Two different patches, an older one that extracted long search
blocks that were cut-and-pasted into a standalone component, and a
newer one that fixed displaying placeholder values properly,
conflicted and broke a relationship that allowed for the values to
be propagated through those standalone components correctly.
This restores the event handling and updates the listener set-ups
with more idiomatic hooks into Lit's event system.
* web: clear "blanked" placeholder when present (#15)
- Renames "SearchSelect.ts" to "ak-search-select.ts", the better to reflect that it is a web
component.
- Moves it into an independent folder named "SearchSelect" so that all existing folders that use it
don't need any renaming or manipulation.
- Refactors SearchSelect.ts in the following ways:
- Re-arranges the properties declaration so the seven properties actually used by callers are at
the top; comments and documents every property.
- Separates out the `renderItem` and `renderEmptyItem` HTML blocks into their own templates.
- Separates `renderItem` further into `renderItemWithDescription` and
`RenderItemWithoutDescription`; prior to this, there were multiple conditionals handling the
description issue
- Separates `renderItems` into `renderItemsAsGroups` and `renderItems`; this documents what each
function does and removes multiple conditionals
- Isolates the `groupedItems()` logic into a single method, moving the *how* away from the *what*.
- Replaces the manual styling of `renderMenu()` into a lit-element `styleMap()`. This makes the
actual render a lot more readable!
- Refactors the `value` logic into its own method, as a _getter_.
- Refactors the ad-hoc handlers for `focus`, `input`, and `blur` into functions on the `render()`
method itself.
- Alternatively, I could have put the handlers as methods on the ak-search-select Node itself;
Lit would automatically bind `this` correctly if referenced through the `@event` syntax.
Moving them *out* of the `render()` method would require significantly more testing, however,
as that would change the code flow enough it might have risked the original behavior. By
leaving them in the `render()` scope, this guarantees their original behavior -- whether that
behavior is correct or not.
- FIXES#15
- Having isolated as much functionality as was possible, it was easy to change the `onFocus()`
event so that when the user focuses on the `<input>` object, if it's currently populated with
the empty option and the user specified `isBlankable`, clear it.
- **Notice**: This creates a new, possibly undesirable behavior; since it's not possible to know
*why* the input object is currently empty, in the event that it is currently empty as a result
of this clearing there is no way to know when the "empty option" marker needs to be put back.
This is an incredibly complex bit of code, the sort that really shouldn't be written by application
teams. The behavior is undefined in a number of cases, and although none of those cases are fatal,
some of them are quite annoying. I recommend that we seriously consider adopting a third-party
solution.
Selects (and DataLists) are notoriously difficult to get right on the desktop; they are almost
impossible to get right on mobile. Every responsible implementation of Selects has a
"default-to-native" experience on mobile because, for the most part, the mobile native experience is
excellent -- delta wanting two-line `<option>` blocks and `<optiongroup>`s, both of which we do
want.
This component implements:
- Rendering the `<input>` element and handling its behavior
- Rendering the `<select>` element and handling its behavior
- Mediating between these two components
- Fetching the data for the `<select>` component from the back-end
- Filtering the data via a partial-match search through the `<input>` element
- Distinguishing between hard-affirm and soft-affirm "No choice" options
- Dispatching the `<select>` element via a portal, the better to control rendering.
That's a *lot* of responsibilities! And it makes Storybooking this component non-viable. I recommend
breaking this up further, but I've already spent a lot of time just doing the refactoring and
getting the new behavior as right as possible, so for now I'm just going to submit the clean-up and
come back to this later.
* web: refactor search-select and fix placeholder
* web: refactor search-select and fix placeholder; fix misleading comment
* backport changes
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* Fix display issue when using "grouped" select lists
---------
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
* make rac blueprint only run when enterprise is active
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* make rac api same as other mappings
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* automatically scale size sent by device pixel ratio
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* actually always allow creation of rac mappings
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* fix missing application in flow context
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* fix wizard showing enterprise warning when license is installed
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* cleanup
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
---------
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* This commit abstracts access to the object `rootInterface()?.config?` into a single accessor,
`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();
```
* This commit abstracts access to the object `rootInterface()?.tenant?` into a single accessor,
`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();
```
* web: Added a README with a description of the applications' "mental model," essentially an architectural description.
* web: prettier did a thing
* web: prettier had opinions about the README
* web: Jens requested that subscription be by default, and it's the right call.
* web: Jens requested that the default subscription state for contexts be , and it's the right call.
* web: prettier having opinions after merging with dependent branch
* web: prettier still having opinions.
* This commit abstracts access to the object `rootInterface()?.config?` into a single accessor,
`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: Added a README with a description of the applications' "mental model," essentially an architectural description.
* web: prettier had opinions about the README
* web: Jens requested that subscription be by default, and it's the right call.
* This commit abstracts access to the object `rootInterface()?.config?` into a single accessor,
`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: Added a README with a description of the applications' "mental model," essentially an architectural description.
* web: prettier had opinions about the README
* web: Jens requested that subscription be by default, and it's the right call.
* web: adjust RAC to point to the (now independent) Interface.
- Also, removed redundant check.