This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import { canOperate } from '$lib/auth.js';
|
||||
import { contextHref } from '$lib/navigation-context.js';
|
||||
import { onMount } from 'svelte';
|
||||
import { afterNavigate } from '$app/navigation';
|
||||
@@ -20,6 +21,7 @@
|
||||
import Input from '$ui/components/primitives/Input.svelte';
|
||||
import Select from '$ui/components/primitives/Select.svelte';
|
||||
import { libraryLimit, saveLibraryContext } from '$ui/library-context.js';
|
||||
const editable = $derived(canOperate($page.data?.user?.role));
|
||||
|
||||
type ArtifactKind = 'script' | 'config' | 'plugin' | 'baseline';
|
||||
interface ArtifactRow {
|
||||
@@ -266,11 +268,11 @@
|
||||
title="Plugins"
|
||||
subtitle="Manage plugin versions and test changes before promotion."
|
||||
>
|
||||
{#snippet actions()}{#if plugins.length}<Button
|
||||
{#snippet actions()}{#if editable && plugins.length}<Button
|
||||
variant="ghost"
|
||||
onclick={() => (updatesOpen = !updatesOpen)}
|
||||
>{updatesOpen ? 'Hide update details' : 'Check for updates'}</Button
|
||||
>{/if}{#if loading || plugins.length || flash}<Button
|
||||
>{/if}{#if editable && (loading || plugins.length || flash)}<Button
|
||||
variant="primary"
|
||||
onclick={() => (addOpen = true)}>Add plugin</Button
|
||||
>{/if}{/snippet}
|
||||
@@ -339,7 +341,7 @@
|
||||
{#if game}<p class="filter-hint">
|
||||
Game results include unscoped plugins that can use explicitly selected beta servers.
|
||||
</p>{/if}
|
||||
{#if updatesOpen}<details
|
||||
{#if editable && updatesOpen}<details
|
||||
open
|
||||
ontoggle={(event) => {
|
||||
if (!event.currentTarget.open) updatesOpen = false;
|
||||
@@ -377,8 +379,9 @@
|
||||
game = '';
|
||||
status = '';
|
||||
}}>Clear filters</Button
|
||||
>{:else}<Button variant="primary" onclick={() => (addOpen = true)}
|
||||
>Add plugin</Button
|
||||
>{:else if editable}<Button
|
||||
variant="primary"
|
||||
onclick={() => (addOpen = true)}>Add plugin</Button
|
||||
>{/if}{/snippet}
|
||||
</EmptyState>
|
||||
{:else}
|
||||
@@ -449,91 +452,95 @@
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<Dialog bind:open={addOpen} title="Add plugin" busy={uploading || githubBusy} wide>
|
||||
<Tabs
|
||||
tabs={[
|
||||
{ id: 'upload', label: 'Upload file', disabled: uploading || githubBusy },
|
||||
{ id: 'github', label: 'GitHub release', disabled: uploading || githubBusy }
|
||||
]}
|
||||
bind:value={method}
|
||||
ariaLabel="Plugin source"
|
||||
idPrefix="plugin-source"
|
||||
panelId="plugin-source-panel"
|
||||
/>
|
||||
<div id="plugin-source-panel" role="tabpanel" aria-labelledby={'plugin-source-' + method}>
|
||||
{#if method === 'github'}<PluginGithubImport
|
||||
bind:busy={githubBusy}
|
||||
onimport={async (result) => {
|
||||
importComplete = result;
|
||||
updates = updates.filter((update) => update.pluginId !== result.pluginId);
|
||||
importCount++;
|
||||
addOpen = false;
|
||||
await load();
|
||||
}}
|
||||
/>
|
||||
{:else}
|
||||
<form onsubmit={createPlugin} class="upload-form">
|
||||
<Field label="Name">
|
||||
<Input bind:value={newName} placeholder="my plugin" disabled={uploading} />
|
||||
</Field>
|
||||
<Field
|
||||
label="Release version"
|
||||
hint="Optional. Use the publisher’s version or release tag, such as v3.1.0."
|
||||
>
|
||||
<Input
|
||||
bind:value={newReleaseVersion}
|
||||
placeholder="v3.1.0"
|
||||
disabled={uploading}
|
||||
/>
|
||||
</Field>
|
||||
<Field label="Notes" hint="Optional. What changed in this version.">
|
||||
<Input bind:value={newNotes} placeholder="what changed" disabled={uploading} />
|
||||
</Field>
|
||||
<Field label="Scope" hint="Where this plugin deploys.">
|
||||
<div class="scope-row">
|
||||
<Select
|
||||
ariaLabel="Scope type"
|
||||
bind:value={newScopeType}
|
||||
options={scopeTypeOptions}
|
||||
{#if editable}<Dialog bind:open={addOpen} title="Add plugin" busy={uploading || githubBusy} wide>
|
||||
<Tabs
|
||||
tabs={[
|
||||
{ id: 'upload', label: 'Upload file', disabled: uploading || githubBusy },
|
||||
{ id: 'github', label: 'GitHub release', disabled: uploading || githubBusy }
|
||||
]}
|
||||
bind:value={method}
|
||||
ariaLabel="Plugin source"
|
||||
idPrefix="plugin-source"
|
||||
panelId="plugin-source-panel"
|
||||
/>
|
||||
<div id="plugin-source-panel" role="tabpanel" aria-labelledby={'plugin-source-' + method}>
|
||||
{#if method === 'github'}<PluginGithubImport
|
||||
bind:busy={githubBusy}
|
||||
onimport={async (result) => {
|
||||
importComplete = result;
|
||||
updates = updates.filter((update) => update.pluginId !== result.pluginId);
|
||||
importCount++;
|
||||
addOpen = false;
|
||||
await load();
|
||||
}}
|
||||
/>
|
||||
{:else}
|
||||
<form onsubmit={createPlugin} class="upload-form">
|
||||
<Field label="Name">
|
||||
<Input bind:value={newName} placeholder="my plugin" disabled={uploading} />
|
||||
</Field>
|
||||
<Field
|
||||
label="Release version"
|
||||
hint="Optional. Use the publisher’s version or release tag, such as v3.1.0."
|
||||
>
|
||||
<Input
|
||||
bind:value={newReleaseVersion}
|
||||
placeholder="v3.1.0"
|
||||
disabled={uploading}
|
||||
/>
|
||||
{#if newScopeType === 'game' || newScopeType === 'map'}
|
||||
</Field>
|
||||
<Field label="Notes" hint="Optional. What changed in this version.">
|
||||
<Input
|
||||
bind:value={newNotes}
|
||||
placeholder="what changed"
|
||||
disabled={uploading}
|
||||
/>
|
||||
</Field>
|
||||
<Field label="Scope" hint="Where this plugin deploys.">
|
||||
<div class="scope-row">
|
||||
<Select
|
||||
ariaLabel="Scope game"
|
||||
bind:value={newScopeGame}
|
||||
onchange={() => (newScopeMap = '')}
|
||||
options={gameOptions}
|
||||
ariaLabel="Scope type"
|
||||
bind:value={newScopeType}
|
||||
options={scopeTypeOptions}
|
||||
disabled={uploading}
|
||||
/>
|
||||
{/if}
|
||||
{#if newScopeType === 'map'}
|
||||
<Select
|
||||
ariaLabel="Scope map"
|
||||
bind:value={newScopeMap}
|
||||
options={mapOptions}
|
||||
disabled={uploading || !newScopeGame}
|
||||
/>
|
||||
{/if}
|
||||
{#if newScopeType === 'game' || newScopeType === 'map'}
|
||||
<Select
|
||||
ariaLabel="Scope game"
|
||||
bind:value={newScopeGame}
|
||||
onchange={() => (newScopeMap = '')}
|
||||
options={gameOptions}
|
||||
disabled={uploading}
|
||||
/>
|
||||
{/if}
|
||||
{#if newScopeType === 'map'}
|
||||
<Select
|
||||
ariaLabel="Scope map"
|
||||
bind:value={newScopeMap}
|
||||
options={mapOptions}
|
||||
disabled={uploading || !newScopeGame}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
</Field>
|
||||
<Field label="Plugin file (.dll)">
|
||||
<Input type="file" accept=".dll" onchange={pickFile} disabled={uploading} />
|
||||
</Field>
|
||||
<div class="form-actions ui-sticky-actions">
|
||||
<Button
|
||||
type="submit"
|
||||
variant="primary"
|
||||
disabled={uploading || !newFile || !newName}
|
||||
loading={uploading}
|
||||
>
|
||||
Upload plugin
|
||||
</Button>
|
||||
{#if flash}<span class="flash" role="alert">{flash}</span>{/if}
|
||||
</div>
|
||||
</Field>
|
||||
<Field label="Plugin file (.dll)">
|
||||
<Input type="file" accept=".dll" onchange={pickFile} disabled={uploading} />
|
||||
</Field>
|
||||
<div class="form-actions ui-sticky-actions">
|
||||
<Button
|
||||
type="submit"
|
||||
variant="primary"
|
||||
disabled={uploading || !newFile || !newName}
|
||||
loading={uploading}
|
||||
>
|
||||
Upload plugin
|
||||
</Button>
|
||||
{#if flash}<span class="flash" role="alert">{flash}</span>{/if}
|
||||
</div>
|
||||
</form>
|
||||
{/if}
|
||||
</div>
|
||||
</Dialog>
|
||||
</form>
|
||||
{/if}
|
||||
</div>
|
||||
</Dialog>{/if}
|
||||
|
||||
<style>
|
||||
.page {
|
||||
|
||||
Reference in New Issue
Block a user