@pb33f/cowboy-components 0.7.6 → 0.7.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/auth/login-button.d.ts +5 -2
- package/dist/components/auth/login-button.js +38 -11
- package/dist/components/auth/login-panel.d.ts +2 -1
- package/dist/components/auth/login-panel.js +4 -3
- package/dist/components/auth/oauth-login.d.ts +1 -1
- package/dist/components/auth/oauth-login.js +3 -3
- package/dist/components/paginator/paginator.css.js +1 -1
- package/dist/components/paginator/paginator.d.ts +2 -0
- package/dist/components/paginator/paginator.js +6 -6
- package/dist/components/problems-overview/problems-overview.js +6 -0
- package/dist/components/the-doctor/sparks.d.ts +1 -0
- package/dist/components/the-doctor/sparks.js +36 -21
- package/dist/components/the-doctor/status-bar.css.js +10 -8
- package/dist/components/the-doctor/status-bar.d.ts +2 -0
- package/dist/components/the-doctor/status-bar.js +18 -8
- package/dist/components/the-doctor/the-doctor.d.ts +1 -0
- package/dist/components/the-doctor/the-doctor.js +9 -1
- package/dist/controllers/auth-controller.d.ts +2 -1
- package/dist/controllers/auth-controller.js +49 -20
- package/dist/controllers/diagnostic-controller.js +6 -2
- package/dist/controllers/docs-controller.js +9 -32
- package/dist/cowboy-components.umd.cjs +897 -896
- package/dist/css/pb33f-theme.css +1 -0
- package/dist/events/doctor.d.ts +2 -0
- package/dist/events/doctor.js +2 -0
- package/dist/style.css +1 -1
- package/package.json +1 -1
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import { LitElement } from "lit";
|
|
2
2
|
import { SlDialog } from "@shoelace-style/shoelace";
|
|
3
|
-
import { OAuthLogin } from "./oauth-login";
|
|
3
|
+
import { OAuthLogin } from "./oauth-login.js";
|
|
4
4
|
export declare class LoginButton extends LitElement {
|
|
5
5
|
static styles: import("lit").CSSResult[];
|
|
6
6
|
authDialog: SlDialog;
|
|
7
7
|
title: string;
|
|
8
8
|
buttonLabel: string;
|
|
9
9
|
redirectUrl: string;
|
|
10
|
+
textLink: boolean;
|
|
11
|
+
stateCheck: boolean;
|
|
10
12
|
oauthLogin: OAuthLogin;
|
|
11
13
|
private controller;
|
|
12
14
|
constructor();
|
|
15
|
+
protected firstUpdated(): void;
|
|
13
16
|
updated(): void;
|
|
14
|
-
render(): import("lit-html").TemplateResult<1
|
|
17
|
+
render(): import("lit-html").TemplateResult<1> | null;
|
|
15
18
|
anonView(): import("lit-html").TemplateResult<1>;
|
|
16
19
|
hide(): void;
|
|
17
20
|
authenticatedView(): import("lit-html").TemplateResult<1>;
|
|
@@ -6,12 +6,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
};
|
|
7
7
|
import { html, LitElement } from "lit";
|
|
8
8
|
import { customElement, property, query } from "lit/decorators.js";
|
|
9
|
-
import { AuthController } from "../../controllers/auth-controller";
|
|
10
|
-
import buttonCss from "../../css/button.css";
|
|
11
|
-
import modalCss from "../../css/modal.css";
|
|
12
|
-
import loginButtonCss from "./login-button.css";
|
|
13
|
-
import tooltipCss from "../../css/tooltip.css";
|
|
14
|
-
import { LogoutRequested } from "../../events/doctor";
|
|
9
|
+
import { AuthController } from "../../controllers/auth-controller.js";
|
|
10
|
+
import buttonCss from "../../css/button.css.js";
|
|
11
|
+
import modalCss from "../../css/modal.css.js";
|
|
12
|
+
import loginButtonCss from "./login-button.css.js";
|
|
13
|
+
import tooltipCss from "../../css/tooltip.css.js";
|
|
14
|
+
import { LogoutRequested } from "../../events/doctor.js";
|
|
15
|
+
import linksCss from "../../css/links.css.js";
|
|
15
16
|
let LoginButton = class LoginButton extends LitElement {
|
|
16
17
|
constructor() {
|
|
17
18
|
super();
|
|
@@ -19,6 +20,19 @@ let LoginButton = class LoginButton extends LitElement {
|
|
|
19
20
|
this.title = 'authenticate';
|
|
20
21
|
this.buttonLabel = 'Authenticate';
|
|
21
22
|
this.redirectUrl = '';
|
|
23
|
+
this.textLink = false;
|
|
24
|
+
this.stateCheck = false;
|
|
25
|
+
}
|
|
26
|
+
firstUpdated() {
|
|
27
|
+
if (this.stateCheck) {
|
|
28
|
+
this.controller.checkState().then(() => {
|
|
29
|
+
this.stateCheck = false;
|
|
30
|
+
this.requestUpdate();
|
|
31
|
+
}).finally(() => {
|
|
32
|
+
this.stateCheck = false;
|
|
33
|
+
this.requestUpdate();
|
|
34
|
+
});
|
|
35
|
+
}
|
|
22
36
|
}
|
|
23
37
|
updated() {
|
|
24
38
|
if (this.oauthLogin) {
|
|
@@ -26,6 +40,9 @@ let LoginButton = class LoginButton extends LitElement {
|
|
|
26
40
|
}
|
|
27
41
|
}
|
|
28
42
|
render() {
|
|
43
|
+
if (this.stateCheck) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
29
46
|
let out = this.anonView();
|
|
30
47
|
if (this.controller.authenticated) {
|
|
31
48
|
out = this.authenticatedView();
|
|
@@ -33,11 +50,15 @@ let LoginButton = class LoginButton extends LitElement {
|
|
|
33
50
|
return out;
|
|
34
51
|
}
|
|
35
52
|
anonView() {
|
|
53
|
+
let action = html ` <sl-button @click="${this.openAuthModal}">
|
|
54
|
+
<sl-icon name="key" slot="prefix" style="font-size: 1rem"></sl-icon>
|
|
55
|
+
${this.buttonLabel}
|
|
56
|
+
</sl-button>`;
|
|
57
|
+
if (this.textLink) {
|
|
58
|
+
action = html `<a href="#" @click="${this.openAuthModal}"><strong>${this.buttonLabel}</strong></a>`;
|
|
59
|
+
}
|
|
36
60
|
return html `
|
|
37
|
-
|
|
38
|
-
<sl-icon name="key" slot="prefix" style="font-size: 1rem"></sl-icon>
|
|
39
|
-
${this.buttonLabel}
|
|
40
|
-
</sl-button>
|
|
61
|
+
${action}
|
|
41
62
|
<sl-dialog id="auth-dialog" style="--width: 600px" no-header>
|
|
42
63
|
<div style="padding-top: 20px;">
|
|
43
64
|
<pb33f-oauth-login title="${this.title}"></pb33f-oauth-login>
|
|
@@ -84,7 +105,7 @@ let LoginButton = class LoginButton extends LitElement {
|
|
|
84
105
|
this.authDialog.show();
|
|
85
106
|
}
|
|
86
107
|
};
|
|
87
|
-
LoginButton.styles = [tooltipCss, buttonCss, modalCss, loginButtonCss];
|
|
108
|
+
LoginButton.styles = [tooltipCss, buttonCss, modalCss, loginButtonCss, linksCss];
|
|
88
109
|
__decorate([
|
|
89
110
|
query('#auth-dialog')
|
|
90
111
|
], LoginButton.prototype, "authDialog", void 0);
|
|
@@ -97,6 +118,12 @@ __decorate([
|
|
|
97
118
|
__decorate([
|
|
98
119
|
property()
|
|
99
120
|
], LoginButton.prototype, "redirectUrl", void 0);
|
|
121
|
+
__decorate([
|
|
122
|
+
property({ type: Boolean })
|
|
123
|
+
], LoginButton.prototype, "textLink", void 0);
|
|
124
|
+
__decorate([
|
|
125
|
+
property({ type: Boolean })
|
|
126
|
+
], LoginButton.prototype, "stateCheck", void 0);
|
|
100
127
|
__decorate([
|
|
101
128
|
query('pb33f-oauth-login')
|
|
102
129
|
], LoginButton.prototype, "oauthLogin", void 0);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { LitElement } from "lit";
|
|
2
|
+
import { AuthController } from "../../controllers/auth-controller.js";
|
|
2
3
|
export declare class LoginPanel extends LitElement {
|
|
3
4
|
static styles: import("lit").CSSResult[];
|
|
4
5
|
title: string;
|
|
5
6
|
redirect: string;
|
|
6
|
-
|
|
7
|
+
controller: AuthController;
|
|
7
8
|
constructor();
|
|
8
9
|
willUpdate(): void;
|
|
9
10
|
render(): import("lit-html").TemplateResult<1> | undefined;
|
|
@@ -6,12 +6,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
};
|
|
7
7
|
import { html, LitElement } from "lit";
|
|
8
8
|
import { customElement, property } from "lit/decorators.js";
|
|
9
|
-
import
|
|
10
|
-
import loginButtonCss from "./login-button.css";
|
|
9
|
+
import loginButtonCss from "./login-button.css.js";
|
|
11
10
|
let LoginPanel = class LoginPanel extends LitElement {
|
|
12
11
|
constructor() {
|
|
13
12
|
super();
|
|
14
|
-
this.controller = new AuthController(this);
|
|
15
13
|
this.title = 'authenticate';
|
|
16
14
|
this.redirect = '/';
|
|
17
15
|
}
|
|
@@ -40,6 +38,9 @@ __decorate([
|
|
|
40
38
|
__decorate([
|
|
41
39
|
property()
|
|
42
40
|
], LoginPanel.prototype, "redirect", void 0);
|
|
41
|
+
__decorate([
|
|
42
|
+
property()
|
|
43
|
+
], LoginPanel.prototype, "controller", void 0);
|
|
43
44
|
LoginPanel = __decorate([
|
|
44
45
|
customElement('pb33f-login-panel')
|
|
45
46
|
], LoginPanel);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LitElement } from "lit";
|
|
2
2
|
import '../electric-box/electric-box.js';
|
|
3
3
|
import { SlAnimation, SlButton } from "@shoelace-style/shoelace";
|
|
4
|
-
import { ElectricBox } from "../electric-box/electric-box";
|
|
4
|
+
import { ElectricBox } from "../electric-box/electric-box.js";
|
|
5
5
|
export declare class OAuthLogin extends LitElement {
|
|
6
6
|
static styles: import("lit").CSSResult[];
|
|
7
7
|
title: string;
|
|
@@ -6,10 +6,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
};
|
|
7
7
|
import { html, LitElement } from "lit";
|
|
8
8
|
import { customElement, property, query, state } from "lit/decorators.js";
|
|
9
|
-
import oauthLoginCss from "./oauth-login.css";
|
|
10
|
-
import buttonCss from "../../css/button.css";
|
|
9
|
+
import oauthLoginCss from "./oauth-login.css.js";
|
|
10
|
+
import buttonCss from "../../css/button.css.js";
|
|
11
11
|
import '../electric-box/electric-box.js';
|
|
12
|
-
import { AuthenticationGithubRequested } from "../../events/doctor";
|
|
12
|
+
import { AuthenticationGithubRequested } from "../../events/doctor.js";
|
|
13
13
|
let OAuthLogin = class OAuthLogin extends LitElement {
|
|
14
14
|
constructor() {
|
|
15
15
|
super();
|
|
@@ -83,15 +83,15 @@ let Paginator = class Paginator extends LitElement {
|
|
|
83
83
|
}
|
|
84
84
|
this.renderValues = this.values?.slice(this.paginatorNavigator.getRangeStart(), this.paginatorNavigator.getRangeEnd());
|
|
85
85
|
}
|
|
86
|
+
startSparks() {
|
|
87
|
+
this.sparks.startAnimation();
|
|
88
|
+
}
|
|
89
|
+
stopSparks() {
|
|
90
|
+
this.sparks.stopAnimation();
|
|
91
|
+
}
|
|
86
92
|
render() {
|
|
87
93
|
this.sparks.isError = this.invalid;
|
|
88
|
-
if (this.sparks.animating) {
|
|
89
|
-
this.sparks.stopAnimation();
|
|
90
|
-
}
|
|
91
94
|
if (this.renderValues?.length === 0 || !this.renderValues) {
|
|
92
|
-
if (!this.sparks.animating) {
|
|
93
|
-
this.sparks.startAnimation();
|
|
94
|
-
}
|
|
95
95
|
if (!this.hideSparks) {
|
|
96
96
|
return html `
|
|
97
97
|
<div class="no-values ${this.invalid ? 'error' : ''}" style="position: relative">
|
|
@@ -73,6 +73,12 @@ let ProblemsOverview = class ProblemsOverview extends LitElement {
|
|
|
73
73
|
this.problemOverviewGroups = this.buildProblemOverviewGroups(value);
|
|
74
74
|
this.paginator.values = this.problemOverviewGroups;
|
|
75
75
|
this.paginator.itemsPerPage = 10;
|
|
76
|
+
if (this.problemList.length <= 0) {
|
|
77
|
+
this.paginator.startSparks();
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
this.paginator.stopSparks();
|
|
81
|
+
}
|
|
76
82
|
}
|
|
77
83
|
render() {
|
|
78
84
|
if (this.unavailable) {
|
|
@@ -9,9 +9,10 @@ import { css, html, LitElement } from "lit";
|
|
|
9
9
|
let PixelSparks = class PixelSparks extends LitElement {
|
|
10
10
|
constructor() {
|
|
11
11
|
super();
|
|
12
|
+
this.animationFrameId = null;
|
|
12
13
|
this.sparkArray = [];
|
|
13
|
-
this.gravity = 0.
|
|
14
|
-
this.spawnRate =
|
|
14
|
+
this.gravity = 0.005;
|
|
15
|
+
this.spawnRate = 50;
|
|
15
16
|
this.isError = false;
|
|
16
17
|
this.animating = false;
|
|
17
18
|
}
|
|
@@ -26,39 +27,52 @@ let PixelSparks = class PixelSparks extends LitElement {
|
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
startAnimation() {
|
|
30
|
+
// Only start if not already animating
|
|
29
31
|
if (!this.animating) {
|
|
30
32
|
this.animationTimer = setInterval(() => this.spawnSpark(), 1000 / this.spawnRate);
|
|
31
|
-
this.animateSparks();
|
|
32
33
|
this.animating = true;
|
|
34
|
+
this.animateSparks();
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
stopAnimation() {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
this.animating = false;
|
|
39
|
+
clearInterval(this.animationTimer);
|
|
40
|
+
// Cancel any pending animation frame
|
|
41
|
+
if (this.animationFrameId !== null) {
|
|
42
|
+
cancelAnimationFrame(this.animationFrameId);
|
|
43
|
+
this.animationFrameId = null;
|
|
44
|
+
}
|
|
45
|
+
this.sparkArray = [];
|
|
46
|
+
// Clear the canvas one last time
|
|
47
|
+
if (this.ctx && this.canvas) {
|
|
48
|
+
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
39
49
|
}
|
|
40
50
|
}
|
|
41
51
|
getRandomBetween(min, max) {
|
|
42
52
|
return Math.random() * (max - min) + min;
|
|
43
53
|
}
|
|
44
54
|
spawnSpark() {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
55
|
+
if (this.animating) {
|
|
56
|
+
let color = Math.random() > 0.5 ? 'rgb(248, 58, 255)' : 'rgb(98, 196, 255)';
|
|
57
|
+
if (this.isError) {
|
|
58
|
+
// create a color between
|
|
59
|
+
color = Math.random() > 0.5 ? 'rgb(255, 60, 116)' : 'rgb(157, 26, 65)';
|
|
60
|
+
}
|
|
61
|
+
this.sparkArray.push({
|
|
62
|
+
x: Math.random() * this.canvas.width,
|
|
63
|
+
y: -2,
|
|
64
|
+
size: 1,
|
|
65
|
+
color: color,
|
|
66
|
+
velocityY: this.getRandomBetween(0.05, 0.3),
|
|
67
|
+
lifetime: 150,
|
|
68
|
+
initialLifetime: 150,
|
|
69
|
+
opacity: 1
|
|
70
|
+
});
|
|
49
71
|
}
|
|
50
|
-
this.sparkArray.push({
|
|
51
|
-
x: Math.random() * this.canvas.width,
|
|
52
|
-
y: -2,
|
|
53
|
-
size: 1,
|
|
54
|
-
color: color,
|
|
55
|
-
velocityY: this.getRandomBetween(0.05, 0.3),
|
|
56
|
-
lifetime: 300,
|
|
57
|
-
initialLifetime: 300,
|
|
58
|
-
opacity: 1
|
|
59
|
-
});
|
|
60
72
|
}
|
|
61
73
|
animateSparks() {
|
|
74
|
+
if (!this.animating)
|
|
75
|
+
return;
|
|
62
76
|
this.ctx?.clearRect(0, 0, this.canvas?.width, this.canvas?.height);
|
|
63
77
|
this.sparkArray = this.sparkArray.filter(spark => spark.lifetime > 0);
|
|
64
78
|
for (let spark of this.sparkArray) {
|
|
@@ -68,7 +82,8 @@ let PixelSparks = class PixelSparks extends LitElement {
|
|
|
68
82
|
spark.lifetime--;
|
|
69
83
|
spark.opacity = spark.lifetime / spark.initialLifetime;
|
|
70
84
|
}
|
|
71
|
-
|
|
85
|
+
// Store the ID so we can cancel it later
|
|
86
|
+
this.animationFrameId = requestAnimationFrame(() => this.animateSparks());
|
|
72
87
|
}
|
|
73
88
|
drawSpark(spark) {
|
|
74
89
|
this.ctx.globalAlpha = spark.opacity; // Set transparency level
|
|
@@ -4,14 +4,14 @@ export default css `
|
|
|
4
4
|
position: absolute;
|
|
5
5
|
bottom: 8px;
|
|
6
6
|
left: 0;
|
|
7
|
-
width: 100
|
|
8
|
-
height:
|
|
7
|
+
width: calc(100% - 6px);
|
|
8
|
+
height: 22px;
|
|
9
9
|
background: var(--background-color);
|
|
10
|
-
border: 1px dashed var(--secondary-color);
|
|
10
|
+
border-top: 1px dashed var(--secondary-color);
|
|
11
11
|
z-index: 100;
|
|
12
12
|
border-bottom: none;
|
|
13
|
-
font-size: 0.
|
|
14
|
-
padding: 4px 0
|
|
13
|
+
font-size: 0.9rem;
|
|
14
|
+
padding: 4px 0 2px 5px;
|
|
15
15
|
vertical-align: middle;
|
|
16
16
|
|
|
17
17
|
}
|
|
@@ -27,18 +27,20 @@ export default css `
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
.error-icon {
|
|
30
|
-
color: var(--
|
|
30
|
+
color: var(--font-color);
|
|
31
31
|
vertical-align: middle;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
.warning {
|
|
35
|
-
border: 1px dashed var(--warn-color);
|
|
35
|
+
border-top: 1px dashed var(--warn-color);
|
|
36
36
|
border-bottom: none;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
.error {
|
|
40
|
-
border: 1px
|
|
40
|
+
border-top: 1px solid var(--error-color);
|
|
41
|
+
background-color: var(--error-color-dimmed);
|
|
41
42
|
border-bottom: none;
|
|
43
|
+
color: var(--font-color)
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
strong {
|
|
@@ -4,9 +4,11 @@ export declare class StatusBar extends LitElement {
|
|
|
4
4
|
static styles: import("lit").CSSResult[];
|
|
5
5
|
visible: boolean;
|
|
6
6
|
callsRemaining: number;
|
|
7
|
+
authenticated: boolean;
|
|
7
8
|
dialog: SlDialog;
|
|
8
9
|
constructor();
|
|
9
10
|
openDialog(): void;
|
|
10
11
|
closeDialog(): void;
|
|
12
|
+
authenticate(): void;
|
|
11
13
|
render(): import("lit-html").TemplateResult<1> | undefined;
|
|
12
14
|
}
|
|
@@ -9,11 +9,14 @@ import { html, LitElement } from "lit";
|
|
|
9
9
|
import buttonCss from "../../css/button.css.js";
|
|
10
10
|
import statusBarCss from "./status-bar.css.js";
|
|
11
11
|
import linksCss from "../../css/links.css.js";
|
|
12
|
+
import dialogCss from "../../css/dialog.css.js";
|
|
13
|
+
import { OpenAuthentication } from "../../events/doctor.js";
|
|
12
14
|
let StatusBar = class StatusBar extends LitElement {
|
|
13
15
|
constructor() {
|
|
14
16
|
super();
|
|
15
17
|
this.visible = false;
|
|
16
18
|
this.callsRemaining = 0;
|
|
19
|
+
this.authenticated = false;
|
|
17
20
|
}
|
|
18
21
|
openDialog() {
|
|
19
22
|
this.dialog.show();
|
|
@@ -21,6 +24,11 @@ let StatusBar = class StatusBar extends LitElement {
|
|
|
21
24
|
closeDialog() {
|
|
22
25
|
this.dialog.hide();
|
|
23
26
|
}
|
|
27
|
+
authenticate() {
|
|
28
|
+
this.dispatchEvent(new Event(OpenAuthentication, {
|
|
29
|
+
bubbles: true
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
24
32
|
render() {
|
|
25
33
|
if (this.visible) {
|
|
26
34
|
let clazz = '';
|
|
@@ -41,28 +49,30 @@ let StatusBar = class StatusBar extends LitElement {
|
|
|
41
49
|
}
|
|
42
50
|
return html `
|
|
43
51
|
<div class="status-bar ${clazz}">
|
|
44
|
-
<sl-dialog label="Credit
|
|
45
|
-
<p>
|
|
46
|
-
<p>
|
|
47
|
-
In the meantime please wait 24 hours for your credit to be reset.
|
|
52
|
+
<sl-dialog label="Purchase Credit" class="dialog-overview">
|
|
53
|
+
<p>Still working on this, coming soon! Come back tomorrow for more free credit.
|
|
48
54
|
</p>
|
|
49
55
|
<sl-button slot="footer" variant="primary" @click="${this.closeDialog}">Close</sl-button>
|
|
50
56
|
</sl-dialog>
|
|
51
57
|
<sl-icon name="${icon}" class="${clazzIcon}"></sl-icon>
|
|
52
|
-
<span class="status-text">Credits remaining:
|
|
53
|
-
<span class="action-text">${actionText}</span>
|
|
54
|
-
${this.callsRemaining <= 0 ? html
|
|
58
|
+
<span class="status-text"><strong>Credits remaining: ${this.callsRemaining}</strong></span> |
|
|
59
|
+
<span class="action-text"><strong>${actionText}</strong></span>
|
|
60
|
+
${this.callsRemaining <= 0 && !this.authenticated ? html `| <pb33f-login-button title="Get More Credit" buttonLabel="Authenticate for more credit" textLink></pb33f-login-button>` : ''}
|
|
61
|
+
${this.callsRemaining <= 0 && this.authenticated ? html `| <a href="#" @click="${this.openDialog}"><strong>Purchase Credit</strong></a>` : ''}
|
|
55
62
|
</div>`;
|
|
56
63
|
}
|
|
57
64
|
}
|
|
58
65
|
};
|
|
59
|
-
StatusBar.styles = [statusBarCss, linksCss, buttonCss];
|
|
66
|
+
StatusBar.styles = [statusBarCss, linksCss, buttonCss, dialogCss];
|
|
60
67
|
__decorate([
|
|
61
68
|
property({ type: Boolean })
|
|
62
69
|
], StatusBar.prototype, "visible", void 0);
|
|
63
70
|
__decorate([
|
|
64
71
|
property({ type: Number })
|
|
65
72
|
], StatusBar.prototype, "callsRemaining", void 0);
|
|
73
|
+
__decorate([
|
|
74
|
+
property({ type: Boolean })
|
|
75
|
+
], StatusBar.prototype, "authenticated", void 0);
|
|
66
76
|
__decorate([
|
|
67
77
|
query('sl-dialog')
|
|
68
78
|
], StatusBar.prototype, "dialog", void 0);
|
|
@@ -222,6 +222,7 @@ export declare class TheDoctor extends LitElement {
|
|
|
222
222
|
updateExplorerDivider(): void;
|
|
223
223
|
updateRolodexDivider(): void;
|
|
224
224
|
updateRefmapBag(currentPath: string | undefined, result: Reference[]): void;
|
|
225
|
+
creditEmpty(e: CustomEvent): void;
|
|
225
226
|
platformUnavailable(error: PlatformError | null): void;
|
|
226
227
|
builtInRulesetSelected(): void;
|
|
227
228
|
runDiagnostics(): void;
|
|
@@ -16,7 +16,7 @@ import '@shoelace-style/shoelace/dist/components/avatar/avatar.js';
|
|
|
16
16
|
import { customElement, property, query, state } from "lit/decorators.js";
|
|
17
17
|
import { html, LitElement } from "lit";
|
|
18
18
|
import { SpecEditor } from "../editor/editor.js";
|
|
19
|
-
import { ActiveView, AddToast, ArchiveURLRequested, BuiltInRulesetChanged, CustomRulesetEnabled, DocumentReferenceClicked, EditorClicked, EditorUpdated, ExplorerEqualizerChanged, ExplorerEqualizerFiltered, ExplorerNodeClicked, ExportRuleset, LoadRenderedNodeIntoInspector, ModelTreeNodeClicked, NodeReferenceClicked, NukeWorkspaceEvent, OpenProblemDrawer, OpenSettings, ProblemClicked, RolodexRootFileSelected, RolodexTreeNodeClicked, RuleClicked, RulesetSaved, RuleViolationClicked, StartSessionFailed, } from "../../events/doctor.js";
|
|
19
|
+
import { ActiveView, AddToast, ArchiveURLRequested, BuiltInRulesetChanged, CreditEmpty, CustomRulesetEnabled, DocumentReferenceClicked, EditorClicked, EditorUpdated, ExplorerEqualizerChanged, ExplorerEqualizerFiltered, ExplorerNodeClicked, ExportRuleset, LoadRenderedNodeIntoInspector, ModelTreeNodeClicked, NodeReferenceClicked, NukeWorkspaceEvent, OpenProblemDrawer, OpenSettings, ProblemClicked, RolodexRootFileSelected, RolodexTreeNodeClicked, RuleClicked, RulesetSaved, RuleViolationClicked, StartSessionFailed, } from "../../events/doctor.js";
|
|
20
20
|
import { ProblemDetailsDrawer } from "../problem-list/details-drawer.js";
|
|
21
21
|
import { CreateBagManager } from "@pb33f/saddlebag";
|
|
22
22
|
import { LintingService } from "../../services/linting-service.js";
|
|
@@ -200,6 +200,7 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
200
200
|
};
|
|
201
201
|
// create auth controller
|
|
202
202
|
this.authController = new AuthController(this, sessionCallback, true);
|
|
203
|
+
this.authController.start();
|
|
203
204
|
// listen for auth state changes.
|
|
204
205
|
//@ts-ignore
|
|
205
206
|
this.addEventListener(EditorUpdated, this.specController.specChanged.bind(this.specController));
|
|
@@ -248,6 +249,8 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
248
249
|
// @ts-ignore
|
|
249
250
|
this.authController.addEventListener(StartSessionFailed, this.platformUnavailable.bind(this));
|
|
250
251
|
this.timeVortex.historyPicker.addEventListener(OpenSettings, this.openSettings.bind(this));
|
|
252
|
+
// @ts-ignore
|
|
253
|
+
this.authController.addEventListener(CreditEmpty, this.creditEmpty.bind(this));
|
|
251
254
|
//@ts-ignore
|
|
252
255
|
this.addEventListener(LoadRenderedNodeIntoInspector, this.loadRenderedNodeIntoInspector.bind(this));
|
|
253
256
|
// hijack navigation buttons.
|
|
@@ -398,6 +401,9 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
398
401
|
}
|
|
399
402
|
this.referenceMapBag?.set(ReferenceMapBag, refMap);
|
|
400
403
|
}
|
|
404
|
+
creditEmpty(e) {
|
|
405
|
+
this.platformUnavailable(e.detail.error);
|
|
406
|
+
}
|
|
401
407
|
platformUnavailable(error) {
|
|
402
408
|
if (!this.unavailable) {
|
|
403
409
|
this.loadingOverlay?.hide();
|
|
@@ -436,6 +442,7 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
436
442
|
this.diagnosticController.lintSpec('', urlParam);
|
|
437
443
|
return;
|
|
438
444
|
}
|
|
445
|
+
// todo: this needs work man. I want to see all these settimeouts gone brother.
|
|
439
446
|
setTimeout(() => {
|
|
440
447
|
// check for a history
|
|
441
448
|
this.timeVortex.doctor = this;
|
|
@@ -694,6 +701,7 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
694
701
|
${modelTree}
|
|
695
702
|
`;
|
|
696
703
|
if (this.authController.state && this.authController.state.authenticated) {
|
|
704
|
+
this.statusBar.authenticated = true;
|
|
697
705
|
}
|
|
698
706
|
return html `
|
|
699
707
|
${this.uploadArchive}
|
|
@@ -14,12 +14,13 @@ export declare class AuthController extends EventTarget {
|
|
|
14
14
|
brokerStarted: boolean;
|
|
15
15
|
hosts: any[];
|
|
16
16
|
callbackIdx: number;
|
|
17
|
+
checkingState: boolean;
|
|
17
18
|
constructor(host: any, sessionCallback?: Function, autoStart?: boolean);
|
|
18
19
|
start(): void;
|
|
19
20
|
private startSession;
|
|
20
21
|
associateBroker(brokerId: string): Promise<boolean>;
|
|
21
22
|
authGithub(e: CustomEvent<AuthenticationMeta>): void;
|
|
22
|
-
logout(
|
|
23
|
+
logout(): void;
|
|
23
24
|
private notifyStateChange;
|
|
24
25
|
checkState(): Promise<AuthenticationState>;
|
|
25
26
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AuthenticationGithubRequested, AuthenticationStateChange, LogoutRequested, NukeWorkspaceEvent, StartSessionFailed } from "../events/doctor.js";
|
|
1
|
+
import { AuthenticationGithubRequested, AuthenticationStateChange, CreditEmpty, LogoutRequested, NukeWorkspaceEvent, StartSessionFailed } from "../events/doctor.js";
|
|
2
2
|
import { AuthService } from "../services/auth-service.js";
|
|
3
|
-
import { HeaderService } from "../services/header-service";
|
|
3
|
+
import { HeaderService } from "../services/header-service.js";
|
|
4
4
|
export class AuthController extends EventTarget {
|
|
5
5
|
static getInstance() {
|
|
6
6
|
const t = AuthController._instance;
|
|
@@ -20,9 +20,10 @@ export class AuthController extends EventTarget {
|
|
|
20
20
|
}
|
|
21
21
|
t.startSessionAutomatically = autoStart;
|
|
22
22
|
t.brokerStarted = false;
|
|
23
|
-
t.start()
|
|
23
|
+
// t.start()
|
|
24
24
|
return t;
|
|
25
25
|
}
|
|
26
|
+
this.checkingState = false;
|
|
26
27
|
this.doctorEndpoint = 'https://doctor.pb33f.io';
|
|
27
28
|
const sessionEndpoint = sessionStorage.getItem("doctor-endpoint");
|
|
28
29
|
if (sessionEndpoint) {
|
|
@@ -56,8 +57,19 @@ export class AuthController extends EventTarget {
|
|
|
56
57
|
this.sessionCallback.call(this.hosts[this.callbackIdx], session);
|
|
57
58
|
this.hosts[this.callbackIdx].requestUpdate();
|
|
58
59
|
}
|
|
59
|
-
}).catch((
|
|
60
|
-
|
|
60
|
+
}).catch((e) => {
|
|
61
|
+
// determine if this is an API failure, or a credit issue.
|
|
62
|
+
if (e.instance == 'https://pb33f.io/errors/no-credit-remaining') {
|
|
63
|
+
this.dispatchEvent(new CustomEvent(CreditEmpty, {
|
|
64
|
+
bubbles: true,
|
|
65
|
+
composed: true,
|
|
66
|
+
detail: {
|
|
67
|
+
error: e
|
|
68
|
+
}
|
|
69
|
+
}));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
console.error("something went wrong with starting session", e);
|
|
61
73
|
this.dispatchEvent(new Event(StartSessionFailed));
|
|
62
74
|
});
|
|
63
75
|
};
|
|
@@ -89,7 +101,7 @@ export class AuthController extends EventTarget {
|
|
|
89
101
|
});
|
|
90
102
|
const session = await sessionJSON.json();
|
|
91
103
|
if (session.type && session.title && session.status) {
|
|
92
|
-
reject();
|
|
104
|
+
reject(session);
|
|
93
105
|
}
|
|
94
106
|
resolve(session);
|
|
95
107
|
}
|
|
@@ -125,30 +137,47 @@ export class AuthController extends EventTarget {
|
|
|
125
137
|
window.location.href = this.doctorEndpoint + '/auth/github/start';
|
|
126
138
|
}
|
|
127
139
|
}
|
|
128
|
-
logout(
|
|
140
|
+
logout() {
|
|
129
141
|
AuthService.logout().then(() => {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}));
|
|
138
|
-
}
|
|
142
|
+
this.dispatchEvent(new CustomEvent(NukeWorkspaceEvent, {
|
|
143
|
+
bubbles: true,
|
|
144
|
+
composed: true,
|
|
145
|
+
detail: {
|
|
146
|
+
resetFiles: true
|
|
147
|
+
}
|
|
148
|
+
}));
|
|
139
149
|
});
|
|
140
150
|
}
|
|
141
151
|
notifyStateChange(state) {
|
|
152
|
+
this.checkingState = false;
|
|
142
153
|
const event = new CustomEvent(AuthenticationStateChange, {
|
|
143
154
|
detail: { state }
|
|
144
155
|
});
|
|
145
156
|
this.dispatchEvent(event);
|
|
146
157
|
}
|
|
147
158
|
async checkState() {
|
|
148
|
-
|
|
149
|
-
this.
|
|
150
|
-
return
|
|
151
|
-
|
|
159
|
+
if (!this.checkingState) {
|
|
160
|
+
this.checkingState = true;
|
|
161
|
+
return AuthService.checkAuth()
|
|
162
|
+
.then(state => {
|
|
163
|
+
this.state = state;
|
|
164
|
+
this.authenticated = true;
|
|
165
|
+
this.notifyStateChange(state);
|
|
166
|
+
return state;
|
|
167
|
+
})
|
|
168
|
+
.catch(error => {
|
|
169
|
+
this.notifyStateChange();
|
|
170
|
+
this.checkingState = false;
|
|
171
|
+
throw error;
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
return new Promise((resolve) => {
|
|
176
|
+
this.addEventListener(AuthenticationStateChange, ((event) => {
|
|
177
|
+
resolve(event.detail.state);
|
|
178
|
+
}), { once: true });
|
|
179
|
+
});
|
|
180
|
+
}
|
|
152
181
|
}
|
|
153
182
|
}
|
|
154
183
|
AuthController._instance = null;
|