120 lines
4.0 KiB
Svelte
120 lines
4.0 KiB
Svelte
<script>
|
|
import { createEventDispatcher } from 'svelte';
|
|
import { fade, slide } from 'svelte/transition';
|
|
import { invoke } from '@tauri-apps/api/core';
|
|
|
|
import ErrorAlert from '../../ui/ErrorAlert.svelte';
|
|
import Icon from '../../ui/Icon.svelte';
|
|
|
|
export let record;
|
|
export let defaults;
|
|
|
|
import PassphraseInput from '../../ui/PassphraseInput.svelte';
|
|
|
|
|
|
const dispatch = createEventDispatcher();
|
|
|
|
let showDetails = record.isNew ? true : false;
|
|
|
|
let local = JSON.parse(JSON.stringify(record));
|
|
$: isModified = JSON.stringify(local) !== JSON.stringify(record);
|
|
|
|
// explicitly subscribe to updates to `default`, so that we can update
|
|
// our local copy even if the component hasn't been recreated
|
|
// (sadly we can't use a reactive binding because reasons I guess)
|
|
defaults.subscribe(d => local.is_default = local.id === d[local.credential.type])
|
|
|
|
let alert;
|
|
async function saveCredential() {
|
|
await invoke('save_credential', {record: local});
|
|
dispatch('update');
|
|
showDetails = false;
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
<div class="rounded-box space-y-4 bg-base-200 {record.is_default ? 'border border-accent' : ''}">
|
|
<div class="flex items-center px-6 py-4 gap-x-4">
|
|
<h3 class="text-lg font-bold">
|
|
{#if !record?.isNew && showDetails}
|
|
<input type="text" class="input input-bordered bg-transparent" bind:value={local.name}>
|
|
{:else}
|
|
{record.name || ''}
|
|
{/if}
|
|
</h3>
|
|
|
|
{#if record.is_default}
|
|
<span class="badge badge-accent">Default</span>
|
|
{/if}
|
|
|
|
<div class="join ml-auto">
|
|
<button
|
|
type="button"
|
|
class="btn btn-outline join-item"
|
|
on:click={() => showDetails = !showDetails}
|
|
>
|
|
<Icon name="pencil" class="size-6" />
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn btn-outline btn-error join-item"
|
|
on:click={() => dispatch('delete', record)}
|
|
>
|
|
<Icon name="trash" class="size-6" />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
{#if showDetails}
|
|
<form
|
|
transition:slide|local={{duration: 200}}
|
|
class=" px-6 pb-4 space-y-4"
|
|
on:submit|preventDefault={() => alert.run(saveCredential)}
|
|
>
|
|
<ErrorAlert bind:this={alert} />
|
|
|
|
<div class="grid grid-cols-[auto_1fr] items-center gap-4">
|
|
{#if record.isNew}
|
|
<span class="justify-self-end">Name</span>
|
|
<input
|
|
type="text"
|
|
class="input input-bordered bg-transparent"
|
|
bind:value={local.name}
|
|
>
|
|
{/if}
|
|
|
|
<span class="justify-self-end">Key ID</span>
|
|
<input
|
|
type="text"
|
|
class="input input-bordered font-mono bg-transparent"
|
|
bind:value={local.credential.AccessKeyId}
|
|
>
|
|
|
|
<span>Secret key</span>
|
|
<div class="font-mono">
|
|
<PassphraseInput class="bg-transparent" bind:value={local.credential.SecretAccessKey} />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex justify-between">
|
|
<label class="label cursor-pointer justify-self-start space-x-4">
|
|
<span class="label-text">Default AWS access key</span>
|
|
<input type="checkbox" class="toggle toggle-accent" bind:checked={local.is_default}>
|
|
</label>
|
|
{#if isModified}
|
|
<button
|
|
transition:fade={{duration: 100}}
|
|
type="submit"
|
|
class="btn btn-primary"
|
|
>
|
|
Save
|
|
</button>
|
|
{/if}
|
|
</div>
|
|
</form>
|
|
{/if}
|
|
</div>
|