web: Tidy temporal utilities. (#13755)
This commit is contained in:
@ -2,7 +2,7 @@ import { EventGeo, EventUser } from "@goauthentik/admin/events/utils";
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EventWithContext } from "@goauthentik/common/events";
|
import { EventWithContext } from "@goauthentik/common/events";
|
||||||
import { actionToLabel } from "@goauthentik/common/labels";
|
import { actionToLabel } from "@goauthentik/common/labels";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/components/ak-event-info";
|
import "@goauthentik/components/ak-event-info";
|
||||||
import "@goauthentik/elements/Tabs";
|
import "@goauthentik/elements/Tabs";
|
||||||
import "@goauthentik/elements/buttons/Dropdown";
|
import "@goauthentik/elements/buttons/Dropdown";
|
||||||
@ -74,7 +74,7 @@ export class RecentEventsCard extends Table<Event> {
|
|||||||
html`<div><a href="${`#/events/log/${item.pk}`}">${actionToLabel(item.action)}</a></div>
|
html`<div><a href="${`#/events/log/${item.pk}`}">${actionToLabel(item.action)}</a></div>
|
||||||
<small>${item.app}</small>`,
|
<small>${item.app}</small>`,
|
||||||
EventUser(item),
|
EventUser(item),
|
||||||
html`<div>${getRelativeTime(item.created)}</div>
|
html`<div>${formatElapsedTime(item.created)}</div>
|
||||||
<small>${item.created.toLocaleString()}</small>`,
|
<small>${item.created.toLocaleString()}</small>`,
|
||||||
html` <div>${item.clientIp || msg("-")}</div>
|
html` <div>${item.clientIp || msg("-")}</div>
|
||||||
<small>${EventGeo(item)}</small>`,
|
<small>${EventGeo(item)}</small>`,
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import "@goauthentik/admin/blueprints/BlueprintForm";
|
|||||||
import "@goauthentik/admin/rbac/ObjectPermissionModal";
|
import "@goauthentik/admin/rbac/ObjectPermissionModal";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/components/ak-status-label";
|
import "@goauthentik/components/ak-status-label";
|
||||||
import "@goauthentik/elements/buttons/ActionButton";
|
import "@goauthentik/elements/buttons/ActionButton";
|
||||||
import "@goauthentik/elements/buttons/SpinnerButton";
|
import "@goauthentik/elements/buttons/SpinnerButton";
|
||||||
@ -141,7 +141,7 @@ export class BlueprintListPage extends TablePage<BlueprintInstance> {
|
|||||||
html`<div>${item.name}</div>
|
html`<div>${item.name}</div>
|
||||||
${description ? html`<small>${description}</small>` : html``}`,
|
${description ? html`<small>${description}</small>` : html``}`,
|
||||||
html`${BlueprintStatus(item)}`,
|
html`${BlueprintStatus(item)}`,
|
||||||
html`<div>${getRelativeTime(item.lastApplied)}</div>
|
html`<div>${formatElapsedTime(item.lastApplied)}</div>
|
||||||
<small>${item.lastApplied.toLocaleString()}</small>`,
|
<small>${item.lastApplied.toLocaleString()}</small>`,
|
||||||
html`<ak-status-label ?good=${item.enabled}></ak-status-label>`,
|
html`<ak-status-label ?good=${item.enabled}></ak-status-label>`,
|
||||||
html`<ak-forms-modal>
|
html`<ak-forms-modal>
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import "@goauthentik/admin/enterprise/EnterpriseLicenseForm";
|
|||||||
import "@goauthentik/admin/enterprise/EnterpriseStatusCard";
|
import "@goauthentik/admin/enterprise/EnterpriseStatusCard";
|
||||||
import "@goauthentik/admin/rbac/ObjectPermissionModal";
|
import "@goauthentik/admin/rbac/ObjectPermissionModal";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import { PFColor } from "@goauthentik/elements/Label";
|
import { PFColor } from "@goauthentik/elements/Label";
|
||||||
import "@goauthentik/elements/Spinner";
|
import "@goauthentik/elements/Spinner";
|
||||||
import "@goauthentik/elements/buttons/SpinnerButton";
|
import "@goauthentik/elements/buttons/SpinnerButton";
|
||||||
@ -186,7 +186,7 @@ export class EnterpriseLicenseListPage extends TablePage<License> {
|
|||||||
>
|
>
|
||||||
${this.summary &&
|
${this.summary &&
|
||||||
this.summary?.status !== LicenseSummaryStatusEnum.Unlicensed
|
this.summary?.status !== LicenseSummaryStatusEnum.Unlicensed
|
||||||
? html`<div>${getRelativeTime(this.summary.latestValid)}</div>
|
? html`<div>${formatElapsedTime(this.summary.latestValid)}</div>
|
||||||
<small>${this.summary.latestValid.toLocaleString()}</small>`
|
<small>${this.summary.latestValid.toLocaleString()}</small>`
|
||||||
: "-"}
|
: "-"}
|
||||||
</ak-aggregate-card>
|
</ak-aggregate-card>
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { EventGeo, EventUser } from "@goauthentik/admin/events/utils";
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EventWithContext } from "@goauthentik/common/events";
|
import { EventWithContext } from "@goauthentik/common/events";
|
||||||
import { actionToLabel } from "@goauthentik/common/labels";
|
import { actionToLabel } from "@goauthentik/common/labels";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/components/ak-event-info";
|
import "@goauthentik/components/ak-event-info";
|
||||||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||||
@ -78,7 +78,7 @@ export class EventListPage extends TablePage<Event> {
|
|||||||
html`<div>${actionToLabel(item.action)}</div>
|
html`<div>${actionToLabel(item.action)}</div>
|
||||||
<small>${item.app}</small>`,
|
<small>${item.app}</small>`,
|
||||||
EventUser(item),
|
EventUser(item),
|
||||||
html`<div>${getRelativeTime(item.created)}</div>
|
html`<div>${formatElapsedTime(item.created)}</div>
|
||||||
<small>${item.created.toLocaleString()}</small>`,
|
<small>${item.created.toLocaleString()}</small>`,
|
||||||
html`<div>${item.clientIp || msg("-")}</div>
|
html`<div>${item.clientIp || msg("-")}</div>
|
||||||
<small>${EventGeo(item)}</small>`,
|
<small>${EventGeo(item)}</small>`,
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { EventGeo, EventUser } from "@goauthentik/admin/events/utils";
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EventWithContext } from "@goauthentik/common/events";
|
import { EventWithContext } from "@goauthentik/common/events";
|
||||||
import { actionToLabel } from "@goauthentik/common/labels";
|
import { actionToLabel } from "@goauthentik/common/labels";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/components/ak-event-info";
|
import "@goauthentik/components/ak-event-info";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import "@goauthentik/elements/PageHeader";
|
import "@goauthentik/elements/PageHeader";
|
||||||
@ -104,7 +104,7 @@ export class EventViewPage extends AKElement {
|
|||||||
</dt>
|
</dt>
|
||||||
<dd class="pf-c-description-list__description">
|
<dd class="pf-c-description-list__description">
|
||||||
<div class="pf-c-description-list__text">
|
<div class="pf-c-description-list__text">
|
||||||
<div>${getRelativeTime(this.event.created)}</div>
|
<div>${formatElapsedTime(this.event.created)}</div>
|
||||||
<small>${this.event.created.toLocaleString()}</small>
|
<small>${this.event.created.toLocaleString()}</small>
|
||||||
</div>
|
</div>
|
||||||
</dd>
|
</dd>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/components/ak-status-label";
|
import "@goauthentik/components/ak-status-label";
|
||||||
import "@goauthentik/elements/buttons/SpinnerButton";
|
import "@goauthentik/elements/buttons/SpinnerButton";
|
||||||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||||
@ -105,7 +105,7 @@ export class MemberSelectTable extends TableModal<User> {
|
|||||||
<small>${item.name}</small>`,
|
<small>${item.name}</small>`,
|
||||||
html` <ak-status-label type="warning" ?good=${item.isActive}></ak-status-label>`,
|
html` <ak-status-label type="warning" ?good=${item.isActive}></ak-status-label>`,
|
||||||
html`${item.lastLogin
|
html`${item.lastLogin
|
||||||
? html`<div>${getRelativeTime(item.lastLogin)}</div>
|
? html`<div>${formatElapsedTime(item.lastLogin)}</div>
|
||||||
<small>${item.lastLogin.toLocaleString()}</small>`
|
<small>${item.lastLogin.toLocaleString()}</small>`
|
||||||
: msg("-")}`,
|
: msg("-")}`,
|
||||||
];
|
];
|
||||||
|
|||||||
@ -8,8 +8,8 @@ import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
|||||||
import { PFSize } from "@goauthentik/common/enums.js";
|
import { PFSize } from "@goauthentik/common/enums.js";
|
||||||
import { parseAPIResponseError, pluckErrorDetail } from "@goauthentik/common/errors/network";
|
import { parseAPIResponseError, pluckErrorDetail } from "@goauthentik/common/errors/network";
|
||||||
import { MessageLevel } from "@goauthentik/common/messages";
|
import { MessageLevel } from "@goauthentik/common/messages";
|
||||||
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import { me } from "@goauthentik/common/users";
|
import { me } from "@goauthentik/common/users";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
|
||||||
import "@goauthentik/components/ak-status-label";
|
import "@goauthentik/components/ak-status-label";
|
||||||
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
|
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
|
||||||
import {
|
import {
|
||||||
@ -194,7 +194,7 @@ export class RelatedUserList extends WithBrandConfig(WithCapabilitiesConfig(Tabl
|
|||||||
</a>`,
|
</a>`,
|
||||||
html`<ak-status-label ?good=${item.isActive}></ak-status-label>`,
|
html`<ak-status-label ?good=${item.isActive}></ak-status-label>`,
|
||||||
html`${item.lastLogin
|
html`${item.lastLogin
|
||||||
? html`<div>${getRelativeTime(item.lastLogin)}</div>
|
? html`<div>${formatElapsedTime(item.lastLogin)}</div>
|
||||||
<small>${item.lastLogin.toLocaleString()}</small>`
|
<small>${item.lastLogin.toLocaleString()}</small>`
|
||||||
: msg("-")}`,
|
: msg("-")}`,
|
||||||
html`<ak-forms-modal>
|
html`<ak-forms-modal>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import { PFColor } from "@goauthentik/elements/Label";
|
import { PFColor } from "@goauthentik/elements/Label";
|
||||||
import "@goauthentik/elements/Spinner";
|
import "@goauthentik/elements/Spinner";
|
||||||
@ -51,7 +51,7 @@ export class OutpostHealthElement extends AKElement {
|
|||||||
<div class="pf-c-description-list__text">
|
<div class="pf-c-description-list__text">
|
||||||
<ak-label color=${PFColor.Green} ?compact=${true}>
|
<ak-label color=${PFColor.Green} ?compact=${true}>
|
||||||
${msg(
|
${msg(
|
||||||
str`${getRelativeTime(this.outpostHealth.lastSeen)} (${this.outpostHealth.lastSeen?.toLocaleTimeString()})`,
|
str`${formatElapsedTime(this.outpostHealth.lastSeen)} (${this.outpostHealth.lastSeen?.toLocaleTimeString()})`,
|
||||||
)}
|
)}
|
||||||
</ak-label>
|
</ak-label>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import { PFColor } from "@goauthentik/elements/Label";
|
import { PFColor } from "@goauthentik/elements/Label";
|
||||||
import "@goauthentik/elements/Spinner";
|
import "@goauthentik/elements/Spinner";
|
||||||
@ -69,7 +69,7 @@ export class OutpostHealthSimpleElement extends AKElement {
|
|||||||
const lastSeen = this.outpostHealths[0].lastSeen;
|
const lastSeen = this.outpostHealths[0].lastSeen;
|
||||||
return html`<ak-label color=${PFColor.Green}>
|
return html`<ak-label color=${PFColor.Green}>
|
||||||
${msg(
|
${msg(
|
||||||
str`Last seen: ${getRelativeTime(lastSeen)} (${lastSeen.toLocaleTimeString()})`,
|
str`Last seen: ${formatElapsedTime(lastSeen)} (${lastSeen.toLocaleTimeString()})`,
|
||||||
)}</ak-label
|
)}</ak-label
|
||||||
>`;
|
>`;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import "@goauthentik/admin/rbac/ObjectPermissionModal";
|
import "@goauthentik/admin/rbac/ObjectPermissionModal";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/elements/buttons/ModalButton";
|
import "@goauthentik/elements/buttons/ModalButton";
|
||||||
import "@goauthentik/elements/buttons/SpinnerButton";
|
import "@goauthentik/elements/buttons/SpinnerButton";
|
||||||
import "@goauthentik/elements/forms/DeleteBulkForm";
|
import "@goauthentik/elements/forms/DeleteBulkForm";
|
||||||
@ -89,7 +89,7 @@ export class ReputationListPage extends TablePage<Reputation> {
|
|||||||
: html``}
|
: html``}
|
||||||
${item.ip}`,
|
${item.ip}`,
|
||||||
html`${item.score}`,
|
html`${item.score}`,
|
||||||
html`<div>${getRelativeTime(item.updated)}</div>
|
html`<div>${formatElapsedTime(item.updated)}</div>
|
||||||
<small>${item.updated.toLocaleString()}</small>`,
|
<small>${item.updated.toLocaleString()}</small>`,
|
||||||
html`
|
html`
|
||||||
<ak-rbac-object-permission-modal
|
<ak-rbac-object-permission-modal
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import "@goauthentik/admin/common/ak-flow-search/ak-flow-search";
|
import "@goauthentik/admin/common/ak-flow-search/ak-flow-search";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { dateTimeLocal, first } from "@goauthentik/common/utils";
|
import { dateTimeLocal } from "@goauthentik/common/temporal";
|
||||||
|
import { first } from "@goauthentik/common/utils";
|
||||||
import "@goauthentik/elements/CodeMirror";
|
import "@goauthentik/elements/CodeMirror";
|
||||||
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
||||||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import { PFColor } from "@goauthentik/elements/Label";
|
import { PFColor } from "@goauthentik/elements/Label";
|
||||||
import "@goauthentik/elements/buttons/ActionButton";
|
import "@goauthentik/elements/buttons/ActionButton";
|
||||||
import "@goauthentik/elements/buttons/SpinnerButton";
|
import "@goauthentik/elements/buttons/SpinnerButton";
|
||||||
@ -100,7 +100,7 @@ export class SystemTaskListPage extends TablePage<SystemTask> {
|
|||||||
item.expires || new Date()
|
item.expires || new Date()
|
||||||
).toLocaleString()}
|
).toLocaleString()}
|
||||||
>
|
>
|
||||||
${getRelativeTime(item.expires || new Date())}
|
${formatElapsedTime(item.expires || new Date())}
|
||||||
</pf-tooltip>
|
</pf-tooltip>
|
||||||
`
|
`
|
||||||
: msg("-")}
|
: msg("-")}
|
||||||
@ -128,7 +128,7 @@ export class SystemTaskListPage extends TablePage<SystemTask> {
|
|||||||
return [
|
return [
|
||||||
html`<pre>${item.name}${item.uid ? `:${item.uid}` : ""}</pre>`,
|
html`<pre>${item.name}${item.uid ? `:${item.uid}` : ""}</pre>`,
|
||||||
html`${item.description}`,
|
html`${item.description}`,
|
||||||
html`<div>${getRelativeTime(item.finishTimestamp)}</div>
|
html`<div>${formatElapsedTime(item.finishTimestamp)}</div>
|
||||||
<small>${item.finishTimestamp.toLocaleString()}</small>`,
|
<small>${item.finishTimestamp.toLocaleString()}</small>`,
|
||||||
this.taskStatus(item),
|
this.taskStatus(item),
|
||||||
html`<ak-action-button
|
html`<ak-action-button
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { dateTimeLocal, first } from "@goauthentik/common/utils";
|
import { dateTimeLocal } from "@goauthentik/common/temporal";
|
||||||
|
import { first } from "@goauthentik/common/utils";
|
||||||
import "@goauthentik/elements/forms/FormGroup";
|
import "@goauthentik/elements/forms/FormGroup";
|
||||||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||||
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
|
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import "@goauthentik/admin/rbac/ObjectPermissionModal";
|
|||||||
import "@goauthentik/admin/tokens/TokenForm";
|
import "@goauthentik/admin/tokens/TokenForm";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { intentToLabel } from "@goauthentik/common/labels";
|
import { intentToLabel } from "@goauthentik/common/labels";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/components/ak-status-label";
|
import "@goauthentik/components/ak-status-label";
|
||||||
import "@goauthentik/elements/buttons/Dropdown";
|
import "@goauthentik/elements/buttons/Dropdown";
|
||||||
import "@goauthentik/elements/buttons/TokenCopyButton";
|
import "@goauthentik/elements/buttons/TokenCopyButton";
|
||||||
@ -107,7 +107,7 @@ export class TokenListPage extends TablePage<Token> {
|
|||||||
html`<a href="#/identity/users/${item.userObj?.pk}">${item.userObj?.username}</a>`,
|
html`<a href="#/identity/users/${item.userObj?.pk}">${item.userObj?.username}</a>`,
|
||||||
html`<ak-status-label type="warning" ?good=${item.expiring}></ak-status-label>`,
|
html`<ak-status-label type="warning" ?good=${item.expiring}></ak-status-label>`,
|
||||||
html`${item.expires && item.expiring
|
html`${item.expires && item.expiring
|
||||||
? html`<div>${getRelativeTime(item.expires)}</div>
|
? html`<div>${formatElapsedTime(item.expires)}</div>
|
||||||
<small>${item.expires.toLocaleString()}</small>`
|
<small>${item.expires.toLocaleString()}</small>`
|
||||||
: msg("-")}`,
|
: msg("-")}`,
|
||||||
html`${intentToLabel(item.intent ?? IntentEnum.Api)}`,
|
html`${intentToLabel(item.intent ?? IntentEnum.Api)}`,
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { dateTimeLocal } from "@goauthentik/common/utils";
|
import { dateTimeLocal } from "@goauthentik/common/temporal";
|
||||||
import { Form } from "@goauthentik/elements/forms/Form";
|
import { Form } from "@goauthentik/elements/forms/Form";
|
||||||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||||
import { ModalForm } from "@goauthentik/elements/forms/ModalForm";
|
import { ModalForm } from "@goauthentik/elements/forms/ModalForm";
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { deviceTypeName } from "@goauthentik/common/labels";
|
import { deviceTypeName } from "@goauthentik/common/labels";
|
||||||
import { SentryIgnoredError } from "@goauthentik/common/sentry";
|
import { SentryIgnoredError } from "@goauthentik/common/sentry";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/elements/forms/DeleteBulkForm";
|
import "@goauthentik/elements/forms/DeleteBulkForm";
|
||||||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||||
import { Table, TableColumn } from "@goauthentik/elements/table/Table";
|
import { Table, TableColumn } from "@goauthentik/elements/table/Table";
|
||||||
@ -108,15 +108,15 @@ export class UserDeviceTable extends Table<Device> {
|
|||||||
${item.extraDescription ? ` - ${item.extraDescription}` : ""}`,
|
${item.extraDescription ? ` - ${item.extraDescription}` : ""}`,
|
||||||
html`${item.confirmed ? msg("Yes") : msg("No")}`,
|
html`${item.confirmed ? msg("Yes") : msg("No")}`,
|
||||||
html`${item.created.getTime() > 0
|
html`${item.created.getTime() > 0
|
||||||
? html`<div>${getRelativeTime(item.created)}</div>
|
? html`<div>${formatElapsedTime(item.created)}</div>
|
||||||
<small>${item.created.toLocaleString()}</small>`
|
<small>${item.created.toLocaleString()}</small>`
|
||||||
: html`-`}`,
|
: html`-`}`,
|
||||||
html`${item.lastUpdated
|
html`${item.lastUpdated
|
||||||
? html`<div>${getRelativeTime(item.lastUpdated)}</div>
|
? html`<div>${formatElapsedTime(item.lastUpdated)}</div>
|
||||||
<small>${item.lastUpdated.toLocaleString()}</small>`
|
<small>${item.lastUpdated.toLocaleString()}</small>`
|
||||||
: html`-`}`,
|
: html`-`}`,
|
||||||
html`${item.lastUsed
|
html`${item.lastUsed
|
||||||
? html`<div>${getRelativeTime(item.lastUsed)}</div>
|
? html`<div>${formatElapsedTime(item.lastUsed)}</div>
|
||||||
<small>${item.lastUsed.toLocaleString()}</small>`
|
<small>${item.lastUsed.toLocaleString()}</small>`
|
||||||
: html`-`}`,
|
: html`-`}`,
|
||||||
];
|
];
|
||||||
|
|||||||
@ -10,9 +10,9 @@ import { PFSize } from "@goauthentik/common/enums.js";
|
|||||||
import { parseAPIResponseError } from "@goauthentik/common/errors/network";
|
import { parseAPIResponseError } from "@goauthentik/common/errors/network";
|
||||||
import { userTypeToLabel } from "@goauthentik/common/labels";
|
import { userTypeToLabel } from "@goauthentik/common/labels";
|
||||||
import { MessageLevel } from "@goauthentik/common/messages";
|
import { MessageLevel } from "@goauthentik/common/messages";
|
||||||
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import { DefaultUIConfig, uiConfig } from "@goauthentik/common/ui/config";
|
import { DefaultUIConfig, uiConfig } from "@goauthentik/common/ui/config";
|
||||||
import { me } from "@goauthentik/common/users";
|
import { me } from "@goauthentik/common/users";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
|
||||||
import "@goauthentik/components/ak-status-label";
|
import "@goauthentik/components/ak-status-label";
|
||||||
import { rootInterface } from "@goauthentik/elements/Base";
|
import { rootInterface } from "@goauthentik/elements/Base";
|
||||||
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
|
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
|
||||||
@ -244,7 +244,7 @@ export class UserListPage extends WithBrandConfig(WithCapabilitiesConfig(TablePa
|
|||||||
</a>`,
|
</a>`,
|
||||||
html`<ak-status-label ?good=${item.isActive}></ak-status-label>`,
|
html`<ak-status-label ?good=${item.isActive}></ak-status-label>`,
|
||||||
html`${item.lastLogin
|
html`${item.lastLogin
|
||||||
? html`<div>${getRelativeTime(item.lastLogin)}</div>
|
? html`<div>${formatElapsedTime(item.lastLogin)}</div>
|
||||||
<small>${item.lastLogin.toLocaleString()}</small>`
|
<small>${item.lastLogin.toLocaleString()}</small>`
|
||||||
: msg("-")}`,
|
: msg("-")}`,
|
||||||
html`${userTypeToLabel(item.type)}`,
|
html`${userTypeToLabel(item.type)}`,
|
||||||
|
|||||||
@ -15,8 +15,8 @@ import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
|||||||
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
||||||
import { PFSize } from "@goauthentik/common/enums.js";
|
import { PFSize } from "@goauthentik/common/enums.js";
|
||||||
import { userTypeToLabel } from "@goauthentik/common/labels";
|
import { userTypeToLabel } from "@goauthentik/common/labels";
|
||||||
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import { me } from "@goauthentik/common/users";
|
import { me } from "@goauthentik/common/users";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
|
||||||
import "@goauthentik/components/DescriptionList";
|
import "@goauthentik/components/DescriptionList";
|
||||||
import {
|
import {
|
||||||
type DescriptionPair,
|
type DescriptionPair,
|
||||||
@ -155,11 +155,11 @@ export class UserViewPage extends WithCapabilitiesConfig(AKElement) {
|
|||||||
[msg("Name"), user.name],
|
[msg("Name"), user.name],
|
||||||
[msg("Email"), user.email || "-"],
|
[msg("Email"), user.email || "-"],
|
||||||
[msg("Last login"), user.lastLogin
|
[msg("Last login"), user.lastLogin
|
||||||
? html`<div>${getRelativeTime(user.lastLogin)}</div>
|
? html`<div>${formatElapsedTime(user.lastLogin)}</div>
|
||||||
<small>${user.lastLogin.toLocaleString()}</small>`
|
<small>${user.lastLogin.toLocaleString()}</small>`
|
||||||
: html`${msg("-")}`],
|
: html`${msg("-")}`],
|
||||||
[msg("Last password change"), user.passwordChangeDate
|
[msg("Last password change"), user.passwordChangeDate
|
||||||
? html`<div>${getRelativeTime(user.passwordChangeDate)}</div>
|
? html`<div>${formatElapsedTime(user.passwordChangeDate)}</div>
|
||||||
<small>${user.passwordChangeDate.toLocaleString()}</small>`
|
<small>${user.passwordChangeDate.toLocaleString()}</small>`
|
||||||
: html`${msg("-")}`],
|
: html`${msg("-")}`],
|
||||||
[msg("Active"), html`<ak-status-label type="warning" ?good=${user.isActive}></ak-status-label>`],
|
[msg("Active"), html`<ak-status-label type="warning" ?good=${user.isActive}></ak-status-label>`],
|
||||||
|
|||||||
132
web/src/common/temporal.ts
Normal file
132
web/src/common/temporal.ts
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/**
|
||||||
|
* @file Temporal utilitie for working with dates and times.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Duration in milliseconds for time units used by the `Intl.RelativeTimeFormat` API.
|
||||||
|
*/
|
||||||
|
export const Duration = {
|
||||||
|
/**
|
||||||
|
* The number of milliseconds in a year.
|
||||||
|
*/
|
||||||
|
year: 1000 * 60 * 60 * 24 * 365,
|
||||||
|
/**
|
||||||
|
* The number of milliseconds in a month.
|
||||||
|
*/
|
||||||
|
month: (24 * 60 * 60 * 1000 * 365) / 12,
|
||||||
|
/**
|
||||||
|
* The number of milliseconds in a day.
|
||||||
|
*/
|
||||||
|
day: 1000 * 60 * 60 * 24,
|
||||||
|
/**
|
||||||
|
* The number of milliseconds in an hour.
|
||||||
|
*/
|
||||||
|
hour: 1000 * 60 * 60,
|
||||||
|
/**
|
||||||
|
* The number of milliseconds in a minute.
|
||||||
|
*/
|
||||||
|
minute: 1000 * 60,
|
||||||
|
/**
|
||||||
|
* The number of milliseconds in a second.
|
||||||
|
*/
|
||||||
|
second: 1000,
|
||||||
|
} as const satisfies Partial<Record<Intl.RelativeTimeFormatUnit, number>>;
|
||||||
|
|
||||||
|
export type DurationUnit = keyof typeof Duration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The order of time units used by the `Intl.RelativeTimeFormat` API.
|
||||||
|
*/
|
||||||
|
const DurationGranularity = [
|
||||||
|
"year",
|
||||||
|
"month",
|
||||||
|
"day",
|
||||||
|
"hour",
|
||||||
|
"minute",
|
||||||
|
"second",
|
||||||
|
] as const satisfies DurationUnit[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given two dates, return a human-readable string describing the time elapsed between them.
|
||||||
|
*/
|
||||||
|
export function formatElapsedTime(d1: Date, d2: Date = new Date()): string {
|
||||||
|
const elapsed = d1.getTime() - d2.getTime();
|
||||||
|
const rtf = new Intl.RelativeTimeFormat("default", { numeric: "auto" });
|
||||||
|
|
||||||
|
for (const unit of DurationGranularity) {
|
||||||
|
const duration = Duration[unit];
|
||||||
|
|
||||||
|
if (Math.abs(elapsed) > duration || unit === "second") {
|
||||||
|
let rounded = Math.round(elapsed / duration);
|
||||||
|
|
||||||
|
if (!isFinite(rounded)) {
|
||||||
|
rounded = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtf.format(rounded, unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rtf.format(Math.round(elapsed / 1000), "second");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a Date object to a string in the format required by the datetime-local input field.
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* html`<input
|
||||||
|
* type="datetime-local"
|
||||||
|
* data-type="datetime-local"
|
||||||
|
* class="pf-c-form-control"
|
||||||
|
* required
|
||||||
|
* value="${dateTimeLocal(new Date())}"
|
||||||
|
* />
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param input - The Date object to convert.
|
||||||
|
* @returns A string in the format "YYYY-MM-DDTHH:MM" (e.g., "2023-10-01T12:00").
|
||||||
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/datetime-local
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
*
|
||||||
|
* So for some reason, the datetime-local input field requires ISO Datetime as value.
|
||||||
|
*
|
||||||
|
* But the standard`date.toISOString()` returns everything with seconds and milliseconds,
|
||||||
|
* which the input field doesn't like (on chrome, on firefox its fine)
|
||||||
|
*
|
||||||
|
* On chrome, setting .valueAsNumber works, but that causes an error on firefox, so go figure.
|
||||||
|
*
|
||||||
|
* Additionally, `toISOString` always returns the date without timezone,
|
||||||
|
* which we would like to include for better usability
|
||||||
|
*/
|
||||||
|
export function dateTimeLocal(input: Date): string {
|
||||||
|
const tzOffset = new Date().getTimezoneOffset() * 60_000; //offset in milliseconds
|
||||||
|
const localISOTime = new Date(input.getTime() - tzOffset).toISOString().slice(0, -1);
|
||||||
|
|
||||||
|
const [datePart, timePart] = localISOTime.split(":");
|
||||||
|
|
||||||
|
return [datePart, timePart].join(":");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a Date object to UTC.
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
*
|
||||||
|
* Sigh...so our API is UTC/can take TZ info in the ISO format as it should.
|
||||||
|
*
|
||||||
|
* datetime-local fields (which is almost the only date-time input we use)
|
||||||
|
* can return its value as a UTC timestamp...however the generated API client
|
||||||
|
* _requires_ a Date object, only to then convert it to an ISO string anyways
|
||||||
|
* JS Dates don't include timezone info in the ISO string, so that just sends
|
||||||
|
* the local time as UTC...which is wrong.
|
||||||
|
*
|
||||||
|
* Instead we have to do this, convert the given date to a UTC timestamp,
|
||||||
|
* then subtract the timezone offset to create an "invalid" date (correct time&date)
|
||||||
|
* but it still "thinks" it's in local TZ.
|
||||||
|
*/
|
||||||
|
export function dateToUTC(input: Date): Date {
|
||||||
|
const timestamp = input.getTime();
|
||||||
|
const offset = -1 * (new Date().getTimezoneOffset() * 60_000);
|
||||||
|
|
||||||
|
return new Date(timestamp - offset);
|
||||||
|
}
|
||||||
@ -103,35 +103,6 @@ export function randomString(len: number, charset: string): string {
|
|||||||
return chars.join("");
|
return chars.join("");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function dateTimeLocal(date: Date): string {
|
|
||||||
// So for some reason, the datetime-local input field requires ISO Datetime as value
|
|
||||||
// But the standard javascript date.toISOString() returns everything with seconds and
|
|
||||||
// milliseconds, which the input field doesn't like (on chrome, on firefox its fine)
|
|
||||||
// On chrome, setting .valueAsNumber works, but that causes an error on firefox, so go
|
|
||||||
// figure.
|
|
||||||
// Additionally, toISOString always returns the date without timezone, which we would like
|
|
||||||
// to include for better usability
|
|
||||||
const tzOffset = new Date().getTimezoneOffset() * 60000; //offset in milliseconds
|
|
||||||
const localISOTime = new Date(date.getTime() - tzOffset).toISOString().slice(0, -1);
|
|
||||||
const parts = localISOTime.split(":");
|
|
||||||
return `${parts[0]}:${parts[1]}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function dateToUTC(date: Date): Date {
|
|
||||||
// Sigh...so our API is UTC/can take TZ info in the ISO format as it should.
|
|
||||||
// datetime-local fields (which is almost the only date-time input we use)
|
|
||||||
// can return its value as a UTC timestamp...however the generated API client
|
|
||||||
// _requires_ a Date object, only to then convert it to an ISO string anyways
|
|
||||||
// JS Dates don't include timezone info in the ISO string, so that just sends
|
|
||||||
// the local time as UTC...which is wrong
|
|
||||||
// Instead we have to do this, convert the given date to a UTC timestamp,
|
|
||||||
// then subtract the timezone offset to create an "invalid" date (correct time&date)
|
|
||||||
// but it still "thinks" it's in local TZ
|
|
||||||
const timestamp = date.getTime();
|
|
||||||
const offset = -1 * (new Date().getTimezoneOffset() * 60000);
|
|
||||||
return new Date(timestamp - offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lit is extremely well-typed with regard to CSS, and Storybook's `build` does not currently have a
|
// Lit is extremely well-typed with regard to CSS, and Storybook's `build` does not currently have a
|
||||||
// coherent way of importing CSS-as-text into CSSStyleSheet. It works well when Storybook is running
|
// coherent way of importing CSS-as-text into CSSStyleSheet. It works well when Storybook is running
|
||||||
// in `dev,` but in `build` it fails. Storied components will have to map their textual CSS imports
|
// in `dev,` but in `build` it fails. Storied components will have to map their textual CSS imports
|
||||||
@ -156,28 +127,3 @@ export function adaptCSS(sheet: AdaptableStylesheet[]): CSSStyleSheet[];
|
|||||||
export function adaptCSS(sheet: AdaptableStylesheet | AdaptableStylesheet[]): AdaptedStylesheets {
|
export function adaptCSS(sheet: AdaptableStylesheet | AdaptableStylesheet[]): AdaptedStylesheets {
|
||||||
return Array.isArray(sheet) ? sheet.map(_adaptCSS) : _adaptCSS(sheet);
|
return Array.isArray(sheet) ? sheet.map(_adaptCSS) : _adaptCSS(sheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getRelativeTime(d1: Date, d2: Date = new Date()): string {
|
|
||||||
const elapsed = d1.getTime() - d2.getTime();
|
|
||||||
const rtf = new Intl.RelativeTimeFormat("default", { numeric: "auto" });
|
|
||||||
|
|
||||||
const _timeUnits: [Intl.RelativeTimeFormatUnit, number][] = [
|
|
||||||
["year", 1000 * 60 * 60 * 24 * 365],
|
|
||||||
["month", (24 * 60 * 60 * 1000 * 365) / 12],
|
|
||||||
["day", 1000 * 60 * 60 * 24],
|
|
||||||
["hour", 1000 * 60 * 60],
|
|
||||||
["minute", 1000 * 60],
|
|
||||||
["second", 1000],
|
|
||||||
];
|
|
||||||
|
|
||||||
for (const [key, value] of _timeUnits) {
|
|
||||||
if (Math.abs(elapsed) > value || key === "second") {
|
|
||||||
let rounded = Math.round(elapsed / value);
|
|
||||||
if (!isFinite(rounded)) {
|
|
||||||
rounded = 0;
|
|
||||||
}
|
|
||||||
return rtf.format(rounded, key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rtf.format(Math.round(elapsed / 1000), "second");
|
|
||||||
}
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { EventGeo, EventUser } from "@goauthentik/admin/events/utils";
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EventWithContext } from "@goauthentik/common/events";
|
import { EventWithContext } from "@goauthentik/common/events";
|
||||||
import { actionToLabel } from "@goauthentik/common/labels";
|
import { actionToLabel } from "@goauthentik/common/labels";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/components/ak-event-info";
|
import "@goauthentik/components/ak-event-info";
|
||||||
import "@goauthentik/elements/Tabs";
|
import "@goauthentik/elements/Tabs";
|
||||||
import "@goauthentik/elements/buttons/Dropdown";
|
import "@goauthentik/elements/buttons/Dropdown";
|
||||||
@ -73,7 +73,7 @@ export class ObjectChangelog extends Table<Event> {
|
|||||||
return [
|
return [
|
||||||
html`${actionToLabel(item.action)}`,
|
html`${actionToLabel(item.action)}`,
|
||||||
EventUser(item),
|
EventUser(item),
|
||||||
html`<div>${getRelativeTime(item.created)}</div>
|
html`<div>${formatElapsedTime(item.created)}</div>
|
||||||
<small>${item.created.toLocaleString()}</small>`,
|
<small>${item.created.toLocaleString()}</small>`,
|
||||||
html`<div>${item.clientIp || msg("-")}</div>
|
html`<div>${item.clientIp || msg("-")}</div>
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { EventUser } from "@goauthentik/admin/events/utils";
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EventWithContext } from "@goauthentik/common/events";
|
import { EventWithContext } from "@goauthentik/common/events";
|
||||||
import { actionToLabel } from "@goauthentik/common/labels";
|
import { actionToLabel } from "@goauthentik/common/labels";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/components/ak-event-info";
|
import "@goauthentik/components/ak-event-info";
|
||||||
import "@goauthentik/elements/Tabs";
|
import "@goauthentik/elements/Tabs";
|
||||||
import "@goauthentik/elements/buttons/Dropdown";
|
import "@goauthentik/elements/buttons/Dropdown";
|
||||||
@ -47,7 +47,7 @@ export class UserEvents extends Table<Event> {
|
|||||||
return [
|
return [
|
||||||
html`${actionToLabel(item.action)}`,
|
html`${actionToLabel(item.action)}`,
|
||||||
EventUser(item),
|
EventUser(item),
|
||||||
html`<div>${getRelativeTime(item.created)}</div>
|
html`<div>${formatElapsedTime(item.created)}</div>
|
||||||
<small>${item.created.toLocaleString()}</small>`,
|
<small>${item.created.toLocaleString()}</small>`,
|
||||||
html`<span>${item.clientIp || msg("-")}</span>`,
|
html`<span>${item.clientIp || msg("-")}</span>`,
|
||||||
];
|
];
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import {
|
|||||||
parseAPIResponseError,
|
parseAPIResponseError,
|
||||||
pluckErrorDetail,
|
pluckErrorDetail,
|
||||||
} from "@goauthentik/common/errors/network";
|
} from "@goauthentik/common/errors/network";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import "@goauthentik/elements/EmptyState";
|
import "@goauthentik/elements/EmptyState";
|
||||||
import {
|
import {
|
||||||
@ -176,7 +176,7 @@ export abstract class AKChart<T> extends AKElement {
|
|||||||
|
|
||||||
timeTickCallback(tickValue: string | number, index: number, ticks: Tick[]): string {
|
timeTickCallback(tickValue: string | number, index: number, ticks: Tick[]): string {
|
||||||
const valueStamp = ticks[index];
|
const valueStamp = ticks[index];
|
||||||
return getRelativeTime(new Date(valueStamp.value));
|
return formatElapsedTime(new Date(valueStamp.value));
|
||||||
}
|
}
|
||||||
|
|
||||||
getOptions(): ChartOptions {
|
getOptions(): ChartOptions {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/components/ak-status-label";
|
import "@goauthentik/components/ak-status-label";
|
||||||
import "@goauthentik/elements/EmptyState";
|
import "@goauthentik/elements/EmptyState";
|
||||||
import { PaginatedResponse, Table, TableColumn } from "@goauthentik/elements/table/Table";
|
import { PaginatedResponse, Table, TableColumn } from "@goauthentik/elements/table/Table";
|
||||||
@ -102,7 +102,7 @@ export class LogViewer extends Table<LogEvent> {
|
|||||||
|
|
||||||
row(item: LogEvent): TemplateResult[] {
|
row(item: LogEvent): TemplateResult[] {
|
||||||
return [
|
return [
|
||||||
html`${getRelativeTime(item.timestamp)}`,
|
html`${formatElapsedTime(item.timestamp)}`,
|
||||||
html`<ak-status-label
|
html`<ak-status-label
|
||||||
type=${this.statusForItem(item)}
|
type=${this.statusForItem(item)}
|
||||||
bad-label=${item.logLevel}
|
bad-label=${item.logLevel}
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
||||||
import { parseAPIResponseError, pluckErrorDetail } from "@goauthentik/common/errors/network";
|
import { parseAPIResponseError, pluckErrorDetail } from "@goauthentik/common/errors/network";
|
||||||
import { MessageLevel } from "@goauthentik/common/messages";
|
import { MessageLevel } from "@goauthentik/common/messages";
|
||||||
import { camelToSnake, convertToSlug, dateToUTC } from "@goauthentik/common/utils";
|
import { dateToUTC } from "@goauthentik/common/temporal";
|
||||||
|
import { camelToSnake, convertToSlug } from "@goauthentik/common/utils";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import { HorizontalFormElement } from "@goauthentik/elements/forms/HorizontalFormElement";
|
import { HorizontalFormElement } from "@goauthentik/elements/forms/HorizontalFormElement";
|
||||||
import { PreventFormSubmit } from "@goauthentik/elements/forms/helpers";
|
import { PreventFormSubmit } from "@goauthentik/elements/forms/helpers";
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { RequestInfo } from "@goauthentik/common/api/middleware";
|
import { RequestInfo } from "@goauthentik/common/api/middleware";
|
||||||
import { EVENT_API_DRAWER_TOGGLE, EVENT_REQUEST_POST } from "@goauthentik/common/constants";
|
import { EVENT_API_DRAWER_TOGGLE, EVENT_REQUEST_POST } from "@goauthentik/common/constants";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
@ -79,7 +79,7 @@ export class APIDrawer extends AKElement {
|
|||||||
>${item.path}</a
|
>${item.path}</a
|
||||||
>
|
>
|
||||||
<div class="pf-c-notification-drawer__list-item-timestamp">
|
<div class="pf-c-notification-drawer__list-item-timestamp">
|
||||||
${getRelativeTime(new Date(item.time))}
|
${formatElapsedTime(new Date(item.time))}
|
||||||
</div>
|
</div>
|
||||||
</li>`;
|
</li>`;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,8 +3,8 @@ import { EVENT_NOTIFICATION_DRAWER_TOGGLE, EVENT_REFRESH } from "@goauthentik/co
|
|||||||
import { globalAK } from "@goauthentik/common/global";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import { actionToLabel } from "@goauthentik/common/labels";
|
import { actionToLabel } from "@goauthentik/common/labels";
|
||||||
import { MessageLevel } from "@goauthentik/common/messages";
|
import { MessageLevel } from "@goauthentik/common/messages";
|
||||||
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import { me } from "@goauthentik/common/users";
|
import { me } from "@goauthentik/common/users";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import "@goauthentik/elements/EmptyState";
|
import "@goauthentik/elements/EmptyState";
|
||||||
import { showMessage } from "@goauthentik/elements/messages/MessageContainer";
|
import { showMessage } from "@goauthentik/elements/messages/MessageContainer";
|
||||||
@ -134,7 +134,7 @@ export class NotificationDrawer extends AKElement {
|
|||||||
<p class="pf-c-notification-drawer__list-item-description">${item.body}</p>
|
<p class="pf-c-notification-drawer__list-item-description">${item.body}</p>
|
||||||
<small class="pf-c-notification-drawer__list-item-timestamp"
|
<small class="pf-c-notification-drawer__list-item-timestamp"
|
||||||
><pf-tooltip position="top" .content=${item.created?.toLocaleString()}>
|
><pf-tooltip position="top" .content=${item.created?.toLocaleString()}>
|
||||||
${getRelativeTime(item.created!)}
|
${formatElapsedTime(item.created!)}
|
||||||
</pf-tooltip></small
|
</pf-tooltip></small
|
||||||
>
|
>
|
||||||
</li>`;
|
</li>`;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/components/ak-status-label";
|
import "@goauthentik/components/ak-status-label";
|
||||||
import "@goauthentik/elements/chips/Chip";
|
import "@goauthentik/elements/chips/Chip";
|
||||||
import "@goauthentik/elements/chips/ChipGroup";
|
import "@goauthentik/elements/chips/ChipGroup";
|
||||||
@ -92,7 +92,7 @@ export class UserOAuthAccessTokenList extends Table<TokenModel> {
|
|||||||
bad-label=${msg("Yes")}
|
bad-label=${msg("Yes")}
|
||||||
></ak-status-label>`,
|
></ak-status-label>`,
|
||||||
html`${item.expires
|
html`${item.expires
|
||||||
? html`<div>${getRelativeTime(item.expires)}</div>
|
? html`<div>${formatElapsedTime(item.expires)}</div>
|
||||||
<small>${item.expires.toLocaleString()}</small>`
|
<small>${item.expires.toLocaleString()}</small>`
|
||||||
: msg("-")}`,
|
: msg("-")}`,
|
||||||
html`<ak-chip-group>
|
html`<ak-chip-group>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/components/ak-status-label";
|
import "@goauthentik/components/ak-status-label";
|
||||||
import "@goauthentik/elements/chips/Chip";
|
import "@goauthentik/elements/chips/Chip";
|
||||||
import "@goauthentik/elements/chips/ChipGroup";
|
import "@goauthentik/elements/chips/ChipGroup";
|
||||||
@ -93,7 +93,7 @@ export class UserOAuthRefreshTokenList extends Table<TokenModel> {
|
|||||||
bad-label=${msg("Yes")}
|
bad-label=${msg("Yes")}
|
||||||
></ak-status-label>`,
|
></ak-status-label>`,
|
||||||
html`${item.expires
|
html`${item.expires
|
||||||
? html`<div>${getRelativeTime(item.expires)}</div>
|
? html`<div>${formatElapsedTime(item.expires)}</div>
|
||||||
<small>${item.expires.toLocaleString()}</small>`
|
<small>${item.expires.toLocaleString()}</small>`
|
||||||
: msg("-")}`,
|
: msg("-")}`,
|
||||||
html`<ak-chip-group>
|
html`<ak-chip-group>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/components/ak-status-label";
|
import "@goauthentik/components/ak-status-label";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import "@goauthentik/elements/EmptyState";
|
import "@goauthentik/elements/EmptyState";
|
||||||
@ -71,7 +71,7 @@ export class SyncStatusTable extends Table<SystemTask> {
|
|||||||
good-label=${msg("Finished successfully")}
|
good-label=${msg("Finished successfully")}
|
||||||
bad-label=${msg("Finished with errors")}
|
bad-label=${msg("Finished with errors")}
|
||||||
></ak-status-label>`,
|
></ak-status-label>`,
|
||||||
html`<div>${getRelativeTime(item.finishTimestamp)}</div>
|
html`<div>${formatElapsedTime(item.finishTimestamp)}</div>
|
||||||
<small>${item.finishTimestamp.toLocaleString()}</small>`,
|
<small>${item.finishTimestamp.toLocaleString()}</small>`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/elements/forms/DeleteBulkForm";
|
import "@goauthentik/elements/forms/DeleteBulkForm";
|
||||||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||||
import { Table, TableColumn } from "@goauthentik/elements/table/Table";
|
import { Table, TableColumn } from "@goauthentik/elements/table/Table";
|
||||||
@ -73,9 +73,9 @@ export class AuthenticatedSessionList extends Table<AuthenticatedSession> {
|
|||||||
${item.lastIp}
|
${item.lastIp}
|
||||||
</div>
|
</div>
|
||||||
<small>${item.userAgent.userAgent?.family}, ${item.userAgent.os?.family}</small>`,
|
<small>${item.userAgent.userAgent?.family}, ${item.userAgent.os?.family}</small>`,
|
||||||
html`<div>${getRelativeTime(item.lastUsed)}</div>
|
html`<div>${formatElapsedTime(item.lastUsed)}</div>
|
||||||
<small>${item.lastUsed?.toLocaleString()}</small>`,
|
<small>${item.lastUsed?.toLocaleString()}</small>`,
|
||||||
html`<div>${getRelativeTime(item.expires || new Date())}</div>
|
html`<div>${formatElapsedTime(item.expires || new Date())}</div>
|
||||||
<small>${item.expires?.toLocaleString()}</small>`,
|
<small>${item.expires?.toLocaleString()}</small>`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/elements/chips/Chip";
|
import "@goauthentik/elements/chips/Chip";
|
||||||
import "@goauthentik/elements/chips/ChipGroup";
|
import "@goauthentik/elements/chips/ChipGroup";
|
||||||
import "@goauthentik/elements/forms/DeleteBulkForm";
|
import "@goauthentik/elements/forms/DeleteBulkForm";
|
||||||
@ -62,7 +62,7 @@ export class UserConsentList extends Table<UserConsent> {
|
|||||||
return [
|
return [
|
||||||
html`${item.application.name}`,
|
html`${item.application.name}`,
|
||||||
html`${item.expires && item.expiring
|
html`${item.expires && item.expiring
|
||||||
? html`<div>${getRelativeTime(item.expires)}</div>
|
? html`<div>${formatElapsedTime(item.expires)}</div>
|
||||||
<small>${item.expires.toLocaleString()}</small>`
|
<small>${item.expires.toLocaleString()}</small>`
|
||||||
: msg("-")}`,
|
: msg("-")}`,
|
||||||
html`${item.permissions
|
html`${item.permissions
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/elements/forms/DeleteBulkForm";
|
import "@goauthentik/elements/forms/DeleteBulkForm";
|
||||||
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
|
||||||
import { Table, TableColumn } from "@goauthentik/elements/table/Table";
|
import { Table, TableColumn } from "@goauthentik/elements/table/Table";
|
||||||
@ -73,7 +73,7 @@ export class UserReputationList extends Table<Reputation> {
|
|||||||
: html``}
|
: html``}
|
||||||
${item.ip}`,
|
${item.ip}`,
|
||||||
html`${item.score}`,
|
html`${item.score}`,
|
||||||
html`<div>${getRelativeTime(item.updated)}</div>
|
html`<div>${formatElapsedTime(item.updated)}</div>
|
||||||
<small>${item.updated.toLocaleString()}</small>`,
|
<small>${item.updated.toLocaleString()}</small>`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { AndNext, DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
|||||||
import { globalAK } from "@goauthentik/common/global";
|
import { globalAK } from "@goauthentik/common/global";
|
||||||
import { deviceTypeName } from "@goauthentik/common/labels";
|
import { deviceTypeName } from "@goauthentik/common/labels";
|
||||||
import { SentryIgnoredError } from "@goauthentik/common/sentry";
|
import { SentryIgnoredError } from "@goauthentik/common/sentry";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/elements/buttons/Dropdown";
|
import "@goauthentik/elements/buttons/Dropdown";
|
||||||
import "@goauthentik/elements/buttons/ModalButton";
|
import "@goauthentik/elements/buttons/ModalButton";
|
||||||
import "@goauthentik/elements/buttons/TokenCopyButton";
|
import "@goauthentik/elements/buttons/TokenCopyButton";
|
||||||
@ -133,11 +133,11 @@ export class MFADevicesPage extends Table<Device> {
|
|||||||
html`${deviceTypeName(item)}
|
html`${deviceTypeName(item)}
|
||||||
${item.extraDescription ? ` - ${item.extraDescription}` : ""}`,
|
${item.extraDescription ? ` - ${item.extraDescription}` : ""}`,
|
||||||
html`${item.created.getTime() > 0
|
html`${item.created.getTime() > 0
|
||||||
? html`<div>${getRelativeTime(item.created)}</div>
|
? html`<div>${formatElapsedTime(item.created)}</div>
|
||||||
<small>${item.created.toLocaleString()}</small>`
|
<small>${item.created.toLocaleString()}</small>`
|
||||||
: html`-`}`,
|
: html`-`}`,
|
||||||
html`${item.lastUsed
|
html`${item.lastUsed
|
||||||
? html`<div>${getRelativeTime(item.lastUsed)}</div>
|
? html`<div>${formatElapsedTime(item.lastUsed)}</div>
|
||||||
<small>${item.lastUsed.toLocaleString()}</small>`
|
<small>${item.lastUsed.toLocaleString()}</small>`
|
||||||
: html`-`}`,
|
: html`-`}`,
|
||||||
html`
|
html`
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { dateTimeLocal } from "@goauthentik/common/utils";
|
import { dateTimeLocal } from "@goauthentik/common/temporal";
|
||||||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||||
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
|
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { intentToLabel } from "@goauthentik/common/labels";
|
import { intentToLabel } from "@goauthentik/common/labels";
|
||||||
|
import { formatElapsedTime } from "@goauthentik/common/temporal";
|
||||||
import { me } from "@goauthentik/common/users";
|
import { me } from "@goauthentik/common/users";
|
||||||
import { getRelativeTime } from "@goauthentik/common/utils";
|
|
||||||
import "@goauthentik/components/ak-status-label";
|
import "@goauthentik/components/ak-status-label";
|
||||||
import "@goauthentik/elements/buttons/Dropdown";
|
import "@goauthentik/elements/buttons/Dropdown";
|
||||||
import "@goauthentik/elements/buttons/ModalButton";
|
import "@goauthentik/elements/buttons/ModalButton";
|
||||||
@ -110,7 +110,7 @@ export class UserTokenList extends Table<Token> {
|
|||||||
position="top"
|
position="top"
|
||||||
.content=${item.expires?.toLocaleString()}
|
.content=${item.expires?.toLocaleString()}
|
||||||
>
|
>
|
||||||
${getRelativeTime(item.expires!)}
|
${formatElapsedTime(item.expires!)}
|
||||||
</pf-tooltip>`
|
</pf-tooltip>`
|
||||||
: msg("-")}
|
: msg("-")}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user