@pb33f/cowboy-components 0.7.7 → 0.7.9
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 +4 -2
- package/dist/components/auth/login-button.js +25 -7
- package/dist/components/auth/login-panel.d.ts +1 -1
- package/dist/components/auth/login-panel.js +1 -1
- package/dist/components/auth/oauth-login.d.ts +1 -1
- package/dist/components/auth/oauth-login.js +3 -3
- package/dist/components/the-doctor/status-bar.js +3 -3
- package/dist/components/the-doctor/the-doctor.css.js +16 -0
- package/dist/components/the-doctor/the-doctor.d.ts +3 -0
- package/dist/components/the-doctor/the-doctor.js +50 -3
- package/dist/components/time-vortex/tardis-control.css.js +0 -16
- package/dist/components/workspaces/workspace-destroy-dialog.d.ts +17 -0
- package/dist/components/workspaces/workspace-destroy-dialog.js +85 -0
- package/dist/components/workspaces/workspace-form.d.ts +22 -0
- package/dist/components/workspaces/workspace-form.js +194 -0
- package/dist/components/workspaces/workspace-view.css.d.ts +2 -0
- package/dist/components/workspaces/workspace-view.css.js +40 -0
- package/dist/components/workspaces/workspace-view.d.ts +30 -0
- package/dist/components/workspaces/workspace-view.js +196 -0
- package/dist/controllers/auth-controller.d.ts +1 -0
- package/dist/controllers/auth-controller.js +26 -8
- package/dist/controllers/diagnostic-controller.d.ts +1 -0
- package/dist/controllers/diagnostic-controller.js +15 -10
- package/dist/controllers/docs-controller.js +9 -33
- package/dist/controllers/workspace-controller.d.ts +15 -0
- package/dist/controllers/workspace-controller.js +156 -0
- package/dist/cowboy-components.umd.cjs +1559 -1095
- package/dist/css/badges.css.d.ts +2 -0
- package/dist/css/badges.css.js +12 -0
- package/dist/css/button.css.js +1 -1
- package/dist/css/forms.css.js +127 -1
- package/dist/css/lists.css.js +8 -0
- package/dist/css/pb33f-theme.css +1 -0
- package/dist/css/spinner.css.js +29 -0
- package/dist/events/doctor.d.ts +15 -0
- package/dist/events/doctor.js +10 -0
- package/dist/model/form-types.d.ts +32 -0
- package/dist/model/form-types.js +19 -0
- package/dist/model/formable.d.ts +51 -0
- package/dist/model/formable.js +542 -0
- package/dist/model/workspace.d.ts +6 -0
- package/dist/model/workspace.js +1 -0
- package/dist/monacoeditorwork/yaml.worker..bundle.js +14801 -14800
- package/dist/services/workspace-service.d.ts +10 -0
- package/dist/services/workspace-service.js +132 -0
- package/dist/style.css +1 -1
- package/package.json +7 -2
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { html } from "lit";
|
|
8
|
+
import { customElement, state, query, property } from "lit/decorators.js";
|
|
9
|
+
import { Formable } from "../../model/formable.js";
|
|
10
|
+
import { RenderType } from "../../model/form-types.js";
|
|
11
|
+
import { FormDirtyEvent, FormSubmitComplete, CreateWorkspace, UpdateWorkspace } from "../../events/doctor.js";
|
|
12
|
+
import dialogCss from "../../css/dialog.css.js";
|
|
13
|
+
let WorkspaceForm = class WorkspaceForm extends Formable {
|
|
14
|
+
constructor() {
|
|
15
|
+
super();
|
|
16
|
+
this.isEditMode = false;
|
|
17
|
+
this.open = false;
|
|
18
|
+
this.autoFocus = true; // Enable autofocus for workspace form
|
|
19
|
+
this.workspaceModel = {
|
|
20
|
+
name: '',
|
|
21
|
+
active: false
|
|
22
|
+
};
|
|
23
|
+
this.model = this.workspaceModel;
|
|
24
|
+
// Set up hints including hidden field for ID
|
|
25
|
+
this.setHints([
|
|
26
|
+
{
|
|
27
|
+
key: 'name',
|
|
28
|
+
renderType: RenderType.Text,
|
|
29
|
+
placeholder: 'workspace name',
|
|
30
|
+
helpText: 'Choose a unique name for your workspace',
|
|
31
|
+
required: true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
key: 'workspaceId',
|
|
35
|
+
renderType: RenderType.Hidden
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
key: 'active',
|
|
39
|
+
renderType: RenderType.Ignored
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
key: 'default',
|
|
43
|
+
renderType: RenderType.Ignored
|
|
44
|
+
}
|
|
45
|
+
]);
|
|
46
|
+
this.addEventListener(FormDirtyEvent, this.handleFormDirty.bind(this));
|
|
47
|
+
// Set up form submission callback for Enter key handling
|
|
48
|
+
this.onFormSubmit = this.handleSubmit.bind(this);
|
|
49
|
+
}
|
|
50
|
+
handleFormDirty(_) {
|
|
51
|
+
// do nothing
|
|
52
|
+
}
|
|
53
|
+
setEditMode(workspace) {
|
|
54
|
+
this.isEditMode = true;
|
|
55
|
+
this.wipeModel(workspace);
|
|
56
|
+
this.workspaceModel = { ...workspace };
|
|
57
|
+
this.model = this.workspaceModel;
|
|
58
|
+
}
|
|
59
|
+
setCreateMode() {
|
|
60
|
+
this.isEditMode = false;
|
|
61
|
+
this.wipeModel({
|
|
62
|
+
name: '',
|
|
63
|
+
active: false
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
close() {
|
|
67
|
+
this.setCreateMode();
|
|
68
|
+
this.open = false;
|
|
69
|
+
}
|
|
70
|
+
completed(ws) {
|
|
71
|
+
this.dispatchEvent(new CustomEvent(FormSubmitComplete, {
|
|
72
|
+
bubbles: true,
|
|
73
|
+
composed: true,
|
|
74
|
+
detail: ws
|
|
75
|
+
}));
|
|
76
|
+
this.close();
|
|
77
|
+
}
|
|
78
|
+
async handleSubmit() {
|
|
79
|
+
const formData = this.renderForm();
|
|
80
|
+
// Clear any previous errors
|
|
81
|
+
this.clearErrors();
|
|
82
|
+
this.clearTopError();
|
|
83
|
+
// Validation example
|
|
84
|
+
if (!formData.name || formData.name.trim() === '') {
|
|
85
|
+
// Show field-specific error
|
|
86
|
+
this.renderErrors([{
|
|
87
|
+
key: 'name',
|
|
88
|
+
message: 'A name is required'
|
|
89
|
+
}]);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (this.isEditMode) {
|
|
93
|
+
this.setLoading('Updating workspace...');
|
|
94
|
+
this.dispatchEvent(new CustomEvent(UpdateWorkspace, {
|
|
95
|
+
bubbles: true,
|
|
96
|
+
composed: true,
|
|
97
|
+
detail: formData
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
this.setLoading('Creating workspace...');
|
|
102
|
+
this.dispatchEvent(new CustomEvent(CreateWorkspace, {
|
|
103
|
+
bubbles: true,
|
|
104
|
+
composed: true,
|
|
105
|
+
detail: formData.name
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
handleError(err) {
|
|
110
|
+
this.notLoading();
|
|
111
|
+
switch (err.status) {
|
|
112
|
+
case 400:
|
|
113
|
+
case 401:
|
|
114
|
+
this.setTopError({
|
|
115
|
+
key: 'server',
|
|
116
|
+
message: err.detail,
|
|
117
|
+
});
|
|
118
|
+
break;
|
|
119
|
+
case 402:
|
|
120
|
+
this.setTopError({
|
|
121
|
+
key: 'server',
|
|
122
|
+
message: "You don't have enough credit! A new workspace costs five credits.",
|
|
123
|
+
});
|
|
124
|
+
this.renderErrors([{
|
|
125
|
+
key: 'name',
|
|
126
|
+
message: 'More credit required.'
|
|
127
|
+
}]);
|
|
128
|
+
break;
|
|
129
|
+
case 403:
|
|
130
|
+
this.setTopError({
|
|
131
|
+
key: 'server',
|
|
132
|
+
message: err.detail,
|
|
133
|
+
});
|
|
134
|
+
this.renderErrors([{
|
|
135
|
+
key: 'name',
|
|
136
|
+
message: 'All maxed out, delete a workspace before creating new ones.'
|
|
137
|
+
}]);
|
|
138
|
+
break;
|
|
139
|
+
case 409:
|
|
140
|
+
this.setTopError({
|
|
141
|
+
key: 'server',
|
|
142
|
+
message: err.detail
|
|
143
|
+
});
|
|
144
|
+
this.renderErrors([{
|
|
145
|
+
key: 'name',
|
|
146
|
+
message: "There is a conflict",
|
|
147
|
+
}]);
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
handleSuccess(workspace) {
|
|
152
|
+
this.notLoading();
|
|
153
|
+
this.completed(workspace);
|
|
154
|
+
}
|
|
155
|
+
render() {
|
|
156
|
+
const dialogLabel = this.isEditMode ? 'Edit workspace' : 'Create workspace';
|
|
157
|
+
const submitButtonText = this.isEditMode ? 'Update' : 'Create';
|
|
158
|
+
return html `
|
|
159
|
+
<sl-dialog .open=${this.open}
|
|
160
|
+
@sl-hide="${() => {
|
|
161
|
+
this.close();
|
|
162
|
+
}}"
|
|
163
|
+
label="${dialogLabel}">
|
|
164
|
+
|
|
165
|
+
${this.renderModel()}
|
|
166
|
+
|
|
167
|
+
<section class="form-controls">
|
|
168
|
+
${this.renderCancelButton(() => this.close())}
|
|
169
|
+
${this.renderActionButton(submitButtonText, this.handleSubmit)}
|
|
170
|
+
</section>
|
|
171
|
+
</sl-dialog>
|
|
172
|
+
`;
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
WorkspaceForm.styles = [...Formable.styles, dialogCss];
|
|
176
|
+
__decorate([
|
|
177
|
+
query('sl-dialog')
|
|
178
|
+
], WorkspaceForm.prototype, "workspaceDialog", void 0);
|
|
179
|
+
__decorate([
|
|
180
|
+
state()
|
|
181
|
+
], WorkspaceForm.prototype, "active", void 0);
|
|
182
|
+
__decorate([
|
|
183
|
+
state()
|
|
184
|
+
], WorkspaceForm.prototype, "open", void 0);
|
|
185
|
+
__decorate([
|
|
186
|
+
property({ type: Object })
|
|
187
|
+
], WorkspaceForm.prototype, "workspaceModel", void 0);
|
|
188
|
+
__decorate([
|
|
189
|
+
state()
|
|
190
|
+
], WorkspaceForm.prototype, "isEditMode", void 0);
|
|
191
|
+
WorkspaceForm = __decorate([
|
|
192
|
+
customElement("pb33f-doctor-workspace-form")
|
|
193
|
+
], WorkspaceForm);
|
|
194
|
+
export { WorkspaceForm };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { css } from "lit";
|
|
2
|
+
export default css `
|
|
3
|
+
|
|
4
|
+
h2 {
|
|
5
|
+
margin-top: 10px;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.workspace-area {
|
|
9
|
+
padding-left: 20px;
|
|
10
|
+
padding-right: 20px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
p {
|
|
14
|
+
font-size: 0.8rem;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
hr.main-break {
|
|
18
|
+
margin-top: 20px;
|
|
19
|
+
margin-bottom: 10px;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
sl-icon-button.delete-workspace::part(base),sl-icon-button.edit-workspace::part(base) {
|
|
23
|
+
padding: 5px 10px 0 0;
|
|
24
|
+
display:none;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.active {
|
|
28
|
+
background-color: var(--primary-color-verylowalpha);
|
|
29
|
+
color: var(--font-color);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.active sl-icon-button.delete-workspace::part(base) {
|
|
33
|
+
display: inline-block;
|
|
34
|
+
}
|
|
35
|
+
.active sl-icon-button.edit-workspace::part(base) {
|
|
36
|
+
display: inline-block;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
`;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { TheDoctor } from "../the-doctor/the-doctor.js";
|
|
2
|
+
import { WorkspaceController } from "../../controllers/workspace-controller.js";
|
|
3
|
+
import { Workspace } from "../../model/workspace.js";
|
|
4
|
+
import { Formable } from "../../model/formable.js";
|
|
5
|
+
import { WorkspaceForm } from "./workspace-form.js";
|
|
6
|
+
import { WorkspaceDestroyView } from "./workspace-destroy-dialog.js";
|
|
7
|
+
import { PlatformError } from "../../model/errors.js";
|
|
8
|
+
export declare class WorkspacesView extends Formable {
|
|
9
|
+
static styles: import("lit").CSSResult[];
|
|
10
|
+
active: boolean;
|
|
11
|
+
mutateWorkspaceActive: boolean;
|
|
12
|
+
workspaces: Workspace[];
|
|
13
|
+
wsController: WorkspaceController;
|
|
14
|
+
workspaceForm: WorkspaceForm;
|
|
15
|
+
destroyDialog: WorkspaceDestroyView;
|
|
16
|
+
constructor(doc: TheDoctor, wsController: WorkspaceController);
|
|
17
|
+
private setupDestroyDialogEvents;
|
|
18
|
+
private setupWorkspaceFormEvents;
|
|
19
|
+
private handleWorkspaceFormComplete;
|
|
20
|
+
openCreateWorkspaceDialog(): void;
|
|
21
|
+
selectWorkspace(workspace: Workspace): void;
|
|
22
|
+
lightWorkspace(id: string | undefined): void;
|
|
23
|
+
dimWorkspace(id: string | undefined): void;
|
|
24
|
+
showDestroyDialog(w: Workspace): void;
|
|
25
|
+
showEditDialog(w: Workspace): void;
|
|
26
|
+
private handleDestroyCancel;
|
|
27
|
+
private handleDestroyConfirm;
|
|
28
|
+
deleteWorkspaceError(error: PlatformError): void;
|
|
29
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { html } from "lit";
|
|
8
|
+
import { customElement, state } from "lit/decorators.js";
|
|
9
|
+
import { Formable } from "../../model/formable.js";
|
|
10
|
+
import { WorkspaceForm } from "./workspace-form.js";
|
|
11
|
+
import { WorkspaceDestroyView } from "./workspace-destroy-dialog.js";
|
|
12
|
+
import { DeleteWorkspace, SwitchWorkspace, FormSubmitComplete, RefreshWorkspaces, CreateWorkspace, UpdateWorkspace } from "../../events/doctor.js";
|
|
13
|
+
import { AttentionType } from "../attention-box/attention-box.js";
|
|
14
|
+
import listsCss from "../../css/lists.css.js";
|
|
15
|
+
import workspaceViewCss from "./workspace-view.css.js";
|
|
16
|
+
import badgesCss from "../../css/badges.css.js";
|
|
17
|
+
import linksCss from "../../css/links.css.js";
|
|
18
|
+
import tooltipCss from "../../css/tooltip.css.js";
|
|
19
|
+
let WorkspacesView = class WorkspacesView extends Formable {
|
|
20
|
+
constructor(doc, wsController) {
|
|
21
|
+
super(doc);
|
|
22
|
+
this.doc = doc;
|
|
23
|
+
this.wsController = wsController;
|
|
24
|
+
this.active = false;
|
|
25
|
+
this.mutateWorkspaceActive = false;
|
|
26
|
+
this.workspaceForm = new WorkspaceForm();
|
|
27
|
+
this.destroyDialog = new WorkspaceDestroyView();
|
|
28
|
+
this.setupDestroyDialogEvents();
|
|
29
|
+
this.setupWorkspaceFormEvents();
|
|
30
|
+
}
|
|
31
|
+
setupDestroyDialogEvents() {
|
|
32
|
+
this.destroyDialog.addEventListener('cancel', () => this.handleDestroyCancel());
|
|
33
|
+
this.destroyDialog.addEventListener('destroy', (event) => this.handleDestroyConfirm(event));
|
|
34
|
+
}
|
|
35
|
+
setupWorkspaceFormEvents() {
|
|
36
|
+
this.workspaceForm.addEventListener(FormSubmitComplete, (event) => {
|
|
37
|
+
this.handleWorkspaceFormComplete(event);
|
|
38
|
+
});
|
|
39
|
+
this.workspaceForm.addEventListener(CreateWorkspace, (event) => {
|
|
40
|
+
this.wsController.dispatchEvent(new CustomEvent(CreateWorkspace, {
|
|
41
|
+
bubbles: true,
|
|
42
|
+
composed: true,
|
|
43
|
+
detail: event.detail
|
|
44
|
+
}));
|
|
45
|
+
});
|
|
46
|
+
this.workspaceForm.addEventListener(UpdateWorkspace, (event) => {
|
|
47
|
+
this.wsController.dispatchEvent(new CustomEvent(UpdateWorkspace, {
|
|
48
|
+
bubbles: true,
|
|
49
|
+
composed: true,
|
|
50
|
+
detail: event.detail
|
|
51
|
+
}));
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
handleWorkspaceFormComplete(_) {
|
|
55
|
+
// Refresh the workspace list after create/update
|
|
56
|
+
this.wsController.dispatchEvent(new CustomEvent(RefreshWorkspaces, {
|
|
57
|
+
bubbles: true,
|
|
58
|
+
composed: true
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
openCreateWorkspaceDialog() {
|
|
62
|
+
this.workspaceForm.setCreateMode();
|
|
63
|
+
this.workspaceForm.open = true;
|
|
64
|
+
}
|
|
65
|
+
selectWorkspace(workspace) {
|
|
66
|
+
this.wsController.dispatchEvent(new CustomEvent(SwitchWorkspace, {
|
|
67
|
+
bubbles: true,
|
|
68
|
+
composed: true,
|
|
69
|
+
detail: workspace
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
lightWorkspace(id) {
|
|
73
|
+
if (id) {
|
|
74
|
+
let li = this.shadowRoot?.querySelector('li#workspace-' + id);
|
|
75
|
+
if (li) {
|
|
76
|
+
li.classList.add('active');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
dimWorkspace(id) {
|
|
81
|
+
if (id) {
|
|
82
|
+
let li = this.shadowRoot?.querySelector('li#workspace-' + id);
|
|
83
|
+
if (li) {
|
|
84
|
+
li.classList.remove('active');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
showDestroyDialog(w) {
|
|
89
|
+
this.destroyDialog.workspace = w;
|
|
90
|
+
this.destroyDialog.show();
|
|
91
|
+
this.lightWorkspace(w.workspaceId);
|
|
92
|
+
}
|
|
93
|
+
showEditDialog(w) {
|
|
94
|
+
this.workspaceForm.setEditMode(w);
|
|
95
|
+
this.workspaceForm.open = true;
|
|
96
|
+
}
|
|
97
|
+
handleDestroyCancel() {
|
|
98
|
+
this.destroyDialog.hide().then(() => {
|
|
99
|
+
this.dimWorkspace(this.destroyDialog.workspace?.workspaceId);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
handleDestroyConfirm(event) {
|
|
103
|
+
this.wsController.dispatchEvent(new CustomEvent(DeleteWorkspace, {
|
|
104
|
+
bubbles: true,
|
|
105
|
+
composed: true,
|
|
106
|
+
detail: event.detail
|
|
107
|
+
}));
|
|
108
|
+
this.destroyDialog.clearError();
|
|
109
|
+
}
|
|
110
|
+
deleteWorkspaceError(error) {
|
|
111
|
+
this.destroyDialog.setError(error);
|
|
112
|
+
}
|
|
113
|
+
render() {
|
|
114
|
+
if (!this.workspaces || this.workspaces.length === 0) {
|
|
115
|
+
return html ``;
|
|
116
|
+
}
|
|
117
|
+
return html `
|
|
118
|
+
<div class="workspace-area">
|
|
119
|
+
${this.destroyDialog}
|
|
120
|
+
|
|
121
|
+
${this.workspaceForm}
|
|
122
|
+
|
|
123
|
+
<h2>workspaces</h2>
|
|
124
|
+
|
|
125
|
+
<p>The best way to think of a workspace is like a project. Keep all your stuff in one place, and
|
|
126
|
+
switch between workspaces when you need to flip to a different spec or project.</p>
|
|
127
|
+
|
|
128
|
+
${this.workspaces.length >= 5 ? html `
|
|
129
|
+
<sl-tooltip content="maximum limit reached, cannot create any more">
|
|
130
|
+
<sl-button disabled>
|
|
131
|
+
Add workspace
|
|
132
|
+
</sl-button>
|
|
133
|
+
</sl-tooltip>
|
|
134
|
+
` : html `
|
|
135
|
+
<sl-button @click="${() => {
|
|
136
|
+
this.openCreateWorkspaceDialog();
|
|
137
|
+
}}">
|
|
138
|
+
Add workspace
|
|
139
|
+
</sl-button>
|
|
140
|
+
`}
|
|
141
|
+
|
|
142
|
+
${this.workspaces.length >= 5 ? html `
|
|
143
|
+
<pb33f-attention-box type="${AttentionType.Info}"
|
|
144
|
+
headerText="maximum workspace count reached">
|
|
145
|
+
In order to create more workspaces, you will need to upgrade to pro (coming soon).
|
|
146
|
+
</pb33f-attention-box>
|
|
147
|
+
` : ''}
|
|
148
|
+
|
|
149
|
+
<hr class="main-break"/>
|
|
150
|
+
<ul>
|
|
151
|
+
|
|
152
|
+
${this.workspaces.map((w) => {
|
|
153
|
+
// Determine workspace content based on active status
|
|
154
|
+
const workspaceContent = w.active
|
|
155
|
+
? html `<strong>${w.name}</strong> <sl-badge pulse>active</sl-badge>`
|
|
156
|
+
: html `<a href="#" class="workspace-link" @click=${() => this.selectWorkspace(w)}>${w.name}</a>`;
|
|
157
|
+
// Determine CSS classes and styling
|
|
158
|
+
const liClasses = w.active ? 'secondary' : '';
|
|
159
|
+
const liStyles = w.active ? 'color: var(--secondary-color)' : '';
|
|
160
|
+
return html `
|
|
161
|
+
<li id="workspace-${w.workspaceId}"
|
|
162
|
+
class="${liClasses}"
|
|
163
|
+
style="${liStyles}"
|
|
164
|
+
@mouseover="${() => this.lightWorkspace(w.workspaceId)}"
|
|
165
|
+
@mouseout="${() => this.dimWorkspace(w.workspaceId)}">
|
|
166
|
+
|
|
167
|
+
${workspaceContent}
|
|
168
|
+
|
|
169
|
+
<div style="display: inline-block; float: right">
|
|
170
|
+
<sl-icon-button class="edit-workspace" name="pencil-square"
|
|
171
|
+
@click="${() => { this.showEditDialog(w); }}"></sl-icon-button>
|
|
172
|
+
${!w.default && !w.active ? html `
|
|
173
|
+
<sl-icon-button class="delete-workspace" name="trash3"
|
|
174
|
+
@click="${() => { this.showDestroyDialog(w); }}"></sl-icon-button>
|
|
175
|
+
` : ''}
|
|
176
|
+
</div>
|
|
177
|
+
</li>
|
|
178
|
+
`;
|
|
179
|
+
})}
|
|
180
|
+
</ul>
|
|
181
|
+
</div>
|
|
182
|
+
|
|
183
|
+
`;
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
WorkspacesView.styles = [...Formable.styles, workspaceViewCss, badgesCss, linksCss, listsCss, tooltipCss];
|
|
187
|
+
__decorate([
|
|
188
|
+
state()
|
|
189
|
+
], WorkspacesView.prototype, "active", void 0);
|
|
190
|
+
__decorate([
|
|
191
|
+
state()
|
|
192
|
+
], WorkspacesView.prototype, "mutateWorkspaceActive", void 0);
|
|
193
|
+
WorkspacesView = __decorate([
|
|
194
|
+
customElement("pb33f-doctor-workspaces")
|
|
195
|
+
], WorkspacesView);
|
|
196
|
+
export { WorkspacesView };
|
|
@@ -14,6 +14,7 @@ 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;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
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) {
|
|
@@ -138,7 +139,6 @@ export class AuthController extends EventTarget {
|
|
|
138
139
|
}
|
|
139
140
|
logout() {
|
|
140
141
|
AuthService.logout().then(() => {
|
|
141
|
-
//if (e.detail.redirectURL != '') {
|
|
142
142
|
this.dispatchEvent(new CustomEvent(NukeWorkspaceEvent, {
|
|
143
143
|
bubbles: true,
|
|
144
144
|
composed: true,
|
|
@@ -146,20 +146,38 @@ export class AuthController extends EventTarget {
|
|
|
146
146
|
resetFiles: true
|
|
147
147
|
}
|
|
148
148
|
}));
|
|
149
|
-
// }
|
|
150
149
|
});
|
|
151
150
|
}
|
|
152
151
|
notifyStateChange(state) {
|
|
152
|
+
this.checkingState = false;
|
|
153
153
|
const event = new CustomEvent(AuthenticationStateChange, {
|
|
154
154
|
detail: { state }
|
|
155
155
|
});
|
|
156
156
|
this.dispatchEvent(event);
|
|
157
157
|
}
|
|
158
158
|
async checkState() {
|
|
159
|
-
|
|
160
|
-
this.
|
|
161
|
-
return
|
|
162
|
-
|
|
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
|
+
}
|
|
163
181
|
}
|
|
164
182
|
}
|
|
165
183
|
AuthController._instance = null;
|
|
@@ -6,8 +6,13 @@ export class DiagnosticController extends EventTarget {
|
|
|
6
6
|
constructor(doc) {
|
|
7
7
|
super();
|
|
8
8
|
this.doc = doc;
|
|
9
|
+
this.oldScore = 0;
|
|
9
10
|
}
|
|
10
11
|
lintSpec(value, url) {
|
|
12
|
+
// capture old score before any operations
|
|
13
|
+
if (this.doc.problemsOverview.statistics?.statistics.overallScore > 0) {
|
|
14
|
+
this.oldScore = this.doc.problemsOverview.statistics.statistics.overallScore;
|
|
15
|
+
}
|
|
11
16
|
this.doc.activitySpinner.show();
|
|
12
17
|
this.doc.editor.breadcumb.isInvalid = false;
|
|
13
18
|
if (url) {
|
|
@@ -177,10 +182,6 @@ export class DiagnosticController extends EventTarget {
|
|
|
177
182
|
}
|
|
178
183
|
// update the overview statistics
|
|
179
184
|
LintingService.fetchStatistics().then((result) => {
|
|
180
|
-
let oldScore = 0;
|
|
181
|
-
if (this.doc.problemsOverview.statistics) {
|
|
182
|
-
oldScore = this.doc.problemsOverview.statistics.statistics.overallScore;
|
|
183
|
-
}
|
|
184
185
|
this.doc.diagnosticBag?.set(DiagnosticBag, result);
|
|
185
186
|
this.doc.activitySpinner.hide();
|
|
186
187
|
if (result?.remainingCredit <= 10) {
|
|
@@ -196,20 +197,20 @@ export class DiagnosticController extends EventTarget {
|
|
|
196
197
|
if (!settings?.autoDiagnose) {
|
|
197
198
|
if (this.doc.problemsOverview.statistics) {
|
|
198
199
|
const newScore = result.statistics.overallScore;
|
|
199
|
-
if (oldScore > newScore) {
|
|
200
|
+
if (this.oldScore > newScore) {
|
|
200
201
|
this.doc.sendToast({
|
|
201
202
|
id: crypto.randomUUID(),
|
|
202
203
|
type: ToastType.SCOREDOWN,
|
|
203
204
|
body: "Your score has decreased. It is now " + newScore + "%",
|
|
204
|
-
title: "Score went down by " + (oldScore - newScore) + "%"
|
|
205
|
+
title: "Score went down by " + (this.oldScore - newScore) + "%"
|
|
205
206
|
});
|
|
206
207
|
}
|
|
207
|
-
if (oldScore < newScore) {
|
|
208
|
+
if (this.oldScore < newScore) {
|
|
208
209
|
this.doc.sendToast({
|
|
209
210
|
id: crypto.randomUUID(),
|
|
210
211
|
type: ToastType.SCOREUP,
|
|
211
212
|
body: "Your score has increased to " + newScore + "%",
|
|
212
|
-
title: "Score went up by " + (newScore - oldScore) + "%"
|
|
213
|
+
title: "Score went up by " + (newScore - this.oldScore) + "%"
|
|
213
214
|
});
|
|
214
215
|
}
|
|
215
216
|
}
|
|
@@ -237,11 +238,15 @@ export class DiagnosticController extends EventTarget {
|
|
|
237
238
|
if (e.instance === 'https://pb33f.io/errors/no-credit-remaining') {
|
|
238
239
|
this.doc.statusBar.callsRemaining = 0;
|
|
239
240
|
this.doc.statusBar.visible = true;
|
|
241
|
+
let text = "Run out of credit, please authenticate for more or wait 24 hours.";
|
|
242
|
+
if (this.doc.authController.authenticated) {
|
|
243
|
+
text = "Run out of credit, please purchase more, or come back tomorrow for more free credits.";
|
|
244
|
+
}
|
|
240
245
|
this.doc.sendToast({
|
|
241
246
|
id: crypto.randomUUID(),
|
|
242
247
|
type: ToastType.ERROR,
|
|
243
|
-
body:
|
|
244
|
-
title: "Credit
|
|
248
|
+
body: text,
|
|
249
|
+
title: "💰 Credit Exhausted!",
|
|
245
250
|
});
|
|
246
251
|
}
|
|
247
252
|
else {
|