mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
Merge pull request #1882 from appwrite/dat-534-string-encryption
string encryption in create attribute
This commit is contained in:
+1
-2
@@ -23,11 +23,10 @@
|
||||
"dependencies": {
|
||||
"@ai-sdk/svelte": "^1.1.24",
|
||||
"@appwrite.io/console": "https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@e190a19",
|
||||
"@appwrite.io/pink": "0.25.0",
|
||||
"@appwrite.io/pink-icons": "0.25.0",
|
||||
"@appwrite.io/pink-icons-svelte": "^2.0.0-RC.1",
|
||||
"@appwrite.io/pink-legacy": "^1.0.3",
|
||||
"@appwrite.io/pink-svelte": "https://try-module.cloud/module/@appwrite/@appwrite.io/pink-svelte@0cc439f",
|
||||
"@appwrite.io/pink-svelte": "https://try-module.cloud/-/@appwrite/@appwrite.io/pink-svelte@063404f",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@sentry/sveltekit": "^8.38.0",
|
||||
"@stripe/stripe-js": "^3.5.0",
|
||||
|
||||
Generated
+9
-26
@@ -14,9 +14,6 @@ importers:
|
||||
'@appwrite.io/console':
|
||||
specifier: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@e190a19
|
||||
version: https://pkg.pr.new/appwrite-labs/cloud/@appwrite.io/console@e190a19
|
||||
'@appwrite.io/pink':
|
||||
specifier: 0.25.0
|
||||
version: 0.25.0
|
||||
'@appwrite.io/pink-icons':
|
||||
specifier: 0.25.0
|
||||
version: 0.25.0
|
||||
@@ -27,8 +24,8 @@ importers:
|
||||
specifier: ^1.0.3
|
||||
version: 1.0.3
|
||||
'@appwrite.io/pink-svelte':
|
||||
specifier: https://try-module.cloud/module/@appwrite/@appwrite.io/pink-svelte@0cc439f
|
||||
version: https://try-module.cloud/module/@appwrite/%40appwrite.io%2Fpink-svelte@0cc439f(svelte@5.25.3)
|
||||
specifier: https://try-module.cloud/-/@appwrite/@appwrite.io/pink-svelte@063404f
|
||||
version: https://try-module.cloud/-/@appwrite/%40appwrite.io%2Fpink-svelte@063404f(svelte@5.25.3)
|
||||
'@popperjs/core':
|
||||
specifier: ^2.11.8
|
||||
version: 2.11.8
|
||||
@@ -281,15 +278,12 @@ packages:
|
||||
'@appwrite.io/pink-legacy@1.0.3':
|
||||
resolution: {integrity: sha512-GGde5fmPhs+s6/3aFeMPc/kKADG/gTFkYQSy6oBN8pK0y0XNCLrZZgBv+EBbdhwdtqVEWXa0X85Mv9w7jcIlwQ==}
|
||||
|
||||
'@appwrite.io/pink-svelte@https://try-module.cloud/module/@appwrite/%40appwrite.io%2Fpink-svelte@0cc439f':
|
||||
resolution: {tarball: https://try-module.cloud/module/@appwrite/%40appwrite.io%2Fpink-svelte@0cc439f}
|
||||
'@appwrite.io/pink-svelte@https://try-module.cloud/-/@appwrite/%40appwrite.io%2Fpink-svelte@063404f':
|
||||
resolution: {tarball: https://try-module.cloud/-/@appwrite/%40appwrite.io%2Fpink-svelte@063404f}
|
||||
version: 2.0.0-RC.2
|
||||
peerDependencies:
|
||||
svelte: ^4.0.0
|
||||
|
||||
'@appwrite.io/pink@0.25.0':
|
||||
resolution: {integrity: sha512-9z4G/iAhjvVpM7tkNqzGqrokst4hvNt3Fkf2jD4W6n8j//EJbQ3mJ0I+5dye5Sry0a33wUanq5DSztqFNYq5zw==}
|
||||
|
||||
'@asamuzakjp/css-color@3.1.1':
|
||||
resolution: {integrity: sha512-hpRD68SV2OMcZCsrbdkccTw5FXjNDLo5OuqSHyHZfwweGsDWZwDJ2+gONyNAbazZclobMirACLw0lk8WVxIqxA==}
|
||||
|
||||
@@ -1343,8 +1337,8 @@ packages:
|
||||
'@types/prop-types@15.7.14':
|
||||
resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==}
|
||||
|
||||
'@types/react@18.3.22':
|
||||
resolution: {integrity: sha512-vUhG0YmQZ7kL/tmKLrD3g5zXbXXreZXB3pmROW8bg3CnLnpjkRVwUlLne7Ufa2r9yJ8+/6B73RzhAek5TBKh2Q==}
|
||||
'@types/react@18.3.23':
|
||||
resolution: {integrity: sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==}
|
||||
|
||||
'@types/remarkable@2.0.8':
|
||||
resolution: {integrity: sha512-eKXqPZfpQl1kOADjdKchHrp2gwn9qMnGXhH/AtZe0UrklzhGJkawJo/Y/D0AlWcdWoWamFNIum8+/nkAISQVGg==}
|
||||
@@ -2664,9 +2658,6 @@ packages:
|
||||
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
normalize.css@8.0.1:
|
||||
resolution: {integrity: sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==}
|
||||
|
||||
nwsapi@2.2.20:
|
||||
resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==}
|
||||
|
||||
@@ -3644,7 +3635,7 @@ snapshots:
|
||||
'@appwrite.io/pink-icons': 1.0.0
|
||||
the-new-css-reset: 1.11.3
|
||||
|
||||
'@appwrite.io/pink-svelte@https://try-module.cloud/module/@appwrite/%40appwrite.io%2Fpink-svelte@0cc439f(svelte@5.25.3)':
|
||||
'@appwrite.io/pink-svelte@https://try-module.cloud/-/@appwrite/%40appwrite.io%2Fpink-svelte@063404f(svelte@5.25.3)':
|
||||
dependencies:
|
||||
'@appwrite.io/pink-icons-svelte': 2.0.0-RC.1(svelte@5.25.3)
|
||||
'@floating-ui/dom': 1.6.13
|
||||
@@ -3659,12 +3650,6 @@ snapshots:
|
||||
svelte-motion: 0.12.2(svelte@5.25.3)
|
||||
svelte-sonner: 0.3.28(svelte@5.25.3)
|
||||
|
||||
'@appwrite.io/pink@0.25.0':
|
||||
dependencies:
|
||||
'@appwrite.io/pink-icons': 0.25.0
|
||||
normalize.css: 8.0.1
|
||||
the-new-css-reset: 1.11.3
|
||||
|
||||
'@asamuzakjp/css-color@3.1.1':
|
||||
dependencies:
|
||||
'@csstools/css-calc': 2.1.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)
|
||||
@@ -4787,7 +4772,7 @@ snapshots:
|
||||
|
||||
'@types/prop-types@15.7.14': {}
|
||||
|
||||
'@types/react@18.3.22':
|
||||
'@types/react@18.3.23':
|
||||
dependencies:
|
||||
'@types/prop-types': 15.7.14
|
||||
csstype: 3.1.3
|
||||
@@ -6254,8 +6239,6 @@ snapshots:
|
||||
|
||||
normalize-path@3.0.0: {}
|
||||
|
||||
normalize.css@8.0.1: {}
|
||||
|
||||
nwsapi@2.2.20: {}
|
||||
|
||||
object-inspect@1.13.4: {}
|
||||
@@ -6735,7 +6718,7 @@ snapshots:
|
||||
|
||||
svelte-motion@0.12.2(svelte@5.25.3):
|
||||
dependencies:
|
||||
'@types/react': 18.3.22
|
||||
'@types/react': 18.3.23
|
||||
framesync: 6.1.2
|
||||
popmotion: 11.0.5
|
||||
style-value-types: 5.1.2
|
||||
|
||||
@@ -44,6 +44,7 @@ export type Column = PinkColumn & {
|
||||
format?: string;
|
||||
exclude?: boolean;
|
||||
elements?: string[] | { value: string | number; label: string }[];
|
||||
encrypt?: boolean;
|
||||
};
|
||||
|
||||
export function isValueOfStringEnum<T extends Record<string, string>>(
|
||||
|
||||
@@ -338,6 +338,7 @@ export type Plan = {
|
||||
backupPolicies: number;
|
||||
emailBranding: boolean;
|
||||
supportsCredits: boolean;
|
||||
databasesAllowEncrypt: boolean;
|
||||
buildSize: number; // in MB
|
||||
deploymentSize: number; // in MB
|
||||
};
|
||||
|
||||
+35
-20
@@ -13,10 +13,11 @@
|
||||
Link,
|
||||
Popover,
|
||||
Table,
|
||||
Tooltip,
|
||||
Typography
|
||||
} from '@appwrite.io/pink-svelte';
|
||||
import Create from '../createAttribute.svelte';
|
||||
import { isRelationship } from '../document-[document]/attributes/store';
|
||||
import { isRelationship, isString } from '../document-[document]/attributes/store';
|
||||
import FailedModal from '../failedModal.svelte';
|
||||
import CreateIndex from '../indexes/createIndex.svelte';
|
||||
import { attributes, type Attributes, isCsvImportInProgress } from '../store';
|
||||
@@ -33,7 +34,8 @@
|
||||
IconPlus,
|
||||
IconSwitchHorizontal,
|
||||
IconTrash,
|
||||
IconViewList
|
||||
IconViewList,
|
||||
IconLockClosed
|
||||
} from '@appwrite.io/pink-icons-svelte';
|
||||
import type { ComponentProps } from 'svelte';
|
||||
import { Click, trackEvent } from '$lib/actions/analytics';
|
||||
@@ -112,25 +114,38 @@
|
||||
{:else}
|
||||
<Icon icon={option.icon} size="s" />
|
||||
{/if}
|
||||
<span class="text u-trim-1" data-private>{attribute.key}</span>
|
||||
{#if attribute.status !== 'available'}
|
||||
<Badge
|
||||
size="s"
|
||||
variant="secondary"
|
||||
content={attribute.status}
|
||||
type={getAttributeStatusBadge(attribute.status)} />
|
||||
{#if attribute.error}
|
||||
<Link.Button
|
||||
variant="muted"
|
||||
on:click={(e) => {
|
||||
e.preventDefault();
|
||||
error = attribute.error;
|
||||
showFailed = true;
|
||||
}}>Details</Link.Button>
|
||||
<Layout.Stack direction="row" alignItems="center" gap="s">
|
||||
<Layout.Stack inline direction="row" alignItems="center" gap="xxs">
|
||||
<span class="text u-trim-1" data-private>{attribute.key}</span>
|
||||
{#if isString(attribute) && !attribute.encrypt}
|
||||
<Tooltip>
|
||||
<Icon
|
||||
size="s"
|
||||
icon={IconLockClosed}
|
||||
color="--fgcolor-neutral-tertiary" />
|
||||
<div slot="tooltip">Encrypted</div>
|
||||
</Tooltip>
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
{#if attribute.status !== 'available'}
|
||||
<Badge
|
||||
size="s"
|
||||
variant="secondary"
|
||||
content={attribute.status}
|
||||
type={getAttributeStatusBadge(attribute.status)} />
|
||||
{#if attribute.error}
|
||||
<Link.Button
|
||||
variant="muted"
|
||||
on:click={(e) => {
|
||||
e.preventDefault();
|
||||
error = attribute.error;
|
||||
showFailed = true;
|
||||
}}>Details</Link.Button>
|
||||
{/if}
|
||||
{:else if attribute.required}
|
||||
<Badge size="xs" variant="secondary" content="required" />
|
||||
{/if}
|
||||
{:else if attribute.required}
|
||||
<Badge size="s" variant="secondary" content="required" />
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Layout.Stack>
|
||||
</Table.Cell>
|
||||
<Table.Cell column="type" {root}>
|
||||
|
||||
+1
-2
@@ -100,5 +100,4 @@
|
||||
label="Array"
|
||||
bind:checked={data.array}
|
||||
disabled={data.required || editing}
|
||||
description="Indicate whether this attribute should act as an array, with the default value set as an empty
|
||||
array." />
|
||||
description="Indicate whether this attribute is an array. Defaults to an empty array." />
|
||||
|
||||
+1
-2
@@ -92,5 +92,4 @@
|
||||
label="Array"
|
||||
bind:checked={data.array}
|
||||
disabled={data.required || editing}
|
||||
description="Indicate whether this attribute should act as an array, with the default value set as an empty
|
||||
array." />
|
||||
description="Indicate whether this attribute is an array. Defaults to an empty array." />
|
||||
|
||||
+1
-2
@@ -93,5 +93,4 @@
|
||||
label="Array"
|
||||
bind:checked={data.array}
|
||||
disabled={data.required || editing}
|
||||
description="Indicate whether this attribute should act as an array, with the default value set as an empty
|
||||
array." />
|
||||
description="Indicate whether this attribute is an array. Defaults to an empty array." />
|
||||
|
||||
+1
-2
@@ -124,5 +124,4 @@
|
||||
label="Array"
|
||||
bind:checked={data.array}
|
||||
disabled={data.required || editing}
|
||||
description="Indicate whether this attribute should act as an array, with the default value set as an empty
|
||||
array." />
|
||||
description="Indicate whether this attribute is an array. Defaults to an empty array." />
|
||||
|
||||
+1
-2
@@ -122,5 +122,4 @@
|
||||
label="Array"
|
||||
bind:checked={data.array}
|
||||
disabled={data.required || editing}
|
||||
description="Indicate whether this attribute should act as an array, with the default value set as an empty
|
||||
array." />
|
||||
description="Indicate whether this attribute is an array. Defaults to an empty array." />
|
||||
|
||||
+1
-2
@@ -120,5 +120,4 @@
|
||||
label="Array"
|
||||
bind:checked={data.array}
|
||||
disabled={data.required || editing}
|
||||
description="Indicate whether this attribute should act as an array, with the default value set as an empty
|
||||
array." />
|
||||
description="Indicate whether this attribute is an array. Defaults to an empty array." />
|
||||
|
||||
+1
-2
@@ -92,5 +92,4 @@
|
||||
label="Array"
|
||||
bind:checked={data.array}
|
||||
disabled={data.required || editing}
|
||||
description="Indicate whether this attribute should act as an array, with the default value set as an empty
|
||||
array." />
|
||||
description="Indicate whether this attribute is an array. Defaults to an empty array." />
|
||||
|
||||
+92
-27
@@ -18,7 +18,8 @@
|
||||
data.size,
|
||||
data.required,
|
||||
data.default,
|
||||
data.array
|
||||
data.array,
|
||||
data.encrypt
|
||||
);
|
||||
}
|
||||
export async function updateString(
|
||||
@@ -42,16 +43,21 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { Selector } from '@appwrite.io/pink-svelte';
|
||||
import { isCloud } from '$lib/system';
|
||||
import { upgradeURL } from '$lib/stores/billing';
|
||||
import { currentPlan } from '$lib/stores/organization';
|
||||
import { createConservative } from '$lib/helpers/stores';
|
||||
import { ActionMenu, Selector } from '@appwrite.io/pink-svelte';
|
||||
import { InputNumber, InputText, InputTextarea } from '$lib/elements/forms';
|
||||
import { Popover, Layout, Tag, Typography, Link } from '@appwrite.io/pink-svelte';
|
||||
|
||||
export let data: Partial<Models.AttributeString> = {
|
||||
required: false,
|
||||
size: 0,
|
||||
default: null,
|
||||
array: false
|
||||
array: false,
|
||||
encrypt: false
|
||||
};
|
||||
|
||||
export let editing = false;
|
||||
|
||||
let savedDefault = data.default;
|
||||
@@ -73,48 +79,107 @@
|
||||
array: false,
|
||||
...data
|
||||
});
|
||||
|
||||
$: listen(data);
|
||||
|
||||
$: handleDefaultState($required || $array);
|
||||
|
||||
// check plan on cloud, always allow on self-hosted!
|
||||
$: supportsStringEncryption = isCloud ? $currentPlan?.databasesAllowEncrypt : true;
|
||||
</script>
|
||||
|
||||
<InputNumber
|
||||
id="size"
|
||||
label="Size"
|
||||
required
|
||||
placeholder="Enter size"
|
||||
bind:value={data.size}
|
||||
required={true} />
|
||||
{#if data.size >= 50}
|
||||
<InputTextarea
|
||||
id="default"
|
||||
label="Default"
|
||||
placeholder="Enter string"
|
||||
disabled={data.required || data.array}
|
||||
nullable={!data.required && !data.array}
|
||||
maxlength={data.size}
|
||||
bind:value={data.default} />
|
||||
{:else}
|
||||
<InputText
|
||||
id="default"
|
||||
label="Default"
|
||||
placeholder="Enter string"
|
||||
disabled={data.required || data.array}
|
||||
nullable={!data.required && !data.array}
|
||||
maxlength={data.size}
|
||||
bind:value={data.default} />
|
||||
{/if}
|
||||
min={supportsStringEncryption && data.encrypt ? 150 : undefined}
|
||||
helper={supportsStringEncryption && data.encrypt
|
||||
? 'Encrypted string attributes require a minimum size of 150.'
|
||||
: undefined} />
|
||||
|
||||
<svelte:component
|
||||
this={data.size >= 50 ? InputTextarea : InputText}
|
||||
id="default"
|
||||
label="Default"
|
||||
placeholder="Enter string"
|
||||
maxlength={data.size}
|
||||
bind:value={data.default}
|
||||
disabled={data.required || data.array}
|
||||
nullable={!data.required && !data.array} />
|
||||
|
||||
<Selector.Checkbox
|
||||
size="s"
|
||||
id="required"
|
||||
label="Required"
|
||||
bind:checked={data.required}
|
||||
disabled={data.array}
|
||||
description="Indicate whether this attribute is required" />
|
||||
description="Indicate whether this attribute is required." />
|
||||
|
||||
<Selector.Checkbox
|
||||
size="s"
|
||||
id="array"
|
||||
label="Array"
|
||||
bind:checked={data.array}
|
||||
disabled={data.required || editing}
|
||||
description="Indicate whether this attribute should act as an array, with the default value set as an empty
|
||||
array." />
|
||||
description="Indicate whether this attribute is an array. Defaults to an empty array." />
|
||||
|
||||
<Layout.Stack gap="xs" direction="column">
|
||||
<div class="popover-holder" class:disabled-checkbox={!supportsStringEncryption || editing}>
|
||||
<Layout.Stack inline gap="s" alignItems="flex-start" direction="row">
|
||||
<Popover let:toggle placement="bottom-start">
|
||||
<Selector.Checkbox
|
||||
size="s"
|
||||
id="encrypt"
|
||||
bind:checked={data.encrypt}
|
||||
disabled={!supportsStringEncryption || editing} />
|
||||
|
||||
<Layout.Stack gap="xxs" direction="column">
|
||||
<button
|
||||
type="button"
|
||||
class="u-cursor-pointer"
|
||||
on:click={(e) => {
|
||||
if (!supportsStringEncryption) {
|
||||
toggle(e);
|
||||
} else {
|
||||
data.encrypt = !data.encrypt;
|
||||
}
|
||||
}}>
|
||||
<Layout.Stack inline gap="xxs" direction="row" alignItems="center">
|
||||
<Typography.Text variant="m-500">Encrypted</Typography.Text>
|
||||
{#if !supportsStringEncryption}
|
||||
<Tag variant="default" size="xs" on:click={toggle}>Pro</Tag>
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</button>
|
||||
<Typography.Text color="--fgcolor-neutral-tertiary">
|
||||
Indicate whether this attribute is encrypted. Encrypted attributes cannot be
|
||||
queried.
|
||||
</Typography.Text>
|
||||
</Layout.Stack>
|
||||
|
||||
<ActionMenu.Root width="180px" slot="tooltip">
|
||||
<Typography.Text variant="m-500">
|
||||
Available on Pro plan. <Link.Anchor href={$upgradeURL}>Upgrade</Link.Anchor>
|
||||
to enable encrypted attributes.
|
||||
</Typography.Text>
|
||||
</ActionMenu.Root>
|
||||
</Popover>
|
||||
</Layout.Stack>
|
||||
</div>
|
||||
</Layout.Stack>
|
||||
|
||||
<style lang="scss">
|
||||
.popover-holder {
|
||||
& :global([role='tooltip']) {
|
||||
margin-top: 4px;
|
||||
left: 8rem !important;
|
||||
}
|
||||
|
||||
// no cursor when disabled
|
||||
&.disabled-checkbox :global(button) {
|
||||
cursor: unset !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
+1
-2
@@ -93,5 +93,4 @@
|
||||
label="Array"
|
||||
bind:checked={data.array}
|
||||
disabled={data.required || editing}
|
||||
description="Indicate whether this attribute should act as an array, with the default value set as an empty
|
||||
array." />
|
||||
description="Indicate whether this attribute is an array. Defaults to an empty array." />
|
||||
|
||||
+5
@@ -15,3 +15,8 @@ export function isRelationship(attribute: Attributes): attribute is Models.Attri
|
||||
if (!attribute) return false;
|
||||
return attribute?.type === 'relationship';
|
||||
}
|
||||
|
||||
export function isString(attribute: Attributes): attribute is Models.AttributeString {
|
||||
if (!attribute) return false;
|
||||
return attribute?.type === 'string';
|
||||
}
|
||||
|
||||
+25
-11
@@ -12,7 +12,11 @@
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { afterUpdate, onMount } from 'svelte';
|
||||
import type { PageData } from './$types';
|
||||
import { isRelationship, isRelationshipToMany } from './document-[document]/attributes/store';
|
||||
import {
|
||||
isRelationship,
|
||||
isRelationshipToMany,
|
||||
isString
|
||||
} from './document-[document]/attributes/store';
|
||||
import RelationshipsModal from './relationshipsModal.svelte';
|
||||
import { attributes, collection, columns } from './store';
|
||||
import type { ColumnType } from '$lib/helpers/types';
|
||||
@@ -22,10 +26,10 @@
|
||||
Button,
|
||||
Link,
|
||||
Badge,
|
||||
FloatingActionBar
|
||||
FloatingActionBar,
|
||||
InteractiveText
|
||||
} from '@appwrite.io/pink-svelte';
|
||||
import DualTimeView from '$lib/components/dualTimeView.svelte';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
const databaseId = page.params.database;
|
||||
@@ -237,14 +241,24 @@
|
||||
{/if}
|
||||
{:else}
|
||||
{@const formatted = formatColumn(document[id])}
|
||||
<Tooltip disabled={!formatted.truncated} placement="bottom">
|
||||
<span>
|
||||
{formatted.value}
|
||||
</span>
|
||||
<span style:white-space="pre-wrap" slot="tooltip">
|
||||
{formatted.whole}
|
||||
</span>
|
||||
</Tooltip>
|
||||
{#if isString(attr) && !attr.encrypt}
|
||||
<button on:click={(e) => e.preventDefault()}>
|
||||
<InteractiveText
|
||||
copy={false}
|
||||
variant="secret"
|
||||
isVisible={false}
|
||||
text={formatted.value} />
|
||||
</button>
|
||||
{:else}
|
||||
<Tooltip disabled={!formatted.truncated} placement="bottom">
|
||||
<span>
|
||||
{formatted.value}
|
||||
</span>
|
||||
<span style:white-space="pre-wrap" slot="tooltip">
|
||||
{formatted.whole}
|
||||
</span>
|
||||
</Tooltip>
|
||||
{/if}
|
||||
{/if}
|
||||
</Table.Cell>
|
||||
{/each}
|
||||
|
||||
Reference in New Issue
Block a user