* main:
web: Replace calls to `rootInterface()?.tenant?` with a contextual `this.tenant` object (#7778)
web: abstract `rootInterface()?.config?.capabilities.includes()` into `.can()` (#7737)
* 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.
* refs/remotes/origin/web/monorepo-stage-1:
fix for broken lint pass.
web: strengthened weak regex in import map.
web: move the content of the application to a sub-folder and build it via lage
Another stash to check something else...
Stashing this to go back to harmonizing package.json
web: first stab at monorepo.
web: moved all of the authentik building materials into a package.
This commit adds "Polish" and "Korean" to the list of languages recognized by the
web-UI, and updates the XLIFF files to include a few new strings from the RAC
project.
**This commit**
- Moves the content of the authentik web-ui to a subfolder, `packages/authentik`
- Mirrors all of the commands from package.json in the root package, and
mirrors them *again* in Lage, so that lage will run them all as-is.
- Changes paths for things like sonarJS, Codespell, and such to find the
correct sources of their content.
- Update `glob` and `pseudolocale` versions; they were throwing exceptions.
- Update Storybook-Vite's CSS import map function to be a little more readable.
**This commit**
- Moves the content of the authentik web-ui to a subfolder, `packages/authentik`
- Mirrors all of the commands from package.json in the root package, and
mirrors them *again* in Lage, so that lage will run them all as-is.
- Changes paths for things like sonarJS, Codespell, and such to find the
correct sources of their content.
- Update `glob` and `pseudolocale` versions; they were throwing exceptions.
- Update Storybook-Vite's CSS import map function to be a little more readable.
* Translate web/xliff/en.xlf in ko
100% translated source file: 'web/xliff/en.xlf'
on 'ko'.
* Translate web/xliff/en.xlf in ko
100% translated source file: 'web/xliff/en.xlf'
on 'ko'.
* Translate web/xliff/en.xlf in ko
100% translated source file: 'web/xliff/en.xlf'
on 'ko'.
* Translate web/xliff/en.xlf in ko
100% translated source file: 'web/xliff/en.xlf'
on 'ko'.
* Translate web/xliff/en.xlf in ko
100% translated source file: 'web/xliff/en.xlf'
on 'ko'.
* Translate web/xliff/en.xlf in ko
100% translated source file: 'web/xliff/en.xlf'
on 'ko'.
* Translate web/xliff/en.xlf in ko
100% translated source file: 'web/xliff/en.xlf'
on 'ko'.
* Translate web/xliff/en.xlf in ko
100% translated source file: 'web/xliff/en.xlf'
on 'ko'.
* Translate web/xliff/en.xlf in ko
100% translated source file: 'web/xliff/en.xlf'
on 'ko'.
* Translate web/xliff/en.xlf in ko
100% translated source file: 'web/xliff/en.xlf'
on 'ko'.
* Translate web/xliff/en.xlf in ko
100% translated source file: 'web/xliff/en.xlf'
on 'ko'.
* Translate web/xliff/en.xlf in ko
100% translated source file: 'web/xliff/en.xlf'
on 'ko'.
* Translate web/xliff/en.xlf in ko
100% translated source file: 'web/xliff/en.xlf'
on 'ko'.
* Translate web/xliff/en.xlf in ko
100% translated source file: 'web/xliff/en.xlf'
on 'ko'.
* Translate web/xliff/en.xlf in ko
100% translated source file: 'web/xliff/en.xlf'
on 'ko'.
* Translate web/xliff/en.xlf in ko
100% translated source file: 'web/xliff/en.xlf'
on 'ko'.
* Translate web/xliff/en.xlf in ko
100% translated source file: 'web/xliff/en.xlf'
on 'ko'.
* Translate web/xliff/en.xlf in ko
100% translated source file: 'web/xliff/en.xlf'
on 'ko'.
* Translate web/xliff/en.xlf in ko
100% translated source file: 'web/xliff/en.xlf'
on 'ko'.
---------
Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>