Skip to content

Commit

Permalink
Merge pull request #49 from natrontech/code-tab
Browse files Browse the repository at this point in the history
Code tab
  • Loading branch information
janlauber authored Nov 6, 2023
2 parents a0339dd + dcdfc6f commit d046246
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 96 deletions.
15 changes: 15 additions & 0 deletions kubelab-ui/src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,18 @@ h3 {
.btn {
@apply border-2;
}

.splitpanes__splitter {
background-color: darkgray !important;
position: relative;
opacity: 0;
}


.splitpanes--horizontal > .splitpanes__splitter {
border-top: none !important;
}

.splitpanes--vertical > .splitpanes__splitter {
border-left: none !important;
}
15 changes: 15 additions & 0 deletions kubelab-ui/src/lib/stores/codeView.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { writable } from "svelte/store";

const defaultValue = false;
const initialCodeViewValue =
localStorage.getItem("codeView") === null
? defaultValue
: localStorage.getItem("codeView") === "true";

const codeView = writable<boolean>(initialCodeViewValue);

codeView.subscribe((value) => {
localStorage.setItem("codeView", value.toString());
});

export default codeView;
1 change: 1 addition & 0 deletions kubelab-ui/src/lib/stores/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
} from "$lib/pocketbase/generated-types";
import { get, writable, type Writable } from "svelte/store";

