@pb33f/cowboy-components 0.7.8 → 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/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 +49 -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/diagnostic-controller.d.ts +1 -0
- package/dist/controllers/diagnostic-controller.js +9 -8
- package/dist/controllers/workspace-controller.d.ts +15 -0
- package/dist/controllers/workspace-controller.js +156 -0
- package/dist/cowboy-components.umd.cjs +1558 -1094
- 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
|
@@ -48,6 +48,22 @@ export default css `
|
|
|
48
48
|
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
|
|
49
49
|
background: var(--secondary-color-lowalpha);
|
|
50
50
|
padding: var(--global-padding);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.workspace-icon {
|
|
54
|
+
font-size: 1.25rem;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.workspace-icon::part(base) {
|
|
58
|
+
padding: 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.workspace-icon.active {
|
|
62
|
+
color: var(--primary-color);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.tab.hidden {
|
|
66
|
+
display: none;
|
|
51
67
|
}
|
|
52
68
|
|
|
53
69
|
|
|
@@ -54,6 +54,7 @@ import { DocsController } from '../../controllers/docs-controller.js';
|
|
|
54
54
|
import { ModelController } from '../../controllers/model-controller.js';
|
|
55
55
|
import { DiagnosticController } from '../../controllers/diagnostic-controller.js';
|
|
56
56
|
import { StateController } from '../../controllers/state-controller.js';
|
|
57
|
+
import { WorkspaceController } from "../../controllers/workspace-controller";
|
|
57
58
|
export declare const GraphBag = "pb33f-doctor-graph";
|
|
58
59
|
export declare const PanelStateBag = "pb33f-doctor-panel-state";
|
|
59
60
|
export declare const RolodexResponseBag = "pb33f-doctor-rolodex-response";
|
|
@@ -178,6 +179,7 @@ export declare class TheDoctor extends LitElement {
|
|
|
178
179
|
readonly modelController: ModelController;
|
|
179
180
|
readonly diagnosticController: DiagnosticController;
|
|
180
181
|
readonly stateController: StateController;
|
|
182
|
+
readonly workspaceController: WorkspaceController;
|
|
181
183
|
editorMap: Map<string, SpecEditor>;
|
|
182
184
|
selectedEditorTab: string;
|
|
183
185
|
sidebarClosed: boolean;
|
|
@@ -226,6 +228,7 @@ export declare class TheDoctor extends LitElement {
|
|
|
226
228
|
platformUnavailable(error: PlatformError | null): void;
|
|
227
229
|
builtInRulesetSelected(): void;
|
|
228
230
|
runDiagnostics(): void;
|
|
231
|
+
reboot(): void;
|
|
229
232
|
boostrap(): void;
|
|
230
233
|
confirmExport(): void;
|
|
231
234
|
closeWelcome(): 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, 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";
|
|
19
|
+
import { ActiveView, AddToast, ArchiveURLRequested, BuiltInRulesetChanged, CreditEmpty, CustomRulesetEnabled, DocumentReferenceClicked, EditorClicked, EditorUpdated, ExplorerEqualizerChanged, ExplorerEqualizerFiltered, ExplorerNodeClicked, ExportRuleset, LoadRenderedNodeIntoInspector, ModelTreeNodeClicked, NodeReferenceClicked, NukeWorkspaceEvent, OpenProblemDrawer, OpenSettings, ProblemClicked, Reboot, 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";
|
|
@@ -66,6 +66,8 @@ import { DocsController } from '../../controllers/docs-controller.js';
|
|
|
66
66
|
import { ModelController } from '../../controllers/model-controller.js';
|
|
67
67
|
import { DiagnosticController } from '../../controllers/diagnostic-controller.js';
|
|
68
68
|
import { StateController } from '../../controllers/state-controller.js';
|
|
69
|
+
import { WorkspaceController } from "../../controllers/workspace-controller";
|
|
70
|
+
import { WorkspaceService } from 'src/services/workspace-service.js';
|
|
69
71
|
export const GraphBag = "pb33f-doctor-graph";
|
|
70
72
|
export const PanelStateBag = "pb33f-doctor-panel-state";
|
|
71
73
|
export const RolodexResponseBag = "pb33f-doctor-rolodex-response";
|
|
@@ -113,6 +115,7 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
113
115
|
ModelService.doctorEndpoint = this.doctorEndpoint;
|
|
114
116
|
AuthService.doctorEndpoint = this.doctorEndpoint;
|
|
115
117
|
TimelineService.doctorEndpoint = this.doctorEndpoint;
|
|
118
|
+
WorkspaceService.doctorEndpoint = this.doctorEndpoint;
|
|
116
119
|
this.timeVortex = new TimeVortex();
|
|
117
120
|
// bus it up
|
|
118
121
|
this.bus = CreateBus();
|
|
@@ -156,6 +159,7 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
156
159
|
this.problemController = new ProblemController(this);
|
|
157
160
|
this.docsController = new DocsController(this);
|
|
158
161
|
this.diagnosticController = new DiagnosticController(this);
|
|
162
|
+
this.workspaceController = new WorkspaceController(this);
|
|
159
163
|
this.settingsComponent = new DoctorSettings();
|
|
160
164
|
this.editorMap = new Map();
|
|
161
165
|
this.editorMap.set("spec", this.editor);
|
|
@@ -197,6 +201,10 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
197
201
|
}
|
|
198
202
|
this.creditTicker.visible = true;
|
|
199
203
|
this.brokerController.connectToBroker();
|
|
204
|
+
// if the session is authenticated, then fetch a list of workspaces for the user.
|
|
205
|
+
if (this.authController.authenticated) {
|
|
206
|
+
this.workspaceController.getWorkspaces();
|
|
207
|
+
}
|
|
200
208
|
};
|
|
201
209
|
// create auth controller
|
|
202
210
|
this.authController = new AuthController(this, sessionCallback, true);
|
|
@@ -253,6 +261,7 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
253
261
|
this.authController.addEventListener(CreditEmpty, this.creditEmpty.bind(this));
|
|
254
262
|
//@ts-ignore
|
|
255
263
|
this.addEventListener(LoadRenderedNodeIntoInspector, this.loadRenderedNodeIntoInspector.bind(this));
|
|
264
|
+
this.addEventListener(Reboot, this.reboot.bind(this));
|
|
256
265
|
// hijack navigation buttons.
|
|
257
266
|
window.addEventListener('popstate', (e) => {
|
|
258
267
|
const state = e.state;
|
|
@@ -432,6 +441,21 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
432
441
|
this.diagnosticController.lintSpec(this.editor.getValue());
|
|
433
442
|
}
|
|
434
443
|
}
|
|
444
|
+
reboot() {
|
|
445
|
+
// for when we need to switch workspaces, and everything needs an update.
|
|
446
|
+
ModelService.getCurrentSpec().then((result) => {
|
|
447
|
+
this.rolodexController.queryRolodex();
|
|
448
|
+
this.timeVortex.checkHistory();
|
|
449
|
+
this.editor.setValue(result, true);
|
|
450
|
+
this.rolodexActivePath = "";
|
|
451
|
+
this.specController.specChanged(new CustomEvent(EditorUpdated, {
|
|
452
|
+
detail: {
|
|
453
|
+
content: result,
|
|
454
|
+
id: "spec"
|
|
455
|
+
}
|
|
456
|
+
}));
|
|
457
|
+
});
|
|
458
|
+
}
|
|
435
459
|
boostrap() {
|
|
436
460
|
// if the url is set in the query string, fetch it and run a lint with the URL
|
|
437
461
|
const url = new URL(window.location.href);
|
|
@@ -572,12 +596,14 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
572
596
|
title: "Safari Warning"
|
|
573
597
|
});
|
|
574
598
|
}
|
|
599
|
+
this.workspaceController.workspaceView.active = false;
|
|
575
600
|
}
|
|
576
601
|
hideMinimapIcon() {
|
|
577
602
|
this.minimapIconVisible = false;
|
|
578
603
|
}
|
|
579
604
|
hideDiagnosisButton() {
|
|
580
605
|
this.showDiagnosisButton = false;
|
|
606
|
+
this.workspaceController.workspaceView.active = false;
|
|
581
607
|
}
|
|
582
608
|
enableDiagnosisButton() {
|
|
583
609
|
if (!this.autoDiagnose) {
|
|
@@ -779,8 +805,20 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
779
805
|
<sl-tab-group class="tab-group" @sl-tab-show="${this.selectEditorTab}"
|
|
780
806
|
id="editor-controls">
|
|
781
807
|
|
|
782
|
-
<sl-tab slot="nav" panel="
|
|
808
|
+
<sl-tab slot="nav" panel="workspaces" class="tab ${!this.authController.authenticated ? 'hidden' : ''}" id="workspaces"
|
|
809
|
+
@click="${() => {
|
|
810
|
+
this.selectedEditorTab = 'workspaces';
|
|
811
|
+
this.toggleExplorer();
|
|
812
|
+
this.hideDiagnosisButton();
|
|
813
|
+
this.workspaceController.workspaceView.active = true;
|
|
814
|
+
}}">
|
|
815
|
+
<sl-icon-button name="person-workspace"
|
|
816
|
+
class="workspace-icon ${this.selectedEditorTab === 'workspaces' ? 'active' : ''}"></sl-icon-button>
|
|
817
|
+
</sl-tab>
|
|
818
|
+
|
|
819
|
+
<sl-tab slot="nav" panel="spec" class="tab" id="spec" active
|
|
783
820
|
@click="${() => {
|
|
821
|
+
this.selectedEditorTab = 'spec';
|
|
784
822
|
this.closeExplorer();
|
|
785
823
|
this.enableDiagnosisButton();
|
|
786
824
|
}}">
|
|
@@ -788,6 +826,7 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
788
826
|
</sl-tab>
|
|
789
827
|
<sl-tab slot="nav" panel="explorer" class="tab" id="explorer"
|
|
790
828
|
@click="${() => {
|
|
829
|
+
this.selectedEditorTab = 'explorer';
|
|
791
830
|
this.toggleExplorer();
|
|
792
831
|
this.hideDiagnosisButton();
|
|
793
832
|
}}">Explorer
|
|
@@ -861,9 +900,16 @@ let TheDoctor = class TheDoctor extends LitElement {
|
|
|
861
900
|
</sl-tab-panel>
|
|
862
901
|
|
|
863
902
|
<sl-tab-panel name="docs" class="tab-panel" style="height: calc(100vh - 100px)">
|
|
864
|
-
|
|
903
|
+
|
|
865
904
|
</sl-tab-panel>
|
|
866
905
|
|
|
906
|
+
${this.authController.authenticated ? html `
|
|
907
|
+
|
|
908
|
+
<sl-tab-panel name="workspaces" class="tab-panel">
|
|
909
|
+
${this.workspaceController.workspaceView}
|
|
910
|
+
</sl-tab-panel>
|
|
911
|
+
` : ''}
|
|
912
|
+
|
|
867
913
|
</sl-tab-group>
|
|
868
914
|
</div>
|
|
869
915
|
${mainPanelView}
|
|
@@ -98,23 +98,7 @@ export default css `
|
|
|
98
98
|
text-align: center;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
.spinner-icon {
|
|
102
|
-
display: block;
|
|
103
|
-
margin: 20px auto 0 auto;
|
|
104
|
-
width: 200px;
|
|
105
|
-
color: var(--primary-color);
|
|
106
|
-
font-size: 6rem;
|
|
107
|
-
animation: spin 2s linear infinite;
|
|
108
|
-
}
|
|
109
101
|
|
|
110
|
-
@keyframes spin {
|
|
111
|
-
0% {
|
|
112
|
-
transform: rotate(0deg);
|
|
113
|
-
}
|
|
114
|
-
100% {
|
|
115
|
-
transform: rotate(360deg);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
102
|
|
|
119
103
|
.tardis-split-panel {
|
|
120
104
|
--min: 300px;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { LitElement } from "lit";
|
|
2
|
+
import { Workspace } from "../../model/workspace.js";
|
|
3
|
+
import { SlDialog } from "@shoelace-style/shoelace";
|
|
4
|
+
import { PlatformError } from "../../model/errors.js";
|
|
5
|
+
export declare class WorkspaceDestroyView extends LitElement {
|
|
6
|
+
static styles: import("lit").CSSResult[];
|
|
7
|
+
destroyWorkspaceDialog: SlDialog;
|
|
8
|
+
workspace: Workspace | undefined;
|
|
9
|
+
error: PlatformError | undefined;
|
|
10
|
+
show(): void;
|
|
11
|
+
hide(): Promise<void>;
|
|
12
|
+
setError(error: PlatformError): void;
|
|
13
|
+
clearError(): void;
|
|
14
|
+
private handleCancel;
|
|
15
|
+
private handleDestroy;
|
|
16
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
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, LitElement } from "lit";
|
|
8
|
+
import { customElement, property, state, query } from "lit/decorators.js";
|
|
9
|
+
import { AttentionType } from "../attention-box/attention-box.js";
|
|
10
|
+
import dialogCss from "../../css/dialog.css.js";
|
|
11
|
+
import buttonsCss from "../../css/button.css.js";
|
|
12
|
+
import hrCss from "../../css/hr.css.js";
|
|
13
|
+
let WorkspaceDestroyView = class WorkspaceDestroyView extends LitElement {
|
|
14
|
+
show() {
|
|
15
|
+
this.destroyWorkspaceDialog.show();
|
|
16
|
+
}
|
|
17
|
+
hide() {
|
|
18
|
+
this.error = undefined;
|
|
19
|
+
return this.destroyWorkspaceDialog.hide();
|
|
20
|
+
}
|
|
21
|
+
setError(error) {
|
|
22
|
+
this.error = error;
|
|
23
|
+
}
|
|
24
|
+
clearError() {
|
|
25
|
+
this.error = undefined;
|
|
26
|
+
}
|
|
27
|
+
handleCancel() {
|
|
28
|
+
this.dispatchEvent(new CustomEvent('cancel', {
|
|
29
|
+
bubbles: true,
|
|
30
|
+
composed: true
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
handleDestroy() {
|
|
34
|
+
this.dispatchEvent(new CustomEvent('destroy', {
|
|
35
|
+
bubbles: true,
|
|
36
|
+
composed: true,
|
|
37
|
+
detail: this.workspace
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
render() {
|
|
41
|
+
let attentionBox = html `
|
|
42
|
+
<pb33f-attention-box type="${AttentionType.Warning}" headerText="This is a permanent, destructive process">
|
|
43
|
+
All files, records, history and scores for this workspace will be wiped out permanently. There is no
|
|
44
|
+
undo process, if you hit OK - the workspace will be nuked and permanently destroyed.
|
|
45
|
+
</pb33f-attention-box>`;
|
|
46
|
+
if (this.error) {
|
|
47
|
+
attentionBox = html `
|
|
48
|
+
<pb33f-attention-box type="${AttentionType.Error}"
|
|
49
|
+
headerText="Workspace could not be deleted">
|
|
50
|
+
Something went wrong: <strong>${this.error.detail}</strong>
|
|
51
|
+
</pb33f-attention-box>`;
|
|
52
|
+
}
|
|
53
|
+
return html `
|
|
54
|
+
<sl-dialog id="destroy-workspace" label="Delete workspace, are you sure?">
|
|
55
|
+
You're about to destroy the workspace '<strong>${this.workspace?.name}</strong>'
|
|
56
|
+
<hr/>
|
|
57
|
+
|
|
58
|
+
${attentionBox}
|
|
59
|
+
|
|
60
|
+
<sl-button @click="${this.handleCancel}" class="cancel-button">
|
|
61
|
+
Cancel
|
|
62
|
+
</sl-button>
|
|
63
|
+
|
|
64
|
+
<sl-button @click="${this.handleDestroy}" style="float: right" class="danger">
|
|
65
|
+
Do it, destroy it.
|
|
66
|
+
</sl-button>
|
|
67
|
+
|
|
68
|
+
</sl-dialog>
|
|
69
|
+
`;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
WorkspaceDestroyView.styles = [dialogCss, buttonsCss, hrCss];
|
|
73
|
+
__decorate([
|
|
74
|
+
query('sl-dialog#destroy-workspace')
|
|
75
|
+
], WorkspaceDestroyView.prototype, "destroyWorkspaceDialog", void 0);
|
|
76
|
+
__decorate([
|
|
77
|
+
property()
|
|
78
|
+
], WorkspaceDestroyView.prototype, "workspace", void 0);
|
|
79
|
+
__decorate([
|
|
80
|
+
state()
|
|
81
|
+
], WorkspaceDestroyView.prototype, "error", void 0);
|
|
82
|
+
WorkspaceDestroyView = __decorate([
|
|
83
|
+
customElement("pb33f-workspace-destroy-dialog")
|
|
84
|
+
], WorkspaceDestroyView);
|
|
85
|
+
export { WorkspaceDestroyView };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { SlDialog } from "@shoelace-style/shoelace";
|
|
2
|
+
import { Formable } from "../../model/formable.js";
|
|
3
|
+
import { Workspace } from "../../model/workspace.js";
|
|
4
|
+
import { PlatformError } from "../../model/errors.js";
|
|
5
|
+
export declare class WorkspaceForm extends Formable {
|
|
6
|
+
static styles: import("lit").CSSResult[];
|
|
7
|
+
workspaceDialog: SlDialog;
|
|
8
|
+
active: boolean;
|
|
9
|
+
open: boolean;
|
|
10
|
+
workspaceModel: Workspace;
|
|
11
|
+
isEditMode: boolean;
|
|
12
|
+
constructor();
|
|
13
|
+
private handleFormDirty;
|
|
14
|
+
setEditMode(workspace: Workspace): void;
|
|
15
|
+
setCreateMode(): void;
|
|
16
|
+
close(): void;
|
|
17
|
+
completed(ws: Workspace): void;
|
|
18
|
+
private handleSubmit;
|
|
19
|
+
handleError(err: PlatformError): void;
|
|
20
|
+
handleSuccess(workspace: Workspace): void;
|
|
21
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
22
|
+
}
|
|
@@ -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
|
+
}
|