Skip to content

Commit

Permalink
Merge pull request #3223 from centerofci/db-connection-pages
Browse files Browse the repository at this point in the history
Db connection UI
  • Loading branch information
seancolsen authored Oct 25, 2023
2 parents adf1290 + 8028323 commit cd3b437
Show file tree
Hide file tree
Showing 31 changed files with 993 additions and 85 deletions.
3 changes: 3 additions & 0 deletions mathesar/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
path('administration/users/', views.admin_home, name='admin_users_home'),
path('administration/users/<user_id>/', views.admin_home, name='admin_users_edit'),
path('administration/update/', views.admin_home, name='admin_update'),
path('administration/db-connection/', views.list_database_connection, name='list_database_connection'),
path('administration/db-connection/add/', views.add_database_connection, name='add_database_connection'),
path('administration/db-connection/edit/<db_name>/', views.edit_database_connection, name='edit_database_connection'),
path('shares/tables/<slug>/', views.shared_table, name='shared_table'),
path('shares/explorations/<slug>/', views.shared_query, name='shared_query'),
path('db/', views.home, name='db_home'),
Expand Down
27 changes: 27 additions & 0 deletions mathesar/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,12 @@ def get_database_list(request):
failed_db_data = []
for db in permission_restricted_failed_db_qs:
failed_db_data.append({
'id': db.id,
'username': db.username,
'port': db.port,
'host': db.host,
'name': db.name,
'db_name': db.db_name,
'editable': db.editable,
'error': 'Error connecting to the database'
})
Expand Down Expand Up @@ -303,6 +308,28 @@ def schemas(request, db_name):
})


@login_required
def list_database_connection(request):
return render(request, 'mathesar/index.html', {
'common_data': get_common_data(request)
})


@login_required
def add_database_connection(request):
return render(request, 'mathesar/index.html', {
'common_data': get_common_data(request)
})


@login_required
def edit_database_connection(request, db_name):
database = get_current_database(request, db_name)
return render(request, 'mathesar/index.html', {
'common_data': get_common_data(request, database, None)
})


def shared_table(request, slug):
shared_table_link = SharedTable.get_by_slug(slug) if is_valid_uuid_v4(slug) else None
table = shared_table_link.table if shared_table_link else None
Expand Down
18 changes: 17 additions & 1 deletion mathesar_ui/src/AppTypes.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
import type { TreeItem } from '@mathesar-component-library/types';