export const loadingCodeEditor: Writable<boolean> = writable<boolean>(false);
export const avatarUrl: Writable<string> = writable<string>();
export const lab: Writable<LabsResponse> = writable<LabsResponse>();
export const labs: Writable<LabsResponse[]> = writable<LabsResponse[]>();
Expand Down
176 changes: 92 additions & 84 deletions kubelab-ui/src/routes/labs/[id]/[id]/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
RotateCw,
StopCircle,
StretchHorizontal,
StretchVertical
StretchVertical,
Terminal
} from "lucide-svelte";
import { client } from "$lib/pocketbase/index.js";
import toast from "svelte-french-toast";
Expand All @@ -20,7 +21,8 @@
exercise_session,
exercise_sessions,
exercises,
filterExercisesByLab
filterExercisesByLab,
loadingCodeEditor
} from "$lib/stores/data.js";
// @ts-ignore
Expand All @@ -39,7 +41,8 @@
type NotificationsRecord,
NotificationsTypeOptions
} from "$lib/pocketbase/generated-types.js";
import { Tooltip } from "flowbite-svelte";
import { Tooltip } from "flowbite-svelte";
import codeView from "$lib/stores/codeView.js";
$metadata.title = "Exercises";
Expand Down Expand Up @@ -265,24 +268,9 @@
}
function handleOpenVSCode() {
// open target blank new tab with the url
let lab_session_id = data.pathname.split("/")[2];
let exercise_id = window.location.pathname.split("/")[3];
let agentHost = window.location.host === "localhost:5173" ? "kubelab.ch" : window.location.host;
console.log(agentHost);
let agentUrl =
"kubelab-" +
lab_session_id +
"-" +
exercise_id +
"-" +
client.authStore.model?.id +
"." +
agentHost;
// open new tab with agentUrl
window.open("https://" + agentUrl, "_blank");
// window.open(codeUrl, "_blank");
$codeView = !$codeView;
$loadingCodeEditor = true;
}
function isCurrentExercise(exercise_id: string) {
Expand All @@ -293,101 +281,121 @@
{#key $exercise}
<div class="absolute top-0 h-20 left-0 right-0 ">
<div class="mt-5 flex justify-between px-2">
<button
class="btn btn-neutral "
on:click={() => {
if ($sidebar_lab) {
sidebarOpen.set(true);
}
goto("/labs/");
}}
>
<ArrowLeft class="inline-block w-4 h-4 mr-2" />
Labs
</button>
<ToggleConfetti>
<button
slot="label"
class="btn {!$exercise_session.agentRunning ? 'hidden' : 'btn-success'}"
on:click={() => handleCheckExercise()}
>
<CheckCircle class="inline-block mr-2" />
<span> Check </span>
</button>
<div
style="position: fixed; top: -10px; left: 0; height: 100vh; width: 100vw; display: flex; justify-content: center; overflow: hidden; z-index: 10;"
>
{#if $exercise_session.endTime}
<Confetti
x={[-5, 5]}
y={[0, 0.1]}
delay={[0, 2000]}
duration="3000"
amount="100"
fallDistance="100vh"
/>
{/if}
</div>
</ToggleConfetti>
<div class="join grid grid-cols-2">
<div class="grid grid-cols-2 gap-2">
<button
class="btn btn-neutral"
on:click={() => {
horizontalView.set(true);
if ($sidebar_lab) {
sidebarOpen.set(true);
}
goto("/labs/");
}}
class="join-item btn {$horizontalView
? ' btn-neutral dark:btn-primary dark:text-neutral '
: ''} "
>
<StretchHorizontal />
</button>
<button
on:click={() => {
horizontalView.set(false);
}}
class="join-item btn {$horizontalView
? ''
: ' btn-neutral dark:btn-primary dark:text-neutral '}"
>
<StretchVertical />
<ArrowLeft class="inline-block w-4 h-4 mr-2" />
Labs
</button>
<div class="join ">
<button
on:click={() => {
codeView.set(false);
}}
class="join-item btn {!$codeView
? ' btn-neutral dark:btn-primary dark:text-neutral'
: 'btn-outline'} "
>
<Terminal class="inline-block" />
</button>
<button
on:click={() => {
codeView.set(true);
}}
class="join-item btn {!$codeView
? 'btn-outline'
: ' btn-neutral dark:btn-primary dark:text-neutral '}"
>
<FileCode2 class="inline-block" />
</button>
</div>
</div>
<div class="grid grid-cols-2 gap-2">
<div class="join grid grid-cols-2">
<button
on:click={() => {
horizontalView.set(true);
}}
class="join-item btn {$horizontalView
? ' btn-neutral dark:btn-primary dark:text-neutral'
: 'btn-outline'} "
>
<StretchHorizontal />
</button>
<button
on:click={() => {
horizontalView.set(false);
}}
class="join-item btn {$horizontalView
? 'btn-outline'
: ' btn-neutral dark:btn-primary dark:text-neutral '}"
>
<StretchVertical />
</button>
</div>
<ToggleConfetti>
<button
slot="label"
class="btn {!$exercise_session.agentRunning ? 'hidden' : 'btn-success'}"
on:click={() => handleCheckExercise()}
>
<CheckCircle class="inline-block mr-2" />
<span> Check </span>
</button>
<div
style="position: fixed; top: -10px; left: 0; height: 100vh; width: 100vw; display: flex; justify-content: center; overflow: hidden; z-index: 10;"
>
{#if $exercise_session.endTime}
<Confetti
x={[-5, 5]}
y={[0, 0.1]}
delay={[0, 2000]}
duration="3000"
amount="100"
fallDistance="100vh"
/>
{/if}
</div>
</ToggleConfetti>
</div>
</div>
</div>
<div class="absolute top-16 bottom-16 left-0 right-0 z-0">
<slot />
</div>

<div class="absolute h-16 bottom-0 left-0 right-0">
<div class="mt-2 flex justify-between px-2">
<div>
{#if $exercise_session.agentRunning}
<button class="btn btn-info" on:click={() => handleOpenVSCode()}>
<FileCode2 class="inline-block" />
</button>
<Tooltip>Open Code Editor</Tooltip>

{#if client.authStore.model?.workshop == true}
<button
class="btn btn-accent dark:text-black {helpRequested
? 'btn-disabled'
: 'btn-accent'}"
class="btn btn-accent dark:text-black {helpRequested ? 'btn-disabled' : 'btn-accent'}"
on:click={() => {
askForHelp();
}}
>
<HelpCircle class="inline-block" />
</button>
<Tooltip>Call for Help</Tooltip>
<Tooltip class="bg-neutral">Call for Help</Tooltip>
{/if}

<button class="btn btn-error" on:click={() => handleStopExercise()}>
<StopCircle class="inline-block" />
</button>
<Tooltip>Stop Exercise</Tooltip>
<Tooltip class="bg-neutral">Stop Exercise</Tooltip>

<button class="btn btn-warning" on:click={() => handleRestartExercise()}>
<RotateCw class="inline-block {restartLoading ? 'animate-spin' : ''}" />
</button>
<Tooltip>Reset Exercise</Tooltip>
<Tooltip class="bg-neutral">Reset Exercise</Tooltip>
{/if}
</div>
<div class="">
Expand Down
Loading

0 comments on commit d046246

Please sign in to comment.