Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Edit Connection form #3387

Merged
merged 4 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
display: block;
font-size: var(--text-size-small);
color: var(--color-text-muted);
margin-top: 0.5rem;
margin-top: var(--spacing-y, var(--spacing-y-default));
&:empty {
display: none;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
white space.
-->
<span class="label">{label ?? ''}<slot name="label" /></span>
<span class="help">{help ?? ''}<slot name="help" /></span>
<span class="input"><slot /></span>
<span class="help">{help ?? ''}<slot name="help" /></span>
</span>
</Label>
</div>
2 changes: 1 addition & 1 deletion mathesar_ui/src/i18n/languages/en/dict.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
"cannot_move_linked_column_to_linked_table": "Cannot move linking column \"{columnName}\" to its linked table \"{tableName}\".",
"cell": "Cell",
"change_password": "Change Password",
"change_password_leave_empty_help": "If you want to change your password, enter a new one below. Otherwise, just leave the field blank.",
"check_for_updates": "Check for Updates",
"choose_connection": "Choose a Database Connection",
"choose_schema": "Choose a Schema",
Expand Down Expand Up @@ -162,6 +161,7 @@
"description": "Description",
"disable_link": "Disable Link",
"disable_link_question": "Disable Link?",
"disabled_connection_edit_fields_help": "Mathesar does not yet support editing a connection's database name, host, and port. We [issueLink](plan) to add support for this in the future. In the meantime, you can delete this connection and create a new one if needed.",
"disallow_null_values": "Disallow [null] Values",
"disallow_null_values_help": "Enable this option to prevent null values in the column. Null values are empty values that are not the same as zero or an empty string.",
"discard_changes": "Discard Changes",
Expand Down
138 changes: 85 additions & 53 deletions mathesar_ui/src/systems/connections/EditConnectionModal.svelte
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
<script lang="ts">
import { _ } from 'svelte-i18n';
import { map } from 'iter-tools';
import { _ } from 'svelte-i18n';

import {
ControlledModal,
LabeledInput,
PasswordInput,
type ModalController,
} from '@mathesar-component-library';
import type { Connection } from '@mathesar/api/connections';
import DocsLink from '@mathesar/components/DocsLink.svelte';
import Checkbox from '@mathesar/component-library/checkbox/Checkbox.svelte';
import TextInput from '@mathesar/component-library/text-input/TextInput.svelte';
import Identifier from '@mathesar/components/Identifier.svelte';
import {
Field,
FieldLayout,
FormSubmit,
isInPortRange,
makeForm,
optionalField,
requiredField,
uniqueWith,
} from '@mathesar/components/form';
import InfoBox from '@mathesar/components/message-boxes/InfoBox.svelte';
import { RichText } from '@mathesar/components/rich-text';
import { connectionsStore } from '@mathesar/stores/databases';
import { toast } from '@mathesar/stores/toast';
Expand All @@ -39,43 +41,29 @@
$: host = requiredField(connection.host);
$: port = requiredField(connection.port ?? 5432, [isInPortRange()]);
$: username = requiredField(connection.username);
$: password = optionalField('');
$: changePassword = requiredField(false);
$: password = requiredField('');
$: form = makeForm({
connectionName,
databaseName,
host,
port,
username,
password,
...{ connectionName, username, changePassword },
...($changePassword ? { password } : {}),
});

async function save() {
const formValues = $form.values;
const passwordValue =
formValues.password !== '' ? formValues.password : undefined;
try {
await connectionsStore.updateConnection(connection.id, {
database: formValues.databaseName,
host: formValues.host,
port: formValues.port,
username: formValues.username,
password: passwordValue,
nickname: formValues.connectionName,
nickname: $connectionName,
username: $username,
...($changePassword ? { password: $password } : {}),
});
toast.success($_('connection_updated_successfully'));
controller.close();
} catch (error) {
toast.error(getErrorMessage(error));
}
}

function cancel() {
form.reset();
controller.close();
}
</script>

<ControlledModal {controller}>
<ControlledModal {controller} on:open={() => form.reset()}>
<svelte:fragment slot="title">
<RichText text={$_('edit_connection_with_name')} let:slotName>
{#if slotName === 'connectionName'}
Expand All @@ -91,51 +79,97 @@
layout="stacked"
/>
<hr />
<Field label={$_('database_name')} field={databaseName} layout="stacked" />
<Field
label={$_('database_name')}
field={databaseName}
layout="stacked"
input={{ component: TextInput, props: { disabled: true } }}
/>
<FieldLayout>
<div data-identifier="host-port-config">
<div data-identifier="host-config">
<Field label={$_('host')} field={host} layout="stacked" />
<Field
label={$_('host')}
field={host}
layout="stacked"
input={{ component: TextInput, props: { disabled: true } }}
/>
</div>
<div data-identifier="port-config">
<Field label={$_('port')} field={port} layout="stacked" />
<Field
label={$_('port')}
field={port}
layout="stacked"
input={{ component: TextInput, props: { disabled: true } }}
/>
</div>
</div>
</FieldLayout>
<Field label={$_('username')} field={username} layout="stacked" />
<div class="help">
{$_('user_needs_create_connect_privileges')}
<DocsLink path="/">
{$_('why_is_this_needed')}
</DocsLink>
</div>
<hr />

<FieldLayout>
<div>{$_('change_password')}</div>
<div class="help">
{$_('change_password_leave_empty_help')}
<div class="disabled-help">
<InfoBox>
<RichText
text={$_('disabled_connection_edit_fields_help')}
let:slotName
let:translatedArg
>
{#if slotName === 'issueLink'}
<a
href="https://github.com/mathesar-foundation/mathesar/issues/3386"
target="_blank">{translatedArg}</a
>
{/if}
</RichText>
</InfoBox>
</div>
</FieldLayout>

<hr />

<Field
label={$_('password')}
field={password}
input={{
component: PasswordInput,
props: { autocomplete: 'new-password' },
}}
label={$_('username')}
field={username}
layout="stacked"
help={$_('user_needs_create_connect_privileges')}
/>
<div class="help">
{$_('password_encryption_help')}
</div>
<!-- TODO: Add docs link with $_('why_is_this_needed') text. This link needs
to be part of the translated string and it needs to point to a specific page
or section. -->

<!--
TODO: Use Field instead of FieldLayout/LabeledInput/Checkbox. We can't do
this yet because of a compatibility issue between Field and Checkbox.
-->
<FieldLayout>
<LabeledInput label={$_('change_password')} layout="inline-input-first">
<Checkbox bind:checked={$changePassword} />
</LabeledInput>
</FieldLayout>

{#if $changePassword}
<Field
label={$_('new_password')}
field={password}
input={{
component: PasswordInput,
props: { autocomplete: 'new-password' },
}}
layout="stacked"
help={$_('password_encryption_help')}
/>
{/if}
</div>

<div slot="footer">
<FormSubmit
{form}
onCancel={cancel}
onProceed={save}
canCancel={$form.hasChanges}
canProceed={$form.hasChanges}
cancelButton={{ label: $_('reset') }}
proceedButton={{ label: $_('update_connection') }}
onCancel={() => form.reset()}
onProceed={save}
/>
</div>
</ControlledModal>
Expand All @@ -145,10 +179,8 @@
margin: var(--size-large) 0;
}

.help {
.disabled-help {
font-size: var(--size-small);
color: var(--slate-400);
margin: var(--size-super-ultra-small) 0;
}

[data-identifier='host-port-config'] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*
* NOTICE: There is some code duplication between this file and
* `CellMode.svelte` used for the table view. It might be good to resolve this
* duplication at some point. In the mean time, be mindful of propagating
* duplication at some point. In the meantime, be mindful of propagating
* changes to both files as necessary.
*/
import { _ } from 'svelte-i18n';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*
* NOTICE: There is some code duplication between this file and
* `CellTab.svelte` used for the data explorer. It might be good to resolve
* this duplication at some point. In the mean time, be mindful of propagating
* this duplication at some point. In the meantime, be mindful of propagating
* changes to both files as necessary.
*/
import { _ } from 'svelte-i18n';
Expand Down
Loading