export interface Database {
interface BaseDatabase {
id: number;
name: string;
editable: boolean;
username: string;
host: string;
port: string;
db_name: string;
}

export interface DatabaseWithConnectionError extends BaseDatabase {
error: string;
}

export interface SuccessfullyConnectedDatabase extends BaseDatabase {
deleted: boolean;
supported_types: string[];
}

export type Database =
| SuccessfullyConnectedDatabase
| DatabaseWithConnectionError;

export interface DBObjectEntry {
id: number;
name: string;
Expand Down
32 changes: 32 additions & 0 deletions mathesar_ui/src/api/databaseConnection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { Database } from '@mathesar/AppTypes';
import { deleteAPI, patchAPI, postAPI } from './utils/requestUtils';

export interface NewConnection {
name: string;
db_name: string;
username: string;
host: string;
port: string;
password: string;
}

export type ConnectionUpdates = Partial<Omit<NewConnection, 'name'>>;

function add(connectionDetails: NewConnection) {
return postAPI<Database>('/api/db/v0/databases/', connectionDetails);
}

function update(databaseId: number, updates: ConnectionUpdates) {
return patchAPI<Database>(`/api/db/v0/databases/${databaseId}/`, updates);
}

function deleteConnection(databaseId: number, removeMathesarSchemas = false) {
const param = removeMathesarSchemas ? '?del_msar_schemas=True' : '';
return deleteAPI(`/api/db/v0/databases/${databaseId}/${param}`);
}

export default {
add,
update,
delete: deleteConnection,
};
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
--size-ultra-large: 2.074rem; //2.074rem/33.18px
--size-super-ultra-large: 2.488rem; //2.488rem/39.81px

--border-radius-xs: 0.071rem; //1px
--border-radius-s: 0.142rem; //2px
--border-radius-m: 0.285rem; //4px
--border-radius-l: 0.571rem; //8px
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
} from '@mathesar-component-library';
import { Field, type FieldStore } from '@mathesar/components/form';
import type { ComponentWithProps } from '@mathesar-component-library/types';
import UserFormInputRow from './UserFormInputRow.svelte';
import GridFormInputRow from './GridFormInputRow.svelte';
const labelController = new LabelController();
$: setLabelControllerInContext(labelController);
Expand All @@ -22,7 +22,7 @@
export let bypassRow = false;
</script>

<UserFormInputRow bypass={bypassRow}>
<GridFormInputRow bypass={bypassRow}>
<div class="left cell">
<Label controller={labelController}>
{label}
Expand All @@ -33,13 +33,18 @@
<div class="input">
<Field {field} {input} />
</div>
{#if help}
{#if $$slots.help || help}
<div class="help">
{help}
{#if $$slots.help}
<slot name="help" />
{/if}
{#if help}
{help}
{/if}
</div>
{/if}
</div>
</UserFormInputRow>
</GridFormInputRow>

<style lang="scss">
.left {
Expand All @@ -48,5 +53,12 @@
justify-content: end;
margin-right: var(--size-large);
padding-top: var(--size-ultra-small);
margin-left: var(--size-large);
}
.help {
color: var(--slate-500);
margin-top: var(--size-extreme-small);
font-size: var(--size-small);
}
</style>
19 changes: 17 additions & 2 deletions mathesar_ui/src/pages/admin-users/AdminNavigation.svelte
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
<script lang="ts">
import { active } from 'tinro';
import { Menu, MenuItemContents } from '@mathesar-component-library';
import { iconSettingsMajor, iconMultipleUsers } from '@mathesar/icons';
import {
iconSettingsMajor,
iconMultipleUsers,
iconDatabase,
} from '@mathesar/icons';
import {
ADMIN_UPDATE_PAGE_URL,
ADMIN_USERS_PAGE_URL,
DATABASE_CONNECTION_LIST_URL,
} from '@mathesar/routes/urls';
import { getReleaseDataStoreFromContext } from '@mathesar/stores/releases';
Expand Down Expand Up @@ -36,12 +41,22 @@
>
<MenuItemContents icon={iconMultipleUsers}>Users</MenuItemContents>
</a>
<a
role="menuitem"
href={DATABASE_CONNECTION_LIST_URL}
class="menu-item menu-item-link"
use:active
>
<MenuItemContents icon={iconDatabase}>
Database Connection
</MenuItemContents>
</a>
</Menu>
</div>

<style lang="scss">
.admin-navigation {
font-size: var(--text-size-large);
font-size: var(--text-size-base);
--min-width: 100%;
--Menu__item-border-radius: var(--border-radius-m);
--Menu__item-hover-background: var(--sand-100);
Expand Down
2 changes: 1 addition & 1 deletion mathesar_ui/src/pages/admin-users/EditUserPage.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
} from '@mathesar/systems/users-and-permissions';
import AppendBreadcrumb from '@mathesar/components/breadcrumb/AppendBreadcrumb.svelte';
import type { UserModel } from '@mathesar/stores/users';
import FormBox from './FormBox.svelte';
import FormBox from '@mathesar/components/form/FormBox.svelte';
const userProfileStore = getUserProfileStoreFromContext();
const usersStore = getUsersStoreFromContext();
Expand Down
2 changes: 1 addition & 1 deletion mathesar_ui/src/pages/admin-users/NewUserPage.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import { getUsersStoreFromContext } from '@mathesar/stores/users';
import { UserDetailsForm } from '@mathesar/systems/users-and-permissions';
import AppendBreadcrumb from '@mathesar/components/breadcrumb/AppendBreadcrumb.svelte';
import FormBox from './FormBox.svelte';
import FormBox from '@mathesar/components/form/FormBox.svelte';
const usersStore = getUsersStoreFromContext();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<script lang="ts">
import AppendBreadcrumb from '@mathesar/components/breadcrumb/AppendBreadcrumb.svelte';
import { iconAddNew } from '@mathesar/icons';
import {
DATABASE_CONNECTION_ADD_URL,
getDatabasePageUrl,
} from '@mathesar/routes/urls';
import { toast } from '@mathesar/stores/toast';
import type { Database } from '@mathesar/AppTypes';
import { router } from 'tinro';
import { reloadDatabases } from '@mathesar/stores/databases';
import { reflectApi } from '@mathesar/api/reflect';
import FormBox from '@mathesar/components/form/FormBox.svelte';
import DatabaseConnectionForm from './DatabaseConnectionForm.svelte';
async function handleSuccess(database: Database) {
toast.success(`${database.name} connected successfully!`);
try {
await reflectApi.reflect();
await reloadDatabases();
} catch (e) {
toast.fromError(e);
} finally {
router.goto(getDatabasePageUrl(database.name));
}
}
</script>

<AppendBreadcrumb
item={{
type: 'simple',
href: DATABASE_CONNECTION_ADD_URL,
label: 'Add Database Connection',
icon: iconAddNew,
}}
/>

<h1>Add Database Connection</h1>

<FormBox>
<DatabaseConnectionForm onCreate={handleSuccess} />
</FormBox>
Loading

0 comments on commit cd3b437

Please sign in to comment.